Changeset - 48acfcb35ad3
[Not reviewed]
default
0 11 2
ethanzonca@CL-SEC241-08.cedarville.edu - 12 years ago 2012-11-27 21:36:13
ethanzonca@CL-SEC241-08.cedarville.edu
Added slave parser library, added infrastructure for requesting data from slave nodes
13 files changed with 211 insertions and 83 deletions:
0 comments (0 inline, 0 general)
master/master/config.h
Show inline comments
 
@@ -9,13 +9,24 @@
 
#ifndef CONFIG_H_
 
#define CONFIG_H_
 
 
#define F_CPU 11059200
 
#define MODULE_ID '1'
 
 
// --------------------------------------------------------------------------
 
// Slave Sensors config (slavesensors.c)
 
// --------------------------------------------------------------------------
 
 
#define SLAVE0_SENSORS BOARDTEMP
 
#define SLAVE1_SENSORS BOARDTEMP | HUMIDITY | TEMPERATURE | PRESSURE | AMBIENTLIGHT
 
#define SLAVE2_SENSORS BOARDTEMP | GEIGER
 
#define SLAVE3_SENSORS BOARDTEMP | CAMERA
 
#define SLAVE4_SENSORS NONE
 
#define SLAVE5_SENSORS NONE
 
#define SLAVE6_SENSORS NONE
 
#define SLAVE7_SENSORS NONE
 
 
// --------------------------------------------------------------------------
 
// USART config (serial.c)
 
// --------------------------------------------------------------------------
 
 
#define USART0_BAUDRATE 115200
 
@@ -59,18 +70,22 @@
 

	
 
// APRS comment: this goes in the comment portion of the APRS message. You
 
// might want to keep this short. The longer the packet, the more vulnerable
 
// it is to noise.
 
#define APRS_COMMENT    "Trackuino reminder: replace callsign with your own"
 
 
 
// Transmit the APRS sentence every X milliseconds
 
#define APRS_TRANSMIT_PERIOD 5000
 

	
 
// --------------------------------------------------------------------------
 
// Logger config (logger.c)
 
// --------------------------------------------------------------------------
 
 
#define LOGGER_ID_EEPROM_ADDR 0x10
 
 
// Written to the beginning of every log file
 
#define LOGGER_HEADERTEXT "HAB Control Master - 1.0\n"
 
 
// Log to SD card every X milliseconds
 
#define LOGGER_RATE 1000 
 
 
#endif /* CONFIG_H_ */
 
\ No newline at end of file
master/master/lib/aprs.c
Show inline comments
 
@@ -7,15 +7,15 @@
 
 
#include "../config.h"
 
#include "aprs.h"
 
#include "ax25.h"
 
#include <stdio.h>
 

	
 
const char *gps_aprs_lat = "somelatitudesomelatitudesomelatitudesomelatitudesomelatitudesomelatitude";
 
const char *gps_aprs_lon = "somelongitudesomelongitudesomelongitudesomelongitudesomelongitudesomelongitude";
 
const char *gps_time = "sometimedatasometimedatasometimedatasometimedatasometimedatasometimedata";
 
const char *gps_aprs_lat = "omgmylatitude";
 
const char *gps_aprs_lon = "omgmylongitude";
 
const char *gps_time = "omgmygpstime";
 
float gps_altitude = 123.5;
 
int gps_course = 5;
 
int gps_speed = 13;
 

	
 
float meters_to_feet(float m)
 
{
master/master/lib/logger.c
Show inline comments
 
@@ -5,12 +5,13 @@
 
 *  Author: mkanning
 
 */ 
 
 
#include "../config.h"
 
#include <util/delay.h>
 
#include <string.h>
 
#include <stdio.h>
 
#include <avr/pgmspace.h>
 
#include <avr/sleep.h>
 
#include <avr/eeprom.h>
 
#include <string.h>
 
#include "sd/fat.h"
 
#include "sd/fat_config.h"
 
@@ -116,14 +117,13 @@ void logger_setup()
 
		return;
 
	}
 
		
 
	// Write header information
 
	logger_log(LOGGER_HEADERTEXT);
 
	logger_log("\n-- BEGIN DATA --\n");
 
	logger_log("C1, C2, C3, C4, C5, C6\n");
 
	
 
 
}	
 
 
void logger_log(char *buffer) {
 
	uint8_t len = strlen(buffer);
 
	if(fat_write_file(fd, (uint8_t*) buffer, len) != len)
 
	{
master/master/lib/looptime.c
Show inline comments
 
@@ -5,14 +5,14 @@
 
 *  Author: ethanzonca
 
 */ 
 
 
#include "../config.h"
 
#include <avr/io.h>
 
#include <avr/interrupt.h>
 
#include <avr/delay.h>
 
extern volatile uint32_t millis = 0; // Milliseconds since initialization
 
#include <util/delay.h>
 
volatile uint32_t millis = 0; // Milliseconds since initialization
 

	
 

	
 

	
 
void time_setup() {
 
	DDRA = 0xff;
 
	
master/master/lib/sd/sd_raw.c
Show inline comments
 
@@ -188,24 +188,15 @@ uint8_t sd_raw_init()
 
    SPCR0 = (0 << SPIE0) | // SPI Interrupt Enable 
 
            (1 << SPE0)  | // SPI Enable 
 
            (0 << DORD0) | // Data Order: MSB first 
 
            (1 << MSTR0) | // Master mode 
 
            (0 << CPOL0) | // Clock Polarity: SCK low when idle 
 
            (0 << CPHA0) | // Clock Phase: sample on rising SCK edge 
 
            (1 << SPR10);   // Clock Frequency: f_OSC / 128 
 
            //(1 << SPR00); // commentnig this out means /64, which gives over 100khz as required
 
            (1 << SPR10);   // Clock Frequency: f_OSC / 64 which gives over 100khz required minimum clock
 
    SPSR0 &= ~(1 << SPI2X0); // No doubled clock frequency 
 

	
 
/*
 
	while(1) {
 
		SPDR0 = 'a';					//Load byte to Data register
 
		while(!(SPSR0 & (1<<SPIF0))); 	// Wait for transmission complete
 
	}
 
*/
 

	
 

	
 
    /* initialization procedure */
 
    sd_raw_card_type = 0;
 
    
 
    if(!sd_raw_available())
 
        return 0;
 

	
master/master/lib/serial.c
Show inline comments
 
@@ -6,13 +6,12 @@
 
 */ 
 
 
#include "serial.h"
 
#include "../config.h"
 
#include <avr/io.h>
 
 
 
void serial0_setup() {
 
	/* Set baud rate */
 
	UBRR0H = (unsigned char)(USART0_BAUD_PRESCALE>>8);
 
	UBRR0L = (unsigned char)USART0_BAUD_PRESCALE;
 
	/* Enable receiver and transmitter */
 
	UCSR0B = (1<<RXEN0)|(1<<TXEN0);
 
@@ -39,43 +38,55 @@ void serial0_sendChar( unsigned char byt
 
void serial1_sendChar( unsigned char byte )
 
{
 
	while (!(UCSR1A & (1<<UDRE1)));
 
	UDR1 = byte;
 
}
 
 
void serial0_sendString(char* stringPtr){
 
unsigned char serial0_readChar()
 
{
 
	while(!(UCSR0A &(1<<RXC0)));
 
	return UDR0;
 
}
 
 
unsigned char serial1_readChar()
 
{
 
	while(!(UCSR1A &(1<<RXC1)));
 
	return UDR1;
 
}
 
 
void serial0_sendString(const char* stringPtr){
 
	while(*stringPtr != 0x00){
 
		serial0_sendChar(*stringPtr);
 
		stringPtr++;
 
	}
 
}
 
 
void serial1_sendString(char* stringPtr){
 
void serial1_sendString(const char* stringPtr){
 
	while(*stringPtr != 0x00){
 
		serial1_sendChar(*stringPtr);
 
		stringPtr++;
 
	}
 
}
 
 
 
void serial_sendCommand( char moduleID, char sensorID, uint8_t dataLength, char* data )
 
void serial_sendCommand( char moduleID, char sensorID, char* data )
 
{
 
	char checkSum = 0x00; //initialize checksum
 
	
 
	serial0_sendChar('['); //bracket indicates start of command
 
	serial0_sendChar(moduleID);
 
	checkSum+=moduleID;
 
	
 
	serial0_sendChar(sensorID);
 
	checkSum+=sensorID;
 
	
 
	//send each character of data individually
 
	for (int i=0; i<dataLength; i++)
 
	{
 
		serial0_sendChar(data[i]);
 
		checkSum+=data[i];
 
	// send data, null-terminated
 
	while(*data != 0x00){
 
		serial0_sendChar(*data);
 
		checkSum += *data;
 
		data++;
 
	}
 
	
 
	serial0_sendChar(checkSum);
 
	serial0_sendChar(']'); //bracket indicates end of command
 
}
 
master/master/lib/serial.h
Show inline comments
 
@@ -14,17 +14,20 @@
 
#define USART0_BAUD_PRESCALE (((F_CPU / (USART0_BAUDRATE * 16UL))) -1 )
 
#define USART1_BAUD_PRESCALE (((F_CPU / (USART1_BAUDRATE * 16UL))) -1 )
 
 
void serial0_sendChar( unsigned char byte );
 
void serial1_sendChar( unsigned char byte );
 
 
unsigned char serial0_readChar();
 
unsigned char serial1_readChar();
 
 
void serial0_setup();
 
void serial1_setup();
 
 
void serial0_sendString(char* stringPtr);
 
void serial1_sendString(char* stringPtr);
 
void serial0_sendString(const char* stringPtr);
 
void serial1_sendString(const char* stringPtr);
 
 
void serial_sendCommand( char moduleID, char sensorID, uint8_t dataLength, char* data );
 
void serial_sendCommand( char moduleID, char sensorID, char* data );
 
void serial_sendResponseData();
 
 
 
#endif /* SERIAL_H_ */
 
\ No newline at end of file
master/master/lib/serparser.c
Show inline comments
 
@@ -9,24 +9,17 @@
 
// ************* Macros ***************
 
#define SERIAL_RX_HASBYTES UCSR0A & _BV(RXC0)
 
#define MAX_CMD_LEN 16
 
#define BROADCAST_ADDR 0 //public address
 
#include <avr/io.h>
 
#include "../config.h"
 
 
#include "serial.h"
 
//#define DEBUG
 
 
// ************* Command Definitions ***************
 
 
// Serial Commands
 
enum cmd // CMD ID#
 
{
 
	BOARDTEMP = 0, // 0
 
	PRESSURE,      // 1
 
};
 
 
// Incoming command buffer
 
uint8_t buffer[MAX_CMD_LEN+2];
 
 
// Current buffer location
 
uint8_t bufferPosition = 0;
 
 
@@ -39,36 +32,25 @@ char data[16];
 
//ID of the sensor of most recent transmission
 
char sensorID;
 
 
//checksum to be calculated and then compared to the received checksum
 
char checksumCalc;
 
 
/* return char from UART (h/w buffer) */
 
uint8_t uart_getchar(void)
 
{
 
	// Wait for chars
 
	/*	while (!(UCSRA & (1<<RXC)))
 
	{
 
		idle();
 
	}
 
	return UDR;
 
	*/
 
	return 0;
 
}
 
 
/* Process incoming serial data */
 
int uart_Parser(void)
 
// TODO: Maybe make this suck up the whole buffer if there is more to be had. That would make this much more efficient.
 
// we could parse while(SERIAL_RX_HASBYTES && notOverTimeout), don't have it parse for more than 100ms straight or something...
 
int serparser_parse(void)
 
{
 
 
	char byte;
 
 
	if(SERIAL_RX_HASBYTES) // Only process data if buffer has a byte
 
	{
 
		
 
		// Pull byte off of the buffer
 
		byte = uart_getchar();
 
		byte = serial0_readChar();
 
		buffer[bufferPosition] = byte;
 
		
 
		// byte checking/validation
 
		if(bufferPosition == 0)
 
		{
 
			if(byte == '[') // If this is a start byte, we're OK. Keep reading.
 
@@ -105,12 +87,13 @@ int uart_Parser(void)
 
		}
 
		else
 
		{
 
			if (byte == ']') //this is the end of the transmission
 
			{
 
				bufferPosition = 0;
 
				return 2; // got whole msg
 
			}
 
			else //still receiving data
 
			{
 
				data[dataLength] = byte;
 
				dataLength++;
 
				bufferPosition++;
master/master/lib/serparser.h
Show inline comments
 
@@ -6,20 +6,10 @@
 
 */ 
 
 
 
#ifndef SERPARSER_H_
 
#define SERPARSER_H_
 
 
 
// Prototypes
 
uint8_t convertchar(uint8_t);
 
uint8_t uart_getchar(void);
 
void got_char(uint8_t);
 
int uart_machine(void);
 
void uart_putchar(uint8_t);
 
void exec_cmd(void);
 
void idle(void);
 
void uart_init(void);
 
 
 
int serparser_parse(void);
 
 
#endif /* SERPARSER_H_ */
 
\ No newline at end of file
master/master/lib/slavesensors.c
Show inline comments
 
new file 100644
 
/*
 
 * slavesensors.c
 
 *
 
 * Created: 11/27/2012 9:02:12 PM
 
 *  Author: ethanzonca
 
 */ 
 
 
#include <avr/io.h>
 
#include <stdbool.h>
 
#include "../config.h"
 
#include "serial.h"
 
#include "serparser.h"
 

	
 
// Serial Commands
 
enum sensorTypes // CMD ID#
 
{
 
	NONE = 0,
 
	BOARDTEMP = (1<<0),
 
	PRESSURE = (1<<1),
 
	GEIGER = (1<<2),
 
	TEMPERATURE = (1<<3),
 
	HUMIDITY = (1<<4),
 
	AMBIENTLIGHT = (1<<5),
 
	CAMERA = (1<<5),
 
};
 

	
 
uint8_t receptionFinished = 0;
 
uint8_t currentSlave = 0;
 
uint8_t currentSlaveSensor = 0;
 
 
uint8_t maxSlave = 8;
 
uint16_t slaves[8];
 
 
void slavesensors_setup() 
 
{
 
	// Empty array
 
	for(int i=0; i<8; i++) 
 
	{
 
		slaves[i] = 0;
 
	}	
 
	
 
	// Configure sensors
 
	slaves[0] = SLAVE0_SENSORS;
 
	slaves[1] = SLAVE1_SENSORS;
 
	slaves[2] = SLAVE2_SENSORS;
 
	slaves[3] = SLAVE3_SENSORS;
 
	slaves[4] = SLAVE4_SENSORS;
 
	slaves[5] = SLAVE5_SENSORS;
 
	slaves[6] = SLAVE6_SENSORS;
 
	slaves[7] = SLAVE7_SENSORS;	
 
}
 
 
bool slavesensors_process() 
 
{
 
	// Periodic: Every Iteration
 
		
 
	// maybe we should do this in an ISR on byte received. only problem is that this could interrupt things,
 
	// but we only care about interruption during logging and such. don't log when parsing a message?
 
	receptionFinished = serparser_parse();
 
		
 
	// Finished reception of a message (one sensor data value). If not finished, send out command to get the next one
 
	if(receptionFinished == 2)
 
	{
 
		bool weFinishedTHeLastSlaveSensor = false; // ex.
 
		// if we finished the final reception for this slave, set gettingValues = false;
 
		if(currentSlave >= maxSlave && weFinishedTHeLastSlaveSensor)
 
		{
 
			currentSlave = 0;
 
			return false; // We're done for now!
 
		}
 
		else
 
		{
 
			// Request data from the next slave
 
			currentSlave++;
 
			
 
			// Need to check the next bit over to see if it has that...
 
			
 
			serial_sendCommand(currentSlave, 'a', ""); // send req for data
 
			return true; // Keep going...
 
		}
 
	}
 
	else 
 
	{
 
		return true; // Keep going...
 
	}
 
}		
 
\ No newline at end of file
master/master/lib/slavesensors.h
Show inline comments
 
new file 100644
 
/*
 
 * slavesensors.h
 
 *
 
 * Created: 11/27/2012 9:05:47 PM
 
 *  Author: ethanzonca
 
 */ 
 
 
 
#ifndef SLAVESENSORS_H_
 
#define SLAVESENSORS_H_
 
 
#include <stdbool.h>
 
 
void slavesensors_setup();
 
bool slavesensors_process();
 
 
 
#endif /* SLAVESENSORS_H_ */
 
\ No newline at end of file
master/master/master.c
Show inline comments
 
@@ -14,73 +14,98 @@
 
#include "config.h"
 

	
 
#include <avr/io.h>
 
#include <util/delay.h>
 
#include <avr/wdt.h>
 
#include <avr/interrupt.h>
 
#include <stdio.h>
 
#include <stdbool.h>
 

	
 
#include "lib/serial.h"
 
#include "lib/aprs.h"
 
#include "lib/afsk.h"
 
#include "lib/led.h"
 
#include "lib/logger.h"
 
#include "lib/watchdog.h"
 
#include "lib/sd/sd_raw_config.h"
 
#include "lib/looptime.h"
 
#include "lib/slavesensors.h"
 

	
 
void micro_setup() {
 

	
 
}
 

	
 
int main(void)
 
{
 
    
 
	// Initialize. If this takes more than 4 seconds, be sure to reset the WDT
 
	// Initialize libraries
 
	time_setup();
 
	micro_setup();
 
	watchdog_setup();
 
	led_setup();
 
	serial0_setup(); // Config serial ports
 
	serial1_setup(); // Config serial ports
 
	logger_setup(); // this takes a few ms
 
	afsk_setup(); // can take a few ms
 
	serial0_setup();
 
	serial1_setup();
 
	slavesensors_setup();
 
	logger_setup();
 
	afsk_setup();
 

	
 
	serial0_sendString("\r\n\r\n---------------------------------\r\nHAB Controller 1.0 - Initialized!\r\n---------------------------------\r\n\r\n");
 
	
 
	led_on(POWER);
 
		
 
	// Buffer for string operations
 
	char logbuf[32];
 
	const char* logBufPtr = logbuf;
 
	
 
	uint16_t ctr1 = 0;
 
	uint16_t ctr2 = 255;
 
		
 
	char logbuf[32];
 
	
 
	// Software timers	
 
	uint32_t lastAprsBroadcast = 0;
 
	uint32_t lastLog = 0;
 
	
 
	// If we are currently processing sensor data
 
	bool isProcessing = false;
 
	
 
	// Write CSV header to SD card
 
	logger_log("ProgramTime,LastAprsBroadcast,LastLog\n");
 
	
 
	while(1)
 
    {
 
		
 
		if(time_millis() - lastLog > 1000) {
 
		// Periodic: Logging
 
		if(time_millis() - lastLog > LOGGER_RATE) {
 
			
 
			// 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);
 
			sprintf(logbuf, "%lu,%u,%u,%u,%u,%u\r\n", time_millis(),5*ctr1,ctr2, 12*ctr2,43*ctr1,5*ctr2);
 
			snprintf(logbuf, 32, "%lu,%lu,%lu,\r\n", time_millis(), lastAprsBroadcast,lastLog);
 
			logger_log(logbuf);
 
			serial0_sendString("SD Logger: ");
 
			serial0_sendString(logbuf);
 
			serial0_sendString(logBufPtr);
 
			led_off(STAT);
 
			lastLog = time_millis();
 
		}		
 
		
 
		// 8 second periodic for APRS transmission
 
		// for some reason this seems to lock up and the WDT resets everything when the period exceeds 8 seconds. Which is the WDTimeout. Weird.
 
		// If we want ~8+ seconds, then we'll need to do something fun here. Maybe reset the wdt...
 
		if(time_millis() - lastAprsBroadcast > 10000) {
 
		// Periodic: APRS transmission
 
		if(time_millis() - lastAprsBroadcast > APRS_TRANSMIT_PERIOD) {
 
			while(afsk_busy());
 
			aprs_send(); // non-blocking
 
			serial0_sendString("Initiating APRS transmission...\r\n");
 
			
 
			// Start getting values for next transmission
 
			isProcessing = true;
 
			
 
			lastAprsBroadcast = time_millis();
 
		}			
 
		
 
		ctr1++;
 
		ctr2-=6;
 
		// keep calling processSensors until it is finished
 
		if(isProcessing) 
 
		{
 
			isProcessing = slavesensors_process();
 
		}
 
		wdt_reset();
 
    }
 
}
 
\ No newline at end of file
master/master/master.cproj
Show inline comments
 
@@ -195,12 +195,18 @@
 
    <Compile Include="lib\serparser.c">
 
      <SubType>compile</SubType>
 
    </Compile>
 
    <Compile Include="lib\serparser.h">
 
      <SubType>compile</SubType>
 
    </Compile>
 
    <Compile Include="lib\slavesensors.c">
 
      <SubType>compile</SubType>
 
    </Compile>
 
    <Compile Include="lib\slavesensors.h">
 
      <SubType>compile</SubType>
 
    </Compile>
 
    <Compile Include="lib\trackuinoGPS\config.h">
 
      <SubType>compile</SubType>
 
    </Compile>
 
    <Compile Include="lib\trackuinoGPS\gpsMKa.c">
 
      <SubType>compile</SubType>
 
    </Compile>
0 comments (0 inline, 0 general)