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