Peter Cooper
/
Dome
Geodesic Light Dome Controller Program
Revision 0:a7af7ec8b12f, committed 2010-03-19
- Comitter:
- lolpcc
- Date:
- Fri Mar 19 11:17:54 2010 +0000
- Child:
- 1:dc58f0b0eeec
- Commit message:
Changed in this revision
--- /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