Raspberry Pi > C > RPi_i2c_comm_180227: v1.1 > clock stretching 지원(소프트웨어 I2C)
Raspberry Pi 2 Model B (以下RPi)
Raspbian Jessie
gcc (Raspbian 4.9.2-10) 4.9.2
とあるI2Cセンサー (clock strecthingがある通信)
Analog Discovery 2 (以下AD2)
지난번
I2C 통신의 센서와의 통신을 RPi로 c 실장했다.
이번에
어떤 I2C 센서(clock strecthing이 있는 통신) 대응을 위해, clock strecthing을 고려한 ACK 접수로 변경.
Clock stretching의 타이밍 다이어그램은 아래 등 참조.
ぇtps://ぇあrん. s파rk분. 코 m / 쓰리 아 ls / 2c
GitHub 리포지토리
v1.1@GitHub
처리 개요
RPi_i2c_comm_CLKSTR_180712.c
라는 파일에서 Clock stretching을 고려한 I2C 통신을 하고 있다.구체적으로는
send_stopContinuousMeasurement()
의 내용이 된다.i2c_clockStretching_IsACK()
를 이번에 추가해, 이 함수내에서 SCL=Low 상태를 확인하도록 하고 있다.RPi_i2c_comm_CLKSTR_180712.c
...
static void send_stopContinuousMeasurement(int slvAdr)
{
// write header
i2c_SendStartCondition(/* withInit=*/true);
i2c_SendSlaveAddress(slvAdr, /*bfRead=*/false);
if (i2c_clockStretching_IsACK(kMaxloop_SCL_stretch)) {
printf("ACK\n");
};
// send command
i2c_SendData(0x06); // Function Code
if (i2c_clockStretching_IsACK(kMaxloop_SCL_stretch)) {
printf("ACK\n");
};
i2c_SendData(0x00); // Address MSB
if (i2c_clockStretching_IsACK(kMaxloop_SCL_stretch)) {
printf("ACK\n");
};
i2c_SendData(0x37); // Address LSB
if (i2c_clockStretching_IsACK(kMaxloop_SCL_stretch)) {
printf("ACK\n");
};
i2c_SendData(0x00); // Content MSB
if (i2c_clockStretching_IsACK(kMaxloop_SCL_stretch)) {
printf("ACK\n");
};
i2c_SendData(0x01); // Content LSB
if (i2c_clockStretching_IsACK(kMaxloop_SCL_stretch)) {
printf("ACK\n");
};
i2c_SendData(0xF0); // CRC LSB
if (i2c_clockStretching_IsACK(kMaxloop_SCL_stretch)) {
printf("ACK\n");
};
i2c_SendData(0x64); // CRC MSB
if (i2c_clockStretching_IsACK(kMaxloop_SCL_stretch)) {
printf("ACK\n");
};
i2c_SendStopCondition();
}
...
i2c_clockStretching_IsACK()
i2c_comm_180302.c
...
bool i2c_clockStretching_IsACK(int maxloop)
{
bool pinIsH;
int cnt=0;
i2c_gpio_setSCL_level(GPIO_LOW);
i2c_gpio_setSDA_direction(GPIO_IN);
myDelay();
i2c_gpio_setSCL_level(GPIO_HIGH);
// { clock streching
i2c_gpio_setSCL_direction(GPIO_IN);
myDelay();
while(true) {
if(i2c_gpio_isSCL_high()) {
break;
}
if(cnt > maxloop) {
i2c_gpio_setSCL_direction(GPIO_OUT); // end clock stretching
return false;
}
myDelay();
cnt++;
}
// } clock streching
pinIsH = i2c_gpio_isSDA_high();
myDelay();
// set after reading SDA
// (will fail to get ACK when set before reading SDA)
i2c_gpio_setSCL_direction(GPIO_OUT); // end clock stretching
return (pinIsH == BOOL_ACK);
}
...
비고 : 상기에서
i2c_gpio_setSCL_direction(GPIO_OUT);
는 SDA 판독 후이다. SDA 읽기 전에 SCL의 방향을 변경하는 구현에서는 ACK를 수신할 수 없었다.로직 확인
상기 커맨드 발행시의 파형을 Analog Discovery 2 (이하 AD2)로 확인했다.
커맨드 송신 후의 ACK를 받을 수 있다.
Reference
이 문제에 관하여(Raspberry Pi > C > RPi_i2c_comm_180227: v1.1 > clock stretching 지원(소프트웨어 I2C)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/7of9/items/e2b92facbacf8825b19f텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)