Shop OBEX P1 Docs P2 Docs Learn Events
delay problem with multilpe serial port using pcFullDuplexSerial4FC solved — Parallax Forums

delay problem with multilpe serial port using pcFullDuplexSerial4FC solved

Julian800Julian800 Posts: 31
edited 2010-06-29 23:43 in Propeller 1
I am planning a project send ASIC· data stream· to multiple device ‘s RS422/RS485 port.· I know there is a multilpe serial port drive from Tim Moore in the OBEX.··· Can I use that one with some chip to do multiple· RS422/RS485· ?·

I know nothing about serial communications, etc. so I need to take this on one baby step at a time. Any suggestions will be greatly appreciated.

Thanks

Post Edited (pussycat) : 6/29/2010 11:46:24 PM GMT

Comments

  • JonnyMacJonnyMac Posts: 9,208
    edited 2010-06-23 01:08
    You should contact that programmer for specific guidance. I've used two instances of FullDuplexSerial in a project; one for RS-485 comms and another for Propeller-to-PC comms. If you're not short of cogs this may be a cleaner solution.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon McPhalen
    Hollywood, CA
  • T ChapT Chap Posts: 4,223
    edited 2010-06-23 01:56
    I use one port of the 4port with RS485, no reason you couldn't do up to 4 RS485 ports with it. The only trick is you have to have control the enable pins as needed, and they require a short delay time to change states before sending the data over RS485.
  • Julian800Julian800 Posts: 31
    edited 2010-06-29 01:21
    thanks for your help Jon and Todd. I get code running. But there is 200 ns delay for send each of byte in pcFullDuplexSerial4FC. that don't happen in FullDuplexSerial. Anyone know the delay of pcFullDuplexSerial4FC?·

    what i need to do is only sending data on 2 serial under 2ms by using
    I also try to find the delay by my self.·I delete all sending code and serial 2 and serial 3. But there is still 500 microsecond delay between send of serial 1 and serial 2, also delay 100 microsecond delay of each byte.



    entry
    'rxcode· if_never······· mov···· rxcode,#receive······ 'statically set these variables
    txcode· if_never······· mov···· txcode,#transmit
    'rxcode1 if_never······· mov···· rxcode1,#receive1
    txcode1 if_never······· mov···· txcode1,#transmit1
    'rxcode2 if_never······· mov···· rxcode2,#receive2
    'txcode2 if_never······· mov···· txcode2,#transmit2
    'rxcode3 if_never······· mov···· rxcode3,#receive3
    'txcode3 if_never······· mov···· txcode3,#transmit3
    ·······················
    ······
    'port 1
    ······················· test··· rxtx_mode1,#OCTX wz·· 'init tx pin according to mode
    ······················· test··· rxtx_mode1,#INVERTTX wc
    ······· if_z_ne_c······ or····· outa,txmask1
    ······· if_z··········· or····· dira,txmask1
    ······· if_z_eq_c······ or····· txout1,domuxnc······· 'patch muxc to muxnc
    ······· if_nz·········· movd··· txout1,#dira········· 'change destination from outa to dira
    ······················· test··· rxtx_mode1,#INVERTRX wz 'wait for start bit on rx pin
    ······ ' if_nz·········· xor···· start1,doifc2ifnc···· 'if_c jmp to if_nc
    ······················· or····· ctsmask1,#0···· wz
    ······· if_nz·········· test··· rxtx_mode1,#INVERTCTS wc
    ······· if_nz_and_nc··· or····· ctsi1,doif_z_or_nc··· 'if_nc jmp
    ······· if_nz_and_c···· or····· ctsi1,doif_z_or_c···· 'if_c jmp
    ······· if_z··········· mov···· txcts1,transmit1····· 'copy the jmpret over the cts test
    ······· if_z··········· movs··· ctsi1,#txcts1········ 'patch the jmps to transmit to txcts0·
    ······· if_z··········· add···· txcode1,#1··········· 'change co-routine entry to skip first jmpret
    ····················································· 'patch rx routine depending on whether rts is used
    ····················································· 'and if it is inverted
    ······················· or····· rtsmask1,#0···· wz
    ······· if_nz·········· test··· rxtx_mode1,#INVERTRTS wc
    ····· '· if_nz_and_nc··· or····· rts1,domuxnc········· 'patch muxc to muxnc
    ··· '··· if_z··········· mov···· norts1,rec1i········· 'patch to a jmp #receive1
    ····· '· if_z··········· movs··· start1,#receive1····· 'skip all rts processing·················
    ······················· or····· txmask1,#0····· wz
    '······· if_z··········· mov···· txcode1,rxcode2······ 'use variable in case it has been changed
    ······················· or····· rxmask1,#0····· wz
    '······· if_z··········· mov···· rxcode1,txcode1······ 'use variable in case it has been changed
    'port 0
    ······················· test··· rxtx_mode,#OCTX wz··· 'init tx pin according to mode
    ······················· test··· rxtx_mode,#INVERTTX wc
    ······· if_z_ne_c······ or····· outa,txmask
    ······· if_z··········· or····· dira,txmask
    ····················································· 'patch tx routine depending on invert and oc
    ····················································· 'if invert change muxc to muxnc
    ····················································· 'if oc change out1 to dira
    ······· if_z_eq_c······ or····· txout0,domuxnc······· 'patch muxc to muxnc
    ······· if_nz·········· movd··· txout0,#dira········· 'change destination from outa to dira
    ····················································· 'patch rx wait for start bit depending on invert
    ······················· test··· rxtx_mode,#INVERTRX wz· 'wait for start bit on rx pin
    ······ ' if_nz·········· xor···· start0,doifc2ifnc···· 'if_c jmp to if_nc
    ····················································· 'patch tx routine depending on whether cts is used
    ····················································· 'and if it is inverted
    ······················· or····· ctsmask,#0···· wz···· 'cts pin? z not set if in use
    ······· if_nz·········· test··· rxtx_mode,#INVERTCTS wc 'c set if inverted
    ······· if_nz_and_nc··· or····· ctsi0,doif_z_or_nc··· 'if_nc jmp
    ······· if_nz_and_c···· or····· ctsi0,doif_z_or_c···· 'if_c jmp
    ······· if_z··········· mov···· txcts0,transmit······ 'copy the jmpret over the cts test
    ······· if_z··········· movs··· ctsi0,#txcts0········ 'patch the jmps to transmit to txcts0·
    ······· if_z··········· add···· txcode,#1············ 'change co-routine entry to skip first jmpret
    ····················································· 'patch rx routine depending on whether rts is used
    ····················································· 'and if it is inverted
    ······················· or····· rtsmask,#0···· wz···· 'rts pin, z not set if in use
    ······· if_nz·········· test··· rxtx_mode,#INVERTRTS wc
    ··· '··· if_nz_and_nc··· or····· rts0,domuxnc········· 'patch muxc to muxnc
    ···· '·· if_z··········· mov···· norts0,rec0i········· 'patch to a jmp #receive
    ···· '·· if_z··········· movs··· start0,#receive······ 'skip all rts processing if not used
    ····················································· 'patch all of tx routine out if not used·················
    ······················· or····· txmask,#0······ wz
    '······· if_z··········· mov···· txcode,rxcode1······· 'use variable in case it has been changed
    ····················································· 'patch all of rx routine out if not used·················
    ······················· or····· rxmask,#0······ wz
    '······· if_z··········· mov···· rxcode,txcode········ 'use variable in case it has been changed
    '
    '
    ' Transmit
    '
    transmit··············· jmpret· txcode,txcode1······· 'run a chunk of receive code, then return
    ····················································· 'patched to a jmp if pin not used·······················
    ·······················
    txcts0················· test··· ctsmask,ina···· wc··· 'if flow-controlled dont send
    ······················· rdlong· t1,tx_head_ptr······· '{7-22} - head[noparse][[/noparse]0]
    ······················· cmp···· t1,tx_tail····· wz··· 'tail[noparse][[/noparse]0]
    ctsi0·· if_z··········· jmp···· #transmit············ 'may be patched to if_z_or_c or if_z_or_nc
    ······················· rdbyte· txdata,txbuff_tail_ptr '{8}
    ······················· add···· tx_tail,#1
    ······················· and···· tx_tail,#$0F··· wz
    ······················· wrlong· tx_tail,tx_tail_ptr··· '{8}·
    ······· if_z··········· mov···· txbuff_tail_ptr,txbuff_ptr 'reset tail_ptr if we wrapped
    ······· if_nz·········· add···· txbuff_tail_ptr,#1··· 'otherwise add 1
    ·······················
    ······················ ' jmpret· txcode,rxcode1
    ······················· shl···· txdata,#2
    ······················· or····· txdata,txbitor······· 'ready byte to transmit
    ······················· mov···· txbits,#11
    ······················· mov···· txcnt,cnt
    txbit·················· shr···· txdata,#1······ wc
    txout0················· muxc··· outa,txmask·········· 'maybe patched to muxnc dira,txmask
    ······················· add···· txcnt,bit_ticks······ 'ready next cnt
    :wait················· ' jmpret· txcode,rxcode1······· 'run a chunk of receive code, then return
    ······················· mov···· t1,txcnt············· 'check if bit transmit period done
    ······················· sub···· t1,cnt
    ······················· cmps··· t1,#0·········· wc
    ······· if_nc·········· jmp···· #:wait
    ······················· djnz··· txbits,#txbit········ 'another bit to transmit?
    txjmp0················· jmp···· ctsi0················ 'byte done, transmit next byte
    ························ jmp···· #transmit
    '
    ' Transmit1
    '
    transmit1·············· jmpret· txcode1,txcode······ 'run a chunk of receive code, then return
    ·······················
    txcts1················· test··· ctsmask1,ina··· wc··· 'if flow-controlled dont send
    ······················· rdlong· t1,tx_head_ptr1
    ······················· cmp···· t1,tx_tail1···· wz
    ctsi1·· if_z··········· jmp···· #transmit1··········· 'may be patched to if_z_or_c or if_z_or_nc
    ······················· rdbyte· txdata1,txbuff_tail_ptr1
    ······················· add···· tx_tail1,#1
    ······················· and···· tx_tail1,#$0F·· wz
    ······················· wrlong· tx_tail1,tx_tail_ptr1
    ······· if_z··········· mov···· txbuff_tail_ptr1,txbuff_ptr1 'reset tail_ptr if we wrapped
    ······· if_nz·········· add···· txbuff_tail_ptr1,#1·· 'otherwise add 1
    ····················· '· jmpret· txcode1,rxcode2······ 'run a chunk of receive code, then return
    ·······················
    ······················· shl···· txdata1,#2
    ······················· or····· txdata1,txbitor······ 'ready byte to transmit
    ······················· mov···· txbits1,#11
    ······················· mov···· txcnt1,cnt
    txbit1················· shr···· txdata1,#1····· wc
    txout1················· muxc··· outa,txmask1········· 'maybe patched to muxnc dira,txmask
    ······················· add···· txcnt1,bit_ticks1···· 'ready next cnt
    :wait1··············· '· jmpret· txcode1,rxcode2······ 'run a chunk of receive code, then return
    ······················· mov···· t1,txcnt1············ 'check if bit transmit period done
    ······················· sub···· t1,cnt
    ······················· cmps··· t1,#0·········· wc
    ······· if_nc·········· jmp···· #:wait1
    ······················· djnz··· txbits1,#txbit1······ 'another bit to transmit?
    txjmp1················· jmp···· ctsi1················ 'byte done, transmit next byte
    ······················· jmp···· #transmit1
    '
    '
    'These are used by SPIN and assembler, using DAT rather than VAR
    'so all COGs share this instance of the object
    '
    startfill
    · cog·················· long····· 0·················· 'cog flag/id
    · 'Dont Change the order of any of these initialized variables without modifying
    · 'the code to match - both spin and assembler
    · 'Dont make any of the initialized variables, uninitialized, only the initialized
    · 'variables are duplicated in hub memory
    · rx_head·············· long····· 0·················· '16 longs for circular buffer head/tails
    · rx_head1············· long····· 0··························
    · rx_head2············· long····· 0
    · rx_head3············· long····· 0
    · rx_tail·············· long····· 0
    · rx_tail1············· long····· 0
    · rx_tail2············· long····· 0
    · rx_tail3············· long····· 0
    · tx_head·············· long····· 0
    · tx_head1············· long····· 0
    · tx_head2············· long····· 0
    · tx_head3············· long····· 0
    · tx_tail·············· long····· 0
    · tx_tail1············· long····· 0
    · tx_tail2············· long····· 0
    · tx_tail3············· long····· 0
    · 'This set of variables were initialized to the correct values in Spin and loaded into this cog
    · 'when it started
    · rxmask··············· long····· 0·················· '33 longs for per port info
    · rxmask1·············· long····· 0
    · rxmask2·············· long····· 0
    · rxmask3·············· long····· 0
    · txmask··············· long····· 0
    · txmask1·············· long····· 0
    · txmask2·············· long····· 0
    · txmask3·············· long····· 0
    · ctsmask·············· long····· 0
    · ctsmask1············· long····· 0
    · ctsmask2············· long····· 0
    · ctsmask3············· long····· 0
    · rtsmask·············· long····· 0
    · rtsmask1············· long····· 0
    · rtsmask2············· long····· 0
    · rtsmask3············· long····· 0
    · rxtx_mode············ long····· 0
    · rxtx_mode1··········· long····· 0
    · rxtx_mode2··········· long····· 0
    · rxtx_mode3··········· long····· 0
    · bit4_ticks··········· long····· 0
    · bit4_ticks1·········· long····· 0
    · bit4_ticks2·········· long····· 0
    · bit4_ticks3·········· long····· 0
    · bit_ticks············ long····· 0
    · bit_ticks1··········· long····· 0
    · bit_ticks2··········· long····· 0
    · bit_ticks3··········· long····· 0
    · rtssize·············· long····· 0
    · rtssize1············· long····· 0
    · rtssize2············· long····· 0
    · rtssize3············· long····· 0
    · rxchar··············· byte····· 0
    · rxchar1·············· byte····· 0
    · rxchar2·············· byte····· 0
    · rxchar3·············· byte····· 0
    ·
    · 'This set of variables were initialized to the correct values in Spin and loaded into this cog
    · 'when it started. They contain the hub memory address of the rx/txbuffers
    · rxbuff_ptr··········· long····· 0·················· '32 longs for per port buffer hub ptr
    · rxbuff_ptr1·········· long····· 0
    · rxbuff_ptr2·········· long····· 0
    · rxbuff_ptr3·········· long····· 0
    · txbuff_ptr··········· long····· 0
    · txbuff_ptr1·········· long····· 0
    · txbuff_ptr2·········· long····· 0
    · txbuff_ptr3·········· long····· 0
    · rxbuff_head_ptr······ long····· 0
    · rxbuff_head_ptr1····· long····· 0
    · rxbuff_head_ptr2····· long····· 0
    · rxbuff_head_ptr3····· long····· 0
    · txbuff_tail_ptr······ long····· 0
    · txbuff_tail_ptr1····· long····· 0
    · txbuff_tail_ptr2····· long····· 0
    · txbuff_tail_ptr3····· long····· 0
    · rx_head_ptr·········· long····· 0
    · rx_head_ptr1········· long····· 0
    · rx_head_ptr2········· long····· 0
    · rx_head_ptr3········· long····· 0
    · rx_tail_ptr·········· long····· 0
    · rx_tail_ptr1········· long····· 0
    · rx_tail_ptr2········· long····· 0
    · rx_tail_ptr3········· long····· 0
    · tx_head_ptr·········· long····· 0
    · tx_head_ptr1········· long····· 0
    · tx_head_ptr2········· long····· 0
    · tx_head_ptr3········· long····· 0
    · tx_tail_ptr·········· long····· 0
    · tx_tail_ptr1········· long····· 0
    · tx_tail_ptr2········· long····· 0
    · tx_tail_ptr3········· long····· 0
    endfill······ 'used to calculate size of variables for longfill with 0
    '
    'note we are overlaying cog variables on top of these hub arrays, we need the space
    '
    · rx_buffer·········································· 'overlay rx variables over rxbuffer
    · rxdata··············· long····· 0·················· 'transmit and receive buffers
    · rxbits··············· long····· 0
    · rxcnt················ long····· 0
    · rxdata1·············· long····· 0
    · rxbits1·············· long····· 0
    · rxcnt1··············· long····· 0
    · rxdata2·············· long····· 0
    · rxbits2·············· long····· 0
    · rxcnt2··············· long····· 0
    · rxdata3·············· long····· 0
    · rxbits3·············· long····· 0
    · rxcnt3··············· long····· 0
    · t1··················· long····· 0
    ······················· long····· 0
    ······················· long····· 0
    ······················· long····· 0
    · rx_buffer1··········· long····· 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
    · rx_buffer2··········· long····· 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
    · rx_buffer3··········· long····· 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
    · tx_buffer·········································· 'overlay tx variables over txbuffer
    · txdata··············· long····· 0
    · txbits··············· long····· 0
    · txcnt················ long····· 0
    · txdata1·············· long····· 0
    · tx_buffer1········································· 'overlay tx variables over txbuffer
    · txbits1·············· long····· 0
    · txcnt1··············· long····· 0
    · txdata2·············· long····· 0
    · txbits2·············· long····· 0
    · tx_buffer2········································· 'overlay tx variables over txbuffer
    · txcnt2··············· long····· 0
    · txdata3·············· long····· 0
    · txbits3·············· long····· 0
    · txcnt3··············· long····· 0
    ····················································· 'overlay tx variables over txbuffer
    · tx_buffer3··········· long····· 0
    ······················· long····· 0
    ······················· long····· 0
    ······················· long····· 0
    'values to patch the code
    · doifc2ifnc··········· long····· $003c0000·········· 'patch condition if_c to if_nc using xor
    · doif_z_or_c·········· long····· $00380000·········· 'patch condition if_z to if_z_or_c using or
    · doif_z_or_nc········· long····· $002c0000·········· 'patch condition if_z to if_z_or_nc using or
    · domuxnc·············· long····· $04000000·········· 'patch muxc to muxnc using or
    '
    · txbitor·············· long····· $0401·············· 'bits to or for transmitting
    'If you want multiple copys of this driver in a project, then copy the file to multiple files and change
    'version in each to be unique
    · version·············· long····· 1
    '
    ······· FIT

    Post Edited (pussycat) : 6/29/2010 5:46:06 AM GMT
  • Cluso99Cluso99 Posts: 18,069
    edited 2010-06-29 04:00
    pussycat: You need to post your code using the "Post Reply" and use the code icon. This preserves indentation. Otherwise, post your cade as a file.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Links to other interesting threads:

    · Home of the MultiBladeProps: TriBlade,·RamBlade,·SixBlade, website
    · Single Board Computer:·3 Propeller ICs·and a·TriBladeProp board (ZiCog Z80 Emulator)
    · Prop Tools under Development or Completed (Index)
    · Emulators: CPUs Z80 etc; Micros Altair etc;· Terminals·VT100 etc; (Index) ZiCog (Z80) , MoCog (6809)·
    · Prop OS: SphinxOS·, PropDos , PropCmd··· Search the Propeller forums·(uses advanced Google search)
    My cruising website is: ·www.bluemagic.biz·· MultiBlade Props: www.cluso.bluemagic.biz
  • kuronekokuroneko Posts: 3,623
    edited 2010-06-29 04:21
    pussycat said...
    what i need to do is only sending data on 2 serial under 2ms by using
    2ms and 200ns seem worlds apart. Why are you so concerned about 200ns? At 80MHz that's only 16 cycles (4 instructions or one hub access window).
  • Julian800Julian800 Posts: 31
    edited 2010-06-29 05:49
    Cluso99 thanks for the suggeston.
    kuroneko I made a mistake about the time that is microsecond. I just find out that delay is not in assembly. it is pub decl () function call tx() for each number position(100microsecond delay between).·· I want to rewrite decl () function ( create ascii and then send str).
    (PUB decl(port,value,digits,flag) | i         'orginal decl code
      digits := 1 #> digits <# 10
      if value < 0
        -value
        tx(port,"-")
      i := 1_000_000_000
      if flag & 3
        if digits < 10                                      ' less than 10 digits?
          repeat (10 - digits)                              '   yes, adjust divisor
            i /= 10
      repeat digits
        if value => i
          tx(port,value / i + "0")
          value //= i
          result~~
        elseif (i == 1) OR result OR (flag & 2)
          tx(port,"0")       ' here is the delay
        elseif flag & 1
          tx(port," ")
        i /= 10)
    

    I send fix fixed-width 5 decimal place value. I changed code as following. but I have difficult to code· (create ascii and then send str) part.· where should I declare(in DAT or VAR ) that str?· and how to reference in SPIN··
    (PUB declc(port,value) | i ,flag ,digits
      digits:=5
      flag:=1
      i := 10_000
      
      repeat digits
        if value => i
          tx(port,value / i + "0")
          value //= i
          result~~
        elseif (i == 1) OR result OR (flag & 2)
          tx(port,"0")                
        elseif flag & 1
          tx(port," ")
        i /= 10)
    

    Post Edited (pussycat) : 6/29/2010 6:12:46 AM GMT
  • TimmooreTimmoore Posts: 1,031
    edited 2010-06-29 06:17
    In obex there is an object called obex_format.spin, it has a routine itoa that converted an integer to a string in a byte array. Take a look at that, it should be easy o use that routine for what you want.
  • Julian800Julian800 Posts: 31
    edited 2010-06-29 23:43
    Hi Timmoore,
    thanks for your help. the format is real good example.
Sign In or Register to comment.