From 4b23f3b361221f5c57cef31bbf80c70372ab4d35 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Fri, 28 Sep 2018 08:20:40 +0000 Subject: New SIO HAL driver model. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@12300 110e8d01-0319-4d1e-a829-52ad28d1bb01 --- os/hal/dox/sio.dox | 58 +++++++++++++ os/hal/hal.mk | 4 + os/hal/include/hal.h | 9 +- os/hal/include/hal_sio.h | 49 +++++++++++ os/hal/src/hal_sio.c | 126 +++++++++++++++++++++++++++ os/hal/templates/hal_sio_lld.c | 187 +++++++++++++++++++++++++++++++++++++++++ os/hal/templates/hal_sio_lld.h | 10 ++- os/hal/templates/halconf.h | 7 ++ os/hal/templates/platform.mk | 4 + 9 files changed, 450 insertions(+), 4 deletions(-) create mode 100644 os/hal/dox/sio.dox create mode 100644 os/hal/src/hal_sio.c create mode 100644 os/hal/templates/hal_sio_lld.c diff --git a/os/hal/dox/sio.dox b/os/hal/dox/sio.dox new file mode 100644 index 000000000..57ff2bae5 --- /dev/null +++ b/os/hal/dox/sio.dox @@ -0,0 +1,58 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @defgroup SIO SIO Driver + * @brief Generic SIO Driver. + * @details This driver abstracts a generic serial communication channel, + * usually an UART, this driver is similar to Serial and UART drivers + * but follows a different concept: + * - Very close to HW. + * - No buffering done in SW, the driver relies on the peripheral + * internal FIFO, if any. + * - Asynchronous, the API is always non blocking. + * - Callbacks capable, operations completion and other events are + * notified using callbacks. + * - Very short code paths, especially in ISRs. + * . + * @pre In order to use the SIO driver the @p HAL_USE_SIO option + * must be enabled in @p halconf.h. + * + * @section sio_1 Driver State Machine + * The driver implements a state machine internally, not all the driver + * functionalities can be used in any moment, any transition not explicitly + * shown in the following diagram has to be considered an error and shall + * be captured by an assertion (if enabled). + * @dot + digraph example { + rankdir="LR"; + node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true", width="0.9", height="0.9"]; + edge [fontname=Helvetica, fontsize=8]; + + uninit [label="SIO_UNINIT", style="bold"]; + stop [label="SIO_STOP\nLow Power"]; + ready [label="SIO_READY\nClock Enabled"]; + + uninit -> stop [label="\nsioInit()"]; + stop -> ready [label="\nsioStart()"]; + ready -> ready [label="\nsioStart()"]; + ready -> stop [label="\nsioStop()"]; + stop -> stop [label="\nsioStop()"]; + } + * @enddot + * + * @ingroup HAL_NORMAL_DRIVERS + */ diff --git a/os/hal/hal.mk b/os/hal/hal.mk index a8539e259..bd3ec0132 100644 --- a/os/hal/hal.mk +++ b/os/hal/hal.mk @@ -68,6 +68,9 @@ endif ifneq ($(findstring HAL_USE_SERIAL_USB TRUE,$(HALCONF)),) HALSRC += $(CHIBIOS)/os/hal/src/hal_serial_usb.c endif +ifneq ($(findstring HAL_USE_SIO TRUE,$(HALCONF)),) +HALSRC += $(CHIBIOS)/os/hal/src/hal_sio.c +endif ifneq ($(findstring HAL_USE_SPI TRUE,$(HALCONF)),) HALSRC += $(CHIBIOS)/os/hal/src/hal_spi.c endif @@ -109,6 +112,7 @@ HALSRC = $(CHIBIOS)/os/hal/src/hal.c \ $(CHIBIOS)/os/hal/src/hal_sdc.c \ $(CHIBIOS)/os/hal/src/hal_serial.c \ $(CHIBIOS)/os/hal/src/hal_serial_usb.c \ + $(CHIBIOS)/os/hal/src/hal_sio.c \ $(CHIBIOS)/os/hal/src/hal_spi.c \ $(CHIBIOS)/os/hal/src/hal_st.c \ $(CHIBIOS)/os/hal/src/hal_trng.c \ diff --git a/os/hal/include/hal.h b/os/hal/include/hal.h index 4b2ba597c..26299602b 100644 --- a/os/hal/include/hal.h +++ b/os/hal/include/hal.h @@ -94,6 +94,10 @@ #define HAL_USE_SDC FALSE #endif +#if !defined(HAL_USE_SIO) +#define HAL_USE_SPI FALSE +#endif + #if !defined(HAL_USE_SPI) #define HAL_USE_SPI FALSE #endif @@ -150,6 +154,7 @@ #include "hal_rtc.h" #include "hal_serial.h" #include "hal_sdc.h" +#include "hal_sio.h" #include "hal_spi.h" #include "hal_trng.h" #include "hal_uart.h" @@ -197,12 +202,12 @@ /** * @brief HAL version string. */ -#define HAL_VERSION "6.0.0" +#define HAL_VERSION "7.0.0" /** * @brief HAL version major number. */ -#define CH_HAL_MAJOR 6 +#define CH_HAL_MAJOR 7 /** * @brief HAL version minor number. diff --git a/os/hal/include/hal_sio.h b/os/hal/include/hal_sio.h index 4d31940fd..6aedba68a 100644 --- a/os/hal/include/hal_sio.h +++ b/os/hal/include/hal_sio.h @@ -77,6 +77,54 @@ typedef enum { /* Driver macros. */ /*===========================================================================*/ +/** + * @brief Reads data from the RX FIFO. + * @details This function is non-blocking, data is read if present and the + * effective amount is returned. + * @note This function can be called from any context but it is meant to + * be called from the @p rxne_cb callback handler. + * + * @param[in] siop pointer to the @p SIODriver object + * @param[in] buffer buffer for the received data + * @param[in] size maximum number of bytes to read + * @return The number of received bytes. + * + * @xclass + */ +#define sioReadX(siop, buffer, size) sio_lld_read(siop, buffer, size) + +/** + * @brief Writes data into the TX FIFO. + * @details This function is non-blocking, data is written if there is space + * in the FIFO and the effective amount is returned. + * @note This function can be called from any context but it is meant to + * be called from the @p txnf_cb callback handler. + * + * @param[in] siop pointer to the @p SIODriver object + * @param[out] buffer buffer containing the data to be transmitted + * @param[in] size maximum number of bytes to read + * @return The number of transmitted bytes. + * + * @xclass + */ +#define sioWriteX(siop, buffer, size) sio_lld_write(siop, buffer, size) + +/** + * @brief Control operation on a serial port. + * + * @param[in] siop pointer to the @p SIODriver object + * @param[in] operation control operation code + * @param[in,out] arg operation argument + * + * @return The control operation status. + * @retval MSG_OK in case of success. + * @retval MSG_TIMEOUT in case of operation timeout. + * @retval MSG_RESET in case of operation reset. + * + * @xclass + */ +#define sioControlX(siop, operation, arg) sio_lld_control(siop, operation, arg) + /*===========================================================================*/ /* External declarations. */ /*===========================================================================*/ @@ -88,6 +136,7 @@ extern "C" { void sioObjectInit(SIODriver *siop); void sioStart(SIODriver *siop, const SIOConfig *config); void sioStop(SIODriver *siop); + msg_t sioControl(SIODriver *siop, unsigned int operation, void *arg); #ifdef __cplusplus } #endif diff --git a/os/hal/src/hal_sio.c b/os/hal/src/hal_sio.c new file mode 100644 index 000000000..47901e292 --- /dev/null +++ b/os/hal/src/hal_sio.c @@ -0,0 +1,126 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file hal_sio.c + * @brief SIO Driver code. + * + * @addtogroup SIO + * @{ + */ + +#include "hal.h" + +#if (HAL_USE_SIO == TRUE) || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief SIO Driver initialization. + * @note This function is implicitly invoked by @p halInit(), there is + * no need to explicitly initialize the driver. + * + * @init + */ +void sioInit(void) { + + sio_lld_init(); +} + +/** + * @brief Initializes the standard part of a @p SIODriver structure. + * + * @param[out] siop pointer to the @p SIODriver object + * + * @init + */ +void sioObjectInit(SIODriver *siop) { + + siop->state = SIO_STOP; + siop->config = NULL; + + /* Optional, user-defined initializer.*/ +#if defined(SIO_DRIVER_EXT_INIT_HOOK) + SIO_DRIVER_EXT_INIT_HOOK(siop); +#endif +} + +/** + * @brief Configures and activates the SIO peripheral. + * + * @param[in] siop pointer to the @p SIODriver object + * @param[in] config pointer to the @p SIOConfig object + * + * @api + */ +void sioStart(SIODriver *siop, const SIOConfig *config) { + + osalDbgCheck((siop != NULL) && (config != NULL)); + + osalSysLock(); + osalDbgAssert((siop->state == SIO_STOP) || (siop->state == SIO_READY), + "invalid state"); + + siop->config = config; + sio_lld_start(siop); + siop->state = SIO_READY; + osalSysUnlock(); +} + +/** + * @brief Deactivates the SIO peripheral. + * + * @param[in] siop pointer to the @p SIODriver object + * + * @api + */ +void sioStop(SIODriver *siop) { + + osalDbgCheck(siop != NULL); + + osalSysLock(); + + osalDbgAssert((siop->state == SIO_STOP) || (siop->state == SIO_READY), + "invalid state"); + + sio_lld_stop(siop); + siop->config = NULL; + siop->state = SIO_STOP; + + osalSysUnlock(); +} + +#endif /* HAL_USE_SIO == TRUE */ + +/** @} */ diff --git a/os/hal/templates/hal_sio_lld.c b/os/hal/templates/hal_sio_lld.c new file mode 100644 index 000000000..ea425709c --- /dev/null +++ b/os/hal/templates/hal_sio_lld.c @@ -0,0 +1,187 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file hal_sio_lld.c + * @brief PLATFORM SIO subsystem low level driver source. + * + * @addtogroup SIO + * @{ + */ + +#include "hal.h" + +#if (HAL_USE_SIO == TRUE) || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** + * @brief SIO1 driver identifier. + */ +#if (PLATFORM_SIO_USE_SIO1 == TRUE) || defined(__DOXYGEN__) +SIODriver SIOD1; +#endif + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Low level SIO driver initialization. + * + * @notapi + */ +void sio_lld_init(void) { + +#if PLATFORM_SIO_USE_SIO1 == TRUE + /* Driver initialization.*/ + sioObjectInit(&SIOD1); +#endif +} + +/** + * @brief Configures and activates the SIO peripheral. + * + * @param[in] siop pointer to the @p SIODriver object + * + * @notapi + */ +void sio_lld_start(SIODriver *siop) { + + if (siop->state == SIO_STOP) { + /* Enables the peripheral.*/ +#if PLATFORM_SIO_USE_SIO1 == TRUE + if (&SIOD1 == siop) { + + } +#endif + } + /* Configures the peripheral.*/ + +} + +/** + * @brief Deactivates the SIO peripheral. + * + * @param[in] siop pointer to the @p SIODriver object + * + * @notapi + */ +void sio_lld_stop(SIODriver *siop) { + + if (siop->state == SIO_READY) { + /* Resets the peripheral.*/ + + /* Disables the peripheral.*/ +#if PLATFORM_SIO_USE_SIO1 == TRUE + if (&SIOD1 == siop) { + + } +#endif + } +} + + +/** + * @brief Reads data from the RX FIFO. + * @details This function is non-blocking, data is read if present and the + * effective amount is returned. + * @note This function can be called from any context but it is meant to + * be called from the @p rxne_cb callback handler. + * + * @param[in] siop pointer to the @p SIODriver object + * @param[in] buffer buffer for the received data + * @param[in] size maximum number of bytes to read + * @return The number of received bytes. + * + * @notapi + */ +size_t sio_lld_read(SIODriver *siop, uint8_t *buffer, size_t size) { + + (void)siop; + (void)buffer; + (void)size; + + return (size_t)0; +} + +/** + * @brief Writes data into the TX FIFO. + * @details This function is non-blocking, data is written if there is space + * in the FIFO and the effective amount is returned. + * @note This function can be called from any context but it is meant to + * be called from the @p rxne_cb callback handler. + * + * @param[in] siop pointer to the @p SIODriver object + * @param[out] buffer buffer containing the data to be transmitted + * @param[in] size maximum number of bytes to read + * @return The number of transmitted bytes. + * + * @notapi + */ +size_t sio_lld_write(SIODriver *siop, const uint8_t *buffer, size_t size) { + + (void)siop; + (void)buffer; + (void)size; + + return (size_t)0; +} + +/** + * @brief Control operation on a serial port. + * + * @param[in] siop pointer to the @p SIODriver object + * @param[in] operation control operation code + * @param[in,out] arg operation argument + * + * @return The control operation status. + * @retval MSG_OK in case of success. + * @retval MSG_TIMEOUT in case of operation timeout. + * @retval MSG_RESET in case of operation reset. + * + * @notapi + */ +msg_t sio_lld_control(SIODriver *siop, unsigned int operation, void *arg) { + + (void)siop; + (void)operation; + (void)arg; + + return MSG_OK; +} + +#endif /* HAL_USE_SIO == TRUE */ + +/** @} */ diff --git a/os/hal/templates/hal_sio_lld.h b/os/hal/templates/hal_sio_lld.h index ad265dabd..45aa3f2e8 100644 --- a/os/hal/templates/hal_sio_lld.h +++ b/os/hal/templates/hal_sio_lld.h @@ -57,6 +57,11 @@ /* Driver data structures and types. */ /*===========================================================================*/ +/** + * @brief SIO driver condition flags type. + */ +typedef uint32_t sioflags_t; + /** * @brief Type of structure representing an SIO driver. */ @@ -141,8 +146,9 @@ extern "C" { void sio_lld_init(void); void sio_lld_start(SIODriver *siop); void sio_lld_stop(SIODriver *siop); - void sio_lld_read(SIODriver *siop, uint8_t *buffer, size_t size); - void sio_lld_write(SIODriver *siop, const uint8_t *buffer, size_t size); + size_t sio_lld_read(SIODriver *siop, uint8_t *buffer, size_t size); + size_t sio_lld_write(SIODriver *siop, const uint8_t *buffer, size_t size); + msg_t sio_lld_control(SIODriver *siop, unsigned int operation, void *arg); #ifdef __cplusplus } #endif diff --git a/os/hal/templates/halconf.h b/os/hal/templates/halconf.h index 26d8463d4..d78e812a7 100644 --- a/os/hal/templates/halconf.h +++ b/os/hal/templates/halconf.h @@ -159,6 +159,13 @@ #define HAL_USE_SERIAL_USB TRUE #endif +/** + * @brief Enables the SIO subsystem. + */ +#if !defined(HAL_USE_SIO) || defined(__DOXYGEN__) +#define HAL_USE_SIO TRUE +#endif + /** * @brief Enables the SPI subsystem. */ diff --git a/os/hal/templates/platform.mk b/os/hal/templates/platform.mk index 533c654c3..535e83b20 100644 --- a/os/hal/templates/platform.mk +++ b/os/hal/templates/platform.mk @@ -58,6 +58,9 @@ endif ifneq ($(findstring HAL_USE_SERIAL TRUE,$(HALCONF)),) PLATFORMSRC += ${CHIBIOS}/os/hal/templates/hal_serial_lld.c endif +ifneq ($(findstring HAL_USE_SIO TRUE,$(HALCONF)),) +PLATFORMSRC += ${CHIBIOS}/os/hal/templates/hal_sio_lld.c +endif ifneq ($(findstring HAL_USE_SPI TRUE,$(HALCONF)),) PLATFORMSRC += ${CHIBIOS}/os/hal/templates/hal_spi_lld.c endif @@ -91,6 +94,7 @@ PLATFORMSRC = ${CHIBIOS}/os/hal/templates/hal_lld.c \ ${CHIBIOS}/os/hal/templates/hal_rtc_lld.c \ ${CHIBIOS}/os/hal/templates/hal_sdc_lld.c \ ${CHIBIOS}/os/hal/templates/hal_serial_lld.c \ + ${CHIBIOS}/os/hal/templates/hal_sio_lld.c \ ${CHIBIOS}/os/hal/templates/hal_spi_lld.c \ ${CHIBIOS}/os/hal/templates/hal_st_lld.c \ ${CHIBIOS}/os/hal/templates/hal_trng_lld.c \ -- cgit v1.2.3