Categories: BeagleBone : Hardware : Software : Angstrom :

Beaglebone: Bidirectional bus with PRU-ICSS

Showing 1-8 of 8 messages
Beaglebone: Bidirectional bus with PRU-ICSS Lyren Brown 6/25/12 1:49 AM
Is it possible to alternate reads and writes from the PRU-ICSS to an external bidirectional bus?

It seems like I should be able to do this by alternating between pin mux MODE5 and MODE6 for pins LCD_DATA0 through DATA7, since MODE5 attaches those pins to the PRU's write register, R30, and MODE6 attaches them to the read register, R31.  This is according to TI's Pin Mux Utility.

But, is it possible to change pin muxing modes from the PRU? My writes to the Control Module Registers don't seem to take, either from user-space or from the PRU:

root@beaglebone ~ $ devmem2 0x44e108a0 w 0x2e
/dev/mem opened.
Memory mapped at address 0x40127000.
Read at address  0x44E108A0 (0x401278a0): 0x0000002F
Write at address 0x44E108A0 (0x401278a0): 0x0000002E, readback 0x0000002E
root@beaglebone ~ $ cd
root@beaglebone ~ $ devmem2 0x44e108a0
/dev/mem opened.
Memory mapped at address 0x40167000.
Read at address  0x44E108A0 (0x401678a0): 0x0000002F

Using the sysfs interface isn't an option because my application needs to flip between reading and writing every 500ns in a realtime fashion.

Do I need to disable the kernel's pin muxing somehow and/or write my own kernel module? I had hoped I could stay in user space for now. I am using the am335x_pru_package prussdrv interface.

My fallback would be to just use MODE7 and GPIO registers.  As a proof of concept, I am able to make the LEDs blink via GPIO registers with this PRU code, but it requires more instructions on the PRU than simple r30/r31 operations and I imagine there's additional latency to route from the pin header to GPIO to PRU-ICSS vs. a direct route from the pin header to PRU-ICSS.  On the plus side, I can easily extend this to alternate between reads and writes to the bus via writes to GPIO_OE.

#define GPIO1 0x4804c000
#define GPIO_CLEARDATAOUT 0x190
#define GPIO_SETDATAOUT 0x194

    MOV r1, 10
BLINK:
    MOV r2, 7<<22
    MOV r3, GPIO1 | GPIO_SETDATAOUT
    SBBO r2, r3, 0, 4

    MOV r0, 0x00a00000
DELAY:
    SUB r0, r0, 1
    QBNE DELAY, r0, 0

    MOV r2, 7<<22
    MOV r3, GPIO1 | GPIO_CLEARDATAOUT
    SBBO r2, r3, 0, 4

    MOV r0, 0x00a00000
DELAY2:
    SUB r0, r0, 1
    QBNE DELAY2, r0, 0

    SUB r1, r1, 1
    QBNE BLINK, r1, 0
Re: Beaglebone: Bidirectional bus with PRU-ICSS Brandon I 3/7/13 3:37 PM
Even though the PRU can access system memory, writes to the MUX settings require "privileged" (meaning kernel) access. So, no, it's not possible to change the mux from the PRU. But, you can use the PRU to trigger an interrupt, which can be handled by something in userspace (using UIO and the uio_pruss driver) or kernel space (with your own kernel driver) to change the pin mux, and then signal the PRU that the change has been made. Easiest way to signal the PRU would be a memory write to the pru data block that the pru would sit and poll.
Re: Beaglebone: Bidirectional bus with PRU-ICSS Lyren Brown 3/8/13 11:17 AM
Brandon,

Thanks for the response. I should have updated this thread when I learned from Alexander Haim that muxing requires privilege. [1]

Unfortunately interrupt latency would have been too large for my use case, so I used external muxes instead. I posted a write up the beagleboard group. [2]

I was also pleased to learn other people found my work useful.

Matt Porter referenced my abx project in his presentation at the Embedded Linux Conference. [3] [4]

boxysean wrote a post about PRU usage that referenced this very thread. [5]

I think I even see vestiges of the code from this thread in Elias Bakken's replicape PRU code. [6] [7]

I love the power of the PRU and I love to see new applications. Sounds like you have something in the works.

Cheers,
Lyren

Re: Beaglebone: Bidirectional bus with PRU-ICSS Juanjo 3/9/13 7:02 AM
I've using the PRU with success to read a PCM audio stream from a 3G modem using uio_pru. That way I can leave McASP0 for the audio cape or other codec (since McASP1 isn't exposed on BB)

My PRU code reads the serial stream and signal with an interrupt when the buffer is half or full (circular buffer) then a thread in userspace code reads the buffer.

The only weird thing I've noted that I get exactly two (2) UIO events (the library just block reads /dev/uio) per PRU interrupt. It seems this only happens using UIO.

I use two UIO interrupts one for buffer signaling and the usual end of execution interrupt.
Re: Beaglebone: Bidirectional bus with PRU-ICSS Chris Micali 3/16/13 5:07 PM
Juanjo,

    Is there any way you can share some sample code for this?  I want to do the same thing (stream data from the PRU) and am a bit stuck.  Any pointers (especially on the C side) would be much appreciated.

-chris
Re: Beaglebone: Bidirectional bus with PRU-ICSS Brandon I 4/28/13 9:55 AM
The only weird thing I've noted that I get exactly two (2) UIO events (the library just block reads /dev/uio) per PRU interrupt. It seems this only happens using UIO.

The awesome guy at Hipstercircuits covered the double PRU interrupt bug recently: http://hipstercircuits.com/prussdrv-bug/
Re: Beaglebone: Bidirectional bus with PRU-ICSS Juanjo 5/17/13 6:26 AM
Yes thanks to them. And someone even posted the patch on the official git repo but maintainer hasn't applied it.
Re: Beaglebone: Bidirectional bus with PRU-ICSS taffson 11/19/13 6:05 PM
Hi Juanjo, what performance in terms of resolution, latency and sample rate did you push through it? And do you think one could sample one signal with higher precision by somehow sampling the lower part with 12bit and sequentially the upper part with 12bit?