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-d51de3d6d3f4master
parent
c498fdc4d6
commit
3f685aa996
|
@ -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
|
||||||
|
@ -281,12 +259,12 @@ 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;
|
||||||
|
@ -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,6 +458,7 @@ void i2c_lld_init(void) {
|
||||||
|
|
||||||
#if STM32_I2C_USE_I2C1
|
#if STM32_I2C_USE_I2C1
|
||||||
i2cObjectInit(&I2CD1);
|
i2cObjectInit(&I2CD1);
|
||||||
|
I2CD1.thread = NULL;
|
||||||
I2CD1.i2c = I2C1;
|
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);
|
||||||
|
@ -479,6 +466,7 @@ void i2c_lld_init(void) {
|
||||||
|
|
||||||
#if STM32_I2C_USE_I2C2
|
#if STM32_I2C_USE_I2C2
|
||||||
i2cObjectInit(&I2CD2);
|
i2cObjectInit(&I2CD2);
|
||||||
|
I2CD2.thread = NULL;
|
||||||
I2CD2.i2c = I2C2;
|
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);
|
||||||
|
@ -486,6 +474,7 @@ void i2c_lld_init(void) {
|
||||||
|
|
||||||
#if STM32_I2C_USE_I2C3
|
#if STM32_I2C_USE_I2C3
|
||||||
i2cObjectInit(&I2CD3);
|
i2cObjectInit(&I2CD3);
|
||||||
|
I2CD3.thread = NULL;
|
||||||
I2CD3.i2c = I2C3;
|
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);
|
||||||
|
@ -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;
|
||||||
|
|
|
@ -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.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -29,7 +29,6 @@
|
||||||
* @addtogroup I2C
|
* @addtogroup I2C
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "ch.h"
|
#include "ch.h"
|
||||||
#include "hal.h"
|
#include "hal.h"
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue