Application example
Script for Generating Source Code Tables
The following Python script, Widget.py, will generate the declarations and tables for the example in the rest of this section, but the code examples that follow have not been generated using this facility.
import sys
sys.path.append("..\\exec") # for ExecStuff, assuming exec is in this directory
from ExecStuff import *
############# Complete set of definitions for exec, etc. ######################
Definition = {
'Event Queues' : (('BACKGND_QUEUE', 128), ('LOW_QUEUE', 32),
('INTERMED_QUEUE', 32), ('TOP_QUEUE', 8) ),
'State Tables' : (
( 'smSingleTransition',
('SM_SINGLE_STATE', 'STATE1'),
# ========================================================================
(('EV_STATUS_REQUEST', 'BACKGND_QUEUE'),
('STATE1', 0, 'HandleStatusRequest')),
(('EV_SCAN_TRIGGER', 'TOP_QUEUE'), ('STATE1', 0, 'ScanInputs'))
),
( 'smWidgetTransition',
('SM_WIDGET_SEQUENCER', 'WIDGET_IDLE', 'ENTERING_SLOT', 'LEAVING_SLOT',
'ENTERING_TRAY', 'AWAITING_REMOVAL', 'FAULTY'),
# =====================================================================
(('EV_DOOR_READY', 'INTERMED_QUEUE'),
('ENTERING_SLOT', 0, 'DispenseWidget'), # WIDGET_IDLE
('ENTERING_SLOT', 0, None), # ENTERING_SLOT
('LEAVING_SLOT', 0, None), # LEAVING_SLOT
('ENTERING_TRAY', 0, None), # ENTERING_TRAY
('ENTERING_SLOT', 0, 'DispenseWidget'), # AWAITING_REMOVAL
('FAULTY', 0, None)), # FAULTY
(('EV_WIDGET_IN_SLOT', 'INTERMED_QUEUE'),
('FAULTY', 1, 'LogWidgetFault'), # WIDGET_IDLE
('LEAVING_SLOT', 0, None), # ENTERING_SLOT
('LEAVING_SLOT', 0, None), # LEAVING_SLOT
('FAULTY', 3, 'LogWidgetFault'), # ENTERING_TRAY
('FAULTY', 3, 'LogWidgetFault'), # AWAITING_REMOVAL
('FAULTY', 0, None)), # FAULTY
(('EV_SLOT_CLEAR', 'INTERMED_QUEUE'),
('WIDGET_IDLE', 0, None), # WIDGET_IDLE
('ENTERING_SLOT', 0, None), # ENTERING_SLOT
('ENTERING_TRAY', 0, 'HandleWidget'), # LEAVING_SLOT
('ENTERING_TRAY', 0, None), # ENTERING_TRAY
('AWAITING_REMOVAL',0,None), # AWAITING_REMOVAL
('FAULTY', 0, None)), # FAULTY
(('EV_WIDGET_IN_TRAY', 'INTERMED_QUEUE'),
('FAULTY', 2, 'LogWidgetFault'), # WIDGET_IDLE
('FAULTY', 2, 'LogWidgetFault'), # ENTERING_SLOT
('AWAITING_REMOVAL',0,'StopWidget'), # LEAVING_SLOT
('AWAITING_REMOVAL',0,'StopWidget'), # ENTERING_TRAY
('AWAITING_REMOVAL',0,None), # AWAITING_REMOVAL
('FAULTY', 0, None)), # FAULTY
(('EV_TRAY_CLEAR', 'INTERMED_QUEUE'),
('WIDGET_IDLE', 0, None), # WIDGET_IDLE
('ENTERING_SLOT', 0, None), # ENTERING_SLOT
('LEAVING_SLOT', 0, None), # LEAVING_SLOT
('WIDGET_IDLE', 0, 'RecordWidget'), # ENTERING_TRAY
('WIDGET_IDLE', 0, 'RecordWidget' ), # AWAITING_REMOVAL
('FAULTY', 0, None)), # FAULTY
(('EV_WIDGET_TIMEOUT', 'INTERMED_QUEUE'),
('WIDGET_IDLE', 0, None), # WIDGET_IDLE
('FAULTY', 10, 'LogWidgetFault'), # ENTERING_SLOT
('FAULTY', 10, 'LogWidgetFault'), # LEAVING_SLOT
('FAULTY', 10, 'LogWidgetFault'), # ENTERING_TRAY
('WIDGET_IDLE', 0, 'RecordWidget'), # AWAITING_REMOVAL
('WIDGET_IDLE', 0, None)) # FAULTY
),
( 'smDoorTransition',
('SM_DOOR_CONTROL', 'DOOR_CLOSED', 'DOOR_OPENING',
'DOOR_OPEN', 'DOOR_CLOSING'),
# ===================================================================
(('EV_BUTTON_PUSHED', 'LOW_QUEUE'),
('DOOR_OPENING', 0, 'OpenDoor'), # DOOR_CLOSED
('DOOR_OPENING', 0, None), # DOOR_OPENING
('DOOR_OPEN', 0, None), # DOOR_OPEN
('DOOR_OPENING', 0, 'OpenDoor')), # FAULTY
(('EV_DOOR_OPEN', 'LOW_QUEUE'),
('DOOR_CLOSED', 0, None), # DOOR_CLOSED
('DOOR_OPEN', 0, 'TriggerWidget'), # DOOR_OPENING
('DOOR_OPEN', 0, None), # DOOR_OPEN
('DOOR_CLOSING', 0, None)), # FAULTY
(('EV_DOOR_CLOSED', 'LOW_QUEUE'),
('DOOR_CLOSED', 0, None), # DOOR_CLOSED
('DOOR_OPENING', 0, None), # DOOR_OPENING
('DOOR_OPEN', 0, None), # DOOR_OPEN
('DOOR_CLOSING', 0, None)), # FAULTY
(('EV_DOOR_TIMEOUT', 'LOW_QUEUE'),
('DOOR_CLOSED', 0, None), # DOOR_CLOSED
('DOOR_CLOSING', 0, 'CloseDoor'), # DOOR_OPENING
('DOOR_CLOSING', 0, 'CloseDoor'), # DOOR_OPEN
('DOOR_CLOSING', 0, None)) # FAULTY
),
),
'Timers' : ('WIDGET_TIMER', 'DOOR_TIMER'),
'Comms' : (('boolean', 'byte', 'sbyte', 'word', 'sword', 'lword', 'slword'),
(('StatusDef', 'StatusDefDescriptor', 1),
('byte', 'ID', 1),
('lword', 'Flags', 2),
('DateTimeDef', 'Timestamp', 1)),
(('DateTimeDef', None, 0),
('byte', 'Hour', 1),
('byte', 'Minute', 1),
('byte', 'Second', 1),
('byte', 'Day', 1),
('byte', 'Month', 1),
('word', 'Year', 1))
),
'Source Files' : ('Widget.h', 'Widget_d.h', 'Widget00.c', 'Widget01.c',
'Widget02.c', 'Widget03.c', 'Widget04.c')
}
###############################################################################
genFiles( genStateTables (Definition['Event Queues'], Definition['State Tables']) +
genTimers (Definition['Timers']) +
genCommsStructures (Definition['Comms']),
Definition['Source Files'])
genStabReport( Definition['State Tables'], 'WidgetStates')
print 'Source code update complete.'
Application Definition Header File Data
The following is a section from Widget_d.h (which included by Exec.h for use in the executive and the application, by defining the constant APP_HEADER to be “Widget_d.h” in the compile options – this typically appears as APP_HEADER=”\”Widget_d.h\”” in the command line):
#ifdef __C166__
#include "C167Dep.h"
#else
#include "WinDep.h"
#endif
//{{EXEC_DEFINE() – if used, this would go here and be filled with the following:
//}}
/********************* Queues **********************************************/
#define BACKGND_QSIZE 128
#define LOW_QSIZE 32
#define INTERMED_QSIZE 32
#define TOP_QSIZE 8
#define TOTAL_QSIZE (BACKGND_QSIZE + LOW_QSIZE + INTERMED_QSIZE + TOP_QSIZE)
#define BACKGND_QUEUE 0
#define LOW_QUEUE 1
#define INTERMED_QUEUE 2
#define TOP_QUEUE 3
#define TOTAL_QUEUES 4
/********************* Events **********************************************/
#define NON_EVENT 0
#define EV_STATUS_REQUEST 1
#define EV_SCAN_TRIGGER 2
#define EV_DOOR_READY 3
#define EV_WIDGET_IN_SLOT 4
#define EV_SLOT_CLEAR 5
#define EV_WIDGET_IN_TRAY 6
#define EV_TRAY_CLEAR 7
#define EV_WIDGET_TIMEOUT 8
#define EV_BUTTON_PUSHED 9
#define EV_DOOR_OPEN 10
#define EV_DOOR_CLOSED 11
#define EV_DOOR_TIMEOUT 12
#define TOTAL_EVENTS 12
/********************* State Machines **************************************/
#define SM_SINGLE_STATE 0
#define SM_WIDGET_SEQUENCER 1
#define SM_DOOR_CONTROL 2
#define STATE_MACHINES 3
#define SINGLE_EVENTS 2
#define WIDGET_STATES 6
#define WIDGET_EVENTS 6
#define DOOR_STATES 4
#define DOOR_EVENTS 4
/********************* Timers **********************************************/
//{{EXEC_TIMERS() – if used, this would go here and be filled with the following:
//}}
#define WIDGET_TIMER 0
#define DOOR_TIMER 1
#define TOTAL_TIMERS 2
#define WIDGET_TIME 2000
#define DOOR_TIME 500
Application Main Header File Data
The following is a section from Widget.h:
extern VCONST struct execInputEventDef InputEvents;
//{{EXEC_DECLARE() – if used, this would go here and be filled with:
//}}
extern VCONST struct execStateTransitionDef smSingleTransition[SINGLE_EVENTS];
extern VCONST struct execStateTransitionDef
smWidgetTransition[WIDGET_STATES*WIDGET_EVENTS];
extern VCONST struct execStateTransitionDef
smDoorTransition[DOOR_STATES*DOOR_EVENTS];
Application-Provided Data Structures
The following is a section from Widget00.c (module 00 contains the definition tables by convention):
#include "Exec.h"
//{{EXEC_DEFINITION() – if used, this would go here and be filled with:
//}}
// Event queue definitions
// -----------------------
VCONST struct execQueueDef execQueue[TOTAL_QUEUES] =
{
{BACKGND_QSIZE ,&execEventQueue[0]},
{LOW_QSIZE,&execEventQueue[BACKGND_QSIZE]},
{INTERMED_QSIZE,&execEventQueue[BACKGND_QSIZE+LOW_QSIZE]},
{TOP_QSIZE,&execEventQueue[BACKGND_QSIZE+LOW_QSIZE+INTERMED_QSIZE]}
};
// State machine definitions
// -------------------------
VCONST struct execStateMachineDef execStateMachine[STATE_MACHINES] =
{
{1, SINGLE_EVENTS, smSingleTransition},
{WIDGET_STATES, WIDGET_EVENTS, smWidgetTransition},
{DOOR_STATES, DOOR_EVENTS, smDoorTransition}
};
// Event definitions
// -----------------
VCONST struct execEventDef execEvent[TOTAL_EVENTS+1] =
{
{0, 0, 0 }, // NON_EVENT
{BACKGND_QUEUE, 0, SM_SINGLE_STATE}, // EV_STATUS_REQUEST
{TOP_QUEUE, 1, SM_SINGLE_STATE}, // EV_SCAN_TRIGGER
{INTERMED_QUEUE, 0, SM_WIDGET_SEQUENCER}, // EV_DOOR_READY
{INTERMED_QUEUE, 1, SM_WIDGET_SEQUENCER}, // EV_WIDGET_IN_SLOT
{INTERMED_QUEUE, 2, SM_WIDGET_SEQUENCER}, // EV_SLOT_CLEAR
{INTERMED_QUEUE, 3, SM_WIDGET_SEQUENCER}, // EV_WIDGET_IN_TRAY
{INTERMED_QUEUE, 4, SM_WIDGET_SEQUENCER}, // EV_TRAY_CLEAR
{INTERMED_QUEUE, 5, SM_WIDGET_SEQUENCER}, // EV_WIDGET_TIMEOUT
{LOW_QUEUE, 0, SM_DOOR_CONTROL}, // EV_BUTTON_PUSHED
{LOW_QUEUE, 1, SM_DOOR_CONTROL}, // EV_DOOR_OPEN
{LOW_QUEUE, 2, SM_DOOR_CONTROL}, // EV_DOOR_CLOSED
{LOW_QUEUE, 3, SM_DOOR_CONTROL} // EV_DOOR_TIMEOUT
};
// Input event definitions
// -----------------------
VCONST struct execInputEventDef InputEvents =
{
{EV_BUTTON_PUSHED, NON_EVENT, NON_EVENT, EV_DOOR_OPEN,
NON_EVENT, EV_WIDGET_IN_SLOT, EV_WIDGET_IN_TRAY, NON_EVENT},
{NON_EVENT, NON_EVENT, NON_EVENT, EV_DOOR_CLOSED,
NON_EVENT, EV_SLOT_CLEAR, EV_TRAY_CLEAR, NON_EVENT},
0x96 // Bit mask; high-going events (above), low-going events
};
Application-Provided Routines
The following is a section from Widget01.c (module 01 contains the application-provided exec. functions by convention):
#include "Exec.h"
void execAppInit (void)
{
// Perform integrity checks
// ------------------------
if (execCheckIntegrity (0) != 0)
{
IdleMonitorPin = FALSE; // Signal system as non-starter
while (1); // Halt
}
else
IdleMonitorPin = TRUE;
// Initialise the system
// ---------------------
SetupIOandInterrupts();
execEnableStateMachine (SM_SINGLE_STATE, 1);
execEnableStateMachine (SM_WIDGET_SEQUENCER, 1);
execEnableStateMachine (SM_DOOR_CONTROL, 1);
}
void execAppIdle(void)
{
IdleMonitorPin = FALSE;
execSafeCpuIdle(); // Returns after next interrupt has processed
IdleMonitorPin = TRUE;
}
void execAppTrace (byte BeforeState, byte AfterState, word Event)
{
// Assumes maximum of 15 states and 64 events
// ------------------------------------------
EmitCodeSomewhere ( (word)(((BeforeState&15)<< 10) +
((AfterState&15)<< 6) +
Event&63));
}
#ifndef _WIN32
void TimerInterrupt (void) /* interrupt */
{
word NextTick, CurrentTick = HwareTimerReg;
// Process the timeout(s)
// ----------------------
NextTick = execProcessTimeouts(CurrentTick);
// Set up for next interrupt or disable
// ------------------------------------
if (NextTick == CurrentTick)
HwareTimerEnable = FALSE; // Disable timer compare
else
HwareCompareReg = NextTick;
}
word execAppCurrentTick()
{
// Return current timer tick
// -------------------------
return HwareTimerReg;
}
void execAppResyncTimer (word TickCount, boolean Enable)
{
HwareTimerEnable = FALSE; // Disable timer compare
// Set up for next interrupt
// -------------------------
HwareCompareReg = TickCount;
// Enable timer compare if required
// --------------------------------
if (Enable);
HwareTimerEnable = TRUE; // Enable timer compare
}
#else
void execAppFinish()
{
}
#endif // _WIN32
State Machines
The following sections are from Widget02.c, Widget03.c, etc., and each contains one state machine each. Module 02 contains the single-state state machine by convention, which is a collection of all of the event handling functions for which state information is irrelevant. Widget02.c:
#include "Exec.h"
/********************* State transition table *******************************/
//{{EXEC_SM_DECLARE(SM_SINGLE_STATE) – if used, this would go here, filled with:
//}}
// States
// ------
#define STATE1 1 // The only valid state
// State transition functions
// --------------------------
static void HandleStatusRequest(void);
static void ScanInputs(void);
//{{EXEC_SM_DEFINE(SM_SINGLE_STATE) – if used, this would go here, filled with:
//}}
// State table
// -----------
VCONST struct execStateTransitionDef smSingleTransition[SINGLE_EVENTS] =
{
// STATE1:
// ------
{STATE1, 0, HandleStatusRequest}, // EV_STATUS_REQUEST
{STATE1, 0, ScanInputs} // EV_SCAN_TRIGGER
};
/********************* State transition functions ***************************/
// Handle status request
// ---------------------
static void HandleStatusRequest (void)
{
ReplyToRequest();
}
// Trigger events based on input pin transitions
// ---------------------------------------------
static void ScanInputs (void)
{
static byte OldInputs = 0x0000, ValidatedInputs = 0x0000;
execPostInputEvents (PinPort, &OldInputs, &ValidatedInputs, &InputEvents);
}
Widget03.c; Widget sequencer state machine:
#include "Exec.h"
/********************* State transition table *******************************/
//{{EXEC_SM_DECLARE(SM_WIDGET_SEQUENCER) – if used, this would go here, with:
//}}
// States
// ------
#define WIDGET_IDLE 1
#define ENTERING_SLOT 2
#define LEAVING_SLOT 3
#define ENTERING_TRAY 4
#define AWAITING_REMOVAL 5
#define FAULTY 6
// State transition functions
// --------------------------
static void DispenseWidget(void);
static void HandleWidget(void);
static void StopWidget(void);
static void RecordWidget(void);
static void LogWidgetFault(void);
//{{EXEC_SM_DEFINE(SM_WIDGET_SEQUENCER) – if used, this would go here, with:
//}}
// State table
// -----------
VCONST struct execStateTransitionDef smWidgetTransition[WIDGET_STATES *
WIDGET_EVENTS] =
{
// WIDGET_IDLE:
// -----------
{ENTERING_SLOT, 0, DispenseWidget}, // EV_DOOR_READY
{FAULTY, 1, LogWidgetFault}, // EV_WIDGET_IN_SLOT
{WIDGET_IDLE, 0, NOFUNC}, // EV_SLOT_CLEAR
{FAULTY, 2, LogWidgetFault}, // EV_WIDGET_IN_TRAY
{WIDGET_IDLE, 0, NOFUNC}, // EV_TRAY_CLEAR
{WIDGET_IDLE, 0, NOFUNC}, // EV_WIDGET_TIMEOUT
// ENTERING_SLOT:
// -------------
{ENTERING_SLOT, 0, NOFUNC}, // EV_DOOR_READY
{LEAVING_SLOT, 0, NOFUNC}, // EV_WIDGET_IN_SLOT
{ENTERING_SLOT, 0, NOFUNC}, // EV_SLOT_CLEAR
{FAULTY, 2, LogWidgetFault}, // EV_WIDGET_IN_TRAY
{ENTERING_SLOT, 0, NOFUNC}, // EV_TRAY_CLEAR
{FAULTY, 10, LogWidgetFault}, // EV_WIDGET_TIMEOUT
// LEAVING_SLOT:
// ------------
{LEAVING_SLOT, 0, NOFUNC}, // EV_DOOR_READY
{LEAVING_SLOT, 0, NOFUNC}, // EV_WIDGET_IN_SLOT
{ENTERING_TRAY, 0, HandleWidget}, // EV_SLOT_CLEAR
{AWAITING_REMOVAL,0,StopWidget}, // EV_WIDGET_IN_TRAY
{LEAVING_SLOT, 0, NOFUNC}, // EV_TRAY_CLEAR
{FAULTY, 10, LogWidgetFault}, // EV_WIDGET_TIMEOUT
// ENTERING_TRAY:
// -------------
{ENTERING_TRAY, 0, NOFUNC}, // EV_DOOR_READY
{FAULTY, 3, LogWidgetFault}, // EV_WIDGET_IN_SLOT
{ENTERING_TRAY, 0, NOFUNC}, // EV_SLOT_CLEAR
{AWAITING_REMOVAL,0,StopWidget}, // EV_WIDGET_IN_TRAY
{WIDGET_IDLE, 0, RecordWidget}, // EV_TRAY_CLEAR
{FAULTY, 10, LogWidgetFault}, // EV_WIDGET_TIMEOUT
// AWAITING_REMOVAL:
// ----------------
{ENTERING_SLOT, 0, DispenseWidget}, // EV_DOOR_READY
{FAULTY, 3, LogWidgetFault}, // EV_WIDGET_IN_SLOT
{AWAITING_REMOVAL,0,NOFUNC}, // EV_SLOT_CLEAR
{AWAITING_REMOVAL,0,NOFUNC}, // EV_WIDGET_IN_TRAY
{WIDGET_IDLE, 0, RecordWidget }, // EV_TRAY_CLEAR
{WIDGET_IDLE, 0, RecordWidget }, // EV_WIDGET_TIMEOUT
// FAULTY:
// ------
{FAULTY, 0, NOFUNC}, // EV_DOOR_READY
{FAULTY, 0, NOFUNC}, // EV_WIDGET_IN_SLOT
{FAULTY, 0, NOFUNC}, // EV_SLOT_CLEAR
{FAULTY, 0, NOFUNC}, // EV_WIDGET_IN_TRAY
{FAULTY, 0, NOFUNC}, // EV_TRAY_CLEAR
{WIDGET_IDLE, 0, NOFUNC} // EV_WIDGET_TIMEOUT
};
/********************* State transition functions ***************************/
// Start by turning widget dispenser on
// ------------------------------------
static void DispenseWidget(void)
{
WidgetDispenser (TRUE);
execSetTimer (WIDGET_TIMER, WIDGET_TIME, EV_WIDGET_TIMEOUT);
}
// Turn widget dispenser off, widget handler on
// --------------------------------------------
static void HandleWidget(void)
{
WidgetDispenser (FALSE);
WidgetHandler (TRUE);
execSetTimer (WIDGET_TIMER, WIDGET_TIME, EV_WIDGET_TIMEOUT);
}
// Turn widget handler off
// -----------------------
static void StopWidget(void)
{
WidgetHandler (FALSE);
execSetTimer (WIDGET_TIMER, WIDGET_TIME, EV_WIDGET_TIMEOUT);
}
// Record the removal of a widget by sending a number
// --------------------------------------------------
static void RecordWidget(void)
{
EmitCodeSomewhere (0x4000 + execTransitionTag);
execSetTimer (WIDGET_TIMER, WIDGET_TIME, EV_WIDGET_TIMEOUT);
}
// Log fault by sending the fault number somewhere
// -----------------------------------------------
static void LogWidgetFault(void)
{
EmitCodeSomewhere (0x8000 + execTransitionTag);
}
Widget04.c; Door sequencer state machine:
#include "Exec.h"
/********************* State transition table *******************************/
//{{EXEC_SM_DECLARE(SM_DOOR_CONTROL) – if used, this would go here, with:
//}}
// States
// ------
#define DOOR_CLOSED 1
#define DOOR_OPENING 2
#define DOOR_OPEN 3
#define DOOR_CLOSING 4
// State transition functions
// --------------------------
static void OpenDoor(void);
static void TriggerWidget(void);
static void CloseDoor(void);
//{{EXEC_SM_DEFINE(SM_DOOR_CONTROL) – if used, this would go here, with:
//}}
// State table
// -----------
VCONST struct execStateTransitionDef smDoorTransition[DOOR_STATES *
DOOR_EVENTS] =
{
// DOOR_CLOSED:
// -----------
{DOOR_OPENING, 0, OpenDoor}, // EV_BUTTON_PUSHED
{DOOR_CLOSED, 0, NOFUNC}, // EV_DOOR_OPEN
{DOOR_CLOSED, 0, NOFUNC}, // EV_DOOR_CLOSED
{DOOR_CLOSED, 0, NOFUNC}, // EV_DOOR_TIMEOUT
// DOOR_OPENING:
// ------------
{DOOR_OPENING, 0, NOFUNC}, // EV_BUTTON_PUSHED
{DOOR_OPEN, 0, TriggerWidget}, // EV_DOOR_OPEN
{DOOR_OPENING, 0, NOFUNC}, // EV_DOOR_CLOSED
{DOOR_CLOSING, 0, CloseDoor}, // EV_DOOR_TIMEOUT
// DOOR_OPEN:
// ---------
{DOOR_OPEN, 0, NOFUNC}, // EV_BUTTON_PUSHED
{DOOR_OPEN, 0, NOFUNC}, // EV_DOOR_OPEN
{DOOR_OPEN, 0, NOFUNC}, // EV_DOOR_CLOSED
{DOOR_CLOSING, 0, CloseDoor}, // EV_DOOR_TIMEOUT
// DOOR_CLOSING:
// ------------
{DOOR_OPENING, 0, OpenDoor }, // EV_BUTTON_PUSHED
{DOOR_CLOSING, 0, NOFUNC}, // EV_DOOR_OPEN
{DOOR_CLOSING, 0, NOFUNC}, // EV_DOOR_CLOSED
{DOOR_CLOSING, 0, NOFUNC} // EV_DOOR_TIMEOUT
};
/********************* State transition functions ***************************/
// Activate the door opener to open it
// -----------------------------------
static void OpenDoor(void)
{
EnergiseDoor (TRUE);
execSetTimer (DOOR_TIMER, DOOR_TIME, EV_DOOR_TIMEOUT);
}
// Start the widget sequencer off
// ------------------------------
static void TriggerWidget(void)
{
execPostEvent (EV_DOOR_READY);
}
// De-activate the door opener to close it
// ---------------------------------------
static void CloseDoor(void)
{
EnergiseDoor (FALSE);
}