diff --git a/hw/bsp/ra/boards/ra2a1_ek/board.h b/hw/bsp/ra/boards/ra2a1_ek/board.h index c132387bc3..1c2b666d2d 100644 --- a/hw/bsp/ra/boards/ra2a1_ek/board.h +++ b/hw/bsp/ra/boards/ra2a1_ek/board.h @@ -31,10 +31,10 @@ extern "C" { #endif -#define LED1 BSP_IO_PORT_01_PIN_06 +#define LED1 BSP_IO_PORT_02_PIN_05 #define LED_STATE_ON 1 -#define SW1 BSP_IO_PORT_01_PIN_05 +#define SW1 BSP_IO_PORT_02_PIN_06 #define BUTTON_STATE_ACTIVE 0 static const ioport_pin_cfg_t board_pin_cfg[] = { diff --git a/hw/bsp/ra/family.c b/hw/bsp/ra/family.c index 16332be17f..db8988a361 100644 --- a/hw/bsp/ra/family.c +++ b/hw/bsp/ra/family.c @@ -64,8 +64,11 @@ BSP_DONT_REMOVE BSP_PLACE_IN_SECTION(BSP_SECTION_APPLICATION_VECTORS) const fsp_vector_t g_vector_table[BSP_ICU_VECTOR_MAX_ENTRIES] = { [0] = usbfs_interrupt_handler, /* USBFS INT (USBFS interrupt) */ [1] = usbfs_resume_handler, /* USBFS RESUME (USBFS resume interrupt) */ + +#ifndef BSP_MCU_GROUP_RA2A1 [2] = usbfs_d0fifo_handler, /* USBFS FIFO 0 (DMA transfer request 0) */ [3] = usbfs_d1fifo_handler, /* USBFS FIFO 1 (DMA transfer request 1) */ +#endif #ifdef BOARD_HAS_USB_HIGHSPEED [4] = usbhs_interrupt_handler, /* USBHS INT (USBHS interrupt) */ diff --git a/hw/bsp/ra/vector_data.h b/hw/bsp/ra/vector_data.h index ca667faa3f..2b3b7d8378 100644 --- a/hw/bsp/ra/vector_data.h +++ b/hw/bsp/ra/vector_data.h @@ -9,8 +9,11 @@ extern "C" { /* ISR prototypes */ void usbfs_interrupt_handler(void); void usbfs_resume_handler(void); + +#ifndef BSP_MCU_GROUP_RA2A1 void usbfs_d0fifo_handler(void); void usbfs_d1fifo_handler(void); +#endif #ifdef BOARD_HAS_USB_HIGHSPEED void usbhs_interrupt_handler(void); diff --git a/src/portable/renesas/rusb2/dcd_rusb2.c b/src/portable/renesas/rusb2/dcd_rusb2.c index 3ec1b70b5b..50400d1f5f 100644 --- a/src/portable/renesas/rusb2/dcd_rusb2.c +++ b/src/portable/renesas/rusb2/dcd_rusb2.c @@ -57,29 +57,22 @@ //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM //--------------------------------------------------------------------+ +enum { + PIPE_COUNT = 10, +}; -/* Start of definition of packed structs (used by the CCRX toolchain) */ -TU_ATTR_PACKED_BEGIN -TU_ATTR_BIT_FIELD_ORDER_BEGIN - -typedef struct TU_ATTR_PACKED -{ +typedef struct { void *buf; /* the start address of a transfer data buffer */ uint16_t length; /* the number of bytes in the buffer */ uint16_t remaining; /* the number of bytes remaining in the buffer */ - struct { - uint32_t ep : 8; /* an assigned endpoint address */ - uint32_t ff : 1; /* `buf` is TU_FUFO or POD */ - uint32_t : 0; - }; -} pipe_state_t; -TU_ATTR_PACKED_END // End of definition of packed structs (used by the CCRX toolchain) -TU_ATTR_BIT_FIELD_ORDER_END + uint8_t ep; /* an assigned endpoint address */ + uint8_t ff; /* `buf` is TU_FUFO or POD */ +} pipe_state_t; typedef struct { - pipe_state_t pipe[10]; + pipe_state_t pipe[PIPE_COUNT]; uint8_t ep[2][16]; /* a lookup table for a pipe index from an endpoint address */ } dcd_data_t; @@ -89,52 +82,44 @@ static dcd_data_t _dcd; // INTERNAL OBJECT & FUNCTION DECLARATION //--------------------------------------------------------------------+ -// Transfer conditions specifiable for each pipe: -// - Pipe 0: Control transfer with 64-byte single buffer -// - Pipes 1 and 2: Bulk isochronous transfer continuous transfer mode with programmable buffer size up -// to 2 KB and optional double buffer -// - Pipes 3 to 5: Bulk transfer continuous transfer mode with programmable buffer size up to 2 KB and -// optional double buffer -// - Pipes 6 to 9: Interrupt transfer with 64-byte single buffer -enum { - PIPE_1ST_BULK = 3, - PIPE_1ST_INTERRUPT = 6, - PIPE_COUNT = 10, -}; - -static unsigned find_pipe(unsigned xfer) -{ - switch (xfer) { - case TUSB_XFER_ISOCHRONOUS: - for (int i = 1; i < PIPE_1ST_BULK; ++i) { - if (0 == _dcd.pipe[i].ep) return i; - } - break; - case TUSB_XFER_BULK: - for (int i = PIPE_1ST_BULK; i < PIPE_1ST_INTERRUPT; ++i) { - if (0 == _dcd.pipe[i].ep) return i; - } - for (int i = 1; i < PIPE_1ST_BULK; ++i) { - if (0 == _dcd.pipe[i].ep) return i; - } - break; +// Transfer conditions specifiable for each pipe for most MCUs +// - Pipe 0: Control transfer with 64-byte single buffer +// - Pipes 1 and 2: Bulk or ISO +// - Pipes 3 to 5: Bulk +// - Pipes 6 to 9: Interrupt +// +// Note: for small mcu such as +// - RA2A1: only pipe 4-7 are available, and no support for ISO +static unsigned find_pipe(unsigned xfer_type) { + #if defined(BSP_MCU_GROUP_RA2A1) + const uint8_t pipe_idx_arr[4][2] = { + { 0, 0 }, // Control + { 0, 0 }, // Isochronous not supported + { 4, 5 }, // Bulk + { 6, 7 }, // Interrupt + }; + #else + const uint8_t pipe_idx_arr[4][2] = { + { 0, 0 }, // Control + { 1, 2 }, // Isochronous + { 1, 5 }, // Bulk + { 6, 9 }, // Interrupt + }; + #endif - case TUSB_XFER_INTERRUPT: - for (int i = PIPE_1ST_INTERRUPT; i < PIPE_COUNT; ++i) { - if (0 == _dcd.pipe[i].ep) return i; - } - break; + // find backward since only pipe 1, 2 support ISO + const uint8_t idx_first = pipe_idx_arr[xfer_type][0]; + const uint8_t idx_last = pipe_idx_arr[xfer_type][1]; - default: - /* No support for control transfer */ - break; + for (int i = idx_last; i >= idx_first; i--) { + if (0 == _dcd.pipe[i].ep) return i; } + return 0; } -static volatile uint16_t* get_pipectr(rusb2_reg_t *rusb, unsigned num) -{ +static volatile uint16_t* get_pipectr(rusb2_reg_t *rusb, unsigned num) { if (num) { return (volatile uint16_t*)&(rusb->PIPE_CTR[num - 1]); } else { @@ -142,8 +127,7 @@ static volatile uint16_t* get_pipectr(rusb2_reg_t *rusb, unsigned num) } } -static volatile reg_pipetre_t* get_pipetre(rusb2_reg_t *rusb, unsigned num) -{ +static volatile reg_pipetre_t* get_pipetre(rusb2_reg_t *rusb, unsigned num) { volatile reg_pipetre_t* tre = NULL; if ((1 <= num) && (num <= 5)) { tre = (volatile reg_pipetre_t*)&(rusb->PIPE_TR[num - 1].E); @@ -151,8 +135,7 @@ static volatile reg_pipetre_t* get_pipetre(rusb2_reg_t *rusb, unsigned num) return tre; } -static volatile uint16_t* ep_addr_to_pipectr(uint8_t rhport, unsigned ep_addr) -{ +static volatile uint16_t* ep_addr_to_pipectr(uint8_t rhport, unsigned ep_addr) { rusb2_reg_t *rusb = RUSB2_REG(rhport); const unsigned epn = tu_edpt_number(ep_addr); @@ -165,19 +148,16 @@ static volatile uint16_t* ep_addr_to_pipectr(uint8_t rhport, unsigned ep_addr) } } -static uint16_t edpt0_max_packet_size(rusb2_reg_t* rusb) -{ +static uint16_t edpt0_max_packet_size(rusb2_reg_t* rusb) { return rusb->DCPMAXP_b.MXPS; } -static uint16_t edpt_max_packet_size(rusb2_reg_t *rusb, unsigned num) -{ +static uint16_t edpt_max_packet_size(rusb2_reg_t *rusb, unsigned num) { rusb->PIPESEL = num; return rusb->PIPEMAXP; } -static inline void pipe_wait_for_ready(rusb2_reg_t * rusb, unsigned num) -{ +static inline void pipe_wait_for_ready(rusb2_reg_t * rusb, unsigned num) { while ( rusb->D0FIFOSEL_b.CURPIPE != num ) {} while ( !rusb->D0FIFOCTR_b.FRDY ) {} } @@ -835,7 +815,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) } rusb->PIPECFG = cfg; - rusb->BRDYSTS = 0x1FFu ^ TU_BIT(num); + rusb->BRDYSTS = 0x3FFu ^ TU_BIT(num); rusb->BRDYENB |= TU_BIT(num); if (dir || (xfer != TUSB_XFER_BULK)) { @@ -935,6 +915,18 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) //--------------------------------------------------------------------+ // ISR //--------------------------------------------------------------------+ + +#if defined(__CCRX__) +TU_ATTR_ALWAYS_INLINE static inline unsigned __builtin_ctz(unsigned int value) { + unsigned int count = 0; + while ((value & 1) == 0) { + value >>= 1; + count++; + } + return count; +} +#endif + void dcd_int_handler(uint8_t rhport) { rusb2_reg_t* rusb = RUSB2_REG(rhport); @@ -1026,17 +1018,7 @@ void dcd_int_handler(uint8_t rhport) /* clear active bits (don't write 0 to already cleared bits according to the HW manual) */ rusb->BRDYSTS = ~s; while (s) { -#if defined(__CCRX__) - static const int Mod37BitPosition[] = { - -1, 0, 1, 26, 2, 23, 27, 0, 3, 16, 24, 30, 28, 11, 0, 13, 4, - 7, 17, 0, 25, 22, 31, 15, 29, 10, 12, 6, 0, 21, 14, 9, 5, - 20, 8, 19, 18 - }; - - const unsigned num = Mod37BitPosition[(-s & s) % 37]; -#else const unsigned num = __builtin_ctz(s); -#endif process_pipe_brdy(rhport, num); s &= ~TU_BIT(num); } diff --git a/src/portable/renesas/rusb2/hcd_rusb2.c b/src/portable/renesas/rusb2/hcd_rusb2.c index bf95be707c..f140da6909 100644 --- a/src/portable/renesas/rusb2/hcd_rusb2.c +++ b/src/portable/renesas/rusb2/hcd_rusb2.c @@ -45,6 +45,9 @@ //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM DECLARATION //--------------------------------------------------------------------+ +enum { + PIPE_COUNT = 10, +}; TU_ATTR_PACKED_BEGIN TU_ATTR_BIT_FIELD_ORDER_BEGIN @@ -75,7 +78,7 @@ TU_ATTR_BIT_FIELD_ORDER_END typedef struct { bool need_reset; /* The device has not been reset after connection. */ - pipe_state_t pipe[10]; + pipe_state_t pipe[PIPE_COUNT]; uint8_t ep[4][2][15]; /* a lookup table for a pipe index from an endpoint address */ uint8_t ctl_mps[5]; /* EP0 max packet size for each device */ } hcd_data_t; @@ -86,46 +89,30 @@ typedef struct static hcd_data_t _hcd; // TODO merged with DCD -// Transfer conditions specifiable for each pipe: +// Transfer conditions specifiable for each pipe for most MCUs // - Pipe 0: Control transfer with 64-byte single buffer -// - Pipes 1 and 2: Bulk isochronous transfer continuous transfer mode with programmable buffer size up -// to 2 KB and optional double buffer -// - Pipes 3 to 5: Bulk transfer continuous transfer mode with programmable buffer size up to 2 KB and -// optional double buffer -// - Pipes 6 to 9: Interrupt transfer with 64-byte single buffer -enum { - PIPE_1ST_BULK = 3, - PIPE_1ST_INTERRUPT = 6, - PIPE_COUNT = 10, -}; +// - Pipes 1 and 2: Bulk or ISO +// - Pipes 3 to 5: Bulk +// - Pipes 6 to 9: Interrupt +// +// Note: for small mcu such as +// - RA2A1: only pipe 4-7 are available, and no support for ISO +static unsigned find_pipe(unsigned xfer_type) { + const uint8_t pipe_idx_arr[4][2] = { + { 0, 0 }, // Control + { 1, 2 }, // Isochronous + { 1, 5 }, // Bulk + { 6, 9 }, // Interrupt + }; + + // find backward since only pipe 1, 2 support ISO + const uint8_t idx_first = pipe_idx_arr[xfer_type][0]; + const uint8_t idx_last = pipe_idx_arr[xfer_type][1]; -static unsigned find_pipe(unsigned xfer) { - switch ( xfer ) { - case TUSB_XFER_ISOCHRONOUS: - for (int i = 1; i < PIPE_1ST_BULK; ++i) { - if ( 0 == _hcd.pipe[i].ep ) return i; - } - break; - - case TUSB_XFER_BULK: - for (int i = PIPE_1ST_BULK; i < PIPE_1ST_INTERRUPT; ++i) { - if ( 0 == _hcd.pipe[i].ep ) return i; - } - for (int i = 1; i < PIPE_1ST_BULK; ++i) { - if ( 0 == _hcd.pipe[i].ep ) return i; - } - break; - - case TUSB_XFER_INTERRUPT: - for (int i = PIPE_1ST_INTERRUPT; i < PIPE_COUNT; ++i) { - if ( 0 == _hcd.pipe[i].ep ) return i; - } - break; - - default: - /* No support for control transfer */ - break; + for (int i = idx_last; i >= idx_first; i--) { + if (0 == _hcd.pipe[i].ep) return i; } + return 0; } @@ -718,7 +705,7 @@ bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const } rusb->PIPECFG = cfg; - rusb->BRDYSTS = 0x1FFu ^ TU_BIT(num); + rusb->BRDYSTS = 0x3FFu ^ TU_BIT(num); rusb->NRDYENB |= TU_BIT(num); rusb->BRDYENB |= TU_BIT(num); @@ -771,6 +758,17 @@ bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { //--------------------------------------------------------------------+ // ISR //--------------------------------------------------------------------+ +#if defined(__CCRX__) +TU_ATTR_ALWAYS_INLINE static inline unsigned __builtin_ctz(unsigned int value) { + unsigned int count = 0; + while ((value & 1) == 0) { + value >>= 1; + count++; + } + return count; +} +#endif + void hcd_int_handler(uint8_t rhport, bool in_isr) { (void) in_isr; @@ -820,23 +818,12 @@ void hcd_int_handler(uint8_t rhport, bool in_isr) { } } -#if defined(__CCRX__) - static const int Mod37BitPosition[] = { - -1, 0, 1, 26, 2, 23, 27, 0, 3, 16, 24, 30, 28, 11, 0, 13, 4, - 7, 17, 0, 25, 22, 31, 15, 29, 10, 12, 6, 0, 21, 14, 9, 5, - 20, 8, 19, 18}; -#endif - if (is0 & RUSB2_INTSTS0_NRDY_Msk) { const unsigned m = rusb->NRDYENB; unsigned s = rusb->NRDYSTS & m; rusb->NRDYSTS = ~s; while (s) { -#if defined(__CCRX__) - const unsigned num = Mod37BitPosition[(-s & s) % 37]; -#else const unsigned num = __builtin_ctz(s); -#endif process_pipe_nrdy(rhport, num); s &= ~TU_BIT(num); } @@ -847,11 +834,7 @@ void hcd_int_handler(uint8_t rhport, bool in_isr) { /* clear active bits (don't write 0 to already cleared bits according to the HW manual) */ rusb->BRDYSTS = ~s; while (s) { -#if defined(__CCRX__) - const unsigned num = Mod37BitPosition[(-s & s) % 37]; -#else const unsigned num = __builtin_ctz(s); -#endif process_pipe_brdy(rhport, num); s &= ~TU_BIT(num); }