;===================================================================== ; ; LOGICMOD.ASM ; ;===================================================================== ; ; This microcode controls the pressure and forward-flow solenoids (or ; valves) for the hydraulic system in REKLAB. The state of the valves ; is determined by monitoring the external signals below and responding ; according to a designed state-flow diagram. ; ; External signals: ; ----------------- ; - Pump status ; - Pressure On/Off push buttons ; - Fwd Flow On/Off push buttons ; - Panic button status ; ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; ; OSCILLATOR ; ---------- ; An RC-oscillator is used to drive the microprocessor as frequency ; stability/accuracy is not an issue. The frequency need be high enough ; to give a timely response to user input (~ 100KHz should do). ; ; PORT INTERFACE ; -------------- ; RA0: Forward Flow Valve control o/p (0 = Off, 1 = On) ; RA1: Pressure valve control o/p (0 = Off, 1 = On) ; RA2: LED Invalid Operation indicator o/p ; RA3: N/C o/p ; RA4: Heartbeat o/p (Toggles each loop pass) ; ; RB0: Pressure "On" push button i/p (Active low) ; RB1: Pressure "Off" push button i/p (Active low) ; RB2: Forward-Flow "On" push button i/p (Active low) ; RB3: Forward-Flow "Off" push button i/p (Active low) ; RB4: Pump status i/p (0 = Off, 1 = On) ; RB5: Panic button i/p (0 = OK, 1 = Panic) ; RB6: N/C i/p ; RB7: N/C i/p ; ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; ; (c) McGill University ; Biomedical Engineering Department ; Montreal, Quebec, Canada ; ; V1.0 MAY 21, 2001 - (Ross Wagner) Created file. ; ; V1.1 JUL 02, 2001 - (Ross Wagner) Added ability to reset state ; machine when in "invalid operation" mode by depressing both pressure ; and fwd-flow off buttons simultaneously. ; ; ;===================================================================== ;********************************************************************* ; CPU configuration ;********************************************************************* ; PIC16F84 microprocessor ; Code protection off, Power-up timer on, Watchdog timer off, ; RC oscillator. processor 16f84 include __config _CP_OFF & _PWRTE_ON & _WDT_OFF & _RC_OSC ;********************************************************************* ; EEPROM data ;********************************************************************* ; Store microcode version number on-chip. org H'2100' de "Logicmod V1.1", 0 de "2001-07-02", 0 ;********************************************************************* ; Assembler constant declarations ;********************************************************************* ; PORTA bit positions: _FFVC equ 0x00 ; Fwd Flow valve control line _PRVC equ 0x01 ; Pressure valve control line _LEDC equ 0x02 ; LED status light control line _HRTBT equ 0x04 ; Heartbeat monitor line ; PORTB bit positions: _PRON equ 0x00 ; Pressure "On" button (S' i/p) _PROFF equ 0x01 ; Pressure "Off" button (R' i/p) _FFON equ 0x02 ; Fwd Flow "On" button (S' i/p) _FFOFF equ 0x03 ; Fwd Flow "Off" button (R' i/p) _PUMP equ 0x04 ; Pump status _PANIC equ 0x05 ; Panic button ; S'R' Latch bit positions: _LRN equ 0x00 ; R' _LSN equ 0x01 ; S' _LQ equ 0x02 ; Q ; Table index bit positions: _TQ1 equ 0x05 ; Q1 _TQ0 equ 0x04 ; Q0 _TPUMP equ 0x03 ; Pump status _TPR equ 0x02 ; Pressure state _TFF equ 0x01 ; Fwd Flow state _TPAN equ 0x00 ; Panic state ; Table output bit positions: _TQ1P equ 0x07 ; Q1+ _TQ0P equ 0x06 ; Q0+ _TLED equ 0x05 ; LED drive _TPRV equ 0x04 ; Pressure Valve drive _TFFV equ 0x03 ; Fwd Flow Valve drive ;********************************************************************* ; Macro definitions ;********************************************************************* ; Macro --- Bit-to-Byte conversion ----------------------------------- ; ; Tests the bit (b) of a source file register (file) and sets the ; target file (byte) to either 0xFF (if bit is set) or 0x00 (if bit ; is clear). ; ; file: file register ; b: bit number, 0 <= b <= 7 ; byte: file register ; ; Use this to setup a register for byte-oriented boolean operations. ; -------------------------------------------------------------------- b2byte macro file, b, byte clrf byte ; = 0x00 btfsc file, b ; if bit set then comf byte, F ; = 0xFF endm ; Macro --- Byte-to-Bit conversion ----------------------------------- ; ; Clears the bit (b) of a destination file register (file) if source ; file register (byte) is 0x00 and otherwise sets the bit. ; ; byte: file register ; b: bit number, 0 <= b <= 7 ; file: file register ; -------------------------------------------------------------------- byte2b macro byte, b, file bsf file, b ; Set destination file bit movf byte, F ; := btfsc STATUS, Z ; if = 0x00 bcf file, b ; then clear destination file bit endm ; Macro --- Bit transfer --------------------------------------------- ; ; Copies bit value of source file register, fsrc, at bit position bs to ; destination file register, fdest, at bit position bd. ; ; fsrc: file register ; bs: bit number, 0 <= bs <= 7 ; fdest: file register ; db: bit number, 0 <= bd <= 7 ; -------------------------------------------------------------------- bxfr macro fsrc, bs, fdest, bd bsf fdest, bd ; Set destination bit btfss fsrc, bs ; If source bit clear bcf fdest, bd ; then clear destination bit endm ; Macro --- Boolean AND Op ------------------------------------------- ; ; Evaluates the boolean expression = .AND. ; ; arg1: file register ; arg2: file register ; out: file register ; ; -------------------------------------------------------------------- and macro arg1, arg2, out movf arg1, W ; w := andwf arg2, W ; w := w .AND. movwf out ; := w endm ; Macro --- Boolean NAND Op ------------------------------------------ ; ; Evaluates the boolean expression = .NAND. ; ; arg1: file register ; arg2: file register ; out: file register ; ; -------------------------------------------------------------------- nand macro arg1, arg2, out and arg1, arg2, out ; = .AND. comf out, F ; = .NOT. endm ; Macro --- Bit Complementation -------------------------------------- ; ; Complements the b-th bit of a file register (arg). (Uses TEMP ; scratch variable.) ; ; arg: file register ; b: bit number, 0 <= b <= 7 ; ; -------------------------------------------------------------------- bcomf macro arg, b movf arg, W ; w := movwf TEMP ; TEMP := w comf TEMP, F ; TEMP := .NOT. TEMP bxfr TEMP, b, arg, b ; Transfer bit from TEMP to endm ;********************************************************************* ; Assign memory locations for variable storage ;********************************************************************* PR_LATCH equ 0x0C ; Pressure S'R' latch vector FF_LATCH equ 0x0D ; Forward-Flow S'R' latch vector PORTA_BUF equ 0x0E ; Storage for Port A values PORTB_BUF equ 0x0F ; Storage for port B values (latch) MACHINE equ 0x10 ; Machine state vector (See Table:) TEST equ 0x48 ; Scratch variable TEMP equ 0x49 ; Scratch variable INDEX equ 0x4A ; Index into state-transition table ; Variables needed for S'R' latch LATCH equ 0x4B ; - I/O arguments for SRlatch routine SRQ equ 0x4C ; - Internal variable (Q o/p) SRQN equ 0x4D ; - Internal variable (Q' o/p) SNOT equ 0x4E ; - Internal variable (S' i/p) RNOT equ 0x4F ; - Internal variable (R' i/p) ;********************************************************************* ;********************************************************************* ; ; PROGRAM STARTS HERE ; ;********************************************************************* ;********************************************************************* org 0x00 ; Set prog memory base at reset vector goto Start org 0x04 ; Set prog memory base at interrupt vector Start: ; At startup all ports are inputs. ; Set port A for output on all pins. clrf PORTA_BUF ; Clear output vector movf PORTA_BUF, W ; and copy to output movwf PORTA ; port latch. bsf STATUS, RP0 ; Select Bank 1 movlw B'00000000' ; Set all pins as o/p movwf TRISA ; Apply configuration ; Now config port B bcf OPTION_REG, NOT_RBPU ; Enable internal pull-ups bcf STATUS, RP0 ; Select Bank 0 bcf INTCON, GIE ; Disable all interrupts ; Port A is now putting out 0x00 ; To be consistent with this scenario both pressure and forward ; flow must be off. Set their latch vectors accordingly. movlw B'00000011' ; See SRlatch subroutine for details movwf PR_LATCH ; movwf FF_LATCH ; ; Also, the machine state at the power-up is defined to be 00 clrf MACHINE Loop: ; See what is happening in the world... movf PORTB, W ; Read PORTB, store in w movwf PORTB_BUF ; Latch PORTB values ; Pump status is actually using negative logic: A low signal ; indicates that the pump is "On". Need to flip this bit in ; order to be consistent with expectations of this program. bcomf PORTB_BUF, _PUMP ; Update the PRESSURE latch vector to register any push button ; having been depressed during port sample. ; ; Transfer state of pressure S' bit of port input to appropriate ; bit of pressure S'R' latch vector. Then do the same for the R' ; input. bxfr PORTB_BUF, _PRON, PR_LATCH, _LSN bxfr PORTB_BUF, _PROFF, PR_LATCH, _LRN ; Compute resulting latch states. movf PR_LATCH, W ; Need to copy PR_LATCH to i/o movwf LATCH ; variable used by subroutine. call SRlatch ; Get the latch states. movf LATCH, W ; Store result in pressure latch vector. movwf PR_LATCH ; ; Update the FORWARD FLOW latch vector to register any push button ; having been depressed during port sample. ; ; Transfer state of forward flow S' bit of port input to appropriate ; bit of forward flow S'R' latch vector. Then do the same for the R' ; input. bxfr PORTB_BUF, _FFON, FF_LATCH, _LSN bxfr PORTB_BUF, _FFOFF, FF_LATCH, _LRN ; Compute resulting latch states. movf FF_LATCH, W ; Need to copy FF_LATCH to i/o movwf LATCH ; variable used by subroutine. call SRlatch ; Get the latch states. movf LATCH, W ; Store result in fwd flow latch vector. movwf FF_LATCH ; ; Cross-reference state-transition table to determine next ; state of the state machine. ; Setup table index (See Table for details). clrf INDEX bxfr MACHINE, _TQ1P, INDEX, _TQ1 ; Q1 state bxfr MACHINE, _TQ0P, INDEX, _TQ0 ; Q0 state bxfr PORTB_BUF, _PUMP, INDEX, _TPUMP ; Pump status bxfr PR_LATCH, _LQ, INDEX, _TPR ; Pressure state bxfr FF_LATCH, _LQ, INDEX, _TFF ; Fwd Flow state bxfr PORTB_BUF, _PANIC, INDEX, _TPAN ; Panic state movf INDEX, W ; Prepare for table lookup. call Table ; Do it. movwf MACHINE ; Save result. ; Check for over-riding reset condition. A reset places the ; machine into the "power-up" mode and is allowed when the ; machine is in the invalid-operation mode and both pressure ; and forward-flow "off" buttons are depressed. clrf TEST ; Setup test bits bxfr MACHINE, _TQ1P, TEST, 2 ; Q1 state bxfr PORTB_BUF, _PROFF, TEST, 1 ; Pressure off i/p bxfr PORTB_BUF, _FFOFF, TEST, 0 ; Fwd-flow off i/p movf TEST, F ; if TEST = 0x00 btfsc STATUS, Z ; then reset condition present clrf MACHINE ; reset machine state. ; The resulting pressure and forward-flow valve drives need to ; match the pressure and fwd-flow states stored in their ; respective S'R' latches. When the machine states are directed ; solely by the pressure and fwd-flow push buttons then this ; happens automatically. Under all other circumstances there ; will be a mismatch and the valve drives must update the ; push-button latches. Hence the valve-drive states can ; override the latch states without unwanted consquences. ; Do that now. bxfr MACHINE, _TPRV, PR_LATCH, _LQ bxfr MACHINE, _TFFV, FF_LATCH, _LQ ; Now ready to output to the world... ; Setup output vector bxfr MACHINE, _TLED, PORTA_BUF, _LEDC bxfr MACHINE, _TPRV, PORTA_BUF, _PRVC bxfr MACHINE, _TFFV, PORTA_BUF, _FFVC ; Place a heartbeat on an o/p pin that toggles each time ; through this loop. It gives the user a way of monitoring ; program execution. bcomf PORTA_BUF, _HRTBT ; Now write to the world movf PORTA_BUF, W movwf PORTA goto Loop ;********************************************************************* ; Subroutine and Table definitions ;********************************************************************* SRlatch: ; -------------------------------------------------------------------- ; Subroutine ; ========== ; ; Implements an S'R' latch (read "not" for ') ; ; Original latch state, current inputs, and resulting latch state ; are passed via file register LATCH with the following encoding ; scheme: ; ; LATCH<2>: Current Q state (S' NAND gate o/p) ; LATCH<1>: Current S' i/p ; LATCH<0>: Current R' i/p ; ; Upon completion of this routine new latch sate will be returned in ; LATCH<2>. In the illegal input case of S' = 0 and R' = 0 the latch ; state remains unchanged. ; -------------------------------------------------------------------- btfss LATCH, _LSN ; Check latch inputs goto chkr ; S' = 0 (trouble if also R' = 0) goto srok chkr: btfss LATCH, _LRN return ; R' = 0. Illegal. Do nothing. srok: ; Inputs valid. Determine new latch state. ; Extract LATCH bits into file registers for processing b2byte LATCH, _LQ, SRQ b2byte LATCH, _LSN, SNOT b2byte LATCH, _LRN, RNOT comf SRQ, W ; Create Q' state movwf SRQN ; ; Evaluate the boolean equations for the latch. ; Need 3 nand evals in order to handle case where ; (S', R') goes from (0,1) to (1,0). Otherwise, last ; statement is redundant. nand SNOT, SRQN, SRQ ; Q := (S' * Q')' nand RNOT, SRQ, SRQN ; Q' := (R' * Q )' nand SNOT, SRQN, SRQ ; Q := (S' * Q')' ; Pack result back into LATCH vector byte2b SRQ, _LQ, LATCH return Table: ; -------------------------------------------------------------------- ; State-transition table. Used to determine next machine state and ; outputs based on current machine state and inputs. ; ; The offset into the table is supplied via the W register, coded as ; follows: ; ; Bit Description ; ------------------------------- ; 7 Must be 0 ; 6 Must be 0 ; 5 Current machine state (Q1) ; 4 Current machine state (Q0) ; 3 Pump status (0 = off, 1 = on) ; 2 Pressure state (0 = off, 1 = on) ; 1 Forward-flow state (0 = off, 1 = on) ; 0 Panic button state (0 = Normal Operation, 1 = Panic) ; ; Table output is returned in the W register, coded as follows: ; ; Bit Description ; ------------------------------- ; 7 Next machine state (Q1+) ; 6 Next machine state (Q0+) ; 5 LED status light (0 = OK, 1 = invalid operation) ; 4 Pressure valve drive (0 = off, 1 = on) ; 3 Forward-flow valve drive (0 = off, 1 = on) ; 2 Reserved ; 1 Reserved ; 0 Reserved ; ; -------------------------------------------------------------------- addwf PCL, F ; Add table index to PC to generate ; a computed goto retlw B'00000000' ; Index 0 retlw B'00000000' ; Index 1 retlw B'00000000' ; Index 2 retlw B'00000000' ; Index 3 retlw B'00000000' ; Index 4 retlw B'00000000' ; Index 5 retlw B'00000000' ; Index 6 retlw B'00000000' ; Index 7 retlw B'00000000' ; Index 8 retlw B'00000000' ; Index 9 retlw B'00000000' ; Index 10 retlw B'01100000' ; Index 11 retlw B'10010000' ; Index 12 retlw B'01100000' ; Index 13 retlw B'01100000' ; Index 14 retlw B'01100000' ; Index 15 retlw B'00000000' ; Index 16 retlw B'00000000' ; Index 17 retlw B'00000000' ; Index 18 retlw B'00000000' ; Index 19 retlw B'00000000' ; Index 20 retlw B'00000000' ; Index 21 retlw B'00000000' ; Index 22 retlw B'00000000' ; Index 23 retlw B'01100000' ; Index 24 retlw B'01100000' ; Index 25 retlw B'01100000' ; Index 26 retlw B'01100000' ; Index 27 retlw B'01100000' ; Index 28 retlw B'01100000' ; Index 29 retlw B'01100000' ; Index 30 retlw B'01100000' ; Index 31 retlw B'00000000' ; Index 32 retlw B'00000000' ; Index 33 retlw B'00000000' ; Index 34 retlw B'00000000' ; Index 35 retlw B'00000000' ; Index 36 retlw B'00000000' ; Index 37 retlw B'00000000' ; Index 38 retlw B'00000000' ; Index 39 retlw B'00000000' ; Index 40 retlw B'01100000' ; Index 41 retlw B'01100000' ; Index 42 retlw B'01100000' ; Index 43 retlw B'10010000' ; Index 44 retlw B'10010000' ; Index 45 retlw B'11011000' ; Index 46 retlw B'01100000' ; Index 47 retlw B'00000000' ; Index 48 retlw B'00000000' ; Index 49 retlw B'00000000' ; Index 50 retlw B'00000000' ; Index 51 retlw B'00000000' ; Index 52 retlw B'00000000' ; Index 53 retlw B'00000000' ; Index 54 retlw B'00000000' ; Index 55 retlw B'00000000' ; Index 56 retlw B'01100000' ; Index 57 retlw B'01100000' ; Index 58 retlw B'01100000' ; Index 59 retlw B'10010000' ; Index 60 retlw B'10010000' ; Index 61 retlw B'11011000' ; Index 62 retlw B'10010000' ; Index 63 end ; of program