cancel
Showing results for 
Search instead for 
Did you mean: 

set_tx_power_level() and get_tx_power_level() on Zephyr using the STM32WBA55

STTwo-32
ST Employee

Introduction

In this article, we provide a method to modify TX power levels as available in the STM32CubeWBA using ACI_HAL_SET_TX_POWER_LEVEL and read power levels like HCI_READ_TRANSMIT_POWER_LEVEL. This method is implemented usjng the Zephyr example peripheral_hr using the Nucleo-WBA55CG.

The modified version of the main.c file is attached at the end of the article. 

1. Implementation

First, open the main.c of the peripheral_hr example then replace the original code with the new one accordingly:

Original code line 17-22

#include <zephyr/bluetooth/services/bas.h>
#include <zephyr/bluetooth/services/hrs.h>

static bool hrf_ntf_enabled;​

New code line 17-38

#include <zephyr/bluetooth/gatt.h>
#include <zephyr/bluetooth/services/bas.h>
#include <zephyr/bluetooth/services/hrs.h>
#include <zephyr/sys/byteorder.h>

static struct bt_conn *default_conn;
static uint16_t default_conn_handle;

#define ACI_HAL_SET_TX_POWER_LEVEL       BT_OP(BT_OGF_VS, 0xFC0F)

	struct aci_set_tx_power {
		uint8_t cmd;
		uint8_t value[2];
	};

	struct aci_set_tx_power *param;
	struct net_buf *buf, *rsp;

	struct bt_hci_cp_read_tx_power_level *param_r;
	
static bool hrf_ntf_enabled;​

 


Original code line 43-61

#define STATE_CONNECTED    1U
#define STATE_DISCONNECTED 2U

static void connected(struct bt_conn *conn, uint8_t err)
{
	if (err) {
		printk("Connection failed, err 0x%02x %s\n", err, bt_hci_err_to_str(err));
	} else {
		printk("Connected\n");

		(void)atomic_set_bit(state, STATE_CONNECTED);
	}
}

static void disconnected(struct bt_conn *conn, uint8_t reason)
{
	printk("Disconnected, reason 0x%02x %s\n", reason, bt_hci_err_to_str(reason));

	(void)atomic_set_bit(state, STATE_DISCONNECTED);

New code line 59-119

#define STATE_CONNECTED    1U
#define STATE_DISCONNECTED 2U

static int get_tx_power(uint16_t handle)
{

	int err = 0;
	struct bt_hci_rp_read_tx_power_level *rp;

	/* HCI_READ_TRANSMIT_POWER_LEVEL */
	buf = bt_hci_cmd_create(BT_HCI_OP_READ_TX_POWER_LEVEL, sizeof(*param_r));
	if (!buf) {
		printk("Failed - buf creation failed \n\r");
		return -ENOBUFS;
	}
	param_r = net_buf_add(buf, sizeof(*param_r));
	param_r->handle = sys_cpu_to_le16(handle);
	param_r->type = BT_TX_POWER_LEVEL_CURRENT;

	err = bt_hci_cmd_send_sync(BT_HCI_OP_READ_TX_POWER_LEVEL, buf, &rsp);
	if (err) {
		printk("Failed - hci_read_transmit_power_level : %d\n\r", err);
		return err;
	}

	rp = (void *) rsp->data;
	printk ("Current TX power level in dBm : %d\n\r",rp->tx_power_level);

	net_buf_unref(rsp);

	return 0;
}

static void connected(struct bt_conn *conn, uint8_t err)
{
	
	int ret;
	if (err) {
		printk("Connection failed, err 0x%02x %s\n", err, bt_hci_err_to_str(err));
	} else {
		printk("Connected\n");
		default_conn = bt_conn_ref(conn);
		ret = bt_hci_get_conn_handle(default_conn, &default_conn_handle);
		
		(void)atomic_set_bit(state, STATE_CONNECTED);
		if(ret) {
			printk("No connection handle (err %d)\n", ret);
		}
		else {
			printk("Conn handle : %d\n", default_conn_handle);
			get_tx_power(default_conn_handle);
		}	}	
}

static void disconnected(struct bt_conn *conn, uint8_t reason)
{
	bt_conn_unref(conn);
	conn = NULL;	
	printk("Disconnected, reason 0x%02x %s\n", reason, bt_hci_err_to_str(reason));

	(void)atomic_set_bit(state, STATE_DISCONNECTED);

 



Original code line 198-203


	printk("Bluetooth initialized\n");

	bt_conn_auth_cb_register(&auth_cb_display);

	bt_hrs_cb_register(&hrs_cb);

New code line 256-282


	printk("Bluetooth initialized\n");

	/* Send ACI_HAL_SET_TX_POWER_LEVEL */
	buf = bt_hci_cmd_create(ACI_HAL_SET_TX_POWER_LEVEL, 3);
	if (!buf) {
		return -ENOBUFS;
	}
	param = net_buf_add(buf, sizeof(*param));
	/* See STM32WBA table conversion in Annex A */
	param->value[0] = 0x0F;
	/* Deprecated and ignored */
	param->value[1] = 0x00;

	err = bt_hci_cmd_send_sync(ACI_HAL_SET_TX_POWER_LEVEL, buf, &rsp);
	if (err) {
		printk("Failed - aci_hal_tx_pwr : %d\n\r", err);
		return err;
	}
	else{
		printk("Setting PA output level to : 0x%02x \n\r", param->value[0]);
	}
	net_buf_unref(rsp);

	bt_conn_auth_cb_register(&auth_cb_display);

	bt_hrs_cb_register(&hrs_cb);

This code sets the desired TX power (-10dBm in this case) and reads the new TX power. If you want to change the TX power to another value, replace the value of "param->value[0]"

/* See STM32WBA table conversion in Annex A */
    param->value[0] = 0x0F;

with the value of PA_Level corresponding to the values in dBm you are looking for according to the TX Power Level table in this HTML file. (0x0F is for -10dBm).

Version history
Last update:
‎2025-01-28 03:09 AM
Updated by: