doubao_chat/apps/common/usb/device/printer.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