123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417 |
- #include "usb_config.h"
- #include "usb/scsi.h"
- #include "irq.h"
- #include "init.h"
- #include "gpio.h"
- #include "timer.h"
- #include "app_config.h"
- #include "lbuf.h"
- #ifdef CONFIG_ADAPTER_ENABLE
- #include "adapter_usb_hid.h"
- #endif//CONFIG_ADAPTER_ENABLE
- #define LOG_TAG_CONST USB
- #define LOG_TAG "[USB]"
- #define LOG_ERROR_ENABLE
- #define LOG_DEBUG_ENABLE
- #define LOG_INFO_ENABLE
- /* #define LOG_DUMP_ENABLE */
- #define LOG_CLI_ENABLE
- #include "debug.h"
- #define SET_INTERRUPT ___interrupt
- #define MAX_EP_TX 5
- #define MAX_EP_RX 5
- static usb_interrupt usb_interrupt_tx[USB_MAX_HW_NUM][MAX_EP_TX];// SEC(.usb_g_bss);
- static usb_interrupt usb_interrupt_rx[USB_MAX_HW_NUM][MAX_EP_RX];// SEC(.usb_h_bss);
- static u8 ep0_dma_buffer[EP0_SETUP_LEN] __attribute__((aligned(4))) SEC(.usb_ep0) ;
- #if TCFG_USB_SLAVE_MSD_ENABLE
- #define MSD_DMA_SIZE (64*2)
- #else
- #define MSD_DMA_SIZE 0
- #endif
- #if TCFG_USB_SLAVE_HID_ENABLE
- #define HID_DMA_SIZE 64
- #if CONFIG_APP_DONGLE
- #define HID_DMA_SIZE 64*CONFIG_BT_GATT_CLIENT_NUM
- #endif
- #else
- #define HID_DMA_SIZE 0
- #endif
- #if TCFG_USB_CUSTOM_HID_ENABLE
- #define CUSTOM_HID_DMA_SIZE 64 * 2
- #else
- #define CUSTOM_HID_DMA_SIZE 0
- #endif
- #if TCFG_USB_SLAVE_AUDIO_ENABLE
- #define AUDIO_DMA_SIZE 256+192
- #else
- #define AUDIO_DMA_SIZE 0
- #endif
- #if TCFG_USB_SLAVE_CDC_ENABLE
- #if CDC_INTR_EP_ENABLE
- #define CDC_DMA_SIZE (64*3)
- #else
- #define CDC_DMA_SIZE (64*2)
- #endif
- #else
- #define CDC_DMA_SIZE 0
- #endif
- struct usb_config_var_t {
- u8 usb_setup_buffer[USB_SETUP_SIZE];
- struct usb_ep_addr_t usb_ep_addr;
- struct usb_setup_t usb_setup;
- };
- static struct usb_config_var_t *usb_config_var = {NULL};
- #if USB_MALLOC_ENABLE
- #else
- static struct usb_config_var_t _usb_config_var SEC(.usb_config_var);
- #endif
- #define USB_DMA_BUF_ALIGN (8)
- #ifndef USB_DMA_BUF_MAX_SIZE
- #define USB_DMA_BUF_MAX_SIZE (HID_DMA_SIZE +USB_DMA_BUF_ALIGN+ AUDIO_DMA_SIZE +USB_DMA_BUF_ALIGN+ MSD_DMA_SIZE*2 + USB_DMA_BUF_ALIGN+CDC_DMA_SIZE + USB_DMA_BUF_ALIGN + CUSTOM_HID_DMA_SIZE + USB_DMA_BUF_ALIGN+ 100)
- #endif//USB_DMA_BUF_MAX_SIZE
- static u8 usb_dma_buf[USB_DMA_BUF_MAX_SIZE] SEC(.usb_msd_dma) __attribute__((aligned(8)));
- struct lbuff_head *usb_dma_lbuf = NULL;
- void usb_memory_init()
- {
- usb_dma_lbuf = lbuf_init(usb_dma_buf, sizeof(usb_dma_buf), USB_DMA_BUF_ALIGN, 0);
- log_info("%s() total dma size %x @%x", __func__, sizeof(usb_dma_buf), usb_dma_buf);
- }
- __attribute__((always_inline_when_const_args))
- void *usb_alloc_ep_dmabuffer(const usb_dev usb_id, u32 ep, u32 dma_size)
- {
- u8 *ep_buffer = NULL;
- u32 _ep = ep & 0xf;
- if (ep & USB_DIR_IN) {
- switch (_ep) {
- case 0:
- ep_buffer = ep0_dma_buffer;
- break;
- default :
- ep_buffer = lbuf_alloc(usb_dma_lbuf, dma_size);
- break;
- }
- } else {
- switch (_ep) {
- case 0:
- ep_buffer = ep0_dma_buffer;
- break;
- default :
- ep_buffer = lbuf_alloc(usb_dma_lbuf, dma_size);
- break;
- }
- }
- ASSERT(ep_buffer, "usb_alloc_ep_dmabuffer ep_buffer = NULL!!!, _ep = %x, dma_size = %d\n", ep, dma_size);
- log_info("ep_buffer = %x, ep = %x, dma_size = %d\n", ep_buffer, ep, dma_size);
- return ep_buffer;
- }
- static u8 usb_remote_wakeup_flag = USB_READY;//0:初始状态或suspend 1:从机已发送wakeup 2:主机已被唤醒
- static u32 usb_remote_wakeup_cnt = 0;
- static void usb_resume_sign(void *priv)
- {
- usb_remote_wakeup_flag = USB_RESUME_WAIT;
- usb_remote_wakeup_cnt = 0;
- log_info("slave remote_wakeup host signal has been sent");
- usb_dev usb_id = usb_device2id(priv);
- u32 reg = usb_read_power(usb_id);
- usb_write_power(usb_id, reg | BIT(2));//send resume
- os_time_dly(2);//10ms~20ms
- usb_write_power(usb_id, reg);//clean resume
- usb_sof_isr_reg(usb_id, 3, 0);
- }
- static u16 Wakeup_detect_timer;
- void usb_remote_wakeup_detect(void *priv)
- {
- if (usb_remote_wakeup_flag != USB_RESUME_WAIT) {
- return ;
- }
- if (usb_remote_wakeup_cnt == 0) {
- usb_remote_wakeup_flag = USB_SUSPEND;
- log_info("Wakeup fail!!! no SOF packet receive!\n");
- }
- if (usb_remote_wakeup_cnt > USB_REMOTE_WAKEUP_TIMEOUT_DETECT_TIMES - 200) {
- usb_remote_wakeup_flag = USB_READY;
- log_info("Receive %d SOF packet, USB ready!\n", usb_remote_wakeup_cnt);
- } else {
- usb_remote_wakeup_flag = USB_READY;
- log_info("Receive %d SOF packet, please increase USB_REMOTE_WAKEUP_TIMEOUT_DETECT_TIMES\n", usb_remote_wakeup_cnt);
- }
- }
- void usb_remote_wakeup(const usb_dev usb_id)
- {
- struct usb_device_t *usb_device = usb_id2device(usb_id);
- if (usb_device->bRemoteWakup) {
- sys_timeout_add(usb_device, usb_remote_wakeup_detect, USB_REMOTE_WAKEUP_TIMEOUT_DETECT_TIMES);
- sys_timeout_add(usb_device, usb_resume_sign, 1);
- } else {
- usb_device->bRemoteWakup = 1;
- }
- }
- void usb_phy_resume(const usb_dev usb_id)
- {
- usb_iomode(0);
- struct usb_device_t *usb_device = usb_id2device(usb_id);
- usb_write_faddr(usb_id, usb_device->baddr);
- if (usb_device->baddr == 0) {
- usb_device->bDeviceStates = USB_DEFAULT;
- } else {
- usb_device->bDeviceStates = USB_CONFIGURED;
- }
- usb_otg_resume(usb_id);
- }
- void usb_phy_suspend(const usb_dev usb_id)
- {
- gpio_set_pull_up(IO_PORT_DP, 1);
- gpio_set_pull_down(IO_PORT_DP, 0);
- gpio_set_direction(IO_PORT_DP, 1);
- usb_iomode(1);
- /* musb_read_usb(0, MUSB_INTRUSB); */
- usb_otg_suspend(usb_id, OTG_KEEP_STATE);
- }
- u32 usb_get_suspend_resume_status(const usb_dev usb_id)
- {
- switch (usb_remote_wakeup_flag) {
- case USB_READY:
- //log_info("USB READY\n");
- putchar('R');
- break;
- case USB_SUSPEND:
- log_info("USB SUSPEND\n");
- break;
- case USB_RESUME_WAIT:
- log_info("USB remote_wakeup send, RESUME WAIT\n");
- break;
- case USB_RESUME_OK://保留状态,未使用
- log_info("USB RESUME OK\n");
- break;
- default:
- break;
- }
- return usb_remote_wakeup_flag;
- }
- void usb_isr(const usb_dev usb_id)
- {
- u32 intr_usb, intr_usbe;
- u32 intr_tx, intr_txe;
- u32 intr_rx, intr_rxe;
- __asm__ volatile("ssync");
- usb_read_intr(usb_id, &intr_usb, &intr_tx, &intr_rx);
- usb_read_intre(usb_id, &intr_usbe, &intr_txe, &intr_rxe);
- struct usb_device_t *usb_device = usb_id2device(usb_id);
- intr_usb &= intr_usbe;
- intr_tx &= intr_txe;
- intr_rx &= intr_rxe;
- if (intr_usb & INTRUSB_SUSPEND) {
- log_error("usb suspend");
- usb_remote_wakeup_flag = USB_SUSPEND;
- #if USB_SUSPEND_RESUME
- usb_phy_suspend(usb_id);
- #endif
- #if USB_SUSPEND_RESUME_SYSTEM_NO_SLEEP
- printf("\n NULL \n");
- #endif
- }
- if (intr_usb & INTRUSB_RESET_BABBLE) {
- log_error("usb reset");
- usb_reset_interface(usb_device);
- #if USB_SUSPEND_RESUME || USB_SUSPEND_RESUME_SYSTEM_NO_SLEEP
- u32 reg = usb_read_power(usb_id);
- usb_write_power(usb_id, (reg | INTRUSB_SUSPEND | INTRUSB_RESUME));//enable suspend resume
- #endif
- }
- if (intr_usb & INTRUSB_RESUME) {
- log_error("usb resume");
- #if USB_SUSPEND_RESUME
- usb_phy_resume(usb_id);
- #endif
- }
- if (intr_tx & BIT(0)) {
- if (usb_interrupt_rx[usb_id][0]) {
- usb_interrupt_rx[usb_id][0](usb_device, 0);
- } else {
- #if USB_SUSPEND_RESUME || USB_SUSPEND_RESUME_SYSTEM_NO_SLEEP
- if (usb_remote_wakeup_flag == USB_RESUME_WAIT) {
- if (usb_device->bsetup_phase == USB_EP0_STAGE_SETUP) {
- usb_remote_wakeup_flag = USB_READY;
- log_info("receive setup packet");
- }
- }
- #endif
- usb_control_transfer(usb_device);
- }
- }
- for (int i = 1; i < MAX_EP_TX; i++) {
- if (intr_tx & BIT(i)) {
- if (usb_interrupt_tx[usb_id][i]) {
- usb_interrupt_tx[usb_id][i](usb_device, i);
- }
- }
- }
- for (int i = 1; i < MAX_EP_RX; i++) {
- if (intr_rx & BIT(i)) {
- if (usb_interrupt_rx[usb_id][i]) {
- usb_interrupt_rx[usb_id][i](usb_device, i);
- }
- }
- }
- __asm__ volatile("csync");
- }
- void usb_sof_isr(const usb_dev usb_id)
- {
- usb_sof_clr_pnd(usb_id);
- static u32 sof_count = 0;
- #if USB_SUSPEND_RESUME || USB_SUSPEND_RESUME_SYSTEM_NO_SLEEP
- usb_remote_wakeup_cnt++;
- #else
- if ((sof_count++ % 1000) == 0) {
- log_d("sof 1s isr frame:%d", usb_read_sofframe(usb_id));
- }
- #endif
- }
- void usb_suspend_check(void *p)
- {
- usb_dev usb_id = (usb_dev)p;
- static u16 sof_frame = 0;
- u16 frame = usb_read_sofframe(usb_id);// sof frame 不更新,则usb进入断开或者suspend状态
- if (frame == sof_frame) {
- usb_phy_suspend(usb_id);
- }
- sof_frame = frame;
- }
- SET_INTERRUPT
- void usb0_g_isr()
- {
- usb_isr(0);
- }
- SET_INTERRUPT
- void usb0_sof_isr()
- {
- usb_sof_isr(0);
- }
- #if USB_MAX_HW_NUM == 2
- SET_INTERRUPT
- void usb1_g_isr()
- {
- usb_isr(1);
- }
- SET_INTERRUPT
- void usb1_sof_isr()
- {
- usb_sof_isr(1);
- }
- #endif
- __attribute__((always_inline_when_const_args))
- u32 usb_g_set_intr_hander(const usb_dev usb_id, u32 ep, usb_interrupt hander)
- {
- if (ep & USB_DIR_IN) {
- usb_interrupt_tx[usb_id][ep & 0xf] = hander;
- } else {
- usb_interrupt_rx[usb_id][ep] = hander;
- }
- return 0;
- }
- void usb_g_isr_reg(const usb_dev usb_id, u8 priority, u8 cpu_id)
- {
- if (usb_id == 0) {
- request_irq(IRQ_USB_CTRL_IDX, priority, usb0_g_isr, cpu_id);
- } else {
- #if USB_MAX_HW_NUM == 2
- request_irq(IRQ_USB1_CTRL_IDX, priority, usb1_g_isr, cpu_id);
- #endif
- }
- }
- void usb_sof_isr_reg(const usb_dev usb_id, u8 priority, u8 cpu_id)
- {
- if (usb_id == 0) {
- request_irq(IRQ_USB_SOF_IDX, priority, usb0_sof_isr, cpu_id);
- } else {
- #if USB_MAX_HW_NUM == 2
- request_irq(IRQ_USB1_SOF_IDX, priority, usb1_sof_isr, cpu_id);
- #endif
- }
- usb_sofie_enable(usb_id);
- }
- u32 usb_config(const usb_dev usb_id)
- {
- memset(usb_interrupt_rx[usb_id], 0, sizeof(usb_interrupt_rx[usb_id]));
- memset(usb_interrupt_tx[usb_id], 0, sizeof(usb_interrupt_tx[usb_id]));
- if (!usb_config_var) {
- #if USB_MALLOC_ENABLE
- usb_config_var = (struct usb_config_var_t *)zalloc(sizeof(struct usb_config_var_t));
- if (!usb_config_var) {
- return -1;
- }
- #else
- memset(&_usb_config_var, 0, sizeof(_usb_config_var));
- usb_config_var = &_usb_config_var;
- #endif
- }
- log_debug("zalloc: usb_config_var = %x\n", usb_config_var);
- usb_var_init(usb_id, &(usb_config_var->usb_ep_addr));
- usb_setup_init(usb_id, &(usb_config_var->usb_setup), usb_config_var->usb_setup_buffer);
- return 0;
- }
- u32 usb_release(const usb_dev usb_id)
- {
- log_debug("free zalloc: usb_config_var = %x\n", usb_id, usb_config_var);
- usb_var_init(usb_id, NULL);
- usb_setup_init(usb_id, NULL, NULL);
- #if USB_MALLOC_ENABLE
- if (usb_config_var) {
- log_debug("free: usb_config_var = %x\n", usb_config_var);
- free(usb_config_var);
- }
- #endif
- usb_config_var = NULL;
- return 0;
- }
|