2010-01-09 10:09 PM
I2C read problem STM32 as master
2011-05-17 04:37 AM
Hello All
On our latest Electronic Design we are using the STM32, with mostly good results. I can read and write large chunks of bytes (200 to 250) with an external 24C08 I2C EEPROM. However when I try to read a single byte I hang up the external EEPROM and can only get it operating again by powering down and then back up again. I have seen lots of discussion about I2C problems but none have indicated the solution. I have identified that using the following function causes my problem. uint8 epd_receiveByte(uint16 memAddr) { I2C_sendReadStart(memAddr); I2C_DISABLE_ACK; I2C_waitForEvent(I2C_FLAG_RXNE); I2C_GenerateSTOP(I2C1, ENABLE); // send stop after current byte I2C_ENABLE_ACK; return I2C1->DR; // received byte } The debug output from my very small section of code where we read one byte (using function above), and then write one byte is as below. ----------------------------------------------------------- main: Receive single byte for installer/user setting epd: epd_receiveBuffer: Beginning epd: Event Found epd: Event Found epd: Event Found epd: Event Found epd: TimeOut waiting for Event 1 epd: epd_receiveBuffer: End main: Write single byte for installer/user setting epd2: byteWrite epd: TimeOut waiting for Event 0 epd: TimeOut waiting for Event 1 epd: TimeOut waiting for Event 2 epd: TimeOut waiting for Event 2 epd: TimeOut Checking device BUSY - NO ACK Returned --------------------------------------------------------------- Many thanks Denis _____________________ http://www.CentronSolutions.com2011-05-17 04:37 AM
Hi,
I have had heaps of trouble getting single byte read to work over I2C, in the end the thing that worked is following the code from the AN2824 application note to the letter:Code:
/** * @brief Read a byte from the slave. * @param ne. * @retval : The read data byte. */ uint8_t I2C_Master_BufferRead1Byte(void) { uint8_t Data; __IO uint32_t temp; /* Send START condition */ I2C_GenerateSTART(I2C1, ENABLE); while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)); /* Send EEPROM address for read */ I2C_Send7bitAddress(I2C1, SLAVE_ADDRESS, I2C_Direction_Receiver); /* Wait until ADDR is set */ while (!I2C_GetFlagStatus(I2C1, I2C_FLAG_ADDR)); /* Clear ACK */ I2C_AcknowledgeConfig(I2C1, DISABLE); __disable_irq(); /* Clear ADDR flag */ temp = I2C1->SR2; /* Program the STOP */ I2C_GenerateSTOP(I2C1, ENABLE); __enable_irq(); while ((I2C_GetLastEvent(I2C1) & 0x0040) != 0x000040); /* Poll on RxNE */ /* Read the data */ Data = I2C_ReceiveData(I2C1); /* Make sure that the STOP bit is cleared by Hardware before CR1 write access */ while ((I2C1->CR1&0x200) == 0x200); /* Enable Acknowledgement to be ready for another reception */ I2C_AcknowledgeConfig(I2C1, ENABLE); return(Data); }2011-05-17 04:37 AM
Thanks Peter
I will try on Monday Denis ___________________________ http://www.CentronSolutions.com