110 lines
3.4 KiB
C
Executable File
110 lines
3.4 KiB
C
Executable File
#define F_CPU 16000000UL
|
|
|
|
#include <avr/io.h>
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
#include <stdint.h>
|
|
#include <stdfix.h>
|
|
#include <util/delay.h>
|
|
#include <avr/interrupt.h>
|
|
#include "usart.h"
|
|
#include "mytimer.h"
|
|
|
|
//global variables
|
|
char rx[21]; //USART input buffer
|
|
char tmp[100]; //auxiliary var for converting strings
|
|
volatile unsigned int cnt = 0; //counter
|
|
volatile char rxCmd; //input is command flag
|
|
int trains;
|
|
int carriages; //storing stats
|
|
int trg0;
|
|
int trg1;
|
|
volatile char iflag;
|
|
volatile char isBlocked; //state information
|
|
accum tsb; //store time since boot
|
|
|
|
|
|
//USART baudrate calculations
|
|
#define BAUDRATE 9600
|
|
#define BAUD_PRESCALER (((F_CPU / (BAUDRATE * 16UL))) - 1)
|
|
|
|
|
|
//USART-related function definitions
|
|
void initUSART(void){
|
|
UBRR0H = (uint8_t)(BAUD_PRESCALER>>8);
|
|
UBRR0L = (uint8_t)(BAUD_PRESCALER); //setting baudrate to high and low regs
|
|
// UCSR0B = (1<<RXEN0)|(1<<TXEN0); //rx tx with no interrupts
|
|
UCSR0B = 0x98; //enable RX interrupt
|
|
UCSR0C = (3<<UCSZ00); //data bit size
|
|
}
|
|
unsigned char USART_receive(void){
|
|
while(!(UCSR0A & (1<<RXC0))); //wait for empty transmit buffer
|
|
return UDR0; //return buffer value
|
|
}
|
|
void USART_send(unsigned char data){
|
|
while(!(UCSR0A & (1<<UDRE0))); //while buffer reg is empty
|
|
UDR0 = data; //put data into buffer reg
|
|
}
|
|
void USART_putstring(char* StringPtr){
|
|
while(*StringPtr != 0x00){
|
|
USART_send(*StringPtr);
|
|
StringPtr++;}
|
|
}
|
|
|
|
//USART recieve interrupt
|
|
ISR(USART_RX_vect) {
|
|
rx[cnt] = UDR0; //store incoming characters in buffer
|
|
cnt++; //increment count of characters
|
|
if (cnt == 20 || rx[cnt-1] == 13){ //process data if data exceeds 20 characters or carriage return is entered
|
|
if(rx[0] == 58) rxCmd=1; //if a character sequence starts with : it is a command
|
|
else rxCmd=0;
|
|
rx[cnt] = 0; //add zero at the end to produce a string literal
|
|
switch (rxCmd){
|
|
case 0:
|
|
USART_putstring(rx);
|
|
USART_putstring("\r\n"); //echo entered characters to console
|
|
cnt=0;
|
|
break;
|
|
case 1:
|
|
if(strcmp(":hello\r",rx) == 0){ //find what command is entered and respond accordingly
|
|
USART_putstring(rx);
|
|
USART_putstring("\r\nWELCOME\r\nNOTE: Stats are not saved between reboots\r\n");
|
|
}
|
|
else if(strcmp(":help\r",rx) == 0){
|
|
USART_putstring(rx);
|
|
USART_putstring("\r\nAvailable commands:\r\n:hello -- Show system status\r\n:stats -- Show system stats\r\n:block -- Manually set barriers down\r\n:ublock -- Manually clear blockage\r\n:help -- Display this help\r\n");
|
|
}
|
|
else if(strcmp(":stats\r",rx) == 0){
|
|
tsb = ssinceboot() / 60;
|
|
USART_putstring(rx);
|
|
sprintf(tmp,"\r\nIn the %.2fmin since boot %d trains passed totalling %d carriages.\r\n",(double)tsb,trains,carriages);
|
|
USART_putstring(tmp);
|
|
}
|
|
else if(strcmp(":block\r",rx) == 0){
|
|
USART_putstring(rx);
|
|
USART_putstring("\r\nManual override: crossing is blocked\r\n");
|
|
isBlocked = 1;
|
|
}
|
|
else if(strcmp(":unblock\r",rx) == 0){
|
|
USART_putstring(rx);
|
|
USART_putstring("\r\nManual override: crossing is clear\r\n");
|
|
isBlocked = 0;
|
|
iflag = -1;
|
|
trg0 = trg1 = 0; //set state to clear, reset int_fired flag and trigger counts
|
|
}
|
|
else {
|
|
USART_putstring(rx);
|
|
USART_putstring("\r\n Unknown Command\r\n");
|
|
}
|
|
rxCmd=0;
|
|
cnt=0;
|
|
break;
|
|
default:
|
|
USART_putstring(rx);
|
|
USART_putstring("\r\n");
|
|
cnt=0; //echo entered characters and reset the buffer by default
|
|
break;
|
|
};
|
|
};
|
|
}
|