2015-06-29 07:37 AM
Hi
I'm trying to get a STM32F427 working as a I2C master using interrupts and everything is working apart from reading more than 2 bytes. I can write any number of bytes and read 1 or 2 bytes all OK. After the slave address is sent I get an ADDR interrupt and depending on the number of bytes I need to read I do:if ( I2C.No_Read_Bytes == 1 ) // only 1 byte to read so set not ack and set stop
{
I2C2->CR1 &= ~I2C_CR1_ACK; /* Not ack */
__disable_irq(); /* Stop all interrupts */
sr2 = I2C2->SR2; /* Clear the ADDR bit by reading status 2 register */
I2C2->CR1 |= I2C_CR1_STOP; /* Set stop */
__enable_irq(); /* Enable all interrupts */
}
else if ( I2C.No_Read_Bytes == 2 ) // 2 bytes to read POS must be set high
{
I2C2->CR1 |= I2C_CR1_POS; /* Set POS */
__disable_irq(); /* Stop all interrupts */
sr2 = I2C2->SR2; /* Clear the ADDR bit by reading status 2 register */
I2C2->CR1 &= ~I2C_CR1_ACK; /* Not ack */
__enable_irq(); /* Enable all interrupts */
}
else // more than 2 bytes to still read
{
__disable_irq(); /* Stop all interrupts */
sr2 = I2C2->SR2; /* Clear the ADDR bit by reading status 2 register */
I2C2->CR1 &= ~I2C_CR1_ACK; /* Not ack */
__enable_irq(); /* Enable all interrupts */
}
As soon as the ADDR bit is cleared an I2C read byte occurs (2 bytes are read when POS is set high). I then handle those from a 'byte transfer finished' interrupt all OK.
My problem is when reading more than 2 bytes. When I read the DR register there is no I2C activity. I'm expecting a new byte to be read for every DR register read. Is this correct?
The only time I see I2C read activity is when I clear the ADDR bit which only works for 1 or 2 byte reads.
I am following the programming reference and also app note AN2824 and both documents suggest just reading the DR register for read bytes N>2. I found nothing in the errata.
Any help or suggestions are greatly appreciated.
Regards
Simon
2015-06-29 12:02 PM
Ooops my mistake. I was unsetting the ACK bit (when I should have been setting it) for more than 2 bytes therefore the comms was being ended too soon and reading the DR register wouldn't do anything.