From 596689d960fd8290a44a5278b45e5a38aaa81adf Mon Sep 17 00:00:00 2001 From: alexrayne Date: Wed, 11 Oct 2017 13:36:54 +0300 Subject: [PATCH 1/4] +cc26xx:prop-mode:safe on timeout - turn on radio checks HF OSC for timeout, ant fails if OSC not ready for RF_CORE_CONF_HFOSC_STARTUP_TOUS +cc26xx:oscillators:oscillators_wait_ready_hf_xosc - waiting HF OSC ready until timeout *Note - if OSC is bad, and can`t start, therefore mcu hung forever. when RF_CORE_CONF_HFOSC_STARTUP_TOUS defined, it checks with this timeout and reports failure --- cpu/cc26xx-cc13xx/dev/oscillators.c | 21 +++++++++++++++++++++ cpu/cc26xx-cc13xx/dev/oscillators.h | 13 +++++++++++++ cpu/cc26xx-cc13xx/rf-core/prop-mode.c | 14 ++++++++++++++ cpu/cc26xx-cc13xx/rf-core/rf-core.h | 11 +++++++++++ 4 files changed, 59 insertions(+) diff --git a/cpu/cc26xx-cc13xx/dev/oscillators.c b/cpu/cc26xx-cc13xx/dev/oscillators.c index 7890a8e5586..691a4949fdb 100644 --- a/cpu/cc26xx-cc13xx/dev/oscillators.c +++ b/cpu/cc26xx-cc13xx/dev/oscillators.c @@ -111,6 +111,27 @@ 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; + 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..32b1658d2af 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 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..10eab162282 100644 --- a/cpu/cc26xx-cc13xx/rf-core/prop-mode.c +++ b/cpu/cc26xx-cc13xx/rf-core/prop-mode.c @@ -904,6 +904,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(), @@ -953,6 +956,17 @@ on(void) } } +#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_core_power_down(); + trace_rf_on_off(); + return RF_CORE_CMD_ERROR; + } +#endif + rf_core_setup_interrupts(false); init_rx_buffers(); 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 /*---------------------------------------------------------------------------*/ From f9297ea802e32ab1478f4d9cc9a7074b0ac6c5ce Mon Sep 17 00:00:00 2001 From: alexrayne Date: Wed, 11 Oct 2017 17:29:17 +0300 Subject: [PATCH 2/4] !cc26xx:oscillators_wait_ready_hf_xosc - fixed DOXY wans --- cpu/cc26xx-cc13xx/dev/oscillators.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpu/cc26xx-cc13xx/dev/oscillators.h b/cpu/cc26xx-cc13xx/dev/oscillators.h index 32b1658d2af..adddbff2d3c 100644 --- a/cpu/cc26xx-cc13xx/dev/oscillators.h +++ b/cpu/cc26xx-cc13xx/dev/oscillators.h @@ -85,7 +85,7 @@ void oscillators_select_lf_rcosc(void); void oscillators_request_hf_xosc(void); /** - * \brief waits until for HF clock be ready, after requested the + * \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 * From 8b66be3cee521daf3d1754e645c9a346cb8c7503 Mon Sep 17 00:00:00 2001 From: alexrayne Date: Thu, 12 Oct 2017 16:57:42 +0300 Subject: [PATCH 3/4] !cc26xx:oscillators_wait_ready_hf_xosc - fix for already switched to HF OSC --- cpu/cc26xx-cc13xx/dev/oscillators.c | 1 + 1 file changed, 1 insertion(+) diff --git a/cpu/cc26xx-cc13xx/dev/oscillators.c b/cpu/cc26xx-cc13xx/dev/oscillators.c index 691a4949fdb..e6176b10324 100644 --- a/cpu/cc26xx-cc13xx/dev/oscillators.c +++ b/cpu/cc26xx-cc13xx/dev/oscillators.c @@ -121,6 +121,7 @@ bool oscillators_wait_ready_hf_xosc(rtimer_clock_t timeout) }; 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; From 2462b4e75acfbf70c39907116671f0c87c5b7424 Mon Sep 17 00:00:00 2001 From: alexrayne Date: Thu, 15 Feb 2018 17:07:19 +0300 Subject: [PATCH 4/4] +cc26xx:rf:prop-mode:RADIO_CC26_POWER_STYLE - introduce power control style on rf power on/off + RADIO_POWER_STYLE_GLDO - force turn off DCDC during radio is on. * Using GLDO can provide less noise on rf-receiver by turn off onchip DCDC. --- core/dev/radio.h | 2 ++ cpu/cc26xx-cc13xx/rf-core/prop-mode.c | 43 +++++++++++++++++++++++---- cpu/cc26xx-cc13xx/rf-core/prop-mode.h | 13 ++++++++ 3 files changed, 53 insertions(+), 5 deletions(-) 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/rf-core/prop-mode.c b/cpu/cc26xx-cc13xx/rf-core/prop-mode.c index 10eab162282..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) { @@ -915,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; } @@ -950,7 +972,7 @@ 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; } @@ -961,7 +983,7 @@ on(void) 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_core_power_down(); + rf_power_down(); trace_rf_on_off(); return RF_CORE_CMD_ERROR; } @@ -1003,7 +1025,7 @@ off(void) } rx_off_prop(); - rf_core_power_down(); + rf_power_down(); ENERGEST_OFF(ENERGEST_TYPE_LISTEN); @@ -1082,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) { @@ -1112,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_ */ /*---------------------------------------------------------------------------*/