Shop OBEX P1 Docs P2 Docs Learn Events
SmartPin Synchronous Serial Transmit — Parallax Forums

SmartPin Synchronous Serial Transmit

So I am looking at using a pair of Smartpins in Synchronous Serial Transmit mode. (%11100) and I need some help understanding how to initialize and use the Smartpins. The first hurtle I have to cross is how to setup the A - B pair. How do I determine what pin the clock is going to reside on?

I have looked at some other's code for configuring Smart Pins, but I don't have any examples of mode %11100. I just need another point of view. Feeling really stuck on something simple. I am missing some fundamental of the Smartpins.

Thanks in advance.

--Terry
«13

Comments

  • ozpropdevozpropdev Posts: 2,791
    edited 2019-02-13 06:01
    Try this code
    	clkout = 30
    	txout = 31
    
    dat	org
    	
    	wrpin	sync_tx,#txout		'sync tx
    	wxpin	#%1_00111,#txout	'stop/start mode
    	dirh	#txout			'enable smartpin
    
    
    loop	waitx	##20_000_000
    	wypin	#$f1,#txout
    	rep	@clkgen,#8
    	drvnot	#clkout
    	waitx	#100
    	drvnot	#clkout
    	waitx	#100
    clkgen
    	jmp	#loop
    
    '%11100 = synchronous serial transmit 
    sync_tx	long	%0111 << 24 | %1_11100_0  'b pin = current pin-1
    
    
    

    The B-pin is configured to a neighbour pin, in this case 30.
    640 x 480 - 12K
  • Also if you invert the clock you offset the clock to data timing.
    sync_tx	long	%1111 << 24 | %1_11100_0  'b pin = current pin-1 (inverted)
    

    Transmitting a byte ($71) results in.

    640 x 480 - 12K
  • and here's the same with a smartpin as the clock source.
    	clkout = 30
    	txout = 31
    
    dat	org
    	
    	wrpin	sync_tx,#txout		'sync tx
    	wxpin	#%1_00111,#txout	'stop/start mode
    	dirh	#txout			'enable smartpin
    
    	wrpin	trans,#clkout
    	wxpin	##$1000,#clkout		'set base period
    	dirh	#clkout
    
    loop	waitx	##20_000_000
    	wypin	#$71,#txout		'data
    	wypin	#16,#clkout		'start clock, tx data
    clkgen
    	jmp	#loop
    
    sync_tx	long	%1111 << 24 | %1_11100_0  'b pin = current pin-1
    trans	long	%1_00101_0 
    

  • evanhevanh Posts: 15,171
    Terry,
    In the smartpin docs the WRPIN mode setting config bits are listed as
    D/# = %AAAA_BBBB_FFF_PPPPPPPPPPPPP_TT_MMMMM_0
    
    The BBBB portion is how you select which pin is the B input. Brian's examples above uses %0111<<24 (pin - 1) in the first example, and %1111<<24 (pin - 1, then inverted) in the second example.

    You'll also note he's set bit six of the config. This is TT = %01, which forces the physical pin driver output on (Equivalent to DIRH in non-smartpin).
  • Thanks guys! OzProp, the examples are great! The B "input" is what confused me in the documentation. That made it sound as if it only did "input" to the chip.

    I will play around with it this evening.

    There need to be examples in the manual, of various implementations, to help folks like myself better understand how to use these versatile features.

    --Terry
  • evanhevanh Posts: 15,171
    It's too early for detailed examples in the docs. There is plenty in the forums though.

    Yeah, some terms aren't very distinctive. The one place that is strongly defined is "IN", "OUT" and "DIR" always represent what the cogs/streamers will see and/or control. The smartpins sit between IN/OUT/DIR and the real pins. When enabled, %MMMMM != 0, they change the meaning of IN/OUT/DIR.
  • evanh wrote: »
    Terry,
    In the smartpin docs the WRPIN mode setting config bits are listed as
    D/# = %AAAA_BBBB_FFF_PPPPPPPPPPPPP_TT_MMMMM_0
    
    The BBBB portion is how you select which pin is the B input. Brian's examples above uses %0111<<24 (pin - 1) in the first example, and %1111<<24 (pin - 1, then inverted) in the second example.
    A real noob in P2 assembly here, so probably a dumb question... I'm still not sure how setting the BBBB portion of the config bits works. What does %0111 or %1111 represent? It's not the actual B pin number (%0111 == 7 & %1111 == 15 decimal), so is it an offset from the known pin? One really good example of what each of the bits represent would probably help get me off the ground on smart pins. Maybe I'm just a bit "dense" in understanding the smart pin doc, but I do think there's a gap that's difficult to cross in actual usage of the config bits and the instructions.

    Thanks for any help,
    dgately
  • jmgjmg Posts: 15,144
    dgately wrote: »
    ...so is it an offset from the known pin? ..
    Yes. B MSB sets True/Inverted and the lower 3 bits are an 8 way relative-to-A pin mapping

    This bit is from the smart pins docs
    For the WRPIN instruction, which establishes both the low-level and smart-pin configuration for each I/O pin, the D operand is composed as:
    
    D/# = %AAAA_BBBB_FFF_PPPPPPPPPPPPP_TT_MMMMM_0
    
     %AAAA:  ‘A’ input selector
                 0xxx = true (default)
                 1xxx = inverted
                 x000 = this pin’s read state (default)
                 x001 = relative +1 pin’s read state
                 x010 = relative +2 pin’s read state
                 x011 = relative +3 pin’s read state
                 x100 = this pin’s OUT bit from cogs
                 x101 = relative -3 pin’s read state
                 x110 = relative -2 pin’s read state
                 x111 = relative -1 pin’s read state
    
     %BBBB:  ‘B’ input selector
                 0xxx = true (default)
                 1xxx = inverted
                 x000 = this pin’s read state (default)
                 x001 = relative +1 pin’s read state
                 x010 = relative +2 pin’s read state
                 x011 = relative +3 pin’s read state
                 x100 = this pin’s OUT bit from cogs
                 x101 = relative -3 pin’s read state
                 x110 = relative -2 pin’s read state
                 x111 = relative -1 pin’s read state
    
      %FFF:  ‘A’ and ‘B’ input logic/filtering (after ‘A’ and ‘B’ input selectors)
                 000 = A, B (default)
                 001 = A AND B, B
                 010 = A OR  B, B
                 011 = A XOR B, B
                 100 = A, B, both filtered using global filt0 settings
                 101 = A, B, both filtered using global filt1 settings
                 110 = A, B, both filtered using global filt2 settings
                 111 = A, B, both filtered using global filt3 settings
    
                 The resultant ‘A’ will drive the IN signal in non-smart-pin modes.
    
     %P..P:  low-level pin control (needs final silicon to fully operate)
                 The table below shows the %P..P bits as M[12:0]: {Graphics table does not paste}
    
    
    
       %TT:  pin DIR/OUT control (default = %00)
    
             for odd pins,  ‘OTHER’ = NOT lower pin’s output state (diff source)
             for even pins, ‘OTHER’ = unique pseudo-random bit (noise source)
             for all pins,  ‘SMART’ = smart pin output which overrides OUT/OTHER
             ‘DAC_MODE’ is enabled when P[12:10] = %101
             ‘BIT_DAC’ overrides P[7:0] with $00 during ‘low’ output in DAC_MODE
    
             for smart pin mode off (%MMMMM = %00000):
    
                 DIR enables output
    
                 for non-DAC_MODE:
                     0x = OUT drives output
                     1x = OTHER drives output
                 for DAC_MODE:
                     00 = OUT enables ADC, P[7:0] sets DAC level
                     01 = OUT enables ADC, P[3:0] selects cog DAC channel
                     10 = OUT drives BIT_DAC
                     11 = OTHER drives BIT_DAC
    
             for all smart pin modes (%MMMMM > %00000):
                 x0 = output disabled, regardless of DIR
                 x1 = output enabled, regardless of DIR
    
             for DAC smart pin modes (%MMMMM = %00001..%00011):
                 0x = OUT enables ADC in DAC_MODE, P[7:0] overriden
                 1x = OTHER enables ADC in DAC_MODE, P[7:0] overriden
    
             for non-DAC smart pin modes (%MMMMM = %00100..%11111):
                 0x = SMART/OUT drives output or BIT_DAC if DAC_MODE
                 1x = SMART/OTHER drives output or BIT_DAC if DAC_MODE
    
    %MMMMM:  00000   = smart pin off (default)
             00001   = long repository              (P[12:10] != %101)
             00010   = long repository              (P[12:10] != %101)
             00011   = long repository              (P[12:10] != %101)
             00001   = DAC noise                    (P[12:10]  = %101)
             00010   = DAC 16-bit dither, noise     (P[12:10]  = %101)
             00011   = DAC 16-bit dither, PWM       (P[12:10]  = %101)
             00100*  = pulse/cycle output
             00101*  = transition output
             00110*  = NCO frequency
             00111*  = NCO duty
             01000*  = PWM triangle
             01001*  = PWM sawtooth
             01010*  = PWM switch-mode power supply, V and I feedback
             01011   = periodic/continuous: A-B quadrature encoder
             01100   = periodic/continuous: inc on A-rise & B-high
             01101   = periodic/continuous: inc on A-rise & B-high / dec on A-rise & B-low
             01110   = periodic/continuous: inc on A-rise {/ dec on B-rise}
             01111   = periodic/continuous: inc on A-high {/ dec on B-high}
             10000   = time A-states
             10001   = time A-highs
             10010   = time X A-highs/rises/edges -or- timeout a-/high/rise/edge
             10011   = for X periods, count time
             10100   = for X periods, count states
             10101   = for periods in X+ clocks, count time
             10110   = for periods in X+ clocks, count states
             10111   = for periods in X+ clocks, count periods
             11000*  = USB host, low-speed          (even/odd pin pair = DM/DP)
             11001*  = USB host, full-speed         (even/odd pin pair = DM/DP)
             11010*  = USB device, low-speed        (even/odd pin pair = DM/DP)
             11011*  = USB device, full-speed       (even/odd pin pair = DM/DP)
             11100*  = sync serial transmit         (A-data, B-clock)
             11101   = sync serial receive          (A-data, B-clock)
             11110*  = async serial transmit        (baudrate)
             11111   = async serial receive         (baudrate)
    
             * OUT signal overridden
    
    

  • jmg wrote: »
    dgately wrote: »
    ...so is it an offset from the known pin? ..
    Yes. B MSB sets True/Inverted and the lower 3 bits are an 8 way relative-to-A pin mapping

    This bit is from the smart pins docs

    Ah, the MSB... Read it several times, but didn't stick. Got it now!

    Thank you
  • what does - x100 = this pin’s OUT bit from cogs

    I do not understand.

    Mike
  • evanhevanh Posts: 15,171
    edited 2019-02-14 14:41
    Mike,
    That's what I've been working on here - https://forums.parallax.com/discussion/comment/1464427/#Comment_1464427

    I've labelled it with ?? in the block diagram. Then spent a little time verifying more precisely its source, documenting in the subsequent post.
  • msrobotsmsrobots Posts: 3,704
    edited 2019-02-14 14:55
    ahh so I can use IN from a pin as AAAA 0000 OUT from the same pin as BBBB 0100 and then combine them?

    Interesting.

    Enjoy!

    Mike
  • evanhevanh Posts: 15,171
    Yep.
  • Ok, I need more help. It appears that when I write the code to send data MSB first, it sends LSB first. When I comment the two lines that prepare the data for MSB, it generates a completely nonsensical output.

    I think I am going nuts! Or I have a poor fundamental understanding of sync-serial. Probably both!
    con
    	clkout = 9
    	txout = 8
    
    dat	org
    	
    	wrpin	sync_tx,#txout		'sync tx
    	wxpin	#%1_00111,#txout	'stop/start mode
    	dirh	#txout			'enable smartpin
    
    	wrpin	trans,#clkout
    	wxpin	##$1000,#clkout		'set base period
    	dirh	#clkout
    
    	SHL data,#32-8  ' Set MSB First
    	REV data	' Set MSB First
    
    
    loop	waitx	##20_000_000
    	wypin	data,#txout		'data
    	wypin	#16,#clkout		'start clock, tx data
    clkgen
    	jmp	#loop
    sync_tx	long	%1001 << 24 | %1_11100_0  'b pin = current pin+1 and inverted
    trans	long	%1_00101_0
    data	long	$C1
    
    MSB First commented out
    Screenshot%20%2832%29.png

    MSB First Enabled
    Screenshot%20%2833%29.png
    375 x 152 - 3K
    312 x 172 - 3K
  • Terry
    Your code looks and runs Ok here.
    I did a slight change to the code to return the txout signal low on completion just to make better pictures.
    loop	waitx	##20_000_000
    	wypin	data,#txout		'data
    	wypin	#16,#clkout		'start clock, tx data
    busy	testp	#clkout wc
    	if_nc	jmp	#busy
    	rdpin	pa,#clkout
    	wypin	#0,#txout
    	jmp	#loop
    
    640 x 480 - 9K
    640 x 480 - 8K
    640 x 480 - 8K
    640 x 480 - 9K
  • ozpropdev

    Well, good to know I am not completely mad! LOL. Maybe this is a problem with fastspin or maybe how my Saleae analyzer is configured. I will press on.

    Thank you for the additional code snippet. Quick question about it. What is "pa" used in rdpin?

    BTW, saw your code for the pixel strip. The P2 is going to make one heck of a "pixel pusher". Can't wait to fill my yard with them come Christmas time!

    Thanks,
    Terry
  • Cluso99Cluso99 Posts: 18,069
    PA & PB are special registers similar to PTRA & PTRB.
  • I used the pa reg as a dummy reg with rdpin to clear the smartpin status.
  • evanhevanh Posts: 15,171
    I picked up on that Brian, and recently started using pa/pb for parameter passing and scratch. Particularly handy for using LOC to specify hubRAM addresses for strings for example.
  • ke4pjwke4pjw Posts: 1,074
    edited 2019-02-15 14:16
    This is a bug in fastspin. Works correctly in PNUT, does not work correctly in Spin2GUI 1.3.7.

    Without Spin, my plans are kind of taken off the rails. :( At least I know I am not bonkers!
    con
    	clkout = 9
    	txout = 8
    
    dat	org
    	
    	wrpin	sync_tx,#txout		'sync tx
    	wxpin	#%1_00111,#txout	'stop/start mode
    	dirh	#txout			'enable smartpin
    
    	wrpin	trans,#clkout
    	wxpin	##$1000,#clkout		'set base period
    	dirh	#clkout
    
    	SHL data,#32-8  ' Set MSB First
    	REV data	' Set MSB First
    
    
    loop	waitx	##20_000_000
    	wypin	data,#txout		'data
    	wypin	#16,#clkout		'start clock, tx data
    
    busy	testp	#clkout wc
    	if_nc	jmp	#busy
    	rdpin	pa,#clkout
    	wypin	#0,#txout
    
    	jmp	#loop
    
    sync_tx	long	%1001 << 24 | %1_11100_0  'b pin = current pin+1 and inverted
    trans	long	%1_00101_0
    data	long	$C1
    
    



    Screenshot%20%2834%29.png
    Screenshot%20%2835%29%201.png






    Screenshot%20%2836%29.png
    Screenshot%20%2835%29%202.png
    544 x 159 - 2K
    825 x 619 - 31K
    384 x 139 - 2K
    1171 x 1253 - 246K
  • I don't think this is a bug in fastspin -- the binary file that PNut produces (.obj) is exactly the same as the one fastspin produces (.binary), at least for me.

    That means something else in the environment is causing your problem. I notice that you are not setting the clock frequency in your program. I guess you're assuming it is in RCFAST mode? I suspect loadp2 changes that. It'd be safest to explicitly set the clock mode and frequency to what you want them to be when your program starts up.
  • Yes, this is some difference between PNut and loadp2. The binaries are identical in content and length.

    I will set the clock information and see if that makes a difference. I think it would be valuable to understand why this is happening. I will run it down as best I can.

    Thanks,
    Terry
  • Hmmm, The fact that the clock is being generated by the transition smartpin and I assume your timebase hasn't changed then the sync tx smartpin should still work.
    It should work at any clock speed.
    Strange...
  • BTW
    I could have used the alias AKPIN #clkout or WRPIN #1,#clkout instead of RDPIN pa,#clkout.
    The all achive the same outcome, clearing the smartpin status.
  • ozpropdev wrote: »
    Hmmm, The fact that the clock is being generated by the transition smartpin and I assume your timebase hasn't changed then the sync tx smartpin should still work.
    It should work at any clock speed.
    Strange...

    My thoughts exactly. I don't know if the problem is something with my machine or not. Do you have spin2gui installed? I am using version 1.3.7 It includes everything needed to compile and load the P2.

    It would be interesting to see if it does the same for you.
  • Installing spin2gui now....
  • Terry
    Running code from spin2gui works Ok here.
    I added a hubset #0 so waveform timing match pnut.
    Not sure what's going on?

  • ke4pjwke4pjw Posts: 1,074
    edited 2019-02-16 00:21
    So I loaded both binaries on to SD cards. When booted from SD, they both behave the same and behave incorrectly. Not the result I was expecting.

    Let me add hubset #0 into the mix.
  • hubset #0 makes no difference. Still can only get pnut to operate correctly, but only if loaded into RAM. Runs incorrectly when copying binary onto the SD card.

    Setting the clock to 250Mhz makes no difference.
    con
    	clkout = 9
    	txout = 8
    
    	osc = 20_000_000
    	dv = 2
    	mlt = 25	'for 250 MHz 
    	clk = 1 << 24 | (dv-1) << 18 | (mlt-1) << 8
    	sys_clk	= osc / dv * mlt
    
    dat	org
    	hubset	##clk | %1111_01_00	'enable crystal+PLL, stay in 20MHz+ mode
    	waitx	##20_000_000/100	'wait ~10ms for crystal+PLL to stabilize
    	hubset	##clk | %1111_01_11	'now switch to PLL running at 250Mhz
    
    
    	wrpin	sync_tx,#txout		'sync tx
    	wxpin	#%1_00111,#txout	'stop/start mode
    	dirh	#txout			'enable smartpin
    
    	wrpin	trans,#clkout
    	wxpin	##$1000,#clkout		'set base period
    	dirh	#clkout
    
    	SHL data,#32-8  ' Set MSB First
    	REV data	' Set MSB First
    
    
    loop	waitx	##20_000_000
    	wypin	data,#txout		'data
    	wypin	#16,#clkout		'start clock, tx data
    
    busy	testp	#clkout wc
    	if_nc	jmp	#busy
    	rdpin	pa,#clkout
    	wypin	#0,#txout
    
    	jmp	#loop
    
    sync_tx	long	%1001 << 24 | %1_11100_0  'b pin = current pin+1 and inverted
    trans	long	%1_00101_0
    data	long	$C1
    
    


    This must be something with my Windows machine. The only commonality is the binary touches the filesystem.

    Oh well. I am at a loss. Thanks for looking at it. Apparently it is my Windows box. I will try another machine.
  • ke4pjwke4pjw Posts: 1,074
    edited 2019-02-17 06:50
    Something is flaky.

    Programming with Pnut it works correctly sometimes.
    Programming with spin2gui it never works correctly.
    Booting from SD never works correctly.

    I don't know what could be wrong, unless my P2 is flaky. Please watch the video. This is maddening.

Sign In or Register to comment.