IMXRT1064 SEMC Write and Read Operations

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

IMXRT1064 SEMC Write and Read Operations

376 Views
Lukas_Frank
Senior Contributor I

Hi Dear Authorized,

 

I have some issue for write and read operations with SEMC on SRAM. Here is my code. It is not making me closer to the what I expect.

My Code:

 

 

 

#include "fsl_debug_console.h"
#include "fsl_device_registers.h"
#include "pin_mux.h"
#include "clock_config.h"
#include "board.h"
#include "fsl_semc.h"

/*******************************************************************************
 * Definitions
 ******************************************************************************/
#define EXAMPLE_SEMC               SEMC
#define EXAMPLE_SEMC_START_ADDRESS (0x80000000U)
#define EXAMPLE_SEMC_START_ADDRESS_TX (0x800000A0U)
#define EXAMPLE_SEMC_START_ADDRESS_RX (0x800000B0U)
#define EXAMPLE_SEMC_CLK_FREQ      CLOCK_GetFreq(kCLOCK_SemcClk)

#define SEMC_EXAMPLE_DATALEN    16//(0x1000U)
#define SEMC_EXAMPLE_WRITETIMES (1000U)

/*******************************************************************************
 * Prototypes
 ******************************************************************************/
extern status_t BOARD_InitSEMC(void);
/*******************************************************************************
 * Variables
 ******************************************************************************/

uint32_t sram_writeBuffer[SEMC_EXAMPLE_DATALEN];
uint32_t sram_readBuffer[SEMC_EXAMPLE_DATALEN];

/*******************************************************************************
 * Code
 ******************************************************************************/

void SEMC_SRAMWrite32Bit_TXDREG(void);
void SEMC_SRAMRead32Bit_RXDREG(void);

status_t BOARD_InitSRAM(void)
{
    semc_config_t config;
    semc_sram_config_t sram_config;
    uint32_t clockFrq = EXAMPLE_SEMC_CLK_FREQ;

    /* Initializes the MAC configure structure to zero. */
    memset(&config, 0, sizeof(semc_config_t));
    memset(&sram_config, 0, sizeof(semc_sram_config_t));

    /* Initialize SEMC. */
    SEMC_GetDefaultConfig(&config);
    config.dqsMode = kSEMC_Loopbackdqspad; /* For more accurate timing. */
    SEMC_Init(SEMC, &config);

    //config SRAM
    sram_config.cePinMux           = kSEMC_MUXA8;        	// SEMC_ADDR08 is CE0# (IOCR[MUX_A8])
    sram_config.address            = SRAM_BASE;          	// Base address 0x90000000 (BR6[BA])
    sram_config.memsize_kbytes     = 0x10000;			// SRAM0 space size 64MB (BR6[MS])
    sram_config.addrPortWidth      = 8;                    	// Port width (SRAMCR0[COL]) Don't care in SRAM.
    sram_config.advActivePolarity  = kSEMC_AdvActiveLow;   	// ADV# polarity (SRAMCR0[ADVP]) Don't care if not use ADV.
    sram_config.addrMode           = kSEMC_AddrDataNonMux; 	// Non Mux mode (SRAMCR0[AM])
    sram_config.burstLen           = kSEMC_Nor_BurstLen1;	// Burst length (SRAMCR0[BL])
    sram_config.portSize           = kSEMC_PortSize16Bit;	// Port size 16bit (SRAMCR0[PS])
    sram_config.syncMode           = kSEMC_SyncMode;		// ASYNC mode (SRAMCR0[SYNCEN])
    //sram_config.waitEnable       = true;			// WAIT enable (SRAMCR0[WAITEN])
    //sram_config.waitSample       = 0; 			// WAIT sample (SRAMCR0[WAITSP])
    //sram_config.advLevelCtrl     = kSEMC_AdvHigh; 		// ADV# level control (SRAMCR0[ADVH]) Don't care if not use ADV.
    sram_config.tCeSetup_Ns        = 20; 			// CE# setup time [nsec] (SRAMCR1[CES]) Need tuning.
    sram_config.tCeHold_Ns         = 20;			// CE# hold time [nsec] (SRAMCR1[CEH]) Need tuning.
    sram_config.tCeInterval_Ns     = 20; 			// CE# interval time [nsec] (SRAMCR2[CEITV]) Need tuning.
    sram_config.readHoldTime_Ns    = 20; 			// Read hold time [nsec] (SRAMCR2[RDH]) Only for SYNC mode.
    sram_config.tAddrSetup_Ns      = 20; 			// ADDR setup time [nsec] (SRAMCR1[AS]) Need tuning.
    sram_config.tAddrHold_Ns       = 20;			// ADDR hold time [nsec] (SRAMCR1[AH]) Need tuning.
    sram_config.tWeLow_Ns          = 20; 			// WE low time [nsec] (SRAMCR1[WEL]) Need tuning.
    sram_config.tWeHigh_Ns         = 20; 			// WE high time [nsec] (SRAMCR1[WEH]) Need tuning.
    sram_config.tReLow_Ns          = 20; 			// RE low time [nsec] (SRAMCR1[REL]) Need tuning.
    sram_config.tReHigh_Ns         = 20;			// RE high time [nsec] (SRAMCR1[REH]) Need tuning.
    sram_config.tTurnAround_Ns     = 20; 			// Turnaround time [nsec] (SRAMCR2[TA]) Need tuning but don't set it to be 0.
    sram_config.tAddr2WriteHold_Ns = 20;			// Address to write data hold time [nsec] (SRAMCR2[AWDH]) Need tuning.
    sram_config.tWriteSetup_Ns     = 20; 			// Write Data setup time [nsec] (SRAMCR2[WDS]) Only for SYNC mode.
    sram_config.tWriteHold_Ns      = 20; 			// Write Data hold time [nsec] (SRAMCR2[WDH]) Only for SYNC mode.
    sram_config.latencyCount       = 20; 			// Latency count (SRAMCR2[LC]) Only for SYNC mode.
    sram_config.readCycle          = 20; 			// read time (SRAMCR2[RD]) Only for SYNC mode.
    //sram_config.delayChain       = 20; 			// typically not used in SRAM. (DCCR [SRAMXVAL], DCCR [SRAMXEN], DCCR [SRAM0VAL], DCCR [SRAM0EN])

    return SEMC_ConfigureSRAM(SEMC, &sram_config, clockFrq);
}

#if defined(CACHE_MAINTAIN) && CACHE_MAINTAIN
#include "fsl_cache.h"
#endif


int main(void)
{
    /* Hardware initialize. */
    BOARD_ConfigMPU();
    BOARD_InitBootPins();
    BOARD_InitBootClocks();


    CLOCK_InitSysPfd(kCLOCK_Pfd2, 29);
    CLOCK_SetMux(kCLOCK_SemcMux, 1);
    CLOCK_SetDiv(kCLOCK_SemcDiv, 7);

    BOARD_InitDebugConsole();

    if (BOARD_InitSRAM() != kStatus_Success)
    {
        PRINTF("\r\n SEMC SRAM Init Failed\r\n");
    }

    SEMC_SRAMRead32Bit_RXDREG();
    SEMC_SRAMWrite32Bit_TXDREG();

    return 0;
}

void SEMC_SRAMWrite32Bit_TXDREG(void)
{
    uint32_t index;
    uint32_t dataRef = 1;
    uint32_t datalen = SEMC_EXAMPLE_DATALEN;
    uint32_t *sram  = (uint32_t *)EXAMPLE_SEMC_START_ADDRESS_TX;
    bool result      = true;

    for (index = 0; index < datalen; )
    {
        sram[0] = sram_writeBuffer[index++];
        dataRef += 2;
        sram[1] = sram_writeBuffer[index++];
        dataRef += 2;
        sram[2] = sram_writeBuffer[index++];
        dataRef += 2;
        sram[3] = sram_writeBuffer[index++];
        dataRef += 2;
    }

}

void SEMC_SRAMRead32Bit_RXDREG(void)
{
    uint32_t index;
    uint32_t datalen = SEMC_EXAMPLE_DATALEN;
    uint32_t *sram  = (uint32_t *)EXAMPLE_SEMC_START_ADDRESS_RX;

    for (index = 0; index < datalen; )
    {
    	sram_readBuffer[index++] = sram[0];
    	sram_readBuffer[index++] = sram[1];
    	sram_readBuffer[index++] = sram[2];
    	sram_readBuffer[index++] = sram[3];
    }

}

 

 

 

 

 

 

You teammates shared me below code in this post. But this code is not help me. There are some tragic errors like "sram_config.waitEnable" and "sram_config.waitSample". These configuration params are not available for sram. Could you please help me with a working code for basic operations write and read for SRAM - SEMC?

 

 

 

 

/*
 * Copyright 2017 NXP
 * All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */
#include "board.h"
#include "fsl_debug_console.h"
#include "fsl_device_registers.h"
#include "pin_mux.h"
#include "fsl_semc.h"

#include "clock_config.h"
/*******************************************************************************
 * Definitions
 ******************************************************************************/
#define EXAMPLE_SEMC SEMC
#define EXAMPLE_SEMC_START_ADDRESS (0x80000000U)
#define EXAMPLE_SEMC_CLK_FREQ CLOCK_GetRootClockFreq(kCLOCK_Root_Semc)

#define SEMC_EXAMPLE_DATALEN    (0x1000U)
#define SEMC_EXAMPLE_WRITETIMES (1000U)

/*******************************************************************************
 * Prototypes
 ******************************************************************************/
extern status_t BOARD_InitSEMC(void);

/*******************************************************************************
 * Variables
 ******************************************************************************/

uint32_t sdram_writeBuffer[SEMC_EXAMPLE_DATALEN];
uint32_t sdram_readBuffer[SEMC_EXAMPLE_DATALEN];

/*******************************************************************************
 * Code
 ******************************************************************************/
status_t BOARD_InitSEMC(void)
{
    semc_config_t config;
    semc_sdram_config_t sdramconfig;
    uint32_t clockFrq = EXAMPLE_SEMC_CLK_FREQ;

    /* Initializes the MAC configure structure to zero. */
    memset(&config, 0, sizeof(semc_config_t));
    memset(&sdramconfig, 0, sizeof(semc_sdram_config_t));

    /* Initialize SEMC. */
    SEMC_GetDefaultConfig(&config);
    config.dqsMode = kSEMC_Loopbackdqspad; /* For more accurate timing. */
    SEMC_Init(SEMC, &config);

    /* Configure SDRAM. */
    sdramconfig.csxPinMux           = kSEMC_MUXCSX0;
    sdramconfig.address             = 0x80000000;
    sdramconfig.memsize_kbytes      = 32 * 1024; /* 32MB = 32*1024*1KBytes*/
    sdramconfig.portSize            = kSEMC_PortSize16Bit;
    sdramconfig.burstLen            = kSEMC_Sdram_BurstLen8;
    sdramconfig.columnAddrBitNum    = kSEMC_SdramColunm_9bit;
    sdramconfig.casLatency          = kSEMC_LatencyThree;
    sdramconfig.tPrecharge2Act_Ns   = 15; /* tRP 15ns */
    sdramconfig.tAct2ReadWrite_Ns   = 15; /* tRCD 15ns */
    sdramconfig.tRefreshRecovery_Ns = 70; /* Use the maximum of the (Trfc , Txsr). */
    sdramconfig.tWriteRecovery_Ns   = 2;  /* tWR 2ns */
    sdramconfig.tCkeOff_Ns =
        42; /* The minimum cycle of SDRAM CLK off state. CKE is off in self refresh at a minimum period tRAS.*/
    sdramconfig.tAct2Prechage_Ns       = 40; /* tRAS 40ns */
    sdramconfig.tSelfRefRecovery_Ns    = 70;
    sdramconfig.tRefresh2Refresh_Ns    = 60;
    sdramconfig.tAct2Act_Ns            = 2; /* tRC/tRDD 2ns */
    sdramconfig.tPrescalePeriod_Ns     = 160 * (1000000000 / clockFrq);
    sdramconfig.refreshPeriod_nsPerRow = 64 * 1000000 / 8192; /* 64ms/8192 */
    sdramconfig.refreshUrgThreshold    = sdramconfig.refreshPeriod_nsPerRow;
    sdramconfig.refreshBurstLen        = 1;
    sdramconfig.delayChain             = 2;

    return SEMC_ConfigureSDRAM(SEMC, kSEMC_SDRAM_CS0, &sdramconfig, clockFrq);
}


#define SRAM_BASE 0x90000000
status_t BOARD_InitSRAM(void)
{

    semc_config_t config;
    semc_sdram_config_t sdramconfig;
    semc_sram_config_t sram_config;
    uint32_t clockFrq = EXAMPLE_SEMC_CLK_FREQ;

    /* Initializes the MAC configure structure to zero. */
    memset(&config, 0, sizeof(semc_config_t));
    memset(&sdramconfig, 0, sizeof(semc_sdram_config_t));
    memset(&sram_config, 0, sizeof(semc_sram_config_t));

    /* Initialize SEMC. */
    SEMC_GetDefaultConfig(&config);
    config.dqsMode = kSEMC_Loopbackdqspad; /* For more accurate timing. */
    SEMC_Init(SEMC, &config);

#if 0    
    /* Configure SDRAM. */
    sdramconfig.csxPinMux           = kSEMC_MUXCSX0;
    sdramconfig.address             = 0x80000000;
    sdramconfig.memsize_kbytes      = 32 * 1024; /* 32MB = 32*1024*1KBytes*/
    sdramconfig.portSize            = kSEMC_PortSize16Bit;
    sdramconfig.burstLen            = kSEMC_Sdram_BurstLen8;
    sdramconfig.columnAddrBitNum    = kSEMC_SdramColunm_9bit;
    sdramconfig.casLatency          = kSEMC_LatencyThree;
    sdramconfig.tPrecharge2Act_Ns   = 15; /* tRP 15ns */
    sdramconfig.tAct2ReadWrite_Ns   = 15; /* tRCD 15ns */
    sdramconfig.tRefreshRecovery_Ns = 70; /* Use the maximum of the (Trfc , Txsr). */
    sdramconfig.tWriteRecovery_Ns   = 2;  /* tWR 2ns */
    sdramconfig.tCkeOff_Ns =
        42; /* The minimum cycle of SDRAM CLK off state. CKE is off in self refresh at a minimum period tRAS.*/
    sdramconfig.tAct2Prechage_Ns       = 40; /* tRAS 40ns */
    sdramconfig.tSelfRefRecovery_Ns    = 70;
    sdramconfig.tRefresh2Refresh_Ns    = 60;
    sdramconfig.tAct2Act_Ns            = 2; /* tRC/tRDD 2ns */
    sdramconfig.tPrescalePeriod_Ns     = 160 * (1000000000 / clockFrq);
    sdramconfig.refreshPeriod_nsPerRow = 64 * 1000000 / 8192; /* 64ms/8192 */
    sdramconfig.refreshUrgThreshold    = sdramconfig.refreshPeriod_nsPerRow;
    sdramconfig.refreshBurstLen        = 1;
    sdramconfig.delayChain             = 2;
#endif
    
    // config SRAM
    sram_config.cePinMux          = kSEMC_MUXCSX0;        // 
    sram_config.address           = SRAM_BASE;            // Base address
    sram_config.memsize_kbytes    = 0x1000;               // SRAM space size
    sram_config.addrPortWidth     = 8;                    // Port width
    sram_config.advActivePolarity = kSEMC_AdvActiveLow;   //
    sram_config.addrMode          = kSEMC_AddrDataNonMux; // kSEMC_AdvAddrdataMux; // Mux mode or non Mux mode
    sram_config.burstLen          = kSEMC_Nor_BurstLen8;
    sram_config.portSize          = kSEMC_PortSize16Bit;
    sram_config.syncMode          = kSEMC_SyncMode; //kSEMC_AsyncMode;
    sram_config.waitEnable        = false;
    sram_config.waitSample        = 0; //?
    sram_config.advLevelCtrl      = kSEMC_AdvHigh;
    
    sram_config.tCeSetup_Ns        = 20; // CS setup and hold
    sram_config.tCeHold_Ns         = 20;
    sram_config.tCeInterval_Ns     = 20; // CS interval
    sram_config.readHoldTime_Ns    = 20; // Only for sync mode
    sram_config.tAddrSetup_Ns      = 20; // ADDR setup and hold
    sram_config.tAddrHold_Ns       = 20;
    sram_config.tWeLow_Ns          = 20; // WRITE feature
    sram_config.tWeHigh_Ns         = 20; 
    sram_config.tReLow_Ns          = 20; // READ feature
    sram_config.tReHigh_Ns         = 20;
    sram_config.tTurnAround_Ns     = 20; // TA, do not set it to be 0
    sram_config.tAddr2WriteHold_Ns = 20; // ?
    sram_config.tWriteSetup_Ns     = 20; // For sync mode.
    sram_config.tWriteHold_Ns      = 20; // For sync mode.
    sram_config.latencyCount       = 20; // For sync mode.
    sram_config.readCycle          = 20; // For sync mode.
    sram_config.delayChain         = 20; // typically not used in SRAM.
    
    return SEMC_ConfigureSRAM(SEMC, &sram_config, clockFrq);
    //return SEMC_ConfigureSDRAM(SEMC, kSEMC_SDRAM_CS0, &sdramconfig, clockFrq);    
}


/*
    EVB measurement:
    IOMUXC_GPIO_EMC_B1_29_SEMC_CS0        --> R249 --> BB_EMC_B129
    IOMUXC_GPIO_EMC_B1_00_SEMC_DATA00     --> R242 --> SW_EMC_B100 --> BANK1 --> BB_EMC_B100
    IOMUXC_GPIO_EMC_B1_19_SEMC_ADDR11(WE) --> R418 --> SW_EMC_B119 --> BANK1 --> BB_EMC_B119
    IOMUXC_GPIO_EMC_B1_20_SEMC_ADDR12(OE) --> R431 --> SW_EMC_B120 --> BANK1 --> BB_EMC_B120
    IOMUXC_GPIO_EMC_B1_22_SEMC_BA1(ADV)   --> R411 --> SW_EMC_B122 --> BANK1 --> BB_EMC_B122


    IOMUXC_GPIO_EMC_B1_29_SEMC_CS0        --> TP32
    IOMUXC_GPIO_EMC_B1_00_SEMC_DATA00     --> R241
    IOMUXC_GPIO_EMC_B1_19_SEMC_ADDR11(WE) --> 
    IOMUXC_GPIO_EMC_B1_20_SEMC_ADDR12(OE) --> 
    IOMUXC_GPIO_EMC_B1_22_SEMC_BA1(ADV)   --> R410
*/
void test_sram(void)
{
    char * p;
    int64_t * p64;
    
    p = (char *)SRAM_BASE;
    p64 = (int64_t *)SRAM_BASE;
    /*
    for(int i=0; i<0x1000; i++)
    {
        p[i] = i;
        asm(" dsb");
    }
    */
    
    //p64[0] = 0x0201020102010201;
    p64[0] = 0x0002000100020001;
    //p[0] = 1;
    //p[0] = 0;
    //p[1] = 1;
    //p[2] = 2;
    //p[3] = 3;
    
    
}
void test_sdram(void)
{
    char * p;
    p = (char *)EXAMPLE_SEMC_START_ADDRESS;
    p[0] = 0;
    p[1] = 1;
    p[2] = 2;
    p[3] = 3;
    
    asm(" dsb");
}
/*!
 * @brief Main function
 */
void SEMC_SDRAMReadWrite32Bit(void);
int main(void)
{
    /* Hardware initialize. */
    BOARD_ConfigMPU();
    BOARD_InitPins();
    BOARD_BootClockRUN();
    BOARD_InitDebugConsole();

//    PRINTF("\r\n SEMC SDRAM Example Start!\r\n");
//    if (BOARD_InitSEMC() != kStatus_Success)
//    {
//        PRINTF("\r\n SEMC SDRAM Init Failed\r\n");
//    }
    
//    BOARD_InitSEMC();
//    test_sdram();

    BOARD_InitSRAM();
    test_sram();

    /* 32Bit data read and write. */
    //SEMC_SDRAMReadWrite32Bit();


    PRINTF("\r\n SEMC SDRAM Example End.\r\n");
    while (1)
    {
    }
}

void SEMC_SDRAMReadWrite32Bit(void)
{
    uint32_t index;
    uint32_t datalen = SEMC_EXAMPLE_DATALEN;
    uint32_t *sdram  = (uint32_t *)EXAMPLE_SEMC_START_ADDRESS; /* SDRAM start address. */
    bool result      = true;

    PRINTF("\r\n SEMC SDRAM Memory 32 bit Write Start, Start Address 0x%x, Data Length %d !\r\n", sdram, datalen);
    /* Prepare data and write to SDRAM. */
    for (index = 0; index < datalen; index++)
    {
        sdram_writeBuffer[index] = index;
        sdram[index]             = sdram_writeBuffer[index];
    }

    PRINTF("\r\n SEMC SDRAM Read 32 bit Data Start, Start Address 0x%x, Data Length %d !\r\n", sdram, datalen);
    /* Read data from the SDRAM. */
    for (index = 0; index < datalen; index++)
    {
        sdram_readBuffer[index] = sdram[index];
    }

    PRINTF("\r\n SEMC SDRAM 32 bit Data Write and Read Compare Start!\r\n");
    /* Compare the two buffers. */
    while (datalen--)
    {
        if (sdram_writeBuffer[datalen] != sdram_readBuffer[datalen])
        {
            result = false;
            break;
        }
    }

    if (!result)
    {
        PRINTF("\r\n SEMC SDRAM 32 bit Data Write and Read Compare Failed!\r\n");
    }
    else
    {
        PRINTF("\r\n SEMC SDRAM 32 bit Data Write and Read Compare Succeed!\r\n");
    }
}

 

 

 

Thanks and Regards.

Labels (1)
0 Kudos
Reply
0 Replies