Shop OBEX P1 Docs P2 Docs Learn Events
Using Multiple FDS problems — Parallax Forums

Using Multiple FDS problems

T ChapT Chap Posts: 4,223
edited 2010-11-28 16:28 in Propeller 1
I have a test program to communicate with a Wifly radio device. The Prop sends and receives from the device. They need to be able to talk over each other without waiting. I have connected two pins for Rx and Tx to the device, and can communicate with it (pins 2 and 5). I am using a repeat loop that takes the responses from the device and sends them straight out of the Prop back to a computer on the standard Tx p30. The Prop will ultimately use some of the responses, but I need to monitor the output as well on the GUI for now. The GUI needs to also talk back and forth to the Prop, and is connected with the FT232RL to the programming pins 30/31.

As soon as I turn on the second copy(real duplicate) of FullDuplexSerial, things get weird. Without the second instance, I can send a string containing an Opcode from the GUI to the Prop, it determines what the Opcode is and sends a command to the radio device. This works fine but when I put in the second instance, all of a sudden the first instance of the serial object no longer 'waits' at the ser.rx command, it just blows past it and the loop never stops. I tried all modes for that instance. In mode 0 is where it never waits. Other modes it will wait, but then the GUI cannot talk to it anymore, however the Prop will forward the responses from the radio out as they are received. Even when unplugging the USB cable it still repeats non stop as if it is getting a byte from the GUI, but it isn't. Mode 3 will cause it to wait but the GUI stops sending to the Prop.

Any suggestions would be appreciated on how to solve this.
OBJ

  'pst    : "Parallax Serial Terminal"                   ' Serial communication object
  ser    : "FullDuplexSerial"
  ser2    : "FullDuplexSerial2"
VAR
   LONG  SerialStack[64]
   BYTE  ResponseArray1[64], buffer, pingbuffer[16], chksum, voll


PUB Start | value, i
  voll := 11
  dira[23] := 1
  dira[19] := 1
  SetBuzzVol(800_000_000)
  i := 0
  'ser.start(5, 2, 0, 9600)    'start(rxpin, txpin, mode, baudrate)
  ser.start(31, 2, 0, 9600)  '//  Prop Rx pin from GUI   TX Pin goes to WiFly Rx input
  '//  MODE 3 above will cause the repeat to wait on ser.rx  MODE 0 does not wait, repeats
  cognew(ReadWifi, @SerialSTack)
  ReadGUIinput

PUB ReadGUIinput    | ii, val     'pingbuffer
   repeat
     beep(19, 3000, 400)
     ser.rxflush
     pingbuffer[0] := ser.rx  'time(2)  'waits here for first byte  ***********NEVER WAITS************
     ii := 1
     Repeat 3                    'look for more, else return
       Val :=  ser.rxtime(2)   'read more, port 0, wait only 2 ms if no byte found
       If val == -1
         Return
       pingbuffer[ii] := Val
       ii := ii + 1
     'beep(19, 1000, 200)
     W(2_000_000)
     If pingbuffer[0] == $1F   'check for a start byte
        'beep(19, 2000, 400)
        chksum := pingbuffer[0] + pingbuffer[1] + pingbuffer[2]  'add first 3 bytes
        !chksum    'NOT   invert bits
        if chksum == pingbuffer[3]      'test incoming chksum to see if correct
           chksum :=  $1F + $01 + $FF  '1F + LEN + ACK   create response chksum
           !chksum'invert the checksum
           'beep(19, 2000, 200)
           'w(1_000_000) 'allow time for flow control to flip
           'now send back the response
           'ser.str(string($1F, $0A, $FF, $62, $65, $6C, $6C, $5F, $76, $30, $30, $31, $D2 ))
           'w(2_000_000)  'allowtime for string to send before resetting flow to off
           'beep(19, 3000, 400)
           'w(10000000)
           'beep(19, 3000, 400)
           DoCommands

PUB ReadWifi
  ser2.start(5, 30, 0, 9600)    '//  Wifly communication setup.   start(rxpin, txpin, mode, baudrate)
  '//  P5 is the Rx on the Prop from the radio    P30 sends back the radio data to the GUI
  repeat
    buffer := ser2.rx  '//  get anything that comes in from Wifly
    ser2.str(@buffer)  '//  foward all wifi responses back to the GUI app

Comments

  • kwinnkwinn Posts: 8,697
    edited 2010-11-28 08:47
    I don't have my protoboard here to try and run your code, but it is most likely one of three problems. 1- the two copies of FDS are sharing a variable they should not share, 2- there is not enough stack space, 3- the "pingbuffer[0] := ser.rx" call is receiving a character that has already been placed in the buffer from an earlier piece of code.

    Try using "pcFullDuplexSerial4FC" instead of FDS. It provides 4 serial ports using 1 cog. I have used it to have 4 spin routines in one cog/program communicate with each other, and 4 programs in separate cogs communicate with each other.
  • kuronekokuroneko Posts: 3,623
    edited 2010-11-28 16:05
    @T Chap: In you repeater loop you do the following:
    repeat
        buffer := ser2.rx  '//  get anything that comes in from Wifly
        ser2.str(@buffer)  '//  foward all wifi responses back to the GUI app
    
    ser2.rx returns a byte, which you should send as a char/byte by using ser2.tx. It's not a string. Also, you don't need a second copy of the FDS just use a different alias, e.g.
    OBJ
      serial1: "FullDuplexSerial"
      serial2: "FullDuplexSerial"
    
    or
    OBJ
      serial[2]: "FullDuplexSerial"
    
  • kuronekokuroneko Posts: 3,623
    edited 2010-11-28 16:28
    The listed program runs 3 FDS linked as a star without any issues (demoboard). So whatever is causing you trouble is unlikely to be the FDS object.
    CON
      _clkmode = XTAL1|PLL16X
      _xinfreq = 5_000_000
    
    OBJ
      serial[3]: "FullDuplexSerial"
    
    VAR
      long  stack[64]
      
    PUB null
    
      dira[16..23]~~                                        ' stop LEDs from bleeding
    
      serial[0].start(0, 1, %0000, 300)                     '
      serial[1].start(1, 2, %0000, 300)                     ' start FDS instances linked
      serial[2].start(2, 0, %0000, 300)                     ' like a mercedes star
    
      cognew(repeater(16, 0, FALSE), @stack[0])             '
      cognew(repeater(17, 1, FALSE), @stack[32])            ' start slave repeaters
      repeater(18, 2, TRUE)                                 ' run master
    
    PRI repeater(pin, idx, master)
    
      dira[pin]~~
    
      if master                                             ' master triggers loop
        serial[idx].tx(42)
    
      repeat
        repeat 100                                          '
          serial[idx].tx(serial[idx].rx)                    ' resend 100 characters
          !outa[pin]                                        ' indicate traffic
        waitcnt(clkfreq + cnt)                              ' wait 1 sec then continue
    
    DAT
    
Sign In or Register to comment.