#include
"
def.h
"
#include
"
option.h
"
#include
"
2440addr.h
"
#include
"
2440lib.h
"
#include
"
2440slib.h
"
#include
"
mmu.h
"
//
================================
extern
char
__ENTRY[];
//
void MMU_SetMTT(int vaddrStart,int vaddrEnd,int paddrStart,int attr);
//
void MMU_Init(void);
//
LCD*****************************************************
#define
M5D(n) ((n) & 0x1fffff)
//
用于设置显示缓存区时,取低21位地址
#define
LCD_WIDTH 240
//
屏幕的宽
#define
LCD_HEIGHT 320
//
屏幕的高
//
垂直同步信号的脉宽、后肩和前肩-----这些值是根据TopPoly-TD035STED4.pdf文件中的13页的表
#define
VSPW 1
//
(3-1)
#define
VBPD 1
//
(15-1)
#define
VFPD 1
//
(12-1)
//
水平同步信号的脉宽、后肩和前肩-----这些值是根据TopPoly-TD035STED4.pdf文件中的13页的表
#define
HSPW (10-1)
#define
HBPD (20-1)
#define
HFPD (10-1)
//
显示尺寸
#define
LINEVAL (LCD_HEIGHT-1)
#define
HOZVAL (LCD_WIDTH-1)
//
for LCDCON1
#define
CLKVAL_TFT 4
//
设置时钟信号
#define
MVAL_USED 0
//
#define
PNRMODE_TFT 3
//
TFT型LCD
#define
BPPMODE_TFT 13
//
24位TFT型LCD
//
for LCDCON5
#define
BPP24BL 0
//
32位数据表示24位颜色值时,低位数据有效,高8位无效
#define
INVVCLK 0
//
像素值在VCLK下降沿有效
#define
INVVLINE 1
//
翻转HSYNC信号
#define
INVVFRAME 1
//
翻转VSYNC信号
#define
INVVD 0
//
正常VD信号极性
#define
INVVDEN 0
//
正常VDEN信号极性
#define
PWREN 1
//
使能PWREN信号
#define
BSWP 0
//
颜色数据字节不交换
#define
HWSWP 0
//
颜色数据半字不交换
//
定义显示缓存区
volatile
unsigned
int
LCD_BUFFER[LCD_HEIGHT][LCD_WIDTH];
int
A,B,C,D,E,F,K;
volatile
int
xdata, ydata;
int
flagIIC;
//
IIC标志
int
flagTS;
//
触摸屏标志
//
lCD******************************************************
//
LCD显示函数
//////////////////////////////////////////////////
//
延时程序
void
delay(
int
a)
{
int
k;
for
(k
=
0
;k
<
a;k
++
) ;
}
//
绘制屏幕背景颜色,颜色为c
void
Brush_Background( unsigned
int
c)
{
int
x,y ;
for
( y
=
0
; y
<
LCD_HEIGHT ; y
++
)
{
for
( x
=
0
; x
<
LCD_WIDTH ; x
++
)
{
LCD_BUFFER[y][x]
=
c ;
}
}
}
//
绘制“十”字型
void
drawCross(unsigned
int
x,unsigned
int
y,unsigned
int
color)
{
int
i;
for
(i
=
x
-
10
;i
<
x
+
11
;i
++
)
LCD_BUFFER[y][i]
=
color;
for
(i
=
y
-
10
;i
<
y
+
11
;i
++
)
LCD_BUFFER[i][x]
=
color;
}
//
绘制正方形
void
drawsquare(unsigned
int
x,unsigned
int
y,unsigned
int
color)
{
int
i,j;
int
x1
=
x
-
2
;
int
y1
=
y
-
2
;
for
(i
=
y1;i
<
y
+
2
;i
++
)
{
for
(j
=
x1;j
<
x
+
2
;j
++
)
LCD_BUFFER[i][j]
=
color ;
}
}
//
绘制大小为8×16的ASCII码
void
Draw_ASCII(unsigned
int
x,unsigned
int
y,unsigned
int
color,
const
unsigned
char
*
ch)
{
unsigned
short
int
i,j;
unsigned
char
mask,buffer;
for
(i
=
0
;i
<
16
;i
++
)
{
mask
=
0x80
;
buffer
=
ch[i];
for
(j
=
0
;j
<
8
;j
++
)
{
if
(buffer
&
mask)
{
LCD_BUFFER[y
+
i][x
+
j]
=
color;
}
mask
=
mask
>>
1
;
}
}
}
void
init_port_lcd()
//
初始化
{
rGPCCON
=
0xaaaaaaaa
;
rGPCUP
=
0xffff
;
//
The pull up function is disabled GPC[15:0]
//
*** PORT D GROUP
//
Ports : GPD15 GPD14 GPD13 GPD12 GPD11 GPD10 GPD9 GPD8 GPD7 GPD6 GPD5 GPD4 GPD3 GPD2 GPD1 GPD0
//
Signal : VD23 VD22 VD21 VD20 VD19 VD18 VD17 VD16 VD15 VD14 VD13 VD12 VD11 VD10 VD9 VD8
//
Binary : 10 10 , 10 10 , 10 10 , 10 10 , 10 10 , 10 10 , 10 10 ,10 10
rGPDCON
=
0xaaaaaaaa
;
rGPDUP
=
0xffff
;
rLCDCON1
=
(CLKVAL_TFT
<<
8
)
|
(MVAL_USED
<<
7
)
|
(PNRMODE_TFT
<<
5
)
|
(BPPMODE_TFT
<<
1
)
|
0
;
rLCDCON2
=
(VBPD
<<
24
)
|
(LINEVAL
<<
14
)
|
(VFPD
<<
6
)
|
(VSPW);
rLCDCON3
=
(HBPD
<<
19
)
|
(HOZVAL
<<
8
)
|
(HFPD);
rLCDCON4
=
(HSPW);
//
//
rLCDCON4 = (5<< 0);
rLCDCON5
=
(BPP24BL
<<
12
)
|
(INVVCLK
<<
10
)
|
(INVVLINE
<<
9
)
|
(INVVFRAME
<<
8
)
|
(
0
<<
7
)
|
(INVVDEN
<<
6
)
|
(PWREN
<<
3
)
|
(BSWP
<<
1
)
|
(HWSWP);
rLCDSADDR1
=
(((unsigned
int
)LCD_BUFFER
>>
22
)
<<
21
)
|
M5D((unsigned
int
)LCD_BUFFER
>>
1
);
rLCDSADDR2
=
M5D( (M5D((unsigned
int
)LCD_BUFFER
>>
1
)
+
((LCD_WIDTH
*
32
/
16
+
0
)
*
320
)) );
//
LCD_WIDTH*LCD_HEIGHT*4
rLCDSADDR3
=
(LCD_WIDTH
*
32
/
16
)
&
0x7ff
;
//
参考s3c2440的手册
rLCDINTMSK
|=
(
3
);
//
屏蔽LCD中断
//
rTCONSEL = 0;
//
无效LPC3480
rTCONSEL
&=
(
~
7
);
rTPAL
=
0x0
;
rTCONSEL
&=
~
((
1
<<
4
)
|
1
);
rGPGUP
=
rGPGUP
&
(
~
(
1
<<
4
))
|
(
1
<<
4
);
//
GPG4上拉电阻无效
rGPGCON
=
rGPGCON
&
(
~
(
3
<<
8
))
|
(
3
<<
8
);
//
设置GPG4为LCD_PWREN
rGPGDAT
=
rGPGDAT
|
(
1
<<
4
);
//
GPG4置1
rLCDCON5
=
rLCDCON5
&
(
~
(
1
<<
3
))
|
(
1
<<
3
);
//
有效PWREN信号
rLCDCON5
=
rLCDCON5
&
(
~
(
1
<<
5
))
|
(
0
<<
5
);
//
PWREN信号极性不翻转
rLCDCON1
|=
1
;
//
LCD开启
}
//
LCD显示函数
//////////////////////////////////////////////////
void
__irq ADCTs(
void
)
{
rADCTSC
=
(
1
<<
3
)
|
(
1
<<
2
);
//
上拉电阻无效,自动连续XY坐标转换模式开启
rADCDLY
=
40000
;
//
延时
rADCCON
|=
0x1
;
//
开始A/D转换
while
(rADCCON
&
0x1
);
//
检查A/D转换是否开始
while
(
!
(rADCCON
&
0x8000
));
//
等待A/D转换的结束
while
(
!
(rSRCPND
&
((unsigned
int
)
0x1
<<
31
)));
//
判断A/D中断的悬挂位
xdata
=
(rADCDAT0
&
0x3ff
);
//
读取X轴坐标
ydata
=
(rADCDAT1
&
0x3ff
);
//
读取Y轴坐标
flagTS
=
1
;
//
置标志
rSUBSRCPND
|=
0x1
<<
9
;
rSRCPND
=
0x1
<<
31
;
rINTPND
=
0x1
<<
31
;
rINTSUBMSK
=~
(
0x1
<<
9
);
rINTMSK
=~
(
0x1
<<
31
);
//
清A/D中断,开启A/D中断屏蔽
rADCTSC
=
0xd3
;
//
再次设置等待中断模式,这一次是判断触笔的抬起
rADCTSC
=
rADCTSC
|
(
1
<<
8
);
//
设置触笔抬起中断
while
(
1
)
//
等待触笔的抬起
{
if
(rSUBSRCPND
&
(
0x1
<<
9
))
//
检查A/D触摸屏中断悬挂
{
break
;
//
如果触笔抬起,则跳出该循环
}
}
rADCDLY
=
50000
;
rSUBSRCPND
|=
0x1
<<
9
;
//
写1清除标志
rINTSUBMSK
=~
(
0x1
<<
9
);
//
清0中断使能,ADC的子中断
rSRCPND
=
0x1
<<
31
;
//
写1清除标志
rINTPND
=
0x1
<<
31
;
//
再次清A/D中断,开启A/D中断屏蔽
rADCTSC
=
0xd3
;
//
设置等待光标按下中断模式,为下一次触笔的落下做准备
//
01101 0011--
//
XP_PU, XP_Dis, XM_Dis, YP_Dis, YM_En.
}
const
unsigned
char
one[]
=
{
0x00
,
0x00
,
0x00
,
0x10
,
0x70
,
0x10
,
0x10
,
0x10
,
0x10
,
0x10
,
0x10
,
0x10
,
0x10
,
0x7C
,
0x00
,
0x00
};
const
unsigned
char
two[]
=
{
0x00
,
0x00
,
0x00
,
0x3C
,
0x42
,
0x42
,
0x42
,
0x04
,
0x04
,
0x08
,
0x10
,
0x20
,
0x42
,
0x7E
,
0x00
,
0x00
};
const
unsigned
char
three[]
=
{
0x00
,
0x00
,
0x00
,
0x3C
,
0x42
,
0x42
,
0x04
,
0x18
,
0x04
,
0x02
,
0x02
,
0x42
,
0x44
,
0x38
,
0x00
,
0x00
};
//
用PCtoLCD2002字符生成软件
//
触摸屏校正
void
TSCal(
void
)
{
int
i
=
0
;
int
xt[
3
],yt[
3
];
Brush_Background(
0xFFFFFF
);
drawCross(
24
,
32
,
0xFF0000
);
Draw_ASCII(
28
,
36
,
0xFF0000
,one);
//
----
drawCross(
216
,
160
,
0xFF0000
);
Draw_ASCII(
220
,
164
,
0xFF0000
,two);
//
----
drawCross(
120
,
288
,
0xFF0000
);
Draw_ASCII(
124
,
292
,
0xFF0000
,three);
//
----
//
依次读取三个采样点的坐标值
for
(i
=
0
;i
<
3
;i
++
)
{
while
(flagTS
==
0
)
delay(
500
);
xt[i]
=
xdata;
yt[i]
=
ydata;
flagTS
=
0
;
}
//
计算参数
K
=
(xt[
0
]
-
xt[
2
])
*
(yt[
1
]
-
yt[
2
])
-
(xt[
1
]
-
xt[
2
])
*
(yt[
0
]
-
yt[
2
]);
D
=
(
32
-
288
)
*
(yt[
1
]
-
yt[
2
])
-
(
160
-
288
)
*
(yt[
0
]
-
yt[
2
]);
E
=
(xt[
0
]
-
xt[
2
])
*
(
160
-
288
)
-
(
32
-
288
)
*
(xt[
1
]
-
xt[
2
]);
F
=
yt[
0
]
*
(xt[
2
]
*
160
-
xt[
1
]
*
288
)
+
yt[
1
]
*
(xt[
0
]
*
288
-
xt[
2
]
*
32
)
+
yt[
2
]
*
(xt[
1
]
*
32
-
xt[
0
]
*
160
);
A
=
(
24
-
120
)
*
(yt[
1
]
-
yt[
2
])
-
(
216
-
120
)
*
(yt[
0
]
-
yt[
2
]);
B
=
(xt[
0
]
-
xt[
2
])
*
(
216
-
120
)
-
(
24
-
120
)
*
(xt[
1
]
-
xt[
2
]);
C
=
yt[
0
]
*
(xt[
2
]
*
216
-
xt[
1
]
*
120
)
+
yt[
1
]
*
(xt[
0
]
*
120
-
xt[
2
]
*
24
)
+
yt[
2
]
*
(xt[
1
]
*
24
-
xt[
0
]
*
216
);
}
int
Main(
int
argc,
char
**
argv)
{
int
i;
unsigned
char
key;
unsigned
int
mpll_val
=
0
;
int
data;
int
xLcd,yLcd;
mpll_val
=
(
92
<<
12
)
|
(
1
<<
4
)
|
(
1
);
//
init FCLK=400M, so change MPLL first
ChangeMPllValue((mpll_val
>>
12
)
&
0xff
, (mpll_val
>>
4
)
&
0x3f
, mpll_val
&
3
);
ChangeClockDivider(key,
12
);
rINTMOD
=
0x0
;
//
All=IRQ mode
rINTMSK
=
BIT_ALLMSK;
//
All interrupt is masked.
MMU_Init();
init_port_lcd();
//
*********************
rADCDLY
=
50000
;
//
设置延时
rADCCON
=
(
1
<<
14
)
+
(
9
<<
6
);
//
设置A/D预分频
rADCTSC
=
0xd3
;
//
设置cm屏为等待中断模式。
pISR_ADC
=
(
int
)ADCTs;
rINTMSK
=~
(
0x1
<<
31
);
//
开启中断
rINTSUBMSK
=~
(BIT_SUB_TC);
flagTS
=
0
;
//
*********************
TSCal();
//
校正
delay(
200000
);
Brush_Background(
0xFFFFFF
);
while
(
1
)
{
if
(flagTS)
{
flagTS
=
0
;
xLcd
=
(A
*
xdata
+
B
*
ydata
+
C)
/
K;
//
计算Y轴坐标
yLcd
=
(D
*
xdata
+
E
*
ydata
+
F)
/
K;
//
计算X轴坐标
drawsquare(xLcd,yLcd,
0xFF0000
);
//
绘制正方形
}
delay(
1000000
);
}
return
0
;
}
//
-------------------------------------------------------------------------------------------
//
-------------------------------------------------------------------------------------------
void
MMU_Init(
void
)
//
配置MMU
{
int
i,j;
MMU_DisableDCache();
MMU_DisableICache();
for
(i
=
0
;i
<
64
;i
++
)
for
(j
=
0
;j
<
8
;j
++
)
MMU_CleanInvalidateDCacheIndex((i
<<
26
)
|
(j
<<
5
));
MMU_InvalidateICache();
MMU_DisableMMU();
MMU_InvalidateTLB();
MMU_SetMTT(
0x00000000
,
0x03f00000
,
0x30000000
,RW_CB);
//
bank0 __ENTRY的地址就是0x30000000
MMU_SetMTT(
0x04000000
,
0x07f00000
,
0
,RW_NCNB);
//
bank0
MMU_SetMTT(
0x08000000
,
0x0ff00000
,
0x08000000
,RW_CNB);
//
bank1
MMU_SetMTT(
0x10000000
,
0x17f00000
,
0x10000000
,RW_NCNB);
//
bank2
MMU_SetMTT(
0x18000000
,
0x1ff00000
,
0x18000000
,RW_NCNB);
//
bank3
//
MMU_SetMTT(0x20000000,0x27f00000,0x20000000,RW_CB);
//
bank4
MMU_SetMTT(
0x20000000
,
0x27f00000
,
0x20000000
,RW_CNB);
//
bank4 for STRATA Flash
MMU_SetMTT(
0x28000000
,
0x2ff00000
,
0x28000000
,RW_NCNB);
//
bank5
//
30f00000->30100000, 31000000->30200000
MMU_SetMTT(
0x30000000
,
0x30100000
,
0x30000000
,RW_CB);
//
bank6-1
MMU_SetMTT(
0x30200000
,
0x33e00000
,
0x30200000
,RW_NCNB);
//
bank6-2
//
MMU_SetMTT(
0x33f00000
,
0x33f00000
,
0x33f00000
,RW_CB);
//
bank6-3
MMU_SetMTT(
0x38000000
,
0x3ff00000
,
0x38000000
,RW_NCNB);
//
bank7
MMU_SetMTT(
0x40000000
,
0x47f00000
,
0x40000000
,RW_NCNB);
//
SFR
MMU_SetMTT(
0x48000000
,
0x5af00000
,
0x48000000
,RW_NCNB);
//
SFR
MMU_SetMTT(
0x5b000000
,
0x5b000000
,
0x5b000000
,RW_NCNB);
//
SFR
MMU_SetMTT(
0x5b100000
,
0xfff00000
,
0x5b100000
,RW_FAULT);
//
not used
MMU_SetTTBase(_MMUTT_STARTADDRESS);
//
写转换表基地址到C2
MMU_SetDomain(
0x55555550
|
DOMAIN1_ATTR
|
DOMAIN0_ATTR);
//
写域访问控制位到C3
//
DOMAIN1: no_access, DOMAIN0,2~15=client(AP is checked)
MMU_SetProcessId(
0x0
);
MMU_EnableAlignFault();
MMU_EnableMMU();
//
使能MMU
MMU_EnableICache();
//
使能ICache
MMU_EnableDCache();
//
DCache 必须要打开,当MMU打开时. DCache should be turned on after MMU is turned on.
}
//
vaddrStart:虚拟起始地址
//
vaddrEnd: 虚拟结束地址
//
paddrStart:物理起始地址
//
attr:访问属性
void
MMU_SetMTT(
int
vaddrStart,
int
vaddrEnd,
int
paddrStart,
int
attr)
{
volatile
unsigned
int
*
pTT;
//
定义了页表的指针
volatile
int
i,nSec;
pTT
=
(unsigned
int
*
)_MMUTT_STARTADDRESS
+
(vaddrStart
>>
20
);
//
由于内存块是1M的,写页表的基地址
nSec
=
(vaddrEnd
>>
20
)
-
(vaddrStart
>>
20
);
//
计数有多少个段(每个段为1M)
for
(i
=
0
;i
<=
nSec;i
++
)
*
pTT
++=
attr
|
(((paddrStart
>>
20
)
+
i)
<<
20
);
//
页表存储访问信息和存储块的基地址
//
(((paddrStart>>20)+i)<<20) :对应的物理内存页的地址
//
attr:访问权限和缓冲属性
}