View previous topic :: View next topic |
Author |
Message |
FreakShow!
Joined: 13 Feb 2012 Posts: 21
|
|
Posted: Thu Mar 15, 2012 2:36 pm |
|
|
Have included and still no joy.
Every single time it does the if statement, it sets the bits, all of them. |
|
|
FreakShow!
Joined: 13 Feb 2012 Posts: 21
|
|
Posted: Thu Mar 15, 2012 2:51 pm |
|
|
I'm an idiot. My restarted code had the function for intialising the camera, but didn't actually call that function.
So now I'm at a good stage I think. It's reading data, it's giving it up to a maximum of 1024. Now I just need to clarify the setting of the bits, whether the bit set code or the previous code of the bit shifting and & 0x30 was correct. |
|
|
FreakShow!
Joined: 13 Feb 2012 Posts: 21
|
|
Posted: Sat Mar 17, 2012 9:15 pm |
|
|
Right, I finally have the correct data!
However, it's not done in an elegant form, I'm having to literally bit-test the bytes and then bit_set or bit_clear the data.
The data is in the form of 8-bit bytes.
This is the code that I am currently doing:
Code: | int16 result=0;
byte data_in[16];
if(bit_test(data_in[3],5)) {
bit_set (result, 9);
printf("1");
}else printf("0");
if(bit_test(data_in[3],4)) {
bit_set (result, 8);
printf("1");
}else printf("0");
if(bit_test(data_in[1],7))
{
bit_set (result, 7);
printf("1");
}
else printf("0");
if(bit_test(data_in[1],6)) {
bit_set (result, 6);
printf("1");
}
else printf("0");
if(bit_test(data_in[1],5)) {
bit_set (result, 5);
printf("1");
}
else printf("0");
if(bit_test(data_in[1],4)) {
bit_set (result, 4);
printf("1");
}
else printf("0");
if(bit_test(data_in[1],3)) {
bit_set (result, 3);
printf("1");
}
else printf("0");
if(bit_test(data_in[1],2)){
bit_set (result, 2);
printf("1");
}
else printf("0");
if(bit_test(data_in[1],1)) {
bit_set (result, 1);
printf("1");
}else printf("0");
if(bit_test(data_in[1],0)){
bit_set (result, 0);
printf("1");
}else printf("0");
puts("");
printf("Result: %Ld \t", result);
|
Is there a better way of doing this? I've tried to use the following code, but it doesn't seem to work. It just seems to set at 255:
Code: | x1=0;
x1 = data_in[1];
x1 += (data_in[3] & 0x30) << 4;
printf("The result: %Ld",x1); |
I'd much rather be able to make a nice neat function, but atm I can only get it working with bitset. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat Mar 17, 2012 9:23 pm |
|
|
Post a short list of the data bytes that you want to reformat.
Show the bit positions of the one byte that has packed msb bits.
Show the desired end-result.
Be very clear about which bits are for the msb bits for which lower byte.
You problem is simply one of bit/byte formatting. It can all be tested and
done in MPLAB simulator. It's a pure logic and coding problem. |
|
|
FreakShow!
Joined: 13 Feb 2012 Posts: 21
|
|
Posted: Sat Mar 17, 2012 9:35 pm |
|
|
MPLAB Simulator? Not heard of that at all.
OK, so for the first point the three bytes are, for example:
Quote: |
X LSBs 11001010
Y LSBs 01011010
Size and MSBs 01000100
|
So, to get the X co-ordinate, I use the sections that are in bold.
Of the Size and MSBs bits, the 1 is the Most Significant Bit (512) and the 0 is the next (256).
Then all the LSBs are in reverse order. So the final number is 595 with Binary:
1001010011
I hope that's clear enough! |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat Mar 17, 2012 10:46 pm |
|
|
How do you know the LSB bits are in reverse order ? Where is there
any documentation that says this ? |
|
|
FreakShow!
Joined: 13 Feb 2012 Posts: 21
|
|
Posted: Sat Mar 17, 2012 10:56 pm |
|
|
The documentation I have used is this:
http://alumni.soe.ucsc.edu/~inio/wiipaper.pdf
If you look at section B.4.2 that shows the format that the data is in.
However after using bit_test and bit_set (zeroing the data each time) I have found that it is in reverse order, so LSB first, not MSB.
So the code I have works doing it in reverse order. The problem I have is that I am only able to do this by using nested for loops, and bit_test and bit_set only.
I'm hoping for something much more "clean" and quicker overall.
I can't offer any more documentation to prove it, apart from that I've put in plenty of work and have this confirmed for myself. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
FreakShow!
Joined: 13 Feb 2012 Posts: 21
|
|
Posted: Sat Mar 17, 2012 11:09 pm |
|
|
No in built function? That's a pain.
Final question then on this, I've been looking round on ways to select bits that I want to put into the resultant co-ordinate.
I've found something called bit-masking? Is that a credible way of doing it? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat Mar 17, 2012 11:25 pm |
|
|
Bit-masking is a common way to isolate the particular bits that you want
to look at, or move to another location. The code posted earlier in this
thread which ANDs a byte with 0x30, is doing bit masking. |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Sun Mar 18, 2012 7:04 am |
|
|
FreakShow! wrote: | Code: | x1 += (data_in[3] & 0x30) << 4; |
| This code can't work!
Just assume data_in[3] contains all '1's:
0b1111 1111 & 0x30 = 0b0011 0000
Then shifting to the left by 4 positions you get: 0b0000 0000
So, no matter what your data_in[3] input is, you will always get a zero result.
Not tested, but what could work is adding a cast to int16: Code: | x1 += ((int16)(data_in[3] & 0x30)) << 4; |
Quote: | No in built function? That's a pain. | What do mean by pain? You were given a link to a very efficient algorithm, so who cares if it is Compiler built-in or not?
Or did you means built-in as a single processor instruction? Yes, that is too bad, but that is also the difference between a cheap RISC processor and an expensive CISC processor.
Quote: | MPLAB Simulator? Not heard of that at all. | One of the most powerful tools when developing PIC software! And best of all, it comes for free when you install MPLAB. Don't waste time and add this to your toolbox.
The afore mentioned reverse bits function from the Code Library would be a great starting point for you to write your bit extraction function. With a little bit of tweaking you can change it into a very fast and compact function. Sometimes a large C program can compile into very short assembly code.
Just a few hints:
- The PIC is inefficient in relative-addressing modes. A construct like a[i] takes a lot of code. But hard coded references like a[3] can be resolved at compile time and are efficient.
- An if-statement means the processor can execute the next instruction or has to jump, depending on the outcome of the if-statement. The reverse bit-program uses a peculiarity of the processor instructions that a jump always takes two instruction times because the second instruction is already in the instruction stage line. So, by limiting the instruction inside the if-statement to a single assembly instruction it doesn't matter for speed if the instruction inside the if-statement is executed or skipped. You can achieve this in your program by removing the printf calls. (move this to the end of your function if you want to keep the functionality). |
|
|
|