SubGhz: add GFSK modulation, refactoring subghz_chat (#866)
* SubGhz: add GFSK modulation, refactoring subghz_chat * SubGhz: off echo subghz_chat * SubGhz: subghz_chat add sending and receiving formatted text, translation of the chat to events * SubGhz: add UTF support in subghz_chat_worker_alloc Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
@@ -291,6 +291,45 @@ static const uint8_t furi_hal_subghz_preset_msk_99_97kb_async_regs[][2] = {
|
||||
/* 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
|
||||
{CC1101_FSCAL3, 0xE9}, //Frequency Synthesizer Calibration
|
||||
{CC1101_FSCAL2, 0x2A}, //Frequency Synthesizer Calibration
|
||||
{CC1101_FSCAL1, 0x00}, //Frequency Synthesizer Calibration
|
||||
{CC1101_FSCAL0, 0x1F}, //Frequency Synthesizer Calibration
|
||||
{CC1101_TEST2, 0x81}, //Various Test Settings
|
||||
{CC1101_TEST1, 0x35}, //Various Test Settings
|
||||
{CC1101_TEST0, 0x09}, //Various Test Settings
|
||||
/* End */
|
||||
{0, 0},
|
||||
};
|
||||
|
||||
static const uint8_t furi_hal_subghz_preset_ook_async_patable[8] = {
|
||||
0x00,
|
||||
@@ -319,6 +358,15 @@ static const uint8_t furi_hal_subghz_preset_msk_async_patable[8] = {
|
||||
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() {
|
||||
furi_assert(furi_hal_subghz_state == SubGhzStateInit);
|
||||
@@ -344,7 +392,8 @@ void furi_hal_subghz_init() {
|
||||
;
|
||||
|
||||
// GD0 high
|
||||
cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG0, CC1101IocfgHW | CC1101_IOCFG_INV);
|
||||
cc1101_write_reg(
|
||||
&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG0, CC1101IocfgHW | CC1101_IOCFG_INV);
|
||||
while(hal_gpio_read(&gpio_cc1101_g0) != true)
|
||||
;
|
||||
|
||||
@@ -402,6 +451,9 @@ void furi_hal_subghz_load_preset(FuriHalSubGhzPreset preset) {
|
||||
} else if(preset == FuriHalSubGhzPresetMSK99_97KbAsync) {
|
||||
furi_hal_subghz_load_registers(furi_hal_subghz_preset_msk_99_97kb_async_regs);
|
||||
furi_hal_subghz_load_patable(furi_hal_subghz_preset_msk_async_patable);
|
||||
} else if(preset == FuriHalSubGhzPresetGFSK9_99KbAsync) {
|
||||
furi_hal_subghz_load_registers(furi_hal_subghz_preset_gfsk_9_99kb_async_regs);
|
||||
furi_hal_subghz_load_patable(furi_hal_subghz_preset_gfsk_async_patable);
|
||||
} else {
|
||||
furi_crash(NULL);
|
||||
}
|
||||
@@ -438,10 +490,17 @@ void furi_hal_subghz_flush_rx() {
|
||||
furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz);
|
||||
}
|
||||
|
||||
void furi_hal_subghz_flush_tx() {
|
||||
furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz);
|
||||
cc1101_flush_tx(&furi_hal_spi_bus_handle_subghz);
|
||||
furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz);
|
||||
}
|
||||
|
||||
bool furi_hal_subghz_rx_pipe_not_empty() {
|
||||
CC1101RxBytes status[1];
|
||||
furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz);
|
||||
cc1101_read_reg(&furi_hal_spi_bus_handle_subghz, (CC1101_STATUS_RXBYTES) | CC1101_BURST, (uint8_t*)status);
|
||||
cc1101_read_reg(
|
||||
&furi_hal_spi_bus_handle_subghz, (CC1101_STATUS_RXBYTES) | CC1101_BURST, (uint8_t*)status);
|
||||
furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz);
|
||||
// TODO: you can add a buffer overflow flag if needed
|
||||
if(status->NUM_RXBYTES > 0) {
|
||||
@@ -520,6 +579,14 @@ float furi_hal_subghz_get_rssi() {
|
||||
return rssi;
|
||||
}
|
||||
|
||||
uint8_t furi_hal_subghz_get_lqi() {
|
||||
furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz);
|
||||
uint8_t data[1];
|
||||
cc1101_read_reg(&furi_hal_spi_bus_handle_subghz, CC1101_STATUS_LQI | CC1101_BURST, data);
|
||||
furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz);
|
||||
return data[0] & 0x7F;
|
||||
}
|
||||
|
||||
bool furi_hal_subghz_is_frequency_valid(uint32_t value) {
|
||||
if(!(value >= 299999755 && value <= 348000335) &&
|
||||
!(value >= 386999938 && value <= 464000000) &&
|
||||
@@ -607,13 +674,15 @@ void furi_hal_subghz_set_path(FuriHalSubGhzPath path) {
|
||||
furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz);
|
||||
if(path == FuriHalSubGhzPath433) {
|
||||
hal_gpio_write(&gpio_rf_sw_0, 0);
|
||||
cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG2, CC1101IocfgHW | CC1101_IOCFG_INV);
|
||||
cc1101_write_reg(
|
||||
&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG2, CC1101IocfgHW | CC1101_IOCFG_INV);
|
||||
} else if(path == FuriHalSubGhzPath315) {
|
||||
hal_gpio_write(&gpio_rf_sw_0, 1);
|
||||
cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG2, CC1101IocfgHW);
|
||||
} else if(path == FuriHalSubGhzPath868) {
|
||||
hal_gpio_write(&gpio_rf_sw_0, 1);
|
||||
cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG2, CC1101IocfgHW | CC1101_IOCFG_INV);
|
||||
cc1101_write_reg(
|
||||
&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG2, CC1101IocfgHW | CC1101_IOCFG_INV);
|
||||
} else if(path == FuriHalSubGhzPathIsolate) {
|
||||
hal_gpio_write(&gpio_rf_sw_0, 0);
|
||||
cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG2, CC1101IocfgHW);
|
||||
|
@@ -291,6 +291,45 @@ static const uint8_t furi_hal_subghz_preset_msk_99_97kb_async_regs[][2] = {
|
||||
/* 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
|
||||
{CC1101_FSCAL3, 0xE9}, //Frequency Synthesizer Calibration
|
||||
{CC1101_FSCAL2, 0x2A}, //Frequency Synthesizer Calibration
|
||||
{CC1101_FSCAL1, 0x00}, //Frequency Synthesizer Calibration
|
||||
{CC1101_FSCAL0, 0x1F}, //Frequency Synthesizer Calibration
|
||||
{CC1101_TEST2, 0x81}, //Various Test Settings
|
||||
{CC1101_TEST1, 0x35}, //Various Test Settings
|
||||
{CC1101_TEST0, 0x09}, //Various Test Settings
|
||||
/* End */
|
||||
{0, 0},
|
||||
};
|
||||
|
||||
static const uint8_t furi_hal_subghz_preset_ook_async_patable[8] = {
|
||||
0x00,
|
||||
@@ -319,6 +358,15 @@ static const uint8_t furi_hal_subghz_preset_msk_async_patable[8] = {
|
||||
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() {
|
||||
furi_assert(furi_hal_subghz_state == SubGhzStateInit);
|
||||
@@ -402,7 +450,10 @@ void furi_hal_subghz_load_preset(FuriHalSubGhzPreset preset) {
|
||||
} else if(preset == FuriHalSubGhzPresetMSK99_97KbAsync) {
|
||||
furi_hal_subghz_load_registers(furi_hal_subghz_preset_msk_99_97kb_async_regs);
|
||||
furi_hal_subghz_load_patable(furi_hal_subghz_preset_msk_async_patable);
|
||||
} else {
|
||||
} else if(preset == FuriHalSubGhzPresetGFSK9_99KbAsync) {
|
||||
furi_hal_subghz_load_registers(furi_hal_subghz_preset_gfsk_9_99kb_async_regs);
|
||||
furi_hal_subghz_load_patable(furi_hal_subghz_preset_gfsk_async_patable);
|
||||
} else{
|
||||
furi_crash(NULL);
|
||||
}
|
||||
}
|
||||
@@ -438,6 +489,12 @@ void furi_hal_subghz_flush_rx() {
|
||||
furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz);
|
||||
}
|
||||
|
||||
void furi_hal_subghz_flush_tx() {
|
||||
furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz);
|
||||
cc1101_flush_tx(&furi_hal_spi_bus_handle_subghz);
|
||||
furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz);
|
||||
}
|
||||
|
||||
bool furi_hal_subghz_rx_pipe_not_empty() {
|
||||
CC1101RxBytes status[1];
|
||||
furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz);
|
||||
@@ -520,6 +577,14 @@ float furi_hal_subghz_get_rssi() {
|
||||
return rssi;
|
||||
}
|
||||
|
||||
uint8_t furi_hal_subghz_get_lqi() {
|
||||
furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz);
|
||||
uint8_t data[1];
|
||||
cc1101_read_reg(&furi_hal_spi_bus_handle_subghz, CC1101_STATUS_LQI | CC1101_BURST, data);
|
||||
furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz);
|
||||
return data[0] & 0x7F;
|
||||
}
|
||||
|
||||
bool furi_hal_subghz_is_frequency_valid(uint32_t value) {
|
||||
if(!(value >= 299999755 && value <= 348000335) &&
|
||||
!(value >= 386999938 && value <= 464000000) &&
|
||||
|
@@ -21,6 +21,7 @@ typedef enum {
|
||||
FuriHalSubGhzPreset2FSKDev238Async, /**< FM, deviation 2.380371 kHz, asynchronous */
|
||||
FuriHalSubGhzPreset2FSKDev476Async, /**< FM, deviation 4.760742 kHz, asynchronous */
|
||||
FuriHalSubGhzPresetMSK99_97KbAsync, /**< MSK, deviation 47.60742 kHz, 99.97Kb/s, asynchronous */
|
||||
FuriHalSubGhzPresetGFSK9_99KbAsync /**< GFSK, deviation 19.042969 kHz, 9.996Kb/s, asynchronous */
|
||||
} FuriHalSubGhzPreset;
|
||||
|
||||
/** Switchable Radio Paths */
|
||||
@@ -114,6 +115,10 @@ void furi_hal_subghz_read_packet(uint8_t* data, uint8_t* size);
|
||||
*/
|
||||
void furi_hal_subghz_flush_rx();
|
||||
|
||||
/** Flush tx FIFO buffer
|
||||
*/
|
||||
void furi_hal_subghz_flush_tx();
|
||||
|
||||
/** Shutdown Issue spwd command
|
||||
* @warning registers content will be lost
|
||||
*/
|
||||
@@ -144,6 +149,12 @@ bool furi_hal_subghz_tx();
|
||||
*/
|
||||
float furi_hal_subghz_get_rssi();
|
||||
|
||||
/** Get LQI
|
||||
*
|
||||
* @return LQI value
|
||||
*/
|
||||
uint8_t furi_hal_subghz_get_lqi();
|
||||
|
||||
/** Check if frequency is in valid range
|
||||
*
|
||||
* @param value frequency in Hz
|
||||
|
Reference in New Issue
Block a user