Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
CmdBuffer.h@0:27e403b8981e, 2012-04-28 (annotated)
- 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?
User | Revision | Line number | New 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 |