BasicMicro - Forums

www.basicmicro.com
It is currently Sat Feb 04, 2012 7:03 pm

All times are UTC - 8 hours [ DST ]




Post new topic Reply to topic  [ 5 posts ] 
Author Message
 Post subject: HSERVOTIME, Interrupt handlers and ASM...
PostPosted: Sun Aug 15, 2010 8:21 am 
Offline
Master

Joined: Tue Nov 21, 2006 9:34 am
Posts: 500
Hi Nathan,

I am playing around with a modified Hitec RC receiver, that I have modified to get the clock signal from the receiver which with one IO line you can deduce all of the signals. I thought I would generate a quick and dirty RC input file for the phoenix code using this. I thought I would try it on the Arc32 as currently that is the only BAP I have running on a hex...

I thought I would try doing this in the background using interrupts. I am starting off with a version of the IRQ2 handler in basic. Once I think things are working well, will convert to asm...

On a Bap28 in a test program I used TimerA to time the pulses. My IRQ2 handler emulates my get clock time as I have not enabled interrupts. IE, it grabs the overrun count, TMA and checks to see if there is a pending timer interupt... Could do similar on Arc32 by using TimerB1, but...

You already have a timer running that you can get the time from using the command HSERVOTIME. But I assume I have the same problem with pending timer interrupt probably TimerZ? Suggestions? Also is the timer value associated with HSERVOTIME available in ASM?

Thanks
Kurt

P.S. - Beginning hacked up interrupt handler

Code:
Handle_IRQ2:
   toggle p44            ; status LED on arc32...
   
   ; Use hservo
   ;gosub GetCurrentTime - don't want to enable interrupts yet so do inline
#ifdef USER_TIMERA    ; BUGBUG: Convert to B1 if we go this way...
   _lNewPulseTime = lTimerCnt + TCA
   ; see if timer is waiting to process interrupt.
   if IRR1.bit6 then
      _lNewPulseTime = lTimerCnt + 256 + TCA
   endif
#else
   _lNewPulseTime = HServoTime 0;   
#endif      
   ; calculate the pulse width and convert to us and save away the pulse time
   _wPulseWidth = _lNewPulseTime - _lLastPulseTime      ; not scaled yet
   _wPulseWidth = _wPulseWidth / 20;   20mhz clock, convert to 1mhz
   _lLastPulseTIme = _lNewPulseTime;

   ; See if the value appears to be OK.
   if _wPulseWidth > 2500 then
      ; Where were we???
      if _bNextChannel < CNT_PPM_SIGNALS then
         ; We got a long value when we did not expect it...???
         fPPMsValid = 0;
      endif
      _bNextChannel = 0;    // Ok lets assume the next value will be for our first channel
   else
      if _bNextChannel < CNT_PPM_SIGNALS then
         awPPMs(_bNextChannel) = _wPulseWidth
         _bNextChannel = _bNextChannel + 1
         if  _bNextChannel = CNT_PPM_SIGNALS then
            fPPMsValid = 1      ; Let the main line know that we received a complete valid set of values
         endif
      endif
   endif
      
   resume


Top
 Profile  
 
 Post subject: Re: HSERVOTIME, Interrupt handlers and ASM...
PostPosted: Sun Aug 15, 2010 9:49 am 
Offline
Site Admin
User avatar

Joined: Thu Mar 01, 2001 11:00 am
Posts: 784
Location: Temecula, CA
Quote:
But I assume I have the same problem with pending timer interrupt probably TimerZ?


I'm not sure what you meany by this. Hservotime gets the current overflowed time and adds the current TimerZ time to it. The code is:

Code:
      .ifdef _DEFHSERVOTIME
_HSERVOTIMECMD:
   .ifdef _DEFENABLEHSERVO2
         mov.b         r0l,r2l                     ;2 save shift count
         ;calc HSERVOTIME
         mov.w         @_HSERVOTIMER:16,e1         ;6 get HSERVOTIME
         mov.w         @TCNT_0:16,r1               ;6 get TimerZ time
         mov.w         @_HSERVOTIMER:16,e0         ;6 get HSERVOTIME again
         cmp.w         e1,e0                        ;2 if HSERVOTIMEs match no int happened
         beq         _hservotime_noint:8         ;4
         mov.w         @TCNT_0:16,r1               ;6 else get TimerZ time again
         mov.w         e0,e1                        ;2 and keep second HSERVOTIME
_hservotime_noint:
         mov.l         er1,er0                     ;2
         mov.l         @_HSERVOTIMERH:16,er1      ;10 get HSERVOTIMEH
            
         and.b         #0x3f,r2l                  ;2 limit to 1:2^63 and calc flags
         beq         _hservotime_finish:8         ;4 if 0 we are done else shift right specified times
_hservotime_shift:
         shlr.l      er1                        ;2
         rotxr.l      er0                        ;2
         dec.b         r2l                        ;2
         bne         _hservotime_shift:8         ;4(10*prescaler)
_hservotime_finish:
   .else
         xor.l         er0,er0
   .endif
         rts                                    ;8(52/60 + (10*prescaler))
      .endif


You can duplicate parts of this code or you can call it in asm directly. R0L must hold the shift count if you are calling directly in asm. _HSERVOTIMER is a word variable. Combined with the current TimerZ TCNT time you get the low 32bits of the current time. _HSERVOTIMERH is the high 32bits of the current time since the last reset.

_________________
Nathan Scherdin
Basic Micro - Robotic Technology Evolved


Top
 Profile  
 
 Post subject: Re: HSERVOTIME, Interrupt handlers and ASM...
PostPosted: Sun Aug 15, 2010 12:32 pm 
Offline
Master

Joined: Tue Nov 21, 2006 9:34 am
Posts: 500
Thanks Nathan,

What I was trying to say is calling it within an Interrupt handler I believe will have interrupts disabled (unless you explicitly re enable). So if TimerZ overflowed during the processing you will get the lower TCNT (it wrapped) but _HSERVOTIMER will not have been updated yet...

Kurt


Top
 Profile  
 
 Post subject: Re: HSERVOTIME, Interrupt handlers and ASM...
PostPosted: Sun Aug 15, 2010 5:40 pm 
Offline
Master

Joined: Tue Nov 21, 2006 9:34 am
Posts: 500
Just to be clear, within the interrupt handler I think I need to have the code that looks something like:
Code:
asm {
;   _lNewPulseTime = HServoTime 0;   
    ;calc HSERVOTIME
   mov.w   @_HSERVOTIMER:16,e1         ;6 get HSERVOTIME
   mov.w   @TCNT_0:16,r1               ;6 get TimerZ time
   bld.b   #4,@TSR_0:16               ; Get the overflow status from TSR
   bcc      _GHST_NOOVERFLOW:8         ; Not overflow
   inc.w   #1, e1                  ; do the add ourself
   mov.w   @TCNT_0:16,r1               ; Neda to reload the timer value to make sure
_GHST_NOOVERFLOW:   
   mov.l   er1, @_LNEWPULSETIME      ; save away the time
}   

Alternative - add a line at the start of my handler that looks something like:
Code:
Handle_IRQ2:
   enable  ; let other interrupts preempt me...
...

Thanks again
Kurt


Top
 Profile  
 
 Post subject: Re: HSERVOTIME, Interrupt handlers and ASM...
PostPosted: Sun Aug 15, 2010 7:21 pm 
Offline
Site Admin
User avatar

Joined: Thu Mar 01, 2001 11:00 am
Posts: 784
Location: Temecula, CA
That may work. But if you are enabling interrupts inside your handler, then I don't think you will ever see the overflow flag being set. When there is an overflow my handler will trigger, clear the overflow flag and increment the _HSERVOTIMER variable and you will never know it happened.

So what I think you should probably do is:

1. Read _HSERVOTIMER
2. Read TCNT
3. Read _HSERVOTIMER again
4. if the first and second reading differs an interrupt happened so re-read TCNT again.

_________________
Nathan Scherdin
Basic Micro - Robotic Technology Evolved


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 5 posts ] 

All times are UTC - 8 hours [ DST ]


Who is online

Users browsing this forum: No registered users and 3 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Jump to:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group

phpBB SEO