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 "r_usb_host.h"
11 #include "bsp_api.h"
12
13 /***********************************************************************************************************************
14 * Macro definitions
15 **********************************************************************************************************************/
16 #define USBH_OPEN (0x55534248) /* USBH in ASCII */
17 #define USB_HS_MODULE_NUMBER_START (1)
18 #define USB_MODULE_NUM (2)
19
20 #define USB_SETBIT(n) (1UL << (n))
21
22 #if defined(__GNUC__)
23 #define CTZ(x) (__builtin_ctz(x))
24 #else
25 #error "Compiler not supported"
26 #endif
27
28 #define USB_DIRPD (0x0001U) /* b0: Power down control */
29 #define USB_PLLRESET (0x0002U) /* b1: PLL reset control */
30 #define USB_CLKSEL (0x0030U) /* b5-4: System clock setting */
31 #define USB_REPSEL_16 (0x0100U) /* 16 sec */
32 #define USB_CLKSEL_20 (0x0020U) /* 20MHz */
33 #define USB_HSEB (0x8000U) /* b15: CL only mode bit */
34 #define USB_PLLLOCK (0x0001U)
35
36 #define USB_SIGN (0x0020U) /* b5: Setup ignore interrupt */
37 #define USB_SACK (0x0010U) /* b4: Setup ack interrupt */
38 #define USB_SIGNE (0x0020U) /* b5: SETUP IGNORE interrupt */
39 #define USB_SACKE (0x0010U) /* b4: SETUP ACK interrupt */
40 #define INTSTS1_MASK (0xD870U) /* INTSTS1 Reserved bit mask */
41 #define USB_UACT (0x0010U) /* b4: USB bus enable */
42 #define USB_RESUME (0x0020U) /* b5: Resume enable */
43 #define USB_USBRST (0x0040U) /* b6: USB reset enable */
44 #define USB_HSPROC (0x0004U) /* HS handshake processing */
45 #define USB_RHST (0x0007U) /* b2-0: Reset handshake status */
46 #define USB_SUSPENDM (0x4000U) /* b14: UTMI SuspendM control */
47 #define USB_SQSET (0x0080U) /* b7: Sequence bit set */
48
49 /* System Configuration Control Register */
50 #define USB_USBE (0x0001U) /* b0: USB module enable */
51 #define USB_DPRPU (0x0010U) /* b4: D+ pull up control */
52 #define USB_DRPD (0x0020U) /* b5: D+/D- pull down control */
53 #define USB_DCFM (0x0040U) /* b6: Function select */
54
55 /* PIPE_CTR */
56 #define USB_PIPE_CTR_ACLRM_Pos (9UL) /* ACLRM (Bit 9) */
57 #define USB_PIPE_CTR_ACLRM_Msk (0x200UL) /* ACLRM (Bitfield-Mask: 0x01) */
58 #define USB_PIPE_CTR_SQCLR_Pos (8UL) /* SQCLR (Bit 8) */
59 #define USB_PIPE_CTR_SQCLR_Msk (0x100UL) /* SQCLR (Bitfield-Mask: 0x01) */
60 #define USB_PIPE_CTR_PID_Pos (0UL) /* PID (Bit 0) */
61 #define USB_PIPE_CTR_PID_Msk (0x3UL) /* PID (Bitfield-Mask: 0x03) */
62
63 /* PIPECFG */
64 #define USB_PIPECFG_TYPE_Pos (14UL) /* TYPE (Bit 14) */
65 #define USB_PIPECFG_TYPE_Msk (0xc000UL) /* TYPE (Bitfield-Mask: 0x03) */
66 #define USB_PIPECFG_DBLB_Pos (9UL) /* DBLB (Bit 9) */
67 #define USB_PIPECFG_DBLB_Msk (0x200UL) /* DBLB (Bitfield-Mask: 0x01) */
68 #define USB_PIPECFG_SHTNAK_Pos (7UL) /* SHTNAK (Bit 7) */
69 #define USB_PIPECFG_SHTNAK_Msk (0x80UL) /* SHTNAK (Bitfield-Mask: 0x01) */
70
71 /* INTSTS0 */
72 #define USB_INTSTS0_BEMP_Pos (10UL) /* BEMP (Bit 10) */
73 #define USB_INTSTS0_BEMP_Msk (0x400UL) /* BEMP (Bitfield-Mask: 0x01) */
74 #define USB_INTSTS0_NRDY_Pos (9UL) /* NRDY (Bit 9) */
75 #define USB_INTSTS0_NRDY_Msk (0x200UL) /* NRDY (Bitfield-Mask: 0x01) */
76 #define USB_INTSTS0_BRDY_Pos (8UL) /* BRDY (Bit 8) */
77 #define USB_INTSTS0_BRDY_Msk (0x100UL) /* BRDY (Bitfield-Mask: 0x01) */
78
79 /* INTSTS1 */
80 #define USB_INTSTS1_OVRCR_Pos (15UL) /* OVRCR (Bit 15) */
81 #define USB_INTSTS1_OVRCR_Msk (0x8000UL) /* OVRCR (Bitfield-Mask: 0x01) */
82 #define USB_INTSTS1_BCHG_Pos (14UL) /* BCHG (Bit 14) */
83 #define USB_INTSTS1_BCHG_Msk (0x4000UL) /* BCHG (Bitfield-Mask: 0x01) */
84 #define USB_INTSTS1_DTCH_Pos (12UL) /* DTCH (Bit 12) */
85 #define USB_INTSTS1_DTCH_Msk (0x1000UL) /* DTCH (Bitfield-Mask: 0x01) */
86 #define USB_INTSTS1_ATTCH_Pos (11UL) /* ATTCH (Bit 11) */
87 #define USB_INTSTS1_ATTCH_Msk (0x800UL) /* ATTCH (Bitfield-Mask: 0x01) */
88 #define USB_INTSTS1_L1RSMEND_Pos (9UL) /* L1RSMEND (Bit 9) */
89 #define USB_INTSTS1_L1RSMEND_Msk (0x200UL) /* L1RSMEND (Bitfield-Mask: 0x01) \
90 */
91 #define USB_INTSTS1_EOFERR_Pos (6UL) /* EOFERR (Bit 6) */
92 #define USB_INTSTS1_EOFERR_Msk (0x40UL) /* EOFERR (Bitfield-Mask: 0x01) */
93 #define USB_INTSTS1_SIGN_Pos (5UL) /* SIGN (Bit 5) */
94 #define USB_INTSTS1_SIGN_Msk (0x20UL) /* SIGN (Bitfield-Mask: 0x01) */
95 #define USB_INTSTS1_SACK_Pos (4UL) /* SACK (Bit 4) */
96 #define USB_INTSTS1_SACK_Msk (0x10UL) /* SACK (Bitfield-Mask: 0x01) */
97
98 #define USB_PIPE_CTR_PID_NAK (0U << USB_PIPE_CTR_PID_Pos) /* NAK response */
99 #define USB_PIPE_CTR_PID_BUF (1U << USB_PIPE_CTR_PID_Pos) /* BUF response (depends buffer state) */
100 #define USB_PIPE_CTR_PID_STALL (2U << USB_PIPE_CTR_PID_Pos) /* STALL response \
101 */
102 #define USB_PIPE_CTR_PID_STALL2 (3U << USB_PIPE_CTR_PID_Pos) /* Also STALL response */
103
104 #define USB_CFIFOSEL_ISEL_Pos (5UL) /* ISEL (Bit 5) */
105
106 #define USB_DEVADD_USBSPD_Pos (6UL) /* USBSPD (Bit 6) */
107 #define USB_DEVADD_USBSPD_Msk (0xc0UL) /* USBSPD (Bitfield-Mask: 0x03) */
108 #define USB_DEVADD_USBSPD_LS (1U << USB_DEVADD_USBSPD_Pos) /* Target Device Low-speed */
109 #define USB_DEVADD_USBSPD_FS (2U << USB_DEVADD_USBSPD_Pos) /* Target Device Full-speed */
110 #define USB_DEVADD_USBSPD_HS (3U << USB_DEVADD_USBSPD_Pos) /* Target Device Full-speed */
111
112 #define USB_PIPECFG_TYPE_BULK (1U << USB_PIPECFG_TYPE_Pos)
113 #define USB_PIPECFG_TYPE_INT (2U << USB_PIPECFG_TYPE_Pos)
114 #define USB_PIPECFG_TYPE_ISO (3U << USB_PIPECFG_TYPE_Pos)
115
116 #define USB_CFIFOCTR_BVAL_Pos (15UL) /* BVAL (Bit 15) */
117 #define USB_CFIFOCTR_BVAL_Msk (0x8000UL) /* BVAL (Bitfield-Mask: 0x01) */
118
119 #define USB_CFIFOSEL_ISEL_WRITE (1U << USB_CFIFOSEL_ISEL_Pos) /* FIFO write AKA TX*/
120
121 #define USB_CFIFOSEL_MBW_Pos (10UL) /* MBW (Bit 10) */
122
123 #define USB_FIFOSEL_MBW_8BIT (0U << USB_CFIFOSEL_MBW_Pos) /* 8-bit width */
124 #define USB_FIFOSEL_MBW_16BIT (1U << USB_CFIFOSEL_MBW_Pos) /* 16-bit width */
125 #define USB_FIFOSEL_MBW_32BIT (2U << USB_CFIFOSEL_MBW_Pos) /* 32-bit width */
126
127 #define USB_D0FIFOCTR_BCLR_Msk (0x4000UL) /* BCLR (Bitfield-Mask: 0x01) */
128 #define USB_CFIFOCTR_BCLR_Msk (0x4000UL) /* BCLR (Bitfield-Mask: 0x01) */
129
130 #define USB_D0FIFOCTR_BVAL_Pos (15UL) /* BVAL (Bit 15) */
131 #define USB_D0FIFOCTR_BVAL_Msk (0x8000UL) /* BVAL (Bitfield-Mask: 0x01) */
132
133 #define USB_DEVADDRBIT (12U)
134 #define USB_UPPHUB (0x7800U) /* b14-11: HUB register */
135 #define USB_HUBPORT (0x0700U) /* b10-8: HUB port */
136 #define USB_USBSPD (0x00C0U) /* b7-6: Device speed */
137 #define USB_DEVICE_0 (0x0000U) /* Device address 0 */
138 #define USB_DEFPACKET (0x0040U) /* Default DCP Max packet size */
139
140 #define USB_STATUS_ATTACH (1 << 0)
141 #define USB_STATUS_DETACH (1 << 1)
142 #define USB_STATUS_EOFERR (1 << 2)
143 #define USB_STATUS_OVRCR (1 << 3)
144
145 #define USB_DVSTCTR0_RHST_LS (1U) /* Low-speed connection */
146 #define USB_DVSTCTR0_RHST_FS (2U) /* Full-speed connection */
147 #define USB_DVSTCTR0_RHST_HS (3U) /* Full-speed connection */
148
149 #define USB_HS_DEVADD_NUM (0x0A)
150 #define USB_FS_DEVADD_NUM (0x05)
151
152 #define USB_PIPE_COUNT 10
153 #define USB_DEVICE_NUM 4
154
155 #define USB_MIN(_x, _y) (((_x) < (_y)) ? (_x) : (_y))
156 #define USB_MAX(_x, _y) (((_x) > (_y)) ? (_x) : (_y))
157
158 /***********************************************************************************************************************
159 * Typedef definitions
160 **********************************************************************************************************************/
161 typedef __PACKED_UNION
162 {
163 struct
164 {
165 volatile uint16_t u8 : 8;
166 volatile uint16_t : 0;
167 };
168
169 volatile uint16_t u16;
170 } hw_fifo_t;
171
172 typedef __PACKED_STRUCT
173 {
174 union
175 {
176 struct
177 {
178 uint16_t : 8;
179 uint16_t TRCLR : 1;
180 uint16_t TRENB : 1;
181 uint16_t : 0;
182 };
183
184 uint16_t TRE;
185 };
186
187 uint16_t TRN;
188 } usb_reg_pipetre_t;
189
190 typedef __PACKED_STRUCT st_pipe_state
191 {
192 void * buf; /* the start address of a transfer data buffer */
193 uint16_t length; /* the number of bytes in the buffer */
194 uint16_t remaining; /* the number of bytes remaining in the buffer */
195 struct
196 {
197 uint32_t ep : 8; /* an assigned endpoint address */
198 uint32_t dev : 8; /* an assigned device address */
199 uint32_t ff : 1; /* `buf` is USB_FUFO or POD */
200 uint32_t : 0;
201 };
202 } pipe_state_t;
203
204 typedef struct st_usbh_dev0
205 {
206 uint8_t hub_addr;
207 uint8_t hub_port;
208 __PACKED_STRUCT
209 {
210 uint8_t speed : 4; /* packed speed to save footprint */
211 volatile uint8_t enumerating : 1; /* enumeration is in progress, false if not connected or all interfaces are configured */
212 uint8_t USB_RESERVED : 3;
213 } usbh_dev0_info;
214 } usbh_dev0_t;
215
216 typedef struct st_uhc_data
217 {
218 pipe_state_t pipe[10];
219 uint8_t ep[USB_DEVICE_NUM][2][USB_PIPE_COUNT]; /* a lookup table for a pipe index from an endpoint address */
220 uint8_t ctl_mps[USB_DEVICE_NUM]; /* EP0 max packet size for each device */
221 usbh_dev0_t dev0;
222 } uhc_data_t;
223
224 /***********************************************************************************************************************
225 * Private function prototypes
226 **********************************************************************************************************************/
r_usbh_edpt_addr(uint8_t num,uint8_t dir)227 static inline uint8_t r_usbh_edpt_addr (uint8_t num, uint8_t dir)
228 {
229 return (uint8_t) (num | (dir ? USB_DIR_IN_MASK : 0));
230 }
231
r_usbh_edpt_number(uint8_t addr)232 static inline uint8_t r_usbh_edpt_number (uint8_t addr)
233 {
234 return (uint8_t) (addr & (~USB_DIR_IN_MASK));
235 }
236
r_usbh_edpt_dir(uint8_t addr)237 static inline usb_dir_t r_usbh_edpt_dir (uint8_t addr)
238 {
239 return (addr & USB_DIR_IN_MASK) ? USB_DIR_IN : USB_DIR_OUT;
240 }
241
r_usbh_edpt_packet_size(usb_desc_endpoint_t const * desc_ep)242 static inline uint16_t r_usbh_edpt_packet_size (usb_desc_endpoint_t const * desc_ep)
243 {
244 return (desc_ep->wMaxPacketSize) & 0x7FF;
245 }
246
247 static volatile uint16_t * r_usbh_get_pipectr(usbh_instance_ctrl_t * const p_ctrl, uint32_t num);
248 static uint32_t r_usbh_find_pipe(usbh_instance_ctrl_t * const p_ctrl, uint8_t xfer_type);
249 static fsp_err_t r_usbh_hw_module_start(usbh_instance_ctrl_t * const p_ctrl);
250 static fsp_err_t r_usbh_hw_init(usbh_instance_ctrl_t * const p_ctrl);
251 static fsp_err_t r_usbh_module_register_clear(usbh_instance_ctrl_t * const p_ctrl);
252 static fsp_err_t r_usbh_hw_module_stop(usbh_instance_ctrl_t * const p_ctrl);
253 static uint16_t r_usb_chk_dev_addr(usbh_instance_ctrl_t * p_ctrl, uint16_t addr);
254 static void r_usbh_device_release(usbh_instance_ctrl_t * p_ctrl, uint8_t dev_addr);
255 static bool r_usbh_process_edpt_xfer(usbh_instance_ctrl_t * const p_ctrl,
256 uint8_t dev_addr,
257 uint8_t ep_addr,
258 void * buffer,
259 uint16_t buflen);
260 static bool r_usbh_process_pipe_xfer(usbh_instance_ctrl_t * const p_ctrl,
261 uint8_t dev_addr,
262 uint8_t ep_addr,
263 void * buffer,
264 uint16_t buflen);
265 static bool r_usbh_process_pipe0_xfer(usbh_instance_ctrl_t * const p_ctrl,
266 uint8_t dev_addr,
267 uint8_t ep_addr,
268 void * buffer,
269 uint16_t buflen);
270 static bool r_usbh_pipe_xfer_out(usbh_instance_ctrl_t * const p_ctrl, uint32_t num);
271 static bool r_usbh_pipe0_xfer_out(usbh_instance_ctrl_t * const p_ctrl);
272 static bool r_usbh_pipe_xfer_in(usbh_instance_ctrl_t * const p_ctrl, uint32_t num);
273 static bool r_usbh_pipe0_xfer_in(usbh_instance_ctrl_t * const p_ctrl);
274 static void r_usbh_pipe_write_packet(void * buf, volatile void * fifo, uint32_t len);
275 static void r_usbh_pipe_read_packet(void * buf, volatile void * fifo, uint32_t len);
276 static uint16_t r_usbh_edpt_max_packet_size(usbh_instance_ctrl_t * const p_ctrl, uint32_t num);
277 static uint16_t r_usbh_edpt0_max_packet_size(usbh_instance_ctrl_t * const p_ctrl);
278
279 /***********************************************************************************************************************
280 * Private global variables
281 **********************************************************************************************************************/
282 uhc_data_t g_uhc_data[USB_MODULE_NUM];
283
284 /***********************************************************************************************************************
285 * Functions
286 **********************************************************************************************************************/
287
288 /**
289 * @brief Start USB module, configure correct operate mode and default pipe0
290 *
291 * @param p_api_ctrl [in]
292 * @param p_cfg [in]
293 *
294 * @retval FSP_SUCCESS on success
295 * @retval FSP_ERR_UNSUPPORTED if USB module just support FS only
296 * @retval FSP_ERR_ALREADY_OPEN if USB module has opened
297 */
R_USBH_Open(usb_ctrl_t * const p_api_ctrl,usb_cfg_t const * const p_cfg)298 fsp_err_t R_USBH_Open (usb_ctrl_t * const p_api_ctrl, usb_cfg_t const * const p_cfg)
299 {
300 usbh_instance_ctrl_t * p_ctrl = (usbh_instance_ctrl_t *) p_api_ctrl;
301
302 #if USBH_CFG_PARAM_CHECKING_ENABLE
303 FSP_ASSERT(p_api_ctrl)
304 FSP_ASSERT(p_cfg)
305 FSP_ERROR_RETURN(0 == p_ctrl->open, FSP_ERR_ALREADY_OPEN);
306
307 /* Make sure this channel exists. */
308 FSP_ERROR_RETURN(USB_MODULE_NUM > p_cfg->module_number, FSP_ERR_IP_CHANNEL_NOT_PRESENT);
309 #endif
310
311 p_ctrl->module_number = p_cfg->module_number;
312 if (p_cfg->module_number < USB_HS_MODULE_NUMBER_START)
313 {
314 p_ctrl->p_reg = (void *) R_USB_FS0_BASE;
315 }
316 else
317 {
318 p_ctrl->p_reg = (void *) R_USB_HS0_BASE;
319 }
320
321 if (p_cfg->high_speed)
322 {
323 p_ctrl->max_speed = USB_SPEED_HS;
324 }
325 else
326 {
327 p_ctrl->max_speed = USB_SPEED_FS;
328 }
329
330 #if USBD_CFG_PARAM_CHECKING_ENABLE
331 if (USB_HS_MODULE_NUMBER_START != p_cfg->module_number)
332 {
333 return FSP_ERR_UNSUPPORTED;
334 }
335 #endif
336
337 p_ctrl->p_cfg = p_cfg;
338 p_ctrl->p_callback = p_cfg->p_callback;
339 p_ctrl->p_context = p_cfg->p_context;
340 p_ctrl->p_callback_memory = NULL;
341
342 /* Start module */
343 r_usbh_hw_module_start(p_ctrl);
344
345 /* Initialize usb host hardware layer */
346 r_usbh_hw_init(p_ctrl);
347
348 if (p_cfg->hs_irq != BSP_IRQ_DISABLED)
349 {
350 R_BSP_IrqCfg(p_cfg->hs_irq, p_cfg->hsipl, p_ctrl);
351 }
352
353 memset(&g_uhc_data, 0, sizeof(uhc_data_t));
354
355 p_ctrl->open = USBH_OPEN;
356
357 return FSP_SUCCESS;
358 }
359
360 /**
361 * @brief Get port status
362 *
363 * @param p_api_ctrl [in]
364 *
365 * @retval status
366 */
R_USBH_PortStatusGet(usb_ctrl_t * const p_api_ctrl,usb_status_t * p_status)367 fsp_err_t R_USBH_PortStatusGet (usb_ctrl_t * const p_api_ctrl, usb_status_t * p_status)
368 {
369 usbh_instance_ctrl_t * p_ctrl = (usbh_instance_ctrl_t *) p_api_ctrl;
370
371 #if USBH_CFG_PARAM_CHECKING_ENABLE
372 FSP_ASSERT(p_api_ctrl)
373 FSP_ASSERT(p_status)
374 FSP_ERROR_RETURN(0 != p_ctrl->open, FSP_ERR_NOT_OPEN);
375 #endif
376
377 R_USB_HS0_Type * p_reg = (R_USB_HS0_Type *) p_ctrl->p_reg;
378 *p_status = 0;
379
380 uint16_t info = p_reg->INTSTS1;
381 if ((info & USB_INTSTS1_OVRCR_Msk) != 0)
382 {
383 *p_status |= USB_STATUS_OVRCR;
384 }
385
386 if ((info & USB_INTSTS1_EOFERR_Msk) != 0)
387 {
388 *p_status |= USB_STATUS_EOFERR;
389 }
390
391 if ((info & USB_INTSTS1_ATTCH_Msk) != 0)
392 {
393 *p_status |= USB_STATUS_ATTACH;
394 }
395
396 if ((info & USB_INTSTS1_DTCH_Msk) != 0)
397 {
398 *p_status |= USB_STATUS_DETACH;
399 }
400
401 if ((info & USB_INTSTS1_SACK_Msk) != 0)
402 {
403 *p_status |= USB_STATUS_DETACH;
404 }
405
406 return FSP_SUCCESS;
407 }
408
409 /**
410 * @brief Reset port
411 *
412 * @param p_api_ctrl [in]
413 *
414 * @retval FSP_SUCCESS on success
415 * @retval FSP_ERR_NOT_OPEN if USB host has not been opened
416 */
R_USBH_PortReset(usb_ctrl_t * const p_api_ctrl)417 fsp_err_t R_USBH_PortReset (usb_ctrl_t * const p_api_ctrl)
418 {
419 usbh_instance_ctrl_t * p_ctrl = (usbh_instance_ctrl_t *) p_api_ctrl;
420 R_USB_HS0_Type * p_reg = (R_USB_HS0_Type *) p_ctrl->p_reg;
421
422 #if USBH_CFG_PARAM_CHECKING_ENABLE
423 FSP_ASSERT(p_api_ctrl)
424 FSP_ERROR_RETURN(0 != p_ctrl->open, FSP_ERR_NOT_OPEN);
425 #endif
426
427 p_reg->DCPCTR = USB_PIPE_CTR_PID_NAK;
428
429 FSP_HARDWARE_REGISTER_WAIT(p_reg->DCPCTR_b.PBUSY, 0);
430
431 R_BSP_IrqDisable(p_ctrl->p_cfg->irq);
432
433 p_reg->DVSTCTR0_b.UACT = 0;
434 if (p_reg->DCPCTR_b.SUREQ)
435 {
436 p_reg->DCPCTR_b.SUREQCLR = 1;
437 }
438
439 R_BSP_IrqEnable(p_ctrl->p_cfg->irq);
440
441 p_reg->DVSTCTR0_b.USBRST = 1;
442
443 /* Reset should be asserted 10-20ms. */
444 R_BSP_SoftwareDelay(20, BSP_DELAY_UNITS_MILLISECONDS);
445
446 p_reg->DVSTCTR0_b.USBRST = 0;
447 p_reg->DVSTCTR0_b.UACT = 1;
448
449 return FSP_SUCCESS;
450 }
451
452 /**
453 * @brief Get usb device speed
454 *
455 * @param p_api_ctrl [in]
456 * @param p_speed [out]
457 *
458 * @retval FSP_SUCCESS on success
459 * @retval FSP_ERR_NOT_OPEN if USB host has not been opened
460 */
R_USBH_GetDeviceSpeed(usb_ctrl_t * const p_api_ctrl,usb_speed_t * p_speed)461 fsp_err_t R_USBH_GetDeviceSpeed (usb_ctrl_t * const p_api_ctrl, usb_speed_t * p_speed)
462 {
463 usbh_instance_ctrl_t * p_ctrl = (usbh_instance_ctrl_t *) p_api_ctrl;
464
465 #if USBH_CFG_PARAM_CHECKING_ENABLE
466 FSP_ASSERT(p_api_ctrl)
467 FSP_ASSERT(p_speed)
468 FSP_ERROR_RETURN(0 != p_ctrl->open, FSP_ERR_NOT_OPEN);
469 #endif
470
471 R_USB_HS0_Type * p_reg = (R_USB_HS0_Type *) p_ctrl->p_reg;
472
473 switch (p_reg->DVSTCTR0_b.RHST)
474 {
475 case USB_DVSTCTR0_RHST_HS:
476 {
477 *p_speed = USB_SPEED_HS;
478 break;
479 }
480
481 case USB_DVSTCTR0_RHST_FS:
482 {
483 *p_speed = USB_SPEED_FS;
484 break;
485 }
486
487 case USB_DVSTCTR0_RHST_LS:
488 {
489 *p_speed = USB_SPEED_LS;
490 break;
491 }
492
493 default:
494 {
495 *p_speed = USB_SPEED_INVALID;
496 }
497 }
498
499 g_uhc_data[p_ctrl->p_cfg->module_number].dev0.usbh_dev0_info.speed = *p_speed;
500
501 return FSP_SUCCESS;
502 }
503
504 /**
505 * @brief Release usb device
506 *
507 * @param p_api_ctrl [in]
508 *
509 * @retval FSP_SUCCESS on success
510 * @retval FSP_ERR_NOT_OPEN if USB host has not been opened
511 */
R_USBH_DeviceRelease(usb_ctrl_t * const p_api_ctrl,uint8_t dev_addr)512 fsp_err_t R_USBH_DeviceRelease (usb_ctrl_t * const p_api_ctrl, uint8_t dev_addr)
513 {
514 usbh_instance_ctrl_t * p_ctrl = (usbh_instance_ctrl_t *) p_api_ctrl;
515
516 #if USBH_CFG_PARAM_CHECKING_ENABLE
517 FSP_ASSERT(p_api_ctrl)
518 FSP_ERROR_RETURN(0 != p_ctrl->open, FSP_ERR_NOT_OPEN);
519 FSP_ASSERT(dev_addr < USB_DEVICE_NUM);
520 #endif
521
522 if (r_usb_chk_dev_addr(p_ctrl, dev_addr) != 0)
523 {
524 r_usbh_device_release(p_ctrl, dev_addr);
525
526 return FSP_SUCCESS;
527 }
528
529 return FSP_ERR_ABORTED;
530 }
531
532 /**
533 * @brief Setup send
534 *
535 * @param p_api_ctrl [in]
536 * @param dev_addr [in]
537 * @param setup_packet [in]
538 *
539 * @retval FSP_SUCCESS on success
540 * @retval FSP_ERR_NOT_OPEN if USB host has not been opened
541 */
R_USBH_SetupSend(usb_ctrl_t * const p_api_ctrl,uint8_t dev_addr,uint8_t const setup_packet[8])542 fsp_err_t R_USBH_SetupSend (usb_ctrl_t * const p_api_ctrl, uint8_t dev_addr, uint8_t const setup_packet[8])
543 {
544 usbh_instance_ctrl_t * p_ctrl = (usbh_instance_ctrl_t *) p_api_ctrl;
545
546 #if USBH_CFG_PARAM_CHECKING_ENABLE
547 FSP_ASSERT(p_api_ctrl)
548 FSP_ERROR_RETURN(0 != p_ctrl->open, FSP_ERR_NOT_OPEN);
549 FSP_ERROR_RETURN(dev_addr < USB_DEVICE_NUM, FSP_ERR_INVALID_ARGUMENT);
550 #endif
551
552 R_USB_HS0_Type * p_reg = (R_USB_HS0_Type *) p_ctrl->p_reg;
553
554 FSP_ERROR_RETURN(0 == p_reg->DCPCTR_b.SUREQ, FSP_ERR_USB_FAILED);
555
556 p_reg->DCPCTR = USB_PIPE_CTR_PID_NAK;
557
558 g_uhc_data[p_ctrl->p_cfg->module_number].pipe[0].buf = NULL;
559 g_uhc_data[p_ctrl->p_cfg->module_number].pipe[0].length = 8;
560 g_uhc_data[p_ctrl->p_cfg->module_number].pipe[0].remaining = 0;
561 g_uhc_data[p_ctrl->p_cfg->module_number].pipe[0].dev = dev_addr;
562
563 FSP_HARDWARE_REGISTER_WAIT(p_reg->DCPCTR_b.PBUSY, 0);
564
565 p_reg->DCPMAXP = (dev_addr << 12) | g_uhc_data[p_ctrl->p_cfg->module_number].ctl_mps[dev_addr];
566
567 /* Set direction in advance for DATA stage */
568 uint8_t const bmRequesttype = setup_packet[0];
569 p_reg->DCPCFG_b.DIR = r_usbh_edpt_dir(bmRequesttype) ? 0 : 1;
570
571 uint16_t const * p = (uint16_t const *) (uintptr_t) &setup_packet[0];
572 p_reg->USBREQ = p[0];
573 p_reg->USBVAL = p[1];
574 p_reg->USBINDX = p[2];
575 p_reg->USBLENG = p[3];
576
577 p_reg->INTSTS1 = (uint16_t) ((~USB_SIGN) & INTSTS1_MASK);
578 p_reg->INTSTS1 = (uint16_t) ((~USB_SACK) & INTSTS1_MASK);
579 p_reg->INTENB1 |= USB_SIGNE;
580 p_reg->INTENB1 |= USB_SACKE;
581
582 p_reg->DCPCTR_b.SUREQ = 1;
583
584 return FSP_SUCCESS;
585 }
586
587 /**
588 * @brief Open an endpoint
589 *
590 * @param p_api_ctrl [in]
591 * @param dev_addr [in]
592 * @param ep_desc [in]
593 * @param p_api_ctrl [in]
594 *
595 * @retval FSP_SUCCESS on success
596 * @retval FSP_ERR_NOT_OPEN if USB host has not been opened
597 */
R_USBH_EdptOpen(usb_ctrl_t * const p_api_ctrl,uint8_t dev_addr,usb_desc_endpoint_t const * ep_desc)598 fsp_err_t R_USBH_EdptOpen (usb_ctrl_t * const p_api_ctrl, uint8_t dev_addr, usb_desc_endpoint_t const * ep_desc)
599 {
600 usbh_instance_ctrl_t * p_ctrl = (usbh_instance_ctrl_t *) p_api_ctrl;
601
602 #if USBH_CFG_PARAM_CHECKING_ENABLE
603 FSP_ASSERT(p_api_ctrl)
604 FSP_ASSERT(ep_desc)
605 FSP_ERROR_RETURN(0 != p_ctrl->open, FSP_ERR_NOT_OPEN);
606 FSP_ASSERT(dev_addr < USB_DEVICE_NUM);
607
608 FSP_ERROR_RETURN(dev_addr != 0, FSP_ERR_INVALID_ARGUMENT);
609 #endif
610
611 R_USB_HS0_Type * p_reg = (R_USB_HS0_Type *) p_ctrl->p_reg;
612 const uint8_t ep_addr = ep_desc->bEndpointAddress;
613 const uint8_t epn = r_usbh_edpt_number(ep_addr);
614 const uint32_t mps = r_usbh_edpt_packet_size(ep_desc);
615
616 const uint8_t dir_in = r_usbh_edpt_dir(ep_addr);
617 const uint8_t xfer = ep_desc->bmAttributes.xfer;
618
619 if (xfer == USB_XFER_ISOCHRONOUS)
620 {
621 /* USBa supports up to 256 bytes */
622 FSP_ERROR_RETURN(mps <= 256, FSP_ERR_INVALID_ARGUMENT);
623 }
624
625 const uint32_t num = r_usbh_find_pipe(p_ctrl, xfer);
626
627 /* There are no available pipes that can be configured for this endpoint. */
628 FSP_ERROR_RETURN(0 != num, FSP_ERR_USB_BUSY);
629
630 g_uhc_data[p_ctrl->p_cfg->module_number].pipe[num].dev = dev_addr;
631 g_uhc_data[p_ctrl->p_cfg->module_number].pipe[num].ep = ep_addr;
632 g_uhc_data[p_ctrl->p_cfg->module_number].ep[dev_addr - 1][dir_in][epn - 1] = num;
633
634 /* setup pipe */
635 R_BSP_IrqDisable(p_ctrl->p_cfg->irq);
636
637 p_reg->PIPESEL = num;
638 p_reg->PIPEMAXP = (dev_addr << 12) | mps;
639 volatile uint16_t * ctr = r_usbh_get_pipectr(p_ctrl, num);
640 *ctr = USB_PIPE_CTR_ACLRM_Msk | USB_PIPE_CTR_SQCLR_Msk;
641 *ctr = 0;
642
643 uint16_t cfg = ((1 ^ dir_in) << 4) | epn;
644 if (xfer == USB_XFER_BULK)
645 {
646 cfg |= USB_PIPECFG_TYPE_BULK | USB_PIPECFG_SHTNAK_Msk | USB_PIPECFG_DBLB_Msk;
647 }
648 else if (xfer == USB_XFER_INTERRUPT)
649 {
650 cfg |= USB_PIPECFG_TYPE_INT;
651 }
652 else
653 {
654 cfg |= USB_PIPECFG_TYPE_ISO | USB_PIPECFG_DBLB_Msk;
655 }
656
657 p_reg->PIPECFG = cfg;
658 p_reg->BRDYSTS = 0x3FFu ^ USB_SETBIT(num);
659 p_reg->NRDYENB |= USB_SETBIT(num);
660 p_reg->BRDYENB |= USB_SETBIT(num);
661
662 if (dir_in == 0)
663 {
664 /* OUT */
665 *ctr = USB_PIPE_CTR_PID_BUF;
666 }
667
668 R_BSP_IrqEnable(p_ctrl->p_cfg->irq);
669
670 return FSP_SUCCESS;
671 }
672
673 /**
674 * @brief Open a USB port to start communicate with USB device
675 *
676 * @param p_api_ctrl [in]
677 * @param dev_addr [in]
678 *
679 * @retval FSP_SUCCESS on success
680 * @retval FSP_ERR_NOT_OPEN if USB host has not been opened
681 */
R_USBH_PortOpen(usb_ctrl_t * const p_api_ctrl,uint8_t dev_addr)682 fsp_err_t R_USBH_PortOpen (usb_ctrl_t * const p_api_ctrl, uint8_t dev_addr)
683 {
684 usbh_instance_ctrl_t * p_ctrl = (usbh_instance_ctrl_t *) p_api_ctrl;
685
686 #if USBH_CFG_PARAM_CHECKING_ENABLE
687 FSP_ASSERT(p_api_ctrl)
688 FSP_ERROR_RETURN(0 != p_ctrl->open, FSP_ERR_NOT_OPEN);
689
690 /* Currently, USBH only support 1 USB device */
691 FSP_ASSERT(dev_addr != 1);
692 #endif
693
694 uint16_t volatile * devadd = &R_USB_HS0->DEVADD[dev_addr];
695
696 R_USB_HS0->DCPCTR = USB_PIPE_CTR_PID_NAK;
697 FSP_HARDWARE_REGISTER_WAIT(R_USB_HS0->DCPCTR_b.PBUSY, 0);
698
699 R_USB_HS0->DCPMAXP = dev_addr << USB_DEVADDRBIT | 64; /* Default mps = 64 */
700
701 switch (g_uhc_data[p_ctrl->p_cfg->module_number].dev0.usbh_dev0_info.speed)
702 {
703 case USB_SPEED_FS:
704 {
705 *devadd = USB_DEVADD_USBSPD_FS;
706 break;
707 }
708
709 case USB_SPEED_LS:
710 {
711 *devadd = USB_DEVADD_USBSPD_LS;
712 break;
713 }
714
715 case USB_SPEED_HS:
716 {
717 *devadd = USB_DEVADD_USBSPD_HS;
718 break;
719 }
720
721 default:
722 {
723 *devadd = 0;
724 break;
725 }
726 }
727
728 g_uhc_data[p_ctrl->p_cfg->module_number].ctl_mps[dev_addr] = 64;
729
730 return FSP_SUCCESS;
731 }
732
733 /**
734 * @brief Start SOF generator
735 *
736 * @param p_api_ctrl [in]
737 *
738 * @retval FSP_SUCCESS on success
739 * @retval FSP_ERR_NOT_OPEN if USB host has not been opened
740 */
R_USBH_SOFEnable(usb_ctrl_t * const p_api_ctrl)741 fsp_err_t R_USBH_SOFEnable (usb_ctrl_t * const p_api_ctrl)
742 {
743 usbh_instance_ctrl_t * p_ctrl = (usbh_instance_ctrl_t *) p_api_ctrl;
744 R_USB_HS0_Type * p_reg = (R_USB_HS0_Type *) p_ctrl->p_reg;
745
746 #if USBH_CFG_PARAM_CHECKING_ENABLE
747 FSP_ASSERT(p_api_ctrl)
748 FSP_ERROR_RETURN(0 != p_ctrl->open, FSP_ERR_NOT_OPEN);
749 #endif
750
751 p_reg->DVSTCTR0 |= USB_UACT;
752
753 return FSP_SUCCESS;
754 }
755
756 /**
757 * @brief Stop SOF generator
758 *
759 * @param p_api_ctrl [in]
760 *
761 * @retval FSP_SUCCESS on success
762 * @retval FSP_ERR_NOT_OPEN if USB host has not been opened
763 */
R_USBH_SOFDisable(usb_ctrl_t * const p_api_ctrl)764 fsp_err_t R_USBH_SOFDisable (usb_ctrl_t * const p_api_ctrl)
765 {
766 usbh_instance_ctrl_t * p_ctrl = (usbh_instance_ctrl_t *) p_api_ctrl;
767 R_USB_HS0_Type * p_reg = (R_USB_HS0_Type *) p_ctrl->p_reg;
768
769 #if USBH_CFG_PARAM_CHECKING_ENABLE
770 FSP_ASSERT(p_api_ctrl)
771 FSP_ERROR_RETURN(0 != p_ctrl->open, FSP_ERR_NOT_OPEN);
772 #endif
773
774 p_reg->DVSTCTR0 = (uint16_t) (p_reg->DVSTCTR0 & (~USB_UACT));
775
776 return FSP_SUCCESS;
777 }
778
779 /**
780 * @brief Resume bus
781 *
782 * @param p_api_ctrl [in]
783 *
784 * @retval FSP_SUCCESS on success
785 * @retval FSP_ERR_NOT_OPEN if USB host has not been opened
786 */
R_USBH_BusResume(usb_ctrl_t * const p_api_ctrl)787 fsp_err_t R_USBH_BusResume (usb_ctrl_t * const p_api_ctrl)
788 {
789 usbh_instance_ctrl_t * p_ctrl = (usbh_instance_ctrl_t *) p_api_ctrl;
790 R_USB_HS0_Type * p_reg = (R_USB_HS0_Type *) p_ctrl->p_reg;
791
792 #if USBH_CFG_PARAM_CHECKING_ENABLE
793 FSP_ASSERT(p_api_ctrl)
794 FSP_ERROR_RETURN(0 != p_ctrl->open, FSP_ERR_NOT_OPEN);
795 #endif
796
797 p_reg->DVSTCTR0 |= (USB_RESUME);
798 R_BSP_SoftwareDelay(3, BSP_DELAY_UNITS_MILLISECONDS);
799 p_reg->DVSTCTR0 &= ~(USB_RESUME);
800 p_reg->DVSTCTR0 |= USB_UACT;
801 R_BSP_SoftwareDelay(20, BSP_DELAY_UNITS_MILLISECONDS);
802
803 return FSP_SUCCESS;
804 }
805
806 /**
807 * @brief Suspend bus
808 *
809 * @param p_api_ctrl [in]
810 *
811 * @retval FSP_SUCCESS on success
812 * @retval FSP_ERR_NOT_OPEN if USB host has not been opened
813 */
R_USBH_BusSuspend(usb_ctrl_t * const p_api_ctrl)814 fsp_err_t R_USBH_BusSuspend (usb_ctrl_t * const p_api_ctrl)
815 {
816 usbh_instance_ctrl_t * p_ctrl = (usbh_instance_ctrl_t *) p_api_ctrl;
817 R_USB_HS0_Type * p_reg = (R_USB_HS0_Type *) p_ctrl->p_reg;
818
819 #if USBH_CFG_PARAM_CHECKING_ENABLE
820 FSP_ASSERT(p_api_ctrl)
821 FSP_ERROR_RETURN(0 != p_ctrl->open, FSP_ERR_NOT_OPEN);
822 #endif
823
824 p_reg->DVSTCTR0 &= ~(USB_UACT | USB_RESUME);
825
826 return FSP_SUCCESS;
827 }
828
829 /**
830 * @brief Close usb host
831 *
832 * @param p_api_ctrl [in]
833 *
834 * @retval FSP_SUCCESS on success
835 * @retval FSP_ERR_NOT_OPEN if USB host has not been opened
836 */
R_USBH_Close(usb_ctrl_t * const p_api_ctrl)837 fsp_err_t R_USBH_Close (usb_ctrl_t * const p_api_ctrl)
838 {
839 usbh_instance_ctrl_t * p_ctrl = (usbh_instance_ctrl_t *) p_api_ctrl;
840
841 #if USBH_CFG_PARAM_CHECKING_ENABLE
842 FSP_ASSERT(p_api_ctrl)
843 FSP_ERROR_RETURN(0 != p_ctrl->open, FSP_ERR_NOT_OPEN);
844 #endif
845
846 r_usbh_hw_module_stop(p_ctrl);
847
848 return FSP_SUCCESS;
849 }
850
851 /**
852 * @brief Start a transfer
853 *
854 * @param p_api_ctrl [in]
855 * @param dev_addr [in]
856 * @param ep_addr [in]
857 * @param buffer [in]
858 * @param buflen [in]
859 *
860 * @retval FSP_SUCCESS on success
861 * @retval FSP_ERR_NOT_OPEN if USB host has not been opened
862 * @retval FSP_ERR_WRITE_FAILED if failed
863 */
R_USBH_XferStart(usb_ctrl_t * const p_api_ctrl,uint8_t dev_addr,uint8_t ep_addr,uint8_t * buffer,uint16_t buflen)864 fsp_err_t R_USBH_XferStart (usb_ctrl_t * const p_api_ctrl,
865 uint8_t dev_addr,
866 uint8_t ep_addr,
867 uint8_t * buffer,
868 uint16_t buflen)
869 {
870 usbh_instance_ctrl_t * p_ctrl = (usbh_instance_ctrl_t *) p_api_ctrl;
871 bool r;
872
873 #if USBH_CFG_PARAM_CHECKING_ENABLE
874 FSP_ASSERT(p_api_ctrl)
875 FSP_ASSERT(buffer)
876 FSP_ERROR_RETURN(0 != p_ctrl->open, FSP_ERR_NOT_OPEN);
877 #endif
878
879 R_BSP_IrqDisable(p_ctrl->p_cfg->irq);
880 r = r_usbh_process_edpt_xfer(p_ctrl, dev_addr, ep_addr, buffer, buflen);
881 R_BSP_IrqEnable(p_ctrl->p_cfg->irq);
882
883 if (r == true)
884 {
885 return FSP_SUCCESS;
886 }
887
888 return FSP_ERR_WRITE_FAILED;
889 }
890
891 /**
892 * @brief Connect to the USB data bus
893 *
894 * @param p_api_ctrl [in]
895 *
896 * @retval FSP_SUCCESS on success
897 * @retval FSP_ERR_NOT_OPEN if USB host has not been opened
898 */
R_USBH_Enable(usb_ctrl_t * const p_api_ctrl)899 fsp_err_t R_USBH_Enable (usb_ctrl_t * const p_api_ctrl)
900 {
901 usbh_instance_ctrl_t * p_ctrl = (usbh_instance_ctrl_t *) p_api_ctrl;
902 R_USB_HS0_Type * p_reg = (R_USB_HS0_Type *) p_ctrl->p_reg;
903
904 #if USBH_CFG_PARAM_CHECKING_ENABLE
905 FSP_ASSERT(p_api_ctrl)
906 FSP_ERROR_RETURN(0 != p_ctrl->open, FSP_ERR_NOT_OPEN);
907 #endif
908
909 p_reg->SYSCFG_b.DRPD = 1;
910 p_reg->SYSCFG_b.DPRPU = 0;
911 p_reg->SYSCFG_b.CNEN = 1;
912 p_reg->BUSWAIT = USBH_CFG_BUS_WAIT_CYCLES;
913 R_BSP_SoftwareDelay(1, BSP_DELAY_UNITS_MICROSECONDS);
914 p_reg->SYSCFG_b.USBE = 1;
915
916 return FSP_SUCCESS;
917 }
918
919 /**
920 * @brief Disconnect to the USB data bus
921 *
922 * @param p_api_ctrl [in]
923 *
924 * @retval FSP_SUCCESS on success
925 * @retval FSP_ERR_NOT_OPEN if USB host has not been opened
926 */
R_USBH_Disable(usb_ctrl_t * const p_api_ctrl)927 fsp_err_t R_USBH_Disable (usb_ctrl_t * const p_api_ctrl)
928 {
929 usbh_instance_ctrl_t * p_ctrl = (usbh_instance_ctrl_t *) p_api_ctrl;
930 R_USB_HS0_Type * p_reg = (R_USB_HS0_Type *) p_ctrl->p_reg;
931
932 #if USBH_CFG_PARAM_CHECKING_ENABLE
933 FSP_ASSERT(p_api_ctrl)
934 FSP_ERROR_RETURN(0 != p_ctrl->open, FSP_ERR_NOT_OPEN);
935 #endif
936
937 p_reg->SYSCFG_b.DRPD = 0;
938 p_reg->SYSCFG_b.DPRPU = 0;
939 p_reg->SYSCFG_b.CNEN = 0;
940 p_reg->SYSCFG_b.USBE = 0;
941
942 return FSP_SUCCESS;
943 }
944
945 /***********************************************************************************************************************
946 * Private Functions
947 **********************************************************************************************************************/
r_usbh_hw_module_start(usbh_instance_ctrl_t * const p_ctrl)948 static fsp_err_t r_usbh_hw_module_start (usbh_instance_ctrl_t * const p_ctrl)
949 {
950 if (p_ctrl->module_number == USB_HS_MODULE_NUMBER_START)
951 {
952 FSP_ERROR_RETURN(0 != R_MSTP->MSTPCRB_b.MSTPB12, FSP_ERR_USB_BUSY)
953
954 /* Enable power for USBA */
955 R_BSP_MODULE_START(FSP_IP_USBHS, 0);
956 }
957 else
958 {
959 FSP_ERROR_RETURN(0 != R_MSTP->MSTPCRB_b.MSTPB12, FSP_ERR_USB_BUSY)
960
961 /* Enable power for USBA */
962 R_BSP_MODULE_START(FSP_IP_USBFS, 0);
963 }
964
965 return FSP_SUCCESS;
966 }
967
r_usbh_module_register_clear(usbh_instance_ctrl_t * const p_ctrl)968 static fsp_err_t r_usbh_module_register_clear (usbh_instance_ctrl_t * const p_ctrl)
969 {
970 R_USB_HS0_Type * p_reg = (R_USB_HS0_Type *) p_ctrl->p_reg;
971
972 p_reg->DVSTCTR0 = 0;
973 p_reg->DCPCTR = USB_SQSET;
974 p_reg->PIPE_CTR[0] = 0;
975 p_reg->PIPE_CTR[1] = 0;
976 p_reg->PIPE_CTR[2] = 0;
977 p_reg->PIPE_CTR[3] = 0;
978 p_reg->PIPE_CTR[4] = 0;
979 p_reg->PIPE_CTR[5] = 0;
980 p_reg->PIPE_CTR[6] = 0;
981 p_reg->PIPE_CTR[7] = 0;
982 p_reg->PIPE_CTR[8] = 0;
983 p_reg->BRDYENB = 0;
984 p_reg->NRDYENB = 0;
985 p_reg->BEMPENB = 0;
986 p_reg->INTENB0 = 0;
987 p_reg->INTENB1 = 0;
988 p_reg->BRDYSTS = 0;
989 p_reg->NRDYSTS = 0;
990 p_reg->BEMPSTS = 0;
991 p_reg->SYSCFG = (uint16_t) (p_reg->SYSCFG & (~USB_DPRPU));
992 p_reg->SYSCFG = (uint16_t) (p_reg->SYSCFG & (~USB_DRPD));
993 p_reg->SYSCFG = (uint16_t) (p_reg->SYSCFG & (~USB_DCFM));
994 p_reg->CFIFOCTR = 0;
995
996 if (p_ctrl->module_number == USB_HS_MODULE_NUMBER_START)
997 {
998 for (uint32_t i = 0; i < USB_HS_DEVADD_NUM; i++)
999 {
1000 p_reg->DEVADD[i] = 0;
1001 }
1002
1003 p_reg->SYSCFG = (uint16_t) (p_reg->SYSCFG & (~USB_USBE));
1004 p_reg->LPSTS = 0;
1005 }
1006 else
1007 {
1008 for (uint32_t i = 0; i < USB_FS_DEVADD_NUM; i++)
1009 {
1010 p_reg->DEVADD[i] = 0;
1011 }
1012 }
1013
1014 return FSP_SUCCESS;
1015 }
1016
r_usbh_hw_module_stop(usbh_instance_ctrl_t * const p_ctrl)1017 static fsp_err_t r_usbh_hw_module_stop (usbh_instance_ctrl_t * const p_ctrl)
1018 {
1019 r_usbh_module_register_clear(p_ctrl);
1020
1021 if (p_ctrl->module_number == USB_HS_MODULE_NUMBER_START)
1022 {
1023 FSP_ERROR_RETURN(0 == R_MSTP->MSTPCRB_b.MSTPB12, FSP_ERR_USB_NOT_OPEN)
1024
1025 /* Enable power for USBA */
1026 R_BSP_MODULE_STOP(FSP_IP_USBHS, 0);
1027 }
1028 else
1029 {
1030 FSP_ERROR_RETURN(0 == R_MSTP->MSTPCRB_b.MSTPB11, FSP_ERR_USB_NOT_OPEN)
1031
1032 /* Disable power for USB0 */
1033 R_BSP_MODULE_STOP(FSP_IP_USBFS, 0);
1034 }
1035
1036 return FSP_SUCCESS;
1037 }
1038
r_usbh_hw_init(usbh_instance_ctrl_t * const p_ctrl)1039 static fsp_err_t r_usbh_hw_init (usbh_instance_ctrl_t * const p_ctrl)
1040 {
1041 R_USB_HS0_Type * p_reg = (R_USB_HS0_Type *) p_ctrl->p_reg;
1042
1043 if (p_ctrl->module_number == USB_HS_MODULE_NUMBER_START)
1044 {
1045 if (p_ctrl->max_speed == USB_SPEED_HS)
1046 {
1047 p_reg->SYSCFG_b.HSE = 1;
1048 }
1049
1050 p_reg->PHYSET = (USB_DIRPD | USB_PLLRESET | USB_CLKSEL);
1051 p_reg->PHYSET &= (uint16_t) ~USB_CLKSEL;
1052
1053 #if !USBHS_PHY_CLOCK_SOURCE_IS_XTAL
1054 p_reg->PHYSET |= USB_HSEB;
1055 #else
1056 p_reg->PHYSET_b.CLKSEL = USBH_CFG_PHYSET_CLKSEL;
1057 p_reg->PHYSET |= USB_REPSEL_16;
1058 #endif
1059
1060 R_BSP_SoftwareDelay(1, BSP_DELAY_UNITS_MICROSECONDS);
1061 p_reg->PHYSET = (uint16_t) (p_reg->PHYSET & (~USB_DIRPD));
1062 R_BSP_SoftwareDelay(1, BSP_DELAY_UNITS_MILLISECONDS);
1063 p_reg->PHYSET = (uint16_t) (p_reg->PHYSET & (~USB_PLLRESET));
1064
1065 p_reg->LPSTS_b.SUSPENDM = 1;
1066
1067 /* Wait for PLL Lock */
1068 FSP_HARDWARE_REGISTER_WAIT((p_reg->PLLSTA & USB_PLLLOCK), USB_PLLLOCK);
1069
1070 p_reg->SYSCFG_b.DCFM = 1;
1071 p_reg->SOFCFG_b.INTL = 1;
1072
1073 p_reg->DVSTCTR0_b.VBUSEN = 1;
1074 p_reg->CFIFOSEL_b.MBW = 1;
1075 p_reg->D0FIFOSEL_b.MBW = 1;
1076 p_reg->D1FIFOSEL_b.MBW = 1;
1077 R_BSP_SoftwareDelay(1, BSP_DELAY_UNITS_MICROSECONDS);
1078
1079 p_reg->SYSCFG_b.USBE = 1;
1080 }
1081 else
1082 {
1083 R_USB_FS0_Type * p_fs_reg = (R_USB_FS0_Type *) p_ctrl->p_reg;
1084 p_fs_reg->SYSCFG_b.SCKE = 1;
1085
1086 FSP_HARDWARE_REGISTER_WAIT(p_fs_reg->SYSCFG_b.SCKE, 1);
1087
1088 p_fs_reg->SYSCFG_b.DCFM = 1; /* Host function */
1089 p_fs_reg->SYSCFG_b.DPRPU = 0; /* Disable D+ pull up */
1090 p_fs_reg->SYSCFG_b.DRPD = 1; /* Enable D+/D- pull down */
1091
1092 p_fs_reg->DVSTCTR0_b.VBUSEN = 1;
1093 R_BSP_SoftwareDelay(10, BSP_DELAY_UNITS_MILLISECONDS);
1094 p_fs_reg->SYSCFG_b.USBE = 1;
1095
1096 p_fs_reg->PHYSLEW = 0x5;
1097 p_fs_reg->DPUSR0R_FS_b.FIXPHY0 = 0u; /* Transceiver Output fixed */
1098 }
1099
1100 /* Setup default control pipe */
1101 p_reg->DCPCFG = USB_PIPECFG_SHTNAK_Msk;
1102 p_reg->DCPMAXP = 64;
1103 p_reg->INTENB0 =
1104 USB_INTSTS0_BRDY_Msk | USB_INTSTS0_NRDY_Msk | USB_INTSTS0_BEMP_Msk;
1105 p_reg->INTENB1 = USB_INTSTS1_SACK_Msk | USB_INTSTS1_SIGN_Msk |
1106 USB_INTSTS1_ATTCH_Msk | USB_INTSTS1_DTCH_Msk;
1107 p_reg->BEMPENB = 1;
1108 p_reg->NRDYENB = 1;
1109 p_reg->BRDYENB = 1;
1110 p_reg->INTSTS0 = 0;
1111 p_reg->INTSTS1 = 0;
1112
1113 return true;
1114 }
1115
r_usb_chk_dev_addr(usbh_instance_ctrl_t * p_ctrl,uint16_t addr)1116 static uint16_t r_usb_chk_dev_addr (usbh_instance_ctrl_t * p_ctrl, uint16_t addr)
1117 {
1118 /* Get device address configuration register from device address */
1119 R_USB_HS0_Type * p_reg = (R_USB_HS0_Type *) p_ctrl->p_reg;
1120 volatile uint16_t * preg;
1121 uint16_t value;
1122
1123 preg = (uint16_t *) &(p_reg->DEVADD[0]) + addr;
1124 value = ((*preg) & ((USB_UPPHUB | USB_HUBPORT) | USB_USBSPD));
1125
1126 return (uint16_t) (value & USB_USBSPD);
1127 }
1128
r_usbh_set_dev_addr(usbh_instance_ctrl_t * p_ctrl,uint16_t addr,uint16_t speed)1129 void r_usbh_set_dev_addr (usbh_instance_ctrl_t * p_ctrl, uint16_t addr, uint16_t speed)
1130 {
1131 R_USB_HS0_Type * p_reg = (R_USB_HS0_Type *) p_ctrl->p_reg;
1132 volatile uint16_t * devadd = &p_reg->DEVADD[addr];
1133
1134 if (USB_DEVICE_0 == addr)
1135 {
1136 p_reg->DCPMAXP = (uint16_t) (USB_DEFPACKET + USB_DEVICE_0);
1137 }
1138
1139 *devadd &= (uint16_t) (~USB_USBSPD);
1140 *devadd |= (uint16_t) (speed);
1141 }
1142
r_usbh_device_release(usbh_instance_ctrl_t * p_ctrl,uint8_t dev_addr)1143 static void r_usbh_device_release (usbh_instance_ctrl_t * p_ctrl, uint8_t dev_addr)
1144 {
1145 R_USB_HS0_Type * p_reg = (R_USB_HS0_Type *) p_ctrl->p_reg;
1146 uint16_t volatile * ctr;
1147
1148 g_uhc_data[p_ctrl->p_cfg->module_number].ctl_mps[dev_addr] = 0;
1149 uint8_t * ep = &g_uhc_data[p_ctrl->p_cfg->module_number].ep[dev_addr - 1][0][0];
1150
1151 for (int i = 0; i < 2 * USB_PIPE_COUNT; ++i, ++ep)
1152 {
1153 uint32_t num = *ep;
1154 if (!num || (dev_addr != g_uhc_data[p_ctrl->p_cfg->module_number].pipe[num].dev))
1155 {
1156 continue;
1157 }
1158
1159 ctr = (uint16_t volatile *) &p_reg->PIPE_CTR[num - 1];
1160 *ctr = 0;
1161 p_reg->NRDYENB &= ~USB_SETBIT(num);
1162 p_reg->BRDYENB &= ~USB_SETBIT(num);
1163 p_reg->PIPESEL = num;
1164 p_reg->PIPECFG = 0;
1165 p_reg->PIPEMAXP = 0;
1166
1167 g_uhc_data[p_ctrl->p_cfg->module_number].pipe[num].ep = 0;
1168 g_uhc_data[p_ctrl->p_cfg->module_number].pipe[num].dev = 0;
1169 *ep = 0;
1170 }
1171
1172 r_usbh_set_dev_addr(p_ctrl, dev_addr, 0);
1173 }
1174
r_usbh_find_pipe(usbh_instance_ctrl_t * const p_ctrl,uint8_t xfer_type)1175 static uint32_t r_usbh_find_pipe (usbh_instance_ctrl_t * const p_ctrl, uint8_t xfer_type)
1176 {
1177 const uint8_t pipe_idx_arr[4][2] =
1178 {
1179 {0, 0}, /* Control */
1180 {1, 2}, /* Isochronous */
1181 {1, 5}, /* Bulk */
1182 {6, 9}, /* Interrupt */
1183 };
1184
1185 const uint8_t idx_first = pipe_idx_arr[xfer_type][0];
1186 const uint8_t idx_last = pipe_idx_arr[xfer_type][1];
1187
1188 for (int i = idx_last; i >= idx_first; i--)
1189 {
1190 if (0 == g_uhc_data[p_ctrl->p_cfg->module_number].pipe[i].ep)
1191 {
1192 return i;
1193 }
1194 }
1195
1196 return 0;
1197 }
1198
r_usbh_get_pipectr(usbh_instance_ctrl_t * const p_ctrl,uint32_t num)1199 static volatile uint16_t * r_usbh_get_pipectr (usbh_instance_ctrl_t * const p_ctrl, uint32_t num)
1200 {
1201 R_USB_HS0_Type * p_reg = (R_USB_HS0_Type *) p_ctrl->p_reg;
1202
1203 if (num != 0)
1204 {
1205 return (volatile uint16_t *) &(p_reg->PIPE_CTR[num - 1]);
1206 }
1207 else
1208 {
1209 return (volatile uint16_t *) &(p_reg->DCPCTR);
1210 }
1211 }
1212
1213 /* Helper to send USB transfer event */
r_usbh_event_xfer_complete_notify(usbh_instance_ctrl_t * const p_ctrl,uint8_t dev_addr,uint8_t ep_addr,uint32_t xferred_bytes,usb_xfer_result_t result)1214 static inline void r_usbh_event_xfer_complete_notify (usbh_instance_ctrl_t * const p_ctrl,
1215 uint8_t dev_addr,
1216 uint8_t ep_addr,
1217 uint32_t xferred_bytes,
1218 usb_xfer_result_t result)
1219 {
1220 usbh_event_t event =
1221 {
1222 .event_id = USBH_EVENT_XFER_COMPLETE,
1223 .dev_addr = dev_addr,
1224 };
1225 event.complete.ep_addr = ep_addr;
1226 event.complete.result = result;
1227 event.complete.len = xferred_bytes;
1228
1229 usbh_callback_arg_t args;
1230 usbh_callback_arg_t * p_args = p_ctrl->p_callback_memory;
1231
1232 if (NULL == p_ctrl->p_callback)
1233 {
1234 return;
1235 }
1236
1237 if (NULL == p_args)
1238 {
1239 /* Store on stack */
1240 p_args = &args;
1241 }
1242 else
1243 {
1244 /* Save current arguments on the stack in case this is a nested interrupt.
1245 */
1246 args = *p_args;
1247 }
1248
1249 p_args->module_number = p_ctrl->p_cfg->module_number;
1250 p_args->p_context = p_ctrl->p_context;
1251 memcpy(&p_args->event, &event, sizeof(usbh_event_t));
1252
1253 if (p_ctrl->p_callback != NULL)
1254 {
1255 p_ctrl->p_callback(p_args);
1256 }
1257 }
1258
r_usbh_event_device_attach_notify(usbh_instance_ctrl_t * const p_ctrl)1259 static inline void r_usbh_event_device_attach_notify (usbh_instance_ctrl_t * const p_ctrl)
1260 {
1261 usbh_event_t event;
1262 event.event_id = USBH_EVENT_DEVICE_ATTACH;
1263 event.attach.hub_addr = 0;
1264 event.attach.hub_port = 0;
1265
1266 usbh_callback_arg_t args;
1267 usbh_callback_arg_t * p_args = p_ctrl->p_callback_memory;
1268
1269 if (NULL == p_ctrl->p_callback)
1270 {
1271 return;
1272 }
1273
1274 if (NULL == p_args)
1275 {
1276 /* Store on stack */
1277 p_args = &args;
1278 }
1279 else
1280 {
1281 /* Save current arguments on the stack in case this is a nested interrupt.
1282 */
1283 args = *p_args;
1284 }
1285
1286 p_args->module_number = p_ctrl->p_cfg->module_number;
1287 p_args->p_context = p_ctrl->p_context;
1288 memcpy(&p_args->event, &event, sizeof(usbh_event_t));
1289
1290 if (p_ctrl->p_callback != NULL)
1291 {
1292 p_ctrl->p_callback(p_args);
1293 }
1294 }
1295
r_usbh_get_pipetre(usbh_instance_ctrl_t * const p_ctrl,uint32_t num)1296 static volatile usb_reg_pipetre_t * r_usbh_get_pipetre (usbh_instance_ctrl_t * const p_ctrl, uint32_t num)
1297 {
1298 R_USB_HS0_Type * p_reg = p_ctrl->p_reg;
1299 volatile usb_reg_pipetre_t * tre = NULL;
1300
1301 if ((1 <= num) && (num <= 5))
1302 {
1303 tre = (volatile usb_reg_pipetre_t *) &(p_reg->PIPE_TR[num - 1].E);
1304 }
1305
1306 return tre;
1307 }
1308
r_usbh_edpt0_max_packet_size(usbh_instance_ctrl_t * const p_ctrl)1309 static uint16_t r_usbh_edpt0_max_packet_size (usbh_instance_ctrl_t * const p_ctrl)
1310 {
1311 R_USB_HS0_Type * p_reg = (R_USB_HS0_Type *) p_ctrl->p_reg;
1312
1313 return p_reg->DCPMAXP_b.MXPS;
1314 }
1315
r_usbh_edpt_max_packet_size(usbh_instance_ctrl_t * const p_ctrl,uint32_t num)1316 static uint16_t r_usbh_edpt_max_packet_size (usbh_instance_ctrl_t * const p_ctrl, uint32_t num)
1317 {
1318 R_USB_HS0_Type * p_reg = (R_USB_HS0_Type *) p_ctrl->p_reg;
1319
1320 p_reg->PIPESEL = num;
1321
1322 return p_reg->PIPEMAXP_b.MXPS;
1323 }
1324
r_usbh_pipe_wait_for_ready(usbh_instance_ctrl_t * const p_ctrl,uint32_t num)1325 static inline void r_usbh_pipe_wait_for_ready (usbh_instance_ctrl_t * const p_ctrl, uint32_t num)
1326 {
1327 R_USB_HS0_Type * p_reg = (R_USB_HS0_Type *) p_ctrl->p_reg;
1328
1329 FSP_HARDWARE_REGISTER_WAIT(p_reg->D0FIFOSEL_b.CURPIPE, num);
1330
1331 FSP_HARDWARE_REGISTER_WAIT(p_reg->D0FIFOCTR_b.FRDY, 1);
1332 }
1333
r_usbh_pipe_write_packet(void * buf,volatile void * fifo,uint32_t len)1334 static void r_usbh_pipe_write_packet (void * buf, volatile void * fifo, uint32_t len)
1335 {
1336 volatile hw_fifo_t * reg = fifo;
1337 uint8_t * addr = buf;
1338
1339 while (len >= 2)
1340 {
1341 reg->u16 = *(const uint16_t *) addr;
1342 addr += 2;
1343 len -= 2;
1344 }
1345
1346 if (len)
1347 {
1348 reg->u8 = *(const uint8_t *) addr;
1349 ++addr;
1350 }
1351 }
1352
r_usbh_pipe_read_packet(void * buf,volatile void * fifo,uint32_t len)1353 static void r_usbh_pipe_read_packet (void * buf, volatile void * fifo, uint32_t len)
1354 {
1355 uint8_t * p = (uint8_t *) buf;
1356
1357 /* byte access is always at base register address */
1358 volatile uint8_t * reg = (volatile uint8_t *) fifo;
1359 while (len--)
1360 {
1361 *p++ = *reg;
1362 }
1363 }
1364
r_usbh_pipe0_xfer_in(usbh_instance_ctrl_t * const p_ctrl)1365 static bool r_usbh_pipe0_xfer_in (usbh_instance_ctrl_t * const p_ctrl)
1366 {
1367 R_USB_HS0_Type * p_reg = (R_USB_HS0_Type *) p_ctrl->p_reg;
1368 pipe_state_t * pipe = &g_uhc_data[p_ctrl->p_cfg->module_number].pipe[0];
1369 const uint32_t rem = pipe->remaining;
1370
1371 const uint32_t mps = r_usbh_edpt0_max_packet_size(p_ctrl);
1372 const uint32_t vld = p_reg->CFIFOCTR_b.DTLN;
1373 const uint32_t len = USB_MIN(USB_MIN(rem, mps), vld);
1374 void * buf = pipe->buf;
1375 if (len)
1376 {
1377 p_reg->DCPCTR = USB_PIPE_CTR_PID_NAK;
1378 r_usbh_pipe_read_packet(buf, (volatile void *) &p_reg->CFIFO, len);
1379 pipe->buf = (uint8_t *) buf + len;
1380 }
1381
1382 if (len < mps)
1383 {
1384 p_reg->CFIFOCTR = USB_CFIFOCTR_BCLR_Msk;
1385 }
1386
1387 pipe->remaining = rem - len;
1388 if ((len < mps) || (rem == len))
1389 {
1390 pipe->buf = NULL;
1391
1392 return true;
1393 }
1394
1395 p_reg->DCPCTR = USB_PIPE_CTR_PID_BUF;
1396
1397 return false;
1398 }
1399
r_usbh_pipe0_xfer_out(usbh_instance_ctrl_t * const p_ctrl)1400 static bool r_usbh_pipe0_xfer_out (usbh_instance_ctrl_t * const p_ctrl)
1401 {
1402 R_USB_HS0_Type * p_reg = (R_USB_HS0_Type *) p_ctrl->p_reg;
1403 pipe_state_t * pipe = &g_uhc_data[p_ctrl->p_cfg->module_number].pipe[0];
1404 const uint32_t rem = pipe->remaining;
1405 if (!rem)
1406 {
1407 pipe->buf = NULL;
1408
1409 return true;
1410 }
1411
1412 const uint32_t mps = r_usbh_edpt0_max_packet_size(p_ctrl);
1413 const uint32_t len = USB_MIN(mps, rem);
1414 void * buf = pipe->buf;
1415 if (len)
1416 {
1417 r_usbh_pipe_write_packet(buf, (volatile void *) &p_reg->CFIFO, len);
1418 pipe->buf = (uint8_t *) buf + len;
1419 }
1420
1421 if (len < mps)
1422 {
1423 p_reg->CFIFOCTR = USB_CFIFOCTR_BVAL_Msk;
1424 }
1425
1426 pipe->remaining = rem - len;
1427
1428 return false;
1429 }
1430
r_usbh_pipe_xfer_in(usbh_instance_ctrl_t * const p_ctrl,uint32_t num)1431 static bool r_usbh_pipe_xfer_in (usbh_instance_ctrl_t * const p_ctrl, uint32_t num)
1432 {
1433 R_USB_HS0_Type * p_reg = (R_USB_HS0_Type *) p_ctrl->p_reg;
1434 pipe_state_t * pipe = &g_uhc_data[p_ctrl->p_cfg->module_number].pipe[num];
1435 const uint32_t rem = pipe->remaining;
1436
1437 p_reg->D0FIFOSEL = num | USB_FIFOSEL_MBW_8BIT;
1438 const uint32_t mps = r_usbh_edpt_max_packet_size(p_ctrl, num);
1439 r_usbh_pipe_wait_for_ready(p_ctrl, num);
1440 const uint32_t vld = p_reg->D0FIFOCTR_b.DTLN;
1441 const uint32_t len = USB_MIN(USB_MIN(rem, mps), vld);
1442 void * buf = pipe->buf;
1443
1444 if (len)
1445 {
1446 r_usbh_pipe_read_packet(buf, (volatile void *) &p_reg->D0FIFO, len);
1447 pipe->buf = (uint8_t *) buf + len;
1448 }
1449
1450 if (len < mps)
1451 {
1452 p_reg->D0FIFOCTR = USB_D0FIFOCTR_BCLR_Msk;
1453 }
1454
1455 p_reg->D0FIFOSEL = 0;
1456 FSP_HARDWARE_REGISTER_WAIT(p_reg->D0FIFOSEL_b.CURPIPE, 0); /* if CURPIPE bits changes, check written value */
1457
1458 pipe->remaining = rem - len;
1459 if ((len < mps) || (rem == len))
1460 {
1461 pipe->buf = NULL;
1462
1463 return NULL != buf;
1464 }
1465
1466 return false;
1467 }
1468
r_usbh_pipe_xfer_out(usbh_instance_ctrl_t * const p_ctrl,uint32_t num)1469 static bool r_usbh_pipe_xfer_out (usbh_instance_ctrl_t * const p_ctrl, uint32_t num)
1470 {
1471 R_USB_HS0_Type * p_reg = (R_USB_HS0_Type *) p_ctrl->p_reg;
1472 pipe_state_t * pipe = &g_uhc_data[p_ctrl->p_cfg->module_number].pipe[num];
1473 const uint32_t rem = pipe->remaining;
1474
1475 if (!rem)
1476 {
1477 pipe->buf = NULL;
1478
1479 return true;
1480 }
1481
1482 p_reg->D0FIFOSEL =
1483 num | USB_FIFOSEL_MBW_16BIT;
1484 const uint32_t mps = r_usbh_edpt_max_packet_size(p_ctrl, num);
1485 r_usbh_pipe_wait_for_ready(p_ctrl, num);
1486 const uint32_t len = USB_MIN(rem, mps);
1487 void * buf = pipe->buf;
1488 if (len)
1489 {
1490 r_usbh_pipe_write_packet(buf, (volatile void *) &p_reg->D0FIFO, len);
1491 pipe->buf = (uint8_t *) buf + len;
1492 }
1493
1494 if (len < mps)
1495 {
1496 p_reg->D0FIFOCTR = USB_D0FIFOCTR_BVAL_Msk;
1497 }
1498
1499 p_reg->D0FIFOSEL = 0;
1500 FSP_HARDWARE_REGISTER_WAIT(p_reg->D0FIFOSEL_b.CURPIPE, 0); /* if CURPIPE bits changes, check written value */
1501 pipe->remaining = rem - len;
1502
1503 return false;
1504 }
1505
r_usbh_process_pipe0_xfer(usbh_instance_ctrl_t * const p_ctrl,uint8_t dev_addr,uint8_t ep_addr,void * buffer,uint16_t buflen)1506 static bool r_usbh_process_pipe0_xfer (usbh_instance_ctrl_t * const p_ctrl,
1507 uint8_t dev_addr,
1508 uint8_t ep_addr,
1509 void * buffer,
1510 uint16_t buflen)
1511 {
1512 FSP_PARAMETER_NOT_USED(dev_addr);
1513
1514 R_USB_HS0_Type * p_reg = (R_USB_HS0_Type *) p_ctrl->p_reg;
1515 const uint32_t dir_in = r_usbh_edpt_dir(ep_addr);
1516
1517 /* configure fifo direction and access unit settings */
1518 if (dir_in)
1519 {
1520 /* IN, a byte */
1521 p_reg->CFIFOSEL = USB_FIFOSEL_MBW_8BIT;
1522 FSP_HARDWARE_REGISTER_WAIT((p_reg->CFIFOSEL & USB_CFIFOSEL_ISEL_WRITE), 0)
1523 }
1524 else
1525 {
1526 /* OUT, 2 bytes */
1527 p_reg->CFIFOSEL =
1528 USB_CFIFOSEL_ISEL_WRITE |
1529 USB_FIFOSEL_MBW_16BIT;
1530 FSP_HARDWARE_REGISTER_WAIT((p_reg->CFIFOSEL & USB_CFIFOSEL_ISEL_WRITE), USB_CFIFOSEL_ISEL_WRITE);
1531 }
1532
1533 pipe_state_t * pipe = &g_uhc_data[p_ctrl->p_cfg->module_number].pipe[0];
1534 pipe->ep = ep_addr;
1535 pipe->length = buflen;
1536 pipe->remaining = buflen;
1537 if (buflen)
1538 {
1539 pipe->buf = buffer;
1540 if (!dir_in)
1541 {
1542 /* OUT */
1543 FSP_ASSERT(p_reg->DCPCTR_b.BSTS && (p_reg->USBREQ & 0x80));
1544 r_usbh_pipe0_xfer_out(p_ctrl);
1545 }
1546 }
1547 else
1548 {
1549 /* ZLP */
1550 pipe->buf = NULL;
1551 if (!dir_in)
1552 {
1553 /* OUT */
1554 p_reg->CFIFOCTR = USB_CFIFOCTR_BVAL_Msk;
1555 }
1556
1557 if (dir_in == p_reg->DCPCFG_b.DIR)
1558 {
1559 FSP_ASSERT(USB_PIPE_CTR_PID_NAK == p_reg->DCPCTR_b.PID);
1560 p_reg->DCPCTR_b.SQSET = 1;
1561 p_reg->DCPCFG_b.DIR = dir_in ^ 1;
1562 }
1563 }
1564
1565 p_reg->DCPCTR = USB_PIPE_CTR_PID_BUF;
1566
1567 return true;
1568 }
1569
r_usbh_process_pipe_xfer(usbh_instance_ctrl_t * const p_ctrl,uint8_t dev_addr,uint8_t ep_addr,void * buffer,uint16_t buflen)1570 static bool r_usbh_process_pipe_xfer (usbh_instance_ctrl_t * const p_ctrl,
1571 uint8_t dev_addr,
1572 uint8_t ep_addr,
1573 void * buffer,
1574 uint16_t buflen)
1575 {
1576 R_USB_HS0_Type * p_reg = (R_USB_HS0_Type *) p_ctrl->p_reg;
1577
1578 const uint32_t epn = r_usbh_edpt_number(ep_addr);
1579 const uint32_t dir_in = r_usbh_edpt_dir(ep_addr);
1580 const uint32_t num = g_uhc_data[p_ctrl->p_cfg->module_number].ep[dev_addr - 1][dir_in][epn - 1];
1581
1582 FSP_ASSERT(num);
1583
1584 pipe_state_t * pipe = &g_uhc_data[p_ctrl->p_cfg->module_number].pipe[num];
1585 pipe->buf = buffer;
1586 pipe->length = buflen;
1587 pipe->remaining = buflen;
1588 if (!dir_in)
1589 {
1590 /* OUT */
1591 if (buflen)
1592 {
1593 r_usbh_pipe_xfer_out(p_ctrl, num);
1594 }
1595 else
1596 {
1597 /* ZLP */
1598 p_reg->D0FIFOSEL = num;
1599 r_usbh_pipe_wait_for_ready(p_ctrl, num);
1600 p_reg->D0FIFOCTR = USB_D0FIFOCTR_BVAL_Msk;
1601 p_reg->D0FIFOSEL = 0;
1602 FSP_HARDWARE_REGISTER_WAIT(p_reg->D0FIFOSEL_b.CURPIPE, 0); /* if CURPIPE bits changes, check written value */
1603 }
1604 }
1605 else
1606 {
1607 volatile uint16_t * ctr = r_usbh_get_pipectr(p_ctrl, num);
1608 volatile usb_reg_pipetre_t * pt = r_usbh_get_pipetre(p_ctrl, num);
1609 if (pt)
1610 {
1611 const uint32_t mps = r_usbh_edpt_max_packet_size(p_ctrl, num);
1612 if (*ctr & 0x3)
1613 {
1614 *ctr = USB_PIPE_CTR_PID_NAK;
1615 }
1616
1617 pt->TRE = USB_SETBIT(8);
1618 pt->TRN = (buflen + mps - 1) / mps;
1619 pt->TRENB = 1;
1620 }
1621
1622 *ctr = USB_PIPE_CTR_PID_BUF;
1623 }
1624
1625 return true;
1626 }
1627
r_usbh_process_edpt_xfer(usbh_instance_ctrl_t * const p_ctrl,uint8_t dev_addr,uint8_t ep_addr,void * buffer,uint16_t buflen)1628 static bool r_usbh_process_edpt_xfer (usbh_instance_ctrl_t * const p_ctrl,
1629 uint8_t dev_addr,
1630 uint8_t ep_addr,
1631 void * buffer,
1632 uint16_t buflen)
1633 {
1634 const uint32_t epn = r_usbh_edpt_number(ep_addr);
1635 if (0 == epn)
1636 {
1637 return r_usbh_process_pipe0_xfer(p_ctrl, dev_addr, ep_addr, buffer, buflen);
1638 }
1639 else
1640 {
1641 return r_usbh_process_pipe_xfer(p_ctrl, dev_addr, ep_addr, buffer, buflen);
1642 }
1643 }
1644
r_usbh_event_device_remove_notify(usbh_instance_ctrl_t * const p_ctrl)1645 static inline void r_usbh_event_device_remove_notify (usbh_instance_ctrl_t * const p_ctrl)
1646 {
1647 usbh_event_t event;
1648 event.event_id = USBH_EVENT_DEVICE_REMOVE;
1649 event.remove.hub_addr = 0;
1650 event.remove.hub_port = 0;
1651
1652 usbh_callback_arg_t args;
1653 usbh_callback_arg_t * p_args = p_ctrl->p_callback_memory;
1654
1655 if (NULL == p_ctrl->p_callback)
1656 {
1657 return;
1658 }
1659
1660 if (NULL == p_args)
1661 {
1662 /* Store on stack */
1663 p_args = &args;
1664 }
1665 else
1666 {
1667 /* Save current arguments on the stack in case this is a nested interrupt. */
1668 args = *p_args;
1669 }
1670
1671 p_args->module_number = p_ctrl->p_cfg->module_number;
1672 p_args->p_context = p_ctrl->p_context;
1673 memcpy(&p_args->event, &event, sizeof(usbh_event_t));
1674
1675 if (p_ctrl->p_callback != NULL)
1676 {
1677 p_ctrl->p_callback(p_args);
1678 }
1679 }
1680
r_usbh_process_pipe0_bemp(usbh_instance_ctrl_t * const p_ctrl)1681 static void r_usbh_process_pipe0_bemp (usbh_instance_ctrl_t * const p_ctrl)
1682 {
1683 bool completed = r_usbh_pipe0_xfer_out(p_ctrl);
1684 if (completed)
1685 {
1686 pipe_state_t * pipe = &g_uhc_data[p_ctrl->p_cfg->module_number].pipe[0];
1687 r_usbh_event_xfer_complete_notify(
1688 p_ctrl,
1689 pipe->dev,
1690 r_usbh_edpt_addr(0, USB_DIR_OUT),
1691 pipe->length - pipe->remaining,
1692 USB_XFER_RESULT_SUCCESS);
1693 }
1694 }
1695
r_usbh_process_pipe_nrdy(usbh_instance_ctrl_t * const p_ctrl,uint32_t num)1696 static void r_usbh_process_pipe_nrdy (usbh_instance_ctrl_t * const p_ctrl, uint32_t num)
1697 {
1698 usb_xfer_result_t result;
1699 uint16_t volatile * ctr = r_usbh_get_pipectr(p_ctrl, num);
1700
1701 switch (*ctr & USB_PIPE_CTR_PID_Msk)
1702 {
1703 default:
1704 {
1705 return;
1706 }
1707
1708 case USB_PIPE_CTR_PID_STALL:
1709 {
1710 result = USB_XFER_RESULT_STALLED;
1711 break;
1712 }
1713
1714 case USB_PIPE_CTR_PID_STALL2:
1715 {
1716 result = USB_XFER_RESULT_STALLED;
1717 break;
1718 }
1719
1720 case USB_PIPE_CTR_PID_NAK:
1721 {
1722 result = USB_XFER_RESULT_FAILED;
1723 break;
1724 }
1725 }
1726
1727 pipe_state_t * pipe = &g_uhc_data[p_ctrl->p_cfg->module_number].pipe[num];
1728 r_usbh_event_xfer_complete_notify(p_ctrl,
1729 pipe->dev,
1730 pipe->ep,
1731 pipe->length - pipe->remaining,
1732 result);
1733 }
1734
r_usbh_process_pipe_brdy(usbh_instance_ctrl_t * const p_ctrl,uint32_t num)1735 static void r_usbh_process_pipe_brdy (usbh_instance_ctrl_t * const p_ctrl, uint32_t num)
1736 {
1737 pipe_state_t * pipe = &g_uhc_data[p_ctrl->p_cfg->module_number].pipe[num];
1738 const uint32_t dir_in = r_usbh_edpt_dir(pipe->ep);
1739 bool completed;
1740
1741 if (dir_in)
1742 {
1743 /* IN */
1744 if (num)
1745 {
1746 completed = r_usbh_pipe_xfer_in(p_ctrl, num);
1747 }
1748 else
1749 {
1750 completed = r_usbh_pipe0_xfer_in(p_ctrl);
1751 }
1752 }
1753 else
1754 {
1755 completed = r_usbh_pipe_xfer_out(p_ctrl, num);
1756 }
1757
1758 if (completed)
1759 {
1760 r_usbh_event_xfer_complete_notify(p_ctrl,
1761 pipe->dev,
1762 pipe->ep,
1763 pipe->length - pipe->remaining,
1764 USB_XFER_RESULT_SUCCESS);
1765 }
1766 }
1767
1768 /***********************************************************************************************************************
1769 * Interrupt handler *
1770 **********************************************************************************************************************/
r_usbh_isr(void)1771 void r_usbh_isr (void)
1772 {
1773 /* Save context if RTOS is used */
1774 FSP_CONTEXT_SAVE
1775
1776 IRQn_Type irq = R_FSP_CurrentIrqGet();
1777
1778 usbh_instance_ctrl_t * p_ctrl = R_FSP_IsrContextGet(irq);
1779
1780 R_USB_HS0_Type * p_reg = (R_USB_HS0_Type *) p_ctrl->p_reg;
1781
1782 uint32_t is0 = p_reg->INTSTS0;
1783 uint32_t is1 = p_reg->INTSTS1;
1784
1785 /* clear active bits except VALID (don't write 0 to already cleared bits
1786 * according to the HW manual) */
1787 p_reg->INTSTS1 = ~((USB_INTSTS1_SACK_Msk | USB_INTSTS1_SIGN_Msk |
1788 USB_INTSTS1_ATTCH_Msk | USB_INTSTS1_DTCH_Msk) &
1789 is1);
1790 p_reg->INTSTS0 =
1791 ~((USB_INTSTS0_BRDY_Msk | USB_INTSTS0_NRDY_Msk | USB_INTSTS0_BEMP_Msk) &
1792 is0);
1793
1794 is1 &= p_reg->INTENB1;
1795 is0 &= p_reg->INTENB0;
1796
1797 if (is1 & USB_INTSTS1_SACK_Msk)
1798 {
1799 /* Set DATA1 in advance for the next transfer. */
1800 p_reg->DCPCTR_b.SQSET = 1;
1801 r_usbh_event_xfer_complete_notify(p_ctrl,
1802 p_reg->DCPMAXP_b.DEVSEL,
1803 r_usbh_edpt_addr(0, USB_DIR_OUT),
1804 8,
1805 USB_XFER_RESULT_SUCCESS);
1806 }
1807
1808 if (is1 & USB_INTSTS1_SIGN_Msk)
1809 {
1810 r_usbh_event_xfer_complete_notify(p_ctrl,
1811 p_reg->DCPMAXP_b.DEVSEL,
1812 r_usbh_edpt_addr(0, USB_DIR_OUT),
1813 8,
1814 USB_XFER_RESULT_FAILED);
1815 }
1816
1817 if (is1 & USB_INTSTS1_ATTCH_Msk)
1818 {
1819 p_reg->DVSTCTR0_b.UACT = 1;
1820 p_reg->INTENB1 =
1821 (p_reg->INTENB1 & ~USB_INTSTS1_ATTCH_Msk) | USB_INTSTS1_DTCH_Msk;
1822
1823 r_usbh_event_device_attach_notify(p_ctrl);
1824 }
1825 else if (is1 & USB_INTSTS1_DTCH_Msk)
1826 {
1827 p_reg->DVSTCTR0_b.UACT = 0;
1828 if (p_reg->DCPCTR_b.SUREQ)
1829 {
1830 p_reg->DCPCTR_b.SUREQCLR = 1;
1831 }
1832
1833 p_reg->INTENB1 =
1834 (p_reg->INTENB1 & ~USB_INTSTS1_DTCH_Msk) | USB_INTSTS1_ATTCH_Msk;
1835
1836 r_usbh_event_device_remove_notify(p_ctrl);
1837 }
1838
1839 if (is0 & USB_INTSTS0_BEMP_Msk)
1840 {
1841 const uint32_t s = p_reg->BEMPSTS;
1842 p_reg->BEMPSTS = 0;
1843 if (s & 1)
1844 {
1845 r_usbh_process_pipe0_bemp(p_ctrl);
1846 }
1847 }
1848
1849 if (is0 & USB_INTSTS0_NRDY_Msk)
1850 {
1851 const uint32_t m = p_reg->NRDYENB;
1852 uint32_t s = p_reg->NRDYSTS & m;
1853 p_reg->NRDYSTS = ~s;
1854 while (s)
1855 {
1856 const uint32_t num = CTZ(s);
1857 r_usbh_process_pipe_nrdy(p_ctrl, num);
1858 s &= ~USB_SETBIT(num);
1859 }
1860 }
1861
1862 if (is0 & USB_INTSTS0_BRDY_Msk)
1863 {
1864 const uint32_t m = p_reg->BRDYENB;
1865 uint32_t s = p_reg->BRDYSTS & m;
1866
1867 /* clear active bits (don't write 0 to already cleared bits according to the
1868 * HW manual) */
1869 p_reg->BRDYSTS = ~s;
1870 while (s)
1871 {
1872 const uint32_t num = CTZ(s);
1873 r_usbh_process_pipe_brdy(p_ctrl, num);
1874 s &= ~USB_SETBIT(num);
1875 }
1876 }
1877
1878 /* Clear pending IRQ to make sure it doesn't fire again after exiting */
1879 R_BSP_IrqStatusClear(irq);
1880
1881 /* Restore context if RTOS is used */
1882 FSP_CONTEXT_RESTORE
1883 }
1884