Basis for the C2 protocol from Silicon Labs.

Dependencies:   mbed

main.cpp

Committer:
Ivop
Date:
2014-05-24
Revision:
3:b30605f1c435
Parent:
2:9092d0d1558b
Child:
4:a9e3ee5741be

File content as of revision 3:b30605f1c435:

/*
 * SiLabs C2 Protocol on mbed pins p5/p6
 *
 * Copyright (c) 2014, Ivo van Poorten <ivopvp@gmail.com>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
#include "mbed.h"

DigitalOut c2ck(p5);
DigitalInOut c2d(p6);

static void c2ck_reset(void) {
    c2ck = 0;
    wait_us(25);
    c2ck = 1;
    wait_us(1);
}

static void c2ck_strobe(void) {
    c2ck = 0;
    wait_us(1);
    c2ck = 1;
    wait_us(1);
}

// Four basic C2 Instructions
//
// 00b  Data Read
// 01b  Data Write
// 10b  Address Read
// 11b  Address Write
//
// Remember, ALL fields are sent LSB first(!)

#define START       do{ c2ck_strobe(); }while(0)
#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) {    \
            c2ck_strobe();      \
            wait_us(1);         \
        } if (!t) return -1;    \
    } while(0)

static int c2_read_dr(void) {
    int t = 20, i, d = 0;
    
    START;
    c2d.output();
    INS(0,0);
    LENGTH(0,0);    
    c2d.input();
    WAIT;    

    for (i=0; i<8; i++) {   // DATA
        d >>= 1;
        c2ck_strobe();
        if (c2d) d |= 0x80;
    }
    
    STOP;
    
    return d;
}

static int c2_write_dr(int d) {
    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;
    }

    c2d.input();
    WAIT;
    STOP;
    
    return 0;
}

static int c2_read_ar(void) {
    int i, a = 0;
    
    START;
    c2d.output();
    INS(0,1);
    c2d.input();

    for(i=0; i<8; i++) {        // ADDRESS
        a >>= 1;
        c2ck_strobe();
        if (c2d) a |= 0x80;
    }
    
    STOP;
    
    return a;
}

static void c2_write_ar(int a) {
    int i;

    START;
    c2d.output();
    INS(1,1);

    for(i=0; i<8; i++) {        // ADDRESS
        c2d = a & 1;
        c2ck_strobe();
        a >>= 1;
    }
    
    c2d.input();
    STOP;
}

static void fatal(char *s) {
    puts(s);
loop:
    goto loop;
}

int main() {
    int c, devid, revid;
    
    c2d.input();
    c2ck = 1;

    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);

    c2_write_ar(0x00);
    devid = c2_read_dr();
    if (devid < 0) fatal("unable to read devid\n\r");
    
    c2_write_ar(0x01);
    revid = c2_read_dr();
    if (revid < 0) fatal("unable to read revid\n\r");

    printf("devid:revid = %02x:%02x\n\r", devid, revid);
}