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