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:   DHT 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 #include "DHT.h"
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 DHT tempSensor(D4,DHT22);
00048 
00049 #ifdef VERBOSE
00050 static bool_t bCCAFailed;
00051 static bool_t bACKFailed;
00052 #endif
00053 uint32_t gTaskEventFlags;
00054 static uint8_t gau8TxDataBuffer[gMaxSmacSDULength_c  + sizeof(rxPacket_t)];  
00055 txPacket_t *gAppTxPacket;
00056 rxPacket_t *gAppRxPacket;
00057 static txContextConfig_t txConfigContext;
00058 
00059 
00060 void PrintMenu(char * const pu8Menu[])
00061 {
00062   uint8_t u8Index = 0;
00063   while(pu8Menu[u8Index]){
00064     uart.printf(pu8Menu[u8Index]);
00065     u8Index++;
00066   }
00067 }
00068 
00069 
00070 void InitProject(void);
00071 void InitApp(void);
00072 
00073 extern smacErrors_t smacToAppMlmeSap(smacToAppMlmeMessage_t* pMsg, instanceId_t instance);
00074 extern smacErrors_t smacToAppMcpsSap(smacToAppDataMessage_t* pMsg, instanceId_t instance);
00075 
00076 DigitalOut led1(LED_GREEN);
00077 DigitalOut led2(LED_RED);
00078 DigitalOut led3(LED_BLUE);
00079 InterruptIn sw2(SW2);
00080 uint32_t button_pressed;
00081 uint8_t timer;
00082 Thread *thread2;
00083 Thread *eventsThread;
00084 Thread *timerThread;
00085 
00086 void uartSetBaudRate(uint32_t b)
00087 {
00088     uart.baud(b);
00089 }
00090 
00091 /*ISR for sw2*/
00092 /*On sw2 press, spoof HVAC server by sending 30F as current temp*/
00093 void sw2_press(void)
00094 {      
00095     /*Add fake temp to buffer*/ 
00096     (void)uartBuf.addToBuffer('0');
00097     (void)uartBuf.addToBuffer('3');
00098     (void)uartBuf.addToBuffer('0');
00099     
00100     /*Set flags for TX in eventsThread and signal that an event has occured*/
00101     gTaskEventFlags |= gWUSelf_EVENT_c;
00102     thread2->signal_set(0x1);
00103     
00104 }
00105 
00106 void timer_thread(void const *argument)
00107 {
00108     char Buffer[BUF_SIZE];
00109     int temp = 0;
00110     int error = 0;
00111     
00112     while (true) {
00113     
00114         Thread::wait(1000);
00115         timer++;    
00116         
00117         printf("timer(%d)\n\r",timer);
00118         
00119         /*Update temp and load to Buffer every 10 seconds*/
00120         if(timer >= 10)
00121         {
00122             printf("Timer up! Preparing to send temp..\n\r");
00123             
00124             /*Reset timer*/
00125             timer = 0;
00126             
00127             /*Wait for tempSensor data to be ready*/
00128             error = tempSensor.readData();
00129             while(0 != error)
00130             {
00131                 error = tempSensor.readData();
00132             }
00133             
00134             temp = (int)tempSensor.ReadTemperature(FARENHEIT);
00135             
00136             /*Convert temp to ASCII and add to Buffer*/
00137             Buffer[0] = (temp / 100) + 0x30;//hundreds digit
00138             Buffer[1] = ((temp % 100) / 10) + 0x30;//tens digit
00139             Buffer[2] = ((temp % 100) % 10) + 0x30;//ones digit
00140                 
00141             /*Buffer gets ASCII conversion of temp*/
00142             for(int i = 0; i < sizeof(Buffer); i++)
00143             {
00144                 (void)uartBuf.addToBuffer(Buffer[i]);
00145             }/*end for*/
00146         }/*end if*/ 
00147     }/*end while*/
00148 }
00149 
00150 void led_thread(void const *argument)
00151 {
00152     while (true) {
00153         led1 = !led1;
00154         Thread::wait(200);
00155     }
00156 }
00157 
00158 void button_thread(void const *argument)
00159 {
00160     while (true) {
00161         Thread::signal_wait(0x1);
00162         button_pressed++;
00163     }
00164 }
00165 
00166 void events_thread(void const *argument)
00167 {
00168     uint8_t rcvd = 0, c = 0; 
00169 
00170     while (true)
00171     {
00172         /*Wait for signal*/
00173         Thread::signal_wait(0x1);
00174         
00175         /*If packet has been sent, reenable recieving mode*/
00176         if(gMcps_Cnf_EVENT_c == (gTaskEventFlags & gMcps_Cnf_EVENT_c))
00177         {
00178             /*Reenable RX requests*/
00179             MLMERXEnableRequest(gAppRxPacket, 0); 
00180 
00181         }
00182         
00183         /*If a packet has been recieved, rcvd gets data*/
00184         if(gMcps_Ind_EVENT_c == (gTaskEventFlags & gMcps_Ind_EVENT_c))
00185         {
00186             for(int i = 0; i <= gAppRxPacket->u8DataLength; i++)
00187             {
00188                 rcvd = gAppRxPacket->smacPdu.smacPdu[i];
00189                 uart.printf("%c", rcvd);
00190             }
00191             
00192             /*Reenable RX requests*/
00193             MLMERXEnableRequest(gAppRxPacket, 0);
00194 
00195             
00196         }
00197         
00198         if(gMlme_TimeoutInd_EVENT_c == (gTaskEventFlags & gMlme_TimeoutInd_EVENT_c))
00199         {
00200             uart.printf("MlmeTimeoutInd: \r\n");
00201         }
00202         
00203         if(gMlme_EdCnf_EVENT_c == (gTaskEventFlags & gMlme_EdCnf_EVENT_c))
00204         {
00205             uart.printf("EdCnf: \r\n");
00206         }
00207         
00208         if(gMlme_CcaCnf_EVENT_c == (gTaskEventFlags & gMlme_CcaCnf_EVENT_c))
00209         {
00210             uart.printf("CcaCnf: \r\n");
00211         }
00212         
00213         /*If there is something on the buffer, load packet and send*/
00214         if(gWUSelf_EVENT_c == (gTaskEventFlags & gWUSelf_EVENT_c))
00215         {
00216             
00217             /*Set Data Length to number of items on uartBuf*/
00218             gAppTxPacket->u8DataLength = uartBuf.getCount();
00219                 
00220             /*Load TX packets until uartBuf is empty*/
00221             for(int i = 0; uartBuf.getCount() > 0; i++)
00222             {
00223                 uartBuf.getFromBuffer(&c);
00224                 gAppTxPacket->smacPdu.smacPdu[i] = c;
00225             }
00226                 /*Disable RX requests (block incoming packets)*/
00227                 (void)MLMERXDisableRequest();
00228                 /*Generate request to send data packet*/
00229                 (void)MCPSDataRequest(gAppTxPacket);
00230                 
00231                 printf("Data Sent\n\r");
00232                 
00233                 /*Toggle Red LED after transmission*/
00234                 led2 = !led2;
00235             
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 }