Shop OBEX P1 Docs P2 Docs Learn Events
Need help receiving data into a buffer — Parallax Forums

Need help receiving data into a buffer

Don MDon M Posts: 1,652
edited 2012-12-05 10:44 in Propeller 1
I am trying to store 6 bytes into a byte buffer. The data is coming in a 9600 baud and here's a screen shot from the Logic analyzer:

Command 034.png


As you can see the data is contiguous. I am using a case statement to trigger on the initial byte which is $1_34. From there I want to store the next 6 bytes. Here is a snippet of the code:
  repeat
    v : \mdb.rx_check
    if v <> -1
      case v 
        $1_34:
          pos := 0
          chksum := v
          repeat pos from 0 to 8
            v := vmc.rx_time(5)
            valen[pos] := v
            chksum += v
            pos++
          term.str(string("Valen: "))
          repeat pos from 1 to 9
            term.hex(valen[pos], 2)
            term.tx(32)
          term.tx(13)        

I was thinking I could define my byte buffer as valen[6] or even valen[8] to give me a little room. But as you can see from the code I need to make it larger as it seems to be catching some inadvertent $00 that are not in the logic trace.

Here is a screen shot from PST:

Valen buffer.PNG


If I change "repeat pos from 0 to 8" to "repeat pos from 0 to 7 then it does not get the final byte which is 6A. But what is more concerning to me is why are there extra $00's in the buffer and why do I have to make it so much larger in order to save it?

I don't understand.

Thanks.
Don

Edit: I declared my byte buffer as valen[18] just to make is more than big enough in case you are wondering...
1024 x 255 - 12K
402 x 58 - 1K

Comments

  • Mike GMike G Posts: 2,702
    edited 2012-12-05 06:04
    Don M $1_34 is larger than a byte.
  • Don MDon M Posts: 1,652
    edited 2012-12-05 06:09
    Mike- Yes I know. v is defined as a long. But the rest of the data is byte length. Just for conversations sake here I even tried using a word buffer but it made no difference.

    Also I'm not storing the initial command which is larger than a byte but even so I would think that it would store the "34" portion of it and skip the "1" if I was.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2012-12-05 06:11
    Don M wrote: »
    Mike- Yes I know. v is defined as a long. But the rest of the data is byte length. Just for conversations sake here I even tried using a word buffer but it made no difference.

    Also I'm not storing the initial command which is larger than a byte but even so I would think that it would store the "34" portion of it and skip the "1".

    But rx_check only returns one byte (if it doesn't return a -1).

    It will only see an $01 or a $34; never a $0134.
  • Mike GMike G Posts: 2,702
    edited 2012-12-05 06:18
    Also I'm not storing the initial command which is larger than a byte but even so I would think that it would store the "34" portion of it and skip the "1" if I was.
    No, not if you are using a one of the standard serial drivers. As soon as the line goes from high to low the serial driver will try to read the next 8 bits. Looks like you are trying to read 9 bits?
  • Don MDon M Posts: 1,652
    edited 2012-12-05 06:18
    Duane Degn wrote: »
    But rx_check only returns one byte (if it doesn't return a -1).

    Duane- The serial receive object I'm using deals in words so it does return a word. It is a custom object written for me by Jonny Mac several years ago.
    pub rx_check | mdb
    
    '' Pulls mdb (word) from RX buffer if available  
    '' -- returns -1 if buffer empty
    
  • Don MDon M Posts: 1,652
    edited 2012-12-05 06:21
    Mike G wrote: »
    No, not if you are using a one of the standard serial drivers. As soon as the line goes from high to low the serial driver will try to read the next 8 bits. Looks like you are trying to read 9 bits?

    Mike- see above. Also I should mention that the data is inverted. So it goes from low to high.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2012-12-05 06:23
    Can you get a LA trace with the $0134 shown? It might help.
  • Don MDon M Posts: 1,652
    edited 2012-12-05 06:28
    Duane Degn wrote: »
    Can you get a LA trace with the $0134 shown? It might help.

    Duane- there is a screen shot of the trace in the very first post. I shows the $0134. I'm using the Saleae analyzer that has the mdb protocol as one of the settings. It labels any data that has the 9th bit set as "address".
  • Don MDon M Posts: 1,652
    edited 2012-12-05 06:31
    And again as I mentioned above- I also tried defining the buffer as a word buffer- "word valen[18]" and I get the same result.

    Again I'm wondering where the extra $00's are coming from and whether it's my code logic that isn't right to avoid them. I am lost at this point.
  • Mike GMike G Posts: 2,702
    edited 2012-12-05 06:31
    According to your original post, you are reading bytes. Nowhere does it say you are reading longs or that you are using an enhanced serial driver. How in the world do you expect someone to help without that info?
  • Don MDon M Posts: 1,652
    edited 2012-12-05 06:54
    Mike G wrote: »
    According to your original post, you are reading bytes. Nowhere does it say you are reading longs or that you are using an enhanced serial driver. How in the world do you expect someone to help without that info?

    Fair enough.
  • Don MDon M Posts: 1,652
    edited 2012-12-05 09:27
    Mike- What I have done is convert my code into something that I'm able to share. I'm using bytes only and the FDS object to illustrate. I also took a second Prop and wrote a program that sends just this certain string of byte data once every second. I have attached the archives for both objects.

    Here's the main code:
    pub main 
    
      term.start(31, 30, %0000, 115_200)                    ' start terminal (use PST)
      pause(1000)
      term.str(@message1)
      comm.start(MSTR, SLAV, 1, 9_600)
    
      chksum := 0
    
      repeat 
        v := comm.rxtime(2000)                                 
        if v <> -1                                          
          case v                                            
            $0C:
              pos := 0
              chksum := v
              repeat pos from 0 to 3
                v := comm.rxtime(1)
                chen[pos] := v
                chksum += v
                pos++
              v := comm.rxtime(1)               ' Why are 3 of these needed to get the next byte?
              v := comm.rxtime(1)
              v := comm.rxtime(1)    
              term.str(string("V: "))
              term.hex(v, 2)
              term.tx(32)
              term.str(string("Chksum: "))
              term.hex(chksum, 2)
              term.tx(13)
              if chksum == v
                comm.tx($00)
              term.str(string("Chen buffer: ")) 
              repeat pos from 1 to 6
                term.hex(chen[pos], 2)
                term.tx(32)
              term.tx(13)
    

    Here's a screen shot of the Saleae Logic analyzer trace:

    Command 0C.jpg


    Here's a screen shot of PST:

    PST Chen buffer.PNG


    So again why isn't the "4B" available as the very next byte in the buffer? See my comments in the code as to how I have to get it. What am I doing wrong?

    If you look at the logic trace you see 0C (not saved) 00 3F 00 00 4B. But in the buffer it has an extra 00 in it. I realize that I'm not saving all those byte to the buffer but even if you change the code to do so it still gives the same result.

    Thanks for your help.
    Don
  • lonesocklonesock Posts: 917
    edited 2012-12-05 10:26
    I would try a longer time in the rxtime function. At 9600 bps, even if there is only 1 stop bit, that's still a total of 10 bits needed for a character. If your custom version does 16 bits per token, then you are looking at at least 18 bits to get a value across, which is 533 tokens per second. You will want at least 2 ms. rxtime will return as soon as it does get a value, so you might was well be safe and make it longer, say 10ms.

    Jonathan
  • Don MDon M Posts: 1,652
    edited 2012-12-05 10:44
    My good friend Mike Otte found the problem. Thanks a ton Mike!

    The problem was that I was incrementing pos in my loop when in reality the statement "repeat pos from 0 to 3" already increments pos.... so it got incremented twice.

    So here is the fixed code...
      repeat 
        v := comm.rxtime(2000)                                 
        if v <> -1                                          
          case v                                            
            $0C:
              pos := 0
              chksum := v
              repeat pos from 0 to 3
                v := comm.rxtime(1)
                chen[pos] := v
                chksum += v
                'pos++                           ' not needed as the repeat command already increments pos
              v := comm.rxtime(1)                ' receive in chksum
              term.str(string("V: "))            ' display received checksum
              term.hex(v, 2)
              term.tx(32)
              term.str(string("Chksum: "))       ' display calculated checksum
              term.hex(chksum, 2)
              term.tx(13)
              if chksum == v                     ' if checksum is ok...
                comm.tx($00)                     ' send ACK
              term.str(string("Chen buffer: ")) 
              repeat pos from 0 to 5
                term.hex(chen[pos], 2)
                term.tx(32)
              term.tx(13)
    

    Amazing what you can spend hours trying to track down. I hope this helps anyone else that may run into this.

    Thanks again.

    Don
Sign In or Register to comment.