diff --git a/demos/rt/RT-STM32F407-DISCOVERY-MEMS/Makefile b/demos/rt/RT-STM32F407-DISCOVERY-MEMS/Makefile index 6d6c54232..6a1e61aa3 100644 --- a/demos/rt/RT-STM32F407-DISCOVERY-MEMS/Makefile +++ b/demos/rt/RT-STM32F407-DISCOVERY-MEMS/Makefile @@ -96,7 +96,10 @@ CSRC = $(PORTSRC) \ $(OSALSRC) \ $(PLATFORMSRC) \ $(BOARDSRC) \ - main.c + $(CHIBIOS)/os/various/devices_lib/accel/lis302dl.c \ + $(CHIBIOS)/os/various/shell.c \ + $(CHIBIOS)/os/various/chprintf.c \ + usbcfg.c main.c # C++ sources that can be compiled in ARM or THUMB mode depending on the global # setting. @@ -127,6 +130,7 @@ ASMSRC = $(PORTASM) INCDIR = $(PORTINC) $(KERNINC) $(TESTINC) \ $(HALINC) $(OSALINC) $(PLATFORMINC) $(BOARDINC) \ + $(CHIBIOS)/os/various/devices_lib/accel \ $(CHIBIOS)/os/various # diff --git a/demos/rt/RT-STM32F407-DISCOVERY-MEMS/main.c b/demos/rt/RT-STM32F407-DISCOVERY-MEMS/main.c index c71f2f1ee..f3f6a0e86 100644 --- a/demos/rt/RT-STM32F407-DISCOVERY-MEMS/main.c +++ b/demos/rt/RT-STM32F407-DISCOVERY-MEMS/main.c @@ -31,8 +31,8 @@ SerialUSBDriver SDU1; /* Command line related. */ /*===========================================================================*/ -#define SHELL_WA_SIZE THD_WA_SIZE(2048) -#define TEST_WA_SIZE THD_WA_SIZE(256) +#define SHELL_WA_SIZE THD_WORKING_AREA_SIZE(2048) +#define TEST_WA_SIZE THD_WORKING_AREA_SIZE(256) static void cmd_mem(BaseSequentialStream *chp, int argc, char *argv[]) { size_t n, size; @@ -49,7 +49,7 @@ static void cmd_mem(BaseSequentialStream *chp, int argc, char *argv[]) { } static void cmd_threads(BaseSequentialStream *chp, int argc, char *argv[]) { - static const char *states[] = {CH_THD_STATE_NAMES}; + static const char *states[] = {CH_STATE_NAMES}; thread_t *tp; (void)argv; @@ -62,7 +62,8 @@ static void cmd_threads(BaseSequentialStream *chp, int argc, char *argv[]) { do { chprintf(chp, "%.8lx %.8lx %4lu %4lu %9s\r\n", (uint32_t)tp, (uint32_t)tp->p_ctx.r13, - (uint32_t)tp->p_prio, (uint32_t)(tp->p_refs - 1)); + (uint32_t)tp->p_prio, (uint32_t)(tp->p_refs - 1), + states[tp->p_state]); tp = chRegNextThread(tp); } while (tp != NULL); } @@ -150,8 +151,8 @@ static const SPIConfig spi2cfg = { * This is a periodic thread that reads accelerometer and outputs * result to SPI2 and PWM. */ -static WORKING_AREA(waThread1, 128); -static msg_t Thread1(void *arg) { +static THD_WORKING_AREA(waThread1, 128); +static THD_FUNCTION(Thread1, arg) { static int8_t xbuf[4], ybuf[4]; /* Last accelerometer data.*/ systime_t time; /* Next deadline.*/ @@ -164,7 +165,7 @@ static msg_t Thread1(void *arg) { lis302dlWriteRegister(&SPID1, LIS302DL_CTRL_REG3, 0x00); /* Reader thread loop.*/ - time = chTimeNow(); + time = chVTGetSystemTime(); while (TRUE) { int32_t x, y; unsigned i; @@ -314,7 +315,7 @@ int main(void) { } else { /* If the previous shell exited.*/ - if (chThdTerminated(shelltp)) { + if (chThdTerminatedX(shelltp)) { /* Recovers memory of the previous shell.*/ chThdRelease(shelltp); shelltp = NULL; diff --git a/demos/rt/RT-STM32F407-DISCOVERY-MEMS/usbcfg.c b/demos/rt/RT-STM32F407-DISCOVERY-MEMS/usbcfg.c index 24955b881..cc943edd2 100644 --- a/demos/rt/RT-STM32F407-DISCOVERY-MEMS/usbcfg.c +++ b/demos/rt/RT-STM32F407-DISCOVERY-MEMS/usbcfg.c @@ -270,7 +270,7 @@ static void usb_event(USBDriver *usbp, usbevent_t event) { case USB_EVENT_ADDRESS: return; case USB_EVENT_CONFIGURED: - chSysLockFromIsr(); + chSysLockFromISR(); /* Enables the endpoints specified into the configuration. Note, this callback is invoked from an ISR so I-Class functions @@ -281,7 +281,7 @@ static void usb_event(USBDriver *usbp, usbevent_t event) { /* Resetting the state of the CDC subsystem.*/ sduConfigureHookI(&SDU1); - chSysUnlockFromIsr(); + chSysUnlockFromISR(); return; case USB_EVENT_SUSPEND: return; diff --git a/os/hal/ports/STM32/OTGv1/usb_lld.c b/os/hal/ports/STM32/OTGv1/usb_lld.c index f6287a49c..2db125d47 100644 --- a/os/hal/ports/STM32/OTGv1/usb_lld.c +++ b/os/hal/ports/STM32/OTGv1/usb_lld.c @@ -24,7 +24,6 @@ #include -#include "ch.h" #include "hal.h" #if HAL_USE_USB || defined(__DOXYGEN__) @@ -110,21 +109,6 @@ static const stm32_otg_params_t hsparams = { /* Driver local functions. */ /*===========================================================================*/ -/** - * @brief Wakes up the pump thread. - * - * @param[in] usbp pointer to the @p USBDriver object - * - * @notapi - */ -static void usb_lld_wakeup_pump(USBDriver *usbp) { - - if (usbp->thd_wait != NULL) { - chThdResumeI(usbp->thd_wait); - usbp->thd_wait = NULL; - } -} - static void otg_core_reset(USBDriver *usbp) { stm32_otg_t *otgp = usbp->otg; @@ -132,7 +116,7 @@ static void otg_core_reset(USBDriver *usbp) { otgp->GRSTCTL = GRSTCTL_CSRST; while ((otgp->GRSTCTL & GRSTCTL_CSRST) != 0) ; - halPolledDelay(12); + osalSysPolledDelayX(12); /* Wait AHB idle condition.*/ while ((otgp->GRSTCTL & GRSTCTL_AHBIDL) == 0) ; @@ -182,7 +166,7 @@ static void otg_rxfifo_flush(USBDriver *usbp) { while ((otgp->GRSTCTL & GRSTCTL_RXFFLSH) != 0) ; /* Wait for 3 PHY Clocks.*/ - halPolledDelay(12); + osalSysPolledDelayX(12); } static void otg_txfifo_flush(USBDriver *usbp, uint32_t fifo) { @@ -192,7 +176,7 @@ static void otg_txfifo_flush(USBDriver *usbp, uint32_t fifo) { while ((otgp->GRSTCTL & GRSTCTL_TXFFLSH) != 0) ; /* Wait for 3 PHY Clocks.*/ - halPolledDelay(12); + osalSysPolledDelayX(12); } /** @@ -220,8 +204,8 @@ static uint32_t otg_ram_alloc(USBDriver *usbp, size_t size) { next = usbp->pmnext; usbp->pmnext += size; - chDbgAssert(usbp->pmnext <= usbp->otgparams->otg_ram_size, - "otg_fifo_alloc(), #1", "OTG FIFO memory overflow"); + osalDbgAssert(usbp->pmnext <= usbp->otgparams->otg_ram_size, + "OTG FIFO memory overflow"); return next; } @@ -269,13 +253,13 @@ static void otg_fifo_write_from_buffer(volatile uint32_t *fifop, * @brief Writes to a TX FIFO fetching data from a queue. * * @param[in] fifop pointer to the FIFO register - * @param[in] oqp pointer to an @p OutputQueue object + * @param[in] oqp pointer to an @p output_queue_t object * @param[in] n maximum number of bytes to copy * * @notapi */ static void otg_fifo_write_from_queue(volatile uint32_t *fifop, - OutputQueue *oqp, + output_queue_t *oqp, size_t n) { size_t ntogo; @@ -315,12 +299,11 @@ static void otg_fifo_write_from_queue(volatile uint32_t *fifop, } /* Updating queue.*/ - chSysLock(); + osalSysLock(); oqp->q_counter += n; - while (notempty(&oqp->q_waiting)) - chSchReadyI(fifo_remove(&oqp->q_waiting))->p_u.rdymsg = Q_OK; - chSchRescheduleS(); - chSysUnlock(); + osalQueueWakeupAllI(&oqp->q_waiting, Q_OK); + osalOsRescheduleS(); + osalSysUnlock(); } /** @@ -382,13 +365,13 @@ static void otg_fifo_read_to_buffer(volatile uint32_t *fifop, * @brief Reads a packet from the RXFIFO. * * @param[in] fifop pointer to the FIFO register - * @param[in] iqp pointer to an @p InputQueue object + * @param[in] iqp pointer to an @p input_queue_t object * @param[in] n number of bytes to pull from the FIFO * * @notapi */ static void otg_fifo_read_to_queue(volatile uint32_t *fifop, - InputQueue *iqp, + input_queue_t *iqp, size_t n) { size_t ntogo; @@ -427,12 +410,11 @@ static void otg_fifo_read_to_queue(volatile uint32_t *fifop, } /* Updating queue.*/ - chSysLock(); + osalSysLock(); iqp->q_counter += n; - while (notempty(&iqp->q_waiting)) - chSchReadyI(fifo_remove(&iqp->q_waiting))->p_u.rdymsg = Q_OK; - chSchRescheduleS(); - chSysUnlock(); + osalQueueWakeupAllI(&iqp->q_waiting, Q_OK); + osalOsRescheduleS(); + osalSysUnlock(); } /** @@ -489,7 +471,7 @@ static void otg_rxfifo_handler(USBDriver *usbp) { * * @notapi */ -static bool_t otg_txfifo_handler(USBDriver *usbp, usbep_t ep) { +static bool otg_txfifo_handler(USBDriver *usbp, usbep_t ep) { /* The TXFIFO is filled until there is space and data to be transmitted.*/ while (TRUE) { @@ -557,11 +539,11 @@ static void otg_epin_handler(USBDriver *usbp, usbep_t ep) { if ((epint & DIEPINT_TXFE) && (otgp->DIEPEMPMSK & DIEPEMPMSK_INEPTXFEM(ep))) { /* The thread is made ready, it will be scheduled on ISR exit.*/ - chSysLockFromIsr(); + osalSysLockFromISR(); usbp->txpending |= (1 << ep); otgp->DIEPEMPMSK &= ~(1 << ep); - usb_lld_wakeup_pump(usbp); - chSysUnlockFromIsr(); + osalThreadResumeI(&usbp->wait, MSG_OK); + osalSysUnlockFromISR(); } } @@ -626,10 +608,10 @@ static void usb_lld_serve_interrupt(USBDriver *usbp) { if (sts & GINTSTS_RXFLVL) { /* The interrupt is masked while the thread has control or it would be triggered again.*/ - chSysLockFromIsr(); + osalSysLockFromISR(); otgp->GINTMSK &= ~GINTMSK_RXFLVLM; - usb_lld_wakeup_pump(usbp); - chSysUnlockFromIsr(); + osalThreadResumeI(&usbp->wait, MSG_OK); + osalSysUnlockFromISR(); } /* IN/OUT endpoints event handling.*/ @@ -669,67 +651,9 @@ static void usb_lld_serve_interrupt(USBDriver *usbp) { } /*===========================================================================*/ -/* Driver interrupt handlers and threads. */ +/* Driver interrupt handlers. */ /*===========================================================================*/ -static msg_t usb_lld_pump(void *p) { - USBDriver *usbp = (USBDriver *)p; - stm32_otg_t *otgp = usbp->otg; - - chRegSetThreadName("usb_lld_pump"); - chSysLock(); - while (TRUE) { - usbep_t ep; - uint32_t epmask; - - /* Nothing to do, going to sleep.*/ - if ((usbp->state == USB_STOP) || - ((usbp->txpending == 0) && !(otgp->GINTSTS & GINTSTS_RXFLVL))) { - otgp->GINTMSK |= GINTMSK_RXFLVLM; - usbp->thd_wait = chThdSelf(); - chSchGoSleepS(THD_STATE_SUSPENDED); - } - chSysUnlock(); - - /* Checks if there are TXFIFOs to be filled.*/ - for (ep = 0; ep <= usbp->otgparams->num_endpoints; ep++) { - - /* Empties the RX FIFO.*/ - while (otgp->GINTSTS & GINTSTS_RXFLVL) { - otg_rxfifo_handler(usbp); - } - - epmask = (1 << ep); - if (usbp->txpending & epmask) { - bool_t done; - - chSysLock(); - /* USB interrupts are globally *suspended* because the peripheral - does not allow any interference during the TX FIFO filling - operation. - Synopsys document: DesignWare Cores USB 2.0 Hi-Speed On-The-Go (OTG) - "The application has to finish writing one complete packet before - switching to a different channel/endpoint FIFO. Violating this - rule results in an error.".*/ - otgp->GAHBCFG &= ~GAHBCFG_GINTMSK; - usbp->txpending &= ~epmask; - chSysUnlock(); - - done = otg_txfifo_handler(usbp, ep); - - chSysLock(); - otgp->GAHBCFG |= GAHBCFG_GINTMSK; - if (!done) - otgp->DIEPEMPMSK |= epmask; - chSysUnlock(); - } - } - chSysLock(); - } - chSysUnlock(); - return 0; -} - #if STM32_USB_USE_OTG1 || defined(__DOXYGEN__) #if !defined(STM32_OTG1_HANDLER) #error "STM32_OTG1_HANDLER not defined" @@ -739,13 +663,13 @@ static msg_t usb_lld_pump(void *p) { * * @isr */ -CH_IRQ_HANDLER(STM32_OTG1_HANDLER) { +OSAL_IRQ_HANDLER(STM32_OTG1_HANDLER) { - CH_IRQ_PROLOGUE(); + OSAL_IRQ_PROLOGUE(); usb_lld_serve_interrupt(&USBD1); - CH_IRQ_EPILOGUE(); + OSAL_IRQ_EPILOGUE(); } #endif @@ -758,13 +682,13 @@ CH_IRQ_HANDLER(STM32_OTG1_HANDLER) { * * @isr */ -CH_IRQ_HANDLER(STM32_OTG2_HANDLER) { +OSAL_IRQ_HANDLER(STM32_OTG2_HANDLER) { - CH_IRQ_PROLOGUE(); + OSAL_IRQ_PROLOGUE(); usb_lld_serve_interrupt(&USBD2); - CH_IRQ_EPILOGUE(); + OSAL_IRQ_EPILOGUE(); } #endif @@ -782,46 +706,16 @@ void usb_lld_init(void) { /* Driver initialization.*/ #if STM32_USB_USE_OTG1 usbObjectInit(&USBD1); - USBD1.thd_ptr = NULL; - USBD1.thd_wait = NULL; + USBD1.wait = NULL; USBD1.otg = OTG_FS; USBD1.otgparams = &fsparams; - - /* Filling the thread working area here because the function - @p chThdCreateI() does not do it.*/ -#if CH_DBG_FILL_THREADS - { - void *wsp = USBD1.wa_pump; - _thread_memfill((uint8_t *)wsp, - (uint8_t *)wsp + sizeof(Thread), - CH_THREAD_FILL_VALUE); - _thread_memfill((uint8_t *)wsp + sizeof(Thread), - (uint8_t *)wsp + sizeof(USBD1.wa_pump) - sizeof(Thread), - CH_STACK_FILL_VALUE); - } -#endif #endif #if STM32_USB_USE_OTG2 usbObjectInit(&USBD2); - USBD2.thd_ptr = NULL; - USBD2.thd_wait = NULL; + USBD2.wait = NULL; USBD2.otg = OTG_HS; USBD2.otgparams = &hsparams; - - /* Filling the thread working area here because the function - @p chThdCreateI() does not do it.*/ -#if CH_DBG_FILL_THREADS - { - void *wsp = USBD2.wa_pump; - _thread_memfill((uint8_t *)wsp, - (uint8_t *)wsp + sizeof(Thread), - CH_THREAD_FILL_VALUE); - _thread_memfill((uint8_t *)wsp + sizeof(Thread), - (uint8_t *)wsp + sizeof(USBD2.wa_pump) - sizeof(Thread), - CH_STACK_FILL_VALUE); - } -#endif #endif } @@ -847,8 +741,7 @@ void usb_lld_start(USBDriver *usbp) { rccResetOTG_FS(); /* Enables IRQ vector.*/ - nvicEnableVector(STM32_OTG1_NUMBER, - CORTEX_PRIORITY_MASK(STM32_USB_OTG1_IRQ_PRIORITY)); + nvicEnableVector(STM32_OTG1_NUMBER, STM32_USB_OTG1_IRQ_PRIORITY); } #endif #if STM32_USB_USE_OTG2 @@ -858,20 +751,11 @@ void usb_lld_start(USBDriver *usbp) { rccResetOTG_HS(); /* Enables IRQ vector.*/ - nvicEnableVector(STM32_OTG2_NUMBER, - CORTEX_PRIORITY_MASK(STM32_USB_OTG2_IRQ_PRIORITY)); + nvicEnableVector(STM32_OTG2_NUMBER, STM32_USB_OTG2_IRQ_PRIORITY); } #endif - /* Creates the data pump threads in a suspended state. Note, it is - created only once, the first time @p usbStart() is invoked.*/ usbp->txpending = 0; - if (usbp->thd_ptr == NULL) - usbp->thd_ptr = usbp->thd_wait = chThdCreateI(usbp->wa_pump, - sizeof usbp->wa_pump, - STM32_USB_OTG_THREAD_PRIO, - usb_lld_pump, - usbp); /* - Forced device mode. - USB turn-around time = TRDT_VALUE. @@ -1295,6 +1179,77 @@ void usb_lld_clear_in(USBDriver *usbp, usbep_t ep) { usbp->otg->ie[ep].DIEPCTL &= ~DIEPCTL_STALL; } +/** + * @brief USB data transfer loop. + * @details This function must be executed by a system thread in order to + * make the USB driver work. + * @note The data copy part of the driver is implemented in this thread + * in order to not perform heavy tasks withing interrupt handlers. + * + * @param[in] p pointer to the @p USBDriver object + * @return The function never returns. + * + * @special + */ +msg_t usb_lld_pump(void *p) { + USBDriver *usbp = (USBDriver *)p; + stm32_otg_t *otgp = usbp->otg; + +#if defined(__CHIBIOS_RT__) + chRegSetThreadName("usb_lld_pump"); +#endif + osalSysLock(); + while (true) { + usbep_t ep; + uint32_t epmask; + + /* Nothing to do, going to sleep.*/ + if ((usbp->state == USB_STOP) || + ((usbp->txpending == 0) && !(otgp->GINTSTS & GINTSTS_RXFLVL))) { + otgp->GINTMSK |= GINTMSK_RXFLVLM; + osalThreadSuspendS(&usbp->wait); + } + osalSysUnlock(); + + /* Checks if there are TXFIFOs to be filled.*/ + for (ep = 0; ep <= usbp->otgparams->num_endpoints; ep++) { + + /* Empties the RX FIFO.*/ + while (otgp->GINTSTS & GINTSTS_RXFLVL) { + otg_rxfifo_handler(usbp); + } + + epmask = (1 << ep); + if (usbp->txpending & epmask) { + bool done; + + osalSysLock(); + /* USB interrupts are globally *suspended* because the peripheral + does not allow any interference during the TX FIFO filling + operation. + Synopsys document: DesignWare Cores USB 2.0 Hi-Speed On-The-Go (OTG) + "The application has to finish writing one complete packet before + switching to a different channel/endpoint FIFO. Violating this + rule results in an error.".*/ + otgp->GAHBCFG &= ~GAHBCFG_GINTMSK; + usbp->txpending &= ~epmask; + osalSysUnlock(); + + done = otg_txfifo_handler(usbp, ep); + + osalSysLock(); + otgp->GAHBCFG |= GAHBCFG_GINTMSK; + if (!done) + otgp->DIEPEMPMSK |= epmask; + osalSysUnlock(); + } + } + osalSysLock(); + } + osalSysUnlock(); + return 0; +} + #endif /* HAL_USE_USB */ /** @} */ diff --git a/os/hal/ports/STM32/OTGv1/usb_lld.h b/os/hal/ports/STM32/OTGv1/usb_lld.h index 570309750..31e0094d7 100644 --- a/os/hal/ports/STM32/OTGv1/usb_lld.h +++ b/os/hal/ports/STM32/OTGv1/usb_lld.h @@ -198,7 +198,7 @@ typedef struct { /** * @brief Buffer mode, queue or linear. */ - bool_t txqueued; + bool txqueued; /** * @brief Requested transmit transfer size. */ @@ -218,7 +218,7 @@ typedef struct { /** * @brief Pointer to the output queue. */ - OutputQueue *txqueue; + output_queue_t *txqueue; } queue; } mode; } USBInEndpointState; @@ -230,7 +230,7 @@ typedef struct { /** * @brief Buffer mode, queue or linear. */ - bool_t rxqueued; + bool rxqueued; /** * @brief Requested receive transfer size. */ @@ -250,7 +250,7 @@ typedef struct { /** * @brief Pointer to the input queue. */ - InputQueue *rxqueue; + input_queue_t *rxqueue; } queue; } mode; } USBOutEndpointState; @@ -441,18 +441,10 @@ struct USBDriver { * @brief Mask of TXFIFOs to be filled by the pump thread. */ uint32_t txpending; - /** - * @brief Pointer to the thread. - */ - Thread *thd_ptr; /** * @brief Pointer to the thread when it is sleeping or @p NULL. */ - Thread *thd_wait; - /** - * @brief Working area for the dedicated data pump thread; - */ - WORKING_AREA(wa_pump, STM32_USB_OTG_THREAD_STACK_SIZE); + thread_reference_t wait; }; /*===========================================================================*/ @@ -523,6 +515,7 @@ extern "C" { void usb_lld_stall_in(USBDriver *usbp, usbep_t ep); void usb_lld_clear_out(USBDriver *usbp, usbep_t ep); void usb_lld_clear_in(USBDriver *usbp, usbep_t ep); + msg_t usb_lld_pump(void *p); #ifdef __cplusplus } #endif diff --git a/os/various/devices_lib/accel/lis302dl.c b/os/various/devices_lib/accel/lis302dl.c index 14e2a0ad1..77c2566ad 100644 --- a/os/various/devices_lib/accel/lis302dl.c +++ b/os/various/devices_lib/accel/lis302dl.c @@ -22,7 +22,6 @@ * @{ */ -#include "ch.h" #include "hal.h" #include "lis302dl.h" @@ -81,7 +80,7 @@ void lis302dlWriteRegister(SPIDriver *spip, uint8_t reg, uint8_t value) { default: /* Reserved register must not be written, according to the datasheet this could permanently damage the device.*/ - chDbgAssert(FALSE, "lis302dlWriteRegister(), #1", "reserved register"); + osalDbgAssert(FALSE, "reserved register"); case LIS302DL_WHO_AM_I: case LIS302DL_HP_FILTER_RESET: case LIS302DL_STATUS_REG: