Previous Topic

Next Topic

Book Contents

Book Index

Example: Simple I/O expansion using Xwire

Let's consider a simple example of of just using a CC18 as an I/O expander for an MS120 (or for another CC18 for that matter). We will make it so all 16 I/O points are available both as inputs and as outputs. That means we have to send 2 bytes to the CC18 and receive 2 bytes back. Let's give the slave an address that is simply set by the Xwire jumpers. For demonstration purposes some of the CC18 I/O will be reflected on the user interface (buttons and LEDs) of an MS120.

Slave program

Here's a program for the slave. Here's what it does:

;=====================================================================
;======== Slave program for making a CC18 into an I/O expander =======
;=====================================================================

;Define RAM locations for the exchange. Here I have used "absolute" (mEQU)
;allocations. I could just as easily use defBYTE allocations, as long as 
;I also use defBLOCK to make sure the bytes get allocated to contiguous RAM
;locations.
XwRx0           mEQU            0       ;1st byte from master
XwRx1           mEQU            1       ;2nd byte from master
XwTx0           mEQU            2       ;1st byte to master
XwTx1           mEQU            3       ;2nd byte to master

Start:          XwireGetJumpers         ;Read the 2 address jumpers. 
;                                        For address 0 both jumpers should be out
                XwireSetAddr            ;That sets the board address

                XwireSlave      XwTab   ;Start Xwire with its configuration

Loop:           Recall          XwRx0   ;1st byte of data from the master
                LoadX           'FF     ;Enable all bits
                OutputM         0       ;Output all bits
                Recall          XwRx1   ;2nd byte from master
                LoadX           'FF     ;Enable all bits
                OutputM         8       ;Output all bits

                InputFM         0       ;Read lower 8 input bits
                Store           XwTx0   ;1st byte to master
                InputFM         8       ;Read upper 8 input bits
                Store           XwTx1   ;2nd byte to master
                GoTo            Loop    ;Repeat
;-------------------------------------------------------------------
                NVEM0	;Must appear after all executable code!
XwTab:
                NV0Byte                      XwTx0,2,XwRx0,2
; Address of 1st RAM byte to be transmitted ___^   ^    ^  ^
; Number of RAM bytes to be transmitted ___________|    |  |
; Address of 1st RAM byte received from master _________|  |
; Number of receive bytes to expect from master ___________|
;Note: If the byte counts each end do not match, it will not work.

Note: Xwire is not supported during simulation in SPLat/PC. That means it is not possible to be debugging one board and see it interacting with another board while you are using the Run menu. You need to run it in the actual hardware (Translate, Download and then Run button on Module window)

Master program

Here is a fully working program for the master. This will work with the slave program above, that has turned a CC18 into a 16 I/O peripheral expansion board. What the program will do is have the 5 front panel push buttons of the MS120 appear on outputs 0 through 4 of the CC18. At the same time inputs 8-11 of the CC18 will appear on the 4 front panel LEDs on the MS120 (on the MMI202 3 LEDs plus the beeper). I have provided equivalent MMi202 button/LED addresses as well.

I am going to use semaphore addressing in the master. What this means is:

What the program has to do is:

Tip: If you are trying to get several slaves going, do one at a time. Write a simple test program that uses the error counter, and extend it as you add each slave to your system. If you try and get several slaves all working at once, you are likely to be overwhelmed if any one of them is incorrect. Divide and conquer!

Note: I am not going to define named (symbolic) values for all the slave I/O and MS120/MMi202 front panel stuff. I will use simple numeric values. Normally that would be naughty. In this case it is better not to clutter the program with 20+ lines of EQUates.

;=====================================================================
;======== Master program for using a CC18 as an I/O expander =========
;=====================================================================

;Define RAM locations for the exchange.
Slv0Inputs      defBYTE         2    ;Remote inputs stored in 2 bytes as 16 semaphores
                                     ;Each semaphore will correspond to one slave input
Slv0Outputs     defBYTE         2    ;Remote outputs stored in 2 bytes as 16 semaphores
                                     ;Each semaphore will correspond to one slave output
 
Slv0Addr       EQU             0     ;Define the slave address.
 
Start:
                XwireMaster     XwTab   ;Start Xwire with its configuration
 
;For MS120, as I want to use the LCD for error counts, I must turn on the backlight
                On              20      ;MS120 only
 
;Once the startup stuff is done Xwire will be running 
;(if everything is correctly set up and wired together!).
 
;I now go into a "tight loop" updating I/O and the error count display...
 
Loop:
;---------- Do the slave inputs: Copy to front panel resources
                RecallS         8,Slv0Inputs    ;Reflecting input 8 on the CC18
;Notice                         ^_________________________________^
                Output          8               ;One front panel LED (Beeper on MMi)
 
                RecallS         9,Slv0Inputs    ;Reflecting input 9 on the CC18
                Output          9               ;One front panel LED
 
                RecallS         10,Slv0Inputs   ;Reflecting input 10 on the CC18
;                                ^
;Coincidence ------------------- |
;                                v
                Output          10               ;One front panel LED
 
                RecallS         11,Slv0Inputs   ;Reflecting input 11 on the CC18
                Output          11              ;One front panel LED

;---------- Do the slave outputs: Set from front panel resources
                Input           12 ;(8 on MMi)  ;One front panel button
                StoreS          0,Slv0Outputs   ;Reflects in slave output 0
;Notice                         ^_________________________________________^

                Input           13 ;(9 on MMi)  ;One front panel button
                StoreS          1,Slv0Outputs   ;Reflects in slave output 1
 
                Input           14 ;(10 on MMi) ;One front panel button
                StoreS          2,Slv0Outputs   ;Reflects in slave output 2
 
                Input           15 ;(11 on MMi) ;One front panel button
                StoreS          3,Slv0Outputs   ;Reflects in slave output 3
 
                Input           16 ;(12 on MMi) ;One front panel button
                StoreS          4,Slv0Outputs   ;Reflects in slave output 4
 
;-----------  Display the error count. The count displayed will increment
;whenever there is an Xwire error. 
fErrors         defFLOAT
                XwireGetErrCount                ;Error count -> X, reset error count
                float                           ;Convert to floating point
                fRecallQ        fErrors         ;Previous running total
                fAdd                            ;Add in new counts, if any
                fStore          fErrors         ;Save
                OBLCD_SetCur     0,0            ;Position LCD cursor
                OBLCD_fDispW    5,0             ;Display running total    
 
;-----------  All done
                GoTo             Loop
;-------------------------------------------------------------------
;The NVEM0 directive must come after all executable code.
                NVEM0
XwTab:
                NV0Byte         Slv0Addr,Slv0Outputs,2,Slv0Inputs,2
                NV0Byte         'FF     ;Sentinel

Previous Topic

Next Topic