void configure_radio(modulation_t mod){ #if defined USE_SI4460 || defined USE_SX127X if(mod == MODULATION_CW){ hw_radio_continuous_tx(&tx_cfg, true); } else { hw_radio_continuous_tx(&tx_cfg, false); } #elif defined USE_CC1101 hw_radio_set_rx(&tx_cfg, NULL, NULL); // we 'misuse' hw_radio_set_rx to configure the channel (using the public API) hw_radio_set_idle(); // go straight back to idle /* Configure */ cc1101_interface_write_single_patable(current_eirp_level); //cc1101_interface_write_single_reg(0x08, 0x22); // PKTCTRL0 random PN9 mode + disable data whitening cc1101_interface_write_single_reg(0x08, 0x22); // PKTCTRL0 disable data whitening, continious preamble if(mod == MODULATION_CW) { cc1101_interface_write_single_reg(0x12, 0x30); // MDMCFG2 } else { cc1101_interface_write_single_reg(0x12, 0x12); // MDMCFG2 } cc1101_interface_strobe(0x32); // strobe calibrate #endif }
static void stop() { // make sure to cancel tasks which might me pending already hw_radio_set_idle(); if(is_mode_rx) { sched_cancel_task(&start_rx); } else { sched_cancel_task(&transmit_packet); } }
static void start() { counter = 0; missed_packets_counter = 0; received_packets_counter = 0; uint8_t lcd_line = 0; switch(current_state) { case STATE_CONFIG_DIRECTION: is_mode_rx? sprintf(lcd_msg, "PER RX") : sprintf(lcd_msg, "PER TX"); break; case STATE_CONFIG_DATARATE: lcd_line = 1; switch(current_channel_id.channel_header.ch_class) { case PHY_CLASS_LO_RATE: sprintf(lcd_msg, "LO-RATE"); break; case PHY_CLASS_NORMAL_RATE: sprintf(lcd_msg, "NOR-RATE"); break; case PHY_CLASS_HI_RATE: sprintf(lcd_msg, "HI-RATE"); break; } break; case STATE_RUNNING: lcd_line = 2; if(is_mode_rx) { sprintf(lcd_msg, "RUN RX"); //lcd_write_string(lcd_msg); console_printf("%s,%s,%s,%s,%s,%s\n", "channel_id", "counter", "rssi", "tx_id", "rx_id", "timestamp"); rx_cfg.channel_id = current_channel_id; timer_post_task(&start_rx, TIMER_TICKS_PER_SEC * 5); } else { hw_radio_set_idle(); sprintf(lcd_msg, "RUN TX"); //lcd_write_string(lcd_msg); timer_post_task(&transmit_packet, TIMER_TICKS_PER_SEC * 5); } break; } #ifdef PLATFORM_EFM32GG_STK3700 lcd_write_string(lcd_msg); #else lcd_write_line(lcd_line, lcd_msg); #endif }
static void start() { counter = 0; missed_packets_counter = 0; received_packets_counter = 0; switch(current_state) { case STATE_CONFIG_DIRECTION: is_mode_rx? sprintf(lcd_msg, "PER RX") : sprintf(lcd_msg, "PER TX"); break; case STATE_CONFIG_DATARATE: switch(current_channel_id.channel_header.ch_class) { case PHY_CLASS_LO_RATE: sprintf(lcd_msg, "LO-RATE"); break; case PHY_CLASS_NORMAL_RATE: sprintf(lcd_msg, "NOR-RATE"); break; case PHY_CLASS_HI_RATE: sprintf(lcd_msg, "HI-RATE"); break; } break; case STATE_RUNNING: if(is_mode_rx) { sprintf(lcd_msg, "RUN RX"); lcd_write_string(lcd_msg); sprintf(record, "%s,%s,%s,%s,%s,%s\n", "channel_id", "counter", "rssi", "tx_id", "rx_id", "timestamp"); uart_transmit_message(record, strlen(record)); rx_cfg.channel_id = current_channel_id; timer_post_task(&start_rx, TIMER_TICKS_PER_SEC * 5); } else { hw_radio_set_idle(); sprintf(lcd_msg, "RUN TX"); lcd_write_string(lcd_msg); timer_post_task(&transmit_packet, TIMER_TICKS_PER_SEC * 5); } break; } lcd_write_string(lcd_msg); }
void start() { hw_rx_cfg_t rx_cfg; rx_cfg.channel_id.channel_header.ch_coding = PHY_CODING_PN9; rx_cfg.channel_id.channel_header.ch_class = current_channel_class; rx_cfg.channel_id.channel_header.ch_freq_band = current_channel_band; rx_cfg.channel_id.center_freq_index = channel_indexes[current_channel_indexes_index]; #ifdef HAS_LCD char string[10] = ""; char rate; char band[3]; switch(current_channel_class) { case PHY_CLASS_LO_RATE: rate = 'L'; break; case PHY_CLASS_NORMAL_RATE: rate = 'N'; break; case PHY_CLASS_HI_RATE: rate = 'H'; break; } switch(current_channel_band) { case PHY_BAND_433: strncpy(band, "433", sizeof(band)); break; case PHY_BAND_868: strncpy(band, "868", sizeof(band)); break; case PHY_BAND_915: strncpy(band, "915", sizeof(band)); break; } sprintf(string, "%.3s%c-%i", band, rate, rx_cfg.channel_id.center_freq_index), lcd_write_string(string); #endif hw_radio_set_rx(&rx_cfg, NULL, &rssi_valid_cb); // we 'misuse' hw_radio_set_rx to configure the channel (using the public API) hw_radio_set_idle(); // go straight back to idle cc1101_interface_write_single_reg(0x08, 0x22); // PKTCTRL0 random PN9 mode + disable data whitening //cc1101_interface_write_single_reg(0x12, 0x30); // MDMCFG2: use OOK modulation to clearly view centre freq on spectrum analyzer, comment for GFSK cc1101_interface_write_single_patable(0xc0); // 10dBm TX EIRP cc1101_interface_strobe(0x35); // strobe TX }
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; }