On 12/7/2018 3:52 AM, Fred Gomes wrote:
>
> Here's the code where I got the better results:
>
> while(__R31&cs); // CS = 1
>
> while(__R31&sclk){ //sclk = 1
>
> if(__R31&cs){
> goto END;}
> }
> while(!(__R31&sclk)); //SCLK = 0
> var = (__R31&miso)? var |(0x01 << shift): var;
>
> k++;
> shift--;
>
> if(shift == -1){
> *(buffer_shared + cnt) = var;
> cnt++;
> shift=31;
> var = 0;
> }
> END:
> *(buffer_shared+2600) = k; // Here I am storing the value of the counter,
> to check if all the clocks wre catched.
>
> I have only one small problem though, the sensor is sending data every
> time, and sometimes it catches more than one frame. I don't
> understand quite well why is it happening since the time between frames is
> about 10 ms, and in that why it is difficult to have sure that I haven't
> miss clocks in the frame. So, to have sure I am not missing clocks I add
> the following line:
>
> LABEL:
> if(k==79184)
> goto END;
>
> And I noticed that sometimes I miss one clock (although here I am
> introducing one extra instruction, which will make the program a bit slow).
> If you have any suggestion I should implement to tackle this problem,
> please let me know ...
Again, please either write in assembly or post the assembly listing
the compiler is generating. You have 12 lines of C code above, and
that doesn't even look like the entire loop (just the inner loop for
one 32-bit word). As mentioned previously, you have time for about 20
PRU assembly instructions, which isn't many for 12 lines of C.
Without the full code and seeing the assembly your compiler is
generating, I can only make a few suggestions. An optimizing compiler
would probably do much of this for you, but it doesn't sound like your
compiler is doing much optimization (again, let's see some listing
files!):
* Get rid of the count variable and create a dedicated buffer pointer,
then increment that, ie:
*(buffer_shared + cnt) = var;
cnt++;
...turns into:
// Initial setup
uint32_t *buffer_ptr = buffer_shared
// ...other code goes here...
*(buffer_ptr) = var;
buffer_ptr++;
* Review the generated code for the var update. The PRU has lots of
bit test and shift instructions, so changing this calculation slightly
could reduce the number of instructions needed. If I was writing in
assembly I would shift var first then conditionally or in a '1'
depending on the state of the input pin. In C it would look like this
(but I don't know if this will generate the actual assembly I'm
thinking of, it depends on your compiler):
var >>= 1;
if (__R31&miso) var |= 0x8000;
* Review the code generated for the various bit test instructions (eg:
__R31 & <val>). These should be a single bit test instruction in PRU
assembly, but that may not be what the compiler is generating.
There are other "tricks" you can try (eg: get rid of the shift count
and use a bit in var instead). Without being able to see the
generated assembly you can easily wind up making things much worse,
but you can try it if you like. Make sure to initialize var to 0x8000
and set the buffer_ptr value in your setup code:
while(!(__R31&sclk)); //SCLK = 0
k++; // I assume this is needed outside the loop
// 1 in the LSB means this is the last bit of our 32-bit word
if (var & 0x01)
{
// Shift in the last bit
var >>= 1;
if (__R31&miso) var |= 0x8000;
// Store the value
*(buffer_ptr) = var;
// Setup for the next word
buffer_ptr++;
var = 0x8000;
} else {
// Shift in the next bit
var >>= 1;
if (__R31&miso) var |= 0x8000;
}
--
Charles Steinkuehler
[email protected]
--
For more options, visit http://beagleboard.org/discuss
---
You received this message because you are subscribed to the Google Groups
"BeagleBoard" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/beagleboard/95d14956-6dad-f1c4-fe34-7074cb4e926d%40steinkuehler.net.
For more options, visit https://groups.google.com/d/optout.