Rock, Paper, Scissors game - remote controller
Dependencies: fsl_phy_mcr20a fsl_smac mbed-rtos mbed
Fork of mcr20_RPS_GameController by
main.cpp
- Committer:
- mnorman4
- Date:
- 2015-11-17
- Revision:
- 0:7654345263e0
File content as of revision 0:7654345263e0:
#include "mbed.h" #include "rtos.h" #include "Phy.h" #include "SMAC_Interface.h" #include "SMAC_Config.h" #include "MemManager.h" #include "circular_buffer.h" /* Hardware Resources */ /* LEDs */ DigitalOut k64f_led_red(LED_RED, 1); DigitalOut k64f_led_green(LED_GREEN, 1); DigitalOut k64f_led_blue(LED_BLUE, 1); DigitalOut cr20a_led_red(PTC11, 1); DigitalOut cr20a_led_green(PTC10, 1); DigitalOut cr20a_led_blue(PTB11, 1); #define LED_ON (0) #define LED_OFF (1) /* Pushbuttons */ InterruptIn k64f_sw2(SW2); InterruptIn k64f_sw3(SW3); InterruptIn cr20a_sw1(PTB23); InterruptIn cr20a_sw2(PTA1); InterruptIn cr20a_sw3(PTC4); #define gPushbutton_K64F_SW2 (1<<0) #define gPushbutton_K64F_SW3 (1<<1) #define gPushbutton_CR20A_SW1 (1<<2) #define gPushbutton_CR20A_SW2 (1<<3) #define gPushbutton_CR20A_SW3 (1<<4) #define gResultWin (1<<0) #define gResultLose (1<<1) #define gResultDraw (1<<2) /* OpenSDA Serial Port (UART) */ Serial uart(USBTX, USBRX); CircularBuffer uartBuf; #define gDefaultBaudRate_UART_c 115200UL /* Event Flags */ #define gMcps_Cnf_EVENT_c (1<<1) #define gMcps_Ind_EVENT_c (1<<2) #define gMlme_EdCnf_EVENT_c (1<<3) #define gMlme_CcaCnf_EVENT_c (1<<4) #define gMlme_TimeoutInd_EVENT_c (1<<5) #define gWUSelf_EVENT_c (1<<6) #ifdef VERBOSE static bool_t bCCAFailed; static bool_t bACKFailed; #endif uint32_t gTaskEventFlags; static uint8_t gau8TxDataBuffer[gMaxSmacSDULength_c + sizeof(rxPacket_t)]; txPacket_t *gAppTxPacket; rxPacket_t *gAppRxPacket; static txContextConfig_t txConfigContext; void InitProject(void); void InitApp(void); extern smacErrors_t smacToAppMlmeSap(smacToAppMlmeMessage_t* pMsg, instanceId_t instance); extern smacErrors_t smacToAppMcpsSap(smacToAppDataMessage_t* pMsg, instanceId_t instance); osThreadId PushbuttonThreadID; osThreadId ResultThreadID; osThreadId EventsThreadID; osThreadId MainThreadID; void k64f_sw2_press(void) { osSignalSet(PushbuttonThreadID, gPushbutton_K64F_SW2); } void k64f_sw3_press(void) { osSignalSet(PushbuttonThreadID, gPushbutton_K64F_SW3); } void cr20a_sw1_press(void) { osSignalSet(PushbuttonThreadID, gPushbutton_CR20A_SW1); } void cr20a_sw2_press(void) { osSignalSet(PushbuttonThreadID, gPushbutton_CR20A_SW2); } void cr20a_sw3_press(void) { osSignalSet(PushbuttonThreadID, gPushbutton_CR20A_SW3); } void HeartbeatThread(void const *argument) { while (true) { k64f_led_green = LED_ON; Thread::wait(50); k64f_led_green = LED_OFF; Thread::wait(1950); } } void ResultThread(void const *argument) { ResultThreadID = Thread::gettid(); osEvent event; DigitalOut *led; while (true) { event = Thread::signal_wait(0, osWaitForever); if (event.value.signals & gResultWin) { led = &cr20a_led_green; } else if (event.value.signals & gResultDraw) { led = &cr20a_led_blue; } else { led = &cr20a_led_red; } *led = LED_ON; Thread::wait(200); *led = LED_OFF; Thread::wait(200); *led = LED_ON; Thread::wait(200); *led = LED_OFF; Thread::wait(200); *led = LED_ON; Thread::wait(200); *led = LED_OFF; Thread::wait(200); *led = LED_ON; Thread::wait(200); *led = LED_OFF; Thread::wait(200); *led = LED_ON; Thread::wait(200); *led = LED_OFF; Thread::wait(200); *led = LED_ON; Thread::wait(200); *led = LED_OFF; } } /* Constants used to build the single byte game selection and results */ char const PlayerA = 0xA0; char const PlayerB = 0xB0; char const Player = PlayerB; char const Rock = 0x01; char const Paper = 0x02; char const Scissors = 0x03; char const Winner = 0x08; char const Loser = 0x0F; char const Draw = 0xFF; void PushbuttonThread(void const *argument) { PushbuttonThreadID = Thread::gettid(); osEvent event; while (true) { event = Thread::signal_wait(0, osWaitForever); if (event.value.signals & gPushbutton_CR20A_SW1) { (void)uartBuf.addToBuffer(uint8_t(Player | Rock)); } if (event.value.signals & gPushbutton_CR20A_SW2) { (void)uartBuf.addToBuffer(uint8_t(Player | Paper)); } if (event.value.signals & gPushbutton_CR20A_SW3) { (void)uartBuf.addToBuffer(uint8_t(Player | Scissors)); } if (uartBuf.getCount()) { gTaskEventFlags |= gWUSelf_EVENT_c; osSignalSet(EventsThreadID, 0x1); } Thread::wait(500); osSignalClear(PushbuttonThreadID, 0xFF); } } void CheckReceivedData (uint8_t data) { uint8_t player = (data & 0xF0); uint8_t result = (data & 0x0F); if (result == Winner) { if (player == Player) osSignalSet(ResultThreadID, gResultWin); else osSignalSet(ResultThreadID, gResultLose); } if (data == Draw) osSignalSet(ResultThreadID, gResultDraw); } void EventsThread(void const *argument) { EventsThreadID = Thread::gettid(); uint8_t rcvd = 0, c = 0; while (true) { Thread::signal_wait(0x1); if(gMcps_Cnf_EVENT_c == (gTaskEventFlags & gMcps_Cnf_EVENT_c)) { MLMERXEnableRequest(gAppRxPacket, 0); } if(gMcps_Ind_EVENT_c == (gTaskEventFlags & gMcps_Ind_EVENT_c)) { rcvd = gAppRxPacket->smacPdu.smacPdu[0]; //uart.printf("%c", rcvd); CheckReceivedData(rcvd); MLMERXEnableRequest(gAppRxPacket, 0); } if(gMlme_TimeoutInd_EVENT_c == (gTaskEventFlags & gMlme_TimeoutInd_EVENT_c)) { uart.printf("MlmeTimeoutInd: \r\n"); } if(gMlme_EdCnf_EVENT_c == (gTaskEventFlags & gMlme_EdCnf_EVENT_c)) { uart.printf("EdCnf: \r\n"); } if(gMlme_CcaCnf_EVENT_c == (gTaskEventFlags & gMlme_CcaCnf_EVENT_c)) { uart.printf("CcaCnf: \r\n"); } if(gWUSelf_EVENT_c == (gTaskEventFlags & gWUSelf_EVENT_c)) { if (buffer_Ok_c == uartBuf.getFromBuffer(&c)) { gAppTxPacket->smacPdu.smacPdu[0] = c; gAppTxPacket->u8DataLength = 1; (void)MLMERXDisableRequest(); (void)MCPSDataRequest(gAppTxPacket); } } gTaskEventFlags = 0; } } int main() { MEM_Init(); /* Init the threads */ Thread heartbeat(HeartbeatThread); Thread pushbuttons(PushbuttonThread); Thread events(EventsThread); Thread result(ResultThread); MainThreadID = Thread::gettid(); Phy_Init(); InitSmac(); //Tell SMAC who to call when it needs to pass a message to the application thread. Smac_RegisterSapHandlers((SMAC_APP_MCPS_SapHandler_t)smacToAppMcpsSap,(SMAC_APP_MLME_SapHandler_t)smacToAppMlmeSap,0); InitApp(); if (Player == 0xA0) uart.printf("Player A is online\r\n"); else uart.printf("Player B is online\r\n"); while (true) { Thread::yield(); } } void InitApp() { gAppTxPacket = (txPacket_t*)gau8TxDataBuffer; //Map TX packet to buffer gAppRxPacket = (rxPacket_t*)MEM_BufferAlloc(gMaxSmacSDULength_c + sizeof(rxPacket_t)); InitProject(); SMACFillHeader(&(gAppTxPacket->smacHeader), gDefaultAddress_c); (void)MLMEPAOutputAdjust(gDefaultOutputPower_c); (void)MLMESetChannelRequest(gDefaultChannelNumber_c); (void)MLMEConfigureTxContext(&txConfigContext); //AppDelayTmr = TMR_AllocateTimer(); gAppRxPacket->u8MaxDataLength = gMaxSmacSDULength_c; (void)MLMERXEnableRequest(gAppRxPacket, 0); } /* (Management) Sap handler for managing timeout indication and ED confirm This is running in INTERRUPT context, so need to send messages to one of the task */ smacErrors_t smacToAppMlmeSap(smacToAppMlmeMessage_t* pMsg, instanceId_t instance) { switch(pMsg->msgType) { case gMlmeEdCnf_c: gTaskEventFlags |= gMlme_EdCnf_EVENT_c; break; case gMlmeCcaCnf_c: gTaskEventFlags |= gMlme_CcaCnf_EVENT_c; break; case gMlmeTimeoutInd_c: gTaskEventFlags |= gMlme_TimeoutInd_EVENT_c; break; default: break; } osSignalSet(EventsThreadID, 0x1); MEM_BufferFree(pMsg); return gErrorNoError_c; } /* (Data) Sap handler for managing data confirm and data indication This is running in INTERRUPT context, so need to send messages to one of the task */ smacErrors_t smacToAppMcpsSap(smacToAppDataMessage_t* pMsg, instanceId_t instance) { switch(pMsg->msgType) { case gMcpsDataInd_c: if(pMsg->msgData.dataInd.pRxPacket->rxStatus == rxSuccessStatus_c) { gTaskEventFlags |= gMcps_Ind_EVENT_c; } break; case gMcpsDataCnf_c: #ifdef VERBOSE if(pMsg->msgData.dataCnf.status == gErrorChannelBusy_c) { bCCAFailed = TRUE; } if(pMsg->msgData.dataCnf.status == gErrorNoAck_c) { bACKFailed = TRUE; } #endif gTaskEventFlags |= gMcps_Cnf_EVENT_c; break; default: break; } osSignalSet(EventsThreadID, 0x1); MEM_BufferFree(pMsg); return gErrorNoError_c; } void InitProject(void) { /*Global Data init*/ #ifdef VERBOSE bACKFailed = FALSE; bCCAFailed = FALSE; #endif gTaskEventFlags = 0; txConfigContext.autoAck = FALSE; txConfigContext.ccaBeforeTx = FALSE; txConfigContext.retryCountAckFail = 0; txConfigContext.retryCountCCAFail = 0; /* Setup UART */ uart.baud(gDefaultBaudRate_UART_c); /* Setup Pushbutton Interrupt Callbacks */ k64f_sw2.fall(&k64f_sw2_press); k64f_sw3.fall(&k64f_sw3_press); cr20a_sw1.fall(&cr20a_sw1_press); cr20a_sw2.fall(&cr20a_sw2_press); cr20a_sw3.fall(&cr20a_sw3_press); }