SDRAM in RBC (Row, Bank, Column mode)

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

SDRAM in RBC (Row, Bank, Column mode)

1,357 Views
bjorns
Contributor III

Hello,

I have managed to get the external sdram working in BRC (Bank Row Column) mode. This seems to be stable and passes the memory tests.

I'm now trying to switch to RBC mode and are getting some strange results.

The SDRAM in question is IS42S16100 (16Mbit, 512k x 16bits x 2 banks). The MCU is LPC54616.

If I write the first 512 bytes of the ram and read it back it has the correct data. But it seems that writing the 513th byte overwrites byte 0. When looking into this more it seems as if address bit 9 (should be the lowest row address bit) is stuck at 1. Since it works as expected in BRC mode i do not think this is a hardware issue.

This makes me believe that the mode settings configuration is wrong, that it is using 2 bank bits or something like that. But the configurations looks correct to me.

The sdram is configured using code generated by MCUXpresso. With the following mode and memory map config.

#define SDRAM_MODEREG_VALUE (0x23u) // CAS: 2, Burst length: 8, Sequential burst
#define SDRAM_DEV_MEMORYMAP (0x01u) /* 64Mbits (1M*16, 2banks, 11 rows, 8 columns) (RBC)*/

When breaking in the EMC_DynamicMemInit function I can see that the offset is calculated to 10 which I think is correct. (8 (column bits) + 1 (16 bit memory, A0 not used) + 1 (bank bits) == 10)

Any ideas what could cause this?

I have attached a log showing what is read back from the memory after writing the lower 16bit of the address to each 16bit memory location. So address 0xa0000000 should have the value 0x0000, and 0xa0000002 should have the value 0x0002 and so on.

Thanks
Björn

4 Replies

1,333 Views
Alice_Yang
NXP TechSupport
NXP TechSupport

Hello bjorns,

Sorry I haven't find the issue, how about have a look at the SDRAM demo emc_sdram under SDK.

 

 

BR

Alice

1,329 Views
bjorns
Contributor III

Hello @Alice_Yang,

Thanks for your reply, I have seen the demo and even based the implementation on it.

Another question you might be able to assist with. When reading the datasheet I get the impression that since we have a 16-bit wide memory, address pin 0 from the sdram should be connected to address pin A1 on the mcu? In our case it is connected to A0.

Thanks
/Björn

1,323 Views
carstengroen
Senior Contributor II

Björn,

I use this in my designs:

carstengroen_0-1646035199726.png

 

carstengroen_1-1646035233254.png

 

carstengroen_2-1646035258616.png

 

 

carstengroen_3-1646035277732.png

 

This is my board.c file:

//----------------------------------------------------------------------------
// board.c													  	  20170926 CHG
//----------------------------------------------------------------------------
#include "board.h"
#include "fsl_common.h"
#include "fsl_emc.h"
#include "fsl_power.h"
#include "fsl_clock.h"
#include "fsl_iocon.h"
#include "fsl_emc.h"

// System clock frequency
extern uint32_t SystemCoreClock;



#define IOCON_PIO_DIGITAL_EN 0x0100u  /*!<@brief Enables digital function */
#define IOCON_PIO_FUNC0 0x00u         /*!<@brief Selects pin function 0 */
#define IOCON_PIO_FUNC1 0x01u         /*!<@brief Selects pin function 1 */
#define IOCON_PIO_FUNC2 0x02u         /*!<@brief Selects pin function 2 */
#define IOCON_PIO_FUNC6 0x06u         /*!<@brief Selects pin function 6 */
#define IOCON_PIO_FUNC7 0x07u         /*!<@brief Selects pin function 7 */
#define IOCON_PIO_INPFILT_OFF 0x0200u /*!<@brief Input filter disabled */
#define IOCON_PIO_INV_DI 0x00u        /*!<@brief Input function is not inverted */
#define IOCON_PIO_MODE_INACT 0x00u    /*!<@brief No addition pin function */
#define IOCON_PIO_MODE_PULLUP 0x20u   /*!<@brief Selects pull-up function */
#define IOCON_PIO_MODE_PULLDOWN 0x10u   /*!<@brief Selects pull-down function */
#define IOCON_PIO_OPENDRAIN_DI 0x00u  /*!<@brief Open drain is disabled */
#define IOCON_PIO_SLEW_FAST 0x0400u   /*!<@brief Fast mode, slew rate control is disabled */
#define IOCON_PIO_SLEW_STANDARD 0x00u /*!<@brief Standard mode, output slew rate control is enabled */

//----------------------------------------------------------------------------
// The SDRAM timing
//----------------------------------------------------------------------------
//#define SDRAM_REFRESHPERIOD_NS (64 * 1000000 / 4096) /* 4096 rows/ 64ms */
#define SDRAM_REFRESHPERIOD_NS (64 * 1000000 / 8192) /* 4096 rows/ 64ms */
#define SDRAM_TRP_NS (18u)
#define SDRAM_TRAS_NS (42u)
#define SDRAM_TSREX_NS (67u)
#define SDRAM_TAPR_NS (18u)
#define SDRAM_TWRDELT_NS (6u)
#define SDRAM_TRC_NS (60u)
#define SDRAM_RFC_NS (60u)
#define SDRAM_XSR_NS (67u)
#define SDRAM_RRD_NS (12u)
#define SDRAM_MRD_NCLK (2u)
#define SDRAM_RAS_NCLK (2u)
#define SDRAM_MODEREG_VALUE (0x23u) // CAS 2
//#define SDRAM_MODEREG_VALUE (0x33u) // CAS 3
//#define SDRAM_DEV_MEMORYMAP (0x09u) /* 128Mbits (8M*16, 4banks, 12 rows, 9 columns)*/
//#define SDRAM_DEV_MEMORYMAP (0x05u) /* 64Mbits (4M*16, 4banks, 12 rows, 8 columns)*/
#define SDRAM_DEV_MEMORYMAP (0x0Du) /* 256Mbits (16M*16, 4banks, 13 rows, 9 columns)*/

//----------------------------------------------------------------------------
// 
//----------------------------------------------------------------------------
void BOARD_InitPins(void) {
	CLOCK_EnableClock(kCLOCK_Iocon); 
    CLOCK_EnableClock(kCLOCK_InputMux);

	// VUSB
	IOCON_PinMuxSet(IOCON, 0, 22, (IOCON_FUNC7 | IOCON_MODE_INACT | IOCON_DIGITAL_EN)); // P0.22 => VUSB
	// SWO
	IOCON_PinMuxSet(IOCON, 0, 10, (IOCON_FUNC6 | IOCON_MODE_INACT | IOCON_DIGITAL_EN)); // P0.10 => SWO


	/* A0 to A14 */
	IOCON_PinMuxSet(IOCON, 0, 18, (IOCON_FUNC6 | IOCON_MODE_INACT | IOCON_DIGITAL_EN | IOCON_PIO_SLEW_FAST));
	IOCON_PinMuxSet(IOCON, 0, 19, (IOCON_FUNC6 | IOCON_MODE_INACT | IOCON_DIGITAL_EN | IOCON_PIO_SLEW_FAST));
	IOCON_PinMuxSet(IOCON, 0, 20, (IOCON_FUNC6 | IOCON_MODE_INACT | IOCON_DIGITAL_EN | IOCON_PIO_SLEW_FAST));
	IOCON_PinMuxSet(IOCON, 0, 21, (IOCON_FUNC6 | IOCON_MODE_INACT | IOCON_DIGITAL_EN | IOCON_PIO_SLEW_FAST));
	IOCON_PinMuxSet(IOCON, 1,  5, (IOCON_FUNC6 | IOCON_MODE_INACT | IOCON_DIGITAL_EN | IOCON_PIO_SLEW_FAST));
	IOCON_PinMuxSet(IOCON, 1,  6, (IOCON_FUNC6 | IOCON_MODE_INACT | IOCON_DIGITAL_EN | IOCON_PIO_SLEW_FAST));
	IOCON_PinMuxSet(IOCON, 1,  7, (IOCON_FUNC6 | IOCON_MODE_INACT | IOCON_DIGITAL_EN | IOCON_PIO_SLEW_FAST));
	IOCON_PinMuxSet(IOCON, 1,  8, (IOCON_FUNC6 | IOCON_MODE_INACT | IOCON_DIGITAL_EN | IOCON_PIO_SLEW_FAST));
	IOCON_PinMuxSet(IOCON, 1, 26, (IOCON_FUNC6 | IOCON_MODE_INACT | IOCON_DIGITAL_EN | IOCON_PIO_SLEW_FAST));
	IOCON_PinMuxSet(IOCON, 1, 27, (IOCON_FUNC6 | IOCON_MODE_INACT | IOCON_DIGITAL_EN | IOCON_PIO_SLEW_FAST));
	IOCON_PinMuxSet(IOCON, 1, 16, (IOCON_FUNC6 | IOCON_MODE_INACT | IOCON_DIGITAL_EN | IOCON_PIO_SLEW_FAST));
	IOCON_PinMuxSet(IOCON, 1, 23, (IOCON_FUNC6 | IOCON_MODE_INACT | IOCON_DIGITAL_EN | IOCON_PIO_SLEW_FAST));
	IOCON_PinMuxSet(IOCON, 1, 24, (IOCON_FUNC6 | IOCON_MODE_INACT | IOCON_DIGITAL_EN | IOCON_PIO_SLEW_FAST));
	IOCON_PinMuxSet(IOCON, 1, 25, (IOCON_FUNC6 | IOCON_MODE_INACT | IOCON_DIGITAL_EN | IOCON_PIO_SLEW_FAST));
	IOCON_PinMuxSet(IOCON, 3, 25, (IOCON_FUNC6 | IOCON_MODE_INACT | IOCON_DIGITAL_EN | IOCON_PIO_SLEW_FAST));

	/* D0 to D15 */
	IOCON_PinMuxSet(IOCON, 0,  2, (IOCON_FUNC6 | IOCON_MODE_INACT | IOCON_DIGITAL_EN | IOCON_PIO_SLEW_FAST));
	IOCON_PinMuxSet(IOCON, 0,  3, (IOCON_FUNC6 | IOCON_MODE_INACT | IOCON_DIGITAL_EN | IOCON_PIO_SLEW_FAST));
	IOCON_PinMuxSet(IOCON, 0,  4, (IOCON_FUNC6 | IOCON_MODE_INACT | IOCON_DIGITAL_EN | IOCON_PIO_SLEW_FAST));
	IOCON_PinMuxSet(IOCON, 0,  5, (IOCON_FUNC6 | IOCON_MODE_INACT | IOCON_DIGITAL_EN | IOCON_PIO_SLEW_FAST));
	IOCON_PinMuxSet(IOCON, 0,  6, (IOCON_FUNC6 | IOCON_MODE_INACT | IOCON_DIGITAL_EN | IOCON_PIO_SLEW_FAST));
	IOCON_PinMuxSet(IOCON, 0,  7, (IOCON_FUNC6 | IOCON_MODE_INACT | IOCON_DIGITAL_EN | IOCON_PIO_SLEW_FAST));
	IOCON_PinMuxSet(IOCON, 0,  8, (IOCON_FUNC6 | IOCON_MODE_INACT | IOCON_DIGITAL_EN | IOCON_PIO_SLEW_FAST));
	IOCON_PinMuxSet(IOCON, 0,  9, (IOCON_FUNC6 | IOCON_MODE_INACT | IOCON_DIGITAL_EN | IOCON_PIO_SLEW_FAST));
	IOCON_PinMuxSet(IOCON, 1, 19, (IOCON_FUNC6 | IOCON_MODE_INACT | IOCON_DIGITAL_EN | IOCON_PIO_SLEW_FAST));
	IOCON_PinMuxSet(IOCON, 1, 20, (IOCON_FUNC6 | IOCON_MODE_INACT | IOCON_DIGITAL_EN | IOCON_PIO_SLEW_FAST));
	IOCON_PinMuxSet(IOCON, 1, 21, (IOCON_FUNC6 | IOCON_MODE_INACT | IOCON_DIGITAL_EN | IOCON_PIO_SLEW_FAST));
	IOCON_PinMuxSet(IOCON, 1,  4, (IOCON_FUNC6 | IOCON_MODE_INACT | IOCON_DIGITAL_EN | IOCON_PIO_SLEW_FAST));
	IOCON_PinMuxSet(IOCON, 1, 28, (IOCON_FUNC6 | IOCON_MODE_INACT | IOCON_DIGITAL_EN | IOCON_PIO_SLEW_FAST));
	IOCON_PinMuxSet(IOCON, 1, 29, (IOCON_FUNC6 | IOCON_MODE_INACT | IOCON_DIGITAL_EN | IOCON_PIO_SLEW_FAST));
	IOCON_PinMuxSet(IOCON, 1, 30, (IOCON_FUNC6 | IOCON_MODE_INACT | IOCON_DIGITAL_EN | IOCON_PIO_SLEW_FAST));
	IOCON_PinMuxSet(IOCON, 1, 31, (IOCON_FUNC6 | IOCON_MODE_INACT | IOCON_DIGITAL_EN | IOCON_PIO_SLEW_FAST));

	/* Control pins */
	IOCON_PinMuxSet(IOCON, 1, 15, (IOCON_FUNC6 | IOCON_MODE_INACT | IOCON_DIGITAL_EN | IOCON_PIO_SLEW_FAST));  /* CLKE0 */
	IOCON_PinMuxSet(IOCON, 1, 11, (IOCON_FUNC6 | IOCON_MODE_INACT | IOCON_DIGITAL_EN | IOCON_PIO_SLEW_FAST));  /* CLK0 */
	IOCON_PinMuxSet(IOCON, 1, 13, (IOCON_FUNC6 | IOCON_MODE_INACT | IOCON_DIGITAL_EN | IOCON_PIO_SLEW_FAST));  /* DQM0 */
	IOCON_PinMuxSet(IOCON, 1, 14, (IOCON_FUNC6 | IOCON_MODE_INACT | IOCON_DIGITAL_EN | IOCON_PIO_SLEW_FAST));  /* DQM1 */
	IOCON_PinMuxSet(IOCON, 1, 12, (IOCON_FUNC6 | IOCON_MODE_INACT | IOCON_DIGITAL_EN | IOCON_PIO_SLEW_FAST));  /* DYSC0 */
	IOCON_PinMuxSet(IOCON, 1, 10, (IOCON_FUNC6 | IOCON_MODE_INACT | IOCON_DIGITAL_EN | IOCON_PIO_SLEW_FAST));  /* RASn */
	IOCON_PinMuxSet(IOCON, 1,  9, (IOCON_FUNC6 | IOCON_MODE_INACT | IOCON_DIGITAL_EN | IOCON_PIO_SLEW_FAST));  /* CASn */
	IOCON_PinMuxSet(IOCON, 0, 15, (IOCON_FUNC6 | IOCON_MODE_INACT | IOCON_DIGITAL_EN | IOCON_PIO_SLEW_FAST));  /* WEn */

	// FLASH-SI (FC0-MOSI)
    IOCON_PinMuxSet(IOCON, 2U, 0U, IOCON_PIO_FUNC2 | IOCON_PIO_MODE_PULLDOWN | IOCON_PIO_INV_DI | IOCON_PIO_DIGITAL_EN | IOCON_PIO_INPFILT_OFF | IOCON_PIO_SLEW_STANDARD | IOCON_PIO_OPENDRAIN_DI);
	// FLASH-SO (FC0-MISO)
    IOCON_PinMuxSet(IOCON, 2U, 1U, IOCON_PIO_FUNC2 | IOCON_PIO_MODE_PULLDOWN | IOCON_PIO_INV_DI | IOCON_PIO_DIGITAL_EN | IOCON_PIO_INPFILT_OFF | IOCON_PIO_SLEW_STANDARD | IOCON_PIO_OPENDRAIN_DI);
	// FLASH-SCK (FC0-SCK)
    IOCON_PinMuxSet(IOCON, 0U, 28U, IOCON_PIO_FUNC1 | IOCON_PIO_MODE_PULLDOWN | IOCON_PIO_INV_DI | IOCON_PIO_DIGITAL_EN | IOCON_PIO_INPFILT_OFF | IOCON_PIO_SLEW_STANDARD | IOCON_PIO_OPENDRAIN_DI);



}


/*


_WDWORD(0x40000208, 0x00000080);         // SYSCON->AHBCLKCTRL2 = Bit 7 (EMC)=1

_WDWORD(0x40000108, 0x00000080);         // SYSCON->PRESETCTRL2 = Bit 7 (EMC_RESET)=1
_WDWORD(0x40000108, 0x00000000);         // SYSCON->PRESETCTRL2 = Bit 7 (EMC_RESET)=0

_WDWORD(0x400003B8, 0x00000001);         // SYSCON->EMCCLKDIV = 1
_WDWORD(0x40000444, 0x00000000);         // SYSCON->EMCSYSCTRL = Bit 3 (EMCFBCLKIN = 0, using internal loopback for EMC_CLK output)





*/


/* Initialize the external memory. */
void BOARD_InitSDRAM(void) {
    uint32_t emcFreq;
    emc_basic_config_t basicConfig;
    emc_dynamic_timing_config_t dynTiming;
    emc_dynamic_chip_config_t dynChipConfig;

    //emcFreq = CLOCK_GetEmcClkFreq();
	emcFreq=100000000; // NOTE::: NEED TO SET THIS MANUALLY AS THIS IS CALLED IN STARTUP_XXXX.S !!!!!
	
    assert(emcFreq != 0); /* Check the clock of emc */
    /* Basic configuration. */
    basicConfig.endian   = kEMC_LittleEndian;
    basicConfig.fbClksrc=kEMC_IntloopbackEmcclk;
    /* EMC Clock = CPU FREQ/2 here can fit CPU freq from 12M ~ 180M.
     * If you change the divide to 0 and EMC clock is larger than 100M
     * please take refer to emc.dox to adjust EMC clock delay.
     */
    basicConfig.emcClkDiv = 1; // For 220 MHz: 2 => div 3, for 200 MHz: 1 => div 2
    /* Dynamic memory timing configuration. */
    dynTiming.readConfig            = kEMC_Cmddelay;
    dynTiming.refreshPeriod_Nanosec = SDRAM_REFRESHPERIOD_NS;
    dynTiming.tRp_Ns                = SDRAM_TRP_NS;
    dynTiming.tRas_Ns               = SDRAM_TRAS_NS;
    dynTiming.tSrex_Ns              = SDRAM_TSREX_NS;
    dynTiming.tApr_Ns               = SDRAM_TAPR_NS;
    dynTiming.tWr_Ns                = (1000000000 / emcFreq + SDRAM_TWRDELT_NS); /* one clk + 6ns */
    dynTiming.tDal_Ns               = dynTiming.tWr_Ns + dynTiming.tRp_Ns;
    dynTiming.tRc_Ns                = SDRAM_TRC_NS;
    dynTiming.tRfc_Ns               = SDRAM_RFC_NS;
    dynTiming.tXsr_Ns               = SDRAM_XSR_NS;
    dynTiming.tRrd_Ns               = SDRAM_RRD_NS;
    dynTiming.tMrd_Nclk             = SDRAM_MRD_NCLK;
    /* Dynamic memory chip specific configuration: Chip 0 - MTL48LC8M16A2B4-6A */
    dynChipConfig.chipIndex       = 0;
    dynChipConfig.dynamicDevice   = kEMC_Sdram;
    dynChipConfig.rAS_Nclk        = SDRAM_RAS_NCLK;
    dynChipConfig.sdramModeReg    = SDRAM_MODEREG_VALUE;
    dynChipConfig.sdramExtModeReg = 0; /* it has no use for normal sdram */
    dynChipConfig.devAddrMap      = SDRAM_DEV_MEMORYMAP;
    /* EMC Basic configuration. */
    EMC_Init(EMC, &basicConfig);
    /* EMC Dynamc memory configuration. */
    EMC_DynamicMemInit(EMC, &dynTiming, &dynChipConfig, 1);

	SYSCON->EMCDLYCTRL = 0x1010; // Handles EMC clock=90 MHz !!!
								 // Default value is 0x0210, 02 => FBCLK_DELAY, 10 = CMD_DELAY
	
}


//----------------------------------------------------------------------------
// Code for BOARD_BootClockFRO12M configuration
//----------------------------------------------------------------------------
void BOARD_BootClockFRO12M(void) {
    POWER_DisablePD(kPDRUNCFG_PD_FRO_EN); // Ensure FRO is on
    CLOCK_AttachClk(
        kFRO12M_to_MAIN_CLK); // Switch to FRO 12MHz first to ensure we can change voltage without accidentally
                              // being below the voltage for current speed
    CLOCK_SetupFROClocking(12000000U); // Set up FRO to the 12 MHz, just for sure
    POWER_SetVoltageForFreq(
        12000000U); // Set voltage for the one of the fastest clock outputs: System clock output
    CLOCK_SetFLASHAccessCyclesForFreq(12000000U); // Set FLASH wait states for core

    // Set up dividers
    CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U, false); // Reset divider counter and set divider to value 1

    // Set up clock selectors - Attach clocks to the peripheries
    CLOCK_AttachClk(kFRO12M_to_MAIN_CLK); // Switch MAIN_CLK to FRO12M
    SystemCoreClock = BOARD_BOOTCLOCKFRO12M_CORE_CLOCK;
}

//----------------------------------------------------------------------------
// Code for BOARD_BootClockFROHF48M configuration
//----------------------------------------------------------------------------
void BOARD_BootClockFROHF48M(void) {
    POWER_DisablePD(kPDRUNCFG_PD_FRO_EN); // Ensure FRO is on 
    CLOCK_AttachClk(
        kFRO12M_to_MAIN_CLK); // Switch to FRO 12MHz first to ensure we can change voltage without accidentally
                              // being below the voltage for current speed
    POWER_SetVoltageForFreq(
        48000000U); // Set voltage for the one of the fastest clock outputs: System clock output
    CLOCK_SetFLASHAccessCyclesForFreq(48000000U); // Set FLASH wait states for core

    CLOCK_SetupFROClocking(48000000U); // Set up high frequency FRO output to selected frequency

    // Set up dividers
    CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U, false); // Reset divider counter and set divider to value 1

    // Set up clock selectors - Attach clocks to the peripheries
    CLOCK_AttachClk(kFRO_HF_to_MAIN_CLK); // Switch MAIN_CLK to FRO_HF
    SystemCoreClock = BOARD_BOOTCLOCKFROHF48M_CORE_CLOCK;
}

//----------------------------------------------------------------------------
// Code for BOARD_BootClockFROHF96M configuration
//----------------------------------------------------------------------------
void BOARD_BootClockFROHF96M(void) {
    POWER_DisablePD(kPDRUNCFG_PD_FRO_EN); // Ensure FRO is on 
    CLOCK_AttachClk(
        kFRO12M_to_MAIN_CLK); // Switch to FRO 12MHz first to ensure we can change voltage without accidentally
                              // being below the voltage for current speed 
    POWER_SetVoltageForFreq(
        96000000U); // Set voltage for the one of the fastest clock outputs: System clock output
    CLOCK_SetFLASHAccessCyclesForFreq(96000000U); // Set FLASH wait states for core

    CLOCK_SetupFROClocking(96000000U); // Set up high frequency FRO output to selected frequency

    // Set up dividers
    CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U, false); /*!< Reset divider counter and set divider to value 1 */

    // Set up clock selectors - Attach clocks to the peripheries
    CLOCK_AttachClk(kFRO_HF_to_MAIN_CLK); // Switch MAIN_CLK to FRO_HF
    SystemCoreClock = BOARD_BOOTCLOCKFROHF96M_CORE_CLOCK;
}

//----------------------------------------------------------------------------
// Code for BOARD_BootClockPLL180M configuration
//----------------------------------------------------------------------------
void BOARD_BootClockPLL180M(void) {
    POWER_DisablePD(kPDRUNCFG_PD_FRO_EN); // Ensure FRO is on
    CLOCK_AttachClk(
        kFRO12M_to_MAIN_CLK); // Switch to FRO 12MHz first to ensure we can change voltage without accidentally
                              // being below the voltage for current speed 
    POWER_SetVoltageForFreq(
        12000000U); // Set voltage for the one of the fastest clock outputs: System clock output
    CLOCK_SetFLASHAccessCyclesForFreq(12000000U); // Set FLASH wait states for core

    // Set up SYS PLL
    const pll_setup_t pllSetup = {
        .pllctrl = SYSCON_SYSPLLCTRL_SELI(32U) | SYSCON_SYSPLLCTRL_SELP(16U) | SYSCON_SYSPLLCTRL_SELR(0U),
        .pllmdec = (SYSCON_SYSPLLMDEC_MDEC(8191U)),
        .pllndec = (SYSCON_SYSPLLNDEC_NDEC(770U)),
        .pllpdec = (SYSCON_SYSPLLPDEC_PDEC(98U)),
        .pllRate = 180000000U,
        .flags = PLL_SETUPFLAG_WAITLOCK | PLL_SETUPFLAG_POWERUP};
    //CLOCK_AttachClk(kEXT_CLK_to_SYS_PLL); // Set sys pll clock source from external crystal
    CLOCK_AttachClk(kFRO12M_to_SYS_PLL); // Set sys pll clock source from FRO
		
		
    CLOCK_SetPLLFreq(&pllSetup);
    POWER_SetVoltageForFreq(
        180000000U); // Set voltage for the one of the fastest clock outputs: System clock output
    CLOCK_SetFLASHAccessCyclesForFreq(180000000U); // Set FLASH wait states for core 
		
    CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U, false); // Reset divider counter and set divider to value 1
    CLOCK_SetClkDiv(kCLOCK_DivEmcClk, 0U, true);  // Reset EMCCLKDIV divider counter and halt it
    CLOCK_SetClkDiv(kCLOCK_DivEmcClk, 2U, false); // Set EMCCLKDIV divider to value 2
		
    CLOCK_AttachClk(kSYS_PLL_to_MAIN_CLK); // Switch System clock to SYS PLL 180MHz
	// Switch MAINCLKSELA to FRO12M even it is not used for MAINCLKSELB
	SYSCON->MAINCLKSELA = ((SYSCON->MAINCLKSELA & ~SYSCON_MAINCLKSELA_SEL_MASK) | SYSCON_MAINCLKSELA_SEL(0U)); 
		
    SystemCoreClock = BOARD_BootClockPLL180M_CORE_CLOCK;
}

#if (0)
//----------------------------------------------------------------------------
// Code for BOARD_BootClockPLL200M configuration
//----------------------------------------------------------------------------
void BOARD_BootClockPLL200M(void) {
    /*!< Set up the clock sources */
    /*!< Set up FRO */
    POWER_DisablePD(kPDRUNCFG_PD_FRO_EN);                   /*!< Ensure FRO is on  */
    CLOCK_AttachClk(kFRO12M_to_MAIN_CLK);                  /*!< Switch to FRO 12MHz first to ensure we can change voltage without accidentally
                                                                being below the voltage for current speed */
    POWER_SetVoltageForFreq(200000000U);             /*!< Set voltage for the one of the fastest clock outputs: System clock output */
    CLOCK_SetFLASHAccessCyclesForFreq(200000000U);    /*!< Set FLASH wait states for core */

    /*!< Set up SYS PLL */
    const pll_setup_t pllSetup = {
        .pllctrl =  SYSCON_SYSPLLCTRL_SELI(38U) | SYSCON_SYSPLLCTRL_SELP(31U) | SYSCON_SYSPLLCTRL_SELR(0U),
        .pllmdec = (SYSCON_SYSPLLMDEC_MDEC(6557U)),
        .pllndec = (SYSCON_SYSPLLNDEC_NDEC(1U)),
        .pllpdec = (SYSCON_SYSPLLPDEC_PDEC(98U)),
        .pllRate = 200000000U,
        .flags =  PLL_SETUPFLAG_WAITLOCK | PLL_SETUPFLAG_POWERUP
    };
    CLOCK_AttachClk(kFRO12M_to_SYS_PLL);        /*!< Set sys pll clock source*/
    CLOCK_SetPLLFreq(&pllSetup);                 /*!< Configure PLL to the desired value */

    /*!< Set up dividers */
    CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U, false);                  /*!< Reset divider counter and set divider to value 1 */

    /*!< Set up clock selectors - Attach clocks to the peripheries */
    CLOCK_AttachClk(kSYS_PLL_to_MAIN_CLK);                    /*!< Switch MAIN_CLK to SYS_PLL */
    SYSCON->MAINCLKSELA = ((SYSCON->MAINCLKSELA & ~SYSCON_MAINCLKSELA_SEL_MASK) | SYSCON_MAINCLKSELA_SEL(0U)); /*!< Switch MAINCLKSELA to FRO12M even it is not used for MAINCLKSELB */
    /* Set SystemCoreClock variable. */
    SystemCoreClock = BOARD_BootClockPLL200M_CORE_CLOCK;
}

#endif


//----------------------------------------------------------------------------
// Code for BOARD_BootClockPLL200M configuration
//----------------------------------------------------------------------------
void BOARD_BootClockPLL200M(void) {
    /*!< Set up the clock sources */
    /*!< Set up FRO */
    POWER_DisablePD(kPDRUNCFG_PD_FRO_EN);                   /*!< Ensure FRO is on  */
    CLOCK_AttachClk(kFRO12M_to_MAIN_CLK);                  /*!< Switch to FRO 12MHz first to ensure we can change voltage without accidentally
                                                                being below the voltage for current speed */
    POWER_SetVoltageForFreq(200000000U);             /*!< Set voltage for the one of the fastest clock outputs: System clock output */
    CLOCK_SetFLASHAccessCyclesForFreq(200000000U);    /*!< Set FLASH wait states for core */

    /*!< Set up SYS PLL */
    const pll_setup_t pllSetup = {
        .pllctrl =  SYSCON_SYSPLLCTRL_SELI(38U) | SYSCON_SYSPLLCTRL_SELP(31U) | SYSCON_SYSPLLCTRL_SELR(0U),
        .pllmdec = (SYSCON_SYSPLLMDEC_MDEC(6557U)),
        .pllndec = (SYSCON_SYSPLLNDEC_NDEC(1U)),
        .pllpdec = (SYSCON_SYSPLLPDEC_PDEC(98U)),
        .pllRate = 200000000U,
        .flags =  PLL_SETUPFLAG_WAITLOCK | PLL_SETUPFLAG_POWERUP
    };
    CLOCK_AttachClk(kFRO12M_to_SYS_PLL);        /*!< Set sys pll clock source*/
    CLOCK_SetPLLFreq(&pllSetup);                 /*!< Configure PLL to the desired value */

    /*!< Set up dividers */
    CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U, false);                  /*!< Reset divider counter and set divider to value 1 */
    CLOCK_SetClkDiv(kCLOCK_DivUsb0Clk, 0U, true);  /*!< Reset USB0CLKDIV divider counter and halt it */
    CLOCK_SetClkDiv(kCLOCK_DivUsb0Clk, 1U, false); /*!< Set USB0CLKDIV divider to value 1 */

	
    /*!< Set up clock selectors - Attach clocks to the peripheries */
    CLOCK_AttachClk(kSYS_PLL_to_MAIN_CLK); /*!< Switch MAIN_CLK to SYS_PLL */
    CLOCK_AttachClk(kFRO_HF_to_USB0_CLK);  /*!< Switch USB0_CLK to FRO_HF */
    SYSCON->MAINCLKSELA =
        ((SYSCON->MAINCLKSELA & ~SYSCON_MAINCLKSELA_SEL_MASK) |
         SYSCON_MAINCLKSELA_SEL(0U)); /*!< Switch MAINCLKSELA to FRO12M even it is not used for MAINCLKSELB */
    /* Set SystemCoreClock variable. */
    SystemCoreClock = BOARD_BootClockPLL200M_CORE_CLOCK;
}


//----------------------------------------------------------------------------
// Code for BOARD_BootClockPLL220M configuration
//----------------------------------------------------------------------------
void BOARD_BootClockPLL220M(void) {
    /*!< Set up the clock sources */
    /*!< Set up FRO */
    POWER_DisablePD(kPDRUNCFG_PD_FRO_EN); /*!< Ensure FRO is on  */
    CLOCK_AttachClk(kFRO12M_to_MAIN_CLK); /*!< Switch to FRO 12MHz first to ensure we can change voltage without
                                             accidentally being below the voltage for current speed */
    POWER_SetVoltageForFreq(
        220000000U); /*!< Set voltage for the one of the fastest clock outputs: System clock output */
    CLOCK_SetFLASHAccessCyclesForFreq(220000000U); /*!< Set FLASH wait states for core */

    /*!< Set up SYS PLL */
    const pll_setup_t pllSetup = {
        .pllctrl = SYSCON_SYSPLLCTRL_SELI(34U) | SYSCON_SYSPLLCTRL_SELP(31U) | SYSCON_SYSPLLCTRL_SELR(0U),
        .pllmdec = (SYSCON_SYSPLLMDEC_MDEC(13243U)),
        .pllndec = (SYSCON_SYSPLLNDEC_NDEC(1U)),
        .pllpdec = (SYSCON_SYSPLLPDEC_PDEC(98U)),
        .pllRate = 220000000U,
        .flags   = PLL_SETUPFLAG_WAITLOCK | PLL_SETUPFLAG_POWERUP};
    CLOCK_AttachClk(kFRO12M_to_SYS_PLL); /*!< Set sys pll clock source*/
    CLOCK_SetPLLFreq(&pllSetup);         /*!< Configure PLL to the desired value */
    /*!< Need to make sure ROM and OTP has power(PDRUNCFG0[17,29]= 0U)
         before calling this API since this API is implemented in ROM code */
    CLOCK_SetupFROClocking(96000000U); /*!< Set up high frequency FRO output to selected frequency */

    /*!< Set up dividers */
    CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U, false);  /*!< Reset divider counter and set divider to value 1 */
    CLOCK_SetClkDiv(kCLOCK_DivUsb0Clk, 0U, true);  /*!< Reset USB0CLKDIV divider counter and halt it */
    CLOCK_SetClkDiv(kCLOCK_DivUsb0Clk, 1U, false); /*!< Set USB0CLKDIV divider to value 1 */

    /*!< Set up clock selectors - Attach clocks to the peripheries */
    CLOCK_AttachClk(kSYS_PLL_to_MAIN_CLK); /*!< Switch MAIN_CLK to SYS_PLL */
    CLOCK_AttachClk(kFRO_HF_to_USB0_CLK);  /*!< Switch USB0_CLK to FRO_HF */
    SYSCON->MAINCLKSELA =
        ((SYSCON->MAINCLKSELA & ~SYSCON_MAINCLKSELA_SEL_MASK) |
         SYSCON_MAINCLKSELA_SEL(0U)); /*!< Switch MAINCLKSELA to FRO12M even it is not used for MAINCLKSELB */
    /* Set SystemCoreClock variable. */
    SystemCoreClock = BOARD_BootClockPLL220M_CORE_CLOCK;
}

1,312 Views
bjorns
Contributor III

Thanks @carstengroen. I have gone through the info but so far not found the cause of my issue.

/Björn

0 Kudos