This program utilizes the mcr20 Thread Shield on the FRDM-K64F MCU which is a two-part workspace (HVAC Server (RX)/Probe(TX)) to handle low temperature events read at the probe(s) to prevent pipes from freezing.

Dependencies:   fsl_phy_mcr20a fsl_smac mbed-rtos mbed

Fork of mcr20_wireless_uart by NXP

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 #include "rtos.h"
00003 
00004 #include "Phy.h"
00005 #include "SMAC_Interface.h"
00006 #include "SMAC_Config.h"
00007 #include "MemManager.h"
00008 #include "circular_buffer.h"
00009 
00010 char * const cu8FreescaleLogo[]={  
00011   "\f\r\n",
00012   "\n\r\n\r\n\r      #\n",
00013   "\r     ###\n",
00014   "\r    ###  *\n",
00015   "\r     #  ***\n",
00016   "\r       ***  #\n",
00017   "\r        *  ###\n",
00018   "\r          ###\n",
00019   "\r        *  #\n",
00020   "\r       ***\n",
00021   "\r      ***  #\n",
00022   "\r    #  *  ###\n",
00023   "\r   ###   ###\n",
00024   "\r  ###  *  #         F R E E S C A L E\n",
00025   "\r   #  ***\n",
00026   "\r     ***            S E M I C O N D U C T O R\n",
00027   "\r   #  *\n",
00028   "\r  ###               2 0 1 5\n",
00029   "\r ###\n",
00030   "\r  #           Wireless Uart Demo\r\n\n",
00031   NULL
00032 };
00033 
00034 #define gMcps_Cnf_EVENT_c        (1<<1)
00035 #define gMcps_Ind_EVENT_c        (1<<2)
00036 #define gMlme_EdCnf_EVENT_c      (1<<3)
00037 #define gMlme_CcaCnf_EVENT_c     (1<<4)
00038 #define gMlme_TimeoutInd_EVENT_c (1<<5)
00039 #define gWUSelf_EVENT_c          (1<<6)
00040 
00041 #define gDefaultBaudRate_UART_c 115200UL
00042 
00043 #define BUF_SIZE 3
00044 
00045 Serial uart(USBTX, USBRX);
00046 CircularBuffer uartBuf;
00047 
00048 
00049 #ifdef VERBOSE
00050 static bool_t bCCAFailed;
00051 static bool_t bACKFailed;
00052 #endif
00053 uint32_t gTaskEventFlags;
00054 int low_temp_flag = 0;
00055 int heat_state = 0;
00056 static uint8_t gau8TxDataBuffer[gMaxSmacSDULength_c  + sizeof(rxPacket_t)];  
00057 txPacket_t *gAppTxPacket;
00058 rxPacket_t *gAppRxPacket;
00059 static txContextConfig_t txConfigContext;
00060 
00061 
00062 void PrintMenu(char * const pu8Menu[])
00063 {
00064   uint8_t u8Index = 0;
00065   while(pu8Menu[u8Index]){
00066     uart.printf(pu8Menu[u8Index]);
00067     u8Index++;
00068   }
00069 }
00070 
00071 
00072 void InitProject(void);
00073 void InitApp(void);
00074 
00075 extern smacErrors_t smacToAppMlmeSap(smacToAppMlmeMessage_t* pMsg, instanceId_t instance);
00076 extern smacErrors_t smacToAppMcpsSap(smacToAppDataMessage_t* pMsg, instanceId_t instance);
00077 
00078 DigitalOut led1(LED_GREEN);
00079 DigitalOut led2(LED_RED);
00080 DigitalOut led3(LED_BLUE);
00081 InterruptIn sw2(SW2);
00082 uint32_t button_pressed;
00083 uint8_t timer;
00084 char temp[] = {'1','0','0'}; /*initialize temp to safe value*/
00085 Thread *thread2;
00086 Thread *eventsThread;
00087 Thread *timerThread;
00088 
00089 void uartSetBaudRate(uint32_t b)
00090 {
00091     uart.baud(b);
00092 }
00093 
00094 /*ISR for sw2*/
00095 void sw2_press(void)
00096 {
00097     thread2->signal_set(0x1);
00098     /*Toggle Blue LED*/
00099     led3 = !led3;
00100     
00101 }
00102 
00103 void timer_thread(void const *argument)
00104 {
00105     while (true) {
00106     
00107         Thread::wait(1000);
00108         /*Kick heat on (turn on Red LED) if temp drops below
00109          threshold and heat is not already on*/
00110         if((atoi(temp) <= 37) && (heat_state != 1))
00111         {
00112             low_temp_flag = 1;
00113             eventsThread->signal_set(0x1);
00114         }
00115                
00116         /*Normal temp, turn off heat*/
00117         if(atoi(temp) > 37)
00118         {
00119             /*Turn off Red LED*/
00120             led2 = 1;   
00121             
00122             /*Set heat_state to off*/
00123             heat_state = 0;
00124         }
00125     }
00126 }
00127 
00128 void led_thread(void const *argument)
00129 {
00130     while (true) {
00131         //led1 = !led1;
00132         Thread::wait(200);
00133     }
00134 }
00135 
00136 void button_thread(void const *argument)
00137 {
00138     while (true) {
00139         Thread::signal_wait(0x1);
00140         button_pressed++;
00141     }
00142 }
00143 
00144 void events_thread(void const *argument)
00145 {
00146     uint8_t rcvd = 0, c = 0; 
00147 
00148     while (true)
00149     {
00150         /*Wait for signal*/
00151         Thread::signal_wait(0x1);
00152         
00153         /*If packet has been sent, reenable recieving mode*/
00154         if(gMcps_Cnf_EVENT_c == (gTaskEventFlags & gMcps_Cnf_EVENT_c))
00155         {
00156             /*Reenable RX requests*/
00157             MLMERXEnableRequest(gAppRxPacket, 0); 
00158 
00159         }
00160         
00161         /*If a packet has been recieved, rcvd gets data*/
00162         if(gMcps_Ind_EVENT_c == (gTaskEventFlags & gMcps_Ind_EVENT_c))
00163         {
00164             
00165             for(int i = 0; i <= gAppRxPacket->u8DataLength; i++)
00166             {
00167                 rcvd = gAppRxPacket->smacPdu.smacPdu[i];
00168                 
00169                 /*Add received data to temp*/
00170                 temp[i] = rcvd;
00171                 
00172             }
00173             
00174             printf("Node Temp: %dF\n\r",atoi(temp));
00175             
00176             /*Reenable RX requests*/
00177             MLMERXEnableRequest(gAppRxPacket, 0);
00178 
00179             
00180         }
00181         
00182         if(gMlme_TimeoutInd_EVENT_c == (gTaskEventFlags & gMlme_TimeoutInd_EVENT_c))
00183         {
00184             uart.printf("MlmeTimeoutInd: \r\n");
00185         }
00186         
00187         if(gMlme_EdCnf_EVENT_c == (gTaskEventFlags & gMlme_EdCnf_EVENT_c))
00188         {
00189             uart.printf("EdCnf: \r\n");
00190         }
00191         
00192         if(gMlme_CcaCnf_EVENT_c == (gTaskEventFlags & gMlme_CcaCnf_EVENT_c))
00193         {
00194             uart.printf("CcaCnf: \r\n");
00195         }
00196         
00197         /*If there is something on the buffer, load packet and send*/
00198         if(gWUSelf_EVENT_c == (gTaskEventFlags & gWUSelf_EVENT_c))
00199         {
00200             
00201             /*Set Data Length to number of items on uartBuf*/
00202             gAppTxPacket->u8DataLength = uartBuf.getCount();
00203                 
00204             /*Load TX packets until uartBuf is empty*/
00205             for(int i = 0; uartBuf.getCount() > 0; i++)
00206             {
00207                 uartBuf.getFromBuffer(&c);
00208                 gAppTxPacket->smacPdu.smacPdu[i] = c;
00209             }
00210                 /*Disable RX requests (block incoming packets)*/
00211                 (void)MLMERXDisableRequest();
00212                 /*Generate request to send data packet*/
00213                 (void)MCPSDataRequest(gAppTxPacket);
00214                 
00215                 printf("Data Sent\n\r");
00216                 
00217                 /*Toggle Red LED after transmission*/
00218                 led2 = !led2;
00219             
00220         }
00221         
00222         if(low_temp_flag)
00223         {
00224             printf("WARNING: Node detected temp below safe threshold\n\r");
00225             printf("Suspect Node temp: %dF\n\r",atoi(temp));
00226             printf("Turning on heat..\n\r");
00227             
00228             /*Simulate heat by turning on red LED*/
00229             led2 = 0;
00230             
00231             /*Lower low_temp_flag*/
00232             low_temp_flag = 0;
00233             
00234             /*Set head_state to on*/
00235             heat_state = 1;
00236         }
00237        
00238         gTaskEventFlags = 0;
00239     }
00240 }
00241 
00242 int main()
00243 {    
00244     led1 = 1;/*Turn off Green LED*/
00245     led2 = 1;/*Turn off Red LED*/
00246     led3 = 1;/*Turn off Blue LED*/
00247   
00248     MEM_Init();
00249     Thread thread(led_thread);
00250     thread2 = new Thread(button_thread);
00251     eventsThread = new Thread(events_thread);
00252     timerThread = new Thread(timer_thread);
00253     Phy_Init();
00254     InitSmac();
00255     
00256     uartSetBaudRate(gDefaultBaudRate_UART_c);
00257     
00258     //Tell SMAC who to call when it needs to pass a message to the application thread.
00259     Smac_RegisterSapHandlers((SMAC_APP_MCPS_SapHandler_t)smacToAppMcpsSap,(SMAC_APP_MLME_SapHandler_t)smacToAppMlmeSap,0);
00260 
00261     InitApp();
00262     
00263     PrintMenu(cu8FreescaleLogo);
00264         
00265     button_pressed = 0;
00266     sw2.fall(&sw2_press);
00267     while (true) 
00268     {   
00269         /*Set signal for eventsThread if anything on uartBuf to be sent*/
00270         if ( uartBuf.getCount() )
00271         {
00272             gTaskEventFlags |= gWUSelf_EVENT_c;
00273             eventsThread->signal_set(0x1);
00274             
00275         }   
00276         Thread::yield();
00277     }
00278 }
00279 
00280 void InitApp()
00281 {
00282   gAppTxPacket = (txPacket_t*)gau8TxDataBuffer;   //Map TX packet to buffer
00283   gAppRxPacket = (rxPacket_t*)MEM_BufferAlloc(gMaxSmacSDULength_c + sizeof(rxPacket_t));
00284   
00285   InitProject();
00286   
00287   SMACFillHeader(&(gAppTxPacket->smacHeader), gDefaultAddress_c);                  
00288   
00289   (void)MLMEPAOutputAdjust(gDefaultOutputPower_c);
00290   (void)MLMESetChannelRequest(gDefaultChannelNumber_c);         
00291   (void)MLMEConfigureTxContext(&txConfigContext);
00292   //AppDelayTmr = TMR_AllocateTimer();
00293   gAppRxPacket->u8MaxDataLength = gMaxSmacSDULength_c;
00294   (void)MLMERXEnableRequest(gAppRxPacket, 0);
00295 }
00296 
00297 /* (Management) Sap handler for managing timeout indication and ED confirm
00298    This is running in INTERRUPT context, so need to send messages to one of the task */
00299 smacErrors_t smacToAppMlmeSap(smacToAppMlmeMessage_t* pMsg, instanceId_t instance)
00300 {
00301   switch(pMsg->msgType)
00302   {
00303     case gMlmeEdCnf_c:
00304         gTaskEventFlags |= gMlme_EdCnf_EVENT_c;
00305         break;
00306     case gMlmeCcaCnf_c:
00307         gTaskEventFlags |= gMlme_CcaCnf_EVENT_c;
00308         break;
00309     case gMlmeTimeoutInd_c:
00310         gTaskEventFlags |= gMlme_TimeoutInd_EVENT_c;
00311         break;
00312     default:
00313         break;
00314   }
00315   eventsThread->signal_set(0x1);
00316   MEM_BufferFree(pMsg);
00317   return gErrorNoError_c;
00318 }
00319 
00320 /* (Data) Sap handler for managing data confirm and data indication
00321    This is running in INTERRUPT context, so need to send messages to one of the task */
00322 smacErrors_t smacToAppMcpsSap(smacToAppDataMessage_t* pMsg, instanceId_t instance)
00323 {  
00324     switch(pMsg->msgType)
00325     {
00326         case gMcpsDataInd_c:
00327             if(pMsg->msgData.dataInd.pRxPacket->rxStatus == rxSuccessStatus_c)
00328             {       
00329                 gTaskEventFlags |= gMcps_Ind_EVENT_c;
00330             }
00331             break;
00332 
00333         case gMcpsDataCnf_c:
00334 #ifdef VERBOSE
00335             if(pMsg->msgData.dataCnf.status == gErrorChannelBusy_c)
00336             {
00337                 bCCAFailed = TRUE;
00338             }
00339 
00340             if(pMsg->msgData.dataCnf.status == gErrorNoAck_c)
00341             {
00342                 bACKFailed = TRUE;
00343             }
00344 #endif
00345 
00346             gTaskEventFlags |= gMcps_Cnf_EVENT_c;
00347             break;
00348 
00349         default:
00350             break;
00351     }
00352     eventsThread->signal_set(0x1);
00353     MEM_BufferFree(pMsg);
00354 
00355     return gErrorNoError_c;
00356 }
00357 
00358 void InitProject(void)
00359 {   
00360   /*Global Data init*/
00361 #ifdef VERBOSE
00362   bACKFailed                        = FALSE;
00363   bCCAFailed                        = FALSE;
00364 #endif
00365 
00366   gTaskEventFlags = 0;
00367 
00368   txConfigContext.autoAck           = FALSE;
00369   txConfigContext.ccaBeforeTx       = FALSE;
00370   txConfigContext.retryCountAckFail = 0;
00371   txConfigContext.retryCountCCAFail = 0;
00372 }