I2C. Driver still cause stack overflows.

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/i2c_dev@3134 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
barthess 2011-07-07 21:53:01 +00:00
parent ff535c27e6
commit 6eca655484
3 changed files with 45 additions and 23 deletions

View File

@ -167,8 +167,10 @@ struct I2CSlaveConfig{
#define _i2c_wait_s(i2cp) { \ #define _i2c_wait_s(i2cp) { \
chDbgAssert((i2cp)->id_thread == NULL, \ chDbgAssert((i2cp)->id_thread == NULL, \
"_i2c_wait(), #1", "already waiting"); \ "_i2c_wait(), #1", "already waiting"); \
chSysLock(); \
(i2cp)->id_thread = chThdSelf(); \ (i2cp)->id_thread = chThdSelf(); \
chSchGoSleepS(THD_STATE_SUSPENDED); \ chSchGoSleepS(THD_STATE_SUSPENDED); \
chSysUnlock(); \
} }
/** /**

View File

@ -152,6 +152,10 @@ static void i2c_serve_event_interrupt(I2CDriver *i2cp) {
case 0: case 0:
dp->CR2 &= (uint16_t)~I2C_CR2_ITEVTEN; dp->CR2 &= (uint16_t)~I2C_CR2_ITEVTEN;
dp->CR2 &= (uint16_t)~I2C_CR2_ITBUFEN; 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.*/ /* Portable I2C ISR code defined in the high level driver, note, it is a macro.*/
_i2c_isr_code(i2cp, i2cp->id_slave_config); _i2c_isr_code(i2cp, i2cp->id_slave_config);
break; break;
@ -186,19 +190,31 @@ static void i2c_serve_event_interrupt(I2CDriver *i2cp) {
break; break;
case I2C_EV7_3_MASTER_REC_2BYTES_TO_PROCESS: /* only for case of two bytes to be received */ case I2C_EV7_3_MASTER_REC_2BYTES_TO_PROCESS: /* only for case of two bytes to be received */
/* DataN-1 and DataN are received */ /* DataN-1 and DataN are received */
chSysLockFromIsr(); // chSysLockFromIsr();
dp->CR2 &= (uint16_t)~I2C_CR2_ITEVTEN; dp->CR2 &= (uint16_t)~I2C_CR2_ITEVTEN;
dp->CR2 &= (uint16_t)~I2C_CR2_ITBUFEN; dp->CR2 &= (uint16_t)~I2C_CR2_ITBUFEN;
/* Program the STOP */ /* Program the STOP */
dp->CR1 |= I2C_CR1_STOP; dp->CR1 |= I2C_CR1_STOP;
/* Read the DataN-1*/ /* Read the DataN-1*/
*rxBuffp = dp->DR; *rxBuffp = dp->DR;
chSysUnlockFromIsr();
rxBuffp++; rxBuffp++;
/* Read the DataN*/ /* Read the DataN*/
*rxBuffp = dp->DR; *rxBuffp = dp->DR;
i2cp->rxbytes = 0; i2cp->rxbytes = 0;
i2cp->flags = 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.*/ /* Portable I2C ISR code defined in the high level driver, note, it is a macro.*/
_i2c_isr_code(i2cp, i2cp->id_slave_config); _i2c_isr_code(i2cp, i2cp->id_slave_config);
break; break;
@ -577,8 +593,6 @@ void i2c_lld_master_transmit(I2CDriver *i2cp, uint16_t slave_addr,
i2cp->flags = 0; i2cp->flags = 0;
i2cp->errors = 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_POS;
i2cp->id_i2c->CR1 |= I2C_CR1_START; /* send start bit */ 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 */ //#endif /* I2C_USE_WAIT */
uint32_t timeout = I2C_START_TIMEOUT; // uint32_t timeout = I2C_START_TIMEOUT;
while((i2cp->id_i2c->CR1 & I2C_CR1_START) && timeout--) // while((i2cp->id_i2c->CR1 & I2C_CR1_START) && timeout--)
; // ;
/* is timeout overflows? */ // /* is timeout overflows? */
chDbgAssert(timeout <= I2C_START_TIMEOUT, // chDbgAssert(timeout <= I2C_START_TIMEOUT,
"i2c_lld_master_transmit(), #1", "time is out"); // "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, void i2c_lld_master_receive(I2CDriver *i2cp, uint16_t slave_addr,
uint8_t *rxbuf, size_t rxbytes){ 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->slave_addr = slave_addr;
i2cp->rxbytes = rxbytes; i2cp->rxbytes = rxbytes;
i2cp->rxbuf = rxbuf; 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->flags = I2C_FLG_MASTER_RECEIVER;
i2cp->errors = 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_ACK; /* acknowledge returned */ i2cp->id_i2c->CR1 |= I2C_CR1_ACK; /* acknowledge returned */
i2cp->id_i2c->CR1 &= ~I2C_CR1_POS; 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 */ //#endif /* I2C_USE_WAIT */
uint32_t timeout = I2C_START_TIMEOUT; uint32_t timeout = I2C_START_TIMEOUT;
while((i2cp->id_i2c->CR1 & I2C_CR1_START) && timeout--) while((i2cp->id_i2c->CR1 & I2C_CR1_START) && timeout--)
; ;
/* is timeout overflows? */ /* is timeout overflows? */
chDbgAssert(timeout <= I2C_START_TIMEOUT, chDbgAssert(timeout <= I2C_START_TIMEOUT,
"i2c_lld_master_receive(), #1", "time is out"); "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 */ //#endif /* I2C_USE_WAIT */
uint32_t timeout = I2C_START_TIMEOUT; // uint32_t timeout = I2C_START_TIMEOUT;
while((i2cp->id_i2c->CR1 & I2C_CR1_START) && timeout--) // while((i2cp->id_i2c->CR1 & I2C_CR1_START) && timeout--)
; // ;
/* is timeout overflows? */ // /* is timeout overflows? */
chDbgAssert(timeout <= I2C_START_TIMEOUT, // chDbgAssert(timeout <= I2C_START_TIMEOUT,
"i2c_lld_master_receive(), #1", "time is out"); // "i2c_lld_master_receive(), #1", "time is out");
} }

View File

@ -178,11 +178,11 @@ void i2cMasterTransmit(I2CDriver *i2cp,
}; };
#endif /* CH_DBG_ENABLE_ASSERTS */ #endif /* CH_DBG_ENABLE_ASSERTS */
chSysLock();
chDbgAssert(i2cp->id_state == I2C_READY, chDbgAssert(i2cp->id_state == I2C_READY,
"i2cMasterTransmit(), #1", "not ready"); "i2cMasterTransmit(), #1", "not ready");
i2cp->id_state = I2C_ACTIVE; i2cp->id_state = I2C_ACTIVE;
chSysLock();
i2c_lld_master_transmit(i2cp, slave_addr, txbuf, txbytes, rxbuf, rxbytes); i2c_lld_master_transmit(i2cp, slave_addr, txbuf, txbytes, rxbuf, rxbytes);
_i2c_wait_s(i2cp); _i2c_wait_s(i2cp);
chSysUnlock(); chSysUnlock();
@ -226,14 +226,12 @@ void i2cMasterReceive(I2CDriver *i2cp,
}; };
#endif /* CH_DBG_ENABLE_ASSERTS */ #endif /* CH_DBG_ENABLE_ASSERTS */
chSysLock();
chDbgAssert(i2cp->id_state == I2C_READY, chDbgAssert(i2cp->id_state == I2C_READY,
"i2cMasterReceive(), #1", "not ready"); "i2cMasterReceive(), #1", "not ready");
i2cp->id_state = I2C_ACTIVE; i2cp->id_state = I2C_ACTIVE;
i2c_lld_master_receive(i2cp, slave_addr, rxbuf, rxbytes); i2c_lld_master_receive(i2cp, slave_addr, rxbuf, rxbytes);
_i2c_wait_s(i2cp); _i2c_wait_s(i2cp);
chSysUnlock();
} }