Low-voltage 8-bit I2C-bus and SMBus low power I/O port with interrupt, weak pull-up and Agile I/O

Dependencies:   mbed

Revision:
0:16f7f665ba9d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PCAL9554B.cpp	Wed Feb 04 06:10:27 2015 +0000
@@ -0,0 +1,157 @@
+#include "mbed.h"
+#include "PCAL9554B.h"
+ 
+I2C i2c(p28,p27);        // sda, scl
+Serial pc(USBTX, USBRX); // tx, rx
+char cmd[32];
+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("PCAL9554B Sample Program\r\n");
+    set_ch(2);              // PCAL9554Bはch1に接続
+
+  // PCAL9554B
+    while(1)
+    {
+        pc.printf("入力(PU) … 1, 出力 … 2, 出力-入力反転 … 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_enable;
+            cmd[1] = 0xff;           // all PUPD enable
+            i2c.write(PCAL9554B_ADDR, cmd, 2);
+            cmd[0] = PUPD_selection;
+            cmd[1] = 0xff;           // all PU
+            i2c.write(PCAL9554B_ADDR, cmd, 2);
+
+            for(i=0; i<20; i++)
+            {
+                cmd[0] = Input_port;
+                i2c.write(PCAL9554B_ADDR, cmd, 1);
+                i2c.read(PCAL9554B_ADDR, cmd, 1);    // Inport Regを読込み
+                pc.printf("Input P0=%02x\r\n",cmd[0]); // InPort Regを表示
+                wait(0.5);
+            }
+            pc.printf("入力(PU) Sample End\r\n");
+            break;
+            
+        case 2:
+            pc.printf("出力 Sample Start\r\n");
+
+            cmd[0] = Configuration;
+            cmd[1] = 0x0;           // all output
+            i2c.write(PCAL9554B_ADDR, cmd, 2);
+            for(i=0; i<256; i++)
+            {
+                cmd[0] = Output_port;
+                cmd[1] = i;           // P0 = i
+                i2c.write(PCAL9554B_ADDR, cmd, 2);
+
+                cmd[0] = Input_port;           // input
+                i2c.write(PCAL9554B_ADDR, cmd, 1, true);   // cmd[0]Regにcmd[1]を書込み
+                i2c.read(PCAL9554B_ADDR, cmd, 1);    // Input Regを読込み
+                pc.printf("Output P=%02x Input P=%02x\r\n",cmd[1],cmd[0]); // Cont Regを表示
+                wait(0.1);
+            }
+            pc.printf("出力 Sample End\r\n");
+
+            cmd[0] = Configuration;
+            cmd[1] = 0xff;           // all input
+            i2c.write(PCAL9554B_ADDR, cmd, 2);
+
+            break;
+            
+        case 3:
+            pc.printf("出力-入力反転 Sample Start\r\n");
+
+            cmd[0] = Configuration;
+            cmd[1] = 0x0;           // all output
+            i2c.write(PCAL9554B_ADDR, cmd, 2);
+
+            cmd[0] = Polarity_Inversion;
+            cmd[1] = 0xff;           // all inversion
+            i2c.write(PCAL9554B_ADDR, cmd, 2);
+
+            for(i=0; i<256; i++)
+            {
+                cmd[0] = Output_port;
+                cmd[1] = i;           // P0 = i
+                i2c.write(PCAL9554B_ADDR, cmd, 2);
+
+                cmd[0] = Input_port;           // input
+                i2c.write(PCAL9554B_ADDR, cmd, 1, true);   // cmd[0]Regにcmd[1]を書込み
+                i2c.read(PCAL9554B_ADDR, cmd, 1);    // Input Regを読込み
+                pc.printf("Output P=%02x Input P=%02x\r\n",cmd[1],cmd[0]); // Cont Regを表示
+                wait(0.1);
+            }
+            pc.printf("出力-入力反転 Sample End\r\n");
+
+            cmd[0] = Configuration;
+            cmd[1] = 0xff;           // all input
+            i2c.write(PCAL9554B_ADDR, cmd, 2);
+            cmd[0] = Polarity_Inversion;
+            cmd[1] = 0x00;           // all no inversion
+            i2c.write(PCAL9554B_ADDR, cmd, 2);
+
+            break;
+        default:
+            break;
+        }    
+    }
+}