HC908GP32 Timer question

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

HC908GP32 Timer question

741 Views
roberthiebert
Contributor IV

Hi all,

I'm using an HC908GP32 as an engine controller and have been stumped by what I thought should be an easy thing. I want to generate a single pulse width for fuel injector control using Tim1 CH0 for injector 1, and CH1 for injector 2. Below is the code I'm using to initialize Port D, the Tim1 timer, the calling code for inj1 and the CH0 interrupt service routine. For some reason I'm not getting an interrupt for either channel. Any help would be greatly appreciated. Here' my code:

; MC68HC908GP32 40 Pin
; PORT D INIT
;***********************************************************************************************
; Port D
    mov     #$30,PORTD      ; Move %00110000 to Port D Data Direction Register (preinit output
                                           ; pins 5,4 Hi)(Turn off injectors (inverted output)
    mov     #$FF,DDRD       ; Move %11111111 to Port D Data Direction Register 
                                          ; (PTD7,6 not available, outputs on PTD5,4,3,2,1,0
                                          ; = N/A,N/A,Inj1,Inj2,N/C,N/C,N/C,N/C
;***********************************************************************************************
 
; TIM1 INIT
;***********************************************************************************************
; Set up TIM1 as a free running ~1us counter. Set channels 0 and 1 for output
; compare, pulsewidth control of injectors. INJ1 on T1SC0 and INJ2 on T1SC1
;***********************************************************************************************
 
    mov     #%00110011,T1SC  ; Move %00110011 into Timer1 Status and Control Register
                             ; Bit7 TOF, (no effect)
                             ; Bit6 TOIE, (Overflow interrupts disabled)
                             ; Bit5 TSTOP, (counter stopped)
                             ; Bit4 TRST, (Prescale and counter cleared)
; Bit3 Unimplemented
                             ; Bits 2,3,0 (Prescale for bus frequency /
    mov     #$FF,T1MODH      ; Move decimal 255 into T1 modulo reg Hi (Free running timer)
    mov     #$FF,T1MODL      ; Move decimal 255 into T1 modulo reg Lo
 
    mov    #%01000000,T1SC0 ; Channel 1 Output compare, interrupt enabled
                         ; Bit7 CHxF, CH0 output compare
                         ; Bit6 CHxIE, CH0 interrupts enabled
                         ; Bit5 MSxB, CH0 Buffered OC/PWM disabled
                         ; Bit4 MSxA, CH0 Initial output level Hi (Inj1 off)
                         ; Bit3 ELSxB, CH0 Pin under port control
                         ; Bit2 ELSxA, CH0 Pin under port control
                         ; Bit1 TOVx, CH0 No toggle on overflow
                         ; Bit0 CHxMAX, CH0 No max duty cycle
                        
    mov    #$00,T1CH0H       ; Move decimal 0 to T1CH0 register Hi
    mov    #$00,T1CH0L       ; Move decimal 0 to T1CH0 register Lo
    bclr   CHxF,T1SC0          ; Clear CH0 output compare flag
    bclr   CHxIE,T1SC0        ; Disable CH0 interrupt until we are ready
 
    mov    #%01000000,T1SC1 ; Channel 1 Output compare, interrupt enabled
                         ; Bit7 CHxF, CH1 output compare
                         ; Bit6 CHxIE, CH1 interrupts enabled
                         ; Bit5 MSxB, CH1 Buffered OC/PWM disabled
                         ; Bit4 MSxA, CH1 Initial output level Hi (Inj2 off)
                         ; Bit3 ELSxB, Pin under port control
                         ; Bit2 ELSxA, Pin under port control
                         ; Bit1 TOVx, CH1 No toggle on overflow
                         ; Bit0 CHxMAX, CH0 No max duty cycle
 
    mov    #$00,T1CH1H       ; Move decimal 0 to T1CH0 register Hi
    mov    #$00,T1CH1L       ; Move decimal 0 to T1CH0 register Lo
    bclr   CHxF,T1SC1          ; Clear CH1 output compare flag
    bclr   CHxIE,T1SC1         ; Disable CH1 interrupt until we are ready
    mov    #%01010011,T1SC ; Start timer, no overflow int, div / 8
                             ; Bit7 TOF, (no effect)
                             ; Bit6 TOIE, (overflow interrupts enabled)
                             ; Bit5 TSTOP, (counter active)
                             ; Bit4 TRST, (Prescale and counter cleared)
                             ; Bit3 Unimplemented
                             ; Bits 2,3,0 (Prescale for bus frequency /
 
;****************************************************************************
 
 
; CALL FOR INJECTOR PULSE 1 IN PROGRAM
;****************************************************************************
 
    lda     T1CNTL               ; Unlatch any previous reads
    lda     pwcalc1L             ; uS pulse width Lo byte
    add     T1CNTL             ; A<-(A)+(M) Current counter value Lo byte
    tax                                 ; (A)->(X) Result to X
    lda     pwcalc1H            ; uS pulse width Hi byte
    adc     T1CNTH             ; A<-(A)+(M)+(C) Current counter value Hi byte
    sta     T1CH0H               ; Write high byte timer output compare first
    stx     T1CH0L                ; Then low byte
    bclr    inject1,portd         ; Turn on Injector #1 (inverted drive)
    bclr    CHxF,T1SC0        ; Clear CH0 output compare flag
    bset    CHxIE,T1SC0      ; Enable CH0 interrupt
 
;****************************************************************************
 
 
; TIM1 CHANNEL 0 INTERRUPT SERVICE ROUTINE
;***************************************************************************
; - TIM1_CH0_ISR (Inj1 control)
;**************************************************************************
 
TIM1_CH0_ISR:
    pshh
    lda     T1SC0                ; Read interrupt
    bclr    CHxF,T1SC0      ; Reset interrupt flag
    bclr    CHxIE,T1SC0     ; Disable interrupt
    bset    inject1,portd       ; Turn Off Injector #1 (inverted drive)
    pulh
    rti
 
;***************************************************************************
0 Kudos
5 Replies

610 Views
roberthiebert
Contributor IV

Update:

 I've made some progress. I kept trying different combinations for the TIM1 set up and finally got the correct one. I don't know why it works, but it works. Here it is:

;***********************************************************************************************
; Set up TIM1 as a free running ~1us counter. Set channels 0 and 1 for output
; compare, pulsewidth control of injectors. INJ1 on T1SC0 and INJ2 on T1SC1
;***********************************************************************************************
 
     mov     #%00110011,t1sc  ; Move %00110011 into Timer1 Status and Control Register
                             ; Bit7 TOF, (no effect)
                             ; Bit6 TOIE, (Overflow interrupts disabled)
                             ; Bit5 TSTOP, (counter stopped)
                             ; Bit4 TRST, (Prescale and counter cleared)
                             ; Bit3 Unimplemented
                             ; Bits 2,1,0 (Prescale for bus frequency /
     mov     #$FF,t1modh      ; Move decimal 255 into T1 modulo reg Hi (Free running timer)
     mov     #$FF,t1modl      ; Move decimal 255 into T1 modulo reg Lo
 
     mov    #%00010000,t1sc0 ; Channel 1 Output compare, interrupt enabled
                         ; Bit7 CHxF, CH0 output compare
                         ; Bit6 CHxIE, CH0 interrupts disabled until we are ready
                         ; Bit5 MSxB, CH0 Buffered OC/PWM disabled
                         ; Bit4 MSxA, CH0 Unbuffered output compare/PWM operation
                         ; Bit3 ELSxB, CH0 Pin under port control initial output Low
                         ; Bit2 ELSxA, CH0 Pin under port control initial output Low
                         ; Bit1 TOVx, CH0 No toggle on overflow
                         ; Bit0 CHxMAX, CH0 No max duty cycle
                        
     mov    #%00010000,t1sc1 ; Channel 1 Output compare, interrupt disabled
                         ; Bit7 CHxF, CH0 output compare
                         ; Bit6 CHxIE, CH0 interrupts disabled until we are ready
                         ; Bit5 MSxB, CH0 Buffered OC/PWM disabled
                         ; Bit4 MSxA, CH0 Unbuffered output compare/PWM operation
                         ; Bit3 ELSxB, CH0 Pin under port control initial output Low
                         ; Bit2 ELSxA, CH0 Pin under port control initial output Low
                         ; Bit1 TOVx, CH0 No toggle on overflow
                         ; Bit0 CHxMAX, CH0 No max duty cycle
 
  mov    #%00010011,t1sc ; Start timer, no overflow int, div / 8
                             ; Bit7 TOF, (no effect)
                             ; Bit6 TOIE, (overflow interrupts disabled)
                             ; Bit5 TSTOP, (counter active)
                             ; Bit4 TRST, (Prescale and counter cleared)
                             ; Bit3 Unimplemented
                             ; Bits 2,1,0 (Prescale for bus frequency /
 
;***********************************************************************************************
 
But, I still have another problem. I have TIM2 set up as a free running counter with CH0 generating an interrupt every 100 uS. I use this to generate other time periods for my program. This works fine. I have TIM2 CH1set up for spark control,  similar to the TIM1 channels. The ISR routine is a bit more complicated because I have to enter it twice. First after a delay time to energize the coil and second to de energize it after the correct dwell time. I can't even get to the first interrupt. Again, I suspect my TIM2 timer set up. I've tried almost every combination I can think of but I only end up breaking the CH0 function. Here is how I have TIM2 set up:
;***********************************************************************************************
; - Set up TIM2 as a free running ~1us counter. Set Channel 0 output compare
;   to generate the ~100us(.1ms) clock tick. Interrupt vector "TIM2CH0_ISR:"
;   Set Channel 1 output compare for spark control. Interrupt vector "TIM2CH1_ISR:"
;***********************************************************************************************
 
     MOV    #%00110011,t2sc ; Stop Timer so it can be set up
                                              ; Bit7 TOF, Tim counter has not reached modulo value
                                              ; Bit6 TOIE, TIM overflow interrupts disabled
                                              ; Bit5 TSTOP, TIM counter stopped
                                              ; Bit4 TRST, Prescaler and counter cleared
                                              ; Bit3 Unimplemented
                                              ; Bit2 PS2, Internal bus clock / 8
                                              ; Bit1 PS1, Internal bus clock / 8
                                              ; Bit0 PS0, Internal bus clock / 8
 
     mov    #$FF,t2modh ; Free running timer
     mov    #$FF,t2modl
     mov    #0T,t2ch0h ; Channel 0 high, 0
     mov    #100T,t2ch0l ; Channel 0 low, 100 = 0.1 ms @ 8.0MHz - DJLH
     mov    #%11010100,t2sc0 ; Output compare, interrupt enabled
                         ; Bit7 CHxF, CH0 output compare
                         ; Bit6 CHxIE, CH0 interrupts enabled
                        ; Bit5 MSxB, CH0 Buffered OC/PWM disabled
                        ; Bit4 MSxA, CH0 Unbuffered OC operation
                        ; Bit3 ELSxB, CH0 Toggle output on compare
                        ; Bit2 ELSxA, CH0 Toggle output on compare
                        ; Bit1 TOVx, CH0 No toggle on overflow
                        ; Bit0 CHxMAX, CH0 No max duty cycle
     mov    #$00,t2ch1h ; Channel 1 high, to be used for spark control
     mov    #$00,t2ch1l ; Channel 1 low, 0
     mov    #%00010000,t2sc1 ; Channel 1 Output compare, interrupt enabled
                         ; Bit7 CHxF, CH1 output compare
                         ; Bit6 CHxIE, CH1 interrupts disabled until we are ready
                         ; Bit5 MSxB, CH1 Buffered OC/PWM disabled
                         ; Bit4 MSxA, CH1 Unbuffered OC operation
                         ; Bit3 ELSxB, Pin under port control, initial output level low
                         ; Bit2 ELSxA, Pin under port control, initial output level low
                         ; Bit1 TOVx, CH1 No toggle on overflow
                         ; Bit0 CHxMAX, CH1 No max duty cycle
 
  mov    #%00010011,t2sc ; Start timer          
                                           ; Bit7 TOF, Tim counter has not reached modulo value
                                           ; Bit6 TOIE, TIM overflow interrupts disabled
                                           ; Bit5 TSTOP, TIM counter active
                                           ; Bit4 TRST, Prescaler and counter cleared
                                           ; Bit3 Unimplemented
                                           ; Bit2 PS2, Internal bus clock / 8
                                           ; Bit1 PS1, Internal bus clock / 8
                                           ; Bit0 PS0, Internal bus clock / 8
 
 
;***********************************************************************************************
 
Any suggestions would be greatly appreciated.
Regards,
Robert
0 Kudos

587 Views
roberthiebert
Contributor IV

Another update. After a lot of blood sweat and tears I think I have things figured out. Here is my TIM2 set up:

mov    #%00110011,t2sc

mov    #%FF,t2modh

mov    #%FF,t2modl

mov    #0T,t2ch0h

mov    #100T,t2ch0l

mov    #%11010100,t2sc0

mov    #$00,t2ch1h

mov    #$00,t2ch1l

mov    #%00010000,t2sc1

mov    #%00010011,t2sc

And for TIM1:

mov    #%00110011,t1sc

mov    #%FF,t1modh

mov    #%FF,t1modl

mov    #%00010000,t1sc0

mov    #%00010000,t1sc1

mov    #%00010011,t1sc

I'm still hunting bugs in the ISRs, but they appear to be functioning as they should.

 

 

0 Kudos

701 Views
Itzzamna_Supp
NXP TechSupport
NXP TechSupport

After validating the code, I see some instructions that I would like to understand.

I see that you enabe the interruption by using the command mov #%01000000,T1SC0, after more setup commands you disable the same interruption by using bclr CHxIE,T1SC0, which means that the interruption will only be active during that setup procedure, right?

Also, I see that you are not using the CLI for general interruptions. Can you please try using it?

0 Kudos

697 Views
roberthiebert
Contributor IV

Hi Itzzamna,

So sorry about my late reply, I didn't get any e-mail notification.

In the set up procedure, after I have set things up, I disable the interrupt until I am ready to use it. I enable it again in the code at the time that I have the output compare values set and want to enable the interrupt. I think that's the correct way to do it.

I'm in the process of setting up a development board to test my code and should have it ready in a day or so. When it's up and running I will try your  suggestion and get back to you as soon as I can. Thanks for taking the time to reply.

Robert

0 Kudos

664 Views
roberthiebert
Contributor IV

Well, I'm not doing too good with this. I set up another board just to experiment with coding just so I know that there would be nothing in my main code that would be there to cause issues. I think there is something wrong with the way I am setting up Tim1. Probably because I am not completely clear on how to do this for what I want it to do.

This is what I want it to do:

I have Port D4 set up as an output for Inj1. Port D5 is set up as an output for Inj2. Both are hardware inverted.

I have Tim1 set up as a free running counter. I have both Ch0 and Ch1 set up as output compare and the pins are under port control.  I want Ch0 to control Inj1 and Ch1 to control Inj2. In my program when I get an input signal that it is time to energize Inj1 for a particular pulse width, I will get a time stamp of the Tim1 counter, add the pulse width to it, save these values to the T1CH0H;T1CH0L registers, Clear the Inj1 pin on Port D to start the injection and and enable the interrupt. In the Tim1 Ch0 ISR I will disable the interrupt and set the Inj1 pin of Port D to terminate the injection. I'll use the same procedure for Inj2.

Here is how I have things set up:

;****************************************************************************
; - Set Port D for injector control (injectors hardware inverted), Input 
;   status LED, and spark control
;****************************************************************************
 
; Port D
 
     mov     #$30,PORTD      ; %00110000 to port D Data register
                                   ; (Inj2,Inj1 high, all others low
     lda     #$FF            ; Load accumulator with %11111111
                                   ; (port direction setup 1 = output)
     sta     DDRD           ; Copy to Port D Data Direction Register
                                   ; (Set all as outputs)
                                   ; NA,NA,Inj2,Inj1,Input Stat,SpkB,SpkA,NA)
 
;***********************************************************************************************
; Set up TIM1 as a free running ~1us counter. Set channels 0 and 1 for output
; compare, pulsewidth control of injectors. INJ1 on T1SC0 and INJ2 on T1SC1
;***********************************************************************************************
 
     mov     #%00110011,t1sc  ; Move %00110011 into Timer1 Status and Control Register
                             ; Bit7 TOF, (no effect)
                            ; Bit6 TOIE, (Overflow interrupts disabled)
                            ; Bit5 TSTOP, (counter stopped)
                            ; Bit4 TRST, (Prescale and counter cleared)
                            ; Bit3 Unimplemented
                            ; Bits 2,1,0 (Prescale for bus frequency /
     mov     #$FF,t1modh      ; Move decimal 255 into T1 modulo reg Hi (Free running timer)
     mov     #$FF,t1modl      ; Move decimal 255 into T1 modulo reg Lo
 
     mov    #%11010000,t1sc0 ; Channel 1 Output compare, interrupt enabled
                         ; Bit7 CHxF, CH0 output compare
                         ; Bit6 CHxIE, CH0 interrupts enabled
                         ; Bit5 MSxB, CH0 Buffered OC/PWM disabled
                         ; Bit4 MSxA, CH0 Unbuffered output compare/PWM operation
                         ; Bit3 ELSxB, CH0 Pin under port control initial output high
                         ; Bit2 ELSxA, CH0 Pin under port control initial output high
                         ; Bit1 TOVx, CH0 No toggle on overflow
                         ; Bit0 CHxMAX, CH0 No max duty cycle
                        
     mov    #%11010000,t1sc1 ; Channel 1 Output compare, interrupt enabled
                         ; Bit7 CHxF, CH0 output compare
                         ; Bit6 CHxIE, CH0 interrupts enabled
                         ; Bit5 MSxB, CH0 Buffered OC/PWM disabled
                         ; Bit4 MSxA, CH0 Unbuffered output compare/PWM operation
                         ; Bit3 ELSxB, CH0 Pin under port control initial output high
                         ; Bit2 ELSxA, CH0 Pin under port control initial output high
                         ; Bit1 TOVx, CH0 No toggle on overflow
                         ; Bit0 CHxMAX, CH0 No max duty cycle
 
  mov    #%01010011,t1sc ; Start timer, no overflow int, div / 8
                             ; Bit7 TOF, (no effect)
                             ; Bit6 TOIE, (overflow interrupts enabled)
                             ; Bit5 TSTOP, (counter active)
                             ; Bit4 TRST, (Prescale and counter cleared)
                             ; Bit3 Unimplemented
                             ; Bits 2,1,0 (Prescale for bus frequency /
 
;***********************************************************************************************
 
Is there anything wrong with the way I have Port B and the timer set up?
Any suggestions would be greatly appreciated
Robert
0 Kudos