Commit d8f1e42f authored by Theodor-Adrian Stana's avatar Theodor-Adrian Stana

Work towards optimizing GPS application

parent a71fa0f1
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -54,11 +54,13 @@ ...@@ -54,11 +54,13 @@
#define RXBUFSIZE 128 #define RXBUFSIZE 128
static char rxbuf[RXBUFSIZE]; static char rxbuf[RXBUFSIZE];
volatile int idx = 0; static volatile int idx = 0;
static volatile int frame_rdy = 0;
static nmeaINFO gps_info; static nmeaINFO info;
static nmeaPARSER gps_parser; static nmeaPARSER parser;
__attribute__((__weak__))
void LEUART0_IRQHandler() void LEUART0_IRQHandler()
{ {
if (LEUART0->IF & LEUART_IF_RXDATAV) { if (LEUART0->IF & LEUART_IF_RXDATAV) {
...@@ -66,9 +68,7 @@ void LEUART0_IRQHandler() ...@@ -66,9 +68,7 @@ void LEUART0_IRQHandler()
if ((rxbuf[idx-2] == '\r') && (rxbuf[idx-1] == '\n')) { if ((rxbuf[idx-2] == '\r') && (rxbuf[idx-1] == '\n')) {
rxbuf[idx] = '\0'; rxbuf[idx] = '\0';
idx = 0; idx = 0;
nmea_parse(&gps_parser, rxbuf, strlen(rxbuf), frame_rdy = 1;
&gps_info);
usbdbg_puts(rxbuf);
} }
} }
} }
...@@ -118,8 +118,8 @@ void gps_init() ...@@ -118,8 +118,8 @@ void gps_init()
LEUART_Enable(LEUART0, leuartEnable); LEUART_Enable(LEUART0, leuartEnable);
/* NMEA parser & info structure init */ /* NMEA parser & info structure init */
nmea_zero_INFO(&gps_info); nmea_zero_INFO(&info);
nmea_parser_init(&gps_parser); nmea_parser_init(&parser);
} }
void gps_on_off_pulse() void gps_on_off_pulse()
...@@ -141,78 +141,85 @@ void gps_reset(int val) ...@@ -141,78 +141,85 @@ void gps_reset(int val)
val ? GPIO_PinOutClear(gpioPortF, 5) : GPIO_PinOutSet(gpioPortF, 5); val ? GPIO_PinOutClear(gpioPortF, 5) : GPIO_PinOutSet(gpioPortF, 5);
} }
int gps_puts(char *s) void gps_parse_nmea()
{
while (*s++) {
if (*s == EOF)
return EOF;
LEUART_Tx(LEUART0, *s);
}
return 1;
}
int gps_nmea_crc(const char *nmeastr)
{ {
int chksum = 0; // TODO: check return of nmea_parse
int i = 0; nmea_parse(&parser, rxbuf, strlen(rxbuf), &info);
int n = 0; usbdbg_puts(rxbuf);
char buf[128];
while (*nmeastr != '*')
buf[n++] = *nmeastr++;
for (i = 1; i < n; i++)
chksum ^= (int)buf[i];
return chksum;
} }
int gps_fixed() int gps_fixed()
{ {
return gps_info.sig; return info.sig;
} }
void gps_get_utc(struct gps_utc *utc) void gps_get_utc(struct gps_utc *utc)
{ {
utc->yr = 1900 + gps_info.utc.year; utc->yr = 1900 + info.utc.year;
utc->mon = 1 + gps_info.utc.mon; utc->mon = 1 + info.utc.mon;
utc->day = gps_info.utc.day; utc->day = info.utc.day;
utc->hr = gps_info.utc.hour; utc->hr = info.utc.hour;
utc->min = gps_info.utc.min; utc->min = info.utc.min;
utc->sec = gps_info.utc.sec; utc->sec = info.utc.sec;
} }
void gps_get_coord(struct gps_coord *coord, int format) void gps_get_coord(struct gps_coord *coord, int format)
{ {
if (format == 0) { if (format == 0) {
/* Raw [deg][min].[sec/60] */ /* Raw [deg][min].[sec/60] */
coord->lat = gps_info.lat; coord->lat = info.lat;
coord->lon = gps_info.lon; coord->lon = info.lon;
} else if (format == 1) { } else if (format == 1) {
/* [deg][min].[sec] */ /* [deg][min].[sec] */
coord->lat = (int)gps_info.lat + 0.6 * ( coord->lat = (int)info.lat + 0.6 * (
gps_info.lat - (int)gps_info.lat); info.lat - (int)info.lat);
coord->lon = (int)gps_info.lon + 0.6 * ( coord->lon = (int)info.lon + 0.6 * (
gps_info.lon - (int)gps_info.lon); info.lon - (int)info.lon);
} else if (format == 2) { } else if (format == 2) {
/* [deg].[min/60] */ /* [deg].[min/60] */
float tmp; float tmp;
tmp = gps_info.lat/100; tmp = info.lat/100;
coord->lat = (int)tmp + (tmp - (int)tmp) / 0.6; coord->lat = (int)tmp + (tmp - (int)tmp) / 0.6;
tmp = gps_info.lon/100; tmp = info.lon/100;
coord->lon = (int)tmp + (tmp - (int)tmp) / 0.6; coord->lon = (int)tmp + (tmp - (int)tmp) / 0.6;
} }
coord->elev = gps_info.elv; coord->elev = info.elv;
} }
void gps_get_speed(double *spd) void gps_get_speed(double *spd)
{ {
*spd = gps_info.speed; *spd = info.speed;
} }
void gps_get_direction(double *dir) void gps_get_direction(double *dir)
{ {
*dir = gps_info.direction; *dir = info.direction;
}
int gps_puts(char *s)
{
while (*s++) {
if (*s == EOF)
return EOF;
LEUART_Tx(LEUART0, *s);
}
return 1;
}
int gps_nmea_crc(const char *nmeastr)
{
int chksum = 0;
int i = 0;
int n = 0;
char buf[128];
while (*nmeastr != '*')
buf[n++] = *nmeastr++;
for (i = 1; i < n; i++)
chksum ^= (int)buf[i];
return chksum;
} }
...@@ -60,12 +60,13 @@ struct gps_utc { ...@@ -60,12 +60,13 @@ struct gps_utc {
void gps_init(); void gps_init();
void gps_on_off_pulse(); void gps_on_off_pulse();
void gps_reset(int val); void gps_reset(int val);
int gps_puts(char *s); void gps_parse_nmea();
int gps_nmea_crc(const char *nmeastr);
int gps_fixed(); int gps_fixed();
void gps_get_utc(struct gps_utc *utc); void gps_get_utc(struct gps_utc *utc);
void gps_get_coord(struct gps_coord *coord, int format); void gps_get_coord(struct gps_coord *coord, int format);
void gps_get_speed(double *spd); void gps_get_speed(double *spd);
void gps_get_direction(double *dir); void gps_get_direction(double *dir);
int gps_puts(char *s);
int gps_nmea_crc(const char *nmeastr);
#endif // __GPS_H_ #endif // __GPS_H_
...@@ -34,8 +34,8 @@ enum event_type { ...@@ -34,8 +34,8 @@ enum event_type {
BUTTON_PRESSED, BUTTON_PRESSED,
SENSOR, SENSOR,
RTC_TICK, RTC_TICK,
GPS_FIX_LOST, GPS_FRAME_RDY,
GPS_FIX_ACQ GPS_PARSE_RDY
}; };
/** /**
......
...@@ -169,6 +169,7 @@ FreeRTOS/Source/croutine.c \ ...@@ -169,6 +169,7 @@ FreeRTOS/Source/croutine.c \
FreeRTOS/Source/portable/MemMang/heap_1.c \ FreeRTOS/Source/portable/MemMang/heap_1.c \
FreeRTOS/Source/portable/GCC/ARM_CM3/port.c \ FreeRTOS/Source/portable/GCC/ARM_CM3/port.c \
src/apps/widgets/status_bar.c \ src/apps/widgets/status_bar.c \
src/apps/gpsbkgrnd.c \
src/apps/application.c \ src/apps/application.c \
src/apps/clock.c \ src/apps/clock.c \
src/apps/example_app.c \ src/apps/example_app.c \
...@@ -271,7 +272,7 @@ ifeq ($(filter $(MAKECMDGOALS),all debug release),) ...@@ -271,7 +272,7 @@ ifeq ($(filter $(MAKECMDGOALS),all debug release),)
endif endif
flash: $(EXE_DIR)/$(PROJECTNAME).bin flash: $(EXE_DIR)/$(PROJECTNAME).bin
openocd -s ../common/openocd -f interface/$(OOCD_IFACE).cfg -f init.cfg -c "program $(EXE_DIR)/$(PROJECTNAME).bin 0 verify reset" openocd -s ../common/openocd -f interface/$(OOCD_IFACE).cfg -f init.cfg -c "program $(EXE_DIR)/$(PROJECTNAME).bin 0 verify reset 0x8000"
# include auto-generated dependency files (explicit rules) # include auto-generated dependency files (explicit rules)
ifneq (clean,$(findstring clean, $(MAKECMDGOALS))) ifneq (clean,$(findstring clean, $(MAKECMDGOALS)))
......
...@@ -174,7 +174,7 @@ extern "C" { ...@@ -174,7 +174,7 @@ extern "C" {
#define INCLUDE_eTaskGetState ( 0 ) #define INCLUDE_eTaskGetState ( 0 )
/* Default value of CPU clock (RC)*/ /* Default value of CPU clock (RC)*/
#define configCPU_CLOCK_HZ (( unsigned long ) 14000000) #define configCPU_CLOCK_HZ (( unsigned long ) 48000000)
/* Defines used in energy modes */ /* Defines used in energy modes */
#if ( ( configSLEEP_MODE == 2 ) && ( ( configUSE_SLEEP_MODE_IN_IDLE == 1 ) || ( configUSE_TICKLESS_IDLE == 1 ) ) ) #if ( ( configSLEEP_MODE == 2 ) && ( ( configUSE_SLEEP_MODE_IN_IDLE == 1 ) || ( configUSE_TICKLESS_IDLE == 1 ) ) )
......
...@@ -34,6 +34,7 @@ extern application clock; ...@@ -34,6 +34,7 @@ extern application clock;
extern application example; extern application example;
extern application gpscoord; extern application gpscoord;
extern application reset; extern application reset;
extern application gpsbkgrnd;
#endif /* APP_LIST_H */ #endif /* APP_LIST_H */
...@@ -28,15 +28,6 @@ ...@@ -28,15 +28,6 @@
#include "event.h" #include "event.h"
#include <FreeRTOSConfig.h> #include <FreeRTOSConfig.h>
///> Capacity of event queue
#define APP_QUEUE_LEN 16
///> Shared application stack size
#define APP_STACK_SIZE (configMINIMAL_STACK_SIZE)
///> Prioriuty of application task
#define APP_PRIORITY (tskIDLE_PRIORITY + 1)
xQueueHandle appQueue; xQueueHandle appQueue;
void startMain(application* app) { void startMain(application* app) {
...@@ -45,6 +36,7 @@ void startMain(application* app) { ...@@ -45,6 +36,7 @@ void startMain(application* app) {
// TODO oops.. // TODO oops..
} }
/* Create task for main menu app */
if(xTaskCreate(app->main, (const signed char*)app->name, APP_STACK_SIZE, if(xTaskCreate(app->main, (const signed char*)app->name, APP_STACK_SIZE,
NULL, APP_PRIORITY, NULL) != pdPASS) { NULL, APP_PRIORITY, NULL) != pdPASS) {
// TODO oops.. // TODO oops..
......
...@@ -31,6 +31,22 @@ ...@@ -31,6 +31,22 @@
#include <task.h> #include <task.h>
#include <queue.h> #include <queue.h>
#include <em_gpio.h>
#include <udelay.h>
void debug();
///> Capacity of event queue
#define APP_QUEUE_LEN 16
///> Shared application stack size
#define APP_STACK_SIZE (configMINIMAL_STACK_SIZE)
///> Prioriuty of application task
#define APP_PRIORITY (tskIDLE_PRIORITY + 1)
#define BKGRND_APP_PRIORITY (tskIDLE_PRIORITY + 2)
///> Shared application task handle ///> Shared application task handle
extern xTaskHandle appTask; extern xTaskHandle appTask;
......
/*
* Copyright (C) 2014 Julian Lewis
* @author Theodor Stana <theodor.stana@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <event.h>
#include <drivers/gps/gps.h>
#include <em_gpio.h>
#include "application.h"
#define dbg() \
int i; \
GPIO_PinOutSet(gpioPortE, 11); \
for (i = 0; i < 1000000; i++) \
; \
GPIO_PinOutClear(gpioPortE, 11);
void gpsbkgrnd_main(void *params)
{
(void)params;
struct event evt;
while (1) {
if (xQueueReceive(appQueue, &evt, portMAX_DELAY)) {
if (evt.type == GPS_FRAME_RDY) {
gps_parse_nmea();
evt.type = GPS_PARSE_RDY;
xQueueSendToBack(appQueue, &evt, 0);
}
}
}
}
application gpsbkgrnd = {
.main = gpsbkgrnd_main,
.name = "GPS background"
};
...@@ -106,7 +106,7 @@ static void gps_redraw(struct ui_widget *w) ...@@ -106,7 +106,7 @@ static void gps_redraw(struct ui_widget *w)
static void gps_event(struct ui_widget *w, const struct event *evt) static void gps_event(struct ui_widget *w, const struct event *evt)
{ {
if (evt->type == RTC_TICK) if (evt->type == GPS_PARSE_RDY)
w->flags |= WF_DIRTY; w->flags |= WF_DIRTY;
} }
...@@ -161,7 +161,7 @@ void gpscoord_main(void *params) ...@@ -161,7 +161,7 @@ void gpscoord_main(void *params)
gpsscreen %= 2; gpsscreen %= 2;
} }
break; break;
case RTC_TICK: case GPS_PARSE_RDY:
ui_update(&evt); ui_update(&evt);
default: default:
break; break;
......
...@@ -172,7 +172,7 @@ void menu_main(void* params) { ...@@ -172,7 +172,7 @@ void menu_main(void* params) {
menu_size = get_menu_size(*current_menu); menu_size = get_menu_size(*current_menu);
// run clock as the the initial application // run clock as the the initial application
gpscoord.main(NULL); clock.main(NULL);
menu_ui_init(); menu_ui_init();
// Once it is deactivated - display the menu // Once it is deactivated - display the menu
......
...@@ -36,7 +36,7 @@ static int gps_ico_blink = 0; ...@@ -36,7 +36,7 @@ static int gps_ico_blink = 0;
static void status_bar_event(struct ui_widget *w, const struct event *evt) static void status_bar_event(struct ui_widget *w, const struct event *evt)
{ {
if (evt->type == RTC_TICK) { if (evt->type == GPS_PARSE_RDY) {
w->flags |= WF_DIRTY; w->flags |= WF_DIRTY;
if (gps_fixed()) { if (gps_fixed()) {
memcpy(&gps_ico, &gps_receiving, memcpy(&gps_ico, &gps_receiving,
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include <em_device.h> #include <em_device.h>
#include <em_gpio.h> #include <em_gpio.h>
#include <em_burtc.h> #include <em_burtc.h>
#include <em_leuart.h>
static portBASE_TYPE gpio_irq_dispatcher(uint32_t flags) static portBASE_TYPE gpio_irq_dispatcher(uint32_t flags)
{ {
...@@ -108,3 +109,27 @@ void HardFault_Handler(void) ...@@ -108,3 +109,27 @@ void HardFault_Handler(void)
{ {
SCB->AIRCR = 0x05FA0004; SCB->AIRCR = 0x05FA0004;
} }
#define RXBUFSIZE 128
static char rxbuf[RXBUFSIZE];
static volatile int idx = 0;
void LEUART0_IRQHandler(void)
{
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
// Fill the event data
struct event evt;
evt.type = GPS_FRAME_RDY;
if (LEUART0->IF & LEUART_IF_RXDATAV) {
rxbuf[idx++] = LEUART_Rx(LEUART0);
if ((rxbuf[idx-2] == '\r') && (rxbuf[idx-1] == '\n')) {
rxbuf[idx] = '\0';
idx = 0;
xQueueSendFromISR(appQueue, &evt, &xHigherPriorityTaskWoken);
}
}
portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
}
...@@ -64,6 +64,12 @@ int main(void) ...@@ -64,6 +64,12 @@ int main(void)
startMain(&menu); startMain(&menu);
/* Create background task for GPS */
if (xTaskCreate(gpsbkgrnd.main, (const signed char *)gpsbkgrnd.name,
APP_STACK_SIZE, NULL, BKGRND_APP_PRIORITY, NULL) != pdPASS) {
// TODO oops..
}
// Start FreeRTOS Scheduler // Start FreeRTOS Scheduler
vTaskStartScheduler(); vTaskStartScheduler();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment