DA14683: At what point during power up is the BLE TX Power Level Set?

Hardware:

Custom DA14683 Board

Latest SDK = 1.0.14.1081 (Last updated in 2018)

 

Situation:

This question applies to any demo, but lets take the BMS demo for an example.

From hw_rf.h, I can see where the tx power levels are defined in this enum:

typedef enum {
        HW_RF_PWR_LUT_0dbm = 0,   /**< TX PWR attenuation 0 dbm */
        HW_RF_PWR_LUT_m1dbm = 1,  /**< TX PWR attenuation -1 dbm */
        HW_RF_PWR_LUT_m2dbm = 2,  /**< TX PWR attenuation -2 dbm */
        HW_RF_PWR_LUT_m3dbm = 3,  /**< TX PWR attenuation -3 dbm */
        HW_RF_PWR_LUT_m4dbm = 4,  /**< TX PWR attenuation -4 dbm */
} HW_RF_PWR_LUT_SETTING;

From hw_rf.c, I can see the function that sets the TX power level:

void hw_rf_set_tx_power_ble(HW_RF_PWR_LUT_SETTING lut)
{
        RFCU->RF_TX_PWR_BLE_REG = lut;
        rf_tx_power_luts.tx_power_ble = lut;
}

...But the "hw_rf_set_tx_power_ble()" function does not appear to be called anywhere.  

...Also none of the enums from "HW_RF_PWR_LUT_SETTING" appear anywhere in the project.

It is unclear where the TX power is being defined.  It is also unclear at what point in the power up sequence the TX power is being set.

Questions:

1) Where is the default TX Power level defined? (file and line please)

2) At what point in the BLE radio initialization sequence is the TX power level set? (file and line please)

3) If I wanted to change the BLE radio TX power level, what is the correct sequence of operations to do so? (do I need to power down the radio first?, just stop advertising?, etc)

Parents
  • Did you see my response? 

    1.

    If you search the code, the hw_rf_set_tx_power_ble() is called in hw_rf_request_recommended_settings() which is called in ad_rf_request_recommended_settings().  Just search into the code in hw_rf.c file.

    #ifdef CONFIG_USE_BLE
    hw_rf_set_tx_power_ble(rf_tx_power_luts.tx_power_ble);
    #endif

    According to hw_rf_tx_power_luts_t struct, rf_tx_power_luts.tx_power_ble = 4. 

    rf_tx_power_luts.tx_power_ble = 4 --->> HW_RF_PWR_LUT_m4dbm = 4,  /**< TX PWR attenuation -4 dbm */

    2. Power down radio and then call hw_rf_set_tx_power_ble()

    3. application specific 

Reply
  • Did you see my response? 

    1.

    If you search the code, the hw_rf_set_tx_power_ble() is called in hw_rf_request_recommended_settings() which is called in ad_rf_request_recommended_settings().  Just search into the code in hw_rf.c file.

    #ifdef CONFIG_USE_BLE
    hw_rf_set_tx_power_ble(rf_tx_power_luts.tx_power_ble);
    #endif

    According to hw_rf_tx_power_luts_t struct, rf_tx_power_luts.tx_power_ble = 4. 

    rf_tx_power_luts.tx_power_ble = 4 --->> HW_RF_PWR_LUT_m4dbm = 4,  /**< TX PWR attenuation -4 dbm */

    2. Power down radio and then call hw_rf_set_tx_power_ble()

    3. application specific 

Children
  • Yes, I did see your response.  Did you read any of my response to your response?  I explained exactly why what you said is wrong, in pretty good detail.  I'll repost it here.  Lets learn together!

    Lets start with the hw_rf_tx_power_luts_t struct:

    typedef struct __attribute__ ((__packed__)) {
        uint8_t tx_power_ble: 4;
        uint8_t tx_power_ftdf: 4;
    } hw_rf_tx_power_luts_t;
    
    extern hw_rf_tx_power_luts_t rf_tx_power_luts;

    That is the format for a c bit field: https://www.tutorialspoint.com/cprogramming/c_bit_fields.htm

    Those "4"s are not values.  You can't assign a value in a c struct definition.  Those "4"s are the number of bits for each variable.  If you run sizeof(rf_tx_power_luts) you will see that returns 1 byte.  

    Your statement that "According to hw_rf_tx_power_luts_t struct, rf_tx_power_luts.tx_power_ble = 4. " is both incorrect theoretically (as in you are misunderstanding what the code is doing), and practically when run.  As I mentioned, when I debug the code the value that is actually used when the unmodified system calls "hw_rf_set_tx_power_ble()" is 0 = "HW_RF_PWR_LUT_0dbm".  Normally I would leave this issue here, but it's super bad form to use an uninitialized variable like this.  The "rf_tx_power_luts" is declared but it is never initialized.  You would see this if you look through the code I've already posted above or you can check the actual SDK if you don't believe me.  

    If you think I got this wrong still, go ahead and respond with the file and line number where you think the "rf_tx_power_luts" is initialized with a "4" or "HW_RF_PWR_LUT_m4dbm".

    The "ad_rf_request_recommended_settings()"  calls "hw_rf_set_recommended_settings()" as follows:

    /**
     * \brief Preferred settings 680 radio
     *
     */
    void hw_rf_set_recommended_settings(void)
    {
    
            // Preferred Settings File for DCTMON
            // Device             : DA14680AA
            // Package            : All packages, no dependency on package.
            // Last change date   : June 18, 2015 - 18:00:48
            // Last change item   : Register: RF_KMOD_ALPHA_REG, Field: KMOD_ALPHA_FTDF, Value: 0x10
            // File date          : June 18, 2015 - 19:16:16
    
            REG_SET_MASKED(DEM, RF_AFC_CTRL_REG,                    0x0330, 0x01F5);
            REG_SET_MASKED(DEM, RF_AGC_CTRL1_REG,                   0x007F, 0x950A);
            REG_SET_MASKED(DEM, RF_AGC_CTRL2_REG,                   0x003F, 0x0049);
            REG_SET_MASKED(DEM, RF_CCA_RSSITH_REG,                  0xE000, 0xE708);
    
            RFCU_POWER->RF_CNTRL_TIMER_10_REG =  0x0A42;
            RFCU_POWER->RF_CNTRL_TIMER_11_REG =  0x0A44;
            REG_SET_MASKED(RFCU_POWER, RF_CNTRL_TIMER_12_REG,       0x00FF, 0x0050);
            RFCU_POWER->RF_CNTRL_TIMER_13_REG =  0x0850;
            RFCU_POWER->RF_CNTRL_TIMER_14_REG =  0x1858;
            RFCU_POWER->RF_CNTRL_TIMER_15_REG =  0x0A50;
            REG_SET_MASKED(RFCU_POWER, RF_CNTRL_TIMER_16_REG, 0xFF00, 0x1207);
            REG_SET_MASKED(RFCU_POWER, RF_CNTRL_TIMER_1_REG, 0xFF00, 0x0F00);
            REG_SET_MASKED(RFCU_POWER, RF_CNTRL_TIMER_21_REG, 0x00FF, 0x0044);
            REG_SET_MASKED(RFCU_POWER, RF_CNTRL_TIMER_22_REG, 0x00FF, 0x0040);
            REG_SET_MASKED(RFCU_POWER, RF_CNTRL_TIMER_23_REG, 0x00FF, 0x0052);
            REG_SET_MASKED(RFCU_POWER, RF_CNTRL_TIMER_2_REG, 0xFF00, 0x0D08);
            REG_SET_MASKED(RFCU_POWER, RF_CNTRL_TIMER_3_REG, 0xFF00, 0x0C10);
            REG_SET_MASKED(RFCU_POWER, RF_CNTRL_TIMER_5_REG, 0xFF00, 0x0A18);
            REG_SET_MASKED(RFCU_POWER, RF_CNTRL_TIMER_7_REG, 0xFF00, 0x0A18);
            RFCU->RF_CP_CTRL_BLE_REG = 0x3535;
            REG_SET_MASKED(RFCU, RF_CP_CTRL_FTDF_REG, 0x0F0F, 0x7575);
            REG_SET_MASKED(DEM, RF_DC_OFFSET_CTRL2_REG, 0x0402, 0x05D0);
            DEM->RF_DC_OFFSET_CTRL3_REG = 0xE9EE;
            REG_SET_MASKED(RFCU, RF_DIV_IQ_TX_REG, 0x00FF, 0x00A1);
            REG_SET_MASKED(RFCU_POWER, RF_ENABLE_CONFIG16_REG, 0x001F, 0x0014);
            REG_SET_MASKED(RFCU_POWER, RF_ENABLE_CONFIG23_BLE_REG, 0x03E0, 0x0000);
            RFCU_POWER->RF_ENABLE_CONFIG42_REG = 0x0210;
            REG_SET_MASKED(RFCU_POWER, RF_ENABLE_CONFIG45_BLE_REG, 0x03E0, 0x0060);
            REG_SET_MASKED(RFCU_POWER, RF_ENABLE_CONFIG46_BLE_REG, 0x001F, 0x0015);
            REG_SET_MASKED(RFCU_POWER, RF_ENABLE_CONFIG46_FTDF_REG, 0x001F, 0x0015);
            REG_SET_MASKED(RFCU_POWER, RF_ENABLE_CONFIG47_BLE_REG, 0x001F, 0x0016);
            REG_SET_MASKED(RFCU_POWER, RF_ENABLE_CONFIG47_FTDF_REG, 0x001F, 0x0016);
            REG_SET_MASKED(RFCU_POWER, RF_ENABLE_CONFIG48_BLE_REG, 0x001F, 0x0017);
            REG_SET_MASKED(RFCU_POWER, RF_ENABLE_CONFIG48_FTDF_REG, 0x001F, 0x0017);
            REG_SET_MASKED(DEM, RF_FTDF_CTRL1_REG,                  0xCC00, 0x47C0);
            REG_SET_MASKED(DEM, RF_FTDF_CTRL4_REG,                  0x0500, 0xC6A7);
            REG_SET_MASKED(DEM, RF_FTDF_LOOP_GAIN_DS_REG,           0x00FF, 0x0000);
            REG_SET_MASKED(DEM, RF_FTDF_LOOP_GAIN_PD_REG,           0x00FF, 0x0000);
            REG_SET_MASKED(DEM, RF_FTDF_SIGDET_CTRL_REG,            0x1FFF, 0x0BC3);
            REG_SET_MASKED(PLLDIG, RF_KMOD_ALPHA_BLE_REG, 0x0FC0, 0x030C);
            PLLDIG->RF_KMOD_ALPHA_FTDF_REG = 0x000D;
            REG_SET_MASKED(RFCU, RF_LF_CTRL_REG,                    0x0040, 0x0080);
            RFCU->RF_LF_RES_CTRL_BLE_REG = 0x3434;
            REG_SET_MASKED(RFCU, RF_LF_RES_CTRL_FTDF_REG, 0x0F0F, 0x7474);
            RFCU->RF_LO_IQ_TRIM_REG = 0x0001;
            PLLDIG->RF_MGAIN_CTRL3_REG = 0x0050;
            REG_SET_MASKED(PLLDIG, RF_MGAIN_CTRL_FTDF_REG, 0xFF00, 0x5000);
            REG_SET_MASKED(RFCU, RF_MIXER_CTRL1_BLE_REG, 0x000F, 0x0031);
            REG_SET_MASKED(RFCU, RF_MIXER_CTRL1_FTDF_REG, 0x000F, 0x0031);
            REG_SET_MASKED(RFCU, RF_OVERRULE_REG, 0x3C00, 0x5800);
            REG_SET_MASKED(RFCU, RF_REF_OSC_FTDF_REG, 0x7FFF, 0x31EB);
            REG_SET_MASKED(DEM, RF_RSSI_COMP_CTRL_REG, 0xF000, 0x9777);
            REG_SET_MASKED(RFCU, RF_SPARE1_BLE_REG, 0x0038, 0x0018);
            REG_SET_MASKED(RFCU, RF_SPARE1_FTDF_REG, 0x0008, 0x0008);
            REG_SET_MASKED(PLLDIG, RF_SYNTH_CTRL2_BLE_REG, 0x20C0, 0x304B);
            REG_SET_MASKED(PLLDIG, RF_SYNTH_CTRL2_FTDF_REG, 0x0040, 0x004B);
            RFCU->RF_TX_PWR_LUT_5_REG = 0x09FF;
            REG_SET_MASKED(RFCU, RF_TXDAC_CTRL_REG, 0x0040, 0x0000);
    }

    I'm sure there is something there as well, but most of those registers don't have documentation that makes any sense.

     

  • Nathan, will get back on this. Let me check again.