ECU6 8051 assembly routines

Al Lipper alipper at cardozo.org
Sun Jan 31 20:20:44 GMT 1999


--=====================_98831695==_
Content-Type: text/plain; charset="us-ascii"

Wayne, I've attached the latest software.  Basically, we need the routines
in EFI02.ASM adapted from the Intel 80C51GB to the Phillips 80C552.  The
key routines are the ones that deal with the Intel's PCA - these need to
work with the Phillip's Capture/compare.  These are the RPM, Injector
turn-off and async injector pulse routines.  If you have some time to work
on it, that would be great.  Perhaps we can find someone else to help with
other parts of it also.  Just as a note, the hardware for the next version
ECU7, is almost complete.  Thanks.


			Al

BTW, if you need the assember, it's in the ZIP of all the EFI system files
(includes all the software) at: http://members.aol.com/ALIPPER/

At 02:52 PM 1/19/99 +1000, you wrote:
>Al 
>
>I wrote 8051 assembler for phillips and intel variants 5 or 6 years ago.
>I think you mentioned basic, C but  would be nice.
>Are you looking for some one with development tools.
>What needs doing ?
>I dunno how much time you need.
>

--=====================_98831695==_
Content-Type: text/plain; charset="us-ascii"
Content-Disposition: attachment; filename="EFI02.asm"

$NOPAGING
; 6/7/97 - added WDT routines
; efi00.asm     950204RHAL

;       ASM routines for Electronic Fuel Injection System.
;       Includes ISRs for RPM and injector pulsing.


; Using the 87C51GB.
$MOD51GB


;*************************************************************************

; Memory useage, Variable declaration, and Vector tables--

r0b0       equ    00h           ; Register R0, Bank0
r1b0       equ    01h           ; Register R1, Bank0

; Variables for use in/with ASM routines.

;       Note: Internal bits 00-0F use internal memory locations 20 and 21.
;       Internal Bits 00-07 for ASM only flags.

;       Internal Bits 08-0F for BASIC/ASM flags.
SP_SYNC    BIT    008h                  ; Set when Injector Pulse is to be
					;   Synchronized with Spark Pulse.
					;   Written by Main loop.  EX_ASYNC
					;   must be called by main loop when
					;   this value is changed.

;       Direct addresses 18H-21H of Internal RAM for BASIC/ASM variables.
;       These addresses are not used by the compiler
; External addresses FFF0-FFFF are used to transfer data to BASIC
OLD_CCAP0  DATA   018h                  ; Previous PCA0 capture value, 2
					;   bytes (lo-hi).  Used to compute
					;   Spark Pulse period.  Used only
					;   in ISR (Static Local).

PW1        DATA   01Ah                  ; Injector Pulse Width (count for
					;   PCA1), 2 bytes (lo-hi).  Data is
					;   passed from Main to ISR here.
					;   Main loop should clear EC0 when
					;   when writing these bytes.
RPMPW      DATA   01Ch                  ; Spark Pulse period, 2 bytes.  Data
					;   is passed from ISR to Main here.
					;   Main loop should clear EC0 when
					;   when reading these bytes.
APP        DATA   01Eh                  ; Async Injector Pulse Period.  Data
					;   is passed form Main to ISR here.
					;   Main loop should clear EC0 when
					;   when writing these bytes.
TICK15     XDATA   0FFF6H               ; Two byte counter, incremented
					;   every 15ms by WDT_ISR: for use by
					;   BASIC program in timed operations.

; A/D Converter addresses
ADC_0        DATA   084h                  ; A/D Converter channel 0
ADC_1        DATA   094h                  ; A/D Converter channel 1
ADC_2        DATA   0A4h                  ; A/D Converter channel 2
ADC_3        DATA   0B4h                  ; A/D Converter channel 3
ADC_4        DATA   0C4h                  ; A/D Converter channel 4
ADC_5        DATA   0D4h                  ; A/D Converter channel 5
ADC_6        DATA   0E4h                  ; A/D Converter channel 6
ADC_7        DATA   0F4h                  ; A/D Converter channel 7
ACON       DATA   097h                  ; A/D Converter control register
;A/D Converter uses FFF8-FFFF as mirror locations for the above registers
ADC_MIRR   XDATA  0FFF8h                ; A/D Mirror for transfer to BASIC

; Enter values into Interrupt Vector "Mirror."
	   ORG  0FE00H                  ; RESET VECTOR
	   JMP  WDT_INIT                ; INIT TIMER 0 FOR WDT RESET
	   ORG  0FE0Bh                  ; Timer 0           TF0
	   LJMP WDT_ISR                 ; WATCHDOG TIMER (WDT) ISR
	   ORG  0FE33h                  ; PCA INTERRUPT VECTOR LOCATION
	   LJMP ISR_PCA                 ; Jump to PCA Interrupt Handler.

;*************************************************************************

; BASIC call vectors--

	   ORG  0FE50H                  ; Put at very top of code memory
				     ; (must be decreased if code is expanded)

	   AJMP INIT                	; Init routine.
	   AJMP READ_ADC                ; Read A/D Converter
	   AJMP EX_ASYNC                ; Handle change of SP_SYNC.
	   AJMP IAC_HIGHER		; IAC motor init for higher idle
	   AJMP IAC_LOWER		; IAC motor init for lower idle
	   AJMP IAC_STEP		; Step IAC motor in selected direction
	   AJMP IAC_OFF			; Turn off power to IAC motor (doesn't move)

;*************************************************************************

; Startup routines--

    INIT:  				; Init stuff for ASM routines.
 setb p4.0    ;debug
	   MOV	IP,#01000010b           ; Set PPC and PT0 (PCA0 2nd, Timer0 1st)
	   MOV  IE,#11000010b           ; Enable global (EA), PCA (EC) and TIMER0 (ET0) ints.

	   MOV  CMOD,#00               ; Setup PCA Counter Mode. (f.osc/12)
	   MOV  CCON,#01000000b        ; Enable PCA counter (CR)
	   MOV  CCAPM0,#00100001b       ; Set PCA0 Mode: Capture positive
					;  edge and enable PCA interrupt.
	   SETB  SP_SYNC                ; Set flag to sync mode initially
	   ACALL EX_ASYNC               ; Set sync mode (based on flag)

	   MOV  DPTR, #TICK15           ; Clear 2 BASIC counter register
	   MOV  A, #00                  ;   bytes.
	   MOVX @DPTR, A                ;   Clear the first byte...
	   INC DPTR                     ;   then clear the second byte.
	   MOVX @DPTR, A                ; 

	   MOV  ACON,#00010000b         ; Enable A/D Converter

; Setup I/O ports.  Inputs must be set to 1 before they will work.
; See "8051 IO Ports.xls" for specific pin functions.
	   SETB P1.0	; Cranking
	   SETB P1.1	; Key on
	   SETB P1.3	; SP in	   
	   SETB P3.2	; External Int 0
	   SETB P3.4	; A/C on
	   SETB P5.2	; DIP SW 2
	   SETB P5.3	; DIP SW 1

  clr p4.0     ;debug
	   RET

;*************************************************************************

; Main Loop subroutines--

; ASM routine called by BASIC to start or end Async Injection Mode based on
;   Async Mode flag, must be called when ever SP_SYNC is changed.

EX_ASYNC:
;  setb p4.1    ;debug
	   MOV  CCAPM3,#0               ; Disable PCA3.
	   JB   SP_SYNC,EA_OFF          ; Check Sync Mode Flag.
					; Startup Async Mode.
	   CLR  CCF3                    ;    Clear any pending IRQ for PCA3.
	   MOV  CCAP3L,#0               ;    Setup Compare Register with
	   MOV  A,CH                    ;      0.25-0.51 ms from now to start
	   ADD  A,#2                    ;      1st Async pulse.
	   MOV  CCAP3H,A
	   MOV  CCAPM3,#01001001b       ;    Set PCA3 for Compare Mode and 
					;      Enable Interrupt.
EA_OFF:
;    clr p4.1     ;debug
	   RET                          ; Done.


; Read AD Converter and store in mirror locations (ADCMIRR..ADCMIRR+7) since 
; the internal locations which contain the registers are not accesible from
; from BASIC.

READ_ADC:  PUSH ACC
	   PUSH DPL
	   PUSH DPH
	   PUSH PSW

	   MOV  DPTR,#ADC_MIRR          ; Put first mirror address in DPTR
	   MOV  A,ADC_0         ; Read A/D Channel 0
	   MOVX @DPTR,A                 ; Save channel 0 to mirror location
	   MOV  A,ADC_1         ; Read A/D Channel 1
	   INC  DPTR                    ; Increment mirror address
	   MOVX @DPTR,A                 ; Save channel 1 to mirror location
	   MOV  A,ADC_2         ; Read A/D Channel 2
	   INC  DPTR                    ; Increment mirror address
	   MOVX @DPTR,A                 ; Save channel 2 to mirror location
	   MOV  A,ADC_3         ; Read A/D Channel 3
	   INC  DPTR                    ; Increment mirror address
	   MOVX @DPTR,A                 ; Save channel 3 to mirror location
	   MOV  A,ADC_4         ; Read A/D Channel 4
	   INC  DPTR                    ; Increment mirror address
	   MOVX @DPTR,A                 ; Save channel 4 to mirror location
	   MOV  A,ADC_5         ; Read A/D Channel 5
	   INC  DPTR                    ; Increment mirror address
	   MOVX @DPTR,A                 ; Save channel 5 to mirror location
	   MOV  A,ADC_6         ; Read A/D Channel 6
	   INC  DPTR                    ; Increment mirror address
	   MOVX @DPTR,A                 ; Save channel 6 to mirror location
	   MOV  A,ADC_7         ; Read A/D Channel 7
	   INC  DPTR                    ; Increment mirror address
	   MOVX @DPTR,A                 ; Save channel 7 to mirror location

	   POP	PSW
	   POP  DPH
	   POP  DPL
	   POP  ACC
	   RET


;*************************************************************************

; Interrupt Service Routines--

; Interrupt Service Routine for all PCA interrupts.  Determines which
; PCA generated the int. and jumps to the corresponding routine.

ISR_PCA:
	   JBC  CCF0,ISR_PCA0           ; Check & clear flag for PCA0.
	   JBC  CCF1,ISR_PCA1           ;   etc.
	   JBC  CCF3,ISR_PCA3
	   RETI                         ; Others are not used.


; Interrupt Service Routine for End of Injection Pulse -- PCA 1 (Inj 1).
; PCA 2 (Inj 2) is not currently used as an independent timer, but just as a
; single bit output based on the timer used by inj. 1.
ISR_PCA1:  MOV  CCAPM1,#0               ; Disable PCA Module 1. Turn off inj. #1
	   CLR	P1.5			; Turn off Inj. #2
	   RETI                         ; Return from Interrupt.


; Interrupt Service Routine for Starting Async Injection Pulses -- PCA3.
ISR_PCA3:  
 ;setb p4.3 ; debug
	   PUSH PSW                     ; Save registers.
	   PUSH ACC

	   ACALL SETPW                  ; Handle Starting Output Pulse.
	   
	   MOV  A,APP                   ; Set up this PCA for the next Async 
	   ADD  A,CCAP3L                ;   Pulse.
	   MOV  CCAP3L,A                ;    Add Async period to last time
	   MOV  A,APP+1                 ;      for next time.  Also, note
	   ADDC A,CCAP3H                ;      that PCA Compare is disabled
	   MOV  CCAP3H,A                ;      by hardware between write of
					;      low and high CAP bytes.
 ;clr p4.3 ; debug
	   AJMP IP0_RTI                 ; Done, restore registers and return
					;   from interrupt.


; Interrupt Service Routine for Spark Timing (RPM) -- PCA 0.  Also starts
;   Injection Pulse when in Synchronous Mode.

ISR_PCA0:  PUSH PSW                     ; Save registers.
	   PUSH ACC
setb p4.2
	   JNB  SP_SYNC,IP0_RPM         ; If in Async mode, skip output
					;   pulse.

	   ACALL SETPW                  ; Handle Starting Output Pulse.
	   
IP0_RPM:   CLR  C                       ; Compute RPM Pulse Width.
	   MOV  A,CCAP0L                ;    RPMPW = CCAP0 - OLD_CCAP0
	   SUBB A,OLD_CCAP0             ;      (16-bit subtract)
	   MOV  RPMPW,A
	   MOV  A,CCAP0H                ;       Do MSB.
	   SUBB A,OLD_CCAP0+1
	   MOV  RPMPW+1,A
	   MOV  OLD_CCAP0,CCAP0L        ;    Save CCAP0 for next time.
	   MOV  OLD_CCAP0+1,CCAP0H

IP0_RTI:   POP  ACC                     ; Restore registers.
	   POP  PSW
clr p4.2  ; debug
	   RETI                         ; Return from Interrupt.


; Handle Starting an Output Pulse.  Common to ISR_PCA0 & ISR_PCA3.

SETPW:                                  ; Test for zero output pulse width.
 setb p4.4 ; debug
	   MOV  A,PW1                   ;    Get LSB of PW.
	   JNZ  SPW_SETPW               ;    If not zero, setup PW.
	   MOV  A,PW1+1                 ;    Get MSB of PW.
	   JZ   SPW_DONE                ;    If zero, skip PW.
	   MOV  A,PW1                   ;    Get LSB of PW.

SPW_SETPW: 
	   SETB CEX1                    ; Start output pulse. Turn on inj. #1
	   SETB P1.5			; Turn on Inj. #2
	   JNB  SP_SYNC,SPW_ASYN        ; Handle PW for Sync Mode.

SPW_SYNC:  ADD  A,CCAP0L                ;    Setup PCA1 for output pulse
	   MOV  CCAP1L,A                ;      width.  CCAP1 = CCAP0 + PW1
	   MOV  A,PW1+1                 ;      (16-bit add)
	   ADDC A,CCAP0H

SPW_FIN:   MOV  CCAP1H,A                ; Finish both paths.
	   MOV  CCAPM1,#01001101b       ; Set PCA1 for High Speed Output
					;    and enable interrupt. 
 clr p4.4  ;debug
SPW_DONE:  RET                          ; Return from Subroutine.

SPW_ASYN:  ADD  A,CCAP3L                ; Handle PW for Async Mode.
	   MOV  CCAP1L,A                ;    Setup PCA1 for output pulse
	   MOV  A,PW1+1                 ;      width.  CCAP1 = CCAP3 + PW1
	   ADDC A,CCAP3H                ;      (16-bit add)
	   AJMP SPW_FIN                 ;    Go finish.

IAC_HIGHER:		; IAC motor init for higher idle
		CLR	P5.4		; Set step output low
		CLR	P5.5		; Set direction to higher idle
		SETB	P5.6		; Enable IAC (Turn on)
		RET

IAC_LOWER:		; IAC motor init for lower idle
		CLR	P5.4		; Set step output low
		SETB	P5.5		; Set direction to higher idle
		SETB	P5.6		; Enable IAC (Turn on)
		RET

IAC_STEP:		; Step IAC motor in selected direction
		SETB	P5.4		; Set step output high
		NOP			; Delay for 10us 
		NOP			; for step to be initiated (MC3479 - PWCKx)
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		CLR	P5.4		; Set step output low
		RET

IAC_OFF:		; Turn off power to IAC motor (doesn't move)
		CLR	P5.6		; Disable IAC (Turn off)
		CLR	P5.4		; Set step output to low (it should already be low)
		RET

; WDT routines - see Intel appnotes (AB-44)
; Initialize timer 0 for watchdog ISR - see WDT_ISR:
; Note: Each timer 'tick' is osc/12 secs.
WDT_INIT:
	setb p4.5       ;debug
		SETB EA         ; Enable All interrupts
		SETB ET0        ; Enable Timer0 Int
		SETB PT0	; Set Timer0 int to 1st priority (highest) PT0
		MOV IPH,#00000010b	; Set PT0H	

		MOV TMOD, #01   ; Set Timer0 mode to 16-bit, no prescale
		MOV TL0, #67H   ; Set the timer to interrupt (hit FFFF) in 15000 ticks
		MOV TH0, #0C5H  ; FFFF-3A98 = C567 (65535-15000 = 50535)

		SETB TR0        ; Start the timer

	clr p4.5        ;debug
		RET

	
; This ISR has 3 functions:
;       1) To reset the WDT before 16.3667 ms passes (at 12 MHz)
;       2) To check for rapid TPS movement
;       3) To increment a byte for use as a counter for EGO and related routines

; WDT reset - WDT needs to be reset every 16.3667ms or it will reset the CPU
; Timer 0 is used to call this ISR every 15ms to do this reset.

WDT_ISR:
setb p4.6        ;debug

	PUSH    DPH
	PUSH    DPL
	PUSH    ACC
	PUSH	PSW

	CLR TR0                 ; stop timer 0
	MOV WDTRST, #1EH        ; clear WDT
	MOV WDTRST, #0E1H
	MOV TL0, #67H           ; Set the timer to interrupt (hit FFFF) in 15000 ticks
	MOV TH0, #0C5H          ; FFFF-3A98 = C567 (65535-15000 = 50535)
	SETB TR0                ; restart timer 0

; Pulse bit for external WDT/reset IC.  Inverts every time through.
; This should NOT be kept in the ISR, it needs to be in the main BASIC loop
	CPL P1.6		; Invert Reset IC's WDT bit

; Increment BASIC counter bytes
	   MOV  DPTR, #TICK15           ; Get counter address
	   MOVX A, @DPTR                ; Put the contents of TICK15 in A (LSB)
	   INC  A                       ; Increment it
	   MOVX @DPTR, A                ; Put it back in TICK15
	   JNZ  WDT_EXIT                ; If it hasn't rolled over to 00, then exit
	   INC DPTR                     ; Do the MSB
	   MOVX A, @DPTR

	   MOV  A, #00                  ; 
	   MOVX A, @DPTR                ; Put the contents of TICK15+1 in A (MSB)
	   INC  A                       ; Increment it
	   MOVX @DPTR, A                ; Put it back in TICK15+1

WDT_EXIT:       
		POP	PSW
		POP     ACC
		POP     DPL
		POP     DPH

clr p4.6       ;debug
		RETI

	

	   END

--=====================_98831695==_
Content-Type: text/plain; charset="us-ascii"


--=====================_98831695==_--




More information about the Diy_efi mailing list