Basis for the C2 protocol from Silicon Labs.

Dependencies:   mbed

Committer:
Ivop
Date:
Sun May 25 17:11:20 2014 +0000
Revision:
6:deb670cb8105
Parent:
5:53d4a67cd657
Child:
7:65a72aad87b8
added poll_status function (for inbusy and outready)

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 6:deb670cb8105 69 #define C2_MASK_FLBUSY 0x80
Ivop 6:deb670cb8105 70 #define C2_MASK_INBUSY 0x02
Ivop 6:deb670cb8105 71 #define C2_MASK_OUTREADY 0x01
Ivop 6:deb670cb8105 72
Ivop 4:a9e3ee5741be 73 #define C2_DEVID 0
Ivop 4:a9e3ee5741be 74 #define C2_REVID 1
Ivop 4:a9e3ee5741be 75 #define C2_FPCTL 2
Ivop 4:a9e3ee5741be 76 static int C2_FPDAT = 0xb4; // or 0xad
Ivop 4:a9e3ee5741be 77 static int page_size = 512; // not seen 4096 yet
Ivop 4:a9e3ee5741be 78
Ivop 1:7a82f806fe92 79 static void c2ck_reset(void) {
Ivop 1:7a82f806fe92 80 c2ck = 0;
Ivop 1:7a82f806fe92 81 wait_us(25);
Ivop 1:7a82f806fe92 82 c2ck = 1;
Ivop 1:7a82f806fe92 83 wait_us(1);
Ivop 1:7a82f806fe92 84 }
Ivop 1:7a82f806fe92 85
Ivop 1:7a82f806fe92 86 static void c2ck_strobe(void) {
Ivop 1:7a82f806fe92 87 c2ck = 0;
Ivop 1:7a82f806fe92 88 wait_us(1);
Ivop 1:7a82f806fe92 89 c2ck = 1;
Ivop 1:7a82f806fe92 90 wait_us(1);
Ivop 1:7a82f806fe92 91 }
Ivop 1:7a82f806fe92 92
Ivop 1:7a82f806fe92 93 // Four basic C2 Instructions
Ivop 1:7a82f806fe92 94 //
Ivop 1:7a82f806fe92 95 // 00b Data Read
Ivop 1:7a82f806fe92 96 // 01b Data Write
Ivop 1:7a82f806fe92 97 // 10b Address Read
Ivop 1:7a82f806fe92 98 // 11b Address Write
Ivop 2:9092d0d1558b 99 //
Ivop 2:9092d0d1558b 100 // Remember, ALL fields are sent LSB first(!)
Ivop 1:7a82f806fe92 101
Ivop 2:9092d0d1558b 102 #define START do{ c2ck_strobe(); }while(0)
Ivop 2:9092d0d1558b 103 #define STOP START
Ivop 2:9092d0d1558b 104 #define INS(a,b) do{ c2d = a; c2ck_strobe(); c2d = b; c2ck_strobe(); }while(0)
Ivop 2:9092d0d1558b 105 #define LENGTH(a,b) INS(a,b)
Ivop 2:9092d0d1558b 106 #define WAIT do{\
Ivop 2:9092d0d1558b 107 while(t-- && !c2d) { \
Ivop 2:9092d0d1558b 108 c2ck_strobe(); \
Ivop 2:9092d0d1558b 109 wait_us(1); \
Ivop 2:9092d0d1558b 110 } if (!t) return -1; \
Ivop 2:9092d0d1558b 111 } while(0)
Ivop 4:a9e3ee5741be 112 #define READV do{\
Ivop 4:a9e3ee5741be 113 for (i=0; i<8; i++) { \
Ivop 4:a9e3ee5741be 114 v >>= 1; \
Ivop 4:a9e3ee5741be 115 c2ck_strobe(); \
Ivop 4:a9e3ee5741be 116 if (c2d) v |= 0x80; \
Ivop 4:a9e3ee5741be 117 } } while(0)
Ivop 4:a9e3ee5741be 118 #define WRITEV do{\
Ivop 4:a9e3ee5741be 119 for(i=0; i<8; i++) { \
Ivop 4:a9e3ee5741be 120 c2d = v & 1; \
Ivop 4:a9e3ee5741be 121 c2ck_strobe(); \
Ivop 4:a9e3ee5741be 122 v >>= 1; \
Ivop 4:a9e3ee5741be 123 } } while(0)
Ivop 2:9092d0d1558b 124
Ivop 2:9092d0d1558b 125 static int c2_read_dr(void) {
Ivop 4:a9e3ee5741be 126 int t = 20, i, v = 0;
Ivop 2:9092d0d1558b 127
Ivop 2:9092d0d1558b 128 START;
Ivop 2:9092d0d1558b 129 c2d.output();
Ivop 2:9092d0d1558b 130 INS(0,0);
Ivop 2:9092d0d1558b 131 LENGTH(0,0);
Ivop 2:9092d0d1558b 132 c2d.input();
Ivop 2:9092d0d1558b 133 WAIT;
Ivop 4:a9e3ee5741be 134 READV;
Ivop 2:9092d0d1558b 135 STOP;
Ivop 2:9092d0d1558b 136
Ivop 4:a9e3ee5741be 137 return v;
Ivop 2:9092d0d1558b 138 }
Ivop 2:9092d0d1558b 139
Ivop 4:a9e3ee5741be 140 static int c2_write_dr(int v) {
Ivop 2:9092d0d1558b 141 int t = 20, i;
Ivop 2:9092d0d1558b 142
Ivop 2:9092d0d1558b 143 START;
Ivop 2:9092d0d1558b 144 c2d.output();
Ivop 2:9092d0d1558b 145 INS(1,0);
Ivop 2:9092d0d1558b 146 LENGTH(0,0);
Ivop 4:a9e3ee5741be 147 WRITEV;
Ivop 2:9092d0d1558b 148 c2d.input();
Ivop 2:9092d0d1558b 149 WAIT;
Ivop 2:9092d0d1558b 150 STOP;
Ivop 2:9092d0d1558b 151
Ivop 2:9092d0d1558b 152 return 0;
Ivop 2:9092d0d1558b 153 }
Ivop 2:9092d0d1558b 154
Ivop 2:9092d0d1558b 155 static int c2_read_ar(void) {
Ivop 4:a9e3ee5741be 156 int i, v = 0;
Ivop 2:9092d0d1558b 157
Ivop 2:9092d0d1558b 158 START;
Ivop 2:9092d0d1558b 159 c2d.output();
Ivop 2:9092d0d1558b 160 INS(0,1);
Ivop 2:9092d0d1558b 161 c2d.input();
Ivop 4:a9e3ee5741be 162 READV;
Ivop 4:a9e3ee5741be 163 STOP;
Ivop 2:9092d0d1558b 164
Ivop 4:a9e3ee5741be 165 return v;
Ivop 2:9092d0d1558b 166 }
Ivop 2:9092d0d1558b 167
Ivop 4:a9e3ee5741be 168 static void c2_write_ar(int v) {
Ivop 2:9092d0d1558b 169 int i;
Ivop 2:9092d0d1558b 170
Ivop 2:9092d0d1558b 171 START;
Ivop 2:9092d0d1558b 172 c2d.output();
Ivop 2:9092d0d1558b 173 INS(1,1);
Ivop 4:a9e3ee5741be 174 WRITEV;
Ivop 2:9092d0d1558b 175 c2d.input();
Ivop 2:9092d0d1558b 176 STOP;
Ivop 2:9092d0d1558b 177 }
Ivop 1:7a82f806fe92 178
Ivop 3:b30605f1c435 179 static void fatal(char *s) {
Ivop 3:b30605f1c435 180 puts(s);
Ivop 4:a9e3ee5741be 181 exit(1);
Ivop 3:b30605f1c435 182 }
Ivop 3:b30605f1c435 183
Ivop 6:deb670cb8105 184 static int poll_status(int mask) {
Ivop 6:deb670cb8105 185 int t = 20;
Ivop 6:deb670cb8105 186 do {
Ivop 6:deb670cb8105 187 if (!(c2_read_ar() & mask)) return 0;
Ivop 6:deb670cb8105 188 wait_us(1);
Ivop 6:deb670cb8105 189 } while(--t);
Ivop 6:deb670cb8105 190 return -1;
Ivop 6:deb670cb8105 191 }
Ivop 6:deb670cb8105 192
Ivop 0:902f10e5d3e0 193 int main() {
Ivop 4:a9e3ee5741be 194 int i, c, devid, revid;
Ivop 1:7a82f806fe92 195
Ivop 1:7a82f806fe92 196 c2d.input();
Ivop 1:7a82f806fe92 197 c2ck = 1;
Ivop 1:7a82f806fe92 198
Ivop 4:a9e3ee5741be 199 printf("\033[H\033[J");
Ivop 1:7a82f806fe92 200 printf("SiLabs C2 Protocol\n\r\n\r");
Ivop 1:7a82f806fe92 201 printf("Connect C2CK (clock) to p5 and C2D (data) to p6\n\r\n\r");
Ivop 1:7a82f806fe92 202 printf("Press any key to continue\n\r");
Ivop 4:a9e3ee5741be 203
Ivop 4:a9e3ee5741be 204 getc(stdin);
Ivop 3:b30605f1c435 205
Ivop 5:53d4a67cd657 206 c2_write_ar(C2_DEVID);
Ivop 3:b30605f1c435 207 devid = c2_read_dr();
Ivop 5:53d4a67cd657 208 if (devid <= 0) fatal("unable to read devid\n\r");
Ivop 1:7a82f806fe92 209
Ivop 5:53d4a67cd657 210 c2_write_ar(C2_REVID);
Ivop 3:b30605f1c435 211 revid = c2_read_dr();
Ivop 3:b30605f1c435 212 if (revid < 0) fatal("unable to read revid\n\r");
Ivop 3:b30605f1c435 213
Ivop 4:a9e3ee5741be 214 for (i=0; devices[i].name; i++) {
Ivop 4:a9e3ee5741be 215 if (devices[i].devid == devid) break;
Ivop 4:a9e3ee5741be 216 }
Ivop 4:a9e3ee5741be 217
Ivop 4:a9e3ee5741be 218 if (!i) {
Ivop 4:a9e3ee5741be 219 printf("unknown device: %02X:%02X\n\r", devid, revid);
Ivop 4:a9e3ee5741be 220 fatal("unable to continue\n\r");
Ivop 4:a9e3ee5741be 221 }
Ivop 4:a9e3ee5741be 222
Ivop 4:a9e3ee5741be 223 switch(devid) {
Ivop 4:a9e3ee5741be 224 case 0x0f: case 0x28: case 0x18: case 0x19: C2_FPDAT = 0xad;
Ivop 4:a9e3ee5741be 225 default: break;
Ivop 4:a9e3ee5741be 226 }
Ivop 4:a9e3ee5741be 227
Ivop 4:a9e3ee5741be 228 printf("\n\rDevice found: %s (%02X:%02X)", devices[i].name, devid, revid);
Ivop 4:a9e3ee5741be 229 printf("\n\rFPDAT Address: 0x%02X", C2_FPDAT);
Ivop 4:a9e3ee5741be 230 printf("\n\rPage Size: %i\n\r", page_size);
Ivop 4:a9e3ee5741be 231 }