Files @ e2403547a6c7
Branch filter:

Location: seniordesign-firmware/master/master/master.c

ethanzonca@CL-ENS241-08.cedarville.edu
merge
/*
 * Master Firmware
 *
 * Wireless Observational Modular Aerial Network
 * 
 * Ethan Zonca
 * Matthew Kanning
 * Kyle Ripperger
 * Matthew Kroening
 *
 */


#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 <string.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/gps.h"
#include "lib/i2c.h"
#include "lib/sensors.h"
#include "lib/heater.h"
#include "lib/looptime.h"
#include "lib/slavesensors.h"
#include "lib/serparser.h"
#include "lib/sensordata.h"

int main(void)
{
	// Power debounce
	_delay_ms(1000);
	
	// Initialize libraries
	time_setup();
	watchdog_setup(); // enables interrupts
	led_setup();
	gps_setup();
	serial0_setup();
	serial1_setup();
	i2c_init();
	sensordata_setup(); // must happen before slavesensors/logger/AFSK
	slavesensors_setup();
	sensors_setup();
	logger_setup();
	afsk_setup();
	
	serial0_sendString("\r\nHello.\r\n\r\n");
	
	// Blocking ZigBee node discovery
	slavesensors_network_scan();
	
	// Software timers	
	uint32_t lastAprsBroadcast = 0;
	uint32_t lastLog = 0;
	uint32_t lastLedCycle = 0;
	uint32_t lastDataReq = 0;
	uint32_t lastBuzz = 0;
	
	// Result of last parser run
	int parseResult = PARSERESULT_NODATA;
	
	// FIXME: Probably don't need this.
	serial1_ioff();
	
	while(1)
    {
		// Periodic: LED execution indicator
		if(time_millis() - lastLedCycle > LEDCYCLE_RATE) 
		{
			led_power_toggle();
			led_spin();
			
			// Enable GPS serial interrupts if we aren't doing AFSK
			if(!afsk_busy())
				serial1_ion();
				
			lastLedCycle = time_millis();	
		}
		
		// Periodic: Logging
		if(time_millis() - lastLog > LOGGER_RATE) 
		{
			led_on(LED_CYCLE);
			
			heater_regulateTemp();
			
			// Turn on sideboard LED if we have a fix
			if(gps_hasfix()) 
			{
				led_on(LED_SIDEBOARD);
			}
			else 
			{
				led_off(LED_SIDEBOARD);
			}
			
			sensors_readBoardTemp();
			sensors_readBatt();
		
			// Write CSV header and log data values
			sensordata_logvalues();			
			
			led_off(LED_CYCLE);
			lastLog = time_millis();
		}		
		
		// Periodic: Buzzer
		if(time_millis() - lastBuzz > BUZZER_RATE) {
			if(sensordata_isTouchdown())
			{
				led_on(LED_BUZZ);
				_delay_ms(BUZZER_DURATION);
				led_off(LED_BUZZ);
			}			
			lastBuzz = time_millis();
		}
		
		// Periodic: Data Request
		if(time_millis() - lastDataReq > DATAREQUEST_RATE)  
		{
			// Start getting values for next transmission
			if(slavesensors_isrequesting())
			{
				// TODO: something is terribly wrong. Timeout?
			}
			else
			{
				slavesensors_startprocess();
			}
			
			lastDataReq = time_millis();
		}
		
		
		// Periodic: APRS transmission
		if(time_millis() - lastAprsBroadcast > APRS_TRANSMIT_PERIOD) 
		{
			// Check for touchdown
			sensordata_checkTouchdown();
			
			// Ensure we aren't already transmitting
			while(afsk_busy());
			
			// Turn off interrupts and transmit APRS sentence
			serial1_ioff();
			aprs_send(); // non-blocking
			
			lastAprsBroadcast = time_millis();
		}			
		
		#ifdef BLACKOUT_ENABLE
		bool black = false;
		if(!black && time_millis() > BLACKOUT_TIMEOUT) 
		{
			// LED blackout
			led_blackout();
			black = true;
		}
		#endif
		
		// Parse any serial data in the XBee software buffer
		parseResult = serparser_parse();
		slavesensors_process(parseResult);
		
		
		// Parse any NMEA messages in the GPS software buffer
		parse_gps_transmission();
		
		
		wdt_reset();
    }
}