Skip to content

Commit

Permalink
Completed functioning TX/RX system between Props
Browse files Browse the repository at this point in the history
  • Loading branch information
cspang1 committed May 10, 2018
1 parent c3445dd commit f5575c8
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 47 deletions.
37 changes: 37 additions & 0 deletions Dev/Game/Software/rx_test.spin
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{{
File: txrx.spin
Author: Connor Spangler
Date: 5/9/2018
Version: 1.0
Description:
This file contains the PASM code defining a test transmission routine
}}

CON
' Clock settings
_clkmode = xtal1 + pll16x ' Standard clock mode w/ 16x PLL
_xinfreq = 6_500_000 ' 6.5 MHz clock for x16 = 104 MHz

OBJ
vga_rx : "vga_rx" ' Import graphics reception system
serial : "FullDuplexSerial"

PUB main | time, indx
serial.Start(31, 30, %0000, 57600)
waitcnt(cnt + (1 * clkfreq))

vga_rx.start(@output)
indx := 0
time := cnt

repeat
waitcnt(time += (clkfreq/60))
serial.Hex(long[@output][indx], 8)
serial.Tx($0D)
indx++
if indx == ((40*30*2)+(32*16)*2+(64*4))/4
indx := 0

DAT

output long 0[((40*30*2)+(32*16)*2+(64*4))/4]
28 changes: 28 additions & 0 deletions Dev/Game/Software/tx_test.spin
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{{
File: txrx.spin
Author: Connor Spangler
Date: 5/9/2018
Version: 1.0
Description:
This file contains the PASM code defining a test transmission routine
}}

CON
' Clock settings
_clkmode = xtal1 + pll16x ' Standard clock mode w/ 16x PLL
_xinfreq = 6_500_000 ' 6.5 MHz clock for x16 = 104 MHz

OBJ
vga_tx : "vga_tx" ' Import graphics transmission system

PUB main | time, indx
vga_tx.start(@input)
time := cnt

repeat
waitcnt(time += (clkfreq/60))
vga_tx.transmit

DAT

input long $ABCD_DCBA[((40*30*2)+(32*16)*2+(64*4))/4]
41 changes: 0 additions & 41 deletions Dev/Game/Software/txrx.spin

This file was deleted.

11 changes: 5 additions & 6 deletions Dev/Game/Software/vga_rx.spin
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ PUB receive
cont_ := FALSE

PUB stop ' Function to stop reception driver
if cog_ ' If cog is running
cogstop(cog_~ - 1) ' Stop the cog
if cog_ ' If cog is running
cogstop(cog_~ - 1) ' Stop the cog

DAT
org 0
Expand All @@ -45,16 +45,15 @@ rx
rdlong bufptr, par ' Initialize pointer to variables

' Initialize pins
andn dira, RxPin ' Set output pin {{ DOES THIS BREAK??? }}
andn dira, RxPin ' Set output pin
or outa, RxPin ' Set pin high for ACK

' Receive graphics buffer
rxbuff mov bufsiz, BuffSz ' Initialize graphics buffer size
mov curlng, bufptr ' Initialize graphics buffer location

' Receive long
:rxlong mov rxval, #0 ' Zero reception long buffer {{ NECESSARY??? }}
waitpeq RxPin, RxPin ' Wait for ACK
:rxlong waitpeq RxPin, RxPin ' Wait for ACK

' Receive bits
:rxbits test RxPin, ina wc ' Get bit
Expand Down Expand Up @@ -143,4 +142,4 @@ bufsiz res 1 ' Container for size of graphics buffer
curlng res 1 ' Container for current long address
rxval res 1 ' Container for current long

fit
fit
1 change: 1 addition & 0 deletions Dev/Game/Software/vga_tx.spin
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ txbuff mov bufsiz, BuffSz ' Initialize graphics buffer siz

' Setup long transmission start
mov phsa, TxStart ' Send one bit high
nop
mov phsa, txval ' Stage long for transfer

' Transmit bits
Expand Down

9 comments on commit f5575c8

@konimaru
Copy link
Collaborator

@konimaru konimaru commented on f5575c8 May 14, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

vga_tx: Is it on purpose that bit 31 only has a 4-cycle life-time whereas all the other bits get 8 cycles?

@cspang1
Copy link
Owner Author

@cspang1 cspang1 commented on f5575c8 May 14, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@konimaru If you look @ vga_rx, you'll see it waits for the 1-instruction ACK then immediately begins polling the data line. For each subsequent bit however, an RCL instruction is required between each. On the TX side this is mirrored by the ACK followed by an immediate first bit, with each subsequent bit requiring a SHL between each.

I'm only getting extremely non-deterministic and intermittent success however, and diagnosing is difficult between 2 Props. If you see anything obvious, please call it out! I already noticed I'm messing up storing the control flag here (should be storing to cntptr), however I'm not using that control flag for RX and I'm sampling the data directly from the wire via a logic analyzer and not relying on the stored data in memory. This value should also be -1, not FALSE.

@konimaru
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One thing you have to make sure is that the rx overhead of writing to hub is covered by the tx part. IOW if you write too fast and you can't get rid of the data fast enough due to unaligned hub-ops then you have a problem.
Another thing is the waitpxx/test timing, once the condition is met waitpxx has - IIRC - a 2 cycle exit path. Live registers are sampled in the 3rd cycle of an instruction. So it looks to me that first bit may get overlooked occasionally.
I'd deal with the hub timing first (same prop, different cogs) or do the worst-case timing manually and put enough spacer code into the tx part. This may help, (last posted proplink archive). You'll notice a simple waitcnt loop to take care of the issue.

Once this is stable (I still expect the occasional wrong top bit) you can deal with point two.

@cspang1
Copy link
Owner Author

@cspang1 cspang1 commented on f5575c8 May 15, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@konimaru crunching the numbers!

@cspang1
Copy link
Owner Author

@cspang1 cspang1 commented on f5575c8 May 15, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@konimaru Alright here's a crack at it. Assume we start our RX cog and it runs for a hundred years, the waitpeq spinning its tires. Then, we fire up the TX cog. We take the mutual clock cycle where the TX cog sends an ACK and the RX cog's waitpeq responds to the ACK as cycle 0:

TX/RX LONG Timing

Based on this analysis, if the RX cog takes longer than 15 cycles to write the previous long (given a worst-case scenario of an 8-cycle TX rdlong), it will miss the next TX ACK and therefore 1 or more data bits from the next long. I'm a fan of KISS, so a few nops before the TX ACK will satisfy me. Is the analysis above accurate? I'm pretty sure it covers both the writing to hub overhead and the waitpxx/test timing, as long as I take into account the worst-case scenarios.

For the transition from one full buffer to the next, I still can't see what the problem is. As far as I can tell, the timing should work perfectly:

TX/RX Buffer Timing

@konimaru
Copy link
Collaborator

@konimaru konimaru commented on f5575c8 May 16, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Timing for long-to-long looks OK except you missed 4 cycles for the nop after the start bit, my own analysis tells me that the receiver part is a tiny but longer. So yes, a few nops should do the trick.

At some point please include some top-bit-clear values in the TX data set, I have the suspicion there is a hidden bug (I could be wrong).

Still thinking about the buffer issue ...

... so are you saying that the transmitter doesn't see the ACK? Can you verify that they are generated? Do you actually trigger a new transfer from Spin (transmit method)?

@cspang1
Copy link
Owner Author

@cspang1 cspang1 commented on f5575c8 May 16, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@konimaru ah yes I removed the nop from the analysis as it was for debugging.

By "top-bit-clear" values do you mean values with bit 31 zero?

As for what's happening: I'm able to successfully transmit 1 full buffer at Prop start, but (apparently) not a long more afterwards until I restart the cogs altogether. I'm definitely triggering a transfer via the transmit method, and based on some logic analyzer debugging, what's ultimately happening is both cogs end up somehow sitting in their respective waitpeq purgatories.

I have an idea as to my next debugging steps when I get home today to pin down when and how the logic is flowing, but based solely on my timing analysis it should be working.

@konimaru
Copy link
Collaborator

@konimaru konimaru commented on f5575c8 May 17, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By "top-bit-clear" values do you mean values with bit 31 zero?

Exactly!

Yeah, based on a initial review timing should be fine. I wonder if the pulse gets lost when you connect two props (cable & Co issues), can you try widening it to 8 cycles just to cover that corner?

@cspang1
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@konimaru that's actually exactly my suspicion; my next round of debugging will give that a shot!

Please sign in to comment.