Table driven Finite State Machine library based on the Harel state machine, supporting actions on transitions, state entry and state exit. Comes with example illustrating use with interrupts and timers. 03/01/2010 - fixed potential memory leak in DebugTrace.

Dependencies:   mbed

MyInterruptHandler.cpp

Committer:
snatch59
Date:
2010-01-03
Revision:
0:918566a376fb

File content as of revision 0:918566a376fb:

/*
* FiniteStateMachine. Table driven Finite State Machine library 
* based on theHarel state machine, supporting actions on transitions, state
* entry and state exit.
*
* Copyright (C) <2009> Petras Saduikis <petras@petras.co.uk>
*
* This file is part of FiniteStateMachine.
*
* FiniteStateMachine is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* 
* FiniteStateMachine is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with DebugTrace.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <mbed.h>
#include "MyInterruptHandler.h"
#include "FSMDefs.h"
#include "FSM.h"
#include "DebugTrace.h"

DebugTrace pc(ON, TO_SERIAL);

typedef void (MyInterruptHandler::* clientActionPtr)( );

// states
const char* S_START     = "Start";
const char* S_LED_SEQ1  = "LedSeq1";
const char* S_LED_SEQ2  = "LedSeq2";

const StateDefinition<clientActionPtr> states[] = 
   {// state,        entry action,                         exit action
       S_START,       NULL,                                NULL,
       S_LED_SEQ1,    &MyInterruptHandler::ledSequence1,   NULL,
       S_LED_SEQ2,    &MyInterruptHandler::ledSequence2,   NULL
   };
const int total_states = sizeof(states)/sizeof(StateDefinition<clientActionPtr>);

// transitions
const TransitionDefinition<clientActionPtr> transitions[] = 
   {// start state,     event,          type        transition action,    end state
       S_START,         (int)intr1,     actions,    NULL,                 S_LED_SEQ1,
       S_LED_SEQ1,      (int)intr2,     actions,    NULL,                 S_LED_SEQ2,
       S_LED_SEQ2,      (int)intr1,     actions,    NULL,                 S_LED_SEQ1,
       S_LED_SEQ1,      (int)tickr1,    actions,    NULL,                 S_LED_SEQ1,
       S_LED_SEQ2,      (int)tickr1,    actions,    NULL,                 S_LED_SEQ2,
   };
const int total_transitions = sizeof(transitions)/sizeof(TransitionDefinition<clientActionPtr>);

// declare a state machine
static FiniteStateMachine<MyInterruptHandler, clientActionPtr, total_states> itsStateMachine;

// put LEDs on a bus for convenience
BusOut leds(LED1, LED2, LED3, LED4);


MyInterruptHandler::MyInterruptHandler() : interrupt1(p5), interrupt2(p6)
{
    // init state machine
    itsStateMachine.initialize(this, states, total_states, transitions, total_transitions, S_START);
    
    // attach callbacks for interrupts and timer
    interrupt1.rise(this, &MyInterruptHandler::intrhandler1);
    interrupt2.rise(this, &MyInterruptHandler::intrhandler2);
    ticker1.attach(this, &MyInterruptHandler::tickerhandler1, 0.5);
}

void MyInterruptHandler::processEvent(clientEvent event_id)
{
    itsStateMachine.traverse((int)event_id);
}

void MyInterruptHandler::intrhandler1()
{
    processEvent(intr1);
}

void MyInterruptHandler::intrhandler2()
{
    processEvent(intr2);
}

void MyInterruptHandler::tickerhandler1()
{
    processEvent(tickr1);
}

void MyInterruptHandler::ledSequence1()
{
    pc.traceOut("ledSequence1\r\n");
    (0x00 == leds || 0x08 == leds) ? leds = 1 : leds = leds << 1;
}

void MyInterruptHandler::ledSequence2()
{
    pc.traceOut("ledSequence2\r\n");
    (0x00 == leds || 0x01 == leds) ? leds = 8 : leds = leds >> 1;
}