Knowledge Base

Example: Read and display SPice10209 with full TSP and LCD handshaking

The TSP interface can take appreciable time to complete some operations. This is because it uses relatively slow serial communications between the SPLat controller and the peripheral. If you try and hit the TSP interface with an instruction before it has completed the previous one, it will stall the SPLat processor while the pending instruction completes.

This example makes full use of the status information available from the TSP, the SPice10209 and the OBLCD to create a temperature display task that uses the absolute minimum of processor time. This task is one of two tasks in a multitasking structure. The other task is a simple binary count in outputs 0-7. Just observing how fast that is counting proves that the temperature task is using very little processor time. The file is also located in the examples supplied with SPLat/PC, file name TC-2.SPT.

;TC-2: A more elaborate SPice10209 program for MMi200 (or MMi99)

;This program contains two separate tasks in a multi-tasking structure.
;You should study and understand the Multitasking Tutorial in the
;SPLat Knowledge Base before attempting to understand this program.
;The workings of the multitasking are not explained here!

;The first task reads the SPice10209 and displays temperature on
;the OBLCD. It uses full polling of the SPice10209 and of the LCD, so
;it will never stall (tie up) the processor while waiting for either
;to be ready to do something.

;The second task is a simple binary count in outputs 0-7.

;============== I/O allocations for MMi99/200 ==============
iFault10209 iEQU 17 ;This SPice pin is a direct hardware fault flag
i10209Rdy1 iEQU 13 ;Reading available flag ch 1 of Spice10209
i10209Rdy2 iEQU 14 ;Reading available flag ch 2 of Spice10209

oWaitSignal oEQU 15 ;Front panel LED, signals waiting for TSP
oActivity oEQU 14 ;Activity monitor
oFault10209 oEQU 10 ;Front panel LED, signals SPice10209 fault
oFaultyTSP oEQU 9 ;Front panel LED, signals TSP fault

;=============== RAM ==============================
TempAddr mEQU 20 ;2 bytes for a bookmark for temperature task
CountAddr mEQU 22 ;2 bytes for a bookmark for Counter task
TempRdg mEQU 24 ;4 bytes for temperature reading (floating point)

;============= Initialization ============================
;Both tasks require some initialization.
GoSub TempInit ;Temperature display task
GoSub CountInit ;Counter task

;==== End of initialization ==============

;===== Main loop ==========================
Loop:
GoSub DoTemperature ;Task to update temperature display
GoSub Counter ;Task to update LED Counter

GoTo Loop
;============== End of main loop ==============

*************** Temperature monitor/display task ********************

DoTemperature:
Resume TempAddr

TempInit: ;Initialize TSP and SPice10209
setu 2,2 ;set all as inputs
setu 3,2
setu 4,2
SpiceConfigU ;Configure the SPice pins according
TSPReset ;Enable TSP interface driver and pins
SetU 3,4 ;Set up filter time constant 1=min, 4=max
TSPPutByteL 8 ;Send filter Time Constant to the board

TempSet0:
;In state 0 we poll the TSP interface using TSPBranch to see if it is idle
;(capable of handling a transfer). If it is, we then test if the SP10209
;has a reading. When both conditions are satisfied we move down to the next state
;to acquire the reading.
Temp0:
Suspend TempAddr
TSPBranch ;Test state of the TSP interface
Target Temp0_Idle ;If idle go test for TC rdg
Target Temp0 ;Should not be busy at this stage
Target Temp0 ;Should not have data at this stage
Target TempSet2 ;Handle TSP interface fault

;The following line must change if you want to monitor the other SPice10209 channel
Temp0_Idle:
InputF i10209Rdy1
GoIfF Temp0 ;Test if a reading is available

TempSet1:
;The TSP interface is idle (available) AND the SPice10209 has a reading
;In state 1 we request a reading from the SPice10209 then sit and wait for
;an outcome.
TSPGetWordL 0 ;Initiate readout of the data
ON oWaitSignal ;Display that we are waiting
Temp1:
Suspend TempAddr
TSPBranch ;Test state of the TSP interface
Target Temp0 ;Should never be idle at this stage
Target Temp1 ;Waiting for reading
Target TempSet3 ;Have a reading. Result is now in U
Target TempSet2 ;Handle TSP interface fault

;There is a reading available. The TSPBranch we just did transferred it to U
;In state 3 we access the reading and convert to degrees,
;then sit and wait for the LCD to be free
TempSet3:
floatFromU 0 ;Convert to a Floating point number in W
fLoadQ 0.25 ;Scale factor
fMul
fStore TempRdg ;Save result in degrees
InputO oActivity ;Update activity indicator
NOT
Output oActivity
Input iFault10209 ;Read the SPice10209 fault flag ..
Output oFault10209 ; .. display it

;Loop to wait for the LCD to become free ...
Temp3:
Suspend TempAddr
OBLCD_GoIfBusy Temp3 ;Wait for the LCD

;State 4 sets the LCD cursor then waits for the LCD to complete the operation
TempSet4:
OBLCD_SetCur 0,0 ;Position LCD cursor
Temp4:
Suspend TempAddr
OBLCD_GoIfBusy Temp4 ;Wait for the LCD

;State 5 displays the reading then waits for the LCD to complete the operation
TempSet5:
fRecallW TempRdg
OBLCD_fDispW 7,2 ;Display reading
Temp5:
Suspend TempAddr
OBLCD_GoIfBusy Temp5 ;Wait for the LCD

;State 6 displays a degree sign then waits for the LCD to complete the operation
TempSet6:
OBLCD_SpclChar 223
Temp6:
Suspend TempAddr
OBLCD_GoIfBusy Temp6 ;Wait for the LCD

;State 7 displays a 'C' then waits for the LCD to complete the operation
TempSet7:
OBLCD_Text "C"
Temp7:
Suspend TempAddr
OBLCD_GoIfBusy Temp7 ;Wait for the LCD

;End of the process. Loop back and wait for the next reading.
GoTo TempSet0

;Handle TSP interface fault. In this case simply flash a front panel LED
TempSet2:
TSPReset ;Reset TSP interface on fault
On oFaultyTSP ;Visual signal
SetTimer 4,50 ;500mS. Allow it to be on for this long
Temp2:
Suspend TempAddr
Test 4 ;Timing?
GoIfT Temp2 ;G/ yes
Off oFaultyTSP ;Timeout: Turn off indicator
GoTo TempSet0 ;Try the whole thing again

*************** Counter task ************************************
;A simple binary count in outputs 0-7. You can only actually see the top
;2 bits counting, indicating how fast it is. Insert a short Pause before
;the Resume to slow it down.
CountInit:
CountLoop
LoadX 'FF
OutputM 0
Suspend CountAddr
InputOM 0
IncX
GoTo CountLoop
Counter:
Resume CountAddr