// ****** Standard Includes ***** #include #include //#include #include #include // ****** Non-Blocking serial transmit and receive ****** // Transmit ISR variables #define RINGSIZE 512 unsigned char t_buffer[RINGSIZE]; // transmit ring buffer unsigned char t_start; // ring start unsigned char t_end; // ring end void WriteSerString(char *ws); unsigned char temp[20]; unsigned char interfacestyle; #include "interruptserial.c" // ****** SPI Flash ******* unsigned int page_address, byte_address; /* Data structure (8 byte packet sizes) * Packet size - 1 byte - total packet size for future compatibility * Timestamp - 2 bytes - seconds since reset * Data - 5 bytes - unit depending on data */ #include "dataflash.c" // ******* Data Acquisition ******* unsigned char packet_array[256]; unsigned char lastSensor; unsigned char sensorData[6]; unsigned char sensorSetting[] = {0, 0b01100110, 0b01100111, 0b01101001, 0b01111011, 0b01100100}; // 1 - Temperature (F) - ADC6 // 2 - Light - ADC7 // 3 - 10x gain Differential Signal - ADC1(+) ADC0(-) // 4 - 1x gain Differential Signal - ADC3(+) ADC2(-) // 5 - Singled-ended Voltage - ADC4 #define MAXSENSORS 5 // ****** State Machine ****** #define InitState 0 #define ContLogState 1 #define TimedLogState 2 #define DumpState 3 unsigned char LogState; #define HEARTBEAT_TIMEOUT 5000 unsigned int currentTime; unsigned int secondCounter; unsigned int heartbeat; void addressAdd(int addee){ byte_address = byte_address + addee; if (byte_address == 528) { byte_address = 0; page_address ++; } if (page_address == 512) { page_address = 0; } } char addressNewPage (){ if (byte_address == 0) { return 1; } return 0; } //------------------ UART receive ------------------------- interrupt [USART_RXC] void uart_rec(void) { int i, j; unsigned char r_char; unsigned char c; char statusc; r_char=UDR; //get a char switch(r_char) { case 'p': case 'P': // ping heartbeat=0; WriteSerPacket(currentTime, sensorData); break; case 's': case 'S': // stop if (interfacestyle=='h') AddTx('S'); DF_finalize_buff1(); LogState = InitState; CS = 1; break; case 'd': case 'D': // dump if (interfacestyle=='h') AddTx('D'); if(LogState == InitState) { LogState = DumpState; page_address = 257; byte_address=0; // Make sure DF is ready while (!DF_ready()) {} // Begin operation CS = 0; // op-code SPI(0xE8); // Buffer 1 Write // address DF_address(); SPI(0x55); SPI(0x55); SPI(0x55); SPI(0x55); // send data } if (LogState == DumpState) { for(i=0; i<128; i++) { AddTx(SPI(0x55)); } } break; case 'r': case 'R': // reset if (interfacestyle=='h') AddTx('R'); if (LogState == InitState) { LogState = ContLogState; DF_clear(); currentTime = 0; secondCounter = 0; heartbeat = 0; lastSensor = 0; page_address = 257; byte_address = 0; ADMUX = sensorSetting[1]; ADCSR.6=1; } break; case 'h': case 'H': // human interface interfacestyle = 'h'; if (interfacestyle=='h') AddTx('H'); break; case 'm': case 'M': // machine interface interfacestyle = 'm'; break; } } //------------------ UART transmit ------------------------ interrupt [USART_DRE] void uart_send(void) { if (t_start!=t_end) { UDR = t_buffer[t_start]; t_start = (t_start+1)%RINGSIZE; } } //------------------ Data acquisition --------------------- void saveData(void){ DF_writepacket_buff1 (currentTime, sensorData); byte_address += 8; if (byte_address >= 528) { byte_address = 0; DF_finalize_buff1(); page_address ++; if (page_address >= 4096) { page_address = 257; } } } //timer 1a compare match ISR interrupt [TIM1_COMPA] void timer1a_cmp(void) { unsigned char ADCval; if (LogState == ContLogState || LogState == TimedLogState) { // Log the sample ADCval = ADCH; sensorData[lastSensor] = ADCval; if (lastSensor == MAXSENSORS) { saveData(); lastSensor = 0; } lastSensor++; //start another conversion ADMUX = sensorSetting[lastSensor]; ADCSR.6=1; } } //-------------------- Timing ------------------------ interrupt [TIM0_COMP] void timer0_overflow(void) { secondCounter++; if(secondCounter>=1027) { secondCounter=0; currentTime++; } if (LogState == ContLogState || LogState == TimedLogState) { heartbeat++; } if (heartbeat > HEARTBEAT_TIMEOUT && LogState == ContLogState) { heartbeat = 0; LogState = TimedLogState; } if (heartbeat > HEARTBEAT_TIMEOUT && LogState == TimedLogState) { heartbeat = 0; LogState = InitState; } } void initialize(void) { // Start RS232 Serial UCSRB = 0xB8 ; // both transmit and receive interrupts turned on UBRRL = 16 ; // baud set to 57.6k // initialize transmit buffer empty t_start=0; t_end=0; interfacestyle = 'm'; // Start SPI Flash SPI_init(); page_address = 257; byte_address = 0; // Start ADC ADMUX = sensorSetting[1]; ADCSR.6=1; //channel zero/ left adj /EXTERNAL Aref ADCSR = 0b11000111; // ADEN - Enable (1) // ADSC - Start Conversion (1) // ADATE - Auto Trigger (0) // ADIF - Interrupt Flag (0) - set when conversion complete, cleared when interrupt run // ADIE - Interrupt Enable (0) - enable i-bit in SREG to enable ADC conversion complete interrupt // ADPS2:0 - Prescaler (111) - f_osc/128 1/128*16MHz=125,000 // Start Timers // Timer 0 OCR0=249; // 1 mSec TCCR0=0b00001011; // prescalar to 64 and Clear-on-match // Timer 1 TCNT1=0; TIMSK=18; // turn on timer 0 cmp-match ISR //turn on timer 1A cmp match ISR OCR1A = 249; //250 ticks=1 mSec //prescalar to 64 and turn on clear-on-match TCCR1A = 0b00000000; TCCR1B = 0b00001011; // Start internal state machine LogState = InitState; lastSensor = 0; currentTime = 0; secondCounter=0; heartbeat = 0; #asm sei // crank up the ISRs #endasm } void main(void) { initialize(); while(1) { } }