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

Update the new firmware update, add camera model. Stabilize Flipper Zero software.

Cody Tolene 2 лет назад
Родитель
Сommit
6bf551234c
1 измененных файлов с 54 добавлено и 58 удалено
  1. 54 58
      views/camera_suite_view_camera.c

+ 54 - 58
views/camera_suite_view_camera.c

@@ -20,6 +20,11 @@ void camera_suite_view_camera_set_callback(
 
 // Function to draw pixels on the canvas based on camera orientation
 static void draw_pixel_by_orientation(Canvas* canvas, uint8_t x, uint8_t y, uint8_t orientation) {
+    furi_assert(canvas);
+    furi_assert(x);
+    furi_assert(y);
+    furi_assert(orientation);
+
     switch(orientation) {
     default:
     case 0: { // Camera rotated 0 degrees (right side up, default)
@@ -42,8 +47,11 @@ static void draw_pixel_by_orientation(Canvas* canvas, uint8_t x, uint8_t y, uint
     }
 }
 
-static void camera_suite_view_camera_draw(Canvas* canvas, void* _model) {
-    UartDumpModel* model = _model;
+static void camera_suite_view_camera_draw(Canvas* canvas, void* model) {
+    furi_assert(canvas);
+    furi_assert(model);
+
+    UartDumpModel* uartDumpModel = model;
 
     // Clear the screen.
     canvas_set_color(canvas, ColorBlack);
@@ -56,14 +64,14 @@ static void camera_suite_view_camera_draw(Canvas* canvas, void* _model) {
         uint8_t y = p / ROW_BUFFER_LENGTH; // 0 .. 63
 
         for(uint8_t i = 0; i < 8; ++i) {
-            if((model->pixels[p] & (1 << (7 - i))) != 0) {
-                draw_pixel_by_orientation(canvas, (x * 8) + i, y, model->orientation);
+            if((uartDumpModel->pixels[p] & (1 << (7 - i))) != 0) {
+                draw_pixel_by_orientation(canvas, (x * 8) + i, y, uartDumpModel->orientation);
             }
         }
     }
 
     // Draw the guide if the camera is not initialized.
-    if(!model->initialized) {
+    if(!uartDumpModel->initialized) {
         canvas_draw_icon(canvas, 74, 16, &I_DolphinCommon_56x48);
         canvas_set_font(canvas, FontSecondary);
         canvas_draw_str(canvas, 8, 12, "Connect the ESP32-CAM");
@@ -74,8 +82,10 @@ static void camera_suite_view_camera_draw(Canvas* canvas, void* _model) {
     }
 }
 
-static void save_image(void* _model) {
-    UartDumpModel* model = _model;
+static void save_image(void* model) {
+    furi_assert(model);
+
+    UartDumpModel* uartDumpModel = model;
 
     // This pointer is used to access the storage.
     Storage* storage = furi_record_open(RECORD_STORAGE);
@@ -122,7 +132,7 @@ static void save_image(void* _model) {
     // if(!model->inverted) { }
 
     for(size_t i = 0; i < FRAME_BUFFER_LENGTH; ++i) {
-        model->pixels[i] = ~model->pixels[i];
+        uartDumpModel->pixels[i] = ~uartDumpModel->pixels[i];
     }
 
     // If the file was opened successfully, write the bitmap header and the
@@ -140,7 +150,7 @@ static void save_image(void* _model) {
         // @todo - Save image based on orientation.
         for(size_t i = 64; i > 0; --i) {
             for(size_t j = 0; j < ROW_BUFFER_LENGTH; ++j) {
-                row_buffer[j] = model->pixels[((i - 1) * ROW_BUFFER_LENGTH) + j];
+                row_buffer[j] = uartDumpModel->pixels[((i - 1) * ROW_BUFFER_LENGTH) + j];
             }
             storage_file_write(file, row_buffer, ROW_BUFFER_LENGTH);
         }
@@ -154,6 +164,8 @@ static void save_image(void* _model) {
 }
 
 static void camera_suite_view_camera_model_init(UartDumpModel* const model) {
+    furi_assert(model);
+
     for(size_t i = 0; i < FRAME_BUFFER_LENGTH; i++) {
         model->pixels[i] = 0;
     }
@@ -161,6 +173,7 @@ static void camera_suite_view_camera_model_init(UartDumpModel* const model) {
 
 static bool camera_suite_view_camera_input(InputEvent* event, void* context) {
     furi_assert(context);
+    furi_assert(event);
 
     CameraSuiteViewCamera* instance = context;
 
@@ -184,7 +197,6 @@ static bool camera_suite_view_camera_input(InputEvent* event, void* context) {
         switch(event->key) {
         // Camera: Stop stream.
         case InputKeyBack: {
-            data[0] = 's';
             // Go back to the main menu.
             with_view_model(
                 instance->view,
@@ -262,10 +274,10 @@ static bool camera_suite_view_camera_input(InputEvent* event, void* context) {
         }
         // Camera: Take picture.
         case InputKeyOk: {
-            // Set up data to trigger picture sequence on the ESP32-CAM.
-            data[0] = 'P';
-            // Send `data` to the ESP32-CAM.
-            furi_hal_uart_tx(FuriHalUartIdUSART1, data, 1);
+            // Save picture directly to ESP32-CAM.
+            // @todo - Add this functionality.
+            // data[0] = 'P';
+            // furi_hal_uart_tx(FuriHalUartIdUSART1, data, 1);
             with_view_model(
                 instance->view,
                 UartDumpModel * model,
@@ -278,7 +290,6 @@ static bool camera_suite_view_camera_input(InputEvent* event, void* context) {
                     instance->callback(CameraSuiteCustomEventSceneCameraOk, instance->context);
                 },
                 true);
-            return true;
         }
         // Camera: Do nothing.
         case InputKeyMAX:
@@ -294,58 +305,34 @@ static bool camera_suite_view_camera_input(InputEvent* event, void* context) {
 }
 
 static void camera_suite_view_camera_exit(void* context) {
-    furi_assert(context);
+    UNUSED(context);
+
+    // Stop camera stream.
+    uint8_t stop_camera = 's';
+    furi_hal_uart_tx(FuriHalUartIdUSART1, &stop_camera, 1);
+    furi_delay_ms(50);
 }
 
 static void camera_suite_view_camera_enter(void* context) {
-    // Check `context` for null. If it is null, abort program, else continue.
     furi_assert(context);
 
-    // Cast `context` to `CameraSuiteViewCamera*` and store it in `instance`.
+    // Get the camera suite instance context.
     CameraSuiteViewCamera* instance = (CameraSuiteViewCamera*)context;
 
-    uint8_t data[1];
-    data[0] = 'S'; // Uppercase `S` to start the camera
-
-    // Send `data` to the ESP32-CAM
-    furi_hal_uart_tx(FuriHalUartIdUSART1, data, 1);
+    // Get the camera suite instance context.
+    CameraSuite* instance_context = instance->context;
 
-    // Delay for 50ms to make sure the camera is started before sending any other commands.
+    // Start camera stream.
+    uint8_t start_camera = 'S';
+    furi_hal_uart_tx(FuriHalUartIdUSART1, &start_camera, 1);
     furi_delay_ms(50);
 
-    // Initialize the camera with the selected dithering option from options.
-    CameraSuite* instanceContext = instance->context;
-    switch(instanceContext->dither) {
-    case 0: // Floyd Steinberg
-        data[0] = '0';
-        break;
-    case 1: // Stucki
-        data[0] = '1';
-        break;
-    case 2: // Jarvis Judice Ninke
-        data[0] = '2';
-        break;
-    }
-
-    // Send `data` as the dither type to the ESP32-CAM
-    furi_hal_uart_tx(FuriHalUartIdUSART1, data, 1);
-
-    // Wait for 50ms to make sure dither is set before sending any other commands.
+    // Get/set dither type.
+    uint8_t dither_type = instance_context->dither;
+    furi_hal_uart_tx(FuriHalUartIdUSART1, &dither_type, 1);
     furi_delay_ms(50);
 
-    // Initialize the camera with the selected flash option from options.
-    switch(instanceContext->flash) {
-    case 0: // Flash OFF
-        data[0] = 'f';
-        break;
-    case 1: // Flash ON
-        data[0] = 'F';
-        break;
-    }
-
-    // Send `data` as the flash bool to the ESP32-CAM
-    furi_hal_uart_tx(FuriHalUartIdUSART1, data, 1);
-    uint32_t orientation = instanceContext->orientation;
+    uint32_t orientation = instance_context->orientation;
     with_view_model(
         instance->view,
         UartDumpModel * model,
@@ -358,7 +345,8 @@ static void camera_suite_view_camera_enter(void* context) {
 }
 
 static void camera_on_irq_cb(UartIrqEvent uartIrqEvent, uint8_t data, void* context) {
-    // Check `context` for null. If it is null, abort program, else continue.
+    furi_assert(uartIrqEvent);
+    furi_assert(data);
     furi_assert(context);
 
     // Cast `context` to `CameraSuiteViewCamera*` and store it in `instance`.
@@ -372,7 +360,10 @@ static void camera_on_irq_cb(UartIrqEvent uartIrqEvent, uint8_t data, void* cont
     }
 }
 
-static void process_ringbuffer(UartDumpModel* model, uint8_t byte) {
+static void process_ringbuffer(UartDumpModel* model, uint8_t const byte) {
+    furi_assert(model);
+    furi_assert(byte);
+
     // The first HEADER_LENGTH bytes are reserved for header information.
     if(model->ringbuffer_index < HEADER_LENGTH) {
         // Validate the start of row characters 'Y' and ':'.
@@ -419,6 +410,7 @@ static void process_ringbuffer(UartDumpModel* model, uint8_t byte) {
 
 static int32_t camera_worker(void* context) {
     furi_assert(context);
+
     CameraSuiteViewCamera* instance = context;
 
     while(1) {
@@ -499,7 +491,11 @@ CameraSuiteViewCamera* camera_suite_view_camera_alloc() {
 
     // Enable uart listener
     furi_hal_console_disable();
+
+    // 115200 is the default baud rate for the ESP32-CAM.
     furi_hal_uart_set_br(FuriHalUartIdUSART1, 230400);
+
+    // Enable UART1 and set the IRQ callback.
     furi_hal_uart_set_irq_cb(FuriHalUartIdUSART1, camera_on_irq_cb, instance);
 
     return instance;
@@ -529,4 +525,4 @@ void camera_suite_view_camera_free(CameraSuiteViewCamera* instance) {
 View* camera_suite_view_camera_get_view(CameraSuiteViewCamera* instance) {
     furi_assert(instance);
     return instance->view;
-}
+}