Skip to content

Commit 5b4cd59

Browse files
committed
merge fixes pt2
by Willy-JL
1 parent ed94779 commit 5b4cd59

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+4968
-2646
lines changed

base_pack/gps_nmea_uart/README.md

Lines changed: 45 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,29 @@
11
# GPS for Flipper Zero
22

3-
A simple Flipper Zero application for NMEA 0183 serial GPS modules, such as the
4-
- Adafruit Ultimate GPS Breakout.
3+
[![FAP Build](https://github.com/ezod/flipperzero-gps/actions/workflows/build.yml/badge.svg)](https://github.com/ezod/flipperzero-gps/actions/workflows/build.yml)
54

6-
Heavy lifting (NMEA parsing) provided by minmea.
5+
A simple Flipper Zero application for NMEA 0183 serial GPS modules.
6+
7+
![ui](ui.png)
8+
9+
Heavy lifting (NMEA parsing) provided by [minmea].
10+
11+
## Installation
12+
13+
1. Navigate to the [FAP Build](https://github.com/ezod/flipperzero-gps/actions/workflows/build.yml)
14+
GitHub action workflow, and select the most recent run.
15+
2. The FAP is built for both the `dev` and `release` channels of the official
16+
firmware. Download the artifact corresponding to your firmware version.
17+
3. Extract `gps_nmea.fap` from the ZIP file to `apps/GPIO` on your Flipper
18+
Zero SD card.
719

820
## Usage
921

1022
This is a single-screen app, and a few interactions are provided via the
1123
hardware buttons:
1224

1325
- Long press the up button to change the **baud rate**. The default baud rate
14-
is 9600, but 19200, 38400, 57600, and 115200 baud are also supported.
26+
is 9600, but 4800, 19200, 38400, 57600, and 115200 baud are also supported.
1527
- Long press the right button to change **speed units** from knots to
1628
kilometers per hour.
1729
- Press the OK button to set the **backlight** to always on mode. Press it
@@ -23,24 +35,43 @@ hardware buttons:
2335
Connect the GPS module to power and the USART using GPIO pins 9 (3.3V), 11
2436
(GND), 13 (TX), and 14 (RX), as appropriate.
2537

38+
![wiring](wiring.png)
2639

27-
See the tutorial video - https://www.youtube.com/watch?v=5vSGFzEBp-k from
28-
Lab401 by RocketGod - https://github.com/RocketGod-git for a visual guide to
40+
See the [tutorial video](https://www.youtube.com/watch?v=5vSGFzEBp-k) from
41+
Lab401 by [RocketGod](https://github.com/RocketGod-git) for a visual guide to
2942
the hardware setup.
3043

31-
## Confirmed Compatible Modules
44+
### Confirmed Compatible Modules
3245

33-
* Adafruit Ultimate GPS Breakout
46+
* [Adafruit Ultimate GPS Breakout]
47+
* ATGM336H
3448
* Beitian BN-180
49+
* Beitian BN-220
50+
* Beitian BN-280
51+
* Beitian BN-880
52+
* Beitian BK-250
53+
* Beitian BK-357
54+
* Beitian BK-880Q
55+
* Beitian BE-280
56+
* Beitian BN-280ZF
57+
* Beitian BN-357ZF
3558
* Royaltek RBT-2100LP
36-
* u-blox NEO-6M
59+
* [u-blox NEO-6M]
60+
* [u-blox NEO-7M]
61+
* [Uputronics u-blox MAX-M8C Pico]
3762

3863
If you have verified this application working with a module not listed here,
3964
please submit a PR adding it to the list.
4065

41-
## Links
66+
## Building
67+
68+
This application can be compiled using [uFBT]. Run `ufbt` in the root directory
69+
of the repository.
4270

43-
Original repo link - https://github.com/ezod/flipperzero-gps
44-
Adafruit Ultimate GPS Breakout: https://www.adafruit.com/product/746
45-
minmea: https://github.com/kosma/minmea
46-
u-blox NEO-6M: https://www.u-blox.com/en/product/neo-6-series
71+
[Adafruit Ultimate GPS Breakout]: https://www.adafruit.com/product/746
72+
[minmea]: https://github.com/kosma/minmea
73+
[qFlipper]: https://flipperzero.one/update
74+
[u-blox NEO-6M]: https://www.u-blox.com/en/product/neo-6-series
75+
[u-blox NEO-7M]: https://www.u-blox.com/en/product/neo-7-series
76+
[uFBT]: https://github.com/flipperdevices/flipperzero-ufbt
77+
[Uputronics u-blox MAX-M8C Pico]: https://store.uputronics.com/index.php?route=product/product&product_id=72

base_pack/gps_nmea_uart/application.fam

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,13 @@ App(
88
order=35,
99
fap_icon="gps_10px.png",
1010
fap_category="GPIO",
11+
fap_private_libs=[
12+
Lib(
13+
name="minmea",
14+
sources=["minmea.c"],
15+
cdefines=["timegm=mktime"],
16+
),
17+
],
1118
fap_author="@ezod & @xMasterX",
1219
fap_version="1.2",
1320
fap_description="Works with GPS modules via UART, using NMEA protocol.",

base_pack/gps_nmea_uart/gps.c

Lines changed: 95 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
#include "constants.h"
33

44
#include <furi.h>
5-
#include <furi_hal_power.h>
65
#include <gui/gui.h>
76
#include <string.h>
87

@@ -21,7 +20,53 @@ static void render_callback(Canvas* const canvas, void* context) {
2120
GpsUart* gps_uart = context;
2221
furi_mutex_acquire(gps_uart->mutex, FuriWaitForever);
2322

24-
if(!gps_uart->changing_baudrate) {
23+
char buffer[64];
24+
25+
switch(gps_uart->view_state) {
26+
case CHANGE_BAUDRATE:
27+
canvas_set_font(canvas, FontPrimary);
28+
canvas_draw_str_aligned(canvas, 64, 32, AlignCenter, AlignBottom, "Baudrate set to:");
29+
snprintf(buffer, 64, "%ld baud", gps_uart->baudrate);
30+
canvas_draw_str_aligned(canvas, 64, 47, AlignCenter, AlignBottom, buffer);
31+
break;
32+
case CHANGE_BACKLIGHT:
33+
canvas_set_font(canvas, FontPrimary);
34+
canvas_draw_str_aligned(
35+
canvas,
36+
64,
37+
32,
38+
AlignCenter,
39+
AlignBottom,
40+
gps_uart->backlight_enabled ? "Backlight enabled" : "Backlight disabled");
41+
break;
42+
case CHANGE_DEEPSLEEP:
43+
canvas_set_font(canvas, FontPrimary);
44+
canvas_draw_str_aligned(
45+
canvas,
46+
64,
47+
32,
48+
AlignCenter,
49+
AlignBottom,
50+
gps_uart->deep_sleep_enabled ? "Deep sleep enabled" : "Deep sleep disabled");
51+
break;
52+
case CHANGE_SPEEDUNIT:
53+
canvas_set_font(canvas, FontPrimary);
54+
canvas_draw_str_aligned(canvas, 64, 32, AlignCenter, AlignBottom, "Speed unit set to:");
55+
switch(gps_uart->speed_units) {
56+
case KPH:
57+
canvas_draw_str_aligned(canvas, 64, 47, AlignCenter, AlignBottom, "km/h");
58+
break;
59+
case MPH:
60+
canvas_draw_str_aligned(canvas, 64, 47, AlignCenter, AlignBottom, "mi/h");
61+
break;
62+
case KNOTS:
63+
default:
64+
canvas_draw_str_aligned(canvas, 64, 47, AlignCenter, AlignBottom, "kn");
65+
break;
66+
}
67+
break;
68+
case NORMAL:
69+
default:
2570
canvas_set_font(canvas, FontPrimary);
2671
canvas_draw_str_aligned(canvas, 32, 8, AlignCenter, AlignBottom, "Latitude");
2772
canvas_draw_str_aligned(canvas, 96, 8, AlignCenter, AlignBottom, "Longitude");
@@ -32,7 +77,6 @@ static void render_callback(Canvas* const canvas, void* context) {
3277
canvas_draw_str_aligned(canvas, 96, 52, AlignCenter, AlignBottom, "Last Fix");
3378

3479
canvas_set_font(canvas, FontSecondary);
35-
char buffer[64];
3680
snprintf(buffer, 64, "%f", (double)gps_uart->status.latitude);
3781
canvas_draw_str_aligned(canvas, 32, 18, AlignCenter, AlignBottom, buffer);
3882
snprintf(buffer, 64, "%f", (double)gps_uart->status.longitude);
@@ -42,10 +86,10 @@ static void render_callback(Canvas* const canvas, void* context) {
4286

4387
switch(gps_uart->speed_units) {
4488
case KPH:
45-
snprintf(buffer, 64, "%.2f km", (double)(gps_uart->status.speed * KNOTS_TO_KPH));
89+
snprintf(buffer, 64, "%.2f km/h", (double)(gps_uart->status.speed * KNOTS_TO_KPH));
4690
break;
4791
case MPH:
48-
snprintf(buffer, 64, "%.2f mi", (double)(gps_uart->status.speed * KNOTS_TO_MPH));
92+
snprintf(buffer, 64, "%.2f mi/h", (double)(gps_uart->status.speed * KNOTS_TO_MPH));
4993
break;
5094
case KNOTS:
5195
default:
@@ -71,13 +115,7 @@ static void render_callback(Canvas* const canvas, void* context) {
71115
gps_uart->status.time_minutes,
72116
gps_uart->status.time_seconds);
73117
canvas_draw_str_aligned(canvas, 96, 62, AlignCenter, AlignBottom, buffer);
74-
} else {
75-
char buffer[64];
76-
canvas_set_font(canvas, FontPrimary);
77-
canvas_draw_str_aligned(canvas, 64, 32, AlignCenter, AlignBottom, "Baudrate set to:");
78-
79-
snprintf(buffer, 64, "%ld baud", gps_uart->baudrate);
80-
canvas_draw_str_aligned(canvas, 64, 47, AlignCenter, AlignBottom, buffer);
118+
break;
81119
}
82120

83121
furi_mutex_release(gps_uart->mutex);
@@ -95,14 +133,6 @@ int32_t gps_app(void* p) {
95133

96134
FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(PluginEvent));
97135

98-
uint8_t attempts = 0;
99-
bool otg_was_enabled = furi_hal_power_is_otg_enabled();
100-
while(!furi_hal_power_is_otg_enabled() && attempts++ < 5) {
101-
furi_hal_power_enable_otg();
102-
furi_delay_ms(10);
103-
}
104-
furi_delay_ms(200);
105-
106136
GpsUart* gps_uart = gps_uart_enable();
107137

108138
gps_uart->mutex = furi_mutex_alloc(FuriMutexTypeNormal);
@@ -112,6 +142,14 @@ int32_t gps_app(void* p) {
112142
return 255;
113143
}
114144

145+
uint8_t attempts = 0;
146+
bool otg_was_enabled = furi_hal_power_is_otg_enabled();
147+
while(!furi_hal_power_is_otg_enabled() && attempts++ < 5) {
148+
furi_hal_power_enable_otg();
149+
furi_delay_ms(10);
150+
}
151+
furi_delay_ms(200);
152+
115153
// set system callbacks
116154
ViewPort* view_port = view_port_alloc();
117155
view_port_draw_callback_set(view_port, render_callback, gps_uart);
@@ -132,24 +170,27 @@ int32_t gps_app(void* p) {
132170
if(event.type == EventTypeKey) {
133171
if(event.input.type == InputTypeShort) {
134172
switch(event.input.key) {
135-
case InputKeyUp:
136-
case InputKeyDown:
137-
case InputKeyRight:
138-
case InputKeyLeft:
139173
case InputKeyBack:
174+
processing = false;
140175
break;
141176
case InputKeyOk:
142-
if(!gps_uart->backlight_on) {
177+
if(!gps_uart->backlight_enabled) {
143178
notification_message_block(
144179
gps_uart->notifications, &sequence_display_backlight_enforce_on);
145-
gps_uart->backlight_on = true;
180+
gps_uart->backlight_enabled = true;
146181
} else {
147182
notification_message_block(
148183
gps_uart->notifications, &sequence_display_backlight_enforce_auto);
149184
notification_message(
150185
gps_uart->notifications, &sequence_display_backlight_off);
151-
gps_uart->backlight_on = false;
186+
gps_uart->backlight_enabled = false;
152187
}
188+
189+
gps_uart->view_state = CHANGE_BACKLIGHT;
190+
furi_mutex_release(gps_uart->mutex);
191+
view_port_update(view_port);
192+
furi_delay_ms(1000);
193+
gps_uart->view_state = NORMAL;
153194
break;
154195
default:
155196
break;
@@ -167,15 +208,39 @@ int32_t gps_app(void* p) {
167208
gps_uart->baudrate = gps_baudrates[current_gps_baudrate];
168209

169210
gps_uart_init_thread(gps_uart);
170-
gps_uart->changing_baudrate = true;
211+
gps_uart->view_state = CHANGE_BAUDRATE;
212+
171213
furi_mutex_release(gps_uart->mutex);
172214
view_port_update(view_port);
215+
furi_delay_ms(1000);
216+
gps_uart->view_state = NORMAL;
173217
break;
174218
case InputKeyRight:
175219
gps_uart->speed_units++;
176220
if(gps_uart->speed_units == INVALID) {
177221
gps_uart->speed_units = KNOTS;
178222
}
223+
224+
gps_uart->view_state = CHANGE_SPEEDUNIT;
225+
furi_mutex_release(gps_uart->mutex);
226+
view_port_update(view_port);
227+
furi_delay_ms(1000);
228+
gps_uart->view_state = NORMAL;
229+
break;
230+
case InputKeyDown:
231+
gps_uart->view_state = CHANGE_DEEPSLEEP;
232+
gps_uart->deep_sleep_enabled = !gps_uart->deep_sleep_enabled;
233+
234+
// tested on Telit SE868-A and SL871L-S
235+
furi_hal_serial_tx(
236+
gps_uart->serial_handle,
237+
(uint8_t*)"$PMTK161,0*28\r\n",
238+
strlen("$PMTK161,0*28\r\n"));
239+
240+
furi_mutex_release(gps_uart->mutex);
241+
view_port_update(view_port);
242+
furi_delay_ms(1000);
243+
gps_uart->view_state = NORMAL;
179244
break;
180245
case InputKeyBack:
181246
processing = false;
@@ -186,12 +251,10 @@ int32_t gps_app(void* p) {
186251
}
187252
}
188253
}
189-
if(!gps_uart->changing_baudrate) {
254+
255+
if(gps_uart->view_state == NORMAL) {
190256
furi_mutex_release(gps_uart->mutex);
191257
view_port_update(view_port);
192-
} else {
193-
furi_delay_ms(1000);
194-
gps_uart->changing_baudrate = false;
195258
}
196259
}
197260

base_pack/gps_nmea_uart/gps_uart.c

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#include <string.h>
22

3-
#include "minmea.h"
3+
#include <minmea.h>
44
#include "gps_uart.h"
55

66
typedef enum {
@@ -10,25 +10,31 @@ typedef enum {
1010

1111
#define WORKER_ALL_RX_EVENTS (WorkerEvtStop | WorkerEvtRxDone)
1212

13-
static void gps_uart_on_irq_cb(UartIrqEvent ev, uint8_t data, void* context) {
13+
static void
14+
gps_uart_on_irq_cb(FuriHalSerialHandle* handle, FuriHalSerialRxEvent event, void* context) {
1415
GpsUart* gps_uart = (GpsUart*)context;
1516

16-
if(ev == UartIrqEventRXNE) {
17+
if(event == FuriHalSerialRxEventData) {
18+
uint8_t data = furi_hal_serial_async_rx(handle);
1719
furi_stream_buffer_send(gps_uart->rx_stream, &data, 1, 0);
1820
furi_thread_flags_set(furi_thread_get_id(gps_uart->thread), WorkerEvtRxDone);
1921
}
2022
}
2123

2224
static void gps_uart_serial_init(GpsUart* gps_uart) {
23-
furi_hal_console_disable();
24-
furi_hal_uart_set_irq_cb(FuriHalUartIdUSART1, gps_uart_on_irq_cb, gps_uart);
25-
furi_hal_uart_set_br(FuriHalUartIdUSART1, gps_uart->baudrate);
25+
gps_uart->serial_handle = furi_hal_serial_control_acquire(UART_CH);
26+
furi_check(gps_uart->serial_handle);
27+
furi_hal_serial_init(gps_uart->serial_handle, gps_uart->baudrate);
28+
furi_hal_serial_async_rx_start(gps_uart->serial_handle, gps_uart_on_irq_cb, gps_uart, false);
29+
30+
furi_hal_serial_tx(
31+
gps_uart->serial_handle, (uint8_t*)"wakey wakey\r\n", strlen("wakey wakey\r\n"));
2632
}
2733

2834
static void gps_uart_serial_deinit(GpsUart* gps_uart) {
2935
UNUSED(gps_uart);
30-
furi_hal_uart_set_irq_cb(FuriHalUartIdUSART1, NULL, NULL);
31-
furi_hal_console_enable();
36+
furi_hal_serial_deinit(gps_uart->serial_handle);
37+
furi_hal_serial_control_release(gps_uart->serial_handle);
3238
}
3339

3440
static void gps_uart_parse_nmea(GpsUart* gps_uart, char* line) {
@@ -202,9 +208,10 @@ GpsUart* gps_uart_enable() {
202208
gps_uart->notifications = furi_record_open(RECORD_NOTIFICATION);
203209

204210
gps_uart->baudrate = gps_baudrates[current_gps_baudrate];
205-
gps_uart->changing_baudrate = false;
206-
gps_uart->backlight_on = false;
207211
gps_uart->speed_units = KNOTS;
212+
gps_uart->backlight_enabled = false;
213+
gps_uart->deep_sleep_enabled = false;
214+
gps_uart->view_state = NORMAL;
208215

209216
gps_uart_init_thread(gps_uart);
210217

0 commit comments

Comments
 (0)