From 375722180bb379a463f7b27f594c11f1244dbfd4 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Sat, 5 Oct 2019 07:04:14 +0000 Subject: [PATCH] Added error handling to WSPI driver, now LLDs can report error conditions to upper layers. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@13061 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- os/hal/include/hal_wspi.h | 44 ++++++++++++++++--- os/hal/src/hal_wspi.c | 27 +++++++++--- readme.txt | 2 + .../WSPI-MFS/cfg/stm32l476_discovery/portab.c | 1 + .../WSPI-MFS/cfg/stm32l4r9_discovery/portab.c | 1 + 5 files changed, 62 insertions(+), 13 deletions(-) diff --git a/os/hal/include/hal_wspi.h b/os/hal/include/hal_wspi.h index 4f02eb3b5..5404fdad3 100644 --- a/os/hal/include/hal_wspi.h +++ b/os/hal/include/hal_wspi.h @@ -140,6 +140,10 @@ struct hal_wspi_config { * @brief Operation complete callback or @p NULL. */ wspicallback_t end_cb; + /** + * @brief Operation error callback or @p NULL. + */ + wspicallback_t error_cb; /* End of the mandatory fields.*/ wspi_lld_config_fields; }; @@ -356,13 +360,13 @@ struct hal_wspi_driver { * * @notapi */ -#define _wspi_wakeup_isr(wspip) { \ +#define _wspi_wakeup_isr(wspip, msg) { \ osalSysLockFromISR(); \ - osalThreadResumeI(&(wspip)->thread, MSG_OK); \ + osalThreadResumeI(&(wspip)->thread, msg); \ osalSysUnlockFromISR(); \ } #else /* !WSPI_USE_WAIT */ -#define _wspi_wakeup_isr(wspip) +#define _wspi_wakeup_isr(wspip, msg) #endif /* !WSPI_USE_WAIT */ /** @@ -388,7 +392,33 @@ struct hal_wspi_driver { } \ else \ (wspip)->state = WSPI_READY; \ - _wspi_wakeup_isr(wspip); \ + _wspi_wakeup_isr(wspip, MSG_OK); \ +} + +/** + * @brief Common error ISR code. + * @details This code handles the portable part of the ISR code: + * - Callback invocation. + * - Waiting thread wakeup, if any. + * - Driver state transitions. + * . + * @note This macro is meant to be used in the low level drivers + * implementation only. + * + * @param[in] wspip pointer to the @p WSPIDriver object + * + * @notapi + */ +#define _wspi_error_code(wspip) { \ + if ((wspip)->config->error_cb) { \ + (wspip)->state = WSPI_COMPLETE; \ + (wspip)->config->error_cb(wspip); \ + if ((wspip)->state == WSPI_COMPLETE) \ + (wspip)->state = WSPI_READY; \ + } \ + else \ + (wspip)->state = WSPI_READY; \ + _wspi_wakeup_isr(wspip, MSG_RESET); \ } /** @} */ @@ -409,10 +439,10 @@ extern "C" { void wspiStartReceive(WSPIDriver *wspip, const wspi_command_t *cmdp, size_t n, uint8_t *rxbuf); #if WSPI_USE_WAIT == TRUE - void wspiCommand(WSPIDriver *wspip, const wspi_command_t *cmdp); - void wspiSend(WSPIDriver *wspip, const wspi_command_t *cmdp, + bool wspiCommand(WSPIDriver *wspip, const wspi_command_t *cmdp); + bool wspiSend(WSPIDriver *wspip, const wspi_command_t *cmdp, size_t n, const uint8_t *txbuf); - void wspiReceive(WSPIDriver *wspip, const wspi_command_t *cmdp, + bool wspiReceive(WSPIDriver *wspip, const wspi_command_t *cmdp, size_t n, uint8_t *rxbuf); #endif #if WSPI_SUPPORTS_MEMMAP == TRUE diff --git a/os/hal/src/hal_wspi.c b/os/hal/src/hal_wspi.c index 10a0aec24..bde556d23 100644 --- a/os/hal/src/hal_wspi.c +++ b/os/hal/src/hal_wspi.c @@ -216,7 +216,8 @@ void wspiStartReceive(WSPIDriver *wspip, const wspi_command_t *cmdp, * * @api */ -void wspiCommand(WSPIDriver *wspip, const wspi_command_t *cmdp) { +bool wspiCommand(WSPIDriver *wspip, const wspi_command_t *cmdp) { + msg_t msg; osalDbgCheck((wspip != NULL) && (cmdp != NULL)); osalDbgCheck((cmdp->cfg & WSPI_CFG_DATA_MODE_MASK) == WSPI_CFG_DATA_MODE_NONE); @@ -227,9 +228,11 @@ void wspiCommand(WSPIDriver *wspip, const wspi_command_t *cmdp) { osalDbgAssert(wspip->config->end_cb == NULL, "has callback"); wspiStartCommandI(wspip, cmdp); - (void) osalThreadSuspendS(&wspip->thread); + msg = osalThreadSuspendS(&wspip->thread); osalSysUnlock(); + + return (bool)(msg != MSG_OK); } /** @@ -243,11 +246,15 @@ void wspiCommand(WSPIDriver *wspip, const wspi_command_t *cmdp) { * @param[in] cmdp pointer to the command descriptor * @param[in] n number of bytes to send * @param[in] txbuf the pointer to the transmit buffer + * @return The operation status. + * @retval false if the operation succeeded. + * @retval true if the operation failed because HW issues. * * @api */ -void wspiSend(WSPIDriver *wspip, const wspi_command_t *cmdp, +bool wspiSend(WSPIDriver *wspip, const wspi_command_t *cmdp, size_t n, const uint8_t *txbuf) { + msg_t msg; osalDbgCheck((wspip != NULL) && (cmdp != NULL)); osalDbgCheck((n > 0U) && (txbuf != NULL)); @@ -259,9 +266,11 @@ void wspiSend(WSPIDriver *wspip, const wspi_command_t *cmdp, osalDbgAssert(wspip->config->end_cb == NULL, "has callback"); wspiStartSendI(wspip, cmdp, n, txbuf); - (void) osalThreadSuspendS(&wspip->thread); + msg = osalThreadSuspendS(&wspip->thread); osalSysUnlock(); + + return (bool)(msg != MSG_OK); } /** @@ -275,11 +284,15 @@ void wspiSend(WSPIDriver *wspip, const wspi_command_t *cmdp, * @param[in] cmdp pointer to the command descriptor * @param[in] n number of bytes to send * @param[out] rxbuf the pointer to the receive buffer + * @return The operation status. + * @retval false if the operation succeeded. + * @retval true if the operation failed because HW issues. * * @api */ -void wspiReceive(WSPIDriver *wspip, const wspi_command_t *cmdp, +bool wspiReceive(WSPIDriver *wspip, const wspi_command_t *cmdp, size_t n, uint8_t *rxbuf) { + msg_t msg; osalDbgCheck((wspip != NULL) && (cmdp != NULL)); osalDbgCheck((n > 0U) && (rxbuf != NULL)); @@ -291,9 +304,11 @@ void wspiReceive(WSPIDriver *wspip, const wspi_command_t *cmdp, osalDbgAssert(wspip->config->end_cb == NULL, "has callback"); wspiStartReceiveI(wspip, cmdp, n, rxbuf); - (void) osalThreadSuspendS(&wspip->thread); + msg = osalThreadSuspendS(&wspip->thread); osalSysUnlock(); + + return (bool)(msg != MSG_OK); } #endif /* WSPI_USE_WAIT == TRUE */ diff --git a/readme.txt b/readme.txt index 472f7cd36..32bd80479 100644 --- a/readme.txt +++ b/readme.txt @@ -74,6 +74,8 @@ ***************************************************************************** *** Next *** +- NEW: Added error handling to WSPI driver, now LLDs can report error + conditions to upper layers. - NEW: Added mcuconf.h generator for STM32G4x4. - HAL: STM32 DMAv1 driver improvements and generalization, added support for 8 channels. diff --git a/testhal/STM32/multi/WSPI-MFS/cfg/stm32l476_discovery/portab.c b/testhal/STM32/multi/WSPI-MFS/cfg/stm32l476_discovery/portab.c index 893711661..329c202dd 100644 --- a/testhal/STM32/multi/WSPI-MFS/cfg/stm32l476_discovery/portab.c +++ b/testhal/STM32/multi/WSPI-MFS/cfg/stm32l476_discovery/portab.c @@ -36,6 +36,7 @@ const WSPIConfig WSPIcfg1 = { .end_cb = NULL, + .error_cb = NULL, .dcr = STM32_DCR_FSIZE(24U) | /* 16MB device. */ STM32_DCR_CSHT(1U) /* NCS 2 cycles delay. */ }; diff --git a/testhal/STM32/multi/WSPI-MFS/cfg/stm32l4r9_discovery/portab.c b/testhal/STM32/multi/WSPI-MFS/cfg/stm32l4r9_discovery/portab.c index bf15f000d..8df36fd43 100644 --- a/testhal/STM32/multi/WSPI-MFS/cfg/stm32l4r9_discovery/portab.c +++ b/testhal/STM32/multi/WSPI-MFS/cfg/stm32l4r9_discovery/portab.c @@ -36,6 +36,7 @@ const WSPIConfig WSPIcfg1 = { .end_cb = NULL, + .error_cb = NULL, .dcr1 = STM32_DCR1_MTYP(1U) | /* Macronix mode. */ STM32_DCR1_DEVSIZE(26U) | /* 64MB device. */ STM32_DCR1_CSHT(1U), /* NCS 2 cycles delay. */