unleashed-firmware/applications/plugins/protoview/view_raw_signal.c

98 lines
3.7 KiB
C
Raw Normal View History

/* Copyright (C) 2022-2023 Salvatore Sanfilippo -- All Rights Reserved
* See the LICENSE file for information about the license. */
#include "app.h"
/* Render the received signal.
*
* The screen of the flipper is 128 x 64. Even using 4 pixels per line
* (where low level signal is one pixel high, high level is 4 pixels
* high) and 4 pixels of spacing between the different lines, we can
* plot comfortably 8 lines.
*
* The 'idx' argument is the first sample to render in the circular
* buffer. */
void render_signal(ProtoViewApp *app, Canvas *const canvas, RawSamplesBuffer *buf, uint32_t idx) {
canvas_set_color(canvas, ColorBlack);
int rows = 8;
uint32_t time_per_pixel = app->us_scale;
uint32_t start_idx = idx;
bool level = 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+start_idx == 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)
dur -= time_per_pixel;
else
dur = 0;
}
}
}
/* Raw pulses rendering. This is our default view. */
void render_view_raw_pulses(Canvas *const canvas, ProtoViewApp *app) {
/* Show signal. */
render_signal(app, canvas, DetectedSamples, app->signal_offset);
/* Show signal information. */
char buf[64];
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, ColorWhite, ColorBlack);
if (app->signal_decoded) {
canvas_set_font(canvas, FontPrimary);
canvas_draw_str_with_border(canvas, 1, 61, app->msg_info->name, ColorWhite, ColorBlack);
}
}
/* Handle input for the raw pulses view. */
void process_input_raw_pulses(ProtoViewApp *app, InputEvent input) {
if (input.type == InputTypeRepeat) {
/* Handle panning of the signal window. Long pressing
* right will show successive samples, long pressing left
* previous samples. */
if (input.key == InputKeyRight) app->signal_offset++;
else if (input.key == InputKeyLeft) app->signal_offset--;
else if (input.key == InputKeyOk) {
app->signal_offset = 0;
app->us_scale = PROTOVIEW_RAW_VIEW_DEFAULT_SCALE;
}
} else if (input.type == InputTypeShort) {
if (input.key == InputKeyOk) {
/* Reset the current sample to capture the next. */
reset_current_signal(app);
} else if (input.key == InputKeyDown) {
/* Rescaling. The set becomes finer under 50us per pixel. */
uint32_t scale_step = app->us_scale >= 50 ? 50 : 10;
if (app->us_scale < 500) app->us_scale += scale_step;
} else if (input.key == InputKeyUp) {
uint32_t scale_step = app->us_scale > 50 ? 50 : 10;
if (app->us_scale > 10) app->us_scale -= scale_step;
}
}
}