From 27261ab8a6ade925246c1dec80ead3f4a9c651c2 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 16 Feb 2014 09:12:08 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/kernel_3_dev@6715 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/ports/STM32/LLD/SPIv1/i2s_lld.c | 228 ++++++++++++++++++++++ os/hal/ports/STM32/LLD/SPIv1/i2s_lld.h | 312 ++++++++++++++++++++++++++++++ os/hal/ports/STM32/LLD/SPIv1/spi_lld.h | 12 +- os/hal/ports/STM32/LLD/SPIv2/spi_lld.h | 7 +- os/hal/ports/STM32/LLD/i2s_lld.c | 161 ---------------- os/hal/ports/STM32/LLD/i2s_lld.h | 317 ------------------------------- os/hal/ports/STM32/STM32F4xx/platform.mk | 1 + 7 files changed, 551 insertions(+), 487 deletions(-) create mode 100644 os/hal/ports/STM32/LLD/SPIv1/i2s_lld.c create mode 100644 os/hal/ports/STM32/LLD/SPIv1/i2s_lld.h delete mode 100644 os/hal/ports/STM32/LLD/i2s_lld.c delete mode 100644 os/hal/ports/STM32/LLD/i2s_lld.h (limited to 'os/hal/ports/STM32') diff --git a/os/hal/ports/STM32/LLD/SPIv1/i2s_lld.c b/os/hal/ports/STM32/LLD/SPIv1/i2s_lld.c new file mode 100644 index 000000000..9e4924501 --- /dev/null +++ b/os/hal/ports/STM32/LLD/SPIv1/i2s_lld.c @@ -0,0 +1,228 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2013 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 i2s_lld.c + * @brief I2S Driver subsystem low level driver source template. + * + * @addtogroup I2S + * @{ + */ + +#include "hal.h" + +#if HAL_USE_I2S || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** @brief I2S2 driver identifier.*/ +#if STM32_I2S_USE_SPI2 || defined(__DOXYGEN__) +I2SDriver I2SD2; +#endif + +/** @brief I2S3 driver identifier.*/ +#if STM32_I2S_USE_SPI3 || defined(__DOXYGEN__) +I2SDriver I2SD3; +#endif + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/** + * @brief Shared end-of-rx service routine. + * + * @param[in] i2sp pointer to the @p I2SDriver object + * @param[in] flags pre-shifted content of the ISR register + */ +static void i2s_lld_serve_rx_interrupt(I2SDriver *i2sp, uint32_t flags) { + + /* DMA errors handling.*/ +#if defined(STM32_I2S_DMA_ERROR_HOOK) + if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) { + STM32_I2S_DMA_ERROR_HOOK(i2sp); + } +#else + (void)flags; +#endif + + /* Stop everything.*/ + dmaStreamDisable(i2sp->dmatx); + dmaStreamDisable(i2sp->dmarx); + + /* Portable I2S ISR code defined in the high level driver, note, it is + a macro.*/ + _i2s_isr_code(i2sp); +} + +/** + * @brief Shared end-of-tx service routine. + * + * @param[in] i2sp pointer to the @p I2SDriver object + * @param[in] flags pre-shifted content of the ISR register + */ +static void i2s_lld_serve_tx_interrupt(I2SDriver *i2sp, uint32_t flags) { + + /* DMA errors handling.*/ +#if defined(STM32_I2S_DMA_ERROR_HOOK) + (void)i2sp; + if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) { + STM32_I2S_DMA_ERROR_HOOK(i2sp); + } +#else + (void)flags; +#endif +} + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Low level I2S driver initialization. + * + * @notapi + */ +void i2s_lld_init(void) { + +#if STM32_I2S_USE_SPI2 + i2sObjectInit(&I2SD2); + I2SD2.spi = SPI2; +#endif + +#if STM32_I2S_USE_SPI3 + i2sObjectInit(&I2SD3); + I2SD3.spi = SPI3; +#endif +} + +/** + * @brief Configures and activates the I2S peripheral. + * + * @param[in] i2sp pointer to the @p I2SDriver object + * + * @notapi + */ +void i2s_lld_start(I2SDriver *i2sp) { + + /* If in stopped state then enables the SPI and DMA clocks.*/ + if (i2sp->state == I2S_STOP) { +#if STM32_I2S_USE_SPI2 + if (&I2SD2 == i2sp) { + bool b; + b = dmaStreamAllocate(i2sp->dmarx, + STM32_I2S_SPI2_IRQ_PRIORITY, + (stm32_dmaisr_t)i2s_lld_serve_rx_interrupt, + (void *)i2sp); + osalDbgAssert(!b, "stream already allocated"); + b = dmaStreamAllocate(i2sp->dmatx, + STM32_I2S_SPI2_IRQ_PRIORITY, + (stm32_dmaisr_t)i2s_lld_serve_tx_interrupt, + (void *)i2sp); + osalDbgAssert(!b, "stream already allocated"); + rccEnableSPI2(FALSE); + } +#endif +#if STM32_I2S_USE_SPI3 + if (&I2SD3 == i2sp) { + bool b; + b = dmaStreamAllocate(i2sp->dmarx, + STM32_I2S_SPI3_IRQ_PRIORITY, + (stm32_dmaisr_t)i2s_lld_serve_rx_interrupt, + (void *)i2sp); + osalDbgAssert(!b, "stream already allocated"); + b = dmaStreamAllocate(i2sp->dmatx, + STM32_I2S_SPI3_IRQ_PRIORITY, + (stm32_dmaisr_t)i2s_lld_serve_tx_interrupt, + (void *)i2sp); + osalDbgAssert(!b, "stream already allocated"); + rccEnableSPI3(FALSE); + } +#endif + } + /* Configuration.*/ +} + +/** + * @brief Deactivates the I2S peripheral. + * + * @param[in] i2sp pointer to the @p I2SDriver object + * + * @notapi + */ +void i2s_lld_stop(I2SDriver *i2sp) { + + /* If in ready state then disables the SPI clock.*/ + if (i2sp->state == I2S_READY) { + + /* SPI disable.*/ + i2sp->spi->CR1 = 0; + i2sp->spi->CR2 = 0; + dmaStreamRelease(i2sp->dmarx); + dmaStreamRelease(i2sp->dmatx); + +#if STM32_I2S_USE_SPI2 + if (&I2SD2 == i2sp) + rccDisableSPI2(FALSE); +#endif +#if STM32_I2S_USE_SPI3 + if (&I2SD3 == i2sp) + rccDisableSPI3(FALSE); +#endif + } +} + +/** + * @brief Starts a I2S data exchange. + * + * @param[in] i2sp pointer to the @p I2SDriver object + * + * @notapi + */ +void i2s_lld_start_exchange(I2SDriver *i2sp) { + +} + +/** + * @brief Stops the ongoing data exchange. + * @details The ongoing data exchange, if any, is stopped, if the driver + * was not active the function does nothing. + * + * @param[in] i2sp pointer to the @p I2SDriver object + * + * @notapi + */ +void i2s_lld_stop_exchange(I2SDriver *i2sp) { + +} + +#endif /* HAL_USE_I2S */ + +/** @} */ diff --git a/os/hal/ports/STM32/LLD/SPIv1/i2s_lld.h b/os/hal/ports/STM32/LLD/SPIv1/i2s_lld.h new file mode 100644 index 000000000..a3ea2e1c4 --- /dev/null +++ b/os/hal/ports/STM32/LLD/SPIv1/i2s_lld.h @@ -0,0 +1,312 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2013 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 i2s_lld.h + * @brief I2S Driver subsystem low level driver header template. + * + * @addtogroup I2S + * @{ + */ + +#ifndef _I2S_LLD_H_ +#define _I2S_LLD_H_ + +#if HAL_USE_I2S || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @name Configuration options + * @{ + */ +/** + * @brief I2S2 driver enable switch. + * @details If set to @p TRUE the support for I2S2 is included. + * @note The default is @p TRUE. + */ +#if !defined(STM32_I2S_USE_SPI2) || defined(__DOXYGEN__) +#define STM32_I2S_USE_SPI2 FALSE +#endif + +/** + * @brief I2S3 driver enable switch. + * @details If set to @p TRUE the support for I2S3 is included. + * @note The default is @p TRUE. + */ +#if !defined(STM32_I2S_USE_SPI3) || defined(__DOXYGEN__) +#define STM32_I2S_USE_SPI3 FALSE +#endif + +/** + * @brief I2S2 interrupt priority level setting. + */ +#if !defined(STM32_I2S_SPI2_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define STM32_I2S_SPI2_IRQ_PRIORITY 10 +#endif + +/** + * @brief I2S3 interrupt priority level setting. + */ +#if !defined(STM32_I2S_SPI3_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define STM32_I2S_SPI3_IRQ_PRIORITY 10 +#endif + +/** + * @brief I2S2 DMA priority (0..3|lowest..highest). + */ +#if !defined(STM32_I2S_SPI2_DMA_PRIORITY) || defined(__DOXYGEN__) +#define STM32_I2S_SPI2_DMA_PRIORITY 1 +#endif + +/** + * @brief I2S3 DMA priority (0..3|lowest..highest). + */ +#if !defined(STM32_I2S_SPI3_DMA_PRIORITY) || defined(__DOXYGEN__) +#define STM32_I2S_SPI3_DMA_PRIORITY 1 +#endif + +/** + * @brief I2S DMA error hook. + */ +#if !defined(STM32_I2S_DMA_ERROR_HOOK) || defined(__DOXYGEN__) +#define STM32_I2S_DMA_ERROR_HOOK(i2sp) osalSysHalt("DMA failure") +#endif +/** @} */ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +#if STM32_I2S_USE_SPI2 && !STM32_HAS_SPI2 +#error "SPI2 not present in the selected device" +#endif + +#if STM32_I2S_USE_SPI3 && !STM32_HAS_SPI3 +#error "SPI3 not present in the selected device" +#endif + +#if !STM32_I2S_USE_SPI2 && !STM32_I2S_USE_SPI3 +#error "I2S driver activated but no SPI peripheral assigned" +#endif + + +#if STM32_I2S_USE_SPI2 && \ + !CORTEX_IS_VALID_KERNEL_PRIORITY(STM32_I2S_SPI2_IRQ_PRIORITY) +#error "Invalid IRQ priority assigned to SPI2" +#endif + +#if STM32_I2S_USE_SPI3 && \ + !CORTEX_IS_VALID_KERNEL_PRIORITY(STM32_I2S_SPI3_IRQ_PRIORITY) +#error "Invalid IRQ priority assigned to SPI3" +#endif + + +#if STM32_I2S_USE_SPI2 && \ + !STM32_DMA_IS_VALID_PRIORITY(STM32_I2S_SPI2_DMA_PRIORITY) +#error "Invalid DMA priority assigned to SPI2" +#endif + +#if STM32_I2S_USE_SPI3 && \ + !STM32_DMA_IS_VALID_PRIORITY(STM32_I2S_SPI3_DMA_PRIORITY) +#error "Invalid DMA priority assigned to SPI3" +#endif + + +/* The following checks are only required when there is a DMA able to + reassign streams to different channels.*/ +#if STM32_ADVANCED_DMA +/* Check on the presence of the DMA streams settings in mcuconf.h.*/ +#if STM32_I2S_USE_SPI2 && (!defined(STM32_I2S_SPI2_RX_DMA_STREAM) || \ + !defined(STM32_I2S_SPI2_TX_DMA_STREAM)) +#error "SPI2 DMA streams not defined" +#endif + +#if STM32_I2S_USE_SPI3 && (!defined(STM32_I2S_SPI3_RX_DMA_STREAM) || \ + !defined(STM32_I2S_SPI3_TX_DMA_STREAM)) +#error "SPI3 DMA streams not defined" +#endif + +/* Check on the validity of the assigned DMA channels.*/ +#if STM32_I2S_USE_SPI2 && \ + !STM32_DMA_IS_VALID_ID(STM32_I2S_SPI2_RX_DMA_STREAM, STM32_SPI2_RX_DMA_MSK) +#error "invalid DMA stream associated to SPI2 RX" +#endif + +#if STM32_I2S_USE_SPI2 && \ + !STM32_DMA_IS_VALID_ID(STM32_I2S_SPI2_TX_DMA_STREAM, STM32_SPI2_TX_DMA_MSK) +#error "invalid DMA stream associated to SPI2 TX" +#endif + +#if STM32_I2S_USE_SPI3 && \ + !STM32_DMA_IS_VALID_ID(STM32_I2S_SPI3_RX_DMA_STREAM, STM32_SPI3_RX_DMA_MSK) +#error "invalid DMA stream associated to SPI3 RX" +#endif + +#if STM32_I2S_USE_SPI3 && \ + !STM32_DMA_IS_VALID_ID(STM32_I2S_SPI3_TX_DMA_STREAM, STM32_SPI3_TX_DMA_MSK) +#error "invalid DMA stream associated to SPI3 TX" +#endif +#endif /* STM32_ADVANCED_DMA */ + +#if !defined(STM32_DMA_REQUIRED) +#define STM32_DMA_REQUIRED +#endif + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/** + * @brief I2S mode type. + */ +typedef uint32_t i2smode_t; + +/** + * @brief Type of a structure representing an I2S driver. + */ +typedef struct I2SDriver I2SDriver; + +/** + * @brief I2S notification callback type. + * + * @param[in] i2sp pointer to the @p I2SDriver object + * @param[in] offset offset in buffers of the data to read/write + * @param[in] n number of samples to read/write + */ +typedef void (*i2scallback_t)(I2SDriver *i2sp, size_t offset, size_t n); + +/** + * @brief Driver configuration structure. + * @note It could be empty on some architectures. + */ +typedef struct { + /** + * @brief I2S mode selection. + */ + i2smode_t mode; + /** + * @brief Transmission buffer pointer. + * @note Can be @p NULL if TX is not required. + */ + const void *tx_buffer; + /** + * @brief Receive buffer pointer. + * @note Can be @p NULL if RX is not required. + */ + void *rx_buffer; + /** + * @brief TX and RX buffers size in number of samples. + */ + size_t depth; + /** + * @brief Callback function called during streaming. + */ + i2scallback_t end_cb; + /* End of the mandatory fields.*/ + /** + * @brief Configuration of the I2SCFGR register. + * @details See the STM32 reference manual, this register is used for + * the I2S configuration, the following bits must not be + * specified because handled directly by the driver: + * - I2SMOD + * - I2SE + * - I2SCFG + * . + */ + int16_t i2scfgr; + /** + * @brief Configuration of the I2SPR register. + * @details See the STM32 reference manual, this register is used for + * the I2S clock setup. + */ + int16_t i2spr; +} I2SConfig; + +/** + * @brief Structure representing an I2S driver. + */ +struct I2SDriver { + /** + * @brief Driver state. + */ + i2sstate_t state; + /** + * @brief Current configuration data. + */ + const I2SConfig *config; + /* End of the mandatory fields.*/ + /** + * @brief Pointer to the SPIx registers block. + */ + SPI_TypeDef *spi; + /** + * @brief Receive DMA stream. + */ + const stm32_dma_stream_t *dmarx; + /** + * @brief Transmit DMA stream. + */ + const stm32_dma_stream_t *dmatx; + /** + * @brief RX DMA mode bit mask. + */ + uint32_t rxdmamode; + /** + * @brief TX DMA mode bit mask. + */ + uint32_t txdmamode; +}; + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#if STM32_I2S_USE_SPI2 && !defined(__DOXYGEN__) +extern I2SDriver I2SD2; +#endif + +#if STM32_I2S_USE_I2S3 && !defined(__DOXYGEN__) +extern I2SDriver SPI3; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + void i2s_lld_init(void); + void i2s_lld_start(I2SDriver *i2sp); + void i2s_lld_stop(I2SDriver *i2sp); + void i2s_lld_start_exchange(I2SDriver *i2sp); + void i2s_lld_stop_exchange(I2SDriver *i2sp); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_USE_I2S */ + +#endif /* _I2S_LLD_H_ */ + +/** @} */ diff --git a/os/hal/ports/STM32/LLD/SPIv1/spi_lld.h b/os/hal/ports/STM32/LLD/SPIv1/spi_lld.h index fe31daeff..7700c34fe 100644 --- a/os/hal/ports/STM32/LLD/SPIv1/spi_lld.h +++ b/os/hal/ports/STM32/LLD/SPIv1/spi_lld.h @@ -42,7 +42,7 @@ /** * @brief SPI1 driver enable switch. * @details If set to @p TRUE the support for SPI1 is included. - * @note The default is @p TRUE. + * @note The default is @p FALSE. */ #if !defined(STM32_SPI_USE_SPI1) || defined(__DOXYGEN__) #define STM32_SPI_USE_SPI1 FALSE @@ -51,7 +51,7 @@ /** * @brief SPI2 driver enable switch. * @details If set to @p TRUE the support for SPI2 is included. - * @note The default is @p TRUE. + * @note The default is @p FALSE. */ #if !defined(STM32_SPI_USE_SPI2) || defined(__DOXYGEN__) #define STM32_SPI_USE_SPI2 FALSE @@ -60,7 +60,7 @@ /** * @brief SPI3 driver enable switch. * @details If set to @p TRUE the support for SPI3 is included. - * @note The default is @p TRUE. + * @note The default is @p FALSE. */ #if !defined(STM32_SPI_USE_SPI3) || defined(__DOXYGEN__) #define STM32_SPI_USE_SPI3 FALSE @@ -69,7 +69,7 @@ /** * @brief SPI4 driver enable switch. * @details If set to @p TRUE the support for SPI4 is included. - * @note The default is @p TRUE. + * @note The default is @p FALSE. */ #if !defined(STM32_SPI_USE_SPI4) || defined(__DOXYGEN__) #define STM32_SPI_USE_SPI4 FALSE @@ -78,7 +78,7 @@ /** * @brief SPI5 driver enable switch. * @details If set to @p TRUE the support for SPI5 is included. - * @note The default is @p TRUE. + * @note The default is @p FALSE. */ #if !defined(STM32_SPI_USE_SPI5) || defined(__DOXYGEN__) #define STM32_SPI_USE_SPI5 FALSE @@ -87,7 +87,7 @@ /** * @brief SPI6 driver enable switch. * @details If set to @p TRUE the support for SPI6 is included. - * @note The default is @p TRUE. + * @note The default is @p FALSE. */ #if !defined(STM32_SPI_USE_SPI6) || defined(__DOXYGEN__) #define STM32_SPI_USE_SPI6 FALSE diff --git a/os/hal/ports/STM32/LLD/SPIv2/spi_lld.h b/os/hal/ports/STM32/LLD/SPIv2/spi_lld.h index 72ed48c94..0be4f5c48 100644 --- a/os/hal/ports/STM32/LLD/SPIv2/spi_lld.h +++ b/os/hal/ports/STM32/LLD/SPIv2/spi_lld.h @@ -42,7 +42,7 @@ /** * @brief SPI1 driver enable switch. * @details If set to @p TRUE the support for SPI1 is included. - * @note The default is @p TRUE. + * @note The default is @p FALSE. */ #if !defined(STM32_SPI_USE_SPI1) || defined(__DOXYGEN__) #define STM32_SPI_USE_SPI1 FALSE @@ -51,7 +51,7 @@ /** * @brief SPI2 driver enable switch. * @details If set to @p TRUE the support for SPI2 is included. - * @note The default is @p TRUE. + * @note The default is @p FALSE. */ #if !defined(STM32_SPI_USE_SPI2) || defined(__DOXYGEN__) #define STM32_SPI_USE_SPI2 FALSE @@ -60,7 +60,7 @@ /** * @brief SPI3 driver enable switch. * @details If set to @p TRUE the support for SPI3 is included. - * @note The default is @p TRUE. + * @note The default is @p FALSE. */ #if !defined(STM32_SPI_USE_SPI3) || defined(__DOXYGEN__) #define STM32_SPI_USE_SPI3 FALSE @@ -123,6 +123,7 @@ #if !defined(STM32_SPI_DMA_ERROR_HOOK) || defined(__DOXYGEN__) #define STM32_SPI_DMA_ERROR_HOOK(spip) osalSysHalt("DMA failure") #endif +/** @} */ /*===========================================================================*/ /* Derived constants and error checks. */ diff --git a/os/hal/ports/STM32/LLD/i2s_lld.c b/os/hal/ports/STM32/LLD/i2s_lld.c deleted file mode 100644 index b7eaf4b0c..000000000 --- a/os/hal/ports/STM32/LLD/i2s_lld.c +++ /dev/null @@ -1,161 +0,0 @@ -/* - ChibiOS/RT - Copyright (C) 2006-2013 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 STM32/i2s_lld.c - * @brief I2S Driver subsystem low level driver source template. - * - * @addtogroup I2S - * @{ - */ - -#include "ch.h" -#include "hal.h" - -#if HAL_USE_I2S || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local variables and types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver interrupt handlers. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -/** - * @brief Low level I2S driver initialization. - * - * @notapi - */ -void i2s_lld_init(void) { - -#if STM32_I2S_USE_I2S2 - spiObjectInit(&I2SD2); - I2SD2.spi = SPI2; -#endif - -#if STM32_I2S_USE_I2S3 - spiObjectInit(&I2SD3); - I2SD3.spi = SPI3; -#endif -} - -/** - * @brief Configures and activates the I2S peripheral. - * - * @param[in] i2sp pointer to the @p I2SDriver object - * - * @notapi - */ -void i2s_lld_start(I2SDriver *i2sp) { - - /* If in stopped state then enables the SPI and DMA clocks.*/ - if (i2sp->state == I2S_STOP) { -#if STM32_SPI_USE_SPI2 - if (&SPID2 == spip) { - bool_t b; - b = dmaStreamAllocate(spip->dma, - STM32_I2S_I2S2_IRQ_PRIORITY, - (stm32_dmaisr_t)i2s_lld_serve_rx_interrupt, - (void *)spip); - chDbgAssert(!b, "spi_lld_start(), #1", "stream already allocated"); - rccEnableSPI2(FALSE); - } -#endif -#if STM32_SPI_USE_SPI3 - if (&SPID3 == spip) { - bool_t b; - b = dmaStreamAllocate(spip->dma, - STM32_I2S_I2S3_IRQ_PRIORITY, - (stm32_dmaisr_t)i2s_lld_serve_rx_interrupt, - (void *)spip); - chDbgAssert(!b, "spi_lld_start(), #2", "stream already allocated"); - rccEnableSPI3(FALSE); - } -#endif - } - /* Configuration.*/ -} - -/** - * @brief Deactivates the I2S peripheral. - * - * @param[in] i2sp pointer to the @p I2SDriver object - * - * @notapi - */ -void i2s_lld_stop(I2SDriver *i2sp) { - - if (i2sp->state == I2S_READY) { - /* Clock deactivation.*/ - - } -} - -/** - * @brief Starts a I2S data exchange. - * - * @param[in] i2sp pointer to the @p I2SDriver object - * - * @notapi - */ -void i2s_lld_start_exchange(I2SDriver *i2sp) { - -} - -/** - * @brief Starts a I2S data exchange in continuous mode. - * - * @param[in] i2sp pointer to the @p I2SDriver object - * - * @notapi - */ -void i2s_lld_start_exchange_continuous(I2SDriver *i2sp) { - -} - -/** - * @brief Stops the ongoing data exchange. - * @details The ongoing data exchange, if any, is stopped, if the driver - * was not active the function does nothing. - * - * @param[in] i2sp pointer to the @p I2SDriver object - * - * @notapi - */ -void i2s_lld_stop_exchange(I2SDriver *i2sp) { - -} - -#endif /* HAL_USE_I2S */ - -/** @} */ diff --git a/os/hal/ports/STM32/LLD/i2s_lld.h b/os/hal/ports/STM32/LLD/i2s_lld.h deleted file mode 100644 index 3f9c640b3..000000000 --- a/os/hal/ports/STM32/LLD/i2s_lld.h +++ /dev/null @@ -1,317 +0,0 @@ -/* - ChibiOS/RT - Copyright (C) 2006-2013 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 STM32/i2s_lld.h - * @brief I2S Driver subsystem low level driver header template. - * - * @addtogroup I2S - * @{ - */ - -#ifndef _I2S_LLD_H_ -#define _I2S_LLD_H_ - -#if HAL_USE_I2S || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver constants. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver pre-compile time settings. */ -/*===========================================================================*/ - -/** - * @name Configuration options - * @{ - */ -/** - * @brief I2S2 driver enable switch. - * @details If set to @p TRUE the support for I2S2 is included. - * @note The default is @p TRUE. - */ -#if !defined(STM32_I2S_USE_I2S2) || defined(__DOXYGEN__) -#define STM32_I2S_USE_I2S2 FALSE -#endif - -/** - * @brief I2S3 driver enable switch. - * @details If set to @p TRUE the support for I2S3 is included. - * @note The default is @p TRUE. - */ -#if !defined(STM32_I2S_USE_I2S3) || defined(__DOXYGEN__) -#define STM32_I2S_USE_I2S3 FALSE -#endif - -/** - * @brief I2S2 interrupt priority level setting. - */ -#if !defined(STM32_I2S_I2S2_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define STM32_I2S_I2S2_IRQ_PRIORITY 10 -#endif - -/** - * @brief I2S3 interrupt priority level setting. - */ -#if !defined(STM32_I2S_I2S3_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define STM32_I2S_I2S3_IRQ_PRIORITY 10 -#endif - -/** - * @brief I2S2 DMA priority (0..3|lowest..highest). - */ -#if !defined(STM32_I2S_I2S2_DMA_PRIORITY) || defined(__DOXYGEN__) -#define STM32_I2S_I2S2_DMA_PRIORITY 1 -#endif - -/** - * @brief I2S3 DMA priority (0..3|lowest..highest). - */ -#if !defined(STM32_I2S_I2S2_DMA_PRIORITY) || defined(__DOXYGEN__) -#define STM32_I2S_I2S2_DMA_PRIORITY 1 -#endif - -/** - * @brief I2S DMA error hook. - */ -#if !defined(STM32_I2S_DMA_ERROR_HOOK) || defined(__DOXYGEN__) -#define STM32_I2S_DMA_ERROR_HOOK(i2sp) chSysHalt() -#endif - -#if STM32_ADVANCED_DMA || defined(__DOXYGEN__) - -/** - * @brief DMA stream used for I2S2 RX operations. - * @note This option is only available on platforms with enhanced DMA. - */ -#if !defined(STM32_I2S_I2S2_RX_DMA_STREAM) || defined(__DOXYGEN__) -#define STM32_I2S_I2S2_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 0) -#endif - -/** - * @brief DMA stream used for I2S2 TX operations. - * @note This option is only available on platforms with enhanced DMA. - */ -#if !defined(STM32_I2S_I2S2_TX_DMA_STREAM) || defined(__DOXYGEN__) -#define STM32_I2S_I2S2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4) -#endif - -/** - * @brief DMA stream used for I2S3 RX operations. - * @note This option is only available on platforms with enhanced DMA. - */ -#if !defined(STM32_I2S_I2S3_RX_DMA_STREAM) || defined(__DOXYGEN__) -#define STM32_I2S_I2S3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 0) -#endif - -/** - * @brief DMA stream used for I2S3 TX operations. - * @note This option is only available on platforms with enhanced DMA. - */ -#if !defined(STM32_I2S_I2S3_TX_DMA_STREAM) || defined(__DOXYGEN__) -#define STM32_I2S_I2S3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7) -#endif - -#else /* !STM32_ADVANCED_DMA */ - -/* Fixed streams for platforms using the old DMA peripheral, the values are - valid for both STM32F1xx and STM32L1xx.*/ -#define STM32_I2S_I2S2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4) -#define STM32_I2S_I2S2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5) -#define STM32_I2S_I2S3_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 1) -#define STM32_I2S_I2S3_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 2) - -#endif /* !STM32_ADVANCED_DMA */ -/** @} */ - -/*===========================================================================*/ -/* Derived constants and error checks. */ -/*===========================================================================*/ - -#if STM32_I2S_USE_I2S2 && !STM32_HAS_SPI2 -#error "SPI2 not present in the selected device" -#endif - -#if STM32_I2S_USE_I2S3 && !STM32_HAS_SPI3 -#error "SPI3 not present in the selected device" -#endif - -#if !STM32_I2S_USE_I2S2 && !STM32_I2S_USE_I2S3 -#error "I2S driver activated but no I2S peripheral assigned" -#endif - -#if STM32_I2S_USE_I2S2 && \ - !STM32_DMA_IS_VALID_ID(STM32_I2S_I2S2_RX_DMA_STREAM, STM32_SPI2_RX_DMA_MSK) -#error "invalid DMA stream associated to I2S2 RX" -#endif - -#if STM32_I2S_USE_I2S2 && \ - !STM32_DMA_IS_VALID_ID(STM32_I2S_I2S2_TX_DMA_STREAM, STM32_SPI2_TX_DMA_MSK) -#error "invalid DMA stream associated to I2S2 TX" -#endif - -#if STM32_I2S_USE_I2S3 && \ - !STM32_DMA_IS_VALID_ID(STM32_I2S_I2S3_RX_DMA_STREAM, STM32_SPI3_RX_DMA_MSK) -#error "invalid DMA stream associated to I2S3 RX" -#endif - -#if STM32_I2S_USE_I2S3 && \ - !STM32_DMA_IS_VALID_ID(STM32_I2S_I2S3_TX_DMA_STREAM, STM32_SPI3_TX_DMA_MSK) -#error "invalid DMA stream associated to I2S3 TX" -#endif - -#if !defined(STM32_DMA_REQUIRED) -#define STM32_DMA_REQUIRED -#endif - -/*===========================================================================*/ -/* Driver data structures and types. */ -/*===========================================================================*/ - -/** - * @brief I2S mode type. - */ -typedef uint32_t i2smode_t; - -/** - * @brief Type of a structure representing an I2S driver. - */ -typedef struct I2SDriver I2SDriver; - -/** - * @brief I2S notification callback type. - * - * @param[in] i2sp pointer to the @p I2SDriver object - * @param[in] buffer pointer to the buffer - * @param[in] n number of sample positions starting from @p buffer - */ -typedef void (*i2scallback_t)(I2SDriver *i2sp, void *buffer, size_t n); - -/** - * @brief Driver configuration structure. - * @note It could be empty on some architectures. - */ -typedef struct { - /** - * @brief I2S mode selection. - */ - i2smode_t mode; - /** - * @brief Transmission buffer pointer. - */ - const void *tx_buffer; - /** - * @brief Transmission buffer size in number of samples. - */ - size_t tx_size; - /** - * @brief Callback function associated to the transmission or @p NULL. - */ - i2scallback_t tx_cb; - /** - * @brief Receive buffer pointer. - */ - void *rx_buffer; - /** - * @brief Receive buffer size in number of samples. - */ - size_t rx_size; - /** - * @brief Callback function associated to the reception or @p NULL. - */ - i2scallback_t rx_cb;; - /* End of the mandatory fields.*/ - /** - * @brief Configuration of the I2SCFGR register. - * @details See the STM32 reference manual, this register is used for - * the I2S configuration, the following bits must not be - * specified because handled directly by the driver: - * - I2SMOD - * - I2SE - * - I2SCFG - * . - */ - int16_t i2scfgr; - /** - * @brief Configuration of the I2SPR register. - * @details See the STM32 reference manual, this register is used for - * the I2S clock setup. - */ - int16_t i2spr; -} I2SConfig; - -/** - * @brief Structure representing an I2S driver. - */ -struct I2SDriver { - /** - * @brief Driver state. - */ - i2sstate_t state; - /** - * @brief Current configuration data. - */ - const I2SConfig *config; - /* End of the mandatory fields.*/ - /** - * @brief Pointer to the SPIx registers block. - */ - SPI_TypeDef *spi; - /** - * @brief DMA stream. - */ - const stm32_dma_stream_t *dma; - /** - * @brief DMA mode bit mask. - */ - uint32_t dmamode; -}; - -/*===========================================================================*/ -/* Driver macros. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* External declarations. */ -/*===========================================================================*/ - -#if STM32_I2S_USE_I2S2 && !defined(__DOXYGEN__) -extern I2SDriver I2SD2; -#endif - -#if STM32_I2S_USE_I2S3 && !defined(__DOXYGEN__) -extern I2SDriver I2SD3; -#endif - -#ifdef __cplusplus -extern "C" { -#endif - void i2s_lld_init(void); - void i2s_lld_start(I2SDriver *i2sp); - void i2s_lld_stop(I2SDriver *i2sp); - void i2s_lld_start_exchange(I2SDriver *i2sp); - void i2s_lld_start_exchange_continuous(I2SDriver *i2sp); - void i2s_lld_stop_exchange(I2SDriver *i2sp); -#ifdef __cplusplus -} -#endif - -#endif /* HAL_USE_I2S */ - -#endif /* _I2S_LLD_H_ */ - -/** @} */ diff --git a/os/hal/ports/STM32/STM32F4xx/platform.mk b/os/hal/ports/STM32/STM32F4xx/platform.mk index cfbe44433..0f793f18f 100644 --- a/os/hal/ports/STM32/STM32F4xx/platform.mk +++ b/os/hal/ports/STM32/STM32F4xx/platform.mk @@ -12,6 +12,7 @@ PLATFORMSRC = ${CHIBIOS}/os/hal/ports/common/ARMCMx/nvic.c \ ${CHIBIOS}/os/hal/ports/STM32/LLD/I2Cv1/i2c_lld.c \ ${CHIBIOS}/os/hal/ports/STM32/LLD/OTGv1/usb_lld.c \ ${CHIBIOS}/os/hal/ports/STM32/LLD/RTCv2/rtc_lld.c \ + ${CHIBIOS}/os/hal/ports/STM32/LLD/SPIv1/i2s_lld.c \ ${CHIBIOS}/os/hal/ports/STM32/LLD/SPIv1/spi_lld.c \ ${CHIBIOS}/os/hal/ports/STM32/LLD/TIMv1/gpt_lld.c \ ${CHIBIOS}/os/hal/ports/STM32/LLD/TIMv1/icu_lld.c \ -- cgit v1.2.3