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