Remi Beges / DistantIO

Files at this revision

API Documentation at this revision

Comitter:
Overdrivr
Date:
Tue Sep 15 15:27:55 2015 +0000
Child:
1:aaffeb93f99b
Commit message:
Version not bug free (especially names should not be longer thant 8 characters or have spaces), but pretty reliable behavior. See github repo for tickets

Changed in this revision

crc.cpp Show annotated file Show diff for this revision Revisions of this file
crc.h Show annotated file Show diff for this revision Revisions of this file
distantio.cpp Show annotated file Show diff for this revision Revisions of this file
distantio.h Show annotated file Show diff for this revision Revisions of this file
protocol.cpp Show annotated file Show diff for this revision Revisions of this file
protocol.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/crc.cpp	Tue Sep 15 15:27:55 2015 +0000
@@ -0,0 +1,130 @@
+// From : http://stackoverflow.com/questions/15169387/definitive-crc-for-c
+/* 8-bit CRC with polynomial x^8+x^6+x^3+x^2+1, 0x14D.
+   Chosen based on Koopman, et al. (0xA6 in his notation = 0x14D >> 1):
+   http://www.ece.cmu.edu/~koopman/roses/dsn04/koopman04_crc_poly_embedded.pdf
+ */
+
+#include "crc.h"
+/*
+static const unsigned char crc8_table[] = {
+    0x00, 0x3e, 0x7c, 0x42, 0xf8, 0xc6, 0x84, 0xba, 0x95, 0xab, 0xe9, 0xd7,
+    0x6d, 0x53, 0x11, 0x2f, 0x4f, 0x71, 0x33, 0x0d, 0xb7, 0x89, 0xcb, 0xf5,
+    0xda, 0xe4, 0xa6, 0x98, 0x22, 0x1c, 0x5e, 0x60, 0x9e, 0xa0, 0xe2, 0xdc,
+    0x66, 0x58, 0x1a, 0x24, 0x0b, 0x35, 0x77, 0x49, 0xf3, 0xcd, 0x8f, 0xb1,
+    0xd1, 0xef, 0xad, 0x93, 0x29, 0x17, 0x55, 0x6b, 0x44, 0x7a, 0x38, 0x06,
+    0xbc, 0x82, 0xc0, 0xfe, 0x59, 0x67, 0x25, 0x1b, 0xa1, 0x9f, 0xdd, 0xe3,
+    0xcc, 0xf2, 0xb0, 0x8e, 0x34, 0x0a, 0x48, 0x76, 0x16, 0x28, 0x6a, 0x54,
+    0xee, 0xd0, 0x92, 0xac, 0x83, 0xbd, 0xff, 0xc1, 0x7b, 0x45, 0x07, 0x39,
+    0xc7, 0xf9, 0xbb, 0x85, 0x3f, 0x01, 0x43, 0x7d, 0x52, 0x6c, 0x2e, 0x10,
+    0xaa, 0x94, 0xd6, 0xe8, 0x88, 0xb6, 0xf4, 0xca, 0x70, 0x4e, 0x0c, 0x32,
+    0x1d, 0x23, 0x61, 0x5f, 0xe5, 0xdb, 0x99, 0xa7, 0xb2, 0x8c, 0xce, 0xf0,
+    0x4a, 0x74, 0x36, 0x08, 0x27, 0x19, 0x5b, 0x65, 0xdf, 0xe1, 0xa3, 0x9d,
+    0xfd, 0xc3, 0x81, 0xbf, 0x05, 0x3b, 0x79, 0x47, 0x68, 0x56, 0x14, 0x2a,
+    0x90, 0xae, 0xec, 0xd2, 0x2c, 0x12, 0x50, 0x6e, 0xd4, 0xea, 0xa8, 0x96,
+    0xb9, 0x87, 0xc5, 0xfb, 0x41, 0x7f, 0x3d, 0x03, 0x63, 0x5d, 0x1f, 0x21,
+    0x9b, 0xa5, 0xe7, 0xd9, 0xf6, 0xc8, 0x8a, 0xb4, 0x0e, 0x30, 0x72, 0x4c,
+    0xeb, 0xd5, 0x97, 0xa9, 0x13, 0x2d, 0x6f, 0x51, 0x7e, 0x40, 0x02, 0x3c,
+    0x86, 0xb8, 0xfa, 0xc4, 0xa4, 0x9a, 0xd8, 0xe6, 0x5c, 0x62, 0x20, 0x1e,
+    0x31, 0x0f, 0x4d, 0x73, 0xc9, 0xf7, 0xb5, 0x8b, 0x75, 0x4b, 0x09, 0x37,
+    0x8d, 0xb3, 0xf1, 0xcf, 0xe0, 0xde, 0x9c, 0xa2, 0x18, 0x26, 0x64, 0x5a,
+    0x3a, 0x04, 0x46, 0x78, 0xc2, 0xfc, 0xbe, 0x80, 0xaf, 0x91, 0xd3, 0xed,
+    0x57, 0x69, 0x2b, 0x15};
+
+unsigned crc8(unsigned char *data, uint16_t len)
+{
+	static unsigned char crc;
+    unsigned char *end;
+
+    if (len == 0)
+        return crc;
+
+    crc ^= 0xff;
+    end = data + len;
+    do {
+        crc = crc8_table[crc ^ *data++];
+    } while (data < end);
+    return crc ^ 0xff;
+	return 0;
+}*/
+
+/* this was used to generate the table and to test the table-version
+
+#define POLY 0xB2
+
+unsigned crc8_slow(unsigned crc, unsigned char *data, size_t len)
+{
+    unsigned char *end;
+
+    if (len == 0)
+        return crc;
+    crc ^= 0xff;
+    end = data + len;
+    do {
+        crc ^= *data++;
+        crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
+        crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
+        crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
+        crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
+        crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
+        crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
+        crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
+        crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
+    } while (data < end);
+    return crc ^ 0xff;
+}
+*/
+/*
+# From : https://en.wikipedia.org/wiki/Computation_of_cyclic_redundancy_checks
+
+# Most significant bit first (big-endian)
+# x^16+x^12+x^5+1 = (1) 0001 0000 0010 0001 = 0x1021
+
+def crc16(data):
+    rem  = 0
+    n = 16
+    # A popular variant complements rem here
+    for d in data:
+        rem  = rem ^ (d << (n-8))   # n = 16 in this example
+        for j in range(1,8):
+            # Assuming 8 bits per byte
+            if rem & 0x8000:
+            # if leftmost (most significant) bit is set
+                rem  = (rem << 1) ^ 0x1021
+            else:
+                rem  = rem << 1
+        rem  = rem & 0xffff      # Trim remainder to 16 bits
+    # A popular variant complements rem here
+    return rem
+*/
+// Most significant bit first (big-endian)
+// x^16+x^12+x^5+1 = (1) 0001 0000 0010 0001 = 0x1021
+
+uint16_t crc16(uint8_t* data, uint16_t len)
+{
+	uint16_t rem  = 0;
+	uint16_t n = 16;
+	// A popular variant complements rem here
+	for(uint16_t i = 0 ; i < len ; i++)
+	{
+		rem  = rem ^ (data[i] << (n-8));   // n = 16 in this example
+
+		for(uint16_t j = 1 ; j < 8 ; j++)  // Assuming 8 bits per byte
+		{
+
+			if(rem & 0x8000)
+			{
+				// if leftmost (most significant) bit is set
+				rem  = (rem << 1) ^ 0x1021;
+			}
+			else
+			{
+				rem  = rem << 1;
+			}
+		 rem  &= 0xffff;      // Trim remainder to 16 bits
+		}
+	}
+ // A popular variant complements rem here
+  return rem;
+ }
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/crc.h	Tue Sep 15 15:27:55 2015 +0000
@@ -0,0 +1,10 @@
+#ifndef CRC_H_
+#define CRC_H_
+
+#include <stdint.h>
+
+//unsigned crc8(unsigned char *data, uint16_t len);
+uint16_t crc16(uint8_t *data, uint16_t len);
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/distantio.cpp	Tue Sep 15 15:27:55 2015 +0000
@@ -0,0 +1,358 @@
+/*
+ * distantio.c
+ *
+ *  Created on: Oct 13, 2014
+ *      Author: B48923
+ */
+
+#include "distantio.h"
+#include "crc.h"
+#include "string.h"
+#include "protocol.h"
+
+/*
+ * WARNING : IMPLEMENTATION FOR LITTLE-ENDIAN PROCESSOR
+ * TODO : HANDLE BOTH
+ */
+
+static log Log;
+uint32_t tmp;
+
+void send_variable(uint16_t index);
+uint16_t get_size(dio_type type);
+void send_descriptor(uint16_t index);
+void send_group_descriptor(uint16_t index);
+
+/**
+ * Inits the distant io framework
+ */
+void init_distantio()
+{
+	uint16_t i;
+	char default_name[] = {"undef.  "};
+	Log.amount = 0;
+	for(i = 0 ; i < VARIABLES_AMOUNT ; i++)
+	{
+		Log.variables[i].size = 0;
+		Log.variables[i].ptr = 0;
+		Log.variables[i].writeable = 0;
+		Log.variables[i].id = i;
+		strcpy(Log.variables[i].name,default_name);
+		Log.variables[i].send = 0;
+		Log.variables[i].groupID = 0;
+	}
+	tmp=0;
+	Log.current_group_id = 0;
+	strcpy(Log.groups[0].name,"default");
+}
+
+/**
+ * Register a variable exchanged with the computer
+ */
+uint8_t register_var(void* ptr, uint16_t size, dio_type type, uint8_t writeable, char* name)
+{
+	// Too many variables, aborting
+	if(Log.amount >= VARIABLES_AMOUNT)
+		return 1;
+
+	Log.variables[Log.amount].ptr = (uint8_t*) ptr;
+	Log.variables[Log.amount].size = get_size(type);
+	Log.variables[Log.amount].writeable = writeable;
+	Log.variables[Log.amount].type = type;
+	Log.variables[Log.amount].groupID = Log.current_group_id;
+	strcpy(Log.variables[Log.amount].name,name);
+
+	Log.amount++;
+
+	return 0;
+}
+
+void start_group(char* groupname)
+{
+	Log.current_group_id++;
+	strcpy(Log.groups[Log.current_group_id].name,groupname);
+}
+
+/**
+ * Send var descriptor
+ */
+
+void send_descriptor(uint16_t index)
+{
+	if(index >= Log.amount)
+		return;
+
+	static uint8_t buffer[PAYLOAD_SIZE];
+	uint8_t type;
+
+	// Respond returned-descriptor
+	buffer[0] = 0x00;
+
+	// Write id
+	uint16_t ID = ((Log.variables[index].groupID & 0x003F) << 10) + (index & 0x3FF);
+	uint8_t * temp_ptr = (uint8_t*)(&ID);
+	buffer[1] = *(temp_ptr + 1);
+	buffer[2] = *(temp_ptr    );
+
+	// Write type & writeable
+
+	type = (uint8_t)(Log.variables[index].type);
+
+	if(Log.variables[index].writeable)
+		type += 0xF0;
+
+	buffer[3] = type;
+
+	//Write name
+	uint16_t i = 4;
+	for(uint16_t k = 0 ; k < 8 ; k++)
+	{
+		if(k < strlen(Log.variables[index].name))
+		{
+			buffer[i] = Log.variables[index].name[k];
+			i++;
+		}
+		else
+			buffer[i++] = 0;
+	}
+
+	// Compute crc
+	uint16_t crc_value = crc16(buffer,i);
+
+	// Write crc into buffer's last byte
+	buffer[i++] = (crc_value >> 8) & 0xFF;
+	buffer[i++] = crc_value & 0xFF;
+
+	// Encode frame
+	encode(buffer,i);
+}
+
+void send_group_descriptor(uint16_t index)
+{
+	if(index > Log.current_group_id)
+		return;
+
+	static uint8_t buffer[PAYLOAD_SIZE];
+
+	// Respond returned-descriptor
+	buffer[0] = 0x00;
+
+	// Write id
+	uint16_t ID = (index & 0x3F) << 10;
+	uint8_t * temp_ptr = (uint8_t*)(&ID);
+	buffer[1] = *(temp_ptr + 1);
+	buffer[2] = *(temp_ptr);
+
+	// Write type
+	buffer[3] = 0x07;
+
+	//Write name
+	uint16_t i = 4;
+	for(uint16_t k = 0 ; k < 8 ; k++)
+	{
+		if(k < strlen(Log.groups[index].name))
+		{
+			buffer[i] = Log.groups[index].name[k];
+			i++;
+		}
+		else
+			buffer[i++] = 0;
+	}
+
+	// Compute crc
+	uint16_t crc_value = crc16(buffer,i);
+
+	// Write crc into buffer's last byte
+	buffer[i++] = (crc_value >> 8) & 0xFF;
+	buffer[i++] = crc_value & 0xFF;
+
+	// Encode frame
+	encode(buffer,i);
+}
+
+void distantio_decode(uint8_t* data,uint16_t datasize)
+{
+	// First check data size
+	// 1 byte cmd + 2 bytes id + 1 byte type + FRAME_SIZE + 2 byte CRC
+	if(datasize != PAYLOAD_SIZE)
+		return;
+
+	// Second, check CRC
+	uint16_t crc_value = crc16(data,PAYLOAD_SIZE-2);
+	uint16_t crc_rx = ((uint16_t)data[PAYLOAD_SIZE-2] << 8) | data[PAYLOAD_SIZE-1];
+
+	if(crc_value != crc_rx)
+		return;
+	
+	// Process frame
+	// First, identify command
+	uint8_t command = data[0];
+	
+	// Second, identify variable ID
+	uint16_t ID = data[2] + (data[1] << 8);
+	ID = (ID & 0x3FF);
+	
+	// Third, identify data type
+	uint8_t type = data[3];
+
+	switch(command)
+	{
+		// User requested descriptors
+		case 0x02:
+			// Send variables
+			for(uint16_t i = 0 ; i < Log.amount ; i++)
+				send_descriptor(i);
+			// Send groups
+			for(uint16_t i = 0 ; i <= Log.current_group_id ; i++)
+				send_group_descriptor(i);
+			break;
+
+		// User provided value to write
+		case 0x04:
+			if(ID >= Log.amount)
+				return;
+
+			if(Log.variables[ID].writeable == 0x00)
+				return;
+
+			if(Log.variables[ID].type != type)
+				return;
+
+			uint16_t start_address = 4 + DATA_SIZE - 1;
+
+			// Copy contents directly into variable
+			for(uint16_t i = 0 ; i < Log.variables[ID].size ; i++)
+			{
+				// Packet is big-endian, convert to little-endian
+				uint8_t offset = start_address - i;
+				*(Log.variables[ID].ptr + i) = *(data + offset);
+			}
+			break;
+
+		// User requested variable read
+		case 0x05:
+			if(ID >= Log.amount)
+				return;
+
+			Log.variables[ID].send = 1;
+			break;
+
+		// User requested stop variable read
+		case 0x06:
+			if(ID >= Log.amount)
+				return;
+			Log.variables[ID].send = 0;
+			break;
+		
+	}
+}
+
+void send_variables()
+{
+	for(uint16_t i = 0 ; i < Log.amount ; i++)
+	{
+		if(Log.variables[i].send == 0)
+			continue;
+
+		send_variable(i);
+	}
+}
+
+void send_variable(uint16_t index)
+{
+	if(index >= Log.amount)
+		return;
+
+	static uint8_t buffer[PAYLOAD_SIZE];
+
+	// Response code 0x01
+	buffer[0] = 0x01;
+	
+	// Write variable ID
+	uint16_t ID = ((Log.variables[index].groupID & 0x003F) << 10) + (index & 0x3FF);
+	uint8_t * temp_ptr = (uint8_t*)(&ID);
+	buffer[1] = *(temp_ptr + 1);
+	buffer[2] = *(temp_ptr);
+	
+	// Write variable type
+	buffer[3] = Log.variables[index].type;
+	//TODO writeable
+
+	uint16_t i = 4;
+
+	// Write data
+	for(uint16_t k = 0 ; k < DATA_SIZE ; k++)
+	{
+		uint16_t off = DATA_SIZE - 1 - k;
+
+		// Fill buffer with data
+		if(off < Log.variables[index].size)
+		{
+			temp_ptr = Log.variables[index].ptr + off ;
+			buffer[i++] = *temp_ptr;
+		}
+		// Fill remaining bits with 0
+		else
+		{
+			buffer[i++] = 0;
+		}
+	}
+	
+	// Compute crc
+	uint16_t crc_value = crc16(buffer,i);
+
+	// Write crc into buffer's last byte
+	buffer[i++] = (crc_value >> 8) & 0xFF;
+	buffer[i++] = crc_value & 0xFF;
+
+	// Encode frame
+	encode(buffer,i);
+}
+
+void send_alive()
+{
+	static uint8_t buffer[PAYLOAD_SIZE] = {0x03,0x00,0x10,0x00,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x00,0x00};
+	
+	uint16_t index = 1;
+	uint16_t group = 0;
+	uint16_t ID = ((group & 0x003F) << 10) + (index & 0x3FF);
+	uint8_t * temp_ptr = (uint8_t*)(&ID);
+	buffer[1] = *(temp_ptr + 1);
+	buffer[2] = *(temp_ptr    );
+
+	// Compute crc
+	uint16_t crc_value = crc16(buffer,PAYLOAD_SIZE - 2);
+
+	// Write crc into buffer's last byte
+	buffer[PAYLOAD_SIZE - 1] = crc_value & 0xFF;
+	buffer[PAYLOAD_SIZE - 2] = (crc_value >> 8) & 0xFF;
+
+	// Send frame to encoding
+	encode(buffer,PAYLOAD_SIZE);
+}
+
+
+/**
+ * Returns the size in byte for each variable
+ */
+
+uint16_t get_size(dio_type type)
+{
+	switch(type)
+	{
+		case dio_type_FLOAT:
+		case dio_type_UINT32:
+		case dio_type_INT32:
+			return 4;
+
+		case dio_type_UINT16:
+		case dio_type_INT16:
+			return 2;
+
+		case dio_type_UINT8:
+		case dio_type_INT8:
+		default:
+			return 1;
+	}
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/distantio.h	Tue Sep 15 15:27:55 2015 +0000
@@ -0,0 +1,71 @@
+/*
+ * distantio.h
+ *
+ *  Created on: Oct 13, 2014
+ *      Author: B48923
+ */
+
+#ifndef DISTANTIO_H_
+#define DISTANTIO_H_
+
+#include <stdint.h>
+
+#define PAYLOAD_SIZE 14
+#define DATA_SIZE 8
+#define VARIABLES_AMOUNT 256
+#define GROUPS_AMOUNT 128
+
+typedef enum dio_type dio_type;
+enum dio_type
+{
+	dio_type_FLOAT = 0x00,
+	dio_type_UINT8 = 0x01,
+	dio_type_UINT16 = 0x02,
+	dio_type_UINT32 = 0x03,
+	dio_type_INT8 = 0x04,
+	dio_type_INT16 = 0x05,
+	dio_type_INT32 = 0x06,
+};
+
+typedef struct variable variable;
+struct variable
+{
+	uint8_t* ptr;
+	uint16_t size;
+	uint8_t writeable;
+	uint16_t id;
+	dio_type type;
+	char name[8];
+	uint8_t send;
+	uint8_t groupID;
+};
+
+typedef struct group group;
+struct group
+{
+	char name[8];
+	uint8_t groupID;
+};
+
+//typedef struct log log;
+struct log
+{
+	variable variables[VARIABLES_AMOUNT];
+	group groups[GROUPS_AMOUNT];
+	uint16_t amount;
+	uint8_t current_group_id;
+};
+
+void init_distantio();
+
+uint8_t register_var(void* ptr, uint16_t size, dio_type type, uint8_t writeable, char* name);
+void start_group(char* groupname);
+
+void distantio_decode(uint8_t* data,uint16_t datasize);
+
+// To call often
+void send_variables();
+void send_alive();
+
+#endif /* DISTANTIO_H_ */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/protocol.cpp	Tue Sep 15 15:27:55 2015 +0000
@@ -0,0 +1,155 @@
+/*
+ * serial_protocol.c
+ *
+ *  Created on: Oct 22, 2014
+ *      Author: B48923
+ */
+
+#include "protocol.h"
+
+enum state
+{
+	IDLE,
+	IN_PROCESS
+};
+typedef enum state state;
+
+
+enum ESC_state
+{
+	NONE,
+	NEXT
+};
+typedef enum ESC_state ESC_state;
+
+uint16_t decodingIndex;
+state protocol_state;
+ESC_state escape_state;
+
+uint8_t SOF_;
+uint8_t EOF_;
+uint8_t ESC_;
+
+static void (*on_encoding_done)(uint8_t* data, uint16_t size);
+static void (*on_decoding_done)(uint8_t* data, uint16_t size);
+
+
+void init_protocol(void (*encoding_done_callback)(uint8_t*,uint16_t),void (*decoding_done_callback)(uint8_t*,uint16_t))
+{
+	protocol_state = IDLE;
+	escape_state = NONE;
+	
+	SOF_ = 0xF7;
+	EOF_ = 0x7F;
+	ESC_ = 0x7D;
+
+	decodingIndex = 0;
+	
+	on_encoding_done = encoding_done_callback;
+	on_decoding_done = decoding_done_callback;
+}
+
+void encode(uint8_t* framedata, uint16_t framesize)
+{
+	// If frame size is superior than maximum allowed, abort
+	if(framesize > ENCODING_BUFFER_SIZE)
+		return;
+
+	// Actual buffer size is twice the data size (for worst case byte stuffing) + SOF + EOF
+	static uint8_t encodingBuffer[ENCODING_BUFFER_SIZE * 2 + 2];
+
+	uint16_t index = 0, i = 0;
+	
+	//Write start of frame / end of frame byte
+	encodingBuffer[index++] = SOF_;
+	
+	//Write data
+	for(i = 0 ; i < framesize ; i++)
+	{
+		//See serial_protocols_definition.xlsx
+		if(*(framedata + i) == SOF_ ||
+		   *(framedata + i) == EOF_ ||
+		   *(framedata + i) == ESC_)
+		{
+			//If data contains one of the flags, we escape it before
+			encodingBuffer[index++] = ESC_;
+		}
+		encodingBuffer[index++] = framedata[i];
+	}
+	
+	encodingBuffer[index++] = EOF_;
+
+	// Operation is done, call function callback
+	on_encoding_done(encodingBuffer,index);
+}
+
+void decode(uint8_t received_byte)
+{
+	static uint8_t decodingBuffer[DECODING_BUFFER_SIZE];
+
+	// If a reception was in process
+	if(protocol_state == IN_PROCESS)
+	{
+		// If the character was previously marked as pure data
+		if(escape_state == NEXT)
+		{
+			// If max buffer size was reached, cancel reception to avoid overflowing buffer
+			if(decodingIndex + 1 >= DECODING_BUFFER_SIZE)
+			{
+				decodingIndex = 0;
+				protocol_state = IDLE;
+				escape_state = NONE;
+			}
+			else
+			{
+				decodingBuffer[decodingIndex++] = received_byte;
+				escape_state = NONE;
+			}
+		}
+		else
+		{
+			// End of frame
+			if(received_byte == EOF_)
+			{
+				protocol_state = IDLE;
+				// Call the function callback for end of frame
+				on_decoding_done(decodingBuffer,decodingIndex);
+			}
+			else if(received_byte == ESC_)
+			{
+				escape_state = NEXT;
+			}
+			else
+			{
+				// If max buffer size was reached, cancel reception to avoid overflowing buffer
+				if(decodingIndex + 1 >= DECODING_BUFFER_SIZE)
+				{
+					decodingIndex = 0;
+					protocol_state = IDLE;
+					escape_state = NONE;
+				}
+				else
+				{
+					decodingBuffer[decodingIndex++] = received_byte;
+					escape_state = NONE;
+				}
+			}
+		}
+	}
+	else
+	{
+		if(received_byte == SOF_)
+		{
+			protocol_state = IN_PROCESS;
+			decodingIndex = 0;
+			escape_state = NONE;
+		}
+		else
+		{
+			//Received character outside a valid frame, ignore it
+		}
+	}
+}
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/protocol.h	Tue Sep 15 15:27:55 2015 +0000
@@ -0,0 +1,34 @@
+/*
+ * serial_protocol.h
+ *
+ *  Created on: Oct 22, 2014
+ *      Author: B48923
+ */
+
+#ifndef SERIAL_PROTOCOL_H_
+#define SERIAL_PROTOCOL_H_
+
+#include <stdint.h>
+
+#define ENCODING_BUFFER_SIZE 64
+#define DECODING_BUFFER_SIZE 256
+
+typedef void (*callback_t)(uint8_t* data, uint16_t size);
+
+void init_protocol(void (*encoding_done_callback)(uint8_t*,uint16_t),void (*decoding_done_callback)(uint8_t*,uint16_t));
+/*
+ * Encodes new data with byte stuffing algorithm to delimit frame.
+ * @input framedata : the raw data to process
+ * @input framesize : size of the raw data to process (amount of bytes)
+ */
+void encode(uint8_t* framedata, uint16_t framesize);
+
+/*
+ * Append new byte to current decoding sequence. If a valid frame is detected,
+ * the decoding_done_callback function is called and the valid frame is sent as parameter
+ * @input received_byte : the new byte to add to the current decoding sequence
+ */
+void decode(uint8_t received_byte);
+
+#endif /* SERIAL_PROTOCOL_H_ */
+