Beaglebone Black write on GPIO using PRU

433 views
Skip to first unread message

Mihai Seba

unread,
Feb 28, 2016, 4:58:31 AM2/28/16
to BeagleBoard
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;
}

John Syne

unread,
Feb 28, 2016, 4:03:36 PM2/28/16
to beagl...@googlegroups.com
On Feb 28, 2016, at 1:58 AM, Mihai Seba <ardel...@gmail.com> wrote:

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
--
For more options, visit http://beagleboard.org/discuss
---
You received this message because you are subscribed to the Google Groups "BeagleBoard" group.
To unsubscribe from this group and stop receiving emails from it, send an email to beagleboard...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Mihai Seba

unread,
Feb 28, 2016, 4:16:07 PM2/28/16
to BeagleBoard
Hi John,

Thanks for reply! I appreciate your answer!

Best Regards,

Sebastian

Paulo Sherring

unread,
Jul 15, 2016, 10:59:22 AM7/15/16
to BeagleBoard
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.
Reply all
Reply to author
Forward
0 new messages