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.

AM335x GPMC NOR Flash problem

Other Parts Discussed in Thread: AM3358

Hi,

I have the following GPMC configuration on a AM3358 device to NOR FLASH (Spansion S29GL101GP):

- NOR Flash attached to CS0 of GPMC with NON multiplexed address and data bus
- NOR flash is mapped to address 0x10000000 ( 16MB)

 following is the code:
       

        base_addr = 0x10000000;

         /* Auto Select Entry */
        *((unsigned short *)base_addr + 0x555) = 0x00AA; /* write unlock cycle 1 */
        *((unsigned short *)base_addr + 0x2AA) = 0x0055; /* write unlock cycle 2 */
        *((unsigned short *)base_addr + 0x555) = 0x0090; /* write autoselect command */

         //Read Manufacturer Id
         manuf_id = *((unsigned short *)base_addr + 0x00); /* read manuf. id */

          //Read Device Id
         Dev_id_1 = *((unsigned short *)base_addr + 0x001); /* read Dev. id */

         //Read Device Id
         Dev_id_2 = *((unsigned short *)base_addr + 0xE); /* read Dev. id */





This code does put the NOR Flash into "AutoSelect" mode and reads manufacturer code, device code and block protection status of first block.
The code works fine if I step over the code in CCS and the signals on the scope look as they should.
But I could able to read Manufacturer Id 0x01, but Dev ID reading as 0xFFFF instead 0x227E.

I have changed GPMC configuration to NOR FLASH type,16 bit bus width with reference of NAND read write code . Following is the configuration of GPMC. Let me know any other configuration need to change.


GPMC_A1 to GPMC_A26 address lines and GPMC_DQ0 to GPMC_DQ15 data lines used.

/*****************************************************************************/
/*
** Macros which defines the NAND timing info.
**
*/
#define NAND_CSWROFFTIME                        (30)
#define NAND_CSRDOFFTIME                        (31)
#define NAND_CSONTIME                           (0)

#define NAND_ADVONTIME                          (0)
#define NAND_ADVAADMUXONTIME                    (0)
#define NAND_ADVRDOFFTIME                       (31)
#define NAND_ADVWROFFTIME                       (31)
#define NAND_ADVAADMUXRDOFFTIME                 (0)
#define NAND_ADVAADMUXWROFFTIME                 (0)

#define NAND_WEOFFTIME                          (31)
#define NAND_WEONTIME                           (3)
#define NAND_OEAADMUXOFFTIME                    (31)
#define NAND_OEOFFTIME                          (31)
#define NAND_OEAADMUXONTIME                     (3)
#define NAND_OEONTIME                           (1)

#define NAND_RDCYCLETIME                        (31)
#define NAND_WRCYCLETIME                        (31)
#define NAND_RDACCESSTIME                       (28)
#define NAND_PAGEBURSTACCESSTIME                (0)

#define NAND_BUSTURNAROUND                      (0)
#define NAND_CYCLE2CYCLEDIFFCSEN                (0)
#define NAND_CYCLE2CYCLESAMECSEN                (1)
#define NAND_CYCLE2CYCLEDELAY                   (0)
#define NAND_WRDATAONADMUXBUS                   (15)
#define NAND_WRACCESSTIME                       (22)

int GPMC_NOR_CONFIG()
{
    volatile unsigned int conf = 0;
    volatile unsigned int i = 0;
    volatile unsigned short int p_read[20000];// = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};


    GPMCClkConfig();

    GPMCModuleSoftReset(SOC_GPMC_0_REGS);

    while (GPMCModuleResetStatusGet(SOC_GPMC_0_REGS) != 1);

    GPMCIdleModeSelect(SOC_GPMC_0_REGS, GPMC_IDLEMODE_NOIDLE);

    GPMCCSConfig(SOC_GPMC_0_REGS, GPMC_CHIP_SELECT_0, GPMC_CS_DISABLE); // Chip Select should be disabled when the GPMC configuration is being done..

    /* Disable all interrupts */
    GPMCIntDisable(SOC_GPMC_0_REGS, GPMC_FIFOEVENT_INT);
    GPMCIntDisable(SOC_GPMC_0_REGS, GPMC_TERMINALCOUNT_INT);
    GPMCIntDisable(SOC_GPMC_0_REGS, GPMC_WAIT0EDGEDETECTION_INT);
    GPMCIntDisable(SOC_GPMC_0_REGS, GPMC_WAIT1EDGEDETECTION_INT);

    /* Timeout control disable */
    GPMCTimeOutFeatureConfig(SOC_GPMC_0_REGS, GPMC_TIMEOUTFEATURE_DISABLE);



    GPMCWaitPinSelect(SOC_GPMC_0_REGS, GPMC_CHIP_SELECT_0, GPMC_WAIT_PIN0);
    GPMCWaitPinPolaritySelect(SOC_GPMC_0_REGS, GPMC_WAIT_PIN0,GPMC_WAIT_PIN_POLARITY_LOW);
    GPMCWriteProtectPinLevelCtrl(SOC_GPMC_0_REGS, GPMC_WP_PIN_LEVEL_HIGH);
    //GPMCWriteProtectPinLevelCtrl(SOC_GPMC_0_REGS, GPMC_FORCEPOSTEDWRITE_ENABLE);//GPMC_FORCEPOSTEDWRITE_ENABLE


    //configuration as per Table 7-27 of TRM [NOR Memory Type]
    GPMCDevTypeSelect(SOC_GPMC_0_REGS, GPMC_CHIP_SELECT_0, GPMC_DEVICETYPE_NORLIKE); // NOR type Device selected on GPMC.
    GPMCDevSizeSelect(SOC_GPMC_0_REGS, GPMC_CHIP_SELECT_0, GPMC_DEVICESIZE_16BITS); // 16 bit NOR device selected.
    GPMCAddrDataMuxProtocolSelect(SOC_GPMC_0_REGS, GPMC_CHIP_SELECT_0, GPMC_MUXADDDATA_NOMUX ); // Address Data NON Multiplexing
    // GPMCDevPageLenSet(SOC_GPMC_0_REGS, GPMC_CHIP_SELECT_0,GPMC_DEV_PAGELENGTH_FOUR); // ****This should not be effective as the page length will be supported in synchronous mode
    //GPMCSyncWrapBurstConfig(SOC_GPMC_0_REGS, GPMC_CHIP_SELECT_0,GPMC_WRAPBURST_DISABLE); // We are not using syncronous mode so this statement is not effective
    GPMCTimeParaGranularitySelect(SOC_GPMC_0_REGS, GPMC_CHIP_SELECT_0, GPMC_TIMEPARAGRANULARITY_X2); //GPMC_TIMEPARAGRANULARITY_X1// support for slower devices
    GPMCFclkDividerSelect(SOC_GPMC_0_REGS, GPMC_CHIP_SELECT_0,GPMC_FCLK_DIV_BY_4); // GPMC_CLK :- clock division by 4 i.e. 100MHZ /4 = 25MHZ TODO:- Need to confirm on this
    // GPMCClkActivationTimeConfig(SOC_GPMC_0_REGS, GPMC_CHIP_SELECT_0,GPMC_CLKACTIVATIONTIME_ATSTART ); // Not needed in our case, is valid for synchronous read write
    GPMCAccessTypeSelect(SOC_GPMC_0_REGS, GPMC_CHIP_SELECT_0, GPMC_MODE_READ, GPMC_ACCESSTYPE_SINGLE); // single read access
    GPMCReadTypeSelect(SOC_GPMC_0_REGS, GPMC_CHIP_SELECT_0, GPMC_READTYPE_ASYNC); // read type asynchronous
    GPMCAccessTypeSelect(SOC_GPMC_0_REGS, GPMC_CHIP_SELECT_0, GPMC_MODE_WRITE, GPMC_ACCESSTYPE_SINGLE); // single write access
    GPMCWriteTypeSelect(SOC_GPMC_0_REGS, GPMC_CHIP_SELECT_0, GPMC_WRITETYPE_ASYNC); // write type asynchornous

    //configuration as per Table 7-28 of TRM [NOR Chip Select Configuration]
    //GPMCBaseAddrSet(SOC_GPMC_0_REGS, GPMC_CHIP_SELECT_0, 0x10); // A29:A24 = 010000
    //GPMCMaskAddrSet(SOC_GPMC_0_REGS, GPMC_CHIP_SELECT_0, GPMC_CS_SIZE_16MB); //16MB

    GPMCBaseAddrSet(SOC_GPMC_0_REGS, 0, 0x10000000 >> 24);
    GPMCMaskAddrSet(SOC_GPMC_0_REGS, 0, GPMC_CS_SIZE_16MB);


    // NOR Timing Configuration has to be completed on 10/08/2015 by Mohit Hada

    // CS# de-assertion time from start cycle time for write accesses - NAND_CSWROFFTIME
    // CS# de-assertion time from start cycle time for read accesses - NAND_CSRDOFFTIME
    // CS# assertion time from start cycle time - NAND_CSONTIME
    // No extra delay added.
    // Check section 7.1.3.3.9.2 of TRM for details on this

    conf = GPMC_CS_TIMING_CONFIG(NAND_CSWROFFTIME,
                                    NAND_CSRDOFFTIME,
                                    0,
                                    NAND_CSONTIME);

    GPMCCSTimingConfig(SOC_GPMC_0_REGS, GPMC_CHIP_SELECT_0, conf);

    // ADV# de-assertion time from start cycle time for write accesses - NAND_ADVWROFFTIME
    // ADV# de-assertion time from start cycle time for read accesses - NAND_ADVRDOFFTIME
    // ADV# assertion for first address phase when using the AADMultiplexed protocol - NAND_ADVONTIME
    // Check section 7.1.3.3.9.3 of TRM for details on this

    conf = GPMC_ADV_TIMING_CONFIG(NAND_ADVAADMUXWROFFTIME,
                                    NAND_ADVAADMUXRDOFFTIME,
                                    NAND_ADVWROFFTIME,
                                    NAND_ADVRDOFFTIME,
                                    0,
                                    NAND_ADVAADMUXONTIME,
                                    NAND_ADVONTIME);

    GPMCADVTimingConfig(SOC_GPMC_0_REGS, GPMC_CHIP_SELECT_0, conf);


    // TODO:- Will check this?

    conf = GPMC_WE_OE_TIMING_CONFIG(NAND_WEOFFTIME,
                                        0,
                                        NAND_WEONTIME,
                                        NAND_OEAADMUXOFFTIME,
                                        NAND_OEOFFTIME,
                                        0,
                                        NAND_OEAADMUXONTIME,
                                        NAND_OEONTIME);

    GPMCWEAndOETimingConfig(SOC_GPMC_0_REGS, GPMC_CHIP_SELECT_0, conf);

    conf = GPMC_RDACCESS_CYCLETIME_TIMING_CONFIG(NAND_RDCYCLETIME,
                                                    NAND_WRCYCLETIME,
                                                    NAND_RDACCESSTIME,
                                                    NAND_PAGEBURSTACCESSTIME);

    GPMCRdAccessAndCycleTimeTimingConfig(SOC_GPMC_0_REGS, GPMC_CHIP_SELECT_0, conf);

    // TODO:- Will check this?
    conf = GPMC_CYCLE2CYCLE_BUSTURNAROUND_TIMING_CONFIG(
                                                    NAND_CYCLE2CYCLEDELAY,
                                                    NAND_CYCLE2CYCLESAMECSEN,
                                                    NAND_CYCLE2CYCLEDIFFCSEN,
                                                    NAND_BUSTURNAROUND
                                                    );

    GPMCycle2CycleAndTurnArndTimeTimingConfig(SOC_GPMC_0_REGS, GPMC_CHIP_SELECT_0, conf);

    GPMCWrAccessAndWrDataOnADMUXBusTimingConfig(SOC_GPMC_0_REGS,
                                                    GPMC_CHIP_SELECT_0,
                                                    NAND_WRACCESSTIME,
                                                    NAND_WRDATAONADMUXBUS);

    GPMCCSConfig(SOC_GPMC_0_REGS, GPMC_CHIP_SELECT_0, GPMC_CS_ENABLE); // Chip Select should be enabled after the GPMC configuration is done..

    return 0;
}

Thanks & Regards,

Sudheer A.