Solved it I think. You've got a startup out of sync problem with the data word length against the 8 clock pulses. It never recovers. This might be something to be wary of at the start of any packet, ie: make sure clock and data are in sync.
Add a DIRL #clkout at the top of the program, before the WRPIN. May as well do the #txout too.
Without the DIRL, what can happen is the DIR can already be high and the moment WRPIN sets the mode it acts. Which for transition mode may start streaming clocks so that the moment the sync.serial is enable/set will be shifting without you having told it to.
Solved it I think. You've got a startup out of sync problem with the data word length against the 8 clock pulses. It never recovers. This might be something to be wary of at the start of any packet, ie: make sure clock and data are in sync.
To handle this, I thought Smart Pins has some ability to prepare (arm) a number of pins, and then start ?
Even without that, the code seems to always have Tx Shifter load, right before Tx Clock load, so shouldn't that always have a fixed and small 2 Sysclk offset ?
Or, do you mean the startup/configure sequence should always configure CLK first, so the pin is in a stable state, before it preps the TX connected to that clock pin ?
The above code does not do that, and in a part that floats pins during reset and until users define them, there is no assumed starting pin state.
Or, do you mean the startup/configure sequence should always configure CLK first, so the pin is in a stable state, before it preps the TX connected to that clock pin ?
The above code does not do that, and in a part that floats pins during reset and until users define them, there is no assumed starting pin state.
I think he'll be happy when he tries this out tonight! Moving the CLK config before Tx, worked in PNut as well as with fastspin/loadp2...
Without the DIRL, what can happen is the DIR can already be high and the moment WRPIN sets the mode it acts. Which for transition mode may start streaming clocks so that the moment the sync.serial is enable/set will be shifting without you having told it to.
On reset the P2 sets all DIR bits low anyway.
This still doesn't explain why it works for Terry in Pnut (most of the time?) but never from spin2gui.
The code runs fine here from both pnut and spin2gui.
I even tried loading from Python P2 loader as well and it worksfine too.
I'm guessing it depends on prior X and Y. Maybe they can be indeterminate if not set. And Y isn't being set until after the first second.
PS: I've been testing FPGA with v33j.
Yes, but that just floats the pins.
Ideally, you want the Sync CLK pin firmly defined before you enable any connected-shifter, otherwise you have a lottery of a possible first edge on init.
During reset (DIR=0), IN is low, the output is low, and Y is set to zero.
My take from that is, if DIR is high then, any pre-existing Y value is a case for automatic transitions on mode config. And they don't stop until Y counts to zero.
Actually, dgately may have identified the most important part - placing the DIRH #txout at the end of the init code.
Actually, that part of the code was as ke4pjw had written it... I just added the dirl instructions and moved the clk config portion above the txout config portion. So, that's all from JMG's suggestion.
It would seem that my P2-ES board has lower noise than Terry's board.
As has been pointed out the clock config should be done before tx config.
This doesn't seem to matter on my board as I've mentioned above.
To replicate the $1c error I did the following in between tx and clock config.
drvh #clkout
fltl #clkout
A single clock throws the sync transmitter out of order.
Scope images now show $1c instead of $C1 as Terry observed.
So Clock before Tx config and your good to go. :cool:
The code examples work properly. How can I get inverted clock pulses? I want a logic-1 output on the idle clock pin and logic-0 pulses so a device can sample on the logic-1 to logic-0 transition. See figure below. Thanks. --Jon
Thanks, evanh, I tried that. But the result shows the first negative-going edge of the clock signal coincident with the negative-going edge at the end of the first bit, a logic-1. So the first bit sent gets "lost." Seems to me the clocking edge should appear in the middle of the bit time. Any ideas? --Jon
CON
clkout = 20 ' Pin P20
txout = 21 ' Pin P21
dat org
wrpin sync_tx_mode, #txout 'Set up sync tx mode
wxpin #%1_00111, #txout 'Set up stop/start mode
dirh #txout 'Enable Smart Pin
wrpin clock_mode, #clkout 'Set pin P21 as transition-output mode
wxpin ##$1000, #clkout 'Set base period for transition output
dirh #clkout 'Enable P21 as clock-output
.loop waitx ##10_000_000 'Delay between transmissions
wypin #$71, #txout '8-bit data to transmit: 01110001
wypin #16, #clkout 'Start clock, transmit data
jmp #.loop 'Loop to transmit again and again
sync_tx_mode long %0000_1111_000_0000000000000_01_11100_0 'B pin = current pin-1
clock_mode long %0000_0000_000_0000001000000_01_00101_0 'Transition-mode setup
'Courtesy of ozpropdev via Parallax Forum
Back for more help... Looks like the synchronizing clock gets transmitted one cycle too late in one mode. The attached scope image (0009) shows the clock and data output when I run the program below. The sync_tx_mode BBBB bits are set for %1111. The clock output appears delayed so it does not generate an edge for the logic-1 LSB. Data to send is $85, transmitted as %10100001. (Same results on logic analyzer.)
When I change the BBBB bits in sync_tx_mode to %0111 the scope shows the proper negative-going clock edge. Also shown in second attached scope image (0008).
I'm working on revisions to the Propeller-2 Smart-Pin docs and want to include an example of positive-going clocking and negative-going clocking. I appreciate all help offered. --Jon
CON
clkout = 20 ' Pin P20
txout = 21 ' Pin P21
dat org
wrpin sync_tx_mode, #txout 'Set up sync tx mode for pin 21
wxpin #%1_00111, #txout 'Set up stop/start mode, X[5] = 1, 8 bits
dirh #txout 'Enable Smart Pin
wrpin clock_mode, #clkout 'Set pin P20 as transition-output mode
wxpin ##$1000, #clkout 'Set base period for transition output
dirh #clkout 'Enable P20 as clock-output
.loop waitx ##10_000_000 'Delay between transmissions
wypin #$85, #txout '8-bit data to transmit: 10000101
wypin #16, #clkout 'Start clock, transmit data
jmp #.loop 'Loop to transmit again and again
sync_tx_mode long %0000_0111_000_0000000000000_01_11100_0 'B pin = current pin-1
clock_mode long %0000_0000_000_0000001000000_01_00101_0 'Transition-mode setup
Well, there is at least four valid combinations for SPI clocking. And there is more if the clock idle state is treated separately from the clocking edge.
And incoming vs outgoing clocking can also double the combinations again, ie: the master data out can be transitioned on the same clock edge as the slave data in reads. Normally SPI specifically avoids this possibility but the prop2 has such a lot of stages in the I/O that it's a perfectly reliable way of handling SPI.
I wouldn't be able to fit all the examples in one post!
Back for more help... Looks like the synchronizing clock gets transmitted one cycle too late in one mode. The attached scope image (0009) shows the clock and data output when I run the program below.
Ha, I see what you mean. I've not actually tried to use the smartpins as intended for this. My experiments were always operating at the edge where staging trickery was a given.
Okay, so it seems that only CPHA=0 is correctly supported:
'SPI clock mode CPHA=0, CPOL=0
sync_tx_mode long %0000_1111_000_0000000000000_01_11100_0 'B pin = current pin-1
clock_mode long %0000_0000_000_0000000000000_01_00101_0 'Transition-mode setup
'SPI clock mode CPHA=0, CPOL=1
sync_tx_mode long %0000_0111_000_0000000000000_01_11100_0 'B pin = current pin-1
clock_mode long %0000_0000_000_0000001000000_01_00101_0 'Transition-mode setup
PPS: When operating with bit rate at a close fraction of sysclock rate, the phase can be altered by taking advantage the number of sysclock'd stages in from the B pin and back out the tx pin.
Actually, even at a sedentary pace you can still use the fact that those stages exist anyway. They still present a significant hold time that any real hardware slave device will be happy with. Meaning the clock-out and clock-in can be treated as the same polarity rather than the nominal SPI way of using opposing polarities.
It just looks bad at bitrate of sysclock/8192 is all.
Interestingly, it's only the first group after the synchronous serial transmit Smartpin is enabled that indicates the loss of the first clock pulse. Everything sent after that is correct for either BBBB = 0111 or BBBB = 1111. Scope works today, capture does not, sorry. For the code below, trigger on txout pin rising, 10 MHz sample rate gave a nice display when zoomed in.
CON
clkout = 20 ' Pin P20
txout = 21 ' Pin P21
baseperiod = $100 ' 256 decimal
bytedelay = baseperiod * 16 ' 4096 decimal
dat org
dirl #clkout
wrpin clock_mode, #clkout 'Set pin P20 as transition-output mode
wxpin #baseperiod, #clkout 'Set base period for transition output
dirh #clkout 'Enable P20
wypin #48, #clkout 'Start clock first
dirl #txout
wrpin sync_tx_mode, #txout 'Set up sync tx mode for pin 21
wxpin #%1_00111, #txout 'Set up stop/start mode, X[5] = 1, 8 bits
dirh #txout 'Enable P21
wypin #$00, #txout '8-bit data to transmit: 00000000
waitx ##bytedelay
wypin #$85, #txout '8-bit data to transmit: 10000101 LSB transmitted first
waitx ##bytedelay
wypin #$00, #txout '8-bit data to transmit: 00000000
waitx ##bytedelay
.loop jmp #.loop 'We're done, loop forever
sync_tx_mode long %0000_0111_000_0000000000000_01_11100_0 'B pin = current pin-1
clock_mode long %0000_0000_000_0000001000000_01_00101_0 'Transition-mode setup
EDIT: Corrected a couple of comments.
EDIT2: Updated code to change the delay from ##3000 to ##4096.
Comments
Add a DIRL #clkout at the top of the program, before the WRPIN. May as well do the #txout too.
I thought I was going crazy for a moment!
Even without that, the code seems to always have Tx Shifter load, right before Tx Clock load, so shouldn't that always have a fixed and small 2 Sysclk offset ?
Or, do you mean the startup/configure sequence should always configure CLK first, so the pin is in a stable state, before it preps the TX connected to that clock pin ?
The above code does not do that, and in a part that floats pins during reset and until users define them, there is no assumed starting pin state.
dgately
The code works Ok in Pnut and spin2gui here on my P2-ES without any changes.
This still doesn't explain why it works for Terry in Pnut (most of the time?) but never from spin2gui.
The code runs fine here from both pnut and spin2gui.
I even tried loading from Python P2 loader as well and it worksfine too.
Huh, you're right. I'd done that too and forgotten about it.
Same scope images either way.
PS: I've been testing FPGA with v33j.
Ideally, you want the Sync CLK pin firmly defined before you enable any connected-shifter, otherwise you have a lottery of a possible first edge on init.
My take from that is, if DIR is high then, any pre-existing Y value is a case for automatic transitions on mode config. And they don't stop until Y counts to zero.
EDIT: Like JMG says, clkout needs to be well defined before txout is engaged.
As has been pointed out the clock config should be done before tx config.
This doesn't seem to matter on my board as I've mentioned above.
To replicate the $1c error I did the following in between tx and clock config. A single clock throws the sync transmitter out of order.
Scope images now show $1c instead of $C1 as Terry observed.
So Clock before Tx config and your good to go. :cool:
Someone may want to add this to the tricks and traps thread.
Again, thank you!
Just do it, It is just a normal thread...
Cool that you nailed it down.
Enjoy!
Mike
eg: In Terry's example above:
When I change the BBBB bits in sync_tx_mode to %0111 the scope shows the proper negative-going clock edge. Also shown in second attached scope image (0008).
I'm working on revisions to the Propeller-2 Smart-Pin docs and want to include an example of positive-going clocking and negative-going clocking. I appreciate all help offered. --Jon
And incoming vs outgoing clocking can also double the combinations again, ie: the master data out can be transitioned on the same clock edge as the slave data in reads. Normally SPI specifically avoids this possibility but the prop2 has such a lot of stages in the I/O that it's a perfectly reliable way of handling SPI.
I wouldn't be able to fit all the examples in one post!
Okay, so it seems that only CPHA=0 is correctly supported:
PS: See https://en.wikipedia.org/wiki/Serial_Peripheral_Interface#Clock_polarity_and_phase
PPS: When operating with bit rate at a close fraction of sysclock rate, the phase can be altered by taking advantage the number of sysclock'd stages in from the B pin and back out the tx pin.
It just looks bad at bitrate of sysclock/8192 is all.
EDIT: Corrected a couple of comments.
EDIT2: Updated code to change the delay from ##3000 to ##4096.