I2C. Bug fixes.

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/i2c_dev@3562 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
barthess 2011-12-06 18:09:34 +00:00
parent d34bc423c8
commit 2db3c769f1
4 changed files with 38 additions and 43 deletions

View File

@ -141,6 +141,16 @@ static void i2c_serve_event_interrupt(I2CDriver *i2cp) {
dp->DR = i2cp->slave_addr; dp->DR = i2cp->slave_addr;
break; break;
case I2C_EV6_MASTER_REC_MODE_SELECTED:
dmaStreamEnable(i2cp->dmarx);
i2cp->id_i2c->CR2 |= I2C_CR2_DMAEN | I2C_CR2_LAST;
break;
case I2C_EV6_MASTER_TRA_MODE_SELECTED:
dmaStreamEnable(i2cp->dmatx);
i2cp->id_i2c->CR2 |= I2C_CR2_DMAEN | I2C_CR2_LAST;
break;
case I2C_EV8_2_MASTER_BYTE_TRANSMITTED: case I2C_EV8_2_MASTER_BYTE_TRANSMITTED:
/* catch BTF event after the end of trasmission */ /* catch BTF event after the end of trasmission */
if (i2cp->rxbytes > 1){ if (i2cp->rxbytes > 1){
@ -197,6 +207,14 @@ static void i2c_serve_error_interrupt(I2CDriver *i2cp) {
i2cflags_t flags; i2cflags_t flags;
I2C_TypeDef *reg; I2C_TypeDef *reg;
chSysLockFromIsr();
/* clear interrupt falgs just to be safe */
dmaStreamClearInterrupt(i2cp->dmatx);
dmaStreamClearInterrupt(i2cp->dmarx);
dmaStreamDisable(i2cp->dmatx);
dmaStreamDisable(i2cp->dmarx);
chSysUnlockFromIsr();
reg = i2cp->id_i2c; reg = i2cp->id_i2c;
flags = I2CD_NO_ERROR; flags = I2CD_NO_ERROR;
@ -481,9 +499,7 @@ void i2c_lld_master_receive(I2CDriver *i2cp, uint8_t slave_addr,
dmaStreamSetMemory0(i2cp->dmarx, rxbuf); dmaStreamSetMemory0(i2cp->dmarx, rxbuf);
dmaStreamSetTransactionSize(i2cp->dmarx, rxbytes); dmaStreamSetTransactionSize(i2cp->dmarx, rxbytes);
dmaStreamSetMode(i2cp->dmarx, ((i2cp->dmamode) | mode)); dmaStreamSetMode(i2cp->dmarx, ((i2cp->dmamode) | mode));
dmaStreamEnable(i2cp->dmarx);
i2cp->id_i2c->CR2 |= I2C_CR2_DMAEN | I2C_CR2_LAST;
i2cp->id_i2c->CR2 |= I2C_CR2_ITERREN | I2C_CR2_ITEVTEN; i2cp->id_i2c->CR2 |= I2C_CR2_ITERREN | I2C_CR2_ITEVTEN;
i2cp->id_i2c->CR1 |= I2C_CR1_START | I2C_CR1_ACK; i2cp->id_i2c->CR1 |= I2C_CR1_START | I2C_CR1_ACK;
} }
@ -521,9 +537,7 @@ void i2c_lld_master_transmit(I2CDriver *i2cp, uint8_t slave_addr,
dmaStreamSetMemory0(i2cp->dmatx, txbuf); dmaStreamSetMemory0(i2cp->dmatx, txbuf);
dmaStreamSetTransactionSize(i2cp->dmatx, txbytes); dmaStreamSetTransactionSize(i2cp->dmatx, txbytes);
dmaStreamSetMode(i2cp->dmatx, ((i2cp->dmamode) | mode)); dmaStreamSetMode(i2cp->dmatx, ((i2cp->dmamode) | mode));
dmaStreamEnable(i2cp->dmatx);
i2cp->id_i2c->CR2 |= I2C_CR2_DMAEN | I2C_CR2_LAST;
i2cp->id_i2c->CR2 |= I2C_CR2_ITERREN | I2C_CR2_ITEVTEN; i2cp->id_i2c->CR2 |= I2C_CR2_ITERREN | I2C_CR2_ITEVTEN;
i2cp->id_i2c->CR1 |= I2C_CR1_START; i2cp->id_i2c->CR1 |= I2C_CR1_START;
} }

View File

@ -171,12 +171,15 @@
/** @brief flags for interrupt handling */ /** @brief flags for interrupt handling */
#define I2C_EV5_MASTER_MODE_SELECT ((uint32_t)(((I2C_SR2_MSL | I2C_SR2_BUSY) << 16) | I2C_SR1_SB)) /* BUSY, MSL and SB flag */ #define I2C_EV5_MASTER_MODE_SELECT ((uint32_t)(((I2C_SR2_MSL | I2C_SR2_BUSY) << 16) | I2C_SR1_SB)) /* BUSY, MSL and SB flag */
#define I2C_EV6_MASTER_TRA_MODE_SELECTED ((uint32_t)(((I2C_SR2_MSL|I2C_SR2_BUSY|I2C_SR2_TRA)<< 16)|I2C_SR1_ADDR|I2C_SR1_TXE)) /* BUSY, MSL, ADDR, TXE and TRA flags */
#define I2C_EV6_MASTER_REC_MODE_SELECTED ((uint32_t)(((I2C_SR2_MSL|I2C_SR2_BUSY)<< 16)|I2C_SR1_ADDR)) /* BUSY, MSL and ADDR flags */
#define I2C_EV8_2_MASTER_BYTE_TRANSMITTED ((uint32_t)(((I2C_SR2_MSL | I2C_SR2_BUSY | I2C_SR2_TRA) << 16) | I2C_SR1_BTF | I2C_SR1_TXE)) /* TRA, BUSY, MSL, TXE and BTF flags */ #define I2C_EV8_2_MASTER_BYTE_TRANSMITTED ((uint32_t)(((I2C_SR2_MSL | I2C_SR2_BUSY | I2C_SR2_TRA) << 16) | I2C_SR1_BTF | I2C_SR1_TXE)) /* TRA, BUSY, MSL, TXE and BTF flags */
#define I2C_EV_MASK 0x00FFFFFF /* First byte zeroed because there is no need of PEC register part from SR2 */ #define I2C_EV_MASK 0x00FFFFFF /* First byte zeroed because there is no need of PEC register part from SR2 */
#define I2C_FLG_MASTER_RECEIVER 0x10 #define I2C_FLG_MASTER_RECEIVER 0x10
#define I2C_FLG_HEADER_SENT 0x80 #define I2C_FLG_HEADER_SENT 0x80
/** @brief error checks */
#if STM32_I2C_USE_I2C1 && !STM32_HAS_I2C1 #if STM32_I2C_USE_I2C1 && !STM32_HAS_I2C1
#error "I2C1 not present in the selected device" #error "I2C1 not present in the selected device"
#endif #endif
@ -197,57 +200,39 @@
#if STM32_I2C_USE_I2C1 && \ #if STM32_I2C_USE_I2C1 && \
!STM32_DMA_IS_VALID_ID(STM32_I2C_I2C1_RX_DMA_STREAM, \ !STM32_DMA_IS_VALID_ID(STM32_I2C_I2C1_RX_DMA_STREAM, \
STM32_I2C1_RX_DMA_MSK) STM32_I2C1_RX_DMA_MSK)
#error "invalid DMA stream associated to USART1 RX" #error "invalid DMA stream associated to I2C1 RX"
#endif #endif
#if STM32_I2C_USE_I2C1 && \ #if STM32_I2C_USE_I2C1 && \
!STM32_DMA_IS_VALID_ID(STM32_I2C_I2C1_TX_DMA_STREAM, \ !STM32_DMA_IS_VALID_ID(STM32_I2C_I2C1_TX_DMA_STREAM, \
STM32_I2C1_TX_DMA_MSK) STM32_I2C1_TX_DMA_MSK)
#error "invalid DMA stream associated to USART1 TX" #error "invalid DMA stream associated to I2C1 TX"
#endif #endif
#if STM32_I2C_USE_I2C2 && \ #if STM32_I2C_USE_I2C2 && \
!STM32_DMA_IS_VALID_ID(STM32_I2C_I2C2_RX_DMA_STREAM, \ !STM32_DMA_IS_VALID_ID(STM32_I2C_I2C2_RX_DMA_STREAM, \
STM32_I2C2_RX_DMA_MSK) STM32_I2C2_RX_DMA_MSK)
#error "invalid DMA stream associated to USART2 RX" #error "invalid DMA stream associated to I2C2 RX"
#endif #endif
#if STM32_I2C_USE_I2C2 && \ #if STM32_I2C_USE_I2C2 && \
!STM32_DMA_IS_VALID_ID(STM32_I2C_I2C2_TX_DMA_STREAM, \ !STM32_DMA_IS_VALID_ID(STM32_I2C_I2C2_TX_DMA_STREAM, \
STM32_I2C2_TX_DMA_MSK) STM32_I2C2_TX_DMA_MSK)
#error "invalid DMA stream associated to USART2 TX" #error "invalid DMA stream associated to I2C2 TX"
#endif #endif
#if STM32_I2C_USE_I2C3 && \ #if STM32_I2C_USE_I2C3 && \
!STM32_DMA_IS_VALID_ID(STM32_I2C_I2C3_RX_DMA_STREAM, \ !STM32_DMA_IS_VALID_ID(STM32_I2C_I2C3_RX_DMA_STREAM, \
STM32_I2C3_RX_DMA_MSK) STM32_I2C3_RX_DMA_MSK)
#error "invalid DMA stream associated to USART3 RX" #error "invalid DMA stream associated to I2C3 RX"
#endif #endif
#if STM32_I2C_USE_I2C3 && \ #if STM32_I2C_USE_I2C3 && \
!STM32_DMA_IS_VALID_ID(STM32_I2C_I2C3_TX_DMA_STREAM, \ !STM32_DMA_IS_VALID_ID(STM32_I2C_I2C3_TX_DMA_STREAM, \
STM32_I2C3_TX_DMA_MSK) STM32_I2C3_TX_DMA_MSK)
#error "invalid DMA stream associated to USART3 TX" #error "invalid DMA stream associated to I2C3 TX"
#endif #endif
#if !defined(STM32_DMA_REQUIRED) #if !defined(STM32_DMA_REQUIRED)
#define STM32_DMA_REQUIRED #define STM32_DMA_REQUIRED
#endif #endif
@ -300,22 +285,22 @@ struct I2CDriver{
/** /**
* @brief Driver state. * @brief Driver state.
*/ */
i2cstate_t id_state; i2cstate_t id_state;
#if I2C_USE_WAIT #if I2C_USE_WAIT
/** /**
* @brief Thread waiting for I/O completion. * @brief Thread waiting for I/O completion.
*/ */
Thread *id_thread; Thread *id_thread;
#endif /* I2C_USE_WAIT */ #endif /* I2C_USE_WAIT */
#if I2C_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__) #if I2C_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__)
#if CH_USE_MUTEXES || defined(__DOXYGEN__) #if CH_USE_MUTEXES || defined(__DOXYGEN__)
/** /**
* @brief Mutex protecting the bus. * @brief Mutex protecting the bus.
*/ */
Mutex id_mutex; Mutex id_mutex;
#elif CH_USE_SEMAPHORES #elif CH_USE_SEMAPHORES
Semaphore id_semaphore; Semaphore id_semaphore;
#endif #endif
#endif /* I2C_USE_MUTUAL_EXCLUSION */ #endif /* I2C_USE_MUTUAL_EXCLUSION */
@ -338,17 +323,13 @@ struct I2CDriver{
uint8_t slave_addr; /*!< @brief Current slave address without R/W bit. */ uint8_t slave_addr; /*!< @brief Current slave address without R/W bit. */
#if CH_USE_EVENTS
EventSource sevent; /*!< @brief Status Change @p EventSource.*/
#endif
/*********** End of the mandatory fields. **********************************/ /*********** End of the mandatory fields. **********************************/
uint32_t dmamode; /*!< @brief DMA mode bit mask.*/ uint32_t dmamode; /*!< @brief DMA mode bit mask.*/
const stm32_dma_stream_t *dmarx; /*!< @brief Receive DMA channel.*/ const stm32_dma_stream_t *dmarx; /*!< @brief Receive DMA channel.*/
const stm32_dma_stream_t *dmatx; /*!< @brief Transmit DMA channel.*/ const stm32_dma_stream_t *dmatx; /*!< @brief Transmit DMA channel.*/
I2C_TypeDef *id_i2c; /*!< @brief Pointer to the I2Cx registers block. */ I2C_TypeDef *id_i2c; /*!< @brief Pointer to the I2Cx registers block. */
}; };

View File

@ -292,15 +292,16 @@
/* I2C attributes.*/ /* I2C attributes.*/
#define STM32_HAS_I2C1 TRUE #define STM32_HAS_I2C1 TRUE
#define STM32_I2C1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 0) | \ #define STM32_I2C1_RX_DMA_MSK ((STM32_DMA_STREAM_ID_MSK(1, 0) | \
STM32_DMA_STREAM_ID_MSK(1, 5)) STM32_DMA_STREAM_ID_MSK(1, 5)))
#define STM32_I2C1_RX_DMA_CHN 0x00100001 #define STM32_I2C1_RX_DMA_CHN 0x00100001
#define STM32_I2C1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 7)) #define STM32_I2C1_TX_DMA_MSK ((STM32_DMA_STREAM_ID_MSK(1, 7)) | \
(STM32_DMA_STREAM_ID_MSK(1, 6)))
#define STM32_I2C1_TX_DMA_CHN 0x10000000 #define STM32_I2C1_TX_DMA_CHN 0x10000000
#define STM32_HAS_I2C2 TRUE #define STM32_HAS_I2C2 TRUE
#define STM32_I2C2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) | \ #define STM32_I2C2_RX_DMA_MSK ((STM32_DMA_STREAM_ID_MSK(1, 2) | \
STM32_DMA_STREAM_ID_MSK(1, 3)) STM32_DMA_STREAM_ID_MSK(1, 3)))
#define STM32_I2C2_RX_DMA_CHN 0x00007700 #define STM32_I2C2_RX_DMA_CHN 0x00007700
#define STM32_I2C2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 7)) #define STM32_I2C2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 7))
#define STM32_I2C2_TX_DMA_CHN 0x70000000 #define STM32_I2C2_TX_DMA_CHN 0x70000000

View File

@ -238,7 +238,6 @@ void i2cAddFlagsI(I2CDriver *i2cp, i2cflags_t mask) {
chDbgCheck(i2cp != NULL, "i2cAddFlagsI"); chDbgCheck(i2cp != NULL, "i2cAddFlagsI");
i2cp->errors |= mask; i2cp->errors |= mask;
chEvtBroadcastI(&i2cp->sevent);
} }
/** /**