GPS driver implemented
This commit is contained in:
parent
07b589fe3f
commit
4827565bc8
5
Makefile
5
Makefile
|
@ -6,7 +6,7 @@ TARGET = images/OpenModem
|
|||
OPT = s
|
||||
FORMAT = ihex
|
||||
|
||||
SRC = main.c hardware/Serial.c hardware/AFSK.c hardware/VREF.c hardware/LED.c hardware/UserIO.c hardware/SD.c hardware/sdcard/diskio.c hardware/sdcard/ff.c hardware/sdcard/ffsystem.c hardware/sdcard/ffunicode.c hardware/Bluetooth.c util/CRC-CCIT.c protocol/AX25.c protocol/KISS.c
|
||||
SRC = main.c hardware/Serial.c hardware/AFSK.c hardware/VREF.c hardware/LED.c hardware/UserIO.c hardware/SD.c hardware/sdcard/diskio.c hardware/sdcard/ff.c hardware/sdcard/ffsystem.c hardware/sdcard/ffunicode.c hardware/Bluetooth.c hardware/GPS.c util/CRC-CCIT.c protocol/AX25.c protocol/KISS.c
|
||||
|
||||
|
||||
# List Assembler source files here.
|
||||
|
@ -36,10 +36,11 @@ CFLAGS += -std=gnu99
|
|||
ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs
|
||||
|
||||
# Optional linker flags.
|
||||
# Previous: LDFLAGS = -Wl,-Map=$(TARGET).map,--cref
|
||||
# -Wl,...: tell GCC to pass this to linker.
|
||||
# -Map: create map file
|
||||
# --cref: add cross reference to map file
|
||||
LDFLAGS = -Wl,-Map=$(TARGET).map,--cref
|
||||
LDFLAGS = -Wl,-u,vfprintf,-lprintf_flt,-Map=$(TARGET).map,--cref
|
||||
|
||||
# Additional libraries
|
||||
LDFLAGS += -lm
|
||||
|
|
10
device.h
10
device.h
|
@ -27,7 +27,8 @@
|
|||
#define TX_MAXWAIT 2UL
|
||||
#define CONFIG_QUEUE_SIZE 6000 // TODO: Optimise this by saving ram other places, add SD queue
|
||||
#define CONFIG_QUEUE_MAX_LENGTH 15
|
||||
#define CONFIG_SERIAL_BUFFER_SIZE 1536 // TODO: Tune this, what is actually required?
|
||||
#define CONFIG_UART0_BUFFER_SIZE 1536 // TODO: Tune this, what is actually required?
|
||||
#define CONFIG_UART1_BUFFER_SIZE 128
|
||||
#define CONFIG_SERIAL_TIMEOUT_MS 10
|
||||
#define CONFIG_BENCHMARK_MODE false
|
||||
|
||||
|
@ -80,6 +81,11 @@
|
|||
#define BT_MODE 3
|
||||
#define BT_RTS 4
|
||||
|
||||
#define GPS_DDR DDRA
|
||||
#define GPS_PORT PORTA
|
||||
#define GPS_INPUT PINA
|
||||
#define GPS_EN_PIN 5
|
||||
|
||||
#define USR_IO_DDR DDRA
|
||||
#define USR_IO_PORT PORTA
|
||||
#define USR_IO_1 1
|
||||
|
@ -91,7 +97,6 @@
|
|||
#endif
|
||||
|
||||
/*
|
||||
|
||||
PA0 ANALOG_IN
|
||||
PA1 USR_1
|
||||
PA2 USR_2
|
||||
|
@ -127,5 +132,4 @@ PD4 PTT_NEG
|
|||
PD5 PTT_SIG
|
||||
PD6 REF_DAC
|
||||
PD7 REF_ADC
|
||||
|
||||
*/
|
|
@ -13,7 +13,7 @@ void bluetooth_init(void) {
|
|||
// Check module RTS pin is pulled low
|
||||
if (!(BT_INPUT &_BV(BT_RTS))) {
|
||||
// Reconfigure UART to 9600 baud and issue reset
|
||||
serial_setbaudrate_9600();
|
||||
serial_setbaudrate_9600(0);
|
||||
delay_ms(BT_AT_DELAY*2);
|
||||
printf(PSTR("AT"));
|
||||
printf(PSTR("AT+FACTORYRESET\r\n"));
|
||||
|
|
|
@ -0,0 +1,289 @@
|
|||
#include "GPS.h"
|
||||
|
||||
Serial *serial;
|
||||
|
||||
bool gps_installed = false;
|
||||
bool gps_power = true;
|
||||
|
||||
uint8_t nmea_read_length = 0;
|
||||
char nmea_input_buf[NMEA_MAX_LENGTH];
|
||||
char nmea_parse_buf[NMEA_MAX_LENGTH];
|
||||
|
||||
bool gps_detect(void) {
|
||||
GPS_DDR &= ~_BV(GPS_EN_PIN);
|
||||
return (GPS_INPUT & _BV(GPS_EN_PIN));
|
||||
}
|
||||
|
||||
void gps_powerup(void) {
|
||||
GPS_PORT |= _BV(GPS_EN_PIN);
|
||||
}
|
||||
|
||||
void gps_powerdown(void) {
|
||||
GPS_PORT &= ~_BV(GPS_EN_PIN);
|
||||
}
|
||||
|
||||
bool gps_enabled(void) {
|
||||
return gps_power;
|
||||
}
|
||||
|
||||
void gps_init(Serial *ser) {
|
||||
serial = ser;
|
||||
memset(nmea_input_buf, 0, sizeof(nmea_input_buf));
|
||||
memset(nmea_parse_buf, 0, sizeof(nmea_parse_buf));
|
||||
|
||||
gps_speed_knots = 0;
|
||||
gps_speed_kmh = 0;
|
||||
gps_bearing = 0;
|
||||
|
||||
if (gps_detect()) {
|
||||
gps_installed = true;
|
||||
|
||||
serial_setbaudrate_9600(1);
|
||||
gps_send_command(PMTK_SET_BAUD_57600);
|
||||
serial_setbaudrate_57600(1);
|
||||
|
||||
gps_send_command(PMTK_API_SET_FIX_CTL_1HZ);
|
||||
gps_send_command(PMTK_SET_NMEA_OUTPUT_RMCGGA);
|
||||
|
||||
GPS_DDR |= _BV(GPS_EN_PIN);
|
||||
if (gps_enabled()) { gps_powerup(); } else { gps_powerdown(); }
|
||||
|
||||
} else {
|
||||
gps_installed = false;
|
||||
gps_power = false;
|
||||
}
|
||||
}
|
||||
|
||||
void gps_update_rtc(void) {
|
||||
// TODO: implement this
|
||||
}
|
||||
|
||||
void gps_jobs(void) {
|
||||
if (gps_enabled()) { gps_powerup(); } else { gps_powerdown(); }
|
||||
}
|
||||
|
||||
void gps_send_command(const char *cmd) {
|
||||
fprintf_P(&serial->uart1, cmd);
|
||||
}
|
||||
|
||||
void gps_nmea_parse(uint8_t sentence_length) {
|
||||
if (sentence_length > 4) {
|
||||
if (nmea_parse_buf[sentence_length-4] == '*') {
|
||||
uint16_t checksum = gps_nmea_parse_hex(nmea_parse_buf[sentence_length-3]);
|
||||
checksum *= 16;
|
||||
checksum += gps_nmea_parse_hex(nmea_parse_buf[sentence_length-2]);
|
||||
|
||||
for (uint8_t i=1; i < sentence_length-4; i++) {
|
||||
checksum ^= nmea_parse_buf[i];
|
||||
}
|
||||
|
||||
if (checksum != 0) {
|
||||
return;
|
||||
} else {
|
||||
// Parse GGA sentence
|
||||
if (strstr(nmea_parse_buf, "$GPGGA")) {
|
||||
char *pointer = nmea_parse_buf;
|
||||
|
||||
// Parse UTC time
|
||||
pointer = strchr(pointer, ',')+1;
|
||||
uint32_t nmea_time = (float)atof(pointer);
|
||||
|
||||
// Parse latitude
|
||||
pointer = strchr(pointer, ',')+1;
|
||||
char nmea_lat_deg_str[3];
|
||||
nmea_lat_deg_str[0] = pointer[0];
|
||||
nmea_lat_deg_str[1] = pointer[1];
|
||||
nmea_lat_deg_str[2] = '\0';
|
||||
|
||||
char nmea_lat_min_str[3];
|
||||
nmea_lat_min_str[0] = pointer[2];
|
||||
nmea_lat_min_str[1] = pointer[3];
|
||||
nmea_lat_min_str[2] = '\0';
|
||||
|
||||
char nmea_lat_dec_str[5];
|
||||
nmea_lat_dec_str[0] = pointer[5];
|
||||
nmea_lat_dec_str[1] = pointer[6];
|
||||
nmea_lat_dec_str[2] = pointer[7];
|
||||
nmea_lat_dec_str[3] = pointer[8];
|
||||
nmea_lat_dec_str[4] = '\0';
|
||||
|
||||
// Parse latitude sign
|
||||
pointer = strchr(pointer, ',')+1;
|
||||
char nmea_lat_sign = pointer[0];
|
||||
|
||||
// Parse longtitude
|
||||
pointer = strchr(pointer, ',')+1;
|
||||
char nmea_lon_deg_str[4];
|
||||
nmea_lon_deg_str[0] = pointer[0];
|
||||
nmea_lon_deg_str[1] = pointer[1];
|
||||
nmea_lon_deg_str[2] = pointer[2];
|
||||
nmea_lon_deg_str[3] = '\0';
|
||||
|
||||
char nmea_lon_min_str[3];
|
||||
nmea_lon_min_str[0] = pointer[3];
|
||||
nmea_lon_min_str[1] = pointer[4];
|
||||
nmea_lon_min_str[2] = '\0';
|
||||
|
||||
char nmea_lon_dec_str[5];
|
||||
nmea_lon_dec_str[0] = pointer[6];
|
||||
nmea_lon_dec_str[1] = pointer[7];
|
||||
nmea_lon_dec_str[2] = pointer[8];
|
||||
nmea_lon_dec_str[3] = pointer[9];
|
||||
nmea_lon_dec_str[4] = '\0';
|
||||
|
||||
// Parse longtitude sign
|
||||
pointer = strchr(pointer, ',')+1;
|
||||
char nmea_lon_sign = pointer[0];
|
||||
|
||||
// Get fix quality
|
||||
pointer = strchr(pointer, ',')+1;
|
||||
uint8_t nmea_fix = atoi(pointer);
|
||||
if (nmea_fix == 1) {
|
||||
gps_fix = true;
|
||||
} else {
|
||||
gps_fix = false;
|
||||
}
|
||||
|
||||
if (gps_fix) {
|
||||
// Set times
|
||||
gps_t_hour = nmea_time / 10000;
|
||||
gps_t_minute = (nmea_time % 10000) / 100;
|
||||
gps_t_second = (nmea_time % 100);
|
||||
gps_update_rtc();
|
||||
|
||||
// Set latitude and longtitude
|
||||
gps_lat_degrees = atoi(nmea_lat_deg_str);
|
||||
gps_lat_minutes = atoi(nmea_lat_min_str);
|
||||
gps_lat_seconds = (atoi(nmea_lat_dec_str)/10000.0)*60.0;
|
||||
gps_lon_degrees = atoi(nmea_lon_deg_str);
|
||||
gps_lon_minutes = atoi(nmea_lon_min_str);
|
||||
gps_lon_seconds = (atoi(nmea_lon_dec_str)/10000.0)*60.0;
|
||||
gps_lat = gps_lat_degrees + (gps_lat_minutes/60.0) + (gps_lat_seconds/3600.0);
|
||||
gps_lon = gps_lon_degrees + (gps_lon_minutes/60.0) + (gps_lon_seconds/3600.0);
|
||||
|
||||
// Get satellites
|
||||
pointer = strchr(pointer, ',')+1;
|
||||
gps_sats = atoi(pointer);
|
||||
|
||||
// Get horizontal dilution of position
|
||||
pointer = strchr(pointer, ',')+1;
|
||||
gps_hdop = atof(pointer);
|
||||
|
||||
// Get altitude
|
||||
pointer = strchr(pointer, ',')+1;
|
||||
gps_altitude = atof(pointer);
|
||||
|
||||
// Ignore altitude unit reference
|
||||
pointer = strchr(pointer, ',')+1;
|
||||
|
||||
// Get geoid height
|
||||
pointer = strchr(pointer, ',')+1;
|
||||
gps_geoid_height = atof(pointer);
|
||||
// TODO: Check this calculation
|
||||
gps_height_above_msl = gps_geoid_height + gps_altitude;
|
||||
|
||||
// Ignore geoid height unit reference
|
||||
pointer = strchr(pointer, ',')+1;
|
||||
|
||||
gps_lat_sign = nmea_lat_sign;
|
||||
gps_lon_sign = nmea_lon_sign;
|
||||
gps_lat *= (gps_lat_sign == 'N' ? 1 : -1);
|
||||
gps_lon *= (gps_lon_sign == 'E' ? 1 : -1);
|
||||
|
||||
// TODO: Remove this
|
||||
// if (gps_fix) {
|
||||
// printf("GPS fix: %d\r\n", nmea_fix);
|
||||
// printf("GPS satellites: %d\r\n", gps_sats);
|
||||
// printf("GPS latitude: %d\" %d' %.2fs %c\r\n", gps_lat_degrees, gps_lat_minutes, gps_lat_seconds, gps_lat_sign);
|
||||
// printf("GPS longtitude: %d\" %d' %.2fs %c\r\n", gps_lon_degrees, gps_lon_minutes, gps_lon_seconds, gps_lon_sign);
|
||||
// printf("GPS coords: %.6f,%.6f\r\n", gps_lat, gps_lon);
|
||||
// printf("GPS speed %.2f Km/h\r\n", gps_speed_kmh);
|
||||
// printf("GPS speed %.2f knots\r\n", gps_speed_knots);
|
||||
// printf("GPS bearing %.2f\r\n", gps_bearing);
|
||||
// printf("GPS height above MSL: %.2f\r\n", gps_height_above_msl);
|
||||
// printf("GPS altitude: %.2f\r\n", gps_altitude);
|
||||
// printf("GPS geoid height: %.2f\r\n", gps_geoid_height);
|
||||
// printf("GPS HDOP: %.2f\r\n", gps_hdop);
|
||||
// printf("GPS time %d:%d:%d UTC\r\n", gps_t_hour, gps_t_minute, gps_t_second);
|
||||
// } else {
|
||||
// printf("No GPS fix");
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
// Parse RMC sentence
|
||||
if (strstr(nmea_parse_buf, "$GPRMC")) {
|
||||
if (gps_fix) {
|
||||
char *pointer = nmea_parse_buf;
|
||||
|
||||
// Ignore UTC time
|
||||
pointer = strchr(pointer, ',')+1;
|
||||
|
||||
// Ignore navigation receiver warning
|
||||
pointer = strchr(pointer, ',')+1;
|
||||
|
||||
// Ignore latitude
|
||||
pointer = strchr(pointer, ',')+1;
|
||||
|
||||
// Ignore latitude sign
|
||||
pointer = strchr(pointer, ',')+1;
|
||||
|
||||
// Ignore longtitude
|
||||
pointer = strchr(pointer, ',')+1;
|
||||
|
||||
// Ignore longtitude sign
|
||||
pointer = strchr(pointer, ',')+1;
|
||||
|
||||
// Get ground speed
|
||||
pointer = strchr(pointer, ',')+1;
|
||||
gps_speed_knots = atof(pointer);
|
||||
gps_speed_kmh = gps_speed_knots * 1.852;
|
||||
|
||||
// Get bearing
|
||||
pointer = strchr(pointer, ',')+1;
|
||||
gps_bearing = atof(pointer);
|
||||
} else {
|
||||
gps_speed_knots = 0;
|
||||
gps_speed_kmh = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void gps_serial_callback(char byte) {
|
||||
if (byte == '\n') {
|
||||
for (uint8_t i = 0; i < NMEA_MAX_LENGTH; i++)
|
||||
nmea_parse_buf[i] = nmea_input_buf[i];
|
||||
|
||||
memset(nmea_input_buf, 0, sizeof(nmea_input_buf));
|
||||
|
||||
gps_nmea_parse(nmea_read_length);
|
||||
nmea_read_length = 0;
|
||||
} else {
|
||||
if (nmea_read_length < NMEA_MAX_LENGTH) {
|
||||
nmea_input_buf[nmea_read_length++] = byte;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void gps_poll(void) {
|
||||
while (!fifo_isempty_locked(&uart1FIFO)) {
|
||||
char sbyte = fifo_pop_locked(&uart1FIFO);
|
||||
gps_serial_callback(sbyte);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t gps_nmea_parse_hex(char c) {
|
||||
if (c < '0')
|
||||
return 0;
|
||||
if (c <= '9')
|
||||
return c - '0';
|
||||
if (c < 'A')
|
||||
return 0;
|
||||
if (c <= 'F')
|
||||
return (c - 'A')+10;
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
#ifndef GPS_H
|
||||
#define GPS_H
|
||||
|
||||
#include <avr/io.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include "device.h"
|
||||
#include "util/time.h"
|
||||
#include "hardware/serial.h"
|
||||
|
||||
#define NMEA_MAX_LENGTH 128
|
||||
|
||||
#define PMTK_SET_BAUD_57600 PSTR("$PMTK251,57600*2C\r\n")
|
||||
#define PMTK_SET_BAUD_9600 PSTR("$PMTK251,9600*17\r\n")
|
||||
#define PMTK_SET_NMEA_OUTPUT_RMCONLY PSTR("$PMTK314,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*29\r\n")
|
||||
#define PMTK_SET_NMEA_OUTPUT_RMCGGA PSTR("$PMTK314,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*28\r\n")
|
||||
#define PMTK_SET_NMEA_OUTPUT_NONE PSTR("$PMTK314,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*28\r\n")
|
||||
#define PMTK_SET_NMEA_OUTPUT_ALL PSTR("$PMTK314,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0*28\r\n")
|
||||
#define PMTK_API_SET_FIX_CTL_200_mHZ PSTR("$PMTK300,5000,0,0,0,0*18\r\n")
|
||||
#define PMTK_API_SET_FIX_CTL_1HZ PSTR("$PMTK300,1000,0,0,0,0*1C\r\n")
|
||||
#define PGCMD_ANTENNA PSTR("$PGCMD,33,1*6C\r\n")
|
||||
#define PGCMD_NOANTENNA PSTR("$PGCMD,33,0*6D\r\n")
|
||||
|
||||
void gps_init(Serial *ser);
|
||||
bool gps_enabled(void);
|
||||
void gps_poll(void);
|
||||
void gps_jobs(void);
|
||||
void gps_send_command(const char *cmd);
|
||||
uint8_t gps_parse_nmea(char *nmea);
|
||||
uint8_t gps_nmea_parse_hex(char c);
|
||||
|
||||
uint8_t gps_t_year;
|
||||
uint8_t gps_t_month;
|
||||
uint8_t gps_t_day;
|
||||
uint8_t gps_t_hour;
|
||||
uint8_t gps_t_minute;
|
||||
uint8_t gps_t_second;
|
||||
|
||||
int gps_lat_degrees;
|
||||
int gps_lat_minutes;
|
||||
float gps_lat_seconds;
|
||||
float gps_lat;
|
||||
|
||||
int gps_lon_degrees;
|
||||
int gps_lon_minutes;
|
||||
float gps_lon_seconds;
|
||||
float gps_lon;
|
||||
|
||||
float gps_geoid_height;
|
||||
float gps_altitude;
|
||||
float gps_height_above_msl;
|
||||
float gps_speed_knots;
|
||||
float gps_speed_kmh;
|
||||
float gps_speed_mph;
|
||||
float gps_bearing;
|
||||
float gps_magvariation;
|
||||
float gps_hdop;
|
||||
char gps_lat_sign;
|
||||
char gps_lon_sign;
|
||||
char gps_mag_char;
|
||||
bool gps_fix;
|
||||
uint8_t gps_fix_quality;
|
||||
uint8_t gps_sats;
|
||||
|
||||
#endif
|
|
@ -6,25 +6,36 @@ extern volatile uint8_t queue_height;
|
|||
|
||||
void serial_init(Serial *serial) {
|
||||
memset(serial, 0, sizeof(*serial));
|
||||
memset(serialBuf, 0, sizeof(serialBuf));
|
||||
memset(uart0Buf, 0, sizeof(uart0Buf));
|
||||
memset(uart1Buf, 0, sizeof(uart1Buf));
|
||||
|
||||
serial_setbaudrate_115200();
|
||||
serial_setbaudrate_115200(0);
|
||||
serial_setbaudrate_115200(1);
|
||||
|
||||
// Set to 8-bit data, enable RX and TX, enable receive interrupt
|
||||
UCSR0C = _BV(UCSZ01) | _BV(UCSZ00);
|
||||
UCSR0B = _BV(RXEN0) | _BV(TXEN0) | _BV(RXCIE0);
|
||||
|
||||
UCSR1C = _BV(UCSZ11) | _BV(UCSZ10);
|
||||
UCSR1B = _BV(RXEN1) | _BV(TXEN1) | _BV(RXCIE1);
|
||||
|
||||
FILE uart0_fd = FDEV_SETUP_STREAM(uart0_putchar, uart0_getchar, _FDEV_SETUP_RW);
|
||||
FILE uart1_fd = FDEV_SETUP_STREAM(uart1_putchar, uart1_getchar, _FDEV_SETUP_RW);
|
||||
|
||||
serial->uart0 = uart0_fd;
|
||||
serial->uart1 = uart1_fd;
|
||||
|
||||
fifo_init(&serialFIFO, serialBuf, sizeof(serialBuf));
|
||||
fifo_init(&uart0FIFO, uart0Buf, sizeof(uart0Buf));
|
||||
fifo_init(&uart1FIFO, uart1Buf, sizeof(uart1Buf));
|
||||
}
|
||||
|
||||
bool serial_available(uint8_t index) {
|
||||
if (index == 0) {
|
||||
if (UCSR0A & _BV(RXC0)) return true;
|
||||
} else if (index == 1) {
|
||||
if (UCSR1A & _BV(RXC1)) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -38,167 +49,302 @@ int uart0_putchar(char c, FILE *stream) {
|
|||
|
||||
int uart0_getchar(FILE *stream) {
|
||||
loop_until_bit_is_set(UCSR0A, RXC0);
|
||||
LED_COM_ON();
|
||||
return UDR0;
|
||||
}
|
||||
|
||||
char uart0_getchar_nowait(void) {
|
||||
if (!(UCSR0A & _BV(RXC0))) return EOF;
|
||||
LED_COM_ON();
|
||||
return UDR0;
|
||||
}
|
||||
|
||||
int uart1_putchar(char c, FILE *stream) {
|
||||
loop_until_bit_is_set(UCSR1A, UDRE1);
|
||||
UDR1 = c;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int uart1_getchar(FILE *stream) {
|
||||
loop_until_bit_is_set(UCSR1A, RXC1);
|
||||
return UDR1;
|
||||
}
|
||||
|
||||
char uart1_getchar_nowait(void) {
|
||||
if (!(UCSR1A & _BV(RXC1))) return EOF;
|
||||
return UDR1;
|
||||
}
|
||||
|
||||
ISR(USART0_RX_vect) {
|
||||
if (serial_available(0)) {
|
||||
LED_COM_ON();
|
||||
if (!fifo_isfull(&serialFIFO)) {
|
||||
if (!fifo_isfull(&uart0FIFO)) {
|
||||
char c = uart0_getchar_nowait();
|
||||
fifo_push(&serialFIFO, c);
|
||||
fifo_push(&uart0FIFO, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void serial_setbaudrate_1200(void) {
|
||||
ISR(USART1_RX_vect) {
|
||||
if (serial_available(1)) {
|
||||
if (!fifo_isfull(&uart1FIFO)) {
|
||||
char c = uart1_getchar_nowait();
|
||||
fifo_push(&uart1FIFO, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void serial_setbaudrate_1200(uint8_t port) {
|
||||
#undef BAUD
|
||||
#define BAUD 1200
|
||||
#include <util/setbaud.h>
|
||||
if (port == 0) {
|
||||
UBRR0H = UBRRH_VALUE; UBRR0L = UBRRL_VALUE;
|
||||
#if USE_2X
|
||||
UCSR0A |= _BV(U2X0);
|
||||
#else
|
||||
UCSR0A &= ~(_BV(U2X0));
|
||||
#endif
|
||||
} else if (port == 1) {
|
||||
UBRR1H = UBRRH_VALUE; UBRR1L = UBRRL_VALUE;
|
||||
#if USE_2X
|
||||
UCSR1A |= _BV(U2X0);
|
||||
#else
|
||||
UCSR1A &= ~(_BV(U2X0));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void serial_setbaudrate_2400(void) {
|
||||
void serial_setbaudrate_2400(uint8_t port) {
|
||||
#undef BAUD
|
||||
#define BAUD 2400
|
||||
#include <util/setbaud.h>
|
||||
if (port == 0) {
|
||||
UBRR0H = UBRRH_VALUE; UBRR0L = UBRRL_VALUE;
|
||||
#if USE_2X
|
||||
UCSR0A |= _BV(U2X0);
|
||||
#else
|
||||
UCSR0A &= ~(_BV(U2X0));
|
||||
#endif
|
||||
} else if (port == 1) {
|
||||
UBRR1H = UBRRH_VALUE; UBRR1L = UBRRL_VALUE;
|
||||
#if USE_2X
|
||||
UCSR1A |= _BV(U2X0);
|
||||
#else
|
||||
UCSR1A &= ~(_BV(U2X0));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void serial_setbaudrate_4800(void) {
|
||||
void serial_setbaudrate_4800(uint8_t port) {
|
||||
#undef BAUD
|
||||
#define BAUD 4800
|
||||
#include <util/setbaud.h>
|
||||
if (port == 0) {
|
||||
UBRR0H = UBRRH_VALUE; UBRR0L = UBRRL_VALUE;
|
||||
#if USE_2X
|
||||
UCSR0A |= _BV(U2X0);
|
||||
#else
|
||||
UCSR0A &= ~(_BV(U2X0));
|
||||
#endif
|
||||
} else if (port == 1) {
|
||||
UBRR1H = UBRRH_VALUE; UBRR1L = UBRRL_VALUE;
|
||||
#if USE_2X
|
||||
UCSR1A |= _BV(U2X0);
|
||||
#else
|
||||
UCSR1A &= ~(_BV(U2X0));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void serial_setbaudrate_9600(void) {
|
||||
void serial_setbaudrate_9600(uint8_t port) {
|
||||
#undef BAUD
|
||||
#define BAUD 9600
|
||||
#include <util/setbaud.h>
|
||||
if (port == 0) {
|
||||
UBRR0H = UBRRH_VALUE; UBRR0L = UBRRL_VALUE;
|
||||
#if USE_2X
|
||||
UCSR0A |= _BV(U2X0);
|
||||
#else
|
||||
UCSR0A &= ~(_BV(U2X0));
|
||||
#endif
|
||||
} else if (port == 1) {
|
||||
UBRR1H = UBRRH_VALUE; UBRR1L = UBRRL_VALUE;
|
||||
#if USE_2X
|
||||
UCSR1A |= _BV(U2X0);
|
||||
#else
|
||||
UCSR1A &= ~(_BV(U2X0));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void serial_setbaudrate_14400(void) {
|
||||
void serial_setbaudrate_14400(uint8_t port) {
|
||||
#undef BAUD
|
||||
#define BAUD 14400
|
||||
#include <util/setbaud.h>
|
||||
if (port == 0) {
|
||||
UBRR0H = UBRRH_VALUE; UBRR0L = UBRRL_VALUE;
|
||||
#if USE_2X
|
||||
UCSR0A |= _BV(U2X0);
|
||||
#else
|
||||
UCSR0A &= ~(_BV(U2X0));
|
||||
#endif
|
||||
} else if (port == 1) {
|
||||
UBRR1H = UBRRH_VALUE; UBRR1L = UBRRL_VALUE;
|
||||
#if USE_2X
|
||||
UCSR1A |= _BV(U2X0);
|
||||
#else
|
||||
UCSR1A &= ~(_BV(U2X0));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void serial_setbaudrate_19200(void) {
|
||||
void serial_setbaudrate_19200(uint8_t port) {
|
||||
#undef BAUD
|
||||
#define BAUD 19200
|
||||
#include <util/setbaud.h>
|
||||
if (port == 0) {
|
||||
UBRR0H = UBRRH_VALUE; UBRR0L = UBRRL_VALUE;
|
||||
#if USE_2X
|
||||
UCSR0A |= _BV(U2X0);
|
||||
#else
|
||||
UCSR0A &= ~(_BV(U2X0));
|
||||
#endif
|
||||
} else if (port == 1) {
|
||||
UBRR1H = UBRRH_VALUE; UBRR1L = UBRRL_VALUE;
|
||||
#if USE_2X
|
||||
UCSR1A |= _BV(U2X0);
|
||||
#else
|
||||
UCSR1A &= ~(_BV(U2X0));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void serial_setbaudrate_28800(void) {
|
||||
void serial_setbaudrate_28800(uint8_t port) {
|
||||
#undef BAUD
|
||||
#define BAUD 28800
|
||||
#include <util/setbaud.h>
|
||||
if (port == 0) {
|
||||
UBRR0H = UBRRH_VALUE; UBRR0L = UBRRL_VALUE;
|
||||
#if USE_2X
|
||||
UCSR0A |= _BV(U2X0);
|
||||
#else
|
||||
UCSR0A &= ~(_BV(U2X0));
|
||||
#endif
|
||||
} else if (port == 1) {
|
||||
UBRR1H = UBRRH_VALUE; UBRR1L = UBRRL_VALUE;
|
||||
#if USE_2X
|
||||
UCSR1A |= _BV(U2X0);
|
||||
#else
|
||||
UCSR1A &= ~(_BV(U2X0));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void serial_setbaudrate_38400(void) {
|
||||
void serial_setbaudrate_38400(uint8_t port) {
|
||||
#undef BAUD
|
||||
#define BAUD 38400
|
||||
#include <util/setbaud.h>
|
||||
if (port == 0) {
|
||||
UBRR0H = UBRRH_VALUE; UBRR0L = UBRRL_VALUE;
|
||||
#if USE_2X
|
||||
UCSR0A |= _BV(U2X0);
|
||||
#else
|
||||
UCSR0A &= ~(_BV(U2X0));
|
||||
#endif
|
||||
} else if (port == 1) {
|
||||
UBRR1H = UBRRH_VALUE; UBRR1L = UBRRL_VALUE;
|
||||
#if USE_2X
|
||||
UCSR1A |= _BV(U2X0);
|
||||
#else
|
||||
UCSR1A &= ~(_BV(U2X0));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void serial_setbaudrate_57600(void) {
|
||||
void serial_setbaudrate_57600(uint8_t port) {
|
||||
#undef BAUD
|
||||
#define BAUD 57600
|
||||
#include <util/setbaud.h>
|
||||
if (port == 0) {
|
||||
UBRR0H = UBRRH_VALUE; UBRR0L = UBRRL_VALUE;
|
||||
#if USE_2X
|
||||
UCSR0A |= _BV(U2X0);
|
||||
#else
|
||||
UCSR0A &= ~(_BV(U2X0));
|
||||
#endif
|
||||
} else if (port == 1) {
|
||||
UBRR1H = UBRRH_VALUE; UBRR1L = UBRRL_VALUE;
|
||||
#if USE_2X
|
||||
UCSR1A |= _BV(U2X0);
|
||||
#else
|
||||
UCSR1A &= ~(_BV(U2X0));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void serial_setbaudrate_76800(void) {
|
||||
void serial_setbaudrate_76800(uint8_t port) {
|
||||
#undef BAUD
|
||||
#define BAUD 76800
|
||||
#include <util/setbaud.h>
|
||||
if (port == 0) {
|
||||
UBRR0H = UBRRH_VALUE; UBRR0L = UBRRL_VALUE;
|
||||
#if USE_2X
|
||||
UCSR0A |= _BV(U2X0);
|
||||
#else
|
||||
UCSR0A &= ~(_BV(U2X0));
|
||||
#endif
|
||||
} else if (port == 1) {
|
||||
UBRR1H = UBRRH_VALUE; UBRR1L = UBRRL_VALUE;
|
||||
#if USE_2X
|
||||
UCSR1A |= _BV(U2X0);
|
||||
#else
|
||||
UCSR1A &= ~(_BV(U2X0));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void serial_setbaudrate_115200(void) {
|
||||
void serial_setbaudrate_115200(uint8_t port) {
|
||||
#undef BAUD
|
||||
#define BAUD 115200
|
||||
#include <util/setbaud.h>
|
||||
if (port == 0) {
|
||||
UBRR0H = UBRRH_VALUE; UBRR0L = UBRRL_VALUE;
|
||||
#if USE_2X
|
||||
UCSR0A |= _BV(U2X0);
|
||||
#else
|
||||
UCSR0A &= ~(_BV(U2X0));
|
||||
#endif
|
||||
} else if (port == 1) {
|
||||
UBRR1H = UBRRH_VALUE; UBRR1L = UBRRL_VALUE;
|
||||
#if USE_2X
|
||||
UCSR1A |= _BV(U2X0);
|
||||
#else
|
||||
UCSR1A &= ~(_BV(U2X0));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void serial_setbaudrate_230400(void) {
|
||||
void serial_setbaudrate_230400(uint8_t port) {
|
||||
#undef BAUD
|
||||
#define BAUD 230400
|
||||
#include <util/setbaud.h>
|
||||
if (port == 0) {
|
||||
UBRR0H = UBRRH_VALUE; UBRR0L = UBRRL_VALUE;
|
||||
#if USE_2X
|
||||
UCSR0A |= _BV(U2X0);
|
||||
#else
|
||||
UCSR0A &= ~(_BV(U2X0));
|
||||
#endif
|
||||
} else if (port == 1) {
|
||||
UBRR1H = UBRRH_VALUE; UBRR1L = UBRRL_VALUE;
|
||||
#if USE_2X
|
||||
UCSR1A |= _BV(U2X0);
|
||||
#else
|
||||
UCSR1A &= ~(_BV(U2X0));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,28 +11,37 @@
|
|||
|
||||
typedef struct Serial {
|
||||
FILE uart0;
|
||||
FILE uart1;
|
||||
} Serial;
|
||||
|
||||
FIFOBuffer serialFIFO;
|
||||
uint8_t serialBuf[CONFIG_SERIAL_BUFFER_SIZE];
|
||||
FIFOBuffer uart0FIFO;
|
||||
uint8_t uart0Buf[CONFIG_UART0_BUFFER_SIZE];
|
||||
|
||||
FIFOBuffer uart1FIFO;
|
||||
uint8_t uart1Buf[CONFIG_UART1_BUFFER_SIZE];
|
||||
|
||||
void serial_init(Serial *serial);
|
||||
bool serial_available(uint8_t index);
|
||||
|
||||
int uart0_putchar(char c, FILE *stream);
|
||||
int uart0_getchar(FILE *stream);
|
||||
char uart0_getchar_nowait(void);
|
||||
|
||||
void serial_setbaudrate_1200(void);
|
||||
void serial_setbaudrate_2400(void);
|
||||
void serial_setbaudrate_4800(void);
|
||||
void serial_setbaudrate_9600(void);
|
||||
void serial_setbaudrate_14400(void);
|
||||
void serial_setbaudrate_19200(void);
|
||||
void serial_setbaudrate_28800(void);
|
||||
void serial_setbaudrate_38400(void);
|
||||
void serial_setbaudrate_57600(void);
|
||||
void serial_setbaudrate_76800(void);
|
||||
void serial_setbaudrate_115200(void);
|
||||
void serial_setbaudrate_230400(void);
|
||||
int uart1_putchar(char c, FILE *stream);
|
||||
int uart1_getchar(FILE *stream);
|
||||
char uart1_getchar_nowait(void);
|
||||
|
||||
void serial_setbaudrate_1200(uint8_t port);
|
||||
void serial_setbaudrate_2400(uint8_t port);
|
||||
void serial_setbaudrate_4800(uint8_t port);
|
||||
void serial_setbaudrate_9600(uint8_t port);
|
||||
void serial_setbaudrate_14400(uint8_t port);
|
||||
void serial_setbaudrate_19200(uint8_t port);
|
||||
void serial_setbaudrate_28800(uint8_t port);
|
||||
void serial_setbaudrate_38400(uint8_t port);
|
||||
void serial_setbaudrate_57600(uint8_t port);
|
||||
void serial_setbaudrate_76800(uint8_t port);
|
||||
void serial_setbaudrate_115200(uint8_t port);
|
||||
void serial_setbaudrate_230400(uint8_t port);
|
||||
|
||||
#endif
|
|
@ -3,7 +3,9 @@
|
|||
|
||||
void usrio_init(void) {
|
||||
USR_IO_DDR |= _BV(USR_IO_1) | _BV(USR_IO_2);
|
||||
// TODO: Add BT module detect and set up other pins accordingly
|
||||
if (!bluetooth_enabled()) {
|
||||
USR_IO_DDR |= _BV(USR_IO_3) | _BV(USR_IO_4);
|
||||
}
|
||||
}
|
||||
|
||||
bool usrio_1(void) {
|
||||
|
|
3
main.c
3
main.c
|
@ -14,6 +14,7 @@
|
|||
#include "hardware/UserIO.h"
|
||||
#include "hardware/SD.h"
|
||||
#include "hardware/Bluetooth.h"
|
||||
#include "hardware/GPS.h"
|
||||
#include "protocol/AX25.h"
|
||||
#include "protocol/KISS.h"
|
||||
#include "util/time.h"
|
||||
|
@ -69,6 +70,7 @@ void init(void) {
|
|||
kiss_init(&AX25, &modem, &serial);
|
||||
sd_init();
|
||||
bluetooth_init();
|
||||
gps_init(&serial);
|
||||
usrio_init();
|
||||
|
||||
system_check();
|
||||
|
@ -83,6 +85,7 @@ int main (void) {
|
|||
kiss_poll();
|
||||
kiss_csma();
|
||||
sd_jobs();
|
||||
gps_poll();
|
||||
}
|
||||
|
||||
return(0);
|
||||
|
|
|
@ -50,8 +50,8 @@ void kiss_init(AX25Ctx *ax25, Afsk *afsk, Serial *ser) {
|
|||
}
|
||||
|
||||
void kiss_poll(void) {
|
||||
while (!fifo_isempty_locked(&serialFIFO)) {
|
||||
char sbyte = fifo_pop_locked(&serialFIFO);
|
||||
while (!fifo_isempty_locked(&uart0FIFO)) {
|
||||
char sbyte = fifo_pop_locked(&uart0FIFO);
|
||||
kiss_serialCallback(sbyte);
|
||||
last_serial_read = timer_clock();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue