FullDuplexSerial hiccups?

I'm using Chip Gracey's FullDuplexSerial.spin in my project. I'm interfacing with it by PASM code filling FDS's txbuff.
When I put pressure on it by doing a hex/ASCII dump of 64K memory as fast as I can, I experienced a garbage character at around once per second. Now looking for a possible reason in the code, I saw the following timing bits:
Similar code is to be found in the tx section. It occured to me that the compare was unnecessary, because the subtraction t1 - cnt would already indicate a timer expiry. So I changed the code to:
and the one-per-second hiccups seem to be gone. There are still some garbage characters transmitted to my terminal, but they occur at a slower rate.
Edit: Observing for a little longer it seems they occur nearly as often, just not at that determined rate.
Does anyone have used FDS to transmit large amounts of data at 115kbps and seen these hiccups, or is it on my (receiver's) side?
TIA,
Juergen
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
He died at the console of hunger and thirst.
Next day he was buried. Face down, nine edge first.
Post Edited (pullmoll) : 3/15/2010 1:49:00 PM GMT
When I put pressure on it by doing a hex/ASCII dump of 64K memory as fast as I can, I experienced a garbage character at around once per second. Now looking for a possible reason in the code, I saw the following timing bits:
...
:bit add rxcnt,bitticks 'ready next bit period
:wait jmpret rxcode,txcode 'run a chuck of transmit code, then return
mov t1,rxcnt 'check if bit receive period done
sub t1,cnt
cmps t1, #0 wc
if_nc jmp #:wait
...
Similar code is to be found in the tx section. It occured to me that the compare was unnecessary, because the subtraction t1 - cnt would already indicate a timer expiry. So I changed the code to:
...
:bit add rxcnt,bitticks 'ready next bit period
:wait jmpret rxcode,txcode 'run a chuck of transmit code, then return
mov t1,rxcnt 'check if bit receive period done
sub t1,cnt wc
if_nc jmp #:wait
...
and the one-per-second hiccups seem to be gone. There are still some garbage characters transmitted to my terminal, but they occur at a slower rate.
Edit: Observing for a little longer it seems they occur nearly as often, just not at that determined rate.
Does anyone have used FDS to transmit large amounts of data at 115kbps and seen these hiccups, or is it on my (receiver's) side?
TIA,
Juergen
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
He died at the console of hunger and thirst.
Next day he was buried. Face down, nine edge first.
Post Edited (pullmoll) : 3/15/2010 1:49:00 PM GMT
Comments
Wrapping case:
rxcnt = $fffffff0
bitticks = $20
new rxcnt = $00000010
CNT = $fffffff8
sub t1, CNT = $18 okay - doesn't generate a carry.
CNT = $ffffffff
sub t1, CNT = $11 okay - doesn't generate a carry.
CNT = $0000000f
sub t1, CNT = $01 okay - doesn't generate a carry.
CNT = $00000011
sub t1, CNT = $ffffffff carry flag set, gotcha.
Looks okay to me!?
I think the wrapping case would occur roughly once per minute at 80MHz.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
He died at the console of hunger and thirst.
Next day he was buried. Face down, nine edge first.
Post Edited (pullmoll) : 3/15/2010 2:11:57 PM GMT
Err, I can't test that just now, because I'm unable to write a little test program that would verify it... Perhaps you can do.
Just blink with a LED on P16 if your statement holds true.
The way an ALU subtracts a value is it builds the one's complement of the subtrahend, does an addition and then adds 1 to the result. A one's complement + 1 is also called a two's complement, anyway...
So $10 - $fffffff8 would be executed as $10 + $00000007 + 1 = $18 and no carry or borrow is involved here.
But you made me a little nervous now, I have to go and think about the very basics of binary computation again.
Edit: Darn! You are right! I wouldn't have expected this, but the simple SUB does set the carry in this case. The SUBS does not, but I don't know how this would work for the cases around $7fffffff / $80000000.
Edit2: Tested for $80000010 - $7fffffff with SUBS this generates a carry (or borrow).
Conclusion: Chip's code is right in doing what it did - and I have learned my lesson
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
He died at the console of hunger and thirst.
Next day he was buried. Face down, nine edge first.
Post Edited (pullmoll) : 3/15/2010 3:45:18 PM GMT
It would be useful if you posted all your code.· The glitch you are seeing could occur if you update tx_head just before you put the byte in tx_buffer.· In that case FDS could print an old character in the buffer from 16 bytes earlier.
Dave
Hi Dave,
here's the code I use:
'******************************************* ' ' Write data to the FullDuplexSerial ' tx_buffer ' tx rdlong t1, tx_head mov t3, t1 add t1, #1 rdlong t2, tx_tail and t1, #15 cmp t1, t2 WZ if_z jmp #tx ' wait until there's room in the buffer mov t1, t3 add t1, tx_buffer wrbyte data, t1 sub t1, tx_buffer add t1, #1 and t1, #15 wrlong t1, tx_head ' increment the tx_head tx_ret ret
I just realized that this one would be much shorter:
'******************************************* ' ' Write data to the FullDuplexSerial tx_buffer ' tx rdlong t1, tx_head mov t3, t1 add t1, #1 rdlong t2, tx_tail and t1, #15 cmp t1, t2 WZ if_z jmp #tx ' wait until there's room in the buffer add t3, tx_buffer wrbyte data, t3 wrlong t1, tx_head ' increment the tx_head tx_ret ret
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
He died at the console of hunger and thirst.
Next day he was buried. Face down, nine edge first.
Post Edited (pullmoll) : 3/15/2010 4:18:22 PM GMT
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
He died at the console of hunger and thirst.
Next day he was buried. Face down, nine edge first.
You could try sending a known pattern and looping it back to the rx pin.· If you sent an incrementing byte pattern you could detect a break in the pattern and print out a message.· You would need another instance of FDS to be able to print it out.· Or maybe you could use a video display to show the debug messages.
I think Kye has some serial code. And there is the 4 port serial object in the obex (64 byte buffers). I wonder if they can replicate this problem?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
www.smarthome.viviti.com/propeller
Post Edited (Dr_Acula) : 3/16/2010 2:21:07 AM GMT
-Phil
I also run my serial coms at 115.2K constantly but there are irregularities with the timing that can cause problems at higher speeds that I have observed and this is also due to the jmpret trick of handling rx and tx in one cog. Late last year I was threatening to release a universal serial coms object (UNICOM) but I have been a bit slack, so kick me. http://forums.parallax.com/showthread.php?p=867266
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
*Peter*
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Links to other interesting threads:
· Home of the MultiBladeProps: TriBlade,·RamBlade,·SixBlade, website
· Single Board Computer:·3 Propeller ICs·and a·TriBladeProp board (ZiCog Z80 Emulator)
· Prop Tools under Development or Completed (Index)
· Emulators: CPUs Z80 etc; Micros Altair etc;· Terminals·VT100 etc; (Index) ZiCog (Z80) , MoCog (6809)·
· Prop OS: SphinxOS·, PropDos , PropCmd··· Search the Propeller forums·(uses advanced Google search)
My cruising website is: ·www.bluemagic.biz·· MultiBlade Props: www.cluso.bluemagic.biz
After some searching I found it. Unfortunately the problem persists, so it's most probably on my end of things. I tried with a 256 byte buffer.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
He died at the console of hunger and thirst.
Next day he was buried. Face down, nine edge first.
I tried your object and it wont run with any thing higher than 256. I get an error when compiled at 512.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Links to other interesting threads:
· Home of the MultiBladeProps: TriBlade,·RamBlade,·SixBlade, website
· Single Board Computer:·3 Propeller ICs·and a·TriBladeProp board (ZiCog Z80 Emulator)
· Prop Tools under Development or Completed (Index)
· Emulators: CPUs Z80 etc; Micros Altair etc;· Terminals·VT100 etc; (Index) ZiCog (Z80) , MoCog (6809)·
· Prop OS: SphinxOS·, PropDos , PropCmd··· Search the Propeller forums·(uses advanced Google search)
My cruising website is: ·www.bluemagic.biz·· MultiBlade Props: www.cluso.bluemagic.biz
The size of the transmit buffer is irrelevant for your test.· Once you fill up the buffer the back-pressure should cause you to run at the transmit rate.· Since your test is sending 64K of data it will quickly back up even if you used an 8K buffer.· The main question is whether your PASM routine is working correctly.· You could modify your PASM routine to generate an incrementing pattern of bytes, and then read it back to verify if it is correct.· I think the following Spin·method would work to check the stream.
PUB CheckStream | errorcount, value, expected
· errorcount := 0
··value := serial.rx
· repeat 65535
··· expected := (value + 1) & 255
··· value := serial.rx
··· if (value <> expected)
···· errorcount++
· return errorcount
errorcount should return with a value of 0 if everything is OK.· It would really be a lot easier for us to help you if you posted all your code.· Otherwise, we're just guessing.
Dave
I know what you intend, but right now I have just 1 Propeller to test with. The other end is a PC running Linux in my case.
All my code is in the first entry in the thread Proposed Z80 DRC CPU core. The serial i/o functions are in io.spin. A modified version of FullDuplexSerial 1.1 is included. It exports the address of rx_head to allow interfacing from PASM.
Juergen
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
He died at the console of hunger and thirst.
Next day he was buried. Face down, nine edge first.
Post Edited (pullmoll) : 3/16/2010 4:45:01 PM GMT
You don't need two Props to run the test I suggested.· You would just jumper the serial tx pin to the rx pin.
Dave