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 @@
#define RXBUFSIZE 128
static char rxbuf[RXBUFSIZE];
volatile int idx = 0;
static volatile int idx = 0;
static volatile int frame_rdy = 0;
static nmeaINFO gps_info;
static nmeaPARSER gps_parser;
static nmeaINFO info;
static nmeaPARSER parser;
__attribute__((__weak__))
void LEUART0_IRQHandler()
{
if (LEUART0->IF & LEUART_IF_RXDATAV) {
......@@ -66,9 +68,7 @@ void LEUART0_IRQHandler()
if ((rxbuf[idx-2] == '\r') && (rxbuf[idx-1] == '\n')) {
rxbuf[idx] = '\0';
idx = 0;
nmea_parse(&gps_parser, rxbuf, strlen(rxbuf),
&gps_info);
usbdbg_puts(rxbuf);
frame_rdy = 1;
}
}
}
......@@ -118,8 +118,8 @@ void gps_init()
LEUART_Enable(LEUART0, leuartEnable);
/* NMEA parser & info structure init */
nmea_zero_INFO(&gps_info);
nmea_parser_init(&gps_parser);
nmea_zero_INFO(&info);
nmea_parser_init(&parser);
}
void gps_on_off_pulse()
......@@ -141,78 +141,85 @@ void gps_reset(int val)
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;
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;
// TODO: check return of nmea_parse
nmea_parse(&parser, rxbuf, strlen(rxbuf), &info);
usbdbg_puts(rxbuf);
}
int gps_fixed()
{
return gps_info.sig;
return info.sig;
}
void gps_get_utc(struct gps_utc *utc)
{
utc->yr = 1900 + gps_info.utc.year;
utc->mon = 1 + gps_info.utc.mon;
utc->day = gps_info.utc.day;
utc->hr = gps_info.utc.hour;
utc->min = gps_info.utc.min;
utc->sec = gps_info.utc.sec;
utc->yr = 1900 + info.utc.year;
utc->mon = 1 + info.utc.mon;
utc->day = info.utc.day;
utc->hr = info.utc.hour;
utc->min = info.utc.min;
utc->sec = info.utc.sec;
}
void gps_get_coord(struct gps_coord *coord, int format)
{
if (format == 0) {
/* Raw [deg][min].[sec/60] */
coord->lat = gps_info.lat;
coord->lon = gps_info.lon;
coord->lat = info.lat;
coord->lon = info.lon;
} else if (format == 1) {
/* [deg][min].[sec] */
coord->lat = (int)gps_info.lat + 0.6 * (
gps_info.lat - (int)gps_info.lat);
coord->lon = (int)gps_info.lon + 0.6 * (
gps_info.lon - (int)gps_info.lon);
coord->lat = (int)info.lat + 0.6 * (
info.lat - (int)info.lat);
coord->lon = (int)info.lon + 0.6 * (
info.lon - (int)info.lon);
} else if (format == 2) {
/* [deg].[min/60] */
float tmp;
tmp = gps_info.lat/100;
tmp = info.lat/100;
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->elev = gps_info.elv;
coord->elev = info.elv;
}
void gps_get_speed(double *spd)
{
*spd = gps_info.speed;
*spd = info.speed;
}
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 {
void gps_init();
void gps_on_off_pulse();
void gps_reset(int val);
int gps_puts(char *s);
int gps_nmea_crc(const char *nmeastr);
void gps_parse_nmea();
int gps_fixed();
void gps_get_utc(struct gps_utc *utc);
void gps_get_coord(struct gps_coord *coord, int format);
void gps_get_speed(double *spd);
void gps_get_direction(double *dir);
int gps_puts(char *s);
int gps_nmea_crc(const char *nmeastr);
#endif // __GPS_H_
......@@ -34,8 +34,8 @@ enum event_type {
BUTTON_PRESSED,
SENSOR,
RTC_TICK,
GPS_FIX_LOST,
GPS_FIX_ACQ
GPS_FRAME_RDY,
GPS_PARSE_RDY
};
/**
......
......@@ -169,6 +169,7 @@ FreeRTOS/Source/croutine.c \
FreeRTOS/Source/portable/MemMang/heap_1.c \
FreeRTOS/Source/portable/GCC/ARM_CM3/port.c \
src/apps/widgets/status_bar.c \
src/apps/gpsbkgrnd.c \
src/apps/application.c \
src/apps/clock.c \
src/apps/example_app.c \
......@@ -271,7 +272,7 @@ ifeq ($(filter $(MAKECMDGOALS),all debug release),)
endif
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)
ifneq (clean,$(findstring clean, $(MAKECMDGOALS)))
......
......@@ -174,7 +174,7 @@ extern "C" {
#define INCLUDE_eTaskGetState ( 0 )
/* 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 */
#if ( ( configSLEEP_MODE == 2 ) && ( ( configUSE_SLEEP_MODE_IN_IDLE == 1 ) || ( configUSE_TICKLESS_IDLE == 1 ) ) )
......
......@@ -34,6 +34,7 @@ extern application clock;
extern application example;
extern application gpscoord;
extern application reset;
extern application gpsbkgrnd;
#endif /* APP_LIST_H */
......@@ -28,15 +28,6 @@
#include "event.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;
void startMain(application* app) {
......@@ -45,6 +36,7 @@ void startMain(application* app) {
// TODO oops..
}
/* Create task for main menu app */
if(xTaskCreate(app->main, (const signed char*)app->name, APP_STACK_SIZE,
NULL, APP_PRIORITY, NULL) != pdPASS) {
// TODO oops..
......
......@@ -31,6 +31,22 @@
#include <task.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
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"
};
......@@ -42,135 +42,135 @@ static int gpsscreen = 0;
static void gps_redraw(struct ui_widget *w)
{
char buf[16];
float latdeg;
float latmin;
float latsec;
float londeg;
float lonmin;
float lonsec;
if (gps_fixed())
gps_get_coord(&coord, coord_format);
latdeg = coord.lat/100;
latmin = 100 * (latdeg - (int)latdeg);
latsec = coord.lat - (int)coord.lat;
londeg = coord.lon/100;
lonmin = 100 * (londeg - (int)londeg);
lonsec = coord.lon - (int)coord.lon;
gfx_clear(&w->dc, 0);
/* Display latitude and longitude depending on format */
if (gpsscreen == 0) {
if (coord_format == 0) {
/* raw [deg][min].[sec/60] */
sprintf(buf, "L: %d deg", (int)latdeg);
gfx_text(&w->dc, &font_helv22b, 0, 0, buf, 0);
sprintf(buf, "%2.4f'", latmin);
gfx_text(&w->dc, &font_helv22b, 22, 20, buf, 0);
sprintf(buf, "l: %d deg", (int)(londeg));
gfx_text(&w->dc, &font_helv22b, 0, 50, buf, 0);
sprintf(buf, "%2.4f'", lonmin);
gfx_text(&w->dc, &font_helv22b, 15, 70, buf, 0);
} else if (coord_format == 1) {
/* [deg] [min] [sec] */
sprintf(buf, "L: %d deg", (int)latdeg);
gfx_text(&w->dc, &font_helv22b, 0, 0, buf, 0);
sprintf(buf, "%d'%2.2f''", (int)latmin, 0.6 * latsec);
gfx_text(&w->dc, &font_helv22b, 22, 20, buf, 0);
sprintf(buf, "l: %d deg", (int)londeg);
gfx_text(&w->dc, &font_helv22b, 0, 50, buf, 0);
sprintf(buf, "%d'%2.2f''", (int)lonmin, 60 * lonsec);
gfx_text(&w->dc, &font_helv22b, 15, 70, buf, 0);
} else if (coord_format == 2) {
/* [deg].[min/60] */
sprintf(buf, "L: %2.4f", coord.lat);
gfx_text(&w->dc, &font_helv22b, 0, 0, buf, 0);
sprintf(buf, "l: %2.4f", coord.lon);
gfx_text(&w->dc, &font_helv22b, 0, 50, buf, 0);
}
/* Display elevation */
} else {
sprintf(buf, "elev:");
gfx_text(&w->dc, &font_helv22b, 0, 20, buf, 0);
sprintf(buf, "%5.3f", coord.elev);
gfx_text(&w->dc, &font_helv22b, 0, 40, buf, 0);
char buf[16];
float latdeg;
float latmin;
float latsec;
float londeg;
float lonmin;
float lonsec;
if (gps_fixed())
gps_get_coord(&coord, coord_format);
latdeg = coord.lat/100;
latmin = 100 * (latdeg - (int)latdeg);
latsec = coord.lat - (int)coord.lat;
londeg = coord.lon/100;
lonmin = 100 * (londeg - (int)londeg);
lonsec = coord.lon - (int)coord.lon;
gfx_clear(&w->dc, 0);
/* Display latitude and longitude depending on format */
if (gpsscreen == 0) {
if (coord_format == 0) {
/* raw [deg][min].[sec/60] */
sprintf(buf, "L: %d deg", (int)latdeg);
gfx_text(&w->dc, &font_helv22b, 0, 0, buf, 0);
sprintf(buf, "%2.4f'", latmin);
gfx_text(&w->dc, &font_helv22b, 22, 20, buf, 0);
sprintf(buf, "l: %d deg", (int)(londeg));
gfx_text(&w->dc, &font_helv22b, 0, 50, buf, 0);
sprintf(buf, "%2.4f'", lonmin);
gfx_text(&w->dc, &font_helv22b, 15, 70, buf, 0);
} else if (coord_format == 1) {
/* [deg] [min] [sec] */
sprintf(buf, "L: %d deg", (int)latdeg);
gfx_text(&w->dc, &font_helv22b, 0, 0, buf, 0);
sprintf(buf, "%d'%2.2f''", (int)latmin, 0.6 * latsec);
gfx_text(&w->dc, &font_helv22b, 22, 20, buf, 0);
sprintf(buf, "l: %d deg", (int)londeg);
gfx_text(&w->dc, &font_helv22b, 0, 50, buf, 0);
sprintf(buf, "%d'%2.2f''", (int)lonmin, 60 * lonsec);
gfx_text(&w->dc, &font_helv22b, 15, 70, buf, 0);
} else if (coord_format == 2) {
/* [deg].[min/60] */
sprintf(buf, "L: %2.4f", coord.lat);
gfx_text(&w->dc, &font_helv22b, 0, 0, buf, 0);
sprintf(buf, "l: %2.4f", coord.lon);
gfx_text(&w->dc, &font_helv22b, 0, 50, buf, 0);
}
/* Display elevation */
} else {
sprintf(buf, "elev:");
gfx_text(&w->dc, &font_helv22b, 0, 20, buf, 0);
sprintf(buf, "%5.3f", coord.elev);
gfx_text(&w->dc, &font_helv22b, 0, 40, buf, 0);
}
}
static void gps_event(struct ui_widget *w, const struct event *evt)
{
if (evt->type == RTC_TICK)
w->flags |= WF_DIRTY;
if (evt->type == GPS_PARSE_RDY)
w->flags |= WF_DIRTY;
}
static struct ui_widget gps_coord_display = {
gps_redraw,
gps_event,
{16, 16, 111, 111},
0,
WF_ACTIVE | WF_VISIBLE
gps_redraw,
gps_event,
{16, 16, 111, 111},
0,
WF_ACTIVE | WF_VISIBLE
};
static struct ui_widget gps_screen = {
NULL,
NULL,
{0, 0, 127, 127},
0,
WF_ACTIVE | WF_VISIBLE
NULL,
NULL,
{0, 0, 127, 127},
0,
WF_ACTIVE | WF_VISIBLE
};
void gpscoord_main(void *params)
{
struct event evt;
int i = 0;
/* Init UI */
ui_clear();
ui_init_widget(&gps_screen);
ui_add_widget(&gps_screen);
ui_init_widget(&gps_coord_display);
ui_add_widget(&gps_coord_display);
ui_add_child(&gps_screen, &gps_coord_display);
ui_init_widget(&status_bar);
ui_add_widget(&status_bar);
ui_update(NULL);
while (1) {
if (xQueueReceive(appQueue, &evt, 0)) {
switch (evt.type) {
case BUTTON_PRESSED:
if (evt.data.button == BUT_TR)
return;
else if (evt.data.button == BUT_BR) {
/*
* Toggle between coordinate and
* elevation screens
*/
gpsscreen += 1;
gpsscreen %= 2;
}
break;
case RTC_TICK:
ui_update(&evt);
default:
break;
}
struct event evt;
int i = 0;
/* Init UI */
ui_clear();
ui_init_widget(&gps_screen);
ui_add_widget(&gps_screen);
ui_init_widget(&gps_coord_display);
ui_add_widget(&gps_coord_display);
ui_add_child(&gps_screen, &gps_coord_display);
ui_init_widget(&status_bar);
ui_add_widget(&status_bar);
ui_update(NULL);
while (1) {
if (xQueueReceive(appQueue, &evt, 0)) {
switch (evt.type) {
case BUTTON_PRESSED:
if (evt.data.button == BUT_TR)
return;
else if (evt.data.button == BUT_BR) {
/*
* Toggle between coordinate and
* elevation screens
*/
gpsscreen += 1;
gpsscreen %= 2;
}
break;
case GPS_PARSE_RDY:
ui_update(&evt);
default:
break;
}
}
}
}
application gpscoord = {
.name = "uerdefucami",
.main = gpscoord_main
.name = "uerdefucami",
.main = gpscoord_main
};
......@@ -172,7 +172,7 @@ void menu_main(void* params) {
menu_size = get_menu_size(*current_menu);
// run clock as the the initial application
gpscoord.main(NULL);
clock.main(NULL);
menu_ui_init();
// Once it is deactivated - display the menu
......
......@@ -36,7 +36,7 @@ static int gps_ico_blink = 0;
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;
if (gps_fixed()) {
memcpy(&gps_ico, &gps_receiving,
......
......@@ -33,6 +33,7 @@
#include <em_device.h>
#include <em_gpio.h>
#include <em_burtc.h>
#include <em_leuart.h>
static portBASE_TYPE gpio_irq_dispatcher(uint32_t flags)
{
......@@ -108,3 +109,27 @@ void HardFault_Handler(void)
{
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)
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
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