Description of the program:
An LED toggles on and off from a set delay time in R2.
A separate C program loads the PRU program, starts the core and then prompts the user for a Time to do a delay. Upon the user entering a time, the c program writes that value to dataram and reads back the mapped memory from the PRU to show.
The PRU loop does a SBBO each time as well as a LBBO for a single R2 . My LBBO call however is not returning the proper value, I am likely using the wrong pointer value.
lbbo r2, r2, 0 ,4 // read 4 bytes from there and store it into r2
After I write from C into shared_int[2], I am not able to load that value from the PRU. Since I stored SBBO from reference point of r0 =0 then I would expect R2 to be starting on the 9th byte over. I tried that too - no go.
PRU program.
`
#include “memparams.hp”
#define CONST_PRUCFG 0xC4
#define CPU_HZ (200 * 1000 * 1000)
//lbco r3, CONST_PRUCFG, 4, 4
.text
.section .init0, “x”
.global __start
__start:
/* Initialize stack pointer. */
ldi sp, %lo(__stack_top)
ldi sp.w2, %hi_rlz(__stack_top)
r2 = 0x0BEBC200 // set r2 to a default of 200,000,000
jmp main
.text
.section .text
main:
// init
ldi r0, 0
ldi r1, 0xffff
ldi r3, 777
ldi r4, 777
ldi r8, 1000
ldi r5, 10000
main_loop:
//Load valeu of PRU data memory in general register r2
//ldi r9, 9 // offset to the start of the third
lbbo r2, r2, 0 ,4
mov r6, r2 // to prove in the c program that data arrived and is correct when displayed R2 should equal R6- debug
sbbo r0, r0, 0 , 48 // copy all 12 registers to memory R0…R11 .
// the goal is for R2 to get set in a C program outside theis assembly. Thus changing the speed of the
// blinking LED - defualt is set to 1 second = 200,000,000 cycles in CPU delay.
// led on
mov r30, r1
ldi r14, %lo( r2/4 )
ldi r14.w2, %hi_rlz(r2/4)
call delay_n2_cycles
// led off
mov r30, r0
ldi r14, %lo(r2/4)
ldi r14.w2, %hi_rlz(r2/4 )
call delay_n2_cycles
jmp main_loop
delay_n2_cycles:
sub r14, r14, 1
qbne delay_n2_cycles, r14, 0
ret
my_resource_table:
.word 1, 0, 0, 0 /* struct resource_table base /
.word 0 / uint32_t offset[1] */
`
C program
`
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <err.h>
#include <sys/mman.h>
#include <libelf.h>
#include “prussdrv.h”
#include “pruss_intc_mapping.h”
#define AM33XX_PRUSS_IRAM_SIZE 8192
#define AM33XX_PRUSS_DRAM_SIZE 8192
#define PRU_NUM 0
#define ADDEND1 0x98765400u
#define ADDEND2 0x12345678u
#define ADDEND3 0x10210210u
#define LOOPS 30
#define DDR_BASEADDR 0x80000000
#define OFFSET_DDR 0x00001000
#define OFFSET_SHAREDRAM 0x00000000 //equivalent with 0x00002000
#define PRUSS0_SHARED_DATARAM 4
static int LOCAL_exampleInit ( );
static unsigned short LOCAL_examplePassed ( unsigned short pruNum, unsigned int millis );
static int mem_fd;
static void *ddrMem, *sharedMem;
static unsigned int *sharedMem_int;
static int counter ;
int main (int argc, char *argv[])
{
counter = 0 ;
tpruss_intc_initdata pruss_intc_initdata = PRUSS_INTC_INITDATA;
int ret;
printf(“Initializing the PRUs…\n”);
prussdrv_init();
/* Open PRU Interrupt */
ret = prussdrv_open(PRU_EVTOUT_0);
if (ret)
errx(EXIT_FAILURE, “prussdrv_open open failed\n”);
/* Get the interrupt initialized */
prussdrv_pruintc_init(&pruss_intc_initdata);
printf("\tINFO: Initializing example. - Writing Data to Local CPU DDR Ram \r\n");
LOCAL_exampleInit(PRU_NUM);
printf(“Starting …\n”);
prussdrv_pru_enable(0);
prussdrv_pru_enable(1);
unsigned int blinkySpeed = 1000;
while (counter < LOOPS){
printf(“Please Enter a blinky speed in milliseconds:”);
scanf("%d" , &blinkySpeed );
LOCAL_examplePassed(PRU_NUM, blinkySpeed );
//usleep(5 * 1000 * 1000);
counter = counter + 1;
}
fflush(stdout);
/* Disable PRU and close memory mapping*/
prussdrv_pru_disable(PRU_NUM);
//munmap(ddrMem, 0x0FFFFFFF);
//close(mem_fd);
prussdrv_exit();
printf(“Program done.\n”);
return EXIT_SUCCESS;
}
static int LOCAL_exampleInit ( )
{
void *DDR_regaddr1, *DDR_regaddr2, *DDR_regaddr3;
/* open the device */
mem_fd = open("/dev/mem", O_RDWR);
if (mem_fd < 0) {
printf(“Failed to open /dev/mem (%s)\n”, strerror(errno));
return -1;
}
/* map the DDR memory */
ddrMem = mmap(0, 0x0FFFFFFF, PROT_WRITE | PROT_READ, MAP_SHARED, mem_fd, DDR_BASEADDR);
if (ddrMem == NULL) {
printf(“Failed to map the device (%s)\n”, strerror(errno));
close(mem_fd);
return -1;
}
/* Store Addends in DDR memory location */
DDR_regaddr1 = ddrMem + OFFSET_DDR;
DDR_regaddr2 = ddrMem + OFFSET_DDR + 0x00000004;
DDR_regaddr3 = ddrMem + OFFSET_DDR + 0x00000008;
(unsigned long) DDR_regaddr1 = ADDEND1;
(unsigned long) DDR_regaddr2 = ADDEND2;
(unsigned long) DDR_regaddr3 = ADDEND3;
return(0);
}
static unsigned short LOCAL_examplePassed ( unsigned short pruNum, unsigned int millis )
{
unsigned int result_0, result_1, result_2, result_3,result_4,result_5,result_6,result_7,result_8,result_9,result_10,result_11;
/* Allocate PRU Dataram memory. /
prussdrv_map_prumem(PRUSS0_PRU0_DATARAM, &sharedMem);
sharedMem_int = (unsigned int) sharedMem;
// set R2 which hold our delay valy for the blinky action in the pru
sharedMem_int[2] = (millis * 1000 * 200);
// read all the current data ram fields in
result_0 = sharedMem_int[ 0];
result_1 = sharedMem_int[ 1];
result_2 = sharedMem_int[ 2];
result_3 = sharedMem_int[ 3];
result_4 = sharedMem_int[ 4];
result_5 = sharedMem_int[ 5];
result_6 = sharedMem_int[ 6];
result_7 = sharedMem_int[ 7];
result_8 = sharedMem_int[ 8];
result_9 = sharedMem_int[ 9];
result_10 = sharedMem_int[ 10];
result_11 = sharedMem_int[ 11];
printf("-------------------------------------\n");
//printf("%p\n", (void *) &sharedMem_int[0]);
printf("value R0 = %d\n ", result_0);
printf(“value R1 = %d\n”, result_1);
printf(“value R2 = %d\n”, result_2);
printf("value R3 = %d\n ", result_3);
printf(“value R4 = %d\n”, result_4);
printf(“value R5 = %d\n”, result_5);
printf("value R6 = %d\n ", result_6);
printf(“value R7 = %d\n”, result_7);
printf(“value R8 = %d\n”, result_8);
printf("value R9 = %d\n ", result_9);
printf(“value R10 = %d\n”, result_10);
printf(“value R11 = %d\n”, result_11);
//return ((result_0 == ADDEND1) & (result_1 == ADDEND2) & (result_2 == ADDEND3)) ;
return 1;
}
`
Here is the pru program