;=============================================================================== ; SPLat Controls. ; ; Product Development Group ; ; Melbourne, AUSTRALIA ; ;=============================================================================== ;PURPOSE: ; SX10509 sandbox example application. ; Performs basic communication with the SPLat Call Home sandbox page online ;This program is meant to be used in conjunction with the "Tutorial: SPLat Call Home (SX10509) programming" ;in the SPLat Knowledge Base at http://splatco.com/skb/5168.htm ;================ I/O Assignments ===================== ;== MMi202 == ;--- Digital Inputs --- ;iBtnA iEQU 12 ;iBtnB iEQU 11 ;iBtnC iEQU 10 ;iBtnD iEQU 9 ;iBtnE iEQU 8 ;--- LEDs --- ;oLED0 oEQU 15 ;Top ;oLED1 oEQU 14 ;oLED2 oEQU 13 ;oLED3 oEQU 12 ;oLED4 oEQU 11 ;oLED5 oEQU 10 ;oLED6 oEQU 8 ;== MS120 == ;--- Digital Inputs --- iBtnA iEQU 12 ;Top left iBtnB iEQU 13 iBtnC iEQU 14 iBtnD iEQU 15 iBtnE iEQU 16 ;--- LEDs --- oLED0 oEQU 8 ;Right oLED1 oEQU 9 oLED2 oEQU 10 oLED3 oEQU 11 ; ;=============================================================================== ;-- SX10509 Network Commands kCMD_Idle EQU '00 kCMD_Write EQU '01 kCMD_Read EQU '02 kCMD_Server EQU '03 kCMD_Port EQU '04 kCMD_PathA EQU '05 kCMD_ContentType EQU '06 kCMD_DoGet EQU '07 kCMD_DoPost EQU '08 kCMD_GetID EQU '09 kCMD_GetGMT EQU '0A kCMD_GetIP EQU '0B ;=============================================================================== ; Xwire data blocks ;=============================================================================== ;------------------------ ;-- SCH NETWORK data block -- ;------------------------ kTxNetLength EQU 32 defBLOCK 32 ;transmit data block bTxCmd defBYTE ;command (bit 7 toggles the next iteration of the current command) bTxLength defBYTE ;length of transmit data kTxDataLen EQU 30 abTxData defBYTE 30 ;transmit data kRxNetLength EQU 32 defBLOCK 32 ;receive data block (chose 32 as this is the SCH default) bRxCmdEcho defBYTE ;copy (echo) of the last completed command (will match bTxCmd when done) bRxLength defBYTE ;receive data length kRxDataLen EQU 30 abRxData defBYTE 30 ;received data ;--------------------- ;-- SCH TIME data block -- (Not used in this example) ;--------------------- ;kRxTimeLength EQU 3 ; defBLOCK 3 ;receive data block ;bHour defBYTE ;bMin defBYTE ;bSec defBYTE ;--------------------- ;-- SCH DATE data block -- (Not used in this example) ;--------------------- ;kRxDateLength EQU 4 defBLOCK 4 ;receive data block ;bWDay defBYTE ;bMDay defBYTE ;bMon defBYTE ;bYear2000 defBYTE ;=============================================================================== ; This code runs at power on. It launches all tasks. ;=============================================================================== Start: XWireMaster pXWireConfig ;start xwire On 20 ;MS120 (only) backlight OBLCD_Text "SPLat Call Home" LaunchTask ServerUpdate RunTasksForever ;go run all tasks ;=============================================================================== ; Task: Poke the server according to which button is pressed ;=============================================================================== ServerUpdate: ;WAF a button press WAFbutton: Yieldtask GoIfInK iBtnA,Test1 GoIfInK iBtnB,Test2 GoIfInK iBtnC,Test3 GoTo WAFbutton ;1st test ... send GET request with no data (query string). The response is the GMT time in ASCII. Test1: GoSub SCH_Idle ;Force the SCH into idle WaitForST sSCH_GotEcho ;Wait for the command to be echoed GoSub SCH_ClearTx ;Make sure the SX10509 Tx buffer is clear WaitForST sSCH_GotEcho ;Wait for the command to be echoed GoSub SCH_Get ;Send a GET request to the server WaitForST sSCH_GotEcho ;Wait for the command to be echoed fRecallW abRxData ;Get the status code -> W fLoadQ 200 ;OK code fTestWeqQ ;OK? GoIfT Test1a ;g/ good response OBLCD_Cls ;Display the bad status code ;0123456789012345 OBLCD_Text "Error code " OBLCD_fDispW 3,0 GoTo WAFButton Test1a: LoadI 0 ;Offset into SCH network Rx buffer GoSub SCH_Read ;Read the SCH Rx buffer to the Xwire Rx data block WaitForST sSCH_GotEcho ;Wait for the command to be echoed GoSub RxDisplay ;Display the result GoTo WAFbutton ;2nd test ... send GET request with two name/value pairs, a=5 and b=9. ;Response is the sum. Test2: GoSub SCH_Idle ;Force the SCH into idle WaitForST sSCH_GotEcho ;Wait for the command to be echoed GoSub SCH_ClearTx ;Make sure the SX10509 Tx buffer is clear WaitForST sSCH_GotEcho ;Wait for the command to be echoed LoadI 0 ;Write offset pointer for iiPrintText and similar instructions iiPrintText abTxData,"a=" ;Write the first name LoadX 5 ;Set the first value, use an integer iiHexPrintX abTxData ;Write the first value iiPrintText abTxData,"&b=" ;Write delimiter and the second name fLoadW -9 ;Set the 2nd value as a float iifPrintWVW abTxData,10,3 ;Write the 2nd value, max 10 characters, max 3 decimal places ItoX ;Get the number of bytes written Store bTxLength ;Data length byte in the Xwire N/W Tx data block GoSub SCH_Write ;Set the command byte to Write WaitForST sSCH_GotEcho ;Wait for the command to be echoed GoSub SCH_Get ;Send a GET request to the server WaitForST sSCH_GotEcho ;Wait for the command to be echoed fRecallW abRxData ;Get the result code -> W fLoadQ 200 ;OK code fTestWeqQ ;OK? GoIfZ WAFbutton ;g/ bad response LoadI 0 ;Offset into SCH network Rx buffer GoSub SCH_Read WaitForST sSCH_GotEcho ;Wait for the command to be echoed GoSub RxDisplay ; Display the result GoTo WAFbutton ;3rd test ... send GET request with fixed query string "config". ;Response is (e.g.) ;therm=73 ;cktime=25 ;pump=0 ;valve=1 ;With a '0D characters between lines. bSCH_RxBufferOffset defBYTE Test3: GoSub SCH_Idle ;Force the SCH into idle WaitForST sSCH_GotEcho ;Wait for the command to be echoed GoSub SCH_ClearTx ;Make sure the SX10509 Tx buffer is clear WaitForST sSCH_GotEcho ;Wait for the command to be echoed LoadI 0 ;Write offset pointer for iiPrintText and similar instructions iiPrintText abTxData,"config" ;Write the query string ItoX ;Get the number of bytes written Store bTxLength ;Data length byte in the Xwire N/W Tx data block GoSub SCH_Write ;Set the command byte to Write WaitForST sSCH_GotEcho ;Wait for the command to be echoed GoSub SCH_Get ;Send a GET request to the server WaitForST sSCH_GotEcho ;Wait for the command to be echoed fRecallW abRxData ;Get the result code -> W fLoadQ 200 ;OK code fTestWeqQ ;OK? GoIfZ WAFbutton ;g/ bad response ;Extract and process the server response. This loop extracts one name/value pair at a time, ;and processes it as required. OBLCD_Cls SetMem bSCH_RxBufferOffset,0 ;Initialise the offset pointer ParseLoop: Recall bSCH_RxBufferOffset XtoI GoSub SCH_Read ;Read from SCH n/w Rx buffer at offset I. Result in Xwire n/w Rx data block WaitForST sSCH_GotEcho ;Wait for the command to be echoed GoIfMZ bRxLength,T3_NoMoreData ;Make sure SCH returned something NVSetPtr ptrValueNames ;Set the NVEM pointer to the table of string pointers NVSetPage 0 ;Playing safe LoadI 0 ;Search from the first data byte in the Xwire network Rx data block iiStrFind abRxData,kRxDataLen,0 ;Try to find a match in our NVEM table of variable names Branch Target T3_NoMoreData ;Not found in the table Target T3_Therm Target T3_CkTime Target T3_Pump Target T3_Valve T3_Therm: ;Get the temperature value and display iifGetNum abRxData,kRxDataLen,255 ;Get a float from the Xwire n/w Rx data block OBLCD_SetCur 0,0 OBLCD_Text "T=" OBLCD_fDispW 5,2 GoSub UpdatePointers GoTo ParseLoop T3_CkTime: ;Get the CookTime value and display OBLCD_SetCur 0,8 OBLCD_Text " C=" iifGetNum abRxData,kRxDataLen,255 ;Get a float from the Xwire n/w Rx data block OBLCD_fDispW 5,2 GoSub UpdatePointers GoTo ParseLoop T3_Pump: iRecall abRxData ;'30 for OFF, '31 for ON IncI ;Past the character just used LoadX 1 AndM Output oLED0 GoSub UpdatePointers GoTo ParseLoop T3_Valve: iRecall abRxData ;'30 for OFF, '31 for ON IncI ;Past the character just used LoadX 1 AndM Output oLED1 GoSub UpdatePointers GoTo ParseLoop T3_NoMoreData: ;Clean up GoTo WAFButton UpdatePointers: IncI ;Skip the terminator ItoX ;Number of characters used Store bSCH_RxBufferOffset Return ;----- Display contents (up to 30 bytes) of Xwire network Rx data block RxDCount defBYTE ;local loop counter RxDisplay: OBLCD_Cls Recall bRxLength ;Get the byte count Push ;Duplicate GoIfNZ RxD1 ;Test there's something there OBLCD_Text "Nothing frm srvr" ;Oops! Return RxD1: Store RxDCount ;Save the loop counter LoadI 0 ;Index into the Rx data block RxDispLoop: iRecall abRxData ;Get the next byte OBLCD_CharX ;Display IncI ;Increment the read index to the next character DMGNZ RxDCount,RxDispLoop ;Decrement and test the loop counter Return ********** Subroutines for individual Network commands ************************** ;----- Send Idle command to SCH ; sSCH_GotEchois set once the command is echoed by SCH SCH_Idle: LoadX kCMD_Idle GoSub SCH_SetCommand Return ;----- Send GET command to SCH ; sSCH_GotEchois set once the command is echoed by SCH SCH_Get: LoadX kCMD_DoGet GoSub SCH_SetCommand Return ;----- Clear SCH network buffer ; sSCH_GotEchois set once the command is echoed by SCH SCH_ClearTx: SetMem bTxLength,0 GoSub SCH_Write Return ;----- Write network Tx data block contents to SCH network buffer ; sSCH_GotEchois set once the command is echoed by SCH SCH_Write: LoadX kCMD_Write GoSub SCH_SetCommand Return ;----- Read from n/w Rx buffer in SCH to Xwire Rx data block ; Starting offset in I ; sSCH_GotEchois set once the command is echoed by SCH SCH_Read: ItoX Store bTxLength ;Incremental offset LoadX kCMD_Read GoSub SCH_SetCommand Return ;------ Set the command byte in the SCH network Tx data block. ; This will toggle bit 7 of the command byte if required. ; sSCH_GotEcho is set once the command is echoed by SCH. ; This uses a transitory task to look for the echo and set the sSCH_GotEcho semaphore SCH_SetCommand: Push Recall bTxCmd ;What we sent last time Swap Store bTxCmd ;Store the new command Compare ;Are they the same? GoIfNZ SCH_SC1 ; g/ new <> old NotS 7,bTxCmd ; old = new, so toggle bit 7 SCH_SC1: ClrS sSCH_GotEcho ;Clear the Echo semaphore LaunchTask tsk_SCH_AckWait ;Task that watches out for an echo. Return sSCH_GotEcho: defSEM ;Signals completion of a SCH/Xwire command tsk_SCH_AckWait: YieldTask Recall bTxCmd ;Get back the command just set Recall bRxCmdEcho ;read the RX echo location Compare GoIfNZ tsk_SCH_AckWait ; g/ different SetS sSCH_GotEcho ;Signal that the echo is received KillTask ;Job done! ; ;=============================================================================== NVEM0 ;Start of non-volatile memory pXWireConfig: ;SCH Xwire NETWORK configuration NV0Byte 64 ;Address of the SPLat Call Home board NV0Byte bTxCmd ;Address of the Tx data block NV0Byte kTxNetLength ;Length of the Tx data block NV0Byte bRxCmdEcho ;Address of the Rx data block NV0Byte kRxNetLength ;Length of the Rx data block ;SCH Xwire TIME configuration - Not used in this example ; NV0Byte 65 ;Address of the SPLat Call Home board, TIME ; NV0Byte 0 ;Address of the Tx data block ; NV0Byte 0 ;Length of the Tx data block ; NV0Byte bHour ;Address of the Rx data block ; NV0Byte kRxTimeLength ;Length of the Rx data block ;SCH Xwire DATE configuration - Not used in this example ; NV0Byte 66 ;Address of the SPLat Call Home board, DATE ; NV0Byte 0 ;Address of the Tx data block ; NV0Byte 0 ;Length of the Tx data block ; NV0Byte bWDay ;Address of the Rx data block ; NV0Byte kRxDateLength ;Length of the Rx data block NV0Byte 255 ;XWire config end of table marker ;Table of value names expected from the server strTemp NV0Byte "therm=",0 strCkTime NV0Byte "cktime=",0 strPump NV0Byte "pump=",0 strValve NV0Byte "valve=",0 ;Table of pointers into the table of value names: ptrValueNames: NV0Ptr strTemp ; #1 NV0Ptr strCkTime ; #2 NV0Ptr strPump ; #3 NV0Ptr strValve ; #4 NV0Byte 255 ; Sentinal