1 /* 2 * Copyright (c) 2022 Raspberry Pi (Trading) Ltd. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #if PICO_CYW43_ARCH_THREADSAFE_BACKGROUND 8 9 #include "pico/cyw43_arch.h" 10 #include "pico/cyw43_driver.h" 11 #include "pico/async_context_threadsafe_background.h" 12 13 #if CYW43_LWIP 14 #include "pico/lwip_nosys.h" 15 #endif 16 17 #if CYW43_ENABLE_BLUETOOTH 18 #include "pico/btstack_cyw43.h" 19 #endif 20 21 #if CYW43_LWIP && !NO_SYS 22 #error PICO_CYW43_ARCH_THREADSAFE_BACKGROUND requires lwIP NO_SYS=1 23 #endif 24 #if CYW43_LWIP && MEM_LIBC_MALLOC 25 // would attempt to use malloc from IRQ context 26 #error MEM_LIBC_MALLOC is incompatible with PICO_CYW43_ARCH_THREADSAFE_BACKGROUND 27 #endif 28 29 static async_context_threadsafe_background_t cyw43_async_context_threadsafe_background; 30 cyw43_arch_init_default_async_context(void)31async_context_t *cyw43_arch_init_default_async_context(void) { 32 async_context_threadsafe_background_config_t config = async_context_threadsafe_background_default_config(); 33 if (async_context_threadsafe_background_init(&cyw43_async_context_threadsafe_background, &config)) 34 return &cyw43_async_context_threadsafe_background.core; 35 return NULL; 36 } 37 cyw43_arch_init(void)38int cyw43_arch_init(void) { 39 async_context_t *context = cyw43_arch_async_context(); 40 if (!context) { 41 context = cyw43_arch_init_default_async_context(); 42 if (!context) return PICO_ERROR_GENERIC; 43 cyw43_arch_set_async_context(context); 44 } 45 bool ok = cyw43_driver_init(context); 46 #if CYW43_LWIP 47 ok &= lwip_nosys_init(context); 48 #endif 49 #if CYW43_ENABLE_BLUETOOTH 50 ok &= btstack_cyw43_init(context); 51 #endif 52 if (!ok) { 53 cyw43_arch_deinit(); 54 return PICO_ERROR_GENERIC; 55 } else { 56 return 0; 57 } 58 } 59 cyw43_arch_deinit(void)60void cyw43_arch_deinit(void) { 61 async_context_t *context = cyw43_arch_async_context(); 62 #if CYW43_ENABLE_BLUETOOTH 63 btstack_cyw43_deinit(context); 64 #endif 65 // there is a bit of a circular dependency here between lwIP and cyw43_driver. We 66 // shut down cyw43_driver first as it has IRQs calling back into lwIP. Also lwIP itself 67 // does not actually get shut down. 68 // todo add a "pause" method to async_context if we need to provide some atomicity (we 69 // don't want to take the lock as these methods may invoke execute_sync() 70 cyw43_driver_deinit(context); 71 #if CYW43_LWIP 72 lwip_nosys_deinit(context); 73 #endif 74 // if it is our context, then we de-init it. 75 if (context == &cyw43_async_context_threadsafe_background.core) { 76 async_context_deinit(context); 77 cyw43_arch_set_async_context(NULL); 78 } 79 } 80 81 #endif 82