From 88bb420b269e3152bfc482d0b3069b070cbf4691 Mon Sep 17 00:00:00 2001 From: Epagris Date: Tue, 25 Feb 2025 12:17:11 +0100 Subject: [PATCH] - ACM fixes, CH32 driver fixes, example CH32 config added --- class/acm.c | 13 ++++--- driver/ch32/usb_drv.c | 23 +++++++---- examples/configs/flatUSB_config_ch32f207_fs.h | 38 +++++++++++++++++++ 3 files changed, 62 insertions(+), 12 deletions(-) create mode 100644 examples/configs/flatUSB_config_ch32f207_fs.h diff --git a/class/acm.c b/class/acm.c index 9242278..1234ad4 100644 --- a/class/acm.c +++ b/class/acm.c @@ -32,7 +32,8 @@ static osEventFlagsId_t flags; ///< Event flags #define USB_ACM_COMM_INIT (0x02) ///< Communication has been initialized #define USB_ACM_HOSTBOUND_DATA_AVAIL (0x04) ///< Hostbound data is available -#define USB_ACM_LOOP_TIMEOUT_TICKS (100) ///< Main loop timeout for interrupt status transmission +#define USB_ACM_LOOP_TIMEOUT_TICKS (100) ///< Main loop timeout for interrupt status transmission +#define USB_ACM_INITIAL_DELAY_TICKS (100) ///< Delay before sending data // ------------------------- @@ -41,13 +42,15 @@ static void thread_usb_acm(void *arg) { osEventFlagsSet(flags, USB_ACM_DATA_IN_DONE); // assume we can write to the data endpoint + osDelay(USB_ACM_INITIAL_DELAY_TICKS); // inject some initial delay + while (true) { uint32_t signals = osEventFlagsWait(flags, USB_ACM_HOSTBOUND_DATA_AVAIL, osFlagsWaitAny, USB_ACM_LOOP_TIMEOUT_TICKS); if (signals != osErrorTimeout) { // check timeout if (signals & USB_ACM_HOSTBOUND_DATA_AVAIL) { // data hostbound available do { - osEventFlagsWait(flags, USB_ACM_DATA_IN_DONE, osFlagsWaitAny, 1000); // wait for the IN DONE flag + osEventFlagsWait(flags, USB_ACM_DATA_IN_DONE, osFlagsWaitAny, 1); // wait for the IN DONE flag uint32_t readSize = bfifo_read(&fifo, tx_buffer, USB_ACM_PCKT_BUFSIZE); // read from the fifo if (readSize > 0) { uint32_t writeSize = usbcore_schedule_transmission(acms.ep_assignments.data_ep, tx_buffer, readSize); // write data acquired from the buffer @@ -85,6 +88,9 @@ void usb_acm_init(const Usb_Acm_EpAssignments *as) { // communication parameters have not been set acms.commInit = false; + // from now on CDC module is considered initialized + acms.moduleInit = true; + // create flags flags = osEventFlagsNew(NULL); @@ -94,9 +100,6 @@ void usb_acm_init(const Usb_Acm_EpAssignments *as) { attr.stack_size = 1024; attr.name = "acm"; th = osThreadNew(thread_usb_acm, NULL, &attr); - - // from now on CDC module is considered initialized - acms.moduleInit = true; } static void usb_cdc_review_comm_init() { diff --git a/driver/ch32/usb_drv.c b/driver/ch32/usb_drv.c index 0efdbe0..3fefbeb 100644 --- a/driver/ch32/usb_drv.c +++ b/driver/ch32/usb_drv.c @@ -43,8 +43,8 @@ static UsbDrv_IN_cb cbs[USB_NUM_OF_ENDPOINTS]; ///< Callbacks for IN co // FIXME: ez lehet, hogy pont fordĂ­tva van... #define USB_EP_GET_EP0_BUFFER() (gs.buf) -#define USB_EP_GET_TX_BUFFER(ep) (gs.buf + ((ep) * USB_EP_COMBINED_BUF_SIZE)) -#define USB_EP_GET_RX_BUFFER(ep) (gs.buf + ((ep) * USB_EP_COMBINED_BUF_SIZE) + USB_EP_TX_BUF_SIZE) +#define USB_EP_GET_TX_BUFFER(ep) (gs.buf + ((ep) * USB_EP_COMBINED_BUF_SIZE) + USB_EP_RX_BUF_SIZE) +#define USB_EP_GET_RX_BUFFER(ep) (gs.buf + ((ep) * USB_EP_COMBINED_BUF_SIZE)) /** \cond false */ #define MAX(a, b) (((a) > (b)) ? (a) : (b)) @@ -141,6 +141,14 @@ void usbdrv_init_global_state() { gs.buf = buf; } +/** + * Hook for initializing modules after the low-level driver has been initialized + * but has not been connected to the bus yet. + */ +__weak void usbdrv_init_hook() { + return; +} + // initialize USB subsystem void usbdrv_init() { USB_IRQ_DISABLE(USB_IRQ_N); // disable USB interrupts @@ -150,6 +158,7 @@ void usbdrv_init() { usbdrv_gpio_init(); usbdrv_periph_init(false); usbdrv_initial_ep0_setup(); + usbdrv_init_hook(); // <--- usbdrv_power_and_connect(true); USB_IRQ_SET_PRIORITY(USB_IRQ_N, USB_IRQ_PRIORITY); @@ -311,7 +320,7 @@ uint32_t usbdrv_arm_IN_endpoint(uint8_t ep, const uint8_t *data, uint16_t len) { // copy data to the output buffer if (txLen > 0) { - uint8_t *txBuf = USB_EP_GET_EP0_BUFFER(); + uint8_t *txBuf = (ep == 0) ? USB_EP_GET_EP0_BUFFER() : USB_EP_GET_TX_BUFFER(ep); memcpy(txBuf, data, txLen); } @@ -321,9 +330,9 @@ uint32_t usbdrv_arm_IN_endpoint(uint8_t ep, const uint8_t *data, uint16_t len) { // append ZLP only, if packet size is MAX_PCKT_SIZE (this way to ZLP is injected in a longer packet whose first part is limited to 64 bytes) gs.ep_IN[ep].zlp_next = (len == USB_MAX_FS_PCKT_SIZE_NON_ISOCHRONOUS); - // EP0 must begin responding with DATA1 - // if (ep == 0) { - // SET_BIT(*epc->TX_CTRL, USBFS_UEP_T_TOG); + // non-EP0 must begin responding with DATA0 + // if (ep != 0) { + // CLEAR_BIT(*epc->TX_CTRL, USBFS_UEP_T_TOG); // } // signal that transmission is in progress @@ -445,7 +454,7 @@ void usbdrv_fetch_endpoint_configuration(uint8_t config_index) { // build buffer structure, allocate buffers (compute addresses) void usbdrv_allocate_buffers() { for (uint8_t i = 0; i < USB_NUM_OF_ENDPOINTS; i++) { - *USB_EPCtrl[i].BUF_START_ADDR = (uint32_t)USB_EP_GET_TX_BUFFER(i); + *USB_EPCtrl[i].BUF_START_ADDR = (uint32_t)USB_EP_GET_RX_BUFFER(i); USBDRV_EpConfig *cfg = &gs.ep_IN[i]; if (cfg->is_configured) { diff --git a/examples/configs/flatUSB_config_ch32f207_fs.h b/examples/configs/flatUSB_config_ch32f207_fs.h new file mode 100644 index 0000000..84fa3f6 --- /dev/null +++ b/examples/configs/flatUSB_config_ch32f207_fs.h @@ -0,0 +1,38 @@ +#ifndef CONFIGS_FLATUSB_CONFIG +#define CONFIGS_FLATUSB_CONFIG +#ifndef SRC_FLATUSB_CONFIG +#define SRC_FLATUSB_CONFIG + +#include +#include +#include + +static inline void usbdrv_gpio_init(void) { + // turn ON GPIOA clocks + RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); +} + +#define USB_IRQ_N OTG_FS_IRQn +#define USB_IRQ_HANDLER OTG_FS_IRQHandler +#define USB_IRQ_PRIORITY (8) +#define USB_IRQ_SET_PRIORITY(irq, priority) NVIC_SetPriority((irq),(priority)) +#define USB_IRQ_ENABLE(irq) NVIC_EnableIRQ((irq)) +#define USB_IRQ_DISABLE(irq) NVIC_DisableIRQ((irq)) + +// define USBG +#define USBG (USBOTG_FS) + +#define USB_CLOCK_ENABLE() RCC_AHBPeriphClockCmd(RCC_AHBPeriph_OTG_FS, ENABLE);\ + RCC_APB1PeriphClockCmd(RCC_APB1Periph_USB, ENABLE) + +#include "embfmt/embformat.h" +#define SNPRINTF(str, n, fmt, ...) embfmt(str, n, fmt, __VA_ARGS__) + +#ifdef USBDBGMSG +#define USBMSG(...) MSG(__VA_ARGS__) +#endif + +#endif /* SRC_FLATUSB_CONFIG */ + + +#endif /* CONFIGS_FLATUSB_CONFIG */