aboutsummaryrefslogtreecommitdiffstats
path: root/os
diff options
context:
space:
mode:
authorbarthess <barthess@35acf78f-673a-0410-8e92-d51de3d6d3f4>2011-01-26 22:36:12 +0000
committerbarthess <barthess@35acf78f-673a-0410-8e92-d51de3d6d3f4>2011-01-26 22:36:12 +0000
commit9babeb847e50141bb378b77e987d8bc25c33a6d1 (patch)
treee05c490f820a4cf4713f3c2a0ab21a25ce0c6eec /os
parent9c45802837b9053bbe32a8c8d5688cbf8c5d2706 (diff)
downloadChibiOS-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.h11
-rw-r--r--os/hal/platforms/STM32/i2c_lld.c32
-rw-r--r--os/hal/platforms/STM32/i2c_lld.h4
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;