#include "include.h" #include "usb_com.h" #include "usb_hid.h" #include "usb_vendor.h" #include "usb_vendor_desc.h" #include "fota_proc.h" #if USB_VENDOR_EN udv_t udv_0 AT(.usb_buf.usb); epcb_t ep_vendor_tx AT(.usb_buf.usb); epcb_t ep_vendor_rx AT(.usb_buf.usb); u8 ep_vendor_buf_out[VENDOR_EP_OUT_MAX_SIZE + 4] AT(.usb_buf.vendor); // CRC u8 ep_vendor_buf_in[VENDOR_EP_IN_MAX_SIZE] AT(.usb_buf.vendor); static usb_vendor_send_tag_t usb_vendor_send_pool[5] AT(.usb_buf.vendor); static list_t usb_vendor_send_queue AT(.usb_buf.vendor); static list_t usb_vendor_free_queue AT(.usb_buf.vendor); static bool usb_vendor_is_valid(void) { return true; } void ude_vendor_setvalid(bool valid) { udv_t *udv = &udv_0; udv->valid = valid; } void usb_vendor_receive_callback(uint8_t *buf, uint32_t size) { #if (AB_FOT_CHANNEL & AB_FOT_CHANNEL_USB) usb_vendor_pdu_t *pdu = (usb_vendor_pdu_t *)buf; if (pdu->report_id == USB_VENDOR_REPORT_ID_APP) { fota_recv_packet_handle(pdu->payload, pdu->length, FOTA_CHL_USB); } #endif } AT(.com_text.usb.vendor.kick) void usb_vendor_send_prepare(uint8_t *buf, uint32_t *size) { GLOBAL_INT_DISABLE(); usb_vendor_send_tag_t *data = (usb_vendor_send_tag_t *)list_pop_front(&usb_vendor_send_queue); if (data) { memcpy(buf, &data->pdu, data->length); *size = data->length; list_push_back(&usb_vendor_free_queue, (list_hdr_t *)data); } else { *size = 0; } GLOBAL_INT_RESTORE(); } AT(.usbdev.com) void udv_rx_process(void) { u16 size; udv_t *udv = &udv_0; size = usb_ep_get_rx_len(udv->int_out); usb_vendor_receive_callback(udv->int_out->buf, size); usb_ep_clear_rx_fifo(udv->int_out); } AT(.usbdev.com) void udv_tx_process(void) { usb_vendor_send_kick(); } void usb_vendor_ep_reset(void) { udv_t *udv = &udv_0; /* Any usb class can't always use ep0, so it't un-init when index is zere */ if (udv->int_in->index) { usb_ep_reset(udv->int_in); } if (udv->int_out->index) { usb_ep_reset(udv->int_out); } } AT(.com_text.usb.vendor.kick) void usb_vendor_send_kick(void) { udv_t *udv = &udv_0; u32 size = 0; if (!usb_vendor_is_valid()) { return; } if (usb_ep_transfer(udv->int_in)) { usb_vendor_send_prepare(udv->int_in->buf, &size); if (size) { usb_ep_start_transfer(udv->int_in, size); } } } #if (AB_FOT_CHANNEL & AB_FOT_CHANNEL_USB) int usb_vendor_app_mtu_get(uint32_t *mtu) { if (!mtu) { return -1; } /* usb_vendor_pdu_t::payload */ *mtu = usb_vendor_fmt_size_get(USB_VENDOR_REPORT_ID_APP) - 2; /* No error */ return 0; } AT(.com_text.usb.vendor.xfer) int usb_vendor_app_send(uint8_t *buf, uint16_t size) { GLOBAL_INT_DISABLE(); usb_vendor_send_tag_t *free = (usb_vendor_send_tag_t *)list_pop_front(&usb_vendor_free_queue); int status = -1; /* ASSERT(size <= sizeof(usb_vendor_pdu_t::payload)) */ if (free) { free->length = usb_vendor_fmt_size_get(USB_VENDOR_REPORT_ID_APP); free->pdu.report_id = USB_VENDOR_REPORT_ID_APP; free->pdu.length = size; memcpy(free->pdu.payload, buf, size); memset(free->pdu.payload + size, 0x00, free->length - size - 1); list_push_back(&usb_vendor_send_queue, (list_hdr_t *)free); status = 0; /* No error */ thread_driver_msg_post(THREAD_DRIVER_MSG_VENDOR_IN); } GLOBAL_INT_RESTORE(); return status; } #endif // (AB_FOT_CHANNEL & AB_FOT_CHANNEL_USB) void udv_init(void) { epcb_t *epcb; udv_t *udv = &udv_0; udv_0.int_in = &ep_vendor_tx; udv_0.int_out = &ep_vendor_rx; memset(udv->int_in, 0x00, sizeof(epcb_t)); memset(udv->int_out, 0x00, sizeof(epcb_t)); usb_ep_callback_register(udv_tx_process, USB_VENDOR_EP_IN_INDEX, EP_DIR_IN); usb_ep_callback_register(udv_rx_process, USB_VENDOR_EP_OUT_INDEX, EP_DIR_OUT); memset(ep_vendor_buf_in, 0, sizeof(ep_vendor_buf_in)); epcb = udv->int_in; epcb->dir = EP_DIR_IN; epcb->index = USB_VENDOR_EP_IN_INDEX; epcb->type = EP_TYPE_INTR; epcb->epsize = VENDOR_EP_IN_MAX_SIZE; epcb->buf = ep_vendor_buf_in; usb_ep_init(epcb); memset(ep_vendor_buf_out, 0, sizeof(ep_vendor_buf_out)); epcb = udv->int_out; epcb->dir = EP_DIR_OUT; epcb->index = USB_VENDOR_EP_OUT_INDEX; epcb->type = EP_TYPE_INTR; epcb->epsize = VENDOR_EP_OUT_MAX_SIZE; epcb->buf = ep_vendor_buf_out; usb_ep_init(epcb); ude_vendor_setvalid(false); } void usb_vendor_init(void) { usb_vendor_send_queue.first = NULL; usb_vendor_send_queue.last = NULL; list_pool_init( &usb_vendor_free_queue, &usb_vendor_send_pool[0], sizeof(usb_vendor_send_pool[0]), sizeof(usb_vendor_send_pool) / sizeof(usb_vendor_send_pool[0]) ); #if (AB_FOT_CHANNEL & AB_FOT_CHANNEL_USB) ab_fota_cb_t param; param.fota_mtu_check_handle = usb_vendor_app_mtu_get; param.fota_send_packet_handle = usb_vendor_app_send; fota_init(¶m, FOTA_CHL_USB); #endif } void usb_vendor_deinit(void) { ude_vendor_setvalid(false); #if (AB_FOT_CHANNEL & AB_FOT_CHANNEL_USB) fota_disconnected_handle(FOTA_CHL_USB); #endif } void usb_vendor_process(void) { /* Add application layer initialize if need */ } #endif // USB_VENDOR_EN