Skip to content

Commit 6c85cfa

Browse files
thekurtovich2zero
andauthored
NimBLEDevice::get/setPower support full power range. (#229)
* Calculates the tx power level to and from dbm to `esp_power_level` types for esp32 devices. * Add esp32 specific funtions `NimBLEDevice::setPowerLevel` and `NimBLEDevice::getPowerLevel` which take and return the related `esp_power_level* ` types. --------- Co-authored-by: h2zero <powell.rg@gmail.com>
1 parent 15392bf commit 6c85cfa

File tree

2 files changed

+53
-54
lines changed

2 files changed

+53
-54
lines changed

src/NimBLEDevice.cpp

Lines changed: 46 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -421,47 +421,51 @@ std::vector<NimBLEClient*> NimBLEDevice::getConnectedClients() {
421421
/* TRANSMIT POWER */
422422
/* -------------------------------------------------------------------------- */
423423

424+
# ifdef ESP_PLATFORM
425+
/**
426+
* @brief Get the transmission power.
427+
* @return The power level currently used in esp_power_level_t.
428+
*/
429+
esp_power_level_t NimBLEDevice::getPowerLevel(esp_ble_power_type_t powerType) {
430+
# ifdef CONFIG_IDF_TARGET_ESP32P4
431+
return 0xFF; // CONFIG_IDF_TARGET_ESP32P4 does not support esp_ble_tx_power_get
432+
# else
433+
return esp_ble_tx_power_get(powerType);
434+
# endif
435+
} // getPowerLevel
436+
424437
/**
425438
* @brief Set the transmission power.
426-
* @param [in] dbm The power level to set in dBm.
439+
* @param [in] powerLevel The power level to set in esp_power_level_t.
427440
* @return True if the power level was set successfully.
428441
*/
429-
bool NimBLEDevice::setPower(int8_t dbm) {
430-
NIMBLE_LOGD(LOG_TAG, ">> setPower: %d", dbm);
431-
# ifdef ESP_PLATFORM
432-
# ifndef CONFIG_IDF_TARGET_ESP32P4
433-
if (dbm >= 9) {
434-
dbm = ESP_PWR_LVL_P9;
435-
} else if (dbm >= 6) {
436-
dbm = ESP_PWR_LVL_P6;
437-
} else if (dbm >= 3) {
438-
dbm = ESP_PWR_LVL_P3;
439-
} else if (dbm >= 0) {
440-
dbm = ESP_PWR_LVL_N0;
441-
} else if (dbm >= -3) {
442-
dbm = ESP_PWR_LVL_N3;
443-
} else if (dbm >= -6) {
444-
dbm = ESP_PWR_LVL_N6;
445-
} else if (dbm >= -9) {
446-
dbm = ESP_PWR_LVL_N9;
447-
} else if (dbm >= -12) {
448-
dbm = ESP_PWR_LVL_N12;
449-
} else {
450-
NIMBLE_LOGE(LOG_TAG, "Unsupported power level");
451-
return false;
452-
}
453-
454-
esp_err_t errRc = esp_ble_tx_power_set(ESP_BLE_PWR_TYPE_DEFAULT, (esp_power_level_t)dbm);
442+
bool NimBLEDevice::setPowerLevel(esp_power_level_t powerLevel, esp_ble_power_type_t powerType) {
443+
# ifdef CONFIG_IDF_TARGET_ESP32P4
444+
return false; // CONFIG_IDF_TARGET_ESP32P4 does not support esp_ble_tx_power_set
445+
# else
446+
esp_err_t errRc = esp_ble_tx_power_set(powerType, powerLevel);
455447
if (errRc != ESP_OK) {
456448
NIMBLE_LOGE(LOG_TAG, "esp_ble_tx_power_set: rc=%d", errRc);
457449
}
458450

459451
return errRc == ESP_OK;
460-
# else
461-
return 0xFF; // CONFIG_IDF_TARGET_ESP32P4
462452
# endif
453+
} // setPowerLevel
463454

455+
# endif
456+
/**
457+
* @brief Set the transmission power.
458+
* @param [in] dbm The power level to set in dBm.
459+
* @return True if the power level was set successfully.
460+
*/
461+
bool NimBLEDevice::setPower(int8_t dbm) {
462+
# ifdef ESP_PLATFORM
463+
if (dbm % 3 == 2) {
464+
dbm++; // round up to the next multiple of 3 to be able to target 20dbm
465+
}
466+
return setPowerLevel(static_cast<esp_power_level_t>(dbm / 3 + ESP_PWR_LVL_N0));
464467
# else
468+
NIMBLE_LOGD(LOG_TAG, ">> setPower: %d", dbm);
465469
ble_hci_vs_set_tx_pwr_cp cmd{dbm};
466470
ble_hci_vs_set_tx_pwr_rp rsp{0};
467471
int rc = ble_hs_hci_send_vs_cmd(BLE_HCI_OCF_VS_SET_TX_PWR, &cmd, sizeof(cmd), &rsp, sizeof(rsp));
@@ -478,34 +482,24 @@ bool NimBLEDevice::setPower(int8_t dbm) {
478482
/**
479483
* @brief Get the transmission power.
480484
* @return The power level currently used in dbm.
485+
* @note ESP32S3 only returns 0xFF as of IDF 5, so this function will return 20dbm.
481486
*/
482487
int NimBLEDevice::getPower() {
483488
# ifdef ESP_PLATFORM
484-
# ifndef CONFIG_IDF_TARGET_ESP32P4
485-
switch (esp_ble_tx_power_get(ESP_BLE_PWR_TYPE_DEFAULT)) {
486-
case ESP_PWR_LVL_N12:
487-
return -12;
488-
case ESP_PWR_LVL_N9:
489-
return -9;
490-
case ESP_PWR_LVL_N6:
491-
return -6;
492-
case ESP_PWR_LVL_N3:
493-
return -3;
494-
case ESP_PWR_LVL_N0:
495-
return 0;
496-
case ESP_PWR_LVL_P3:
497-
return 3;
498-
case ESP_PWR_LVL_P6:
499-
return 6;
500-
case ESP_PWR_LVL_P9:
501-
return 9;
502-
default:
503-
return 0xFF;
504-
}
505-
# else
489+
# ifdef CONFIG_IDF_TARGET_ESP32P4
506490
return 0xFF; // CONFIG_IDF_TARGET_ESP32P4 does not support esp_ble_tx_power_get
507-
# endif
491+
# else
492+
int pwr = esp_ble_tx_power_get(ESP_BLE_PWR_TYPE_DEFAULT);
493+
if (pwr < ESP_PWR_LVL_N0) {
494+
return -3 * (ESP_PWR_LVL_N0 - pwr);
495+
}
496+
497+
if (pwr > ESP_PWR_LVL_N0) {
498+
return std::min<int>((pwr - ESP_PWR_LVL_N0) * 3, 20);
499+
}
508500

501+
return 0;
502+
# endif
509503
# else
510504
return ble_phy_txpwr_get();
511505
# endif

src/NimBLEDevice.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,6 @@ class NimBLEDevice {
114114
static bool onWhiteList(const NimBLEAddress& address);
115115
static size_t getWhiteListCount();
116116
static NimBLEAddress getWhiteListAddress(size_t index);
117-
static bool setPower(int8_t dbm);
118-
static int getPower();
119117
static bool setOwnAddrType(uint8_t type);
120118
static bool setOwnAddr(const NimBLEAddress& addr);
121119
static bool setOwnAddr(const uint8_t* addr);
@@ -135,6 +133,13 @@ class NimBLEDevice {
135133
static void onReset(int reason);
136134
static void onSync(void);
137135
static void host_task(void* param);
136+
static int getPower();
137+
static bool setPower(int8_t dbm);
138+
139+
# if defined(ESP_PLATFORM)
140+
static esp_power_level_t getPowerLevel(esp_ble_power_type_t powerType = ESP_BLE_PWR_TYPE_DEFAULT);
141+
static bool setPowerLevel(esp_power_level_t powerLevel, esp_ble_power_type_t powerType = ESP_BLE_PWR_TYPE_DEFAULT);
142+
# endif
138143

139144
# if CONFIG_BT_NIMBLE_EXT_ADV
140145
static bool setDefaultPhy(uint8_t txPhyMask, uint8_t rxPhyMask);

0 commit comments

Comments
 (0)