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.

MCU-PLUS-SDK-AM263X: GPMC timing configuration

Part Number: MCU-PLUS-SDK-AM263X
Other Parts Discussed in Thread: AM2634-Q1, SYSCONFIG

I am working on GPMC using AM2634-Q1 and the device which I am interfacing is a 8bit nor like device which has 16bit addressing. I am not using multiplexed s address and data.

As per "Am263+ MCU guide" it supports NOR like devices and for it in sys.config there are limited options like device type(PSRAM) and device size(16bit).

So, I am configuring them manually using functions from gpmc.h 

But for timing configuration even though I am changing values at sys.config they are not reflecting on my generated drivers_config.c file which I am attaching here.

So, I am changing them manually in my .c file for timming calculation I am reffering to complete version of this document "AM64x Sitara™ Processors datasheet (Rev. G) ". and "7.10.5.8.2 GPMC and NOR Flash — Asynchronous Mode "  this section.

 

There is a mistake at gpmc.h file where devtype is assigned two times instead of devsize at this function "static inline void GPMC_Params_init(GPMC_Params *params)"
(I have changed that .h file and it is working fine)


issue:

  1. In sys.config timming configuration is not having any effect.
  2. My timming at IOW, IOR and Cs is taking effect after changing them through .c but the output timing is not as desired.

I am attaching my .c file where I am configuring GPMC and a picture of my sys config

/*
 *  Copyright (C) 2021 Texas Instruments Incorporated
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *    Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 *    Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the
 *    distribution.
 *
 *    Neither the name of Texas Instruments Incorporated nor the names of
 *    its contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
/*
 * Auto generated file
 */

#include "ti_drivers_config.h"

/*
 * GPIO
 */

/* ----------- GPIO Direction, Trigger, Interrupt initialization ----------- */

void GPIO_init()
{
    uint32_t    baseAddr;

    /* Instance 0 */
    /* Get address after translation translate */
    baseAddr = (uint32_t) AddrTranslateP_getLocalAddr(CONFIG_GPIO0_BASE_ADDR);

    GPIO_setDirMode(baseAddr, CONFIG_GPIO0_PIN, CONFIG_GPIO0_DIR);
    /* Instance 1 */
    /* Get address after translation translate */
    baseAddr = (uint32_t) AddrTranslateP_getLocalAddr(CONFIG_GPIO2_BASE_ADDR);
    GPIO_pinWriteLow(baseAddr, CONFIG_GPIO2_PIN);

    GPIO_setDirMode(baseAddr, CONFIG_GPIO2_PIN, CONFIG_GPIO2_DIR);
}


/* ----------- GPIO Interrupt de-initialization ----------- */
void GPIO_deinit()
{

}


/*
 * GPMC
 */

/* GPMC attributes */
static GPMC_HwAttrs gGpmcAttrs[CONFIG_GPMC_NUM_INSTANCES] =
{
    {
        .gpmcBaseAddr         = CSL_GPMC0_CFG_U_BASE,
        .dataBaseAddr         = CSL_GPMC0_MEM_U_BASE,
        .inputClkFreq         = 100000000U,
        .intrNum              = CSLR_R5FSS0_CORE0_GPMC_SINTR,
        .intrPriority         = 4U,
        .chipSelBaseAddr      = 0x68000000U,
        .chipSelAddrSize      = GPMC_CS_MASK_ADDR_SIZE_16MB,
        .clkDivider           = CSL_GPMC_CONFIG1_GPMCFCLKDIVIDER_DIVBY1,
        .waitPinNum           = CSL_GPMC_CONFIG1_WAITPINSELECT_W0,
        .addrDataMux          = CSL_GPMC_CONFIG1_MUXADDDATA_NONMUX,
        .timeLatency          = CSL_GPMC_CONFIG1_TIMEPARAGRANULARITY_X1,
        .waitPinPol           = CSL_GPMC_CONFIG_WAIT0PINPOLARITY_W0ACTIVEL,
        .timingParams         =
        {
            .csOnTime               =   3,
            .csRdOffTime            =   21,
            .csWrOffTime            =   21,
            .advOnTime              =   1,
            .advRdOffTime           =   3,
            .advWrOffTime           =   3,
            .advAadMuxOnTime        =   1,
            .advAadMuxRdOffTime     =   2,
            .advAadMuxWrOffTime     =   2,
            .weOnTtime              =   10,
            .weOffTime              =   16,
            .oeOnTime               =   10,
            .oeOffTime              =   1,
            .oeAadMuxOnTime         =   1,
            .oeAadMuxOffTime        =   15,
            .pageBurstAccess        =   3,
            .rdAccessTime           =   16,
            .wrAcessTime            =   8,
            .rdCycleTime            =   23,
            .wrCycleTime            =   23,
            .wrDataOnMuxBusTime     =   0,
            .cycle2CycleDelay       =   0,
            .cycleDelaySameChipSel  =   CSL_GPMC_CONFIG6_CYCLE2CYCLESAMECSEN_NOC2CDELAY,
            .cycleDelayDiffChipSel  =   CSL_GPMC_CONFIG6_CYCLE2CYCLEDIFFCSEN_NOC2CDELAY,
            .busTurnAroundTime      =   1,
        },
        .readType               =   CSL_GPMC_CONFIG1_READTYPE_RDASYNC,
        .csExDelay              =   CSL_GPMC_CONFIG2_CSEXTRADELAY_NOTDELAYED,
        .accessType             =   CSL_GPMC_CONFIG1_READMULTIPLE_RDSINGLE,
    },
};
/* GPMC objects - initialized by the driver */
static GPMC_Object gGpmcObjects[CONFIG_GPMC_NUM_INSTANCES];
/* GPMC driver configuration */
GPMC_Config gGpmcConfig[CONFIG_GPMC_NUM_INSTANCES] =
{
    {
        &gGpmcAttrs[CONFIG_GPMC0],
        &gGpmcObjects[CONFIG_GPMC0],
    },
};

uint32_t gGpmcConfigNum = CONFIG_GPMC_NUM_INSTANCES;


#include <drivers/gpmc/v0/dma/gpmc_dma.h>
GPMC_DmaConfig gGpmcDmaConfig[CONFIG_GPMC_NUM_DMA_INSTANCES] =
{
};

uint32_t gGpmcDmaConfigNum = CONFIG_GPMC_NUM_DMA_INSTANCES;


/*
 * I2C
 */

/* I2C Attributes */
static I2C_HwAttrs gI2cHwAttrs[CONFIG_I2C_HLD_NUM_INSTANCES] =
{
    {
        .baseAddr       = CSL_I2C2_U_BASE,
        .intNum         = 46,
        .eventId        = 0,
        .funcClk        = 96000000U,
        .enableIntr     = 1,
        .ownTargetAddr   = 0x1C,
    },
};

/* I2C Objects - Initialized by the Driver */
static I2C_Object gI2cObjects[CONFIG_I2C_HLD_NUM_INSTANCES];

/* I2C driver configuration */
I2C_Config gI2cConfig[CONFIG_I2C_HLD_NUM_INSTANCES] =
{
    {
        .object = &gI2cObjects[CONFIG_I2C0],
        .hwAttrs = &gI2cHwAttrs[CONFIG_I2C0]
    },
};

uint32_t gI2cConfigNum = CONFIG_I2C_HLD_NUM_INSTANCES;

/*
 * UART
 */

/* UART atrributes */
static UART_Attrs gUartAttrs[CONFIG_UART_NUM_INSTANCES] =
{
        {
            .baseAddr           = CSL_UART0_U_BASE,
            .inputClkFreq       = 48000000U,
        },
};
/* UART objects - initialized by the driver */
static UART_Object gUartObjects[CONFIG_UART_NUM_INSTANCES];
/* UART driver configuration */
UART_Config gUartConfig[CONFIG_UART_NUM_INSTANCES] =
{
        {
            &gUartAttrs[CONFIG_UART_CONSOLE],
            &gUartObjects[CONFIG_UART_CONSOLE],
        },
};

uint32_t gUartConfigNum = CONFIG_UART_NUM_INSTANCES;

#include <drivers/uart/v0/lld/dma/uart_dma.h>
UART_DmaHandle gUartDmaHandle[] =
{
};

uint32_t gUartDmaConfigNum = CONFIG_UART_NUM_DMA_INSTANCES;

void Drivers_uartInit(void)
{
    UART_init();
}

/*
 * MCU_LBIST
 */

uint32_t gMcuLbistTestStatus = 0U;

void SDL_lbist_selftest(void)
{
}

void Pinmux_init(void);
void PowerClock_init(void);
void PowerClock_deinit(void);
/*
 * Common Functions
 */
void System_init(void)
{
    /* DPL init sets up address transalation unit, on some CPUs this is needed
     * to access SCICLIENT services, hence this needs to happen first
     */
    Dpl_init();

    
    /* initialize PMU */
    CycleCounterP_init(SOC_getSelfCpuClk());

    PowerClock_init();
    /* Now we can do pinmux */
    Pinmux_init();
    /* finally we initialize all peripheral drivers */
    GPIO_init();
    GPMC_init();


    I2C_init();

    Drivers_uartInit();
}

void System_deinit(void)
{
    GPIO_deinit();
    GPMC_deinit();


    I2C_deinit();

    UART_deinit();
    PowerClock_deinit();

    Dpl_deinit();
}

 

Screenshot 2025-11-12 160241.pngScreenshot 2025-11-12 160310.png

  • /*
     *  Copyright (C) 2024 Texas Instruments Incorporated
     *
     *  Redistribution and use in source and binary forms, with or without
     *  modification, are permitted provided that the following conditions
     *  are met:
     *
     *    Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     *    Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the
     *    distribution.
     *
     *    Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     */
    
    #include <kernel/dpl/DebugP.h>
    #include "ti_drivers_open_close.h"
    #include "ti_board_open_close.h"
    #include "ti_drivers_config.h"
    
    
    extern GPMC_Config gGpmcConfig[];
    extern uint32_t gGpmcConfigNum;
    
    
    
    
    
    #if defined(SOC_AM64X) || defined(SOC_AM243X)
    #define APP_GPMC_PSRAM_OFFSET_BASE  (1024*1024)
    #define APP_GPMC_DATA_SIZE          (2*1024*1024)
    
    uint8_t gGpmcTxBuf[APP_GPMC_DATA_SIZE] __attribute__((aligned(64), section("ddr_data"))) ;
    /* read buffer MUST be cache line aligned when using DMA, we aligned to 64B though 32B is enough */
    uint8_t gGpmcRxBuf[APP_GPMC_DATA_SIZE] __attribute__((aligned(64), section("ddr_data")));
    
    #else
    #define APP_GPMC_PSRAM_OFFSET_BASE  (1024*80)
    #define APP_GPMC_DATA_SIZE          (1024*40)
    
    // GPMC_Handle gGpmcHandle;
    
    
    uint8_t gGpmcTxBuf[APP_GPMC_DATA_SIZE] ;
    /* read buffer MUST be cache line aligned when using DMA, we aligned to 128B though 32B is enough */
    uint8_t gGpmcRxBuf[APP_GPMC_DATA_SIZE];
    #endif
    
    #define NO_OF_ITERATIONS            (1U)
    
    void gpmc_psram_io_fill_buffers();
    int32_t gpmc_psram_io_compare_buffers();
    
    
    
    void GPMC_reconfigureTiming(void)
    {
        /* Access SysConfig-generated instance 0 */
        GPMC_HwAttrs *attrs = (GPMC_HwAttrs *)gGpmcConfig[0].attrs;
    
        /* Modify timing parameters safely */
        attrs->timingParams.csOnTime               = 0;//////////////////////
        attrs->timingParams.csRdOffTime            = 21;
        attrs->timingParams.csWrOffTime            = 21;////////////////////////////
        attrs->timingParams.advOnTime              = 1;
        attrs->timingParams.advRdOffTime           = 3;
        attrs->timingParams.advWrOffTime           = 3;
        attrs->timingParams.weOnTtime              = 2;/////////////////////
        attrs->timingParams.weOffTime              = 16;////////////////////////////
        attrs->timingParams.oeOnTime               = 10;
        attrs->timingParams.oeOffTime              = 1;
        attrs->timingParams.rdAccessTime           = 16;
        attrs->timingParams.wrAcessTime            = 18;/////////////////////////
        attrs->timingParams.rdCycleTime            = 23;
        attrs->timingParams.wrCycleTime            = 23;///////////////////
        attrs->timingParams.busTurnAroundTime      = 1;
        attrs->timingParams.pageBurstAccess        = 1;/////////////////////////
        attrs->timingParams.cycle2CycleDelay       = 0;///////////////////////
        attrs->timingParams.cycleDelaySameChipSel  = CSL_GPMC_CONFIG6_CYCLE2CYCLESAMECSEN_NOC2CDELAY;
    
        DebugP_log("GPMC timing parameters updated manually.\n");
    }
    
    void Gpmc_write()
    {
        GPMC_norWriteData(gGpmcHandle[0], 0x04F0, gGpmcTxBuf, 5);
        DebugP_log("GPMC data is written!\n");
    }
    
    
    void Duagon_interface(void *args)
    {
        
        int32_t status = SystemP_SUCCESS;
        uint32_t iter = 0;    
    
        GPMC_reconfigureTiming();
        /* Open GPMC Driver, among others */
        Drivers_open();
        /* Open Psram drivers with GPMC instance as input */
        status = Board_driversOpen();
        DebugP_assert(status==SystemP_SUCCESS);
    
        
    
        /* Initializing the driver */
        GPMC_init();
    
        /*Initializing default parameters */
        GPMC_Params_init(&gGpmcParams[0]);
    
        /*Modifying params as per your memory device */
        gGpmcParams[0].devType = CSL_GPMC_CONFIG1_DEVICETYPE_NORLIKE;
        gGpmcParams[0].devSize = CSL_GPMC_CONFIG1_DEVICESIZE_EIGHTBITS;
        gGpmcParams[0].chipSel = 0;
        gGpmcParams[0].intrEnable = FALSE;
        gGpmcParams[0].dmaEnable = FALSE;
    
        /*Open GPMC instance (index 0 usually) */
        gGpmcHandle[0] = GPMC_open(0, &gGpmcParams[0]);
    
        if (gGpmcHandle[0] == NULL)
        {
            DebugP_log("GPMC open failed!\n");
            while(1);
        }
    
    
            gGpmcTxBuf[0]   = 0x00;
            gGpmcTxBuf[1]   = 0xFF; 
            gGpmcTxBuf[2]   = 0x00;
            gGpmcTxBuf[3]   = 0xFF;
            gGpmcTxBuf[4]   = 0x00;
            gGpmcTxBuf[5]   = 0x20;
            gGpmcTxBuf[6]   = 0x10;
            gGpmcTxBuf[7]   = 0x80;
            gGpmcTxBuf[8]   = 0x0F;
            gGpmcTxBuf[9]   = 0xF0;
    
        
           
        //Configuring timing (this pulls gGpmcConfig[]) */
       
    
        GPMC_configureTimingParameters(gGpmcHandle[0]);
    
        GPMC_setDeviceType(gGpmcHandle[0]);
        GPMC_setDeviceSize(gGpmcHandle[0]);
    
        DebugP_log("GPMC initialized successfully!\n");
    
        Gpmc_write();
        // GPMC_norWriteData(gGpmcHandle, 0x0000, gGpmcTxBuf, 256);
    
        Board_driversClose();
        Drivers_close();
    }
    
    
    
    
    

    This is my .c code which I am using to config GPMC.
    And the code which is posted along with my question before is my driver_config.c file which is being generated through sys.config

      

  • Hi,
    i have just checked, it seems there is a bug in syscfg template, will fix it in the upcoming release - mid december.

    Regards,
    Shivank

  • Hi,
    For a quick fix, navigate to - "sdk_path/source/sysconfig/drivers/.meta/gpmc/templates/gpmc_v1_config.c.xdt".
    Search and replace - "deviceConfig.timingParams" to "config"

    this will allow the drivers_config to fetch syscfg changes.

    Regards,
    Shivan

  • Hi,
    I have tried this timings are being reflected in driver config.c, however "addrDataMux & timeLatency" is not also being updated so i did the same for these and now all the sys.config changes are being reflected in driver config.c.

    I am able to configure write cycle timings and they are fine while performing write operation using norwrite function, but if I tried to read using nor read function even if I specify the length as 1 it is generating 4 IOR, CS cycles and if keep length as any other number it is like len *4.


    I am using the function "
    GPMC_norReadData(GPMC_Handle handle, uint32_t offsetuint8_t *buf, uint32_t len)" from gpmc_norlike_v0.c

    I am attaching the sys.config data generated in driver config file and I have made page burst to 0.

    Also I am attaching signals captured from logic analyzer

    static GPMC_HwAttrs gGpmcAttrs[CONFIG_GPMC_NUM_INSTANCES] =
    {
        {
            .gpmcBaseAddr         = CSL_GPMC0_CFG_U_BASE,
            .dataBaseAddr         = CSL_GPMC0_MEM_U_BASE,
            .inputClkFreq         = 100000000U,
            .intrNum              = CSLR_R5FSS0_CORE0_GPMC_SINTR,
            .intrPriority         = 4U,
            .chipSelBaseAddr      = 0x68000000U,
            .chipSelAddrSize      = GPMC_CS_MASK_ADDR_SIZE_16MB,
            .clkDivider           = CSL_GPMC_CONFIG1_GPMCFCLKDIVIDER_DIVBY1,
            .waitPinNum           = CSL_GPMC_CONFIG1_WAITPINSELECT_W0,
            .addrDataMux          = CSL_GPMC_CONFIG1_MUXADDDATA_NONMUX,
            .timeLatency          = CSL_GPMC_CONFIG1_TIMEPARAGRANULARITY_X2,
            .waitPinPol           = CSL_GPMC_CONFIG_WAIT0PINPOLARITY_W0ACTIVEL,
            .timingParams         =
            {
                .csOnTime               =   0,
                .csRdOffTime            =   25,
                .csWrOffTime            =   25,
                .advOnTime              =   1,
                .advRdOffTime           =   3,
                .advWrOffTime           =   3,
                .advAadMuxOnTime        =   1,
                .advAadMuxRdOffTime     =   2,
                .advAadMuxWrOffTime     =   2,
                .weOnTtime              =   5,
                .weOffTime              =   20,
                .oeOnTime               =   5,
                .oeOffTime              =   20,
                .oeAadMuxOnTime         =   1,
                .oeAadMuxOffTime        =   15,
                .pageBurstAccess        =   0,
                .rdAccessTime           =   25,
                .wrAcessTime            =   25,
                .rdCycleTime            =   30,
                .wrCycleTime            =   30,
                .wrDataOnMuxBusTime     =   0,
                .cycle2CycleDelay       =   0,
                .cycleDelaySameChipSel  =   CSL_GPMC_CONFIG6_CYCLE2CYCLESAMECSEN_NOC2CDELAY,
                .cycleDelayDiffChipSel  =   CSL_GPMC_CONFIG6_CYCLE2CYCLEDIFFCSEN_NOC2CDELAY,
                .busTurnAroundTime      =   0,
            },
            .readType               =   CSL_GPMC_CONFIG1_READTYPE_RDASYNC,
            .csExDelay              =   CSL_GPMC_CONFIG2_CSEXTRADELAY_NOTDELAYED,
            .accessType             =   CSL_GPMC_CONFIG1_READMULTIPLE_RDSINGLE,
        },
    };

    @selva@ti.com
     

    @prayag.sahoo@ti.com

    @rajesh.penchala@hbl.in

    @varma.svrp@hbl.in