;--------------------------------------------
; FI Tester - Embedded Micro Code for MC68HC908JL3
; B.A. Bowling - A.C. Grippo
; (C) February 2001
; All Rights Reserved
; Code Works, but No Warranties
; For personal use only - not for public sale
;--------------------------------------------
;
; Hardware Channels:
;  PORTA[0-3]: Current Trip an npulses
;  PORTB[0-7]: Pulse Width
;  PORTD[2]: Transistor Drive - 4 Amps
;  PORTD[3]: Transistor Drive - 2 Amps
;  PORTD[4]: Transistor Drive - 1 Amp
;  PORTD[5]: Transistor Drive - 1/2 Amp
;  PORTD[6]: RUN LED
;--
;  Npulses DIP Switch Values:
;    00 = One Pulse
;    01 = 50 Shots
;    10 = 100 Shots
;    11 = 250 Shots
;--
;  Current Limit DIP Switch Values:
;    00 = 4 Amps
;    01 = 4 Amps -> 1 Amp
;    10 = 2 Amps
;    11 = 2 Amps -> 1/2 Amp
;---------------------------------------
;
RAMSTART     EQU  $0080
FLASH        EQU  $EC00
ROMSTART     EQU  $FC00
VECTORSTART  EQU  $FFDE

Timerstop    equ  %00110001     ;TSC
Timergo      equ  %01010001     ;TSC
TSC0_No_PWM  equ  %00010000     ;TSC0
IRQ_Int_Dis  equ  %00000111     ;INTSCR
IRQ_Int_Enb  equ  %00000101     ;INTSCR

; Port D Data Direction Values for Different Injector Currents
Drive_four   equ  %11000111
Drive_two    equ  %11001011
Drive_one    equ  %11010011
Drive_half   equ  %11100011
Drive_off    equ  %11000011

$include '08JL3header.asm'
 LIST

 ORG     RAMSTART
tms      rmb     $01            ; tenths of milliseconds (0.0001)
go       rmb     $01            ; 0 = off, 1 = on
curlimit rmb     $01            ; 0= no current limit, 1 = current limit
limitval rmb     $01            ; this is the ADC threshold where current limit kicks in
pw       rmb     $01            ; pulsewidth in "tms" units from DIP switch
npulses  rmb     $01            ; number of pulses from DIP switch
offtime  rmb     $01

 org    FLASH
MAIN:   MOV     #$01,CONFIG1    ;Disable the COP
        rsp                     ; reset the stack
        sei                     ; inhibit interrupts
        clra
        clrx
        mov     #%11000000,PORTD
        mov     #Drive_off,DDRD
        mov     #%00001100,PDCR  ;enable high current sink mode
        mov     #$00,PORTA
        mov     #$00,PORTB
        mov     #$00,DDRA
        mov     #$FF,PTAPUE     ;enable pullups
        mov     #$00,DDRB


; Set up the Timer
        MOV     #Timerstop,TSC        ; Stop Timer so it can be set up
        mov     #$00,TMODH
        mov     #$C8,TMODL      ; set timer modulus register to 200 decimal
        mov     #TSC0_No_PWM,TSC0       ; make this normal port output (PWM MODE is #$5E)
        mov     #$00,TCH0H
        mov     #$00,TCH0L
        MOV     #Timergo,TSC        ;  set timer prescaler to divide by two (for 16 MHz xtal) turn on

; Set up IRQ line
        mov     #IRQ_Int_Enb,INTSCR

; Initialize RAM Variables
        mov     #$00,tms
        mov     #$00,go
        mov     #$00,curlimit
        mov     #$00,pw
        mov     #$00,npulses
        mov     #$00,offtime

        cli


LOOPST: BRA     LOOPST  ; Loop here, waiting for Timer or IRQ interrupt

;--------------------------------------------
; Timer Overflow Interrupt Service Routine

TIMERROLL:
; Go will be non-zero if there is a "test" currently executing
        lda     go
        tsta
        beq     TRDONE

; Check to see if injector is currently on or is it a "off-time"
        lda     offtime
        beq     INCR_TMS

; We are in an off-time - decrement variable and check if finished
        lda     offtime
        deca
        sta     offtime
        bne     TRDONE

; YES - we are done with "off-time" -
; Now start another high bpulse here

        mov     curlimit,DDRD   ;Turn on injector with initial current value
        mov    #%10111111,PORTD ; Turn everything on on port, the data direction reg will select

INCR_TMS:
        lda     tms
        inca
        sta     tms

; Check if we have reached 3 milliseconds ($1E) and put in other current
        cmp     #$1E
        bne     CHECK_TMS
        mov     limitval,DDRD   ;Set in the current-limited value

; Check if tms is equal to pw - if so, then stop pulse and increment "go" variable
CHECK_TMS:
        lda     tms
        cmp     pw
        bne     TRDONE

;Increment "go", check if enough pulses have been sent out
INCR_GO:
        clra
        sta    tms      ; reset tms variable for next round
        mov    #Drive_half,DDRD    ; Turn on drive transistor to 1/2 current resistor, to allow base drain
        mov    #%10000001,PORTD ; Turn everything off on port, keep light on
        mov    #%01100100,offtime ;now set offtime to max value

        lda    go
        inca
        sta    go

        cmp    npulses
        beq    RUN_DONE
        bra    TRDONE

RUN_DONE
        clra
        sta    go
        sta    tms
        sta    offtime
        sta    curlimit
        sta    limitval
        mov    #$00,TCH0L
        mov    #Drive_half,DDRD    ; Turn on drive transistor to 1/2 current resistor, to allow base drain
        mov    #%11000011,PORTD ; Turn everything off on port, turn light off
;        bset   7,PORTD  ;turn off current limit light

TRDONE:
       lda      TSC
       bclr     7,TSC
 rti




;--------------------------------------------
; IRQ Button (trigger) Interrupt Service Routine

INTR:
        lda  #$01
        sta  go
        clra
        sta  tms

        mov  #Drive_off,DDRD
        mov  #%00111100,PORTD ; Turn everything on, LED on, let DDRD select which current
;check for current limit
        lda  PORTA
        coma
        and  #%00001100
        cmp  #%00000000
        beq  FOUR_AMPS
        cmp  #%00001000
        beq  FOUR_TO_ONE
        cmp  #%00000100
        beq  TWO_AMPS
        bra  TWO_TO_HALF

FOUR_AMPS:
        mov  #Drive_four,curlimit
        mov  #Drive_four,limitval
        bra  NPSET
FOUR_TO_ONE:
        mov  #Drive_four,curlimit
        mov  #Drive_one,limitval
        bra  NPSET
TWO_AMPS:
        mov  #Drive_two,curlimit
        mov  #Drive_two,limitval
        bra  NPSET
TWO_TO_HALF:
        mov  #Drive_two,curlimit
        mov  #Drive_half,limitval
        bra  NPSET

NPSET:
; Now check for number of pulses
        lda  PORTA
        coma            ;do this because DIP swith active low inputs
        and  #%00000011
        beq  SINGLE_SHOT
        cmp  #%00000010
        beq  FIFTY_SHOT
        cmp  #%00000001
        beq  HUNDRED_SHOT
                         ;Must be '11' -> default to 250 shots!

; NOTE - each of these include an added 1 to the number because the
;        count is incremented before it is checked against "npulses"

TWOFIFTY_SHOT:
        lda  #%11001001
        sta  npulses
        bra  INTR_EXIT

HUNDRED_SHOT:
        lda  #%01100101
        sta  npulses
        bra  INTR_EXIT

FIFTY_SHOT:
        lda  #%00110011
        sta  npulses
        bra  INTR_EXIT

SINGLE_SHOT:
        lda  #$02
        sta  npulses
        bra  INTR_EXIT

INTR_EXIT:
        mov  #%01100100,offtime

; Get the Pulsewidth from PORTB
        lda  PORTB
        coma      ;do this because DIP switch is active low
        sta  pw

IRQ_DONE:
 rti



 ORG TIMOVRFLOW
 DW TIMERROLL

 ORG IRQ
 DW INTR

 ORG     RESET
        DW   MAIN               ;Reset Vector
