GPS driver implemented

This commit is contained in:
Mark Qvist 2019-02-04 17:02:19 +01:00
parent 07b589fe3f
commit 4827565bc8
10 changed files with 634 additions and 113 deletions

View File

@ -6,7 +6,7 @@ TARGET = images/OpenModem
OPT = s OPT = s
FORMAT = ihex 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. # List Assembler source files here.
@ -36,10 +36,11 @@ CFLAGS += -std=gnu99
ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs
# Optional linker flags. # Optional linker flags.
# Previous: LDFLAGS = -Wl,-Map=$(TARGET).map,--cref
# -Wl,...: tell GCC to pass this to linker. # -Wl,...: tell GCC to pass this to linker.
# -Map: create map file # -Map: create map file
# --cref: add cross reference to 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 # Additional libraries
LDFLAGS += -lm LDFLAGS += -lm

View File

@ -27,7 +27,8 @@
#define TX_MAXWAIT 2UL #define TX_MAXWAIT 2UL
#define CONFIG_QUEUE_SIZE 6000 // TODO: Optimise this by saving ram other places, add SD queue #define CONFIG_QUEUE_SIZE 6000 // TODO: Optimise this by saving ram other places, add SD queue
#define CONFIG_QUEUE_MAX_LENGTH 15 #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_SERIAL_TIMEOUT_MS 10
#define CONFIG_BENCHMARK_MODE false #define CONFIG_BENCHMARK_MODE false
@ -80,6 +81,11 @@
#define BT_MODE 3 #define BT_MODE 3
#define BT_RTS 4 #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_DDR DDRA
#define USR_IO_PORT PORTA #define USR_IO_PORT PORTA
#define USR_IO_1 1 #define USR_IO_1 1
@ -91,7 +97,6 @@
#endif #endif
/* /*
PA0 ANALOG_IN PA0 ANALOG_IN
PA1 USR_1 PA1 USR_1
PA2 USR_2 PA2 USR_2
@ -127,5 +132,4 @@ PD4 PTT_NEG
PD5 PTT_SIG PD5 PTT_SIG
PD6 REF_DAC PD6 REF_DAC
PD7 REF_ADC PD7 REF_ADC
*/ */

View File

@ -13,7 +13,7 @@ void bluetooth_init(void) {
// Check module RTS pin is pulled low // Check module RTS pin is pulled low
if (!(BT_INPUT &_BV(BT_RTS))) { if (!(BT_INPUT &_BV(BT_RTS))) {
// Reconfigure UART to 9600 baud and issue reset // Reconfigure UART to 9600 baud and issue reset
serial_setbaudrate_9600(); serial_setbaudrate_9600(0);
delay_ms(BT_AT_DELAY*2); delay_ms(BT_AT_DELAY*2);
printf(PSTR("AT")); printf(PSTR("AT"));
printf(PSTR("AT+FACTORYRESET\r\n")); printf(PSTR("AT+FACTORYRESET\r\n"));

289
hardware/GPS.c Normal file
View File

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

67
hardware/GPS.h Normal file
View File

@ -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

View File

@ -6,25 +6,36 @@ extern volatile uint8_t queue_height;
void serial_init(Serial *serial) { void serial_init(Serial *serial) {
memset(serial, 0, sizeof(*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 // Set to 8-bit data, enable RX and TX, enable receive interrupt
UCSR0C = _BV(UCSZ01) | _BV(UCSZ00); UCSR0C = _BV(UCSZ01) | _BV(UCSZ00);
UCSR0B = _BV(RXEN0) | _BV(TXEN0) | _BV(RXCIE0); 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 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->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) { bool serial_available(uint8_t index) {
if (index == 0) { if (index == 0) {
if (UCSR0A & _BV(RXC0)) return true; if (UCSR0A & _BV(RXC0)) return true;
} else if (index == 1) {
if (UCSR1A & _BV(RXC1)) return true;
} }
return false; return false;
} }
@ -38,167 +49,302 @@ int uart0_putchar(char c, FILE *stream) {
int uart0_getchar(FILE *stream) { int uart0_getchar(FILE *stream) {
loop_until_bit_is_set(UCSR0A, RXC0); loop_until_bit_is_set(UCSR0A, RXC0);
LED_COM_ON();
return UDR0; return UDR0;
} }
char uart0_getchar_nowait(void) { char uart0_getchar_nowait(void) {
if (!(UCSR0A & _BV(RXC0))) return EOF; if (!(UCSR0A & _BV(RXC0))) return EOF;
LED_COM_ON();
return UDR0; 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) { ISR(USART0_RX_vect) {
if (serial_available(0)) { if (serial_available(0)) {
LED_COM_ON(); LED_COM_ON();
if (!fifo_isfull(&serialFIFO)) { if (!fifo_isfull(&uart0FIFO)) {
char c = uart0_getchar_nowait(); 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 #undef BAUD
#define BAUD 1200 #define BAUD 1200
#include <util/setbaud.h> #include <util/setbaud.h>
if (port == 0) {
UBRR0H = UBRRH_VALUE; UBRR0L = UBRRL_VALUE; UBRR0H = UBRRH_VALUE; UBRR0L = UBRRL_VALUE;
#if USE_2X #if USE_2X
UCSR0A |= _BV(U2X0); UCSR0A |= _BV(U2X0);
#else #else
UCSR0A &= ~(_BV(U2X0)); UCSR0A &= ~(_BV(U2X0));
#endif #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 #undef BAUD
#define BAUD 2400 #define BAUD 2400
#include <util/setbaud.h> #include <util/setbaud.h>
if (port == 0) {
UBRR0H = UBRRH_VALUE; UBRR0L = UBRRL_VALUE; UBRR0H = UBRRH_VALUE; UBRR0L = UBRRL_VALUE;
#if USE_2X #if USE_2X
UCSR0A |= _BV(U2X0); UCSR0A |= _BV(U2X0);
#else #else
UCSR0A &= ~(_BV(U2X0)); UCSR0A &= ~(_BV(U2X0));
#endif #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 #undef BAUD
#define BAUD 4800 #define BAUD 4800
#include <util/setbaud.h> #include <util/setbaud.h>
if (port == 0) {
UBRR0H = UBRRH_VALUE; UBRR0L = UBRRL_VALUE; UBRR0H = UBRRH_VALUE; UBRR0L = UBRRL_VALUE;
#if USE_2X #if USE_2X
UCSR0A |= _BV(U2X0); UCSR0A |= _BV(U2X0);
#else #else
UCSR0A &= ~(_BV(U2X0)); UCSR0A &= ~(_BV(U2X0));
#endif #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 #undef BAUD
#define BAUD 9600 #define BAUD 9600
#include <util/setbaud.h> #include <util/setbaud.h>
if (port == 0) {
UBRR0H = UBRRH_VALUE; UBRR0L = UBRRL_VALUE; UBRR0H = UBRRH_VALUE; UBRR0L = UBRRL_VALUE;
#if USE_2X #if USE_2X
UCSR0A |= _BV(U2X0); UCSR0A |= _BV(U2X0);
#else #else
UCSR0A &= ~(_BV(U2X0)); UCSR0A &= ~(_BV(U2X0));
#endif #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 #undef BAUD
#define BAUD 14400 #define BAUD 14400
#include <util/setbaud.h> #include <util/setbaud.h>
if (port == 0) {
UBRR0H = UBRRH_VALUE; UBRR0L = UBRRL_VALUE; UBRR0H = UBRRH_VALUE; UBRR0L = UBRRL_VALUE;
#if USE_2X #if USE_2X
UCSR0A |= _BV(U2X0); UCSR0A |= _BV(U2X0);
#else #else
UCSR0A &= ~(_BV(U2X0)); UCSR0A &= ~(_BV(U2X0));
#endif #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 #undef BAUD
#define BAUD 19200 #define BAUD 19200
#include <util/setbaud.h> #include <util/setbaud.h>
if (port == 0) {
UBRR0H = UBRRH_VALUE; UBRR0L = UBRRL_VALUE; UBRR0H = UBRRH_VALUE; UBRR0L = UBRRL_VALUE;
#if USE_2X #if USE_2X
UCSR0A |= _BV(U2X0); UCSR0A |= _BV(U2X0);
#else #else
UCSR0A &= ~(_BV(U2X0)); UCSR0A &= ~(_BV(U2X0));
#endif #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 #undef BAUD
#define BAUD 28800 #define BAUD 28800
#include <util/setbaud.h> #include <util/setbaud.h>
if (port == 0) {
UBRR0H = UBRRH_VALUE; UBRR0L = UBRRL_VALUE; UBRR0H = UBRRH_VALUE; UBRR0L = UBRRL_VALUE;
#if USE_2X #if USE_2X
UCSR0A |= _BV(U2X0); UCSR0A |= _BV(U2X0);
#else #else
UCSR0A &= ~(_BV(U2X0)); UCSR0A &= ~(_BV(U2X0));
#endif #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 #undef BAUD
#define BAUD 38400 #define BAUD 38400
#include <util/setbaud.h> #include <util/setbaud.h>
if (port == 0) {
UBRR0H = UBRRH_VALUE; UBRR0L = UBRRL_VALUE; UBRR0H = UBRRH_VALUE; UBRR0L = UBRRL_VALUE;
#if USE_2X #if USE_2X
UCSR0A |= _BV(U2X0); UCSR0A |= _BV(U2X0);
#else #else
UCSR0A &= ~(_BV(U2X0)); UCSR0A &= ~(_BV(U2X0));
#endif #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 #undef BAUD
#define BAUD 57600 #define BAUD 57600
#include <util/setbaud.h> #include <util/setbaud.h>
if (port == 0) {
UBRR0H = UBRRH_VALUE; UBRR0L = UBRRL_VALUE; UBRR0H = UBRRH_VALUE; UBRR0L = UBRRL_VALUE;
#if USE_2X #if USE_2X
UCSR0A |= _BV(U2X0); UCSR0A |= _BV(U2X0);
#else #else
UCSR0A &= ~(_BV(U2X0)); UCSR0A &= ~(_BV(U2X0));
#endif #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 #undef BAUD
#define BAUD 76800 #define BAUD 76800
#include <util/setbaud.h> #include <util/setbaud.h>
if (port == 0) {
UBRR0H = UBRRH_VALUE; UBRR0L = UBRRL_VALUE; UBRR0H = UBRRH_VALUE; UBRR0L = UBRRL_VALUE;
#if USE_2X #if USE_2X
UCSR0A |= _BV(U2X0); UCSR0A |= _BV(U2X0);
#else #else
UCSR0A &= ~(_BV(U2X0)); UCSR0A &= ~(_BV(U2X0));
#endif #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 #undef BAUD
#define BAUD 115200 #define BAUD 115200
#include <util/setbaud.h> #include <util/setbaud.h>
if (port == 0) {
UBRR0H = UBRRH_VALUE; UBRR0L = UBRRL_VALUE; UBRR0H = UBRRH_VALUE; UBRR0L = UBRRL_VALUE;
#if USE_2X #if USE_2X
UCSR0A |= _BV(U2X0); UCSR0A |= _BV(U2X0);
#else #else
UCSR0A &= ~(_BV(U2X0)); UCSR0A &= ~(_BV(U2X0));
#endif #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 #undef BAUD
#define BAUD 230400 #define BAUD 230400
#include <util/setbaud.h> #include <util/setbaud.h>
if (port == 0) {
UBRR0H = UBRRH_VALUE; UBRR0L = UBRRL_VALUE; UBRR0H = UBRRH_VALUE; UBRR0L = UBRRL_VALUE;
#if USE_2X #if USE_2X
UCSR0A |= _BV(U2X0); UCSR0A |= _BV(U2X0);
#else #else
UCSR0A &= ~(_BV(U2X0)); UCSR0A &= ~(_BV(U2X0));
#endif #endif
} else if (port == 1) {
UBRR1H = UBRRH_VALUE; UBRR1L = UBRRL_VALUE;
#if USE_2X
UCSR1A |= _BV(U2X0);
#else
UCSR1A &= ~(_BV(U2X0));
#endif
}
} }

View File

@ -11,28 +11,37 @@
typedef struct Serial { typedef struct Serial {
FILE uart0; FILE uart0;
FILE uart1;
} Serial; } Serial;
FIFOBuffer serialFIFO; FIFOBuffer uart0FIFO;
uint8_t serialBuf[CONFIG_SERIAL_BUFFER_SIZE]; uint8_t uart0Buf[CONFIG_UART0_BUFFER_SIZE];
FIFOBuffer uart1FIFO;
uint8_t uart1Buf[CONFIG_UART1_BUFFER_SIZE];
void serial_init(Serial *serial); void serial_init(Serial *serial);
bool serial_available(uint8_t index); bool serial_available(uint8_t index);
int uart0_putchar(char c, FILE *stream); int uart0_putchar(char c, FILE *stream);
int uart0_getchar(FILE *stream); int uart0_getchar(FILE *stream);
char uart0_getchar_nowait(void); char uart0_getchar_nowait(void);
void serial_setbaudrate_1200(void); int uart1_putchar(char c, FILE *stream);
void serial_setbaudrate_2400(void); int uart1_getchar(FILE *stream);
void serial_setbaudrate_4800(void); char uart1_getchar_nowait(void);
void serial_setbaudrate_9600(void);
void serial_setbaudrate_14400(void); void serial_setbaudrate_1200(uint8_t port);
void serial_setbaudrate_19200(void); void serial_setbaudrate_2400(uint8_t port);
void serial_setbaudrate_28800(void); void serial_setbaudrate_4800(uint8_t port);
void serial_setbaudrate_38400(void); void serial_setbaudrate_9600(uint8_t port);
void serial_setbaudrate_57600(void); void serial_setbaudrate_14400(uint8_t port);
void serial_setbaudrate_76800(void); void serial_setbaudrate_19200(uint8_t port);
void serial_setbaudrate_115200(void); void serial_setbaudrate_28800(uint8_t port);
void serial_setbaudrate_230400(void); 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 #endif

View File

@ -3,7 +3,9 @@
void usrio_init(void) { void usrio_init(void) {
USR_IO_DDR |= _BV(USR_IO_1) | _BV(USR_IO_2); 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) { bool usrio_1(void) {

3
main.c
View File

@ -14,6 +14,7 @@
#include "hardware/UserIO.h" #include "hardware/UserIO.h"
#include "hardware/SD.h" #include "hardware/SD.h"
#include "hardware/Bluetooth.h" #include "hardware/Bluetooth.h"
#include "hardware/GPS.h"
#include "protocol/AX25.h" #include "protocol/AX25.h"
#include "protocol/KISS.h" #include "protocol/KISS.h"
#include "util/time.h" #include "util/time.h"
@ -69,6 +70,7 @@ void init(void) {
kiss_init(&AX25, &modem, &serial); kiss_init(&AX25, &modem, &serial);
sd_init(); sd_init();
bluetooth_init(); bluetooth_init();
gps_init(&serial);
usrio_init(); usrio_init();
system_check(); system_check();
@ -83,6 +85,7 @@ int main (void) {
kiss_poll(); kiss_poll();
kiss_csma(); kiss_csma();
sd_jobs(); sd_jobs();
gps_poll();
} }
return(0); return(0);

View File

@ -50,8 +50,8 @@ void kiss_init(AX25Ctx *ax25, Afsk *afsk, Serial *ser) {
} }
void kiss_poll(void) { void kiss_poll(void) {
while (!fifo_isempty_locked(&serialFIFO)) { while (!fifo_isempty_locked(&uart0FIFO)) {
char sbyte = fifo_pop_locked(&serialFIFO); char sbyte = fifo_pop_locked(&uart0FIFO);
kiss_serialCallback(sbyte); kiss_serialCallback(sbyte);
last_serial_read = timer_clock(); last_serial_read = timer_clock();
} }