a.Memory Controller
b.Nand Flash
c.UART
d.Interrupt
e.Timer
Memory Controller
SDRAM:
S3C2410 供给了外接ROM、SRAM、SDRAM、NOR Flash、NAND Flash的接口。S3C2410外接存储器的空间被分为8 BANKS,每BANK容量为128M:当拜访BANKx(x从0到7)所对应的地址规模x*128M到(x+1)*128M-1
SDRAM运用BANK6,它的物理开端地址为6*128M=0x30000000。
(注:bank便是片选,一个片选便是一个bank,在U-Boot中,制造的时分要制造SDRAM和FLASH的 bank数,那么假如你的SDRAM或许FLASH就接了一个片选的时分,就界说为1就能够了,其他的类推,2410和其他的大部分的处理器相同,支撑NorFlash和NANDFlash发动,而这两种发动办法内存所映射的地址不怎么相同)
SDRAM(改写):
之所以称为DRAM,便是由于它要不断进行改写(Refresh)才干保存住数据,因而它是DRAM最重要的操作。
那么要隔多长时刻重复一次改写呢?现在公认的规范是,存储体中电容的数据有用保存期上限是64ms(毫秒,1/1000秒),也便是说每一行改写的循环周期是64ms。这样改写速度便是:行数量/64ms
改写操作分为两种:主动改写(Auto Refresh,简称AR)与自改写(Self Refresh,简称SR)。不论是何种改写办法,都不需求外部供给行地址信息,由于这是一个内部的主动操作。关于AR, SDRAM内部有一个行地址生成器(也称改写计数器)用来主动的顺次生成行地址。
由于改写涉及到一切L-Bank,因而在改写进程中,一切L-Bank都中止作业,而每次改写所占用的时刻为9个时钟周期(PC133规范),之后就可进入正常的作业状况,也便是说在这9 个时钟期间内,一切作业指令只能等候而无法履行。
SR则首要用于休眠形式低功耗状况下的数据保存,这方面最著名的运用便是STR(Suspend to RAM,休眠挂起于内存)。在宣布AR指令时,将CKE置于无效状况,就进入了SR形式,此刻不再依托体系时钟作业,而是依据内部的时钟进行改写操作。
SDRAM(寄存器设置):
本试验介绍怎么运用SDRAM,这需求设置13个寄存器。由于咱们只运用了BANK6,大部分的寄存器咱们不用理睬:
1.BWSCON:对应BANK0-BANK7,每BANK运用4位。这4位别离标明:
a.STx:发动/制止SDRAM的数据掩码引脚,关于SDRAM,此位为0;关于SRAM,此位为1。
b.WSx:是否运用存储器的WAIT信号,一般设为0
c.DWx:运用两位来设置存储器的位宽:00-8位,01-16位,10-32位,11-保存。
d.比较特别的是BANK0对应的4位,它们由硬件跳线决议,只读。
关于本开发板,运用两片容量为32Mbyte、位宽为16的SDRAM组成容量为64Mbyte、位宽为32的存储器,所以其BWSCON相应位为: 0010。关于本开发板,BWSCON可设为0x22111110:其实咱们只需求将BANK6对应的4位设为0010即可,其它的是什么值没什么影响,这个值是参阅手册上给出的。
2.BANKCON0-BANKCON5:咱们没用到,运用默认值0x00000700即
3. BANKCON6-BANKCON7:设为0x00018005 在8个BANK中,只要BANK6和BANK7能够运用SRAM或SDRAM,所以BANKCON6-7与BANKCON0-5有点不同: a.MT([16:15]):用于设置本BANK外接的是SRAM仍是SDRAM:SRAM-0b00,SDRAM-0b11
b.当MT=0b11时,还需求设置两个参数: Trcd([3:2]):RAS to CAS delay,设为推荐值0b01 SCAN([1:0]):
SDRAM的列地址位数,关于本开发板运用的SDRAM HY57V561620CT-H,列地址位数为9,所以SCAN=0b01。假如运用其他类型的SDRAM,您需求检查它的数据手册来决议SCAN的取值:00-8位,01-9位,10-10位
4. REFRESH(SDRAM refresh control register):设为0x008e0000+ R_CNT 其间R_CNT用于操控SDRAM的改写周期,占用REFRESH寄存器的[10:0]位,它的取值可如下核算(SDRAM时钟频率便是HCLK):
R_CNT = 2^11 + 1 – SDRAM时钟频率(MHz) * SDRAM改写周期(uS)
在未运用PLL时,SDRAM时钟频率等于晶振频率12MHz;
SDRAM 的改写周期在SDRAM的数据手册上有标明,在本开发板运用的SDRAM HY57V561620CT-H的数据手册上,可看见这么一行“8192 refresh cycles / 64ms”:所以,改写周期=64ms/8192 = 7.8125 uS。
关于本试验,R_CNT = 2^11 + 1 – 12 * 7.8125 = 1955, REFRESH=0x008e0000 + 1955 = 0x008e07a3
5.BANKSIZE:0x000000b2
位[7]=1:Enable burst operation
位[5]=1:SDRAM power down mode enable
位 [4]=1:SCLK is active only during the access (recommended) 位[2:1]=010:BANK6、BANK7对应的地址空间与BANK0-5不同。BANK0-5的地址空间都是固定的128M,地址规模是 (x*128M)到(x+1)*128M-1,x标明0到5。可是BANK7的开端地址是可变的,您能够从S3C2410数据手册第5章“Table 5-1. Bank 6/7 Addresses”中了解到BANK6、7的地址规模与地址空间的联系。
本开发板仅运用BANK6的64M空间,咱们能够令位[2:1]=010(128M/128M)或001(64M/64M):这没联系,多出来的空间程序会检测出来,不会产生运用不存在的内存的状况——后边介绍到的bootloader和linux内核都会作内存检测。 位[6]、位[3]没有运用
6.MRSRB6、MRSRB7:0x00000030
能让咱们修正的只要位[6:4](CL),SDRAM HY57V561620CT-H不支撑CL=1的状况,所以位[6:4]取值为010(CL=2)或011(CL=3)。
Nand Flash
当OM1、OM0都是低电平——即开发板插上BOOT SEL跳线时,S3C2410从NAND Flash发动:NAND Flash的开端4k代码会被主动地复制到内部SRAM中。咱们需求运用这4k代码来把更多的代码从NAND Flash中读到SDRAM中去。
NAND Flash的操作通过NFCONF、NFCMD、NFADDR、NFDATA、NFSTAT和NFECC六个寄存器来完结。在开端下面内容前,请翻开S3C2410数据手册和NAND Flash K9F1208U0M的数据手册。
在S3C2410数据手册218页,咱们能够看到读写NAND Flash的操作次第:
1.Set NAND flash configuration by NFCONF register.
2.Write NAND flash command onto NFCMD register.
3.Write NAND flash address onto NFADDR register.
4.Read/Write data while checking NAND flash status by NFSTAT register. R/nB signal should be checked before read operation or after program operation.
1、NFCONF:设为0xf830——
使能NAND Flash操控器、初始化ECC、NAND Flash片选信号nFCE=1(inactive,真实运用时再让它等于0)
设置TACLS、TWRPH0、TWRPH1。
需求指出的是TACLS、TWRPH0和TWRPH1,请翻开S3C2410数据手册218页,能够看到这三个参数操控的是NAND Flash信号线CLE/ALE与写操控信号nWE的时序联系。
咱们设的值为TACLS=0,TWRPH0=3,TWRPH1=0,其意义为:TACLS=1个HCLK时钟,TWRPH0=4个HCLK时钟,TWRPH1=1个HCLK时钟。
请翻开K9F1208U0M数据手册第13页,在表“AC Timing Characteristics for Command / Address / Data Input”中能够看到: CLE setup Time = 0 ns,CLE Hold Time = 10 ns, ALE setup Time = 0 ns,ALE Hold Time = 10 ns, WE Pulse Width = 25 ns 能够核算,即便在HCLK=100MHz的状况下,TACLS+TWRPH0+TWRPH1=6/100 uS=60 ns,也是能够满意NAND Flash K9F1208U0M的时序要求的。
2、NFCMD: 关于不同类型的Flash,操作指令一般不相同。关于本板运用的K9F1208U0M,请翻开其数据手册第8页“Table 1. Command Sets”
3、NFADDR:地址
4、NFDATA:数据,只用到低8位
5、NFSTAT:状况,只用到位0,0-busy,1-ready
6、NFECC:校验
现在来看一下怎么从NAND Flash中读出数据:
1、NFCONF = 0xf830
2、在第一次操作NAND Flash前,一般复位一下:
NFCONF &= ~0x800 (使能NAND Flash)
NFCMD = 0xff (reset指令)
循环查询NFSTAT位0,直到它等于1
3、NFCMD = 0 (读指令)
4、这步得略微留意一下,请翻开K9F1208U0M数据手册第7页,那个表格列出了在地址操作的4个进程对应的地址线,A8没用到:
NFADDR = addr & 0xff
NFADDR = (addr>>9) & 0xff (留意了,左移9位,不是8位)
NFADDR = (addr>>17) & 0xff (左移17位,不是16位)
NFADDR = (addr>>25) & 0xff (左移25位,不是24位)
5、循环查询NFSTAT位0,直到它等于1
6、连续读NFDATA寄存器512次,得到一页数据(512字节)
7、NFCONF |= 0x800 (制止NAND Flash)
UART
UART的寄存器有11X3个(3个UART)之多,我选最简略的办法来进行本试验,用到的寄存器也有8个。不过初始化就用去了5个寄存器,剩余的3个用于接纳、发送数据。
1、初始化:
a.把运用到的引脚GPH2、GPH3界说为TXD0、RXD0:
GPHCON |= 0xa0 GPHUP |= 0x0c (上拉)
b.ULCON0 ( UART channel 0 line control register ):设为0x03 此值意义为:8个数据位,1个中止位,无校验,正常操作形式(与之相对的是Infra-Red Mode,此形式标明0、1的办法比较特别)。
c.UCON0 (UART channel 0 control register ):设为0x05 除了位[3:0],其他位都运用默认值。位[3:0]=0b0101标明:发送、接纳都
运用“中止或查询办法”——本试验运用查询查询办法。
d.UFCON0 (UART channel 0 FIFO control register ):设为0x00 每个UART内部都有一个16字节的发送FIFO和接纳FIFO,可是本试验不运用FIFO,设为默认值0
e.UMCON0 (UART channel 0 Modem control register ):设为0x00 本试验不运用流控,设为默认值0
f.UBRDIV0 ( R/W Baud rate divisior register 0 ):设为12 本试验未运用PLL, PCLK=12MHz,设置波特率为57600,则由公式 UBRDIVn = (int)(PCLK / (bps x 16) ) –1 能够核算得UBRDIV0 = 12,请运用S3C2410数据手册第314页的差错公式验算一下此波特率是否在可容忍的差错规模之内,假如不在,则需求替换另一个波特率(本试验运用的 57600是契合的)。
void init_uart( )
{//初始化UART
GPHCON |= 0xa0; //GPH2,GPH3 used as TXD0,RXD0
GPHUP = 0x0c; //GPH2,GPH3内部上拉
ULCON0 = 0x03; //8N1(8个数据位,无校验位,1个中止位)
UCON0 = 0x05; //查询办法
UFCON0 = 0x00; //不运用FIFO
UMCON0 = 0x00; //不运用流控
UBRDIV0 = 12; //波特率为57600 10 }
2、发送数据:
a.UTRSTAT0 ( UART channel 0 Tx/Rx status register ):位[2]:无数据发送时,主动设为1。当咱们要运用串口发送数据时,先读此位以判别是否有数据正在占用发送口。位[1]:发送FIFO是否为空,本试验未用此位位[0]:接纳缓冲区是否有数据,若有,此位设为1。本试验中,需求不断查询此位一判别是否有数据现已被接纳。
b.UTXH0 (UART channel 0 transmit buffer register ): 把要发送的数据写入此寄存器。
void putc(unsigned char c)
{
while( ! (UTRSTAT0 & TXD0READY) ); //不断查询,直到能够发送数据
UTXH0 = c; //发送数据
}
3、接纳数据:
a.UTRSTAT0:好像上述“2、发送数据”所列,咱们用到位[0]
b.URXH0 (UART channel 0 receive buffer register ): 当查询到UTRSTAT0 位[0]=1时,读此寄存器取得串口接纳到的数据。
unsigned char getc( )
{
while( ! (UTRSTAT0 & RXD0READY) ); //不断查询,直到接纳到了数据
return URXH0; //回来接纳到的数据
}
Interrrupt
SUBSRCPND和SRCPND寄存器标明有哪些中止被触发了,正在等候处理(pending);
SUBMASK(INTSUBMSK寄存器)和MASK(INTMSK寄存器)用于屏蔽某些中止。
1、“Request sources(without sub -register)”中的中止源被触发之后,SRCPND寄存器中相应位被置1,假如此中止没有被INTMSK寄存器屏蔽、或许是快中止(FIQ)的话,它将被进一步处理
2、关于“Request sources(with sub -register)”中的中止源被触发之后,SUBSRCPND寄存器中的相应位被置1,假如此中止没有被INTSUBMSK寄存器屏蔽的话,它在 SRCPND寄存器中的相应位也被置1,之后的处理进程就和“Request sources(without sub -register)”相同了
请翻开S3C2410数据手册357页,“Figure 14-2. Priority Generating Block”显现了各中止源先通过6个一级优先级裁定器选出各自优先级最高的中止,然后再通过二级优先级裁定器选从中选出优先级最高的中止。IRQ的中止优先级由RIORITY寄存器设定,请参阅数据手册365页,RIORITY寄存器中ARB_SELn(n从0到6)用于设定裁定器n各输入信号的中止优先级,例如ARB_SEL6[20:19](0最高,这以后各项顺次下降):
00 = REQ 0-1-2-3-4-5 01 = REQ 0-2-3-4-1-5
10 = REQ 0-3-4-1-2-5 11 = REQ 0-4-1-2-3-5
RIORITY寄存器还有一项比较特别的功用,假如ARB_MODEn设为1,则裁定器n中输入的中止信号的优先等级将会轮换。例如ARB_MODE6设为1,则裁定器6的6个输入信号的优先级将如下轮换(见数据手册358页)
运用中止的进程:
1、当产生中止IRQ时,CPU进入“中止形式”,这时运用“中止形式”下的仓库;当产生快中止FIQ时,CPU进入“快中止形式”,这时运用“快中止形式”下的仓库。所以在运用中止前,先设置好相应形式下的仓库。
2、关于“Request sources(without sub -register)”中的中止,将INTSUBMSK寄存器中相应位设为0
3、将INTMSK寄存器中相应位设为0
4、确认运用此的办法:是FIQ仍是IRQ。
a.假如是FIQ,则在INTMOD寄存器设置相应位为1
b.假如是IRQ,则在RIORITY寄存器中设置优先级
运用中止的进程:
5、准备好中止处理函数,
a.中止向量: 在中止向量设置好当FIQ或IRQ被触发时的跳转函数, IRQ、FIQ的中止向量地址别离为0x00000018、0x0000001c
b.关于IRQ,在跳转函数中读取INTPND寄存器或INTOFFSET寄存器的值来确认中止源,然后调用详细的处理函数
c.关于FIQ,由于只要一个中止能够设为FIQ,无须判别中止源
d.中止处理函数进入和回来
6、设置CPSR寄存器中的F-bit(关于FIQ)或I-bit(关于IRQ)为0,开中止
运用中止的进程:
IRQ进入和回来
sub lr, lr, #4 @核算回来地址
stmdb sp!, { r0-r12,lr } @保存运用到的寄存器 ? ?
ldmia sp!, { r0-r12,pc }^ @中止回来 @^标明将spsr的值赋给cpsr
关于FIQ,进入和回来的代码如下:
sub lr, lr, #4 @核算回来地址
stmdb sp!, { r0-r7,lr } @保存运用到的寄存器 ? ?
ldmia sp!, { r0-r7,pc }^ @快中止回来, @^标明将spsr的值赋给cpsr
中止回来之前需求清中止:往SUBSRCPND(用到的话)、SRCPND、INTPND中相应位写1即可。关于INTPND,最简略的办法便是“INTPND=INTPND”
Timer几个重要寄存器介绍
1、TCFG0和TCFG1:别离设为119和0x03
这连个寄存器用于设置“Control Logic”的时钟,核算公式如下:
Timer input clock Frequency = PCLK / {prescaler value+1} / {divider value}
关于TIMER0,prescaler value = TCFG0[7:0],divider value由TCFG1[3:0]确认(0b000:2,0b001:4,0b010:8,0b0011:16,0b01xx:运用外部TCLK0)。
关于本试验,TIMER0时钟 = 12MHz/(119+1)/(16) = 6250Hz
2、TCNTB0:设为3125
在6250Hz的频率下,此值对应的时刻为0.5S
3、TCON:
TIMER0对应bit[3:0]:
bit[3]用于确认在TCNT0计数到0时,是否主动将TCMPB0和TCNTB0寄存器的值装入TCMP0和TCNT0寄存器中
bit[2]用于确认TOUT0是否回转输出(本试验未用)
bit[1]用于手动更新TCMP0和TCNT0寄存器:在第一次运用定时器前,此位需求设为1,此刻TCMPB0和TCNTB0寄存器的值装入TCMP0和TCNT0寄存器中
bit[0]用于发动TIMER0
4、TCONO0:只读寄存器,用于读取当时TCON0寄存器的值