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

Direct sampling: different improvements.

antirez 3 лет назад
Родитель
Сommit
05899c2613
1 измененных файлов с 42 добавлено и 10 удалено
  1. 42 10
      view_direct_sampling.c

+ 42 - 10
view_direct_sampling.c

@@ -5,6 +5,12 @@
 
 
 #include <cc1101.h>
 #include <cc1101.h>
 
 
+#define CAPTURED_BITMAP_SIZE 128*64/8
+typedef struct {
+    uint8_t *captured; // Bitmap with the last captured screen.
+    uint32_t usec_per_pixel; // Number of useconds a pixel should represent
+} DirectSamplingViewPrivData;
+
 /* Read directly from the G0 CC1101 pin, and draw a black or white
 /* Read directly from the G0 CC1101 pin, and draw a black or white
  * dot depending on the level. */
  * dot depending on the level. */
 void render_view_direct_sampling(Canvas *const canvas, ProtoViewApp *app) {
 void render_view_direct_sampling(Canvas *const canvas, ProtoViewApp *app) {
@@ -20,13 +26,29 @@ void render_view_direct_sampling(Canvas *const canvas, ProtoViewApp *app) {
         return;
         return;
     }
     }
 
 
+    /* Allocate the bitmap only the first time. */
+    DirectSamplingViewPrivData *privdata = app->view_privdata;
+    if (privdata->captured == NULL)
+        privdata->captured = malloc(CAPTURED_BITMAP_SIZE);
+
+    /* Read from data from GPIO */
+    for (int j = 0; j < CAPTURED_BITMAP_SIZE*8; j++) {
+        uint32_t start_time = DWT->CYCCNT;
+        bool level = furi_hal_gpio_read(&gpio_cc1101_g0);
+        bitmap_set(privdata->captured,CAPTURED_BITMAP_SIZE,j,level);
+        uint32_t period =
+            furi_hal_cortex_instructions_per_microsecond() *
+            privdata->usec_per_pixel;
+        while(DWT->CYCCNT - start_time < period);
+    }
+
+    /* Draw on screen. */
+    int idx = 0;
     for (int y = 0; y < 64; y++) {
     for (int y = 0; y < 64; y++) {
         for (int x = 0; x < 128; x++) {
         for (int x = 0; x < 128; x++) {
-            bool level = furi_hal_gpio_read(&gpio_cc1101_g0);
+            bool level = bitmap_get(privdata->captured,
+                CAPTURED_BITMAP_SIZE,idx++);
             if (level) canvas_draw_dot(canvas,x,y);
             if (level) canvas_draw_dot(canvas,x,y);
-            /* Busy loop: this is a terrible approach as it blocks
-             * everything else, but for now it's the best we can do
-             * to obtain direct data with some spacing. */
             uint32_t x = 250; while(x--);
             uint32_t x = 250; while(x--);
         }
         }
     }
     }
@@ -45,17 +67,22 @@ void process_input_direct_sampling(ProtoViewApp *app, InputEvent input) {
 /* Enter view. Stop the subghz thread to prevent access as we read
 /* Enter view. Stop the subghz thread to prevent access as we read
  * the CC1101 data directly. */
  * the CC1101 data directly. */
 void view_enter_direct_sampling(ProtoViewApp *app) {
 void view_enter_direct_sampling(ProtoViewApp *app) {
+    /* Set view defaults. */
+    DirectSamplingViewPrivData *privdata = app->view_privdata;
+    privdata->usec_per_pixel = 30;
+
     if (app->txrx->txrx_state == TxRxStateRx &&
     if (app->txrx->txrx_state == TxRxStateRx &&
         !app->txrx->debug_timer_sampling)
         !app->txrx->debug_timer_sampling)
     {
     {
         furi_hal_subghz_stop_async_rx();
         furi_hal_subghz_stop_async_rx();
 
 
-        // To read data asynchronously directly from the view, we need
-        // to put the CC1101 back into reception mode (the previous call
-        // to stop the async RX will put it into idle) and configure the
-        // G0 pin for reading.
+        /* To read data asynchronously directly from the view, we need
+         * to put the CC1101 back into reception mode (the previous call
+         * to stop the async RX will put it into idle) and configure the
+         * G0 pin for reading. */
         furi_hal_subghz_rx();
         furi_hal_subghz_rx();
-        furi_hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow);
+        furi_hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo,
+                           GpioSpeedLow);
     } else {
     } else {
         raw_sampling_worker_stop(app);
         raw_sampling_worker_stop(app);
     }
     }
@@ -63,6 +90,12 @@ void view_enter_direct_sampling(ProtoViewApp *app) {
 
 
 /* Exit view. Restore the subghz thread. */
 /* Exit view. Restore the subghz thread. */
 void view_exit_direct_sampling(ProtoViewApp *app) {
 void view_exit_direct_sampling(ProtoViewApp *app) {
+    DirectSamplingViewPrivData *privdata = app->view_privdata;
+    free(privdata->captured);
+    privdata->captured = NULL;
+    app->direct_sampling_enabled = false;
+
+    /* Restart normal data feeding. */
     if (app->txrx->txrx_state == TxRxStateRx &&
     if (app->txrx->txrx_state == TxRxStateRx &&
         !app->txrx->debug_timer_sampling)
         !app->txrx->debug_timer_sampling)
     {
     {
@@ -70,5 +103,4 @@ void view_exit_direct_sampling(ProtoViewApp *app) {
     } else {
     } else {
         raw_sampling_worker_start(app);
         raw_sampling_worker_start(app);
     }
     }
-    app->direct_sampling_enabled = false;
 }
 }