Complete P2 assembly-language synchronous receiver-transmitter code

I hope this example might help. A large thank you to Forum members who helped. --Jon
' Synchronous serial transmission, Rev. 3, 06-13-2020 at 1007 MDT
'positive edge-trigger (Jon Titus)

        clkout   = 40	  ' Pin P40       'Transmitter's clock out, to P31
	txout    = 41     ' Pin P41       'Transmitter data out, to P30
	rxin     = 30     ' Pin P30       'Receiver data in
        rxclkin  = 31     ' Pin P31       'Receiver clock in
	'Remember to connect these pins as noted!     
	org 0      
        coginit	id, ##@sync_receive        ' Initialize an available cog for sync receive
' Sync-serial transmit of data at set intervals.
        dirl    #txout				'Transmitter setup
        wrpin	sync_tx_mode,     #txout        'Set sync tx mode for pin 41
	wxpin	#%1_00111,        #txout	'Set up stop/start mode, X[5] = 1, 8 bits (7 + 1)
	dirh	#txout			        'Enable transmitter output
	dirl    #clkout				'Clock output setup
        wrpin	clock_mode,       #clkout       'Set pin as transition-output mode
	wxpin	##$1000,          #clkout       'Set base period for transition output
	dirh	#clkout                         'Enable clock-output

.loop	waitx	##10_000_000			'Delay between transmissions
	wypin	##$11,           #txout         '8-bit data to transmit, your choice
	wypin	#16,             #clkout        'Start clock, transmit data	
	jmp	#.loop				'Continue to transmit

sync_tx_mode    long  %0000_1111_000_0000000000000_01_11100_0	'Positive-edge clock mode

clock_mode	long  %0000_0000_000_000000_0_000000_01_00101_0	'Clock-mode

id	        long 16				'Need the variable, but not used
' Sync-serial receive, data to 8 LEDs on P7-P0
' This software runs in a separate cog	

                org 0
sync_receive  	mov dira, ##$00FF		'Pins P7--P0 set as outputs
                dirl #rxin			'Reset receiver Smart Pin
		wrpin sync_rx_mode, #rxin	'Set sync receiver mode
		wxpin #%1_00111, #rxin		'Set receiver to sample on B-input edge
		dirh #rxin			'Enable Smart-Pin sync receiver

.test_loop	testp #rxin  wc			'Wait in loop for received data; IN flag raised
if_nc		jmp #.test_loop			'If no C flag, repeat testing
		rqpin rcvd_data, #rxin		'Put 32-bit data (see text) in rcvd_data
		shr rcvd_data, #24		'shift-right data 24 places to LSB
		mov outa, rcvd_data		'Send 8 bit data to LEDs
		jmp #.test_loop			'Continue to receive and display data

sync_rx_mode    long  %0000_0001_000_0000000000000_01_11101_0

rcvd_data	long	$00


  • You don't need the "id" variable if you just use an immediate value in the coginit's D field, telling it to allocate a free cog:
    coginit	#%0_1_0000, ##@sync_receive

    I'm assuming you have the unnecessary nop inside .test_loop to save some power while waiting. If you really want to save power, you can entirely avoid the busy-wait loop using SETSE1/2/3/4 and WAITSE1/2/3, or SETPAT and WAITPAT.

    Is there any reason you used RQPIN and not RDPIN? I've never used RQPIN; I was under the impression that you normally only ever use RQPIN instead of RDPIN if you AKPIN or RDPIN that it somewhere else.
  • The NOP was left in so I could insert another instruction during testing, but I forgot to remove the NOP. I'm learning P2 assembly language and haven't looked into the SETSE events yet. I wanted to create code that beginners like me would easily understand. I'm revising the Smart-Pin section of the P2 documentation and think simple code examples will help people. My assembly-language experience started with a PDP-8/L minicomputer and ended when I finished working with the 8080 and Z-80 in the late 1970's. Getting back into it. Thanks for your comments. --Jon
  • I had the idea to use a pull up resistor on a pin designated for serial comms. Set the pin output to low and set dir to high anytime you wanted to output a low. This would eliminate buss contention.

Sign In or Register to comment.