Basis for the C2 protocol from Silicon Labs.

Dependencies:   mbed

Committer:
Ivop
Date:
Sun May 25 13:59:43 2014 +0000
Revision:
4:a9e3ee5741be
Parent:
3:b30605f1c435
Child:
5:53d4a67cd657
smaller table, determine FPDAT, page_size; rest to be done

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Ivop 1:7a82f806fe92 1 /*
Ivop 1:7a82f806fe92 2 * SiLabs C2 Protocol on mbed pins p5/p6
Ivop 1:7a82f806fe92 3 *
Ivop 1:7a82f806fe92 4 * Copyright (c) 2014, Ivo van Poorten <ivopvp@gmail.com>
Ivop 1:7a82f806fe92 5 * All rights reserved.
Ivop 1:7a82f806fe92 6 *
Ivop 1:7a82f806fe92 7 * Redistribution and use in source and binary forms, with or without
Ivop 1:7a82f806fe92 8 * modification, are permitted provided that the following conditions
Ivop 1:7a82f806fe92 9 * are met:
Ivop 1:7a82f806fe92 10 * 1. Redistributions of source code must retain the above copyright
Ivop 1:7a82f806fe92 11 * notice, this list of conditions and the following disclaimer.
Ivop 1:7a82f806fe92 12 * 2. Redistributions in binary form must reproduce the above copyright
Ivop 1:7a82f806fe92 13 * notice, this list of conditions and the following disclaimer in the
Ivop 1:7a82f806fe92 14 * documentation and/or other materials provided with the distribution.
Ivop 1:7a82f806fe92 15 *
Ivop 1:7a82f806fe92 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
Ivop 1:7a82f806fe92 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
Ivop 1:7a82f806fe92 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
Ivop 1:7a82f806fe92 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
Ivop 1:7a82f806fe92 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
Ivop 1:7a82f806fe92 21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
Ivop 1:7a82f806fe92 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
Ivop 1:7a82f806fe92 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
Ivop 1:7a82f806fe92 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
Ivop 1:7a82f806fe92 25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Ivop 1:7a82f806fe92 26 */
Ivop 1:7a82f806fe92 27
Ivop 0:902f10e5d3e0 28 #include "mbed.h"
Ivop 0:902f10e5d3e0 29
Ivop 0:902f10e5d3e0 30 DigitalOut c2ck(p5);
Ivop 0:902f10e5d3e0 31 DigitalInOut c2d(p6);
Ivop 0:902f10e5d3e0 32
Ivop 4:a9e3ee5741be 33 static struct devices {
Ivop 4:a9e3ee5741be 34 char *name;
Ivop 4:a9e3ee5741be 35 int devid;
Ivop 4:a9e3ee5741be 36 } devices[] = {
Ivop 4:a9e3ee5741be 37 { "F30x", 0x04 },
Ivop 4:a9e3ee5741be 38 { "F31x", 0x08 },
Ivop 4:a9e3ee5741be 39 { "F32x", 0x09 },
Ivop 4:a9e3ee5741be 40 { "F326/7", 0x0d },
Ivop 4:a9e3ee5741be 41 { "F33x", 0x0a },
Ivop 4:a9e3ee5741be 42 { "F336/7", 0x14 },
Ivop 4:a9e3ee5741be 43 { "F34x", 0x0f },
Ivop 4:a9e3ee5741be 44 { "F35x", 0x0b },
Ivop 4:a9e3ee5741be 45 { "F36x", 0x12 },
Ivop 4:a9e3ee5741be 46 { "F38x", 0x28 },
Ivop 4:a9e3ee5741be 47 { "F39x/F37x", 0x2b },
Ivop 4:a9e3ee5741be 48 { "F41x", 0x0c },
Ivop 4:a9e3ee5741be 49 { "F50x/F51x", 0x1c },
Ivop 4:a9e3ee5741be 50 { "F52xA/F53xA", 0x11 },
Ivop 4:a9e3ee5741be 51 { "F54x", 0x21 },
Ivop 4:a9e3ee5741be 52 { "F55x/F56x/F57x", 0x22 },
Ivop 4:a9e3ee5741be 53 { "F58x/F59x", 0x20 },
Ivop 4:a9e3ee5741be 54 { "F70x/F71x", 0x1e },
Ivop 4:a9e3ee5741be 55 { "F80x/F81x/F82x/F83x", 0x23 },
Ivop 4:a9e3ee5741be 56 { "F90x/F91x", 0x1f },
Ivop 4:a9e3ee5741be 57 { "F92x/F93x", 0x16 },
Ivop 4:a9e3ee5741be 58 { "F96x", 0x2a },
Ivop 4:a9e3ee5741be 59 { "F99x", 0x25 },
Ivop 4:a9e3ee5741be 60 { "T60x", 0x10 },
Ivop 4:a9e3ee5741be 61 { "T606", 0x1b },
Ivop 4:a9e3ee5741be 62 { "T61x", 0x13 },
Ivop 4:a9e3ee5741be 63 { "T62x/T32x", 0x18 },
Ivop 4:a9e3ee5741be 64 { "T622/T623/T326/T327", 0x19 },
Ivop 4:a9e3ee5741be 65 { "T63x", 0x17 },
Ivop 4:a9e3ee5741be 66 { NULL, 0 }
Ivop 4:a9e3ee5741be 67 };
Ivop 4:a9e3ee5741be 68
Ivop 4:a9e3ee5741be 69 #define C2_DEVID 0
Ivop 4:a9e3ee5741be 70 #define C2_REVID 1
Ivop 4:a9e3ee5741be 71 #define C2_FPCTL 2
Ivop 4:a9e3ee5741be 72 static int C2_FPDAT = 0xb4; // or 0xad
Ivop 4:a9e3ee5741be 73 static int page_size = 512; // not seen 4096 yet
Ivop 4:a9e3ee5741be 74
Ivop 1:7a82f806fe92 75 static void c2ck_reset(void) {
Ivop 1:7a82f806fe92 76 c2ck = 0;
Ivop 1:7a82f806fe92 77 wait_us(25);
Ivop 1:7a82f806fe92 78 c2ck = 1;
Ivop 1:7a82f806fe92 79 wait_us(1);
Ivop 1:7a82f806fe92 80 }
Ivop 1:7a82f806fe92 81
Ivop 1:7a82f806fe92 82 static void c2ck_strobe(void) {
Ivop 1:7a82f806fe92 83 c2ck = 0;
Ivop 1:7a82f806fe92 84 wait_us(1);
Ivop 1:7a82f806fe92 85 c2ck = 1;
Ivop 1:7a82f806fe92 86 wait_us(1);
Ivop 1:7a82f806fe92 87 }
Ivop 1:7a82f806fe92 88
Ivop 1:7a82f806fe92 89 // Four basic C2 Instructions
Ivop 1:7a82f806fe92 90 //
Ivop 1:7a82f806fe92 91 // 00b Data Read
Ivop 1:7a82f806fe92 92 // 01b Data Write
Ivop 1:7a82f806fe92 93 // 10b Address Read
Ivop 1:7a82f806fe92 94 // 11b Address Write
Ivop 2:9092d0d1558b 95 //
Ivop 2:9092d0d1558b 96 // Remember, ALL fields are sent LSB first(!)
Ivop 1:7a82f806fe92 97
Ivop 2:9092d0d1558b 98 #define START do{ c2ck_strobe(); }while(0)
Ivop 2:9092d0d1558b 99 #define STOP START
Ivop 2:9092d0d1558b 100 #define INS(a,b) do{ c2d = a; c2ck_strobe(); c2d = b; c2ck_strobe(); }while(0)
Ivop 2:9092d0d1558b 101 #define LENGTH(a,b) INS(a,b)
Ivop 2:9092d0d1558b 102 #define WAIT do{\
Ivop 2:9092d0d1558b 103 while(t-- && !c2d) { \
Ivop 2:9092d0d1558b 104 c2ck_strobe(); \
Ivop 2:9092d0d1558b 105 wait_us(1); \
Ivop 2:9092d0d1558b 106 } if (!t) return -1; \
Ivop 2:9092d0d1558b 107 } while(0)
Ivop 4:a9e3ee5741be 108 #define READV do{\
Ivop 4:a9e3ee5741be 109 for (i=0; i<8; i++) { \
Ivop 4:a9e3ee5741be 110 v >>= 1; \
Ivop 4:a9e3ee5741be 111 c2ck_strobe(); \
Ivop 4:a9e3ee5741be 112 if (c2d) v |= 0x80; \
Ivop 4:a9e3ee5741be 113 } } while(0)
Ivop 4:a9e3ee5741be 114 #define WRITEV do{\
Ivop 4:a9e3ee5741be 115 for(i=0; i<8; i++) { \
Ivop 4:a9e3ee5741be 116 c2d = v & 1; \
Ivop 4:a9e3ee5741be 117 c2ck_strobe(); \
Ivop 4:a9e3ee5741be 118 v >>= 1; \
Ivop 4:a9e3ee5741be 119 } } while(0)
Ivop 2:9092d0d1558b 120
Ivop 2:9092d0d1558b 121 static int c2_read_dr(void) {
Ivop 4:a9e3ee5741be 122 int t = 20, i, v = 0;
Ivop 2:9092d0d1558b 123
Ivop 2:9092d0d1558b 124 START;
Ivop 2:9092d0d1558b 125 c2d.output();
Ivop 2:9092d0d1558b 126 INS(0,0);
Ivop 2:9092d0d1558b 127 LENGTH(0,0);
Ivop 2:9092d0d1558b 128 c2d.input();
Ivop 2:9092d0d1558b 129 WAIT;
Ivop 4:a9e3ee5741be 130 READV;
Ivop 2:9092d0d1558b 131 STOP;
Ivop 2:9092d0d1558b 132
Ivop 4:a9e3ee5741be 133 return v;
Ivop 2:9092d0d1558b 134 }
Ivop 2:9092d0d1558b 135
Ivop 4:a9e3ee5741be 136 static int c2_write_dr(int v) {
Ivop 2:9092d0d1558b 137 int t = 20, i;
Ivop 2:9092d0d1558b 138
Ivop 2:9092d0d1558b 139 START;
Ivop 2:9092d0d1558b 140 c2d.output();
Ivop 2:9092d0d1558b 141 INS(1,0);
Ivop 2:9092d0d1558b 142 LENGTH(0,0);
Ivop 4:a9e3ee5741be 143 WRITEV;
Ivop 2:9092d0d1558b 144 c2d.input();
Ivop 2:9092d0d1558b 145 WAIT;
Ivop 2:9092d0d1558b 146 STOP;
Ivop 2:9092d0d1558b 147
Ivop 2:9092d0d1558b 148 return 0;
Ivop 2:9092d0d1558b 149 }
Ivop 2:9092d0d1558b 150
Ivop 2:9092d0d1558b 151 static int c2_read_ar(void) {
Ivop 4:a9e3ee5741be 152 int i, v = 0;
Ivop 2:9092d0d1558b 153
Ivop 2:9092d0d1558b 154 START;
Ivop 2:9092d0d1558b 155 c2d.output();
Ivop 2:9092d0d1558b 156 INS(0,1);
Ivop 2:9092d0d1558b 157 c2d.input();
Ivop 4:a9e3ee5741be 158 READV;
Ivop 4:a9e3ee5741be 159 STOP;
Ivop 2:9092d0d1558b 160
Ivop 4:a9e3ee5741be 161 return v;
Ivop 2:9092d0d1558b 162 }
Ivop 2:9092d0d1558b 163
Ivop 4:a9e3ee5741be 164 static void c2_write_ar(int v) {
Ivop 2:9092d0d1558b 165 int i;
Ivop 2:9092d0d1558b 166
Ivop 2:9092d0d1558b 167 START;
Ivop 2:9092d0d1558b 168 c2d.output();
Ivop 2:9092d0d1558b 169 INS(1,1);
Ivop 4:a9e3ee5741be 170 WRITEV;
Ivop 2:9092d0d1558b 171 c2d.input();
Ivop 2:9092d0d1558b 172 STOP;
Ivop 2:9092d0d1558b 173 }
Ivop 1:7a82f806fe92 174
Ivop 3:b30605f1c435 175 static void fatal(char *s) {
Ivop 3:b30605f1c435 176 puts(s);
Ivop 4:a9e3ee5741be 177 exit(1);
Ivop 3:b30605f1c435 178 }
Ivop 3:b30605f1c435 179
Ivop 0:902f10e5d3e0 180 int main() {
Ivop 4:a9e3ee5741be 181 int i, c, devid, revid;
Ivop 1:7a82f806fe92 182
Ivop 1:7a82f806fe92 183 c2d.input();
Ivop 1:7a82f806fe92 184 c2ck = 1;
Ivop 1:7a82f806fe92 185
Ivop 4:a9e3ee5741be 186 printf("\033[H\033[J");
Ivop 1:7a82f806fe92 187 printf("SiLabs C2 Protocol\n\r\n\r");
Ivop 1:7a82f806fe92 188 printf("Connect C2CK (clock) to p5 and C2D (data) to p6\n\r\n\r");
Ivop 1:7a82f806fe92 189 printf("Press any key to continue\n\r");
Ivop 4:a9e3ee5741be 190
Ivop 4:a9e3ee5741be 191 getc(stdin);
Ivop 3:b30605f1c435 192
Ivop 3:b30605f1c435 193 c2_write_ar(0x00);
Ivop 3:b30605f1c435 194 devid = c2_read_dr();
Ivop 3:b30605f1c435 195 if (devid < 0) fatal("unable to read devid\n\r");
Ivop 1:7a82f806fe92 196
Ivop 3:b30605f1c435 197 c2_write_ar(0x01);
Ivop 3:b30605f1c435 198 revid = c2_read_dr();
Ivop 3:b30605f1c435 199 if (revid < 0) fatal("unable to read revid\n\r");
Ivop 3:b30605f1c435 200
Ivop 4:a9e3ee5741be 201 for (i=0; devices[i].name; i++) {
Ivop 4:a9e3ee5741be 202 if (devices[i].devid == devid) break;
Ivop 4:a9e3ee5741be 203 }
Ivop 4:a9e3ee5741be 204
Ivop 4:a9e3ee5741be 205 if (!i) {
Ivop 4:a9e3ee5741be 206 printf("unknown device: %02X:%02X\n\r", devid, revid);
Ivop 4:a9e3ee5741be 207 fatal("unable to continue\n\r");
Ivop 4:a9e3ee5741be 208 }
Ivop 4:a9e3ee5741be 209
Ivop 4:a9e3ee5741be 210 switch(devid) {
Ivop 4:a9e3ee5741be 211 case 0x0f: case 0x28: case 0x18: case 0x19: C2_FPDAT = 0xad;
Ivop 4:a9e3ee5741be 212 default: break;
Ivop 4:a9e3ee5741be 213 }
Ivop 4:a9e3ee5741be 214
Ivop 4:a9e3ee5741be 215 printf("\n\rDevice found: %s (%02X:%02X)", devices[i].name, devid, revid);
Ivop 4:a9e3ee5741be 216 printf("\n\rFPDAT Address: 0x%02X", C2_FPDAT);
Ivop 4:a9e3ee5741be 217 printf("\n\rPage Size: %i\n\r", page_size);
Ivop 4:a9e3ee5741be 218 }