Shop OBEX P1 Docs P2 Docs Learn Events
Help with buffer building please? — Parallax Forums

Help with buffer building please?

RforbesRforbes Posts: 281
edited 2014-01-02 16:42 in Accessories
Hi all :)

I'm not sure if this should be here or in the propeller forum.

I'm currently working on an Xbee HP api mode driver and I've realized I'm writing several methods similar to this:
pri build_value(highest,high,mid,low,lowest,startbyte)

  api_TX_packet[startbyte]:=byte[@highest+3]
  api_TX_packet[startbyte+1]:=byte[@highest+2]
  api_TX_packet[startbyte+2]:=byte[@highest+1]
  api_TX_packet[startbyte+3]:=byte[@highest+0]

  api_TX_packet[startbyte+4]:=byte[@high+3]
  api_TX_packet[startbyte+5]:=byte[@high+2]
  api_TX_packet[startbyte+6]:=byte[@high+1]
  api_TX_packet[startbyte+7]:=byte[@high+0]

  api_TX_packet[startbyte+8]:=byte[@mid+3]
  api_TX_packet[startbyte+9]:=byte[@mid+2]
  api_TX_packet[startbyte+10]:=byte[@mid+1]
  api_TX_packet[startbyte+11]:=byte[@mid+0]

  api_TX_packet[startbyte+12]:=byte[@low+3]
  api_TX_packet[startbyte+13]:=byte[@low+2]
  api_TX_packet[startbyte+14]:=byte[@low+1]
  api_TX_packet[startbyte+15]:=byte[@low+0]
  
  api_TX_packet[startbyte+16]:=byte[@lowest+3]
  api_TX_packet[startbyte+17]:=byte[@lowest+2]
  api_TX_packet[startbyte+18]:=byte[@lowest+1]
  api_TX_packet[startbyte+19]:=byte[@lowest+0]

For instance, this snippet is used when creating a type 17 api packet with a value to send.

This is working, but... it seems there should be a simpler way to handle getting several LONGS into a buffer?

I'd really like to finish this driver, and I can keep at it using this strategy but it sure would be nice to learn a better way to work with data in the way the xbee HP module needs it for api mode.

Comments

  • Duane DegnDuane Degn Posts: 10,588
    edited 2013-12-07 18:09
    One easy way to simplify would be use use a method for the repetitive stuff.
    pri build_value(highest,high,mid,low,lowest,startbyte)
    
      EndianSwap(@spi_TX_packet + startbyte, @highest)
      EndianSwap(@spi_TX_packet + startbyte + 4, @high)
      EndianSwap(@spi_TX_packet + startbyte + 8, @mid)
      EndianSwap(@spi_TX_packet + startbyte + 12, @low)
      EndianSwap(@spi_TX_packet + startbyte + 16, @lowest)
    
    
    PRI EndianSwap(destinationPtr, sourcePtr)
    
      repeat result from 0 to 3
        byte[destination][result] := byte[source][3 - result]
    

    I haven't tested the above but I think it should work.

    You could simplify the above even more with a loop.
    pri build_value(highest,high,mid,low,lowest,startbyte)
    
      repeat result from 0 to 16 step 4
        EndianSwap(@spi_TX_packet + startbyte + result, @highest + result)
    
    

    I'm pretty sure the parameters are located sequentially in memory.

    If you post more of your code, someone may have additional suggestions on how to simplify the code.
  • RforbesRforbes Posts: 281
    edited 2013-12-07 19:15
    Ah, yep that's getting my wheels turning. Ok.

    Thanks man :)

    I will post more code shortly- it's a VERY ROUGH work in progress. But I'll finish it as quick as I can for some testing.
  • Tracy AllenTracy Allen Posts: 6,658
    edited 2013-12-07 19:20
    There was a puzzle thread moons ago about changing the endianness of a long. That was specifically for pasm, but the method PhiPi came up with is instructive (even if maybe not the most practical) in Spin.
    [SIZE=1][FONT=courier new]PRI EndianSwap(longValue)   
      result := longValue & $ff00ff00  ' mask odd #'d bytes
      longValue &= $00ff00ff  ' mask even #'d bytes
      result <-= 8            ' rotate left and to lowest
      longValue ->= 8         ' rotate right and to highest
      result |= longValue     ' inclusive OR[/FONT][/SIZE]
    
  • RforbesRforbes Posts: 281
    edited 2013-12-08 13:06
    @Tracy- thanks man! I'mma study that snippet a bit and try to understand it a little better.

    @Duane- That code snippet works as expected. Thanks!

    Here is what I've started with the driver. I really don't know if this is a good way to go about it, but it's just about all I can think of. I know there's got to be a better way. Just don't know how to code it in that "better way." :)

    I'd really, really appreciate some feedback- whether good, bad or ugly. I got thick skin :)

    This program ports the frame values out to pst (9600 by default in the object) so that it can be compared with what digi's "frame maker" would spit out. The methods I've started work, but they're the simplest of all the api packets. http://ftp1.digi.com/support/utilities/digi_apiframes2.htm
  • Tracy AllenTracy Allen Posts: 6,658
    edited 2013-12-10 10:29
    That is quite an undertaking! You didn't mention having seen Martin Hebel's XBee object from the OBEX, if not, it might provide additional ideas about how to build and parse the API frames. The XSC modules are different in many respects. I have an XSC dev kit but haven't had time or need to get into it, but I'm interested in what you come up with.

    One little concern I have with your methods were statements like this,
    ptr:=buffer+strsize(buffer)
    Strsize() will truncate at the first null that it finds, and values such as the length parameter high byte is usually going to be a null. Other data and addresses too might, or will, contain nulls. An additional issue, note that the packet methodes may have to escape some values, such as the 0x7e.

    I see you are allowing for 300 byte rx and tx buffers. I haven't dug into the XSC capabilities yet, but it looks like it can be up to 256 bytes with 64 set as the default for reliability. Are you going to control both ends of the conversation? The earlier XBees are limited to 100 bytes max in the payload, plus the overhead of the API frame.
  • RforbesRforbes Posts: 281
    edited 2013-12-10 16:32
    Tracy- Yeah man, I've Martins' object quite a bit. It's great!! I actually forgot about the api methods- I have only used the s3B 900 XSC pro and it's an entirely different animal than what he wrote the object for. But I'll be having another look just to glean some more goodies from it. That guy rocks.

    I guess I should have explained that I'm specifically trying to write this one for API mode 1 and then modify it to also work with API mode 2 , escaped characters. I have a plan, but still not totally sure how to see it through for the escaped characters. I'll figure out out one way or another!

    I appreciate your comments. Concerning the add_buffer method, it's just a quick and easy way to add content to a buffer. I need to fix that to work correctly. I just that method in various programs but it's always with a buffer where there's never any null characters until the end. Thanks for pointing that out!

    I set up the rx and tx buffer as 300 bytes just for testing a bit. The actual value will be 285 bytes each. Max of 256 for the rf data payload and a maximum of 29 for the api header stuff. (I think!!)
    Are you going to control both ends of the conversation?
    I'm not sure what you mean by this?
  • Tracy AllenTracy Allen Posts: 6,658
    edited 2013-12-11 09:29
    Are you going to control both ends of the conversation?


    I'm not sure what you mean by this?

    I mean to say, are all the nodes in the network yours to design as you see fit, or do you have to conform to a system that is already in place?
  • Tracy AllenTracy Allen Posts: 6,658
    edited 2013-12-11 09:59
    One way I've dealt with packets is to pre-construct them as a DAT structure. This is application specific, not for a general purpose object. In this application the payload was always 100 bytes, and much the same content from one transmission to the next. So the buffer-building only consisted of filling in the changed information (quick!). This was for a simple 802.15.4 XBee. The whole packet is transferred to the XBee starting at pointer "hey".
    [FONT=courier new][SIZE=1]DAT
      dummy       word 0     ' to enforce word alignment, note that .+30 needs word alignment.
      hey         byte $7e   ' start API packet
      length1     byte 0     ' MSB of length
      length0     byte 105   ' packet length is 100 plus 5 starting with the byte after this one
      apiTXid     byte $01   ' API data transmission identifier
      frameID     byte 1
      dest1       byte 0     ' destination short address msb
      dest0       byte 100   ' destination short address lsb
      options     byte 0             '                      '
    
      fwv         byte VERSION     ' firmware version
      startTime   byte 0,0,0,0,0   ' mhdmy
      stopTime    byte 0,0,0,0     ' mhdmy
      giraDayCode byte 36          ' code for length of giraDay in minutes (36=>24 hours)
      giraWeek    byte 7           ' gira interval (week) setting in number of giradays
      weekCount   byte 0           ' number of giraWeeks logged so far during this deployment
      C_thresh    byte 50          ' temperature threshold in units of 0.1 degreec C
      P_thresh    byte 15          ' percent above threshold by day
      volts       byte 0           ' battery condition, units of 0.1V
      deltaC      byte 0           ' temperature differential
      maxC        byte 0           ' maximum delta T this deployment
      percent     byte 0           ' percent threshold total this deployment
      days        byte 0           ' total days above percent threshold this deployment
      pcnt1       byte 0           ' percent above threshold in gira week #1
      days1       byte 0           ' days used in gira week #1
      degday1     word 0           ' degree days in gira week #1.
    '   etc for 100 byte day by day payload[/SIZE][/FONT]
    
  • RforbesRforbes Posts: 281
    edited 2013-12-11 15:33
    Ah, now I understand your question. The will be designed as I see fit. But with api mode, the driver itself should be universal of course. Errrr... at least universal to the same xbee, regardless of who's using it.
  • Tracy AllenTracy Allen Posts: 6,658
    edited 2013-12-12 09:17
    I opened up the 900HP dev kit yesterday and spent the afternoon and long into the evening working with it. Along with another engineer, it suddenly become very relevant to an upcoming project.

    Back in August, I submitted an answer to a packet-building puzzler that came out in the Digi email newsletter, and managed to come up with the correct answer, and that won me the 900HP Dev kit. Hadn't had occasion to dig into it until now. So far I'm impressed with what it can do.
  • RforbesRforbes Posts: 281
    edited 2013-12-31 17:46
    Hey Tracy,

    I don't have any way to set up my 900 HP modules right now, but I'm itching to see how this works. I have tested this code with the digi frame maker (for writing packets) and I'm pretty sure the read-packet methods will work fine. The only thing you would have to modify is the pins used for TX and RX... right now it just spits everything out to a terminal.

    Would you (or anyone else) mind giving this a try and tell me how it turns out? Thoughts, advice, etc. are always appreciated!!

    xb HP Driver Testing - Archive.zip
  • Tracy AllenTracy Allen Posts: 6,658
    edited 2014-01-02 16:42
    I'll download take a look. I'll pick this XBee project up again now that I'm past the holidays. There are a couple of threads going on now on Series 3 XBee with the HoPping Digimesh firmware.

    We had it going well a couple of weeks ago, mainly experimenting with the sleep modes. Every node in our system has to sleep. We first got it running in a basic sort of way with sleep mediated by the real time clock attached to the Propellers. Then we thought we might have good results and save ourselves some trouble by taking advantage of the XBee's own Digimesh cyclic sleep modes 7 and 8. Well, those worked fine, but are fairly rigid. There is a close link between the CT time and the network parameters. CT is the time the mesh stays awake during each interval in order to originate and relay messages. The more hops there are in the network, and the more allowed retries, the longer has to be the CT time, on the order of seconds. The pin sleep modes controlled by the Prop will allow for a lot more flexibility and ad hoc handshaking as tasks require it, but will be a lot work to implement reliably. (so much can go wrong!).
Sign In or Register to comment.