Method 1 - Setting the output power using the BHET by creating a customized SP.
Now I have the selection window which looks like this:
As you can see the the BT/BLE Max output power settings range from 0dB to 12dB. This does not correspond to the default power vector described here in any way. I also couldn't find any mapping table.
Power Level | dBm | Value in bts file |
---|---|---|
15 | 12 | 0x18 |
14 | 7 | 0x0e |
13 | 2 | 0x04 |
12 | -3 | 0xfa |
11 | -8 | 0xf0 |
10 | -13 | 0xe6 |
9 | -18 | 0xdc |
8 | -23 | 0xd2 |
7 | -23 | 0xd2 |
6 | -23 | 0xd2 |
5 | -23 | 0xd2 |
4 | -23 | 0xd2 |
3 | -23 | 0xd2 |
2 | -23 | 0xd2 |
1 | 18 | 0x18 |
0 | -50 | 0x9c |
The qualification engeneer tells me I have to choose power level 9 (-18dB) in order not to violate regulations with my design. So how do I generate a service pack that sets the power level accordingly? Which levels do I have to pick in the dropdowns above?
This picture shows the RF-Testing Tab used by the qualification engineer to evaluate the hardware design. Here the power levels seem to match the power levels in the vector.
Method 2 - Using the vendor specific commands described in the Wiki
You BLUETOOTH_MAX_TRANSMIT_POWER_LEVEL_DB is #defined to be -18. The code is executed without any errors.
//! \brief
//! \details //! \date 2015-01-11 (MB) - Creation static void Bluetooth_vA_SetTransmitPowerLevel(void) { #define BLUETOOTH_HCI_GET_OGF(_cmd) (((_cmd) >> 10) & 0x3F) #define BLUETOOTH_HCI_GET_OCF(_cmd) ((_cmd) & 0x3FF) #define BLUETOOTH_VS_SETPWRVECT_CMD 0xFD82 #define BLUETOOTH_VS_SETPWRVECT_OGF BLUETOOTH_HCI_GET_OGF(BLUETOOTH_VS_SETPWRVECT_CMD) #define BLUETOOTH_VS_SETPWRVECT_OCF BLUETOOTH_HCI_GET_OCF(BLUETOOTH_VS_SETPWRVECT_CMD) #define BLUETOOTH_VS_SETMAXSINGLEPWR_CMD 0xFD87 #define BLUETOOTH_VS_SETMAXSINGLEPWR_OGF BLUETOOTH_HCI_GET_OGF(BLUETOOTH_VS_SETMAXSINGLEPWR_CMD) #define BLUETOOTH_VS_SETMAXSINGLEPWR_OCF BLUETOOTH_HCI_GET_OCF(BLUETOOTH_VS_SETMAXSINGLEPWR_CMD) #define BLUETOOTH_VS_POWERCALIB_CMD 0xFD80 #define BLUETOOTH_VS_POWERCALIB_OGF BLUETOOTH_HCI_GET_OGF(BLUETOOTH_VS_POWERCALIB_CMD) #define BLUETOOTH_VS_POWERCALIB_OCF BLUETOOTH_HCI_GET_OCF(BLUETOOTH_VS_POWERCALIB_CMD) #define BLUETOOTH_VS_SETBLEPWR_CMD 0xFDDD #define BLUETOOTH_VS_SETBLEPWR_OGF BLUETOOTH_HCI_GET_OGF(BLUETOOTH_VS_SETBLEPWR_CMD) #define BLUETOOTH_VS_SETBLEPWR_OCF BLUETOOTH_HCI_GET_OCF(BLUETOOTH_VS_SETBLEPWR_CMD) #define BLUETOOTH_VS_MODULATION_GFSK 0x00 #define BLUETOOTH_VS_MODULATION_EDR2 0x01 #define BLUETOOTH_VS_MODULATION_EDR3 0x02 static const uint8_t aui8ModGfsk[] = { 0x00 }; static const uint8_t aui8ModEdr2[] = { 0x01 }; static const uint8_t aui8ModEdr3[] = { 0x02 }; static const int8_t ai8PowerLevelVector[] = { BLUETOOTH_MAX_TRANSMIT_POWER_LEVEL_DB * 2, BLUETOOTH_MAX_TRANSMIT_POWER_LEVEL_DB * 2, BLUETOOTH_MAX_TRANSMIT_POWER_LEVEL_DB * 2, BLUETOOTH_MAX_TRANSMIT_POWER_LEVEL_DB * 2, BLUETOOTH_MAX_TRANSMIT_POWER_LEVEL_DB * 2, BLUETOOTH_MAX_TRANSMIT_POWER_LEVEL_DB * 2, BLUETOOTH_MAX_TRANSMIT_POWER_LEVEL_DB * 2, BLUETOOTH_MAX_TRANSMIT_POWER_LEVEL_DB * 2, BLUETOOTH_MAX_TRANSMIT_POWER_LEVEL_DB * 2, BLUETOOTH_MAX_TRANSMIT_POWER_LEVEL_DB * 2, BLUETOOTH_MAX_TRANSMIT_POWER_LEVEL_DB * 2, BLUETOOTH_MAX_TRANSMIT_POWER_LEVEL_DB * 2, BLUETOOTH_MAX_TRANSMIT_POWER_LEVEL_DB * 2, BLUETOOTH_MAX_TRANSMIT_POWER_LEVEL_DB * 2, BLUETOOTH_MAX_TRANSMIT_POWER_LEVEL_DB * 2, BLUETOOTH_MAX_TRANSMIT_POWER_LEVEL_DB * 2, }; static const uint8_t aui8TxPwrEdrEpcIdx[] = { 0xff }; // leave unchanged static const uint8_t aui8ExtPaMode[] = { 0x00, 0x00 }; // no external power amplifier static const uint8_t aui8SingleModePwr[] = { 0x0f, 0x0f, 0x0f }; // max for all modulation types static const uint8_t aui8PowerCalib1[] = { 0x00, 0x00, 0x00, 0x00, 0x01, 0x01 }; static const uint8_t aui8PowerCalib2[] = { 0x3c, 0x00, 0x00, 0x5f, 0xf0, 0x00 }; static const uint8_t aui8BlePwr[] = { 0x0f }; // ble power is max uint8_t ui8RspStatus, ui8RspLength; uint8_t aui8CmdData[20]; uint8_t aui8RspData[20]; ui8RspStatus = 0; ui8RspLength = sizeof(aui8RspData); memcpy(&aui8CmdData[0], aui8ModGfsk, sizeof(aui8ModGfsk)); memcpy(&aui8CmdData[sizeof(aui8ModGfsk)], ai8PowerLevelVector, sizeof(ai8PowerLevelVector)); memcpy(&aui8CmdData[sizeof(aui8ModGfsk) + sizeof(ai8PowerLevelVector)], aui8TxPwrEdrEpcIdx, sizeof(aui8TxPwrEdrEpcIdx)); memcpy(&aui8CmdData[sizeof(aui8ModGfsk) + sizeof(ai8PowerLevelVector) + sizeof(aui8TxPwrEdrEpcIdx)], aui8ExtPaMode, sizeof(aui8ExtPaMode)); if (0 == HCI_Send_Raw_Command( sBluetoothS.sStackStatus.ui32BtStackId, BLUETOOTH_VS_SETPWRVECT_OGF, BLUETOOTH_VS_SETPWRVECT_OCF, sizeof(aui8ModGfsk) + sizeof(ai8PowerLevelVector) + sizeof(aui8TxPwrEdrEpcIdx) + sizeof(aui8ExtPaMode), aui8CmdData, &ui8RspStatus, &ui8RspLength, aui8RspData, TRUE)) { if (0 != ui8RspStatus) { Main_vFatal(BLUETOOTH_MODULE_ID); } } ui8RspLength = sizeof(aui8RspData); memcpy(&aui8CmdData[0], aui8ModEdr2, sizeof(aui8ModEdr2)); memcpy(&aui8CmdData[sizeof(aui8ModEdr2)], ai8PowerLevelVector, sizeof(ai8PowerLevelVector)); memcpy(&aui8CmdData[sizeof(aui8ModEdr2) + sizeof(ai8PowerLevelVector)], aui8TxPwrEdrEpcIdx, sizeof(aui8TxPwrEdrEpcIdx)); memcpy(&aui8CmdData[sizeof(aui8ModEdr2) + sizeof(ai8PowerLevelVector) + sizeof(aui8TxPwrEdrEpcIdx)], aui8ExtPaMode, sizeof(aui8ExtPaMode)); if (0 == HCI_Send_Raw_Command( sBluetoothS.sStackStatus.ui32BtStackId, BLUETOOTH_VS_SETPWRVECT_OGF, BLUETOOTH_VS_SETPWRVECT_OCF, sizeof(aui8ModEdr2) + sizeof(ai8PowerLevelVector) + sizeof(aui8TxPwrEdrEpcIdx) + sizeof(aui8ExtPaMode), aui8CmdData, &ui8RspStatus, &ui8RspLength, aui8RspData, TRUE)) { if (0 != ui8RspStatus) { Main_vFatal(BLUETOOTH_MODULE_ID); } } ui8RspLength = sizeof(aui8RspData); memcpy(&aui8CmdData[0], aui8ModEdr3, sizeof(aui8ModEdr3)); memcpy(&aui8CmdData[sizeof(aui8ModEdr3)], ai8PowerLevelVector, sizeof(ai8PowerLevelVector)); memcpy(&aui8CmdData[sizeof(aui8ModEdr3) + sizeof(ai8PowerLevelVector)], aui8TxPwrEdrEpcIdx, sizeof(aui8TxPwrEdrEpcIdx)); memcpy(&aui8CmdData[sizeof(aui8ModEdr3) + sizeof(ai8PowerLevelVector) + sizeof(aui8TxPwrEdrEpcIdx)], aui8ExtPaMode, sizeof(aui8ExtPaMode)); if (0 == HCI_Send_Raw_Command( sBluetoothS.sStackStatus.ui32BtStackId, BLUETOOTH_VS_SETPWRVECT_OGF, BLUETOOTH_VS_SETPWRVECT_OCF, sizeof(aui8ModEdr3) + sizeof(ai8PowerLevelVector) + sizeof(aui8TxPwrEdrEpcIdx) + sizeof(aui8ExtPaMode), aui8CmdData, &ui8RspStatus, &ui8RspLength, aui8RspData, TRUE)) { if (0 != ui8RspStatus) { Main_vFatal(BLUETOOTH_MODULE_ID); } } ui8RspLength = sizeof(aui8RspData); memcpy(&aui8CmdData[0], aui8SingleModePwr, sizeof(aui8SingleModePwr)); if (0 == HCI_Send_Raw_Command( sBluetoothS.sStackStatus.ui32BtStackId, BLUETOOTH_VS_SETMAXSINGLEPWR_OGF, BLUETOOTH_VS_SETMAXSINGLEPWR_OCF, sizeof(aui8SingleModePwr), aui8CmdData, &ui8RspStatus, &ui8RspLength, aui8RspData, TRUE)) { if (0 != ui8RspStatus) { Main_vFatal(BLUETOOTH_MODULE_ID); } } ui8RspLength = sizeof(aui8RspData); memcpy(&aui8CmdData[0], aui8PowerCalib1, sizeof(aui8PowerCalib1)); if (0 == HCI_Send_Raw_Command( sBluetoothS.sStackStatus.ui32BtStackId, BLUETOOTH_VS_POWERCALIB_OGF, BLUETOOTH_VS_POWERCALIB_OCF, sizeof(aui8PowerCalib1), aui8CmdData, &ui8RspStatus, &ui8RspLength, aui8RspData, TRUE)) { if (0 != ui8RspStatus) { Main_vFatal(BLUETOOTH_MODULE_ID); } } ui8RspLength = sizeof(aui8RspData); memcpy(&aui8CmdData[0], aui8PowerCalib2, sizeof(aui8PowerCalib2)); if (0 == HCI_Send_Raw_Command( sBluetoothS.sStackStatus.ui32BtStackId, BLUETOOTH_VS_POWERCALIB_OGF, BLUETOOTH_VS_POWERCALIB_OCF, sizeof(aui8PowerCalib2), aui8CmdData, &ui8RspStatus, &ui8RspLength, aui8RspData, TRUE)) { if (0 != ui8RspStatus) { Main_vFatal(BLUETOOTH_MODULE_ID); } } ui8RspLength = sizeof(aui8RspData); memcpy(&aui8CmdData[0], aui8BlePwr, sizeof(aui8BlePwr)); if (0 == HCI_Send_Raw_Command( sBluetoothS.sStackStatus.ui32BtStackId, BLUETOOTH_VS_SETBLEPWR_OGF, BLUETOOTH_VS_SETBLEPWR_OCF, sizeof(aui8BlePwr), aui8CmdData, &ui8RspStatus, &ui8RspLength, aui8RspData, TRUE)) { if (0 != ui8RspStatus) { Main_vFatal(BLUETOOTH_MODULE_ID); } } }