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) { // TODO calculate/predict rssi response time and wait until valid. For now we wait 200 us. hw_busy_wait(200); rssi_valid_callback(hw_radio_get_rssi()); } }
error_t hw_radio_init(alloc_packet_callback_t alloc_packet_cb, release_packet_callback_t release_packet_cb) { alloc_packet_callback = alloc_packet_cb; release_packet_callback = release_packet_cb; current_state = HW_RADIO_STATE_IDLE; cc1101_interface_init(&end_of_packet_isr); cc1101_interface_reset_radio_core(); cc1101_interface_write_rfsettings(&rf_settings); DPRINT("RF settings:"); uint8_t* p = (uint8_t*) &rf_settings; uint8_t i; for(i = 0; i < sizeof(RF_SETTINGS); i++) { DPRINT("\t0x%02X", p[i]); } // configure default channel, eirp and syncword configure_channel(¤t_channel_id); configure_eirp(current_eirp); configure_syncword_class(current_syncword_class); }
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); } }
error_t hw_radio_send_packet(hw_radio_packet_t* packet, tx_packet_callback_t tx_cb, uint16_t eta, uint8_t dll_header_bg_frame[2]) { assert(eta == 0); // advertising not implemented on si4460 for now // TODO error handling EINVAL, ESIZE, EOFF if(current_state == HW_RADIO_STATE_TX) return EBUSY; uint8_t data_length = packet->length + 1; if (packet->tx_meta.tx_cfg.channel_id.channel_header.ch_coding == PHY_CODING_FEC_PN9) { DPRINT("Original packet: %d", data_length); DPRINT_DATA(packet->data, data_length); data_length = fec_encode(packet->data, data_length); DPRINT("Encoded packet: %d", data_length); DPRINT_DATA(packet->data, data_length); } else { if (has_hardware_crc) data_length -= 2; } tx_packet_callback = tx_cb; if(current_state == HW_RADIO_STATE_RX) { //pending_rx_cfg.channel_id = current_channel_id; //pending_rx_cfg.syncword_class = current_syncword_class; should_rx_after_tx_completed = true; } current_state = HW_RADIO_STATE_TX; current_packet = packet; DPRINT("Data to TX Fifo:"); DPRINT_DATA(packet->data, data_length); DPRINT("TX ch header=%x, ind=%i", packet->tx_meta.tx_cfg.channel_id.channel_header_raw, packet->tx_meta.tx_cfg.channel_id.center_freq_index); configure_channel((channel_id_t*)&(packet->tx_meta.tx_cfg.channel_id)); configure_eirp(packet->tx_meta.tx_cfg.eirp); configure_syncword_class(current_packet->tx_meta.tx_cfg.syncword_class, current_packet->tx_meta.tx_cfg.channel_id.channel_header.ch_coding); DEBUG_TX_START(); DEBUG_RX_END(); ezradioStartTx(packet, ez_channel_id, should_rx_after_tx_completed, data_length); return SUCCESS; }
error_t hw_radio_send_packet(hw_radio_packet_t* packet, tx_packet_callback_t tx_cb) { // TODO error handling EINVAL, ESIZE, EOFF if(current_state == HW_RADIO_STATE_TX) return EBUSY; uint8_t data_length = packet->length + 1; if (packet->tx_meta.tx_cfg.channel_id.channel_header.ch_coding == PHY_CODING_FEC_PN9) { DPRINT(LOG_STACK_PHY, "Original packet: %d", data_length); DPRINT_DATA(packet->data, data_length); data_length = fec_encode(packet->data, data_length); DPRINT(LOG_STACK_PHY, "Encoded packet: %d", data_length); DPRINT_DATA(packet->data, data_length); } else { if (has_hardware_crc) data_length -= 2; } tx_packet_callback = tx_cb; if(current_state == HW_RADIO_STATE_RX) { //pending_rx_cfg.channel_id = current_channel_id; //pending_rx_cfg.syncword_class = current_syncword_class; should_rx_after_tx_completed = true; } current_state = HW_RADIO_STATE_TX; current_packet = packet; DPRINT(LOG_STACK_PHY, "Data to TX Fifo:"); DPRINT_DATA(packet->data, data_length); configure_channel((channel_id_t*)&(packet->tx_meta.tx_cfg.channel_id)); configure_eirp(packet->tx_meta.tx_cfg.eirp); configure_syncword_class(current_packet->tx_meta.tx_cfg.syncword_class, current_packet->tx_meta.tx_cfg.channel_id.channel_header.ch_coding); DEBUG_TX_START(); DEBUG_RX_END(); ezradioStartTx(packet, ez_channel_id, should_rx_after_tx_completed, data_length); return SUCCESS; }
error_t hw_radio_init(alloc_packet_callback_t alloc_packet_cb, release_packet_callback_t release_packet_cb) { /* EZRadio response structure union */ ezradio_cmd_reply_t ezradioReply; alloc_packet_callback = alloc_packet_cb; release_packet_callback = release_packet_cb; current_state = HW_RADIO_STATE_UNKOWN; /* Initialize EZRadio device. */ DPRINT("INIT ezradioInit"); ezradioInit(&ezradio_int_callback); /* Print EZRadio device number. */ DPRINT("INIT ezradio_part_info"); ezradio_part_info(&ezradioReply); DPRINT(" Device: Si%04x\n\n", ezradioReply.PART_INFO.PART); /* Enable Packet Trace Interface */ //ezradio_set_property(RADIO_CONFIG_SET_PROPERTY_PTI_ENABLE); /* Fix registers not correct set by radio configurator */ // latch on sync word detect - currently no threshold comparison (todo: optimize) //ezradio_set_property(RADIO_CONFIG_SET_PROPERTY_MODEM_RSSI_CONTROL); // disable jump detection (todo: optimize) //ezradio_set_property(RADIO_CONFIG_SET_PROPERTY_MODEM_RSSI_CONTROL2); /* Reset radio fifos. */ DPRINT("INIT ezradioResetTRxFifo"); ezradioResetTRxFifo(); // configure default channel, eirp and syncword configure_channel(¤t_channel_id); configure_eirp(current_eirp); configure_syncword_class(current_rx_cfg.syncword_class, current_channel_id.channel_header.ch_coding); sched_register_task((&report_rssi)); switch_to_idle_mode(); }
static void start_rx(hw_rx_cfg_t const* rx_cfg) { current_state = HW_RADIO_STATE_RX; cc1101_interface_strobe(RF_SFRX); configure_channel(&(rx_cfg->channel_id)); configure_syncword_class(rx_cfg->syncword_class); cc1101_interface_write_single_reg(PKTLEN, 0xFF); if(rx_packet_callback != 0) // when rx callback not set we ignore received packets cc1101_interface_set_interrupts_enabled(true); cc1101_interface_strobe(RF_SRX); if(rssi_valid_callback != 0) { // TODO calculate/predict rssi response time (see DN505) // and wait until valid. For now we wait 200 us. hw_busy_wait(200); rssi_valid_callback(hw_radio_get_rssi()); } }
error_t hw_radio_send_packet(hw_radio_packet_t* packet, tx_packet_callback_t tx_cb) { // TODO error handling EINVAL, ESIZE, EOFF if(current_state == HW_RADIO_STATE_TX) return EBUSY; assert(packet->length < 63); // long packets not yet supported tx_packet_callback = tx_cb; if(current_state == HW_RADIO_STATE_RX) { pending_rx_cfg.channel_id = current_channel_id; pending_rx_cfg.syncword_class = current_syncword_class; should_rx_after_tx_completed = true; } current_state = HW_RADIO_STATE_TX; current_packet = packet; cc1101_interface_strobe(RF_SIDLE); cc1101_interface_strobe(RF_SFTX); #ifdef FRAMEWORK_LOG_ENABLED // TODO more granular log_print_stack_string(LOG_STACK_PHY, "Data to TX Fifo:"); log_print_data(packet->data, packet->length + 1); #endif configure_channel((channel_id_t*)&(current_packet->tx_meta.tx_cfg.channel_id)); configure_eirp(current_packet->tx_meta.tx_cfg.eirp); configure_syncword_class(current_packet->tx_meta.tx_cfg.syncword_class); cc1101_interface_write_burst_reg(TXFIFO, packet->data, packet->length + 1); cc1101_interface_set_interrupts_enabled(true); cc1101_interface_strobe(RF_STX); return SUCCESS; }