view_raw_signal.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. /* Copyright (C) 2022-2023 Salvatore Sanfilippo -- All Rights Reserved
  2. * See the LICENSE file for information about the license. */
  3. #include "app.h"
  4. /* Render the received signal.
  5. *
  6. * The screen of the flipper is 128 x 64. Even using 4 pixels per line
  7. * (where low level signal is one pixel high, high level is 4 pixels
  8. * high) and 4 pixels of spacing between the different lines, we can
  9. * plot comfortably 8 lines.
  10. *
  11. * The 'idx' argument is the first sample to render in the circular
  12. * buffer. */
  13. void render_signal(ProtoViewApp *app, Canvas *const canvas, RawSamplesBuffer *buf, uint32_t idx) {
  14. canvas_set_color(canvas, ColorBlack);
  15. int rows = 8;
  16. uint32_t time_per_pixel = app->us_scale;
  17. uint32_t start_idx = idx;
  18. bool level = 0;
  19. uint32_t dur = 0, sample_num = 0;
  20. for (int row = 0; row < rows ; row++) {
  21. for (int x = 0; x < 128; x++) {
  22. int y = 3 + row*8;
  23. if (dur < time_per_pixel/2) {
  24. /* Get more data. */
  25. raw_samples_get(buf, idx++, &level, &dur);
  26. sample_num++;
  27. }
  28. canvas_draw_line(canvas, x,y,x,y-(level*3));
  29. /* Write a small triangle under the last sample detected. */
  30. if (app->signal_bestlen != 0 &&
  31. sample_num+start_idx == app->signal_bestlen+1)
  32. {
  33. canvas_draw_dot(canvas,x,y+2);
  34. canvas_draw_dot(canvas,x-1,y+3);
  35. canvas_draw_dot(canvas,x,y+3);
  36. canvas_draw_dot(canvas,x+1,y+3);
  37. sample_num++; /* Make sure we don't mark the next, too. */
  38. }
  39. /* Remove from the current level duration the time we
  40. * just plot. */
  41. if (dur > time_per_pixel)
  42. dur -= time_per_pixel;
  43. else
  44. dur = 0;
  45. }
  46. }
  47. }
  48. /* Raw pulses rendering. This is our default view. */
  49. void render_view_raw_pulses(Canvas *const canvas, ProtoViewApp *app) {
  50. /* Show signal. */
  51. render_signal(app, canvas, DetectedSamples, app->signal_offset);
  52. /* Show signal information. */
  53. char buf[64];
  54. snprintf(buf,sizeof(buf),"%luus",
  55. (unsigned long)DetectedSamples->short_pulse_dur);
  56. canvas_set_font(canvas, FontSecondary);
  57. canvas_draw_str_with_border(canvas, 97, 63, buf, ColorWhite, ColorBlack);
  58. if (app->signal_decoded) {
  59. canvas_set_font(canvas, FontPrimary);
  60. canvas_draw_str_with_border(canvas, 1, 61, app->msg_info->decoder->name, ColorWhite, ColorBlack);
  61. }
  62. }
  63. /* Handle input for the raw pulses view. */
  64. void process_input_raw_pulses(ProtoViewApp *app, InputEvent input) {
  65. if (input.type == InputTypeRepeat) {
  66. /* Handle panning of the signal window. Long pressing
  67. * right will show successive samples, long pressing left
  68. * previous samples. */
  69. if (input.key == InputKeyRight) app->signal_offset++;
  70. else if (input.key == InputKeyLeft) app->signal_offset--;
  71. } else if (input.type == InputTypeLong) {
  72. if (input.key == InputKeyOk) {
  73. /* Reset the current sample to capture the next. */
  74. reset_current_signal(app);
  75. }
  76. } else if (input.type == InputTypeShort) {
  77. if (input.key == InputKeyOk) {
  78. app->signal_offset = 0;
  79. adjust_raw_view_scale(app,DetectedSamples->short_pulse_dur);
  80. } else if (input.key == InputKeyDown) {
  81. /* Rescaling. The set becomes finer under 50us per pixel. */
  82. uint32_t scale_step = app->us_scale >= 50 ? 50 : 10;
  83. if (app->us_scale < 500) app->us_scale += scale_step;
  84. } else if (input.key == InputKeyUp) {
  85. uint32_t scale_step = app->us_scale > 50 ? 50 : 10;
  86. if (app->us_scale > 10) app->us_scale -= scale_step;
  87. }
  88. }
  89. }
  90. /* Adjust raw view scale depending on short pulse duration. */
  91. void adjust_raw_view_scale(ProtoViewApp *app, uint32_t short_pulse_dur) {
  92. if (short_pulse_dur == 0)
  93. app->us_scale = PROTOVIEW_RAW_VIEW_DEFAULT_SCALE;
  94. else if (short_pulse_dur < 75)
  95. app->us_scale = 10;
  96. else if (short_pulse_dur < 145)
  97. app->us_scale = 30;
  98. else if (short_pulse_dur < 400)
  99. app->us_scale = 100;
  100. else if (short_pulse_dur < 1000)
  101. app->us_scale = 200;
  102. else
  103. app->us_scale = PROTOVIEW_RAW_VIEW_DEFAULT_SCALE;
  104. }