view_direct_sampling.c 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  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. #include <cc1101.h>
  5. /* Read directly from the G0 CC1101 pin, and draw a black or white
  6. * dot depending on the level. */
  7. void render_view_direct_sampling(Canvas *const canvas, ProtoViewApp *app) {
  8. if (!app->direct_sampling_enabled) {
  9. canvas_set_font(canvas, FontSecondary);
  10. canvas_draw_str(canvas,2,9,"Direct sampling is a special");
  11. canvas_draw_str(canvas,2,18,"mode that displays the signal");
  12. canvas_draw_str(canvas,2,27,"captured in real time. Like in");
  13. canvas_draw_str(canvas,2,36,"a old CRT TV. It's very slow.");
  14. canvas_draw_str(canvas,2,45,"Can crash your Flipper.");
  15. canvas_set_font(canvas, FontPrimary);
  16. canvas_draw_str(canvas,14,60,"To enable press OK");
  17. return;
  18. }
  19. for (int y = 0; y < 64; y++) {
  20. for (int x = 0; x < 128; x++) {
  21. bool level = furi_hal_gpio_read(&gpio_cc1101_g0);
  22. if (level) canvas_draw_dot(canvas,x,y);
  23. /* Busy loop: this is a terrible approach as it blocks
  24. * everything else, but for now it's the best we can do
  25. * to obtain direct data with some spacing. */
  26. uint32_t x = 250; while(x--);
  27. }
  28. }
  29. canvas_set_font(canvas, FontSecondary);
  30. canvas_draw_str_with_border(canvas,36,60,"Direct sampling",
  31. ColorWhite,ColorBlack);
  32. }
  33. /* Handle input */
  34. void process_input_direct_sampling(ProtoViewApp *app, InputEvent input) {
  35. if (input.type == InputTypePress && input.key == InputKeyOk) {
  36. app->direct_sampling_enabled = !app->direct_sampling_enabled;
  37. }
  38. }
  39. /* Enter view. Stop the subghz thread to prevent access as we read
  40. * the CC1101 data directly. */
  41. void view_enter_direct_sampling(ProtoViewApp *app) {
  42. if (app->txrx->txrx_state == TxRxStateRx &&
  43. !app->txrx->debug_timer_sampling)
  44. {
  45. furi_hal_subghz_stop_async_rx();
  46. // To read data asynchronously directly from the view, we need
  47. // to put the CC1101 back into reception mode (the previous call
  48. // to stop the async RX will put it into idle) and configure the
  49. // G0 pin for reading.
  50. furi_hal_subghz_rx();
  51. furi_hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow);
  52. } else {
  53. raw_sampling_worker_stop(app);
  54. }
  55. }
  56. /* Exit view. Restore the subghz thread. */
  57. void view_exit_direct_sampling(ProtoViewApp *app) {
  58. if (app->txrx->txrx_state == TxRxStateRx &&
  59. !app->txrx->debug_timer_sampling)
  60. {
  61. furi_hal_subghz_start_async_rx(protoview_rx_callback, NULL);
  62. } else {
  63. raw_sampling_worker_start(app);
  64. }
  65. app->direct_sampling_enabled = false;
  66. }