I2C

Dependencies:   TextLCD mbed

Fork of I2C_Debug_for_RealTerm by jim hamblen

Revision:
1:be1498ba7fb4
Parent:
0:0c54b73b002c
Child:
2:fa8c916b42a9
--- a/main.cpp	Tue Mar 08 03:16:34 2011 +0000
+++ b/main.cpp	Fri Mar 11 03:25:42 2011 +0000
@@ -1,128 +1,114 @@
 #include "mbed.h"
-
 // The program sends and receives I2C commands using RealTerm's I2C tab feature
 // Run Realterm on PC and this program on mbed
 // In RealTerm connect to the mbed's USB virtual COM port
 // Switch to I2C tab
 // Type in I2C address & data to read and write and see the response
 // It is handy to debug complex I2C hardware setups
-// Prints "noack!" when no I2C device responds
+// Prints "No Ack!" when no I2C device responds to the address
+//
+// See Instructions at http://mbed.org/users/4180_1/notebook/i2c-debug-for-realterm/
+//
 DigitalOut myled(LED1);
 Serial pc(USBTX, USBRX);
 I2C i2c(p9,p10);
 
-char data_length=0;
-int read=0;
-int write=0;
-
-//ugly code structure - should start over and fix this later
-//now that I understand syntax for command strings a bit more - but it works
-// Read in two ASCII characters and convert to a byte
-// ...unless a command character is found
-int getbyte(char *data) {
-    char charin=0;
-    charin = pc.getc();
-    if (charin == 'R') {
-        read=1;
-        if (getbyte(&data_length)==0) pc.printf("error");
-        return 2;
-    }
-    if (charin == 'P') return 3;
-    if (charin > 'F') return 0;
-    if (charin <='9') charin = charin - '0';
-    else charin = charin +10 - 'A';
-    *data = charin << 4;
-    charin = pc.getc();
-    if (charin > 'F') return 0;
-    if (charin <='9') charin = charin - '0';
-    else charin = charin +10 - 'A';
-    *data = *data | charin;
-    return 1;
-}
 int main() {
-
-    char command=0;
-    char address=0x40;
-    char data[255];
+    char last_command=0;
+    char current_char=0;
+    char address=0;
+    char data [255];
+    char current_byte=0;
     char cmd[255];
     int cmd_count=0;
-    int more_cmd = 0;
+    int data_count=0;
+    int read=0;
+    int write=0;
+    int first_data_byte=0;
     int i=0;
+
     myled=1;
-    data[0]=0;
-    data[1]=0;
     i2c.frequency(75000);
     i2c.start();
+    i2c.stop();
     i2c.start();
-    pc.printf("\fmbed I2C ready\n\r");
-// loop forever waiting for PC serial commands
+    i2c.stop();
+// Send a start message to RealTerm
+    pc.printf("\fmbed I2C debug tool ready\n\r");
+// Loop processing command strings from RealTerm
     while (1) {
-        command = pc.getc();
-        switch (command) {
-            case 'S':
-                //Start - automatic start sent on read or write
-                data_length=0;
-                cmd_count=0;
-                read=0;
-                write=0;
-                // in case of multiple starts 
-                while (getbyte(&address)==0) {i2c.start();};
-                pc.printf(" - I2C address=%2.2X ", address);
-                //odd address means a read, otherwise a write
-                if ((address & 0x01) == 1) read=1;
-                else write=1;
-                if (read ==1) {
-                //read number of bytes to read
-                    if (getbyte(&data_length)==0) break;
+        current_char = pc.getc();
+        // Is it a two character ASCII string data byte value
+        if (current_char <='F') {
+            // convert to a binary byte
+            if (current_char <='9') current_byte = current_char - '0';
+            else current_byte =current_char +10 -'A';
+            current_char = pc.getc();
+            if (current_char >'F') pc.printf("error|\n\r");
+            if (current_char <='9') current_byte = (current_byte <<4) | (current_char - '0');
+            else current_byte = (current_byte <<4)|(current_char +10 -'A');
+            // first byte after S command is the I2C address
+            if (first_data_byte==1) {
+                first_data_byte=0;
+                address=current_byte;
+                pc.printf(" -I2C address=%2.2X ", address);
+                //Odd I2C address is a read and even is a write
+                if ((address & 0x01) == 0) write=1;
+                else read=1;
+            } else
+                // Read in cmd bytes for write
+                if ((last_command == 'S')&&(read==0)) {
+                    cmd[cmd_count]=current_byte;
+                    cmd_count++;
                 }
-                if (write==1) {
-                    more_cmd =1;
-                    while (more_cmd==1) {
-                        if (getbyte(&cmd[cmd_count])>=2) {
-                            pc.printf(" write ");
-                            // write I2C command(s)
-                            if (i2c.write(address, cmd, cmd_count)!=0) pc.printf(" noack! ");
-                            for (i=0; i<cmd_count; i++)
-                                pc.printf(" command=%2.2X ", cmd[i]);
-                            cmd_count=0;
-                            more_cmd=0;
-                            write = 0;
-                        } else cmd_count++;
+            // number of bytes for a read
+            if ((last_command =='R')||(read==1)) data_count=current_byte;
+        } else {
+            // Not a number - it is a command character
+            last_command = current_char;
+            switch (last_command) {
+                    // Start
+                case 'S':
+                    first_data_byte=1;
+                    break;
+                    // Stop
+                case 'P':
+                    // Do the I2C write
+                    if (write==1) {
+                        pc.printf(" write ");
+                        if (i2c.write(address,cmd,cmd_count)!=0) pc.printf(" No Ack! ");
+                        for (i=0; i<cmd_count; i++)
+                            pc.printf(" cmd=%2.2X ", cmd[i]);
                     }
-                    if (read==0) pc.printf("\n\r");;
-                }
-                break;
-            case 'P':
-                //Stop
-                if (read == 1) {
-                    pc.printf(" read ");
-                    // read I2C data
-                    if (i2c.read(address, data, data_length)!=0) pc.printf(" noack! ");
-                    read = 0;
-                    write = 0;
-                    // send I2C data back to PC serial port
-                    for (i=0; i<data_length; i++)
-                        pc.printf(" data=%2.2X ",data[i]);
-                }
-                pc.printf("\n\r");
-                data_length=0;
-                cmd_count=0;
-                i2c.stop();
-                break;
-            case 'R':
-                //automatic read after write - read number of bytes to read
-                if (getbyte(&data_length)==0) break;
-                break;
-            case '?':
-                //Status
-                pc.printf(" mbed ready \n\r");
-                break;
-            default:
-
-                myled = 0;
-                break;
+                    // Do the I2C read
+                    if (read==1) {
+                        pc.printf(" read ");
+                        if (i2c.read(address, data, data_count) != 0) pc.printf(" No Ack! ");
+                        for (i=0; i<data_count; i++)
+                            pc.printf(" data=%2.2X ",data[i]);
+                    }
+                    // reset values for next I2C operation
+                    i2c.stop();
+                    pc.printf("\n\r");
+                    read=0;
+                    data_count=0;
+                    cmd_count=0;
+                    write=0;
+                    first_data_byte=0;
+                    break;
+                    // Read after write
+                case 'R':
+                    read=1;
+                    break;
+                    // Status request
+                case '?':
+                    pc.printf(" mbed ready \n\r");
+                    break;
+                    // Unknown or unimplemented command
+                default:
+                    pc.printf("unknown command");
+                    break;
+            }
         }
-
-
     }
 }
\ No newline at end of file