Example #1
0
File: int.c Project: bkovitz/pru
int main(void) {

  prussdrv_init();
  prussdrv_open(PRU_EVTOUT_0);
  prussdrv_pru_reset(PRU0);

  enable_pru_interrupts();
  
  prussdrv_map_prumem(PRUSS0_PRU0_DATARAM, (void**)&pru0_data_ram);
  *pru0_data_ram = 99;
  prussdrv_pru_write_memory(
    PRUSS0_PRU0_IRAM, 0, (unsigned int*)intp_bin, intp_bin_len
  );

// Contra the ARM PRU Linux API documentation, this function does not exist!
//  prussdrv_start_irqthread(
//    PRU_EVTOUT_0, sched_get_priority_max(SCHED_FIFO) - 2, pruevtout0_thread
//  );

  pthread_t irqthread;
  int iret = pthread_create(&irqthread, NULL, pruevtout0_thread, NULL);
  printf("iret = %d\n", iret);
  sleep(1);

  printf("starting PRU...\n");
  prussdrv_pru_enable(PRU0);

  sleep(3);
  printf("after sleep\n");
  printf("count = %d\n", *pru0_data_ram);
  prussdrv_pru_disable(PRU0);
  printf("PRU disabled\n");
  printf("count = %d\n", *pru0_data_ram);
}
Example #2
0
   void main (void)
   {
       int n;
       /* Initialize structure used by prussdrv_pruintc_intc   */
       /* PRUSS_INTC_INITDATA is found in pruss_intc_mapping.h */
       tpruss_intc_initdata pruss_intc_initdata = PRUSS_INTC_INITDATA;

       /* Allocate and initialize memory */
       prussdrv_init ();
       prussdrv_open (PRU_EVTOUT_0);

       /* Map PRU's INTC */
       prussdrv_pruintc_init(&pruss_intc_initdata);

       /* Copy data to PRU memory */
       unsigned int x = 7;
       prussdrv_pru_write_memory(PRUSS0_PRU0_DATARAM, 0, &x, 4);

       /* Load and execute binary on PRU */
       prussdrv_exec_program (PRU_NUM, "./buttonTest.bin");

       /* Wait for event completion from PRU */
       n = prussdrv_pru_wait_event (PRU_EVTOUT_0);  // This assumes the PRU generates an interrupt
                                                    // connected to event out 0 immediately before halting
       printf("PRU program completed, event number %d.\n", n);

       /* Disable PRU and close memory mappings */
       prussdrv_pru_disable(PRU_NUM);
       prussdrv_exit ();
    }
Example #3
0
int main (int argc, char* argv[])
{
int arg_length = strlen(argv[1]);
unsigned int code=0;
unsigned int code_array[15];
int i;
if (arg_length != 15){
printf("Number of bits in pattern is not equal to 15\n");
exit(EXIT_FAILURE);
}



for (i=0;i<15;i++)
{
code_array[i] = (unsigned int)(argv[1][i]-48);
printf("digit %d: %d\n",i, code_array[i]);
code = code | (code_array[i] << i) ;

}

printf("code: %x\n", code);

if(getuid()!=0){
      printf("You must run this program as root. Exiting.\n");
      exit(EXIT_FAILURE);
   }
   // Initialize structure used by prussdrv_pruintc_intc
   // PRUSS_INTC_INITDATA is found in pruss_intc_mapping.h
   tpruss_intc_initdata pruss_intc_initdata = PRUSS_INTC_INITDATA;

   // Allocate and initialize memory
   prussdrv_init ();
   prussdrv_open (PRU_EVTOUT_0);

   // Map PRU's interrupts
   prussdrv_pruintc_init(&pruss_intc_initdata);
   
   // Load the code into the PRU memory
   prussdrv_pru_write_memory(PRUSS0_PRU0_DATARAM, 0, &code, 4);


   // Load and execute the PRU program on the PRU
   prussdrv_exec_program (PRU_NUM, "/usr/scripts/PRU/send_15_bit_IR_pattern.bin");

   // Wait for event completion from PRU, returns the PRU_EVTOUT_0 number
   int n = prussdrv_pru_wait_event (PRU_EVTOUT_0);
   printf("EBB PRU program completed, event number %d.\n", n);

   // Disable PRU and close memory mappings
   prussdrv_pru_disable(PRU_NUM);
   prussdrv_exit ();
  
   return EXIT_SUCCESS;
}
/* This method should be called first. It loads the required Device Tree Overlay (/sys/firmware/EBB-PRU-ADC-00A0.dtbo). 
 * The following pins should be free to use, this means that HDMI should be disabled. 
 * p9_27 : SPI_CSO   -- Chip Select
 * p9_28 : SPI_D0    -- MISO
 * p9_29 : SPI_SCLK  -- Clock
 * p9_30 : SPI_D1    -- MOSI
 * It allso allocates frame_size memory where the PRU's will write to. The sampling_frequency should be set here. VREF is the reference voltage
 * used by the A/D converter.
 */
unsigned int mdau_create(uint32_t frame_size, FREQUENCY_t sampling_frequency, double vref){
	if(getuid()!=0){
		exit(EXIT_FAILURE);
	}
	//Load the Device Tree Overlay.
	system("echo EBB-PRU-ADC>/sys/devices/bone_capemgr.9/slots");
	
	VREF = vref;
	
	//Resize the default allocated shared memory to fit frame_size.
	system("rmmod uio_pruss");
	char modprobe_cmd[80];
	if(0 == sprintf(modprobe_cmd, "modprobe uio_pruss extram_pool_sz=%#x",2*frame_size)){
		return EXIT_FAILURE;
	}
	system(modprobe_cmd);
	
	// Read in the location and address of the shared memory. This value changes
	// each time a new block of memory is allocated.
	unsigned int timerData[2];
	timerData[0] = sampling_frequency;
	timerData[1] = RUNNING;

	// data for PRU0 based on the MCPXXXX datasheet
	unsigned int spiData[3];
	spiData[0] = 0x01800000;
	spiData[1] = readFileValue(MMAP1_LOC "addr");
	spiData[2] = readFileValue(MMAP1_LOC "size");

	// Allocate and initialize memory
	prussdrv_init ();
	prussdrv_open (PRU_EVTOUT_0);

	// Write the address and size into PRU0 Data RAM0. You can edit the value to
	// PRUSS0_PRU1_DATARAM if you wish to write to PRU1
	prussdrv_pru_write_memory(PRUSS0_PRU0_DATARAM, 0, spiData, 12);  // spi code
	prussdrv_pru_write_memory(PRUSS0_PRU1_DATARAM, 0, timerData, 8); // sample clock


	return EXIT_SUCCESS;
	
}
Example #5
0
static bool initPru(void) {
    tpruss_intc_initdata pruss_intc_initdata = PRUSS_INTC_INITDATA;

    printf("Initializing PRU\n");
    prussdrv_init();

    // Open PRU driver and prepare for using the interrupt on event output 1
    if (prussdrv_open(PRU_EVTOUT_1)) {
        fprintf(stderr, "prussdrv_open failed!\n");
        return false;
    }

    // Initialize the PRUSS interrupt controller
    if (prussdrv_pruintc_init(&pruss_intc_initdata)) {
        fprintf(stderr, "prussdrv_pruintc_init failed!\n");
        return false;
    }

    // Get pointer to the shared PRUSS memory. On the AM355x this block is 12KB
    // in size and located locally at 0x0001_0000 within the PRU cores and
    // globally at 0x4A31_0000 in the MPU's memory map. The entire memory is
    // used as our printer queue so we map the global variable to that address.
    prussdrv_map_prumem(PRUSS0_SHARED_DATARAM, (void *)&queue);

    // Initialize the PRU from an array in memory rather than from a file on
    // disk. Make sure PRU sub system is first disabled/reset. Then, transfer
    // the program into the PRU. Note that the write memory functions expect
    // the offsets to be provided in words so we our byte-addresses by four.
    printf("Loading PRU firmware and enabling PRU\n");
    prussdrv_pru_disable(1);
    prussdrv_pru_write_memory(PRUSS0_PRU1_IRAM, pruprinter_fw_iram_start / 4,
            (unsigned int *)&pruprinter_fw_iram, pruprinter_fw_iram_length);
    prussdrv_pru_write_memory(PRUSS0_PRU1_DATARAM, pruprinter_fw_dram_start / 4,
            (unsigned int *)&pruprinter_fw_dram, pruprinter_fw_dram_length);
    prussdrv_pru_enable(1);

    return true;
}
Example #6
0
/*! \brief load firmware to PRU
\param IRam The IRam ID for the PRU to use
\returns Zero on success, otherwise -1

The instructions are compiled by command

    pasm -V3 -c pruss_add.p

from source code (named pruss_add.p)

    .origin 0
      LDI  r0, 0
    start:
      LBBO r1, r0, 4, 16 // load parameters in r1 (start value), r2 (add value), r3 (count), r4 (interrupt)

      LOOP finished, r3.w0
      ADD  r1, r1, r2    // compute result
    finished:

      SBBO r1, r0, 0, 4  // store result
      MOV  r31.b0, r4.b0 // send notification to host
      HALT
      JMP start

\since 0.6.2
*/
int32 load_firmware(uint32 IRam)
{
  const uint32 PRUcode[] =  {
    0x240000e0,
    0xf104e081,
    0x30830002,
    0x00e2e1e1,
    0xe1002081,
    0x1004041f,
    0x2a000000,
    0x21000100 };

  if(0 >= prussdrv_pru_write_memory(IRam, 0, PRUcode, sizeof(PRUcode)))
                   {printf("failed loading instructions\n"); return -1;}
  return 0;
}
Example #7
0
void PruTimer::initalizePRURegisters() {
	*((uint32_t*)ddr_write_location)=0; //So that the PRU waits
	*ddr_nr_events = 0;
	*pru_control = 0;
	
	//Set DDR location for PRU
	//pypruss.pru_write_memory(0, 0, [self.ddr_addr, self.ddr_nr_events, 0])
	uint32_t ddrstartData[3];
	ddrstartData[0] = (uint32_t)ddr_addr;
	ddrstartData[1] = (uint32_t)(ddr_addr+ddr_size-4);
	ddrstartData[2] = (uint32_t)(ddr_addr+ddr_size-8); //PRU control register address
	
	prussdrv_pru_write_memory(PRUSS0_PRU0_DATARAM, 0, ddrstartData, sizeof(ddrstartData));
	
	
}
Example #8
0
int main (void)
{
   if(getuid()!=0){
      printf("You must run this program as root. Exiting.\n");
      exit(EXIT_FAILURE);
   }
   // Initialize structure used by prussdrv_pruintc_intc
   // PRUSS_INTC_INITDATA is found in pruss_intc_mapping.h
   tpruss_intc_initdata pruss_intc_initdata = PRUSS_INTC_INITDATA;

   // Read in the location and address of the shared memory. This value changes
   // each time a new block of memory is allocated.
   unsigned int values[2];
   values[0] = readFileValue(MMAP_LOC "addr");
   values[1] = readFileValue(MMAP_LOC "size");
   printf("The shared memory has location: %x and size %x\n", values[0], values[1]);

   // Allocate and initialize memory
   prussdrv_init ();
   prussdrv_open (PRU_EVTOUT_0);

   // Write the address and size into PRU0 Data RAM0. You can edit the value to
   // PRUSS0_PRU1_DATARAM if you wish to write to PRU1
   prussdrv_pru_write_memory(PRUSS0_PRU0_DATARAM, 0, values, 8);

   // Map PRU's interrupts
   prussdrv_pruintc_init(&pruss_intc_initdata);

   // Load and execute the PRU program on the PRU
   prussdrv_exec_program (PRU_NUM, "./memExample.bin");

   // Wait for event completion from PRU, returns the PRU_EVTOUT_0 number
   int n = prussdrv_pru_wait_event (PRU_EVTOUT_0);
   printf("EBB PRU program completed, event number %d.\n", n);

   // Disable PRU and close memory mappings
   prussdrv_pru_disable(PRU_NUM);
   prussdrv_exit ();
   return EXIT_SUCCESS;
}
Example #9
0
int init_pru_motion_queue(struct MotionQueue *queue) {
  if (!map_gpio()) {
    fprintf(stderr, "Couldn't mmap() GPIO ranges.\n");
    return 1;
  }

  // Prepare all the pins we need for output. All the other bits are inputs,
  // so the STOP switch bits are automatically prepared for input.
  gpio_0[GPIO_OE/4] = ~(MOTOR_OUT_BITS | (1 << AUX_1_BIT) | (1 << AUX_2_BIT));
  gpio_1[GPIO_OE/4] = ~(DIRECTION_OUT_BITS | (1 << MOTOR_ENABLE_GPIO1_BIT));

  pru_motor_enable_nowait(0);  // motors off initially.

  tpruss_intc_initdata pruss_intc_initdata = PRUSS_INTC_INITDATA;
  prussdrv_init();

  /* Get the interrupt initialized */
  int ret = prussdrv_open(PRU_EVTOUT_0);  // allow access.
  if (ret) {
    fprintf(stderr, "prussdrv_open() failed (%d)\n", ret);
    return ret;
  }
  prussdrv_pruintc_init(&pruss_intc_initdata);
  if (map_pru_communication() == NULL) {
    fprintf(stderr, "Couldn't map PRU memory for queue.\n");
    return 1;
  }

  prussdrv_pru_write_memory(PRUSS0_PRU0_IRAM, 0, PRUcode, sizeof(PRUcode));
  prussdrv_pru_enable(0);

  // Initialize operations.
  queue->enqueue = &pru_enqueue_segment;
  queue->wait_queue_empty = &pru_wait_queue_empty;
  queue->motor_enable = &pru_motor_enable_nowait;
  queue->shutdown = &pru_shutdown;
 
  return 0;
}
Example #10
0
int main (void)
{
   if(getuid()!=0){
      printf("You must run this program as root. Exiting.\n");
      exit(EXIT_FAILURE);
   }
   // Initialize structure used by prussdrv_pruintc_intc
   // PRUSS_INTC_INITDATA is found in pruss_intc_mapping.h
   tpruss_intc_initdata pruss_intc_initdata = PRUSS_INTC_INITDATA;

   // Read in the location and address of the shared memory. This value changes
   // each time a new block of memory is allocated.
   unsigned int values[2];
   values[0] = FREQ_1MHz;
   values[1] = RUNNING;
   printf("The clock state is set as period: %d (0x%x) and state: %d\n", values[0], values[0], values[1]);
   printf("This is mapped at the base address: %x\n", readFileValue(MMAP_LOC "addr"));

   // Allocate and initialize memory
   prussdrv_init ();
   prussdrv_open (PRU_EVTOUT_0);

   // Write the address and size into PRU0 Data RAM0. You can edit the value to
   // PRUSS0_PRU1_DATARAM if you wish to write to PRU1
   prussdrv_pru_write_memory(PRUSS0_PRU0_DATARAM, 0, values, 8);

   // Map PRU's interrupts
   prussdrv_pruintc_init(&pruss_intc_initdata);

   // Load and execute the PRU program on the PRU
   prussdrv_exec_program (PRU_NUM, "./PRUClock.bin");
   printf("EBB Clock PRU program now running (%d)\n", values[0]);

   prussdrv_exit ();
   return EXIT_SUCCESS;
}
Example #11
0
   int main (void)
   {
	//Variables for sinusoidal data
	double freq = 367;
	double omega = 2*M_PI*freq;
	double sampleRate = 133333.3333333333;
	int samples = (int)(sampleRate/freq);
    	unsigned int pwms[2000];
	int i;
	FILE *fp;	

	//Initialize all 0s
	for(i=0; i<2000; i++){
		pwms[i] = 0;
	}

	//Eports GPIO0_7
	if ((fp=fopen("/sys/class/gpio/export", "w"))==NULL){
		printf("Cannot open File\n");
		return(1);
	}
	fprintf(fp,"7");
	fclose(fp);

	//Enables GPIO0_7 for output
	if ((fp=fopen("/sys/class/gpio/gpio7/direction", "w"))==NULL){
		printf("Cannot open File\n");
		return(1);
	}
	fprintf(fp,"out");
	fclose(fp);

	//Creates the sinusoid data to be pushed into the PRU's memory. (DO NOT USE BELOW 67 HZ)
	//There is not enough memory on the PRU
	
	pwms[0] = (samples+1)*4;	

	for(i=1; i<=samples;i++){
		if(i < 2000){
			pwms[i] = 250+(int)(25*sin(omega*(i-1)/sampleRate));
		}
	}

	/* Initialize structure used by prussdrv_pruintc_intc   
	   PRUSS_INTC_INITDATA is found in pruss_intc_mapping.h */
	tpruss_intc_initdata pruss_intc_initdata = PRUSS_INTC_INITDATA;

	/* Allocate and initialize memory */
	prussdrv_init();       
	prussdrv_open(PRU_EVTOUT_0);
 
	/* Map PRU's INTC */
	prussdrv_pruintc_init(&pruss_intc_initdata);

	/* load array on PRU */
	prussdrv_pru_write_memory(PRUSS0_PRU0_DATARAM, 0, pwms, sizeof(unsigned int)*(samples+1));

	/* Load and execute binary on PRU */
	prussdrv_exec_program(PRU_NUM, "./gpio_pw_sin.bin");

	printf("Frequency=%f\n",freq);
	fflush(stdout);
	scanf("%lf", &freq);
	if(freq < 67){
		printf("Frequency: %f is too low. Enter a number higher than 67\n", freq);
		freq = 67;
	}
	printf("Frequency=%f\n",freq);
	fflush(stdout);

	while(1){
		if(freq >=67){
			omega = 2*M_PI*freq;
			samples = (int)(sampleRate/freq);
			pwms[0] = (samples+1)*4;
			for(i=1; i<=samples;i++){
				if(i < 2000){
					pwms[i] = 250+(int)(25*sin(omega*(i-1)/sampleRate));
				}
			}
			
			/* load array on PRU */
			prussdrv_pru_write_memory(PRUSS0_PRU0_DATARAM, 0, pwms, sizeof(unsigned int)*(samples+1));
	
			/* Load and execute binary on PRU */
			prussdrv_exec_program(PRU_NUM, "./gpio_pw_sin.bin");
			
		}
		scanf("%lf", &freq);
		if(freq < 67){
			printf("Frequency: %f is too low. Enter a number higher than 67\n", freq);
			freq = 67;
		}
		printf("Frequency=%f\n",freq);
		fflush(stdout);	
	}
	/* Wait for event completion from PRU */
	prussdrv_pru_wait_event (PRU_EVTOUT_0);  // This assumes the PRU generates an interrupt
                                                // connected to event out 0 immediately before halting
  
	/* Disable PRU and close memory mappings */
	prussdrv_pru_disable(PRU_NUM);
	prussdrv_exit ();

	return(0);
    }