@@ -39,6 +39,7 @@ extern "C" {
3939
4040static SemaphoreHandle_t _cyw43_arch_mutex;
4141static SemaphoreHandle_t _cyw43_irq_called_binary;
42+ static SemaphoreHandle_t _cyw43_sleep_poll_binary;
4243
4344static void cb_cyw43_do_poll (void *context);
4445static __callback_req _irqBuffer;
@@ -86,12 +87,17 @@ extern "C" void __wrap_cyw43_schedule_internal_poll_dispatch(__unused void (*fun
8687 lwip_callback (cb_cyw43_do_poll, nullptr );
8788}
8889
90+
91+
8992static int64_t cb_cyw43_sleep_timeout_reached (alarm_id_t id, void *ptr) {
9093 (void ) id;
9194 (void ) ptr;
9295 static __callback_req _sleepIRQBuffer;
9396 // This will be in IRQ context, so do a lwip callback. Only one at a time can be outstanding so this single struct is good enough
94- lwip_callback (cb_cyw43_do_poll, nullptr , &_sleepIRQBuffer);
97+ BaseType_t pxHigherPriorityTaskWoken;
98+ if (xSemaphoreTakeFromISR (_cyw43_sleep_poll_binary, &pxHigherPriorityTaskWoken)) {
99+ lwip_callback (cb_cyw43_do_poll, nullptr , &_sleepIRQBuffer);
100+ }
95101 return 0 ; // Don't reschedule
96102}
97103
@@ -100,6 +106,7 @@ static void cb_cyw43_do_poll(void *context) { //, __unused async_when_pending_wo
100106#ifndef NDEBUG
101107 assert (get_core_num () == 0 );
102108#endif
109+ cyw43_thread_enter ();
103110 if (cyw43_poll) {
104111 if (cyw43_sleep > 0 ) {
105112 cyw43_sleep--;
@@ -111,12 +118,17 @@ static void cb_cyw43_do_poll(void *context) { //, __unused async_when_pending_wo
111118 // Nothing to do. We have 1-shot alarms
112119 }
113120 }
121+ cyw43_thread_exit ();
122+ xSemaphoreGive (_cyw43_irq_called_binary);
123+ xSemaphoreGive (_cyw43_sleep_poll_binary);
114124}
115125
116126extern " C" bool __wrap_cyw43_driver_init (async_context_t *context) {
117127 assert (get_core_num () == 0 );
118128 _cyw43_arch_mutex = xSemaphoreCreateRecursiveMutex ();
119129 _cyw43_irq_called_binary = xSemaphoreCreateBinary ();
130+ _cyw43_sleep_poll_binary = xSemaphoreCreateBinary ();
131+ xSemaphoreGive (_cyw43_sleep_poll_binary);
120132 cyw43_init (&cyw43_state);
121133 cyw43_irq_init (nullptr );
122134 return true ;
@@ -144,6 +156,7 @@ extern "C" void __wrap_cyw43_thread_lock_check() {
144156#endif
145157
146158extern " C" void __wrap_cyw43_await_background_or_timeout_us (uint32_t timeout_us) {
159+ // cyw43_set_irq_enabled(true);
147160 if (__get_current_exception () > 0 ) {
148161 vTaskDelay ((timeout_us / 1000 ) / portTICK_PERIOD_MS);
149162 return ;
@@ -165,4 +178,48 @@ extern "C" void __wrap_cyw43_delay_us(uint32_t us) {
165178 delayMicroseconds (us);
166179}
167180
181+
182+
183+ static int this_cyw43_arch_wifi_connect_bssid_until (const char *ssid, const uint8_t *bssid, const char *pw, uint32_t auth, uint32_t timeout_ms) {
184+ uint32_t start = millis ();
185+ int err = cyw43_arch_wifi_connect_bssid_async (ssid, bssid, pw, auth);
186+ if (err) return err;
187+ int status = CYW43_LINK_UP + 1 ;
188+ while (status >= 0 && status != CYW43_LINK_UP) {
189+ int new_status = cyw43_tcpip_link_status (&cyw43_state, CYW43_ITF_STA);
190+ // If there was no network, keep trying
191+ if (new_status == CYW43_LINK_NONET) {
192+ new_status = CYW43_LINK_JOIN;
193+ err = cyw43_arch_wifi_connect_bssid_async (ssid, bssid, pw, auth);
194+ if (err) return err;
195+ }
196+ if (new_status != status) {
197+ status = new_status;
198+ }
199+ uint32_t delta = millis () - start;
200+ if (delta > timeout_ms) {
201+ return PICO_ERROR_TIMEOUT;
202+ }
203+ // Do polling
204+ // cyw43_arch_poll();
205+ __wrap_cyw43_await_background_or_timeout_us ((timeout_ms - delta) * 1000 ); // cyw43_arch_wait_for_work_until(until);
206+ }
207+ // Turn status into a pico_error_codes, CYW43_LINK_NONET shouldn't happen as we fail with PICO_ERROR_TIMEOUT instead
208+ assert (status == CYW43_LINK_UP || status == CYW43_LINK_BADAUTH || status == CYW43_LINK_FAIL);
209+ if (status == CYW43_LINK_UP) {
210+ return PICO_OK; // success
211+ } else if (status == CYW43_LINK_BADAUTH) {
212+ return PICO_ERROR_BADAUTH;
213+ } else {
214+ return PICO_ERROR_CONNECT_FAILED;
215+ }
216+ }
217+ extern " C" int __wrap_cyw43_arch_wifi_connect_bssid_timeout_ms (const char *ssid, const uint8_t *bssid, const char *pw, uint32_t auth, uint32_t timeout_ms) {
218+ return this_cyw43_arch_wifi_connect_bssid_until (ssid, bssid, pw, auth, timeout_ms); // make_timeout_time_ms(timeout_ms));
219+ }
220+
221+ extern " C" int __wrap_cyw43_arch_wifi_connect_timeout_ms (const char *ssid, const char *pw, uint32_t auth, uint32_t timeout_ms) {
222+ return __wrap_cyw43_arch_wifi_connect_bssid_timeout_ms (ssid, nullptr , pw, auth, timeout_ms);
223+ }
224+
168225#endif
0 commit comments