There are several different things I have found it found it very useful to have a logic analyzer to test the different IO levels. One of the best purchases I have made in awhile was the logic analyzer by www.saleae.com for $150. As I was getting set up to be able to test the DIY receiver again I decided to see how hard it would be to write a rudimentary one that ran on the BAP that I was going to test the DIY receiver to see if I was generating the proper timings on the transmitter side. Note: I have not changed the transmiter side code yet…
So I hacked a bit this afternoon. It is not pretty yet, but I do think it is sort-of starting to work…
The current code waits until you hit ButtonA on the BB2 and then calls a function that is mostly assembly code that captures the state of IO pins 0-7 and records when the change happened. It times out pretty quickly (probably pretty quickly < 15 seconds or when the capture buffer of the number of events is full. I currently can capture 256 changes.
I then have a function that simply dumps the changes and it tries to figure out what changed, like IO pin 0 went to a 1 (high) and it remembers the time that happened and also prints out delta times per each pin. It is not pretty, would be nicer to have it talk to a VB app that does graphics or the like, but…
Here is part of an output with the 7 IO lines of the DIY receiver plugged into IO pins 0-6
Count of items256
T:7926(1EF6) IO:08 Bit: 3->1 DT:7926
T:9426(24D2) IO:00 Bit: 3->0 DT:1500
T:9488(2510) IO:04 Bit: 2->1 DT:9488
T:10988(2AEC) IO:00 Bit: 2->0 DT:1500
T:11049(2B29) IO:02 Bit: 1->1 DT:11049
T:12549(3105) IO:00 Bit: 1->0 DT:1500
T:12609(3141) IO:20 Bit: 5->1 DT:12609
T:14338(3802) IO:00 Bit: 5->0 DT:1729
T:14400(3840) IO:01 Bit: 0->1 DT:14400
T:15399(3C27) IO:00 Bit: 0->0 DT:999
T:15461(3C65) IO:10 Bit: 4->1 DT:15461
T:17318(43A6) IO:00 Bit: 4->0 DT:1857
T:17377(43E1) IO:C0 Bit: 6->1 DT:17377 Bit: 7->1 DT:17377
T:18478(482E) IO:00 Bit: 6->0 DT:1101 Bit: 7->0 DT:1101
T:29924(74E4) IO:08 Bit: 3->1 DT:20498
T:31424(7AC0) IO:00 Bit: 3->0 DT:1500
T:31485(7AFD) IO:04 Bit: 2->1 DT:20497
T:32983(80D7) IO:00 Bit: 2->0 DT:1498
T:33045(8115) IO:02 Bit: 1->1 DT:20496
T:34545(86F1) IO:00 Bit: 1->0 DT:1500
T:34606(872E) IO:20 Bit: 5->1 DT:20268
T:36334(8DEE) IO:00 Bit: 5->0 DT:1728
T:36395(8E2B) IO:01 Bit: 0->1 DT:20996
T:37396(9214) IO:00 Bit: 0->0 DT:1001
T:37456(9250) IO:10 Bit: 4->1 DT:20138
T:39313(9991) IO:00 Bit: 4->0 DT:1857
You will notice the transition to 0 (going low) that there many values around 1500 which is what you would expect from the RC receiver without my hands on the joysticks…
Again if anyone would like to play with this, here is the code:
[code];==============================================================================
; This is the beginnings of a simple logic analyzer, that over time
; may increase in functionality. The first version will simply
; wait until the user press the button on the BB2 and then will enter an
; assembly level function which will, loop reading the IO state of IO pins 0-7
; repeatily and capture whenever the state changes. It will also captuer the WTIMER
; time when the change happened. It will stay looping until either our WTIMER value
; exceeds some threshold or until we max out our capture size.
;
;==============================================================================
BUFFSIZE con 256
; The buffer will contain up to BUFFSIZE transisition, where each transition
; will be 32 bits
; 8 - IO state of IO pins 0-7
; 24 - WTimer value extended to 24 bits. we will setup wtimer to take the clock
; divided by 8 so I think this will give us about 8 seconds.
CaptureBuffer var long(256) ; we will save away up to 256 transistions.
cItems var word ; number of items returned
;button variables…
buttonA var bit
prevA var bit
;==============================================================================
; Complete initialization
;==============================================================================
sound 9,[50\3800, 50\4200, 40\4100]
input p12
output p14
high p14 ; will use the LED to show when we the scan completes.
;==============================================================================
; Main Loop
;==============================================================================
main:
prevA = buttonA
buttonA = in12
if (buttonA = 0) AND (prevA = 1) then
sound 9,[50\3800]
gosub DoCapture
; OK now, lets setup to do a capture.
; Lets transition to assembly language here.
gosub DumpCapture
endif
goto main
;==============================================================================
; Main Capture function. - Mostly assembly language…
;
; Will capture state of BAP io pins 0-7 which on H8 is pins P50-P57
;==============================================================================
DoCapture:
low p14 ; Show LED to let know capture is active
TCRW = 0x30 ;clears TCNT and sets the timer to inc clock cycle / 8
TMRW = 0x80 ;starts the timer counting
TCNT = 0
; Transition to assembly
xor.w r0,r0 ; zero out value, to set all IO pins to read
mov.b r0l, @(PDR5-0xd0+0x70) ; update the shadow location
mov.b r0l, @PCR5 ; update the actual direction word which is write only
; Now lets init the WTIMER to divide by 8
; mov.b r0l, @TMRW:8 ; I think it is stopped now.
; mov.w r0, @TCNT:16 ; make sure our counter starts at zero
; mov.b #0x30, r0l
; mov.b r0l, @TCRW:8 ; Clock divided by 8
; bclr.b #7, @TSRW:8 ; make sure the overflow is has cleared.
; Now lets setup everything for our loop
mov.l #CAPTUREBUFFER, er5 ; Setup pointer to our buffer
mov.w #BUFFSIZE, r4 ; Count of items left to get
xor.w e3, e3 ; use e3 for our timer overflow count. R3 to hold value for WTIMER
; Now lets start the ball rolling
; bset.b #7,@TMRW:8 ; start clock
_DCL_MAIN:
mov.b @PDR5:8, r0l ; Capture the current state of the 8 IO pins
mov.w @TCNT, r3 ; get current timer value - make sure consistent.
bld.b #7, @TSRW:8 ; get overflow count
bcc _DCL_NOOVERFLOW:8 ; timer has not overflowed yet
inc.w #1, e3 ; increment overflow count
bclr.b #7, @TSRW:8 ; clear the overflow
mov.w @TCNT, r3 ; get current timer value again to take care of boundry conditions
cmp.w #512, e3 ; hopefully will figure out right comparison here
bge _DCL_TIMEDOUT:8 ; We have gone long enough
_DCL_NOOVERFLOW:
cmp.b r0l, r0h ; see if the same as before.
beq _DCL_MAIN:8 ; yes, so go back to our hard main loop
; We have a new value
mov.b r0l, r0h ; update our value we are looking at
xor.b r0l, r0l ; zero out low value to combine for buffer entry.
mov.l er3, er2 ; move timer value into ER2 to modify into buffer value
shlr.l er2 ; divide by 2 so now in microseconds...
or.w r0, e2 ; and save away the IO Status bits into the high byte of the long value
; now lets save it away
mov.l er2, @er5 ; save away the entry...
add.l #4,er5 ; point to the next entry
dec.w #1, r4 ; decrement our counter
bne _DCL_MAIN:16 ; not full
; fall through if we filled our buffer
_DCL_TIMEDOUT:
mov.w #BUFFSIZE, r0
sub.w r4, r0 ; calculate how many we did actually store
mov.w r0, @CITEMS:16 ; save it away for basic to use.
; now fall through to return.
high p14
return
;==============================================================================
; Dump Capture
;
; Later may try more fancy things…
;==============================================================================
; localish variable definitions
i var word
j var byte
ItemTime var long
ItemIOBits var byte
ItemTimePrev var long
ItemIOBitsPrev var byte
BitTimes var long(8)
BitMask var byte
DumpCapture:
ItemTimePrev = 0
ItemIOBitsPrev = 0
BitTimes = 0,0,0,0,0,0,0,0
serout s_out, i9600, "Count of items", dec cItems, 13]
; Walk through all of the items we captured
if cItems > 0 then
for i = 0 to cItems-1
ItemTime = (CaptureBuffer(i) & 0xffffff) ;
ItemIOBits = CaptureBuffer(i).highbyte
; Start by dumping simply the time mask and the IO bits in hex
serout s_out, i9600, "T:", dec ItemTime, "(", hex ItemTime, ") IO:", hex2 ItemIOBits\2]
; Then try to tell what bit(s) changed and the delta time for those bits...
bitMask = 0x01 ; low bit
for j = 0 to 7
if ((ItemIOBits & BitMask) <> (ItemIOBitsPrev & BitMask)) then
if (ItemIOBits & BitMask) then
serout s_out, i9600, " Bit: ", dec j, "->1 DT:", dec (ItemTime - BitTimes(j))]
else
serout s_out, i9600, " Bit: ", dec j, "->0 DT:", dec (ItemTime - BitTimes(j))]
endif
BitTimes(j) = ItemTime
endif
bitMask = BitMask << 1
next
serout s_out, i9600, [13] ; output the end of line.
; save away the current valut to compare against for the next item
ItemTimePrev = ItemTime
ItemIOBitsPrev = ItemIOBits
next
else
serout s_out, i9600, "*** No Items returned ***", 13]
endif
; we are done
return
[/code]