Kaynağa Gözat

Update GB Cartridge 2.0 New Serial API closes #17

Esteban Fuentealba 1 yıl önce
ebeveyn
işleme
6edb684b38

+ 1 - 1
application.fam

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

+ 21 - 8
gb_cartridge_app.c

@@ -128,13 +128,12 @@ GBCartridge* gb_cartridge_app_app_alloc() {
     //  Enable 5v
     furi_hal_power_enable_otg();
     furi_delay_ms(1);
+    furi_hal_power_insomnia_enter();
     return app;
 }
 
 void gb_cartridge_app_app_free(GBCartridge* app) {
     furi_assert(app);
-    // Scene manager
-    scene_manager_free(app->scene_manager);
 
     // View Dispatcher
     view_dispatcher_remove_view(app->view_dispatcher, GBCartridgeViewIdMenu);
@@ -143,9 +142,12 @@ void gb_cartridge_app_app_free(GBCartridge* app) {
     view_dispatcher_remove_view(app->view_dispatcher, GBCartridgeViewIdSettings);
     variable_item_list_free(app->submenu);
 
+    // storage_file_free(app->file_path);
+
+
     view_dispatcher_free(app->view_dispatcher);
-    furi_record_close(RECORD_GUI);
-    furi_record_close(RECORD_STORAGE);
+    scene_manager_free(app->scene_manager);
+    
 
     app->gui = NULL;
     app->notification = NULL;
@@ -156,7 +158,9 @@ void gb_cartridge_app_app_free(GBCartridge* app) {
     uart_free(app->lp_uart);
     // Close File Browser
     furi_record_close(RECORD_DIALOGS);
-    furi_string_free(app->file_path);
+    furi_record_close(RECORD_GUI);
+    furi_record_close(RECORD_STORAGE);
+    // furi_string_free(app->file_path);
 
     //Remove whatever is left
     free(app);
@@ -164,6 +168,9 @@ void gb_cartridge_app_app_free(GBCartridge* app) {
 
 int32_t gb_cartridge_app(void* p) {
     UNUSED(p);
+    // Disable expansion protocol to avoid interference with UART Handle
+    Expansion* expansion = furi_record_open(RECORD_EXPANSION);
+    expansion_disable(expansion);
     // uint8_t attempts = 0;
     // while(!furi_hal_power_is_otg_enabled() && attempts++ < 5) {
     //     furi_hal_power_enable_otg();
@@ -195,8 +202,14 @@ int32_t gb_cartridge_app(void* p) {
 
     furi_hal_power_suppress_charge_exit();
     gb_cartridge_app_app_free(app);
-    // if(furi_hal_power_is_otg_enabled()) {
-    //     furi_hal_power_disable_otg();
-    // }
+
+    if(furi_hal_power_is_otg_enabled()) {
+        furi_hal_power_disable_otg();
+    }
+
+    // Return previous state of expansion
+    expansion_enable(expansion);
+    furi_record_close(RECORD_EXPANSION);
+   
     return 0;
 }

+ 1 - 0
gb_cartridge_app.h

@@ -6,6 +6,7 @@
 #include <input/input.h>
 #include <stdlib.h>
 #include <dialogs/dialogs.h>
+#include <expansion/expansion.h>
 #include <notification/notification_messages.h>
 #include <gui/view_dispatcher.h>
 #include <gui/modules/submenu.h>

+ 46 - 30
uart.c

@@ -1,13 +1,15 @@
 #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 {
     void* app;
-    FuriHalUartId channel;
     FuriThread* rx_thread;
+    FuriHalSerialHandle* serial_handle;
+    FuriHalSerialId channel;
+    FuriThread* worker_thread;
     FuriStreamBuffer* rx_stream;
     uint8_t rx_buf[RX_BUF_SIZE + 1];
     void (*handle_rx_data_cb)(uint8_t* buf, size_t len, void* context);
@@ -16,7 +18,11 @@ struct Uart {
 typedef enum {
     WorkerEvtStop = (1 << 0),
     WorkerEvtRxDone = (1 << 1),
-} WorkerEvtFlags;
+} WorkerEventFlags;
+
+#define WORKER_ALL_RX_EVENTS (WorkerEvtStop | WorkerEvtRxDone)
+
+
 
 void uart_set_handle_rx_data_cb(
     Uart* uart,
@@ -25,12 +31,25 @@ void uart_set_handle_rx_data_cb(
     uart->handle_rx_data_cb = handle_rx_data_cb;
 }
 
-#define WORKER_ALL_RX_EVENTS (WorkerEvtStop | WorkerEvtRxDone)
+static void wifi_marauder_uart_on_irq_cb(
+    FuriHalSerialHandle* handle,
+    FuriHalSerialRxEvent event,
+    void* context) {
+    Uart* uart = (Uart*)context;
 
-void uart_on_irq_cb(UartIrqEvent ev, uint8_t data, void* context) {
+    if(event == FuriHalSerialRxEventData) {
+        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);
+    }
+}
+
+static void uart_on_irq_cb(FuriHalSerialHandle* handle, FuriHalSerialRxEvent event, void* context) {
     Uart* uart = (Uart*)context;
+    UNUSED(handle);
 
-    if(ev == UartIrqEventRXNE) {
+    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);
     }
@@ -90,7 +109,7 @@ static int32_t uart_worker(void* context) {
     Uart* uart = (Uart*)context;
 
     while(1) {
-        uint32_t events =
+       uint32_t events =
             furi_thread_flags_wait(WORKER_ALL_RX_EVENTS, FuriFlagWaitAny, FuriWaitForever);
         furi_check((events & FuriFlagError) == 0);
 
@@ -123,18 +142,13 @@ static int32_t uart_worker(void* context) {
 
     return 0;
 }
-
-void uart_tx(uint8_t* data, size_t len) {
-    furi_hal_uart_tx(UART_CH, data, len);
-}
-
-void lp_uart_tx(uint8_t* data, size_t len) {
-    furi_hal_uart_tx(LP_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);
 }
 
-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->app = app;
     uart->channel = channel;
     uart->rx_stream = furi_stream_buffer_alloc(RX_BUF_SIZE, 1);
@@ -144,13 +158,18 @@ Uart* _uart_init(void* app, FuriHalUartId channel, const char* thread_name) {
     furi_thread_set_context(uart->rx_thread, uart);
     furi_thread_set_callback(uart->rx_thread, uart_worker);
     furi_thread_start(uart->rx_thread);
-    if(channel == FuriHalUartIdUSART1) {
-        furi_hal_console_disable(); //  Disable console for UART <-> Serial transfer, TODO: Pass transfer RAM to Serial1/LPUART1
-    } 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;
 }
@@ -166,15 +185,12 @@ Uart* lp_uart_init(void* app) {
 void uart_free(Uart* 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_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);
 }

+ 3 - 3
uart.h

@@ -3,7 +3,8 @@
 
 #pragma once
 
-#include "furi_hal.h"
+#include <furi.h>
+#include <furi_hal.h>
 
 #define RX_BUF_SIZE (1024)
 
@@ -12,8 +13,7 @@ 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_tx(void* app, uint8_t* data, size_t len);
 Uart* usart_init(void* app);
 Uart* lp_uart_init(void* app);
 void uart_free(Uart* uart);

+ 2 - 2
views/gb_cartridge_scene_1.c

@@ -328,7 +328,7 @@ bool gb_cartridge_scene_1_input(InputEvent* event, void* context) {
                         ((GBCartridge*)instance->app)->uart,
                         gameboy_information_handle_rx_data_cb); // setup callback for general log rx thread
                     const char gbcartridge_command[] = "gbcartridge -i\n";
-                    uart_tx((uint8_t*)gbcartridge_command, strlen(gbcartridge_command));
+                    uart_tx(((GBCartridge*)instance->app)->uart, (uint8_t*)gbcartridge_command, strlen(gbcartridge_command));
                 },
                 true);
             consumed = true;
@@ -367,7 +367,7 @@ void gb_cartridge_scene_1_enter(void* context) {
         ((GBCartridge*)instance->app)->uart,
         gameboy_information_handle_rx_data_cb); // setup callback for general log rx thread
     const char gbcartridge_command[] = "gbcartridge -i\n";
-    uart_tx((uint8_t*)gbcartridge_command, strlen(gbcartridge_command));
+    uart_tx(((GBCartridge*)instance->app)->uart, (uint8_t*)gbcartridge_command, strlen(gbcartridge_command));
 }
 
 GBCartridgeScene1* gb_cartridge_scene_1_alloc() {

+ 3 - 10
views/gb_cartridge_scene_2.c

@@ -276,7 +276,7 @@ bool gb_cartridge_scene_2_input(InputEvent* event, void* context) {
                            FSAM_WRITE,
                            FSOM_CREATE_ALWAYS)) {
                         const char gbcartridge_command[] = "gbcartridge -d -o\n";
-                        uart_tx((uint8_t*)gbcartridge_command, strlen(gbcartridge_command));
+                        uart_tx(app->uart, (uint8_t*)gbcartridge_command, strlen(gbcartridge_command));
                     } else {
                         dialog_message_show_storage_error(app->dialogs, "Cannot open dump file");
                     }
@@ -295,10 +295,6 @@ bool gb_cartridge_scene_2_input(InputEvent* event, void* context) {
 void gb_cartridge_scene_2_exit(void* context) {
     furi_assert(context);
     GBCartridge* app = context;
-    // furi_hal_power_enable_otg();
-    // Automatically stop the scan when exiting view
-    // uart_tx((uint8_t*)("stopscan\n"), strlen("stopscan\n"));
-    // furi_delay_ms(50);
     gb_cartridge_stop_all_sound(app);
 }
 
@@ -327,11 +323,8 @@ void gb_cartridge_scene_2_enter(void* context) {
                 model->cart_dump_rom_extension);
             model->cart_dump_rom_filename_sequential = filename;
             // Register callbacks to receive data
-            uart_set_handle_rx_data_cb(
-                app->uart,
-                gameboy_rom_backup_handle_rx_data_cb); // setup callback for general log rx thread
-            uart_set_handle_rx_data_cb(
-                app->lp_uart, dump_handle_rx_data_cb); // setup callback for general log rx thread
+            uart_set_handle_rx_data_cb( app->uart, gameboy_rom_backup_handle_rx_data_cb); // setup callback for general log rx thread
+            uart_set_handle_rx_data_cb( app->lp_uart, dump_handle_rx_data_cb); // setup callback for general log rx thread
             app->is_writing_rom = true;
         },
         false);

+ 3 - 11
views/gb_cartridge_scene_3.c

@@ -280,7 +280,7 @@ bool gb_cartridge_scene_3_input(InputEvent* event, void* context) {
                            FSAM_WRITE,
                            FSOM_CREATE_ALWAYS)) {
                         const char gbcartridge_command[] = "gbcartridge -d -a\n";
-                        uart_tx((uint8_t*)gbcartridge_command, strlen(gbcartridge_command));
+                        uart_tx(app->uart, (uint8_t*)gbcartridge_command, strlen(gbcartridge_command));
                     } else {
                         dialog_message_show_storage_error(app->dialogs, "Cannot open dump file");
                     }
@@ -298,10 +298,6 @@ bool gb_cartridge_scene_3_input(InputEvent* event, void* context) {
 void gb_cartridge_scene_3_exit(void* context) {
     furi_assert(context);
     GBCartridge* app = context;
-    // Automatically stop the scan when exiting view
-    // uart_tx((uint8_t*)("stopscan\n"), strlen("stopscan\n"));
-    // furi_delay_ms(50);
-
     gb_cartridge_stop_all_sound(app);
 }
 
@@ -328,12 +324,8 @@ void gb_cartridge_scene_3_enter(void* context) {
             model->cart_dump_ram_filename_sequential = filename;
             app->is_writing_ram = true;
             // Register callbacks to receive data
-            uart_set_handle_rx_data_cb(
-                app->uart,
-                gameboy_ram_backup_handle_rx_data_cb); // setup callback for general log rx thread
-            uart_set_handle_rx_data_cb(
-                app->lp_uart,
-                dump_ram_handle_rx_data_cb); // setup callback for general log rx thread
+            uart_set_handle_rx_data_cb( app->uart, gameboy_ram_backup_handle_rx_data_cb); // setup callback for general log rx thread
+            uart_set_handle_rx_data_cb( app->lp_uart, dump_ram_handle_rx_data_cb); // setup callback for general log rx thread
         },
         false);
 }

+ 3 - 4
views/gb_cartridge_scene_4.c

@@ -190,7 +190,6 @@ bool gb_cartridge_scene_4_input(InputEvent* event, void* context) {
                     GBCartridge* app = (GBCartridge*)instance->context;
                     // Unregister rx callback
                     uart_set_handle_rx_data_cb(app->uart, NULL);
-                    // uart_set_handle_rx_data_cb(app->lp_uart, NULL);
                     instance->callback(GBCartridgeCustomEventScene4Back, instance->context);
                 },
                 true);
@@ -214,16 +213,16 @@ bool gb_cartridge_scene_4_input(InputEvent* event, void* context) {
 
                     // if(select_rom_file(app, file_stream)) {
                     //     const char gbcartridge_start_command[] = "gbcartridge -w -o -s\n";
-                    //     uart_tx((uint8_t*)gbcartridge_start_command, strlen(gbcartridge_start_command));
+                    //     uart_tx(app->uart, (uint8_t*)gbcartridge_start_command, strlen(gbcartridge_start_command));
                     //     furi_delay_ms(500);
 
                     //     while (file_stream_read(file_stream, buffer, sizeof(buffer), &bytesRead) && bytesRead > 0) {
                     //         // Send 64 bytes at a time
-                    //         lp_uart_tx((uint8_t*)buffer, bytesRead);
+                    //         uart_tx(app->lp_uart, (uint8_t*)buffer, bytesRead);
                     //     }
 
                     //     const char gbcartridge_end_command[] = "gbcartridge -w -o -e\n";
-                    //     uart_tx((uint8_t*)gbcartridge_end_command, strlen(gbcartridge_end_command));
+                    //     uart_tx(app->uart, (uint8_t*)gbcartridge_end_command, strlen(gbcartridge_end_command));
 
                     //     file_stream_close(file_stream);
                     // }

+ 3 - 6
views/gb_cartridge_scene_5.c

@@ -1,9 +1,6 @@
 #include "../gb_cartridge_app.h"
 #include <furi.h>
 #include <furi_hal.h>
-#include <furi_hal_uart.h>
-#include <stm32wbxx_ll_lpuart.h>
-#include <stm32wbxx_ll_usart.h>
 #include <input/input.h>
 #include <gui/elements.h>
 #include <dolphin/dolphin.h>
@@ -104,7 +101,7 @@ static int32_t cartridge_writting_worker_thread(void* thread_context) {
         char gbcartridge_start_command[80]; // A reasonably sized buffer.
         snprintf(gbcartridge_start_command, sizeof(gbcartridge_start_command), "gbcartridge -w -a %d\n", fileSize);
    
-        uart_tx((uint8_t *)gbcartridge_start_command, strlen(gbcartridge_start_command));
+        uart_tx(app->uart, (uint8_t *)gbcartridge_start_command, strlen(gbcartridge_start_command));
         
         furi_delay_ms(500); // wait
         uint8_t* the_savefile = NULL;
@@ -129,8 +126,8 @@ static int32_t cartridge_writting_worker_thread(void* thread_context) {
             buf_ptr += now_read;
         }
         savefile_size = read;
-        uart_tx((uint8_t*)the_savefile, savefile_size);
-        uart_tx((uint8_t*)("\n"), 1);
+        uart_tx(app->uart, (uint8_t*)the_savefile, savefile_size);
+        uart_tx(app->uart, (uint8_t*)("\n"), 1);
         with_view_model(
             app->gb_cartridge_scene_5->view,
             GameBoyCartridgeRAMWriteModel * model,