diff options
author | Skorpionm <85568270+Skorpionm@users.noreply.github.com> | 2021-09-28 03:05:40 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-09-28 03:05:40 +0300 |
commit | a8981d317a0f36e6694e8edc891103eecb5fae7a (patch) | |
tree | 309a0d7ff9668721ee733a4bfa57bd9813375d6a /firmware | |
parent | 416e1bda3519020d3dbcf9b5e66e693fcfa66279 (diff) |
[FL-1815, FL-1851, FL-1856] SubGhz: preparation for certification, add deleting stored signals and rename file in SubGHz app (#714)
* [FL-1811] FuriHal: move core2 startup to hal init stage, prevent working with flash controller till core2 startup finish. #704
* SubGhz: fix GO0 low on last hop transmission, decreased DutyCycle in tests
* SubGhz: test_static fix max 5 sec in transmission mode, DutyCycle <23%
* [FL-1815] SubGhz: prohibiting transmission if it is not within the permitted range for the given region
* SubGhz: fix F7 furi-hal-subghz
* SubGhz: fix logic working tests
* SubGhz: fix princeton encoder for test
* SubGhz: add log princeton encoder
* [FL-1856] Subghz: fix output a double error if the file cannot be opened
* [FL-1851] SubGhz: add deleting Stored Signals in SubGHz App
* SubGhz: add rename file SubGhz app
* SubGhz: update stats message in princeton
* SubGhz: correct spelling
* SubGhz: fix FM config, add hardware signal processing less than 16 μs, add added filter for processing short signals
* SubGhz: add Scher-Khan MAGICAR Dinamic protocol
* SubGhz: sync fury targets
Co-authored-by: あく <alleteam@gmail.com>
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/targets/f6/furi-hal/furi-hal-subghz.c | 113 | ||||
-rw-r--r-- | firmware/targets/f7/furi-hal/furi-hal-subghz.c | 117 | ||||
-rw-r--r-- | firmware/targets/furi-hal-include/furi-hal-subghz.h | 28 |
3 files changed, 188 insertions, 70 deletions
diff --git a/firmware/targets/f6/furi-hal/furi-hal-subghz.c b/firmware/targets/f6/furi-hal/furi-hal-subghz.c index 4d1f0cbf..34446d8d 100644 --- a/firmware/targets/f6/furi-hal/furi-hal-subghz.c +++ b/firmware/targets/f6/furi-hal/furi-hal-subghz.c @@ -1,4 +1,5 @@ #include "furi-hal-subghz.h" +#include "furi-hal-version.h" #include <furi-hal-gpio.h> #include <furi-hal-spi.h> @@ -10,6 +11,7 @@ #include <stdio.h> static volatile SubGhzState furi_hal_subghz_state = SubGhzStateInit; +static volatile SubGhzRegulation furi_hal_subghz_regulation = SubGhzRegulationTxRx; 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 @@ -41,11 +43,11 @@ static const uint8_t furi_hal_subghz_preset_ook_270khz_async_regs[][2] = { 0x18}, // no frequency offset compensation, POST_K same as PRE_K, PRE_K is 4K, GATE is off /* Automatic Gain Control */ - {CC1101_AGCTRL0, + {CC1101_AGCCTRL0, 0x40}, // 01 - Low hysteresis, small asymmetric dead zone, medium gain; 00 - 8 samples agc; 00 - Normal AGC, 00 - 4dB boundary - {CC1101_AGCTRL1, + {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_AGCTRL2, 0x03}, // 00 - DVGA all; 000 - MAX LNA+LNA2; 011 - MAIN_TARGET 24 dB + {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 @@ -99,11 +101,15 @@ static const uint8_t furi_hal_subghz_preset_ook_650khz_async_regs[][2] = { 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_AGCTRL2, 0x03}, // 00 - DVGA all; 000 - MAX LNA+LNA2; 011 - MAIN_TARGET 24 dB + // {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 @@ -131,23 +137,21 @@ static const uint8_t furi_hal_subghz_preset_2fsk_async_regs[][2] = { /* 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 + /* 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}, - /* Frequency Synthesizer Control */ - {CC1101_FSCTRL1, 0x06}, // IF = (26*10^6) / (2^10) * 0x06 = 152343.75Hz - - // Modem Configuration + // // Modem Configuration {CC1101_MDMCFG0, 0x00}, - {CC1101_MDMCFG1, 0x02}, - {CC1101_MDMCFG2, 0x04}, // Format 2-FSK/FM, No preamble/sync, Disable (current optimized) - {CC1101_MDMCFG3, 0x8B}, // Data rate is 19.5885 kBaud - {CC1101_MDMCFG4, 0x69}, // Rx BW filter is 270.833333 kHz - - {CC1101_DEVIATN, 0x47}, //Deviation 47.607422 khz + {CC1101_MDMCFG1, 0x2}, + {CC1101_MDMCFG2, 0x4}, // 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, 0x14 }, //Deviation 4.760742 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) @@ -157,18 +161,18 @@ static const uint8_t furi_hal_subghz_preset_2fsk_async_regs[][2] = { 0x16}, // 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, + {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_AGCTRL2, 0x03}, // 00 - DVGA all; 000 - MAX LNA+LNA2; 011 - MAIN_TARGET 24 dB + {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, 0xB6}, // + {CC1101_FREND1, 0x56}, /* Frequency Synthesizer Calibration, valid for 433.92 */ {CC1101_FSCAL3, 0xE9}, @@ -281,7 +285,7 @@ void furi_hal_subghz_load_preset(FuriHalSubGhzPreset preset) { } else if(preset == FuriHalSubGhzPreset2FSKAsync) { furi_hal_subghz_load_registers(furi_hal_subghz_preset_2fsk_async_regs); furi_hal_subghz_load_patable(furi_hal_subghz_preset_2fsk_async_patable); - }else { + } else { furi_crash(NULL); } } @@ -358,10 +362,12 @@ void furi_hal_subghz_rx() { furi_hal_spi_device_return(device); } -void furi_hal_subghz_tx() { +bool furi_hal_subghz_tx() { + if(furi_hal_subghz_regulation != SubGhzRegulationTxRx) return false; const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); cc1101_switch_to_tx(device); furi_hal_spi_device_return(device); + return true; } float furi_hal_subghz_get_rssi() { @@ -385,6 +391,7 @@ bool furi_hal_subghz_is_frequency_valid(uint32_t value) { !(value >= 778999847 && value <= 928000000)) { return false; } + return true; } @@ -405,6 +412,46 @@ uint32_t furi_hal_subghz_set_frequency_and_path(uint32_t value) { uint32_t furi_hal_subghz_set_frequency(uint32_t value) { const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); + //checking regional settings + bool txrx = false; + switch(furi_hal_version_get_hw_region()) { + case FuriHalVersionRegionEuRu: + //433,05..434,79; 868,15..868,55 + if(!(value >= 433050000 && value <= 434790000) && + !(value >= 868150000 && value <= 8680550000)) { + } else { + txrx = true; + } + break; + case FuriHalVersionRegionUsCaAu: + //304,10..315,25; 433,05..434,79; 915,00..928,00 + if(!(value >= 304100000 && value <= 315250000) && + !(value >= 433050000 && value <= 434790000) && + !(value >= 915000000 && value <= 928000000)) { + } else { + txrx = true; + } + break; + case FuriHalVersionRegionJp: + //312,00..315,25; 920,50..923,50 + if(!(value >= 312000000 && value <= 315250000) && + !(value >= 920500000 && value <= 923500000)) { + } else { + txrx = true; + } + break; + + default: + txrx = true; + break; + } + + if(txrx) { + furi_hal_subghz_regulation = SubGhzRegulationTxRx; + } else { + furi_hal_subghz_regulation = SubGhzRegulationOnlyRx; + } + uint32_t real_frequency = cc1101_set_frequency(device, value); cc1101_calibrate(device); @@ -482,7 +529,7 @@ void furi_hal_subghz_start_async_rx(FuriHalSubGhzCaptureCallback callback, void* TIM_InitStruct.Prescaler = 64 - 1; TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP; TIM_InitStruct.Autoreload = 0x7FFFFFFE; - TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1; + TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV4; LL_TIM_Init(TIM2, &TIM_InitStruct); // Timer: advanced @@ -505,7 +552,7 @@ void furi_hal_subghz_start_async_rx(FuriHalSubGhzCaptureCallback callback, void* LL_TIM_IC_SetActiveInput(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_ACTIVEINPUT_DIRECTTI); LL_TIM_IC_SetPrescaler(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_ICPSC_DIV1); LL_TIM_IC_SetPolarity(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_IC_POLARITY_RISING); - LL_TIM_IC_SetFilter(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_IC_FILTER_FDIV1); + LL_TIM_IC_SetFilter(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_IC_FILTER_FDIV32_N8); // ISR setup furi_hal_interrupt_set_timer_isr(TIM2, furi_hal_subghz_capture_ISR); @@ -610,6 +657,8 @@ static void furi_hal_subghz_async_tx_timer_isr() { if(LL_TIM_GetAutoReload(TIM2) == 0) { if(furi_hal_subghz_state == SubGhzStateAsyncTx) { furi_hal_subghz_state = SubGhzStateAsyncTxLast; + //forcibly pulls the pin to the ground so that there is no carrier + hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullDown, GpioSpeedLow); } else { furi_hal_subghz_state = SubGhzStateAsyncTxEnd; LL_TIM_DisableCounter(TIM2); @@ -618,10 +667,13 @@ static void furi_hal_subghz_async_tx_timer_isr() { } } -void 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(callback); + //If transmission is prohibited by regional settings + if(furi_hal_subghz_regulation != SubGhzRegulationTxRx) return false; + furi_hal_subghz_async_tx.callback = callback; furi_hal_subghz_async_tx.callback_context = context; @@ -696,6 +748,7 @@ void furi_hal_subghz_start_async_tx(FuriHalSubGhzAsyncTxCallback callback, void* LL_TIM_SetCounter(TIM2, 0); LL_TIM_EnableCounter(TIM2); + return true; } bool furi_hal_subghz_is_async_tx_complete() { diff --git a/firmware/targets/f7/furi-hal/furi-hal-subghz.c b/firmware/targets/f7/furi-hal/furi-hal-subghz.c index 7e8c12cd..34446d8d 100644 --- a/firmware/targets/f7/furi-hal/furi-hal-subghz.c +++ b/firmware/targets/f7/furi-hal/furi-hal-subghz.c @@ -1,4 +1,5 @@ #include "furi-hal-subghz.h" +#include "furi-hal-version.h" #include <furi-hal-gpio.h> #include <furi-hal-spi.h> @@ -10,6 +11,7 @@ #include <stdio.h> static volatile SubGhzState furi_hal_subghz_state = SubGhzStateInit; +static volatile SubGhzRegulation furi_hal_subghz_regulation = SubGhzRegulationTxRx; 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 @@ -41,11 +43,11 @@ static const uint8_t furi_hal_subghz_preset_ook_270khz_async_regs[][2] = { 0x18}, // no frequency offset compensation, POST_K same as PRE_K, PRE_K is 4K, GATE is off /* Automatic Gain Control */ - {CC1101_AGCTRL0, + {CC1101_AGCCTRL0, 0x40}, // 01 - Low hysteresis, small asymmetric dead zone, medium gain; 00 - 8 samples agc; 00 - Normal AGC, 00 - 4dB boundary - {CC1101_AGCTRL1, + {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_AGCTRL2, 0x03}, // 00 - DVGA all; 000 - MAX LNA+LNA2; 011 - MAIN_TARGET 24 dB + {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 @@ -99,11 +101,15 @@ static const uint8_t furi_hal_subghz_preset_ook_650khz_async_regs[][2] = { 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_AGCTRL2, 0x03}, // 00 - DVGA all; 000 - MAX LNA+LNA2; 011 - MAIN_TARGET 24 dB + // {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 @@ -131,23 +137,21 @@ static const uint8_t furi_hal_subghz_preset_2fsk_async_regs[][2] = { /* 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 + /* 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}, - /* Frequency Synthesizer Control */ - {CC1101_FSCTRL1, 0x06}, // IF = (26*10^6) / (2^10) * 0x06 = 152343.75Hz - - // Modem Configuration + // // Modem Configuration {CC1101_MDMCFG0, 0x00}, - {CC1101_MDMCFG1, 0x02}, - {CC1101_MDMCFG2, 0x04}, // Format 2-FSK/FM, No preamble/sync, Disable (current optimized) - {CC1101_MDMCFG3, 0x8B}, // Data rate is 19.5885 kBaud - {CC1101_MDMCFG4, 0x69}, // Rx BW filter is 270.833333 kHz - - {CC1101_DEVIATN, 0x47}, //Deviation 47.607422 khz + {CC1101_MDMCFG1, 0x2}, + {CC1101_MDMCFG2, 0x4}, // 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, 0x14 }, //Deviation 4.760742 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) @@ -157,18 +161,18 @@ static const uint8_t furi_hal_subghz_preset_2fsk_async_regs[][2] = { 0x16}, // 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, + {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_AGCTRL2, 0x03}, // 00 - DVGA all; 000 - MAX LNA+LNA2; 011 - MAIN_TARGET 24 dB + {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, 0xB6}, // + {CC1101_FREND1, 0x56}, /* Frequency Synthesizer Calibration, valid for 433.92 */ {CC1101_FSCAL3, 0xE9}, @@ -201,7 +205,9 @@ static const uint8_t furi_hal_subghz_preset_2fsk_async_patable[8] = { 0x00, 0x00, 0x00, - 0x00}; + 0x00 + +}; void furi_hal_subghz_init() { furi_assert(furi_hal_subghz_state == SubGhzStateInit); @@ -279,7 +285,7 @@ void furi_hal_subghz_load_preset(FuriHalSubGhzPreset preset) { } else if(preset == FuriHalSubGhzPreset2FSKAsync) { furi_hal_subghz_load_registers(furi_hal_subghz_preset_2fsk_async_regs); furi_hal_subghz_load_patable(furi_hal_subghz_preset_2fsk_async_patable); - }else { + } else { furi_crash(NULL); } } @@ -356,10 +362,12 @@ void furi_hal_subghz_rx() { furi_hal_spi_device_return(device); } -void furi_hal_subghz_tx() { +bool furi_hal_subghz_tx() { + if(furi_hal_subghz_regulation != SubGhzRegulationTxRx) return false; const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); cc1101_switch_to_tx(device); furi_hal_spi_device_return(device); + return true; } float furi_hal_subghz_get_rssi() { @@ -383,6 +391,7 @@ bool furi_hal_subghz_is_frequency_valid(uint32_t value) { !(value >= 778999847 && value <= 928000000)) { return false; } + return true; } @@ -403,6 +412,46 @@ uint32_t furi_hal_subghz_set_frequency_and_path(uint32_t value) { uint32_t furi_hal_subghz_set_frequency(uint32_t value) { const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); + //checking regional settings + bool txrx = false; + switch(furi_hal_version_get_hw_region()) { + case FuriHalVersionRegionEuRu: + //433,05..434,79; 868,15..868,55 + if(!(value >= 433050000 && value <= 434790000) && + !(value >= 868150000 && value <= 8680550000)) { + } else { + txrx = true; + } + break; + case FuriHalVersionRegionUsCaAu: + //304,10..315,25; 433,05..434,79; 915,00..928,00 + if(!(value >= 304100000 && value <= 315250000) && + !(value >= 433050000 && value <= 434790000) && + !(value >= 915000000 && value <= 928000000)) { + } else { + txrx = true; + } + break; + case FuriHalVersionRegionJp: + //312,00..315,25; 920,50..923,50 + if(!(value >= 312000000 && value <= 315250000) && + !(value >= 920500000 && value <= 923500000)) { + } else { + txrx = true; + } + break; + + default: + txrx = true; + break; + } + + if(txrx) { + furi_hal_subghz_regulation = SubGhzRegulationTxRx; + } else { + furi_hal_subghz_regulation = SubGhzRegulationOnlyRx; + } + uint32_t real_frequency = cc1101_set_frequency(device, value); cc1101_calibrate(device); @@ -480,7 +529,7 @@ void furi_hal_subghz_start_async_rx(FuriHalSubGhzCaptureCallback callback, void* TIM_InitStruct.Prescaler = 64 - 1; TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP; TIM_InitStruct.Autoreload = 0x7FFFFFFE; - TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1; + TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV4; LL_TIM_Init(TIM2, &TIM_InitStruct); // Timer: advanced @@ -503,7 +552,7 @@ void furi_hal_subghz_start_async_rx(FuriHalSubGhzCaptureCallback callback, void* LL_TIM_IC_SetActiveInput(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_ACTIVEINPUT_DIRECTTI); LL_TIM_IC_SetPrescaler(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_ICPSC_DIV1); LL_TIM_IC_SetPolarity(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_IC_POLARITY_RISING); - LL_TIM_IC_SetFilter(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_IC_FILTER_FDIV1); + LL_TIM_IC_SetFilter(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_IC_FILTER_FDIV32_N8); // ISR setup furi_hal_interrupt_set_timer_isr(TIM2, furi_hal_subghz_capture_ISR); @@ -608,6 +657,8 @@ static void furi_hal_subghz_async_tx_timer_isr() { if(LL_TIM_GetAutoReload(TIM2) == 0) { if(furi_hal_subghz_state == SubGhzStateAsyncTx) { furi_hal_subghz_state = SubGhzStateAsyncTxLast; + //forcibly pulls the pin to the ground so that there is no carrier + hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullDown, GpioSpeedLow); } else { furi_hal_subghz_state = SubGhzStateAsyncTxEnd; LL_TIM_DisableCounter(TIM2); @@ -616,10 +667,13 @@ static void furi_hal_subghz_async_tx_timer_isr() { } } -void 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(callback); + //If transmission is prohibited by regional settings + if(furi_hal_subghz_regulation != SubGhzRegulationTxRx) return false; + furi_hal_subghz_async_tx.callback = callback; furi_hal_subghz_async_tx.callback_context = context; @@ -694,6 +748,7 @@ void furi_hal_subghz_start_async_tx(FuriHalSubGhzAsyncTxCallback callback, void* LL_TIM_SetCounter(TIM2, 0); LL_TIM_EnableCounter(TIM2); + return true; } bool furi_hal_subghz_is_async_tx_complete() { diff --git a/firmware/targets/furi-hal-include/furi-hal-subghz.h b/firmware/targets/furi-hal-include/furi-hal-subghz.h index 653a343c..38aa65da 100644 --- a/firmware/targets/furi-hal-include/furi-hal-subghz.h +++ b/firmware/targets/furi-hal-include/furi-hal-subghz.h @@ -26,17 +26,24 @@ typedef enum { /** SubGhz state */ typedef enum { - SubGhzStateInit, /** Init pending */ + SubGhzStateInit, /** Init pending */ - SubGhzStateIdle, /** Idle, energy save mode */ + SubGhzStateIdle, /** Idle, energy save mode */ - SubGhzStateAsyncRx, /** Async RX started */ + SubGhzStateAsyncRx, /** Async RX started */ + + SubGhzStateAsyncTx, /** Async TX started, DMA and timer is on */ + SubGhzStateAsyncTxLast, /** Async TX continue, DMA completed and timer got last value to go */ + SubGhzStateAsyncTxEnd, /** Async TX complete, cleanup needed */ - SubGhzStateAsyncTx, /** Async TX started, DMA and timer is on */ - SubGhzStateAsyncTxLast, /** Async TX continue, DMA completed and timer got last value to go */ - SubGhzStateAsyncTxEnd, /** Async TX complete, cleanup needed */ } SubGhzState; +/** SubGhz regulation, receive transmission on the current frequency for the region */ +typedef enum { + SubGhzRegulationOnlyRx, /**only Rx*/ + SubGhzRegulationTxRx, /**TxRx*/ +} SubGhzRegulation; + /** Initialize and switch to power save mode * Used by internal API-HAL initalization routine * Can be used to reinitialize device to safe state and send it to sleep @@ -100,8 +107,10 @@ void furi_hal_subghz_idle(); /** Switch to Recieve */ void furi_hal_subghz_rx(); -/** Switch to Transmit */ -void furi_hal_subghz_tx(); +/** Switch to Transmit +* @return true if the transfer is allowed by belonging to the region +*/ +bool furi_hal_subghz_tx(); /** Get RSSI value in dBm */ float furi_hal_subghz_get_rssi(); @@ -152,8 +161,9 @@ typedef LevelDuration (*FuriHalSubGhzAsyncTxCallback)(void* context); /** Start async TX * Initializes GPIO, TIM2 and DMA1 for signal output + * @return true if the transfer is allowed by belonging to the region */ -void furi_hal_subghz_start_async_tx(FuriHalSubGhzAsyncTxCallback callback, void* context); +bool furi_hal_subghz_start_async_tx(FuriHalSubGhzAsyncTxCallback callback, void* context); /** Wait for async transmission to complete */ bool furi_hal_subghz_is_async_tx_complete(); |