1

Fintek F75111 GPIO を搭載した Atom ボードがあります。製造元から、チップにアクセスするための SMbus アドレスは 06EH であるという情報があります。

Linux で GPIO の値を読み書きしようとしています。このような Windows 用に作成されたメーカーのサンプル プログラムがあります。

#include “math.h”
#include “stdio.h”
#include “dos.h”
void main(void){
    int SMB_PORT_AD = 0x400;
    int SMB_DEVICE_ADD = 0x6E;
    /*75111R’s Add=6eh */
    //programming DIO as output //0:input 1:Output
    /* Index 10, GPIO1x Output pin control */
    SMB_Byte_WRITE(SMB_PORT_AD,SMB_DEVICE_ADD,0x10,0xff); delay(10);
    //programming DIO default LOW
    /* Index 11, GPIO1x Output Data value */
    SMB_Byte_WRITE(SMB_PORT_AD,SMB_DEVICE_ADD,0x11,0x00); delay(10);
}


unsigned char SMB_Byte_READ (int SMPORT, int DeviceID, int REG_INDEX)
{
    unsigned char SMB_R;
    outportb(SMPORT+02, 0x00); /* clear */ 
    outportb(SMPORT+00, 0xff); /* clear */ 
    delay(10);
    outportb(SMPORT+04, DeviceID+1); /* clear */ 
    outportb(SMPORT+03, REG_INDEX); /* clear */ 
    outportb(SMPORT+02, 0x48); /* read_byte */ 
    delay(10);
    SMB_R= inportb(SMPORT+05);
    return SMB_R;
}

void SMB_Byte_WRITE(int SMPORT, int DeviceID, int REG_INDEX, int REG_DATA)
{
    outportb(SMPORT+02, 0x00); /* clear */ 
    outportb(SMPORT+00, 0xff); /* clear */
    delay(10);
    outportb(SMPORT+04, DeviceID); /* clear */ 
    outportb(SMPORT+03, REG_INDEX); /* clear */
    outportb(SMPORT+05, REG_DATA); /* read_byte */
    outportb(SMPORT+02, 0x48); /* read_byte */
    delay(10);
}

これを Linux 互換関数 inb() および outb() に変換しようとしましたが、これが得られたものです。

#include <stdio.h>
#include <sys/io.h>

unsigned int gpio_read(int PORT, int DEVICE, int REG_INDEX){
    unsigned int RESPONSE;

    outb(0x00, PORT+02);
    outb(0xff, PORT+00);
    usleep(100);
    outb(DEVICE+1, PORT+04);
    outb(REG_INDEX, PORT+03);
    outb(0x48, PORT+02);
    usleep(100);
    RESPONSE = inb(PORT+05);
    return RESPONSE;
}

unsigned int gpio_write(int PORT, int DEVICE, int REG_INDEX, int REG_DATA){
    outb(0x00, PORT+02);
    outb(0xff, PORT+00);
    usleep(100);
    outb(DEVICE, PORT+04);
    outb(REG_INDEX, PORT+03);
    outb(DATA, PORT+05);
    outb(0x48, PORT+02);
    usleep(100);

}

void main() {
    int PORT = 0x400;
    int DEVICE = 0x6E;
    unsigned int RESPONSE;

    // Ask access to port from kernel
    ioperm(0x400, 100, 1);

    // GPIO1x set to input (0xff is output)
    gpio_write(PORT, DEVICE, 0x10, 0x00);

        RESPONSE = gpio_read(PORT, DEVICE, 1);
        printf("\n %u \n", RESPONSE);
}

GPIO1x インデックス 0x10 は、GPIO1x に接続されている 8 つの GPIO ポートが出力ポートか入力ポートかを設定するために使用されます。

GPIO の出力値はインデックス 0x11 を使用して設定され、ポートが入力ポートとして機能する場合は、インデックス 0x12 が入力値の読み取りに使用されます。

問題は、これが正しいかどうか、または値を読み取る方法がわからないことです (なぜ読み取り関数は読み取り前に何かを出力するのですか?!?)

私が実行すると:

RESPONSE = gpio_read(PORT, DEVICE, X);

1..9 の値で X を変更すると、出力として次のようになります: 0 8 8 0 0 0 0 0 0

8という数字は私を混乱させます...

4

1 に答える 1

4

SMBus ポートに直接書き込む代わりに、i2c ライブラリを使用したいと思います。I2C (および SMBUS) は 2 つのポート ピンを使用します。1 つはクロック用、もう 1 つはデータ用です。データはクロック エッジで送受信されます (同期)。コードを読むと、どちら (クロックまたはデータ) がいつアクセスされているのか明確にわかりません。

開始するには、i2ctools を開始点として使用します (このサイトを確認してください: http://elinux.org/Interfacing_with_I2C_Devices )。このツールは、マイクロプロセッサへの I2C バスに接続されたデバイスを見つけ、基本的な通信を実行するのに役立ちます。

それが役に立てば幸い...

于 2012-10-12T21:03:46.220 に答える