Sunteți pe pagina 1din 12

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

Module
SPIStateMachine.c
Revision
1.0
Description
This is the SPIStateMachine for Team 9 ME218b final project. It is a state ma
chine
orthogonal to GameStateMachine.
Notes
History
When
Who
What/Why
----------------------02/11/2015 10:00
Sky
02/09/2015
16:53 Sky
Initial version
****************************************************************************/
//#define testDRS
#include "ES_Configure.h"
#include "ES_Framework.h"
#include "ES_DeferRecall.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include

"inc/hw_memmap.h"
"inc/hw_types.h"
"inc/hw_gpio.h"
"inc/hw_sysctl.h"
"driverlib/sysctl.h"
"driverlib/pin_map.h" // Define PART_TM4C123GH6PM in project
"driverlib/gpio.h"
"inc/hw_ssi.h"
"inc/hw_nvic.h"

#include "MasterMachine.h"
#include "SPIStateMachine.h"
#include "Calculation.h"
#define
#define
#define
#define
#define

BitsPerNibble 4
DRSInterval 5
ByteInterval 2
aGain 1
ALL_BITS (0xff<<2)

/******************************Module Variables*********************************
/
static GameStatusType GameStatus;
static KartStatusType Kart1Status;
static KartStatusType Kart2Status;
static KartStatusType Kart3Status;
static int16_t DRSData[8];
static SPIState CurrentState;
static uint8_t MyPriority;
/**************************Private Function Prototypes**************************
/
static ES_Event DuringSPIGameStatus(ES_Event);
static ES_Event DuringSPIKart1(ES_Event);

static ES_Event DuringSPIKart2(ES_Event);


static ES_Event DuringSPIKart3(ES_Event);
static int16_t CalcDifference(int16_t, int16_t);
/********************************Public Functions*******************************
/
/**************************************************
FUNCTION InitSPI
ARGUMENT: no argument
RETURN: no return
DESCRIPTION: Initialize SPI
**************************************************/
void InitSPI(void)
{
//Enable the clock to the GPIO Port (PA)
//PA2: SSI0Clk
//PA3: SSI0Fss
//PA4: SSI0Rx
//PA5: SSI0Tx
HWREG(SYSCTL_RCGCGPIO) |= SYSCTL_RCGCGPIO_R0;
//Enable the clock to SSI module 0
HWREG(SYSCTL_RCGCSSI) = BIT0HI;
//Wait for GPIO port to be ready
for (int i = 0; i<= 10000; i++);
//set open drain for ss pin
HWREG(GPIO_PORTA_BASE+GPIO_O_ODR) |= BIT3HI;
//Program the GPIO to use the alternate functions on the SSI pins
HWREG(GPIO_PORTA_BASE+GPIO_O_AFSEL) |= (BIT2HI | BIT3HI | BIT4HI | BIT5H
I);
//Select the SSI alternation functions on those pins
//Set mux position in GPIOPCTL to select the SSI use of the pins
HWREG(GPIO_PORTA_BASE+GPIO_O_PCTL) |= (HWREG(GPIO_PORTA_BASE+GPIO_O_PCTL
) & 0xff0000ff)
+ (2<<(2*BitsPerNibble))
+ (2<<(3*BitsPerNibble))
+ (2<<(4*BitsPerNibble))
+ (2<<(5*BitsPerNibble));
//Program the port lines for digital I/O
HWREG(GPIO_PORTA_BASE+GPIO_O_DEN) |= (BIT2HI | BIT3HI | BIT4HI | BIT5HI)
;
//Program the required data directions on the port lines
HWREG(GPIO_PORTA_BASE+GPIO_O_DIR) |= (BIT2HI | BIT3HI | BIT5HI);
HWREG(GPIO_PORTA_BASE+GPIO_O_DIR) &= BIT4LO;
//If using SPI mode 3, program the pull-up on the clock line
HWREG(GPIO_PORTA_BASE+GPIO_O_PUR) |= BIT2HI;
//Wait for the SSI0 to be ready
while ((HWREG(SYSCTL_PRSSI) & SYSCTL_PRSSI_R0) != SYSCTL_PRSSI_R0)
;
//Make sure the SSI is diabled before programming mode bits (clear SSE
bit)
HWREG(SSI0_BASE+SSI_O_CR1) &= BIT1LO;
//Select master mode (MS) & TXRIS indicating End of Transmit(EOT)
HWREG(SSI0_BASE+SSI_O_CR1) = 0;

HWREG(SSI0_BASE+SSI_O_CR1) |= BIT4HI;
//Configure the SSI clock source to the system clock
HWREG(SSI0_BASE+SSI_O_CC) = 0;
//Configure the clock pre-scaler (CPSDVSR = 100)
HWREG(SSI0_BASE+SSI_O_CPSR) = 0x64;
//Configure clock rate(SCR), phase & polarity (SPH = 1, SPO = 1), mode
FRF 0 (SPI)), data size (DSS)
HWREG(SSI0_BASE+SSI_O_CR0) = (HWREG(SSI0_BASE+SSI_O_CR0) & 0xffffff0f)
((BIT2HI | BIT3HI)<<4);
//1100(B) for bit 7-4
HWREG(SSI0_BASE+SSI_O_CR0) = (HWREG(SSI0_BASE+SSI_O_CR0) & 0xfffffff0)
0x07;
//8 bit wide for data size (0111(B) for bit 3-0)
HWREG(SSI0_BASE+SSI_O_CR0) = (HWREG(SSI0_BASE+SSI_O_CR0) & 0xffff00ff)
(0x27 << 8); //SCR = 27 (bit 15-8)

(
|
|
|

//Locally enable interrupts on TXRIS


HWREG(SSI0_BASE+SSI_O_IM) = (HWREG(SSI0_BASE+SSI_O_IM) & ~SSI_IM_TXIM) |
(SSI_IM_TXIM); //set TXIM to 1
//enable the SSI0 interrupt in NVIC
//it is interrupt number 7, bit 7 of en0
HWREG(NVIC_EN0) |= BIT7HI;
//Make sure that the SSI is enabled for operation
HWREG(SSI0_BASE+SSI_O_CR1) |= BIT1HI; //SSE at bit 1
}
/**************************************************
FUNCTION EOTInterruptResponse
ARGUMENT: no argument
RETURN: no return
DESCRIPTION: EOT interrupt response
**************************************************/
void EOTInterruptResponse(void)
{
//puts("EOTInterrput!\n\r");
//do Interrupt Response
for (int i = 0; i <= 7; i++)
{
DRSData[i] = HWREG(SSI0_BASE+SSI_O_DR);
//printf("%d ",DRSData[i]);
}
//printf("\n\r");
ES_Timer_InitTimer(Timer_DRSInterval, DRSInterval);
//disable the interrupt
HWREG(SSI0_BASE+SSI_O_IM) &= ~SSI_IM_TXIM;
}
/**************************************************
FUNCTION InitSPISM
ARGUMENT: an integer represents the priority
RETURN: true if successfully initialize the SPI state machine
DESCRIPTION: Initialize SPI state machine
**************************************************/
bool InitSPISM(uint8_t priority)
{
MyPriority = priority;

SetSelf();
InitSPI();
printf("InitSPISM!\n\r");
ES_Event ThisEvent;
ThisEvent.EventType = ES_ENTRY;
StartSPISM(ThisEvent);
return true;
}
/**************************************************
FUNCTION PostToSPISM
ARGUMENT: ES_Event CurrentEvent
RETURN: true or false
DESCRIPTION: Post event to SPI state machine
**************************************************/
bool PostToSPISM(ES_Event CurrentEvent)
{
return ES_PostToService(MyPriority, CurrentEvent);
}
/**************************************************
FUNCTION StartSPISM
ARGUMENT: ES_Event CurrentEvent
RETURN: no return
DESCRIPTION: start the SPI State machine
**************************************************/
void StartSPISM(ES_Event CurrentEvent)
{
//initial state
CurrentState = SPI_GameStatus;
//Initialize the game field
InitField(240,5, 85, 10, 80,168, 244,167);
//Call RunSPISm with ES_ENTRY to do entry functions
RunSPISM(CurrentEvent);
}
/**************************************************
FUNCTION RunSPISM
ARGUMENT: ES_Event CurrentEvent
RETURN: ES_Event
DESCRIPTION: the run function of SPI state machine
**************************************************/
ES_Event RunSPISM(ES_Event CurrentEvent)
{
ES_Event ReturnEvent;
ES_Event LocalEvent;
SPIState NextState;
bool MakeTransition;
MakeTransition = false;
LocalEvent = CurrentEvent;
ReturnEvent = CurrentEvent;
NextState = CurrentState;
//switch current state
switch (CurrentState)
{
case
SPI_GameStatus
{

//pass down the event to any lower level state machine


LocalEvent = DuringSPIGameStatus(CurrentEvent);
if (ES_NO_EVENT != LocalEvent.EventType) // if there is still an active event
{
if ((LocalEvent.EventType == ES_TIMEOUT)&&
(LocalEvent.EventParam == Timer_DRSInterval))
{
MakeTransition = true;
NextState = SPI_Kart1;
ReturnEvent.EventType = ES_NO_EVENT;
}
}
break;
}
case

SPI_Kart1

: {
//pa
ss down the event to any lower level state machine
LocalEvent = DuringSPIKart1(CurrentEvent);
if (ES_NO_EVENT != LocalEvent.EventType) // if there is still an active event
{
if ((LocalEvent.EventType == ES_TIMEOUT)&&
(LocalEvent.EventParam == Timer_DRSInterval))
{
MakeTransition = true;
NextState = SPI_Kart2;
ReturnEvent.EventType = ES_NO_EVENT;
}
}
break;
}
case
: {

SPI_Kart2

//pass down the event to any lower level state machine


LocalEvent = DuringSPIKart2(CurrentEvent);
if (ES_NO_EVENT != LocalEvent.EventType) // if there is still an active event
{
if ((LocalEvent.EventType == ES_TIMEOUT)&&
(LocalEvent.EventParam == Timer_DRSInterval))
{
MakeTransition = true;
NextState = SPI_Kart3;
ReturnEvent.EventType = ES_NO_EVENT;
}
}
break;
}
case

SPI_Kart3

: {
//pass down the event to any lower level state machine
LocalEvent = DuringSPIKart3(CurrentEvent);
if (ES_NO_EVENT != LocalEvent.EventType) // if there is still an active event
{
if ((LocalEvent.EventType == ES_TIMEOUT)&&
(LocalEvent.EventParam == Timer_DRSInterval))
{
MakeTransition = true;
NextState = SPI_GameStatus;
ReturnEvent.EventType = ES_NO_EVENT;
}
}
break;
}
}

//if we are making transition


if (MakeTransition)
{
//execute exit function for current state
LocalEvent.EventType = ES_EXIT;
RunSPISM(LocalEvent);
//execute entry function for next state
CurrentState = NextState;
LocalEvent.EventType = ES_ENTRY;
RunSPISM(LocalEvent);
}
return ReturnEvent;
}
//Query current game status
GameStatusType QueryGameStatus(void)
{
return GameStatus;
}
//Query current Kart1 status
KartStatusType QueryKart1Status(void)
{
return Kart1Status;
}
//Query current Kart2 status
KartStatusType QueryKart2Status(void)
{
return Kart2Status;
}
//Query current Kart3 status
KartStatusType QueryKart3Status(void)
{
return Kart3Status;
}
/**********************************Private Functions****************************
***************/
/**************************************************
FUNCTION DuringSPIGameStatus
ARGUMENT: ES_Event CurrentEvent
RETURN: ES_Event
DESCRIPTION: the during function of SPI game status
**************************************************/
static ES_Event DuringSPIGameStatus(ES_Event Event)
{
ES_Event LocalEvent = Event;
if (LocalEvent.EventType == ES_ENTRY)
{
//Initialize DRSData
//puts("GameStatus\n\r");
//write 0x3F to data register
HWREG(SSI0_BASE+SSI_O_IM) |= SSI_IM_TXIM;
HWREG(SSI0_BASE+SSI_O_DR) = 0x3F;
HWREG(SSI0_BASE+SSI_O_DR) = 0x00;
HWREG(SSI0_BASE+SSI_O_DR) = 0x00;

HWREG(SSI0_BASE+SSI_O_DR)
HWREG(SSI0_BASE+SSI_O_DR)
HWREG(SSI0_BASE+SSI_O_DR)
HWREG(SSI0_BASE+SSI_O_DR)
HWREG(SSI0_BASE+SSI_O_DR)

=
=
=
=
=

0x00;
0x00;
0x00;
0x00;
0x00;

}
else if (LocalEvent.EventType == ES_EXIT)
{
//update GameStatus
GameStatus.Kart1GameStatus = DRSData[3];
GameStatus.Kart2GameStatus = DRSData[4];
GameStatus.Kart3GameStatus = DRSData[5];
//printf("%d, %d, %d\n\r", DRSData[3], DRSData[4], DRSData[5]);
}
else
{
//nothing to do here
}
return LocalEvent;
}
/**************************************************
FUNCTION DuringSPIKart1
ARGUMENT: ES_Event CurrentEvent
RETURN: ES_Event
DESCRIPTION: the during function of SPI Kart1 status
**************************************************/
static ES_Event DuringSPIKart1(ES_Event Event)
{
ES_Event LocalEvent = Event;
static int16_t LastOrientation = 0;
if (LocalEvent.EventType == ES_ENTRY)
{
//write 0xC3 to to data register
HWREG(SSI0_BASE+SSI_O_IM) |= SSI_IM_TXIM;
HWREG(SSI0_BASE+SSI_O_DR) = 0xC3;
HWREG(SSI0_BASE+SSI_O_DR) = 0x00;
HWREG(SSI0_BASE+SSI_O_DR) = 0x00;
HWREG(SSI0_BASE+SSI_O_DR) = 0x00;
HWREG(SSI0_BASE+SSI_O_DR) = 0x00;
HWREG(SSI0_BASE+SSI_O_DR) = 0x00;
HWREG(SSI0_BASE+SSI_O_DR) = 0x00;
HWREG(SSI0_BASE+SSI_O_DR) = 0x00;
}
else if (LocalEvent.EventType == ES_EXIT)
{
//update Kart1Status
Kart1Status.PositionX = ((DRSData[2]<<8) + DRSData[3]);
Kart1Status.PositionY = ((DRSData[4]<<8) + DRSData[5]);
int16_t Difference = CalcDifference((int16_t)((DRSData[6]<<8)+DRSData[
7]), LastOrientation);
Kart1Status.Orientation = LastOrientation +
Difference/aGain;
if (Kart1Status.Orientation > 180) Kart1Status.Orientation = Kar
t1Status.Orientation-360;
if (Kart1Status.Orientation < -180) Kart1Status.Orientation = Ka
rt1Status.Orientation+360;
Kart1Status.Orientation = LastOrientation +

Difference/(int16_t)aGain;
LastOrientation = Kart1Status.Orientation;
if (Kart1Status.Orientation < 0) Kart1Status.Orientation += (int
16_t)360;
//printf("Kart1: x = %d, y = %d, Orientation = %d\n\r", Kart1Sta
tus.PositionX, Kart1Status.PositionY, Kart1Status.Orientation);
//printf("%d, %d\n\r",(int16_t)((DRSData[6]<<8)+DRSData[7]),(int
16_t)Kart1Status.Orientation);
}
else
{
//nothing to do here
}
return LocalEvent;
}
/**************************************************
FUNCTION DuringSPIKart2
ARGUMENT: ES_Event CurrentEvent
RETURN: ES_Event
DESCRIPTION: the during function of SPI Kart2 status
**************************************************/
static ES_Event DuringSPIKart2(ES_Event Event)
{
ES_Event LocalEvent = Event;
static int16_t LastOrientation = 0;
if (LocalEvent.EventType == ES_ENTRY)
{
//write 0x5A to to data register
HWREG(SSI0_BASE+SSI_O_IM) |= SSI_IM_TXIM;
HWREG(SSI0_BASE+SSI_O_DR) = 0x5A;
HWREG(SSI0_BASE+SSI_O_DR) = 0x00;
HWREG(SSI0_BASE+SSI_O_DR) = 0x00;
HWREG(SSI0_BASE+SSI_O_DR) = 0x00;
HWREG(SSI0_BASE+SSI_O_DR) = 0x00;
HWREG(SSI0_BASE+SSI_O_DR) = 0x00;
HWREG(SSI0_BASE+SSI_O_DR) = 0x00;
HWREG(SSI0_BASE+SSI_O_DR) = 0x00;
}
else if (LocalEvent.EventType == ES_EXIT)
{
//update Kart2Status
Kart2Status.PositionX = ((DRSData[2]<<8) + DRSData[3]);
Kart2Status.PositionY = ((DRSData[4]<<8) + DRSData[5]);
int16_t Difference = CalcDifference((int16_t)((DRSData[6]<<8)+DR
SData[7]), LastOrientation);
Kart2Status.Orientation = LastOrientation +
Difference/aGain;
if (Kart2Status.Orientation > 180) Kart2Status.Orientation = Kar
t2Status.Orientation-360;
if (Kart2Status.Orientation < -180) Kart2Status.Orientation = Ka
rt2Status.Orientation+360;
LastOrientation = Kart2Status.Orientation;
if (Kart2Status.Orientation < 0) Kart2Status.Orientation += 360;
//printf("Kart2: x = %d, y = %d, Orientation = %d\n\r", Kart2Sta
tus.PositionX, Kart2Status.PositionY, Kart2Status.Orientation);

}
else
{
//nothing to do here
}
return LocalEvent;
}
/**************************************************
FUNCTION DuringSPIKart3
ARGUMENT: ES_Event CurrentEvent
RETURN: ES_Event
DESCRIPTION: the during function of SPI Kart3 status
**************************************************/
static ES_Event DuringSPIKart3(ES_Event Event)
{
ES_Event LocalEvent = Event;
static int16_t LastOrientation = 0;
if (LocalEvent.EventType == ES_ENTRY)
{
//write 0x7E to to data register
HWREG(SSI0_BASE+SSI_O_IM) |= SSI_IM_TXIM;
HWREG(SSI0_BASE+SSI_O_DR) = 0x7E;
HWREG(SSI0_BASE+SSI_O_DR) = 0x00;
HWREG(SSI0_BASE+SSI_O_DR) = 0x00;
HWREG(SSI0_BASE+SSI_O_DR) = 0x00;
HWREG(SSI0_BASE+SSI_O_DR) = 0x00;
HWREG(SSI0_BASE+SSI_O_DR) = 0x00;
HWREG(SSI0_BASE+SSI_O_DR) = 0x00;
HWREG(SSI0_BASE+SSI_O_DR) = 0x00;
}
else if (LocalEvent.EventType == ES_EXIT)
{
//update Kart3Status
Kart3Status.PositionX = ((DRSData[2]<<8) + DRSData[3]);
Kart3Status.PositionY = ((DRSData[4]<<8) + DRSData[5]);
int16_t Difference = CalcDifference((int16_t)((DRSData[6]<<8)+DR
SData[7]), LastOrientation);
Kart2Status.Orientation = LastOrientation +
Difference/aGain;
if (Kart3Status.Orientation > 180) Kart3Status.Orientation = Kar
t3Status.Orientation-360;
if (Kart3Status.Orientation < -180) Kart3Status.Orientation = Ka
rt3Status.Orientation+360;
Kart3Status.Orientation = LastOrientation +
Difference/aGain;
LastOrientation = Kart3Status.Orientation;
if (Kart3Status.Orientation < 0) Kart3Status.Orientation += 360;
//printf("Kart3: x = %d, y = %d, Orientation = %d\n\r", Kart3Sta
tus.PositionX, Kart3Status.PositionY, Kart3Status.Orientation);
}
else
{
//nothing to do here
}
return LocalEvent;

}
int16_t CalcDifference(int16_t TargetD, int16_t CurrentD)
{
int16_t ReturnVal;
if (((TargetD<=0)&&(CurrentD<=0))||
((TargetD>=0)&&(CurrentD>=0)))
{
ReturnVal = TargetD-CurrentD;
}
else
{
if (CurrentD>0)
{
int16_t tempD = CurrentD-180;
if (tempD>=TargetD)
{
ReturnVal = TargetD+180+180-CurrentD;
}
else
{
ReturnVal = TargetD-CurrentD;
}
}
else
{
int16_t tempD = CurrentD+180;
if (tempD<=TargetD)
{
ReturnVal = -(180-TargetD+CurrentD+180);
}
else
{
ReturnVal = TargetD-CurrentD;
}
}
}
return ReturnVal;
}
#ifdef testDRS
#define clrScrn()
#define goHome()
#define clrLine()

printf("\x1b[2J")
printf("\x1b[1,1H")
printf("\x1b[K")

int main(void)
{
// Set the clock to run at 40MhZ using the PLL and 16MHz external crysta
l
SysCtlClockSet(SYSCTL_SYSDIV_5 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN
| SYSCTL_XTAL_16MHZ);
TERMIO_Init();
clrScrn();
puts("testing DRS!\n\r");
//ES_Initialize(ES_Timer_RATE_1mS);
InitSPISM(0);
while (1)
{
getchar();

HWREG(SSI0_BASE+SSI_O_IM)
HWREG(SSI0_BASE+SSI_O_DR)
HWREG(SSI0_BASE+SSI_O_DR)
HWREG(SSI0_BASE+SSI_O_DR)
HWREG(SSI0_BASE+SSI_O_DR)
HWREG(SSI0_BASE+SSI_O_DR)
HWREG(SSI0_BASE+SSI_O_DR)
HWREG(SSI0_BASE+SSI_O_DR)
HWREG(SSI0_BASE+SSI_O_DR)
}
}
#endif

|= SSI_IM_TXIM;
= 0x5A;
= 0x00;
= 0x00;
= 0x00;
= 0x00;
= 0x00;
= 0x00;
= 0x00;

S-ar putea să vă placă și