I2C. Workaround allowing to read single byte on STM32 platforms except F1x.

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/stable_2.4.x@4554 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
barthess 2012-08-10 17:49:29 +00:00
parent b2197d1825
commit 5e3abcfd70
2 changed files with 14 additions and 26 deletions

View File

@ -290,31 +290,6 @@ static void i2c_lld_set_opmode(I2CDriver *i2cp) {
dp->CR1 = regCR1;
}
/**
* @brief Return the last event value from I2C status registers.
* @details Important but implicit destination of this function is
* clearing interrupts flags.
* @note Internal use only.
*
* @param[in] i2cp pointer to the @p I2CDriver object
*
* @notapi
*/
static uint32_t i2c_get_event(I2CDriver *i2cp) {
I2C_TypeDef *dp = i2cp->i2c;
uint16_t regSR1 = dp->SR1;
uint16_t regSR2 = dp->SR2;
#if CH_DBG_ENABLE_ASSERTS
dbgSR1 = regSR1;
dbgSR2 = regSR2;
dbgCR1 = dp->CR1;
dbgCR2 = dp->CR2;
#endif /* CH_DBG_ENABLE_ASSERTS */
return (I2C_EV_MASK & (regSR1 | (regSR2 << 16)));
}
/**
* @brief I2C shared ISR code.
*
@ -324,11 +299,13 @@ static uint32_t i2c_get_event(I2CDriver *i2cp) {
*/
static void i2c_lld_serve_event_interrupt(I2CDriver *i2cp) {
I2C_TypeDef *dp = i2cp->i2c;
uint32_t regSR = dp->SR2;
uint32_t event = dp->SR1;
/* Interrupts are disabled just before dmaStreamEnable() because there
is no need of interrupts until next transaction begin. All the work is
done by the DMA.*/
switch (i2c_get_event(i2cp)) {
switch (I2C_EV_MASK & (event | (regSR << 16))) {
case I2C_EV5_MASTER_MODE_SELECT:
dp->DR = i2cp->addr;
break;
@ -336,6 +313,8 @@ static void i2c_lld_serve_event_interrupt(I2CDriver *i2cp) {
dp->CR2 &= ~I2C_CR2_ITEVTEN;
dmaStreamEnable(i2cp->dmarx);
dp->CR2 |= I2C_CR2_LAST; /* Needed in receiver mode. */
if (dmaStreamGetTransactionSize(i2cp->dmarx) < 2)
dp->CR1 &= ~I2C_CR1_ACK;
break;
case I2C_EV6_MASTER_TRA_MODE_SELECTED:
dp->CR2 &= ~I2C_CR2_ITEVTEN;
@ -356,6 +335,9 @@ static void i2c_lld_serve_event_interrupt(I2CDriver *i2cp) {
default:
break;
}
/* Clear ADDR flag. */
if (event & (I2C_SR1_ADDR | I2C_SR1_ADD10))
(void)dp->SR2;
}
/**
@ -786,7 +768,9 @@ msg_t i2c_lld_master_receive_timeout(I2CDriver *i2cp, i2caddr_t addr,
I2C_TypeDef *dp = i2cp->i2c;
VirtualTimer vt;
#if defined(STM32F1XX)
chDbgCheck((rxbytes > 1), "i2c_lld_master_receive_timeout");
#endif
/* Global timeout for the whole operation.*/
if (timeout != TIME_INFINITE)
@ -865,8 +849,10 @@ msg_t i2c_lld_master_transmit_timeout(I2CDriver *i2cp, i2caddr_t addr,
I2C_TypeDef *dp = i2cp->i2c;
VirtualTimer vt;
#if defined(STM32F1XX)
chDbgCheck(((rxbytes == 0) || ((rxbytes > 1) && (rxbuf != NULL))),
"i2c_lld_master_transmit_timeout");
#endif
/* Global timeout for the whole operation.*/
if (timeout != TIME_INFINITE)

View File

@ -101,6 +101,8 @@
- NEW: Validated CAN driver on STM32F2/F4.
- Small fixes to the STM32F4 board files.
- Various documentation fixes and improvements.
- NEW: I2C workaround allowing to read single byte on STM32 platforms
except F1x.
*** 2.4.1 ***
- FIX: Fixed inconsistent LPCxxx Internal RC oscillator names (bug 3524138).