갖고있는 라이다(Ridar lite v3)는 기본적인 인터페이스가 I2C와 PWM방식을 지원한다.
하지만 TC237의 경우 I2C를 하드웨어적으로 지원하지 않는다고 나와있다
그래서 GPIO로 직접 I2C를 구현해야한다.
라이다 데이터시트를 보고 I2C구현
오실로 스코프로 클럭 비트 하나하나 확인했다...
#include "IfxPort_reg.h"
#include "IfxPort.h"
#include <SysSe/Bsp/Bsp.h>
#define RIDAR_ADD 0x62<<1
#define RIDAR_SDA 2
#define RIDAR_SCL 0
#define RIDAR_CMD_WRITE 0xA0
#define RIDAR_CMD_READ 0xA1
#define SET 1
#define RESET 0
#define I2C_PageSize 16
void I2CStart( void )
{
IfxPort_setPinState(&MODULE_P22, RIDAR_SDA, IfxPort_State_high);
waitTime(1*TimeConst_100us);
IfxPort_setPinState(&MODULE_P22, RIDAR_SCL, IfxPort_State_high);
waitTime(1*TimeConst_100us);
IfxPort_setPinState(&MODULE_P22, RIDAR_SDA, IfxPort_State_low);
waitTime(1*TimeConst_100us);
IfxPort_setPinState(&MODULE_P22, RIDAR_SCL, IfxPort_State_low);
}
void I2CStop( void )
{
IfxPort_setPinState(&MODULE_P22, RIDAR_SDA, IfxPort_State_low);
waitTime(1*TimeConst_100us);
IfxPort_setPinState(&MODULE_P22, RIDAR_SCL, IfxPort_State_high);
waitTime(1*TimeConst_100us);
IfxPort_setPinState(&MODULE_P22, RIDAR_SDA, IfxPort_State_high);
waitTime(1*TimeConst_100us);
IfxPort_setPinState(&MODULE_P22, RIDAR_SCL, IfxPort_State_low);
}
unsigned char I2CSlaveAck( void )
{
waitTime(1*TimeConst_100us);
unsigned int TimeOut;
unsigned char RetValue;
Dio_Configuration(&MODULE_P22, RIDAR_SDA, IfxPort_Mode_inputPullUp ,IfxPort_PadDriver_cmosAutomotiveSpeed1,IfxPort_State_high);
IfxPort_setPinState(&MODULE_P22, RIDAR_SCL, IfxPort_State_high);
TimeOut = 10000;
while( TimeOut-- > 0 )
{
if( SET == IfxPort_getPinState(&MODULE_P22, RIDAR_SDA ) )
{
RetValue = RESET;
break;
}
else
{
RetValue = SET;
}
}
IfxPort_setPinState(&MODULE_P22, RIDAR_SCL, IfxPort_State_low);
Dio_Configuration(&MODULE_P22, RIDAR_SDA, IfxPort_Mode_outputPushPullGeneral ,IfxPort_PadDriver_cmosAutomotiveSpeed1,IfxPort_State_high);
return RetValue;
waitTime(1*TimeConst_100us);
}
void I2CWriteByte( unsigned char byte )
{
unsigned char i;
for( i=0; i<8; i++ )
{
if( 0X80 & byte )
IfxPort_setPinState(&MODULE_P22, RIDAR_SDA, IfxPort_State_high);
else
IfxPort_setPinState(&MODULE_P22, RIDAR_SDA, IfxPort_State_low);
byte <<= 1;
waitTime(1*TimeConst_100us);
IfxPort_setPinState(&MODULE_P22, RIDAR_SCL, IfxPort_State_high);
waitTime(1*TimeConst_100us);
IfxPort_setPinState(&MODULE_P22, RIDAR_SCL, IfxPort_State_low);
waitTime(1*TimeConst_100us);
}
}
unsigned char I2CReadByte( void )
{
waitTime(1*TimeConst_100us);
unsigned char i;
unsigned char ReadValue = 0;
unsigned char bit;
Dio_Configuration(&MODULE_P22, RIDAR_SDA, IfxPort_Mode_inputPullUp ,IfxPort_PadDriver_cmosAutomotiveSpeed1,IfxPort_State_high);
for( i=0; i<8; i++ )
{
IfxPort_setPinState(&MODULE_P22, RIDAR_SCL, IfxPort_State_high);
waitTime(1*TimeConst_100us);
if( SET == IfxPort_getPinState(&MODULE_P22, RIDAR_SDA ) )
bit = 0X01;
else
bit = 0x00;
ReadValue = (ReadValue<<1)|bit;
IfxPort_setPinState(&MODULE_P22, RIDAR_SCL, IfxPort_State_low);
waitTime(1*TimeConst_100us);
}
Dio_Configuration(&MODULE_P22, RIDAR_SDA, IfxPort_Mode_outputPushPullGeneral ,IfxPort_PadDriver_cmosAutomotiveSpeed1,IfxPort_State_low);
return ReadValue;
waitTime(1*TimeConst_100us);
}
unsigned char RidarWriteByte( uint8 Sen_addr, uint8 Reg_addr, uint8 data )
{
waitTime(1*TimeConst_100us);
I2CStart();
waitTime(1*TimeConst_100us);
I2CWriteByte((uint8)Sen_addr);
if( RESET == I2CSlaveAck() )
{
return RESET;
}
I2CWriteByte((uint8)Reg_addr);
if( RESET == I2CSlaveAck() )
{
return RESET;
}
I2CWriteByte(data);
if( RESET == I2CSlaveAck() )
{
return RESET;
}
I2CStop();
waitTime(1*TimeConst_100us);
return SET;
}
unsigned char RidarReadByte( uint8 Sen_addr, uint8 Reg_addr, uint8* ReadValue )
{
waitTime(1*TimeConst_100us);
//unsigned char *ReadValue;
I2CStart();
waitTime(1*TimeConst_100us);
I2CWriteByte((uint8)Sen_addr);
if( RESET == I2CSlaveAck() )
{
return RESET;
}
I2CWriteByte((uint8)Reg_addr);
if( RESET == I2CSlaveAck() )
{
return RESET;
}
I2CStop();
waitTime(10*TimeConst_100us);
I2CStart();
I2CWriteByte((uint8)Sen_addr | 0x01);
if( RESET == I2CSlaveAck() )
{
return RESET;
}
ReadValue[0] = I2CReadByte();
IfxPort_setPinState(&MODULE_P22, RIDAR_SDA, IfxPort_State_low);
IfxPort_setPinState(&MODULE_P22, RIDAR_SCL, IfxPort_State_high);
waitTime(1*TimeConst_100us);
IfxPort_setPinState(&MODULE_P22, RIDAR_SCL, IfxPort_State_low);
waitTime(2*TimeConst_100us);
ReadValue[1] = I2CReadByte();
IfxPort_setPinState(&MODULE_P22, RIDAR_SDA, IfxPort_State_high);
IfxPort_setPinState(&MODULE_P22, RIDAR_SCL, IfxPort_State_high);
waitTime(1*TimeConst_100us);
IfxPort_setPinState(&MODULE_P22, RIDAR_SCL, IfxPort_State_low);
waitTime(1*TimeConst_100us);
IfxPort_setPinState(&MODULE_P22, RIDAR_SDA, IfxPort_State_low);
I2CStop();
waitTime(1*TimeConst_100us);
}
void Ridarconfigure(int configuration, uint8 Sen_addr)
{
RidarWriteByte(Sen_addr,0x00,0x04);
switch (configuration)
{
case 0: // Default mode, balanced performance
RidarWriteByte(Sen_addr,0x02,0x80);
RidarWriteByte(Sen_addr,0x04,0x08);
RidarWriteByte(Sen_addr,0x1c,0x00);
break;
case 1: // Short range, high speed
RidarWriteByte(Sen_addr,0x02,0x1d);
RidarWriteByte(Sen_addr,0x04,0x08);
RidarWriteByte(Sen_addr,0x1c,0x00);
break;
case 2: // Default range, higher speed short range
RidarWriteByte(Sen_addr,0x02,0x80);
RidarWriteByte(Sen_addr,0x04,0x00);
RidarWriteByte(Sen_addr,0x1c,0x00);
break;
case 3: // Maximum range
RidarWriteByte(Sen_addr,0x02,0xff);
RidarWriteByte(Sen_addr,0x04,0x08);
RidarWriteByte(Sen_addr,0x1c,0x00);
break;
case 4: // High sensitivity detection, high erroneous measurements
RidarWriteByte(Sen_addr,0x02,0x80);
RidarWriteByte(Sen_addr,0x04,0x08);
RidarWriteByte(Sen_addr,0x1c,0x80);
break;
case 5: // Low sensitivity detection, low erroneous measurements
RidarWriteByte(Sen_addr,0x02,0x80);
RidarWriteByte(Sen_addr,0x04,0x08);
RidarWriteByte(Sen_addr,0x1c,0xb0);
break;
}
} /* LIDARLite::configure */
참고: http://blog.naver.com/PostView.nhn?blogId=io044&logNo=20172757719
참고2: https://www.ngolongtech.net/2016/12/in-this-topic-i-show-how-to-get-data.html