// 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.
//
// test1 
// A CTL application that creates two tasks that wait on an event flag whilst the main task loops.
// This application illustrates the use of an event to share access to a resource.
// Given that all applications are running at the same priority this implements a binary semaphore.

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

CTL_TASK_t mainTask,other1Task,other2Task;
int othercount;

#define CALLSTACKSIZE 16 // this is only required for AVR builds
#define STACKSIZE 64
unsigned other1Stack[1+STACKSIZE+1], other2Stack[1+STACKSIZE+1]; // allocate 1 word before and after to aid debugging stack space problems
unsigned e1=1; // initialised to 1 so that one of the tasks will succesfully wait

void 
other(void *p)
{
  unsigned v=0;
  while (1)
    {
      v++;
      ctl_events_wait(CTL_EVENT_WAIT_ANY_EVENTS_WITH_AUTO_CLEAR, &e1, 1, 0, 0); // by auto_clearing the event only one task will be rescheduled
      ctl_timeout_wait(ctl_get_current_time()+ctl_get_ticks_per_second());
      ctl_events_set_clear(&e1, 1, 0);   
    }  
}

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

int
main(void)
{
  int i;
  ctl_board_init();
  ctl_task_init(&mainTask, 255, "main"); 
  ctl_start_timer(ctl_increment_tick_from_isr);
  memset(other1Stack, 0xcd, sizeof(other1Stack));
  memset(other2Stack, 0xcd, sizeof(other2Stack));
  other1Stack[0]=other1Stack[1+STACKSIZE]=other2Stack[0]=other2Stack[1+STACKSIZE]=0xfacefeed;
  ctl_task_run(&other1Task, 1, other, 0, "other1", STACKSIZE, other1Stack+1, CALLSTACKSIZE);
  ctl_task_run(&other2Task, 1, other, 0, "other2", STACKSIZE, other2Stack+1, CALLSTACKSIZE);
  ctl_task_set_priority(&mainTask, 0);
  while (1)
    {
      ;
    }
}
