Skip to content

Commit 43fb25d

Browse files
Merge branch 'develop' into ina228
2 parents 8f6ed8a + 3cbc84b commit 43fb25d

53 files changed

Lines changed: 3391 additions & 264 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ add_subdirectory(gpio)
7878
add_subdirectory(hstx)
7979
add_subdirectory(i2c)
8080
add_subdirectory(interp)
81+
add_subdirectory(low_power)
8182
add_subdirectory(multicore)
8283
add_subdirectory(otp)
8384
add_subdirectory(picoboard)

README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,9 @@ App|Description
154154
[bmp280_i2c](i2c/bmp280_i2c) | Read and convert temperature and pressure data from a BMP280 sensor, attached to an I2C bus.
155155
[ina260_i2c](i2c/ina260_i2c) | Monitor power usage of another Pico device ina260 sensor, via I2C.
156156
[ina228_i2c](i2c/ina228_i2c) | Monitor power usage of another Pico device ina228 sensor, via I2C.
157+
[ina219_i2c](i2c/ina219_i2c) | Monitor power usage of another Pico device using an ina219 sensor, via I2C.
158+
[ina237_i2c](i2c/ina237_i2c) | Monitor power usage of another Pico device using an ina237 sensor, via I2C.
159+
[ina260_i2c](i2c/ina260_i2c) | Monitor power usage of another Pico device using an ina260 sensor, via I2C.
157160
[lcd_1602_i2c](i2c/lcd_1602_i2c) | Display some text on a generic 16x2 character LCD display, via I2C.
158161
[lis3dh_i2c](i2c/lis3dh_i2c) | Read acceleration and temperature value from a LIS3DH sensor via I2C
159162
[mcp9808_i2c](i2c/mcp9808_i2c) | Read temperature from a MCP9808 sensor, set limits and raise alerts when limits are surpassed.
@@ -173,6 +176,19 @@ App|Description
173176
---|---
174177
[hello_interp](interp/hello_interp) | A bundle of small examples, showing how to access the core-local interpolator hardware, and use most of its features.
175178

179+
### Low Power
180+
181+
These examples demonstrate how to use the pico_low_power library.
182+
183+
App|Description
184+
---|---
185+
[low_power_domant_timer](low_power/low_power_dormant) | Go dormant (disable clocks) and wakeup on a timer. Requires an external clock for when testing with RP2040. See [low_power_clksrc](low_power/low_power_dormant).
186+
[low_power_dormant_gpio](low_power/low_power_dormant) | Go dormant (disable clocks) and wakeup on a GPIO.
187+
[low_power_pstate_timer](low_power/low_power_pstate) | Go to a lower power state (RP2350 only) and restart on an AON timer.
188+
[low_power_pstate_gpio](low_power/low_power_pstate) | Go to a lower power state (RP2350 only) and restart on a GPIO.
189+
[low_power_sleep_timer](low_power/low_power_sleep) | Go to sleep and wakeup on a timer.
190+
[low_power_sleep_gpio](low_power/low_power_sleep) | Go to sleep and wakeup on a GPIO.
191+
176192
### Multicore
177193

178194
App|Description
@@ -202,6 +218,7 @@ These networking examples are only available if Wi-Fi is supported by the board.
202218
App|Description
203219
---|---
204220
[picow_access_point](pico_w/wifi/access_point) | Starts a WiFi access point, and fields DHCP requests.
221+
[picow_access_point_wifi_provisioning](pico_w/wifi/access_point_wifi_provisioning) | Starts a WiFi access point, and allows WiFi credentials to be provisioned through a web page.
205222
[picow_blink](pico_w/wifi/blink) | Blinks the on-board LED (which is connected via the WiFi chip).
206223
[picow_blink_slow_clock](pico_w/wifi/blink) | Blinks the on-board LED (which is connected via the WiFi chip) with a slower system clock to show how to reconfigure communication with the WiFi chip at run time under those circumstances.
207224
[picow_blink_fast_clock](pico_w/wifi/blink) | Blinks the on-board LED (which is connected via the WiFi chip) with a faster system clock to show how to reconfigure communication with the WiFi chip at build time under those circumstances.

bluetooth/ble_doorbell/client.c

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ static btstack_packet_callback_registration_t hci_event_callback_registration;
3737
static gc_state_t state = TC_OFF;
3838
static bd_addr_t server_addr;
3939
static bd_addr_type_t server_addr_type;
40-
static hci_con_handle_t connection_handle;
40+
static hci_con_handle_t con_handle;
4141
static gatt_client_service_t server_service;
4242
static gatt_client_characteristic_t server_characteristic;
4343
static bool listener_registered;
@@ -102,13 +102,13 @@ static void handle_gatt_client_event(uint8_t packet_type, uint16_t channel, uint
102102
att_status = gatt_event_query_complete_get_att_status(packet);
103103
if (att_status != ATT_ERROR_SUCCESS){
104104
ERROR_LOG("SERVICE_QUERY_RESULT, ATT Error 0x%02x.\n", att_status);
105-
gap_disconnect(connection_handle);
105+
gap_disconnect(con_handle);
106106
break;
107107
}
108108
// service query complete, look for characteristic
109109
state = TC_W4_CHARACTERISTIC_RESULT;
110110
INFO_LOG("Search for binary sensing characteristic.\n");
111-
gatt_client_discover_characteristics_for_service_by_uuid16(handle_gatt_client_event, connection_handle, &server_service, ORG_BLUETOOTH_CHARACTERISTIC_DIGITAL_OUTPUT);
111+
gatt_client_discover_characteristics_for_service_by_uuid16(handle_gatt_client_event, con_handle, &server_service, ORG_BLUETOOTH_CHARACTERISTIC_DIGITAL_OUTPUT);
112112
break;
113113
default:
114114
break;
@@ -124,16 +124,16 @@ static void handle_gatt_client_event(uint8_t packet_type, uint16_t channel, uint
124124
att_status = gatt_event_query_complete_get_att_status(packet);
125125
if (att_status != ATT_ERROR_SUCCESS){
126126
ERROR_LOG("CHARACTERISTIC_QUERY_RESULT, ATT Error 0x%02x.\n", att_status);
127-
gap_disconnect(connection_handle);
127+
gap_disconnect(con_handle);
128128
break;
129129
}
130130
// register handler for notifications
131131
listener_registered = true;
132-
gatt_client_listen_for_characteristic_value_updates(&notification_listener, handle_gatt_client_event, connection_handle, &server_characteristic);
132+
gatt_client_listen_for_characteristic_value_updates(&notification_listener, handle_gatt_client_event, con_handle, &server_characteristic);
133133
// enable notifications
134134
INFO_LOG("Enable notify on characteristic.\n");
135135
state = TC_W4_ENABLE_NOTIFICATIONS_COMPLETE;
136-
gatt_client_write_client_characteristic_configuration(handle_gatt_client_event, connection_handle,
136+
gatt_client_write_client_characteristic_configuration(handle_gatt_client_event, con_handle,
137137
&server_characteristic, GATT_CLIENT_CHARACTERISTICS_CONFIGURATION_NOTIFICATION);
138138
break;
139139
default:
@@ -210,25 +210,28 @@ static void hci_event_handler(uint8_t packet_type, uint16_t channel, uint8_t *pa
210210
DEBUG_LOG("Connecting to device with addr %s.\n", bd_addr_to_str(server_addr));
211211
gap_connect(server_addr, server_addr_type);
212212
break;
213-
case HCI_EVENT_LE_META:
214-
// wait for connection complete
215-
switch (hci_event_le_meta_get_subevent_code(packet)) {
216-
case HCI_SUBEVENT_LE_CONNECTION_COMPLETE:
213+
case HCI_EVENT_META_GAP:
214+
// BTstack normalises both the legacy LE Connection Complete and the
215+
// LE Enhanced Connection Complete HCI events into this single GAP
216+
// subevent, so this works regardless of which the controller emits
217+
// (i.e. regardless of ENABLE_LE_ENHANCED_CONNECTION_COMPLETE_EVENT).
218+
switch (hci_event_gap_meta_get_subevent_code(packet)) {
219+
case GAP_SUBEVENT_LE_CONNECTION_COMPLETE:
217220
if (state != TC_W4_CONNECT) return;
218-
connection_handle = hci_subevent_le_connection_complete_get_connection_handle(packet);
221+
con_handle = gap_subevent_le_connection_complete_get_connection_handle(packet);
219222
// initialize gatt client context with handle, and add it to the list of active clients
220223
// query primary services
221224
DEBUG_LOG("Search for binary sensing service.\n");
222225
state = TC_W4_SERVICE_RESULT;
223-
gatt_client_discover_primary_services_by_uuid16(handle_gatt_client_event, connection_handle, ORG_BLUETOOTH_SERVICE_BINARY_SENSOR);
226+
gatt_client_discover_primary_services_by_uuid16(handle_gatt_client_event, con_handle, ORG_BLUETOOTH_SERVICE_BINARY_SENSOR);
224227
break;
225228
default:
226229
break;
227230
}
228231
break;
229232
case HCI_EVENT_DISCONNECTION_COMPLETE:
230233
// unregister listener
231-
connection_handle = HCI_CON_HANDLE_INVALID;
234+
con_handle = HCI_CON_HANDLE_INVALID;
232235
if (listener_registered){
233236
listener_registered = false;
234237
gatt_client_stop_listening_for_characteristic_value_updates(&notification_listener);

bluetooth/ble_secure_temp_sensor/CMakeLists.txt

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,6 @@
1-
# Select a security setting to explore the BLE security
2-
#
3-
# security setting 0: Just works (pairing), no MITM (Man In The Middle) protection
4-
# client and server have no input or output support
5-
#
6-
# security setting 1: Numeric comparison with MITM protection
7-
# client can query yes or no from the user, server has a display only
8-
# server displays passkey
9-
# client displays passkey and user can select Yes or No if they agree the passkey is from the server
10-
#
11-
# security setting 2:
12-
# client has a keyboard and display, server has a display only
13-
# server displays passkey
14-
# client user enters the passkey displayed by the server
15-
#
16-
# security setting 3:
17-
# client has a display only, server has a display and keyboard
18-
# Client displays passkey
19-
# server user enters the passkey displayed by the server
1+
# Select a security setting to explore the BLE security. See README.md for details
202
if (NOT DEFINED SECURITY_SETTING)
21-
set(SECURITY_SETTING 1)
3+
set(SECURITY_SETTING 0)
224
endif()
235

246
# Standalone example that reads from the on board temperature sensor and sends notifications via BLE
Lines changed: 129 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,137 @@
1-
### Secure temp sensor
1+
# Secure temp sensor
22

3-
This example uses BLE to communicate temperature between a pair of pico Ws. This example is a variant of temp sensor, using LE secure to provide a secure connection.
3+
This example uses BLE to communicate temperature between a pair of Pico Ws. It is a variant of
4+
the temp sensor example, using LE Secure Connections to provide a secure connection.
45

5-
secure_temp_server is a peripheral or server that transmits its temperature to another device
6-
secure_temp_client is a client that reads a temperature from another device
6+
`secure_temp_server` is a peripheral/server that transmits its temperature to another device.
7+
`secure_temp_client` is a central/client that reads temperature from another device.
78

8-
In server.c and client.c there is a define SECURITY_SETTING which you can change to explore different security options:
9+
## Security settings
910

10-
security setting 0: Just works (pairing), no MITM (Man In The Middle) protection
11-
client and server have no input or output support
11+
In `server.c` and `client.c` there is a `SECURITY_SETTING` define which you can change to explore
12+
different BLE security options. Both ends must be built with the same setting unless you are
13+
deliberately testing an asymmetric combination (see the table below).
1214

13-
security setting 1: Numeric comparison with MITM protection
14-
client can query yes or no from the user, server has a display only
15-
server displays passkey
16-
client displays passkey and user can select Yes or No if they agree the passkey is from the server
15+
The settings map to Bluetooth IO capabilities as follows:
1716

18-
security setting 2:
19-
client has a keyboard and display, server has a display only
20-
server displays passkey
21-
client user enters the passkey displayed by the server
17+
| Setting | IO capability | Description |
18+
|---------|--------------|-------------|
19+
| 0 | `NO_INPUT_NO_OUTPUT` | Just Works - no MITM protection |
20+
| 1 | `DISPLAY_YES_NO` | Numeric Comparison - MITM protection |
21+
| 2 | `KEYBOARD_DISPLAY` | Passkey Entry - MITM protection |
22+
| 3 | `DISPLAY_ONLY` | Display Only - MITM protection |
2223

23-
security setting 3:
24-
client has a display only, server has a display and keyboard
25-
Client displays passkey
26-
server user enters the passkey displayed by the server
24+
The actual pairing method used depends on the IO capabilities of *both* devices, not just one.
25+
The Bluetooth SIG defines a matrix of initiator × responder capabilities that determines the
26+
method. Setting `SM_AUTHREQ_MITM_PROTECTION` requests MITM protection but does not guarantee it —
27+
if the negotiated method cannot provide it, pairing will fail.
2728

28-
You will need to use the console with both devices to see the passkeys and answer security prompts. Both stdio over UART and USB are enabled so you can use either.
29+
### Working combinations
30+
31+
| Client setting | Server setting | Pairing method | MITM? |
32+
|---------------|---------------|----------------|-------|
33+
| 0 | 0 | Just Works | No |
34+
| 1 | 1 | Numeric Comparison | Yes |
35+
| 2 | 2 | Passkey Entry | Yes |
36+
| 2 | 3 | Passkey Display (server displays, client types) | Yes |
37+
| 3 | 2 | Passkey Display (client displays, server types) | Yes |
38+
| 3 | 3 | Fails (both display only, nobody can type) ||
39+
| 0 | >0 | Fails (MITM required but not achievable) ||
40+
41+
Settings 0, 1 and 2 work symmetrically with the same setting on both ends. Setting 3 is
42+
`DISPLAY_ONLY` so it can only achieve MITM protection when paired with setting 2 on the other end.
43+
44+
You will need a console on each device to see passkeys and answer prompts. Both stdio over UART
45+
and USB are enabled so you can use either.
46+
47+
## Support scripts
48+
49+
Python scripts are provided to make it easier to test with just one Pico W.
50+
51+
> **Note:** Run these scripts on a native Linux host or a Raspberry Pi. WSL2 with a
52+
> usbip-attached Bluetooth adapter can connect and perform GATT discovery, but pairing
53+
> fails during the LE Secure Connections exchange (the DHKey check fails with
54+
> authentication failure / reason 12). This is a limitation of the WSL2 + usbip + BlueZ
55+
> path, not the example code.
56+
57+
### Client (`ble_temp_client.py`)
58+
59+
Acts as a BLE central, connecting to a Pico W running `secure_temp_server`.
60+
61+
```
62+
pip install bleak
63+
python3 ble_temp_client.py [--security <0-3>]
64+
```
65+
66+
- Works with BlueZ running normally — no special setup required.
67+
- If connection fails with a disconnect during service discovery, clear stale bonding info:
68+
```
69+
bluetoothctl remove <addr>
70+
```
71+
The Pico clears its own bond automatically on key mismatch, but BlueZ needs to be told manually.
72+
73+
### Server (`ble_temp_server.py`)
74+
75+
Acts as a BLE peripheral, advertising a simulated temperature for a Pico W running
76+
`secure_temp_client` to connect to.
77+
78+
Uses [Bumble](https://github.com/google/bumble) which talks directly over HCI, bypassing BlueZ.
79+
80+
```
81+
pip install bumble
82+
```
83+
84+
#### Using a USB Bluetooth dongle (recommended)
85+
86+
The easiest option — the dongle is claimed by Bumble leaving the built-in adapter free for BlueZ
87+
and the client script. Find the transport ID with:
88+
89+
```
90+
python3 -m bumble.apps.usb_probe
91+
```
92+
93+
Then run:
94+
95+
```
96+
./ble_temp_server.py --usb <id> [--security <0-3>]
97+
```
98+
99+
#### Using the built-in adapter
100+
101+
BlueZ must be stopped first to release the adapter:
102+
103+
```
104+
sudo systemctl stop bluetooth
105+
sudo systemctl mask bluetooth
106+
```
107+
108+
On Raspberry Pi OS, grant `cap_net_admin` to the Python binary so it can open the HCI socket
109+
without running as root:
110+
111+
```
112+
sudo setcap cap_net_admin+eip $(readlink -f venv/bin/python3)
113+
```
114+
115+
Then run:
116+
117+
```
118+
./ble_temp_server.py --builtin [--security <0-3>]
119+
```
120+
121+
When done, restore BlueZ:
122+
123+
```
124+
sudo systemctl unmask bluetooth
125+
sudo systemctl start bluetooth
126+
```
127+
128+
### Security mode prompts
129+
130+
For settings 1-3 the scripts will prompt for interaction during pairing:
131+
132+
- **Setting 1 (Numeric Comparison)**: The Pico displays a number; confirm it matches when prompted.
133+
- **Setting 2 (Passkey Entry)**: The server displays a passkey; type it into the Pico console.
134+
- **Setting 3 (Display Only)**: The Pico displays a passkey; type it when the script prompts.
135+
136+
For asymmetric combinations (client=2, server=3 or client=3, server=2) the above still applies —
137+
one side displays and the other types, determined by who has `KEYBOARD_DISPLAY` capability.

0 commit comments

Comments
 (0)