Smartpin mode sync serial pin issues
I'm dabbling with smartpins for the first time. I have a SPI connection between a Raspberry PI 4 and the P2. The PI is the Controller, P2 is device (I prefer that over master/slave).
I can see the clock and data lines working. I generate random data on the CODI-line, and both CLK and CODI look great on the scope.
So I pulled up the smart pin documentation by Jon Titus and learned about the sync serial pin mode. I use his example to sample from the clock-pin with the following pasm method:
con CLK = 10 CODI = 11 pri spi_test() org ' output on pins 56-59 mov dirb, ##$0f00_0000 .smartpin dirl #CODI 'Reset receiver Smart Pin wrpin sync_rx_mode, #CODI 'Set sync receiver mode wxpin #%1_00111, #CODI 'Set receiver to sample on B- ' input edge dirh #CODI 'Enable Smart-Pin sync receiver .test_loop testp #CODI wc 'Wait in loop IN flag = set nop if_nc jmp #.test_loop 'If no C flag, repeat testing rqpin rcvd_data, #CODI 'Put 32-bit data (see text) in mov outb, rcvd_data 'Send 8 bit data to LEDs jmp #.test_loop 'Continue to rcv and display ' data sync_rx_mode long %0000_0101_000_0000000000000_01_11101_0 rcvd_data long $00 end
According to the documentation the BBBB selects normal logic, -1 from the pin number - and CLK is pin 10.
Now when I look at the CODI-line with my scope, the signal is severely dampened.
Any idea what's going on here?
Also: currently clock is not touched in any way, as I figured that it would by default be an input, and that's that. But is this correct, or do I need some sort of smartpin-input-mode for CLK as well?
Comments
Given that Parallax compilers have smart pin constants built in (that I think are available in FlexSpin, too), I think it wise to use them instead of manually declaring them. Here's a little Spin demo (easy to translate to PASM) that works, and shows how to deal with MSBFIRST and LSBFIRST values.
Note that I used a couple F-F jumper wires to connect my output pins to my input pins so that I didn't have to so anything unnecessary with the sync rx setup.
Okay, your "sync_rx_mode" is selecting pin - 3 for inputB. So that won't work. And %TT=%01 is also wrong. That sets the output driven when the smartpin is on.
This exact listing has a familiar ring to it. Someone else not long ago did exactly the same. Maybe best not to follow Mr Titus's examples. Avoid hand-coding the bit patterns when there is prebuilt ones ready to go. Less errors then.
Here's the correct pin mode:
sync_rx_mode long P_MINUS1_B | P_SYNC_RX
In your case the rx data pin was driving its output, having a fight with the device at the other end.
Inputs are always operating. Although they can be diverted and also changed type. Default input type is plain logic level; can be changed via the %P..P bit-field. %AAAA and %BBBB is your diverters, they select which inputs to look at.
@JonnyMac @evanh Thank you for the suggestion to use the constants. This did in fact do the trick. I'm in general a fan of doing this, however you have to start somewhere, so using examples you think can be trusted as stepping stone is to be expected I believe.
I will comment on the document and reference this thread.
Next step: streaming the expected 768 into RAM or LUT.
Bob Dury will be much better for book style examples. He's a recent arrival but has been putting in a lot of hours on testing each one. He's always asking on the forum about finer details of certain instructions - https://forums.parallax.com/discussion/173558/notes-on-propeller-might-be-helpful-for-new-user#latest
As a follow-up on this, I'm currently struggling to read the data using the smartpin. I transfer it into the LUT (as it's 768 bytes both in/out), and from there print it on the console for now.
The following is the core SPI device routine that waits for CS to be asserted, and then attempts to read data in 32 bit words. This works somewhat but the data in the lut does not look as expected. My current assumption is that somehow the inner loop not working as expected and simply spins to read the last received bytes. But this might be wrong.
The data I'm sending are 768 bytes counting from 0 to 768 (which of course get truncated to 0..255). See
So what I would expect are three times the bytes 0..255 after another.
However the data I print out looks like this:
This is the last LONG transferred, repeated over. I can kind of verify this when changing the data in my buffer like this:
This just reverts the data, so three blocks from 255..0.
I get this:
So most of the values are what would be expected:
3, 2, 1, 0
the last 4 bytes transferred.
But what is also visible: every now and then there is other data interspersed. But also repeated.
My intuition was that maybe I need to use rdpin instead of rqpin to acknowledge and wait for the next full long to arrive.
But when changing this instruction, the system stops working - I presume I'm stuck inside the loop.
Any hints very welcome.
A quick follow-up: my idea that the input_loop is too fast I could confirm by counting the number of read longs and printing the number - I spin ~4500 times instead of the expected 192.
You're on to it. Definitely need to test the smartpin's (CODI) IN state to identify if new data received. And use RDPIN, instead of RQPIN, to clear IN state.
@evanh as usual, once writing things up (and talking to my partner over burger & fries about my day, she's an engineer, too), my palm and my face connected. So I powered up my machine again, and of course I have to use rdpin, but then need to also count the actual words and terminate my loop. Otherwise I'd be stuck on the last transmission. Doh, to quote a famous fictional father.
I will try and setup streaming the output buffer from LUT next, steel yourself against the next barrage of questions
For completeness sake, here is a buffer output, exactly as expected: