I2S driver (over SPIv1) finished but untested.

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/kernel_3_dev@6748 35acf78f-673a-0410-8e92-d51de3d6d3f4
master
gdisirio 2014-03-03 13:19:56 +00:00
parent 5599a0f0c3
commit 8c4653a413
3 changed files with 64 additions and 17 deletions

View File

@ -118,9 +118,9 @@ typedef enum {
* *
* @notapi * @notapi
*/ */
#define _i2S_isr_half_code(i2sp) { \ #define _i2s_isr_half_code(i2sp) { \
if ((i2sp)->end_cb != NULL) { \ if ((i2sp)->config->end_cb != NULL) { \
(i2sp)->end_cb(i2sp, 0, (i2sp)->config->depth / 2); \ (i2sp)->config->end_cb(i2sp, 0, (i2sp)->config->size / 2); \
} \ } \
} }
@ -137,7 +137,7 @@ typedef enum {
* *
* @notapi * @notapi
*/ */
#define _i2s_isr_code(i2sp) { \ #define _i2s_isr_full_code(i2sp) { \
if ((i2sp)->config->end_cb) { \ if ((i2sp)->config->end_cb) { \
(i2sp)->state = I2S_COMPLETE; \ (i2sp)->state = I2S_COMPLETE; \
(i2sp)->config->end_cb(i2sp, \ (i2sp)->config->end_cb(i2sp, \

View File

@ -118,22 +118,25 @@ I2SDriver I2SD3;
*/ */
static void i2s_lld_serve_rx_interrupt(I2SDriver *i2sp, uint32_t flags) { static void i2s_lld_serve_rx_interrupt(I2SDriver *i2sp, uint32_t flags) {
(void)i2sp;
/* DMA errors handling.*/ /* DMA errors handling.*/
#if defined(STM32_I2S_DMA_ERROR_HOOK) #if defined(STM32_I2S_DMA_ERROR_HOOK)
if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) { if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) {
STM32_I2S_DMA_ERROR_HOOK(i2sp); STM32_I2S_DMA_ERROR_HOOK(i2sp);
} }
#else
(void)flags;
#endif #endif
/* Stop everything.*/ /* Callbacks handling, note it is portable code defined in the high
dmaStreamDisable(i2sp->dmatx); level driver.*/
dmaStreamDisable(i2sp->dmarx); if ((flags & STM32_DMA_ISR_TCIF) != 0) {
/* Transfer complete processing.*/
/* Portable I2S ISR code defined in the high level driver, note, it is _i2s_isr_full_code(i2sp);
a macro.*/ }
_i2s_isr_code(i2sp); else if ((flags & STM32_DMA_ISR_HTIF) != 0) {
/* Half transfer processing.*/
_i2s_isr_half_code(i2sp);
}
} }
#endif #endif
@ -147,15 +150,25 @@ static void i2s_lld_serve_rx_interrupt(I2SDriver *i2sp, uint32_t flags) {
*/ */
static void i2s_lld_serve_tx_interrupt(I2SDriver *i2sp, uint32_t flags) { static void i2s_lld_serve_tx_interrupt(I2SDriver *i2sp, uint32_t flags) {
(void)i2sp;
/* DMA errors handling.*/ /* DMA errors handling.*/
#if defined(STM32_I2S_DMA_ERROR_HOOK) #if defined(STM32_I2S_DMA_ERROR_HOOK)
(void)i2sp;
if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) { if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) {
STM32_I2S_DMA_ERROR_HOOK(i2sp); STM32_I2S_DMA_ERROR_HOOK(i2sp);
} }
#else
(void)flags;
#endif #endif
/* Callbacks handling, note it is portable code defined in the high
level driver.*/
if ((flags & STM32_DMA_ISR_TCIF) != 0) {
/* Transfer complete processing.*/
_i2s_isr_full_code(i2sp);
}
else if ((flags & STM32_DMA_ISR_HTIF) != 0) {
/* Half transfer processing.*/
_i2s_isr_half_code(i2sp);
}
} }
#endif #endif
@ -333,7 +346,7 @@ void i2s_lld_start(I2SDriver *i2sp) {
dmaStreamSetMode(i2sp->dmatx, i2sp->txdmamode | dmasize); dmaStreamSetMode(i2sp->dmatx, i2sp->txdmamode | dmasize);
} }
/* I2S configuration.*/ /* I2S (re)configuration.*/
i2sp->spi->I2SPR = i2sp->config->i2spr; i2sp->spi->I2SPR = i2sp->config->i2spr;
i2sp->spi->I2SCFGR = i2sp->config->i2scfgr | i2sp->cfg | SPI_I2SCFGR_I2SMOD; i2sp->spi->I2SCFGR = i2sp->config->i2scfgr | i2sp->cfg | SPI_I2SCFGR_I2SMOD;
} }
@ -377,6 +390,22 @@ void i2s_lld_stop(I2SDriver *i2sp) {
*/ */
void i2s_lld_start_exchange(I2SDriver *i2sp) { void i2s_lld_start_exchange(I2SDriver *i2sp) {
/* RX DMA setup.*/
if (NULL != i2sp->dmarx) {
dmaStreamSetMemory0(i2sp->dmarx, i2sp->config->rx_buffer);
dmaStreamSetTransactionSize(i2sp->dmarx, i2sp->config->size);
dmaStreamEnable(i2sp->dmarx);
}
/* TX DMA setup.*/
if (NULL != i2sp->dmatx) {
dmaStreamSetMemory0(i2sp->dmatx, i2sp->config->tx_buffer);
dmaStreamSetTransactionSize(i2sp->dmatx, i2sp->config->size);
dmaStreamEnable(i2sp->dmatx);
}
/* Starting transfer.*/
i2sp->spi->I2SCFGR |= SPI_I2SCFGR_I2SE;
} }
/** /**
@ -390,6 +419,14 @@ void i2s_lld_start_exchange(I2SDriver *i2sp) {
*/ */
void i2s_lld_stop_exchange(I2SDriver *i2sp) { void i2s_lld_stop_exchange(I2SDriver *i2sp) {
/* Stop DMAs.*/
if (NULL != i2sp->dmatx)
dmaStreamDisable(i2sp->dmatx);
if (NULL != i2sp->dmarx)
dmaStreamDisable(i2sp->dmarx);
/* Stop transfer.*/
i2sp->spi->I2SCFGR &= ~SPI_I2SCFGR_I2SE;
} }
#endif /* HAL_USE_I2S */ #endif /* HAL_USE_I2S */

View File

@ -134,6 +134,16 @@
/* Derived constants and error checks. */ /* Derived constants and error checks. */
/*===========================================================================*/ /*===========================================================================*/
#if STM32_I2S_RX_ENABLED(STM32_I2S_SPI2_MODE) && \
STM32_I2S_TX_ENABLED(STM32_I2S_SPI2_MODE)
#error "I2S2 RX and TX mode not supported in this driver implementation"
#endif
#if STM32_I2S_RX_ENABLED(STM32_I2S_SPI3_MODE) && \
STM32_I2S_TX_ENABLED(STM32_I2S_SPI3_MODE)
#error "I2S3 RX and TX mode not supported in this driver implementation"
#endif
#if STM32_I2S_USE_SPI2 && !STM32_HAS_SPI2 #if STM32_I2S_USE_SPI2 && !STM32_HAS_SPI2
#error "SPI2 not present in the selected device" #error "SPI2 not present in the selected device"
#endif #endif