Hi,
I have been working on a project that collects data from the ADS8331 4 Ch. ADC at moderate sampling rates (~40 kHz/Channel) using an SPI bus. I would like to use the PRU to implement the SPI bus to take some load of the main CPU.
// Bus definitions
#define MOSI R30.t9 #define MOSI R30.t8 #define MISO R31.t12 #define CS R30.t10
#define A r1 // Storage register
#define C r2 // Carry register
#define DAT r3 // Data byte, externally supplied
I figured an efficient, bit-banged implementation would look something like this using ~ASM51 syntax
MOV A, DAT ; Store data byte in A
MOV, CNT, 8 ; The current tick number
RLC A ; Rotate most significant bit into carry bit
SPI_LOOP:
MOV MOSI, C ; Move carry bit out out MOSI
CLR SCLK ; Bring clock line low
MOV C, MISO ; Move MISO into carry bit
RLC A ; Rotate Carry bit into LSB of A, which is now free,
DJNZ CNT, SPI_LOOP ; Decrement counter and jump back to loop start if not finished
MOV DAT, A ; Supply MISO result and return
However, I am having a hard time translating this type of program to the PRU-ASM instruction set. The biggest problem that I am seeing is that it seems to be impossible to MOV single bits within registers without disrupting the other content of the register. This means that instead of simply MOVing the current MISO bit within the A register (in the example able) to the MISO GPIO pin, I have to do a QBBS to see if the pin is set with the A register and the either SET or CLR the bit. i.e. This command
MOV MOSI, C ; Move carry bit out out MOSI
is replaced by approximately this command set, using the same register definitions from above
QBBS MOSI_HIGH DAT, CNT
// Enable MOSI LOW
CLR MOSI
JMP MOS_DONE
// Enable MOSI HIGH
MOSI_HIGH:
SET MOSI
delay 1
MOSI_DONE:
...
I figure that I must be missing something, because this is way too inefficient. Basically, I have three questions/comment.
1. Is there an example of an efficiently implemented, bit-banged SPI protocol for PRU-ASM?
2. How can I MOV a bit within a register without affected other bits within that register.
3. Any random thoughts on how to improve my SPI implementation would be very helpful since (clearly) I don't have too much of a clue :).
Thanks for any help.
- Jon