66
77#include <stdio.h>
88#include "btstack.h"
9+ #include "pico/cyw43_arch.h"
10+ #include "pico/btstack_cyw43.h"
911#include "hardware/adc.h"
12+ #include "pico/stdlib.h"
1013
1114#include "temp_sensor.h"
12- #include "server_common.h"
1315
16+ #define HEARTBEAT_PERIOD_MS 1000
17+ #define ADC_CHANNEL_TEMPSENSOR 4
1418#define APP_AD_FLAGS 0x06
19+
1520static uint8_t adv_data [] = {
1621 // Flags general discoverable
1722 0x02 , BLUETOOTH_DATA_TYPE_FLAGS , APP_AD_FLAGS ,
@@ -24,6 +29,10 @@ static const uint8_t adv_data_len = sizeof(adv_data);
2429int le_notification_enabled ;
2530hci_con_handle_t con_handle ;
2631uint16_t current_temp ;
32+ static btstack_timer_source_t heartbeat ;
33+ static btstack_packet_callback_registration_t hci_event_callback_registration ;
34+
35+ extern uint8_t const profile_data [];
2736
2837void packet_handler (uint8_t packet_type , uint16_t channel , uint8_t * packet , uint16_t size ) {
2938 UNUSED (size );
@@ -76,7 +85,7 @@ int att_write_callback(hci_con_handle_t connection_handle, uint16_t att_handle,
7685 UNUSED (transaction_mode );
7786 UNUSED (offset );
7887 UNUSED (buffer_size );
79-
88+
8089 if (att_handle != ATT_CHARACTERISTIC_ORG_BLUETOOTH_CHARACTERISTIC_TEMPERATURE_01_CLIENT_CONFIGURATION_HANDLE ) return 0 ;
8190 le_notification_enabled = little_endian_read_16 (buffer , 0 ) == GATT_CLIENT_CHARACTERISTICS_CONFIGURATION_NOTIFICATION ;
8291 con_handle = connection_handle ;
@@ -97,10 +106,96 @@ void poll_temp(void) {
97106 // ref https://github.com/raspberrypi/pico-micropython-examples/blob/master/adc/temperature.py
98107 const float conversion_factor = 3.3 / (65535 );
99108 float reading = raw16 * conversion_factor ;
100-
109+
101110 // The temperature sensor measures the Vbe voltage of a biased bipolar diode, connected to the fifth ADC channel
102- // Typically, Vbe = 0.706V at 27 degrees C, with a slope of -1.721mV (0.001721) per degree.
111+ // Typically, Vbe = 0.706V at 27 degrees C, with a slope of -1.721mV (0.001721) per degree.
103112 float deg_c = 27 - (reading - 0.706 ) / 0.001721 ;
104113 current_temp = deg_c * 100 ;
105114 printf ("Write temp %.2f degc\n" , deg_c );
106- }
115+ }
116+
117+ static void heartbeat_handler (struct btstack_timer_source * ts ) {
118+ static uint32_t counter = 0 ;
119+ counter ++ ;
120+
121+ // Update the temp every 10s
122+ if (counter % 10 == 0 ) {
123+ poll_temp ();
124+ if (le_notification_enabled ) {
125+ att_server_request_can_send_now_event (con_handle );
126+ }
127+ }
128+
129+ // Invert the led
130+ static int led_on = true;
131+ led_on = !led_on ;
132+ cyw43_arch_gpio_put (CYW43_WL_GPIO_LED_PIN , led_on );
133+
134+ // Restart timer
135+ btstack_run_loop_set_timer (ts , HEARTBEAT_PERIOD_MS );
136+ btstack_run_loop_add_timer (ts );
137+ }
138+
139+ static volatile bool key_pressed ;
140+ void key_pressed_func (void * param ) {
141+ int key = getchar_timeout_us (0 ); // get any pending key press but don't wait
142+ if (key == 's' || key == 'S' ) {
143+ key_pressed = true;
144+ }
145+ }
146+
147+ int main () {
148+ stdio_init_all ();
149+
150+ restart :
151+ // initialize CYW43 driver architecture (will enable BT if/because CYW43_ENABLE_BLUETOOTH == 1)
152+ if (cyw43_arch_init ()) {
153+ printf ("failed to initialise cyw43_arch\n" );
154+ return -1 ;
155+ }
156+
157+ // Get notified if the user presses a key
158+ printf ("Press the \"S\" key to Stop bluetooth\n" );
159+ stdio_set_chars_available_callback (key_pressed_func , NULL );
160+
161+ // Initialise adc for the temp sensor
162+ adc_init ();
163+ adc_select_input (ADC_CHANNEL_TEMPSENSOR );
164+ adc_set_temp_sensor_enabled (true);
165+
166+ l2cap_init ();
167+ sm_init ();
168+
169+ att_server_init (profile_data , att_read_callback , att_write_callback );
170+
171+ // inform about BTstack state
172+ hci_event_callback_registration .callback = & packet_handler ;
173+ hci_add_event_handler (& hci_event_callback_registration );
174+
175+ // register for ATT event
176+ att_server_register_packet_handler (packet_handler );
177+
178+ // set one-shot btstack timer
179+ heartbeat .process = & heartbeat_handler ;
180+ btstack_run_loop_set_timer (& heartbeat , HEARTBEAT_PERIOD_MS );
181+ btstack_run_loop_add_timer (& heartbeat );
182+
183+ // turn on bluetooth!
184+ hci_power_control (HCI_POWER_ON );
185+
186+ key_pressed = false;
187+ while (!key_pressed ) {
188+ async_context_poll (cyw43_arch_async_context ());
189+ async_context_wait_for_work_until (cyw43_arch_async_context (), at_the_end_of_time );
190+ }
191+
192+ cyw43_arch_deinit ();
193+
194+ printf ("Press the \"S\" key to Start bluetooth\n" );
195+ key_pressed = false;
196+ while (!key_pressed ) {
197+ sleep_ms (1000 );
198+ }
199+ goto restart ;
200+ return 0 ;
201+ }
0 commit comments