summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHa Thach <[email protected]>2024-04-16 00:16:18 +0700
committerGitHub <[email protected]>2024-04-16 00:16:18 +0700
commit50738f2ab4cbb3d1c00db994279dec620b2870f0 (patch)
tree59e7447d32cc8d6537b58170e3a2313126b45238
parentfb21b6a67d84322c7c55fb4962f317c341c058ab (diff)
parent6328301bb652458ad752b05129e1944404adc7ca (diff)
Merge pull request #2588 from hathach/support-ra2a1
Enhance dcd rusb2, support ra2a1 pipe number scheme
-rw-r--r--hw/bsp/ra/boards/ra2a1_ek/board.h4
-rw-r--r--hw/bsp/ra/family.c3
-rw-r--r--hw/bsp/ra/vector_data.h3
-rw-r--r--src/portable/renesas/rusb2/dcd_rusb2.c132
-rw-r--r--src/portable/renesas/rusb2/hcd_rusb2.c89
5 files changed, 101 insertions, 130 deletions
diff --git a/hw/bsp/ra/boards/ra2a1_ek/board.h b/hw/bsp/ra/boards/ra2a1_ek/board.h
index c132387bc..1c2b666d2 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 16332be17..db8988a36 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 ca667faa3..2b3b7d837 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 3ec1b70b5..50400d1f5 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 bf95be707..f140da690 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,
-};
-
-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;
+// - 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
+ };
- case TUSB_XFER_INTERRUPT:
- for (int i = PIPE_1ST_INTERRUPT; i < PIPE_COUNT; ++i) {
- if ( 0 == _hcd.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 == _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);
}