Skip to content

Commit cbcd9eb

Browse files
committed
implement #80, add requestPHY/getPHY support
update prph and central throuhgput example.
1 parent 4e95f95 commit cbcd9eb

File tree

6 files changed

+183
-126
lines changed

6 files changed

+183
-126
lines changed

libraries/Bluefruit52Lib/examples/Central/central_throughput/central_throughput.ino

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,20 @@
2020

2121
BLEClientUart clientUart; // bleuart client
2222

23+
uint32_t rx_count = 0;
24+
2325
void setup()
2426
{
2527
Serial.begin(115200);
2628
while ( !Serial ) delay(10); // for nrf52840 with native usb
2729

2830
Serial.println("Bluefruit52 Central BLEUART Example");
2931
Serial.println("-----------------------------------\n");
32+
33+
// Config the connection with maximum bandwidth
34+
// more SRAM required by SoftDevice
35+
// Note: All config***() function must be called before begin()
36+
Bluefruit.configCentralBandwidth(BANDWIDTH_MAX);
3037

3138
// Initialize Bluefruit with maximum connections as Peripheral = 0, Central = 1
3239
// SRAM usage required by SoftDevice will increase dramatically with number of connections
@@ -36,7 +43,7 @@ void setup()
3643

3744
// Init BLE Central Uart Serivce
3845
clientUart.begin();
39-
clientUart.setRxCallback(bleuart_rx_callback);
46+
clientUart.setRxCallback(bleuart_rx_callback);
4047

4148
// Increase Blink rate to different from PrPh advertising mode
4249
Bluefruit.setConnLedInterval(250);
@@ -101,7 +108,7 @@ void connect_callback(uint16_t conn_handle)
101108
Serial.println("Found NONE");
102109

103110
// disconnect since we couldn't find bleuart service
104-
Bluefruit.disconnect(conn_handle);
111+
//Bluefruit.disconnect(conn_handle);
105112
}
106113
}
107114

@@ -125,14 +132,8 @@ void disconnect_callback(uint16_t conn_handle, uint8_t reason)
125132
*/
126133
void bleuart_rx_callback(BLEClientUart& uart_svc)
127134
{
128-
Serial.print("[RX]: ");
129-
130-
while ( uart_svc.available() )
131-
{
132-
Serial.print( (char) uart_svc.read() );
133-
}
134-
135-
Serial.println();
135+
int count = uart_svc.available();
136+
uart_svc.flush();
136137
}
137138

138139
void loop()

libraries/Bluefruit52Lib/examples/Peripheral/throughput/throughput.ino

Lines changed: 70 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,18 @@
1414

1515
#include <bluefruit.h>
1616

17-
// String to send in the throughput test
18-
#define TEST_STRING "01234567899876543210"
19-
const int TEST_STRLEN = strlen(TEST_STRING);
17+
/* Best result is
18+
* - 8.74 KB/s with 20 ms, MTU = 23
19+
* - 23.62 KB/s with 7.5 ms, MTU = 23
20+
* - 47.85 KB/s with 15 ms, MTU = 247
21+
*/
22+
23+
// data to send in the throughput test
24+
char test_data[256] = { 0 };
2025

21-
// Number of total data sent ( 1024 times the test string)
22-
#define TOTAL_BYTES (1024 * strlen(TEST_STRING))
26+
// Number of packet to sent
27+
// actualy number of bytes depends on the MTU of the connection
28+
#define PACKET_NUM 1024
2329

2430
BLEDis bledis;
2531
BLEUart bleuart;
@@ -31,7 +37,7 @@ BLEUart bleuart;
3137
*/
3238
/**************************************************************************/
3339
void setup(void)
34-
{
40+
{
3541
Serial.begin(115200);
3642
while ( !Serial ) delay(10); // for nrf52840 with native usb
3743

@@ -43,11 +49,17 @@ void setup(void)
4349
// here in case you want to control this manually via PIN 19
4450
Bluefruit.autoConnLed(true);
4551

52+
// Config the peripheral connection with maximum bandwidth
53+
// more SRAM required by SoftDevice
54+
// Note: All config***() function must be called before begin()
55+
Bluefruit.configPrphBandwidth(BANDWIDTH_MAX);
56+
4657
Bluefruit.begin();
4758
Bluefruit.setTxPower(4); // Check bluefruit.h for supported values
4859
Bluefruit.setName("Bluefruit52");
4960
Bluefruit.Periph.setConnectCallback(connect_callback);
5061
Bluefruit.Periph.setDisconnectCallback(disconnect_callback);
62+
Bluefruit.Periph.setConnInterval(6, 12); // 7.5 - 15 ms
5163

5264
// Configure and Start Device Information Service
5365
bledis.setManufacturer("Adafruit Industries");
@@ -90,8 +102,19 @@ void startAdv(void)
90102

91103
void connect_callback(uint16_t conn_handle)
92104
{
105+
BLEConnection* conn = Bluefruit.Connection(conn_handle);
93106
(void) conn_handle;
94107
Serial.println("Connected");
108+
109+
110+
// request PHY changed to 2MB
111+
112+
113+
// request to update data length
114+
conn->requestDataLengthUpdate();
115+
116+
// request mtu exchange
117+
conn->requestMtuExchange(247);
95118
}
96119

97120
/**
@@ -108,53 +131,55 @@ void disconnect_callback(uint16_t conn_handle, uint8_t reason)
108131
Serial.println("Disconnected");
109132
}
110133

111-
/**************************************************************************/
112-
/*!
113-
@brief Constantly poll for new command or response data
114-
*/
115-
/**************************************************************************/
116-
void loop(void)
134+
135+
void test_throughput(void)
117136
{
118137
uint32_t start, stop, sent;
119-
uint32_t remaining = TOTAL_BYTES;
120138
start = stop = sent = 0;
121139

140+
const uint16_t data_mtu = Bluefruit.Connection(0)->getMtu() - 3;
141+
memset(test_data, '1', data_mtu);
142+
143+
uint32_t remaining = data_mtu*PACKET_NUM;
144+
145+
Serial.print("Sending ");
146+
Serial.print(remaining);
147+
Serial.println(" bytes ...");
148+
Serial.flush();
149+
150+
start = millis();
151+
while ( (remaining > 0) && Bluefruit.connected() && bleuart.notifyEnabled() )
152+
{
153+
if ( !bleuart.write(test_data, data_mtu) ) break;
154+
155+
sent += data_mtu;
156+
remaining -= data_mtu;
157+
}
158+
stop = millis() - start;
159+
160+
Serial.print("Sent ");
161+
Serial.print(sent);
162+
Serial.print(" bytes in ");
163+
Serial.print(stop / 1000.0F, 2);
164+
Serial.println(" seconds.");
165+
166+
Serial.println("Speed ");
167+
Serial.print( (sent / 1000.0F) / (stop / 1000.0F), 2);
168+
Serial.println(" KB/s.\r\n");
169+
}
170+
171+
void loop(void)
172+
{
122173
if (Bluefruit.connected() && bleuart.notifyEnabled())
123174
{
124175
// Wait for user input before trying again
125176
Serial.println("Connected. Send a key and press enter to start test");
126-
getUserInput();
127-
128-
Serial.print("Sending ");
129-
Serial.print(remaining);
130-
Serial.println(" bytes ...");
131-
132-
start = millis();
133-
while ( (remaining > 0) && Bluefruit.connected() && bleuart.notifyEnabled() )
134-
{
135-
if ( !bleuart.print(TEST_STRING) ) break;
136-
137-
sent += TEST_STRLEN;
138-
remaining -= TEST_STRLEN;
139-
140-
// Only print every 100th time
141-
// if ( (sent % (100*TEST_STRLEN) ) == 0 )
142-
// {
143-
// Serial.print("Sent: "); Serial.print(sent);
144-
// Serial.print(" Remaining: "); Serial.println(remaining);
145-
// }
146-
}
147-
stop = millis() - start;
148-
149-
Serial.print("Sent ");
150-
Serial.print(sent);
151-
Serial.print(" bytes in ");
152-
Serial.print(stop / 1000.0F, 2);
153-
Serial.println(" seconds.");
154-
155-
Serial.println("Speed ");
156-
Serial.print( (sent / 1000.0F) / (stop / 1000.0F), 2);
157-
Serial.println(" KB/s.\r\n");
177+
//getUserInput();
178+
179+
test_throughput();
180+
181+
Bluefruit.disconnect(0);
182+
delay(2000);
158183
}
159184
}
160185

libraries/Bluefruit52Lib/src/BLEAdvertising.cpp

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -340,19 +340,18 @@ bool BLEAdvertising::_start(uint16_t interval, uint16_t timeout)
340340
// ADV Params
341341
ble_gap_adv_params_t adv_para =
342342
{
343-
.properties = {
344-
.type = _type,
345-
.anonymous = 0
346-
},
347-
.p_peer_addr = NULL , // Undirected advertisement
348-
.interval = interval , // advertising interval (in units of 0.625 ms)
349-
.duration = (uint16_t) (timeout*100), // in 10-ms unit
350-
351-
.max_adv_evts = 0, // TODO can be used for fast/slow mode
352-
.channel_mask = { 0, 0, 0, 0, 0 } , // 40 channel, set 1 to disable
353-
.filter_policy = BLE_GAP_ADV_FP_ANY ,
354-
355-
//.primary_phy, .secondary_phy, .set_id, .scan_req_notification
343+
.properties = { .type = _type, .anonymous = 0 },
344+
.p_peer_addr = NULL , // Undirected advertisement
345+
.interval = interval , // advertising interval (in units of 0.625 ms)
346+
.duration = (uint16_t) (timeout*100) , // in 10-ms unit
347+
348+
.max_adv_evts = 0 , // TODO can be used for fast/slow mode
349+
.channel_mask = { 0, 0, 0, 0, 0 } , // 40 channel, set 1 to disable
350+
.filter_policy = BLE_GAP_ADV_FP_ANY ,
351+
352+
.primary_phy = BLE_GAP_PHY_AUTO , // 1 Mbps will be used
353+
.secondary_phy = BLE_GAP_PHY_AUTO , // 1 Mbps will be used
354+
// , .set_id, .scan_req_notification
356355
};
357356

358357
// gap_adv long-live is required by SD v6

libraries/Bluefruit52Lib/src/BLEConnection.cpp

Lines changed: 81 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ BLEConnection::BLEConnection(uint16_t conn_hdl, ble_gap_evt_connected_t const* e
4646
_connected = true;
4747

4848
_mtu = BLE_GATT_ATT_MTU_DEFAULT;
49+
_data_length = BLE_GATT_ATT_MTU_DEFAULT + 4; // 27
50+
_phy = BLE_GAP_PHY_1MBPS;
4951
_conn_interval = 0;
5052
_peer_addr = evt_connected->peer_addr;
5153
_role = evt_connected->role;
@@ -99,6 +101,16 @@ uint16_t BLEConnection::getConnInterval(void)
99101
return _conn_interval;
100102
}
101103

104+
uint16_t BLEConnection::getDataLength(void)
105+
{
106+
return _data_length;
107+
}
108+
109+
uint8_t BLEConnection::getPHY(void)
110+
{
111+
return _phy;
112+
}
113+
102114
ble_gap_addr_t BLEConnection::getPeerAddr (void)
103115
{
104116
return _peer_addr;
@@ -138,12 +150,19 @@ bool BLEConnection::requestMtuExchange(uint16_t mtu)
138150
return true;
139151
}
140152

141-
bool BLEConnection::updateDataLength(ble_gap_data_length_params_t const *p_dl_params, ble_gap_data_length_limitation_t *p_dl_limitation)
153+
bool BLEConnection::requestDataLengthUpdate(ble_gap_data_length_params_t const *p_dl_params, ble_gap_data_length_limitation_t *p_dl_limitation)
142154
{
143155
VERIFY_STATUS(sd_ble_gap_data_length_update(_conn_hdl, p_dl_params, p_dl_limitation), false);
144156
return true;
145157
}
146158

159+
bool BLEConnection::requestPHY(uint8_t phy)
160+
{
161+
ble_gap_phys_t gap_phy = { .tx_phys = phy, .rx_phys = phy };
162+
VERIFY_STATUS( sd_ble_gap_phy_update(_conn_hdl, &gap_phy), false);
163+
return true;
164+
}
165+
147166
bool BLEConnection::disconnect(void)
148167
{
149168
return ERROR_NONE == sd_ble_gap_disconnect(_conn_hdl, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
@@ -421,6 +440,7 @@ void BLEConnection::_eventHandler(ble_evt_t* evt)
421440
}
422441
break;
423442

443+
//------------- MTU -------------//
424444
case BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST:
425445
{
426446
uint16_t const max_mtu = Bluefruit.getMaxMtu(_role);
@@ -437,6 +457,66 @@ void BLEConnection::_eventHandler(ble_evt_t* evt)
437457
LOG_LV1("GAP", "ATT MTU is changed to %d", _mtu);
438458
break;
439459

460+
//------------- Data Length -------------//
461+
case BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST:
462+
{
463+
ble_gap_data_length_params_t* param = &evt->evt.gap_evt.params.data_length_update_request.peer_params;
464+
(void) param;
465+
466+
LOG_LV1("GAP", "Data Length Request is (tx, rx) octets = (%d, %d), (tx, rx) time = (%d, %d) us",
467+
param->max_tx_octets, param->max_rx_octets, param->max_tx_time_us, param->max_rx_time_us);
468+
469+
// Let Softdevice decide the data length
470+
VERIFY_STATUS( sd_ble_gap_data_length_update(_conn_hdl, NULL, NULL), );
471+
}
472+
break;
473+
474+
case BLE_GAP_EVT_DATA_LENGTH_UPDATE:
475+
{
476+
ble_gap_data_length_params_t* datalen = &evt->evt.gap_evt.params.data_length_update.effective_params;
477+
(void) datalen;
478+
479+
LOG_LV1("GAP", "Data Length is (tx, rx) octets = (%d, %d), (tx, rx) time = (%d, %d) us",
480+
datalen->max_tx_octets, datalen->max_rx_octets, datalen->max_tx_time_us, datalen->max_rx_time_us);
481+
482+
_data_length = datalen->max_tx_octets;
483+
}
484+
break;
485+
486+
//------------- PHY -------------//
487+
case BLE_GAP_EVT_PHY_UPDATE_REQUEST:
488+
{
489+
ble_gap_phys_t* req_phy = &evt->evt.gap_evt.params.phy_update_request.peer_preferred_phys;
490+
char const *phy_str[] = { "Auto", "1 Mbps", "2 Mbps", "Coded" };
491+
492+
(void) req_phy;
493+
(void) phy_str;
494+
LOG_LV1("GAP", "PHY request tx: %s, rx: %s", phy_str[req_phy->tx_phys], phy_str[req_phy->rx_phys]);
495+
496+
// Tell SoftDevice to choose PHY automatically
497+
ble_gap_phys_t phy = { BLE_GAP_PHY_AUTO, BLE_GAP_PHY_AUTO };
498+
(void) sd_ble_gap_phy_update(_conn_hdl, &phy);
499+
}
500+
break;
501+
502+
case BLE_GAP_EVT_PHY_UPDATE:
503+
{
504+
ble_gap_evt_phy_update_t* active_phy = &evt->evt.gap_evt.params.phy_update;
505+
506+
if ( active_phy->status != BLE_HCI_STATUS_CODE_SUCCESS )
507+
{
508+
LOG_LV1("GAP", "Failed HCI status = 0x%02X", active_phy->status);
509+
}else
510+
{
511+
char const *phy_str[] = { "Auto", "1 Mbps", "2 Mbps", "Coded" };
512+
(void) phy_str;
513+
LOG_LV1("GAP", "PHY active tx: %s, rx: %s", phy_str[active_phy->tx_phy], phy_str[active_phy->rx_phy]);
514+
515+
_phy = active_phy->tx_phy;
516+
}
517+
}
518+
break;
519+
440520
//--------------------------------------------------------------------+
441521
//
442522
//--------------------------------------------------------------------+

0 commit comments

Comments
 (0)