2016-09-01 3 views
0

Ich schreibe C++ - Code (aber mein Beispiel ist gerade c), um mit einem AdaFruit Servomotor Pi Hat zu sprechen, der den I2C-Bus verwendet, um mit dem Pi zu kommunizieren. Ich habe ein Problem, wenn ich versuche, den ioctl I2C_RDWR-Mechanismus zu verwenden. Ich bekomme den Status 'Schlechte Adresse' vom Anruf zurück. Es spielt keine Rolle, welche Adresse ich gebe (der Hut antwortet auf 0x40), es schlägt immer fehl. Ich habe den Code in ein kurzes Modul gekapselt, das eigenständig ist. Dies ist mein erster Beitrag zu dieser Seite. Wenn ich also einen Fauxpas gemacht habe, bitte vergib mir.Unerwarteter Zustand mit I2C auf Raspberry Pi

Wenn ich den beigefügten Code ausführen, bekomme ich die folgende Antwort:

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 

My Pi ist ein Modell B, Version 2. Ich habe das i2c-System aktiviert und kann die i2c Gerät sehen:

crw-rw-rw- 1 root i2c 89, 1 Aug 31 23:02 i2c-1 

Jede Hilfe wäre willkommen.

Der Code folgt:

#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; 
} 

Antwort

0

ich mein Problem gefunden, stellt sich heraus, dass die ‚schlechte Adresse‘ nicht an die Adresse des I2C-Gerät wurde Bezug genommen wird, aber die Adresse des Blocks in der gesendeten ioctl-Befehl. Ich hatte vergessen, die Adresse zu übergeben, im Gegensatz zu dem Wert des Parameters in meinem Aufruf an ioctl.