| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311 |
- #include "include.h"
- #include "usb_com.h"
- #include "usb_hid.h"
- #include "usb_hid_desc.h"
- #if USB_HID_EN
- #define TRACE_RATE_EN 0
- #define TRACE_RATE_PERIOD 1000 // Unit: sof
- #define HID_RECV_PKS_NUM 5
- #define HID_RESUME_PREVENT_TIME 1000 // Unit: ms
- udh_t udh_0 AT(.usb_buf.usb);
- epcb_t ep_hid_tx AT(.usb_buf.usb);
- epcb_t ep_hid_rx AT(.usb_buf.usb);
- u8 ep_hid_buf_out[HID_EP_OUT_MAX_SIZE + 4] AT(.usb_buf.hid); // CRC
- u8 ep_hid_buf_in[HID_EP_IN_MAX_SIZE] AT(.usb_buf.hid);
- u32 tick_resume_prevent AT(.bss.usb_buf.hid);
- #if TRACE_RATE_EN
- static u32 statistic_sof_count;
- static u32 statistic_tx_done_count;
- #endif
- static struct {
- uint8_t ridx;
- uint8_t widx;
- uint16_t cnt;
- uint8_t data[HID_EP_IN_MAX_SIZE * HID_RECV_PKS_NUM];
- } hid_recv_cb AT(.usb_buf.hid);
- #define usb_hid_is_valid() (udh_0.valid == true)
- #define usb_hid_resume_prevent_en() {tick_resume_prevent = tick_get();}
- #define usb_hid_resume_prevent_dis() {tick_resume_prevent = 0;}
- #define usb_hid_resume_prevent_chk() (!tick_resume_prevent || !tick_check_expire(tick_resume_prevent, HID_RESUME_PREVENT_TIME))
- AT(.com_text.hid.mouse)
- static bool hid_recv_queue_push(uint8_t *data)
- {
- GLOBAL_INT_DISABLE();
- bool status = false;
- uint8_t *wptr = &hid_recv_cb.data[hid_recv_cb.widx * HID_EP_IN_MAX_SIZE];
- if (hid_recv_cb.cnt < HID_RECV_PKS_NUM) {
- memcpy(wptr, data, HID_EP_IN_MAX_SIZE);
- hid_recv_cb.widx = (hid_recv_cb.widx + 1) % HID_RECV_PKS_NUM;
- hid_recv_cb.cnt++;
- status = true;
- }
- GLOBAL_INT_RESTORE();
- return (status);
- }
- AT(.com_text.hid.mouse)
- static bool hid_recv_queue_pop(uint8_t *data)
- {
- GLOBAL_INT_DISABLE();
- bool status = false;
- uint8_t *rptr = &hid_recv_cb.data[hid_recv_cb.ridx * HID_EP_IN_MAX_SIZE];
- if (hid_recv_cb.cnt) {
- memcpy(data, rptr, HID_EP_IN_MAX_SIZE);
- hid_recv_cb.ridx = (hid_recv_cb.ridx + 1) % HID_RECV_PKS_NUM;
- hid_recv_cb.cnt--;
- status = true;
- }
- GLOBAL_INT_RESTORE();
- return (status);
- }
- AT(.com_text.hid.mouse)
- static void hid_recv_queue_clear(void)
- {
- GLOBAL_INT_DISABLE();
- hid_recv_cb.ridx = 0;
- hid_recv_cb.widx = 0;
- hid_recv_cb.cnt = 0;
- GLOBAL_INT_RESTORE();
- }
- void ude_hid_setvalid(bool valid)
- {
- udh_t *udh = &udh_0;
- udh->valid = valid;
- }
- AT(.usbdev.com)
- void ude_hid_rx_process(void)
- {
- u16 size;
- udh_t *udh = &udh_0;
- if (udh->valid) {
- size = usb_ep_get_rx_len(udh->int_out);
- usb_hid_receive_callback(udh->int_out->buf, size);
- usb_ep_clear_rx_fifo(udh->int_out);
- }
- }
- AT(.usbdev.com)
- void ude_hid_tx_process(void)
- {
- usb_hid_send_kick();
- #if TRACE_RATE_EN
- if (statistic_sof_count < (TRACE_RATE_PERIOD + 1)) {
- statistic_tx_done_count++;
- }
- #endif
- }
- AT(.com_text.isr.suspend)
- void usb_hid_suspend_callback(bool suspend)
- {
- if (suspend) {
- hid_recv_queue_clear();
- usb_hid_resume_prevent_en();
- } else {
- usb_hid_resume_prevent_dis();
- }
- }
- AT(.com_text.isr.sof)
- void usb_sof_hid_isr(void)
- {
- #if TRACE_RATE_EN
- if (statistic_sof_count < (TRACE_RATE_PERIOD + 1)) {
- statistic_sof_count++;
- }
- #endif
- }
- ///USB hid endpoint reset
- void usb_int_ep_reset(void)
- {
- udh_t *udh = &udh_0;
- /* Any usb class can't always use ep0, so it't un-init when index is zere */
- if (udh->int_in->index) {
- usb_ep_reset(udh->int_in);
- }
- if (udh->int_out->index) {
- usb_ep_reset(udh->int_out);
- }
- }
- ///USB HID 初始化
- void udh_init(void)
- {
- epcb_t *epcb;
- udh_t *udh = &udh_0;
- memset(&udh_0, 0, sizeof(udh_0));
- udh_0.int_in = &ep_hid_tx;
- udh_0.int_out = &ep_hid_rx;
- memset(udh->int_in, 0x00, sizeof(epcb_t));
- memset(udh->int_out, 0x00, sizeof(epcb_t));
- usb_ep_callback_register(ude_hid_tx_process, USB_HID_EP_IN_INDEX, EP_DIR_IN);
- usb_ep_callback_register(ude_hid_rx_process, USB_HID_EP_OUT_INDEX, EP_DIR_OUT);
- memset(ep_hid_buf_in, 0, sizeof(ep_hid_buf_in));
- epcb = udh->int_in;
- epcb->dir = EP_DIR_IN;
- epcb->index = USB_HID_EP_IN_INDEX;
- epcb->type = EP_TYPE_INTR;
- epcb->epsize = HID_EP_IN_MAX_SIZE;
- epcb->buf = ep_hid_buf_in;
- usb_ep_init(epcb);
- memset(ep_hid_buf_out, 0, sizeof(ep_hid_buf_out));
- epcb = udh->int_out;
- epcb->dir = EP_DIR_OUT;
- epcb->index = USB_HID_EP_OUT_INDEX;
- epcb->type = EP_TYPE_INTR;
- epcb->epsize = HID_EP_OUT_MAX_SIZE;
- epcb->buf = ep_hid_buf_out;
- usb_ep_init(epcb);
- ude_hid_setvalid(false);
- }
- /* START: API for upper layer */
- WEAK void usb_hid_receive_callback(uint8_t *buf, uint32_t size)
- {
- hid_rep_info_t *hid_rep_info = (hid_rep_info_t *)buf;
- printf("hid data out[%d]:\n", size);
- print_r(buf, size);
- if (hid_rep_info->report_id == HID_REP_ID_LED) {
- u8 caps_lock[1] = {(hid_rep_info->pdu.led.caps_lock)? 1: 0};
- wireless_send_ctrl_cmd(WIRELESS_CTRL_CMD_CODE_CAPS_LOCK_CHANGE, 1, caps_lock);
- }
- }
- AT(.com_text.usb.kick)
- void usb_hid_send_kick(void)
- {
- udh_t *udh = &udh_0;
- u32 size = 0;
- if (!udh->valid) {
- return;
- }
- if (usb_device_is_suspend()) {
- if (false == usb_hid_resume_prevent_chk()) {
- usb_hid_resume_prevent_dis();
- usb_device_resume();
- }
- return;
- }
- if (usb_ep_transfer(udh->int_in)) {
- usb_hid_send_prepare(udh->int_in->buf, &size);
- if (size) {
- usb_ep_start_transfer(udh->int_in, size);
- }
- }
- }
- AT(.com_text.usb.hid)
- bool usb_hid_buffer_push(uint8_t *buf, uint32_t size)
- {
- if (!usb_hid_is_valid() || usb_device_is_suspend()) {
- return false;
- }
- if ((size % HID_EP_IN_MAX_SIZE) != 0) {
- return false;
- }
- while (size && hid_recv_queue_push(buf)) {
- size -= HID_EP_IN_MAX_SIZE;
- buf += HID_EP_IN_MAX_SIZE;
- }
- // ASSERT: all data can push in queue
- if (size) {
- }
- return true;
- }
- AT(.com_text.usb.hid)
- bool usb_hid_buffer_push_check(void)
- {
- return (hid_recv_cb.cnt < HID_RECV_PKS_NUM);
- }
- AT(.com_text.usb.hid)
- void usb_hid_send_prepare(uint8_t *buf, uint32_t *size)
- {
- if (sys_cb.usb_is_active && hid_recv_queue_pop(buf)) {
- *size = HID_EP_IN_MAX_SIZE;
- } else {
- *size = 0;
- }
- }
- void usb_hid_init(void)
- {
- memset(&hid_recv_cb, 0x00, sizeof(hid_recv_cb));
- }
- void usb_hid_deinit(void)
- {
- ude_hid_setvalid(false);
- }
- #if TRACE_RATE_EN
- AT(.com_text.test)
- void usb_hid_statistic_flush(void)
- {
- GLOBAL_INT_DISABLE();
- statistic_sof_count = 0;
- statistic_tx_done_count = 0;
- GLOBAL_INT_RESTORE();
- }
- #endif
- void usb_hid_process(void)
- {
- #if TRACE_RATE_EN
- if (statistic_sof_count > TRACE_RATE_PERIOD)
- {
- printf("[USB]: %din/%dsof\n", statistic_tx_done_count, TRACE_RATE_PERIOD);
- usb_hid_statistic_flush();
- }
- #endif
- }
- #endif // USB_HID_EN
|