always define CFG_TUH_WCH_USBIP_USBFS=1 for ch32v20x since only port1 support host mode
reformat hcd usbfs add uart rx for ch32v20x bsp
This commit is contained in:
@@ -20,59 +20,56 @@ manufacturer: WCH
|
|||||||
#include "bsp/board_api.h"
|
#include "bsp/board_api.h"
|
||||||
#include "board.h"
|
#include "board.h"
|
||||||
|
|
||||||
/* CH32v203 depending on variants can support 2 USB IPs: FSDEV and USBFS.
|
/* CH32v203 depending on variants can support 2 USB IPs: FSDEV (port0) and USBFS (port1).
|
||||||
* By default, we use FSDEV, but you can explicitly select by define:
|
* By default, we use FSDEV, but you can explicitly select by define:
|
||||||
* - CFG_TUD_WCH_USBIP_FSDEV
|
* - CFG_TUD_WCH_USBIP_FSDEV
|
||||||
* - CFG_TUD_WCH_USBIP_USBFS
|
* - CFG_TUD_WCH_USBIP_USBFS
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// USBFS
|
// Port0: USBD (fsdev)
|
||||||
__attribute__((interrupt)) __attribute__((used))
|
__attribute__((interrupt)) __attribute__((used)) void USB_LP_CAN1_RX0_IRQHandler(void) {
|
||||||
void USBHD_IRQHandler(void) {
|
#if CFG_TUD_WCH_USBIP_FSDEV
|
||||||
#if CFG_TUD_WCH_USBIP_USBFS
|
|
||||||
tud_int_handler(0);
|
tud_int_handler(0);
|
||||||
#endif
|
#endif
|
||||||
#if defined(CFG_TUH_WCH_USBIP_USBFS) && CFG_TUH_WCH_USBIP_USBFS
|
|
||||||
tuh_int_handler(0);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((interrupt)) __attribute__((used))
|
__attribute__((interrupt)) __attribute__((used)) void USB_HP_CAN1_TX_IRQHandler(void) {
|
||||||
void USBHDWakeUp_IRQHandler(void) {
|
#if CFG_TUD_WCH_USBIP_FSDEV
|
||||||
|
tud_int_handler(0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__((interrupt)) __attribute__((used)) void USBWakeUp_IRQHandler(void) {
|
||||||
|
#if CFG_TUD_WCH_USBIP_FSDEV
|
||||||
|
tud_int_handler(0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// Port1: USBFS
|
||||||
|
__attribute__((interrupt)) __attribute__((used)) void USBHD_IRQHandler(void) {
|
||||||
|
#if CFG_TUD_ENABLED && CFG_TUD_WCH_USBIP_USBFS
|
||||||
|
tud_int_handler(1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CFG_TUH_ENABLED
|
||||||
|
tuh_int_handler(1);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__((interrupt)) __attribute__((used)) void USBHDWakeUp_IRQHandler(void) {
|
||||||
#if CFG_TUD_WCH_USBIP_USBFS
|
#if CFG_TUD_WCH_USBIP_USBFS
|
||||||
tud_int_handler(0);
|
tud_int_handler(0);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// USBD (fsdev)
|
//--------------------------------------------------------------------+
|
||||||
__attribute__((interrupt)) __attribute__((used))
|
// Board API
|
||||||
void USB_LP_CAN1_RX0_IRQHandler(void) {
|
//--------------------------------------------------------------------+
|
||||||
#if CFG_TUD_WCH_USBIP_FSDEV
|
|
||||||
tud_int_handler(0);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__((interrupt)) __attribute__((used))
|
|
||||||
void USB_HP_CAN1_TX_IRQHandler(void) {
|
|
||||||
#if CFG_TUD_WCH_USBIP_FSDEV
|
|
||||||
tud_int_handler(0);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__((interrupt)) __attribute__((used))
|
|
||||||
void USBWakeUp_IRQHandler(void) {
|
|
||||||
#if CFG_TUD_WCH_USBIP_FSDEV
|
|
||||||
tud_int_handler(0);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#if CFG_TUSB_OS == OPT_OS_NONE
|
#if CFG_TUSB_OS == OPT_OS_NONE
|
||||||
volatile uint32_t system_ticks = 0;
|
volatile uint32_t system_ticks = 0;
|
||||||
|
|
||||||
__attribute__((interrupt))
|
__attribute__((interrupt)) void SysTick_Handler(void) {
|
||||||
void SysTick_Handler(void) {
|
|
||||||
SysTick->SR = 0;
|
SysTick->SR = 0;
|
||||||
system_ticks++;
|
system_ticks++;
|
||||||
}
|
}
|
||||||
@@ -111,7 +108,7 @@ void board_init(void) {
|
|||||||
#ifdef UART_DEV
|
#ifdef UART_DEV
|
||||||
UART_CLOCK_EN();
|
UART_CLOCK_EN();
|
||||||
GPIO_InitTypeDef usart_init = {
|
GPIO_InitTypeDef usart_init = {
|
||||||
.GPIO_Pin = UART_TX_PIN,
|
.GPIO_Pin = UART_TX_PIN | UART_RX_PIN,
|
||||||
.GPIO_Speed = GPIO_Speed_50MHz,
|
.GPIO_Speed = GPIO_Speed_50MHz,
|
||||||
.GPIO_Mode = GPIO_Mode_AF_PP,
|
.GPIO_Mode = GPIO_Mode_AF_PP,
|
||||||
};
|
};
|
||||||
@@ -122,7 +119,7 @@ void board_init(void) {
|
|||||||
.USART_WordLength = USART_WordLength_8b,
|
.USART_WordLength = USART_WordLength_8b,
|
||||||
.USART_StopBits = USART_StopBits_1,
|
.USART_StopBits = USART_StopBits_1,
|
||||||
.USART_Parity = USART_Parity_No,
|
.USART_Parity = USART_Parity_No,
|
||||||
.USART_Mode = USART_Mode_Tx,
|
.USART_Mode = USART_Mode_Tx | USART_Mode_Rx,
|
||||||
.USART_HardwareFlowControl = USART_HardwareFlowControl_None,
|
.USART_HardwareFlowControl = USART_HardwareFlowControl_None,
|
||||||
};
|
};
|
||||||
USART_Init(UART_DEV, &usart);
|
USART_Init(UART_DEV, &usart);
|
||||||
@@ -192,9 +189,19 @@ size_t board_get_unique_id(uint8_t id[], size_t max_len) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int board_uart_read(uint8_t *buf, int len) {
|
int board_uart_read(uint8_t *buf, int len) {
|
||||||
(void) buf;
|
#ifdef UART_DEV
|
||||||
(void) len;
|
int count;
|
||||||
|
for (count = 0; count < len; count++) {
|
||||||
|
if (USART_GetFlagStatus(UART_DEV, USART_FLAG_RXNE) == RESET) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
buf[count] = USART_ReceiveData(UART_DEV);
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
#else
|
||||||
|
(void) buf; (void) len;
|
||||||
return 0;
|
return 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int board_uart_write(void const *buf, int len) {
|
int board_uart_write(void const *buf, int len) {
|
||||||
@@ -210,7 +217,3 @@ int board_uart_write(void const *buf, int len) {
|
|||||||
|
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
|
||||||
// Neopixel
|
|
||||||
//--------------------------------------------------------------------
|
|
||||||
|
@@ -16,10 +16,13 @@ set(FAMILY_MCUS CH32V20X CACHE INTERNAL "")
|
|||||||
set(OPENOCD_OPTION "-f ${CMAKE_CURRENT_LIST_DIR}/wch-riscv.cfg")
|
set(OPENOCD_OPTION "-f ${CMAKE_CURRENT_LIST_DIR}/wch-riscv.cfg")
|
||||||
|
|
||||||
# Port0 use FSDev, Port1 use USBFS
|
# Port0 use FSDev, Port1 use USBFS
|
||||||
if (NOT DEFINED PORT)
|
if (NOT DEFINED RHPORT_DEVICE)
|
||||||
set(PORT 0)
|
set(RHPORT_DEVICE 0)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
|
# only port1 support host mode
|
||||||
|
set(RHPORT_HOST 1)
|
||||||
|
|
||||||
#------------------------------------
|
#------------------------------------
|
||||||
# BOARD_TARGET
|
# BOARD_TARGET
|
||||||
#------------------------------------
|
#------------------------------------
|
||||||
@@ -56,19 +59,16 @@ function(add_board_target BOARD_TARGET)
|
|||||||
)
|
)
|
||||||
target_compile_definitions(${BOARD_TARGET} PUBLIC
|
target_compile_definitions(${BOARD_TARGET} PUBLIC
|
||||||
CH32V20x_${MCU_VARIANT}
|
CH32V20x_${MCU_VARIANT}
|
||||||
|
BOARD_TUD_RHPORT=${RHPORT_DEVICE}
|
||||||
|
BOARD_TUH_RHPORT=${RHPORT_HOST}
|
||||||
)
|
)
|
||||||
|
|
||||||
if (PORT EQUAL 0)
|
if (RHPORT_DEVICE EQUAL 0)
|
||||||
target_compile_definitions(${BOARD_TARGET} PUBLIC
|
target_compile_definitions(${BOARD_TARGET} PUBLIC CFG_TUD_WCH_USBIP_FSDEV=1)
|
||||||
CFG_TUD_WCH_USBIP_FSDEV=1
|
elseif (RHPORT_DEVICE EQUAL 1)
|
||||||
CFG_TUH_WCH_USBIP_USBFS=1
|
target_compile_definitions(${BOARD_TARGET} PUBLIC CFG_TUH_WCH_USBIP_USBFS=1)
|
||||||
)
|
|
||||||
elseif (PORT EQUAL 1)
|
|
||||||
target_compile_definitions(${BOARD_TARGET} PUBLIC
|
|
||||||
CFG_TUD_WCH_USBIP_USBFS=1
|
|
||||||
)
|
|
||||||
else()
|
else()
|
||||||
message(FATAL_ERROR "Invalid PORT ${PORT}")
|
message(FATAL_ERROR "Invalid RHPORT_DEVICE ${RHPORT_DEVICE}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
update_board(${BOARD_TARGET})
|
update_board(${BOARD_TARGET})
|
||||||
@@ -133,8 +133,6 @@ function(family_configure_example TARGET RTOS)
|
|||||||
)
|
)
|
||||||
target_link_libraries(${TARGET} PUBLIC board_${BOARD})
|
target_link_libraries(${TARGET} PUBLIC board_${BOARD})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Flashing
|
# Flashing
|
||||||
family_add_bin_hex(${TARGET})
|
family_add_bin_hex(${TARGET})
|
||||||
family_flash_openocd_wch(${TARGET})
|
family_flash_openocd_wch(${TARGET})
|
||||||
|
@@ -503,11 +503,17 @@
|
|||||||
#define TUP_DCD_ENDPOINT_MAX 8
|
#define TUP_DCD_ENDPOINT_MAX 8
|
||||||
|
|
||||||
#elif TU_CHECK_MCU(OPT_MCU_CH32V20X)
|
#elif TU_CHECK_MCU(OPT_MCU_CH32V20X)
|
||||||
// v20x support both FSDEV (USBD) and USBFS, default to FSDEV
|
// v20x support both port0 FSDEV (USBD) and port1 USBFS
|
||||||
#define TUP_USBIP_WCH_USBFS
|
#define TUP_USBIP_WCH_USBFS
|
||||||
|
|
||||||
|
#ifndef CFG_TUH_WCH_USBIP_USBFS
|
||||||
|
#define CFG_TUH_WCH_USBIP_USBFS 1
|
||||||
|
#endif
|
||||||
|
|
||||||
#define TUP_USBIP_FSDEV
|
#define TUP_USBIP_FSDEV
|
||||||
#define TUP_USBIP_FSDEV_CH32
|
#define TUP_USBIP_FSDEV_CH32
|
||||||
|
|
||||||
|
// default to FSDEV for device
|
||||||
#if !defined(CFG_TUD_WCH_USBIP_USBFS)
|
#if !defined(CFG_TUD_WCH_USBIP_USBFS)
|
||||||
#define CFG_TUD_WCH_USBIP_USBFS 0
|
#define CFG_TUD_WCH_USBIP_USBFS 0
|
||||||
#endif
|
#endif
|
||||||
|
@@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
#include "tusb_option.h"
|
#include "tusb_option.h"
|
||||||
|
|
||||||
#if CFG_TUD_ENABLED && defined(TUP_USBIP_WCH_USBHS) && CFG_TUD_WCH_USBIP_USBHS
|
#if CFG_TUD_ENABLED && defined(TUP_USBIP_WCH_USBHS) && defined(CFG_TUD_WCH_USBIP_USBHS) && CFG_TUD_WCH_USBIP_USBHS
|
||||||
#include "ch32_usbhs_reg.h"
|
#include "ch32_usbhs_reg.h"
|
||||||
|
|
||||||
#include "device/dcd.h"
|
#include "device/dcd.h"
|
||||||
|
@@ -37,20 +37,20 @@
|
|||||||
#include "ch32v20x.h"
|
#include "ch32v20x.h"
|
||||||
#include "ch32v20x_usb.h"
|
#include "ch32v20x_usb.h"
|
||||||
|
|
||||||
void osal_task_delay(uint32_t msec) {
|
|
||||||
uint32_t start = board_millis();
|
|
||||||
while (board_millis() - start < msec) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
#define USBFS_RX_BUF_LEN 64
|
#define USBFS_RX_BUF_LEN 64
|
||||||
#define USBFS_TX_BUF_LEN 64
|
#define USBFS_TX_BUF_LEN 64
|
||||||
__attribute__((aligned(4))) static uint8_t USBFS_RX_Buf[USBFS_RX_BUF_LEN];
|
TU_ATTR_ALIGNED(4) static uint8_t USBFS_RX_Buf[USBFS_RX_BUF_LEN];
|
||||||
__attribute__((aligned(4))) static uint8_t USBFS_TX_Buf[USBFS_TX_BUF_LEN];
|
TU_ATTR_ALIGNED(4) static uint8_t USBFS_TX_Buf[USBFS_TX_BUF_LEN];
|
||||||
|
|
||||||
#define USB_XFER_TIMEOUT_MILLIS 100
|
#define USB_XFER_TIMEOUT_MILLIS 100
|
||||||
// #define USB_INTERRUPT_XFER_TIMEOUT_MILLIS 1
|
// #define USB_INTERRUPT_XFER_TIMEOUT_MILLIS 1
|
||||||
|
|
||||||
#define PANIC(...) do { printf("%s() L%d: ", __func__, __LINE__); printf("\r\n[PANIC] " __VA_ARGS__); while (true) { } } while (false)
|
#define PANIC(...) \
|
||||||
|
do { \
|
||||||
|
printf("%s() L%d: ", __func__, __LINE__); \
|
||||||
|
printf("\r\n[PANIC] " __VA_ARGS__); \
|
||||||
|
while (true) {} \
|
||||||
|
} while (false)
|
||||||
|
|
||||||
#define LOG_CH32_USBFSH(...) TU_LOG3(__VA_ARGS__)
|
#define LOG_CH32_USBFSH(...) TU_LOG3(__VA_ARGS__)
|
||||||
|
|
||||||
@@ -70,8 +70,7 @@ __attribute__((aligned(4))) static uint8_t USBFS_TX_Buf[USBFS_TX_BUF_LEN];
|
|||||||
|
|
||||||
|
|
||||||
// Endpoint status
|
// Endpoint status
|
||||||
typedef struct usb_edpt
|
typedef struct usb_edpt {
|
||||||
{
|
|
||||||
// Is this a valid struct
|
// Is this a valid struct
|
||||||
bool configured;
|
bool configured;
|
||||||
|
|
||||||
@@ -85,10 +84,8 @@ typedef struct usb_edpt
|
|||||||
uint8_t data_toggle;
|
uint8_t data_toggle;
|
||||||
} usb_edpt_t;
|
} usb_edpt_t;
|
||||||
|
|
||||||
|
|
||||||
static usb_edpt_t usb_edpt_list[CFG_TUH_DEVICE_MAX * 6] = {};
|
static usb_edpt_t usb_edpt_list[CFG_TUH_DEVICE_MAX * 6] = {};
|
||||||
|
|
||||||
|
|
||||||
typedef struct usb_current_xfer_st {
|
typedef struct usb_current_xfer_st {
|
||||||
bool is_busy;
|
bool is_busy;
|
||||||
uint8_t dev_addr;
|
uint8_t dev_addr;
|
||||||
@@ -102,34 +99,26 @@ typedef struct usb_current_xfer_st {
|
|||||||
|
|
||||||
static volatile usb_current_xfer_t usb_current_xfer_info = {};
|
static volatile usb_current_xfer_t usb_current_xfer_info = {};
|
||||||
|
|
||||||
|
static usb_edpt_t *get_edpt_record(uint8_t dev_addr, uint8_t ep_addr) {
|
||||||
static usb_edpt_t* get_edpt_record(uint8_t dev_addr, uint8_t ep_addr)
|
for (size_t i = 0; i < TU_ARRAY_SIZE(usb_edpt_list); i++) {
|
||||||
{
|
|
||||||
for (size_t i = 0; i < TU_ARRAY_SIZE(usb_edpt_list); i++)
|
|
||||||
{
|
|
||||||
usb_edpt_t *cur = &usb_edpt_list[i];
|
usb_edpt_t *cur = &usb_edpt_list[i];
|
||||||
if (cur->configured && cur->dev_addr == dev_addr && cur->ep_addr == ep_addr)
|
if (cur->configured && cur->dev_addr == dev_addr && cur->ep_addr == ep_addr) {
|
||||||
{
|
|
||||||
return cur;
|
return cur;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static usb_edpt_t* get_empty_record_slot(void)
|
static usb_edpt_t *get_empty_record_slot(void) {
|
||||||
{
|
for (size_t i = 0; i < TU_ARRAY_SIZE(usb_edpt_list); i++) {
|
||||||
for (size_t i = 0; i < TU_ARRAY_SIZE(usb_edpt_list); i++)
|
if (!usb_edpt_list[i].configured) {
|
||||||
{
|
|
||||||
if (!usb_edpt_list[i].configured)
|
|
||||||
{
|
|
||||||
return &usb_edpt_list[i];
|
return &usb_edpt_list[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static usb_edpt_t* add_edpt_record(uint8_t dev_addr, uint8_t ep_addr, uint16_t max_packet_size, uint8_t xfer_type)
|
static usb_edpt_t *add_edpt_record(uint8_t dev_addr, uint8_t ep_addr, uint16_t max_packet_size, uint8_t xfer_type) {
|
||||||
{
|
|
||||||
usb_edpt_t *slot = get_empty_record_slot();
|
usb_edpt_t *slot = get_empty_record_slot();
|
||||||
if (slot == NULL) {
|
if (slot == NULL) {
|
||||||
PANIC("add_edpt_record(0x%02x, 0x%02x, ...) no slot for new record\r\n", dev_addr, ep_addr);
|
PANIC("add_edpt_record(0x%02x, 0x%02x, ...) no slot for new record\r\n", dev_addr, ep_addr);
|
||||||
@@ -147,26 +136,18 @@ static usb_edpt_t* add_edpt_record(uint8_t dev_addr, uint8_t ep_addr, uint16_t m
|
|||||||
return slot;
|
return slot;
|
||||||
}
|
}
|
||||||
|
|
||||||
static usb_edpt_t* get_or_add_edpt_record(uint8_t dev_addr, uint8_t ep_addr, uint16_t max_packet_size, uint8_t xfer_type)
|
static usb_edpt_t *get_or_add_edpt_record(uint8_t dev_addr, uint8_t ep_addr, uint16_t max_packet_size, uint8_t xfer_type) {
|
||||||
{
|
|
||||||
usb_edpt_t *ret = get_edpt_record(dev_addr, ep_addr);
|
usb_edpt_t *ret = get_edpt_record(dev_addr, ep_addr);
|
||||||
if (ret != NULL)
|
if (ret != NULL) {
|
||||||
{
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
return add_edpt_record(dev_addr, ep_addr, max_packet_size, xfer_type);
|
return add_edpt_record(dev_addr, ep_addr, max_packet_size, xfer_type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void remove_edpt_record_for_device(uint8_t dev_addr) {
|
||||||
static void remove_edpt_record_for_device(uint8_t dev_addr)
|
for (size_t i = 0; i < TU_ARRAY_SIZE(usb_edpt_list); i++) {
|
||||||
{
|
if (usb_edpt_list[i].configured && usb_edpt_list[i].dev_addr == dev_addr) {
|
||||||
for (size_t i = 0; i < TU_ARRAY_SIZE(usb_edpt_list); i++)
|
|
||||||
{
|
|
||||||
if (usb_edpt_list[i].configured && usb_edpt_list[i].dev_addr == dev_addr)
|
|
||||||
{
|
|
||||||
usb_edpt_list[i].configured = false;
|
usb_edpt_list[i].configured = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -183,25 +164,20 @@ static void remove_edpt_record_for_device(uint8_t dev_addr)
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
|
||||||
static bool interrupt_enabled = false;
|
static bool interrupt_enabled = false;
|
||||||
|
|
||||||
/** Enable or disable USBFS Host function */
|
/** Enable or disable USBFS Host function */
|
||||||
static void hardware_init_host(bool enabled)
|
static void hardware_init_host(bool enabled) {
|
||||||
{
|
|
||||||
// Reset USBOTG module
|
// Reset USBOTG module
|
||||||
USBOTG_H_FS->BASE_CTRL = USBFS_UC_RESET_SIE | USBFS_UC_CLR_ALL;
|
USBOTG_H_FS->BASE_CTRL = USBFS_UC_RESET_SIE | USBFS_UC_CLR_ALL;
|
||||||
|
|
||||||
osal_task_delay(1);
|
tusb_time_delay_ms_api(1);
|
||||||
USBOTG_H_FS->BASE_CTRL = 0;
|
USBOTG_H_FS->BASE_CTRL = 0;
|
||||||
|
|
||||||
if (!enabled)
|
if (!enabled) {
|
||||||
{
|
|
||||||
// Disable all feature
|
// Disable all feature
|
||||||
USBOTG_H_FS->BASE_CTRL = 0;
|
USBOTG_H_FS->BASE_CTRL = 0;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// Enable USB Host features
|
// Enable USB Host features
|
||||||
// NVIC_DisableIRQ(USBFS_IRQn);
|
// NVIC_DisableIRQ(USBFS_IRQn);
|
||||||
hcd_int_disable(0);
|
hcd_int_disable(0);
|
||||||
@@ -214,10 +190,11 @@ static void hardware_init_host(bool enabled)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool hardware_start_xfer(uint8_t pid, uint8_t ep_addr, uint8_t data_toggle)
|
static bool hardware_start_xfer(uint8_t pid, uint8_t ep_addr, uint8_t data_toggle) {
|
||||||
{
|
|
||||||
LOG_CH32_USBFSH("hardware_start_xfer(pid=%s(0x%02x), ep_addr=0x%02x, toggle=%d)\r\n",
|
LOG_CH32_USBFSH("hardware_start_xfer(pid=%s(0x%02x), ep_addr=0x%02x, toggle=%d)\r\n",
|
||||||
pid == USB_PID_IN ? "IN" : pid == USB_PID_OUT ? "OUT" : pid == USB_PID_SETUP ? "SETUP" : "(other)",
|
pid == USB_PID_IN ? "IN" : pid == USB_PID_OUT ? "OUT"
|
||||||
|
: pid == USB_PID_SETUP ? "SETUP"
|
||||||
|
: "(other)",
|
||||||
pid, ep_addr, data_toggle);
|
pid, ep_addr, data_toggle);
|
||||||
|
|
||||||
// if (pid == USB_PID_IN)
|
// if (pid == USB_PID_IN)
|
||||||
@@ -236,16 +213,15 @@ static bool hardware_start_xfer(uint8_t pid, uint8_t ep_addr, uint8_t data_toggl
|
|||||||
|
|
||||||
|
|
||||||
/** Set device address to communicate */
|
/** Set device address to communicate */
|
||||||
static void hardware_update_device_address(uint8_t dev_addr)
|
static void hardware_update_device_address(uint8_t dev_addr) {
|
||||||
{
|
|
||||||
// Keep the bit of GP_BIT. Other 7bits are actual device address.
|
// Keep the bit of GP_BIT. Other 7bits are actual device address.
|
||||||
USBOTG_H_FS->DEV_ADDR = (USBOTG_H_FS->DEV_ADDR & USBFS_UDA_GP_BIT) | (dev_addr & USBFS_USB_ADDR_MASK);
|
USBOTG_H_FS->DEV_ADDR = (USBOTG_H_FS->DEV_ADDR & USBFS_UDA_GP_BIT) | (dev_addr & USBFS_USB_ADDR_MASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Set port speed */
|
/** Set port speed */
|
||||||
static void hardware_update_port_speed(tusb_speed_t speed)
|
static void hardware_update_port_speed(tusb_speed_t speed) {
|
||||||
{
|
LOG_CH32_USBFSH("hardware_update_port_speed(%s)\r\n", speed == TUSB_SPEED_FULL ? "Full" : speed == TUSB_SPEED_LOW ? "Low"
|
||||||
LOG_CH32_USBFSH("hardware_update_port_speed(%s)\r\n", speed == TUSB_SPEED_FULL ? "Full" : speed == TUSB_SPEED_LOW ? "Low" : "(invalid)");
|
: "(invalid)");
|
||||||
switch (speed) {
|
switch (speed) {
|
||||||
case TUSB_SPEED_LOW:
|
case TUSB_SPEED_LOW:
|
||||||
USBOTG_H_FS->BASE_CTRL |= USBFS_UC_LOW_SPEED;
|
USBOTG_H_FS->BASE_CTRL |= USBFS_UC_LOW_SPEED;
|
||||||
@@ -262,7 +238,6 @@ static void hardware_update_port_speed(tusb_speed_t speed)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void hardware_set_port_address_speed(uint8_t dev_addr) {
|
static void hardware_set_port_address_speed(uint8_t dev_addr) {
|
||||||
hardware_update_device_address(dev_addr);
|
hardware_update_device_address(dev_addr);
|
||||||
tusb_speed_t rhport_speed = hcd_port_speed_get(0);
|
tusb_speed_t rhport_speed = hcd_port_speed_get(0);
|
||||||
@@ -273,18 +248,14 @@ static void hardware_set_port_address_speed(uint8_t dev_addr) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool hardware_device_attached(void) {
|
||||||
static bool hardware_device_attached(void)
|
|
||||||
{
|
|
||||||
return USBOTG_H_FS->MIS_ST & USBFS_UMS_DEV_ATTACH;
|
return USBOTG_H_FS->MIS_ST & USBFS_UMS_DEV_ATTACH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// HCD API
|
// HCD API
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
bool hcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init)
|
bool hcd_init(uint8_t rhport, const tusb_rhport_init_t *rh_init) {
|
||||||
{
|
|
||||||
(void) rhport;
|
(void) rhport;
|
||||||
(void) rh_init;
|
(void) rh_init;
|
||||||
hardware_init_host(true);
|
hardware_init_host(true);
|
||||||
@@ -292,19 +263,16 @@ bool hcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hcd_deinit(uint8_t rhport)
|
bool hcd_deinit(uint8_t rhport) {
|
||||||
{
|
|
||||||
(void) rhport;
|
(void) rhport;
|
||||||
hardware_init_host(false);
|
hardware_init_host(false);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static bool int_state_for_portreset = false;
|
static bool int_state_for_portreset = false;
|
||||||
|
|
||||||
void hcd_port_reset(uint8_t rhport)
|
void hcd_port_reset(uint8_t rhport) {
|
||||||
{
|
|
||||||
(void) rhport;
|
(void) rhport;
|
||||||
LOG_CH32_USBFSH("hcd_port_reset()\r\n");
|
LOG_CH32_USBFSH("hcd_port_reset()\r\n");
|
||||||
int_state_for_portreset = interrupt_enabled;
|
int_state_for_portreset = interrupt_enabled;
|
||||||
@@ -319,18 +287,15 @@ void hcd_port_reset(uint8_t rhport)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void hcd_port_reset_end(uint8_t rhport)
|
void hcd_port_reset_end(uint8_t rhport) {
|
||||||
{
|
|
||||||
(void) rhport;
|
(void) rhport;
|
||||||
LOG_CH32_USBFSH("hcd_port_reset_end()\r\n");
|
LOG_CH32_USBFSH("hcd_port_reset_end()\r\n");
|
||||||
|
|
||||||
USBOTG_H_FS->HOST_CTRL &= ~USBFS_UH_BUS_RESET;
|
USBOTG_H_FS->HOST_CTRL &= ~USBFS_UH_BUS_RESET;
|
||||||
osal_task_delay(2);
|
tusb_time_delay_ms_api(2);
|
||||||
|
|
||||||
if ((USBOTG_H_FS->HOST_CTRL & USBFS_UH_PORT_EN) == 0)
|
if ((USBOTG_H_FS->HOST_CTRL & USBFS_UH_PORT_EN) == 0) {
|
||||||
{
|
if (hcd_port_speed_get(0) == TUSB_SPEED_LOW) {
|
||||||
if (hcd_port_speed_get(0) == TUSB_SPEED_LOW)
|
|
||||||
{
|
|
||||||
hardware_update_port_speed(TUSB_SPEED_LOW);
|
hardware_update_port_speed(TUSB_SPEED_LOW);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -344,90 +309,67 @@ void hcd_port_reset_end(uint8_t rhport)
|
|||||||
if (int_state_for_portreset) {
|
if (int_state_for_portreset) {
|
||||||
hcd_int_enable(rhport);
|
hcd_int_enable(rhport);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hcd_port_connect_status(uint8_t rhport)
|
bool hcd_port_connect_status(uint8_t rhport) {
|
||||||
{
|
|
||||||
(void) rhport;
|
(void) rhport;
|
||||||
|
|
||||||
return hardware_device_attached();
|
return hardware_device_attached();
|
||||||
}
|
}
|
||||||
|
|
||||||
tusb_speed_t hcd_port_speed_get(uint8_t rhport)
|
tusb_speed_t hcd_port_speed_get(uint8_t rhport) {
|
||||||
{
|
|
||||||
(void) rhport;
|
(void) rhport;
|
||||||
if (USBOTG_H_FS->MIS_ST & USBFS_UMS_DM_LEVEL)
|
if (USBOTG_H_FS->MIS_ST & USBFS_UMS_DM_LEVEL) {
|
||||||
{
|
|
||||||
return TUSB_SPEED_LOW;
|
return TUSB_SPEED_LOW;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
return TUSB_SPEED_FULL;
|
return TUSB_SPEED_FULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close all opened endpoint belong to this device
|
// 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) {
|
||||||
{
|
|
||||||
(void) rhport;
|
(void) rhport;
|
||||||
LOG_CH32_USBFSH("hcd_device_close(%d, 0x%02x)\r\n", rhport, dev_addr);
|
LOG_CH32_USBFSH("hcd_device_close(%d, 0x%02x)\r\n", rhport, dev_addr);
|
||||||
remove_edpt_record_for_device(dev_addr);
|
remove_edpt_record_for_device(dev_addr);
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t hcd_frame_number(uint8_t rhport)
|
uint32_t hcd_frame_number(uint8_t rhport) {
|
||||||
{
|
|
||||||
(void) rhport;
|
(void) rhport;
|
||||||
|
|
||||||
return board_millis();
|
return board_millis();
|
||||||
}
|
}
|
||||||
|
|
||||||
void hcd_int_enable(uint8_t rhport)
|
void hcd_int_enable(uint8_t rhport) {
|
||||||
{
|
|
||||||
(void) rhport;
|
(void) rhport;
|
||||||
NVIC_EnableIRQ(USBFS_IRQn);
|
NVIC_EnableIRQ(USBFS_IRQn);
|
||||||
interrupt_enabled = true;
|
interrupt_enabled = true;
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void hcd_int_disable(uint8_t rhport)
|
void hcd_int_disable(uint8_t rhport) {
|
||||||
{
|
|
||||||
(void) rhport;
|
(void) rhport;
|
||||||
NVIC_DisableIRQ(USBFS_IRQn);
|
NVIC_DisableIRQ(USBFS_IRQn);
|
||||||
interrupt_enabled = false;
|
interrupt_enabled = false;
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void hcd_int_handler(uint8_t rhport, bool in_isr)
|
void hcd_int_handler(uint8_t rhport, bool in_isr) {
|
||||||
{
|
|
||||||
(void) rhport;
|
(void) rhport;
|
||||||
(void) in_isr;
|
(void) in_isr;
|
||||||
|
|
||||||
if (USBOTG_H_FS->INT_FG & USBFS_UIF_DETECT)
|
if (USBOTG_H_FS->INT_FG & USBFS_UIF_DETECT) {
|
||||||
{
|
|
||||||
// Clear the flag
|
// Clear the flag
|
||||||
USBOTG_H_FS->INT_FG = USBFS_UIF_DETECT;
|
USBOTG_H_FS->INT_FG = USBFS_UIF_DETECT;
|
||||||
// Read the detection state
|
// Read the detection state
|
||||||
bool attached = hardware_device_attached();
|
bool attached = hardware_device_attached();
|
||||||
LOG_CH32_USBFSH("hcd_int_handler() attached = %d\r\n", attached ? 1 : 0);
|
LOG_CH32_USBFSH("hcd_int_handler() attached = %d\r\n", attached ? 1 : 0);
|
||||||
if (attached)
|
if (attached) {
|
||||||
{
|
|
||||||
hcd_event_device_attach(rhport, true);
|
hcd_event_device_attach(rhport, true);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
hcd_event_device_remove(rhport, true);
|
hcd_event_device_remove(rhport, true);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (USBOTG_H_FS->INT_FG & USBFS_UIF_TRANSFER)
|
if (USBOTG_H_FS->INT_FG & USBFS_UIF_TRANSFER) {
|
||||||
{
|
|
||||||
// Disable transfer interrupt
|
// Disable transfer interrupt
|
||||||
USBOTG_H_FS->INT_EN &= ~USBFS_UIE_TRANSFER;
|
USBOTG_H_FS->INT_EN &= ~USBFS_UIE_TRANSFER;
|
||||||
// Clear the flag
|
// Clear the flag
|
||||||
@@ -444,43 +386,34 @@ void hcd_int_handler(uint8_t rhport, bool in_isr)
|
|||||||
uint8_t request_pid = pid_edpt >> 4;
|
uint8_t request_pid = pid_edpt >> 4;
|
||||||
uint8_t response_pid = status & USBFS_UIS_H_RES_MASK;
|
uint8_t response_pid = status & USBFS_UIS_H_RES_MASK;
|
||||||
uint8_t ep_addr = pid_edpt & 0x0f;
|
uint8_t ep_addr = pid_edpt & 0x0f;
|
||||||
if (request_pid == USB_PID_IN)
|
if (request_pid == USB_PID_IN) {
|
||||||
{
|
|
||||||
ep_addr |= 0x80;
|
ep_addr |= 0x80;
|
||||||
}
|
}
|
||||||
|
|
||||||
usb_edpt_t *edpt_info = get_edpt_record(dev_addr, ep_addr);
|
usb_edpt_t *edpt_info = get_edpt_record(dev_addr, ep_addr);
|
||||||
if (edpt_info == NULL)
|
if (edpt_info == NULL) {
|
||||||
{
|
|
||||||
PANIC("\r\nget_edpt_record(0x%02x, 0x%02x) returned NULL in USBHD_IRQHandler\r\n", dev_addr, ep_addr);
|
PANIC("\r\nget_edpt_record(0x%02x, 0x%02x) returned NULL in USBHD_IRQHandler\r\n", dev_addr, ep_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status & USBFS_UIS_TOG_OK)
|
if (status & USBFS_UIS_TOG_OK) {
|
||||||
{
|
|
||||||
edpt_info->data_toggle ^= 0x01;
|
edpt_info->data_toggle ^= 0x01;
|
||||||
|
|
||||||
switch (request_pid)
|
switch (request_pid) {
|
||||||
{
|
|
||||||
case USB_PID_SETUP:
|
case USB_PID_SETUP:
|
||||||
case USB_PID_OUT:
|
case USB_PID_OUT: {
|
||||||
{
|
|
||||||
uint16_t tx_len = USBOTG_H_FS->HOST_TX_LEN;
|
uint16_t tx_len = USBOTG_H_FS->HOST_TX_LEN;
|
||||||
usb_current_xfer_info.bufferlen -= tx_len;
|
usb_current_xfer_info.bufferlen -= tx_len;
|
||||||
usb_current_xfer_info.xferred_len += tx_len;
|
usb_current_xfer_info.xferred_len += tx_len;
|
||||||
if (usb_current_xfer_info.bufferlen == 0)
|
if (usb_current_xfer_info.bufferlen == 0) {
|
||||||
{
|
|
||||||
LOG_CH32_USBFSH("USB_PID_%s completed %d bytes\r\n", request_pid == USB_PID_OUT ? "OUT" : "SETUP", usb_current_xfer_info.xferred_len);
|
LOG_CH32_USBFSH("USB_PID_%s completed %d bytes\r\n", request_pid == USB_PID_OUT ? "OUT" : "SETUP", usb_current_xfer_info.xferred_len);
|
||||||
usb_current_xfer_info.is_busy = false;
|
usb_current_xfer_info.is_busy = false;
|
||||||
hcd_event_xfer_complete(dev_addr, ep_addr, usb_current_xfer_info.xferred_len, XFER_RESULT_SUCCESS, true);
|
hcd_event_xfer_complete(dev_addr, ep_addr, usb_current_xfer_info.xferred_len, XFER_RESULT_SUCCESS, true);
|
||||||
return;
|
return;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
LOG_CH32_USBFSH("USB_PID_OUT continue...\r\n");
|
LOG_CH32_USBFSH("USB_PID_OUT continue...\r\n");
|
||||||
usb_current_xfer_info.buffer += tx_len;
|
usb_current_xfer_info.buffer += tx_len;
|
||||||
uint16_t copylen = USBFS_TX_BUF_LEN;
|
uint16_t copylen = USBFS_TX_BUF_LEN;
|
||||||
if (copylen > usb_current_xfer_info.bufferlen)
|
if (copylen > usb_current_xfer_info.bufferlen) {
|
||||||
{
|
|
||||||
copylen = usb_current_xfer_info.bufferlen;
|
copylen = usb_current_xfer_info.bufferlen;
|
||||||
}
|
}
|
||||||
memcpy(USBFS_TX_Buf, usb_current_xfer_info.buffer, copylen);
|
memcpy(USBFS_TX_Buf, usb_current_xfer_info.buffer, copylen);
|
||||||
@@ -488,8 +421,7 @@ void hcd_int_handler(uint8_t rhport, bool in_isr)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case USB_PID_IN:
|
case USB_PID_IN: {
|
||||||
{
|
|
||||||
uint16_t received_len = USBOTG_H_FS->RX_LEN;
|
uint16_t received_len = USBOTG_H_FS->RX_LEN;
|
||||||
usb_current_xfer_info.xferred_len += received_len;
|
usb_current_xfer_info.xferred_len += received_len;
|
||||||
uint16_t xferred_len = usb_current_xfer_info.xferred_len;
|
uint16_t xferred_len = usb_current_xfer_info.xferred_len;
|
||||||
@@ -499,67 +431,49 @@ void hcd_int_handler(uint8_t rhport, bool in_isr)
|
|||||||
// }
|
// }
|
||||||
memcpy(usb_current_xfer_info.buffer, USBFS_RX_Buf, received_len);
|
memcpy(usb_current_xfer_info.buffer, USBFS_RX_Buf, received_len);
|
||||||
usb_current_xfer_info.buffer += received_len;
|
usb_current_xfer_info.buffer += received_len;
|
||||||
if ((received_len < edpt_info->max_packet_size) || (xferred_len == usb_current_xfer_info.bufferlen))
|
if ((received_len < edpt_info->max_packet_size) || (xferred_len == usb_current_xfer_info.bufferlen)) {
|
||||||
{
|
|
||||||
// USB device sent all data.
|
// USB device sent all data.
|
||||||
LOG_CH32_USBFSH("USB_PID_IN completed\r\n");
|
LOG_CH32_USBFSH("USB_PID_IN completed\r\n");
|
||||||
usb_current_xfer_info.is_busy = false;
|
usb_current_xfer_info.is_busy = false;
|
||||||
hcd_event_xfer_complete(dev_addr, ep_addr, xferred_len, XFER_RESULT_SUCCESS, true);
|
hcd_event_xfer_complete(dev_addr, ep_addr, xferred_len, XFER_RESULT_SUCCESS, true);
|
||||||
return;
|
return;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// USB device may send more data.
|
// USB device may send more data.
|
||||||
LOG_CH32_USBFSH("Read more data\r\n");
|
LOG_CH32_USBFSH("Read more data\r\n");
|
||||||
hardware_start_xfer(USB_PID_IN, ep_addr, edpt_info->data_toggle);
|
hardware_start_xfer(USB_PID_IN, ep_addr, edpt_info->data_toggle);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
default:
|
default: {
|
||||||
{
|
|
||||||
PANIC("Unknown PID: 0x%02x\n", request_pid);
|
PANIC("Unknown PID: 0x%02x\n", request_pid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
if (response_pid == USB_PID_STALL) {
|
||||||
{
|
|
||||||
if (response_pid == USB_PID_STALL)
|
|
||||||
{
|
|
||||||
LOG_CH32_USBFSH("STALL response\r\n");
|
LOG_CH32_USBFSH("STALL response\r\n");
|
||||||
hcd_edpt_clear_stall(0, dev_addr, ep_addr);
|
hcd_edpt_clear_stall(0, dev_addr, ep_addr);
|
||||||
edpt_info->data_toggle = 0;
|
edpt_info->data_toggle = 0;
|
||||||
hardware_start_xfer(request_pid, ep_addr, 0);
|
hardware_start_xfer(request_pid, ep_addr, 0);
|
||||||
return;
|
return;
|
||||||
}
|
} else if (response_pid == USB_PID_NAK) {
|
||||||
else if (response_pid == USB_PID_NAK)
|
|
||||||
{
|
|
||||||
LOG_CH32_USBFSH("NAK reposense\r\n");
|
LOG_CH32_USBFSH("NAK reposense\r\n");
|
||||||
uint32_t elapsed_time = board_millis() - usb_current_xfer_info.start_ms;
|
uint32_t elapsed_time = board_millis() - usb_current_xfer_info.start_ms;
|
||||||
if (edpt_info->xfer_type == TUSB_XFER_INTERRUPT)
|
if (edpt_info->xfer_type == TUSB_XFER_INTERRUPT) {
|
||||||
{
|
|
||||||
usb_current_xfer_info.is_busy = false;
|
usb_current_xfer_info.is_busy = false;
|
||||||
hcd_event_xfer_complete(dev_addr, ep_addr, 0, XFER_RESULT_SUCCESS, true);
|
hcd_event_xfer_complete(dev_addr, ep_addr, 0, XFER_RESULT_SUCCESS, true);
|
||||||
}
|
} else if (elapsed_time > USB_XFER_TIMEOUT_MILLIS) {
|
||||||
else if (elapsed_time > USB_XFER_TIMEOUT_MILLIS)
|
|
||||||
{
|
|
||||||
usb_current_xfer_info.is_busy = false;
|
usb_current_xfer_info.is_busy = false;
|
||||||
hcd_event_xfer_complete(dev_addr, ep_addr, 0, XFER_RESULT_FAILED, true);
|
hcd_event_xfer_complete(dev_addr, ep_addr, 0, XFER_RESULT_FAILED, true);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
hardware_start_xfer(request_pid, ep_addr, edpt_info->data_toggle);
|
hardware_start_xfer(request_pid, ep_addr, edpt_info->data_toggle);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
} else if (response_pid == USB_PID_DATA0 || response_pid == USB_PID_DATA1) {
|
||||||
else if (response_pid == USB_PID_DATA0 || response_pid == USB_PID_DATA1)
|
|
||||||
{
|
|
||||||
LOG_CH32_USBFSH("Data toggle mismatched and DATA0/1 (not STALL). RX_LEN=%d\r\n", USBOTG_H_FS->RX_LEN);
|
LOG_CH32_USBFSH("Data toggle mismatched and DATA0/1 (not STALL). RX_LEN=%d\r\n", USBOTG_H_FS->RX_LEN);
|
||||||
usb_current_xfer_info.is_busy = false;
|
usb_current_xfer_info.is_busy = false;
|
||||||
hcd_event_xfer_complete(dev_addr, ep_addr, 0, XFER_RESULT_FAILED, true);
|
hcd_event_xfer_complete(dev_addr, ep_addr, 0, XFER_RESULT_FAILED, true);
|
||||||
return;
|
return;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
LOG_CH32_USBFSH("In USBHD_IRQHandler, unexpected response PID: 0x%02x\r\n", response_pid);
|
LOG_CH32_USBFSH("In USBHD_IRQHandler, unexpected response PID: 0x%02x\r\n", response_pid);
|
||||||
usb_current_xfer_info.is_busy = false;
|
usb_current_xfer_info.is_busy = false;
|
||||||
hcd_event_xfer_complete(dev_addr, ep_addr, 0, XFER_RESULT_FAILED, true);
|
hcd_event_xfer_complete(dev_addr, ep_addr, 0, XFER_RESULT_FAILED, true);
|
||||||
@@ -573,8 +487,7 @@ void hcd_int_handler(uint8_t rhport, bool in_isr)
|
|||||||
// Endpoint API
|
// Endpoint API
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const * ep_desc)
|
bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const *ep_desc) {
|
||||||
{
|
|
||||||
(void) rhport;
|
(void) rhport;
|
||||||
uint8_t ep_addr = ep_desc->bEndpointAddress;
|
uint8_t ep_addr = ep_desc->bEndpointAddress;
|
||||||
uint8_t ep_num = tu_edpt_number(ep_addr);
|
uint8_t ep_num = tu_edpt_number(ep_addr);
|
||||||
@@ -582,17 +495,13 @@ bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const
|
|||||||
uint8_t xfer_type = ep_desc->bmAttributes.xfer;
|
uint8_t xfer_type = ep_desc->bmAttributes.xfer;
|
||||||
LOG_CH32_USBFSH("hcd_edpt_open(rhport=%d, dev_addr=0x%02x, %p) EndpointAdderss=0x%02x,maxPacketSize=%d,xfer_type=%d\r\n", rhport, dev_addr, ep_desc, ep_addr, max_packet_size, xfer_type);
|
LOG_CH32_USBFSH("hcd_edpt_open(rhport=%d, dev_addr=0x%02x, %p) EndpointAdderss=0x%02x,maxPacketSize=%d,xfer_type=%d\r\n", rhport, dev_addr, ep_desc, ep_addr, max_packet_size, xfer_type);
|
||||||
|
|
||||||
if (ep_num == 0x00)
|
if (ep_num == 0x00) {
|
||||||
{
|
|
||||||
TU_ASSERT(get_or_add_edpt_record(dev_addr, 0x00, max_packet_size, xfer_type) != NULL, false);
|
TU_ASSERT(get_or_add_edpt_record(dev_addr, 0x00, max_packet_size, xfer_type) != NULL, false);
|
||||||
TU_ASSERT(get_or_add_edpt_record(dev_addr, 0x80, max_packet_size, xfer_type) != NULL, false);
|
TU_ASSERT(get_or_add_edpt_record(dev_addr, 0x80, max_packet_size, xfer_type) != NULL, false);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
TU_ASSERT(get_or_add_edpt_record(dev_addr, ep_addr, max_packet_size, xfer_type) != NULL, false);
|
TU_ASSERT(get_or_add_edpt_record(dev_addr, ep_addr, max_packet_size, xfer_type) != NULL, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
USBOTG_H_FS->HOST_CTRL |= USBFS_UH_PORT_EN;
|
USBOTG_H_FS->HOST_CTRL |= USBFS_UH_PORT_EN;
|
||||||
USBOTG_H_FS->HOST_SETUP |= USBFS_UH_SOF_EN;
|
USBOTG_H_FS->HOST_SETUP |= USBFS_UH_SOF_EN;
|
||||||
|
|
||||||
@@ -601,19 +510,16 @@ bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
{
|
|
||||||
(void) rhport;
|
(void) rhport;
|
||||||
|
|
||||||
LOG_CH32_USBFSH("hcd_edpt_xfer(%d, 0x%02x, 0x%02x, ...)\r\n", rhport, dev_addr, ep_addr);
|
LOG_CH32_USBFSH("hcd_edpt_xfer(%d, 0x%02x, 0x%02x, ...)\r\n", rhport, dev_addr, ep_addr);
|
||||||
|
|
||||||
while (usb_current_xfer_info.is_busy) {}
|
while (usb_current_xfer_info.is_busy) {}
|
||||||
|
|
||||||
usb_current_xfer_info.is_busy = true;
|
usb_current_xfer_info.is_busy = true;
|
||||||
|
|
||||||
usb_edpt_t *edpt_info = get_edpt_record(dev_addr, ep_addr);
|
usb_edpt_t *edpt_info = get_edpt_record(dev_addr, ep_addr);
|
||||||
if (edpt_info == NULL)
|
if (edpt_info == NULL) {
|
||||||
{
|
|
||||||
PANIC("get_edpt_record() returned NULL in hcd_edpt_xfer()\r\n");
|
PANIC("get_edpt_record() returned NULL in hcd_edpt_xfer()\r\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -626,17 +532,13 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *
|
|||||||
usb_current_xfer_info.start_ms = board_millis();
|
usb_current_xfer_info.start_ms = board_millis();
|
||||||
usb_current_xfer_info.xferred_len = 0;
|
usb_current_xfer_info.xferred_len = 0;
|
||||||
|
|
||||||
if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN)
|
if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN) {
|
||||||
{
|
|
||||||
LOG_CH32_USBFSH("hcd_edpt_xfer(): READ, dev_addr=0x%02x, ep_addr=0x%02x, len=%d\r\n", dev_addr, ep_addr, buflen);
|
LOG_CH32_USBFSH("hcd_edpt_xfer(): READ, dev_addr=0x%02x, ep_addr=0x%02x, len=%d\r\n", dev_addr, ep_addr, buflen);
|
||||||
return hardware_start_xfer(USB_PID_IN, ep_addr, edpt_info->data_toggle);
|
return hardware_start_xfer(USB_PID_IN, ep_addr, edpt_info->data_toggle);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
LOG_CH32_USBFSH("hcd_edpt_xfer(): WRITE, dev_addr=0x%02x, ep_addr=0x%02x, len=%d\r\n", dev_addr, ep_addr, buflen);
|
LOG_CH32_USBFSH("hcd_edpt_xfer(): WRITE, dev_addr=0x%02x, ep_addr=0x%02x, len=%d\r\n", dev_addr, ep_addr, buflen);
|
||||||
uint16_t copylen = USBFS_TX_BUF_LEN;
|
uint16_t copylen = USBFS_TX_BUF_LEN;
|
||||||
if (copylen > buflen)
|
if (copylen > buflen) {
|
||||||
{
|
|
||||||
copylen = buflen;
|
copylen = buflen;
|
||||||
}
|
}
|
||||||
USBOTG_H_FS->HOST_TX_LEN = copylen;
|
USBOTG_H_FS->HOST_TX_LEN = copylen;
|
||||||
@@ -645,8 +547,7 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hcd_edpt_abort_xfer(uint8_t rhport, 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) rhport;
|
||||||
(void) dev_addr;
|
(void) dev_addr;
|
||||||
(void) ep_addr;
|
(void) ep_addr;
|
||||||
@@ -654,8 +555,7 @@ bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8])
|
bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8]) {
|
||||||
{
|
|
||||||
(void) rhport;
|
(void) rhport;
|
||||||
|
|
||||||
while (usb_current_xfer_info.is_busy) {}
|
while (usb_current_xfer_info.is_busy) {}
|
||||||
@@ -692,8 +592,7 @@ bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr)
|
bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) {
|
||||||
{
|
|
||||||
(void) rhport;
|
(void) rhport;
|
||||||
(void) dev_addr;
|
(void) dev_addr;
|
||||||
LOG_CH32_USBFSH("hcd_edpt_clear_stall(rhport=%d, dev_addr=0x%02x, ep_addr=0x%02x)\r\n", rhport, dev_addr, ep_addr);
|
LOG_CH32_USBFSH("hcd_edpt_clear_stall(rhport=%d, dev_addr=0x%02x, ep_addr=0x%02x)\r\n", rhport, dev_addr, ep_addr);
|
||||||
|
Reference in New Issue
Block a user