An event set is a means to synchronise tasks with other tasks and interrupt service routines. An event set contains a set of events (one per bit) which tasks can wait to become set (value 1). When a task waits on an event set the events it is waiting for are matched against the current values - if they match then the task can still execute. If they don't match then the task is put on the task list together with details of the event set and the events that the task is waiting for.

An event set is defined as follows

    typedef unsigned CTL_EVENT_SET_t;

i.e. on an 8/16 bit machine an event set will contain 16 events and on a 32 bit machine an event set will contain 32 events.

You can set and clear events of an event set using the ctl_set_clear_events function.

    void
    ctl_set_clear_events(CTL_EVENT_SET_t *eventSet,
                         CTL_EVENT_SET_t set,
                         CTL_EVENT_SET_t clear);

This will set the events defined in set, clear the events defined in clear of the event set at *eventSet. This function will then search the task list, matching tasks that are waiting on the *eventSet and make them runnable if the match is successful.

You can wait for a timeout and/or an event set using the ctl_task_wait function.

    unsigned
    ctl_task_wait(unsigned waitType,
                  CTL_TIME_t timeout,
                  CTL_EVENT_SET_t *eventSet,
                  CTL_EVENT_SET_t events);

The waitType can be one of the following.

- CTL_STATE_TIMER_WAIT - wait for timeout.
- CTL_STATE_EVENT_WAIT - wait for the eventsin *eventSet to match.
- CTL_STATE_TIMER_WAIT | CTL_STATE_EVENT_WAIT - wait for timeout or the events in *eventSet to match.
- 0 which causes a co-operative task switch.

If you specify an event wait you can also use the following modifiers

- CTL_STATE_EVENT_ANY_NOT_ALL - wait for any of the events in *eventSet to be set. The default is to wait for all of the events in *eventSet to be set.
- CTL_STATE_EVENT_AUTO_CLEAR - clear the events in *eventSet when the match has been successful.

The ctl_task_wait function returns the *eventSet value before any auto clearing occurred or zero if the timeout occurred or a co-operative task switch was requested.

#### Example Task Synchronisation

The following example illustrates synchronising a task with a function called from an ISR.

    EventSet e1;
    Task t1;

    void ISRfn()
    {
      // do work
      ctl_set_clear_events(&e1, 1, 0);
    }
    void task1(void *p)
    {
      while (1)
        {
          ctl_task_wait(TaskStateEventWait, 0, &e1, 1);
          ...
          ctl_set_clear_events(&e1, 0, 1);
        }
    }

#### Example Task Synchronisation

The following example illustrates synchronising a task with functions called from two ISR's.

    EventSet e1;
    Task t1;

    void ISRfn1()
    {
      // do work
      ctl_set_clear_events(&e1, 1, 0);
    }
    void ISRfn2()
    {
      // do work
      ctl_set_clear_events(&e1, 2, 0);
    }
    void task1(void *p)
    {
      while (1)
        {
          unsigned e;
          e=ctl_task_wait(CTL_STATE_EVENT_WAIT | CTL_STATE_EVENT_ANY_NOT_ALL | CTL_STATE_EVENT_AUTO_CLEAR, 0, &e1, 1|2);
          if (e & 1)
            ; // ISRfn1 completed
          else if (e & 2)
            ; // ISRfn2 completed
          else
            ; // error
        }
    }

#### Example Resource Serialisation

The following example illustrates resource serialisation of two tasks.

    CTL_EVENT_SET_t e1=1;
    void task1()
    {
      while (1)
        {
          ctl_task_wait(CTL_STATE_EVENT_WAIT | CTL_STATE_EVENT_AUTO_CLEAR, 0, &e1, 1);
          // resource has now been acquired
          ctl_set_clear_events(&e1, 1, 0);
          // resource has now been released
        }
    }
    void task2()
    {
      while (1)
        {
          ctl_task_wait(CTL_STATE_EVENT_WAIT | CTL_STATE_EVENT_AUTO_CLEAR, 0, &e1, 1);
          // resource has now been acquired
          ctl_set_clear_events(&e1, 1, 0);
          // resource has now been released
        }
    }

Note that e1 is initialised with the event set - without this neither task would acquire the resource.