diff --git a/core/dev/radio.h b/core/dev/radio.h index 982acc51dba..abb686a0b56 100644 --- a/core/dev/radio.h +++ b/core/dev/radio.h @@ -181,6 +181,8 @@ enum { RADIO_CONST_TXPOWER_MIN, /* The maximum transmission power in dBm. */ RADIO_CONST_TXPOWER_MAX + + , RADIO_PARAM_TOTAL }; /* Radio power modes */ diff --git a/cpu/cc26xx-cc13xx/dev/oscillators.c b/cpu/cc26xx-cc13xx/dev/oscillators.c index 7890a8e5586..e6176b10324 100644 --- a/cpu/cc26xx-cc13xx/dev/oscillators.c +++ b/cpu/cc26xx-cc13xx/dev/oscillators.c @@ -111,6 +111,28 @@ oscillators_request_hf_xosc(void) /* Release the OSC AUX consumer */ aux_ctrl_unregister_consumer(&osc); } + +/*---------------------------------------------------------------------------*/ +bool oscillators_wait_ready_hf_xosc(rtimer_clock_t timeout) +{ + /* Request AUX access, with OSCCTRL and SMPH clocks */ + aux_consumer_module_t osc = { + .clocks = AUX_WUC_OSCCTRL_CLOCK | AUX_WUC_SMPH_CLOCK + }; + aux_ctrl_register_consumer(&osc); + bool res = true; + if (ti_lib_osc_clock_source_get(OSC_SRC_CLK_HF) != (OSC_XOSC_HF)) + while (!ti_lib_osc_hf_source_ready()){ + if (RTIMER_CLOCK_LT( timeout, RTIMER_NOW() )){ + res = false; + break; + } + } + /* Release the OSC AUX consumer */ + aux_ctrl_unregister_consumer(&osc); + return res; +} + /*---------------------------------------------------------------------------*/ void oscillators_switch_to_hf_xosc(void) diff --git a/cpu/cc26xx-cc13xx/dev/oscillators.h b/cpu/cc26xx-cc13xx/dev/oscillators.h index 47e95a3113c..adddbff2d3c 100644 --- a/cpu/cc26xx-cc13xx/dev/oscillators.h +++ b/cpu/cc26xx-cc13xx/dev/oscillators.h @@ -48,6 +48,9 @@ /*---------------------------------------------------------------------------*/ #ifndef OSCILLATORS_H_ #define OSCILLATORS_H_ + +#include + /*---------------------------------------------------------------------------*/ /** * \brief Set the LF clock source to be the LF XOSC @@ -81,6 +84,16 @@ void oscillators_select_lf_rcosc(void); */ void oscillators_request_hf_xosc(void); +/** + * \brief waits until timeout for HF clock be ready, after requested the + * HF XOSC as the source for the HF clock. + * \sa oscillators_request_hf_xosc + * + * This checks while an startup HF XOSC in progess + * + */ +bool oscillators_wait_ready_hf_xosc(rtimer_clock_t timeout); + /** * \brief Performs the switch to the XOSC * diff --git a/cpu/cc26xx-cc13xx/rf-core/prop-mode.c b/cpu/cc26xx-cc13xx/rf-core/prop-mode.c index 96d0fba7843..0fe86bd2f27 100644 --- a/cpu/cc26xx-cc13xx/rf-core/prop-mode.c +++ b/cpu/cc26xx-cc13xx/rf-core/prop-mode.c @@ -144,6 +144,7 @@ static int8_t rssi_threshold = PROP_MODE_RSSI_THRESHOLD; /*---------------------------------------------------------------------------*/ static int on(void); static int off(void); +static rf_power_style power_style = RADIO_POWER_STYLE_FREE; static rfc_propRxOutput_t rx_stats; /*---------------------------------------------------------------------------*/ @@ -888,6 +889,27 @@ pending_packet(void) return rv; } /*---------------------------------------------------------------------------*/ +#include +static uint32_t power_style_save; +static +int rf_power_up(){ + if (power_style == RADIO_POWER_STYLE_GLDO){ + power_style_save = PowerCtrlSourceGet(); + if (power_style_save != PWRCTRL_PWRSRC_GLDO) + PowerCtrlSourceSet(PWRCTRL_PWRSRC_GLDO); + } + return rf_core_power_up(); +} + +static +void rf_power_down(){ + rf_core_power_down(); + if (power_style != RADIO_POWER_STYLE_FREE) { + if (PowerCtrlSourceGet() != power_style_save) + PowerCtrlSourceSet(power_style_save); + } +} + static int on(void) { @@ -904,6 +926,9 @@ on(void) * use the FS. This will only request, it will _not_ perform the switch. */ oscillators_request_hf_xosc(); +#if (RF_CORE_HFOSC_STARTUP_TOUS > 0) + rtimer_clock_t hf_start_time = RTIMER_NOW(); +#endif if(rf_is_on()) { PRINTF("on: We were on. PD=%u, RX=0x%04x \n", rf_core_is_accessible(), @@ -912,10 +937,10 @@ on(void) } if(!rf_core_is_accessible()) { - if(rf_core_power_up() != RF_CORE_CMD_OK) { + if(rf_power_up() != RF_CORE_CMD_OK) { PRINTF("on: rf_core_power_up() failed\n"); - rf_core_power_down(); + rf_power_down(); return RF_CORE_CMD_ERROR; } @@ -947,12 +972,23 @@ on(void) if(rf_core_start_rat() != RF_CORE_CMD_OK) { PRINTF("on: rf_core_start_rat() failed\n"); - rf_core_power_down(); + rf_power_down(); return RF_CORE_CMD_ERROR; } } +#if (RF_CORE_HFOSC_STARTUP_TOUS > 0) + const unsigned hf_start_timeout = US_TO_RTIMERTICKS(RF_CORE_HFOSC_STARTUP_TOUS); + rtimer_clock_t hf_start_limit = hf_start_time + hf_start_timeout; + if( !oscillators_wait_ready_hf_xosc(hf_start_limit) ){ + PRINTF("on: rf_core_start_rat() failed start HF\n"); + rf_power_down(); + trace_rf_on_off(); + return RF_CORE_CMD_ERROR; + } +#endif + rf_core_setup_interrupts(false); init_rx_buffers(); @@ -989,7 +1025,7 @@ off(void) } rx_off_prop(); - rf_core_power_down(); + rf_power_down(); ENERGEST_OFF(ENERGEST_TYPE_LISTEN); @@ -1068,6 +1104,14 @@ set_value(radio_param_t param, radio_value_t value) return RADIO_RESULT_OK; } return RADIO_RESULT_INVALID_VALUE; + + case RADIO_CC26_POWER_STYLE: + if (value < RADIO_POWER_STYLE_TOTAL){ + power_style = value; + return RADIO_RESULT_OK; + } + return RADIO_RESULT_INVALID_VALUE; + case RADIO_PARAM_CHANNEL: if(value < 0 || value > DOT_15_4G_CHANNEL_MAX) { @@ -1098,6 +1142,9 @@ set_value(radio_param_t param, radio_value_t value) } return RADIO_RESULT_OK; + case RADIO_CC26_POWER_STYLE: + *value = power_style; + return RADIO_RESULT_OK; case RADIO_PARAM_RX_MODE: return RADIO_RESULT_OK; case RADIO_PARAM_CCA_THRESHOLD: diff --git a/cpu/cc26xx-cc13xx/rf-core/prop-mode.h b/cpu/cc26xx-cc13xx/rf-core/prop-mode.h index 55048777acb..772e45ae5ff 100644 --- a/cpu/cc26xx-cc13xx/rf-core/prop-mode.h +++ b/cpu/cc26xx-cc13xx/rf-core/prop-mode.h @@ -52,6 +52,19 @@ typedef struct prop_mode_tx_power_config { radio_value_t dbm; uint16_t tx_power; /* Value for the PROP_DIV_RADIO_SETUP.txPower field */ } prop_mode_tx_power_config_t; + +#include +enum rf_power_style { + RADIO_POWER_STYLE_FREE + , RADIO_POWER_STYLE_GLDO + , RADIO_POWER_STYLE_TOTAL +}; +typedef enum rf_power_style rf_power_style; +enum { + RADIO_CC26_PARAMS = RADIO_PARAM_TOTAL + , RADIO_CC26_POWER_STYLE +}; + /*---------------------------------------------------------------------------*/ #endif /* PROP_MODE_H_ */ /*---------------------------------------------------------------------------*/ diff --git a/cpu/cc26xx-cc13xx/rf-core/rf-core.h b/cpu/cc26xx-cc13xx/rf-core/rf-core.h index 762aa565042..127a4fb7dd7 100644 --- a/cpu/cc26xx-cc13xx/rf-core/rf-core.h +++ b/cpu/cc26xx-cc13xx/rf-core/rf-core.h @@ -103,6 +103,17 @@ #define RF_CORE_PROP_BIAS_MODE RF_CORE_BIAS_MODE_EXTERNAL #endif /*---------------------------------------------------------------------------*/ +/* RF-Front End RAT resyncing strategy provides mechanisms for RAT sync monitoring + * and resyncing + * 0 : resync only on rf-core propety setup + * 1 : validate RF-timestamp in window of current operation, and resync if violate + * */ +#ifdef RF_CORE_CONF_HFOSC_STARTUP_TOUS +#define RF_CORE_HFOSC_STARTUP_TOUS RF_CORE_CONF_HFOSC_STARTUP_TOUS +#else +//#define RF_CORE_HFOSC_STARTUP_TOUS 1000 +#endif +/*---------------------------------------------------------------------------*/ #define RF_CORE_CMD_ERROR 0 #define RF_CORE_CMD_OK 1 /*---------------------------------------------------------------------------*/