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.

[参考译文] AM5729:使用具有 DSP 远程处理器固件的 GPMC 读取 ADC 数据

Guru**** 2350610 points
Other Parts Discussed in Thread: ADS8568, AM5729
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1510406/am5729-adc-data-read-using-gpmc-with-dsp-remoteproc-fw

器件型号:AM5729
主题: ADS8568中讨论的其他器件

工具/软件:

我正在尝试使用 AM5729的 GPMC 以并行模式从 ADS8568读取数据。

在连接 ADS8568之前、我通过检查 CS 引脚信号来尝试测试 GPMC 操作。

然而,我没有观察到任何信号,并且有一个错误消息中dmesg.

[ 2534.408285] 44000000.ocp:L3 Custom Error: MASTER DSP1_MDMA TARGET GPMC (Read): Data Access in User mode during Functional access
[ 2534.408291] Modules linked in: rpmsg_rpc rpmsg_proto xt_state xt_conntrack nft_counter pru_rproc nft_meta pruss_intc nft_chain_nat_ipv4 nf_tables_ipv4 ipt_MASQUERADE nf_nat_masquerade_ipv4 nft_compat bnep pruss pruss_soc_bus btsdio ti_vpe bluetooth ti_sc videobuf2_dma_contig ti_csc ti_vpdma v4l2_mem2mem v4l2_common videobuf2_memops videobuf2_v4l2 videobuf2_core videodev media ecdh_generic brcmfmac brcmutil cfg80211 omap_remoteproc virtio_rpmsg_bus rpmsg_core usb_f_ecm usb_f_mass_storage usb_f_rndis u_ether libcomposite uio_pdrv_genirq uio cmemk(O)
[ 2534.408530] CPU: 0 PID: 0 Comm: swapper/0 Tainted: G        W  O    4.14.108-ti-r131 #1buster
[ 2534.408536] Hardware name: Generic DRA74X (Flattened Device Tree)
[ 2534.408559] [<c0112de8>] (unwind_backtrace) from [<c010d6a8>] (show_stack+0x20/0x24)
[ 2534.408573] [<c010d6a8>] (show_stack) from [<c0c982a4>] (dump_stack+0x80/0x94)
[ 2534.408588] [<c0c982a4>] (dump_stack) from [<c013fbb8>] (__warn+0xec/0x114)
[ 2534.408600] [<c013fbb8>] (__warn) from [<c013fc38>] (warn_slowpath_fmt+0x58/0x74)
[ 2534.408613] [<c013fc38>] (warn_slowpath_fmt) from [<c0736434>] (l3_interrupt_handler+0x368/0x3a4)
[ 2534.408629] [<c0736434>] (l3_interrupt_handler) from [<c01ac04c>] (__handle_irq_event_percpu+0x84/0x2d0)
[ 2534.408642] [<c01ac04c>] (__handle_irq_event_percpu) from [<c01ac2d4>] (handle_irq_event_percpu+0x3c/0x90)
[ 2534.408653] [<c01ac2d4>] (handle_irq_event_percpu) from [<c01ac370>] (handle_irq_event+0x48/0x6c)
[ 2534.408666] [<c01ac370>] (handle_irq_event) from [<c01b030c>] (handle_fasteoi_irq+0xd0/0x178)
[ 2534.408678] [<c01b030c>] (handle_fasteoi_irq) from [<c01ab15c>] (generic_handle_irq+0x34/0x44)
[ 2534.408689] [<c01ab15c>] (generic_handle_irq) from [<c01ab76c>] (__handle_domain_irq+0x8c/0xfc)
[ 2534.408702] [<c01ab76c>] (__handle_domain_irq) from [<c01015bc>] (gic_handle_irq+0x4c/0x88)
[ 2534.408714] [<c01015bc>] (gic_handle_irq) from [<c0cb434c>] (__irq_svc+0x6c/0xa8)
[ 2534.408721] Exception stack(0xc1301ee0 to 0xc1301f28)
[ 2534.408732] 1ee0: 00000000 c109e3a4 fe600000 00000000 ffffe000 c1305ea0 c1305e3c c13dd1e1
[ 2534.408742] 1f00: c0fc2f50 00000001 c1278a28 c1301f3c c1301f1c c1301f30 c01306c8 c0109a2c
[ 2534.408749] 1f20: 60070013 ffffffff
[ 2534.408763] [<c0cb434c>] (__irq_svc) from [<c0109a2c>] (arch_cpu_idle+0x30/0x4c)
[ 2534.408775] [<c0109a2c>] (arch_cpu_idle) from [<c0cb37bc>] (default_idle_call+0x38/0x3c)
[ 2534.408788] [<c0cb37bc>] (default_idle_call) from [<c018d748>] (do_idle+0x10c/0x148)
[ 2534.408801] [<c018d748>] (do_idle) from [<c018da80>] (cpu_startup_entry+0x28/0x2c)
[ 2534.408814] [<c018da80>] (cpu_startup_entry) from [<c0cacca0>] (rest_init+0xd4/0xd8)
[ 2534.408830] [<c0cacca0>] (rest_init) from [<c1200e9c>] (start_kernel+0x420/0x448)
[ 2534.408841] ---[ end trace 77d87014de97e676 ]---

下面是我的 Remoteproc 固件代码。

GPMC 初始化代码。
 

#define GPMC_BASE_ADDR 0x14000000
volatile int16_t *ads_data = (volatile int16_t*) (GPMC_BASE_ADDR);

void gpmcInit() {
	// pinMux - data line
	uint32_t offsets[16] = {
	CTRL_CORE_PAD_GPMC_AD0,
	CTRL_CORE_PAD_GPMC_AD1,
	CTRL_CORE_PAD_GPMC_AD2,
	CTRL_CORE_PAD_GPMC_AD3,
	CTRL_CORE_PAD_GPMC_AD4,
	CTRL_CORE_PAD_GPMC_AD5,
	CTRL_CORE_PAD_GPMC_AD6,
	CTRL_CORE_PAD_GPMC_AD7,
	CTRL_CORE_PAD_GPMC_AD8,
	CTRL_CORE_PAD_GPMC_AD9,
	CTRL_CORE_PAD_GPMC_AD10,
	CTRL_CORE_PAD_GPMC_AD11,
	CTRL_CORE_PAD_GPMC_AD12,
	CTRL_CORE_PAD_GPMC_AD13,
	CTRL_CORE_PAD_GPMC_AD14,
	CTRL_CORE_PAD_GPMC_AD15, 
	};

	int i = 0;
	for (; i < 16; ++i) {
		HW_WR_FIELD32(SOC_CORE_PAD_IO_REGISTERS_BASE+offsets[i],
			CTRL_CORE_PAD_GPMC_AD0_GPMC_AD0_MUXMODE, // 0 ~ 15 모두 같은 값
			CTRL_CORE_PAD_GPMC_AD0_GPMC_AD0_MUXMODE_GPMC_AD0_0// 0 ~ 15 모두 같은 값
		);
		HW_WR_FIELD32(SOC_CORE_PAD_IO_REGISTERS_BASE+offsets[i],
			CTRL_CORE_PAD_GPMC_AD0_GPMC_AD0_INPUTENABLE, // 0 ~ 15 모두 같은 값
			CTRL_CORE_PAD_GPMC_AD0_GPMC_AD0_INPUTENABLE_ENABLE// 0 ~ 15 모두 같은 값
		);
	}

	// pinMux - CS3
	HW_WR_FIELD32(SOC_CORE_PAD_IO_REGISTERS_BASE+CTRL_CORE_PAD_GPMC_CS3,
			CTRL_CORE_PAD_GPMC_CS3_GPMC_CS3_MUXMODE,
			CTRL_CORE_PAD_GPMC_CS3_GPMC_CS3_MUXMODE_GPMC_CS3_0);
	HW_WR_FIELD32(SOC_CORE_PAD_IO_REGISTERS_BASE+CTRL_CORE_PAD_GPMC_CS3,
			CTRL_CORE_PAD_GPMC_CS3_GPMC_CS3_INPUTENABLE,
			CTRL_CORE_PAD_GPMC_CS3_GPMC_CS3_INPUTENABLE_DISABLE);

	// pinMux - oe
	HW_WR_FIELD32(SOC_CORE_PAD_IO_REGISTERS_BASE+CTRL_CORE_PAD_GPMC_OEN_REN,
			CTRL_CORE_PAD_GPMC_OEN_REN_GPMC_OEN_REN_MUXMODE,
			CTRL_CORE_PAD_GPMC_OEN_REN_GPMC_OEN_REN_MUXMODE_GPMC_OEN_REN_0);
	HW_WR_FIELD32(SOC_CORE_PAD_IO_REGISTERS_BASE+CTRL_CORE_PAD_GPMC_OEN_REN,
			CTRL_CORE_PAD_GPMC_OEN_REN_GPMC_OEN_REN_INPUTENABLE,
			CTRL_CORE_PAD_GPMC_OEN_REN_GPMC_OEN_REN_INPUTENABLE_DISABLE);

	Log_print0(Diags_INFO, "GPMC Pin Mux Configured");

	// prcm - gpmc
	volatile UInt32 *prcm_gpmc = (UInt32*) (SOC_CORE_CM_CORE_BASE
			+ CM_L3MAIN1_GPMC_CLKCTRL);

	HW_WR_REG32(prcm_gpmc, CM_L3MAIN1_GPMC_CLKCTRL_MODULEMODE_AUTO);
	while (HW_RD_FIELD32(prcm_gpmc, CM_L3MAIN1_GPMC_CLKCTRL_IDLEST));

	Log_print0(Diags_INFO, "GPMC Clock enabled");

	GPMCTimeOutFeatureConfig(SOC_GPMC_CONF_REGS_BASE,
	GPMC_TIMEOUTFEATURE_ENABLE);
	GPMCTimeOutStartValSet(SOC_GPMC_CONF_REGS_BASE, 2000);

	// async / nor / nonmultiplexed
	GPMCIdleModeSelect(SOC_GPMC_CONF_REGS_BASE, GPMC_IDLEMODE_NOIDLE);
	GPMCDevTypeSelect(SOC_GPMC_CONF_REGS_BASE, GPMC_CHIP_SELECT_3,
	GPMC_DEVICETYPE_NORLIKE);
	GPMCDevSizeSelect(SOC_GPMC_CONF_REGS_BASE, GPMC_CHIP_SELECT_3,
	GPMC_DEVICESIZE_16BITS);
	GPMCReadTypeSelect(SOC_GPMC_CONF_REGS_BASE, GPMC_CHIP_SELECT_3,
	GPMC_READTYPE_ASYNC);
	// burst / single
	GPMCAccessTypeSelect(SOC_GPMC_CONF_REGS_BASE, GPMC_CHIP_SELECT_3,
	GPMC_MODE_READ,
	GPMC_ACCESSTYPE_SINGLE);

	Log_print0(Diags_INFO, "GPMC Dev Set");

	// timing
	GPMCCSTimingConfig(
		SOC_GPMC_CONF_REGS_BASE, /* Base */
		GPMC_CHIP_SELECT_3,
		GPMC_CS_TIMING_CONFIG(
			0x12, /* CSWrOffTime = 18 */
			0x12, /* CSRdOffTime = 18 */
			GPMC_CS_EXTRA_NODELAY, /* Delay 없음 */
			0x00 /* 시작부터 CS assert */
		)
	);
	GPMCWEAndOETimingConfig(
		SOC_GPMC_CONF_REGS_BASE,
		GPMC_CHIP_SELECT_3,
		GPMC_WE_OE_TIMING_CONFIG(
			0, /* WEOffTime - 무시 */
			GPMC_WE_EXTRA_NODELAY, /* WEExtDelayFlag */
			0, /* WEOnTime - 무시 */
			0, /* OEAADMuxOffTime - 사용 안함 */
			16, /* OEOffTime */
			GPMC_OE_EXTRA_NODELAY, /* OEExtDelayFlag */
			0, /* OEAADMuxOnTime - 사용 안함 */
			10 /* OEOnTime */
		)
	);
	GPMCRdAccessAndCycleTimeTimingConfig(
		SOC_GPMC_CONF_REGS_BASE,
		GPMC_CHIP_SELECT_3,
		GPMC_RDACCESS_CYCLETIME_TIMING_CONFIG(
			0x20, /* rdCycleTime = 32 GPMC_FCLK cycles (전체 read 사이클 길이) */
			0x20, /* wrCycleTime = 32 GPMC_FCLK cycles (전체 write 사이클 길이) */
			0x10, /* rdAccessTime = 16 GPMC_FCLK cycles (OE# 이후 데이터 유효 시점) */
			0x00 /* pageBurstAccessTime = 0 (사용 안함, burst mode off) */
		)
	);
	GPMCycle2CycleAndTurnArndTimeTimingConfig(
		SOC_GPMC_CONF_REGS_BASE,
		GPMC_CHIP_SELECT_3,
		GPMC_CYCLE2CYCLE_BUSTURNAROUND_TIMING_CONFIG(
			0x01, /* 트랜잭션 간 대기 시간 (1 GPMC_FCLK 사이클) */
			1, /* 같은 CS를 사용하는 연속 트랜잭션 간 대기 적용 (사용함) */
			1, /* 다른 CS를 사용하는 연속 트랜잭션 간 대기 적용 (사용함) */
			0x02 /* 버스 전환 시간 (예: Write → Read 전환 시 2 GPMC_FCLK 대기) */
		)
	);

	Log_print0(Diags_INFO, "GPMC Timing Set");

//    GPMCWaitPinMonitoringConfig(SOC_GPMC_CONF_REGS_BASE, GPMC_CHIP_SELECT_3, GPMC_MODE_READ, GPMC_WAITMONITORING_DISABLE);
//    Log_print0(Diags_INFO, "GPMC Wait Monitoring DISABLE");

	GPMCCSConfig(SOC_GPMC_CONF_REGS_BASE, GPMC_CHIP_SELECT_3, GPMC_CS_DISABLE);
	GPMCBaseAddrSet(SOC_GPMC_CONF_REGS_BASE, GPMC_CHIP_SELECT_3, 0x11);
	GPMCMaskAddrSet(SOC_GPMC_CONF_REGS_BASE, GPMC_CHIP_SELECT_3,
	GPMC_CS_SIZE_16MB);
	GPMCCSConfig(SOC_GPMC_CONF_REGS_BASE, GPMC_CHIP_SELECT_3, GPMC_CS_ENABLE);

	Log_print0(Diags_INFO, "GPMC Configured");
	Log_print1(Diags_INFO, "GPMC PRCM : %x", SOC_CORE_CM_CORE_BASE + CM_L3MAIN1_GPMC_CLKCTRL);
	Log_print1(Diags_INFO, "GPMC GPMC_CONFIG7_3 : %x", SOC_GPMC_CONF_REGS_BASE + GPMC_CONFIG7_N(GPMC_CHIP_SELECT_3));

}

读取地址"0x1400_0000"

CacheP_Inv((void*) ads_data, sizeof(int16_t));
int16_t value = ads_data[0];
Log_print1(Diags_INFO, "Value: (%d)", value);


根据我的理解、"L3自定义错误"意味着 GPMC 返回了从器件响应错误。

如果我的 GPMC 初始化过程有任何问题、请告诉我、以便我可以修复。 如果不是、我希望获得有关如何解决此问题的任何建议