BTstack for Nucleo F401RE/FRDM-KL46Z example program

Dependencies:   F401RE-USBHost mbed

The usage is the same as KL46Z-BTstack_example.
使い方はKL46Z-BTstack_exampleと同じです。
/media/uploads/va009039/f401re-btstack.jpg

Committer:
va009039
Date:
Mon Jun 09 09:03:25 2014 +0000
Revision:
0:a05a07cd6fdf
first commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
va009039 0:a05a07cd6fdf 1 /*
va009039 0:a05a07cd6fdf 2 * Copyright (C) 2009-2012 by Matthias Ringwald
va009039 0:a05a07cd6fdf 3 *
va009039 0:a05a07cd6fdf 4 * Redistribution and use in source and binary forms, with or without
va009039 0:a05a07cd6fdf 5 * modification, are permitted provided that the following conditions
va009039 0:a05a07cd6fdf 6 * are met:
va009039 0:a05a07cd6fdf 7 *
va009039 0:a05a07cd6fdf 8 * 1. Redistributions of source code must retain the above copyright
va009039 0:a05a07cd6fdf 9 * notice, this list of conditions and the following disclaimer.
va009039 0:a05a07cd6fdf 10 * 2. Redistributions in binary form must reproduce the above copyright
va009039 0:a05a07cd6fdf 11 * notice, this list of conditions and the following disclaimer in the
va009039 0:a05a07cd6fdf 12 * documentation and/or other materials provided with the distribution.
va009039 0:a05a07cd6fdf 13 * 3. Neither the name of the copyright holders nor the names of
va009039 0:a05a07cd6fdf 14 * contributors may be used to endorse or promote products derived
va009039 0:a05a07cd6fdf 15 * from this software without specific prior written permission.
va009039 0:a05a07cd6fdf 16 * 4. Any redistribution, use, or modification is done solely for
va009039 0:a05a07cd6fdf 17 * personal benefit and not for any commercial purpose or for
va009039 0:a05a07cd6fdf 18 * monetary gain.
va009039 0:a05a07cd6fdf 19 *
va009039 0:a05a07cd6fdf 20 * THIS SOFTWARE IS PROVIDED BY MATTHIAS RINGWALD AND CONTRIBUTORS
va009039 0:a05a07cd6fdf 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
va009039 0:a05a07cd6fdf 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
va009039 0:a05a07cd6fdf 23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS
va009039 0:a05a07cd6fdf 24 * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
va009039 0:a05a07cd6fdf 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
va009039 0:a05a07cd6fdf 26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
va009039 0:a05a07cd6fdf 27 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
va009039 0:a05a07cd6fdf 28 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
va009039 0:a05a07cd6fdf 29 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
va009039 0:a05a07cd6fdf 30 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
va009039 0:a05a07cd6fdf 31 * SUCH DAMAGE.
va009039 0:a05a07cd6fdf 32 *
va009039 0:a05a07cd6fdf 33 * Please inquire about commercial licensing options at btstack@ringwald.ch
va009039 0:a05a07cd6fdf 34 *
va009039 0:a05a07cd6fdf 35 */
va009039 0:a05a07cd6fdf 36
va009039 0:a05a07cd6fdf 37 /*
va009039 0:a05a07cd6fdf 38 * run_loop_embedded.c
va009039 0:a05a07cd6fdf 39 *
va009039 0:a05a07cd6fdf 40 * For this run loop, we assume that there's no global way to wait for a list
va009039 0:a05a07cd6fdf 41 * of data sources to get ready. Instead, each data source has to queried
va009039 0:a05a07cd6fdf 42 * individually. Calling ds->isReady() before calling ds->process() doesn't
va009039 0:a05a07cd6fdf 43 * make sense, so we just poll each data source round robin.
va009039 0:a05a07cd6fdf 44 *
va009039 0:a05a07cd6fdf 45 * To support an idle state, where an MCU could go to sleep, the process function
va009039 0:a05a07cd6fdf 46 * has to return if it has to called again as soon as possible
va009039 0:a05a07cd6fdf 47 *
va009039 0:a05a07cd6fdf 48 * After calling process() on every data source and evaluating the pending timers,
va009039 0:a05a07cd6fdf 49 * the idle hook gets called if no data source did indicate that it needs to be
va009039 0:a05a07cd6fdf 50 * called right away.
va009039 0:a05a07cd6fdf 51 *
va009039 0:a05a07cd6fdf 52 */
va009039 0:a05a07cd6fdf 53
va009039 0:a05a07cd6fdf 54
va009039 0:a05a07cd6fdf 55 #include <btstack/run_loop.h>
va009039 0:a05a07cd6fdf 56 #include <btstack/linked_list.h>
va009039 0:a05a07cd6fdf 57 #include <btstack/hal_tick.h>
va009039 0:a05a07cd6fdf 58 #include <btstack/hal_cpu.h>
va009039 0:a05a07cd6fdf 59
va009039 0:a05a07cd6fdf 60 #include "run_loop_private.h"
va009039 0:a05a07cd6fdf 61 #include "debug.h"
va009039 0:a05a07cd6fdf 62
va009039 0:a05a07cd6fdf 63 #include <stddef.h> // NULL
va009039 0:a05a07cd6fdf 64
va009039 0:a05a07cd6fdf 65 // the run loop
va009039 0:a05a07cd6fdf 66 static linked_list_t data_sources;
va009039 0:a05a07cd6fdf 67
va009039 0:a05a07cd6fdf 68 static linked_list_t timers;
va009039 0:a05a07cd6fdf 69
va009039 0:a05a07cd6fdf 70 #ifdef HAVE_TICK
va009039 0:a05a07cd6fdf 71 static uint32_t system_ticks;
va009039 0:a05a07cd6fdf 72 #endif
va009039 0:a05a07cd6fdf 73
va009039 0:a05a07cd6fdf 74 static int trigger_event_received = 0;
va009039 0:a05a07cd6fdf 75
va009039 0:a05a07cd6fdf 76 /**
va009039 0:a05a07cd6fdf 77 * trigger run loop iteration
va009039 0:a05a07cd6fdf 78 */
va009039 0:a05a07cd6fdf 79 void embedded_trigger(void){
va009039 0:a05a07cd6fdf 80 trigger_event_received = 1;
va009039 0:a05a07cd6fdf 81 }
va009039 0:a05a07cd6fdf 82
va009039 0:a05a07cd6fdf 83 /**
va009039 0:a05a07cd6fdf 84 * Add data_source to run_loop
va009039 0:a05a07cd6fdf 85 */
va009039 0:a05a07cd6fdf 86 void embedded_add_data_source(data_source_t *ds){
va009039 0:a05a07cd6fdf 87 linked_list_add(&data_sources, (linked_item_t *) ds);
va009039 0:a05a07cd6fdf 88 }
va009039 0:a05a07cd6fdf 89
va009039 0:a05a07cd6fdf 90 /**
va009039 0:a05a07cd6fdf 91 * Remove data_source from run loop
va009039 0:a05a07cd6fdf 92 */
va009039 0:a05a07cd6fdf 93 int embedded_remove_data_source(data_source_t *ds){
va009039 0:a05a07cd6fdf 94 return linked_list_remove(&data_sources, (linked_item_t *) ds);
va009039 0:a05a07cd6fdf 95 }
va009039 0:a05a07cd6fdf 96
va009039 0:a05a07cd6fdf 97 /**
va009039 0:a05a07cd6fdf 98 * Add timer to run_loop (keep list sorted)
va009039 0:a05a07cd6fdf 99 */
va009039 0:a05a07cd6fdf 100 void embedded_add_timer(timer_source_t *ts){
va009039 0:a05a07cd6fdf 101 #ifdef HAVE_TICK
va009039 0:a05a07cd6fdf 102 linked_item_t *it;
va009039 0:a05a07cd6fdf 103 for (it = (linked_item_t *) &timers; it->next ; it = it->next){
va009039 0:a05a07cd6fdf 104 if (ts->timeout < ((timer_source_t *) it->next)->timeout) {
va009039 0:a05a07cd6fdf 105 break;
va009039 0:a05a07cd6fdf 106 }
va009039 0:a05a07cd6fdf 107 }
va009039 0:a05a07cd6fdf 108 ts->item.next = it->next;
va009039 0:a05a07cd6fdf 109 it->next = (linked_item_t *) ts;
va009039 0:a05a07cd6fdf 110 // log_info("Added timer %x at %u\n", (int) ts, (unsigned int) ts->timeout.tv_sec);
va009039 0:a05a07cd6fdf 111 // embedded_dump_timer();
va009039 0:a05a07cd6fdf 112 #endif
va009039 0:a05a07cd6fdf 113 }
va009039 0:a05a07cd6fdf 114
va009039 0:a05a07cd6fdf 115 /**
va009039 0:a05a07cd6fdf 116 * Remove timer from run loop
va009039 0:a05a07cd6fdf 117 */
va009039 0:a05a07cd6fdf 118 int embedded_remove_timer(timer_source_t *ts){
va009039 0:a05a07cd6fdf 119 #ifdef HAVE_TICK
va009039 0:a05a07cd6fdf 120 // log_info("Removed timer %x at %u\n", (int) ts, (unsigned int) ts->timeout.tv_sec);
va009039 0:a05a07cd6fdf 121 return linked_list_remove(&timers, (linked_item_t *) ts);
va009039 0:a05a07cd6fdf 122 #else
va009039 0:a05a07cd6fdf 123 return 0;
va009039 0:a05a07cd6fdf 124 #endif
va009039 0:a05a07cd6fdf 125 }
va009039 0:a05a07cd6fdf 126
va009039 0:a05a07cd6fdf 127 void embedded_dump_timer(void){
va009039 0:a05a07cd6fdf 128 #ifdef HAVE_TICK
va009039 0:a05a07cd6fdf 129 #ifdef ENABLE_LOG_INFO
va009039 0:a05a07cd6fdf 130 linked_item_t *it;
va009039 0:a05a07cd6fdf 131 int i = 0;
va009039 0:a05a07cd6fdf 132 for (it = (linked_item_t *) timers; it ; it = it->next){
va009039 0:a05a07cd6fdf 133 timer_source_t *ts = (timer_source_t*) it;
va009039 0:a05a07cd6fdf 134 log_info("timer %u, timeout %u\n", i, (unsigned int) ts->timeout);
va009039 0:a05a07cd6fdf 135 }
va009039 0:a05a07cd6fdf 136 #endif
va009039 0:a05a07cd6fdf 137 #endif
va009039 0:a05a07cd6fdf 138 }
va009039 0:a05a07cd6fdf 139
va009039 0:a05a07cd6fdf 140 /**
va009039 0:a05a07cd6fdf 141 * Execute run_loop
va009039 0:a05a07cd6fdf 142 */
va009039 0:a05a07cd6fdf 143 void embedded_execute(void) {
va009039 0:a05a07cd6fdf 144 data_source_t *ds;
va009039 0:a05a07cd6fdf 145
va009039 0:a05a07cd6fdf 146 while (1) {
va009039 0:a05a07cd6fdf 147
va009039 0:a05a07cd6fdf 148 // process data sources
va009039 0:a05a07cd6fdf 149 data_source_t *next;
va009039 0:a05a07cd6fdf 150 for (ds = (data_source_t *) data_sources; ds != NULL ; ds = next){
va009039 0:a05a07cd6fdf 151 next = (data_source_t *) ds->item.next; // cache pointer to next data_source to allow data source to remove itself
va009039 0:a05a07cd6fdf 152 ds->process(ds);
va009039 0:a05a07cd6fdf 153 }
va009039 0:a05a07cd6fdf 154
va009039 0:a05a07cd6fdf 155 #ifdef HAVE_TICK
va009039 0:a05a07cd6fdf 156 // process timers
va009039 0:a05a07cd6fdf 157 while (timers) {
va009039 0:a05a07cd6fdf 158 timer_source_t *ts = (timer_source_t *) timers;
va009039 0:a05a07cd6fdf 159 if (ts->timeout > system_ticks) break;
va009039 0:a05a07cd6fdf 160 run_loop_remove_timer(ts);
va009039 0:a05a07cd6fdf 161 ts->process(ts);
va009039 0:a05a07cd6fdf 162 }
va009039 0:a05a07cd6fdf 163 #endif
va009039 0:a05a07cd6fdf 164
va009039 0:a05a07cd6fdf 165 // disable IRQs and check if run loop iteration has been requested. if not, go to sleep
va009039 0:a05a07cd6fdf 166 hal_cpu_disable_irqs();
va009039 0:a05a07cd6fdf 167 if (trigger_event_received){
va009039 0:a05a07cd6fdf 168 hal_cpu_enable_irqs_and_sleep();
va009039 0:a05a07cd6fdf 169 continue;
va009039 0:a05a07cd6fdf 170 }
va009039 0:a05a07cd6fdf 171 hal_cpu_enable_irqs();
va009039 0:a05a07cd6fdf 172 }
va009039 0:a05a07cd6fdf 173 }
va009039 0:a05a07cd6fdf 174
va009039 0:a05a07cd6fdf 175 #ifdef HAVE_TICK
va009039 0:a05a07cd6fdf 176 static void embedded_tick_handler(void){
va009039 0:a05a07cd6fdf 177 system_ticks++;
va009039 0:a05a07cd6fdf 178 trigger_event_received = 1;
va009039 0:a05a07cd6fdf 179 }
va009039 0:a05a07cd6fdf 180
va009039 0:a05a07cd6fdf 181 uint32_t embedded_get_ticks(void){
va009039 0:a05a07cd6fdf 182 return system_ticks;
va009039 0:a05a07cd6fdf 183 }
va009039 0:a05a07cd6fdf 184
va009039 0:a05a07cd6fdf 185 uint32_t embedded_ticks_for_ms(uint32_t time_in_ms){
va009039 0:a05a07cd6fdf 186 return time_in_ms / hal_tick_get_tick_period_in_ms();
va009039 0:a05a07cd6fdf 187 }
va009039 0:a05a07cd6fdf 188
va009039 0:a05a07cd6fdf 189 // set timer
va009039 0:a05a07cd6fdf 190 void run_loop_set_timer(timer_source_t *ts, uint32_t timeout_in_ms){
va009039 0:a05a07cd6fdf 191 uint32_t ticks = embedded_ticks_for_ms(timeout_in_ms);
va009039 0:a05a07cd6fdf 192 if (ticks == 0) ticks++;
va009039 0:a05a07cd6fdf 193 ts->timeout = system_ticks + ticks;
va009039 0:a05a07cd6fdf 194 }
va009039 0:a05a07cd6fdf 195 #endif
va009039 0:a05a07cd6fdf 196
va009039 0:a05a07cd6fdf 197 void embedded_init(void){
va009039 0:a05a07cd6fdf 198
va009039 0:a05a07cd6fdf 199 data_sources = NULL;
va009039 0:a05a07cd6fdf 200
va009039 0:a05a07cd6fdf 201 #ifdef HAVE_TICK
va009039 0:a05a07cd6fdf 202 timers = NULL;
va009039 0:a05a07cd6fdf 203 system_ticks = 0;
va009039 0:a05a07cd6fdf 204 hal_tick_init();
va009039 0:a05a07cd6fdf 205 hal_tick_set_handler(&embedded_tick_handler);
va009039 0:a05a07cd6fdf 206 #endif
va009039 0:a05a07cd6fdf 207 }
va009039 0:a05a07cd6fdf 208
va009039 0:a05a07cd6fdf 209 extern const run_loop_t run_loop_embedded;
va009039 0:a05a07cd6fdf 210 const run_loop_t run_loop_embedded = {
va009039 0:a05a07cd6fdf 211 &embedded_init,
va009039 0:a05a07cd6fdf 212 &embedded_add_data_source,
va009039 0:a05a07cd6fdf 213 &embedded_remove_data_source,
va009039 0:a05a07cd6fdf 214 &embedded_add_timer,
va009039 0:a05a07cd6fdf 215 &embedded_remove_timer,
va009039 0:a05a07cd6fdf 216 &embedded_execute,
va009039 0:a05a07cd6fdf 217 &embedded_dump_timer
va009039 0:a05a07cd6fdf 218 };