Drs C

You might also like

Download as rtf, pdf, or txt
Download as rtf, pdf, or txt
You are on page 1of 10

/****************************************************************************

Module
DRS.c
Description
This is a template for doing SPI communication with the Dred Reckoning System
Notes
****************************************************************************/
/*----------------------------- Include Files -----------------------------*/
/* include header files for this state machine as well as any machines at the
next lower level in the hierarchy that are sub-machines to this machine
*/
#include "ES_Configure.h"
#include "ES_Framework.h"
#include "DRS.h"
#include "SendCommand.h"
#include "DeadReckoning.h"
#include "TargetTracking.h"
#include "MasterMachine.h"
#include
#include
#include
#include
#include
#include
#include
#include

"inc/hw_memmap.h"
"inc/hw_gpio.h"
"inc/hw_ssi.h"
"inc/hw_sysctl.h"
"inc/hw_types.h"
"inc/hw_nvic.h"
"bitdefs.h"
<math.h>

/*----------------------------- Module Defines ----------------------------*/


#define BitsPerNibble 4
/*---------------------------- Module Functions ---------------------------*/
static ES_Event DuringWaitDRS( ES_Event Event);
static ES_Event DuringQueryGame( ES_Event Event);
static ES_Event DuringQueryKart1( ES_Event Event);
static ES_Event DuringQueryKart2( ES_Event Event);
static ES_Event DuringQueryKart3( ES_Event Event);
/*---------------------------- Module Variables ---------------------------*/
static DRSState_t CurrentState;
static uint8_t LastFlagStatus = RaceOverFlag;
/*------------------------------ Module Code ------------------------------*/
/****************************************************************************
Function
InitDRS
Returns
boolean, False if error in initialization, True otherwise
Description
Hardware initializations and configuration for SPI
Notes
Author
****************************************************************************/
bool InitDRS( void )
{
// enable the clock to Port A
HWREG(SYSCTL_RCGCGPIO) |= SYSCTL_RCGCGPIO_R0;

// start by enabling the clock to the SSI Module 0


HWREG(SYSCTL_RCGCSSI) |= SYSCTL_RCGCSSI_R0;

//wait for GPIO port to be ready


while ((HWREG(SYSCTL_PRGPIO) & SYSCTL_PRGPIO_R0) != SYSCTL_PRGPIO_R0)

// start by selecting the alternate function for PA2-5


HWREG(GPIO_PORTA_BASE+GPIO_O_AFSEL) |= (BIT5HI | BIT4HI | BIT3HI | BIT2HI);
//enable pull up on clk line
HWREG(GPIO_PORTA_BASE+GPIO_O_PUR) |= (BIT2HI | BIT4HI);
HWREG(GPIO_PORTA_BASE+GPIO_O_ODR) |= BIT3HI;
//set GPIO_PCTL to select SSI
HWREG(GPIO_PORTA_BASE+GPIO_O_PCTL) =
(HWREG(GPIO_PORTA_BASE+GPIO_O_PCTL) & 0xff0000ff) + (2<<(5*BitsPerNibble)) +
(2<<(4*BitsPerNibble)) + (2<<(3*BitsPerNibble)) + (2<<(2*BitsPerNibble));
// Enable pins 2-5 on Port A for digital I/O
HWREG(GPIO_PORTA_BASE+GPIO_O_DEN) |= (BIT5HI | BIT4HI | BIT3HI | BIT2HI);
// make pins 2, 3, 5 on Port A outputs
HWREG(GPIO_PORTA_BASE+GPIO_O_DIR) |= (BIT5HI | BIT3HI | BIT2HI);
// make pin 4 on Port A an input
HWREG(GPIO_PORTA_BASE+GPIO_O_DIR) &= ~BIT4HI;

//wait for SSI0 to be ready


while ((HWREG(SYSCTL_PRSSI) & SYSCTL_PRSSI_R0) != SYSCTL_PRSSI_R0)
//disable SSI before programming mode bits (SSE = 0)
HWREG(SSI0_BASE+SSI_O_CR1) &= ~(SSI_CR1_SSE);
//select master mode and TXRIS indicating end of transmit
HWREG(SSI0_BASE+SSI_O_CR1) &= ~SSI_CR1_MS;
HWREG(SSI0_BASE+SSI_O_CR1) |= SSI_CR1_EOT;
//configure clock pre-scalar
HWREG(SSI0_BASE+SSI_O_CPSR) |= 0x90; // 64
//configure SSI clock source to the system clk
HWREG(SSI0_BASE+SSI_O_CC) |= SSI_CC_CS_SYSPLL;

//Configure clock rate (SCR), phase & polarity (SPH, SPO), mode (FRF),
data size (DSS)
HWREG(SSI0_BASE+SSI_O_CR0) |= (SSI_CR0_SPH | SSI_CR0_SPO | SSI_CR0_DSS_8);
HWREG(SSI0_BASE+SSI_O_CR0) &= ~(SSI_CR0_FRF_MOTO);
HWREG(SSI0_BASE+SSI_O_CR0) |= (HWREG(SSI0_BASE+SSI_O_CR0) &
~SSI_CR0_SCR_M) + (48<<SSI_CR0_SCR_S); // 40 something
//Enable interrupts globally
__enable_irq();
//Locally enable interrupts on TXRIS
HWREG(SSI0_BASE + SSI_O_CR1) |= SSI_CR1_EOT;
// enable the Timer B in Wide Timer 0 interrupt in the NVIC
// it is interrupt number 7 so apppears in EN0 at bit 7
HWREG(NVIC_EN0) = BIT7HI;
//enable SSI (SSE = 1)

HWREG(SSI0_BASE+SSI_O_CR1) |= SSI_CR1_SSE;
printf("InitDRS Complete\r\n");
return true;
}
/****************************************************************************
Function
QueryDRS
Parameters
None
Returns
DRSState_t The current state of the DRS state machine
Description
returns the current state of the DRS state machine
Notes
****************************************************************************/
DRSState_t QueryDRS ( void )
{
return(CurrentState);
}
/****************************************************************************
Function
RunDRS
Parameters
ES_Event: the event to process
Returns
ES_Event: an event to return
Description
Executes communication with the DRS
****************************************************************************/
ES_Event RunDRS( ES_Event CurrentEvent )
{
bool MakeTransition = false;/* are we making a state transition? */
DRSState_t NextState = CurrentState;
ES_Event EntryEventKind = { ES_ENTRY, 0 };// default to normal entry to new
state
ES_Event ReturnEvent = { ES_NO_EVENT, 0 }; // assume no error
switch ( CurrentState )

case WaitDRS :
CurrentEvent = DuringWaitDRS(CurrentEvent);
//process any events
if ( CurrentEvent.EventType != ES_NO_EVENT ) //If an event is active
{
if (CurrentEvent.EventType == ES_TIMEOUT && CurrentEvent.EventParam
== DRS_UPDATE_TIMER)
{
// Execute action function for state
one : event one
NextState = QueryGame;//Decide what
the next state will be
// for internal transitions, skip
changing MakeTransition

are taking a transition


history change kind of entry

MakeTransition = true; //mark that we


// if transitioning to a state with
EntryEventKind.EventType = ES_ENTRY;
// optionally, consume or re-map this

event for the upper

relevant events
}
}
break;

// level state machine


ReturnEvent.EventType = ES_NO_EVENT;
break;
// repeat cases as required for

case QueryGame :
CurrentEvent = DuringQueryGame(CurrentEvent);
//process any events
if ( CurrentEvent.EventType != ES_NO_EVENT ) //If an event is active
{
if(CurrentEvent.EventType == ES_NEW_COMMAND)
{
// Execute action function for state
one : event one
NextState = QueryKart1;//Decide what
the next state will be
// for internal transitions, skip
changing MakeTransition
MakeTransition = true; //mark that we
are taking a transition
// if transitioning to a state with
history change kind of entry
EntryEventKind.EventType = ES_ENTRY;
// optionally, consume or re-map this
event for the upper
// level state machine
ReturnEvent.EventType = ES_NO_EVENT;
break;
// repeat cases as required for
relevant events
}
}
break;
case QueryKart1 :
// Execute During function for state one. ES_ENTRY & ES_EXIT are
// processed here allow the lowere level state machines to re-map
// or consume the event
CurrentEvent = DuringQueryKart1(CurrentEvent);
//process any events
if ( CurrentEvent.EventType != ES_NO_EVENT ) //If an event is active
{
if(CurrentEvent.EventType == ES_NEW_COMMAND)
{
// Execute action function for state
one : event one
NextState = QueryKart2;//Decide what
the next state will be
// for internal transitions, skip
changing MakeTransition
MakeTransition = true; //mark that we

are taking a transition


history change kind of entry
event for the upper

// if transitioning to a state with


EntryEventKind.EventType = ES_ENTRY;
// optionally, consume or re-map this
// level state machine
ReturnEvent.EventType = ES_NO_EVENT;
break;
// repeat cases as required for

relevant events
}
}
break;
case QueryKart2 :
// Execute During function for state one. ES_ENTRY & ES_EXIT are
// processed here allow the lowere level state machines to re-map
// or consume the event
CurrentEvent = DuringQueryKart2(CurrentEvent);
//process any events
if ( CurrentEvent.EventType != ES_NO_EVENT ) //If an event is active
{
if(CurrentEvent.EventType == ES_NEW_COMMAND)
{
// Execute action function for state
one : event one
NextState = QueryKart3;//Decide what
the next state will be
// for internal transitions, skip
changing MakeTransition
MakeTransition = true; //mark that we
are taking a transition
// if transitioning to a state with
history change kind of entry
EntryEventKind.EventType = ES_ENTRY;
// optionally, consume or re-map this
event for the upper
// level state machine
ReturnEvent.EventType = ES_NO_EVENT;
break;
// repeat cases as required for
relevant events
}
}
break;
case QueryKart3 :
// Execute During function for state one. ES_ENTRY & ES_EXIT are
// processed here allow the lowere level state machines to re-map
// or consume the event
CurrentEvent = DuringQueryKart3(CurrentEvent);
//process any events
if ( CurrentEvent.EventType != ES_NO_EVENT ) //If an event is active
{
if(CurrentEvent.EventType == ES_NEW_COMMAND)
{
// Execute action function for state
one : event one
NextState = WaitDRS;//Decide what the
next state will be
// for internal transitions, skip

changing MakeTransition
are taking a transition
history change kind of entry
event for the upper

MakeTransition = true; //mark that we


// if transitioning to a state with
EntryEventKind.EventType = ES_ENTRY;
// optionally, consume or re-map this
// level state machine
ReturnEvent.EventType = ES_NO_EVENT;
break;
// repeat cases as required for

relevant events
}
}
break;
}
//
If we are making a state transition
if (MakeTransition == true)
{
//
Execute exit function for current state
CurrentEvent.EventType = ES_EXIT;
RunDRS(CurrentEvent);
CurrentState = NextState; //Modify state variable
// Execute entry function for new state
// this defaults to ES_ENTRY
RunDRS(EntryEventKind);
}
// in the absence of an error the top level state machine should
// always return ES_NO_EVENT, which we initialized at the top of func
return(ReturnEvent);
}
/****************************************************************************
Function
StartDRS
Parameters
ES_Event CurrentEvent
Returns
nothing
Description
Does any required initialization for this state machine
Notes
****************************************************************************/
void StartDRS( ES_Event CurrentEvent )
{
// if there is more than 1 state to the top level machine you will need
// to initialize the state variable
CurrentState = WaitDRS;
// Start DRS Update Timer
ES_Timer_InitTimer(DRS_UPDATE_TIMER, 100);
// now we need to let the Run function init the lower level state machines
// use LocalEvent to keep the compiler from complaining about unused var
RunDRS(CurrentEvent);
return;

}
/***************************************************************************
private functions
***************************************************************************/
static ES_Event DuringWaitDRS( ES_Event Event)
{
ES_Event ReturnEvent = Event; // assme no re-mapping or comsumption
// process ES_ENTRY, ES_ENTRY_HISTORY & ES_EXIT events
if ( (Event.EventType == ES_ENTRY) ||
(Event.EventType == ES_ENTRY_HISTORY) )
{
// do nothing
}
else if ( Event.EventType == ES_EXIT )
{
// do nothing
}else
// do the 'during' function for this state
{
// do nothing
}
// return either Event, if you don't want to allow the lower level machine
// to remap the current event, or ReturnEvent if you do want to allow it.
return(ReturnEvent);
}
static ES_Event DuringQueryGame( ES_Event Event)
{
ES_Event ReturnEvent = Event; // assme no re-mapping or comsumption
// process ES_ENTRY, ES_ENTRY_HISTORY & ES_EXIT events
if ( (Event.EventType == ES_ENTRY) ||
(Event.EventType == ES_ENTRY_HISTORY) )
{
Event.EventType = ES_SEND_COMMAND;
Event.EventParam = 0x3F; //command for DRS
// after that start any lower level machines that run in this
state
machines

StartSendCommandSM( Event );
// repeat the StartxxxSM() functions for concurrent state

// on the lower level


}
else if ( Event.EventType == ES_EXIT )
{
// on exit, give the lower levels a chance to clean up first
RunSendCommandSM(Event);
// repeat for any concurrently running state machines
// now do any local exit functionality

CautionFlag) {

// compare current flag status to last flag and status


// post an event if they're different
uint8_t CurrentStatus = GetFlagDroppedStatus();
if ( (CurrentStatus != LastFlagStatus) && CurrentStatus ==

ES_Event PostEvent = {EV_CAUTION_FLAG, 0};


PostMaster(PostEvent);
printf("Caution flag\r\n");

FlagDropped) {

if ( (CurrentStatus != LastFlagStatus) && CurrentStatus ==


ES_Event PostEvent = {EV_FLAG_DROPPED, 0};
PostMaster(PostEvent);
printf("Start flag\r\n");

RaceOverFlag) {

}
if ( (CurrentStatus != LastFlagStatus) && CurrentStatus ==
ES_Event PostEvent = {EV_RACE_OVER_FLAG, 0};
PostMaster(PostEvent);
printf("Race over\r\n");

}
LastFlagStatus = CurrentStatus;

}else
// do the 'during' function for this state
{
// run any lower level state machine
ReturnEvent = RunSendCommandSM(Event);
// repeat for any concurrent lower level machines
// do any activity that is repeated as long as we are in this
state
}
// return either Event, if you don't want to allow the lower level machine
// to remap the current event, or ReturnEvent if you do want to allow it.
return(ReturnEvent);
}
static ES_Event DuringQueryKart1( ES_Event Event)
{
ES_Event ReturnEvent = Event; // assme no re-mapping or comsumption
// process ES_ENTRY, ES_ENTRY_HISTORY & ES_EXIT events
if ( (Event.EventType == ES_ENTRY) ||
(Event.EventType == ES_ENTRY_HISTORY) )
{
// implement any entry actions required for this state machine
Event.EventType = ES_SEND_COMMAND;
Event.EventParam = 0xC3; //command for DRS
// after that start any lower level machines that run in this
state
StartSendCommandSM( Event );
// repeat the StartxxxSM() functions for concurrent state
machines
// on the lower level
}
else if ( Event.EventType == ES_EXIT )
{
// on exit, give the lower levels a chance to clean up first
RunSendCommandSM(Event);
// repeat for any concurrently running state machines
// now do any local exit functionality
}else
// do the 'during' function for this state
{
// run any lower level state machine
ReturnEvent = RunSendCommandSM(Event);
// repeat for any concurrent lower level machines

// do any activity that is repeated as long as we are in this


state
}
// return either Event, if you don't want to allow the lower level machine
// to remap the current event, or ReturnEvent if you do want to allow it.
return(ReturnEvent);
}
static ES_Event DuringQueryKart2( ES_Event Event)
{
ES_Event ReturnEvent = Event; // assme no re-mapping or comsumption
// process ES_ENTRY, ES_ENTRY_HISTORY & ES_EXIT events
if ( (Event.EventType == ES_ENTRY) ||
(Event.EventType == ES_ENTRY_HISTORY) )
{
// implement any entry actions required for this state machine
Event.EventType = ES_SEND_COMMAND;
Event.EventParam = 0x5A; //command for DRS
state

// after that start any lower level machines that run in this
StartSendCommandSM( Event );
// repeat the StartxxxSM() functions for concurrent state

machines

// on the lower level


}
else if ( Event.EventType == ES_EXIT )
{
// on exit, give the lower levels a chance to clean up first
RunSendCommandSM(Event);
// repeat for any concurrently running state machines
// now do any local exit functionality
}else
// do the 'during' function for this state
{
// run any lower level state machine
ReturnEvent = RunSendCommandSM(Event);
// repeat for any concurrent lower level machines

// do any activity that is repeated as long as we are in this


state
}
// return either Event, if you don't want to allow the lower level machine
// to remap the current event, or ReturnEvent if you do want to allow it.
return(ReturnEvent);
}
static ES_Event DuringQueryKart3( ES_Event Event)
{
ES_Event ReturnEvent = Event; // assme no re-mapping or comsumption
// process ES_ENTRY, ES_ENTRY_HISTORY & ES_EXIT events
if ( (Event.EventType == ES_ENTRY) ||
(Event.EventType == ES_ENTRY_HISTORY) )
{
// implement any entry actions required for this state machine
Event.EventType = ES_SEND_COMMAND;
Event.EventParam = 0x7E; //command for DRS
// after that start any lower level machines that run in this

state
machines

StartSendCommandSM( Event );
// repeat the StartxxxSM() functions for concurrent state

// on the lower level


}
else if ( Event.EventType == ES_EXIT )
{
// on exit, give the lower levels a chance to clean up first
RunSendCommandSM(Event);
// repeat for any concurrently running state machines
// now do any local exit functionality
// update dead reckoning coordinates with DRS coordinates
double x = GetKartX();
double y = GetKartY();
double PrevHeading = GetHeading();
// Update Kart Coordinates
SetCoordinates(x,y,PrevHeading);
ES_Timer_InitTimer(DRS_UPDATE_TIMER, 100);
}else
// do the 'during' function for this state
{
// run any lower level state machine
ReturnEvent = RunSendCommandSM(Event);
// repeat for any concurrent lower level machines
// do any activity that is repeated as long as we are in this
state
}
// return either Event, if you don't want to allow the lower level machine
// to remap the current event, or ReturnEvent if you do want to allow it.
return(ReturnEvent);
}

You might also like