From f83396ec387f0921f70ddd4efb527106753e2000 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Sun, 17 Oct 2021 10:30:42 +0000 Subject: [PATCH] More SPI v2 code. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@14916 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- os/hal/include/hal.h | 2 +- os/hal/include/hal_spi_v2.h | 58 ++++++++++--------- os/hal/ports/STM32/LLD/SPIv2/hal_spi_v2_lld.c | 44 +++++++++----- 3 files changed, 59 insertions(+), 45 deletions(-) diff --git a/os/hal/include/hal.h b/os/hal/include/hal.h index 774f2d939..11aa59b53 100644 --- a/os/hal/include/hal.h +++ b/os/hal/include/hal.h @@ -111,7 +111,7 @@ #define HAL_RET_HW_BUSY (msg_t)-18 /** * @brief Peripheral failure. - * @details Peripheral failed during initialization, for example HW timeouts. + * @details Peripheral failed, for example HW timeouts. */ #define HAL_RET_HW_FAILURE (msg_t)-19 /** @} */ diff --git a/os/hal/include/hal_spi_v2.h b/os/hal/include/hal_spi_v2.h index bfd2278ad..b53090314 100644 --- a/os/hal/include/hal_spi_v2.h +++ b/os/hal/include/hal_spi_v2.h @@ -44,6 +44,14 @@ #define SPI_SELECT_MODE_LLD 4 /** @brief LLD-defined mode.*/ /** @} */ +/** + * @name SPI-specific messages + * @{ + */ +#define MSG_SPI_BUFFER_FULL MSG_OK +#define MSG_SPI_BUFFER_HALF (msg_t)-3 +/** @} */ + /*===========================================================================*/ /* Driver pre-compile time settings. */ /*===========================================================================*/ @@ -365,7 +373,7 @@ do { \ * * @notapi */ -#define __spi_wakeup_isr(spip) { \ +#define __spi_wakeup_isr(spip, msg) { \ osalSysLockFromISR(); \ osalThreadResumeI(&(spip)->sync_transfer, MSG_OK); \ osalSysUnlockFromISR(); \ @@ -374,32 +382,6 @@ do { \ #define __spi_wakeup_isr(spip) #endif /* !SPI_USE_SYNCHRONIZATION */ -/** - * @brief Common ISR code when circular mode is not supported. - * @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] spip pointer to the @p SPIDriver object - * - * @notapi - */ -#define __spi_isr_code(spip) { \ - if ((spip)->config->end_cb) { \ - (spip)->state = SPI_COMPLETE; \ - (spip)->config->end_cb(spip); \ - if ((spip)->state == SPI_COMPLETE) \ - (spip)->state = SPI_READY; \ - } \ - else \ - (spip)->state = SPI_READY; \ - __spi_wakeup_isr(spip); \ -} - /** * @brief Half buffer filled ISR code in circular mode. * @details This code handles the portable part of the ISR code: @@ -416,6 +398,7 @@ do { \ if ((spip)->config->end_cb) { \ (spip)->config->end_cb(spip); \ } \ + __spi_wakeup_isr(spip, MSG_SPI_BUFFER_HALF); \ } /** @@ -435,9 +418,28 @@ do { \ if ((spip)->config->end_cb) { \ (spip)->state = SPI_COMPLETE; \ (spip)->config->end_cb(spip); \ - if ((spip)->state == SPI_COMPLETE) \ + if ((spip)->state == SPI_COMPLETE) { \ (spip)->state = SPI_ACTIVE; \ + } \ } \ + __spi_wakeup_isr(spip, MSG_SPI_BUFFER_FULL); \ +} + +/** + * @brief ISR error reporting code.. + * @note This macro is meant to be used in the low level drivers + * implementation only. + * + * @param[in] spip pointer to the @p SPIDriver object + * @param[in] msg error code + * + * @notapi + */ +#define __spi_isr_error_code(spip, msg) { \ + if ((spip)->config->error_cb) { \ + (spip)->config->error_cb(spip); \ + } \ + __spi_wakeup_isr(spip, msg); \ } /** @} */ diff --git a/os/hal/ports/STM32/LLD/SPIv2/hal_spi_v2_lld.c b/os/hal/ports/STM32/LLD/SPIv2/hal_spi_v2_lld.c index 01726ec94..4382060f5 100644 --- a/os/hal/ports/STM32/LLD/SPIv2/hal_spi_v2_lld.c +++ b/os/hal/ports/STM32/LLD/SPIv2/hal_spi_v2_lld.c @@ -132,15 +132,19 @@ static uint16_t dummyrx; static void spi_lld_serve_rx_interrupt(SPIDriver *spip, uint32_t flags) { /* DMA errors handling.*/ -#if defined(STM32_SPI_DMA_ERROR_HOOK) if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) { +#if defined(STM32_SPI_DMA_ERROR_HOOK) + /* Hook first, if defined.*/ STM32_SPI_DMA_ERROR_HOOK(spip); - } -#else - (void)flags; #endif - if (spip->config->circular) { + /* Aborting the transfer, best effort.*/ + (void) spi_lld_stop_transfer(spip, NULL); + + /* Reporting the failure.*/ + __spi_isr_error_code(spip, HAL_RET_HW_FAILURE); + } + else if (spip->config->circular) { if ((flags & STM32_DMA_ISR_HTIF) != 0U) { /* Half buffer interrupt.*/ __spi_isr_half_code(spip); @@ -151,13 +155,9 @@ static void spi_lld_serve_rx_interrupt(SPIDriver *spip, uint32_t flags) { } } else { - /* Stopping DMAs.*/ - dmaStreamDisable(spip->dmatx); - dmaStreamDisable(spip->dmarx); - /* Portable SPI ISR code defined in the high level driver, note, it is a macro.*/ - __spi_isr_code(spip); + __spi_isr_full_code(spip); } } @@ -170,17 +170,29 @@ static void spi_lld_serve_rx_interrupt(SPIDriver *spip, uint32_t flags) { static void spi_lld_serve_tx_interrupt(SPIDriver *spip, uint32_t flags) { /* DMA errors handling.*/ -#if defined(STM32_SPI_DMA_ERROR_HOOK) - (void)spip; if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) { +#if defined(STM32_SPI_DMA_ERROR_HOOK) + /* Hook first, if defined.*/ STM32_SPI_DMA_ERROR_HOOK(spip); - } -#else - (void)spip; - (void)flags; #endif + + /* Aborting the transfer, best effort.*/ + (void) spi_lld_stop_transfer(spip, NULL); + + /* Reporting the failure.*/ + __spi_isr_error_code(spip, HAL_RET_HW_FAILURE); + } } +/** + * @brief DMA streams allocation. + * + * @param[in] spip pointer to the @p SPIDriver object + * @param[in] rxstream stream to be allocated for RX + * @param[in] txstream stream to be allocated for TX + * @param[in] priority streams IRQ priority + * @return The operation status. + */ static msg_t spi_lld_get_dma(SPIDriver *spip, uint32_t rxstream, uint32_t txstream, uint32_t priority){