Merge remote-tracking branch 'origin/dev' into release-candidate

This commit is contained in:
Aleksandr Kutuzov 2022-06-14 12:08:22 +09:00
commit e682e02bca
No known key found for this signature in database
GPG Key ID: 0D0011717914BBCD
14 changed files with 599 additions and 442 deletions

132
.github/CODEOWNERS vendored
View File

@ -1,63 +1,91 @@
# Who owns all the fish by default # Who owns all the fish by default
* @skotopes @DrZlo13 @hedger
* @skotopes @DrZlo13 # Apps
/applications/about/ @skotopes @DrZlo13 @hedger
/applications/accessor/ @skotopes @DrZlo13 @hedger
/applications/archive/ @skotopes @DrZlo13 @hedger @nminaylov
/applications/bad_usb/ @skotopes @DrZlo13 @hedger @nminaylov
/applications/bt/ @skotopes @DrZlo13 @hedger @gornekich
/applications/cli/ @skotopes @DrZlo13 @hedger @nminaylov
/applications/crypto/ @skotopes @DrZlo13 @hedger @nminaylov
/applications/debug_tools/ @skotopes @DrZlo13 @hedger
/applications/desktop/ @skotopes @DrZlo13 @hedger @nminaylov
/applications/dialogs/ @skotopes @DrZlo13 @hedger
/applications/dolphin/ @skotopes @DrZlo13 @hedger
/applications/gpio/ @skotopes @DrZlo13 @hedger @nminaylov
/applications/gui/ @skotopes @DrZlo13 @hedger
/applications/ibutton/ @skotopes @DrZlo13 @hedger @gsurkov
/applications/infrared/ @skotopes @DrZlo13 @hedger @gsurkov
/applications/infrared_monitor/ @skotopes @DrZlo13 @hedger @gsurkov
/applications/input/ @skotopes @DrZlo13 @hedger
/applications/lfrfid/ @skotopes @DrZlo13 @hedger
/applications/lfrfid_debug/ @skotopes @DrZlo13 @hedger
/applications/loader/ @skotopes @DrZlo13 @hedger
/applications/music_player/ @skotopes @DrZlo13 @hedger
/applications/nfc/ @skotopes @DrZlo13 @hedger @gornekich
/applications/notification/ @skotopes @DrZlo13 @hedger
/applications/power/ @skotopes @DrZlo13 @hedger
/applications/rpc/ @skotopes @DrZlo13 @hedger @nminaylov
/applications/snake_game/ @skotopes @DrZlo13 @hedger
/applications/storage/ @skotopes @DrZlo13 @hedger
/applications/storage_settings/ @skotopes @DrZlo13 @hedger
/applications/subghz/ @skotopes @DrZlo13 @hedger @Skorpionm
/applications/system/ @skotopes @DrZlo13 @hedger
/applications/u2f/ @skotopes @DrZlo13 @hedger @nminaylov
/applications/unit_tests/ @skotopes @DrZlo13 @hedger
/applications/updater/ @skotopes @DrZlo13 @hedger
# Applications # Assets
applications/** @skotopes @DrZlo13 /assets/ @skotopes @DrZlo13 @hedger
applications/accessor/** @skotopes @DrZlo13
applications/loader/** @skotopes @DrZlo13 @gornekich
applications/bt/** @skotopes @DrZlo13
applications/cli/** @skotopes @DrZlo13
applications/dolphin/** @skotopes @DrZlo13
applications/gpio-tester/** @skotopes @DrZlo13
applications/gui/** @skotopes @DrZlo13
applications/gui-test/** @skotopes @DrZlo13
applications/ibutton/** @skotopes @DrZlo13
applications/input/** @skotopes @DrZlo13
applications/infrared/** @skotopes @DrZlo13
applications/lf-rfid/** @skotopes @DrZlo13
applications/menu/** @skotopes @DrZlo13
applications/music-player/** @skotopes @DrZlo13
applications/nfc/** @skotopes @DrZlo13 @gornekich
applications/power/** @skotopes @DrZlo13
applications/sd-card-test/** @skotopes @DrZlo13
applications/sd-filesystem/** @skotopes @DrZlo13
applications/subghz/** @skotopes @DrZlo13
applications/template/** @skotopes @DrZlo13
applications/tests/** @skotopes @DrZlo13
applications/updater/** @skotopes @DrZlo13 @hedger
# Assets and asset generator # Furi Core
assets/** @skotopes @DrZlo13 /core/ @skotopes @DrZlo13 @hedger
# Bootloader # Debug tools and plugins
bootloader/** @skotopes @DrZlo13 /debug/ @skotopes @DrZlo13 @hedger
# Core, HAL and applocation loader # Docker
core/** @skotopes @DrZlo13 /docker/ @skotopes @DrZlo13 @hedger @aprosvetova
/docker-compose.yml @skotopes @DrZlo13 @hedger @aprosvetova
# Debug tools # Documentation
debug/** @skotopes @DrZlo13 /documentation/ @skotopes @DrZlo13 @hedger @aprosvetova
# Firmware # Firmware targets
firmware/** @skotopes @DrZlo13 /firmware/ @skotopes @DrZlo13 @hedger
# Lib # Lib
lib/app-template/** @skotopes @DrZlo13 /lib/FreeRTOS-Kernel/ @skotopes @DrZlo13 @hedger
lib/callback-connector/** @skotopes @DrZlo13 /lib/FreeRTOS-glue/ @skotopes @DrZlo13 @hedger
lib/common-api/** @skotopes @DrZlo13 /lib/ST25RFAL002/ @skotopes @DrZlo13 @hedger @gornekich
lib/cyfral/** @skotopes @DrZlo13 /lib/STM32CubeWB/ @skotopes @DrZlo13 @hedger @gornekich
lib/drivers/** @skotopes @DrZlo13 @gornekich /lib/app-scened-template/ @skotopes @DrZlo13 @hedger
lib/fatfs/** @skotopes @DrZlo13 /lib/callback-connector/ @skotopes @DrZlo13 @hedger
lib/fnv1a-hash/** @skotopes @DrZlo13 /lib/digital_signal/ @skotopes @DrZlo13 @hedger @gornekich
lib/littlefs/** @skotopes @DrZlo13 /lib/drivers/ @skotopes @DrZlo13 @hedger
lib/mlib/** @skotopes @DrZlo13 /lib/fatfs/ @skotopes @DrZlo13 @hedger
lib/onewire/** @skotopes @DrZlo13 /lib/flipper_format/ @skotopes @DrZlo13 @hedger
lib/qrcode/** @skotopes @DrZlo13 /lib/fnv1a-hash/ @skotopes @DrZlo13 @hedger
lib/ST25RFAL002/** @skotopes @DrZlo13 @gornekich /lib/heatshrink/ @skotopes @DrZlo13 @hedger
lib/STM32CubeWB/** @skotopes @DrZlo13 /lib/infrared/ @skotopes @DrZlo13 @hedger @gsurkov
lib/u8g2/** @skotopes @DrZlo13 /lib/libusb_stm32/ @skotopes @DrZlo13 @hedger @nminaylov
lib/version/** @skotopes @DrZlo13 /lib/littlefs/ @skotopes @DrZlo13 @hedger
/lib/lfs_config.h @skotopes @DrZlo13 @hedger
/lib/micro-ecc/ @skotopes @DrZlo13 @hedger @nminaylov
/lib/microtar/ @skotopes @DrZlo13 @hedger
/lib/mlib/ @skotopes @DrZlo13 @hedger
/lib/nanopb/ @skotopes @DrZlo13 @hedger
/lib/nfc_protocols/ @skotopes @DrZlo13 @hedger @gornekich
/lib/one_wire/ @skotopes @DrZlo13 @hedger
/lib/qrcode/ @skotopes @DrZlo13 @hedger
/lib/subghz/ @skotopes @DrZlo13 @hedger @Skorpionm
/lib/toolbox/ @skotopes @DrZlo13 @hedger
/lib/u8g2/ @skotopes @DrZlo13 @hedger
/lib/update_util/ @skotopes @DrZlo13 @hedger
# Make # Make tools
make/** @skotopes @DrZlo13 /make/ @skotopes @DrZlo13 @hedger @aprosvetova
# Helper scripts
/scripts/ @skotopes @DrZlo13 @hedger

View File

@ -152,7 +152,7 @@ jobs:
with: with:
issue-number: ${{ github.event.pull_request.number }} issue-number: ${{ github.event.pull_request.number }}
comment-author: 'github-actions[bot]' comment-author: 'github-actions[bot]'
body-includes: 'to flash the' body-includes: 'Install with web updater'
- name: 'Create or update comment' - name: 'Create or update comment'
if: ${{ !github.event.pull_request.head.repo.fork && github.event.pull_request}} if: ${{ !github.event.pull_request.head.repo.fork && github.event.pull_request}}
@ -161,7 +161,7 @@ jobs:
comment-id: ${{ steps.fc.outputs.comment-id }} comment-id: ${{ steps.fc.outputs.comment-id }}
issue-number: ${{ github.event.pull_request.number }} issue-number: ${{ github.event.pull_request.number }}
body: | body: |
[Install with web updater](https://my.flipp.dev/?url=https://update.flipperzero.one/builds/firmware/${{steps.names.outputs.artifacts-path}}/flipper-z-${{steps.names.outputs.default-target}}-update-${{steps.names.outputs.suffix}}.tgz&channel=${{steps.names.outputs.artifacts-path}}&version=${{steps.names.outputs.short-hash}}) [Install with web updater](https://my.flipp.dev/?url=https://update.flipperzero.one/builds/firmware/${{steps.names.outputs.artifacts-path}}/flipper-z-${{steps.names.outputs.default-target}}-update-${{steps.names.outputs.suffix}}.tgz&channel=${{steps.names.outputs.artifacts-path}}&version=${{steps.names.outputs.short-hash}}).
edit-mode: replace edit-mode: replace
compact: compact:

View File

@ -1,6 +1,7 @@
#include "nfc_debug_pcap.h" #include "nfc_debug_pcap.h"
#include <furi_hal_rtc.h> #include <furi_hal_rtc.h>
#include <stream_buffer.h>
#define TAG "NfcDebugPcap" #define TAG "NfcDebugPcap"
@ -14,9 +15,20 @@
#define DATA_PICC_TO_PCD_CRC_DROPPED 0xFB #define DATA_PICC_TO_PCD_CRC_DROPPED 0xFB
#define DATA_PCD_TO_PICC_CRC_DROPPED 0xFA #define DATA_PCD_TO_PICC_CRC_DROPPED 0xFA
File* nfc_debug_pcap_open(Storage* storage) { #define NFC_DEBUG_PCAP_FILENAME "/ext/nfc/debug.pcap"
#define NFC_DEBUG_PCAP_BUFFER_SIZE 64
struct NfcDebugPcapWorker {
bool alive;
Storage* storage;
File* file;
StreamBufferHandle_t stream;
FuriThread* thread;
};
static File* nfc_debug_pcap_open(Storage* storage) {
File* file = storage_file_alloc(storage); File* file = storage_file_alloc(storage);
if(!storage_file_open(file, "/ext/nfc/debug.pcap", FSAM_WRITE, FSOM_OPEN_APPEND)) { if(!storage_file_open(file, NFC_DEBUG_PCAP_FILENAME, FSAM_WRITE, FSOM_OPEN_APPEND)) {
storage_file_free(file); storage_file_free(file);
return NULL; return NULL;
} }
@ -41,10 +53,8 @@ File* nfc_debug_pcap_open(Storage* storage) {
return file; return file;
} }
void nfc_debug_pcap_write(Storage* storage, uint8_t event, uint8_t* data, uint16_t len) { static void
File* file = nfc_debug_pcap_open(storage); nfc_debug_pcap_write(NfcDebugPcapWorker* instance, uint8_t event, uint8_t* data, uint16_t len) {
if(!file) return;
FuriHalRtcDateTime datetime; FuriHalRtcDateTime datetime;
furi_hal_rtc_get_datetime(&datetime); furi_hal_rtc_get_datetime(&datetime);
@ -67,26 +77,83 @@ void nfc_debug_pcap_write(Storage* storage, uint8_t event, uint8_t* data, uint16
.event = event, .event = event,
.len = len << 8 | len >> 8, .len = len << 8 | len >> 8,
}; };
if(storage_file_write(file, &pkt_hdr, sizeof(pkt_hdr)) != sizeof(pkt_hdr)) { xStreamBufferSend(instance->stream, &pkt_hdr, sizeof(pkt_hdr), osWaitForever);
FURI_LOG_E(TAG, "Failed to write pcap packet header"); xStreamBufferSend(instance->stream, data, len, osWaitForever);
} else if(storage_file_write(file, data, len) != len) {
FURI_LOG_E(TAG, "Failed to write pcap packet data");
}
storage_file_free(file);
} }
void nfc_debug_pcap_write_tx(uint8_t* data, uint16_t bits, bool crc_dropped, void* context) { static void
nfc_debug_pcap_write_tx(uint8_t* data, uint16_t bits, bool crc_dropped, void* context) {
NfcDebugPcapWorker* instance = context;
uint8_t event = crc_dropped ? DATA_PCD_TO_PICC_CRC_DROPPED : DATA_PCD_TO_PICC; uint8_t event = crc_dropped ? DATA_PCD_TO_PICC_CRC_DROPPED : DATA_PCD_TO_PICC;
nfc_debug_pcap_write(context, event, data, bits / 8); nfc_debug_pcap_write(instance, event, data, bits / 8);
} }
void nfc_debug_pcap_write_rx(uint8_t* data, uint16_t bits, bool crc_dropped, void* context) { static void
nfc_debug_pcap_write_rx(uint8_t* data, uint16_t bits, bool crc_dropped, void* context) {
NfcDebugPcapWorker* instance = context;
uint8_t event = crc_dropped ? DATA_PICC_TO_PCD_CRC_DROPPED : DATA_PICC_TO_PCD; uint8_t event = crc_dropped ? DATA_PICC_TO_PCD_CRC_DROPPED : DATA_PICC_TO_PCD;
nfc_debug_pcap_write(context, event, data, bits / 8); nfc_debug_pcap_write(instance, event, data, bits / 8);
} }
void nfc_debug_pcap_prepare_tx_rx(FuriHalNfcTxRxContext* tx_rx, Storage* storage, bool is_picc) { int32_t nfc_debug_pcap_thread(void* context) {
if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) { NfcDebugPcapWorker* instance = context;
uint8_t buffer[NFC_DEBUG_PCAP_BUFFER_SIZE];
while(instance->alive) {
size_t ret =
xStreamBufferReceive(instance->stream, buffer, NFC_DEBUG_PCAP_BUFFER_SIZE, 50);
if(storage_file_write(instance->file, buffer, ret) != ret) {
FURI_LOG_E(TAG, "Failed to write pcap data");
}
}
return 0;
}
NfcDebugPcapWorker* nfc_debug_pcap_alloc(Storage* storage) {
NfcDebugPcapWorker* instance = malloc(sizeof(NfcDebugPcapWorker));
instance->alive = true;
instance->storage = storage;
instance->file = nfc_debug_pcap_open(storage);
instance->stream = xStreamBufferCreate(4096, 1);
instance->thread = furi_thread_alloc();
furi_thread_set_name(instance->thread, "PcapWorker");
furi_thread_set_stack_size(instance->thread, 1024);
furi_thread_set_callback(instance->thread, nfc_debug_pcap_thread);
furi_thread_set_context(instance->thread, instance);
furi_thread_start(instance->thread);
return instance;
}
void nfc_debug_pcap_free(NfcDebugPcapWorker* instance) {
furi_assert(instance);
instance->alive = false;
furi_thread_join(instance->thread);
furi_thread_free(instance->thread);
vStreamBufferDelete(instance->stream);
if(instance->file) storage_file_free(instance->file);
instance->storage = NULL;
free(instance);
}
void nfc_debug_pcap_prepare_tx_rx(
NfcDebugPcapWorker* instance,
FuriHalNfcTxRxContext* tx_rx,
bool is_picc) {
if(!instance || !instance->file) return;
if(is_picc) { if(is_picc) {
tx_rx->sniff_tx = nfc_debug_pcap_write_rx; tx_rx->sniff_tx = nfc_debug_pcap_write_rx;
tx_rx->sniff_rx = nfc_debug_pcap_write_tx; tx_rx->sniff_rx = nfc_debug_pcap_write_tx;
@ -94,6 +161,6 @@ void nfc_debug_pcap_prepare_tx_rx(FuriHalNfcTxRxContext* tx_rx, Storage* storage
tx_rx->sniff_tx = nfc_debug_pcap_write_tx; tx_rx->sniff_tx = nfc_debug_pcap_write_tx;
tx_rx->sniff_rx = nfc_debug_pcap_write_rx; tx_rx->sniff_rx = nfc_debug_pcap_write_rx;
} }
tx_rx->sniff_context = storage;
} tx_rx->sniff_context = instance;
} }

View File

@ -3,10 +3,19 @@
#include <furi_hal_nfc.h> #include <furi_hal_nfc.h>
#include <storage/storage.h> #include <storage/storage.h>
typedef struct NfcDebugPcapWorker NfcDebugPcapWorker;
NfcDebugPcapWorker* nfc_debug_pcap_alloc(Storage* storage);
void nfc_debug_pcap_free(NfcDebugPcapWorker* instance);
/** Prepare tx/rx context for debug pcap logging, if enabled. /** Prepare tx/rx context for debug pcap logging, if enabled.
* *
* @param instance NfcDebugPcapWorker* instance, can be NULL
* @param tx_rx TX/RX context to log * @param tx_rx TX/RX context to log
* @param storage Storage to log to
* @param is_picc if true, record Flipper as PICC, else PCD. * @param is_picc if true, record Flipper as PICC, else PCD.
*/ */
void nfc_debug_pcap_prepare_tx_rx(FuriHalNfcTxRxContext* tx_rx, Storage* storage, bool is_picc); void nfc_debug_pcap_prepare_tx_rx(
NfcDebugPcapWorker* instance,
FuriHalNfcTxRxContext* tx_rx,
bool is_picc);

View File

@ -1,17 +1,6 @@
#include "nfc_worker_i.h" #include "nfc_worker_i.h"
#include <furi_hal.h> #include <furi_hal.h>
#include <lib/nfc_protocols/nfc_util.h>
#include <lib/nfc_protocols/emv.h>
#include <lib/nfc_protocols/mifare_common.h>
#include <lib/nfc_protocols/mifare_ultralight.h>
#include <lib/nfc_protocols/mifare_classic.h>
#include <lib/nfc_protocols/mifare_desfire.h>
#include <lib/nfc_protocols/nfca.h>
#include "helpers/nfc_mf_classic_dict.h"
#include "helpers/nfc_debug_pcap.h"
#define TAG "NfcWorker" #define TAG "NfcWorker"
/***************************** NFC Worker API *******************************/ /***************************** NFC Worker API *******************************/
@ -36,13 +25,22 @@ NfcWorker* nfc_worker_alloc() {
} }
nfc_worker_change_state(nfc_worker, NfcWorkerStateReady); nfc_worker_change_state(nfc_worker, NfcWorkerStateReady);
if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) {
nfc_worker->debug_pcap_worker = nfc_debug_pcap_alloc(nfc_worker->storage);
}
return nfc_worker; return nfc_worker;
} }
void nfc_worker_free(NfcWorker* nfc_worker) { void nfc_worker_free(NfcWorker* nfc_worker) {
furi_assert(nfc_worker); furi_assert(nfc_worker);
furi_thread_free(nfc_worker->thread); furi_thread_free(nfc_worker->thread);
furi_record_close("storage"); furi_record_close("storage");
if(nfc_worker->debug_pcap_worker) nfc_debug_pcap_free(nfc_worker->debug_pcap_worker);
free(nfc_worker); free(nfc_worker);
} }
@ -154,7 +152,7 @@ void nfc_worker_detect(NfcWorker* nfc_worker) {
void nfc_worker_emulate(NfcWorker* nfc_worker) { void nfc_worker_emulate(NfcWorker* nfc_worker) {
FuriHalNfcTxRxContext tx_rx = {}; FuriHalNfcTxRxContext tx_rx = {};
nfc_debug_pcap_prepare_tx_rx(&tx_rx, nfc_worker->storage, true); nfc_debug_pcap_prepare_tx_rx(nfc_worker->debug_pcap_worker, &tx_rx, true);
FuriHalNfcDevData* data = &nfc_worker->dev_data->nfc_data; FuriHalNfcDevData* data = &nfc_worker->dev_data->nfc_data;
NfcReaderRequestData* reader_data = &nfc_worker->dev_data->reader_data; NfcReaderRequestData* reader_data = &nfc_worker->dev_data->reader_data;
@ -177,7 +175,7 @@ void nfc_worker_emulate(NfcWorker* nfc_worker) {
void nfc_worker_read_emv_app(NfcWorker* nfc_worker) { void nfc_worker_read_emv_app(NfcWorker* nfc_worker) {
FuriHalNfcTxRxContext tx_rx = {}; FuriHalNfcTxRxContext tx_rx = {};
nfc_debug_pcap_prepare_tx_rx(&tx_rx, nfc_worker->storage, false); nfc_debug_pcap_prepare_tx_rx(nfc_worker->debug_pcap_worker, &tx_rx, false);
EmvApplication emv_app = {}; EmvApplication emv_app = {};
NfcDeviceData* result = nfc_worker->dev_data; NfcDeviceData* result = nfc_worker->dev_data;
FuriHalNfcDevData* nfc_data = &nfc_worker->dev_data->nfc_data; FuriHalNfcDevData* nfc_data = &nfc_worker->dev_data->nfc_data;
@ -209,7 +207,7 @@ void nfc_worker_read_emv_app(NfcWorker* nfc_worker) {
void nfc_worker_read_emv(NfcWorker* nfc_worker) { void nfc_worker_read_emv(NfcWorker* nfc_worker) {
FuriHalNfcTxRxContext tx_rx = {}; FuriHalNfcTxRxContext tx_rx = {};
nfc_debug_pcap_prepare_tx_rx(&tx_rx, nfc_worker->storage, false); nfc_debug_pcap_prepare_tx_rx(nfc_worker->debug_pcap_worker, &tx_rx, false);
EmvApplication emv_app = {}; EmvApplication emv_app = {};
NfcDeviceData* result = nfc_worker->dev_data; NfcDeviceData* result = nfc_worker->dev_data;
FuriHalNfcDevData* nfc_data = &nfc_worker->dev_data->nfc_data; FuriHalNfcDevData* nfc_data = &nfc_worker->dev_data->nfc_data;
@ -258,7 +256,7 @@ void nfc_worker_read_emv(NfcWorker* nfc_worker) {
void nfc_worker_emulate_apdu(NfcWorker* nfc_worker) { void nfc_worker_emulate_apdu(NfcWorker* nfc_worker) {
FuriHalNfcTxRxContext tx_rx = {}; FuriHalNfcTxRxContext tx_rx = {};
nfc_debug_pcap_prepare_tx_rx(&tx_rx, nfc_worker->storage, true); nfc_debug_pcap_prepare_tx_rx(nfc_worker->debug_pcap_worker, &tx_rx, true);
FuriHalNfcDevData params = { FuriHalNfcDevData params = {
.uid = {0xCF, 0x72, 0xd4, 0x40}, .uid = {0xCF, 0x72, 0xd4, 0x40},
.uid_len = 4, .uid_len = 4,
@ -283,7 +281,7 @@ void nfc_worker_emulate_apdu(NfcWorker* nfc_worker) {
void nfc_worker_read_mifare_ultralight(NfcWorker* nfc_worker) { void nfc_worker_read_mifare_ultralight(NfcWorker* nfc_worker) {
FuriHalNfcTxRxContext tx_rx = {}; FuriHalNfcTxRxContext tx_rx = {};
nfc_debug_pcap_prepare_tx_rx(&tx_rx, nfc_worker->storage, false); nfc_debug_pcap_prepare_tx_rx(nfc_worker->debug_pcap_worker, &tx_rx, false);
MfUltralightReader reader = {}; MfUltralightReader reader = {};
MfUltralightData data = {}; MfUltralightData data = {};
NfcDeviceData* result = nfc_worker->dev_data; NfcDeviceData* result = nfc_worker->dev_data;
@ -348,7 +346,7 @@ void nfc_worker_emulate_mifare_ul(NfcWorker* nfc_worker) {
void nfc_worker_mifare_classic_dict_attack(NfcWorker* nfc_worker) { void nfc_worker_mifare_classic_dict_attack(NfcWorker* nfc_worker) {
furi_assert(nfc_worker->callback); furi_assert(nfc_worker->callback);
FuriHalNfcTxRxContext tx_rx_ctx = {}; FuriHalNfcTxRxContext tx_rx_ctx = {};
nfc_debug_pcap_prepare_tx_rx(&tx_rx_ctx, nfc_worker->storage, false); nfc_debug_pcap_prepare_tx_rx(nfc_worker->debug_pcap_worker, &tx_rx_ctx, false);
MfClassicAuthContext auth_ctx = {}; MfClassicAuthContext auth_ctx = {};
MfClassicReader reader = {}; MfClassicReader reader = {};
uint64_t curr_key = 0; uint64_t curr_key = 0;
@ -491,6 +489,7 @@ void nfc_worker_mifare_classic_dict_attack(NfcWorker* nfc_worker) {
void nfc_worker_emulate_mifare_classic(NfcWorker* nfc_worker) { void nfc_worker_emulate_mifare_classic(NfcWorker* nfc_worker) {
FuriHalNfcTxRxContext tx_rx = {}; FuriHalNfcTxRxContext tx_rx = {};
nfc_debug_pcap_prepare_tx_rx(nfc_worker->debug_pcap_worker, &tx_rx, true);
FuriHalNfcDevData* nfc_data = &nfc_worker->dev_data->nfc_data; FuriHalNfcDevData* nfc_data = &nfc_worker->dev_data->nfc_data;
MfClassicEmulator emulator = { MfClassicEmulator emulator = {
.cuid = nfc_util_bytes2num(&nfc_data->uid[nfc_data->uid_len - 4], 4), .cuid = nfc_util_bytes2num(&nfc_data->uid[nfc_data->uid_len - 4], 4),
@ -519,7 +518,7 @@ void nfc_worker_emulate_mifare_classic(NfcWorker* nfc_worker) {
void nfc_worker_read_mifare_desfire(NfcWorker* nfc_worker) { void nfc_worker_read_mifare_desfire(NfcWorker* nfc_worker) {
FuriHalNfcTxRxContext tx_rx = {}; FuriHalNfcTxRxContext tx_rx = {};
nfc_debug_pcap_prepare_tx_rx(&tx_rx, nfc_worker->storage, false); nfc_debug_pcap_prepare_tx_rx(nfc_worker->debug_pcap_worker, &tx_rx, false);
NfcDeviceData* result = nfc_worker->dev_data; NfcDeviceData* result = nfc_worker->dev_data;
nfc_device_data_clear(result); nfc_device_data_clear(result);
MifareDesfireData* data = &result->mf_df_data; MifareDesfireData* data = &result->mf_df_data;

15
applications/nfc/nfc_worker_i.h Executable file → Normal file
View File

@ -1,11 +1,22 @@
#pragma once #pragma once
#include "nfc_i.h"
#include "nfc_worker.h" #include "nfc_worker.h"
#include "nfc_i.h"
#include <furi.h> #include <furi.h>
#include <lib/toolbox/stream/file_stream.h> #include <lib/toolbox/stream/file_stream.h>
#include <lib/nfc_protocols/nfc_util.h>
#include <lib/nfc_protocols/emv.h>
#include <lib/nfc_protocols/mifare_common.h>
#include <lib/nfc_protocols/mifare_ultralight.h>
#include <lib/nfc_protocols/mifare_classic.h>
#include <lib/nfc_protocols/mifare_desfire.h>
#include <lib/nfc_protocols/nfca.h>
#include "helpers/nfc_mf_classic_dict.h"
#include "helpers/nfc_debug_pcap.h"
struct NfcWorker { struct NfcWorker {
FuriThread* thread; FuriThread* thread;
Storage* storage; Storage* storage;
@ -17,6 +28,8 @@ struct NfcWorker {
void* context; void* context;
NfcWorkerState state; NfcWorkerState state;
NfcDebugPcapWorker* debug_pcap_worker;
}; };
void nfc_worker_change_state(NfcWorker* nfc_worker, NfcWorkerState state); void nfc_worker_change_state(NfcWorker* nfc_worker, NfcWorkerState state);

View File

@ -134,6 +134,10 @@ bool storage_file_close(File* file) {
} }
uint16_t storage_file_read(File* file, void* buff, uint16_t bytes_to_read) { uint16_t storage_file_read(File* file, void* buff, uint16_t bytes_to_read) {
if(bytes_to_read == 0) {
return 0;
}
S_FILE_API_PROLOGUE; S_FILE_API_PROLOGUE;
S_API_PROLOGUE; S_API_PROLOGUE;
@ -150,6 +154,10 @@ uint16_t storage_file_read(File* file, void* buff, uint16_t bytes_to_read) {
} }
uint16_t storage_file_write(File* file, const void* buff, uint16_t bytes_to_write) { uint16_t storage_file_write(File* file, const void* buff, uint16_t bytes_to_write) {
if(bytes_to_write == 0) {
return 0;
}
S_FILE_API_PROLOGUE; S_FILE_API_PROLOGUE;
S_API_PROLOGUE; S_API_PROLOGUE;

View File

@ -200,8 +200,6 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) {
} }
if((subghz->txrx->txrx_state == SubGhzTxRxStateIDLE) || if((subghz->txrx->txrx_state == SubGhzTxRxStateIDLE) ||
(subghz->txrx->txrx_state == SubGhzTxRxStateSleep)) { (subghz->txrx->txrx_state == SubGhzTxRxStateSleep)) {
//ToDo FIX
if(!subghz_tx_start(subghz, subghz->txrx->fff_data)) { if(!subghz_tx_start(subghz, subghz->txrx->fff_data)) {
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowOnlyRx); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowOnlyRx);
} else { } else {

View File

@ -39,12 +39,12 @@ void subghz_scene_save_name_on_enter(void* context) {
path_extract_filename(subghz->file_path, file_name, true); path_extract_filename(subghz->file_path, file_name, true);
if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneReadRAW) != if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneReadRAW) !=
SubGhzCustomEventManagerNoSet) { SubGhzCustomEventManagerNoSet) {
subghz_get_next_name_file(subghz, SUBGHZ_MAX_LEN_NAME);
path_extract_filename(subghz->file_path, file_name, true);
if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneReadRAW) == if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneReadRAW) ==
SubGhzCustomEventManagerSetRAW) { SubGhzCustomEventManagerSetRAW) {
dev_name_empty = true; dev_name_empty = true;
subghz_get_next_name_file(subghz, SUBGHZ_MAX_LEN_NAME);
} }
path_extract_filename(subghz->file_path, file_name, true);
} }
string_set(subghz->file_path, dir_name); string_set(subghz->file_path, dir_name);
} }
@ -72,7 +72,11 @@ void subghz_scene_save_name_on_enter(void* context) {
bool subghz_scene_save_name_on_event(void* context, SceneManagerEvent event) { bool subghz_scene_save_name_on_event(void* context, SceneManagerEvent event) {
SubGhz* subghz = context; SubGhz* subghz = context;
if(event.type == SceneManagerEventTypeBack) { if(event.type == SceneManagerEventTypeBack) {
if(!strcmp(subghz->file_name_tmp, "") ||
scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneReadRAW) !=
SubGhzCustomEventManagerNoSet) {
string_set(subghz->file_path, subghz->file_path_tmp); string_set(subghz->file_path, subghz->file_path_tmp);
}
scene_manager_previous_scene(subghz->scene_manager); scene_manager_previous_scene(subghz->scene_manager);
return true; return true;
} else if(event.type == SceneManagerEventTypeCustom) { } else if(event.type == SceneManagerEventTypeCustom) {

View File

@ -1,5 +1,5 @@
V:0 V:0
T:1654009290 T:1655152832
D:badusb D:badusb
D:dolphin D:dolphin
D:infrared D:infrared
@ -7,7 +7,7 @@ D:music_player
D:nfc D:nfc
D:subghz D:subghz
D:u2f D:u2f
F:bb8ffef2d052f171760ce3dc5220cbad:1591:badusb/demo_macos.txt F:0e41ba26498b7511d7c9e6e6b5e3b149:1592:badusb/demo_macos.txt
F:e538ad2ce5a06ec45e1b5b24824901b1:1552:badusb/demo_windows.txt F:e538ad2ce5a06ec45e1b5b24824901b1:1552:badusb/demo_windows.txt
D:dolphin/L1_Boxing_128x64 D:dolphin/L1_Boxing_128x64
D:dolphin/L1_Cry_128x64 D:dolphin/L1_Cry_128x64

View File

@ -13,7 +13,7 @@ DELAY 500
ENTER ENTER
DELAY 750 DELAY 750
REM Copy-Paste previuos string REM Copy-Paste previous string
UP UP
CTRL c CTRL c
@ -77,7 +77,7 @@ ENTER
STRING Flipper Zero BadUSB feature is compatible with USB Rubber Ducky script format STRING Flipper Zero BadUSB feature is compatible with USB Rubber Ducky script format
ENTER ENTER
STRING More information about script synax can be found here: STRING More information about script syntax can be found here:
ENTER ENTER
STRING https://github.com/hak5darren/USB-Rubber-Ducky/wiki/Duckyscript STRING https://github.com/hak5darren/USB-Rubber-Ducky/wiki/Duckyscript
ENTER ENTER

View File

@ -392,6 +392,10 @@ static bool furi_hal_nfc_transparent_tx_rx(FuriHalNfcTxRxContext* tx_rx, uint16_
furi_hal_spi_bus_handle_init(&furi_hal_spi_bus_handle_nfc); furi_hal_spi_bus_handle_init(&furi_hal_spi_bus_handle_nfc);
st25r3916ExecuteCommand(ST25R3916_CMD_UNMASK_RECEIVE_DATA); st25r3916ExecuteCommand(ST25R3916_CMD_UNMASK_RECEIVE_DATA);
if(tx_rx->sniff_tx) {
tx_rx->sniff_tx(tx_rx->tx_data, tx_rx->tx_bits, false, tx_rx->sniff_context);
}
// Manually wait for interrupt // Manually wait for interrupt
furi_hal_gpio_init(&gpio_rfid_pull, GpioModeInput, GpioPullDown, GpioSpeedVeryHigh); furi_hal_gpio_init(&gpio_rfid_pull, GpioModeInput, GpioPullDown, GpioSpeedVeryHigh);
st25r3916ClearAndEnableInterrupts(ST25R3916_IRQ_MASK_RXE); st25r3916ClearAndEnableInterrupts(ST25R3916_IRQ_MASK_RXE);
@ -428,6 +432,10 @@ static bool furi_hal_nfc_transparent_tx_rx(FuriHalNfcTxRxContext* tx_rx, uint16_
tx_rx->rx_bits = len * 8; tx_rx->rx_bits = len * 8;
memcpy(tx_rx->rx_data, rx, len); memcpy(tx_rx->rx_data, rx, len);
if(tx_rx->sniff_rx) {
tx_rx->sniff_rx(tx_rx->rx_data, tx_rx->rx_bits, false, tx_rx->sniff_context);
}
ret = true; ret = true;
} else { } else {
FURI_LOG_E(TAG, "Timeout error"); FURI_LOG_E(TAG, "Timeout error");

View File

@ -1,7 +1,8 @@
#include "furi_hal_subghz.h" #include "furi_hal_subghz.h"
#include "furi_hal_version.h" #include "furi_hal_subghz_configs.h"
#include "furi_hal_rtc.h"
#include <furi_hal_version.h>
#include <furi_hal_rtc.h>
#include <furi_hal_gpio.h> #include <furi_hal_gpio.h>
#include <furi_hal_spi.h> #include <furi_hal_spi.h>
#include <furi_hal_interrupt.h> #include <furi_hal_interrupt.h>
@ -15,317 +16,22 @@
#define TAG "FuriHalSubGhz" #define TAG "FuriHalSubGhz"
static volatile SubGhzState furi_hal_subghz_state = SubGhzStateInit; typedef struct {
static volatile SubGhzRegulation furi_hal_subghz_regulation = SubGhzRegulationTxRx; volatile SubGhzState state;
static volatile FuriHalSubGhzPreset furi_hal_subghz_preset = FuriHalSubGhzPresetIDLE; volatile SubGhzRegulation regulation;
volatile FuriHalSubGhzPreset preset;
} FuriHalSubGhz;
static const uint8_t furi_hal_subghz_preset_ook_270khz_async_regs[][2] = { volatile FuriHalSubGhz furi_hal_subghz = {
// https://e2e.ti.com/support/wireless-connectivity/sub-1-ghz-group/sub-1-ghz/f/sub-1-ghz-forum/382066/cc1101---don-t-know-the-correct-registers-configuration .state = SubGhzStateInit,
.regulation = SubGhzRegulationTxRx,
/* GPIO GD0 */ .preset = FuriHalSubGhzPresetIDLE,
{CC1101_IOCFG0, 0x0D}, // GD0 as async serial data output/input
/* FIFO and internals */
{CC1101_FIFOTHR, 0x47}, // The only important bit is ADC_RETENTION, FIFO Tx=33 Rx=32
/* Packet engine */
{CC1101_PKTCTRL0, 0x32}, // Async, continious, no whitening
/* Frequency Synthesizer Control */
{CC1101_FSCTRL1, 0x06}, // IF = (26*10^6) / (2^10) * 0x06 = 152343.75Hz
// Modem Configuration
{CC1101_MDMCFG0, 0x00}, // Channel spacing is 25kHz
{CC1101_MDMCFG1, 0x00}, // Channel spacing is 25kHz
{CC1101_MDMCFG2, 0x30}, // Format ASK/OOK, No preamble/sync
{CC1101_MDMCFG3, 0x32}, // Data rate is 3.79372 kBaud
{CC1101_MDMCFG4, 0x67}, // Rx BW filter is 270.833333kHz
/* Main Radio Control State Machine */
{CC1101_MCSM0, 0x18}, // Autocalibrate on idle-to-rx/tx, PO_TIMEOUT is 64 cycles(149-155us)
/* Frequency Offset Compensation Configuration */
{CC1101_FOCCFG,
0x18}, // no frequency offset compensation, POST_K same as PRE_K, PRE_K is 4K, GATE is off
/* Automatic Gain Control */
{CC1101_AGCCTRL0,
0x40}, // 01 - Low hysteresis, small asymmetric dead zone, medium gain; 00 - 8 samples agc; 00 - Normal AGC, 00 - 4dB boundary
{CC1101_AGCCTRL1,
0x00}, // 0; 0 - LNA 2 gain is decreased to minimum before decreasing LNA gain; 00 - Relative carrier sense threshold disabled; 0000 - RSSI to MAIN_TARGET
{CC1101_AGCCTRL2, 0x03}, // 00 - DVGA all; 000 - MAX LNA+LNA2; 011 - MAIN_TARGET 24 dB
/* Wake on radio and timeouts control */
{CC1101_WORCTRL, 0xFB}, // WOR_RES is 2^15 periods (0.91 - 0.94 s) 16.5 - 17.2 hours
/* Frontend configuration */
{CC1101_FREND0, 0x11}, // Adjusts current TX LO buffer + high is PATABLE[1]
{CC1101_FREND1, 0xB6}, //
/* End */
{0, 0},
}; };
static const uint8_t furi_hal_subghz_preset_ook_650khz_async_regs[][2] = {
// https://e2e.ti.com/support/wireless-connectivity/sub-1-ghz-group/sub-1-ghz/f/sub-1-ghz-forum/382066/cc1101---don-t-know-the-correct-registers-configuration
/* GPIO GD0 */
{CC1101_IOCFG0, 0x0D}, // GD0 as async serial data output/input
/* FIFO and internals */
{CC1101_FIFOTHR, 0x07}, // The only important bit is ADC_RETENTION
/* Packet engine */
{CC1101_PKTCTRL0, 0x32}, // Async, continious, no whitening
/* Frequency Synthesizer Control */
{CC1101_FSCTRL1, 0x06}, // IF = (26*10^6) / (2^10) * 0x06 = 152343.75Hz
// Modem Configuration
{CC1101_MDMCFG0, 0x00}, // Channel spacing is 25kHz
{CC1101_MDMCFG1, 0x00}, // Channel spacing is 25kHz
{CC1101_MDMCFG2, 0x30}, // Format ASK/OOK, No preamble/sync
{CC1101_MDMCFG3, 0x32}, // Data rate is 3.79372 kBaud
{CC1101_MDMCFG4, 0x17}, // Rx BW filter is 650.000kHz
/* Main Radio Control State Machine */
{CC1101_MCSM0, 0x18}, // Autocalibrate on idle-to-rx/tx, PO_TIMEOUT is 64 cycles(149-155us)
/* Frequency Offset Compensation Configuration */
{CC1101_FOCCFG,
0x18}, // no frequency offset compensation, POST_K same as PRE_K, PRE_K is 4K, GATE is off
/* Automatic Gain Control */
// {CC1101_AGCTRL0,0x40}, // 01 - Low hysteresis, small asymmetric dead zone, medium gain; 00 - 8 samples agc; 00 - Normal AGC, 00 - 4dB boundary
// {CC1101_AGCTRL1,0x00}, // 0; 0 - LNA 2 gain is decreased to minimum before decreasing LNA gain; 00 - Relative carrier sense threshold disabled; 0000 - RSSI to MAIN_TARGET
// {CC1101_AGCCTRL2, 0x03}, // 00 - DVGA all; 000 - MAX LNA+LNA2; 011 - MAIN_TARGET 24 dB
//MAGN_TARGET for RX filter BW =< 100 kHz is 0x3. For higher RX filter BW's MAGN_TARGET is 0x7.
{CC1101_AGCCTRL0,
0x91}, // 10 - Medium hysteresis, medium asymmetric dead zone, medium gain ; 01 - 16 samples agc; 00 - Normal AGC, 01 - 8dB boundary
{CC1101_AGCCTRL1,
0x0}, // 0; 0 - LNA 2 gain is decreased to minimum before decreasing LNA gain; 00 - Relative carrier sense threshold disabled; 0000 - RSSI to MAIN_TARGET
{CC1101_AGCCTRL2, 0x07}, // 00 - DVGA all; 000 - MAX LNA+LNA2; 111 - MAIN_TARGET 42 dB
/* Wake on radio and timeouts control */
{CC1101_WORCTRL, 0xFB}, // WOR_RES is 2^15 periods (0.91 - 0.94 s) 16.5 - 17.2 hours
/* Frontend configuration */
{CC1101_FREND0, 0x11}, // Adjusts current TX LO buffer + high is PATABLE[1]
{CC1101_FREND1, 0xB6}, //
/* End */
{0, 0},
};
static const uint8_t furi_hal_subghz_preset_2fsk_dev2_38khz_async_regs[][2] = {
/* GPIO GD0 */
{CC1101_IOCFG0, 0x0D}, // GD0 as async serial data output/input
/* Frequency Synthesizer Control */
{CC1101_FSCTRL1, 0x06}, // IF = (26*10^6) / (2^10) * 0x06 = 152343.75Hz
/* Packet engine */
{CC1101_PKTCTRL0, 0x32}, // Async, continious, no whitening
{CC1101_PKTCTRL1, 0x04},
// // Modem Configuration
{CC1101_MDMCFG0, 0x00},
{CC1101_MDMCFG1, 0x02},
{CC1101_MDMCFG2, 0x04}, // Format 2-FSK/FM, No preamble/sync, Disable (current optimized)
{CC1101_MDMCFG3, 0x83}, // Data rate is 4.79794 kBaud
{CC1101_MDMCFG4, 0x67}, //Rx BW filter is 270.833333 kHz
{CC1101_DEVIATN, 0x04}, //Deviation 2.380371 kHz
/* Main Radio Control State Machine */
{CC1101_MCSM0, 0x18}, // Autocalibrate on idle-to-rx/tx, PO_TIMEOUT is 64 cycles(149-155us)
/* Frequency Offset Compensation Configuration */
{CC1101_FOCCFG,
0x16}, // no frequency offset compensation, POST_K same as PRE_K, PRE_K is 4K, GATE is off
/* Automatic Gain Control */
{CC1101_AGCCTRL0,
0x91}, //10 - Medium hysteresis, medium asymmetric dead zone, medium gain ; 01 - 16 samples agc; 00 - Normal AGC, 01 - 8dB boundary
{CC1101_AGCCTRL1,
0x00}, // 0; 0 - LNA 2 gain is decreased to minimum before decreasing LNA gain; 00 - Relative carrier sense threshold disabled; 0000 - RSSI to MAIN_TARGET
{CC1101_AGCCTRL2, 0x07}, // 00 - DVGA all; 000 - MAX LNA+LNA2; 111 - MAIN_TARGET 42 dB
/* Wake on radio and timeouts control */
{CC1101_WORCTRL, 0xFB}, // WOR_RES is 2^15 periods (0.91 - 0.94 s) 16.5 - 17.2 hours
/* Frontend configuration */
{CC1101_FREND0, 0x10}, // Adjusts current TX LO buffer
{CC1101_FREND1, 0x56},
/* End */
{0, 0},
};
static const uint8_t furi_hal_subghz_preset_2fsk_dev47_6khz_async_regs[][2] = {
/* GPIO GD0 */
{CC1101_IOCFG0, 0x0D}, // GD0 as async serial data output/input
/* Frequency Synthesizer Control */
{CC1101_FSCTRL1, 0x06}, // IF = (26*10^6) / (2^10) * 0x06 = 152343.75Hz
/* Packet engine */
{CC1101_PKTCTRL0, 0x32}, // Async, continious, no whitening
{CC1101_PKTCTRL1, 0x04},
// // Modem Configuration
{CC1101_MDMCFG0, 0x00},
{CC1101_MDMCFG1, 0x02},
{CC1101_MDMCFG2, 0x04}, // Format 2-FSK/FM, No preamble/sync, Disable (current optimized)
{CC1101_MDMCFG3, 0x83}, // Data rate is 4.79794 kBaud
{CC1101_MDMCFG4, 0x67}, //Rx BW filter is 270.833333 kHz
{CC1101_DEVIATN, 0x47}, //Deviation 47.60742 kHz
/* Main Radio Control State Machine */
{CC1101_MCSM0, 0x18}, // Autocalibrate on idle-to-rx/tx, PO_TIMEOUT is 64 cycles(149-155us)
/* Frequency Offset Compensation Configuration */
{CC1101_FOCCFG,
0x16}, // no frequency offset compensation, POST_K same as PRE_K, PRE_K is 4K, GATE is off
/* Automatic Gain Control */
{CC1101_AGCCTRL0,
0x91}, //10 - Medium hysteresis, medium asymmetric dead zone, medium gain ; 01 - 16 samples agc; 00 - Normal AGC, 01 - 8dB boundary
{CC1101_AGCCTRL1,
0x00}, // 0; 0 - LNA 2 gain is decreased to minimum before decreasing LNA gain; 00 - Relative carrier sense threshold disabled; 0000 - RSSI to MAIN_TARGET
{CC1101_AGCCTRL2, 0x07}, // 00 - DVGA all; 000 - MAX LNA+LNA2; 111 - MAIN_TARGET 42 dB
/* Wake on radio and timeouts control */
{CC1101_WORCTRL, 0xFB}, // WOR_RES is 2^15 periods (0.91 - 0.94 s) 16.5 - 17.2 hours
/* Frontend configuration */
{CC1101_FREND0, 0x10}, // Adjusts current TX LO buffer
{CC1101_FREND1, 0x56},
/* End */
{0, 0},
};
static const uint8_t furi_hal_subghz_preset_msk_99_97kb_async_regs[][2] = {
/* GPIO GD0 */
{CC1101_IOCFG0, 0x06},
{CC1101_FIFOTHR, 0x07}, // The only important bit is ADC_RETENTION
{CC1101_SYNC1, 0x46},
{CC1101_SYNC0, 0x4C},
{CC1101_ADDR, 0x00},
{CC1101_PKTLEN, 0x00},
{CC1101_CHANNR, 0x00},
{CC1101_PKTCTRL0, 0x05},
{CC1101_FSCTRL0, 0x23},
{CC1101_FSCTRL1, 0x06},
{CC1101_MDMCFG0, 0xF8},
{CC1101_MDMCFG1, 0x22},
{CC1101_MDMCFG2, 0x72},
{CC1101_MDMCFG3, 0xF8},
{CC1101_MDMCFG4, 0x5B},
{CC1101_DEVIATN, 0x47},
{CC1101_MCSM0, 0x18},
{CC1101_FOCCFG, 0x16},
{CC1101_AGCCTRL0, 0xB2},
{CC1101_AGCCTRL1, 0x00},
{CC1101_AGCCTRL2, 0xC7},
{CC1101_FREND0, 0x10},
{CC1101_FREND1, 0x56},
{CC1101_BSCFG, 0x1C},
{CC1101_FSTEST, 0x59},
/* End */
{0, 0},
};
static const uint8_t furi_hal_subghz_preset_gfsk_9_99kb_async_regs[][2] = {
{CC1101_IOCFG0, 0x06}, //GDO0 Output Pin Configuration
{CC1101_FIFOTHR, 0x47}, //RX FIFO and TX FIFO Thresholds
//1 : CRC calculation in TX and CRC check in RX enabled,
//1 : Variable packet length mode. Packet length configured by the first byte after sync word
{CC1101_PKTCTRL0, 0x05},
{CC1101_FSCTRL1, 0x06}, //Frequency Synthesizer Control
{CC1101_SYNC1, 0x46},
{CC1101_SYNC0, 0x4C},
{CC1101_ADDR, 0x00},
{CC1101_PKTLEN, 0x00},
{CC1101_MDMCFG4, 0xC8}, //Modem Configuration 9.99
{CC1101_MDMCFG3, 0x93}, //Modem Configuration
{CC1101_MDMCFG2, 0x12}, // 2: 16/16 sync word bits detected
{CC1101_DEVIATN, 0x34}, //Deviation = 19.042969
{CC1101_MCSM0, 0x18}, //Main Radio Control State Machine Configuration
{CC1101_FOCCFG, 0x16}, //Frequency Offset Compensation Configuration
{CC1101_AGCCTRL2, 0x43}, //AGC Control
{CC1101_AGCCTRL1, 0x40},
{CC1101_AGCCTRL0, 0x91},
{CC1101_WORCTRL, 0xFB}, //Wake On Radio Control
/* End */
{0, 0},
};
static const uint8_t furi_hal_subghz_preset_ook_async_patable[8] = {
0x00,
0xC0, // 12dBm 0xC0, 10dBm 0xC5, 7dBm 0xCD, 5dBm 0x86, 0dBm 0x50, -6dBm 0x37, -10dBm 0x26, -15dBm 0x1D, -20dBm 0x17, -30dBm 0x03
0x00,
0x00,
0x00,
0x00,
0x00,
0x00};
static const uint8_t furi_hal_subghz_preset_ook_async_patable_au[8] = {
0x00,
0x37, // 12dBm 0xC0, 10dBm 0xC5, 7dBm 0xCD, 5dBm 0x86, 0dBm 0x50, -6dBm 0x37, -10dBm 0x26, -15dBm 0x1D, -20dBm 0x17, -30dBm 0x03
0x00,
0x00,
0x00,
0x00,
0x00,
0x00};
static const uint8_t furi_hal_subghz_preset_2fsk_async_patable[8] = {
0xC0, // 10dBm 0xC0, 7dBm 0xC8, 5dBm 0x84, 0dBm 0x60, -10dBm 0x34, -15dBm 0x1D, -20dBm 0x0E, -30dBm 0x12
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00};
static const uint8_t furi_hal_subghz_preset_msk_async_patable[8] = {
0xC0, // 10dBm 0xC0, 7dBm 0xC8, 5dBm 0x84, 0dBm 0x60, -10dBm 0x34, -15dBm 0x1D, -20dBm 0x0E, -30dBm 0x12
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00};
static const uint8_t furi_hal_subghz_preset_gfsk_async_patable[8] = {
0xC0, // 10dBm 0xC0, 7dBm 0xC8, 5dBm 0x84, 0dBm 0x60, -10dBm 0x34, -15dBm 0x1D, -20dBm 0x0E, -30dBm 0x12
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00};
void furi_hal_subghz_init() { void furi_hal_subghz_init() {
furi_assert(furi_hal_subghz_state == SubGhzStateInit); furi_assert(furi_hal_subghz.state == SubGhzStateInit);
furi_hal_subghz_state = SubGhzStateIdle; furi_hal_subghz.state = SubGhzStateIdle;
furi_hal_subghz_preset = FuriHalSubGhzPresetIDLE; furi_hal_subghz.preset = FuriHalSubGhzPresetIDLE;
furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz);
@ -368,7 +74,7 @@ void furi_hal_subghz_init() {
} }
void furi_hal_subghz_sleep() { void furi_hal_subghz_sleep() {
furi_assert(furi_hal_subghz_state == SubGhzStateIdle); furi_assert(furi_hal_subghz.state == SubGhzStateIdle);
furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz);
cc1101_switch_to_idle(&furi_hal_spi_bus_handle_subghz); cc1101_switch_to_idle(&furi_hal_spi_bus_handle_subghz);
@ -380,7 +86,7 @@ void furi_hal_subghz_sleep() {
furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz);
furi_hal_subghz_preset = FuriHalSubGhzPresetIDLE; furi_hal_subghz.preset = FuriHalSubGhzPresetIDLE;
} }
void furi_hal_subghz_dump_state() { void furi_hal_subghz_dump_state() {
@ -414,7 +120,7 @@ void furi_hal_subghz_load_preset(FuriHalSubGhzPreset preset) {
} else { } else {
furi_crash("SubGhz: Missing config."); furi_crash("SubGhz: Missing config.");
} }
furi_hal_subghz_preset = preset; furi_hal_subghz.preset = preset;
} }
void furi_hal_subghz_load_registers(const uint8_t data[][2]) { void furi_hal_subghz_load_registers(const uint8_t data[][2]) {
@ -515,7 +221,7 @@ void furi_hal_subghz_rx() {
} }
bool furi_hal_subghz_tx() { bool furi_hal_subghz_tx() {
if(furi_hal_subghz_regulation != SubGhzRegulationTxRx) return false; if(furi_hal_subghz.regulation != SubGhzRegulationTxRx) return false;
furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz);
cc1101_switch_to_tx(&furi_hal_spi_bus_handle_subghz); cc1101_switch_to_tx(&furi_hal_spi_bus_handle_subghz);
furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz);
@ -589,8 +295,8 @@ bool furi_hal_subghz_is_tx_allowed(uint32_t value) {
} else { } else {
if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) { if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) {
if((value >= 304100000 && value <= 321950000) && if((value >= 304100000 && value <= 321950000) &&
((furi_hal_subghz_preset == FuriHalSubGhzPresetOok270Async) || ((furi_hal_subghz.preset == FuriHalSubGhzPresetOok270Async) ||
(furi_hal_subghz_preset == FuriHalSubGhzPresetOok650Async))) { (furi_hal_subghz.preset == FuriHalSubGhzPresetOok650Async))) {
furi_hal_subghz_load_patable(furi_hal_subghz_preset_ook_async_patable_au); furi_hal_subghz_load_patable(furi_hal_subghz_preset_ook_async_patable_au);
} }
} }
@ -615,9 +321,9 @@ bool furi_hal_subghz_is_tx_allowed(uint32_t value) {
uint32_t furi_hal_subghz_set_frequency(uint32_t value) { uint32_t furi_hal_subghz_set_frequency(uint32_t value) {
if(furi_hal_subghz_is_tx_allowed(value)) { if(furi_hal_subghz_is_tx_allowed(value)) {
furi_hal_subghz_regulation = SubGhzRegulationTxRx; furi_hal_subghz.regulation = SubGhzRegulationTxRx;
} else { } else {
furi_hal_subghz_regulation = SubGhzRegulationOnlyRx; furi_hal_subghz.regulation = SubGhzRegulationOnlyRx;
} }
furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz);
@ -684,8 +390,8 @@ static void furi_hal_subghz_capture_ISR() {
} }
void furi_hal_subghz_start_async_rx(FuriHalSubGhzCaptureCallback callback, void* context) { void furi_hal_subghz_start_async_rx(FuriHalSubGhzCaptureCallback callback, void* context) {
furi_assert(furi_hal_subghz_state == SubGhzStateIdle); furi_assert(furi_hal_subghz.state == SubGhzStateIdle);
furi_hal_subghz_state = SubGhzStateAsyncRx; furi_hal_subghz.state = SubGhzStateAsyncRx;
furi_hal_subghz_capture_callback = callback; furi_hal_subghz_capture_callback = callback;
furi_hal_subghz_capture_callback_context = context; furi_hal_subghz_capture_callback_context = context;
@ -741,8 +447,8 @@ void furi_hal_subghz_start_async_rx(FuriHalSubGhzCaptureCallback callback, void*
} }
void furi_hal_subghz_stop_async_rx() { void furi_hal_subghz_stop_async_rx() {
furi_assert(furi_hal_subghz_state == SubGhzStateAsyncRx); furi_assert(furi_hal_subghz.state == SubGhzStateAsyncRx);
furi_hal_subghz_state = SubGhzStateIdle; furi_hal_subghz.state = SubGhzStateIdle;
// Shutdown radio // Shutdown radio
furi_hal_subghz_idle(); furi_hal_subghz_idle();
@ -822,7 +528,10 @@ static void furi_hal_subghz_async_tx_refill(uint32_t* buffer, size_t samples) {
} }
static void furi_hal_subghz_async_tx_dma_isr() { static void furi_hal_subghz_async_tx_dma_isr() {
furi_assert(furi_hal_subghz_state == SubGhzStateAsyncTx); furi_assert(
furi_hal_subghz.state == SubGhzStateAsyncTx ||
furi_hal_subghz.state == SubGhzStateAsyncTxEnd ||
furi_hal_subghz.state == SubGhzStateAsyncTxLast);
if(LL_DMA_IsActiveFlag_HT1(DMA1)) { if(LL_DMA_IsActiveFlag_HT1(DMA1)) {
LL_DMA_ClearFlag_HT1(DMA1); LL_DMA_ClearFlag_HT1(DMA1);
furi_hal_subghz_async_tx_refill( furi_hal_subghz_async_tx_refill(
@ -840,12 +549,12 @@ static void furi_hal_subghz_async_tx_timer_isr() {
if(LL_TIM_IsActiveFlag_UPDATE(TIM2)) { if(LL_TIM_IsActiveFlag_UPDATE(TIM2)) {
LL_TIM_ClearFlag_UPDATE(TIM2); LL_TIM_ClearFlag_UPDATE(TIM2);
if(LL_TIM_GetAutoReload(TIM2) == 0) { if(LL_TIM_GetAutoReload(TIM2) == 0) {
if(furi_hal_subghz_state == SubGhzStateAsyncTx) { if(furi_hal_subghz.state == SubGhzStateAsyncTx) {
furi_hal_subghz_state = SubGhzStateAsyncTxLast; furi_hal_subghz.state = SubGhzStateAsyncTxLast;
//forcibly pulls the pin to the ground so that there is no carrier //forcibly pulls the pin to the ground so that there is no carrier
furi_hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullDown, GpioSpeedLow); furi_hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullDown, GpioSpeedLow);
} else { } else {
furi_hal_subghz_state = SubGhzStateAsyncTxEnd; furi_hal_subghz.state = SubGhzStateAsyncTxEnd;
LL_TIM_DisableCounter(TIM2); LL_TIM_DisableCounter(TIM2);
} }
} }
@ -853,16 +562,16 @@ static void furi_hal_subghz_async_tx_timer_isr() {
} }
bool furi_hal_subghz_start_async_tx(FuriHalSubGhzAsyncTxCallback callback, void* context) { bool furi_hal_subghz_start_async_tx(FuriHalSubGhzAsyncTxCallback callback, void* context) {
furi_assert(furi_hal_subghz_state == SubGhzStateIdle); furi_assert(furi_hal_subghz.state == SubGhzStateIdle);
furi_assert(callback); furi_assert(callback);
//If transmission is prohibited by regional settings //If transmission is prohibited by regional settings
if(furi_hal_subghz_regulation != SubGhzRegulationTxRx) return false; if(furi_hal_subghz.regulation != SubGhzRegulationTxRx) return false;
furi_hal_subghz_async_tx.callback = callback; furi_hal_subghz_async_tx.callback = callback;
furi_hal_subghz_async_tx.callback_context = context; furi_hal_subghz_async_tx.callback_context = context;
furi_hal_subghz_state = SubGhzStateAsyncTx; furi_hal_subghz.state = SubGhzStateAsyncTx;
furi_hal_subghz_async_tx.duty_low = 0; furi_hal_subghz_async_tx.duty_low = 0;
furi_hal_subghz_async_tx.duty_high = 0; furi_hal_subghz_async_tx.duty_high = 0;
@ -935,14 +644,14 @@ bool furi_hal_subghz_start_async_tx(FuriHalSubGhzAsyncTxCallback callback, void*
} }
bool furi_hal_subghz_is_async_tx_complete() { bool furi_hal_subghz_is_async_tx_complete() {
return furi_hal_subghz_state == SubGhzStateAsyncTxEnd; return furi_hal_subghz.state == SubGhzStateAsyncTxEnd;
} }
void furi_hal_subghz_stop_async_tx() { void furi_hal_subghz_stop_async_tx() {
furi_assert( furi_assert(
furi_hal_subghz_state == SubGhzStateAsyncTx || furi_hal_subghz.state == SubGhzStateAsyncTx ||
furi_hal_subghz_state == SubGhzStateAsyncTxLast || furi_hal_subghz.state == SubGhzStateAsyncTxLast ||
furi_hal_subghz_state == SubGhzStateAsyncTxEnd); furi_hal_subghz.state == SubGhzStateAsyncTxEnd);
// Shutdown radio // Shutdown radio
furi_hal_subghz_idle(); furi_hal_subghz_idle();
@ -976,5 +685,5 @@ void furi_hal_subghz_stop_async_tx() {
(double)furi_hal_subghz_async_tx.duty_low, (double)furi_hal_subghz_async_tx.duty_low,
(double)duty_cycle); (double)duty_cycle);
furi_hal_subghz_state = SubGhzStateIdle; furi_hal_subghz.state = SubGhzStateIdle;
} }

View File

@ -0,0 +1,314 @@
#pragma once
#include <cc1101.h>
static const uint8_t furi_hal_subghz_preset_ook_270khz_async_regs[][2] = {
// https://e2e.ti.com/support/wireless-connectivity/sub-1-ghz-group/sub-1-ghz/f/sub-1-ghz-forum/382066/cc1101---don-t-know-the-correct-registers-configuration
/* GPIO GD0 */
{CC1101_IOCFG0, 0x0D}, // GD0 as async serial data output/input
/* FIFO and internals */
{CC1101_FIFOTHR, 0x47}, // The only important bit is ADC_RETENTION, FIFO Tx=33 Rx=32
/* Packet engine */
{CC1101_PKTCTRL0, 0x32}, // Async, continious, no whitening
/* Frequency Synthesizer Control */
{CC1101_FSCTRL1, 0x06}, // IF = (26*10^6) / (2^10) * 0x06 = 152343.75Hz
// Modem Configuration
{CC1101_MDMCFG0, 0x00}, // Channel spacing is 25kHz
{CC1101_MDMCFG1, 0x00}, // Channel spacing is 25kHz
{CC1101_MDMCFG2, 0x30}, // Format ASK/OOK, No preamble/sync
{CC1101_MDMCFG3, 0x32}, // Data rate is 3.79372 kBaud
{CC1101_MDMCFG4, 0x67}, // Rx BW filter is 270.833333kHz
/* Main Radio Control State Machine */
{CC1101_MCSM0, 0x18}, // Autocalibrate on idle-to-rx/tx, PO_TIMEOUT is 64 cycles(149-155us)
/* Frequency Offset Compensation Configuration */
{CC1101_FOCCFG,
0x18}, // no frequency offset compensation, POST_K same as PRE_K, PRE_K is 4K, GATE is off
/* Automatic Gain Control */
{CC1101_AGCCTRL0,
0x40}, // 01 - Low hysteresis, small asymmetric dead zone, medium gain; 00 - 8 samples agc; 00 - Normal AGC, 00 - 4dB boundary
{CC1101_AGCCTRL1,
0x00}, // 0; 0 - LNA 2 gain is decreased to minimum before decreasing LNA gain; 00 - Relative carrier sense threshold disabled; 0000 - RSSI to MAIN_TARGET
{CC1101_AGCCTRL2, 0x03}, // 00 - DVGA all; 000 - MAX LNA+LNA2; 011 - MAIN_TARGET 24 dB
/* Wake on radio and timeouts control */
{CC1101_WORCTRL, 0xFB}, // WOR_RES is 2^15 periods (0.91 - 0.94 s) 16.5 - 17.2 hours
/* Frontend configuration */
{CC1101_FREND0, 0x11}, // Adjusts current TX LO buffer + high is PATABLE[1]
{CC1101_FREND1, 0xB6}, //
/* End */
{0, 0},
};
static const uint8_t furi_hal_subghz_preset_ook_650khz_async_regs[][2] = {
// https://e2e.ti.com/support/wireless-connectivity/sub-1-ghz-group/sub-1-ghz/f/sub-1-ghz-forum/382066/cc1101---don-t-know-the-correct-registers-configuration
/* GPIO GD0 */
{CC1101_IOCFG0, 0x0D}, // GD0 as async serial data output/input
/* FIFO and internals */
{CC1101_FIFOTHR, 0x07}, // The only important bit is ADC_RETENTION
/* Packet engine */
{CC1101_PKTCTRL0, 0x32}, // Async, continious, no whitening
/* Frequency Synthesizer Control */
{CC1101_FSCTRL1, 0x06}, // IF = (26*10^6) / (2^10) * 0x06 = 152343.75Hz
// Modem Configuration
{CC1101_MDMCFG0, 0x00}, // Channel spacing is 25kHz
{CC1101_MDMCFG1, 0x00}, // Channel spacing is 25kHz
{CC1101_MDMCFG2, 0x30}, // Format ASK/OOK, No preamble/sync
{CC1101_MDMCFG3, 0x32}, // Data rate is 3.79372 kBaud
{CC1101_MDMCFG4, 0x17}, // Rx BW filter is 650.000kHz
/* Main Radio Control State Machine */
{CC1101_MCSM0, 0x18}, // Autocalibrate on idle-to-rx/tx, PO_TIMEOUT is 64 cycles(149-155us)
/* Frequency Offset Compensation Configuration */
{CC1101_FOCCFG,
0x18}, // no frequency offset compensation, POST_K same as PRE_K, PRE_K is 4K, GATE is off
/* Automatic Gain Control */
// {CC1101_AGCTRL0,0x40}, // 01 - Low hysteresis, small asymmetric dead zone, medium gain; 00 - 8 samples agc; 00 - Normal AGC, 00 - 4dB boundary
// {CC1101_AGCTRL1,0x00}, // 0; 0 - LNA 2 gain is decreased to minimum before decreasing LNA gain; 00 - Relative carrier sense threshold disabled; 0000 - RSSI to MAIN_TARGET
// {CC1101_AGCCTRL2, 0x03}, // 00 - DVGA all; 000 - MAX LNA+LNA2; 011 - MAIN_TARGET 24 dB
//MAGN_TARGET for RX filter BW =< 100 kHz is 0x3. For higher RX filter BW's MAGN_TARGET is 0x7.
{CC1101_AGCCTRL0,
0x91}, // 10 - Medium hysteresis, medium asymmetric dead zone, medium gain ; 01 - 16 samples agc; 00 - Normal AGC, 01 - 8dB boundary
{CC1101_AGCCTRL1,
0x0}, // 0; 0 - LNA 2 gain is decreased to minimum before decreasing LNA gain; 00 - Relative carrier sense threshold disabled; 0000 - RSSI to MAIN_TARGET
{CC1101_AGCCTRL2, 0x07}, // 00 - DVGA all; 000 - MAX LNA+LNA2; 111 - MAIN_TARGET 42 dB
/* Wake on radio and timeouts control */
{CC1101_WORCTRL, 0xFB}, // WOR_RES is 2^15 periods (0.91 - 0.94 s) 16.5 - 17.2 hours
/* Frontend configuration */
{CC1101_FREND0, 0x11}, // Adjusts current TX LO buffer + high is PATABLE[1]
{CC1101_FREND1, 0xB6}, //
/* End */
{0, 0},
};
static const uint8_t furi_hal_subghz_preset_2fsk_dev2_38khz_async_regs[][2] = {
/* GPIO GD0 */
{CC1101_IOCFG0, 0x0D}, // GD0 as async serial data output/input
/* Frequency Synthesizer Control */
{CC1101_FSCTRL1, 0x06}, // IF = (26*10^6) / (2^10) * 0x06 = 152343.75Hz
/* Packet engine */
{CC1101_PKTCTRL0, 0x32}, // Async, continious, no whitening
{CC1101_PKTCTRL1, 0x04},
// // Modem Configuration
{CC1101_MDMCFG0, 0x00},
{CC1101_MDMCFG1, 0x02},
{CC1101_MDMCFG2, 0x04}, // Format 2-FSK/FM, No preamble/sync, Disable (current optimized)
{CC1101_MDMCFG3, 0x83}, // Data rate is 4.79794 kBaud
{CC1101_MDMCFG4, 0x67}, //Rx BW filter is 270.833333 kHz
{CC1101_DEVIATN, 0x04}, //Deviation 2.380371 kHz
/* Main Radio Control State Machine */
{CC1101_MCSM0, 0x18}, // Autocalibrate on idle-to-rx/tx, PO_TIMEOUT is 64 cycles(149-155us)
/* Frequency Offset Compensation Configuration */
{CC1101_FOCCFG,
0x16}, // no frequency offset compensation, POST_K same as PRE_K, PRE_K is 4K, GATE is off
/* Automatic Gain Control */
{CC1101_AGCCTRL0,
0x91}, //10 - Medium hysteresis, medium asymmetric dead zone, medium gain ; 01 - 16 samples agc; 00 - Normal AGC, 01 - 8dB boundary
{CC1101_AGCCTRL1,
0x00}, // 0; 0 - LNA 2 gain is decreased to minimum before decreasing LNA gain; 00 - Relative carrier sense threshold disabled; 0000 - RSSI to MAIN_TARGET
{CC1101_AGCCTRL2, 0x07}, // 00 - DVGA all; 000 - MAX LNA+LNA2; 111 - MAIN_TARGET 42 dB
/* Wake on radio and timeouts control */
{CC1101_WORCTRL, 0xFB}, // WOR_RES is 2^15 periods (0.91 - 0.94 s) 16.5 - 17.2 hours
/* Frontend configuration */
{CC1101_FREND0, 0x10}, // Adjusts current TX LO buffer
{CC1101_FREND1, 0x56},
/* End */
{0, 0},
};
static const uint8_t furi_hal_subghz_preset_2fsk_dev47_6khz_async_regs[][2] = {
/* GPIO GD0 */
{CC1101_IOCFG0, 0x0D}, // GD0 as async serial data output/input
/* Frequency Synthesizer Control */
{CC1101_FSCTRL1, 0x06}, // IF = (26*10^6) / (2^10) * 0x06 = 152343.75Hz
/* Packet engine */
{CC1101_PKTCTRL0, 0x32}, // Async, continious, no whitening
{CC1101_PKTCTRL1, 0x04},
// // Modem Configuration
{CC1101_MDMCFG0, 0x00},
{CC1101_MDMCFG1, 0x02},
{CC1101_MDMCFG2, 0x04}, // Format 2-FSK/FM, No preamble/sync, Disable (current optimized)
{CC1101_MDMCFG3, 0x83}, // Data rate is 4.79794 kBaud
{CC1101_MDMCFG4, 0x67}, //Rx BW filter is 270.833333 kHz
{CC1101_DEVIATN, 0x47}, //Deviation 47.60742 kHz
/* Main Radio Control State Machine */
{CC1101_MCSM0, 0x18}, // Autocalibrate on idle-to-rx/tx, PO_TIMEOUT is 64 cycles(149-155us)
/* Frequency Offset Compensation Configuration */
{CC1101_FOCCFG,
0x16}, // no frequency offset compensation, POST_K same as PRE_K, PRE_K is 4K, GATE is off
/* Automatic Gain Control */
{CC1101_AGCCTRL0,
0x91}, //10 - Medium hysteresis, medium asymmetric dead zone, medium gain ; 01 - 16 samples agc; 00 - Normal AGC, 01 - 8dB boundary
{CC1101_AGCCTRL1,
0x00}, // 0; 0 - LNA 2 gain is decreased to minimum before decreasing LNA gain; 00 - Relative carrier sense threshold disabled; 0000 - RSSI to MAIN_TARGET
{CC1101_AGCCTRL2, 0x07}, // 00 - DVGA all; 000 - MAX LNA+LNA2; 111 - MAIN_TARGET 42 dB
/* Wake on radio and timeouts control */
{CC1101_WORCTRL, 0xFB}, // WOR_RES is 2^15 periods (0.91 - 0.94 s) 16.5 - 17.2 hours
/* Frontend configuration */
{CC1101_FREND0, 0x10}, // Adjusts current TX LO buffer
{CC1101_FREND1, 0x56},
/* End */
{0, 0},
};
static const uint8_t furi_hal_subghz_preset_msk_99_97kb_async_regs[][2] = {
/* GPIO GD0 */
{CC1101_IOCFG0, 0x06},
{CC1101_FIFOTHR, 0x07}, // The only important bit is ADC_RETENTION
{CC1101_SYNC1, 0x46},
{CC1101_SYNC0, 0x4C},
{CC1101_ADDR, 0x00},
{CC1101_PKTLEN, 0x00},
{CC1101_CHANNR, 0x00},
{CC1101_PKTCTRL0, 0x05},
{CC1101_FSCTRL0, 0x23},
{CC1101_FSCTRL1, 0x06},
{CC1101_MDMCFG0, 0xF8},
{CC1101_MDMCFG1, 0x22},
{CC1101_MDMCFG2, 0x72},
{CC1101_MDMCFG3, 0xF8},
{CC1101_MDMCFG4, 0x5B},
{CC1101_DEVIATN, 0x47},
{CC1101_MCSM0, 0x18},
{CC1101_FOCCFG, 0x16},
{CC1101_AGCCTRL0, 0xB2},
{CC1101_AGCCTRL1, 0x00},
{CC1101_AGCCTRL2, 0xC7},
{CC1101_FREND0, 0x10},
{CC1101_FREND1, 0x56},
{CC1101_BSCFG, 0x1C},
{CC1101_FSTEST, 0x59},
/* End */
{0, 0},
};
static const uint8_t furi_hal_subghz_preset_gfsk_9_99kb_async_regs[][2] = {
{CC1101_IOCFG0, 0x06}, //GDO0 Output Pin Configuration
{CC1101_FIFOTHR, 0x47}, //RX FIFO and TX FIFO Thresholds
//1 : CRC calculation in TX and CRC check in RX enabled,
//1 : Variable packet length mode. Packet length configured by the first byte after sync word
{CC1101_PKTCTRL0, 0x05},
{CC1101_FSCTRL1, 0x06}, //Frequency Synthesizer Control
{CC1101_SYNC1, 0x46},
{CC1101_SYNC0, 0x4C},
{CC1101_ADDR, 0x00},
{CC1101_PKTLEN, 0x00},
{CC1101_MDMCFG4, 0xC8}, //Modem Configuration 9.99
{CC1101_MDMCFG3, 0x93}, //Modem Configuration
{CC1101_MDMCFG2, 0x12}, // 2: 16/16 sync word bits detected
{CC1101_DEVIATN, 0x34}, //Deviation = 19.042969
{CC1101_MCSM0, 0x18}, //Main Radio Control State Machine Configuration
{CC1101_FOCCFG, 0x16}, //Frequency Offset Compensation Configuration
{CC1101_AGCCTRL2, 0x43}, //AGC Control
{CC1101_AGCCTRL1, 0x40},
{CC1101_AGCCTRL0, 0x91},
{CC1101_WORCTRL, 0xFB}, //Wake On Radio Control
/* End */
{0, 0},
};
static const uint8_t furi_hal_subghz_preset_ook_async_patable[8] = {
0x00,
0xC0, // 12dBm 0xC0, 10dBm 0xC5, 7dBm 0xCD, 5dBm 0x86, 0dBm 0x50, -6dBm 0x37, -10dBm 0x26, -15dBm 0x1D, -20dBm 0x17, -30dBm 0x03
0x00,
0x00,
0x00,
0x00,
0x00,
0x00};
static const uint8_t furi_hal_subghz_preset_ook_async_patable_au[8] = {
0x00,
0x37, // 12dBm 0xC0, 10dBm 0xC5, 7dBm 0xCD, 5dBm 0x86, 0dBm 0x50, -6dBm 0x37, -10dBm 0x26, -15dBm 0x1D, -20dBm 0x17, -30dBm 0x03
0x00,
0x00,
0x00,
0x00,
0x00,
0x00};
static const uint8_t furi_hal_subghz_preset_2fsk_async_patable[8] = {
0xC0, // 10dBm 0xC0, 7dBm 0xC8, 5dBm 0x84, 0dBm 0x60, -10dBm 0x34, -15dBm 0x1D, -20dBm 0x0E, -30dBm 0x12
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00};
static const uint8_t furi_hal_subghz_preset_msk_async_patable[8] = {
0xC0, // 10dBm 0xC0, 7dBm 0xC8, 5dBm 0x84, 0dBm 0x60, -10dBm 0x34, -15dBm 0x1D, -20dBm 0x0E, -30dBm 0x12
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00};
static const uint8_t furi_hal_subghz_preset_gfsk_async_patable[8] = {
0xC0, // 10dBm 0xC0, 7dBm 0xC8, 5dBm 0x84, 0dBm 0x60, -10dBm 0x34, -15dBm 0x1D, -20dBm 0x0E, -30dBm 0x12
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00};