I2C. Waits moved from ISR.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/i2c_dev@3161 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
parent
5fee9bc344
commit
e02d3607dc
|
@ -48,12 +48,23 @@ static volatile uint16_t dbgSR1 = 0;
|
||||||
static volatile uint16_t dbgSR2 = 0;
|
static volatile uint16_t dbgSR2 = 0;
|
||||||
static volatile uint16_t dbgCR1 = 0;
|
static volatile uint16_t dbgCR1 = 0;
|
||||||
static volatile uint16_t dbgCR2 = 0;
|
static volatile uint16_t dbgCR2 = 0;
|
||||||
|
|
||||||
|
static uint32_t polling_time_worst = 0;
|
||||||
|
static uint32_t polling_time_begin = 0;
|
||||||
|
static uint32_t polling_time_delta = 0;
|
||||||
|
|
||||||
#endif /* CH_DBG_ENABLE_ASSERTS */
|
#endif /* CH_DBG_ENABLE_ASSERTS */
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
/* Driver local functions. */
|
/* Driver local functions. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
#if STM32_I2C_USE_POLLING_WAIT
|
||||||
|
#else
|
||||||
|
VirtualTimer i2c_waiting_vt;
|
||||||
|
#endif /* STM32_I2C_USE_POLLING_WAIT */
|
||||||
|
|
||||||
|
|
||||||
/* defines for convenience purpose */
|
/* defines for convenience purpose */
|
||||||
#define txBuffp (i2cp->txbuff_p)
|
#define txBuffp (i2cp->txbuff_p)
|
||||||
#define rxBuffp (i2cp->rxbuff_p)
|
#define rxBuffp (i2cp->rxbuff_p)
|
||||||
|
@ -113,8 +124,6 @@ void _i2c_ev6_master_rec_mode_selected(I2CDriver *i2cp){
|
||||||
case I2C_EV6_3_MASTER_REC_1BTR_MODE_SELECTED: /* only an single byte to receive */
|
case I2C_EV6_3_MASTER_REC_1BTR_MODE_SELECTED: /* only an single byte to receive */
|
||||||
dp->CR1 &= (uint16_t)~I2C_CR1_ACK; /* Clear ACK */
|
dp->CR1 &= (uint16_t)~I2C_CR1_ACK; /* Clear ACK */
|
||||||
dp->CR1 |= I2C_CR1_STOP; /* Program the STOP */
|
dp->CR1 |= I2C_CR1_STOP; /* Program the STOP */
|
||||||
while(dp->CR1 & I2C_CR1_STOP)
|
|
||||||
;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case I2C_EV6_1_MASTER_REC_2BTR_MODE_SELECTED: /* only two bytes to receive */
|
case I2C_EV6_1_MASTER_REC_2BTR_MODE_SELECTED: /* only two bytes to receive */
|
||||||
|
@ -146,14 +155,14 @@ void _i2c_ev7_master_rec_byte_qued(I2CDriver *i2cp){
|
||||||
dp->CR1 &= (uint16_t)~I2C_CR1_ACK; /* Clear ACK */
|
dp->CR1 &= (uint16_t)~I2C_CR1_ACK; /* Clear ACK */
|
||||||
*rxBuffp = dp->DR; /* Read the DataN-2. This clear the RXE & BFT flags and launch the DataN exception in the shift register (ending the SCL stretch) */
|
*rxBuffp = dp->DR; /* Read the DataN-2. This clear the RXE & BFT flags and launch the DataN exception in the shift register (ending the SCL stretch) */
|
||||||
rxBuffp++;
|
rxBuffp++;
|
||||||
|
chSysLockFromIsr();
|
||||||
dp->CR1 |= I2C_CR1_STOP; /* Program the STOP */
|
dp->CR1 |= I2C_CR1_STOP; /* Program the STOP */
|
||||||
*rxBuffp = dp->DR; /* Read the DataN-1 */
|
*rxBuffp = dp->DR; /* Read the DataN-1 */
|
||||||
|
chSysUnlockFromIsr();
|
||||||
rxBuffp++;
|
rxBuffp++;
|
||||||
i2cp->rxbytes -= 2; /* Decrement the number of readed bytes */
|
i2cp->rxbytes -= 2; /* Decrement the number of readed bytes */
|
||||||
i2cp->flags = 0;
|
i2cp->flags = 0;
|
||||||
dp->CR2 |= I2C_CR2_ITBUFEN; /* ready for read DataN. Enable interrupt for next (and last) RxNE event*/
|
dp->CR2 |= I2C_CR2_ITBUFEN; /* ready for read DataN. Enable interrupt for next (and last) RxNE event*/
|
||||||
while(dp->CR1 & I2C_CR1_STOP)
|
|
||||||
;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case I2C_EV7_3_MASTER_REC_2BYTES_TO_PROCESS:
|
case I2C_EV7_3_MASTER_REC_2BYTES_TO_PROCESS:
|
||||||
|
@ -161,15 +170,15 @@ void _i2c_ev7_master_rec_byte_qued(I2CDriver *i2cp){
|
||||||
* DataN-1 and DataN are received */
|
* DataN-1 and DataN are received */
|
||||||
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;
|
||||||
|
chSysLockFromIsr();
|
||||||
dp->CR1 |= I2C_CR1_STOP; /* Program the STOP */
|
dp->CR1 |= I2C_CR1_STOP; /* Program the STOP */
|
||||||
*rxBuffp = dp->DR; /* Read the DataN-1*/
|
*rxBuffp = dp->DR; /* Read the DataN-1*/
|
||||||
rxBuffp++;
|
rxBuffp++;
|
||||||
*rxBuffp = dp->DR; /* Read the DataN*/
|
*rxBuffp = dp->DR; /* Read the DataN*/
|
||||||
|
chSysUnlockFromIsr();
|
||||||
i2cp->rxbytes = 0;
|
i2cp->rxbytes = 0;
|
||||||
i2cp->flags = 0;
|
i2cp->flags = 0;
|
||||||
_i2c_isr_code(i2cp, i2cp->id_slave_config); /* Portable I2C ISR code defined in the high level driver. */
|
_i2c_isr_code(i2cp, i2cp->id_slave_config); /* Portable I2C ISR code defined in the high level driver. */
|
||||||
while(dp->CR1 & I2C_CR1_STOP)
|
|
||||||
;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case I2C_FLG_MASTER_RECEIVER:
|
case I2C_FLG_MASTER_RECEIVER:
|
||||||
|
@ -250,8 +259,6 @@ static void i2c_serve_event_interrupt(I2CDriver *i2cp) {
|
||||||
if (i2cp->rxbytes == 0){ /* if nothing to read then generate stop */
|
if (i2cp->rxbytes == 0){ /* if nothing to read then generate stop */
|
||||||
dp->CR1 |= I2C_CR1_STOP;
|
dp->CR1 |= I2C_CR1_STOP;
|
||||||
_i2c_isr_code(i2cp, i2cp->id_slave_config); /* Portable I2C ISR code defined in the high level driver. */
|
_i2c_isr_code(i2cp, i2cp->id_slave_config); /* Portable I2C ISR code defined in the high level driver. */
|
||||||
while(dp->CR1 & I2C_CR1_STOP)
|
|
||||||
;
|
|
||||||
}
|
}
|
||||||
else{ /* start reading operation */
|
else{ /* start reading operation */
|
||||||
i2c_lld_master_transceive(i2cp);
|
i2c_lld_master_transceive(i2cp);
|
||||||
|
@ -629,6 +636,17 @@ void i2c_lld_master_transmit(I2CDriver *i2cp, uint16_t slave_addr,
|
||||||
i2cp->flags = 0;
|
i2cp->flags = 0;
|
||||||
i2cp->errors = 0;
|
i2cp->errors = 0;
|
||||||
|
|
||||||
|
#if CH_DBG_ENABLE_ASSERTS
|
||||||
|
polling_time_begin = PWMD4.tim->CNT;
|
||||||
|
#endif
|
||||||
|
while(i2cp->id_i2c->CR1 & I2C_CR1_STOP)
|
||||||
|
;
|
||||||
|
#if CH_DBG_ENABLE_ASSERTS
|
||||||
|
polling_time_delta = PWMD4.tim->CNT - polling_time_begin;
|
||||||
|
if (polling_time_delta > polling_time_worst)
|
||||||
|
polling_time_worst = polling_time_delta;
|
||||||
|
#endif
|
||||||
|
|
||||||
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 */
|
||||||
i2cp->id_i2c->CR2 |= (I2C_CR2_ITERREN|I2C_CR2_ITEVTEN|I2C_CR2_ITBUFEN); /* enable ERR, EVT & BUF ITs */
|
i2cp->id_i2c->CR2 |= (I2C_CR2_ITERREN|I2C_CR2_ITEVTEN|I2C_CR2_ITBUFEN); /* enable ERR, EVT & BUF ITs */
|
||||||
|
@ -668,6 +686,18 @@ 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;
|
||||||
|
|
||||||
|
#if CH_DBG_ENABLE_ASSERTS
|
||||||
|
polling_time_begin = PWMD4.tim->CNT;
|
||||||
|
#endif
|
||||||
|
while(i2cp->id_i2c->CR1 & I2C_CR1_STOP)
|
||||||
|
;
|
||||||
|
#if CH_DBG_ENABLE_ASSERTS
|
||||||
|
polling_time_delta = PWMD4.tim->CNT - polling_time_begin;
|
||||||
|
if (polling_time_delta > polling_time_worst)
|
||||||
|
polling_time_worst = polling_time_delta;
|
||||||
|
#endif
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,17 @@
|
||||||
/* Driver pre-compile time settings. */
|
/* Driver pre-compile time settings. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Waiting method switch.
|
||||||
|
* @details If set to @p TRUE than waiting of STOP generation will use
|
||||||
|
* while() loop polling. Otherwise -- virtual timer will be used.
|
||||||
|
* @note The default is @p TRUE.
|
||||||
|
* @note Virtual timer resolution is 1/@p CH_FREQUENCY seconds.
|
||||||
|
*/
|
||||||
|
#if !defined(STM32_I2C_USE_POLLING_WAIT) || defined(__DOXYGEN__)
|
||||||
|
#define STM32_I2C_USE_POLLING_WAIT TRUE
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief I2C1 driver enable switch.
|
* @brief I2C1 driver enable switch.
|
||||||
* @details If set to @p TRUE the support for I2C1 is included.
|
* @details If set to @p TRUE the support for I2C1 is included.
|
||||||
|
|
Loading…
Reference in New Issue