工具与软件:
大家好!
我想使用 AM625上的 XFR2VBUS、并使用 AM62 TRM 来尝试和理解、以及以下链接中问题的一些见解:
根据上述内容、我创建了此样例程序:
/*
* 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();
}
}
并编译出来。 `是将`0x9c600000 μ s `32个字节的块复制到` 0x9c600020 μ s 中、可通过器件树将其配置为 DDR 中的保留存储器区域。
我希望在每次执行此测试时都有一个 GPO 切换、但信号完全不会切换。
出于好奇心、我在第一个__sin 循环之前立即添加了一个无限循环(SET_H/SET_L)(代替`//这个循环似乎一直挂起`注释)。 完成这一更改后、我可以看到输出信号切换。
看来有些东西会导致 PRU 挂起、或者如果允许它从该点向前继续、就会进入无限循环。
clpru 编译标记为:`-O0 --opt_for_speed=1 --auto_inline -v3`。
上述某些操作是从链接的问题推断得出的、因为 AM62 TRM 似乎没有包含与表6-73 (读取命令)等效的用于描述写入命令。 这些在 AM62 PRU 上极有可能不受支持吗?
如果您能为本代码的运行提供任何帮助、我们将不胜感激。
此致、
António μ A


