Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions docs/psoc6/quickref.rst
Original file line number Diff line number Diff line change
Expand Up @@ -998,6 +998,30 @@ Here is a function you can run (or put in your boot.py file) to automatically co
else:
print(wlan.ifconfig())


Bluetooth Module
-----------------
The ``bluetooth`` module.

See module :mod:`bluetooth`

For some methods and constants, the PSoC6 bluetooth module implements certain specializations and slightly different behaviour. This is explained in this section.

Methods
^^^^^^^
.. method:: BLE.config('param', /)
BLE.config(*, param=value, ...)

Among the suggested parameters of the general BLE.config() API, for this port, only these are available:

- ``'addr_mode'``: Supported values:

* 0x00 - PUBLIC - Use the controller's public address.
* 0x01 - RANDOM - Use a generated static address.

- ``'mtu'``, ``'bond'``, ``'mitm'``, ``'io'`` and ``'le_secure'`` will be evaluated for enablement in future.


NeoPixel driver
---------------

Expand Down
92 changes: 80 additions & 12 deletions ports/psoc6/modbluetooth.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,16 @@
// ******************************************************************************
#if MICROPY_PY_BLUETOOTH
#define NUM_ADV_PACKETS (3u)

#define ERRNO_BLUETOOTH_NOT_ACTIVE MP_ENODEV
#define CASE_RETURN_STR(const) case const: \
return #const;

// Bring externs from MTB GeneratedSource/
extern uint8_t app_gap_device_name[];

// MPY defines and variables
volatile int mp_bluetooth_ble_stack_state = MP_BLUETOOTH_BLE_STATE_OFF;
static uint8_t address_mode = BLE_ADDR_PUBLIC;

// ToDo: Add appropriate BLE device name in GeneratedSource/cycfg_bt_settings.c. Currently it is set to "Hello"

Expand Down Expand Up @@ -178,20 +183,16 @@ static void ble_init() {
wiced_result_t bt_management_callback(wiced_bt_management_evt_t event,
wiced_bt_management_evt_data_t *p_event_data) {
wiced_result_t wiced_result = WICED_BT_SUCCESS;
wiced_bt_device_address_t bda = { 0 };

switch (event)
{
case BTM_ENABLED_EVT:
/* Bluetooth Controller and Host Stack Enabled */
if (WICED_BT_SUCCESS == p_event_data->enabled.status) {
wiced_result = wiced_bt_set_local_bdaddr((uint8_t *)cy_bt_device_address, BLE_ADDR_PUBLIC);
wiced_bt_dev_read_local_addr(bda);

/* Perform application-specific initialization */
ble_init();
} else {
mp_printf(&mp_plat_print, "Bluetooth Disabled \n");
mp_printf(&mp_plat_print, "Bluetooth disabled \n");
}
break;

Expand Down Expand Up @@ -275,23 +276,85 @@ bool mp_bluetooth_is_active(void) {
return mp_bluetooth_ble_stack_state == MP_BLUETOOTH_BLE_STATE_ACTIVE;
}

void print_bd_address(wiced_bt_device_address_t bdadr) {
printf("%02X:%02X:%02X:%02X:%02X:%02X \n", bdadr[0], bdadr[1], bdadr[2], bdadr[3], bdadr[4], bdadr[5]);
}

// Gets the current address of this device in big-endian format.
void mp_bluetooth_get_current_address(uint8_t *addr_type, uint8_t *addr) {
// wiced_bt_device_address_t bda = { 0 };
if (!mp_bluetooth_is_active()) {
mp_raise_OSError(ERRNO_BLUETOOTH_NOT_ACTIVE);
}
switch (address_mode) {
case BLE_ADDR_PUBLIC:
*addr_type = BLE_ADDR_PUBLIC;
break;
case BLE_ADDR_RANDOM:
*addr_type = BLE_ADDR_RANDOM;
break;
default:
mp_raise_OSError(MP_EINVAL);
}

wiced_bt_dev_read_local_addr(addr);
}

// Sets the addressing mode to use.
void mp_bluetooth_set_address_mode(uint8_t addr_mode) {
static void generate_random_address(wiced_bt_device_address_t addr) {
cyhal_trng_t trng_obj;
uint32_t random_data[2];
cy_rslt_t rslt = cyhal_trng_init(&trng_obj);
if (rslt != CY_RSLT_SUCCESS) {
mp_raise_msg(&mp_type_Exception, MP_ERROR_TEXT("TRNG init failed!\n"));
}
random_data[0] = cyhal_trng_generate(&trng_obj);
random_data[1] = cyhal_trng_generate(&trng_obj);
memcpy(addr, random_data, 6);
cyhal_trng_free(&trng_obj);
}

// Sets the addressing mode to use.Alongwith it already sets the address as well based on mode selected
void mp_bluetooth_set_address_mode(uint8_t addr_mode) {
wiced_bt_device_address_t addr;
if (!mp_bluetooth_is_active()) {
mp_raise_OSError(ERRNO_BLUETOOTH_NOT_ACTIVE);
}
switch (addr_mode) {
case MP_BLUETOOTH_ADDRESS_MODE_PUBLIC: {
address_mode = BLE_ADDR_PUBLIC;
for (int i = 0; i < 5; i++) {
addr[i] = *(cy_bt_device_address + i);
}
break;
}
case MP_BLUETOOTH_ADDRESS_MODE_RANDOM: {
address_mode = BLE_ADDR_RANDOM;
generate_random_address(addr);
addr[5] = (addr[5] & 0x3F) | 0xC0; // MSB[0:1] - 11 - Static Random Address
break;
}
// ToDo: This is in a way supported from MTB BLE stack side but is complicated to map to MPY side. Requires NVRAM to store the keys. Considering this is not an absolutely necessary feature, let's postpone for extension after MVP?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From all these key storage requirements, is there an example of how is this done in other cores?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have only 3 references. All the ports that have BLE support depend on nimble or btstack and in each following is the implementation:

  1. extmod/nimble/modbluetooth_nimble.c : IRK is stored in NVM. This might give some explanation
  2. extmod/btstack/modbluetooth_stack.c : Not supported (https://github.com/Infineon/micropython/blob/ports-psoc6-main/extmod/btstack/modbluetooth_btstack.c#L777)
  3. ports/zephyr/modbluetooth_zephyr.c : Not supported

We have API's in MTB BLE stack to do this, but just that it is not evaluated yet how to especially with the NVM enablement part.

case MP_BLUETOOTH_ADDRESS_MODE_RPA:
case MP_BLUETOOTH_ADDRESS_MODE_NRPA:
// Not yet supported.
mp_raise_OSError(MP_EINVAL);
break;
}
wiced_result_t wiced_result = wiced_bt_set_local_bdaddr(addr, address_mode);
if (WICED_BT_SUCCESS != wiced_result) {
mp_printf(&mp_plat_print, "Device address setting failed!\n");
}
}

// Get or set the GAP device name that will be used by service 0x1800, characteristic 0x2a00.
size_t mp_bluetooth_gap_get_device_name(const uint8_t **buf) {
return 0;
*buf = (const uint8_t *)app_gap_device_name;
return strlen((const char *)app_gap_device_name);
}

int mp_bluetooth_gap_set_device_name(const uint8_t *buf, size_t len) {
return 0;
mp_raise_msg(&mp_type_Exception, MP_ERROR_TEXT("Feature unsupported: Device name cannot be set in run-time for this port.\n"));
return MP_EOPNOTSUPP;
}

// Start advertisement. Will re-start advertisement when already enabled.
Expand Down Expand Up @@ -344,11 +407,16 @@ int mp_bluetooth_gap_disconnect(uint16_t conn_handle) {
}

// Set/get the MTU that we will respond to a MTU exchange with.
// ToDo: wiced_bt_l2cap_le_get_peer_mtu gets the peer mtu but needs L2CAP connection established. Handle in L2CAP enablement // Default size is GATT_BLE_DEFAULT_MTU_SIZE : 23
int mp_bluetooth_get_preferred_mtu(void) {
return 0;
return GATT_BLE_DEFAULT_MTU_SIZE;
}

// ToDo: wiced_bt_gatt_client_configure_mtu allows configuring mtu size but needs GATT connection handle. Handle in GATT enablement.
int mp_bluetooth_set_preferred_mtu(uint16_t mtu) {
return 0;
if (!mp_bluetooth_is_active()) {
return ERRNO_BLUETOOTH_NOT_ACTIVE;
}
return MP_EOPNOTSUPP;
}
#endif
4 changes: 4 additions & 0 deletions ports/psoc6/mpconfigport.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,10 @@
#define MICROPY_TIME_SUPPORT_Y1969_AND_BEFORE (1)

#define MICROPY_PY_MACHINE_PULSE (1)

// BLE
#define MICROPY_PY_BLUETOOTH_USE_SYNC_EVENTS (1)

// VFS
#define MICROPY_VFS (1)
#define MICROPY_READER_VFS (1)
Expand Down
22 changes: 20 additions & 2 deletions tests/ports/psoc6/board_only_hw/single/ble_basics.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,28 @@
raise SystemExit


def irq_handle(event, data):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we already add this tests to the HIL? Or to early!?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The events possible in this handler are the only ones listed here: https://ifx-micropython.readthedocs.io/en/latest/library/bluetooth.html#bluetooth.BLE.irq
This is right now solved in extmod/modbluetooth.c already. We need to at least enable the roles test this irq functionality wise. These are the next tickets I am working on. So I would say, little more time that we get the test in required shape.

pass


ble_obj = bluetooth.BLE()
ble_obj.active(True)
print("BLE active: ", ble_obj.active())

print("Turning off BLE radio")
# Config get test
print("\n** Configurations set for device **")
print("GAP_NAME: ", ble_obj.config("gap_name"))
print("MTU: ", ble_obj.config("mtu"))

ble_obj.config(addr_mode=0) # Public
print("MAC: ", ble_obj.config("mac")[1].hex())

# Check if ble.irq registers handle
ble_obj.irq(irq_handle)

# Cannot be verified since trng is used and changes in every test
# ble_obj.config(addr_mode=1) #Static Random
# print("Set random address: ", ble_obj.config("mac")[1].hex())
print("\n")
ble_obj.active(False)
print("BLE active: ", ble_obj.active())
print("Turned off BLE radio: ", not ble_obj.active())
10 changes: 8 additions & 2 deletions tests/ports/psoc6/board_only_hw/single/ble_basics.py.exp
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
Bluetooth Stack Initialization Successful
BLE active: True
Turning off BLE radio

** Configurations set for device **
GAP_NAME: b'Hello'
MTU: 23
MAC: 00a050000000


Bluetooth disabled
BLE active: False
Turned off BLE radio: True
Loading