From 8c768b83f71594a13a07efcf3e830345663dad5f Mon Sep 17 00:00:00 2001 From: Matthias Ringwald Date: Fri, 29 Jul 2016 15:02:19 +0200 Subject: [PATCH 1/7] posix-h4: print if eHCILL is enabled or disabled --- port/posix-h4/main.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/port/posix-h4/main.c b/port/posix-h4/main.c index 5c5f4402f..5bdcc728a 100644 --- a/port/posix-h4/main.c +++ b/port/posix-h4/main.c @@ -141,6 +141,8 @@ static void local_version_information_callback(uint8_t * packet){ hci_set_chipset(btstack_chipset_cc256x_instance()); #ifdef ENABLE_EHCILL printf("eHCILL enabled.\n"); +#else + printf("eHCILL disable.\n"); #endif break; case COMPANY_ID_BROADCOM_CORPORATION: From ce7ff1f89f6bb901a93263a47f79423d26c756e8 Mon Sep 17 00:00:00 2001 From: Matthias Ringwald Date: Tue, 16 Aug 2016 14:18:12 +0200 Subject: [PATCH 2/7] wiced: reset Bluetooth controller via RESET line if available --- port/wiced/hci_transport_h4_wiced.c | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/port/wiced/hci_transport_h4_wiced.c b/port/wiced/hci_transport_h4_wiced.c index 445261812..091303229 100644 --- a/port/wiced/hci_transport_h4_wiced.c +++ b/port/wiced/hci_transport_h4_wiced.c @@ -270,6 +270,13 @@ static int h4_open(void){ platform_gpio_init(wiced_bt_control_pins[WICED_BT_PIN_HOST_WAKE], INPUT_HIGH_IMPEDANCE); platform_gpio_init(wiced_bt_control_pins[WICED_BT_PIN_DEVICE_WAKE], OUTPUT_PUSH_PULL); platform_gpio_output_low(wiced_bt_control_pins[WICED_BT_PIN_DEVICE_WAKE]); + + /* Configure Reg Enable pin to output. Set to HIGH */ + if (wiced_bt_control_pins[ WICED_BT_PIN_POWER ]){ + platform_gpio_init( wiced_bt_control_pins[ WICED_BT_PIN_POWER ], OUTPUT_OPEN_DRAIN_PULL_UP ); + platform_gpio_output_high( wiced_bt_control_pins[ WICED_BT_PIN_POWER ] ); + } + wiced_rtos_delay_milliseconds( 100 ); // -- init UART @@ -291,12 +298,23 @@ static int h4_open(void){ #endif platform_uart_init( wiced_bt_uart_driver, wiced_bt_uart_peripheral, &uart_config, ring_buffer ); - // reset Bluetooth - platform_gpio_init( wiced_bt_control_pins[ WICED_BT_PIN_POWER ], OUTPUT_PUSH_PULL ); - platform_gpio_output_low( wiced_bt_control_pins[ WICED_BT_PIN_POWER ] ); - wiced_rtos_delay_milliseconds( 100 ); - platform_gpio_output_high( wiced_bt_control_pins[ WICED_BT_PIN_POWER ] ); + // Reset Bluetooth via RESET line. Fallback to toggling POWER otherwise + if ( wiced_bt_control_pins[ WICED_BT_PIN_RESET ]){ + platform_gpio_init( wiced_bt_control_pins[ WICED_BT_PIN_RESET ], OUTPUT_PUSH_PULL ); + platform_gpio_output_high( wiced_bt_control_pins[ WICED_BT_PIN_RESET ] ); + + platform_gpio_output_low( wiced_bt_control_pins[ WICED_BT_PIN_RESET ] ); + wiced_rtos_delay_milliseconds( 100 ); + platform_gpio_output_high( wiced_bt_control_pins[ WICED_BT_PIN_RESET ] ); + } + else if ( wiced_bt_control_pins[ WICED_BT_PIN_POWER ]){ + platform_gpio_output_low( wiced_bt_control_pins[ WICED_BT_PIN_POWER ] ); + wiced_rtos_delay_milliseconds( 100 ); + platform_gpio_output_high( wiced_bt_control_pins[ WICED_BT_PIN_POWER ] ); + } + + // wait for Bluetooth to start up wiced_rtos_delay_milliseconds( 500 ); // create worker threads for rx/tx. only single request is posted to their queues From 401a70243a6d174497aabfcc12a02ff94aec4d5b Mon Sep 17 00:00:00 2001 From: Matthias Ringwald Date: Tue, 16 Aug 2016 14:58:08 +0200 Subject: [PATCH 3/7] wiced: enable set baudrate for STM32F40_41xxx, too --- port/wiced/hci_transport_h4_wiced.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/port/wiced/hci_transport_h4_wiced.c b/port/wiced/hci_transport_h4_wiced.c index 091303229..e11ec2e6d 100644 --- a/port/wiced/hci_transport_h4_wiced.c +++ b/port/wiced/hci_transport_h4_wiced.c @@ -193,7 +193,7 @@ static wiced_result_t h4_tx_worker_send_packet(void * arg){ static int h4_set_baudrate(uint32_t baudrate){ -#ifdef _STM32F205RGT6_ +#if defined(_STM32F205RGT6_) || defined(STM32F40_41xxx) // directly use STM peripheral functions to change baud rate dynamically From d8f374f670113273557bae3ad214fda946eaa59d Mon Sep 17 00:00:00 2001 From: Matthias Ringwald Date: Tue, 16 Aug 2016 15:12:30 +0200 Subject: [PATCH 4/7] wiced: only print dot if we're waiting for CTS --- port/wiced/hci_transport_h4_wiced.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/port/wiced/hci_transport_h4_wiced.c b/port/wiced/hci_transport_h4_wiced.c index e11ec2e6d..097b7f6f0 100644 --- a/port/wiced/hci_transport_h4_wiced.c +++ b/port/wiced/hci_transport_h4_wiced.c @@ -178,11 +178,15 @@ static wiced_result_t h4_rx_worker_receive_packet(void * arg){ // executed on tx worker thread static wiced_result_t h4_tx_worker_send_packet(void * arg){ #ifdef WICED_BT_UART_MANUAL_CTS_RTS + int cts_was_raised = 0; while (platform_gpio_input_get(wiced_bt_uart_pins[WICED_BT_PIN_UART_CTS]) == WICED_TRUE){ - printf("."); - wiced_rtos_delay_milliseconds(10); + log_info("."); + wiced_rtos_delay_milliseconds(100); + cts_was_raised = 1; + } + if (cts_was_raised){ + printf("\n"); } - printf("\n"); #endif // blocking send platform_uart_transmit_bytes(wiced_bt_uart_driver, tx_worker_data_buffer, tx_worker_data_size); From f27f89f93b3f148c94752c364bfd864fa4969ed8 Mon Sep 17 00:00:00 2001 From: Matthias Ringwald Date: Fri, 19 Aug 2016 18:06:29 +0200 Subject: [PATCH 5/7] wiced: don't init WIFI automatically --- port/wiced/main.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/port/wiced/main.c b/port/wiced/main.c index dfcd5332c..f34f77a73 100644 --- a/port/wiced/main.c +++ b/port/wiced/main.c @@ -43,7 +43,7 @@ #include "platform_bluetooth.h" #include "wiced.h" - +#include "platform/wwd_platform_interface.h" // see generated_mac_address.txt - "macaddr=02:0A:F7:3d:76:be" static const char * wifi_mac_address = NVRAM_GENERATED_MAC_ADDRESS; @@ -53,7 +53,7 @@ static btstack_packet_callback_registration_t hci_event_callback_registration; static const hci_transport_config_uart_t hci_transport_config_uart = { HCI_TRANSPORT_CONFIG_UART, 115200, - 0, // 3000000, + 0, 1, NULL, }; @@ -69,8 +69,11 @@ static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *pack void application_start(void){ - /* Initialise the WICED device */ - wiced_init(); + /* Initialise the WICED device without WLAN */ + wiced_core_init(); + + /* 32 kHz clock also needed for Bluetooth */ + host_platform_init_wlan_powersave_clock(); printf("BTstack on WICED\n"); From 598564e4d374bbf1bf9093ea6bf8487d047c6e06 Mon Sep 17 00:00:00 2001 From: Matthias Ringwald Date: Fri, 19 Aug 2016 18:07:37 +0200 Subject: [PATCH 6/7] wiced: only print dot if we're waiting for CTS --- port/wiced/hci_transport_h4_wiced.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/port/wiced/hci_transport_h4_wiced.c b/port/wiced/hci_transport_h4_wiced.c index 097b7f6f0..ee2890fc7 100644 --- a/port/wiced/hci_transport_h4_wiced.c +++ b/port/wiced/hci_transport_h4_wiced.c @@ -180,7 +180,7 @@ static wiced_result_t h4_tx_worker_send_packet(void * arg){ #ifdef WICED_BT_UART_MANUAL_CTS_RTS int cts_was_raised = 0; while (platform_gpio_input_get(wiced_bt_uart_pins[WICED_BT_PIN_UART_CTS]) == WICED_TRUE){ - log_info("."); + printf("."); wiced_rtos_delay_milliseconds(100); cts_was_raised = 1; } From cb2649100c2b08b300bf4869e402c0af3d698250 Mon Sep 17 00:00:00 2001 From: Matthias Ringwald Date: Tue, 23 Aug 2016 10:03:07 +0200 Subject: [PATCH 7/7] docs: power management --- doc/manual/docs/how_to.md | 50 +++++++++++++++++++++++++++++++++++++-- src/gap.h | 2 +- 2 files changed, 49 insertions(+), 3 deletions(-) diff --git a/doc/manual/docs/how_to.md b/doc/manual/docs/how_to.md index f64839e39..845bfd57d 100644 --- a/doc/manual/docs/how_to.md +++ b/doc/manual/docs/how_to.md @@ -19,9 +19,9 @@ that is necessary to setup BTstack. From the point when the run loop is executed, the application runs as a finite state machine, which processes events received from BTstack. BTstack groups events logically and provides them via packet handlers. -We provide their overview here, and finally, for the case that there is a need to inspect the data exchanged +We provide their overview here. For the case that there is a need to inspect the data exchanged between BTstack and the Bluetooth chipset, we describe how to configure -packet logging mechanism. +packet logging mechanism. Finally, we provide an overview on power management in Bluetooth in general and how to save energy in BTstack. ## Configuration in btstack_config.h {#sec:btstackConfigHowTo} @@ -477,3 +477,49 @@ In addition to the HCI packets, you can also enable BTstack's debug information to the btstack_config.h and recompiling your application. +## Bluetooth Power Control {#sec:powerControl} + +In most BTstack examples, the device is set to be discoverable and connectable. In this mode, even when there's no active connection, the Bluetooth Controller will periodicaly activate its receiver in order to listen for inquiries or connecting requests from another device. +The ability to be discoverable requires more energy than the ability to be connected. Being discoverable also announces the device to anybody in the area. Therefore, it is a good idea to pause listening for inquiries when not needed. Other devices that have your Bluetooth address can still connect to your device. + +To enable/disable discoverabilty, you can call: + + /** + * @brief Allows to control if device is discoverable. OFF by default. + */ + void gap_discoverable_control(uint8_t enable); + +If you don't need to become connected from other devices for a longer period of time, you can also disable the listening to connection requests. + +To enable/disable connectability, you can call: + + /** + * @brief Override page scan mode. Page scan mode enabled by l2cap when services are registered + * @note Might be used to reduce power consumption while Bluetooth module stays powered but no (new) + * connections are expected + */ + void gap_connectable_control(uint8_t enable); + +For Bluetooth Low Energy, the radio is periodically used to broadcast advertisements that are used for both discovery and connection establishment. + +To enable/disable advertisements, you can call: + + /** + * @brief Enable/Disable Advertisements. OFF by default. + * @param enabled + */ + void gap_advertisements_enable(int enabled); + +If a Bluetooth Controller is neither discoverable nor conectable, it does not need to periodically turn on its radio and it only needs to respond to commands from the Host. In this case, the Bluetooth Controller is free to enter some kind of deep sleep where the power consumption is minimal. + +Finally, if that's not sufficient for your application, you could request BTstack to shutdown the Bluetooth Controller. For this, the "on" and "off" functions in the btstack_control_t struct must be implemented. To shutdown the Bluetooth Controller, you can call: + + /** + * @brief Requests the change of BTstack power mode. + */ + int hci_power_control(HCI_POWER_MODE mode); + +with mode set to *HCI_POWER_OFF*. When needed later, Bluetooth can be started again via by calling it with mode *HCI_POWER_ON*, as seen in all examples. + + + diff --git a/src/gap.h b/src/gap.h index 6abf05859..00313dc3b 100644 --- a/src/gap.h +++ b/src/gap.h @@ -248,7 +248,7 @@ void gap_advertisements_set_params(uint16_t adv_int_min, uint16_t adv_int_max, u uint8_t direct_address_typ, bd_addr_t direct_address, uint8_t channel_map, uint8_t filter_policy); /** - * @brief Enable/Disable Advertisements + * @brief Enable/Disable Advertisements. OFF by default. * @param enabled */ void gap_advertisements_enable(int enabled);