It works! (on AVR)
[cerebrum.git] / msp / comm.c
blob97782378364a3639bdab603f2ffa8f7b20d3d9f3
1 /*
2 Copyright (C) 2012 jaseg <s@jaseg.de>
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 version 3 as published by the Free Software Foundation.
7 */
9 #include <stdint.h>
10 #include <stddef.h>
11 #include <msp430.h>
12 #include "comm.h"
13 #include "uart_io.h"
15 void comm_loop(){
16 static uint8_t escape_state = 0;
17 static uint8_t state = 0;
18 static uint16_t pos = 0;
19 static uint16_t funcid = 0;
20 static uint16_t crcbuf = 0;
21 static uint8_t argbuf[ARGBUF_SIZE];
22 static uint16_t arglen = 0;
24 uint16_t v = uart_getc_nonblocking();
25 uint8_t c = v&0xff;
26 v &= 0xff00;
27 if(!v){ //a character was successfully received
28 if(escape_state){
29 if(c == '#'){ //FIXME
30 pos = 0;
31 return;
33 escape_state = 0;
34 }else{
35 if(c == '\\'){
36 escape_state = 1;
37 return;
40 //escape sequence handling completed. 'c' now contains the next char of the payload.
41 switch(state){
42 case 0: //receive funcid, payload length
43 switch(pos){
44 case 0:
45 funcid = c<<8;
46 pos++;
47 break;
48 case 1:
49 funcid |= c;
50 pos++;
51 break;
52 case 2:
53 arglen = c<<8;
54 pos++;
55 break;
56 case 3:
57 pos = c;
58 arglen |= c;
59 state = 1;
60 break;
62 break;
63 case 1: //receive arg payload
64 pos--;
65 argbuf[pos] = c;
66 if(pos == 0)
67 state = 3;
68 break;
69 case 2: //receive and check payload crc. finally, call the function and send the return value
70 if(pos == 0){
71 crcbuf = c<<8;
72 pos++;
73 }else{
74 crcbuf |= c;
75 //successfully received the crc
76 //FIXME add crc checking
77 if(funcid < NUM_CALLBACKS){
78 //HACK: The argument buffer is currently passed as the response buffer for ram efficiency.
79 //Only write to the response buffer *after* you are done reading from it.
80 comm_callbacks[funcid](arglen, argbuf);
81 }else{
82 //FIXME error handling
85 break;
90 void putc_escaped(char c){
91 if(c == '\\'){
92 uart_putc(c);
94 uart_putc(c);