BeagleBone Black PRU IEP timer

Hi everyone, I started using IEP timer a few days ago and I faced with one problem which could not be solved up to now.
There are parts of my code C and code assembly for PRU.
The C code:

`

while(1)
{
char filename[100];
strcpy(filename, “frame_”);
sprintf(filename,"%d",number);
cout << “Capture” << filename << endl;
prussdrv_pru_wait_event (PRU_EVTOUT_1);
prussdrv_pru_clear_event (PRU1_ARM_INTERRUPT);
number++;
}

`

And the assembly code for PRU

`

#include “PRU_memAccess_DDR_PRUsharedRAM.hp”
#define CONST_IEP C26

MEMACCESS_DDR_PRUSHAREDRAM:

// Enable OCP master port
LBCO r0, CONST_PRUCFG, 4, 4
CLR r0, r0, 4 // Clear SYSCFG[STANDBY_INIT] to enable OCP master port
SBCO r0, CONST_PRUCFG, 4, 4

// *************************************
// * Timer Configuration *
// *************************************

// spruhf8 AM335x PRU-ICSS Reference Guide 10.x
LBCO r6, CONST_IEP, 0x40, 40 // Read all 10 32-bit CMP registers into r6-r15
OR r6, r6, 0x03 // Set count reset and enable compare 0 event

// Set loop period to 1S
MOV r8, 1000000000

SBCO r6, CONST_IEP, 0x40, 40 // Save 10 32-bit CMP registers

MOV r2, 0x00000551 // Enable counter, configured to count nS (increments by 5 each clock)
SBCO r2, CONST_IEP, 0x00, 4 // Save IEP GLOBAL_CFG register

// *************************************
// * Waiting for timer *
// *************************************

WAIT:
LBCO r2, CONST_IEP, 0x44, 4 // Load CMP_STATUS register
QBBC WAIT, r2, 0 // Wait until counter times out
SBCO r2, CONST_IEP, 0x44, 4 // Clear counter timeout bit

// Send notification to Host for program completion
MOV r31.b0, PRU1_ARM_INTERRUPT+16

JMP WAIT
// Halt the processor
HALT

`
The function of this program is to display (Capture+“number”) on the screen after 1s. The number is increasing. When I ran this code, the result was: Capture 0 (delay) Capture 1 Capture 2 (delay) Capture 3 Capture 4 (delay) … It means the number is increase by 2 each 1s (I want it to increase by 1).
I have tried many different ways but I could not find the solution. I thought that the instruction prussdrv_pru_clear_event (PRU1_ARM_INTERRUPT); in code C need a period of time to clear the interrupt. I tested this idea by adding 1 more prussdrv_pru_wait_event (PRU_EVTOUT_1); after this. The code was changed to:

`

while(1)
{
char filename[100];
strcpy(filename, “frame_”);
sprintf(filename,"%d",number);
cout << “Capture” << filename << endl;
prussdrv_pru_wait_event (PRU_EVTOUT_1);
prussdrv_pru_clear_event (PRU1_ARM_INTERRUPT);
prussdrv_pru_wait_event (PRU_EVTOUT_1); //Additional instruction
number++;
}

`

Fotunately, the problem is solved. I don’t know how to explain for this. I think that PRU sends another interrupt to main processor when the timer is matched. Can anyone help me to explain this?

Best regards,

Phong

I think is related to a bug (double interrupt) on the PRUSS userspace library provided. Patch was sent many months ago but the maintainer (jadonk) hasn’t applied. Weird since the repository has movement 4 months ago but just cosmetics:

Repository:

https://github.com/beagleboard/am335x_pru_package

Bug report on same repository with patch:

https://github.com/beagleboard/am335x_pru_package/issues/3

Thank you very much. I think this is my problem.

Phong/

Vào 21:48:56 UTC+7 Thứ ba, ngày 05 tháng mười một năm 2013, Juanjo đã viết: