Byte Order of Channel Communications

If you have a simple question and just want an answer.
Post Reply
kyle123
Member++
Posts: 25
Joined: Tue May 19, 2015 8:17 pm

Byte Order of Channel Communications

Post by kyle123 »

Hello all,

I recently observed some strange behavior that I can't quite explain. I am trying to send some 16bit data over a streaming channel to a buffer core. This buffer subsequently talks to the USB core which sends data back to my computer. The following test code represents the beginning of the signal chain. Note: the configuration char isn't relevant for this example. I have also rolled back from the timestamped I/O version of this code to a simple processor intensive bit-banging implementation.

Code: Select all

        case ADC.RUN(char cfg):
            /*  */
            configure_clock_ref(acq_clk, 100);
            start_clock(acq_clk);
          unsigned  short buffer;
          unsigned  short tmp;
          unsigned  short result;

            for(int i =0; i< 256; i++){
                p_busy when pinseq(1):> void;
                p_busy when pinseq(0):> void;  //trigger signaling data is ready to grab
                tmp=0;
                buffer=0;
                result=0;
                for(char i=0; i< 16; i++){
                    p_sck <: 1;
                    p_sdo :> tmp;
                    buffer = (result <<1) | tmp;  //manually get each bit and place into the result variable.  
                    p_sck <: 0;
                    result = buffer;
                }
                c_data <: result;
            }
            stop_clock(acq_clk);
            break;
If I replace result with a number cast as a short, I get the correct result all the way through my signal chain back on the computer end of things. However, when I try to send the two's complement result (from ADC), it looks very much like the *nibbles, not bytes or bits are reversed... I can decode the serial signal externally on an oscilloscope. The values all seem reasonable (lsb varies a little, but nominal values are as expected).

I have tried the following,

result = byterev(buffer); -> It looks like the buffer gets promoted to an int since I get all 0's back. To test this, I do a byterev() operation and shift the result back into the lower 16bits of the resulting int32 before transmitting as shown in the following line.

result = byterev(buffer)>>16;

Here, data looks more a little more reasonable...However, the result is clearly discontinuous for some values. In the attached screenshot, I have applied an offset to show the effect of bit discontinuity. See attached. Removing the offset results in a wrong, but continuous time domain result.
byterevShift16.png
(21.51 KiB) Not downloaded yet
byterevShift16.png
(21.51 KiB) Not downloaded yet
Next: result = bitrev(byterev) >>16; Returns all zeros.


This is the first time i've had trouble sending data over channels. For instance, I can read back configuration information sent from the host to the device without trouble. The issues seems to be in the way that the data is packed or transmitted at the device end.

I'm sincerely hoping someone might be able to explain the bit/byte structure of data sent via channels so that I can pack it correctly.

Thanks,

Kyle


henk
Respected Member
Posts: 347
Joined: Wed Jan 27, 2016 5:21 pm

Post by henk »

Hi kyle123,

Words are sent over a channel *most significant byte* first.

So if you output 4 bytes 0xAB, 0xCD, 0xEF, 0x01, and input a word, you will get 0xABCDEF01.

I have had fun in the past where an implicit cast caused my data to be garbled - but I have forgotten the details. I would add a line 'result = 0xABCD' and see what you get out at the output.

Cheers,
Henk
kyle123
Member++
Posts: 25
Joined: Tue May 19, 2015 8:17 pm

Post by kyle123 »

Hi Henk,

Sorry i forgot to mention that I have tried sending various known test values through without explicit cast. For example:

0x8000 -> -32768
0x0001 -> 1
0x0000 -> 1
0x8001 ->-32767

These all make sense for two's complement. I did not think to try 0xABCDEF... However, it appears that xTimeComposer is smart enough to let me know that this is an implicit overflow condition seeing as how i defined the result to be only 16 bits long.

Kyle
henk
Respected Member
Posts: 347
Joined: Wed Jan 27, 2016 5:21 pm

Post by henk »

So,

If you add a line

Code: Select all

 
result = (unsigned short) 0x1234
You should get the same value out continuously on the receiving side.
Which value(s) do come out?


Cheers,
Henk
kyle123
Member++
Posts: 25
Joined: Tue May 19, 2015 8:17 pm

Post by kyle123 »

I get 4660 => 0x1234. --K
henk
Respected Member
Posts: 347
Joined: Wed Jan 27, 2016 5:21 pm

Post by henk »

Thanks - so the channel communication is correct in that case.

My guess is that the problem is elsewhere - I would start with the IO protocol. In particular,
how are the ports declared, and what sort of protocol does the ADC run?

As it is written, the loop may run quite fast, and there do not appear to be link between the data and the clock. However, with clock blocks in the right place that may all be correct.

Cheers,
Henk
kyle123
Member++
Posts: 25
Joined: Tue May 19, 2015 8:17 pm

Post by kyle123 »

Hi! I think I've come to the conclusion that the 512B buffer is insufficient for the data rate. Need to review the maths after some of the most recent changes. Thanks--K
Post Reply