Hi
I’m trying to use IEP timer on PRU on my BeagleBone Black, but without much luck. I would like to use it for precise timing, so I have created demo app that should demonstrate IEP timer capabilities. Demo app should work in following way:
- first turns LED on one of GPIO pins
- then starts timer
- pools timer value until reaches some predefined value
- turns LED off
- exits
Part with runing LEDs on/off works fine, problem is with timer. From what I have tried so far, I’m not able to get it running. Here are the steps that I performed in the code to start counter:
- set counter value to 0
- enable timer clock PRU_ICSS_CFG.CGR.IEP_CLK_EN=1 (although this should be already on upon reset)
- // start counter IEP_GLOBAL_CFG.CNT_ENABLE = 1
Code gets stuck when pooling counter value (red bellow) - it never reaches desired value. Did I missed something in initialization? any hint?
Here is code of sample app:
.origin 0
.entrypoint START
#define PRU0_ARM_INTERRUPT 19
#define AM33XX
#define GPIO0 0x44E07000 // base address of GPIO 0
#define GPIO_OE 0x134 // offset of the register that defines pin directions
#define GPIO_CLEARDATAOUT 0x190 // offset of the register used for setting pin to LOW
#define GPIO_SETDATAOUT 0x194 // offset of the register used for setting pin to HIGH
#define IEP 0x2E000 // base address of Industrial Etherne Peripheral (IEP)
#define PIN_GPIO_0_26 1<<26 // references GPIO 0 pin 26 (P8-14 on BBB headers)
#define IEP_GLOBAL_CFG 0
#define IEP_COUNT 0xc
#define rGPIO0Base r0
#define rOE r1
#define rSetDataOut r2
#define rClearDataOut r3
#define rOutPin r4
#define rIEPBase r5
#define rT1 r16
#define rT2 r17
START:
LBCO rT1, c4, 4, 4 // Load Byte Constant Offset
CLR rT1, rT1, 4 // clears r0 and copies to destination r0
SBCO rT1, c4, 4, 4 // Store byte constant table offset
MOV rGPIO0Base, GPIO0 // setup needed address offsets
MOV rOE, GPIO_OE
MOV rSetDataOut, GPIO_SETDATAOUT
MOV rClearDataOut, GPIO_CLEARDATAOUT
MOV rOutPin, PIN_GPIO_0_26
MOV rIEPBase, IEP
MOV rT1, 0x00000000 // set all pins on GPIO 0 as output
SBBO rT1, rGPIO0Base, rOE, 4
// turn led on
SBBO rOutPin, rGPIO0Base, rSetDataOut, 4
// init counter value to 0
MOV rT1, 0
SBBO rT1, rIEPBase, IEP_COUNT, 4
// enable timer clock PRU_ICSS_CFG.CGR.IEP_CLK_EN=1
LBCO rT1, C4, 0x10, 4
SET rT1, 17
SBCO rT1, C4, 0x10, 4
// start counter IEP_GLOBAL_CFG.CNT_ENABLE = 1
LBBO rT1, rIEPBase, IEP_GLOBAL_CFG, 4
SET rT1, 0
SBBO rT1, rIEPBase, IEP_GLOBAL_CFG, 4
// wait until counter reaches desired value
MOV rT1, 1 // for testing only → counter never reaches this value
L1:
LBBO rT2, rIEPBase, IEP_COUNT, 4
QBLT L1, rT1, rT2
// led off
SBBO rOutPin, rGPIO0Base, rClearDataOut, 4
MOV r31.b0, PRU0_ARM_INTERRUPT+16 //tell the c program we are done (just remove it if your c program does not handle the interrupt)
HALT
BR
Ivan
Also will try debugger you mentioned, as writing apps blindly and debug them only with LED attached to GPIO is bit of pain