Basis for the C2 protocol from Silicon Labs.

Dependencies:   mbed

Revision:
4:a9e3ee5741be
Parent:
3:b30605f1c435
Child:
5:53d4a67cd657
--- a/main.cpp	Sat May 24 12:50:30 2014 +0000
+++ b/main.cpp	Sun May 25 13:59:43 2014 +0000
@@ -30,6 +30,48 @@
 DigitalOut c2ck(p5);
 DigitalInOut c2d(p6);
 
+static struct devices {
+    char *name;
+    int devid;
+} devices[] = {
+    { "F30x",                  0x04 },
+    { "F31x",                  0x08 },
+    { "F32x",                  0x09 },
+    { "F326/7",                0x0d },
+    { "F33x",                  0x0a },
+    { "F336/7",                0x14 },
+    { "F34x",                  0x0f },
+    { "F35x",                  0x0b },
+    { "F36x",                  0x12 },
+    { "F38x",                  0x28 },
+    { "F39x/F37x",             0x2b },
+    { "F41x",                  0x0c },
+    { "F50x/F51x",             0x1c },
+    { "F52xA/F53xA",           0x11 },
+    { "F54x",                  0x21 },
+    { "F55x/F56x/F57x",        0x22 },
+    { "F58x/F59x",             0x20 },
+    { "F70x/F71x",             0x1e },
+    { "F80x/F81x/F82x/F83x",   0x23 },
+    { "F90x/F91x",             0x1f },
+    { "F92x/F93x",             0x16 },
+    { "F96x",                  0x2a },
+    { "F99x",                  0x25 },
+    { "T60x",                  0x10 },
+    { "T606",                  0x1b },
+    { "T61x",                  0x13 },
+    { "T62x/T32x",             0x18 },
+    { "T622/T623/T326/T327",   0x19 },
+    { "T63x",                  0x17 },
+    { NULL, 0 }
+};
+
+#define C2_DEVID    0
+#define C2_REVID    1
+#define C2_FPCTL    2
+static int C2_FPDAT = 0xb4;         // or 0xad
+static int page_size = 512;         // not seen 4096 yet
+
 static void c2ck_reset(void) {
     c2ck = 0;
     wait_us(25);
@@ -63,9 +105,21 @@
             wait_us(1);         \
         } if (!t) return -1;    \
     } while(0)
+#define READV       do{\
+    for (i=0; i<8; i++) {       \
+        v >>= 1;                \
+        c2ck_strobe();          \
+        if (c2d) v |= 0x80;     \
+    } } while(0)
+#define WRITEV      do{\
+    for(i=0; i<8; i++) {        \
+        c2d = v & 1;            \
+        c2ck_strobe();          \
+        v >>= 1;                \
+    } } while(0)
 
 static int c2_read_dr(void) {
-    int t = 20, i, d = 0;
+    int t = 20, i, v = 0;
     
     START;
     c2d.output();
@@ -73,32 +127,20 @@
     LENGTH(0,0);    
     c2d.input();
     WAIT;    
-
-    for (i=0; i<8; i++) {   // DATA
-        d >>= 1;
-        c2ck_strobe();
-        if (c2d) d |= 0x80;
-    }
-    
+    READV;
     STOP;
     
-    return d;
+    return v;
 }
 
-static int c2_write_dr(int d) {
+static int c2_write_dr(int v) {
     int t = 20, i;
     
     START;
     c2d.output();
     INS(1,0);
     LENGTH(0,0);
-
-    for(i=0; i<8; i++) {
-        c2d = d & 1;
-        c2ck_strobe();
-        d >>= 1;
-    }
-
+    WRITEV;
     c2d.input();
     WAIT;
     STOP;
@@ -107,58 +149,46 @@
 }
 
 static int c2_read_ar(void) {
-    int i, a = 0;
+    int i, v = 0;
     
     START;
     c2d.output();
     INS(0,1);
     c2d.input();
+    READV;
+    STOP;
 
-    for(i=0; i<8; i++) {        // ADDRESS
-        a >>= 1;
-        c2ck_strobe();
-        if (c2d) a |= 0x80;
-    }
-    
-    STOP;
-    
-    return a;
+    return v;
 }
 
-static void c2_write_ar(int a) {
+static void c2_write_ar(int v) {
     int i;
 
     START;
     c2d.output();
     INS(1,1);
-
-    for(i=0; i<8; i++) {        // ADDRESS
-        c2d = a & 1;
-        c2ck_strobe();
-        a >>= 1;
-    }
-    
+    WRITEV;
     c2d.input();
     STOP;
 }
 
 static void fatal(char *s) {
     puts(s);
-loop:
-    goto loop;
+    exit(1);
 }
 
 int main() {
-    int c, devid, revid;
+    int i, c, devid, revid;
     
     c2d.input();
     c2ck = 1;
 
+    printf("\033[H\033[J");
     printf("SiLabs C2 Protocol\n\r\n\r");
     printf("Connect C2CK (clock) to p5 and C2D (data) to p6\n\r\n\r");
     printf("Press any key to continue\n\r");
-    
-    c = getc(stdin);
+
+    getc(stdin);
 
     c2_write_ar(0x00);
     devid = c2_read_dr();
@@ -168,5 +198,21 @@
     revid = c2_read_dr();
     if (revid < 0) fatal("unable to read revid\n\r");
 
-    printf("devid:revid = %02x:%02x\n\r", devid, revid);
-}
+    for (i=0; devices[i].name; i++) {
+        if (devices[i].devid == devid) break;
+    }
+    
+    if (!i) {
+        printf("unknown device: %02X:%02X\n\r", devid, revid);
+        fatal("unable to continue\n\r");
+    }
+
+    switch(devid) {
+        case 0x0f: case 0x28: case 0x18: case 0x19: C2_FPDAT = 0xad;
+        default: break;
+    }
+
+    printf("\n\rDevice found: %s (%02X:%02X)", devices[i].name, devid, revid);
+    printf("\n\rFPDAT Address: 0x%02X", C2_FPDAT);
+    printf("\n\rPage Size: %i\n\r", page_size);
+}
\ No newline at end of file