From 675296b85232a6139da384f63bb829f9182029da Mon Sep 17 00:00:00 2001 From: gdisirio Date: Tue, 2 Apr 2013 17:28:18 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@5536 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/include/i2c.h | 5 +- os/hal/platforms/STM32/I2Cv1/i2c_lld.c | 84 +++++++++++++++++----------------- testhal/STM32F4xx/I2C/.cproject | 51 +++++++++++++++++++++ testhal/STM32F4xx/I2C/.project | 38 +++++++++++++++ 4 files changed, 136 insertions(+), 42 deletions(-) create mode 100644 testhal/STM32F4xx/I2C/.cproject create mode 100644 testhal/STM32F4xx/I2C/.project diff --git a/os/hal/include/i2c.h b/os/hal/include/i2c.h index b3a9ffdff..2e45450ee 100644 --- a/os/hal/include/i2c.h +++ b/os/hal/include/i2c.h @@ -48,7 +48,10 @@ #define I2CD_ARBITRATION_LOST 0x02 /**< @brief Arbitration Lost. */ #define I2CD_ACK_FAILURE 0x04 /**< @brief Acknowledge Failure. */ #define I2CD_OVERRUN 0x08 /**< @brief Overrun/Underrun. */ -#define I2CD_TIMEOUT 0x10 /**< @brief Hardware timeout. */ +#define I2CD_PEC_ERROR 0x10 /**< @brief PEC Error in + reception. */ +#define I2CD_TIMEOUT 0x20 /**< @brief Hardware timeout. */ +#define I2CD_SMB_ALERT 0x40 /**< @brief SMBus Alert. */ /** @} */ /*===========================================================================*/ diff --git a/os/hal/platforms/STM32/I2Cv1/i2c_lld.c b/os/hal/platforms/STM32/I2Cv1/i2c_lld.c index 9e8b5ef86..fbf1c1f71 100644 --- a/os/hal/platforms/STM32/I2Cv1/i2c_lld.c +++ b/os/hal/platforms/STM32/I2Cv1/i2c_lld.c @@ -65,16 +65,24 @@ #define I2C_EV5_MASTER_MODE_SELECT \ ((uint32_t)(((I2C_SR2_MSL | I2C_SR2_BUSY) << 16) | I2C_SR1_SB)) + #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)) + #define I2C_EV6_MASTER_REC_MODE_SELECTED \ ((uint32_t)(((I2C_SR2_MSL|I2C_SR2_BUSY)<< 16) | I2C_SR1_ADDR)) + #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)) + #define I2C_EV_MASK 0x00FFFFFF +#define I2C_ERROR_MASK \ + ((uint16_t)(I2C_SR1_BERR | I2C_SR1_ARLO | I2C_SR1_AF | I2C_SR1_OVR | \ + I2C_SR1_PECERR | I2C_SR1_TIMEOUT | I2C_SR1_SMBALERT)) + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ @@ -380,57 +388,45 @@ static void i2c_lld_serve_tx_end_irq(I2CDriver *i2cp, uint32_t flags) { * @brief I2C error handler. * * @param[in] i2cp pointer to the @p I2CDriver object + * @param[in] sr content of the SR1 register to be decoded * * @notapi */ -static void i2c_lld_serve_error_interrupt(I2CDriver *i2cp) { - I2C_TypeDef *dp = i2cp->i2c; - i2cflags_t errors; +static void i2c_lld_serve_error_interrupt(I2CDriver *i2cp, uint16_t sr) { /* Clears interrupt flags just to be safe.*/ - chSysLockFromIsr(); dmaStreamDisable(i2cp->dmatx); dmaStreamDisable(i2cp->dmarx); - chSysUnlockFromIsr(); - errors = I2CD_NO_ERROR; + i2cp->errors = I2CD_NO_ERROR; - if (dp->SR1 & I2C_SR1_BERR) { /* Bus error. */ - dp->SR1 &= ~I2C_SR1_BERR; - errors |= I2CD_BUS_ERROR; - } - if (dp->SR1 & I2C_SR1_ARLO) { /* Arbitration lost. */ - dp->SR1 &= ~I2C_SR1_ARLO; - errors |= I2CD_ARBITRATION_LOST; - } - if (dp->SR1 & I2C_SR1_AF) { /* Acknowledge fail. */ - dp->SR1 &= ~I2C_SR1_AF; - dp->CR2 &= ~I2C_CR2_ITEVTEN; - dp->CR1 |= I2C_CR1_STOP; /* Setting stop bit. */ - errors |= I2CD_ACK_FAILURE; - } - if (dp->SR1 & I2C_SR1_OVR) { /* Overrun. */ - dp->SR1 &= ~I2C_SR1_OVR; - errors |= I2CD_OVERRUN; - } - if (dp->SR1 & I2C_SR1_PECERR) { /* PEC error. */ - dp->SR1 &= ~I2C_SR1_PECERR; - errors |= I2CD_PEC_ERROR; - } - if (dp->SR1 & I2C_SR1_TIMEOUT) { /* SMBus Timeout. */ - dp->SR1 &= ~I2C_SR1_TIMEOUT; - errors |= I2CD_TIMEOUT; - } - if (dp->SR1 & I2C_SR1_SMBALERT) { /* SMBus alert. */ - dp->SR1 &= ~I2C_SR1_SMBALERT; - errors |= I2CD_SMB_ALERT; + if (sr & I2C_SR1_BERR) /* Bus error. */ + i2cp->errors |= I2CD_BUS_ERROR; + + if (sr & I2C_SR1_ARLO) /* Arbitration lost. */ + i2cp->errors |= I2CD_ARBITRATION_LOST; + + if (sr & I2C_SR1_AF) { /* Acknowledge fail. */ + i2cp->i2c->CR2 &= ~I2C_CR2_ITEVTEN; + i2cp->i2c->CR1 |= I2C_CR1_STOP; /* Setting stop bit. */ + i2cp->errors |= I2CD_ACK_FAILURE; } + if (sr & I2C_SR1_OVR) /* Overrun. */ + i2cp->errors |= I2CD_OVERRUN; + + if (sr & I2C_SR1_TIMEOUT) /* SMBus Timeout. */ + i2cp->errors |= I2CD_TIMEOUT; + + if (sr & I2C_SR1_PECERR) /* PEC error. */ + i2cp->errors |= I2CD_PEC_ERROR; + + if (sr & I2C_SR1_SMBALERT) /* SMBus alert. */ + i2cp->errors |= I2CD_SMB_ALERT; + /* If some error has been identified then sends wakes the waiting thread.*/ - if (errors != I2CD_NO_ERROR) { - i2cp->errors = errors; + if (i2cp->errors != I2CD_NO_ERROR) wakeup_isr(i2cp, RDY_RESET); - } } /*===========================================================================*/ @@ -456,10 +452,12 @@ CH_IRQ_HANDLER(I2C1_EV_IRQHandler) { * @brief I2C1 error interrupt handler. */ CH_IRQ_HANDLER(I2C1_ER_IRQHandler) { + uint16_t sr = I2CD1.i2c->SR1; CH_IRQ_PROLOGUE(); - i2c_lld_serve_error_interrupt(&I2CD1); + I2CD1.i2c->SR1 = ~(sr & I2C_ERROR_MASK); + i2c_lld_serve_error_interrupt(&I2CD1, sr); CH_IRQ_EPILOGUE(); } @@ -486,10 +484,12 @@ CH_IRQ_HANDLER(I2C2_EV_IRQHandler) { * @notapi */ CH_IRQ_HANDLER(I2C2_ER_IRQHandler) { + uint16_t sr = I2CD2.i2c->SR1; CH_IRQ_PROLOGUE(); - i2c_lld_serve_error_interrupt(&I2CD2); + I2CD2.i2c->SR1 = ~(sr & I2C_ERROR_MASK); + i2c_lld_serve_error_interrupt(&I2CD2, sr); CH_IRQ_EPILOGUE(); } @@ -516,10 +516,12 @@ CH_IRQ_HANDLER(I2C3_EV_IRQHandler) { * @notapi */ CH_IRQ_HANDLER(I2C3_ER_IRQHandler) { + uint16_t sr = I2CD3.i2c->SR1; CH_IRQ_PROLOGUE(); - i2c_lld_serve_error_interrupt(&I2CD3); + I2CD3.i2c->SR1 = ~(sr & I2C_ERROR_MASK); + i2c_lld_serve_error_interrupt(&I2CD3, sr); CH_IRQ_EPILOGUE(); } diff --git a/testhal/STM32F4xx/I2C/.cproject b/testhal/STM32F4xx/I2C/.cproject new file mode 100644 index 000000000..5effe9a53 --- /dev/null +++ b/testhal/STM32F4xx/I2C/.cproject @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/testhal/STM32F4xx/I2C/.project b/testhal/STM32F4xx/I2C/.project new file mode 100644 index 000000000..c506abb10 --- /dev/null +++ b/testhal/STM32F4xx/I2C/.project @@ -0,0 +1,38 @@ + + + STM32F4xx-I2C + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + board + 2 + CHIBIOS/boards/NONSTANDARD_STM32F4_BARTHESS1 + + + os + 2 + CHIBIOS/os + + + -- cgit v1.2.3