The MCR20A Wireless UART application functions as an wireless UART bridge between two (one-to-one) or several (one to many) boards. The application can be used with both a TERM, or with software that is capable of opening a serial port and writing to or reading from it. The characters sent or received are not necessarily ASCII printable characters.

Dependencies:   fsl_phy_mcr20a fsl_smac mbed-rtos mbed

Fork of mcr20_wireless_uart by Freescale

By default, the application uses broadcast addresses for OTA communication. This way, the application can be directly downloaded and run without any user intervention. The following use case assumes no changes have been done to the project.

  • Two (or more) MCR20A platforms (plugged into the FRDM-K64F Freescale Freedom Development platform) have to be connected to the PC using the mini/micro-USB cables.
  • The code must be downloaded on the platforms via CMSIS-DAP (or other means).
  • After that, two or more TERM applications must be opened, and the serial ports must be configured with the same baud rate as the one in the project (default baud rate is 115200). Other necessary serial configurations are 8 bit, no parity, and 1 stop bit.
  • To start the setup, each platform must be reset, and one of the (user) push buttons found on the MCR20A platform must be pressed. The user can press any of the non-reset buttons on the FRDM-K64F Freescale Freedom Development platform as well. *This initiates the state machine of the application so user can start.

Documentation

SMAC Demo Applications User Guide

Revision:
23:6f13fea3cace
Parent:
19:71b793021c78
Child:
24:088286081619
--- a/main.cpp	Fri Apr 24 22:54:35 2015 +0000
+++ b/main.cpp	Sat Apr 25 00:50:20 2015 -0500
@@ -1,25 +1,30 @@
 #include "mbed.h"
 #include "rtos.h"
 
+#include "Phy.h"
 #include "SMAC_Interface.h"
 #include "SMAC_Config.h"
 
-static uint8_t mAppSer;
-static uint8_t timePassed;       
+#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
-static bool_t bTxDone;
-static bool_t bRxDone;
-static bool_t evKeyPressed;
-static bool_t bTxInProgress;
+uint32_t gTaskEventFlags;
 static uint8_t gau8TxDataBuffer[gMaxSmacSDULength_c  + sizeof(rxPacket_t)];  
 static txPacket_t *gAppTxPacket;
 static 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);
 
@@ -27,6 +32,7 @@
 InterruptIn sw2(SW2);
 uint32_t button_pressed;
 Thread *thread2;
+Thread *eventsThread;
 
 void sw2_press(void)
 {
@@ -49,91 +55,163 @@
     }
 }
 
+void events_thread(void const *argument)
+{
+    uint8_t rcvd = 0;
+
+    while (true)
+    {
+        Thread::signal_wait(0x1);
+
+        if(gMcps_Cnf_EVENT_c == (gTaskEventFlags & gMcps_Cnf_EVENT_c))
+        {
+            //get back in RX
+            MLMERXEnableRequest(gAppRxPacket, 0); 
+
+            //printf("McpsDataCnf: Packet sent\r\n");
+        }
+        
+        if(gMcps_Ind_EVENT_c == (gTaskEventFlags & gMcps_Ind_EVENT_c))
+        {
+            rcvd = gAppRxPacket->smacPdu.smacPdu[0];
+
+            //get back in RX
+            //gAppRxPacket = (rxPacket_t*)MEM_BufferAlloc(gMaxSmacSDULength_c + sizeof(rxPacket_t));
+            //gAppRxPacket->u8MaxDataLength = gMaxSmacSDULength_c;
+            MLMERXEnableRequest(gAppRxPacket, 0);
+
+            printf("McpsDataInd: Received %d\r\n", rcvd);
+        }
+        
+        if(gMlme_TimeoutInd_EVENT_c == (gTaskEventFlags & gMlme_TimeoutInd_EVENT_c))
+        {
+            //printf("MlmeTimeoutInd: \r\n");
+        }
+        
+        if(gMlme_EdCnf_EVENT_c == (gTaskEventFlags & gMlme_EdCnf_EVENT_c))
+        {
+            //printf("EdCnf: \r\n");
+        }
+        
+        if(gMlme_CcaCnf_EVENT_c == (gTaskEventFlags & gMlme_CcaCnf_EVENT_c))
+        {
+            //printf("CcaCnf: \r\n");
+        }
+        
+        if(gWUSelf_EVENT_c == (gTaskEventFlags & gWUSelf_EVENT_c))
+        {
+
+        }
+
+        gTaskEventFlags = 0;
+    }
+}
+
 int main()
 {
     Thread thread(led_thread);
     thread2 = new Thread(button_thread);
-    
+    eventsThread = new Thread(events_thread);
+
+    Phy_Init();
     InitSmac();
-    Smac_RegisterSapHandlers((SMAC_APP_MCPS_SapHandler_t)smacToAppMcpsSap,(SMAC_APP_MLME_SapHandler_t)smacToAppMlmeSap,0);
-    
-    InitProject();
-
-    gAppTxPacket = (txPacket_t*)gau8TxDataBuffer;   //Map TX packet to buffer
-    gAppRxPacket = (rxPacket_t*)MEM_BufferAlloc(gMaxSmacSDULength_c + sizeof(rxPacket_t));
 
-    SMACFillHeader(&(gAppTxPacket->smacHeader), gDefaultAddress_c);                  
-    
-    (void)MLMEPAOutputAdjust(gDefaultOutputPower_c);
-    (void)MLMESetChannelRequest(gDefaultChannelNumber_c);         
-    (void)MLMEConfigureTxContext(&txConfigContext);
-    gAppRxPacket->u8MaxDataLength = gMaxSmacSDULength_c;
-    (void)MLMERXEnableRequest(gAppRxPacket, 0);
-    
+    //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();
+	    
     button_pressed = 0;
     sw2.fall(&sw2_press);
     while (true) {
         Thread::wait(5000);
+        gAppTxPacket->smacPdu.smacPdu[0] = (uint8_t)button_pressed;
+        gAppTxPacket->u8DataLength = 1;
+        (void)MLMERXDisableRequest();
+        (void)MCPSDataRequest(gAppTxPacket);
         printf("SW2 was pressed (last 5 seconds): %d \r\n", button_pressed);
         fflush(stdout);
         button_pressed = 0;
     }
 }
 
+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:
-    printf("EdCnf: \r\n");
-     //(void)OSA_EventSet(&gTaskEvent, gMlme_EdCnf_EVENT_c);
-    break;
-  case gMlmeCcaCnf_c:
-    printf("CcaCnf: \r\n");
-    //(void)OSA_EventSet(&gTaskEvent, gMlme_CcaCnf_EVENT_c);
-    break;
-  case gMlmeTimeoutInd_c:
-    printf("MlmeTimeoutInd: \r\n");
-     //(void)OSA_EventSet(&gTaskEvent, gMlme_TimeoutInd_EVENT_c);
-     break;
-  default:
-    break;
+    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;
   }
+  eventsThread->signal_set(0x1);
   MEM_BufferFree(pMsg);
   return gErrorNoError_c;
 }
 
-//(Data) Sap handler for managing data confirm and data indication
+/* (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)
-    {
-      printf("McpsDataInd: \r\n");
-      //(void)OSA_EventSet(&gTaskEvent, gMcps_Ind_EVENT_c);
-    }
-    break;
-  case gMcpsDataCnf_c:
-#ifdef VERBOSE
-    if(pMsg->msgData.dataCnf.status == gErrorChannelBusy_c)
+{  
+    switch(pMsg->msgType)
     {
-      bCCAFailed = TRUE;
-    }
-    if(pMsg->msgData.dataCnf.status == gErrorNoAck_c)
-    {
-      bACKFailed = TRUE;
-    }
+        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
-    printf("McpsDataCnf: \r\n");
-    //(void)OSA_EventSet(&gTaskEvent, gMcps_Cnf_EVENT_c);
-    break;
-  default:
-    break;
-  }
-  MEM_BufferFree(pMsg);
-  return gErrorNoError_c;
+
+            gTaskEventFlags |= gMcps_Cnf_EVENT_c;
+            break;
+
+        default:
+            break;
+    }
+    
+    eventsThread->signal_set(0x1);
+    MEM_BufferFree(pMsg);
+
+    return gErrorNoError_c;
 }
 
 void InitProject(void)
@@ -143,11 +221,11 @@
   bACKFailed                        = FALSE;
   bCCAFailed                        = FALSE;
 #endif
-  bTxInProgress                     = FALSE;
-  bTxDone                           = FALSE;
-  evKeyPressed                      = FALSE;
+
+  gTaskEventFlags = 0;
+
   txConfigContext.autoAck           = FALSE;
   txConfigContext.ccaBeforeTx       = FALSE;
   txConfigContext.retryCountAckFail = 0;
   txConfigContext.retryCountCCAFail = 0;
-}
\ No newline at end of file
+}