天天看點

s3c2440學習筆記(上)-基于FL2440

學習ARM有一段時間了,現在做一個記錄裸機程式,再網上看到了趙老師講2440裸機程式的部落格,寫的很好,建議和我一樣的初學者能好好的學習一下趙老師的部落格,網址:http://blog.csdn.net/zhaocj/article/details/6118860,真心不錯!給趙老師做一下廣告,哈哈 ^_^

1  2440啟動檔案分析

由于啟動檔案無法仿真,可以再要判斷的語句的地方加上一段點亮led小燈程式

ResetHandler ;系統上電或複位後,由0x0處的跳轉指令,跳轉到該處開始真正執行系統的初始化工作

2  2440外部中斷

2440的外部中斷引腳EINT與通用IO引腳F和G複用,要想使用中斷功能,就要把相應的引腳配置成中斷模式,如我們想把端口F0設定成外部中斷,而其他引腳功能不變,則GPFCON=(GPFCON & ~0x3) | 0x2。配置完引腳後,還需要配置具體的中斷功能。我們要打開某一中斷的屏蔽,這樣才能響應該中斷,相對應的寄存器為INTMSK;還要設定外部中斷的觸發方式,如低電平、高電平、上升沿、下降沿等,相對應的寄存器為EXTINTn。另外由于EINT4到EINT7共用一個中斷向量,EINT8到EINT23也共用一個中斷向量,而INTMSK隻負責總的中斷向量的屏蔽,要具體打開某一具體的中斷屏蔽,還需要設定EINTMASK。

SRCPND和INTPND

S3C2440A有兩個中斷挂起寄存器:源挂起寄存器(SRCPND)和中斷挂起寄存器(INTPND)。這些挂起寄存器表明一個中斷請求是否為挂起。當中斷源請求中斷服務,SRCPND寄存器的相應位被置位為1,并且同時在仲裁步驟後INTPND 寄存器僅有1位自動置位為1。如果屏蔽了中斷,則SRCPND寄存器的相應位被置位為1。這并不會引起INTPND 寄存器的位的改變。當INTPND 寄存器的挂起位為置位,每當I 标志或F标志被清除為0中斷服務程式将開始。SRCPND和INTPND寄存器可以被讀取和寫入,是以服務程式必須首先通過寫1到SRCPND寄存器的相應位來清除挂起狀态并且通過相同方法來清除INTPND寄存器中挂起狀态

3  2440的PWM應用

s3c2440晶片中一共有5個16位的定時器,其中有4個定時器(定時器0~定時器3)具有脈寬調制功能,是以用s3c2440可以很容易地實作PWM功能。下面就具體介紹如何實作PWM功能。

1、PWM是通過引腳TOUT0~TOUT3輸出的,而這4個引腳是與GPB0~GPB3複用的,是以要實作PWM功能首先要把相應的引腳配置成TOUT輸出。

2、再設定定時器的輸出時鐘頻率,它是以PCLK為基準,再除以用寄存器TCFG0配置的prescaler參數,和用寄存器TCFG1配置的divider參數。

3、然後設定脈沖的具體寬度,它的基本原理是通過寄存器TCNTBn來對寄存器TCNTn(内部寄存器)進行配置計數,TCNTn是遞減的,如果減到零,則它又會重新裝載TCNTBn裡的數,重新開始計數,而寄存器TCMPBn作為比較寄存器與計數值進行比較,當TCNTn等于TCMPBn時,TOUTn輸出的電平會翻轉,而當TCNTn減為零時,電平會又翻轉過來,就這樣周而複始。是以這一步的關鍵是設定寄存器TCNTBn和TCMPBn,前者可以确定一個計數周期的時間長度,而後者可以确定方波的占空比。由于s3c2440的定時器具有雙緩存,是以可以在定時器運作的狀态下,改變這兩個寄存器的值,它會在下個周期開始有效。

4、最後就是對PWM的控制,它是通過寄存器TCON來實作的,一般來說每個定時器主要有4個位要配置(定時器0多一個死區位):啟動/終止位,用于啟動和終止定時器;手動更新位,用于手動更新TCNTBn和TCMPBn,這裡要注意的是在開始定時時,一定要把這位清零,否則是不能開啟定時器的;輸出反轉位,用于改變輸出的電平方向,使原先是高電平輸出的變為低電平,而低電平的變為高電平;自動重載位,用于TCNTn減為零後重載TCNTBn裡的值,當不想計數了,可以使自動重載無效,這樣在TCNTn減為零後,不會有新的數加載給它,那麼TOUTn輸出會始終保持一個電平(輸出反轉位為0時,是高電平輸出;輸出反轉位為1時,是低電平輸出),這樣就沒有PWM功能了,是以這一位可以用于停止PWM。

TCFG0 = 0xFFFF00;

TCFG0 |= 0x31; //低8為時鐘的分頻數

TCFG1 &= ~0xF; //1/2,PCLK=50MHz,所有50MHz/25/2=500KHz

TCNTB0 = 5000;

TCMPB0 = freq;

TCON &= ~0x1F;

TCON |= 0xF;  //死區無效,自動裝載,電平反轉,手動更新,定時器開啟

TCON &= ~0x2; //手動更新位清零,PWM開始工作

4  2440的PWM應用

在s3c2440中,有2個不同的PLL,一個是MPLL,另一個是UPLL。UPLL是給USB提供48MHz。在這裡,我們主要介紹MPLL。外部時鐘源經過MPLL處理後能夠得到三個不同的系統時鐘:FCLK、HCLK和PCLK。FCLK是主頻時鐘,用于ARM920T核心;HCLK用于AHB總線裝置,如ARM920T,記憶體控制,中斷控制,LCD控制,DMA以及USB主子產品;PCLK用于APB總線裝置,如外圍裝置的看門狗,IIS,I2C,PWM,MMC接口,ADC,UART,GPIO,RTC以及SPI。這三個系統時鐘(FCLK、HCLK和PCLK)是有一定的比例關系,這種關系是通過寄存器CLKDIVN中的HDIVN位和PDIVN位來控制的,是以我們隻要知道了FCLK,再通過這兩位的控制,就能确定HCLK和PCLK。而FCLK是如何得到的呢?它是通過輸入時鐘(即外部時鐘源)的頻率,經過一個計算公式(具體公式請查閱資料手冊)得到的,這個計算公式還需要三個參數(MDIV、PDIV、SDIV),而這三個參數是經過寄存器MPLLCON配置得到的。最後,我們用最清晰的線路來繪制一下時鐘的産生過程:外部時鐘源→通過寄存器MPLLCON得到FCLK→再通過寄存器CLKDIVN得到HCLK和PCLK。這個配置過程在啟動檔案中就已完成。

TCFG0 :定時器配置寄存器0,配置2個8位預分頻器

[23:16] :死區長度

[16:8] :precsaler1,決定定時器2,3,4預分頻值

[7:0] :prescaler0,決定定時器0,1的預分頻值

5  2440的UART應用

s3c2440提供了三個UART端口,它們都可以通過查詢、中斷和DMA方式傳輸資料,而且每個UART都分别有一個64個位元組的接收FIFO和一個64個位元組的發送FIFO。

要實作某種通信,就必須遵循該通信協定。UART的協定包括傳輸資料的位數,停止位的位數,以及是否進行奇偶校驗,這些設定是利用ULCONn寄存器完成的。另一個很重要的地方就是設定波特率。s3c2440波特率的時鐘源有三個:PCLK、FCLK/n和UEXTCLK。時鐘源的選擇是由UCONn的第10位和第11位來完成的。波特率的具體計算公式為:

時鐘源頻率÷(波特率×16)-1

RS-232C标準采用的是負邏輯方式,邏輯1對用-15到-5V,邏輯0對應5到15V

S3C2440A 的 UART(通用異步串行接口)單元提供了三個獨立的異步串行 I/O 端口,每個

都可以在中斷和 DMA 兩種模式下進行,他們支援的最高波特率是 115.2Kbps。每個 UART 通道包含 2 個 64 位元組 FIFO 分别提供個接收和發送。

GPH7  [15:14]  00 = 輸入  01 = 輸出  10 = RXD[2]  11 = nCTS1

GPH6  [13:12]  00 = 輸入  01 = 輸出  10 = TXD[2]  11 = nRTS1

GPH5  [11:10]  00 = 輸入  01 = 輸出  10 = RXD[1]  11 = 保留

GPH4  [9:8]    00 = 輸入  01 = 輸出  10 = TXD[1]  11 = 保留

GPH3  [7:6]    00 = 輸入  01 = 輸出  10 = RXD[0]  11 = 保留

GPH2  [5:4]    00 = 輸入  01 = 輸出  10 = TXD[0]  11 = 保留 

6  2440的NAND Flash應用

NAND Flash引導啟動模式中必須選擇GPG[15:13]為輸入。

當複位時,NAND  Flash控制器将通過引腳狀态(NCON(先進閃存),  GPG13(頁大小),GPG14(位址周期),GPG15(總線寬度)—請參考引腳配置)來擷取連接配接的NAND Flash的資訊,在發生掉電或系統複位後,NAND Flash控制器自動加載4K位元組的BootLoader代碼。在加載完BootLoader代碼後,Steppingstone中的BootLoader代碼已經執行了

D[7:0] : 資料/指令/位址/的輸入/輸出口(與資料總線共享)

CLE : 指令鎖存使能 (輸出)

ALE : 位址鎖存使能(輸出)

nFCE : NAND Flash 片選使能(輸出)

nFRE : NAND Flash 讀使能 (輸出)

nFWE : NAND Flash 寫使能 (輸出)

R/nB : NAND Flash 準備好/繁忙(輸入)

//-------------- s3c2440的頭檔案 ----------------------------

/***********************************************************************/
/*  This file is part of the uVision/ARM development tools             */
/*  Copyright KEIL - An ARM Company 2002-2007                          */
/***********************************************************************/
/*                                                                     */
/*  S3C2440.H:  Header file for Samsung S3C2440                        */
/*                                                                     */
/***********************************************************************/


#ifndef __S3C2440_H
#define __S3C2440_H


// Memory Controllers 
#define BWSCON               (*(volatile unsigned long *) 0x48000000)
#define BANKCON0             (*(volatile unsigned long *) 0x48000004)
#define BANKCON1             (*(volatile unsigned long *) 0x48000008)
#define BANKCON2             (*(volatile unsigned long *) 0x4800000C)
#define BANKCON3             (*(volatile unsigned long *) 0x48000010)
#define BANKCON4             (*(volatile unsigned long *) 0x48000014)
#define BANKCON5             (*(volatile unsigned long *) 0x48000018)
#define BANKCON6             (*(volatile unsigned long *) 0x4800001C)
#define BANKCON7             (*(volatile unsigned long *) 0x48000020)
#define REFRESH              (*(volatile unsigned long *) 0x48000024)
#define BANKSIZE             (*(volatile unsigned long *) 0x48000028)
#define MRSRB6               (*(volatile unsigned long *) 0x4800002C)
#define MRSRB7               (*(volatile unsigned long *) 0x48000030)


// USB Host Controller
#define HcRevision           (*(volatile unsigned long *) 0x49000000)
#define HcControl            (*(volatile unsigned long *) 0x49000004)
#define HcCommonStatus       (*(volatile unsigned long *) 0x49000008)
#define HcInterruptStatus    (*(volatile unsigned long *) 0x4900000C)
#define HcInterruptEnable    (*(volatile unsigned long *) 0x49000010)
#define HcInterruptDisable   (*(volatile unsigned long *) 0x49000014)
#define HcHCCA               (*(volatile unsigned long *) 0x49000018)
#define HcPeriodCuttentED    (*(volatile unsigned long *) 0x4900001C)
#define HcControlHeadED      (*(volatile unsigned long *) 0x49000020)
#define HcControlCurrentED   (*(volatile unsigned long *) 0x49000024)
#define HcBulkHeadED         (*(volatile unsigned long *) 0x49000028)
#define HcBulkCurrentED      (*(volatile unsigned long *) 0x4900002C)
#define HcDoneHead           (*(volatile unsigned long *) 0x49000030)
#define HcRmInterval         (*(volatile unsigned long *) 0x49000034)
#define HcFmRemaining        (*(volatile unsigned long *) 0x49000038)
#define HcFmNumber           (*(volatile unsigned long *) 0x4900003C)
#define HcPeriodicStart      (*(volatile unsigned long *) 0x49000040)
#define HcLSTreshold         (*(volatile unsigned long *) 0x49000044)
#define HcRhDescriptorA      (*(volatile unsigned long *) 0x49000048)
#define HcRhDescriptorB      (*(volatile unsigned long *) 0x4900004C)
#define HcRhStatus           (*(volatile unsigned long *) 0x49000050)
#define HcRhPortStatus1      (*(volatile unsigned long *) 0x49000054)
#define HcRhPortStatus2      (*(volatile unsigned long *) 0x49000058)


// Interrupt Controller
#define SRCPND               (*(volatile unsigned long *) 0x4A000000)
#define INTMOD               (*(volatile unsigned long *) 0x4A000004)
#define INTMSK               (*(volatile unsigned long *) 0x4A000008)
#define PRIORITY             (*(volatile unsigned long *) 0x4A00000C)
#define INTPND               (*(volatile unsigned long *) 0x4A000010)
#define INTOFFSET            (*(volatile unsigned long *) 0x4A000014)
#define SUBSRCPND            (*(volatile unsigned long *) 0x4A000018)
#define INTSUBMSK            (*(volatile unsigned long *) 0x4A00001C)


// DMA
#define DISRC0               (*(volatile unsigned long *) 0x4B000000)
#define DISRCC0              (*(volatile unsigned long *) 0x4B000004)
#define DIDST0               (*(volatile unsigned long *) 0x4B000008)
#define DIDSTC0              (*(volatile unsigned long *) 0x4B00000C)
#define DCON0                (*(volatile unsigned long *) 0x4B000010)
#define DSTAT0               (*(volatile unsigned long *) 0x4B000014)
#define DCSRC0               (*(volatile unsigned long *) 0x4B000018)
#define DCDST0               (*(volatile unsigned long *) 0x4B00001C)
#define DMASKTRIG0           (*(volatile unsigned long *) 0x4B000020)


#define DISRC1               (*(volatile unsigned long *) 0x4B000040)
#define DISRCC1              (*(volatile unsigned long *) 0x4B000044)
#define DIDST1               (*(volatile unsigned long *) 0x4B000048)
#define DIDSTC1              (*(volatile unsigned long *) 0x4B00004C)
#define DCON1                (*(volatile unsigned long *) 0x4B000050)
#define DSTAT1               (*(volatile unsigned long *) 0x4B000054)
#define DCSRC1               (*(volatile unsigned long *) 0x4B000058)
#define DCDST1               (*(volatile unsigned long *) 0x4B00005C)
#define DMASKTRIG1           (*(volatile unsigned long *) 0x4B000060)


#define DISRC2               (*(volatile unsigned long *) 0x4B000080)
#define DISRCC2              (*(volatile unsigned long *) 0x4B000084)
#define DIDST2               (*(volatile unsigned long *) 0x4B000088)
#define DIDSTC2              (*(volatile unsigned long *) 0x4B00008C)
#define DCON2                (*(volatile unsigned long *) 0x4B000090)
#define DSTAT2               (*(volatile unsigned long *) 0x4B000094)
#define DCSRC2               (*(volatile unsigned long *) 0x4B000098)
#define DCDST2               (*(volatile unsigned long *) 0x4B00009C)
#define DMASKTRIG2           (*(volatile unsigned long *) 0x4B0000a0)


#define DISRC3               (*(volatile unsigned long *) 0x4B0000C0)
#define DISRCC3              (*(volatile unsigned long *) 0x4B0000C4)
#define DIDST3               (*(volatile unsigned long *) 0x4B0000C8)
#define DIDSTC3              (*(volatile unsigned long *) 0x4B0000CC)
#define DCON3                (*(volatile unsigned long *) 0x4B0000D0)
#define DSTAT3               (*(volatile unsigned long *) 0x4B0000D4)
#define DCSRC3               (*(volatile unsigned long *) 0x4B0000D8)
#define DCDST3               (*(volatile unsigned long *) 0x4B0000DC)
#define DMASKTRIG3           (*(volatile unsigned long *) 0x4B0000E0)


// Clock & Power Management
#define LOCKTIME             (*(volatile unsigned long *) 0x4C000000)
#define MPLLCON              (*(volatile unsigned long *) 0x4C000004)
#define UPLLCON              (*(volatile unsigned long *) 0x4C000008)
#define CLKCON               (*(volatile unsigned long *) 0x4C00000C)
#define CLKSLOW              (*(volatile unsigned long *) 0x4C000010)
#define CLKDIVN              (*(volatile unsigned long *) 0x4C000014)
#define CAMDIVN              (*(volatile unsigned long *) 0x4C000018)


// LCD Controller
#define LCDCON1              (*(volatile unsigned long *) 0x4D000000)
#define LCDCON2              (*(volatile unsigned long *) 0x4D000004)
#define LCDCON3              (*(volatile unsigned long *) 0x4D000008)
#define LCDCON4              (*(volatile unsigned long *) 0x4D00000C)
#define LCDCON5              (*(volatile unsigned long *) 0x4D000010)
#define LCDSADDR1            (*(volatile unsigned long *) 0x4D000014)
#define LCDSADDR2            (*(volatile unsigned long *) 0x4D000018)
#define LCDSADDR3            (*(volatile unsigned long *) 0x4D00001C)
#define REDLUT               (*(volatile unsigned long *) 0x4D000020)
#define GREENLUT             (*(volatile unsigned long *) 0x4D000024)
#define BLUELUT              (*(volatile unsigned long *) 0x4D000028)
#define DITHMODE             (*(volatile unsigned long *) 0x4D00004C)
#define TPAL                 (*(volatile unsigned long *) 0x4D000050)
#define LCDINTPND            (*(volatile unsigned long *) 0x4D000054)
#define LCDSRCPND            (*(volatile unsigned long *) 0x4D000058)
#define LCDINTMSK            (*(volatile unsigned long *) 0x4D00005C)
#define LPCSEL               (*(volatile unsigned long *) 0x4D000060)
#define PALETTE               0x4D000400


// NAND flash
#define NFCONF               (*(volatile unsigned long *) 0x4E000000)
#define NFCONT               (*(volatile unsigned long *) 0x4E000004)
#define NFCMD                (*(volatile unsigned long *) 0x4E000008)
#define NFADDR               (*(volatile unsigned long *) 0x4E00000C)
#define NFDATA               (*(volatile unsigned long *) 0x4E000010)
#define NFMECCD0             (*(volatile unsigned long *) 0x4E000014)
#define NFMECCD1             (*(volatile unsigned long *) 0x4E000018)
#define NFSECCD              (*(volatile unsigned long *) 0x4E00001C)
#define NFSTAT               (*(volatile unsigned long *) 0x4E000020)
#define NFESTAT0             (*(volatile unsigned long *) 0x4E000024)
#define NFESTAT1             (*(volatile unsigned long *) 0x4E000028)
#define NFMECC0              (*(volatile unsigned long *) 0x4E00002C)
#define NFMECC1              (*(volatile unsigned long *) 0x4E000030)
#define NFSECC               (*(volatile unsigned long *) 0x4E000034)
#define NFSBLK               (*(volatile unsigned long *) 0x4E000038)
#define NFEBLK               (*(volatile unsigned long *) 0x4E00003C)


// Camera Interface
#define CISRCFMT             (*(volatile unsigned long *) 0x4F000000)
#define CIWDOFST             (*(volatile unsigned long *) 0x4F000004)
#define CIGCTRL              (*(volatile unsigned long *) 0x4F000008)
#define CICOYSA1             (*(volatile unsigned long *) 0x4F000018)
#define CICOYSA2             (*(volatile unsigned long *) 0x4F00001C)
#define CICOYSA3             (*(volatile unsigned long *) 0x4F000020)
#define CICOYSA4             (*(volatile unsigned long *) 0x4F000024)
#define CICOCBSA1            (*(volatile unsigned long *) 0x4F000028)
#define CICOCBSA2            (*(volatile unsigned long *) 0x4F00002C)
#define CICOCBSA3            (*(volatile unsigned long *) 0x4F000030)
#define CICOCBSA4            (*(volatile unsigned long *) 0x4F000034)
#define CICORSA1             (*(volatile unsigned long *) 0x4F000038)
#define CICORSA2             (*(volatile unsigned long *) 0x4F00003C)
#define CICORSA3             (*(volatile unsigned long *) 0x4F000040)
#define CICORSA4             (*(volatile unsigned long *) 0x4F000044)
#define CICOTRGFMT           (*(volatile unsigned long *) 0x4F000048)
#define CICOCTRL             (*(volatile unsigned long *) 0x4F00004C)
#define CICOSCPRERATIO       (*(volatile unsigned long *) 0x4F000050)
#define CICOSCPREDST         (*(volatile unsigned long *) 0x4F000054)
#define CICOSCCTRL           (*(volatile unsigned long *) 0x4F000058)
#define CICOTAREA            (*(volatile unsigned long *) 0x4F00005C)
#define CICOSTATUS           (*(volatile unsigned long *) 0x4F000064)
#define CIPRCLRSA1           (*(volatile unsigned long *) 0x4F00006C)
#define CIPRCLRSA2           (*(volatile unsigned long *) 0x4F000070)
#define CIPRCLRSA3           (*(volatile unsigned long *) 0x4F000074)
#define CIPRCLRSA4           (*(volatile unsigned long *) 0x4F000078)
#define CIPRTRGFMT           (*(volatile unsigned long *) 0x4F00007C)
#define CIPRCTRL             (*(volatile unsigned long *) 0x4F000080)
#define CIPRSCPRERATIO       (*(volatile unsigned long *) 0x4F000084)
#define CIPRSCPREDST         (*(volatile unsigned long *) 0x4F000088)
#define CIPRSCCTRL           (*(volatile unsigned long *) 0x4F00008C)
#define CIPRTAREA            (*(volatile unsigned long *) 0x4F000090)
#define CIPRSTATUS           (*(volatile unsigned long *) 0x4F000098)
#define CIIMGCPT             (*(volatile unsigned long *) 0x4F0000A0)




// UART
#define ULCON0               (*(volatile unsigned long *) 0x50000000)
#define UCON0                (*(volatile unsigned long *) 0x50000004)
#define UFCON0               (*(volatile unsigned long *) 0x50000008)
#define UMCON0               (*(volatile unsigned long *) 0x5000000C)
#define UTRSTAT0             (*(volatile unsigned long *) 0x50000010)
#define UERSTAT0             (*(volatile unsigned long *) 0x50000014)
#define UFSTAT0              (*(volatile unsigned long *) 0x50000018)
#define UMSTAT0              (*(volatile unsigned long *) 0x5000001C)
#define UTXH0                (*(volatile unsigned char *) 0x50000020)
#define URXH0                (*(volatile unsigned char *) 0x50000024)
#define UBRDIV0              (*(volatile unsigned long *) 0x50000028)


#define ULCON1               (*(volatile unsigned long *) 0x50004000)
#define UCON1                (*(volatile unsigned long *) 0x50004004)
#define UFCON1               (*(volatile unsigned long *) 0x50004008)
#define UMCON1               (*(volatile unsigned long *) 0x5000400C)
#define UTRSTAT1             (*(volatile unsigned long *) 0x50004010)
#define UERSTAT1             (*(volatile unsigned long *) 0x50004014)
#define UFSTAT1              (*(volatile unsigned long *) 0x50004018)
#define UMSTAT1              (*(volatile unsigned long *) 0x5000401C)
#define UTXH1                (*(volatile unsigned char *) 0x50004020)
#define URXH1                (*(volatile unsigned char *) 0x50004024)
#define UBRDIV1              (*(volatile unsigned long *) 0x50004028)


#define ULCON2               (*(volatile unsigned long *) 0x50008000)
#define UCON2                (*(volatile unsigned long *) 0x50008004)
#define UFCON2               (*(volatile unsigned long *) 0x50008008)
#define UMCON2               (*(volatile unsigned long *) 0x5000800C)
#define UTRSTAT2             (*(volatile unsigned long *) 0x50008010)
#define UERSTAT2             (*(volatile unsigned long *) 0x50008014)
#define UFSTAT2              (*(volatile unsigned long *) 0x50008018)
#define UTXH2                (*(volatile unsigned char *) 0x50008020)
#define URXH2                (*(volatile unsigned char *) 0x50008024)
#define UBRDIV2              (*(volatile unsigned long *) 0x50008028)


#ifdef __BIG_ENDIAN
#undef  UTXH0
#define UTXH0                (*(volatile unsigned char *) 0x50000023)
#undef  URXH0
#define URXH0                (*(volatile unsigned char *) 0x50000027)
#undef  UTXH1
#define UTXH1                (*(volatile unsigned char *) 0x50004023)
#undef  URXH1
#define URXH1                (*(volatile unsigned char *) 0x50004027)
#undef  UTXH2
#define UTXH2                (*(volatile unsigned char *) 0x50008023)
#undef  URXH2
#define URXH2                (*(volatile unsigned char *) 0x50008027)
#endif


// PWM Timer
#define TCFG0                (*(volatile unsigned long *) 0x51000000)
#define TCFG1                (*(volatile unsigned long *) 0x51000004)
#define TCON                 (*(volatile unsigned long *) 0x51000008)
#define TCNTB0               (*(volatile unsigned long *) 0x5100000C)
#define TCMPB0               (*(volatile unsigned long *) 0x51000010)
#define TCNTO0               (*(volatile unsigned long *) 0x51000014)
#define TCNTB1               (*(volatile unsigned long *) 0x51000018)
#define TCMPB1               (*(volatile unsigned long *) 0x5100001C)
#define TCNTO1               (*(volatile unsigned long *) 0x51000020)
#define TCNTB2               (*(volatile unsigned long *) 0x51000024)
#define TCMPB2               (*(volatile unsigned long *) 0x51000028)
#define TCNTO2               (*(volatile unsigned long *) 0x5100002C)
#define TCNTB3               (*(volatile unsigned long *) 0x51000030)
#define TCMPB3               (*(volatile unsigned long *) 0x51000034)
#define TCNTO3               (*(volatile unsigned long *) 0x51000038)
#define TCNTB4               (*(volatile unsigned long *) 0x5100003C)
#define TCNTO4               (*(volatile unsigned long *) 0x51000040)




// USB Device
#ifdef  __BIG_ENDIAN
#define FUNC_ADDR_REG        (*(volatile unsigned char *) 0x52000143)
#define PWR_REG              (*(volatile unsigned char *) 0x52000147)
#define EP_INT_REG           (*(volatile unsigned char *) 0x5200014B)
#define USB_INT_REG          (*(volatile unsigned char *) 0x5200015B)
#define EP_INT_EN_REG        (*(volatile unsigned char *) 0x5200015F)
#define USB_INT_EN_REG       (*(volatile unsigned char *) 0x5200016F)
#define FRAME_NUM1_REG       (*(volatile unsigned char *) 0x52000173)
#define FRAME_NUM2_REG       (*(volatile unsigned char *) 0x52000177)
#define INDEX_REG            (*(volatile unsigned char *) 0x5200017B)
#define MAXP_REG             (*(volatile unsigned char *) 0x52000183)
#define EP0_CSR              (*(volatile unsigned char *) 0x52000187)
#define IN_CSR1_REG          (*(volatile unsigned char *) 0x52000187)
#define IN_CSR2_REG          (*(volatile unsigned char *) 0x5200018B)
#define OUT_CSR1_REG         (*(volatile unsigned char *) 0x52000193)
#define OUT_CSR2_REG         (*(volatile unsigned char *) 0x52000197)
#define OUT_FIFO_CNT1_REG    (*(volatile unsigned char *) 0x5200019B)
#define OUT_FIFO_CNT2_REG    (*(volatile unsigned char *) 0x5200019F)
#define EP0_FIFO             (*(volatile unsigned char *) 0x520001C3)
#define EP1_FIFO             (*(volatile unsigned char *) 0x520001C7)
#define EP2_FIFO             (*(volatile unsigned char *) 0x520001CF)
#define EP3_FIFO             (*(volatile unsigned char *) 0x520001CF)
#define EP4_FIFO             (*(volatile unsigned char *) 0x520001D3)
#define EP1_DMA_CON          (*(volatile unsigned char *) 0x52000203)
#define EP1_DMA_UNIT         (*(volatile unsigned char *) 0x52000207)
#define EP1_DMA_FIFO         (*(volatile unsigned char *) 0x5200020B)
#define EP1_DMA_TTC_L        (*(volatile unsigned char *) 0x5200020F)
#define EP1_DMA_TTC_M        (*(volatile unsigned char *) 0x52000213)
#define EP1_DMA_TTC_H        (*(volatile unsigned char *) 0x52000217)
#define EP2_DMA_CON          (*(volatile unsigned char *) 0x5200021B)
#define EP2_DMA_UNIT         (*(volatile unsigned char *) 0x5200021F)
#define EP2_DMA_FIFO         (*(volatile unsigned char *) 0x52000223)
#define EP2_DMA_TTC_L        (*(volatile unsigned char *) 0x52000227)
#define EP2_DMA_TTC_M        (*(volatile unsigned char *) 0x5200022B)
#define EP2_DMA_TTC_H        (*(volatile unsigned char *) 0x5200022F)
#define EP3_DMA_CON          (*(volatile unsigned char *) 0x52000243)
#define EP3_DMA_UNIT         (*(volatile unsigned char *) 0x52000247)
#define EP3_DMA_FIFO         (*(volatile unsigned char *) 0x5200024B)
#define EP3_DMA_TTC_L        (*(volatile unsigned char *) 0x5200024F)
#define EP3_DMA_TTC_M        (*(volatile unsigned char *) 0x52000253)
#define EP3_DMA_TTC_H        (*(volatile unsigned char *) 0x52000257)
#define EP4_DMA_CON          (*(volatile unsigned char *) 0x5200025B)
#define EP4_DMA_UNIT         (*(volatile unsigned char *) 0x5200025F)
#define EP4_DMA_FIFO         (*(volatile unsigned char *) 0x52000263)
#define EP4_DMA_TTC_L        (*(volatile unsigned char *) 0x52000267)
#define EP4_DMA_TTC_M        (*(volatile unsigned char *) 0x5200026B)
#define EP4_DMA_TTC_H        (*(volatile unsigned char *) 0x5200026F)


#else   // Little Endian
#define FUNC_ADDR_REG        (*(volatile unsigned char *) 0x52000140)
#define PWR_REG              (*(volatile unsigned char *) 0x52000144)
#define EP_INT_REG           (*(volatile unsigned char *) 0x52000148)
#define USB_INT_REG          (*(volatile unsigned char *) 0x52000158)
#define EP_INT_EN_REG        (*(volatile unsigned char *) 0x5200015C)
#define USB_INT_EN_REG       (*(volatile unsigned char *) 0x5200016C)
#define FRAME_NUM1_REG       (*(volatile unsigned char *) 0x52000170)
#define FRAME_NUM2_REG       (*(volatile unsigned char *) 0x52000174)
#define INDEX_REG            (*(volatile unsigned char *) 0x52000178)
#define MAXP_REG             (*(volatile unsigned char *) 0x52000180)
#define EP0_CSR              (*(volatile unsigned char *) 0x52000184)
#define IN_CSR1_REG          (*(volatile unsigned char *) 0x52000184)
#define IN_CSR2_REG          (*(volatile unsigned char *) 0x52000188)
#define OUT_CSR1_REG         (*(volatile unsigned char *) 0x52000190)
#define OUT_CSR2_REG         (*(volatile unsigned char *) 0x52000194)
#define OUT_FIFO_CNT1_REG    (*(volatile unsigned char *) 0x52000198)
#define OUT_FIFO_CNT2_REG    (*(volatile unsigned char *) 0x5200019C)
#define EP0_FIFO             (*(volatile unsigned char *) 0x520001C0)
#define EP1_FIFO             (*(volatile unsigned char *) 0x520001C4)
#define EP2_FIFO             (*(volatile unsigned char *) 0x520001C8)
#define EP3_FIFO             (*(volatile unsigned char *) 0x520001CC)
#define EP4_FIFO             (*(volatile unsigned char *) 0x520001D0)
#define EP1_DMA_CON          (*(volatile unsigned char *) 0x52000200)
#define EP1_DMA_UNIT         (*(volatile unsigned char *) 0x52000204)
#define EP1_DMA_FIFO         (*(volatile unsigned char *) 0x52000208)
#define EP1_DMA_TTC_L        (*(volatile unsigned char *) 0x5200020C)
#define EP1_DMA_TTC_M        (*(volatile unsigned char *) 0x52000210)
#define EP1_DMA_TTC_H        (*(volatile unsigned char *) 0x52000214)
#define EP2_DMA_CON          (*(volatile unsigned char *) 0x52000218)
#define EP2_DMA_UNIT         (*(volatile unsigned char *) 0x5200021C)
#define EP2_DMA_FIFO         (*(volatile unsigned char *) 0x52000220)
#define EP2_DMA_TTC_L        (*(volatile unsigned char *) 0x52000224)
#define EP2_DMA_TTC_M        (*(volatile unsigned char *) 0x52000228)
#define EP2_DMA_TTC_H        (*(volatile unsigned char *) 0x5200022C)
#define EP3_DMA_CON          (*(volatile unsigned char *) 0x52000240)
#define EP3_DMA_UNIT         (*(volatile unsigned char *) 0x52000244)
#define EP3_DMA_FIFO         (*(volatile unsigned char *) 0x52000248)
#define EP3_DMA_TTC_L        (*(volatile unsigned char *) 0x5200024C)
#define EP3_DMA_TTC_M        (*(volatile unsigned char *) 0x52000250)
#define EP3_DMA_TTC_H        (*(volatile unsigned char *) 0x52000254)
#define EP4_DMA_CON          (*(volatile unsigned char *) 0x52000258)
#define EP4_DMA_UNIT         (*(volatile unsigned char *) 0x5200025C)
#define EP4_DMA_FIFO         (*(volatile unsigned char *) 0x52000260)
#define EP4_DMA_TTC_L        (*(volatile unsigned char *) 0x52000264)
#define EP4_DMA_TTC_M        (*(volatile unsigned char *) 0x52000268)
#define EP4_DMA_TTC_H        (*(volatile unsigned char *) 0x5200026C)
#endif


// Watchdog Timer
#define WTCON                (*(volatile unsigned long *) 0x53000000)
#define WTDAT                (*(volatile unsigned long *) 0x53000004)
#define WTCNT                (*(volatile unsigned long *) 0x53000008)


// IIC
#define IICCON               (*(volatile unsigned long *) 0x54000000)
#define IICSTAT              (*(volatile unsigned long *) 0x54000004)
#define IICADD               (*(volatile unsigned long *) 0x54000008)
#define IICDS                (*(volatile unsigned long *) 0x5400000C)
#define IICLC                (*(volatile unsigned long *) 0x54000010)


// IIS
#define IISCON               (*(volatile unsigned long *) 0x55000000)
#define IISMOD               (*(volatile unsigned long *) 0x55000004)
#define IISPSR               (*(volatile unsigned long *) 0x55000008)
#define IISFCON              (*(volatile unsigned long *) 0x5500000C)
#define IISFIFO              (*(volatile unsigned short*) 0x55000010)


#ifdef __BIG_ENDIAN
#undef  IISFIFO
#define IISFIFO              (*(volatile unsigned short*) 0x55000012)
#endif


// I/O port 
#define GPACON               (*(volatile unsigned long *) 0x56000000)
#define GPADAT               (*(volatile unsigned long *) 0x56000004)
                       
#define GPBCON               (*(volatile unsigned long *) 0x56000010)
#define GPBDAT               (*(volatile unsigned long *) 0x56000014)
#define GPBUP                (*(volatile unsigned long *) 0x56000018)
                       
#define GPCCON               (*(volatile unsigned long *) 0x56000020)
#define GPCDAT               (*(volatile unsigned long *) 0x56000024)
#define GPCUP                (*(volatile unsigned long *) 0x56000028)
                       
#define GPDCON               (*(volatile unsigned long *) 0x56000030)
#define GPDDAT               (*(volatile unsigned long *) 0x56000034)
#define GPDUP                (*(volatile unsigned long *) 0x56000038)
                       
#define GPECON               (*(volatile unsigned long *) 0x56000040)
#define GPEDAT               (*(volatile unsigned long *) 0x56000044)
#define GPEUP                (*(volatile unsigned long *) 0x56000048)
                       
#define GPFCON               (*(volatile unsigned long *) 0x56000050)
#define GPFDAT               (*(volatile unsigned long *) 0x56000054)
#define GPFUP                (*(volatile unsigned long *) 0x56000058)
                       
#define GPGCON               (*(volatile unsigned long *) 0x56000060)
#define GPGDAT               (*(volatile unsigned long *) 0x56000064)
#define GPGUP                (*(volatile unsigned long *) 0x56000068)
                       
#define GPHCON               (*(volatile unsigned long *) 0x56000070)
#define GPHDAT               (*(volatile unsigned long *) 0x56000074)
#define GPHUP                (*(volatile unsigned long *) 0x56000078)


#define GPJCON               (*(volatile unsigned long *) 0x560000D0)
#define GPJDAT               (*(volatile unsigned long *) 0x560000D4)
#define GPJUP                (*(volatile unsigned long *) 0x560000D8)
                       
#define MISCCR               (*(volatile unsigned long *) 0x56000080)
#define DCLKCON              (*(volatile unsigned long *) 0x56000084)
#define EXTINT0              (*(volatile unsigned long *) 0x56000088)
#define EXTINT1              (*(volatile unsigned long *) 0x5600008C)
#define EXTINT2              (*(volatile unsigned long *) 0x56000090)
#define EINTFLT0             (*(volatile unsigned long *) 0x56000094)
#define EINTFLT1             (*(volatile unsigned long *) 0x56000098)
#define EINTFLT2             (*(volatile unsigned long *) 0x5600009C)
#define EINTFLT3             (*(volatile unsigned long *) 0x560000A0)
#define EINTMASK             (*(volatile unsigned long *) 0x560000A4)
#define EINTPEND             (*(volatile unsigned long *) 0x560000A8)
#define GSTATUS0             (*(volatile unsigned long *) 0x560000AC)
#define GSTATUS1             (*(volatile unsigned long *) 0x560000B0)
#define GSTATUS2             (*(volatile unsigned long *) 0x560000B4)
#define GSTATUS3             (*(volatile unsigned long *) 0x560000B8)
#define GSTATUS4             (*(volatile unsigned long *) 0x560000BC)
#define MSLCON               (*(volatile unsigned long *) 0x560000CC)


// RTC
#ifdef  __BIG_ENDIAN
#define RTCCON               (*(volatile unsigned char *) 0x57000043)
#define TICNT                (*(volatile unsigned char *) 0x57000047)
#define RTCALM               (*(volatile unsigned char *) 0x57000053)
#define ALMSEC               (*(volatile unsigned char *) 0x57000057)
#define ALMMIN               (*(volatile unsigned char *) 0x5700005B)
#define ALMHOUR              (*(volatile unsigned char *) 0x5700005F)
#define ALMDATE              (*(volatile unsigned char *) 0x57000063)
#define ALMMON               (*(volatile unsigned char *) 0x57000067)
#define ALMYEAR              (*(volatile unsigned char *) 0x5700006B)
#define RTCRST               (*(volatile unsigned char *) 0x5700006F)
#define BCDSEC               (*(volatile unsigned char *) 0x57000073)
#define BCDMIN               (*(volatile unsigned char *) 0x57000077)
#define BCDHOUR              (*(volatile unsigned char *) 0x5700007B)
#define BCDDATE              (*(volatile unsigned char *) 0x5700007F)
#define BCDDAY               (*(volatile unsigned char *) 0x57000083)
#define BCDMON               (*(volatile unsigned char *) 0x57000087)
#define BCDYEAR              (*(volatile unsigned char *) 0x5700008B)


#else   //Little Endian
#define RTCCON               (*(volatile unsigned char *) 0x57000040)
#define TICNT                (*(volatile unsigned char *) 0x57000044)
#define RTCALM               (*(volatile unsigned char *) 0x57000050)
#define ALMSEC               (*(volatile unsigned char *) 0x57000054)
#define ALMMIN               (*(volatile unsigned char *) 0x57000058)
#define ALMHOUR              (*(volatile unsigned char *) 0x5700005C)
#define ALMDATE              (*(volatile unsigned char *) 0x57000060)
#define ALMMON               (*(volatile unsigned char *) 0x57000064)
#define ALMYEAR              (*(volatile unsigned char *) 0x57000068)
#define RTCRST               (*(volatile unsigned char *) 0x5700006C)
#define BCDSEC               (*(volatile unsigned char *) 0x57000070)
#define BCDMIN               (*(volatile unsigned char *) 0x57000074)
#define BCDHOUR              (*(volatile unsigned char *) 0x57000078)
#define BCDDATE              (*(volatile unsigned char *) 0x5700007C)
#define BCDDAY               (*(volatile unsigned char *) 0x57000080)
#define BCDMON               (*(volatile unsigned char *) 0x57000084)
#define BCDYEAR              (*(volatile unsigned char *) 0x57000088)
#endif


// A/D Converter
#define ADCCON               (*(volatile unsigned long *) 0x58000000)
#define ADCTSC               (*(volatile unsigned long *) 0x58000004)
#define ADCDLY               (*(volatile unsigned long *) 0x58000008)
#define ADCDAT0              (*(volatile unsigned long *) 0x5800000C)
#define ADCDAT1              (*(volatile unsigned long *) 0x58000010)
#define ADCUPDN              (*(volatile unsigned long *) 0x58000014)          
                       
// SPI         
#define SPCON0               (*(volatile unsigned long *) 0x59000000)
#define SPSTA0               (*(volatile unsigned long *) 0x59000004)
#define SPPIN0               (*(volatile unsigned long *) 0x59000008)
#define SPPRE0               (*(volatile unsigned long *) 0x5900000C)
#define SPTDAT0              (*(volatile unsigned long *) 0x59000010)
#define SPRDAT0              (*(volatile unsigned long *) 0x59000014)


#define SPCON1               (*(volatile unsigned long *) 0x59000020)
#define SPSTA1               (*(volatile unsigned long *) 0x59000024)
#define SPPIN1               (*(volatile unsigned long *) 0x59000028)
#define SPPRE1               (*(volatile unsigned long *) 0x5900002C)
#define SPTDAT1              (*(volatile unsigned long *) 0x59000030)
#define SPRDAT1              (*(volatile unsigned long *) 0x59000034)


// SD Interface
#define SDICON               (*(volatile unsigned long *) 0x5A000000)
#define SDIPRE               (*(volatile unsigned long *) 0x5A000004)
#define SDICARG              (*(volatile unsigned long *) 0x5A000008)
#define SDICCON              (*(volatile unsigned long *) 0x5A00000C)
#define SDICSTA              (*(volatile unsigned long *) 0x5A000010)
#define SDIRSP0              (*(volatile unsigned long *) 0x5A000014)
#define SDIRSP1              (*(volatile unsigned long *) 0x5A000018)
#define SDIRSP2              (*(volatile unsigned long *) 0x5A00001C)
#define SDIRSP3              (*(volatile unsigned long *) 0x5A000020)
#define SDIDTIMER            (*(volatile unsigned long *) 0x5A000024)
#define SDIBSIZE             (*(volatile unsigned long *) 0x5A000028)
#define SDIDCON              (*(volatile unsigned long *) 0x5A00002C)
#define SDIDCNT              (*(volatile unsigned long *) 0x5A000030)
#define SDIDSTA              (*(volatile unsigned long *) 0x5A000034)
#define SDIFSTA              (*(volatile unsigned long *) 0x5A000038)
#define SDIIMSK              (*(volatile unsigned long *) 0x5A00003C)
#define SDIDAT               (*(volatile unsigned char *) 0x5A000040)


#ifdef __BIG_ENDIAN
#undef  SDIDAT
#define SDIDAT               (*(volatile unsigned char *) 0x5A000043)
#endif


// AC97 Audio-CODEC Interface
#define AC_GLBCTRL           (*(volatile unsigned long *) 0x5B000000)
#define AC_GLBSTAT           (*(volatile unsigned long *) 0x5B000004)
#define AC_CODEC_CMD         (*(volatile unsigned long *) 0x5B000008)
#define AC_CODEC_STAT        (*(volatile unsigned long *) 0x5B00000C)
#define AC_PCMADDR           (*(volatile unsigned long *) 0x5B000010)
#define AC_MICADDR           (*(volatile unsigned long *) 0x5B000014)
#define AC_PCMDATA           (*(volatile unsigned long *) 0x5B000018)
#define AC_MICDATA           (*(volatile unsigned long *) 0x5B00001C)


// Interrupt Pending Bit
#define BIT_EINT0            (1 <<  0)
#define BIT_EINT1            (1 <<  1)
#define BIT_EINT2            (1 <<  2)
#define BIT_EINT3            (1 <<  3)
#define BIT_EINT4_7          (1 <<  4)
#define BIT_EINT8_23         (1 <<  5)
#define BIT_CAM              (1 <<  6)
#define BIT_nBAT_FLT         (1 <<  7)
#define BIT_TICK             (1 <<  8)
#define BIT_WDT_AC97         (1 <<  9)
#define BIT_TIMER0           (1 << 10)
#define BIT_TIMER1           (1 << 11)
#define BIT_TIMER2           (1 << 12)
#define BIT_TIMER3           (1 << 13)
#define BIT_TIMER4           (1 << 14)
#define BIT_UART2            (1 << 15)
#define BIT_LCD              (1 << 16)
#define BIT_DMA0             (1 << 17)
#define BIT_DMA1             (1 << 18)
#define BIT_DMA2             (1 << 19)
#define BIT_DMA3             (1 << 20)
#define BIT_SDI              (1 << 21)
#define BIT_SPI0             (1 << 22)
#define BIT_UART1            (1 << 23)
#define BIT_NFCON            (1 << 24)
#define BIT_USBD             (1 << 25)
#define BIT_USBH             (1 << 26)
#define BIT_IIC              (1 << 27)
#define BIT_UART0            (1 << 28)
#define BIT_SPI1             (1 << 29)
#define BIT_RTC              (1 << 30)
#define BIT_ADC              (1 << 31)
#define BIT_ALLMSK           (0xFFFFFFFF)


#define BIT_SUB_RXD0         (1 <<  0)
#define BIT_SUB_TXD0         (1 <<  1)
#define BIT_SUB_ERR0         (1 <<  2)
#define BIT_SUB_RXD1         (1 <<  3)
#define BIT_SUB_TXD1         (1 <<  4)
#define BIT_SUB_ERR1         (1 <<  5)
#define BIT_SUB_RXD2         (1 <<  6)
#define BIT_SUB_TXD2         (1 <<  7)
#define BIT_SUB_ERR2         (1 <<  8)
#define BIT_SUB_TC           (1 <<  9)
#define BIT_SUB_ADC_S        (1 << 10)
#define BIT_SUB_CAM_C        (1 << 11)
#define BIT_SUB_CAM_P        (1 << 12)
#define BIT_SUB_WDT          (1 << 13)
#define BIT_SUB_AC97         (1 << 14)
#define BIT_SUB_ALLMSK       (0x000007FF)


#define ClearPending(bit)    { SRCPND = bit;    \
                               INTPND = INTPND; }


#endif // __S3C2440_H
           

//-------------- GPIO操作的頭檔案 ----------------------------

#ifndef _GPIO_H_
#define _GPIO_H_


#include "s3c2440.h"


void Delay(int x);
void Led_Init(void);
void Led_ON(int x);
void Led_OFF(int x);


void Bell_Init(void);
void Bell_ON(void);
void Bell_OFF(void);


void Key_Init(void);
int Key_Scan(void);


#endif
           

//-------------- GPIO操作的源檔案 ----------------------------

/*
;
; 檔案名:init.s
; 說明:  啟動代碼
;
AREA |DATA|, CODE, READONLY
ENTRY

ldr r13, =0x1000
IMPORT timerMain
b timerMain ;我是在
END

;----------------- the end of init.s ----------------------
*/
           
/*
 * 檔案:led.c
 * 說明:有關LED控制的函數
*/


/*
LED借口說明
LED0 ----- GPB5
LED1 ----- GPB6
LED2 ----- GPB8
LED3 ----- GPB10
*/
void Delay(int x)
{
int i=0;

while(x)
{
for(i = 0; i < 2000; i++);
x--;
}
}


void Led_Init(void)
{
GPBCON &= 0xCCC3FF;
GPBCON |= 0x111400;//GPB5, GPB6, GPB8, GPB10設定為輸出
GPBDAT |= ((1<<5) | (1<<6) | (1<<8) | (1<<10));//關閉LED
GPBUP = 0x00;
}


void Led_ON(int x)
{
switch(x)
{
case 0: GPBDAT &= ~(1<<5); break;
case 1: GPBDAT &= ~(1<<6); break;
case 2: GPBDAT &= ~(1<<8); break;
case 3: GPBDAT &= ~(1<<10); break;
default: break;
}
}


void Led_OFF(int x)
{
switch(x)
{
case 0: GPBDAT |= (1<<5); break;
case 1: GPBDAT |= (1<<6); break;
case 2: GPBDAT |= (1<<8); break;
case 3: GPBDAT |= (1<<10); break;
default: break;
}
}
           

// ----------------------- the end of bell.c ---------------------

/*
 * 檔案:bell.c
 * 說明:有關bell控制的函數
*/


/*
bell接口說明
BELL ----- GPB0
*/


void Bell_Init(void)
{
GPBCON &= ~0x3;
GPBCON |= 0x1;
GPBUP  &= ~0x1;//使能上拉
}


void Bell_ON(void)
{
GPBDAT |= 0x1;   
}


void Bell_OFF(void)
{
GPBDAT &= ~0x1; H*
}


// ----------------------- the end of bell.c ---------------------
           
/*
 * 檔案:key.c
 * 說明:有關key控制的函數
*/


/*
按鍵接口說明
GPF0 ------ 按鍵S2------- key1
GPF2 ------ 按鍵S3------- key2
GPF3 ------ 按鍵S4------- key3
GPF4 ------ 按鍵S5------- key4
*/


static void Key_Delay(void)
{
int n;

for(n = 0; n < 1000; n++);
}


void Key_Init(void)
{
GPFCON &= ~(3<<0 | 3<<2*2 | 3<<2*3 | 3<<2*4);
GPFUP &= ~(1<<0 | 1<<2 | 1<<3 | 1<<4);
}
           
/*
 * 函數:Key_Scan
 * 說明:掃描按鍵,傳回被按下按鍵的值
 * 傳回值:對應按鍵的值
*/
int Key_Scan(void)
{
int tmp = 0;

if((GPFDAT&0x01) == 0)
{
Key_Delay();
if((GPFDAT&0x01) == 0)
{
while((GPFDAT&0x01) == 0);
tmp = 1;
}
}
if((GPFDAT&0x04) == 0)
{
Key_Delay();
if((GPFDAT&0x04) == 0)
{
while((GPFDAT&0x04) == 0);
tmp = 2;
}
}
if((GPFDAT&0x08) == 0)
{
Key_Delay();
if((GPFDAT&0x08) == 0)
{
while((GPFDAT&0x08) == 0);
tmp = 3;
}
}
if((GPFDAT&0x10) == 0)
{
Key_Delay();
if((GPFDAT&0x10) == 0)
{
while((GPFDAT&0x10) == 0);
tmp = 4;
}
}

return tmp;
}
           

// ----------------------- the end of key.c ---------------------

//-------------- watchdog操作的頭檔案 ----------------------------

#ifndef _WATCHDOG_H_
#define _WATCHDOG_H_


#include "s3c440.h"


void watchdog_Init(void);


#endif


/* --------------- 應用執行個體 ------------------
void timer(void)
{
//int n;
//char str[] = "luoxn28\n";


Led_Init();
Bell_Init();
Key_Init();
UART0_Init();
watchdog_Init();

ISR_WDT_AC97 = (u32)watchdog;

//UART_SendString("\n the old data:\n");

while(1)
{
Led_ON(0);
Delay(200);
Led_OFF(0);
Delay(200);

//WTCNT = 50000;               //喂狗,重新指派,防止中斷

Led_ON(1);
Delay(200);
Led_OFF(1);
Delay(200);

//WTCNT = 50000;               //喂狗,重新指派,防止中斷
}
}


*/
           

//-------------- watchdog操作的源檔案 ----------------------------

#include "watchdog.h"


#define _ISR_STARTADD 0x33FFFF00
#define ISR_WDT_AC97 (*(unsigned *)(_ISR_STARTADD + 0x44))


char cnt = 0;


__irq void watchdog(void)
{

cnt++;
if((cnt%2) == 1)
{
Led_ON(2);
UART_SendString("\n Led_ON(2)\n");
}
else
{
Led_ON(3);
UART_SendString("\n Led_ON(3)\n");
}

UART_SendChar((char)(cnt/100 + '0'));
UART_SendChar(cnt/10%10 + '0');
UART_SendChar(cnt%10 + '0');

//清中斷标志位
SRCPND = 0x1<<9;
SUBSRCPND = 0x1<<13;
INTPND = 0x1<<9;

WTCNT = 50000;  
}


//看門狗産生中斷方式
void watchdog_Init(void)
{
WTCON = 0xf9<<8;                  //Prescaler = 249,Division = 16,時鐘頻率為12.5kHz
                                                        //禁止看門狗複位
WTDAT = 50000;               //設定看門狗定時器逾時時間為4秒(50÷12.5)
WTCNT = 50000;
WTCON |= (1<<5)|(1<<2);         //開啟看門狗定時器中斷
SRCPND = 0x1<<9;
SUBSRCPND = 0x1<<13;
INTPND = 0x1<<9;
INTSUBMSK = ~(0x1<<13);      //打開中斷子屏蔽
INTMSK = ~(0x1<<9);                     //打開中斷屏蔽
}
           

//-------------- nanflash操作的頭檔案 ----------------------------

#ifndef _NANDFLASH_H_
#define _NANDFLASH_H_


#include "s3c2440.h"


typedef unsigned int u32;
typedef unsigned char u8;


#define CMD_READ1               0x00              //頁讀指令周期1
#define CMD_READ2               0x30              //頁讀指令周期2
#define CMD_READID              0x90              //讀ID指令
#define CMD_WRITE1              0x80              //頁寫指令周期1
#define CMD_WRITE2              0x10              //頁寫指令周期2
#define CMD_ERASE1              0x60              //塊擦除指令周期1
#define CMD_ERASE2              0xd0              //塊擦除指令周期2
#define CMD_STATUS              0x70              //讀狀态指令
#define CMD_RESET               0xff               //複位
#define CMD_RANDOMREAD1         0x05       //随意讀指令周期1
#define CMD_RANDOMREAD2         0xE0       //随意讀指令周期2
#define CMD_RANDOMWRITE         0x85       //随意寫指令


#define NFDATA8   (*(volatile unsigned char *)0x4E000010)
#define NF_CMD(data)           NFCMD  = (data)         //傳輸指令
#define NF_ADDR(addr)          NFADDR = (addr)          //傳輸位址
#define NF_RDDATA()            (NFDATA)                         //讀32位資料
#define NF_RDDATA8()           (NFDATA8)                       //讀8位資料
#define NF_WRDATA(data)        NFDATA = (data)           //寫32位資料
#define NF_WRDATA8(data)       NFDATA8 = (data)         //寫8位資料


#define TACLS 1
#define TWRPH0 2
#define TWRPH1 0


#define NF_nFCE_L()              NFCONT &= ~(1<<1)
#define NF_CE_L()                NF_nFCE_L()                                   //打開nandflash片選
#define NF_nFCE_H()              NFCONT |= (1<<1)
#define NF_CE_H()                NF_nFCE_H()                            //關閉nandflash片選
#define NF_RSTECC()              NFCONT |= (1<<4)                      //複位ECC
#define NF_MECC_UnLock()         NFCONT &= ~(1<<5)           //解鎖main區ECC
#define NF_MECC_Lock()           NFCONT |= (1<<5)                      //鎖定main區ECC
#define NF_SECC_UnLock()         NFCONT &= ~(1<<6)           //解鎖spare區ECC
#define NF_SECC_Lock()           NFCONT |= (1<<6)                      //鎖定spare區ECC


#define NF_WAITRB()              while(!(NFSTAT&(1<<0)))           //等待nandflash不忙
#define NF_CLEAR_RB()            NFSTAT |= (1<<2)                      //清除RnB信号
#define NF_DETECT_RB()           while(!(NFSTAT&(1<<2)))           //等待RnB信号變高,即不忙


void NF_Init ( void );
char NF_ReadID();
u8 NF_ReadPage(u32 page_number, char buffer[]);
u8 NF_WritePage(u32 page_number, char buffer[]);
u8 NF_EraseBlock(u32 block_number);
u8 NF_RamdomRead(u32 page_number, u32 add);
u8 NF_RamdomWrite(u32 page_number, u32 add, u8 dat);


#endif
 
/* -------------- 程式執行個體 --------------
void main(void)
{
int n;
char str[] = "luoxn28\n";
char buffer[2048], id;
u32 NFBlockNO=6;
u32 NFPagesNO = 25;
u32 BlockPages;

BlockPages =(NFBlockNO<<6)+NFPagesNO;

Led_Init();
Bell_Init();
Key_Init();
UART0_Init();

NF_Init();
id = NF_ReadID();
UART_SendString("\ntest nand flash\n");
UART_SendChar(id/100 + '0');
UART_SendChar(id/10%10 + '0');
UART_SendChar(id%10 + '0');


UART_SendString("\n the old data:\n");
NF_ReadPage(BlockPages*64, buffer);
for(n = 0; n < 2048; n++)
{
UART_SendChar(buffer[n]);
}

if(NF_EraseBlock(BlockPages) == 0x66)
{
//NF_ReadPage(BlockPages*64, buffer);
//for(n = 0; n < 2048; n++)
//{
// UART_SendChar(buffer[n]);
//}
UART_SendString("\nerase is ok1\n");
}

for(n = 0; n < 2048; n++)
{
buffer[n] = 128 - n%128;
}
if(NF_WritePage(BlockPages*64, buffer) == 0x66)
{
NF_ReadPage(BlockPages*64, buffer);
UART_SendString("\nthe new data:\n");
for(n = 0; n < 2048; n++)
{
UART_SendChar(buffer[n]);
}
}

while(1)
{
Led_ON(0);
Delay(1000);
Led_OFF(0);
Delay(1000);
}
}
*/
           

//-------------- nanflash操作的源檔案 ----------------------------

#include "nandflash.h"


void NF_Init ( void )
{
GPACON = (GPACON &~(0x3f<<17)) | (0x3f<<17);            //配置晶片引腳
NFCONF = (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4)|(0<<0);//TACLS=1、TWRPH0=2、TWRPH1=0,8位IO

//非鎖定,屏蔽nandflash中斷,初始化ECC及鎖定main區和spare區ECC,使能nandflash片選及控制器
    NFCONT = (0<<13)|(0<<12)|(0<<10)|(0<<9)|(0<<8)|(1<<6)|(1<<5)|(1<<4)|(1<<1)|(1<<0);
}


static void NF_Reset()
{
NF_CE_L();                   //打開nandflash片選
NF_CLEAR_RB();               //清除RnB信号
NF_CMD(CMD_RESET);           //寫入複位指令
NF_DETECT_RB();              //等待RnB信号變高,即不忙
NF_CE_H();                   //關閉nandflash片選
}


char NF_ReadID()
{
char MID;
char DID;
char cyc3, cyc4, cyc5;


NF_nFCE_L();                           //打開nandflash片選
NF_CLEAR_RB();                      //清RnB信号
NF_CMD(CMD_READID);        //讀ID指令
NF_ADDR(0x0);                        //寫0x00位址


//讀五個周期的ID
MID = NF_RDDATA8();                   //廠商ID:0xEC
DID = NF_RDDATA8();                   //裝置ID:0xDA
cyc3 = NF_RDDATA8();                     //0x10
cyc4 = NF_RDDATA8();                     //0x95
cyc5 = NF_RDDATA8();                     //0x44


NF_nFCE_H();                    //關閉nandflash片選


return (DID);
}


u8 NF_ReadPage(u32 page_number, char buffer[])
{
u32 i, mecc0, secc;


NF_RSTECC();               //複位ECC
NF_MECC_UnLock();          //解鎖main區ECC


NF_nFCE_L();               //打開nandflash片選
NF_CLEAR_RB();             //清RnB信号


NF_CMD(CMD_READ1);         //頁讀指令周期1


//寫入5個位址周期
NF_ADDR(0x00);                                  //列位址A0~A7
NF_ADDR(0x00);                                  //列位址A8~A11
NF_ADDR((page_number) & 0xff);                  //行位址A12~A19
NF_ADDR((page_number >> 8) & 0xff);             //行位址A20~A27
NF_ADDR((page_number >> 16) & 0xff);            //行位址A28


NF_CMD(CMD_READ2);          //頁讀指令周期2


NF_DETECT_RB();                   //等待RnB信号變高,即不忙


//讀取一頁資料内容
for (i = 0; i < 2048; i++)
{
     buffer[i] =  NF_RDDATA8();
}


NF_MECC_Lock();                     //鎖定main區ECC值


NF_SECC_UnLock();                  //解鎖spare區ECC


mecc0=NF_RDDATA();        //讀spare區的前4個位址内容,即第2048~2051位址,這4個位元組為main區的ECC
//把讀取到的main區的ECC校驗碼放入NFMECCD0/1的相應位置内
NFMECCD0=((mecc0&0xff00)<<8)|(mecc0&0xff);
NFMECCD1=((mecc0&0xff000000)>>8)|((mecc0&0xff0000)>>16);
   
NF_SECC_Lock();               //鎖定spare區的ECC值


secc=NF_RDDATA();           //繼續讀spare區的4個位址内容,即第2052~2055位址,其中前2個位元組為spare區的ECC值
//把讀取到的spare區的ECC校驗碼放入NFSECCD的相應位置内
NFSECCD=((secc&0xff00)<<8)|(secc&0xff);


NF_nFCE_H();             //關閉nandflash片選


//判斷所讀取到的資料是否正确
if ((NFESTAT0&0xf) == 0x0)
     return 0x66;                  //正确
else
     return 0x44;                  //錯誤


}


u8 NF_IsBadBlock(u32 block)
{
       return NF_RamdomRead(block*64, 2054);
}


u8 NF_MarkBadBlock(u32 block)
{
u8 result;
   
    result = NF_RamdomWrite(block*64, 2054, 0x33);
 
       if(result == 0x44)
return 0x21;                  //寫壞塊标注失敗
       else
            return 0x60;                  //寫壞塊标注成功
}


void NF_Delay(int n)
{
int i;

while(n > 0)
{
n--;
for(i = 0; i < 200; i++);
}
}
u8 ECCBuf[6];


u8 NF_WritePage(u32 page_number, char buffer[])
{
u32 i, mecc0, secc;
u8 stat, temp;


temp = NF_IsBadBlock(page_number>>6);              //判斷該塊是否為壞塊
if(temp == 0x33)
     return 0x42;           //是壞塊,傳回


NF_RSTECC();                   //複位ECC
NF_MECC_UnLock();          //解鎖main區的ECC


NF_nFCE_L();             //打開nandflash片選
NF_CLEAR_RB();        //清RnB信号


NF_CMD(CMD_WRITE1);                //頁寫指令周期1


//寫入5個位址周期
NF_ADDR(0x00);                                     //列位址A0~A7
NF_ADDR(0x00);                                     //列位址A8~A11
NF_ADDR((page_number) & 0xff);           //行位址A12~A19
NF_ADDR((page_number >> 8) & 0xff);    //行位址A20~A27
NF_ADDR((page_number >> 16) & 0xff);  //行位址A28


//寫入一頁資料
for (i = 0; i < 2048; i++)
{
     NF_WRDATA8((char)buffer[i]);
}


NF_MECC_Lock();                     //鎖定main區的ECC值


mecc0=NFMECC0;                    //讀取main區的ECC校驗碼
//把ECC校驗碼由字型轉換為位元組型,并儲存到全局變量數組ECCBuf中
ECCBuf[0]=(u8)(mecc0&0xff);
ECCBuf[1]=(u8)((mecc0>>8) & 0xff);
ECCBuf[2]=(u8)((mecc0>>16) & 0xff);
ECCBuf[3]=(u8)((mecc0>>24) & 0xff);


NF_SECC_UnLock();                  //解鎖spare區的ECC
//把main區的ECC值寫入到spare區的前4個位元組位址内,即第2048~2051位址
for(i=0;i<4;i++)
{
     NF_WRDATA8(ECCBuf[i]);
}


NF_SECC_Lock();                      //鎖定spare區的ECC值
secc=NFSECC;                   //讀取spare區的ECC校驗碼
//把ECC校驗碼儲存到全局變量數組ECCBuf中
ECCBuf[4]=(u8)(secc&0xff);
ECCBuf[5]=(u8)((secc>>8) & 0xff);
//把spare區的ECC值繼續寫入到spare區的第2052~2053位址内
for(i=4;i<6;i++)
{
     NF_WRDATA8(ECCBuf[i]);
}


NF_CMD(CMD_WRITE2);                //頁寫指令周期2


NF_Delay(1000);          //延時一段時間,以等待寫操作完成


NF_CMD(CMD_STATUS);                 //讀狀态指令


//判斷狀态值的第6位是否為1,即是否在忙,該語句的作用與NF_DETECT_RB();相同
do{
     stat = NF_RDDATA8();
}while(!(stat&0x40));


NF_nFCE_H();                    //關閉nandflash片選


//判斷狀态值的第0位是否為0,為0則寫操作正确,否則錯誤
if (stat & 0x1)
{
temp = NF_MarkBadBlock(page_number>>6);         //标注該頁所在的塊為壞塊
if (temp == 0x21)
     return 0x43;            //标注壞塊失敗
else
     return 0x44;           //寫操作失敗
}
else
return 0x66;                  //寫操作成功
}


u8 stat;


u8 NF_EraseBlock(u32 block_number)
{
char stat, temp;


temp = NF_IsBadBlock(block_number);     //判斷該塊是否為壞塊
if(temp == 0x33)
     return 0x42;           //是壞塊,傳回


NF_nFCE_L();             //打開片選
NF_CLEAR_RB();        //清RnB信号


NF_CMD(CMD_ERASE1);         //擦除指令周期1


//寫入3個位址周期,從A18開始寫起
NF_ADDR((block_number << 6) & 0xff);         //行位址A18~A19
NF_ADDR((block_number >> 2) & 0xff);         //行位址A20~A27
NF_ADDR((block_number >> 10) & 0xff);        //行位址A28


NF_CMD(CMD_ERASE2);         //擦除指令周期2
 
NF_Delay(1000);          //延時一段時間
  
NF_CMD(CMD_STATUS);          //讀狀态指令
     
      //判斷狀态值的第6位是否為1,即是否在忙,該語句的作用與NF_DETECT_RB();相同
do{
    stat = NF_RDDATA8();
}while(!(stat&0x40));
  
NF_nFCE_H();             //關閉nandflash片選
 
//判斷狀态值的第0位是否為0,為0則擦除操作正确,否則錯誤
if (stat & 0x1)
{
      temp = NF_MarkBadBlock(block_number>>6);         //标注該塊為壞塊
      if (temp == 0x21)
             return 0x43;            //标注壞塊失敗
      else
             return 0x44;           //擦除操作失敗
}
else
return 0x66;                  //擦除操作成功
}


u8 NF_RamdomRead(u32 page_number, u32 add)
{
NF_nFCE_L();                    //打開nandflash片選
NF_CLEAR_RB();               //清RnB信号


NF_CMD(CMD_READ1);           //頁讀指令周期1


//寫入5個位址周期
NF_ADDR(0x00);                                            //列位址A0~A7
NF_ADDR(0x00);                                            //列位址A8~A11
NF_ADDR((page_number) & 0xff);                  //行位址A12~A19
NF_ADDR((page_number >> 8) & 0xff);           //行位址A20~A27
NF_ADDR((page_number >> 16) & 0xff);         //行位址A28


NF_CMD(CMD_READ2);          //頁讀指令周期2


NF_DETECT_RB();                    //等待RnB信号變高,即不忙


NF_CMD(CMD_RANDOMREAD1);                 //随意讀指令周期1
//頁内位址
NF_ADDR((char)(add&0xff));                          //列位址A0~A7
NF_ADDR((char)((add>>8)&0x0f));                 //列位址A8~A11
NF_CMD(CMD_RANDOMREAD2);                //随意讀指令周期2


return NF_RDDATA8();               //讀取資料
}
 
u8 NF_RamdomWrite(u32 page_number, u32 add, u8 dat)
{
u8 stat;


NF_nFCE_L();                    //打開nandflash片選
NF_CLEAR_RB();               //清RnB信号


NF_CMD(CMD_WRITE1);                //頁寫指令周期1


//寫入5個位址周期
NF_ADDR(0x00);                                     //列位址A0~A7
NF_ADDR(0x00);                                     //列位址A8~A11
NF_ADDR((page_number) & 0xff);           //行位址A12~A19
NF_ADDR((page_number >> 8) & 0xff);    //行位址A20~A27
NF_ADDR((page_number >> 16) & 0xff);  //行位址A28


NF_CMD(CMD_RANDOMWRITE);                 //随意寫指令
//頁内位址
NF_ADDR((char)(add&0xff));                   //列位址A0~A7
NF_ADDR((char)((add>>8)&0x0f));          //列位址A8~A11


NF_WRDATA8(dat);                          //寫入資料


NF_CMD(CMD_WRITE2);                //頁寫指令周期2


NF_Delay(1000);                 //延時一段時間


NF_CMD(CMD_STATUS);                        //讀狀态指令


//判斷狀态值的第6位是否為1,即是否在忙,該語句的作用與NF_DETECT_RB();相同
do{
stat =  NF_RDDATA8();
}while(!(stat&0x40));


NF_nFCE_H();                    //關閉nandflash片選


//判斷狀态值的第0位是否為0,為0則寫操作正确,否則錯誤
if (stat & 0x1)
return 0x44;                  //失敗
else
return 0x66;                  //成功
}