summaryrefslogtreecommitdiff
path: root/src/portable
diff options
context:
space:
mode:
authorHa Thach <[email protected]>2023-08-28 17:46:05 +0700
committerGitHub <[email protected]>2023-08-28 17:46:05 +0700
commit9063ede25f4a013dae8edccc2d953ba2de7ed684 (patch)
tree6f3b8ed3721b60955380514d414228bb567767cb /src/portable
parentaa0fabd51d3ed855ccb337602c6a0083bb50f648 (diff)
parent7bf5923052e5861f54c9cb0581e328f8be26a0a9 (diff)
Merge branch 'master' into nxp_k64
Diffstat (limited to 'src/portable')
-rw-r--r--src/portable/bridgetek/ft9xx/dcd_ft9xx.c2
-rw-r--r--src/portable/chipidea/ci_fs/dcd_ci_fs.c2
-rw-r--r--src/portable/chipidea/ci_hs/ci_hs_imxrt.h15
-rw-r--r--src/portable/chipidea/ci_hs/ci_hs_lpc18_43.h9
-rw-r--r--src/portable/chipidea/ci_hs/dcd_ci_hs.c2
-rw-r--r--src/portable/chipidea/ci_hs/hcd_ci_hs.c43
-rw-r--r--src/portable/dialog/da146xx/dcd_da146xx.c2
-rw-r--r--src/portable/ehci/ehci.c616
-rw-r--r--src/portable/ehci/ehci.h25
-rw-r--r--src/portable/mentor/musb/dcd_musb.c30
-rw-r--r--src/portable/mentor/musb/hcd_musb.c20
-rw-r--r--src/portable/microchip/pic/dcd_pic.c2
-rw-r--r--src/portable/microchip/samx7x/dcd_samx7x.c2
-rw-r--r--src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c2
-rw-r--r--src/portable/nxp/khci/dcd_khci.c2
-rw-r--r--src/portable/nxp/khci/hcd_khci.c28
-rw-r--r--src/portable/nxp/lpc17_40/dcd_lpc17_40.c2
-rw-r--r--src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c270
-rw-r--r--src/portable/ohci/ohci.c37
-rw-r--r--src/portable/raspberrypi/pio_usb/hcd_pio_usb.c86
-rw-r--r--src/portable/raspberrypi/rp2040/dcd_rp2040.c6
-rw-r--r--src/portable/raspberrypi/rp2040/hcd_rp2040.c16
-rw-r--r--src/portable/raspberrypi/rp2040/rp2040_usb.c8
-rw-r--r--src/portable/renesas/rusb2/dcd_rusb2.c778
-rw-r--r--src/portable/renesas/rusb2/hcd_rusb2.c554
-rw-r--r--src/portable/renesas/rusb2/rusb2_common.c61
-rw-r--r--src/portable/renesas/rusb2/rusb2_ra.h58
-rw-r--r--src/portable/renesas/rusb2/rusb2_rx.h20
-rw-r--r--src/portable/renesas/rusb2/rusb2_type.h339
-rw-r--r--src/portable/st/typec/typec_stm32.c18
-rw-r--r--src/portable/sunxi/dcd_sunxi_musb.c32
31 files changed, 1789 insertions, 1298 deletions
diff --git a/src/portable/bridgetek/ft9xx/dcd_ft9xx.c b/src/portable/bridgetek/ft9xx/dcd_ft9xx.c
index 95dfda49c..f02415904 100644
--- a/src/portable/bridgetek/ft9xx/dcd_ft9xx.c
+++ b/src/portable/bridgetek/ft9xx/dcd_ft9xx.c
@@ -51,7 +51,7 @@ extern int8_t board_ft9xx_vbus(void);
extern int board_uart_write(void const *buf, int len);
// Static array to store an incoming SETUP request for processing by tinyusb.
-CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN
+CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN
static uint8_t _ft9xx_setup_packet[8];
struct ft9xx_xfer_state
diff --git a/src/portable/chipidea/ci_fs/dcd_ci_fs.c b/src/portable/chipidea/ci_fs/dcd_ci_fs.c
index 37265df8b..9327e09d8 100644
--- a/src/portable/chipidea/ci_fs/dcd_ci_fs.c
+++ b/src/portable/chipidea/ci_fs/dcd_ci_fs.c
@@ -116,7 +116,7 @@ typedef struct
// INTERNAL OBJECT & FUNCTION DECLARATION
//--------------------------------------------------------------------+
// BDT(Buffer Descriptor Table) must be 256-byte aligned
-CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(512) static dcd_data_t _dcd;
+CFG_TUD_MEM_SECTION TU_ATTR_ALIGNED(512) static dcd_data_t _dcd;
TU_VERIFY_STATIC( sizeof(_dcd.bdt) == 512, "size is not correct" );
diff --git a/src/portable/chipidea/ci_hs/ci_hs_imxrt.h b/src/portable/chipidea/ci_hs/ci_hs_imxrt.h
index 96f0ba766..c59c107ff 100644
--- a/src/portable/chipidea/ci_hs/ci_hs_imxrt.h
+++ b/src/portable/chipidea/ci_hs/ci_hs_imxrt.h
@@ -68,31 +68,34 @@ TU_ATTR_ALWAYS_INLINE static inline bool imxrt_is_cache_mem(uintptr_t addr) {
return !(0x20000000 <= addr && addr < 0x20100000);
}
-TU_ATTR_ALWAYS_INLINE static inline void imxrt_dcache_clean(void const* addr, uint32_t data_size) {
+TU_ATTR_ALWAYS_INLINE static inline bool imxrt_dcache_clean(void const* addr, uint32_t data_size) {
const uintptr_t addr32 = (uintptr_t) addr;
if (imxrt_is_cache_mem(addr32)) {
+ TU_ASSERT(tu_is_aligned32(addr32));
SCB_CleanDCache_by_Addr((uint32_t *) addr32, (int32_t) data_size);
}
+ return true;
}
-TU_ATTR_ALWAYS_INLINE static inline void imxrt_dcache_invalidate(void const* addr, uint32_t data_size) {
+TU_ATTR_ALWAYS_INLINE static inline bool imxrt_dcache_invalidate(void const* addr, uint32_t data_size) {
const uintptr_t addr32 = (uintptr_t) addr;
if (imxrt_is_cache_mem(addr32)) {
// Invalidating does not push cached changes back to RAM so we need to be
// *very* careful when we do it. If we're not aligned, then we risk resetting
// values back to their RAM state.
- // if (addr32 % 32 != 0) {
- // TU_BREAKPOINT();
- // }
+ TU_ASSERT(tu_is_aligned32(addr32));
SCB_InvalidateDCache_by_Addr((void*) addr32, (int32_t) data_size);
}
+ return true;
}
-TU_ATTR_ALWAYS_INLINE static inline void imxrt_dcache_clean_invalidate(void const* addr, uint32_t data_size) {
+TU_ATTR_ALWAYS_INLINE static inline bool imxrt_dcache_clean_invalidate(void const* addr, uint32_t data_size) {
const uintptr_t addr32 = (uintptr_t) addr;
if (imxrt_is_cache_mem(addr32)) {
+ TU_ASSERT(tu_is_aligned32(addr32));
SCB_CleanInvalidateDCache_by_Addr((uint32_t *) addr32, (int32_t) data_size);
}
+ return true;
}
#endif
diff --git a/src/portable/chipidea/ci_hs/ci_hs_lpc18_43.h b/src/portable/chipidea/ci_hs/ci_hs_lpc18_43.h
index 2e84c93e7..178eec419 100644
--- a/src/portable/chipidea/ci_hs/ci_hs_lpc18_43.h
+++ b/src/portable/chipidea/ci_hs/ci_hs_lpc18_43.h
@@ -27,9 +27,18 @@
#ifndef _CI_HS_LPC18_43_H_
#define _CI_HS_LPC18_43_H_
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
// LPCOpen for 18xx & 43xx
#include "chip.h"
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
+
static const ci_hs_controller_t _ci_controller[] =
{
{ .reg_base = LPC_USB0_BASE, .irqnum = USB0_IRQn },
diff --git a/src/portable/chipidea/ci_hs/dcd_ci_hs.c b/src/portable/chipidea/ci_hs/dcd_ci_hs.c
index f50550d33..f9ec666e5 100644
--- a/src/portable/chipidea/ci_hs/dcd_ci_hs.c
+++ b/src/portable/chipidea/ci_hs/dcd_ci_hs.c
@@ -175,7 +175,7 @@ typedef struct {
dcd_qtd_t qtd[TUP_DCD_ENDPOINT_MAX][2] TU_ATTR_ALIGNED(32);
}dcd_data_t;
-CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(2048)
+CFG_TUD_MEM_SECTION TU_ATTR_ALIGNED(2048)
static dcd_data_t _dcd_data;
//--------------------------------------------------------------------+
diff --git a/src/portable/chipidea/ci_hs/hcd_ci_hs.c b/src/portable/chipidea/ci_hs/hcd_ci_hs.c
index 56167b8f6..462cbd301 100644
--- a/src/portable/chipidea/ci_hs/hcd_ci_hs.c
+++ b/src/portable/chipidea/ci_hs/hcd_ci_hs.c
@@ -39,24 +39,27 @@
#include "ci_hs_type.h"
#if CFG_TUSB_MCU == OPT_MCU_MIMXRT1XXX
- #include "ci_hs_imxrt.h"
- void hcd_dcache_clean(void const* addr, uint32_t data_size) {
- imxrt_dcache_clean(addr, data_size);
- }
+#include "ci_hs_imxrt.h"
- void hcd_dcache_invalidate(void const* addr, uint32_t data_size) {
- imxrt_dcache_invalidate(addr, data_size);
- }
+bool hcd_dcache_clean(void const* addr, uint32_t data_size) {
+ return imxrt_dcache_clean(addr, data_size);
+}
+
+bool hcd_dcache_invalidate(void const* addr, uint32_t data_size) {
+ return imxrt_dcache_invalidate(addr, data_size);
+}
- void hcd_dcache_clean_invalidate(void const* addr, uint32_t data_size) {
- imxrt_dcache_clean_invalidate(addr, data_size);
- }
+bool hcd_dcache_clean_invalidate(void const* addr, uint32_t data_size) {
+ return imxrt_dcache_clean_invalidate(addr, data_size);
+}
#elif TU_CHECK_MCU(OPT_MCU_LPC18XX, OPT_MCU_LPC43XX)
- #include "ci_hs_lpc18_43.h"
+
+#include "ci_hs_lpc18_43.h"
+
#else
- #error "Unsupported MCUs"
+#error "Unsupported MCUs"
#endif
//--------------------------------------------------------------------+
@@ -67,25 +70,25 @@
// Controller API
//--------------------------------------------------------------------+
-bool hcd_init(uint8_t rhport)
-{
- ci_hs_regs_t* hcd_reg = CI_HS_REG(rhport);
+bool hcd_init(uint8_t rhport) {
+ ci_hs_regs_t *hcd_reg = CI_HS_REG(rhport);
// Reset controller
hcd_reg->USBCMD |= USBCMD_RESET;
- while( hcd_reg->USBCMD & USBCMD_RESET ) {}
+ while ( hcd_reg->USBCMD & USBCMD_RESET ) {}
// Set mode to device, must be set immediately after reset
#if CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX
// LPC18XX/43XX need to set VBUS Power Select to HIGH
// RHPORT1 is fullspeed only (need external PHY for Highspeed)
hcd_reg->USBMODE = USBMODE_CM_HOST | USBMODE_VBUS_POWER_SELECT;
- if (rhport == 1) hcd_reg->PORTSC1 |= PORTSC1_FORCE_FULL_SPEED;
+ if ( rhport == 1 ) hcd_reg->PORTSC1 |= PORTSC1_FORCE_FULL_SPEED;
#else
hcd_reg->USBMODE = USBMODE_CM_HOST;
#endif
// FIXME force full speed, still have issue with Highspeed enumeration
+ // probably due to physical connection bouncing when plug/unplug
// 1. Have issue when plug/unplug devices, maybe the port is not reset properly
// 2. Also does not seems to detect disconnection
hcd_reg->PORTSC1 |= PORTSC1_FORCE_FULL_SPEED;
@@ -93,13 +96,11 @@ bool hcd_init(uint8_t rhport)
return ehci_init(rhport, (uint32_t) &hcd_reg->CAPLENGTH, (uint32_t) &hcd_reg->USBCMD);
}
-void hcd_int_enable(uint8_t rhport)
-{
+void hcd_int_enable(uint8_t rhport) {
CI_HCD_INT_ENABLE(rhport);
}
-void hcd_int_disable(uint8_t rhport)
-{
+void hcd_int_disable(uint8_t rhport) {
CI_HCD_INT_DISABLE(rhport);
}
diff --git a/src/portable/dialog/da146xx/dcd_da146xx.c b/src/portable/dialog/da146xx/dcd_da146xx.c
index 961da81d6..d1e85c2df 100644
--- a/src/portable/dialog/da146xx/dcd_da146xx.c
+++ b/src/portable/dialog/da146xx/dcd_da146xx.c
@@ -651,7 +651,7 @@ static void handle_epx_tx_ev(xfer_ctl_t *xfer)
}
if (txs & USB_USB_TXS1_REG_USB_TX_URUN_Msk)
{
- TU_LOG1("EP %d FIFO underrun\n", epnum);
+ TU_LOG1("EP %d FIFO underrun\r\n", epnum);
}
// Start next or repeated packet.
start_tx_packet(xfer);
diff --git a/src/portable/ehci/ehci.c b/src/portable/ehci/ehci.c
index 38711e382..c93c33fc0 100644
--- a/src/portable/ehci/ehci.c
+++ b/src/portable/ehci/ehci.c
@@ -48,8 +48,8 @@
#ifdef TUP_USBIP_CHIPIDEA_HS
// NXP Transdimension: 8 elements
#define FRAMELIST_SIZE_BIT_VALUE 7u
- #define FRAMELIST_SIZE_USBCMD_VALUE (((FRAMELIST_SIZE_BIT_VALUE & 3) << EHCI_USBCMD_POS_FRAMELIST_SIZE) | \
- ((FRAMELIST_SIZE_BIT_VALUE >> 2) << EHCI_USBCMD_POS_NXP_FRAMELIST_SIZE_MSB))
+ #define FRAMELIST_SIZE_USBCMD_VALUE (((FRAMELIST_SIZE_BIT_VALUE & 3) << EHCI_USBCMD_FRAMELIST_SIZE_SHIFT) | \
+ ((FRAMELIST_SIZE_BIT_VALUE >> 2) << EHCI_USBCMD_CHIPIDEA_FRAMELIST_SIZE_MSB_SHIFT))
#else
// STD EHCI: 256 elements
#define FRAMELIST_SIZE_BIT_VALUE 2u
@@ -126,52 +126,50 @@ static inline void print_intr(uint32_t intr) {
//--------------------------------------------------------------------+
// PROTOTYPE
//--------------------------------------------------------------------+
-static inline ehci_link_t* get_period_head(uint8_t rhport, uint32_t interval_ms)
-{
- (void) rhport;
- return (ehci_link_t*) &ehci_data.period_head_arr[ tu_log2( tu_min32(FRAMELIST_SIZE, interval_ms) ) ];
-}
-
-static inline ehci_qhd_t* qhd_control(uint8_t dev_addr)
-{
- return &ehci_data.control[dev_addr].qhd;
-}
-
-static inline ehci_qhd_t* qhd_async_head(uint8_t rhport)
-{
- (void) rhport;
- // control qhd of dev0 is used as async head
- return qhd_control(0);
-}
-
-static inline ehci_qtd_t* qtd_control(uint8_t dev_addr)
-{
- return &ehci_data.control[dev_addr].qtd;
-}
+// weak dcache for non-cacheable MCU
+TU_ATTR_WEAK bool hcd_dcache_clean(void const* addr, uint32_t data_size) { (void) addr; (void) data_size; return true; }
+TU_ATTR_WEAK bool hcd_dcache_invalidate(void const* addr, uint32_t data_size) { (void) addr; (void) data_size; return true; }
+TU_ATTR_WEAK bool hcd_dcache_clean_invalidate(void const* addr, uint32_t data_size) { (void) addr; (void) data_size; return true; }
-static inline ehci_qhd_t* qhd_next (ehci_qhd_t const * p_qhd);
-static inline ehci_qhd_t* qhd_find_free (void);
-static inline ehci_qhd_t* qhd_get_from_addr (uint8_t dev_addr, uint8_t ep_addr);
+TU_ATTR_ALWAYS_INLINE static inline ehci_qhd_t* qhd_control(uint8_t dev_addr);
+TU_ATTR_ALWAYS_INLINE static inline ehci_qhd_t* qhd_next (ehci_qhd_t const * p_qhd);
+TU_ATTR_ALWAYS_INLINE static inline ehci_qhd_t* qhd_find_free (void);
+static ehci_qhd_t* qhd_get_from_addr (uint8_t dev_addr, uint8_t ep_addr);
static void qhd_init(ehci_qhd_t *p_qhd, uint8_t dev_addr, tusb_desc_endpoint_t const * ep_desc);
static void qhd_attach_qtd(ehci_qhd_t *qhd, ehci_qtd_t *qtd);
+static void qhd_remove_qtd(ehci_qhd_t *qhd);
-static inline ehci_qtd_t* qtd_find_free (void);
+TU_ATTR_ALWAYS_INLINE static inline ehci_qtd_t* qtd_control(uint8_t dev_addr);
+TU_ATTR_ALWAYS_INLINE static inline ehci_qtd_t* qtd_find_free (void);
static void qtd_init (ehci_qtd_t* qtd, void const* buffer, uint16_t total_bytes);
-static inline void list_insert (ehci_link_t *current, ehci_link_t *new, uint8_t new_type);
-static inline ehci_link_t* list_next (ehci_link_t const *p_link);
-
-TU_ATTR_WEAK void hcd_dcache_clean(void const* addr, uint32_t data_size) {
- (void) addr; (void) data_size;
-}
+TU_ATTR_ALWAYS_INLINE static inline ehci_link_t* list_get_period_head(uint8_t rhport, uint32_t interval_ms);
+TU_ATTR_ALWAYS_INLINE static inline ehci_qhd_t* list_get_async_head(uint8_t rhport);
+TU_ATTR_ALWAYS_INLINE static inline void list_insert (ehci_link_t *current, ehci_link_t *new, uint8_t new_type);
+TU_ATTR_ALWAYS_INLINE static inline ehci_link_t* list_next (ehci_link_t const *p_link);
+static void list_remove_qhd_by_daddr(ehci_link_t* list_head, uint8_t dev_addr);
-TU_ATTR_WEAK void hcd_dcache_invalidate(void const* addr, uint32_t data_size) {
- (void) addr; (void) data_size;
+static void ehci_disable_schedule(ehci_registers_t* regs, bool is_period) {
+ // maybe have a timeout for status
+ if (is_period) {
+ regs->command_bm.periodic_enable = 0;
+ while(regs->status_bm.periodic_status) {}
+ } else {
+ regs->command_bm.async_enable = 0;
+ while(regs->status_bm.async_status) {} // should have a timeout
+ }
}
-TU_ATTR_WEAK void hcd_dcache_clean_invalidate(void const* addr, uint32_t data_size) {
- (void) addr; (void) data_size;
+static void ehci_enable_schedule(ehci_registers_t* regs, bool is_period) {
+ // maybe have a timeout for status
+ if (is_period) {
+ regs->command_bm.periodic_enable = 1;
+ while ( 0 == regs->status_bm.periodic_status ) {}
+ } else {
+ regs->command_bm.async_enable = 1;
+ while( 0 == regs->status_bm.async_status ) {}
+ }
}
//--------------------------------------------------------------------+
@@ -190,6 +188,11 @@ void hcd_port_reset(uint8_t rhport)
ehci_registers_t* regs = ehci_data.regs;
+ // skip if already in reset
+ if (regs->portsc_bm.port_reset) {
+ return;
+ }
+
// mask out Write-1-to-Clear bits
uint32_t portsc = regs->portsc & ~EHCI_PORTSC_MASK_W1C;
@@ -204,16 +207,18 @@ void hcd_port_reset(uint8_t rhport)
void hcd_port_reset_end(uint8_t rhport)
{
(void) rhport;
-
-#if 0 // TODO check if this is necessary
ehci_registers_t* regs = ehci_data.regs;
+ // skip if reset is already complete
+ if (!regs->portsc_bm.port_reset) {
+ return;
+ }
+
// mask out all change bits since they are Write 1 to clear
- uint32_t portsc = regs->portsc & ~EHCI_PORTSC_MASK_CHANGE_ALL;
- portsc &= ~(EHCI_PORTSC_MASK_PORT_RESET);
+ uint32_t portsc = regs->portsc & ~EHCI_PORTSC_MASK_W1C;
+ portsc &= ~EHCI_PORTSC_MASK_PORT_RESET;
regs->portsc = portsc;
-#endif
}
bool hcd_port_connect_status(uint8_t rhport)
@@ -228,43 +233,6 @@ tusb_speed_t hcd_port_speed_get(uint8_t rhport)
return (tusb_speed_t) ehci_data.regs->portsc_bm.nxp_port_speed; // NXP specific port speed
}
-static void list_remove_qhd_by_daddr(ehci_link_t* list_head, uint8_t dev_addr) {
- ehci_link_t* prev = list_head;
-
- while (prev && !prev->terminate) {
- ehci_qhd_t* qhd = (ehci_qhd_t*) (uintptr_t) list_next(prev);
-
- // done if loop back to head
- if ( (uintptr_t) qhd == (uintptr_t) list_head) {
- break;
- }
-
- if ( qhd->dev_addr == dev_addr ) {
- // TODO deactivate all TD, wait for QHD to inactive before removal
- prev->address = qhd->next.address;
-
- // EHCI 4.8.2 link the removed qhd's next to async head (which always reachable by Host Controller)
- qhd->next.address = ((uint32_t) list_head) | (EHCI_QTYPE_QHD << 1);
-
- if ( qhd->int_smask )
- {
- // period list queue element is guarantee to be free in the next frame (1 ms)
- qhd->used = 0;
- }else
- {
- // async list use async advance handshake
- // mark as removing, will completely re-usable when async advance isr occurs
- qhd->removing = 1;
- }
-
- hcd_dcache_clean(qhd, sizeof(ehci_qhd_t));
- hcd_dcache_clean(prev, sizeof(ehci_qhd_t));
- }else {
- prev = list_next(prev);
- }
- }
-}
-
// Close all opened endpoint belong to this device
void hcd_device_close(uint8_t rhport, uint8_t daddr)
{
@@ -274,7 +242,7 @@ void hcd_device_close(uint8_t rhport, uint8_t daddr)
}
// Remove from async list
- list_remove_qhd_by_daddr((ehci_link_t *) qhd_async_head(rhport), daddr);
+ list_remove_qhd_by_daddr((ehci_link_t *) list_get_async_head(rhport), daddr);
// Remove from all interval period list
for(uint8_t i = 0; i < TU_ARRAY_SIZE(ehci_data.period_head_arr); i++) {
@@ -286,37 +254,42 @@ void hcd_device_close(uint8_t rhport, uint8_t daddr)
}
static void init_periodic_list(uint8_t rhport) {
+ (void) rhport;
+
// Build the polling interval tree with 1 ms, 2 ms, 4 ms and 8 ms (framesize) only
for ( uint32_t i = 0; i < TU_ARRAY_SIZE(ehci_data.period_head_arr); i++ ) {
ehci_data.period_head_arr[i].int_smask = 1; // queue head in period list must have smask non-zero
ehci_data.period_head_arr[i].qtd_overlay.halted = 1; // dummy node, always inactive
}
- ehci_link_t * const framelist = ehci_data.period_framelist;
- ehci_link_t * const period_1ms = get_period_head(rhport, 1u);
-
+ // TODO EHCI_FRAMELIST_SIZE with other size than 8
// all links --> period_head_arr[0] (1ms)
// 0, 2, 4, 6 etc --> period_head_arr[1] (2ms)
// 1, 5 --> period_head_arr[2] (4ms)
// 3 --> period_head_arr[3] (8ms)
- // TODO EHCI_FRAMELIST_SIZE with other size than 8
+ ehci_link_t * const framelist = ehci_data.period_framelist;
+ ehci_link_t * const head_1ms = (ehci_link_t *) &ehci_data.period_head_arr[0];
+ ehci_link_t * const head_2ms = (ehci_link_t *) &ehci_data.period_head_arr[1];
+ ehci_link_t * const head_4ms = (ehci_link_t *) &ehci_data.period_head_arr[2];
+ ehci_link_t * const head_8ms = (ehci_link_t *) &ehci_data.period_head_arr[3];
+
for (uint32_t i = 0; i < FRAMELIST_SIZE; i++) {
- framelist[i].address = (uint32_t) period_1ms;
+ framelist[i].address = (uint32_t) head_1ms;
framelist[i].type = EHCI_QTYPE_QHD;
}
for (uint32_t i = 0; i < FRAMELIST_SIZE; i += 2) {
- list_insert(framelist + i, get_period_head(rhport, 2u), EHCI_QTYPE_QHD);
+ list_insert(framelist + i, head_2ms, EHCI_QTYPE_QHD);
}
for (uint32_t i = 1; i < FRAMELIST_SIZE; i += 4) {
- list_insert(framelist + i, get_period_head(rhport, 4u), EHCI_QTYPE_QHD);
+ list_insert(framelist + i, head_4ms, EHCI_QTYPE_QHD);
}
- list_insert(framelist + 3, get_period_head(rhport, 8u), EHCI_QTYPE_QHD);
+ list_insert(framelist + 3, head_8ms, EHCI_QTYPE_QHD);
- period_1ms->terminate = 1;
+ head_1ms->terminate = 1;
}
bool ehci_init(uint8_t rhport, uint32_t capability_reg, uint32_t operatial_reg)
@@ -341,18 +314,18 @@ bool ehci_init(uint8_t rhport, uint32_t capability_reg, uint32_t operatial_reg)
regs->status = (EHCI_INT_MASK_ALL & ~EHCI_INT_MASK_PORT_CHANGE);
// Enable interrupts
- regs->inten = EHCI_INT_MASK_ERROR | EHCI_INT_MASK_PORT_CHANGE | EHCI_INT_MASK_ASYNC_ADVANCE |
- EHCI_INT_MASK_NXP_PERIODIC | EHCI_INT_MASK_NXP_ASYNC | EHCI_INT_MASK_FRAMELIST_ROLLOVER;
+ regs->inten = EHCI_INT_MASK_USB | EHCI_INT_MASK_ERROR | EHCI_INT_MASK_PORT_CHANGE |
+ EHCI_INT_MASK_ASYNC_ADVANCE | EHCI_INT_MASK_FRAMELIST_ROLLOVER;
//------------- Asynchronous List -------------//
- ehci_qhd_t * const async_head = qhd_async_head(rhport);
+ ehci_qhd_t * const async_head = list_get_async_head(rhport);
tu_memclr(async_head, sizeof(ehci_qhd_t));
- async_head->next.address = (uint32_t) async_head; // circular list, next is itself
- async_head->next.type = EHCI_QTYPE_QHD;
- async_head->head_list_flag = 1;
- async_head->qtd_overlay.halted = 1; // inactive most of time
- async_head->qtd_overlay.next.terminate = 1; // TODO removed if verified
+ async_head->next.address = (uint32_t) async_head; // circular list, next is itself
+ async_head->next.type = EHCI_QTYPE_QHD;
+ async_head->head_list_flag = 1;
+ async_head->qtd_overlay.halted = 1; // inactive most of time
+ async_head->qtd_overlay.next.terminate = 1; // TODO removed if verified
regs->async_list_addr = (uint32_t) async_head;
@@ -366,8 +339,7 @@ bool ehci_init(uint8_t rhport, uint32_t capability_reg, uint32_t operatial_reg)
regs->nxp_tt_control = 0;
//------------- USB CMD Register -------------//
- regs->command |= TU_BIT(EHCI_USBCMD_POS_RUN_STOP) | TU_BIT(EHCI_USBCMD_POS_ASYNC_ENABLE) |
- TU_BIT(EHCI_USBCMD_POS_PERIOD_ENABLE) | // TODO enable period list only there is int/iso endpoint
+ regs->command |= EHCI_USBCMD_RUN_STOP | EHCI_USBCMD_PERIOD_SCHEDULE_ENABLE | EHCI_USBCMD_ASYNC_SCHEDULE_ENABLE |
FRAMELIST_SIZE_USBCMD_VALUE;
//------------- ConfigFlag Register (skip) -------------//
@@ -377,7 +349,7 @@ bool ehci_init(uint8_t rhport, uint32_t capability_reg, uint32_t operatial_reg)
if (ehci_data.cap_regs->hcsparams_bm.port_power_control) {
// mask out all change bits since they are Write 1 to clear
uint32_t portsc = (regs->portsc & ~EHCI_PORTSC_MASK_W1C);
- portsc |= ECHI_PORTSC_MASK_PORT_POWER;
+ portsc |= EHCI_PORTSC_MASK_PORT_POWER;
regs->portsc = portsc;
}
@@ -426,11 +398,11 @@ bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const
{
case TUSB_XFER_CONTROL:
case TUSB_XFER_BULK:
- list_head = (ehci_link_t*) qhd_async_head(rhport);
+ list_head = (ehci_link_t*) list_get_async_head(rhport);
break;
case TUSB_XFER_INTERRUPT:
- list_head = get_period_head(rhport, p_qhd->interval_ms);
+ list_head = list_get_period_head(rhport, p_qhd->interval_ms);
break;
case TUSB_XFER_ISOCHRONOUS:
@@ -439,10 +411,8 @@ bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const
default: break;
}
-
TU_ASSERT(list_head);
- // TODO might need to disable async/period list
list_insert(list_head, (ehci_link_t*) p_qhd, EHCI_QTYPE_QHD);
hcd_dcache_clean(p_qhd, sizeof(ehci_qhd_t));
@@ -463,6 +433,11 @@ bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet
hcd_dcache_clean(setup_packet, 8);
+ // Control endpoint never be stalled. Skip reset Data Toggle since it is fixed per stage
+ if (qhd->qtd_overlay.halted) {
+ qhd->qtd_overlay.halted = false;
+ }
+
// attach TD to QHD -> start transferring
qhd_attach_qtd(qhd, td);
@@ -476,20 +451,25 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *
uint8_t const epnum = tu_edpt_number(ep_addr);
uint8_t const dir = tu_edpt_dir(ep_addr);
- ehci_qhd_t* qhd;
+ ehci_qhd_t* qhd = qhd_get_from_addr(dev_addr, ep_addr);
ehci_qtd_t* qtd;
if (epnum == 0) {
- qhd = qhd_control(dev_addr);
- qtd = qtd_control(dev_addr);
+ // Control endpoint never be stalled. Skip reset Data Toggle since it is fixed per stage
+ if (qhd->qtd_overlay.halted) {
+ qhd->qtd_overlay.halted = false;
+ }
+ qtd = qtd_control(dev_addr);
qtd_init(qtd, buffer, buflen);
// first data toggle is always 1 (data & setup stage)
qtd->data_toggle = 1;
qtd->pid = dir ? EHCI_PID_IN : EHCI_PID_OUT;
} else {
- qhd = qhd_get_from_addr(dev_addr, ep_addr);
+ // skip if endpoint is halted
+ TU_VERIFY(!qhd->qtd_overlay.halted);
+
qtd = qtd_find_free();
TU_ASSERT(qtd);
@@ -510,12 +490,45 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *
return true;
}
-bool hcd_edpt_clear_stall(uint8_t daddr, uint8_t ep_addr)
-{
+bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) {
+ (void) rhport;
+
+ // TODO ISO not supported yet
+ ehci_qhd_t* qhd = qhd_get_from_addr(dev_addr, ep_addr);
+ ehci_qtd_t * volatile qtd = qhd->attached_qtd;
+ TU_VERIFY(qtd != NULL); // no queued transfer
+
+ hcd_dcache_invalidate(qtd, sizeof(ehci_qtd_t));
+ TU_VERIFY(qtd->active); // transfer is already complete
+
+ // HC is still processing, disable HC list schedule before making changes
+ bool const is_period = (qhd->interval_ms > 0);
+
+ ehci_disable_schedule(ehci_data.regs, is_period);
+
+ // check active bit again just in case HC has just processed the TD
+ bool const still_active = qtd->active;
+ if (still_active) {
+ // remove TD from QH overlay
+ qhd->qtd_overlay.next.terminate = 1;
+ hcd_dcache_clean(qhd, sizeof(ehci_qhd_t));
+
+ // remove TD from QH software list
+ qhd_remove_qtd(qhd);
+ }
+
+ ehci_enable_schedule(ehci_data.regs, is_period);
+
+ return still_active; // true if removed an active transfer
+}
+
+bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t daddr, uint8_t ep_addr) {
+ (void) rhport;
ehci_qhd_t *qhd = qhd_get_from_addr(daddr, ep_addr);
qhd->qtd_overlay.halted = 0;
+ qhd->qtd_overlay.data_toggle = 0;
hcd_dcache_clean_invalidate(qhd, sizeof(ehci_qhd_t));
- // TODO reset data toggle ?
+
return true;
}
@@ -541,71 +554,79 @@ void async_advance_isr(uint8_t rhport)
}
TU_ATTR_ALWAYS_INLINE static inline
-void port_connect_status_change_isr(uint8_t rhport)
-{
+void port_connect_status_change_isr(uint8_t rhport) {
// NOTE There is an sequence plug->unplug->…..-> plug if device is powering with pre-plugged device
- if (ehci_data.regs->portsc_bm.current_connect_status)
- {
+ if ( ehci_data.regs->portsc_bm.current_connect_status ) {
hcd_port_reset(rhport);
hcd_event_device_attach(rhport, true);
- }else // device unplugged
+ } else // device unplugged
{
hcd_event_device_remove(rhport, true);
}
}
+// Check queue head for potential transfer complete (successful or error)
TU_ATTR_ALWAYS_INLINE static inline
void qhd_xfer_complete_isr(ehci_qhd_t * qhd) {
- // examine TD attached to queue head
- ehci_qtd_t * volatile qtd = (ehci_qtd_t * volatile) qhd->attached_qtd;
- if (qtd == NULL) return; // no TD attached
- hcd_dcache_invalidate(qtd, sizeof(ehci_qtd_t));
+ hcd_dcache_invalidate(qhd, sizeof(ehci_qhd_t)); // HC may have updated the overlay
+ volatile ehci_qtd_t *qtd_overlay = &qhd->qtd_overlay;
- // TD is still active, no need to process
- if (qtd->active) {
- return;
- }
+ // process non-active (completed) QHD with attached (scheduled) TD
+ if ( !qtd_overlay->active && qhd->attached_qtd != NULL ) {
+ xfer_result_t xfer_result;
- uint8_t dir = (qtd->pid == EHCI_PID_IN) ? 1 : 0;
- uint32_t const xferred_bytes = qtd->expected_bytes - qtd->total_bytes;
+ if ( qtd_overlay->halted ) {
+ if (qtd_overlay->xact_err || qtd_overlay->err_count == 0 || qtd_overlay->buffer_err || qtd_overlay->babble_err) {
+ // Error count = 0 often occurs when device disconnected, or other bus-related error
+ // clear halted bit if not caused by STALL to allow more transfer
+ xfer_result = XFER_RESULT_FAILED;
+ qtd_overlay->halted = false;
+ TU_LOG3(" QHD xfer err count: %d\n", qtd_overlay->err_count);
+ // TU_BREAKPOINT(); // TODO skip unplugged device
+ }else {
+ // no error bits are set, endpoint is halted due to STALL
+ xfer_result = XFER_RESULT_STALLED;
+ }
+ } else {
+ xfer_result = XFER_RESULT_SUCCESS;
+ }
- // invalidate dcache if IN transfer
- if (dir == 1 && qhd->attached_buffer != 0 && xferred_bytes > 0) {
- hcd_dcache_invalidate((void*) qhd->attached_buffer, xferred_bytes);
- }
+ ehci_qtd_t * volatile qtd = qhd->attached_qtd;
+ hcd_dcache_invalidate(qtd, sizeof(ehci_qtd_t)); // HC may have written back TD
- // remove and free TD before invoking callback
- qhd->attached_qtd = NULL;
- qhd->attached_buffer = 0;
- qtd->used = 0; // free QTD
+ uint8_t const dir = (qtd->pid == EHCI_PID_IN) ? 1 : 0;
+ uint32_t const xferred_bytes = qtd->expected_bytes - qtd->total_bytes;
+
+ // invalidate dcache if IN transfer with data
+ if (dir == 1 && qhd->attached_buffer != 0 && xferred_bytes > 0) {
+ hcd_dcache_invalidate((void*) qhd->attached_buffer, xferred_bytes);
+ }
+
+ // remove and free TD before invoking callback
+ qhd_remove_qtd(qhd);
- // notify usbh
- uint8_t const ep_addr = tu_edpt_addr(qhd->ep_number, dir);
- hcd_event_xfer_complete(qhd->dev_addr, ep_addr, xferred_bytes, XFER_RESULT_SUCCESS, true);
+ // notify usbh
+ uint8_t const ep_addr = tu_edpt_addr(qhd->ep_number, dir);
+ hcd_event_xfer_complete(qhd->dev_addr, ep_addr, xferred_bytes, xfer_result, true);
+ }
}
TU_ATTR_ALWAYS_INLINE static inline
-void async_list_xfer_complete_isr(ehci_qhd_t * const async_head)
+void proccess_async_xfer_isr(ehci_qhd_t * const list_head)
{
- ehci_qhd_t *p_qhd = async_head;
- do
- {
- hcd_dcache_invalidate(p_qhd, sizeof(ehci_qhd_t));
+ ehci_qhd_t *qhd = list_head;
- // halted or error is processed in error isr
- if ( !p_qhd->qtd_overlay.halted ) {
- qhd_xfer_complete_isr(p_qhd);
- }
-
- p_qhd = qhd_next(p_qhd);
- }while(p_qhd != async_head); // async list traversal, stop if loop around
+ do {
+ qhd_xfer_complete_isr(qhd);
+ qhd = qhd_next(qhd);
+ } while ( qhd != list_head ); // async list traversal, stop if loop around
}
TU_ATTR_ALWAYS_INLINE static inline
-void period_list_xfer_complete_isr(uint8_t rhport, uint32_t interval_ms)
+void process_period_xfer_isr(uint8_t rhport, uint32_t interval_ms)
{
- uint32_t const period_1ms_addr = (uint32_t) get_period_head(rhport, 1u);
- ehci_link_t next_link = * get_period_head(rhport, interval_ms);
+ uint32_t const period_1ms_addr = (uint32_t) list_get_period_head(rhport, 1u);
+ ehci_link_t next_link = *list_get_period_head(rhport, interval_ms);
while (!next_link.terminate) {
if (interval_ms > 1 && period_1ms_addr == tu_align32(next_link.address)) {
@@ -618,22 +639,13 @@ void period_list_xfer_complete_isr(uint8_t rhport, uint32_t interval_ms)
switch (next_link.type) {
case EHCI_QTYPE_QHD: {
ehci_qhd_t *qhd = (ehci_qhd_t *) entry_addr;
- hcd_dcache_invalidate(qhd, sizeof(ehci_qhd_t));
-
- if (!qhd->qtd_overlay.halted) {
- qhd_xfer_complete_isr(qhd);
- }
+ qhd_xfer_complete_isr(qhd);
}
break;
+ // TODO support hs/fs ISO
case EHCI_QTYPE_ITD:
- // TODO support hs ISO
- break;
-
case EHCI_QTYPE_SITD:
- // TODO support split ISO
- break;
-
case EHCI_QTYPE_FSTN:
default:
break;
@@ -643,108 +655,6 @@ void period_list_xfer_complete_isr(uint8_t rhport, uint32_t interval_ms)
}
}
-// TODO merge with qhd_xfer_complete_isr()
-TU_ATTR_ALWAYS_INLINE static inline
-void qhd_xfer_error_isr(ehci_qhd_t * qhd)
-{
- volatile ehci_qtd_t *qtd_overlay = &qhd->qtd_overlay;
-
- // TD has error
- if (qtd_overlay->halted) {
- xfer_result_t xfer_result;
-
- if (qtd_overlay->xact_err || qtd_overlay->err_count == 0 || qtd_overlay->buffer_err || qtd_overlay->babble_err) {
- // Error count = 0 often occurs when device disconnected, or other bus-related error
- xfer_result = XFER_RESULT_FAILED;
- }else {
- // no error bits are set, endpoint is halted due to STALL
- xfer_result = XFER_RESULT_STALLED;
- }
-
-// if (XFER_RESULT_FAILED == xfer_result ) {
-// TU_LOG1(" QHD xfer err count: %d\n", qtd_overlay->err_count);
-// TU_BREAKPOINT(); // TODO skip unplugged device
-// }
-
- ehci_qtd_t * volatile qtd = (ehci_qtd_t * volatile) qhd->attached_qtd;
- TU_ASSERT(qtd, ); // No TD yet, probably a race condition or cache issue !?
-
- hcd_dcache_invalidate(qtd, sizeof(ehci_qtd_t));
-
- uint8_t dir = (qtd->pid == EHCI_PID_IN) ? 1 : 0;
- uint32_t const xferred_bytes = qtd->expected_bytes - qtd->total_bytes;
-
- // invalidate dcache if IN transfer
- if (dir == 1 && qhd->attached_buffer != 0 && xferred_bytes > 0) {
- hcd_dcache_invalidate((void*) qhd->attached_buffer, xferred_bytes);
- }
-
- // remove and free TD before invoking callback
- qhd->attached_qtd = NULL;
- qhd->attached_buffer = 0;
- qtd->used = 0; // free QTD
-
- if (0 == qhd->ep_number ) {
- // control cannot be halted
- qhd->qtd_overlay.next.terminate = 1;
- qhd->qtd_overlay.alternate.terminate = 1;
- qhd->qtd_overlay.halted = 0;
-
- hcd_dcache_clean(qhd, sizeof(ehci_qhd_t));
- }
-
- // notify usbh
- uint8_t const ep_addr = tu_edpt_addr(qhd->ep_number, dir);
- hcd_event_xfer_complete(qhd->dev_addr, ep_addr, xferred_bytes, xfer_result, true);
- }
-}
-
-TU_ATTR_ALWAYS_INLINE static inline
-void xfer_error_isr(uint8_t rhport)
-{
- //------------- async list -------------//
- ehci_qhd_t * const async_head = qhd_async_head(rhport);
- ehci_qhd_t *p_qhd = async_head;
- do
- {
- hcd_dcache_invalidate(p_qhd, sizeof(ehci_qhd_t));
- qhd_xfer_error_isr( p_qhd );
- p_qhd = qhd_next(p_qhd);
- }while(p_qhd != async_head); // async list traversal, stop if loop around
-
- //------------- TODO refractor period list -------------//
- uint32_t const period_1ms_addr = (uint32_t) get_period_head(rhport, 1u);
- for (uint32_t interval_ms=1; interval_ms <= FRAMELIST_SIZE; interval_ms *= 2)
- {
- ehci_link_t next_item = * get_period_head(rhport, interval_ms);
-
- // TODO abstract max loop guard for period
- while( !next_item.terminate &&
- !(interval_ms > 1 && period_1ms_addr == tu_align32(next_item.address)) )
- {
- switch ( next_item.type )
- {
- case EHCI_QTYPE_QHD:
- {
- ehci_qhd_t *p_qhd_int = (ehci_qhd_t *) tu_align32(next_item.address);
- hcd_dcache_invalidate(p_qhd_int, sizeof(ehci_qhd_t));
-
- qhd_xfer_error_isr(p_qhd_int);
- }
- break;
-
- // TODO support hs/fs ISO
- case EHCI_QTYPE_ITD:
- case EHCI_QTYPE_SITD:
- case EHCI_QTYPE_FSTN:
- default: break;
- }
-
- next_item = *list_next(&next_item);
- }
- }
-}
-
//------------- Host Controller Driver's Interrupt Handler -------------//
void hcd_int_handler(uint8_t rhport)
{
@@ -766,7 +676,7 @@ void hcd_int_handler(uint8_t rhport)
if (int_status & EHCI_INT_MASK_PORT_CHANGE) {
// Including: Force port resume, over-current change, enable/disable change and connect status change.
uint32_t const port_status = regs->portsc & EHCI_PORTSC_MASK_W1C;
- print_portsc(regs);
+ // print_portsc(regs);
if (regs->portsc_bm.connect_status_change) {
port_connect_status_change_isr(rhport);
@@ -776,29 +686,16 @@ void hcd_int_handler(uint8_t rhport)
regs->status = EHCI_INT_MASK_PORT_CHANGE; // Acknowledge
}
- if (int_status & EHCI_INT_MASK_ERROR) {
- xfer_error_isr(rhport);
- regs->status = EHCI_INT_MASK_ERROR; // Acknowledge
- }
-
- //------------- some QTD/SITD/ITD with IOC set is completed -------------//
- if (int_status & EHCI_INT_MASK_NXP_ASYNC) {
- async_list_xfer_complete_isr(qhd_async_head(rhport));
- regs->status = EHCI_INT_MASK_NXP_ASYNC; // Acknowledge
- }
+ // A USB transfer is completed (OK or error)
+ uint32_t const usb_int = int_status & (EHCI_INT_MASK_USB | EHCI_INT_MASK_ERROR);
+ if (usb_int) {
+ proccess_async_xfer_isr(list_get_async_head(rhport));
- if (int_status & EHCI_INT_MASK_NXP_PERIODIC)
- {
- for (uint32_t i=1; i <= FRAMELIST_SIZE; i *= 2)
- {
- period_list_xfer_complete_isr(rhport, i);
+ for ( uint32_t i = 1; i <= FRAMELIST_SIZE; i *= 2 ) {
+ process_period_xfer_isr(rhport, i);
}
- regs->status = EHCI_INT_MASK_NXP_PERIODIC; // Acknowledge
- }
- if (int_status & EHCI_INT_MASK_USB) {
- // TODO standard EHCI xfer complete
- regs->status = EHCI_INT_MASK_USB; // Acknowledge
+ regs->status = usb_int; // Acknowledge
}
//------------- There is some removed async previously -------------//
@@ -810,35 +707,103 @@ void hcd_int_handler(uint8_t rhport)
}
//--------------------------------------------------------------------+
-// HELPER
+// List Managing Helper
//--------------------------------------------------------------------+
+// Get head of periodic list
+TU_ATTR_ALWAYS_INLINE static inline ehci_link_t* list_get_period_head(uint8_t rhport, uint32_t interval_ms) {
+ (void) rhport;
+ return (ehci_link_t*) &ehci_data.period_head_arr[ tu_log2( tu_min32(FRAMELIST_SIZE, interval_ms) ) ];
+}
+
+// Get head of async list
+TU_ATTR_ALWAYS_INLINE static inline ehci_qhd_t* list_get_async_head(uint8_t rhport) {
+ (void) rhport;
+ return qhd_control(0); // control qhd of dev0 is used as async head
+}
+
+TU_ATTR_ALWAYS_INLINE static inline ehci_link_t* list_next(ehci_link_t const *p_link) {
+ return (ehci_link_t*) tu_align32(p_link->address);
+}
-//------------- queue head helper -------------//
-static inline ehci_qhd_t* qhd_find_free (void)
+TU_ATTR_ALWAYS_INLINE static inline void list_insert(ehci_link_t *current, ehci_link_t *new, uint8_t new_type)
{
- for (uint32_t i=0; i<QHD_MAX; i++)
- {
- if ( !ehci_data.qhd_pool[i].used ) return &ehci_data.qhd_pool[i];
+ new->address = current->address;
+ current->address = ((uint32_t) new) | (new_type << 1);
+}
+
+// Remove all queue head belong to this device address
+static void list_remove_qhd_by_daddr(ehci_link_t* list_head, uint8_t dev_addr) {
+ ehci_link_t* prev = list_head;
+
+ while (prev && !prev->terminate) {
+ ehci_qhd_t* qhd = (ehci_qhd_t*) (uintptr_t) list_next(prev);
+
+ // done if loop back to head
+ if ( (uintptr_t) qhd == (uintptr_t) list_head) {
+ break;
+ }
+
+ if ( qhd->dev_addr == dev_addr ) {
+ // TODO deactivate all TD, wait for QHD to inactive before removal
+ prev->address = qhd->next.address;
+
+ // EHCI 4.8.2 link the removed qhd's next to async head (which always reachable by Host Controller)
+ qhd->next.address = ((uint32_t) list_head) | (EHCI_QTYPE_QHD << 1);
+
+ if ( qhd->int_smask )
+ {
+ // period list queue element is guarantee to be free in the next frame (1 ms)
+ qhd->used = 0;
+ }else
+ {
+ // async list use async advance handshake
+ // mark as removing, will completely re-usable when async advance isr occurs
+ qhd->removing = 1;
+ }
+
+ hcd_dcache_clean(qhd, sizeof(ehci_qhd_t));
+ hcd_dcache_clean(prev, sizeof(ehci_qhd_t));
+ }else {
+ prev = list_next(prev);
+ }
}
+}
+
+
+//--------------------------------------------------------------------+
+// Queue Header helper
+//--------------------------------------------------------------------+
+
+// Get queue head for control transfer (always available)
+TU_ATTR_ALWAYS_INLINE static inline ehci_qhd_t* qhd_control(uint8_t dev_addr) {
+ return &ehci_data.control[dev_addr].qhd;
+}
+// Find a free queue head
+TU_ATTR_ALWAYS_INLINE static inline ehci_qhd_t *qhd_find_free(void) {
+ for ( uint32_t i = 0; i < QHD_MAX; i++ ) {
+ if ( !ehci_data.qhd_pool[i].used ) return &ehci_data.qhd_pool[i];
+ }
return NULL;
}
-static inline ehci_qhd_t* qhd_next(ehci_qhd_t const * p_qhd)
-{
- return (ehci_qhd_t*) tu_align32(p_qhd->next.address);
+// Next queue head link
+TU_ATTR_ALWAYS_INLINE static inline ehci_qhd_t *qhd_next(ehci_qhd_t const *p_qhd) {
+ return (ehci_qhd_t *) tu_align32(p_qhd->next.address);
}
-static inline ehci_qhd_t* qhd_get_from_addr(uint8_t dev_addr, uint8_t ep_addr)
-{
- ehci_qhd_t* qhd_pool = ehci_data.qhd_pool;
+// Get queue head from device + endpoint address
+static ehci_qhd_t *qhd_get_from_addr(uint8_t dev_addr, uint8_t ep_addr) {
+ if ( 0 == tu_edpt_number(ep_addr) ) {
+ return qhd_control(dev_addr);
+ }
- for(uint32_t i=0; i<QHD_MAX; i++)
- {
+ ehci_qhd_t *qhd_pool = ehci_data.qhd_pool;
+
+ for ( uint32_t i = 0; i < QHD_MAX; i++ ) {
if ( (qhd_pool[i].dev_addr == dev_addr) &&
- ep_addr == tu_edpt_addr(qhd_pool[i].ep_number, qhd_pool[i].pid) )
- {
+ ep_addr == tu_edpt_addr(qhd_pool[i].ep_number, qhd_pool[i].pid) ) {
return &qhd_pool[i];
}
}
@@ -846,6 +811,7 @@ static inline ehci_qhd_t* qhd_get_from_addr(uint8_t dev_addr, uint8_t ep_addr)
return NULL;
}
+// Init queue head with endpoint descriptor
static void qhd_init(ehci_qhd_t *p_qhd, uint8_t dev_addr, tusb_desc_endpoint_t const * ep_desc)
{
// address 0 is used as async head, which always on the list --> cannot be cleared (ehci halted otherwise)
@@ -920,6 +886,7 @@ static void qhd_init(ehci_qhd_t *p_qhd, uint8_t dev_addr, tusb_desc_endpoint_t c
}
}
+// Attach a TD to queue head
static void qhd_attach_qtd(ehci_qhd_t *qhd, ehci_qtd_t *qtd) {
qhd->attached_qtd = qtd;
qhd->attached_buffer = qtd->buffer[0];
@@ -931,17 +898,35 @@ static void qhd_attach_qtd(ehci_qhd_t *qhd, ehci_qtd_t *qtd) {
hcd_dcache_clean_invalidate(qhd, sizeof(ehci_qhd_t));
}
+// Remove an attached TD from queue head
+static void qhd_remove_qtd(ehci_qhd_t *qhd) {
+ ehci_qtd_t * volatile qtd = qhd->attached_qtd;
+
+ qhd->attached_qtd = NULL;
+ qhd->attached_buffer = 0;
+ hcd_dcache_clean(qhd, sizeof(ehci_qhd_t));
+
+ qtd->used = 0; // free QTD
+ hcd_dcache_clean(qtd, sizeof(ehci_qtd_t));
+}
+
+//--------------------------------------------------------------------+
+// Queue TD helper
+//--------------------------------------------------------------------+
+
+// Get TD for control transfer (always available)
+TU_ATTR_ALWAYS_INLINE static inline ehci_qtd_t* qtd_control(uint8_t dev_addr) {
+ return &ehci_data.control[dev_addr].qtd;
+}
-//------------- TD helper -------------//
-static inline ehci_qtd_t *qtd_find_free(void) {
+TU_ATTR_ALWAYS_INLINE static inline ehci_qtd_t *qtd_find_free(void) {
for (uint32_t i = 0; i < QTD_MAX; i++) {
if (!ehci_data.qtd_pool[i].used) return &ehci_data.qtd_pool[i];
}
return NULL;
}
-static void qtd_init(ehci_qtd_t* qtd, void const* buffer, uint16_t total_bytes)
-{
+static void qtd_init(ehci_qtd_t* qtd, void const* buffer, uint16_t total_bytes) {
tu_memclr(qtd, sizeof(ehci_qtd_t));
qtd->used = 1;
@@ -955,24 +940,9 @@ static void qtd_init(ehci_qtd_t* qtd, void const* buffer, uint16_t total_bytes)
qtd->expected_bytes = total_bytes;
qtd->buffer[0] = (uint32_t) buffer;
- for(uint8_t i=1; i<5; i++)
- {
+ for(uint8_t i=1; i<5; i++) {
qtd->buffer[i] |= tu_align4k(qtd->buffer[i - 1] ) + 4096;
}
}
-//------------- List Managing Helper -------------//
-
-// insert at head
-static inline void list_insert(ehci_link_t *current, ehci_link_t *new, uint8_t new_type)
-{
- new->address = current->address;
- current->address = ((uint32_t) new) | (new_type << 1);
-}
-
-static inline ehci_link_t* list_next(ehci_link_t const *p_link)
-{
- return (ehci_link_t*) tu_align32(p_link->address);
-}
-
#endif
diff --git a/src/portable/ehci/ehci.h b/src/portable/ehci/ehci.h
index 8338fb419..457adc1d3 100644
--- a/src/portable/ehci/ehci.h
+++ b/src/portable/ehci/ehci.h
@@ -278,23 +278,24 @@ enum {
EHCI_INT_MASK_PERIODIC_SCHED_STATUS = TU_BIT(14),
EHCI_INT_MASK_ASYNC_SCHED_STATUS = TU_BIT(15),
- EHCI_INT_MASK_NXP_ASYNC = TU_BIT(18),
- EHCI_INT_MASK_NXP_PERIODIC = TU_BIT(19),
-
EHCI_INT_MASK_ALL =
EHCI_INT_MASK_USB | EHCI_INT_MASK_ERROR | EHCI_INT_MASK_PORT_CHANGE |
EHCI_INT_MASK_FRAMELIST_ROLLOVER | EHCI_INT_MASK_PCI_HOST_SYSTEM_ERROR |
- EHCI_INT_MASK_ASYNC_ADVANCE | EHCI_INT_MASK_NXP_SOF |
- EHCI_INT_MASK_NXP_ASYNC | EHCI_INT_MASK_NXP_PERIODIC
+ EHCI_INT_MASK_ASYNC_ADVANCE | EHCI_INT_MASK_NXP_SOF
+};
+
+enum {
+ EHCI_USBCMD_FRAMELIST_SIZE_SHIFT = 2, // [2..3]
+ EHCI_USBCMD_CHIPIDEA_FRAMELIST_SIZE_MSB_SHIFT = 15,
+ EHCI_USBCMD_INTERRUPT_THRESHOLD_SHIFT = 16
};
enum {
- EHCI_USBCMD_POS_RUN_STOP = 0,
- EHCI_USBCMD_POS_FRAMELIST_SIZE = 2,
- EHCI_USBCMD_POS_PERIOD_ENABLE = 4,
- EHCI_USBCMD_POS_ASYNC_ENABLE = 5,
- EHCI_USBCMD_POS_NXP_FRAMELIST_SIZE_MSB = 15,
- EHCI_USBCMD_POS_INTERRUPT_THRESHOLD = 16
+ EHCI_USBCMD_RUN_STOP = TU_BIT(0), // [0..0] 1 = Run, 0 = Stop
+ EHCI_USBCMD_HCRESET = TU_BIT(1), // [1..1] SW write 1 to reset HC, clear by HC when complete
+ EHCI_USBCMD_PERIOD_SCHEDULE_ENABLE = TU_BIT(4), // [4..4] Enable periodic schedule
+ EHCI_USBCMD_ASYNC_SCHEDULE_ENABLE = TU_BIT(5), // [5..5] Enable async schedule
+ EHCI_USBCMD_INTR_ON_ASYNC_ADVANCE_DOORBELL = TU_BIT(6), // [6..6] Tell HC to interrupt next time it advances async list. Clear by HC
};
enum {
@@ -306,7 +307,7 @@ enum {
EHCI_PORTSC_MASK_FORCE_RESUME = TU_BIT(6),
EHCI_PORTSC_MASK_PORT_SUSPEND = TU_BIT(7),
EHCI_PORTSC_MASK_PORT_RESET = TU_BIT(8),
- ECHI_PORTSC_MASK_PORT_POWER = TU_BIT(12),
+ EHCI_PORTSC_MASK_PORT_POWER = TU_BIT(12),
EHCI_PORTSC_MASK_W1C =
EHCI_PORTSC_MASK_CONNECT_STATUS_CHANGE |
diff --git a/src/portable/mentor/musb/dcd_musb.c b/src/portable/mentor/musb/dcd_musb.c
index 487761847..3c0114e41 100644
--- a/src/portable/mentor/musb/dcd_musb.c
+++ b/src/portable/mentor/musb/dcd_musb.c
@@ -317,7 +317,7 @@ static bool handle_xfer_in(uint_fast8_t ep_addr)
const unsigned mps = regs->TXMAXP;
const unsigned len = TU_MIN(mps, rem);
void *buf = pipe->buf;
- // TU_LOG1(" %p mps %d len %d rem %d\n", buf, mps, len, rem);
+ // TU_LOG1(" %p mps %d len %d rem %d\r\n", buf, mps, len, rem);
if (len) {
if (_dcd.pipe_buf_is_fifo[TUSB_DIR_IN] & TU_BIT(epnum_minus1)) {
pipe_read_write_packet_ff(buf, &USB0->FIFO1_WORD + epnum_minus1, len, TUSB_DIR_IN);
@@ -328,7 +328,7 @@ static bool handle_xfer_in(uint_fast8_t ep_addr)
pipe->remaining = rem - len;
}
regs->TXCSRL = USB_TXCSRL1_TXRDY;
- // TU_LOG1(" TXCSRL%d = %x %d\n", epnum_minus1 + 1, regs->TXCSRL, rem - len);
+ // TU_LOG1(" TXCSRL%d = %x %d\r\n", epnum_minus1 + 1, regs->TXCSRL, rem - len);
return false;
}
@@ -337,7 +337,7 @@ static bool handle_xfer_out(uint_fast8_t ep_addr)
unsigned epnum_minus1 = tu_edpt_number(ep_addr) - 1;
pipe_state_t *pipe = &_dcd.pipe[tu_edpt_dir(ep_addr)][epnum_minus1];
volatile hw_endpoint_t *regs = edpt_regs(epnum_minus1);
- // TU_LOG1(" RXCSRL%d = %x\n", epnum_minus1 + 1, regs->RXCSRL);
+ // TU_LOG1(" RXCSRL%d = %x\r\n", epnum_minus1 + 1, regs->RXCSRL);
TU_ASSERT(regs->RXCSRL & USB_RXCSRL1_RXRDY);
@@ -399,14 +399,14 @@ static bool edpt0_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_
* may have already finished and received the next setup packet
* without calling this function, so we have no choice but to
* invoke the callback function of status packet here. */
- // TU_LOG1(" STATUS OUT USB0->CSRL0 = %x\n", USB0->CSRL0);
+ // TU_LOG1(" STATUS OUT USB0->CSRL0 = %x\r\n", USB0->CSRL0);
_dcd.status_out = 0;
if (req == REQUEST_TYPE_INVALID) {
dcd_event_xfer_complete(rhport, ep_addr, total_bytes, XFER_RESULT_SUCCESS, false);
} else {
/* The next setup packet has already been received, it aborts
* invoking callback function to avoid confusing TUSB stack. */
- TU_LOG1("Drop CONTROL_STAGE_ACK\n");
+ TU_LOG1("Drop CONTROL_STAGE_ACK\r\n");
}
return true;
}
@@ -431,16 +431,16 @@ static bool edpt0_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_
} else {
USB0->CSRL0 = USB_CSRL0_TXRDY; /* Flush TX FIFO to return ACK. */
}
- // TU_LOG1(" IN USB0->CSRL0 = %x\n", USB0->CSRL0);
+ // TU_LOG1(" IN USB0->CSRL0 = %x\r\n", USB0->CSRL0);
} else {
- // TU_LOG1(" OUT USB0->CSRL0 = %x\n", USB0->CSRL0);
+ // TU_LOG1(" OUT USB0->CSRL0 = %x\r\n", USB0->CSRL0);
_dcd.pipe0.buf = buffer;
_dcd.pipe0.length = len;
_dcd.pipe0.remaining = len;
USB0->CSRL0 = USB_CSRL0_RXRDYC; /* Clear RX FIFO to return ACK. */
}
} else if (dir_in) {
- // TU_LOG1(" STATUS IN USB0->CSRL0 = %x\n", USB0->CSRL0);
+ // TU_LOG1(" STATUS IN USB0->CSRL0 = %x\r\n", USB0->CSRL0);
_dcd.pipe0.buf = NULL;
_dcd.pipe0.length = 0;
_dcd.pipe0.remaining = 0;
@@ -454,7 +454,7 @@ static void process_ep0(uint8_t rhport)
{
uint_fast8_t csrl = USB0->CSRL0;
- // TU_LOG1(" EP0 USB0->CSRL0 = %x\n", csrl);
+ // TU_LOG1(" EP0 USB0->CSRL0 = %x\r\n", csrl);
if (csrl & USB_CSRL0_STALLED) {
/* Returned STALL packet to HOST. */
@@ -464,7 +464,7 @@ static void process_ep0(uint8_t rhport)
unsigned req = _dcd.setup_packet.bmRequestType;
if (csrl & USB_CSRL0_SETEND) {
- TU_LOG1(" ABORT by the next packets\n");
+ TU_LOG1(" ABORT by the next packets\r\n");
USB0->CSRL0 = USB_CSRL0_SETENDC;
if (req != REQUEST_TYPE_INVALID && _dcd.pipe0.buf) {
/* DATA stage was aborted by receiving STATUS or SETUP packet. */
@@ -539,14 +539,14 @@ static void process_edpt_n(uint8_t rhport, uint_fast8_t ep_addr)
volatile hw_endpoint_t *regs = edpt_regs(epn_minus1);
if (dir_in) {
- // TU_LOG1(" TXCSRL%d = %x\n", epn_minus1 + 1, regs->TXCSRL);
+ // TU_LOG1(" TXCSRL%d = %x\r\n", epn_minus1 + 1, regs->TXCSRL);
if (regs->TXCSRL & USB_TXCSRL1_STALLED) {
regs->TXCSRL &= ~(USB_TXCSRL1_STALLED | USB_TXCSRL1_UNDRN);
return;
}
completed = handle_xfer_in(ep_addr);
} else {
- // TU_LOG1(" RXCSRL%d = %x\n", epn_minus1 + 1, regs->RXCSRL);
+ // TU_LOG1(" RXCSRL%d = %x\r\n", epn_minus1 + 1, regs->RXCSRL);
if (regs->RXCSRL & USB_RXCSRL1_STALLED) {
regs->RXCSRL &= ~(USB_RXCSRL1_STALLED | USB_RXCSRL1_OVER);
return;
@@ -789,7 +789,7 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t t
{
(void)rhport;
bool ret;
- // TU_LOG1("X %x %d\n", ep_addr, total_bytes);
+ // TU_LOG1("X %x %d\r\n", ep_addr, total_bytes);
unsigned const epnum = tu_edpt_number(ep_addr);
unsigned const ie = NVIC_GetEnableIRQ(USB0_IRQn);
NVIC_DisableIRQ(USB0_IRQn);
@@ -807,7 +807,7 @@ bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_
{
(void)rhport;
bool ret;
- // TU_LOG1("X %x %d\n", ep_addr, total_bytes);
+ // TU_LOG1("X %x %d\r\n", ep_addr, total_bytes);
unsigned const epnum = tu_edpt_number(ep_addr);
TU_ASSERT(epnum);
unsigned const ie = NVIC_GetEnableIRQ(USB0_IRQn);
@@ -869,7 +869,7 @@ void dcd_int_handler(uint8_t rhport)
is = USB0->IS; /* read and clear interrupt status */
txis = USB0->TXIS; /* read and clear interrupt status */
rxis = USB0->RXIS; /* read and clear interrupt status */
- // TU_LOG1("D%2x T%2x R%2x\n", is, txis, rxis);
+ // TU_LOG1("D%2x T%2x R%2x\r\n", is, txis, rxis);
is &= USB0->IE; /* Clear disabled interrupts */
if (is & USB_IS_DISCON) {
diff --git a/src/portable/mentor/musb/hcd_musb.c b/src/portable/mentor/musb/hcd_musb.c
index 9eb2e005e..02090df85 100644
--- a/src/portable/mentor/musb/hcd_musb.c
+++ b/src/portable/mentor/musb/hcd_musb.c
@@ -418,7 +418,7 @@ static void process_ep0(uint8_t rhport)
(void)rhport;
uint_fast8_t csrl = USB0->CSRL0;
- // TU_LOG1(" EP0 CSRL = %x\n", csrl);
+ // TU_LOG1(" EP0 CSRL = %x\r\n", csrl);
unsigned const dev_addr = USB0->TXFUNCADDR0;
unsigned const req = _hcd.bmRequestType;
@@ -508,7 +508,7 @@ static void process_pipe_tx(uint8_t rhport, uint_fast8_t pipenum)
volatile hw_endpoint_t *regs = edpt_regs(pipenum - 1);
unsigned const csrl = regs->TXCSRL;
- // TU_LOG1(" TXCSRL%d = %x\n", pipenum, csrl);
+ // TU_LOG1(" TXCSRL%d = %x\r\n", pipenum, csrl);
if (csrl & (USB_TXCSRL1_STALLED | USB_TXCSRL1_ERROR)) {
if (csrl & USB_TXCSRL1_TXRDY)
regs->TXCSRL = (csrl & ~(USB_TXCSRL1_STALLED | USB_TXCSRL1_ERROR)) | USB_TXCSRL1_FLUSH;
@@ -537,7 +537,7 @@ static void process_pipe_rx(uint8_t rhport, uint_fast8_t pipenum)
volatile hw_endpoint_t *regs = edpt_regs(pipenum - 1);
unsigned const csrl = regs->RXCSRL;
- // TU_LOG1(" RXCSRL%d = %x\n", pipenum, csrl);
+ // TU_LOG1(" RXCSRL%d = %x\r\n", pipenum, csrl);
if (csrl & (USB_RXCSRL1_STALLED | USB_RXCSRL1_ERROR)) {
if (csrl & USB_RXCSRL1_RXRDY)
regs->RXCSRL = (csrl & ~(USB_RXCSRL1_STALLED | USB_RXCSRL1_ERROR)) | USB_RXCSRL1_FLUSH;
@@ -822,9 +822,17 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *b
return ret;
}
+bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) {
+ (void) rhport;
+ (void) dev_addr;
+ (void) ep_addr;
+ // TODO not implemented yet
+ return false;
+}
+
// clear stall, data toggle is also reset to DATA0
-bool hcd_edpt_clear_stall(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;
unsigned const pipenum = find_pipe(dev_addr, ep_addr);
if (!pipenum) return false;
hw_endpoint_t volatile *regs = edpt_regs(pipenum - 1);
@@ -846,7 +854,7 @@ void hcd_int_handler(uint8_t rhport)
is = USB0->IS; /* read and clear interrupt status */
txis = USB0->TXIS; /* read and clear interrupt status */
rxis = USB0->RXIS; /* read and clear interrupt status */
- // TU_LOG1("D%2x T%2x R%2x\n", is, txis, rxis);
+ // TU_LOG1("D%2x T%2x R%2x\r\n", is, txis, rxis);
is &= USB0->IE; /* Clear disabled interrupts */
if (is & USB_IS_RESUME) {
diff --git a/src/portable/microchip/pic/dcd_pic.c b/src/portable/microchip/pic/dcd_pic.c
index 6986c8317..ccc27c3c9 100644
--- a/src/portable/microchip/pic/dcd_pic.c
+++ b/src/portable/microchip/pic/dcd_pic.c
@@ -189,7 +189,7 @@ typedef struct
// INTERNAL OBJECT & FUNCTION DECLARATION
//--------------------------------------------------------------------+
// BDT(Buffer Descriptor Table) must be 256-byte aligned
-CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(512) volatile static dcd_data_t _dcd;
+CFG_TUD_MEM_SECTION TU_ATTR_ALIGNED(512) volatile static dcd_data_t _dcd;
#if TU_PIC_INT_SIZE == 4
TU_VERIFY_STATIC( sizeof(_dcd.bdt) == 512, "size is not correct" );
diff --git a/src/portable/microchip/samx7x/dcd_samx7x.c b/src/portable/microchip/samx7x/dcd_samx7x.c
index 2bbb345d6..9586df84d 100644
--- a/src/portable/microchip/samx7x/dcd_samx7x.c
+++ b/src/portable/microchip/samx7x/dcd_samx7x.c
@@ -77,7 +77,7 @@ static tusb_speed_t get_speed(void);
static void dcd_transmit_packet(xfer_ctl_t * xfer, uint8_t ep_ix);
// DMA descriptors shouldn't be placed in ITCM !
-CFG_TUSB_MEM_SECTION static dma_desc_t dma_desc[6];
+CFG_TUD_MEM_SECTION static dma_desc_t dma_desc[6];
static xfer_ctl_t xfer_status[EP_MAX];
diff --git a/src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c b/src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c
index 39b09db68..c3d0c7297 100644
--- a/src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c
+++ b/src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c
@@ -110,7 +110,7 @@ typedef struct
// INTERNAL OBJECT & FUNCTION DECLARATION
//--------------------------------------------------------------------+
// BDT(Buffer Descriptor Table) must be 256-byte aligned
-CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(512) static dcd_data_t _dcd;
+CFG_TUD_MEM_SECTION TU_ATTR_ALIGNED(512) static dcd_data_t _dcd;
TU_VERIFY_STATIC( sizeof(_dcd.bdt) == 512, "size is not correct" );
diff --git a/src/portable/nxp/khci/dcd_khci.c b/src/portable/nxp/khci/dcd_khci.c
index 2293d1b59..5a2f768b3 100644
--- a/src/portable/nxp/khci/dcd_khci.c
+++ b/src/portable/nxp/khci/dcd_khci.c
@@ -114,7 +114,7 @@ typedef struct
// INTERNAL OBJECT & FUNCTION DECLARATION
//--------------------------------------------------------------------+
// BDT(Buffer Descriptor Table) must be 256-byte aligned
-CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(512) static dcd_data_t _dcd;
+CFG_TUD_MEM_SECTION TU_ATTR_ALIGNED(512) static dcd_data_t _dcd;
TU_VERIFY_STATIC( sizeof(_dcd.bdt) == 512, "size is not correct" );
diff --git a/src/portable/nxp/khci/hcd_khci.c b/src/portable/nxp/khci/hcd_khci.c
index f6029ee0d..55327e02d 100644
--- a/src/portable/nxp/khci/hcd_khci.c
+++ b/src/portable/nxp/khci/hcd_khci.c
@@ -161,7 +161,7 @@ static int prepare_packets(int pipenum)
buffer_descriptor_t *bd = _hcd.bdt[dir_tx];
TU_ASSERT(0 == bd[odd].own, -1);
- // TU_LOG1(" %p dir %d odd %d data %d\n", &bd[odd], dir_tx, odd, pipe->data);
+ // TU_LOG1(" %p dir %d odd %d data %d\r\n", &bd[odd], dir_tx, odd, pipe->data);
ep->pipenum = pipenum;
@@ -251,7 +251,7 @@ static bool resume_transfer(int pipenum)
flags |= USB_ENDPT_EPHSHK_MASK | USB_ENDPT_EPCTLDIS_MASK | USB_ENDPT_RETRYDIS_MASK;
break;
}
- // TU_LOG1(" resume pipenum %d flags %x\n", pipenum, flags);
+ // TU_LOG1(" resume pipenum %d flags %x\r\n", pipenum, flags);
KHCI->ENDPOINT[0].ENDPT = flags;
KHCI->ADDR = (KHCI->ADDR & USB_ADDR_LSEN_MASK) | pipe->dev_addr;
@@ -302,7 +302,7 @@ static void process_tokdne(uint8_t rhport)
int pipenum = ep->pipenum;
int next_pipenum;
- // TU_LOG1("TOKDNE %x PID %x pipe %d\n", s, pid, pipenum);
+ // TU_LOG1("TOKDNE %x PID %x pipe %d\r\n", s, pid, pipenum);
xfer_result_t result;
switch (pid) {
@@ -479,7 +479,7 @@ 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_LOG1("SETUP %u\n", dev_addr);
+ // TU_LOG1("SETUP %u\r\n", dev_addr);
TU_ASSERT(0 == (_hcd.in_progress & TU_BIT(0)));
int pipenum = find_pipe(dev_addr, 0);
@@ -510,7 +510,7 @@ bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const
{
(void)rhport;
uint8_t const ep_addr = ep_desc->bEndpointAddress;
- // TU_LOG1("O %u %x\n", dev_addr, ep_addr);
+ // TU_LOG1("O %u %x\r\n", dev_addr, ep_addr);
/* Find a free pipe */
pipe_state_t *p = &_hcd.pipe[0];
pipe_state_t *end = &_hcd.pipe[CFG_TUH_ENDPOINT_MAX * 2];
@@ -543,7 +543,7 @@ bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const
bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t buflen)
{
(void)rhport;
- // TU_LOG1("X %u %x %x %d\n", dev_addr, ep_addr, (uintptr_t)buffer, buflen);
+ // TU_LOG1("X %u %x %x %d\r\n", dev_addr, ep_addr, (uintptr_t)buffer, buflen);
int pipenum = find_pipe(dev_addr, ep_addr);
TU_ASSERT(0 <= pipenum);
@@ -562,8 +562,16 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *
return true;
}
-bool hcd_edpt_clear_stall(uint8_t dev_addr, uint8_t ep_addr)
-{
+bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) {
+ (void) rhport;
+ (void) dev_addr;
+ (void) ep_addr;
+ // TODO not implemented yet
+ return false;
+}
+
+bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) {
+ (void) rhport;
if (!tu_edpt_number(ep_addr)) return true;
int num = find_pipe(dev_addr, ep_addr);
if (num < 0) return false;
@@ -580,7 +588,7 @@ void hcd_int_handler(uint8_t rhport)
uint32_t is = KHCI->ISTAT;
uint32_t msk = KHCI->INTEN;
- // TU_LOG1("S %lx\n", is);
+ // TU_LOG1("S %lx\r\n", is);
/* clear disabled interrupts */
KHCI->ISTAT = (is & ~msk & ~USB_ISTAT_TOKDNE_MASK) | USB_ISTAT_SOFTOK_MASK;
@@ -589,7 +597,7 @@ void hcd_int_handler(uint8_t rhport)
if (is & USB_ISTAT_ERROR_MASK) {
unsigned err = KHCI->ERRSTAT;
if (err) {
- TU_LOG1(" ERR %x\n", err);
+ TU_LOG1(" ERR %x\r\n", err);
KHCI->ERRSTAT = err;
} else {
KHCI->INTEN &= ~USB_ISTAT_ERROR_MASK;
diff --git a/src/portable/nxp/lpc17_40/dcd_lpc17_40.c b/src/portable/nxp/lpc17_40/dcd_lpc17_40.c
index 86149afd8..b880c2870 100644
--- a/src/portable/nxp/lpc17_40/dcd_lpc17_40.c
+++ b/src/portable/nxp/lpc17_40/dcd_lpc17_40.c
@@ -92,7 +92,7 @@ typedef struct
} dcd_data_t;
-CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(128) static dcd_data_t _dcd;
+CFG_TUD_MEM_SECTION TU_ATTR_ALIGNED(128) static dcd_data_t _dcd;
//--------------------------------------------------------------------+
diff --git a/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c b/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c
index 5368ef868..f4ed09d83 100644
--- a/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c
+++ b/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c
@@ -34,18 +34,13 @@
* - LPC54114
* - LPC55s69
*/
-#if CFG_TUD_ENABLED && ( CFG_TUSB_MCU == OPT_MCU_LPC11UXX || \
- CFG_TUSB_MCU == OPT_MCU_LPC13XX || \
- CFG_TUSB_MCU == OPT_MCU_LPC15XX || \
- CFG_TUSB_MCU == OPT_MCU_LPC51UXX || \
- CFG_TUSB_MCU == OPT_MCU_LPC54XXX || \
- CFG_TUSB_MCU == OPT_MCU_LPC55XX)
+#if CFG_TUD_ENABLED && defined(TUP_USBIP_IP3511)
//--------------------------------------------------------------------+
// INCLUDE
//--------------------------------------------------------------------+
-#if CFG_TUSB_MCU == OPT_MCU_LPC11UXX || CFG_TUSB_MCU == OPT_MCU_LPC13XX || CFG_TUSB_MCU == OPT_MCU_LPC15XX
+#if TU_CHECK_MCU(OPT_MCU_LPC11UXX, OPT_MCU_LPC13XX, OPT_MCU_LPC15XX)
// LPCOpen
#include "chip.h"
#else
@@ -80,7 +75,7 @@ typedef struct {
enum {
NBYTES_ISO_FS_MAX = 1023, // FS ISO
NBYTES_ISO_HS_MAX = 1024, // HS ISO
- NBYTES_CBI_FS_MAX = 64, // FS control/bulk/interrupt
+ NBYTES_CBI_FS_MAX = 64, // FS control/bulk/interrupt. TODO some FS can do burst with higher size e.g 1024. Need to test
NBYTES_CBI_HS_MAX = 32767 // can be up to all 15-bit, but only tested with 4096
};
@@ -90,26 +85,36 @@ enum {
};
enum {
- CMDSTAT_DEVICE_ADDR_MASK = TU_BIT(7 )-1,
- CMDSTAT_DEVICE_ENABLE_MASK = TU_BIT(7 ),
- CMDSTAT_SETUP_RECEIVED_MASK = TU_BIT(8 ),
- CMDSTAT_DEVICE_CONNECT_MASK = TU_BIT(16), // reflect the soft-connect only, does not reflect the actual attached state
- CMDSTAT_DEVICE_SUSPEND_MASK = TU_BIT(17),
- // 23-22 is link speed (only available for HighSpeed port)
- CMDSTAT_CONNECT_CHANGE_MASK = TU_BIT(24),
- CMDSTAT_SUSPEND_CHANGE_MASK = TU_BIT(25),
- CMDSTAT_RESET_CHANGE_MASK = TU_BIT(26),
- CMDSTAT_VBUS_DEBOUNCED_MASK = TU_BIT(28),
+ DEVCMDSTAT_DEVICE_ADDR_MASK = TU_BIT(7 )-1,
+ DEVCMDSTAT_DEVICE_ENABLE_MASK = TU_BIT(7 ),
+ DEVCMDSTAT_SETUP_RECEIVED_MASK = TU_BIT(8 ),
+ DEVCMDSTAT_DEVICE_CONNECT_MASK = TU_BIT(16), // reflect the soft-connect only, does not reflect the actual attached state
+ DEVCMDSTAT_DEVICE_SUSPEND_MASK = TU_BIT(17),
+ // 23-22 is link speed (only available for HighSpeed port)
+ DEVCMDSTAT_CONNECT_CHANGE_MASK = TU_BIT(24),
+ DEVCMDSTAT_SUSPEND_CHANGE_MASK = TU_BIT(25),
+ DEVCMDSTAT_RESET_CHANGE_MASK = TU_BIT(26),
+ DEVCMDSTAT_VBUS_DEBOUNCED_MASK = TU_BIT(28),
};
enum {
- CMDSTAT_SPEED_SHIFT = 22
+ DEVCMDSTAT_SPEED_SHIFT = 22
};
//--------------------------------------------------------------------+
// Endpoint Command/Status List
//--------------------------------------------------------------------+
+// EP Command/Status field definition
+enum {
+ EPCS_TYPE = TU_BIT(26),
+ EPCS_RF_TV = TU_BIT(27),
+ EPCS_TOGGLE_RESET = TU_BIT(28),
+ EPCS_STALL = TU_BIT(29),
+ EPCS_DISABLED = TU_BIT(30),
+ EPCS_ACTIVE = TU_BIT(31),
+};
+
// Endpoint Command/Status
typedef union TU_ATTR_PACKED
{
@@ -133,8 +138,8 @@ typedef union TU_ATTR_PACKED
volatile struct {
uint32_t TU_RESERVED : 26;
- uint32_t is_iso : 1 ;
- uint32_t toggle_mode : 1 ;
+ uint32_t type : 1 ;
+ uint32_t rf_tv : 1 ; // rate feedback or toggle value
uint32_t toggle_reset : 1 ;
uint32_t stall : 1 ;
uint32_t disable : 1 ;
@@ -176,11 +181,12 @@ typedef struct
// EP list must be 256-byte aligned
// Some MCU controller may require this variable to be placed in specific SRAM region.
// For example: LPC55s69 port1 Highspeed must be USB_RAM (0x40100000)
-// Use CFG_TUSB_MEM_SECTION to place it accordingly.
-CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(256) static dcd_data_t _dcd;
+// Use CFG_TUD_MEM_SECTION to place it accordingly.
+CFG_TUD_MEM_SECTION TU_ATTR_ALIGNED(256) static dcd_data_t _dcd;
// Dummy buffer to fix ZLPs overwriting the buffer (probably an USB/DMA controller bug)
-CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(64) static uint8_t dummy[8];
+// TODO find way to save memory
+CFG_TUD_MEM_SECTION TU_ATTR_ALIGNED(64) static uint8_t dummy[8];
//--------------------------------------------------------------------+
// Multiple Controllers
@@ -188,59 +194,73 @@ CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(64) static uint8_t dummy[8];
typedef struct
{
- dcd_registers_t* regs; // registers
- const tusb_speed_t max_speed; // max link speed
- const IRQn_Type irqnum; // IRQ number
- const uint8_t ep_pairs; // Max bi-directional Endpoints
+ dcd_registers_t* regs; // registers
+ const bool is_highspeed; // max link speed
+ const IRQn_Type irqnum; // IRQ number
+ const uint8_t ep_pairs; // Max bi-directional Endpoints
}dcd_controller_t;
#ifdef INCLUDE_FSL_DEVICE_REGISTERS
-static const dcd_controller_t _dcd_controller[] =
-{
- { .regs = (dcd_registers_t*) USB0_BASE , .max_speed = TUSB_SPEED_FULL, .irqnum = USB0_IRQn, .ep_pairs = FSL_FEATURE_USB_EP_NUM },
+static const dcd_controller_t _dcd_controller[] = {
+ { .regs = (dcd_registers_t*) USB0_BASE , .is_highspeed = false, .irqnum = USB0_IRQn, .ep_pairs = FSL_FEATURE_USB_EP_NUM },
#if defined(FSL_FEATURE_SOC_USBHSD_COUNT) && FSL_FEATURE_SOC_USBHSD_COUNT
- { .regs = (dcd_registers_t*) USBHSD_BASE, .max_speed = TUSB_SPEED_HIGH, .irqnum = USB1_IRQn, .ep_pairs = FSL_FEATURE_USBHSD_EP_NUM }
+ { .regs = (dcd_registers_t*) USBHSD_BASE, .is_highspeed = true, .irqnum = USB1_IRQn, .ep_pairs = FSL_FEATURE_USBHSD_EP_NUM }
#endif
};
#else
-static const dcd_controller_t _dcd_controller[] =
-{
- { .regs = (dcd_registers_t*) LPC_USB0_BASE, .max_speed = TUSB_SPEED_FULL, .irqnum = USB0_IRQn, .ep_pairs = 5 },
+static const dcd_controller_t _dcd_controller[] = {
+ { .regs = (dcd_registers_t*) LPC_USB0_BASE, .is_highspeed = false, .irqnum = USB0_IRQn, .ep_pairs = 5 },
};
#endif
+#if defined(FSL_FEATURE_SOC_USBHSD_COUNT) && FSL_FEATURE_SOC_USBHSD_COUNT
+ #define IP3511_HAS_HIGHSPEED
+#endif
+
//--------------------------------------------------------------------+
// INTERNAL OBJECT & FUNCTION DECLARATION
//--------------------------------------------------------------------+
-static inline uint16_t get_buf_offset(void const * buffer)
-{
+TU_ATTR_ALWAYS_INLINE static inline uint16_t get_buf_offset(void const * buffer) {
uint32_t addr = (uint32_t) buffer;
TU_ASSERT( (addr & 0x3f) == 0, 0 );
return ( (addr >> 6) & 0xFFFFUL ) ;
}
-static inline uint8_t ep_addr2id(uint8_t ep_addr)
-{
+TU_ATTR_ALWAYS_INLINE static inline uint8_t ep_addr2id(uint8_t ep_addr) {
return 2*(ep_addr & 0x0F) + ((ep_addr & TUSB_DIR_IN_MASK) ? 1 : 0);
}
+TU_ATTR_ALWAYS_INLINE static inline bool ep_is_iso(ep_cmd_sts_t* ep_cs, bool is_highspeed) {
+ return is_highspeed ? (ep_cs[0].cmd_sts.type && !ep_cs[0].cmd_sts.rf_tv) : ep_cs->cmd_sts.type;
+}
+
+TU_ATTR_ALWAYS_INLINE static inline bool ep_is_bulk(ep_cmd_sts_t* ep_cs) {
+ return (ep_cs[0].cmd_sts.type == 0) && (ep_cs[0].cmd_sts.rf_tv == 0);
+}
+
+TU_ATTR_ALWAYS_INLINE static inline ep_cmd_sts_t* get_ep_cs(uint8_t ep_id) {
+ return _dcd.ep[ep_id];
+}
+
+TU_ATTR_ALWAYS_INLINE static inline bool rhport_is_highspeed(uint8_t rhport) {
+ return _dcd_controller[rhport].is_highspeed;
+}
+
//--------------------------------------------------------------------+
// CONTROLLER API
//--------------------------------------------------------------------+
-static void prepare_setup_packet(uint8_t rhport)
-{
- if (_dcd_controller[rhport].max_speed == TUSB_SPEED_FULL )
- {
- _dcd.ep[0][1].buffer_fs.offset = get_buf_offset(_dcd.setup_packet);
- }else
- {
- _dcd.ep[0][1].buffer_hs.offset = get_buf_offset(_dcd.setup_packet);
+static void prepare_setup_packet(uint8_t rhport) {
+ uint16_t const buf_offset = get_buf_offset(_dcd.setup_packet);
+ if ( _dcd_controller[rhport].is_highspeed ) {
+ _dcd.ep[0][1].buffer_hs.offset = buf_offset;
+ } else {
+ _dcd.ep[0][1].buffer_fs.offset = buf_offset;
}
}
@@ -268,8 +288,8 @@ void dcd_init(uint8_t rhport)
dcd_reg->DATABUFSTART = tu_align((uint32_t) &_dcd, TU_BIT(22)); // 22-bit alignment
dcd_reg->INTSTAT |= dcd_reg->INTSTAT; // clear all pending interrupt
dcd_reg->INTEN = INT_DEVICE_STATUS_MASK;
- dcd_reg->DEVCMDSTAT |= CMDSTAT_DEVICE_ENABLE_MASK | CMDSTAT_DEVICE_CONNECT_MASK |
- CMDSTAT_RESET_CHANGE_MASK | CMDSTAT_CONNECT_CHANGE_MASK | CMDSTAT_SUSPEND_CHANGE_MASK;
+ dcd_reg->DEVCMDSTAT |= DEVCMDSTAT_DEVICE_ENABLE_MASK | DEVCMDSTAT_DEVICE_CONNECT_MASK |
+ DEVCMDSTAT_RESET_CHANGE_MASK | DEVCMDSTAT_CONNECT_CHANGE_MASK | DEVCMDSTAT_SUSPEND_CHANGE_MASK;
NVIC_ClearPendingIRQ(_dcd_controller[rhport].irqnum);
}
@@ -291,7 +311,7 @@ void dcd_set_address(uint8_t rhport, uint8_t dev_addr)
// Response with status first before changing device address
dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0);
- dcd_reg->DEVCMDSTAT &= ~CMDSTAT_DEVICE_ADDR_MASK;
+ dcd_reg->DEVCMDSTAT &= ~DEVCMDSTAT_DEVICE_ADDR_MASK;
dcd_reg->DEVCMDSTAT |= dev_addr;
}
@@ -303,13 +323,13 @@ void dcd_remote_wakeup(uint8_t rhport)
void dcd_connect(uint8_t rhport)
{
dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs;
- dcd_reg->DEVCMDSTAT |= CMDSTAT_DEVICE_CONNECT_MASK;
+ dcd_reg->DEVCMDSTAT |= DEVCMDSTAT_DEVICE_CONNECT_MASK;
}
void dcd_disconnect(uint8_t rhport)
{
dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs;
- dcd_reg->DEVCMDSTAT &= ~CMDSTAT_DEVICE_CONNECT_MASK;
+ dcd_reg->DEVCMDSTAT &= ~DEVCMDSTAT_DEVICE_CONNECT_MASK;
}
void dcd_sof_enable(uint8_t rhport, bool en)
@@ -340,19 +360,39 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr)
_dcd.ep[ep_id][0].cmd_sts.stall = 0;
_dcd.ep[ep_id][0].cmd_sts.toggle_reset = 1;
- _dcd.ep[ep_id][0].cmd_sts.toggle_mode = 0;
+ _dcd.ep[ep_id][0].cmd_sts.rf_tv = 0;
}
bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc)
{
//------------- Prepare Queue Head -------------//
uint8_t ep_id = ep_addr2id(p_endpoint_desc->bEndpointAddress);
+ ep_cmd_sts_t* ep_cs = get_ep_cs(ep_id);
// Check if endpoint is available
- TU_ASSERT( _dcd.ep[ep_id][0].cmd_sts.disable && _dcd.ep[ep_id][1].cmd_sts.disable );
+ TU_ASSERT( ep_cs[0].cmd_sts.disable && ep_cs[1].cmd_sts.disable );
edpt_reset(rhport, ep_id);
- _dcd.ep[ep_id][0].cmd_sts.is_iso = (p_endpoint_desc->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS);
+
+ switch (p_endpoint_desc->bmAttributes.xfer) {
+ case TUSB_XFER_ISOCHRONOUS:
+ ep_cs[0].cmd_sts.type = 1;
+ break;
+
+ case TUSB_XFER_INTERRUPT:
+ // What is interrupt endpoint in rate feedback mode ?
+ if ( rhport_is_highspeed(rhport) ) {
+ ep_cs[0].cmd_sts.type = 1;
+ ep_cs[0].cmd_sts.rf_tv = 1;
+ }
+ break;
+
+ case TUSB_XFER_BULK:
+ // nothing to do both type and rf_tv are 0
+ break;
+
+ default: break;
+ }
// Enable EP interrupt
dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs;
@@ -379,42 +419,50 @@ void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr)
_dcd.ep[ep_id][0].cmd_sts.disable = _dcd.ep[ep_id][1].cmd_sts.disable = 1;
}
-static void prepare_ep_xfer(uint8_t rhport, uint8_t ep_id, uint16_t buf_offset, uint16_t total_bytes)
-{
+static void prepare_ep_xfer(uint8_t rhport, uint8_t ep_id, uint16_t buf_offset, uint16_t total_bytes) {
uint16_t nbytes;
+ ep_cmd_sts_t* ep_cs = get_ep_cs(ep_id);
- if (_dcd_controller[rhport].max_speed == TUSB_SPEED_FULL )
- {
- nbytes = tu_min16(total_bytes, _dcd.ep[ep_id][0].cmd_sts.is_iso ? NBYTES_ISO_FS_MAX : NBYTES_CBI_FS_MAX);
- _dcd.ep[ep_id][0].buffer_fs.offset = buf_offset;
- _dcd.ep[ep_id][0].buffer_fs.nbytes = nbytes;
- }else
- {
- nbytes = tu_min16(total_bytes, NBYTES_CBI_HS_MAX);
- _dcd.ep[ep_id][0].buffer_hs.offset = buf_offset;
- _dcd.ep[ep_id][0].buffer_hs.nbytes = nbytes;
+ const bool is_iso = ep_is_iso(ep_cs, _dcd_controller[rhport].is_highspeed);
+
+ if ( rhport_is_highspeed(rhport) ) {
+ nbytes = tu_min16(total_bytes, is_iso ? NBYTES_ISO_HS_MAX : NBYTES_CBI_HS_MAX);
+ #if TU_CHECK_MCU(OPT_MCU_LPC54)
+ // LPC54 Errata USB.1: In USB high-speed device mode, the NBytes field does not decrement after BULK OUT transfer.
+ // Suggested Work-around: Program the NByte to the max packet size (512)
+ // Actual Work-around: round up NByte to multiple of 4.
+ // Note: this can cause buffer overflowed and corrupt data if host send more data than total_bytes
+ if ( (ep_id > 1) && (ep_id & 0x01) == 0 && ep_is_bulk(ep_cs) ) {
+ if ( nbytes & 0x03 ) {
+ nbytes = tu_align4(nbytes) + 4;
+ }
+ }
+ #endif
+
+ ep_cs[0].buffer_hs.offset = buf_offset;
+ ep_cs[0].buffer_hs.nbytes = nbytes;
+ }else {
+ nbytes = tu_min16(total_bytes, is_iso ? NBYTES_ISO_FS_MAX : NBYTES_CBI_FS_MAX);
+ ep_cs[0].buffer_fs.offset = buf_offset;
+ ep_cs[0].buffer_fs.nbytes = nbytes;
}
_dcd.dma[ep_id].nbytes = nbytes;
-
- _dcd.ep[ep_id][0].cmd_sts.active = 1;
+ ep_cs[0].cmd_sts.active = 1;
}
-bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes)
-{
+bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes) {
uint8_t const ep_id = ep_addr2id(ep_addr);
+ if (!buffer || total_bytes == 0) {
+ // Although having no data, ZLPs can cause buffer overwritten to zeroes. Probably due to USB/DMA controller side
+ // effect/bug. Assigned buffer offset to (valid) dummy to prevent overwriting to DATABUFSTART
+ buffer = (uint8_t *) (uint32_t) dummy;
+ }
+
tu_memclr(&_dcd.dma[ep_id], sizeof(xfer_dma_t));
_dcd.dma[ep_id].total_bytes = total_bytes;
- if (!buffer)
- {
- // Although having no data, ZLPs can cause buffer overwritten to zeroes.
- // Probably due to USB/DMA controller side effect/bug.
- // Assigned buffer offset to (valid) dummy to prevent overwriting to DATABUFSTART
- buffer = (uint8_t*)(uint32_t)dummy;
- }
-
prepare_ep_xfer(rhport, ep_id, get_buf_offset(buffer), total_bytes);
return true;
@@ -441,23 +489,19 @@ static void bus_reset(uint8_t rhport)
dcd_reg->EPSKIP = 0xFFFFFFFF;
dcd_reg->INTSTAT = dcd_reg->INTSTAT; // clear all pending interrupt
- dcd_reg->DEVCMDSTAT |= CMDSTAT_SETUP_RECEIVED_MASK; // clear setup received interrupt
+ dcd_reg->DEVCMDSTAT |= DEVCMDSTAT_SETUP_RECEIVED_MASK; // clear setup received interrupt
dcd_reg->INTEN = INT_DEVICE_STATUS_MASK | TU_BIT(0) | TU_BIT(1); // enable device status & control endpoints
}
-static void process_xfer_isr(uint8_t rhport, uint32_t int_status)
-{
+static void process_xfer_isr(uint8_t rhport, uint32_t int_status) {
uint8_t const max_ep = 2*_dcd_controller[rhport].ep_pairs;
- for(uint8_t ep_id = 0; ep_id < max_ep; ep_id++ )
- {
- if ( tu_bit_test(int_status, ep_id) )
- {
+ for(uint8_t ep_id = 0; ep_id < max_ep; ep_id++ ) {
+ if ( tu_bit_test(int_status, ep_id) ) {
ep_cmd_sts_t * ep_cs = &_dcd.ep[ep_id][0];
xfer_dma_t* xfer_dma = &_dcd.dma[ep_id];
- if ( ep_id == 0 || ep_id == 1)
- {
+ if ( ep_id <= 1 ) {
// For control endpoint, we need to manually clear Active bit
ep_cs->cmd_sts.active = 0;
}
@@ -465,26 +509,29 @@ static void process_xfer_isr(uint8_t rhport, uint32_t int_status)
uint16_t buf_offset;
uint16_t buf_nbytes;
- if (_dcd_controller[rhport].max_speed == TUSB_SPEED_FULL)
- {
- buf_offset = ep_cs->buffer_fs.offset;
- buf_nbytes = ep_cs->buffer_fs.nbytes;
- }else
- {
+ if ( rhport_is_highspeed(rhport) ) {
buf_offset = ep_cs->buffer_hs.offset;
buf_nbytes = ep_cs->buffer_hs.nbytes;
+
+ #if TU_CHECK_MCU(OPT_MCU_LPC54)
+ // LPC54 Errata USB.2: In USB high-speed device mode, the NBytes field is not correct after BULK IN transfer
+ // There is no work-around. For EP in transfer, the NByte value can be ignored after a packet is transmitted.
+ if ( (ep_id > 1) && (ep_id & 0x01) == 1 && ep_is_bulk(ep_cs) ) {
+ buf_nbytes = 0;
+ }
+ #endif
+ } else {
+ buf_offset = ep_cs->buffer_fs.offset;
+ buf_nbytes = ep_cs->buffer_fs.nbytes;
}
xfer_dma->xferred_bytes += xfer_dma->nbytes - buf_nbytes;
- if ( (buf_nbytes == 0) && (xfer_dma->total_bytes > xfer_dma->xferred_bytes) )
- {
+ if ( (buf_nbytes == 0) && (xfer_dma->total_bytes > xfer_dma->xferred_bytes) ) {
// There is more data to transfer
// buff_offset has been already increased by hw to correct value for next transfer
prepare_ep_xfer(rhport, ep_id, buf_offset, xfer_dma->total_bytes - xfer_dma->xferred_bytes);
- }
- else
- {
+ } else {
// for detecting ZLP
xfer_dma->total_bytes = xfer_dma->xferred_bytes;
@@ -511,19 +558,16 @@ void dcd_int_handler(uint8_t rhport)
//------------- Device Status -------------//
if ( int_status & INT_DEVICE_STATUS_MASK )
{
- dcd_reg->DEVCMDSTAT |= CMDSTAT_RESET_CHANGE_MASK | CMDSTAT_CONNECT_CHANGE_MASK | CMDSTAT_SUSPEND_CHANGE_MASK;
+ dcd_reg->DEVCMDSTAT |= DEVCMDSTAT_RESET_CHANGE_MASK | DEVCMDSTAT_CONNECT_CHANGE_MASK | DEVCMDSTAT_SUSPEND_CHANGE_MASK;
- if ( cmd_stat & CMDSTAT_RESET_CHANGE_MASK) // bus reset
+ if ( cmd_stat & DEVCMDSTAT_RESET_CHANGE_MASK) // bus reset
{
bus_reset(rhport);
tusb_speed_t speed = TUSB_SPEED_FULL;
-
- if (_dcd_controller[rhport].max_speed == TUSB_SPEED_HIGH)
- {
+ if ( _dcd_controller[rhport].is_highspeed ) {
// 0 : reserved, 1 : full, 2 : high, 3: super
- if ( 2 == ((cmd_stat >> CMDSTAT_SPEED_SHIFT) & 0x3UL) )
- {
+ if ( 2 == ((cmd_stat >> DEVCMDSTAT_SPEED_SHIFT) & 0x3UL) ) {
speed= TUSB_SPEED_HIGH;
}
}
@@ -531,35 +575,35 @@ void dcd_int_handler(uint8_t rhport)
dcd_event_bus_reset(rhport, speed, true);
}
- if (cmd_stat & CMDSTAT_CONNECT_CHANGE_MASK)
+ if (cmd_stat & DEVCMDSTAT_CONNECT_CHANGE_MASK)
{
// device disconnect
- if (cmd_stat & CMDSTAT_DEVICE_ADDR_MASK)
+ if (cmd_stat & DEVCMDSTAT_DEVICE_ADDR_MASK)
{
// debouncing as this can be set when device is powering
dcd_event_bus_signal(rhport, DCD_EVENT_UNPLUGGED, true);
}
}
- if (cmd_stat & CMDSTAT_SUSPEND_CHANGE_MASK)
+ if (cmd_stat & DEVCMDSTAT_SUSPEND_CHANGE_MASK)
{
// suspend signal, bus idle for more than 3ms
// Note: Host may delay more than 3 ms before and/or after bus reset before doing enumeration.
- if (cmd_stat & CMDSTAT_DEVICE_ADDR_MASK)
+ if (cmd_stat & DEVCMDSTAT_DEVICE_ADDR_MASK)
{
- dcd_event_bus_signal(rhport, (cmd_stat & CMDSTAT_DEVICE_SUSPEND_MASK) ? DCD_EVENT_SUSPEND : DCD_EVENT_RESUME, true);
+ dcd_event_bus_signal(rhport, (cmd_stat & DEVCMDSTAT_DEVICE_SUSPEND_MASK) ? DCD_EVENT_SUSPEND : DCD_EVENT_RESUME, true);
}
}
}
// Setup Receive
- if ( tu_bit_test(int_status, 0) && (cmd_stat & CMDSTAT_SETUP_RECEIVED_MASK) )
+ if ( tu_bit_test(int_status, 0) && (cmd_stat & DEVCMDSTAT_SETUP_RECEIVED_MASK) )
{
// Follow UM flowchart to clear Active & Stall on both Control IN/OUT endpoints
_dcd.ep[0][0].cmd_sts.active = _dcd.ep[1][0].cmd_sts.active = 0;
_dcd.ep[0][0].cmd_sts.stall = _dcd.ep[1][0].cmd_sts.stall = 0;
- dcd_reg->DEVCMDSTAT |= CMDSTAT_SETUP_RECEIVED_MASK;
+ dcd_reg->DEVCMDSTAT |= DEVCMDSTAT_SETUP_RECEIVED_MASK;
dcd_event_setup_received(rhport, _dcd.setup_packet, true);
diff --git a/src/portable/ohci/ohci.c b/src/portable/ohci/ohci.c
index 3f702d22c..413e72037 100644
--- a/src/portable/ohci/ohci.c
+++ b/src/portable/ohci/ohci.c
@@ -341,19 +341,24 @@ static void ed_init(ohci_ed_t *p_ed, uint8_t dev_addr, uint16_t ep_size, uint8_t
p_ed->is_interrupt_xfer = (xfer_type == TUSB_XFER_INTERRUPT ? 1 : 0);
}
-static void gtd_init(ohci_gtd_t* p_td, uint8_t* data_ptr, uint16_t total_bytes)
-{
+static void gtd_init(ohci_gtd_t *p_td, uint8_t *data_ptr, uint16_t total_bytes) {
tu_memclr(p_td, sizeof(ohci_gtd_t));
- p_td->used = 1;
- p_td->expected_bytes = total_bytes;
+ p_td->used = 1;
+ p_td->expected_bytes = total_bytes;
+
+ p_td->buffer_rounding = 1; // less than queued length is not a error
+ p_td->delay_interrupt = OHCI_INT_ON_COMPLETE_NO;
+ p_td->condition_code = OHCI_CCODE_NOT_ACCESSED;
- p_td->buffer_rounding = 1; // less than queued length is not a error
- p_td->delay_interrupt = OHCI_INT_ON_COMPLETE_NO;
- p_td->condition_code = OHCI_CCODE_NOT_ACCESSED;
+ uint8_t *cbp = (uint8_t *) _phys_addr(data_ptr);
- p_td->current_buffer_pointer = _phys_addr(data_ptr);
- p_td->buffer_end = total_bytes ? (_phys_addr(data_ptr + total_bytes - 1)) : (uint8_t *)p_td->current_buffer_pointer;
+ p_td->current_buffer_pointer = cbp;
+ if ( total_bytes ) {
+ p_td->buffer_end = _phys_addr(data_ptr + total_bytes - 1);
+ } else {
+ p_td->buffer_end = cbp;
+ }
}
static ohci_ed_t * ed_from_addr(uint8_t dev_addr, uint8_t ep_addr)
@@ -487,7 +492,7 @@ bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet
ohci_ed_t* ed = &ohci_data.control[dev_addr].ed;
ohci_gtd_t *qtd = &ohci_data.control[dev_addr].gtd;
- gtd_init(qtd, (uint8_t*) setup_packet, 8);
+ gtd_init(qtd, (uint8_t*)(uintptr_t) setup_packet, 8);
qtd->index = dev_addr;
qtd->pid = PID_SETUP;
qtd->data_toggle = GTD_DT_DATA0;
@@ -543,8 +548,16 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *
return true;
}
-bool hcd_edpt_clear_stall(uint8_t dev_addr, uint8_t ep_addr)
-{
+bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) {
+ (void) rhport;
+ (void) dev_addr;
+ (void) ep_addr;
+ // TODO not implemented yet
+ return false;
+}
+
+bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) {
+ (void) rhport;
ohci_ed_t * const p_ed = ed_from_addr(dev_addr, ep_addr);
p_ed->is_stalled = 0;
diff --git a/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c b/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c
index 264af2e7a..93bc1bf43 100644
--- a/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c
+++ b/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c
@@ -48,16 +48,14 @@ static pio_usb_configuration_t pio_host_cfg = PIO_USB_DEFAULT_CONFIG;
//--------------------------------------------------------------------+
// HCD API
//--------------------------------------------------------------------+
-bool hcd_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param)
-{
+bool hcd_configure(uint8_t rhport, uint32_t cfg_id, const void *cfg_param) {
(void) rhport;
TU_VERIFY(cfg_id == TUH_CFGID_RPI_PIO_USB_CONFIGURATION);
memcpy(&pio_host_cfg, cfg_param, sizeof(pio_usb_configuration_t));
return true;
}
-bool hcd_init(uint8_t rhport)
-{
+bool hcd_init(uint8_t rhport) {
(void) rhport;
// To run USB SOF interrupt in core1, call this init in core1
@@ -66,20 +64,17 @@ bool hcd_init(uint8_t rhport)
return true;
}
-void hcd_port_reset(uint8_t rhport)
-{
+void hcd_port_reset(uint8_t rhport) {
uint8_t const pio_rhport = RHPORT_PIO(rhport);
pio_usb_host_port_reset_start(pio_rhport);
}
-void hcd_port_reset_end(uint8_t rhport)
-{
+void hcd_port_reset_end(uint8_t rhport) {
uint8_t const pio_rhport = RHPORT_PIO(rhport);
pio_usb_host_port_reset_end(pio_rhport);
}
-bool hcd_port_connect_status(uint8_t rhport)
-{
+bool hcd_port_connect_status(uint8_t rhport) {
uint8_t const pio_rhport = RHPORT_PIO(rhport);
root_port_t *root = PIO_USB_ROOT_PORT(pio_rhport);
@@ -88,33 +83,28 @@ bool hcd_port_connect_status(uint8_t rhport)
return line_state != PORT_PIN_SE0;
}
-tusb_speed_t hcd_port_speed_get(uint8_t rhport)
-{
+tusb_speed_t hcd_port_speed_get(uint8_t rhport) {
// TODO determine link speed
uint8_t const pio_rhport = RHPORT_PIO(rhport);
return PIO_USB_ROOT_PORT(pio_rhport)->is_fullspeed ? TUSB_SPEED_FULL : TUSB_SPEED_LOW;
}
// Close all opened endpoint belong to this device
-void hcd_device_close(uint8_t rhport, uint8_t dev_addr)
-{
+void hcd_device_close(uint8_t rhport, uint8_t dev_addr) {
uint8_t const pio_rhport = RHPORT_PIO(rhport);
pio_usb_host_close_device(pio_rhport, dev_addr);
}
-uint32_t hcd_frame_number(uint8_t rhport)
-{
+uint32_t hcd_frame_number(uint8_t rhport) {
(void) rhport;
return pio_usb_host_get_frame_number();
}
-void hcd_int_enable(uint8_t rhport)
-{
+void hcd_int_enable(uint8_t rhport) {
(void) rhport;
}
-void hcd_int_disable(uint8_t rhport)
-{
+void hcd_int_disable(uint8_t rhport) {
(void) rhport;
}
@@ -122,24 +112,26 @@ void hcd_int_disable(uint8_t rhport)
// Endpoint API
//--------------------------------------------------------------------+
-bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const * desc_ep)
-{
+bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const *desc_ep) {
hcd_devtree_info_t dev_tree;
hcd_devtree_get_info(dev_addr, &dev_tree);
bool const need_pre = (dev_tree.hub_addr && dev_tree.speed == TUSB_SPEED_LOW);
uint8_t const pio_rhport = RHPORT_PIO(rhport);
- return pio_usb_host_endpoint_open(pio_rhport, dev_addr, (uint8_t const*) desc_ep, need_pre);
+ return pio_usb_host_endpoint_open(pio_rhport, dev_addr, (uint8_t const *) desc_ep, need_pre);
}
-bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t buflen)
-{
+bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *buffer, uint16_t buflen) {
uint8_t const pio_rhport = RHPORT_PIO(rhport);
return pio_usb_host_endpoint_transfer(pio_rhport, dev_addr, ep_addr, buffer, buflen);
}
-bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8])
-{
+bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) {
+ uint8_t const pio_rhport = RHPORT_PIO(rhport);
+ return pio_usb_host_endpoint_abort_transfer(pio_rhport, dev_addr, ep_addr);
+}
+
+bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8]) {
uint8_t const pio_rhport = RHPORT_PIO(rhport);
return pio_usb_host_send_setup(pio_rhport, dev_addr, setup_packet);
}
@@ -150,34 +142,32 @@ bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet
// // so if any transfer is active on epx, we are busy. Interrupt endpoints have their own
// // EPX so ep->active will only be busy if there is a pending transfer on that interrupt endpoint
// // on that device
-// pico_trace("hcd_edpt_busy dev addr %d ep_addr 0x%x\n", dev_addr, ep_addr);
+// pico_trace("hcd_edpt_busy dev addr %d ep_addr 0x%x\r\n", dev_addr, ep_addr);
// struct hw_endpoint *ep = get_dev_ep(dev_addr, ep_addr);
// assert(ep);
// bool busy = ep->active;
-// pico_trace("busy == %d\n", busy);
+// pico_trace("busy == %d\r\n", busy);
// return busy;
//}
-bool hcd_edpt_clear_stall(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;
(void) dev_addr;
(void) ep_addr;
return true;
}
-static void __no_inline_not_in_flash_func(handle_endpoint_irq)(root_port_t* rport, xfer_result_t result, volatile uint32_t* ep_reg)
-{
+static void __no_inline_not_in_flash_func(handle_endpoint_irq)(root_port_t *rport, xfer_result_t result,
+ volatile uint32_t *ep_reg) {
(void) rport;
const uint32_t ep_all = *ep_reg;
- for(uint8_t ep_idx = 0; ep_idx < PIO_USB_EP_POOL_CNT; ep_idx++)
- {
+ for ( uint8_t ep_idx = 0; ep_idx < PIO_USB_EP_POOL_CNT; ep_idx++ ) {
uint32_t const mask = (1u << ep_idx);
- if (ep_all & mask)
- {
- endpoint_t* ep = PIO_USB_ENDPOINT(ep_idx);
+ if ( ep_all & mask ) {
+ endpoint_t * ep = PIO_USB_ENDPOINT(ep_idx);
hcd_event_xfer_complete(ep->dev_addr, ep->ep_num, ep->actual_len, result, true);
}
}
@@ -187,34 +177,28 @@ static void __no_inline_not_in_flash_func(handle_endpoint_irq)(root_port_t* rpor
}
// IRQ Handler
-void __no_inline_not_in_flash_func(pio_usb_host_irq_handler)(uint8_t root_id)
-{
+void __no_inline_not_in_flash_func(pio_usb_host_irq_handler)(uint8_t root_id) {
uint8_t const tu_rhport = root_id + 1;
- root_port_t* rport = PIO_USB_ROOT_PORT(root_id);
+ root_port_t *rport = PIO_USB_ROOT_PORT(root_id);
uint32_t const ints = rport->ints;
- if ( ints & PIO_USB_INTS_CONNECT_BITS )
- {
+ if ( ints & PIO_USB_INTS_CONNECT_BITS ) {
hcd_event_device_attach(tu_rhport, true);
}
- if ( ints & PIO_USB_INTS_DISCONNECT_BITS )
- {
+ if ( ints & PIO_USB_INTS_DISCONNECT_BITS ) {
hcd_event_device_remove(tu_rhport, true);
}
- if ( ints & PIO_USB_INTS_ENDPOINT_COMPLETE_BITS )
- {
+ if ( ints & PIO_USB_INTS_ENDPOINT_COMPLETE_BITS ) {
handle_endpoint_irq(rport, XFER_RESULT_SUCCESS, &rport->ep_complete);
}
- if ( ints & PIO_USB_INTS_ENDPOINT_STALLED_BITS )
- {
+ if ( ints & PIO_USB_INTS_ENDPOINT_STALLED_BITS ) {
handle_endpoint_irq(rport, XFER_RESULT_STALLED, &rport->ep_stalled);
}
- if ( ints & PIO_USB_INTS_ENDPOINT_ERROR_BITS )
- {
+ if ( ints & PIO_USB_INTS_ENDPOINT_ERROR_BITS ) {
handle_endpoint_irq(rport, XFER_RESULT_FAILED, &rport->ep_error);
}
diff --git a/src/portable/raspberrypi/rp2040/dcd_rp2040.c b/src/portable/raspberrypi/rp2040/dcd_rp2040.c
index 479b17b67..e8cee73fd 100644
--- a/src/portable/raspberrypi/rp2040/dcd_rp2040.c
+++ b/src/portable/raspberrypi/rp2040/dcd_rp2040.c
@@ -189,7 +189,7 @@ static void hw_endpoint_xfer(uint8_t ep_addr, uint8_t *buffer, uint16_t total_by
static void __tusb_irq_path_func(hw_handle_buff_status)(void)
{
uint32_t remaining_buffers = usb_hw->buf_status;
- pico_trace("buf_status = 0x%08lx\n", remaining_buffers);
+ pico_trace("buf_status = 0x%08lx\r\n", remaining_buffers);
uint bit = 1u;
for (uint8_t i = 0; remaining_buffers && i < USB_MAX_ENDPOINTS * 2; i++)
{
@@ -331,7 +331,7 @@ static void __tusb_irq_path_func(dcd_rp2040_irq)(void)
// SE0 for 2.5 us or more (will last at least 10ms)
if ( status & USB_INTS_BUS_RESET_BITS )
{
- pico_trace("BUS RESET\n");
+ pico_trace("BUS RESET\r\n");
handled |= USB_INTS_BUS_RESET_BITS;
@@ -565,7 +565,7 @@ void dcd_edpt_close (uint8_t rhport, uint8_t ep_addr)
{
(void) rhport;
- pico_trace("dcd_edpt_close %02x\n", ep_addr);
+ pico_trace("dcd_edpt_close %02x\r\n", ep_addr);
hw_endpoint_close(ep_addr);
}
diff --git a/src/portable/raspberrypi/rp2040/hcd_rp2040.c b/src/portable/raspberrypi/rp2040/hcd_rp2040.c
index 02f9968a7..21dc3f67d 100644
--- a/src/portable/raspberrypi/rp2040/hcd_rp2040.c
+++ b/src/portable/raspberrypi/rp2040/hcd_rp2040.c
@@ -219,7 +219,7 @@ static void __tusb_irq_path_func(hcd_rp2040_irq)(void)
if ( status & USB_INTS_BUFF_STATUS_BITS )
{
handled |= USB_INTS_BUFF_STATUS_BITS;
- TU_LOG(2, "Buffer complete\n");
+ TU_LOG(2, "Buffer complete\r\n");
hw_handle_buff_status();
}
@@ -227,7 +227,7 @@ static void __tusb_irq_path_func(hcd_rp2040_irq)(void)
{
handled |= USB_INTS_TRANS_COMPLETE_BITS;
usb_hw_clear->sie_status = USB_SIE_STATUS_TRANS_COMPLETE_BITS;
- TU_LOG(2, "Transfer complete\n");
+ TU_LOG(2, "Transfer complete\r\n");
hw_trans_complete();
}
@@ -576,6 +576,14 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *
return true;
}
+bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) {
+ (void) rhport;
+ (void) dev_addr;
+ (void) ep_addr;
+ // TODO not implemented yet
+ return false;
+}
+
bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8])
{
(void) rhport;
@@ -617,8 +625,8 @@ bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet
return true;
}
-bool hcd_edpt_clear_stall(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;
(void) dev_addr;
(void) ep_addr;
diff --git a/src/portable/raspberrypi/rp2040/rp2040_usb.c b/src/portable/raspberrypi/rp2040/rp2040_usb.c
index 1f49665ff..a512dc34f 100644
--- a/src/portable/raspberrypi/rp2040/rp2040_usb.c
+++ b/src/portable/raspberrypi/rp2040/rp2040_usb.c
@@ -219,7 +219,7 @@ void hw_endpoint_xfer_start(struct hw_endpoint *ep, uint8_t *buffer, uint16_t to
if ( ep->active )
{
// TODO: Is this acceptable for interrupt packets?
- TU_LOG(1, "WARN: starting new transfer on already active ep %d %s\n", tu_edpt_number(ep->ep_addr),
+ TU_LOG(1, "WARN: starting new transfer on already active ep %d %s\r\n", tu_edpt_number(ep->ep_addr),
ep_dir_string[tu_edpt_dir(ep->ep_addr)]);
hw_endpoint_reset_transfer(ep);
@@ -276,7 +276,7 @@ static uint16_t __tusb_irq_path_func(sync_ep_buffer)(struct hw_endpoint *ep, uin
// Short packet
if (xferred_bytes < ep->wMaxPacketSize)
{
- pico_trace(" Short packet on buffer %d with %u bytes\n", buf_id, xferred_bytes);
+ pico_trace(" Short packet on buffer %d with %u bytes\r\n", buf_id, xferred_bytes);
// Reduce total length as this is last packet
ep->remaining_len = 0;
}
@@ -352,7 +352,7 @@ bool __tusb_irq_path_func(hw_endpoint_xfer_continue)(struct hw_endpoint *ep)
// If we are done then notify tinyusb
if (ep->remaining_len == 0)
{
- pico_trace("Completed transfer of %d bytes on ep %d %s\n",
+ pico_trace("Completed transfer of %d bytes on ep %d %s\r\n",
ep->xferred_len, tu_edpt_number(ep->ep_addr), ep_dir_string[tu_edpt_dir(ep->ep_addr)]);
// Notify caller we are done so it can notify the tinyusb stack
hw_endpoint_lock_update(ep, -1);
@@ -419,7 +419,7 @@ static bool __tusb_irq_path_func(e15_is_critical_frame_period) (struct hw_endpoi
if (delta < 800 || delta > 998) {
return false;
}
- TU_LOG(3, "Avoiding sof %lu now %lu last %lu\n", (usb_hw->sof_rd + 1) & USB_SOF_RD_BITS, time_us_32(), e15_last_sof);
+ TU_LOG(3, "Avoiding sof %lu now %lu last %lu\r\n", (usb_hw->sof_rd + 1) & USB_SOF_RD_BITS, time_us_32(), e15_last_sof);
return true;
}
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 65bbc656b..790cd6b32 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_D0FIFOCTR_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_D0FIFOCTR_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_D0FIFOCTR_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,10 +411,10 @@ 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);
- TU_LOG(TU_RUSB2_HCD_DBG, "NRDY %d %x\n", num, *ctr);
+ uint16_t volatile *ctr = get_pipectr(rusb, num);
+ TU_LOG(TU_RUSB2_HCD_DBG, "NRDY %d %x\r\n", num, *ctr);
switch (*ctr & RUSB2_PIPE_CTR_PID_Msk) {
default: return;
case RUSB2_PIPE_CTR_PID_STALL: result = XFER_RESULT_STALLED; break;
@@ -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;
-
- RUSB2->SYSCFG_b.DRPD = 1;
- for (volatile int i = 0; i < 30000; ++i) ;
- RUSB2->SYSCFG_b.USBE = 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;
- // 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\r\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;
@@ -704,15 +735,22 @@ 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);
+ TU_LOG(TU_RUSB2_HCD_DBG, "X %d %x %u\r\n", dev_addr, ep_addr, 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);
+bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) {
+ (void) rhport;
+ (void) dev_addr;
+ (void) ep_addr;
+ // TODO not implemented yet
+ return false;
+}
+
+bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) {
+ uint16_t volatile *ctr = addr_to_pipectr(rhport, dev_addr, ep_addr);
TU_ASSERT(ctr);
const uint32_t pid = *ctr & 0x3;
@@ -735,57 +773,63 @@ bool hcd_edpt_clear_stall(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\r\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];
@@ -797,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
}
diff --git a/src/portable/st/typec/typec_stm32.c b/src/portable/st/typec/typec_stm32.c
index bf8b660f0..8da2e39ba 100644
--- a/src/portable/st/typec/typec_stm32.c
+++ b/src/portable/st/typec/typec_stm32.c
@@ -246,7 +246,7 @@ void tcd_int_handler(uint8_t rhport) {
v_cc[0] = (UCPD1->SR >> UCPD_SR_TYPEC_VSTATE_CC1_Pos) & 0x03;
v_cc[1] = (UCPD1->SR >> UCPD_SR_TYPEC_VSTATE_CC2_Pos) & 0x03;
- TU_LOG3("VState CC1 = %lu, CC2 = %lu\n", v_cc[0], v_cc[1]);
+ TU_LOG3("VState CC1 = %lu, CC2 = %lu\r\n", v_cc[0], v_cc[1]);
uint32_t cr = UCPD1->CR;
@@ -255,15 +255,15 @@ void tcd_int_handler(uint8_t rhport) {
// FIXME somehow CC2 is vstate is not correct, always 1 even not attached.
// on DPOW1 board, it is connected to PA10 (USBPD_DBCC2), we probably miss something.
if ((sr & UCPD_SR_TYPECEVT1) && (v_cc[0] == 3)) {
- TU_LOG3("Attach CC1\n");
+ TU_LOG3("Attach CC1\r\n");
cr &= ~(UCPD_CR_PHYCCSEL | UCPD_CR_CCENABLE);
cr |= UCPD_CR_PHYRXEN | UCPD_CR_CCENABLE_0;
} else if ((sr & UCPD_SR_TYPECEVT2) && (v_cc[1] == 3)) {
- TU_LOG3("Attach CC2\n");
+ TU_LOG3("Attach CC2\r\n");
cr &= ~UCPD_CR_CCENABLE;
cr |= (UCPD_CR_PHYCCSEL | UCPD_CR_PHYRXEN | UCPD_CR_CCENABLE_1);
} else {
- TU_LOG3("Detach\n");
+ TU_LOG3("Detach\r\n");
cr &= ~UCPD_CR_PHYRXEN;
cr |= UCPD_CR_CCENABLE_0 | UCPD_CR_CCENABLE_1;
}
@@ -290,7 +290,7 @@ void tcd_int_handler(uint8_t rhport) {
//------------- RX -------------//
if (sr & UCPD_SR_RXORDDET) {
// SOP: Start of Packet.
- TU_LOG3("SOP\n");
+ TU_LOG3("SOP\r\n");
// UCPD1->RX_ORDSET & UCPD_RX_ORDSET_RXORDSET_Msk;
// ack
@@ -299,7 +299,7 @@ void tcd_int_handler(uint8_t rhport) {
// Received full message
if (sr & UCPD_SR_RXMSGEND) {
- TU_LOG3("RX MSG END\n");
+ TU_LOG3("RX MSG END\r\n");
// stop TX
dma_stop(rhport, true);
@@ -328,7 +328,7 @@ void tcd_int_handler(uint8_t rhport) {
}
if (sr & UCPD_SR_RXOVR) {
- TU_LOG3("RXOVR\n");
+ TU_LOG3("RXOVR\r\n");
// ack
UCPD1->ICR = UCPD_ICR_RXOVRCF;
}
@@ -343,12 +343,12 @@ void tcd_int_handler(uint8_t rhport) {
uint8_t result;
if ( sr & UCPD_SR_TXMSGSENT ) {
- TU_LOG3("TX MSG SENT\n");
+ TU_LOG3("TX MSG SENT\r\n");
result = XFER_RESULT_SUCCESS;
// ack
UCPD1->ICR = UCPD_ICR_TXMSGSENTCF;
}else {
- TU_LOG3("TX Error\n");
+ TU_LOG3("TX Error\r\n");
result = XFER_RESULT_FAILED;
// ack
UCPD1->ICR = UCPD_SR_TXMSGDISC | UCPD_SR_TXMSGABT | UCPD_SR_TXUND;
diff --git a/src/portable/sunxi/dcd_sunxi_musb.c b/src/portable/sunxi/dcd_sunxi_musb.c
index e26be775d..6cc1975a8 100644
--- a/src/portable/sunxi/dcd_sunxi_musb.c
+++ b/src/portable/sunxi/dcd_sunxi_musb.c
@@ -408,9 +408,9 @@ static inline unsigned free_block_size(free_block_t const *blk)
#if 0
static inline void print_block_list(free_block_t const *blk, unsigned num)
{
- TU_LOG1("*************\n");
+ TU_LOG1("*************\r\n");
for (unsigned i = 0; i < num; ++i) {
- TU_LOG1(" Blk%u %u %u\n", i, blk->beg, blk->end);
+ TU_LOG1(" Blk%u %u %u\r\n", i, blk->beg, blk->end);
++blk;
}
}
@@ -590,7 +590,7 @@ static bool handle_xfer_in(uint_fast8_t ep_addr)
const unsigned mps = USBC_Readw(USBC_REG_TXMAXP(USBC0_BASE));
const unsigned len = TU_MIN(mps, rem);
uint8_t *buf = pipe->buf;
- // TU_LOG1(" %p mps %d len %d rem %d\n", buf, mps, len, rem);
+ // TU_LOG1(" %p mps %d len %d rem %d\r\n", buf, mps, len, rem);
if (len) {
volatile void* addr = (volatile void*)(USBC_REG_EPFIFO1(USBC0_BASE) + (epnum_minus1 << 2));
if (_dcd.pipe_buf_is_fifo[TUSB_DIR_IN] & TU_BIT(epnum_minus1)) {
@@ -602,7 +602,7 @@ static bool handle_xfer_in(uint_fast8_t ep_addr)
pipe->remaining = rem - len;
}
__USBC_Dev_Tx_WriteDataComplete();
- // TU_LOG1(" TXCSRL%d = %x %d\n", epnum_minus1 + 1, regs->TXCSRL, rem - len);
+ // TU_LOG1(" TXCSRL%d = %x %d\r\n", epnum_minus1 + 1, regs->TXCSRL, rem - len);
return false;
}
@@ -610,7 +610,7 @@ static bool handle_xfer_out(uint_fast8_t ep_addr)
{
unsigned epnum_minus1 = tu_edpt_number(ep_addr) - 1;
pipe_state_t *pipe = &_dcd.pipe[tu_edpt_dir(ep_addr)][epnum_minus1];
- // TU_LOG1(" RXCSRL%d = %x\n", epnum_minus1 + 1, regs->RXCSRL);
+ // TU_LOG1(" RXCSRL%d = %x\r\n", epnum_minus1 + 1, regs->RXCSRL);
TU_ASSERT(__USBC_Dev_Rx_IsReadDataReady());
@@ -677,14 +677,14 @@ static bool edpt0_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_
* may have already finished and received the next setup packet
* without calling this function, so we have no choice but to
* invoke the callback function of status packet here. */
- // TU_LOG1(" STATUS OUT CSRL0 = %x\n", CSRL0);
+ // TU_LOG1(" STATUS OUT CSRL0 = %x\r\n", CSRL0);
_dcd.status_out = 0;
if (req == REQUEST_TYPE_INVALID) {
dcd_event_xfer_complete(rhport, ep_addr, total_bytes, XFER_RESULT_SUCCESS, false);
} else {
/* The next setup packet has already been received, it aborts
* invoking callback function to avoid confusing TUSB stack. */
- TU_LOG1("Drop CONTROL_STAGE_ACK\n");
+ TU_LOG1("Drop CONTROL_STAGE_ACK\r\n");
}
return true;
}
@@ -709,16 +709,16 @@ static bool edpt0_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_
} else {
__USBC_Dev_ep0_WriteDataHalf();
}
- // TU_LOG1(" IN CSRL0 = %x\n", CSRL0);
+ // TU_LOG1(" IN CSRL0 = %x\r\n", CSRL0);
} else {
- // TU_LOG1(" OUT CSRL0 = %x\n", CSRL0);
+ // TU_LOG1(" OUT CSRL0 = %x\r\n", CSRL0);
_dcd.pipe0.buf = buffer;
_dcd.pipe0.length = len;
_dcd.pipe0.remaining = len;
__USBC_Dev_ep0_ReadDataHalf();
}
} else if (dir_in) {
- // TU_LOG1(" STATUS IN CSRL0 = %x\n", CSRL0);
+ // TU_LOG1(" STATUS IN CSRL0 = %x\r\n", CSRL0);
_dcd.pipe0.buf = NULL;
_dcd.pipe0.length = 0;
_dcd.pipe0.remaining = 0;
@@ -733,7 +733,7 @@ static void process_ep0(uint8_t rhport)
USBC_SelectActiveEp(0);
uint_fast8_t csrl = USBC_Readw(USBC_REG_CSR0(USBC0_BASE));
- // TU_LOG1(" EP0 CSRL0 = %x\n", csrl);
+ // TU_LOG1(" EP0 CSRL0 = %x\r\n", csrl);
if (csrl & USB_CSRL0_STALLED) {
/* Returned STALL packet to HOST. */
@@ -743,7 +743,7 @@ static void process_ep0(uint8_t rhport)
unsigned req = _dcd.setup_packet.bmRequestType;
if (csrl & USB_CSRL0_SETEND) {
- // TU_LOG1(" ABORT by the next packets\n");
+ // TU_LOG1(" ABORT by the next packets\r\n");
USBC_Dev_Ctrl_ClearSetupEnd();
if (req != REQUEST_TYPE_INVALID && _dcd.pipe0.buf) {
/* DATA stage was aborted by receiving STATUS or SETUP packet. */
@@ -819,14 +819,14 @@ static void process_edpt_n(uint8_t rhport, uint_fast8_t ep_addr)
USBC_SelectActiveEp(epn);
if (dir_in) {
- // TU_LOG1(" TXCSRL%d = %x\n", epn_minus1 + 1, regs->TXCSRL);
+ // TU_LOG1(" TXCSRL%d = %x\r\n", epn_minus1 + 1, regs->TXCSRL);
if (__USBC_Dev_Tx_IsEpStall()) {
__USBC_Dev_Tx_ClearStall();
return;
}
completed = handle_xfer_in(ep_addr);
} else {
- // TU_LOG1(" RXCSRL%d = %x\n", epn_minus1 + 1, regs->RXCSRL);
+ // TU_LOG1(" RXCSRL%d = %x\r\n", epn_minus1 + 1, regs->RXCSRL);
if (__USBC_Dev_Rx_IsEpStall()) {
__USBC_Dev_Rx_ClearStall();
return;
@@ -1092,7 +1092,7 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t t
{
(void)rhport;
bool ret;
- // TU_LOG1("X %x %d\n", ep_addr, total_bytes);
+ // TU_LOG1("X %x %d\r\n", ep_addr, total_bytes);
unsigned const epnum = tu_edpt_number(ep_addr);
musb_int_mask();
@@ -1111,7 +1111,7 @@ bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_
{
(void)rhport;
bool ret;
- // TU_LOG1("X %x %d\n", ep_addr, total_bytes);
+ // TU_LOG1("X %x %d\r\n", ep_addr, total_bytes);
unsigned const epnum = tu_edpt_number(ep_addr);
TU_ASSERT(epnum);