Explorar el Código

Set freq and modulation + other improvements.

antirez hace 3 años
padre
commit
eea8b4ef4c
Se han modificado 4 ficheros con 93 adiciones y 21 borrados
  1. 87 15
      app.c
  2. 1 1
      app.h
  3. 1 1
      app_buffer.h
  4. 4 4
      app_subghz.c

+ 87 - 15
app.c

@@ -25,17 +25,29 @@ void render_signal(ProtoViewApp *app, Canvas *const canvas, RawSamplesBuffer *bu
     int rows = 8;
     uint32_t time_per_pixel = app->us_scale;
     bool level = 0;
-    uint32_t dur = 0;
+    uint32_t dur = 0, sample_num = 0;
     for (int row = 0; row < rows ; row++) {
         for (int x = 0; x < 128; x++) {
             int y = 3 + row*8;
             if (dur < time_per_pixel/2) {
                 /* Get more data. */
                 raw_samples_get(buf, idx++, &level, &dur);
+                sample_num++;
             }
 
             canvas_draw_line(canvas, x,y,x,y-(level*3));
 
+            /* Write a small triangle under the last sample detected. */
+            if (app->signal_bestlen != 0 &&
+                sample_num == app->signal_bestlen+1)
+            {
+                canvas_draw_dot(canvas,x,y+2);
+                canvas_draw_dot(canvas,x-1,y+3);
+                canvas_draw_dot(canvas,x,y+3);
+                canvas_draw_dot(canvas,x+1,y+3);
+                sample_num++; /* Make sure we don't mark the next, too. */
+            }
+
             /* Remove from the current level duration the time we
              * just plot. */
             if (dur > time_per_pixel)
@@ -73,7 +85,7 @@ uint32_t search_coherent_signal(RawSamplesBuffer *s, uint32_t idx) {
                                             allow for high and low. */
     uint32_t len = 0; /* Observed len of coherent samples. */
     s->short_pulse_dur = 0;
-    for (uint32_t j = idx; j < idx+100; j++) {
+    for (uint32_t j = idx; j < idx+500; j++) {
         bool level;
         uint32_t dur;
         raw_samples_get(s, j, &level, &dur);
@@ -160,8 +172,12 @@ void scan_for_signal(ProtoViewApp *app) {
     raw_samples_free(copy);
 }
 
-/* Draw some white text with a black border. */
-void canvas_draw_str_with_border(Canvas* canvas, uint8_t x, uint8_t y, const char* str)
+/* Draw some text with a border. If the outside color is black and the inside
+ * color is white, it just writes the border of the text, but the function can
+ * also be used to write a bold variation of the font setting both the
+ * colors to black, or alternatively to write a black text with a white
+ * border so that it is visible if there are black stuff on the background. */
+void canvas_draw_str_with_border(Canvas* canvas, uint8_t x, uint8_t y, const char* str, Color text_color, Color border_color)
 {
     struct {
         uint8_t x; uint8_t y;
@@ -176,13 +192,13 @@ void canvas_draw_str_with_border(Canvas* canvas, uint8_t x, uint8_t y, const cha
         {-1,0}
     };
 
-    /* Rotate in all the directions writing the same string in black
-     * to create a border, then write the actaul string in white in the
+    /* Rotate in all the directions writing the same string to create a
+     * border, then write the actual string in the other color in the
      * middle. */
-    canvas_set_color(canvas, ColorBlack);
+    canvas_set_color(canvas, border_color);
     for (int j = 0; j < 8; j++)
         canvas_draw_str(canvas,x+dir[j].x,y+dir[j].y,str);
-    canvas_set_color(canvas, ColorWhite);
+    canvas_set_color(canvas, text_color);
     canvas_draw_str(canvas,x,y,str);
     canvas_set_color(canvas, ColorBlack);
 }
@@ -197,7 +213,7 @@ void render_view_raw_pulses(Canvas *const canvas, ProtoViewApp *app) {
     snprintf(buf,sizeof(buf),"%luus",
         (unsigned long)DetectedSamples->short_pulse_dur);
     canvas_set_font(canvas, FontSecondary);
-    canvas_draw_str_with_border(canvas, 97, 63, buf);
+    canvas_draw_str_with_border(canvas, 97, 63, buf, ColorWhite, ColorBlack);
 }
 
 /* Renders a single view with frequency and modulation setting. However
@@ -207,14 +223,28 @@ void render_view_settings(Canvas *const canvas, ProtoViewApp *app) {
     UNUSED(app);
     canvas_set_font(canvas, FontPrimary);
     if (app->current_view == ViewFrequencySettings)
-        canvas_draw_str_with_border(canvas,1,10,"Frequency");
+        canvas_draw_str_with_border(canvas,1,10,"Frequency",ColorWhite,ColorBlack);
     else
         canvas_draw_str(canvas,1,10,"Frequency");
 
     if (app->current_view == ViewModulationSettings)
-        canvas_draw_str_with_border(canvas,70,10,"Modulation");
+        canvas_draw_str_with_border(canvas,70,10,"Modulation",ColorWhite,ColorBlack);
     else
         canvas_draw_str(canvas,70,10,"Modulation");
+    canvas_set_font(canvas, FontSecondary);
+    canvas_draw_str(canvas,10,61,"Use up and down to modify");
+
+    /* Show frequency. We can use big numbers font since it's just a number. */
+    if (app->current_view == ViewFrequencySettings) {
+        char buf[16];
+        snprintf(buf,sizeof(buf),"%.2f",(double)app->frequency/1000000);
+        canvas_set_font(canvas, FontBigNumbers);
+        canvas_draw_str(canvas, 30, 40, buf);
+    } else if (app->current_view == ViewModulationSettings) {
+        int current = app->modulation;
+        canvas_set_font(canvas, FontPrimary);
+        canvas_draw_str(canvas, 33, 39, ProtoViewModulations[current].name);
+    }
 }
 
 /* The callback actually just passes the control to the actual active
@@ -227,6 +257,7 @@ static void render_callback(Canvas *const canvas, void *ctx) {
     canvas_set_color(canvas, ColorWhite);
     canvas_draw_box(canvas, 0, 0, 127, 63);
     canvas_set_color(canvas, ColorBlack);
+    canvas_set_font(canvas, FontPrimary);
 
     /* Call who is in charge right now. */
     switch(app->current_view) {
@@ -363,8 +394,49 @@ void process_input_raw_pulses(ProtoViewApp *app, InputEvent input) {
 
 /* Handle input for the settings view. */
 void process_input_settings(ProtoViewApp *app, InputEvent input) {
-    UNUSED(input);
-    UNUSED(app);
+    /* Here we handle only up and down. Avoid any work if the user
+     * pressed something else. */
+    if (input.key != InputKeyDown && input.key != InputKeyUp) return;
+
+    if (app->current_view == ViewFrequencySettings) {
+        size_t curidx = 0, i;
+        size_t count = subghz_setting_get_frequency_count(app->setting);
+
+        /* Scan the list of frequencies to check for the index of the
+         * currently set frequency. */
+        for(i = 0; i < count; i++) {
+            uint32_t freq = subghz_setting_get_frequency(app->setting,i);
+            if (freq == app->frequency) {
+                curidx = i;
+                break;
+            }
+        }
+        if (i == count) return; /* Should never happen. */
+
+        if (input.key == InputKeyUp) {
+            curidx = (curidx+1) % count;
+        } else if (input.key == InputKeyDown) {
+            curidx = curidx == 0 ? count-1 : curidx-1;
+        }
+        app->frequency = subghz_setting_get_frequency(app->setting,curidx);
+    } else if (app->current_view == ViewModulationSettings) {
+        uint32_t count = 0;
+        uint32_t modid = app->modulation;
+
+        while(ProtoViewModulations[count].name != NULL) count++;
+        if (input.key == InputKeyUp) {
+            modid = (modid+1) % count;
+        } else if (input.key == InputKeyDown) {
+            modid = modid == 0 ? count-1 : modid-1;
+        }
+        app->modulation = modid;
+    }
+
+    /* Apply changes. */
+    FURI_LOG_E(TAG, "Setting view, setting frequency/modulation to %lu %s", app->frequency, ProtoViewModulations[app->modulation].name);
+    radio_rx_end(app);
+    radio_begin(app);
+    radio_rx(app);
 }
 
 int32_t protoview_app_entry(void* p) {
@@ -373,11 +445,11 @@ int32_t protoview_app_entry(void* p) {
 
     /* Create a timer. We do data analysis in the callback. */
     FuriTimer *timer = furi_timer_alloc(timer_callback, FuriTimerTypePeriodic, app);
-    furi_timer_start(timer, furi_kernel_get_tick_frequency() / 10);
+    furi_timer_start(timer, furi_kernel_get_tick_frequency() / 4);
 
     /* Start listening to signals immediately. */
     radio_begin(app);
-    radio_rx(app, app->frequency);
+    radio_rx(app);
 
     /* This is the main event loop: here we get the events that are pushed
      * in the queue by input_callback(), and process them one after the

+ 1 - 1
app.h

@@ -73,7 +73,7 @@ struct ProtoViewApp {
 };
 
 void radio_begin(ProtoViewApp* app);
-uint32_t radio_rx(ProtoViewApp* app, uint32_t frequency);
+uint32_t radio_rx(ProtoViewApp* app);
 void radio_idle(ProtoViewApp* app);
 void radio_rx_end(ProtoViewApp* app);
 void radio_sleep(ProtoViewApp* app);

+ 1 - 1
app_buffer.h

@@ -1,7 +1,7 @@
 /* Our circular buffer of raw samples, used in order to display
  * the signal. */
 
-#define RAW_SAMPLES_NUM 1024 /* Use a power of two: we take the modulo
+#define RAW_SAMPLES_NUM 2048 /* Use a power of two: we take the modulo
                                 of the index quite often to normalize inside
                                 the range, and division is slow. */
 

+ 4 - 4
app_subghz.c

@@ -26,16 +26,16 @@ void radio_begin(ProtoViewApp* app) {
 }
 
 /* Setup subghz to start receiving using a background worker. */
-uint32_t radio_rx(ProtoViewApp* app, uint32_t frequency) {
+uint32_t radio_rx(ProtoViewApp* app) {
     furi_assert(app);
-    if(!furi_hal_subghz_is_frequency_valid(frequency)) {
+    if(!furi_hal_subghz_is_frequency_valid(app->frequency)) {
         furi_crash(TAG" Incorrect RX frequency.");
     }
 
-    if (app->txrx->txrx_state == TxRxStateRx) return frequency;
+    if (app->txrx->txrx_state == TxRxStateRx) return app->frequency;
 
     furi_hal_subghz_idle(); /* Put it into idle state in case it is sleeping. */
-    uint32_t value = furi_hal_subghz_set_frequency_and_path(frequency);
+    uint32_t value = furi_hal_subghz_set_frequency_and_path(app->frequency);
     FURI_LOG_E(TAG, "Switched to frequency: %lu", value);
     furi_hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow);
     furi_hal_subghz_flush_rx();