1 /*
2  * Copyright (c) 2020 - 2024 Renesas Electronics Corporation and/or its affiliates
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 /***********************************************************************************************************************
8  * Includes
9  **********************************************************************************************************************/
10 #include "bsp_api.h"
11 #include "r_usb_device.h"
12 #include "r_usb_device_define.h"
13 
14 /***********************************************************************************************************************
15  * Macro definitions
16  **********************************************************************************************************************/
17 #define LITTLE_ENDIAN         0
18 #define BIG_ENDIAN            1
19 #if defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
20  #define BYTE_ORDER           LITTLE_ENDIAN
21 #elif defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
22  #define BYTE_ORDER           BIG_ENDIAN
23 #else
24  #error "Cannot determine endianness"
25 #endif
26 
27 #define USBD_OPEN             (0x55534244) /* USBD in ASCII */
28 
29 #define USB_EP_DIR_Msk        (0x80UL)
30 #define USB_EP_IN_DIR         (0x80UL)
31 #define USB_EP_OUT_DIR        (0UL)
32 
33 #define USB_EP_IDX_Msk        (0x7FUL)
34 #define USB_EP_CONTROL_IN     (0x80UL)
35 #define USB_EP_CONTROL_OUT    (0UL)
36 
37 #define USB_GET_EP_DIR(ep_addr)      (ep_addr & USB_EP_DIR_Msk)
38 #define USB_GET_EP_IDX(ep_addr)      (ep_addr & USB_EP_IDX_Msk)
39 #define USB_GET_EP_ADDR(idx, dir)    ((idx & USB_EP_IDX_Msk) | (dir & USB_EP_DIR_Msk))
40 
41 #define USB_PIPECFG_DIR_IDX(dir)     ((dir == USB_EP_IN_DIR) ? 1 : 0)
42 
43 #define USB_HIGHSPEED_MPS_Msk           (0x7ffUL)
44 #define USB_FULLSPEED_MPS_Msk           (0x1ffUL)
45 
46 #define USB_XFER_TYPE_CONTROL           (0)
47 #define USB_XFER_TYPE_ISO               (1)
48 #define USB_XFER_TYPE_BULK              (2)
49 #define USB_XFER_TYPE_INT               (3)
50 
51 #define USB_REQUEST_TYPE_SET_ADDRESS    (0x0500)
52 
53 /* TODO: BUFNMB should be changed depending on the allocation scheme */
54 #define R_USB_PIPEBUF_FIXED             (0x7C08) /* Fixed Pipe Buffer configurations */
55 
56 /***********************************************************************************************************************
57  * Private constants
58  **********************************************************************************************************************/
59 
60 /***********************************************************************************************************************
61  * Typedef definitions
62  **********************************************************************************************************************/
63 typedef struct st_pipe_state
64 {
65     void   * buf;                      /* the start address of a transfer data buffer */
66     uint16_t length;                   /* the number of bytes in the buffer */
67     uint16_t remaining;                /* the number of bytes remaining in the buffer */
68     uint8_t  ep;                       /* an assigned endpoint address */
69 } pipe_state_t;
70 
71 typedef struct st_usb_pipe_cfg
72 {
73     pipe_state_t pipe[10];
74     uint8_t      ep[2][16];            /* a lookup table for a pipe index from an endpoint address */
75 } usb_pipe_cfg_t;
76 
77 /***********************************************************************************************************************
78  * Private function prototypes
79  **********************************************************************************************************************/
min16(uint16_t x,uint16_t y)80 static inline uint16_t min16 (uint16_t x, uint16_t y) {
81     return (x < y) ? x : y;
82 }
83 
get_first_bit1_offset(uint32_t s)84 static inline uint32_t get_first_bit1_offset (uint32_t s) {
85     return __builtin_ctz(s);
86 }
87 
88 static inline uint16_t get_edpt_packet_size(usbd_instance_ctrl_t * const p_ctrl,
89                                             usbd_desc_endpoint_t const * p_desc_ep);
90 static uint32_t                   find_pipe(usbd_instance_ctrl_t * const p_ctrl, uint32_t xfer_type);
91 static inline volatile uint16_t * get_pipectr(usbd_instance_ctrl_t * const p_ctrl, uint32_t num);
92 static volatile void *            get_pipetre(usbd_instance_ctrl_t * const p_ctrl, uint32_t num);
93 static inline uint16_t            edpt0_max_packet_size(usbd_instance_ctrl_t * const p_ctrl);
94 static inline uint16_t            edpt_max_packet_size(usbd_instance_ctrl_t * const p_ctrl, uint32_t num);
95 static inline void                pipe_wait_for_ready(usbd_instance_ctrl_t * const p_ctrl, uint32_t num);
96 static inline void                pipe_write_packet(usbd_instance_ctrl_t * const p_ctrl,
97                                                     void                       * buf,
98                                                     volatile void              * fifo,
99                                                     unsigned int                 len);
100 static inline void pipe_read_packet(usbd_instance_ctrl_t * const p_ctrl,
101                                     void                       * buf,
102                                     volatile void              * fifo,
103                                     unsigned int                 len);
104 static inline bool      pipe0_xfer_in(usbd_instance_ctrl_t * const p_ctrl);
105 static inline bool      pipe0_xfer_out(usbd_instance_ctrl_t * const p_ctrl);
106 static inline bool      pipe_xfer_in(usbd_instance_ctrl_t * const p_ctrl, uint8_t num);
107 static inline bool      pipe_xfer_out(usbd_instance_ctrl_t * const p_ctrl, uint8_t num);
108 static void             r_usb_device_call_callback(usbd_instance_ctrl_t * const p_ctrl, usbd_event_t * event);
109 static inline void      process_setup_packet(usbd_instance_ctrl_t * const p_ctrl);
110 static inline void      process_status_completion(usbd_instance_ctrl_t * const p_ctrl);
111 static inline fsp_err_t process_pipe0_xfer(usbd_instance_ctrl_t * const p_ctrl,
112                                            uint8_t                      ep_addr,
113                                            void                       * buffer,
114                                            uint16_t                     total_bytes);
115 static inline fsp_err_t process_pipe_xfer(usbd_instance_ctrl_t * const p_ctrl,
116                                           uint8_t                      ep_addr,
117                                           void                       * buffer,
118                                           uint16_t                     total_bytes);
119 static inline void process_pipe_forced_termination(usbd_instance_ctrl_t * const p_ctrl, uint8_t ep);
120 static inline void process_pipe0_bemp(usbd_instance_ctrl_t * const p_ctrl);
121 static inline void process_pipe_brdy(usbd_instance_ctrl_t * const p_ctrl, uint32_t num);
122 static inline void process_bus_reset(usbd_instance_ctrl_t * const p_ctrl);
123 static inline void process_set_address(usbd_instance_ctrl_t * const p_ctrl);
124 static inline void physical_init(usbd_instance_ctrl_t * const p_ctrl, usbd_cfg_t const * const p_cfg);
125 static inline void control_pipe_setup(usbd_instance_ctrl_t * const p_ctrl);
126 static inline void usb_interrupt_configure(usbd_instance_ctrl_t * p_ctrl, usbd_cfg_t const * p_cfg);
127 static inline void usb_module_start(usbd_instance_ctrl_t * p_ctrl);
128 static inline void usb_module_stop(usbd_instance_ctrl_t * p_ctrl);
129 static inline void usb_disable_interrupt(usbd_instance_ctrl_t * p_ctrl);
130 static inline void usb_enable_interrupt(usbd_instance_ctrl_t * p_ctrl);
131 
132 /***********************************************************************************************************************
133  * Private global variables
134  **********************************************************************************************************************/
135 static usb_pipe_cfg_t g_pipe_cfg[USB_NUM_USBIP];
136 
137 /***********************************************************************************************************************
138  * Functions
139  **********************************************************************************************************************/
140 
141 /**
142  * @brief Start USB module, configure correct operate mode and default pipe0
143  *
144  * @param p_api_ctrl
145  * @param p_cfg
146  *
147  * @retval FSP_SUCCESS on success
148  */
R_USBD_Open(usbd_ctrl_t * const p_api_ctrl,usbd_cfg_t const * const p_cfg)149 fsp_err_t R_USBD_Open (usbd_ctrl_t * const p_api_ctrl, usbd_cfg_t const * const p_cfg)
150 {
151     usbd_instance_ctrl_t * p_ctrl = (usbd_instance_ctrl_t *) p_api_ctrl;
152 
153 #if USBD_CFG_PARAM_CHECKING_ENABLE
154     FSP_ASSERT(p_ctrl);
155     FSP_ASSERT(p_cfg);
156     FSP_ERROR_RETURN(0 == p_ctrl->open, FSP_ERR_ALREADY_OPEN);
157 
158     /* Make sure this channel exists. */
159     FSP_ERROR_RETURN(USB_NUM_USBIP > p_cfg->module_number, FSP_ERR_IP_CHANNEL_NOT_PRESENT);
160 
161     /* USBFS module only support FS operation */
162     if (USB_IP0_MODULE == p_cfg->module_number)
163     {
164         FSP_ERROR_RETURN((USBD_SPEED_FS == p_cfg->usb_speed), FSP_ERR_INVALID_ARGUMENT);
165     }
166 
167     /* USBHS module only support FS/HS operation */
168     if (USB_IP1_MODULE == p_cfg->module_number)
169     {
170         FSP_ERROR_RETURN((USBD_SPEED_FS == p_cfg->usb_speed) || (USBD_SPEED_HS == p_cfg->usb_speed),
171                          FSP_ERR_INVALID_ARGUMENT);
172     }
173 #endif
174 
175 #ifdef USB_HIGH_SPEED_MODULE
176     p_ctrl->p_reg = (void *) (USB_IS_USBHS(p_cfg->module_number) ? R_USB_HS0_BASE : R_USB_FS0_BASE);
177 #else
178     p_ctrl->p_reg = (void *) R_USB_FS0_BASE;
179 #endif
180     p_ctrl->p_cfg             = p_cfg;
181     p_ctrl->p_callback        = p_cfg->p_callback;
182     p_ctrl->p_context         = p_cfg->p_context;
183     p_ctrl->p_callback_memory = NULL;
184 
185     /* clear pipe config */
186     memset(&g_pipe_cfg[p_cfg->module_number], 0, sizeof(usb_pipe_cfg_t));
187 
188     /* module start */
189     usb_module_start(p_ctrl);
190 
191     /* physical layer init */
192     physical_init(p_ctrl, p_cfg);
193 
194     /* setup default control pipe */
195     control_pipe_setup(p_ctrl);
196 
197     /* enable interrupt */
198     usb_interrupt_configure(p_ctrl, p_cfg);
199 
200     p_ctrl->open = USBD_OPEN;
201 
202     return FSP_SUCCESS;
203 }
204 
205 /**
206  * @brief Shutdown USB device
207  *
208  * @param p_api_ctrl
209  *
210  * @retval FSP_SUCCESS on success
211  */
R_USBD_Close(usbd_ctrl_t * const p_api_ctrl)212 fsp_err_t R_USBD_Close (usbd_ctrl_t * const p_api_ctrl)
213 {
214     usbd_instance_ctrl_t * p_ctrl = (usbd_instance_ctrl_t *) p_api_ctrl;
215 
216 #if USBD_CFG_PARAM_CHECKING_ENABLE
217     FSP_ASSERT(p_ctrl);
218     FSP_ERROR_RETURN(0 != p_ctrl->open, FSP_ERR_NOT_OPEN);
219 #endif
220 
221     /* disable interrupt */
222     usb_disable_interrupt(p_ctrl);
223 
224     /* module stop */
225     usb_module_stop(p_ctrl);
226 
227     p_ctrl->open = 0;
228 
229     return FSP_SUCCESS;
230 }
231 
232 /**
233  * @brief Connect USB D+/D- pin to the USB data bus
234  *
235  * @param p_api_ctrl
236  *
237  * @retval FSP_SUCCESS on success
238  */
R_USBD_Connect(usbd_ctrl_t * const p_api_ctrl)239 fsp_err_t R_USBD_Connect (usbd_ctrl_t * const p_api_ctrl)
240 {
241 #ifdef USB_HIGH_SPEED_MODULE
242     usbd_instance_ctrl_t * p_ctrl = (usbd_instance_ctrl_t *) p_api_ctrl;
243 #else
244     FSP_PARAMETER_NOT_USED(p_api_ctrl);
245 #endif
246 
247 #if USBD_CFG_PARAM_CHECKING_ENABLE
248     FSP_ASSERT(p_ctrl);
249     FSP_ERROR_RETURN(0 != p_ctrl->open, FSP_ERR_NOT_OPEN);
250 #endif
251 
252 #ifdef USB_HIGH_SPEED_MODULE
253     if (USB_IS_USBHS(p_ctrl->p_cfg->module_number))
254     {
255         R_USB_HS0->SYSCFG_b.CNEN  = 1;
256         R_USB_HS0->SYSCFG_b.DPRPU = 1;
257     }
258     else
259 #endif
260     {
261         R_USB_FS0->SYSCFG_b.DPRPU = 1;
262     }
263 
264     return FSP_SUCCESS;
265 }
266 
267 /**
268  * @brief Disconnect pin D+/D- to USB data bus
269  *
270  * @param p_api_ctrl
271  *
272  * @retval FSP_SUCCESS on success
273  */
R_USBD_Disconnect(usbd_ctrl_t * const p_api_ctrl)274 fsp_err_t R_USBD_Disconnect (usbd_ctrl_t * const p_api_ctrl)
275 {
276 #ifdef USB_HIGH_SPEED_MODULE
277     usbd_instance_ctrl_t * p_ctrl = (usbd_instance_ctrl_t *) p_api_ctrl;
278 #else
279     FSP_PARAMETER_NOT_USED(p_api_ctrl);
280 #endif
281 
282 #if USBD_CFG_PARAM_CHECKING_ENABLE
283     FSP_ASSERT(p_ctrl);
284     FSP_ERROR_RETURN(0 != p_ctrl->open, FSP_ERR_NOT_OPEN);
285 #endif
286 
287 #ifdef USB_HIGH_SPEED_MODULE
288     if (USB_IS_USBHS(p_ctrl->p_cfg->module_number))
289     {
290         R_USB_HS0->SYSCFG_b.DPRPU = 0;
291     }
292     else
293 #endif
294     {
295         R_USB_FS0->SYSCFG_b.DPRPU = 0;
296     }
297 
298     return FSP_SUCCESS;
299 }
300 
301 /**
302  * @brief Configure an endpoint to make it ready to transfer
303  *
304  * @param p_api_ctrl
305  * @param p_ep_desc
306  *
307  * @retval FSP_SUCCESS          on success
308  * @retval FSP_ERR_USB_BUSY     if these is no available pipe can be used with this endpoint
309  */
R_USBD_EdptOpen(usbd_ctrl_t * const p_api_ctrl,usbd_desc_endpoint_t const * p_ep_desc)310 fsp_err_t R_USBD_EdptOpen (usbd_ctrl_t * const p_api_ctrl, usbd_desc_endpoint_t const * p_ep_desc)
311 {
312     usbd_instance_ctrl_t * const p_ctrl = (usbd_instance_ctrl_t *) p_api_ctrl;
313 
314 #if USBD_CFG_PARAM_CHECKING_ENABLE
315     FSP_ASSERT(p_ctrl);
316     FSP_ASSERT(p_ep_desc);
317     FSP_ERROR_RETURN(0 != p_ctrl->open, FSP_ERR_NOT_OPEN);
318 #endif
319 
320     const uint8_t  ep_addr = p_ep_desc->bEndpointAddress;
321     const uint8_t  epn     = USB_GET_EP_IDX(ep_addr);
322     const uint8_t  dir     = USB_GET_EP_DIR(ep_addr);
323     const uint8_t  xfer    = p_ep_desc->Attributes.xfer;
324     const uint32_t num     = find_pipe(p_ctrl, xfer);
325 
326     /* There are no available pipes that can be configured for this endpoint. */
327     FSP_ERROR_RETURN(0 != num, FSP_ERR_USB_BUSY);
328 
329     g_pipe_cfg[p_ctrl->p_cfg->module_number].pipe[num].ep = ep_addr;
330     g_pipe_cfg[p_ctrl->p_cfg->module_number].ep[USB_PIPECFG_DIR_IDX(dir)][epn] = num;
331 
332     /* setup pipe */
333     usb_disable_interrupt(p_ctrl);
334 
335 #ifdef USB_HIGH_SPEED_MODULE
336     if (USB_IS_USBHS(p_ctrl->p_cfg->module_number))
337     {
338         R_USB_HS0->PIPEBUF  = R_USB_PIPEBUF_FIXED;
339         R_USB_HS0->PIPESEL  = num;
340         R_USB_HS0->PIPEMAXP = get_edpt_packet_size(p_ctrl, p_ep_desc);
341     }
342     else
343 #endif
344     {
345         R_USB_FS0->PIPESEL  = num;
346         R_USB_FS0->PIPEMAXP = get_edpt_packet_size(p_ctrl, p_ep_desc);
347     }
348 
349     volatile uint16_t * ctr = get_pipectr(p_api_ctrl, num);
350     *ctr = R_USB_PIPE_CTR_ACLRM_Msk | R_USB_PIPE_CTR_SQCLR_Msk;
351     *ctr = 0;
352 
353     uint16_t cfg = (USB_PIPECFG_DIR_IDX(dir) << R_USB_PIPECFG_DIR_Pos) | epn;
354 
355     if (xfer == USB_XFER_TYPE_BULK)
356     {
357         cfg |= (R_USB_PIPECFG_TYPE_BULK | R_USB_PIPECFG_SHTNAK_Msk | R_USB_PIPECFG_DBLB_Msk);
358     }
359     else if (xfer == USB_XFER_TYPE_INT)
360     {
361         cfg |= R_USB_PIPECFG_TYPE_INT;
362     }
363     else
364     {
365         cfg |= (R_USB_PIPECFG_TYPE_ISO | R_USB_PIPECFG_DBLB_Msk);
366     }
367 
368 #ifdef USB_HIGH_SPEED_MODULE
369     if (USB_IS_USBHS(p_ctrl->p_cfg->module_number))
370     {
371         R_USB_HS0->PIPECFG  = cfg;
372         R_USB_HS0->BRDYSTS  = R_USB_BRDYSTS_PIPEBRDY_Msk ^ (1 << num);
373         R_USB_HS0->BRDYENB |= (1 << num);
374     }
375     else
376 #endif
377     {
378         R_USB_FS0->PIPECFG  = cfg;
379         R_USB_FS0->BRDYSTS  = R_USB_BRDYSTS_PIPEBRDY_Msk ^ (1 << num);
380         R_USB_FS0->BRDYENB |= (1 << num);
381     }
382 
383     if ((USB_EP_IN_DIR == dir) || (USB_XFER_TYPE_BULK != xfer))
384     {
385         *ctr = R_USB_PIPE_CTR_PID_BUF;
386     }
387 
388     usb_enable_interrupt(p_ctrl);
389 
390     return FSP_SUCCESS;
391 }
392 
393 /**
394  * @brief Remove configuration for an endpoint
395  *
396  * @param p_api_ctrl
397  * @param ep_addr
398  *
399  * @retval FSP_SUCCESS on success
400  */
R_USBD_EdptClose(usbd_ctrl_t * const p_api_ctrl,uint8_t ep_addr)401 fsp_err_t R_USBD_EdptClose (usbd_ctrl_t * const p_api_ctrl, uint8_t ep_addr)
402 {
403     usbd_instance_ctrl_t * p_ctrl = (usbd_instance_ctrl_t *) p_api_ctrl;
404 
405 #if USBD_CFG_PARAM_CHECKING_ENABLE
406     FSP_ASSERT(p_ctrl);
407     FSP_ERROR_RETURN(0 != p_ctrl->open, FSP_ERR_NOT_OPEN);
408 #endif
409 
410     const uint8_t epn = USB_GET_EP_IDX(ep_addr);
411     const uint8_t dir = USB_GET_EP_DIR(ep_addr);
412     const uint8_t num = g_pipe_cfg[p_ctrl->p_cfg->module_number].ep[USB_PIPECFG_DIR_IDX(dir)][epn];
413 
414 #ifdef USB_HIGH_SPEED_MODULE
415     if (USB_IS_USBHS(p_ctrl->p_cfg->module_number))
416     {
417         volatile uint16_t * ctr = get_pipectr(p_ctrl, num);
418 
419         R_USB_HS0->BRDYENB &= ~(1 << num);
420         *ctr                = 0;
421         R_USB_HS0->PIPESEL  = num;
422         R_USB_HS0->PIPECFG  = 0;
423     }
424     else
425 #endif
426     {
427         volatile uint16_t * ctr = get_pipectr(p_ctrl, num);
428 
429         R_USB_FS0->BRDYENB &= ~(1 << num);
430         *ctr                = 0;
431         R_USB_FS0->PIPESEL  = num;
432         R_USB_FS0->PIPECFG  = 0;
433     }
434 
435     g_pipe_cfg[p_ctrl->p_cfg->module_number].pipe[num].ep = 0;
436     g_pipe_cfg[p_ctrl->p_cfg->module_number].ep[USB_PIPECFG_DIR_IDX(dir)][epn] = 0;
437 
438     return FSP_SUCCESS;
439 }
440 
441 /**
442  * @brief Wake up host
443  *
444  * @param p_api_ctrl
445  *
446  * @retval FSP_SUCCESS on success
447  */
R_USBD_RemoteWakeup(usbd_ctrl_t * const p_api_ctrl)448 fsp_err_t R_USBD_RemoteWakeup (usbd_ctrl_t * const p_api_ctrl)
449 {
450 #ifdef USB_HIGH_SPEED_MODULE
451     usbd_instance_ctrl_t * p_ctrl = (usbd_instance_ctrl_t *) p_api_ctrl;
452 #else
453     FSP_PARAMETER_NOT_USED(p_api_ctrl);
454 #endif
455 
456 #if USBD_CFG_PARAM_CHECKING_ENABLE
457     FSP_ASSERT(p_ctrl);
458     FSP_ERROR_RETURN(0 != p_ctrl->open, FSP_ERR_NOT_OPEN);
459 #endif
460 
461 #ifdef USB_HIGH_SPEED_MODULE
462     if (USB_IS_USBHS(p_ctrl->p_cfg->module_number))
463     {
464         R_USB_HS0->DVSTCTR0_b.WKUP = 1;
465     }
466     else
467 #endif
468     {
469         R_USB_FS0->DVSTCTR0_b.WKUP = 1;
470     }
471 
472     return FSP_SUCCESS;
473 }
474 
475 /**
476  * @brief Trigger an endpoint transfer
477  *
478  * @param p_api_ctrl
479  * @param ep_addr
480  * @param buffer
481  * @param total_bytes
482  *
483  * @retval FSP_SUCCESS              on success
484  * @retval FSP_ERR_USB_NOT_OPEN     if input endpoint has not opened yet
485  */
R_USBD_XferStart(usbd_ctrl_t * const p_api_ctrl,uint8_t ep_addr,uint8_t * buffer,uint16_t total_bytes)486 fsp_err_t R_USBD_XferStart (usbd_ctrl_t * const p_api_ctrl, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes)
487 {
488     usbd_instance_ctrl_t * p_ctrl = (usbd_instance_ctrl_t *) p_api_ctrl;
489     fsp_err_t              err    = FSP_SUCCESS;
490 
491 #if USBD_CFG_PARAM_CHECKING_ENABLE
492     FSP_ASSERT(p_ctrl);
493     FSP_ERROR_RETURN(0 != p_ctrl->open, FSP_ERR_NOT_OPEN);
494 #endif
495 
496     usb_disable_interrupt(p_ctrl);
497 
498     if (USB_GET_EP_IDX(ep_addr) > 0)
499     {
500         err = process_pipe_xfer(p_api_ctrl, ep_addr, buffer, total_bytes);
501     }
502     else
503     {
504         err = process_pipe0_xfer(p_api_ctrl, ep_addr, buffer, total_bytes);
505     }
506 
507     usb_enable_interrupt(p_ctrl);
508 
509     return err;
510 }
511 
512 /**
513  * @brief Abort on-going transfer
514  *
515  * @param p_api_ctrl
516  * @param ep_addr
517  *
518  * @retval FSP_SUCCESS on success
519  */
R_USBD_XferAbort(usbd_ctrl_t * const p_api_ctrl,uint8_t ep_addr)520 fsp_err_t R_USBD_XferAbort (usbd_ctrl_t * const p_api_ctrl, uint8_t ep_addr)
521 {
522     usbd_instance_ctrl_t * p_ctrl = (usbd_instance_ctrl_t *) p_api_ctrl;
523 
524 #if USBD_CFG_PARAM_CHECKING_ENABLE
525     FSP_ASSERT(p_ctrl);
526     FSP_ERROR_RETURN(0 != p_ctrl->open, FSP_ERR_NOT_OPEN);
527 #endif
528 
529     usb_disable_interrupt(p_ctrl);
530 
531     process_pipe_forced_termination(p_ctrl, ep_addr);
532 
533     usb_enable_interrupt(p_ctrl);
534 
535     return FSP_SUCCESS;
536 }
537 
538 /**
539  * @brief Set a endpoint to halt and send a stall packet
540  *
541  * @param p_api_ctrl
542  * @param ep_addr
543  *
544  * @retval FSP_SUCCESS on success
545  */
R_USBD_EdptStall(usbd_ctrl_t * const p_api_ctrl,uint8_t ep_addr)546 fsp_err_t R_USBD_EdptStall (usbd_ctrl_t * const p_api_ctrl, uint8_t ep_addr)
547 {
548     usbd_instance_ctrl_t * p_ctrl = (usbd_instance_ctrl_t *) p_api_ctrl;
549 
550 #if USBD_CFG_PARAM_CHECKING_ENABLE
551     FSP_ASSERT(p_ctrl);
552     FSP_ERROR_RETURN(0 != p_ctrl->open, FSP_ERR_NOT_OPEN);
553 #endif
554 
555     usb_disable_interrupt(p_ctrl);
556 
557     const uint8_t       epn     = USB_GET_EP_IDX(ep_addr);
558     const uint8_t       dir     = USB_GET_EP_DIR(ep_addr);
559     const uint8_t       num     = g_pipe_cfg[p_ctrl->p_cfg->module_number].ep[USB_PIPECFG_DIR_IDX(dir)][epn];
560     volatile uint16_t * pipectr = get_pipectr(p_api_ctrl, num);
561     const uint16_t      pid     = *pipectr & R_USB_PIPE_CTR_PID_Msk;
562 
563     *pipectr = pid | R_USB_PIPE_CTR_PID_STALL;
564     *pipectr = R_USB_PIPE_CTR_PID_STALL;
565 
566     usb_enable_interrupt(p_ctrl);
567 
568     return FSP_SUCCESS;
569 }
570 
571 /**
572  * @brief Reset halt state of an endpoint
573  *
574  * @param p_api_ctrl
575  * @param ep_addr
576  *
577  * @retval FSP_SUCCESS on success
578  */
R_USBD_EdptClearStall(usbd_ctrl_t * const p_api_ctrl,uint8_t ep_addr)579 fsp_err_t R_USBD_EdptClearStall (usbd_ctrl_t * const p_api_ctrl, uint8_t ep_addr)
580 {
581     usbd_instance_ctrl_t * p_ctrl = (usbd_instance_ctrl_t *) p_api_ctrl;
582 
583 #if USBD_CFG_PARAM_CHECKING_ENABLE
584     FSP_ASSERT(p_ctrl);
585     FSP_ERROR_RETURN(0 != p_ctrl->open, FSP_ERR_NOT_OPEN);
586 #endif
587 
588     usb_disable_interrupt(p_ctrl);
589 
590     const uint8_t       epn     = USB_GET_EP_IDX(ep_addr);
591     const uint8_t       dir     = USB_GET_EP_DIR(ep_addr);
592     const uint8_t       num     = g_pipe_cfg[p_ctrl->p_cfg->module_number].ep[USB_PIPECFG_DIR_IDX(dir)][epn];
593     volatile uint16_t * pipectr = get_pipectr(p_api_ctrl, num);
594 
595     *pipectr = R_USB_PIPE_CTR_SQCLR_Msk;
596     if (USB_EP_IN_DIR == dir)
597     {
598         *pipectr = R_USB_PIPE_CTR_PID_BUF;
599     }
600     else
601     {
602 #ifdef USB_HIGH_SPEED_MODULE
603         if (USB_IS_USBHS(p_ctrl->p_cfg->module_number))
604         {
605             R_USB_HS0->PIPESEL = num;
606             if (R_USB_HS0->PIPECFG_b.TYPE != 1)
607             {
608                 *pipectr = R_USB_PIPE_CTR_PID_BUF;
609             }
610         }
611         else
612 #endif
613         {
614             R_USB_FS0->PIPESEL = num;
615             if (R_USB_FS0->PIPECFG_b.TYPE != 1)
616             {
617                 *pipectr = R_USB_PIPE_CTR_PID_BUF;
618             }
619         }
620     }
621 
622     usb_enable_interrupt(p_ctrl);
623 
624     return FSP_SUCCESS;
625 }
626 
627 /**********************************************************************************************************************
628  * Private functions
629  **********************************************************************************************************************/
630 
631 /* get the mps from an EP descriptor */
get_edpt_packet_size(usbd_instance_ctrl_t * const p_ctrl,usbd_desc_endpoint_t const * p_desc_ep)632 static inline uint16_t get_edpt_packet_size (usbd_instance_ctrl_t * const p_ctrl,
633                                              usbd_desc_endpoint_t const * p_desc_ep)
634 {
635     uint16_t mps = 0;
636 
637 #ifdef USB_HIGH_SPEED_MODULE
638     if (p_ctrl->p_cfg->usb_speed == USBD_SPEED_HS)
639     {
640         mps = p_desc_ep->wMaxPacketSize & USB_HIGHSPEED_MPS_Msk;
641     }
642     else
643 #endif
644     {
645         mps = p_desc_ep->wMaxPacketSize & USB_FULLSPEED_MPS_Msk;
646     }
647 
648     return mps;
649 }
650 
651 /* get the available pipe can be used to configure for new endpoint */
find_pipe(usbd_instance_ctrl_t * const p_ctrl,uint32_t xfer_type)652 static uint32_t find_pipe (usbd_instance_ctrl_t * const p_ctrl, uint32_t xfer_type)
653 {
654     const uint8_t pipe_idx_arr[4][2] =
655     {
656         {0, 0},                        // Control
657         {1, 2},                        // Isochronous
658         {1, 5},                        // Bulk
659         {6, 9},                        // Interrupt
660     };
661 
662     /* find backward since only pipe 1, 2 support ISO */
663     const uint8_t idx_first = pipe_idx_arr[xfer_type][0];
664     const uint8_t idx_last  = pipe_idx_arr[xfer_type][1];
665 
666     for (int i = idx_last; i >= idx_first; i--)
667     {
668         if (0 == g_pipe_cfg[p_ctrl->p_cfg->module_number].pipe[i].ep)
669         {
670             return i;
671         }
672     }
673 
674     return 0;
675 }
676 
677 /* get the correct PIPE_CTR register by the pipe number */
get_pipectr(usbd_instance_ctrl_t * const p_ctrl,uint32_t num)678 static inline volatile uint16_t * get_pipectr (usbd_instance_ctrl_t * const p_ctrl, uint32_t num)
679 {
680     volatile uint16_t * pipectr = NULL;
681 
682 #ifdef USB_HIGH_SPEED_MODULE
683     if (USB_IS_USBHS(p_ctrl->p_cfg->module_number))
684     {
685         if (0 != num)
686         {
687             pipectr = &R_USB_HS0->PIPE_CTR[num - 1];
688         }
689         else
690         {
691             pipectr = &R_USB_HS0->DCPCTR;
692         }
693     }
694     else
695 #endif
696     {
697         if (0 != num)
698         {
699             pipectr = &R_USB_FS0->PIPE_CTR[num - 1];
700         }
701         else
702         {
703             pipectr = &R_USB_FS0->DCPCTR;
704         }
705     }
706 
707     return pipectr;
708 }
709 
710 /* get the correct PIPE_TR by the pipe number */
get_pipetre(usbd_instance_ctrl_t * const p_ctrl,uint32_t num)711 static volatile void * get_pipetre (usbd_instance_ctrl_t * const p_ctrl, uint32_t num)
712 {
713     volatile void * pipetre = NULL;
714 
715 #ifdef USB_HIGH_SPEED_MODULE
716     if (USB_IS_USBHS(p_ctrl->p_cfg->module_number))
717     {
718         pipetre = (1 <= num) && (num <= 5) ? &(R_USB_HS0->PIPE_TR[num - 1].E) : NULL;
719     }
720     else
721 #endif
722     {
723         pipetre = (1 <= num) && (num <= 5) ? &(R_USB_FS0->PIPE_TR[num - 1].E) : NULL;
724     }
725 
726     return pipetre;
727 }
728 
729 /* get the mps of pipe0 */
edpt0_max_packet_size(usbd_instance_ctrl_t * const p_ctrl)730 static inline uint16_t edpt0_max_packet_size (usbd_instance_ctrl_t * const p_ctrl)
731 {
732     uint16_t mps = 0;
733 
734 #ifdef USB_HIGH_SPEED_MODULE
735     if (USB_IS_USBHS(p_ctrl->p_cfg->module_number))
736     {
737         mps = R_USB_HS0->DCPMAXP_b.MXPS;
738     }
739     else
740 #endif
741     {
742         mps = R_USB_FS0->DCPMAXP_b.MXPS;
743     }
744 
745     return mps;
746 }
747 
748 /* get the mps of common endpoint */
edpt_max_packet_size(usbd_instance_ctrl_t * const p_ctrl,uint32_t num)749 static inline uint16_t edpt_max_packet_size (usbd_instance_ctrl_t * const p_ctrl, uint32_t num)
750 {
751     uint16_t mps = 0;
752 
753 #ifdef USB_HIGH_SPEED_MODULE
754     if (USB_IS_USBHS(p_ctrl->p_cfg->module_number))
755     {
756         R_USB_HS0->PIPESEL = num;
757 
758         mps = R_USB_HS0->PIPEMAXP;
759     }
760     else
761 #endif
762     {
763         R_USB_FS0->PIPESEL = num;
764 
765         mps = R_USB_FS0->PIPEMAXP;
766     }
767 
768     return mps;
769 }
770 
771 /* wait for pipe to be ready */
pipe_wait_for_ready(usbd_instance_ctrl_t * const p_ctrl,uint32_t num)772 static inline void pipe_wait_for_ready (usbd_instance_ctrl_t * const p_ctrl, uint32_t num)
773 {
774 #ifdef USB_HIGH_SPEED_MODULE
775     if (USB_IS_USBHS(p_ctrl->p_cfg->module_number))
776     {
777         FSP_HARDWARE_REGISTER_WAIT(R_USB_HS0->D0FIFOSEL_b.CURPIPE, num);
778         FSP_HARDWARE_REGISTER_WAIT(R_USB_HS0->D0FIFOCTR_b.FRDY, 1);
779     }
780     else
781 #endif
782     {
783         FSP_HARDWARE_REGISTER_WAIT(R_USB_FS0->D0FIFOSEL_b.CURPIPE, num);
784         FSP_HARDWARE_REGISTER_WAIT(R_USB_FS0->D0FIFOCTR_b.FRDY, 1);
785     }
786 }
787 
788 /* write data buffer --> hw fifo */
pipe_write_packet(usbd_instance_ctrl_t * const p_ctrl,void * buf,volatile void * fifo,unsigned int len)789 static inline void pipe_write_packet (usbd_instance_ctrl_t * const p_ctrl,
790                                       void                       * buf,
791                                       volatile void              * fifo,
792                                       unsigned int                 len)
793 {
794     volatile uint16_t * ff16;
795     volatile uint8_t  * ff8;
796 
797 #ifdef USB_HIGH_SPEED_MODULE
798     if (USB_IS_USBHS(p_ctrl->p_cfg->module_number))
799     {
800         /* Highspeed FIFO is 32-bit */
801         ff16 = (volatile uint16_t *) ((uintptr_t) fifo + 2);
802         ff8  = (volatile uint8_t *) ((uintptr_t) fifo + 3);
803     }
804     else
805 #endif
806     {
807         ff16 = (volatile uint16_t *) fifo;
808         ff8  = ((volatile uint8_t *) fifo);
809     }
810 
811     uint8_t const * buf8 = (uint8_t const *) buf;
812 
813     while (len >= 2)
814     {
815         *ff16 = *(uint16_t *) (buf8);
816         buf8 += 2;
817         len  -= 2;
818     }
819 
820     if (len > 0)
821     {
822         *ff8 = *buf8;
823         ++buf8;
824     }
825 }
826 
827 /* read data buffer <-- hw fifo */
pipe_read_packet(usbd_instance_ctrl_t * const p_ctrl,void * buf,volatile void * fifo,unsigned int len)828 static inline void pipe_read_packet (usbd_instance_ctrl_t * const p_ctrl,
829                                      void                       * buf,
830                                      volatile void              * fifo,
831                                      unsigned int                 len)
832 {
833     FSP_PARAMETER_NOT_USED(p_ctrl);
834     uint8_t          * p_buf = (uint8_t *) buf;
835     volatile uint8_t * reg   = (volatile uint8_t *) fifo; /* byte access is always at base register address */
836 
837     while (len--)
838     {
839         *p_buf++ = *reg;
840     }
841 }
842 
843 /* process IN direction transfer through pipe0 */
pipe0_xfer_in(usbd_instance_ctrl_t * const p_ctrl)844 static inline bool pipe0_xfer_in (usbd_instance_ctrl_t * const p_ctrl)
845 {
846 #ifdef USB_HIGH_SPEED_MODULE
847     bool                hs_module = USB_IS_USBHS(p_ctrl->p_cfg->module_number);
848     volatile void     * cfifo     = hs_module ? &R_USB_HS0->CFIFO : &R_USB_FS0->CFIFO;
849     volatile uint16_t * cfifoctr  = hs_module ? &R_USB_HS0->CFIFOCTR : &R_USB_FS0->CFIFOCTR;
850 #else
851     volatile void     * cfifo    = &R_USB_FS0->CFIFO;
852     volatile uint16_t * cfifoctr = &R_USB_FS0->CFIFOCTR;
853 #endif
854 
855     pipe_state_t * pipe = &g_pipe_cfg[p_ctrl->p_cfg->module_number].pipe[0];
856     const uint16_t rem  = pipe->remaining;
857 
858     if (0 == rem)
859     {
860         pipe->buf = NULL;
861 
862         return true;
863     }
864 
865     const uint16_t mps = edpt0_max_packet_size(p_ctrl);
866     const uint16_t len = min16(mps, rem);
867     void         * buf = pipe->buf;
868 
869     if (len)
870     {
871         pipe_write_packet(p_ctrl, buf, cfifo, len);
872         pipe->buf = (uint8_t *) buf + len;
873     }
874 
875     if (len < mps)
876     {
877         *cfifoctr = R_USB_CFIFOCTR_BVAL_Msk;
878     }
879 
880     pipe->remaining = rem - len;
881 
882     return false;
883 }
884 
885 /* process OUT direction transfer through pipe0 */
pipe0_xfer_out(usbd_instance_ctrl_t * const p_ctrl)886 static inline bool pipe0_xfer_out (usbd_instance_ctrl_t * const p_ctrl)
887 {
888 #ifdef USB_HIGH_SPEED_MODULE
889     bool                hs_module = USB_IS_USBHS(p_ctrl->p_cfg->module_number);
890     volatile void     * cfifo     = hs_module ? &R_USB_HS0->CFIFO : &R_USB_FS0->CFIFO;
891     volatile uint16_t * cfifoctr  = hs_module ? &R_USB_HS0->CFIFOCTR : &R_USB_FS0->CFIFOCTR;
892 #else
893     volatile void     * cfifo    = &R_USB_FS0->CFIFO;
894     volatile uint16_t * cfifoctr = &R_USB_FS0->CFIFOCTR;
895 #endif
896 
897     pipe_state_t * pipe = &g_pipe_cfg[p_ctrl->p_cfg->module_number].pipe[0];
898     const uint16_t rem  = pipe->remaining;
899     const uint16_t mps  = edpt0_max_packet_size(p_ctrl);
900 #ifdef USB_HIGH_SPEED_MODULE
901     const uint16_t vld = hs_module ? R_USB_HS0->CFIFOCTR_b.DTLN : R_USB_FS0->CFIFOCTR_b.DTLN;
902 #else
903     const uint16_t vld = R_USB_FS0->CFIFOCTR_b.DTLN;
904 #endif
905     const uint16_t len = min16(min16(rem, mps), vld);
906     void         * buf = pipe->buf;
907 
908     if (len)
909     {
910         pipe_read_packet(p_ctrl, buf, cfifo, len);
911         pipe->buf = (uint8_t *) buf + len;
912     }
913 
914     if (len < mps)
915     {
916         *cfifoctr = R_USB_CFIFOCTR_BCLR_Msk;
917     }
918 
919     pipe->remaining = rem - len;
920     if ((len < mps) || (rem == len))
921     {
922         pipe->buf = NULL;
923 
924         return true;
925     }
926 
927     return false;
928 }
929 
930 /* process IN direction transfer for common pipe */
pipe_xfer_in(usbd_instance_ctrl_t * const p_ctrl,uint8_t num)931 static inline bool pipe_xfer_in (usbd_instance_ctrl_t * const p_ctrl, uint8_t num)
932 {
933 #ifdef USB_HIGH_SPEED_MODULE
934     bool                hs_module = USB_IS_USBHS(p_ctrl->p_cfg->module_number);
935     volatile uint16_t * d0fifosel = hs_module ? &R_USB_HS0->D0FIFOSEL : &R_USB_FS0->D0FIFOSEL;
936     volatile void     * d0fifo    = hs_module ? &R_USB_HS0->D0FIFO : &R_USB_FS0->D0FIFO;
937     volatile uint16_t * d0fifoctr = hs_module ? &R_USB_HS0->D0FIFOCTR : &R_USB_FS0->D0FIFOCTR;
938 #else
939     volatile uint16_t * d0fifosel = &R_USB_FS0->D0FIFOSEL;
940     volatile void     * d0fifo    = &R_USB_FS0->D0FIFO;
941     volatile uint16_t * d0fifoctr = &R_USB_FS0->D0FIFOCTR;
942 #endif
943 
944     pipe_state_t * pipe = &g_pipe_cfg[p_ctrl->p_cfg->module_number].pipe[num];
945     const uint16_t rem  = pipe->remaining;
946 
947     if (!rem)
948     {
949         pipe->buf = NULL;
950 
951         return true;
952     }
953 
954     *d0fifosel = num | R_USB_FIFOSEL_MBW_16BIT | (BYTE_ORDER == BIG_ENDIAN ? R_USB_FIFOSEL_BIGEND : 0);
955 
956     const uint16_t mps = edpt_max_packet_size(p_ctrl, num);
957     pipe_wait_for_ready(p_ctrl, num);
958     const uint16_t len = min16(rem, mps);
959     void         * buf = pipe->buf;
960 
961     if (len)
962     {
963         pipe_write_packet(p_ctrl, buf, d0fifo, len);
964         pipe->buf = (uint8_t *) buf + len;
965     }
966 
967     if (len < mps)
968     {
969         *d0fifoctr = R_USB_D0FIFOCTR_BVAL_Msk;
970     }
971 
972     *d0fifosel = 0;
973 
974     /* if CURPIPE bits changes, check written value */
975     FSP_HARDWARE_REGISTER_WAIT((*d0fifosel & R_USB_D0FIFOSEL_CURPIPE_Msk), 0);
976 
977     pipe->remaining = rem - len;
978 
979     return false;
980 }
981 
982 /* process OUT direction transfer for common pipe */
pipe_xfer_out(usbd_instance_ctrl_t * const p_ctrl,uint8_t num)983 static inline bool pipe_xfer_out (usbd_instance_ctrl_t * const p_ctrl, uint8_t num)
984 {
985 #ifdef USB_HIGH_SPEED_MODULE
986     bool                hs_module = USB_IS_USBHS(p_ctrl->p_cfg->module_number);
987     volatile uint16_t * d0fifosel = hs_module ? &R_USB_HS0->D0FIFOSEL : &R_USB_FS0->D0FIFOSEL;
988     volatile uint32_t * d0fifo    = hs_module ? &R_USB_HS0->D0FIFO : &R_USB_FS0->D0FIFO;
989     volatile uint16_t * d0fifoctr = hs_module ? &R_USB_HS0->D0FIFOCTR : &R_USB_FS0->D0FIFOCTR;
990 #else
991     volatile uint16_t * d0fifosel = &R_USB_FS0->D0FIFOSEL;
992     volatile uint32_t * d0fifo    = &R_USB_FS0->D0FIFO;
993     volatile uint16_t * d0fifoctr = &R_USB_FS0->D0FIFOCTR;
994 #endif
995 
996     pipe_state_t * pipe = &g_pipe_cfg[p_ctrl->p_cfg->module_number].pipe[num];
997     const uint16_t rem  = pipe->remaining;
998 
999     *d0fifosel = num | R_USB_FIFOSEL_MBW_8BIT;
1000 
1001     const uint16_t mps = edpt_max_packet_size(p_ctrl, num);
1002     pipe_wait_for_ready(p_ctrl, num);
1003 
1004 #ifdef USB_HIGH_SPEED_MODULE
1005     const uint16_t vld = hs_module ? R_USB_HS0->D0FIFOCTR_b.DTLN : R_USB_FS0->D0FIFOCTR_b.DTLN;
1006 #else
1007     const uint16_t vld = R_USB_FS0->D0FIFOCTR_b.DTLN;
1008 #endif
1009     const uint16_t len = min16(min16(rem, mps), vld);
1010     void         * buf = pipe->buf;
1011 
1012     if (len > 0)
1013     {
1014         pipe_read_packet(p_ctrl, buf, d0fifo, len);
1015         pipe->buf = (uint8_t *) buf + len;
1016     }
1017 
1018     if (len < mps)
1019     {
1020         *d0fifoctr = R_USB_D0FIFOCTR_BCLR_Msk;
1021     }
1022 
1023     *d0fifosel = 0;
1024 
1025     /* if CURPIPE bits changes, check written value */
1026     FSP_HARDWARE_REGISTER_WAIT((*d0fifosel & R_USB_D0FIFOSEL_CURPIPE_Msk), 0);
1027 
1028     pipe->remaining = rem - len;
1029     if ((len < mps) || (rem == len))
1030     {
1031         pipe->buf = NULL;
1032 
1033         return NULL != buf;
1034     }
1035 
1036     return false;
1037 }
1038 
1039 /* setup packet received event handler */
process_setup_packet(usbd_instance_ctrl_t * const p_ctrl)1040 static inline void process_setup_packet (usbd_instance_ctrl_t * const p_ctrl)
1041 {
1042 #ifdef USB_HIGH_SPEED_MODULE
1043     bool                hs_module = USB_IS_USBHS(p_ctrl->p_cfg->module_number);
1044     volatile uint16_t * intsts0   = hs_module ? &R_USB_HS0->INTSTS0 : &R_USB_FS0->INTSTS0;
1045     volatile uint16_t * cfifoctr  = hs_module ? &R_USB_HS0->CFIFOCTR : &R_USB_FS0->CFIFOCTR;
1046 #else
1047     volatile uint16_t * intsts0  = &R_USB_FS0->INTSTS0;
1048     volatile uint16_t * cfifoctr = &R_USB_FS0->CFIFOCTR;
1049 #endif
1050 
1051     if (0 == (*intsts0 & R_USB_INTSTS0_VALID_Msk))
1052     {
1053         return;
1054     }
1055 
1056     *cfifoctr = R_USB_CFIFOCTR_BCLR_Msk;
1057 
1058 #ifdef USB_HIGH_SPEED_MODULE
1059     usbd_event_t event =
1060     {
1061         .event_id       = USBD_EVENT_SETUP_RECEIVED,
1062         .setup_received =
1063         {
1064             hs_module ? R_USB_HS0->USBREQ : R_USB_FS0->USBREQ,
1065             hs_module ? R_USB_HS0->USBVAL : R_USB_FS0->USBVAL,
1066             hs_module ? R_USB_HS0->USBINDX : R_USB_FS0->USBINDX,
1067             hs_module ? R_USB_HS0->USBLENG : R_USB_FS0->USBLENG
1068         }
1069     };
1070 #else
1071     usbd_event_t event =
1072     {
1073         .event_id       = USBD_EVENT_SETUP_RECEIVED,
1074         .setup_received =
1075         {
1076             R_USB_FS0->USBREQ,
1077             R_USB_FS0->USBVAL,
1078             R_USB_FS0->USBINDX,
1079             R_USB_FS0->USBLENG
1080         }
1081     };
1082 #endif
1083 
1084     r_usb_device_call_callback(p_ctrl, &event);
1085 
1086     *intsts0 = ~((uint16_t) R_USB_INTSTS0_VALID_Msk);
1087 }
1088 
1089 /* status packet transfer complete event handler */
process_status_completion(usbd_instance_ctrl_t * const p_ctrl)1090 static inline void process_status_completion (usbd_instance_ctrl_t * const p_ctrl)
1091 {
1092 #ifdef USB_HIGH_SPEED_MODULE
1093     volatile uint16_t * cfifosel =
1094         USB_IS_USBHS(p_ctrl->p_cfg->module_number) ? &R_USB_HS0->CFIFOSEL : &R_USB_FS0->CFIFOSEL;
1095 #else
1096     volatile uint16_t * cfifosel = &R_USB_FS0->CFIFOSEL;
1097 #endif
1098     uint8_t ep_addr;
1099 
1100     /* Check the data stage direction */
1101     if (*cfifosel & R_USB_CFIFOSEL_ISEL_WRITE)
1102     {
1103         /* IN transfer. */
1104         ep_addr = USB_EP_CONTROL_IN;
1105     }
1106     else
1107     {
1108         /* OUT transfer. */
1109         ep_addr = USB_EP_CONTROL_OUT;
1110     }
1111 
1112     usbd_event_t event =
1113     {
1114         .event_id      = USBD_EVENT_XFER_COMPLETE,
1115         .xfer_complete =
1116         {
1117             .result  = USBD_XFER_RESULT_SUCCESS,
1118             .ep_addr = ep_addr,
1119             .len     = 0,
1120         },
1121     };
1122 
1123     r_usb_device_call_callback(p_ctrl, &event);
1124 }
1125 
1126 /* pipe0 transfer */
process_pipe0_xfer(usbd_instance_ctrl_t * const p_ctrl,uint8_t ep_addr,void * buffer,uint16_t total_bytes)1127 static inline fsp_err_t process_pipe0_xfer (usbd_instance_ctrl_t * const p_ctrl,
1128                                             uint8_t                      ep_addr,
1129                                             void                       * buffer,
1130                                             uint16_t                     total_bytes)
1131 {
1132 #ifdef USB_HIGH_SPEED_MODULE
1133     bool                hs_module = USB_IS_USBHS(p_ctrl->p_cfg->module_number);
1134     volatile uint16_t * cfifosel  = hs_module ? &R_USB_HS0->CFIFOSEL : &R_USB_FS0->CFIFOSEL;
1135     volatile uint16_t * dcpctr    = hs_module ? &R_USB_HS0->DCPCTR : &R_USB_FS0->DCPCTR;
1136 #else
1137     volatile uint16_t * cfifosel = &R_USB_FS0->CFIFOSEL;
1138     volatile uint16_t * dcpctr   = &R_USB_FS0->DCPCTR;
1139 #endif
1140 
1141     const uint8_t dir = USB_GET_EP_DIR(ep_addr);
1142     const uint8_t num = g_pipe_cfg[p_ctrl->p_cfg->module_number].ep[USB_PIPECFG_DIR_IDX(dir)][0];
1143 
1144     /* configure fifo direction and access unit settings */
1145     if (USB_EP_CONTROL_IN == ep_addr)
1146     {
1147         /* IN, 2 bytes */
1148         *cfifosel = R_USB_CFIFOSEL_ISEL_WRITE | R_USB_FIFOSEL_MBW_16BIT |
1149                     (BYTE_ORDER == BIG_ENDIAN ? R_USB_FIFOSEL_BIGEND : 0);
1150         FSP_HARDWARE_REGISTER_WAIT((*cfifosel & R_USB_CFIFOSEL_ISEL_Msk), R_USB_CFIFOSEL_ISEL_WRITE);
1151     }
1152     else
1153     {
1154         /* OUT, a byte */
1155         *cfifosel = R_USB_FIFOSEL_MBW_8BIT;
1156         FSP_HARDWARE_REGISTER_WAIT((*cfifosel & R_USB_CFIFOSEL_ISEL_Msk), 0);
1157     }
1158 
1159     pipe_state_t * pipe = &g_pipe_cfg[p_ctrl->p_cfg->module_number].pipe[num];
1160     pipe->length    = total_bytes;
1161     pipe->remaining = total_bytes;
1162 
1163     if (total_bytes > 0)
1164     {
1165         pipe->buf = buffer;
1166         if (USB_EP_CONTROL_IN == ep_addr)
1167         {
1168             pipe0_xfer_in(p_ctrl);
1169         }
1170 
1171         *dcpctr = R_USB_PIPE_CTR_PID_BUF;
1172     }
1173     else
1174     {
1175         /* ZLP */
1176         pipe->buf = NULL;
1177         *dcpctr   = R_USB_DCPCTR_CCPL_Msk | R_USB_PIPE_CTR_PID_BUF;
1178     }
1179 
1180     return FSP_SUCCESS;
1181 }
1182 
1183 /* common pipe transfer */
process_pipe_xfer(usbd_instance_ctrl_t * const p_ctrl,uint8_t ep_addr,void * buffer,uint16_t total_bytes)1184 static inline fsp_err_t process_pipe_xfer (usbd_instance_ctrl_t * const p_ctrl,
1185                                            uint8_t                      ep_addr,
1186                                            void                       * buffer,
1187                                            uint16_t                     total_bytes)
1188 {
1189 #ifdef USB_HIGH_SPEED_MODULE
1190     bool                hs_module = USB_IS_USBHS(p_ctrl->p_cfg->module_number);
1191     volatile uint16_t * d0fifosel = hs_module ? &R_USB_HS0->D0FIFOSEL : &R_USB_FS0->D0FIFOSEL;
1192     volatile uint16_t * d0fifoctr = hs_module ? &R_USB_HS0->D0FIFOCTR : &R_USB_FS0->D0FIFOCTR;
1193 #else
1194     volatile uint16_t * d0fifosel = &R_USB_FS0->D0FIFOSEL;
1195     volatile uint16_t * d0fifoctr = &R_USB_FS0->D0FIFOCTR;
1196 #endif
1197     const uint8_t epn = USB_GET_EP_IDX(ep_addr);
1198     const uint8_t dir = USB_GET_EP_DIR(ep_addr);
1199     const uint8_t num = g_pipe_cfg[p_ctrl->p_cfg->module_number].ep[USB_PIPECFG_DIR_IDX(dir)][epn];
1200 
1201     if (0 == num)
1202     {
1203         return FSP_ERR_USB_NOT_OPEN;
1204     }
1205 
1206     pipe_state_t * pipe = &g_pipe_cfg[p_ctrl->p_cfg->module_number].pipe[num];
1207     pipe->buf       = buffer;
1208     pipe->length    = total_bytes;
1209     pipe->remaining = total_bytes;
1210 
1211     if (USB_EP_IN_DIR == dir)
1212     {
1213         /* IN */
1214         if (total_bytes > 0)
1215         {
1216             pipe_xfer_in(p_ctrl, num);
1217         }
1218         else
1219         {
1220             /* ZLP */
1221             *d0fifosel = num;
1222 
1223             if ((*d0fifoctr & R_USB_CFIFOCTR_BVAL_Msk) != 0)
1224             {
1225                 *d0fifoctr = R_USB_CFIFOCTR_BVAL_Msk;
1226             }
1227 
1228             *d0fifosel = 0;
1229 
1230             /* if CURPIPE bits changes, check written value */
1231             FSP_HARDWARE_REGISTER_WAIT((*d0fifosel & R_USB_D0FIFOSEL_CURPIPE_Msk), 0);
1232         }
1233     }
1234     else
1235     {
1236         /* OUT */
1237         volatile R_USB_PIPE_TR_t * pt = get_pipetre(p_ctrl, num);
1238 
1239         if (NULL != pt)
1240         {
1241             const uint16_t      mps     = edpt_max_packet_size(p_ctrl, num);
1242             volatile uint16_t * pipectr = get_pipectr(p_ctrl, num);
1243 
1244             if (*pipectr & R_USB_PIPE_CTR_PID_Msk)
1245             {
1246                 *pipectr = R_USB_PIPE_CTR_PID_NAK;
1247             }
1248 
1249             pt->E_b.TRCLR = 1;
1250             pt->N         = (total_bytes + mps - 1) / mps;
1251             pt->E_b.TRENB = 1;
1252             *pipectr      = R_USB_PIPE_CTR_PID_BUF;
1253         }
1254     }
1255 
1256     return FSP_SUCCESS;
1257 }
1258 
1259 /* pipe0 BEMP event handler */
process_pipe0_bemp(usbd_instance_ctrl_t * const p_ctrl)1260 static inline void process_pipe0_bemp (usbd_instance_ctrl_t * const p_ctrl)
1261 {
1262     bool completed = pipe0_xfer_in(p_ctrl);
1263 
1264     if (!completed)
1265     {
1266         return;
1267     }
1268 
1269     pipe_state_t * pipe  = &g_pipe_cfg[p_ctrl->p_cfg->module_number].pipe[0];
1270     usbd_event_t   event =
1271     {
1272         .event_id      = USBD_EVENT_XFER_COMPLETE,
1273         .xfer_complete =
1274         {
1275             .result  = USBD_XFER_RESULT_SUCCESS,
1276             .ep_addr = USB_EP_CONTROL_IN,
1277             .len     = pipe->length,
1278         },
1279     };
1280     r_usb_device_call_callback(p_ctrl, &event);
1281 }
1282 
1283 /* BRDY event hanlder  */
process_pipe_brdy(usbd_instance_ctrl_t * const p_ctrl,uint32_t num)1284 static inline void process_pipe_brdy (usbd_instance_ctrl_t * const p_ctrl, uint32_t num)
1285 {
1286     pipe_state_t * pipe = &g_pipe_cfg[p_ctrl->p_cfg->module_number].pipe[num];
1287     const uint32_t dir  = USB_GET_EP_DIR(pipe->ep);
1288     bool           completed;
1289 
1290     if (USB_EP_IN_DIR == dir)
1291     {
1292         completed = pipe_xfer_in(p_ctrl, num);
1293     }
1294     else
1295     {
1296         /* OUT */
1297         if (num)
1298         {
1299             completed = pipe_xfer_out(p_ctrl, num);
1300         }
1301         else
1302         {
1303             completed = pipe0_xfer_out(p_ctrl);
1304         }
1305     }
1306 
1307     if (completed)
1308     {
1309         usbd_event_t event =
1310         {
1311             .event_id      = USBD_EVENT_XFER_COMPLETE,
1312             .xfer_complete =
1313             {
1314                 .result  = USBD_XFER_RESULT_SUCCESS,
1315                 .ep_addr = pipe->ep,
1316                 .len     = pipe->length - pipe->remaining,
1317             },
1318         };
1319         r_usb_device_call_callback(p_ctrl, &event);
1320     }
1321 }
1322 
usbfs_module_bus_reset(void)1323 static inline usbd_speed_t usbfs_module_bus_reset (void)
1324 {
1325     usbd_speed_t speed;
1326 
1327     R_USB_FS0->BEMPENB  = 1;
1328     R_USB_FS0->BRDYENB  = 1;
1329     R_USB_FS0->CFIFOCTR = R_USB_CFIFOCTR_BCLR_Msk;
1330 
1331     R_USB_FS0->D0FIFOSEL = 0;
1332 
1333     /* if CURPIPE bits changes, check written value */
1334     FSP_HARDWARE_REGISTER_WAIT(R_USB_FS0->D0FIFOSEL_b.CURPIPE, 0);
1335 
1336     R_USB_FS0->D1FIFOSEL = 0;
1337 
1338     /* if CURPIPE bits changes, check written value */
1339     FSP_HARDWARE_REGISTER_WAIT(R_USB_FS0->D0FIFOSEL_b.CURPIPE, 0);
1340 
1341     volatile uint16_t * pipectr = (volatile uint16_t *) &R_USB_FS0->PIPE_CTR[0];
1342     volatile uint16_t * pipetre = (volatile uint16_t *) &R_USB_FS0->PIPE_TR[0].E;
1343 
1344     for (int i = 1; i <= 5; ++i)
1345     {
1346         R_USB_FS0->PIPESEL = i;
1347         R_USB_FS0->PIPECFG = 0;
1348         *pipectr           = R_USB_PIPE_CTR_ACLRM_Msk;
1349         *pipectr           = 0;
1350         ++pipectr;
1351         *pipetre = (1 << 8);
1352         pipetre += 2;
1353     }
1354 
1355     for (int i = 6; i <= 9; ++i)
1356     {
1357         R_USB_FS0->PIPESEL = i;
1358         R_USB_FS0->PIPECFG = 0;
1359         *pipectr           = R_USB_PIPE_CTR_ACLRM_Msk;
1360         *pipectr           = 0;
1361         ++pipectr;
1362     }
1363 
1364     switch (R_USB_FS0->DVSTCTR0 & R_USB_DVSTCTR0_RHST_Msk)
1365     {
1366         case (1 << R_USB_DVSTCTR0_RHST_Pos):
1367         {
1368             speed = USBD_SPEED_LS;
1369             break;
1370         }
1371 
1372         case (2 << R_USB_DVSTCTR0_RHST_Pos):
1373         {
1374             speed = USBD_SPEED_FS;
1375             break;
1376         }
1377 
1378         case (3 << R_USB_DVSTCTR0_RHST_Pos):
1379         {
1380             speed = USBD_SPEED_HS;
1381             break;
1382         }
1383 
1384         default:
1385         {
1386             speed = USBD_SPEED_INVALID;
1387             break;
1388         }
1389     }
1390 
1391     return speed;
1392 }
1393 
1394 #ifdef USB_HIGH_SPEED_MODULE
usbhs_module_bus_reset(void)1395 static inline usbd_speed_t usbhs_module_bus_reset (void)
1396 {
1397     usbd_speed_t speed;
1398 
1399     R_USB_HS0->BEMPENB  = 1;
1400     R_USB_HS0->BRDYENB  = 1;
1401     R_USB_HS0->CFIFOCTR = R_USB_CFIFOCTR_BCLR_Msk;
1402 
1403     R_USB_HS0->D0FIFOSEL = 0;
1404 
1405     /* if CURPIPE bits changes, check written value */
1406     FSP_HARDWARE_REGISTER_WAIT(R_USB_HS0->D0FIFOSEL_b.CURPIPE, 0);
1407 
1408     R_USB_HS0->D1FIFOSEL = 0;
1409 
1410     /* if CURPIPE bits changes, check written value */
1411     FSP_HARDWARE_REGISTER_WAIT(R_USB_HS0->D0FIFOSEL_b.CURPIPE, 0);
1412 
1413     volatile uint16_t * pipectr = (volatile uint16_t *) ((uintptr_t) (&R_USB_HS0->PIPE_CTR[0]));
1414     volatile uint16_t * pipetre = (volatile uint16_t *) ((uintptr_t) (&R_USB_HS0->PIPE_TR[0].E));
1415 
1416     for (int i = 1; i <= 5; ++i)
1417     {
1418         R_USB_HS0->PIPESEL = i;
1419         R_USB_HS0->PIPECFG = 0;
1420         *pipectr           = R_USB_PIPE_CTR_ACLRM_Msk;
1421         *pipectr           = 0;
1422         ++pipectr;
1423         *pipetre = (1 << 8);
1424         pipetre += 2;
1425     }
1426 
1427     for (int i = 6; i <= 9; ++i)
1428     {
1429         R_USB_HS0->PIPESEL = i;
1430         R_USB_HS0->PIPECFG = 0;
1431         *pipectr           = R_USB_PIPE_CTR_ACLRM_Msk;
1432         *pipectr           = 0;
1433         ++pipectr;
1434     }
1435 
1436     switch (R_USB_HS0->DVSTCTR0 & R_USB_DVSTCTR0_RHST_Msk)
1437     {
1438         case (1 << R_USB_DVSTCTR0_RHST_Pos):
1439         {
1440             speed = USBD_SPEED_LS;
1441             break;
1442         }
1443 
1444         case (2 << R_USB_DVSTCTR0_RHST_Pos):
1445         {
1446             speed = USBD_SPEED_FS;
1447             break;
1448         }
1449 
1450         case (3 << R_USB_DVSTCTR0_RHST_Pos):
1451         {
1452             speed = USBD_SPEED_HS;
1453             break;
1454         }
1455 
1456         default:
1457         {
1458             speed = USBD_SPEED_INVALID;
1459             break;
1460         }
1461     }
1462 
1463     return speed;
1464 }
1465 
1466 #endif
1467 
1468 /* BUS_RESET event handler */
process_bus_reset(usbd_instance_ctrl_t * const p_ctrl)1469 static inline void process_bus_reset (usbd_instance_ctrl_t * const p_ctrl)
1470 {
1471     usbd_speed_t speed = USBD_SPEED_INVALID;
1472 
1473 #ifdef USB_HIGH_SPEED_MODULE
1474     if (USB_IS_USBHS(p_ctrl->p_cfg->module_number))
1475     {
1476         speed = usbhs_module_bus_reset();
1477     }
1478     else
1479 #endif
1480     {
1481         speed = usbfs_module_bus_reset();
1482     }
1483 
1484     usbd_event_t event =
1485     {
1486         .event_id        = USBD_EVENT_BUS_RESET,
1487         .bus_reset.speed = speed,
1488     };
1489 
1490     r_usb_device_call_callback(p_ctrl, &event);
1491 }
1492 
1493 /* SET_ADDRESS request packet received event handler */
process_set_address(usbd_instance_ctrl_t * const p_ctrl)1494 static inline void process_set_address (usbd_instance_ctrl_t * const p_ctrl)
1495 {
1496 #ifdef USB_HIGH_SPEED_MODULE
1497     const bool     is_usbhs = USB_IS_USBHS(p_ctrl->p_cfg->module_number);
1498     const uint16_t addr     = (is_usbhs ? R_USB_HS0->USBADDR : R_USB_FS0->USBADDR) & 0x7fUL;
1499 #else
1500     const uint16_t addr = R_USB_FS0->USBADDR & 0x7fUL;
1501 #endif
1502 
1503     if (0 == addr)
1504     {
1505         return;
1506     }
1507 
1508     usbd_event_t event =
1509     {
1510         .event_id       = USBD_EVENT_SETUP_RECEIVED,
1511         .setup_received =
1512         {
1513             .request_type   = USB_REQUEST_TYPE_SET_ADDRESS,
1514             .request_value  = addr,
1515             .request_index  = 0,
1516             .request_length = 0,
1517         },
1518     };
1519 
1520     r_usb_device_call_callback(p_ctrl, &event);
1521 }
1522 
1523 /* configure for usb physical layer */
physical_init(usbd_instance_ctrl_t * const p_ctrl,usbd_cfg_t const * const p_cfg)1524 static inline void physical_init (usbd_instance_ctrl_t * const p_ctrl, usbd_cfg_t const * const p_cfg)
1525 {
1526 #ifdef USB_HIGH_SPEED_MODULE
1527     if (USB_IS_USBHS(p_cfg->module_number))
1528     {
1529         /* High-speed selection */
1530         R_USB_HS0->SYSCFG_b.HSE = (p_cfg->usb_speed == USBD_SPEED_HS) ? 1 : 0;
1531 
1532         /* Power and reset UTMI PHY */
1533         uint16_t physet = (R_USB_HS0->PHYSET | R_USB_PHYSET_PLLRESET_Msk) & ~R_USB_PHYSET_DIRPD_Msk;
1534 
1535         physet           |= (USBHS_PHY_CLOCK_SOURCE_IS_XTAL == 0) ? R_USB_PHYSET_HSEB_Msk : 0;
1536         R_USB_HS0->PHYSET = physet;
1537 
1538         /* Setting the PHY clock */
1539  #if USBHS_PHY_CLOCK_SOURCE_IS_XTAL
1540         R_USB_HS0->PHYSET_b.CLKSEL = USBD_CFG_PHYSET_CLKSEL;
1541  #endif
1542         R_BSP_SoftwareDelay(1, BSP_DELAY_UNITS_MICROSECONDS);
1543 
1544         /* PHY power down selection */
1545         R_USB_HS0->SYSCFG_b.DRPD = 0;
1546         R_BSP_SoftwareDelay(1, BSP_DELAY_UNITS_MILLISECONDS);
1547 
1548         /* PHY return */
1549         R_USB_HS0->PHYSET_b.PLLRESET = 0;
1550 
1551         /* Set UTMI to operating mode and wait for PLL lock confirmation */
1552         R_USB_HS0->LPSTS_b.SUSPENDM = 1;
1553         FSP_HARDWARE_REGISTER_WAIT(R_USB_HS0->PLLSTA_b.PLLLOCK, 1);
1554 
1555         /* Enable USB operation */
1556         R_USB_HS0->SYSCFG_b.USBE = 1;
1557 
1558         /* Set CPU bus wait time */
1559         R_USB_HS0->BUSWAIT |= USBD_CFG_BUS_WAIT_TIME;
1560 
1561         /* Adjust terminating resistance at 16-second intervals */
1562         R_USB_HS0->PHYSET_b.REPSEL = 1;
1563     }
1564     else
1565 #endif
1566     {
1567         /* Enable clock supply to USBFS */
1568         R_USB_FS0->SYSCFG_b.SCKE = 1;
1569         FSP_HARDWARE_REGISTER_WAIT(R_USB_FS0->SYSCFG_b.SCKE, 1);
1570 
1571         /* Disable line pull-down */
1572         R_USB_FS0->SYSCFG_b.DRPD = 0;
1573 
1574         /* Select controller as device controller */
1575         R_USB_FS0->SYSCFG_b.DCFM = 0;
1576 
1577         /* Enable module operation */
1578         R_USB_FS0->SYSCFG_b.USBE = 1;
1579 
1580         /* Adjust PHY cross point */
1581         R_USB_FS0->PHYSLEW = 0x5;      /* TODO: tunning it */
1582 
1583         /* USB_BASE Transceiver Output fixed */
1584         R_USB_FS0->DPUSR0R_FS_b.FIXPHY0 = 0;
1585     }
1586 }
1587 
1588 /* setting default pipe0 to ready for enumerations */
control_pipe_setup(usbd_instance_ctrl_t * const p_ctrl)1589 static inline void control_pipe_setup (usbd_instance_ctrl_t * const p_ctrl)
1590 {
1591 #ifdef USB_HIGH_SPEED_MODULE
1592     if (USB_IS_USBHS(p_ctrl->p_cfg->module_number))
1593     {
1594         R_USB_HS0->DCPMAXP_b.MXPS = 64;
1595         R_USB_HS0->BEMPENB        = 1;
1596         R_USB_HS0->BRDYENB        = 1;
1597     }
1598     else
1599 #endif
1600     {
1601         R_USB_FS0->DCPMAXP_b.MXPS = 64;
1602         R_USB_FS0->BEMPENB        = 1;
1603         R_USB_FS0->BRDYENB        = 1;
1604     }
1605 }
1606 
usb_interrupt_configure(usbd_instance_ctrl_t * p_ctrl,usbd_cfg_t const * p_cfg)1607 static inline void usb_interrupt_configure (usbd_instance_ctrl_t * p_ctrl, usbd_cfg_t const * p_cfg)
1608 {
1609 #ifdef USB_HIGH_SPEED_MODULE
1610     if (USB_IS_USBHS(p_cfg->module_number))
1611     {
1612         R_USB_HS0->INTSTS0 = 0;
1613         R_USB_HS0->INTENB0 = R_USB_INTSTS0_VBINT_Msk | R_USB_INTSTS0_BRDY_Msk | R_USB_INTSTS0_BEMP_Msk |
1614                              R_USB_INTSTS0_DVST_Msk | R_USB_INTSTS0_CTRT_Msk |
1615                              R_USB_INTSTS0_RESM_Msk;
1616 
1617         R_BSP_IrqCfgEnable(p_cfg->hs_irq, p_cfg->hsipl, p_ctrl);
1618     }
1619     else
1620 #endif
1621     {
1622         R_USB_FS0->INTSTS0 = 0;
1623         R_USB_FS0->INTENB0 = R_USB_INTSTS0_VBINT_Msk | R_USB_INTSTS0_BRDY_Msk | R_USB_INTSTS0_BEMP_Msk |
1624                              R_USB_INTSTS0_DVST_Msk | R_USB_INTSTS0_CTRT_Msk |
1625                              R_USB_INTSTS0_RESM_Msk;
1626 
1627         R_BSP_IrqCfgEnable(p_cfg->irq, p_cfg->ipl, p_ctrl);
1628         R_BSP_IrqCfgEnable(p_cfg->irq_r, p_cfg->ipl_r, p_ctrl);
1629     }
1630 }
1631 
r_usb_device_call_callback(usbd_instance_ctrl_t * p_ctrl,usbd_event_t * event)1632 static void r_usb_device_call_callback (usbd_instance_ctrl_t * p_ctrl, usbd_event_t * event)
1633 {
1634     usbd_callback_arg_t   args;
1635     usbd_callback_arg_t * p_args = p_ctrl->p_callback_memory;
1636 
1637     if (NULL == p_ctrl->p_callback)
1638     {
1639         return;
1640     }
1641 
1642     if (NULL == p_args)
1643     {
1644         /* Store on stack */
1645         p_args = &args;
1646     }
1647     else
1648     {
1649         /* Save current arguments on the stack in case this is a nested interrupt. */
1650         args = *p_args;
1651     }
1652 
1653     p_args->module_number = p_ctrl->p_cfg->module_number;
1654     p_args->p_context     = p_ctrl->p_context;
1655     memcpy(&p_args->event, event, sizeof(usbd_event_t));
1656 
1657     p_ctrl->p_callback(p_args);
1658 
1659     if (NULL != p_ctrl->p_callback_memory)
1660     {
1661         /* Restore callback memory in case this is a nested interrupt. */
1662         *p_ctrl->p_callback_memory = args;
1663     }
1664 }
1665 
usb_module_register_clear(uint8_t usb_ip)1666 static inline void usb_module_register_clear (uint8_t usb_ip)
1667 {
1668 #ifdef USB_HIGH_SPEED_MODULE
1669     if (USB_IS_USBHS(usb_ip))
1670     {
1671         R_USB_HS0->DVSTCTR0    = 0;
1672         R_USB_HS0->DCPCTR      = R_USB_PIPE_CTR_SQSET_Msk;
1673         R_USB_HS0->PIPE_CTR[0] = 0;
1674         R_USB_HS0->PIPE_CTR[1] = 0;
1675         R_USB_HS0->PIPE_CTR[2] = 0;
1676         R_USB_HS0->PIPE_CTR[3] = 0;
1677         R_USB_HS0->PIPE_CTR[4] = 0;
1678         R_USB_HS0->PIPE_CTR[5] = 0;
1679         R_USB_HS0->PIPE_CTR[6] = 0;
1680         R_USB_HS0->PIPE_CTR[7] = 0;
1681         R_USB_HS0->PIPE_CTR[8] = 0;
1682         R_USB_HS0->BRDYENB     = 0;
1683         R_USB_HS0->NRDYENB     = 0;
1684         R_USB_HS0->BEMPENB     = 0;
1685         R_USB_HS0->INTENB0     = 0;
1686         R_USB_HS0->INTENB1     = 0;
1687         R_USB_HS0->BRDYSTS     = 0;
1688         R_USB_HS0->NRDYSTS     = 0;
1689         R_USB_HS0->BEMPSTS     = 0;
1690         R_USB_HS0->SYSCFG     &= (~R_USB_SYSCFG_DPRPU_Msk);
1691         R_USB_HS0->SYSCFG     &= (~R_USB_SYSCFG_USBE_Msk);
1692         R_USB_HS0->SYSCFG     &= (~R_USB_SYSCFG_DRPD_Msk);
1693         R_USB_HS0->SYSCFG     &= (~R_USB_SYSCFG_DCFM_Msk);
1694         R_USB_HS0->LPSTS       = 0;
1695     }
1696     else
1697 #endif
1698     {
1699         R_USB_FS0->DVSTCTR0    = 0;
1700         R_USB_FS0->DCPCTR      = R_USB_PIPE_CTR_SQSET_Msk;
1701         R_USB_FS0->PIPE_CTR[0] = 0;
1702         R_USB_FS0->PIPE_CTR[1] = 0;
1703         R_USB_FS0->PIPE_CTR[2] = 0;
1704         R_USB_FS0->PIPE_CTR[3] = 0;
1705         R_USB_FS0->PIPE_CTR[4] = 0;
1706         R_USB_FS0->PIPE_CTR[5] = 0;
1707         R_USB_FS0->PIPE_CTR[6] = 0;
1708         R_USB_FS0->PIPE_CTR[7] = 0;
1709         R_USB_FS0->PIPE_CTR[8] = 0;
1710         R_USB_FS0->BRDYENB     = 0;
1711         R_USB_FS0->NRDYENB     = 0;
1712         R_USB_FS0->BEMPENB     = 0;
1713         R_USB_FS0->INTENB0     = 0;
1714         R_USB_FS0->INTENB1     = 0;
1715         R_USB_FS0->BRDYSTS     = 0;
1716         R_USB_FS0->NRDYSTS     = 0;
1717         R_USB_FS0->BEMPSTS     = 0;
1718         R_USB_FS0->SYSCFG     &= (~R_USB_SYSCFG_DPRPU_Msk);
1719         R_USB_FS0->SYSCFG     &= (~R_USB_SYSCFG_DRPD_Msk);
1720         R_USB_FS0->SYSCFG     &= (~R_USB_SYSCFG_DCFM_Msk);
1721         R_USB_FS0->SYSCFG     &= (~R_USB_SYSCFG_USBE_Msk);
1722     }
1723 
1724     R_BSP_SoftwareDelay(1, BSP_DELAY_UNITS_MICROSECONDS);
1725 }
1726 
usb_module_start(usbd_instance_ctrl_t * p_ctrl)1727 static inline void usb_module_start (usbd_instance_ctrl_t * p_ctrl)
1728 {
1729 #ifdef USB_HIGH_SPEED_MODULE
1730     if (USB_IS_USBHS(p_ctrl->p_cfg->module_number))
1731     {
1732         R_BSP_MODULE_START(FSP_IP_USBHS, 0);
1733     }
1734     else
1735 #endif
1736     {
1737         R_BSP_MODULE_START(FSP_IP_USBFS, 0);
1738     }
1739 }
1740 
usb_module_stop(usbd_instance_ctrl_t * p_ctrl)1741 static inline void usb_module_stop (usbd_instance_ctrl_t * p_ctrl)
1742 {
1743     usb_module_register_clear(p_ctrl->p_cfg->module_number);
1744 
1745 #ifdef USB_HIGH_SPEED_MODULE
1746     if (USB_IS_USBHS(p_ctrl->p_cfg->module_number))
1747     {
1748         R_BSP_MODULE_STOP(FSP_IP_USBHS, 0);
1749     }
1750     else
1751 #endif
1752     {
1753         R_BSP_MODULE_STOP(FSP_IP_USBFS, 0);
1754     }
1755 }
1756 
usb_disable_interrupt(usbd_instance_ctrl_t * p_ctrl)1757 static inline void usb_disable_interrupt (usbd_instance_ctrl_t * p_ctrl)
1758 {
1759 #ifdef USB_HIGH_SPEED_MODULE
1760     if (USB_IS_USBHS(p_ctrl->p_cfg->module_number))
1761     {
1762         R_USB_HS0->INTENB0 &= ~(R_USB_INTSTS0_VBINT_Msk | R_USB_INTSTS0_BRDY_Msk | R_USB_INTSTS0_BEMP_Msk |
1763                                 R_USB_INTSTS0_DVST_Msk | R_USB_INTSTS0_CTRT_Msk |
1764                                 R_USB_INTSTS0_RESM_Msk);
1765 
1766         R_BSP_IrqDisable(p_ctrl->p_cfg->hs_irq);
1767     }
1768     else
1769 #endif
1770     {
1771         R_USB_FS0->INTENB0 &= ~(R_USB_INTSTS0_VBINT_Msk | R_USB_INTSTS0_BRDY_Msk | R_USB_INTSTS0_BEMP_Msk |
1772                                 R_USB_INTSTS0_DVST_Msk | R_USB_INTSTS0_CTRT_Msk |
1773                                 R_USB_INTSTS0_RESM_Msk);
1774 
1775         R_BSP_IrqDisable(p_ctrl->p_cfg->irq);
1776         R_BSP_IrqDisable(p_ctrl->p_cfg->irq_r);
1777     }
1778 }
1779 
usb_enable_interrupt(usbd_instance_ctrl_t * p_ctrl)1780 static inline void usb_enable_interrupt (usbd_instance_ctrl_t * p_ctrl)
1781 {
1782 #ifdef USB_HIGH_SPEED_MODULE
1783     if (USB_IS_USBHS(p_ctrl->p_cfg->module_number))
1784     {
1785         R_BSP_IrqEnable(p_ctrl->p_cfg->hs_irq);
1786 
1787         R_USB_HS0->INTENB0 = R_USB_INTSTS0_VBINT_Msk | R_USB_INTSTS0_BRDY_Msk | R_USB_INTSTS0_BEMP_Msk |
1788                              R_USB_INTSTS0_DVST_Msk | R_USB_INTSTS0_CTRT_Msk |
1789                              R_USB_INTSTS0_RESM_Msk;
1790     }
1791     else
1792 #endif
1793     {
1794         R_BSP_IrqEnable(p_ctrl->p_cfg->irq);
1795         R_BSP_IrqEnable(p_ctrl->p_cfg->irq_r);
1796 
1797         R_USB_FS0->INTENB0 = R_USB_INTSTS0_VBINT_Msk | R_USB_INTSTS0_BRDY_Msk | R_USB_INTSTS0_BEMP_Msk |
1798                              R_USB_INTSTS0_DVST_Msk | R_USB_INTSTS0_CTRT_Msk |
1799                              R_USB_INTSTS0_RESM_Msk;
1800     }
1801 }
1802 
process_pipe_forced_termination(usbd_instance_ctrl_t * const p_ctrl,uint8_t ep)1803 static inline void process_pipe_forced_termination (usbd_instance_ctrl_t * const p_ctrl, uint8_t ep)
1804 {
1805     const uint8_t epn = USB_GET_EP_IDX(ep);
1806     const uint8_t dir = USB_GET_EP_DIR(ep);
1807     const uint8_t num = g_pipe_cfg[p_ctrl->p_cfg->module_number].ep[USB_PIPECFG_DIR_IDX(dir)][epn];
1808 
1809     if (0 == num)
1810     {
1811         /* This endpoint is not yet opened */
1812         return;
1813     }
1814 
1815     volatile uint16_t * pt      = get_pipetre(p_ctrl, num);
1816     volatile uint16_t * pipectr = get_pipectr(p_ctrl, num);
1817 
1818     /* Set NAK */
1819     if (0 != (*pipectr & R_USB_PIPE_CTR_PID_Msk))
1820     {
1821         *pipectr = R_USB_PIPE_CTR_PID_NAK;
1822     }
1823 
1824 #ifdef USB_HIGH_SPEED_MODULE
1825     if (USB_IS_USBHS(p_ctrl->p_cfg->module_number))
1826     {
1827         /* Disable pipe interrupt */
1828         R_USB_HS0->BRDYENB &= (uint16_t) ~(1 << num);
1829         R_USB_HS0->NRDYENB &= (uint16_t) ~(1 << num);
1830         R_USB_HS0->BEMPENB &= (uint16_t) ~(1 << num);
1831 
1832         /* Clear transaction counter */
1833         *pt &= ~R_USB_PIPE_TR_E_TRENB_Msk;
1834         *pt |= R_USB_PIPE_TR_E_TRCLR_Msk;
1835 
1836         /* Clear FIFO port */
1837         if (num == R_USB_HS0->D0FIFOSEL_b.CURPIPE)
1838         {
1839             R_USB_HS0->D0FIFOSEL_b.CURPIPE = 0;
1840         }
1841     }
1842     else
1843 #endif
1844     {
1845         R_USB_FS0->BRDYENB &= (uint16_t) ~(1 << num);
1846         R_USB_FS0->NRDYENB &= (uint16_t) ~(1 << num);
1847         R_USB_FS0->BEMPENB &= (uint16_t) ~(1 << num);
1848 
1849         /* Clear transaction counter */
1850         *pt &= ~R_USB_PIPE_TR_E_TRENB_Msk;
1851         *pt |= R_USB_PIPE_TR_E_TRCLR_Msk;
1852 
1853         /* Clear FIFO port */
1854         if (num == R_USB_FS0->D0FIFOSEL_b.CURPIPE)
1855         {
1856             R_USB_FS0->D0FIFOSEL_b.CURPIPE = 0;
1857         }
1858     }
1859 
1860     /* Buffer clear */
1861     *pipectr |= R_USB_PIPE_CTR_ACLRM_Msk;
1862     *pipectr &= ~R_USB_PIPE_CTR_ACLRM_Msk;
1863 
1864     /* SPLIT Buffer clear */
1865     *pipectr &= R_USB_PIPE_CTR_CSCLR_Msk;
1866 }
1867 
get_active_bit_intsts0(usbd_instance_ctrl_t * p_ctrl)1868 static inline uint16_t get_active_bit_intsts0 (usbd_instance_ctrl_t * p_ctrl)
1869 {
1870     uint16_t intsts0 = 0;
1871 
1872 #ifdef USB_HIGH_SPEED_MODULE
1873     if (USB_IS_USBHS(p_ctrl->p_cfg->module_number))
1874     {
1875         intsts0 = R_USB_HS0->INTSTS0;
1876 
1877         /* clear active bits except VALID (don't write 0 to already cleared bits according to the HW manual) */
1878         R_USB_HS0->INTSTS0 = ~((R_USB_INTSTS0_CTRT_Msk | R_USB_INTSTS0_DVST_Msk | R_USB_INTSTS0_SOFR_Msk |
1879                                 R_USB_INTSTS0_RESM_Msk | R_USB_INTSTS0_VBINT_Msk) & intsts0) | R_USB_INTSTS0_VALID_Msk;
1880     }
1881     else
1882 #endif
1883     {
1884         intsts0 = R_USB_FS0->INTSTS0;
1885 
1886         /* clear active bits except VALID (don't write 0 to already cleared bits according to the HW manual) */
1887         R_USB_FS0->INTSTS0 = ~((R_USB_INTSTS0_CTRT_Msk | R_USB_INTSTS0_DVST_Msk | R_USB_INTSTS0_SOFR_Msk |
1888                                 R_USB_INTSTS0_RESM_Msk | R_USB_INTSTS0_VBINT_Msk) & intsts0) | R_USB_INTSTS0_VALID_Msk;
1889     }
1890 
1891     return intsts0;
1892 }
1893 
process_vbus_changed(usbd_instance_ctrl_t * p_ctrl,uint16_t intsts0)1894 static inline void process_vbus_changed (usbd_instance_ctrl_t * p_ctrl, uint16_t intsts0)
1895 {
1896     usbd_event_t event;
1897 
1898     if (intsts0 & R_USB_INTSTS0_VBSTS_Msk)
1899     {
1900         event.event_id = USBD_EVENT_VBUS_RDY;
1901     }
1902     else
1903     {
1904         event.event_id = USBD_EVENT_VBUS_REMOVED;
1905     }
1906 
1907     r_usb_device_call_callback(p_ctrl, &event);
1908 }
1909 
process_resumed_event(usbd_instance_ctrl_t * p_ctrl)1910 static inline void process_resumed_event (usbd_instance_ctrl_t * p_ctrl)
1911 {
1912     usbd_event_t event =
1913     {
1914         .event_id = USBD_EVENT_RESUME,
1915     };
1916 
1917 #ifdef USB_HIGH_SPEED_MODULE
1918     if (USB_IS_USBHS(p_ctrl->p_cfg->module_number))
1919     {
1920         R_USB_HS0->INTENB0_b.SOFE = 0;
1921     }
1922     else
1923 #endif
1924     {
1925         R_USB_FS0->INTENB0_b.SOFE = 0;
1926     }
1927 
1928     r_usb_device_call_callback(p_ctrl, &event);
1929 }
1930 
process_sof_event(usbd_instance_ctrl_t * p_ctrl)1931 static inline void process_sof_event (usbd_instance_ctrl_t * p_ctrl)
1932 {
1933     usbd_event_t event =
1934     {
1935         .event_id = USBD_EVENT_SOF,
1936     };
1937 
1938 #ifdef USB_HIGH_SPEED_MODULE
1939     if (USB_IS_USBHS(p_ctrl->p_cfg->module_number))
1940     {
1941         if (R_USB_HS0->INTENB0_b.SOFE)
1942         {
1943             R_USB_HS0->INTENB0_b.SOFE = 0;
1944         }
1945         else
1946         {
1947             return;
1948         }
1949     }
1950     else
1951 #endif
1952     {
1953         if (R_USB_FS0->INTENB0_b.SOFE)
1954         {
1955             R_USB_FS0->INTENB0_b.SOFE = 0;
1956         }
1957         else
1958         {
1959             return;
1960         }
1961     }
1962 
1963     r_usb_device_call_callback(p_ctrl, &event);
1964 }
1965 
process_suppend_event(usbd_instance_ctrl_t * p_ctrl)1966 static inline void process_suppend_event (usbd_instance_ctrl_t * p_ctrl)
1967 {
1968     usbd_event_t event =
1969     {
1970         .event_id = USBD_EVENT_SUSPEND,
1971     };
1972 
1973 #ifdef USB_HIGH_SPEED_MODULE
1974     if (USB_IS_USBHS(p_ctrl->p_cfg->module_number))
1975     {
1976         R_USB_HS0->INTENB0_b.SOFE = 1;
1977     }
1978     else
1979 #endif
1980     {
1981         R_USB_FS0->INTENB0_b.SOFE = 1;
1982     }
1983 
1984     r_usb_device_call_callback(p_ctrl, &event);
1985 }
1986 
process_nrdy_event(usbd_instance_ctrl_t * p_ctrl)1987 static inline void process_nrdy_event (usbd_instance_ctrl_t * p_ctrl)
1988 {
1989 #ifdef USB_HIGH_SPEED_MODULE
1990     if (USB_IS_USBHS(p_ctrl->p_cfg->module_number))
1991     {
1992         R_USB_HS0->NRDYSTS = 0;
1993     }
1994     else
1995 #endif
1996     {
1997         R_USB_FS0->NRDYSTS = 0;
1998     }
1999 }
2000 
process_bemp_event(usbd_instance_ctrl_t * p_ctrl)2001 static inline void process_bemp_event (usbd_instance_ctrl_t * p_ctrl)
2002 {
2003 #ifdef USB_HIGH_SPEED_MODULE
2004     const bool     is_usbhs = USB_IS_USBHS(p_ctrl->p_cfg->module_number);
2005     const uint16_t bempsts  = is_usbhs ? R_USB_HS0->BEMPSTS : R_USB_FS0->BEMPSTS;
2006 #else
2007     const uint16_t bempsts = R_USB_FS0->BEMPSTS;
2008 #endif
2009 
2010 #ifdef USB_HIGH_SPEED_MODULE
2011     if (is_usbhs)
2012     {
2013         R_USB_HS0->BEMPSTS = 0;
2014     }
2015     else
2016 #endif
2017     {
2018         R_USB_FS0->BEMPSTS = 0;
2019     }
2020 
2021     if ((bempsts & 0x1U) != 0)
2022     {
2023         process_pipe0_bemp(p_ctrl);
2024     }
2025 }
2026 
process_brdy_event(usbd_instance_ctrl_t * p_ctrl)2027 static inline void process_brdy_event (usbd_instance_ctrl_t * p_ctrl)
2028 {
2029 #ifdef USB_HIGH_SPEED_MODULE
2030     const bool     is_usbhs = USB_IS_USBHS(p_ctrl->p_cfg->module_number);
2031     const uint16_t brdyenb  = is_usbhs ? R_USB_HS0->BRDYENB : R_USB_FS0->BRDYENB;
2032     uint16_t       brdysts  = (is_usbhs ? R_USB_HS0->BRDYSTS : R_USB_FS0->BRDYSTS) & brdyenb;
2033 #else
2034     const uint16_t brdyenb = R_USB_FS0->BRDYENB;
2035     uint16_t       brdysts = R_USB_FS0->BRDYSTS & brdyenb;
2036 #endif
2037 
2038     /* clear active bits (don't write 0 to already cleared bits according to the HW manual) */
2039 #ifdef USB_HIGH_SPEED_MODULE
2040     if (is_usbhs)
2041     {
2042         R_USB_HS0->BRDYSTS = ~brdysts;
2043     }
2044     else
2045 #endif
2046     {
2047         R_USB_FS0->BRDYSTS = ~brdysts;
2048     }
2049 
2050     while (brdysts)
2051     {
2052         const uint32_t num = get_first_bit1_offset(brdysts);
2053         process_pipe_brdy(p_ctrl, num);
2054         brdysts &= ~(1 << num);
2055     }
2056 }
2057 
2058 /***********************************************************************************************************************
2059  * USB device isr
2060  **********************************************************************************************************************/
usb_device_isr(void)2061 void usb_device_isr (void)
2062 {
2063     /* Save context if RTOS is used */
2064     FSP_CONTEXT_SAVE
2065 
2066     IRQn_Type irq = R_FSP_CurrentIrqGet();
2067 
2068     usbd_instance_ctrl_t * p_ctrl = R_FSP_IsrContextGet(irq);
2069 
2070     uint16_t intsts0 = get_active_bit_intsts0(p_ctrl);
2071 
2072     /* VBUS changes */
2073     if (intsts0 & R_USB_INTSTS0_VBINT_Msk)
2074     {
2075         process_vbus_changed(p_ctrl, intsts0);
2076     }
2077 
2078     /* Resumed */
2079     if (intsts0 & R_USB_INTSTS0_RESM_Msk)
2080     {
2081         process_resumed_event(p_ctrl);
2082     }
2083 
2084     /* SOF received */
2085     if (intsts0 & R_USB_INTSTS0_SOFR_Msk)
2086     {
2087         process_sof_event(p_ctrl);
2088     }
2089 
2090     /* Device state changes */
2091     if (intsts0 & R_USB_INTSTS0_DVST_Msk)
2092     {
2093         switch (intsts0 & R_USB_INTSTS0_DVSQ_Msk)
2094         {
2095             case R_USB_INTSTS0_DVSQ_STATE_DEF:
2096             {
2097                 process_bus_reset(p_ctrl);
2098                 break;
2099             }
2100 
2101             case R_USB_INTSTS0_DVSQ_STATE_ADDR:
2102             {
2103                 process_set_address(p_ctrl);
2104                 break;
2105             }
2106 
2107             case R_USB_INTSTS0_DVSQ_STATE_SUSP0:
2108             case R_USB_INTSTS0_DVSQ_STATE_SUSP1:
2109             case R_USB_INTSTS0_DVSQ_STATE_SUSP2:
2110             case R_USB_INTSTS0_DVSQ_STATE_SUSP3:
2111             {
2112                 process_suppend_event(p_ctrl);
2113                 break;
2114             }
2115 
2116             default:
2117             {
2118                 break;
2119             }
2120         }
2121     }
2122 
2123     if (intsts0 & R_USB_INTSTS0_NRDY_Msk)
2124     {
2125         process_nrdy_event(p_ctrl);
2126     }
2127 
2128     /* Control transfer stage changes */
2129     if (intsts0 & R_USB_INTSTS0_CTRT_Msk)
2130     {
2131         if (intsts0 & R_USB_INTSTS0_CTSQ_CTRL_RDATA)
2132         {
2133             /* A setup packet has been received. */
2134             process_setup_packet(p_ctrl);
2135         }
2136         else if (0 == (intsts0 & R_USB_INTSTS0_CTSQ_Msk))
2137         {
2138             /* A ZLP has been sent/received. */
2139             process_status_completion(p_ctrl);
2140         }
2141     }
2142 
2143     /* Buffer empty */
2144     if (intsts0 & R_USB_INTSTS0_BEMP_Msk)
2145     {
2146         process_bemp_event(p_ctrl);
2147     }
2148 
2149     /* Buffer ready */
2150     if (intsts0 & R_USB_INTSTS0_BRDY_Msk)
2151     {
2152         process_brdy_event(p_ctrl);
2153     }
2154 
2155     /* Clear pending IRQ to make sure it doesn't fire again after exiting */
2156     R_BSP_IrqStatusClear(irq);
2157 
2158     /* Restore context if RTOS is used */
2159     FSP_CONTEXT_RESTORE
2160 }
2161