start.S源码:
.globl _start
_start:
// 硬件相关的设置
// Peri port setup
ldr r0, =0x70000000
orr r0, r0, #0x13
mcr p15,0,r0,c15,c2,4 @ 256M(0x70000000-0x7fffffff)
// 关看门狗
// 往WTCON(0x7E004000)写0
ldr r0, =0x7E004000 // 伪指令
mov r1, #0
str r1, [r0]
bl clock_init
// 为调用C函数准备环境
ldr sp, =8*1024
bl sdram_init
// 重定位代码
// 把片内内存中程序的代码段、数据段复制到它的链接地址去
adr r0, _start // 获得_start指令当前所在的地址 : 0
ldr r1, =_start // _start的链接地址 0x50000000
ldr r2, =bss_start // bss段的起始链接地址
cmp r0,r1
beq clean_bss
copy_loop:
ldr r3, [r0], #4
str r3, [r1], #4
cmp r1, r2
bne copy_loop
// 把BSS段对应的内存清零
clean_bss:
ldr r0, =bss_start
ldr r1, =bss_end
mov r3, #0
cmp r0, r1
beq on_ddr
clean_loop:
str r3, [r0], #4
cmp r0, r1
bne clean_loop
on_ddr:
// 调用C函数
ldr pc, =main // pc等于main的链接地址
===================================================================
clock.S源码:
#define APLL_LOCK 0x7e00f000
#define MPLL_LOCK 0x7e00f004
#define EPLL_LOCK 0x7e00f008
#define LOCK_TIME 0xffff
#define OTHERS 0x7e00f900
#define CLK_DIV0 0x7e00f020
#define CLK_SRC 0x7e00f01c
.text
.global clock_init
clock_init: //初始化系统时钟
@ set the lock time to max
ldr r0, =LOCK_TIME
ldr r1, =APLL_LOCK
str r0, [r1]
ldr r1, =MPLL_LOCK
str r0, [r1]
ldr r1, =EPLL_LOCK
str r0, [r1]
@ set async mode
ldr r0, =OTHERS
ldr r1, [r0]
bic r1, #0xc0
str r1, [r0]
loop1:
ldr r0, =OTHERS
ldr r1, [r0]
and r1, #0xf00
cmp r1, #0
bne loop1
@ set the divider
#define DIV_VAL ( (0)|(1<<4)|(1<<8)|(1<<9)|(3<<12) )
ldr r0, =CLK_DIV0
ldr r1, =DIV_VAL
str r1, [r0]
@ set APLL, MPLL, EPLL
#define SDIV 1
#define PDIV 3
#define MDIV 266
#define PLL_ENABLE ( 1 << 31 )
#define APLL_VAL ( (SDIV<<0)|(PDIV<<8)|(MDIV<<16)|(PLL_ENABLE) )
#define MPLL_VAL APLL_VAL
#define EPLL0_VAL ( (2<<0)|(1<<8)|(32<<16)|PLL_ENABLE)
#define EPLL1_VAL ( 0 )
#define APLL_CON 0x7e00f00c
#define MPLL_CON 0x7e00f010
#define EPLL_CON0 0x7e00f014
#define EPLL_CON1 0x7e00f018
ldr r0, =APLL_CON
ldr r1, =APLL_VAL
str r1, [r0]
ldr r0, =MPLL_CON
ldr r1, =MPLL_VAL
str r1, [r0]
ldr r0, =EPLL_CON0
ldr r1, =EPLL0_VAL
str r1, [r0]
ldr r0, =EPLL_CON1
ldr r1, =EPLL1_VAL
str r1, [r0]
@ select the source
ldr r0, =CLK_SRC
mov r1, #7
str r1, [r0]
mov pc, lr
====================================================================
sdram.c源码:
#include "common.h"
#define MEMCCMD 0x7e001004
#define P1REFRESH 0x7e001010
#define P1CASLAT 0x7e001014
#define MEM_SYS_CFG 0x7e00f120
#define P1MEMCFG 0x7e00100c
#define P1T_DQSS 0x7e001018
#define P1T_MRD 0x7e00101c
#define P1T_RAS 0x7e001020
#define P1T_RC 0x7e001024
#define P1T_RCD 0x7e001028
#define P1T_RFC 0x7e00102c
#define P1T_RP 0x7e001030
#define P1T_RRD 0x7e001034
#define P1T_WR 0x7e001038
#define P1T_WTR 0x7e00103c
#define P1T_XP 0x7e001040
#define P1T_XSR 0x7e001044
#define P1T_ESR 0x7e001048
#define P1MEMCFG2 0X7e00104c
#define P1_chip_0_cfg 0x7e001200
#define P1MEMSTAT 0x7e001000
#define P1MEMCCMD 0x7e001004
#define P1DIRECTCMD 0x7e001008
#define HCLK 133000000
#define nstoclk(ns) (ns/( 1000000000/HCLK)+1)
//初始化DDR
int sdram_init( void )
{
// tell dramc to configure
set_val( MEMCCMD, 0x4 );
// set refresh period
set_val( P1REFRESH, nstoclk(7800) );
// set timing para
set_val( P1CASLAT, ( 3 << 1 ) );
set_val( P1T_DQSS, 0x1 ); // 0.75 - 1.25
set_val( P1T_MRD, 0x2 );
set_val( P1T_RAS, nstoclk(45) );
set_val( P1T_RC, nstoclk(68) );
u32 trcd = nstoclk( 23 );
set_val( P1T_RCD, trcd | (( trcd - 3 ) << 3 ) );
u32 trfc = nstoclk( 80 );
set_val( P1T_RFC, trfc | ( ( trfc-3 ) << 5 ) );
u32 trp = nstoclk( 23 );
set_val( P1T_RP, trp | ( ( trp - 3 ) << 3 ) );
set_val( P1T_RRD, nstoclk(15) );
set_val( P1T_WR, nstoclk(15) );
set_val( P1T_WTR, 0x7 );
set_val( P1T_XP, 0x2 );
set_val( P1T_XSR, nstoclk(120) );
set_val( P1T_ESR, nstoclk(120) );
// set mem cfg
set_nbit( P1MEMCFG, 0, 3, 0x2 ); // 10 column address
// set_nbit: 把从第bit位开始的一共len位消零,然后把这几位设为val
//set_nbit( P1MEMCFG, 3, 3, 0x2 ); // 13 row address
set_nbit( P1MEMCFG, 3, 3, 0x3 ); // 14 row address
set_zero( P1MEMCFG, 6 ); // A10/AP
set_nbit( P1MEMCFG, 15, 3, 0x2 ); // Burst 4
set_nbit( P1MEMCFG2, 0, 4, 0x5 );
set_2bit( P1MEMCFG2, 6, 0x1 ); // 32 bit
set_nbit( P1MEMCFG2, 8, 3, 0x3 ); // Mobile DDR SDRAM
set_2bit( P1MEMCFG2, 11, 0x1 );
set_one( P1_chip_0_cfg, 16 ); // Bank-Row-Column organization
// memory init
set_val( P1DIRECTCMD, 0xc0000 ); // NOP
set_val( P1DIRECTCMD, 0x000 ); // precharge
set_val( P1DIRECTCMD, 0x40000 ); // auto refresh
set_val( P1DIRECTCMD, 0x40000 ); // auto refresh
set_val( P1DIRECTCMD, 0xa0000 ); // EMRS
set_val( P1DIRECTCMD, 0x80032 ); // MRS
set_val( MEM_SYS_CFG, 0x0 );
// set dramc to "go" status
set_val( P1MEMCCMD, 0x000 );
// wait ready
while( !(( read_val( P1MEMSTAT ) & 0x3 ) == 0x1));
}
==================================================================
led.c源码:
void delay(volatile int count)
{
volatile int i = count;
while(i)
{
i--;
}
}
//int i = 0xf; // 位于数据段
int i = 0; // 位于BSS段
volatile const int j = 0x12345678; // 位于只读数据段
//volatile int k=0; // bss段
int main()
{
// 配置GPMCON让GPM0,1,2,3作为输出引脚
volatile unsigned long *gpmcon = (volatile unsigned long *)0x7F008820;
volatile unsigned long *gpmdat = (volatile unsigned long *)0x7F008824;
*gpmcon &= ~(0xffff);
*gpmcon |= 0x1111;
// 循环点亮这4个LED
while (1)
{
*gpmdat &= ~0xf;
*gpmdat |= i;
i++;
delay(20000);
if (i == 16)
i = 0;
}
return 0;
}
====================================================================
Makefile文件:
led.bin : start.o clock.o sdram.o led.o
arm-linux-ld -T led.lds -o led.elf $^
arm-linux-objcopy -O binary led.elf led.bin
arm-linux-objdump -D led.elf > led.dis
%.o : %.S
arm-linux-gcc -g -c -O2 -o $@ $^
%.o : %.c
arm-linux-gcc -g -c -O2 -o $@ $^
clean:
rm -f *.o *.bin *.elf *.dis
====================================================================
led.lds文件:
SECTIONS
{
. = 0x50000000;
.text :
{
start.o
* (.text)
}
. = ALIGN(4);
.rodata :
{
* (.rodata)
}
. = ALIGN(4);
.data :
{
* (.data)
}
. = ALIGN(4);
bss_start = . ; // 0x50000450
.bss :
{
* (.bss) // i
* (.common)
}
bss_end = . ; // 0x50000450
}
===================================================================
引脚定义:Xm1RAS :Row address strobe (active low),行地址锁存信号
Xm1CAS : Column address strobe (active low),列地址锁存信号
Xm1WEN:Write enable (active low) ,写使能
上一篇:OK6410裸机之NAND Flash操作更新固件
下一篇:OK6410裸机片内内存中重定位代码
推荐阅读
史海拾趣
ETA-USA公司起源于XXXX年,当时由几位电子工程领域的先驱者在美国密歇根州的Troy市创立了这家专注于电子技术和解决方案的公司。初创时期,ETA-USA面临着技术挑战、资金短缺和市场竞争激烈等多重困难。然而,通过不断创新和提供高质量的工程服务,公司逐渐在电子行业崭露头角,赢得了客户的信任。
常州能动(ENDRIVE)公司自创立之初,就将技术创新作为公司发展的核心驱动力。在公司发展的早期阶段,研发团队成功开发出一款高效能、低能耗的电源管理芯片,这一创新产品在市场上引起了广泛关注。通过不断的技术迭代和优化,这款芯片的性能逐渐提升,成本逐渐降低,成为了公司的明星产品,为公司的快速发展奠定了坚实基础。
为了进一步提升自身的技术实力和市场竞争力,Davicom积极寻求与业界巨头的合作。经过多轮谈判,Davicom最终与一家国际知名的IC设计大厂达成战略合作协议。双方共同研发出一系列高性能、低功耗的网络通讯IC产品,这些产品一经推出便受到市场的热烈欢迎。
在竞争激烈的电子行业中,Davicom始终坚持自主研发,不断突破核心技术。公司投入大量研发资金,建立了一支高素质的研发团队,并申请了多项专利。通过多年的努力,Davicom在DSP IC及系统应用技术方面取得了重大突破,成功开发出多款具有竞争力的产品。
面对数字化转型的浪潮,DLG Hanbit公司积极拥抱变革。公司加大了对云计算、大数据、人工智能等技术的研发投入,推出了一系列智能电子产品和解决方案。同时,公司还加强了与互联网企业、电信运营商等合作伙伴的合作,共同打造智能生态圈。未来,DLG Hanbit公司将继续秉承创新、品质、环保的理念,致力于成为全球领先的半导体设计和制造企业。
先说说自己的情况:刚刚自学完Verilog HDL,下载了ModelSim-Altera 6.4a,能用它做一些简单的仿真,测试程序主要还是模仿。 如果想要深入,有两问题想请教下各位大大: ...… 查看全部问答∨ |
|
大家好,我毕业于一所普通高校的计算机专业,到现在已经毕业一年了,目前在一家小型企业做单片机程序员(主要用51系列),用的是C语言,由于所学的专业和从事的工作有一定差距,所以往往感到力不从心,比如,电路方面很薄弱,单片机又是自己自学的 ...… 查看全部问答∨ |
RCC_HCLKConfig(RCC_SYSCLK_Div1); RCC_PCLK2Config(RCC_HCLK_Div1); RCC_PCLK1Config(RCC_HCLK_Div2);RCC_ADCCLKConfig(RCC_PCLK2_Div4);RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);SysTick_CLKSourceConfig(SysTi ...… 查看全部问答∨ |
请用过的朋友说下,这个器件的稳定性如何? FLASH 100次的问题解决了没?到底存不存在这个问题(勘误上倒是写了)? 有朋友在项目上使用了吗?功耗怎样? 谢谢。。 … 查看全部问答∨ |
由于工作比较忙!基本能实现功能,精度及稳定性有待提高 1,应该是811把计算好的电压,电流值发送给PC或就地LCD上显示,可是我现在都是在PC或在程序里手动添加个系数进去的 2,板子连接比较多,导致壳体里安不下所有的板子了,计划下次有空,画个 ...… 查看全部问答∨ |
在采集一组并行接口信号时,发现接收到的数据非常不稳定。用示波器测量几个用于同步的控制信号,发现时不时的有毛刺产生。因为这些数据最终都是要显示在液晶屏上的,当示波器同时测量两个同步信号时,液晶屏的显示错位现 ...… 查看全部问答∨ |
|
TMS320C6727下错程序后再下应用程序不能工作是怎么回事? 2块电路板上TMS320C6727和FPGA连接引脚都是一样的,不小心把A的程序下载到B的板子上后,就把B板的Flash擦了一遍后,重新写boot和loader,再下载B程序下载到B板上,结果发现程序跑不起来,跟仿真器发现,应用程序创建任务是出错,请高手指点是TMS320 ...… 查看全部问答∨ |