aboutsummaryrefslogtreecommitdiff
path: root/sem4/embedded/m3
diff options
context:
space:
mode:
Diffstat (limited to 'sem4/embedded/m3')
-rw-r--r--sem4/embedded/m3/EBNF.txt14
-rw-r--r--sem4/embedded/m3/m3.ino191
2 files changed, 205 insertions, 0 deletions
diff --git a/sem4/embedded/m3/EBNF.txt b/sem4/embedded/m3/EBNF.txt
new file mode 100644
index 0000000..8c1a81a
--- /dev/null
+++ b/sem4/embedded/m3/EBNF.txt
@@ -0,0 +1,14 @@
+l2frame = 0x02, len, l3packet, checksum, 0x03;
+len = byte;
+checksum = byte, byte;
+l3packet = type, recv_id, transducerl, quiet, nummasters, masters;
+recv_id = byte, byte, byte;
+transducerl = byte;
+quiet = byte;
+nummasters = byte;
+masters = master | { master };
+master = rssi, txid, txidtime;
+rssi = byte;
+txid = byte, byte, byte;
+txidtime = byte, byte;
+byte = 0 | 1 | 2 | ... | 255;
diff --git a/sem4/embedded/m3/m3.ino b/sem4/embedded/m3/m3.ino
new file mode 100644
index 0000000..235a49e
--- /dev/null
+++ b/sem4/embedded/m3/m3.ino
@@ -0,0 +1,191 @@
+
+
+void setup() {
+ Serial.begin(115200);
+
+ Serial.println("Starting the stuff");
+
+}
+
+#define ST_PRE 0
+#define ST_LEN 1
+#define ST_DAT 2
+#define ST_CHK_1 3
+#define ST_CHK_2 4
+
+#define P_START 0x02
+#define P_STOP 0x03
+#define P_ESCAPE 0x10
+
+#define ESCAPE(c) P_ESCAPE, (uint8_t)c - P_ESCAPE
+
+struct l2state{
+ // See ST_* defines
+ int state;
+ // Keeps track of data array.
+ size_t data_index;
+ // Whether to interpret next byte as raw.
+ bool doesc;
+ // Placeholder for check digits
+ uint8_t chk[2];
+ // Length of data read in layer 2 header
+ size_t len;
+};
+
+// Simple test function. Should be replaced with serial.read etc.
+uint8_t readnext() {
+ static size_t index = 0;
+ uint8_t msg[] = {0, 0, 12, 0x12, 123, 40, 120, 0x02, 13, 1, 2, 2, 0, 88, 50, 1, 90, 5, 0, 0, 88, 2, 74, 216, 0x03,
+ 0, 0, 0, 0x02, 25, 'A', 0x01, 0, 0, 0x88, ESCAPE(0x10), 3, 23, 0x44, 0, 0, 0xFF, 0xFF, 11, 0xAB, 0, 0, 0xFE, 0xFF, ESCAPE(0x03), 0x40, 0, 0, 0xFF, 0xFF, 50, 125, 0x03, 0, 0, 0, 0};
+
+ // If we reached the end, stop
+ if( index > sizeof(msg) / sizeof(uint8_t) ) {
+ for(;;);
+ }
+ return msg[index++ ];
+}
+
+// Updates checksum vars in s with input
+// The flecker algorithm overflows at 254 not 255
+void checksum(struct l2state *s, uint8_t input) {
+ s->chk[0] = (s->chk[0] + input) % 255;
+ s->chk[1] = (s->chk[1] + s->chk[0]) % 255;
+}
+
+void l2reset(struct l2state *s) {
+ s->state = ST_PRE;
+ memset(s->chk, 0, sizeof(s->chk));
+ s->data_index = 0;
+}
+
+// Decodes a single character, returning a value > 0 when finished.
+// Remember to zero out s
+size_t layer2decode(struct l2state *s, uint8_t *data, uint8_t input) {
+ /* Commented out because we never check for P_STOP
+ // Whether to take input as raw with no special meaning.
+ bool escaped = false;
+ */
+
+ // Handle escape
+ if( s->state && input == P_ESCAPE ) {
+ s->doesc = true;
+ return 0;
+ }
+ if( s->doesc ) {
+ input += P_ESCAPE;
+ s->doesc = false;
+ //escaped = true;
+ }
+
+ switch(s->state) {
+ case ST_PRE:
+ Serial.print("p");
+ // Wait for start.
+ // Escaped will not be checked because it will always be false here.
+ if(input == P_START) {
+ // We are go
+ s->state = ST_LEN;
+ }
+ break;
+ case ST_LEN:
+ Serial.print("l");
+ // Read a single len, and switch state
+ s->len = input;
+ s->state = ST_DAT;
+ break;
+ case ST_DAT:
+ Serial.print("d");
+ // Save input as data byte
+ data[s->data_index++] = input;
+
+ // Update checksum
+ checksum(s, input);
+
+ // Check if we are done
+ if(s->data_index >= s->len) {
+ s->state = ST_CHK_1;
+ }
+ break;
+ case ST_CHK_1:
+ Serial.print("c1");
+ // Check with the one calculated through ST_DAT
+ if( s->chk[0] != input ) {
+ Serial.print("Wrong chk1, expected: "); Serial.println(s->chk[0]);
+ l2reset(s);
+ break;
+ }
+
+ s->state = ST_CHK_2;
+ break;
+ case ST_CHK_2:
+ Serial.print("c2");
+ if( s->chk[1] != input ) {
+ Serial.print("Wrong chk2, expected: "); Serial.println(s->chk[1]);
+ l2reset(s);
+ // TODO should return error
+ break;
+ }
+
+ l2reset(s);
+ return s->len;
+ }
+
+ return 0;
+}
+
+struct l3master {
+ uint8_t rssi;
+ uint32_t txid : 24;
+ uint16_t txidtime;
+};
+
+struct l3pkg {
+ uint8_t type;
+ // Arduino is littleendian( LSByte first ).
+ uint32_t recvid : 24;
+ // Transducerlevel
+ uint8_t trslevel;
+ uint8_t quiettime;
+ uint8_t nummasters;
+ struct l3master masters[0];
+};
+
+void printl3pkg(struct l3pkg *l3) {
+ Serial.print("Type :"); Serial.println(l3->type);
+ Serial.print("Recvid :"); Serial.println(l3->recvid);
+ Serial.print("Transducerlevel :"); Serial.println(l3->trslevel);
+ Serial.print("Quiettime :"); Serial.println(l3->quiettime);
+ Serial.print("Masters :"); Serial.println(l3->nummasters);
+
+ // Loop the masters
+ for(int i = 0; i < l3->nummasters; i++) {
+ Serial.print("\nMASTER: "); Serial.println(i);
+ Serial.print(" rssi :"); Serial.println(l3->masters[i].rssi);
+ Serial.print(" txid :"); Serial.println(l3->masters[i].txid);
+ Serial.print(" ixidtime :"); Serial.println(l3->masters[i].txidtime);
+ }
+}
+
+void loop() {
+ struct l2state s;
+ // Zero it out
+ l2reset(&s);
+
+ uint8_t data[256];
+
+ while(1) {
+ uint8_t i = readnext();
+
+ if( layer2decode(&s, data, i) > 0) {
+ // Finished package decode
+ Serial.println("DONE");
+
+ // Cast to the pkg type
+ Serial.println("DONE");
+ struct l3pkg *l3 = (struct l3pkg *)data;
+ printl3pkg(l3);
+
+ }
+
+ }
+}