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:
parent
d34bc423c8
commit
2db3c769f1
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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. */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue