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
}
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 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());
    }
}
static void configure_channel(const channel_id_t* channel_id)
{
    // only change settings if channel_id changed compared to current config
    if(!hw_radio_channel_ids_equal(channel_id, &current_channel_id))
    {
        assert(channel_id->channel_header.ch_coding == PHY_CODING_PN9); // TODO implement other codings
        // TODO assert valid center freq index

        memcpy(&current_channel_id, channel_id, sizeof(channel_id_t)); // cache new settings

        // TODO preamble size depends on channel class

        // set freq band
        DPRINT("Set frequency band index: %d", channel_id->channel_header.ch_freq_band);

        // TODO validate
        switch(channel_id->channel_header.ch_freq_band)
        {
        // TODO calculate depending on rate and channr
        case PHY_BAND_433:
            cc1101_interface_write_single_reg(FREQ2, RADIO_FREQ2(RADIO_FREQ_433_NORMAL_RATE));
            cc1101_interface_write_single_reg(FREQ1, RADIO_FREQ1(RADIO_FREQ_433_NORMAL_RATE));
            cc1101_interface_write_single_reg(FREQ0, RADIO_FREQ0(RADIO_FREQ_433_NORMAL_RATE));
            break;
        case PHY_BAND_868_1: // TODO 868_2
            cc1101_interface_write_single_reg(FREQ2, RADIO_FREQ2(RADIO_FREQ_868_NORMAL_RATE));
            cc1101_interface_write_single_reg(FREQ1, RADIO_FREQ2(RADIO_FREQ_868_NORMAL_RATE));
            cc1101_interface_write_single_reg(FREQ0, RADIO_FREQ2(RADIO_FREQ_868_NORMAL_RATE));
            break;
        case PHY_BAND_915_1: // TODO 915_x
            assert(false);
//            WriteSingleReg(RADIO_FREQ2, (uint8_t)(RADIO_FREQ_915>>16 & 0xFF));
//            WriteSingleReg(RADIO_FREQ1, (uint8_t)(RADIO_FREQ_915>>8 & 0xFF));
//            WriteSingleReg(RADIO_FREQ0, (uint8_t)(RADIO_FREQ_915 & 0xFF));
            break;
        }

        // set channel center frequency
        DPRINT("Set channel freq index: %d", channel_id->center_freq_index);
        cc1101_interface_write_single_reg(CHANNR, channel_id->center_freq_index); // TODO validate

        // set modulation, symbol rate and deviation
        switch(channel_id->channel_header.ch_class)
        {
            case PHY_CLASS_NORMAL_RATE:
                // TODO validate
                cc1101_interface_write_single_reg(MDMCFG3, RADIO_MDMCFG3_DRATE_M_NORMAL_RATE);
                cc1101_interface_write_single_reg(MDMCFG4, RADIO_MDMCFG4_NORMAL_RATE);
                cc1101_interface_write_single_reg(DEVIATN, RADIO_DEVIATN_NORMAL_RATE);
                break;
            case PHY_CLASS_LO_RATE:
                cc1101_interface_write_single_reg(MDMCFG3, RADIO_MDMCFG3_DRATE_M_LOW_RATE);
                cc1101_interface_write_single_reg(MDMCFG4, RADIO_MDMCFG4_LOW_RATE);
                cc1101_interface_write_single_reg(DEVIATN, RADIO_DEVIATN_LOW_RATE);
                break;
            default:
                assert(false);
                // TODO: other classes
        }
    }

    cc1101_interface_strobe(RF_SCAL); // TODO is this the right case?
}