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.
Tool/software:
Hi, TI expert,
I am trying to communicate with an FPGA using GPMC on custom AM2434 hardware, employing address/data multiplexed, synchronous burst read/write mode. During actual use, there are some timing issues, such as being able to read only 2 bytes of data instead of 64 bytes. Below are some of my register configurations:
/* GPMC attributes */ static GPMC_HwAttrs gGpmcAttrs[CONFIG_GPMC_NUM_INSTANCES] = { { .gpmcConfig1 = { .wrapBurst = CSL_GPMC_CONFIG1_WRAPBURST_WRAPNOTSUPP, .readMultipleFlag = CSL_GPMC_CONFIG1_READMULTIPLE_RDMULTIPLE, .writeMultipleFlag = CSL_GPMC_CONFIG1_WRITEMULTIPLE_WRMULTIPLE, .readType = CSL_GPMC_CONFIG1_READTYPE_RDSYNC, .writeType = CSL_GPMC_CONFIG1_WRITETYPE_WRSYNC, .attachedDevicePageLength = CSL_GPMC_CONFIG1_ATTACHEDDEVICEPAGELENGTH_THIRTYTWO, .waitReadMonitoring = CSL_GPMC_CONFIG1_WAITREADMONITORING_WMONIT, .waitWriteMonitoring = CSL_GPMC_CONFIG1_WAITWRITEMONITORING_WMONIT, .waitMonitoringTime = CSL_GPMC_CONFIG1_WAITMONITORINGTIME_ATVALID, .waitPinSelect = CSL_GPMC_CONFIG1_WAITPINSELECT_W0, .deviceSize = CSL_GPMC_CONFIG1_DEVICESIZE_SIXTEENBITS, .deviceType = CSL_GPMC_CONFIG1_DEVICETYPE_NORLIKE, .muxAddrData = CSL_GPMC_CONFIG1_MUXADDDATA_MUX, .timeParGranuLarity = CSL_GPMC_CONFIG1_TIMEPARAGRANULARITY_X1, .fclkDivider = CSL_GPMC_CONFIG1_GPMCFCLKDIVIDER_DIVBY1, .clkActivationTime = CSL_GPMC_CONFIG1_CLKACTIVATIONTIME_ONECLKB4, }, .timingParams = { .csOnTime = 0, .csRdOffTime = 11, .csWrOffTime = 11, .advOnTime = 1, .advRdOffTime = 2, .advWrOffTime = 2, .advAadMuxOnTime = 0, .advAadMuxRdOffTime = 0, .advAadMuxWrOffTime = 0, .weOnTime = 3, .weOffTime = 11, .oeOnTime = 3, .oeOffTime = 11, .oeAadMuxOnTime = 0, .oeAadMuxOffTime = 0, .pageBurstAccess = 1, .rdAccessTime = 10, .wrAccessTime = 10, .rdCycleTime = 11, .wrCycleTime = 11, .wrDataOnMuxBusTime = 2, .cycle2CycleDelay = 2, .cycleDelaySameChipSel = CSL_GPMC_CONFIG6_CYCLE2CYCLESAMECSEN_C2CDELAY, .cycleDelayDiffChipSel = CSL_GPMC_CONFIG6_CYCLE2CYCLEDIFFCSEN_C2CDELAY, .busTurnAroundTime = 1, }, .gpmcBaseAddr = CSL_GPMC0_CFG_BASE, .dataBaseAddr = CSL_GPMC0_DATA_BASE, .elmBaseAddr = CSL_ELM0_BASE, .inputClkFreq = 100000000U, .intrNum = CSLR_R5FSS0_CORE0_INTR_GPMC0_GPMC_SINTERRUPT_0, .intrPriority = 4U, .chipSelBaseAddr = 0x50000000U, .chipSelAddrSize = GPMC_CS_MASK_ADDR_SIZE_128MB, .waitPinPol = CSL_GPMC_CONFIG_WAIT0PINPOLARITY_W0ACTIVEL, .eccAlgo = GPMC_NAND_ECC_ALGO_BCH_16BIT, .csExtraDelay = CSL_GPMC_CONFIG2_CSEXTRADELAY_NOTDELAYED, .advExtraDelay = CSL_GPMC_CONFIG3_ADVEXTRADELAY_NOTDELAYED, .weExtraDelay = CSL_GPMC_CONFIG4_WEEXTRADELAY_NOTDELAYED, .oeExtraDelay = CSL_GPMC_CONFIG4_OEEXTRADELAY_NOTDELAYED, .dmaRestrictedRegions = gGpmcDmaRestrictRegions, }, };
there is few question about GPMC:
1. I want to achieve a burst read/write operation of 16bit * 32word. Are there any issues with my register configurations?
2. What is the specific function of wrapBurst? I checked the reference manual's description, but I didn't understand it. Are there more specific resources available, and does this function only support certain chips?
3. Since I configured deviceType to 16bit and attachedDevicePageLength to 32words, I believe the data transfer amount for one GPMC operation is 16bit * 32words = 64bytes. Here is my GPMC read/write function:
typedef struct { uint8_t data[64]; } DataStruct64; int32_t GPMC_NormalRead(GPMC_Handle handle, GPMC_Transaction *trans) { DataStruct64 data64; int32_t status = SystemP_SUCCESS; if (handle == NULL && trans == NULL) { status = SystemP_FAILURE; return status; } GPMC_Object *object = ((GPMC_Config*)handle)->object; const GPMC_HwAttrs *attrs = ((GPMC_Config*)handle)->attrs; uint32_t byteCount = trans->count; if (object->operMode == GPMC_OPERATING_MODE_POLLING) { if (trans->transType == GPMC_TRANSACTION_TYPE_READ) { uint32_t baseAddress = GPMC_DATA_BASE_ADDRESS; volatile DataStruct64 *pDst = (volatile DataStruct64 *)trans->Buf; volatile DataStruct64 *pSrc = (volatile DataStruct64 *)(trans->offset + baseAddress); while (byteCount != 0U) { *pDst = *pSrc; pSrc++; pDst++; if (byteCount < 64) { byteCount = 0; } else { byteCount -= 64; } } } } return status; } int32_t GPMC_NormalWrite(GPMC_Handle handle, GPMC_Transaction *trans) { int32_t status = SystemP_SUCCESS; if (handle == NULL && trans == NULL) { status = SystemP_FAILURE; return status; } GPMC_Object *object = ((GPMC_Config*)handle)->object; uint32_t byteCount = trans->count; if (object->operMode == GPMC_OPERATING_MODE_POLLING) { if (trans->transType == GPMC_TRANSACTION_TYPE_WRITE) { uint32_t baseAddress = GPMC_DATA_BASE_ADDRESS; volatile DataStruct64 *pDst = (volatile DataStruct64 *)(trans->offset + baseAddress); volatile DataStruct64 *pSrc = (volatile DataStruct64 *)trans->Buf; uint32_t remain = byteCount % 64; if (remain != 0U) { byteCount = byteCount - remain + 64U; } while (byteCount != 0U) { *pDst = *pSrc; pSrc++; pDst++; byteCount -= 64; } } } return status; }
Based on *pDst = *pSrc
, it can be seen that I am performing read/write operations in increments of 64 bytes. Is my implementation correct? Additionally, if I perform a pointer assignment operation using uint16_t*
, does this mean that the GPMC only transfers 2 bytes at a time?
4. Regarding write operations, I believe that after copying data to the CSL_GPMC0_DATA_BASE address, the GPMC data transmission will be triggered automatically. However, for read operations, when I perform a copy operation from the CSL_GPMC0_DATA_BASE address, this copy operation gets blocked until the GPMC read timing is complete. Is my understanding correct?