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.

AM625: Need help understanding __xin() and __xout() usage and operation

Part Number: AM625

Tool/software:

Hi all,

I want to use the XFR2VBUS on the AM625 and used the AM62 TRM to try and understand as well as a number of insights from the question on the link below:

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1169066/sk-am64-follow-up-question-how-to-read-write-data-with-the-pru_icssg-xfr2vbus-hardware-accelerator/4401798?tisearch=e2e-sitesearch&keymatch=PRU%252520__xin#4401798

Based on the above I created this sample program:

/*
 * Copyright (c) 2015, 2016, 2022, 2024 Vorne Industries, Inc.
 * All rights reserved.
 */

#include <stdint.h>
#include <pru_cfg.h>
#include <pru_ctrl.h>
#include <pru_iep.h>
#include <pru_intc.h>

volatile register uint32_t __R30;

#define BIT(n) (1u<<n)

static inline void set_clk_l()
{
    __R30 &= ~BIT(6); // shows up on pin #3 of LGS on the EVK
}

static inline void set_clk_h()
{
    __R30 |= BIT(6); // shows up on pin #3 of LGS on the EVK
}


static inline void nop1()
{
    __R30 |= BIT(31);
}

static inline void nop10()
{
    nop1();
    nop1();
    nop1();
    nop1();
    nop1();
    nop1();
    nop1();
    nop1();
    nop1();
    nop1();
}


static inline void nop30()
{
    nop10();
    nop10();
    nop10();
}


#define XFR_RD_ID0  0x60
#define XFR_RD_ID1  0x61
#define XFR_WR_ID0  0x62


#define XFR_SIZE_4B (0)
#define XFR_SIZE_32B (2<<1)
#define XFR_SIZE_64B (3<<1)

#define XFR_REG_RD_BUSY 18
#define XFR_REG_WR_BUSY 20
#define XFR_REG_DATA    2

#define XFR_MASK_RD_BUSY 0x1
#define XFR_MASK_WR_BUSY 0x1

#define NO_REMAPPING 0

#define DDR_ADDR_IN (0x9c600000ull)
#define DDR_ADDR_OUT (0x9c600020ull)

typedef union {
    uint8_t byte[32];
    struct {
        uint64_t r2r3;
        uint64_t r4r5;
        uint64_t r6r7;
        uint64_t r8r9;
    } regs;
} PAYLOAD;

typedef struct {
    PAYLOAD data;
    uint64_t addr; // R10, R11
} DATA_PACKET;

DATA_PACKET pkt_tmp;
PAYLOAD data;

void test_xfr()
{
    nop30();
    nop30();
    nop30();
    uint32_t busy_status;

    busy_status = 1;
    // This loop seems to hang forever
    while ( (busy_status&XFR_MASK_RD_BUSY)==XFR_MASK_RD_BUSY ) {
        __xin(XFR_RD_ID0,XFR_REG_RD_BUSY,NO_REMAPPING,busy_status);
    }

    uint64_t cmd = (DDR_ADDR_IN<<32) | XFR_SIZE_32B;
    __xout(XFR_RD_ID0,XFR_REG_RD_BUSY,NO_REMAPPING,cmd);

    do {
        __xin(XFR_RD_ID0, XFR_REG_RD_BUSY, NO_REMAPPING, busy_status );
    } while ( !(busy_status&BIT(0)) || busy_status&BIT(2) );

    __xin(XFR_RD_ID0, XFR_REG_DATA, NO_REMAPPING, data );

    pkt_tmp.data.regs = data.regs;
    pkt_tmp.addr = DDR_ADDR_OUT;
    do {
        __xout(XFR_WR_ID0, XFR_REG_WR_BUSY, NO_REMAPPING, busy_status);
    } while ( busy_status&BIT(0) );

    __xout(XFR_WR_ID0, XFR_REG_DATA, NO_REMAPPING, pkt_tmp);

    do {
        __xout(XFR_WR_ID0, XFR_REG_WR_BUSY, NO_REMAPPING, busy_status);
    }  while ( busy_status&BIT(0) );
}

int main()
{
    while(1) {
        set_clk_h();
        test_xfr();
        set_clk_l();
        test_xfr();
    }
}

And compiled it. The goal is to copy a chunk of 32 bytes from `0x9c600000` into `0x9c600020`, which is configured through the device tree as a reserved memory region in DDR.

I'd expect one GPO to toggle at each execution of this test but instead the signal doesn't switch at all.

Out of curiosity, I added an infinite loop (SET_H/SET_L) immediately before the first __xin loop (in place of the `// This loop seems to hang forever` comment). With this change I can see the output signal switching.

So it seems that something causes the PRU to hang, or enter an infinite loop if it is allowed to proceed from that point forward.

The clpru compilation flags are: `-O0 --opt_for_speed=1 --auto_inline -v3`.

Some of the operations above were inferred from the linked question, as the AM62 TRM doesn't seem to include the equivalent to Table 6-73 (Read Commands) to describe the write commands. Are these, by any chance not supported on the AM62 PRU?

Any help getting this code to work would be greatly appreciated.

Best regards,

António

  • Hello António,

    Things are still wild on my end, so I am passing your thread to another team member to work with you on this topic.

    In the meantime, we have put out additional training on using the broadside interface on the AM243x/AM64x. You can think of this like the "rough draft" of the content that we are working on for the upcoming PRU academy: https://git.ti.com/cgit/pru-software-support-package/pru-software-support-package/tree/examples/am243x

    Could I get you to take a look and let us know if it helps? There is a PDF document in addition to the Ultrafast_broadside example project.

    We want to add AM62x-specific broadside documentation in addition to migrating the existing AM243x/AM64x documentation, so any feedback you have is appreciated. We already have your PRU core clock thread listed as a reference for our core frequency section.

    Regards,

    Nick

  • Hi Nick,

    Sorry for the delay, only today I had a chance to have a look at the materials you linked to. I had a look at the PDF and assembly example but I'm not sure what to make of the "For C code implementation using broadside accelerator a register context save and restore is required.". 

    The topic, though, seems extremely relevant and there are things I'd like to find, such as:

    • The available broadside IDs available on the SoC, listed in the TRM. Something along the lines of the Broadside Functions table that is present on the PDF that you referred to
    • Example on how to use the XFR2VBUS accelerator from C code to speed up transfers to and from the DDR

    The PRU has its intricacies but can be very useful if we have examples to draw from and quickly put something up that works without extensive reading and trial-and-error. Unfortunately the combination of the TRM and the pru-c-compiler (or assembler), most often than not, takes us to the rabbit hole of trial and error because some things are not obvious and difficult to guess (my opinion, anyway :) )

    Would it be possible to have an idea of why my example seems to hang forever on the first __xin? I tried placing setting it between a pair of set_clk_h/set_clk_l and my GPO isn't toggling at all if I run that code [EDIT: this is not true. It **does** toggle!]. It does toggle immediately before the loop.

    From the original question this code seemed to have the potential to work, but something eludes me that causes my test to fail.

    Thanks for the inputs. If you need anything more specific from me, please just let me know.

    Best regards,

    António

  • Hi António,

    Would it be possible to have an idea of why my example seems to hang forever on the first __xin? I tried placing setting it between a pair of set_clk_h/set_clk_l and my GPO isn't toggling at all if I run that code. It does toggle immediately before the loop.

    Do you mean on running the code with this modification you see the signal become high but it doesn't go low? Does placing the infinite loop (SET_H/SET_L) right after the first __xin leads to that loop not getting executed at all?

    As per the TRM, your code for performing the read operation seems correct so I do not expect it to get stuck in the first __xin loop.

    However, the TRM does mention the availability of only 2 XFR2VBUS RX threads which could lead to issues with the write operations in your code. I will double check this internally with the team and get back to you.

      

    Regards,

    Nitika

  • Hi Nikita, thanks for your feedback.

    Oops, I'm glad you asked that Sweat smile

    I must've missed something moments ago... Indeed, if I place the __xin() between set_clk_h/set_clk_l calls (as shown below), the GPO **DOES** toggle. Sorry for my misleading information.

        // This loop seems to hang forever
        while ( (busy_status&XFR_MASK_RD_BUSY)==XFR_MASK_RD_BUSY ) {
            set_clk_h();
            __xin(XFR_RD_ID0,XFR_REG_RD_BUSY,NO_REMAPPING,busy_status);
            set_clk_l();
        }

    So, the PRU is running, the gpo is toggling but it seems that the busy flag never clears or my code is buggy.

    The PDF linked to by Nick suggests that using the broadside from C has conflicts on some registers:

    There is a collision with C compiler which uses R2, R14, R15 for stack pointer and function call arguments. Therefore these examples are using assembler coding. For C code implementation using broadside accelerator a register context save and restore is required.

    I wonder is this is somehow related with my issue.

    I'm also unsure of whether the broadside IDs I'm using are wrong. The information is a bit hard to follow in this regard, on the AM62 TRM.

    The second PRU is stopped, so I'm pretty sure that only one XFR is active. At the very least, if we can get execution to get past the first read, I'd be already happy and could then focus on debugging any potential issue with the write that follows.

    Best regards,

    António

  • Hi António,

    The IDs and register you are using is correct as per the TRM.

    I tried the below simplified version of your code on my setup with SBL_NULL and loading via CCS for testing. I believe it is working as expected.  

    /*
     * Copyright (C) 2025 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.
     */
    
    
    /*
     * main.c
     */
    
    #include <stdint.h>
    
    volatile register uint32_t __R30;
    volatile register uint32_t __R31;
    
    #define BIT(n) (1u<<n)
    
    #define XFR_RD_ID0  0x60
    #define XFR_RD_ID1  0x61
    
    #define XFR_SIZE_32B (2<<1)
    #define XFR_SIZE_64B (3<<1)
    
    #define XFR_MASK_RD_BUSY 0x1
    #define XFR_REG_RD_BUSY 18
    #define XFR_REG_DATA    2
    
    #define NO_REMAPPING 0
    
    #define DDR_ADDR_IN (0x9c600000ull)
    #define DDR_ADDR_OUT (0x9c600020ull)
    
    /*
     * These structs (datagram_type) and (container_type) force the compiler to align data 64bit-wise.
     * This is necessary in order to use it with the xfr2vbus
     * accelerators
     *  */
    
    struct datagram_type{
        uint64_t r2and3; //data
        uint64_t r4and5; //data
        uint64_t r6and7; //data
        uint64_t r8and9; //data
        uint64_t r10and11; //addr
    };
    
    struct container_type{
        uint64_t r2and3; //data
        uint64_t r4and5; //data
        uint64_t r6and7; //data
        uint64_t r8and9; //data
      };
    
    typedef union package{
        struct datagram_type datagram;
        uint8_t bytes[sizeof(struct datagram_type)];
    }frame;
    
    typedef union package_wo_addr{
        struct container_type datagram;
        uint8_t bytes[sizeof(struct container_type)];
    }frame_wo_addr;
    frame_wo_addr data_2_read;
    
    static inline void nop1()
    {
        __R30 |= BIT(31);
    }
    
    void main(void)
    {
        uint32_t busy_status;
    
        busy_status = 1;
        /* Wait RD_BUSY = 0h */
        while ( (busy_status&XFR_MASK_RD_BUSY)== XFR_MASK_RD_BUSY) {
            __xin(XFR_RD_ID0,XFR_REG_RD_BUSY,NO_REMAPPING,busy_status);
        }
    
        /* XOUT R18 (configure RD_AUTO/ RD_SIZE); */
        uint64_t cmd = (DDR_ADDR_IN<<32) | XFR_SIZE_32B;
        __xout(XFR_RD_ID0,XFR_REG_RD_BUSY,NO_REMAPPING,cmd);
    
        /* Wait WR_BUSY = 0h OR RD_DATA_FL = 1h */
        busy_status  = 1;
        while((busy_status & 0xF) != 0x05)
        {
            __xin(XFR_RD_ID0, XFR_REG_RD_BUSY, NO_REMAPPING, busy_status);
        }
    
        /* XIN RD_DATA */
        __xin(XFR_RD_ID0, XFR_REG_DATA, NO_REMAPPING, data_2_read );
        /* end read procedure */
    
        while(1) {
            nop1();
        }
    
    }
    

    Memory location (values manually modified from CCS):

    R2-R9 PRU register values after read:

    Currently I don't have an answer as to why it is not working for you. Can you look at the above information and let me know if anything helps.

    Regards,

    Nitika

  • Humm, thanks for going through all the trouble to test it yourself.

    I'm going to return to this setup soon and have another go. I wonder if, similar to the GPO what wasn't toggling, I might have missed something when I tested this firmware.

    Best regards,

    António

  • Well, that didn't work for me. From my observation, the gpo I'm driving just keeps toggling, meaning we don't get past the first check for the busy flag.

    The project where I was exploring this took a turn away from the need to use XFR2VBUS. So, while it's not a big deal that I didn't get it to work, I'd surely like to see it in action, even for the sake of understanding how to do it from C with clpru.

    I'll see if I can find some time to create a minimal example that I can share here (sources, Makefile, etc) which might help anyone spot what's missing more easily.

    Also, I wonder if there's anything from the host processor side, whether at the device tree level, kernel config, etc that needs to be ensured to enable this test to run.

    All the best,

    António

  • OK,  here's what I know so far:

    This code appears to do _something_, even if it's not what I want:

    /*
     * Copyright (c) 2015, 2016, 2022, 2024 Vorne Industries, Inc.
     * All rights reserved.
     */
    
    #include <stdint.h>
    #include <pru_cfg.h>
    #include <pru_ctrl.h>
    #include <pru_intc.h>
    
    volatile register uint32_t __R30;
    
    #define BIT(n) (1u<<n)
    
    static inline void set_clk_l()
    {
        __R30 &= ~BIT(6); // shows up on pin #3 of LGS on the EVK
    }
    
    static inline void set_clk_h()
    {
        __R30 |= BIT(6); // shows up on pin #3 of LGS on the EVK
    }
    
    static inline void toggle_clk()
    {
        __R30 ^= BIT(6);
    }
    
    #define XFR_RD_ID0  0x60
    #define XFR_RD_ID1  0x61
    #define XFR_WR_ID0  0x62
    #define XFR_WR_ID1  0x63
    
    
    #define XFR_SIZE_4B (0)
    #define XFR_SIZE_32B (2<<1)
    #define XFR_SIZE_64B (3<<1)
    
    #define XFR_REG_RD_BUSY 18
    #define XFR_REG_WR_BUSY 20
    #define XFR_REG_DATA    2
    
    #define XFR_MASK_RD_BUSY 0x1
    #define XFR_MASK_WR_BUSY 0x1
    
    #define NO_REMAPPING 0
    
    #define DDR_ADDR_IN (0x9c600000ull)
    #define DDR_ADDR_OUT (0x9c600020ull)
    
    typedef union {
        uint8_t byte[32];
        struct {
            uint64_t r2r3;
            uint64_t r4r5;
            uint64_t r6r7;
            uint64_t r8r9;
        } regs;
    } PAYLOAD;
    
    typedef struct {
        PAYLOAD data;
        uint64_t addr; // R10, R11
    } DATA_PACKET;
    
    DATA_PACKET pkt_tmp;
    PAYLOAD data;
    
    
    int main()
    {
        set_clk_l();
    
        uint32_t busy_status;
    
        busy_status = 1;
        // This loop seems to hang forever
        while ( (busy_status&XFR_MASK_RD_BUSY)==XFR_MASK_RD_BUSY ) {
            toggle_clk();
            __xin(XFR_RD_ID0,XFR_REG_RD_BUSY,NO_REMAPPING,busy_status);
        }
    
        set_clk_h();
        set_clk_h();
        set_clk_l();
        set_clk_l();
    
        uint64_t cmd = (DDR_ADDR_IN<<32) | XFR_SIZE_32B;
        __xout(XFR_RD_ID0,XFR_REG_RD_BUSY,NO_REMAPPING,cmd);
    
        set_clk_h();
        set_clk_h();
        set_clk_l();
        set_clk_l();
    
        do {
            __xin(XFR_RD_ID0, XFR_REG_RD_BUSY, NO_REMAPPING, busy_status );
        } while ( !(busy_status&BIT(0)) );
    
        set_clk_h();
        set_clk_h();
        set_clk_l();
        set_clk_l();
    
        __xin(XFR_RD_ID0, XFR_REG_DATA, NO_REMAPPING, data );
    
        do {
            __xin(XFR_RD_ID0, XFR_REG_RD_BUSY, NO_REMAPPING, busy_status );
        } while ( !(busy_status&BIT(0)) || busy_status&BIT(2) );
    
        set_clk_h();
        set_clk_h();
        set_clk_l();
        set_clk_l();
    
        uint32_t *dest = (uint32_t *)DDR_ADDR_OUT;
        dest[0] = data.regs.r2r3>>32;
        dest[1] = data.regs.r2r3&0xffffffff;
        dest[2] = data.regs.r4r5>>32;
        dest[3] = data.regs.r4r5&0xffffffff;
        dest[4] = data.regs.r6r7>>32;
        dest[5] = data.regs.r6r7&0xffffffff;
        dest[6] = data.regs.r8r9>>32;
        dest[7] = data.regs.r8r9&0xffffffff;
    }

     I found out in the meantime that:

    * If my board came from a power cycle or reboot that code runs and I can see 4 pulses on the scope.

    * If put something in the 0x9c600000 to 0x9c60001f memory region (it's reserved memory through the devicetree) before running the code, I'd expect something resembling the original data popping up on 0x9c600020 to 0x9c60003f, but all I get is zeroes.

    * If I try to run the same code again without a power cycle or reboot, the PRU seems stuck at the first wait loop (the GPO keeps toggling).

    So it seems I may be doing something wront with the data movement itself and on the operation of the XFR2VBUS as well.

    For reference, this is how I built the firmware:

    clpru --define=AM62X --include_path=/home/amsobr/Apps/pru-bsp//include/am62x --include_path=/home/amsobr/Apps/ti-cgt-pru-2.3.3//include -O0 --opt_for_speed=0 --auto_inline -v3 --endian=little --hardware_mac=on xfr-test.c
    clpru --run_linker --rom_model -i/home/amsobr/Apps/ti-cgt-pru-2.3.3//lib --reread_libs -oxfr-test.bin xfr-test.obj

    The linker scipt:

    -cr
    -stack 0x400
    -heap 0x200
    
    MEMORY
    {
    	PAGE 0:
    	PRUIMEM		: org = 0x00000000 len = 0x00004000  /* 16kB PRU Instruction RAM */
    
    	PAGE 1:
    	PRUDMEM		: org = 0x00000000 len = 0x00002000  /* 8kB PRU Data RAM 0 */
    
    	PAGE 2:
    	SHAREDMEM	: org = 0x00010000 len = 0x00008000  /* 32kB Shared RAM */
    	PRU0_CTRL	: org = 0x00022000 len = 0x00000030
    	PRU1_CTRL	: org = 0x00024000 len = 0x00000030
    
    	/* Constant Table Memory directives. */
    
    	PRU_INTC	: org = 0x00020000 len = 0x00001504	CREGISTER=0
    	DMTIMER2	: org = 0x48040000 len = 0x00000100	CREGISTER=1
    	I2C1		: org = 0x4802A000 len = 0x00000100	CREGISTER=2
    	PRU_ECAP	: org = 0x00030000 len = 0x00000100	CREGISTER=3
    	PRU_CFG		: org = 0x00026000 len = 0x00000100	CREGISTER=4
    	MMCHS0		: org = 0x48060000 len = 0x00000100	CREGISTER=5
    	MCSPI0		: org = 0x48030000 len = 0x00000100	CREGISTER=6
    	PRU_UART0	: org = 0x00028000 len = 0x00000100	CREGISTER=7
    	MCASP0_DMA	: org = 0x46000000 len = 0x00000100	CREGISTER=8
    	GEMAC		: org = 0x4A100000 len = 0x00000100	CREGISTER=9
    	RSVD10		: org = 0x48318000 len = 0x00000100	CREGISTER=10
    	UART1		: org = 0x48022000 len = 0x00000100	CREGISTER=11
    	UART2		: org = 0x48024000 len = 0x00000100	CREGISTER=12
    	RSVD13		: org = 0x48310000 len = 0x00000100	CREGISTER=13
    	DCAN0		: org = 0x481CC000 len = 0x00000100	CREGISTER=14
    	DCAN1		: org = 0x481D0000 len = 0x00000100	CREGISTER=15
    	MCSPI1		: org = 0x481A0000 len = 0x00000100	CREGISTER=16
    	I2C2		: org = 0x4819C000 len = 0x00000100	CREGISTER=17
    	EHRPWM1		: org = 0x48300000 len = 0x00000100	CREGISTER=18
    	EHRPWM2		: org = 0x48302000 len = 0x00000100	CREGISTER=19
    	EHRPWM3		: org = 0x48304000 len = 0x00000100	CREGISTER=20
    	MDIO		: org = 0x00032400 len = 0x00000100	CREGISTER=21
    	MBX0		: org = 0x480C8000 len = 0x00000100	CREGISTER=22
    	SPINLOCK	: org = 0x480CA000 len = 0x00000100	CREGISTER=23
    	PRU_IEP		: org = 0x0002E000 len = 0x0000031C	CREGISTER=26
    	TPCC		: org = 0x49000000 len = 0x000010A0	CREGISTER=29
    	L3OCMC		: org = 0x40000000 len = 0x00010000	CREGISTER=30
    	DDR			: org = 0x80000000 len = 0x00010000	CREGISTER=31
    }
    
    SECTIONS {
    	.text		>  PRUIMEM, PAGE 0
    
    	.stack		>  PRUDMEM, PAGE 1
    	.bss		>  PRUDMEM, PAGE 1
    	.cio		>  PRUDMEM, PAGE 1
    	.data		>  PRUDMEM, PAGE 1
    	.switch		>  PRUDMEM, PAGE 1
    	.sysmem		>  PRUDMEM, PAGE 1
    	.cinit		>  PRUDMEM, PAGE 1
    	.rodata		>  PRUDMEM, PAGE 1
    	.rofardata	>  PRUDMEM, PAGE 1
    	.farbss		>  PRUDMEM, PAGE 1
    	.fardata	>  PRUDMEM, PAGE 1
    	.resource_table >  PRUDMEM, PAGE 1
    	.FRAME_BUFFER > SHAREDMEM, PAGE 2
    	.PRU0_CTRL	>  PRU0_CTRL, PAGE 2
    	.PRU1_CTRL	>  PRU1_CTRL, PAGE 2
    }
    

    And the reserved memory block on the device tree:

    	reserved-memory {
    		#address-cells = <2>;
    		#size-cells = <2>;
    		ranges;
    
    		rsvd-pru@0x9c600000 {
    			reg = <0x00000000 0x9c600000 0x000000 0x00100000>;
    		};
        };

    Thanks for the patience, even it it's unlikely that we'll be using the XFR2VBUS in our firmware, it might be useful to understand the quircks of using it from C code and, hopefully, integrate it as an example on the pru-support-package examples.

    To be clear, it's not an urgent topic for me at the moment and I can help trying different things on my setup to figure this out, for the sake of better understanding how these things work.

    Best regards,

    António

  • Hi António,

    I believe the first read is successful in your case and the values read in the first iteration should be updated in registers R2-R9.

    I'd expect something resembling the original data popping up on 0x9c600020 to 0x9c60003f

    As I mentioned above, the AM62x TRM mentions the availability of only 2 XFR2VBUS RX threads which might be why you are not seeing the write getting reflected in the memory.

    I will follow-up with the design team on the reasoning behind this.

    Regards,

    Nitika

  • Hi António,

    The design team confirmed that AM62x PRUSS only supports RX XFR2VBUS. For write, you will not be able to use the XFR2VBUS widget.

    Regards,

    Nitika

  • Hi Nikita, 

    Thanks for taking the time to look into this.

    Best regards,

    António