beagleboard / am335x_pru_package

332 stars 181 forks source link

BeagleBone Black - PRU; prussdrv_pru_clear_event (PRU_EVTOUT_1, PRU0_ARM_INTERRUPT); #56

Open ghost opened 7 years ago

ghost commented 7 years ago

Hello everyone,

I have an issue with clearing event using prussdrv_pru_clear_event (PRU_EVTOUT_1, PRU0_ARM_INTERRUPT); It does not clear the corresponding register.

I am not sure if it is on the HOST-side or the PRU-side. I found some posts reporting the same problem: https://groups.google.com/forum/#!topic/beagleboard/e-Nqdngv9mo https://e2e.ti.com/support/embedded/linux/f/354/t/477657 https://e2e.ti.com/support/arm/sitara_arm/f/791/t/479917

My HOST-code:

//
// testPRU.c
// gcc testPRU.c ‐o testPRU ‐lpthread ‐lprussdrv 
//
// program to drive a sensor and display the sensor output in Linux userspace by sending an interrupt.
// written by Derek Molloy for the book Exploring BeagleBone Black and modified by me.
//
#include <stdio.h>
#include <stdlib.h>
#include <prussdrv.h>
#include <pruss_intc_mapping.h>
#include <pthread.h>
#include <unistd.h>

#define PRU_NUM 0

static void *pru0DataMemory;
static unsigned int *pru0DataMemory_int;

void *threadFunction(void *value){
   do {
      int notimes = prussdrv_pru_wait_event (PRU_EVTOUT_1);
      unsigned int prudata = *(pru0DataMemory_int+2);
      int num = ((int)prudata / (1 * 1));
      int pruclear = prussdrv_pru_clear_event (PRU_EVTOUT_1, PRU0_ARM_INTERRUPT);
     printf("%d %d %d\n",notimes, pruclear, num);
   } while (1);
}

int  main (void)
{
   if(getuid()!=0){
      printf("You must run this program as root. Exiting.\n");
      exit(EXIT_FAILURE);
   }
   pthread_t thread;
   tpruss_intc_initdata pruss_intc_initdata = PRUSS_INTC_INITDATA;

   // Allocate and initialize memory
   prussdrv_init ();
   prussdrv_open (PRU_EVTOUT_0);
   prussdrv_open (PRU_EVTOUT_1);

   // Map PRU's INTC
   prussdrv_pruintc_init(&pruss_intc_initdata);

   // Copy data to PRU memory - different way
   prussdrv_map_prumem(PRUSS0_PRU0_DATARAM, &pru0DataMemory);
   pru0DataMemory_int = (unsigned int *) pru0DataMemory;
   // Use the first 4 bytes for the number of samples
   *pru0DataMemory_int = 10;
   // Use the second 4 bytes for the sample delay in ms
   *(pru0DataMemory_int+1) = 100000000;

   // Load and execute binary on PRU
   prussdrv_exec_program (PRU_NUM, "./testPRU.bin");
   if(pthread_create(&thread, NULL, &threadFunction, NULL)){
       printf("Failed to create thread!");
   }
   int n = prussdrv_pru_wait_event (PRU_EVTOUT_0);
   printf("PRU program completed, event number %d.\n", n);
   // printf("The data that is in memory is:\n");
   printf("- the number of samples used is %d.\n", *pru0DataMemory_int);
   printf("- the time delay used is %d.\n", *(pru0DataMemory_int+1));
   unsigned int prudata = *(pru0DataMemory_int+2);
   printf("- the last distance sample is %d.\n", prudata);

   // raw_distance is in 10ns samples
   // distance in inches = time (ms) / 148 according to datasheet
   // float distin = ((float)raw_distance / (100 * 148));
   // float distcm = ((float)raw_distance / (100 * 58));
   // printf("-- A distance of %f inches (%f cm).\n", distin, distcm);

   /* Disable PRU and close memory mappings */
   prussdrv_pru_disable(PRU_NUM);
   prussdrv_exit ();
   return EXIT_SUCCESS;
}

My PRU-code:

// pasm -b testPUR.p
//
// PRUSS program to drive a HC-SR04 sensor and store the output in memory
// that can be read by a Linux userspace program when an interrupt is sent
// Writen by Derek Molloy for the book Exploring BeagleBone and modified by me.

.origin 0               // offset of start of program in PRU memory
.entrypoint START       // program entry point used by the debugger

#define INS_PER_US          200
#define INS_PER_LOOP        2
#define SAMPLE_DELAY_1MS    (1000000 * INS_PER_US) / INS_PER_LOOP
#define PRU0_R31_VEC_VALID  32;
#define PRU_EVTOUT_0        3
#define PRU_EVTOUT_1        4
#define PRU0_ARM_INTERRUPT    19

// Using register 0 for all temporary storage (reused multiple times)
START:

   // Read number of samples to read and inter-sample delay
   MOV    r0, 0x00000000        //load the memory location, number of samples
   LBBO   r1, r0, 0, 4          //load the value into memory - keep r1
   // Read the sample delay
   MOV    r0, 0x00000004        //the sample delay is in the second 32-bits
   LBBO   r2, r0, 0, 4          //the sample delay is stored in r2

   MOV    r3, 0
MAINLOOP:

   // at this point the echo is now low - write the value to shared memory
   MOV    r0, 0x00000008        // going to write the result to this address
   SBBO   r3, r0, 0, 4          // store the count at this address
   MOV    r0, r2                // need a delay between samples 

SAMPLEDELAY:            // do this loop r2 times (1ms delay each time)
   SUB r0, r0, 1
   QBNE   SAMPLEDELAY, r0, 0
//   MOV R31.b0, PRU0_R31_VEC_VALID | PRU_EVTOUT_1
   MOV R31.b0, PRU0_ARM_INTERRUPT+17
   ADD    r3, r3, 1             // increment the counter by 1

   QBLT   MAINLOOP, r1, r3       // loop if the no of iterations has not passed

END:
//   MOV R31.b0, PRU0_R31_VEC_VALID | PRU_EVTOUT_0
     MOV R31.b0, PRU0_ARM_INTERRUPT+16
   HALT

My System:


root@beaglebone:~# uname -or
4.4.30-ti-r64 GNU/Linux
root@beaglebone:~# lsb_release -irc
Distributor ID: Debian
Release:    8.6
Codename:   jessie

root@beaglebone:~# cat /boot/uEnv.txt

#Docs: http://elinux.org/Beagleboard:U-boot_partitioning_layout_2.0

uname_r=4.4.30-ti-r64
#uuid=
#dtb=

##BeagleBone Black/Green dtb's for v4.1.x (BeagleBone White just works..)

##BeagleBone Black: HDMI (Audio/Video) disabled:
#dtb=am335x-boneblack-emmc-overlay.dtb

dtb=am335x-boneblack.dtb

##BeagleBone Black: eMMC disabled:
#dtb=am335x-boneblack-hdmi-overlay.dtb

##BeagleBone Black: HDMI Audio/eMMC disabled:
#dtb=am335x-boneblack-nhdmi-overlay.dtb

##BeagleBone Black: HDMI (Audio/Video)/eMMC disabled:
#dtb=am335x-boneblack-overlay.dtb

##BeagleBone Black: wl1835
#dtb=am335x-boneblack-wl1835mod.dtb

##BeagleBone Green: eMMC disabled
#dtb=am335x-bonegreen-overlay.dtb

##cape-universale
#cmdline=coherent_pool=1M quiet cape_universal=enable
cmdline=coherent_pool=1M quiet

#In the event of edid real failures, uncomment this next line:
#cmdline=coherent_pool=1M quiet cape_universal=enable video=HDMI-A-1:1024x768@60e

##Example v3.8.x
#cape_disable=capemgr.disable_partno=
#cape_enable=capemgr.enable_partno=

##Example v4.1.x
#cape_disable=bone_capemgr.disable_partno=
#cape_enable=bone_capemgr.enable_partno=

##enable Generic eMMC Flasher:
##make sure, these tools are installed: dosfstools rsync
#cmdline=init=/opt/scripts/tools/eMMC/init-eMMC-flasher-v3.sh

uuid=1ee84d4f-1ca6-4df1-8272-2b712b64643e

root@beaglebone:~/dtb-rebuilder/src/arm# cat am335x-boneblack.dts

/*
  Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License version 2 as
  published by the Free Software Foundation.
 */
/dts-v1/;

#include "am33xx.dtsi"
#include "am335x-bone-common.dtsi"
/* #include "am33xx-overlay-edma-fix.dtsi" */
#include <dt-bindings/display/tda998x.h>
/* #include "am335x-bone-jtag.dtsi" */

/* pruss: pick one: */

/*
  /etc/modprobe.d/pruss-blacklist.conf

  blacklist uio_pruss
 */

#include "am33xx-pruss-rproc.dtsi"

/*
  /etc/modprobe.d/pruss-blacklist.conf

  blacklist pruss
  blacklist pruss_intc
  blacklist pru-rproc
 */

/* #include "am33xx-pruss-uio.dtsi" */
#include "am33xx-pruss-uio.dtsi"

/ {
    model = "TI AM335x BeagleBone Black";
    compatible = "ti,am335x-bone-black", "ti,am335x-bone", "ti,am33xx";
};

&ldo3_reg {
    regulator-min-microvolt = <1800000>;
    regulator-max-microvolt = <1800000>;
    regulator-always-on;
};

&mmc1 {
    vmmc-supply = <&vmmcsd_fixed>;
};

&mmc2 {
    vmmc-supply = <&vmmcsd_fixed>;
    pinctrl-names = "default";
    pinctrl-0 = <&emmc_pins>;
    bus-width = <8>;
    status = "okay";
};

&cpu0_opp_table {
    /*
     * All PG 2.0 silicon may not support 1GHz but some of the early
     * BeagleBone Blacks have PG 2.0 silicon which is guaranteed
     * to support 1GHz OPP so enable it for PG 2.0 on this board.
     */
    oppnitro@1000000000 {
        opp-supported-hw = <0x06 0x0100>;
    };
};

&am33xx_pinmux {
    nxp_hdmi_bonelt_pins: nxp_hdmi_bonelt_pins {
        pinctrl-single,pins = <
            AM33XX_IOPAD(0x9b0, PIN_OUTPUT_PULLDOWN | MUX_MODE3)    /* xdma_event_intr0 */
            AM33XX_IOPAD(0x8a0, PIN_OUTPUT | MUX_MODE0)     /* lcd_data0.lcd_data0 */
            AM33XX_IOPAD(0x8a4, PIN_OUTPUT | MUX_MODE0)     /* lcd_data1.lcd_data1 */
            AM33XX_IOPAD(0x8a8, PIN_OUTPUT | MUX_MODE0)     /* lcd_data2.lcd_data2 */
            AM33XX_IOPAD(0x8ac, PIN_OUTPUT | MUX_MODE0)     /* lcd_data3.lcd_data3 */
            AM33XX_IOPAD(0x8b0, PIN_OUTPUT | MUX_MODE0)     /* lcd_data4.lcd_data4 */
            AM33XX_IOPAD(0x8b4, PIN_OUTPUT | MUX_MODE0)     /* lcd_data5.lcd_data5 */
            AM33XX_IOPAD(0x8b8, PIN_OUTPUT | MUX_MODE0)     /* lcd_data6.lcd_data6 */
            AM33XX_IOPAD(0x8bc, PIN_OUTPUT | MUX_MODE0)     /* lcd_data7.lcd_data7 */
            AM33XX_IOPAD(0x8c0, PIN_OUTPUT | MUX_MODE0)     /* lcd_data8.lcd_data8 */
            AM33XX_IOPAD(0x8c4, PIN_OUTPUT | MUX_MODE0)     /* lcd_data9.lcd_data9 */
            AM33XX_IOPAD(0x8c8, PIN_OUTPUT | MUX_MODE0)     /* lcd_data10.lcd_data10 */
            AM33XX_IOPAD(0x8cc, PIN_OUTPUT | MUX_MODE0)     /* lcd_data11.lcd_data11 */
            AM33XX_IOPAD(0x8d0, PIN_OUTPUT | MUX_MODE0)     /* lcd_data12.lcd_data12 */
            AM33XX_IOPAD(0x8d4, PIN_OUTPUT | MUX_MODE0)     /* lcd_data13.lcd_data13 */
            AM33XX_IOPAD(0x8d8, PIN_OUTPUT | MUX_MODE0)     /* lcd_data14.lcd_data14 */
            AM33XX_IOPAD(0x8dc, PIN_OUTPUT | MUX_MODE0)     /* lcd_data15.lcd_data15 */
            AM33XX_IOPAD(0x8e0, PIN_OUTPUT_PULLDOWN | MUX_MODE0)    /* lcd_vsync.lcd_vsync */
            AM33XX_IOPAD(0x8e4, PIN_OUTPUT_PULLDOWN | MUX_MODE0)    /* lcd_hsync.lcd_hsync */
            AM33XX_IOPAD(0x8e8, PIN_OUTPUT_PULLDOWN | MUX_MODE0)    /* lcd_pclk.lcd_pclk */
            AM33XX_IOPAD(0x8ec, PIN_OUTPUT_PULLDOWN | MUX_MODE0)    /* lcd_ac_bias_en.lcd_ac_bias_en */
        >;
    };
    nxp_hdmi_bonelt_off_pins: nxp_hdmi_bonelt_off_pins {
        pinctrl-single,pins = <
            AM33XX_IOPAD(0x9b0, PIN_OUTPUT_PULLDOWN | MUX_MODE3)    /* xdma_event_intr0 */
        >;
    };

    mcasp0_pins: mcasp0_pins {
        pinctrl-single,pins = <
            AM33XX_IOPAD(0x9ac, PIN_INPUT_PULLUP | MUX_MODE0) /* mcasp0_ahcklx.mcasp0_ahclkx */
            AM33XX_IOPAD(0x99c, PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mcasp0_ahclkr.mcasp0_axr2*/
            AM33XX_IOPAD(0x994, PIN_OUTPUT_PULLUP | MUX_MODE0) /* mcasp0_fsx.mcasp0_fsx */
            AM33XX_IOPAD(0x990, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mcasp0_aclkx.mcasp0_aclkx */
            AM33XX_IOPAD(0x86c, PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_a11.GPIO1_27 */
                        /* added */
                        AM33XX_IOPAD(0x834, 0x6) /* p8_11 pin13 */
        >;
    };
};

&lcdc {
    status = "okay";

    /* If you want to get 24 bit RGB and 16 BGR mode instead of
     * current 16 bit RGB and 24 BGR modes, set the propety
     * below to "crossed" and uncomment the video-ports -property
     * in tda19988 node.
     */
    blue-and-red-wiring = "straight";

    port {
        lcdc_0: endpoint@0 {
            remote-endpoint = <&hdmi_0>;
        };
    };
};

&i2c0 {
    tda19988: tda19988 {
        compatible = "nxp,tda998x";
        reg = <0x70>;

        pinctrl-names = "default", "off";
        pinctrl-0 = <&nxp_hdmi_bonelt_pins>;
        pinctrl-1 = <&nxp_hdmi_bonelt_off_pins>;

        /* Convert 24bit BGR to RGB, e.g. cross red and blue wiring */
        /* video-ports = <0x234501>; */

        #sound-dai-cells = <0>;
        audio-ports = < AFMT_I2S    0x03>;

        ports {
            port@0 {
                hdmi_0: endpoint@0 {
                    remote-endpoint = <&lcdc_0>;
                };
            };
        };
    };
};

&mcasp0 {
    #sound-dai-cells = <0>;
    pinctrl-names = "default";
    pinctrl-0 = <&mcasp0_pins>;
    status = "okay";
    op-mode = <0>;  /* MCASP_IIS_MODE */
    tdm-slots = <2>;
    serial-dir = <  /* 0: INACTIVE, 1: TX, 2: RX */
            0 0 1 0
        >;
    tx-num-evt = <32>;
    rx-num-evt = <32>;
};

/ {
    clk_mcasp0_fixed: clk_mcasp0_fixed {
        #clock-cells = <0>;
        compatible = "fixed-clock";
        clock-frequency = <24576000>;
    };

      clk_mcasp0: clk_mcasp0 {
        #clock-cells = <0>;
        compatible = "gpio-gate-clock";
        clocks = <&clk_mcasp0_fixed>;
        enable-gpios = <&gpio1 27 0>; /* BeagleBone Black Clk enable on GPIO1_27 */
    };

    sound {
        compatible = "simple-audio-card";
        simple-audio-card,name = "TI BeagleBone Black";
        simple-audio-card,format = "i2s";
        simple-audio-card,bitclock-master = <&dailink0_master>;
        simple-audio-card,frame-master = <&dailink0_master>;

        dailink0_master: simple-audio-card,cpu {
            sound-dai = <&mcasp0>;
            clocks = <&clk_mcasp0>;
        };

        simple-audio-card,codec {
            sound-dai = <&tda19988>;
        };
    };
};