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
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 }
Generated on Tue Jul 12 2022 21:51:45 by 1.7.2