This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

BBB working with PRU interrupts on GPIOx

Hi,

I am trying for days now but had no success yet, hopefully you could help:

I checked out an example on getting a HCSR04 example to work from here: https://github.com/luigif/hcsr04 

After setting up the PRU environment on the BBB the examples worked fine, but now I want to move the sonar to different pins on my BBB (echo pin P9_27 and trigger pin P9_31). I adapted the dts file accordingly and also tried to modify the .p-file. My overlay seems to be initialized correctly:

# cat /sys/devices/bone_capemgr.9/slots
1: 55:PF---
2: 56:PF---
3: 57:PF---
4: ff:P-O-L Bone-LT-eMMC-2G,00A0,Texas Instrument,BB-BONE-EMMC-2G
5: ff:P-O-- Bone-Black-HDMI,00A0,Texas Instrument,BB-BONELT-HDMI
6: ff:P-O-- Bone-Black-HDMIN,00A0,Texas Instrument,BB-BONELT-HDMIN
8: ff:P-O-L Override Board Name,00A0,Override Manuf,hcsr04_2
root@beaglebone:/home/debian/Projects/hcsr04_2#

and the pinmux-functions output:

root@beaglebone:/home/debian/Projects/hcsr04_2# cat /sys/kernel/debug/pinctrl/44e10800.pinmux/pinmux-functions
function: pinmux_userled_pins, groups = [ pinmux_userled_pins ]
function: pinmux_rstctl_pins, groups = [ pinmux_rstctl_pins ]
function: pinmux_i2c0_pins, groups = [ pinmux_i2c0_pins ]
function: pinmux_i2c2_pins, groups = [ pinmux_i2c2_pins ]
function: pinmux_mmc1_pins, groups = [ pinmux_mmc1_pins ]
function: pinmux_emmc2_pins, groups = [ pinmux_emmc2_pins ]
function: pinmux_userled_pins, groups = [ pinmux_userled_pins ]
function: pinctrl_hcsr04_2_pins, groups = [ pinctrl_hcsr04_2_pins ]

root@beaglebone:/home/debian/Projects/hcsr04_2#

When I now start the application, I don't get any reception from the sonar. I suppose I got something wrong in my assembly code, but I cannot figure out what exactly. I hope someone could give me a hint.

My modified .dts file looks like:

/dts-v1/;
/plugin/;
// www.valvers.com/.../step04-gpio
/ {
compatible = "ti,beaglebone", "ti,beaglebone-black";

/* identification */
part-number = "hcsr04_2";
version = "00A0";

/*exclusive-use =
"P8_12", "P8_11",
"GPIO44", "GPIO45";*/

exclusive-use =
"P9.31", "P9.27",
"gpio3_14", "gpio3_19";

fragment@10 {
target = <&am33xx_pinmux>;
__overlay__ {
pinctrl_hcsr04_2: pinctrl_hcsr04_2_pins {
pinctrl-single,pins = <

/* old stuff */
/*0x030 0x07*/ /* P8_12 gpio1[12] GPIO44 out pulldown Mode: 7 */
/*0x034 0x27*/ /* P8_11 gpio1[13] GPIO45 in pulldown Mode: 7 */
/* end of old stuff*/


0x1a4 0x07 /* Trigger: P9_27 gpio3[19] GPIO117 out pulldown Mode: 7 */
0x190 0x27 /* Echo: P9_31 gpio3[14] GPIO110 in pulldown Mode: 7 */


>;
};
};
};

fragment@11 {
target = <&ocp>;
__overlay__ {
hcsr04_2 {
compatible = "bone-pinmux-helper","gpio","pruss";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_hcsr04_2>;
status = "okay";
};
};
};

fragment@12{
target = <&pruss>;
__overlay__ {
status = "okay";
};
};
};

And also my .p-File

// Define the entry point of the program
.origin 0
.entrypoint START

// Address of the io controller for GPIO1 and GPIO2
#define GPIO1 0x4804C000
#define GPIO2 0x481AC000
#define GPIO3 0x481AE000

// Offset address for the output enable register of the gpio controller
#define GPIO_OE 0x134

// Offset address for the data in/out register of the gpio controller
#define GPIO_DATAIN 0x138
#define GPIO_CLEARDATAOUT 0x190
#define GPIO_SETDATAOUT 0x194

// PRU interrupt for PRU0 and PRU1
#define PRU0_ARM_INTERRUPT 19
#define PRU1_ARM_INTERRUPT 20

// original code
// gpio1[12] P8_12 gpio44 0x030
//#define BIT_TRIGGER 0x0C

// gpio1[13] P8_11 gpio45 0x034
//#define BIT_ECHO 0x0D
// end of original code

// gpio3[14] P9_31 gpio110 0x6B
#define BIT_ECHO 0x0E // gpio3_14 -> gpio pin 110

// gpio3[21] P9_27 gpio115 0x03
#define BIT_TRIGGER 0x13 // gpio3_19 -> gpio pin 125

#define delay r0
#define roundtrip r4


START:

// Clear the STANDBY_INIT bit in the SYSCFG register
// otherwise the PRU will not be able to write outside the PRU memory space
// and to the Beaglebone pins
LBCO r0, C4, 4, 4
CLR r0, r0, 4
SBCO r0, C4, 4, 4

// Make constant 24 (c24) point to the beginning of PRU0 data ram
MOV r0, 0x00000000
MOV r1, 0x22020
SBBO r0, r1, 0, 4

// Enable trigger as output and echo as input (clear BIT_TRIGGER and set BIT_ECHO of output enable)
MOV r3, GPIO3 | GPIO_OE
LBBO r2, r3, 0, 4
CLR r2, BIT_TRIGGER
SET r2, BIT_ECHO
SBBO r2, r3, 0, 4

TRIGGER:

// Fire the sonar
// Set trigger pin to high
MOV r2, 1<<BIT_TRIGGER
MOV r3, GPIO3 | GPIO_SETDATAOUT
SBBO r2, r3, 0, 4

// Delay 10 microseconds (200 MHz / 2 instructions = 10 ns per loop, 10 us = 1000 loops)
MOV delay, 1000
TRIGGER_DELAY:
SUB delay, delay, 1
QBNE TRIGGER_DELAY, delay, 0

// Set trigger pin to low
MOV r2, 1<<BIT_TRIGGER
MOV r3, GPIO3 | GPIO_CLEARDATAOUT
SBBO r2, r3, 0, 4

// Wait for BIT_ECHO to go high, i.e. wait for the echo cycle to start
MOV r3, GPIO3 | GPIO_DATAIN
WAIT_ECHO:
// Read the GPIO until BIT_ECHO goes high
LBBO r2, r3, 0, 4
QBBC WAIT_ECHO, r2, BIT_ECHO

// roundtrip measures the echo duration in microseconds, resolution is 1us
MOV roundtrip, 0

SAMPLE_ECHO:

// Delay 1 microsecond (adjusted because it takes time to query the GPIO pin)
MOV delay, 76
SAMPLE_ECHO_DELAY:
SUB delay, delay, 1
QBNE SAMPLE_ECHO_DELAY, delay, 0

// Add 1us to the roundtrip counter
ADD roundtrip, roundtrip, 1

// Read GPIO until BIT_ECHO goes low
LBBO r2, r3, 0, 4
QBBS SAMPLE_ECHO, r2, BIT_ECHO

// Echo is complete
// Store the microsecond count in the PRU's data ram so C program can read it
SBCO roundtrip, c24, 0, 4

// Trigger the PRU0 interrupt (C program gets the event)
MOV r31.b0, PRU0_ARM_INTERRUPT+16

// Delay to allow sonar to stop resonating and sound burst to decay in environment
MOV delay, 3000000
RESET_DELAY:
SUB delay, delay, 1
QBNE RESET_DELAY, delay, 0

// Jump back to triggering the sonar
JMP TRIGGER

HALT

Additional information: I work on a Beaglebone Black in revision C1,

thank you in advance!

  • Hi,

    I will forward this to the PRU experts.
  • Hello again,

    I just did some debug work from command line: I used a totally different gpio pin and triggered it via /sys/class/gpio/... for 10ms to high. In fact the base example from the repository in my original post responded as expected. As I tested this sequence with my modified overlay, no response on the echo pin could be received in my application.
    What I also saw is when I connect a multimeter to the trigger pin in the working example and leaving the echo pin unconnected, the voltage is going down while the application is waiting for the sonar echo. In my modified code the same procedure results in no reaction at the trigger pin at all. So, it seems that there is a major misconfiguration in my project, but I have no idea where to start searching...
  • I finally solved the main issue in my configuration above. The PRU code was correct! I simply used the wrong pin address offset in my dts file: If I want to use pin 27 and 31 on pin header P9, I need to get the correct global GPIO pin number which are 0x1CC for pin 27 and 0x1B8! I simply had a wrong pin mux offset table and never proofed the values in it.
    Now I am have another problem, I don't understand. To get the updated sample working, I somehow need to apply the gpio configuration manually in /sys/class/gpio to set the pin 115 (P9_27) to an output pin. When I do this, my pru code starts working immediately. When I remove it from the gpio config in /sys/class/gpio it stops instantly! My /sys/kernel/debug/pinctrl/44e10800.pinmux/pins show the same config for pin 115 after loading the overlay and configuring the pin manually: pin 115 (44e109cc) 00000007 pinctrl-single
    It seems the gpio setting in my overlay is not active even if the kernel log says different. I see my pin not going to ground and output although its configured like that.

    Any suggestions?
    Thanks!!!
  • Hi,

    What Linux version is this? Please note that this forum supports only the TI released Linux SDK. All other versions are supported by the community on beagleboard.org/.../Forums
  • I am running Debian with kernel 3.8.13 (bone47). I got the image from rcn-ee.com, I will forward my question to the BB.org forums.

    Thank you anyway,

    regards

  • Hi,

    I wanted to know how you get these  0x1CC for pin 27 and 0x1B8 values.I want to do for P9_24,i did it but it could not work,help me

  • Hi,

    it actually is prety simple: Take you BBB reference manual and navigate to expansion header pinout tables. On expansion header P9 the pin 27 is connected to gpio3_19, so 3rd gpio bank. Each gpio bank has 32 gpio pins with 4bytes memory space.

    This means for pin P9_27:

    3(gpio bank) * 32(size per bank) + 19(offset in bank) * 4(bytes memory offset) = 460 = 0x1CC

    So for P9_24 your address offset would be 0x3c

    Regards,

    Daniel

  • I solved the initialization problem by simply using a gpio library to initialize the driver. Here is a link to a guide how to get and use the lib. www.element14.com/.../bbb--beaglebone-black-io-library-for-c
  • Hi,

    I tried how you said,

    this is my dts

    /dts-v1/;
    /plugin/;

    / {
    compatible = "ti,beaglebone", "ti,beaglebone-black";

    /* identification */
    part-number = "hcsr04_2";
    version = "00A0";


    /*exclusive-use = "P9_24","gpio0_15";*/

    fragment@0 {
    target = <&am33xx_pinmux>;
    __overlay__ {
    pinctrl_hcsr04_2: pinctrl_hcsr04_2_pins {
    pinctrl-single,pins = < 0x3c 0x27 /* Echo: P9_24 gpio0[15] GPIO15 in pulldown Mode: 7 */

    >;
    };
    };
    };

    fragment@1 {
    target = <&ocp>;
    __overlay__ {
    test_helper:helper {
    compatible = "bone-pinmux-helper";
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_hcsr04_2>;
    status = "okay";
    };
    };
    };

    /*fragment@2{
    target = <&pruss>;
    __overlay__ {
    status = "okay";
    };
    };*/
    };

    and .p file

    // Define the entry point of the program
    .origin 0
    .entrypoint START

    // Address of the io controller for GPIO1
    #define GPIO1 0x4804C000

    // Offset address for the output enable register of the gpio controller
    #define GPIO_OE 0x134

    // Offset address for the data in/out register of the gpio controller
    #define GPIO_DATAIN 0x138
    #define GPIO_CLEARDATAOUT 0x190
    #define GPIO_SETDATAOUT 0x194

    // PRU interrupt for PRU0
    #define PRU0_ARM_INTERRUPT 19

    // gpio0[15] P9_24 gpio15 0x184
    #define SENSOR_DETECT 0x0f

    #define delay r0
    #define roundtrip r4


    START:

    // Clear the STANDBY_INIT bit in the SYSCFG register
    // otherwise the PRU will not be able to write outside the PRU memory space
    // and to the Beaglebone pins
    LBCO r0, C4, 4, 4
    CLR r0, r0, 4
    SBCO r0, C4, 4, 4

    // Make constant 24 (c24) point to the beginning of PRU0 data ram
    MOV r0, 0x00000000
    MOV r1, 0x22020
    SBBO r0, r1, 0, 4

    // Enable SENSOR DETECT as input (set SENSOR_DETECT of output enable)
    MOV r3, GPIO1 | GPIO_OE
    LBBO r2, r3, 0, 4
    SET r2, SENSOR_DETECT
    SBBO r2, r3, 0, 4

    // Wait for SENSOR_DETECT to go high, i.e. RISING EDGE
    MOV r3, GPIO1 | GPIO_DATAIN

    WAIT_SENSOR:
    // Read the GPIO until SENSOR_DETECT goes high
    LBBO r2, r3, 0, 4
    QBBC WAIT_SENSOR, r2, SENSOR_DETECT


    SAMPLE_SENSOR:

    // Delay 1 microsecond (adjusted because it takes time to query the GPIO pin)
    MOV delay, 76

    SAMPLE_SENSOR_DELAY:
    SUB delay, delay, 1
    QBNE SAMPLE_SENSOR_DELAY, delay, 0

    // Add 1us to the roundtrip counter
    ADD roundtrip, roundtrip, 1

    // Read GPIO until SENSOR_DETECT goes low again
    LBBO r2, r3, 0, 4
    QBBS SAMPLE_SENSOR, r2, SENSOR_DETECT

    // SENSOR DETECTION is complete
    // I will store here value that comes from i2c1  in the PRU's data ram so PYTHON program can read it
    //SBCO i2cvalue, c24, 0, 4

    // Trigger the PRU0 interrupt (Python gets the event)
    MOV r31.b0, PRU0_ARM_INTERRUPT+16

    // Jump back to SENSOR Rising EDGE CHECK
    JMP WAIT_SENSOR

    HALT

    I don't know why it is not working,i tried for P8_11 nad P8_12 for both i can detect rising edge.but i can't for P9_24

    Thanks