AnsweredAssumed Answered

I2C DMA

Question asked by sd.pranathi on Jan 11, 2013
Latest reply on Sep 12, 2014 by rost0031
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 wrong

void  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 routine

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

Outcomes