Adam Resnick / CNCAirbrush

Dependents:   CNCAirbrushCode

Committer:
stretch
Date:
Sat Apr 28 21:09:44 2012 +0000
Revision:
0:27e403b8981e
Child:
1:e16f55e9dcd3
Initial Public Release

Who changed what in which revision?

UserRevisionLine numberNew contents of line
stretch 0:27e403b8981e 1 #ifndef CMDBUFFER_H
stretch 0:27e403b8981e 2 #define CMDBUFFER_H
stretch 0:27e403b8981e 3
stretch 0:27e403b8981e 4 #define MAX_CMD_BUF 16
stretch 0:27e403b8981e 5 #define MAX_CMD_NUM 0xb
stretch 0:27e403b8981e 6 #define MAX_INTERRUPTS 3
stretch 0:27e403b8981e 7
stretch 0:27e403b8981e 8 // Command Struct
stretch 0:27e403b8981e 9 typedef struct {
stretch 0:27e403b8981e 10 char cmd;
stretch 0:27e403b8981e 11 union {
stretch 0:27e403b8981e 12 float f[6];
stretch 0:27e403b8981e 13 long l[6];
stretch 0:27e403b8981e 14 };
stretch 0:27e403b8981e 15 } Command;
stretch 0:27e403b8981e 16
stretch 0:27e403b8981e 17 class CmdBuffer {
stretch 0:27e403b8981e 18 public:
stretch 0:27e403b8981e 19 CmdBuffer() {
stretch 0:27e403b8981e 20 write = 0;
stretch 0:27e403b8981e 21 read = 0;
stretch 0:27e403b8981e 22 size = MAX_CMD_BUF + 1;
stretch 0:27e403b8981e 23 temp_ptr = 0;
stretch 0:27e403b8981e 24 temp_size = 2 + 6*9;
stretch 0:27e403b8981e 25 cmd_sizes[0x0] = 3;
stretch 0:27e403b8981e 26 cmd_sizes[0x1] = 5;
stretch 0:27e403b8981e 27 cmd_sizes[0x2] = 6;
stretch 0:27e403b8981e 28 cmd_sizes[0x3] = 6;
stretch 0:27e403b8981e 29 cmd_sizes[0x4] = 1;
stretch 0:27e403b8981e 30 cmd_sizes[0x5] = 1;
stretch 0:27e403b8981e 31 cmd_sizes[0x6] = 2;
stretch 0:27e403b8981e 32 cmd_sizes[0x7] = 1;
stretch 0:27e403b8981e 33 cmd_sizes[0x8] = 0;
stretch 0:27e403b8981e 34 cmd_sizes[0x9] = 0;
stretch 0:27e403b8981e 35 cmd_sizes[0xa] = 0;
stretch 0:27e403b8981e 36 interrupt_cmds[0] = 0xff;
stretch 0:27e403b8981e 37 interrupt_cmds[1] = 0xff;
stretch 0:27e403b8981e 38 interrupt_cmds[2] = 0xff;
stretch 0:27e403b8981e 39 };
stretch 0:27e403b8981e 40
stretch 0:27e403b8981e 41 bool isFull() {
stretch 0:27e403b8981e 42 return ((write + 1) % size == read);
stretch 0:27e403b8981e 43 };
stretch 0:27e403b8981e 44
stretch 0:27e403b8981e 45 bool isEmpty() {
stretch 0:27e403b8981e 46 return (read == write);
stretch 0:27e403b8981e 47 };
stretch 0:27e403b8981e 48
stretch 0:27e403b8981e 49 // Return true if we've queued a command
stretch 0:27e403b8981e 50 bool queue(char k) {
stretch 0:27e403b8981e 51 tempbuf[temp_ptr++] = k;
stretch 0:27e403b8981e 52 if (temp_ptr == 2) {
stretch 0:27e403b8981e 53 int cmd_num = (0x0f&char_to_num(tempbuf[1]))|(0xf0&char_to_num(tempbuf[0])<<4);
stretch 0:27e403b8981e 54 if (cmd_num > MAX_CMD_NUM) { //Invalid
stretch 0:27e403b8981e 55 temp_ptr = 0;
stretch 0:27e403b8981e 56 temp_size = 4 + 6*9;
stretch 0:27e403b8981e 57 return true;
stretch 0:27e403b8981e 58 } else {
stretch 0:27e403b8981e 59 temp_size = 2 + 9 * cmd_sizes[cmd_num];
stretch 0:27e403b8981e 60 }
stretch 0:27e403b8981e 61 }
stretch 0:27e403b8981e 62 if (temp_ptr >= temp_size) {
stretch 0:27e403b8981e 63 Command c;
stretch 0:27e403b8981e 64 c.cmd = (0x0f&char_to_num(tempbuf[1]))|(0xf0&char_to_num(tempbuf[0])<<4);
stretch 0:27e403b8981e 65 for (int i = 0; i < cmd_sizes[c.cmd]; i++) {
stretch 0:27e403b8981e 66 c.l[i] = str_to_long(tempbuf + 3 + i*9);
stretch 0:27e403b8981e 67 #ifdef DEBUG
stretch 0:27e403b8981e 68 printf("arg%d: %x\n\r",i,c.l[i]);
stretch 0:27e403b8981e 69 #endif
stretch 0:27e403b8981e 70 }
stretch 0:27e403b8981e 71 for (int i = 0; i < MAX_INTERRUPTS; i++) {
stretch 0:27e403b8981e 72 if (c.cmd == interrupt_cmds[i]){
stretch 0:27e403b8981e 73 interrupt_funcs[i](&c);
stretch 0:27e403b8981e 74 }
stretch 0:27e403b8981e 75 }
stretch 0:27e403b8981e 76 queue_cmd(c);
stretch 0:27e403b8981e 77 temp_ptr = 0;
stretch 0:27e403b8981e 78 temp_size = 4 + 6*9;
stretch 0:27e403b8981e 79 return true;
stretch 0:27e403b8981e 80 }
stretch 0:27e403b8981e 81 return false;
stretch 0:27e403b8981e 82 }
stretch 0:27e403b8981e 83
stretch 0:27e403b8981e 84 uint16_t available() {
stretch 0:27e403b8981e 85 return (write >= read) ? write - read : size - read + write;
stretch 0:27e403b8981e 86 };
stretch 0:27e403b8981e 87
stretch 0:27e403b8981e 88 Command * dequeue() {
stretch 0:27e403b8981e 89 Command * c = NULL;
stretch 0:27e403b8981e 90 if (!isEmpty()) {
stretch 0:27e403b8981e 91 c = &buf[read++];
stretch 0:27e403b8981e 92 read %= size;
stretch 0:27e403b8981e 93 }
stretch 0:27e403b8981e 94 return c;
stretch 0:27e403b8981e 95 };
stretch 0:27e403b8981e 96
stretch 0:27e403b8981e 97 bool attach_interrupt(char cmd, void (*func)(Command *), int num) {
stretch 0:27e403b8981e 98 if (num < MAX_INTERRUPTS) {
stretch 0:27e403b8981e 99 interrupt_funcs[num] = func;
stretch 0:27e403b8981e 100 interrupt_cmds[num] = cmd;
stretch 0:27e403b8981e 101 return true;
stretch 0:27e403b8981e 102 }
stretch 0:27e403b8981e 103 return false;
stretch 0:27e403b8981e 104 }
stretch 0:27e403b8981e 105
stretch 0:27e403b8981e 106 private:
stretch 0:27e403b8981e 107 void queue_cmd(Command k) {
stretch 0:27e403b8981e 108 if (isFull()) {
stretch 0:27e403b8981e 109 read++;
stretch 0:27e403b8981e 110 read %= size;
stretch 0:27e403b8981e 111 }
stretch 0:27e403b8981e 112 buf[write++] = k;
stretch 0:27e403b8981e 113 write %= size;
stretch 0:27e403b8981e 114 }
stretch 0:27e403b8981e 115
stretch 0:27e403b8981e 116 // Return 0xf if char is invalid
stretch 0:27e403b8981e 117 char char_to_num(char c) {
stretch 0:27e403b8981e 118 if(c >= '0' && c <= '9') {
stretch 0:27e403b8981e 119 return c - '0';
stretch 0:27e403b8981e 120 } else if(c >= 'a' && c <= 'f') {
stretch 0:27e403b8981e 121 return c - 'a' + 0xa;
stretch 0:27e403b8981e 122 } else if(c >= 'A' && c <= 'F') {
stretch 0:27e403b8981e 123 return c - 'A' + 0xa;
stretch 0:27e403b8981e 124 } else {
stretch 0:27e403b8981e 125 #ifdef DEBUG
stretch 0:27e403b8981e 126 printf("CmdBuffer::char_to_num: invalid number\r\n");
stretch 0:27e403b8981e 127 #endif
stretch 0:27e403b8981e 128 return 0xf;
stretch 0:27e403b8981e 129 }
stretch 0:27e403b8981e 130 }
stretch 0:27e403b8981e 131
stretch 0:27e403b8981e 132 long str_to_long(char * str) {
stretch 0:27e403b8981e 133 long ans = 0;
stretch 0:27e403b8981e 134 for (int i = 7; (i > 0 && i < 8); i -= 2) {
stretch 0:27e403b8981e 135 ans = ans << 8;
stretch 0:27e403b8981e 136 ans |= (0xf0 & char_to_num(str[i - 1])<<4);
stretch 0:27e403b8981e 137 ans |= (0x0f & char_to_num(str[i]));
stretch 0:27e403b8981e 138 }
stretch 0:27e403b8981e 139 return ans;
stretch 0:27e403b8981e 140 }
stretch 0:27e403b8981e 141
stretch 0:27e403b8981e 142 volatile uint16_t write;
stretch 0:27e403b8981e 143 volatile uint16_t read;
stretch 0:27e403b8981e 144 uint16_t size;
stretch 0:27e403b8981e 145 void (*interrupt_funcs[MAX_INTERRUPTS])(Command *);
stretch 0:27e403b8981e 146 char interrupt_cmds[MAX_INTERRUPTS];
stretch 0:27e403b8981e 147 Command buf[MAX_CMD_BUF + 1];
stretch 0:27e403b8981e 148 volatile uint16_t temp_ptr;
stretch 0:27e403b8981e 149 volatile uint16_t temp_size;
stretch 0:27e403b8981e 150 char tempbuf[2 + 6*9 + 1];
stretch 0:27e403b8981e 151 uint16_t cmd_sizes[MAX_CMD_NUM];
stretch 0:27e403b8981e 152 };
stretch 0:27e403b8981e 153
stretch 0:27e403b8981e 154 #endif