// Copyright (c) 2004 Rowley Associates Limited.
//
// This file may be distributed under the terms of the License Agreement
// provided with this software.
//
// THIS FILE IS PROVIDED AS IS WITH NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.

#include <string.h>
#include <ctl_api.h>

void start_timer(void);
long ticks_per_sec(void);

CTL_TASK_t main_task, timer_task, blink_task;
CTL_EVENT_SET_t e1;

#define CALLSTACKSIZE 16 // this is only required for AVR builds
#define STACKSIZE 64          
unsigned timer_stack[1+STACKSIZE+1];
unsigned blink_stack[1+STACKSIZE+1];

void 
timer(void *p)
{  
  unsigned int v=0;
  while (1)
    {      
      ctl_timeout_wait(ctl_get_current_time() + ctl_get_ticks_per_second());  
      ctl_events_set_clear(&e1, 1, 0);
      v++;
    }  
}

void 
blink(void *p)
{  
  unsigned int v=0;
  unsigned led = 0xFFFFFFFF;
  while (1)
    { 
      ctl_events_wait(CTL_EVENT_WAIT_ALL_EVENTS, &e1, 1, 0, 0);     
      ctl_events_set_clear(&e1, 0, 1);  
      ctl_board_set_leds(led);
      led ^= 0xFFFFFFFF;
      v++;   
    }
}

void
ctl_handle_error(CTL_ERROR_CODE_t e)
{
  while (1);
}

int main(void)
{
  ctl_board_init();
  ctl_task_init(&main_task, 255, "main");
  ctl_start_timer(ctl_increment_tick_from_isr);  
  memset(timer_stack, 0xcd, sizeof(timer_stack));
  memset(blink_stack, 0xcd, sizeof(blink_stack));
  timer_stack[0]=timer_stack[1+STACKSIZE]=blink_stack[0]=blink_stack[1+STACKSIZE]=0xfacefeed;
  ctl_task_run(&timer_task, 1, timer, 0, "timer", STACKSIZE, timer_stack+1, CALLSTACKSIZE);
  ctl_task_run(&blink_task, 1, blink, 0, "blink", STACKSIZE, blink_stack+1, CALLSTACKSIZE);
  ctl_task_set_priority(&main_task, 0);
  while (1)
    {
      ;
    }
  return 0;
}
