Beaglebone Black write on GPIO using PRU

Hi guys,

I’m trying to control a gpio using PRU but I not understand something. First of all, I know that for certain pins, there is the PRU mode for writing and reading (mode 5 and 6) and for gpio is mode 7. My question is, can I control the pin in mode 7 with PRU?

I already tried to control a pin in mode 5 or 6 with PRU and everything seems to work. But what I don’t understand from documentation is that if I can control it in mode 7, and I’m asking that because I saw some examples with pin used in mode 7 ( gpio) controlled by PRU ( output or capture).

I already have some code but it seems that it doesn’t work.
//pru

#include <stdint.h>
#include “pru_cfg.h”
#include “pru_ctrl.h”
#define GROUP_ADDRESS 0x44E07000
#define GPIO_CTRL 0x130
#define GPIO_DATAOUT 0x13C
#define HWREG(x) (*((volatile unsigned int *)(x)))
unsigned int shared_ram = (unsigned int ) 0x10000;
volatile register unsigned int __R31;
int finish = 0;
static void delay(uint32_t microseconds);
/

  • Configurations for shared ram
  • shared_ram[0]=finish
  • shared_ram[1]=pullup/down
  • shared_ram[2]=event
  • shared_ram[3]=sample event
  • shared_ram[4:260]=data to arm
    */
    int main(void) {

/* Clear SYSCFG[STANDBY_INIT] to enable OCP master port*/
uint8_t ii;
uint8_t value;

CT_CFG.SYSCFG_bit.STANDBY_INIT = 0;

// /* Enable GPIO0 Module.GPIO0_CTRL Register*/
// HWREG((GROUP_ADDRESS|GPIO_CTRL)) = 0x00;

/Set pins as output/
HWREG((GROUP_ADDRESS|0x1B4)) = 0x0f;

while (!finish) {
value=shared_ram[0];
HWREG((GROUP_ADDRESS|GPIO_DATAOUT))^=(1<<20);
__R31 = 35;
delay(100);
}
__halt();
/**/
return 0;
}

void delay(uint32_t microseconds) {
while (0 < microseconds) {
__delay_cycles(200); /if 1 cycle takes 5 ns, in 1 us PRU executes 200 cycles/
–microseconds;
}
}

//host

#include <stdio.h>
#include <pthread.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/time.h>
#include <fcntl.h>
#include <sys/mman.h>

#include <prussdrv.h>
#include <pruss_intc_mapping.h>

#define PRU_NUM 0
#define START_ADDR 0x00000000 /took from pru.map file/
#ifndef START_ADDR
#error “START_ADDR must be defined”
#endif

unsigned int* shared_ram = NULL;
pthread_t thread;
int finish = 0;

void init_pru_program(){
tpruss_intc_initdata pruss_intc_initdata = PRUSS_INTC_INITDATA;
prussdrv_init();
prussdrv_open(PRU_EVTOUT_1);
prussdrv_pruintc_init(&pruss_intc_initdata);

prussdrv_load_datafile(PRU_NUM, “./data.bin”);
prussdrv_exec_program_at(PRU_NUM, “./text.bin”, START_ADDR);
}

void signal_handler(int signal){
finish = 1;
}

void* threaded_function(void* param){
printf(“Started thread\n”);
while(!finish){

// Wait for interrupt from PRU
// prussdrv_pru_wait_event(PRU_EVTOUT_1);
// prussdrv_pru_clear_event(PRU_EVTOUT_1, PRU1_ARM_INTERRUPT);
shared_ram[0]=1;
sleep(1);
shared_ram[0]=0;
sleep(1);
// Read number in shared ram
// printf(“Got input: %u\n”, shared_ram[0]);
}

return NULL;
}

void start_thread(){
pthread_attr_t attr;
if(pthread_attr_init(&attr)){
printf(“Cannot start a new thread.\n”);
exit(1);
}
if(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED)){
printf(“Cannot start a new thread.”);
exit(1);
}
if(pthread_create(&thread, &attr, &threaded_function, NULL)){
printf(“Cannot start a new thread.”);
exit(1);
}
}

void stop_thread(){
while(pthread_cancel(thread)){
printf(“Stopping thread”);
}
printf(“Stopped thread”);
}

int main(int argc, const char *argv[]){
printf("\n\n");

// Listen to SIGINT signals (program termination)
signal(SIGINT, signal_handler);

// Load and run binary into pru0
init_pru_program();

// Get pointer to shared ram
void* p;
prussdrv_map_prumem(PRUSS0_SHARED_DATARAM, &p);
shared_ram = (unsigned int*)p;

// Start input polling thread
start_thread();

while(!finish)
{

}

printf(“Disabling PRU.\n”);
prussdrv_pru_disable(PRU_NUM);
prussdrv_exit ();

stop_thread();

return 0;
}

Hi guys,

I’m trying to control a gpio using PRU but I not understand something. First of all, I know that for certain pins, there is the PRU mode for writing and reading (mode 5 and 6) and for gpio is mode 7. My question is, can I control the pin in mode 7 with PRU?

I already tried to control a pin in mode 5 or 6 with PRU and everything seems to work. But what I don’t understand from documentation is that if I can control it in mode 7, and I’m asking that because I saw some examples with pin used in mode 7 ( gpio) controlled by PRU ( output or capture).

When you use the PRU I/O modes, then you get very fast I/O, but if you use GPIO in Mode7 then you have to control the GPIO via the GPIO registers and that will be much slower.

Regards,
John

Hi John,

Thanks for reply! I appreciate your answer!

Best Regards,

Sebastian

Hello there. I am currently using TI’s C compiler for PRUSS. I am doing it this way, for instance to toggle user Leds (GPIO 21 to 24)

#define LED0_OFFSET 21
#define LED0_GPIO_ADDRESS 0x4804c000
#define GPIO_CLEARDATAOUT 0x190
#define GPIO_SETDATAOUT 0x194

volatile uint32_t * p;
p = LED0_GPIO_ADDRESS | GPIO_SETDATAOUT;
*p = 1 << LED0_OFFSET;
p = LED0_GPIO_ADDRESS | GPIO_CLEARDATAOUT;
*p = 1 << LED0_OFFSET;

john3909 is completely right: this way is much slower, but, sometimes you just need doing it because you ran out of PRU pins.
Best regards.
Paulo Sherring.