/** * Copyright (c) 2023 Raspberry Pi (Trading) Ltd. * * SPDX-License-Identifier: BSD-3-Clause */ #include #include "btstack.h" #include "pico/cyw43_arch.h" #include "pico/stdlib.h" #include "hardware/adc.h" #include "lwip/netif.h" #include "lwip/ip4_addr.h" #include "lwip/apps/lwiperf.h" #include "server_common.h" #define HEARTBEAT_PERIOD_MS 1000 static void heartbeat_handler(async_context_t *context, async_at_time_worker_t *worker); static async_at_time_worker_t heartbeat_worker = { .do_work = heartbeat_handler }; static btstack_packet_callback_registration_t hci_event_callback_registration; static void heartbeat_handler(async_context_t *context, async_at_time_worker_t *worker) { static uint32_t counter = 0; counter++; // Update the temp every 10s if (counter % 10 == 0) { poll_temp(); if (le_notification_enabled) { att_server_request_can_send_now_event(con_handle); } } // Invert the led static int led_on = true; led_on = !led_on; cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, led_on); // Restart timer async_context_add_at_time_worker_in_ms(context, &heartbeat_worker, HEARTBEAT_PERIOD_MS); } // Report IP results and exit static void iperf_report(void *arg, enum lwiperf_report_type report_type, const ip_addr_t *local_addr, u16_t local_port, const ip_addr_t *remote_addr, u16_t remote_port, u32_t bytes_transferred, u32_t ms_duration, u32_t bandwidth_kbitpsec) { static uint32_t total_iperf_megabytes = 0; uint32_t mbytes = bytes_transferred / 1024 / 1024; float mbits = bandwidth_kbitpsec / 1000.0; total_iperf_megabytes += mbytes; printf("Completed iperf transfer of %u MBytes @ %.1f Mbits/sec\n", mbytes, mbits); printf("Total iperf megabytes since start %u Mbytes\n", total_iperf_megabytes); } int main() { stdio_init_all(); // initialize CYW43 architecture // - will enable BT if CYW43_ENABLE_BLUETOOTH == 1 // - will enable lwIP if CYW43_LWIP == 1 if (cyw43_arch_init()) { printf("failed to initialise cyw43_arch\n"); return -1; } // Initialise adc for the temp sensor adc_init(); adc_select_input(ADC_CHANNEL_TEMPSENSOR); adc_set_temp_sensor_enabled(true); l2cap_init(); sm_init(); att_server_init(profile_data, att_read_callback, att_write_callback); // inform about BTstack state hci_event_callback_registration.callback = &packet_handler; hci_add_event_handler(&hci_event_callback_registration); // register for ATT event att_server_register_packet_handler(packet_handler); // use an async worker for for the led async_context_add_at_time_worker_in_ms(cyw43_arch_async_context(), &heartbeat_worker, HEARTBEAT_PERIOD_MS); // Connect to Wi-Fi cyw43_arch_enable_sta_mode(); printf("Connecting to Wi-Fi...\n"); if (cyw43_arch_wifi_connect_timeout_ms(WIFI_SSID, WIFI_PASSWORD, CYW43_AUTH_WPA2_AES_PSK, 30000)) { printf("failed to connect.\n"); return 1; } else { printf("Connected.\n"); } // setup iperf cyw43_arch_lwip_begin(); printf("\nReady, running iperf server at %s\n", ip4addr_ntoa(netif_ip4_addr(netif_list))); lwiperf_start_tcp_server_default(&iperf_report, NULL); cyw43_arch_lwip_end(); // turn on bluetooth! hci_power_control(HCI_POWER_ON); // For threadsafe background we can just enter a loop while(true) { sleep_ms(1000); } cyw43_arch_deinit(); return 0; }