//
// 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
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:
My PRU-code:
My System:
root@beaglebone:~# cat /boot/uEnv.txt
root@beaglebone:~/dtb-rebuilder/src/arm# cat am335x-boneblack.dts