Tool/software: Starterware
Hello everybody,
I'm doing some tests with a BBB, and I would like to drive four outputs with PRU1.
As starting point, I've cleaned the PruDemo project, contained inside the pru software support package, leaving included only PRU_LED0 and PRU_LED1
With the code below I can drive the output GPIO2[22], GPIO2[23], GPIO2[24], GPIO2[25], making them toggling.
file pru_cape_demo.c
int main(void)
{
//sets pin mux for PRU cape
PRUCapePinmux();
//Sets and Enables clock, Zeros memory, resets PRU
PRUICSSInit();
UARTInit();
LEDTest();
}
int LEDTest(void)
{
PRUMemLoad(PRU_ICSS1, PRU0_IRAM, 0, sizeof(LED0_INST), (unsigned int*)LED0_INST); // copia da LED0_INST a 0x4A334000
PRUMemLoad(PRU_ICSS1, PRU0_DRAM, 0, sizeof(LED0_DATA), (unsigned int*)LED0_DATA); // copia da LED0_DATA a 0x4A300000
PRUMemLoad(PRU_ICSS1, PRU1_IRAM, 0, sizeof(LED1_INST), (unsigned int*)LED1_INST); // copia da LED1_INST a 0x4A338000
PRUMemLoad(PRU_ICSS1, PRU1_DRAM, 0, sizeof(LED1_DATA), (unsigned int*)LED1_DATA); // copia da LED1_DATA a 0x4A302000
PRUEnable(PRU_ICSS1, PRU0); // scrive 0xb in CTRL a (0x4A300000 + 0x00022000) 4.5.1.1 del trm
PRUEnable(PRU_ICSS1, PRU1); // scrive 0xb in CTRL a (0x4A300000 + 0x00024000) 4.5.1.1 del trm
...
}
void PRUCapePinmux(void)
{
// P8 pin27 -> pr1_pru1_pru_r30[8] -> U5
HWREG(SOC_CONTROL_REGS + CONTROL_CONF_LCD_VSYNC) =
(5 << 0) |
(0 << 3) | // attiva Pull
(0 << 4) |
(0 << 5) | // RX
(0 << 6);
// P8 pin29 -> pr1_pru1_pru_r30[9] -> R5
HWREG(SOC_CONTROL_REGS + CONTROL_CONF_LCD_HSYNC) =
(5 << 0) |
(0 << 3) | // attiva Pull
(0 << 4) |
(0 << 5) | // RX
(0 << 6);
// P8 pin28 -> pr1_pru1_pru_r30[10] -> V5
HWREG(SOC_CONTROL_REGS + CONTROL_CONF_LCD_PCLK) =
(5 << 0) |
(0 << 3) | // attiva Pull
(0 << 4) |
(0 << 5) | // RX
(0 << 6);
// P8 pin30 -> pr1_pru1_pru_r30[11] -> R6
HWREG(SOC_CONTROL_REGS + CONTROL_CONF_LCD_AC_BIAS_EN) =
(5 << 0) |
(0 << 3) | // attiva Pull
(0 << 4) |
(0 << 5) | // RX
(0 << 6);
}
Inside the PRU_LED1 project, this code works correctly.
void main(void)
{
/* Clear SYSCFG[STANDBY_INIT] to enable OCP master port */
CT_CFG.SYSCFG_bit.STANDBY_INIT = 0;
/*****************************************************************/
/* Access PRU Shared RAM using Constant Table */
/*****************************************************************/
/* C28 defaults to 0x00000000, we need to set bits 23:8 to 0x0120 in order to have it point to 0x00012000 */
PRU1_CTRL.CTPPR0_bit.C28_BLK_POINTER = 0x0120;
/* Ensure CT_DDR (C31) is pointing to DDR memory (0x80001000) */
PRU1_CTRL.CTPPR1_bit.C31_BLK_POINTER = 0x0010; // (0x80001000)
gpio = 0x0F00;
__R30 = gpio; // all 4 leds on
/* Toggle the LEDs */
while (1)
{
__R30 = 0x000; // all 4 leds off
__delay_cycles(10);
__R30 = gpio; // all 4 leds on
__delay_cycles(10);
}
/* Halt PRU core */
__halt();
}
Now, I disable this code, and I insert an .asm file inside the project PRU_LED1 , containing this code
.asg r0, r_data_addr
.asg r1, r_data_len
.asg r4, r_gpio2_zeros
.asg r6, r_bit_num
.asg r7, r_sleep_counter
.asg r8, r_temp_addr
.asg r9, r_temp1
.asg r10, r_data0
.asg r11, r_data1
.asg r12, r_data2
.asg r13, r_data3
.asg r22, r_gpio2_mask
.asg r26, r_gpio2_addr
.asg r28, r_temp2
.asg 0x481AC000, GPIO2
.asg 0x190, GPIO_CLEARDATAOUT ; 25.4.1.25
.asg 0x194, GPIO_SETDATAOUT ; 25.4.1.26 TRM
.asg 20, PRU1_ARM_INTERRUPT
.asg 0x24000, PRU_CONTROL_ADDRESS
.asg 0x24028, CTPPR_0
.asg 0x2402C, CTPPR_1
CONST_PRUDRAM .set C24
CONST_SHAREDRAM .set C28
CONST_L3RAM .set C30
CONST_DDR .set C31
.global main
; gpio2-22,23,24,25
main:
LBCO &r0, C4, 4, 4
CLR r0, r0, 4
SBCO &r0, C4, 4, 4
; Configure the programmable pointer register for PRU0 by setting c28_pointer[15:0] field to 0x0120.
; This will make C28 point to 0x00012000 (PRU shared RAM).
LDI32 r0, 0x00000120
LDI32 r1, CTPPR_0
SBBO &r0,r1,0x00,4
; Configure the programmable pointer register for PRU0 by setting c31_pointer[15:0] field to 0x0010.
; This will make C31 point to 0x80001000 (DDR memory).
LDI32 r0, 0x00100000
LDI32 r1, CTPPR_1
SBBO &r0,r1,0x00,4
qua:
; Load the address(es) of the GPIO devices
LDI32 r_gpio2_mask, 0x03c00000
LDI32 r_gpio2_addr, (GPIO2 | GPIO_CLEARDATAOUT)
SBBO &r_gpio2_mask, r_gpio2_addr, 0, 4
LBCO &r5, c31, 0, 4
ADD r5, r5, 0x01 ; counter to be read @ 0x80001000
SBCO &r5, c31, 0, 4
LDI32 r_gpio2_mask, 0x03c00000
LDI32 r_gpio2_addr, GPIO2 | GPIO_SETDATAOUT
SBBO &r_gpio2_mask, r_gpio2_addr, 0, 4
JMP qua
...
Here my problems begin.
It run, and debugging from the PruDemo I can see R5 counting throught an 0x80001000 memory readout, but the outputs don't toggle.
I don't understand what I'm missing.
Someone can help me ?
Mario