Low-voltage 16-bit I2C-bus GPIO with Agile I/O, interrupt and weak pull-up

Dependencies:   mbed

PCAL9555A.cpp

Committer:
wataaki
Date:
2015-02-04
Revision:
0:e714fc19ba54

File content as of revision 0:e714fc19ba54:

#include "mbed.h"
#include "PCAL9555A.h"
 
I2C i2c(p28,p27);        // sda, scl
Serial pc(USBTX, USBRX); // tx, rx
char cmd[32];
char buf[4];
int i, j, k;
int sw;

void set_ch(char sel)
{    // PCA9541のサンプル
        // MST_0側の自分にスレーブ側の制御権を得る場合
    cmd[0] = 1;                     // PCA9541 コマンドコード Cont Reg
    i2c.write( 0xe2, cmd, 1);       // Cont Regを指定
    i2c.read( 0xe2, cmd, 1);        // Cont Regを読込み
    wait(0.1);                      // 0.1s待つ
    switch(cmd[0] & 0xf)
    {
    case 0:                         // bus off, has control
    case 1:                         // bus off, no control
    case 5:                         // bus on, no control
        cmd[0] = 1;                 // PCA9541 コマンドコード Cont Reg
        cmd[1] = 4;                 // bus on, has control
        i2c.write( 0xe2, cmd, 2);   // Cont Regにcmd[1]を書込み
        i2c.read( 0xe2, cmd, 1);    // Cont Regを読込み
        break;
    case 2:                         // bus off, no control
    case 3:                         // bus off, has control
    case 6:                         // bus on, no control
        cmd[0] = 1;                 // PCA9541 コマンドコード Cont Reg
        cmd[1] = 5;                 // bus on, has control
        i2c.write( 0xe2, cmd, 2);   // Cont Regにcmd[1]を書込み
        i2c.read( 0xe2, cmd, 1);    // Cont Regを読込み
        break;
    case 9:                         // bus on, no control
    case 0xc:                       // bus on, no control
    case 0xd:                       // bus off, no control
        cmd[0] = 1;                 // PCA9541 コマンドコード Cont Reg
        cmd[1] = 0;                 // bus on, has control
        i2c.write( 0xe2, cmd, 2);   // Cont Regにcmd[1]を書込み
        i2c.read( 0xe2, cmd, 1);    // Cont Regを読込み
        break;
    case 0xa:                       // bus on, no control
    case 0xe:                       // bus off, no control
    case 0xf:                       // bus on, has control
        cmd[0] = 1;                 // PCA9541 コマンドコード Cont Reg
        cmd[1] = 1;                 // bus on, has control
        i2c.write( 0xe2, cmd, 2);   // Cont Regにcmd[1]を書込み
        i2c.read( 0xe2, cmd, 1);    // Cont Regを読込み
        break;
    default:
        break;
    }

    cmd[0] = sel;                   // PCA9546 Cont Reg sel channel enabled
    i2c.write( 0xe8, cmd, 1);       // Send command string
}
 
int main ()
{
   i2c.frequency(100000);
    pc.printf("PCAL9555A Sample Program\r\n");
    set_ch(1);              // PCAL9555Aはch0に接続

  // PCAL9555A
    while(1)
    {
        pc.printf("入力(PU) … 1, 出力 … 2, Interrupt_status … 3 ? \r\n");
        pc.scanf("%d", &sw);
        pc.printf("%d\r\n", sw);
        switch (sw)
        {
        case 1:
            pc.printf("入力(PU) Sample Start\r\n");

            cmd[0] = PUPD_enable0;
            cmd[1] = 0xff;           // all P0 PUPD enable
            i2c.write(PCAL9555A_ADDR, cmd, 2);
            cmd[0] = PUPD_selection0;
            cmd[1] = 0xff;           // all P0 PU
            i2c.write(PCAL9555A_ADDR, cmd, 2);
            cmd[0] = PUPD_enable1;
            cmd[1] = 0xff;           // all P1 PUPD enable
            i2c.write(PCAL9555A_ADDR, cmd, 2);
            cmd[0] = PUPD_selection1;
            cmd[1] = 0xff;           // all P1 PU
            i2c.write(PCAL9555A_ADDR, cmd, 2);

            for(i=0; i<20; i++)
            {
                cmd[0] = Input_port0;
                i2c.write(PCAL9555A_ADDR, cmd, 1);
                i2c.read(PCAL9555A_ADDR, cmd, 1);    // Input port0 Regを読込み
                buf[0] = cmd[0];
                cmd[0] = Input_port1;
                i2c.write(PCAL9555A_ADDR, cmd, 1);
                i2c.read(PCAL9555A_ADDR, cmd, 1);    // Input port1 Regを読込み
                pc.printf("Input P0=%02x P1=%02x\r\n", buf[0], cmd[0]); // Input port Regを表示
                wait(0.5);
            }
            pc.printf("入力(PU) Sample End\r\n");
            break;
            
        case 2:
            pc.printf("出力 Sample Start\r\n");

            cmd[0] = Configuration0;
            cmd[1] = 0x0;           // all P1 output
            i2c.write(PCAL9555A_ADDR, cmd, 2);
            cmd[0] = Configuration1;
            cmd[1] = 0x0;           // all P2 output
            i2c.write(PCAL9555A_ADDR, cmd, 2);
            for(i=0; i<256; i++)
            {
                cmd[0] = Output_port0;
                cmd[1] = i;           // P1 = i
                buf[0] = cmd[1];        // data buffer
                i2c.write(PCAL9555A_ADDR, cmd, 2);
                cmd[0] = Output_port1;
                cmd[1] = i;           // P2 = 255-i
                cmd[1] = 255-i;           // P2 = 255-i
                buf[1] = cmd[1];        // data buffer
                i2c.write(PCAL9555A_ADDR, cmd, 2);

                cmd[0] = Input_port0;
                i2c.write(PCAL9555A_ADDR, cmd, 1, true);
                i2c.read(PCAL9555A_ADDR, cmd, 1);    // Input port1 Regを読込み
                buf[2] = cmd[0];        // data buffer
                cmd[0] = Input_port1;
                i2c.write(PCAL9555A_ADDR, cmd, 1, true);
                i2c.read(PCAL9555A_ADDR, cmd, 1);    // Input port1 Regを読込み
                buf[3] = cmd[0];        // data buffer

                pc.printf("Output P0=%02x P1=%02x  Input P0=%02x P1=%02x\r\n", buf[0], buf[1], buf[2], buf[3]);
                wait(0.1);
            }
            pc.printf("出力 Sample End\r\n");

            cmd[0] = Configuration0;
            cmd[1] = 0xff;           // all input
            i2c.write(PCAL9555A_ADDR, cmd, 2);
            break;
           
        case 3:
            pc.printf("Interrupt_status Sample Start\r\n");

            cmd[0] = Configuration0;
            cmd[1] = 0xff;           // all P0 input
            i2c.write(PCAL9555A_ADDR, cmd, 2);

            cmd[0] = Configuration1;
            cmd[1] = 0xff;           // all P1 input
            i2c.write(PCAL9555A_ADDR, cmd, 2);

            cmd[0] = Interrupt_mask0;
            cmd[1] = 0x00;           // all P0 割込み可
            i2c.write(PCAL9555A_ADDR, cmd, 2);

            cmd[0] = Interrupt_mask1;
            cmd[1] = 0x00;           // all P1 割込み可
            i2c.write(PCAL9555A_ADDR, cmd, 2);

            cmd[0] = Input_port0;
            i2c.write(PCAL9555A_ADDR, cmd, 1, true);
            i2c.read(PCAL9555A_ADDR, cmd, 1);    // Input_port0からオリジナル値の取得

            cmd[0] = Input_port1;
            i2c.write(PCAL9555A_ADDR, cmd, 1, true);
            i2c.read(PCAL9555A_ADDR, cmd, 1);    // Input_port1からオリジナル値の取得

            for(i=0; i<100; i++)
            {
                cmd[0] = Interrupt_status0;
                i2c.write(PCAL9555A_ADDR, cmd, 1, true);
                i2c.read(PCAL9555A_ADDR, cmd, 1);    // Interrupt_status0 Regを読込み
                buf[0] = cmd[0];        // data buffer

                cmd[0] = Interrupt_status1;
                i2c.write(PCAL9555A_ADDR, cmd, 1, true);
                i2c.read(PCAL9555A_ADDR, cmd, 1);    // Interrupt_status1 Regを読込み
                pc.printf("Interrupt_status P0=%02x P1=%02x\r\n", buf[0], cmd[0]); // 割込状況を表示
                wait(0.2);
            }
            pc.printf("Interrupt_status Sample End\r\n");
            break;
        default:
            break;
        }    
    }
}