FACComm.c
/****************************************************************************
Module
FACComm.c
****************************************************************************/
/*----------------------------- Include Files -----------------------------*/
// Basic includes for a program using the Events and Services Framework
#include "ES_Configure.h"
#include "ES_Framework.h"
#include "ES_ServiceHeaders.h"
#include "FACComm.h"
/*----------------------------- Module Defines ----------------------------*/
/*---------------------------- Module Functions ---------------------------*/
static ES_Event DuringStateOne( ES_Event Event);
static void QueryCurrentCommand(void );
static void QueryForResponse(void );
static char readMessage(void );
static void updateCounts(void );
/*---------------------------- Module Variables ---------------------------*/
static CommState_t CurrentState;
static char msg;
static coord coordinates[40];
static int blueShips;
static int redShips;
static int updateAll;
static boolean blueDisable;
static boolean redDisable;
static int active = 0;
static int currState = 0;
/*------------------------------ Module Code ------------------------------*/
/****************************************************************************
Function
RunCommSM
Parameters
ES_Event: the event to process
Returns
ES_Event: an event to return
Description
add your description here
Notes
uses nested switch/case to implement the machine.
Author
J. Edward Carryer, 2/11/05, 10:45AM
****************************************************************************/
ES_Event RunCommSM( ES_Event CurrentEvent )
{
unsigned char MakeTransition = False;/* are we making a state transition? */
CommState_t NextState = CurrentState;
ES_Event EntryEventKind = { ES_ENTRY, 0 };// default to normal entry to new state
ES_Event ReturnEvent = CurrentEvent; // assume we are not consuming event
ES_Event newEvent;
int recMsg;
int num;
int derp = 0;
switch ( CurrentState )
{
case Sending :
if ( CurrentEvent.EventType != ES_NO_EVENT ) //If an event is active
{
switch (CurrentEvent.EventType)
{
case ES_ENTRY:
active = 1;
// printf("Starting to query %X\r\n", msg);
break;
case ES_TIMEOUT :
if(CurrentEvent.EventParam == 0) //If event is timer 0 timeout
{
PTS &= BIT7LO;
QueryCurrentCommand();
break;
}
break;
case SPIFSet :
recMsg = readMessage() & 0xFF;
NextState = WaitFirst;
MakeTransition = True;
ReturnEvent = CurrentEvent;
break;
}
}
break;
//state machine for sending each
case WaitFirst :
if ( CurrentEvent.EventType != ES_NO_EVENT ) //If an event is active
{
switch (CurrentEvent.EventType)
{
case ES_ENTRY:
QueryForResponse();
break;
case SPIFSet :
// printf("Received");
recMsg = readMessage() & 0xFF;
// printf("%X\r\n", recMsg);
NextState = WaitSecond;
MakeTransition = True;
ReturnEvent = CurrentEvent;
break;
}
}
break;
case WaitSecond :
if ( CurrentEvent.EventType != ES_NO_EVENT ) //If an event is active
{
switch (CurrentEvent.EventType)
{
case ES_ENTRY:
QueryForResponse();
break;
case SPIFSet :
// printf("Received");
recMsg = readMessage() & 0xFF;
// printf("%X\r\n", recMsg);
if (msg == 0x3F)
{
} else
{
num = (msg & 0x3F);
coordinates[num].x = recMsg;
}
NextState = WaitThird;
MakeTransition = True;
ReturnEvent = CurrentEvent;
break;
}
}
break;
case WaitThird :
if ( CurrentEvent.EventType != ES_NO_EVENT ) //If an event is active
{
switch (CurrentEvent.EventType)
{
case ES_ENTRY:
QueryForResponse();
break;
case SPIFSet :
// printf("Received");
recMsg = readMessage() & 0xFF;
// printf("%X\r\n", recMsg);
if (msg == 0x3F)
{
} else
{
num = (msg & 0x3F);
coordinates[num].y = recMsg;
}
NextState = FACEnd;
MakeTransition = True;
ReturnEvent = CurrentEvent;
}
}
break;
case FACEnd :
if ( CurrentEvent.EventType != ES_NO_EVENT ) //If an event is active
{
switch (CurrentEvent.EventType)
{
case ES_ENTRY:
QueryForResponse();
break;
case SPIFSet :
// printf("Received");
recMsg = readMessage() & 0xFF;
// printf("%X\r\n", recMsg);
//If we were updating status, process status
if (msg == 0x3F)
{
if (recMsg & BIT7HI)
{
redDisable = TRUE;
} else
{
redDisable = FALSE;
}
if (recMsg & BIT6HI)
{
blueDisable = TRUE;
} else
{
blueDisable = FALSE;
}
if ((recMsg &= 0x0F) == 0x00)
{
}
if ((recMsg &= 0x0F) == 0x0A)
{
if (currState != 1 || QueryMasterSM() == WaitForStart)
{
newEvent.EventType = GameStart;
PostMasterSM(newEvent);
currState = 1;
}
}
if ((recMsg &= 0x0F) == 0x0B)
{
if (currState != 2)
{
newEvent.EventType = GameEnd;
PostMasterSM(newEvent);
currState = 2;
}
}
if ((recMsg &= 0x0F) == 0x0C)
{
if (currState != 2)
{
newEvent.EventType = GameEnd;
PostMasterSM(newEvent);
}
}
} else //Else we were updating a ship or bot, so update data for corresponding ship/bot
{
num = (msg & 0x3F);
coordinates[num].r = recMsg;
if (coordinates[num].x == 0 && coordinates[num].y == 0 && coordinates[num].r == 0)
{
coordinates[num].active = 0;
} else
{
coordinates[num].active = 1;
}
if (coordinates[num].x >= 128) // if blue
{
//Sectors for target processing
if (coordinates[num].y >= 111 && coordinates[num].y <= 143 && coordinates[num].x >= 96 && coordinates[num].x <= 160)
{
if(coordinates[num].x <=190)
{
coordinates[num].sector = 1;
} else if(coordinates[num].x > 190)
{
coordinates[num].sector = 4;
}
} else if (coordinates[num].y > (coordinates[num].x))
{
if(coordinates[num].x <=190)
{
coordinates[num].sector = 2;
} else if(coordinates[num].x > 190)
{
coordinates[num].sector = 5;
}
} else if (coordinates[num].y < (255-coordinates[num].x))
{
if(coordinates[num].x <=190)
{
coordinates[num].sector = 3;
} else if(coordinates[num].x > 190)
{
coordinates[num].sector = 6;
}
} else
{
coordinates[num].sector = 1;
}
}
if (coordinates[num].x < 128) // if red
{
if (coordinates[num].y >= 111 && coordinates[num].y <= 143 && coordinates[num].x >= 96 && coordinates[num].x <= 160)
{
coordinates[num].sector = 1;
} else if (coordinates[num].y < (coordinates[num].x))
{
if(coordinates[num].x >=64)
{
coordinates[num].sector = 2;
} else if(coordinates[num].x < 64)
{
coordinates[num].sector = 5;
}
} else if (coordinates[num].y > (255-coordinates[num].x))
{
if(coordinates[num].x >=64)
{
coordinates[num].sector = 3;
} else if(coordinates[num].x < 64)
{
coordinates[num].sector = 6;
}
} else
{
if(coordinates[num].x >=64)
{
coordinates[num].sector = 1;
} else if(coordinates[num].x < 64)
{
coordinates[num].sector = 4;
}
}
}
}
// printf("%d, x = %d, y = %d, r = %d\r\n", (msg & 0x3F), coordinates[num].x, coordinates[num].y, coordinates[num].r);
updateCounts();
//Switches from status message to update all if updateall flag is set, so they don't conflict.
if ((updateAll == 1) && ((msg & 0xFF) == 0x3F))
{
//printf("Switching to Update All from Status\r\n");
msg = 0xC3 & 0xFF;
NextState = Sending;
MakeTransition = True;
//printf("Updating\r\n");
ES_Timer_SetTimer(0, 2);
ES_Timer_StartTimer(0);
} else if ((updateAll == 1) && ((msg & 0xFF) != 0xE7)) //Loop for updating all ships/bots
{
//printf("Proceeding on\r\n");
msg++;
NextState = Sending;
MakeTransition = True;
ES_Timer_SetTimer(0, 2);
ES_Timer_StartTimer(0);
}
if ((updateAll == 1) && ((msg & 0xFF) == 0xE7)) //Finished loop
{
newEvent.EventType = UpdateFinish;
PostMasterSM(newEvent);
updateAll = 0;
}
//Sets slave select line
PTS |= BIT7HI;
active = 0;
break;
}
}
break;
// repeat state pattern as required for other states
}
// If we are making a state transition
if (MakeTransition == True)
{
// Execute exit function for current state
CurrentEvent.EventType = ES_EXIT;
RunCommSM(CurrentEvent);
CurrentState = NextState; //Modify state variable
// Execute entry function for new state
// this defaults to ES_ENTRY
RunCommSM(EntryEventKind);
}
return(CurrentEvent);
}
/****************************************************************************
Function
StartCommSM
Parameters
None
Returns
None
Description
Does any required initialization for this state machine
Notes
Author
J. Edward Carryer, 2/18/99, 10:38AM
****************************************************************************/
void StartCommSM ( ES_Event CurrentEvent, char sendMsg )
{
// local variable to get debugger to display the value of CurrentEvent
ES_Event LocalEvent = CurrentEvent;
// to implement entry to a history state or directly to a substate
// you can modify the initialization of the CurrentState variable
// otherwise just start in the entry state every time the state machine
// is started
if (active == 0) //Makes sure it doesn't interrupt an ongoing communication
{
msg = sendMsg;
ES_Timer_SetTimer(0, 2);
ES_Timer_StartTimer(0);
CurrentState = Sending;
active = 1;
// call the entry function (if any) for the ENTRY_STATE
RunCommSM(CurrentEvent);
}
}
/****************************************************************************
Function
QueryCommSM
Parameters
None
Returns
TemplateState_t The current state of the Template state machine
Description
returns the current state of the Template state machine
Notes
Author
J. Edward Carryer, 2/11/05, 10:38AM
****************************************************************************/
CommState_t QueryCommSM ( void )
{
return(CurrentState);
}
/***************************************************************************
private functions
***************************************************************************/
static void QueryCurrentCommand(void )
{
if ((SPISR & _S12_SPTEF) != 0)
{
// printf("Sending 0xAA\r\n");
SPIDR = msg;
} else
{
// printf("SPITEF not set \r\n");
}
}
static void QueryForResponse(void )
{
if ((SPISR & _S12_SPTEF) != 0)
{
// printf("Sending 0xAA\r\n");
SPIDR = 0x00;
} else
{
// printf("SPITEF not set \r\n");
}
}
static char readMessage(void )
{
char inputMessage;
if ((SPISR & _S12_SPIF) != 0)
{
inputMessage = SPIDR;
} else
{
//printf("SPIF not set\r\n");
}
return inputMessage;
}
static void updateCounts(void )
{
int i;
int blueShipCount = 0;
int redShipCount = 0;
for (i = 20; i < 30; i++)
{
if (coordinates[i].active == 1) redShipCount++;
}
for (i = 30; i < 40; i++)
{
if (coordinates[i].active == 1) blueShipCount++;
}
blueShips = blueShipCount;
redShips = redShipCount;
}
/*******************************
Public Functions
*******************************/
coord queryShip(int i)
{
return coordinates[i];
}
int queryRedShips(void )
{
return redShips;
}
int queryBlueShips(void )
{
return blueShips;
}
boolean queryActive(int i)
{
if (coordinates[i].active == 0)
{
return FALSE;
} else
{
return TRUE;
}
}
void updateFAC(void )
{
ES_Event currEvent;
updateAll = 1; //Sets update all flag, so even if active, will go into update all after finishing.
if (active == 0) //If not active, start state machine
{
//printf("Starting Update\r\n");
msg = 0xC3 & 0xFF;
currEvent.EventType = ES_ENTRY;
CurrentState = Sending;
//printf("Updating\r\n");
ES_Timer_SetTimer(0, 2);
ES_Timer_StartTimer(0);
RunCommSM(currEvent);
} else
{
}
}
boolean getBlueDisable(void )
{
return blueDisable;
}
boolean getRedDisable(void )
{
return redDisable;
}
Module
FACComm.c
****************************************************************************/
/*----------------------------- Include Files -----------------------------*/
// Basic includes for a program using the Events and Services Framework
#include "ES_Configure.h"
#include "ES_Framework.h"
#include "ES_ServiceHeaders.h"
#include "FACComm.h"
/*----------------------------- Module Defines ----------------------------*/
/*---------------------------- Module Functions ---------------------------*/
static ES_Event DuringStateOne( ES_Event Event);
static void QueryCurrentCommand(void );
static void QueryForResponse(void );
static char readMessage(void );
static void updateCounts(void );
/*---------------------------- Module Variables ---------------------------*/
static CommState_t CurrentState;
static char msg;
static coord coordinates[40];
static int blueShips;
static int redShips;
static int updateAll;
static boolean blueDisable;
static boolean redDisable;
static int active = 0;
static int currState = 0;
/*------------------------------ Module Code ------------------------------*/
/****************************************************************************
Function
RunCommSM
Parameters
ES_Event: the event to process
Returns
ES_Event: an event to return
Description
add your description here
Notes
uses nested switch/case to implement the machine.
Author
J. Edward Carryer, 2/11/05, 10:45AM
****************************************************************************/
ES_Event RunCommSM( ES_Event CurrentEvent )
{
unsigned char MakeTransition = False;/* are we making a state transition? */
CommState_t NextState = CurrentState;
ES_Event EntryEventKind = { ES_ENTRY, 0 };// default to normal entry to new state
ES_Event ReturnEvent = CurrentEvent; // assume we are not consuming event
ES_Event newEvent;
int recMsg;
int num;
int derp = 0;
switch ( CurrentState )
{
case Sending :
if ( CurrentEvent.EventType != ES_NO_EVENT ) //If an event is active
{
switch (CurrentEvent.EventType)
{
case ES_ENTRY:
active = 1;
// printf("Starting to query %X\r\n", msg);
break;
case ES_TIMEOUT :
if(CurrentEvent.EventParam == 0) //If event is timer 0 timeout
{
PTS &= BIT7LO;
QueryCurrentCommand();
break;
}
break;
case SPIFSet :
recMsg = readMessage() & 0xFF;
NextState = WaitFirst;
MakeTransition = True;
ReturnEvent = CurrentEvent;
break;
}
}
break;
//state machine for sending each
case WaitFirst :
if ( CurrentEvent.EventType != ES_NO_EVENT ) //If an event is active
{
switch (CurrentEvent.EventType)
{
case ES_ENTRY:
QueryForResponse();
break;
case SPIFSet :
// printf("Received");
recMsg = readMessage() & 0xFF;
// printf("%X\r\n", recMsg);
NextState = WaitSecond;
MakeTransition = True;
ReturnEvent = CurrentEvent;
break;
}
}
break;
case WaitSecond :
if ( CurrentEvent.EventType != ES_NO_EVENT ) //If an event is active
{
switch (CurrentEvent.EventType)
{
case ES_ENTRY:
QueryForResponse();
break;
case SPIFSet :
// printf("Received");
recMsg = readMessage() & 0xFF;
// printf("%X\r\n", recMsg);
if (msg == 0x3F)
{
} else
{
num = (msg & 0x3F);
coordinates[num].x = recMsg;
}
NextState = WaitThird;
MakeTransition = True;
ReturnEvent = CurrentEvent;
break;
}
}
break;
case WaitThird :
if ( CurrentEvent.EventType != ES_NO_EVENT ) //If an event is active
{
switch (CurrentEvent.EventType)
{
case ES_ENTRY:
QueryForResponse();
break;
case SPIFSet :
// printf("Received");
recMsg = readMessage() & 0xFF;
// printf("%X\r\n", recMsg);
if (msg == 0x3F)
{
} else
{
num = (msg & 0x3F);
coordinates[num].y = recMsg;
}
NextState = FACEnd;
MakeTransition = True;
ReturnEvent = CurrentEvent;
}
}
break;
case FACEnd :
if ( CurrentEvent.EventType != ES_NO_EVENT ) //If an event is active
{
switch (CurrentEvent.EventType)
{
case ES_ENTRY:
QueryForResponse();
break;
case SPIFSet :
// printf("Received");
recMsg = readMessage() & 0xFF;
// printf("%X\r\n", recMsg);
//If we were updating status, process status
if (msg == 0x3F)
{
if (recMsg & BIT7HI)
{
redDisable = TRUE;
} else
{
redDisable = FALSE;
}
if (recMsg & BIT6HI)
{
blueDisable = TRUE;
} else
{
blueDisable = FALSE;
}
if ((recMsg &= 0x0F) == 0x00)
{
}
if ((recMsg &= 0x0F) == 0x0A)
{
if (currState != 1 || QueryMasterSM() == WaitForStart)
{
newEvent.EventType = GameStart;
PostMasterSM(newEvent);
currState = 1;
}
}
if ((recMsg &= 0x0F) == 0x0B)
{
if (currState != 2)
{
newEvent.EventType = GameEnd;
PostMasterSM(newEvent);
currState = 2;
}
}
if ((recMsg &= 0x0F) == 0x0C)
{
if (currState != 2)
{
newEvent.EventType = GameEnd;
PostMasterSM(newEvent);
}
}
} else //Else we were updating a ship or bot, so update data for corresponding ship/bot
{
num = (msg & 0x3F);
coordinates[num].r = recMsg;
if (coordinates[num].x == 0 && coordinates[num].y == 0 && coordinates[num].r == 0)
{
coordinates[num].active = 0;
} else
{
coordinates[num].active = 1;
}
if (coordinates[num].x >= 128) // if blue
{
//Sectors for target processing
if (coordinates[num].y >= 111 && coordinates[num].y <= 143 && coordinates[num].x >= 96 && coordinates[num].x <= 160)
{
if(coordinates[num].x <=190)
{
coordinates[num].sector = 1;
} else if(coordinates[num].x > 190)
{
coordinates[num].sector = 4;
}
} else if (coordinates[num].y > (coordinates[num].x))
{
if(coordinates[num].x <=190)
{
coordinates[num].sector = 2;
} else if(coordinates[num].x > 190)
{
coordinates[num].sector = 5;
}
} else if (coordinates[num].y < (255-coordinates[num].x))
{
if(coordinates[num].x <=190)
{
coordinates[num].sector = 3;
} else if(coordinates[num].x > 190)
{
coordinates[num].sector = 6;
}
} else
{
coordinates[num].sector = 1;
}
}
if (coordinates[num].x < 128) // if red
{
if (coordinates[num].y >= 111 && coordinates[num].y <= 143 && coordinates[num].x >= 96 && coordinates[num].x <= 160)
{
coordinates[num].sector = 1;
} else if (coordinates[num].y < (coordinates[num].x))
{
if(coordinates[num].x >=64)
{
coordinates[num].sector = 2;
} else if(coordinates[num].x < 64)
{
coordinates[num].sector = 5;
}
} else if (coordinates[num].y > (255-coordinates[num].x))
{
if(coordinates[num].x >=64)
{
coordinates[num].sector = 3;
} else if(coordinates[num].x < 64)
{
coordinates[num].sector = 6;
}
} else
{
if(coordinates[num].x >=64)
{
coordinates[num].sector = 1;
} else if(coordinates[num].x < 64)
{
coordinates[num].sector = 4;
}
}
}
}
// printf("%d, x = %d, y = %d, r = %d\r\n", (msg & 0x3F), coordinates[num].x, coordinates[num].y, coordinates[num].r);
updateCounts();
//Switches from status message to update all if updateall flag is set, so they don't conflict.
if ((updateAll == 1) && ((msg & 0xFF) == 0x3F))
{
//printf("Switching to Update All from Status\r\n");
msg = 0xC3 & 0xFF;
NextState = Sending;
MakeTransition = True;
//printf("Updating\r\n");
ES_Timer_SetTimer(0, 2);
ES_Timer_StartTimer(0);
} else if ((updateAll == 1) && ((msg & 0xFF) != 0xE7)) //Loop for updating all ships/bots
{
//printf("Proceeding on\r\n");
msg++;
NextState = Sending;
MakeTransition = True;
ES_Timer_SetTimer(0, 2);
ES_Timer_StartTimer(0);
}
if ((updateAll == 1) && ((msg & 0xFF) == 0xE7)) //Finished loop
{
newEvent.EventType = UpdateFinish;
PostMasterSM(newEvent);
updateAll = 0;
}
//Sets slave select line
PTS |= BIT7HI;
active = 0;
break;
}
}
break;
// repeat state pattern as required for other states
}
// If we are making a state transition
if (MakeTransition == True)
{
// Execute exit function for current state
CurrentEvent.EventType = ES_EXIT;
RunCommSM(CurrentEvent);
CurrentState = NextState; //Modify state variable
// Execute entry function for new state
// this defaults to ES_ENTRY
RunCommSM(EntryEventKind);
}
return(CurrentEvent);
}
/****************************************************************************
Function
StartCommSM
Parameters
None
Returns
None
Description
Does any required initialization for this state machine
Notes
Author
J. Edward Carryer, 2/18/99, 10:38AM
****************************************************************************/
void StartCommSM ( ES_Event CurrentEvent, char sendMsg )
{
// local variable to get debugger to display the value of CurrentEvent
ES_Event LocalEvent = CurrentEvent;
// to implement entry to a history state or directly to a substate
// you can modify the initialization of the CurrentState variable
// otherwise just start in the entry state every time the state machine
// is started
if (active == 0) //Makes sure it doesn't interrupt an ongoing communication
{
msg = sendMsg;
ES_Timer_SetTimer(0, 2);
ES_Timer_StartTimer(0);
CurrentState = Sending;
active = 1;
// call the entry function (if any) for the ENTRY_STATE
RunCommSM(CurrentEvent);
}
}
/****************************************************************************
Function
QueryCommSM
Parameters
None
Returns
TemplateState_t The current state of the Template state machine
Description
returns the current state of the Template state machine
Notes
Author
J. Edward Carryer, 2/11/05, 10:38AM
****************************************************************************/
CommState_t QueryCommSM ( void )
{
return(CurrentState);
}
/***************************************************************************
private functions
***************************************************************************/
static void QueryCurrentCommand(void )
{
if ((SPISR & _S12_SPTEF) != 0)
{
// printf("Sending 0xAA\r\n");
SPIDR = msg;
} else
{
// printf("SPITEF not set \r\n");
}
}
static void QueryForResponse(void )
{
if ((SPISR & _S12_SPTEF) != 0)
{
// printf("Sending 0xAA\r\n");
SPIDR = 0x00;
} else
{
// printf("SPITEF not set \r\n");
}
}
static char readMessage(void )
{
char inputMessage;
if ((SPISR & _S12_SPIF) != 0)
{
inputMessage = SPIDR;
} else
{
//printf("SPIF not set\r\n");
}
return inputMessage;
}
static void updateCounts(void )
{
int i;
int blueShipCount = 0;
int redShipCount = 0;
for (i = 20; i < 30; i++)
{
if (coordinates[i].active == 1) redShipCount++;
}
for (i = 30; i < 40; i++)
{
if (coordinates[i].active == 1) blueShipCount++;
}
blueShips = blueShipCount;
redShips = redShipCount;
}
/*******************************
Public Functions
*******************************/
coord queryShip(int i)
{
return coordinates[i];
}
int queryRedShips(void )
{
return redShips;
}
int queryBlueShips(void )
{
return blueShips;
}
boolean queryActive(int i)
{
if (coordinates[i].active == 0)
{
return FALSE;
} else
{
return TRUE;
}
}
void updateFAC(void )
{
ES_Event currEvent;
updateAll = 1; //Sets update all flag, so even if active, will go into update all after finishing.
if (active == 0) //If not active, start state machine
{
//printf("Starting Update\r\n");
msg = 0xC3 & 0xFF;
currEvent.EventType = ES_ENTRY;
CurrentState = Sending;
//printf("Updating\r\n");
ES_Timer_SetTimer(0, 2);
ES_Timer_StartTimer(0);
RunCommSM(currEvent);
} else
{
}
}
boolean getBlueDisable(void )
{
return blueDisable;
}
boolean getRedDisable(void )
{
return redDisable;
}