2013-01-11 01:33 AM
Hello All,
I am programing an EEPROM which is interfaced to STM32 via I2c2. I am using DMA interrupt for reading data from EEPROM location. I feel Writing to EEPROM works fine and could see TxE and TRA flags set while trsanmitting the data from STM. But i have problem in redaing data from EEPROM. I can see no flags set when i watch the registers. The DMA interrupt occurs but DMA_FLAG_TCIF0 doesnt get clerared. Either I am able to see some data in the buffer. I have posted the code.Please let me know where am I going wrongvoid ReadBuffer(uint8_t* pBuffer, uint16_t ReadAddr, uint16_t* NumByteToRead)
{ uint16_t data; uint8_t i; ptEEDataReadPointer=NumByteToRead; // While the bus is busy Timeout=LONG_TIMEOUT; while(I2C_GetFlagStatus(I2C2, I2C_FLAG_BUSY)) { Timeout--; if (Timeout==0) { return TIMEOUT_ERROR; } } //Send START condition I2C_GenerateSTART(I2C2,ENABLE); //Test on EV5 and clear it (cleared by reading SR1 then writing to DR)if(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT))
{ I2C_GenerateSTART(I2C2,ENABLE); } Timeout=FLAG_TIMEOUT; while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT)) { Timeout--; if(Timeout == 0) { return TIMEOUT_ERROR; } } I2C_Send7bitAddress(I2C2, nEEAddress, I2C_Direction_Transmitter);//Test on EV6 and clear it
if(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) { I2C_GenerateSTART(I2C2,ENABLE); I2C_Send7bitAddress(I2C2, nEEAddress, I2C_Direction_Transmitter); }I2C_SendData(I2C2, ReadAddr);
//Test on EV8 and clear it
Timeout = FLAG_TIMEOUT;data = I2C1->DR;
//Send STRAT condition a second time I2C_GenerateSTART(I2C2, ENABLE); //Test on EV5 and clear it (cleared by reading SR1 then writing to DR) Timeout = FLAG_TIMEOUT; while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT)) { if((Timeout--) == 0) return TIMEOUT_ERROR; } //Send EEPROM address for read I2C_Send7bitAddress(I2C2, nEEAddress, I2C_Direction_Receiver); /* If number of data to be read is 1, then DMA couldn't be used */ /* One Byte Master Reception procedure (POLLING) */ if ((uint16_t)(*NumByteToRead) < 2) { //Disable Acknowledgment I2C_AcknowledgeConfig(I2C2, DISABLE); //Clear ADDR register by reading SR1 then SR2 register (SR1 has already been read) (void)I2Cx->SR2; // Read the byte received from the EEPROM *pBuffer = I2C_ReceiveData(I2Cx);
//Send STOP Condition
I2C_GenerateSTOP(I2Cx, ENABLE); /*!< Decrement the read bytes counter */ (uint16_t)(*NumByteToRead)--; /* Wait to make sure that STOP control bit has been cleared */ Timeout = FLAG_TIMEOUT; while(I2Cx->CR1 & I2C_CR1_STOP) { if((Timeout--) == 0) return TIMEOUT_ERROR; } Here is my Interrupt service routinevoid DMA1_Stream3_IRQHandler(void)
{ //Check if the DMA transfer is complete if(DMA_GetFlagStatus(DMA1_Stream3, DMA_FLAG_TCIF0) != RESET) { //Send STOP Condition I2C_GenerateSTOP(I2Cx, ENABLE); //Disable the DMA Rx Stream and Clear TC Flag */ DMA_Cmd(Stream3, DISABLE); DMA_ClearFlag(Stream3, DMA_FLAG_TCIF0); *ptEEDataReadPointer = 0; } Thanks #i2014-09-11 04:00 PM
You're running DMA1_Stream3 but checking DMA_FLAG_TCIF0. You need to be checking DMA_FLAG_TCIF3 (which matches Stream3).
void DMA1_Stream3_IRQHandler(void)
{
//Check if the DMA transfer is complete if(DMA_GetFlagStatus(DMA1_Stream3, DMA_FLAG_TCIF0) != RESET) { //Send STOP Condition I2C_GenerateSTOP(I2Cx, ENABLE); //Disable the DMA Rx Stream and Clear TC Flag */ DMA_Cmd(Stream3, DISABLE); DMA_ClearFlag(Stream3, DMA_FLAG_TCIF0); *ptEEDataReadPointer = 0; } Thanks