Generic communication interface between the wireless board (mote) and the sensor board. Any kind of sensor board can be connected to the mote using this specification given it provides a SPI peripheral, one input pin with interrupt capability and one digital output. The sensor board must implement a special register set from which all required information can be retrieved. Protocol: http://is.gd/wuQorh Github: http://is.gd/ySj1L9

Dependencies:   mbed-src

Committer:
marcelobarrosalmeida
Date:
Tue Apr 08 16:34:20 2014 +0000
Revision:
1:acdf490d94a7
Adding accel to sensor list

Who changed what in which revision?

UserRevisionLine numberNew contents of line
marcelobarrosalmeida 1:acdf490d94a7 1 /*
marcelobarrosalmeida 1:acdf490d94a7 2 * Copyright (c) 2004-2005, Swedish Institute of Computer Science.
marcelobarrosalmeida 1:acdf490d94a7 3 * All rights reserved.
marcelobarrosalmeida 1:acdf490d94a7 4 *
marcelobarrosalmeida 1:acdf490d94a7 5 * Redistribution and use in source and binary forms, with or without
marcelobarrosalmeida 1:acdf490d94a7 6 * modification, are permitted provided that the following conditions
marcelobarrosalmeida 1:acdf490d94a7 7 * are met:
marcelobarrosalmeida 1:acdf490d94a7 8 * 1. Redistributions of source code must retain the above copyright
marcelobarrosalmeida 1:acdf490d94a7 9 * notice, this list of conditions and the following disclaimer.
marcelobarrosalmeida 1:acdf490d94a7 10 * 2. Redistributions in binary form must reproduce the above copyright
marcelobarrosalmeida 1:acdf490d94a7 11 * notice, this list of conditions and the following disclaimer in the
marcelobarrosalmeida 1:acdf490d94a7 12 * documentation and/or other materials provided with the distribution.
marcelobarrosalmeida 1:acdf490d94a7 13 * 3. Neither the name of the Institute nor the names of its contributors
marcelobarrosalmeida 1:acdf490d94a7 14 * may be used to endorse or promote products derived from this software
marcelobarrosalmeida 1:acdf490d94a7 15 * without specific prior written permission.
marcelobarrosalmeida 1:acdf490d94a7 16 *
marcelobarrosalmeida 1:acdf490d94a7 17 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
marcelobarrosalmeida 1:acdf490d94a7 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
marcelobarrosalmeida 1:acdf490d94a7 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
marcelobarrosalmeida 1:acdf490d94a7 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
marcelobarrosalmeida 1:acdf490d94a7 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
marcelobarrosalmeida 1:acdf490d94a7 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
marcelobarrosalmeida 1:acdf490d94a7 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
marcelobarrosalmeida 1:acdf490d94a7 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
marcelobarrosalmeida 1:acdf490d94a7 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
marcelobarrosalmeida 1:acdf490d94a7 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
marcelobarrosalmeida 1:acdf490d94a7 27 * SUCH DAMAGE.
marcelobarrosalmeida 1:acdf490d94a7 28 *
marcelobarrosalmeida 1:acdf490d94a7 29 * This file is part of the Contiki operating system.
marcelobarrosalmeida 1:acdf490d94a7 30 *
marcelobarrosalmeida 1:acdf490d94a7 31 * Author: Adam Dunkels <adam@sics.se>
marcelobarrosalmeida 1:acdf490d94a7 32 *
marcelobarrosalmeida 1:acdf490d94a7 33 * $Id: graham-pt.h,v 1.1 2005/10/04 08:30:05 adam Exp $
marcelobarrosalmeida 1:acdf490d94a7 34 */
marcelobarrosalmeida 1:acdf490d94a7 35
marcelobarrosalmeida 1:acdf490d94a7 36 /**
marcelobarrosalmeida 1:acdf490d94a7 37 * \addtogroup pt
marcelobarrosalmeida 1:acdf490d94a7 38 * @{
marcelobarrosalmeida 1:acdf490d94a7 39 */
marcelobarrosalmeida 1:acdf490d94a7 40
marcelobarrosalmeida 1:acdf490d94a7 41 /**
marcelobarrosalmeida 1:acdf490d94a7 42 * \file
marcelobarrosalmeida 1:acdf490d94a7 43 * Protothreads implementation.
marcelobarrosalmeida 1:acdf490d94a7 44 * \author
marcelobarrosalmeida 1:acdf490d94a7 45 * Adam Dunkels <adam@sics.se>
marcelobarrosalmeida 1:acdf490d94a7 46 *
marcelobarrosalmeida 1:acdf490d94a7 47 */
marcelobarrosalmeida 1:acdf490d94a7 48
marcelobarrosalmeida 1:acdf490d94a7 49 #ifndef __PT_H__
marcelobarrosalmeida 1:acdf490d94a7 50 #define __PT_H__
marcelobarrosalmeida 1:acdf490d94a7 51
marcelobarrosalmeida 1:acdf490d94a7 52 #include "lc.h"
marcelobarrosalmeida 1:acdf490d94a7 53
marcelobarrosalmeida 1:acdf490d94a7 54 struct pt {
marcelobarrosalmeida 1:acdf490d94a7 55 lc_t lc;
marcelobarrosalmeida 1:acdf490d94a7 56 };
marcelobarrosalmeida 1:acdf490d94a7 57
marcelobarrosalmeida 1:acdf490d94a7 58 /**
marcelobarrosalmeida 1:acdf490d94a7 59 * Extended PT.
marcelobarrosalmeida 1:acdf490d94a7 60 * This add's a flags field to the basic pt structure.
marcelobarrosalmeida 1:acdf490d94a7 61 */
marcelobarrosalmeida 1:acdf490d94a7 62 struct ptx {
marcelobarrosalmeida 1:acdf490d94a7 63 lc_t lc;
marcelobarrosalmeida 1:acdf490d94a7 64 unsigned short flags;
marcelobarrosalmeida 1:acdf490d94a7 65 };
marcelobarrosalmeida 1:acdf490d94a7 66
marcelobarrosalmeida 1:acdf490d94a7 67 #define PT_THREAD_WAITING 0
marcelobarrosalmeida 1:acdf490d94a7 68 #define PT_THREAD_EXITED 1
marcelobarrosalmeida 1:acdf490d94a7 69
marcelobarrosalmeida 1:acdf490d94a7 70 /** Extended PT flag : thread is sleeping */
marcelobarrosalmeida 1:acdf490d94a7 71 #define PT_F_SLEEPING 1
marcelobarrosalmeida 1:acdf490d94a7 72 /** Extended PT flag : thread has been flagged to be killed (will exit on next block/wait/yield) */
marcelobarrosalmeida 1:acdf490d94a7 73 #define PT_F_KILL 2
marcelobarrosalmeida 1:acdf490d94a7 74 /** Extended PT flag : thread is waiting */
marcelobarrosalmeida 1:acdf490d94a7 75 #define PT_F_WAITING 4
marcelobarrosalmeida 1:acdf490d94a7 76
marcelobarrosalmeida 1:acdf490d94a7 77 /**
marcelobarrosalmeida 1:acdf490d94a7 78 * Declaration of a protothread.
marcelobarrosalmeida 1:acdf490d94a7 79 *
marcelobarrosalmeida 1:acdf490d94a7 80 * This macro is used to declare a protothread. All protothreads must
marcelobarrosalmeida 1:acdf490d94a7 81 * be declared with this macro.
marcelobarrosalmeida 1:acdf490d94a7 82 *
marcelobarrosalmeida 1:acdf490d94a7 83 * Example:
marcelobarrosalmeida 1:acdf490d94a7 84 \code
marcelobarrosalmeida 1:acdf490d94a7 85 PT_THREAD(consumer(struct pt *p, int event)) {
marcelobarrosalmeida 1:acdf490d94a7 86 PT_BEGIN(p);
marcelobarrosalmeida 1:acdf490d94a7 87 while(1) {
marcelobarrosalmeida 1:acdf490d94a7 88 PT_WAIT_UNTIL(p, event == AVAILABLE);
marcelobarrosalmeida 1:acdf490d94a7 89 consume();
marcelobarrosalmeida 1:acdf490d94a7 90 PT_WAIT_UNTIL(p, event == CONSUMED);
marcelobarrosalmeida 1:acdf490d94a7 91 acknowledge_consumed();
marcelobarrosalmeida 1:acdf490d94a7 92 }
marcelobarrosalmeida 1:acdf490d94a7 93 PT_END(p);
marcelobarrosalmeida 1:acdf490d94a7 94 }
marcelobarrosalmeida 1:acdf490d94a7 95 \endcode
marcelobarrosalmeida 1:acdf490d94a7 96 *
marcelobarrosalmeida 1:acdf490d94a7 97 * \param name_args The name and arguments of the C function
marcelobarrosalmeida 1:acdf490d94a7 98 * implementing the protothread.
marcelobarrosalmeida 1:acdf490d94a7 99 *
marcelobarrosalmeida 1:acdf490d94a7 100 * \hideinitializer
marcelobarrosalmeida 1:acdf490d94a7 101 */
marcelobarrosalmeida 1:acdf490d94a7 102 #define PT_THREAD(name_args) char name_args
marcelobarrosalmeida 1:acdf490d94a7 103
marcelobarrosalmeida 1:acdf490d94a7 104 /**
marcelobarrosalmeida 1:acdf490d94a7 105 * Initialize a protothread.
marcelobarrosalmeida 1:acdf490d94a7 106 *
marcelobarrosalmeida 1:acdf490d94a7 107 * Initializes a protothread. Initialization must be done prior to
marcelobarrosalmeida 1:acdf490d94a7 108 * starting to execute the protothread.
marcelobarrosalmeida 1:acdf490d94a7 109 *
marcelobarrosalmeida 1:acdf490d94a7 110 * \param pt A pointer to the protothread control structure.
marcelobarrosalmeida 1:acdf490d94a7 111 *
marcelobarrosalmeida 1:acdf490d94a7 112 * Example:
marcelobarrosalmeida 1:acdf490d94a7 113 *
marcelobarrosalmeida 1:acdf490d94a7 114 \code
marcelobarrosalmeida 1:acdf490d94a7 115 void main(void) {
marcelobarrosalmeida 1:acdf490d94a7 116 struct pt p;
marcelobarrosalmeida 1:acdf490d94a7 117 int event;
marcelobarrosalmeida 1:acdf490d94a7 118
marcelobarrosalmeida 1:acdf490d94a7 119 PT_INIT(&p);
marcelobarrosalmeida 1:acdf490d94a7 120 while(PT_SCHEDULE(consumer(&p, event))) {
marcelobarrosalmeida 1:acdf490d94a7 121 event = get_event();
marcelobarrosalmeida 1:acdf490d94a7 122 }
marcelobarrosalmeida 1:acdf490d94a7 123 }
marcelobarrosalmeida 1:acdf490d94a7 124 \endcode
marcelobarrosalmeida 1:acdf490d94a7 125 *
marcelobarrosalmeida 1:acdf490d94a7 126 * \sa PT_SPAWN()
marcelobarrosalmeida 1:acdf490d94a7 127 *
marcelobarrosalmeida 1:acdf490d94a7 128 * \hideinitializer
marcelobarrosalmeida 1:acdf490d94a7 129 */
marcelobarrosalmeida 1:acdf490d94a7 130 #define PT_INIT(pt) LC_INIT((pt)->lc)
marcelobarrosalmeida 1:acdf490d94a7 131
marcelobarrosalmeida 1:acdf490d94a7 132 /**
marcelobarrosalmeida 1:acdf490d94a7 133 * Declare the start of a protothread inside the C function
marcelobarrosalmeida 1:acdf490d94a7 134 * implementing the protothread.
marcelobarrosalmeida 1:acdf490d94a7 135 *
marcelobarrosalmeida 1:acdf490d94a7 136 * This macro is used to declare the starting point of a
marcelobarrosalmeida 1:acdf490d94a7 137 * protothread. It should be placed at the start of the function in
marcelobarrosalmeida 1:acdf490d94a7 138 * which the protothread runs. All C statements above the PT_BEGIN()
marcelobarrosalmeida 1:acdf490d94a7 139 * invokation will be executed each time the protothread is scheduled.
marcelobarrosalmeida 1:acdf490d94a7 140 *
marcelobarrosalmeida 1:acdf490d94a7 141 * \param pt A pointer to the protothread control structure.
marcelobarrosalmeida 1:acdf490d94a7 142 *
marcelobarrosalmeida 1:acdf490d94a7 143 * Example:
marcelobarrosalmeida 1:acdf490d94a7 144 *
marcelobarrosalmeida 1:acdf490d94a7 145 \code
marcelobarrosalmeida 1:acdf490d94a7 146 PT_THREAD(producer(struct pt *p, int event)) {
marcelobarrosalmeida 1:acdf490d94a7 147 PT_BEGIN(p);
marcelobarrosalmeida 1:acdf490d94a7 148 while(1) {
marcelobarrosalmeida 1:acdf490d94a7 149 PT_WAIT_UNTIL(p, event == CONSUMED || event == DROPPED);
marcelobarrosalmeida 1:acdf490d94a7 150 produce();
marcelobarrosalmeida 1:acdf490d94a7 151 PT_WAIT_UNTIL(p, event == PRODUCED);
marcelobarrosalmeida 1:acdf490d94a7 152 }
marcelobarrosalmeida 1:acdf490d94a7 153
marcelobarrosalmeida 1:acdf490d94a7 154 PT_END(p);
marcelobarrosalmeida 1:acdf490d94a7 155 }
marcelobarrosalmeida 1:acdf490d94a7 156 \endcode
marcelobarrosalmeida 1:acdf490d94a7 157 *
marcelobarrosalmeida 1:acdf490d94a7 158 * \hideinitializer
marcelobarrosalmeida 1:acdf490d94a7 159 */
marcelobarrosalmeida 1:acdf490d94a7 160 #define PT_BEGIN(pt) LC_RESUME((pt)->lc)
marcelobarrosalmeida 1:acdf490d94a7 161
marcelobarrosalmeida 1:acdf490d94a7 162 /**
marcelobarrosalmeida 1:acdf490d94a7 163 * Block and wait until condition is true.
marcelobarrosalmeida 1:acdf490d94a7 164 *
marcelobarrosalmeida 1:acdf490d94a7 165 * This macro blocks the protothread until the specified condition is
marcelobarrosalmeida 1:acdf490d94a7 166 * true.
marcelobarrosalmeida 1:acdf490d94a7 167 *
marcelobarrosalmeida 1:acdf490d94a7 168 * \param pt A pointer to the protothread control structure.
marcelobarrosalmeida 1:acdf490d94a7 169 * \param condition The condition.
marcelobarrosalmeida 1:acdf490d94a7 170 *
marcelobarrosalmeida 1:acdf490d94a7 171 * Example:
marcelobarrosalmeida 1:acdf490d94a7 172 \code
marcelobarrosalmeida 1:acdf490d94a7 173 PT_THREAD(seconds(struct pt *p)) {
marcelobarrosalmeida 1:acdf490d94a7 174 PT_BEGIN(p);
marcelobarrosalmeida 1:acdf490d94a7 175
marcelobarrosalmeida 1:acdf490d94a7 176 PT_WAIT_UNTIL(p, time >= 2 * SECOND);
marcelobarrosalmeida 1:acdf490d94a7 177 printf("Two seconds have passed\n");
marcelobarrosalmeida 1:acdf490d94a7 178
marcelobarrosalmeida 1:acdf490d94a7 179 PT_END(p);
marcelobarrosalmeida 1:acdf490d94a7 180 }
marcelobarrosalmeida 1:acdf490d94a7 181 \endcode
marcelobarrosalmeida 1:acdf490d94a7 182 *
marcelobarrosalmeida 1:acdf490d94a7 183 * \hideinitializer
marcelobarrosalmeida 1:acdf490d94a7 184 */
marcelobarrosalmeida 1:acdf490d94a7 185 #define PT_WAIT_UNTIL(pt, condition) \
marcelobarrosalmeida 1:acdf490d94a7 186 do { \
marcelobarrosalmeida 1:acdf490d94a7 187 LC_SET((pt)->lc); \
marcelobarrosalmeida 1:acdf490d94a7 188 if(sizeof(*(pt))==sizeof(struct ptx)) \
marcelobarrosalmeida 1:acdf490d94a7 189 { \
marcelobarrosalmeida 1:acdf490d94a7 190 if(((struct ptx*)(pt))->flags&PT_F_KILL) \
marcelobarrosalmeida 1:acdf490d94a7 191 { \
marcelobarrosalmeida 1:acdf490d94a7 192 PT_INIT(pt); \
marcelobarrosalmeida 1:acdf490d94a7 193 return PT_THREAD_EXITED; \
marcelobarrosalmeida 1:acdf490d94a7 194 } \
marcelobarrosalmeida 1:acdf490d94a7 195 if(condition) \
marcelobarrosalmeida 1:acdf490d94a7 196 ((struct ptx*)(pt))->flags&=PT_F_WAITING; \
marcelobarrosalmeida 1:acdf490d94a7 197 else \
marcelobarrosalmeida 1:acdf490d94a7 198 ((struct ptx*)(pt))->flags|=PT_F_WAITING; \
marcelobarrosalmeida 1:acdf490d94a7 199 if(((struct ptx*)(pt))->flags&PT_F_WAITING) { \
marcelobarrosalmeida 1:acdf490d94a7 200 return PT_THREAD_WAITING; \
marcelobarrosalmeida 1:acdf490d94a7 201 } \
marcelobarrosalmeida 1:acdf490d94a7 202 }else{ \
marcelobarrosalmeida 1:acdf490d94a7 203 if(!(condition)) { \
marcelobarrosalmeida 1:acdf490d94a7 204 return PT_THREAD_WAITING; \
marcelobarrosalmeida 1:acdf490d94a7 205 } \
marcelobarrosalmeida 1:acdf490d94a7 206 } \
marcelobarrosalmeida 1:acdf490d94a7 207 } while(0)
marcelobarrosalmeida 1:acdf490d94a7 208
marcelobarrosalmeida 1:acdf490d94a7 209 /**
marcelobarrosalmeida 1:acdf490d94a7 210 * Block and wait while condition is true.
marcelobarrosalmeida 1:acdf490d94a7 211 *
marcelobarrosalmeida 1:acdf490d94a7 212 * This function blocks and waits while condition is true. See
marcelobarrosalmeida 1:acdf490d94a7 213 * PT_WAIT_UNTIL().
marcelobarrosalmeida 1:acdf490d94a7 214 *
marcelobarrosalmeida 1:acdf490d94a7 215 * \param pt A pointer to the protothread control structure.
marcelobarrosalmeida 1:acdf490d94a7 216 * \param cond The condition.
marcelobarrosalmeida 1:acdf490d94a7 217 *
marcelobarrosalmeida 1:acdf490d94a7 218 * \hideinitializer
marcelobarrosalmeida 1:acdf490d94a7 219 */
marcelobarrosalmeida 1:acdf490d94a7 220 #define PT_WAIT_WHILE(pt, cond) PT_WAIT_UNTIL((pt), !(cond))
marcelobarrosalmeida 1:acdf490d94a7 221
marcelobarrosalmeida 1:acdf490d94a7 222
marcelobarrosalmeida 1:acdf490d94a7 223 /**
marcelobarrosalmeida 1:acdf490d94a7 224 * Block and wait until a child protothread completes.
marcelobarrosalmeida 1:acdf490d94a7 225 *
marcelobarrosalmeida 1:acdf490d94a7 226 * This macro schedules a child protothread. The current protothread
marcelobarrosalmeida 1:acdf490d94a7 227 * will block until the child protothread completes.
marcelobarrosalmeida 1:acdf490d94a7 228 *
marcelobarrosalmeida 1:acdf490d94a7 229 * \note The child protothread must be manually initialized with the
marcelobarrosalmeida 1:acdf490d94a7 230 * PT_INIT() function before this function is used.
marcelobarrosalmeida 1:acdf490d94a7 231 *
marcelobarrosalmeida 1:acdf490d94a7 232 * \param pt A pointer to the protothread control structure.
marcelobarrosalmeida 1:acdf490d94a7 233 * \param thread The child protothread with arguments
marcelobarrosalmeida 1:acdf490d94a7 234 *
marcelobarrosalmeida 1:acdf490d94a7 235 * Example:
marcelobarrosalmeida 1:acdf490d94a7 236 \code
marcelobarrosalmeida 1:acdf490d94a7 237 PT_THREAD(child(struct pt *p, int event)) {
marcelobarrosalmeida 1:acdf490d94a7 238 PT_BEGIN(p);
marcelobarrosalmeida 1:acdf490d94a7 239
marcelobarrosalmeida 1:acdf490d94a7 240 PT_WAIT_UNTIL(p, event == EVENT1);
marcelobarrosalmeida 1:acdf490d94a7 241
marcelobarrosalmeida 1:acdf490d94a7 242 PT_END(p);
marcelobarrosalmeida 1:acdf490d94a7 243 }
marcelobarrosalmeida 1:acdf490d94a7 244
marcelobarrosalmeida 1:acdf490d94a7 245 PT_THREAD(parent(struct pt *p, struct pt *child_pt, int event)) {
marcelobarrosalmeida 1:acdf490d94a7 246 PT_BEGIN(p);
marcelobarrosalmeida 1:acdf490d94a7 247
marcelobarrosalmeida 1:acdf490d94a7 248 PT_INIT(child_pt);
marcelobarrosalmeida 1:acdf490d94a7 249
marcelobarrosalmeida 1:acdf490d94a7 250 PT_WAIT_THREAD(p, child(child_pt, event));
marcelobarrosalmeida 1:acdf490d94a7 251
marcelobarrosalmeida 1:acdf490d94a7 252 PT_END(p);
marcelobarrosalmeida 1:acdf490d94a7 253 }
marcelobarrosalmeida 1:acdf490d94a7 254 \endcode
marcelobarrosalmeida 1:acdf490d94a7 255 *
marcelobarrosalmeida 1:acdf490d94a7 256 * \sa PT_SPAWN()
marcelobarrosalmeida 1:acdf490d94a7 257 *
marcelobarrosalmeida 1:acdf490d94a7 258 * \hideinitializer
marcelobarrosalmeida 1:acdf490d94a7 259 */
marcelobarrosalmeida 1:acdf490d94a7 260 #define PT_WAIT_THREAD(pt, thread) PT_WAIT_WHILE((pt), PT_SCHEDULE(thread))
marcelobarrosalmeida 1:acdf490d94a7 261
marcelobarrosalmeida 1:acdf490d94a7 262 /**
marcelobarrosalmeida 1:acdf490d94a7 263 * Spawn a child protothread and wait until it exits.
marcelobarrosalmeida 1:acdf490d94a7 264 *
marcelobarrosalmeida 1:acdf490d94a7 265 * This macro spawns a child protothread and waits until it exits. The
marcelobarrosalmeida 1:acdf490d94a7 266 * macro can only be used within a protothread.
marcelobarrosalmeida 1:acdf490d94a7 267 *
marcelobarrosalmeida 1:acdf490d94a7 268 * Example:
marcelobarrosalmeida 1:acdf490d94a7 269 \code
marcelobarrosalmeida 1:acdf490d94a7 270 static struct pt parent_pt, child_pt;
marcelobarrosalmeida 1:acdf490d94a7 271 int should_spawn_flag;
marcelobarrosalmeida 1:acdf490d94a7 272
marcelobarrosalmeida 1:acdf490d94a7 273 PT_THREAD(child(struct pt *pt)) {
marcelobarrosalmeida 1:acdf490d94a7 274 PT_BEGIN(pt);
marcelobarrosalmeida 1:acdf490d94a7 275
marcelobarrosalmeida 1:acdf490d94a7 276 while(all_items_processed()) {
marcelobarrosalmeida 1:acdf490d94a7 277 process_item();
marcelobarrosalmeida 1:acdf490d94a7 278 PT_WAIT_UNTIL(pt, item_processed());
marcelobarrosalmeida 1:acdf490d94a7 279 }
marcelobarrosalmeida 1:acdf490d94a7 280
marcelobarrosalmeida 1:acdf490d94a7 281 PT_END(pt);
marcelobarrosalmeida 1:acdf490d94a7 282 }
marcelobarrosalmeida 1:acdf490d94a7 283
marcelobarrosalmeida 1:acdf490d94a7 284 PT_THREAD(parent(void)) {
marcelobarrosalmeida 1:acdf490d94a7 285 PT_BEGIN(&parent_pt);
marcelobarrosalmeida 1:acdf490d94a7 286
marcelobarrosalmeida 1:acdf490d94a7 287 if(should_spawn_flag) {
marcelobarrosalmeida 1:acdf490d94a7 288 PT_SPAWN(&parent_pt, &child_pt, child(&child_pt));
marcelobarrosalmeida 1:acdf490d94a7 289 }
marcelobarrosalmeida 1:acdf490d94a7 290
marcelobarrosalmeida 1:acdf490d94a7 291 PT_END(&parent_pt);
marcelobarrosalmeida 1:acdf490d94a7 292 }
marcelobarrosalmeida 1:acdf490d94a7 293 \endcode
marcelobarrosalmeida 1:acdf490d94a7 294 *
marcelobarrosalmeida 1:acdf490d94a7 295 *
marcelobarrosalmeida 1:acdf490d94a7 296 * \param pt A pointer to the protothread control structure.
marcelobarrosalmeida 1:acdf490d94a7 297 * \param child A pointer to the child protothread's control structure.
marcelobarrosalmeida 1:acdf490d94a7 298 * \param thread The child protothread with arguments
marcelobarrosalmeida 1:acdf490d94a7 299 *
marcelobarrosalmeida 1:acdf490d94a7 300 * \hideinitializer
marcelobarrosalmeida 1:acdf490d94a7 301 */
marcelobarrosalmeida 1:acdf490d94a7 302 #define PT_SPAWN(pt, child, thread) \
marcelobarrosalmeida 1:acdf490d94a7 303 do { \
marcelobarrosalmeida 1:acdf490d94a7 304 PT_INIT((child)); \
marcelobarrosalmeida 1:acdf490d94a7 305 PT_WAIT_THREAD((pt), (thread)); \
marcelobarrosalmeida 1:acdf490d94a7 306 } while(0)
marcelobarrosalmeida 1:acdf490d94a7 307
marcelobarrosalmeida 1:acdf490d94a7 308 /**
marcelobarrosalmeida 1:acdf490d94a7 309 * Restart the protothread.
marcelobarrosalmeida 1:acdf490d94a7 310 *
marcelobarrosalmeida 1:acdf490d94a7 311 * This macro will block and cause the running protothread to restart
marcelobarrosalmeida 1:acdf490d94a7 312 * its execution at the place of the PT_BEGIN() call.
marcelobarrosalmeida 1:acdf490d94a7 313 *
marcelobarrosalmeida 1:acdf490d94a7 314 * \param pt A pointer to the protothread control structure.
marcelobarrosalmeida 1:acdf490d94a7 315 *
marcelobarrosalmeida 1:acdf490d94a7 316 * \hideinitializer
marcelobarrosalmeida 1:acdf490d94a7 317 */
marcelobarrosalmeida 1:acdf490d94a7 318 #define PT_RESTART(pt) \
marcelobarrosalmeida 1:acdf490d94a7 319 do { \
marcelobarrosalmeida 1:acdf490d94a7 320 PT_INIT(pt); \
marcelobarrosalmeida 1:acdf490d94a7 321 return PT_THREAD_WAITING; \
marcelobarrosalmeida 1:acdf490d94a7 322 } while(0)
marcelobarrosalmeida 1:acdf490d94a7 323
marcelobarrosalmeida 1:acdf490d94a7 324 /**
marcelobarrosalmeida 1:acdf490d94a7 325 * Exit the protothread.
marcelobarrosalmeida 1:acdf490d94a7 326 *
marcelobarrosalmeida 1:acdf490d94a7 327 * This macro causes the protothread to exit. If the protothread was
marcelobarrosalmeida 1:acdf490d94a7 328 * spawned by another protothread, the parent protothread will become
marcelobarrosalmeida 1:acdf490d94a7 329 * unblocked and can continue to run.
marcelobarrosalmeida 1:acdf490d94a7 330 *
marcelobarrosalmeida 1:acdf490d94a7 331 * \param pt A pointer to the protothread control structure.
marcelobarrosalmeida 1:acdf490d94a7 332 *
marcelobarrosalmeida 1:acdf490d94a7 333 * \hideinitializer
marcelobarrosalmeida 1:acdf490d94a7 334 */
marcelobarrosalmeida 1:acdf490d94a7 335 #define PT_EXIT(pt) \
marcelobarrosalmeida 1:acdf490d94a7 336 do { \
marcelobarrosalmeida 1:acdf490d94a7 337 PT_INIT(pt); \
marcelobarrosalmeida 1:acdf490d94a7 338 return PT_THREAD_EXITED; \
marcelobarrosalmeida 1:acdf490d94a7 339 } while(0)
marcelobarrosalmeida 1:acdf490d94a7 340
marcelobarrosalmeida 1:acdf490d94a7 341 /**
marcelobarrosalmeida 1:acdf490d94a7 342 * Declare the end of a protothread.
marcelobarrosalmeida 1:acdf490d94a7 343 *
marcelobarrosalmeida 1:acdf490d94a7 344 * This macro is used for declaring that a protothread ends. It should
marcelobarrosalmeida 1:acdf490d94a7 345 * always be used together with a matching PT_BEGIN() macro.
marcelobarrosalmeida 1:acdf490d94a7 346 *
marcelobarrosalmeida 1:acdf490d94a7 347 * \param pt A pointer to the protothread control structure.
marcelobarrosalmeida 1:acdf490d94a7 348 *
marcelobarrosalmeida 1:acdf490d94a7 349 * \hideinitializer
marcelobarrosalmeida 1:acdf490d94a7 350 */
marcelobarrosalmeida 1:acdf490d94a7 351 #define PT_END(pt) LC_END((pt)->lc); PT_EXIT(pt)
marcelobarrosalmeida 1:acdf490d94a7 352
marcelobarrosalmeida 1:acdf490d94a7 353
marcelobarrosalmeida 1:acdf490d94a7 354 /**
marcelobarrosalmeida 1:acdf490d94a7 355 * Schedule a protothread.
marcelobarrosalmeida 1:acdf490d94a7 356 *
marcelobarrosalmeida 1:acdf490d94a7 357 * This function shedules a protothread. The return value of the
marcelobarrosalmeida 1:acdf490d94a7 358 * function is non-zero if the protothread is running or zero if the
marcelobarrosalmeida 1:acdf490d94a7 359 * protothread has exited.
marcelobarrosalmeida 1:acdf490d94a7 360 *
marcelobarrosalmeida 1:acdf490d94a7 361 * Example
marcelobarrosalmeida 1:acdf490d94a7 362 \code
marcelobarrosalmeida 1:acdf490d94a7 363 void main(void) {
marcelobarrosalmeida 1:acdf490d94a7 364 struct pt p;
marcelobarrosalmeida 1:acdf490d94a7 365 int event;
marcelobarrosalmeida 1:acdf490d94a7 366
marcelobarrosalmeida 1:acdf490d94a7 367 PT_INIT(&p);
marcelobarrosalmeida 1:acdf490d94a7 368 while(PT_SCHEDULE(consumer(&p, event))) {
marcelobarrosalmeida 1:acdf490d94a7 369 event = get_event();
marcelobarrosalmeida 1:acdf490d94a7 370 }
marcelobarrosalmeida 1:acdf490d94a7 371 }
marcelobarrosalmeida 1:acdf490d94a7 372 \endcode
marcelobarrosalmeida 1:acdf490d94a7 373 *
marcelobarrosalmeida 1:acdf490d94a7 374 * \param f The call to the C function implementing the protothread to
marcelobarrosalmeida 1:acdf490d94a7 375 * be scheduled
marcelobarrosalmeida 1:acdf490d94a7 376 *
marcelobarrosalmeida 1:acdf490d94a7 377 * \hideinitializer
marcelobarrosalmeida 1:acdf490d94a7 378 */
marcelobarrosalmeida 1:acdf490d94a7 379 #define PT_SCHEDULE(f) (f == PT_THREAD_WAITING)
marcelobarrosalmeida 1:acdf490d94a7 380
marcelobarrosalmeida 1:acdf490d94a7 381 /**
marcelobarrosalmeida 1:acdf490d94a7 382 * Declarare that a protothread can yield.
marcelobarrosalmeida 1:acdf490d94a7 383 *
marcelobarrosalmeida 1:acdf490d94a7 384 * If a protothread should be able to yield with the PT_YIELD()
marcelobarrosalmeida 1:acdf490d94a7 385 * statement, this flag must be placed first in the protothread's
marcelobarrosalmeida 1:acdf490d94a7 386 * function body.
marcelobarrosalmeida 1:acdf490d94a7 387 *
marcelobarrosalmeida 1:acdf490d94a7 388 * Example:
marcelobarrosalmeida 1:acdf490d94a7 389 \code
marcelobarrosalmeida 1:acdf490d94a7 390 static
marcelobarrosalmeida 1:acdf490d94a7 391 PT_THREAD(loop_thread(struct pt *pt))
marcelobarrosalmeida 1:acdf490d94a7 392 {
marcelobarrosalmeida 1:acdf490d94a7 393 PT_YIELDING();
marcelobarrosalmeida 1:acdf490d94a7 394 static int i;
marcelobarrosalmeida 1:acdf490d94a7 395
marcelobarrosalmeida 1:acdf490d94a7 396 PT_BEGIN(pt);
marcelobarrosalmeida 1:acdf490d94a7 397
marcelobarrosalmeida 1:acdf490d94a7 398 for(i = 0; i < 200; ++i) {
marcelobarrosalmeida 1:acdf490d94a7 399 handle_item(i);
marcelobarrosalmeida 1:acdf490d94a7 400 PT_YIELD(pt);
marcelobarrosalmeida 1:acdf490d94a7 401 }
marcelobarrosalmeida 1:acdf490d94a7 402
marcelobarrosalmeida 1:acdf490d94a7 403 PT_END(pt);
marcelobarrosalmeida 1:acdf490d94a7 404 }
marcelobarrosalmeida 1:acdf490d94a7 405 \endcode
marcelobarrosalmeida 1:acdf490d94a7 406 *
marcelobarrosalmeida 1:acdf490d94a7 407 * \hideinitializer
marcelobarrosalmeida 1:acdf490d94a7 408 */
marcelobarrosalmeida 1:acdf490d94a7 409 #define PT_YIELDING() char pt_yielded = 1
marcelobarrosalmeida 1:acdf490d94a7 410
marcelobarrosalmeida 1:acdf490d94a7 411 /**
marcelobarrosalmeida 1:acdf490d94a7 412 * Yield from the current protothread.
marcelobarrosalmeida 1:acdf490d94a7 413 *
marcelobarrosalmeida 1:acdf490d94a7 414 * This function will yield the protothread, thereby allowing other
marcelobarrosalmeida 1:acdf490d94a7 415 * processing to take place in the system.
marcelobarrosalmeida 1:acdf490d94a7 416 *
marcelobarrosalmeida 1:acdf490d94a7 417 * \note The PT_YIELDING() flag must be placed first in the
marcelobarrosalmeida 1:acdf490d94a7 418 * protothread's body if the PT_YIELD() function should be used.
marcelobarrosalmeida 1:acdf490d94a7 419 *
marcelobarrosalmeida 1:acdf490d94a7 420 * Example
marcelobarrosalmeida 1:acdf490d94a7 421 \code
marcelobarrosalmeida 1:acdf490d94a7 422 static
marcelobarrosalmeida 1:acdf490d94a7 423 PT_THREAD(fade(struct pt *pt))
marcelobarrosalmeida 1:acdf490d94a7 424 {
marcelobarrosalmeida 1:acdf490d94a7 425 PT_YIELDING();
marcelobarrosalmeida 1:acdf490d94a7 426 static int delay;
marcelobarrosalmeida 1:acdf490d94a7 427
marcelobarrosalmeida 1:acdf490d94a7 428 PT_BEGIN(pt);
marcelobarrosalmeida 1:acdf490d94a7 429
marcelobarrosalmeida 1:acdf490d94a7 430 for(delay = 3980; delay > 20; delay -= 20) {
marcelobarrosalmeida 1:acdf490d94a7 431 leds_red(LEDS_ON);
marcelobarrosalmeida 1:acdf490d94a7 432 clock_delay(4000 - delay);
marcelobarrosalmeida 1:acdf490d94a7 433 leds_red(LEDS_OFF);
marcelobarrosalmeida 1:acdf490d94a7 434 clock_delay(delay);
marcelobarrosalmeida 1:acdf490d94a7 435 PT_YIELD(pt);
marcelobarrosalmeida 1:acdf490d94a7 436 }
marcelobarrosalmeida 1:acdf490d94a7 437
marcelobarrosalmeida 1:acdf490d94a7 438 PT_END(pt);
marcelobarrosalmeida 1:acdf490d94a7 439 }
marcelobarrosalmeida 1:acdf490d94a7 440 \endcode
marcelobarrosalmeida 1:acdf490d94a7 441 * \param pt A pointer to the protothread control structure.
marcelobarrosalmeida 1:acdf490d94a7 442 *
marcelobarrosalmeida 1:acdf490d94a7 443 * \hideinitializer
marcelobarrosalmeida 1:acdf490d94a7 444 */
marcelobarrosalmeida 1:acdf490d94a7 445 #define PT_YIELD(pt) \
marcelobarrosalmeida 1:acdf490d94a7 446 do { \
marcelobarrosalmeida 1:acdf490d94a7 447 pt_yielded = 0; \
marcelobarrosalmeida 1:acdf490d94a7 448 PT_WAIT_UNTIL(pt, pt_yielded); \
marcelobarrosalmeida 1:acdf490d94a7 449 } while(0)
marcelobarrosalmeida 1:acdf490d94a7 450
marcelobarrosalmeida 1:acdf490d94a7 451 /*
marcelobarrosalmeida 1:acdf490d94a7 452 * Extended Protothread API.
marcelobarrosalmeida 1:acdf490d94a7 453 * The following functions require a struct ptx, rather than a plan struct pt.
marcelobarrosalmeida 1:acdf490d94a7 454 */
marcelobarrosalmeida 1:acdf490d94a7 455
marcelobarrosalmeida 1:acdf490d94a7 456 /**
marcelobarrosalmeida 1:acdf490d94a7 457 * Put a protothread to sleep.
marcelobarrosalmeida 1:acdf490d94a7 458 * Execution of the thread won't continue until another thread explicitly wakes the thread
marcelobarrosalmeida 1:acdf490d94a7 459 * with PT_WAKE().
marcelobarrosalmeida 1:acdf490d94a7 460 * Requires a ptx.
marcelobarrosalmeida 1:acdf490d94a7 461 */
marcelobarrosalmeida 1:acdf490d94a7 462 #define PT_SLEEP(ptx) \
marcelobarrosalmeida 1:acdf490d94a7 463 do { \
marcelobarrosalmeida 1:acdf490d94a7 464 ptx->flags|=PT_F_SLEEPING; \
marcelobarrosalmeida 1:acdf490d94a7 465 PT_WAIT_UNTIL(ptx, (((ptx)->flags&PT_F_SLEEPING)==0)); \
marcelobarrosalmeida 1:acdf490d94a7 466 } while(0)
marcelobarrosalmeida 1:acdf490d94a7 467
marcelobarrosalmeida 1:acdf490d94a7 468 /**
marcelobarrosalmeida 1:acdf490d94a7 469 * Wake a protothread.
marcelobarrosalmeida 1:acdf490d94a7 470 * Wake up a protothread if it is sleeping (ie. has called PT_SLEEP()) - if the thread isn't sleeping,
marcelobarrosalmeida 1:acdf490d94a7 471 * then it has no effect.
marcelobarrosalmeida 1:acdf490d94a7 472 * NOTE: Requires a ptx.
marcelobarrosalmeida 1:acdf490d94a7 473 */
marcelobarrosalmeida 1:acdf490d94a7 474 #define PT_WAKE(ptx) (ptx)->flags&=~PT_F_SLEEPING
marcelobarrosalmeida 1:acdf490d94a7 475
marcelobarrosalmeida 1:acdf490d94a7 476 /**
marcelobarrosalmeida 1:acdf490d94a7 477 * Kill a protothread.
marcelobarrosalmeida 1:acdf490d94a7 478 * The thread is marked with the kill flag and will exit next time the thread sleeps/waits/yields.
marcelobarrosalmeida 1:acdf490d94a7 479 * NOTE: Requires a ptx.
marcelobarrosalmeida 1:acdf490d94a7 480 */
marcelobarrosalmeida 1:acdf490d94a7 481 #define PT_KILL(ptx) (ptx)->flags&=~PT_F_KILL
marcelobarrosalmeida 1:acdf490d94a7 482
marcelobarrosalmeida 1:acdf490d94a7 483 /**
marcelobarrosalmeida 1:acdf490d94a7 484 * Is a protothread blocked?
marcelobarrosalmeida 1:acdf490d94a7 485 * Returns non-zero is the thread is waiting.
marcelobarrosalmeida 1:acdf490d94a7 486 * NOTE: Requires a ptx.
marcelobarrosalmeida 1:acdf490d94a7 487 */
marcelobarrosalmeida 1:acdf490d94a7 488 #define PT_ISBLOCKED(ptx) ((ptx)->flags&PT_F_WAITING)
marcelobarrosalmeida 1:acdf490d94a7 489
marcelobarrosalmeida 1:acdf490d94a7 490 #endif /* __PT_H__ */
marcelobarrosalmeida 1:acdf490d94a7 491
marcelobarrosalmeida 1:acdf490d94a7 492
marcelobarrosalmeida 1:acdf490d94a7 493 /** @} */