This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[FAQ] PROCESSOR-SDK-AM64X: Accessing DDR from PRU-ICSSG

Part Number: PROCESSOR-SDK-AM64X
Other Parts Discussed in Thread: SYSCONFIG

Hi,

Can you please help me to access DDR from a PRU core?

.

The information in this FAQ applies to all Sitara processors with a PRU_ICSSG: AM24x, AM64x, AM65x. The example was tested on AM64x.

The basic concepts of this FAQ also apply to Sitara processors with other kinds of PRU subsystem:

AM335x, AM437x, AM57x:
For information about how to initialize the PRU core from CCS or from a Linux core, reference the PRU Getting Started Labs. These older PRU-ICSS devices require enabling the OCP port before allowing reads and writes outside of the PRU subsystem. For an example of enabling the OCP port, reference the RPMsg_Echo_Interrupt firmware for the associated device: https://git.ti.com/cgit/pru-software-support-package/pru-software-support-package/tree/examples/am335x/PRU_RPMsg_Echo_Interrupt0/main.c 

AM62x: For information about how to initialize the PRU core from CCS or from a Linux core, reference the PRU Getting Started Labs.

.

For more information on multicore subjects, reference the Sitara multicore development and documentation FAQ.

For more "getting started" information about PRU, including how to initialize the PRU core from CCS or from a Linux core, reference the PRU Getting Started Labs.

  • This example will use the IEP timer to timestamp the memory accesses. However, the PRU_CYCLE register can also be used to count the clock cycles taken by the memory access. For more information about using the PRU_CYCLE register, reference this post

    Prerequisite:

    1. Follow Getting Started Steps (Refer https://software-dl.ti.com/mcu-plus-sdk/esd/AM64X/08_05_00_24/exports/docs/api_guide_am64x/GETTING_STARTED.html)
    2. Import and Build a Hello World example (Refer https://software-dl.ti.com/mcu-plus-sdk/esd/AM64X/latest/exports/docs/api_guide_am64x/GETTING_STARTED_BUILD.html)
      1. Update hello_world.c file as below (Add while(1);) as below
      2. /*
         *  Copyright (C) 2018-2021 Texas Instruments Incorporated
         *
         *  Redistribution and use in source and binary forms, with or without
         *  modification, are permitted provided that the following conditions
         *  are met:
         *
         *    Redistributions of source code must retain the above copyright
         *    notice, this list of conditions and the following disclaimer.
         *
         *    Redistributions in binary form must reproduce the above copyright
         *    notice, this list of conditions and the following disclaimer in the
         *    documentation and/or other materials provided with the
         *    distribution.
         *
         *    Neither the name of Texas Instruments Incorporated nor the names of
         *    its contributors may be used to endorse or promote products derived
         *    from this software without specific prior written permission.
         *
         *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
         *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
         *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
         *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
         *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
         *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
         *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
         *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
         *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
         *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
         *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
         */
         
         
        #include <stdio.h>
        #include <kernel/dpl/DebugP.h>
        #include "ti_drivers_config.h"
        #include "ti_drivers_open_close.h"
        #include "ti_board_open_close.h"
         
        void hello_world_main(void *args)
        {
            /* Open drivers to open the UART driver for console */
            Drivers_open();
            Board_driversOpen();
         
            DebugP_log("Hello World!\r\n");
         
            while(1);
         
            Board_driversClose();
            Drivers_close();
        }
    3. Changes in example.sysconfig
      1. Add PRU instance
      2. update IEP clk value to 500 MHz to get prices timestamping 
    4. Build again
    5. Import and Build CCS project (C:\mcu_plus_sdk\examples\pru_io\empty\firmware\am64x-evm) 
    6. Update main.asm file as below ()
      1. Refer TRM Section 6.4.12 PRU_ICSSG_IEP for IEP timestamping

      2. main.asm file as below
      3. ; Copyright (C) 2022 Texas Instruments Incorporated - http://www.ti.com/
        ;
        ; Redistribution and use in source and binary forms, with or without
        ; modification, are permitted provided that the following conditions
        ; are met:
        ;
        ; Redistributions of source code must retain the above copyright
        ; notice, this list of conditions and the following disclaimer.
        ;
        ; Redistributions in binary form must reproduce the above copyright
        ; notice, this list of conditions and the following disclaimer in the
        ; documentation and/or other materials provided with the
        ; distribution.
        ;
        ; Neither the name of Texas Instruments Incorporated nor the names of
        ; its contributors may be used to endorse or promote products derived
        ; from this software without specific prior written permission.
        ;
        ; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
        ; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
        ; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
        ; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
        ; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        ; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
        ; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
        ; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
        ; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
        ; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
        ; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
         
        ;************************************************************************************
        ;   File:     main.asm
        ;
        ;   Brief:    Template asm file example
        ;************************************************************************************
         
        ; CCS/makefile specific settings
            .retain     ; Required for building .out with assembly file
            .retainrefs ; Required for building .out with assembly file
         
            .global     main
            .sect       ".text"
         
        ;************************************* includes *************************************
        ; icss_constant_defines.inc: Defines symbols corresponding to Constant Table Entries
            .include "icss_constant_defines.inc"
         
            .asg    R2, IEP_CFG_REG
            .asg    R3, IEP_COUNT_REG0
            .asg    R4, IEP_COUNT_REG1
            .asg    R8, TEMP_REG
         
        ;********
        ;* MAIN *
        ;********
         
        main:
         
        init:
        ;----------------------------------------------------------------------------
        ;   Clear the register space
        ;   Before begining with the application, make sure all the registers are set
        ;   to 0. PRU has 32 - 4 byte registers: R0 to R31, with R30 and R31 being special
        ;   registers for output and input respectively.
        ;----------------------------------------------------------------------------
         
        ; Give the starting address and number of bytes to clear.
            zero    &r0, 120
         
        ;----------------------------------------------------------------------------
        ;   Constant Table Entries Configuration
        ;   Sample code to configure Constant Table Entries.
        ;----------------------------------------------------------------------------
         
        ; Configure the Constant Table entry C28 to point to start of shared memory
        ; PRU_ICSSG Shared RAM (local-C28) : 00nn_nn00h, nnnn = c28_pointer[15:0]
        ; By default it is set to 0000_0000h so it will point to DMEM0 address
            ldi     TEMP_REG, 0x0100
            sbco    &TEMP_REG, ICSS_PRU_CTRL_CONST, 0x28, 2
         
        ; Load 32 bit value to TEMP_REG reg
        ; To load values greater than 16 bits, we use ldi32 which performs ldi 2 times
        ; - for lsb 16 bits and then for msb 16 bits
            ldi32   TEMP_REG, 0x12345678
         
         
        ;----------------------------------------------------------------------------
        ;   Reading and Writing latency calculation for DDR from PRU
        ;----------------------------------------------------------------------------
         
            ldi32 R15, 0x80000000 ; DDR base address
            ;ldi R15.w0, 0
            ldi32 R5 ,0x04 ; data to write in DDR
            ldi32 R6, 0x00 ; data to read from DDR
            ldi32 R7, 0x00; counter status
            ldi32 R8, 0x00 ; counter value1
            ldi32 R9, 0x00 ; counter value2
            ldi32 R10, 0x00 ; counter value3
         
        ;----------------------------------------------------------------------------
        ;   Initiaizae IEP
        ;----------------------------------------------------------------------------
         
         ;IEP_CNT_ENABLE
            lbbo R7, ICSS_IEP1_0_CONST, 0, 4
            OR R7, R7, 0x00000001
            sbbo R7, ICSS_IEP1_0_CONST, 0, 4
         
        ;Read IEP_COUNT_REG0
            lbbo R8, ICSS_IEP1_0_CONST, 0x10, 4 ; T0 in ns
         
        ; writing R5 => DDR => R6
            sbbo &R5, R15, 0, 0x02
         
        ;Read IEP_COUNT_REG0
            lbbo R9, ICSS_IEP1_0_CONST, 0x10, 4 ; T1 in ns
         
        ; Reading DDR => R6
            lbbo &R6, R15, 0, 0x02
         
        ;Read IEP_COUNT_REG0
            lbbo R8, ICSS_IEP1_0_CONST, 0x10, 4 ; T2 in ns
         
        ; T1-T0 - 3 PRU_CYCLE = DDR Write Time Latency
         
        ; T2-T1 - 3 PRU_CYCLE = DDR Read Time Latency
         
        ; Write 4 byte register value to DMEM0 at offset 0x14
            sbco    &TEMP_REG, ICSS_DMEM0_CONST, 0x14, 4
         
        ; Write 3 byte register value to DMEM1 at offset 0x10
            sbco    &TEMP_REG, ICSS_DMEM1_CONST, 0x10, 3
         
        ; Write 2 byte register value to SMEM0 at offset 0x22
            sbco    &TEMP_REG, ICSS_SMEM_CONST,  0x22, 2
         
            halt ; end of program
      4. Build again
    7. Assuming OSPI loading method is followed (As this method will take care of initialization of DDR) 
      1. Refer "Flash SOC Initialization Binary" section of "https://software-dl.ti.com/mcu-plus-sdk/esd/AM64X/latest/exports/docs/api_guide_am64x/EVM_SETUP_PAGE.html"
    8. Connect R5F_0_0
    9. Load  binary
    10. Run it
    11. Now, connect and load PRU_0 or PRU_1 as
    12. Load  binary
    13. Add a breakpoint
    14. Run it
    15. Break point will hit
    16. Then, go to menu bar => View => Registers
    17. Check the content of R2 and R4 registers of selected PRU
      1. It should be 0x00000004 

    Best Regards