aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--os/hal/include/i2c.h2
-rw-r--r--os/hal/platforms/STM32/i2c_lld.c62
-rw-r--r--os/hal/src/i2c.c4
3 files changed, 45 insertions, 23 deletions
diff --git a/os/hal/include/i2c.h b/os/hal/include/i2c.h
index 774c0cf22..1e7ce3e1e 100644
--- a/os/hal/include/i2c.h
+++ b/os/hal/include/i2c.h
@@ -167,8 +167,10 @@ struct I2CSlaveConfig{
#define _i2c_wait_s(i2cp) { \
chDbgAssert((i2cp)->id_thread == NULL, \
"_i2c_wait(), #1", "already waiting"); \
+ chSysLock(); \
(i2cp)->id_thread = chThdSelf(); \
chSchGoSleepS(THD_STATE_SUSPENDED); \
+ chSysUnlock(); \
}
/**
diff --git a/os/hal/platforms/STM32/i2c_lld.c b/os/hal/platforms/STM32/i2c_lld.c
index 1c80cdb2f..b2e404c71 100644
--- a/os/hal/platforms/STM32/i2c_lld.c
+++ b/os/hal/platforms/STM32/i2c_lld.c
@@ -152,6 +152,10 @@ static void i2c_serve_event_interrupt(I2CDriver *i2cp) {
case 0:
dp->CR2 &= (uint16_t)~I2C_CR2_ITEVTEN;
dp->CR2 &= (uint16_t)~I2C_CR2_ITBUFEN;
+
+ regSR1 = dp->SR1;
+ regSR2 = dp->SR2;
+
/* Portable I2C ISR code defined in the high level driver, note, it is a macro.*/
_i2c_isr_code(i2cp, i2cp->id_slave_config);
break;
@@ -186,19 +190,31 @@ static void i2c_serve_event_interrupt(I2CDriver *i2cp) {
break;
case I2C_EV7_3_MASTER_REC_2BYTES_TO_PROCESS: /* only for case of two bytes to be received */
/* DataN-1 and DataN are received */
- chSysLockFromIsr();
+// chSysLockFromIsr();
dp->CR2 &= (uint16_t)~I2C_CR2_ITEVTEN;
dp->CR2 &= (uint16_t)~I2C_CR2_ITBUFEN;
/* Program the STOP */
dp->CR1 |= I2C_CR1_STOP;
/* Read the DataN-1*/
*rxBuffp = dp->DR;
- chSysUnlockFromIsr();
rxBuffp++;
/* Read the DataN*/
*rxBuffp = dp->DR;
i2cp->rxbytes = 0;
i2cp->flags = 0;
+
+ while(dp->CR1 & I2C_CR1_STOP){
+ ;
+ }
+
+ regSR1 = dp->SR1;
+ regSR2 = dp->SR2;
+
+ if((regSR1 + regSR2) > 0){
+ chDbgPanic("i2c_lld_master_receive");
+ }
+
+// chSysUnlockFromIsr();
/* Portable I2C ISR code defined in the high level driver, note, it is a macro.*/
_i2c_isr_code(i2cp, i2cp->id_slave_config);
break;
@@ -577,8 +593,6 @@ void i2c_lld_master_transmit(I2CDriver *i2cp, uint16_t slave_addr,
i2cp->flags = 0;
i2cp->errors = 0;
- /* enable ERR, EVT & BUF ITs */
- i2cp->id_i2c->CR2 |= (I2C_CR2_ITERREN|I2C_CR2_ITEVTEN|I2C_CR2_ITBUFEN);
i2cp->id_i2c->CR1 &= ~I2C_CR1_POS;
i2cp->id_i2c->CR1 |= I2C_CR1_START; /* send start bit */
@@ -592,14 +606,15 @@ void i2c_lld_master_transmit(I2CDriver *i2cp, uint16_t slave_addr,
//#endif /* I2C_USE_WAIT */
- uint32_t timeout = I2C_START_TIMEOUT;
- while((i2cp->id_i2c->CR1 & I2C_CR1_START) && timeout--)
- ;
- /* is timeout overflows? */
- chDbgAssert(timeout <= I2C_START_TIMEOUT,
- "i2c_lld_master_transmit(), #1", "time is out");
-
-
+// uint32_t timeout = I2C_START_TIMEOUT;
+// while((i2cp->id_i2c->CR1 & I2C_CR1_START) && timeout--)
+// ;
+// /* is timeout overflows? */
+// chDbgAssert(timeout <= I2C_START_TIMEOUT,
+// "i2c_lld_master_transmit(), #1", "time is out");
+//
+// /* enable ERR, EVT & BUF ITs */
+// i2cp->id_i2c->CR2 |= (I2C_CR2_ITERREN|I2C_CR2_ITEVTEN|I2C_CR2_ITBUFEN);
}
@@ -619,6 +634,10 @@ void i2c_lld_master_transmit(I2CDriver *i2cp, uint16_t slave_addr,
void i2c_lld_master_receive(I2CDriver *i2cp, uint16_t slave_addr,
uint8_t *rxbuf, size_t rxbytes){
+ if(i2cp->id_i2c->SR1 + i2cp->id_i2c->SR2 > 0){
+ chDbgPanic("i2c_lld_master_receive");
+ }
+
i2cp->slave_addr = slave_addr;
i2cp->rxbytes = rxbytes;
i2cp->rxbuf = rxbuf;
@@ -639,8 +658,6 @@ void i2c_lld_master_receive(I2CDriver *i2cp, uint16_t slave_addr,
i2cp->flags = I2C_FLG_MASTER_RECEIVER;
i2cp->errors = 0;
- /* 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;
@@ -665,12 +682,17 @@ void i2c_lld_master_receive(I2CDriver *i2cp, uint16_t slave_addr,
//#endif /* I2C_USE_WAIT */
+
uint32_t timeout = I2C_START_TIMEOUT;
while((i2cp->id_i2c->CR1 & I2C_CR1_START) && timeout--)
;
/* is timeout overflows? */
chDbgAssert(timeout <= I2C_START_TIMEOUT,
"i2c_lld_master_receive(), #1", "time is out");
+
+ /* enable ERR, EVT & BUF ITs */
+ i2cp->id_i2c->CR2 |= (I2C_CR2_ITERREN|I2C_CR2_ITEVTEN|I2C_CR2_ITBUFEN);
+
}
@@ -708,12 +730,12 @@ void i2c_lld_master_transceive(I2CDriver *i2cp){
//#endif /* I2C_USE_WAIT */
- uint32_t timeout = I2C_START_TIMEOUT;
- while((i2cp->id_i2c->CR1 & I2C_CR1_START) && timeout--)
- ;
- /* is timeout overflows? */
- chDbgAssert(timeout <= I2C_START_TIMEOUT,
- "i2c_lld_master_receive(), #1", "time is out");
+// uint32_t timeout = I2C_START_TIMEOUT;
+// while((i2cp->id_i2c->CR1 & I2C_CR1_START) && timeout--)
+// ;
+// /* is timeout overflows? */
+// chDbgAssert(timeout <= I2C_START_TIMEOUT,
+// "i2c_lld_master_receive(), #1", "time is out");
}
diff --git a/os/hal/src/i2c.c b/os/hal/src/i2c.c
index 4aade6fe9..4882330bd 100644
--- a/os/hal/src/i2c.c
+++ b/os/hal/src/i2c.c
@@ -178,11 +178,11 @@ void i2cMasterTransmit(I2CDriver *i2cp,
};
#endif /* CH_DBG_ENABLE_ASSERTS */
- chSysLock();
chDbgAssert(i2cp->id_state == I2C_READY,
"i2cMasterTransmit(), #1", "not ready");
i2cp->id_state = I2C_ACTIVE;
+ chSysLock();
i2c_lld_master_transmit(i2cp, slave_addr, txbuf, txbytes, rxbuf, rxbytes);
_i2c_wait_s(i2cp);
chSysUnlock();
@@ -226,14 +226,12 @@ void i2cMasterReceive(I2CDriver *i2cp,
};
#endif /* CH_DBG_ENABLE_ASSERTS */
- chSysLock();
chDbgAssert(i2cp->id_state == I2C_READY,
"i2cMasterReceive(), #1", "not ready");
i2cp->id_state = I2C_ACTIVE;
i2c_lld_master_receive(i2cp, slave_addr, rxbuf, rxbytes);
_i2c_wait_s(i2cp);
- chSysUnlock();
}