diff options
author | barthess <barthess@35acf78f-673a-0410-8e92-d51de3d6d3f4> | 2011-01-26 22:36:12 +0000 |
---|---|---|
committer | barthess <barthess@35acf78f-673a-0410-8e92-d51de3d6d3f4> | 2011-01-26 22:36:12 +0000 |
commit | 9babeb847e50141bb378b77e987d8bc25c33a6d1 (patch) | |
tree | e05c490f820a4cf4713f3c2a0ab21a25ce0c6eec /os | |
parent | 9c45802837b9053bbe32a8c8d5688cbf8c5d2706 (diff) | |
download | ChibiOS-9babeb847e50141bb378b77e987d8bc25c33a6d1.tar.gz ChibiOS-9babeb847e50141bb378b77e987d8bc25c33a6d1.tar.bz2 ChibiOS-9babeb847e50141bb378b77e987d8bc25c33a6d1.zip |
I2C. Rewriting low level driver to handle IRQs and DMA
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/i2c_dev@2687 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os')
-rw-r--r-- | os/hal/include/i2c.h | 11 | ||||
-rw-r--r-- | os/hal/platforms/STM32/i2c_lld.c | 32 | ||||
-rw-r--r-- | os/hal/platforms/STM32/i2c_lld.h | 4 |
3 files changed, 37 insertions, 10 deletions
diff --git a/os/hal/include/i2c.h b/os/hal/include/i2c.h index 73bab57f4..e93f2249c 100644 --- a/os/hal/include/i2c.h +++ b/os/hal/include/i2c.h @@ -61,10 +61,13 @@ typedef enum { I2C_UNINIT = 0, /**< Not initialized. */
I2C_STOP = 1, /**< Stopped. */
I2C_READY = 2, /**< Ready. */
- I2C_MREADY = 3, /**< START and address sent. */
- I2C_MTRANSMIT = 4, /**< Master transmitting. */
- I2C_MRECEIVE = 5, /**< Master receiving. */
- I2C_MERROR = 6 /**< Error condition. */
+
+ I2C_MACTIVE = 3, /**< START condition sent. */
+ I2C_MTXREADY = 4, /**< address sent when tx-flag set. */
+ I2C_MTRANSMIT = 5, /**< Master transmitting. */
+
+ I2C_MRECEIVE = 6, /**< Master receiving. */
+ I2C_MERROR = 7 /**< Error condition. */
} i2cstate_t;
#include "i2c_lld.h"
diff --git a/os/hal/platforms/STM32/i2c_lld.c b/os/hal/platforms/STM32/i2c_lld.c index c1b932748..8802d5af4 100644 --- a/os/hal/platforms/STM32/i2c_lld.c +++ b/os/hal/platforms/STM32/i2c_lld.c @@ -63,9 +63,30 @@ static i2cflags_t translate_errors(uint16_t sr) { static void i2c_serve_event_interrupt(I2CDriver *i2cp) { + // TODO: enable interrupts in config registers + if ((i2cp->id_state == I2C_READY) && (i2cp->id_i2c->SR1 & I2C_SR1_SB)){// start bit sent + i2cp->id_state = I2C_MACTIVE; + i2cp->id_i2c->DR = (i2cp->id_slave_config->slave_addr1 << 1) | + i2cp->id_slave_config->rw_bit; // write slave address in DR + } + + // now wait interrupt with ADDR flag + // TODO: 10 bit address handling here + if ((i2cp->id_state == I2C_MACTIVE) && (i2cp->id_i2c->SR1 & I2C_SR1_ADDR)){// address successfully sent + if(i2cp->id_slave_config->rw_bit == I2C_WRITE){ + i2cp->id_state = I2C_MTRANSMIT; + // TODO: setup here transmission via DMA like in ADC + } + else { + i2cp->id_state = I2C_MRECEIVE; + // TODO: setup here transmission via DMA like in ADC + } + } } + + static void i2c_serve_error_interrupt(I2CDriver *i2cp) { } @@ -218,15 +239,14 @@ void i2c_lld_stop(I2CDriver *i2cp) { void i2c_lld_master_transmit(I2CDriver *i2cp, I2CSlaveConfig *i2cscfg, bool_t restart) { //TODO: check txbytes <= sizeof(i2cscfg->txbuf) here, or in hylevel API - chSysLock(); - int i = 0; i2cp->id_slave_config = i2cscfg; + i2cp->id_slave_config->rw_bit = I2C_WRITE; + + //TODO: setup DMA channel here i2cp->id_i2c->CR1 |= I2C_CR1_START; // generate start condition - while (!(i2cp->id_i2c->SR1 & I2C_SR1_SB)){ - i++; // wait start bit - } + i2cp->id_i2c->DR = (i2cp->id_slave_config->slave_addr1 << 1) | I2C_WRITE; // write slave addres in DR while (!(i2cp->id_i2c->SR1 & I2C_SR1_ADDR)){ @@ -256,7 +276,7 @@ void i2c_lld_master_transmit(I2CDriver *i2cp, I2CSlaveConfig *i2cscfg, bool_t re } else i2cp->id_i2c->CR1 |= I2C_CR1_STOP; // generate stop condition - chSysUnlock(); + } /** diff --git a/os/hal/platforms/STM32/i2c_lld.h b/os/hal/platforms/STM32/i2c_lld.h index 427e72896..0179ba0e8 100644 --- a/os/hal/platforms/STM32/i2c_lld.h +++ b/os/hal/platforms/STM32/i2c_lld.h @@ -150,6 +150,10 @@ typedef struct { uint16_t error_flags; + uint8_t rw_bit; // this flag contain R/W bit + + bool_t restart; // send restart or stop event after complete data tx/rx + }I2CSlaveConfig; |