void bootstrap() { #ifdef HAS_LCD lcd_write_string("NOISE"); #endif #if NUM_USERBUTTONS > 1 ubutton_register_callback(0, &userbutton_callback); ubutton_register_callback(1, &userbutton_callback); #endif prepare_channel_indexes(); hw_radio_init(NULL, NULL); fifo_init(&uart_rx_fifo, uart_rx_buffer, sizeof(uart_rx_buffer)); console_set_rx_interrupt_callback(&uart_rx_cb); console_rx_interrupt_enable(true); sched_register_task(&read_rssi); sched_register_task(&start_rx); sched_register_task(&process_uart_rx_fifo); timer_post_task_delay(&start_rx, TIMER_TICKS_PER_SEC * 3); sched_register_task((&execute_sensor_measurement)); timer_post_task_delay(&execute_sensor_measurement, TEMPERATURE_PERIOD); measureTemperature(); }
void led_on_callback() { led_on(0); timer_post_task_delay(&led_on_callback, TIMER_TICKS_PER_SEC); timer_post_task_delay(&led_off_callback, TIMER_TICKS_PER_SEC*0.050); log_print_string("Toggled on %d", 0); hw_watchdog_feed(); }
void bootstrap() { led_on(0); led_on(1); log_print_string("Device booted at time: %d\n", timer_get_counter_value()); console_print("Device Booted\r\n"); sched_register_task(&led_on_callback); sched_register_task(&led_off_callback); sched_register_task(&timer1_callback); timer_post_task_delay(&led_on_callback, TIMER_TICKS_PER_SEC); //timer_post_task_delay(&timer1_callback, 0x0000FFFF + (uint32_t)100); #if PLATFORM_NUM_BUTTONS > 0 int i= 0; for (i=0;i<PLATFORM_NUM_BUTTONS;i++) { ubutton_register_callback(i, &userbutton_callback); } #endif led_off(0); led_off(1); }
static void start_rx(hw_rx_cfg_t const* rx_cfg) { DPRINT("start_rx"); if (current_state == HW_RADIO_STATE_OFF) ezradio_hal_DeassertShutdown(); current_state = HW_RADIO_STATE_RX; configure_channel(&(rx_cfg->channel_id)); configure_syncword_class(rx_cfg->syncword_class, rx_cfg->channel_id.channel_header.ch_coding); rx_fifo_data_lenght = 0; if (rx_cfg->channel_id.channel_header.ch_coding == PHY_CODING_FEC_PN9) { ezradioStartRx(ez_channel_id, false); } else { ezradioStartRx(ez_channel_id, true); } DEBUG_RX_START(); if(rssi_valid_callback != 0) { timer_post_task_delay(&report_rssi, TIMER_TICKS_PER_SEC / 5000); } }
void timer1_callback() { led_toggle(1); timer_post_task_delay(&timer1_callback, 0x0000FFFF + (uint32_t)100); log_print_string("Toggled led %d", 1); console_print("Toggle led 1\r\n"); }
void bootstrap() { log_print_string("Device booted at time: %d\n", timer_get_counter_value()); hw_radio_init(p_alloc, p_free); hw_radio_set_rx(&rx_cfg, rx_callback, rssi_valid); NG(tx_buffer).radio_packet.length = sizeof(packet_struct_t) - sizeof(hw_radio_packet_t); NG(tx_buffer).radio_packet.tx_meta.tx_cfg.channel_id = rx_cfg.channel_id; NG(tx_buffer).radio_packet.tx_meta.tx_cfg.syncword_class = rx_cfg.syncword_class; NG(tx_buffer).radio_packet.tx_meta.tx_cfg.eirp = 0; NG(tx_buffer).src_node = hw_get_unique_id(); NG(tx_buffer).dst_node = 0xFFFF; NG(tx_buffer).counter = 0; sched_register_task(&send_packet); timer_post_task_delay(&send_packet, TIMER_TICKS_PER_SEC + (get_rnd() %TIMER_TICKS_PER_SEC)); // NG(status).is_rx = false; // NG(status).is_sleep = true; // NG(status).tx_busy = false; // NG(status).rx_busy = false; // sched_register_task(&poll_status); // sched_post_task(poll_status); }
void send_packet() { hw_radio_send_packet((hw_radio_packet_t*)(&NG(tx_buffer)), tx_callback); log_print_string("Sending packet with counter %u", NG(tx_buffer).counter); NG(tx_buffer).counter++; timer_post_task_delay(send_packet, TIMER_TICKS_PER_SEC + (get_rnd() %TIMER_TICKS_PER_SEC)); }
void execute_sensor_measurement() { #if HW_NUM_LEDS >= 1 led_toggle(0); #endif // use the counter value for now instead of 'real' sensor uint32_t val = timer_get_counter_value(); // file 0x40 is configured to use D7AActP trigger an ALP action which // broadcasts this file data on Access Class 0 fs_write_file(0x40, 0, (uint8_t*)&val, 4); timer_post_task_delay(&execute_sensor_measurement, REPORTING_INTERVAL_TICKS); }
void led_on_callback() { led_toggle(0); timer_post_task_delay(&led_on_callback, TIMER_TICKS_PER_SEC * 70); //timer_post_task_delay(&led_off_callback, TIMER_TICKS_PER_SEC*0.050); log_print_string("Toggled on %d", 0); console_print("Toggle led 0\r\n"); hw_watchdog_feed(); }
void read_rssi() { timestamped_rssi_t rssi_measurement; rssi_measurement.tick = timer_get_counter_value(); rssi_measurement.rssi = hw_radio_get_rssi(); rssi_measurements[rssi_measurements_index] = rssi_measurement; rssi_measurements_index++; if(rssi_measurements_index < 1000) timer_post_task_delay(&read_rssi, 1); // TODO delay else log_print_string("done"); }
void execute_sensor_measurement() { #ifdef PLATFORM_EFM32GG_STK3700 float internal_temp = hw_get_internal_temperature(); lcd_write_temperature(internal_temp*10, 1); uint32_t vdd = hw_get_battery(); fs_write_file(SENSOR_FILE_ID, 0, (uint8_t*)&internal_temp, sizeof(internal_temp)); // File 0x40 is configured to use D7AActP trigger an ALP action which broadcasts this file data on Access Class 0 #endif #if (defined PLATFORM_EFM32HG_STK3400 || defined PLATFORM_EZR32LG_WSTK6200A) char str[30]; float internal_temp = hw_get_internal_temperature(); sprintf(str, "Int T: %2d.%d C", (int)internal_temp, (int)(internal_temp*10)%10); lcd_write_line(2,str); log_print_string(str); uint32_t rhData; uint32_t tData; getHumidityAndTemperature(&rhData, &tData); sprintf(str, "Ext T: %d.%d C", (tData/1000), (tData%1000)/100); lcd_write_line(3,str); log_print_string(str); sprintf(str, "Ext H: %d.%d", (rhData/1000), (rhData%1000)/100); lcd_write_line(4,str); log_print_string(str); uint32_t vdd = hw_get_battery(); sprintf(str, "Batt %d mV", vdd); lcd_write_line(5,str); log_print_string(str); //TODO: put sensor values in array uint8_t sensor_values[8]; uint16_t *pointer = (uint16_t*) sensor_values; *pointer++ = (uint16_t) (internal_temp * 10); *pointer++ = (uint16_t) (tData /100); *pointer++ = (uint16_t) (rhData /100); *pointer++ = (uint16_t) (vdd /10); fs_write_file(SENSOR_FILE_ID, 0, (uint8_t*)&sensor_values,8); #endif timer_post_task_delay(&execute_sensor_measurement, SENSOR_UPDATE); }
static void process_uart_rx_fifo() { if(fifo_get_size(&uart_rx_fifo) >= COMMAND_SIZE) { uint8_t received_cmd[COMMAND_SIZE]; fifo_pop(&uart_rx_fifo, received_cmd, COMMAND_SIZE); if(strncmp(received_cmd, COMMAND_CHAN, COMMAND_SIZE) == 0) { process_command_chan(); } else if(strncmp(received_cmd, COMMAND_TRAN, COMMAND_SIZE) == 0) { while(fifo_get_size(&uart_rx_fifo) < COMMAND_TRAN_PARAM_SIZE); char param[COMMAND_TRAN_PARAM_SIZE]; fifo_pop(&uart_rx_fifo, param, COMMAND_TRAN_PARAM_SIZE); tx_packet_delay_s = atoi(param); DPRINT("performing TRAN command with %d tx_packet_delay_s\r\n", tx_packet_delay_s); stop(); is_mode_rx = false; current_state = STATE_RUNNING; sched_post_task(&start); } else if(strncmp(received_cmd, COMMAND_RECV, COMMAND_SIZE) == 0) { DPRINT("entering RECV mode\r\n"); stop(); is_mode_rx = true; current_state = STATE_RUNNING; sched_post_task(&start); } else if(strncmp(received_cmd, COMMAND_RSET, COMMAND_SIZE) == 0) { DPRINT("resetting...\r\n"); hw_reset(); } else { char err[40]; DPRINT("ERROR invalid command %.4s\n\r", received_cmd); } fifo_clear(&uart_rx_fifo); } timer_post_task_delay(&process_uart_rx_fifo, TIMER_TICKS_PER_SEC); }
void bootstrap() { led_on(0); led_on(1); log_print_string("Device booted at time: %d\n", timer_get_counter_value()); sched_register_task(&led_on_callback); sched_register_task(&led_off_callback); sched_register_task(&timer1_callback); timer_post_task_delay(&led_on_callback, TIMER_TICKS_PER_SEC); timer_post_task_delay(&timer1_callback, 0x0000FFFF + (uint32_t)100); #if NUM_USERBUTTONS > 0 ubutton_register_callback(0, &userbutton_callback); ubutton_register_callback(1, &userbutton_callback); #endif led_off(0); led_off(1); }
void read_rssi() { timestamped_rssi_t rssi_measurement; rssi_measurement.tick = timer_get_counter_value(); char rssi_samples_str[5 * RSSI_SAMPLES_PER_MEASUREMENT] = ""; int16_t max_rssi_sample = -200; for(int i = 0; i < RSSI_SAMPLES_PER_MEASUREMENT; i++) { rssi_measurement.rssi[i] = hw_radio_get_rssi(); if(rssi_measurement.rssi[i] > max_rssi_sample) max_rssi_sample = rssi_measurement.rssi[i]; sprintf(rssi_samples_str + (i * 5), ",%04i", rssi_measurement.rssi[i]); // TODO delay? } char str[80]; char channel_str[8] = ""; channel_id_to_string(&rx_cfg.channel_id, channel_str, sizeof(channel_str)); lcd_write_string(channel_str); sprintf(str, "%7s,%i%s\n", channel_str, rssi_measurement.tick, rssi_samples_str); console_print(str); #ifdef PLATFORM_EFM32GG_STK3700 //lcd_all_on(); lcd_write_number(max_rssi_sample); #elif defined HAS_LCD sprintf(str, "%7s,%d\n", channel_str, max_rssi_sample); lcd_write_string(str); #endif if(!use_manual_channel_switching) { switch_next_channel(); sched_post_task(&start_rx); } else { sched_post_task(&process_uart_rx_fifo); // check for UART commands first uint16_t delay = rand() % 5000; timer_post_task_delay(&read_rssi, delay); } hw_watchdog_feed(); }
static void process_uart_rx_fifo() { if(fifo_get_size(&uart_rx_fifo) >= COMMAND_SIZE) { uint8_t received_cmd[COMMAND_SIZE]; fifo_pop(&uart_rx_fifo, received_cmd, COMMAND_SIZE); if(strncmp(received_cmd, COMMAND_CHAN, COMMAND_SIZE) == 0) { process_command_chan(); } else if(strncmp(received_cmd, COMMAND_TRAN, COMMAND_SIZE) == 0) { while(fifo_get_size(&uart_rx_fifo) < COMMAND_TRAN_PARAM_SIZE); char param[COMMAND_TRAN_PARAM_SIZE]; fifo_pop(&uart_rx_fifo, param, COMMAND_TRAN_PARAM_SIZE); tx_packet_delay_s = atoi(param); stop(); is_mode_rx = false; current_state = STATE_RUNNING; sched_post_task(&start); } else if(strncmp(received_cmd, COMMAND_RECV, COMMAND_SIZE) == 0) { stop(); is_mode_rx = true; current_state = STATE_RUNNING; sched_post_task(&start); } else if(strncmp(received_cmd, COMMAND_RSET, COMMAND_SIZE) == 0) { hw_reset(); } else { char err[40]; snprintf(err, sizeof(err), "ERROR invalid command %.4s\n", received_cmd); uart_transmit_string(err); } fifo_clear(&uart_rx_fifo); } timer_post_task_delay(&process_uart_rx_fifo, TIMER_TICKS_PER_SEC); }
void bootstrap() { DPRINT("Device booted at time: %d\n", timer_get_counter_value()); // TODO not printed for some reason, debug later #ifdef HAS_LCD lcd_write_string("cont tx"); #endif switch(current_channel_class) { // TODO only 433 for now case PHY_CLASS_NORMAL_RATE: channel_count = NORMAL_RATE_CHANNEL_COUNT; realloc(channel_indexes, channel_count); for(int i = 0; i < channel_count; i++) channel_indexes[i] = i * 8; break; case PHY_CLASS_LO_RATE: channel_count = LO_RATE_CHANNEL_COUNT; realloc(channel_indexes, channel_count); for(int i = 0; i < channel_count; i++) channel_indexes[i] = i; break; } #if NUM_USERBUTTONS > 1 ubutton_register_callback(0, &userbutton_callback); ubutton_register_callback(1, &userbutton_callback); #endif hw_radio_init(NULL, NULL); sched_register_task(&start); timer_post_task_delay(&start, TIMER_TICKS_PER_SEC * 5); }
void bootstrap() { DPRINT("Device booted at time: %d\n", timer_get_counter_value()); // TODO not printed for some reason, debug later #ifdef HAS_LCD lcd_write_string("cont TX \n"); #endif switch(current_channel_class) { case PHY_CLASS_NORMAL_RATE: channel_count = NORMAL_RATE_CHANNEL_COUNT; realloc(channel_indexes, channel_count); for(int i = 0; i < channel_count; i++) channel_indexes[i] = i * 8; break; case PHY_CLASS_LO_RATE: channel_count = LO_RATE_CHANNEL_COUNT; realloc(channel_indexes, channel_count); for(int i = 0; i < channel_count; i++) channel_indexes[i] = i; break; } #if PLATFORM_NUM_BUTTONS > 1 ubutton_register_callback(0, &userbutton_callback); ubutton_register_callback(1, &userbutton_callback); #endif hw_radio_init(&alloc_packet_callback, &release_packet_callback); sched_register_task(&start); timer_post_task_delay(&start, 500); }
static void tx_callback(hw_radio_packet_t* tx_packet) { log_print_string("Sent packet with counter %u", NG(tx_buffer).counter); timer_post_task_delay(send_packet, TIMER_TICKS_PER_SEC + (get_rnd() %TIMER_TICKS_PER_SEC)); }
void rssi_valid(int16_t cur_rssi) { timer_post_task_delay(&read_rssi, 1); // TODO delay }
void execute_sensor_measurement() { timer_post_task_delay(&execute_sensor_measurement, TEMPERATURE_PERIOD); measureTemperature(); }
static void packet_transmitted(hw_radio_packet_t* hw_radio_packet) { assert(dll_state == DLL_STATE_TX_FOREGROUND); switch_state(DLL_STATE_TX_FOREGROUND_COMPLETED); DPRINT("Transmitted packet with length = %i", hw_radio_packet->length); packet_t* packet = packet_queue_find_packet(hw_radio_packet); d7anp_signal_packet_transmitted(packet); if(process_received_packets_after_tx) { sched_post_task(&process_received_packets); process_received_packets_after_tx = false; } #ifdef RESPONDER_USE_FG_SCAN_OUTSIDE_TRANSACTION // TODO validate if still needed, if yes: needs to be tested /* * Resume the FG scan only after an unicast packet, otherwise, wait the * response period expiration. */ if (resume_fg_scan && packet->dll_header.control_target_address_set) { switch_state(DLL_STATE_FOREGROUND_SCAN); hw_rx_cfg_t rx_cfg = (hw_rx_cfg_t){ .channel_id.channel_header = current_access_profile->subbands[0].channel_header, .channel_id.center_freq_index = current_access_profile->subbands[0].channel_index_start, .syncword_class = PHY_SYNCWORD_CLASS1, }; hw_radio_set_rx(&rx_cfg, &packet_received, NULL); resume_fg_scan = false; } #else if (resume_fg_scan) { switch_state(DLL_STATE_FOREGROUND_SCAN); hw_rx_cfg_t rx_cfg = (hw_rx_cfg_t){ .channel_id.channel_header = current_access_profile->subbands[0].channel_header, .channel_id.center_freq_index = current_access_profile->subbands[0].channel_index_start, .syncword_class = PHY_SYNCWORD_CLASS1, }; hw_radio_set_rx(&rx_cfg, &packet_received, NULL); resume_fg_scan = false; } #endif } static void cca_rssi_valid(int16_t cur_rssi) { // When the radio goes back to Rx state, the rssi_valid callback may be still set. Skip it in this case if (dll_state != DLL_STATE_CCA1 && dll_state != DLL_STATE_CCA2) return; if (cur_rssi <= E_CCA) { if(dll_state == DLL_STATE_CCA1) { DPRINT("CCA1 RSSI: %d", cur_rssi); switch_state(DLL_STATE_CCA2); timer_post_task_delay(&execute_cca, 5); return; } else if(dll_state == DLL_STATE_CCA2) { // OK, send packet DPRINT("CCA2 RSSI: %d", cur_rssi); DPRINT("CCA2 succeeded, transmitting ..."); // log_print_data(current_packet->hw_radio_packet.data, current_packet->hw_radio_packet.length + 1); // TODO tmp switch_state(DLL_STATE_TX_FOREGROUND); d7anp_signal_packet_csma_ca_insertion_completed(true); error_t err = hw_radio_send_packet(¤t_packet->hw_radio_packet, &packet_transmitted); assert(err == SUCCESS); if (!resume_fg_scan) hw_radio_set_idle(); // ensure radio goes back to IDLE after transmission instead of to RX return; } } else { DPRINT("Channel not clear, RSSI: %i", cur_rssi); switch_state(DLL_STATE_CSMA_CA_RETRY); execute_csma_ca(); //switch_state(DLL_STATE_CCA_FAIL); //d7atp_signal_packet_csma_ca_insertion_completed(false); } } static void execute_cca() { assert(dll_state == DLL_STATE_CCA1 || dll_state == DLL_STATE_CCA2); hw_rx_cfg_t rx_cfg =(hw_rx_cfg_t){ .channel_id.channel_header = current_access_profile->subbands[0].channel_header, .channel_id.center_freq_index = current_access_profile->subbands[0].channel_index_start, .syncword_class = PHY_SYNCWORD_CLASS1, }; hw_radio_set_rx(&rx_cfg, NULL, &cca_rssi_valid); } static uint16_t calculate_tx_duration() { int data_rate = 6; // Normal rate: 6.9 bytes/tick // TODO select correct subband switch (current_access_profile->subbands[0].channel_header.ch_class) { case PHY_CLASS_LO_RATE: data_rate = 1; // Lo Rate: 1.2 bytes/tick break; case PHY_CLASS_HI_RATE: data_rate = 20; // High rate: 20.83 byte/tick } uint16_t duration = (current_packet->hw_radio_packet.length / data_rate) + 1; return duration; }
static void execute_csma_ca() { // TODO generate random channel queue //hw_radio_set_rx(NULL, NULL, NULL); // put radio in RX but disable callbacks to make sure we don't receive packets when in this state // TODO use correct rx cfg + it might be interesting to switch to idle first depending on calculated offset uint16_t tx_duration = calculate_tx_duration(); timer_tick_t Tc = CONVERT_TO_TI(current_packet->d7atp_tc); switch (dll_state) { case DLL_STATE_CSMA_CA_STARTED: { dll_tca = Tc - tx_duration; dll_cca_started = timer_get_counter_value(); DPRINT("Tca= %i = %i - %i", dll_tca, Tc, tx_duration); #ifndef FRAMEWORK_TIMER_RESET_COUNTER // Adjust TCA value according the time already elapsed in the response period if (tc_starting_time) // TODO how do manage tc_starting_time? not set for now { dll_tca -= dll_cca_started - tc_starting_time; DPRINT("Adjusted Tca= %i = %i - %i", dll_tca, dll_cca_started, tc_starting_time); } #endif if (dll_tca <= 0) { DPRINT("Tca negative, CCA failed"); // Let the upper layer decide eventually to change the channel in order to get a chance a send this frame switch_state(DLL_STATE_IDLE); d7anp_signal_packet_csma_ca_insertion_completed(false); break; } uint16_t t_offset = 0; csma_ca_mode_t csma_ca_mode = current_access_profile->control_csma_ca_mode; // TODO overrule mode to UNC for subsequent requests by the requester, or a single response to a unicast request switch(csma_ca_mode) { case CSMA_CA_MODE_UNC: // no delay dll_slot_duration = 0; break; case CSMA_CA_MODE_AIND: // TODO implement AIND { dll_slot_duration = tx_duration; // no initial delay break; } case CSMA_CA_MODE_RAIND: // TODO implement RAIND { dll_slot_duration = tx_duration; uint16_t max_nr_slots = dll_tca / tx_duration; uint16_t slots_wait = get_rnd() % max_nr_slots; t_offset = slots_wait * tx_duration; break; } case CSMA_CA_MODE_RIGD: // TODO implement RAIND { dll_rigd_n = 0; dll_tca0 = dll_tca; dll_slot_duration = (uint16_t) ((double)dll_tca0) / (2 << (dll_rigd_n)); t_offset = get_rnd() % dll_slot_duration; break; } } DPRINT("slot duration: %i t_offset: %i csma ca mode: %i", dll_slot_duration, t_offset, csma_ca_mode); dll_to = dll_tca - t_offset; if (t_offset > 0) { switch_state(DLL_STATE_CCA1); timer_post_task_delay(&execute_cca, t_offset); } else { switch_state(DLL_STATE_CCA1); sched_post_task(&execute_cca); } break; } case DLL_STATE_CSMA_CA_RETRY: { int32_t cca_duration = timer_get_counter_value() - dll_cca_started; dll_to -= cca_duration; DPRINT("RETRY dll_to = %i < %i ", dll_to, t_g); if (dll_to < t_g) { switch_state(DLL_STATE_CCA_FAIL); sched_post_task(&execute_csma_ca); break; } dll_tca = dll_to; dll_cca_started = timer_get_counter_value(); uint16_t t_offset = 0; switch(current_access_profile->control_csma_ca_mode) { case CSMA_CA_MODE_AIND: case CSMA_CA_MODE_RAIND: { uint16_t max_nr_slots = dll_tca / tx_duration; uint16_t slots_wait = get_rnd() % max_nr_slots; t_offset = slots_wait * tx_duration; break; } case CSMA_CA_MODE_RIGD: { dll_rigd_n++; dll_slot_duration = (uint16_t) ((double)dll_tca0) / (2 << (dll_rigd_n+1)); if(dll_slot_duration != 0) // TODO can be 0, validate t_offset = get_rnd() % dll_slot_duration; else t_offset = 0; DPRINT("slot duration: %i", dll_slot_duration); break; } } DPRINT("t_offset: %i", t_offset); dll_to = dll_tca - t_offset; if (t_offset > 0) { timer_post_task_delay(&execute_csma_ca, t_offset); } else { switch_state(DLL_STATE_CCA1); sched_post_task(&execute_cca); } break; } case DLL_STATE_CCA_FAIL: { // TODO hw_radio_set_idle(); switch_state(DLL_STATE_IDLE); d7anp_signal_packet_csma_ca_insertion_completed(false); if (process_received_packets_after_tx) { sched_post_task(&process_received_packets); process_received_packets_after_tx = false; } if (resume_fg_scan) { switch_state(DLL_STATE_FOREGROUND_SCAN); hw_rx_cfg_t rx_cfg = (hw_rx_cfg_t){ .channel_id.channel_header = current_access_profile->subbands[0].channel_header, .channel_id.center_freq_index = current_access_profile->subbands[0].channel_index_start, .syncword_class = PHY_SYNCWORD_CLASS1, }; hw_radio_set_rx(&rx_cfg, &packet_received, NULL); resume_fg_scan = false; } break; } } } void dll_execute_scan_automation() { uint8_t scan_access_class = fs_read_dll_conf_active_access_class(); if(active_access_class != scan_access_class) { fs_read_access_class(scan_access_class, &scan_access_profile); active_access_class = scan_access_class; } current_access_profile = &scan_access_profile; if(current_access_profile->control_scan_type_is_foreground && current_access_profile->control_number_of_subbands > 0) // TODO background scan { assert(current_access_profile->control_number_of_subbands == 1); // TODO multiple not supported switch_state(DLL_STATE_SCAN_AUTOMATION); hw_rx_cfg_t rx_cfg = { .channel_id = { .channel_header = current_access_profile->subbands[0].channel_header, .center_freq_index = current_access_profile->subbands[0].channel_index_start }, .syncword_class = PHY_SYNCWORD_CLASS1 };