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.

GPMC Interfacing

Other Parts Discussed in Thread: AM4379, SYSBIOS

Hi,

We are using GPMC interface of AM4379 to connect an FPGA chip in following mode.


1)NOR type Synchronous 16 bit address/data multiplexed memory device(only using AD0- 15)
2)FPGA is connnectd to Chip select 0(base address is 0x00000000)
3)FPGA CLock frequency at 50 Mhz..

In datasheet,it is mentioned that the first 1MB of address space 0x0-0xFFFFF is inaccessible externally.So we used BASE address as 0x00100000.

After initialization, when we tried to read from GPMC interface as follows

value = ((*(volatile unsigned short *)(0x00100000)));    

We are not seeing any activity on GPMC Lines and Processor is getting getting struck at this line . Can you please help us on this?

we initialized the FPGA as follows..

#define FPGA_BASE_ADDRSS 0x00100000

gpmcCfgObj_t fpga_param =
{
0x50000000,
0,
GPMC_CHIP_SEL_0
};

gpmcChipSelTimingParams_t fpga_cs =
{
0x11, //chipSelWrOffTime
0x11, //chipSelRdOffTime
FALSE, //addExtDelay
0x0 //chipSelOnTime

};

gpmcAdvSignalTimingParams_t fpga_adv =
{
0x0, //advAadMuxWrOffTime;
0x0, //advAadMuxRdOffTime;
0x02, //advWrOffTime
0x02, //advRdOffTime
FALSE, //addExtDelay
0, //advAadMuxOnTime
0 //advOnTime
};


gpmcOeWeSignalTimingParams_t fpga_oe =
{
0x11, //writeEnableOffTime
0x03, //writeEnableOnTime
0x0, //oeAadMuxOffTime
0x11, //oeOffTime
FALSE, //addExtDelay
0x0, //oeAadMuxOnTime
0x03 //oeOnTime
};
gpmcReadAccessTime_t fpga_rd =
{
0x11, //readCycleTime
0x11, //writeCycleTime
0x10, //readAccessTime
0x00, //pageBurstAccessTime
};

gpmcCycle2CycleDelay_t fpga_cycle =
{
1,
GPMC_CYCLE_DELAY_SAME_CHIP_SEL_DELAY,
GPMC_CYCLE_DELAY_DIFF_CHIP_SEL_DELAY,
0
};

gpmcCfgObj_t *pGpmcinit;

/* ========================================================================== */
/* Function Definitions */
/* ========================================================================== */

int32_t ConfigFpga(void)
{
int32_t status = S_PASS;
/*initialize GPMC module instance */
status = InitGpmc();
if(status == S_PASS)
{
/*initialize FPGA */
status= InitFpga();
}

return status;
}


int32_t InitGpmc(void)
{
int32_t status = S_PASS;
pGpmcinit = &fpga_param;
/*initialize clock for GPMC Module*/
status = PRCMModuleEnable(CHIPDB_MOD_ID_GPMC, 0U, 0U);

if(status == S_PASS)
{
/* PinMux Configuration */
status = PINMUXModuleConfig(CHIPDB_MOD_ID_GPMC, 0U,
NULL);
}

return status;
}

int32_t InitFpga(void)
{
int32_t status = S_PASS;
int16_t value;
volatile int32_t timeOut;
int i;
timeOut =0xFFFF;

/*Reset GPMC Module*/
GPMCModuleReset(pGpmcinit->gpmcBaseAddr);

/*Check reset done or not*/
while((GPMCIsModuleResetDone(pGpmcinit->gpmcBaseAddr) != 1) && (timeOut != 0))
{
timeOut--;
}
if(timeOut == 0)
{
return (FALSE);
}

GPMCSetIdleMode(pGpmcinit->gpmcBaseAddr, GPMC_IDLE_MODE_NO_IDLE);

/* Disable all interrupts */
GPMCIntrDisable(pGpmcinit->gpmcBaseAddr, GPMC_INTR_MASK_ALL);

/* Timeout control disable */
GPMCTimeoutEnable(pGpmcinit->gpmcBaseAddr, FALSE);

GPMCChipSelEnable(pGpmcinit->gpmcBaseAddr,pGpmcinit->csNum,FALSE);


/*Set device type as NOR*/
GPMCSetDevType(pGpmcinit->gpmcBaseAddr,pGpmcinit->csNum,GPMC_DEV_TYPE_NOR);
/*Set device size as 16 bit*/
GPMCSetDevSize(pGpmcinit->gpmcBaseAddr,pGpmcinit->csNum,GPMC_DEV_SIZE_16BIT);
/*Set as Address and Data Multiplexed device.*/
GPMCSetAddrDataMuxType(pGpmcinit->gpmcBaseAddr,pGpmcinit->csNum,GPMC_MUX_TYPE_ADDR_DATA);
/*Disable Interrupt*/
GPMCIntrDisable(pGpmcinit->gpmcBaseAddr,GPMC_INTR_MASK_ALL);

GPMCSetTimeParaGranularity (pGpmcinit->gpmcBaseAddr,pGpmcinit->csNum,GPMC_TIME_GRANULARITY_X1);
GPMCSetFclkDivider(pGpmcinit->gpmcBaseAddr,pGpmcinit->csNum,GPMC_FCLK_DIVIDER_2); //fclk/2
GPMCSetClkActivationTime(pGpmcinit->gpmcBaseAddr,pGpmcinit->csNum,0x01);


/* set single read and single write mode */
GPMCSetAccessType(pGpmcinit->gpmcBaseAddr,pGpmcinit->csNum,GPMC_ACCESS_TYPE_SYNC_READ);
GPMCSetAccessType(pGpmcinit->gpmcBaseAddr,pGpmcinit->csNum,GPMC_ACCESS_TYPE_SYNC_WRITE);
GPMCSetAccessMode(pGpmcinit->gpmcBaseAddr,pGpmcinit->csNum,GPMC_OPER_MODE_READ,GPMC_ACCESS_MODE_SINGLE);
GPMCSetAccessMode(pGpmcinit->gpmcBaseAddr,pGpmcinit->csNum,GPMC_OPER_MODE_WRITE,GPMC_ACCESS_MODE_SINGLE);


/* base address and mask address */
/*32 Mb */
GPMCSetChipSelBaseAddr(pGpmcinit->gpmcBaseAddr, pGpmcinit->csNum, 0x01);
GPMCSetChipSelMaskAddr(pGpmcinit->gpmcBaseAddr, pGpmcinit->csNum, GPMC_CS_SIZE_32MB);


/* FPGA timings configuration */
GPMCChipSelectTimingConfig(pGpmcinit->gpmcBaseAddr, pGpmcinit->csNum,&fpga_cs);
GPMCAdvSignalTimingConfig(pGpmcinit->gpmcBaseAddr, pGpmcinit->csNum,&fpga_adv);
GPMCWeOeSignalTimingConfig(pGpmcinit->gpmcBaseAddr, pGpmcinit->csNum,&fpga_oe);
GPMCReadAccessTimingConfig(pGpmcinit->gpmcBaseAddr, pGpmcinit->csNum,&fpga_rd);
GPMCCycleDelayTimingConfig(pGpmcinit->gpmcBaseAddr, pGpmcinit->csNum,&fpga_cycle);
GPMCWriteAccessTimingConfig(pGpmcinit->gpmcBaseAddr, pGpmcinit->csNum,FPGA_WRACCESSTIME,FPGA_WRDATAONADMUXBUS);


/* Wait pin Configuration */
GPMCWaitPinMonitoringEnable(pGpmcinit->gpmcBaseAddr,pGpmcinit->csNum,GPMC_OPER_MODE_READ,GPMC_WAIT_PIN_MONITOR_DISABLE);
GPMCWaitPinMonitoringEnable(pGpmcinit->gpmcBaseAddr,pGpmcinit->csNum,GPMC_OPER_MODE_WRITE,GPMC_WAIT_PIN_MONITOR_DISABLE);

/* Enable Chip select */

GPMCChipSelEnable(pGpmcinit->gpmcBaseAddr,pGpmcinit->csNum,TRUE);

value= ((*(volatile unsigned short *)(0x00100000)));

return status;
}

  • Hi,

    What software are you using?
  • AM437x SDK with code composer studio 6.1
  • Hi Biser ,

    After initializing the GPMC , if i need to read from a particular memory location say 0x00100000 , is the following piece of code is correct?

    value= ((*(volatile unsigned short *)(0x00100000)));


    Regards,
    Jinu
  • Which SDK - Linux, RTOS, Industrial?
  • Hi Biser ,
    Thanks for reply.
    we are using am437x_sysbios_ind_sdk_2.0.0.1 SDK and AM437x IDK boards.

    Regards,
    Jinu
  • I will ask the software team to look into this.
  • Jinu,

    How the FPGA is connected to the AM437X IDK EVM?

    I looked at your code:

    The sequence initGpmc() to enable clk and pinmux are OK. Then initFpga(), this is similar to the sequence in our NAND W/R example NANDLibGpmcInit(), there is our code has /* Set the wait pin polarity */ in the example, do you need that?

    And for those configurations parameters: fpga_cs, fpga_adv, fpga_oe, fpga_rd, fpga_cycle, where did you get those number?

    Regards, Eric

  • Hi Eric,
    Thanks for the reply.
    1)We are using AM4379 Board not IDK.
    2)We disabled the wait pin monitoring in the above code. So does the wait pin polarity will have any impact?
    3)For fpga_cs, fpga_adv, fpga_oe, fpga_rd, fpga_cycle, we used the standard timing parameters from data sheet. and FPGA is programmed accordingly.

    Suppose if we run the above code on an IDK board(which dosent have anything connected to GPMC) After enabling the chip select line, if we try to access the memory region as follows, what will be the behavior?

    GPMCChipSelEnable(pGpmcinit->gpmcBaseAddr,pGpmcinit->csNum,TRUE);

    value= ((*(volatile unsigned short *)(0x00100000)));

    At present we are not seeing any activities on FPGA lines(cs,clock,oe enable etc.). what we expect is we can see the GPMC clock when we try to access the 0x00100000 memory region.

    so anything is wrong in the above initialization?
  • Hi Eric,
    Any updates on this?

  • Jinu,

    usual way will be Command followed by Address then wait for the data to receive.
    Not sure whether it supports memory mapped access like how you access them through pointers.

    Regards,
    Murali Krishna
  • HI Murali,

    Thnakyou so much for your reply on this.

    Can you please explain the above statement? because we connected a FPGA through GPMC.It can be programmed in any way which dosent require any command. NAND or NOR flash may require commands.

    Can you please tell me, if i want to access a memory location say 0x00400000 (which lies inside GPMC memory an we connected a NOR type Synchronous 16 bit address/data multiplexed memory device ) what i need to do?If i want to write to 0x0040000, what piece of code i need to write? I thought it is through pointers.

    If you want send any  command also, how can we do it? In GPMC, there is no data registers. So suppose if i want to send a command (say 16 bit) how can i send it?

    Regards,

    Jinu Jacob

    Regards,

    Jinu 

  • Jinu,

    "QSPI" Connected to serial Flash supports memory mapped mode. In such cases Access through Pointers is possible.

    If memory mapped mode is not supported, Conventional method of read command and address need to be sent to read from any particular address.

    In NANDs case, usually cmd(usually 8 bits), follwed by ColumnAddress and RowAddress is sent to access the NAND Array. (Need to check for NOR).

    Please go through GPMC Controller Registers and NOR Device Data sheet for getting idea on how to access.

    GPMC has COMMAND, ADDRESS, DATA registers for each chipselect.

    NOR is accessed in memory mapped way.

    -Murali Krishna

  • Hi Murali,

    In the above mail, you mentioned that If memory mapped mode is not supported, Conventional method of read command and address need to be sent to read from any particular address. GPMC is memory mapped right?

    1) We connected FPGA chip through GPMC interface.and device type is Address Data 16-Bit NOR Flash Type Device.

    I am not able to find out any registers related with NOR Commands for GPMC.

    Using this, I want to send a 16 bit Command(0xAAAA) to address location 0x00400000 for enabling the Flash chip.
    For this, in which GPMC register, i have to put data 0xAAAA and which register i have to set address?

    Regards,
    Jinu

  • Jinu,

    Please check AM437x Technical reference manual.

    Murali Krishna
  • Hi ,
    Please help us on this issue. i am not able to find out any of such register for NOR type implementation.
    I have gone through TRM. Can you please tell us page number ?

    Regards,
    Jinu
  • Jinu,

    Thanks for the question.
    NOR is accessed through memory mapped way, like the way you were accessing through pointers. ( I was wrong in earlier chain)
    where NAND can not be accessed in the same way but it should be acess through ADDRESS, DATA, COMMAND registers.

    Is the PinMux proper?
    Is the config registers timing values proper, like read access time, read cycle time etc. ?
    If you are using the code which is used for NAND then you should be focussing on differences in accessing the NAND and NOR in terms of sequence, timing parameters and PinMux.

    PinMux can make everything bad. Check schematics to configure it.

    Regards,
    Murali Krishna
  • Jinu,

    Found a reference for Interfacing NOR with GPMC in u-boot source code. Code is common for NAND and NOR.
    I Hope it will be useful for you to make out the differences easily.

    git.denx.de/

    Check the other dependent files aswell.

    Murali Krishna

  • Hi Murali,

    Please find the register settings below.

    #define GPMCBASE 0x00100000 /* Counter/Timer Base */
    #define PortValue ((volatile unsigned short *)(GPMCBASE + 0x00))

    void pinmux(void)
    {
    HW_WR_REG32(0x44E1087C, 0x40000); // CSn0 //pulldown
    HW_WR_REG32(0x44E1088C, 0x40000); // CLK //pullup
    HW_WR_REG32(0x44E10884, 0x00001); // CSn2 //dir //muxmode gpmc
    HW_WR_REG32(0x44E10898, 0x20000); // WEn //pullup
    HW_WR_REG32(0x44E10894, 0x20000); // OEn_REn //pullup
    HW_WR_REG32(0x44E10890, 0x00000); // ADVn_ALE //pulldown
    HW_WR_REG32(0x44E10878, 0x20000); // Be1 //pulldown
    HW_WR_REG32(0x44E1089C, 0x20000); // Be0 //pulldown


    HW_WR_REG32(0x44E10800, 0x40000); // AD0 //pulldown selected,rx active,
    HW_WR_REG32(0x44E10804, 0x40000); // AD1
    HW_WR_REG32(0x44E10808, 0x40000); // AD2
    HW_WR_REG32(0x44E1080C, 0x40000); // AD3
    HW_WR_REG32(0x44E10810, 0x40000); // AD4
    HW_WR_REG32(0x44E10814, 0x40000); // AD5
    HW_WR_REG32(0x44E10818, 0x40000); // AD6
    HW_WR_REG32(0x44E1081C, 0x40000); // AD7
    HW_WR_REG32(0x44E10820, 0x40000); // AD8
    HW_WR_REG32(0x44E10824, 0x40000); // AD9
    HW_WR_REG32(0x44E10828, 0x40000); // AD10
    HW_WR_REG32(0x44E1082C, 0x40000); // AD11
    HW_WR_REG32(0x44E10830, 0x40000); // AD12
    HW_WR_REG32(0x44E10834, 0x40000); // AD13
    HW_WR_REG32(0x44E10838, 0x40000); // AD14
    HW_WR_REG32(0x44E1083C, 0x40000); // AD15
    }

    void gpmc_read(void)
    {
    uint32_t temp;
    int32_t status = S_PASS;

    // Clear CSVALID
    temp = HW_RD_REG32((FPGA_REG_BASE+GPMC_CONFIG7(FPGA_GPMC_CS)));
    temp = temp & ~(1 << 6);
    HW_WR_REG32((FPGA_REG_BASE+GPMC_CONFIG7(FPGA_GPMC_CS)), temp);

    // AM339x GPMC Config Registers
    HW_WR_REG32((FPGA_REG_BASE+GPMC_CONFIG1(FPGA_GPMC_CS)), 0x28001201); // clkdiv=1,multplexed nor,16bit,read/write synchronous
    HW_WR_REG32((FPGA_REG_BASE+GPMC_CONFIG2(FPGA_GPMC_CS)), 0x000b0b00);//cs read/write off time 0,on time B
    HW_WR_REG32((FPGA_REG_BASE+GPMC_CONFIG3(FPGA_GPMC_CS)), 0x00020200);//advrd/write off time 2,on time 0
    HW_WR_REG32((FPGA_REG_BASE+GPMC_CONFIG4(FPGA_GPMC_CS)), 0x00000b03); //oe on time 3,offtime B
    HW_WR_REG32((FPGA_REG_BASE+GPMC_CONFIG5(FPGA_GPMC_CS)), 0x000a0b0b); //rd/write access time a,wr cycle time b,
    HW_WR_REG32((FPGA_REG_BASE+GPMC_CONFIG6(FPGA_GPMC_CS)), 0x0a070000); //wr access time a, write data on mux bus 7
    HW_WR_REG32((FPGA_REG_BASE+GPMC_CONFIG7(FPGA_GPMC_CS)), 0x00000F00); //cs size 16 mb,base address 16 mb

    // Set CSVALID
    temp = HW_RD_REG32(FPGA_REG_BASE+GPMC_CONFIG7(FPGA_GPMC_CS));
    temp = temp | (1 << 6);
    HW_WR_REG32(GPMC_CONFIG7(FPGA_REG_BASE+FPGA_GPMC_CS), temp);


    *PortValue = (unsigned short) 0xAA55;

    return status;
    }

    After performing the initialization, i checked the GPMC and control registers. it is properly initialized with the above mentioned values.

    But When we access the memory, we are not seeing any activities on GPMC lines and processor hangs.

    Do we need to set anything else?


    Regards,
    Jinu
  • Hi Murali,

    What we observed is if we comment the MMUConfigAndEnable() function,Then GPMC memory can be accessible .

    In example_utils_mmu.c file, We can see only the following 4 regions in MMU and not included GPMC module.

    MMUMemRegionMap(&regionDdr, (uint32_t*)pageTable);
    MMUMemRegionMap(&regionOcmc, (uint32_t*)pageTable);
    MMUMemRegionMap(&regionDev, (uint32_t*)pageTable);
    MMUMemRegionMap(&regionQspi, (uint32_t *)pageTable);


    What is the reason behind this? If we need to access GPMC memory, We need to add it here right?


    Regards,
    Jinu Jacob

  • Jinu, 

    Good obseravation.

    I think, Either  MMU should be disabled, or you can provide that region in MMU mapping like it is done in QSPI. Provide that region in &regsionGpmc and check the functionality.

    GPMC NOR requires memory mapping. GPMC is not added in as GPMC NOR example is not provided in starterware. Though there is GPMC NAND, it is not accessed in memory mapped way.

    Murali Krishna

  • Thanks Murali.
    :)

    Regards,
    Jinu
  • Jinu,
    Please post your observations here to enable GPMC NOR so that it will be easier for the forum users to refer.
    Thanks.-Murali Krishna
  • Sure. i will update.