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

Update GBA Cartridge 2.0 New Serial API closes #19

Esteban Fuentealba 1 год назад
Родитель
Сommit
f319e6076b
6 измененных файлов с 78 добавлено и 52 удалено
  1. 1 1
      application.fam
  2. 8 0
      gba_cartridge_app.c
  3. 1 0
      gba_cartridge_app.h
  4. 60 44
      uart.c
  5. 6 5
      uart.h
  6. 2 2
      views/gba_cartridge_scene_1.c

+ 1 - 1
application.fam

@@ -14,7 +14,7 @@ App(
     fap_icon="icons/icon.png",
     fap_icon="icons/icon.png",
     fap_icon_assets="icons",
     fap_icon_assets="icons",
     fap_category="GPIO",
     fap_category="GPIO",
-    fap_version=[1,1],
+    fap_version=[2,0],
     fap_author="Esteban Fuentealba",
     fap_author="Esteban Fuentealba",
     fap_weburl="https://github.com/EstebanFuentealba/MALVEKE-Flipper-Zero"
     fap_weburl="https://github.com/EstebanFuentealba/MALVEKE-Flipper-Zero"
 )
 )

+ 8 - 0
gba_cartridge_app.c

@@ -91,6 +91,10 @@ void gba_cartridge_app_app_free(GBACartridge* app) {
 
 
 int32_t gba_cartridge_app(void* p) {
 int32_t gba_cartridge_app(void* p) {
     UNUSED(p);
     UNUSED(p);
+    // Disable expansion protocol to avoid interference with UART Handle
+    Expansion* expansion = furi_record_open(RECORD_EXPANSION);
+    expansion_disable(expansion);
+
     GBACartridge* app = gba_cartridge_app_app_alloc();
     GBACartridge* app = gba_cartridge_app_app_alloc();
     
     
     view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen);
     view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen);
@@ -103,6 +107,10 @@ int32_t gba_cartridge_app(void* p) {
     
     
     furi_hal_power_suppress_charge_exit();
     furi_hal_power_suppress_charge_exit();
     gba_cartridge_app_app_free(app);
     gba_cartridge_app_app_free(app);
+
+    // Return previous state of expansion
+    expansion_enable(expansion);
+    furi_record_close(RECORD_EXPANSION);
     
     
     return 0;
     return 0;
 }
 }

+ 1 - 0
gba_cartridge_app.h

@@ -14,6 +14,7 @@
 #include <gui/modules/variable_item_list.h>
 #include <gui/modules/variable_item_list.h>
 #include <gui/modules/button_menu.h>
 #include <gui/modules/button_menu.h>
 #include <gui/modules/dialog_ex.h>
 #include <gui/modules/dialog_ex.h>
+#include <expansion/expansion.h>
 #include "scenes/gba_cartridge_scene.h"
 #include "scenes/gba_cartridge_scene.h"
 #include "views/gba_cartridge_startscreen.h"
 #include "views/gba_cartridge_startscreen.h"
 #include "views/gba_cartridge_scene_1.h"
 #include "views/gba_cartridge_scene_1.h"

+ 60 - 44
uart.c

@@ -1,23 +1,28 @@
 #include "uart.h"
 #include "uart.h"
 
 
-#define UART_CH (FuriHalUartIdUSART1)
-#define LP_UART_CH (FuriHalUartIdLPUART1)
-#define BAUDRATE (115200)
+#define UART_CH (FuriHalSerialIdUsart)
+#define LP_UART_CH (FuriHalSerialIdLpuart)
+#define BAUDRATE (115200UL)
 
 
 struct Uart {
 struct Uart {
     void* app;
     void* app;
-    FuriHalUartId channel;
     FuriThread* rx_thread;
     FuriThread* rx_thread;
+    FuriHalSerialHandle* serial_handle;
+    FuriHalSerialId channel;
+    FuriThread* worker_thread;
     FuriStreamBuffer* rx_stream;
     FuriStreamBuffer* rx_stream;
     uint8_t rx_buf[RX_BUF_SIZE + 1];
     uint8_t rx_buf[RX_BUF_SIZE + 1];
     void (*handle_rx_data_cb)(uint8_t* buf, size_t len, void* context);
     void (*handle_rx_data_cb)(uint8_t* buf, size_t len, void* context);
 };
 };
 
 
-
 typedef enum {
 typedef enum {
     WorkerEvtStop = (1 << 0),
     WorkerEvtStop = (1 << 0),
     WorkerEvtRxDone = (1 << 1),
     WorkerEvtRxDone = (1 << 1),
-} WorkerEvtFlags;
+} WorkerEventFlags;
+
+#define WORKER_ALL_RX_EVENTS (WorkerEvtStop | WorkerEvtRxDone)
+
+
 
 
 void uart_set_handle_rx_data_cb(
 void uart_set_handle_rx_data_cb(
     Uart* uart,
     Uart* uart,
@@ -26,17 +31,29 @@ void uart_set_handle_rx_data_cb(
     uart->handle_rx_data_cb = handle_rx_data_cb;
     uart->handle_rx_data_cb = handle_rx_data_cb;
 }
 }
 
 
-#define WORKER_ALL_RX_EVENTS (WorkerEvtStop | WorkerEvtRxDone)
-
-void uart_on_irq_cb(UartIrqEvent ev, uint8_t data, void* context) {
+static void wifi_marauder_uart_on_irq_cb(
+    FuriHalSerialHandle* handle,
+    FuriHalSerialRxEvent event,
+    void* context) {
     Uart* uart = (Uart*)context;
     Uart* uart = (Uart*)context;
 
 
-    if(ev == UartIrqEventRXNE) {
+    if(event == FuriHalSerialRxEventData) {
+        uint8_t data = furi_hal_serial_async_rx(handle);
         furi_stream_buffer_send(uart->rx_stream, &data, 1, 0);
         furi_stream_buffer_send(uart->rx_stream, &data, 1, 0);
         furi_thread_flags_set(furi_thread_get_id(uart->rx_thread), WorkerEvtRxDone);
         furi_thread_flags_set(furi_thread_get_id(uart->rx_thread), WorkerEvtRxDone);
     }
     }
 }
 }
 
 
+static void uart_on_irq_cb(FuriHalSerialHandle* handle, FuriHalSerialRxEvent event, void* context) {
+    Uart* uart = (Uart*)context;
+    UNUSED(handle);
+
+    if(event & (FuriHalSerialRxEventData | FuriHalSerialRxEventIdle)) {
+        uint8_t data = furi_hal_serial_async_rx(handle);
+        furi_stream_buffer_send(uart->rx_stream, &data, 1, 0);
+        furi_thread_flags_set(furi_thread_get_id(uart->rx_thread), WorkerEvtRxDone);
+    }
+}
 
 
 // Define una constante para el prefijo que estamos buscando
 // Define una constante para el prefijo que estamos buscando
 #define JSON_PREFIX "JSON:"
 #define JSON_PREFIX "JSON:"
@@ -50,26 +67,25 @@ static bool json_capture_active = false;
 // Prototipo de la función
 // Prototipo de la función
 // static void process_json_buffer();
 // static void process_json_buffer();
 
 
-
 static void process_json_buffer(void* context) {
 static void process_json_buffer(void* context) {
     Uart* uart = (Uart*)context;
     Uart* uart = (Uart*)context;
     // Agregamos el terminador nulo al final del buffer
     // Agregamos el terminador nulo al final del buffer
     json_buffer[json_buffer_index] = '\0';
     json_buffer[json_buffer_index] = '\0';
-    if (uart->handle_rx_data_cb) {
-        uart->handle_rx_data_cb((uint8_t *)json_buffer, json_buffer_index, uart->app);
+    if(uart->handle_rx_data_cb) {
+        uart->handle_rx_data_cb((uint8_t*)json_buffer, json_buffer_index, uart->app);
         memset(json_buffer, 0, sizeof(json_buffer));
         memset(json_buffer, 0, sizeof(json_buffer));
     }
     }
-    
+
     // Reiniciamos el buffer
     // Reiniciamos el buffer
     json_buffer_index = 0;
     json_buffer_index = 0;
 }
 }
 
 
 static void uart_echo_push_to_list(void* context, uint8_t data) {
 static void uart_echo_push_to_list(void* context, uint8_t data) {
     Uart* uart = (Uart*)context;
     Uart* uart = (Uart*)context;
-    if (!json_capture_active) {
-        if (data == JSON_PREFIX[json_buffer_index]) {
+    if(!json_capture_active) {
+        if(data == JSON_PREFIX[json_buffer_index]) {
             json_buffer[json_buffer_index++] = data; // Agregar el carácter al buffer
             json_buffer[json_buffer_index++] = data; // Agregar el carácter al buffer
-            if (json_buffer_index == strlen(JSON_PREFIX)) {
+            if(json_buffer_index == strlen(JSON_PREFIX)) {
                 // Encontramos el prefijo, comenzamos a capturar
                 // Encontramos el prefijo, comenzamos a capturar
                 json_buffer_index = 0;
                 json_buffer_index = 0;
                 json_capture_active = true;
                 json_capture_active = true;
@@ -81,7 +97,7 @@ static void uart_echo_push_to_list(void* context, uint8_t data) {
     } else {
     } else {
         // Capturamos caracteres hasta encontrar '\n'
         // Capturamos caracteres hasta encontrar '\n'
         json_buffer[json_buffer_index++] = data;
         json_buffer[json_buffer_index++] = data;
-        if (data == '\n') {
+        if(data == '\n') {
             // Terminamos de capturar la línea, procesamos el buffer
             // Terminamos de capturar la línea, procesamos el buffer
             json_capture_active = false;
             json_capture_active = false;
             process_json_buffer(uart);
             process_json_buffer(uart);
@@ -93,7 +109,8 @@ static int32_t uart_worker(void* context) {
     Uart* uart = (Uart*)context;
     Uart* uart = (Uart*)context;
 
 
     while(1) {
     while(1) {
-        uint32_t events = furi_thread_flags_wait(WORKER_ALL_RX_EVENTS, FuriFlagWaitAny, FuriWaitForever);
+       uint32_t events =
+            furi_thread_flags_wait(WORKER_ALL_RX_EVENTS, FuriFlagWaitAny, FuriWaitForever);
         furi_check((events & FuriFlagError) == 0);
         furi_check((events & FuriFlagError) == 0);
 
 
         if(events & WorkerEvtStop) break;
         if(events & WorkerEvtStop) break;
@@ -103,17 +120,20 @@ static int32_t uart_worker(void* context) {
                 do {
                 do {
                     uint8_t data[64];
                     uint8_t data[64];
                     length = furi_stream_buffer_receive(uart->rx_stream, data, 64, 0);
                     length = furi_stream_buffer_receive(uart->rx_stream, data, 64, 0);
-                    // FURI_LOG_I("UART", "[in]: %s", (char*)data);
+
                     if(length > 0) {
                     if(length > 0) {
                         for(size_t i = 0; i < length; i++) {
                         for(size_t i = 0; i < length; i++) {
                             uart_echo_push_to_list(uart, data[i]);
                             uart_echo_push_to_list(uart, data[i]);
+                            // FURI_LOG_I("UART", "[in]: %c - %d", (const char)data[i], data[i]);
                         }
                         }
                     }
                     }
                 } while(length > 0);
                 } while(length > 0);
             } else if(uart->channel == LP_UART_CH) {
             } else if(uart->channel == LP_UART_CH) {
-                size_t len = furi_stream_buffer_receive(uart->rx_stream, uart->rx_buf, RX_BUF_SIZE, 0);
+                size_t len =
+                    furi_stream_buffer_receive(uart->rx_stream, uart->rx_buf, RX_BUF_SIZE, 0);
                 if(len > 0) {
                 if(len > 0) {
-                    if(uart->handle_rx_data_cb) uart->handle_rx_data_cb(uart->rx_buf, len, uart->app);
+                    if(uart->handle_rx_data_cb)
+                        uart->handle_rx_data_cb(uart->rx_buf, len, uart->app);
                 }
                 }
             }
             }
         }
         }
@@ -122,19 +142,13 @@ static int32_t uart_worker(void* context) {
 
 
     return 0;
     return 0;
 }
 }
-
-void uart_tx(uint8_t* data, size_t len) {
-    furi_hal_uart_tx(UART_CH, data, len);
+void uart_tx(void* app, uint8_t* data, size_t len) {
+    Uart* uart = (Uart*)app;
+    furi_hal_serial_tx(uart->serial_handle, data, len);
 }
 }
 
 
-void lp_uart_tx(uint8_t* data, size_t len) {
-    furi_hal_uart_tx(LP_UART_CH, data, len);
-}
-
-Uart*
-    _uart_init(void* app, FuriHalUartId channel, const char* thread_name) {
+Uart* _uart_init(void* app, FuriHalSerialId channel, const char* thread_name) {
     Uart* uart = (Uart*)malloc(sizeof(Uart));
     Uart* uart = (Uart*)malloc(sizeof(Uart));
-
     uart->app = app;
     uart->app = app;
     uart->channel = channel;
     uart->channel = channel;
     uart->rx_stream = furi_stream_buffer_alloc(RX_BUF_SIZE, 1);
     uart->rx_stream = furi_stream_buffer_alloc(RX_BUF_SIZE, 1);
@@ -144,13 +158,18 @@ Uart*
     furi_thread_set_context(uart->rx_thread, uart);
     furi_thread_set_context(uart->rx_thread, uart);
     furi_thread_set_callback(uart->rx_thread, uart_worker);
     furi_thread_set_callback(uart->rx_thread, uart_worker);
     furi_thread_start(uart->rx_thread);
     furi_thread_start(uart->rx_thread);
-    if(channel == FuriHalUartIdUSART1) {
-        furi_hal_console_disable();
-    } else if(channel == FuriHalUartIdLPUART1) {
-        furi_hal_uart_init(channel, BAUDRATE);
+    uart->serial_handle = furi_hal_serial_control_acquire(channel);
+    if(!uart->serial_handle) {
+        furi_delay_ms(5000);
     }
     }
-    furi_hal_uart_set_br(channel, BAUDRATE);
-    furi_hal_uart_set_irq_cb(channel, uart_on_irq_cb, uart);
+    furi_check(uart->serial_handle);
+    furi_hal_serial_init(uart->serial_handle,  BAUDRATE);
+    furi_hal_serial_async_rx_start(
+        uart->serial_handle,
+        channel == FuriHalSerialIdUsart ? uart_on_irq_cb : wifi_marauder_uart_on_irq_cb,
+        uart,
+        false);
+
 
 
     return uart;
     return uart;
 }
 }
@@ -166,15 +185,12 @@ Uart* lp_uart_init(void* app) {
 void uart_free(Uart* uart) {
 void uart_free(Uart* uart) {
     furi_assert(uart);
     furi_assert(uart);
 
 
-    furi_thread_flags_set(furi_thread_get_id(uart->rx_thread), WorkerEvtStop);
+   furi_thread_flags_set(furi_thread_get_id(uart->rx_thread), WorkerEvtStop);
     furi_thread_join(uart->rx_thread);
     furi_thread_join(uart->rx_thread);
     furi_thread_free(uart->rx_thread);
     furi_thread_free(uart->rx_thread);
 
 
-    furi_hal_uart_set_irq_cb(uart->channel, NULL, NULL);
-    if(uart->channel == FuriHalUartIdLPUART1) {
-        furi_hal_uart_deinit(uart->channel);
-    }
-    furi_hal_console_enable();
+    furi_hal_serial_deinit(uart->serial_handle);
+    furi_hal_serial_control_release(uart->serial_handle);
 
 
     free(uart);
     free(uart);
 }
 }

+ 6 - 5
uart.h

@@ -3,16 +3,17 @@
 
 
 #pragma once
 #pragma once
 
 
-#include "furi_hal.h"
-
+#include <furi.h>
+#include <furi_hal.h>
 
 
 #define RX_BUF_SIZE (1024)
 #define RX_BUF_SIZE (1024)
 
 
 typedef struct Uart Uart;
 typedef struct Uart Uart;
 
 
-void uart_set_handle_rx_data_cb(Uart* uart, void (*handle_rx_data_cb)(uint8_t* buf, size_t len, void* context));
-void uart_tx(uint8_t* data, size_t len);
-void lp_uart_tx(uint8_t* data, size_t len);
+void uart_set_handle_rx_data_cb(
+    Uart* uart,
+    void (*handle_rx_data_cb)(uint8_t* buf, size_t len, void* context));
+void uart_tx(void* app, uint8_t* data, size_t len);
 Uart* usart_init(void* app);
 Uart* usart_init(void* app);
 Uart* lp_uart_init(void* app);
 Uart* lp_uart_init(void* app);
 void uart_free(Uart* uart);
 void uart_free(Uart* uart);

+ 2 - 2
views/gba_cartridge_scene_1.c

@@ -240,7 +240,7 @@ bool gba_cartridge_scene_1_input(InputEvent* event, void* context) {
                         // Register callbacks to receive data
                         // Register callbacks to receive data
                         uart_set_handle_rx_data_cb(((GBACartridge*)instance->app)->uart, gameboy_information_handle_rx_data_cb); // setup callback for general log rx thread
                         uart_set_handle_rx_data_cb(((GBACartridge*)instance->app)->uart, gameboy_information_handle_rx_data_cb); // setup callback for general log rx thread
                         const char GBACartridge_command[] = "gbacartridge -i\n";
                         const char GBACartridge_command[] = "gbacartridge -i\n";
-                        uart_tx((uint8_t*)GBACartridge_command, strlen(GBACartridge_command));
+                        uart_tx(((GBACartridge*)instance->app)->uart, (uint8_t*)GBACartridge_command, strlen(GBACartridge_command));
                     },
                     },
                     true);
                     true);
                 consumed = true;
                 consumed = true;
@@ -285,7 +285,7 @@ void gba_cartridge_scene_1_enter(void* context) {
     // Register callbacks to receive data
     // Register callbacks to receive data
     uart_set_handle_rx_data_cb(((GBACartridge*)instance->app)->uart, gameboy_information_handle_rx_data_cb); // setup callback for general log rx thread
     uart_set_handle_rx_data_cb(((GBACartridge*)instance->app)->uart, gameboy_information_handle_rx_data_cb); // setup callback for general log rx thread
     const char GBACartridge_command[] = "gbacartridge -i\n";
     const char GBACartridge_command[] = "gbacartridge -i\n";
-    uart_tx((uint8_t*)GBACartridge_command, strlen(GBACartridge_command));
+    uart_tx(((GBACartridge*)instance->app)->uart,(uint8_t*)GBACartridge_command, strlen(GBACartridge_command));
 }
 }
 
 
 GBACartridgeScene1* gba_cartridge_scene_1_alloc() {
 GBACartridgeScene1* gba_cartridge_scene_1_alloc() {