Basis for the C2 protocol from Silicon Labs.

Dependencies:   mbed

Revision:
17:0c5581ae2471
Parent:
16:844edb89d863
--- a/main.cpp	Mon May 26 18:08:12 2014 +0000
+++ b/main.cpp	Wed Jun 11 14:56:58 2014 +0000
@@ -60,7 +60,7 @@
 #define C2_MASK_INBUSY      0x02
 #define C2_MASK_OUTREADY    0x01
 
-// Programming INterface (PI) Commands
+// Programming Interface (PI) Commands
 
 #define C2_PI_CMD_GET_VERSION       0x01
 #define C2_PI_CMD_GET_DERIVATIVE    0x02
@@ -85,6 +85,7 @@
 #define C2_PI_STATUS_COMMAND_INVALID    0x00
 #define C2_PI_STATUS_NO_CONNECT         0x01
 #define C2_PI_STATUS_FAILED             0x02
+#define C2_PI_STATUS_PAGE_LOCKED        0x03    // "security" feature
 #define C2_PI_STATUS_TIMEOUT            0x04
 #define C2_PI_STATUS_BAD_DATA           0x05
 #define C2_PI_STATUS_OK                 0x0d
@@ -94,7 +95,7 @@
 #define C2_REG_REVID    1
 #define C2_REG_FPCTL    2
 static int C2_REG_FPDAT = 0xb4;         // or 0xad
-static int page_size = 512;         // not seen 4096 yet
+static int page_size = 512;
 
 static void fatal(char *f, ...) {
     va_list ap;
@@ -106,6 +107,7 @@
 }
 
 static void c2ck_reset(void) {
+    c2d.input();
     c2ck = 0;
     wait_us(25);
     c2ck = 1;
@@ -125,8 +127,8 @@
 #define STOP        START
 #define INS(a,b)    do{ c2d = a; c2ck_strobe(); c2d = b; c2ck_strobe(); }while(0)
 #define LENGTH(a,b) INS(a,b)
-#define WAIT        do{\
-        while(t-- && !c2d) {    \
+#define WAIT        c2ck_strobe(); do{\
+        while(!c2d && t--) {    \
             c2ck_strobe();      \
             wait_us(1);         \
         } if (!t) return -1;    \
@@ -207,7 +209,6 @@
         } else {
             if (s & mask)    return 0;
         }
-        printf("debug: wait 1us\r\n");
         wait_us(1);
     } while(--t);
     return -1;
@@ -215,13 +216,18 @@
 
 static void c2_enable_pi(void) {
     c2ck_reset();
+    wait_ms(2);
     c2_write_ar(C2_REG_FPCTL);
-    if ((c2_write_dr(0x02)+c2_write_dr(0x04)+c2_write_dr(0x01))<0)
-        fatal("cannot enable PI");
-    wait_ms(21);
+    if ((c2_write_dr(0x02))<0)
+        fatal("cannot enable PI (wr2)");
+    if ((c2_write_dr(0x04))<0)
+        fatal("cannot enable PI (wr4)");
+    if ((c2_write_dr(0x01))<0)
+        fatal("cannot enable PI (wr1)");
+    wait_ms(25);
 }
 
-static void c2_read_mem(int type, uint16_t address, uint8_t size, uint8_t *buf) {
+static int c2_read_mem(int type, int address, int size, uint8_t *buf) {
     int ret, i, ram_or_sfr = (type == C2_PI_CMD_DIRECT_READ) || (type == C2_PI_CMD_INDIRECT_READ);
 
     c2_write_ar(C2_REG_FPDAT);
@@ -250,14 +256,23 @@
     if (poll_status(C2_MASK_INBUSY) < 0)
         fatal("read_mem: cannot set block length");
     if (poll_status(C2_MASK_OUTREADY) < 0)
-        fatal("read_mem: no data ready (dr:%02X ar:%02X)", c2_read_dr(), c2_read_ar());
+        fatal("read_mem: no data ready");
 
-    for (i=0; i<size; i++)
+    ret = c2_read_dr();
+    if (ret != C2_PI_STATUS_OK)
+        return ret;
+    
+    for (i=0; i<size; i++) {
+        if (poll_status(C2_MASK_OUTREADY) < 0)
+            fatal("read_mem: no data ready during retrieval of block");
         buf[i] = c2_read_dr();
+    }
+    
+    return C2_PI_STATUS_OK;
 }
 
 int main() {
-    int i, c, devid, revid;
+    int i, c, devid, revid, ret;
     
     c2d.input();
     c2ck = 1;
@@ -294,8 +309,19 @@
     
     printf("\r\nEnabling Programming Interface\r\n");
     c2_enable_pi();
-    
-    printf("Reading page 0\r\n");
-    c2_read_mem(C2_PI_CMD_BLOCK_READ, 0x0000, 0x100, buffer);
-    printf("Looks like all went well!!!");
-}
\ No newline at end of file
+
+    for (c=0; c<256; c++) {
+        printf("\r\nReading page %i\r\n", c);
+        ret = c2_read_mem(C2_PI_CMD_BLOCK_READ, c<<8, 0x100, buffer);
+        if (ret == C2_PI_STATUS_OK) {
+            for (i=0; i<0x100; i++) {
+                printf("%02x ", buffer[i]);
+                if (i%16 == 15) printf("\r\n");
+            }
+        } else {
+            if (ret == C2_PI_STATUS_PAGE_LOCKED)
+                printf("page is locked, ");
+            printf("read failed\r\n");
+        }
+    }
+}