Changeset - 2e9d4bb3d9c7
[Not reviewed]
default
0 4 0
ethanzonca@CL-SEC241-08.cedarville.edu - 13 years ago 2012-11-29 15:34:24
ethanzonca@CL-SEC241-08.cedarville.edu
Circular buffer serial parser is operational
4 files changed with 70 insertions and 28 deletions:
0 comments (0 inline, 0 general)
master/master/config.h
Show inline comments
 
@@ -51,26 +51,26 @@
 
#define MAX_PAYLOAD_LEN 16
 
 
// Circular serial buffer size. Must be at least MAX_CMD_LEN + 5
 
#define BUFFER_SIZE 32 
 
 
// Public broadcast address
 
#define BROADCAST_ADDR 0 
 
 
// --------------------------------------------------------------------------
 
// USART config (serial.c)
 
// --------------------------------------------------------------------------
 
 
#define USART0_BAUDRATE 115200
 
#define USART1_BAUDRATE 115200
 
#define USART0_BAUDRATE 9600
 
#define USART1_BAUDRATE 9600
 
 
 
// --------------------------------------------------------------------------
 
// AX.25 config (ax25.c)
 
// --------------------------------------------------------------------------
 

	
 
// TX delay in milliseconds
 
#define TX_DELAY      300
 

	
 
// Maximum packet delay
 
#define MAX_PACKET_LEN 512  // bytes
 
master/master/lib/serial.c
Show inline comments
 
@@ -2,44 +2,59 @@
 
 * Master Firmware: USART Send/Recieve
 
 *
 
 * Wireless Observational Modular Aerial Network
 
 * 
 
 * Ethan Zonca
 
 * Matthew Kanning
 
 * Kyle Ripperger
 
 * Matthew Kroening
 
 *
 
 */
 
 
#include "serial.h"
 
#include "led.h"
 
#include "../config.h"
 
#include <avr/io.h>
 
#include <avr/interrupt.h>
 
 
// NOTE: USART ISRs for charachter reception are included in serparser.c
 
// NOTE: USART ISRs for character reception are included in serparser.c
 
 
void serial0_setup() {
 
	PORTD &= ~(1<<PD0);
 
	PORTD |= (1<<PD1);
 
	//PORTD &= ~(1<<PD0);
 
	//PORTD |= (1<<PD1);
 
	
 
	/* Enable receiver and transmitter */
 
	UCSR0B |= (1<<RXEN0)|(1<<TXEN0); // Enable rx/tx
 
	/* Set frame format: 8data, 1stop bit */
 
	UCSR0C |= (1 << UCSZ00) | (1 << UCSZ01); // - 1 stop bit
 
	
 
	/* Set baud rate */
 
	UBRR0H = (unsigned char)(USART0_BAUD_PRESCALE>>8);
 
	UBRR0L = (unsigned char)USART0_BAUD_PRESCALE;
 
	
 
	UCSR0A |= (1<<RXC0);
 
	/* Enable receiver and transmitter */
 
	UCSR0B = (1<<RXEN0)|(1<<TXEN0)|(RXCIE0); // Enable rx/tx/rx interrupt
 
	/* Set frame format: 8data, 1stop bit */
 
	UCSR0C = (3<<UCSZ00); // - 1 stop bit
 
	UCSR0B |= (1 << RXCIE0); // Enable interrupt
 
	
 
	//UCSR0A |= (1<<RXC0);
 
 
 
}
 
 
/*
 
uint8_t test = 0;
 
ISR(USART0__RX_vect)
 
{
 
	led_on(POWER);
 
	test = UDR0;
 
}*/
 
 
void serial1_setup() {
 
	/* Set baud rate */
 
	UBRR1H = (unsigned char)(USART1_BAUD_PRESCALE>>8);
 
	UBRR1L = (unsigned char)USART1_BAUD_PRESCALE;
 
	/* Enable receiver and transmitter */
 
	UCSR1B = (1<<RXEN1)|(1<<TXEN1);
 
	/* Set frame format: 8data, 1stop bit */
 
	UCSR1C = (3<<UCSZ10); // - 1 stop bit
 
}
 
 
void serial0_sendChar( unsigned char byte )
 
{
master/master/lib/serparser.c
Show inline comments
 
@@ -3,28 +3,29 @@
 
 *
 
 * Wireless Observational Modular Aerial Network
 
 * 
 
 * Ethan Zonca
 
 * Matthew Kanning
 
 * Kyle Ripperger
 
 * Matthew Kroening
 
 *
 
 */
 
 
 
#include <avr/io.h>
 
#include <avr/interrupt.h>
 
#include "../config.h"
 
#include "serial.h"
 
#include "serparser.h"
 
 
#include "led.h"
 
 
// Circular buffer for incoming data
 
uint8_t buffer[BUFFER_SIZE];
 
 
// Location of parser in the buffer
 
uint8_t bufferParsePosition = 0;
 
 
// Location of receive byte interrupt in the buffer
 
volatile uint16_t bufferDataPosition = 0;
 
 
// Parser state
 
uint8_t parserState = STATE_RESET;
 
@@ -51,112 +52,138 @@ static void setParserState(uint8_t state
 
	// If resetting, clear vars
 
	if(state == STATE_RESET) 
 
	{
 
		dataLength = 0;
 
		checksumCalc = 0;
 
	}
 
	
 
	// Every time we change state, we have parsed a byte
 
	bufferParsePosition = (bufferParsePosition + 1) % BUFFER_SIZE;
 
}
 
 
// Receive data on USART
 
ISR(USART0_RX_vect) 
 
 
char buffmeh[16];
 
 
ISR(USART0__RX_vect)
 
{
 
	led_on(POWER);
 
	buffer[bufferDataPosition % BUFFER_SIZE] = UDR0;
 
	bufferDataPosition = (bufferDataPosition + 1) % BUFFER_SIZE;
 
	sprintf(buffmeh, "bdp: %d, bpp: %d \r\n", bufferDataPosition, bufferParsePosition);
 
	serial0_sendString((buffmeh));
 
}
 
 
 
 
#define DEBUG
 
 
// Parse data from circular buffer
 
int serparser_parse(void)
 
{
 
	
 
	char byte;
 
 
	// Process first command (if any) on the circular buffer
 
	while(bufferDataPosition != bufferParsePosition)
 
	{
 
		byte = buffer[bufferParsePosition];
 
		
 
		// Reset 
 
		if(parserState == STATE_RESET)
 
		{
 
			if(byte == '[') // Start of frame; keep parsing
 
			{
 
				serial0_sendString("PARSER: start ok\r\n");
 
				#ifdef DEBUG
 
				serial0_sendString("start ok\r\n");
 
				#endif
 
				setParserState(STATE_GETID);
 
			}
 
			else // Not start of frame, reset
 
			{
 
				serial0_sendString("PARSER: not start, reset\r\n");
 
				#ifdef DEBUG
 
				serial0_sendString("not start\r\n");
 
				#endif
 
				setParserState(STATE_RESET);
 
				return PARSERESULT_NODATA; // no valid start bit; better luck next time. run the function the next time around the main loop.
 
			}
 
		}
 
		
 
		// Get destination module ID
 
		else if(parserState == STATE_GETID)
 
		{
 
			if(byte == MODULE_ID) // Message intended for this module; keep parsing
 
			{
 
				serial0_sendString("SER: dest ok\r\n");
 
				#ifdef DEBUG
 
				serial0_sendString("dest ok\r\n");
 
				#endif
 
				checksumCalc += byte;
 
				setParserState(STATE_GETDATATYPE);
 
			}
 
			else // Transmission is intended for another module; reset
 
			{
 
				serial0_sendString("SER: bad dest, reset\r\n");
 
				#ifdef DEBUG
 
				serial0_sendString("bad dest\r\n");
 
				#endif
 
				setParserState(STATE_RESET);
 
			}
 
		}
 
		
 
		// Get payload type ID
 
		else if(parserState == STATE_GETDATATYPE)
 
		{
 
			serial0_sendString("SER: type ok\r\n");
 
			#ifdef DEBUG
 
			serial0_sendString("type ok\r\n");
 
			#endif
 
			receivedDataType = byte; // Store the type of data receiving
 
			checksumCalc += byte;
 
			setParserState(STATE_GETDATA);
 
		}
 
		
 
		// Get payload data
 
		else if(parserState == STATE_GETDATA)
 
		{		
 
			if (byte == ']') // End of frame
 
			{
 
				serial0_sendString("SER: eof ok\r\n");
 
				#ifdef DEBUG
 
				serial0_sendString("eof ok\r\n");
 
				#endif
 
				if(bufferParsePosition == bufferDataPosition) 
 
				{
 
					// We are at the end of the line. No more data to parse.
 
					setParserState(STATE_RESET);
 
					return PARSERESULT_PARSEOK;
 
				}
 
				else 
 
				{
 
					setParserState(STATE_RESET);
 
					// we could choose to keep parsing now, or parse the next message next loop around (better idea).
 
					// return now so we hit it the next time around
 
					return PARSERESULT_PARSEOK;
 
				}
 
			}
 
			else // Still receiving data
 
			{
 
				serial0_sendString("SER: data ok\r\n");
 
				#ifdef DEBUG
 
				serial0_sendString("data ok\r\n");
 
				#endif
 
				receivedPayload[dataLength] = byte;
 
				dataLength++;
 
				checksumCalc += byte;
 
				
 
				// Data buffer overrun protection
 
				if(dataLength > MAX_PAYLOAD_LEN) {
 
					serial0_sendString("SER: buf overflow, reset\r\n");
 
					#ifdef DEBUG
 
					serial0_sendString("buf ovf\r\n");
 
					#endif
 
					setParserState(STATE_RESET);
 
					return PARSERESULT_FAIL;
 
				}
 
				else {
 
					// Set state. MUST call even though state is maintained to update parse position
 
					setParserState(STATE_GETDATA);
 
					return PARSERESULT_STILLPARSING;
 
				}
 
				
 
			}
 
 
		}
master/master/master.c
Show inline comments
 
@@ -45,25 +45,25 @@ int main(void)
 
	watchdog_setup();
 
	led_setup();
 
	serial0_setup();
 
	serial1_setup();
 
	slavesensors_setup();
 
	logger_setup();
 
	afsk_setup();
 

	
 
	serial0_sendString("\r\n\r\n---------------------------------\r\n");
 
	serial0_sendString("HAB Controller 1.0 - Initialized!\r\n");
 
	serial0_sendString("---------------------------------\r\n\r\n");
 
	
 
	led_on(POWER);
 
	//led_on(POWER);
 
	
 
	// Buffer for string operations
 
	char logbuf[32];
 
	const char* logBufPtr = logbuf;
 
	
 
	// Software timers	
 
	uint32_t lastAprsBroadcast = 0;
 
	uint32_t lastLog = 0;
 
	
 
	// If we are currently processing sensor data
 
	bool isProcessing = false;
 
	
 
@@ -83,42 +83,42 @@ int main(void)
 
			
 
			// TODO: Acquire data from daughterboards
 
			//       This will be complicated because we need timeouts / unreliable transmission, etc
 
			//
 
			// For each daughterboard...
 
			//   1. Send request to daughterboard for sensor data
 
			//   2. Wait for response from daughterboard (timeout!)
 
			//   3. Put data into local variables for transmission / logging
 
			
 
			led_on(STAT);
 
			snprintf(logbuf, 32, "%lu,%lu,%lu,\r\n", time_millis(), lastAprsBroadcast,lastLog);
 
			logger_log(logbuf);
 
			serial0_sendString("SD Logger: ");
 
			serial0_sendString(logBufPtr);
 
			//serial0_sendString("SD Logger: ");
 
			//serial0_sendString(logBufPtr);
 
			led_off(STAT);
 
			lastLog = time_millis();
 
		}		
 
		
 
		// Periodic: APRS transmission
 
		if(time_millis() - lastAprsBroadcast > APRS_TRANSMIT_PERIOD) 
 
		{
 
			while(afsk_busy());
 
			aprs_send(); // non-blocking
 
			serial0_sendString("Initiating APRS transmission...\r\n");
 
			//serial0_sendString("Initiating APRS transmission...\r\n");
 
			
 
			// Start getting values for next transmission
 
			isProcessing = true;
 
			
 
			lastAprsBroadcast = time_millis();
 
		}			
 
		
 
		parseResult = serparser_parse();
 
		
 
		// TODO: If we receive a command, we should still process it even if we aren't isProcessing, right?
 
		// Maybe we should isolate the received command handling ("Execution") and the issuing of requests.
 
		if(isProcessing) 
 
		{
 
			isProcessing = slavesensors_process(parseResult);
 
		}
 
		//if(isProcessing) 
 
		//{
 
		//	isProcessing = slavesensors_process(parseResult);
 
		//}
 
		wdt_reset();
 
    }
 
}
 
\ No newline at end of file
0 comments (0 inline, 0 general)