diff --git a/pico_w/wifi/access_point/picow_access_point.c b/pico_w/wifi/access_point/picow_access_point.c index c0a6895..fe58b27 100644 --- a/pico_w/wifi/access_point/picow_access_point.c +++ b/pico_w/wifi/access_point/picow_access_point.c @@ -30,6 +30,7 @@ typedef struct TCP_SERVER_T_ { struct tcp_pcb *server_pcb; bool complete; ip_addr_t gw; + async_context_t *context; } TCP_SERVER_T; typedef struct TCP_CONNECT_STATE_T_ { @@ -236,7 +237,7 @@ static err_t tcp_server_accept(void *arg, struct tcp_pcb *client_pcb, err_t err) return ERR_OK; } -static bool tcp_server_open(void *arg) { +static bool tcp_server_open(void *arg, const char *ap_name) { TCP_SERVER_T *state = (TCP_SERVER_T*)arg; DEBUG_printf("starting server on port %d\n", TCP_PORT); @@ -264,9 +265,31 @@ static bool tcp_server_open(void *arg) { tcp_arg(state->server_pcb, state); tcp_accept(state->server_pcb, tcp_server_accept); + printf("Try connecting to '%s' (press 'd' to disable access point)\n", ap_name); return true; } +// This "worker" function is called to safely perform work when instructed by key_pressed_func +void key_pressed_worker_func(async_context_t *context, async_when_pending_worker_t *worker) { + assert(worker->user_data); + printf("Disabling wifi\n"); + cyw43_arch_disable_ap_mode(); + ((TCP_SERVER_T*)(worker->user_data))->complete = true; +} + +static async_when_pending_worker_t key_pressed_worker = { + .do_work = key_pressed_worker_func +}; + +void key_pressed_func(void *param) { + assert(param); + int key = getchar_timeout_us(0); // get any pending key press but don't wait + if (key == 'd' || key == 'D') { + // We are probably in irq context so call wifi in a "worker" + async_context_set_work_pending(((TCP_SERVER_T*)param)->context, &key_pressed_worker); + } +} + int main() { stdio_init_all(); @@ -280,6 +303,13 @@ int main() { DEBUG_printf("failed to initialise\n"); return 1; } + + // Get notified if the user presses a key + state->context = cyw43_arch_async_context(); + key_pressed_worker.user_data = state; + async_context_add_when_pending_worker(cyw43_arch_async_context(), &key_pressed_worker); + stdio_set_chars_available_callback(key_pressed_func, state); + const char *ap_name = "picow_test"; #if 1 const char *password = "password"; @@ -301,11 +331,12 @@ int main() { dns_server_t dns_server; dns_server_init(&dns_server, &state->gw); - if (!tcp_server_open(state)) { + if (!tcp_server_open(state, ap_name)) { DEBUG_printf("failed to open server\n"); return 1; } + state->complete = false; while(!state->complete) { // the following #ifdef is only here so this same example can be used in multiple modes; // you do not need it in your code @@ -323,6 +354,7 @@ int main() { sleep_ms(1000); #endif } + tcp_server_close(state); dns_server_deinit(&dns_server); dhcp_server_deinit(&dhcp_server); cyw43_arch_deinit(); diff --git a/pico_w/wifi/iperf/picow_iperf.c b/pico_w/wifi/iperf/picow_iperf.c index 6e90d5d..c99671f 100644 --- a/pico_w/wifi/iperf/picow_iperf.c +++ b/pico_w/wifi/iperf/picow_iperf.c @@ -36,6 +36,24 @@ static void iperf_report(void *arg, enum lwiperf_report_type report_type, #endif } +// This "worker" function is called to safely perform work when instructed by key_pressed_func +void key_pressed_worker_func(async_context_t *context, async_when_pending_worker_t *worker) { + printf("Disabling wifi\n"); + cyw43_arch_disable_sta_mode(); +} + +static async_when_pending_worker_t key_pressed_worker = { + .do_work = key_pressed_worker_func +}; + +void key_pressed_func(void *param) { + int key = getchar_timeout_us(0); // get any pending key press but don't wait + if (key == 'd' || key == 'D') { + // We are probably in irq context so call wifi in a "worker" + async_context_set_work_pending((async_context_t*)param, &key_pressed_worker); + } +} + int main() { stdio_init_all(); @@ -43,8 +61,13 @@ int main() { printf("failed to initialise\n"); return 1; } + + // Get notified if the user presses a key + async_context_add_when_pending_worker(cyw43_arch_async_context(), &key_pressed_worker); + stdio_set_chars_available_callback(key_pressed_func, cyw43_arch_async_context()); + cyw43_arch_enable_sta_mode(); - printf("Connecting to Wi-Fi...\n"); + printf("Connecting to Wi-Fi... (press 'd' to disconnect)\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; @@ -64,7 +87,7 @@ int main() { #endif cyw43_arch_lwip_end(); - while(true) { + while(cyw43_wifi_link_status(&cyw43_state, CYW43_ITF_STA) != CYW43_LINK_DOWN) { #if USE_LED static absolute_time_t led_time; static int led_on = true;