Subghz packet test (#512)

* subghz: add cli support for packet tx rx

* api-hal-subghz: add comments

* subghz_cli: fix typo

Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
gornekich 2021-06-08 12:51:16 +03:00 committed by GitHub
parent 216f8b4fb8
commit 498ffe8d2c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 213 additions and 18 deletions

126
applications/subghz/subghz_cli.c Normal file → Executable file
View File

@ -2,6 +2,13 @@
#include <furi.h> #include <furi.h>
#include <api-hal.h> #include <api-hal.h>
static const uint8_t subghz_test_packet_data[] = {
0x30, // 48bytes to transmit
0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
};
void subghz_cli_init() { void subghz_cli_init() {
Cli* cli = furi_record_open("cli"); Cli* cli = furi_record_open("cli");
@ -32,9 +39,9 @@ void subghz_cli_command_tx_carrier(Cli* cli, string_t args, void* context) {
frequency = api_hal_subghz_set_frequency(frequency); frequency = api_hal_subghz_set_frequency(frequency);
printf("Transmitting at frequency %lu Hz\r\n", frequency); printf("Transmitting at frequency %lu Hz\r\n", frequency);
printf("Press CTRL+C to stop\r\n"); printf("Press CTRL+C to stop\r\n");
if(frequency < 400) { if(frequency < 400000000) {
api_hal_subghz_set_path(ApiHalSubGhzPath315); api_hal_subghz_set_path(ApiHalSubGhzPath315);
} else if(frequency < 500) { } else if(frequency < 500000000) {
api_hal_subghz_set_path(ApiHalSubGhzPath433); api_hal_subghz_set_path(ApiHalSubGhzPath433);
} else { } else {
api_hal_subghz_set_path(ApiHalSubGhzPath868); api_hal_subghz_set_path(ApiHalSubGhzPath868);
@ -73,9 +80,9 @@ void subghz_cli_command_rx_carrier(Cli* cli, string_t args, void* context) {
frequency = api_hal_subghz_set_frequency(frequency); frequency = api_hal_subghz_set_frequency(frequency);
printf("Receiving at frequency %lu Hz\r\n", frequency); printf("Receiving at frequency %lu Hz\r\n", frequency);
printf("Press CTRL+C to stop\r\n"); printf("Press CTRL+C to stop\r\n");
if(frequency < 400) { if(frequency < 400000000) {
api_hal_subghz_set_path(ApiHalSubGhzPath315); api_hal_subghz_set_path(ApiHalSubGhzPath315);
} else if(frequency < 500) { } else if(frequency < 500000000) {
api_hal_subghz_set_path(ApiHalSubGhzPath433); api_hal_subghz_set_path(ApiHalSubGhzPath433);
} else { } else {
api_hal_subghz_set_path(ApiHalSubGhzPath868); api_hal_subghz_set_path(ApiHalSubGhzPath868);
@ -96,9 +103,116 @@ void subghz_cli_command_rx_carrier(Cli* cli, string_t args, void* context) {
} }
void subghz_cli_command_tx_pt(Cli* cli, string_t args, void* context) { void subghz_cli_command_tx_pt(Cli* cli, string_t args, void* context) {
printf("Not implemented\r\n"); uint32_t frequency;
uint32_t pattern;
uint32_t count;
int ret = sscanf(string_get_cstr(args), "%lu %lu %lu", &frequency, &pattern, &count);
if(ret != 3) {
printf(
"sscanf returned %d, frequency: %lu; pattern: %lu; count: %lu\r\n",
ret,
frequency,
pattern,
count);
cli_print_usage(
"subghz_tx_pt", "<Frequency in HZ> <Pattern> <Count>", string_get_cstr(args));
return;
}
if(frequency < 300000000 || frequency > 925000000) {
printf("Frequency must be in 300000000...925000000 range, not %lu\r\n", frequency);
return;
}
if(pattern > 1) {
printf("Pattern must be 1, not %lu\r\n", pattern);
}
api_hal_subghz_reset();
api_hal_subghz_idle();
api_hal_subghz_load_preset(ApiHalSubGhzPreset2FskPacket);
frequency = api_hal_subghz_set_frequency(frequency);
if(frequency < 400000000) {
api_hal_subghz_set_path(ApiHalSubGhzPath315);
} else if(frequency < 500000000) {
api_hal_subghz_set_path(ApiHalSubGhzPath433);
} else {
api_hal_subghz_set_path(ApiHalSubGhzPath868);
}
hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow);
uint8_t status = api_hal_subghz_get_status();
FURI_LOG_D("SUBGHZ CLI", "Status: %02X", status);
while(!cli_cmd_interrupt_received(cli) && count) {
api_hal_subghz_idle();
api_hal_subghz_write_packet(subghz_test_packet_data, sizeof(subghz_test_packet_data));
api_hal_subghz_tx();
while(!hal_gpio_read(&gpio_cc1101_g0))
; // Wait for sync
while(hal_gpio_read(&gpio_cc1101_g0))
; // Wait end of transaction
count--;
}
api_hal_subghz_reset();
api_hal_subghz_set_path(ApiHalSubGhzPathIsolate);
hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
} }
void subghz_cli_command_rx_pt(Cli* cli, string_t args, void* context) { void subghz_cli_command_rx_pt(Cli* cli, string_t args, void* context) {
printf("Not implemented\r\n"); uint32_t frequency;
int ret = sscanf(string_get_cstr(args), "%lu", &frequency);
if(ret != 1) {
printf("sscanf returned %d, frequency: %lu\r\n", ret, frequency);
cli_print_usage("subghz_rx_pt", "<Frequency in HZ>", string_get_cstr(args));
return;
}
if(frequency < 300000000 || frequency > 925000000) {
printf("Frequency must be in 300000000...925000000 range, not %lu\r\n", frequency);
return;
}
api_hal_subghz_reset();
api_hal_subghz_idle();
api_hal_subghz_load_preset(ApiHalSubGhzPreset2FskPacket);
frequency = api_hal_subghz_set_frequency(frequency);
if(frequency < 400000000) {
api_hal_subghz_set_path(ApiHalSubGhzPath315);
} else if(frequency < 500000000) {
api_hal_subghz_set_path(ApiHalSubGhzPath433);
} else {
api_hal_subghz_set_path(ApiHalSubGhzPath868);
}
hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow);
uint8_t status = api_hal_subghz_get_status();
FURI_LOG_D("SUBGHZ CLI", "Status: %02X", status);
printf("Start receiving packets. Press CTRL+C to stop\r\n");
api_hal_subghz_flush_rx();
api_hal_subghz_rx();
uint32_t packet_cnt = 0;
while(!cli_cmd_interrupt_received(cli)) {
if(hal_gpio_read(&gpio_cc1101_g0)) {
while(hal_gpio_read(&gpio_cc1101_g0))
; // Wait reception
packet_cnt++;
api_hal_subghz_idle();
api_hal_subghz_flush_rx();
api_hal_subghz_rx();
}
}
printf("Received %lu packets", packet_cnt);
api_hal_subghz_reset();
api_hal_subghz_set_path(ApiHalSubGhzPathIsolate);
hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
} }

View File

@ -35,6 +35,9 @@ void api_hal_subghz_dump_state();
*/ */
void api_hal_subghz_load_preset(ApiHalSubGhzPreset preset); void api_hal_subghz_load_preset(ApiHalSubGhzPreset preset);
/** Get status */
uint8_t api_hal_subghz_get_status();
/** Load registers /** Load registers
* @param register-value pairs array, terminated with {0,0} * @param register-value pairs array, terminated with {0,0}
*/ */
@ -55,7 +58,11 @@ void api_hal_subghz_write_packet(const uint8_t* data, uint8_t size);
* @param data, pointer * @param data, pointer
* @param size, size * @param size, size
*/ */
void api_hal_subghz_read_packet(uint8_t* data, uint8_t size);
void api_hal_subghz_read_packet(uint8_t* data, uint8_t* size);
/** Flush rx FIFO buffer */
void api_hal_subghz_flush_rx();
/** Shutdown /** Shutdown
* Issue spwd command * Issue spwd command

View File

@ -29,6 +29,11 @@ static const uint8_t api_hal_subghz_preset_2fsk_packet_regs[][2] = {
{ CC1101_IOCFG0, 0x06 }, // GD0 as async serial data output/input { CC1101_IOCFG0, 0x06 }, // GD0 as async serial data output/input
{ CC1101_FSCTRL1, 0x06 }, // Set IF 26m/2^10*2=2.2MHz { CC1101_FSCTRL1, 0x06 }, // Set IF 26m/2^10*2=2.2MHz
{ CC1101_MCSM0, 0x18 }, // Autocalibrate on idle to TRX, ~150us OSC guard time { CC1101_MCSM0, 0x18 }, // Autocalibrate on idle to TRX, ~150us OSC guard time
{ CC1101_TEST2, 0x81},
{ CC1101_TEST1, 0x35},
{ CC1101_TEST0, 0x09},
/* End */ /* End */
{ 0, 0 }, { 0, 0 },
}; };
@ -80,6 +85,14 @@ void api_hal_subghz_load_preset(ApiHalSubGhzPreset preset) {
} }
} }
uint8_t api_hal_subghz_get_status() {
const ApiHalSpiDevice* device = api_hal_spi_device_get(ApiHalSpiDeviceIdSubGhz);
CC1101StatusRaw st;
st.status = cc1101_get_status(device);
api_hal_spi_device_return(device);
return st.status_raw;
}
void api_hal_subghz_load_registers(const uint8_t data[][2]) { void api_hal_subghz_load_registers(const uint8_t data[][2]) {
const ApiHalSpiDevice* device = api_hal_spi_device_get(ApiHalSpiDeviceIdSubGhz); const ApiHalSpiDevice* device = api_hal_spi_device_get(ApiHalSpiDeviceIdSubGhz);
cc1101_reset(device); cc1101_reset(device);
@ -104,8 +117,16 @@ void api_hal_subghz_write_packet(const uint8_t* data, uint8_t size) {
api_hal_spi_device_return(device); api_hal_spi_device_return(device);
} }
void api_hal_subghz_read_packet(uint8_t* data, uint8_t size) { void api_hal_subghz_flush_rx() {
const ApiHalSpiDevice* device = api_hal_spi_device_get(ApiHalSpiDeviceIdSubGhz);
cc1101_flush_rx(device);
api_hal_spi_device_return(device);
}
void api_hal_subghz_read_packet(uint8_t* data, uint8_t* size) {
const ApiHalSpiDevice* device = api_hal_spi_device_get(ApiHalSpiDeviceIdSubGhz);
cc1101_read_fifo(device, data, size);
api_hal_spi_device_return(device);
} }
void api_hal_subghz_shutdown() { void api_hal_subghz_shutdown() {

View File

@ -29,6 +29,11 @@ static const uint8_t api_hal_subghz_preset_2fsk_packet_regs[][2] = {
{ CC1101_IOCFG0, 0x06 }, // GD0 as async serial data output/input { CC1101_IOCFG0, 0x06 }, // GD0 as async serial data output/input
{ CC1101_FSCTRL1, 0x06 }, // Set IF 26m/2^10*2=2.2MHz { CC1101_FSCTRL1, 0x06 }, // Set IF 26m/2^10*2=2.2MHz
{ CC1101_MCSM0, 0x18 }, // Autocalibrate on idle to TRX, ~150us OSC guard time { CC1101_MCSM0, 0x18 }, // Autocalibrate on idle to TRX, ~150us OSC guard time
{ CC1101_TEST2, 0x81},
{ CC1101_TEST1, 0x35},
{ CC1101_TEST0, 0x09},
/* End */ /* End */
{ 0, 0 }, { 0, 0 },
}; };
@ -80,6 +85,14 @@ void api_hal_subghz_load_preset(ApiHalSubGhzPreset preset) {
} }
} }
uint8_t api_hal_subghz_get_status() {
const ApiHalSpiDevice* device = api_hal_spi_device_get(ApiHalSpiDeviceIdSubGhz);
CC1101StatusRaw st;
st.status = cc1101_get_status(device);
api_hal_spi_device_return(device);
return st.status_raw;
}
void api_hal_subghz_load_registers(const uint8_t data[][2]) { void api_hal_subghz_load_registers(const uint8_t data[][2]) {
const ApiHalSpiDevice* device = api_hal_spi_device_get(ApiHalSpiDeviceIdSubGhz); const ApiHalSpiDevice* device = api_hal_spi_device_get(ApiHalSpiDeviceIdSubGhz);
cc1101_reset(device); cc1101_reset(device);
@ -104,8 +117,16 @@ void api_hal_subghz_write_packet(const uint8_t* data, uint8_t size) {
api_hal_spi_device_return(device); api_hal_spi_device_return(device);
} }
void api_hal_subghz_read_packet(uint8_t* data, uint8_t size) { void api_hal_subghz_flush_rx() {
const ApiHalSpiDevice* device = api_hal_spi_device_get(ApiHalSpiDeviceIdSubGhz);
cc1101_flush_rx(device);
api_hal_spi_device_return(device);
}
void api_hal_subghz_read_packet(uint8_t* data, uint8_t* size) {
const ApiHalSpiDevice* device = api_hal_spi_device_get(ApiHalSpiDeviceIdSubGhz);
cc1101_read_fifo(device, data, size);
api_hal_spi_device_return(device);
} }
void api_hal_subghz_shutdown() { void api_hal_subghz_shutdown() {
@ -135,6 +156,7 @@ void api_hal_subghz_rx() {
void api_hal_subghz_tx() { void api_hal_subghz_tx() {
const ApiHalSpiDevice* device = api_hal_spi_device_get(ApiHalSpiDeviceIdSubGhz); const ApiHalSpiDevice* device = api_hal_spi_device_get(ApiHalSpiDeviceIdSubGhz);
cc1101_switch_to_idle(device);
cc1101_switch_to_tx(device); cc1101_switch_to_tx(device);
api_hal_spi_device_return(device); api_hal_spi_device_return(device);
} }

View File

@ -71,6 +71,10 @@ void cc1101_reset(const ApiHalSpiDevice* device) {
cc1101_strobe(device, CC1101_STROBE_SRES); cc1101_strobe(device, CC1101_STROBE_SRES);
} }
CC1101Status cc1101_get_status(const ApiHalSpiDevice* device) {
return cc1101_strobe(device, CC1101_STROBE_SNOP);
}
void cc1101_shutdown(const ApiHalSpiDevice* device) { void cc1101_shutdown(const ApiHalSpiDevice* device) {
cc1101_strobe(device, CC1101_STROBE_SPWD); cc1101_strobe(device, CC1101_STROBE_SPWD);
} }
@ -148,24 +152,40 @@ void cc1101_set_pa_table(const ApiHalSpiDevice* device, const uint8_t value[8])
} }
uint8_t cc1101_write_fifo(const ApiHalSpiDevice* device, const uint8_t* data, uint8_t size) { uint8_t cc1101_write_fifo(const ApiHalSpiDevice* device, const uint8_t* data, uint8_t size) {
uint8_t tx = CC1101_FIFO | CC1101_BURST; uint8_t buff_tx[64];
CC1101Status rx = { 0 }; uint8_t buff_rx[64];
buff_tx[0] = CC1101_FIFO | CC1101_BURST;
memcpy(&buff_tx[1], data, size);
// Start transaction // Start transaction
hal_gpio_write(device->chip_select, false); hal_gpio_write(device->chip_select, false);
// Wait IC to become ready // Wait IC to become ready
while(hal_gpio_read(device->bus->miso)); while(hal_gpio_read(device->bus->miso));
// Tell IC what we want // Tell IC what we want
api_hal_spi_bus_trx(device->bus, &tx, (uint8_t*)&rx, 1, CC1101_TIMEOUT); api_hal_spi_bus_trx(device->bus, buff_tx, (uint8_t*) buff_rx, size + 1, CC1101_TIMEOUT);
assert((rx.CHIP_RDYn) == 0);
// Transmit data
api_hal_spi_bus_tx(device->bus, (uint8_t*)data, size, CC1101_TIMEOUT);
// Finish transaction // Finish transaction
hal_gpio_write(device->chip_select, true); hal_gpio_write(device->chip_select, true);
return size; return size;
} }
uint8_t cc1101_read_fifo(const ApiHalSpiDevice* device, uint8_t* data, uint8_t size) { uint8_t cc1101_read_fifo(const ApiHalSpiDevice* device, uint8_t* data, uint8_t* size) {
return size; uint8_t buff_tx[64];
buff_tx[0] = CC1101_FIFO | CC1101_READ | CC1101_BURST;
uint8_t buff_rx[2];
// Start transaction
hal_gpio_write(device->chip_select, false);
// Wait IC to become ready
while(hal_gpio_read(device->bus->miso));
// First byte - packet length
api_hal_spi_bus_trx(device->bus, buff_tx, buff_rx, 2, CC1101_TIMEOUT);
*size = buff_rx[2];
api_hal_spi_bus_trx(device->bus, &buff_tx[1], data, *size, CC1101_TIMEOUT);
cc1101_flush_rx(device);
hal_gpio_write(device->chip_select, true);
return *size;
} }

View File

@ -42,6 +42,11 @@ CC1101Status cc1101_read_reg(const ApiHalSpiDevice* device, uint8_t reg, uint8_t
*/ */
void cc1101_reset(const ApiHalSpiDevice* device); void cc1101_reset(const ApiHalSpiDevice* device);
/** Get status
* @param device - pointer to ApiHalSpiDevice
*/
CC1101Status cc1101_get_status(const ApiHalSpiDevice* device);
/** Enable shutdown mode /** Enable shutdown mode
* @param device - pointer to ApiHalSpiDevice * @param device - pointer to ApiHalSpiDevice
*/ */
@ -146,7 +151,7 @@ uint8_t cc1101_write_fifo(const ApiHalSpiDevice* device, const uint8_t* data, ui
* @param size, bytes to read from fifo * @param size, bytes to read from fifo
* @return size, read bytes count * @return size, read bytes count
*/ */
uint8_t cc1101_read_fifo(const ApiHalSpiDevice* device, uint8_t* data, uint8_t size); uint8_t cc1101_read_fifo(const ApiHalSpiDevice* device, uint8_t* data, uint8_t* size);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -173,6 +173,12 @@ typedef struct {
bool CHIP_RDYn:1; bool CHIP_RDYn:1;
} CC1101Status; } CC1101Status;
typedef union {
CC1101Status status;
uint8_t status_raw;
} CC1101StatusRaw;
typedef struct { typedef struct {
uint8_t NUM_TXBYTES:7; uint8_t NUM_TXBYTES:7;
bool TXFIFO_UNDERFLOW:1; bool TXFIFO_UNDERFLOW:1;