全志V3S裸机 SDRAM内存初始化(并使用SDRAM启动仿真)

全志V3S自带64MB内部DDR II RAM,但是官方手持上面没有任何信息,不知道如何操作,通过查找xboot以及uboot代码,找到了初始化代码,很复杂。

//dram.c

/*
 * sys-dram.c
 *
 * Copyright(c) 2007-2020 Jianjun Jiang <8192542@qq.com>
 * Official site: http://xboot.org
 * Mobile phone: +86-18665388956
 * QQ: 8192542
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 */

#include "typedef.h"
#include "v3s_map.h"
#include "dram.h"
#include "reg-ccu.h"

#define u32_t	u32
#define u8_t	u8
#define u16_t	u16
#define virtual_addr_t	volatile unsigned int




#define CONFIG_DRAM_BASE	(0x40000000)
#define CONFIG_DRAM_CLK		(360)
#define CONFIG_DRAM_ZQ 		(14779)

//#define write32(addr, data) (uart_printf("0x%X = 0x%X\r\n",addr, data);SYS_REG_TYPE(addr) = data)
#define read32(addr)        (SYS_REG_TYPE(addr))
#define max(x,y)            (x>y?x:y)

#include "v3s_system.h"  
void  write32(u32 addr, u32 data)
{
    uart_printf("__writeMemory32(0x%X,0x%X,\"Memory\");\r\n", data, addr);
    SYS_REG_TYPE(addr) = data;
}
     

int clamp(int x, int min, int max)
{
    if (x > max)
        return max;
    if (x < min)
        return min;
    return x;
}



#define clrbits_le32(addr, clear) \
	write32(((virtual_addr_t)(addr)), read32(((virtual_addr_t)(addr))) & ~(clear))

#define setbits_le32(addr, set) \
	write32(((virtual_addr_t)(addr)), read32(((virtual_addr_t)(addr))) | (set))

#define clrsetbits_le32(addr, clear, set) \
	write32(((virtual_addr_t)(addr)), (read32(((virtual_addr_t)(addr))) & ~(clear)) | (set))

#define DIV_ROUND_UP(n, d)	(((n) + (d) - 1) / (d))
#define REPEAT_BYTE(x)		((~0ul / 0xff) * (x))

struct v3s_dram_com_reg_t {
	u32_t cr;			/* 0x00 control register */
	u8_t res0[0xc];		/* 0x04 */
	u32_t mcr[16][2];	/* 0x10 */
	u32_t bwcr;			/* 0x90 bandwidth control register */
	u32_t maer;			/* 0x94 master enable register */
	u32_t mapr;			/* 0x98 master priority register */
	u32_t mcgcr;		/* 0x9c */
	u32_t cpu_bwcr;		/* 0xa0 */
	u32_t gpu_bwcr;		/* 0xa4 */
	u32_t ve_bwcr;		/* 0xa8 */
	u32_t disp_bwcr;	/* 0xac */
	u32_t other_bwcr;	/* 0xb0 */
	u32_t total_bwcr;	/* 0xb4 */
	u8_t res1[0x8];		/* 0xb8 */
	u32_t swonr;		/* 0xc0 */
	u32_t swoffr;		/* 0xc4 */
	u8_t res2[0x8];		/* 0xc8 */
	u32_t cccr;			/* 0xd0 */
	u8_t res3[0x72c];	/* 0xd4 */
	u32_t protect;		/* 0x800 */
};

struct v3s_dram_ctl_reg_t {
	u32_t pir;			/* 0x00 PHY initialization register */
	u32_t pwrctl;		/* 0x04 */
	u32_t mrctrl;		/* 0x08 */
	u32_t clken;		/* 0x0c */
	u32_t pgsr[2];		/* 0x10 PHY general status registers */
	u32_t statr;		/* 0x18 */
	u8_t res1[0x14];	/* 0x1c */
	u32_t mr[4];		/* 0x30 mode registers */
	u32_t pllgcr;		/* 0x40 */
	u32_t ptr[5];		/* 0x44 PHY timing registers */
	u32_t dramtmg[9];	/* 0x58 DRAM timing registers */
	u32_t odtcfg;		/* 0x7c */
	u32_t pitmg[2];		/* 0x80 PHY interface timing registers */
	u8_t res2[0x4];		/* 0x88 */
	u32_t rfshctl0;		/* 0x8c */
	u32_t rfshtmg;		/* 0x90 refresh timing */
	u32_t rfshctl1;		/* 0x94 */
	u32_t pwrtmg;		/* 0x98 */
	u8_t res3[0x20];	/* 0x9c */
	u32_t dqsgmr;		/* 0xbc */
	u32_t dtcr;			/* 0xc0 */
	u32_t dtar[4];		/* 0xc4 */
	u32_t dtdr[2];		/* 0xd4 */
	u32_t dtmr[2];		/* 0xdc */
	u32_t dtbmr;		/* 0xe4 */
	u32_t catr[2];		/* 0xe8 */
	u32_t dtedr[2];		/* 0xf0 */
	u8_t res4[0x8];		/* 0xf8 */
	u32_t pgcr[4];		/* 0x100 PHY general configuration registers */
	u32_t iovcr[2];		/* 0x110 */
	u32_t dqsdr;		/* 0x118 */
	u32_t dxccr;		/* 0x11c */
	u32_t odtmap;		/* 0x120 */
	u32_t zqctl[2];		/* 0x124 */
	u8_t res6[0x14];	/* 0x12c */
	u32_t zqcr;			/* 0x140 ZQ control register */
	u32_t zqsr;			/* 0x144 ZQ status register */
	u32_t zqdr[3];		/* 0x148 ZQ data registers */
	u8_t res7[0x6c];	/* 0x154 */
	u32_t sched;		/* 0x1c0 */
	u32_t perfhpr[2];	/* 0x1c4 */
	u32_t perflpr[2];	/* 0x1cc */
	u32_t perfwr[2];	/* 0x1d4 */
	u8_t res8[0x2c];	/* 0x1dc */
	u32_t aciocr;		/* 0x208 */
	u8_t res9[0xf4];	/* 0x20c */
	struct {			/* 0x300 DATX8 modules*/
		u32_t mdlr;		/* 0x00 */
		u32_t lcdlr[3];	/* 0x04 */
		u32_t iocr[11];	/* 0x10 IO configuration register */
		u32_t bdlr6;	/* 0x3c */
		u32_t gtr;		/* 0x40 */
		u32_t gcr;		/* 0x44 */
		u32_t gsr[3];	/* 0x48 */
		u8_t res0[0x2c];/* 0x54 */
	} datx[4];
	u8_t res10[0x388];	/* 0x500 */
	u32_t upd2;			/* 0x888 */
};

struct dram_para_t {
	u32_t read_delays;
	u32_t write_delays;
	u16_t page_size;
	u8_t bus_width;
	u8_t dual_rank;
	u8_t row_bits;
	u8_t bank_bits;
};

static inline void sdelay(int loops)
{
	//__asm__ __volatile__ ("1:\n" "subs %0, %1, #1\n"
	//	"bne 1b":"=r" (loops):"0"(loops));
    uart_printf("_sleep_(%d);\r\n", loops);
	while(loops--)
	{
		asm("nop");
	};
}

static inline int gfls(int x)
{
	int r = 32;

	if(!x)
		return 0;
	if(!(x & 0xffff0000u))
	{
		x <<= 16;
		r -= 16;
	}
	if(!(x & 0xff000000u))
	{
		x <<= 8;
		r -= 8;
	}
	if(!(x & 0xf0000000u))
	{
		x <<= 4;
		r -= 4;
	}
	if(!(x & 0xc0000000u))
	{
		x <<= 2;
		r -= 2;
	}
	if(!(x & 0x80000000u))
	{
		x <<= 1;
		r -= 1;
	}
	return r;
}

static inline int ns_to_t(int ns)
{
	unsigned int freq = CONFIG_DRAM_CLK / 2;
	return DIV_ROUND_UP(freq * ns, 1000);
}

static u32_t bin_to_mgray(int val)
{
	u8_t table[32];

	table[0] = 0x00;
	table[1] = 0x01;
	table[2] = 0x02;
	table[3] = 0x03;
	table[4] = 0x06;
	table[5] = 0x07;
	table[6] = 0x04;
	table[7] = 0x05;
	table[8] = 0x0c;
	table[9] = 0x0d;
	table[10] = 0x0e;
	table[11] = 0x0f;
	table[12] = 0x0a;
	table[13] = 0x0b;
	table[14] = 0x08;
	table[15] = 0x09;
	table[16] = 0x18;
	table[17] = 0x19;
	table[18] = 0x1a;
	table[19] = 0x1b;
	table[20] = 0x1e;
	table[21] = 0x1f;
	table[22] = 0x1c;
	table[23] = 0x1d;
	table[24] = 0x14;
	table[25] = 0x15;
	table[26] = 0x16;
	table[27] = 0x17;
	table[28] = 0x12;
	table[29] = 0x13;
	table[30] = 0x10;
	table[31] = 0x11;
	return table[clamp(val, 0, 31)];
}

static int mgray_to_bin(u32_t val)
{
	u8_t table[32];

	table[0] = 0x00;
	table[1] = 0x01;
	table[2] = 0x02;
	table[3] = 0x03;
	table[4] = 0x06;
	table[5] = 0x07;
	table[6] = 0x04;
	table[7] = 0x05;
	table[8] = 0x0e;
	table[9] = 0x0f;
	table[10] = 0x0c;
	table[11] = 0x0d;
	table[12] = 0x08;
	table[13] = 0x09;
	table[14] = 0x0a;
	table[15] = 0x0b;
	table[16] = 0x1e;
	table[17] = 0x1f;
	table[18] = 0x1c;
	table[19] = 0x1d;
	table[20] = 0x18;
	table[21] = 0x19;
	table[22] = 0x1a;
	table[23] = 0x1b;
	table[24] = 0x10;
	table[25] = 0x11;
	table[26] = 0x12;
	table[27] = 0x13;
	table[28] = 0x16;
	table[29] = 0x17;
	table[30] = 0x14;
	table[31] = 0x15;
	return table[val & 0x1f];
}

static void clock_set_pll_ddr(u32_t clk)
{
	int n = 32;
	int k = 1;
	int m = 2;
	u32_t val;

	/* ddr pll rate = 24000000 * n * k / m */
	if(clk > 24000000 * k * n / m)
	{
		m = 1;
		if(clk > 24000000 * k * n / m)
		{
			k = 2;
		}
	}

	val = (0x1 << 31);
	val |= (0x0 << 24);
	val |= (0x1 << 20);
	val |= ((((clk / (24000000 * k / m)) - 1) & 0x1f) << 8);
	val |= (((k - 1) & 0x3) << 4);
	val |= (((m - 1) & 0x3) << 0);
	write32(V3S_CCU_BASE + CCU_PLL_DDR0_CTRL, val);
	sdelay(5500);
}

static void mctl_await_completion(u32_t * reg, u32_t mask, u32_t val)
{
	int timeout = 0;

	while((read32((virtual_addr_t)reg) & mask) != val)
	{
		if(timeout++ > 10000)
			break;
	}
}

static int mctl_mem_matches(u32_t offset)
{
	write32(CONFIG_DRAM_BASE, 0);
	write32(CONFIG_DRAM_BASE + offset, 0xaa55aa55);
#if !__ICCARM__

#else	
	asm volatile ("dsb" : : : "memory");
#endif //__ICCARM__	
	return (read32(CONFIG_DRAM_BASE) == read32(CONFIG_DRAM_BASE + offset)) ? 1 : 0;
}

static void mctl_phy_init(u32_t val)
{
	struct v3s_dram_ctl_reg_t * ctl = (struct v3s_dram_ctl_reg_t *)V3S_DRAM_CTL_BASE;

	write32((virtual_addr_t)&ctl->pir, val | PIR_INIT);
	mctl_await_completion(&ctl->pgsr[0], PGSR_INIT_DONE, 0x1);
}

static void mctl_dq_delay(u32_t read, u32_t write)
{
	struct v3s_dram_ctl_reg_t * ctl = (struct v3s_dram_ctl_reg_t *)V3S_DRAM_CTL_BASE;
	int i, j;
	u32_t val;

	for(i = 0; i < 4; i++)
	{
		val = DATX_IOCR_WRITE_DELAY((write >> (i * 4)) & 0xf) | DATX_IOCR_READ_DELAY(((read >> (i * 4)) & 0xf) * 2);
		for(j = DATX_IOCR_DQ(0); j <= DATX_IOCR_DM; j++)
			write32((virtual_addr_t)&ctl->datx[i].iocr[j], val);
	}

	clrbits_le32(&ctl->pgcr[0], 1 << 26);
	for(i = 0; i < 4; i++)
	{
		val = DATX_IOCR_WRITE_DELAY((write >> (16 + i * 4)) & 0xf) | DATX_IOCR_READ_DELAY((read >> (16 + i * 4)) & 0xf);
		write32((virtual_addr_t)&ctl->datx[i].iocr[DATX_IOCR_DQS], val);
		write32((virtual_addr_t)&ctl->datx[i].iocr[DATX_IOCR_DQSN], val);
	}

	setbits_le32(&ctl->pgcr[0], 1 << 26);
	sdelay(1);
}

static void mctl_set_master_priority(void)
{
	struct v3s_dram_com_reg_t * com = (struct v3s_dram_com_reg_t *)V3S_DRAM_COM_BASE;

	write32((virtual_addr_t)&com->bwcr, 0x00010190);
	write32((virtual_addr_t)&com->mapr, 0x00000001);
	write32((virtual_addr_t)&com->mcr[0][0], 0x0200000d);
	write32((virtual_addr_t)&com->mcr[0][1], 0x00800100);
	write32((virtual_addr_t)&com->mcr[1][0], 0x06000009);
	write32((virtual_addr_t)&com->mcr[1][1], 0x01000400);
	write32((virtual_addr_t)&com->mcr[2][0], 0x0200000d);
	write32((virtual_addr_t)&com->mcr[2][1], 0x00600100);
	write32((virtual_addr_t)&com->mcr[3][0], 0x0100000d);
	write32((virtual_addr_t)&com->mcr[3][1], 0x00200080);
	write32((virtual_addr_t)&com->mcr[4][0], 0x07000009);
	write32((virtual_addr_t)&com->mcr[4][1], 0x01000640);
	write32((virtual_addr_t)&com->mcr[5][0], 0x0100000d);
	write32((virtual_addr_t)&com->mcr[5][1], 0x00200080);
	write32((virtual_addr_t)&com->mcr[6][0], 0x01000009);
	write32((virtual_addr_t)&com->mcr[6][1], 0x00400080);
	write32((virtual_addr_t)&com->mcr[7][0], 0x0100000d);
	write32((virtual_addr_t)&com->mcr[7][1], 0x00400080);
	write32((virtual_addr_t)&com->mcr[8][0], 0x0100000d);
	write32((virtual_addr_t)&com->mcr[8][1], 0x00400080);
	write32((virtual_addr_t)&com->mcr[9][0], 0x04000009);
	write32((virtual_addr_t)&com->mcr[9][1], 0x00400100);
	write32((virtual_addr_t)&com->mcr[10][0], 0x2000030d);
	write32((virtual_addr_t)&com->mcr[10][1], 0x04001800);
	write32((virtual_addr_t)&com->mcr[11][0], 0x04000009);
	write32((virtual_addr_t)&com->mcr[11][1], 0x00400120);
}

static void mctl_set_timing_params(struct dram_para_t * para)
{
	struct v3s_dram_ctl_reg_t * ctl = (struct v3s_dram_ctl_reg_t *)V3S_DRAM_CTL_BASE;
	u8_t tccd = 1;
	u8_t tfaw = ns_to_t(50);
	u8_t trrd = max(ns_to_t(10), 2);
	u8_t trcd = ns_to_t(20);
	u8_t trc = ns_to_t(65);
	u8_t txp = 2;
	u8_t twtr = max(ns_to_t(8), 2);
	u8_t trtp = max(ns_to_t(8), 2);
	u8_t twr = max(ns_to_t(15), 3);
	u8_t trp = ns_to_t(15);
	u8_t tras = ns_to_t(45);
	u16_t trefi = ns_to_t(7800) / 32;
	u16_t trfc = ns_to_t(328);
	u8_t tmrw = 0;
	u8_t tmrd = 2;
	u8_t tmod = 12;
	u8_t tcke = 3;
	u8_t tcksrx = 5;
	u8_t tcksre = 5;
	u8_t tckesr = 4;
	u8_t trasmax = 27;
	u8_t tcl = 3; 										/* CL 12 */
	u8_t tcwl = 3; 										/* CWL 8 */
	u8_t t_rdata_en = 1;
	u8_t wr_latency = 1;
	u32_t tdinit0 = (400 * CONFIG_DRAM_CLK) + 1;		/* 400us */
	u32_t tdinit1 = (500 * CONFIG_DRAM_CLK) / 1000 + 1;	/* 500ns */
	u32_t tdinit2 = (200 * CONFIG_DRAM_CLK) + 1;		/* 200us */
	u32_t tdinit3 = (1 * CONFIG_DRAM_CLK) + 1;			/* 1us */
	u8_t twtp = tcwl + 2 + twr;							/* WL + BL / 2 + tWR */
	u8_t twr2rd = tcwl + 2 + twtr;						/* WL + BL / 2 + tWTR */
	u8_t trd2wr = tcl + 2 + 1 - tcwl;					/* RL + BL / 2 + 2 - WL */

	write32((virtual_addr_t)&ctl->mr[0], 0x263);		/* CL=11, WR=12 */
	write32((virtual_addr_t)&ctl->mr[1], 0x4);
	write32((virtual_addr_t)&ctl->mr[2], 0x0);			/* CWL=8 */
	write32((virtual_addr_t)&ctl->mr[3], 0x0);

	/* Set DRAM timing */
	write32((virtual_addr_t)&ctl->dramtmg[0], DRAMTMG0_TWTP(twtp) | DRAMTMG0_TFAW(tfaw) | DRAMTMG0_TRAS_MAX(trasmax) | DRAMTMG0_TRAS(tras));
	write32((virtual_addr_t)&ctl->dramtmg[1], DRAMTMG1_TXP(txp) | DRAMTMG1_TRTP(trtp) | DRAMTMG1_TRC(trc));
	write32((virtual_addr_t)&ctl->dramtmg[2], DRAMTMG2_TCWL(tcwl) | DRAMTMG2_TCL(tcl) | DRAMTMG2_TRD2WR(trd2wr) | DRAMTMG2_TWR2RD(twr2rd));
	write32((virtual_addr_t)&ctl->dramtmg[3], DRAMTMG3_TMRW(tmrw) | DRAMTMG3_TMRD(tmrd) | DRAMTMG3_TMOD(tmod));
	write32((virtual_addr_t)&ctl->dramtmg[4], DRAMTMG4_TRCD(trcd) | DRAMTMG4_TCCD(tccd) | DRAMTMG4_TRRD(trrd) | DRAMTMG4_TRP(trp));
	write32((virtual_addr_t)&ctl->dramtmg[5], DRAMTMG5_TCKSRX(tcksrx) | DRAMTMG5_TCKSRE(tcksre) | DRAMTMG5_TCKESR(tckesr) | DRAMTMG5_TCKE(tcke));

	/* Set two rank timing */
	clrsetbits_le32(&ctl->dramtmg[8], (0xff << 8) | (0xff << 0), (0x66 << 8) | (0x10 << 0));

	/* Set PHY interface timing, write latency and read latency configure */
	write32((virtual_addr_t)&ctl->pitmg[0], (0x2 << 24) | (t_rdata_en << 16) | (0x1 << 8) | (wr_latency << 0));

	/* Set PHY timing, PTR0-2 use default */
	write32((virtual_addr_t)&ctl->ptr[3], PTR3_TDINIT0(tdinit0) | PTR3_TDINIT1(tdinit1));
	write32((virtual_addr_t)&ctl->ptr[4], PTR4_TDINIT2(tdinit2) | PTR4_TDINIT3(tdinit3));

	/* Set refresh timing */
	write32((virtual_addr_t)&ctl->rfshtmg, RFSHTMG_TREFI(trefi) | RFSHTMG_TRFC(trfc));
}

static void mctl_zq_calibration(struct dram_para_t * para)
{
	struct v3s_dram_ctl_reg_t * ctl = (struct v3s_dram_ctl_reg_t *)V3S_DRAM_CTL_BASE;
	u16_t zq_val[6];
	u32_t val;
	u8_t zq;
	int i;

	if(((read32(0x01c00000 + 0x24) & 0xff) == 0) && ((read32(0x01c00000 + 0xf0) & 0x1) == 0))
	{
		clrsetbits_le32(&ctl->zqcr, 0xffff, CONFIG_DRAM_ZQ & 0xffff);

		write32((virtual_addr_t)&ctl->pir, PIR_CLRSR);
		mctl_phy_init(PIR_ZCAL);

		val = read32((virtual_addr_t)&ctl->zqdr[0]);
		val &= (0x1f << 16) | (0x1f << 0);
		val |= val << 8;
		write32((virtual_addr_t)&ctl->zqdr[0], val);

		val = read32((virtual_addr_t)&ctl->zqdr[1]);
		val &= (0x1f << 16) | (0x1f << 0);
		val |= val << 8;
		write32((virtual_addr_t)&ctl->zqdr[1], val);
		write32((virtual_addr_t)&ctl->zqdr[2], val);
	}
	else
	{
		write32((virtual_addr_t)&ctl->zqdr[2], 0x0a0a0a0a);

		for(i = 0; i < 4; i++)
		{
			zq = (CONFIG_DRAM_ZQ >> (i * 4)) & 0xf;
			write32((virtual_addr_t)&ctl->zqcr, (zq << 20) | (zq << 16) | (zq << 12) | (zq << 8) | (zq << 4) | (zq << 0));

			write32((virtual_addr_t)&ctl->pir, PIR_CLRSR);
			mctl_phy_init(PIR_ZCAL);

			zq_val[i] = read32((virtual_addr_t)&ctl->zqdr[0]) & 0xff;
			write32((virtual_addr_t)&ctl->zqdr[2], REPEAT_BYTE(zq_val[i]));

			write32((virtual_addr_t)&ctl->pir, PIR_CLRSR);
			mctl_phy_init(PIR_ZCAL);

			val = read32((virtual_addr_t)&ctl->zqdr[0]) >> 24;
			zq_val[i] |= bin_to_mgray(mgray_to_bin(val) - 1) << 8;
		}

		write32((virtual_addr_t)&ctl->zqdr[0], (zq_val[1] << 16) | zq_val[0]);
		write32((virtual_addr_t)&ctl->zqdr[1], (zq_val[3] << 16) | zq_val[2]);
	}
}

static void mctl_set_cr(struct dram_para_t * para)
{
	struct v3s_dram_com_reg_t * com = (struct v3s_dram_com_reg_t *)V3S_DRAM_COM_BASE;

	write32((virtual_addr_t)&com->cr, MCTL_CR_BL8 |
		MCTL_CR_2T |
		(para->bank_bits == 3 ? MCTL_CR_EIGHT_BANKS : MCTL_CR_FOUR_BANKS) |
		MCTL_CR_DDR2 |
		MCTL_CR_32BIT |
		MCTL_CR_INTERLEAVED |
		(para->dual_rank ? MCTL_CR_DUAL_RANK : MCTL_CR_SINGLE_RANK) |
		MCTL_CR_PAGE_SIZE(para->page_size) |
		MCTL_CR_ROW_BITS(para->row_bits));
}

static void mctl_sys_init(struct dram_para_t * para)
{
	struct v3s_dram_ctl_reg_t * ctl = (struct v3s_dram_ctl_reg_t *)V3S_DRAM_CTL_BASE;
	u32_t val;

	val = read32(V3S_CCU_BASE + CCU_MBUS_CLK);
	val &= ~(0x1 << 31);
	write32(V3S_CCU_BASE + CCU_MBUS_CLK, val);

	val = read32(V3S_CCU_BASE + CCU_MBUS_RST);
	val &= ~(0x1 << 31);
	write32(V3S_CCU_BASE + CCU_MBUS_RST, val);

	val = read32(V3S_CCU_BASE + CCU_BUS_CLK_GATE0);
	val &= ~(0x1 << 14);
	write32(V3S_CCU_BASE + CCU_BUS_CLK_GATE0, val);

	val = read32(V3S_CCU_BASE + CCU_BUS_SOFT_RST0);
	val &= ~(0x1 << 14);
	write32(V3S_CCU_BASE + CCU_BUS_SOFT_RST0, val);

	val = read32(V3S_CCU_BASE + CCU_PLL_DDR0_CTRL);
	val &= ~(0x1 << 31);
	write32(V3S_CCU_BASE + CCU_PLL_DDR0_CTRL, val);
	sdelay(10);

	val = read32(V3S_CCU_BASE + CCU_DRAM_CLK_GATE);
	val &= ~(0x1 << 31);
	write32(V3S_CCU_BASE + CCU_DRAM_CLK_GATE, val);
	sdelay(1000);

	clock_set_pll_ddr(CONFIG_DRAM_CLK * 2 * 1000000);

	val = read32(V3S_CCU_BASE + CCU_DRAM_CFG);
	val &= ~(0xf << 0);
	val &= ~(0x3 << 20);
	val |= ((1 - 1) << 0);
	val |= (0x0 << 20);
	val |= (0x1 << 16);
	write32(V3S_CCU_BASE + CCU_DRAM_CFG, val);
	mctl_await_completion((u32_t *)(V3S_CCU_BASE + CCU_DRAM_CFG), 0x1 << 16, 0);

	val = read32(V3S_CCU_BASE + CCU_BUS_SOFT_RST0);
	val |= (0x1 << 14);
	write32(V3S_CCU_BASE + CCU_BUS_SOFT_RST0, val);

	val = read32(V3S_CCU_BASE + CCU_BUS_CLK_GATE0);
	val |= (0x1 << 14);
	write32(V3S_CCU_BASE + CCU_BUS_CLK_GATE0, val);

	val = read32(V3S_CCU_BASE + CCU_MBUS_CLK);
	val |= (0x1 << 31);
	write32(V3S_CCU_BASE + CCU_MBUS_CLK, val);

	val = read32(V3S_CCU_BASE + CCU_MBUS_RST);
	val |= (0x1 << 31);
	write32(V3S_CCU_BASE + CCU_MBUS_RST, val);

	val = read32(V3S_CCU_BASE + CCU_DRAM_CFG);
	val |= (0x1 << 31);
	write32(V3S_CCU_BASE + CCU_DRAM_CFG, val);
	sdelay(10);

	write32((virtual_addr_t)&ctl->clken, 0xc00e);
	sdelay(500);
}

static int mctl_channel_init(struct dram_para_t * para)
{
	struct v3s_dram_com_reg_t * com = (struct v3s_dram_com_reg_t *)V3S_DRAM_COM_BASE;
	struct v3s_dram_ctl_reg_t * ctl = (struct v3s_dram_ctl_reg_t *)V3S_DRAM_CTL_BASE;
	int i;

	mctl_set_cr(para);
	mctl_set_timing_params(para);
	mctl_set_master_priority();

	clrbits_le32(&ctl->pgcr[0], (1 << 30) | 0x3f);
	clrsetbits_le32(&ctl->pgcr[1], 1 << 24, 1 << 26);

	write32((virtual_addr_t)&com->protect, 0x94be6fa3);
	sdelay(100);
	clrsetbits_le32(&ctl->upd2, 0xfff << 16, 0x50 << 16);
	write32((virtual_addr_t)&com->protect, 0x0);
	sdelay(100);

	for(i = 0; i < 4; i++)
		clrsetbits_le32(&ctl->datx[i].gcr, (0x3 << 4) | (0x1 << 1) | (0x3 << 2) | (0x3 << 12) | (0x3 << 14), 0x20);

	setbits_le32(&ctl->aciocr, 0x1 << 1);
	setbits_le32(&ctl->pgcr[2], 0x3 << 6);
	clrbits_le32(&ctl->pgcr[0], (0x3 << 14) | (0x3 << 12));
	clrsetbits_le32(&ctl->pgcr[2], (0x3 << 10) | (0x3 << 8), (0x1 << 10) | (0x2 << 8));

	if(para->bus_width != 32)
	{
		write32((virtual_addr_t)&ctl->datx[2].gcr, 0x0);
		write32((virtual_addr_t)&ctl->datx[3].gcr, 0x0);
	}
	clrsetbits_le32(&ctl->dtcr, 0xf << 24, (para->dual_rank ? 0x3 : 0x1) << 24);

	if(para->read_delays || para->write_delays)
	{
		mctl_dq_delay(para->read_delays, para->write_delays);
		sdelay(50);
	}
	mctl_zq_calibration(para);
	mctl_phy_init(PIR_PLLINIT | PIR_DCAL | PIR_PHYRST | PIR_DRAMINIT | PIR_QSGATE);

	if(read32((virtual_addr_t)&ctl->pgsr[0]) & (0xfe << 20))
	{
		if(((read32((virtual_addr_t)&ctl->datx[0].gsr[0]) >> 24) & 0x2) || ((read32((virtual_addr_t)&ctl->datx[1].gsr[0]) >> 24) & 0x2))
		{
			clrsetbits_le32(&ctl->dtcr, 0xf << 24, 0x1 << 24);
			para->dual_rank = 0;
		}

		if(((read32((virtual_addr_t)&ctl->datx[2].gsr[0]) >> 24) & 0x1) || ((read32((virtual_addr_t)&ctl->datx[3].gsr[0]) >> 24) & 0x1))
		{
			write32((virtual_addr_t)&ctl->datx[2].gcr, 0x0);
			write32((virtual_addr_t)&ctl->datx[3].gcr, 0x0);
			para->bus_width = 16;
		}

		mctl_set_cr(para);
		sdelay(20);

		mctl_phy_init(PIR_QSGATE);
		if(read32((virtual_addr_t)&ctl->pgsr[0]) & (0xfe << 20))
			return 1;
	}
	mctl_await_completion(&ctl->statr, 0x1, 0x1);

	setbits_le32(&ctl->rfshctl0, 0x1 << 31);
	sdelay(10);
	clrbits_le32(&ctl->rfshctl0, 0x1 << 31);
	sdelay(10);

	write32((virtual_addr_t)&ctl->pgcr[3], 0x00aa0060);
	setbits_le32(&ctl->zqcr, ZQCR_PWRDOWN);
	write32((virtual_addr_t)&com->maer, 0xffffffff);

	return 0;
}

static void mctl_auto_detect_dram_size(struct dram_para_t * para)
{
	para->page_size = 512;
	para->row_bits = 16;
	para->bank_bits = 2;

	mctl_set_cr(para);
	for(para->row_bits = 11; para->row_bits < 16; para->row_bits++)
	{
		if(mctl_mem_matches((1 << (para->row_bits + para->bank_bits)) * para->page_size))
			break;
	}

	para->page_size = 8192;
	mctl_set_cr(para);

	for(para->page_size = 512; para->page_size < 8192; para->page_size *= 2)
	{
		if(mctl_mem_matches(para->page_size))
			break;
	}
}

void sys_dram_init(void)
{
	struct v3s_dram_com_reg_t * com = (struct v3s_dram_com_reg_t *)V3S_DRAM_COM_BASE;
	struct v3s_dram_ctl_reg_t * ctl = (struct v3s_dram_ctl_reg_t *)V3S_DRAM_CTL_BASE;
	struct dram_para_t para = {
		.read_delays = 0x00007878,
		.write_delays = 0x6a440000,
		.dual_rank = 0,
		.bus_width = 32,
		.row_bits = 15,
		.bank_bits = 3,
		.page_size = 4096,
	};
	u32_t * dsz = (void *)0x00000020;

	//if(dsz[0] != 0)
	//	return;

	mctl_sys_init(&para);
	if(mctl_channel_init(&para))
	{
		dsz[0] = 0;
		return;
	}

	if(para.dual_rank)
		write32((virtual_addr_t)&ctl->odtmap, 0x00000303);
	else
		write32((virtual_addr_t)&ctl->odtmap, 0x00000201);
	sdelay(1);
	write32((virtual_addr_t)&ctl->odtcfg, 0x04000400);

	clrbits_le32(&ctl->pgcr[2], (1 << 13));
	setbits_le32(&com->cccr, 1 << 31);
	sdelay(10);
	mctl_auto_detect_dram_size(&para);
	mctl_set_cr(&para);

	dsz[0] = (1UL << (para.row_bits + para.bank_bits)) * para.page_size * (para.dual_rank ? 2 : 1);
}

//dram.h

#ifndef __V3S_REG_DRAM_H__
#define __V3S_REG_DRAM_H__

#define V3S_DRAM_COM_BASE			(0x01c62000)
#define V3S_DRAM_CTL_BASE			(0x01c63000)

#define MCTL_CR_BL8					(0x4 << 20)
#define MCTL_CR_1T					(0x1 << 19)
#define MCTL_CR_2T					(0x0 << 19)
#define MCTL_CR_LPDDR3				(0x7 << 16)
#define MCTL_CR_LPDDR2				(0x6 << 16)
#define MCTL_CR_DDR3				(0x3 << 16)
#define MCTL_CR_DDR2				(0x2 << 16)
#define MCTL_CR_SEQUENTIAL			(0x1 << 15)
#define MCTL_CR_INTERLEAVED			(0x0 << 15)
#define MCTL_CR_32BIT				(0x1 << 12)
#define MCTL_CR_16BIT				(0x0 << 12)
#define MCTL_CR_BUS_WIDTH(x)		((x) == 32 ? MCTL_CR_32BIT : MCTL_CR_16BIT)
#define MCTL_CR_PAGE_SIZE(x)		((gfls(x) - 4) << 8)
#define MCTL_CR_ROW_BITS(x)			(((x) - 1) << 4)
#define MCTL_CR_EIGHT_BANKS			(0x1 << 2)
#define MCTL_CR_FOUR_BANKS			(0x0 << 2)
#define MCTL_CR_DUAL_RANK			(0x1 << 0)
#define MCTL_CR_SINGLE_RANK			(0x0 << 0)

#define DRAMTMG0_TWTP(x)			((x) << 24)
#define DRAMTMG0_TFAW(x)			((x) << 16)
#define DRAMTMG0_TRAS_MAX(x)		((x) <<  8)
#define DRAMTMG0_TRAS(x)			((x) <<  0)

#define DRAMTMG1_TXP(x)				((x) << 16)
#define DRAMTMG1_TRTP(x)			((x) <<  8)
#define DRAMTMG1_TRC(x)				((x) <<  0)

#define DRAMTMG2_TCWL(x)			((x) << 24)
#define DRAMTMG2_TCL(x)				((x) << 16)
#define DRAMTMG2_TRD2WR(x)			((x) <<  8)
#define DRAMTMG2_TWR2RD(x)			((x) <<  0)

#define DRAMTMG3_TMRW(x)			((x) << 16)
#define DRAMTMG3_TMRD(x)			((x) << 12)
#define DRAMTMG3_TMOD(x)			((x) <<  0)

#define DRAMTMG4_TRCD(x)			((x) << 24)
#define DRAMTMG4_TCCD(x)			((x) << 16)
#define DRAMTMG4_TRRD(x)			((x) <<  8)
#define DRAMTMG4_TRP(x)				((x) <<  0)

#define DRAMTMG5_TCKSRX(x)			((x) << 24)
#define DRAMTMG5_TCKSRE(x)			((x) << 16)
#define DRAMTMG5_TCKESR(x)			((x) <<  8)
#define DRAMTMG5_TCKE(x)			((x) <<  0)

#define PTR3_TDINIT1(x)				((x) << 20)
#define PTR3_TDINIT0(x)				((x) <<  0)

#define PTR4_TDINIT3(x)				((x) << 20)
#define PTR4_TDINIT2(x)				((x) <<  0)

#define RFSHTMG_TREFI(x)			((x) << 16)
#define RFSHTMG_TRFC(x)				((x) <<  0)

#define PIR_CLRSR					(0x1 << 27)	/* Clear status registers */
#define PIR_QSGATE					(0x1 << 10)	/* Read DQS gate training */
#define PIR_DRAMINIT				(0x1 << 8)	/* DRAM initialization */
#define PIR_DRAMRST					(0x1 << 7)	/* DRAM reset */
#define PIR_PHYRST					(0x1 << 6)	/* PHY reset */
#define PIR_DCAL					(0x1 << 5)	/* DDL calibration */
#define PIR_PLLINIT					(0x1 << 4)	/* PLL initialization */
#define PIR_ZCAL					(0x1 << 1)	/* ZQ calibration */
#define PIR_INIT					(0x1 << 0)	/* PHY initialization trigger */
#define PGSR_INIT_DONE				(0x1 << 0)	/* PHY init done */
#define ZQCR_PWRDOWN				(0x1 << 31)	/* ZQ power down */

#define DATX_IOCR_DQ(x)				(x)
#define DATX_IOCR_DM				(8)
#define DATX_IOCR_DQS				(9)
#define DATX_IOCR_DQSN				(10)

#define DATX_IOCR_WRITE_DELAY(x)	((x) << 8)
#define DATX_IOCR_READ_DELAY(x)		((x) << 0)


void sys_dram_init(void);


#endif /* __V3S_REG_DRAM_H__ */

//reg-ccu.h

#ifndef __V3S_REG_CCU_H__
#define __V3S_REG_CCU_H__

#define V3S_CCU_BASE			(0x01c20000)

#define CCU_PLL_CPU_CTRL		(0x000)
#define CCU_PLL_AUDIO_CTRL		(0x008)
#define CCU_PLL_VIDEO_CTRL		(0x010)
#define CCU_PLL_VE_CTRL			(0x018)
#define CCU_PLL_DDR0_CTRL		(0x020)
#define CCU_PLL_PERIPH0_CTRL	(0x028)
#define CCU_PLL_ISP_CTRL		(0x02c)
#define CCU_PLL_PERIPH1_CTRL	(0x044)
#define CCU_PLL_DDR1_CTRL		(0x04c)

#define CCU_CPU_AXI_CFG			(0x050)
#define CCU_AHB_APB0_CFG		(0x054)
#define CCU_APB1_CFG			(0x058)
#define CCU_AHB2_CFG			(0x05c)

#define CCU_BUS_CLK_GATE0		(0x060)
#define CCU_BUS_CLK_GATE1		(0x064)
#define CCU_BUS_CLK_GATE2		(0x068)
#define CCU_BUS_CLK_GATE3		(0x06c)
#define CCU_BUS_CLK_GATE4		(0x070)

#define CCU_SDMMC0_CLK			(0x088)
#define CCU_SDMMC1_CLK			(0x08c)
#define CCU_SDMMC2_CLK			(0x090)
#define CCU_CE_CLK				(0x09c)
#define CCU_SPI0_CLK			(0x0a0)
#define CCU_USBPHY_CFG			(0x0cc)
#define CCU_DRAM_CFG			(0x0f4)
#define CCU_PLL_DDR1_CFG		(0x0f8)
#define CCU_MBUS_RST			(0x0fc)
#define CCU_DRAM_CLK_GATE		(0x100)
#define CCU_TCON_CLK			(0x118)
#define CCU_CSI_MISC_CLK		(0x130)
#define CCU_CSI_CLK				(0x134)
#define CCU_VE_CLK				(0x13c)
#define CCU_AC_DIG_CLK			(0x140)
#define CCU_AVS_CLK				(0x144)
#define CCU_MBUS_CLK			(0x15c)
#define CCU_MIPI_CSI_CLK		(0x16c)

#define CCU_PLL_STABLE_TIME0	(0x200)
#define CCU_PLL_STABLE_TIME1	(0x204)
#define CCU_PLL_CPU_BIAS		(0x220)
#define CCU_PLL_AUDIO_BIAS		(0x224)
#define CCU_PLL_VIDEO_BIAS		(0x228)
#define CCU_PLL_VE_BIAS			(0x22c)
#define CCU_PLL_DDR0_BIAS		(0x230)
#define CCU_PLL_PERIPH0_BIAS	(0x234)
#define CCU_PLL_ISP_BIAS		(0x238)
#define CCU_PLL_PERIPH1_BIAS	(0x244)
#define CCU_PLL_DDR1_BIAS		(0x24C)
#define CCU_PLL_CPU_TUN			(0x250)
#define CCU_PLL_DDR0_TUN		(0x260)
#define CCU_PLL_CPU_PAT			(0x280)
#define CCU_PLL_AUDIO_PAT		(0x284)
#define CCU_PLL_VIDEO_PAT		(0x288)
#define CCU_PLL_VE_PAT			(0x28c)
#define CCU_PLL_DDR0_PAT		(0x290)
#define CCU_PLL_ISP_PAT			(0x298)
#define CCU_PLL_PERIPH1_PAT		(0x2a4)
#define CCU_PLL_DDR1_PAT0		(0x2ac)
#define CCU_PLL_DDR1_PAT1		(0x2b0)

#define CCU_BUS_SOFT_RST0		(0x2c0)
#define CCU_BUS_SOFT_RST1		(0x2c4)
#define CCU_BUS_SOFT_RST2		(0x2c8)
#define CCU_BUS_SOFT_RST3		(0x2d0)
#define CCU_BUS_SOFT_RST4		(0x2d8)

#define CCU_PS_CTRL				(0x300)
#define CCU_PS_CNT				(0x304)

#endif /* __V3S_REG_CCU_H__ */

之后就可以调用 sys_dram_init(); 初始化SDRAM了,但是这样只能在代码执行后才能使用SDRAM,内部44KB的RAM当做ROM是不够的,想要程序在SDRAM中执行,就要在下载代码前就将SDRAM初始化好,然后将代码下载到SDRAM,并将IRAM IROM 中断向量表都设置到SDRAM所在地址。

这个使用jlink v9初始化SDRAM的工作我已经做好了,在工程目录下建立一个文件 外部SDRAM初始化.mac

//外部SDRAM初始化.mac

execUserPreload()
{
    __message "Initializing SDRAM ...\n";
    __writeMemory32(0x0,0x1C2015C,"Memory");
    __writeMemory32(0x0,0x1C200FC,"Memory");
    __writeMemory32(0x1000000,0x1C20060,"Memory");
    __writeMemory32(0x1000000,0x1C202C0,"Memory");
    __writeMemory32(0x1000,0x1C20020,"Memory");
    //__reg_value=__readMemory32(0x00, “Memory”);
    __writeMemory32(0x0,0x1C20100,"Memory");
    //__reg_value=__readMemory32(0x00, “Memory”);
    __writeMemory32(0x80101D00,0x1C20020,"Memory");
    //__reg_value=__readMemory32(0x00, “Memory”);
    __writeMemory32(0x10000,0x1C200F4,"Memory");
    __writeMemory32(0x1004000,0x1C202C0,"Memory");
    __writeMemory32(0x1004000,0x1C20060,"Memory");
    __writeMemory32(0x80000000,0x1C2015C,"Memory");
    __writeMemory32(0x80000000,0x1C200FC,"Memory");
    __writeMemory32(0x80000000,0x1C200F4,"Memory");
    //__reg_value=__readMemory32(0x00, “Memory”);
    __writeMemory32(0xC00E,0x1C6300C,"Memory");
    //__reg_value=__readMemory32(0x00, “Memory”);
    __writeMemory32(0x4219E4,0x1C62000,"Memory");
    __writeMemory32(0x263,0x1C63030,"Memory");
    __writeMemory32(0x4,0x1C63034,"Memory");
    __writeMemory32(0x0,0x1C63038,"Memory");
    __writeMemory32(0x0,0x1C6303C,"Memory");
    __writeMemory32(0x8091B09,0x1C63058,"Memory");
    __writeMemory32(0x2020C,0x1C6305C,"Memory");
    __writeMemory32(0x3030307,0x1C63060,"Memory");
    __writeMemory32(0x200C,0x1C63064,"Memory");
    __writeMemory32(0x4010203,0x1C63068,"Memory");
    __writeMemory32(0x5050403,0x1C6306C,"Memory");
    __writeMemory32(0x90006610,0x1C63078,"Memory");
    __writeMemory32(0x2010101,0x1C63080,"Memory");
    __writeMemory32(0xB523281,0x1C63050,"Memory");
    __writeMemory32(0x16911941,0x1C63054,"Memory");
    __writeMemory32(0x2B003C,0x1C63090,"Memory");
    __writeMemory32(0x10190,0x1C62090,"Memory");
    __writeMemory32(0x1,0x1C62098,"Memory");
    __writeMemory32(0x200000D,0x1C62010,"Memory");
    __writeMemory32(0x800100,0x1C62014,"Memory");
    __writeMemory32(0x6000009,0x1C62018,"Memory");
    __writeMemory32(0x1000400,0x1C6201C,"Memory");
    __writeMemory32(0x200000D,0x1C62020,"Memory");
    __writeMemory32(0x600100,0x1C62024,"Memory");
    __writeMemory32(0x100000D,0x1C62028,"Memory");
    __writeMemory32(0x200080,0x1C6202C,"Memory");
    __writeMemory32(0x7000009,0x1C62030,"Memory");
    __writeMemory32(0x1000640,0x1C62034,"Memory");
    __writeMemory32(0x100000D,0x1C62038,"Memory");
    __writeMemory32(0x200080,0x1C6203C,"Memory");
    __writeMemory32(0x1000009,0x1C62040,"Memory");
    __writeMemory32(0x400080,0x1C62044,"Memory");
    __writeMemory32(0x100000D,0x1C62048,"Memory");
    __writeMemory32(0x400080,0x1C6204C,"Memory");
    __writeMemory32(0x100000D,0x1C62050,"Memory");
    __writeMemory32(0x400080,0x1C62054,"Memory");
    __writeMemory32(0x4000009,0x1C62058,"Memory");
    __writeMemory32(0x400100,0x1C6205C,"Memory");
    __writeMemory32(0x2000030D,0x1C62060,"Memory");
    __writeMemory32(0x4001800,0x1C62064,"Memory");
    __writeMemory32(0x4000009,0x1C62068,"Memory");
    __writeMemory32(0x400120,0x1C6206C,"Memory");
    __writeMemory32(0x4005400,0x1C63100,"Memory");
    __writeMemory32(0x4680C620,0x1C63104,"Memory");
    __writeMemory32(0x94BE6FA3,0x1C62800,"Memory");
    //__reg_value=__readMemory32(0x00, “Memory”);
    __writeMemory32(0x80500010,0x1C63888,"Memory");
    __writeMemory32(0x0,0x1C62800,"Memory");
    //__reg_value=__readMemory32(0x00, “Memory”);
    __writeMemory32(0x7C0002A1,0x1C63344,"Memory");
    __writeMemory32(0x7C0002A1,0x1C633C4,"Memory");
    __writeMemory32(0x20,0x1C63444,"Memory");
    __writeMemory32(0x20,0x1C634C4,"Memory");
    __writeMemory32(0x34A,0x1C63208,"Memory");
    __writeMemory32(0x2CC0,0x1C63108,"Memory");
    __writeMemory32(0x4000400,0x1C63100,"Memory");
    __writeMemory32(0x26C0,0x1C63108,"Memory");
    __writeMemory32(0x81003087,0x1C630C0,"Memory");
    __writeMemory32(0x10,0x1C63310,"Memory");
    __writeMemory32(0x10,0x1C63314,"Memory");
    __writeMemory32(0x10,0x1C63318,"Memory");
    __writeMemory32(0x10,0x1C6331C,"Memory");
    __writeMemory32(0x10,0x1C63320,"Memory");
    __writeMemory32(0x10,0x1C63324,"Memory");
    __writeMemory32(0x10,0x1C63328,"Memory");
    __writeMemory32(0x10,0x1C6332C,"Memory");
    __writeMemory32(0x10,0x1C63330,"Memory");
    __writeMemory32(0xE,0x1C63390,"Memory");
    __writeMemory32(0xE,0x1C63394,"Memory");
    __writeMemory32(0xE,0x1C63398,"Memory");
    __writeMemory32(0xE,0x1C6339C,"Memory");
    __writeMemory32(0xE,0x1C633A0,"Memory");
    __writeMemory32(0xE,0x1C633A4,"Memory");
    __writeMemory32(0xE,0x1C633A8,"Memory");
    __writeMemory32(0xE,0x1C633AC,"Memory");
    __writeMemory32(0xE,0x1C633B0,"Memory");
    __writeMemory32(0x10,0x1C63410,"Memory");
    __writeMemory32(0x10,0x1C63414,"Memory");
    __writeMemory32(0x10,0x1C63418,"Memory");
    __writeMemory32(0x10,0x1C6341C,"Memory");
    __writeMemory32(0x10,0x1C63420,"Memory");
    __writeMemory32(0x10,0x1C63424,"Memory");
    __writeMemory32(0x10,0x1C63428,"Memory");
    __writeMemory32(0x10,0x1C6342C,"Memory");
    __writeMemory32(0x10,0x1C63430,"Memory");
    __writeMemory32(0xE,0x1C63490,"Memory");
    __writeMemory32(0xE,0x1C63494,"Memory");
    __writeMemory32(0xE,0x1C63498,"Memory");
    __writeMemory32(0xE,0x1C6349C,"Memory");
    __writeMemory32(0xE,0x1C634A0,"Memory");
    __writeMemory32(0xE,0x1C634A4,"Memory");
    __writeMemory32(0xE,0x1C634A8,"Memory");
    __writeMemory32(0xE,0x1C634AC,"Memory");
    __writeMemory32(0xE,0x1C634B0,"Memory");
    __writeMemory32(0x400,0x1C63100,"Memory");
    __writeMemory32(0x400,0x1C63334,"Memory");
    __writeMemory32(0x400,0x1C63338,"Memory");
    __writeMemory32(0x400,0x1C633B4,"Memory");
    __writeMemory32(0x400,0x1C633B8,"Memory");
    __writeMemory32(0xA00,0x1C63434,"Memory");
    __writeMemory32(0xA00,0x1C63438,"Memory");
    __writeMemory32(0x600,0x1C634B4,"Memory");
    __writeMemory32(0x600,0x1C634B8,"Memory");
    __writeMemory32(0x4000400,0x1C63100,"Memory");
    //__reg_value=__readMemory32(0x00, “Memory”);
    //__reg_value=__readMemory32(0x00, “Memory”);
    __writeMemory32(0xA0A0A0A,0x1C63150,"Memory");
    __writeMemory32(0xBBBBBB,0x1C63140,"Memory");
    __writeMemory32(0x8000000,0x1C63000,"Memory");
    __writeMemory32(0x3,0x1C63000,"Memory");
    __writeMemory32(0xA0A0A0A,0x1C63150,"Memory");
    __writeMemory32(0x8000000,0x1C63000,"Memory");
    __writeMemory32(0x3,0x1C63000,"Memory");
    __writeMemory32(0xBBBBBB,0x1C63140,"Memory");
    __writeMemory32(0x8000000,0x1C63000,"Memory");
    __writeMemory32(0x3,0x1C63000,"Memory");
    __writeMemory32(0xA0A0A0A,0x1C63150,"Memory");
    __writeMemory32(0x8000000,0x1C63000,"Memory");
    __writeMemory32(0x3,0x1C63000,"Memory");
    __writeMemory32(0x999999,0x1C63140,"Memory");
    __writeMemory32(0x8000000,0x1C63000,"Memory");
    __writeMemory32(0x3,0x1C63000,"Memory");
    __writeMemory32(0xE0E0E0E,0x1C63150,"Memory");
    __writeMemory32(0x8000000,0x1C63000,"Memory");
    __writeMemory32(0x3,0x1C63000,"Memory");
    __writeMemory32(0x333333,0x1C63140,"Memory");
    __writeMemory32(0x8000000,0x1C63000,"Memory");
    __writeMemory32(0x3,0x1C63000,"Memory");
    __writeMemory32(0x7070707,0x1C63150,"Memory");
    __writeMemory32(0x8000000,0x1C63000,"Memory");
    __writeMemory32(0x3,0x1C63000,"Memory");
    __writeMemory32(0xA0A0A0A,0x1C63148,"Memory");
    __writeMemory32(0x7070E0E,0x1C6314C,"Memory");
    __writeMemory32(0x571,0x1C63000,"Memory");
    __writeMemory32(0x80200010,0x1C6308C,"Memory");
    //__reg_value=__readMemory32(0x00, “Memory”);
    __writeMemory32(0x200010,0x1C6308C,"Memory");
    //__reg_value=__readMemory32(0x00, “Memory”);
    __writeMemory32(0xAA0060,0x1C6310C,"Memory");
    __writeMemory32(0x80333333,0x1C63140,"Memory");
    __writeMemory32(0xFFFFFFFF,0x1C62094,"Memory");
    __writeMemory32(0x201,0x1C63120,"Memory");
    //__reg_value=__readMemory32(0x00, “Memory”);
    __writeMemory32(0x4000400,0x1C6307C,"Memory");
    __writeMemory32(0x6C0,0x1C63108,"Memory");
    __writeMemory32(0x80103040,0x1C620D0,"Memory");
    //__reg_value=__readMemory32(0x00, “Memory”);
    __writeMemory32(0x4216F0,0x1C62000,"Memory");
    __writeMemory32(0x0,0x40000000,"Memory");
    __writeMemory32(0xAA55AA55,0x40400000,"Memory");
    __writeMemory32(0x0,0x40000000,"Memory");
    __writeMemory32(0xAA55AA55,0x40800000,"Memory");
    __writeMemory32(0x0,0x40000000,"Memory");
    __writeMemory32(0xAA55AA55,0x41000000,"Memory");
    __writeMemory32(0x421AC0,0x1C62000,"Memory");
    __writeMemory32(0x0,0x40000000,"Memory");
    __writeMemory32(0xAA55AA55,0x40000200,"Memory");
    __writeMemory32(0x0,0x40000000,"Memory");
    __writeMemory32(0xAA55AA55,0x40000400,"Memory");
    __writeMemory32(0x0,0x40000000,"Memory");
    __writeMemory32(0xAA55AA55,0x40000800,"Memory");
    __writeMemory32(0x4218C0,0x1C62000,"Memory");
    __message "Initializing SDRAM ... Completed\n";
}

上面这个就是初始化SDRAM的命令,是我从上面代码执行后写入的寄存器已经数据中分析得到的,现在要设置IAR,让IAR控制jlink在下载代码前对这些寄存器进行初始化。

在设置中 Debugger->setup 中setup macros 勾选use macro file(s),然后添加刚刚这个.mac文件

之后修改.icf文件,修改地址信息(看我的第一篇V3S裸机文章)

define symbol __ICFEDIT_intvec_start__ = 0x41000000;
/*-Memory Regions-*/
define symbol __ICFEDIT_region_IROM1_start__ = 0x41000000;
define symbol __ICFEDIT_region_IROM1_end__   = 0x41FFFFFF;
define symbol __ICFEDIT_region_IRAM1_start__ = 0x40000000;
define symbol __ICFEDIT_region_IRAM1_end__   = 0x40FFFFFF;

这样的话就使用0x41000000这个地址作为ROM,有32MBrom足够你裸机使用了,千万注意,用了这个jlink初始化SDRAM后,千万不要在程序中再去初始化SDRAM了,会导致SDRAM数据被破坏,程序最终也无法执行的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cp1300

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值