/*
 * tthread.h 
 *
 * Tiny Multitasking Threads for Small Microcontrollers
 * - Idea based on http://www.chiark.greenend.org.uk/~sgtatham/coroutines.html.
 * - Only 1 byte RAM needed per thread.
 * - Very small overhead context switching.
 * 
 * Limitations:
 * - Maximum 254 lines per thread.
 * - Thread context switching will not work within a switch block.
 * 
 * Usage example:
 * 
 * TT_DEF(1)
 * {
 *    TT_BEGIN(1);
 * 	  while (1)
 *    {
 *       ...
 *       TT_SWITCH(1);
 *       ...
 *       ...
 *       TT_WAIT_UNTIL(1,keypress);
 *    }
 *    TT_END(1);
 * }
 * 
 * TT_DEF(LED_TASK)
 * {
 *     TT_BEGIN(LED_TASK);
 *     while (1)
 *     {
 *         LedOn();
 *         delay=DELAY_1_SECOND;
 *         TT_WAIT_UNTIL(LED_TASK,delay==0);
 *         LedOff();
 *         delay=DELAY_1_SECOND;
 *         TT_WAIT_UNTIL(LED_TASK,delay==0);
 *     }
 *     TT_END(LED_TASK);
 * }
 *  
 * void main(void) 
 * {
 *     ...
 *     ...
 *     while(1)
 *     {
 *         TT_SCHED(1);
 *         TT_SCHED(LED_TASK);
 *     }
 * }
 * 
 */

/*
 * tthread.h
 *
 * Tiny Multitasking Threads for Small Microcontrollers
 * Copyright (c) 2006, Regulus Berdin
 * All rights reserved. 
 * 
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following
 * conditions:
 * 
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT.  IN NO EVENT SHALL REGULUS BERDIN BE LIABLE FOR
 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
*/
 
 
#ifndef _TINY_THREAD_H_
#define _TINY_THREAD_H_

#define TT_DEF(fn) 				\
unsigned char tt_var_##fn=0; 	\
void tt_##fn(void)

#define TT_BEGIN(fn)			\
	switch (tt_var_##fn)	 {	\
		case 0:					\
			do {} while(0)

#define TT_END(fn)  } 			\
	tt_var_##fn = 0xFF
		
#define TT_KILL(fn)	\
	tt_var_##fn = 0xFF 

#define TT_INIT(fn)	\
	tt_var_##fn = 0 

#define TT_WAIT_WHILE(fn, condition) 								\
	tt_var_##fn = ((__LINE__ % 254)+1); case ((__LINE__ % 254)+1):	\
	if ((condition)) return

#define TT_WAIT_UNTIL(fn, condition) 								\
	tt_var_##fn = ((__LINE__ % 254)+1); case ((__LINE__ % 254)+1):	\
	if (!(condition)) return

#define TT_SCHED(fn) \
	if (tt_var_##fn!=0xFF) tt_##fn()

#define TT_SWITCH(fn) \
	tt_var_##fn = ((__LINE__ % 254)+1); return; case ((__LINE__ % 254)+1): \
	do {} while(0)
	
#define TT_IS_RUNNING(fn) (tt_var_##fn != 0xFF)

#endif


