Shop OBEX P1 Docs P2 Docs Learn Events
SOLVED: Setting up SERIN/OUT (Serial Transceivers) — Parallax Forums

SOLVED: Setting up SERIN/OUT (Serial Transceivers)

mindrobotsmindrobots Posts: 6,506
edited 2014-02-18 15:58 in Propeller 2
I'm trying to use the serial transceivers and having trouble making them work. I'm assuming I'm doing something wrong in the setup portion.
con
  _clkmode = xtal1+pll16x
  _clkfreq = 80_000_000

 
  rx_pin        = 91
  tx_pin        = 90

DAT
                        org     0
enter
                        jmp              #init

sera            long    <<16 + rx_pin<<9 + <<7 + tx_pin  ' percent 10 is before the <<16 and the <<7 but the forum ate them
bit_period        long    _clkfreq / 115_200

init            
            
            setsera    sera,bit_period        ' setup ser
.
.
.
            serina         x
.
.
.
            serouta       x


I'm trying to replace the bit-banged I/O in pfth with the new SERIN/OUT so once I get a character in, I should be in solid code.

Am I missing something in my setup? The long that is generated appears to have the correct bits set for enabling the RX/TX (8 bit non-inverting) and the proper pin numbers. If I understand the bit period parameter, I think mine should work.

Any thoughts? Need to wrap my knuckles for something stupid?

Thanks!!

Comments

  • rjo__rjo__ Posts: 2,114
    edited 2014-02-16 19:03
    I don't know if this will help, but it works.
    '********************************************************
    '*							*
    '*		Propeller II auto-baud, multi-tasking Hello world		*
    '*							*
    '*		Version 0.4				*
    '*							*
    '********************************************************
    '
    'Ripped from Chip's Rom Monitor 
    '
    '
    ' Usage:	cognew($6E4, rx_pin << 9 + tx_pin)	'start monitor in new cog
    '
    '		rx_pin bit 8 can be set for rx inversion
    '		tx_pin bit 8 can be set for tx inversion
    '
    
    CON
    
    
    
    DAT
    		orgh	$380
    
    		org
    
    		coginit	monitor_pgm,monitor_ptr,#0
    
    monitor_pgm	long	@entry
    monitor_ptr	long	91<<9 + 90
    
    monitor 
                     org
    		
    '********
    '* Data *
    '********
    
    
    
    longs		long
    
    '*********
    
    '* Entry *
    '*********
    
    		org
    
    entry		long	0			'start of data string = 0/nop
    
    		reps	#$1F2-reserves,#1	'clear reserves
    		setinda	#reserves
    		mov	inda++,#0
    		getptra	ctra			'get rx pin into ctra configuration
    		testb	ctra,#16	wc	'handle !rx
    		movbyts	ctra,#%%3313		'keep byte 1, clear others
    		sets	ctra,#%1_100_01001	'ready state-time mode
    		setbnc	ctra,#5			'handle !rx
    		getptra	sera			'get rx/tx pins
    		setb	sera,#8			'ready tx 8T/8N
    		setb	sera,#17		'ready rx 8T/8N
    		setp	sera			'tx high
    		jmptask	#%0010,#baud_task	'enable baud detector task
    		settask	#%%1010
    		jz	base,@$			'wait for <space> to set period
    		clrp	sera			'release tx
    		jmptask	#%0100,#rx_task		'enable serial receiver task
    		settask	#%%1210
    		wraux	#0,#0			'init input line to <enter>
    		getptrb	base			'get base address of byte data
    		sub	base,#longs<<2
    		setptra	myhw_addr
            call	@tx_str			'print hello message
    		serouta	#$0D			'print cr/lf
    		serouta	#$0A						'end of data string
    
    
    '*************
    '* Main Task *
    '*************
    
    
    cmd_new			call	@rx_line		'get input line   ... main loop
                    jmp     @cmd_new
    
    
    '********************************
    
    '*****main task sub-routines*****
    
    rx_line		setptrx	#0			'point to start of line
    			serouta	#">"			'show prompt
    			call	@rx			'get first chr
    			cmp	x,#"'"		wz	'check for repeat
    	if_nz	jmp	@:first			'if not repeat, first chr
    
    :show		rdaux	x,ptrx++	wz	'repeat, show line
    	if_nz	serouta	x
    	if_nz	jmp	@:show
    			jmp	@:done
    :loop			call	@rx			'get next chr
    :first			cmp	x,#13		wz	'cr?
    	if_z		jmp	@:cr
    
    				cmp	x,#8		wz	'backspace?
    	if_nz		cmp	x,#127		wz
    	if_z		jmp	@:bs
    
    				cmp		x,#"A"		wz	'rjo
       	if_z    	setptra my_addr
    	if_z		call	@tx_str
    	
    	
        			cmp      x,#"B"          wz
        if_z        mov      value,mynum			
        if_z    	call     @tx_dec
        
                     cmp      x,#"S"          wz
        if_z        mov      value,#0
        if_z           setb     value,#1
        if_z           call @tx_dec	
        
        
        
        
        			cmp   	 x,#"M"  wz
        			
       	if_z		mov multiplier,#1
       	if_z        mov decvalue,#2
       	if_z        call @MULTIPLY
       	if_z        mov decvalue,multiple
       	if_z        call @tx_dec 
       	
       	    		cmp      x,#"D"          wz
       	if_z        mov decvalue,#32
       	if_z        mov divisor,#5
       	if_z		call @DIVIDE
    
    
       	
       	
                  		cmp     tester, #1  wz,wc
       	if_z   	        setptra equaladdr
        if_z   	        call @tx_str    
    	cmp	x,#" "		wc	'visible chr?
    	if_nc	cmpr	x,#"~"		wc
    	if_c	jmp	@:loop
    	
    	
    	
    		wraux	x,ptrx++		'visible chr, append to line
    		chkptrx			wc	'overflow?
    	if_c	subptrx	#1			'if overflow, back up
    	if_nc	serouta	x			'if not overflow, print chr
    		jmp	@:loop
    
    :bs		chkptrx			wz	'backspace, line empty? if not,
    	if_nz	serouta	x			'..print backspace
    	if_nz	serouta	#" "			'..print space
    	if_nz	serouta	x			'..print backspace
    	if_nz	subptrx	#1			'..back up
    		jmp	@:loop
    
    :cr		wraux	#0,ptrx			'cr, end line with 0
    
    :done		setptrx	#0			'point to start of line
    tx_crlf		serouta	#$0D			'print cr/lf
    			serouta	#$0A
    
    :done		sub	w,#1		wc	'get data count
    	if_nc	mov	dsize,w			'if 0, reuse old data
    			setd	:fix,dsize		'form circular buffer
    :fix		fixinda	#0,#0			'(no instruction-modification problem with 1:4 threading)
    	
    			ret
    			
    DIVIDE      mov  mymsb,#0
                mov  shiftval,#0
                mov  quotient,#0
                abs  tempval,decvalue
                abs  divisor,divisor
    :getmsb     shl  tempval, #1 wc
         if_nc  add mymsb,#1
         if_nc  jmp@:getmsb
                     
                sub bits,mymsb
    'now we have msbit of value (tempval)
         
                mov  shiftval,#1          
           		cmp  shiftval,divisor wc
    :rloop
    
         if_c    		 shl  tempval,#1 wc 
                		 rcl shiftval,#1
                		 cmp  shiftval,divisor wc
                 		 sub  bits,#1
         if_c       	 jmp @:rloop          
                
         		sub shiftval,divisor 
         		add quotient,#1
    :dloop      
    :lloop      
    
        	    cmp bits, #0 wz
                if_z    jmp @:getdone
                shl  tempval,#1 wc
                rcl  shiftval,#1
                cmp  shiftval,divisor wc
        	    shl quotient,#1
        	    sub bits,#1
      '  	    cmp bits, #0 wz
      '  if_z    jmp @:getdone
                cmp  shiftval,divisor wc
        if_c    jmp @:lloop
           
                
                sub shiftval,divisor
           '     shl quotient,#1
                add quotient,#1
              
        	    cmp bits, #0 wz
        if_z    jmp @:getdone
                jmp @:dloop
    :getdone            
    			
                
       	        setptra my_addr
    			call	@tx_str
                mov decvalue,quotient
       		    call @tx_dec
       		    serouta  #13
       		    mov remainder,shiftval
       		    mov decvalue,remainder
       		 	call @tx_dec
    
                
                ret
    
        
                
    
    'shl value, #1 WC, NR    'puts bit 31 into c without affecting value
    'cmpsub  x,y  wc     'y =< x? Subtract it, quotient bit in c
    'rcl x,#1  'rotate c into quotient, shift dividend
    			
    MULTIPLY
    					abs  tempval,decvalue
    					abs  tempmul,multiplier
    					cmp  tempmul,tempval  wc
    		   if_nc    mov  tempval2,tempmul
    		   if_nc    mov  tempmul,tempval
    		   if_nc    mov  tempval,tempval2
    			        mov  multiple,#0
    			        mov  shift,#0
    			        
    :sloop
    			        cmp  tempmul,#0 wz
    		    if_z        mov decvalue,multiple
       	        if_z        call @tx_dec 
    			if_z    ret
    			        mov  tempval2,tempval
    			        shr  tempmul, #1      wc
    				    shl  tempval2, shift
    			 		add shift,#1
    			if_c   add  multiple,tempval2
    			        jmp @:sloop
    
    
    skip_spaces	rdaux	x,ptrx++		'skip space chr(s)
    					cmp	x,#" "		wz
    	if_z			jmp	@skip_spaces
    
    		subptrx	#1			'back up to non-space chr
    
    		ret			wz	'restore z
    tx_dec         
                    mov      gotfirst,#0
                    mov      myreps,#10
                    mov      tempval,decvalue
                    setptra  tensarrayaddr
                    getptra  tempptr
                    sub 	 tempptr,#4
    :repsloop                
                    mov      q,#0
                    add   	 tempptr,#4
                    rdlong   decval,tempptr
                    
    :decloop         		cmp    tempval, decval wc
        if_nc		     	add    q,#1
        if_nc		        sub    tempval,decval
        if_nc		        mov gotfirst,#1
        if_nc		        jmp @:decloop
    
                    
                    cmp   gotfirst,#1  wz
            
        			add   q,#48
       if_z         serouta q
                    djnz myreps,@:repsloop
                    mov decvalue,multiple
                    call @tx_dec 
        	        serouta	#$0D			'print cr/lf
    				serouta	#$0A
                    serouta	#">"
                    ret
    
    
    tx_string	addptra	base			'add data base pointer
    
    tx_str		rdbyte	x,ptra++	wz	'get chr
    	if_z	ret				'if 0, done
    
    		test	x,#$80		wz	'substring?
    	if_nz	notb	tx_str,#8		'toggle ptra/ptrb
    	if_nz	setptrb	x			'ptrb points to substring
    	if_nz	addptrb	base
    	if_nz	jmp	@tx_str			'start substring or resume string
    
    		cmp	x,#"`"		wz	'long tab?
    	if_z	subr	y,#32-16
    	if_nz	cmp	x,#"~"		wz	'short tab?
    	if_z	add	y,#16
    :tab	if_z	serouta	#" "
    	if_z	djnz	y,@:tab
    	if_z	serouta	#"-"
    	if_z	serouta	#" "
    	if_z	jmp	@tx_str
    
    
    		cmp	x,#13		wz	'cr?
    	if_z	call	@tx_crlf
    	if_z	mov	y,#0
    
    	if_nz	serouta	x			'other?
    	if_nz	add	y,#1
    		jmp	@tx_str
                    ret
    '
    '
    ' Print hex (value)
    '
    tx_hex		mov	y,hsize			'pre-rotate to get 1st nibble in top
    		shl	y,#2
    		ror	value,y
    
    		mov	y,hsize			'print nibbles
    :loop		rol	value,#4
    		mov	x,value
    		call	@tx_nib
    		djnz	y,@:loop
    
    		ret
    '
    '
    ' Print nibble (x)
    '
    tx_nib		and	x,#$F			'isolate nibble
    
    			cmp	x,#$A		wc	'alpha or numeric?
    	if_c	add	x,#"0"			'numeric
    	if_nc	add	x,#"A"-$A		'alpha
    			serouta	x
    
    			ret
    '
    '
    ' Receive chr (x)
    '
    rx			call	@rx_check		'wait for rx chr
    	if_z	jmp	@rx
    
    		ret
    '
    '
    ' Check receiver, z=0 if chr (x)
    '
    rx_check	cmp	rx_head,rx_tail	wz
    
    	if_nz	rdauxr	x,rx_tail
    	if_nz	incmod	rx_tail,#$7F
    
    		ret
    
    
    '************************
    '* Serial Receiver Task *
    '************************
    
    rx_task		serina	rx_data			'wait for character
    
    			wrauxr	rx_data,rx_head		'store byte at head
    			incmod	rx_head,#$7F		'inc head
    			jmp	@rx_task		'wait for next byte
    
    
    '**********************
    '* Baud Detector Task *
    '**********************
    
    baud_task	notb	ctra,#8		wc	'if 1,0 sample set, c=0 (bit8 is not used by ctra)
    		notb	ctra,#5			'toggle state to measure ($20 -> 10000001001 -> 1, 6x 0, 1x 1, 2x 0, 1)
    		setctra	ctra			'ctra measures rx pin states
    
    	if_nc	mov	limh,buf0		'if 1,0 sample set,
    	if_nc	shr	limh,#4			'..make window from 1st 0 (6x if $20)
    	if_nc	neg	liml,limh
    	if_nc	add	limh,buf0
    	if_nc	add	liml,buf0
    
    	if_nc	mov	comp,buf1		'if 1,0 sample set,
    	if_nc	mul	comp,#6			'..normalize 2nd 1 (1x if $20) to 6x
    	if_nc	cmpr	comp,limh	wc	'..check if within window
    	if_nc	cmp	comp,liml	wc
    
    	if_nc	mov	comp,buf2		'if 1,0 sample set,
    	if_nc	mul	comp,#3			'..normalize 2nd 0 (2x if $20) to 6x
    	if_nc	cmpr	comp,limh	wc	'..check if within window
    	if_nc	cmp	comp,liml	wc
    
    	if_nc	add	buf0,buf2		'if $20,
    	if_nc	shr	buf0,#3			'..compute period from 6x 0 and 2x 0
    	if_nc	setsera	sera,buf0		'..(re)initializFe serial
    	if_nc	setb	base,#31		'..flag initial $20
    
    		mov	buf0,buf1		'scroll sample buffer
    		mov	buf1,buf2
    
    :wait		getcosa	buf2			'wait for next sample
    		jnz	buf2,@baud_task
    		jmp	@:wait
    
    
    '*************
    '* Variables *
    '*************
    
    reserves
    equal  byte "is equal",0
    equaladdr long @equal
    zval byte "z = ",0
    zvaladdr long @zval
    cval byte "c = ",0
    cvaladdr long @cval
    myhelloworld byte "        Hello World",0
    myhw_addr long @myhelloworld
    myhello byte "Hello again",0
    my_addr long @myhello
    tempptr long 0
    tempreps long 0
    decval  long 200
    bits   long 31
    mydiv   long 100
    ten    long 10
    myreps  long 10
    bignum  long 10000000
    mynum   long 12398990
    digsarray long 0,0,0,0,0,0,0,0,0
    digsarrayaddr long @digsarray
    tensarray long 1000000000,100000000,10000000,1000000,100000,10000,1000,100,10,1
    tensarrayaddr long @tensarray
    base		res	1			'main task
    w		res	1
    x		res	1
    y		res	1
    z		res	1
    v1		res	1
    v2		res	1
    value		res	1
    view		res	1
    enter		res	1
    pin		res	1
    dsize		res	1
    hsize		res	1
    wsize		res	1
    amask		res	1
    
    rx_data		res	1			'serial receiver task
    rx_head		res	1
    rx_tail		res	1
    
    ctra		res	1			'baud detector task
    sera		res	1
    buf0		res	1
    buf1		res	1
    buf2		res	1
    limh		res	1
    liml		res	1
    comp		res	1
    tester          res     1
    temp            res 	1
    divisor		res 1
    quotient    res 1
    remainder   res 1
    i               res 	1
    outval          res     1
    divval          res     1
    inval           res     1
    myquotient      res 	1
    mynumber        res     1
    mydivisor       res     1
    remainder     res     1
    q 				res		1
    gotfirst        res     1
    tempval         res     1
    tempval2        res     1
    multiplier      res     1
    multiple        res     1
    shift           res     1
    tempmul         res     1
    shiftval        res     1
    mymsb           res		1
    decvalue        res     1
    
  • ozpropdevozpropdev Posts: 2,792
    edited 2014-02-16 19:08
    Your using P1 directives in your code.
    Try inserting the following CLKSET instruction
    			clkset	#$FF			'set 80MHz
    
    

    Edit: Make sure you enable the tx_pin direction with a clrp #tx_pin as well.
  • mindrobotsmindrobots Posts: 6,506
    edited 2014-02-16 19:22
    Brian,

    I'd been looking at Chip's monitor code. That code looked a lot more complicated than the examples in the manual. I was trying to follow those. The monitor also has the ctra setup in there for the baud detect.

    I'll try the proper clk setup even though those lines are from p2 pfth and appear to work.

    Thanks!
  • Cluso99Cluso99 Posts: 18,069
    edited 2014-02-16 19:38
    Here is a piece of code I stripped out from a working version. Perhaps it might help (tx only).
    BTW Don't forget the DE0 only has CTRA now.
    CON
      _clkmode = xinput
      _xinfreq = 80_000_000
      _baud    = 115_200
      _bitrate = _xinfreq / _baud
      _txpin   = 90                                 ' P90=SO
      _rxpin   = 91                                 ' P91=SI
      _MON_START    = $006E4                        ' start address of rom monitor
      _MON_PARAM    = _rxpin << 9 | _txpin          ' monitor pins
      _LMM_org = $1000                              ' hub addr of the LMM routines
      
    DAT
                    orgh    $00E00                          ' start of hub ram
                    org     0
    start        
    'the following is a 5 sec delay mechanism only (allows PST to start)
                    getcnt  waitx
                    add     waitx,delta5
                    waitcnt waitx,0
                  SETSERA   #%10<<7 + _txpin, baud          'set SERA for 8-bit transmit on pin at baud
                  CLRP      #_txpin                         'make pin an output, SERA drives it high
                  SEROUTA   #"O"                            'send message
                  SEROUTA   #"K"
                  SEROUTA   #$0D
                  SEROUTA   #"*"
    .....
    
    
  • mindrobotsmindrobots Posts: 6,506
    edited 2014-02-16 20:12
    Aha! Making tx an output! I remember reading that now...just not doing it!

    I have a few changes to make!

    Thanks!
  • mindrobotsmindrobots Posts: 6,506
    edited 2014-02-16 20:41
    clrp #tx_pin did the trick!!!

    I added that to my code from the first post after the setsera and it started working!

    Amazing! Serial I/O with 4 instructions!!

    2 to set it up and 1 each for input and output. Pretty dang slick!!

    Thanks Chip!!

    Now it's time to move the stacks into AUXRAM.

    EDIT: 460,800 baud is pretty darn quick! I'd go faster but it's bedtime!
  • mindrobotsmindrobots Posts: 6,506
    edited 2014-02-18 03:20
    Wicked fast!

    I've been running my puTTY connection at 2Mbits since last night. That's stupid fast for terminal I/O but fun to see. I stopped at 2Mbits since I was starting to have trouble. I may have hit either a puTTY limit or a Win7 serial I/O limit (or I guess an FTDI limit) at that point.

    Now, it makes me want to have a second P2 core so the two can chatter back and forth. (by forth, I mean as in to and fro, not Forth....don't want to start any battles!! :lol: )
  • ozpropdevozpropdev Posts: 2,792
    edited 2014-02-18 03:42
    mindrobots wrote: »
    Wicked fast!

    I've been running my puTTY connection at 2Mbits since last night. That's stupid fast for terminal I/O but fun to see. I stopped at 2Mbits since I was starting to have trouble. I may have hit either a puTTY limit or a Win7 serial I/O limit (or I guess an FTDI limit) at that point.

    Now, it makes me want to have a second P2 core so the two can chatter back and forth. (by forth, I mean as in to and fro, not Forth....don't want to start any battles!! :lol: )

    IIRC I read somewhere on this forum of FTDI chips having problems over 1.5M baud.
  • cgraceycgracey Posts: 14,151
    edited 2014-02-18 04:09
    ozpropdev wrote: »
    IIRC I read somewhere on this forum of FTDI chips having problems over 1.5M baud.

    Yes, data gets lost. I've found that 1M baud is safe, so I use that.
  • jmgjmg Posts: 15,173
    edited 2014-02-18 15:58
    ozpropdev wrote: »
    IIRC I read somewhere on this forum of FTDI chips having problems over 1.5M baud.

    It depends on the device.
    The FT232H/2232H etc are better behaved at high Baud ( > 1M) speeds.

    Std speed parts start to add more stop bits in what they send, as the baud rates climb, so the data flow is lower than you might expect.
    Loopback tests seem to be ok, but of course, they are no longer true packed-data tests.

    The toughest test would be high baud rates, 1 stop bit, no extra gaps, aka continual data.
    Adding extra stop bits, would probably make it more reliable.

    Not sure if SerDes can do that in HW ?

    There is also a Fast Serial (sync) mode the FTDI HS parts support, that accepts a FSSCK to 50MBd
    It is a half-duplex state machine, and has a simple HW handshake, and 9 data bits.

    50MBd would be nice to have :)
Sign In or Register to comment.