0% found this document useful (0 votes)
186 views10 pages

Drs C

This C code file defines functions for communicating with a Dred Reckoning System (DRS) using SPI. It includes header files related to SPI communication and initializes the SPI hardware. It defines an enum for DRS states like WaitDRS and QueryGame. The main RunDRS function implements a state machine to handle SPI transactions and events between the DRS states.

Uploaded by

api-272643960
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as RTF, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
186 views10 pages

Drs C

This C code file defines functions for communicating with a Dred Reckoning System (DRS) using SPI. It includes header files related to SPI communication and initializes the SPI hardware. It defines an enum for DRS states like WaitDRS and QueryGame. The main RunDRS function implements a state machine to handle SPI transactions and events between the DRS states.

Uploaded by

api-272643960
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as RTF, PDF, TXT or read online on Scribd
You are on page 1/ 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

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy