First of all, you need to enable clock for pruss module. My code is called from the linux driver so I’m doing something like this (removed error checking)
reset = (unsigned int *) ioremap_nocache(RM_PER_RSTCTRL, sizeof(unsigned int));
printk(KERN_INFO “Entering PRUSS reset state.\n”);
*reset=(1<<1);
reg = (unsigned int *) ioremap_nocache(CM_PER_PRUSS_CLKCTRL, sizeof(unsigned int));
*reg = 2;
iounmap(reg);
/* those registers should already have all the bits we need set correctly, however /
/ to make sure nothing goes wrong we set them again. */
reg = (unsigned int *) ioremap_nocache(PM_PER_PWRSTST, sizeof(unsigned int));
*reg = ((3<<23) | (*reg)) ;
iounmap(reg);
reg = (unsigned int *) ioremap_nocache(PM_PER_PWRSTCTRL, sizeof(unsigned int));
*reg = ((3<<5)|(1<<7)|(*reg));
iounmap(reg);
printk(KERN_INFO “Exiting PRUSS reset state.\n”);
*reset=*reset & (~(1<<1));
iounmap(reset);
The registers description can be found in the TRM(I’ve used the same names so ctrl+f should work). As stated in the comment there is no need to change the power registers. If you are trying to access pru from the user space (using some sort of ti provided lib) you may need to modify u-boot to update the pruss clock for you (there are three or four tables with clocks to enable/disable somewhere, but I do not remember in which file). Without it any pru related memory is not accessible.
I’ve created a header file based on the am335x TRM. It contains structure definition describing entire pruss memory (start from pru0 data ram, end with PRU1_iram).
From inside my linux driver i do something like this:
request_mem_region(PRUSS_BASE, sizeof(pruss_mem_t), DRV_NAME) ;
pruss_data = (pruss_mem_t*) ioremap_nocache(PRUSS_BASE, sizeof(pruss_mem_t));
pruss_data->CFG.SYSCFG &= ~ (1<<4);
where PRUSS_BASE is the pruss subsytem memory base from chapter 2.1 of TRM, and pruss_mem_t is the huge (around 250KB) structure based on the 4.3.2 chapter of the TRM. pruss_data->CFG.SYSCFG is the bit mentioned in previous post, without it pru stopped after accessing addresses from the global memory space.
Writing software (memcpy probably also works, but I’m unfamiliar with 8 and 32 bit access stuff, so this for sure is 32 bit access:) ):
for(i=0; i<len; i++)
{
pruss_data->PRU0_iram[i] = data[i];
}
Starting:
pruss_data->PRU0_control.CONTROL |= PRU_CTRL_PRU_ENABLE;
where: PRU0_control is the PRU0 Control at PRUSS_BASE + 0x0002_2000 TRM:4.5.4, PRU_CTRL_PRU_ENABLE = 0x02 (bit 1 - enable TRM: Table 4-26), PRU0_iram - PRUSS_BASE + 0x0003_4000.
Note that this is linux driver code, so you can not access the PRUSS_BASE+ address directly, you have to remap the memory. In my case I remap entire PRUSS memory (pruss_data = (pruss_mem_t*) ioremap_nocache(PRUSS_BASE, sizeof(pruss_mem_t)) so all the offsets stay the same, only the base address changes. From pru assembler there is no memory mapping, so you can access other subsystems directly.
Best regards,
Marek
2012/1/6 Alistair <alistair.lowe@resonance-systems.com>