DEFINT A-Z DECLARE SUB INIT () DECLARE SUB INPUTS () DECLARE SUB OUTPUTS () DECLARE SUB RXBYTE () DECLARE SUB TXPACK () REM*****************USTPQB.BAS************************* REM***** UNIVERSAL SERIAL CARD TEST PROGRAM ** REM**COMBINED OUTPUT CARD AND WRAPAROUND TEST PROGRAM** REM** QuickBASIC CALL VERSION ** REM** FOR USE WITH USIC, SUSIC AND SMINI NODES ** REM** WRITTEN BY BRUCE CHUBB - August 18, 2003 ** REM**************************************************** REM**DIMENSION VARIABLES USED IN MAINLINE ONLY DIM PNU$(4) 'Array used to print out port letter for SUSIC/USIC nodes DIM PNM$(6) 'Array used to print out card-port for SMINI nodes REM**GLOBALIZE SERIAL PROTOCOL HANDLING VARIABLES DIM SHARED OB(60), IB(60), CT(15), TB(80) COMMON SHARED UA, COMPORT, BAUD100, NDP$, DL, NS, NI, NO, MAXTRIES COMMON SHARED INBYTE, ABORTIN, INTRIES, INITERR, PA, LM, MT REM**DEFINE I/O CARD PORTS FOR USIC AND SUSIC NODES PNU$(1) = "A": PNU$(2) = "B": PNU$(3) = "C": PNU$(4) = "D" REM**DEFINE OUTPUT CARD-PORT NOMENCLATURE FOR SMINI NODE PNM$(1) = "0 A": PNM$(2) = "0 B": PNM$(3) = "0 C" PNM$(4) = "1 A": PNM$(5) = "1 B": PNM$(6) = "1 C" REM**CLEAR SCREEN AND PRINT OUT PROGRAM TITLE CLS 'Clear screen PRINT "*************************************************************" PRINT "**COMBINED TEST PROGRAM FOR OUTPUT CARD AND WRAPAROUND TEST**" PRINT "** FOR USE WITH SERIAL USIC, SUSIC AND SMINI NODES **" PRINT "*************************************************************" PRINT " " 'Print blank line used throughout program REM**CHECK IF TESTING SMINI NODE TO PRINT HARDWARE ASSUMPTIONS** NODEIN: INPUT "ARE YOU TESTING AN SMINI NODE?, ENTER Y OR N ? ", CMD$ IF CMD$ = "Y" OR CMD$ = "y" THEN GOTO INSTM IF CMD$ = "N" OR CMD$ = "n" THEN GOTO INSTU PRINT "INVALID ENTRY - TRY AGAIN" PRINT " " GOTO NODEIN INSTU: REM**PRINT OUT HARDWARE SETUP ASSUMPTIONS FOR USIC AND SUSIC** PRINT " " PRINT "******FOR OUTPUT CARD TESTING WITH USIC AND SUSIC*****" PRINT "1) Node's USIC address must be 0 (UA DIP switch all off)" PRINT "2) Output card in card address slot 0 (DIP switch all off)" PRINT "3) Compatible test card to be mounted on output card" PRINT " " PRINT "******FOR WRAPAROUND TESTING WITH USIC AND SUSIC*****" PRINT "1) Node's USIC address must be 0 (UA DIP switch all off)" PRINT "2) Output card in card address slot 0 (DIP switch all off)" PRINT "3) Output card must be standard current sinking configuration" PRINT "4) Input card in card address slot 1 (DIP switch right segment on)" PRINT "5) Wraparound cable to be connected between output and input cards" PRINT "6) Adding a second output card, set to the same card address..." PRINT " ...slot as the first output card, with an appropriate test..." PRINT " ...card attached enhances wraparound test debug if a..." PRINT " ...problem is detected with the input card." PRINT " " REM**DEFINE NODE DEFINITION PARAMETER FOR USIC AND SUSIC APPLICATIONS** BITIN: PRINT "Note: If using classic USIC node, I/O cards must be 24-bit" PRINT " " INPUT "INPUT NUMBER OF I/O LINES PER I/O CARD (24 OR 32)? ", NUMBITS IF NUMBITS = 24 THEN NDP$ = "N": GOTO COMIN IF NUMBITS = 32 THEN NDP$ = "X": GOTO COMIN PRINT "INVALID INPUT - TRY AGAIN" PRINT " " GOTO BITIN INSTM: REM**PRINT OUT HARDWARE SETUP ASSUMPTIONS FOR SMINI** PRINT " " PRINT "******FOR OUTPUT CARD TESTING WITH SMINI*****" PRINT "1) Node's SMINI address must be zero (UA DIP switch all off)" PRINT "2) Compatible test card to be mounted on output card 0" PRINT "3) Additional test card can be mounted on output card 1 or..." PRINT " ...the same test card moved to card 1 once card 0 is tested OK" PRINT " " PRINT "******FOR WRAPAROUND TESTING WITH SMINI*****" PRINT "1) Node's SMINI address must be 0 (UA DIP switch all off)" PRINT "2) Test card to be mounted on output card 0" PRINT "3) Output card 1 must be standard current sinking configuration" PRINT "4) Wraparound cable to be connected between output card 1 and..." PRINT "...input card 2 (make sure A0 on card 1 connects to A0 on card 2)" REM**DEFINE NODE DEFINITION PARAMETER FOR SMINI APPLICATIONS** NDP$ = "M" REM**READ KEYBOARD TO DEFINE DESIRED PC COM PORT** COMIN: INPUT "TO BEGIN TESTING, INPUT PC COM PORT = 1, 2, 3, OR 4 ? ", COMPORT IF COMPORT = 1 THEN GOTO BAUDIN IF COMPORT = 2 THEN GOTO BAUDIN IF COMPORT = 3 THEN GOTO BAUDIN IF COMPORT = 4 THEN GOTO BAUDIN PRINT "INVALID ENTRY - TRY AGAIN" PRINT " " GOTO COMIN REM**READ KEYBOARD TO DEFINE DESIRED BAUD RATE** BAUDIN: PRINT " " PRINT "Baud rate of 9600 or 19200 advised when testing I/O cards..." PRINT "...as this minimizes the chances that a communication error can..." PRINT "...occur that might be mistakenly identified as a board error" PRINT " " PRINT "The baud rate DIP switch, as well as the UA address DIP..." PRINT "...switch, are read only during the card's power up cycle." PRINT "Therefore, if you change either of these DIP switch..." PRINT "...settings, you must cycle power to the card to activate..." PRINT "...the new switch settings." PRINT " " PRINT "INPUT BAUD RATE/100 CORRESPONDING TO DIP SWITCH SETTINGS:" PRINT " FOR 9600 enter 1" PRINT " FOR 19200 enter 2" PRINT " FOR 28800 enter 3" PRINT " FOR 57600 enter 4" INPUT " FOR 115200 enter 5 ? ", BAUD IF BAUD = 1 THEN BAUD100 = 96: GOTO ADJPAR IF BAUD = 2 THEN BAUD100 = 192: GOTO ADJPAR IF BAUD = 3 THEN BAUD100 = 288: GOTO ADJPAR IF BAUD = 4 THEN BAUD100 = 576: GOTO ADJPAR IF BAUD = 5 THEN BAUD100 = 1152: GOTO ADJPAR PRINT "INVALID ENTRY - TRY AGAIN" GOTO BAUDIN ADJPAR: REM**DEFINE INITIALIZED DEFAULT PARAMETERS** PRINT " " MAXTRIES = 30000 'Define maximum number of reading input tries for PC DL = 0 'Define USIC delay between transmitted bytes to PC SLOWDIS = 400 'Define slow display factor to observe test card LEDs INFILTER = 0 'Define input filtering delay for wraparound testing REM**PRINT OUT DEFAULT VALUES OF PARAMETERS PRINT " " PRINT "DEFAULT PARAMETERS ARE:" PRINT " MAXTRIES = "; MAXTRIES PRINT " USIC DELAY (DL) = "; DL PRINT " SLOW DISPLAY FACTOR (SLOWDIS) = "; SLOWDIS PRINT " INPUT FILTER DELAY (INFILTER) = "; INFILTER REM**CHECK IF DESIRE TO CHANGE DEFAULT PARAMETERS CHKIN: INPUT "WANT TO CHANGE DEFAULT PARAMETERS?, ENTER Y OR N ? ", CMD$ IF CMD$ = "N" OR CMD$ = "n" THEN GOTO TESTIN IF CMD$ = "Y" OR CMD$ = "y" THEN GOTO DFLTIN PRINT "INVALID ENTRY - TRY AGAIN" GOTO CHKIN REM**READ KEYBOARD FOR UPDATING DEFAULT PARAMETERS DFLTIN: PRINT " " INPUT "INPUT MAXTRIES ? ", MAXTRIES INPUT "INPUT USIC TRANSMISSION DELAY ? ", DL INPUT "INPUT SLOW DISPLAY FACTOR ? "; SLOWDIS INPUT "INPUT INPUT FILTER DELAY ? "; INFILTER REM**DISPLAY UPDATED DEFAULT PARAMETERS PRINT " " PRINT "DEFAULT PARAMETERS HAVE BEEN CHANGED TO:" PRINT " MAXTRIES = "; MAXTRIES PRINT " USIC DELAY = "; DL PRINT " SLOW DISPLAY FACTOR = "; SLOWDIS PRINT " INPUT FILTER DELAY = "; INFILTER REM**USER VERIFICATION OF CHANGES BEING OK RPTIN: INPUT "ARE CHANGED VALUES CORRECT ?, ENTER Y OR N", CMD$ IF CMD$ = "Y" OR CMD$ = "y" THEN GOTO TESTIN IF CMD$ = "N" OR CMD$ = "n" THEN GOTO DFLTIN PRINT "INVALID ENTRY - TRY AGAIN" GOTO RPTIN REM**READ KEYBOARD FOR DESIRED TEST TO BE PERFORMED TESTIN: PRINT " " PRINT "INPUT DESIRED TEST TO BE PERFORMED:" PRINT " For OUTPUT CARD TEST enter O (letter O)" PRINT " For WRAPAROUND TEST enter W" INPUT " For Ending Testing enter E ? ", DESTST$ IF DESTST$ = "O" OR DESTST$ = "o" THEN GOTO OTEST IF DESTST$ = "W" OR DESTST$ = "w" THEN GOTO WTEST IF DESTST$ = "E" OR DESTST$ = "e" THEN GOTO OPSYS PRINT "INVALID ENTRY - TRY AGAIN" GOTO TESTIN REM************************************************** REM**BEGIN USER ROUTINE TO PERFORM OUTPUT CARD TEST** REM************************************************** OTEST: CLS PRINT "PERFORMING OUTPUT CARD LED DRIVER TEST" PRINT " " REM**CHECK AND BRANCH TO SEPARATE TEST INITIALIZATION FOR SMINI IF NDP$ = "M" THEN GOTO OTESTM REM**INITIALIZE USIC AND SUSIC OTESTU: PRINT "PERFORMING OUTPUT CARD TEST ON USIC OR SUSIC" PRINT " " UA = 0 'USIC address NS = 1 'Number of card sets of 4 NI = 0 'Number of input ports IF NDP$ = "N" THEN NO = 3 'Define number of output ports 24-bit card IF NDP$ = "X" THEN NO = 4 'Define number of output ports 32-bit card CT(1) = 2 'Card type definition (one output card in slot 0) CALL INIT 'Invoke initialization subroutine PRINT " " PRINT "Node Initialization is complete - check blink rate of..." PRINT "...green status LED for 1 second on 1 second off blink rate" PRINT " " PRINT "Press any key to continue" SLEEP 'Sleep until key is pressed GOTO OTESTR 'Branch to start output card test repeating REM**INITIALIZE SMINI OTESTM: PRINT "PERFORMING OUTPUT CARD TEST ON SMINI" PRINT " " UA = 0 'USIC address NS = 0 'Number of 2-lead yellow aspect oscillate signals NI = 3 'Number of input ports NO = 6 'Number of output ports CALL INIT 'Invoke initialization subroutine PRINT " " PRINT "Node Initialization is complete - check blink rate of..." PRINT "...green status LED for 1 second on 1 second off blink rate" PRINT " " PRINT "Press any key to continue" SLEEP 'Sleep until key is pressed REM**BEGIN COMMON CODE OF ALL OUTPUT CARD TESTING** REM**INITIALIZE ALL LEDS TO OFF OTESTR: FOR I = 1 TO NO OB(I) = 0 NEXT I REM**INCREMENT PORT TO BE TESTED IN A LOOP FOR PN = 1 TO NO REM**INCREMENT DISPLAYED BIT NUMBER IN A LOOP FOR N = 0 TO 7 REM**OUTPUT TEST STATUS TO CRT FOR SMINI AND NON-SMINI IF NDP$ = "M" THEN PRINT "PORT IS "; PNM$(PN); " BIT NUMBER IS "; N ELSE PRINT "PORT IS "; PNU$(PN); " BIT NUMBER IS "; N END IF REM**SETUP TEST LED PATTERN FOR DISPLAY ON TEST CARD OB(PN) = 2 ^ N 'Integer 2 raised to the power N shifts... '...the turn-on displayed LED one position... '...to the left each loop through program. REM**OUTPUT LED DISPLAY DATA TO CARD CALL OUTPUTS 'Invoke transmit data subroutine REM**ADD DELAY TO BE ABLE TO READ LEDs IF SLOWDIS > 0 THEN 'Add slow display loop if non-zero FOR I = 1 TO SLOWDIS 'Delay by looping to give... FOR IJ = 1 TO 1000: NEXT IJ '...time to visually check... NEXT I '...operation of LEDs on test card END IF REM**COMPLETE LOOPS NEXT N 'Update display to next LED bit position OB(PN) = 0 'Last LED within port tested so turn off port LED NEXT PN 'Update display to next port number REM**REPEAT OUTPUT CARD TEST GOTO OTESTR 'All ports completed, so branch back to repeat test REM************************************************* REM**BEGIN USER ROUTINE TO PERFORM WRAPAROUND TEST** REM************************************************* WTEST: CLS PRINT "PERFORMING WRAPAROUND TEST" PRINT " " REM**CHECK IF DESIRE TO PRINT EVERY I/O LINE OR ONLY ERROR LINES CHKPIO: PRINT " " PRINT "NOTE: Entering N to following will print only error lines" INPUT "DESIRE TO PRINT EVERY I/O LINE ?, ENTER Y OR N ? ", CMD$ IF CMD$ = "N" OR CMD$ = "n" THEN PRTIO = 0: GOTO CHKNDP IF CMD$ = "Y" OR CMD$ = "y" THEN PRTIO = 1: GOTO CHKNDP PRINT "INVALID ENTRY - TRY AGAIN" GOTO CHKPIO REM**CHECK AND BRANCH TO SEPARATE TEST INITIALIZATION FOR SMINI CHKNDP: IF NDP$ = "M" THEN GOTO WTESTM REM**INITIALIZE USIC AND SUSIC WTESTU: PRINT "PERFORMING WRAPAROUND TEST ON USIC OR SUSIC" PRINT " " UA = 0 'USIC address NS = 1 'Number of card sets of 4 IF NDP$ = "N" THEN NI = 3: NO = 3 'Define no. I/O ports 24-bit cards IF NDP$ = "X" THEN NI = 4: NO = 4 'Define no. I/O ports 32-bit cards CT(1) = 6 'Card type definition (output slot 1, input slot 2) CALL INIT 'Invoke initialization subroutine PRINT "Node Initialization is complete - check blink rate of..." PRINT "...green status LED for 1 second on 1 second off blink rate" PRINT " " PRINT "Press any key to continue" SLEEP 'Sleep until key is pressed GOTO WTESTR 'Branch to start wraparound test repeating REM**INITIALIZE SMINI WTESTM: PRINT "PERFORMING WRAPAROUND TEST ON SMINI" PRINT " " UA = 0 'USIC address NS = 0 'Number of 2-lead yellow aspect oscillating signals NI = 3 'Number of input ports NO = 6 'Number of output ports CALL INIT 'Invoke initialization subroutine PRINT " " PRINT "Node Initilization is complete - check blink rate of..." PRINT "...green status LED for 1 second on 1 second off blink rate" PRINT " " PRINT "Press any key to continue" SLEEP 'Sleep until key is pressed REM**BEGIN COMMON CODE OF ALL WRAPAROUND TESTING REM**INITIALIZE ALL OUTPUTS TO ZERO WTESTR: FOR I = 1 TO NO OB(I) = 0 NEXT I REM**SETUP TO INCREMENT THROUGH ONLY 3 PORTS IF SMINI... '...AND THROUGH ALL NO PORTS IF USIC OR SUSIC 'Note: During wraparound testing of SMINI... '...test program increments test pattern... '...through first 3 ports while setting the... '...second 3 ports equal to the same pattern. 'During wraparound testing of SUSIC and USIC... '...test program increments test pattern... '...through all NO ports. IF NDP$ = "M" THEN N3NO = 3 ELSE N3NO = NO REM**INCREMENT PORT NUMBER TO BE TESTED IN A LOOP FOR PN = 1 TO N3NO REM**INCREMENT TEST PATTERN IN A LOOP FOR D = 0 TO 255 OB(PN) = D IF NDP$ = "M" THEN OB(PN + 3) = D 'For SMINI case also set... '...second card's port to same bit pattern REM**OUTPUT BIT PATTERN TO OUTPUT CARD CALL OUTPUTS 'Invoke transmit subroutine FOR IJ = 1 TO 1000: NEXT IJ 'Basic delay to slow program... '...to read LEDs on output card REM**ADD DELAY TO ACCOUNT FOR INPUT LINE FILTERING IF INFILTER > 0 THEN 'Add delay loop if INFILTER non-zero FOR I = 1 TO INFILTER 'Delay to compensate for input card filtering FOR IJ = 1 TO 100 'Stretch length of effective delay NEXT IJ NEXT I END IF REM**READ BIT PATTERN FROM INPUT CARD CALL INPUTS 'Invoke receive subroutine REM**OUTPUT TEST STATUS TO CRT IF PRTIO = 1 THEN PRINT "PORT IS "; PNU$(PN); " DEC OUT = "; OB(PN); " DEC IN = "; IB(PN) END IF REM**COMPARE INPUT TO OUTPUT AND BRANCH TO CONTINUE LOOP IF NO ERROR IF IB(PN) = OB(PN) THEN GOTO CLOOP REM**ERROR FOUND SO PRINT TO CRT IF PRTIO = 1 THEN PRINT "ERROR FOUND IN ABOVE I/O, ENTER RETURN TO CONTINUE TEST" INPUT CR 'Input carriage return (enter key) to continue ELSE PRINT "PORT IS "; PNU$(PN); " DEC OUT = "; OB(PN); " DEC IN = "; IB(PN) PRINT "ERROR FOUND IN ABOVE I/O, CONTINUING TEST" END IF REM**COMPLETE LOOPS CLOOP: NEXT D 'Increment to next bit pattern for port OB(PN) = 0 'Zero out port before starting new port IF NDP$ = "M" THEN OB(PN + 3) = 0 'For SMINI case also set... '...second card's port to 0 NEXT PN 'Increment to next port REM**REPEAT WRAPAROUND TEST GOTO WTESTR 'At end of port loops so branch back to repeat test REM**TERMINATE TESTING OPSYS: PRINT " " PRINT "TESTING IS BEING TERMINATED BY USER REQUEST" SYSTEM 'Return to system program DEFINT A-Z SUB INIT REM*************************************************** REM********SERIAL PROTOCOL SUBROUTINES**************** REM*************QB4.5 CALL VERSION******************** REM SPSQBC01.BAS DATED: JUNE 30, 2003 ** REM (Enhanced version for use with QuickBASIC V4.5) ** REM FOR USIC, SUSIC AND SMINI APPLICATIONS ** REM*************************************************** REM**EACH SPS PACKAGE CONTAINS 5 SEPARATE SUBROUTINES DEFINED AS: '1) INIT -- Invoked by application program to initialize node '2) INPUTS -- Invoked by application program to read input bytes... '...IB(1) up through IB(NI) from the interface hardware 'where NI = number of input ports contaned within node '3) OUTPUTS -- Invoked by application program to write output bytes... '...OB(1) up through OB(NO) to the interface hardware 'where NO = number of output ports contained within node '4) RXBYTE -- Used by INPUTS to read an input byte (INBYTE) into... '...the PC receive buffer from the interface hardware '5) TXPACK -- Used by INIT, INPUTS and OUTPUTS to formulate and... '...transmit data packet from PC to interface hardware REM********************************************** REM** ***INIT*** ** REM**************QB4.5 CALL VERSION************** REM** SUBROUTINE TO INITIALIZE NODE ** REM** for use with USIC, SUSIC and SMINI nodes ** REM********************************************** '**NOTE: This subroutine must be executed correctly prior to... ' ...invoking INPUTS and OUTPUTS subroutines ' Following parameters must be defined in the application... ' ...program prior to invoking INIT: ' UA = USIC address (range 0 to 127) unless using... ' ... Classic USIC with 68701 then range is 0 to 15 ' COMPORT = PC COM port = 1, 2, 3 or 4 ' BAUD100 = PC baud rate divided by 100 ' DL = USIC transmission delay ' NDP$ = Node definition parameter = "M", "N" or "X" ' NI = Number of input ports contained within node ' NO = Number of output ports contained within node ' MAXTRIES = Maximum number of PC tries to read input... ' ...bytes prior to PC aborting inputs 'For SMINI applications: ' NS = Number of 2-lead searchlight signals... ' ...requiring yellow oscillation feature 'Only for SMINI case when NS > 0 i.e. signals are present ' CT(1) through CT(6) = Card type definition elements... ' ...defining signal bit locations within each... ' ...of the SMINI's 6 output ports 'For SUSIC and USIC applications: ' NS = Number of I/O card sets of 4 ' CT(1) through CT(NS) = Card type definition elements... ' ...defining the card type arrangement within... ' ...each set of 4 cards REM**BEGIN INITIALIZATION OF USIC, SUSIC OR SMINI REM**Initialize intries counter and initialization error flag INTRIES = 0 'Initialize INTRIES counter to zero INITERR = 0 'Initialize error flag to zero REM**CHECK FOR VALID RANGE OF USIC ADDRESS 'NOTE: Range 0 - 15 is not checked for Classic USIC with 68701 IF UA > 127 THEN PRINT "**ERROR** UA = "; UA; " Out of range 0 to 127" INITERR = 1 END IF REM**CHECK FOR VALID NUMBER FOR PC COM PORT (COM1 THRU COM4)... '...and if valid number, assign Port Address IF COMPORT = 1 THEN PA = 1016: GOTO COMOK IF COMPORT = 2 THEN PA = 760: GOTO COMOK IF COMPORT = 3 THEN PA = 1000: GOTO COMOK IF COMPORT = 4 THEN PA = 744: GOTO COMOK PRINT "**ERROR** COMPORT = "; COMPORT; " MUST = 1, 2, 3 OR 4" INITERR = 1 COMOK: REM**CHECK FOR VALID BAUD RATE AND IF VALID SET LOWER ORDER BAUD LATCH IF BAUD100 = 96 THEN BAUDLS = 12: GOTO BAUDOK IF BAUD100 = 192 THEN BAUDLS = 6: GOTO BAUDOK IF BAUD100 = 288 THEN BAUDLS = 4: GOTO BAUDOK IF BAUD100 = 576 THEN BAUDLS = 2: GOTO BAUDOK IF BAUD100 = 1152 THEN BAUDLS = 1: GOTO BAUDOK PRINT "**ERROR** BAUD100 = "; BAUD100 PRINT "Valid BAUD100 values are 96, 192, 228, 576 and 1152" INITERR = 1 BAUDOK: REM**CHECK FOR VALID NODE DEFINITION PARAMETER AND BRANCH ACCORDINGLY IF NDP$ = "M" THEN GOTO CHKMINI IF NDP$ = "N" THEN GOTO CHKMAXI IF NDP$ = "X" THEN GOTO CHKMAXI PRINT "***ERROR*** NDP$ = "; NDP$; " must be set to M, N, OR X " PRINT "****INITIALIZATION TERMINATED DUE TO INVALID NDP$****" INITERR = 1 GOTO INITRET CHKMINI: REM*************BEGIN SMINI SPECIFIC PARAMETER CHECKING************ REM**CHECK FOR VALID NI, NO AND NS USING SMINI IF NI <> 3 THEN PRINT "INVALID NI = "; NI; "MUST BE NI = 3 FOR SMINI" INITERR = 1 END IF IF NO <> 6 THEN PRINT "INVALID NO = "; NO; "MUST BE NO = 6 FOR SMINI" INITERR = 1 END IF IF NS = 0 THEN GOTO INCHKCMP 'No signals so branch to initialization... '...checking complete REM**SMINI HAS 2-LEAD OSCILLATING SIGNAL SO CHECK IF NS IN RANGE IF NS > 24 THEN PRINT "**ERROR** NS = "; NS; " OUT OF RANGE 0 TO 24 FOR SMINI" INITERR = 1 END IF REM**CHECK FOR VALID CT ARRAY ELEMENTS WHILE COUNTING SIGNALS TO EQUAL NS NSCNT = 0 'Initialize signal count to zero FOR I = 1 TO 6 'Loop through 6 SMINI CT elements IF CT(I) = 0 THEN GOTO NEXTCT IF CT(I) = 3 THEN NSCNT = NSCNT + 1: GOTO NEXTCT IF CT(I) = 6 THEN NSCNT = NSCNT + 1: GOTO NEXTCT IF CT(I) = 12 THEN NSCNT = NSCNT + 1: GOTO NEXTCT IF CT(I) = 24 THEN NSCNT = NSCNT + 1: GOTO NEXTCT IF CT(I) = 48 THEN NSCNT = NSCNT + 1: GOTO NEXTCT IF CT(I) = 96 THEN NSCNT = NSCNT + 1: GOTO NEXTCT IF CT(I) = 192 THEN NSCNT = NSCNT + 1: GOTO NEXTCT IF CT(I) = 15 THEN NSCNT = NSCNT + 2: GOTO NEXTCT IF CT(I) = 27 THEN NSCNT = NSCNT + 2: GOTO NEXTCT IF CT(I) = 51 THEN NSCNT = NSCNT + 2: GOTO NEXTCT IF CT(I) = 99 THEN NSCNT = NSCNT + 2: GOTO NEXTCT IF CT(I) = 195 THEN NSCNT = NSCNT + 2: GOTO NEXTCT IF CT(I) = 30 THEN NSCNT = NSCNT + 2: GOTO NEXTCT IF CT(I) = 54 THEN NSCNT = NSCNT + 2: GOTO NEXTCT IF CT(I) = 102 THEN NSCNT = NSCNT + 2: GOTO NEXTCT IF CT(I) = 198 THEN NSCNT = NSCNT + 2: GOTO NEXTCT IF CT(I) = 60 THEN NSCNT = NSCNT + 2: GOTO NEXTCT IF CT(I) = 108 THEN NSCNT = NSCNT + 2: GOTO NEXTCT IF CT(I) = 204 THEN NSCNT = NSCNT + 2: GOTO NEXTCT IF CT(I) = 120 THEN NSCNT = NSCNT + 2: GOTO NEXTCT IF CT(I) = 216 THEN NSCNT = NSCNT + 2: GOTO NEXTCT IF CT(I) = 240 THEN NSCNT = NSCNT + 2: GOTO NEXTCT IF CT(I) = 63 THEN NSCNT = NSCNT + 3: GOTO NEXTCT IF CT(I) = 123 THEN NSCNT = NSCNT + 3: GOTO NEXTCT IF CT(I) = 243 THEN NSCNT = NSCNT + 3: GOTO NEXTCT IF CT(I) = 111 THEN NSCNT = NSCNT + 3: GOTO NEXTCT IF CT(I) = 207 THEN NSCNT = NSCNT + 3: GOTO NEXTCT IF CT(I) = 219 THEN NSCNT = NSCNT + 3: GOTO NEXTCT IF CT(I) = 126 THEN NSCNT = NSCNT + 3: GOTO NEXTCT IF CT(I) = 222 THEN NSCNT = NSCNT + 3: GOTO NEXTCT IF CT(I) = 246 THEN NSCNT = NSCNT + 3: GOTO NEXTCT IF CT(I) = 252 THEN NSCNT = NSCNT + 3: GOTO NEXTCT IF CT(I) = 255 THEN NSCNT = NSCNT + 4: GOTO NEXTCT PRINT "**ERROR** INVALID CT("; I; ") = "; CT(I); " FOR SMINI" INITERR = 1 NEXTCT: NEXT I IF NSCNT <> NS THEN PRINT "**ERROR** SIGNAL COUNT FROM CTs <> NS FOR SMINI" INITERR = 1 END IF GOTO INCHKCMP 'Proceed to initialization checking REM*************BEGIN SUSIC SPECIFIC PARAMETER CHECKING************ REM**CHECK FOR VALID NS AND CTs USING USIC AND SUSIC CHKMAXI: IF NS = 0 OR NS > 16 THEN PRINT "**ERROR** NS ="; NS; " OUT OF RANGE 1 TO 16 FOR SUSIC NODE" INITERR = 1 END IF NICT = 0: NOCT = 0 'Initialize I/O type card counters to zero REM**GO THROUGH CT ELEMENT TO CHECK IF VALID AND COUNT I/O CARDS FOR I = 1 TO NS IF I = NS THEN 'Note: These CT( ) elements valid only for last card set IF CT(I) = 2 THEN NOCT = NOCT + 1: GOTO NEXTCTU IF CT(I) = 1 THEN NICT = NICT + 1: GOTO NEXTCTU IF CT(I) = 10 THEN NOCT = NOCT + 2: GOTO NEXTCTU IF CT(I) = 6 THEN NOCT = NOCT + 1: NICT = NICT + 1: GOTO NEXTCTU IF CT(I) = 9 THEN NOCT = NOCT + 1: NICT = NICT + 1: GOTO NEXTCTU IF CT(I) = 5 THEN NICT = NICT + 2: GOTO NEXTCTU IF CT(I) = 42 THEN NOCT = NOCT + 3: GOTO NEXTCTU IF CT(I) = 26 THEN NOCT = NOCT + 2: NICT = NICT + 1: GOTO NEXTCTU IF CT(I) = 38 THEN NOCT = NOCT + 2: NICT = NICT + 1: GOTO NEXTCTU IF CT(I) = 22 THEN NOCT = NOCT + 1: NICT = NICT + 2: GOTO NEXTCTU IF CT(I) = 41 THEN NOCT = NOCT + 2: NICT = NICT + 1: GOTO NEXTCTU IF CT(I) = 25 THEN NOCT = NOCT + 1: NICT = NICT + 2: GOTO NEXTCTU IF CT(I) = 37 THEN NOCT = NOCT + 1: NICT = NICT + 2: GOTO NEXTCTU IF CT(I) = 21 THEN NICT = NICT + 3: GOTO NEXTCTU END IF IF CT(I) = 170 THEN NOCT = NOCT + 4: GOTO NEXTCTU IF CT(I) = 106 THEN NOCT = NOCT + 3: NICT = NICT + 1: GOTO NEXTCTU IF CT(I) = 154 THEN NOCT = NOCT + 3: NICT = NICT + 1: GOTO NEXTCTU IF CT(I) = 90 THEN NOCT = NOCT + 2: NICT = NICT + 2: GOTO NEXTCTU IF CT(I) = 166 THEN NOCT = NOCT + 3: NICT = NICT + 1: GOTO NEXTCTU IF CT(I) = 102 THEN NOCT = NOCT + 2: NICT = NICT + 2: GOTO NEXTCTU IF CT(I) = 150 THEN NOCT = NOCT + 2: NICT = NICT + 2: GOTO NEXTCTU IF CT(I) = 86 THEN NOCT = NOCT + 1: NICT = NICT + 3: GOTO NEXTCTU IF CT(I) = 169 THEN NOCT = NOCT + 3: NICT = NICT + 1: GOTO NEXTCTU IF CT(I) = 105 THEN NOCT = NOCT + 2: NICT = NICT + 2: GOTO NEXTCTU IF CT(I) = 153 THEN NOCT = NOCT + 2: NICT = NICT + 2: GOTO NEXTCTU IF CT(I) = 89 THEN NOCT = NOCT + 1: NICT = NICT + 3: GOTO NEXTCTU IF CT(I) = 165 THEN NOCT = NOCT + 2: NICT = NICT + 2: GOTO NEXTCTU IF CT(I) = 101 THEN NOCT = NOCT + 1: NICT = NICT + 3: GOTO NEXTCTU IF CT(I) = 149 THEN NOCT = NOCT + 1: NICT = NICT + 3: GOTO NEXTCTU IF CT(I) = 85 THEN NICT = NICT + 4: GOTO NEXTCTU PRINT " **ERROR**INVALID CT("; I; ") = "; CT(I); " OR CT POSITIONING" NEXTCTU: NEXT I REM**CONVERT I/O CARD COUNTS TO PORT COUNTS IF NDP$ = "N" THEN NOCT = NOCT * 3: NICT = NICT * 3 IF NDP$ = "X" THEN NOCT = NOCT * 4: NICT = NICT * 4 REM**CHECK IF PORT COUNTS EQUAL NUMBER OF PORTS INPUTTED IF NOCT <> NO THEN PRINT "**ERROR**NUMBER OF OUTPUT PORTS COUNTED IN CT NOT EQUAL TO NO" INTERR = 1 END IF IF NICT <> NI THEN PRINT "**ERROR**NUMBER OF INPUT PORTS COUNTED IN CT NOT EQUAL TO NI" INTERR = 1 END IF INCHKCMP: REM*********INITIALIZATION PARAMETER CHECKING IS COMPLETE********** REM**SET UP UART IN PC OUT PA + 3, 128 'Turn on bit 7 of UART's line control... '...register (LCR) to access baud rate OUT PA, BAUDLS 'Set LS latch for desired baud rate OUT PA + 1, 0 'Set MS latch = 0 for all in use baud rates OUT PA + 3, 7 'Set up UART for 8 data bits and 2 stop bits 'Note: including the 2 stop bits is... '...recommended especially at the higher... '...baud rates of 57600 and 115200. However... '...if you are only using baud rates of... '...28800 and below you can replace the above... '...line with the following line providing 1... '...stop bit that will speed up response a bit. 'OUT PA + 3, 3 'Optional, set up UART for 8 data bits... '...and 1 stop bit REM**DEFINE INITIALIZATION MESSAGE PARAMETERS MT = ASC("I") 'Define message type = "I" (decimal 73) OB(1) = ASC(NDP$) 'Define node definition parameter OB(2) = INT(DL / 256) 'Set USIC delay high-order byte OB(3) = DL - (OB(2) * 256) 'Set USIC delay low-order byte OB(4) = NS 'Define number of card sets of 4 for... 'USIC and SUSIC cases and the... '...number of 2-lead yellow aspect... '...oscillating signals for the SMINI. LM = 4 'Initialize length of message to start of loading CT elements REM**CHECK TYPE OF NODE TO CONTINUE SPECIFIC INITIALIZATION IF NDP$ = "M" THEN GOTO INITSMINI 'SMINI node so branch accordingly INITUSIC: REM**SUSIC-NODE (either "N" or "X") SO LOAD CT( ) ARRAY ELEMENTS FOR I = 1 TO NS 'Loop through number of card sets... LM = LM + 1 '...accumulating message length while... OB(LM) = CT(I) '...loading card type definition CT... NEXT I '...array elements into output byte array GOTO TXMSG 'CT( )s complete so branch to transmit initialization... '...message to interface INITSMINI: REM**SMINI-NODE ("M") SO CHECK IF REQUIRES 2-LEAD OSCILLATION... '...SEARCHLIGHT SIGNALS IF NS = 0 THEN GOTO TXMSG 'No signals so hold message length at... '...LM = 4 and branch to transmit packet REM**SMINI CASE WITH SIGNALS (NS > 0) SO LOOP THROUGH TO LOAD... FOR I = 1 TO 6 '...signal location CT array elements... LM = LM + 1 '...into output byte array while... OB(LM) = CT(I) '...accumulating message length NEXT I REM**FORM INITIALIZATION PACKET AND TRANSMIT TO INTERFACE TXMSG: CALL TXPACK 'Invoke transmit packet subroutine REM**COMPLETED USE OF OUTPUT BYTE ARRAY SO CLEAR IT BEFORE EXIT SUBROUTINE FOR I = 1 TO NO: OB(I) = 0: NEXT I INITRET: 'Return to application program END SUB DEFINT A-Z SUB INPUTS REM****************************************************** REM** ***INPUTS*** ** REM**************QB4.5 CALL VERSION********************** REM** SUBROUTINE TO READ INPUT BYTES IB(1) THRU IB(NI) ** REM** for use with USIC, SUSIC and SMINI nodes ** REM****************************************************** REM**TRANSMIT POLL REQUEST TO INITIATE RECEIVING DATA BACK FROM... '...INTERFACE HARDWARE REPOL: MT = ASC("P") 'Define message type as poll request "P" (decimal 80) CALL TXPACK 'Invoke transmit packet subroutine to transmit... ' ...poll request message to external hardware REM**LOOP ON RECEIVING INPUT BYTES UNTIL RECEIVE A Start-of-Text (STX) GETSTX: CALL RXBYTE 'Receive input byte IF ABORTIN = 1 THEN GOTO INPUTRET IF INBYTE <> 2 THEN GOTO GETSTX 'input byte not STX so branch... '...back to read another byte REM**RECEIVED STX SO READ NEXT BYTE AND SEE IF RETURNED DATA IS... '...COMING FROM THE CORRECT USIC ADDRESS CALL RXBYTE 'Receive input byte which should be USIC address IF ABORTIN = 1 THEN GOTO INPUTRET INBYTE = INBYTE - 65 'Subtract offset of 65 from address and... '...check that matches node that was polled IF INBYTE <> UA THEN PRINT "ERROR; Received bad UA = "; IB: GOTO REPOL REM**CORRECT UA IS REPLYING BACK TO PC SO CHECK IF "R" MESSAGE CALL RXBYTE 'Receive input byte which shoud be "R" (decimal 82) IF ABORTIN = 1 THEN GOTO INPUTRET IF INBYTE <> 82 THEN PRINT "Error received not = R for UA = "; UA: GOTO REPOL REM**MESSAGE IS "R" SO LOOP THROUGH READING INPUTS FROM INPUT PORTS... '...ON INTERFACE HARDWARE FOR I = 1 TO NI 'Loop through number of input ports CALL RXBYTE 'Receive input byte IF ABORTIN = 1 THEN GOTO INPUTRET IF INBYTE = 2 THEN PRINT "ERROR: No DLE ahead of 2 for UA = "; UA: GOTO REPOL IF INBYTE = 3 THEN PRINT "ERROR: No DLE ahead of 3 for UA = "; UA: GOTO REPOL IF INBYTE = 16 THEN CALL RXBYTE 'DLE so read next byte and... IB(I) = INBYTE '...store as valid input byte NEXT I REM**RECEIVED ALL NI INPUT BYTES SO CHECK FOR End-of-Text (ETX = 3) CALL RXBYTE 'Receive input byte which should be ETX IF ABORTIN = 1 THEN GOTO INPUTRET IF INBYTE <> 3 THEN PRINT "ERROR: ETX NOT PROPERLY RECEIVED FOR UA = "; UA INPUTRET: 'Receive message complete so execute return 'Note: if aborted inputs then ABORTIN = 1 else = 0 END SUB DEFINT A-Z SUB OUTPUTS REM******************************************************** REM** ***OUTPUTS*** ** REM******************QB4.5 CALL VERSION******************** REM** SUBROUTINE TO WRITE OUTPUT BYTES OB(1) THRU OB(NO) ** REM** for use with USIC, SUSIC and SMINI nodes ** REM******************************************************** REM**TRANSMIT DATA FROM PC TO OUTPUT PORTS ON INTERFACE HARDWARE MT = ASC("T") 'Define message type = "T" (decimal 84) LM = NO 'Define message length as number of output ports CALL TXPACK 'Invoke transmit packet subroutine 'Transmit message complete so return to calling program END SUB DEFINT A-Z SUB RXBYTE REM************************************************ REM** ***RXBYTE*** ** REM*************QB4.5 CALL VERSION***************** REM** SUBROUTINE TO RECEIVE BYTE AT PC FROM NODE ** REM** for use with USIC, SUSIC and SMINI nodes ** REM************************************************ REM**Note: Reference page 41 of Serial Port Complete book for... REM**...more detailed definition and usage of line control... REM**...register (LCR) and line status register (LSR) as... REM**...applicable to standard 8250, 15450 and 16550 UARTs. REM**INITIALIZE INPUT TRIES COUNTER AND ABORTING INPUT FLAG INTRIES = 0 'Initialize input tries counter to 0 ABORTIN = 0 'Initialize aborting input flag to 0 REM**SET UP A MAJOR LOOP STARTING AT INLOOP FOR PC TO RECEIVE AN... '...INPUT BYTE FROM THE INTERFACE HARDWARE REM**START LOOP BY CHECKING FOR PC OVERRUN ERROR INLOOP: LSR = INP(PA + 5) 'Read UART's line status register (LSR)... IF (LSR AND 2) <> 0 THEN '...and if bit 1 set, PC has overrun... '...error, so print error message PRINT "PC overrun at node = "; UA; "line status register = "; LSR END IF REM**CHECK IF INPUT TRIES EXCEED MAXIMUM ALLOWED INTRIES = INTRIES + 1 'Increment input tries counter IF INTRIES > MAXTRIES THEN 'If counter exceeds maximum tries... ' ...then abort reading inputs ABORTIN = 1: INTRIES = 0 PRINT "INPUT TRIES EXCEEDED = "; MAXTRIES; " NODE = "; UA; "ABORTING INPUT" INBYTE = 0 'Aborted input so set input byte value to 0... GOTO RXRET '...and branch to receive input byte return END IF REM**READING INPUTS NOT ABORTED SO CHECK PC LINE STATUS REGISTER... '...TO SEE IF INPUT BUFFER IS LOADED LSR = INP(PA + 5) 'Read UART's line status register (LSR) and... IF (LSR AND 1) = 0 THEN GOTO INLOOP '...if input buffer not... '...yet loaded (bit 0 in LSR is clear)... '...then branch back to beginning of... '...input loop to try read again REM**PC SERIAL INPUT BUFFER IS LOADED SO RECEIVED INPUT BYTE INBYTE = INP(PA) 'Transfer received input byte available from COM... '...port address (PA) to input byte working register 'PRINT INBYTE '!!!!Optional printout of input byte for test and debug 'Note: Invoking this print slows PC... '...significantly so will most likely need... '...to significantly increase USIC delay (DL) RXRET: 'Received byte complete so return to calling program END SUB DEFINT A-Z SUB TXPACK REM*************************************************** REM** ***TXPACK*** ** REM**************QB4.5 CALL VERSION******************* REM** SUBROUTINE TO TRANSMIT PACKET FROM PC TO NODE ** REM** for use with USIC, SUSIC and SMINI nodes ** REM*************************************************** REM**FORM PACKET TO SEND TO USIC, SUSIC OR SMINI TB(1) = 255 'Set 1st start byte to all 1's TB(2) = 255 'Set 2nd start byte to all 1's TB(3) = 2 'Define start-of-text (STX = 2) TB(4) = UA + 65 'Add 65 offset to USIC address TB(5) = MT 'Define message type TP = 6 'Define next position for transmit pointer IF MT = 80 THEN GOTO ENDMSG 'Poll request so branch to end message REM**LOOP TO SET UP OUTPUT DATA IN TRANSMIT BUFFER INCLUDING THE... '...ADDING IN OF DLE BYTES WHERE NEEDED FOR I = 1 TO LM 'Loop to set up output data... '...including DLE processing IF OB(I) = 2 THEN TB(TP) = 16: TP = TP + 1: GOTO DATABYT IF OB(I) = 3 THEN TB(TP) = 16: TP = TP + 1: GOTO DATABYT IF OB(I) = 16 THEN TB(TP) = 16: TP = TP + 1 DATABYT: TB(TP) = OB(I) 'Move actual data byte to transmit buffer TP = TP + 1 'Increment pointer to next byte position NEXT I REM**END MESSAGE FORMULATION WITH End-of-text ENDMSG: TB(TP) = 3 'Add end-of-text (ETX = 3) REM**TRANSMIT PACKET TO USIC, SUSIC OR SMINI FOR I = 1 TO TP 'Loop through transmit buffer to transmit EMTY: LSR = INP(PA + 5) 'Read UART's line status register (LSR) and... IF (LSR AND 32) = 0 THEN GOTO EMTY '...if transmit holding... '...register is full (bit 5 in LSR is clear)... '...then branch back to wait for register to empty OUT PA, TB(I) 'Transmit holding register is empty so can... 'transmit byte out the serial port PA 'PRINT TB(I); '!!!!Optional printout of transmitted byte for... '...test and debug. Note: Invoking this print... '...slows PC significantly so will most likely... '...need to significantly increase USIC delay (DL) '...between each byte NEXT I 'Increment to pick up next output byte 'Transmission of output byte is complete so execute return END SUB