Przeglądaj źródła

WIP: write RAM (test serial)

Esteban Fuentealba 2 lat temu
rodzic
commit
1ce1287908
4 zmienionych plików z 290 dodań i 103 usunięć
  1. 5 0
      gb_cartridge_app.c
  2. 10 1
      gb_cartridge_app.h
  3. 7 3
      uart.c
  4. 268 99
      views/gb_cartridge_scene_5.c

+ 5 - 0
gb_cartridge_app.c

@@ -57,6 +57,11 @@ GBCartridge* gb_cartridge_app_app_alloc() {
     app->uart = usart_init(app);
     app->lp_uart = lp_uart_init(app);
     
+    FURI_LOG_I(TAG, "Hola1!");
+    FURI_LOG_D(TAG, "Hola2!");
+    FURI_LOG_E(TAG, "Hola3!");
+    FURI_LOG_W(TAG, "Hola4!");
+    
     view_dispatcher_add_view(app->view_dispatcher, GBCartridgeViewIdMenu, variable_item_list_get_view(app->submenu));
     app->gb_cartridge_startscreen = gb_cartridge_startscreen_alloc();
     view_dispatcher_add_view(app->view_dispatcher, GBCartridgeViewIdStartscreen, gb_cartridge_startscreen_get_view(app->gb_cartridge_startscreen));

+ 10 - 1
gb_cartridge_app.h

@@ -41,7 +41,16 @@
 #define UI_PROGRESS_COLS 8
 #define UI_PROGRESS_ROWS 4
 
-#define BUFFER_SIZE 64
+#define BUFFER_SIZE 128
+
+#ifndef MAX
+#define MAX(a, b) ((a) > (b)) ? (a) : (b)
+#endif
+
+#ifndef MIN
+#define MIN(a, b) ((a) < (b)) ? (a) : (b)
+#endif
+
 
 typedef struct {
     Gui* gui;

+ 7 - 3
uart.c

@@ -32,7 +32,7 @@ void uart_on_irq_cb(UartIrqEvent ev, uint8_t data, void* context) {
     Uart* uart = (Uart*)context;
 
     if(ev == UartIrqEventRXNE) {
-        furi_stream_buffer_send(uart->rx_stream, &data,  sizeof(data), 0);
+        furi_stream_buffer_send(uart->rx_stream, &data,  1, 0);
         furi_thread_flags_set(furi_thread_get_id(uart->rx_thread), WorkerEvtRxDone);
     }
 }
@@ -103,11 +103,15 @@ static int32_t uart_worker(void* context) {
                 do {
                     uint8_t data[64];
                     length = furi_stream_buffer_receive(uart->rx_stream, data, 64, 0);
-                    // FURI_LOG_I("UART", "[in]: %s", (char*)data);
+                    
                     if(length > 0) {
+                        
                         for(size_t i = 0; i < length; 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);
             } else if(uart->channel == LP_UART_CH) {
@@ -145,7 +149,7 @@ Uart*
     furi_thread_set_callback(uart->rx_thread, uart_worker);
     furi_thread_start(uart->rx_thread);
     if(channel == FuriHalUartIdUSART1) {
-        furi_hal_console_disable();
+        // furi_hal_console_disable();
     } else if(channel == FuriHalUartIdLPUART1) {
         furi_hal_uart_init(channel, BAUDRATE);
     }

+ 268 - 99
views/gb_cartridge_scene_5.c

@@ -2,7 +2,7 @@
 #include <furi.h>
 #include <furi_hal.h>
 #include <furi_hal_uart.h>
-// #include <stm32wbxx_ll_lpuart.h>
+#include <stm32wbxx_ll_lpuart.h>
 #include <stm32wbxx_ll_usart.h>
 #include <input/input.h>
 #include <gui/elements.h>
@@ -16,7 +16,7 @@
 #include "../helpers/sequential_file.h"
 #include <stdio.h>  // Para sprintf
 #include <string.h> // Para strlen
-
+// #include <stm32wbxx_ll_uart.h>
 
 // static bool waiting_acknowledgement = true;
 struct GBCartridgeScene5
@@ -40,11 +40,16 @@ typedef struct
     char *cart_dump_ram_filename_sequential;
     bool rx_active;
 
-    bool ack;
+    bool waiting_ack;
 
 
     char* event_title;
 
+    uint32_t offset;
+    uint32_t value;
+
+    File* selectedfile;
+
 } GameBoyCartridgeRAMWriteModel;
 /*
 void gameboy_log_handle_rx_data_cb(uint8_t* buf, size_t len, void* context) {
@@ -101,25 +106,45 @@ static bool select_ram_file(GBCartridge *app, File *file)
     furi_string_free(file_path);
     return result;
 }
-
-// static void wait_for_ack (void* context) {
-//     GBCartridge* instance = context;
-//     bool waiting_acknowledgement = true;
-//     while(waiting_acknowledgement) {
-//         with_view_model(
-//                 instance->gb_cartridge_scene_5->view,
-//                 GameBoyCartridgeRAMWriteModel * model,
-//                 {
-//                     waiting_acknowledgement = model->ack;
-//                     if(model->ack) {
-//                         model->ack = false;
-//                     }
-//                 },
-//                 true);
-//         furi_delay_ms(2);
+/*
+static void wait_for_ack (void* context) {
+    GBCartridge* instance = context;
+    bool waiting_acknowledgement = true;
+    while(waiting_acknowledgement) {
+        with_view_model(
+                instance->gb_cartridge_scene_5->view,
+                GameBoyCartridgeRAMWriteModel * model,
+                {
+                    waiting_acknowledgement = model->waiting_ack;
+                },
+                true);
+        furi_delay_ms(10);
+    }
+    // if(!waiting_acknowledgement) {
+    //     with_view_model(
+    //             instance->gb_cartridge_scene_5->view,
+    //             GameBoyCartridgeRAMWriteModel * model,
+    //             {
+    //                 model->waiting_ack = true;
+    //             },
+    //             true);
+    // }
+}
+*/
+// static bool to_hex(char* dest, size_t dest_len, const uint8_t* values, size_t val_len) {
+//     if(dest_len < (val_len*2+1)) /* check that dest is large enough */
+//         return false;
+//     *dest = '\0'; /* in case val_len==0 */
+//     while(val_len--) {
+//         /* sprintf directly to where dest points */
+//         sprintf(dest, "%02X", *values);
+//         dest += 2;
+//         ++values;
 //     }
+//     return true;
 // }
 
+
 static int32_t cartridge_writting_worker_thread(void* thread_context) {
     GBCartridge* app = thread_context;
     UNUSED(app);
@@ -160,25 +185,22 @@ static int32_t cartridge_writting_worker_thread(void* thread_context) {
 
     if (select_ram_file(app, file))
     {
-
-        uint64_t fileSize = storage_file_size(file);
-
-
-        uint8_t buffer[BUFFER_SIZE];
-        
-        char gbcartridge_start_command[80]; // A reasonably sized buffer.
-        snprintf(gbcartridge_start_command, sizeof(gbcartridge_start_command), "gbcartridge -w -a %lld\n", fileSize);
-        // snprintf(gbcartridge_start_command, sizeof(gbcartridge_start_command), "gbcartridge -t %d\n", 128);
-   
-        uart_tx((uint8_t *)gbcartridge_start_command, strlen(gbcartridge_start_command));
-        furi_delay_ms(500);
-    
+        uint16_t fileSize = storage_file_size(file);
         
-        with_view_model(
+        /*
+        uint8_t buffer[BUFFER_SIZE];
+        */
+
+       with_view_model(
             app->gb_cartridge_scene_5->view,
             GameBoyCartridgeRAMWriteModel * model,
             {
                 model->total_ram = fileSize;
+                model->selectedfile = file;
+                model->waiting_ack = true;
+
+                
+                // 
 
                 // char title[42];
                 // snprintf(title, sizeof(title), "%lld", fileSize);
@@ -186,32 +208,132 @@ static int32_t cartridge_writting_worker_thread(void* thread_context) {
                 // model->event_title = (char*)malloc(strlen(title) + 1);
                 
                 // strcpy(model->event_title, title);
+
+
+                //  dev
+                // model->offset = 64;
+                // uint8_t buffer[64];
+                // if(storage_file_seek(file, 64, true)) {
+                //     size_t to_read = MIN((size_t)fileSize, sizeof(buffer));
+                //     uint16_t bytes_read = storage_file_read(file, buffer, to_read);
+                //     if (bytes_read > 0) {
+                //         cJSON *monitor = cJSON_CreateObject();
+                //         cJSON *name = cJSON_CreateString("Awesome 4K");
+                //         cJSON *resolutions = cJSON_CreateArray();
+
+                //         for (size_t i = 0; i < bytes_read; i++) {
+                //             cJSON_AddItemToArray(resolutions, cJSON_CreateNumber((int)buffer[i]));
+                //         }
+                //         cJSON_AddItemToObject(monitor, "resolutions", resolutions);
+
+                //         cJSON_AddItemToObject(monitor, "name", name);
+                //         char *string = cJSON_PrintUnformatted(monitor);
+
+                //         FURI_LOG_I(TAG, string);
+                        
+                //     }
+                // }
             },
             true);
+
+
+        char gbcartridge_start_command[80]; // A reasonably sized buffer.
+        snprintf(gbcartridge_start_command, sizeof(gbcartridge_start_command), "gbcartridge -w -a %d %d\n", fileSize, BUFFER_SIZE);
+        // snprintf(gbcartridge_start_command, sizeof(gbcartridge_start_command), "gbcartridge -t %d\n", 128);
+   
+        uart_tx((uint8_t *)gbcartridge_start_command, strlen(gbcartridge_start_command));
+        // furi_delay_ms(100);
+
+            // furi_delay_ms(500);
+
+        FURI_LOG_I(TAG, "Start send file..." );
+        
+        uint8_t payload[BUFFER_SIZE];
+        int j = 0;
         
+        while(fileSize > 0) {
+            size_t to_read = MIN(fileSize, BUFFER_SIZE);
+            uint16_t num_bytes = storage_file_read(file, payload, to_read);
+            // FURI_LOG_I(TAG, "[%d] fileSize: %d , bytes_read: %d - to read: %d" , j, fileSize, num_bytes,  to_read);
+            if(num_bytes > 0) {
+                // payload[BUFFER_SIZE] = '\0';
+                // furi_hal_console_tx_with_new_line((uint8_t *)payload, num_bytes);
+                // uart_tx((uint8_t *)payload, num_bytes);
+                FURI_CRITICAL_ENTER();
+                // Transmit data
+                furi_hal_uart_tx(FuriHalUartIdUSART1, payload, num_bytes);
+                if(fileSize - num_bytes == 0) {
+                    furi_hal_uart_tx(FuriHalUartIdUSART1, (uint8_t*)("\r\n"),2);
+                }
+                
+                while(!LL_USART_IsActiveFlag_TC(USART1))
+                    ;
+                FURI_CRITICAL_EXIT();
+
+                
+                // Transmit new line symbols
+                // uart_tx((uint8_t*)("\n"), 1);
+                // Wait for TC flag to be raised for last char
+                
+                // wait_for_ack(app);
+                // with_view_model(
+                //             app->gb_cartridge_scene_5->view,
+                //             GameBoyCartridgeRAMWriteModel * model,
+                //             {
+                //                 model->transfered += num_bytes;
+                //                 model->waiting_ack = true;
+                //             },
+                //             true);
+                
+
+                 
+                // NVIC_DisableIRQ(USART1_IRQn);
+                // LL_USART_EnableIT_RXNE_RXFNE(USART1);
+                // while(true) {
+                //     uint8_t data = LL_USART_ReceiveData8(USART1);
+                //     if(data) {
+                //         FURI_LOG_I(TAG, "read: %d" , data);
+                //         break;
+                //     }
+                // }
+                // NVIC_EnableIRQ(USART1_IRQn);
+                fileSize -= num_bytes;
+                j++;
+            }
+        }
+        
+        FURI_LOG_I(TAG, "Read all file." );
+        /*
         // uint8_t data[1];
         int counter = 0;
         while (fileSize > 0) {
-            uint16_t bytes_read = storage_file_read(file, buffer, BUFFER_SIZE);
+            size_t to_read = MIN(fileSize, sizeof(buffer));
+            uint16_t bytes_read = storage_file_read(file, buffer, to_read);
             
             if (bytes_read > 0) {
-                // buffer[BUFFER_SIZE-1] = '\0';
-                // uart_tx((uint8_t *)buffer, bytes_read+1);
-
-                // uint8_t string_buffer[BUFFER_SIZE + 1]; // +1 para el carácter nulo
-                // memcpy(string_buffer, buffer, bytes_read); // Copia los datos del búfer al búfer de cadena
-                // string_buffer[bytes_read] = '\0'; // Agrega el carácter nulo al final
-
-
 
                 uart_tx((uint8_t *)buffer, bytes_read);
+                
+                
                 // furi_delay_ms(500);
                 // while(!LL_USART_IsActiveFlag_TC(USART1));
                 
                 // if(counter == 1) {
                 //     break;
                 // }
+                // while(true) {
+                //     // while(LL_USART_IsActiveFlag_TXE(USART1))
+                //     // ;
+                //     uint8_t data = LL_USART_ReceiveData8(USART1);
+                //     if(data) {
+                //         break;
+                //     }
+                // }
+                // furi_delay_ms(1);
                 fileSize -= bytes_read;
+
+                // furi_delay_ms(2);
+                
                     with_view_model(
                         app->gb_cartridge_scene_5->view,
                         GameBoyCartridgeRAMWriteModel * model,
@@ -219,32 +341,17 @@ static int32_t cartridge_writting_worker_thread(void* thread_context) {
                             model->transfered += bytes_read;
                         },
                         true);
-                // bool waiting_acknowledgement = true;
-                // while(waiting_acknowledgement){
-                //             with_view_model(
-                //                     app->gb_cartridge_scene_5->view,
-                //                     GameBoyCartridgeRAMWriteModel * model,
-                //                     {
-                //                         waiting_acknowledgement = model->ack;
-                //                         if(model->ack) {
-                //                             model->ack = false;
-                //                         }
-                //                     },
-                //                     false);
-                //     furi_delay_ms(50);
-                // }
-
                 counter++;
             } else {
                 break;
             }
         }
-
         storage_file_close(file);
 
         // const char gbcartridge_end_command[] = "gbcartridge -w -a\n";
         // uart_tx((uint8_t *)gbcartridge_end_command, strlen(gbcartridge_end_command));
         storage_file_free(file);
+        */
     }
     
     return 0;
@@ -354,7 +461,7 @@ static void gb_cartridge_scene_5_model_init(GameBoyCartridgeRAMWriteModel *const
     model->elapsed_time = 0;
     model->start_time = 0;
     model->event_title = "...";
-    model->ack = false;
+    model->waiting_ack = true;
 }
 void gameboy_handle_rx_data_cb(uint8_t* buf, size_t len, void* context) {
     furi_assert(context);
@@ -381,16 +488,72 @@ void gameboy_handle_rx_data_cb(uint8_t* buf, size_t len, void* context) {
                 } else {
                     model->event_title = "None";
                 }
-                
+
+                cJSON* x1 = cJSON_GetObjectItemCaseSensitive(json, "x1");
+                if(cJSON_IsString(x1) && (x1->valuestring != NULL)) {
+                    FURI_LOG_I(TAG, "X1: %s", strdup(x1->valuestring));
+                } 
+                cJSON* x2 = cJSON_GetObjectItemCaseSensitive(json, "x2");
+                if(cJSON_IsString(x2) && (x2->valuestring != NULL)) {
+                    FURI_LOG_I(TAG, "X2: %s", strdup(x2->valuestring));
+                } 
+                cJSON* x3 = cJSON_GetObjectItemCaseSensitive(json, "x3");
+                if(cJSON_IsString(x3) && (x3->valuestring != NULL)) {
+                    FURI_LOG_I(TAG, "X3: %s", strdup(x3->valuestring));
+                } 
+
+                //  offset
+                cJSON* offset = cJSON_GetObjectItemCaseSensitive(json, "offset");
+                if(cJSON_IsNumber(offset)) {
+                    model->offset = offset->valueint;
+                } else {
+                    model->offset = 0;
+                }
+
+                //  value
+                cJSON* value = cJSON_GetObjectItemCaseSensitive(json, "value");
+                if(cJSON_IsNumber(value)) {
+                    model->value = value->valueint;
+                } else {
+                    model->value = 0;
+                }
             }
             if (strcmp(model->event_type, "ack") == 0) {
-                model->ack = true;
+                FURI_LOG_I(TAG, "ACK: %ld (%d)", model->value, model->total_ram);
                 // model->transfered += 1;
                 // waiting_acknowledgement = false;
+                model->waiting_ack = false;
             }
             if (strcmp(model->event_type, "success") == 0) {
                 notification_success(instance->notification);
             }
+            else if (strcmp(model->event_type, "read") == 0) {
+                // furi_delay_ms(20);
+                FURI_LOG_I(TAG, "Read: %ld - %ld (%d)" , model->offset, model->value, model->total_ram);
+                // model->value
+                // 
+                furi_check(storage_file_is_open(model->selectedfile));
+                if(storage_file_seek(model->selectedfile, model->offset, true)) {
+
+                    uint8_t buffer[BUFFER_SIZE];
+                    size_t remaining = model->total_ram - model->offset;
+                    size_t to_read;
+
+                    if (remaining > 0) {
+
+                        to_read = MIN(remaining, (size_t)BUFFER_SIZE);   
+                        uint16_t bytes_read = storage_file_read(model->selectedfile, buffer, to_read);
+                        if (bytes_read > 0) {
+                            // furi_delay_ms(200);
+                            furi_hal_console_tx_with_new_line((uint8_t *)buffer, bytes_read);
+                            // uart_tx((uint8_t*)"\n", 1);
+                            FURI_LOG_I(TAG, "offset: %ld , bytes_read: %d - to read: %d" , model->offset, bytes_read,  to_read);
+                            model->transfered += bytes_read;
+                        }
+                        
+                    }
+                }
+            }
         },
         true);
 }
@@ -428,49 +591,54 @@ bool gb_cartridge_scene_5_input(InputEvent *event, void *context)
         case InputKeyRight:
             break;
         case InputKeyOk:
-            with_view_model(
-                instance->view,
-                GameBoyCartridgeRAMWriteModel * model,
-                {
-                    GBCartridge *app = ((GBCartridge *)instance->context);
-                    // app->cart_log = storage_file_alloc(app->storage);
-                    // char *filename = sequential_file_resolve_path(app->storage, MALVEKE_APP_FOLDER, "logs", "txt");
-                    // if(storage_file_open(app->cart_log, filename, FSAM_WRITE, FSOM_CREATE_ALWAYS)) {
-                        uart_set_handle_rx_data_cb(app->uart, gameboy_handle_rx_data_cb);
-                        // uart_set_handle_rx_data_cb(app->lp_uart, gameboy_log_handle_rx_data_cb);
+        {
+            GBCartridge *app = ((GBCartridge *)instance->context);
+            uart_set_handle_rx_data_cb(app->uart, gameboy_handle_rx_data_cb);
+            cartridge_writting_worker_thread(app);
+        }
+            // with_view_model(
+            //     instance->view,
+            //     GameBoyCartridgeRAMWriteModel * model,
+            //     {
+            //         GBCartridge *app = ((GBCartridge *)instance->context);
+            //         // app->cart_log = storage_file_alloc(app->storage);
+            //         // char *filename = sequential_file_resolve_path(app->storage, MALVEKE_APP_FOLDER, "logs", "txt");
+            //         // if(storage_file_open(app->cart_log, filename, FSAM_WRITE, FSOM_CREATE_ALWAYS)) {
+            //             uart_set_handle_rx_data_cb(app->uart, gameboy_handle_rx_data_cb);
+            //             // uart_set_handle_rx_data_cb(app->lp_uart, gameboy_log_handle_rx_data_cb);
                         
-                        app->thread = furi_thread_alloc_ex("CartridgeWriterWorker", 2048, cartridge_writting_worker_thread, app);
-                        furi_thread_start(app->thread);
-                       
-
-                    // }
+            //             app->thread = furi_thread_alloc_ex("CartridgeWriterWorker", 2048, cartridge_writting_worker_thread, app);
+            //             furi_thread_start(app->thread);
+            //         //    furi_delay_ms(10);
+            //         //     cartridge_writting_worker_thread(app);
+            //         // }
                     
 
-                    UNUSED(model);
+            //         UNUSED(model);
                     
-                    // UNUSED(app);
-                    // uint8_t buffer[BUFFER_SIZE];
-                    // File* file = storage_file_alloc(app->storage);
-
-                    // if (select_ram_file(app, file))
-                    // {
-                    //     model->total_ram = storage_file_size(file);
-                    //     const char gbcartridge_start_command[] = "gbcartridge -w -o -s\n";
-                    //     uart_tx((uint8_t *)gbcartridge_start_command, strlen(gbcartridge_start_command));
-                    //     furi_delay_ms(500);
+            //         // UNUSED(app);
+            //         // uint8_t buffer[BUFFER_SIZE];
+            //         // File* file = storage_file_alloc(app->storage);
+
+            //         // if (select_ram_file(app, file))
+            //         // {
+            //         //     model->total_ram = storage_file_size(file);
+            //         //     const char gbcartridge_start_command[] = "gbcartridge -w -o -s\n";
+            //         //     uart_tx((uint8_t *)gbcartridge_start_command, strlen(gbcartridge_start_command));
+            //         //     furi_delay_ms(500);
                         
-                    //     uint16_t ret = 0;
-                    //     do {
-                    //         ret = storage_file_read(file, buffer, sizeof(buffer) - 1);
-                    //         lp_uart_tx((uint8_t *)buffer, sizeof(buffer));
-                    //         model->transfered += ret;
-                    //     } while(ret > 0);
-                    //     const char gbcartridge_end_command[] = "gbcartridge -w -o -e\n";
-                    //     uart_tx((uint8_t *)gbcartridge_end_command, strlen(gbcartridge_end_command));
-                    //     storage_file_free(file);
-                    // }
-                },
-                true);
+            //         //     uint16_t ret = 0;
+            //         //     do {
+            //         //         ret = storage_file_read(file, buffer, sizeof(buffer) - 1);
+            //         //         lp_uart_tx((uint8_t *)buffer, sizeof(buffer));
+            //         //         model->transfered += ret;
+            //         //     } while(ret > 0);
+            //         //     const char gbcartridge_end_command[] = "gbcartridge -w -o -e\n";
+            //         //     uart_tx((uint8_t *)gbcartridge_end_command, strlen(gbcartridge_end_command));
+            //         //     storage_file_free(file);
+            //         // }
+            //     },
+            //     true);
             break;
         case InputKeyMAX:
             break;
@@ -489,6 +657,7 @@ void gb_cartridge_scene_5_exit(void *context)
 
 void gb_cartridge_scene_5_enter(void *context)
 {
+    
     furi_assert(context);
     GBCartridgeScene5 *instance = context;
     GBCartridge *app = (GBCartridge *)instance->context;