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.

AM2434: AM2434 GPMC read/write function question

Part Number: AM2434

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?