Shop OBEX P1 Docs P2 Docs Learn Events
communicate between propeller chips on MUX bus — Parallax Forums

communicate between propeller chips on MUX bus

average joeaverage joe Posts: 795
edited 2013-01-27 10:32 in Propeller 1
*Edit*
Tried asynchronous serial and decided there may be better ways to do this. Post 3 will have Schematic and more info

Hey guys, looking for some advice on using full-duplex serial to communicate between 2 propeller chips. Here's the rundown. The first propeller *master* is a touchburger. The second *slave* is running SidSynth.

I have not decided on which serial object I will use on the master. The slave is using "pcFullDuplexSerial4FC" and is only using 2 ports at this point. I plan on enabling all 4, with 2 at 31250bps for midi I/Os. A third port will be running serial midi to computer *baud > 31250, likely at least twice* and fourth port would be used to talk to the master propeller.

I have the idea that I could use the programming port on the master, but I would really like to use the shared bus. A quick rundown of the shared bus is as follows: Pins 0-20 are data pins and used in "Groups". There are 4 groups that can be selected. Group select is Active Low.

Since the bus is shared, I can only transmit and receive when in group 3.

The CTS/RTS sounds like the key. I'm just unsure of a few things.

1: connection. CTS on master connected to RTS on slave, and CTS on slave connected to RTS on master?

2: I would need to OR CTS/RTS with the group select (active low) and set to inverted?

3: I would need to use OPEN DRAIN setting to prevent interference with the bus?

This will not work if full duplex serial follows the old, asymmetric spec. I'm hoping it uses the symmetric alternative, commonly called "RTS/CTS handshaking" mentioned by wikipedia.

" In this scheme, CTS is no longer a response to RTS; instead, CTS indicates permission from the DCE for the DTE to send data to the DCE, and RTS indicates permission from the DTE for the DCE to send data to the DTE. RTS and CTS are controlled by the DTE and DCE respectively, each independent of the other. This was eventually codified in version RS-232-E"

The only problems I see is the master will not release the RTS, and the CTS pin will interfere with bus opperation if using a push-pull OR gate. So maybe use a `244 tri-state buffer instead of a `32 OR. Use the group select or enable the buffer. Still use inverted since the master's pins already have pull-ups?

The master's RTS will still interfere with normal bus operation, unless I shut the serial cog down before changing out of group 3. I'd RATHER not do this, I'd like to leave the cog running at all times.
Maybe there is no way around this without modifying FullDuplex? Maybe there's a better object to run on the master. Perhaps have an open-drain setting for RTS?

Any thoughts or suggestions would be greatly appreciated!

Comments

  • Duane DegnDuane Degn Posts: 10,588
    edited 2012-10-19 21:49
    You'll probably want to use Tracy Allen's improved four port object. He fixed the flow control and a couple of other problems the original version had.
  • average joeaverage joe Posts: 795
    edited 2013-01-26 00:42
    I tried Tracy Allen's object and it worked but there were still some issues. Even after some work I lost a small but still unacceptable amount of data. I took a break and decided it would be a good idea to create a schematic to help explain the problem. This is a "condensed" schematic, containing the important blocks. I'm hoping the geniuses here can help me figure a better protocol for this bus than asynchronous serial. So what do you guys think?
  • cavelambcavelamb Posts: 720
    edited 2013-01-26 09:30
    Hey Joe,

    Sounds like an ambitious project, but schematic looks reasonable for what you have described.

    My gut reaction, like you said, would suspect how RTS/CTS hand shaking hooks up with the
    group 3 signal...

    To investigate I think I would try to set up a structured data set to send back and forth to see
    exactly what data is being lost where. Send binary 0 to F ( or more?) for instance. compare results.
    Might see a pattern in the tea leaves?

    Does your current physical circuit have more parts to it?
    If so, can it be reduced to match the schematic for development purposes?
  • kwinnkwinn Posts: 8,697
    edited 2013-01-26 11:19
    I tried Tracy Allen's object and it worked but there were still some issues. Even after some work I lost a small but still unacceptable amount of data. I took a break and decided it would be a good idea to create a schematic to help explain the problem. This is a "condensed" schematic, containing the important blocks. I'm hoping the geniuses here can help me figure a better protocol for this bus than asynchronous serial. So what do you guys think?

    It is not so much that Asynch Serial is unsuitable as that full duplex serial is unsuitable. For a shared bus to work there must be some way to for each micro on the bus to get control of it to send data. There are several ways to do this.

    A master/slave setup has one micro that controls the bus and slaves that respond to the master.

    Token passing involves passing a token that allows the micro that has the token to send on the bus.

    Carrier Sense Multiple Access / Collision Detection ( CSMA/CD as used by ethernet ). The CSMA part means each microcontroller listens to the bus and starts to send if it is quiet. The CD portion involves listening while it is sending to see if the data it is sending is the same as the data being read back. If it is not it means a collision has occurred and the micro stops sending for a random period of time before trying again.

    Master/Slave and Token Passing would be fairly easy to do with one of the serial objects.
  • average joeaverage joe Posts: 795
    edited 2013-01-26 11:28
    Thanks for the reply! My current circuit has many more parts. I'll upload schematics for the master and slave boards. The slave board does not match schematic, the pins used on the master are different. Also used the 74hc244 instead of resistors for the common connection point *data comms at the bottom of expansion schematic. I did not populate R23,R6 on flow control or R22 for GROUP3 *not GROUP_4*

    Large portions of the expansion board are unpopulated, although I am using MIDI and SD. Wiznet 812mj on expansion board P12..P8.
    The entire touchburger board is populated, although all chips have sockets.
    CON
    ' //////////////////////////////////////////////////////////////////////
    ' touchburger debugger program, simple serial to text on screen        /
    ' //////////////////////////////////////////////////////////////////////
    ' /                                                                    /
    ' //////////////////////////////////////////////////////////////////////
    ' /////          Clock settings                                    /////
         _clkmode   = xtal1 + pll16x       ' use crystal x 16              /
         _xinfreq   = 5_000_000            ' use 5MHZ crystal              /
    ' //////////////////////////////////////////////////////////////////////
    ' /                                                                    /
    ' /                                                                    /
    ' //////////////////////////////////////////////////////////////////////
    ExpRX     = 16
    ExpTX     = 19
    ExpCTS    = 18
    ExpRTS    = 17
    ExpMODE   = exp#OCTX
    EXP_BRATE = 115200
    
    DebugRx       = 31            'pin is TX, pin+1 is RX
    DebugTX       = 30
    DebugMODE     = 0
    Debug_BRATE   = 115200
    
    OBJ                                                                                                       *
       exp  :          "fullDuplexSerial4portJM"            
    
    PUB Ini  | ptr, font, p
     beginDesktop("S")                                           ' warmBoot
      font := Loadfont(string("Par16.ifn"))                 ' black on white 16 point, load and set font to file
      Clearscreen(BackFontColor)                            ' clear screen to BackFontColor = font file loaded above
      curx := 0                                             ' return Cursor to X 0
      cury := 0                                             ' return Cursor to Y 0
    
      repeat                                                ' loop
        exp.init                                            ' init serial driver
        exp.AddPort(0,ExpRX,ExpTX,ExpCTS,ExpRTS,EXP#DefaultThreshold,ExpMODE,EXP_BRATE)  ' create expansion port
        SelectSPIGroup                                      ' Change to group3 for transfers
        exp.start                                           ' start serial driver
        ptr := 0                                            ' zero pointer
        pause1ms(50)                                        ' ?wait? for buffer to fill?
        exp.Stop                                            ' stop expander port
        repeat while ((p:=exp.rxcheck(0)) <> -1)            ' empty serial buffer
    
          if 31 < p < 126                                   ' check for printable character
            byte[@sdbuffer][ptr++] := p                     ' and copy into sdbuffer
        IF ptr > 0                                          ' if captured character
          byte[@sdbuffer][ptr] := 0                         ' zero terminate string
          TextT(font,@sdbuffer)                             ' and print message on display
    
    
    PUB SelectMemGroup                                      ' select group 2 for memory transfer
       spi.stop                                             ' and stop any other cogs here too if needed
       DIRA |= %00000000_00011111_11111111_11111111         ' enable these pins for output
       OUTA |= %00000000_00011111_00000000_00000000         ' set /rd /wr /disp wr and 161 clock high
       LatchGroup2
       
    PUB SelectSPIGroup
       DIRA &= %00000000_00000000_00000000_00000000         ' so no clashes with the cogs using P0-P2 set these as inputs and P3-P5, and expansion pins
       LatchGroup3                                          ' select group 3 for spi transfers
       TouchStart                                           ' start the touchscreen cog   
    

    The only changes to FDX are
      TX_SIZE0                      = 64   ' enter in the needed size in bytes for each rx and tx buffer
      TX_SIZE1                      = 64    ' these values can be any size within available memory.
      TX_SIZE2                      = 0   ' They do not have to be a power of two.
      TX_SIZE3                      = 0   '
    
      RX_SIZE0                      = 128
      RX_SIZE1                      = 128
      RX_SIZE2                      = 0
      RX_SIZE3                      = 0
    

    For code on the slave side, I've just replaced the serial debug with
    CON
    ExpRX     = uart#PINNOTUSED
    ExpTX     = 5
    ExpCTS    = 4
    ExpRTS    = 3
    ExpMODE   = 0
    EXP_BRATE = 115200
    ...
      uart.init
      uart.AddPort(1,ExpRX,ExpTX,ExpCTS,ExpRTS,uart#DEFAULTTHRESHOLD,ExpMODE,EXP_BRATE)
      uart.Start
    ....
    
    I've tried plugging this into several existing objects on the slave side and they work but there is occasional character corruption. And it seems to end up happening in the same place, although I didn't get a really good "look" at it when debugging.
    1024 x 768 - 91K
    1024 x 768 - 116K
    1024 x 1365 - 231K
  • kwinnkwinn Posts: 8,697
    edited 2013-01-26 12:40
    I think I may have misinterpreted your first post. After looking at your schematic and re-reading it I have a couple of questions.

    Can you add the names of the signals going through the '244 between the two props? I am guessing they are Rx, Tx, RTS, and CTS but it would help to be sure.

    Are both props on the same pcb?

    How much data are you sending at any one time?

    One problem I can foresee with using any of the serial objects on a bus is that the receive portion of the PASM program is always looking at the Rx pin and buffering anything it thinks is serial data. When another part of your software is using P0-P7 to read or write data the PASM portion of "pcFullDuplexSerial4FC" will also be running in its own cog and interpreting that data as serial input.

    The simplest solution is to use 2 dedicated pins for Rx and Tx to communicate between the cogs with software flow control.

    The alternative is to write a communication program that transfers data back and forth 4 bits at a time.
  • average joeaverage joe Posts: 795
    edited 2013-01-26 22:13
    kwinn wrote: »

    The alternative is to write a communication program that transfers data back and forth 4 bits at a time.

    I've been thinking about that and it's a distinct possibility. I'd really like to do 8 bits at a time, perhaps replace the `244 with a `245? I thought serial would be the easy way to go but I was wrong.

    RE: "One problem I can foresee with using any of the serial objects on a bus is that the receive portion of the PASM program is always looking at the Rx pin and buffering anything it thinks is serial data."

    This actually seems to be the easy part, since the expansion is disconnected from the touchburger when not in GROUP_3. On the master side, the serial cog has to be shut down for several reasons. The biggest problem comes from using hardware flow control. /RTS line is always driven and would interfere with proper operation of the other GROUPs. The other major reason is Rx buffering as you mentioned.

    RE: The simplest solution is to use 2 dedicated pins for Rx and Tx to communicate between the cogs with software flow control.

    I agree that this would be the easiest, problem is the only pins left over on the touchburger that could be considered dedicated pins are the programming pins and eeprom pins... Maybe something to ponder though.

    Now the other questions. As far as how much data is being sent, that involves a number of factors. I'm testing this as simple debugger right now since it's easy. In the future, I would like this bus to transfer quite a bit of data. Perhaps copying files from SD on master to SD on slave. Maybe from Wiznet on slave to SD on master, etc.

    The props are on separate boards, connected with a short 34 pin ribbon cable.

    You are correct on the usage of pins, I'll try to name the signals shortly.

    Thanks for both your posts, I was typing my last one when you posted and didn't have a chance to reply before work.

    I thought asyn. serial would be the easiest way to make this work, but I was obviously wrong. I keep thinking SPI or perhaps parallel would work better. Input greatly appreciated!
  • kwinnkwinn Posts: 8,697
    edited 2013-01-27 00:38
    For 8 bit transfers take a look at the '245 tristate transceiver. Gives you 8 bit bidirectional capability.

    Even if everything else is kept off the bus when in group3 the cog running the serial code will still be looking at the data on that pin when the other groups are active and storing that in the buffer.
  • kwinnkwinn Posts: 8,697
    edited 2013-01-27 00:40
    OK, time to get some shuteye. I see you were already mentioning it in your post and I missed it.
  • average joeaverage joe Posts: 795
    edited 2013-01-27 01:13
    I might try to implement parallel in the future, but it seems the serial connection is working now! If I use all 8 pins, I can have 2 ports running @ 115,200!!! * I hope* Need to further test the reliability of the connection. It was faulty to the naked eye, but seems fine now!

    I've run several test programs on the expansion, can't see corruption. Maybe try dumping a file from 1 SD card, across the bus, to the other SD card, then BACK ACROSS the bus and compare against original?
    CON
    ' //////////////////////////////////////////////////////////////////////
    ' touchburger debugger program, simple serial to text on screen        /
    ' //////////////////////////////////////////////////////////////////////
    ' /                                                                    /
    ' //////////////////////////////////////////////////////////////////////
    ' /////          Clock settings                                    /////
         _clkmode   = xtal1 + pll16x       ' use crystal x 16              /
         _xinfreq   = 5_000_000            ' use 5MHZ crystal              /
    ' //////////////////////////////////////////////////////////////////////
    ' /                                                                    /
    '               expansion pin config, slave currently 1 way.
    ' /                                                                    /
    ' //////////////////////////////////////////////////////////////////////
      ExpRX     = 16
      ExpTX     = 19
      ExpCTS    = 14
      ExpRTS    = 15
      ExpMODE   = exp#OCTX
      EXP_BRATE = 115200
    ' //////////////////////////////////////////////////////////////////////
    ' 
    VAR     byte          buffer[512]
    
    'dat  default_font byte   "Par16.ifn",0        ' default font
    dat  default_font byte   "4x6.ifn",0        ' default font
    
    OBJ     tch  : "Touch3"
            exp  : "fullDuplexSerial4portJM"             ' 4 port serial driver with 
    PUB Ini  | ptr, font, p
      tch.beginDesktop("S")                                 ' warmBoot
      font := tch.Loadfont(@default_font)                   ' black on white 16 point, load and set font to file
      tch.Clearscreen(tch.GetBackFontColor)                 ' clear screen to BackFontColor = font file loaded above
      tch.SetCursor(0,0)                                    ' re-set cursor
      repeat                                                ' *Start of loop*
        exp.init                                            ' init serial driver
        exp.AddPort(0,ExpRX,ExpTX,ExpCTS,ExpRTS,{           ' create expansion port
          }EXP#DefaultThreshold,ExpMODE,EXP_BRATE)            
        tch.SelectSPIGroup                                  ' Change to group3 for transfers
        exp.start                                           ' start serial driver
        ptr := 0                                            ' zero pointer
        tch.pause1ms(50)                                    ' ?wait? for buffer to fill?
        exp.Stop                                            ' stop expander port
        repeat while ((p:=exp.rxcheck(0)) <> -1)            ' empty serial buffer
          if 31 < p < 126                                   ' check for printable character
            byte[@buffer][ptr++] := p                       ' and copy into sdbuffer
        IF ptr > 0                                          ' if captured character
          byte[@buffer][ptr] := 0                           ' zero terminate string
          tch.TextT(font,@buffer)                           ' and print message on display
    

    Kwinn - thanks for your input! Post #9 leads me to believe I'm on track! Time for some shut eye for me as well!
  • kwinnkwinn Posts: 8,697
    edited 2013-01-27 10:32
    .............

    I've run several test programs on the expansion, can't see corruption. Maybe try dumping a file from 1 SD card, across the bus, to the other SD card, then BACK ACROSS the bus and compare against original?

    !

    Sounds like a good plan.

    If you do find some corruption you might try sending the data in packets with a specific pattern of bytes at the beginning and end, or a checksum at the end.
Sign In or Register to comment.