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
This commit is contained in:
Giovanni Di Sirio 2019-10-05 07:04:14 +00:00
parent 3ea7ec6586
commit 375722180b
5 changed files with 62 additions and 13 deletions

View File

@ -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

View File

@ -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 */

View File

@ -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.

View File

@ -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. */
};

View File

@ -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. */