Clarifications for sdc_default_tx_power_set() and CONFIG_BT_CTLR_TX_PWR in NCS 2.2


1. Can I assume that if I set CONFIG_MPSL_FEM_POWER_MODEL=n, then the value I set with sdc_default_tx_power_set() is just the radio tx power level and not necessarily the power level fed to the antenna?

  • The documentation for sdc_default_tx_power_set(int8_t requested_power_level) says:

requested_power_level represents the actual power level fed to the antenna. When a Front-End Module is used, gain values for the SoC and FEM are calculated automatically to guarantee the closest possible match to the value requested by the user at the RF output.

The reason I bring this up is that I can still have an FEM that I control outside of the SDC. In this case, with CONFIG_MPSL_FEM_POWER_MODEL=n, the requested_power_level is not the power level fed to the antenna, contrary to the description. right?  If so, then perhaps the description could be clarified by adding what's in bold:  “When a Front-End Module is used and CONFIG_MPSL_FEM_POWER_MODEL=y, gain values for …”

2. If CONFIG_MPSL_FEM_POWER_MODEL=n, then what is the difference between CONFIG_BT_CTLR_TX_PWR and sdc_default_tx_power_set()?  Do they both achieve the same result, except one is a build-time setting and the other is a run-time setting, and the latter can override the former?

3. Why don’t the possible values of CONFIG_BT_CTLR_TX_PWR allow all possible nRF5340 radio transmit power levels?  For example, -6 dBm is a valid nRF5340 radio tx power (see TXPOWER register) but no such choice exists for CONFIG_BT_CTRL_TX_PWR.  The closest choices are CONFIG_BT_CTLR_TX_PWR_MINUS_4 and CONFIG_BT_CTLR_TX_PWR_MINUS_8.

4. Again with CONFIG_MPSL_FEM_POWER_MODEL=n:  From my understanding, the beginning of a transmit for a BLE connection or for BLE advertising begins with the radio transmit power value in CONFIG_BT_CTRL_TX_PWR, unless overridden by sdc_default_tx_power_set() having been called before calling sdc_enable().  If, for example, I change the transmit power during a BLE connection by using the HCI command BT_HCI_OP_VS_WRITE_TX_POWER_LEVEL, the radio transmit power level will change to that HCI command value, but the radio transmit power level will return to the default value at the start of the next BLE connection or if I start advertising again.  Is that correct?

Thanks in advance.

Parents
  • Hi Mike

    Can I assume that if I set CONFIG_MPSL_FEM_POWER_MODEL=n, then the value I set with sdc_default_tx_power_set() is just the radio tx power level and not necessarily the power level fed to the antenna?

    Not quite. After v2.2.0 the various power API's and configurations define the power as seen from the antenna, and does not set the power of the nRF device directly. This includes the power you request through the sdc_default_tx_power_set() function, as well as the older BT_CTLR_TX_PWR and the new BT_CTLR_TX_PWR_ANTENNA configurations.

    2. If CONFIG_MPSL_FEM_POWER_MODEL=n, then what is the difference between CONFIG_BT_CTLR_TX_PWR and sdc_default_tx_power_set()?  Do they both achieve the same result, except one is a build-time setting and the other is a run-time setting, and the latter can override the former?

    There is no difference between these two ways of configuring the TX power, that is correct. The build-time configuration will be provided to the SDC by default, but you can override this at runtime by using the sdc_default_tx_power_set() function. 

    3. Why don’t the possible values of CONFIG_BT_CTLR_TX_PWR allow all possible nRF5340 radio transmit power levels?  For example, -6 dBm is a valid nRF5340 radio tx power (see TXPOWER register) but no such choice exists for CONFIG_BT_CTRL_TX_PWR.  The closest choices are CONFIG_BT_CTLR_TX_PWR_MINUS_4 and CONFIG_BT_CTLR_TX_PWR_MINUS_8.

    Could you try this again using the BT_CTLR_TX_PWR_ANTENNA configuration? 
    Then all the valid TX power settings should be available. 

    If, for example, I change the transmit power during a BLE connection by using the HCI command BT_HCI_OP_VS_WRITE_TX_POWER_LEVEL, the radio transmit power level will change to that HCI command value, but the radio transmit power level will return to the default value at the start of the next BLE connection or if I start advertising again.  Is that correct?

    That is correct. Like before this command only sets the TX power for the particular connection you provide as the handle. Once the connection ends so does the scope of this change. 

    Best regards
    Torbjørn

  • Hi Torbjørn,

    Thank you very very much for the clear responses to my questions.

    In many of my questions above, I started with "If CONFIG_MPSL_FEM_POWER_MODEL=n".  I think we are learning as part of our effort to change from NCS 2.0 to 2.2 that we want that CONFIG to be yes, and set the FEM power model's gain to 0.  That is, we want to control our FEM independently from the nRF SoC. 

    Once we get this working, I can check if the answer to question 1 changes if I set CONFIG_MPSL_FEM_POWER_MODEL=y with FEM power model gain set to 0.

    Give our new finding about needing the CONFIG=y, should I follow up with any questions in a new ticket or this one? 

  • Hi Mike

    Setting CONFIG_MPSL_FEM_POWER_MODEL=y basically means that you are given the responsibility of deciding how a given output power on the antenna should be achieved, by controlling the TX power of the nRF device and the FEM directly. 

    You need to provide a function that takes the requested power level and the current radio frequency (in order to allow for different gain settings across the band), and returns the exact TX power setting for the nRF and the FEM. 

    In other words it sounds like exactly what you're looking for, if you want to control the FEM directly. 

    For more details about this please have a look at the documentation here, and the power model API here

    Best regards
    Torbjørn

  • Hi Torbjørn,

    I work with Mike. Do you have a sample project that implements a custom FEM model? When I tried implementing it, the net core crashes after the model fetch function is called.

    Here's what I did.

    1) Set the CONFIG_MPSL_FEM_POWER_MODEL=y

    2) Added the following code in the net core:

    #include <mpsl_fem_power_model.h>
    #include <mpsl_tx_power.h>
    
    static void model_init(const mpsl_fem_calibration_data_t *p_calibration_data)
    {
    }
     
    static void model_fetch(int8_t                        requested_power,
                            uint16_t                       freq_mhz,
                            mpsl_fem_power_model_output_t *p_output)
    {
          (void) freq_mhz;
    
          printk("model_fetch() requested_power=%d soc_pwr=%d\n", requested_power,  mpsl_tx_power_radio_supported_power_adjust(requested_power) );
    
          p_output->soc_pwr = mpsl_tx_power_radio_supported_power_adjust(requested_power);
          p_output->fem.gain_db = 0;
          p_output->achieved_pwr = 9;
    }
     
    static const mpsl_fem_power_model_t model = {.fetch = model_fetch, .init = model_init};
    
    const mpsl_fem_power_model_t *mpsl_fem_power_model_to_use_get(void)
    {
          return &model;
    }

    I'm not able to debug the network core crash because it just reboots even after setting the following config options.

    CONFIG_THREAD_MONITOR=y
    CONFIG_DEBUG_THREAD_INFO=y
    CONFIG_THREAD_NAME=y
    CONFIG_RESET_ON_FATAL_ERROR=n
    CONFIG_ASSERT=y
    CONFIG_ASSERT_NO_COND_INFO=y
    CONFIG_ASSERT_NO_MSG_INFO=y
  • Hi Ronald

    What if you remove the printk(..) call? 

    As mentioned in the documentation this function has to execute in less than 2us, and I think it is quite limited what kind of library or kernel functions you can invoke, including logging or console commands. 

    Best regards
    Torbjørn

  • Hi Torbjørn,

    It still crashes without the printk(). I added it there to debug the crash.

    Do you guys have a sample app that works on the nRF5340DK board that has the CONFIG_MPSL_FEM_POWER_MODEL set to 'y' and mpsl_fem_power_model_to_use_get() implemented?

    Thanks,

    ronbo999

Reply Children
  • Hi Ron

    There is no sample showing how to use this function unfortunately. There is a built in default power model, but the source code is not provided since this is a part of the SoftDevice controller. 

    The closest is this file which handles triggering of the internal power model repeatedly when there is a large change in temperature, but again the actual power model function is not shown. 

    I have asked the developers for some input on your code and I will update you once I hear back. 

    Did you ever test without running any code in the function to see if it still crashes?

    Best regards
    Torbjørn

  • Hi Torbjørn,

    Yes. I tested with just an empty function for the init and get functions. The net core still crashes when an HCI TX POWER message is sent from the app core to the net core.

    Regards,

    ronbo999

  • Hi Torbjørn,

    Just an update. The network core is actually crashing when the app core calls the bt_le_adv_start().

    If I comment out the bt_le_adv_start() or set CONFIG_MPSL_FEM_POWER_MODEL=n then the network core doesn't crash.

    I should be able to call the bt_le_adv_start() when CONFIG_MPSL_FEM_POWER_MODEL=y right?

    Thanks,

    ronbo999

  • Hi Ron

    What is the gain of the connected PA?

    According to the developers it is critical that the value assigned to p_output->fem.gain_db should be the same as the value configured in the device tree. 

    If these values are not in accordance it will trigger an assert in the controller. 

    Best regards
    Torbjørn

  • Hi Torbjørn,

    The gain of the connected PA is set to -10 dBm.

    I updated my model init and fetch routines to look like this.

    static int8_t gFemGain = 0;
    
    static void model_init(const mpsl_fem_calibration_data_t *p_calibration_data)
    {
       gFemGain = p_calibration_data->simple_gpio.gain;
    }
     
    static void model_fetch(int8_t                        requested_power,
                            uint16_t                       freq_mhz,
                            mpsl_fem_power_model_output_t *p_output)
    {
          (void) freq_mhz;
    
          p_output->soc_pwr      = mpsl_tx_power_radio_supported_power_adjust(requested_power);
          p_output->fem.gain_db  = gFemGain;
          p_output->achieved_pwr = requested_power;
    }

    Setting the p_output->fem.gain_db to the same value that's in the device tree does fix the network core reset issue.

    The following table shows the Radio Power values with their corresponding TXPOWER register value:

    Radio Tx Power TXPOWEER register
    3 0xFE => -2 dBm w/VREGRADIO.VREQH=1
    2 0xFE => -2 dBm w/VREGRADIO.VREQH=1
    1 0xFE => -2 dBm w/VREGRADIO.VREQH=1
    0 0x00 => 0 dBm
    -1 0xFF => -1 dBm
    -2 0xFE => -2 dBm
    -3 0xFD => -3 dBm
    -4 0xFC => -4 dBm
    -5 0xFB => -5 dBm
    -6 0xFA => -6 dBm
    -7 0xF9 => -7 dBm
    -8 0xF8 => -8 dBm
    -12 0xF4 => -12 dBm
    -16 0xF0 => -16 dBm

    Everything looks good except for the 1st two rows. The 1st two rows should look like this:

    Radio Tx Power TXPOWER Register
    3 0x00 => 0 dBm w/VREGRADIO.VREQH=1
    2 0xFF => -1 dBm w/VREGRADIO.VREQH=1

    because if VREGADIO.VREQH=1, there's a +3 dBm TX power that's added on the radio.

    In NCS 2.0, we got the right TXPOWER register values for Radio Tx Power 2 &3.

    Thanks,

    ronbo999

Related