SOLVED: Setting up SERIN/OUT (Serial Transceivers)

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.
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!!
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
'******************************************************** '* * '* 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
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.
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!
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 #"*" .....
I have a few changes to make!
Thanks!
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!
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!!
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.
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