현재 개발하고 있는 디바이스에 여러개의 센서가 달려 있고 모두 I2C를 사용하고 있다.
그 중 2개의 센서는 40ms 주기로 번갈아 가며 I2C Transmit/Receive를 해야 하는 상황인데 이번에 GNSS 모듈에 대한 관련 기능을 구현하면서 확인해보니 HAL_I2C_Master_Transmit 실행 부분에서 TIMEOUT 에러가 발생하기 시작했다.
- HAL_I2C_GetError 함수로 에러를 확인해 보면 0x20 에러 발생 (HAL_I2C_ERROR_TIMEOUT)
- 아주 랜덤하게 에러가 발생했다. 시작하자마자 발생되기도 하고 5분 정도가 지나서 발생되기도 했다.
두개의 센서 중 하나의 I2C 인터페이싱 코드 부를 삭제하고 테스트해보면 에러가 발생하지 않는다. 아무래도 빠른 속도로 I2C를 수행하다보니 어느 순간 I2C 연결 디바이스가 준비되지 않은 상태에서 송수신을 시도하게 되면 에러가 발생되는 것 같다.
결론적으로 이 문제는 완벽한 해결 방법은 아닌 것 같지만 (Sampling interval 기준 데이터 누락이 매우 Critical한 문제라면...) HAL_I2C_IsDeviceReady() 함수를 이용하여 디바이스 준비 상태를 체크를 해 줌으로써 해결했다.
if(HAL_I2C_IsDeviceReady(&hi2c2,slaveAddr,10,100)==HAL_OK)
{
while(HAL_I2C_Master_Transmit(&hi2c2, (slaveAddr << 1) | 0x00, ®Addr, 1, HAL_MAX_DELAY)!= HAL_OK)
{
if (HAL_I2C_GetError(&hi2c2) != HAL_I2C_ERROR_AF)
{
Debug_Log("A sensor HAL_I2C_GetError_TX: Read_Waveform.\r\n")
Error_Handler();
}
}
while(HAL_I2C_GetState(&hi2c2) != HAL_I2C_STATE_READY); //Wait for the end of the transfer
while(HAL_I2C_Master_Receive(&hi2c2, (slaveAddr << 1) | 0x01, data, 3, HAL_MAX_DELAY) != HAL_OK)
{
...
}
}