1 /*
2  * Copyright (c) 2022 Raspberry Pi (Trading) Ltd.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #if PICO_CYW43_ARCH_POLL
8 
9 #include "pico/cyw43_arch.h"
10 #include "pico/cyw43_driver.h"
11 
12 #include "pico/async_context_poll.h"
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_POLL requires lwIP NO_SYS=1
23 #endif
24 
25 static async_context_poll_t cyw43_async_context_poll;
26 
cyw43_arch_init_default_async_context(void)27 async_context_t *cyw43_arch_init_default_async_context(void) {
28     if (async_context_poll_init_with_defaults(&cyw43_async_context_poll))
29         return &cyw43_async_context_poll.core;
30     return NULL;
31 }
32 
cyw43_arch_init(void)33 int cyw43_arch_init(void) {
34     async_context_t *context = cyw43_arch_async_context();
35     if (!context) {
36         context = cyw43_arch_init_default_async_context();
37         if (!context) return PICO_ERROR_GENERIC;
38         cyw43_arch_set_async_context(context);
39     }
40     bool ok = cyw43_driver_init(context);
41 #if CYW43_LWIP
42     ok &= lwip_nosys_init(context);
43 #endif
44 #if CYW43_ENABLE_BLUETOOTH
45     ok &= btstack_cyw43_init(context);
46 #endif
47     if (!ok) {
48         cyw43_arch_deinit();
49         return PICO_ERROR_GENERIC;
50     } else {
51         return 0;
52     }
53 }
54 
cyw43_arch_deinit(void)55 void cyw43_arch_deinit(void) {
56     async_context_t *context = cyw43_arch_async_context();
57 #if CYW43_ENABLE_BLUETOOTH
58     btstack_cyw43_deinit(context);
59 #endif
60     // there is a bit of a circular dependency here between lwIP and cyw43_driver. We
61     // shut down cyw43_driver first as it has IRQs calling back into lwIP. Also lwIP itself
62     // does not actually get shut down.
63     // todo add a "pause" method to async_context if we need to provide some atomicity (we
64     //      don't want to take the lock as these methods may invoke execute_sync()
65     cyw43_driver_deinit(context);
66 #if CYW43_LWIP
67     lwip_nosys_deinit(context);
68 #endif
69     // if it is our context, then we de-init it.
70     if (context == &cyw43_async_context_poll.core) {
71         async_context_deinit(context);
72         cyw43_arch_set_async_context(NULL);
73     }
74 }
75 
76 #endif
77