Skip to content

Commit

Permalink
Merge pull request #10 from xMasterX/ul-updates
Browse files Browse the repository at this point in the history
Some big improvements
  • Loading branch information
ezod authored May 24, 2023
2 parents 53aa016 + a9c1301 commit d28dfe9
Show file tree
Hide file tree
Showing 4 changed files with 147 additions and 66 deletions.
5 changes: 2 additions & 3 deletions application.fam
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
App(
appid="gps",
name="GPS",
appid="gps_nmea",
name="[NMEA] GPS",
apptype=FlipperAppType.EXTERNAL,
entry_point="gps_app",
cdefines=["APP_GPS"],
requires=["gui"],
stack_size=1 * 1024,
order=35,
Expand Down
157 changes: 112 additions & 45 deletions gps.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,45 +15,59 @@ typedef struct {
} PluginEvent;

static void render_callback(Canvas* const canvas, void* context) {
const GpsUart* gps_uart = (GpsUart*)context;
furi_assert(context);
GpsUart* gps_uart = context;
furi_mutex_acquire(gps_uart->mutex, FuriWaitForever);

canvas_set_font(canvas, FontPrimary);
canvas_draw_str_aligned(canvas, 32, 8, AlignCenter, AlignBottom, "Latitude");
canvas_draw_str_aligned(canvas, 96, 8, AlignCenter, AlignBottom, "Longitude");
canvas_draw_str_aligned(canvas, 21, 30, AlignCenter, AlignBottom, "Course");
canvas_draw_str_aligned(canvas, 64, 30, AlignCenter, AlignBottom, "Speed");
canvas_draw_str_aligned(canvas, 107, 30, AlignCenter, AlignBottom, "Altitude");
canvas_draw_str_aligned(canvas, 32, 52, AlignCenter, AlignBottom, "Satellites");
canvas_draw_str_aligned(canvas, 96, 52, AlignCenter, AlignBottom, "Last Fix");

canvas_set_font(canvas, FontSecondary);
char buffer[64];
snprintf(buffer, 64, "%f", (double)gps_uart->status.latitude);
canvas_draw_str_aligned(canvas, 32, 18, AlignCenter, AlignBottom, buffer);
snprintf(buffer, 64, "%f", (double)gps_uart->status.longitude);
canvas_draw_str_aligned(canvas, 96, 18, AlignCenter, AlignBottom, buffer);
snprintf(buffer, 64, "%.1f", (double)gps_uart->status.course);
canvas_draw_str_aligned(canvas, 21, 40, AlignCenter, AlignBottom, buffer);
snprintf(buffer, 64, "%.2f kn", (double)gps_uart->status.speed);
canvas_draw_str_aligned(canvas, 64, 40, AlignCenter, AlignBottom, buffer);
snprintf(
buffer,
64,
"%.1f %c",
(double)gps_uart->status.altitude,
tolower(gps_uart->status.altitude_units));
canvas_draw_str_aligned(canvas, 107, 40, AlignCenter, AlignBottom, buffer);
snprintf(buffer, 64, "%d", gps_uart->status.satellites_tracked);
canvas_draw_str_aligned(canvas, 32, 62, AlignCenter, AlignBottom, buffer);
snprintf(
buffer,
64,
"%02d:%02d:%02d UTC",
gps_uart->status.time_hours,
gps_uart->status.time_minutes,
gps_uart->status.time_seconds);
canvas_draw_str_aligned(canvas, 96, 62, AlignCenter, AlignBottom, buffer);
if(!gps_uart->changing_baudrate) {
canvas_set_font(canvas, FontPrimary);
canvas_draw_str_aligned(canvas, 32, 8, AlignCenter, AlignBottom, "Latitude");
canvas_draw_str_aligned(canvas, 96, 8, AlignCenter, AlignBottom, "Longitude");
canvas_draw_str_aligned(canvas, 21, 30, AlignCenter, AlignBottom, "Course");
canvas_draw_str_aligned(canvas, 64, 30, AlignCenter, AlignBottom, "Speed");
canvas_draw_str_aligned(canvas, 107, 30, AlignCenter, AlignBottom, "Altitude");
canvas_draw_str_aligned(canvas, 32, 52, AlignCenter, AlignBottom, "Satellites");
canvas_draw_str_aligned(canvas, 96, 52, AlignCenter, AlignBottom, "Last Fix");

canvas_set_font(canvas, FontSecondary);
char buffer[64];
snprintf(buffer, 64, "%f", (double)gps_uart->status.latitude);
canvas_draw_str_aligned(canvas, 32, 18, AlignCenter, AlignBottom, buffer);
snprintf(buffer, 64, "%f", (double)gps_uart->status.longitude);
canvas_draw_str_aligned(canvas, 96, 18, AlignCenter, AlignBottom, buffer);
snprintf(buffer, 64, "%.1f", (double)gps_uart->status.course);
canvas_draw_str_aligned(canvas, 21, 40, AlignCenter, AlignBottom, buffer);
if(!gps_uart->speed_in_kms) {
snprintf(buffer, 64, "%.2f kn", (double)gps_uart->status.speed);
} else {
snprintf(buffer, 64, "%.2f km", (double)(gps_uart->status.speed * 1.852));
}
canvas_draw_str_aligned(canvas, 64, 40, AlignCenter, AlignBottom, buffer);
snprintf(
buffer,
64,
"%.1f %c",
(double)gps_uart->status.altitude,
tolower(gps_uart->status.altitude_units));
canvas_draw_str_aligned(canvas, 107, 40, AlignCenter, AlignBottom, buffer);
snprintf(buffer, 64, "%d", gps_uart->status.satellites_tracked);
canvas_draw_str_aligned(canvas, 32, 62, AlignCenter, AlignBottom, buffer);
snprintf(
buffer,
64,
"%02d:%02d:%02d UTC",
gps_uart->status.time_hours,
gps_uart->status.time_minutes,
gps_uart->status.time_seconds);
canvas_draw_str_aligned(canvas, 96, 62, AlignCenter, AlignBottom, buffer);
} else {
char buffer[64];
canvas_set_font(canvas, FontPrimary);
canvas_draw_str_aligned(canvas, 64, 32, AlignCenter, AlignBottom, "Baudrate set to:");

snprintf(buffer, 64, "%ld baud", gps_uart->baudrate);
canvas_draw_str_aligned(canvas, 64, 47, AlignCenter, AlignBottom, buffer);
}

furi_mutex_release(gps_uart->mutex);
}
Expand All @@ -71,7 +85,11 @@ int32_t gps_app(void* p) {
FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(PluginEvent));

GpsUart* gps_uart = gps_uart_enable();
if(gps_uart == NULL) {

gps_uart->mutex = furi_mutex_alloc(FuriMutexTypeNormal);
if(!gps_uart->mutex) {
FURI_LOG_E("GPS", "cannot create mutex\r\n");
free(gps_uart);
return 255;
}

Expand All @@ -81,7 +99,7 @@ int32_t gps_app(void* p) {
view_port_input_callback_set(view_port, input_callback, event_queue);

// open GUI and register view_port
Gui* gui = furi_record_open("gui");
Gui* gui = furi_record_open(RECORD_GUI);
gui_add_view_port(gui, view_port, GuiLayerFullscreen);

PluginEvent event;
Expand All @@ -93,8 +111,54 @@ int32_t gps_app(void* p) {
if(event_status == FuriStatusOk) {
// press events
if(event.type == EventTypeKey) {
if(event.input.type == InputTypePress) {
if(event.input.type == InputTypeShort) {
switch(event.input.key) {
case InputKeyUp:
case InputKeyDown:
case InputKeyRight:
case InputKeyLeft:
case InputKeyBack:
break;
case InputKeyOk:
if(!gps_uart->backlight_on) {
notification_message_block(
gps_uart->notifications, &sequence_display_backlight_enforce_on);
gps_uart->backlight_on = true;
} else {
notification_message_block(
gps_uart->notifications, &sequence_display_backlight_enforce_auto);
notification_message(
gps_uart->notifications, &sequence_display_backlight_off);
gps_uart->backlight_on = false;
}
break;
default:
break;
}
} else if(event.input.type == InputTypeLong) {
switch(event.input.key) {
case InputKeyUp:
gps_uart_deinit_thread(gps_uart);
const int baudrate_length =
sizeof(gps_baudrates) / sizeof(gps_baudrates[0]);
current_gps_baudrate++;
if(current_gps_baudrate >= baudrate_length) {
current_gps_baudrate = 0;
}
gps_uart->baudrate = gps_baudrates[current_gps_baudrate];

gps_uart_init_thread(gps_uart);
gps_uart->changing_baudrate = true;
view_port_update(view_port);
furi_mutex_release(gps_uart->mutex);
break;
case InputKeyRight:
if(gps_uart->speed_in_kms) {
gps_uart->speed_in_kms = false;
} else {
gps_uart->speed_in_kms = true;
}
break;
case InputKeyBack:
processing = false;
break;
Expand All @@ -103,17 +167,20 @@ int32_t gps_app(void* p) {
}
}
}
}
if(!gps_uart->changing_baudrate) {
view_port_update(view_port);
furi_mutex_release(gps_uart->mutex);
} else {
FURI_LOG_D("GPS", "FuriMessageQueue: event timeout");
furi_delay_ms(1000);
gps_uart->changing_baudrate = false;
}

view_port_update(view_port);
furi_mutex_release(gps_uart->mutex);
}

notification_message_block(gps_uart->notifications, &sequence_display_backlight_enforce_auto);
view_port_enabled_set(view_port, false);
gui_remove_view_port(gui, view_port);
furi_record_close("gui");
furi_record_close(RECORD_GUI);
view_port_free(view_port);
furi_message_queue_free(event_queue);
furi_mutex_free(gps_uart->mutex);
Expand Down
40 changes: 23 additions & 17 deletions gps_uart.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ static void gps_uart_on_irq_cb(UartIrqEvent ev, uint8_t data, void* context) {
static void gps_uart_serial_init(GpsUart* gps_uart) {
furi_hal_console_disable();
furi_hal_uart_set_irq_cb(FuriHalUartIdUSART1, gps_uart_on_irq_cb, gps_uart);
furi_hal_uart_set_br(FuriHalUartIdUSART1, GPS_BAUDRATE);
furi_hal_uart_set_br(FuriHalUartIdUSART1, gps_uart->baudrate);
}

static void gps_uart_serial_deinit(GpsUart* gps_uart) {
Expand Down Expand Up @@ -87,11 +87,8 @@ static void gps_uart_parse_nmea(GpsUart* gps_uart, char* line) {
static int32_t gps_uart_worker(void* context) {
GpsUart* gps_uart = (GpsUart*)context;

gps_uart->rx_stream = furi_stream_buffer_alloc(RX_BUF_SIZE * 5, 1);
size_t rx_offset = 0;

gps_uart_serial_init(gps_uart);

while(1) {
uint32_t events =
furi_thread_flags_wait(WORKER_ALL_RX_EVENTS, FuriFlagWaitAny, FuriWaitForever);
Expand Down Expand Up @@ -164,16 +161,8 @@ static int32_t gps_uart_worker(void* context) {
return 0;
}

GpsUart* gps_uart_enable() {
GpsUart* gps_uart = malloc(sizeof(GpsUart));

gps_uart->mutex = furi_mutex_alloc(FuriMutexTypeNormal);
if(!gps_uart->mutex) {
FURI_LOG_E("GPS", "cannot create mutex\r\n");
free(gps_uart);
return NULL;
}

void gps_uart_init_thread(GpsUart* gps_uart) {
furi_assert(gps_uart);
gps_uart->status.valid = false;
gps_uart->status.latitude = 0.0;
gps_uart->status.longitude = 0.0;
Expand All @@ -187,7 +176,7 @@ GpsUart* gps_uart_enable() {
gps_uart->status.time_minutes = 0;
gps_uart->status.time_seconds = 0;

gps_uart->notifications = furi_record_open(RECORD_NOTIFICATION);
gps_uart->rx_stream = furi_stream_buffer_alloc(RX_BUF_SIZE * 5, 1);

gps_uart->thread = furi_thread_alloc();
furi_thread_set_name(gps_uart->thread, "GpsUartWorker");
Expand All @@ -196,15 +185,32 @@ GpsUart* gps_uart_enable() {
furi_thread_set_callback(gps_uart->thread, gps_uart_worker);

furi_thread_start(gps_uart->thread);
return gps_uart;

gps_uart_serial_init(gps_uart);
}

void gps_uart_disable(GpsUart* gps_uart) {
void gps_uart_deinit_thread(GpsUart* gps_uart) {
furi_assert(gps_uart);
furi_thread_flags_set(furi_thread_get_id(gps_uart->thread), WorkerEvtStop);
furi_thread_join(gps_uart->thread);
furi_thread_free(gps_uart->thread);
}

GpsUart* gps_uart_enable() {
GpsUart* gps_uart = malloc(sizeof(GpsUart));

gps_uart->notifications = furi_record_open(RECORD_NOTIFICATION);

gps_uart->baudrate = gps_baudrates[current_gps_baudrate];

gps_uart_init_thread(gps_uart);

return gps_uart;
}

void gps_uart_disable(GpsUart* gps_uart) {
furi_assert(gps_uart);
gps_uart_deinit_thread(gps_uart);
furi_record_close(RECORD_NOTIFICATION);

free(gps_uart);
Expand Down
11 changes: 10 additions & 1 deletion gps_uart.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
#include <furi_hal.h>
#include <notification/notification_messages.h>

#define GPS_BAUDRATE 9600
#define RX_BUF_SIZE 1024

static const int gps_baudrates[5] = {9600, 19200, 38400, 57600, 115200};
static int current_gps_baudrate = 0;

typedef struct {
bool valid;
float latitude;
Expand All @@ -28,10 +30,17 @@ typedef struct {
uint8_t rx_buf[RX_BUF_SIZE];

NotificationApp* notifications;
uint32_t baudrate;
bool changing_baudrate;
bool backlight_on;
bool speed_in_kms;

GpsStatus status;
} GpsUart;

void gps_uart_init_thread(GpsUart* gps_uart);
void gps_uart_deinit_thread(GpsUart* gps_uart);

GpsUart* gps_uart_enable();

void gps_uart_disable(GpsUart* gps_uart);

0 comments on commit d28dfe9

Please sign in to comment.