cancel
Showing results for 
Search instead for 
Did you mean: 

BlueNRG-2 IIC error with reading more than 16 bytes

SZhan.5
Associate

Hi,

I am working on BlueNRG-2 and I need drive NFC-EERPOM(M24SR64).

I tried to read from M24SR64, I got error when the reading bytes were more than 16.(It was ok <= 16 bytes), it stuck on the while loop as below. I put my readfunction and init function here, could you help me fix this issue?

Thanks a lot!

ErrorStatus SdkEvalI2CRead_2(uint8_t* pBuffer, uint8_t DeviceAddr, uint8_t NumByteToRead)

{

 I2C_TransactionType t;

 /* read data */

 t.Operation = I2C_Operation_Read;

 t.Address = DeviceAddr;

 t.StartByte = I2C_StartByte_Disable;

 t.AddressType = I2C_AddressType_7Bit;

 t.StopCondition = I2C_StopCondition_Enable;

 t.Length = NumByteToRead;  

 I2C_BeginTransaction((I2C_Type*)I2C2, &t);

  

 /* Wait loop */

 do {

  if(I2C_OP_ABORTED == I2C_GetStatus((I2C_Type*)I2C2))

   return ERROR;

   

 } while (RESET == I2C_GetITStatus((I2C_Type*)I2C2, I2C_IT_MTD));

  

 /* Clear pending bits */

 I2C_ClearITPendingBit((I2C_Type*)I2C2, I2C_IT_MTD | I2C_IT_MTDWS);

  

 /* Get data from RX FIFO */

 while(NumByteToRead--) {

  *pBuffer = I2C_ReceiveData((I2C_Type*)I2C2);

  pBuffer ++;

 }

 return SUCCESS;

}

ErrorStatus SdkEvalI2C_2_Init(uint32_t baudrate) //baudrate is 400000

{  

 GPIO_InitType GPIO_InitStructure;

 I2C_InitType I2C_InitStruct;

   

 /* Enable I2C and GPIO clocks */

  SysCtrl_PeripheralClockCmd(CLOCK_PERIPH_GPIO | CLOCK_PERIPH_I2C2, ENABLE);

    

 /* Configure I2C pins */

 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 ;

 GPIO_InitStructure.GPIO_Mode = Serial0_Mode;

 GPIO_InitStructure.GPIO_Pull = DISABLE;

 GPIO_InitStructure.GPIO_HighPwr = DISABLE;

 GPIO_Init(&GPIO_InitStructure);

  

 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;

 GPIO_InitStructure.GPIO_Mode = Serial0_Mode;  

 GPIO_Init(&GPIO_InitStructure);

    

 /* Configure I2C in master mode */

 I2C_StructInit(&I2C_InitStruct);

 I2C_InitStruct.I2C_OperatingMode = I2C_OperatingMode_Master;

 I2C_InitStruct.I2C_ClockSpeed = baudrate;

 I2C_Init((I2C_Type*)I2C2, &I2C_InitStruct);

  

 /* Clear all I2C pending interrupts */

 I2C_ClearITPendingBit((I2C_Type*)I2C2, I2C_IT_MSK);

  

 return SUCCESS;

}

2 REPLIES 2
ahmed.khabkhab
Associate

Change

while (RESET == I2C_GetITStatus((I2C_Type*)I2C2, I2C_IT_MTD));

To

while (RESET == I2C_GetITStatus((I2C_Type*)I2C2, I2C_IT_MTD | I2C_IT_MTDWS));

rnone
Associate II

Into the second loop, you need to read the fifo to empty it else you will either end-up with either locked-down I2C logic or overrun.

Fifo size is 16, this is why you get into trouble over that size.

something along the lines:

 /* Wait loop */

 clock_arm(500000);

 do {

     uint8_t c;

   if(I2C_OP_ABORTED == I2C_GetStatus((I2C_Type*)I2C2))

     return ERROR;

   i = I2C_ITStatus((I2C_Type*)I2C2);

   if ((i & I2C_IT_RXFE) == 0)

     {

       c = I2C_ReceiveData((I2C_Type*)I2C2);

       if (NumByteToRead)

         {

           NumByteToRead--;

           *pBuffer++ = c;

         }

       clock_arm(500000);

       continue;

     }

   if (i & I2C_IT_MTD)        /* Check and of Transaction */

       break;

   if (clock_expired())

       return(ERROR);

 } while (RESET == I2C_GetITStatus((I2C_Type*)I2C2, I2C_IT_MTD));

(And don't forget the recheck FIFO after the loop to be sure something left over).