![](/media/cache/group/NXP_logo_RGB_web.png.50x50_q85.jpg)
Rock, Paper, Scissors game - remote controller
Dependencies: fsl_phy_mcr20a fsl_smac mbed-rtos mbed
Fork of mcr20_RPS_GameController by
Revision 0:7654345263e0, committed 2015-11-17
- Comitter:
- mnorman4
- Date:
- Tue Nov 17 17:15:28 2015 +0000
- Commit message:
- Initial commit of Rock, Paper, Scissors game remote control
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/circular_buffer.cpp Tue Nov 17 17:15:28 2015 +0000 @@ -0,0 +1,77 @@ +#include "circular_buffer.h" + +CircularBuffer::CircularBuffer() +{ + size = gCircularBufferSize_c; + readIndex = 0; + writeIndex = 0; + count = 0; + MEM_Init(); + buffer = (uint8_t *) MEM_BufferAlloc(size * sizeof(uint8_t)); + if ( NULL == buffer ) + { + /*if buffer alloc fails stop the program execution*/ + while(1); + } +} + +CircularBuffer::CircularBuffer(uint32_t sz) +{ + size = sz; + readIndex = 0; + writeIndex = 0; + count = 0; + MEM_Init(); + buffer = (uint8_t *) MEM_BufferAlloc(size * sizeof(uint8_t)); + if ( NULL == buffer ) + { + /*if buffer alloc fails stop the program execution*/ + while(1); + } +} + +CircularBuffer::~CircularBuffer() +{ + size = 0; + readIndex = 0; + writeIndex = 0; + count = 0; + MEM_BufferFree(buffer); +} + +bufferStatus_t CircularBuffer :: addToBuffer (uint8_t c) +{ + buffer[writeIndex] = c; + writeIndex++; + if (writeIndex >= size) + { + writeIndex = 0; + } + count++; + if (count >= size) + { + return buffer_Full_c; + } + return buffer_Ok_c; +} + +bufferStatus_t CircularBuffer :: getFromBuffer (uint8_t *c) +{ + if ( 0 == count ) + { + return buffer_Empty_c; + } + (*c) = buffer[readIndex]; + readIndex++; + if (readIndex >= size) + { + readIndex = 0; + } + count--; + return buffer_Ok_c; +} + +uint32_t CircularBuffer :: getCount() +{ + return count; +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/circular_buffer.h Tue Nov 17 17:15:28 2015 +0000 @@ -0,0 +1,34 @@ +#ifndef __CIRCULAR_BUFFER_H__ +#define __CIRCULAR_BUFFER_H__ + +#include "EmbeddedTypes.h" +#include "MemManager.h" + +#ifndef gCircularBufferSize_c +#define gCircularBufferSize_c 32 +#endif + +typedef enum bufferStatus_tag +{ + buffer_Ok_c = 0, + buffer_Empty_c, + buffer_Full_c +}bufferStatus_t; + +class CircularBuffer { + public: + CircularBuffer(); + CircularBuffer(uint32_t sz); + ~CircularBuffer(); + bufferStatus_t addToBuffer (uint8_t c); + bufferStatus_t getFromBuffer (uint8_t *c); + uint32_t getCount(); + private: + uint8_t *buffer; + uint32_t size; + uint32_t readIndex; + uint32_t writeIndex; + uint32_t count; +}; + +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/fsl_phy_mcr20a.lib Tue Nov 17 17:15:28 2015 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/teams/Freescale/code/fsl_phy_mcr20a/#764779eedf2d
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/fsl_smac.lib Tue Nov 17 17:15:28 2015 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/teams/Freescale/code/fsl_smac/#401ba973869e
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Tue Nov 17 17:15:28 2015 +0000 @@ -0,0 +1,363 @@ +#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); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-rtos.lib Tue Nov 17 17:15:28 2015 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed-rtos/#6d90423c236e
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Tue Nov 17 17:15:28 2015 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/9296ab0bfc11 \ No newline at end of file