Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
ghost opened this issue Apr 6, 2017 · 0 comments

Comments

@ghost
Copy link

ghost commented Apr 6, 2017

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>;
		};
	};
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant