From c16d52e3c8c7460bb6b127661199fcf4ea8109db Mon Sep 17 00:00:00 2001 From: bkleiner Date: Wed, 16 Nov 2022 01:22:04 +0100 Subject: [PATCH] cc2500: optimize set channel and packet_size --- src/drivers/drv_spi_cc2500.c | 53 ++++++++++++++++++++++++++++++++++++ src/drivers/drv_spi_cc2500.h | 2 ++ src/rx/rx_frsky.c | 33 ++-------------------- src/rx/rx_frsky_d16.c | 3 +- src/rx/rx_frsky_d8.c | 3 +- src/rx/rx_frsky_redpine.c | 7 ++--- 6 files changed, 62 insertions(+), 39 deletions(-) diff --git a/src/drivers/drv_spi_cc2500.c b/src/drivers/drv_spi_cc2500.c index 0ab943d24..c96dedb4a 100644 --- a/src/drivers/drv_spi_cc2500.c +++ b/src/drivers/drv_spi_cc2500.c @@ -124,6 +124,59 @@ static void cc2500_write_multi(uint8_t reg, uint8_t *data, uint8_t len) { spi_txn_continue_ex(&bus, true); } +void cc2500_set_channel(uint8_t channel, uint8_t *cal_data) { + { + spi_txn_t *txn = spi_txn_init(&bus, NULL); + spi_txn_add_seg_const(txn, CC2500_SIDLE); + spi_txn_submit(txn); + } + { + spi_txn_t *txn = spi_txn_init(&bus, NULL); + spi_txn_add_seg_const(txn, CC2500_FSCAL3 | CC2500_WRITE_BURST); + spi_txn_add_seg(txn, NULL, cal_data, 3); + spi_txn_submit(txn); + } + { + spi_txn_t *txn = spi_txn_init(&bus, NULL); + spi_txn_add_seg_const(txn, CC2500_CHANNR | CC2500_WRITE_SINGLE); + spi_txn_add_seg_const(txn, channel); + spi_txn_submit(txn); + } + spi_txn_continue(&bus); +} + +uint8_t cc2500_packet_size() { + if (cc2500_read_gdo0() == 0) { + return 0; + } + + // there is a bug in the cc2500 + // see p3 http:// www.ti.com/lit/er/swrz002e/swrz002e.pdf + // workaround: read len register very quickly twice: + + // try this 10 times befor giving up: + for (uint8_t i = 0; i < 10; i++) { + uint8_t len1 = 0; + uint8_t len2 = 0; + + { + spi_txn_t *txn = spi_txn_init(&bus, NULL); + spi_txn_add_seg_const(txn, CC2500_RXBYTES | CC2500_READ_SINGLE); + spi_txn_add_seg(txn, &len1, NULL, 1); + spi_txn_add_seg_const(txn, CC2500_RXBYTES | CC2500_READ_SINGLE); + spi_txn_add_seg(txn, &len2, NULL, 1); + spi_txn_submit_wait(&bus, txn); + } + + // valid len found? + if (len1 == len2) { + return len1; + } + } + + return 0; +} + uint8_t cc2500_read_fifo(uint8_t *result, uint8_t len) { return cc2500_read_multi(CC2500_FIFO | CC2500_READ_BURST, result, len); } diff --git a/src/drivers/drv_spi_cc2500.h b/src/drivers/drv_spi_cc2500.h index b7404b4b2..80463cd1f 100644 --- a/src/drivers/drv_spi_cc2500.h +++ b/src/drivers/drv_spi_cc2500.h @@ -105,6 +105,8 @@ void cc2500_write_reg(uint8_t reg, uint8_t data); uint8_t cc2500_read_fifo(uint8_t *result, uint8_t len); void cc2500_write_fifo(uint8_t *data, uint8_t len); uint8_t cc2500_read_gdo0(); +void cc2500_set_channel(uint8_t channel, uint8_t *cal_data); +uint8_t cc2500_packet_size(); void cc2500_enter_rxmode(); void cc2500_enter_txmode(); diff --git a/src/rx/rx_frsky.c b/src/rx/rx_frsky.c index 2b7fc09ac..d6c0268fd 100644 --- a/src/rx/rx_frsky.c +++ b/src/rx/rx_frsky.c @@ -74,13 +74,7 @@ void set_address(uint8_t is_bind) { } static void set_channel(uint8_t channel) { - cc2500_strobe(CC2500_SIDLE); - - cc2500_write_reg(CC2500_FSCAL3, cal_data[channel][0]); - cc2500_write_reg(CC2500_FSCAL2, cal_data[channel][1]); - cc2500_write_reg(CC2500_FSCAL1, cal_data[channel][2]); - - cc2500_write_reg(CC2500_CHANNR, channel); + cc2500_set_channel(channel, cal_data[channel]); } uint8_t next_channel(uint8_t skip) { @@ -101,31 +95,8 @@ uint8_t next_channel(uint8_t skip) { return channr; } -uint8_t packet_size() { - if (cc2500_read_gdo0() == 0) { - return 0; - } - - // there is a bug in the cc2500 - // see p3 http:// www.ti.com/lit/er/swrz002e/swrz002e.pdf - // workaround: read len register very quickly twice: - - // try this 10 times befor giving up: - for (uint8_t i = 0; i < 10; i++) { - uint8_t len1 = cc2500_read_reg(CC2500_RXBYTES | CC2500_READ_BURST) & 0x7F; - uint8_t len2 = cc2500_read_reg(CC2500_RXBYTES | CC2500_READ_BURST) & 0x7F; - - // valid len found? - if (len1 == len2) { - return len1; - } - } - - return 0; -} - static uint8_t read_packet() { - uint8_t len = packet_size(); + uint8_t len = cc2500_packet_size(); if (len == 0) { return 0; } diff --git a/src/rx/rx_frsky_d16.c b/src/rx/rx_frsky_d16.c index 11ab565df..b4ab11ffa 100644 --- a/src/rx/rx_frsky_d16.c +++ b/src/rx/rx_frsky_d16.c @@ -103,7 +103,6 @@ void handle_overflows(); void calibrate_channels(); void set_address(uint8_t is_bind); uint8_t next_channel(uint8_t skip); -uint8_t packet_size(); static uint16_t frsky_d16_crc(const uint8_t *data, uint8_t len) { uint16_t crc = 0; @@ -303,7 +302,7 @@ static uint8_t frsky_d16_handle_packet() { last_packet_received_time = time_micros(); // fallthrough case FRSKY_STATE_DATA: { - uint8_t len = packet_size(); + uint8_t len = cc2500_packet_size(); if (frame_had_packet == 0 && len >= FRSKY_D16_PACKET_LENGTH) { cc2500_read_fifo(packet, FRSKY_D16_PACKET_LENGTH); frsky_d16_frame_header *header = (frsky_d16_frame_header *)packet; diff --git a/src/rx/rx_frsky_d8.c b/src/rx/rx_frsky_d8.c index 16f5ebfde..c22ac2a69 100644 --- a/src/rx/rx_frsky_d8.c +++ b/src/rx/rx_frsky_d8.c @@ -42,7 +42,6 @@ void handle_overflows(); void calibrate_channels(); void set_address(uint8_t is_bind); uint8_t next_channel(uint8_t skip); -uint8_t packet_size(); static void frsky_d8_set_rc_data() { uint16_t channels[FRSKY_D8_CHANNEL_COUNT]; @@ -201,7 +200,7 @@ static uint8_t frsky_d8_handle_packet() { last_packet_received_time = current_packet_received_time; // fallthrough case FRSKY_STATE_DATA: { - uint8_t len = packet_size(); + uint8_t len = cc2500_packet_size(); if (len >= 20) { cc2500_read_fifo(packet, 20); frsky_d8_frame *frame = (frsky_d8_frame *)packet; diff --git a/src/rx/rx_frsky_redpine.c b/src/rx/rx_frsky_redpine.c index 7ac09ed66..08539925f 100644 --- a/src/rx/rx_frsky_redpine.c +++ b/src/rx/rx_frsky_redpine.c @@ -35,7 +35,6 @@ void handle_overflows(); void calibrate_channels(); void set_address(uint8_t is_bind); uint8_t next_channel(uint8_t skip); -uint8_t packet_size(); static void redpine_set_rc_data() { if (packet[REDPINE_CHANNEL_START] == 1 && packet[REDPINE_CHANNEL_START + 1] == 0) { @@ -110,7 +109,9 @@ static uint8_t redpine_handle_packet() { // fallthrough case FRSKY_STATE_DATA: { - uint8_t len = packet_size(); + handle_overflows(); + + uint8_t len = cc2500_packet_size(); if (len == REDPINE_PACKET_SIZE_W_ADDONS) { cc2500_read_fifo(packet, len); @@ -149,8 +150,6 @@ static uint8_t redpine_handle_packet() { cc2500_strobe(CC2500_SFRX); } - handle_overflows(); - if ((time_micros() - total_time) > 50 * max_sync_delay) { // out of sync with packets - do a complete resysnc quic_debugf("REDPINE: resync %u", (time_micros() - total_time));