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 NOR flash R/W issue

Hi, I am working on AM335x EVM NOR, I have taken reference of NandReadwrite example in starterware based on this i have changed GPMC configuration, #Profile selection is (0011) on DIp switch and NOR command sequence i followed as per datasheet (M29W).

I am not able to read Flash Device . For reference i have attached code.

Thanks in advance.


#include "consoleUtils.h"
#include "hw_gpmc.h"
#include "hw_types.h"
#include "soc_AM335x.h"
#include "interrupt.h"
#include "gpmc.h"
#include "nandlib.h"
#include "nand_gpmc.h"
#include "nandDma.h"
#include "evmAM335x.h"
#include "cache.h"
#include "mmu.h"
#include "M29W_device_driver.h"



#include "hw_control_AM335x.h"
//#include "soc_AM335x.h"
#include "hw_cm_wkup.h"
#include "hw_cm_per.h"
//#include "evmAM335x.h"
//#include "hw_types.h"
/*******************************************************************************
* INTERNAL MACRO DEFINITIONS
*******************************************************************************/

/* Definitions related to MMU Configuration. */
#define START_ADDR_DDR (0x80000000u)
#define START_ADDR_DEV (0x44000000u)
#define START_ADDR_OCMC (0x40300000u)
#define START_ADDR_SRAM (0x402F0000u)

#define NUM_SECTIONS_DDR (512u)
#define NUM_SECTIONS_DEV (960u)
#define NUM_SECTIONS_OCMC (1u)
#define NUM_SECTIONS_SRAM (1u)



/* #define NAND_DATAINTEGRITY_TEST_WITH_FIXED_ADDR */

/*****************************************************************************/
/*
** Macros which defines attached device info like num of pages per block,
** number of blocks, device ID and manufacturer ID.
**
*/
#define NAND_DATA_XFER_MODE (NAND_XFER_MODE_CPU)
#define NAND_BUSWIDTH (NAND_BUSWIDTH_8BIT)
#define NAND_CHIP_SELECT (NAND_CHIP_SELECT_0)
#define NAND_PAGE_SIZE_IN_BYTES (NAND_PAGESIZE_2048BYTES)
#define NAND_BLOCK_SIZE_IN_BYTES (NAND_BLOCKSIZE_128KB)
#define NAND_NUMOF_BLK (2048)
#define NAND_MANUFATURER_MICRON_ID (0x2C)
#define NAND_DEVICE_ID (0xDA)
#define MAX_VALUE_OF_CHAR (256)

/*****************************************************************************/
/*
** Macros which defines the read write size, buffer size and number of transfers
**
*/
#define NAND_DATA_BUFF_SIZE (NAND_PAGE_SIZE_IN_BYTES)
#define NAND_ECC_BUFF_SIZE ((NAND_PAGE_SIZE_IN_BYTES/NAND_BYTES_PER_TRNFS) \
* NAND_MAX_ECC_BYTES_PER_TRNFS)
/*****************************************************************************/
/*
** Macros which defines default block, page and num of pages for read/write.
**
*/
#define NAND_DEFAULT_START_PAGE (0)
#define NAND_DEFAULT_BLK (5)
#define NAND_DEFAULT_NMBR_OF_PAGES (1)

/*****************************************************************************/
/*
** Macros which defines the data integrity status.
**
*/
#define NAND_DATA_INTEGRITY_PASS (0)
#define NAND_DATA_INTEGRITY_FAIL (1)

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

#define NAND_ADVONTIME (0)
#define NAND_ADVAADMUXONTIME (0)
#define NAND_ADVRDOFFTIME (4) // For address data multiplexing , value has been changed from 31 to 4 by Mohit Hada - 10/08/2015
#define NAND_ADVWROFFTIME (4) // For address data multiplexing , value has been changed from 31 to 4 by Mohit Hada - 10/08/2015
#define NAND_ADVAADMUXRDOFFTIME (0)
#define NAND_ADVAADMUXWROFFTIME (0)

#define NAND_WEOFFTIME (30) // TODO:- just check if it can be reduced by '1'
#define NAND_WEONTIME (8) // Value has been modified from 3 to 8 , 4 GPMC_CLK cycles after ALE De-assertion
#define NAND_OEAADMUXOFFTIME (0) // Value has been changed from 31 to 0 as this is not being used in our application
#define NAND_OEOFFTIME (30) // TODO:- just check if it can be reduced by '1'
#define NAND_OEAADMUXONTIME (0) // Value has been changed from 31 to 0 as this is not being used in our application
#define NAND_OEONTIME (8) // Value has been modified from 1 to 8 , 4 GPMC_CLK cycles after ALE De-assertion

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

#define NAND_BUSTURNAROUND (0)
#define NAND_CYCLE2CYCLEDIFFCSEN (1) // changed to a value 1 from 0
#define NAND_CYCLE2CYCLESAMECSEN (1)
#define NAND_CYCLE2CYCLEDELAY (4) // changed to a value 4 from 0
#define NAND_WRDATAONADMUXBUS (15)
#define NAND_WRACCESSTIME (28) // Value has been changed from 22 to 28 - Mohit Hada

/*****************************************************************************/
/*
** Macros which defines the chip select base address and cs region size.
**
*/
#define NAND_CS0_BASEADDR (0x10000000)
#define NAND_CS0_REGIONSIZE (GPMC_CS_SIZE_256MB)


/******************************************************************************
** INTERNAL VARIABLE DEFINITIONS
*******************************************************************************/

#if defined(__IAR_SYSTEMS_ICC__)

#pragma data_alignment=SOC_CACHELINE_SIZE_MAX
volatile unsigned char txData[NAND_DATA_BUFF_SIZE];
#pragma data_alignment=SOC_CACHELINE_SIZE_MAX
volatile unsigned char rxData[NAND_DATA_BUFF_SIZE];

#elif defined(__TMS470__) || defined(_TMS320C6X)

#pragma DATA_ALIGN(txData, SOC_CACHELINE_SIZE_MAX);
volatile unsigned char txData[NAND_DATA_BUFF_SIZE];
#pragma DATA_ALIGN(rxData, SOC_CACHELINE_SIZE_MAX);
volatile unsigned char rxData[NAND_DATA_BUFF_SIZE];

#else

volatile unsigned char __attribute__ ((aligned (SOC_CACHELINE_SIZE_MAX)))
txData[NAND_DATA_BUFF_SIZE];
volatile unsigned char __attribute__ ((aligned (SOC_CACHELINE_SIZE_MAX)))
rxData[NAND_DATA_BUFF_SIZE];

#endif

unsigned char eccData[NAND_ECC_BUFF_SIZE];

/* Page tables start must be aligned in 16K boundary */
#ifdef __TMS470__
#pragma DATA_ALIGN(pageTable, MMU_PAGETABLE_ALIGN_SIZE);
static volatile unsigned int pageTable[MMU_PAGETABLE_NUM_ENTRY];

#elif defined(__IAR_SYSTEMS_ICC__)
#pragma data_alignment=MMU_PAGETABLE_ALIGN_SIZE
static volatile unsigned int pageTable[MMU_PAGETABLE_NUM_ENTRY];

#elif defined(gcc)
static volatile unsigned int pageTable[MMU_PAGETABLE_NUM_ENTRY]
__attribute__((aligned(MMU_PAGETABLE_ALIGN_SIZE)));

#else
#error "Unsupported Compiler. \r\n"

#endif

unsigned short int *p = (unsigned short int *) 0x08000000;

/******************************************************************************
** INTERNAL FUNCTION PROTOTYPES
*******************************************************************************/

void NORPinMuxSetup(void);
static void Delay(unsigned int count);
void NorFlashErase (unsigned int sector_add);
void NorFlashProgram (unsigned int prog_data_len);

/******************************************************************************
** GLOBAL FUNCTION DEFINITIONS
*******************************************************************************/

/******************************************************************************
* *
* \brief Main Function.\n *
* *
******************************************************************************/
int main(void)
{
    // int blkNum;
    // int pageNum;
    // int numOfPages;
    // unsigned int retVal;
    unsigned short uiDeviceID = 0;
    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};

    /* Configure and enable the MMU. */
    // MMUConfigAndEnable(); // This function is not required.

    /* Enable all levels of Cache. */
    // CacheEnable(CACHE_ALL); // This function is not required.

    /* Pin mux and clock setting */
    //NORPinMuxSetup();
    GPMCClkConfig();

    /* Initialize the UART console */
    ConsoleUtilsInit();

    /* Select the console type based on compile time check */
    ConsoleUtilsSetType(CONSOLE_UART);


    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);

    ///////////Wait Pin Polarity TODO: HAs to be checked as to CS should be disabled here or not on 10/08/2015
    /* Set the wait pin polarity */

    //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);
    //GPMCLimitedAddrDevSupportConfig(SOC_GPMC_0_REGS,GPMC_LIMITEDADDRESS_SUPPORT_ENABLE);

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////

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

    //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_ADMUX ); // Address Data 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); // 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, 0x08); // A29:A24 = 001000
    GPMCMaskAddrSet(SOC_GPMC_0_REGS, GPMC_CHIP_SELECT_0, GPMC_CS_SIZE_16MB); //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:- Further description on this remains pending for lack of time
    // Check section 7.1.3.3.9.4 and 7.1.3.3.9.5 of TRM for further details on 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..

    ConsoleUtilsPrintf(" \n\r*********NOR Flash Program **********\n\r" );



    //Read Device ID
    *(p+1365) = 0x00AA; //1355 -> 0xAAA
    *(p+682)  = 0x0055; //682  -> 0x2AA
    *(p+1365) = 0x0090; //1355 -> 0xAAA

    uiDeviceID = *(p+1);

    ConsoleUtilsPrintf(" \n\rFlash Device ID %x \n\r",uiDeviceID );

#if 0
    NorFlashProgram(3);//20000);

    for(i=0;i<=3;i++)//19999
    {
        p_read[i] = *(p+i);
        ConsoleUtilsPrintf(" \n\r1 NOR Read %x %d \n\r",(p+i),p_read[i] );

    }

    NorFlashErase(0x00000000);

    for(i=0;i<=3;i++)//8191
    {

        p_read[i] = *(p+i);
        ConsoleUtilsPrintf(" \n\r2 NOR Read %d \n\r",p_read[i] );

    }
#endif
    while(1);

}

void NorFlashErase (unsigned int sector_add)
{
    volatile unsigned int i ; // sector address to be erased.
    volatile unsigned short int Dq_check = 0;

    i = sector_add;

    // six command erase cycle as described in the Table 10.10 of datasheet of S29AL016J
    *(p+1365) = 0x00AA;
    *(p+682) = 0x0055;
    *(p+1365) = 0x0080;
    *(p+1365) = 0x00AA;
    *(p+682) = 0x0055;
    *(p+1365) = 0x0010;


    Dq_check = 0;

    // Checking DQ3 of the data word determined by address 'i' whether gone to '1' indicating an erase operation starting

    while(1)
    {
        Dq_check = *(p+i);
        Dq_check = Dq_check & (0x0008);//0x0004

        if(Dq_check==0x0000)//0x0004
        {
            break;
        }
        if(Dq_check==0x0001)//0x0004
        {
            break;
        }


        // Checking DQ7 of the data word determined by address 'i' whether gone to '1' and whether subsequently Dq7:Dq0 = "11111111" indicating an erase operation completion
        #if 0
            while(1)
            {
                Dq_check = *(p+i);
                Dq_check = Dq_check & (0x0080);

                if(Dq_check==0x0080)
                {
                    Dq_check = *(p+i);
                    Dq_check = Dq_check & (0xffff);
                }
                if(Dq_check==0xffff)
                {
                    break;
                }
            }

        #endif
    }
}


void NorFlashProgram (unsigned int prog_data_len)
{
    volatile unsigned int i = 0;//0x00001FFF;
    volatile unsigned short int Dq_check = 0, data = 0,value = 0;

    for(i=0;i<=(prog_data_len-1);i++)
    {
        data = i;
        // four command programming cycle as described in the Table 10.10 of datasheet of S29AL016J
         *(p+1365) = 0x00AA;
         *(p+682)  = 0x0055;
         *(p+1365) = 0x0020;//Unlock Bypass command
         *(p+1365) = 0x00A0;//Unlock Bypass program command


         *(p+i)    = data; // Here i can be replaced by some global array holding the data for the uC program code // This can also hold FPGA programming code data

         *(p+1365) = 0x0090;//Unlock Bypass reset
         *(p+1365) = 0x0000;//Unlock Bypass reset
        value     = *(p+i);
        ConsoleUtilsPrintf(" \n\rNorFlashProgram %x %d \n\r",(p+i),value );

        Dq_check = 0;
        // Check if (read DQ7 = complemented) indicates program operation start, data word determined by address 'i'
        //    while(1)
        //    {
        //    Dq_check = *(p+i);
        //    Dq_check = (Dq_check & (0x0080)) - (data & (0x00000080));
        //
        //    if(Dq_check!=0x0000)
        //    {
        //    break;
        //    }
        //    }

        // Check if (read DQ7 = same) indicates program operation complete, data word determined by address 'i'
    #if 0
        while(1)
        {
            Dq_check = *(p+i);
            Dq_check = (Dq_check & (0x0080)) - (data & (0x00000080));

            if(Dq_check == 0x0000)
            {
                Dq_check = *(p+i);
                if(data == Dq_check)
                {
                    break;
                }
            }

        }
    #endif
    }

    // TODO:- Ready or Busy Status checking
}


/**
* \brief This function selects the GPMC pins for NOR use. The GPMC pins
* are multiplexed with pins of other peripherals in the SoC
*
* \return TRUE/FALSE
*
* \note This pin multiplexing depends on the profile in which the EVM
* is configured.
*/

void NORPinMuxSetup(void) // TODO:- This portion of the original code needs to be checked again for correctness of '<<' operation - Mohit Hada - 10/08/2015
{
    HWREG(SOC_CONTROL_REGS + CONTROL_CONF_GPMC_AD(0)) = 0x20; /* GPMC_AD0 */
    HWREG(SOC_CONTROL_REGS + CONTROL_CONF_GPMC_AD(1)) = 0x20; /* GPMC_AD1 */
    HWREG(SOC_CONTROL_REGS + CONTROL_CONF_GPMC_AD(2)) = 0x20; /* GPMC_AD2 */
    HWREG(SOC_CONTROL_REGS + CONTROL_CONF_GPMC_AD(3)) = 0x20; /* GPMC_AD3 */
    HWREG(SOC_CONTROL_REGS + CONTROL_CONF_GPMC_AD(4)) = 0x20; /* GPMC_AD4 */
    HWREG(SOC_CONTROL_REGS + CONTROL_CONF_GPMC_AD(5)) = 0x20; /* GPMC_AD5 */
    HWREG(SOC_CONTROL_REGS + CONTROL_CONF_GPMC_AD(6)) = 0x20; /* GPMC_AD6 */
    HWREG(SOC_CONTROL_REGS + CONTROL_CONF_GPMC_AD(7)) = 0x20; /* GPMC_AD7 */
    HWREG(SOC_CONTROL_REGS + CONTROL_CONF_GPMC_AD(8)) = 0x20; /* GPMC_AD8 */
    HWREG(SOC_CONTROL_REGS + CONTROL_CONF_GPMC_AD(9)) = 0x20; /* GPMC_AD9 */
    HWREG(SOC_CONTROL_REGS + CONTROL_CONF_GPMC_AD(10)) = 0x20; /* GPMC_AD10 */
    HWREG(SOC_CONTROL_REGS + CONTROL_CONF_GPMC_AD(11)) = 0x20; /* GPMC_AD11 */
    HWREG(SOC_CONTROL_REGS + CONTROL_CONF_GPMC_AD(12)) = 0x20; /* GPMC_AD12 */
    HWREG(SOC_CONTROL_REGS + CONTROL_CONF_GPMC_AD(13)) = 0x20; /* GPMC_AD13 */
    HWREG(SOC_CONTROL_REGS + CONTROL_CONF_GPMC_AD(14)) = 0x20; /* GPMC_AD14 */
    HWREG(SOC_CONTROL_REGS + CONTROL_CONF_GPMC_AD(15)) = 0x20; /* GPMC_AD15 */
    /* GPMC_WAIT0 */
    HWREG(SOC_CONTROL_REGS + CONTROL_CONF_GPMC_WAIT0) = 0x30;
    /* GPMC_WPN */
    HWREG(SOC_CONTROL_REGS + CONTROL_CONF_GPMC_WPN) = 0x10;
    /* GPMC_CS0 */
    HWREG(SOC_CONTROL_REGS + CONTROL_CONF_GPMC_CSN(0)) = 0x10;
    /* GPMC_ALE */
    HWREG(SOC_CONTROL_REGS + CONTROL_CONF_GPMC_ADVN_ALE) = 0x10;
    // /* GPMC_BE0N_CLE */
    HWREG(SOC_CONTROL_REGS + CONTROL_CONF_GPMC_BE0N_CLE) = 0x10;
    /* GPMC_OEN_REN */
    HWREG(SOC_CONTROL_REGS + CONTROL_CONF_GPMC_OEN_REN) = 0x10;
    /* GPMC_WEN */
    HWREG(SOC_CONTROL_REGS + CONTROL_CONF_GPMC_WEN) = 0x10;

    HWREG(SOC_CONTROL_REGS + CONTROL_CONF_GPMC_A(1)) = 0x20; /* GPMC_A1 */
    HWREG(SOC_CONTROL_REGS + CONTROL_CONF_GPMC_A(2)) = 0x20; /* GPMC_A2 */
    HWREG(SOC_CONTROL_REGS + CONTROL_CONF_GPMC_A(3)) = 0x20; /* GPMC_A3 */
    HWREG(SOC_CONTROL_REGS + CONTROL_CONF_GPMC_A(4)) = 0x20; /* GPMC_A4 */

}

/*
** A function which is used to generate a delay.
*/
static void Delay(volatile unsigned int count)
{
    while(count--);
}
/*
 * //    *(p+1365) = 0x00AA;
//    *(p+682) = 0x0055;
//    *(p+1365) = 0x00F0;
//Read Device ID
*(p+1365) = 0x00AA;
*(p+682)  = 0x0055;
*(p+1365) = 0x0090;
uiDeviceID = *(p+1);

ConsoleUtilsPrintf(" \n\rFlash Device ID %x \n\r",uiDeviceID );

 *
 *
 */
/******************************************************************************
** END OF FILE
*******************************************************************************/