diff --git a/common/transport/transport.c b/common/transport/transport.c
index e9b5538f5e1c0c8f90d52b50878ab62993e207a9..ff5d62c2f773924e0b1930927e4279821aabdb81 100644
--- a/common/transport/transport.c
+++ b/common/transport/transport.c
@@ -2,7 +2,7 @@
 
 #define USART_NAME USART
 #undef USART_USE_AS_STDOUT
-#define BAUD 2400
+#define BAUD 9600
 // #define USART_USE_AS_STDOUT //Debugging only!
 void USART_recv_interrupt(void);
 #define USART_NUMBER TRANSPORT_USART_NUMBER
@@ -26,18 +26,82 @@ void USART_recv_interrupt(void);
 
 interrupt_msg_handler_t interrupt_msg_table[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
 
-volatile uint8_t msg_start_received = 0;
-
-uint16_t transport_receive_char(uint16_t timeout);
+#define RECV_IDLE           0x00
+#define RECV_START          0x01
+#define RECV_BODY           0x02
+#define RECV_CHECKSUM       0x03
+#define RECV_FINISHED       0x04
+#define RECV_ERROR          0x0A
+#define RECV_ESCAPE_FLAG    0x40
+#define RECV_INTERRUPT_FLAG 0x80
+#define RECV_SET_STATE(s) {msg_recv_state = (msg_recv_state & (RECV_ESCAPE_FLAG | RECV_INTERRUPT_FLAG)) | s;}
+#define RECV_STATE() (msg_recv_state & ~(RECV_ESCAPE_FLAG | RECV_INTERRUPT_FLAG))
+volatile uint8_t  msg_recv_state = RECV_IDLE;
+volatile uint8_t  msg_recv_pos = 0;
+volatile uint8_t  msg_recv_body_length = 0;
+volatile uint16_t msg_recv_checksum = 0;
+#define RECV_MAX_LENGTH 255
+volatile uint8_t msg_recv_buffer[RECV_MAX_LENGTH];
+
+uint8_t transport_unescape(uint8_t c);
 
 void USART_recv_interrupt(void){
-	uint16_t ret = transport_receive_char(400);
-// 	printf("RXI %04x\n", ret);
-// 	lcd_write_char('R');
-	if (ret == RET_MSG_START){
-		msg_start_received = 1;
-// 		printf("Start\n");
-		USART_disable_rx_interrupt();
+	uint8_t c = USART_read_char();
+	if (msg_recv_state & RECV_INTERRUPT_FLAG){
+		if (c != INTERRUPT_NONE && interrupt_msg_table[INTERRUPT_NUM(c)]){
+			interrupt_msg_table[INTERRUPT_NUM(c)]();
+		}
+		msg_recv_state &= ~RECV_INTERRUPT_FLAG;
+	} else if (c == SC_ESCAPE){
+		msg_recv_state |= RECV_ESCAPE_FLAG;
+	} else if (c == SC_INTERRUPT){
+		msg_recv_state |= RECV_INTERRUPT_FLAG;
+	} else if (c == SC_MSG_START){
+		RECV_SET_STATE(RECV_START);
+		msg_recv_pos = 0;
+	} else if (c == SC_MSG_END){
+		msg_recv_body_length = msg_recv_pos;
+		RECV_SET_STATE(RECV_CHECKSUM);
+		msg_recv_pos = 0;
+	} else {
+		
+		if (msg_recv_state & RECV_ESCAPE_FLAG){
+			c = transport_unescape(c);
+			msg_recv_state &= ~RECV_ESCAPE_FLAG;
+		}
+		
+		if (RECV_STATE() == RECV_START){
+			msg_recv_pos = 0;
+			RECV_SET_STATE(RECV_BODY);
+		}
+		
+		if (RECV_STATE() == RECV_BODY){
+			if (msg_recv_pos < RECV_MAX_LENGTH){
+				msg_recv_buffer[msg_recv_pos] = c;
+				msg_recv_pos++;
+			}
+		} else if (RECV_STATE() == RECV_CHECKSUM){
+			if (msg_recv_pos == 0) msg_recv_checksum = c;
+			if (msg_recv_pos == 1) {
+				msg_recv_checksum |= c << 8;
+				RECV_SET_STATE(RECV_FINISHED);
+			}
+			msg_recv_pos++;
+		}
+	}
+}
+
+uint8_t transport_unescape(uint8_t c){
+	if (c == EC_2B){
+		return 0x2B;
+	} else if (c == EC_D4){
+		return 0xD4;
+	} else if (c == EC_5C){
+		return 0x5C;
+	} else if (c == EC_AA){
+		return 0xAA;
+	} else {
+		return c;
 	}
 }
 
@@ -89,12 +153,15 @@ void transport_send_message(uint8_t* body, uint8_t length){
 	
 	for (uint8_t i = 0; i < length; i++){
 		transport_send_char(body[i]);
+// 		printf(">%02x>", body[i]);
 		checksum = _crc16_update(checksum, body[i]);
 	}
 	USART_transmit_char(SC_MSG_END);
 	
 	transport_send_char(checksum & 0xFF);
 	transport_send_char(checksum >> 8);
+	
+	USART_flush();
 }
 
 void transport_send_interrupt_message(uint8_t interrupt){
@@ -107,177 +174,31 @@ void transport_send_interrupt_message(uint8_t interrupt){
 }
 
 uint8_t transport_data_available(void){
-	return msg_start_received;
-}
-
-uint16_t transport_handle_interrupt_msg(uint16_t timeout){
-	uint8_t num_interrupts = 1;
-	uint16_t ret = SC_INTERRUPT;
-	
-// 	while (ret == SC_INTERRUPT){
-// 		ret = USART_read_char_timeout(timeout);
-// 		if (ret == ERR_TIMEOUT) return ERR_TIMEOUT;
-// 		if (ret == SC_INTERRUPT){
-// 			if (num_interrupts < 255){
-// 				num_interrupts++;
-// 			} else { //more than 255 nested interrupt msgs?! somebody is fucking with us.
-// 				return TRANSPORT_ERR_NESTED_INTERRUPTS;
-// 			}
-// 		}
-// 	}
-// 	
-// 	printf("Int");
-	for (uint8_t i = 0; i < num_interrupts; i++){
-		ret = USART_read_char_timeout(timeout);
-		if (ret == ERR_TIMEOUT) return ERR_TIMEOUT;
-		
-		if (ret != INTERRUPT_NONE && interrupt_msg_table[INTERRUPT_NUM(ret)]){
-			interrupt_msg_table[INTERRUPT_NUM(ret)]();
-		}
-	}
-	return 0;
+	return msg_recv_state == RECV_FINISHED;
 }
 
-uint16_t transport_receive_char(uint16_t timeout){
-	uint16_t ret;
-	uint8_t  c;
+uint16_t transport_receive_message(uint8_t* buffer, uint8_t length, uint16_t timeout){
 	
-	while (1){
-		ret = USART_read_char_timeout(timeout);
-		if (ret == ERR_TIMEOUT) return TRANSPORT_ERR_TIMEOUT;
-		c = ret & 0xFF;
-		
-		if (c == SC_ESCAPE){
-			
-			while(1){
-				ret = USART_read_char_timeout(timeout);
-				if (ret == ERR_TIMEOUT) return TRANSPORT_ERR_TIMEOUT;
-				c = ret & 0xFF;
-				
-				if (c == SC_INTERRUPT) {
-					ret = transport_handle_interrupt_msg(timeout);
-					if (ret == ERR_TIMEOUT) return TRANSPORT_ERR_TIMEOUT;
-					if (ret == TRANSPORT_ERR_NESTED_INTERRUPTS) return TRANSPORT_ERR_NESTED_INTERRUPTS;					
-					//loop again, to read the next char (the one that was about to be escaped, when this interrupt came in)
-				} else {
-					break;
-				}
-			}
-			
-			if (c == EC_2B){
-				return 0x2B;
-			} else if (c == EC_D4){
-				return 0xD4;
-			} else if (c == EC_5C){
-				return 0x5C;
-			} else if (c == EC_AA){
-				return 0xAA;
-			} else {
-				//keep unknown escape char unchanged //TODO: Handle this properly? Error?
-				return c;
-			}
-		} else if (c == SC_MSG_END){
-			return RET_MSG_END;
-		} else if (c == SC_MSG_START){
-			return RET_MSG_START;
-		} else if (c == SC_INTERRUPT){
-			ret = transport_handle_interrupt_msg(timeout);
-			if (ret == ERR_TIMEOUT) return TRANSPORT_ERR_TIMEOUT;
-			if (ret == TRANSPORT_ERR_NESTED_INTERRUPTS) return TRANSPORT_ERR_NESTED_INTERRUPTS;					
-			//we have nothing to return, so loop again to read the next char.
-			
-		} else { //literal char
-			return c;
-		}
+	while (RECV_STATE() != RECV_FINISHED && timeout > 0){
+		timeout--;
+		_delay_us(100);
 	}
-}
-
-
-uint16_t _transport_receive_message(uint8_t* buffer, uint8_t length, uint16_t timeout){
-	uint16_t ret = 0;
-	uint8_t c = 0;
-	uint8_t recv_length = 0;
-	uint16_t real_checksum = 0xFFFF;
-	uint16_t expected_checksum;
-	uint8_t has_body = 1;
 	
-	//Wait for message start char (if the interrupt didn't pick it up for us already)
-	if (!msg_start_received){
-		while (1){
-			ret = transport_receive_char(timeout);
-			if (ret == TRANSPORT_ERR_TIMEOUT) return TRANSPORT_ERR_TIMEOUT;
-			if (ret == RET_MSG_START) break;
-		}
+	if (RECV_STATE() != RECV_FINISHED){
+		return TRANSPORT_ERR_TIMEOUT;
+	} else if (msg_recv_body_length > length) {
+		RECV_SET_STATE(RECV_IDLE);
+		return TRANSPORT_ERR_MESSAGE_TOO_LONG;
 	} else {
-		msg_start_received = 0;
-	}
-	
-	//The start char can be repeated multiple times, wait for something else
-	while (1){
-		ret = transport_receive_char(timeout);
-		if (ret == TRANSPORT_ERR_TIMEOUT) return TRANSPORT_ERR_TIMEOUT;
-		if (ret == TRANSPORT_ERR_NESTED_INTERRUPTS) return TRANSPORT_ERR_NESTED_INTERRUPTS;
-		if (ret == RET_MSG_END) {has_body = 0; break;}; //end after start -> empty message
-		if (ret != RET_MSG_START) break;
-	}
-	
-	if (has_body){
-		c = ret & 0xFF;
-		
-		//Receive the message body
-		while (1){
-			if (recv_length < length){ //write byte to the buffer (if not full)
-				buffer[recv_length] = c;
-				recv_length++;
-			} else {
-				return TRANSPORT_ERR_MESSAGE_TOO_LONG;
-			}
-			
-			real_checksum = _crc16_update(real_checksum, c); //checksum byte
-			
-			//Receive next char
-			ret = transport_receive_char(timeout);
-			if (ret == TRANSPORT_ERR_TIMEOUT) return TRANSPORT_ERR_TIMEOUT;
-			if (ret == TRANSPORT_ERR_NESTED_INTERRUPTS) return TRANSPORT_ERR_NESTED_INTERRUPTS;
-			if (ret == RET_MSG_START) return TRANSPORT_ERR_MESSAGE_ABORT; //no start char expected, this is an error (truncated message?)
-			if (ret == RET_MSG_END) break; //end char (literal) received
-			c = ret & 0xFF;
+		uint16_t checksum = 0xFFFF;
+		for (uint8_t i = 0; i < msg_recv_body_length; i++){
+			checksum = _crc16_update(checksum, msg_recv_buffer[i]);
+			buffer[i] = msg_recv_buffer[i];
 		}
+		RECV_SET_STATE(RECV_IDLE);
+		
+		if (checksum != msg_recv_checksum) return TRANSPORT_ERR_CHECKSUM_FAIL;
+		
+		return msg_recv_body_length;
 	}
-	
-	//checksum (low byte)
-	ret = transport_receive_char(timeout);
-	if (ret == TRANSPORT_ERR_TIMEOUT) return TRANSPORT_ERR_TIMEOUT;
-	if (ret == TRANSPORT_ERR_NESTED_INTERRUPTS) return TRANSPORT_ERR_NESTED_INTERRUPTS;
-	if (ret == RET_MSG_START) return TRANSPORT_ERR_MESSAGE_ABORT; //no start char expected, this is an error (truncated message?)
-	if (ret == RET_MSG_END)   return TRANSPORT_ERR_UNEXPCETED_END; //doesnt belong here, don't know how to handle that
-	expected_checksum = ret & 0xFF;
-	
-	//checksum (high byte)
-	ret = transport_receive_char(timeout);
-	if (ret == TRANSPORT_ERR_TIMEOUT) return TRANSPORT_ERR_TIMEOUT;
-	if (ret == TRANSPORT_ERR_NESTED_INTERRUPTS) return TRANSPORT_ERR_NESTED_INTERRUPTS;
-	if (ret == RET_MSG_START) return TRANSPORT_ERR_MESSAGE_ABORT; //no start char expected, this is an error (truncated message?)
-	if (ret == RET_MSG_END)   return TRANSPORT_ERR_UNEXPCETED_END; //doesnt belong here, don't know how to handle that
-	expected_checksum |= (ret & 0xFF) << 8;
-	
-	
-	if (expected_checksum != real_checksum){
-// 		lcd_clear();
-// 		lcd_home();
-// 		for (uint8_t i = 0; i < recv_length; i++){
-// 			lcd_write_byte_hex(buffer[i]);
-// 		}
-// 		_delay_ms(10000);
-		return TRANSPORT_ERR_CHECKSUM_FAIL;
-	}
-	
-	return recv_length;
 }
-
-uint16_t transport_receive_message(uint8_t* buffer, uint8_t length, uint16_t timeout){
-	USART_disable_rx_interrupt(); //Disable RX interrupt, we are going to poll rx from here now.
-	uint16_t ret = _transport_receive_message(buffer,length, timeout);
-	USART_enable_rx_interrupt(); //Enable RX interrupt again.
-	return ret;
-}
\ No newline at end of file
diff --git a/common/transport/transport.h b/common/transport/transport.h
index ce65972aa469fd435371397e53ef4368d210d431..f970d03671e07e7b4523560a7391b0ff8ef92226 100644
--- a/common/transport/transport.h
+++ b/common/transport/transport.h
@@ -8,10 +8,7 @@
 
 #define TRANSPORT_ERR_TIMEOUT 0xFFFF
 #define TRANSPORT_ERR_CHECKSUM_FAIL 0xFFEE
-#define TRANSPORT_ERR_MESSAGE_ABORT 0xFFDD
 #define TRANSPORT_ERR_MESSAGE_TOO_LONG 0xFFCC
-#define TRANSPORT_ERR_UNEXPCETED_END 0xFFBB
-#define TRANSPORT_ERR_NESTED_INTERRUPTS 0xFFAA
 #define TRANSPORT_IS_ERROR(ret) (((ret) & 0xFF00) != 0)
 
 typedef void (*interrupt_msg_handler_t)(void);