I2C. Async transfer complete. Needs testing.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/i2c_dev@2716 35acf78f-673a-0410-8e92-d51de3d6d3f4master
parent
da3a453945
commit
00800dd8ed
|
@ -122,6 +122,7 @@ static void i2c_serve_event_interrupt(I2CDriver *i2cp) {
|
||||||
// if ((i2cp->id_state == I2C_MWAIT_TF) && (i2cp->id_i2c->SR1 & I2C_SR1_BTF)){
|
// if ((i2cp->id_state == I2C_MWAIT_TF) && (i2cp->id_i2c->SR1 & I2C_SR1_BTF)){
|
||||||
if ((i2cp->id_state == I2C_MWAIT_TF) && (i2cp->id_i2c->SR1 & I2C_SR1_BTF)){
|
if ((i2cp->id_state == I2C_MWAIT_TF) && (i2cp->id_i2c->SR1 & I2C_SR1_BTF)){
|
||||||
chSysLockFromIsr();
|
chSysLockFromIsr();
|
||||||
|
i2cp->id_i2c->CR2 &= (~I2C_CR2_ITEVTEN); // disable BTF interrupt
|
||||||
i2cp->id_slave_config->id_callback(i2cp, i2cp->id_slave_config);
|
i2cp->id_slave_config->id_callback(i2cp, i2cp->id_slave_config);
|
||||||
|
|
||||||
i = i2cp->id_i2c->SR1;
|
i = i2cp->id_i2c->SR1;
|
||||||
|
@ -283,16 +284,23 @@ void i2c_lld_stop(I2CDriver *i2cp) {
|
||||||
* return TRUE if last byte written
|
* return TRUE if last byte written
|
||||||
*/
|
*/
|
||||||
bool_t i2c_lld_txbyte(I2CDriver *i2cp) {
|
bool_t i2c_lld_txbyte(I2CDriver *i2cp) {
|
||||||
void *txbufhead = i2cp->id_slave_config->txbufhead;
|
#define _txbufhead (i2cp->id_slave_config->txbufhead)
|
||||||
void *txbytes = i2cp->id_slave_config->txbytes;
|
#define _txbytes (i2cp->id_slave_config->txbytes)
|
||||||
|
#define _txbuf (i2cp->id_slave_config->txbuf)
|
||||||
|
|
||||||
if (i2cp->id_slave_config->txbufhead < i2cp->id_slave_config->txbytes){
|
if (_txbufhead < _txbytes){
|
||||||
i2cp->id_i2c->DR = i2cp->id_slave_config->txbuf[i2cp->id_slave_config->txbufhead];
|
/* disable interrupt to avoid jumping to ISR */
|
||||||
(i2cp->id_slave_config->txbufhead)++;
|
if ( _txbytes - _txbufhead == 1)
|
||||||
|
i2cp->id_i2c->CR2 &= (~I2C_CR2_ITBUFEN);
|
||||||
|
i2cp->id_i2c->DR = _txbuf[_txbufhead];
|
||||||
|
(_txbufhead)++;
|
||||||
return(FALSE);
|
return(FALSE);
|
||||||
}
|
}
|
||||||
i2cp->id_slave_config->txbufhead = 0;
|
_txbufhead = 0;
|
||||||
return(TRUE); // last byte written
|
return(TRUE); // last byte written
|
||||||
|
#undef _txbufhead
|
||||||
|
#undef _txbytes
|
||||||
|
#undef _txbuf
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -302,44 +310,49 @@ bool_t i2c_lld_txbyte(I2CDriver *i2cp) {
|
||||||
*/
|
*/
|
||||||
bool_t i2c_lld_rxbyte(I2CDriver *i2cp) {
|
bool_t i2c_lld_rxbyte(I2CDriver *i2cp) {
|
||||||
// temporal variables
|
// temporal variables
|
||||||
#define rxbuf i2cp->id_slave_config->rxbuf
|
#define _rxbuf (i2cp->id_slave_config->rxbuf)
|
||||||
#define rxbufhead i2cp->id_slave_config->rxbufhead
|
#define _rxbufhead (i2cp->id_slave_config->rxbufhead)
|
||||||
#define rxdepth i2cp->id_slave_config->rxdepth
|
#define _rxdepth (i2cp->id_slave_config->rxdepth)
|
||||||
#define rxbytes i2cp->id_slave_config->rxbytes
|
#define _rxbytes (i2cp->id_slave_config->rxbytes)
|
||||||
|
|
||||||
/* In order to generate the non-acknowledge pulse after the last received
|
/* In order to generate the non-acknowledge pulse after the last received
|
||||||
* data byte, the ACK bit must be cleared just after reading the second
|
* data byte, the ACK bit must be cleared just after reading the second
|
||||||
* last data byte (after second last RxNE event).
|
* last data byte (after second last RxNE event).
|
||||||
*/
|
*/
|
||||||
if (rxbufhead < rxbytes){
|
if (_rxbufhead < _rxbytes){
|
||||||
rxbuf[rxbufhead] = i2cp->id_i2c->DR;
|
_rxbuf[_rxbufhead] = i2cp->id_i2c->DR;
|
||||||
if ((rxbytes - rxbufhead) <= 2){
|
if ((_rxbytes - _rxbufhead) <= 2){
|
||||||
i2cp->id_i2c->CR1 &= (~I2C_CR1_ACK);// clear ACK bit for automatically send NACK
|
i2cp->id_i2c->CR1 &= (~I2C_CR1_ACK);// clear ACK bit for automatically send NACK
|
||||||
}
|
}
|
||||||
rxbufhead++;
|
(_rxbufhead)++;
|
||||||
return(FALSE);
|
return(FALSE);
|
||||||
}
|
}
|
||||||
i2cp->id_i2c->CR2 &= (~I2C_CR2_ITBUFEN); // disable interrupt
|
/* disable interrupt to avoid jumping to ISR */
|
||||||
rxbuf[rxbufhead] = i2cp->id_i2c->DR; // read last byte
|
i2cp->id_i2c->CR2 &= (~I2C_CR2_ITBUFEN);
|
||||||
rxbufhead = 0;
|
|
||||||
#undef rxbuf
|
|
||||||
#undef rxbufhead
|
|
||||||
#undef rxdepth
|
|
||||||
#undef rxbytes
|
|
||||||
|
|
||||||
|
_rxbuf[_rxbufhead] = i2cp->id_i2c->DR; // read last byte
|
||||||
|
_rxbufhead = 0;
|
||||||
return(TRUE); // last byte read
|
return(TRUE); // last byte read
|
||||||
|
|
||||||
|
#undef _rxbuf
|
||||||
|
#undef _rxbufhead
|
||||||
|
#undef _rxdepth
|
||||||
|
#undef _rxbytes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void i2c_lld_master_start(I2CDriver *i2cp){
|
void i2c_lld_master_start(I2CDriver *i2cp){
|
||||||
i2cp->id_i2c->CR1 |= I2C_CR1_START;
|
i2cp->id_i2c->CR1 |= I2C_CR1_START;
|
||||||
|
while (i2cp->id_i2c->CR1 & I2C_CR1_START);
|
||||||
|
|
||||||
|
// enable interrupts
|
||||||
|
i2cp->id_i2c->CR2 |= I2C_CR2_ITEVTEN;
|
||||||
|
i2cp->id_i2c->CR2 |= I2C_CR2_ITBUFEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
void i2c_lld_master_stop(I2CDriver *i2cp){
|
void i2c_lld_master_stop(I2CDriver *i2cp){
|
||||||
i2cp->id_i2c->CR1 |= I2C_CR1_STOP;
|
i2cp->id_i2c->CR1 |= I2C_CR1_STOP;
|
||||||
chSysLock();
|
|
||||||
while (i2cp->id_i2c->CR1 & I2C_CR1_STOP);
|
while (i2cp->id_i2c->CR1 & I2C_CR1_STOP);
|
||||||
chSysUnlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue