Просмотр исходного кода

Merge pull request #10 from xMasterX/ul-updates

Some big improvements
Aaron Mavrinac 2 лет назад
Родитель
Сommit
d28dfe9e88
4 измененных файлов с 147 добавлено и 66 удалено
  1. 2 3
      application.fam
  2. 112 45
      gps.c
  3. 23 17
      gps_uart.c
  4. 10 1
      gps_uart.h

+ 2 - 3
application.fam

@@ -1,9 +1,8 @@
 App(
 App(
-    appid="gps",
-    name="GPS",
+    appid="gps_nmea",
+    name="[NMEA] GPS",
     apptype=FlipperAppType.EXTERNAL,
     apptype=FlipperAppType.EXTERNAL,
     entry_point="gps_app",
     entry_point="gps_app",
-    cdefines=["APP_GPS"],
     requires=["gui"],
     requires=["gui"],
     stack_size=1 * 1024,
     stack_size=1 * 1024,
     order=35,
     order=35,

+ 112 - 45
gps.c

@@ -15,45 +15,59 @@ typedef struct {
 } PluginEvent;
 } PluginEvent;
 
 
 static void render_callback(Canvas* const canvas, void* context) {
 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);
     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);
     furi_mutex_release(gps_uart->mutex);
 }
 }
@@ -71,7 +85,11 @@ int32_t gps_app(void* p) {
     FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(PluginEvent));
     FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(PluginEvent));
 
 
     GpsUart* gps_uart = gps_uart_enable();
     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;
         return 255;
     }
     }
 
 
@@ -81,7 +99,7 @@ int32_t gps_app(void* p) {
     view_port_input_callback_set(view_port, input_callback, event_queue);
     view_port_input_callback_set(view_port, input_callback, event_queue);
 
 
     // open GUI and register view_port
     // 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);
     gui_add_view_port(gui, view_port, GuiLayerFullscreen);
 
 
     PluginEvent event;
     PluginEvent event;
@@ -93,8 +111,54 @@ int32_t gps_app(void* p) {
         if(event_status == FuriStatusOk) {
         if(event_status == FuriStatusOk) {
             // press events
             // press events
             if(event.type == EventTypeKey) {
             if(event.type == EventTypeKey) {
-                if(event.input.type == InputTypePress) {
+                if(event.input.type == InputTypeShort) {
                     switch(event.input.key) {
                     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:
                     case InputKeyBack:
                         processing = false;
                         processing = false;
                         break;
                         break;
@@ -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 {
         } 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);
     view_port_enabled_set(view_port, false);
     gui_remove_view_port(gui, view_port);
     gui_remove_view_port(gui, view_port);
-    furi_record_close("gui");
+    furi_record_close(RECORD_GUI);
     view_port_free(view_port);
     view_port_free(view_port);
     furi_message_queue_free(event_queue);
     furi_message_queue_free(event_queue);
     furi_mutex_free(gps_uart->mutex);
     furi_mutex_free(gps_uart->mutex);

+ 23 - 17
gps_uart.c

@@ -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) {
 static void gps_uart_serial_init(GpsUart* gps_uart) {
     furi_hal_console_disable();
     furi_hal_console_disable();
     furi_hal_uart_set_irq_cb(FuriHalUartIdUSART1, gps_uart_on_irq_cb, gps_uart);
     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) {
 static void gps_uart_serial_deinit(GpsUart* gps_uart) {
@@ -87,11 +87,8 @@ static void gps_uart_parse_nmea(GpsUart* gps_uart, char* line) {
 static int32_t gps_uart_worker(void* context) {
 static int32_t gps_uart_worker(void* context) {
     GpsUart* gps_uart = (GpsUart*)context;
     GpsUart* gps_uart = (GpsUart*)context;
 
 
-    gps_uart->rx_stream = furi_stream_buffer_alloc(RX_BUF_SIZE * 5, 1);
     size_t rx_offset = 0;
     size_t rx_offset = 0;
 
 
-    gps_uart_serial_init(gps_uart);
-
     while(1) {
     while(1) {
         uint32_t events =
         uint32_t events =
             furi_thread_flags_wait(WORKER_ALL_RX_EVENTS, FuriFlagWaitAny, FuriWaitForever);
             furi_thread_flags_wait(WORKER_ALL_RX_EVENTS, FuriFlagWaitAny, FuriWaitForever);
@@ -164,16 +161,8 @@ static int32_t gps_uart_worker(void* context) {
     return 0;
     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.valid = false;
     gps_uart->status.latitude = 0.0;
     gps_uart->status.latitude = 0.0;
     gps_uart->status.longitude = 0.0;
     gps_uart->status.longitude = 0.0;
@@ -187,7 +176,7 @@ GpsUart* gps_uart_enable() {
     gps_uart->status.time_minutes = 0;
     gps_uart->status.time_minutes = 0;
     gps_uart->status.time_seconds = 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();
     gps_uart->thread = furi_thread_alloc();
     furi_thread_set_name(gps_uart->thread, "GpsUartWorker");
     furi_thread_set_name(gps_uart->thread, "GpsUartWorker");
@@ -196,15 +185,32 @@ GpsUart* gps_uart_enable() {
     furi_thread_set_callback(gps_uart->thread, gps_uart_worker);
     furi_thread_set_callback(gps_uart->thread, gps_uart_worker);
 
 
     furi_thread_start(gps_uart->thread);
     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_assert(gps_uart);
     furi_thread_flags_set(furi_thread_get_id(gps_uart->thread), WorkerEvtStop);
     furi_thread_flags_set(furi_thread_get_id(gps_uart->thread), WorkerEvtStop);
     furi_thread_join(gps_uart->thread);
     furi_thread_join(gps_uart->thread);
     furi_thread_free(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);
     furi_record_close(RECORD_NOTIFICATION);
 
 
     free(gps_uart);
     free(gps_uart);

+ 10 - 1
gps_uart.h

@@ -3,9 +3,11 @@
 #include <furi_hal.h>
 #include <furi_hal.h>
 #include <notification/notification_messages.h>
 #include <notification/notification_messages.h>
 
 
-#define GPS_BAUDRATE 9600
 #define RX_BUF_SIZE 1024
 #define RX_BUF_SIZE 1024
 
 
+static const int gps_baudrates[5] = {9600, 19200, 38400, 57600, 115200};
+static int current_gps_baudrate = 0;
+
 typedef struct {
 typedef struct {
     bool valid;
     bool valid;
     float latitude;
     float latitude;
@@ -28,10 +30,17 @@ typedef struct {
     uint8_t rx_buf[RX_BUF_SIZE];
     uint8_t rx_buf[RX_BUF_SIZE];
 
 
     NotificationApp* notifications;
     NotificationApp* notifications;
+    uint32_t baudrate;
+    bool changing_baudrate;
+    bool backlight_on;
+    bool speed_in_kms;
 
 
     GpsStatus status;
     GpsStatus status;
 } GpsUart;
 } GpsUart;
 
 
+void gps_uart_init_thread(GpsUart* gps_uart);
+void gps_uart_deinit_thread(GpsUart* gps_uart);
+
 GpsUart* gps_uart_enable();
 GpsUart* gps_uart_enable();
 
 
 void gps_uart_disable(GpsUart* gps_uart);
 void gps_uart_disable(GpsUart* gps_uart);