mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-04-24 03:29:57 -07:00
Add nrf24 channel scanner
This commit is contained in:
21
applications/external/nrf24channelscanner/application.fam
vendored
Normal file
21
applications/external/nrf24channelscanner/application.fam
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
App(
|
||||
appid="nrf24channelscanner",
|
||||
name="[NRF24] Channel scanner",
|
||||
apptype=FlipperAppType.EXTERNAL,
|
||||
entry_point="nrf24channelscanner_main",
|
||||
stack_size=2 * 1024,
|
||||
requires=["gui"],
|
||||
fap_category="GPIO",
|
||||
fap_version=(1, 1),
|
||||
fap_icon_assets="images",
|
||||
fap_icon="fapicon.png",
|
||||
fap_description="Scans 2.4Ghz frequency for usage data.",
|
||||
fap_private_libs=[
|
||||
Lib(
|
||||
name="nrf24",
|
||||
sources=[
|
||||
"nrf24.c",
|
||||
],
|
||||
),
|
||||
],
|
||||
)
|
||||
BIN
applications/external/nrf24channelscanner/fapicon.png
vendored
Normal file
BIN
applications/external/nrf24channelscanner/fapicon.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 145 B |
BIN
applications/external/nrf24channelscanner/images/Ok_btn_9x9.png
vendored
Normal file
BIN
applications/external/nrf24channelscanner/images/Ok_btn_9x9.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 967 B |
BIN
applications/external/nrf24channelscanner/images/Pin_back_arrow_10x8.png
vendored
Normal file
BIN
applications/external/nrf24channelscanner/images/Pin_back_arrow_10x8.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 978 B |
117
applications/external/nrf24channelscanner/lib/nrf24/nrf24.c
vendored
Normal file
117
applications/external/nrf24channelscanner/lib/nrf24/nrf24.c
vendored
Normal file
@@ -0,0 +1,117 @@
|
||||
#include "nrf24.h"
|
||||
#include <furi.h>
|
||||
#include <furi_hal.h>
|
||||
#include <furi_hal_resources.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
void nrf24_init() {
|
||||
// this is needed if multiple SPI devices are connected to the same bus but with different CS pins
|
||||
if(XTREME_SETTINGS()->spi_nrf24_handle == SpiDefault) {
|
||||
furi_hal_gpio_init_simple(&gpio_ext_pc3, GpioModeOutputPushPull);
|
||||
furi_hal_gpio_write(&gpio_ext_pc3, true);
|
||||
} else if(XTREME_SETTINGS()->spi_nrf24_handle == SpiExtra) {
|
||||
furi_hal_gpio_init_simple(&gpio_ext_pa4, GpioModeOutputPushPull);
|
||||
furi_hal_gpio_write(&gpio_ext_pa4, true);
|
||||
}
|
||||
|
||||
furi_hal_spi_bus_handle_init(nrf24_HANDLE);
|
||||
furi_hal_spi_acquire(nrf24_HANDLE);
|
||||
furi_hal_gpio_init(nrf24_CE_PIN, GpioModeOutputPushPull, GpioPullUp, GpioSpeedVeryHigh);
|
||||
furi_hal_gpio_write(nrf24_CE_PIN, false);
|
||||
}
|
||||
|
||||
void nrf24_deinit() {
|
||||
furi_hal_spi_release(nrf24_HANDLE);
|
||||
furi_hal_spi_bus_handle_deinit(nrf24_HANDLE);
|
||||
furi_hal_gpio_write(nrf24_CE_PIN, false);
|
||||
furi_hal_gpio_init(nrf24_CE_PIN, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
|
||||
|
||||
// resetting the CS pins to floating
|
||||
if(XTREME_SETTINGS()->spi_nrf24_handle == SpiDefault) {
|
||||
furi_hal_gpio_init_simple(&gpio_ext_pc3, GpioModeAnalog);
|
||||
} else if(XTREME_SETTINGS()->spi_nrf24_handle == SpiExtra) {
|
||||
furi_hal_gpio_init_simple(&gpio_ext_pa4, GpioModeAnalog);
|
||||
}
|
||||
}
|
||||
|
||||
void nrf24_spi_trx(
|
||||
FuriHalSpiBusHandle* handle,
|
||||
uint8_t* tx,
|
||||
uint8_t* rx,
|
||||
uint8_t size,
|
||||
uint32_t timeout) {
|
||||
UNUSED(timeout);
|
||||
furi_hal_gpio_write(handle->cs, false);
|
||||
furi_hal_spi_bus_trx(handle, tx, rx, size, nrf24_TIMEOUT);
|
||||
furi_hal_gpio_write(handle->cs, true);
|
||||
}
|
||||
|
||||
uint8_t nrf24_write_reg(FuriHalSpiBusHandle* handle, uint8_t reg, uint8_t data) {
|
||||
uint8_t tx[2] = {W_REGISTER | (REGISTER_MASK & reg), data};
|
||||
uint8_t rx[2] = {0};
|
||||
nrf24_spi_trx(handle, tx, rx, 2, nrf24_TIMEOUT);
|
||||
return rx[0];
|
||||
}
|
||||
|
||||
uint8_t nrf24_read_reg(FuriHalSpiBusHandle* handle, uint8_t reg, uint8_t* data, uint8_t size) {
|
||||
uint8_t tx[size + 1];
|
||||
uint8_t rx[size + 1];
|
||||
memset(rx, 0, size + 1);
|
||||
tx[0] = R_REGISTER | (REGISTER_MASK & reg);
|
||||
memset(&tx[1], 0, size);
|
||||
nrf24_spi_trx(handle, tx, rx, size + 1, nrf24_TIMEOUT);
|
||||
memcpy(data, &rx[1], size);
|
||||
return rx[0];
|
||||
}
|
||||
|
||||
uint8_t nrf24_flush_rx(FuriHalSpiBusHandle* handle) {
|
||||
uint8_t tx[] = {FLUSH_RX};
|
||||
uint8_t rx[] = {0};
|
||||
nrf24_spi_trx(handle, tx, rx, 1, nrf24_TIMEOUT);
|
||||
return rx[0];
|
||||
}
|
||||
|
||||
uint8_t nrf24_get_rdp(FuriHalSpiBusHandle* handle) {
|
||||
uint8_t rdp;
|
||||
nrf24_read_reg(handle, REG_RDP, &rdp, 1);
|
||||
return rdp;
|
||||
}
|
||||
|
||||
uint8_t nrf24_status(FuriHalSpiBusHandle* handle) {
|
||||
uint8_t status;
|
||||
uint8_t tx[] = {R_REGISTER | (REGISTER_MASK & REG_STATUS)};
|
||||
nrf24_spi_trx(handle, tx, &status, 1, nrf24_TIMEOUT);
|
||||
return status;
|
||||
}
|
||||
|
||||
uint8_t nrf24_set_idle(FuriHalSpiBusHandle* handle) {
|
||||
uint8_t status = 0;
|
||||
uint8_t cfg = 0;
|
||||
nrf24_read_reg(handle, REG_CONFIG, &cfg, 1);
|
||||
cfg &= 0xfc; // clear bottom two bits to power down the radio
|
||||
status = nrf24_write_reg(handle, REG_CONFIG, cfg);
|
||||
furi_hal_gpio_write(nrf24_CE_PIN, false);
|
||||
return status;
|
||||
}
|
||||
|
||||
uint8_t nrf24_set_rx_mode(FuriHalSpiBusHandle* handle, bool nodelay) {
|
||||
uint8_t status = 0;
|
||||
uint8_t cfg = 0;
|
||||
nrf24_read_reg(handle, REG_CONFIG, &cfg, 1);
|
||||
cfg |= 0x03; // PWR_UP, and PRIM_RX
|
||||
status = nrf24_write_reg(handle, REG_CONFIG, cfg);
|
||||
furi_hal_gpio_write(nrf24_CE_PIN, true);
|
||||
if(!nodelay) furi_delay_ms(2000);
|
||||
return status;
|
||||
}
|
||||
|
||||
bool nrf24_check_connected(FuriHalSpiBusHandle* handle) {
|
||||
uint8_t status = nrf24_status(handle);
|
||||
|
||||
if(status != 0x00) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
129
applications/external/nrf24channelscanner/lib/nrf24/nrf24.h
vendored
Normal file
129
applications/external/nrf24channelscanner/lib/nrf24/nrf24.h
vendored
Normal file
@@ -0,0 +1,129 @@
|
||||
#pragma once
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <furi_hal_spi.h>
|
||||
#include <xtreme.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define R_REGISTER 0x00
|
||||
#define W_REGISTER 0x20
|
||||
#define REGISTER_MASK 0x1F
|
||||
#define ACTIVATE 0x50
|
||||
#define R_RX_PL_WID 0x60
|
||||
#define R_RX_PAYLOAD 0x61
|
||||
#define W_TX_PAYLOAD 0xA0
|
||||
#define W_TX_PAYLOAD_NOACK 0xB0
|
||||
#define W_ACK_PAYLOAD 0xA8
|
||||
#define FLUSH_TX 0xE1
|
||||
#define FLUSH_RX 0xE2
|
||||
#define REUSE_TX_PL 0xE3
|
||||
#define RF24_NOP 0xFF
|
||||
|
||||
#define REG_CONFIG 0x00
|
||||
#define REG_EN_AA 0x01
|
||||
#define REG_EN_RXADDR 0x02
|
||||
#define REG_SETUP_AW 0x03
|
||||
#define REG_SETUP_RETR 0x04
|
||||
#define REG_RDP 0x09
|
||||
#define REG_DYNPD 0x1C
|
||||
#define REG_FEATURE 0x1D
|
||||
#define REG_RF_SETUP 0x06
|
||||
#define REG_STATUS 0x07
|
||||
#define REG_RX_ADDR_P0 0x0A
|
||||
#define REG_RF_CH 0x05
|
||||
#define REG_TX_ADDR 0x10
|
||||
|
||||
#define RX_PW_P0 0x11
|
||||
#define TX_DS 0x20
|
||||
#define MAX_RT 0x10
|
||||
|
||||
#define nrf24_TIMEOUT 500
|
||||
#define nrf24_CE_PIN &gpio_ext_pb2
|
||||
#define nrf24_HANDLE \
|
||||
(XTREME_SETTINGS()->spi_nrf24_handle == SpiDefault ? &furi_hal_spi_bus_handle_external : \
|
||||
&furi_hal_spi_bus_handle_external_extra)
|
||||
|
||||
/* Low level API */
|
||||
|
||||
/** Write device register
|
||||
*
|
||||
* @param handle - pointer to FuriHalSpiHandle
|
||||
* @param reg - register
|
||||
* @param data - data to write
|
||||
*
|
||||
* @return device status
|
||||
*/
|
||||
uint8_t nrf24_write_reg(FuriHalSpiBusHandle* handle, uint8_t reg, uint8_t data);
|
||||
|
||||
/** Read device register
|
||||
*
|
||||
* @param handle - pointer to FuriHalSpiHandle
|
||||
* @param reg - register
|
||||
* @param[out] data - pointer to data
|
||||
*
|
||||
* @return device status
|
||||
*/
|
||||
uint8_t nrf24_read_reg(FuriHalSpiBusHandle* handle, uint8_t reg, uint8_t* data, uint8_t size);
|
||||
|
||||
/** Power down the radio
|
||||
*
|
||||
* @param handle - pointer to FuriHalSpiHandle
|
||||
*
|
||||
* @return device status
|
||||
*/
|
||||
uint8_t nrf24_set_idle(FuriHalSpiBusHandle* handle);
|
||||
|
||||
/** Sets the radio to RX mode
|
||||
*
|
||||
* @param handle - pointer to FuriHalSpiHandle
|
||||
*
|
||||
* @return device status
|
||||
*/
|
||||
uint8_t nrf24_set_rx_mode(FuriHalSpiBusHandle* handle, bool nodelay);
|
||||
|
||||
/*=============================================================================================================*/
|
||||
|
||||
/* High level API */
|
||||
|
||||
/** Must call this before using any other nrf24 API
|
||||
*
|
||||
*/
|
||||
void nrf24_init();
|
||||
|
||||
/** Must call this when we end using nrf24 device
|
||||
*
|
||||
*/
|
||||
void nrf24_deinit();
|
||||
|
||||
/** Send flush rx command
|
||||
*
|
||||
* @param handle - pointer to FuriHalSpiHandle
|
||||
*
|
||||
* @return device status
|
||||
*/
|
||||
uint8_t nrf24_flush_rx(FuriHalSpiBusHandle* handle);
|
||||
|
||||
/** Gets RDP from register 0x09
|
||||
*
|
||||
* @param handle - pointer to FuriHalSpiHandle
|
||||
*
|
||||
* @return RDP from register 0x09
|
||||
*/
|
||||
uint8_t nrf24_get_rdp(FuriHalSpiBusHandle* handle);
|
||||
|
||||
/** Gets the current status flags from the STATUS register
|
||||
*
|
||||
* @param handle - pointer to FuriHalSpiHandle
|
||||
*
|
||||
* @return status flags
|
||||
*/
|
||||
uint8_t nrf24_status(FuriHalSpiBusHandle* handle);
|
||||
|
||||
bool nrf24_check_connected(FuriHalSpiBusHandle* handle);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
251
applications/external/nrf24channelscanner/nrf24channelscanner.c
vendored
Normal file
251
applications/external/nrf24channelscanner/nrf24channelscanner.c
vendored
Normal file
@@ -0,0 +1,251 @@
|
||||
#include <stdio.h>
|
||||
#include <furi.h>
|
||||
#include <gui/gui.h>
|
||||
#include <input/input.h>
|
||||
#include <gui/elements.h>
|
||||
#include <notification/notification_messages.h>
|
||||
#include <nrf24.h>
|
||||
#include "nrf24channelscanner_icons.h"
|
||||
|
||||
const uint8_t num_channels = 128;
|
||||
static uint8_t nrf24values[128] = {0}; //to store channel data
|
||||
|
||||
bool ifNotFoundNrf = false; //to show error message
|
||||
bool szuz = true; //to show welcome screen
|
||||
static bool isScanning = false; //to track the progress
|
||||
static bool stopNrfScan = false; //to exit thread
|
||||
|
||||
static bool threadStoppedsoFree = false; //indicate if I can free the thread from ram.
|
||||
static uint8_t currCh = 0; //for the progress bar or the channel selector
|
||||
|
||||
static int delayPerChan = 5; //can set via up / down.
|
||||
|
||||
bool showFreq = true;
|
||||
|
||||
FuriThread* thread;
|
||||
|
||||
typedef enum {
|
||||
EventTypeKey,
|
||||
EventTypeTick,
|
||||
} EventType;
|
||||
|
||||
typedef struct {
|
||||
EventType type;
|
||||
InputEvent input;
|
||||
} Event;
|
||||
|
||||
static void draw_callback(Canvas* canvas, void* ctx) {
|
||||
UNUSED(ctx);
|
||||
|
||||
canvas_clear(canvas);
|
||||
canvas_set_bitmap_mode(canvas, 1);
|
||||
canvas_draw_icon(canvas, 100, 0, &I_Pin_back_arrow_10x8);
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
canvas_draw_str(canvas, 112, 8, "Exit");
|
||||
canvas_draw_icon(canvas, 1, 0, &I_Ok_btn_9x9);
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
if(isScanning) {
|
||||
canvas_draw_str(canvas, 12, 8, "Stop");
|
||||
} else {
|
||||
canvas_draw_str(canvas, 12, 8, "Scan");
|
||||
}
|
||||
canvas_draw_line(canvas, 0, 11, 127, 11);
|
||||
|
||||
if(ifNotFoundNrf) {
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
canvas_draw_str(canvas, 23, 35, "NRF24 not found!");
|
||||
return;
|
||||
}
|
||||
|
||||
canvas_draw_line(canvas, currCh, 12, currCh, 13); //draw the current channel
|
||||
|
||||
//draw hello mesage
|
||||
if(szuz) {
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
canvas_draw_str(canvas, 1, 22, "Up / Down to change channel time.");
|
||||
canvas_draw_str(canvas, 1, 36, "Left / Right to select channel,");
|
||||
canvas_draw_str(canvas, 1, 48, "to get it's frequency");
|
||||
}
|
||||
|
||||
//draw freq ir the progress
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
if(isScanning) {
|
||||
canvas_draw_str(canvas, 37, 8, "scanning");
|
||||
} else {
|
||||
if(showFreq) {
|
||||
int freq = 2400 + currCh;
|
||||
char strfreq[10] = {32};
|
||||
itoa(freq, strfreq, 10);
|
||||
strfreq[4] = ' ';
|
||||
strfreq[5] = 'M';
|
||||
strfreq[6] = 'H';
|
||||
strfreq[7] = 'Z';
|
||||
strfreq[8] = 0;
|
||||
canvas_draw_str(canvas, 40, 8, strfreq);
|
||||
} else {
|
||||
//show delay
|
||||
int dly = delayPerChan;
|
||||
char strdel[10] = {32};
|
||||
itoa(dly, strdel, 10);
|
||||
if(dly < 10) strdel[1] = ' ';
|
||||
if(dly < 100) strdel[2] = ' ';
|
||||
if(dly < 1000) strdel[3] = ' ';
|
||||
strdel[4] = ' ';
|
||||
strdel[5] = 'm';
|
||||
strdel[6] = 's';
|
||||
strdel[7] = 0;
|
||||
canvas_draw_str(canvas, 40, 8, strdel);
|
||||
}
|
||||
}
|
||||
|
||||
//draw the chart
|
||||
for(int i = 0; i < num_channels; ++i) {
|
||||
int h = 64 - nrf24values[i];
|
||||
if(h < 11) h = 12;
|
||||
canvas_draw_line(canvas, i, h, i, 64);
|
||||
}
|
||||
}
|
||||
|
||||
static void input_callback(InputEvent* input_event, void* ctx) {
|
||||
furi_assert(ctx);
|
||||
FuriMessageQueue* event_queue = ctx;
|
||||
Event event = {.type = EventTypeKey, .input = *input_event};
|
||||
furi_message_queue_put(event_queue, &event, FuriWaitForever);
|
||||
}
|
||||
|
||||
static int32_t scanner(void* context) {
|
||||
UNUSED(context);
|
||||
isScanning = true;
|
||||
stopNrfScan = false;
|
||||
threadStoppedsoFree = false;
|
||||
uint8_t tmp = 0;
|
||||
currCh = 0;
|
||||
nrf24_set_rx_mode(nrf24_HANDLE, false);
|
||||
nrf24_write_reg(nrf24_HANDLE, REG_EN_AA, 0x0);
|
||||
nrf24_write_reg(nrf24_HANDLE, REG_RF_SETUP, 0x0f);
|
||||
for(uint8_t j = 0; j < 15;) { //scan until stopped!
|
||||
if(stopNrfScan) break;
|
||||
for(uint8_t i = 0; i < num_channels; i++) {
|
||||
if(stopNrfScan) break;
|
||||
currCh = i;
|
||||
nrf24_write_reg(nrf24_HANDLE, REG_RF_CH, i);
|
||||
nrf24_set_rx_mode(nrf24_HANDLE, true);
|
||||
for(uint8_t ii = 0; ii < 3; ++ii) {
|
||||
nrf24_flush_rx(nrf24_HANDLE);
|
||||
furi_delay_ms(delayPerChan);
|
||||
tmp = nrf24_get_rdp(nrf24_HANDLE);
|
||||
if(tmp > 0) nrf24values[i]++;
|
||||
if(nrf24values[i] > 50) j = 254; //stop, bc maxed
|
||||
}
|
||||
}
|
||||
}
|
||||
nrf24_set_idle(nrf24_HANDLE);
|
||||
isScanning = false;
|
||||
threadStoppedsoFree = true;
|
||||
currCh = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ChangeFreq(int delta) {
|
||||
currCh += delta;
|
||||
if(currCh > num_channels) currCh = 0;
|
||||
showFreq = true;
|
||||
}
|
||||
|
||||
void ChangeDelay(int delta) {
|
||||
delayPerChan += delta;
|
||||
if(delayPerChan > 100) delayPerChan = 100;
|
||||
if(delayPerChan < 1) delayPerChan = 1;
|
||||
if(delayPerChan == 11) delayPerChan = 10; //to get it rounded :)
|
||||
if(delayPerChan == 6) delayPerChan = 5; //to get it rounded :)
|
||||
showFreq = false;
|
||||
}
|
||||
|
||||
// Main entry of the application
|
||||
int32_t nrf24channelscanner_main(void* p) {
|
||||
UNUSED(p);
|
||||
|
||||
Event event;
|
||||
FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(Event));
|
||||
|
||||
nrf24_init();
|
||||
|
||||
ViewPort* view_port = view_port_alloc();
|
||||
view_port_draw_callback_set(view_port, draw_callback, NULL);
|
||||
view_port_input_callback_set(view_port, input_callback, event_queue);
|
||||
|
||||
Gui* gui = furi_record_open(RECORD_GUI);
|
||||
gui_add_view_port(gui, view_port, GuiLayerFullscreen);
|
||||
|
||||
NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION);
|
||||
|
||||
while(true) {
|
||||
furi_check(furi_message_queue_get(event_queue, &event, FuriWaitForever) == FuriStatusOk);
|
||||
|
||||
if(event.type == EventTypeKey) {
|
||||
szuz = false; //hit any button, so hide welcome screen
|
||||
if(event.input.type == InputTypeLong && event.input.key == InputKeyBack) {
|
||||
if(isScanning) {
|
||||
stopNrfScan = true; //if running, stop it.
|
||||
notification_message(notification, &sequence_blink_yellow_100);
|
||||
furi_thread_join(thread);
|
||||
furi_thread_free(thread);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if(event.input.type == InputTypeShort && event.input.key == InputKeyOk) {
|
||||
if(isScanning) {
|
||||
notification_message(notification, &sequence_blink_yellow_100);
|
||||
stopNrfScan = true;
|
||||
furi_thread_join(thread);
|
||||
furi_thread_free(thread);
|
||||
threadStoppedsoFree = false; //to prevent double free
|
||||
continue;
|
||||
}
|
||||
memset(nrf24values, 0, sizeof(nrf24values));
|
||||
if(nrf24_check_connected(nrf24_HANDLE)) {
|
||||
threadStoppedsoFree = false;
|
||||
ifNotFoundNrf = false;
|
||||
notification_message(notification, &sequence_blink_green_100);
|
||||
thread = furi_thread_alloc();
|
||||
furi_thread_set_name(thread, "nrfscannerth");
|
||||
furi_thread_set_stack_size(thread, 1024);
|
||||
furi_thread_set_callback(thread, scanner);
|
||||
furi_thread_start(thread);
|
||||
} else {
|
||||
ifNotFoundNrf = true;
|
||||
notification_message(notification, &sequence_error);
|
||||
}
|
||||
}
|
||||
//change the delay
|
||||
if(event.input.type == InputTypeShort && event.input.key == InputKeyUp) {
|
||||
ChangeDelay(5);
|
||||
}
|
||||
if(event.input.type == InputTypeShort && event.input.key == InputKeyDown) {
|
||||
ChangeDelay(-5);
|
||||
}
|
||||
|
||||
if(!isScanning) {
|
||||
if(event.input.type == InputTypeLong && event.input.key == InputKeyLeft)
|
||||
ChangeFreq(-10);
|
||||
if(event.input.type == InputTypeShort && event.input.key == InputKeyLeft)
|
||||
ChangeFreq(-1);
|
||||
if(event.input.type == InputTypeLong && event.input.key == InputKeyRight)
|
||||
ChangeFreq(10);
|
||||
if(event.input.type == InputTypeShort && event.input.key == InputKeyRight)
|
||||
ChangeFreq(1);
|
||||
}
|
||||
}
|
||||
if(threadStoppedsoFree) {
|
||||
threadStoppedsoFree = false;
|
||||
furi_thread_join(thread);
|
||||
furi_thread_free(thread);
|
||||
}
|
||||
}
|
||||
nrf24_deinit();
|
||||
furi_message_queue_free(event_queue);
|
||||
gui_remove_view_port(gui, view_port);
|
||||
view_port_free(view_port);
|
||||
furi_record_close(RECORD_GUI);
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user