270 lines
7.6 KiB
C
270 lines
7.6 KiB
C
#include "usb/device/usb_stack.h"
|
|
#include "usb/usb_config.h"
|
|
#include "usb/device/cdc.h"
|
|
#include "app_config.h"
|
|
#include "os/os_api.h"
|
|
#include "printer.h" //need redefine __u8, __u16, __u32
|
|
|
|
#define LOG_TAG_CONST USB
|
|
#define LOG_TAG "[Printer]"
|
|
#define LOG_ERROR_ENABLE
|
|
#define LOG_DEBUG_ENABLE
|
|
#define LOG_INFO_ENABLE
|
|
/* #define LOG_DUMP_ENABLE */
|
|
#define LOG_CLI_ENABLE
|
|
#include "debug.h"
|
|
|
|
#if TCFG_USB_SLAVE_PRINTER_ENABLE
|
|
|
|
static const u8 printer_desc[] = {
|
|
///Interface
|
|
USB_DT_INTERFACE_SIZE, //Length
|
|
USB_DT_INTERFACE, //DescriptorType:Inerface
|
|
0x00, //InterfaceNum:0
|
|
0x00, //AlternateSetting:0
|
|
0x02, //NumEndpoint:0
|
|
USB_CLASS_PRINTER, //InterfaceClass:Printer
|
|
0x01, //Printers
|
|
0x02, //InterfaceProtocol
|
|
0x04, //Interface String
|
|
///Endpoint IN
|
|
USB_DT_ENDPOINT_SIZE,
|
|
USB_DT_ENDPOINT,
|
|
USB_DIR_IN | PTR_BULK_EP_IN,
|
|
USB_ENDPOINT_XFER_BULK,
|
|
LOBYTE(MAXP_SIZE_BULKIN), HIBYTE(MAXP_SIZE_BULKIN),
|
|
0x01,
|
|
///Endpoint OUT
|
|
USB_DT_ENDPOINT_SIZE,
|
|
USB_DT_ENDPOINT,
|
|
PTR_BULK_EP_OUT,
|
|
USB_ENDPOINT_XFER_BULK,
|
|
LOBYTE(MAXP_SIZE_BULKOUT), HIBYTE(MAXP_SIZE_BULKOUT),
|
|
0x01,
|
|
};
|
|
|
|
|
|
struct usb_printer_handle {
|
|
u8 *ep_out_dmabuffer;
|
|
u8 *ep_in_dmabuffer;
|
|
void (*wakeup_handle)(struct usb_device_t *usb_device);
|
|
void (*reset_wakeup_handle)(struct usb_device_t *usb_device, u32 itf_num);
|
|
|
|
};
|
|
|
|
struct usb_printer_handle *printer_handle = NULL;
|
|
static OS_SEM wake_sem;
|
|
|
|
|
|
static void printer_wakeup_handler(struct usb_device_t *usb_device)
|
|
{
|
|
os_sem_post(&wake_sem);
|
|
}
|
|
|
|
|
|
static void printer_wakeup(struct usb_device_t *usb_device, u32 ep)
|
|
{
|
|
#if 0 //for test
|
|
u32 len = 0;
|
|
u8 read_ep[64];
|
|
const usb_dev usb_id = usb_device2id(usb_device);
|
|
|
|
ep &= 0x0f;
|
|
len = usb_g_intr_read(usb_id, ep, read_ep, sizeof(read_ep), 0);
|
|
printf("recv_len = %d, ep = %d\n", len, ep);
|
|
put_buf(read_ep, len);
|
|
#else
|
|
if ((printer_handle) && (printer_handle->wakeup_handle)) {
|
|
printer_handle->wakeup_handle(usb_device);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
|
|
static void reset_wakeup(struct usb_device_t *usb_device, u32 itf_num)
|
|
{
|
|
const usb_dev usb_id = usb_device2id(usb_device);
|
|
if (printer_handle && printer_handle->reset_wakeup_handle) {
|
|
printer_handle->reset_wakeup_handle(usb_device, itf_num);
|
|
}
|
|
}
|
|
|
|
|
|
static void printer_endpoint_init(struct usb_device_t *usb_device, u32 itf)
|
|
{
|
|
const usb_dev usb_id = usb_device2id(usb_device);
|
|
|
|
usb_g_ep_config(usb_id, PTR_BULK_EP_IN | USB_DIR_IN, USB_ENDPOINT_XFER_BULK, 0, printer_handle->ep_out_dmabuffer, MAXP_SIZE_BULKIN);
|
|
|
|
usb_g_ep_config(usb_id, PTR_BULK_EP_OUT, USB_ENDPOINT_XFER_BULK, 1, printer_handle->ep_out_dmabuffer, MAXP_SIZE_BULKOUT);
|
|
usb_g_set_intr_hander(usb_id, PTR_BULK_EP_OUT, printer_wakeup);
|
|
|
|
usb_enable_ep(usb_id, PTR_BULK_EP_IN);
|
|
usb_enable_ep(usb_id, PTR_BULK_EP_OUT);
|
|
}
|
|
|
|
|
|
static const u8 device_id[] = {
|
|
/* 0x00, 0x0D, 0x50, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x56, 0x30, 0x2E, 0x31, 0x00 */
|
|
0x00, 0x50, 0x4d, 0x46, 0x47, 0x3a, 0x50, 0x6f, 0x73, 0x74, 0x65, 0x4b, 0x50, 0x72, 0x69, 0x6e,
|
|
0x74, 0x65, 0x72, 0x73, 0x3b, 0x4d, 0x44, 0x4c, 0x3a, 0x50, 0x4f, 0x53, 0x54, 0x45, 0x4b, 0x20,
|
|
0x51, 0x38, 0x2f, 0x32, 0x30, 0x30, 0x3b, 0x43, 0x4d, 0x44, 0x3a, 0x50, 0x50, 0x4c, 0x49, 0x3b,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
};
|
|
|
|
|
|
static u32 printer_itf_hander(struct usb_device_t *usb_device, struct usb_ctrlrequest *setup)
|
|
{
|
|
u32 tx_len;
|
|
u8 *tx_payload = usb_get_setup_buffer(usb_device);
|
|
u32 bRequestType = setup->bRequestType & USB_TYPE_MASK;
|
|
log_info("%s() %x %x", __func__, bRequestType, setup->bRequest);
|
|
switch (bRequestType) {
|
|
case USB_TYPE_STANDARD:
|
|
switch (setup->bRequest) {
|
|
case USB_REQ_GET_STATUS:
|
|
usb_set_setup_phase(usb_device, USB_EP0_STAGE_SETUP);
|
|
break;
|
|
case USB_REQ_GET_INTERFACE:
|
|
tx_len = 1;
|
|
u8 i = 0;
|
|
usb_set_data_payload(usb_device, setup, &i, tx_len);
|
|
break;
|
|
case USB_REQ_SET_INTERFACE:
|
|
usb_set_setup_phase(usb_device, USB_EP0_STAGE_SETUP);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
case USB_TYPE_CLASS:
|
|
switch (setup->bRequest) {
|
|
case 0:
|
|
printer_endpoint_init(usb_device, -1);
|
|
tx_len = sizeof(device_id);
|
|
memcpy(tx_payload, device_id, sizeof(device_id));
|
|
usb_set_data_payload(usb_device, setup, tx_payload, tx_len);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
u32 printer_desc_config(const usb_dev usb_id, u8 *ptr, u32 *cur_itf_num)
|
|
{
|
|
log_debug("%s() %d", __func__, *cur_itf_num);
|
|
memcpy(ptr, printer_desc, sizeof(printer_desc));
|
|
ptr[2] = *cur_itf_num;
|
|
if (usb_set_interface_hander(usb_id, *cur_itf_num, printer_itf_hander) != *cur_itf_num) {
|
|
|
|
}
|
|
if (usb_set_reset_hander(usb_id, *cur_itf_num, reset_wakeup) != *cur_itf_num) {
|
|
|
|
}
|
|
*cur_itf_num = *cur_itf_num + 1;
|
|
return sizeof(printer_desc);
|
|
}
|
|
|
|
|
|
u32 printer_register(const usb_dev usb_id)
|
|
{
|
|
if (printer_handle == NULL) {
|
|
printer_handle = (struct usb_printer_handle *)zalloc(sizeof(struct usb_printer_handle));
|
|
if (printer_handle == NULL) {
|
|
log_error("printer_register err");
|
|
return -1;
|
|
}
|
|
log_info("printer_handle = %x", printer_handle);
|
|
os_sem_create(&wake_sem, 0);
|
|
|
|
printer_handle->ep_out_dmabuffer = usb_alloc_ep_dmabuffer(usb_id, PTR_BULK_EP_OUT, MAXP_SIZE_BULKIN + MAXP_SIZE_BULKOUT);
|
|
(usb_id, PTR_BULK_EP_OUT, MAXP_SIZE_BULKIN + MAXP_SIZE_BULKOUT);
|
|
printer_handle->wakeup_handle = printer_wakeup_handler;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
u32 printer_release()
|
|
{
|
|
if (printer_handle) {
|
|
os_sem_del(&wake_sem, 0);
|
|
free(printer_handle);
|
|
printer_handle = NULL;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
#if 0
|
|
|
|
#include "event/device_event.h"
|
|
|
|
static u8 printer_exit;
|
|
static usb_dev printer_id;
|
|
|
|
static void printer_data_handler_task(void *priv)
|
|
{
|
|
u32 len;
|
|
u8 buffer[64];
|
|
|
|
for (;;) {
|
|
os_sem_pend(&wake_sem, 0);
|
|
if (printer_exit) {
|
|
return;
|
|
}
|
|
memset(buffer, 0, sizeof(buffer));
|
|
len = usb_g_bulk_read(printer_id, PTR_BULK_EP_OUT, buffer, sizeof(buffer), 0);
|
|
printf("%s, recv_len = %d\n", __func__, len);
|
|
|
|
put_buf(buffer, len);
|
|
usb_g_bulk_write(printer_id, PTR_BULK_EP_IN, buffer, len);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
static int product_device_event_handler(struct sys_event *e)
|
|
{
|
|
int pid;
|
|
struct device_event *event = (struct device_event *)e->payload;
|
|
const char *usb_msg = (const char *)event->value;
|
|
|
|
if (e->from == DEVICE_EVENT_FROM_OTG) {
|
|
if (usb_msg[0] == 's') {
|
|
if (event->event == DEVICE_EVENT_IN) {
|
|
printf("usb %c online", usb_msg[2]);
|
|
printer_id = usb_msg[2] - '0';
|
|
printer_exit = 0;
|
|
thread_fork("printer_data_handler_task", 30, 1024, 0, &pid, printer_data_handler_task, NULL);
|
|
} else if (event->event == DEVICE_EVENT_OUT) {
|
|
printf("usb %c offline", usb_msg[2]);
|
|
printer_exit = 1;
|
|
os_sem_post(&wake_sem);
|
|
thread_kill(&pid, KILL_WAIT);
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
SYS_EVENT_STATIC_HANDLER_REGISTER(product_device_event) = {
|
|
.event_type = SYS_DEVICE_EVENT,
|
|
.prob_handler = product_device_event_handler,
|
|
.post_handler = NULL,
|
|
};
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|