Sendcommand C
Sendcommand C
Module
SendCommand.c
Description
Send Command state machine
****************************************************************************/
/*----------------------------- Include Files -----------------------------*/
// Basic includes for a program using the Events and Services Framework
#include "ES_Configure.h"
#include "ES_Framework.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"
"driverlib/gpio.h"
/* 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 "SendCommand.h"
#include "DRS.h"
#include "MasterMachine.h"
/*----------------------------- Module Defines ----------------------------*/
// define constants for the states for this machine
// and any other local defines
#define ALL_BITS (0xff<<2)
/*---------------------------- Module Functions ---------------------------*/
/* prototypes for private functions for this machine, things like during
functions, entry & exit functions.They should be functions relevant to the
behavior of this state machine
*/
static ES_Event DuringWaitSendCommand( ES_Event Event);
static ES_Event DuringSendBytes( ES_Event Event);
void
void
void
void
EOTHandler( void );
WriteData(void);
ReadData(void);
DecodeResponse(void);
EntryEventKind.EventType = ES_ENTRY;
EntryEventKind.EventParam =
CurrentEvent.EventParam;
}
}
break;
case SendBytes :
// Execute During function for state one. ES_ENTRY & ES_EXIT are
// processed here allow the lower level state machines to re-map
// or consume the event
CurrentEvent = DuringSendBytes(CurrentEvent);
if ( CurrentEvent.EventType != ES_NO_EVENT ) //If
an event is active
if (CurrentEvent.EventType ==
ES_TIMEOUT && CurrentEvent.EventParam == SPI_TIMER)
{
// Execute action function for
NextState =
WaitSendCommand;//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;
default:;
}
//
If we are making a state transition
if (MakeTransition == true)
{
//
Execute exit function for current state
CurrentEvent.EventType = ES_EXIT;
RunSendCommandSM(CurrentEvent);
CurrentState = NextState; //Modify state variable
//
Execute entry function for new state
// this defaults to ES_ENTRY
RunSendCommandSM(EntryEventKind);
}
return(ReturnEvent);
}
/****************************************************************************
Function
StartSendCommandSM
Parameters
None
Returns
None
Description
Does any required initialization for this state machine
Notes
Author
****************************************************************************/
void StartSendCommandSM ( ES_Event CurrentEvent )
{
// start in waitSendCommand state
if ( ES_ENTRY_HISTORY != CurrentEvent.EventType )
{
CurrentState = WaitSendCommand;
}
// call the entry function (if any) for the ENTRY_STATE
RunSendCommandSM(CurrentEvent);
}
/****************************************************************************
Function
QuerySendCommandSM
Parameters
None
****************************************************************************/
SendCommandState_t QuerySendCommandSM ( void )
{
return(CurrentState);
}
/***************************************************************************
private functions
***************************************************************************/
static ES_Event DuringWaitSendCommand( ES_Event Event)
{
ES_Event ReturnEvent = Event; // assume 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 DuringSendBytes( ES_Event Event)
{
ES_Event ReturnEvent = Event; // assume no re-mapping or comsumption
// process ES_ENTRY, ES_ENTRY_HISTORY & ES_EXIT events
if ( (Event.EventType == ES_ENTRY) ||
(Event.EventType == ES_ENTRY_HISTORY) )
{
// Write Command to Transmit FIFO
command = Event.EventParam;
WriteData();
}
else if ( Event.EventType == ES_EXIT )
{
// Post NEW COMMAND to master
ES_Event ThisEvent = {ES_NEW_COMMAND,0};
PostMaster(ThisEvent);
}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);
}
/****************************************************************************
Function
EOTHandler
Parameters
none
Returns
none
Description
This is an Interrupt Service Routine to clear the interrupt triggered by
the EOT and post an event to the SendByte
****************************************************************************/
void EOTHandler( void )
{
//disable end of transmission interrupt
HWREG(SSI0_BASE + SSI_O_IM) &= ~SSI_IM_TXIM;
//read data from data register
ReadData();
//decode receive bytes
DecodeResponse();
// Wait more than 2 ms for next Send Command
ES_Timer_InitTimer(SPI_TIMER, 5);
}
void WriteData(void) {
//write all 8 bytes to the data register
HWREG(SSI0_BASE + SSI_O_DR) = command;
HWREG(SSI0_BASE + SSI_O_DR) = 0;
HWREG(SSI0_BASE + SSI_O_DR) = 0;
HWREG(SSI0_BASE + SSI_O_DR) = 0;
HWREG(SSI0_BASE + SSI_O_DR) = 0;
HWREG(SSI0_BASE + SSI_O_DR) = 0;
HWREG(SSI0_BASE + SSI_O_DR) = 0;
HWREG(SSI0_BASE + SSI_O_DR) = 0;
//enable end of transmission interrupt
HWREG(SSI0_BASE + SSI_O_IM) |= SSI_IM_TXIM;
}
void ReadData(void) {
// Read data from Receive FIFO & store in responseByte
responseByte1 = HWREG(SSI0_BASE + SSI_O_DR);
responseByte2 = HWREG(SSI0_BASE + SSI_O_DR);
responseByte3 = HWREG(SSI0_BASE + SSI_O_DR);
responseByte4 = HWREG(SSI0_BASE + SSI_O_DR);
responseByte5 = HWREG(SSI0_BASE + SSI_O_DR);
responseByte6 = HWREG(SSI0_BASE + SSI_O_DR);
responseByte7 = HWREG(SSI0_BASE + SSI_O_DR);
responseByte8 = HWREG(SSI0_BASE + SSI_O_DR);
}
void DecodeResponse(void) {
//parse Query Game command
if(command == 0x3F) {
SS1 = responseByte4;
SS2 = responseByte5;
SS3 = responseByte6;
}
//parse Query Kart1 command
else if(command == 0xC3) {
X1 = (responseByte3 << 8) + responseByte4;
Y1 = (responseByte5 << 8) + responseByte6;
O1 = (responseByte7 << 8) + responseByte8;
}
//parse Query Kart2 command
else if(command == 0x5A) {
X2 = (responseByte3 << 8) + responseByte4;
Y2 = (responseByte5 << 8) + responseByte6;
O2 = (responseByte7 << 8) + responseByte8;
}
//parse Query Kart3 command
else if(command == 0x7E) {
X3 = (responseByte3 << 8) + responseByte4;
Y3 = (responseByte5 << 8) + responseByte6;
O3 = (responseByte7 << 8) + responseByte8;
}
}
uint16_t GetKartX(void) {
if(KartNum == 1) {
return X1;
}
else if(KartNum == 2) {
return X2;
}
else if(KartNum == 3) {
return X3;
}
else {
return 0xff;
}
uint16_t GetKartY(void) {
if(KartNum == 1) {
return Y1;
}
else if(KartNum == 2) {
return Y2;
}
else if(KartNum == 3) {
return Y3;
}
else {
return 0xff;
}
}
uint16_t GetX1(void) {
return X1;
}
uint16_t GetX2(void) {
return X2;
}
uint16_t GetX3(void) {
return X3;
}
uint16_t GetY1(void) {
return Y1;
}
uint16_t GetY2(void) {
return Y2;
}
uint16_t GetY3(void) {
return Y3;
}
int16_t GetO1(void) {
return O1;
}
int16_t GetO2(void) {
return O2;
}
int16_t GetO3(void) {
return O3;
}
// 0: DO BALL SHOOTING
// 1: SKIP BALL SHOOTING
uint8_t GetTargetStatus(void) {
if(KartNum == 1) {
return ((SS1 & BIT7HI) == BIT7HI);
}
else if(KartNum ==
return ((SS2
}
else if(KartNum ==
return ((SS3
}
else {
return 0xff;
}
2) {
& BIT7HI) == BIT7HI);
3) {
& BIT7HI) == BIT7HI);
}
// 0: DO OBSTACLE
// 1: SKIP OBSTACLE
uint8_t GetObstacleStatus(void) {
if(KartNum == 1) {
return ((SS1 & BIT6HI) == BIT6HI);
}
else if(KartNum == 2) {
return ((SS2 & BIT6HI) == BIT6HI);
}
else if(KartNum == 3) {
return ((SS3 & BIT6HI) == BIT6HI);
}
else {
return 0xff;
}
}
uint8_t GetNumLapsLeft(void) {
if(KartNum == 1) {
return (SS1 & (BIT2HI | BIT1HI | BIT0HI));
}
else if(KartNum == 2) {
return (SS2 & (BIT2HI | BIT1HI | BIT0HI));
}
else if(KartNum == 3) {
return (SS3 & (BIT2HI | BIT1HI | BIT0HI));
}
else {
return 0xff;
}
}
uint8_t GetFlagDroppedStatus (void) {
if(KartNum == 1) {
return ((SS1 & (BIT3HI | BIT4HI)) >> 3);
}
else if(KartNum == 2) {
return ((SS2 & (BIT3HI | BIT4HI)) >> 3);
}
else if(KartNum == 3) {
return ((SS3 & (BIT3HI | BIT4HI)) >> 3);
}
else {
return 0xff;
}
}
void SetKartNumber (uint8_t N)
{
KartNum = N;
}