After the last posts I have made some progress on this. I have been playing with a Bap28 only version of this, that uses the input capture for one of the channels on TimerW. I decided to try this way as I have not tried the input capture and thought it would be fun and it should be reasonably accurate. I started off with a Basic interrupt handler but was having trouble getting reasonable results, so I converted to assembly language. I think I now have the interrupt handler working OK. So I am now trying a setup a simple set of functions for controlling the phoenix. Having it interrupt based, I had to generalize the disable interrupts function I had for the XBEE interrupts such that the serouts to the SSC-32 would work.
I am now playing with how/when to get the inputs. When I disable the inputs I invalidate the data and only after a complete new pass to I say the data is valid. Currently I disable the input through the calls to the ServoDriver and more or less call off to ControlInput before it had a chance to do a complete new pass. I have a couple of options. I could simply wait a certain amount of time for the data to become valid or I could detect if I had new valid data just before the servo driver commit and use it. I will probably go the later route. The data should be very current anyway and it would mean that the input processing should not slow down the code much at all. Can minimize this to only have the code running while in the sleep waiting for the current step to complete. Just in case anyone wishes to see the interrupt handler ![:laughing: :laughing:](//community.robotshop.com/forum/images/emoji/twitter/laughing.png?v=9)
[code];------------------------------------------------------------------------------
; HANDLE_TIMERW_IMIED handler - The idea is to capture our current time
; value when the interrupt happens and then calculate a delta from the
; previous one. If > some max we know that we are starting up a new run
; of timings, else save away in the appropriate index value in our array
; of timing with 1 per logical channel.
;------------------------------------------------------------------------------
BEGINASMSUB
HANDLE_TIMERW_ASM:
ASM {
; First see why we woke up.
push.l er0
push.l er1 ; save away the registers we are using
#ifdef DEBUG_LA
; bset #4, @PCR5:8 ; make sure it is set for output
; bnot #4, @PDR5:8 ; DEBUG - togle P4…
#endif
bld #3, @TSRW:8 ; See if GRD match…
bcc _RCHTW_CLEANUP:8 ; not ours
bclr #3, @TSRW:8 ; clear it out.
mov.w @GRD:16, e1 ; Get the new GRD value
mov.w @_WGRDPREV:16, r1 ; get the saved value to use
mov.w e1, @_WGRDPREV:16 ; Save away the new one
sub.w r1, e1 ; subtract the prev from the new to get delta - I think it handles wrap OK…
bcc _RCHTW_NGRD:8 ; NO Carry so assume no wrap.
bld #7, @TSRW ; see if it shows a wrap happened
bcc _RCHTW_NGRD:8 ; Did not have overflow so fine
mov.w #0xffff, e1 ; set high value …
_RCHTW_NGRD:
shlr.w e1 ; divide by 2 to get uS
xor.w r0,r0 ; zero out r0
mov.b @_BNEXTCHANNEL:16, r0l ; Load which channel we are using into r0l
cmp.b #CNT_PPM_SIGNALS+1, r0l ; See if this is the first interrupt …
beq _RCHTW_INITMODE:8 ; we are in the init phase…
cmp.w #499,e1 ; see if the value is lower than expected
bls _RCHTW_LESS500:8 ; < 500 assume an error again
cmp.w #2500, e1 ; see if > 2500
bls _RCHTW_LT2500:8 ;
; So exceeds what we think should be a valid signal
cmp.b #CNT_PPM_SIGNALS-1, r0l ;
bhi _RCHTW_SARTNEWRUN:8 ;
_RCHTW_LESS500:
mov.b r0h, @FPPMSVALID:16 ; say we are not valid r0h should be zero
; bra _RCHTW_CLEANUP:8 ; go to cleanup
#ifdef DEBUG_LA
; bnot #7, @PDR5:8 ; P7…
#endif
_RCHTW_INITMODE:
mov.b #CNT_PPM_SIGNALS, r0h ; Hack - reuse code below to set channel value…
_RCHTW_SARTNEWRUN:
#ifdef DEBUG_LA
bnot #5, @PDR5:8 ; DEBUG - togle P5…
#endif
mov.b r0h, @_BNEXTCHANNEL:16 ; next one should be channel 0
bra _RCHTW_CLEANUP:8 ; go to cleanup
_RCHTW_LT2500:
cmp.b #CNT_PPM_SIGNALS-1, r0l ; see if we are working on a proper channel
bhi _RCHTW_CLEANUP:8 ;
mov.b r0l, r1l ; save the value
extu r0 ;
shll.w r0 ; *2
mov.w e1,@(AWPPMSINPUT, er0) ; save away the new pulse width into the array
inc.b r1l ; increment our counter
mov.b r1l,@_BNEXTCHANNEL:16 ; save away the updated count
cmp.b #CNT_PPM_SIGNALS, r1l ; see if we got a complete set
bne _RCHTW_CLEANUP:8
mov.b #1, r0l
mov.b r0l, @FPPMSVALID:16 ; let caller know we have a complete set
#ifdef DEBUG_LA
; bnot #6, @PDR5:8 ; DEBUG - togle P6…
#endif
_RCHTW_CLEANUP:
pop.l er1 ; restore the registers we used
pop.l er0
rte ; return from the exception.
}
ENDASMSUB
[/code]
Kurt