30#if CFG_TUH_ENABLED && defined(TUP_USBIP_RUSB2)
35#if TU_CHECK_MCU(OPT_MCU_RX63X, OPT_MCU_RX65X, OPT_MCU_RX72N)
37#elif TU_CHECK_MCU(OPT_MCU_RAXXX)
40 #error "Unsupported MCU"
43#define TU_RUSB2_HCD_DBG 2
53TU_ATTR_BIT_FIELD_ORDER_BEGIN
76TU_ATTR_BIT_FIELD_ORDER_END
101 const uint8_t pipe_idx_arr[4][2] = {
109 const uint8_t idx_first = pipe_idx_arr[xfer_type][0];
110 const uint8_t idx_last = pipe_idx_arr[xfer_type][1];
112 for (
int i = idx_last; i >= idx_first; i--) {
122 return (
volatile uint16_t*)&(rusb->
PIPE_CTR[num - 1]);
124 return (
volatile uint16_t*)&(rusb->
DCPCTR);
131 if ((1 <= num) && (num <= 5)) {
172 uintptr_t addr = (uintptr_t)buf;
174 reg->
u16 = *(
const uint16_t *)addr;
179 reg->
u8 = *(
const uint8_t *)addr;
186 uint8_t *p = (uint8_t*)buf;
187 volatile uint8_t *reg = (
volatile uint8_t*)fifo;
188 while (len--) *p++ = *reg;
198 const unsigned len = TU_MIN(TU_MIN(rem, mps), vld);
199 void *buf = pipe->
buf;
201 rusb->
DCPCTR = RUSB2_PIPE_CTR_PID_NAK;
203 pipe->
buf = (uint8_t*)buf + len;
206 rusb->
CFIFOCTR = RUSB2_CFIFOCTR_BCLR_Msk;
209 if ((len < mps) || (rem == len)) {
213 rusb->
DCPCTR = RUSB2_PIPE_CTR_PID_BUF;
226 const unsigned len = TU_MIN(mps, rem);
227 void *buf = pipe->
buf;
230 pipe->
buf = (uint8_t*)buf + len;
233 rusb->
CFIFOCTR = RUSB2_CFIFOCTR_BVAL_Msk;
244 rusb->
D0FIFOSEL = num | RUSB2_FIFOSEL_MBW_8BIT;
248 const unsigned len = TU_MIN(TU_MIN(rem, mps), vld);
249 void *buf = pipe->
buf;
252 pipe->
buf = (uint8_t*)buf + len;
255 rusb->
D0FIFOCTR = RUSB2_D0FIFOCTR_BCLR_Msk;
260 if ((len < mps) || (rem == len)) {
277 rusb->
D0FIFOSEL = num | RUSB2_FIFOSEL_MBW_16BIT | (TU_BYTE_ORDER == TU_BIG_ENDIAN ? RUSB2_FIFOSEL_BIGEND : 0);
280 const unsigned len = TU_MIN(rem, mps);
281 void *buf = pipe->
buf;
284 pipe->
buf = (uint8_t*)buf + len;
287 rusb->
D0FIFOCTR = RUSB2_D0FIFOCTR_BVAL_Msk;
304 rusb->
CFIFOSEL = RUSB2_FIFOSEL_MBW_8BIT;
305 while (rusb->
CFIFOSEL & RUSB2_CFIFOSEL_ISEL_WRITE) ;
307 rusb->
CFIFOSEL = RUSB2_CFIFOSEL_ISEL_WRITE | RUSB2_FIFOSEL_MBW_16BIT |
308 (TU_BYTE_ORDER == TU_BIG_ENDIAN ? RUSB2_FIFOSEL_BIGEND : 0);
309 while (!(rusb->
CFIFOSEL & RUSB2_CFIFOSEL_ISEL_WRITE)) ;
325 rusb->
CFIFOCTR = RUSB2_CFIFOCTR_BVAL_Msk;
328 TU_ASSERT(RUSB2_PIPE_CTR_PID_NAK == rusb->
DCPCTR_b.PID);
333 rusb->
DCPCTR = RUSB2_PIPE_CTR_PID_BUF;
357 rusb->
D0FIFOCTR = RUSB2_D0FIFOCTR_BVAL_Msk;
366 if (*ctr & 0x3) *ctr = RUSB2_PIPE_CTR_PID_NAK;
368 pt->TRN = (buflen + mps - 1) / mps;
371 *ctr = RUSB2_PIPE_CTR_PID_BUF;
404 TU_LOG(TU_RUSB2_HCD_DBG,
"NRDY %d %x\r\n", num, *ctr);
405 switch (*ctr & RUSB2_PIPE_CTR_PID_Msk) {
437 TU_LOG(TU_RUSB2_HCD_DBG,
"C %d %d\r\n", num, pipe->
length - pipe->
remaining);
450 pswi = get_psw() & 0x010000;
453 pswi = __builtin_rx_mvfc(0) & 0x010000;
454 __builtin_rx_clrpsw(
'I');
462 set_psw(get_psw() | pswi);
464 __builtin_rx_mvtc(0, __builtin_rx_mvfc(0) | pswi);
474#ifdef RUSB2_SUPPORT_HIGHSPEED
475 if (rusb2_is_highspeed_rhport(rhport) ) {
479 R_BSP_SoftwareDelay((uint32_t) 1, BSP_DELAY_UNITS_MILLISECONDS);
494 for (
volatile int i = 0; i < 30000; ++i );
506 for (
volatile int i = 0; i < 30000; ++i ) {}
518 rusb->
DCPCFG = RUSB2_PIPECFG_SHTNAK_Msk;
520 rusb->
INTENB0 = RUSB2_INTSTS0_BRDY_Msk | RUSB2_INTSTS0_NRDY_Msk | RUSB2_INTSTS0_BEMP_Msk;
521 rusb->
INTENB1 = RUSB2_INTSTS1_SACK_Msk | RUSB2_INTSTS1_SIGN_Msk | RUSB2_INTSTS1_ATTCH_Msk | RUSB2_INTSTS1_DTCH_Msk;
552 return rusb->
INTSTS1_b.ATTCH ? true :
false;
557 rusb->
DCPCTR = RUSB2_PIPE_CTR_PID_NAK;
569 for (
volatile int i = 0; i < 2400000; ++i) {}
592 uint16_t
volatile *ctr;
600 for (
int i = 0; i < 2 * 15; ++i, ++ep) {
604 ctr = (uint16_t
volatile*)&rusb->
PIPE_CTR[num - 1];
628 TU_ASSERT(0 == rusb->
DCPCTR_b.SUREQ);
630 rusb->
DCPCTR = RUSB2_PIPE_CTR_PID_NAK;
641 uint8_t
const bmRequesttype = setup_packet[0];
644 uint16_t
const* p = (uint16_t
const*)(uintptr_t)&setup_packet[0];
645 rusb->
USBREQ = tu_htole16(p[0]);
664 rusb->
DCPCTR = RUSB2_PIPE_CTR_PID_NAK;
667 uint16_t
volatile *devadd = (uint16_t
volatile *)(uintptr_t) &rusb->
DEVADD[0];
683 if (!num)
return false;
695 *ctr = RUSB2_PIPE_CTR_ACLRM_Msk | RUSB2_PIPE_CTR_SQCLR_Msk;
698 unsigned cfg = ((1 ^ dir_in) << 4) | epn;
700 cfg |= RUSB2_PIPECFG_TYPE_BULK | RUSB2_PIPECFG_SHTNAK_Msk | RUSB2_PIPECFG_DBLB_Msk;
702 cfg |= RUSB2_PIPECFG_TYPE_INT;
704 cfg |= RUSB2_PIPECFG_TYPE_ISO | RUSB2_PIPECFG_DBLB_Msk;
708 rusb->
BRDYSTS = 0x3FFu ^ TU_BIT(num);
713 *ctr = RUSB2_PIPE_CTR_PID_BUF;
725 TU_LOG(TU_RUSB2_HCD_DBG,
"X %d %x %u\r\n",
dev_addr, ep_addr, buflen);
743 const uint32_t pid = *ctr & 0x3;
748 *ctr = RUSB2_PIPE_CTR_SQCLR_Msk;
750 if (!epn)
return true;
753 *ctr = RUSB2_PIPE_CTR_PID_BUF;
762TU_ATTR_ALWAYS_INLINE
static inline unsigned __builtin_ctz(
unsigned int value) {
763 unsigned int count = 0;
764 while ((value & 1) == 0) {
780 rusb->
INTSTS1 = ~((RUSB2_INTSTS1_SACK_Msk | RUSB2_INTSTS1_SIGN_Msk | RUSB2_INTSTS1_ATTCH_Msk | RUSB2_INTSTS1_DTCH_Msk) & is1);
781 rusb->
INTSTS0 = ~((RUSB2_INTSTS0_BRDY_Msk | RUSB2_INTSTS0_NRDY_Msk | RUSB2_INTSTS0_BEMP_Msk) & is0);
783 TU_LOG3(
"IS %04x %04x\r\n", is0, is1);
787 if (is1 & RUSB2_INTSTS1_SACK_Msk) {
793 if (is1 & RUSB2_INTSTS1_SIGN_Msk) {
797 if (is1 & RUSB2_INTSTS1_ATTCH_Msk) {
800 rusb->
INTENB1 = (rusb->
INTENB1 & ~RUSB2_INTSTS1_ATTCH_Msk) | RUSB2_INTSTS1_DTCH_Msk;
804 if (is1 & RUSB2_INTSTS1_DTCH_Msk) {
809 rusb->
INTENB1 = (rusb->
INTENB1 & ~RUSB2_INTSTS1_DTCH_Msk) | RUSB2_INTSTS1_ATTCH_Msk;
813 if (is0 & RUSB2_INTSTS0_BEMP_Msk) {
814 const unsigned s = rusb->
BEMPSTS;
821 if (is0 & RUSB2_INTSTS0_NRDY_Msk) {
822 const unsigned m = rusb->
NRDYENB;
823 unsigned s = rusb->
NRDYSTS & m;
831 if (is0 & RUSB2_INTSTS0_BRDY_Msk) {
832 const unsigned m = rusb->
BRDYENB;
833 unsigned s = rusb->
BRDYSTS & m;
xfer_td_t xfer[EP_CBI_COUNT+1][2]
static TU_ATTR_ALWAYS_INLINE void hcd_event_device_remove(uint8_t rhport, bool in_isr)
static TU_ATTR_ALWAYS_INLINE void hcd_event_xfer_complete(uint8_t dev_addr, uint8_t ep_addr, uint32_t xferred_bytes, xfer_result_t result, bool in_isr)
static TU_ATTR_ALWAYS_INLINE void hcd_event_device_attach(uint8_t rhport, bool in_isr)
void hcd_devtree_get_info(uint8_t dev_addr, hcd_devtree_info_t *devtree_info)
bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8])
static volatile uint16_t * addr_to_pipectr(uint8_t rhport, uint8_t dev_addr, unsigned ep_addr)
static bool pipe_xfer_in(rusb2_reg_t *rusb, unsigned num)
struct TU_ATTR_PACKED pipe_state_t
void hcd_int_disable(uint8_t rhport)
static uint16_t edpt_max_packet_size(rusb2_reg_t *rusb, unsigned num)
static bool pipe_xfer_out(rusb2_reg_t *rusb, unsigned num)
static uint16_t edpt0_max_packet_size(rusb2_reg_t *rusb)
static TU_ATTR_ALWAYS_INLINE unsigned __builtin_ctz(unsigned int value)
static uint32_t disable_interrupt(void)
static unsigned find_pipe(unsigned xfer_type)
static volatile reg_pipetre_t * get_pipetre(rusb2_reg_t *rusb, unsigned num)
static void process_pipe0_bemp(uint8_t rhport)
static void pipe_write_packet(void *buf, volatile void *fifo, unsigned len)
static void process_pipe_nrdy(uint8_t rhport, unsigned num)
bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr)
static void enable_interrupt(uint32_t pswi)
void hcd_int_enable(uint8_t rhport)
bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *buffer, uint16_t buflen)
void hcd_device_close(uint8_t rhport, uint8_t dev_addr)
bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr)
static bool pipe0_xfer_out(rusb2_reg_t *rusb)
TU_ATTR_PACKED_BEGIN TU_ATTR_BIT_FIELD_ORDER_BEGIN union TU_ATTR_PACKED hw_fifo_t
void hcd_port_reset_end(uint8_t rhport)
void hcd_port_reset(uint8_t rhport)
static bool process_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, void *buffer, uint16_t buflen)
static void pipe_read_packet(void *buf, volatile void *fifo, unsigned len)
bool hcd_port_connect_status(uint8_t rhport)
static bool process_pipe_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, void *buffer, uint16_t buflen)
static void process_pipe_brdy(uint8_t rhport, unsigned num)
uint32_t hcd_frame_number(uint8_t rhport)
static volatile uint16_t * get_pipectr(rusb2_reg_t *rusb, unsigned num)
static bool pipe0_xfer_in(rusb2_reg_t *rusb)
tusb_speed_t hcd_port_speed_get(uint8_t rhport)
void hcd_int_handler(uint8_t rhport, bool in_isr)
bool hcd_init(uint8_t rhport, const tusb_rhport_init_t *rh_init)
bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const *ep_desc)
static void pipe_wait_for_ready(rusb2_reg_t *rusb, unsigned num)
static bool process_pipe0_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, void *buffer, uint16_t buflen)
static TU_ATTR_ALWAYS_INLINE void rusb2_phy_init(void)
static TU_ATTR_ALWAYS_INLINE void rusb2_int_disable(uint8_t rhport)
static TU_ATTR_ALWAYS_INLINE void rusb2_module_start(uint8_t rhport, bool start)
static TU_ATTR_ALWAYS_INLINE void rusb2_int_enable(uint8_t rhport)
static TU_ATTR_ALWAYS_INLINE rusb2_reg_t * RUSB2_REG(uint8_t rhport)
TU_ATTR_PACKED_BEGIN TU_ATTR_BIT_FIELD_ORDER_BEGIN struct TU_ATTR_PACKED _ccrx_evenaccess reg_pipetre_t
volatile uint16_t BEMPSTS
struct _ccrx_evenaccess::@512::TU_ATTR_PACKED FRMNUM_b
volatile uint16_t DEVADD[10]
struct _ccrx_evenaccess::@504::TU_ATTR_PACKED INTSTS1_b
volatile uint16_t USBINDX
struct _ccrx_evenaccess::@500::TU_ATTR_PACKED PHYSET_b
volatile uint16_t D0FIFOSEL
volatile uint16_t PIPESEL
struct _ccrx_evenaccess::@538::TU_ATTR_PACKED PIPEMAXP_b
volatile uint16_t PIPEMAXP
struct _ccrx_evenaccess::@478::TU_ATTR_PACKED CFIFOCTR_b
volatile uint16_t BUSWAIT
volatile uint16_t CFIFOSEL
volatile uint16_t INTENB1
struct _ccrx_evenaccess::@530::TU_ATTR_PACKED DCPCTR_b
volatile uint16_t DCPMAXP
struct _ccrx_evenaccess::@476::TU_ATTR_PACKED CFIFOSEL_b
struct _ccrx_evenaccess::@556::TU_ATTR_PACKED LPSTS_b
volatile uint16_t NRDYSTS
struct _ccrx_evenaccess::@482::TU_ATTR_PACKED D0FIFOCTR_b
volatile RUSB2_PIPE_TR_t PIPE_TR[5]
volatile uint16_t USBLENG
volatile uint16_t INTSTS0
volatile uint16_t PIPE_CTR[9]
struct _ccrx_evenaccess::@498::TU_ATTR_PACKED SOFCFG_b
volatile uint16_t NRDYENB
volatile uint16_t PIPECFG
volatile uint16_t INTENB0
struct _ccrx_evenaccess::@464::TU_ATTR_PACKED PLLSTA_b
struct _ccrx_evenaccess::@480::TU_ATTR_PACKED D0FIFOSEL_b
struct _ccrx_evenaccess::@528::TU_ATTR_PACKED DCPMAXP_b
struct _ccrx_evenaccess::@466::TU_ATTR_PACKED DVSTCTR0_b
struct _ccrx_evenaccess::@458::TU_ATTR_PACKED SYSCFG_b
volatile uint16_t BEMPENB
volatile uint16_t D0FIFOCTR
volatile uint32_t PHYSLEW
struct _ccrx_evenaccess::@526::TU_ATTR_PACKED DCPCFG_b
struct _ccrx_evenaccess::@580::TU_ATTR_PACKED DPUSR0R_FS_b
volatile uint16_t CFIFOCTR
volatile uint16_t INTSTS1
volatile uint16_t BRDYSTS
struct _ccrx_evenaccess::@484::TU_ATTR_PACKED D1FIFOSEL_b
volatile uint16_t BRDYENB
AUDIO Channel Cluster Descriptor (4.1)
uint8_t bmAttributes
See: audio_clock_source_attribute_t.
tusb_speed_t
defined base on EHCI specs value for Endpoint Speed
static TU_ATTR_ALWAYS_INLINE uint8_t tu_edpt_number(uint8_t addr)
static TU_ATTR_ALWAYS_INLINE uint16_t tu_edpt_packet_size(tusb_desc_endpoint_t const *desc_ep)
TU_ATTR_PACKED_END TU_ATTR_BIT_FIELD_ORDER_END static TU_ATTR_ALWAYS_INLINE tusb_dir_t tu_edpt_dir(uint8_t addr)
static TU_ATTR_ALWAYS_INLINE uint8_t tu_edpt_addr(uint8_t num, uint8_t dir)