Hello,
We are looking to use an AM64x device to communicate with an FPGA through the GPMC. We are verifying configuration and timing using a TMDS64GPEVM evaluation module.
I am attempting to configure the GPMC and read/write a register in the GPMC0_DATA space in order to scope the output signals. The configuration appears correct, but any read/write access to the GPMC0_DATA space hangs. I do not see most of the expected waveforms on the GPMC signals, however I can confirm the proper waveform and frequency of the GPMC_CLK.
Based upon the TRM, I am running the following general sequence:
- Establish the proper pad configuration,
- Configure the desired GPMC clocking,
- Configure the GPMC for our target FPGA communication,
- Attempt to read/write to the configured CS data space.
Here is the current state of the code I am running:
#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" #include <drivers/gpmc/v0/cslr_gpmc.h> // GPMC_* #include <drivers/hw_include/am64x_am243x/cslr_soc_baseaddress.h> // CSL_GPMC0_CFG_BASE /* TRM: MAIN Domain Memory Map GPMC0_CFG 0x03B000000 0x03B0003FF 1 KB GPMC0_DATA 0x050000000 0x057FFFFFF 128 MB */ void pad_config() { HW_WR_REG32(0x000F403C, 0x54000); // PADCFG_CTRL0_CFG0_PADCONFIG15 (GPMC0_AD0) HW_WR_REG32(0x000F4040, 0x54000); // PADCFG_CTRL0_CFG0_PADCONFIG16 (GPMC0_AD1) HW_WR_REG32(0x000F4044, 0x54000); // PADCFG_CTRL0_CFG0_PADCONFIG17 (GPMC0_AD2) HW_WR_REG32(0x000F4048, 0x54000); // PADCFG_CTRL0_CFG0_PADCONFIG18 (GPMC0_AD3) HW_WR_REG32(0x000F404C, 0x54000); // PADCFG_CTRL0_CFG0_PADCONFIG19 (GPMC0_AD4) HW_WR_REG32(0x000F4050, 0x54000); // PADCFG_CTRL0_CFG0_PADCONFIG20 (GPMC0_AD5) HW_WR_REG32(0x000F4054, 0x54000); // PADCFG_CTRL0_CFG0_PADCONFIG21 (GPMC0_AD6) HW_WR_REG32(0x000F4058, 0x54000); // PADCFG_CTRL0_CFG0_PADCONFIG22 (GPMC0_AD7) HW_WR_REG32(0x000F405C, 0x54000); // PADCFG_CTRL0_CFG0_PADCONFIG23 (GPMC0_AD8) HW_WR_REG32(0x000F4060, 0x54000); // PADCFG_CTRL0_CFG0_PADCONFIG24 (GPMC0_AD9) HW_WR_REG32(0x000F4064, 0x54000); // PADCFG_CTRL0_CFG0_PADCONFIG25 (GPMC0_AD10) HW_WR_REG32(0x000F4068, 0x54000); // PADCFG_CTRL0_CFG0_PADCONFIG26 (GPMC0_AD11) HW_WR_REG32(0x000F406C, 0x54000); // PADCFG_CTRL0_CFG0_PADCONFIG27 (GPMC0_AD12) HW_WR_REG32(0x000F4070, 0x54000); // PADCFG_CTRL0_CFG0_PADCONFIG28 (GPMC0_AD13) HW_WR_REG32(0x000F4074, 0x54000); // PADCFG_CTRL0_CFG0_PADCONFIG29 (GPMC0_AD14) HW_WR_REG32(0x000F4078, 0x54000); // PADCFG_CTRL0_CFG0_PADCONFIG30 (GPMC0_AD15) HW_WR_REG32(0x000F407C, 0x54004); // PADCFG_CTRL0_CFG0_PADCONFIG31 (GPMC0_CLK) HW_WR_REG32(0x000F4084, 0x10000); // PADCFG_CTRL0_CFG0_PADCONFIG33 (GPMC0_ADVn_ALE) HW_WR_REG32(0x000F4088, 0x10000); // PADCFG_CTRL0_CFG0_PADCONFIG34 (GPMC0_OEn_REn) HW_WR_REG32(0x000F408C, 0x10000); // PADCFG_CTRL0_CFG0_PADCONFIG35 (GPMC0_WEn) HW_WR_REG32(0x000F4090, 0x10000); // PADCFG_CTRL0_CFG0_PADCONFIG36 (GPMC0_BE0n_CLE) HW_WR_REG32(0x000F4094, 0x10000); // PADCFG_CTRL0_CFG0_PADCONFIG37 (GPMC0_BE1n) HW_WR_REG32(0x000F4098, 0x10000); // PADCFG_CTRL0_CFG0_PADCONFIG38 (GPMC0_WAIT0) HW_WR_REG32(0x000F409C, 0x10000); // PADCFG_CTRL0_CFG0_PADCONFIG39 (GPMC0_WAIT1) HW_WR_REG32(0x000F40A0, 0x10000); // PADCFG_CTRL0_CFG0_PADCONFIG40 (GPMC0_WPn) HW_WR_REG32(0x000F40A4, 0x10000); // PADCFG_CTRL0_CFG0_PADCONFIG41 (GPMC0_DIR) HW_WR_REG32(0x000F40A8, 0x10000); // PADCFG_CTRL0_CFG0_PADCONFIG42 (GPMC0_CSn0) HW_WR_REG32(0x000F40AC, 0x10000); // PADCFG_CTRL0_CFG0_PADCONFIG43 (GPMC0_CSn1) HW_WR_REG32(0x000F40B0, 0x10000); // PADCFG_CTRL0_CFG0_PADCONFIG44 (GPMC0_CSn2) HW_WR_REG32(0x000F40B4, 0x10000); // PADCFG_CTRL0_CFG0_PADCONFIG45 (GPMC0_CSn3) HW_WR_REG32(0x000F40B8, 0x54008); // PADCFG_CTRL0_CFG0_PADCONFIG46 (GPMC0_AD16) HW_WR_REG32(0x000F40BC, 0x54008); // PADCFG_CTRL0_CFG0_PADCONFIG47 (GPMC0_AD17) HW_WR_REG32(0x000F40C0, 0x54008); // PADCFG_CTRL0_CFG0_PADCONFIG48 (GPMC0_AD18) HW_WR_REG32(0x000F40C4, 0x54008); // PADCFG_CTRL0_CFG0_PADCONFIG49 (GPMC0_AD19) HW_WR_REG32(0x000F40C8, 0x54008); // PADCFG_CTRL0_CFG0_PADCONFIG50 (GPMC0_AD20) HW_WR_REG32(0x000F40CC, 0x54008); // PADCFG_CTRL0_CFG0_PADCONFIG51 (GPMC0_AD21) HW_WR_REG32(0x000F40D0, 0x54008); // PADCFG_CTRL0_CFG0_PADCONFIG52 (GPMC0_AD22) HW_WR_REG32(0x000F40D4, 0x54008); // PADCFG_CTRL0_CFG0_PADCONFIG53 (GPMC0_AD23) HW_WR_REG32(0x000F40D8, 0x54008); // PADCFG_CTRL0_CFG0_PADCONFIG54 (GPMC0_AD24) HW_WR_REG32(0x000F40DC, 0x54008); // PADCFG_CTRL0_CFG0_PADCONFIG55 (GPMC0_AD25) HW_WR_REG32(0x000F40E0, 0x54008); // PADCFG_CTRL0_CFG0_PADCONFIG56 (GPMC0_AD26) HW_WR_REG32(0x000F40E4, 0x54008); // PADCFG_CTRL0_CFG0_PADCONFIG57 (GPMC0_AD27) HW_WR_REG32(0x000F40E8, 0x54008); // PADCFG_CTRL0_CFG0_PADCONFIG58 (GPMC0_AD28) HW_WR_REG32(0x000F40EC, 0x54008); // PADCFG_CTRL0_CFG0_PADCONFIG59 (GPMC0_AD29) HW_WR_REG32(0x000F40F0, 0x54008); // PADCFG_CTRL0_CFG0_PADCONFIG60 (GPMC0_AD30) HW_WR_REG32(0x000F40F4, 0x54008); // PADCFG_CTRL0_CFG0_PADCONFIG61 (GPMC0_AD31) HW_WR_REG32(0x000F40F4, 0x54008); // PADCFG_CTRL0_CFG0_PADCONFIG63 (GPMC0_A0) HW_WR_REG32(0x000F40F4, 0x54008); // PADCFG_CTRL0_CFG0_PADCONFIG64 (GPMC0_A1) HW_WR_REG32(0x000F40F4, 0x54008); // PADCFG_CTRL0_CFG0_PADCONFIG65 (GPMC0_A2) HW_WR_REG32(0x000F40F4, 0x54008); // PADCFG_CTRL0_CFG0_PADCONFIG66 (GPMC0_A3) HW_WR_REG32(0x000F40F4, 0x54008); // PADCFG_CTRL0_CFG0_PADCONFIG67 (GPMC0_A4) HW_WR_REG32(0x000F40F4, 0x54008); // PADCFG_CTRL0_CFG0_PADCONFIG68 (GPMC0_A5) HW_WR_REG32(0x000F40F4, 0x54008); // PADCFG_CTRL0_CFG0_PADCONFIG69 (GPMC0_A6) HW_WR_REG32(0x000F40F4, 0x54008); // PADCFG_CTRL0_CFG0_PADCONFIG70 (GPMC0_A7) HW_WR_REG32(0x000F40F4, 0x54008); // PADCFG_CTRL0_CFG0_PADCONFIG71 (GPMC0_A8) HW_WR_REG32(0x000F40F4, 0x54008); // PADCFG_CTRL0_CFG0_PADCONFIG72 (GPMC0_A9) HW_WR_REG32(0x000F40F4, 0x54008); // PADCFG_CTRL0_CFG0_PADCONFIG73 (GPMC0_A10) DebugP_log("Pad Configuration Complete.\r\n"); } void gpmc_init() { uint32_t gpmc_revision; // For FPGA clocking, configure the GPMC_FCLK (100MHz). HW_WR_REG32(0x43008180, 0x1); // CTRLMMR_GPMC_CLKSEL (MAIN_PLL2_HSDIV3_CLKOUT) DebugP_log("GPMC_FCLK Configured\r\n"); // Read GPMC0 revision. gpmc_revision = HW_RD_REG32(CSL_GPMC0_CFG_BASE + CSL_GPMC_REVISION); DebugP_log("GPMC Revision: 0x%X\r\n", gpmc_revision); // Disable the target chip selects for configuration. Per TRM: // Chip-select configuration (base and mask address or any protocol and // timing settings) must be performed while the associated chip-select // is disabled through the GPMC_CONFIG7_i[6] CSVALID bit. HW_WR_REG32(CSL_GPMC0_CFG_BASE + CSL_GPMC_CONFIG7(0), ((0x0U << CSL_GPMC_CONFIG7_CSVALID_SHIFT) & CSL_GPMC_CONFIG7_CSVALID_MASK)); // Program GPMC_CONFIG1 HW_WR_REG32(CSL_GPMC0_CFG_BASE + CSL_GPMC_CONFIG1(0), ((CSL_GPMC_CONFIG1_GPMCFCLKDIVIDER_DIVBY1 << CSL_GPMC_CONFIG1_GPMCFCLKDIVIDER_SHIFT) & CSL_GPMC_CONFIG1_GPMCFCLKDIVIDER_MASK) | ((CSL_GPMC_CONFIG1_TIMEPARAGRANULARITY_X1 << CSL_GPMC_CONFIG1_TIMEPARAGRANULARITY_SHIFT) & CSL_GPMC_CONFIG1_TIMEPARAGRANULARITY_MASK) | ((CSL_GPMC_CONFIG1_MUXADDDATA_NONMUX << CSL_GPMC_CONFIG1_MUXADDDATA_SHIFT) & CSL_GPMC_CONFIG1_MUXADDDATA_MASK) | ((CSL_GPMC_CONFIG1_DEVICETYPE_NORLIKE << CSL_GPMC_CONFIG1_DEVICETYPE_SHIFT) & CSL_GPMC_CONFIG1_DEVICETYPE_MASK) | ((CSL_GPMC_CONFIG1_DEVICESIZE_THIRTYTWOBITS << CSL_GPMC_CONFIG1_DEVICESIZE_SHIFT) & CSL_GPMC_CONFIG1_DEVICESIZE_MASK) | ((CSL_GPMC_CONFIG1_WAITPINSELECT_W0 << CSL_GPMC_CONFIG1_WAITPINSELECT_SHIFT) & CSL_GPMC_CONFIG1_WAITPINSELECT_MASK) | ((CSL_GPMC_CONFIG1_WAITMONITORINGTIME_ATVALID << CSL_GPMC_CONFIG1_WAITMONITORINGTIME_SHIFT) & CSL_GPMC_CONFIG1_WAITMONITORINGTIME_MASK) | ((CSL_GPMC_CONFIG1_WAITWRITEMONITORING_WNOTMONIT << CSL_GPMC_CONFIG1_WAITWRITEMONITORING_SHIFT) & CSL_GPMC_CONFIG1_WAITWRITEMONITORING_MASK) | ((CSL_GPMC_CONFIG1_WAITREADMONITORING_WNOTMONIT << CSL_GPMC_CONFIG1_WAITREADMONITORING_SHIFT) & CSL_GPMC_CONFIG1_WAITREADMONITORING_MASK) | ((CSL_GPMC_CONFIG1_ATTACHEDDEVICEPAGELENGTH_FOUR << CSL_GPMC_CONFIG1_ATTACHEDDEVICEPAGELENGTH_SHIFT) & CSL_GPMC_CONFIG1_ATTACHEDDEVICEPAGELENGTH_MASK) | ((CSL_GPMC_CONFIG1_CLKACTIVATIONTIME_ATSTART << CSL_GPMC_CONFIG1_CLKACTIVATIONTIME_SHIFT) & CSL_GPMC_CONFIG1_CLKACTIVATIONTIME_MASK)| ((CSL_GPMC_CONFIG1_WRITETYPE_WRSYNC << CSL_GPMC_CONFIG1_WRITETYPE_SHIFT) & CSL_GPMC_CONFIG1_WRITETYPE_MASK) | ((CSL_GPMC_CONFIG1_WRITEMULTIPLE_WRSINGLE << CSL_GPMC_CONFIG1_WRITEMULTIPLE_SHIFT) & CSL_GPMC_CONFIG1_WRITEMULTIPLE_MASK) | ((CSL_GPMC_CONFIG1_READTYPE_RDSYNC << CSL_GPMC_CONFIG1_READTYPE_SHIFT) & CSL_GPMC_CONFIG1_READTYPE_MASK) | ((CSL_GPMC_CONFIG1_READMULTIPLE_RDSINGLE << CSL_GPMC_CONFIG1_READMULTIPLE_SHIFT) & CSL_GPMC_CONFIG1_READMULTIPLE_MASK) | ((CSL_GPMC_CONFIG1_WRAPBURST_WRAPNOTSUPP << CSL_GPMC_CONFIG1_WRAPBURST_SHIFT) & CSL_GPMC_CONFIG1_WRAPBURST_MASK) ); // Program GPMC_CONFIG2 HW_WR_REG32(CSL_GPMC0_CFG_BASE + CSL_GPMC_CONFIG2(0), ((0x0U << CSL_GPMC_CONFIG2_CSONTIME_SHIFT) & CSL_GPMC_CONFIG2_CSONTIME_MASK) | ((CSL_GPMC_CONFIG2_CSEXTRADELAY_NOTDELAYED << CSL_GPMC_CONFIG2_CSEXTRADELAY_SHIFT) & CSL_GPMC_CONFIG2_CSEXTRADELAY_MASK) | ((0xCU << CSL_GPMC_CONFIG2_CSRDOFFTIME_SHIFT) & CSL_GPMC_CONFIG2_CSRDOFFTIME_MASK) | ((0xFU << CSL_GPMC_CONFIG2_CSWROFFTIME_SHIFT) & CSL_GPMC_CONFIG2_CSWROFFTIME_MASK) ); // Program GPMC_CONFIG3 HW_WR_REG32(CSL_GPMC0_CFG_BASE + CSL_GPMC_CONFIG3(0), 0x0U); // Program GPMC_CONFIG4 HW_WR_REG32(CSL_GPMC0_CFG_BASE + CSL_GPMC_CONFIG4(0), ((0x2U << CSL_GPMC_CONFIG4_OEONTIME_SHIFT) & CSL_GPMC_CONFIG4_OEONTIME_MASK) | ((0x0U << CSL_GPMC_CONFIG4_OEAADMUXONTIME_SHIFT) & CSL_GPMC_CONFIG4_OEAADMUXONTIME_MASK) | ((CSL_GPMC_CONFIG4_OEEXTRADELAY_NOTDELAYED << CSL_GPMC_CONFIG4_OEEXTRADELAY_SHIFT) & CSL_GPMC_CONFIG4_OEEXTRADELAY_MASK) | ((0xAU << CSL_GPMC_CONFIG4_OEOFFTIME_SHIFT) & CSL_GPMC_CONFIG4_OEOFFTIME_MASK) | ((0x0U << CSL_GPMC_CONFIG4_OEAADMUXOFFTIME_SHIFT) & CSL_GPMC_CONFIG4_OEAADMUXOFFTIME_MASK) | ((0x3U << CSL_GPMC_CONFIG4_WEONTIME_SHIFT) & CSL_GPMC_CONFIG4_WEONTIME_MASK) | ((CSL_GPMC_CONFIG4_WEEXTRADELAY_NOTDELAYED << CSL_GPMC_CONFIG4_WEEXTRADELAY_SHIFT) & CSL_GPMC_CONFIG4_WEEXTRADELAY_MASK) | ((0x8U << CSL_GPMC_CONFIG4_WEOFFTIME_SHIFT) & CSL_GPMC_CONFIG4_WEOFFTIME_MASK) ); // Program GPMC_CONFIG5 HW_WR_REG32(CSL_GPMC0_CFG_BASE + CSL_GPMC_CONFIG5(0), ((0x5U << CSL_GPMC_CONFIG5_RDCYCLETIME_SHIFT) & CSL_GPMC_CONFIG5_RDCYCLETIME_MASK) | ((0x3U << CSL_GPMC_CONFIG5_WRCYCLETIME_SHIFT) & CSL_GPMC_CONFIG5_WRCYCLETIME_MASK) | ((0x4U << CSL_GPMC_CONFIG5_RDACCESSTIME_SHIFT) & CSL_GPMC_CONFIG5_RDACCESSTIME_MASK) | ((0x1U << CSL_GPMC_CONFIG5_PAGEBURSTACCESSTIME_SHIFT) & CSL_GPMC_CONFIG5_PAGEBURSTACCESSTIME_MASK) ); // Program GPMC_CONFIG6 HW_WR_REG32(CSL_GPMC0_CFG_BASE + CSL_GPMC_CONFIG6(0), ((0x2U << CSL_GPMC_CONFIG6_BUSTURNAROUND_SHIFT) & CSL_GPMC_CONFIG6_BUSTURNAROUND_MASK) | ((CSL_GPMC_CONFIG6_CYCLE2CYCLEDIFFCSEN_NOC2CDELAY << CSL_GPMC_CONFIG6_CYCLE2CYCLEDIFFCSEN_SHIFT) & CSL_GPMC_CONFIG6_CYCLE2CYCLEDIFFCSEN_MASK) | ((CSL_GPMC_CONFIG6_CYCLE2CYCLESAMECSEN_NOC2CDELAY << CSL_GPMC_CONFIG6_CYCLE2CYCLESAMECSEN_SHIFT) & CSL_GPMC_CONFIG6_CYCLE2CYCLESAMECSEN_MASK) | ((0x0U << CSL_GPMC_CONFIG6_CYCLE2CYCLEDELAY_SHIFT) & CSL_GPMC_CONFIG6_CYCLE2CYCLEDELAY_MASK) | ((0x7U << CSL_GPMC_CONFIG6_WRDATAONADMUXBUS_SHIFT) & CSL_GPMC_CONFIG6_WRDATAONADMUXBUS_MASK) | ((0x3U << CSL_GPMC_CONFIG6_WRACCESSTIME_SHIFT) & CSL_GPMC_CONFIG6_WRACCESSTIME_MASK) ); // Program GPMC_CONFIG7 HW_WR_REG32(CSL_GPMC0_CFG_BASE + CSL_GPMC_CONFIG7(0), ((0x0U << CSL_GPMC_CONFIG7_BASEADDRESS_SHIFT) & CSL_GPMC_CONFIG7_BASEADDRESS_MASK) | ((0x1U << CSL_GPMC_CONFIG7_CSVALID_SHIFT) & CSL_GPMC_CONFIG7_CSVALID_MASK) | ((0xFU << CSL_GPMC_CONFIG7_MASKADDRESS_SHIFT) & CSL_GPMC_CONFIG7_MASKADDRESS_MASK) ); DebugP_log("GPMC Initialization Complete.\r\n"); } void gpmc_test_main(void *args) { uint32_t value; /* Open drivers to open the UART driver for console */ Drivers_open(); Board_driversOpen(); pad_config(); gpmc_init(); while ( 1 ) { DebugP_log("Pre Read Reg\r\n"); value = HW_RD_REG32(CSL_GPMC0_DATA_BASE); DebugP_log("Post Read Reg: 0x%X\r\n", value); } Board_driversClose(); Drivers_close(); }
Any guidance with what I am missing or doing incorrectly would be greatly appreciated.