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; 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. * @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) { static void i2c_lld_serve_event_interrupt(I2CDriver *i2cp) {
I2C_TypeDef *dp = i2cp->i2c; I2C_TypeDef *dp = i2cp->i2c;
uint32_t regSR = dp->SR2;
uint32_t event = dp->SR1;
/* Interrupts are disabled just before dmaStreamEnable() because there /* Interrupts are disabled just before dmaStreamEnable() because there
is no need of interrupts until next transaction begin. All the work is is no need of interrupts until next transaction begin. All the work is
done by the DMA.*/ done by the DMA.*/
switch (i2c_get_event(i2cp)) { switch (I2C_EV_MASK & (event | (regSR << 16))) {
case I2C_EV5_MASTER_MODE_SELECT: case I2C_EV5_MASTER_MODE_SELECT:
dp->DR = i2cp->addr; dp->DR = i2cp->addr;
break; break;
@ -336,6 +313,8 @@ static void i2c_lld_serve_event_interrupt(I2CDriver *i2cp) {
dp->CR2 &= ~I2C_CR2_ITEVTEN; dp->CR2 &= ~I2C_CR2_ITEVTEN;
dmaStreamEnable(i2cp->dmarx); dmaStreamEnable(i2cp->dmarx);
dp->CR2 |= I2C_CR2_LAST; /* Needed in receiver mode. */ dp->CR2 |= I2C_CR2_LAST; /* Needed in receiver mode. */
if (dmaStreamGetTransactionSize(i2cp->dmarx) < 2)
dp->CR1 &= ~I2C_CR1_ACK;
break; break;
case I2C_EV6_MASTER_TRA_MODE_SELECTED: case I2C_EV6_MASTER_TRA_MODE_SELECTED:
dp->CR2 &= ~I2C_CR2_ITEVTEN; dp->CR2 &= ~I2C_CR2_ITEVTEN;
@ -356,6 +335,9 @@ static void i2c_lld_serve_event_interrupt(I2CDriver *i2cp) {
default: default:
break; 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; I2C_TypeDef *dp = i2cp->i2c;
VirtualTimer vt; VirtualTimer vt;
#if defined(STM32F1XX)
chDbgCheck((rxbytes > 1), "i2c_lld_master_receive_timeout"); chDbgCheck((rxbytes > 1), "i2c_lld_master_receive_timeout");
#endif
/* Global timeout for the whole operation.*/ /* Global timeout for the whole operation.*/
if (timeout != TIME_INFINITE) 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; I2C_TypeDef *dp = i2cp->i2c;
VirtualTimer vt; VirtualTimer vt;
#if defined(STM32F1XX)
chDbgCheck(((rxbytes == 0) || ((rxbytes > 1) && (rxbuf != NULL))), chDbgCheck(((rxbytes == 0) || ((rxbytes > 1) && (rxbuf != NULL))),
"i2c_lld_master_transmit_timeout"); "i2c_lld_master_transmit_timeout");
#endif
/* Global timeout for the whole operation.*/ /* Global timeout for the whole operation.*/
if (timeout != TIME_INFINITE) if (timeout != TIME_INFINITE)

View File

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