273 lines
		
	
	
		
			9.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			273 lines
		
	
	
		
			9.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*****************************************************************************
 | |
|  *
 | |
|  *   Copyright(C) 2011, Embedded Artists AB
 | |
|  *   All rights reserved.
 | |
|  *
 | |
|  ******************************************************************************
 | |
|  * Software that is described herein is for illustrative purposes only
 | |
|  * which provides customers with programming information regarding the
 | |
|  * products. This software is supplied "AS IS" without any warranties.
 | |
|  * Embedded Artists AB assumes no responsibility or liability for the
 | |
|  * use of the software, conveys no license or title under any patent,
 | |
|  * copyright, or mask work right to the product. Embedded Artists AB
 | |
|  * reserves the right to make changes in the software without
 | |
|  * notification. Embedded Artists AB also make no representation or
 | |
|  * warranty that such application will be suitable for the specified
 | |
|  * use without further testing or modification.
 | |
|  *****************************************************************************/
 | |
| 
 | |
| 
 | |
| 
 | |
| /******************************************************************************
 | |
|  * Includes
 | |
|  *****************************************************************************/
 | |
| #include "../board.h"
 | |
| 
 | |
| #if BOARD == BOARD_EA4357
 | |
| 
 | |
| #include "LPC43xx.h"
 | |
| #include "lpc_types.h"
 | |
| #include "lpc43xx_scu.h"
 | |
| #include "lpc43xx_timer.h"
 | |
| #include "lpc43xx_cgu.h"
 | |
| #include "sdram.h"
 | |
| #include <string.h>
 | |
| 
 | |
| /******************************************************************************
 | |
|  * Defines and typedefs
 | |
|  *****************************************************************************/
 | |
| 
 | |
| /* SDRAM refresh time to 16 clock num */
 | |
| #define EMC_SDRAM_REFRESH(freq,time)  \
 | |
|   (((uint64_t)((uint64_t)time * freq)/16000000000ull)+1)
 | |
| 
 | |
| /******************************************************************************
 | |
|  * External global variables
 | |
|  *****************************************************************************/
 | |
| 
 | |
| /******************************************************************************
 | |
|  * Local variables
 | |
|  *****************************************************************************/
 | |
| 
 | |
| /******************************************************************************
 | |
|  * Local Functions
 | |
|  *****************************************************************************/
 | |
| 
 | |
| 
 | |
| /*-------------------------PRIVATE FUNCTIONS------------------------------*/
 | |
| /*********************************************************************
 | |
|  * @brief		Calculate EMC Clock from nano second
 | |
|  * @param[in]	freq - frequency of EMC Clk
 | |
|  * @param[in]	time - nano second
 | |
|  * @return 		None
 | |
|  **********************************************************************/
 | |
| uint32_t NS2CLK(uint32_t freq, uint32_t time){
 | |
|  return (((uint64_t)time*freq/1000000000));
 | |
| }
 | |
| 
 | |
| static void pinConfig(void)
 | |
| {
 | |
| 	/* Set up EMC pin */
 | |
| 	scu_pinmux(	 2	,	 9	,	MD_PLN_FAST	,	3	);//A0
 | |
| 	scu_pinmux(	 2	,	10	,	MD_PLN_FAST	,	3	);//A1
 | |
| 	scu_pinmux(	 2	,	11	,	MD_PLN_FAST	,	3	);//A2
 | |
| 	scu_pinmux(	 2	,	12	,	MD_PLN_FAST	,	3	);//A3
 | |
| 	scu_pinmux(	 2	,	13	,	MD_PLN_FAST	,	3	);//A4
 | |
| 	scu_pinmux(	 1	,	 0	,	MD_PLN_FAST	,	2	);//A5
 | |
| 	scu_pinmux(	 1	,	 1	,	MD_PLN_FAST	,	2	);//A6
 | |
| 	scu_pinmux(	 1	,	 2	,	MD_PLN_FAST	,	2	);//A7
 | |
| 	scu_pinmux(	 2	,	 8	,	MD_PLN_FAST	,	3	);//A8
 | |
| 	scu_pinmux(	 2	,	 7	,	MD_PLN_FAST	,	3	);//A9
 | |
| 	scu_pinmux(	 2	,	 6	,	MD_PLN_FAST	,	2	);//A10
 | |
| 	scu_pinmux(	 2	,	 2	,	MD_PLN_FAST	,	2	);//A11
 | |
| 	scu_pinmux(	 2	,	 1	,	MD_PLN_FAST	,	2	);//A12
 | |
| 	scu_pinmux(	 2	,	 0	,	MD_PLN_FAST	,	2	);//A13
 | |
| 	scu_pinmux(	 6	,	 8	,	MD_PLN_FAST	,	1	);//A14
 | |
| 	scu_pinmux(	 6	,	 7	,	MD_PLN_FAST	,	1	);//A15
 | |
| 	scu_pinmux(	13	,	16	,	MD_PLN_FAST	,	2	);//A16
 | |
| 	scu_pinmux(	13	,	15	,	MD_PLN_FAST	,	2	);//A17
 | |
| 	scu_pinmux(	14	,	 0	,	MD_PLN_FAST	,	3	);//A18
 | |
| 	scu_pinmux(	14	,	 1	,	MD_PLN_FAST	,	3	);//A19
 | |
| 	scu_pinmux(	14	,	 2	,	MD_PLN_FAST	,	3	);//A20
 | |
| 	scu_pinmux(	14	,	 3	,	MD_PLN_FAST	,	3	);//A21
 | |
| 	scu_pinmux(	14	,	 4	,	MD_PLN_FAST	,	3	);//A22
 | |
| 	scu_pinmux(	10	,	 4	,	MD_PLN_FAST	,	3	);//A23
 | |
| 	
 | |
| 	scu_pinmux(	 1	,	 7	,	MD_PLN_FAST	,	3	);//D0
 | |
| 	scu_pinmux(	 1	,	 8	,	MD_PLN_FAST	,	3	);//D1
 | |
| 	scu_pinmux(	 1	,	 9	,	MD_PLN_FAST	,	3	);//D2
 | |
| 	scu_pinmux(	 1	,	10	,	MD_PLN_FAST	,	3	);//D3
 | |
| 	scu_pinmux(	 1	,	11	,	MD_PLN_FAST	,	3	);//D4
 | |
| 	scu_pinmux(	 1	,	12	,	MD_PLN_FAST	,	3	);//D5
 | |
| 	scu_pinmux(	 1	,	13	,	MD_PLN_FAST	,	3	);//D6
 | |
| 	scu_pinmux(	 1	,	14	,	MD_PLN_FAST	,	3	);//D7
 | |
| 	scu_pinmux(	 5	,	 4	,	MD_PLN_FAST	,	2	);//D8
 | |
| 	scu_pinmux(	 5	,	 5	,	MD_PLN_FAST	,	2	);//D9
 | |
| 	scu_pinmux(	 5	,	 6	,	MD_PLN_FAST	,	2	);//D10
 | |
| 	scu_pinmux(	 5	,	 7	,	MD_PLN_FAST	,	2	);//D11
 | |
| 	scu_pinmux(	 5	,	 0	,	MD_PLN_FAST	,	2	);//D12
 | |
| 	scu_pinmux(	 5	,	 1	,	MD_PLN_FAST	,	2	);//D13
 | |
| 	scu_pinmux(	 5	,	 2	,	MD_PLN_FAST	,	2	);//D14
 | |
| 	scu_pinmux(	 5	,	 3	,	MD_PLN_FAST	,	2	);//D15
 | |
| 	scu_pinmux(	13	,	 2	,	MD_PLN_FAST	,	2	);//D16
 | |
| 	scu_pinmux(	13	,	 3	,	MD_PLN_FAST	,	2	);//D17
 | |
| 	scu_pinmux(	13	,	 4	,	MD_PLN_FAST	,	2	);//D18
 | |
| 	scu_pinmux(	13	,	 5	,	MD_PLN_FAST	,	2	);//D19
 | |
| 	scu_pinmux(	13	,	 6	,	MD_PLN_FAST	,	2	);//D20
 | |
| 	scu_pinmux(	13	,	 7	,	MD_PLN_FAST	,	2	);//D21
 | |
| 	scu_pinmux(	13	,	 8	,	MD_PLN_FAST	,	2	);//D22
 | |
| 	scu_pinmux(	13	,	 9	,	MD_PLN_FAST	,	2	);//D23
 | |
| 	scu_pinmux(	14	,	 5	,	MD_PLN_FAST	,	3	);//D24
 | |
| 	scu_pinmux(	14	,	 6	,	MD_PLN_FAST	,	3	);//D25
 | |
| 	scu_pinmux(	14	,	 7	,	MD_PLN_FAST	,	3	);//D26
 | |
| 	scu_pinmux(	14	,	 8	,	MD_PLN_FAST	,	3	);//D27
 | |
| 	scu_pinmux(	14	,	 9	,	MD_PLN_FAST	,	3	);//D28
 | |
| 	scu_pinmux(	14	,	10	,	MD_PLN_FAST	,	3	);//D29
 | |
| 	scu_pinmux(	14	,	11	,	MD_PLN_FAST	,	3	);//D30
 | |
| 	scu_pinmux(	14	,	12	,	MD_PLN_FAST	,	3	);//D31
 | |
| 		
 | |
| 	scu_pinmux(	 1	,	 3	,	MD_PLN_FAST	,	3	);//OE
 | |
| 	scu_pinmux(	 1	,	 6	,	MD_PLN_FAST	,	3	);//WE
 | |
| 	
 | |
| 	scu_pinmux(	 1	,	 4	,	MD_PLN_FAST	,	3	);//BLS0
 | |
| 	scu_pinmux(	 6	,	 6	,	MD_PLN_FAST	,	1	);//BLS1	
 | |
| 	scu_pinmux(	13	,	13	,	MD_PLN_FAST	,	2	);//BLS2
 | |
| 	scu_pinmux(	13	,	10	,	MD_PLN_FAST	,	2	);//BLS3
 | |
| 	
 | |
| 	scu_pinmux(	 1	,	 5	,	MD_PLN_FAST	,	3	);//CS0	
 | |
| 	scu_pinmux(	 6	,	 3	,	MD_PLN_FAST	,	3	);//CS1
 | |
| 	scu_pinmux(	13	,	12	,	MD_PLN_FAST	,	2	);//CS2
 | |
| 	scu_pinmux(	13	,	11	,	MD_PLN_FAST	,	2	);//CS3
 | |
| 	
 | |
| 	scu_pinmux(	 6	,	 4	,	MD_PLN_FAST	,	3	);//CAS
 | |
| 	scu_pinmux(	 6	,	 5	,	MD_PLN_FAST	,	3	);//RAS
 | |
| 	
 | |
| 	scu_pinmux(  6	,	 9	,	MD_PLN_FAST	,	3	);//DYCS0
 | |
| 	scu_pinmux(	 6	,	 1	,	MD_PLN_FAST	,	1	);//DYCS1
 | |
| 	scu_pinmux(	13	,	14	,	MD_PLN_FAST	,	2	);//DYCS2
 | |
| 	scu_pinmux(	15	,	14	,	MD_PLN_FAST	,	3	);//DYCS3
 | |
| 
 | |
| 	scu_pinmux(	 6	,	11	,	MD_PLN_FAST	,	3	);//CKEOUT0
 | |
| 	scu_pinmux(	 6	,	 2	,	MD_PLN_FAST	,	1	);//CKEOUT1
 | |
| 	scu_pinmux(	13	,	 1	,	MD_PLN_FAST	,	2	);//CKEOUT2
 | |
| 	scu_pinmux(	14	,	15	,	MD_PLN_FAST	,	3	);//CKEOUT3
 | |
| 	
 | |
| 	scu_pinmux(	 6	,	12	,	MD_PLN_FAST	,	3	);//DQMOUT0
 | |
| 	scu_pinmux(	 6	,	10	,	MD_PLN_FAST	,	3	);//DQMOUT1
 | |
| 	scu_pinmux(	13	,	 0	,	MD_PLN_FAST	,	2	);//DQMOUT2
 | |
| 	scu_pinmux(	14	,	13	,	MD_PLN_FAST	,	3	);//DQMOUT3
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| /******************************************************************************
 | |
|  * Public Functions
 | |
|  *****************************************************************************/
 | |
| 
 | |
| 
 | |
| /******************************************************************************
 | |
|  *
 | |
|  * Description:
 | |
|  *    Initialize the SDRAM
 | |
|  *
 | |
|  *****************************************************************************/
 | |
| uint32_t sdram_init (void)
 | |
| {
 | |
| 	uint32_t pclk, temp;
 | |
|  	uint64_t tmpclk;
 | |
|   
 | |
|   pinConfig(); //Full 32-bit Data bus, 24-bit Address 
 | |
|     
 | |
| 	/* Select EMC clock-out */
 | |
| 	LPC_SCU->SFSCLK_0 = MD_PLN_FAST;
 | |
| 	LPC_SCU->SFSCLK_1 = MD_PLN_FAST;
 | |
| 	LPC_SCU->SFSCLK_2 = MD_PLN_FAST;
 | |
| 	LPC_SCU->SFSCLK_3 = MD_PLN_FAST;
 | |
| 
 | |
| 	LPC_EMC->CONTROL 	= 0x00000001;
 | |
| 	LPC_EMC->CONFIG  	= 0x00000000;
 | |
|   LPC_EMC->DYNAMICCONFIG0    = 1<<14 | 0<<12 | 2<<9 | 1<<7; /* 256Mb, 8Mx32, 4 banks, row=12, column=9 */
 | |
| 
 | |
| 	pclk = CGU_GetPCLKFrequency(CGU_PERIPHERAL_M4CORE);
 | |
| 
 | |
|   LPC_EMC->DYNAMICRASCAS0    = 0x00000202; /* 2 RAS, 2 CAS latency */
 | |
| 	LPC_EMC->DYNAMICREADCONFIG = 0x00000001; /* Command delayed strategy, using EMCCLKDELAY */
 | |
|   
 | |
| 	LPC_EMC->DYNAMICRP         = NS2CLK(pclk, 20);
 | |
| 	LPC_EMC->DYNAMICRAS        = NS2CLK(pclk, 42);
 | |
| 	LPC_EMC->DYNAMICSREX       = NS2CLK(pclk, 63);
 | |
| 	LPC_EMC->DYNAMICAPR        = 0x00000005;
 | |
| 	LPC_EMC->DYNAMICDAL        = 0x00000005;
 | |
| 	LPC_EMC->DYNAMICWR         = 2;
 | |
| 	LPC_EMC->DYNAMICRC         = NS2CLK(pclk, 63);
 | |
| 	LPC_EMC->DYNAMICRFC        = NS2CLK(pclk, 63);
 | |
| 	LPC_EMC->DYNAMICXSR        = NS2CLK(pclk, 63);
 | |
| 	LPC_EMC->DYNAMICRRD        = NS2CLK(pclk, 14);
 | |
| 	LPC_EMC->DYNAMICMRD        = 0x00000002;
 | |
| 
 | |
| 	TIM_Waitus(100);						   /* wait 100ms */
 | |
| 	LPC_EMC->DYNAMICCONTROL    = 0x00000183; /* Issue NOP command */
 | |
| 
 | |
| 	TIM_Waitus(200);						   /* wait 200ms */
 | |
| 	LPC_EMC->DYNAMICCONTROL    = 0x00000103; /* Issue PALL command */
 | |
| 
 | |
| 	LPC_EMC->DYNAMICREFRESH    = EMC_SDRAM_REFRESH(pclk,70); /* ( n * 16 ) -> 32 clock cycles */
 | |
| 
 | |
| 	//for(i = 0; i < 0x80; i++);	           /* wait 128 AHB clock cycles */
 | |
| 	TIM_Waitus(200);						   /* wait 200ms */
 | |
| 
 | |
| 	tmpclk = (uint64_t)15625*(uint64_t)pclk/1000000000/16;
 | |
| 	LPC_EMC->DYNAMICREFRESH    = tmpclk; /* ( n * 16 ) -> 736 clock cycles -> 15.330uS at 48MHz <= 15.625uS ( 64ms / 4096 row ) */
 | |
| 
 | |
| 	LPC_EMC->DYNAMICCONTROL    = 0x00000083; /* Issue MODE command */
 | |
| 
 | |
| 	//Timing for 48/60/72MHZ Bus
 | |
| 	temp = *((volatile uint32_t *)(SDRAM_BASE | (2<<4| 2)<<(9+2+2))); /* 4 burst, 2 CAS latency */
 | |
| 	temp = temp;
 | |
| 	LPC_EMC->DYNAMICCONTROL    = 0x00000000; /* Issue NORMAL command */
 | |
| 
 | |
| 	//[re]enable buffers
 | |
| 	LPC_EMC->DYNAMICCONFIG0    |= 1<<19;
 | |
| 
 | |
|   return TRUE;
 | |
| }
 | |
| 
 | |
| uint32_t sdram_test( void )
 | |
| {
 | |
|   volatile uint32_t *wr_ptr; 
 | |
|   volatile uint16_t *short_wr_ptr;
 | |
|   uint32_t data;
 | |
|   uint32_t i, j;
 | |
| 
 | |
|   wr_ptr = (uint32_t *)SDRAM_BASE;
 | |
|   short_wr_ptr = (uint16_t *)wr_ptr;
 | |
|     
 | |
|   /* 16 bit write */
 | |
|   for (i = 0; i < SDRAM_SIZE/0x40000; i++)
 | |
|   {
 | |
|     for (j = 0; j < 0x100; j++)
 | |
|     {
 | |
|       *short_wr_ptr++ = (i + j) & 0xFFFF;
 | |
|       *short_wr_ptr++ = ((i + j) + 1) & 0xFFFF;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /* Verifying */
 | |
|   wr_ptr = (uint32_t *)SDRAM_BASE;
 | |
|   for (i = 0; i < SDRAM_SIZE/0x40000; i++)
 | |
|   {
 | |
|     for (j = 0; j < 0x100; j++)
 | |
|     {
 | |
|       data = *wr_ptr;          
 | |
|       if (data != (((((i + j) + 1) & 0xFFFF) << 16) | ((i + j) & 0xFFFF)))
 | |
|       {
 | |
|         return 0x0;
 | |
|       }
 | |
|       wr_ptr++;
 | |
|     }
 | |
|   }
 | |
|   return 0x1;
 | |
| }
 | |
| 
 | |
| #endif
 | 
