nrf_radio robustness, packet loss (CRC mismatch)

Hello, 
I am implementing a radio interface with a master and a slave. the master sends a synchronization frame every 1ms. this way the slave can transmit data for 500us, every 1ms.
the principle works well, but my slave sometimes receives corrupted packets. he therefore loses an opportunity to transmit information.


Is there any way to make the link more robust?

here is the configuration:

Thanks for help


#define RADIO_CHANNEL 0
#define RADIO_MODE NRF_RADIO_MODE_NRF_2MBIT

#define TIMER_INST_IDX 0

#define CHAN_TO_FREQ(_channel) (2400 + _channel)

// Radio config
nrf_radio_modecnf0_set(NRF_RADIO, true, RADIO_MODECNF0_DTX_Center);
nrf_radio_crc_configure(NRF_RADIO, RADIO_CRCCNF_LEN_Two, NRF_RADIO_CRC_ADDR_SKIP, 0);
nrf_radio_txaddress_set(NRF_RADIO, 0);
nrf_radio_rxaddresses_set(NRF_RADIO, 1);
nrf_radio_prefix0_set(NRF_RADIO, 0xAB);
nrf_radio_base0_set(NRF_RADIO, 0xABABABAB);
nrf_radio_packet_conf_t packet_conf;
uint16_t frequency;

// Configure sync packet
memset(&packet_conf, 0, sizeof(packet_conf));
packet_conf.lflen = 8;
packet_conf.maxlen = (sizeof(tx_packet) - 1);
packet_conf.statlen = 0;
packet_conf.balen = 4;
packet_conf.big_endian = true;
packet_conf.whiteen = true;
packet_conf.plen = NRF_RADIO_PREAMBLE_LENGTH_16BIT;
total_payload_size = 2 + (packet_conf.balen + 1) + 1 + packet_conf.maxlen;
nrf_radio_packet_configure(NRF_RADIO, &packet_conf);

nrf_radio_mode_set(NRF_RADIO, RADIO_MODE);
nrf_radio_txpower_set(NRF_RADIO, RADIO_TXPOWER_TXPOWER_Pos8dBm);

frequency = CHAN_TO_FREQ(RADIO_CHANNEL);
nrf_radio_frequency_set(NRF_RADIO, frequency);

 
/* Includes -----------------------------------------------------------------*/
#include "hidBridgeHostInt_rfCtrl.h"

#include <zephyr/sys/byteorder.h>
#include <zephyr/irq.h>
#include <hal/nrf_radio.h>
#include <nrfx_timer.h>

#include <zephyr/drivers/clock_control.h>
#include <zephyr/drivers/clock_control/nrf_clock_control.h>

#include "hidBridge_common.h"
#include "debugLog.h"

/* Global variables ---------------------------------------------------------*/
#define RX_BUFF_SIZE    MAX(HID_REPORT_ABS_VAL_SIZE, HID_REPORT_BTN_EVT_SIZE) + COM_HEADER_SIZE
#define TX_BUFF_SIZE    MAX(HID_REPORT_ABS_VAL_SIZE, HID_REPORT_BTN_EVT_SIZE) + COM_HEADER_SIZE
#define BUFF_SIZE       HIDPP36_IN_OUT_REPORT_SIZE + COM_HEADER_SIZE

#define RADIO_CHANNEL   0
#define RADIO_MODE      NRF_RADIO_MODE_NRF_2MBIT

#define TIMER_INST_IDX  0

#define CHAN_TO_FREQ(_channel) (2400 + _channel)

#define SYNC_PACKET     0x33

#define LEN_OFFSET      0
#define DATA_OFFSET     1

/* Private constants --------------------------------------------------------*/

/* Private macros -----------------------------------------------------------*/

/* Private typedefs ---------------------------------------------------------*/

/* Private variables --------------------------------------------------------*/
static bool mb_radioModeTX = true;
static bool mb_dataToSend = false;

// Buffer for the radio TX packet
static uint8_t tx_packet[BUFF_SIZE] = {0};
// Buffer for the radio RX packet.
static uint8_t rx_packet[BUFF_SIZE] = {0};
// Number of transmitted packets.
static uint32_t tx_packet_cnt = 0;
// Number of received packets with valid CRC.
static uint32_t rx_packet_cnt = 0;
// Total payload size 
static uint16_t total_payload_size;

/* Private prototypes -------------------------------------------------------*/
static void
button_cb (uint32_t button_state, uint32_t has_changed);

static void 
timer_handler (nrf_timer_event_t event_type, void * p_context);

static void 
clock_init (void);

void
radio_handler (const void *context);

static void 
radio_disable (void);

static void 
radio_enableTx (void);

static void 
radio_enableRx (void);

/* Public functions ---------------------------------------------------------*/
int16_t
hidBridgeHostInt_rfCtrl_init (void)
{
  nrfx_err_t status;
  int ret;
  debugLog_subscribe(__FILE__, DEBUGLOG_LEVEL_Info);

  clock_init();

  irq_connect_dynamic(RADIO_IRQn, IRQ_PRIO_LOWEST, radio_handler, NULL, 0);
  irq_enable(RADIO_IRQn);

  // Radio config
  nrf_radio_modecnf0_set(NRF_RADIO, true, RADIO_MODECNF0_DTX_Center);
  nrf_radio_crc_configure(NRF_RADIO, RADIO_CRCCNF_LEN_Two, NRF_RADIO_CRC_ADDR_SKIP, 0);
  nrf_radio_txaddress_set(NRF_RADIO, 0);
  nrf_radio_rxaddresses_set(NRF_RADIO, 1);
  nrf_radio_prefix0_set(NRF_RADIO, 0xAB);
  nrf_radio_base0_set(NRF_RADIO, 0xABABABAB);
  nrf_radio_packet_conf_t packet_conf;
  uint16_t frequency;
  
  // Configure sync packet
  memset(&packet_conf, 0, sizeof(packet_conf));
  packet_conf.lflen = 8;
  packet_conf.maxlen = (sizeof(tx_packet) - 1);
  packet_conf.statlen = 0;
  packet_conf.balen = 4;
  packet_conf.big_endian = true;
  packet_conf.whiteen = true;
  packet_conf.plen = NRF_RADIO_PREAMBLE_LENGTH_16BIT;
  total_payload_size = 2 + (packet_conf.balen + 1) + 1 + packet_conf.maxlen;
  nrf_radio_packet_configure(NRF_RADIO, &packet_conf);

  nrf_radio_mode_set(NRF_RADIO, RADIO_MODE);
  nrf_radio_txpower_set(NRF_RADIO, RADIO_TXPOWER_TXPOWER_Pos8dBm);

  frequency = CHAN_TO_FREQ(RADIO_CHANNEL);
  nrf_radio_frequency_set(NRF_RADIO, frequency);

  dk_leds_init(); // only for test
  dk_buttons_init(button_cb);

  IRQ_CONNECT(NRFX_IRQ_NUMBER_GET(NRF_TIMER_INST_GET(TIMER_INST_IDX)), IRQ_PRIO_LOWEST,
            NRFX_TIMER_INST_HANDLER_GET(TIMER_INST_IDX), 0, 0);

  nrfx_timer_t timer_inst = NRFX_TIMER_INSTANCE(TIMER_INST_IDX);
  uint32_t base_frequency = NRF_TIMER_BASE_FREQUENCY_GET(timer_inst.p_reg);
  nrfx_timer_config_t config = NRFX_TIMER_DEFAULT_CONFIG(base_frequency);
  config.bit_width = NRF_TIMER_BIT_WIDTH_32;
  config.p_context = "Some context";

  status = nrfx_timer_init(&timer_inst, &config, timer_handler);
  NRFX_ASSERT(status == NRFX_SUCCESS);
  
  nrfx_timer_clear(&timer_inst);

  uint32_t desired_ticks = nrfx_timer_us_to_ticks(&timer_inst, 500);

  nrfx_timer_extended_compare(&timer_inst, NRF_TIMER_CC_CHANNEL0, desired_ticks,
                              NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, true);

  nrfx_timer_enable(&timer_inst);
  
  // Success
  return 0;
}

void
hidBridgeHostInt_rfCtrl_sendData (uint8_t *p_data, uint16_t length)
{    
  if (mb_dataToSend == false)
  {
    mb_dataToSend = true;
    tx_packet[LEN_OFFSET] = length;
    memcpy(&tx_packet[DATA_OFFSET], p_data, length);
  }
  else
  {
    log_error("Interface Busy - lost data");    
  }
}

void
radio_handler (const void *context)
{
  const struct radio_test_config *config =
    (const struct radio_test_config *) context;

  if (nrf_radio_event_check(NRF_RADIO, NRF_RADIO_EVENT_CRCOK)) {
    nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_CRCOK);
    if (false == mb_radioModeTX)
    {
      if (COM_HEADER_DATA_ABS_VAL == rx_packet[DATA_OFFSET])
      {
        log_info("RX COM_HEADER_DATA_ABS_VAL");
      }
      else if (COM_HEADER_DATA_BTN_EVT == rx_packet[DATA_OFFSET])
      {
        log_info("RX COM_HEADER_DATA_BTN_EVT");
      }
      else
      {
        log_error("unknown packet type");
      }
      rx_packet_cnt++;
    }
  }
  else if (nrf_radio_event_check(NRF_RADIO, NRF_RADIO_EVENT_END)) {
    dk_set_led(2,true);
    nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_END);
    if (true == mb_radioModeTX)
    {
      tx_packet_cnt++;
    }
  }
  else 
  {
    log_error("not handle event");
  }

}

/* Private functions --------------------------------------------------------*/
static void 
timer_handler (nrf_timer_event_t event_type, void * p_context)
{  
    if(event_type == NRF_TIMER_EVENT_COMPARE0)
    {
        char * p_msg = p_context;
        dk_set_led(1,mb_radioModeTX);
        if (false == mb_radioModeTX)
        {
          radio_disable();
          radio_enableTx();
          mb_radioModeTX = true;
        }
        else
        {
          radio_disable();
          radio_enableRx();     
          mb_radioModeTX = false;
        }
    }
}

static void 
clock_init (void)
{
  int err;
  int res;
  struct onoff_manager *clk_mgr;
  struct onoff_client clk_cli;

  clk_mgr = z_nrf_clock_control_get_onoff(CLOCK_CONTROL_NRF_SUBSYS_HF);
  if (!clk_mgr) {
    log_error("Unable to get the Clock manager");
    return;
  }

  sys_notify_init_spinwait(&clk_cli.notify);

  err = onoff_request(clk_mgr, &clk_cli);
  if (err < 0) {
    log_error("Clock request failed: %d", err);
    return;
  }

  do {
    err = sys_notify_fetch_result(&clk_cli.notify, &res);
    if (!err && res) {
      log_error("Clock could not be started: %d", res);
      return;
    }
  } while (err);

  log_info("Clock has started");
}


static void 
radio_disable (void)
{
  nrf_radio_shorts_set(NRF_RADIO, 0);
  nrf_radio_int_disable(NRF_RADIO, ~0);
  nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_DISABLED);

  nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_DISABLE);
  while (!nrf_radio_event_check(NRF_RADIO, NRF_RADIO_EVENT_DISABLED)) {
    /* Do nothing */ // TODO: not blocking fct !!! 
  }
  nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_DISABLED);

}

static void 
radio_enableTx (void)
{
  nrf_radio_packetptr_set(NRF_RADIO, tx_packet);

  nrf_radio_shorts_set(NRF_RADIO, NRF_RADIO_SHORT_READY_START_MASK);

  nrf_radio_int_enable(NRF_RADIO, NRF_RADIO_INT_END_MASK);

  if (mb_dataToSend == false)
  {
    tx_packet[LEN_OFFSET] = 1;
    tx_packet[DATA_OFFSET] = SYNC_PACKET;
  }
  else
  {
    mb_dataToSend = false;
  }
  
  dk_set_led(2,false);
  nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_TXEN);
}

static void 
radio_enableRx (void)
{
  nrf_radio_shorts_set(NRF_RADIO,
        NRF_RADIO_SHORT_READY_START_MASK |
        NRF_RADIO_SHORT_END_START_MASK);
  
  nrf_radio_packetptr_set(NRF_RADIO, rx_packet);
  
  nrf_radio_int_enable(NRF_RADIO, NRF_RADIO_INT_CRCOK_MASK);

  nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_RXEN);
}
  
/* Includes -----------------------------------------------------------------*/

#include <zephyr/sys/byteorder.h>
#include <zephyr/irq.h>
#include <hal/nrf_radio.h>
#include <nrfx_timer.h>

#include <zephyr/drivers/clock_control.h>
#include <zephyr/drivers/clock_control/nrf_clock_control.h>

#include "hidBridge_common.h"
#include "debugLog.h"

/* Global variables ---------------------------------------------------------*/
#define RX_BUFF_SIZE    MAX(HID_REPORT_ABS_VAL_SIZE, HID_REPORT_BTN_EVT_SIZE) + COM_HEADER_SIZE
#define TX_BUFF_SIZE    MAX(HID_REPORT_ABS_VAL_SIZE, HID_REPORT_BTN_EVT_SIZE) + COM_HEADER_SIZE
#define BUFF_SIZE       HIDPP36_IN_OUT_REPORT_SIZE + COM_HEADER_SIZE

#define RADIO_CHANNEL   0
#define RADIO_MODE      NRF_RADIO_MODE_NRF_2MBIT

#define TIMER_INST_IDX  0

#define CHAN_TO_FREQ(_channel) (2400 + _channel)

#define SYNC_PACKET     0x33
#define RX_DELAY_US     400
#define TX_DELAY_US     400

#define LEN_OFFSET      0
#define DATA_OFFSET     1

/* Private constants --------------------------------------------------------*/

/* Private macros -----------------------------------------------------------*/

/* Private typedefs ---------------------------------------------------------*/

/* Private variables --------------------------------------------------------*/
static bool mb_radioModeTX = false;
static bool mb_dataToSend = false;
// Buffer for the radio TX packet
static uint8_t tx_packet[BUFF_SIZE] = {0};
static uint8_t tx_length = 0;
// Buffer for the radio RX packet.
static uint8_t rx_packet[BUFF_SIZE] = {0};
// Number of transmitted packets.
static uint32_t tx_packet_cnt = 0;
// Number of received packets with valid CRC.
static uint32_t rx_packet_cnt = 0;
// Total payload size 
static uint16_t total_payload_size;

static nrfx_timer_t m_timer_inst = NRFX_TIMER_INSTANCE(TIMER_INST_IDX);

/* Private prototypes -------------------------------------------------------*/
static void
button_cb (uint32_t button_state, uint32_t has_changed);

static void 
timer_handler (nrf_timer_event_t event_type, void * p_context);

static void 
clock_init (void);

void
radio_handler (const void *context);

static void 
radio_disable (void);

static void 
radio_enableTx (void);

static void 
radio_enableRx (void);

static void
startTimer (uint32_t us_delay);
/* Public functions ---------------------------------------------------------*/
int16_t
hidBridgeDevInt_rfCtrl_init (void)
{
  nrfx_err_t status;
  int ret;

  debugLog_subscribe(__FILE__, DEBUGLOG_LEVEL_Info);

  clock_init();

  irq_connect_dynamic(RADIO_IRQn, IRQ_PRIO_LOWEST, radio_handler, NULL, 0);
  irq_enable(RADIO_IRQn);

  // Radio config
  nrf_radio_modecnf0_set(NRF_RADIO, true, RADIO_MODECNF0_DTX_Center);
  nrf_radio_crc_configure(NRF_RADIO, RADIO_CRCCNF_LEN_Two, NRF_RADIO_CRC_ADDR_SKIP, 0);
  nrf_radio_txaddress_set(NRF_RADIO, 0);
  nrf_radio_rxaddresses_set(NRF_RADIO, 1);
  nrf_radio_prefix0_set(NRF_RADIO, 0xAB);
  nrf_radio_base0_set(NRF_RADIO, 0xABABABAB);
  nrf_radio_packet_conf_t packet_conf;
  uint16_t frequency;
  
  // Configure sync packet
  memset(&packet_conf, 0, sizeof(packet_conf));
  packet_conf.lflen = 8;
  packet_conf.maxlen = (sizeof(tx_packet) - 1);
  packet_conf.statlen = 0;
  packet_conf.balen = 4;
  packet_conf.big_endian = true;
  packet_conf.whiteen = true;
  packet_conf.plen = NRF_RADIO_PREAMBLE_LENGTH_16BIT;
  total_payload_size = 2 + (packet_conf.balen + 1) + 1 + packet_conf.maxlen;
  nrf_radio_packet_configure(NRF_RADIO, &packet_conf);

  nrf_radio_mode_set(NRF_RADIO, RADIO_MODE);
  nrf_radio_txpower_set(NRF_RADIO, RADIO_TXPOWER_TXPOWER_Pos8dBm);

  frequency = CHAN_TO_FREQ(RADIO_CHANNEL);
  nrf_radio_frequency_set(NRF_RADIO, frequency);
  
  radio_disable();
  radio_enableRx();

  dk_leds_init(); // TODO: remove only for test
  dk_buttons_init(button_cb);

  IRQ_CONNECT(NRFX_IRQ_NUMBER_GET(NRF_TIMER_INST_GET(TIMER_INST_IDX)), IRQ_PRIO_LOWEST,
            NRFX_TIMER_INST_HANDLER_GET(TIMER_INST_IDX), 0, 0);

  uint32_t base_frequency = NRF_TIMER_BASE_FREQUENCY_GET(m_timer_inst.p_reg);
  nrfx_timer_config_t config = NRFX_TIMER_DEFAULT_CONFIG(base_frequency);
  config.bit_width = NRF_TIMER_BIT_WIDTH_32;
  config.p_context = "Some context";

  status = nrfx_timer_init(&m_timer_inst, &config, timer_handler);
  NRFX_ASSERT(status == NRFX_SUCCESS);
  
  nrfx_timer_clear(&m_timer_inst);

  // Success
  return 0;
}

void
hidBridgeDevInt_rfCtrl_sendData (uint8_t *p_data, uint16_t length)
{
  if ((mb_dataToSend == false) && (length < BUFF_SIZE))
  {
    tx_packet[LEN_OFFSET] = length;
    memcpy(&tx_packet[DATA_OFFSET], p_data, length);
    mb_dataToSend = true;
    // start transmission if radio already configure in tx mode
    if (true == mb_radioModeTX)
    {
      nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_START);      
    }
  }
  else 
  {
    log_error("RF interface busy or length to long");
  }
}

void
radio_handler (const void *context)
{
  const struct radio_test_config *config =
    (const struct radio_test_config *) context;

  if (nrf_radio_event_check(NRF_RADIO, NRF_RADIO_EVENT_CRCOK)) {
    nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_CRCOK);
    dk_set_led(0,false);
    if (false == mb_radioModeTX)
    {
      if (SYNC_PACKET == rx_packet[DATA_OFFSET])
      {
        startTimer (RX_DELAY_US);
        rx_packet_cnt++;
        if (rx_packet_cnt >= 1000)
        {
          log_info("SYNC 1s");
          rx_packet_cnt = 0;
        }
      }
      else
      {
        log_info("RX DATA");
      }
      dk_set_led(0,true);
    }
  }
  else if (nrf_radio_event_check(NRF_RADIO, NRF_RADIO_EVENT_END)) 
  {
    nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_END);
    mb_dataToSend = false;
    if (true == mb_radioModeTX)
    {
      tx_packet_cnt++;
    }
  }
  else if (nrf_radio_event_check(NRF_RADIO, NRF_RADIO_EVENT_READY)) 
  {
    nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_READY);
    dk_set_led(2,mb_radioModeTX);
  }
  else 
  {
    log_error("not handle event");
  }

}

/* Private functions --------------------------------------------------------*/
static void 
timer_handler (nrf_timer_event_t event_type, void * p_context)
{  
  if(event_type == NRF_TIMER_EVENT_COMPARE0)
  {
    char * p_msg = p_context;
    dk_set_led(1,(mb_radioModeTX));
    if (false == mb_radioModeTX)
    {
      startTimer (TX_DELAY_US);
      radio_disable();
      radio_enableTx();
      mb_radioModeTX = true;
    }
    else
    {
      radio_disable();
      radio_enableRx();          
      mb_radioModeTX = false;
    }
  }
}

static void 
clock_init (void)
{
  int err;
  int res;
  struct onoff_manager *clk_mgr;
  struct onoff_client clk_cli;

  clk_mgr = z_nrf_clock_control_get_onoff(CLOCK_CONTROL_NRF_SUBSYS_HF);
  if (!clk_mgr) {
    log_error("Unable to get the Clock manager");
    return;
  }

  sys_notify_init_spinwait(&clk_cli.notify);

  err = onoff_request(clk_mgr, &clk_cli);
  if (err < 0) {
    log_error("Clock request failed: %d", err);
    return;
  }

  do {
    err = sys_notify_fetch_result(&clk_cli.notify, &res);
    if (!err && res) {
      log_error("Clock could not be started: %d", res);
      return;
    }
  } while (err);

  log_info("Clock has started");
}


static void 
radio_disable (void)
{
  nrf_radio_shorts_set(NRF_RADIO, 0);
  nrf_radio_int_disable(NRF_RADIO, ~0);
  nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_DISABLED);

  nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_DISABLE);
  while (!nrf_radio_event_check(NRF_RADIO, NRF_RADIO_EVENT_DISABLED)) {
    /* Do nothing */ // TODO: not blocking fct !!! 
  }
  nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_DISABLED);

}

static void 
radio_enableTx (void)
{
  nrf_radio_packetptr_set(NRF_RADIO, tx_packet);

  // SHORT ready and start if data to send already configured
  if (mb_dataToSend == true)
  {
    nrf_radio_shorts_set(NRF_RADIO, NRF_RADIO_SHORT_READY_START_MASK);
  }
  
  nrf_radio_int_enable(NRF_RADIO, NRF_RADIO_INT_END_MASK);
  nrf_radio_int_enable(NRF_RADIO, NRF_RADIO_INT_READY_MASK);

  nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_TXEN);
}

static void 
radio_enableRx (void)
{
  nrf_radio_shorts_set(NRF_RADIO,
        NRF_RADIO_SHORT_READY_START_MASK |
        NRF_RADIO_SHORT_END_START_MASK);
  
  nrf_radio_packetptr_set(NRF_RADIO, rx_packet);
  
  nrf_radio_int_enable(NRF_RADIO, NRF_RADIO_INT_CRCOK_MASK);

  nrf_radio_int_enable(NRF_RADIO, NRF_RADIO_INT_READY_MASK);

  nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_RXEN);
}

static void
startTimer (uint32_t us_delay)
{
  uint32_t desired_ticks = nrfx_timer_us_to_ticks(&m_timer_inst, us_delay);

  nrfx_timer_clear(&m_timer_inst);

  nrfx_timer_extended_compare(&m_timer_inst, NRF_TIMER_CC_CHANNEL0, desired_ticks,
                              NRF_TIMER_SHORT_COMPARE0_STOP_MASK|NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, true);
                        
  nrfx_timer_enable(&m_timer_inst);
}

Parents
  • Hi,

    For us to help you with this in the best possible way, please list the following information:

    • SDK Version
    • Which sample do you use, if any?
    • Do you use custom hardware or code?

    Regards,
    Sigurd Hellesvik

  • Hello, 
    i use sdk 2.6.0 and dev kit nrf52840DK. 

    I started from the example radio_test, but I modified a lot. my files are attached to the first post.

  • And to make sure that I understand correctly, You are trying to implement your own radio protocol?

    In that case, I will not give my own ideas, but rather I think "Whatever Bluetooth LE does, that is probably some good ideas", so I asked ChatGPT:

    "how does bluetooth low energy make sure that messages does not corrupt? Provide references to documentation"
    ChatGPT

    Bluetooth Low Energy (BLE) ensures message integrity through several mechanisms:

    1. Cyclic Redundancy Check (CRC): Each packet includes a 24-bit CRC, which helps detect errors in the transmitted data.
    2. Error Detection and Correction: BLE employs error detection and correction techniques such as Forward Error Correction (FEC) and the use of redundancy in the packet structure.
    3. Adaptive Frequency Hopping (AFH): This technique minimizes interference by changing frequencies during communication, reducing the likelihood of data corruption.
    4. Encryption and Authentication: BLE uses encryption and authentication protocols to ensure data integrity and prevent tampering.

    For detailed information, you can refer to the official Bluetooth Core Specification:

    • Bluetooth Core Specification 5.3, particularly Volume 6, Part B, Section 3 (Link Layer).

    "

    Since it is ChatGPT, I suggest that you take the stuff with a pinch of salt.
    You could also try to look up what other radio protocols does, such as 802.15.4 or Wi-Fi.

    Does this answer your question?

    Regards,
    Sigurd Hellesvik

Reply
  • And to make sure that I understand correctly, You are trying to implement your own radio protocol?

    In that case, I will not give my own ideas, but rather I think "Whatever Bluetooth LE does, that is probably some good ideas", so I asked ChatGPT:

    "how does bluetooth low energy make sure that messages does not corrupt? Provide references to documentation"
    ChatGPT

    Bluetooth Low Energy (BLE) ensures message integrity through several mechanisms:

    1. Cyclic Redundancy Check (CRC): Each packet includes a 24-bit CRC, which helps detect errors in the transmitted data.
    2. Error Detection and Correction: BLE employs error detection and correction techniques such as Forward Error Correction (FEC) and the use of redundancy in the packet structure.
    3. Adaptive Frequency Hopping (AFH): This technique minimizes interference by changing frequencies during communication, reducing the likelihood of data corruption.
    4. Encryption and Authentication: BLE uses encryption and authentication protocols to ensure data integrity and prevent tampering.

    For detailed information, you can refer to the official Bluetooth Core Specification:

    • Bluetooth Core Specification 5.3, particularly Volume 6, Part B, Section 3 (Link Layer).

    "

    Since it is ChatGPT, I suggest that you take the stuff with a pinch of salt.
    You could also try to look up what other radio protocols does, such as 802.15.4 or Wi-Fi.

    Does this answer your question?

    Regards,
    Sigurd Hellesvik

Children
No Data
Related