diff options
| author | hathach <[email protected]> | 2023-08-04 00:31:12 +0700 |
|---|---|---|
| committer | hathach <[email protected]> | 2023-08-04 00:31:12 +0700 |
| commit | ef5bd9ee6cc2506745c0c5d602d4c540da681b69 (patch) | |
| tree | cf25b4da1827914720fed5b3abb78029da280e7c /src | |
| parent | 9360a3bd5197792584ede8a33c50a4d3054d84e6 (diff) | |
| parent | 6d03bb9ffc4c80a0c2663f0b791856af89e20adc (diff) | |
Merge branch 'master' into enhance-bsp
Diffstat (limited to 'src')
| -rw-r--r-- | src/common/tusb_common.h | 18 | ||||
| -rw-r--r-- | src/common/tusb_mcu.h | 13 | ||||
| -rw-r--r-- | src/portable/renesas/rusb2/dcd_rusb2.c | 778 | ||||
| -rw-r--r-- | src/portable/renesas/rusb2/hcd_rusb2.c | 540 | ||||
| -rw-r--r-- | src/portable/renesas/rusb2/rusb2_common.c | 61 | ||||
| -rw-r--r-- | src/portable/renesas/rusb2/rusb2_ra.h | 58 | ||||
| -rw-r--r-- | src/portable/renesas/rusb2/rusb2_rx.h | 20 | ||||
| -rw-r--r-- | src/portable/renesas/rusb2/rusb2_type.h | 339 |
8 files changed, 1139 insertions, 688 deletions
diff --git a/src/common/tusb_common.h b/src/common/tusb_common.h index eb4c3ce81..25f85e501 100644 --- a/src/common/tusb_common.h +++ b/src/common/tusb_common.h @@ -263,11 +263,21 @@ TU_ATTR_ALWAYS_INLINE static inline void tu_unaligned_write16(void* mem, uint16_ #else // MCU that could access unaligned memory natively -TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_unaligned_read32 (const void* mem) { return *((uint32_t const *) mem); } -TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_unaligned_read16 (const void* mem) { return *((uint16_t const *) mem); } +TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_unaligned_read32(const void *mem) { + return *((uint32_t const *) mem); +} + +TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_unaligned_read16(const void *mem) { + return *((uint16_t const *) mem); +} -TU_ATTR_ALWAYS_INLINE static inline void tu_unaligned_write32 (void* mem, uint32_t value ) { *((uint32_t*) mem) = value; } -TU_ATTR_ALWAYS_INLINE static inline void tu_unaligned_write16 (void* mem, uint16_t value ) { *((uint16_t*) mem) = value; } +TU_ATTR_ALWAYS_INLINE static inline void tu_unaligned_write32(void *mem, uint32_t value) { + *((uint32_t *) mem) = value; +} + +TU_ATTR_ALWAYS_INLINE static inline void tu_unaligned_write16(void *mem, uint16_t value) { + *((uint16_t *) mem) = value; +} #endif diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index 9f3be78fd..89f89182e 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -34,10 +34,16 @@ //------------- Unaligned Memory Access -------------// -// ARMv7+ (M3-M7, M23-M33) can access unaligned memory -#if (defined(__ARM_ARCH) && (__ARM_ARCH >= 7)) - #define TUP_ARCH_STRICT_ALIGN 0 +#ifdef __ARM_ARCH + // ARM Architecture set __ARM_FEATURE_UNALIGNED to 1 for mcu supports unaligned access + #if defined(__ARM_FEATURE_UNALIGNED) && __ARM_FEATURE_UNALIGNED == 1 + #define TUP_ARCH_STRICT_ALIGN 0 + #else + #define TUP_ARCH_STRICT_ALIGN 1 + #endif #else + // TODO default to strict align for others + // Should investigate other architecture such as risv, xtensa, mips for optimal setting #define TUP_ARCH_STRICT_ALIGN 1 #endif @@ -327,6 +333,7 @@ // Renesas //--------------------------------------------------------------------+ #elif TU_CHECK_MCU(OPT_MCU_RX63X, OPT_MCU_RX65X, OPT_MCU_RX72N, OPT_MCU_RAXXX) + #define TUP_USBIP_RUSB2 #define TUP_DCD_ENDPOINT_MAX 10 //--------------------------------------------------------------------+ diff --git a/src/portable/renesas/rusb2/dcd_rusb2.c b/src/portable/renesas/rusb2/dcd_rusb2.c index 022c1b5b6..3ec1b70b5 100644 --- a/src/portable/renesas/rusb2/dcd_rusb2.c +++ b/src/portable/renesas/rusb2/dcd_rusb2.c @@ -27,13 +27,12 @@ #include "tusb_option.h" +#if CFG_TUD_ENABLED && defined(TUP_USBIP_RUSB2) + // Since TinyUSB doesn't use SOF for now, and this interrupt too often (1ms interval) // We disable SOF for now until needed later on #define USE_SOF 0 -#if CFG_TUD_ENABLED && (TU_CHECK_MCU(OPT_MCU_RX63X, OPT_MCU_RX65X, OPT_MCU_RX72N) || \ - TU_CHECK_MCU(OPT_MCU_RAXXX)) - #include "device/dcd.h" #include "rusb2_type.h" @@ -41,48 +40,28 @@ #include "rusb2_rx.h" #elif TU_CHECK_MCU(OPT_MCU_RAXXX) #include "rusb2_ra.h" + #if defined(RENESAS_CORTEX_M23) + #define D0FIFO CFIFO + #define D0FIFOSEL CFIFOSEL + #define D0FIFOSEL_b CFIFOSEL_b + #define D1FIFOSEL CFIFOSEL + #define D1FIFOSEL_b CFIFOSEL_b + #define D0FIFOCTR CFIFOCTR + #define D0FIFOCTR_b CFIFOCTR_b + #endif + #else #error "Unsupported MCU" #endif -#define TU_RUSB2_DCD_DBG 0 - //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM //--------------------------------------------------------------------+ -/* LINK core registers */ -#if defined(__CCRX__) - #define RUSB2 ((RUSB2_REG_t __evenaccess*) RUSB2_REG_BASE) -#else - #define RUSB2 ((RUSB2_REG_t*) RUSB2_REG_BASE) -#endif - /* 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 { - union { - struct { - uint16_t : 8; - uint16_t TRCLR: 1; - uint16_t TRENB: 1; - uint16_t : 0; - }; - uint16_t TRE; - }; - uint16_t TRN; -} reg_pipetre_t; - -typedef union TU_ATTR_PACKED { - struct { - volatile uint16_t u8: 8; - volatile uint16_t : 0; - }; - volatile uint16_t u16; -} hw_fifo_t; - typedef struct TU_ATTR_PACKED { void *buf; /* the start address of a transfer data buffer */ @@ -104,188 +83,257 @@ typedef struct uint8_t ep[2][16]; /* a lookup table for a pipe index from an endpoint address */ } dcd_data_t; +static dcd_data_t _dcd; + //--------------------------------------------------------------------+ // INTERNAL OBJECT & FUNCTION DECLARATION //--------------------------------------------------------------------+ -static dcd_data_t _dcd; + +// 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 <= 2; ++i) { - if (0 == _dcd.pipe[i].ep) return i; - } - break; - case TUSB_XFER_BULK: - for (int i = 3; i <= 5; ++i) { - if (0 == _dcd.pipe[i].ep) return i; - } - for (int i = 1; i <= 1; ++i) { - if (0 == _dcd.pipe[i].ep) return i; - } - break; - case TUSB_XFER_INTERRUPT: - for (int i = 6; i <= 9; ++i) { - if (0 == _dcd.pipe[i].ep) return i; - } - break; - default: - /* No support for control transfer */ - break; + 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; + + case TUSB_XFER_INTERRUPT: + for (int i = PIPE_1ST_INTERRUPT; i < PIPE_COUNT; ++i) { + if (0 == _dcd.pipe[i].ep) return i; + } + break; + + default: + /* No support for control transfer */ + break; } return 0; } -static volatile uint16_t* get_pipectr(unsigned num) +static volatile uint16_t* get_pipectr(rusb2_reg_t *rusb, unsigned num) { if (num) { - return (volatile uint16_t*)&(RUSB2->PIPE_CTR[num - 1]); + return (volatile uint16_t*)&(rusb->PIPE_CTR[num - 1]); } else { - return (volatile uint16_t*)&(RUSB2->DCPCTR); + return (volatile uint16_t*)&(rusb->DCPCTR); } } -static volatile reg_pipetre_t* get_pipetre(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*)&(RUSB2->PIPE_TR[num - 1].E); + tre = (volatile reg_pipetre_t*)&(rusb->PIPE_TR[num - 1].E); } return tre; } static volatile uint16_t* ep_addr_to_pipectr(uint8_t rhport, unsigned ep_addr) { - (void)rhport; + rusb2_reg_t *rusb = RUSB2_REG(rhport); const unsigned epn = tu_edpt_number(ep_addr); + if (epn) { const unsigned dir = tu_edpt_dir(ep_addr); const unsigned num = _dcd.ep[dir][epn]; - return get_pipectr(num); + return get_pipectr(rusb, num); } else { - return get_pipectr(0); + return get_pipectr(rusb, 0); } } -static unsigned edpt0_max_packet_size(void) +static uint16_t edpt0_max_packet_size(rusb2_reg_t* rusb) { - return RUSB2->DCPMAXP_b.MXPS; + return rusb->DCPMAXP_b.MXPS; } -static unsigned edpt_max_packet_size(unsigned num) +static uint16_t edpt_max_packet_size(rusb2_reg_t *rusb, unsigned num) { - RUSB2->PIPESEL = num; - return RUSB2->PIPEMAXP; + rusb->PIPESEL = num; + return rusb->PIPEMAXP; } -static inline void pipe_wait_for_ready(unsigned num) +static inline void pipe_wait_for_ready(rusb2_reg_t * rusb, unsigned num) { - while (RUSB2->D0FIFOSEL_b.CURPIPE != num) ; - while (!RUSB2->D0FIFOCTR_b.FRDY) ; + while ( rusb->D0FIFOSEL_b.CURPIPE != num ) {} + while ( !rusb->D0FIFOCTR_b.FRDY ) {} } -static void pipe_write_packet(void *buf, volatile void *fifo, unsigned len) +//--------------------------------------------------------------------+ +// Pipe FIFO +//--------------------------------------------------------------------+ + +// Write data buffer --> hw fifo +static void pipe_write_packet(rusb2_reg_t * rusb, void *buf, volatile void *fifo, unsigned len) { - volatile hw_fifo_t *reg = (volatile hw_fifo_t*) fifo; - uintptr_t addr = (uintptr_t)buf; + (void) rusb; + + volatile uint16_t *ff16; + volatile uint8_t *ff8; + + // Highspeed FIFO is 32-bit + if ( rusb2_is_highspeed_reg(rusb) ) { + // TODO 32-bit access for better performance + ff16 = (volatile uint16_t*) ((uintptr_t) fifo+2); + ff8 = (volatile uint8_t *) ((uintptr_t) fifo+3); + }else { + ff16 = (volatile uint16_t*) fifo; + ff8 = ((volatile uint8_t*) fifo); + } + + uint8_t const* buf8 = (uint8_t const*) buf; + while (len >= 2) { - reg->u16 = *(const uint16_t *)addr; - addr += 2; + *ff16 = tu_unaligned_read16(buf8); + buf8 += 2; len -= 2; } - if (len) { - reg->u8 = *(const uint8_t *)addr; - ++addr; + + if (len > 0) { + *ff8 = *buf8; + ++buf8; } } -static void pipe_read_packet(void *buf, volatile void *fifo, unsigned len) +// Read data buffer <-- hw fifo +static void pipe_read_packet(rusb2_reg_t * rusb, void *buf, volatile void *fifo, unsigned len) { - uint8_t *p = (uint8_t*)buf; + (void) rusb; + + // TODO 16/32-bit access for better performance + + uint8_t *p = (uint8_t*)buf; volatile uint8_t *reg = (volatile uint8_t*)fifo; /* byte access is always at base register address */ while (len--) *p++ = *reg; } -static void pipe_read_write_packet_ff(tu_fifo_t *f, volatile void *fifo, unsigned len, unsigned dir) -{ - static const struct { - void (*tu_fifo_get_info)(tu_fifo_t *f, tu_fifo_buffer_info_t *info); - void (*tu_fifo_advance)(tu_fifo_t *f, uint16_t n); - void (*pipe_read_write)(void *buf, volatile void *fifo, unsigned len); - } ops[] = { - /* OUT */ {tu_fifo_get_write_info,tu_fifo_advance_write_pointer,pipe_read_packet}, - /* IN */ {tu_fifo_get_read_info, tu_fifo_advance_read_pointer, pipe_write_packet}, - }; +// Write data sw fifo --> hw fifo +static void pipe_write_packet_ff(rusb2_reg_t * rusb, tu_fifo_t *f, volatile void *fifo, uint16_t total_len) { tu_fifo_buffer_info_t info; - ops[dir].tu_fifo_get_info(f, &info); - unsigned total_len = len; - len = TU_MIN(total_len, info.len_lin); - ops[dir].pipe_read_write(info.ptr_lin, fifo, len); - unsigned rem = total_len - len; + tu_fifo_get_read_info(f, &info); + + uint16_t count = tu_min16(total_len, info.len_lin); + pipe_write_packet(rusb, info.ptr_lin, fifo, count); + + uint16_t rem = total_len - count; + if (rem) { + rem = tu_min16(rem, info.len_wrap); + pipe_write_packet(rusb, info.ptr_wrap, fifo, rem); + count += rem; + } + + tu_fifo_advance_read_pointer(f, count); +} + +// Read data sw fifo <-- hw fifo +static void pipe_read_packet_ff(rusb2_reg_t * rusb, tu_fifo_t *f, volatile void *fifo, uint16_t total_len) { + tu_fifo_buffer_info_t info; + tu_fifo_get_write_info(f, &info); + + uint16_t count = tu_min16(total_len, info.len_lin); + pipe_read_packet(rusb, info.ptr_lin, fifo, count); + + uint16_t rem = total_len - count; if (rem) { - len = TU_MIN(rem, info.len_wrap); - ops[dir].pipe_read_write(info.ptr_wrap, fifo, len); - rem -= len; + rem = tu_min16(rem, info.len_wrap); + pipe_read_packet(rusb, info.ptr_wrap, fifo, rem); + count += rem; } - ops[dir].tu_fifo_advance(f, total_len - rem); + + tu_fifo_advance_write_pointer(f, count); } -static bool pipe0_xfer_in(void) +//--------------------------------------------------------------------+ +// Pipe Transfer +//--------------------------------------------------------------------+ + +static bool pipe0_xfer_in(rusb2_reg_t* rusb) { pipe_state_t *pipe = &_dcd.pipe[0]; const unsigned rem = pipe->remaining; + if (!rem) { pipe->buf = NULL; return true; } - const unsigned mps = edpt0_max_packet_size(); - const unsigned len = TU_MIN(mps, rem); + + const uint16_t mps = edpt0_max_packet_size(rusb); + const uint16_t len = tu_min16(mps, rem); void *buf = pipe->buf; + if (len) { if (pipe->ff) { - pipe_read_write_packet_ff((tu_fifo_t*)buf, (volatile void*)&RUSB2->CFIFO, len, TUSB_DIR_IN); + pipe_write_packet_ff(rusb, (tu_fifo_t*)buf, (volatile void*)&rusb->CFIFO, len); } else { - pipe_write_packet(buf, (volatile void*)&RUSB2->CFIFO, len); + pipe_write_packet(rusb, buf, (volatile void*)&rusb->CFIFO, len); pipe->buf = (uint8_t*)buf + len; } } + if (len < mps) { - RUSB2->CFIFOCTR = RUSB2_CFIFOCTR_BVAL_Msk; + rusb->CFIFOCTR = RUSB2_CFIFOCTR_BVAL_Msk; } + pipe->remaining = rem - len; return false; } -static bool pipe0_xfer_out(void) +static bool pipe0_xfer_out(rusb2_reg_t* rusb) { pipe_state_t *pipe = &_dcd.pipe[0]; const unsigned rem = pipe->remaining; - const unsigned mps = edpt0_max_packet_size(); - const unsigned vld = RUSB2->CFIFOCTR_b.DTLN; - const unsigned len = TU_MIN(TU_MIN(rem, mps), vld); + const uint16_t mps = edpt0_max_packet_size(rusb); + const uint16_t vld = rusb->CFIFOCTR_b.DTLN; + const uint16_t len = tu_min16(tu_min16(rem, mps), vld); void *buf = pipe->buf; + if (len) { if (pipe->ff) { - pipe_read_write_packet_ff((tu_fifo_t*)buf, (volatile void*)&RUSB2->CFIFO, len, TUSB_DIR_OUT); + pipe_read_packet_ff(rusb, (tu_fifo_t*)buf, (volatile void*)&rusb->CFIFO, len); } else { - pipe_read_packet(buf, (volatile void*)&RUSB2->CFIFO, len); + pipe_read_packet(rusb, buf, (volatile void*)&rusb->CFIFO, len); pipe->buf = (uint8_t*)buf + len; } } + if (len < mps) { - RUSB2->CFIFOCTR = RUSB2_CFIFOCTR_BCLR_Msk; + rusb->CFIFOCTR = RUSB2_CFIFOCTR_BCLR_Msk; } + pipe->remaining = rem - len; if ((len < mps) || (rem == len)) { pipe->buf = NULL; return true; } + return false; } -static bool pipe_xfer_in(unsigned num) +static bool pipe_xfer_in(rusb2_reg_t* rusb, unsigned num) { pipe_state_t *pipe = &_dcd.pipe[num]; const unsigned rem = pipe->remaining; @@ -295,119 +343,141 @@ static bool pipe_xfer_in(unsigned num) return true; } - RUSB2->D0FIFOSEL = num | RUSB2_FIFOSEL_MBW_16BIT | (TU_BYTE_ORDER == TU_BIG_ENDIAN ? RUSB2_FIFOSEL_BIGEND : 0); - const unsigned mps = edpt_max_packet_size(num); - pipe_wait_for_ready(num); - const unsigned len = TU_MIN(rem, mps); + rusb->D0FIFOSEL = num | RUSB2_FIFOSEL_MBW_16BIT | (TU_BYTE_ORDER == TU_BIG_ENDIAN ? RUSB2_FIFOSEL_BIGEND : 0); + const uint16_t mps = edpt_max_packet_size(rusb, num); + pipe_wait_for_ready(rusb, num); + const uint16_t len = tu_min16(rem, mps); void *buf = pipe->buf; + if (len) { if (pipe->ff) { - pipe_read_write_packet_ff((tu_fifo_t*)buf, (volatile void*)&RUSB2->D0FIFO, len, TUSB_DIR_IN); + pipe_write_packet_ff(rusb, (tu_fifo_t*)buf, (volatile void*)&rusb->D0FIFO, len); } else { - pipe_write_packet(buf, (volatile void*)&RUSB2->D0FIFO, len); + pipe_write_packet(rusb, buf, (volatile void*)&rusb->D0FIFO, len); pipe->buf = (uint8_t*)buf + len; } } + if (len < mps) { - RUSB2->D0FIFOCTR = RUSB2_CFIFOCTR_BVAL_Msk; + rusb->D0FIFOCTR = RUSB2_CFIFOCTR_BVAL_Msk; } - RUSB2->D0FIFOSEL = 0; - while (RUSB2->D0FIFOSEL_b.CURPIPE) {} /* if CURPIPE bits changes, check written value */ + + rusb->D0FIFOSEL = 0; + while (rusb->D0FIFOSEL_b.CURPIPE) {} /* if CURPIPE bits changes, check written value */ + pipe->remaining = rem - len; + return false; } -static bool pipe_xfer_out(unsigned num) +static bool pipe_xfer_out(rusb2_reg_t* rusb, unsigned num) { pipe_state_t *pipe = &_dcd.pipe[num]; - const unsigned rem = pipe->remaining; + const uint16_t rem = pipe->remaining; + + rusb->D0FIFOSEL = num | RUSB2_FIFOSEL_MBW_8BIT; + const uint16_t mps = edpt_max_packet_size(rusb, num); + pipe_wait_for_ready(rusb, num); - RUSB2->D0FIFOSEL = num | RUSB2_FIFOSEL_MBW_8BIT; - const unsigned mps = edpt_max_packet_size(num); - pipe_wait_for_ready(num); - const unsigned vld = RUSB2->D0FIFOCTR_b.DTLN; - const unsigned len = TU_MIN(TU_MIN(rem, mps), vld); + const uint16_t vld = rusb->D0FIFOCTR_b.DTLN; + const uint16_t len = tu_min16(tu_min16(rem, mps), vld); void *buf = pipe->buf; + if (len) { if (pipe->ff) { - pipe_read_write_packet_ff((tu_fifo_t*)buf, (volatile void*)&RUSB2->D0FIFO, len, TUSB_DIR_OUT); + pipe_read_packet_ff(rusb, (tu_fifo_t*)buf, (volatile void*)&rusb->D0FIFO, len); } else { - pipe_read_packet(buf, (volatile void*)&RUSB2->D0FIFO, len); + pipe_read_packet(rusb, buf, (volatile void*)&rusb->D0FIFO, len); pipe->buf = (uint8_t*)buf + len; } } + if (len < mps) { - RUSB2->D0FIFOCTR = RUSB2_CFIFOCTR_BCLR_Msk; + rusb->D0FIFOCTR = RUSB2_CFIFOCTR_BCLR_Msk; } - RUSB2->D0FIFOSEL = 0; - while (RUSB2->D0FIFOSEL_b.CURPIPE) {} /* if CURPIPE bits changes, check written value */ + + rusb->D0FIFOSEL = 0; + while (rusb->D0FIFOSEL_b.CURPIPE) {} /* if CURPIPE bits changes, check written value */ + pipe->remaining = rem - len; if ((len < mps) || (rem == len)) { pipe->buf = NULL; return NULL != buf; } + return false; } static void process_setup_packet(uint8_t rhport) { - uint16_t setup_packet[4]; - if (0 == (RUSB2->INTSTS0 & RUSB2_INTSTS0_VALID_Msk)) return; - RUSB2->CFIFOCTR = RUSB2_CFIFOCTR_BCLR_Msk; - setup_packet[0] = tu_le16toh(RUSB2->USBREQ); - setup_packet[1] = RUSB2->USBVAL; - setup_packet[2] = RUSB2->USBINDX; - setup_packet[3] = RUSB2->USBLENG; - RUSB2->INTSTS0 = ~((uint16_t)RUSB2_INTSTS0_VALID_Msk); + rusb2_reg_t* rusb = RUSB2_REG(rhport); + if (0 == (rusb->INTSTS0 & RUSB2_INTSTS0_VALID_Msk)) return; + + rusb->CFIFOCTR = RUSB2_CFIFOCTR_BCLR_Msk; + uint16_t setup_packet[4] = { + tu_htole16(rusb->USBREQ), + tu_htole16(rusb->USBVAL), + tu_htole16(rusb->USBINDX), + tu_htole16(rusb->USBLENG) + }; + + rusb->INTSTS0 = ~((uint16_t) RUSB2_INTSTS0_VALID_Msk); dcd_event_setup_received(rhport, (const uint8_t*)&setup_packet[0], true); } static void process_status_completion(uint8_t rhport) { + rusb2_reg_t* rusb = RUSB2_REG(rhport); uint8_t ep_addr; /* Check the data stage direction */ - if (RUSB2->CFIFOSEL & RUSB2_CFIFOSEL_ISEL_WRITE) { + if (rusb->CFIFOSEL & RUSB2_CFIFOSEL_ISEL_WRITE) { /* IN transfer. */ ep_addr = tu_edpt_addr(0, TUSB_DIR_IN); } else { /* OUT transfer. */ ep_addr = tu_edpt_addr(0, TUSB_DIR_OUT); } + dcd_event_xfer_complete(rhport, ep_addr, 0, XFER_RESULT_SUCCESS, true); } -static bool process_pipe0_xfer(int buffer_type, uint8_t ep_addr, void* buffer, uint16_t total_bytes) +static bool process_pipe0_xfer(rusb2_reg_t* rusb, int buffer_type, uint8_t ep_addr, void* buffer, uint16_t total_bytes) { /* configure fifo direction and access unit settings */ - if (ep_addr) { /* IN, 2 bytes */ - RUSB2->CFIFOSEL = RUSB2_CFIFOSEL_ISEL_WRITE | RUSB2_FIFOSEL_MBW_16BIT | - (TU_BYTE_ORDER == TU_BIG_ENDIAN ? RUSB2_FIFOSEL_BIGEND : 0); - while (!(RUSB2->CFIFOSEL & RUSB2_CFIFOSEL_ISEL_WRITE)) ; - } else { /* OUT, a byte */ - RUSB2->CFIFOSEL = RUSB2_FIFOSEL_MBW_8BIT; - while (RUSB2->CFIFOSEL & RUSB2_CFIFOSEL_ISEL_WRITE) ; + if ( ep_addr ) { + /* IN, 2 bytes */ + rusb->CFIFOSEL = RUSB2_CFIFOSEL_ISEL_WRITE | RUSB2_FIFOSEL_MBW_16BIT | + (TU_BYTE_ORDER == TU_BIG_ENDIAN ? RUSB2_FIFOSEL_BIGEND : 0); + while ( !(rusb->CFIFOSEL & RUSB2_CFIFOSEL_ISEL_WRITE) ) {} + } else { + /* OUT, a byte */ + rusb->CFIFOSEL = RUSB2_FIFOSEL_MBW_8BIT; + while ( rusb->CFIFOSEL & RUSB2_CFIFOSEL_ISEL_WRITE ) {} } pipe_state_t *pipe = &_dcd.pipe[0]; pipe->ff = buffer_type; pipe->length = total_bytes; pipe->remaining = total_bytes; - if (total_bytes) { - pipe->buf = buffer; - if (ep_addr) { /* IN */ - TU_ASSERT(RUSB2->DCPCTR_b.BSTS && (RUSB2->USBREQ & 0x80)); - pipe0_xfer_in(); + + if ( total_bytes ) { + pipe->buf = buffer; + if ( ep_addr ) { + /* IN */ + TU_ASSERT(rusb->DCPCTR_b.BSTS && (rusb->USBREQ & 0x80)); + pipe0_xfer_in(rusb); } - RUSB2->DCPCTR = RUSB2_PIPE_CTR_PID_BUF; + rusb->DCPCTR = RUSB2_PIPE_CTR_PID_BUF; } else { /* ZLP */ - pipe->buf = NULL; - RUSB2->DCPCTR = RUSB2_DCPCTR_CCPL_Msk | RUSB2_PIPE_CTR_PID_BUF; + pipe->buf = NULL; + rusb->DCPCTR = RUSB2_DCPCTR_CCPL_Msk | RUSB2_PIPE_CTR_PID_BUF; } + return true; } -static bool process_pipe_xfer(int buffer_type, uint8_t ep_addr, void* buffer, uint16_t total_bytes) +static bool process_pipe_xfer(rusb2_reg_t* rusb, int buffer_type, uint8_t ep_addr, void* buffer, uint16_t total_bytes) { const unsigned epn = tu_edpt_number(ep_addr); const unsigned dir = tu_edpt_dir(ep_addr); @@ -420,49 +490,55 @@ static bool process_pipe_xfer(int buffer_type, uint8_t ep_addr, void* buffer, ui pipe->buf = buffer; pipe->length = total_bytes; pipe->remaining = total_bytes; - if (dir) { /* IN */ + + if (dir) { + /* IN */ if (total_bytes) { - pipe_xfer_in(num); - } else { /* ZLP */ - RUSB2->D0FIFOSEL = num; - pipe_wait_for_ready(num); - RUSB2->D0FIFOCTR = RUSB2_CFIFOCTR_BVAL_Msk; - RUSB2->D0FIFOSEL = 0; - while (RUSB2->D0FIFOSEL_b.CURPIPE) ; /* if CURPIPE bits changes, check written value */ + pipe_xfer_in(rusb, num); + } else { + /* ZLP */ + rusb->D0FIFOSEL = num; + pipe_wait_for_ready(rusb, num); + rusb->D0FIFOCTR = RUSB2_CFIFOCTR_BVAL_Msk; + rusb->D0FIFOSEL = 0; + /* if CURPIPE bits changes, check written value */ + while (rusb->D0FIFOSEL_b.CURPIPE) {} } } else { -#if defined(__CCRX__) - __evenaccess volatile reg_pipetre_t *pt = get_pipetre(num); -#else - volatile reg_pipetre_t *pt = get_pipetre(num); -#endif + // OUT + volatile reg_pipetre_t *pt = get_pipetre(rusb, num); + if (pt) { - const unsigned mps = edpt_max_packet_size(num); - volatile uint16_t *ctr = get_pipectr(num); + const uint16_t mps = edpt_max_packet_size(rusb, num); + volatile uint16_t *ctr = get_pipectr(rusb, num); + if (*ctr & 0x3) *ctr = RUSB2_PIPE_CTR_PID_NAK; + pt->TRE = TU_BIT(8); pt->TRN = (total_bytes + mps - 1) / mps; pt->TRENB = 1; *ctr = RUSB2_PIPE_CTR_PID_BUF; } } - TU_LOG(TU_RUSB2_DCD_DBG ,"X %x %d %d\r\n", ep_addr, total_bytes, buffer_type); + + // TU_LOG2("X %x %d %d\r\n", ep_addr, total_bytes, buffer_type); return true; } -static bool process_edpt_xfer(int buffer_type, uint8_t ep_addr, void* buffer, uint16_t total_bytes) +static bool process_edpt_xfer(rusb2_reg_t* rusb, int buffer_type, uint8_t ep_addr, void* buffer, uint16_t total_bytes) { const unsigned epn = tu_edpt_number(ep_addr); if (0 == epn) { - return process_pipe0_xfer(buffer_type, ep_addr, buffer, total_bytes); + return process_pipe0_xfer(rusb, buffer_type, ep_addr, buffer, total_bytes); } else { - return process_pipe_xfer(buffer_type, ep_addr, buffer, total_bytes); + return process_pipe_xfer(rusb, buffer_type, ep_addr, buffer, total_bytes); } } static void process_pipe0_bemp(uint8_t rhport) { - bool completed = pipe0_xfer_in(); + rusb2_reg_t* rusb = RUSB2_REG(rhport); + bool completed = pipe0_xfer_in(rusb); if (completed) { pipe_state_t *pipe = &_dcd.pipe[0]; dcd_event_xfer_complete(rhport, tu_edpt_addr(0, TUSB_DIR_IN), @@ -472,62 +548,94 @@ static void process_pipe0_bemp(uint8_t rhport) static void process_pipe_brdy(uint8_t rhport, unsigned num) { + rusb2_reg_t* rusb = RUSB2_REG(rhport); pipe_state_t *pipe = &_dcd.pipe[num]; const unsigned dir = tu_edpt_dir(pipe->ep); bool completed; - if (dir) { /* IN */ - completed = pipe_xfer_in(num); + if (dir) { + /* IN */ + completed = pipe_xfer_in(rusb, num); } else { + // OUT if (num) { - completed = pipe_xfer_out(num); + completed = pipe_xfer_out(rusb, num); } else { - completed = pipe0_xfer_out(); + completed = pipe0_xfer_out(rusb); } } if (completed) { dcd_event_xfer_complete(rhport, pipe->ep, pipe->length - pipe->remaining, XFER_RESULT_SUCCESS, true); - TU_LOG(TU_RUSB2_DCD_DBG, "C %d %d\r\n", num, pipe->length - pipe->remaining); + // TU_LOG1("C %d %d\r\n", num, pipe->length - pipe->remaining); } } static void process_bus_reset(uint8_t rhport) { - RUSB2->BEMPENB = 1; - RUSB2->BRDYENB = 1; - RUSB2->CFIFOCTR = RUSB2_CFIFOCTR_BCLR_Msk; - RUSB2->D0FIFOSEL = 0; - while (RUSB2->D0FIFOSEL_b.CURPIPE) ; /* if CURPIPE bits changes, check written value */ - RUSB2->D1FIFOSEL = 0; - while (RUSB2->D1FIFOSEL_b.CURPIPE) ; /* if CURPIPE bits changes, check written value */ - volatile uint16_t *ctr = (volatile uint16_t*)((uintptr_t) (&RUSB2->PIPE_CTR[0])); - volatile uint16_t *tre = (volatile uint16_t*)((uintptr_t) (&RUSB2->PIPE_TR[0].E)); + rusb2_reg_t* rusb = RUSB2_REG(rhport); + + rusb->BEMPENB = 1; + rusb->BRDYENB = 1; + rusb->CFIFOCTR = RUSB2_CFIFOCTR_BCLR_Msk; + + rusb->D0FIFOSEL = 0; + while (rusb->D0FIFOSEL_b.CURPIPE) {} /* if CURPIPE bits changes, check written value */ + + rusb->D1FIFOSEL = 0; + while (rusb->D1FIFOSEL_b.CURPIPE) {} /* if CURPIPE bits changes, check written value */ + + volatile uint16_t *ctr = (volatile uint16_t*)((uintptr_t) (&rusb->PIPE_CTR[0])); + volatile uint16_t *tre = (volatile uint16_t*)((uintptr_t) (&rusb->PIPE_TR[0].E)); + for (int i = 1; i <= 5; ++i) { - RUSB2->PIPESEL = i; - RUSB2->PIPECFG = 0; + rusb->PIPESEL = i; + rusb->PIPECFG = 0; *ctr = RUSB2_PIPE_CTR_ACLRM_Msk; *ctr = 0; ++ctr; *tre = TU_BIT(8); tre += 2; } + for (int i = 6; i <= 9; ++i) { - RUSB2->PIPESEL = i; - RUSB2->PIPECFG = 0; + rusb->PIPESEL = i; + rusb->PIPECFG = 0; *ctr = RUSB2_PIPE_CTR_ACLRM_Msk; *ctr = 0; ++ctr; } tu_varclr(&_dcd); - dcd_event_bus_reset(rhport, TUSB_SPEED_FULL, true); + + TU_LOG3("Bus reset, RHST = %u\r\n", rusb->DVSTCTR0_b.RHST); + tusb_speed_t speed; + switch(rusb->DVSTCTR0 & RUSB2_DVSTCTR0_RHST_Msk) { + case RUSB2_DVSTCTR0_RHST_LS: + speed = TUSB_SPEED_LOW; + break; + + case RUSB2_DVSTCTR0_RHST_FS: + speed = TUSB_SPEED_FULL; + break; + + case RUSB2_DVSTCTR0_RHST_HS: + speed = TUSB_SPEED_HIGH; + break; + + default: + TU_ASSERT(false, ); + } + + dcd_event_bus_reset(rhport, speed, true); } static void process_set_address(uint8_t rhport) { - const uint32_t addr = RUSB2->USBADDR_b.USBADDR; + rusb2_reg_t* rusb = RUSB2_REG(rhport); + const uint16_t addr = rusb->USBADDR_b.USBADDR; if (!addr) return; + const tusb_control_request_t setup_packet = { #if defined(__CCRX__) .bmRequestType = { 0 }, /* Note: CCRX needs the braces over this struct member */ @@ -538,8 +646,9 @@ static void process_set_address(uint8_t rhport) .wValue = addr, .wIndex = 0, .wLength = 0, - }; - dcd_event_setup_received(rhport, (const uint8_t*)&setup_packet, true); + }; + + dcd_event_setup_received(rhport, (const uint8_t *) &setup_packet, true); } /*------------------------------------------------------------------*/ @@ -572,73 +681,97 @@ static void enable_interrupt(uint32_t pswi) void dcd_init(uint8_t rhport) { - (void)rhport; + rusb2_reg_t* rusb = RUSB2_REG(rhport); + rusb2_module_start(rhport, true); -#if 0 // previously present in the rx driver before generalization - uint32_t pswi = disable_interrupt(); - SYSTEM.PRCR.WORD = SYSTEM_PRCR_PRKEY | SYSTEM_PRCR_PRC1; - MSTP(USB0) = 0; - SYSTEM.PRCR.WORD = SYSTEM_PRCR_PRKEY; - enable_interrupt(pswi); -#endif +#ifdef RUSB2_SUPPORT_HIGHSPEED + if ( rusb2_is_highspeed_rhport(rhport) ) { + rusb->SYSCFG_b.HSE = 1; + + // leave CLKSEL as default (0x11) 24Mhz - RUSB2->SYSCFG_b.SCKE = 1; - while (!RUSB2->SYSCFG_b.SCKE) ; - RUSB2->SYSCFG_b.DRPD = 0; - RUSB2->SYSCFG_b.DCFM = 0; - RUSB2->SYSCFG_b.USBE = 1; + // Power and reset UTMI Phy + uint16_t physet = (rusb->PHYSET | RUSB2_PHYSET_PLLRESET_Msk) & ~RUSB2_PHYSET_DIRPD_Msk; + rusb->PHYSET = physet; + R_BSP_SoftwareDelay((uint32_t) 1, BSP_DELAY_UNITS_MILLISECONDS); + rusb->PHYSET_b.PLLRESET = 0; - // MCU specific PHY init - rusb2_phy_init(); + // set UTMI to operating mode and wait for PLL lock confirmation + rusb->LPSTS_b.SUSPENDM = 1; + while (!rusb->PLLSTA_b.PLLLOCK) {} - RUSB2->PHYSLEW = 0x5; - RUSB2->DPUSR0R_FS_b.FIXPHY0 = 0u; /* USB_BASE Transceiver Output fixed */ + rusb->SYSCFG_b.DRPD = 0; + rusb->SYSCFG_b.USBE = 1; + + // Set CPU bus wait time (fine tunne later) + // rusb2->BUSWAIT |= 0x0F00U; + + rusb->PHYSET_b.REPSEL = 1; + } else +#endif + { + rusb->SYSCFG_b.SCKE = 1; + while (!rusb->SYSCFG_b.SCKE) {} + rusb->SYSCFG_b.DRPD = 0; + rusb->SYSCFG_b.DCFM = 0; + rusb->SYSCFG_b.USBE = 1; + + // MCU specific PHY init + rusb2_phy_init(); + + rusb->PHYSLEW = 0x5; + rusb->DPUSR0R_FS_b.FIXPHY0 = 0u; /* USB_BASE Transceiver Output fixed */ + } /* Setup default control pipe */ - RUSB2->DCPMAXP_b.MXPS = 64; - RUSB2->INTENB0 = RUSB2_INTSTS0_VBINT_Msk | RUSB2_INTSTS0_BRDY_Msk | RUSB2_INTSTS0_BEMP_Msk | - RUSB2_INTSTS0_DVST_Msk | RUSB2_INTSTS0_CTRT_Msk | (USE_SOF ? RUSB2_INTSTS0_SOFR_Msk : 0) | - RUSB2_INTSTS0_RESM_Msk; - RUSB2->BEMPENB = 1; - RUSB2->BRDYENB = 1; + rusb->DCPMAXP_b.MXPS = 64; + + rusb->INTSTS0 = 0; + rusb->INTENB0 = RUSB2_INTSTS0_VBINT_Msk | RUSB2_INTSTS0_BRDY_Msk | RUSB2_INTSTS0_BEMP_Msk | + RUSB2_INTSTS0_DVST_Msk | RUSB2_INTSTS0_CTRT_Msk | (USE_SOF ? RUSB2_INTSTS0_SOFR_Msk : 0) | + RUSB2_INTSTS0_RESM_Msk; + rusb->BEMPENB = 1; + rusb->BRDYENB = 1; - if (RUSB2->INTSTS0_b.VBSTS) { + // If VBUS (detect) pin is not used, application need to call tud_connect() manually after tud_init() + if (rusb->INTSTS0_b.VBSTS) { dcd_connect(rhport); } } -void dcd_int_enable(uint8_t rhport) -{ +void dcd_int_enable(uint8_t rhport) { rusb2_int_enable(rhport); } -void dcd_int_disable(uint8_t rhport) -{ +void dcd_int_disable(uint8_t rhport) { rusb2_int_disable(rhport); } -void dcd_set_address(uint8_t rhport, uint8_t dev_addr) -{ - (void)rhport; - (void)dev_addr; +void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { + (void) rhport; + (void) dev_addr; } void dcd_remote_wakeup(uint8_t rhport) { - (void)rhport; - RUSB2->DVSTCTR0_b.WKUP = 1; + rusb2_reg_t* rusb = RUSB2_REG(rhport); + rusb->DVSTCTR0_b.WKUP = 1; } void dcd_connect(uint8_t rhport) { - (void)rhport; - RUSB2->SYSCFG_b.DPRPU = 1; + rusb2_reg_t* rusb = RUSB2_REG(rhport); + + if ( rusb2_is_highspeed_rhport(rhport)) { + rusb->SYSCFG_b.CNEN = 1; + } + rusb->SYSCFG_b.DPRPU = 1; } void dcd_disconnect(uint8_t rhport) { - (void)rhport; - RUSB2->SYSCFG_b.DPRPU = 0; + rusb2_reg_t* rusb = RUSB2_REG(rhport); + rusb->SYSCFG_b.DPRPU = 0; } void dcd_sof_enable(uint8_t rhport, bool en) @@ -656,30 +789,43 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) { (void)rhport; + rusb2_reg_t * rusb = RUSB2_REG(rhport); const unsigned ep_addr = ep_desc->bEndpointAddress; const unsigned epn = tu_edpt_number(ep_addr); const unsigned dir = tu_edpt_dir(ep_addr); const unsigned xfer = ep_desc->bmAttributes.xfer; const unsigned mps = tu_edpt_packet_size(ep_desc); - if (xfer == TUSB_XFER_ISOCHRONOUS && mps > 256) { - /* USBa supports up to 256 bytes */ - return false; + + if (xfer == TUSB_XFER_ISOCHRONOUS) { + // Fullspeed ISO is limit to 256 bytes + if ( !rusb2_is_highspeed_rhport(rhport) && mps > 256) { + return false; + } } const unsigned num = find_pipe(xfer); - if (!num) return false; + TU_ASSERT(num); + _dcd.pipe[num].ep = ep_addr; _dcd.ep[dir][epn] = num; /* setup pipe */ dcd_int_disable(rhport); - RUSB2->PIPESEL = num; - RUSB2->PIPEMAXP = mps; - volatile uint16_t *ctr = get_pipectr(num); + + if ( rusb2_is_highspeed_rhport(rhport) ) { + // FIXME shouldn't be after pipe selection and config, also the BUFNMB should be changed + // depending on the allocation scheme + rusb->PIPEBUF = 0x7C08; + } + + rusb->PIPESEL = num; + rusb->PIPEMAXP = mps; + volatile uint16_t *ctr = get_pipectr(rusb, num); *ctr = RUSB2_PIPE_CTR_ACLRM_Msk | RUSB2_PIPE_CTR_SQCLR_Msk; *ctr = 0; unsigned cfg = (dir << 4) | epn; + if (xfer == TUSB_XFER_BULK) { cfg |= (RUSB2_PIPECFG_TYPE_BULK | RUSB2_PIPECFG_SHTNAK_Msk | RUSB2_PIPECFG_DBLB_Msk); } else if (xfer == TUSB_XFER_INTERRUPT) { @@ -687,13 +833,16 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) } else { cfg |= (RUSB2_PIPECFG_TYPE_ISO | RUSB2_PIPECFG_DBLB_Msk); } - RUSB2->PIPECFG = cfg; - RUSB2->BRDYSTS = 0x1FFu ^ TU_BIT(num); - RUSB2->BRDYENB |= TU_BIT(num); + + rusb->PIPECFG = cfg; + rusb->BRDYSTS = 0x1FFu ^ TU_BIT(num); + rusb->BRDYENB |= TU_BIT(num); + if (dir || (xfer != TUSB_XFER_BULK)) { *ctr = RUSB2_PIPE_CTR_PID_BUF; } - TU_LOG(TU_RUSB2_DCD_DBG, "O %d %x %x\r\n", RUSB2->PIPESEL, RUSB2->PIPECFG, RUSB2->PIPEMAXP); + + // TU_LOG1("O %d %x %x\r\n", rusb->PIPESEL, rusb->PIPECFG, rusb->PIPEMAXP); dcd_int_enable(rhport); return true; @@ -713,26 +862,28 @@ void dcd_edpt_close_all(uint8_t rhport) void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { - (void)rhport; + rusb2_reg_t * rusb = RUSB2_REG(rhport); const unsigned epn = tu_edpt_number(ep_addr); const unsigned dir = tu_edpt_dir(ep_addr); const unsigned num = _dcd.ep[dir][epn]; - RUSB2->BRDYENB &= ~TU_BIT(num); - volatile uint16_t *ctr = get_pipectr(num); + rusb->BRDYENB &= ~TU_BIT(num); + volatile uint16_t *ctr = get_pipectr(rusb, num); *ctr = 0; - RUSB2->PIPESEL = num; - RUSB2->PIPECFG = 0; + rusb->PIPESEL = num; + rusb->PIPECFG = 0; _dcd.pipe[num].ep = 0; _dcd.ep[dir][epn] = 0; } bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes) { - bool r; + rusb2_reg_t* rusb = RUSB2_REG(rhport); + dcd_int_disable(rhport); - r = process_edpt_xfer(0, ep_addr, buffer, total_bytes); + bool r = process_edpt_xfer(rusb, 0, ep_addr, buffer, total_bytes); dcd_int_enable(rhport); + return r; } @@ -740,10 +891,12 @@ bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_ { // USB buffers always work in bytes so to avoid unnecessary divisions we demand item_size = 1 TU_ASSERT(ff->item_size == 1); - bool r; + rusb2_reg_t* rusb = RUSB2_REG(rhport); + dcd_int_disable(rhport); - r = process_edpt_xfer(1, ep_addr, ff, total_bytes); + bool r = process_edpt_xfer(rusb, 1, ep_addr, ff, total_bytes); dcd_int_enable(rhport); + return r; } @@ -760,8 +913,10 @@ void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { + rusb2_reg_t * rusb = RUSB2_REG(rhport); volatile uint16_t *ctr = ep_addr_to_pipectr(rhport, ep_addr); if (!ctr) return; + dcd_int_disable(rhport); *ctr = RUSB2_PIPE_CTR_SQCLR_Msk; @@ -769,8 +924,8 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) *ctr = RUSB2_PIPE_CTR_PID_BUF; } else { const unsigned num = _dcd.ep[0][tu_edpt_number(ep_addr)]; - RUSB2->PIPESEL = num; - if (RUSB2->PIPECFG_b.TYPE != 1) { + rusb->PIPESEL = num; + if (rusb->PIPECFG_b.TYPE != 1) { *ctr = RUSB2_PIPE_CTR_PID_BUF; } } @@ -782,73 +937,94 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) //--------------------------------------------------------------------+ void dcd_int_handler(uint8_t rhport) { - (void)rhport; + rusb2_reg_t* rusb = RUSB2_REG(rhport); + + uint16_t is0 = rusb->INTSTS0; - unsigned is0 = RUSB2->INTSTS0; /* clear active bits except VALID (don't write 0 to already cleared bits according to the HW manual) */ - RUSB2->INTSTS0 = ~((RUSB2_INTSTS0_CTRT_Msk | RUSB2_INTSTS0_DVST_Msk | RUSB2_INTSTS0_SOFR_Msk | - RUSB2_INTSTS0_RESM_Msk | RUSB2_INTSTS0_VBINT_Msk) & is0) | RUSB2_INTSTS0_VALID_Msk; - if (is0 & RUSB2_INTSTS0_VBINT_Msk) { - if (RUSB2->INTSTS0_b.VBSTS) { + rusb->INTSTS0 = ~((RUSB2_INTSTS0_CTRT_Msk | RUSB2_INTSTS0_DVST_Msk | RUSB2_INTSTS0_SOFR_Msk | + RUSB2_INTSTS0_RESM_Msk | RUSB2_INTSTS0_VBINT_Msk) & is0) | RUSB2_INTSTS0_VALID_Msk; + + // VBUS changes + if ( is0 & RUSB2_INTSTS0_VBINT_Msk ) { + if ( rusb->INTSTS0_b.VBSTS ) { dcd_connect(rhport); } else { dcd_disconnect(rhport); } } - if (is0 & RUSB2_INTSTS0_RESM_Msk) { + + // Resumed + if ( is0 & RUSB2_INTSTS0_RESM_Msk ) { dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true); -#if (0==USE_SOF) - RUSB2->INTENB0_b.SOFE = 0; +#if (0 == USE_SOF) + rusb->INTENB0_b.SOFE = 0; #endif } - if ((is0 & RUSB2_INTSTS0_SOFR_Msk) && RUSB2->INTENB0_b.SOFE) { + + // SOF received + if ( (is0 & RUSB2_INTSTS0_SOFR_Msk) && rusb->INTENB0_b.SOFE ) { // USBD will exit suspended mode when SOF event is received dcd_event_bus_signal(rhport, DCD_EVENT_SOF, true); #if (0 == USE_SOF) - RUSB2->INTENB0_b.SOFE = 0; + rusb->INTENB0_b.SOFE = 0; #endif } - if (is0 & RUSB2_INTSTS0_DVST_Msk) { + + // Device state changes + if ( is0 & RUSB2_INTSTS0_DVST_Msk ) { switch (is0 & RUSB2_INTSTS0_DVSQ_Msk) { - case RUSB2_INTSTS0_DVSQ_STATE_DEF: - process_bus_reset(rhport); - break; - case RUSB2_INTSTS0_DVSQ_STATE_ADDR: - process_set_address(rhport); - break; - case RUSB2_INTSTS0_DVSQ_STATE_SUSP0: - case RUSB2_INTSTS0_DVSQ_STATE_SUSP1: - case RUSB2_INTSTS0_DVSQ_STATE_SUSP2: - case RUSB2_INTSTS0_DVSQ_STATE_SUSP3: - dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true); -#if (0==USE_SOF) - RUSB2->INTENB0_b.SOFE = 1; + case RUSB2_INTSTS0_DVSQ_STATE_DEF: + process_bus_reset(rhport); + break; + + case RUSB2_INTSTS0_DVSQ_STATE_ADDR: + process_set_address(rhport); + break; + + case RUSB2_INTSTS0_DVSQ_STATE_SUSP0: + case RUSB2_INTSTS0_DVSQ_STATE_SUSP1: + case RUSB2_INTSTS0_DVSQ_STATE_SUSP2: + case RUSB2_INTSTS0_DVSQ_STATE_SUSP3: + dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true); +#if (0 == USE_SOF) + rusb->INTENB0_b.SOFE = 1; #endif - default: - break; + + default: break; } } - if (is0 & RUSB2_INTSTS0_CTRT_Msk) { - if (is0 & RUSB2_INTSTS0_CTSQ_CTRL_RDATA) { + +// if ( is0 & RUSB2_INTSTS0_NRDY_Msk ) { +// rusb->NRDYSTS = 0; +// } + + // Control transfer stage changes + if ( is0 & RUSB2_INTSTS0_CTRT_Msk ) { + if ( is0 & RUSB2_INTSTS0_CTSQ_CTRL_RDATA ) { /* A setup packet has been received. */ process_setup_packet(rhport); - } else if (0 == (is0 & RUSB2_INTSTS0_CTSQ_Msk)) { + } else if ( 0 == (is0 & RUSB2_INTSTS0_CTSQ_Msk) ) { /* A ZLP has been sent/received. */ process_status_completion(rhport); } } - if (is0 & RUSB2_INTSTS0_BEMP_Msk) { - const unsigned s = RUSB2->BEMPSTS; - RUSB2->BEMPSTS = 0; - if (s & 1) { + + // Buffer empty + if ( is0 & RUSB2_INTSTS0_BEMP_Msk ) { + const uint16_t s = rusb->BEMPSTS; + rusb->BEMPSTS = 0; + if ( s & 1 ) { process_pipe0_bemp(rhport); } } - if (is0 & RUSB2_INTSTS0_BRDY_Msk) { - const unsigned m = RUSB2->BRDYENB; - unsigned s = RUSB2->BRDYSTS & m; + + // Buffer ready + if ( is0 & RUSB2_INTSTS0_BRDY_Msk ) { + const unsigned m = rusb->BRDYENB; + unsigned s = rusb->BRDYSTS & m; /* clear active bits (don't write 0 to already cleared bits according to the HW manual) */ - RUSB2->BRDYSTS = ~s; + rusb->BRDYSTS = ~s; while (s) { #if defined(__CCRX__) static const int Mod37BitPosition[] = { diff --git a/src/portable/renesas/rusb2/hcd_rusb2.c b/src/portable/renesas/rusb2/hcd_rusb2.c index 292d40da8..f6683529a 100644 --- a/src/portable/renesas/rusb2/hcd_rusb2.c +++ b/src/portable/renesas/rusb2/hcd_rusb2.c @@ -27,8 +27,7 @@ #include "tusb_option.h" -#if CFG_TUH_ENABLED && (TU_CHECK_MCU(OPT_MCU_RX63X, OPT_MCU_RX65X, OPT_MCU_RX72N) || \ - TU_CHECK_MCU(OPT_MCU_RAXXX)) +#if CFG_TUH_ENABLED && defined(TUP_USBIP_RUSB2) #include "host/hcd.h" #include "rusb2_type.h" @@ -41,35 +40,15 @@ #error "Unsupported MCU" #endif -#define TU_RUSB2_HCD_DBG 0 +#define TU_RUSB2_HCD_DBG 2 //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM DECLARATION //--------------------------------------------------------------------+ -/* LINK core registers */ -#if defined(__CCRX__) - #define RUSB2 ((RUSB2_REG_t __evenaccess*) RUSB2_REG_BASE) -#else - #define RUSB2 ((RUSB2_REG_t*) RUSB2_REG_BASE) -#endif - TU_ATTR_PACKED_BEGIN TU_ATTR_BIT_FIELD_ORDER_BEGIN -typedef struct TU_ATTR_PACKED { - union { - struct { - uint16_t : 8; - uint16_t TRCLR: 1; - uint16_t TRENB: 1; - uint16_t : 0; - }; - uint16_t TRE; - }; - uint16_t TRN; -} reg_pipetre_t; - typedef union TU_ATTR_PACKED { struct { volatile uint16_t u8: 8; @@ -106,83 +85,102 @@ typedef struct //--------------------------------------------------------------------+ static hcd_data_t _hcd; -static unsigned find_pipe(unsigned xfer) -{ - switch (xfer) { - case TUSB_XFER_ISOCHRONOUS: - for (int i = 1; i <= 2; ++i) { - if (0 == _hcd.pipe[i].ep) return i; - } - break; - case TUSB_XFER_BULK: - for (int i = 3; i <= 5; ++i) { - if (0 == _hcd.pipe[i].ep) return i; - } - for (int i = 1; i <= 2; ++i) { - if (0 == _hcd.pipe[i].ep) return i; - } - break; - case TUSB_XFER_INTERRUPT: - for (int i = 6; i <= 9; ++i) { - if (0 == _hcd.pipe[i].ep) return i; - } - break; - default: - /* No support for control transfer */ - break; +// TODO merged with DCD +// 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 == _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; } return 0; } -static volatile uint16_t* get_pipectr(unsigned num) +static volatile uint16_t* get_pipectr(rusb2_reg_t *rusb, unsigned num) { if (num) { - return (volatile uint16_t*)&(RUSB2->PIPE_CTR[num - 1]); + return (volatile uint16_t*)&(rusb->PIPE_CTR[num - 1]); } else { - return (volatile uint16_t*)&(RUSB2->DCPCTR); + return (volatile uint16_t*)&(rusb->DCPCTR); } } -static volatile reg_pipetre_t* get_pipetre(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*)&(RUSB2->PIPE_TR[num - 1].E); + tre = (volatile reg_pipetre_t*)&(rusb->PIPE_TR[num - 1].E); } return tre; } -static volatile uint16_t* addr_to_pipectr(uint8_t dev_addr, unsigned ep_addr) +static volatile uint16_t* addr_to_pipectr(uint8_t rhport, uint8_t dev_addr, unsigned ep_addr) { + rusb2_reg_t* rusb = RUSB2_REG(rhport); const unsigned epn = tu_edpt_number(ep_addr); + if (epn) { const unsigned dir_in = tu_edpt_dir(ep_addr); const unsigned num = _hcd.ep[dev_addr][dir_in][epn - 1]; - return get_pipectr(num); + return get_pipectr(rusb, num); } else { - return get_pipectr(0); + return get_pipectr(rusb, 0); } } -static unsigned edpt0_max_packet_size(void) +static uint16_t edpt0_max_packet_size(rusb2_reg_t* rusb) { - return RUSB2->DCPMAXP_b.MXPS; + return rusb->DCPMAXP_b.MXPS; } -static unsigned edpt_max_packet_size(unsigned num) +static uint16_t edpt_max_packet_size(rusb2_reg_t *rusb, unsigned num) { - RUSB2->PIPESEL = num; - return RUSB2->PIPEMAXP_b.MXPS; + rusb->PIPESEL = num; + return rusb->PIPEMAXP_b.MXPS; } -static inline void pipe_wait_for_ready(unsigned num) +static inline void pipe_wait_for_ready(rusb2_reg_t* rusb, unsigned num) { - while (RUSB2->D0FIFOSEL_b.CURPIPE != num) ; - while (!RUSB2->D0FIFOCTR_b.FRDY) ; + while (rusb->D0FIFOSEL_b.CURPIPE != num) ; + while (!rusb->D0FIFOCTR_b.FRDY) {} } static void pipe_write_packet(void *buf, volatile void *fifo, unsigned len) { + // NOTE: unlike DCD, Highspeed 32-bit FIFO does not need to adjust the fifo address volatile hw_fifo_t *reg = (volatile hw_fifo_t*)fifo; uintptr_t addr = (uintptr_t)buf; while (len >= 2) { @@ -203,33 +201,33 @@ static void pipe_read_packet(void *buf, volatile void *fifo, unsigned len) while (len--) *p++ = *reg; } -static bool pipe0_xfer_in(void) +static bool pipe0_xfer_in(rusb2_reg_t* rusb) { pipe_state_t *pipe = &_hcd.pipe[0]; const unsigned rem = pipe->remaining; - const unsigned mps = edpt0_max_packet_size(); - const unsigned vld = RUSB2->CFIFOCTR_b.DTLN; + const unsigned mps = edpt0_max_packet_size(rusb); + const unsigned vld = rusb->CFIFOCTR_b.DTLN; const unsigned len = TU_MIN(TU_MIN(rem, mps), vld); void *buf = pipe->buf; if (len) { - RUSB2->DCPCTR = RUSB2_PIPE_CTR_PID_NAK; - pipe_read_packet(buf, (volatile void*)&RUSB2->CFIFO, len); + rusb->DCPCTR = RUSB2_PIPE_CTR_PID_NAK; + pipe_read_packet(buf, (volatile void*)&rusb->CFIFO, len); pipe->buf = (uint8_t*)buf + len; } if (len < mps) { - RUSB2->CFIFOCTR = RUSB2_CFIFOCTR_BCLR_Msk; + rusb->CFIFOCTR = RUSB2_CFIFOCTR_BCLR_Msk; } pipe->remaining = rem - len; if ((len < mps) || (rem == len)) { pipe->buf = NULL; return true; } - RUSB2->DCPCTR = RUSB2_PIPE_CTR_PID_BUF; + rusb->DCPCTR = RUSB2_PIPE_CTR_PID_BUF; return false; } -static bool pipe0_xfer_out(void) +static bool pipe0_xfer_out(rusb2_reg_t* rusb) { pipe_state_t *pipe = &_hcd.pipe[0]; const unsigned rem = pipe->remaining; @@ -237,40 +235,40 @@ static bool pipe0_xfer_out(void) pipe->buf = NULL; return true; } - const unsigned mps = edpt0_max_packet_size(); + const unsigned mps = edpt0_max_packet_size(rusb); const unsigned len = TU_MIN(mps, rem); void *buf = pipe->buf; if (len) { - pipe_write_packet(buf, (volatile void*)&RUSB2->CFIFO, len); + pipe_write_packet(buf, (volatile void*)&rusb->CFIFO, len); pipe->buf = (uint8_t*)buf + len; } if (len < mps) { - RUSB2->CFIFOCTR = RUSB2_CFIFOCTR_BVAL_Msk; + rusb->CFIFOCTR = RUSB2_CFIFOCTR_BVAL_Msk; } pipe->remaining = rem - len; return false; } -static bool pipe_xfer_in(unsigned num) +static bool pipe_xfer_in(rusb2_reg_t* rusb, unsigned num) { pipe_state_t *pipe = &_hcd.pipe[num]; const unsigned rem = pipe->remaining; - RUSB2->D0FIFOSEL = num | RUSB2_FIFOSEL_MBW_8BIT; - const unsigned mps = edpt_max_packet_size(num); - pipe_wait_for_ready(num); - const unsigned vld = RUSB2->D0FIFOCTR_b.DTLN; + rusb->D0FIFOSEL = num | RUSB2_FIFOSEL_MBW_8BIT; + const unsigned mps = edpt_max_packet_size(rusb, num); + pipe_wait_for_ready(rusb, num); + const unsigned vld = rusb->D0FIFOCTR_b.DTLN; const unsigned len = TU_MIN(TU_MIN(rem, mps), vld); void *buf = pipe->buf; if (len) { - pipe_read_packet(buf, (volatile void*)&RUSB2->D0FIFO, len); + pipe_read_packet(buf, (volatile void*)&rusb->D0FIFO, len); pipe->buf = (uint8_t*)buf + len; } if (len < mps) { - RUSB2->D0FIFOCTR = RUSB2_CFIFOCTR_BCLR_Msk; + rusb->D0FIFOCTR = RUSB2_CFIFOCTR_BCLR_Msk; } - RUSB2->D0FIFOSEL = 0; - while (RUSB2->D0FIFOSEL_b.CURPIPE) ; /* if CURPIPE bits changes, check written value */ + rusb->D0FIFOSEL = 0; + while (rusb->D0FIFOSEL_b.CURPIPE) ; /* if CURPIPE bits changes, check written value */ pipe->remaining = rem - len; if ((len < mps) || (rem == len)) { pipe->buf = NULL; @@ -279,7 +277,7 @@ static bool pipe_xfer_in(unsigned num) return false; } -static bool pipe_xfer_out(unsigned num) +static bool pipe_xfer_out(rusb2_reg_t* rusb, unsigned num) { pipe_state_t *pipe = &_hcd.pipe[num]; const unsigned rem = pipe->remaining; @@ -289,36 +287,39 @@ static bool pipe_xfer_out(unsigned num) return true; } - RUSB2->D0FIFOSEL = num | RUSB2_FIFOSEL_MBW_16BIT | (TU_BYTE_ORDER == TU_BIG_ENDIAN ? RUSB2_FIFOSEL_BIGEND : 0); - const unsigned mps = edpt_max_packet_size(num); - pipe_wait_for_ready(num); + rusb->D0FIFOSEL = num | RUSB2_FIFOSEL_MBW_16BIT | (TU_BYTE_ORDER == TU_BIG_ENDIAN ? RUSB2_FIFOSEL_BIGEND : 0); + const unsigned mps = edpt_max_packet_size(rusb, num); + pipe_wait_for_ready(rusb, num); const unsigned len = TU_MIN(rem, mps); void *buf = pipe->buf; if (len) { - pipe_write_packet(buf, (volatile void*)&RUSB2->D0FIFO, len); + pipe_write_packet(buf, (volatile void*)&rusb->D0FIFO, len); pipe->buf = (uint8_t*)buf + len; } - if (len < mps) - RUSB2->D0FIFOCTR = RUSB2_CFIFOCTR_BVAL_Msk; - RUSB2->D0FIFOSEL = 0; - while (RUSB2->D0FIFOSEL_b.CURPIPE) ; /* if CURPIPE bits changes, check written value */ + if (len < mps) { + rusb->D0FIFOCTR = RUSB2_CFIFOCTR_BVAL_Msk; + } + rusb->D0FIFOSEL = 0; + while (rusb->D0FIFOSEL_b.CURPIPE) ; /* if CURPIPE bits changes, check written value */ pipe->remaining = rem - len; return false; } -static bool process_pipe0_xfer(uint8_t dev_addr, uint8_t ep_addr, void* buffer, uint16_t buflen) +static bool process_pipe0_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, void* buffer, uint16_t buflen) { (void)dev_addr; + + rusb2_reg_t* rusb = RUSB2_REG(rhport); const unsigned dir_in = tu_edpt_dir(ep_addr); /* configure fifo direction and access unit settings */ if (dir_in) { /* IN, a byte */ - RUSB2->CFIFOSEL = RUSB2_FIFOSEL_MBW_8BIT; - while (RUSB2->CFIFOSEL & RUSB2_CFIFOSEL_ISEL_WRITE) ; + rusb->CFIFOSEL = RUSB2_FIFOSEL_MBW_8BIT; + while (rusb->CFIFOSEL & RUSB2_CFIFOSEL_ISEL_WRITE) ; } else { /* OUT, 2 bytes */ - RUSB2->CFIFOSEL = RUSB2_CFIFOSEL_ISEL_WRITE | RUSB2_FIFOSEL_MBW_16BIT | + rusb->CFIFOSEL = RUSB2_CFIFOSEL_ISEL_WRITE | RUSB2_FIFOSEL_MBW_16BIT | (TU_BYTE_ORDER == TU_BIG_ENDIAN ? RUSB2_FIFOSEL_BIGEND : 0); - while (!(RUSB2->CFIFOSEL & RUSB2_CFIFOSEL_ISEL_WRITE)) ; + while (!(rusb->CFIFOSEL & RUSB2_CFIFOSEL_ISEL_WRITE)) ; } pipe_state_t *pipe = &_hcd.pipe[0]; @@ -328,26 +329,28 @@ static bool process_pipe0_xfer(uint8_t dev_addr, uint8_t ep_addr, void* buffer, if (buflen) { pipe->buf = buffer; if (!dir_in) { /* OUT */ - TU_ASSERT(RUSB2->DCPCTR_b.BSTS && (RUSB2->USBREQ & 0x80)); - pipe0_xfer_out(); + TU_ASSERT(rusb->DCPCTR_b.BSTS && (rusb->USBREQ & 0x80)); + pipe0_xfer_out(rusb); } } else { /* ZLP */ pipe->buf = NULL; if (!dir_in) { /* OUT */ - RUSB2->CFIFOCTR = RUSB2_CFIFOCTR_BVAL_Msk; + rusb->CFIFOCTR = RUSB2_CFIFOCTR_BVAL_Msk; } - if (dir_in == RUSB2->DCPCFG_b.DIR) { - TU_ASSERT(RUSB2_PIPE_CTR_PID_NAK == RUSB2->DCPCTR_b.PID); - RUSB2->DCPCTR_b.SQSET = 1; - RUSB2->DCPCFG_b.DIR = dir_in ^ 1; + if (dir_in == rusb->DCPCFG_b.DIR) { + TU_ASSERT(RUSB2_PIPE_CTR_PID_NAK == rusb->DCPCTR_b.PID); + rusb->DCPCTR_b.SQSET = 1; + rusb->DCPCFG_b.DIR = dir_in ^ 1; } } - RUSB2->DCPCTR = RUSB2_PIPE_CTR_PID_BUF; + rusb->DCPCTR = RUSB2_PIPE_CTR_PID_BUF; return true; } -static bool process_pipe_xfer(uint8_t dev_addr, uint8_t ep_addr, void *buffer, uint16_t buflen) +static bool process_pipe_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, void *buffer, uint16_t buflen) { + rusb2_reg_t* rusb = RUSB2_REG(rhport); + const unsigned epn = tu_edpt_number(ep_addr); const unsigned dir_in = tu_edpt_dir(ep_addr); const unsigned num = _hcd.ep[dev_addr - 1][dir_in][epn - 1]; @@ -360,19 +363,19 @@ static bool process_pipe_xfer(uint8_t dev_addr, uint8_t ep_addr, void *buffer, u pipe->remaining = buflen; if (!dir_in) { /* OUT */ if (buflen) { - pipe_xfer_out(num); + pipe_xfer_out(rusb, num); } else { /* ZLP */ - RUSB2->D0FIFOSEL = num; - pipe_wait_for_ready(num); - RUSB2->D0FIFOCTR = RUSB2_CFIFOCTR_BVAL_Msk; - RUSB2->D0FIFOSEL = 0; - while (RUSB2->D0FIFOSEL_b.CURPIPE) {} /* if CURPIPE bits changes, check written value */ + rusb->D0FIFOSEL = num; + pipe_wait_for_ready(rusb, num); + rusb->D0FIFOCTR = RUSB2_CFIFOCTR_BVAL_Msk; + rusb->D0FIFOSEL = 0; + while (rusb->D0FIFOSEL_b.CURPIPE) {} /* if CURPIPE bits changes, check written value */ } } else { - volatile uint16_t *ctr = get_pipectr(num); - volatile reg_pipetre_t *pt = get_pipetre(num); + volatile uint16_t *ctr = get_pipectr(rusb, num); + volatile reg_pipetre_t *pt = get_pipetre(rusb, num); if (pt) { - const unsigned mps = edpt_max_packet_size(num); + const unsigned mps = edpt_max_packet_size(rusb, num); if (*ctr & 0x3) *ctr = RUSB2_PIPE_CTR_PID_NAK; pt->TRE = TU_BIT(8); pt->TRN = (buflen + mps - 1) / mps; @@ -383,20 +386,20 @@ static bool process_pipe_xfer(uint8_t dev_addr, uint8_t ep_addr, void *buffer, u return true; } -static bool process_edpt_xfer(uint8_t dev_addr, uint8_t ep_addr, void* buffer, uint16_t buflen) +static bool process_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, void* buffer, uint16_t buflen) { const unsigned epn = tu_edpt_number(ep_addr); if (0 == epn) { - return process_pipe0_xfer(dev_addr, ep_addr, buffer, buflen); + return process_pipe0_xfer(rhport, dev_addr, ep_addr, buffer, buflen); } else { - return process_pipe_xfer(dev_addr, ep_addr, buffer, buflen); + return process_pipe_xfer(rhport, dev_addr, ep_addr, buffer, buflen); } } static void process_pipe0_bemp(uint8_t rhport) { - (void)rhport; - bool completed = pipe0_xfer_out(); + rusb2_reg_t* rusb = RUSB2_REG(rhport); + bool completed = pipe0_xfer_out(rusb); if (completed) { pipe_state_t *pipe = &_hcd.pipe[0]; hcd_event_xfer_complete(pipe->dev, @@ -408,9 +411,9 @@ static void process_pipe0_bemp(uint8_t rhport) static void process_pipe_nrdy(uint8_t rhport, unsigned num) { - (void)rhport; + rusb2_reg_t* rusb = RUSB2_REG(rhport); xfer_result_t result; - uint16_t volatile *ctr = get_pipectr(num); + uint16_t volatile *ctr = get_pipectr(rusb, num); TU_LOG(TU_RUSB2_HCD_DBG, "NRDY %d %x\n", num, *ctr); switch (*ctr & RUSB2_PIPE_CTR_PID_Msk) { default: return; @@ -426,19 +429,19 @@ static void process_pipe_nrdy(uint8_t rhport, unsigned num) static void process_pipe_brdy(uint8_t rhport, unsigned num) { - (void)rhport; + rusb2_reg_t* rusb = RUSB2_REG(rhport); pipe_state_t *pipe = &_hcd.pipe[num]; const unsigned dir_in = tu_edpt_dir(pipe->ep); bool completed; if (dir_in) { /* IN */ if (num) { - completed = pipe_xfer_in(num); + completed = pipe_xfer_in(rusb, num); } else { - completed = pipe0_xfer_in(); + completed = pipe0_xfer_in(rusb); } } else { - completed = pipe_xfer_out(num); + completed = pipe_xfer_out(rusb, num); } if (completed) { hcd_event_xfer_complete(pipe->dev, pipe->ep, @@ -478,126 +481,146 @@ static void enable_interrupt(uint32_t pswi) bool hcd_init(uint8_t rhport) { - (void)rhport; + rusb2_reg_t* rusb = RUSB2_REG(rhport); + rusb2_module_start(rhport, true); -#if 0 // previously present in the rx driver before generalization - uint32_t pswi = disable_interrupt(); - SYSTEM.PRCR.WORD = SYSTEM_PRCR_PRKEY | SYSTEM_PRCR_PRC1; - MSTP(USB0) = 0; - SYSTEM.PRCR.WORD = SYSTEM_PRCR_PRKEY; - enable_interrupt(pswi); +#ifdef RUSB2_SUPPORT_HIGHSPEED + if (rusb2_is_highspeed_rhport(rhport) ) { + rusb->SYSCFG_b.HSE = 1; + rusb->PHYSET_b.HSEB = 0; + rusb->PHYSET_b.DIRPD = 0; + R_BSP_SoftwareDelay((uint32_t) 1, BSP_DELAY_UNITS_MILLISECONDS); + rusb->PHYSET_b.PLLRESET = 0; + rusb->LPSTS_b.SUSPENDM = 1; + while ( !rusb->PLLSTA_b.PLLLOCK ); + rusb->SYSCFG_b.DRPD = 1; + rusb->SYSCFG_b.DCFM = 1; + rusb->SYSCFG_b.DPRPU = 0; + rusb->SYSCFG_b.CNEN = 1; + rusb->BUSWAIT |= 0x0F00U; + rusb->SOFCFG_b.INTL = 1; + rusb->DVSTCTR0_b.VBUSEN = 1; + rusb->CFIFOSEL_b.MBW = 1; + rusb->D0FIFOSEL_b.MBW = 1; + rusb->D1FIFOSEL_b.MBW = 1; + rusb->INTSTS0 = 0; + for ( volatile int i = 0; i < 30000; ++i ); + rusb->SYSCFG_b.USBE = 1; + } else #endif + { + rusb->SYSCFG_b.SCKE = 1; + while ( !rusb->SYSCFG_b.SCKE ) {} + rusb->SYSCFG_b.DCFM = 1; // Host function + rusb->SYSCFG_b.DPRPU = 0; // Disable D+ pull up + rusb->SYSCFG_b.DRPD = 1; // Enable D+/D- pull down - RUSB2->SYSCFG_b.SCKE = 1; - while (!RUSB2->SYSCFG_b.SCKE) ; - RUSB2->SYSCFG_b.DPRPU = 0; - RUSB2->SYSCFG_b.DRPD = 0; - RUSB2->SYSCFG_b.DCFM = 1; - - RUSB2->DVSTCTR0_b.VBUSEN = 1; + rusb->DVSTCTR0_b.VBUSEN = 1; + for ( volatile int i = 0; i < 30000; ++i ) {} // FIXME do we need to wait here? how long ? + //R_BSP_SoftwareDelay(10, BSP_DELAY_UNITS_MILLISECONDS); + rusb->SYSCFG_b.USBE = 1; - RUSB2->SYSCFG_b.DRPD = 1; - for (volatile int i = 0; i < 30000; ++i) ; - RUSB2->SYSCFG_b.USBE = 1; + // MCU specific PHY init + rusb2_phy_init(); - // MCU specific PHY init - rusb2_phy_init(); - - RUSB2->PHYSLEW = 0x5; - RUSB2->DPUSR0R_FS_b.FIXPHY0 = 0u; /* Transceiver Output fixed */ + rusb->PHYSLEW = 0x5; + rusb->DPUSR0R_FS_b.FIXPHY0 = 0u; /* Transceiver Output fixed */ + } /* Setup default control pipe */ - RUSB2->DCPCFG = RUSB2_PIPECFG_SHTNAK_Msk; - RUSB2->DCPMAXP = 64; - RUSB2->INTENB0 = RUSB2_INTSTS0_BRDY_Msk | RUSB2_INTSTS0_NRDY_Msk | RUSB2_INTSTS0_BEMP_Msk; - RUSB2->INTENB1 = RUSB2_INTSTS1_SACK_Msk | RUSB2_INTSTS1_SIGN_Msk | RUSB2_INTSTS1_ATTCH_Msk | RUSB2_INTSTS1_DTCH_Msk; - RUSB2->BEMPENB = 1; - RUSB2->NRDYENB = 1; - RUSB2->BRDYENB = 1; + rusb->DCPCFG = RUSB2_PIPECFG_SHTNAK_Msk; + rusb->DCPMAXP = 64; + rusb->INTENB0 = RUSB2_INTSTS0_BRDY_Msk | RUSB2_INTSTS0_NRDY_Msk | RUSB2_INTSTS0_BEMP_Msk; + rusb->INTENB1 = RUSB2_INTSTS1_SACK_Msk | RUSB2_INTSTS1_SIGN_Msk | RUSB2_INTSTS1_ATTCH_Msk | RUSB2_INTSTS1_DTCH_Msk; + rusb->BEMPENB = 1; + rusb->NRDYENB = 1; + rusb->BRDYENB = 1; return true; } -void hcd_int_enable(uint8_t rhport) -{ +void hcd_int_enable(uint8_t rhport) { rusb2_int_enable(rhport); } -void hcd_int_disable(uint8_t rhport) -{ +void hcd_int_disable(uint8_t rhport) { rusb2_int_disable(rhport); } uint32_t hcd_frame_number(uint8_t rhport) { - (void)rhport; + rusb2_reg_t* rusb = RUSB2_REG(rhport); + /* The device must be reset at least once after connection * in order to start the frame counter. */ if (_hcd.need_reset) hcd_port_reset(rhport); - return RUSB2->FRMNUM_b.FRNM; + return rusb->FRMNUM_b.FRNM; } /*--------------------------------------------------------------------+ * Port API *--------------------------------------------------------------------+*/ -bool hcd_port_connect_status(uint8_t rhport) -{ - (void)rhport; - return RUSB2->INTSTS1_b.ATTCH ? true : false; +bool hcd_port_connect_status(uint8_t rhport) { + rusb2_reg_t* rusb = RUSB2_REG(rhport); + return rusb->INTSTS1_b.ATTCH ? true : false; } -void hcd_port_reset(uint8_t rhport) -{ - RUSB2->DCPCTR = RUSB2_PIPE_CTR_PID_NAK; - while (RUSB2->DCPCTR_b.PBUSY) ; +void hcd_port_reset(uint8_t rhport) { + rusb2_reg_t* rusb = RUSB2_REG(rhport); + rusb->DCPCTR = RUSB2_PIPE_CTR_PID_NAK; + while (rusb->DCPCTR_b.PBUSY) {} + hcd_int_disable(rhport); - RUSB2->DVSTCTR0_b.UACT = 0; - if (RUSB2->DCPCTR_b.SUREQ) { - RUSB2->DCPCTR_b.SUREQCLR = 1; + rusb->DVSTCTR0_b.UACT = 0; + if (rusb->DCPCTR_b.SUREQ) { + rusb->DCPCTR_b.SUREQCLR = 1; } hcd_int_enable(rhport); + /* Reset should be asserted 10-20ms. */ - RUSB2->DVSTCTR0_b.USBRST = 1; - for (volatile int i = 0; i < 2400000; ++i) ; - RUSB2->DVSTCTR0_b.USBRST = 0; - RUSB2->DVSTCTR0_b.UACT = 1; + rusb->DVSTCTR0_b.USBRST = 1; + for (volatile int i = 0; i < 2400000; ++i) {} + rusb->DVSTCTR0_b.USBRST = 0; + + rusb->DVSTCTR0_b.UACT = 1; _hcd.need_reset = false; } -void hcd_port_reset_end(uint8_t rhport) -{ +void hcd_port_reset_end(uint8_t rhport) { (void) rhport; } -tusb_speed_t hcd_port_speed_get(uint8_t rhport) -{ - (void)rhport; - switch (RUSB2->DVSTCTR0_b.RHST) { - default: return TUSB_SPEED_INVALID; +tusb_speed_t hcd_port_speed_get(uint8_t rhport) { + rusb2_reg_t* rusb = RUSB2_REG(rhport); + switch (rusb->DVSTCTR0_b.RHST) { + case RUSB2_DVSTCTR0_RHST_HS: return TUSB_SPEED_HIGH; case RUSB2_DVSTCTR0_RHST_FS: return TUSB_SPEED_FULL; - case RUSB2_DVSTCTR0_RHST_LS: return TUSB_SPEED_LOW; + case RUSB2_DVSTCTR0_RHST_LS: return TUSB_SPEED_LOW; + default: return TUSB_SPEED_INVALID; } } -void hcd_device_close(uint8_t rhport, uint8_t dev_addr) -{ - (void)rhport; +void hcd_device_close(uint8_t rhport, uint8_t dev_addr) { + rusb2_reg_t* rusb = RUSB2_REG(rhport); uint16_t volatile *ctr; + TU_ASSERT(dev_addr < 6,); /* USBa can only handle addresses from 0 to 5. */ if (!dev_addr) return; + _hcd.ctl_mps[dev_addr] = 0; uint8_t *ep = &_hcd.ep[dev_addr - 1][0][0]; + for (int i = 0; i < 2 * 15; ++i, ++ep) { unsigned num = *ep; if (!num || (dev_addr != _hcd.pipe[num].dev)) continue; - ctr = (uint16_t volatile*)&RUSB2->PIPE_CTR[num - 1]; + ctr = (uint16_t volatile*)&rusb->PIPE_CTR[num - 1]; *ctr = 0; - RUSB2->NRDYENB &= ~TU_BIT(num); - RUSB2->BRDYENB &= ~TU_BIT(num); - RUSB2->PIPESEL = num; - RUSB2->PIPECFG = 0; - RUSB2->PIPEMAXP = 0; + rusb->NRDYENB &= ~TU_BIT(num); + rusb->BRDYENB &= ~TU_BIT(num); + rusb->PIPESEL = num; + rusb->PIPECFG = 0; + rusb->PIPEMAXP = 0; _hcd.pipe[num].ep = 0; _hcd.pipe[num].dev = 0; @@ -610,52 +633,54 @@ void hcd_device_close(uint8_t rhport, uint8_t dev_addr) *--------------------------------------------------------------------+*/ bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8]) { - (void)rhport; - TU_LOG(TU_RUSB2_HCD_DBG, "S %d %x\n", dev_addr, RUSB2->DCPCTR); - TU_ASSERT(dev_addr < 6); /* USBa can only handle addresses from 0 to 5. */ - TU_ASSERT(0 == RUSB2->DCPCTR_b.SUREQ); - RUSB2->DCPCTR = RUSB2_PIPE_CTR_PID_NAK; + rusb2_reg_t* rusb = RUSB2_REG(rhport); + TU_LOG(TU_RUSB2_HCD_DBG, "S %d %x\n", dev_addr, rusb->DCPCTR); + + TU_ASSERT(0 == rusb->DCPCTR_b.SUREQ); + + rusb->DCPCTR = RUSB2_PIPE_CTR_PID_NAK; _hcd.pipe[0].buf = NULL; _hcd.pipe[0].length = 8; _hcd.pipe[0].remaining = 0; _hcd.pipe[0].dev = dev_addr; - while (RUSB2->DCPCTR_b.PBUSY) ; - RUSB2->DCPMAXP = (dev_addr << 12) | _hcd.ctl_mps[dev_addr]; + while (rusb->DCPCTR_b.PBUSY) ; + rusb->DCPMAXP = (dev_addr << 12) | _hcd.ctl_mps[dev_addr]; /* Set direction in advance for DATA stage */ uint8_t const bmRequesttype = setup_packet[0]; - RUSB2->DCPCFG_b.DIR = tu_edpt_dir(bmRequesttype) ? 0: 1; + rusb->DCPCFG_b.DIR = tu_edpt_dir(bmRequesttype) ? 0: 1; uint16_t const* p = (uint16_t const*)(uintptr_t)&setup_packet[0]; - RUSB2->USBREQ = tu_htole16(p[0]); - RUSB2->USBVAL = p[1]; - RUSB2->USBINDX = p[2]; - RUSB2->USBLENG = p[3]; + rusb->USBREQ = tu_htole16(p[0]); + rusb->USBVAL = p[1]; + rusb->USBINDX = p[2]; + rusb->USBLENG = p[3]; - RUSB2->DCPCTR_b.SUREQ = 1; + rusb->DCPCTR_b.SUREQ = 1; return true; } bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const *ep_desc) { - (void)rhport; TU_ASSERT(dev_addr < 6); /* USBa can only handle addresses from 0 to 5. */ + rusb2_reg_t* rusb = RUSB2_REG(rhport); const unsigned ep_addr = ep_desc->bEndpointAddress; const unsigned epn = tu_edpt_number(ep_addr); const unsigned mps = tu_edpt_packet_size(ep_desc); + if (0 == epn) { - RUSB2->DCPCTR = RUSB2_PIPE_CTR_PID_NAK; + rusb->DCPCTR = RUSB2_PIPE_CTR_PID_NAK; hcd_devtree_info_t devtree; hcd_devtree_get_info(dev_addr, &devtree); - uint16_t volatile *devadd = (uint16_t volatile *)(uintptr_t) &RUSB2->DEVADD[0]; + uint16_t volatile *devadd = (uint16_t volatile *)(uintptr_t) &rusb->DEVADD[0]; devadd += dev_addr; - while (RUSB2->DCPCTR_b.PBUSY) ; - RUSB2->DCPMAXP = (dev_addr << 12) | mps; + while (rusb->DCPCTR_b.PBUSY) {} + rusb->DCPMAXP = (dev_addr << 12) | mps; *devadd = (TUSB_SPEED_FULL == devtree.speed) ? RUSB2_DEVADD_USBSPD_FS : RUSB2_DEVADD_USBSPD_LS; _hcd.ctl_mps[dev_addr] = mps; return true; @@ -669,17 +694,20 @@ bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const } const unsigned num = find_pipe(xfer); if (!num) return false; + _hcd.pipe[num].dev = dev_addr; _hcd.pipe[num].ep = ep_addr; _hcd.ep[dev_addr - 1][dir_in][epn - 1] = num; /* setup pipe */ hcd_int_disable(rhport); - RUSB2->PIPESEL = num; - RUSB2->PIPEMAXP = (dev_addr << 12) | mps; - volatile uint16_t *ctr = get_pipectr(num); + + rusb->PIPESEL = num; + rusb->PIPEMAXP = (dev_addr << 12) | mps; + volatile uint16_t *ctr = get_pipectr(rusb, num); *ctr = RUSB2_PIPE_CTR_ACLRM_Msk | RUSB2_PIPE_CTR_SQCLR_Msk; *ctr = 0; + unsigned cfg = ((1 ^ dir_in) << 4) | epn; if (xfer == TUSB_XFER_BULK) { cfg |= RUSB2_PIPECFG_TYPE_BULK | RUSB2_PIPECFG_SHTNAK_Msk | RUSB2_PIPECFG_DBLB_Msk; @@ -688,13 +716,16 @@ bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const } else { cfg |= RUSB2_PIPECFG_TYPE_ISO | RUSB2_PIPECFG_DBLB_Msk; } - RUSB2->PIPECFG = cfg; - RUSB2->BRDYSTS = 0x1FFu ^ TU_BIT(num); - RUSB2->NRDYENB |= TU_BIT(num); - RUSB2->BRDYENB |= TU_BIT(num); + + rusb->PIPECFG = cfg; + rusb->BRDYSTS = 0x1FFu ^ TU_BIT(num); + rusb->NRDYENB |= TU_BIT(num); + rusb->BRDYENB |= TU_BIT(num); + if (!dir_in) { *ctr = RUSB2_PIPE_CTR_PID_BUF; } + hcd_int_enable(rhport); return true; @@ -705,7 +736,7 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *b bool r; hcd_int_disable(rhport); TU_LOG(TU_RUSB2_HCD_DBG, "X %d %x %u\n", dev_addr, ep_addr, buflen); - r = process_edpt_xfer(dev_addr, ep_addr, buffer, buflen); + r = process_edpt_xfer(rhport, dev_addr, ep_addr, buffer, buflen); hcd_int_enable(rhport); return r; } @@ -719,8 +750,7 @@ bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { } bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { - (void) rhport; - uint16_t volatile *ctr = addr_to_pipectr(dev_addr, ep_addr); + uint16_t volatile *ctr = addr_to_pipectr(rhport, dev_addr, ep_addr); TU_ASSERT(ctr); const uint32_t pid = *ctr & 0x3; @@ -743,57 +773,63 @@ bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { //--------------------------------------------------------------------+ void hcd_int_handler(uint8_t rhport) { - (void)rhport; -#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 + rusb2_reg_t* rusb = RUSB2_REG(rhport); + unsigned is0 = rusb->INTSTS0; + unsigned is1 = rusb->INTSTS1; - unsigned is1 = RUSB2->INTSTS1; - unsigned is0 = RUSB2->INTSTS0; /* clear active bits except VALID (don't write 0 to already cleared bits according to the HW manual) */ - RUSB2->INTSTS1 = ~((RUSB2_INTSTS1_SACK_Msk | RUSB2_INTSTS1_SIGN_Msk | RUSB2_INTSTS1_ATTCH_Msk | RUSB2_INTSTS1_DTCH_Msk) & is1); - RUSB2->INTSTS0 = ~((RUSB2_INTSTS0_BRDY_Msk | RUSB2_INTSTS0_NRDY_Msk | RUSB2_INTSTS0_BEMP_Msk) & is0); - TU_LOG(TU_RUSB2_HCD_DBG, "IS %04x %04x\n", is0, is1); - is1 &= RUSB2->INTENB1; - is0 &= RUSB2->INTENB0; + rusb->INTSTS1 = ~((RUSB2_INTSTS1_SACK_Msk | RUSB2_INTSTS1_SIGN_Msk | RUSB2_INTSTS1_ATTCH_Msk | RUSB2_INTSTS1_DTCH_Msk) & is1); + rusb->INTSTS0 = ~((RUSB2_INTSTS0_BRDY_Msk | RUSB2_INTSTS0_NRDY_Msk | RUSB2_INTSTS0_BEMP_Msk) & is0); + + TU_LOG3("IS %04x %04x\n", is0, is1); + is1 &= rusb->INTENB1; + is0 &= rusb->INTENB0; if (is1 & RUSB2_INTSTS1_SACK_Msk) { /* Set DATA1 in advance for the next transfer. */ - RUSB2->DCPCTR_b.SQSET = 1; - hcd_event_xfer_complete(RUSB2->DCPMAXP_b.DEVSEL, tu_edpt_addr(0, TUSB_DIR_OUT), 8, XFER_RESULT_SUCCESS, true); + rusb->DCPCTR_b.SQSET = 1; + hcd_event_xfer_complete(rusb->DCPMAXP_b.DEVSEL, tu_edpt_addr(0, TUSB_DIR_OUT), 8, XFER_RESULT_SUCCESS, true); } + if (is1 & RUSB2_INTSTS1_SIGN_Msk) { - hcd_event_xfer_complete(RUSB2->DCPMAXP_b.DEVSEL, tu_edpt_addr(0, TUSB_DIR_OUT), 8, XFER_RESULT_FAILED, true); + hcd_event_xfer_complete(rusb->DCPMAXP_b.DEVSEL, tu_edpt_addr(0, TUSB_DIR_OUT), 8, XFER_RESULT_FAILED, true); } + if (is1 & RUSB2_INTSTS1_ATTCH_Msk) { - RUSB2->DVSTCTR0_b.UACT = 1; + rusb->DVSTCTR0_b.UACT = 1; _hcd.need_reset = true; - RUSB2->INTENB1 = (RUSB2->INTENB1 & ~RUSB2_INTSTS1_ATTCH_Msk) | RUSB2_INTSTS1_DTCH_Msk; + rusb->INTENB1 = (rusb->INTENB1 & ~RUSB2_INTSTS1_ATTCH_Msk) | RUSB2_INTSTS1_DTCH_Msk; hcd_event_device_attach(rhport, true); } + if (is1 & RUSB2_INTSTS1_DTCH_Msk) { - RUSB2->DVSTCTR0_b.UACT = 0; - if (RUSB2->DCPCTR_b.SUREQ) { - RUSB2->DCPCTR_b.SUREQCLR = 1; + rusb->DVSTCTR0_b.UACT = 0; + if (rusb->DCPCTR_b.SUREQ) { + rusb->DCPCTR_b.SUREQCLR = 1; } - RUSB2->INTENB1 = (RUSB2->INTENB1 & ~RUSB2_INTSTS1_DTCH_Msk) | RUSB2_INTSTS1_ATTCH_Msk; + rusb->INTENB1 = (rusb->INTENB1 & ~RUSB2_INTSTS1_DTCH_Msk) | RUSB2_INTSTS1_ATTCH_Msk; hcd_event_device_remove(rhport, true); } if (is0 & RUSB2_INTSTS0_BEMP_Msk) { - const unsigned s = RUSB2->BEMPSTS; - RUSB2->BEMPSTS = 0; + const unsigned s = rusb->BEMPSTS; + rusb->BEMPSTS = 0; if (s & 1) { process_pipe0_bemp(rhport); } } + +#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 = RUSB2->NRDYENB; - unsigned s = RUSB2->NRDYSTS & m; - RUSB2->NRDYSTS = ~s; + 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]; @@ -805,10 +841,10 @@ void hcd_int_handler(uint8_t rhport) } } if (is0 & RUSB2_INTSTS0_BRDY_Msk) { - const unsigned m = RUSB2->BRDYENB; - unsigned s = RUSB2->BRDYSTS & m; + const unsigned m = rusb->BRDYENB; + unsigned s = rusb->BRDYSTS & m; /* clear active bits (don't write 0 to already cleared bits according to the HW manual) */ - RUSB2->BRDYSTS = ~s; + rusb->BRDYSTS = ~s; while (s) { #if defined(__CCRX__) const unsigned num = Mod37BitPosition[(-s & s) % 37]; diff --git a/src/portable/renesas/rusb2/rusb2_common.c b/src/portable/renesas/rusb2/rusb2_common.c new file mode 100644 index 000000000..850060777 --- /dev/null +++ b/src/portable/renesas/rusb2/rusb2_common.c @@ -0,0 +1,61 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2023 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +#if defined(TUP_USBIP_RUSB2) && (CFG_TUH_ENABLED || CFG_TUD_ENABLED) + +#include "rusb2_type.h" + +#if TU_CHECK_MCU(OPT_MCU_RX63X, OPT_MCU_RX65X, OPT_MCU_RX72N) +#include "rusb2_rx.h" + +#elif TU_CHECK_MCU(OPT_MCU_RAXXX) +#include "rusb2_ra.h" + +// USBFS_INT_IRQn and USBHS_USB_INT_RESUME_IRQn are generated by FSP +rusb2_controller_t rusb2_controller[] = { + { .reg_base = R_USB_FS0_BASE, .irqnum = USBFS_INT_IRQn }, + #ifdef RUSB2_SUPPORT_HIGHSPEED + { .reg_base = R_USB_HS0_BASE, .irqnum = USBHS_USB_INT_RESUME_IRQn }, + #endif +}; + +// Application API for setting IRQ number. May throw warnings for missing prototypes. +void tusb_rusb2_set_irqnum(uint8_t rhport, int32_t irqnum) { + rusb2_controller[rhport].irqnum = irqnum; +} + +// void osal_task_delay(uint32_t msec) { +// R_BSP_SoftwareDelay(msec, BSP_DELAY_UNITS_MILLISECONDS); +// } + +#else + #error "Unsupported MCU" +#endif + + +#endif diff --git a/src/portable/renesas/rusb2/rusb2_ra.h b/src/portable/renesas/rusb2/rusb2_ra.h index df4afdfa0..4774d2e2c 100644 --- a/src/portable/renesas/rusb2/rusb2_ra.h +++ b/src/portable/renesas/rusb2/rusb2_ra.h @@ -47,27 +47,59 @@ extern "C" { #pragma GCC diagnostic pop #endif -#define RUSB2_REG_BASE (0x40090000) - +// IAR does not have __builtin_ctz #if defined(__ICCARM__) - #define __builtin_ctz(x) __iar_builtin_CLZ(__iar_builtin_RBIT(x)) + #define __builtin_ctz(x) __iar_builtin_CLZ(__iar_builtin_RBIT(x)) #endif -TU_ATTR_ALWAYS_INLINE static inline void rusb2_int_enable(uint8_t rhport) -{ - (void) rhport; - NVIC_EnableIRQ(TU_IRQn); +//--------------------------------------------------------------------+ +// +//--------------------------------------------------------------------+ + +typedef struct { + uint32_t reg_base; + int32_t irqnum; +}rusb2_controller_t; + +#if defined(BSP_MCU_GROUP_RA6M5) || defined(BSP_MCU_GROUP_RA6M3) || (BSP_CFG_MCU_PART_SERIES == 8) + #define RUSB2_SUPPORT_HIGHSPEED + #define RUSB2_CONTROLLER_COUNT 2 + + #define rusb2_is_highspeed_rhport(_p) (_p == 1) + #define rusb2_is_highspeed_reg(_reg) (_reg == RUSB2_REG(1)) +#else + #define RUSB2_CONTROLLER_COUNT 1 + + #define rusb2_is_highspeed_rhport(_p) (false) + #define rusb2_is_highspeed_reg(_reg) (false) +#endif + +extern rusb2_controller_t rusb2_controller[]; +#define RUSB2_REG(_p) ((rusb2_reg_t*) rusb2_controller[_p].reg_base) + +//--------------------------------------------------------------------+ +// RUSB2 API +//--------------------------------------------------------------------+ + +TU_ATTR_ALWAYS_INLINE static inline void rusb2_module_start(uint8_t rhport, bool start) { + uint32_t const mask = 1U << (11+rhport); + if (start) { + R_MSTP->MSTPCRB &= ~mask; + }else { + R_MSTP->MSTPCRB |= mask; + } +} + +TU_ATTR_ALWAYS_INLINE static inline void rusb2_int_enable(uint8_t rhport) { + NVIC_EnableIRQ(rusb2_controller[rhport].irqnum); } -TU_ATTR_ALWAYS_INLINE static inline void rusb2_int_disable(uint8_t rhport) -{ - (void) rhport; - NVIC_DisableIRQ(TU_IRQn); +TU_ATTR_ALWAYS_INLINE static inline void rusb2_int_disable(uint8_t rhport) { + NVIC_DisableIRQ(rusb2_controller[rhport].irqnum); } // MCU specific PHY init -TU_ATTR_ALWAYS_INLINE static inline void rusb2_phy_init(void) -{ +TU_ATTR_ALWAYS_INLINE static inline void rusb2_phy_init(void) { } #ifdef __cplusplus diff --git a/src/portable/renesas/rusb2/rusb2_rx.h b/src/portable/renesas/rusb2/rusb2_rx.h index 397c0d56c..7bf4be47e 100644 --- a/src/portable/renesas/rusb2/rusb2_rx.h +++ b/src/portable/renesas/rusb2/rusb2_rx.h @@ -37,6 +37,26 @@ extern "C" { #define RUSB2_REG_BASE (0x000A0000) +TU_ATTR_ALWAYS_INLINE static inline rusb2_reg_t* RUSB2_REG(uint8_t rhport) { + (void) rhport; + return (rusb2_reg_t *) RUSB2_REG_BASE; +} + + +#define rusb2_is_highspeed_rhport(_p) (false) +#define rusb2_is_highspeed_reg(_reg) (false) + +//--------------------------------------------------------------------+ +// +//--------------------------------------------------------------------+ + + +// Start/Stop MSTP TODO implement later +TU_ATTR_ALWAYS_INLINE static inline void rusb2_module_start(uint8_t rhport, bool start) { + (void) rhport; + (void) start; +} + TU_ATTR_ALWAYS_INLINE static inline void rusb2_int_enable(uint8_t rhport) { (void) rhport; diff --git a/src/portable/renesas/rusb2/rusb2_type.h b/src/portable/renesas/rusb2/rusb2_type.h index 83119507a..dd88f66a7 100644 --- a/src/portable/renesas/rusb2/rusb2_type.h +++ b/src/portable/renesas/rusb2/rusb2_type.h @@ -28,11 +28,19 @@ #define _TUSB_RUSB2_TYPE_H_ #include <stdint.h> +#include <stddef.h> #ifdef __cplusplus extern "C" { #endif +// CCRX specific attribute to generate a Code that Accesses Variables in the Declared Size +#ifdef __CCRX__ + #define _ccrx_evenaccess __evenaccess +#else + #define _ccrx_evenaccess +#endif + /*--------------------------------------------------------------------*/ /* Register Definitions */ /*--------------------------------------------------------------------*/ @@ -41,15 +49,29 @@ extern "C" { TU_ATTR_PACKED_BEGIN TU_ATTR_BIT_FIELD_ORDER_BEGIN +// TODO same as RUSB2_PIPE_TR_t +typedef struct TU_ATTR_PACKED _ccrx_evenaccess { + union { + struct { + uint16_t : 8; + uint16_t TRCLR: 1; + uint16_t TRENB: 1; + uint16_t : 0; + }; + uint16_t TRE; + }; + uint16_t TRN; +} reg_pipetre_t; + typedef struct { union { volatile uint16_t E; /* (@ 0x00000000) Pipe Transaction Counter Enable Register */ struct TU_ATTR_PACKED { - uint16_t : 8; + uint16_t : 8; volatile uint16_t TRCLR : 1; /* [8..8] Transaction Counter Clear */ volatile uint16_t TRENB : 1; /* [9..9] Transaction Counter Enable */ - uint16_t : 6; + uint16_t : 6; } E_b; }; @@ -62,8 +84,9 @@ typedef struct { }; } RUSB2_PIPE_TR_t; /* Size = 4 (0x4) */ -/* LINK_REG Structure */ -typedef struct { + +/* RUSB2 Registers Structure */ +typedef struct _ccrx_evenaccess { union { volatile uint16_t SYSCFG; /* (@ 0x00000000) System Configuration Control Register */ @@ -74,7 +97,7 @@ typedef struct { volatile uint16_t DPRPU : 1; /* [4..4] D+ Line Resistor Control */ volatile uint16_t DRPD : 1; /* [5..5] D+/D- Line Resistor Control */ volatile uint16_t DCFM : 1; /* [6..6] Controller Function Select */ - uint16_t : 1; + volatile uint16_t HSE : 1; // [7..7] High-Speed Operation Enable volatile uint16_t CNEN : 1; /* [8..8] CNEN Single End Receiver Enable */ uint16_t : 1; volatile uint16_t SCKE : 1; /* [10..10] USB Clock Enable */ @@ -87,7 +110,7 @@ typedef struct { struct TU_ATTR_PACKED { volatile uint16_t BWAIT : 4; /* [3..0] CPU Bus Access Wait Specification BWAIT waits (BWAIT+2 access cycles) */ - uint16_t : 12; + uint16_t : 12; } BUSWAIT_b; }; @@ -98,8 +121,7 @@ typedef struct { volatile const uint16_t LNST : 2; /* [1..0] USB Data Line Status Monitor */ volatile const uint16_t IDMON : 1; /* [2..2] External ID0 Input Pin Monitor */ uint16_t : 2; - volatile const uint16_t - SOFEA : 1; /* [5..5] SOF Active Monitor While Host Controller Function is Selected. */ + volatile const uint16_t SOFEA : 1; /* [5..5] SOF Active Monitor While Host Controller Function is Selected. */ volatile const uint16_t HTACT : 1; /* [6..6] USB Host Sequencer Status Monitor */ uint16_t : 7; volatile const uint16_t OVCMON : 2; /* [15..14] External USB0_OVRCURA/ USB0_OVRCURB Input Pin Monitor */ @@ -111,7 +133,7 @@ typedef struct { struct TU_ATTR_PACKED { volatile const uint16_t PLLLOCK : 1; /* [0..0] PLL Lock Flag */ - uint16_t : 15; + uint16_t : 15; } PLLSTA_b; }; @@ -139,7 +161,7 @@ typedef struct { struct TU_ATTR_PACKED { volatile uint16_t UTST : 4; /* [3..0] Test Mode */ - uint16_t : 12; + uint16_t : 12; } TESTMODE_b; }; volatile const uint16_t RESERVED1; @@ -295,7 +317,7 @@ typedef struct { volatile uint16_t INTENB0; /* (@ 0x00000030) Interrupt Enable Register 0 */ struct TU_ATTR_PACKED { - uint16_t : 8; + uint16_t : 8; volatile uint16_t BRDYE : 1; /* [8..8] Buffer Ready Interrupt Enable */ volatile uint16_t NRDYE : 1; /* [9..9] Buffer Not Ready Response Interrupt Enable */ volatile uint16_t BEMPE : 1; /* [10..10] Buffer Empty Interrupt Enable */ @@ -316,7 +338,10 @@ typedef struct { volatile uint16_t SACKE : 1; /* [4..4] Setup Transaction Normal Response Interrupt Enable */ volatile uint16_t SIGNE : 1; /* [5..5] Setup Transaction Error Interrupt Enable */ volatile uint16_t EOFERRE : 1; /* [6..6] EOF Error Detection Interrupt Enable */ - uint16_t : 4; + uint16_t : 1; + volatile uint16_t LPMENDE : 1; /*!< [8..8] LPM Transaction End Interrupt Enable */ + volatile uint16_t L1RSMENDE : 1; /*!< [9..9] L1 Resume End Interrupt Enable */ + uint16_t : 1; volatile uint16_t ATTCHE : 1; /* [11..11] Connection Detection Interrupt Enable */ volatile uint16_t DTCHE : 1; /* [12..12] Disconnection Detection Interrupt Enable */ uint16_t : 1; @@ -340,7 +365,7 @@ typedef struct { volatile uint16_t PIPE7BRDYE : 1; /* [7..7] BRDY Interrupt Enable for PIPE */ volatile uint16_t PIPE8BRDYE : 1; /* [8..8] BRDY Interrupt Enable for PIPE */ volatile uint16_t PIPE9BRDYE : 1; /* [9..9] BRDY Interrupt Enable for PIPE */ - uint16_t : 6; + uint16_t : 6; } BRDYENB_b; }; @@ -358,7 +383,7 @@ typedef struct { volatile uint16_t PIPE7NRDYE : 1; /* [7..7] NRDY Interrupt Enable for PIPE */ volatile uint16_t PIPE8NRDYE : 1; /* [8..8] NRDY Interrupt Enable for PIPE */ volatile uint16_t PIPE9NRDYE : 1; /* [9..9] NRDY Interrupt Enable for PIPE */ - uint16_t : 6; + uint16_t : 6; } NRDYENB_b; }; @@ -376,7 +401,7 @@ typedef struct { volatile uint16_t PIPE7BEMPE : 1; /* [7..7] BEMP Interrupt Enable for PIPE */ volatile uint16_t PIPE8BEMPE : 1; /* [8..8] BEMP Interrupt Enable for PIPE */ volatile uint16_t PIPE9BEMPE : 1; /* [9..9] BEMP Interrupt Enable for PIPE */ - uint16_t : 6; + uint16_t : 6; } BEMPENB_b; }; @@ -390,7 +415,7 @@ typedef struct { volatile uint16_t BRDYM : 1; /* [6..6] BRDY Interrupt Status Clear Timing */ uint16_t : 1; volatile uint16_t TRNENSEL : 1; /* [8..8] Transaction-Enabled Time Select */ - uint16_t : 7; + uint16_t : 7; } SOFCFG_b; }; @@ -467,7 +492,7 @@ typedef struct { volatile uint16_t PIPE7BRDY : 1; /* [7..7] BRDY Interrupt Status for PIPE */ volatile uint16_t PIPE8BRDY : 1; /* [8..8] BRDY Interrupt Status for PIPE */ volatile uint16_t PIPE9BRDY : 1; /* [9..9] BRDY Interrupt Status for PIPE */ - uint16_t : 6; + uint16_t : 6; } BRDYSTS_b; }; @@ -485,7 +510,7 @@ typedef struct { volatile uint16_t PIPE7NRDY : 1; /* [7..7] NRDY Interrupt Status for PIPE */ volatile uint16_t PIPE8NRDY : 1; /* [8..8] NRDY Interrupt Status for PIPE */ volatile uint16_t PIPE9NRDY : 1; /* [9..9] NRDY Interrupt Status for PIPE */ - uint16_t : 6; + uint16_t : 6; } NRDYSTS_b; }; @@ -503,7 +528,7 @@ typedef struct { volatile uint16_t PIPE7BEMP : 1; /* [7..7] BEMP Interrupt Status for PIPE */ volatile uint16_t PIPE8BEMP : 1; /* [8..8] BEMP Interrupt Status for PIPE */ volatile uint16_t PIPE9BEMP : 1; /* [9..9] BEMP Interrupt Status for PIPE */ - uint16_t : 6; + uint16_t : 6; } BEMPSTS_b; }; @@ -609,7 +634,8 @@ typedef struct { volatile uint16_t SQCLR : 1; /* [8..8] Sequence Toggle Bit Clear */ uint16_t : 2; volatile uint16_t SUREQCLR : 1; /* [11..11] SUREQ Bit Clear */ - uint16_t : 2; + volatile uint16_t CSSTS : 1; /* [12..12] Split Transaction COMPLETE SPLIT(CSPLIT) Status */ + volatile uint16_t CSCLR : 1; /* [13..13] Split Transaction CSPLIT Status Clear */ volatile uint16_t SUREQ : 1; /* [14..14] Setup Token Transmission */ volatile const uint16_t BSTS : 1; /* [15..15] Buffer Status */ } DCPCTR_b; @@ -621,7 +647,7 @@ typedef struct { struct TU_ATTR_PACKED { volatile uint16_t PIPESEL : 4; /* [3..0] Pipe Window Select */ - uint16_t : 12; + uint16_t : 12; } PIPESEL_b; }; volatile const uint16_t RESERVED11; @@ -634,21 +660,31 @@ typedef struct { volatile uint16_t DIR : 1; /* [4..4] Transfer Direction */ uint16_t : 2; volatile uint16_t SHTNAK : 1; /* [7..7] Pipe Disabled at End of Transfer */ - uint16_t : 1; + volatile uint16_t CNTMD : 1; /* [8..8] Continuous Transfer Mode */ volatile uint16_t DBLB : 1; /* [9..9] Double Buffer Mode */ volatile uint16_t BFRE : 1; /* [10..10] BRDY Interrupt Operation Specification */ uint16_t : 3; volatile uint16_t TYPE : 2; /* [15..14] Transfer Type */ } PIPECFG_b; }; - volatile const uint16_t RESERVED12; + + union { + volatile uint16_t PIPEBUF; /*!< (@ 0x0000006A) Pipe Buffer Register */ + + struct { + volatile uint16_t BUFNMB : 8; // [7..0] Buffer NumberThese bits specify the FIFO buffer number of the selected pipe (04h to 87h) + uint16_t : 2; + volatile uint16_t BUFSIZE : 5; /*!< [14..10] Buffer Size 00h: 64 bytes 01h: 128 bytes : 1Fh: 2 Kbytes */ + uint16_t : 1; + } PIPEBUF_b; + }; union { volatile uint16_t PIPEMAXP; /* (@ 0x0000006C) Pipe Maximum Packet Size Register */ struct TU_ATTR_PACKED { - volatile uint16_t MXPS : 9; /* [8..0] Maximum Packet Size */ - uint16_t : 3; + volatile uint16_t MXPS : 11; /* [10..0] Maximum Packet Size */ + uint16_t : 1; volatile uint16_t DEVSEL : 4; /* [15..12] Device Select */ } PIPEMAXP_b; }; @@ -694,11 +730,9 @@ typedef struct { struct TU_ATTR_PACKED { volatile uint16_t RPDME0 : 1; /* [0..0] D- Pin Pull-Down Control */ volatile uint16_t IDPSRCE0 : 1; /* [1..1] D+ Pin IDPSRC Output Control */ - volatile uint16_t - IDMSINKE0 : 1; /* [2..2] D- Pin 0.6 V Input Detection (Comparator and Sink) Control */ + volatile uint16_t IDMSINKE0 : 1; /* [2..2] D- Pin 0.6 V Input Detection (Comparator and Sink) Control */ volatile uint16_t VDPSRCE0 : 1; /* [3..3] D+ Pin VDPSRC (0.6 V) Output Control */ - volatile uint16_t - IDPSINKE0 : 1; /* [4..4] D+ Pin 0.6 V Input Detection (Comparator and Sink) Control */ + volatile uint16_t IDPSINKE0 : 1; /* [4..4] D+ Pin 0.6 V Input Detection (Comparator and Sink) Control */ volatile uint16_t VDMSRCE0 : 1; /* [5..5] D- Pin VDMSRC (0.6 V) Output Control */ uint16_t : 1; volatile uint16_t BATCHGE0 : 1; /* [7..7] BC (Battery Charger) Function Ch0 General Enable Control */ @@ -715,7 +749,7 @@ typedef struct { struct TU_ATTR_PACKED { volatile uint16_t UCKSELC : 1; /* [0..0] USB Clock Selection */ - uint16_t : 15; + uint16_t : 15; } UCKSEL_b; }; volatile const uint16_t RESERVED18; @@ -737,11 +771,11 @@ typedef struct { volatile uint16_t DEVADD[10]; /* (@ 0x000000D0) Device Address Configuration Register */ struct TU_ATTR_PACKED { - uint16_t : 6; + uint16_t : 6; volatile uint16_t USBSPD : 2; /* [7..6] Transfer Speed of Communication Target Device */ volatile uint16_t HUBPORT : 3; /* [10..8] Communication Target Connecting Hub Port */ volatile uint16_t UPPHUB : 4; /* [14..11] Communication Target Connecting Hub Register */ - uint16_t : 1; + uint16_t : 1; } DEVADD_b[10]; }; volatile const uint32_t RESERVED21[3]; @@ -754,7 +788,7 @@ typedef struct { volatile uint32_t SLEWR01 : 1; /* [1..1] Receiver Cross Point Adjustment 01 */ volatile uint32_t SLEWF00 : 1; /* [2..2] Receiver Cross Point Adjustment 00 */ volatile uint32_t SLEWF01 : 1; /* [3..3] Receiver Cross Point Adjustment 01 */ - uint32_t : 28; + uint32_t : 28; } PHYSLEW_b; }; volatile const uint32_t RESERVED22[3]; @@ -763,9 +797,9 @@ typedef struct { volatile uint16_t LPCTRL; /* (@ 0x00000100) Low Power Control Register */ struct TU_ATTR_PACKED { - uint16_t : 7; + uint16_t : 7; volatile uint16_t HWUPM : 1; /* [7..7] Resume Return Mode Setting */ - uint16_t : 8; + uint16_t : 8; } LPCTRL_b; }; @@ -773,9 +807,9 @@ typedef struct { volatile uint16_t LPSTS; /* (@ 0x00000102) Low Power Status Register */ struct TU_ATTR_PACKED { - uint16_t : 14; + uint16_t : 14; volatile uint16_t SUSPENDM : 1; /* [14..14] UTMI SuspendM Control */ - uint16_t : 1; + uint16_t : 1; } LPSTS_b; }; volatile const uint32_t RESERVED23[15]; @@ -793,7 +827,7 @@ typedef struct { uint16_t : 2; volatile const uint16_t CHGDETSTS : 1; /* [8..8] CHGDET Status */ volatile const uint16_t PDDETSTS : 1; /* [9..9] PDDET Status */ - uint16_t : 6; + uint16_t : 6; } BCCTRL_b; }; volatile const uint16_t RESERVED24; @@ -809,7 +843,7 @@ typedef struct { volatile uint16_t HIRDTHR : 4; /* [11..8] L1 Response Negotiation Threshold Value */ uint16_t : 2; volatile uint16_t L1EXTMD : 1; /* [14..14] PHY Control Mode at L1 Return */ - uint16_t : 1; + uint16_t : 1; } PL1CTRL1_b; }; @@ -817,10 +851,10 @@ typedef struct { volatile uint16_t PL1CTRL2; /* (@ 0x00000146) Function L1 Control Register 2 */ struct TU_ATTR_PACKED { - uint16_t : 8; + uint16_t : 8; volatile uint16_t HIRDMON : 4; /* [11..8] HIRD Value Monitor */ volatile uint16_t RWEMON : 1; /* [12..12] RWE Value Monitor */ - uint16_t : 3; + uint16_t : 3; } PL1CTRL2_b; }; @@ -830,7 +864,7 @@ typedef struct { struct TU_ATTR_PACKED { volatile uint16_t L1REQ : 1; /* [0..0] L1 Transition Request */ volatile const uint16_t L1STATUS : 2; /* [2..1] L1 Request Completion Status */ - uint16_t : 13; + uint16_t : 13; } HL1CTRL1_b; }; @@ -846,18 +880,48 @@ typedef struct { volatile uint16_t BESL : 1; /* [15..15] BESL & Alternate HIRD */ } HL1CTRL2_b; }; - volatile const uint32_t RESERVED25[5]; + + volatile uint32_t RESERVED25_1; + + union { + volatile uint16_t PHYTRIM1; /*!< (@ 0x00000150) PHY Timing Register 1 */ + + struct { + volatile uint16_t DRISE : 2; /*!< [1..0] FS/LS Rising-Edge Output Waveform Adjustment Function */ + volatile uint16_t DFALL : 2; /*!< [3..2] FS/LS Falling-Edge Output Waveform Adjustment Function */ + uint16_t : 3; + volatile uint16_t PCOMPENB : 1; /*!< [7..7] PVDD Start-up Detection */ + volatile uint16_t HSIUP : 4; /*!< [11..8] HS Output Level Setting */ + volatile uint16_t IMPOFFSET : 3; /*!< [14..12] terminating resistance offset value setting.Offset value for adjusting the terminating resistance. */ + uint16_t : 1; + } PHYTRIM1_b; + }; + + union { + volatile uint16_t PHYTRIM2; /*!< (@ 0x00000152) PHY Timing Register 2 */ + + struct { + volatile uint16_t SQU : 4; /*!< [3..0] Squelch Detection Level */ + uint16_t : 3; + volatile uint16_t HSRXENMO : 1; /*!< [7..7] HS Receive Enable Control Mode */ + volatile uint16_t PDR : 2; /*!< [9..8] HS Output Adjustment Function */ + uint16_t : 2; + volatile uint16_t DIS : 3; /*!< [14..12] Disconnect Detection Level */ + uint16_t : 1; + } PHYTRIM2_b; + }; + volatile uint32_t RESERVED25_2[3]; union { volatile const uint32_t DPUSR0R; /* (@ 0x00000160) Deep Standby USB Transceiver Control/Pin Monitor Register */ struct TU_ATTR_PACKED { - uint32_t : 20; + uint32_t : 20; volatile const uint32_t DOVCAHM : 1; /* [20..20] OVRCURA InputIndicates OVRCURA input signal on the HS side of USB port. */ volatile const uint32_t DOVCBHM : 1; /* [21..21] OVRCURB InputIndicates OVRCURB input signal on the HS side of USB port. */ uint32_t : 1; volatile const uint32_t DVBSTSHM : 1; /* [23..23] VBUS InputIndicates VBUS input signal on the HS side of USB port. */ - uint32_t : 8; + uint32_t : 8; } DPUSR0R_b; }; @@ -865,7 +929,7 @@ typedef struct { volatile uint32_t DPUSR1R; /* (@ 0x00000164) Deep Standby USB Suspend/Resume Interrupt Register */ struct TU_ATTR_PACKED { - uint32_t : 4; + uint32_t : 4; volatile uint32_t DOVCAHE : 1; /* [4..4] OVRCURA Interrupt Enable Clear */ volatile uint32_t DOVCBHE : 1; /* [5..5] OVRCURB Interrupt Enable Clear */ uint32_t : 1; @@ -875,7 +939,7 @@ typedef struct { volatile const uint32_t DOVCBH : 1; /* [21..21] Indication of Return from OVRCURB Interrupt Source */ uint32_t : 1; volatile const uint32_t DVBSTSH : 1; /* [23..23] Indication of Return from VBUS Interrupt Source */ - uint32_t : 8; + uint32_t : 8; } DPUSR1R_b; }; @@ -891,7 +955,7 @@ typedef struct { uint16_t : 2; volatile uint16_t DPINTE : 1; /* [8..8] DP Interrupt Enable Clear */ volatile uint16_t DMINTE : 1; /* [9..9] DM Interrupt Enable Clear */ - uint16_t : 6; + uint16_t : 6; } DPUSR2R_b; }; @@ -901,7 +965,7 @@ typedef struct { struct TU_ATTR_PACKED { volatile uint16_t FIXPHY : 1; /* [0..0] USB Transceiver Control Fix */ volatile uint16_t FIXPHYPD : 1; /* [1..1] USB Transceiver Control Fix for PLL */ - uint16_t : 14; + uint16_t : 14; } DPUSRCR_b; }; volatile const uint32_t RESERVED26[165]; @@ -924,7 +988,7 @@ typedef struct { volatile const uint32_t DOVCB0 : 1; /* [21..21] USB OVRCURB InputIndicates the OVRCURB input signal of the USB. */ uint32_t : 1; volatile const uint32_t DVBSTS0 : 1; /* [23..23] USB VBUS InputIndicates the VBUS input signal of the USB. */ - uint32_t : 8; + uint32_t : 8; } DPUSR0R_FS_b; }; @@ -947,10 +1011,10 @@ typedef struct { volatile const uint32_t DOVRCRB0 : 1; /* [21..21] USB OVRCURB Interrupt Source Recovery */ uint32_t : 1; volatile const uint32_t DVBINT0 : 1; /* [23..23] USB VBUS Interrupt Source Recovery */ - uint32_t : 8; + uint32_t : 8; } DPUSR1R_FS_b; }; -} RUSB2_REG_t; /* Size = 1032 (0x408) */ +} rusb2_reg_t; /* Size = 1032 (0x408) */ TU_ATTR_PACKED_END /* End of definition of packed structs (used by the CCRX toolchain) */ TU_ATTR_BIT_FIELD_ORDER_END @@ -970,13 +1034,15 @@ TU_ATTR_BIT_FIELD_ORDER_END #define RUSB2_PIPE_TR_N_TRNCNT_Pos (0UL) /* TRNCNT (Bit 0) */ #define RUSB2_PIPE_TR_N_TRNCNT_Msk (0xffffUL) /* TRNCNT (Bitfield-Mask: 0xffff) */ -// LINK_REG +// Core Registers // SYSCFG #define RUSB2_SYSCFG_SCKE_Pos (10UL) /* SCKE (Bit 10) */ #define RUSB2_SYSCFG_SCKE_Msk (0x400UL) /* SCKE (Bitfield-Mask: 0x01) */ #define RUSB2_SYSCFG_CNEN_Pos (8UL) /* CNEN (Bit 8) */ #define RUSB2_SYSCFG_CNEN_Msk (0x100UL) /* CNEN (Bitfield-Mask: 0x01) */ +#define RUSB2_SYSCFG_HSE_Pos (7UL) /*!< HSE (Bit 7) */ +#define RUSB2_SYSCFG_HSE_Msk (0x80UL) /*!< HSE (Bitfield-Mask: 0x01) */ #define RUSB2_SYSCFG_DCFM_Pos (6UL) /* DCFM (Bit 6) */ #define RUSB2_SYSCFG_DCFM_Msk (0x40UL) /* DCFM (Bitfield-Mask: 0x01) */ #define RUSB2_SYSCFG_DRPD_Pos (5UL) /* DRPD (Bit 5) */ @@ -1135,6 +1201,10 @@ TU_ATTR_BIT_FIELD_ORDER_END #define RUSB2_INTENB1_DTCHE_Msk (0x1000UL) /* DTCHE (Bitfield-Mask: 0x01) */ #define RUSB2_INTENB1_ATTCHE_Pos (11UL) /* ATTCHE (Bit 11) */ #define RUSB2_INTENB1_ATTCHE_Msk (0x800UL) /* ATTCHE (Bitfield-Mask: 0x01) */ +#define RUSB2_INTENB1_L1RSMENDE_Pos (9UL) /*!< L1RSMENDE (Bit 9) */ +#define RUSB2_INTENB1_L1RSMENDE_Msk (0x200UL) /*!< L1RSMENDE (Bitfield-Mask: 0x01) */ +#define RUSB2_INTENB1_LPMENDE_Pos (8UL) /*!< LPMENDE (Bit 8) */ +#define RUSB2_INTENB1_LPMENDE_Msk (0x100UL) /*!< LPMENDE (Bitfield-Mask: 0x01) */ #define RUSB2_INTENB1_EOFERRE_Pos (6UL) /* EOFERRE (Bit 6) */ #define RUSB2_INTENB1_EOFERRE_Msk (0x40UL) /* EOFERRE (Bitfield-Mask: 0x01) */ #define RUSB2_INTENB1_SIGNE_Pos (5UL) /* SIGNE (Bit 5) */ @@ -1299,6 +1369,10 @@ TU_ATTR_BIT_FIELD_ORDER_END #define RUSB2_DCPCTR_BSTS_Msk (0x8000UL) /* BSTS (Bitfield-Mask: 0x01) */ #define RUSB2_DCPCTR_SUREQ_Pos (14UL) /* SUREQ (Bit 14) */ #define RUSB2_DCPCTR_SUREQ_Msk (0x4000UL) /* SUREQ (Bitfield-Mask: 0x01) */ +#define R_USB_HS0_DCPCTR_CSCLR_Pos (13UL) /*!< CSCLR (Bit 13) */ +#define RUSB2_DCPCTR_CSCLR_Msk (0x2000UL) /*!< CSCLR (Bitfield-Mask: 0x01) */ +#define RUSB2_DCPCTR_CSSTS_Pos (12UL) /*!< CSSTS (Bit 12) */ +#define RUSB2_DCPCTR_CSSTS_Msk (0x1000UL) /*!< CSSTS (Bitfield-Mask: 0x01) */ #define RUSB2_DCPCTR_SUREQCLR_Pos (11UL) /* SUREQCLR (Bit 11) */ #define RUSB2_DCPCTR_SUREQCLR_Msk (0x800UL) /* SUREQCLR (Bitfield-Mask: 0x01) */ #define RUSB2_DCPCTR_SQCLR_Pos (8UL) /* SQCLR (Bit 8) */ @@ -1325,6 +1399,8 @@ TU_ATTR_BIT_FIELD_ORDER_END #define RUSB2_PIPECFG_BFRE_Msk (0x400UL) /* BFRE (Bitfield-Mask: 0x01) */ #define RUSB2_PIPECFG_DBLB_Pos (9UL) /* DBLB (Bit 9) */ #define RUSB2_PIPECFG_DBLB_Msk (0x200UL) /* DBLB (Bitfield-Mask: 0x01) */ +#define RUSB2_PIPECFG_CNTMD_Pos (8UL) /*!< CNTMD (Bit 8) */ +#define RUSB2_PIPECFG_CNTMD_Msk (0x100UL) /*!< CNTMD (Bitfield-Mask: 0x01) */ #define RUSB2_PIPECFG_SHTNAK_Pos (7UL) /* SHTNAK (Bit 7) */ #define RUSB2_PIPECFG_SHTNAK_Msk (0x80UL) /* SHTNAK (Bitfield-Mask: 0x01) */ #define RUSB2_PIPECFG_DIR_Pos (4UL) /* DIR (Bit 4) */ @@ -1332,6 +1408,12 @@ TU_ATTR_BIT_FIELD_ORDER_END #define RUSB2_PIPECFG_EPNUM_Pos (0UL) /* EPNUM (Bit 0) */ #define RUSB2_PIPECFG_EPNUM_Msk (0xfUL) /* EPNUM (Bitfield-Mask: 0x0f) */ +// PIPEBUF +#define RUSB2_PIPEBUF_BUFSIZE_Pos (10UL) /*!< BUFSIZE (Bit 10) */ +#define RUSB2_PIPEBUF_BUFSIZE_Msk (0x7c00UL) /*!< BUFSIZE (Bitfield-Mask: 0x1f) */ +#define RUSB2_PIPEBUF_BUFNMB_Pos (0UL) /*!< BUFNMB (Bit 0) */ +#define RUSB2_PIPEBUF_BUFNMB_Msk (0xffUL) /*!< BUFNMB (Bitfield-Mask: 0xff) */ + // PIPEMAXP #define RUSB2_PIPEMAXP_DEVSEL_Pos (12UL) /* DEVSEL (Bit 12) */ #define RUSB2_PIPEMAXP_DEVSEL_Msk (0xf000UL) /* DEVSEL (Bitfield-Mask: 0x0f) */ @@ -1478,6 +1560,28 @@ TU_ATTR_BIT_FIELD_ORDER_END #define RUSB2_HL1CTRL2_L1ADDR_Pos (0UL) /* L1ADDR (Bit 0) */ #define RUSB2_HL1CTRL2_L1ADDR_Msk (0xfUL) /* L1ADDR (Bitfield-Mask: 0x0f) */ +// PHYTRIM1 +#define RUSB2_PHYTRIM1_IMPOFFSET_Pos (12UL) /*!< IMPOFFSET (Bit 12) */ +#define RUSB2_PHYTRIM1_IMPOFFSET_Msk (0x7000UL) /*!< IMPOFFSET (Bitfield-Mask: 0x07) */ +#define RUSB2_PHYTRIM1_HSIUP_Pos (8UL) /*!< HSIUP (Bit 8) */ +#define RUSB2_PHYTRIM1_HSIUP_Msk (0xf00UL) /*!< HSIUP (Bitfield-Mask: 0x0f) */ +#define RUSB2_PHYTRIM1_PCOMPENB_Pos (7UL) /*!< PCOMPENB (Bit 7) */ +#define RUSB2_PHYTRIM1_PCOMPENB_Msk (0x80UL) /*!< PCOMPENB (Bitfield-Mask: 0x01) */ +#define RUSB2_PHYTRIM1_DFALL_Pos (2UL) /*!< DFALL (Bit 2) */ +#define RUSB2_PHYTRIM1_DFALL_Msk (0xcUL) /*!< DFALL (Bitfield-Mask: 0x03) */ +#define RUSB2_PHYTRIM1_DRISE_Pos (0UL) /*!< DRISE (Bit 0) */ +#define RUSB2_PHYTRIM1_DRISE_Msk (0x3UL) /*!< DRISE (Bitfield-Mask: 0x03) */ + +// PHYTRIM2 +#define RUSB2_PHYTRIM2_DIS_Pos (12UL) /*!< DIS (Bit 12) */ +#define RUSB2_PHYTRIM2_DIS_Msk (0x7000UL) /*!< DIS (Bitfield-Mask: 0x07) */ +#define RUSB2_PHYTRIM2_PDR_Pos (8UL) /*!< PDR (Bit 8) */ +#define RUSB2_PHYTRIM2_PDR_Msk (0x300UL) /*!< PDR (Bitfield-Mask: 0x03) */ +#define RUSB2_PHYTRIM2_HSRXENMO_Pos (7UL) /*!< HSRXENMO (Bit 7) */ +#define RUSB2_PHYTRIM2_HSRXENMO_Msk (0x80UL) /*!< HSRXENMO (Bitfield-Mask: 0x01) */ +#define RUSB2_PHYTRIM2_SQU_Pos (0UL) /*!< SQU (Bit 0) */ +#define RUSB2_PHYTRIM2_SQU_Msk (0xfUL) /*!< SQU (Bitfield-Mask: 0x0f) */ + // DPUSR0R #define RUSB2_DPUSR0R_DVBSTSHM_Pos (23UL) /* DVBSTSHM (Bit 23) */ #define RUSB2_DPUSR0R_DVBSTSHM_Msk (0x800000UL) /* DVBSTSHM (Bitfield-Mask: 0x01) */ @@ -1572,6 +1676,7 @@ TU_ATTR_BIT_FIELD_ORDER_END #define RUSB2_DVSTCTR0_RHST_LS (1U << RUSB2_DVSTCTR0_RHST_Pos) /* Low-speed connection */ #define RUSB2_DVSTCTR0_RHST_FS (2U << RUSB2_DVSTCTR0_RHST_Pos) /* Full-speed connection */ +#define RUSB2_DVSTCTR0_RHST_HS (3U << RUSB2_DVSTCTR0_RHST_Pos) /* Full-speed connection */ #define RUSB2_DEVADD_USBSPD_LS (1U << RUSB2_DEVADD_USBSPD_Pos) /* Target Device Low-speed */ #define RUSB2_DEVADD_USBSPD_FS (2U << RUSB2_DEVADD_USBSPD_Pos) /* Target Device Full-speed */ @@ -1581,6 +1686,7 @@ TU_ATTR_BIT_FIELD_ORDER_END #define RUSB2_FIFOSEL_BIGEND (1U << RUSB2_CFIFOSEL_BIGEND_Pos) /* FIFO Big Endian */ #define RUSB2_FIFOSEL_MBW_8BIT (0U << RUSB2_CFIFOSEL_MBW_Pos) /* 8-bit width */ #define RUSB2_FIFOSEL_MBW_16BIT (1U << RUSB2_CFIFOSEL_MBW_Pos) /* 16-bit width */ +#define RUSB2_FIFOSEL_MBW_32BIT (2U << RUSB2_CFIFOSEL_MBW_Pos) /* 32-bit width */ #define RUSB2_INTSTS0_CTSQ_CTRL_RDATA (1U << RUSB2_INTSTS0_CTSQ_Pos) @@ -1600,69 +1706,72 @@ TU_ATTR_BIT_FIELD_ORDER_END //--------------------------------------------------------------------+ TU_VERIFY_STATIC(sizeof(RUSB2_PIPE_TR_t) == 4, "incorrect size"); -TU_VERIFY_STATIC(sizeof(RUSB2_REG_t) == 1032, "incorrect size"); +TU_VERIFY_STATIC(sizeof(rusb2_reg_t) == 1032, "incorrect size"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, SYSCFG ) == 0x00000000, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, BUSWAIT ) == 0x00000002, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, SYSSTS0 ) == 0x00000004, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, PLLSTA ) == 0x00000006, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, DVSTCTR0 ) == 0x00000008, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, TESTMODE ) == 0x0000000C, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, CFIFO ) == 0x00000014, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, D0FIFO ) == 0x00000018, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, D1FIFO ) == 0x0000001C, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, CFIFOSEL ) == 0x00000020, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, CFIFOCTR ) == 0x00000022, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, D0FIFOSEL ) == 0x00000028, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, D0FIFOCTR ) == 0x0000002A, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, D1FIFOSEL ) == 0x0000002C, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, D1FIFOCTR ) == 0x0000002E, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, INTENB0 ) == 0x00000030, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, INTENB1 ) == 0x00000032, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, BRDYENB ) == 0x00000036, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, NRDYENB ) == 0x00000038, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, BEMPENB ) == 0x0000003A, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, SOFCFG ) == 0x0000003C, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, PHYSET ) == 0x0000003E, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, INTSTS0 ) == 0x00000040, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, INTSTS1 ) == 0x00000042, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, BRDYSTS ) == 0x00000046, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, NRDYSTS ) == 0x00000048, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, BEMPSTS ) == 0x0000004A, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, FRMNUM ) == 0x0000004C, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, UFRMNUM ) == 0x0000004E, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, USBADDR ) == 0x00000050, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, USBREQ ) == 0x00000054, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, USBVAL ) == 0x00000056, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, USBINDX ) == 0x00000058, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, USBLENG ) == 0x0000005A, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, DCPCFG ) == 0x0000005C, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, DCPMAXP ) == 0x0000005E, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, DCPCTR ) == 0x00000060, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, PIPESEL ) == 0x00000064, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, PIPECFG ) == 0x00000068, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, PIPEMAXP ) == 0x0000006C, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, PIPEPERI ) == 0x0000006E, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, PIPE_CTR ) == 0x00000070, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, PIPE_TR ) == 0x00000090, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, USBBCCTRL0 ) == 0x000000B0, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, UCKSEL ) == 0x000000C4, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, USBMC ) == 0x000000CC, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, DEVADD ) == 0x000000D0, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, PHYSLEW ) == 0x000000F0, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, LPCTRL ) == 0x00000100, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, LPSTS ) == 0x00000102, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, BCCTRL ) == 0x00000140, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, PL1CTRL1 ) == 0x00000144, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, PL1CTRL2 ) == 0x00000146, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, HL1CTRL1 ) == 0x00000148, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, HL1CTRL2 ) == 0x0000014A, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, DPUSR0R ) == 0x00000160, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, DPUSR1R ) == 0x00000164, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, DPUSR2R ) == 0x00000168, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, DPUSRCR ) == 0x0000016A, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, DPUSR0R_FS ) == 0x00000400, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, DPUSR1R_FS ) == 0x00000404, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, SYSCFG ) == 0x0000, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, BUSWAIT ) == 0x0002, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, SYSSTS0 ) == 0x0004, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, PLLSTA ) == 0x0006, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, DVSTCTR0 ) == 0x0008, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, TESTMODE ) == 0x000C, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, CFIFO ) == 0x0014, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, D0FIFO ) == 0x0018, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, D1FIFO ) == 0x001C, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, CFIFOSEL ) == 0x0020, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, CFIFOCTR ) == 0x0022, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, D0FIFOSEL ) == 0x0028, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, D0FIFOCTR ) == 0x002A, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, D1FIFOSEL ) == 0x002C, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, D1FIFOCTR ) == 0x002E, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, INTENB0 ) == 0x0030, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, INTENB1 ) == 0x0032, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, BRDYENB ) == 0x0036, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, NRDYENB ) == 0x0038, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, BEMPENB ) == 0x003A, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, SOFCFG ) == 0x003C, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, PHYSET ) == 0x003E, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, INTSTS0 ) == 0x0040, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, INTSTS1 ) == 0x0042, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, BRDYSTS ) == 0x0046, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, NRDYSTS ) == 0x0048, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, BEMPSTS ) == 0x004A, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, FRMNUM ) == 0x004C, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, UFRMNUM ) == 0x004E, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, USBADDR ) == 0x0050, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, USBREQ ) == 0x0054, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, USBVAL ) == 0x0056, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, USBINDX ) == 0x0058, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, USBLENG ) == 0x005A, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, DCPCFG ) == 0x005C, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, DCPMAXP ) == 0x005E, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, DCPCTR ) == 0x0060, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, PIPESEL ) == 0x0064, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, PIPECFG ) == 0x0068, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, PIPEBUF ) == 0x006A, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, PIPEMAXP ) == 0x006C, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, PIPEPERI ) == 0x006E, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, PIPE_CTR ) == 0x0070, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, PIPE_TR ) == 0x0090, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, USBBCCTRL0 ) == 0x00B0, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, UCKSEL ) == 0x00C4, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, USBMC ) == 0x00CC, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, DEVADD ) == 0x00D0, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, PHYSLEW ) == 0x00F0, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, LPCTRL ) == 0x0100, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, LPSTS ) == 0x0102, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, BCCTRL ) == 0x0140, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, PL1CTRL1 ) == 0x0144, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, PL1CTRL2 ) == 0x0146, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, HL1CTRL1 ) == 0x0148, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, HL1CTRL2 ) == 0x014A, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, PHYTRIM1 ) == 0x0150, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, PHYTRIM2 ) == 0x0152, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, DPUSR0R ) == 0x0160, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, DPUSR1R ) == 0x0164, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, DPUSR2R ) == 0x0168, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, DPUSRCR ) == 0x016A, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, DPUSR0R_FS ) == 0x0400, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, DPUSR1R_FS ) == 0x0404, "incorrect offset"); #ifdef __cplusplus } |
