Merge branch 'master' into pio-host
This commit is contained in:
@@ -35,6 +35,7 @@
|
||||
// INCLUDE
|
||||
//--------------------------------------------------------------------+
|
||||
#include "common/tusb_common.h"
|
||||
#include "host/hcd.h"
|
||||
#include "portable/ehci/ehci_api.h"
|
||||
#include "ci_hs_type.h"
|
||||
|
||||
|
||||
+36
-10
@@ -58,6 +58,9 @@
|
||||
|
||||
#define FRAMELIST_SIZE (1024 >> FRAMELIST_SIZE_BIT_VALUE)
|
||||
|
||||
#define QHD_MAX (CFG_TUH_DEVICE_MAX*CFG_TUH_ENDPOINT_MAX)
|
||||
#define QTD_MAX QHD_MAX
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ehci_link_t period_framelist[FRAMELIST_SIZE];
|
||||
@@ -73,8 +76,8 @@ typedef struct
|
||||
ehci_qtd_t qtd;
|
||||
}control[CFG_TUH_DEVICE_MAX+CFG_TUH_HUB+1];
|
||||
|
||||
ehci_qhd_t qhd_pool[HCD_MAX_ENDPOINT];
|
||||
ehci_qtd_t qtd_pool[HCD_MAX_XFER] TU_ATTR_ALIGNED(32);
|
||||
ehci_qhd_t qhd_pool[QHD_MAX];
|
||||
ehci_qtd_t qtd_pool[QTD_MAX] TU_ATTR_ALIGNED(32);
|
||||
|
||||
ehci_registers_t* regs;
|
||||
|
||||
@@ -189,7 +192,11 @@ static void list_remove_qhd_by_addr(ehci_link_t* list_head, uint8_t dev_addr)
|
||||
prev = list_next(prev) )
|
||||
{
|
||||
// TODO check type for ISO iTD and siTD
|
||||
// TODO Suppress cast-align warning
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wcast-align"
|
||||
ehci_qhd_t* qhd = (ehci_qhd_t*) list_next(prev);
|
||||
#pragma GCC diagnostic pop
|
||||
if ( qhd->dev_addr == dev_addr )
|
||||
{
|
||||
// TODO deactive all TD, wait for QHD to inactive before removal
|
||||
@@ -474,7 +481,7 @@ static void async_advance_isr(uint8_t rhport)
|
||||
(void) rhport;
|
||||
|
||||
ehci_qhd_t* qhd_pool = ehci_data.qhd_pool;
|
||||
for(uint32_t i = 0; i < HCD_MAX_ENDPOINT; i++)
|
||||
for(uint32_t i = 0; i < QHD_MAX; i++)
|
||||
{
|
||||
if ( qhd_pool[i].removing )
|
||||
{
|
||||
@@ -542,7 +549,7 @@ static void period_list_xfer_complete_isr(uint8_t hostid, uint32_t interval_ms)
|
||||
// TODO abstract max loop guard for period
|
||||
while( !next_item.terminate &&
|
||||
!(interval_ms > 1 && period_1ms_addr == tu_align32(next_item.address)) &&
|
||||
max_loop < (HCD_MAX_ENDPOINT + EHCI_MAX_ITD + EHCI_MAX_SITD)*CFG_TUH_DEVICE_MAX)
|
||||
max_loop < (QHD_MAX + EHCI_MAX_ITD + EHCI_MAX_SITD)*CFG_TUH_DEVICE_MAX)
|
||||
{
|
||||
switch ( next_item.type )
|
||||
{
|
||||
@@ -649,6 +656,26 @@ static void xfer_error_isr(uint8_t hostid)
|
||||
}
|
||||
}
|
||||
|
||||
#if CFG_TUSB_DEBUG >= EHCI_DBG
|
||||
|
||||
static inline void print_portsc(ehci_registers_t* regs)
|
||||
{
|
||||
TU_LOG_HEX(EHCI_DBG, regs->portsc);
|
||||
TU_LOG(EHCI_DBG, " Current Connect Status: %u\r\n", regs->portsc_bm.current_connect_status);
|
||||
TU_LOG(EHCI_DBG, " Connect Status Change : %u\r\n", regs->portsc_bm.connect_status_change);
|
||||
TU_LOG(EHCI_DBG, " Port Enabled : %u\r\n", regs->portsc_bm.port_enabled);
|
||||
TU_LOG(EHCI_DBG, " Port Enabled Change : %u\r\n", regs->portsc_bm.port_enable_change);
|
||||
|
||||
TU_LOG(EHCI_DBG, " Port Reset : %u\r\n", regs->portsc_bm.port_reset);
|
||||
TU_LOG(EHCI_DBG, " Port Power : %u\r\n", regs->portsc_bm.port_power);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define print_portsc(_reg)
|
||||
|
||||
#endif
|
||||
|
||||
//------------- Host Controller Driver's Interrupt Handler -------------//
|
||||
void hcd_int_handler(uint8_t rhport)
|
||||
{
|
||||
@@ -668,9 +695,8 @@ void hcd_int_handler(uint8_t rhport)
|
||||
|
||||
if (int_status & EHCI_INT_MASK_PORT_CHANGE)
|
||||
{
|
||||
uint32_t port_status = regs->portsc & EHCI_PORTSC_MASK_ALL;
|
||||
|
||||
TU_LOG_HEX(EHCI_DBG, regs->portsc);
|
||||
uint32_t const port_status = regs->portsc & EHCI_PORTSC_MASK_ALL;
|
||||
print_portsc(regs);
|
||||
|
||||
if (regs->portsc_bm.connect_status_change)
|
||||
{
|
||||
@@ -714,7 +740,7 @@ void hcd_int_handler(uint8_t rhport)
|
||||
//------------- queue head helper -------------//
|
||||
static inline ehci_qhd_t* qhd_find_free (void)
|
||||
{
|
||||
for (uint32_t i=0; i<HCD_MAX_ENDPOINT; i++)
|
||||
for (uint32_t i=0; i<QHD_MAX; i++)
|
||||
{
|
||||
if ( !ehci_data.qhd_pool[i].used ) return &ehci_data.qhd_pool[i];
|
||||
}
|
||||
@@ -731,7 +757,7 @@ 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;
|
||||
|
||||
for(uint32_t i=0; i<HCD_MAX_ENDPOINT; i++)
|
||||
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) )
|
||||
@@ -746,7 +772,7 @@ static inline ehci_qhd_t* qhd_get_from_addr(uint8_t dev_addr, uint8_t ep_addr)
|
||||
//------------- TD helper -------------//
|
||||
static inline ehci_qtd_t* qtd_find_free(void)
|
||||
{
|
||||
for (uint32_t i=0; i<HCD_MAX_XFER; i++)
|
||||
for (uint32_t i=0; i<QTD_MAX; i++)
|
||||
{
|
||||
if ( !ehci_data.qtd_pool[i].used ) return &ehci_data.qtd_pool[i];
|
||||
}
|
||||
|
||||
@@ -101,8 +101,8 @@ typedef struct
|
||||
|
||||
// Word 2: qTQ Token
|
||||
volatile uint32_t ping_err : 1 ; ///< For Highspeed: 0 Out, 1 Ping. Full/Slow used as error indicator
|
||||
volatile uint32_t non_hs_split_state : 1 ; ///< Used by HC to track the state of slipt transaction
|
||||
volatile uint32_t non_hs_missed_uframe : 1 ; ///< HC misses a complete slip transaction
|
||||
volatile uint32_t non_hs_split_state : 1 ; ///< Used by HC to track the state of split transaction
|
||||
volatile uint32_t non_hs_missed_uframe : 1 ; ///< HC misses a complete split transaction
|
||||
volatile uint32_t xact_err : 1 ; ///< Error (Timeout, CRC, Bad PID ... )
|
||||
volatile uint32_t babble_err : 1 ; ///< Babble detected, also set Halted bit to 1
|
||||
volatile uint32_t buffer_err : 1 ; ///< Data overrun/underrun error
|
||||
|
||||
@@ -34,7 +34,6 @@
|
||||
#include "freertos/xtensa_api.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
#include "esp_log.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "soc/dport_reg.h"
|
||||
#include "soc/gpio_sig_map.h"
|
||||
#include "soc/usb_periph.h"
|
||||
|
||||
@@ -125,7 +125,7 @@ typedef struct
|
||||
uint16_t bda[2*2];
|
||||
};
|
||||
endpoint_state_t endpoint[2];
|
||||
pipe_state_t pipe[HCD_MAX_XFER * 2];
|
||||
pipe_state_t pipe[CFG_TUH_ENDPOINT_MAX * 2];
|
||||
uint32_t in_progress; /* Bitmap. Each bit indicates that a transfer of the corresponding pipe is in progress */
|
||||
uint32_t pending; /* Bitmap. Each bit indicates that a transfer of the corresponding pipe will be resume the next frame */
|
||||
bool need_reset; /* The device has not been reset after connection. */
|
||||
@@ -142,7 +142,7 @@ int find_pipe(uint8_t dev_addr, uint8_t ep_addr)
|
||||
{
|
||||
/* Find the target pipe */
|
||||
int num;
|
||||
for (num = 0; num < HCD_MAX_XFER * 2; ++num) {
|
||||
for (num = 0; num < CFG_TUH_ENDPOINT_MAX * 2; ++num) {
|
||||
pipe_state_t *p = &_hcd.pipe[num];
|
||||
if ((p->dev_addr == dev_addr) && (p->ep_addr == ep_addr))
|
||||
return num;
|
||||
@@ -463,7 +463,7 @@ void hcd_device_close(uint8_t rhport, uint8_t dev_addr)
|
||||
const unsigned ie = NVIC_GetEnableIRQ(USB0_IRQn);
|
||||
NVIC_DisableIRQ(USB0_IRQn);
|
||||
pipe_state_t *p = &_hcd.pipe[0];
|
||||
pipe_state_t *end = &_hcd.pipe[HCD_MAX_XFER * 2];
|
||||
pipe_state_t *end = &_hcd.pipe[CFG_TUH_ENDPOINT_MAX * 2];
|
||||
for (;p != end; ++p) {
|
||||
if (p->dev_addr == dev_addr)
|
||||
tu_memclr(p, sizeof(*p));
|
||||
@@ -511,7 +511,7 @@ bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const
|
||||
// TU_LOG1("O %u %x\n", dev_addr, ep_addr);
|
||||
/* Find a free pipe */
|
||||
pipe_state_t *p = &_hcd.pipe[0];
|
||||
pipe_state_t *end = &_hcd.pipe[HCD_MAX_XFER * 2];
|
||||
pipe_state_t *end = &_hcd.pipe[CFG_TUH_ENDPOINT_MAX * 2];
|
||||
if (dev_addr || ep_addr) {
|
||||
p += 2;
|
||||
for (; p < end && (p->dev_addr || p->ep_addr); ++p) ;
|
||||
|
||||
@@ -318,7 +318,7 @@ static ohci_ed_t * ed_from_addr(uint8_t dev_addr, uint8_t ep_addr)
|
||||
|
||||
ohci_ed_t* ed_pool = ohci_data.ed_pool;
|
||||
|
||||
for(uint32_t i=0; i<HCD_MAX_ENDPOINT; i++)
|
||||
for(uint32_t i=0; i<ED_MAX; i++)
|
||||
{
|
||||
if ( (ed_pool[i].dev_addr == dev_addr) &&
|
||||
ep_addr == tu_edpt_addr(ed_pool[i].ep_number, ed_pool[i].pid == PID_IN) )
|
||||
@@ -334,7 +334,7 @@ static ohci_ed_t * ed_find_free(void)
|
||||
{
|
||||
ohci_ed_t* ed_pool = ohci_data.ed_pool;
|
||||
|
||||
for(uint8_t i = 0; i < HCD_MAX_ENDPOINT; i++)
|
||||
for(uint8_t i = 0; i < ED_MAX; i++)
|
||||
{
|
||||
if ( !ed_pool[i].used ) return &ed_pool[i];
|
||||
}
|
||||
@@ -373,7 +373,7 @@ static void ed_list_remove_by_addr(ohci_ed_t * p_head, uint8_t dev_addr)
|
||||
|
||||
static ohci_gtd_t * gtd_find_free(void)
|
||||
{
|
||||
for(uint8_t i=0; i < HCD_MAX_XFER; i++)
|
||||
for(uint8_t i=0; i < GTD_MAX; i++)
|
||||
{
|
||||
if ( !ohci_data.gtd_pool[i].used ) return &ohci_data.gtd_pool[i];
|
||||
}
|
||||
|
||||
@@ -42,6 +42,9 @@ enum {
|
||||
OHCI_MAX_ITD = 4
|
||||
};
|
||||
|
||||
#define ED_MAX (CFG_TUH_DEVICE_MAX*CFG_TUH_ENDPOINT_MAX)
|
||||
#define GTD_MAX ED_MAX
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// OHCI Data Structure
|
||||
//--------------------------------------------------------------------+
|
||||
@@ -162,8 +165,8 @@ typedef struct TU_ATTR_ALIGNED(256)
|
||||
}control[CFG_TUH_DEVICE_MAX+CFG_TUH_HUB+1];
|
||||
|
||||
// ochi_itd_t itd[OHCI_MAX_ITD]; // itd requires alignment of 32
|
||||
ohci_ed_t ed_pool[HCD_MAX_ENDPOINT];
|
||||
ohci_gtd_t gtd_pool[HCD_MAX_XFER];
|
||||
ohci_ed_t ed_pool[ED_MAX];
|
||||
ohci_gtd_t gtd_pool[GTD_MAX];
|
||||
|
||||
volatile uint16_t frame_number_hi;
|
||||
|
||||
|
||||
@@ -329,9 +329,11 @@ static void _hw_endpoint_init(struct hw_endpoint *ep, uint8_t dev_addr, uint8_t
|
||||
// endpoint number / direction
|
||||
// preamble
|
||||
uint32_t reg = dev_addr | (num << USB_ADDR_ENDP1_ENDPOINT_LSB);
|
||||
// Assert the interrupt endpoint is IN_TO_HOST
|
||||
// TODO Interrupt can also be OUT
|
||||
assert(dir == TUSB_DIR_IN);
|
||||
|
||||
if (dir == TUSB_DIR_OUT)
|
||||
{
|
||||
reg |= USB_ADDR_ENDP1_INTEP_DIR_BITS;
|
||||
}
|
||||
|
||||
if (need_pre(dev_addr))
|
||||
{
|
||||
|
||||
@@ -58,8 +58,12 @@ void rp2040_usb_init(void)
|
||||
unreset_block_wait(RESETS_RESET_USBCTRL_BITS);
|
||||
|
||||
// Clear any previous state just in case
|
||||
// TODO Suppress warning array-bounds with gcc11
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Warray-bounds"
|
||||
memset(usb_hw, 0, sizeof(*usb_hw));
|
||||
memset(usb_dpram, 0, sizeof(*usb_dpram));
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
// Mux the controller to the onboard usb phy
|
||||
usb_hw->muxing = USB_USB_MUXING_TO_PHY_BITS | USB_USB_MUXING_SOFTCON_BITS;
|
||||
|
||||
@@ -110,7 +110,7 @@
|
||||
#endif
|
||||
|
||||
#if CFG_TUD_ENABLED && \
|
||||
( TU_CHECK_MCU(OPT_MCU_STM32F0, OPT_MCU_STM32F3, OPT_MCU_STM32L0, OPT_MCU_STM32L1, OPT_MCU_STM32G4) || \
|
||||
( TU_CHECK_MCU(OPT_MCU_STM32F0, OPT_MCU_STM32F3, OPT_MCU_STM32L0, OPT_MCU_STM32L1, OPT_MCU_STM32G4, OPT_MCU_STM32WB) || \
|
||||
(TU_CHECK_MCU(OPT_MCU_STM32F1) && defined(STM32F1_FSDEV)) \
|
||||
)
|
||||
|
||||
@@ -328,6 +328,10 @@ void dcd_int_enable (uint8_t rhport)
|
||||
NVIC_EnableIRQ(USB_LP_IRQn);
|
||||
NVIC_EnableIRQ(USBWakeUp_IRQn);
|
||||
|
||||
#elif CFG_TUSB_MCU == OPT_MCU_STM32WB
|
||||
NVIC_EnableIRQ(USB_HP_IRQn);
|
||||
NVIC_EnableIRQ(USB_LP_IRQn);
|
||||
|
||||
#else
|
||||
#error Unknown arch in USB driver
|
||||
#endif
|
||||
@@ -370,6 +374,10 @@ void dcd_int_disable(uint8_t rhport)
|
||||
NVIC_DisableIRQ(USB_LP_IRQn);
|
||||
NVIC_DisableIRQ(USBWakeUp_IRQn);
|
||||
|
||||
#elif CFG_TUSB_MCU == OPT_MCU_STM32WB
|
||||
NVIC_DisableIRQ(USB_HP_IRQn);
|
||||
NVIC_DisableIRQ(USB_LP_IRQn);
|
||||
|
||||
#else
|
||||
#error Unknown arch in USB driver
|
||||
#endif
|
||||
|
||||
@@ -91,6 +91,13 @@
|
||||
#include "stm32g4xx.h"
|
||||
#define PMA_LENGTH (1024u)
|
||||
|
||||
#elif CFG_TUSB_MCU == OPT_MCU_STM32WB
|
||||
#include "stm32wbxx.h"
|
||||
#define PMA_LENGTH (1024u)
|
||||
/* ST provided header has incorrect value */
|
||||
#undef USB_PMAADDR
|
||||
#define USB_PMAADDR USB1_PMAADDR
|
||||
|
||||
#else
|
||||
#error You are using an untested or unimplemented STM32 variant. Please update the driver.
|
||||
// This includes L1x0, L1x1, L1x2, L4x2 and L4x3, G1x1, G1x3, and G1x4
|
||||
|
||||
@@ -986,16 +986,16 @@ TU_VERIFY_STATIC(offsetof(dwc2_regs_t, fifo ) == 0x1000, "incorrect size");
|
||||
|
||||
/******************** Bit definition for OTG register ********************/
|
||||
#define GNPTXFSIZ_NPTXFSA_Pos (0U)
|
||||
#define GNPTXFSIZ_NPTXFSA_Msk (0xFFFFUL << NPTXFSA_Pos) // 0x0000FFFF */
|
||||
#define GNPTXFSIZ_NPTXFSA_Msk (0xFFFFUL << GNPTXFSIZ_NPTXFSA_Pos) // 0x0000FFFF */
|
||||
#define GNPTXFSIZ_NPTXFSA GNPTXFSIZ_NPTXFSA_Msk // Nonperiodic transmit RAM start address */
|
||||
#define GNPTXFSIZ_NPTXFD_Pos (16U)
|
||||
#define GNPTXFSIZ_NPTXFD_Msk (0xFFFFUL << NPTXFD_Pos) // 0xFFFF0000 */
|
||||
#define GNPTXFSIZ_NPTXFD_Msk (0xFFFFUL << GNPTXFSIZ_NPTXFD_Pos) // 0xFFFF0000 */
|
||||
#define GNPTXFSIZ_NPTXFD GNPTXFSIZ_NPTXFD_Msk // Nonperiodic TxFIFO depth */
|
||||
#define DIEPTXF0_TX0FSA_Pos (0U)
|
||||
#define DIEPTXF0_TX0FSA_Msk (0xFFFFUL << TX0FSA_Pos) // 0x0000FFFF */
|
||||
#define DIEPTXF0_TX0FSA_Msk (0xFFFFUL << DIEPTXF0_TX0FSA_Pos) // 0x0000FFFF */
|
||||
#define DIEPTXF0_TX0FSA DIEPTXF0_TX0FSA_Msk // Endpoint 0 transmit RAM start address */
|
||||
#define DIEPTXF0_TX0FD_Pos (16U)
|
||||
#define DIEPTXF0_TX0FD_Msk (0xFFFFUL << TX0FD_Pos) // 0xFFFF0000 */
|
||||
#define DIEPTXF0_TX0FD_Msk (0xFFFFUL << DIEPTXF0_TX0FD_Pos) // 0xFFFF0000 */
|
||||
#define DIEPTXF0_TX0FD DIEPTXF0_TX0FD_Msk // Endpoint 0 TxFIFO depth */
|
||||
|
||||
/******************** Bit definition for DVBUSPULSE register ********************/
|
||||
|
||||
Reference in New Issue
Block a user