From 51372dc5ecceaa207bc147de0254f916b5fe286a Mon Sep 17 00:00:00 2001 From: Peter Wu Date: Wed, 10 Jun 2015 18:11:58 +0200 Subject: Add clean/check targets to Makefile, consider libs --- .gitignore | 4 ++++ Venus_Skeleton/Makefile | 31 ++++++++++++++++++++++++++++--- 2 files changed, 32 insertions(+), 3 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4fe7862 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +*.o +.*.sw? +__pycache__/ +*.py[oc] diff --git a/Venus_Skeleton/Makefile b/Venus_Skeleton/Makefile index 26b4ee2..d85d9a8 100644 --- a/Venus_Skeleton/Makefile +++ b/Venus_Skeleton/Makefile @@ -2,9 +2,34 @@ CC = avr-gcc WFLAGS = -Wall -Wextra -Wno-attributes WFLAGS += -fdiagnostics-color=auto -CFLAGS = +EXTRA_CFLAGS = $(shell cat .syntastic_c_config) -O2 $(CFLAGS) -SOURCES = Venus_Skeleton.ino +MY_SOURCES = Venus_Skeleton.ino +MY_OBJECTS = $(patsubst %.cpp,%.o,$(patsubst %.ino,%.o,$(MY_SOURCES))) +LIBS_SOURCES = $(wildcard libs/*/*.cpp) +LIBS_OBJECTS = $(patsubst %.cpp,%.o,$(LIBS_SOURCES)) +SOURCES = $(MY_SOURCES) $(LIBS_SOURCES) +OBJECTS = $(MY_OBJECTS) $(LIBS_OBJECTS) +PROGRAM ?= main +_V_0 = @ +_V = $(_V_$(V)) + +.PHONY: main clean check check: - $(CC) $(WFLAGS) $$(cat .syntastic_c_config) $(CFLAGS) -x c++ $(SOURCES) -o /dev/null -O2 + rm -f $(MY_OBJECTS) + $(MAKE) $(MY_OBJECTS) +# Note: does not compile due to link errors. +$(PROGRAM): $(OBJECTS) + $(_V)$(CC) $(WFLAGS) $(EXTRA_CFLAGS) $(OBJECTS) -o $@ + +clean: + $(_V)rm -f $(PROGRAM) $(OBJECTS) + +# Not my code... +libs/%.o: libs/%.cpp + $(_V)$(CC) -w $(EXTRA_CFLAGS) -c -o $@ $< +%.o: %.cpp + $(_V)$(CC) $(WFLAGS) $(EXTRA_CFLAGS) -c -o $@ $< +%.o: %.ino + $(_V)$(CC) $(WFLAGS) $(EXTRA_CFLAGS) -c -x c++ -o $@ $< -- cgit v1.2.1 From dad98df26e43dc08876270fa7cb575ed9bb36679 Mon Sep 17 00:00:00 2001 From: Peter Wu Date: Wed, 10 Jun 2015 18:14:46 +0200 Subject: Add comm.cpp to Makefile (rename from .c) --- Venus_Skeleton/Makefile | 2 +- Venus_Skeleton/comm.c | 90 ------------------------------------------------- Venus_Skeleton/comm.cpp | 90 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 91 insertions(+), 91 deletions(-) delete mode 100644 Venus_Skeleton/comm.c create mode 100644 Venus_Skeleton/comm.cpp diff --git a/Venus_Skeleton/Makefile b/Venus_Skeleton/Makefile index d85d9a8..c2c5198 100644 --- a/Venus_Skeleton/Makefile +++ b/Venus_Skeleton/Makefile @@ -4,7 +4,7 @@ WFLAGS = -Wall -Wextra -Wno-attributes WFLAGS += -fdiagnostics-color=auto EXTRA_CFLAGS = $(shell cat .syntastic_c_config) -O2 $(CFLAGS) -MY_SOURCES = Venus_Skeleton.ino +MY_SOURCES = Venus_Skeleton.ino comm.cpp MY_OBJECTS = $(patsubst %.cpp,%.o,$(patsubst %.ino,%.o,$(MY_SOURCES))) LIBS_SOURCES = $(wildcard libs/*/*.cpp) LIBS_OBJECTS = $(patsubst %.cpp,%.o,$(LIBS_SOURCES)) diff --git a/Venus_Skeleton/comm.c b/Venus_Skeleton/comm.c deleted file mode 100644 index f5392e0..0000000 --- a/Venus_Skeleton/comm.c +++ /dev/null @@ -1,90 +0,0 @@ -/** - * Serial communication module. - */ - -#include -#include "dataTypes.h" - -serial_state_t serial_state = SERIAL_UNKNOWN; - -static void handle_recv(int r); - -static void handle_ctrl(int r) { - // detect reset procedure - switch (r) { - case RESET1: - // reset request received, ack and wait for RESET2 - Serial.write(ACK1); - serial_state = SERIAL_INIT; - return; - case RESET2: - if (serial_state == SERIAL_INIT) { - // Handshake completed! - Serial.write(ACK2); - serial_state = SERIAL_READY; - } else { - // invalid state, reject it - Serial.write(OUTOFSYNC); - serial_state = SERIAL_UNKNOWN; - } - return; - case PONG: - // TODO mark as alive if PING was previously sent - return; - } - // TODO commands for navigation? Use DATA_LEN, etc? -} - -void handle_serial(data_t *data, int changedBits) { - // first attempt sync - while (Serial.available()) { - r = Serial.read(); - - if ((r & 0xC0) == 0x80) { - // handle control packets - handle_ctrl(r); - // TODO if DATA_ESCAPE or DATA_LEN1, react appropriately - } else if (serial_state == SERIAL_READY) { - // handle normal data only when the handshake has completed. - handle_recv(r); - } - } - - if (serial_state != SERIAL_READY) { - // Hardware is not ready, do not send data. - return; - } - - // then send queued data -} - -// writes data of length len -static void serial_write_data(const char *data, unsigned len) { - len--; // length on wire is one smaller (00 means 1 byte, 01 means 2, etc.) - if (len >= 0 && len < 56) { - Serial.write(0x80 + len + 7); - } else if (len >= 0 && len < 256) { - Serial.write(0x88 | (len >> 5)); - Serial.write(0xA0 | (len & 0x1F)); - } else { - // zero length or too long. - return; - } - // write remainder - for (unsigned i = 0; i < len; i++) { - char c = data[i]; - if (c & 0x80) { - Serial.write(DATA_ESCAPE); - Serial.write(c & ~0x80); - } else { - Serial.write(c); - } - } -} - -void serial_print_debug(const char *str) { - serial_print_debug(str, strlen(str)); -} - -static void handle_recv(int r) { -} diff --git a/Venus_Skeleton/comm.cpp b/Venus_Skeleton/comm.cpp new file mode 100644 index 0000000..f5392e0 --- /dev/null +++ b/Venus_Skeleton/comm.cpp @@ -0,0 +1,90 @@ +/** + * Serial communication module. + */ + +#include +#include "dataTypes.h" + +serial_state_t serial_state = SERIAL_UNKNOWN; + +static void handle_recv(int r); + +static void handle_ctrl(int r) { + // detect reset procedure + switch (r) { + case RESET1: + // reset request received, ack and wait for RESET2 + Serial.write(ACK1); + serial_state = SERIAL_INIT; + return; + case RESET2: + if (serial_state == SERIAL_INIT) { + // Handshake completed! + Serial.write(ACK2); + serial_state = SERIAL_READY; + } else { + // invalid state, reject it + Serial.write(OUTOFSYNC); + serial_state = SERIAL_UNKNOWN; + } + return; + case PONG: + // TODO mark as alive if PING was previously sent + return; + } + // TODO commands for navigation? Use DATA_LEN, etc? +} + +void handle_serial(data_t *data, int changedBits) { + // first attempt sync + while (Serial.available()) { + r = Serial.read(); + + if ((r & 0xC0) == 0x80) { + // handle control packets + handle_ctrl(r); + // TODO if DATA_ESCAPE or DATA_LEN1, react appropriately + } else if (serial_state == SERIAL_READY) { + // handle normal data only when the handshake has completed. + handle_recv(r); + } + } + + if (serial_state != SERIAL_READY) { + // Hardware is not ready, do not send data. + return; + } + + // then send queued data +} + +// writes data of length len +static void serial_write_data(const char *data, unsigned len) { + len--; // length on wire is one smaller (00 means 1 byte, 01 means 2, etc.) + if (len >= 0 && len < 56) { + Serial.write(0x80 + len + 7); + } else if (len >= 0 && len < 256) { + Serial.write(0x88 | (len >> 5)); + Serial.write(0xA0 | (len & 0x1F)); + } else { + // zero length or too long. + return; + } + // write remainder + for (unsigned i = 0; i < len; i++) { + char c = data[i]; + if (c & 0x80) { + Serial.write(DATA_ESCAPE); + Serial.write(c & ~0x80); + } else { + Serial.write(c); + } + } +} + +void serial_print_debug(const char *str) { + serial_print_debug(str, strlen(str)); +} + +static void handle_recv(int r) { +} -- cgit v1.2.1 From d110079f946fa1066d1d29187dcee3a4a99333f5 Mon Sep 17 00:00:00 2001 From: Peter Wu Date: Wed, 10 Jun 2015 18:22:50 +0200 Subject: Compile fixes for comm, fix debug write --- Venus_Skeleton/comm.cpp | 34 +++++++++++++++++++++++++++------- Venus_Skeleton/comm.h | 5 +++++ rpi2/app/comm_arduino.py | 11 ++++------- rpi2/design.txt | 2 +- 4 files changed, 37 insertions(+), 15 deletions(-) diff --git a/Venus_Skeleton/comm.cpp b/Venus_Skeleton/comm.cpp index f5392e0..d60138e 100644 --- a/Venus_Skeleton/comm.cpp +++ b/Venus_Skeleton/comm.cpp @@ -3,7 +3,9 @@ */ #include +#include "definitions.h" #include "dataTypes.h" +#include "comm.h" serial_state_t serial_state = SERIAL_UNKNOWN; @@ -38,7 +40,7 @@ static void handle_ctrl(int r) { void handle_serial(data_t *data, int changedBits) { // first attempt sync while (Serial.available()) { - r = Serial.read(); + int r = Serial.read(); if ((r & 0xC0) == 0x80) { // handle control packets @@ -59,18 +61,20 @@ void handle_serial(data_t *data, int changedBits) { } // writes data of length len -static void serial_write_data(const char *data, unsigned len) { +static void serial_write_len(unsigned len) { len--; // length on wire is one smaller (00 means 1 byte, 01 means 2, etc.) - if (len >= 0 && len < 56) { + if (len < 56) { Serial.write(0x80 + len + 7); - } else if (len >= 0 && len < 256) { + } else if (len < DATA_MAX_SIZE) { Serial.write(0x88 | (len >> 5)); Serial.write(0xA0 | (len & 0x1F)); } else { // zero length or too long. - return; } - // write remainder +} + +// write remainder of data +static void serial_write_data(const char *data, unsigned len) { for (unsigned i = 0; i < len; i++) { char c = data[i]; if (c & 0x80) { @@ -83,7 +87,23 @@ static void serial_write_data(const char *data, unsigned len) { } void serial_print_debug(const char *str) { - serial_print_debug(str, strlen(str)); + unsigned len = strlen(str); + const char c = DATA_DEBUG_PREFIX; + + // only write data when the serial connection is ready + if (serial_state != SERIAL_READY) { + return; + } + + while (len > 0) { + // len is no more than DATA_MAX_SIZE - 1 because of debug prefix + unsigned datalen = len >= DATA_MAX_SIZE ? DATA_MAX_SIZE - 1 : len; + // add one for the debug prefix + serial_write_len(1 + datalen); + serial_write_data(&c, 1); /* write prefix */ + serial_write_data(str, datalen); /* write actual data payload */ + len -= datalen; + } } static void handle_recv(int r) { diff --git a/Venus_Skeleton/comm.h b/Venus_Skeleton/comm.h index 5cdf77e..7f3b43c 100644 --- a/Venus_Skeleton/comm.h +++ b/Venus_Skeleton/comm.h @@ -9,6 +9,11 @@ typedef enum { DATA_ESCAPE = 0x84, } serial_control_command_t; +// prefix for Debug Data packets +#define DATA_DEBUG_PREFIX 0xC0 +// maximum size of a data packet +#define DATA_MAX_SIZE 256 + typedef enum { // waiting for RESET1 SERIAL_UNKNOWN, diff --git a/rpi2/app/comm_arduino.py b/rpi2/app/comm_arduino.py index 884c325..b34f1d1 100644 --- a/rpi2/app/comm_arduino.py +++ b/rpi2/app/comm_arduino.py @@ -25,10 +25,7 @@ class Ctrl(object): def is_control(b): return (b & 0xC0) == 0x80 -def get_data_length(b): - if (b & 0xC0) != 0x80: - return 0 - return (b & 0x3f) - 4 +DATA_DEBUG_PREFIX = b'\xC0' def configure_serial(path): # Disables parameters which are not controlled by pyserial @@ -63,8 +60,8 @@ class SerialState(object): while True: try: return self.ser.read() - except serial.SerialTimeoutException: - pass + except serial.SerialTimeoutException as e: + _logger.warn('Read timeout: %s', e) def handle_one(self, ser): b = self._read_one(ser) @@ -192,7 +189,7 @@ def handle_serial(path): while True: try: data = state.handle_one(ser) - if data and data[0] == b'\x80': # Debug packet + if data and data.startswith(DATA_DEBUG_PREFIX): handle_data_debug(data[1:]) elif data: _logger.info('PI DATA: %r', data) diff --git a/rpi2/design.txt b/rpi2/design.txt index 6957ad5..10c0c34 100644 --- a/rpi2/design.txt +++ b/rpi2/design.txt @@ -68,7 +68,7 @@ Data is interpreted as follows: 0... .... .... .... Bits that need to be updated (max 15). The length of the following data depends on this. -1000 0000 Debug packet, max len is determined by higher-level hdr. +1100 0000 Debug packet, max len is determined by higher-level hdr. Serial state machine: -- cgit v1.2.1