I2C バスを使用して Pi と通信する AdaFruit サーボ モーター Pi Hat と通信するための C++ コード (ただし、私の例はストレート c) を作成しています。ioctl I2C_RDWR メカニズムを使用しようとすると問題が発生します。通話から「Bad Address」ステータスが返されます。どのアドレスを指定しても (ただし、ハットは 0x40 に応答します)、常に失敗します。コードを自己完結型の短いモジュールにまとめました。これは、このサイトへの私の最初の投稿です。何か間違いを犯した場合は、ご容赦ください。
添付のコードを実行すると、次の応答が返されます。
I2C_FUNC_I2C OK
I2C_FUNC_10BIT_ADDR
I2C_FUNC_PROTOCOL_MANGLING
I2C_FUNC_SMBUS_QUICK OK
I2C_FUNC_SMBUS_READ_BYTE OK
I2C_FUNC_SMBUS_WRITE_BYTE OK
I2C_FUNC_SMBUS_READ_BYTE_DATA OK
I2C_FUNC_SMBUS_WRITE_BYTE_DATA OK
I2C_FUNC_SMBUS_READ_WORD_DATA OK
I2C_FUNC_SMBUS_WRITE_WORD_DATA OK
I2C_FUNC_SMBUS_PROC_CALL OK
I2C_FUNC_SMBUS_READ_BLOCK_DATA
I2C_FUNC_SMBUS_WRITE_BLOCK_DATA OK
I2C_FUNC_SMBUS_READ_I2C_BLOCK OK
I2C_FUNC_SMBUS_WRITE_I2C_BLOCK OK
Write failed: Bad address
私の Pi はモデル B、バージョン 2 です。i2c システムを有効にして、i2c デバイスを確認できます。
crw-rw-rw- 1 root i2c 89, 1 Aug 31 23:02 i2c-1
どんな助けでも大歓迎です。
コードは次のとおりです。
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/i2c-dev.h>
#include <linux/i2c.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
int main() {
int file;
int devAddr = 0x40;
int status;
uint32_t funcs;
uint8_t data = 0xAA;
struct i2c_rdwr_ioctl_data request;
struct i2c_msg ioctlMsg[1];
file = open("/dev/i2c-1", O_RDWR);
if(file < 0) {
perror("could not open device");
return 1;
}
status = ioctl(file, I2C_FUNCS, &funcs);
if(status < 0) {
perror("could not get funcs");
return 3;
}
fprintf(stderr, "\nI2C_FUNC_I2C ");
if ( I2C_FUNC_I2C & funcs) fprintf(stderr, "\t\t\t\tOK");
fprintf(stderr, "\nI2C_FUNC_10BIT_ADDR ");
if ( I2C_FUNC_10BIT_ADDR & funcs) fprintf(stderr, "\t\t\tOK");
fprintf(stderr, "\nI2C_FUNC_PROTOCOL_MANGLING ");
if ( I2C_FUNC_PROTOCOL_MANGLING & funcs) fprintf(stderr, "\tOK");
fprintf(stderr, "\nI2C_FUNC_SMBUS_QUICK ");
if ( I2C_FUNC_SMBUS_QUICK & funcs) fprintf(stderr, "\t\t\tOK");
fprintf(stderr, "\nI2C_FUNC_SMBUS_READ_BYTE ");
if ( I2C_FUNC_SMBUS_READ_BYTE & funcs) fprintf(stderr, "\t\tOK");
fprintf(stderr, "\nI2C_FUNC_SMBUS_WRITE_BYTE ");
if ( I2C_FUNC_SMBUS_WRITE_BYTE & funcs) fprintf(stderr, "\t\tOK");
fprintf(stderr, "\nI2C_FUNC_SMBUS_READ_BYTE_DATA ");
if ( I2C_FUNC_SMBUS_READ_BYTE_DATA & funcs) fprintf(stderr, "\t\tOK");
fprintf(stderr, "\nI2C_FUNC_SMBUS_WRITE_BYTE_DATA ");
if ( I2C_FUNC_SMBUS_WRITE_BYTE_DATA & funcs) fprintf(stderr, "\t\tOK");
fprintf(stderr, "\nI2C_FUNC_SMBUS_READ_WORD_DATA ");
if ( I2C_FUNC_SMBUS_READ_WORD_DATA & funcs) fprintf(stderr, "\t\tOK");
fprintf(stderr, "\nI2C_FUNC_SMBUS_WRITE_WORD_DATA ");
if ( I2C_FUNC_SMBUS_WRITE_WORD_DATA & funcs) fprintf(stderr, "\t\tOK");
fprintf(stderr, "\nI2C_FUNC_SMBUS_PROC_CALL ");
if ( I2C_FUNC_SMBUS_PROC_CALL & funcs) fprintf(stderr, "\t\tOK");
fprintf(stderr, "\nI2C_FUNC_SMBUS_READ_BLOCK_DATA ");
if ( I2C_FUNC_SMBUS_READ_BLOCK_DATA & funcs) fprintf(stderr, "\t\tOK");
fprintf(stderr, "\nI2C_FUNC_SMBUS_WRITE_BLOCK_DATA ");
if ( I2C_FUNC_SMBUS_WRITE_BLOCK_DATA & funcs) fprintf(stderr, "\tOK");
fprintf(stderr, "\nI2C_FUNC_SMBUS_READ_I2C_BLOCK ");
if ( I2C_FUNC_SMBUS_READ_I2C_BLOCK & funcs) fprintf(stderr, "\t\tOK");
fprintf(stderr, "\nI2C_FUNC_SMBUS_WRITE_I2C_BLOCK ");
if ( I2C_FUNC_SMBUS_WRITE_I2C_BLOCK & funcs) fprintf(stderr, "\t\tOK");
fprintf(stderr, "\n");
memset(ioctlMsg, 0, sizeof(struct i2c_rdwr_ioctl_data) * 2);
ioctlMsg[0].addr = 0x0;
ioctlMsg[0].flags = 0; /* write command */
ioctlMsg[0].len = 1;
ioctlMsg[0].buf = &data;
request.msgs = ioctlMsg;
request.nmsgs = 1;
status = ioctl(file, I2C_RDWR, request);
if(status < 0) {
perror("Write failed");
return 2;
}
close(file);
return 0;
}