xingcontrol/usart.c
2019-10-18 22:08:59 +02:00

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;
};
};
}