aboutsummaryrefslogtreecommitdiffstats
path: root/os/hal
diff options
context:
space:
mode:
authorbarthess <barthess@35acf78f-673a-0410-8e92-d51de3d6d3f4>2011-05-06 15:16:15 +0000
committerbarthess <barthess@35acf78f-673a-0410-8e92-d51de3d6d3f4>2011-05-06 15:16:15 +0000
commit60975ca7fed0e2960bced2fe72239422f8376068 (patch)
tree116f496bf509daccf541b8a10fc32d5dc49681a9 /os/hal
parent4fda4dc84fcfcfa483f10a8b5043d124ad551ba0 (diff)
downloadChibiOS-60975ca7fed0e2960bced2fe72239422f8376068.tar.gz
ChibiOS-60975ca7fed0e2960bced2fe72239422f8376068.tar.bz2
ChibiOS-60975ca7fed0e2960bced2fe72239422f8376068.zip
I2C. Some fixes.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/i2c_dev@2922 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os/hal')
-rw-r--r--os/hal/include/i2c.h11
-rw-r--r--os/hal/platforms/STM32/i2c_lld.c69
-rw-r--r--os/hal/platforms/STM32/i2c_lld.h14
-rw-r--r--os/hal/src/i2c.c11
4 files changed, 91 insertions, 14 deletions
diff --git a/os/hal/include/i2c.h b/os/hal/include/i2c.h
index 39ba313fd..6e740cfa9 100644
--- a/os/hal/include/i2c.h
+++ b/os/hal/include/i2c.h
@@ -204,7 +204,6 @@ struct I2CSlaveConfig{
} \
}
#else /* !I2C_USE_WAIT */
-#define i2c_lld_wait_bus_free(i2cp) //TODO: remove this STUB
#define _i2c_wait_s(i2cp)
#define _i2c_wakeup_isr(i2cp)
#endif /* !I2C_USE_WAIT */
@@ -223,12 +222,12 @@ struct I2CSlaveConfig{
*
* @notapi
*/
-#define _i2c_isr_code(i2cp, i2cscfg) { \
- (i2cp)->id_state = I2C_COMPLETE; \
+#define _i2c_isr_code(i2cp, i2cscfg) { \
+ (i2cp)->id_state = I2C_COMPLETE; \
if(((i2cp)->id_slave_config)->id_callback) { \
- ((i2cp)->id_slave_config)->id_callback(i2cp, i2cscfg); \
- } \
- _i2c_wakeup_isr(i2cp); \
+ ((i2cp)->id_slave_config)->id_callback(i2cp, i2cscfg); \
+ } \
+ _i2c_wakeup_isr(i2cp); \
}
/*===========================================================================*/
diff --git a/os/hal/platforms/STM32/i2c_lld.c b/os/hal/platforms/STM32/i2c_lld.c
index 6384300f7..7d48b01c8 100644
--- a/os/hal/platforms/STM32/i2c_lld.c
+++ b/os/hal/platforms/STM32/i2c_lld.c
@@ -94,11 +94,20 @@ static void i2c_serve_event_interrupt(I2CDriver *i2cp) {
}
break;
case I2C_EV8_2_MASTER_BYTE_TRANSMITTED:
- dp->CR1 |= I2C_CR1_STOP; // stop generation
- /* Disable ITEVT In order to not have again a BTF IT */
- dp->CR2 &= (uint16_t)~I2C_CR2_ITEVTEN;
- /* Portable I2C ISR code defined in the high level driver, note, it is a macro.*/
- _i2c_isr_code(i2cp, i2cp->id_slave_config);
+ /* if nothing to read then generate stop */
+ if (i2cp->id_slave_config->rx_remaining_bytes == 0){
+ dp->CR1 |= I2C_CR1_STOP; // stop generation
+ /* Disable ITEVT In order to not have again a BTF IT */
+ dp->CR2 &= (uint16_t)~I2C_CR2_ITEVTEN;
+ /* Portable I2C ISR code defined in the high level driver, note, it is a macro.*/
+ _i2c_isr_code(i2cp, i2cp->id_slave_config);
+ }
+ else{
+ /* Disable ITEVT In order to not have again a BTF IT */
+ dp->CR2 &= (uint16_t)~I2C_CR2_ITEVTEN;
+ /* send restart and begin reading operations */
+ i2c_lld_master_transceive(i2cp);
+ }
break;
@@ -550,7 +559,7 @@ void i2c_lld_master_receive(I2CDriver *i2cp){
i2cp->id_i2c->CR1 |= I2C_CR1_ACK; // acknowledge returned
i2cp->id_i2c->CR1 &= ~I2C_CR1_POS;
- switch(i2cp->nbit_address){
+ switch(i2cp->id_slave_config->nbit_address){
case 7:
i2cp->slave_addr1 = ((i2cp->id_slave_config->slave_addr <<1) | 0x01); // LSB = 1 -> receive
break;
@@ -586,4 +595,52 @@ void i2c_lld_master_receive(I2CDriver *i2cp){
+/**
+ * @brief
+ *
+ * @param[in] i2cp pointer to the @p I2CDriver object
+ *
+ */
+void i2c_lld_master_transceive(I2CDriver *i2cp){
+ uint32_t a, b;
+ // enable ERR, EVT & BUF ITs
+ i2cp->id_i2c->CR2 |= (I2C_CR2_ITERREN|I2C_CR2_ITEVTEN|I2C_CR2_ITBUFEN);
+ i2cp->id_i2c->CR1 |= I2C_CR1_ACK; // acknowledge returned
+ i2cp->id_i2c->CR1 &= ~I2C_CR1_POS;
+
+ switch(i2cp->id_slave_config->nbit_address){
+ case 7:
+ i2cp->slave_addr1 = ((i2cp->id_slave_config->slave_addr <<1) | 0x01); // LSB = 1 -> receive
+ break;
+ case 10:
+ i2cp->slave_addr1 = ((i2cp->id_slave_config->slave_addr >>7) & 0x0006); // add the two msb of 10-bit address to the header
+ i2cp->slave_addr1 |= 0xF0; // add the header bits (the LSB -> 1 will be add to second
+ i2cp->slave_addr2 = i2cp->id_slave_config->slave_addr & 0x00FF; // the remaining 8 bit of 10-bit address
+ break;
+ }
+
+ i2cp->id_slave_config->flags = I2C_FLG_MASTER_RECEIVER;
+ i2cp->id_slave_config->errors = 0;
+
+ // Only one byte to be received
+ if(i2cp->id_slave_config->rx_remaining_bytes == 1) {
+ i2cp->id_slave_config->flags |= I2C_FLG_1BTR;
+ }
+ // Only two bytes to be received
+ else if(i2cp->id_slave_config->rx_remaining_bytes == 2) {
+ i2cp->id_slave_config->flags |= I2C_FLG_2BTR;
+ i2cp->id_i2c->CR1 |= I2C_CR1_POS; // Acknowledge Position
+ }
+
+ i2cp->id_i2c->CR1 |= I2C_CR1_START; // send start bit
+
+#if !I2C_USE_WAIT
+ /* Wait until the START condition is generated on the bus: the START bit is cleared by hardware */
+ uint32_t timeout = 0xfffff;
+ while((i2cp->id_i2c->CR1 & I2C_CR1_START) && timeout--)
+ ;
+#endif /* I2C_USE_WAIT */
+}
+
+
#endif // HAL_USE_I2C
diff --git a/os/hal/platforms/STM32/i2c_lld.h b/os/hal/platforms/STM32/i2c_lld.h
index 268e7264d..00c6410fa 100644
--- a/os/hal/platforms/STM32/i2c_lld.h
+++ b/os/hal/platforms/STM32/i2c_lld.h
@@ -185,6 +185,19 @@ struct I2CDriver{
/* Driver macros. */
/*===========================================================================*/
+#define i2c_lld_bus_is_busy(i2cp) \
+ (i2cp->id_i2c->SR2 & I2C_SR2_BUSY)
+
+
+/* Wait until BUSY flag is reset: a STOP has been generated on the bus
+ * signaling the end of transmission
+ */
+#define i2c_lld_wait_bus_free(i2cp) { \
+ uint32_t tmo = 0xffff; \
+ while((i2cp->id_i2c->SR2 & I2C_SR2_BUSY) && tmo--) \
+ ; \
+}
+
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
@@ -211,6 +224,7 @@ void i2c_lld_start(I2CDriver *i2cp);
void i2c_lld_stop(I2CDriver *i2cp);
void i2c_lld_master_transmit(I2CDriver *i2cp);
void i2c_lld_master_receive(I2CDriver *i2cp);
+void i2c_lld_master_transceive(I2CDriver *i2cp);
#ifdef __cplusplus
}
diff --git a/os/hal/src/i2c.c b/os/hal/src/i2c.c
index 50767b3a9..1a2873a29 100644
--- a/os/hal/src/i2c.c
+++ b/os/hal/src/i2c.c
@@ -140,11 +140,14 @@ void i2cMasterTransmit(I2CDriver *i2cp, I2CSlaveConfig *i2cscfg) {
size_t n;
i2cblock_t *txbuf;
+ uint8_t nbit_addr;
txbuf = i2cscfg->txbuf;
+ nbit_addr = i2cscfg->nbit_address;
n = i2cscfg->tx_remaining_bytes;
- chDbgCheck((i2cp != NULL) && (i2cscfg != NULL) && (n > 0) && (txbuf != NULL),
+ chDbgCheck((i2cp != NULL) && (i2cscfg != NULL) && \
+ ((nbit_addr == 7) || (nbit_addr == 10)) && (n > 0) && (txbuf != NULL),
"i2cMasterTransmit");
// init slave config field in driver
@@ -186,11 +189,14 @@ void i2cMasterReceive(I2CDriver *i2cp, I2CSlaveConfig *i2cscfg){
size_t n;
i2cblock_t *rxbuf;
+ uint8_t nbit_addr;
rxbuf = i2cscfg->rxbuf;
n = i2cscfg->rx_remaining_bytes;
+ nbit_addr = i2cscfg->nbit_address;
- chDbgCheck((i2cp != NULL) && (n > 0) && (rxbuf != NULL),
+ chDbgCheck((i2cp != NULL) && (i2cscfg != NULL) && (n > 0) && \
+ ((nbit_addr == 7) || (nbit_addr == 10)) && (rxbuf != NULL),
"i2cMasterReceive");
// init slave config field in driver
@@ -221,6 +227,7 @@ void i2cMasterReceive(I2CDriver *i2cp, I2CSlaveConfig *i2cscfg){
chSysUnlock();
}
+
uint16_t i2cSMBusAlertResponse(I2CDriver *i2cp, I2CSlaveConfig *i2cscfg) {
i2cMasterReceive(i2cp, i2cscfg);