BLE demo for mbed Ported RunningElectronics's SBDBT firmware for BLE. It can communicate with iOS
Dependencies: FatFileSystem mbed
Fork of BTstack by
run_loop_embedded.c
00001 /* 00002 * Copyright (C) 2009-2012 by Matthias Ringwald 00003 * 00004 * Redistribution and use in source and binary forms, with or without 00005 * modification, are permitted provided that the following conditions 00006 * are met: 00007 * 00008 * 1. Redistributions of source code must retain the above copyright 00009 * notice, this list of conditions and the following disclaimer. 00010 * 2. Redistributions in binary form must reproduce the above copyright 00011 * notice, this list of conditions and the following disclaimer in the 00012 * documentation and/or other materials provided with the distribution. 00013 * 3. Neither the name of the copyright holders nor the names of 00014 * contributors may be used to endorse or promote products derived 00015 * from this software without specific prior written permission. 00016 * 4. Any redistribution, use, or modification is done solely for 00017 * personal benefit and not for any commercial purpose or for 00018 * monetary gain. 00019 * 00020 * THIS SOFTWARE IS PROVIDED BY MATTHIAS RINGWALD AND CONTRIBUTORS 00021 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00022 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 00023 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS 00024 * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 00025 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 00026 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 00027 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 00028 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00029 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 00030 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 00031 * SUCH DAMAGE. 00032 * 00033 * Please inquire about commercial licensing options at btstack@ringwald.ch 00034 * 00035 */ 00036 00037 /* 00038 * run_loop_embedded.c 00039 * 00040 * For this run loop, we assume that there's no global way to wait for a list 00041 * of data sources to get ready. Instead, each data source has to queried 00042 * individually. Calling ds->isReady() before calling ds->process() doesn't 00043 * make sense, so we just poll each data source round robin. 00044 * 00045 * To support an idle state, where an MCU could go to sleep, the process function 00046 * has to return if it has to called again as soon as possible 00047 * 00048 * After calling process() on every data source and evaluating the pending timers, 00049 * the idle hook gets called if no data source did indicate that it needs to be 00050 * called right away. 00051 * 00052 */ 00053 00054 00055 #include "btstack/run_loop.h" 00056 #include "btstack/linked_list.h" 00057 #include "btstack/hal_tick.h" 00058 #include "btstack/hal_cpu.h" 00059 00060 #include "run_loop_private.h" 00061 #include "debug.h" 00062 00063 #include <stddef.h> // NULL 00064 00065 // the run loop 00066 static linked_list_t data_sources; 00067 00068 static linked_list_t timers; 00069 00070 #ifdef HAVE_TICK 00071 static uint32_t system_ticks; 00072 #endif 00073 00074 static int trigger_event_received = 0; 00075 00076 /** 00077 * trigger run loop iteration 00078 */ 00079 void embedded_trigger(void){ 00080 trigger_event_received = 1; 00081 } 00082 00083 /** 00084 * Add data_source to run_loop 00085 */ 00086 void embedded_add_data_source(data_source_t *ds){ 00087 linked_list_add(&data_sources, (linked_item_t *) ds); 00088 } 00089 00090 /** 00091 * Remove data_source from run loop 00092 */ 00093 int embedded_remove_data_source(data_source_t *ds){ 00094 return linked_list_remove(&data_sources, (linked_item_t *) ds); 00095 } 00096 00097 /** 00098 * Add timer to run_loop (keep list sorted) 00099 */ 00100 void embedded_add_timer(timer_source_t *ts){ 00101 #ifdef HAVE_TICK 00102 linked_item_t *it; 00103 for (it = (linked_item_t *) &timers; it->next ; it = it->next){ 00104 if (ts->timeout < ((timer_source_t *) it->next)->timeout) { 00105 break; 00106 } 00107 } 00108 ts->item.next = it->next; 00109 it->next = (linked_item_t *) ts; 00110 // log_info("Added timer %x at %u\n", (int) ts, (unsigned int) ts->timeout.tv_sec); 00111 // embedded_dump_timer(); 00112 #endif 00113 } 00114 00115 /** 00116 * Remove timer from run loop 00117 */ 00118 int embedded_remove_timer(timer_source_t *ts){ 00119 #ifdef HAVE_TICK 00120 // log_info("Removed timer %x at %u\n", (int) ts, (unsigned int) ts->timeout.tv_sec); 00121 return linked_list_remove(&timers, (linked_item_t *) ts); 00122 #else 00123 return 0; 00124 #endif 00125 } 00126 00127 void embedded_dump_timer(void){ 00128 #ifdef HAVE_TICK 00129 #ifdef ENABLE_LOG_INFO 00130 linked_item_t *it; 00131 int i = 0; 00132 for (it = (linked_item_t *) timers; it ; it = it->next){ 00133 timer_source_t *ts = (timer_source_t*) it; 00134 log_info("timer %u, timeout %u\n", i, (unsigned int) ts->timeout); 00135 } 00136 #endif 00137 #endif 00138 } 00139 00140 /** 00141 * Execute run_loop 00142 */ 00143 void embedded_execute(void) { 00144 data_source_t *ds; 00145 00146 while (1) { 00147 00148 // process data sources 00149 data_source_t *next; 00150 for (ds = (data_source_t *) data_sources; ds != NULL ; ds = next){ 00151 next = (data_source_t *) ds->item.next; // cache pointer to next data_source to allow data source to remove itself 00152 ds->process(ds); 00153 } 00154 00155 #ifdef HAVE_TICK 00156 // process timers 00157 while (timers) { 00158 timer_source_t *ts = (timer_source_t *) timers; 00159 if (ts->timeout > system_ticks) break; 00160 run_loop_remove_timer(ts); 00161 ts->process(ts); 00162 } 00163 #endif 00164 00165 // disable IRQs and check if run loop iteration has been requested. if not, go to sleep 00166 hal_cpu_disable_irqs(); 00167 if (trigger_event_received){ 00168 hal_cpu_enable_irqs_and_sleep(); 00169 continue; 00170 } 00171 hal_cpu_enable_irqs(); 00172 } 00173 } 00174 00175 #ifdef HAVE_TICK 00176 static void embedded_tick_handler(void){ 00177 system_ticks++; 00178 trigger_event_received = 1; 00179 } 00180 00181 uint32_t embedded_get_ticks(void){ 00182 return system_ticks; 00183 } 00184 00185 uint32_t embedded_ticks_for_ms(uint32_t time_in_ms){ 00186 return time_in_ms / hal_tick_get_tick_period_in_ms(); 00187 } 00188 00189 // set timer 00190 void run_loop_set_timer(timer_source_t *ts, uint32_t timeout_in_ms){ 00191 uint32_t ticks = embedded_ticks_for_ms(timeout_in_ms); 00192 if (ticks == 0) ticks++; 00193 ts->timeout = system_ticks + ticks; 00194 } 00195 #endif 00196 00197 void embedded_init(void){ 00198 00199 data_sources = NULL; 00200 00201 #ifdef HAVE_TICK 00202 timers = NULL; 00203 system_ticks = 0; 00204 hal_tick_init(); 00205 hal_tick_set_handler(&embedded_tick_handler); 00206 #endif 00207 } 00208 00209 extern const run_loop_t run_loop_embedded; 00210 const run_loop_t run_loop_embedded = { 00211 &embedded_init, 00212 &embedded_add_data_source, 00213 &embedded_remove_data_source, 00214 &embedded_add_timer, 00215 &embedded_remove_timer, 00216 &embedded_execute, 00217 &embedded_dump_timer 00218 };
Generated on Thu Jul 14 2022 15:03:49 by 1.7.2