Alternative Methods to Convert between Power Levels and dBm Output Power#

For your application, having highly granular dBm output levels may not be necessary. Therefore, it may make sense to overwrite the RAIL_ConvertRawToDbm and RAIL_ConvertDbmToRaw functions that Silicon Labs provides. This example demonstrates how to simplify those functions to return only a few values of interest. Doing this would also allow you to remove calls to the RAIL_InitTxPowerCurves function and RAIL_DECLARE_TX_POWER_XXXX_CURVES macro. Removing these dependencies on the piecewise linear curve fits allows you to reduce application code size significantly. In this example, the functions are meant to work with common dBm values, such as 20, 13, 3, 0 and -10 (200, 130, 30, 0 and -100 deci-dBm, respectively).

RAIL_TxPowerLevel_t RAIL_ConvertDbmToRaw(RAIL_Handle_t railHandle,
                                         RAIL_TxPowerMode_t mode,
                                         RAIL_TxPower_t power)
{
  // Anything above this power is likely still an error, so it
  // should return an invalid value
  if (power >= RAIL_TX_POWER_MAX) {
    return RAIL_TX_POWER_LEVEL_INVALID;
  }
  if (mode == RAIL_TX_POWER_MODE_2P4_LP) {
    if (power >= 0) {
      return RAIL_TX_POWER_LEVEL_LP_MAX;
    } else if (power >= -100) {
      return 2;
    } else {
      return 1;
    }
  }
  if (mode == RAIL_TX_POWER_MODE_2P4_HP) {
    if (power >= 200) {
      return RAIL_TX_POWER_LEVEL_HP_MAX;
    } else if (power >= 130) {
      return 93;
    } else if (power >= 30) {
      return 33;
    } else if (power >= 0) {
      return 22;
    } else if (power >= -100) {
      return 7;
    } else {
      return 1;
    }
  }
  if (mode == RAIL_TX_POWER_MODE_SUBGIG) {
    if (power >= 200) {
      return RAIL_TX_POWER_LEVEL_SUBGIG_MAX;
    } else if (power >= 130) {
      return 86;
    } else if (power >= 30) {
      return 26;
    } else if (power >= 0) {
      return 18;
    } else if (power >= -100) {
      return 6;
    } else {
      return 1;
    }
  }
  // return an error value if no PA is initialized
  return RAIL_TX_POWER_MIN;
}
RAIL_TxPower_t RAIL_ConvertRawToDbm(RAIL_Handle_t railHandle,
                                    RAIL_TxPowerMode_t mode,
                                    RAIL_TxPowerLevel_t powerLevel)
{
  if (mode == RAIL_TX_POWER_MODE_2P4_LP) {
    if (powerLevel >= RAIL_TX_POWER_LEVEL_LP_MAX) {
      return 0;
    } else if (powerLevel >= 2) {
      return -100;
    } else {
      return 1;
    }
  }
  if (mode == RAIL_TX_POWER_MODE_2P4_HP) {
    if (powerLevel >= RAIL_TX_POWER_LEVEL_HP_MAX) {
      return 200;
    } else if (powerLevel >= 93) {
      return 130;
    } else if (powerLevel >= 33) {
      return 30;
    } else if (powerLevel >=22) {
      return 0;
    } else if (powerLevel >= -7) {
      return -100;
    } else {
      return -250;
    }
  }
  if (mode == RAIL_TX_POWER_MODE_SUBGIG) {
    if (powerLevel >= RAIL_TX_POWER_LEVEL_SUBGIG_MAX) {
      return 200;
    } else if (powerLevel >= 86) {
      return 130;
    } else if (powerLevel >= 26) {
      return 30;
    } else if (powerLevel >= 18) {
      return 0;
    } else if (powerLevel >= 6) {
      return -100;
    } else {
      return 1;
    }
  }
  // return an error value if no PA is initialized
  return RAIL_TX_POWER_MIN;
}