git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/kernel_3_dev@6744 35acf78f-673a-0410-8e92-d51de3d6d3f4

master
gdisirio 2014-03-02 15:15:21 +00:00
parent d48b888620
commit 351ff9c8cc
3 changed files with 48 additions and 43 deletions

View File

@ -41,10 +41,6 @@
*/ */
#define I2S_MODE_SLAVE 0 #define I2S_MODE_SLAVE 0
#define I2S_MODE_MASTER 1 #define I2S_MODE_MASTER 1
#define I2S_MODE_TX 2
#define I2S_MODE_RX 4
#define I2S_MODE_TXRX (I2S_MODE_TX | I2S_MODE_RX)
#define I2S_MODE_CONTINUOUS 16
/** @} */ /** @} */
/*===========================================================================*/ /*===========================================================================*/
@ -84,6 +80,10 @@ typedef enum {
* @brief Starts a I2S data exchange. * @brief Starts a I2S data exchange.
* *
* @param[in] i2sp pointer to the @p I2SDriver object * @param[in] i2sp pointer to the @p I2SDriver object
* @param[in] n size of the transmit buffer, must be even and greater
* than zero
* @param[out] txbuf the pointer to the transmit buffer
* @param[out] rxbuf the pointer to the receive buffer
* *
* @iclass * @iclass
*/ */
@ -141,8 +141,8 @@ typedef enum {
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, \
(i2sp)->config->depth / 2, \ (i2sp)->config->size / 2, \
(i2sp)->config->depth / 2); \ (i2sp)->config->size / 2); \
if ((i2sp)->state == I2S_COMPLETE) \ if ((i2sp)->state == I2S_COMPLETE) \
(i2sp)->state = I2S_READY; \ (i2sp)->state = I2S_READY; \
} \ } \
@ -163,7 +163,7 @@ extern "C" {
void i2sStart(I2SDriver *i2sp, const I2SConfig *config); void i2sStart(I2SDriver *i2sp, const I2SConfig *config);
void i2sStop(I2SDriver *i2sp); void i2sStop(I2SDriver *i2sp);
void i2sStartExchange(I2SDriver *i2sp); void i2sStartExchange(I2SDriver *i2sp);
void i2sStopExchange(I2SDriver *i2sp); void i2sStopTransfer(I2SDriver *i2sp);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -16,7 +16,7 @@
/** /**
* @file i2s_lld.c * @file i2s_lld.c
* @brief I2S Driver subsystem low level driver source template. * @brief STM32 I2S subsystem low level driver source.
* *
* @addtogroup I2S * @addtogroup I2S
* @{ * @{
@ -132,42 +132,55 @@ void i2s_lld_init(void) {
*/ */
void i2s_lld_start(I2SDriver *i2sp) { void i2s_lld_start(I2SDriver *i2sp) {
osalDbgAssert(!((i2sp->config->tx_buffer != NULL) &&
(i2sp->config->rx_buffer != NULL)),
"full duplex not supported");
/* If in stopped state then enables the SPI and DMA clocks.*/ /* If in stopped state then enables the SPI and DMA clocks.*/
if (i2sp->state == I2S_STOP) { if (i2sp->state == I2S_STOP) {
#if STM32_I2S_USE_SPI2 #if STM32_I2S_USE_SPI2
if (&I2SD2 == i2sp) { if (&I2SD2 == i2sp) {
bool b; bool b;
if (NULL != i2sp->config->rx_buffer) {
b = dmaStreamAllocate(i2sp->dmarx, b = dmaStreamAllocate(i2sp->dmarx,
STM32_I2S_SPI2_IRQ_PRIORITY, STM32_I2S_SPI2_IRQ_PRIORITY,
(stm32_dmaisr_t)i2s_lld_serve_rx_interrupt, (stm32_dmaisr_t)i2s_lld_serve_rx_interrupt,
(void *)i2sp); (void *)i2sp);
osalDbgAssert(!b, "stream already allocated"); osalDbgAssert(!b, "stream already allocated");
}
if (NULL != i2sp->config->tx_buffer) {
b = dmaStreamAllocate(i2sp->dmatx, b = dmaStreamAllocate(i2sp->dmatx,
STM32_I2S_SPI2_IRQ_PRIORITY, STM32_I2S_SPI2_IRQ_PRIORITY,
(stm32_dmaisr_t)i2s_lld_serve_tx_interrupt, (stm32_dmaisr_t)i2s_lld_serve_tx_interrupt,
(void *)i2sp); (void *)i2sp);
osalDbgAssert(!b, "stream already allocated"); osalDbgAssert(!b, "stream already allocated");
}
rccEnableSPI2(FALSE); rccEnableSPI2(FALSE);
} }
#endif #endif
#if STM32_I2S_USE_SPI3 #if STM32_I2S_USE_SPI3
if (&I2SD3 == i2sp) { if (&I2SD3 == i2sp) {
bool b; bool b;
if (NULL != i2sp->config->rx_buffer) {
b = dmaStreamAllocate(i2sp->dmarx, b = dmaStreamAllocate(i2sp->dmarx,
STM32_I2S_SPI3_IRQ_PRIORITY, STM32_I2S_SPI3_IRQ_PRIORITY,
(stm32_dmaisr_t)i2s_lld_serve_rx_interrupt, (stm32_dmaisr_t)i2s_lld_serve_rx_interrupt,
(void *)i2sp); (void *)i2sp);
osalDbgAssert(!b, "stream already allocated"); osalDbgAssert(!b, "stream already allocated");
}
if (NULL != i2sp->config->tx_buffer) {
b = dmaStreamAllocate(i2sp->dmatx, b = dmaStreamAllocate(i2sp->dmatx,
STM32_I2S_SPI3_IRQ_PRIORITY, STM32_I2S_SPI3_IRQ_PRIORITY,
(stm32_dmaisr_t)i2s_lld_serve_tx_interrupt, (stm32_dmaisr_t)i2s_lld_serve_tx_interrupt,
(void *)i2sp); (void *)i2sp);
osalDbgAssert(!b, "stream already allocated"); osalDbgAssert(!b, "stream already allocated");
}
rccEnableSPI3(FALSE); rccEnableSPI3(FALSE);
} }
#endif #endif
} }
/* Configuration.*/ /* Configuration.*/
i2sp->spi->CR1 = 0;
} }
/** /**
@ -183,9 +196,10 @@ void i2s_lld_stop(I2SDriver *i2sp) {
if (i2sp->state == I2S_READY) { if (i2sp->state == I2S_READY) {
/* SPI disable.*/ /* SPI disable.*/
i2sp->spi->CR1 = 0;
i2sp->spi->CR2 = 0; i2sp->spi->CR2 = 0;
if (NULL != i2sp->config->rx_buffer)
dmaStreamRelease(i2sp->dmarx); dmaStreamRelease(i2sp->dmarx);
if (NULL != i2sp->config->tx_buffer)
dmaStreamRelease(i2sp->dmatx); dmaStreamRelease(i2sp->dmatx);
#if STM32_I2S_USE_SPI2 #if STM32_I2S_USE_SPI2

View File

@ -16,7 +16,7 @@
/** /**
* @file i2s_lld.h * @file i2s_lld.h
* @brief I2S Driver subsystem low level driver header template. * @brief STM32 I2S subsystem low level driver header.
* *
* @addtogroup I2S * @addtogroup I2S
* @{ * @{
@ -176,11 +176,6 @@
/* Driver data structures and types. */ /* Driver data structures and types. */
/*===========================================================================*/ /*===========================================================================*/
/**
* @brief I2S mode type.
*/
typedef uint32_t i2smode_t;
/** /**
* @brief Type of a structure representing an I2S driver. * @brief Type of a structure representing an I2S driver.
*/ */
@ -200,10 +195,6 @@ typedef void (*i2scallback_t)(I2SDriver *i2sp, size_t offset, size_t n);
* @note It could be empty on some architectures. * @note It could be empty on some architectures.
*/ */
typedef struct { typedef struct {
/**
* @brief I2S mode selection.
*/
i2smode_t mode;
/** /**
* @brief Transmission buffer pointer. * @brief Transmission buffer pointer.
* @note Can be @p NULL if TX is not required. * @note Can be @p NULL if TX is not required.
@ -215,9 +206,9 @@ typedef struct {
*/ */
void *rx_buffer; void *rx_buffer;
/** /**
* @brief TX and RX buffers size in number of samples. * @brief TX and RX buffers size as number of samples.
*/ */
size_t depth; size_t size;
/** /**
* @brief Callback function called during streaming. * @brief Callback function called during streaming.
*/ */