My objective is to poll sensor output using GPIO and process the data. The CPU is missing some of the pulses from sensor while processing the previous data. My idea is to use PRU to count the sensor pulses and provide the counter value to CPU using shared memory. I am using C code for PRU after installing ti-pru-cgt-installer, the PRU-C code has to write the counter data at some memory location after each pulse from sensor so that host C-prog will be able to read the data whenever it is free.
Given below is a PRU-C code which generates a square wave and user-LED blinking of 20 cycles
#include <stdint.h>
#include <pru_cfg.h>
#include <gpio_v2.h>
#include <soc_AM335x.h>
#include <gpio_v2.c>
#define PRU0_ARM_INTERRUPT 19 // Interrupt used for halt signal
#define GPIO1 (*(volatile unsigned long )(0x4804c000)) // The address of the GPIO1
#define GPIO_INSTANCE_ADDRESS0 (SOC_GPIO_0_REGS)
#define GPIO_INSTANCE_ADDRESS1 (SOC_GPIO_1_REGS)
#define GPIO_INSTANCE_ADDRESS2 (SOC_GPIO_2_REGS)
#define GPIO_INSTANCE_ADDRESS3 (SOC_GPIO_3_REGS)
#define SYSCFG ((&C4+0x01))
int C4 attribute((cregister(“CFG”,near),peripheral)); //only compatible with v1.1.0B1 +
//add following lines to MEMORY{} in lnk.cmd
//PAGE 2:
// MEM : o = 0x00026000 l = 0x00002000 CREGISTER=4
volatile register uint32_t __R30;
volatile register uint32_t __R31;
/* Mapping Constant table register to variable */
volatile pruCfg CT_CFG attribute((cregister(“CFG”, near), peripheral));
void main(){
volatile uint32_t gpio;
int i=0,j=1;
/* Clear SYSCFG[STANDBY_INIT] to enable OCP master port */
CT_CFG.SYSCFG_bit.STANDBY_INIT = 0;
/Intialise OCP Master port for accessing external memories/
SYSCFG&=0xFFFFFFEF;
/* Toggle GPO pins TODO: Figure out which to use /
gpio = 1<<2; //p9_30
// Just a test to show how you can use assembly instructions directly
// subtract 1 from REG1
/ asm volatile
(
" SUB r1, r1, 1 \n"
);*/
/* TODO: Create stop condition, else it will toggle indefinitely */
while(j<20){
//__R30 ^= gpio;
__R30 = 0<<2;
//GPIOPinWrite(GPIO_INSTANCE_ADDRESS3, 16, GPIO_PIN_LOW);
GPIOPinWrite(GPIO_INSTANCE_ADDRESS1, 21, GPIO_PIN_LOW);
GPIOPinWrite(GPIO_INSTANCE_ADDRESS1, 22, GPIO_PIN_LOW);
GPIOPinWrite(GPIO_INSTANCE_ADDRESS1, 23, GPIO_PIN_LOW);
GPIOPinWrite(GPIO_INSTANCE_ADDRESS1, 24, GPIO_PIN_LOW);
i++;
//GPIOPinWrite(GPIO_INSTANCE_ADDRESS, 16, GPIO_PIN_LOW);
//__R30 = __R30 | 1<<2;
//for(j=0;j<5000000;j++);
//__delay_cycles(50000000);
//GPIOPinWrite(GPIO_INSTANCE_ADDRESS, 16, GPIO_PIN_HIGH);
//__R30 = __R30 & 0<<2;
//for(j=0;j<5000000;j++);
__delay_cycles(50000000);
//__R30 ^= gpio;
__R30 = 1<<2;
//GPIOPinWrite(GPIO_INSTANCE_ADDRESS3, 16, GPIO_PIN_HIGH);
GPIOPinWrite(GPIO_INSTANCE_ADDRESS1, 21, GPIO_PIN_HIGH);
GPIOPinWrite(GPIO_INSTANCE_ADDRESS1, 22, GPIO_PIN_HIGH);
GPIOPinWrite(GPIO_INSTANCE_ADDRESS1, 23, GPIO_PIN_HIGH);
GPIOPinWrite(GPIO_INSTANCE_ADDRESS1, 24, GPIO_PIN_HIGH);
i++;
__delay_cycles(50000000);
j++;
}
// Signal the process has completed (this will wake up the loader to tell it work is done)
__R31 = (__R31 & ~0xff) | (PRU0_ARM_INTERRUPT+16);
/* Halt the PRU core */
__halt();
}
and the host C prog to load PRU code is as below
#include <stdio.h>
#include <stdlib.h>
#include <prussdrv.h>
#include <pruss_intc_mapping.h>
#define PRU_NUM 0
#define AM33XX
int main (int argc, char **argv)
{
unsigned int ret;
tpruss_intc_initdata pruss_intc_initdata = PRUSS_INTC_INITDATA;
/* Initialize the PRU */
prussdrv_init ();
/* Open PRU Interrupt */
ret = prussdrv_open(PRU_EVTOUT_0);
if (ret) {
printf(“prussdrv_open open failed\n”);
return (ret);
}
/* Get the interrupt initialized */
prussdrv_pruintc_init(&pruss_intc_initdata);
/* Execute example on PRU */
prussdrv_exec_program (PRU_NUM, “./text.bin”);
/* Wait until PRU0 has finished execution */
prussdrv_pru_wait_event (PRU_EVTOUT_0);
prussdrv_pru_clear_event (PRU_EVTOUT_0, PRU0_ARM_INTERRUPT);
/* Disable PRU and close memory mapping*/
prussdrv_pru_disable (PRU_NUM);
prussdrv_exit ();
return(0);
}
The above codes are generating output and my aim is to write the counter value stored in ‘i’ from PRU code to be available to host C code. Can anyone please help me ?
and one more doubt is the lines GPIOPinWrite(GPIO_INSTANCE_ADDRESS3, 16, GPIO_PIN_HIGH); and GPIOPinWrite(GPIO_INSTANCE_ADDRESS3, 16, GPIO_PIN_LOW); doesn’t produce out put, I have tired all the four GPIO base addresses, but in vain.