Geodesic Light Dome Controller Program

Dependencies:   mbed

Files at this revision

API Documentation at this revision

Comitter:
lolpcc
Date:
Fri Mar 19 11:17:54 2010 +0000
Child:
1:dc58f0b0eeec
Commit message:

Changed in this revision

breakup.c Show annotated file Show diff for this revision Revisions of this file
breakup.h Show annotated file Show diff for this revision Revisions of this file
cmd.c Show annotated file Show diff for this revision Revisions of this file
cmd.h Show annotated file Show diff for this revision Revisions of this file
i2c.c Show annotated file Show diff for this revision Revisions of this file
i2c.h Show annotated file Show diff for this revision Revisions of this file
local_defines.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
main.h Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
pca9685_reg.h Show annotated file Show diff for this revision Revisions of this file
scripting.c Show annotated file Show diff for this revision Revisions of this file
scripting.h Show annotated file Show diff for this revision Revisions of this file
serial.c Show annotated file Show diff for this revision Revisions of this file
serial.h Show annotated file Show diff for this revision Revisions of this file
useful.c Show annotated file Show diff for this revision Revisions of this file
useful.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/breakup.c	Fri Mar 19 11:17:54 2010 +0000
@@ -0,0 +1,114 @@
+#include "mbed.h"
+
+/*
+int breakup(char *, char *[], char);
+void breakup_sub(char *, char *,char,char);
+*/
+
+void breakup_sub(char *line,char *entery_point,char c,char d)
+{
+    char *point,*pt2;
+     
+    point = entery_point;
+    
+    point++;
+    pt2 = point;
+    point --;
+    while (*pt2!='\0') {
+        *point = *pt2;
+        point ++;
+        pt2 ++;
+    }
+    *point = *pt2;
+}
+
+int breakup(char *string,char *p[],char c)
+{
+    char *pt,*pt1;
+    char cc,ccc;
+    int cnt = 0;
+    int number = 0;
+    int flag = 0;
+    int last = 0;
+    int just = 0;
+    int length = strlen(string);
+
+    pt = string;
+    p[number] = pt;
+    number++;
+
+    while (cnt != length + 1) {
+        cc = *pt;
+        if (cc == '\0')
+            return(number);
+        /* this section of code will need sorting, so we don't have to use a space
+           char, we should move the ramainder of the buffer down one charactor
+        */
+        if (cc=='\\') {
+            pt1 = pt;    /* save the current pointer */
+            pt++;
+            ccc = *pt;
+            if (ccc=='"') {
+                pt--;
+                breakup_sub(string,pt,cc,ccc);
+                pt = pt1;
+            } else {
+                pt--;
+                pt = pt1;    /* restore the current pointer */
+            }
+        }
+        if (flag == 0) {
+            switch (cc) {
+                case '"' :
+                    flag = 1;
+                case '\n' :
+                case '\t' :
+                case ' ' :
+                    if (just==1) {
+                        /* move the current pointer along */
+                        pt = pt + 1;
+                        p[number] = pt;
+                        pt = pt - 1;
+                    } else {
+                        /* add the current point to the array  */
+                        just = 1;
+                        *pt = '\0';
+                        pt++;
+                        p[number] = pt;
+                        pt--;
+                    }
+                    if (flag == 1) {
+                        number ++;
+                        just = 0;
+                    }
+                    break;
+                default :
+                    if (just == 1) {
+                        just = 0;
+                        number ++;
+                    }
+                    break;
+            }
+            if (cc == c) {  /* test for the user defined char  */
+                just = 1;
+                *pt = '\0';
+                pt++;
+                p[number] = pt;
+                pt--;
+            }
+        } else {
+            if ((last == 0) & (cc =='"')) {     /* close of quoate */
+                flag = 0;
+                just = 1;
+                *pt = '\0';
+                pt++;
+                p[number] = pt;
+                pt--;
+            } else if ((flag == 1) & (last == 1) & (cc!='\\'))
+                last = 0;
+        }
+        pt++;
+        cnt++;
+    }
+    return(-1);
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/breakup.h	Fri Mar 19 11:17:54 2010 +0000
@@ -0,0 +1,1 @@
+int breakup(char *string,char *p[],char c);
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cmd.c	Fri Mar 19 11:17:54 2010 +0000
@@ -0,0 +1,214 @@
+#include "mbed.h"
+#include "breakup.h"
+#include "useful.h"
+#include "i2c.h"
+#include "serial.h"
+#include "cmd.h"
+#include "local_defines.h"
+#include "scripting.h"
+
+
+LocalFileSystem local("local");
+FILE    *exec_fp;
+extern int sys_state;
+extern int var[MAX_VAR];
+extern int jmp[MAX_JMP];
+
+
+
+/******************************************/
+/*                                        */
+/* Exec commands, for the dome            */
+/*                                        */
+/******************************************/
+
+struct    cmd_callback {
+    char    *label;            /* command */
+    int     cmd;               /* switch value */
+    int     args;              /* Number of args for this command */
+    void    (*cmd_routine)(int,char **);    /* call */
+};
+struct cmd_callback cmd_cb[] ={
+    {  "list",     0,   1,    list},                /* List I2C Devices to user */
+    {  "list2",    0,   1,    list2},               /* List I2C Devices to user */
+    {  "exec",     0,   2,    exec_file},           /* Run a script file from the local file store */
+    {  "dir",      0,   1,    dir_file},            /* Get a directory listing from the local file store */
+    {   "cat",      0,      2,    cat_file},            /* Cat a file on the file system to the current output device */
+    {  "relay",    0,   2,    relay_control},       /* Switch a relay 0-8 */
+    {  "light",    0,   3,    light_control},       /* Set a light level on a channel */
+    {  "wait",     0,   2,    wait_control},        /* wait for X tenths of a second */
+    {  "baud",     0,   2,    baud_rate},           /* Set the baudrate of the serial I/O */
+    {  "pca",      0,   2,    init_pca},            /* Init a PCA9685 device from the command line */
+    {  "print",    0,   0,    print_string},        /* Print a string to current output device */
+    {   "set",      0,      0,    set_var},             /* Set the variable to a value */
+    {   "sum",      0,      0,    sum_var},             /* Add some basic maths */
+    {   "point",    0,      0,    point_var},           /* Set out loop point */
+    {   "tst",      0,      0,    tst_var},             /* test the value of a var */
+    {   "clr",      0,      0,    clr_var},             /* Clear the var's to zero */
+    {  "END",      -1,  -1,   error_handler}
+};
+
+
+/* Scan down tags, to find the match, else return -1 */
+int find_cmd(char *tag)
+{
+    int     cnt=0,c;
+    int  length=strlen(tag);
+    char *elements[0x10];
+
+    if(tag[0]=='#') /* See is we have a command or a comment */
+        return(0);
+
+    c = breakup(tag,elements,' ');
+    while(1){
+        if((strcmp(cmd_cb[cnt].label,"END"))==0){
+                  if(length>1)
+            cmd_cb[cnt].cmd_routine(c,elements);  /* this will call the error routine */
+            return(cmd_cb[cnt].cmd);
+        } else if((strcmp(cmd_cb[cnt].label,tag))==0){
+            if((cmd_cb[cnt].args==c) || (cmd_cb[cnt].args==0)){    /* if arg count set to zero, can be anything */
+                cmd_cb[cnt].cmd_routine(c,elements);        /* Call the function with args */
+                return(cnt);
+            } else {
+                lprintf("\n\rWrong number of args passed to %s\n\r",cmd_cb[cnt].label);
+                return(-1);
+            }
+        }
+        cnt++;
+    }
+}
+
+
+void error_handler(int c, char **a)
+{
+    int cnt=0;
+    lprintf("\n\rCommands available are ");
+    while(1){
+        if((strcmp(cmd_cb[cnt].label,"END"))==0){
+            lprintf("\n\r");
+            return;
+        } else
+            lprintf("%s, ",cmd_cb[cnt].label);
+        cnt++;
+    }
+}
+
+/******************************************/
+/*                                        */
+/* Command stubs are here                 */
+/*                                        */
+/******************************************/
+
+void list(int c, char **a)
+{
+    i2c_probe();
+}
+void list2(int c, char **a)
+{
+    i2c_probe2();
+}
+
+void exec_file(int c, char **a)
+{
+    /* File on a[1] */
+    
+    FILE    *fp;
+    char     buf[0x60];
+    char     cmd[0x60];
+    
+    sprintf(buf,"/local/%s",a[1]);
+    
+    if((fp = fopen(buf,"r"))==NULL){
+        lprintf("Unable to open %s\n\r",buf);
+        return;
+    }
+    sys_state = sys_state | EXEC_CALLED;
+    while(!feof(fp)){
+        fgets(buf,sizeof(buf),fp);
+        if(strlen(buf) > 2){
+            sprintf(cmd,"%s\n",buf);
+            find_cmd(cmd);
+        }
+        buf[0]='\0';
+        buf[1]='\0';
+    }
+    fclose(fp);
+}
+void dir_file(int c, char **a)
+{
+    lprintf("List of files in /local\n\r");
+
+    DIR *d;
+    struct dirent *p;
+    d = opendir("/local");
+    if(d != NULL) {
+        while((p = readdir(d)) != NULL) {
+            lprintf(" - %s\n\r", p->d_name);
+        }
+    } else {
+        error("Could not open directory!");
+    }
+}
+void cat_file(int c, char **a)
+{
+    /* File on a[1] */
+    
+    FILE    *fp;
+    char     buf[0x60];
+    
+    sprintf(buf,"/local/%s",a[1]);
+    
+    if((fp = fopen(buf,"r"))==NULL){
+        lprintf("Unable to open %s\n\r",buf);
+        return;
+    }
+    
+    while(!feof(fp)){
+        fgets(buf,sizeof(buf),fp);
+        if(strlen(buf) > 2){
+            lprintf(buf);
+        }
+        buf[0]='\0';
+        buf[1]='\0';
+    }
+    fclose(fp);
+}
+
+
+void relay_control(int c, char **a)
+{
+    relay_operate(htoi(a[1]));
+}
+
+void wait_control(int c, char **a)
+{
+    wait(htoi(a[1])/10);
+}
+
+void light_control(int c, char **a)
+{
+     channel_light(htoi(a[1]), htoi(a[2]));
+}
+void init_pca(int c, char **a)
+{
+    init_pca9685(htoi(a[1]));
+}
+
+void print_string(int c, char **a)
+{
+    int cnt = 1;
+    int len;
+    while(cnt <= c){
+        if(a[cnt][0]=='v' || a[cnt][0]=='V'){
+            len = strlen(a[cnt]);
+            if(len == 2){
+                lprintf(" %04x",htoi(a[cnt]));
+            } else {
+                lprintf("%s",a[cnt]);
+            }
+        } else
+            lprintf("%s",a[cnt]);
+        cnt++;
+    }
+    lprintf("\n");
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cmd.h	Fri Mar 19 11:17:54 2010 +0000
@@ -0,0 +1,13 @@
+int find_cmd(char *tag);
+void error_handler(int c, char **a);
+
+void list(int c, char **a);
+void list2(int c, char **a);
+void exec_file(int c, char **a);
+void dir_file(int c, char **a);
+void cat_file(int c, char **a);
+void relay_control(int c, char **a);
+void wait_control(int c, char **a);
+void light_control(int c, char **a);
+void init_pca(int c, char **a);
+void print_string(int c, char **a);
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/i2c.c	Fri Mar 19 11:17:54 2010 +0000
@@ -0,0 +1,252 @@
+#include "mbed.h"
+
+#include "main.h"
+#include "useful.h"
+#include "i2c.h"
+#include "pca9685_reg.h"    /* Light Driver Chip */
+
+I2C i2c(p9, p10); // sda, scl
+I2C i2c_1(p28, p27); // sda, scl
+
+
+#define PIO          0x40
+#define RELAYS       0x40
+
+
+
+/******************************************/
+/*                                        */
+/*   Probe the I2C bus, and show the      */
+/*   user what we have found              */
+/*                                        */
+/*                                        */
+/*                                        */
+/******************************************/
+void i2c_probe(void) 
+{
+    lprintf("Searching for I2C devices...\n");
+    
+    int count = 0;
+    for (int address=4; address<256; address+=2) {
+        if (!i2c.write(address, NULL, 0)) { // 0 returned is ok
+            lprintf(" - I2C device found at address 0x%02X\n", address);
+            count++;
+        }
+    }
+    lprintf("%d devices found\n", count);
+}
+void i2c_probe2(void) 
+{
+    lprintf("Searching for I2C devices... (seconday bus)\n");
+    
+    int count = 0;
+    for (int address=4; address<256; address+=2) {
+        if (!i2c_1.write(address, NULL, 0)) { // 0 returned is ok
+            lprintf(" - I2C device found at address 0x%02X\n", address);
+            count++;
+        }
+    }
+    lprintf("%d devices found\n", count);
+}
+
+
+
+/******************************************/
+/*                                        */
+/* 1 - 8, Relays On,                      */
+/*                                        */
+/******************************************/
+void relay_operate(char r)
+{
+    char buf[0x60];
+        
+    switch(r){
+        case    0    :    /* Turn off the relays */
+            buf[0]=0x00; 
+            break;
+        case    1    :
+            buf[0]=0x01; 
+            break;
+        case    2    :
+            buf[0]=0x02; 
+            break;
+        case    3    :
+            buf[0]=0x04; 
+            break;
+        case    4    :
+            buf[0]=0x08; 
+            break;
+        case    5    :
+            buf[0]=0x10; 
+            break;
+        case    6    :
+            buf[0]=0x20; 
+            break;
+        case    7    :
+            buf[0]=0x40; 
+            break;
+        case    8    :
+            buf[0]=0x80; 
+            break;
+        default      :
+            lprintf("Unknown Relay %d\n\r",r);
+            return;
+    }
+    i2c.write(RELAYS,buf,1);
+}
+
+/******************************************/
+/*                                        */
+/* Read and Write the PIO latch           */
+/*                                        */
+/******************************************/
+void pio_write(unsigned char r, unsigned char d)
+{
+    unsigned char buf[0x60];
+    
+    buf[0]=d;
+    i2c.write(r,(char *)buf,1);
+}
+void pio_read(unsigned char d)
+{
+   unsigned char r;
+   unsigned char buf[0x60];
+    
+   i2c.read(d,(char *)buf,1);
+   r = buf[0];
+   
+   lprintf("Returned value from the PIO was 0x%02x\n\r",r);
+}
+
+/******************************************/
+/*                                        */
+/* Philips PCA9685 I2C Driver, 16 channel */
+/* Lighting controler chip, we have 4     */
+/* running in this system, so we need to  */
+/* think how the channels map ??          */
+/*                                        */
+/******************************************/
+
+/******************************************/
+/*                                        */
+/* Init code for the PCA9685              */
+/*                                        */
+/******************************************/
+
+void init_pca9685(unsigned char address)
+{
+    unsigned char buf[30];
+    
+    lprintf("Setting up channel %d\n\r",address);
+    
+    buf[0] = PCA9685_MODE1;
+    buf[1] = PCA9685_AI;
+    buf[2] = PCA9685_OUTDRV;
+    i2c.write(address,(char *) buf, 3);
+}
+
+/******************************************/
+/*                                        */
+/* Send data to a given channle of a      */
+/* given PCA9685 chip                     */
+/*                                        */
+/******************************************/
+
+void pca9685_led(unsigned char addr, int led, unsigned char *values) 
+{
+    unsigned char buf[5];
+   
+    if (led == PCA9685_ALL_LEDS) {
+        buf[0] = PCA9685_ALL_LED_ON_L;
+    } else {
+        buf[0] = PCA9685_BASE(led);
+    }
+
+    buf[1] = values[0];
+    buf[2] = values[1];
+    buf[3] = values[2];
+    buf[4] = values[3];
+    i2c.write(addr, (char *)buf, 5);
+}
+
+/******************************************/
+/*                                        */
+/* Calculate the register values for a    */
+/* givern brightness percentage           */
+/*                                        */
+/******************************************/
+
+void pca9685_brightness(int percent, unsigned char *values) 
+{
+    unsigned int on, off;
+
+    if (percent == 0) {
+    values[PCA9685_LED_ON_H] = 0;
+    values[PCA9685_LED_OFF_H] = PCA9685_LED_OFF;
+    return;
+    }
+    if (percent == 100) {
+    values[PCA9685_LED_ON_H] = PCA9685_LED_ON;
+    values[PCA9685_LED_OFF_H] = 0;
+    return;
+    }
+    on = 0;
+    off = (4096 * percent) / 100;
+    values[PCA9685_LED_ON_L] = on & 0xff;
+    values[PCA9685_LED_ON_H] = (on >> 8) & 0xf;
+    values[PCA9685_LED_OFF_L] = off & 0xff;
+    values[PCA9685_LED_OFF_H] = (off >> 8) & 0xf;
+}
+
+/******************************************/
+/*                                        */
+/* Set a given channel to a given level   */
+/*                                        */
+/******************************************/
+void channel_light(unsigned char ch, unsigned char lev)
+{
+    char            chip,led;     /* Chip Number, channel number */
+    unsigned char   v[4];         /* register data for givern level */
+    
+    led = ch%16;
+    v[0]=0;
+    v[1]=0;
+    v[2]=0;
+    v[3]=0;
+    
+    if(lev > 100){
+        lprintf("Level percentage range 0 - 100 (Trying for %d)\n\r",lev);
+        return;
+    }
+    
+    switch(ch/16){
+        case    0    :
+            chip=LEDDRV1;
+            break;
+        case    1    :
+            chip=LEDDRV2;
+            break;
+        case    2    :
+            chip=LEDDRV3;
+            break;
+        case    3    :
+            chip=LEDDRV4;
+            break;
+        case    4    :
+            chip=LEDDRV5;
+            break;
+        case    5    :
+            chip=LEDDRV6;
+            break;
+        default      :
+            lprintf("Error unknown chip %d\n\r",ch/16);
+            return;
+    }
+    
+    lprintf("Setting channel %d to brightness leven %d chip = %d(%d),%d\n\r",
+        ch,lev,chip,ch/16,led);
+    pca9685_brightness(lev,v);    /* Calculate the brightness level */
+    lprintf("Brightness level is %02x,%02x,%02x,%02x\n\r",v[0],v[1],v[2],v[3]);
+    pca9685_led(chip,led,v);      /* Send to chip */
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/i2c.h	Fri Mar 19 11:17:54 2010 +0000
@@ -0,0 +1,35 @@
+/* I2C bus Functions */
+
+void i2c_probe(void);
+void i2c_probe2(void);
+
+char init_lcd(void);
+char clear_lcd(void);
+char set_lcd(char line, char col);
+char write_lcd(char *str);
+
+char read_keyboard(void);
+char blocking_read_keyboard(void);
+
+void relay_operate(char r);
+void pio_write(unsigned char r,unsigned char d);
+void pio_read(unsigned char  d);
+
+void init_pca9685(unsigned char address);
+void channel_light(unsigned char ch, unsigned char lev);
+void pca9685_led(unsigned char addr, int led, unsigned char *values);
+void pca9685_brightness(int percent, unsigned char *values);
+
+void test_seven_seg(char loop);
+void print_seven_seg(unsigned char a,unsigned char b,unsigned char c,unsigned char d);
+
+void batron_lcd_init(void);
+void batron(void);
+char batron_lcd_write(char *b);
+char ascii_to_lcd(char ch);
+void batron_clear(void);
+char batron_clear_line(char row);
+char batron_put_xy(char ddram_byte, char row, char column);
+
+char pcf8574_kbd(char state);
+char pcf8584_sub_kbd(unsigned char d);
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/local_defines.h	Fri Mar 19 11:17:54 2010 +0000
@@ -0,0 +1,8 @@
+#define TO_RS232 0x00000001
+#define TO_USB   0x00000002
+
+#define EXEC_CALLED     0x00010000      /* Execed a script from the user */
+#define INDENT_SET      0x00020000      /* Jump point set */
+
+#define MAX_VAR         10              /* Max number of variables in the stack */
+#define MAX_JMP         10              /* Max jump points in code */
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Fri Mar 19 11:17:54 2010 +0000
@@ -0,0 +1,108 @@
+#include "mbed.h"
+#include "main.h"
+#include "cmd.h"
+#include "i2c.h"
+#include "serial.h"
+#include "scripting.h"
+#include "breakup.h"
+#include "local_defines.h"
+
+Serial pc(USBTX, USBRX); // tx, rx
+
+int sys_state = 0;
+int var[MAX_VAR];
+
+int main() 
+{
+    char    buf[0x20];    /* input buffer */
+    int     r;            /* general int */
+    
+    sys_state = TO_RS232;
+    
+    exec_profile();
+    
+//    relay_operate(0);
+//    init_pca9685(0xb8);
+//    init_pca9685(0xba);
+    
+    pc.printf("\n\rDome Controler\n\n\r\r");
+    rs232_opener();
+    pc.printf("\n\rCMD > ");
+    while(1){             /* Command Loop */
+        r = 0;
+        while(r==0){
+            if(pc.readable()){
+                sys_state = TO_USB;
+                r = usb_gets(buf,sizeof(buf));
+            } else if(rs232_readable()){
+                sys_state = TO_RS232;
+                r = rs232_gets(buf,sizeof(buf));
+            }
+        }
+        if(r>2){
+            find_cmd(buf);
+        }
+        if (sys_state & TO_USB)
+            pc_output_string("\n\rCMD > ");
+        if (sys_state & TO_RS232)
+            rs232_output_string("\n\rCMD > ");
+        sys_state = 0;
+    }
+}
+
+int usb_gets(char *s,int len) 
+{
+    char   c;
+    int    cnt=0;
+
+    while ((c = pc.getc()) != 0) {
+        if ((c == 0x0a) || (c==0x0d)) {
+            pc.printf("\n\r");
+            *s++ = '\0';
+            return(cnt);    /* Return length */
+        } else if (c==0x7f) {  /* Delete */
+            pc.putc(0x08);
+            pc.putc(0x20);
+            pc.putc(0x08);
+            cnt--;
+            *s--;
+        } else if (c==0x08) {  /* BS */
+            pc.putc(0x08);
+            pc.putc(0x20);
+            pc.putc(0x08);
+            cnt--;
+            *s--;
+        } else if (c==025) {  /* CTRL-U */
+            while (cnt!=0) {
+                pc.putc(0x08);
+                pc.putc(0x20);
+                pc.putc(0x08);
+                cnt--;
+                *s--;
+            }
+        } else {
+            *s++ = c;
+            pc.putc(c);
+            cnt++;
+        }
+    }
+    return(cnt);
+}
+
+void pc_output_string(char *buf)
+{
+    int a = 0;
+    while(a != strlen(buf)){
+        pc.putc(buf[a]);
+        if(buf[a]=='\n')
+            pc.putc('\r');
+        a++;
+    }
+}
+
+void exec_profile(void)
+{
+    char    *a[2] = {"exec","profile.cmd"};
+    exec_file(2,a);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.h	Fri Mar 19 11:17:54 2010 +0000
@@ -0,0 +1,4 @@
+int usb_gets(char *s,int len);
+void usb_remap(void);
+void pc_output_string(char *buf);
+void exec_profile(void);
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Fri Mar 19 11:17:54 2010 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/49a220cc26e0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pca9685_reg.h	Fri Mar 19 11:17:54 2010 +0000
@@ -0,0 +1,120 @@
+#ifndef __PCA9685_H
+#define __PCA9685_H
+
+/* Devices */
+#define LEDDRV1    0xb8
+#define LEDDRV2    0xba
+#define LEDDRV3    0xd8
+#define LEDDRV4    0xda
+#define LEDDRV5    0xc8
+#define LEDDRV6    0xca
+
+/* Registers */
+#define PCA9685_MODE1            0x00
+#define PCA9685_MODE2            0x01
+#define PCA9685_SUBADR1            0x02
+#define PCA9685_SUBADR2            0x03
+#define PCA9685_SUBADR3            0x04
+#define PCA9685_ALLCALLADR        0x05
+#define PCA9685_LED0_ON_L        0x06
+#define PCA9685_LED0_ON_H        0x07
+#define PCA9685_LED0_OFF_L        0x08
+#define PCA9685_LED0_OFF_H        0x09
+#define PCA9685_LED1_ON_L        0x0a
+#define PCA9685_LED1_ON_H        0x0b
+#define PCA9685_LED1_OFF_L        0x0c
+#define PCA9685_LED1_OFF_H        0x0d
+#define PCA9685_LED2_ON_L        0x0e
+#define PCA9685_LED2_ON_H        0x0f
+#define PCA9685_LED2_OFF_L        0x10
+#define PCA9685_LED2_OFF_H        0x11
+#define PCA9685_LED3_ON_L        0x12
+#define PCA9685_LED3_ON_H        0x13
+#define PCA9685_LED3_OFF_L        0x14
+#define PCA9685_LED3_OFF_H        0x15
+#define PCA9685_LED4_ON_L        0x16
+#define PCA9685_LED4_ON_H        0x17
+#define PCA9685_LED4_OFF_L        0x18
+#define PCA9685_LED4_OFF_H        0x19
+#define PCA9685_LED5_ON_L        0x1a
+#define PCA9685_LED5_ON_H        0x1b
+#define PCA9685_LED5_OFF_L        0x1c
+#define PCA9685_LED5_OFF_H        0x1d
+#define PCA9685_LED6_ON_L        0x1e
+#define PCA9685_LED6_ON_H        0x1d
+#define PCA9685_LED6_OFF_L        0x20
+#define PCA9685_LED6_OFF_H        0x21
+#define PCA9685_LED7_ON_L        0x22
+#define PCA9685_LED7_ON_H        0x23
+#define PCA9685_LED7_OFF_L        0x24
+#define PCA9685_LED7_OFF_H        0x25
+#define PCA9685_LED8_ON_L        0x26
+#define PCA9685_LED8_ON_H        0x27
+#define PCA9685_LED8_OFF_L        0x28
+#define PCA9685_LED8_OFF_H        0x29
+#define PCA9685_LED9_ON_L        0x2a
+#define PCA9685_LED9_ON_H        0x2b
+#define PCA9685_LED9_OFF_L        0x2c
+#define PCA9685_LED9_OFF_H        0x2d
+#define PCA9685_LED10_ON_L        0x2e
+#define PCA9685_LED10_ON_H        0x2f
+#define PCA9685_LED10_OFF_L        0x30
+#define PCA9685_LED10_OFF_H        0x31
+#define PCA9685_LED11_ON_L        0x32
+#define PCA9685_LED11_ON_H        0x33
+#define PCA9685_LED11_OFF_L        0x34
+#define PCA9685_LED11_OFF_H        0x35
+#define PCA9685_LED12_ON_L        0x36
+#define PCA9685_LED12_ON_H        0x37
+#define PCA9685_LED12_OFF_L        0x38
+#define PCA9685_LED12_OFF_H        0x39
+#define PCA9685_LED13_ON_L        0x3a
+#define PCA9685_LED13_ON_H        0x3b
+#define PCA9685_LED13_OFF_L        0x3c
+#define PCA9685_LED13_OFF_H        0x3d
+#define PCA9685_LED14_ON_L        0x3e
+#define PCA9685_LED14_ON_H        0x3f
+#define PCA9685_LED14_OFF_L        0x40
+#define PCA9685_LED14_OFF_H        0x41
+#define PCA9685_LED15_ON_L        0x42
+#define PCA9685_LED15_ON_H        0x43
+#define PCA9685_LED15_OFF_L        0x44
+#define PCA9685_LED15_OFF_H        0x45
+#define PCA9685_ALL_LED_ON_L       0xfa
+#define PCA9685_ALL_LED_ON_H       0xfb
+#define PCA9685_ALL_LED_OFF_L      0xfc
+#define PCA9685_ALL_LED_OFF_H      0xfd
+#define PCA9685_PRE_SCALE      0xfe
+
+/* MODE1 bits */
+#define PCA9685_RESTART    0x80
+#define PCA9685_EXTCLK    0x40
+#define PCA9685_AI    0x20
+#define PCA9685_SLEEP    0x10
+#define PCA9685_SUB1    0x08
+#define PCA9685_SUB2    0x04
+#define PCA9685_SUB3    0x02
+#define PCA9685_ALLCALL    0x01
+
+/* MODE2 bits */
+#define PCA9685_INVRT    0x10
+#define PCA9685_OCH    0x08
+#define PCA9685_OUTDRV    0x04
+#define PCA9685_OUTNE1    0x02
+#define PCA9685_OUTNE0    0x01
+
+/* LEDX_ON_H bits */
+#define PCA9685_LED_ON 0x10
+
+/* LEDX_OFF_H bits */
+#define PCA9685_LED_OFF 0x10
+
+#define PCA9685_LED_BUFSIZ       0x04
+#define PCA9685_BASE(led) ((led * 4) + 6)
+#define PCA9685_LED_ON_L       0x00
+#define PCA9685_LED_ON_H       0x01
+#define PCA9685_LED_OFF_L      0x02
+#define PCA9685_LED_OFF_H      0x03
+#define PCA9685_ALL_LEDS    -1
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripting.c	Fri Mar 19 11:17:54 2010 +0000
@@ -0,0 +1,177 @@
+#include "mbed.h"
+#include "local_defines.h"
+#include "useful.h"
+#include "scripting.h"
+
+extern int var[MAX_VAR];
+extern int sys_state;
+extern FILE    *exec_fp;
+
+long jmp[MAX_JMP];      /* Jump points */
+
+void clear_var(void)
+{
+    int a = 0;
+    
+    while(a != MAX_VAR){
+        var[a] = 0;
+        a++;
+    }
+}
+
+void set_var(int c, char **a)
+{
+    int v,val;
+    
+    if(sys_state & EXEC_CALLED){
+        if(c != 3)
+            var_exec_error(VAR_SET_CNT_ERROR);
+        else {
+            v = return_var(a[1]);
+            val = htoi(a[2]);
+            var[v]=val;
+        }
+            
+    } else 
+        var_exec_error(VAR_EXEC_ERROR);
+    
+}
+
+void sum_var(int c, char **a)
+{   
+    int v,val1,val2;
+       
+    if(sys_state & EXEC_CALLED){
+        if(c != 4)
+            var_exec_error(VAR_SUM_CNT_ERROR);
+        else {
+            val1 = htoi(a[1]);
+            val2 = htoi(a[3]);
+            v = return_var(a[1]);
+            switch(a[2][0]){
+                case    '+' :
+                    var[v] = val1 + val2;
+                    break;
+                case    '-' :
+                    var[v] = val1 - val2;
+                    break;
+                case    '/' :
+                    var[v] = val1 / val2;
+                    break;
+                case    '*' :
+                    var[v] = val1 * val2;
+                    break;
+                case    '%' :
+                    var[v] = val1 * val2;
+                    break;
+                default     :
+                    var_exec_error(VAR_SUM_TYPE_ERROR);
+            }
+        }
+    } else 
+        var_exec_error(VAR_EXEC_ERROR);
+}
+void point_var(int c, char **a)
+{
+    int v;
+    if(sys_state & EXEC_CALLED){
+        v = return_jmp(a[1]);
+       jmp[v] = ftell(exec_fp);         /* Read the current file pointers position */
+       sys_state = sys_state | INDENT_SET;  /* Mark the state as set */
+    } else 
+        var_exec_error(VAR_EXEC_ERROR);
+}
+void tst_var(int c, char **a)
+{
+    int v,val,j;
+    int doit=0;
+    
+    if(sys_state & EXEC_CALLED){
+        if(sys_state & INDENT_SET){
+            if(c != 5)
+                var_exec_error(VAR_TST_CNT_ERROR);
+            else {
+                v = return_var(a[1]);
+                j = return_jmp(a[4]);
+                val = htoi(a[3]);
+                switch(a[2][0]){
+                    case    '<' :
+                        if(var[v] < val)
+                            doit = 1;
+                        break;
+                    case    '>' :
+                        if(var[v] > val)
+                            doit = 1;
+                        break;
+                    case    '=' :
+                        if(var[v] == val)
+                            doit = 1;
+                        break;
+                    case    '!' :
+                        if(var[v] != val)
+                            doit = 1;
+                        break;
+                    default     :
+                        var_exec_error(VAR_TST_TYPE_ERROR);
+                }
+                if(doit)
+                    fseek (exec_fp ,jmp[j] , SEEK_SET );
+            }
+        } else
+            var_exec_error(VAR_INDENT_ERROR);
+    } else 
+        var_exec_error(VAR_EXEC_ERROR);
+}
+void clr_var(int c, char **a)
+{
+    if(sys_state & EXEC_CALLED){
+         clear_var();
+    } else 
+        var_exec_error(VAR_EXEC_ERROR);
+}
+void var_exec_error(int state)
+{
+    switch(state){
+        case    VAR_EXEC_ERROR  :
+            lprintf("Can only be called from an exec call\n");
+            break;
+        case    VAR_SET_CNT_ERROR :
+            lprintf("Format: set v<num> <value>\n");
+            break;
+        case    VAR_SUM_CNT_ERROR :
+            lprintf("Format: sum v<num> <action> v<num>\n");
+            break;
+        case    VAR_TST_CNT_ERROR :
+            lprintf("Format: tst v<num> <type> <value>\n");
+            break;
+        case    VAR_INDENT_ERROR :
+            lprintf("In branch test, with no point to loop back to\n");
+            break;
+        case    VAR_SUM_TYPE_ERROR :
+            lprintf("Unknown test type should be either +-/*\n");
+            break;
+        case    VAR_TST_TYPE_ERROR :
+            lprintf("Unknown test type should be either <>=!\n");
+            break;
+        default     :
+            lprintf("Unknown exec_error %04x\n",state);
+    }
+}
+
+int return_jmp(char *str)
+{
+    char    buf[0x4];
+    int     a;
+    
+    buf[0] = str[1];
+    buf[1] = str[2];
+    buf[2] = str[3];
+    buf[3] = str[4];
+    a = atoi(buf);
+    if(a > MAX_VAR){
+        lprintf("In Return_jmp, jmp number %d more than MAXJMP %d, returned -1\n",
+            a,MAX_JMP);
+        return(-1);
+    }
+    return(a);
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripting.h	Fri Mar 19 11:17:54 2010 +0000
@@ -0,0 +1,17 @@
+void clear_var(void);
+void set_var(int c, char **a);
+void sum_var(int c, char **a);
+void point_var(int c, char **a);
+void tst_var(int c, char **a);
+void clr_var(int c, char **a);
+void var_exec_error(int state);
+int return_jmp(char *str);
+
+
+#define     VAR_EXEC_ERROR      0x0001      /* Function called out side of an exec call */
+#define     VAR_SET_CNT_ERROR   0x0002      /* Set Var call, wrong number of arguments */
+#define     VAR_SUM_TYPE_ERROR  0x0004      /* Unknown type in sum call */
+#define     VAR_SUM_CNT_ERROR   0x0008      /* SuM var call, wrong number of arguments */
+#define     VAR_TST_CNT_ERROR   0x0010      /* Tst var call, wrong number of arguments */
+#define     VAR_INDENT_ERROR    0x0020      /* No point to jump back to */
+#define     VAR_TST_TYPE_ERROR  0x0040      /* Unknown type in test call */
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/serial.c	Fri Mar 19 11:17:54 2010 +0000
@@ -0,0 +1,118 @@
+#include "mbed.h"
+#include "useful.h"
+
+Serial rs232(p13, p14);  // tx, rx
+/******************************************/
+/*                                        */
+/*  Test the RS232 interface              */
+/*  Should send and recieve data on the   */
+/*  serial port, send a string, and get   */
+/*  back what is returned from the RX     */
+/*                                        */
+/******************************************/
+void rs232_opener(void)
+{
+    rs232.baud(9600);
+    rs232.printf("\n\r");
+    rs232.printf("Dome Controler\n\r");
+    rs232.printf("\n\rCMD > ");
+}
+
+void rs232_output_string(char *buf)
+{
+    int a = 0;
+    while(a != strlen(buf)){
+        rs232.putc(buf[a]);
+        if(buf[a]=='\n')
+            rs232.putc('\r');
+        a++;
+    }
+}
+
+int rs232_readable(void)
+{
+    return(rs232.readable());
+}
+
+int rs232_gets(char *s,int len) 
+{
+    char   c;
+    int    cnt=0;
+
+    while ((c = rs232.getc()) != 0) {
+        if ((c == 0x0a) || (c==0x0d)) {
+            rs232.printf("\n\r");
+            *s++ = '\0';
+            return(cnt);    /* Return length */
+        } else if (c==0x7f) {  /* Delete */
+            rs232.putc(0x08);
+            rs232.putc(0x20);
+            rs232.putc(0x08);
+            cnt--;
+            *s--;
+        } else if (c==0x08) {  /* BS */
+            rs232.putc(0x08);
+            rs232.putc(0x20);
+            rs232.putc(0x08);
+            cnt--;
+            *s--;
+        } else if (c==025) {  /* CTRL-U */
+            while (cnt!=0) {
+                rs232.putc(0x08);
+                rs232.putc(0x20);
+                rs232.putc(0x08);
+                cnt--;
+                *s--;
+            }
+        } else {
+            *s++ = c;
+            rs232.putc(c);
+            cnt++;
+        }
+    }
+    return(cnt);
+}
+
+/******************************************/
+/*                                        */
+/* Set the baud rate of the serial line   */
+/* from the command line input            */
+/*                                        */
+/******************************************/
+#define BAUD_NUMBER 10
+void baud_rate(int c, char **a)
+{
+    int    b,cnt;
+    int    v[BAUD_NUMBER] = {300,600,1200,2400,4800,9600,19200,38400,57600,15200};
+    
+    b = atoi(a[1]);
+    cnt = 0;
+    while(cnt < BAUD_NUMBER){
+        if(v[cnt]==b){    
+            rs232.baud(b);
+            return;
+        }
+        cnt++;
+    }
+    cnt=0;
+    lprintf("Select a speed from ");
+    while(cnt < BAUD_NUMBER){
+        lprintf("%d ",v[cnt]);
+        cnt++;
+    }
+    lprintf("\n\r");
+}
+
+void serial_test(int c, char **a)
+{
+    char    ch;
+    
+    rs232_output_string("Serial Test Routine\n\r");
+    
+    while(1){
+        ch = rs232.getc();
+        printf("Got %c\n\r",ch);
+        if(ch=='q')
+            return;
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/serial.h	Fri Mar 19 11:17:54 2010 +0000
@@ -0,0 +1,6 @@
+void rs232_opener(void);
+void rs232_output_string(char *buf);
+int rs232_readable(void);
+int rs232_gets(char *s,int len);
+void baud_rate(int c, char **a);
+void serial_test(int c, char **a);
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/useful.c	Fri Mar 19 11:17:54 2010 +0000
@@ -0,0 +1,112 @@
+#include "mbed.h"
+#include <stdarg.h>
+#include "main.h"
+#include "serial.h"
+#include "local_defines.h"
+#include "useful.h"
+
+extern int var[MAX_VAR];
+extern int sys_state;
+
+/* Function: hexview
+ *  Prints an array of char to stdout in hex.
+ *  The data is grouped in two 8 byte groups per line.
+ *  Each byte is displayed as 2 hex digits and every 
+ *  line starts with the address of the first byte.
+ *
+ *  There is no text view of a line.
+ *
+ * Variables:
+ *  buffer - The array to display.
+ *  size - The length of buffer.
+ * 
+ * Author: rmeyer
+ */
+void hexview(char *buffer, unsigned int size) {
+    printf("\n");
+    for(int i = 0; i < size; ++i) {
+        if((i%16)!=0) {
+            printf(" ");
+        } else {
+            printf("%04X:  ", (i));
+        }
+        printf("%02hhx", buffer[i]);
+        if((i%16) ==  7) { 
+            printf(" ");
+        }
+        if((i%16) == 15) {
+            printf("\n\r");
+        }
+    }
+    printf("\n\r\n\r\n\r");
+}
+
+/******************************************/
+/*                                        */
+/* Lprintf, Bring the printf under our    */
+/* control, so we can use either rs232    */
+/* or the USB-Serial connections as an    */
+/* I/O channel.                           */
+/*                                        */
+/******************************************/
+
+void lprintf(const char* fmt, ...)
+{
+    char    str[0x1000];
+    
+    va_list ap;
+    va_start(ap, fmt); 
+    vsprintf(str, fmt, ap);   
+    if (sys_state & TO_RS232){
+        rs232_output_string(str);
+    } else if (sys_state & TO_USB){
+        pc_output_string(str);           
+    }
+    va_end(ap);
+}
+
+/******************************************/
+/*                                        */
+/* Read a value in from a user, workout   */
+/* if its hex or decimal, and return an   */
+/* int to the user                        */
+/*                                        */
+/******************************************/
+int htoi(char *str)
+{
+    if(strlen(str)>=2){
+        if(str[0]=='v' || str[0]=='V'){
+            return(var[return_var(str)]);
+        } else if(str[1]=='x' || str[1]=='X'){
+            return(strtol(str, NULL, 16));
+        }        
+    }
+    return(atoi(str));
+}
+
+/******************************************/
+/*                                        */
+/* Given the input string, return the     */
+/* number of the variable the user wants  */
+/* its added to htoi, so all inputs       */
+/* should get access to the variable data */
+/*                                        */
+/******************************************/
+
+int return_var(char *str)
+{
+    char    buf[0x4];
+    int     a;
+    
+    buf[0] = str[1];
+    buf[1] = str[2];
+    buf[2] = str[3];
+    buf[3] = str[4];
+    a = atoi(buf);
+    if(a > MAX_VAR){
+        lprintf("In Return_var, var number %d more than MAXVAR %d, returned -1\n",
+            a,MAX_VAR);
+        return(-1);
+    }
+    return(a);
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/useful.h	Fri Mar 19 11:17:54 2010 +0000
@@ -0,0 +1,1 @@
+void hexview(char *buffer, unsigned int size);
void lprintf(const char* fmt, ...);
int htoi(char *str);
int return_var(char *str);
\ No newline at end of file