I2C. Merged changes from i2c_lld_2.zip

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3729 35acf78f-673a-0410-8e92-d51de3d6d3f4
master
barthess 2012-01-04 14:36:51 +00:00
parent c498fdc4d6
commit 3f685aa996
3 changed files with 36 additions and 53 deletions

View File

@ -210,28 +210,6 @@ static void i2c_lld_set_opmode(I2CDriver *i2cp) {
i2cp->i2c->CR1 = regCR1; i2cp->i2c->CR1 = regCR1;
} }
/**
* @brief Receive data via the I2C bus after writing.
*
* @param[in] i2cp pointer to the @p I2CDriver object
*
* @notapi
*/
static void i2c_lld_master_transceive(I2CDriver *i2cp) {
/* init driver fields */
i2cp->addr |= 0x01; /* LSB = 1 -> receive */
/* TODO: DMA error handling */
dmaStreamSetMemory0(i2cp->dmarx, i2cp->rxbuf);
dmaStreamSetTransactionSize(i2cp->dmarx, i2cp->rxbytes);
dmaStreamSetMode(i2cp->dmarx, ((i2cp->dmamode) | STM32_DMA_CR_DIR_P2M));
i2cp->i2c->CR1 |= I2C_CR1_START | I2C_CR1_ACK;
}
/** /**
* @brief Return the last event value from I2C status registers. * @brief Return the last event value from I2C status registers.
* @details Important but implicit destination of this function is * @details Important but implicit destination of this function is
@ -247,10 +225,10 @@ static uint32_t i2c_get_event(I2CDriver *i2cp) {
uint16_t regSR2 = i2cp->i2c->SR2; uint16_t regSR2 = i2cp->i2c->SR2;
#if CH_DBG_ENABLE_ASSERTS #if CH_DBG_ENABLE_ASSERTS
dbgSR1 = regSR1; dbgSR1 = regSR1;
dbgSR2 = regSR2; dbgSR2 = regSR2;
dbgCR1 = i2cp->i2c->CR1; dbgCR1 = i2cp->i2c->CR1;
dbgCR2 = i2cp->i2c->CR2; dbgCR2 = i2cp->i2c->CR2;
#endif /* CH_DBG_ENABLE_ASSERTS */ #endif /* CH_DBG_ENABLE_ASSERTS */
return (I2C_EV_MASK & (regSR1 | (regSR2 << 16))); return (I2C_EV_MASK & (regSR1 | (regSR2 << 16)));
@ -281,14 +259,14 @@ static void i2c_serve_event_interrupt(I2CDriver *i2cp) {
break; break;
case I2C_EV8_2_MASTER_BYTE_TRANSMITTED: case I2C_EV8_2_MASTER_BYTE_TRANSMITTED:
/* Catches BTF event after the end of transmission.*/ /* Catches BTF event after the end of transmission.*/
if (i2cp->rxbytes > 1) { if (dmaStreamGetTransactionSize(i2cp->dmarx) > 0) {
/* Starts "read after write" operation.*/ /* Starts "read after write" operation.*/
i2c_lld_master_transceive(i2cp); i2cp->addr |= 0x01; /* LSB = 1 -> receive */
i2cp->i2c->CR1 |= I2C_CR1_START | I2C_CR1_ACK;
return; return;
} }
else i2cp->i2c->CR1 |= I2C_CR1_STOP;
i2cp->i2c->CR1 |= I2C_CR1_STOP; i2c_lld_isr_code(i2cp);
i2c_lld_isr_code(i2cp);
break; break;
default: default:
break; break;
@ -371,7 +349,7 @@ static void i2c_serve_error_interrupt(I2CDriver *i2cp) {
errors |= I2CD_SMB_ALERT; errors |= I2CD_SMB_ALERT;
} }
/* If some error has been identified then sends wakes the waitingthread.*/ /* If some error has been identified then sends wakes the waiting thread.*/
if (errors != I2CD_NO_ERROR) { if (errors != I2CD_NO_ERROR) {
i2cp->errors |= errors; i2cp->errors |= errors;
i2c_lld_isr_err_code(i2cp); i2c_lld_isr_err_code(i2cp);
@ -413,6 +391,8 @@ CH_IRQ_HANDLER(I2C1_ER_IRQHandler) {
#if STM32_I2C_USE_I2C2 || defined(__DOXYGEN__) #if STM32_I2C_USE_I2C2 || defined(__DOXYGEN__)
/** /**
* @brief I2C2 event interrupt handler. * @brief I2C2 event interrupt handler.
*
* @notapi
*/ */
CH_IRQ_HANDLER(I2C2_EV_IRQHandler) { CH_IRQ_HANDLER(I2C2_EV_IRQHandler) {
@ -425,6 +405,8 @@ CH_IRQ_HANDLER(I2C2_EV_IRQHandler) {
/** /**
* @brief I2C2 error interrupt handler. * @brief I2C2 error interrupt handler.
*
* @notapi
*/ */
CH_IRQ_HANDLER(I2C2_ER_IRQHandler) { CH_IRQ_HANDLER(I2C2_ER_IRQHandler) {
@ -439,6 +421,8 @@ CH_IRQ_HANDLER(I2C2_ER_IRQHandler) {
#if STM32_I2C_USE_I2C3 || defined(__DOXYGEN__) #if STM32_I2C_USE_I2C3 || defined(__DOXYGEN__)
/** /**
* @brief I2C3 event interrupt handler. * @brief I2C3 event interrupt handler.
*
* @notapi
*/ */
CH_IRQ_HANDLER(I2C3_EV_IRQHandler) { CH_IRQ_HANDLER(I2C3_EV_IRQHandler) {
@ -451,6 +435,8 @@ CH_IRQ_HANDLER(I2C3_EV_IRQHandler) {
/** /**
* @brief I2C3 error interrupt handler. * @brief I2C3 error interrupt handler.
*
* @notapi
*/ */
CH_IRQ_HANDLER(I2C3_ER_IRQHandler) { CH_IRQ_HANDLER(I2C3_ER_IRQHandler) {
@ -472,21 +458,24 @@ void i2c_lld_init(void) {
#if STM32_I2C_USE_I2C1 #if STM32_I2C_USE_I2C1
i2cObjectInit(&I2CD1); i2cObjectInit(&I2CD1);
I2CD1.i2c = I2C1; I2CD1.thread = NULL;
I2CD1.i2c = I2C1;
I2CD1.dmarx = STM32_DMA_STREAM(STM32_I2C_I2C1_RX_DMA_STREAM); I2CD1.dmarx = STM32_DMA_STREAM(STM32_I2C_I2C1_RX_DMA_STREAM);
I2CD1.dmatx = STM32_DMA_STREAM(STM32_I2C_I2C1_TX_DMA_STREAM); I2CD1.dmatx = STM32_DMA_STREAM(STM32_I2C_I2C1_TX_DMA_STREAM);
#endif /* STM32_I2C_USE_I2C1 */ #endif /* STM32_I2C_USE_I2C1 */
#if STM32_I2C_USE_I2C2 #if STM32_I2C_USE_I2C2
i2cObjectInit(&I2CD2); i2cObjectInit(&I2CD2);
I2CD2.i2c = I2C2; I2CD2.thread = NULL;
I2CD2.i2c = I2C2;
I2CD2.dmarx = STM32_DMA_STREAM(STM32_I2C_I2C2_RX_DMA_STREAM); I2CD2.dmarx = STM32_DMA_STREAM(STM32_I2C_I2C2_RX_DMA_STREAM);
I2CD2.dmatx = STM32_DMA_STREAM(STM32_I2C_I2C2_TX_DMA_STREAM); I2CD2.dmatx = STM32_DMA_STREAM(STM32_I2C_I2C2_TX_DMA_STREAM);
#endif /* STM32_I2C_USE_I2C2 */ #endif /* STM32_I2C_USE_I2C2 */
#if STM32_I2C_USE_I2C3 #if STM32_I2C_USE_I2C3
i2cObjectInit(&I2CD3); i2cObjectInit(&I2CD3);
I2CD3.i2c = I2C3; I2CD3.thread = NULL;
I2CD3.i2c = I2C3;
I2CD3.dmarx = STM32_DMA_STREAM(STM32_I2C_I2C3_RX_DMA_STREAM); I2CD3.dmarx = STM32_DMA_STREAM(STM32_I2C_I2C3_RX_DMA_STREAM);
I2CD3.dmatx = STM32_DMA_STREAM(STM32_I2C_I2C3_TX_DMA_STREAM); I2CD3.dmatx = STM32_DMA_STREAM(STM32_I2C_I2C3_TX_DMA_STREAM);
#endif /* STM32_I2C_USE_I2C3 */ #endif /* STM32_I2C_USE_I2C3 */
@ -705,18 +694,17 @@ msg_t i2c_lld_master_receive_timeout(I2CDriver *i2cp, i2caddr_t addr,
/* Releases the lock from high level driver.*/ /* Releases the lock from high level driver.*/
chSysUnlock(); chSysUnlock();
chDbgCheck((rxbytes > 1), "i2c_lld_master_receive"); chDbgCheck((rxbytes > 1), "i2c_lld_master_receive_timeout");
/* Initializes driver fields, LSB = 1 -> receive.*/ /* Initializes driver fields, LSB = 1 -> receive.*/
i2cp->addr = (addr << 1) | 0x01; i2cp->addr = (addr << 1) | 0x01;
i2cp->rxbytes = rxbytes;
i2cp->rxbuf = rxbuf;
i2cp->errors = 0; i2cp->errors = 0;
/* TODO: DMA error handling */ /* TODO: DMA error handling */
/* RX DMA setup.*/
dmaStreamSetMemory0(i2cp->dmarx, rxbuf); dmaStreamSetMemory0(i2cp->dmarx, rxbuf);
dmaStreamSetTransactionSize(i2cp->dmarx, rxbytes); dmaStreamSetTransactionSize(i2cp->dmarx, rxbytes);
dmaStreamSetMode(i2cp->dmarx, ((i2cp->dmamode) | STM32_DMA_CR_DIR_P2M)); dmaStreamSetMode(i2cp->dmarx, i2cp->dmamode | STM32_DMA_CR_DIR_P2M);
/* Waits until BUSY flag is reset.*/ /* Waits until BUSY flag is reset.*/
volatile uint32_t tmo = 1 + (STM32_SYSCLK / 1000000) * 20; volatile uint32_t tmo = 1 + (STM32_SYSCLK / 1000000) * 20;
@ -778,18 +766,22 @@ msg_t i2c_lld_master_transmit_timeout(I2CDriver *i2cp, i2caddr_t addr,
chSysUnlock(); chSysUnlock();
chDbgCheck(((rxbytes == 0) || ((rxbytes > 1) && (rxbuf != NULL))), chDbgCheck(((rxbytes == 0) || ((rxbytes > 1) && (rxbuf != NULL))),
"i2cMasterTransmit"); "i2c_lld_master_transmit_timeout");
/* Initializes driver fields, LSB = 0 -> write.*/ /* Initializes driver fields, LSB = 0 -> write.*/
i2cp->addr = (addr << 1) & 0x00FE; i2cp->addr = addr << 1;
i2cp->rxbytes = rxbytes;
i2cp->rxbuf = rxbuf;
i2cp->errors = 0; i2cp->errors = 0;
/* TODO: DMA error handling */ /* TODO: DMA error handling */
/* TX DMA setup.*/
dmaStreamSetMemory0(i2cp->dmatx, txbuf); dmaStreamSetMemory0(i2cp->dmatx, txbuf);
dmaStreamSetTransactionSize(i2cp->dmatx, txbytes); dmaStreamSetTransactionSize(i2cp->dmatx, txbytes);
dmaStreamSetMode(i2cp->dmatx, ((i2cp->dmamode) | STM32_DMA_CR_DIR_M2P)); dmaStreamSetMode(i2cp->dmatx, i2cp->dmamode | STM32_DMA_CR_DIR_M2P);
/* RX DMA setup.*/
dmaStreamSetMemory0(i2cp->dmarx, rxbuf);
dmaStreamSetTransactionSize(i2cp->dmarx, rxbytes);
dmaStreamSetMode(i2cp->dmarx, i2cp->dmamode | STM32_DMA_CR_DIR_P2M);
/* Waits until BUSY flag is reset.*/ /* Waits until BUSY flag is reset.*/
volatile uint32_t tmo = 1 + (STM32_SYSCLK / 1000000) * 20; volatile uint32_t tmo = 1 + (STM32_SYSCLK / 1000000) * 20;

View File

@ -341,14 +341,6 @@ struct I2CDriver{
* @brief Thread waiting for I/O completion. * @brief Thread waiting for I/O completion.
*/ */
Thread *thread; Thread *thread;
/**
* @brief Number of bytes to receive in the receive phase.
*/
size_t rxbytes;
/**
* @brief Pointer to receive buffer.
*/
uint8_t *rxbuf;
/** /**
* @brief Current slave address without R/W bit. * @brief Current slave address without R/W bit.
*/ */

View File

@ -29,7 +29,6 @@
* @addtogroup I2C * @addtogroup I2C
* @{ * @{
*/ */
#include "ch.h" #include "ch.h"
#include "hal.h" #include "hal.h"