1e25b4a2fSMatthias Ringwald /* 2e25b4a2fSMatthias Ringwald * Copyright (C) 2015 BlueKitchen GmbH 3e25b4a2fSMatthias Ringwald * 4e25b4a2fSMatthias Ringwald * Redistribution and use in source and binary forms, with or without 5e25b4a2fSMatthias Ringwald * modification, are permitted provided that the following conditions 6e25b4a2fSMatthias Ringwald * are met: 7e25b4a2fSMatthias Ringwald * 8e25b4a2fSMatthias Ringwald * 1. Redistributions of source code must retain the above copyright 9e25b4a2fSMatthias Ringwald * notice, this list of conditions and the following disclaimer. 10e25b4a2fSMatthias Ringwald * 2. Redistributions in binary form must reproduce the above copyright 11e25b4a2fSMatthias Ringwald * notice, this list of conditions and the following disclaimer in the 12e25b4a2fSMatthias Ringwald * documentation and/or other materials provided with the distribution. 13e25b4a2fSMatthias Ringwald * 3. Neither the name of the copyright holders nor the names of 14e25b4a2fSMatthias Ringwald * contributors may be used to endorse or promote products derived 15e25b4a2fSMatthias Ringwald * from this software without specific prior written permission. 16e25b4a2fSMatthias Ringwald * 4. Any redistribution, use, or modification is done solely for 17e25b4a2fSMatthias Ringwald * personal benefit and not for any commercial purpose or for 18e25b4a2fSMatthias Ringwald * monetary gain. 19e25b4a2fSMatthias Ringwald * 20e25b4a2fSMatthias Ringwald * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS 21e25b4a2fSMatthias Ringwald * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22e25b4a2fSMatthias Ringwald * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23e25b4a2fSMatthias Ringwald * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS 24e25b4a2fSMatthias Ringwald * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25e25b4a2fSMatthias Ringwald * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 26e25b4a2fSMatthias Ringwald * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 27e25b4a2fSMatthias Ringwald * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 28e25b4a2fSMatthias Ringwald * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29e25b4a2fSMatthias Ringwald * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 30e25b4a2fSMatthias Ringwald * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31e25b4a2fSMatthias Ringwald * SUCH DAMAGE. 32e25b4a2fSMatthias Ringwald * 33e25b4a2fSMatthias Ringwald * Please inquire about commercial licensing options at 34e25b4a2fSMatthias Ringwald * [email protected] 35e25b4a2fSMatthias Ringwald * 36e25b4a2fSMatthias Ringwald */ 37e25b4a2fSMatthias Ringwald 38e501bae0SMatthias Ringwald #define BTSTACK_FILE__ "btstack_run_loop_wiced.c" 39e25b4a2fSMatthias Ringwald 40e25b4a2fSMatthias Ringwald /* 41e25b4a2fSMatthias Ringwald * btstack_run_loop_wiced.c 42e25b4a2fSMatthias Ringwald * 43e25b4a2fSMatthias Ringwald * Run loop for Broadcom WICED SDK which currently supports FreeRTOS and ThreadX 44e25b4a2fSMatthias Ringwald * WICED 3.3.1 does not support Event Flags on FreeRTOS so a queue is used instead 45e25b4a2fSMatthias Ringwald */ 46e25b4a2fSMatthias Ringwald 47e25b4a2fSMatthias Ringwald #include "wiced.h" 48e25b4a2fSMatthias Ringwald 4985ce275aSMatthias Ringwald #include "btstack_run_loop_wiced.h" 50e25b4a2fSMatthias Ringwald 51e25b4a2fSMatthias Ringwald #include "btstack_linked_list.h" 52e25b4a2fSMatthias Ringwald #include "btstack_debug.h" 5385ce275aSMatthias Ringwald #include "btstack_util.h" 54e25b4a2fSMatthias Ringwald #include "btstack_run_loop.h" 5585ce275aSMatthias Ringwald 5685ce275aSMatthias Ringwald #include <stddef.h> // NULL 57e25b4a2fSMatthias Ringwald 58e25b4a2fSMatthias Ringwald typedef struct function_call { 59e25b4a2fSMatthias Ringwald wiced_result_t (*fn)(void * arg); 60e25b4a2fSMatthias Ringwald void * arg; 61e25b4a2fSMatthias Ringwald } function_call_t; 62e25b4a2fSMatthias Ringwald 63e25b4a2fSMatthias Ringwald static const btstack_run_loop_t btstack_run_loop_wiced; 64e25b4a2fSMatthias Ringwald 65e25b4a2fSMatthias Ringwald static wiced_queue_t btstack_run_loop_queue; 66e25b4a2fSMatthias Ringwald 67e25b4a2fSMatthias Ringwald // the run loop 68*66c452cfSMatthias Ringwald static bool run_loop_exit_requested; 69*66c452cfSMatthias Ringwald 70e25b4a2fSMatthias Ringwald static uint32_t btstack_run_loop_wiced_get_time_ms(void){ 71e25b4a2fSMatthias Ringwald wiced_time_t time; 72e25b4a2fSMatthias Ringwald wiced_time_get_time(&time); 73e25b4a2fSMatthias Ringwald return time; 74e25b4a2fSMatthias Ringwald } 75e25b4a2fSMatthias Ringwald 76e25b4a2fSMatthias Ringwald // set timer 77e25b4a2fSMatthias Ringwald static void btstack_run_loop_wiced_set_timer(btstack_timer_source_t *ts, uint32_t timeout_in_ms){ 78e25b4a2fSMatthias Ringwald ts->timeout = btstack_run_loop_wiced_get_time_ms() + timeout_in_ms + 1; 79e25b4a2fSMatthias Ringwald } 80e25b4a2fSMatthias Ringwald 81e25b4a2fSMatthias Ringwald // schedules execution similar to wiced_rtos_send_asynchronous_event for worker threads 82e25b4a2fSMatthias Ringwald void btstack_run_loop_wiced_execute_code_on_main_thread(wiced_result_t (*fn)(void *arg), void * arg){ 83e25b4a2fSMatthias Ringwald function_call_t message; 84e25b4a2fSMatthias Ringwald message.fn = fn; 85e25b4a2fSMatthias Ringwald message.arg = arg; 86e25b4a2fSMatthias Ringwald wiced_rtos_push_to_queue(&btstack_run_loop_queue, &message, WICED_NEVER_TIMEOUT); 87e25b4a2fSMatthias Ringwald } 88e25b4a2fSMatthias Ringwald 89e25b4a2fSMatthias Ringwald /** 90e25b4a2fSMatthias Ringwald * Execute run_loop 91e25b4a2fSMatthias Ringwald */ 92e25b4a2fSMatthias Ringwald static void btstack_run_loop_wiced_execute(void) { 93*66c452cfSMatthias Ringwald while (run_loop_exit_requested == false) { 946cdca94fSMatthias Ringwald 956cdca94fSMatthias Ringwald // process timers 96e25b4a2fSMatthias Ringwald uint32_t now = btstack_run_loop_wiced_get_time_ms(); 976cdca94fSMatthias Ringwald btstack_run_loop_base_process_timers(now); 986cdca94fSMatthias Ringwald 996cdca94fSMatthias Ringwald // get time until next timeout 1006cdca94fSMatthias Ringwald int32_t timeout_next_timer_ms = btstack_run_loop_base_get_time_until_timeout(now); 1016cdca94fSMatthias Ringwald uint32_t timeout_ms = WICED_NEVER_TIMEOUT; 1026cdca94fSMatthias Ringwald if (timeout_next_timer_ms >= 0){ 1036cdca94fSMatthias Ringwald timeout_ms = (uint32_t) timeout_next_timer_ms; 104e25b4a2fSMatthias Ringwald } 105e25b4a2fSMatthias Ringwald 106e25b4a2fSMatthias Ringwald // pop function call 107e25b4a2fSMatthias Ringwald function_call_t message = { NULL, NULL }; 108e25b4a2fSMatthias Ringwald wiced_rtos_pop_from_queue( &btstack_run_loop_queue, &message, timeout_ms); 109e25b4a2fSMatthias Ringwald if (message.fn){ 110e25b4a2fSMatthias Ringwald // execute code on run loop 111e25b4a2fSMatthias Ringwald message.fn(message.arg); 112e25b4a2fSMatthias Ringwald } 113e25b4a2fSMatthias Ringwald } 114e25b4a2fSMatthias Ringwald } 115e25b4a2fSMatthias Ringwald 116*66c452cfSMatthias Ringwald 117*66c452cfSMatthias Ringwald static void btstack_run_loop_wiced_trigger_exit(void){ 118*66c452cfSMatthias Ringwald run_loop_exit_requested = true; 119*66c452cfSMatthias Ringwald } 120*66c452cfSMatthias Ringwald 121e25b4a2fSMatthias Ringwald static void btstack_run_loop_wiced_btstack_run_loop_init(void){ 1226cdca94fSMatthias Ringwald btstack_run_loop_base_init(); 123e25b4a2fSMatthias Ringwald 124e25b4a2fSMatthias Ringwald // queue to receive events: up to 2 calls from transport, up to 3 for app 125e25b4a2fSMatthias Ringwald wiced_rtos_init_queue(&btstack_run_loop_queue, "BTstack Run Loop", sizeof(function_call_t), 5); 126e25b4a2fSMatthias Ringwald } 127e25b4a2fSMatthias Ringwald 128e25b4a2fSMatthias Ringwald /** 129e25b4a2fSMatthias Ringwald * @brief Provide btstack_run_loop_posix instance for use with btstack_run_loop_init 130e25b4a2fSMatthias Ringwald */ 131e25b4a2fSMatthias Ringwald const btstack_run_loop_t * btstack_run_loop_wiced_get_instance(void){ 132e25b4a2fSMatthias Ringwald return &btstack_run_loop_wiced; 133e25b4a2fSMatthias Ringwald } 134e25b4a2fSMatthias Ringwald 135e25b4a2fSMatthias Ringwald static const btstack_run_loop_t btstack_run_loop_wiced = { 136e25b4a2fSMatthias Ringwald &btstack_run_loop_wiced_btstack_run_loop_init, 137e25b4a2fSMatthias Ringwald NULL, 138e25b4a2fSMatthias Ringwald NULL, 139e25b4a2fSMatthias Ringwald NULL, 140e25b4a2fSMatthias Ringwald NULL, 141e25b4a2fSMatthias Ringwald &btstack_run_loop_wiced_set_timer, 1426cdca94fSMatthias Ringwald &btstack_run_loop_base_add_timer, 1436cdca94fSMatthias Ringwald &btstack_run_loop_base_remove_timer, 144e25b4a2fSMatthias Ringwald &btstack_run_loop_wiced_execute, 1456cdca94fSMatthias Ringwald &btstack_run_loop_base_dump_timer, 146e25b4a2fSMatthias Ringwald &btstack_run_loop_wiced_get_time_ms, 147*66c452cfSMatthias Ringwald NULL, /* poll data sources from irq */ 148*66c452cfSMatthias Ringwald NULL, 149*66c452cfSMatthias Ringwald btstack_run_loop_wiced_trigger_exit 150e25b4a2fSMatthias Ringwald }; 151