#ifndef CH32_USB_DRV #define CH32_USB_DRV #include "../../usb_common_types.h" #include "../../usb_driver_common.h" // maximum number of endpoints that can be supported #define USB_MAX_NUM_OF_ENDPOINTS (8) // number of supported endpoints #ifndef USB_NUM_OF_ENDPOINTS // number of endpoints can be overridden to conserve memory #define USB_NUM_OF_ENDPOINTS (USB_MAUSB_MAX_NUM_OF_ENDPOINTS) // set it to the maximum that this type of module can support #else #if USB_MAX_NUM_OF_ENDPOINTS > USB_MAX_NUM_OF_ENDPOINTS // do not allow greater number of endpoints than what the device supports #undef USB_NUM_OF_ENDPOINTS #define USB_NUM_OF_ENDPOINTS (USB_MUSB_MAX_NUM_OF_ENDPOINTS) #endif #endif // non isochronous transfers #define USB_MAX_FS_PCKT_SIZE_NON_ISOCHRONOUS (64) // isochronous transfers #define USB_MAX_FS_PCKT_SIZE_ISOCHRONOUS (1023) // endpoint configuration structure typedef struct { uint16_t max_packet_size; // maximum packet size bool8_t responding_NAK; // indicates if endpoint responds with NAK uint8_t type; // endpoint type uint8_t service_interval; // service interval // calculated values uint8_t is_configured; // the endpoint is in use uint16_t buffer_address; // address in the FIFO 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) bool8_t txp; // transfer in progress } USBDRV_EpConfig; typedef enum { USB_EVT_USB_RESET, // bus reset received USB_EVT_TRANSFER_COMPLETION, } USBDRV_EventCode; // 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 uint8_t *buf; // pointer to the receive buffer (this way declaration can be separated) uint8_t address; // device address bool address_pending; // address change is pending } USBDRV_GlobalState; // 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(); /** * Init driver's global state. */ void usbdrv_init_global_state(); /** * Initialize driver interface. */ void usbdrv_init_intf(); /** * USB peripheral initialization. * * @param reset only perform an after-reset reinitialization */ void usbdrv_periph_init(bool reset); /** * Clear all TX and RX FIFOs. */ void usbdrv_clear_all_fifos(); /** * 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); /** * 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); /** * 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_allocate_buffers(); /** * 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 */ UsbDrv_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); /** * Get Endpoint interrupt flag. * * @param ep index of the Endpoint * @param dir direction of the Endpoint * @return flag was set */ bool usbdrv_get_endpoint_interrupt_flag(uint8_t ep, uint8_t dir); #endif /* CH32_USB_DRV */