|
|
|
/* based on example-small.c in the protothreads tarball */
|
|
|
|
|
|
|
|
#include "avr/io.h"
|
|
|
|
#include "util/delay.h"
|
|
|
|
|
|
|
|
#include "pt.h"
|
|
|
|
#include "clock.h"
|
|
|
|
#include "timer.h"
|
|
|
|
|
|
|
|
/* TIMER_DELAY macro for convenience */
|
|
|
|
#define TIMER_DELAY(pt, timer, t) \
|
|
|
|
do { \
|
|
|
|
timer_set(&timer, t); \
|
|
|
|
PT_WAIT_UNTIL(pt, timer_expired(&timer)); \
|
|
|
|
} while(0);
|
|
|
|
|
|
|
|
/* Two timers for the two protothreads. */
|
|
|
|
static struct timer timer1, timer2;
|
|
|
|
|
|
|
|
static int
|
|
|
|
protothread1(struct pt *pt)
|
|
|
|
{
|
|
|
|
/* A protothread function must begin with PT_BEGIN() which takes a
|
|
|
|
pointer to a struct pt. */
|
|
|
|
PT_BEGIN(pt);
|
|
|
|
|
|
|
|
/* We loop forever here. */
|
|
|
|
while(1) {
|
|
|
|
PORTB |= _BV(PB3);
|
|
|
|
TIMER_DELAY(pt, timer1, 20);
|
|
|
|
PORTB &= ~_BV(PB3);
|
|
|
|
TIMER_DELAY(pt, timer1, 20);
|
|
|
|
|
|
|
|
/* And we loop. */
|
|
|
|
}
|
|
|
|
|
|
|
|
/* All protothread functions must end with PT_END() which takes a
|
|
|
|
pointer to a struct pt. */
|
|
|
|
PT_END(pt);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
protothread2(struct pt *pt)
|
|
|
|
{
|
|
|
|
/* A protothread function must begin with PT_BEGIN() which takes a
|
|
|
|
pointer to a struct pt. */
|
|
|
|
PT_BEGIN(pt);
|
|
|
|
|
|
|
|
/* We loop forever here. */
|
|
|
|
while(1) {
|
|
|
|
PORTB |= _BV(PB2);
|
|
|
|
TIMER_DELAY(pt, timer2, 60);
|
|
|
|
PORTB &= ~_BV(PB2);
|
|
|
|
TIMER_DELAY(pt, timer2, 60);
|
|
|
|
|
|
|
|
/* And we loop. */
|
|
|
|
}
|
|
|
|
|
|
|
|
/* All protothread functions must end with PT_END() which takes a
|
|
|
|
pointer to a struct pt. */
|
|
|
|
PT_END(pt);
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct pt pt1, pt2;
|
|
|
|
|
|
|
|
int main(void) {
|
|
|
|
// pin 11 = PB3
|
|
|
|
DDRB |= _BV(PB3);
|
|
|
|
// pin 10 = PB2
|
|
|
|
DDRB |= _BV(PB2);
|
|
|
|
|
|
|
|
/* Initialize clock */
|
|
|
|
clock_init();
|
|
|
|
|
|
|
|
/* Initialize the protothread state variables with PT_INIT(). */
|
|
|
|
PT_INIT(&pt1);
|
|
|
|
PT_INIT(&pt2);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Then we schedule the two protothreads by repeatedly calling their
|
|
|
|
* protothread functions and passing a pointer to the protothread
|
|
|
|
* state variables as arguments.
|
|
|
|
*/
|
|
|
|
while(1) {
|
|
|
|
protothread1(&pt1);
|
|
|
|
protothread2(&pt2);
|
|
|
|
}
|
|
|
|
}
|