1 /*
2  * Copyright (c) 2021-2024 HPMicro
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 /*
8  * Copyright (c) 2024, sakumisu
9  *
10  * SPDX-License-Identifier: Apache-2.0
11  */
12 #include "usbd_core.h"
13 #include "usb_chipidea_reg.h"
14 
15 #define USB_OTG_DEV ((CHIPIDEA_TypeDef *)g_usbdev_bus[busid].reg_base)
16 
17 #define CHIPIDEA_BITSMASK(val, offset) ((uint32_t)(val) << (offset))
18 #define QTD_COUNT_EACH_ENDPOINT        (8U)
19 
20 #ifndef CONFIG_USBDEV_EP_NUM
21 #define CONFIG_USBDEV_EP_NUM 8
22 #endif
23 
24 /* ENDPTCTRL */
25 enum {
26     ENDPTCTRL_STALL = CHIPIDEA_BITSMASK(1, 0),
27     ENDPTCTRL_TYPE = CHIPIDEA_BITSMASK(3, 2),
28     ENDPTCTRL_TOGGLE_INHIBIT = CHIPIDEA_BITSMASK(1, 5),
29     ENDPTCTRL_TOGGLE_RESET = CHIPIDEA_BITSMASK(1, 6),
30     ENDPTCTRL_ENABLE = CHIPIDEA_BITSMASK(1, 7),
31 };
32 
33 /* USBSTS, USBINTR */
34 enum {
35     intr_usb = CHIPIDEA_BITSMASK(1, 0),
36     intr_error = CHIPIDEA_BITSMASK(1, 1),
37     intr_port_change = CHIPIDEA_BITSMASK(1, 2),
38     intr_reset = CHIPIDEA_BITSMASK(1, 6),
39     intr_sof = CHIPIDEA_BITSMASK(1, 7),
40     intr_suspend = CHIPIDEA_BITSMASK(1, 8),
41     intr_nak = CHIPIDEA_BITSMASK(1, 16)
42 };
43 
44 /* Queue Transfer Descriptor */
45 typedef struct {
46     /* Word 0: Next QTD Pointer */
47     volatile uint32_t next; /* Next link pointer This field contains the physical memory address of the next dTD to be processed */
48 
49     /* Word 1: qTQ Token */
50     volatile uint32_t                   : 3;
51     volatile uint32_t xact_err          : 1;
52     volatile uint32_t                   : 1;
53     volatile uint32_t buffer_err        : 1;
54     volatile uint32_t halted            : 1;
55     volatile uint32_t active            : 1;
56     volatile uint32_t                   : 2;
57     volatile uint32_t iso_mult_override : 2; /* This field can be used for transmit ISOs to override the MULT field in the dQH. This field must be zero for all packet types that are not transmit-ISO. */
58     volatile uint32_t                   : 3;
59     volatile uint32_t int_on_complete   : 1;
60     volatile uint32_t total_bytes       : 15;
61     volatile uint32_t                   : 0;
62 
63     /* Word 2-6: Buffer Page Pointer List, Each element in the list is a 4K page aligned, physical memory address. The lower 12 bits in each pointer are reserved (except for the first one) as each memory pointer must reference the start of a 4K page */
64     volatile uint32_t buffer[5];
65 
66     /*------------- DCD Area -------------*/
67     volatile uint16_t expected_bytes;
68     volatile uint8_t reserved[2];
69 } dcd_qtd_t;
70 
71 /* Queue Head */
72 typedef struct {
73     /* Word 0: Capabilities and Characteristics */
74 
75     volatile uint32_t                         : 15; /* Number of packets executed per transaction descriptor 00 - Execute N transactions as demonstrated by the USB variable length protocol where N is computed using Max_packet_length and the Total_bytes field in the dTD. 01 - Execute one transaction 10 - Execute two transactions 11 - Execute three transactions Remark: Non-isochronous endpoints must set MULT = 00. Remark: Isochronous endpoints must set MULT = 01, 10, or 11 as needed. */
76     volatile uint32_t int_on_setup            : 1;  /* Interrupt on setup This bit is used on control type endpoints to indicate if USBINT is set in response to a setup being received. */
77     volatile uint32_t max_packet_size         : 11; /* This directly corresponds to the maximum packet size of the associated endpoint (wMaxPacketSize) */
78     volatile uint32_t                         : 2;
79     volatile uint32_t zero_length_termination : 1; /* This bit is used for non-isochronous endpoints to indicate when a zero-length packet is received to terminate transfers in case the total transfer length is “multiple”. 0 - Enable zero-length packet to terminate transfers equal to a multiple of Max_packet_length (default). 1 - Disable zero-length packet on transfers that are equal in length to a multiple Max_packet_length. */
80     volatile uint32_t iso_mult                : 2;
81     volatile uint32_t                         : 0;
82 
83     /* Word 1: Current qTD Pointer */
84     volatile uint32_t qtd_addr;
85 
86     /* Word 2-9: Transfer Overlay */
87     volatile dcd_qtd_t qtd_overlay;
88 
89     /* Word 10-11: Setup request (control OUT only) */
90     volatile struct usb_setup_packet setup_request;
91 
92     /*--------------------------------------------------------------------
93      * Due to the fact QHD is 64 bytes aligned but occupies only 48 bytes
94      * thus there are 16 bytes padding free that we can make use of.
95      *--------------------------------------------------------------------
96      */
97     volatile uint8_t reserved[16];
98 } dcd_qhd_t;
99 
100 typedef struct {
101     dcd_qhd_t qhd[CONFIG_USBDEV_EP_NUM * 2];
102     dcd_qtd_t qtd[CONFIG_USBDEV_EP_NUM * 2 * QTD_COUNT_EACH_ENDPOINT];
103 } dcd_data_t;
104 
105 /* Endpoint state */
106 struct chipidea_ep_state {
107     uint16_t ep_mps;    /* Endpoint max packet size */
108     uint8_t ep_type;    /* Endpoint type */
109     uint8_t ep_stalled; /* Endpoint stall flag */
110     uint8_t ep_enable;  /* Endpoint enable */
111     uint8_t *xfer_buf;
112     uint32_t xfer_len;
113     uint32_t actual_xfer_len;
114 };
115 
116 /* Driver state */
117 struct chipidea_udc {
118     dcd_data_t *dcd_data;
119     bool is_suspend;
120     struct chipidea_ep_state in_ep[CONFIG_USBDEV_EP_NUM];  /*!< IN endpoint parameters*/
121     struct chipidea_ep_state out_ep[CONFIG_USBDEV_EP_NUM]; /*!< OUT endpoint parameters */
122 } g_chipidea_udc[CONFIG_USBDEV_MAX_BUS];
123 
124 static USB_NOCACHE_RAM_SECTION __attribute__((aligned(2048))) dcd_data_t _dcd_data0;
125 #if CONFIG_USBDEV_MAX_BUS == 2
126 static USB_NOCACHE_RAM_SECTION __attribute__((aligned(2048))) dcd_data_t _dcd_data1;
127 #endif
128 
129 static dcd_data_t *g_dcd_data[CONFIG_USBDEV_MAX_BUS] = {
130     &_dcd_data0,
131 #if CONFIG_USBDEV_MAX_BUS == 2
132     &_dcd_data1
133 #endif
134 };
135 
136 /* Index to bit position in register */
ep_idx2bit(uint8_t ep_idx)137 static inline uint8_t ep_idx2bit(uint8_t ep_idx)
138 {
139     return ep_idx / 2 + ((ep_idx % 2) ? 16 : 0);
140 }
141 
__chipidea_bus_reset(CHIPIDEA_TypeDef * ptr)142 static void __chipidea_bus_reset(CHIPIDEA_TypeDef *ptr)
143 {
144     /* The reset value for all endpoint types is the control endpoint. If one endpoint
145      * direction is enabled and the paired endpoint of opposite direction is disabled, then the
146      * endpoint type of the unused direction must be changed from the control type to any other
147      * type (e.g. bulk). Leaving an un-configured endpoint control will cause undefined behavior
148      * for the data PID tracking on the active endpoint.
149      */
150 
151     for (uint32_t i = 1; i < CONFIG_USBDEV_EP_NUM; i++) {
152         ptr->ENDPTCTRL[i] = USB_ENDPTCTRL_TXT_SET(USB_ENDPOINT_TYPE_BULK) | USB_ENDPTCTRL_RXT_SET(USB_ENDPOINT_TYPE_BULK);
153     }
154 
155     /* Clear All Registers */
156     ptr->ENDPTNAK = ptr->ENDPTNAK;
157     ptr->ENDPTNAKEN = 0;
158     ptr->USBSTS = ptr->USBSTS;
159     ptr->ENDPTSETUPSTAT = ptr->ENDPTSETUPSTAT;
160     ptr->ENDPTCOMPLETE = ptr->ENDPTCOMPLETE;
161 
162     while (ptr->ENDPTPRIME) {
163     }
164     ptr->ENDPTFLUSH = 0xFFFFFFFF;
165     while (ptr->ENDPTFLUSH) {
166     }
167 }
168 
chipidea_init(CHIPIDEA_TypeDef * ptr)169 static void chipidea_init(CHIPIDEA_TypeDef *ptr)
170 {
171     /* Reset controller */
172     ptr->USBCMD |= USB_USBCMD_RST_MASK;
173     while (USB_USBCMD_RST_GET(ptr->USBCMD)) {
174     }
175 
176     /* Set mode to device, must be set immediately after reset */
177     ptr->USBMODE &= ~USB_USBMODE_CM_MASK;
178     ptr->USBMODE |= USB_USBMODE_CM_SET(2);
179 
180     /* Disable setup lockout, please refer to "Control Endpoint Operation" section in RM. */
181     ptr->USBMODE &= ~USB_USBMODE_SLOM_MASK;
182 
183     /* Set the endian */
184     ptr->USBMODE &= ~USB_USBMODE_ES_MASK;
185 
186     /* Set parallel interface signal */
187     ptr->PORTSC1 &= ~USB_PORTSC1_STS_MASK;
188 
189     /* Set parallel transceiver width */
190     ptr->PORTSC1 &= ~USB_PORTSC1_PTW_MASK;
191 
192     /* Set usb forced to full speed mode */
193     //ptr->PORTSC1 |= USB_PORTSC1_PFSC_MASK;
194 
195     /* Not use interrupt threshold. */
196     ptr->USBCMD &= ~USB_USBCMD_ITC_MASK;
197 
198     /* Enable VBUS discharge */
199     ptr->OTGSC |= USB_OTGSC_VD_MASK;
200 }
201 
chipidea_deinit(CHIPIDEA_TypeDef * ptr)202 static void chipidea_deinit(CHIPIDEA_TypeDef *ptr)
203 {
204     /* Stop */
205     ptr->USBCMD &= ~USB_USBCMD_RS_MASK;
206 
207     /* Reset controller */
208     ptr->USBCMD |= USB_USBCMD_RST_MASK;
209     while (USB_USBCMD_RST_GET(ptr->USBCMD)) {
210     }
211 
212     /* Reset endpoint list address register */
213     ptr->ENDPTLISTADDR = 0;
214 
215     /* Reset status register */
216     ptr->USBSTS = ptr->USBSTS;
217 
218     /* Reset interrupt enable register */
219     ptr->USBINTR = 0;
220 }
221 
222 /*---------------------------------------------------------------------
223  * Endpoint API
224  *---------------------------------------------------------------------
225  */
__chipidea_edpt_open(CHIPIDEA_TypeDef * ptr,uint8_t ep_addr,uint8_t ep_type)226 static void __chipidea_edpt_open(CHIPIDEA_TypeDef *ptr, uint8_t ep_addr, uint8_t ep_type)
227 {
228     uint8_t const epnum = ep_addr & 0x0f;
229     uint8_t const dir = (ep_addr & 0x80) >> 7;
230 
231     /* Enable EP Control */
232     uint32_t temp = ptr->ENDPTCTRL[epnum];
233     temp &= ~((0x03 << 2) << (dir ? 16 : 0));
234     temp |= ((ep_type << 2) | ENDPTCTRL_ENABLE | ENDPTCTRL_TOGGLE_RESET) << (dir ? 16 : 0);
235     ptr->ENDPTCTRL[epnum] = temp;
236 }
237 
chipidea_edpt_xfer(CHIPIDEA_TypeDef * ptr,uint8_t ep_idx)238 static void chipidea_edpt_xfer(CHIPIDEA_TypeDef *ptr, uint8_t ep_idx)
239 {
240     uint32_t offset = ep_idx / 2 + ((ep_idx % 2) ? 16 : 0);
241 
242     /* Start transfer */
243     ptr->ENDPTPRIME = 1 << offset;
244 }
245 
chipidea_edpt_stall(CHIPIDEA_TypeDef * ptr,uint8_t ep_addr)246 static void chipidea_edpt_stall(CHIPIDEA_TypeDef *ptr, uint8_t ep_addr)
247 {
248     uint8_t const epnum = ep_addr & 0x0f;
249     uint8_t const dir = (ep_addr & 0x80) >> 7;
250 
251     ptr->ENDPTCTRL[epnum] |= ENDPTCTRL_STALL << (dir ? 16 : 0);
252 }
253 
chipidea_edpt_clear_stall(CHIPIDEA_TypeDef * ptr,uint8_t ep_addr)254 static void chipidea_edpt_clear_stall(CHIPIDEA_TypeDef *ptr, uint8_t ep_addr)
255 {
256     uint8_t const epnum = ep_addr & 0x0f;
257     uint8_t const dir = (ep_addr & 0x80) >> 7;
258 
259     /* data toggle also need to be reset */
260     ptr->ENDPTCTRL[epnum] |= ENDPTCTRL_TOGGLE_RESET << (dir ? 16 : 0);
261     ptr->ENDPTCTRL[epnum] &= ~(ENDPTCTRL_STALL << (dir ? 16 : 0));
262 }
263 
chipidea_edpt_check_stall(CHIPIDEA_TypeDef * ptr,uint8_t ep_addr)264 static bool chipidea_edpt_check_stall(CHIPIDEA_TypeDef *ptr, uint8_t ep_addr)
265 {
266     uint8_t const epnum = ep_addr & 0x0f;
267     uint8_t const dir = (ep_addr & 0x80) >> 7;
268 
269     return (ptr->ENDPTCTRL[epnum] & (ENDPTCTRL_STALL << (dir ? 16 : 0))) ? true : false;
270 }
271 
chipidea_edpt_close(CHIPIDEA_TypeDef * ptr,uint8_t ep_addr)272 static void chipidea_edpt_close(CHIPIDEA_TypeDef *ptr, uint8_t ep_addr)
273 {
274     uint8_t const epnum = ep_addr & 0x0f;
275     uint8_t const dir = (ep_addr & 0x80) >> 7;
276 
277     uint32_t primebit = CHIPIDEA_BITSMASK(1, epnum) << (dir ? 16 : 0);
278 
279     /* Flush the endpoint to stop a transfer. */
280     do {
281         /* Set the corresponding bit(s) in the ENDPTFLUSH register */
282         ptr->ENDPTFLUSH |= primebit;
283 
284         /* Wait until all bits in the ENDPTFLUSH register are cleared. */
285         while (0U != (ptr->ENDPTFLUSH & primebit)) {
286         }
287         /*
288          * Read the ENDPTSTAT register to ensure that for all endpoints
289          * commanded to be flushed, that the corresponding bits
290          * are now cleared.
291          */
292     } while (0U != (ptr->ENDPTSTAT & primebit));
293 
294     /* Disable the endpoint */
295     ptr->ENDPTCTRL[epnum] &= ~((ENDPTCTRL_TYPE | ENDPTCTRL_ENABLE | ENDPTCTRL_STALL) << (dir ? 16 : 0));
296     ptr->ENDPTCTRL[epnum] |= (USB_ENDPOINT_TYPE_BULK << 2) << (dir ? 16 : 0);
297 }
298 
299 /* Initialize qtd */
usb_qtd_init(dcd_qtd_t * p_qtd,void * data_ptr,uint16_t total_bytes)300 static void usb_qtd_init(dcd_qtd_t *p_qtd, void *data_ptr, uint16_t total_bytes)
301 {
302     memset(p_qtd, 0, sizeof(dcd_qtd_t));
303 
304     p_qtd->next = 1;
305     p_qtd->active = 1;
306     p_qtd->total_bytes = p_qtd->expected_bytes = total_bytes;
307 
308     if (data_ptr != NULL) {
309         p_qtd->buffer[0] = (uint32_t)data_ptr;
310         for (uint8_t i = 1; i < 5; i++) {
311             p_qtd->buffer[i] = ((p_qtd->buffer[i - 1]) & 0xFFFFF000UL) + 4096U;
312         }
313     }
314 }
315 
chipidea_qhd_get(uint8_t busid,uint8_t ep_idx)316 static dcd_qhd_t *chipidea_qhd_get(uint8_t busid, uint8_t ep_idx)
317 {
318     dcd_data_t *dcd_data;
319 
320     dcd_data = g_chipidea_udc[busid].dcd_data;
321     return &dcd_data->qhd[ep_idx];
322 }
323 
chipidea_qtd_get(uint8_t busid,uint8_t ep_idx)324 static dcd_qtd_t *chipidea_qtd_get(uint8_t busid, uint8_t ep_idx)
325 {
326     dcd_data_t *dcd_data;
327 
328     dcd_data = g_chipidea_udc[busid].dcd_data;
329     return &dcd_data->qtd[ep_idx * QTD_COUNT_EACH_ENDPOINT];
330 }
331 
chipidea_bus_reset(uint8_t busid,uint16_t ep0_max_packet_size)332 static void chipidea_bus_reset(uint8_t busid, uint16_t ep0_max_packet_size)
333 {
334     dcd_data_t *dcd_data;
335 
336     dcd_data = g_chipidea_udc[busid].dcd_data;
337     __chipidea_bus_reset(USB_OTG_DEV);
338 
339     /* Queue Head & Queue TD */
340     memset(dcd_data, 0, sizeof(dcd_data_t));
341 
342     /* Set up Control Endpoints (0 OUT, 1 IN) */
343     dcd_data->qhd[0].zero_length_termination = dcd_data->qhd[1].zero_length_termination = 1;
344     dcd_data->qhd[0].max_packet_size = dcd_data->qhd[1].max_packet_size = ep0_max_packet_size;
345     dcd_data->qhd[0].qtd_overlay.next = dcd_data->qhd[1].qtd_overlay.next = 1;
346 
347     /* OUT only */
348     dcd_data->qhd[0].int_on_setup = 1;
349 }
350 
chipidea_edpt_open(uint8_t busid,uint8_t ep_addr,uint8_t ep_type,uint16_t ep_mps)351 static void chipidea_edpt_open(uint8_t busid, uint8_t ep_addr, uint8_t ep_type, uint16_t ep_mps)
352 {
353     uint8_t const epnum = ep_addr & 0x0f;
354     uint8_t const dir = (ep_addr & 0x80) >> 7;
355     uint8_t const ep_idx = 2 * epnum + dir;
356     dcd_data_t *dcd_data;
357     dcd_qhd_t *p_qhd;
358 
359     /* Prepare Queue Head */
360     dcd_data = g_chipidea_udc[busid].dcd_data;
361     p_qhd = &dcd_data->qhd[ep_idx];
362     memset(p_qhd, 0, sizeof(dcd_qhd_t));
363 
364     p_qhd->zero_length_termination = 1;
365     p_qhd->max_packet_size = ep_mps & 0x7FFu;
366     p_qhd->qtd_overlay.next = 1;
367     if (ep_type == USB_ENDPOINT_TYPE_ISOCHRONOUS) {
368         p_qhd->iso_mult = ((ep_mps >> 11u) & 0x3u) + 1u;
369     }
370 
371     __chipidea_edpt_open(USB_OTG_DEV, ep_addr, ep_type);
372 }
373 
chipidea_start_xfer(uint8_t busid,uint8_t ep_addr,uint8_t * buffer,uint32_t total_bytes)374 static bool chipidea_start_xfer(uint8_t busid, uint8_t ep_addr, uint8_t *buffer, uint32_t total_bytes)
375 {
376     uint8_t const epnum = ep_addr & 0x0f;
377     uint8_t const dir = (ep_addr & 0x80) >> 7;
378     uint8_t const ep_idx = 2 * epnum + dir;
379     uint8_t qtd_num;
380     uint8_t i;
381     uint32_t xfer_len;
382     dcd_qhd_t *p_qhd;
383     dcd_qtd_t *p_qtd;
384     dcd_qtd_t *first_p_qtd = NULL;
385     dcd_qtd_t *prev_p_qtd = NULL;
386     dcd_data_t *dcd_data;
387 
388     dcd_data = g_chipidea_udc[busid].dcd_data;
389 
390     if (epnum == 0) {
391         /* follows UM Setup packet handling using setup lockout mechanism
392          * wait until ENDPTSETUPSTAT before priming data/status in response TODO add time out
393          */
394         while (USB_OTG_DEV->ENDPTSETUPSTAT & CHIPIDEA_BITSMASK(1, 0)) {
395         }
396     }
397 
398     qtd_num = (total_bytes + 0x3fff) / 0x4000;
399     if (qtd_num > QTD_COUNT_EACH_ENDPOINT) {
400         return false;
401     }
402 
403     if (buffer != NULL) {
404         buffer = (uint8_t *)buffer;
405     }
406     p_qhd = &dcd_data->qhd[ep_idx];
407     i = 0;
408     do {
409         p_qtd = &dcd_data->qtd[ep_idx * QTD_COUNT_EACH_ENDPOINT + i];
410         i++;
411 
412         if (total_bytes > 0x4000) {
413             xfer_len = 0x4000;
414             total_bytes -= 0x4000;
415         } else {
416             xfer_len = total_bytes;
417             total_bytes = 0;
418         }
419 
420         usb_qtd_init(p_qtd, (void *)buffer, xfer_len);
421         if (total_bytes == 0) {
422             p_qtd->int_on_complete = true;
423         }
424         buffer += xfer_len;
425 
426         if (prev_p_qtd) {
427             prev_p_qtd->next = (uint32_t)p_qtd;
428         } else {
429             first_p_qtd = p_qtd;
430         }
431         prev_p_qtd = p_qtd;
432     } while (total_bytes > 0);
433 
434     p_qhd->qtd_overlay.next = (uint32_t)first_p_qtd; /* link qtd to qhd */
435 
436     chipidea_edpt_xfer(USB_OTG_DEV, ep_idx);
437 
438     return true;
439 }
440 
usb_dc_low_level_init(uint8_t busid)441 __WEAK void usb_dc_low_level_init(uint8_t busid)
442 {
443 }
444 
usb_dc_low_level_deinit(uint8_t busid)445 __WEAK void usb_dc_low_level_deinit(uint8_t busid)
446 {
447 }
448 
usb_dc_init(uint8_t busid)449 int usb_dc_init(uint8_t busid)
450 {
451     uint32_t int_mask;
452     int_mask = (USB_USBINTR_UE_MASK | USB_USBINTR_UEE_MASK | USB_USBINTR_SLE_MASK |
453                 USB_USBINTR_PCE_MASK | USB_USBINTR_URE_MASK);
454 
455     usb_dc_low_level_init(busid);
456 
457     memset(&g_chipidea_udc[busid], 0, sizeof(struct chipidea_udc));
458     g_chipidea_udc[busid].dcd_data = g_dcd_data[busid];
459     memset(g_chipidea_udc[busid].dcd_data, 0, sizeof(dcd_data_t));
460 
461     chipidea_init(USB_OTG_DEV);
462 
463     /* Set endpoint list address */
464     USB_OTG_DEV->ENDPTLISTADDR = ((uint32_t)g_chipidea_udc[busid].dcd_data->qhd) & USB_ENDPTLISTADDR_EPBASE_MASK;
465 
466     /* Clear status */
467     USB_OTG_DEV->USBSTS = USB_OTG_DEV->USBSTS;
468 
469 #ifdef CONFIG_USBDEV_SOF_ENABLE
470     int_mask |= USB_USBINTR_SRE_MASK;
471 #endif
472 
473     /* Enable interrupt mask */
474     USB_OTG_DEV->USBINTR |= int_mask;
475 
476     /* Connect by enabling internal pull-up resistor on D+/D- */
477     USB_OTG_DEV->USBCMD |= USB_USBCMD_RS_MASK;
478     return 0;
479 }
480 
usb_dc_deinit(uint8_t busid)481 int usb_dc_deinit(uint8_t busid)
482 {
483     chipidea_deinit(USB_OTG_DEV);
484 
485     for (uint32_t i = 0; i < CONFIG_USBDEV_EP_NUM; i++) {
486         chipidea_edpt_close(USB_OTG_DEV, (i | 0x80));
487         chipidea_edpt_close(USB_OTG_DEV, (i | 0x00));
488     }
489 
490     usb_dc_low_level_deinit(busid);
491     return 0;
492 }
493 
usbd_set_address(uint8_t busid,const uint8_t addr)494 int usbd_set_address(uint8_t busid, const uint8_t addr)
495 {
496     USB_OTG_DEV->DEVICEADDR = USB_DEVICEADDR_USBADR_SET(addr) | USB_DEVICEADDR_USBADRA_MASK;
497     return 0;
498 }
499 
usbd_set_remote_wakeup(uint8_t busid)500 int usbd_set_remote_wakeup(uint8_t busid)
501 {
502     if (!USB_PORTSC1_SUSP_GET(USB_OTG_DEV->PORTSC1)) {
503         return -1;
504     }
505 
506     USB_OTG_DEV->PORTSC1 |= USB_PORTSC1_FPR_MASK;
507     while (USB_OTG_DEV->PORTSC1 & USB_PORTSC1_FPR_MASK) {
508     }
509 
510     return 0;
511 }
512 
usbd_get_port_speed(uint8_t busid)513 uint8_t usbd_get_port_speed(uint8_t busid)
514 {
515     uint8_t speed;
516 
517     speed = USB_PORTSC1_PSPD_GET(USB_OTG_DEV->PORTSC1);
518 
519     if (speed == 0x00) {
520         return USB_SPEED_FULL;
521     }
522     if (speed == 0x01) {
523         return USB_SPEED_LOW;
524     }
525     if (speed == 0x02) {
526         return USB_SPEED_HIGH;
527     }
528 
529     return 0;
530 }
531 
usbd_ep_open(uint8_t busid,const struct usb_endpoint_descriptor * ep)532 int usbd_ep_open(uint8_t busid, const struct usb_endpoint_descriptor *ep)
533 {
534     uint8_t ep_idx = USB_EP_GET_IDX(ep->bEndpointAddress);
535 
536     USB_ASSERT_MSG(ep_idx < CONFIG_USBDEV_EP_NUM, "Ep addr %02x overflow", ep->bEndpointAddress);
537 
538     chipidea_edpt_open(busid, ep->bEndpointAddress, USB_GET_ENDPOINT_TYPE(ep->bmAttributes), ep->wMaxPacketSize);
539 
540     if (USB_EP_DIR_IS_OUT(ep->bEndpointAddress)) {
541         g_chipidea_udc[busid].out_ep[ep_idx].ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize);
542         g_chipidea_udc[busid].out_ep[ep_idx].ep_type = USB_GET_ENDPOINT_TYPE(ep->bmAttributes);
543         g_chipidea_udc[busid].out_ep[ep_idx].ep_enable = true;
544     } else {
545         g_chipidea_udc[busid].in_ep[ep_idx].ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize);
546         g_chipidea_udc[busid].in_ep[ep_idx].ep_type = USB_GET_ENDPOINT_TYPE(ep->bmAttributes);
547         g_chipidea_udc[busid].in_ep[ep_idx].ep_enable = true;
548     }
549 
550     return 0;
551 }
552 
usbd_ep_close(uint8_t busid,const uint8_t ep)553 int usbd_ep_close(uint8_t busid, const uint8_t ep)
554 {
555     uint8_t ep_idx = USB_EP_GET_IDX(ep);
556 
557     if (USB_EP_DIR_IS_OUT(ep)) {
558         g_chipidea_udc[busid].out_ep[ep_idx].ep_enable = false;
559     } else {
560         g_chipidea_udc[busid].in_ep[ep_idx].ep_enable = false;
561     }
562 
563     chipidea_edpt_close(USB_OTG_DEV, ep);
564 
565     return 0;
566 }
567 
usbd_ep_set_stall(uint8_t busid,const uint8_t ep)568 int usbd_ep_set_stall(uint8_t busid, const uint8_t ep)
569 {
570     chipidea_edpt_stall(USB_OTG_DEV, ep);
571     return 0;
572 }
573 
usbd_ep_clear_stall(uint8_t busid,const uint8_t ep)574 int usbd_ep_clear_stall(uint8_t busid, const uint8_t ep)
575 {
576     chipidea_edpt_clear_stall(USB_OTG_DEV, ep);
577     return 0;
578 }
579 
usbd_ep_is_stalled(uint8_t busid,const uint8_t ep,uint8_t * stalled)580 int usbd_ep_is_stalled(uint8_t busid, const uint8_t ep, uint8_t *stalled)
581 {
582     *stalled = chipidea_edpt_check_stall(USB_OTG_DEV, ep);
583     return 0;
584 }
585 
usbd_ep_start_write(uint8_t busid,const uint8_t ep,const uint8_t * data,uint32_t data_len)586 int usbd_ep_start_write(uint8_t busid, const uint8_t ep, const uint8_t *data, uint32_t data_len)
587 {
588     uint8_t ep_idx = USB_EP_GET_IDX(ep);
589 
590     if (!data && data_len) {
591         return -1;
592     }
593     if (!g_chipidea_udc[busid].in_ep[ep_idx].ep_enable) {
594         return -2;
595     }
596 
597     g_chipidea_udc[busid].in_ep[ep_idx].xfer_buf = (uint8_t *)data;
598     g_chipidea_udc[busid].in_ep[ep_idx].xfer_len = data_len;
599     g_chipidea_udc[busid].in_ep[ep_idx].actual_xfer_len = 0;
600 
601     chipidea_start_xfer(busid, ep, (uint8_t *)data, data_len);
602 
603     return 0;
604 }
605 
usbd_ep_start_read(uint8_t busid,const uint8_t ep,uint8_t * data,uint32_t data_len)606 int usbd_ep_start_read(uint8_t busid, const uint8_t ep, uint8_t *data, uint32_t data_len)
607 {
608     uint8_t ep_idx = USB_EP_GET_IDX(ep);
609 
610     if (!data && data_len) {
611         return -1;
612     }
613     if (!g_chipidea_udc[busid].out_ep[ep_idx].ep_enable) {
614         return -2;
615     }
616 
617     g_chipidea_udc[busid].out_ep[ep_idx].xfer_buf = (uint8_t *)data;
618     g_chipidea_udc[busid].out_ep[ep_idx].xfer_len = data_len;
619     g_chipidea_udc[busid].out_ep[ep_idx].actual_xfer_len = 0;
620 
621     chipidea_start_xfer(busid, ep, data, data_len);
622 
623     return 0;
624 }
625 
USBD_IRQHandler(uint8_t busid)626 void USBD_IRQHandler(uint8_t busid)
627 {
628     uint32_t int_status;
629     uint32_t transfer_len;
630     bool ep_cb_req;
631 
632     /* Acknowledge handled interrupt */
633     int_status = USB_OTG_DEV->USBSTS;
634     int_status &= USB_OTG_DEV->USBINTR;
635     USB_OTG_DEV->USBSTS = int_status;
636 
637     if (int_status & intr_error) {
638         USB_LOG_ERR("usbd intr error!\r\n");
639     }
640 
641 #ifdef CONFIG_USBDEV_SOF_ENABLE
642     if (int_status & intr_sof) {
643         usbd_event_sof_handler(busid);
644     }
645 #endif
646 
647     if (int_status & intr_reset) {
648         g_chipidea_udc[busid].is_suspend = false;
649         memset(g_chipidea_udc[busid].in_ep, 0, sizeof(struct chipidea_ep_state) * CONFIG_USBDEV_EP_NUM);
650         memset(g_chipidea_udc[busid].out_ep, 0, sizeof(struct chipidea_ep_state) * CONFIG_USBDEV_EP_NUM);
651         usbd_event_reset_handler(busid);
652         chipidea_bus_reset(busid, 64);
653     }
654 
655     if (int_status & intr_suspend) {
656         if (USB_PORTSC1_SUSP_GET(USB_OTG_DEV->PORTSC1)) {
657             /* Note: Host may delay more than 3 ms before and/or after bus reset before doing enumeration. */
658             if (USB_DEVICEADDR_USBADR_GET(USB_OTG_DEV->DEVICEADDR)) {
659                 g_chipidea_udc[busid].is_suspend = true;
660                 usbd_event_suspend_handler(busid);
661             }
662         } else {
663         }
664     }
665 
666     if (int_status & intr_port_change) {
667         if (!USB_PORTSC1_CCS_GET(USB_OTG_DEV->PORTSC1)) {
668             usbd_event_disconnect_handler(busid);
669         } else {
670             if (g_chipidea_udc[busid].is_suspend) {
671                 g_chipidea_udc[busid].is_suspend = false;
672                 usbd_event_resume_handler(busid);
673             }
674             usbd_event_connect_handler(busid);
675         }
676     }
677 
678     if (int_status & intr_usb) {
679         uint32_t const edpt_complete = USB_OTG_DEV->ENDPTCOMPLETE;
680         uint32_t edpt_setup_status = USB_OTG_DEV->ENDPTSETUPSTAT;
681 
682         if (edpt_complete) {
683             USB_OTG_DEV->ENDPTCOMPLETE = edpt_complete;
684             for (uint8_t ep_idx = 0; ep_idx < (CONFIG_USBDEV_EP_NUM * 2); ep_idx++) {
685                 if (edpt_complete & (1 << ep_idx2bit(ep_idx))) {
686                     transfer_len = 0;
687                     ep_cb_req = true;
688 
689                     /* Failed QTD also get ENDPTCOMPLETE set */
690                     dcd_qtd_t *p_qtd = chipidea_qtd_get(busid, ep_idx);
691                     while (1) {
692                         if (p_qtd->halted || p_qtd->xact_err || p_qtd->buffer_err) {
693                             USB_LOG_ERR("usbd transfer error!\r\n");
694                             ep_cb_req = false;
695                             break;
696                         } else if (p_qtd->active) {
697                             ep_cb_req = false;
698                             break;
699                         } else {
700                             transfer_len += p_qtd->expected_bytes - p_qtd->total_bytes;
701                         }
702 
703                         if (p_qtd->next == 1) {
704                             break;
705                         } else {
706                             p_qtd = (dcd_qtd_t *)p_qtd->next;
707                         }
708                     }
709 
710                     if (ep_cb_req) {
711                         uint8_t const ep_addr = (ep_idx / 2) | ((ep_idx & 0x01) ? 0x80 : 0);
712                         if (ep_addr & 0x80) {
713                             usbd_event_ep_in_complete_handler(busid, ep_addr, transfer_len);
714                         } else {
715                             usbd_event_ep_out_complete_handler(busid, ep_addr, transfer_len);
716                         }
717                     }
718                 }
719             }
720         }
721 
722         if (edpt_setup_status) {
723             /*------------- Set up Received -------------*/
724             USB_OTG_DEV->ENDPTSETUPSTAT = edpt_setup_status;
725             dcd_qhd_t *qhd0 = chipidea_qhd_get(busid, 0);
726             usbd_event_ep0_setup_complete_handler(busid, (uint8_t *)&qhd0->setup_request);
727         }
728     }
729 }