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:
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