From 3aab763f7336f86e2bf810de8fb9954a15a80cc2 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Sun, 14 Aug 2022 12:14:29 +0000 Subject: [PATCH] More SIO work. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@15722 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- os/hal/include/hal_sio.h | 16 +++++++++ .../complex/buffered_sio/hal_buffered_sio.c | 35 ++++++++++++++++++- os/hal/src/hal_sio.c | 7 ++-- testhal/STM32/multi/SIO/main.c | 1 + .../multi/SIO/make/stm32g474re_nucleo64.make | 1 + .../multi/SIO/make/stm32l476vg_discovery.make | 1 + 6 files changed, 57 insertions(+), 4 deletions(-) diff --git a/os/hal/include/hal_sio.h b/os/hal/include/hal_sio.h index c45d98f12..3729f0908 100644 --- a/os/hal/include/hal_sio.h +++ b/os/hal/include/hal_sio.h @@ -109,12 +109,17 @@ */ #define SIO_EV_RXNOTEMPY (1U << SIO_EV_RXNOTEMPY_POS) #define SIO_EV_TXNOTFULL (1U << SIO_EV_TXNOTFULL_POS) +#define SIO_EV_ALL_DATA (SIO_EV_RXNOTEMPY | SIO_EV_TXNOTFULL) #define SIO_EV_TXDONE (1U << SIO_EV_TXDONE_POS) #define SIO_EV_PARITY_ERR (1U << SIO_EV_PARITY_ERR_POS) #define SIO_EV_FRAMING_ERR (1U << SIO_EV_FRAMING_ERR_POS) #define SIO_EV_OVERRUN_ERR (1U << SIO_EV_OVERRUN_ERR_POS) #define SIO_EV_NOISE_ERR (1U << SIO_EV_NOISE_ERR_POS) #define SIO_EV_BREAK (1U << SIO_EV_BREAK_POS) +#define SIO_EV_ALL_ERRORS (SIO_EV_PARITY_ERR | \ + SIO_EV_FRAMING_ERR | \ + SIO_EV_OVERRUN_ERR | \ + SIO_EV_NOISE_ERR) #define SIO_EV_RXIDLE (1U << SIO_EV_RXIDLE_POS) /** @} */ @@ -221,6 +226,9 @@ typedef enum { struct hal_sio_config { /* End of the mandatory fields.*/ sio_lld_config_fields; +#if defined(SIO_CONFIG_EXT_FIELS) + SIO_CONFIG_EXT_FIELDS +#endif }; /** @@ -266,6 +274,11 @@ struct hal_sio_driver { * @brief Current configuration data. */ const SIOOperation *operation; + /** + * @brief User argument to the operation. + * @note Can be retrieved through the @p siop argument of the callback. + */ + void *arg; #if (SIO_USE_SYNCHRONIZATION == TRUE) || defined(__DOXYGEN__) /** * @brief Synchronization point for RX. @@ -300,6 +313,9 @@ struct hal_sio_operation { * @note Can be @p NULL. */ siocb_t cb; +#if defined(SIO_OPERATION_EXT_FIELS) + SIO_OPERATION_EXT_FIELS +#endif }; /*===========================================================================*/ diff --git a/os/hal/lib/complex/buffered_sio/hal_buffered_sio.c b/os/hal/lib/complex/buffered_sio/hal_buffered_sio.c index 43c25baff..c89dc563c 100644 --- a/os/hal/lib/complex/buffered_sio/hal_buffered_sio.c +++ b/os/hal/lib/complex/buffered_sio/hal_buffered_sio.c @@ -50,8 +50,40 @@ static const SIOOperation bs_default_operation = { /*===========================================================================*/ static void bs_default_cb(SIODriver *siop) { + BufferedSIODriver *bsdp = (BufferedSIODriver *)siop->arg; + sioevents_t events; - (void)siop; + osalSysLockFromISR(); + + /* Posting the non-data SIO events as channel event flags, the masks are + made to match.*/ + events = sioGetAndClearEventsI(siop); + chnAddFlagsI(bsdp, (eventflags_t)(events & ~SIO_EV_ALL_DATA)); + + /* RX FIFO event.*/ + if ((events & SIO_EV_RXNOTEMPY) != (sioevents_t)0) { + /* RX FIFO needs to be emptied or SIO will not generate more RX FIFO + events.*/ + while (!sioIsRXEmptyX(siop)) { + bsIncomingDataI((BufferedSerial *)bsdp, sioGetX(siop)); + } + } + + /* TX FIFO event.*/ + if ((events & SIO_EV_TXNOTFULL) != (sioevents_t)0) { + while (!sioIsTXFullX(siop)) { + msg_t msg; + + msg = oqGetI(&bsdp->oqueue); + if (msg < MSG_OK) { + chnAddFlagsI((BufferedSerial *)bsdp, CHN_OUTPUT_EMPTY); + break; + } + sioPutX(siop, (uint_fast16_t)msg); + } + } + + osalSysUnlockFromISR(); } /* @@ -138,6 +170,7 @@ void bsdObjectInit(BufferedSIODriver *bsdp, SIODriver *siop, ib, ibsize, NULL, NULL, ob, obsize, NULL, NULL); bsdp->siop = siop; + siop->arg = (void *)bsdp; } /** diff --git a/os/hal/src/hal_sio.c b/os/hal/src/hal_sio.c index 091736463..8cb1dbaec 100644 --- a/os/hal/src/hal_sio.c +++ b/os/hal/src/hal_sio.c @@ -223,15 +223,16 @@ void sioObjectInit(SIODriver *siop) { #if SIO_USE_STREAMS_INTERFACE == TRUE siop->vmt = &vmt; #endif + siop->state = SIO_STOP; + siop->config = NULL; + siop->enabled = (sioflags_t)0; + siop->arg = NULL; #if SIO_USE_SYNCHRONIZATION == TRUE siop->sync_rx = NULL; siop->sync_rxidle = NULL; siop->sync_tx = NULL; siop->sync_txend = NULL; #endif - siop->state = SIO_STOP; - siop->config = NULL; - siop->enabled = (sioflags_t)0; /* Optional, user-defined initializer.*/ #if defined(SIO_DRIVER_EXT_INIT_HOOK) diff --git a/testhal/STM32/multi/SIO/main.c b/testhal/STM32/multi/SIO/main.c index 0191d3055..b1db61cac 100644 --- a/testhal/STM32/multi/SIO/main.c +++ b/testhal/STM32/multi/SIO/main.c @@ -16,6 +16,7 @@ #include "ch.h" #include "hal.h" +#include "hal_buffered_sio.h" #include "portab.h" diff --git a/testhal/STM32/multi/SIO/make/stm32g474re_nucleo64.make b/testhal/STM32/multi/SIO/make/stm32g474re_nucleo64.make index ec462b243..79864dc76 100644 --- a/testhal/STM32/multi/SIO/make/stm32g474re_nucleo64.make +++ b/testhal/STM32/multi/SIO/make/stm32g474re_nucleo64.make @@ -103,6 +103,7 @@ include $(CHIBIOS)/os/hal/hal.mk include $(CHIBIOS)/os/hal/ports/STM32/STM32G4xx/platform.mk include $(CHIBIOS)/os/hal/boards/ST_NUCLEO64_G474RE/board.mk include $(CHIBIOS)/os/hal/osal/rt-nil/osal.mk +include $(CHIBIOS)/os/hal/lib/complex/buffered_sio/hal_buffered_sio.mk # RTOS files (optional). include $(CHIBIOS)/os/rt/rt.mk include $(CHIBIOS)/os/common/ports/ARMv7-M/compilers/GCC/mk/port.mk diff --git a/testhal/STM32/multi/SIO/make/stm32l476vg_discovery.make b/testhal/STM32/multi/SIO/make/stm32l476vg_discovery.make index 45c6c39d1..7797d2b86 100644 --- a/testhal/STM32/multi/SIO/make/stm32l476vg_discovery.make +++ b/testhal/STM32/multi/SIO/make/stm32l476vg_discovery.make @@ -103,6 +103,7 @@ include $(CHIBIOS)/os/hal/hal.mk include $(CHIBIOS)/os/hal/ports/STM32/STM32L4xx/platform.mk include $(CHIBIOS)/os/hal/boards/ST_STM32L476_DISCOVERY/board.mk include $(CHIBIOS)/os/hal/osal/rt-nil/osal.mk +include $(CHIBIOS)/os/hal/lib/complex/buffered_sio/hal_buffered_sio.mk # RTOS files (optional). include $(CHIBIOS)/os/rt/rt.mk include $(CHIBIOS)/os/common/ports/ARMv7-M/compilers/GCC/mk/port.mk