Help with buffer building please?
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:
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.

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
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.
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.
[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]
@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
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.
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!!)
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?
[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]
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.
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
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!).