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
main.cpp
- Committer:
- haircules
- Date:
- 2017-03-30
- Revision:
- 29:c49f83ab80bd
- Parent:
- 27:1eb29717bfd9
File content as of revision 29:c49f83ab80bd:
#include "mbed.h" #include "rtos.h" #include "DHT.h" #include "Phy.h" #include "SMAC_Interface.h" #include "SMAC_Config.h" #include "MemManager.h" #include "circular_buffer.h" char * const cu8FreescaleLogo[]={ "\f\r\n", "\n\r\n\r\n\r #\n", "\r ###\n", "\r ### *\n", "\r # ***\n", "\r *** #\n", "\r * ###\n", "\r ###\n", "\r * #\n", "\r ***\n", "\r *** #\n", "\r # * ###\n", "\r ### ###\n", "\r ### * # F R E E S C A L E\n", "\r # ***\n", "\r *** S E M I C O N D U C T O R\n", "\r # *\n", "\r ### 2 0 1 5\n", "\r ###\n", "\r # Wireless Uart Demo\r\n\n", NULL }; #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) #define gDefaultBaudRate_UART_c 115200UL #define BUF_SIZE 3 Serial uart(USBTX, USBRX); CircularBuffer uartBuf; DHT tempSensor(D4,DHT22); #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 PrintMenu(char * const pu8Menu[]) { uint8_t u8Index = 0; while(pu8Menu[u8Index]){ uart.printf(pu8Menu[u8Index]); u8Index++; } } 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); DigitalOut led1(LED_GREEN); DigitalOut led2(LED_RED); DigitalOut led3(LED_BLUE); InterruptIn sw2(SW2); uint32_t button_pressed; uint8_t timer; Thread *thread2; Thread *eventsThread; Thread *timerThread; void uartSetBaudRate(uint32_t b) { uart.baud(b); } /*ISR for sw2*/ /*On sw2 press, spoof HVAC server by sending 30F as current temp*/ void sw2_press(void) { /*Add fake temp to buffer*/ (void)uartBuf.addToBuffer('0'); (void)uartBuf.addToBuffer('3'); (void)uartBuf.addToBuffer('0'); /*Set flags for TX in eventsThread and signal that an event has occured*/ gTaskEventFlags |= gWUSelf_EVENT_c; thread2->signal_set(0x1); } void timer_thread(void const *argument) { char Buffer[BUF_SIZE]; int temp = 0; int error = 0; while (true) { Thread::wait(1000); timer++; printf("timer(%d)\n\r",timer); /*Update temp and load to Buffer every 10 seconds*/ if(timer >= 10) { printf("Timer up! Preparing to send temp..\n\r"); /*Reset timer*/ timer = 0; /*Wait for tempSensor data to be ready*/ error = tempSensor.readData(); while(0 != error) { error = tempSensor.readData(); } temp = (int)tempSensor.ReadTemperature(FARENHEIT); /*Convert temp to ASCII and add to Buffer*/ Buffer[0] = (temp / 100) + 0x30;//hundreds digit Buffer[1] = ((temp % 100) / 10) + 0x30;//tens digit Buffer[2] = ((temp % 100) % 10) + 0x30;//ones digit /*Buffer gets ASCII conversion of temp*/ for(int i = 0; i < sizeof(Buffer); i++) { (void)uartBuf.addToBuffer(Buffer[i]); }/*end for*/ }/*end if*/ }/*end while*/ } void led_thread(void const *argument) { while (true) { led1 = !led1; Thread::wait(200); } } void button_thread(void const *argument) { while (true) { Thread::signal_wait(0x1); button_pressed++; } } void events_thread(void const *argument) { uint8_t rcvd = 0, c = 0; while (true) { /*Wait for signal*/ Thread::signal_wait(0x1); /*If packet has been sent, reenable recieving mode*/ if(gMcps_Cnf_EVENT_c == (gTaskEventFlags & gMcps_Cnf_EVENT_c)) { /*Reenable RX requests*/ MLMERXEnableRequest(gAppRxPacket, 0); } /*If a packet has been recieved, rcvd gets data*/ if(gMcps_Ind_EVENT_c == (gTaskEventFlags & gMcps_Ind_EVENT_c)) { for(int i = 0; i <= gAppRxPacket->u8DataLength; i++) { rcvd = gAppRxPacket->smacPdu.smacPdu[i]; uart.printf("%c", rcvd); } /*Reenable RX requests*/ 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 there is something on the buffer, load packet and send*/ if(gWUSelf_EVENT_c == (gTaskEventFlags & gWUSelf_EVENT_c)) { /*Set Data Length to number of items on uartBuf*/ gAppTxPacket->u8DataLength = uartBuf.getCount(); /*Load TX packets until uartBuf is empty*/ for(int i = 0; uartBuf.getCount() > 0; i++) { uartBuf.getFromBuffer(&c); gAppTxPacket->smacPdu.smacPdu[i] = c; } /*Disable RX requests (block incoming packets)*/ (void)MLMERXDisableRequest(); /*Generate request to send data packet*/ (void)MCPSDataRequest(gAppTxPacket); printf("Data Sent\n\r"); /*Toggle Red LED after transmission*/ led2 = !led2; } gTaskEventFlags = 0; } } int main() { led1 = 1;/*Turn off Green LED*/ led2 = 1;/*Turn off Red LED*/ led3 = 1;/*Turn off Blue LED*/ MEM_Init(); Thread thread(led_thread); thread2 = new Thread(button_thread); eventsThread = new Thread(events_thread); timerThread = new Thread(timer_thread); Phy_Init(); InitSmac(); uartSetBaudRate(gDefaultBaudRate_UART_c); //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(); PrintMenu(cu8FreescaleLogo); button_pressed = 0; sw2.fall(&sw2_press); while (true) { /*Set signal for eventsThread if anything on uartBuf to be sent*/ if ( uartBuf.getCount() ) { gTaskEventFlags |= gWUSelf_EVENT_c; eventsThread->signal_set(0x1); } 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; } eventsThread->signal_set(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; } eventsThread->signal_set(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; }