cancel
Showing results for 
Search instead for 
Did you mean: 

I2C DMA

pranathi1091
Associate II
Posted on January 11, 2013 at 10:33

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

#i
1 REPLY 1
harry_rostovtsev
Associate II
Posted on September 12, 2014 at 01:00

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