标题: SDRAM操作代码分析 [打印本页] 作者: grand 时间: 2021-11-26 13:28 标题: SDRAM操作代码分析 本帖最后由 grand 于 2021-11-26 15:54 编辑 ( c8 c+ j3 {2 S8 G
6 k( d% [( v; Y" {不多说先放代码:# A' m0 T/ G" o8 D* {1 R! U
3 @$ b, k% X8 g6 |4 k! L9 \' \5 @9 S' P( J
<span style="font-size:18px;"><span style="font-size:14px;">#include <csl.h> & E* _' f3 r- ^- w O8 r: u#include <csl_pll.h> " }( T/ v! m3 U2 k#include <csl_emif.h> ( \* o. k2 \+ |- y% \4 o#include <csl_chip.h>$ Z- F/ \: i3 N( S5 o+ M; v- _" O
#include <stdio.h> * q+ H* Y5 B- _* g% s5 x {; M( M+ w5 P, Y7 FUint16 x;$ d8 ^! G% n% j' h- ?
Uint32 y; : W7 R5 U3 S1 b6 ]! P$ [CSLBool b; 0 ?* J" h Q1 E6 @; ?1 f( i6 T! Bunsigned int datacount = 0;3 y: D% u Z3 ?1 M. G7 o
int databuffer[1000] ={0}; $ v" j' j% ~" I" ~- Q" \int *souraddr,*deminaddr; 6 f. j' \+ ]. \" z4 ~0 M+ h/*锁相环的设置*/ ' H; v# g, T& D \" a& tPLL_Config myConfig = {+ ]( i) D- n. G8 Z: g; P& X
0, //IAI: the PLL locks using the same process that was underway # g0 y4 E, H( P1 e1 j, h
//before the idle mode was entered \! T; M! e6 N8 a3 i
1, //IOB: If the PLL indicates a break in the phase lock, ' u" z m- R- b //it switches to its bypass mode and restarts the PLL phase-locking 7 Z+ O' p3 {4 ?1 N* k //sequence ; F# j3 I: H$ h- q6 y3 R 20, //PLL multiply value; multiply 20 times, H/ e; o) }; K/ z0 G0 B! Y" x
1 //Divide by 2 PLL divide value; it can be either PLL divide value 2 R; V6 e0 p9 Q
//(when PLL is enabled), or Bypass-mode divide value . c% F5 l7 \/ W //(PLL in bypass mode, if PLL multiply value is set to 1)3 L5 ^. L8 @# h$ B& y5 F
}; s. B+ w- A) V" J& R9 c
/*SDRAM的EMIF设置*/ / `1 j1 G6 Y' W4 C$ tEMIF_Config emiffig = {0 |1 [+ ]$ Q3 J- w
0x0021, //EGCR : the MEMFREQ = 00,the clock for the memory is equal to cpu frequence % u1 Q2 b8 Z0 C% o7 R( l- O // the WPE = 0 ,forbiden the writing posting when we debug the EMIF ' q( v! D+ S, v // the MEMCEN = 1,the memory clock is reflected on the CLKMEM pin & y) e/ N+ k+ e/ r& m* x. | // the NOHOLD = 1,HOLD requests are not recognized by the EMIF T# X7 E. K9 {& t" g 0xFFFF, //EMI_RST: any write to this register resets the EMIF state machine3 H( I9 A W. e9 v6 @6 p
0x3FFF, //CE0_1: CE0 space control register 13 x3 N m, {& A
// MTYPE = 011,Synchronous DRAM(SDRAM),16-bit data bus width/ o9 p6 I6 ~. }, c! z% `2 L( X
0xFFFF, //CE0_2: CE0 space control register 2 ; T8 |% h% u, Z% T 0x00FF, //CE0_3: CE0 space control register 3* J s4 E7 P9 M L0 ?" r
// TIMEOUT = 0xFF; % z/ [' i( K2 ]5 ~& c1 J# o# y t 0x7FFF, //CE1_1: CE0 space control register 1$ ]7 z* t9 H- G0 h; t: O
0xFFFF, //CE1_2: CE0 space control register 2: b: C9 i0 t7 d# z' v
0x00FF, //CE1_3: CE0 space control register 30 k h% q1 z! M5 t/ l/ H$ n
# q: r6 W5 D/ G- l
0x7FFF, //CE2_1: CE0 space control register 19 O) {. N' f3 n1 o# }! l. K( V2 F: y
0xFFFF, //CE2_2: CE0 space control register 2 : [5 Y- \7 Z, b. T: n8 P 0x00FF, //CE2_3: CE0 space control register 3 ; u. B, `9 M, ^6 u5 L, E6 h/ T # ]5 w* D! S$ }' d 0x7FFF, //CE3_1: CE0 space control register 1 + Q1 {! s! p. S1 l2 z' d' Q 0xFFFF, //CE3_2: CE0 space control register 24 ^& L6 Z. e2 h( n8 i
0x00FF, //CE3_3: CE0 space control register 3- b! H7 E7 _& [# q; q/ H3 f
7 b; s* ~/ {! \" E, W+ ?; \
0x2922, //SDC1: SDRAM control register 1! `6 ~# L4 e- N0 G+ x/ _
// TRC = 8 : L& b5 z) A4 _. _- } O // SDSIZE = 0;SDWID = 0 M8 ~5 l( k5 I" o2 P // RFEN = 1 + G$ S% E. D; s# w# h, g+ ] // TRCD = 2* i w! k2 a& x1 _. _; d
// TRP = 2 " g# x7 P( k2 e% d$ O 0x0410, //SDPER : SDRAM period register: G4 I' Q/ |- N9 r0 m2 C3 p
// 7ns *4096 ; Y3 _) |' P4 J- z 0x07FF, //SDINIT: SDRAM initialization register ( l6 t1 t$ }8 a) s* n4 p+ M+ | // any write to this register to init the all CE spaces, $ f; o8 s. I: B3 p, P( \6 F5 |. c // do it after hardware reset or power up the C55x device# a$ ^2 F. d2 Q
0x0131 //SDC2: SDRAM control register 2- f) K! w. j2 N% O
// SDACC = 0;( y P, T- P4 o$ f7 t
// TMRD = 01;0 h; G% {2 d2 e) S; w
// TRAS = 0101; : z) T% H* s4 b& x! t4 K // TACTV2ACTV = 0001; 2 E; i: Q# a- Z: l. p };1 L* ?* n! {7 r$ f( P( G D
& w4 m2 F7 ?" ^" k' Y. B( J
g7 H( Q5 \3 F) ?, e$ X
main()# X+ c G Q B& E& _6 [
{ ! X3 S0 t0 U: B8 l7 |3 P unsigned int error=0;) ]) N: z D; V4 x( \
/*初始化CSL库*/ 0 @4 B4 V. p/ Z; w& Z6 o/ [
CSL_init(); ) q$ q0 C1 ~( \4 b, c$ } : m- I" |! U: f6 I* L& f8 {
/*EMIF为全EMIF接口*/ $ q8 h) o9 N+ ^- `5 ? CHIP_RSET(XBSR,0x0a01);5 g( K `% X5 m4 t0 O% z" X7 p/ y
! @- s7 M* v& e. V
/*设置系统的运行速度为120MHz*/2 y6 ^7 J4 ]6 z/ t* W& \$ Y5 D
PLL_config(&myConfig); 0 i( g: o# b% w , p( n/ j6 N% k. _( R0 E. \# a4 x2 k- x3 G& a
/*初始化DSP的外部SDRAM*/- _) I; a8 U- D( y5 u3 o
EMIF_config(&emiffig);) d4 \! l& U' r+ W
/*向SDRAM中写入数据*/ ( I3 I% Q8 k3 I& u- {+ L) B 6 ]! _- f7 b5 n) D souraddr = (int *)0x40000; * ?; v9 s/ z3 Z, i0 a# ^! a deminaddr = (int *)0x41000;4 P9 o+ o) E h5 }+ R4 b8 C, l) I
while(souraddr<deminaddr)0 L: i$ @$ Q, a3 T- g; B( A& k
{9 T5 J4 s5 A* f" J( W
*souraddr++ = datacount; ; l+ ]2 b4 C* O4 C5 L datacount++ ;. J# o0 t& c9 w H9 o' _8 l4 z
} $ d [: f* i9 w( d /*读出SDRAM中的数据*/ / v! N% _: M8 h9 U souraddr = (int *)0x40000; 8 Z" @7 n) s) {, _8 H# s datacount = 0; + |( i6 S- }3 G6 w. r+ T$ D while(souraddr<deminaddr)6 U N \' ^, G0 H
{ - t) R0 R; c h# s databuffer[datacount++] = *souraddr++; $ ^1 R1 x& ^3 ]& w3 V( @% \0 ^' g if(databuffer[datacount-1]!=(datacount-1)) 9 n0 r3 x3 t; s error++;; j- N! y% Q# ?* C* ?& a
}& h* ~+ x1 p+ H2 L! u1 c
4 w1 S* g1 T: `0 x3 v" W
while(1); 6 f8 B% M4 P: ^. M: z& r/ R5 j} 6 }$ O7 Y7 A+ V( e/*************************</span></span># Y2 l# a& D1 B- | [, C
下面分部分分析: 7 Q5 ^9 T! o7 x1 I* T: D锁相环的设置:PLL_Config结构体是在csl_pllA.H中定义的* q ?' {9 [$ H+ ` k5 b# @/ }3 B
, I2 p0 D+ L( p' I3 }* r$ r( g% l& t
PLL锁相环的配置寄存器Clock Mode Register (CLKMD)的各位的详细描述 在5509A的datasheet里是没有的, u, M; ]* {3 Q + s' w$ L* {, i在overview_spru317f.pdf里有详细介绍,想要的发评论留下方式我发给你。 $ O Z, w/ i1 R2 M$ V) P8 S& l* K! m7 {/ m$ p+ q/ H; K! {' [
IAI:Initialize after idle bit.IAI=0表示The PLL locks using the same process that was underwaybefore the idle 1 ?1 \: r7 E n9 T9 z
. T0 V# e; ]! S% J% t& ^mode was entered。5 y) g* r* @& s$ p8 G0 t9 c/ c, H9 z
7 u" m+ F' `& Z3 O Y
翻译过来大致就是在进入空闲模式之前PLL lock使用相同的方式。' {# Z, p0 K. i% d! ~
7 r3 Y; X9 |- p
IOB:Initialize on break bit. IOB=1:时钟发生器选择它的旁路模式并且重启锁相序列。" D6 \: J ?% r. O7 `8 _% ?
PLL MULT:pll倍频位。pllmult=20,输入时钟频率倍频20倍 5 m! i, e2 p6 A& F% V) oPLL DIVLL分频位。plldiv=1,输入频率分频28 I% V2 D. D! j7 _ p7 p
我的开发板外接频率是12MHZ,倍频20,再分频2以后系统时钟频率就是12*20/2=120MHZ。 $ Q4 D6 ?5 X- KSDRMA的EMIF设置:0 c4 O Z) h' z1 C% ]" ~; O! M
EMIF_Config结构体在csl_emifA.h中定义3 y$ q* @; \3 x/ {; k
2 a9 t6 h/ R/ K1 j9 E
' q8 s% _3 b% }+ v; f
结构体里每个参数都是寄存器的名字,每个寄存器的具体描述在datasheetemif_spru670.pdf中, # ~, N2 V: k& l# Q+ Q. v! K+ f6 {, [$ ]7 I3 t2 p. @, q0 X4 c
在5509A的datasheet中并没有具体的描述,只有寄存器的memory map。 1 o) }2 c6 j5 G0 M1 O9 E I5 r# z4 Z- q8 B, A9 G
5509A的外扩内存映射被分成4个CE片选空间,每个空间可以扩展4Mx16,5 C; B' L% o5 ~- R$ L) Z) d
# V( e4 z% s" y v$ x) _/ d$ lEMIF Global Control Register (EGCR):MEMFREQ的9-11位是000,CLKMEM的频率就等于 # a% k2 @' a) ?9 f b Z5 L$ w' S7 M- A - U: H2 N/ U' [- U; k0 kcpu的时钟频率(120mhz), ( n" D* [' v2 g% [9 s0 v0 \: Z - e' C. G8 o5 c: ~+ `, R. D8 ]但是对于5509A芯片来说,如果MEMFREQ=000b,SDRAM控制寄存器3的DIV1位必须设置为1, ) a/ W, t' y7 l3 b1 N' e( o4 c# ~' b) w7 F* h$ w! z
但是结构体中并没有定义SDC3(SDRAM Control Register 3 ),晚上回实验室再补上SDC3的定义试试,应该可以通过。 6 g) F' R3 L3 ~3 q : ?' E+ }! G( @4 v- JEMIF Global Reset Register (EMIRST):用默认的0xFFFF就行。 5 N( d: ~; g! n3 u * f+ e Y( Y0 n- y% e" VCE Space Control Registers (CEn1, CEn2, and CEn3 in Each CE Space):外部的内存memory map 9 L* o9 b( t0 ]; X( M* r8 ?
被分成4个CE空间, ; ^0 ~% h6 B s6 Q; x* P每个CE空间都3个CE控制寄存器, 2 z: ~' B( q1 Q) J分别是CEn1, CEn2, and CEn3 ,n是表示的4个CE空间,CE0空间寄存器就是CE01,CE02,CE03,以此类推。 k% `' h4 H+ f3 e y1 W我的开发板外接的SDRAM是4MX16的,4M是内存大小,16是数据位宽D0-D15,所以CE0的片选空间被完全占用,! o9 S3 M9 c/ A; {& s* y
只用到了CE0的3个寄存器,其他3个CE空间不适用,也是将CEn1寄存器的MTYPE位设置为0x7FFF(只要MTYPE不是00,01,10,11,认识数值都可以,具体描述看手册)。其他的寄存器数值配置按默认的就可以。 ( E, @5 F! d! a2 M" X7 s! H* L/ o, D- e$ H; C$ {: _8 Y
* |9 R6 B# r+ y' T9 L
SDRAM寄存器配置: / B l8 S& ~4 t8 ^ s! uSDRAM Control Registers 1 and 2 (SDC1 and SDC2):SDRAM控制寄存器主要就是配置SDRAM的时序,: e( o, l L) k$ u6 j& S
这要结合SDRAM的厂家提供的时序资料来配置。 ' K& L* o6 w9 `( K$ _* `3 m % n. t7 }( c+ c, q9 x 4 K, C, B6 ?: U; ^3 E
这里就举一个例子,其他的类似。+ C, C8 y8 D; E6 ~
SDC1=0x2911,TRP[3:0]=0010,; y% G0 W& w: ~. y$ y; ]7 q( z
TRP = (tRP/CLKMEM) − 1: 9 M y5 p. u7 q4 o! r" E' j查看SDRAM的厂家datasheet,查tTP的参考数值,发现,tRP最小值是20ns,CLKMEM的时钟频率就是前面设置的120MHZ,周期t=1/120MHZ=8ns,.tRP=24ns。$ ]9 c* F9 \& Q/ o+ K+ x2 l M