/*---------------------------------------------------------------------------*/ static radio_result_t set_value(radio_param_t param, radio_value_t value) { switch(param) { case RADIO_PARAM_POWER_MODE: if(value == RADIO_POWER_MODE_ON) { on(); return RADIO_RESULT_OK; } if(value == RADIO_POWER_MODE_OFF) { off(); return RADIO_RESULT_OK; } return RADIO_RESULT_INVALID_VALUE; case RADIO_PARAM_CHANNEL: if(value < 11 || value > 26) { return RADIO_RESULT_INVALID_VALUE; } set_channel(value); return RADIO_RESULT_OK; case RADIO_PARAM_RX_MODE: if(value & ~(RADIO_RX_MODE_ADDRESS_FILTER | RADIO_RX_MODE_AUTOACK | RADIO_RX_MODE_POLL_MODE)) { return RADIO_RESULT_INVALID_VALUE; } set_frame_filtering((value & RADIO_RX_MODE_ADDRESS_FILTER) != 0); set_autoack((value & RADIO_RX_MODE_AUTOACK) != 0); set_poll_mode((value & RADIO_RX_MODE_POLL_MODE) != 0); return RADIO_RESULT_OK; case RADIO_PARAM_TX_MODE: if(value & ~(RADIO_TX_MODE_SEND_ON_CCA)) { return RADIO_RESULT_INVALID_VALUE; } set_send_on_cca((value & RADIO_TX_MODE_SEND_ON_CCA) != 0); return RADIO_RESULT_OK; case RADIO_PARAM_TXPOWER: if(value < OUTPUT_POWER_MIN || value > OUTPUT_POWER_MAX) { return RADIO_RESULT_INVALID_VALUE; /* Find the closest higher PA_LEVEL for the desired output power */ } set_txpower(value); return RADIO_RESULT_OK; case RADIO_PARAM_CCA_THRESHOLD: cca_thershold = value; return RADIO_RESULT_OK; default: return RADIO_RESULT_NOT_SUPPORTED; } }
/*---------------------------------------------------------------------------*/ static radio_result_t set_value(radio_param_t param, radio_value_t value) { switch(param) { case RADIO_PARAM_POWER_MODE: if(value == RADIO_POWER_MODE_ON) { on(); return RADIO_RESULT_OK; } if(value == RADIO_POWER_MODE_OFF) { off(); return RADIO_RESULT_OK; } return RADIO_RESULT_INVALID_VALUE; case RADIO_PARAM_CHANNEL: if(value < CC2538_RF_CHANNEL_MIN || value > CC2538_RF_CHANNEL_MAX) { return RADIO_RESULT_INVALID_VALUE; } if(set_channel(value) == CC2538_RF_CHANNEL_SET_ERROR) { return RADIO_RESULT_ERROR; } return RADIO_RESULT_OK; case RADIO_PARAM_PAN_ID: set_pan_id(value & 0xffff); return RADIO_RESULT_OK; case RADIO_PARAM_16BIT_ADDR: set_short_addr(value & 0xffff); return RADIO_RESULT_OK; case RADIO_PARAM_RX_MODE: if(value & ~(RADIO_RX_MODE_ADDRESS_FILTER | RADIO_RX_MODE_AUTOACK | RADIO_RX_MODE_POLL_MODE)) { return RADIO_RESULT_INVALID_VALUE; } set_frame_filtering((value & RADIO_RX_MODE_ADDRESS_FILTER) != 0); set_auto_ack((value & RADIO_RX_MODE_AUTOACK) != 0); set_poll_mode((value & RADIO_RX_MODE_POLL_MODE) != 0); return RADIO_RESULT_OK; case RADIO_PARAM_TX_MODE: if(value & ~(RADIO_TX_MODE_SEND_ON_CCA)) { return RADIO_RESULT_INVALID_VALUE; } set_send_on_cca((value & RADIO_TX_MODE_SEND_ON_CCA) != 0); return RADIO_RESULT_OK; case RADIO_PARAM_TXPOWER: if(value < OUTPUT_POWER_MIN || value > OUTPUT_POWER_MAX) { return RADIO_RESULT_INVALID_VALUE; } set_tx_power(value); return RADIO_RESULT_OK; case RADIO_PARAM_CCA_THRESHOLD: set_cca_threshold(value); return RADIO_RESULT_OK; default: return RADIO_RESULT_NOT_SUPPORTED; } }
/*---------------------------------------------------------------------------*/ static int init(void) { PRINTF("RF: Init\n"); if(rf_flags & RF_ON) { return 0; } /* Enable clock for the RF Core while Running, in Sleep and Deep Sleep */ REG(SYS_CTRL_RCGCRFC) = 1; REG(SYS_CTRL_SCGCRFC) = 1; REG(SYS_CTRL_DCGCRFC) = 1; REG(RFCORE_XREG_CCACTRL0) = CC2538_RF_CCA_THRES_USER_GUIDE; /* * Changes from default values * See User Guide, section "Register Settings Update" */ REG(RFCORE_XREG_TXFILTCFG) = 0x09; /** TX anti-aliasing filter bandwidth */ REG(RFCORE_XREG_AGCCTRL1) = 0x15; /** AGC target value */ REG(ANA_REGS_IVCTRL) = 0x0B; /** Bias currents */ /* * Defaults: * Auto CRC; Append RSSI, CRC-OK and Corr. Val.; CRC calculation; * RX and TX modes with FIFOs */ REG(RFCORE_XREG_FRMCTRL0) = RFCORE_XREG_FRMCTRL0_AUTOCRC; #if CC2538_RF_AUTOACK REG(RFCORE_XREG_FRMCTRL0) |= RFCORE_XREG_FRMCTRL0_AUTOACK; #endif /* If we are a sniffer, turn off frame filtering */ #if CC2538_RF_CONF_SNIFFER REG(RFCORE_XREG_FRMFILT0) &= ~RFCORE_XREG_FRMFILT0_FRAME_FILTER_EN; #endif /* Disable source address matching and autopend */ REG(RFCORE_XREG_SRCMATCH) = 0; /* MAX FIFOP threshold */ REG(RFCORE_XREG_FIFOPCTRL) = CC2538_RF_MAX_PACKET_LEN; /* Set TX Power */ REG(RFCORE_XREG_TXPOWER) = CC2538_RF_TX_POWER; set_channel(rf_channel); /* Acknowledge all RF Error interrupts */ REG(RFCORE_XREG_RFERRM) = RFCORE_XREG_RFERRM_RFERRM; nvic_interrupt_enable(NVIC_INT_RF_ERR); if(CC2538_RF_CONF_TX_USE_DMA) { /* Disable peripheral triggers for the channel */ udma_channel_mask_set(CC2538_RF_CONF_TX_DMA_CHAN); /* * Set the channel's DST. SRC can not be set yet since it will change for * each transfer */ udma_set_channel_dst(CC2538_RF_CONF_TX_DMA_CHAN, RFCORE_SFR_RFDATA); } if(CC2538_RF_CONF_RX_USE_DMA) { /* Disable peripheral triggers for the channel */ udma_channel_mask_set(CC2538_RF_CONF_RX_DMA_CHAN); /* * Set the channel's SRC. DST can not be set yet since it will change for * each transfer */ udma_set_channel_src(CC2538_RF_CONF_RX_DMA_CHAN, RFCORE_SFR_RFDATA); } set_poll_mode(poll_mode); process_start(&cc2538_rf_process, NULL); rf_flags |= RF_ON; ENERGEST_ON(ENERGEST_TYPE_LISTEN); return 1; }