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); }
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 (); }
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; }
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; }
/*! \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; }
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)); }
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; }
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; }
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; }
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); }