Example program demonstrating how to interface with a SX10504
* For use with MMI202 and SX10504 *
* 2x16 LCD *
** Setup **
* The SX10504 is interfaced to the MMI202 over X-Wire protocol by setting the communications jumper to
* the X position.
* No board ID jumpers are installed as the X-Wire address for the SX10504 is address 0.
* If it is a MMI202 the X-Wire cable is connected from the Spice connector on the MMI202 to the X1 connector on the SX10504.
* If it is a MMI202a the X-Wire cable is connected from the CN12 connector on the MMI202a to the X1 connector on the SX10504.
* 10k thermistors are connected to the analog inputs and the associated jumpers are set to the T position.
** Program operation **
* The thermistor drive voltage is set to 10 volts.
* Conductivity Channels.
* These can be triggered by causing conduction to ground.
* Input 0 on the MMI202 will toggle the Conductivity Control bit which will turn on and off all conductivity
* channels.
* Pressing front panel button IN8 advances to the next screen.
* Analog Inputs.
* From left to right fAI_AnIn0, fAI_AnIn1, fAI_AnIn2.
* Input voltage is displayed for the analog inputs.
* Pressing front panel button IN8 advances to the next screen.
* Analog Outputs.
* From left to right fAO_AnOut0, fAO_AnOut1.
* Current output voltage is displayed for the analog outputs.
* Pressing front panel button IN12 increments AnOut0 by 1 volt.
* Pressing front panel button IN11 decrements AnOut0 by 1 volt.
* Pressing front panel button IN10 increments AnOut1 by 1 volt.
* Pressing front panel button IN9 decrements AnOut1 by 1 volt.
* The voltage range is 0 to 10 Volts.
* If at any time there are Xwire communications errors the front panel LED on output 15 will light.
* Equates *
* XWire Receive data block *
* Data block of 13 bytes *
fAI_Anin0: mequ 100,4 ;Location where Analog Input 0 from SX10504 is returned.
fAI_Anin1: mequ 104,4 ;Location where Analog Input 1 from SX10504 is returned.
fAI_Anin2: mequ 108,4 ;Location where Analog Input 2 from SX10504 is returned.
bCC_Conduct_Data: mequ 112 ;Bits 0-4 conductivity channels (reads back true when conducting).
;Bit 7 = readings available bit (reads back true when reading ready).
* XWire Transmit data block *
* Data block of 13 bytes *
fAO_Anout0: mequ 10,4 ;Location where Analog Output 0 value is stored for SX10504 to take.
fAO_Anout1: mequ 14,4 ;Location where Analog Output 1 value is stored for SX10504 to take.
bAI_Thermistor_Drive: mequ 18,4 ;Location where Thermistor Drive value is stored for SX10504 to take.
bCC_CCB: mequ 22 ;Bits 0-6 conductivity channels time factor.
;Bit 7 disables ALL channels when set true.
* Input equates *
iCC_ConductToggle: iequ 0 ;this input is used to toggle the conductivity control bit, to force on/off conductivity testing.
iAO_AnOut0_Up_Btn: iequ 12 ;increments analog output 0 by 10%
iAO_AnOut0_Dn_Btn: iequ 11 ;decrements analog output 0 by 10%
iAO_AnOut1_Up_Btn: iequ 10 ;increments analog output 1 by 10%
iAO_AnOut1_Dn_Btn: iequ 9 ;decrements analog output 1 by 10%
* Output Equates *
oXW_XWireError: oequ 15 ;LED turns on when there is an Xwire communication error.
*******************
** Program start **
*******************
Start
XwireMaster XWireTab ;start xwire going
launchtask Analog_Out_Task ;start the Analog Output task running
launchtask Analog_In_Task ;start the Analog Input task running
launchtask Conductivity_Task ;start the Conductivity Task running
launchtask LCD_Task ;start the Display task running
launchtask Xwire_Task ;start the XWire error checking task running
runtasksforever
************************
** Analog Output Task **
************************
* Entry points *
AO_GET_AnOut0:
frecallw fAO_Anout0 ;recall user set analog out 0 voltage (returns value in W as a value 0-1)
return
AO_GET_AnOut1:
frecallw fAO_Anout1 ;recall user set analog out 1 voltage (returns value in W as a value 0-1)
return
Analog_Out_Task:
AO0:
yieldtask
goifink iAO_AnOut0_Up_Btn,AO1 ;does the user wish to increase the voltage on AnOut 0?
goifink iAO_AnOut0_Dn_Btn,AO3 ;does the user wish to decrease the voltage on AnOut 0?
goifink iAO_AnOut1_Up_Btn,AO5 ;does the user wish to increase the voltage on AnOut 1?
goifink iAO_AnOut1_Dn_Btn,AO7 ;does the user wish to decrease the voltage on AnOut 1?
goto AO0
;; AnOut0 ;;
AO1:
frecallq fAO_Anout0 ;limit check to prevent attempting to set voltage higher than maximum
floadw .9
fsub
fgoifpos AO2
frecallq fAO_Anout0 ;below upper limit so increment AnOut 0 value by 10%
floadw .1
fadd
fstore fAO_Anout0
goto AO0
AO2:
floadw 1 ;reached limit so increment no further
fstore fAO_Anout0
goto AO0
AO3:
frecallq fAO_Anout0 ;limit check to prevent attempting to set voltage lower than minimum
floadw .1
fsub
fgoifneg AO4
frecallq fAO_Anout0 ;above lower limit so decrement AnOut 0 value by 10%
floadw .1
fsub
fstore fAO_Anout0
goto AO0
AO4:
floadw 0 ;reached limit so decrement no further
fstore fAO_Anout0
goto AO0
;; AnOut1 ;;
AO5:
frecallq fAO_Anout1 ;limit check to prevent attempting to set voltage higher than maximum
floadw .9
fsub
fgoifpos AO6
frecallq fAO_Anout1 ;below upper limit so increment AnOut 0 value by 10%
floadw .1
fadd
fstore fAO_Anout1
goto AO0
AO6:
floadw 1 ;reached limit so increment no further
fstore fAO_Anout1
goto AO0
AO7:
frecallq fAO_Anout1 ;limit check to prevent attempting to set voltage lower than minimum
floadw .1
fsub
fgoifneg AO8
frecallq fAO_Anout1 ;above lower limit so decrement AnOut 0 value by 10%
floadw .1
fsub
fstore fAO_Anout1
goto AO0
AO8:
floadw 0 ;reached limit so decrement no further
fstore fAO_Anout1
goto AO0
***********************
** Analog Input Task **
***********************
* Define Memory *
fAI_AnalogVal0: defFloat ;Where the data from the returned analog reading is stored as a voltage.
fAI_AnalogVal1: defFloat
fAI_AnalogVal2: defFloat
* Entry points *
AI_GET_AnIn0:
frecallw fAI_AnalogVal0 ;display task gets the analog input voltage value. (Return in W as value 0-5V)
return
AI_GET_AnIn1:
frecallw fAI_AnalogVal1
return
AI_GET_AnIn2:
frecallw fAI_AnalogVal2
return
Analog_In_Task:
floadw .5 ;set thermistor drive voltage to 10 volts
fstore bAI_Thermistor_Drive
pause 200 ;allow the drive voltage to settle
AI0:
yieldtask
frecallw fAI_Anin0 ;get the analog reading from AnIn channel 0.
floadq 5 ;load Q with maximum possible analog input voltage. (5 volts)
fmul ;multiply to convert to volts.
fstore fAI_AnalogVal0 ;store calculation.
frecallw fAI_Anin1 ;get the analog reading from AnIn channel 1.
floadq 5 ;load Q with maximum possible analog input voltage. (5 volts)
fmul ;multiply to convert to volts.
fstore fAI_AnalogVal1 ;store calculation.
frecallw fAI_Anin2 ;get the analog reading from AnIn channel 2.
floadq 5 ;load Q with maximum possible analog input voltage. (5 volts)
fmul ;multiply to convert to volts.
fstore fAI_AnalogVal2 ;store calculation.
goto AI0
*******************************
** Conductivity Channel Task **
*******************************
* Define Memory *
bCC_Conduct_Ch1: defbyte ;byte is true when channel is conducting and is false when it is not.
bCC_Conduct_Ch2: defbyte
bCC_Conduct_Ch3: defbyte
bCC_Conduct_Ch4: defbyte
bCC_Conduct_Ch5: defbyte
* Entry points *
CC_GET_CondCh1:
recall bCC_Conduct_Ch1 ;returns a true in X if conducting and false if not conducting.
return
CC_GET_CondCh2:
recall bCC_Conduct_Ch2
return
CC_GET_CondCh3:
recall bCC_Conduct_Ch3
return
CC_GET_CondCh4:
recall bCC_Conduct_Ch4
return
CC_GET_CondCh5:
recall bCC_Conduct_Ch5
return
Conductivity_Task:
loadx %00111011 ;enable conductivity testing by clearing bit 7.
;set the conductivity time factor by setting appropriate bits of 0-6. (59 + 1) x .05 = 3 seconds.
store bCC_CCB
CC0:
yieldtask
goifink iCC_ConductToggle,CC1 ;toggle the conductivity control bit to enable/disable conductivity channels.
goto CC3
CC1:
recall bCC_CCB
loadx %10000000
andm ;separate the conductivity control 'bit' out of the Conductivity Control 'Byte'
goift CC2
recall bCC_CCB ;bit previously not set so OR %10000000 with CCB to set bit.
loadx %10000000
orm
store bCC_CCB
goto CC3
CC2:
recall bCC_CCB ;bit previously was set so AND %01111111 with CCB to Clear bit.
loadx %01111111
andm
store bCC_CCB
CC3:
;; Check if reading is valid ;;
recall bCC_Conduct_Data
loadx %10000000
andm
goiff CC0 ;if bit 7 is true then conductivity channel readings are stable and ready to be read.
;; Check conductivity channels ;;
recall bCC_Conduct_Data ;check conductivity channel 5
loadx %00010000 ;mask all unwanted bits
andm
store bCC_Conduct_Ch5 ;store channel status
recall bCC_Conduct_Data ;check conductivity channel 4
loadx %00001000 ;mask all unwanted bits
andm
store bCC_Conduct_Ch4 ;store channel status
recall bCC_Conduct_Data ;check conductivity channel 3
loadx %00000100 ;mask all unwanted bits
andm
store bCC_Conduct_Ch3 ;store channel status
recall bCC_Conduct_Data ;check conductivity channel 2
loadx %00000010 ;mask all unwanted bits
andm
store bCC_Conduct_Ch2 ;store channel status
recall bCC_Conduct_Data ;check conductivity channel 1
loadx %00000001 ;mask all unwanted bits
andm
store bCC_Conduct_Ch1 ;store channel status
goto CC0
******************
** Display Task **
******************
* Input equates *
iLCD_Cycle: iequ 8 ;this input is used to cycle the data on the LCD
LCD_Task:
oblcd_CLS
;; Display Conductivity channels ;;
LCD0:
yieldtask
goifink iLCD_Cycle,LCD10 ;if toggle button is pressed change LCD display
oblcd_setcur 0,0
; "0123456789012345"
oblcd_text "Chan: 1 2 3 4 5 "
oblcd_setcur 1,0
oblcd_text "Cond: "
gosub CC_GET_CondCh1 ;get channel 1 current conductivity status. Returned in X as true if conducting.
goifF LCD1
oblcd_text "Y " ;yes channel is conducting
goto LCD2
LCD1:
oblcd_text "N " ;no channel is not conducting
LCD2:
gosub CC_GET_CondCh2 ;get channel 2 current conductivity status. Returned in X as true if conducting.
goifF LCD3
oblcd_text "Y " ;yes channel is conducting
goto LCD4
LCD3:
oblcd_text "N " ;no channel is not conducting
LCD4:
gosub CC_GET_CondCh3 ;get channel 3 current conductivity status. Returned in X as true if conducting.
goifF LCD5
oblcd_text "Y " ;yes channel is conducting
goto LCD6
LCD5:
oblcd_text "N " ;no channel is not conducting
LCD6:
gosub CC_GET_CondCh4 ;get channel 4 current conductivity status. Returned in X as true if conducting.
goifF LCD7
oblcd_text "Y " ;yes channel is conducting
goto LCD8
LCD7:
oblcd_text "N " ;no channel is not conducting
LCD8:
gosub CC_GET_CondCh5 ;get channel 5 current conductivity status. Returned in X as true if conducting.
goifF LCD9
oblcd_text "Y " ;yes channel is conducting
goto LCD0
LCD9:
oblcd_text "N " ;no channel is not conducting
goto LCD0
;; Display Analog Inputs ;;
LCD10:
yieldtask
goifink iLCD_Cycle,LCD_17 ;if toggle button is pressed change LCD display
oblcd_setcur 0,0
; "0123456789012345"
oblcd_text "Analog Inputs: "
oblcd_setcur 1,0
gosub AI_GET_AnIn0
;; Check for LCD formatting issue ;;
gosub CF_Lower ;check lower limit, FALSE will return in X if it is NOT a floating point value of 1
goiff LCD_11 ;if returns TRUE check the upper limit
;; Analog In 0 ;;
gosub AI_GET_AnIn0
gosub CF_Upper ;check upper limit, FALSE will return in X if it is NOT a floating point value of 1
goiff LCD_11 ;if returns TRUE run the LCD formatting issue workaround
oblcd_text "1.0" ;value to display is floating point value of 1, therefore use OBLCD_Text instruction to display 1.0
goto LCD_12
LCD_11:
gosub AI_GET_AnIn0
oblcd_fdispw 3,1 ;display AnIn channel 0 voltage
LCD_12:
oblcd_text "V "
;; Analog In 1 ;;
gosub AI_GET_AnIn1
gosub CF_Lower ;check lower limit, FALSE will return in X if it is NOT a floating point value of 1
goiff LCD_13 ;if returns TRUE check the upper limit
gosub AI_GET_AnIn1
gosub CF_Upper ;check upper limit, FALSE will return in X if it is NOT a floating point value of 1
goiff LCD_13 ;if returns TRUE run the LCD formatting issue workaround
oblcd_text "1.0" ;value to display is floating point value of 1, therefore use OBLCD_Text instruction to display 1.0
goto LCD_14
LCD_13:
gosub AI_GET_AnIn1
oblcd_fdispw 3,1 ;display AnIn channel 1 voltage
LCD_14:
oblcd_text "V "
;; Analog In 2 ;;
gosub AI_GET_AnIn2
gosub CF_Lower ;check lower limit, FALSE will return in X if it is NOT a floating point value of 1
goiff LCD_15 ;if returns TRUE run the LCD formatting issue workaround
gosub AI_GET_AnIn2
gosub CF_Upper ;check upper limit, FALSE will return in X if it is NOT a floating point value of 1
goiff LCD_15 ;if returns TRUE run the LCD formatting issue workaround
oblcd_text "1.0" ;value to display is floating point value of 1, therefore use OBLCD_Text instruction to display 1.0
goto LCD_16
LCD_15:
gosub AI_GET_AnIn2
oblcd_fdispw 3,1 ;display AnIn channel 2 voltage
LCD_16:
oblcd_text "V "
goto LCD10
;; Display Analog Outputs ;;
LCD_17:
yieldtask
goifink iLCD_Cycle,LCD0 ;if toggle button is pressed change LCD display
oblcd_setcur 0,0
; "0123456789012345"
oblcd_text "Analog Outputs: "
oblcd_setcur 1,0
;; Analog Out 0 ;;
gosub AO_Get_AnOut0 ;recalls user set voltage in W as a value 0-1
floadq 10 ;load Q with maximum possible output voltage
fmul ;multiply to get user set voltage out
;; Check for LCD formatting issue ;;
gosub CF_Lower ;check lower limit, FALSE will return in X if it is NOT a floating point value of 1
goiff LCD_18 ;if returns TRUE check the upper limit
gosub AO_Get_AnOut0 ;recalls user set voltage in W as a value 0-1
floadq 10 ;load Q with maximum possible output voltage
fmul ;multiply to get user set voltage out
gosub CF_Upper ;check upper limit, FALSE will return in X if it is NOT a floating point value of 1
goiff LCD_18 ;if returns TRUE run the LCD formatting issue workaround
oblcd_text "1.0" ;value to display is floating point value of 1, therefore use OBLCD_Text instruction to display 1.0
goto LCD_19
LCD_18:
gosub AO_Get_AnOut0 ;recalls user set voltage in W as a value 0-1
floadq 10 ;load Q with maximum possible output voltage
fmul ;multiply to get user set voltage out
oblcd_fdispw 3,1 ;display AnOut channel 0 voltage
LCD_19:
oblcd_text "V "
;; Analog Out 1 ;;
gosub AO_Get_AnOut1 ;recalls user set voltage in W as a value 0-1
floadq 10 ;load Q with maximum possible output voltage
fmul ;multiply to get user set voltage out
;; Check for LCD formatting issue ;;
gosub CF_Lower ;check lower limit, FALSE will return in X if it is NOT a floating point value of 1
goiff LCD_20 ;if returns TRUE check the upper limit
gosub AO_Get_AnOut1 ;recalls user set voltage in W as a value 0-1
floadq 10 ;load Q with maximum possible output voltage
fmul ;multiply to get user set voltage out
gosub CF_Upper ;check upper limit, FALSE will return in X if it is NOT a floating point value of 1
goiff LCD_20 ;if returns TRUE run the LCD formatting issue workaround
oblcd_text "1.0" ;value to display is floating point value of 1, therefore use OBLCD_Text instruction to display 1.0
goto LCD_21
LCD_20:
gosub AO_Get_AnOut1 ;recalls user set voltage in W as a value 0-1
floadq 10 ;load Q with maximum possible output voltage
fmul ;multiply to get user set voltage out
oblcd_fdispw 3,1 ;display AnOut channel 0 voltage
LCD_21:
oblcd_text "V "
goto LCD_17
;; Subroutines ;;
;; Check Floating point value of 1 ;;
CF_Lower: ;following subroutines test if LCD formatting workaround needs to be run.
floadq .95
fsub
fgoifpos CF_0
loadx 255 ;Return with X TRUE if above lower limit check, this will cause an upper limit check.
goto CF_1
CF_0:
loadx 0 ;Return FALSE in X if no action is needed
CF_1: return
CF_Upper:
floadq 1.05
fsub
fgoifneg CF_2
loadx 255 ;Return with X TRUE if both limit checks find the floating point number is 1 and-
goto CF_3 ;LCD format workaround needs to be run
CF_2:
loadx 0 ;Return FALSE in X if no action is needed
CF_3: return
****************************
** Xwire Error Check Task **
****************************
Xwire_Task:
XW0:
yieldtask
xwiregeterrcount ;get the xwire error count
goiff XW1
on oXW_XWireError ;turn on error LED if there are XWire errors
pause 1
goto XW0
XW1: off oXW_XWireError
goto XW0
** X-Wire Master table **
NVEM0
XWireTab:
NV0Byte 0,10,13,100,13 ;slave address 0, memory 10 is transmit data block, 13 bytes, 100 is Receive data block, 13 bytes.
NV0Byte 255 ;End of table sentinel.