- function separation done
- a load of CMake modification
This commit is contained in:
parent
48a7ae54a3
commit
685fa77bda
@ -34,19 +34,24 @@ elseif(NOT FLATUSB_DESC_SRC)
|
|||||||
message("flatUSB: No source of descriptors passed! Please either set FLATUSB_DESC_DIR to the directory containing the descriptor files OR pass descriptor files directly by defining FLATUSB_DESC_SRC and FLATUSB_DESC_HEADER!")
|
message("flatUSB: No source of descriptors passed! Please either set FLATUSB_DESC_DIR to the directory containing the descriptor files OR pass descriptor files directly by defining FLATUSB_DESC_SRC and FLATUSB_DESC_HEADER!")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if (NOT FLATUSB_DRIVER_SRC)
|
||||||
|
message("flatUSB: No USB driver passed! It's likely an error and not intentional. Please populate FLATUSB_DRIVER_SRC with the list of the USB driver files!")
|
||||||
|
endif()
|
||||||
|
|
||||||
message("flatUSB classes selected: ${FLATUSB_CLASSES}")
|
message("flatUSB classes selected: ${FLATUSB_CLASSES}")
|
||||||
|
|
||||||
set(FLATUSB_SRC
|
set(FLATUSB_SRC
|
||||||
${FLATUSB_CLASSES_SRC}
|
${FLATUSB_CLASSES_SRC}
|
||||||
${FLATUSB_DESC_SRC}
|
${FLATUSB_DESC_SRC}
|
||||||
|
${FLATUSB_DRIVER_SRC}
|
||||||
|
|
||||||
usb.c
|
usb.c
|
||||||
usb_callback_event.h
|
usb_callback_event.h
|
||||||
usb_common.h
|
usb_common.h
|
||||||
usb_common_types.h
|
usb_common_types.h
|
||||||
usb_device_types.h
|
usb_device_types.h
|
||||||
usb_driver.c
|
#usb_driver.c
|
||||||
usb_driver.h
|
#usb_driver.h
|
||||||
usb.h
|
usb.h
|
||||||
|
|
||||||
# utils/gen_queue.c
|
# utils/gen_queue.c
|
||||||
|
13
class/cdc.c
13
class/cdc.c
@ -5,7 +5,6 @@
|
|||||||
#include "../usb_device_types.h"
|
#include "../usb_device_types.h"
|
||||||
|
|
||||||
#include "../usb.h"
|
#include "../usb.h"
|
||||||
#include "flatUSB/usb_driver.h"
|
|
||||||
|
|
||||||
#include <blocking_io/blocking_fifo.h>
|
#include <blocking_io/blocking_fifo.h>
|
||||||
|
|
||||||
@ -56,6 +55,10 @@ void usb_cdc_init(const USB_CdcAssignments *as) {
|
|||||||
|
|
||||||
// static uint8_t replyBuf[sizeof(USB_Cdc_LineCodingStruct)];
|
// static uint8_t replyBuf[sizeof(USB_Cdc_LineCodingStruct)];
|
||||||
|
|
||||||
|
// static void usbcore_setup_cplt_cb(uint8_t in) {
|
||||||
|
// usbcore_wake_up_endpoint(cdcs.ep_assignments.data_ep, USB_IN);
|
||||||
|
// }
|
||||||
|
|
||||||
static void usb_cdc_review_comm_init() {
|
static void usb_cdc_review_comm_init() {
|
||||||
// check if line coding was initialized
|
// check if line coding was initialized
|
||||||
USB_Cdc_LineCodingStruct *lc = &cdcs.line_coding;
|
USB_Cdc_LineCodingStruct *lc = &cdcs.line_coding;
|
||||||
@ -67,10 +70,10 @@ static void usb_cdc_review_comm_init() {
|
|||||||
// combine the above criteria
|
// combine the above criteria
|
||||||
cdcs.commInit = lcOk && clsOk;
|
cdcs.commInit = lcOk && clsOk;
|
||||||
|
|
||||||
// wake up endpoint if initialized
|
// // wake up endpoint if initialized
|
||||||
if (cdcs.commInit) {
|
// if (cdcs.commInit) {
|
||||||
usbcore_wake_up_endpoint(cdcs.ep_assignments.data_ep, USB_IN);
|
// usbcore_register_IN_callback(0, usbcore_setup_cplt_cb);
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
int usb_cdc_process_and_return(USB_CallbackEvent *cbevt) {
|
int usb_cdc_process_and_return(USB_CallbackEvent *cbevt) {
|
||||||
|
@ -29,4 +29,19 @@
|
|||||||
#define USBFIFO(ep) ((uint32_t *)(((uint32_t)(USBG)) + USB_OTG_FIFO_BASE + (USB_OTG_FIFO_SIZE) * (ep)))
|
#define USBFIFO(ep) ((uint32_t *)(((uint32_t)(USBG)) + USB_OTG_FIFO_BASE + (USB_OTG_FIFO_SIZE) * (ep)))
|
||||||
#define USBPCGCCTL ((uint32_t *)(((uint32_t)(USBG)) + USB_OTG_PCGCCTL_BASE))
|
#define USBPCGCCTL ((uint32_t *)(((uint32_t)(USBG)) + USB_OTG_PCGCCTL_BASE))
|
||||||
|
|
||||||
|
// Set TOCAL and TRDT values (see Ref. Man.)
|
||||||
|
#if defined(USB_STM32H7) /*|| defined(USB_HIGH_SPEED)*/
|
||||||
|
#define TOCAL_VALUE (0x00)
|
||||||
|
#define TRDT_VALUE (0x05)
|
||||||
|
#elif defined(USB_STM32F4)
|
||||||
|
#if !defined(USB_HIGH_SPEED)
|
||||||
|
#define TOCAL_VALUE (0x07)
|
||||||
|
#define TRDT_VALUE (0x06)
|
||||||
|
#else
|
||||||
|
#define TOCAL_VALUE (0x07)
|
||||||
|
#define TRDT_VALUE (0x09)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#endif /* CORE_USB_USB_COMMON_DEFS */
|
#endif /* CORE_USB_USB_COMMON_DEFS */
|
@ -1,16 +1,16 @@
|
|||||||
#ifndef CORE_USB_USB_CORE_TYPES
|
#ifndef CORE_USB_USB_CORE_TYPES
|
||||||
#define CORE_USB_USB_CORE_TYPES
|
#define CORE_USB_USB_CORE_TYPES
|
||||||
|
|
||||||
#include "usb_common_types.h"
|
// #include "usb_common_types.h"
|
||||||
|
|
||||||
/* USB linespeed */
|
// /* USB linespeed */
|
||||||
typedef enum { USB_SPD_UNKNOWN = 0b00, USB_SPD_LOW = 0b01, USB_SPD_FULL = 0b11 } USB_Speed;
|
// typedef enum { USB_SPD_UNKNOWN = 0b00, USB_SPD_LOW = 0b01, USB_SPD_FULL = 0b11 } USB_Speed;
|
||||||
|
|
||||||
/* USB core state */
|
// /* USB core state */
|
||||||
typedef struct
|
// typedef struct
|
||||||
{
|
// {
|
||||||
uint8_t linespeed; // USB linespeed
|
// uint8_t linespeed; // USB linespeed
|
||||||
} USB_CoreState;
|
// } USB_CoreState;
|
||||||
|
|
||||||
|
|
||||||
#endif /* CORE_USB_USB_CORE_TYPES */
|
#endif /* CORE_USB_USB_CORE_TYPES */
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,35 +1,309 @@
|
|||||||
#ifndef STM32_USB_DRV
|
#ifndef STM32_USB_DRV
|
||||||
#define STM32_USB_DRV
|
#define STM32_USB_DRV
|
||||||
|
|
||||||
#include "usb_common_defs.h"
|
#include "common_defs.h"
|
||||||
|
|
||||||
// Select IO crossbar advanced function
|
#include "../../usb_common_types.h"
|
||||||
#if defined(USB_STM32H7)
|
|
||||||
#ifndef STM32H723xx
|
#include "../../usb_driver_common.h"
|
||||||
#define USB_GPIO_AF (GPIO_AF10_OTG2_FS)
|
|
||||||
#else
|
// number of supported endpoints
|
||||||
// #define USB_GPIO_AF (GPIO_AF10_OTG1_HS)
|
#define USB_NUM_OF_ENDPOINTS (6) // set it to the maximum that this type of module can support
|
||||||
#endif
|
|
||||||
#elif defined(USB_STM32F4)
|
// non isochronous transfers
|
||||||
#ifdef USB_HIGH_SPEED
|
#define USB_MAX_FS_PCKT_SIZE_NON_ISOCHRONOUS (64)
|
||||||
#define USB_GPIO_AF (GPIO_AF10_OTG_HS)
|
#define USB_MAX_HS_PCKT_SIZE_NON_ISOCHRONOUS (512)
|
||||||
#else
|
|
||||||
#define USB_GPIO_AF (GPIO_AF10_OTG_FS)
|
// isochronous transfers
|
||||||
#endif
|
#define USB_MAX_FS_PCKT_SIZE_ISOCHRONOUS (1023)
|
||||||
|
|
||||||
|
#define USB_MIN_EP_FIFO_SIZE (64)
|
||||||
|
|
||||||
|
// Unfortunately this cannot be enabled, since the USB controller
|
||||||
|
// generates such enormous amounts of interrupts, so that no other
|
||||||
|
// task can run along the USB processing.
|
||||||
|
#define USB_EVENT_PROCESSING_IN_OS_THREAD (0)
|
||||||
|
|
||||||
|
#if USB_EVENT_PROCESSING_IN_OS_THREAD
|
||||||
|
#include <cmsis_os2.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Set TOCAL and TRDT values (see Ref. Man.)
|
// endpoint configuration structure
|
||||||
#if defined(USB_STM32H7) /*|| defined(USB_HIGH_SPEED)*/
|
typedef struct {
|
||||||
#define TOCAL_VALUE (0x00)
|
uint16_t max_packet_size; // maximum packet size
|
||||||
#define TRDT_VALUE (0x05)
|
bool8_t responding_NAK; // indicates if endpoint responds with NAK
|
||||||
#elif defined(USB_STM32F4)
|
uint8_t type; // endpoint type
|
||||||
#if !defined(USB_HIGH_SPEED)
|
uint8_t service_interval; // service interval
|
||||||
#define TOCAL_VALUE (0x07)
|
|
||||||
#define TRDT_VALUE (0x06)
|
// calculated values
|
||||||
#else
|
|
||||||
#define TOCAL_VALUE (0x07)
|
uint8_t is_configured; // the endpoint is in use
|
||||||
#define TRDT_VALUE (0x09)
|
uint16_t fifo_address; // address in the FIFO
|
||||||
#endif
|
uint16_t fifo_size; // FIFO size
|
||||||
|
bool8_t zlp_next; // indicates, that ZLP should be transmitted at the end of the current transfer (for IN endpoints)
|
||||||
|
bool8_t autoarm; // automatically arm endpoint (for OUT endpoints)
|
||||||
|
} USBDRV_EpConfig;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
USB_FSM_INITIAL_WAIT_SPEEDNEG = 0, // initial state, right after reset, wait for speed negotiation, must be ZERO!
|
||||||
|
USB_FSM_SETUP_OPERATE, // ready to perform setup operations
|
||||||
|
} USBDRV_FsmState;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
USB_EVT_USB_RESET, // bus reset received
|
||||||
|
USB_EVT_SPEEDNEG_DONE, // linespeed negotiation (ST calls "enumeration") done
|
||||||
|
USB_EVT_RECEPTION_DONE, // received packet is waiting to be fetched from the Rx FIFO
|
||||||
|
USB_EVT_OUT_DONE, // something has happened on an OUT endpoint
|
||||||
|
USB_EVT_IN_DONE, // previously armed IN endpoint has finished packet transmission
|
||||||
|
} USBDRV_EventCode;
|
||||||
|
|
||||||
|
// endpoint event
|
||||||
|
typedef enum {
|
||||||
|
USB_EPEVT_IDLE = 0x00, // endpoint is IDLE
|
||||||
|
USB_EPEVT_ARMED, // endpoint is armed for transmission
|
||||||
|
USB_EPEVT_STALLED, // endpoint is stalled
|
||||||
|
USB_EPEVT_NAK // endpoint responds NAK regardless of FIFO level
|
||||||
|
} USBDRV_EndpointEvent;
|
||||||
|
|
||||||
|
// USB device state
|
||||||
|
typedef struct {
|
||||||
|
USBDRV_EpConfig ep_OUT[USB_NUM_OF_ENDPOINTS]; // OUT endpoint configs
|
||||||
|
USBDRV_EpConfig ep_IN[USB_NUM_OF_ENDPOINTS]; // IN endpoint configs
|
||||||
|
uint16_t rx_fifo_size; // Rx FIFO size in bytes
|
||||||
|
uint16_t state; // FSM state
|
||||||
|
uint8_t *rx_buf; // pointer to the receive buffer (this way declaration can be separated)
|
||||||
|
uint16_t rx_buf_level; // fill level of the rx buffer
|
||||||
|
uint8_t address; // device address
|
||||||
|
#if USB_EVENT_PROCESSING_IN_OS_THREAD
|
||||||
|
osMessageQueueId_t event_queue; // event queue
|
||||||
|
osThreadId_t th; // event processing thread
|
||||||
#endif
|
#endif
|
||||||
|
} USBDRV_GlobalState;
|
||||||
|
|
||||||
|
// USB received packet status
|
||||||
|
typedef enum { USB_PCKT_STATUS_GLOBAL_OUT_NAK = 0b0001,
|
||||||
|
USB_PCKT_STATUS_OUT_DATA_RECV = 0b0010,
|
||||||
|
USB_PCKT_STATUS_OUT_TRANSFER_CPLT = 0b0011,
|
||||||
|
USB_PCKT_STATUS_SETUP_CPLT = 0b0100,
|
||||||
|
USB_PCKT_STATUS_SETUP_DATA_RECV = 0b0110,
|
||||||
|
} USBDRV_PcktStatus;
|
||||||
|
|
||||||
|
#define USB_FLUSH_TX_FIFO_ALL (0b10000)
|
||||||
|
|
||||||
|
// event data
|
||||||
|
typedef union {
|
||||||
|
struct {
|
||||||
|
uint8_t pckt_status; // read packet status
|
||||||
|
uint8_t data_pid; // data PID
|
||||||
|
uint8_t byte_count; // byte count
|
||||||
|
uint8_t ep_num; // read endpoint number
|
||||||
|
} rx; // receive event data
|
||||||
|
} USBDRV_EventData;
|
||||||
|
|
||||||
|
// event compound for queueing
|
||||||
|
typedef struct {
|
||||||
|
uint32_t code; // event code
|
||||||
|
USBDRV_EventData data; // accompaining event data
|
||||||
|
} USBDRV_EventCompound;
|
||||||
|
|
||||||
|
// ------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fully initialize USB driver.
|
||||||
|
*/
|
||||||
|
void usbdrv_init();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset USB driver.
|
||||||
|
*/
|
||||||
|
void usbdrv_reset();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize driver interface.
|
||||||
|
*/
|
||||||
|
void usbdrv_init_intf();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* USB peripheral initialization.
|
||||||
|
*
|
||||||
|
* @param reset only perform an after-reset reinitialization
|
||||||
|
*/
|
||||||
|
void usbdrv_periph_init(bool reset);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flush specific TX FIFO.
|
||||||
|
*
|
||||||
|
* @param n index of the TX FIFO
|
||||||
|
*/
|
||||||
|
void usbdrv_flush_tx_fifo(uint8_t n);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flush specific RX FIFO.
|
||||||
|
*/
|
||||||
|
void usbdrv_flush_rx_fifo();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Power down or up the USB peripheral. Also control built-in transciever.
|
||||||
|
*
|
||||||
|
* @param en power on/off
|
||||||
|
*/
|
||||||
|
void usbdrv_power_and_connect(bool en);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configure USB Endpoint.
|
||||||
|
*
|
||||||
|
* @param ep index of the endpoint
|
||||||
|
* @param dir direction of the endpoint to be configured
|
||||||
|
* @param cfg pointer to the configuration details
|
||||||
|
*/
|
||||||
|
void usbdrv_configure_endpoint(uint8_t ep, uint8_t dir, const USBDRV_EpConfig *cfg);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deconfigure a specific USB Endpoint.
|
||||||
|
*
|
||||||
|
* @param ep index of the endpoint
|
||||||
|
* @param dir direction of the endpoint to be deconfigured
|
||||||
|
*/
|
||||||
|
void usbdrv_deconfigure_endpoint(uint8_t ep, uint8_t dir);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stall a particular USB Endpoint.
|
||||||
|
*
|
||||||
|
* @param ep index of the endpoint to be stalled
|
||||||
|
* @param dir direction of the endpoint
|
||||||
|
* @param stall enable/disable stalling
|
||||||
|
*/
|
||||||
|
void usbdrv_stall_endpoint(uint8_t ep, uint8_t dir, bool stall);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implement or rescind responding NAK globally in the chosen direction.
|
||||||
|
*
|
||||||
|
* @param dir communication direction
|
||||||
|
* @param en enable/disable NAK responses
|
||||||
|
*/
|
||||||
|
void usbdrv_set_global_NAK(uint8_t dir, bool en);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch data corresponding to a single Endpoint.
|
||||||
|
*
|
||||||
|
* @param ep index of endpoint
|
||||||
|
* @param len maximum length of data to be fetched
|
||||||
|
*/
|
||||||
|
void usbdrv_fetch_received_data(uint8_t ep, uint16_t len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setup and prepare Endpoint to transfer data towards the host.
|
||||||
|
* May be called multiple times in a single transmission, since
|
||||||
|
* large messages do not have to fit into a single buffer.
|
||||||
|
*
|
||||||
|
* @param ep index of the Endpoint
|
||||||
|
* @param data pointer to the data
|
||||||
|
* @param len length of the data to be read
|
||||||
|
* @return number of bytes read from the data buffer
|
||||||
|
*/
|
||||||
|
uint32_t usbdrv_arm_IN_endpoint(uint8_t ep, const uint8_t *data, uint16_t len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare Endpoint to expect data reception from the host.
|
||||||
|
*
|
||||||
|
* @param ep index of the Endpoint
|
||||||
|
* @param size expected reception length
|
||||||
|
* @return message length that the endpoint can support during next reception
|
||||||
|
*/
|
||||||
|
uint32_t usbdrv_arm_OUT_endpoint(uint8_t ep, uint16_t size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable or disable OUT Endpoint auto arming.
|
||||||
|
* Right after a transaction completes the USB core
|
||||||
|
* automatically prepares the endpoint for the next
|
||||||
|
* reception if this feature is enabled.
|
||||||
|
*
|
||||||
|
* @param ep index of the Endpoint
|
||||||
|
*/
|
||||||
|
void usbdrv_autoarm_OUT_endpoint(uint8_t ep);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mask or unmask Endpoint interrupt generation.
|
||||||
|
*
|
||||||
|
* @param ep index of the Endpoint
|
||||||
|
* @param dir direction of the Endpoint
|
||||||
|
* @param en enable/disable interrupt
|
||||||
|
*/
|
||||||
|
void usbdrv_enable_endpoint_interrupt(uint8_t ep, uint8_t dir, bool en);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the shared FIFO size for all receptions.
|
||||||
|
* (Shared among all OUT endpoints.)
|
||||||
|
* Size of multiple of 4 are recommended. Values
|
||||||
|
* not obeying this will be rounded up.
|
||||||
|
*
|
||||||
|
* @param size FIFO size in BYTES
|
||||||
|
*/
|
||||||
|
void usbdrv_set_rx_fifo_size(uint16_t size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Preload Endpoint config. Do not write configuration
|
||||||
|
* to the hardware right away, just buffer them in.
|
||||||
|
*
|
||||||
|
* @param ep index of the Endpoint
|
||||||
|
* @param dir direction of the Endpint
|
||||||
|
* @param cfg pointer to Endpoint configuration
|
||||||
|
*/
|
||||||
|
void usbdrv_preload_endpoint_config(uint8_t ep, uint8_t dir, const USBDRV_EpConfig *cfg);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear ALL Endpoints' preload configurations.
|
||||||
|
* Does NOT clear configuration in the hardware!
|
||||||
|
*/
|
||||||
|
void usbdrv_clear_endpoint_config();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply preloaded Endpoint configuration, write
|
||||||
|
* Endpoint config to the hardware.
|
||||||
|
*/
|
||||||
|
void usbdrv_apply_endpoint_config();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Select a specific configuration from the descriptor
|
||||||
|
* dump, preload Endpoint settings and finally apply them.
|
||||||
|
*
|
||||||
|
* @param config_index configuration index
|
||||||
|
*/
|
||||||
|
void usbdrv_fetch_endpoint_configuration(uint8_t config_index);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct FIFO considering configured Endpoints.
|
||||||
|
*/
|
||||||
|
void usbdrv_build_fifo();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply an initial EP0 setup.
|
||||||
|
*/
|
||||||
|
void usbdrv_initial_ep0_setup();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set USB device address.
|
||||||
|
*
|
||||||
|
* @param addr device address
|
||||||
|
*/
|
||||||
|
void usbdrv_set_address(uint8_t addr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get driver interface.
|
||||||
|
*
|
||||||
|
* @return pointer to the driver interface
|
||||||
|
*/
|
||||||
|
USB_DrvIntf * usbdrv_get_intf();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register callback for IN transaction complete.
|
||||||
|
*
|
||||||
|
* @param ep index of the Endpoint
|
||||||
|
* @param cb pointer to the callback function
|
||||||
|
*/
|
||||||
|
void usbdrv_register_IN_complete_cb(uint8_t ep, USBDRV_IN_cb cb);
|
||||||
|
|
||||||
#endif /* STM32_USB_DRV */
|
#endif /* STM32_USB_DRV */
|
||||||
|
70
usb.c
70
usb.c
@ -2,35 +2,24 @@
|
|||||||
|
|
||||||
#include <memory.h>
|
#include <memory.h>
|
||||||
|
|
||||||
|
#include "usb_callback_event.h"
|
||||||
#include "usb_common.h"
|
#include "usb_common.h"
|
||||||
|
#include "usb_driver_common.h"
|
||||||
|
|
||||||
// #include "utils/gen_queue.h"
|
// #include "utils/gen_queue.h"
|
||||||
|
|
||||||
#include FLATUSB_DESCRIPTOR_HEADER
|
#include FLATUSB_DESCRIPTOR_HEADER
|
||||||
|
|
||||||
#include "usb_driver.h"
|
|
||||||
|
|
||||||
// ---------------
|
// ---------------
|
||||||
|
|
||||||
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
||||||
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
||||||
|
|
||||||
#ifdef USBDBGMSG
|
|
||||||
#include "../cli/stdio_uart.h"
|
|
||||||
#define USBMSG(...) MSG(__VA_ARGS__)
|
|
||||||
#else
|
|
||||||
#define USBMSG(...)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ---------------
|
// ---------------
|
||||||
|
|
||||||
#ifndef USB_HIGH_SPEED
|
#define USBDRV_ARM_IN_ZLP(ep) drv->arm_IN((ep), NULL, 0)
|
||||||
#define USB_RX_BUF_SIZE (USB_MAX_FS_PCKT_SIZE_NON_ISOCHRONOUS)
|
|
||||||
#else
|
|
||||||
#define USB_RX_BUF_SIZE (USB_MAX_HS_PCKT_SIZE_NON_ISOCHRONOUS)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
#define USB_RX_BUF_SIZE (512) // FIXME
|
||||||
static uint8_t tx_assembly_buf[USB_RX_BUF_SIZE] DWORD_ALIGN; // buffer for assembling packets
|
static uint8_t tx_assembly_buf[USB_RX_BUF_SIZE] DWORD_ALIGN; // buffer for assembling packets
|
||||||
|
|
||||||
// ---------------
|
// ---------------
|
||||||
@ -67,12 +56,29 @@ typedef struct {
|
|||||||
} USB_SetupTransferState;
|
} USB_SetupTransferState;
|
||||||
|
|
||||||
static USB_SetupTransferState stups;
|
static USB_SetupTransferState stups;
|
||||||
|
static USB_DrvIntf *drv;
|
||||||
|
|
||||||
void usbcore_init() {
|
void usbcore_reset() {
|
||||||
// init state
|
// init state
|
||||||
memset(&stups, 0, sizeof(USB_SetupTransferState));
|
memset(&stups, 0, sizeof(USB_SetupTransferState));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void usbcore_rst_notify() {
|
||||||
|
usbcore_reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void usbcore_enum_notify(uint8_t spd) {
|
||||||
|
(void)spd;
|
||||||
|
}
|
||||||
|
|
||||||
|
void usbcore_init(USB_DrvIntf *drvIntf) {
|
||||||
|
usbcore_reset(); // reset USB Core
|
||||||
|
|
||||||
|
drv = drvIntf; // store USB driver interface assignments
|
||||||
|
drv->rst_notify = usbcore_rst_notify; // assign Reset Done callback
|
||||||
|
drv->enum_notify = usbcore_enum_notify; // assign Enumeration Done callback
|
||||||
|
}
|
||||||
|
|
||||||
void usbcore_process_setup_pckt(const uint8_t *data, uint16_t size, uint8_t stage) {
|
void usbcore_process_setup_pckt(const uint8_t *data, uint16_t size, uint8_t stage) {
|
||||||
|
|
||||||
// MSG("STUP: %u, %s\n", size, stage == UST_SETUP ? "SETUP" : "DATA");
|
// MSG("STUP: %u, %s\n", size, stage == UST_SETUP ? "SETUP" : "DATA");
|
||||||
@ -112,7 +118,7 @@ void usbcore_process_setup_pckt(const uint8_t *data, uint16_t size, uint8_t stag
|
|||||||
}
|
}
|
||||||
|
|
||||||
// expect status transaction to follow the data phase
|
// expect status transaction to follow the data phase
|
||||||
usbdrv_arm_OUT_endpoint(0, 64);
|
drv->arm_OUT(0, 64);
|
||||||
|
|
||||||
// only continue processing if the transaction has concluded
|
// only continue processing if the transaction has concluded
|
||||||
if (!stups.out_complete) {
|
if (!stups.out_complete) {
|
||||||
@ -136,7 +142,7 @@ void usbcore_process_setup_pckt(const uint8_t *data, uint16_t size, uint8_t stag
|
|||||||
DETERMINE_TRANSFER_SIZE(devDesc.bLength);
|
DETERMINE_TRANSFER_SIZE(devDesc.bLength);
|
||||||
SET_TRANSMISSION_POINTER(&devDesc);
|
SET_TRANSMISSION_POINTER(&devDesc);
|
||||||
break;
|
break;
|
||||||
case UD_Configuration: // CONFIGURATION DESCRIPTOR
|
case UD_Configuration: // CONFIGURATION DESCRIPTOR
|
||||||
case UD_OtherSpeedConfiguration: // OTHER SPEED CONFIGURATION DESCRIPTOR
|
case UD_OtherSpeedConfiguration: // OTHER SPEED CONFIGURATION DESCRIPTOR
|
||||||
DETERMINE_TRANSFER_SIZE(confDescs[desc_index]->wTotalLength);
|
DETERMINE_TRANSFER_SIZE(confDescs[desc_index]->wTotalLength);
|
||||||
SET_TRANSMISSION_POINTER(confDescs[desc_index]);
|
SET_TRANSMISSION_POINTER(confDescs[desc_index]);
|
||||||
@ -155,26 +161,26 @@ void usbcore_process_setup_pckt(const uint8_t *data, uint16_t size, uint8_t stag
|
|||||||
break;
|
break;
|
||||||
// Descriptors not implemented
|
// Descriptors not implemented
|
||||||
default:
|
default:
|
||||||
usbdrv_stall_endpoint(0, USB_IN, true); // stall IN, since request in unsupported
|
drv->stall(0, USB_IN, true); // stall IN, since request in unsupported
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// arm data transmission
|
// arm data transmission
|
||||||
usbdrv_arm_IN_endpoint(0, data, sz);
|
drv->arm_IN(0, data, sz);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case UREQ_SetAddress: { // SET ADDRESS
|
case UREQ_SetAddress: { // SET ADDRESS
|
||||||
uint8_t addr = stups.setup_req.wValue & 0x7F;
|
uint8_t addr = stups.setup_req.wValue & 0x7F;
|
||||||
usbdrv_set_address(addr);
|
drv->set_address(addr);
|
||||||
usbdrv_arm_OUT_endpoint(0, 64); // prepare for data OUT stage
|
drv->arm_OUT(0, 64); // prepare for data OUT stage
|
||||||
USBDRV_ARM_IN_ZLP(0); // ZLP IN
|
USBDRV_ARM_IN_ZLP(0); // ZLP IN
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case UREQ_SetConfiguration: // SET CONFIGURATION
|
case UREQ_SetConfiguration: // SET CONFIGURATION
|
||||||
{
|
{
|
||||||
uint8_t config_id = stups.setup_req.wValue & 0xFF;
|
uint8_t config_id = stups.setup_req.wValue & 0xFF;
|
||||||
usbdrv_fetch_endpoint_configuration(config_id - 1);
|
drv->set_config(config_id - 1);
|
||||||
USBDRV_ARM_IN_ZLP(0);
|
USBDRV_ARM_IN_ZLP(0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -196,7 +202,7 @@ void usbcore_process_setup_pckt(const uint8_t *data, uint16_t size, uint8_t stag
|
|||||||
usb_event_callback(&cbevt);
|
usb_event_callback(&cbevt);
|
||||||
|
|
||||||
if (cbevt.reply_valid) {
|
if (cbevt.reply_valid) {
|
||||||
usbdrv_arm_IN_endpoint(0, cbevt.reply_data, cbevt.reply_size);
|
drv->arm_IN(0, cbevt.reply_data, cbevt.reply_size);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -241,21 +247,25 @@ void usbcore_process_nonsetup_event(USBDRV_CallbackCompound *cbcpd) {
|
|||||||
// for OUT events, check the autoarm flag
|
// for OUT events, check the autoarm flag
|
||||||
if (cbevt.dir == USB_OUT) {
|
if (cbevt.dir == USB_OUT) {
|
||||||
if (cbevt.arm_out_endpoint) {
|
if (cbevt.arm_out_endpoint) {
|
||||||
usbdrv_autoarm_OUT_endpoint(cbcpd->ep);
|
drv->autoarm(cbcpd->ep);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void usbcore_wake_up_endpoint(uint8_t ep, uint8_t dir) {
|
void usbcore_wake_up_endpoint(uint8_t ep, uint8_t dir) {
|
||||||
usbdrv_enable_endpoint_interrupt(ep, dir, true);
|
drv->en_ep_irq(ep, dir, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void usbcore_register_IN_callback(uint8_t ep, USBDRV_IN_cb cb) {
|
||||||
|
drv->reg_IN_cb(ep, cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t usbcore_schedule_transmission(uint8_t ep, const uint8_t *data, uint16_t size) {
|
uint32_t usbcore_schedule_transmission(uint8_t ep, const uint8_t *data, uint16_t size) {
|
||||||
usbdrv_enable_endpoint_interrupt(ep, USB_IN, true);
|
drv->en_ep_irq(ep, USB_IN, true);
|
||||||
return usbdrv_arm_IN_endpoint(ep, data, size);
|
return drv->arm_IN(ep, data, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t usbcore_schedule_reception(uint8_t ep, uint16_t size) {
|
uint32_t usbcore_schedule_reception(uint8_t ep, uint16_t size) {
|
||||||
return usbdrv_arm_OUT_endpoint(ep, size);
|
return drv->arm_OUT(ep, size);
|
||||||
}
|
}
|
7
usb.h
7
usb.h
@ -1,11 +1,14 @@
|
|||||||
#ifndef CORE_USB_USB
|
#ifndef CORE_USB_USB
|
||||||
#define CORE_USB_USB
|
#define CORE_USB_USB
|
||||||
|
|
||||||
#include "usb_callback_event.h"
|
#include <stdint.h>
|
||||||
|
|
||||||
void usbcore_init(); // initialize USB core
|
#include "usb_driver_common.h"
|
||||||
|
|
||||||
|
void usbcore_init(USB_DrvIntf *drvIntf); // initialize USB core
|
||||||
uint32_t usbcore_schedule_transmission(uint8_t ep, const uint8_t *data, uint16_t size); // write data to endpoint, return with number of bytes actually written
|
uint32_t usbcore_schedule_transmission(uint8_t ep, const uint8_t *data, uint16_t size); // write data to endpoint, return with number of bytes actually written
|
||||||
uint32_t usbcore_schedule_reception(uint8_t ep, uint16_t size); // expect data coming from the endpoint
|
uint32_t usbcore_schedule_reception(uint8_t ep, uint16_t size); // expect data coming from the endpoint
|
||||||
void usbcore_wake_up_endpoint(uint8_t ep, uint8_t dir); // wake up endpoint
|
void usbcore_wake_up_endpoint(uint8_t ep, uint8_t dir); // wake up endpoint
|
||||||
|
void usbcore_register_IN_callback(uint8_t ep, USBDRV_IN_cb cb); // register IN complete callback
|
||||||
|
|
||||||
#endif /* CORE_USB_USB */
|
#endif /* CORE_USB_USB */
|
||||||
|
@ -4,12 +4,14 @@
|
|||||||
#include "usb_common_types.h"
|
#include "usb_common_types.h"
|
||||||
#include "usb_device_types.h"
|
#include "usb_device_types.h"
|
||||||
|
|
||||||
|
#define USB_DELAY(t) for (uint64_t i = 0; i < (t) * 10000; i++) { asm("nop"); }
|
||||||
|
|
||||||
#define READ_FIELD(r,f) (((r) & (f##_Msk)) >> (f##_Pos))
|
#define READ_FIELD(r,f) (((r) & (f##_Msk)) >> (f##_Pos))
|
||||||
#define WRITE_FIELD(r,f,v) ((r) = ((r) & ~(f##_Msk)) | (v << (f##_Pos)))
|
#define WRITE_FIELD(r,f,v) ((r) = ((r) & ~(f##_Msk)) | (v << (f##_Pos)))
|
||||||
#define WAIT_FOR_BIT(r,b) while ((r) & (b)) {}
|
#define WAIT_FOR_BIT(r,b) while ((r) & (b)) {}
|
||||||
#define WAIT_FOR_BIT_DELAY(r,b,d) while ((r) & (b)) { HAL_Delay((d)); }
|
#define WAIT_FOR_BIT_DELAY(r,b,d) while ((r) & (b)) { USB_DELAY((d)); }
|
||||||
#define WAIT_FOR_nBIT(r,b) while (!((r) & (b))) {}
|
#define WAIT_FOR_nBIT(r,b) while (!((r) & (b))) {}
|
||||||
#define WAIT_FOR_nBIT_DELAY(r,b,d) while (!((r) & (b))) { HAL_Delay((d)); }
|
#define WAIT_FOR_nBIT_DELAY(r,b,d) while (!((r) & (b))) { USB_DELAY((d)); }
|
||||||
|
|
||||||
#define DWORD_ALIGN __attribute__((aligned(4)))
|
#define DWORD_ALIGN __attribute__((aligned(4)))
|
||||||
|
|
||||||
|
57
usb_driver_common.h
Normal file
57
usb_driver_common.h
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
#ifndef FLATUSB_USB_DRIVER_INTERFACE
|
||||||
|
#define FLATUSB_USB_DRIVER_INTERFACE
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
USB_SPD_UKWN = 0,
|
||||||
|
USB_SPD_LOW = 1,
|
||||||
|
USB_SPD_FULL = 2,
|
||||||
|
USB_SPD_HIGH = 3
|
||||||
|
} USBDRV_LineSpeed;
|
||||||
|
|
||||||
|
typedef void (*USBDRV_IN_cb)(uint8_t ep);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
// USB CORE -> USB DRIVER
|
||||||
|
void (*init)(); // initialize USB driver
|
||||||
|
void (*reset)(); // reset USB driver
|
||||||
|
void (*stall)(uint8_t ep, uint8_t dir, bool stall); // stall the endpoint
|
||||||
|
uint32_t (*arm_IN)(uint8_t ep, const uint8_t *data, uint16_t len); // arm IN endpoint
|
||||||
|
uint32_t (*arm_OUT)(uint8_t ep, uint16_t len); // arm OUT endpoint
|
||||||
|
void (*set_address)(uint8_t addr); // set device address
|
||||||
|
void (*set_config)(uint8_t ci); // make the chosen setting operational
|
||||||
|
void (*autoarm)(uint8_t ep); // enable OUT autoarm
|
||||||
|
void (*en_ep_irq)(uint8_t ep, uint8_t dir, bool en); // enable endpoint interrupt
|
||||||
|
void (*reg_IN_cb)(uint8_t ep, USBDRV_IN_cb cb); // register a callback for IN transaction complete
|
||||||
|
|
||||||
|
// USB DRIVER -> USB CORE
|
||||||
|
void (*rst_notify)(); // notify USB core of a bus issued reset
|
||||||
|
void (*enum_notify)(uint8_t spd); // notify the USB core that speed negotiation has concluded
|
||||||
|
} USB_DrvIntf;
|
||||||
|
|
||||||
|
#ifndef USBDBGMSG
|
||||||
|
#define USBMSG(...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// callback codes
|
||||||
|
typedef enum {
|
||||||
|
USB_CBC_OUT, // OUT done!
|
||||||
|
USB_CBC_IN_DONE, // IN done!
|
||||||
|
USB_CBC_IN_FIFOEMPTY, // could not serve IN request, since Tx FIFO was empty
|
||||||
|
} USBDRV_CallbackCode;
|
||||||
|
|
||||||
|
// callback compound
|
||||||
|
typedef struct {
|
||||||
|
uint8_t ep : 4; // endpoint number
|
||||||
|
uint8_t dir : 1; // direction
|
||||||
|
uint8_t code : 3; // event code
|
||||||
|
uint16_t size; // data size
|
||||||
|
const uint8_t *data; // data
|
||||||
|
} USBDRV_CallbackCompound;
|
||||||
|
|
||||||
|
typedef enum { UST_SETUP,
|
||||||
|
UST_DATA } USBDRV_ControlTfStage;
|
||||||
|
|
||||||
|
#endif /* FLATUSB_USB_DRIVER_INTERFACE */
|
Loading…
x
Reference in New Issue
Block a user