2018-11-26 01:43 PM
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;
}
2019-09-03 01:16 AM
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));
2019-09-05 02:32 AM
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).