📄 radio.c
字号:
* * \returns 0 to 15 Current output power in "TX power settings" as defined in * the radio transceiver's datasheet */uint8_tradio_get_tx_power_level(void){ return hal_subregister_read(SR_TX_PWR);}/*----------------------------------------------------------------------------*//** \brief This function will change the output power level. * * \param power_level New output power level in the "TX power settings" * as defined in the radio transceiver's datasheet. * * \retval RADIO_SUCCESS New output power set successfully. * \retval RADIO_INVALID_ARGUMENT The supplied function argument is out of bounds. * \retval RADIO_WRONG_STATE It is not possible to change the TX power when the * device is sleeping. */radio_status_tradio_set_tx_power_level(uint8_t power_level){ /*Check function parameter and state.*/ if (power_level > TX_PWR_17_2DBM){ return RADIO_INVALID_ARGUMENT; } if (radio_is_sleeping() == true){ return RADIO_WRONG_STATE; } /*Set new power level*/ hal_subregister_write(SR_TX_PWR, power_level); return RADIO_SUCCESS;}/*----------------------------------------------------------------------------*//** \brief This function returns the current CCA mode used. * * \return CCA mode currently used, 0 to 3. */uint8_tradio_get_cca_mode(void){ return hal_subregister_read(SR_CCA_MODE);}/*----------------------------------------------------------------------------*//** \brief This function returns the current ED threshold used by the CCA algorithm. * * \return Current ED threshold, 0 to 15. */uint8_tradio_get_ed_threshold(void){ return hal_subregister_read(SR_CCA_ED_THRES);}/*----------------------------------------------------------------------------*//** \brief This function will configure the Clear Channel Assessment algorithm. * * \param mode Three modes are available: Energy above threshold, carrier * sense only and carrier sense with energy above threshold. * \param ed_threshold Above this energy threshold the channel is assumed to be * busy. The threshold is given in positive dBm values. * Ex. -91 dBm gives a csThreshold of 91. Value range for * the variable is [61 to 91]. Only valid for the CCA_ED * and CCA_CARRIER_SENSE_ED modes. * * \retval RADIO_SUCCESS Mode and its parameters successfully changed. * \retval RADIO_WRONG_STATE This function cannot be called in the SLEEP state. * \retval RADIO_INVALID_ARGUMENT If one of the three function arguments are out * of bounds. */radio_status_tradio_set_cca_mode(uint8_t mode, uint8_t ed_threshold){ /*Check function parameters and state.*/ if ((mode != CCA_ED) && (mode != CCA_CARRIER_SENSE) && (mode != CCA_CARRIER_SENSE_WITH_ED)){ return RADIO_INVALID_ARGUMENT; } /* Ensure that the ED threshold is within bounds. */ if (ed_threshold > RF230_MAX_ED_THRESHOLD){ return RADIO_INVALID_ARGUMENT; } /* Ensure that the radio transceiver is not sleeping. */ if (radio_is_sleeping() == true){ return RADIO_WRONG_STATE; } /*Change cca mode and ed threshold.*/ hal_subregister_write(SR_CCA_MODE, mode); hal_subregister_write(SR_CCA_ED_THRES, ed_threshold); return RADIO_SUCCESS;}/*----------------------------------------------------------------------------*//** \brief This function returns the Received Signal Strength Indication. * * \note This function should only be called from the: RX_ON and BUSY_RX. This * can be ensured by reading the current state of the radio transceiver * before executing this function! * \param rssi Pointer to memory location where RSSI value should be written. * \retval RADIO_SUCCESS The RSSI measurement was successful. * \retval RADIO_WRONG_STATE The radio transceiver is not in RX_ON or BUSY_RX. */radio_status_tradio_get_rssi_value(uint8_t *rssi){ uint8_t current_state = radio_get_trx_state(); radio_status_t retval = RADIO_WRONG_STATE; /*The RSSI measurement should only be done in RX_ON or BUSY_RX.*/ if ((current_state == RX_ON) || (current_state == BUSY_RX)){ *rssi = hal_subregister_read(SR_RSSI); retval = RADIO_SUCCESS; } return retval;}/*----------------------------------------------------------------------------*//** \brief This function returns the current threshold volatge used by the * battery monitor (BATMON_VTH). * * \note This function can not be called from P_ON or SLEEP. This is ensured * by reading the device state before calling this function. * * \return Current threshold voltage, 0 to 15. */uint8_tradio_batmon_get_voltage_threshold(void){ return hal_subregister_read(SR_BATMON_VTH);}/*----------------------------------------------------------------------------*//** \brief This function returns if high or low voltage range is used. * * \note This function can not be called from P_ON or SLEEP. This is ensured * by reading the device state before calling this function. * * \retval 0 Low voltage range selected. * \retval 1 High voltage range selected. */uint8_tradio_batmon_get_voltage_range(void){ return hal_subregister_read(SR_BATMON_HR);}/*----------------------------------------------------------------------------*//** \brief This function is used to configure the battery monitor module * * \param range True means high voltage range and false low voltage range. * \param voltage_threshold The datasheet defines 16 voltage levels for both * low and high range. * \retval RADIO_SUCCESS Battery monitor configured * \retval RADIO_WRONG_STATE The device is sleeping. * \retval RADIO_INVALID_ARGUMENT The voltage_threshold parameter is out of * bounds (Not within [0 - 15]). */radio_status_tradio_batmon_configure(bool range, uint8_t voltage_threshold){ /*Check function parameters and state.*/ if (voltage_threshold > BATTERY_MONITOR_HIGHEST_VOLTAGE){ return RADIO_INVALID_ARGUMENT; } if (radio_is_sleeping() == true){ return RADIO_WRONG_STATE; } /*Write new voltage range and voltage level.*/ if (range == true){ hal_subregister_write(SR_BATMON_HR, BATTERY_MONITOR_HIGH_VOLTAGE); } else { hal_subregister_write(SR_BATMON_HR, BATTERY_MONITOR_LOW_VOLTAGE); } hal_subregister_write(SR_BATMON_VTH, voltage_threshold); return RADIO_SUCCESS;}/*----------------------------------------------------------------------------*//** \brief This function returns the status of the Battery Monitor module. * * \note This function can not be called from P_ON or SLEEP. This is ensured * by reading the device state before calling this function. * * \retval RADIO_BAT_LOW Battery voltage is below the programmed threshold. * \retval RADIO_BAT_OK Battery voltage is above the programmed threshold. */radio_status_tradio_batmon_get_status(void){ radio_status_t batmon_status = RADIO_BAT_LOW; if (hal_subregister_read(SR_BATMON_OK) != BATTERY_MONITOR_VOLTAGE_UNDER_THRESHOLD){ batmon_status = RADIO_BAT_OK; } return batmon_status;}/*----------------------------------------------------------------------------*//** \brief This function returns the current clock setting for the CLKM pin. * * \retval CLKM_DISABLED CLKM pin is disabled. * \retval CLKM_1MHZ CLKM pin is prescaled to 1 MHz. * \retval CLKM_2MHZ CLKM pin is prescaled to 2 MHz. * \retval CLKM_4MHZ CLKM pin is prescaled to 4 MHz. * \retval CLKM_8MHZ CLKM pin is prescaled to 8 MHz. * \retval CLKM_16MHZ CLKM pin is not prescaled. Output is 16 MHz. */uint8_tradio_get_clock_speed(void){ return hal_subregister_read(SR_CLKM_CTRL);}/*----------------------------------------------------------------------------*//** \brief This function changes the prescaler on the CLKM pin. * * \param direct This boolean variable is used to determine if the frequency * of the CLKM pin shall be changed directly or not. If direct * equals true, the frequency will be changed directly. This is * fine if the CLKM signal is used to drive a timer etc. on the * connected microcontroller. However, the CLKM signal can also * be used to clock the microcontroller itself. In this situation * it is possible to change the CLKM frequency indirectly * (direct == false). When the direct argument equlas false, the * CLKM frequency will be changed first after the radio transceiver * has been taken to SLEEP and awaken again. * \param clock_speed This parameter can be one of the following constants: * CLKM_DISABLED, CLKM_1MHZ, CLKM_2MHZ, CLKM_4MHZ, CLKM_8MHZ * or CLKM_16MHZ. * * \retval RADIO_SUCCESS Clock speed updated. New state is TRX_OFF. * \retval RADIO_INVALID_ARGUMENT Requested clock speed is out of bounds. */radio_status_tradio_set_clock_speed(bool direct, uint8_t clock_speed){ /*Check function parameter and current clock speed.*/ if (clock_speed > CLKM_16MHZ){ return RADIO_INVALID_ARGUMENT; } if (radio_get_clock_speed() == clock_speed){ return RADIO_SUCCESS; } /*Select to change the CLKM frequency directly or after returning from SLEEP.*/ if (direct == false){ hal_subregister_write(SR_CLKM_SHA_SEL, 1); } else { hal_subregister_write(SR_CLKM_SHA_SEL, 0); } hal_subregister_write(SR_CLKM_CTRL, clock_speed); return RADIO_SUCCESS;}/*----------------------------------------------------------------------------*//** \brief This function calibrates the Single Side Band Filter. * * \retval RADIO_SUCCESS Filter is calibrated. * \retval RADIO_TIMED_OUT The calibration could not be completed within time. * \retval RADIO_WRONG_STATE This function can only be called from TRX_OFF or * PLL_ON. */radio_status_tradio_calibrate_filter(void){ /*Check current state. Only possible to do filter calibration from TRX_OFF or PLL_ON.*/ uint8_t trx_state = radio_get_trx_state(); if ((trx_state != TRX_OFF) && (trx_state != PLL_ON)){ return RADIO_WRONG_STATE; } /* Start the tuning algorithm by writing one to the FTN_START subregister. */ hal_subregister_write(SR_FTN_START, 1); delay_us(TIME_FTN_TUNING); /* Wait for the calibration to finish. */ radio_status_t filter_calibration_status = RADIO_TIMED_OUT; /* Verify the calibration result. */ if (hal_subregister_read(SR_FTN_START) == FTN_CALIBRATION_DONE){ filter_calibration_status = RADIO_SUCCESS; } return filter_calibration_status;}/*----------------------------------------------------------------------------*//** \brief This function calibrates the PLL. * * \retval RADIO_SUCCESS PLL Center Frequency and Delay Cell is calibrated. * \retval RADIO_TIMED_OUT The calibration could not be completed within time. * \retval RADIO_WRONG_STATE This function can only be called from PLL_ON. */radio_status_tradio_calibrate_pll(void){ /*Check current state. Only possible to calibrate PLL from PLL_ON state*/ if (radio_get_trx_state() != PLL_ON){ return RADIO_WRONG_STATE; } /* Initiate the DCU and CF calibration loops. */ hal_subregister_write(SR_PLL_DCU_START, 1); hal_subregister_write(SR_PLL_CF_START, 1); /* Wait maximum 150 us for the PLL to lock. */ hal_clear_pll_lock_flag(); delay_us(TIME_PLL_LOCK); radio_status_t pll_calibration_status = RADIO_TIMED_OUT; if (hal_get_pll_lock_flag() > 0){ if (hal_subregister_read(SR_PLL_DCU_START) == PLL_DCU_CALIBRATION_DONE){ if (hal_subregister_read(SR_PLL_CF_START) == PLL_CF_CALIBRATION_DONE){ pll_calibration_status = RADIO_SUCCESS; } } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -