diff options
author | barthess <barthess@35acf78f-673a-0410-8e92-d51de3d6d3f4> | 2011-07-10 21:40:49 +0000 |
---|---|---|
committer | barthess <barthess@35acf78f-673a-0410-8e92-d51de3d6d3f4> | 2011-07-10 21:40:49 +0000 |
commit | caeaf6536e6d9dc087d9a23ff71c442cd2762e63 (patch) | |
tree | 4386bbb355bf8b00caa17fcaa3ecae9067b775bc /os | |
parent | 00885674924c98404203f61aafbe18393eebab2b (diff) | |
download | ChibiOS-caeaf6536e6d9dc087d9a23ff71c442cd2762e63.tar.gz ChibiOS-caeaf6536e6d9dc087d9a23ff71c442cd2762e63.tar.bz2 ChibiOS-caeaf6536e6d9dc087d9a23ff71c442cd2762e63.zip |
I2C. Fixed bug occures when read-through-write two bytes. Code cleanups.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/i2c_dev@3150 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os')
-rw-r--r-- | os/hal/platforms/STM32/i2c_lld.c | 66 |
1 files changed, 25 insertions, 41 deletions
diff --git a/os/hal/platforms/STM32/i2c_lld.c b/os/hal/platforms/STM32/i2c_lld.c index 25b8a30bf..27ab1d809 100644 --- a/os/hal/platforms/STM32/i2c_lld.c +++ b/os/hal/platforms/STM32/i2c_lld.c @@ -90,8 +90,8 @@ void _i2c_ev6_master_rec_mode_selected(I2CDriver *i2cp){ dp->CR1 &= (uint16_t)~I2C_CR1_ACK; /* Program the STOP */ dp->CR1 |= I2C_CR1_STOP; - while(dp->CR1 & I2C_CR1_STOP) - ; +// while(dp->CR1 & I2C_CR1_STOP) +// ; break; case I2C_EV6_1_MASTER_REC_2BTR_MODE_SELECTED: /* only two bytes to receive */ @@ -121,7 +121,6 @@ void _i2c_ev7_master_rec_byte_qued(I2CDriver *i2cp){ case I2C_EV7_2_MASTER_REC_3BYTES_TO_PROCESS:/* only for case of three bytes to be received */ /* DataN-2 and DataN-1 are received */ - dp->CR2 |= I2C_CR2_ITBUFEN; /* Clear ACK */ dp->CR1 &= (uint16_t)~I2C_CR1_ACK; /* Read the DataN-2 @@ -137,9 +136,8 @@ void _i2c_ev7_master_rec_byte_qued(I2CDriver *i2cp){ /* Decrement the number of readed bytes */ i2cp->rxbytes -= 2; i2cp->flags = 0; - /* ready for read DataN on the next EV7 */ - while(dp->CR1 & I2C_CR1_STOP) - ; + /* ready for read DataN. Enable interrupt for next (and last) RxNE event*/ + dp->CR2 |= I2C_CR2_ITBUFEN; break; case I2C_EV7_3_MASTER_REC_2BYTES_TO_PROCESS: /* only for case of two bytes to be received */ @@ -155,8 +153,6 @@ void _i2c_ev7_master_rec_byte_qued(I2CDriver *i2cp){ *rxBuffp = dp->DR; i2cp->rxbytes = 0; i2cp->flags = 0; - while(dp->CR1 & I2C_CR1_STOP) - ; /* Portable I2C ISR code defined in the high level driver, note, it is a macro.*/ _i2c_isr_code(i2cp, i2cp->id_slave_config); break; @@ -251,10 +247,11 @@ static void i2c_serve_event_interrupt(I2CDriver *i2cp) { _i2c_isr_code(i2cp, i2cp->id_slave_config); } else{ - chSysLockFromIsr(); + // chSysLockFromIsr(); /* send restart and begin reading operations */ + // i2c_lld_master_receive(i2cp, i2cp->slave_addr, i2cp->rxbuf, i2cp->rxbytes); i2c_lld_master_transceive(i2cp); - chSysUnlockFromIsr(); + // chSysUnlockFromIsr(); } break; @@ -268,26 +265,18 @@ static void i2c_serve_event_interrupt(I2CDriver *i2cp) { break; case I2C_EV7_MASTER_REC_BYTE_RECEIVED: - if(i2cp->rxbytes != 3) { + if(i2cp->rxbytes > 3) { /* Read the data register */ *rxBuffp = dp->DR; rxBuffp++; i2cp->rxbytes--; - switch(i2cp->rxbytes){ - case 3: + if(i2cp->rxbytes == 3){ /* Disable the ITBUF in order to have only the BTF interrupt */ dp->CR2 &= (uint16_t)~I2C_CR2_ITBUFEN; i2cp->flags |= I2C_FLG_3BTR; - break; - case 0: - dp->CR2 &= (uint16_t)~I2C_CR2_ITEVTEN; - dp->CR2 &= (uint16_t)~I2C_CR2_ITBUFEN; - /* Portable I2C ISR code defined in the high level driver, note, it is a macro.*/ - _i2c_isr_code(i2cp, i2cp->id_slave_config); - break; } } - else{ + else if (i2cp->rxbytes == 3){ /* Disable the ITBUF in order to have only the BTF interrupt */ dp->CR2 &= (uint16_t)~I2C_CR2_ITBUFEN; i2cp->flags |= I2C_FLG_3BTR; @@ -683,13 +672,6 @@ void i2c_lld_master_transmit(I2CDriver *i2cp, uint16_t slave_addr, i2cp->id_i2c->CR1 |= I2C_CR1_START; /* send start bit */ -// uint32_t timeout = I2C_START_TIMEOUT; -// while((i2cp->id_i2c->CR1 & I2C_CR1_START) && timeout--) -// ; -// /* is time out? */ -// 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); } @@ -750,13 +732,6 @@ void i2c_lld_master_receive(I2CDriver *i2cp, uint16_t slave_addr, i2cp->id_i2c->CR1 |= I2C_CR1_START; /* send start bit */ -// uint32_t timeout = I2C_START_TIMEOUT; -// while((i2cp->id_i2c->CR1 & I2C_CR1_START) && timeout--) -// ; -// /* is time out? */ -// 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); } @@ -770,13 +745,23 @@ void i2c_lld_master_transceive(I2CDriver *i2cp){ "i2c_lld_master_transceive(), #1", ""); - /* first send start bit to reduce blocking time */ - i2cp->id_i2c->CR1 |= I2C_CR1_START; - i2cp->flags = I2C_FLG_MASTER_RECEIVER; i2cp->errors = 0; - i2cp->slave_addr1 |= 0x01; + i2cp->id_i2c->CR1 |= I2C_CR1_ACK; /* acknowledge returned */ + i2cp->id_i2c->CR1 &= ~I2C_CR1_POS; + + if(i2cp->slave_addr & 0x8000){/* 10-bit mode used */ + /* add the two msb of 10-bit address to the header */ + i2cp->slave_addr1 = ((i2cp->slave_addr >>7) & 0x0006); + /* add the header bits (the LSB -> 1 will be add to second */ + i2cp->slave_addr1 |= 0xF0; + /* the remaining 8 bit of 10-bit address */ + i2cp->slave_addr2 = i2cp->slave_addr & 0x00FF; + } + else{ + i2cp->slave_addr1 |= 0x01; + } /* Only one byte to be received */ if(i2cp->rxbytes == 1) { @@ -788,8 +773,7 @@ void i2c_lld_master_transceive(I2CDriver *i2cp){ i2cp->id_i2c->CR1 |= I2C_CR1_POS; /* Acknowledge Position */ } - i2cp->id_i2c->CR1 |= I2C_CR1_ACK; /* acknowledge returned */ - i2cp->id_i2c->CR1 &= ~I2C_CR1_POS; + i2cp->id_i2c->CR1 |= I2C_CR1_START; /* send start bit */ uint32_t timeout = I2C_START_TIMEOUT; while((i2cp->id_i2c->CR1 & I2C_CR1_START) && timeout--) |