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