diff --git a/.idea/cmake.xml b/.idea/cmake.xml index 864ff615b..519623b71 100644 --- a/.idea/cmake.xml +++ b/.idea/cmake.xml @@ -2,7 +2,6 @@ - @@ -26,27 +25,27 @@ - - - + + + - + + - - - + + \ No newline at end of file diff --git a/.idea/runConfigurations/ra6m5.xml b/.idea/runConfigurations/ra6m5.xml index 02df11610..89f9787a0 100644 --- a/.idea/runConfigurations/ra6m5.xml +++ b/.idea/runConfigurations/ra6m5.xml @@ -1,5 +1,5 @@ - + diff --git a/hw/bsp/ra/boards/ra6m5_ek/ozone/ra6m5.jdebug b/hw/bsp/ra/boards/ra6m5_ek/ozone/ra6m5.jdebug index aebb29162..7b8ee9c95 100644 --- a/hw/bsp/ra/boards/ra6m5_ek/ozone/ra6m5.jdebug +++ b/hw/bsp/ra/boards/ra6m5_ek/ozone/ra6m5.jdebug @@ -20,7 +20,9 @@ void OnProjectLoad (void) { Project.SetTraceSource ("Trace Pins"); Project.SetTracePortWidth (4); - File.Open ("../../../../../../examples/device/cdc_msc/cmake-build-ra6m5/cdc_msc.elf"); + //File.Open ("../../../../../../examples/device/cdc_msc/cmake-build-ra6m5/cdc_msc.elf"); + //File.Open ("../../../../../../examples/dual/cmake-build-ra6m5/host_hid_to_device_cdc/host_hid_to_device_cdc.elf"); + File.Open ("../../../../../../examples/cmake-build-ra6m5/host/cdc_msc_hid/cdc_msc_hid.elf"); } /********************************************************************* * diff --git a/src/portable/renesas/rusb2/dcd_rusb2.c b/src/portable/renesas/rusb2/dcd_rusb2.c index 6fee4edd7..83f0fdc4a 100644 --- a/src/portable/renesas/rusb2/dcd_rusb2.c +++ b/src/portable/renesas/rusb2/dcd_rusb2.c @@ -83,6 +83,18 @@ typedef struct TU_ATTR_PACKED TU_ATTR_PACKED_END // End of definition of packed structs (used by the CCRX toolchain) TU_ATTR_BIT_FIELD_ORDER_END +typedef struct +{ + pipe_state_t pipe[10]; + 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 +//--------------------------------------------------------------------+ + // 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 @@ -96,18 +108,6 @@ enum { PIPE_COUNT = 10, }; -typedef struct -{ - pipe_state_t pipe[10]; - 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 unsigned find_pipe(unsigned xfer) { switch (xfer) { @@ -746,20 +746,17 @@ void dcd_init(uint8_t 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) diff --git a/src/portable/renesas/rusb2/hcd_rusb2.c b/src/portable/renesas/rusb2/hcd_rusb2.c index 656051e2b..a4b534a05 100644 --- a/src/portable/renesas/rusb2/hcd_rusb2.c +++ b/src/portable/renesas/rusb2/hcd_rusb2.c @@ -52,23 +52,12 @@ #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) -#elif defined(__RX__) - #define RUSB2 ((RUSB2_REG_t*) RUSB2_REG_BASE) -#elif (CFG_TUSB_RHPORT1_MODE & OPT_MODE_HOST) - #define RUSB2 ((R_USB_HS0_Type*) R_USB_HS0_BASE) -#else - #define RUSB2 ((R_USB_FS0_Type*) R_USB_FS0_BASE) -#endif - TU_ATTR_PACKED_BEGIN TU_ATTR_BIT_FIELD_ORDER_BEGIN @@ -108,79 +97,97 @@ 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) @@ -205,33 +212,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; @@ -239,40 +246,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; @@ -281,7 +288,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; @@ -291,37 +298,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; + 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 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]; @@ -331,26 +340,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]; @@ -363,19 +374,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; @@ -386,20 +397,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, @@ -411,9 +422,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; @@ -429,19 +440,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, @@ -539,86 +550,88 @@ bool hcd_init(uint8_t rhport) 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; @@ -631,52 +644,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; @@ -690,17 +705,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; @@ -709,13 +727,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; @@ -726,14 +747,15 @@ 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; } bool hcd_edpt_clear_stall(uint8_t dev_addr, uint8_t ep_addr) { - uint16_t volatile *ctr = addr_to_pipectr(dev_addr, ep_addr); + uint8_t rhport = 0; // FIXME change API + uint16_t volatile *ctr = addr_to_pipectr(rhport, dev_addr, ep_addr); TU_ASSERT(ctr); const uint32_t pid = *ctr & 0x3; @@ -756,67 +778,73 @@ bool hcd_edpt_clear_stall(uint8_t dev_addr, uint8_t ep_addr) //--------------------------------------------------------------------+ void hcd_int_handler(uint8_t rhport) { - (void)rhport; + rusb2_reg_t* rusb = RUSB2_REG(rhport); + static unsigned char attach_attempt = 0; + unsigned is0 = rusb->INTSTS0; + unsigned is1 = rusb->INTSTS1; + + /* clear active bits except VALID (don't write 0 to already cleared bits according to the HW manual) */ + 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. */ + rusb->DCPCTR_b.SQSET = 1; + attach_attempt = 0; + 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(rusb->DCPMAXP_b.DEVSEL, tu_edpt_addr(0, TUSB_DIR_OUT), 8, XFER_RESULT_FAILED, true); + if(attach_attempt > 0) { + rusb->DVSTCTR0_b.UACT = 1; + _hcd.need_reset = true; + rusb->INTENB1 = (rusb->INTENB1 & ~RUSB2_INTSTS1_ATTCH_Msk) | RUSB2_INTSTS1_DTCH_Msk; + hcd_event_device_attach(rhport, true); + } + attach_attempt--; + } + + if (is1 & RUSB2_INTSTS1_ATTCH_Msk) { + attach_attempt = 10; + rusb->DVSTCTR0_b.UACT = 1; + _hcd.need_reset = true; + rusb->INTENB1 = (rusb->INTENB1 & ~RUSB2_INTSTS1_ATTCH_Msk) | RUSB2_INTSTS1_DTCH_Msk; + hcd_event_device_attach(rhport, true); + } + + if (is1 & RUSB2_INTSTS1_DTCH_Msk) { + rusb->DVSTCTR0_b.UACT = 0; + if (rusb->DCPCTR_b.SUREQ) { + rusb->DCPCTR_b.SUREQCLR = 1; + } + 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 = 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 - static unsigned char attach_attempt = 0; - 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; - - if (is1 & RUSB2_INTSTS1_SACK_Msk) { - /* Set DATA1 in advance for the next transfer. */ - RUSB2->DCPCTR_b.SQSET = 1; - attach_attempt = 0; - hcd_event_xfer_complete(RUSB2->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); - if(attach_attempt > 0) { - RUSB2->DVSTCTR0_b.UACT = 1; - _hcd.need_reset = true; - RUSB2->INTENB1 = (RUSB2->INTENB1 & ~RUSB2_INTSTS1_ATTCH_Msk) | RUSB2_INTSTS1_DTCH_Msk; - hcd_event_device_attach(rhport, true); - } - attach_attempt--; - } - if (is1 & RUSB2_INTSTS1_ATTCH_Msk) { - attach_attempt = 10; - RUSB2->DVSTCTR0_b.UACT = 1; - _hcd.need_reset = true; - RUSB2->INTENB1 = (RUSB2->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; - } - RUSB2->INTENB1 = (RUSB2->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; - if (s & 1) { - process_pipe0_bemp(rhport); - } - } 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]; @@ -828,10 +856,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];