Basis for the C2 protocol from Silicon Labs.

Dependencies:   mbed

Committer:
Ivop
Date:
Sun May 25 17:17:40 2014 +0000
Revision:
7:65a72aad87b8
Parent:
6:deb670cb8105
Child:
8:af5d402396fb
better fatal() function (varargs version)

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 7:65a72aad87b8 29 #include <stdarg.h>
Ivop 0:902f10e5d3e0 30
Ivop 0:902f10e5d3e0 31 DigitalOut c2ck(p5);
Ivop 0:902f10e5d3e0 32 DigitalInOut c2d(p6);
Ivop 0:902f10e5d3e0 33
Ivop 4:a9e3ee5741be 34 static struct devices {
Ivop 4:a9e3ee5741be 35 char *name;
Ivop 4:a9e3ee5741be 36 int devid;
Ivop 4:a9e3ee5741be 37 } devices[] = {
Ivop 4:a9e3ee5741be 38 { "F30x", 0x04 },
Ivop 4:a9e3ee5741be 39 { "F31x", 0x08 },
Ivop 4:a9e3ee5741be 40 { "F32x", 0x09 },
Ivop 4:a9e3ee5741be 41 { "F326/7", 0x0d },
Ivop 4:a9e3ee5741be 42 { "F33x", 0x0a },
Ivop 4:a9e3ee5741be 43 { "F336/7", 0x14 },
Ivop 4:a9e3ee5741be 44 { "F34x", 0x0f },
Ivop 4:a9e3ee5741be 45 { "F35x", 0x0b },
Ivop 4:a9e3ee5741be 46 { "F36x", 0x12 },
Ivop 4:a9e3ee5741be 47 { "F38x", 0x28 },
Ivop 4:a9e3ee5741be 48 { "F39x/F37x", 0x2b },
Ivop 4:a9e3ee5741be 49 { "F41x", 0x0c },
Ivop 4:a9e3ee5741be 50 { "F50x/F51x", 0x1c },
Ivop 4:a9e3ee5741be 51 { "F52xA/F53xA", 0x11 },
Ivop 4:a9e3ee5741be 52 { "F54x", 0x21 },
Ivop 4:a9e3ee5741be 53 { "F55x/F56x/F57x", 0x22 },
Ivop 4:a9e3ee5741be 54 { "F58x/F59x", 0x20 },
Ivop 4:a9e3ee5741be 55 { "F70x/F71x", 0x1e },
Ivop 4:a9e3ee5741be 56 { "F80x/F81x/F82x/F83x", 0x23 },
Ivop 4:a9e3ee5741be 57 { "F90x/F91x", 0x1f },
Ivop 4:a9e3ee5741be 58 { "F92x/F93x", 0x16 },
Ivop 4:a9e3ee5741be 59 { "F96x", 0x2a },
Ivop 4:a9e3ee5741be 60 { "F99x", 0x25 },
Ivop 4:a9e3ee5741be 61 { "T60x", 0x10 },
Ivop 4:a9e3ee5741be 62 { "T606", 0x1b },
Ivop 4:a9e3ee5741be 63 { "T61x", 0x13 },
Ivop 4:a9e3ee5741be 64 { "T62x/T32x", 0x18 },
Ivop 4:a9e3ee5741be 65 { "T622/T623/T326/T327", 0x19 },
Ivop 4:a9e3ee5741be 66 { "T63x", 0x17 },
Ivop 4:a9e3ee5741be 67 { NULL, 0 }
Ivop 4:a9e3ee5741be 68 };
Ivop 4:a9e3ee5741be 69
Ivop 6:deb670cb8105 70 #define C2_MASK_FLBUSY 0x80
Ivop 6:deb670cb8105 71 #define C2_MASK_INBUSY 0x02
Ivop 6:deb670cb8105 72 #define C2_MASK_OUTREADY 0x01
Ivop 6:deb670cb8105 73
Ivop 4:a9e3ee5741be 74 #define C2_DEVID 0
Ivop 4:a9e3ee5741be 75 #define C2_REVID 1
Ivop 4:a9e3ee5741be 76 #define C2_FPCTL 2
Ivop 4:a9e3ee5741be 77 static int C2_FPDAT = 0xb4; // or 0xad
Ivop 4:a9e3ee5741be 78 static int page_size = 512; // not seen 4096 yet
Ivop 4:a9e3ee5741be 79
Ivop 7:65a72aad87b8 80 static void fatal(char *f, ...) {
Ivop 7:65a72aad87b8 81 va_list ap;
Ivop 7:65a72aad87b8 82 va_start(ap,f);
Ivop 7:65a72aad87b8 83 printf("\n\rFATAL: ");
Ivop 7:65a72aad87b8 84 vprintf(f, ap);
Ivop 7:65a72aad87b8 85 va_end(ap);
Ivop 7:65a72aad87b8 86 exit(1);
Ivop 7:65a72aad87b8 87 }
Ivop 7:65a72aad87b8 88
Ivop 1:7a82f806fe92 89 static void c2ck_reset(void) {
Ivop 1:7a82f806fe92 90 c2ck = 0;
Ivop 1:7a82f806fe92 91 wait_us(25);
Ivop 1:7a82f806fe92 92 c2ck = 1;
Ivop 1:7a82f806fe92 93 wait_us(1);
Ivop 1:7a82f806fe92 94 }
Ivop 1:7a82f806fe92 95
Ivop 1:7a82f806fe92 96 static void c2ck_strobe(void) {
Ivop 1:7a82f806fe92 97 c2ck = 0;
Ivop 1:7a82f806fe92 98 wait_us(1);
Ivop 1:7a82f806fe92 99 c2ck = 1;
Ivop 1:7a82f806fe92 100 wait_us(1);
Ivop 1:7a82f806fe92 101 }
Ivop 1:7a82f806fe92 102
Ivop 1:7a82f806fe92 103 // Four basic C2 Instructions
Ivop 1:7a82f806fe92 104 //
Ivop 1:7a82f806fe92 105 // 00b Data Read
Ivop 1:7a82f806fe92 106 // 01b Data Write
Ivop 1:7a82f806fe92 107 // 10b Address Read
Ivop 1:7a82f806fe92 108 // 11b Address Write
Ivop 2:9092d0d1558b 109 //
Ivop 2:9092d0d1558b 110 // Remember, ALL fields are sent LSB first(!)
Ivop 1:7a82f806fe92 111
Ivop 2:9092d0d1558b 112 #define START do{ c2ck_strobe(); }while(0)
Ivop 2:9092d0d1558b 113 #define STOP START
Ivop 2:9092d0d1558b 114 #define INS(a,b) do{ c2d = a; c2ck_strobe(); c2d = b; c2ck_strobe(); }while(0)
Ivop 2:9092d0d1558b 115 #define LENGTH(a,b) INS(a,b)
Ivop 2:9092d0d1558b 116 #define WAIT do{\
Ivop 2:9092d0d1558b 117 while(t-- && !c2d) { \
Ivop 2:9092d0d1558b 118 c2ck_strobe(); \
Ivop 2:9092d0d1558b 119 wait_us(1); \
Ivop 2:9092d0d1558b 120 } if (!t) return -1; \
Ivop 2:9092d0d1558b 121 } while(0)
Ivop 4:a9e3ee5741be 122 #define READV do{\
Ivop 4:a9e3ee5741be 123 for (i=0; i<8; i++) { \
Ivop 4:a9e3ee5741be 124 v >>= 1; \
Ivop 4:a9e3ee5741be 125 c2ck_strobe(); \
Ivop 4:a9e3ee5741be 126 if (c2d) v |= 0x80; \
Ivop 4:a9e3ee5741be 127 } } while(0)
Ivop 4:a9e3ee5741be 128 #define WRITEV do{\
Ivop 4:a9e3ee5741be 129 for(i=0; i<8; i++) { \
Ivop 4:a9e3ee5741be 130 c2d = v & 1; \
Ivop 4:a9e3ee5741be 131 c2ck_strobe(); \
Ivop 4:a9e3ee5741be 132 v >>= 1; \
Ivop 4:a9e3ee5741be 133 } } while(0)
Ivop 2:9092d0d1558b 134
Ivop 2:9092d0d1558b 135 static int c2_read_dr(void) {
Ivop 4:a9e3ee5741be 136 int t = 20, i, v = 0;
Ivop 2:9092d0d1558b 137
Ivop 2:9092d0d1558b 138 START;
Ivop 2:9092d0d1558b 139 c2d.output();
Ivop 2:9092d0d1558b 140 INS(0,0);
Ivop 2:9092d0d1558b 141 LENGTH(0,0);
Ivop 2:9092d0d1558b 142 c2d.input();
Ivop 2:9092d0d1558b 143 WAIT;
Ivop 4:a9e3ee5741be 144 READV;
Ivop 2:9092d0d1558b 145 STOP;
Ivop 2:9092d0d1558b 146
Ivop 4:a9e3ee5741be 147 return v;
Ivop 2:9092d0d1558b 148 }
Ivop 2:9092d0d1558b 149
Ivop 4:a9e3ee5741be 150 static int c2_write_dr(int v) {
Ivop 2:9092d0d1558b 151 int t = 20, i;
Ivop 2:9092d0d1558b 152
Ivop 2:9092d0d1558b 153 START;
Ivop 2:9092d0d1558b 154 c2d.output();
Ivop 2:9092d0d1558b 155 INS(1,0);
Ivop 2:9092d0d1558b 156 LENGTH(0,0);
Ivop 4:a9e3ee5741be 157 WRITEV;
Ivop 2:9092d0d1558b 158 c2d.input();
Ivop 2:9092d0d1558b 159 WAIT;
Ivop 2:9092d0d1558b 160 STOP;
Ivop 2:9092d0d1558b 161
Ivop 2:9092d0d1558b 162 return 0;
Ivop 2:9092d0d1558b 163 }
Ivop 2:9092d0d1558b 164
Ivop 2:9092d0d1558b 165 static int c2_read_ar(void) {
Ivop 4:a9e3ee5741be 166 int i, v = 0;
Ivop 2:9092d0d1558b 167
Ivop 2:9092d0d1558b 168 START;
Ivop 2:9092d0d1558b 169 c2d.output();
Ivop 2:9092d0d1558b 170 INS(0,1);
Ivop 2:9092d0d1558b 171 c2d.input();
Ivop 4:a9e3ee5741be 172 READV;
Ivop 4:a9e3ee5741be 173 STOP;
Ivop 2:9092d0d1558b 174
Ivop 4:a9e3ee5741be 175 return v;
Ivop 2:9092d0d1558b 176 }
Ivop 2:9092d0d1558b 177
Ivop 4:a9e3ee5741be 178 static void c2_write_ar(int v) {
Ivop 2:9092d0d1558b 179 int i;
Ivop 2:9092d0d1558b 180
Ivop 2:9092d0d1558b 181 START;
Ivop 2:9092d0d1558b 182 c2d.output();
Ivop 2:9092d0d1558b 183 INS(1,1);
Ivop 4:a9e3ee5741be 184 WRITEV;
Ivop 2:9092d0d1558b 185 c2d.input();
Ivop 2:9092d0d1558b 186 STOP;
Ivop 2:9092d0d1558b 187 }
Ivop 1:7a82f806fe92 188
Ivop 6:deb670cb8105 189 static int poll_status(int mask) {
Ivop 6:deb670cb8105 190 int t = 20;
Ivop 6:deb670cb8105 191 do {
Ivop 6:deb670cb8105 192 if (!(c2_read_ar() & mask)) return 0;
Ivop 6:deb670cb8105 193 wait_us(1);
Ivop 6:deb670cb8105 194 } while(--t);
Ivop 6:deb670cb8105 195 return -1;
Ivop 6:deb670cb8105 196 }
Ivop 7:65a72aad87b8 197
Ivop 0:902f10e5d3e0 198 int main() {
Ivop 4:a9e3ee5741be 199 int i, c, devid, revid;
Ivop 1:7a82f806fe92 200
Ivop 1:7a82f806fe92 201 c2d.input();
Ivop 1:7a82f806fe92 202 c2ck = 1;
Ivop 1:7a82f806fe92 203
Ivop 4:a9e3ee5741be 204 printf("\033[H\033[J");
Ivop 1:7a82f806fe92 205 printf("SiLabs C2 Protocol\n\r\n\r");
Ivop 1:7a82f806fe92 206 printf("Connect C2CK (clock) to p5 and C2D (data) to p6\n\r\n\r");
Ivop 1:7a82f806fe92 207 printf("Press any key to continue\n\r");
Ivop 4:a9e3ee5741be 208
Ivop 4:a9e3ee5741be 209 getc(stdin);
Ivop 3:b30605f1c435 210
Ivop 5:53d4a67cd657 211 c2_write_ar(C2_DEVID);
Ivop 3:b30605f1c435 212 devid = c2_read_dr();
Ivop 5:53d4a67cd657 213 if (devid <= 0) fatal("unable to read devid\n\r");
Ivop 1:7a82f806fe92 214
Ivop 5:53d4a67cd657 215 c2_write_ar(C2_REVID);
Ivop 3:b30605f1c435 216 revid = c2_read_dr();
Ivop 3:b30605f1c435 217 if (revid < 0) fatal("unable to read revid\n\r");
Ivop 3:b30605f1c435 218
Ivop 4:a9e3ee5741be 219 for (i=0; devices[i].name; i++) {
Ivop 4:a9e3ee5741be 220 if (devices[i].devid == devid) break;
Ivop 4:a9e3ee5741be 221 }
Ivop 4:a9e3ee5741be 222
Ivop 7:65a72aad87b8 223 if (!i) fatal("unknown device: %02X:%02X\n\r", devid, revid);
Ivop 4:a9e3ee5741be 224
Ivop 4:a9e3ee5741be 225 switch(devid) {
Ivop 4:a9e3ee5741be 226 case 0x0f: case 0x28: case 0x18: case 0x19: C2_FPDAT = 0xad;
Ivop 4:a9e3ee5741be 227 default: break;
Ivop 4:a9e3ee5741be 228 }
Ivop 4:a9e3ee5741be 229
Ivop 4:a9e3ee5741be 230 printf("\n\rDevice found: %s (%02X:%02X)", devices[i].name, devid, revid);
Ivop 4:a9e3ee5741be 231 printf("\n\rFPDAT Address: 0x%02X", C2_FPDAT);
Ivop 4:a9e3ee5741be 232 printf("\n\rPage Size: %i\n\r", page_size);
Ivop 4:a9e3ee5741be 233 }