Am 04.12.18 um 10:25 schrieb [email protected]:
Hi, I need your help,

I need to read data of an SPI Master device on the BeagleBone. Since the SPI kernel driver doesn't support an SPI slave mode I have to implement it in the PRU (Because the maximum frequency one BeagleBone's GPIO can be toggle is only 15 KHz). From what I have read, the PRU cycle time is 200 MHz, even so, I can't read data up to 10 MHz. I am doing the following:



                         k=0;
shift = 0;

while((__R31&cs) != cs){ // CS = 0


Why not simply

#define CS  15              /* whatever */

while(__R31 & CS) {};


I hope that cs is a #defined macro and not a variable;

In C there is the convention that macros are written in upper case,

as a warning that there may be more action inside than meets the eye.

And macros should employ parentheses generously to avoid bugs like this:

#define A  2 + 3

if (5 * A)  .....  which results in

if (5 * 2 + 3)  , which is probably not what was intended.


Note that EVERY computation result can be used as a boolean.

0 is false, EVERYTHING else is true, so your compares to

generate a boolean are just a non-wanted complication.


while((__R31&sclk) == sclk);
while((__R31&sclk) == sclk){ //sclk = 1

if((__R31&cs) == cs)
goto END;

I don't know where END is, but gotos are known to not work well

with optimizing compilers since the the compiler may have to

throw assumptions overboard that are not safe any more since the

goto is non-local.


buffer[cnt] = ((__R31&miso) == miso)?  buffer[cnt] | 0x01 << shift: buffer[cnt]; // Here is where my cycle is being stranded!!!

The conditional assignment makes the program read back buffer[cnt]. That is bad

in concept since the buffer may be in shared ram and reading that may cost many clocks

for arbitration. Writing the shared RAM may be a little bit cheaper since the bus logic

might buffer the write and let the PRU run on.


Thinking about it, even the PRU local data RAM is somehow shared since the

ARM CPU and the other PRU can read & write it; let's hope that the priorities are set

in a sensible way.


Also the address of buffer[cnt] is computed 3 times in this line.

The compiler might spot that it has the values already. But you could kick it into the

right direction:


register int tmp;        // I have no idea if the TI compiler honors that. It is just a hint.

int *bufferp =  KJHGKJHJHM;


tmp = __R31 & MISO;  // the & result is already usable as a boolean

if (tmp) tmp = tmp | (1 << shift);  // that feels somehow wrong since the original bit is kept.

*bufferp++ = tmp;


You might also leave that shifting to the ARM CPU; it probably can be done

when the data is further proccessed.


regards,

Gerhard

--
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/6f91ab43-b393-277c-43a2-7f201005e65a%40hoffmann-hochfrequenz.de.
For more options, visit https://groups.google.com/d/optout.

Reply via email to