Karl,
I am trying the similar configuration of programming PRU of AM3359 of
beaglebone black. The ARM OS is QNX and hence I need to write the starter
ware to work under QNX. I have followed the same procedure as specified,
but I am getting into problem in enabling the PRU-ICSS module in
CM_PER_PRU_ICSS_CLKCTRL. After writing a value of 0x02, I still not
getting the module enabled. Before and after setting to 0x02, the value of
the register is 0x40002. I know I am using the correct register since if I
write 0x00, the read back value is 0x70000 which is correct. Is there
anything else to be enabled/checked? I am debugging the code & hence there
is sufficient delay.
Please suggest the reason for this kind of behavior. (I know the card
is working since I have testing PRU using Angstrom, where it works fine!!)
Thanks,
Geetha
On Thursday, November 20, 2014 at 12:14:37 PM UTC+5:30, Karl Karpfen wrote:
>
> There are many information about PRU usage out there but most of them
> expect to have a Linux-system running which initialises PRU. In case
> somebody wants to utilitise it out of a bare-metal or Starterware
> application one is lost in the dark. PRU-registers are documentend in
> AM3358 TRM but creating working code out of these specifications is not an
> easy thing. So after it is working for me I'll provide all information here.
>
> To create the code running on PRU I'm using TI's C-compiler from
> http://software-dl.ti.com/codegen/non-esd/downloads/download.htm#PRU
>
> Compilation of the source-file "main.c" is done by calling
>
> clpru --silicon_version=3 -I/opt/ti/ccsv6/tools/compiler/ti-cgt-pru_2.1.0/
> include/ -I/opt/ti/ccsv6/tools/compiler/ti-cgt-pru_2.1.0/lib/ \
> -o4 --opt_for_speed=5 main.c -z AM3359_PRU.cmd -o PRU_tests.out -m
> PRU_tests.map
>
> This generates an ELF-file PRU_tests.out and a linker map file
> PRU_tests.map which is needed to evaluate the start-address of the PRU-code
> later.
>
> Next split the ELF file into two separate sections for text (read-only,
> executable program code) and data (readable and writable but not
> executable):
>
> hexpru bin.cmd PRU_tests.out
>
> This results in two files text.bin and data.bin which later have to be
> loaded into instruction- and data-RAM of PRU. Now one can start with the
> code running on AM3358 that initialises PRU0. First some definitions are
> necessary that contain register-addresses:
>
> #define HWREG(x) (*((volatile unsigned int *)(x)))
>
> #define CM_PER_PRU_ICSS_CLKCTRL (0x000000E8u) // set to 0x00000002 to
> enable/wake up
>
> #define CM_PER_PRU_ICSS_CLKSTCTRL (0x00000140u) // unset to
> 0x00000002 to enable/wake up
> #define CM_PER_PRU_ICSS_CLKSTCTRL_UART_GCLK (0x00000040u) // activate
> UART clock
> #define CM_PER_PRU_ICSS_CLKSTCTRL_IEP_GCLK (0x00000020u) // activate
> IEP clock
> #define CM_PER_PRU_ICSS_CLKSTCTRL_OCP_GCLK (0x00000010u) // activate
> OCP clock
>
> #define PRU_PHYS_BASE_CTRL 0x0000
>
> #define PRUSS_CFG_BASE_SYSCFG 0x0004
> #define PRUSS_CFG_BASE_GPCFG0 0x0008
> #define PRUSS_CFG_BASE_GPCFG1 0x000C
> #define PRUSS_CFG_BASE_CGR 0x0010
> #define PRUSS_CFG_BASE_PIN_MX 0x0040
> #define PRUSS_CFG_BASE_PMAO 0x0028
>
> And the code that initialises PRU's required clocks, copies text.bin and
> data.bin into related RAM-areas, specifies start-address taken out of MAP
> file and starts the whole thing:
>
> volatile int i=0;
>
> // reset the PRU, this may not be necessary in case of initial start-up
> HWREG(SOC_PRM_PER_REGS)|=0x00000002;
> while ((HWREG(SOC_PRM_PER_REGS) & 0x00000002)==0); //wait until reset
> was done
> HWREG(SOC_PRM_PER_REGS)&=0xFFFFFFFD; // clear reset bit
>
> // wake-up and nebale PRU, enable OCP-clock (mandatory)
> // UART and IEP clock have to be enabled here too when needed
> HWREG(SOC_CM_PER_REGS+CM_PER_PRU_ICSS_CLKCTRL)=0x00000002;
> HWREG(SOC_CM_PER_REGS+CM_PER_PRU_ICSS_CLKSTCTRL)=(
> CM_PER_PRU_ICSS_CLKSTCTRL_OCP_GCLK);
>
> // have a short delay before next step
> while (i<10000)
> {
> i++;
> }
> HWREG(PRUSS_CFG_BASE+PRUSS_CFG_BASE_SYSCFG)=(0x00000005);
> while ((HWREG(PRUSS_CFG_BASE+PRUSS_CFG_BASE_SYSCFG) & 0x00000020)!=0); //
> check wait state bit
>
> // copy text and data into PRU0 instruction and data RAM
> memcpy((void*)PRU0IRAM_PHYS_BASE,(void*)text_bin,sizeof(text_bin));
> memcpy((void*)DATARAM0_PHYS_BASE,(void*)data_bin,sizeof(data_bin));
>
> // set start address and execute
> HWREG(PRU0CONTROL_PHYS_BASE+PRU_PHYS_BASE_CTRL)|=0x04200000; // set
> start address
> HWREG(PRU0CONTROL_PHYS_BASE+PRU_PHYS_BASE_CTRL)|=0x00000002; // execute
>
>
> The delay before writing 0x00000005 into SYSCFG-register is necessary for
> some reason, I don't know if this is a good solution or if there is a
> wait-/ready-bit to be checked somewhere.
>
> The start-address where execution of PRU-code has to begin can be found in
> created MAP-file. There an entry
>
> 00000420 _c_int00_noinit_noargs_noexit
>
> can be found. _c_int00_noinit_noargs_noexit is the entry point for code
> generated with TI's C-compiler and 00000420 is it's address. It has to be
> shifted up by 16 bit and written into CTRL-register.
>
> Any comments, ideas, improvements are welcome! And feel free to use this
> code without any restrictions.
>
>
--
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 [email protected].
For more options, visit https://groups.google.com/d/optout.