mirror of
https://github.com/hathach/tinyusb.git
synced 2025-01-31 05:52:55 +08:00
commit
b03a688b24
@ -108,6 +108,17 @@ enum
|
||||
#define EPNUM_CDC_1_OUT 0x05
|
||||
#define EPNUM_CDC_1_IN 0x86
|
||||
|
||||
#elif CFG_TUSB_MCU == OPT_MCU_FT90X || CFG_TUSB_MCU == OPT_MCU_FT93X
|
||||
// FT9XX doesn't support a same endpoint number with different direction IN and OUT
|
||||
// e.g EP1 OUT & EP1 IN cannot exist together
|
||||
#define EPNUM_CDC_0_NOTIF 0x81
|
||||
#define EPNUM_CDC_0_OUT 0x02
|
||||
#define EPNUM_CDC_0_IN 0x83
|
||||
|
||||
#define EPNUM_CDC_1_NOTIF 0x84
|
||||
#define EPNUM_CDC_1_OUT 0x05
|
||||
#define EPNUM_CDC_1_IN 0x86
|
||||
|
||||
#else
|
||||
#define EPNUM_CDC_0_NOTIF 0x81
|
||||
#define EPNUM_CDC_0_OUT 0x02
|
||||
|
@ -145,6 +145,19 @@ enum
|
||||
#define EPNUM_1_MSC_OUT 0x01
|
||||
#define EPNUM_1_MSC_IN 0x82
|
||||
|
||||
#elif CFG_TUSB_MCU == OPT_MCU_FT90X || CFG_TUSB_MCU == OPT_MCU_FT93X
|
||||
// FT9XX doesn't support a same endpoint number with different direction IN and OUT
|
||||
// e.g EP1 OUT & EP1 IN cannot exist together
|
||||
#define EPNUM_0_CDC_NOTIF 0x81
|
||||
#define EPNUM_0_CDC_OUT 0x02
|
||||
#define EPNUM_0_CDC_IN 0x83
|
||||
|
||||
#define EPNUM_0_MIDI_OUT 0x04
|
||||
#define EPNUM_0_MIDI_IN 0x85
|
||||
|
||||
#define EPNUM_1_MSC_OUT 0x01
|
||||
#define EPNUM_1_MSC_IN 0x82
|
||||
|
||||
#else
|
||||
#define EPNUM_0_CDC_NOTIF 0x81
|
||||
#define EPNUM_0_CDC_OUT 0x02
|
||||
|
@ -90,6 +90,12 @@ enum
|
||||
#define EPNUM_MSC_OUT 0x01
|
||||
#define EPNUM_MSC_IN 0x82
|
||||
|
||||
#elif CFG_TUSB_MCU == OPT_MCU_FT90X || CFG_TUSB_MCU == OPT_MCU_FT93X
|
||||
// FT9XX doesn't support a same endpoint number with different direction IN and OUT
|
||||
// e.g EP1 OUT & EP1 IN cannot exist together
|
||||
#define EPNUM_MSC_OUT 0x01
|
||||
#define EPNUM_MSC_IN 0x82
|
||||
|
||||
#else
|
||||
#define EPNUM_MSC_OUT 0x01
|
||||
#define EPNUM_MSC_IN 0x81
|
||||
|
@ -93,6 +93,12 @@ uint8_t const * tud_descriptor_device_cb(void)
|
||||
#define EPNUM_AUDIO_IN 0x01
|
||||
#define EPNUM_AUDIO_OUT 0x02
|
||||
|
||||
#elif CFG_TUSB_MCU == OPT_MCU_FT90X || CFG_TUSB_MCU == OPT_MCU_FT93X
|
||||
// FT9XX doesn't support a same endpoint number with different direction IN and OUT
|
||||
// e.g EP1 OUT & EP1 IN cannot exist together
|
||||
#define EPNUM_AUDIO_IN 0x01
|
||||
#define EPNUM_AUDIO_OUT 0x02
|
||||
|
||||
#else
|
||||
#define EPNUM_AUDIO_IN 0x01
|
||||
#define EPNUM_AUDIO_OUT 0x01
|
||||
|
@ -97,6 +97,13 @@ enum
|
||||
#define EPNUM_CDC_OUT 3
|
||||
#define EPNUM_VENDOR_IN 4
|
||||
#define EPNUM_VENDOR_OUT 5
|
||||
#elif CFG_TUSB_MCU == OPT_MCU_FT90X || CFG_TUSB_MCU == OPT_MCU_FT93X
|
||||
// FT9XX doesn't support a same endpoint number with different direction IN and OUT
|
||||
// e.g EP1 OUT & EP1 IN cannot exist together
|
||||
#define EPNUM_CDC_IN 2
|
||||
#define EPNUM_CDC_OUT 3
|
||||
#define EPNUM_VENDOR_IN 4
|
||||
#define EPNUM_VENDOR_OUT 5
|
||||
#else
|
||||
#define EPNUM_CDC_IN 2
|
||||
#define EPNUM_CDC_OUT 2
|
||||
|
@ -27,21 +27,53 @@
|
||||
#ifndef BOARD_H_
|
||||
#define BOARD_H_
|
||||
|
||||
// Note: This definition file covers all MM900EV1B, MM900EV2B, and MM900EV3B boards.
|
||||
// Note: This definition file covers all MM900EV1B, MM900EV2B, MM900EV3B,
|
||||
// MM900EV-Lite boards.
|
||||
// Each of these boards has an FT900 device.
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define GPIO_UART0_TX 48
|
||||
#define GPIO_UART0_RX 49
|
||||
#define GPIO_ETH_LED0 61
|
||||
#define GPIO_ETH_LED1 62
|
||||
#define GPIO_REMOTE_WAKEUP_PIN 18
|
||||
#define USBD_VBUS_DTC_PIN 3
|
||||
// UART to use on this board.
|
||||
#ifndef BOARD_UART
|
||||
#define BOARD_UART UART0
|
||||
#endif
|
||||
|
||||
#define GPIO_REMOTE_WAKEUP
|
||||
// UART is on connector CN1.
|
||||
#ifndef BOARD_GPIO_UART0_TX
|
||||
#define BOARD_GPIO_UART0_TX 48 // Pin 4 of CN1.
|
||||
#endif
|
||||
#ifndef BOARD_GPIO_UART0_RX
|
||||
#define BOARD_GPIO_UART0_RX 49 // Pin 6 of CN1.
|
||||
#endif
|
||||
|
||||
// LED is connected to pins 17 (signal) and 15 (GND) of CN1.
|
||||
#ifndef BOARD_GPIO_LED
|
||||
#define BOARD_GPIO_LED 35
|
||||
#endif
|
||||
#ifndef BOARD_GPIO_LED_STATE_ON
|
||||
#define BOARD_GPIO_LED_STATE_ON 1
|
||||
#endif
|
||||
// Button is connected to pins 13 (signal) and 15 (GND) of CN1.
|
||||
#ifndef BOARD_GPIO_BUTTON
|
||||
#define BOARD_GPIO_BUTTON 56
|
||||
#endif
|
||||
// Button is pulled up and grounded for active.
|
||||
#ifndef BOARD_GPIO_BUTTON_STATE_ACTIVE
|
||||
#define BOARD_GPIO_BUTTON_STATE_ACTIVE 0
|
||||
#endif
|
||||
|
||||
// Enable the Remote Wakeup signalling.
|
||||
// Remote wakeup is wired to pin 40 of CN1.
|
||||
#ifndef BOARD_GPIO_REMOTE_WAKEUP
|
||||
#define BOARD_GPIO_REMOTE_WAKEUP 18
|
||||
#endif
|
||||
|
||||
// USB VBus signal is connected directly to the FT900.
|
||||
#ifndef BOARD_USBD_VBUS_DTC_PIN
|
||||
#define BOARD_USBD_VBUS_DTC_PIN 3
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -27,15 +27,15 @@
|
||||
#include "bsp/board.h"
|
||||
#include "board.h"
|
||||
|
||||
#include <registers/ft900_registers.h>
|
||||
#include <ft900.h>
|
||||
#include <registers/ft900_registers.h>
|
||||
|
||||
#if CFG_TUD_ENABLED
|
||||
int8_t board_ft90x_vbus(void); // Board specific implementation of VBUS detection for USB device.
|
||||
extern void ft90x_usbd_pm_ISR(uint16_t pmcfg); // Interrupt handler for USB device power management
|
||||
int8_t board_ft9xx_vbus(void); // Board specific implementation of VBUS detection for USB device.
|
||||
extern void ft9xx_usbd_pm_ISR(uint16_t pmcfg); // Interrupt handler for USB device power management
|
||||
#endif
|
||||
|
||||
#ifdef GPIO_REMOTE_WAKEUP
|
||||
#ifdef BOARD_GPIO_REMOTE_WAKEUP
|
||||
void gpio_ISR(void);
|
||||
#endif
|
||||
void timer_ISR(void);
|
||||
@ -49,12 +49,17 @@ void board_pm_ISR(void);
|
||||
void board_init(void)
|
||||
{
|
||||
sys_reset_all();
|
||||
|
||||
// Enable the UART Device.
|
||||
sys_enable(sys_device_uart0);
|
||||
// Set UART0 GPIO functions to UART0_TXD and UART0_RXD.
|
||||
gpio_function(GPIO_UART0_TX, pad_uart0_txd); /* UART0 TXD */
|
||||
gpio_function(GPIO_UART0_RX, pad_uart0_rxd); /* UART0 RXD */
|
||||
uart_open(UART0, /* Device */
|
||||
// Set BOARD_UART GPIO function pins for TXD and RXD.
|
||||
#ifdef BOARD_GPIO_UART_TX
|
||||
gpio_function(BOARD_GPIO_UART_TX, pad_uart0_txd); /* UART0 TXD */
|
||||
#endif
|
||||
#ifdef BOARD_GPIO_UART_RX
|
||||
gpio_function(BOARD_GPIO_UART_RX, pad_uart0_rxd); /* UART0 RXD */
|
||||
#endif
|
||||
uart_open(BOARD_UART, /* Device */
|
||||
1, /* Prescaler = 1 */
|
||||
UART_DIVIDER_19200_BAUD, /* Divider = 1302 */
|
||||
uart_data_bits_8, /* No. Data Bits */
|
||||
@ -64,12 +69,17 @@ void board_init(void)
|
||||
// Use sizeof to avoid pulling in strlen unnecessarily.
|
||||
board_uart_write(WELCOME_MSG, sizeof(WELCOME_MSG));
|
||||
|
||||
#if 0
|
||||
// Ethernet LEDs
|
||||
gpio_function(GPIO_ETH_LED0, pad_gpio4); /* ETH LED0 */
|
||||
gpio_dir(GPIO_ETH_LED0, pad_dir_open_drain);
|
||||
gpio_function(GPIO_ETH_LED1, pad_gpio5); /* ETH LED1 */
|
||||
gpio_dir(GPIO_ETH_LED1, pad_dir_output);
|
||||
#ifdef BOARD_GPIO_LED
|
||||
gpio_function(BOARD_GPIO_LED, pad_func_0);
|
||||
gpio_idrive(BOARD_GPIO_LED, pad_drive_12mA);
|
||||
gpio_dir(BOARD_GPIO_LED, pad_dir_output);
|
||||
#endif
|
||||
|
||||
#ifdef BOARD_GPIO_BUTTON
|
||||
gpio_function(BOARD_GPIO_BUTTON, pad_func_0);
|
||||
// Pull up if active low. Down if active high.
|
||||
gpio_pull(BOARD_GPIO_BUTTON, (BOARD_GPIO_BUTTON_STATE_ACTIVE == 0)?pad_pull_pullup:pad_pull_pulldown);
|
||||
gpio_dir(BOARD_GPIO_BUTTON, pad_dir_input);
|
||||
#endif
|
||||
|
||||
sys_enable(sys_device_timer_wdt);
|
||||
@ -82,26 +92,26 @@ void board_init(void)
|
||||
|
||||
// Setup VBUS detect GPIO. If the device is connected then this
|
||||
// will set the MASK_SYS_PMCFG_DEV_DETECT_EN bit in PMCFG.
|
||||
gpio_interrupt_disable(USBD_VBUS_DTC_PIN);
|
||||
gpio_function(USBD_VBUS_DTC_PIN, pad_vbus_dtc);
|
||||
gpio_pull(USBD_VBUS_DTC_PIN, pad_pull_pulldown);
|
||||
gpio_dir(USBD_VBUS_DTC_PIN, pad_dir_input);
|
||||
gpio_interrupt_disable(BOARD_USBD_VBUS_DTC_PIN);
|
||||
gpio_function(BOARD_USBD_VBUS_DTC_PIN, pad_vbus_dtc);
|
||||
gpio_pull(BOARD_USBD_VBUS_DTC_PIN, pad_pull_pulldown);
|
||||
gpio_dir(BOARD_USBD_VBUS_DTC_PIN, pad_dir_input);
|
||||
|
||||
interrupt_attach(interrupt_0, (int8_t)interrupt_0, board_pm_ISR);
|
||||
|
||||
#ifdef GPIO_REMOTE_WAKEUP
|
||||
//Configuring GPIO pin to wakeup.
|
||||
#ifdef BOARD_GPIO_REMOTE_WAKEUP
|
||||
// Configuring GPIO pin to wakeup.
|
||||
// Set up the wakeup pin.
|
||||
gpio_dir(GPIO_REMOTE_WAKEUP_PIN, pad_dir_input);
|
||||
gpio_pull(GPIO_REMOTE_WAKEUP_PIN, pad_pull_pullup);
|
||||
gpio_dir(BOARD_GPIO_REMOTE_WAKEUP, pad_dir_input);
|
||||
gpio_pull(BOARD_GPIO_REMOTE_WAKEUP, pad_pull_pullup);
|
||||
|
||||
// Attach an interrupt handler.
|
||||
interrupt_attach(interrupt_gpio, (uint8_t)interrupt_gpio, gpio_ISR);
|
||||
gpio_interrupt_enable(GPIO_REMOTE_WAKEUP_PIN, gpio_int_edge_falling);
|
||||
gpio_interrupt_enable(BOARD_GPIO_REMOTE_WAKEUP, gpio_int_edge_falling);
|
||||
#endif
|
||||
|
||||
uart_disable_interrupt(UART0, uart_interrupt_tx);
|
||||
uart_disable_interrupt(UART0, uart_interrupt_rx);
|
||||
uart_disable_interrupt(BOARD_UART, uart_interrupt_tx);
|
||||
uart_disable_interrupt(BOARD_UART, uart_interrupt_rx);
|
||||
|
||||
// Enable all peripheral interrupts.
|
||||
interrupt_enable_globally();
|
||||
@ -117,10 +127,10 @@ void timer_ISR(void)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef GPIO_REMOTE_WAKEUP
|
||||
#ifdef BOARD_GPIO_REMOTE_WAKEUP
|
||||
void gpio_ISR(void)
|
||||
{
|
||||
if (gpio_is_interrupted(GPIO_REMOTE_WAKEUP_PIN))
|
||||
if (gpio_is_interrupted(BOARD_GPIO_REMOTE_WAKEUP))
|
||||
{
|
||||
}
|
||||
}
|
||||
@ -153,16 +163,16 @@ void board_pm_ISR(void)
|
||||
)
|
||||
{
|
||||
#if CFG_TUD_ENABLED
|
||||
ft90x_usbd_pm_ISR(pmcfg);
|
||||
ft9xx_usbd_pm_ISR(pmcfg);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if CFG_TUD_ENABLED
|
||||
int8_t board_ft90x_vbus(void)
|
||||
int8_t board_ft9xx_vbus(void)
|
||||
{
|
||||
return gpio_read(USBD_VBUS_DTC_PIN);
|
||||
return gpio_read(BOARD_USBD_VBUS_DTC_PIN);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -173,20 +183,33 @@ int8_t board_ft90x_vbus(void)
|
||||
// Turn LED on or off
|
||||
void board_led_write(bool state)
|
||||
{
|
||||
gpio_write(GPIO_ETH_LED0, state);
|
||||
#ifdef BOARD_GPIO_LED
|
||||
gpio_write(BOARD_GPIO_LED, (state == 0)?(BOARD_GPIO_LED_STATE_ON?0:1):BOARD_GPIO_LED_STATE_ON);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Get the current state of button
|
||||
// a '1' means active (pressed), a '0' means inactive.
|
||||
uint32_t board_button_read(void)
|
||||
{
|
||||
return 0;
|
||||
uint32_t state = 0;
|
||||
#ifdef BOARD_GPIO_BUTTON
|
||||
state = (gpio_read(BOARD_GPIO_BUTTON) == BOARD_GPIO_BUTTON_STATE_ACTIVE)?1:0;
|
||||
#endif
|
||||
return state;
|
||||
}
|
||||
|
||||
// Get characters from UART
|
||||
int board_uart_read(uint8_t *buf, int len)
|
||||
{
|
||||
int r = uart_readn(UART0, (uint8_t *)buf, len);
|
||||
int r = 0;
|
||||
|
||||
#ifdef BOARD_UART
|
||||
if (uart_rx_has_data(BOARD_UART))
|
||||
{
|
||||
r = uart_readn(BOARD_UART, (uint8_t *)buf, len);
|
||||
}
|
||||
#endif
|
||||
|
||||
return r;
|
||||
}
|
||||
@ -194,10 +217,14 @@ int board_uart_read(uint8_t *buf, int len)
|
||||
// Send characters to UART
|
||||
int board_uart_write(void const *buf, int len)
|
||||
{
|
||||
int r = 0;
|
||||
|
||||
#ifdef BOARD_UART
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wcast-qual" // uart_writen does not have const for buffer parameter.
|
||||
int r = uart_writen(UART0, (uint8_t *)((const void *)buf), len);
|
||||
r = uart_writen(BOARD_UART, (uint8_t *)((const void *)buf), len);
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
return r;
|
||||
}
|
||||
@ -213,3 +240,18 @@ uint32_t board_millis(void)
|
||||
|
||||
return safe_ms;
|
||||
}
|
||||
|
||||
// Restart the program
|
||||
// Called in the event of a watchdog timeout
|
||||
void chip_reboot(void)
|
||||
{
|
||||
// SOFT reset
|
||||
__asm__("call 0");
|
||||
#if 0
|
||||
// HARD reset
|
||||
// Initiates data transfer from Flash Memory to Data Memory (DBG_CMDF2D3)
|
||||
// followed by a system reboot
|
||||
dbg_memory_copy(0xfe, 0, 0, 255);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -3,12 +3,12 @@ CROSS_COMPILE = ft32-elf-
|
||||
SKIP_NANOLIB = 1
|
||||
|
||||
# Set to use FT90X prebuilt libraries.
|
||||
FT90X_PREBUILT_LIBS = 0
|
||||
ifeq ($(FT90X_PREBUILT_LIBS),1)
|
||||
FT9XX_PREBUILT_LIBS = 0
|
||||
ifeq ($(FT9XX_PREBUILT_LIBS),1)
|
||||
# If the FT90X toolchain is installed on Windows systems then the SDK
|
||||
# include files and prebuilt libraries are at: %FT90X_TOOLCHAIN%/hardware
|
||||
FT9XX_SDK = $(FT90X_TOOLCHAIN)/hardware
|
||||
INC += $(FT9XX_SDK)/include
|
||||
INC += "$(FT9XX_SDK)/include"
|
||||
else
|
||||
# The submodule BRTSG-FOSS/ft90x-sdk contains header files and source
|
||||
# code for the Bridgetek SDK. This can be used instead of the prebuilt
|
||||
@ -16,12 +16,12 @@ else
|
||||
DEPS_SUBMODULES += hw/mcu/bridgetek/ft9xx/ft90x-sdk
|
||||
# The SDK can be used to load specific files from the Bridgetek SDK.
|
||||
FT9XX_SDK = hw/mcu/bridgetek/ft9xx/ft90x-sdk/Source
|
||||
INC += $(TOP)/$(FT9XX_SDK)/include
|
||||
INC += "$(TOP)/$(FT9XX_SDK)/include"
|
||||
endif
|
||||
|
||||
# Add include files which are within the TinyUSB directory structure.
|
||||
INC += \
|
||||
$(TOP)/$(BOARD_PATH)
|
||||
$(TOP)/$(BOARD_PATH)
|
||||
|
||||
# Add required C Compiler flags for FT90X.
|
||||
CFLAGS += \
|
||||
@ -30,14 +30,14 @@ CFLAGS += \
|
||||
-fvar-tracking-assignments \
|
||||
-fmessage-length=0 \
|
||||
-ffunction-sections \
|
||||
-DCFG_TUSB_MCU=OPT_MCU_FT90X
|
||||
-DCFG_TUSB_MCU=OPT_MCU_FT90X
|
||||
|
||||
# Maximum USB device speed supported by the board
|
||||
CFLAGS += -DBOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED
|
||||
|
||||
# lwip/src/core/raw.c:334:43: error: declaration of 'recv' shadows a global declaration
|
||||
CFLAGS += -Wno-error=shadow
|
||||
|
||||
# Add include files outside the TinyUSB structure that are added manually.
|
||||
CFLAGS += -I"$(FT9XX_SDK)/include"
|
||||
|
||||
# Set Linker flags.
|
||||
LD_FILE = hw/mcu/bridgetek/ft9xx/scripts/ldscript.ld
|
||||
LDFLAGS += $(addprefix -L,$(LDINC)) \
|
||||
@ -48,7 +48,7 @@ LDFLAGS += $(addprefix -L,$(LDINC)) \
|
||||
SRC_C += src/portable/bridgetek/ft9xx/dcd_ft9xx.c
|
||||
|
||||
# Linker library.
|
||||
ifneq ($(FT90X_PREBUILT_LIBS),1)
|
||||
ifneq ($(FT9XX_PREBUILT_LIBS),1)
|
||||
# Optionally add in files from the Bridgetek SDK instead of the prebuilt
|
||||
# library. These are the minimum required.
|
||||
SRC_C += $(FT9XX_SDK)/src/sys.c
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit e8122eb6bd6286a1fe31f175a3e3eb0e7770c3e3
|
||||
Subproject commit 91060164afe239fcb394122e8bf9eb24d3194eb1
|
@ -38,9 +38,6 @@
|
||||
#include <ft900.h>
|
||||
#include <registers/ft900_registers.h>
|
||||
|
||||
#include "board.h"
|
||||
#include "bsp/board.h"
|
||||
|
||||
#define USBD_USE_STREAMS
|
||||
|
||||
#include "device/dcd.h"
|
||||
@ -50,17 +47,21 @@
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
// Board code will determine the state of VBUS from USB host.
|
||||
extern int8_t board_ft90x_vbus(void);
|
||||
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.
|
||||
static uint8_t _ft90x_setup_packet[8];
|
||||
CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN
|
||||
static uint8_t _ft9xx_setup_packet[8];
|
||||
|
||||
struct ft90x_xfer_state
|
||||
struct ft9xx_xfer_state
|
||||
{
|
||||
volatile uint8_t ready; // OUT Transfer has been received and waiting for transfer.
|
||||
volatile uint8_t valid; // Transfer is pending and total_size, remain_size, and buff_ptr are valid.
|
||||
volatile int16_t total_size; // Total transfer size in bytes for this transfer.
|
||||
volatile int16_t remain_size; // Total remaining in transfer.
|
||||
volatile uint8_t *buff_ptr; // Pointer to buffer to transmit from or receive to.
|
||||
|
||||
int16_t total_size; // Total transfer size in bytes for this transfer.
|
||||
int16_t remain_size; // Total remaining in transfer.
|
||||
uint8_t *buff_ptr; // Pointer to buffer to transmit from or receive to.
|
||||
|
||||
uint8_t type; // Endpoint type. Of type USBD_ENDPOINT_TYPE from endpoint descriptor.
|
||||
uint8_t dir; // Endpoint direction. TUSB_DIR_OUT or TUSB_DIR_IN. For control endpoint this is the current direction.
|
||||
@ -68,24 +69,24 @@ struct ft90x_xfer_state
|
||||
uint16_t size; // Max packet size for endpoint from endpoint descriptor.
|
||||
};
|
||||
// Endpoint description array for each endpoint.
|
||||
static struct ft90x_xfer_state ep_xfer[USBD_MAX_ENDPOINT_COUNT];
|
||||
static struct ft9xx_xfer_state ep_xfer[USBD_MAX_ENDPOINT_COUNT];
|
||||
// USB speed.
|
||||
static tusb_speed_t _speed;
|
||||
|
||||
// Interrupt handlers.
|
||||
void _ft90x_usbd_ISR(void); // Interrupt handler for USB device.
|
||||
void ft90x_usbd_pm_ISR(void); // Interrupt handler for USB device for power management (called by board).
|
||||
void _ft9xx_usbd_ISR(void); // Interrupt handler for USB device.
|
||||
void ft9xx_usbd_pm_ISR(void); // Interrupt handler for USB device for power management (called by board).
|
||||
|
||||
// Internal functions forward declarations.
|
||||
static uint16_t _ft90x_edpt_xfer_out(uint8_t ep_number, uint8_t *buffer, uint16_t xfer_bytes);
|
||||
static uint16_t _ft90x_edpt_xfer_in(uint8_t ep_number, uint8_t *buffer, uint16_t xfer_bytes);
|
||||
static void _ft90x_reset_edpts(void);
|
||||
static inline void _ft90x_phy_enable(bool en);
|
||||
static void _ft90x_usb_speed(void);
|
||||
static void _dcd_ft90x_attach(void);
|
||||
static void _dcd_ft90x_detach(void) __attribute__((unused));
|
||||
static uint16_t _ft90x_dusb_in(uint8_t ep_number, const uint8_t *buffer, uint16_t length);
|
||||
static uint16_t _ft90x_dusb_out(uint8_t ep_number, uint8_t *buffer, uint16_t length);
|
||||
static uint16_t _ft9xx_edpt_xfer_out(uint8_t ep_number, uint8_t *buffer, uint16_t xfer_bytes);
|
||||
static uint16_t _ft9xx_edpt_xfer_in(uint8_t ep_number, uint8_t *buffer, uint16_t xfer_bytes);
|
||||
static void _ft9xx_reset_edpts(void);
|
||||
static inline void _ft9xx_phy_enable(bool en);
|
||||
static void _ft9xx_usb_speed(void);
|
||||
static void _dcd_ft9xx_attach(void);
|
||||
static void _dcd_ft9xx_detach(void) __attribute__((unused));
|
||||
static uint16_t _ft9xx_dusb_in(uint8_t ep_number, const uint8_t *buffer, uint16_t length);
|
||||
static uint16_t _ft9xx_dusb_out(uint8_t ep_number, uint8_t *buffer, uint16_t length);
|
||||
|
||||
// Internal functions.
|
||||
|
||||
@ -93,7 +94,7 @@ static uint16_t _ft90x_dusb_out(uint8_t ep_number, uint8_t *buffer, uint16_t len
|
||||
// This can be up-to the maximum packet size of the endpoint.
|
||||
// Continuation of a transfer beyond the maximum packet size is performed
|
||||
// by the interrupt handler.
|
||||
static uint16_t _ft90x_edpt_xfer_out(uint8_t ep_number, uint8_t *buffer, uint16_t xfer_bytes)
|
||||
static uint16_t _ft9xx_edpt_xfer_out(uint8_t ep_number, uint8_t *buffer, uint16_t xfer_bytes)
|
||||
{
|
||||
//Note: this is called from only the interrupt handler when an OUT transfer is called.
|
||||
uint16_t ep_size = ep_xfer[ep_number].size;
|
||||
@ -108,7 +109,7 @@ static uint16_t _ft90x_edpt_xfer_out(uint8_t ep_number, uint8_t *buffer, uint16_
|
||||
//;
|
||||
|
||||
// Send the first packet of max packet size
|
||||
xfer_bytes = _ft90x_dusb_out(ep_number, (uint8_t *)buffer, xfer_bytes);
|
||||
xfer_bytes = _ft9xx_dusb_out(ep_number, (uint8_t *)buffer, xfer_bytes);
|
||||
if (ep_number == USBD_EP_0)
|
||||
{
|
||||
// Set flags to indicate data ready.
|
||||
@ -126,7 +127,7 @@ static uint16_t _ft90x_edpt_xfer_out(uint8_t ep_number, uint8_t *buffer, uint16_
|
||||
// This can be up-to the maximum packet size of the endpoint.
|
||||
// Continuation of a transfer beyond the maximum packet size is performed
|
||||
// by the interrupt handler.
|
||||
static uint16_t _ft90x_edpt_xfer_in(uint8_t ep_number, uint8_t *buffer, uint16_t xfer_bytes)
|
||||
static uint16_t _ft9xx_edpt_xfer_in(uint8_t ep_number, uint8_t *buffer, uint16_t xfer_bytes)
|
||||
{
|
||||
//Note: this may be called from the interrupt handler or from normal code.
|
||||
uint8_t end = 0;
|
||||
@ -154,17 +155,24 @@ static uint16_t _ft90x_edpt_xfer_in(uint8_t ep_number, uint8_t *buffer, uint16_t
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t sr_reg;
|
||||
// If there is data to transmit then wait until the IN buffer
|
||||
// for the endpoint is empty.
|
||||
do
|
||||
// This does not apply to interrupt endpoints.
|
||||
if (ep_xfer[ep_number].type != TUSB_XFER_INTERRUPT)
|
||||
{
|
||||
sr_reg = USBD_EP_SR_REG(ep_number);
|
||||
} while (sr_reg & MASK_USBD_EPxSR_INPRDY);
|
||||
|
||||
uint8_t sr_reg;
|
||||
do
|
||||
{
|
||||
sr_reg = USBD_EP_SR_REG(ep_number);
|
||||
} while (sr_reg & MASK_USBD_EPxSR_INPRDY);
|
||||
}
|
||||
}
|
||||
|
||||
xfer_bytes = _ft90x_dusb_in(ep_number, (uint8_t *)buffer, xfer_bytes);
|
||||
// Do not send a ZLP for interrupt endpoints.
|
||||
if ((ep_xfer[ep_number].type != TUSB_XFER_INTERRUPT) || (xfer_bytes > 0))
|
||||
{
|
||||
xfer_bytes = _ft9xx_dusb_in(ep_number, (uint8_t *)buffer, xfer_bytes);
|
||||
}
|
||||
|
||||
if (ep_number == USBD_EP_0)
|
||||
{
|
||||
@ -190,13 +198,13 @@ static uint16_t _ft90x_edpt_xfer_in(uint8_t ep_number, uint8_t *buffer, uint16_t
|
||||
|
||||
// Reset all non-control endpoints to a default state.
|
||||
// Control endpoint is always enabled and ready. All others disabled.
|
||||
static void _ft90x_reset_edpts(void)
|
||||
static void _ft9xx_reset_edpts(void)
|
||||
{
|
||||
// Disable all endpoints and remove configuration values.
|
||||
for (int i = 1; i < USBD_MAX_ENDPOINT_COUNT; i++)
|
||||
{
|
||||
// Clear settings.
|
||||
tu_memclr(&ep_xfer[i], sizeof(struct ft90x_xfer_state));
|
||||
tu_memclr(&ep_xfer[i], sizeof(struct ft9xx_xfer_state));
|
||||
// Disable hardware.
|
||||
USBD_EP_CR_REG(i) = 0;
|
||||
}
|
||||
@ -206,7 +214,7 @@ static void _ft90x_reset_edpts(void)
|
||||
}
|
||||
|
||||
// Enable or disable the USB PHY.
|
||||
static inline void _ft90x_phy_enable(bool en)
|
||||
static inline void _ft9xx_phy_enable(bool en)
|
||||
{
|
||||
if (en)
|
||||
SYS->PMCFG_L |= MASK_SYS_PMCFG_DEV_PHY_EN;
|
||||
@ -215,7 +223,7 @@ static inline void _ft90x_phy_enable(bool en)
|
||||
}
|
||||
|
||||
// Safely connect to the USB.
|
||||
static void _dcd_ft90x_attach(void)
|
||||
static void _dcd_ft9xx_attach(void)
|
||||
{
|
||||
uint8_t reg;
|
||||
|
||||
@ -271,7 +279,7 @@ static void _dcd_ft90x_attach(void)
|
||||
}
|
||||
|
||||
// Gracefully disconnect from the USB.
|
||||
static void _dcd_ft90x_detach(void)
|
||||
static void _dcd_ft9xx_detach(void)
|
||||
{
|
||||
// Disable device connect/disconnect/host reset detection.
|
||||
SYS->PMCFG_L = SYS->PMCFG_L & (~MASK_SYS_PMCFG_DEV_DETECT_EN);
|
||||
@ -313,7 +321,7 @@ static void _dcd_ft90x_detach(void)
|
||||
// Determine the speed of the USB to which we are connected.
|
||||
// Set the speed of the PHY accordingly.
|
||||
// High speed can be disabled through CFG_TUSB_RHPORT0_MODE or CFG_TUD_MAX_SPEED settings.
|
||||
static void _ft90x_usb_speed(void)
|
||||
static void _ft9xx_usb_speed(void)
|
||||
{
|
||||
uint8_t fctrl_val;
|
||||
|
||||
@ -376,7 +384,7 @@ static void _ft90x_usb_speed(void)
|
||||
// If streaming is disabled then it will send each byte of the buffer in turn
|
||||
// to the FIFO. The is no reason to not stream.
|
||||
// The total number of bytes sent to the FIFO is returned.
|
||||
static uint16_t _ft90x_dusb_in(uint8_t ep_number, const uint8_t *buffer, uint16_t length)
|
||||
static uint16_t _ft9xx_dusb_in(uint8_t ep_number, const uint8_t *buffer, uint16_t length)
|
||||
{
|
||||
uint16_t bytes_read = 0;
|
||||
uint16_t buff_size = length;
|
||||
@ -433,7 +441,7 @@ static uint16_t _ft90x_dusb_in(uint8_t ep_number, const uint8_t *buffer, uint16_
|
||||
// If streaming is disabled then it will receive each byte from the FIFO in turn
|
||||
// to the buffer. The is no reason to not stream.
|
||||
// The total number of bytes received from the FIFO is returned.
|
||||
static uint16_t _ft90x_dusb_out(uint8_t ep_number, uint8_t *buffer, uint16_t length)
|
||||
static uint16_t _ft9xx_dusb_out(uint8_t ep_number, uint8_t *buffer, uint16_t length)
|
||||
{
|
||||
#ifdef USBD_USE_STREAMS
|
||||
volatile uint8_t *data_reg;
|
||||
@ -511,11 +519,11 @@ static uint16_t _ft90x_dusb_out(uint8_t ep_number, uint8_t *buffer, uint16_t len
|
||||
// Initialize controller to device mode
|
||||
void dcd_init(uint8_t rhport)
|
||||
{
|
||||
TU_LOG2("FT90x initialisation\r\n");
|
||||
TU_LOG2("FT9xx initialisation\r\n");
|
||||
|
||||
_dcd_ft90x_attach();
|
||||
_dcd_ft9xx_attach();
|
||||
|
||||
interrupt_attach(interrupt_usb_device, (int8_t)interrupt_usb_device, _ft90x_usbd_ISR);
|
||||
interrupt_attach(interrupt_usb_device, (int8_t)interrupt_usb_device, _ft9xx_usbd_ISR);
|
||||
|
||||
dcd_connect(rhport);
|
||||
}
|
||||
@ -524,7 +532,7 @@ void dcd_init(uint8_t rhport)
|
||||
void dcd_int_enable(uint8_t rhport)
|
||||
{
|
||||
(void)rhport;
|
||||
TU_LOG3("FT90x int enable\r\n");
|
||||
TU_LOG3("FT9xx int enable\r\n");
|
||||
|
||||
// Peripheral devices interrupt enable.
|
||||
interrupt_enable_globally();
|
||||
@ -534,7 +542,7 @@ void dcd_int_enable(uint8_t rhport)
|
||||
void dcd_int_disable(uint8_t rhport)
|
||||
{
|
||||
(void)rhport;
|
||||
TU_LOG3("FT90x int disable\r\n");
|
||||
TU_LOG3("FT9xx int disable\r\n");
|
||||
|
||||
// Peripheral devices interrupt disable.
|
||||
interrupt_disable_globally();
|
||||
@ -600,18 +608,18 @@ void dcd_remote_wakeup(uint8_t rhport)
|
||||
void dcd_connect(uint8_t rhport)
|
||||
{
|
||||
(void)rhport;
|
||||
TU_LOG2("FT90x connect\r\n");
|
||||
TU_LOG2("FT9xx connect\r\n");
|
||||
|
||||
CRITICAL_SECTION_BEGIN
|
||||
// Is device connected?
|
||||
if (board_ft90x_vbus())
|
||||
if (board_ft9xx_vbus())
|
||||
{
|
||||
// Clear/disable address register.
|
||||
USBD_REG(faddr) = 0;
|
||||
_ft90x_phy_enable(true);
|
||||
_ft9xx_phy_enable(true);
|
||||
|
||||
// Determine bus speed and signal speed to tusb.
|
||||
_ft90x_usb_speed();
|
||||
_ft9xx_usb_speed();
|
||||
}
|
||||
|
||||
// Setup the control endpoint only.
|
||||
@ -636,17 +644,17 @@ void dcd_connect(uint8_t rhport)
|
||||
USBD_REG(epie) = (MASK_USBD_EPIE_EP0IE);
|
||||
|
||||
// Restore default endpoint state.
|
||||
_ft90x_reset_edpts();
|
||||
_ft9xx_reset_edpts();
|
||||
}
|
||||
|
||||
// Disconnect by disabling internal pull-up resistor on D+/D-
|
||||
void dcd_disconnect(uint8_t rhport)
|
||||
{
|
||||
(void)rhport;
|
||||
TU_LOG2("FT90x disconnect\r\n");
|
||||
TU_LOG2("FT9xx disconnect\r\n");
|
||||
|
||||
// Disable the USB PHY.
|
||||
_ft90x_phy_enable(false);
|
||||
_ft9xx_phy_enable(false);
|
||||
}
|
||||
|
||||
void dcd_sof_enable(uint8_t rhport, bool en)
|
||||
@ -674,12 +682,12 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *ep_desc)
|
||||
uint8_t ep_reg_data = 0;
|
||||
int16_t total_ram;
|
||||
|
||||
TU_LOG2("FT90x endpoint open %d %c\r\n", ep_number, ep_dir?'I':'O');
|
||||
TU_LOG2("FT9xx endpoint open %d %c\r\n", ep_number, ep_dir?'I':'O');
|
||||
|
||||
// Check that the requested endpoint number is allowable.
|
||||
if (ep_number >= USBD_MAX_ENDPOINT_COUNT)
|
||||
{
|
||||
TU_LOG1("FT90x endpoint not valid: requested %d max %d\r\n", ep_number, USBD_MAX_ENDPOINT_COUNT);
|
||||
TU_LOG1("FT9xx endpoint not valid: requested %d max %d\r\n", ep_number, USBD_MAX_ENDPOINT_COUNT);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -691,7 +699,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *ep_desc)
|
||||
}
|
||||
if (ep_reg_size > USBD_EP_MAX_SIZE_1024)
|
||||
{
|
||||
TU_LOG1("FT90x endpoint size not valid: requested %d max 1024\r\n", ep_size);
|
||||
TU_LOG1("FT9xx endpoint size not valid: requested %d max 1024\r\n", ep_size);
|
||||
return false;
|
||||
}
|
||||
// Calculate actual amount of buffer RAM used by this endpoint. This may be more than the
|
||||
@ -706,9 +714,9 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *ep_desc)
|
||||
if (ep_xfer[ep_number].type != USBD_EP_TYPE_DISABLED)
|
||||
{
|
||||
// This could be because an endpoint has been assigned with the same number.
|
||||
// On FT90x, IN and OUT endpoints may not have the same number. e.g. There
|
||||
// On FT9xx, IN and OUT endpoints may not have the same number. e.g. There
|
||||
// cannot been an 0x81 and 0x01 endpoint.
|
||||
TU_LOG1("FT90x endpoint %d already assigned\r\n", ep_number);
|
||||
TU_LOG1("FT9xx endpoint %d already assigned\r\n", ep_number);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -732,23 +740,28 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *ep_desc)
|
||||
}
|
||||
}
|
||||
}
|
||||
// The control endpoint is taken into account as well.
|
||||
total_ram -= ep_xfer[0].buff_size;
|
||||
|
||||
if (sys_check_ft900_revB())
|
||||
{
|
||||
// The control endpoint is taken into account as well on RevB silicon.
|
||||
total_ram -= ep_xfer[0].buff_size;
|
||||
}
|
||||
|
||||
// Make sure we have enough space. The corner case is having zero bytes
|
||||
// free which means that total_ram must be signed as zero bytes free is
|
||||
// allowable.
|
||||
if (total_ram < ep_buff_size)
|
||||
{
|
||||
TU_LOG1("FT90x insufficient buffer RAM for endpoint %d\r\n", ep_number);
|
||||
TU_LOG1("FT9xx insufficient buffer RAM for endpoint %d\r\n", ep_number);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set the type of this endpoint in the control register.
|
||||
if (ep_type == USBD_EP_BULK)
|
||||
if (ep_type == TUSB_XFER_BULK)
|
||||
ep_reg_data |= (USBD_EP_DIS_BULK << BIT_USBD_EP_CONTROL_DIS);
|
||||
else if (ep_type == USBD_EP_INT)
|
||||
else if (ep_type == TUSB_XFER_INTERRUPT)
|
||||
ep_reg_data |= (USBD_EP_DIS_INT << BIT_USBD_EP_CONTROL_DIS);
|
||||
else if (ep_type == USBD_EP_ISOC)
|
||||
else if (ep_type == TUSB_XFER_ISOCHRONOUS)
|
||||
ep_reg_data |= (USBD_EP_DIS_ISO << BIT_USBD_EP_CONTROL_DIS);
|
||||
// Set the direction of this endpoint in the control register.
|
||||
if (ep_dir == USBD_DIR_IN)
|
||||
@ -756,9 +769,9 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *ep_desc)
|
||||
// Do not perform double buffering.
|
||||
//if (<double buffering flag> != USBD_DB_OFF)
|
||||
//ep_reg_data |= MASK_USBD_EPxCR_DB;
|
||||
// Set the control endpoint for this endpoint.
|
||||
// Set the control register for this endpoint.
|
||||
USBD_EP_CR_REG(ep_number) = ep_reg_data;
|
||||
TU_LOG2("FT90x endpoint setting %x\r\n", ep_reg_data);
|
||||
TU_LOG2("FT9xx endpoint setting %x\r\n", ep_reg_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -766,14 +779,15 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *ep_desc)
|
||||
USBD_EP_CR_REG(USBD_EP_0) = (ep_reg_size << BIT_USBD_EP0_MAX_SIZE);
|
||||
}
|
||||
|
||||
CRITICAL_SECTION_BEGIN
|
||||
// Store the endpoint characteristics for later reference.
|
||||
ep_xfer[ep_number].dir = ep_dir;
|
||||
ep_xfer[ep_number].type = ep_type;
|
||||
ep_xfer[ep_number].size = ep_size;
|
||||
ep_xfer[ep_number].buff_size = ep_buff_size;
|
||||
|
||||
CRITICAL_SECTION_BEGIN
|
||||
// Clear register transaction continuation and signalling state.
|
||||
ep_xfer[ep_number].ready = 0;
|
||||
ep_xfer[ep_number].valid = 0;
|
||||
ep_xfer[ep_number].buff_ptr = NULL;
|
||||
ep_xfer[ep_number].total_size = 0;
|
||||
@ -788,7 +802,7 @@ void dcd_edpt_close_all(uint8_t rhport)
|
||||
{
|
||||
(void)rhport;
|
||||
// Reset the endpoint configurations.
|
||||
_ft90x_reset_edpts();
|
||||
_ft9xx_reset_edpts();
|
||||
}
|
||||
|
||||
// Submit a transfer, When complete dcd_event_xfer_complete() is invoked to notify the stack
|
||||
@ -796,7 +810,7 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t to
|
||||
{
|
||||
(void)rhport;
|
||||
uint8_t ep_number = tu_edpt_number(ep_addr);
|
||||
uint8_t dir = tu_edpt_dir(ep_addr);
|
||||
uint8_t ep_dir = tu_edpt_dir(ep_addr);
|
||||
uint16_t xfer_bytes;
|
||||
bool status = false;
|
||||
|
||||
@ -806,19 +820,17 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t to
|
||||
// ep_xfer is used to tell the interrupt handler what to do.
|
||||
// ep_xfer can be used at interrupt level to continue transfers.
|
||||
CRITICAL_SECTION_BEGIN
|
||||
|
||||
// Transfer currently in progress.
|
||||
if (ep_xfer[ep_number].valid == 0)
|
||||
{
|
||||
status = true;
|
||||
|
||||
ep_xfer[ep_number].total_size = total_bytes;
|
||||
ep_xfer[ep_number].remain_size = total_bytes;
|
||||
ep_xfer[ep_number].buff_ptr = buffer;
|
||||
ep_xfer[ep_number].valid = 1;
|
||||
|
||||
if (ep_number == USBD_EP_0)
|
||||
{
|
||||
ep_xfer[USBD_EP_0].dir = dir;
|
||||
ep_xfer[USBD_EP_0].dir = ep_dir;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -827,18 +839,53 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t to
|
||||
USBD_REG(epie) = USBD_REG(epie) | (1 << ep_number);
|
||||
}
|
||||
|
||||
if (dir == TUSB_DIR_IN)
|
||||
if (ep_dir == TUSB_DIR_IN)
|
||||
{
|
||||
// For IN transfers send the first packet as a starter. Interrupt handler to complete
|
||||
// this if it is larger than one packet.
|
||||
xfer_bytes = _ft90x_edpt_xfer_in(ep_number, buffer, total_bytes);
|
||||
xfer_bytes = _ft9xx_edpt_xfer_in(ep_number, buffer, total_bytes);
|
||||
|
||||
ep_xfer[ep_number].buff_ptr += xfer_bytes;
|
||||
ep_xfer[ep_number].remain_size -= xfer_bytes;
|
||||
|
||||
// Tell the interrupt handler to signal dcd_event_xfer_complete on completion.
|
||||
ep_xfer[ep_number].valid = 1;
|
||||
}
|
||||
else // (dir == TUSB_DIR_OUT)
|
||||
{
|
||||
// For OUT transfers on the control endpoint.
|
||||
// The host may already have performed the first data transfer after the SETUP packet
|
||||
// before the transfer is setup for it.
|
||||
if (ep_xfer[ep_number].ready)
|
||||
{
|
||||
// We have received a data packet on the endpoint without a transfer
|
||||
// being initialised. This can be because the host has sent this packet before
|
||||
// a new transfer has been initiated on the endpoint.
|
||||
// We will now stream the data from the FIFO.
|
||||
ep_xfer[ep_number].ready = 0;
|
||||
|
||||
// Transfer incoming data from an OUT packet to the buffer.
|
||||
xfer_bytes = _ft9xx_edpt_xfer_out(ep_number, buffer, total_bytes);
|
||||
|
||||
// Report completion of the transfer.
|
||||
dcd_event_xfer_complete(BOARD_TUD_RHPORT, ep_number /*| TUSB_DIR_OUT_MASK */, xfer_bytes, XFER_RESULT_SUCCESS, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Tell the interrupt handler to wait for the packet to be received and
|
||||
// then report the transfer complete with dcd_event_xfer_complete.
|
||||
ep_xfer[ep_number].valid = 1;
|
||||
}
|
||||
}
|
||||
status = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Note: should not arrive here.
|
||||
}
|
||||
|
||||
CRITICAL_SECTION_END
|
||||
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -889,6 +936,7 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr)
|
||||
USBD_EP_SR_REG(ep_number) = MASK_USBD_EPxSR_CLR_TOGGLE;
|
||||
|
||||
// Allow transfers to restart.
|
||||
ep_xfer[ep_number].ready = 0;
|
||||
ep_xfer[ep_number].valid = 0;
|
||||
ep_xfer[ep_number].remain_size = 0;
|
||||
CRITICAL_SECTION_END
|
||||
@ -897,9 +945,9 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr)
|
||||
|
||||
// Interrupt handling.
|
||||
|
||||
void _ft90x_usbd_ISR(void)
|
||||
void _ft9xx_usbd_ISR(void)
|
||||
{
|
||||
tud_int_handler(BOARD_TUD_RHPORT); // Resolves to dcd_int_handler().
|
||||
dcd_int_handler(BOARD_TUD_RHPORT);
|
||||
}
|
||||
|
||||
void dcd_int_handler(uint8_t rhport)
|
||||
@ -936,7 +984,7 @@ void dcd_int_handler(uint8_t rhport)
|
||||
if (cmif & MASK_USBD_CMIF_RSTIRQ) //Handle Reset interrupt
|
||||
{
|
||||
// Reset endpoints to default state.
|
||||
_ft90x_reset_edpts();
|
||||
_ft9xx_reset_edpts();
|
||||
dcd_event_bus_reset(BOARD_TUD_RHPORT, _speed, true);
|
||||
}
|
||||
if (cmif & MASK_USBD_CMIF_SUSIRQ) //Handle Suspend interrupt
|
||||
@ -962,7 +1010,6 @@ void dcd_int_handler(uint8_t rhport)
|
||||
{
|
||||
// Clear interrupt register.
|
||||
USBD_REG(epif) = MASK_USBD_EPIF_EP0IRQ;
|
||||
|
||||
// Test for an incoming SETUP request on the control endpoint.
|
||||
if (USBD_EP_SR_REG(USBD_EP_0) & MASK_USBD_EP0SR_SETUP)
|
||||
{
|
||||
@ -976,16 +1023,19 @@ void dcd_int_handler(uint8_t rhport)
|
||||
USBD_EP_SR_REG(USBD_EP_0) = MASK_USBD_EP0SR_STALL;
|
||||
}
|
||||
|
||||
// Host has sent a SETUP packet. Receive this into the setup packet store.
|
||||
_ft90x_dusb_out(USBD_EP_0, (uint8_t *)_ft90x_setup_packet, sizeof(USB_device_request));
|
||||
// Host has sent a SETUP packet. Receive this into the SETUP packet store.
|
||||
_ft9xx_dusb_out(USBD_EP_0, (uint8_t *)_ft9xx_setup_packet, sizeof(USB_device_request));
|
||||
|
||||
// Send the packet to tinyusb.
|
||||
dcd_event_setup_received(BOARD_TUD_RHPORT, _ft90x_setup_packet, true);
|
||||
dcd_event_setup_received(BOARD_TUD_RHPORT, _ft9xx_setup_packet, true);
|
||||
|
||||
// Clear the interrupt that signals a SETUP packet is received.
|
||||
USBD_EP_SR_REG(USBD_EP_0) = (MASK_USBD_EP0SR_SETUP);
|
||||
|
||||
// Allow new transfers on the control endpoint.
|
||||
// Any SETUP packet will clear the incoming FIFO.
|
||||
ep_xfer[USBD_EP_0].ready = 0;
|
||||
|
||||
// Allow new DATA and ACK transfers on the control endpoint.
|
||||
ep_xfer[USBD_EP_0].valid = 0;
|
||||
return;
|
||||
}
|
||||
@ -998,15 +1048,29 @@ void dcd_int_handler(uint8_t rhport)
|
||||
|
||||
// Transfer incoming data from an OUT packet to the buffer supplied.
|
||||
if (ep_xfer[USBD_EP_0].dir == TUSB_DIR_OUT)
|
||||
{
|
||||
xfer_bytes = _ft90x_edpt_xfer_out(USBD_EP_0, (uint8_t *)ep_xfer[USBD_EP_0].buff_ptr, xfer_bytes);
|
||||
{
|
||||
xfer_bytes = _ft9xx_edpt_xfer_out(USBD_EP_0, ep_xfer[USBD_EP_0].buff_ptr, xfer_bytes);
|
||||
}
|
||||
// Now signal completion of data packet.
|
||||
dcd_event_xfer_complete(BOARD_TUD_RHPORT, (ep_xfer[USBD_EP_0].dir ? TUSB_DIR_IN_MASK : 0), xfer_bytes, XFER_RESULT_SUCCESS, true);
|
||||
dcd_event_xfer_complete(BOARD_TUD_RHPORT, USBD_EP_0 | (ep_xfer[USBD_EP_0].dir ? TUSB_DIR_IN_MASK : 0),
|
||||
xfer_bytes, XFER_RESULT_SUCCESS, true);
|
||||
|
||||
// Incoming FIFO has been cleared.
|
||||
ep_xfer[USBD_EP_0].ready = 0;
|
||||
|
||||
// Allow new transfers on the control endpoint.
|
||||
ep_xfer[USBD_EP_0].valid = 0;
|
||||
}
|
||||
// No transfer is in flight for EP0.
|
||||
else
|
||||
{
|
||||
// We have received a data packet on the control endpoint without a transfer
|
||||
// being initialised. This can be because the host has sent this packet before
|
||||
// a new transfer has been initiated on the control endpoint.
|
||||
// We will record that there is data in the FIFO for dcd_edpt_xfer to obtain
|
||||
// once the transfer is initiated.
|
||||
ep_xfer[USBD_EP_0].ready = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else // !(epif & MASK_USBD_EPIF_EP0IRQ)
|
||||
@ -1026,7 +1090,6 @@ void dcd_int_handler(uint8_t rhport)
|
||||
if (ep_xfer[ep_number].valid)
|
||||
{
|
||||
xfer_bytes = 0;
|
||||
uint8_t ep_dirmask = (ep_xfer[ep_number].dir ? TUSB_DIR_IN_MASK : 0);
|
||||
|
||||
// Clear interrupt register for this endpoint.
|
||||
USBD_REG(epif) = MASK_USBD_EPIF_IRQ(ep_number);
|
||||
@ -1034,10 +1097,15 @@ void dcd_int_handler(uint8_t rhport)
|
||||
// Start or continue an OUT transfer.
|
||||
if (ep_xfer[ep_number].dir == TUSB_DIR_OUT)
|
||||
{
|
||||
xfer_bytes = _ft90x_edpt_xfer_out(ep_number,
|
||||
(uint8_t *)ep_xfer[ep_number].buff_ptr,
|
||||
xfer_bytes = _ft9xx_edpt_xfer_out(ep_number,
|
||||
ep_xfer[ep_number].buff_ptr,
|
||||
(uint16_t)ep_xfer[ep_number].remain_size);
|
||||
|
||||
// Report each OUT packet received to the stack.
|
||||
dcd_event_xfer_complete(BOARD_TUD_RHPORT,
|
||||
ep_number /* | TUSB_DIR_OUT_MASK */,
|
||||
xfer_bytes, XFER_RESULT_SUCCESS, true);
|
||||
|
||||
ep_xfer[ep_number].buff_ptr += xfer_bytes;
|
||||
ep_xfer[ep_number].remain_size -= xfer_bytes;
|
||||
}
|
||||
@ -1046,27 +1114,45 @@ void dcd_int_handler(uint8_t rhport)
|
||||
{
|
||||
if (ep_xfer[ep_number].remain_size > 0)
|
||||
{
|
||||
xfer_bytes = _ft90x_edpt_xfer_in(ep_number,
|
||||
(uint8_t *)ep_xfer[ep_number].buff_ptr,
|
||||
xfer_bytes = _ft9xx_edpt_xfer_in(ep_number,
|
||||
ep_xfer[ep_number].buff_ptr,
|
||||
(uint16_t)ep_xfer[ep_number].remain_size);
|
||||
|
||||
ep_xfer[ep_number].buff_ptr += xfer_bytes;
|
||||
ep_xfer[ep_number].remain_size -= xfer_bytes;
|
||||
}
|
||||
|
||||
if (ep_xfer[ep_number].remain_size == 0)
|
||||
{
|
||||
dcd_event_xfer_complete(BOARD_TUD_RHPORT,
|
||||
ep_number | TUSB_DIR_IN_MASK,
|
||||
ep_xfer[ep_number].total_size, XFER_RESULT_SUCCESS, true);
|
||||
}
|
||||
}
|
||||
|
||||
// When the transfer is complete...
|
||||
if (ep_xfer[ep_number].remain_size == 0)
|
||||
{
|
||||
// Signal tinyUSB.
|
||||
dcd_event_xfer_complete(BOARD_TUD_RHPORT, ep_number | ep_dirmask, ep_xfer[ep_number].total_size, XFER_RESULT_SUCCESS, true);
|
||||
|
||||
// Allow new transfers on this endpoint.
|
||||
// Finish this transfer and allow new transfers on this endpoint.
|
||||
ep_xfer[ep_number].valid = 0;
|
||||
|
||||
// Disable the interrupt for this endpoint now it is complete.
|
||||
USBD_REG(epie) = USBD_REG(epie) & (~(1 << ep_number));
|
||||
}
|
||||
|
||||
ep_xfer[ep_number].ready = 0;
|
||||
}
|
||||
// No OUT transfer is in flight for this endpoint.
|
||||
else
|
||||
{
|
||||
if (ep_xfer[ep_number].dir == TUSB_DIR_OUT)
|
||||
{
|
||||
// We will record that there is data in the FIFO for dcd_edpt_xfer to obtain
|
||||
// once the transfer is initiated.
|
||||
// Strictly this should not happen for a non-control endpoint. Interrupts
|
||||
// are disabled when there are no transfers setup for an endpoint.
|
||||
ep_xfer[ep_number].ready = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1075,7 +1161,7 @@ void dcd_int_handler(uint8_t rhport)
|
||||
|
||||
// Power management interrupt handler.
|
||||
// This handles USB device related power management interrupts only.
|
||||
void ft90x_usbd_pm_ISR(void)
|
||||
void ft9xx_usbd_pm_ISR(void)
|
||||
{
|
||||
uint16_t pmcfg = SYS->PMCFG_H;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user