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

Apply ./fbt format (excluding third-party sources).

Aaron Mavrinac 2 лет назад
Родитель
Сommit
f6fa1e730b
3 измененных файлов с 288 добавлено и 313 удалено
  1. 99 102
      gps.c
  2. 169 189
      gps_uart.c
  3. 20 22
      gps_uart.h

+ 99 - 102
gps.c

@@ -4,123 +4,120 @@
 #include <gui/gui.h>
 #include <string.h>
 
-typedef enum
-{
-  EventTypeTick,
-  EventTypeKey,
+typedef enum {
+    EventTypeTick,
+    EventTypeKey,
 } EventType;
 
-typedef struct
-{
-  EventType type;
-  InputEvent input;
+typedef struct {
+    EventType type;
+    InputEvent input;
 } PluginEvent;
 
-static void render_callback(Canvas* const canvas, void* context)
-{
-  const GpsUart* gps_uart = (GpsUart*)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);
-
-  furi_mutex_release(gps_uart->mutex);
-}
+static void render_callback(Canvas* const canvas, void* context) {
+    const GpsUart* gps_uart = (GpsUart*)context;
+    furi_mutex_acquire(gps_uart->mutex, FuriWaitForever);
 
-static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue)
-{
-  furi_assert(event_queue);
+    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);
 
-  PluginEvent event = {.type = EventTypeKey, .input = *input_event};
-  furi_message_queue_put(event_queue, &event, FuriWaitForever);
+    furi_mutex_release(gps_uart->mutex);
 }
 
-int32_t gps_app(void* p)
-{
-  UNUSED(p);
+static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) {
+    furi_assert(event_queue);
 
-  FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(PluginEvent));
-
-  GpsUart* gps_uart = gps_uart_enable();
-  if (gps_uart == NULL)
-  {
-    return 255;
-  }
-
-  // set system callbacks
-  ViewPort* view_port = view_port_alloc();
-  view_port_draw_callback_set(view_port, render_callback, gps_uart);
-  view_port_input_callback_set(view_port, input_callback, event_queue);
+    PluginEvent event = {.type = EventTypeKey, .input = *input_event};
+    furi_message_queue_put(event_queue, &event, FuriWaitForever);
+}
 
-  // open GUI and register view_port
-  Gui* gui = furi_record_open("gui");
-  gui_add_view_port(gui, view_port, GuiLayerFullscreen);
+int32_t gps_app(void* p) {
+    UNUSED(p);
 
-  PluginEvent event;
-  for (bool processing = true; processing;)
-  {
-    FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100);
+    FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(PluginEvent));
 
-    furi_mutex_acquire(gps_uart->mutex, FuriWaitForever);
+    GpsUart* gps_uart = gps_uart_enable();
+    if(gps_uart == NULL) {
+        return 255;
+    }
 
-    if (event_status == FuriStatusOk)
-    {
-      // press events
-      if (event.type == EventTypeKey)
-      {
-        if (event.input.type == InputTypePress)
-        {
-          switch (event.input.key)
-          {
-            case InputKeyBack:
-              processing = false;
-              break;
-            default:
-              break;
-          }
+    // set system callbacks
+    ViewPort* view_port = view_port_alloc();
+    view_port_draw_callback_set(view_port, render_callback, gps_uart);
+    view_port_input_callback_set(view_port, input_callback, event_queue);
+
+    // open GUI and register view_port
+    Gui* gui = furi_record_open("gui");
+    gui_add_view_port(gui, view_port, GuiLayerFullscreen);
+
+    PluginEvent event;
+    for(bool processing = true; processing;) {
+        FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100);
+
+        furi_mutex_acquire(gps_uart->mutex, FuriWaitForever);
+
+        if(event_status == FuriStatusOk) {
+            // press events
+            if(event.type == EventTypeKey) {
+                if(event.input.type == InputTypePress) {
+                    switch(event.input.key) {
+                    case InputKeyBack:
+                        processing = false;
+                        break;
+                    default:
+                        break;
+                    }
+                }
+            }
+        } else {
+            FURI_LOG_D("GPS", "FuriMessageQueue: event timeout");
         }
-      }
-    } 
-    else
-    {
-      FURI_LOG_D("GPS", "FuriMessageQueue: event timeout");
-    }
 
-    view_port_update(view_port);
-    furi_mutex_release(gps_uart->mutex);
-  }
+        view_port_update(view_port);
+        furi_mutex_release(gps_uart->mutex);
+    }
 
-  view_port_enabled_set(view_port, false);
-  gui_remove_view_port(gui, view_port);
-  furi_record_close("gui");
-  view_port_free(view_port);
-  furi_message_queue_free(event_queue);
-  furi_mutex_free(gps_uart->mutex);
-  gps_uart_disable(gps_uart);
+    view_port_enabled_set(view_port, false);
+    gui_remove_view_port(gui, view_port);
+    furi_record_close("gui");
+    view_port_free(view_port);
+    furi_message_queue_free(event_queue);
+    furi_mutex_free(gps_uart->mutex);
+    gps_uart_disable(gps_uart);
 
-  return 0;
+    return 0;
 }

+ 169 - 189
gps_uart.c

@@ -3,229 +3,209 @@
 #include "minmea.h"
 #include "gps_uart.h"
 
-typedef enum
-{
-  WorkerEvtStop = (1 << 0),
-  WorkerEvtRxDone = (1 << 1),
+typedef enum {
+    WorkerEvtStop = (1 << 0),
+    WorkerEvtRxDone = (1 << 1),
 } WorkerEvtFlags;
 
 #define WORKER_ALL_RX_EVENTS (WorkerEvtStop | WorkerEvtRxDone)
 
-static void gps_uart_on_irq_cb(UartIrqEvent ev, uint8_t data, void* context)
-{
-  GpsUart* gps_uart = (GpsUart*)context;
+static void gps_uart_on_irq_cb(UartIrqEvent ev, uint8_t data, void* context) {
+    GpsUart* gps_uart = (GpsUart*)context;
 
-  if (ev == UartIrqEventRXNE)
-  {
-    furi_stream_buffer_send(gps_uart->rx_stream, &data, 1, 0);
-    furi_thread_flags_set(furi_thread_get_id(gps_uart->thread), WorkerEvtRxDone);
-  }
+    if(ev == UartIrqEventRXNE) {
+        furi_stream_buffer_send(gps_uart->rx_stream, &data, 1, 0);
+        furi_thread_flags_set(furi_thread_get_id(gps_uart->thread), WorkerEvtRxDone);
+    }
 }
 
-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);
+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);
 }
 
-static void gps_uart_serial_deinit(GpsUart* gps_uart)
-{
-  UNUSED(gps_uart);
-  furi_hal_uart_set_irq_cb(FuriHalUartIdUSART1, NULL, NULL);
-  furi_hal_console_enable();
+static void gps_uart_serial_deinit(GpsUart* gps_uart) {
+    UNUSED(gps_uart);
+    furi_hal_uart_set_irq_cb(FuriHalUartIdUSART1, NULL, NULL);
+    furi_hal_console_enable();
 }
 
-static void gps_uart_parse_nmea(GpsUart* gps_uart, char* line)
-{
-  switch (minmea_sentence_id(line, false))
-  {
-    case MINMEA_SENTENCE_RMC:
-    {
-      struct minmea_sentence_rmc frame;
-      if (minmea_parse_rmc(&frame, line))
-      {
-        gps_uart->status.valid = frame.valid;
-        gps_uart->status.latitude = minmea_tocoord(&frame.latitude);
-        gps_uart->status.longitude = minmea_tocoord(&frame.longitude);
-        gps_uart->status.speed = minmea_tofloat(&frame.speed);
-        gps_uart->status.course = minmea_tofloat(&frame.course);
-        gps_uart->status.time_hours = frame.time.hours;
-        gps_uart->status.time_minutes = frame.time.minutes;
-        gps_uart->status.time_seconds = frame.time.seconds;
-
-        notification_message_block(gps_uart->notifications, &sequence_blink_green_10);
-      }
+static void gps_uart_parse_nmea(GpsUart* gps_uart, char* line) {
+    switch(minmea_sentence_id(line, false)) {
+    case MINMEA_SENTENCE_RMC: {
+        struct minmea_sentence_rmc frame;
+        if(minmea_parse_rmc(&frame, line)) {
+            gps_uart->status.valid = frame.valid;
+            gps_uart->status.latitude = minmea_tocoord(&frame.latitude);
+            gps_uart->status.longitude = minmea_tocoord(&frame.longitude);
+            gps_uart->status.speed = minmea_tofloat(&frame.speed);
+            gps_uart->status.course = minmea_tofloat(&frame.course);
+            gps_uart->status.time_hours = frame.time.hours;
+            gps_uart->status.time_minutes = frame.time.minutes;
+            gps_uart->status.time_seconds = frame.time.seconds;
+
+            notification_message_block(gps_uart->notifications, &sequence_blink_green_10);
+        }
     } break;
 
-    case MINMEA_SENTENCE_GGA:
-    {
-      struct minmea_sentence_gga frame;
-      if (minmea_parse_gga(&frame, line))
-      {
-        gps_uart->status.latitude = minmea_tocoord(&frame.latitude);
-        gps_uart->status.longitude = minmea_tocoord(&frame.longitude);
-        gps_uart->status.altitude = minmea_tofloat(&frame.altitude);
-        gps_uart->status.altitude_units = frame.altitude_units;
-        gps_uart->status.fix_quality = frame.fix_quality;
-        gps_uart->status.satellites_tracked = frame.satellites_tracked;
-        gps_uart->status.time_hours = frame.time.hours;
-        gps_uart->status.time_minutes = frame.time.minutes;
-        gps_uart->status.time_seconds = frame.time.seconds;
-
-        notification_message_block(gps_uart->notifications, &sequence_blink_magenta_10);
-      }
+    case MINMEA_SENTENCE_GGA: {
+        struct minmea_sentence_gga frame;
+        if(minmea_parse_gga(&frame, line)) {
+            gps_uart->status.latitude = minmea_tocoord(&frame.latitude);
+            gps_uart->status.longitude = minmea_tocoord(&frame.longitude);
+            gps_uart->status.altitude = minmea_tofloat(&frame.altitude);
+            gps_uart->status.altitude_units = frame.altitude_units;
+            gps_uart->status.fix_quality = frame.fix_quality;
+            gps_uart->status.satellites_tracked = frame.satellites_tracked;
+            gps_uart->status.time_hours = frame.time.hours;
+            gps_uart->status.time_minutes = frame.time.minutes;
+            gps_uart->status.time_seconds = frame.time.seconds;
+
+            notification_message_block(gps_uart->notifications, &sequence_blink_magenta_10);
+        }
     } break;
 
-    case MINMEA_SENTENCE_GLL:
-    {
-      struct minmea_sentence_gll frame;
-      if (minmea_parse_gll(&frame, line))
-      {
-        gps_uart->status.latitude = minmea_tocoord(&frame.latitude);
-        gps_uart->status.longitude = minmea_tocoord(&frame.longitude);
-        gps_uart->status.time_hours = frame.time.hours;
-        gps_uart->status.time_minutes = frame.time.minutes;
-        gps_uart->status.time_seconds = frame.time.seconds;
-
-        notification_message_block(gps_uart->notifications, &sequence_blink_red_10);
-      }
+    case MINMEA_SENTENCE_GLL: {
+        struct minmea_sentence_gll frame;
+        if(minmea_parse_gll(&frame, line)) {
+            gps_uart->status.latitude = minmea_tocoord(&frame.latitude);
+            gps_uart->status.longitude = minmea_tocoord(&frame.longitude);
+            gps_uart->status.time_hours = frame.time.hours;
+            gps_uart->status.time_minutes = frame.time.minutes;
+            gps_uart->status.time_seconds = frame.time.seconds;
+
+            notification_message_block(gps_uart->notifications, &sequence_blink_red_10);
+        }
     } break;
 
     default:
-      break;
-  }
+        break;
+    }
 }
 
-static int32_t gps_uart_worker(void* context)
-{
-  GpsUart* gps_uart = (GpsUart*)context;
+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->rx_stream = furi_stream_buffer_alloc(RX_BUF_SIZE * 5, 1);
+    size_t rx_offset = 0;
 
-  gps_uart_serial_init(gps_uart);
+    gps_uart_serial_init(gps_uart);
 
-  while (1)
-  {
-    uint32_t events =
-    furi_thread_flags_wait(WORKER_ALL_RX_EVENTS, FuriFlagWaitAny, FuriWaitForever);
-    furi_check((events & FuriFlagError) == 0);
+    while(1) {
+        uint32_t events =
+            furi_thread_flags_wait(WORKER_ALL_RX_EVENTS, FuriFlagWaitAny, FuriWaitForever);
+        furi_check((events & FuriFlagError) == 0);
 
-    if (events & WorkerEvtStop)
-    {
-      break;
-    }
-    
-    if (events & WorkerEvtRxDone)
-    {
-      size_t len = 0;
-      do 
-      {
-        // receive serial bytes into rx_buf, starting at rx_offset from the start of the buffer
-        // the maximum we can receive is RX_BUF_SIZE - 1 - rx_offset
-        len = furi_stream_buffer_receive(gps_uart->rx_stream, gps_uart->rx_buf + rx_offset, RX_BUF_SIZE - 1 - rx_offset,
-                                         0);
-        if (len > 0)
-        {
-          // increase rx_offset by the number of bytes received, and null-terminate rx_buf
-          rx_offset += len;
-          gps_uart->rx_buf[rx_offset] = '\0';
-
-          // look for strings ending in newlines, starting at the start of rx_buf
-          char * line_current = (char *)gps_uart->rx_buf;
-          while (1)
-          {
-            // skip null characters
-            while (*line_current == '\0' && line_current < (char *)gps_uart->rx_buf + rx_offset - 1)
-            {
-              line_current++;
-            }
-
-            // find the next newline
-            char * newline = strchr(line_current, '\n');
-            if (newline)  // newline found
-            {
-              // put a null terminator in place of the newline, to delimit the line string
-              *newline = '\0';
-
-              // attempt to parse the line as a NMEA sentence
-              gps_uart_parse_nmea(gps_uart, line_current);
-
-              // move the cursor to the character after the newline
-              line_current = newline + 1;
-            }
-            else  // no more newlines found
-            {
-              if (line_current > (char *)gps_uart->rx_buf)  // at least one line was found
-              {
-                // clear parsed lines, and move any leftover bytes to the start of rx_buf
-                rx_offset = 0;
-                while (*line_current)  // stop when the original rx_offset terminator is reached
-                {
-                  gps_uart->rx_buf[rx_offset++] = *(line_current++);
+        if(events & WorkerEvtStop) {
+            break;
+        }
+
+        if(events & WorkerEvtRxDone) {
+            size_t len = 0;
+            do {
+                // receive serial bytes into rx_buf, starting at rx_offset from the start of the buffer
+                // the maximum we can receive is RX_BUF_SIZE - 1 - rx_offset
+                len = furi_stream_buffer_receive(
+                    gps_uart->rx_stream,
+                    gps_uart->rx_buf + rx_offset,
+                    RX_BUF_SIZE - 1 - rx_offset,
+                    0);
+                if(len > 0) {
+                    // increase rx_offset by the number of bytes received, and null-terminate rx_buf
+                    rx_offset += len;
+                    gps_uart->rx_buf[rx_offset] = '\0';
+
+                    // look for strings ending in newlines, starting at the start of rx_buf
+                    char* line_current = (char*)gps_uart->rx_buf;
+                    while(1) {
+                        // skip null characters
+                        while(*line_current == '\0' &&
+                              line_current < (char*)gps_uart->rx_buf + rx_offset - 1) {
+                            line_current++;
+                        }
+
+                        // find the next newline
+                        char* newline = strchr(line_current, '\n');
+                        if(newline) // newline found
+                        {
+                            // put a null terminator in place of the newline, to delimit the line string
+                            *newline = '\0';
+
+                            // attempt to parse the line as a NMEA sentence
+                            gps_uart_parse_nmea(gps_uart, line_current);
+
+                            // move the cursor to the character after the newline
+                            line_current = newline + 1;
+                        } else // no more newlines found
+                        {
+                            if(line_current >
+                               (char*)gps_uart->rx_buf) // at least one line was found
+                            {
+                                // clear parsed lines, and move any leftover bytes to the start of rx_buf
+                                rx_offset = 0;
+                                while(
+                                    *line_current) // stop when the original rx_offset terminator is reached
+                                {
+                                    gps_uart->rx_buf[rx_offset++] = *(line_current++);
+                                }
+                            }
+                            break; // go back to receiving bytes from the serial stream
+                        }
+                    }
                 }
-              }
-              break;  // go back to receiving bytes from the serial stream
-            }
-          }
+            } while(len > 0);
         }
-      }
-      while (len > 0);
     }
-  }
 
-  gps_uart_serial_deinit(gps_uart);
-  furi_stream_buffer_free(gps_uart->rx_stream);
+    gps_uart_serial_deinit(gps_uart);
+    furi_stream_buffer_free(gps_uart->rx_stream);
 
-  return 0;
+    return 0;
 }
 
-GpsUart* gps_uart_enable()
-{
-  GpsUart* gps_uart = malloc(sizeof(GpsUart));
+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;
-  }
-
-  gps_uart->status.valid = false;
-  gps_uart->status.latitude = 0.0;
-  gps_uart->status.longitude = 0.0;
-  gps_uart->status.speed = 0.0;
-  gps_uart->status.course = 0.0;
-  gps_uart->status.altitude = 0.0;
-  gps_uart->status.altitude_units = ' ';
-  gps_uart->status.fix_quality = 0;
-  gps_uart->status.satellites_tracked = 0;
-  gps_uart->status.time_hours = 0;
-  gps_uart->status.time_minutes = 0;
-  gps_uart->status.time_seconds = 0;
-
-  gps_uart->notifications = furi_record_open(RECORD_NOTIFICATION);
-
-  gps_uart->thread = furi_thread_alloc();
-  furi_thread_set_name(gps_uart->thread, "GpsUartWorker");
-  furi_thread_set_stack_size(gps_uart->thread, 1024);
-  furi_thread_set_context(gps_uart->thread, gps_uart);
-  furi_thread_set_callback(gps_uart->thread, gps_uart_worker);
-
-  furi_thread_start(gps_uart->thread);
-  return gps_uart;
+    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;
+    }
+
+    gps_uart->status.valid = false;
+    gps_uart->status.latitude = 0.0;
+    gps_uart->status.longitude = 0.0;
+    gps_uart->status.speed = 0.0;
+    gps_uart->status.course = 0.0;
+    gps_uart->status.altitude = 0.0;
+    gps_uart->status.altitude_units = ' ';
+    gps_uart->status.fix_quality = 0;
+    gps_uart->status.satellites_tracked = 0;
+    gps_uart->status.time_hours = 0;
+    gps_uart->status.time_minutes = 0;
+    gps_uart->status.time_seconds = 0;
+
+    gps_uart->notifications = furi_record_open(RECORD_NOTIFICATION);
+
+    gps_uart->thread = furi_thread_alloc();
+    furi_thread_set_name(gps_uart->thread, "GpsUartWorker");
+    furi_thread_set_stack_size(gps_uart->thread, 1024);
+    furi_thread_set_context(gps_uart->thread, gps_uart);
+    furi_thread_set_callback(gps_uart->thread, gps_uart_worker);
+
+    furi_thread_start(gps_uart->thread);
+    return gps_uart;
 }
 
-void gps_uart_disable(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);
+void gps_uart_disable(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);
 
-  furi_record_close(RECORD_NOTIFICATION);
+    furi_record_close(RECORD_NOTIFICATION);
 
-  free(gps_uart);
+    free(gps_uart);
 }

+ 20 - 22
gps_uart.h

@@ -6,32 +6,30 @@
 #define GPS_BAUDRATE 9600
 #define RX_BUF_SIZE 1024
 
-typedef struct
-{
-  bool valid;
-  float latitude;
-  float longitude;
-  float speed;
-  float course;
-  float altitude;
-  char altitude_units;
-  int fix_quality;
-  int satellites_tracked;
-  int time_hours;
-  int time_minutes;
-  int time_seconds;
+typedef struct {
+    bool valid;
+    float latitude;
+    float longitude;
+    float speed;
+    float course;
+    float altitude;
+    char altitude_units;
+    int fix_quality;
+    int satellites_tracked;
+    int time_hours;
+    int time_minutes;
+    int time_seconds;
 } GpsStatus;
 
-typedef struct
-{
-  FuriMutex* mutex;
-  FuriThread* thread;
-  FuriStreamBuffer* rx_stream;
-  uint8_t rx_buf[RX_BUF_SIZE];
+typedef struct {
+    FuriMutex* mutex;
+    FuriThread* thread;
+    FuriStreamBuffer* rx_stream;
+    uint8_t rx_buf[RX_BUF_SIZE];
 
-  NotificationApp* notifications;
+    NotificationApp* notifications;
 
-  GpsStatus status;
+    GpsStatus status;
 } GpsUart;
 
 GpsUart* gps_uart_enable();