From 960abcdabbde4ddf90ffad8d0dd97a171e7887ba Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Sat, 17 Jun 2023 10:21:21 +0000 Subject: [PATCH] Improved general drivers state machine handling. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@16291 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- os/xhal/codegen/hal_base_driver.xml | 71 +++++++++++++++++++++-------- os/xhal/codegen/hal_spi.xml | 3 +- os/xhal/include/hal.h | 16 +++++-- os/xhal/src/hal_base_driver.c | 43 ++++++++++++----- os/xhal/src/hal_spi.c | 5 ++ 5 files changed, 100 insertions(+), 38 deletions(-) diff --git a/os/xhal/codegen/hal_base_driver.xml b/os/xhal/codegen/hal_base_driver.xml index 074d9147a..e6f7cca72 100644 --- a/os/xhal/codegen/hal_base_driver.xml +++ b/os/xhal/codegen/hal_base_driver.xml @@ -116,7 +116,8 @@ drv_reg_remove(self); Low level driver stop. - + Driver configure.
@@ -126,7 +127,8 @@ drv_reg_remove(self); depending on the driver implementation and current state.]]> - New driver configuration. + New driver + configuration. @@ -138,8 +140,23 @@ drv_reg_remove(self); call the peripheral is physically initialized using a default configuration, subsequent calls are ignored.]]>
+ The operation status. Operation successful. + + If a required resources + cannot be allocated. + + If a required HW resource is + already in use. + + If an HW failure occurred. state != HAL_DRV_STATE_UNINIT) && - (self->state != HAL_DRV_STATE_STOPPING) && - (self->state != HAL_DRV_STATE_STARTING), - "invalid state"); - -if (self->state == HAL_DRV_STATE_STOP) { +switch (self->state) { +case HAL_DRV_STATE_UNINIT: + /* Falls through.*/ +case HAL_DRV_STATE_STARTING: + /* Falls through.*/ +case HAL_DRV_STATE_STOPPING: + msg = HAL_RET_INV_STATE; + break; +case HAL_DRV_STATE_STOP: /* Physically starting the peripheral.*/ msg = __drv_start(self); if (msg == HAL_RET_SUCCESS) { self->state = HAL_DRV_STATE_READY; + + /* LLD is supposed to set a default configuration.*/ + osalDbgAssert(self->config != NULL, "no configuration"); } else { self->state = HAL_DRV_STATE_STOP; - } + } +default: + /* Any other state ignored, driver already started.*/ } osalSysUnlock(); @@ -180,13 +205,13 @@ osalDbgCheck(self != NULL); osalSysLock(); -osalDbgAssert((self->state != HAL_DRV_STATE_UNINIT) && - (self->state != HAL_DRV_STATE_STARTING), - "invalid state"); +osalDbgAssert(self->state != HAL_DRV_STATE_UNINIT, "invalid state"); -if (self->state != HAL_DRV_STATE_STOP) { +if ((self->state != HAL_DRV_STATE_STOP) && + (self->state != HAL_DRV_STATE_STARTING)) { __drv_stop(self); - self->state = HAL_DRV_STATE_STOP; + self->state = HAL_DRV_STATE_STOP; + self->config = NULL; } osalSysUnlock();]]> @@ -204,7 +229,8 @@ return self->state;]]> Driver state set. - New driver state. + New driver + state. This function is only available when HAL registry is enabled. - Previously found driver. + Previously + found driver. A pointer to the next driver object. If there is no next driver. @@ -346,8 +373,10 @@ return oopGetOwner(hal_base_driver_c, regent, rep);]]> Driver name. - Pointer to store the error code or @p NULL. Note that in case of - driver not found the returned code is @p HAL_RET_SUCCESS. + Pointer to store the + error code or @p NULL. Note that in case of + driver not found the + returned code is @p HAL_RET_SUCCESS. A reference to the driver. If an error occurred. @@ -395,7 +424,8 @@ return drvp;]]> This function is only available when HAL registry is enabled. - Pointer to the @p hal_base_driver_c instance to be inserted. + Pointer to + the @p hal_base_driver_c instance to be inserted. regent;]]> Driver removal from the HAL registry. - Pointer to the @p hal_base_driver_c instance to be inserted. + Pointer to + the @p hal_base_driver_c instance to be inserted. config = config;]]> +self->config = config; +spi_lld_configure(self);]]> state != HAL_DRV_STATE_UNINIT) && - (self->state != HAL_DRV_STATE_STOPPING) && - (self->state != HAL_DRV_STATE_STARTING), - "invalid state"); - - if (self->state == HAL_DRV_STATE_STOP) { + switch (self->state) { + case HAL_DRV_STATE_UNINIT: + /* Falls through.*/ + case HAL_DRV_STATE_STARTING: + /* Falls through.*/ + case HAL_DRV_STATE_STOPPING: + msg = HAL_RET_INV_STATE; + break; + case HAL_DRV_STATE_STOP: /* Physically starting the peripheral.*/ msg = __drv_start(self); if (msg == HAL_RET_SUCCESS) { self->state = HAL_DRV_STATE_READY; + + /* LLD is supposed to set a default configuration.*/ + osalDbgAssert(self->config != NULL, "no configuration"); } else { self->state = HAL_DRV_STATE_STOP; - } + } + default: + /* Any other state ignored, driver already started.*/ } osalSysUnlock(); @@ -321,13 +340,13 @@ void drvStop(void *ip) { osalSysLock(); - osalDbgAssert((self->state != HAL_DRV_STATE_UNINIT) && - (self->state != HAL_DRV_STATE_STARTING), - "invalid state"); + osalDbgAssert(self->state != HAL_DRV_STATE_UNINIT, "invalid state"); - if (self->state != HAL_DRV_STATE_STOP) { + if ((self->state != HAL_DRV_STATE_STOP) && + (self->state != HAL_DRV_STATE_STARTING)) { __drv_stop(self); - self->state = HAL_DRV_STATE_STOP; + self->state = HAL_DRV_STATE_STOP; + self->config = NULL; } osalSysUnlock(); diff --git a/os/xhal/src/hal_spi.c b/os/xhal/src/hal_spi.c index 964d7818b..46b123549 100644 --- a/os/xhal/src/hal_spi.c +++ b/os/xhal/src/hal_spi.c @@ -134,6 +134,8 @@ void __spi_dispose_impl(void *ip) { */ msg_t __spi_start_impl(void *ip) { hal_spi_driver_c *self = (hal_spi_driver_c *)ip; + + return spi_lld_start(self); } /** @@ -146,6 +148,8 @@ msg_t __spi_start_impl(void *ip) { */ void __spi_stop_impl(void *ip) { hal_spi_driver_c *self = (hal_spi_driver_c *)ip; + + spi_lld_stop(self); } /** @@ -161,6 +165,7 @@ msg_t __spi_configure_impl(void *ip, const void *config) { hal_spi_driver_c *self = (hal_spi_driver_c *)ip; self->config = config; + spi_lld_configure(self); } /**