I2C. Some fixes.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/i2c_dev@2922 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
parent
4fda4dc84f
commit
60975ca7fe
|
@ -204,7 +204,6 @@ struct I2CSlaveConfig{
|
|||
} \
|
||||
}
|
||||
#else /* !I2C_USE_WAIT */
|
||||
#define i2c_lld_wait_bus_free(i2cp) //TODO: remove this STUB
|
||||
#define _i2c_wait_s(i2cp)
|
||||
#define _i2c_wakeup_isr(i2cp)
|
||||
#endif /* !I2C_USE_WAIT */
|
||||
|
|
|
@ -94,11 +94,20 @@ static void i2c_serve_event_interrupt(I2CDriver *i2cp) {
|
|||
}
|
||||
break;
|
||||
case I2C_EV8_2_MASTER_BYTE_TRANSMITTED:
|
||||
/* if nothing to read then generate stop */
|
||||
if (i2cp->id_slave_config->rx_remaining_bytes == 0){
|
||||
dp->CR1 |= I2C_CR1_STOP; // stop generation
|
||||
/* Disable ITEVT In order to not have again a BTF IT */
|
||||
dp->CR2 &= (uint16_t)~I2C_CR2_ITEVTEN;
|
||||
/* Portable I2C ISR code defined in the high level driver, note, it is a macro.*/
|
||||
_i2c_isr_code(i2cp, i2cp->id_slave_config);
|
||||
}
|
||||
else{
|
||||
/* Disable ITEVT In order to not have again a BTF IT */
|
||||
dp->CR2 &= (uint16_t)~I2C_CR2_ITEVTEN;
|
||||
/* send restart and begin reading operations */
|
||||
i2c_lld_master_transceive(i2cp);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
|
@ -550,7 +559,7 @@ void i2c_lld_master_receive(I2CDriver *i2cp){
|
|||
i2cp->id_i2c->CR1 |= I2C_CR1_ACK; // acknowledge returned
|
||||
i2cp->id_i2c->CR1 &= ~I2C_CR1_POS;
|
||||
|
||||
switch(i2cp->nbit_address){
|
||||
switch(i2cp->id_slave_config->nbit_address){
|
||||
case 7:
|
||||
i2cp->slave_addr1 = ((i2cp->id_slave_config->slave_addr <<1) | 0x01); // LSB = 1 -> receive
|
||||
break;
|
||||
|
@ -586,4 +595,52 @@ void i2c_lld_master_receive(I2CDriver *i2cp){
|
|||
|
||||
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param[in] i2cp pointer to the @p I2CDriver object
|
||||
*
|
||||
*/
|
||||
void i2c_lld_master_transceive(I2CDriver *i2cp){
|
||||
uint32_t a, b;
|
||||
// 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;
|
||||
|
||||
switch(i2cp->id_slave_config->nbit_address){
|
||||
case 7:
|
||||
i2cp->slave_addr1 = ((i2cp->id_slave_config->slave_addr <<1) | 0x01); // LSB = 1 -> receive
|
||||
break;
|
||||
case 10:
|
||||
i2cp->slave_addr1 = ((i2cp->id_slave_config->slave_addr >>7) & 0x0006); // add the two msb of 10-bit address to the header
|
||||
i2cp->slave_addr1 |= 0xF0; // add the header bits (the LSB -> 1 will be add to second
|
||||
i2cp->slave_addr2 = i2cp->id_slave_config->slave_addr & 0x00FF; // the remaining 8 bit of 10-bit address
|
||||
break;
|
||||
}
|
||||
|
||||
i2cp->id_slave_config->flags = I2C_FLG_MASTER_RECEIVER;
|
||||
i2cp->id_slave_config->errors = 0;
|
||||
|
||||
// Only one byte to be received
|
||||
if(i2cp->id_slave_config->rx_remaining_bytes == 1) {
|
||||
i2cp->id_slave_config->flags |= I2C_FLG_1BTR;
|
||||
}
|
||||
// Only two bytes to be received
|
||||
else if(i2cp->id_slave_config->rx_remaining_bytes == 2) {
|
||||
i2cp->id_slave_config->flags |= I2C_FLG_2BTR;
|
||||
i2cp->id_i2c->CR1 |= I2C_CR1_POS; // Acknowledge Position
|
||||
}
|
||||
|
||||
i2cp->id_i2c->CR1 |= I2C_CR1_START; // send start bit
|
||||
|
||||
#if !I2C_USE_WAIT
|
||||
/* Wait until the START condition is generated on the bus: the START bit is cleared by hardware */
|
||||
uint32_t timeout = 0xfffff;
|
||||
while((i2cp->id_i2c->CR1 & I2C_CR1_START) && timeout--)
|
||||
;
|
||||
#endif /* I2C_USE_WAIT */
|
||||
}
|
||||
|
||||
|
||||
#endif // HAL_USE_I2C
|
||||
|
|
|
@ -185,6 +185,19 @@ struct I2CDriver{
|
|||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#define i2c_lld_bus_is_busy(i2cp) \
|
||||
(i2cp->id_i2c->SR2 & I2C_SR2_BUSY)
|
||||
|
||||
|
||||
/* Wait until BUSY flag is reset: a STOP has been generated on the bus
|
||||
* signaling the end of transmission
|
||||
*/
|
||||
#define i2c_lld_wait_bus_free(i2cp) { \
|
||||
uint32_t tmo = 0xffff; \
|
||||
while((i2cp->id_i2c->SR2 & I2C_SR2_BUSY) && tmo--) \
|
||||
; \
|
||||
}
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
@ -211,6 +224,7 @@ void i2c_lld_start(I2CDriver *i2cp);
|
|||
void i2c_lld_stop(I2CDriver *i2cp);
|
||||
void i2c_lld_master_transmit(I2CDriver *i2cp);
|
||||
void i2c_lld_master_receive(I2CDriver *i2cp);
|
||||
void i2c_lld_master_transceive(I2CDriver *i2cp);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -140,11 +140,14 @@ void i2cMasterTransmit(I2CDriver *i2cp, I2CSlaveConfig *i2cscfg) {
|
|||
|
||||
size_t n;
|
||||
i2cblock_t *txbuf;
|
||||
uint8_t nbit_addr;
|
||||
|
||||
txbuf = i2cscfg->txbuf;
|
||||
nbit_addr = i2cscfg->nbit_address;
|
||||
n = i2cscfg->tx_remaining_bytes;
|
||||
|
||||
chDbgCheck((i2cp != NULL) && (i2cscfg != NULL) && (n > 0) && (txbuf != NULL),
|
||||
chDbgCheck((i2cp != NULL) && (i2cscfg != NULL) && \
|
||||
((nbit_addr == 7) || (nbit_addr == 10)) && (n > 0) && (txbuf != NULL),
|
||||
"i2cMasterTransmit");
|
||||
|
||||
// init slave config field in driver
|
||||
|
@ -186,11 +189,14 @@ void i2cMasterReceive(I2CDriver *i2cp, I2CSlaveConfig *i2cscfg){
|
|||
|
||||
size_t n;
|
||||
i2cblock_t *rxbuf;
|
||||
uint8_t nbit_addr;
|
||||
|
||||
rxbuf = i2cscfg->rxbuf;
|
||||
n = i2cscfg->rx_remaining_bytes;
|
||||
nbit_addr = i2cscfg->nbit_address;
|
||||
|
||||
chDbgCheck((i2cp != NULL) && (n > 0) && (rxbuf != NULL),
|
||||
chDbgCheck((i2cp != NULL) && (i2cscfg != NULL) && (n > 0) && \
|
||||
((nbit_addr == 7) || (nbit_addr == 10)) && (rxbuf != NULL),
|
||||
"i2cMasterReceive");
|
||||
|
||||
// init slave config field in driver
|
||||
|
@ -221,6 +227,7 @@ void i2cMasterReceive(I2CDriver *i2cp, I2CSlaveConfig *i2cscfg){
|
|||
chSysUnlock();
|
||||
}
|
||||
|
||||
|
||||
uint16_t i2cSMBusAlertResponse(I2CDriver *i2cp, I2CSlaveConfig *i2cscfg) {
|
||||
|
||||
i2cMasterReceive(i2cp, i2cscfg);
|
||||
|
|
Loading…
Reference in New Issue