LPC1788的EMC驅(qū)動norflash
Norflash型號為sst39vf32
#ifndef __NORFLASH_H_
#define __NORFLASH_H_
#include "common.h"
#include "delay.h"
#include "debugserial.h"
#define NOR_FLASH_BASE 0x80000000
#define NOR_FLASH_SIZE 0x00100000
#define GET_ADDR(addr) (volatile uint16_t *)(NOR_FLASH_BASE | (addr<<1))
#define SECTOR_SIZE 0x800 /* Must be 2048 words for 39VF160 */
#define BLOCK_SIZE 0x8000 /* Must be 32K words for 39VF160 */
#define SST_ID 0xBF /* SST Manufacturer's ID code */
#define SST_39VF160 0x235D /* SST 39VF160 device code */
#define PROGRAM_TIMEOUT 0x00008000
//norflash 初始化必須在sram初始化之前
void norflash_init(void);
void norflash_erase(void);
u32 norflash_check_id(void);
u32 norflash_write_word(u32 add,u16 data);
u32 norflash_toggle_bit_check(u32 addr,u16 data);
#endif
#include "norflash.h"
static void norflash_io_init(void)
{
//a0-a22
/* init EMC_A1 */
LPC_IOCON->P4_1=0x21;
/* init EMC_A2 */
LPC_IOCON->P4_2=0x21;
/* init EMC_A3 */
LPC_IOCON->P4_3=0x21;
/* init EMC_A4 */
LPC_IOCON->P4_4=0x21;
/* init EMC_A5 */
LPC_IOCON->P4_5=0x21;
/* init EMC_A6 */
LPC_IOCON->P4_6=0x21;
/* init EMC_A7 */
LPC_IOCON->P4_7=0x21;
/* init EMC_A8 */
LPC_IOCON->P4_8=0x21;
/* init EMC_A9 */
LPC_IOCON->P4_9=0x21;
/* init EMC_A10 */
LPC_IOCON->P4_10=0x21;
/* init EMC_A11 */
LPC_IOCON->P4_11=0x21;
/* init EMC_A12 */
LPC_IOCON->P4_12=0x21;
/* init EMC_A13 */
LPC_IOCON->P4_13=0x21;
/* init EMC_A14 */
LPC_IOCON->P4_14=0x21;
/* init EMC_A15 */
LPC_IOCON->P4_15=0x21;
/* init EMC_A16 */
LPC_IOCON->P4_16=0x21;
/* init EMC_A17 */
LPC_IOCON->P4_17=0x21;
/* init EMC_A18 */
LPC_IOCON->P4_18=0x21;
/* init EMC_A19 */
LPC_IOCON->P4_19=0x21;
/* init EMC_A20 */
LPC_IOCON->P4_20=0x21;
/* init EMC_A21 */
LPC_IOCON->P4_21=0x21;
/* init EMC_A22 */
LPC_IOCON->P4_22=0x21;
//d0-d15
/* init EMC_D0 */
LPC_IOCON->P3_0=0x21;
/* init EMC_D1 */
LPC_IOCON->P3_1=0x21;
/* init EMC_D2 */
LPC_IOCON->P3_2=0x21;
/* init EMC_D3 */
LPC_IOCON->P3_3=0x21;
/* init EMC_D4 */
LPC_IOCON->P3_4=0x21;
/* init EMC_D5 */
LPC_IOCON->P3_5=0x21;
/* init EMC_D6 */
LPC_IOCON->P3_6=0x21;
/* init EMC_D7 */
LPC_IOCON->P3_7=0x21;
/* init EMC_D8 */
LPC_IOCON->P3_8=0x21;
/* init EMC_D9 */
LPC_IOCON->P3_9=0x21;
/* init EMC_D10 */
LPC_IOCON->P3_10=0x21;
/* init EMC_D11 */
LPC_IOCON->P3_11=0x21;
/* init EMC_D12 */
LPC_IOCON->P3_12=0x21;
/* init EMC_D13 */
LPC_IOCON->P3_13=0x21;
/* init EMC_D14 */
LPC_IOCON->P3_14=0x21;
/* init EMC_D15 */
LPC_IOCON->P3_15=0x21;
/* init EMC_WE */
LPC_IOCON->P4_25=0x21;
/* init EMC_oe */
LPC_IOCON->P4_24=0x21;
/* init EMC_cs0 */
LPC_IOCON->P4_30=0x21;
}
void norflash_init(void)
{
LPC_SC->SCS|=(1<<0);//emc地址不移位
//打開emc時鐘與端口時鐘
LPC_SC->PCONP|=(1<<15)|(1<<11);//打開時鐘
LPC_SC->EMCDLYCTL=0x00001010;//延時時間初始化
LPC_EMC->Control=0x00000001;//emc使能
LPC_EMC->Config=0x00000000;//emc配置清零,小端模式
norflash_io_init();
DelayMs(100);
LPC_EMC->StaticConfig0&=~(3<<0); //
LPC_EMC->StaticConfig0|=(1<<0); //設(shè)置總線寬度16位
LPC_EMC->StaticConfig0|=(1<<7); //設(shè)置讀寫有效電平,讀為低電平
LPC_EMC->StaticWaitWen0&=~(7<<0);
LPC_EMC->StaticWaitWen0|=(2<<0);//設(shè)置片選到寫使能的延時時間
LPC_EMC->StaticWaitOen0&=~(7<<0);
LPC_EMC->StaticWaitOen0|=(2<<0);//設(shè)置片選到輸出使能的延時
LPC_EMC->StaticWaitWr0&=~(0x1f<<0);
LPC_EMC->StaticWaitWr0|=(0x1f<<0);//設(shè)置片選到寫入的延時
LPC_EMC->StaticWaitPage0&=~(0x1f<<0);
LPC_EMC->StaticWaitPage0|=(0x1f<<0);//設(shè)置讀模式順序存取延時
LPC_EMC->StaticWaitRd0&=~(0x1f<<0);
LPC_EMC->StaticWaitRd0|=(0x1f<<0);//設(shè)置片選到讀取的延時
LPC_EMC->StaticWaitTurn0&=~(0x1f<<0);
LPC_EMC->StaticWaitTurn0|=(0x1f<<0);//設(shè)置總線周轉(zhuǎn)周期
DelayMs(100);
}
void norflash_erase(void)
{
volatile uint16_t*ip;
ip=GET_ADDR(0x5555);
*ip=0x00AA;
ip=GET_ADDR(0x2AAA);
*ip=0x0055;
ip=GET_ADDR(0x5555);
*ip=0x0080;
ip=GET_ADDR(0x5555);
*ip=0x00AA;
ip=GET_ADDR(0x2AAA);
*ip=0x0055;
ip=GET_ADDR(0x5555);
*ip=0x0010;
DelayMs(10); /* Use timer 1 */
return;
}
//檢查nand id
u32 norflash_check_id(void)
{
volatile uint16_t*ip;
uint16_t SST_id1,SST_id2;
/* Issue the Software Product ID code to 39VF160 */
ip=GET_ADDR(0x5555);
*ip=0x00AA;
ip=GET_ADDR(0x2AAA);
*ip=0x0055;
ip=GET_ADDR(0x5555);
*ip=0x0090;
DelayMs(10);
/* Read the product ID from 39VF160 */
ip=GET_ADDR(0x0000);
SST_id1=*ip&0x00FF;
ip=GET_ADDR(0x0001);
SST_id2=*ip;
/* Issue the Soffware Product ID Exit code thus returning the 39VF160 */
/* to the read operating mode */
ip=GET_ADDR(0x5555);
*ip=0x00AA;
ip=GET_ADDR(0x2AAA);
*ip=0x0055;
ip=GET_ADDR(0x5555);
*ip=0x00F0;
DelayMs(10);
/* Check ID */
if((SST_id1==SST_ID)&&(SST_id2==SST_39VF160))
{
return(0);
}
else
{
printf("SST_id1 = %x rn",SST_id1);
p