aboutsummaryrefslogtreecommitdiffstats
path: root/os/hal
diff options
context:
space:
mode:
authorgdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2012-05-27 14:50:05 +0000
committergdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2012-05-27 14:50:05 +0000
commitc0cbc2411e6a7d347be5d20cffcca8d703bf6324 (patch)
tree79e35643886d8fe10e02ee7a3a334d9dc7d69b1c /os/hal
parent2b01d72e42576594924aa12fe50571cd56cafbb5 (diff)
downloadChibiOS-c0cbc2411e6a7d347be5d20cffcca8d703bf6324.tar.gz
ChibiOS-c0cbc2411e6a7d347be5d20cffcca8d703bf6324.tar.bz2
ChibiOS-c0cbc2411e6a7d347be5d20cffcca8d703bf6324.zip
Fixed bug 3530043.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@4244 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os/hal')
-rw-r--r--os/hal/include/i2c.h2
-rw-r--r--os/hal/platforms/STM32/i2c_lld.c40
2 files changed, 21 insertions, 21 deletions
diff --git a/os/hal/include/i2c.h b/os/hal/include/i2c.h
index 8b4d692fe..645729cc2 100644
--- a/os/hal/include/i2c.h
+++ b/os/hal/include/i2c.h
@@ -102,7 +102,7 @@ typedef enum {
*/
#define i2cMasterTransmit(i2cp, addr, txbuf, txbytes, rxbuf, rxbytes) \
(i2cMasterTransmitTimeout(i2cp, addr, txbuf, txbytes, rxbuf, rxbytes, \
- TIME_INFINITE))
+ TIME_INFINITE))
/**
* @brief Wrap i2cMasterReceiveTimeout function with TIME_INFINITE timeout.
diff --git a/os/hal/platforms/STM32/i2c_lld.c b/os/hal/platforms/STM32/i2c_lld.c
index 7458d9252..229520a91 100644
--- a/os/hal/platforms/STM32/i2c_lld.c
+++ b/os/hal/platforms/STM32/i2c_lld.c
@@ -165,13 +165,15 @@ static void i2c_lld_abort_operation(I2CDriver *i2cp) {
static void i2c_lld_safety_timeout(void *p) {
I2CDriver *i2cp = (I2CDriver *)p;
+ chSysLockFromIsr();
if (i2cp->thread) {
+ Thread *tp = i2cp->thread;
i2c_lld_abort_operation(i2cp);
- chSysLockFromIsr();
- i2cp->thread->p_u.rdymsg = RDY_TIMEOUT;
- chSchReadyI(i2cp->thread);
- chSysUnlockFromIsr();
+ i2cp->thread = NULL;
+ tp->p_u.rdymsg = RDY_TIMEOUT;
+ chSchReadyI(tp);
}
+ chSysUnlockFromIsr();
}
/**
@@ -768,12 +770,12 @@ msg_t i2c_lld_master_receive_timeout(I2CDriver *i2cp, i2caddr_t addr,
systime_t timeout) {
I2C_TypeDef *dp = i2cp->i2c;
VirtualTimer vt;
- msg_t rdymsg;
chDbgCheck((rxbytes > 1), "i2c_lld_master_receive_timeout");
/* Global timeout for the whole operation.*/
- chVTSetI(&vt, timeout, i2c_lld_safety_timeout, (void *)i2cp);
+ if (timeout != TIME_INFINITE)
+ chVTSetI(&vt, timeout, i2c_lld_safety_timeout, (void *)i2cp);
/* Releases the lock from high level driver.*/
chSysUnlock();
@@ -789,10 +791,10 @@ msg_t i2c_lld_master_receive_timeout(I2CDriver *i2cp, i2caddr_t addr,
/* Waits until BUSY flag is reset and the STOP from the previous operation
is completed, alternatively for a timeout condition.*/
while ((dp->SR2 & I2C_SR2_BUSY) || (dp->CR1 & I2C_CR1_STOP)) {
- if (!chVTIsArmedI(&vt)) {
- chSysLock();
+ chSysLock();
+ if (!chVTIsArmedI(&vt))
return RDY_TIMEOUT;
- }
+ chSysUnlock();
}
/* This lock will be released in high level driver.*/
@@ -810,11 +812,10 @@ msg_t i2c_lld_master_receive_timeout(I2CDriver *i2cp, i2caddr_t addr,
/* Waits for the operation completion or a timeout.*/
i2cp->thread = chThdSelf();
chSchGoSleepS(THD_STATE_SUSPENDED);
- rdymsg = chThdSelf()->p_u.rdymsg;
- if (rdymsg != RDY_TIMEOUT)
+ if (chVTIsArmedI(&vt))
chVTResetI(&vt);
- return rdymsg;
+ return chThdSelf()->p_u.rdymsg;
}
/**
@@ -848,13 +849,13 @@ msg_t i2c_lld_master_transmit_timeout(I2CDriver *i2cp, i2caddr_t addr,
systime_t timeout) {
I2C_TypeDef *dp = i2cp->i2c;
VirtualTimer vt;
- msg_t rdymsg;
chDbgCheck(((rxbytes == 0) || ((rxbytes > 1) && (rxbuf != NULL))),
"i2c_lld_master_transmit_timeout");
/* Global timeout for the whole operation.*/
- chVTSetI(&vt, timeout, i2c_lld_safety_timeout, (void *)i2cp);
+ if (timeout != TIME_INFINITE)
+ chVTSetI(&vt, timeout, i2c_lld_safety_timeout, (void *)i2cp);
/* Releases the lock from high level driver.*/
chSysUnlock();
@@ -874,10 +875,10 @@ msg_t i2c_lld_master_transmit_timeout(I2CDriver *i2cp, i2caddr_t addr,
/* Waits until BUSY flag is reset and the STOP from the previous operation
is completed, alternatively for a timeout condition.*/
while ((dp->SR2 & I2C_SR2_BUSY) || (dp->CR1 & I2C_CR1_STOP)) {
- if (!chVTIsArmedI(&vt)) {
- chSysLock();
+ chSysLock();
+ if (!chVTIsArmedI(&vt))
return RDY_TIMEOUT;
- }
+ chSysUnlock();
}
/* This lock will be released in high level driver.*/
@@ -895,11 +896,10 @@ msg_t i2c_lld_master_transmit_timeout(I2CDriver *i2cp, i2caddr_t addr,
/* Waits for the operation completion or a timeout.*/
i2cp->thread = chThdSelf();
chSchGoSleepS(THD_STATE_SUSPENDED);
- rdymsg = chThdSelf()->p_u.rdymsg;
- if (rdymsg != RDY_TIMEOUT)
+ if (chVTIsArmedI(&vt))
chVTResetI(&vt);
- return rdymsg;
+ return chThdSelf()->p_u.rdymsg;
}
#endif /* HAL_USE_I2C */