LPC1788的EMC驱动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); //设置总线宽度16位
LPC_EMC->StaticConfig0 |= (1<<7); //设置读写有效电平,读为低电平
LPC_EMC->StaticWaitWen0 &= ~(7<<0);
LPC_EMC->StaticWaitWen0 |= (2<<0);//设置片选到写使能的延时时间
LPC_EMC->StaticWaitOen0 &= ~(7<<0);
LPC_EMC->StaticWaitOen0 |= (2<<0);//设置片选到输出使能的延时
LPC_EMC->StaticWaitWr0 &= ~(0x1f<<0);
LPC_EMC->StaticWaitWr0 |= (0x1f<<0);//设置片选到写入的延时
LPC_EMC->StaticWaitPage0 &= ~(0x1f<<0);
LPC_EMC->StaticWaitPage0 |= (0x1f<<0);//设置读模式顺序存取延时
LPC_EMC->StaticWaitRd0 &= ~(0x1f<<0);
LPC_EMC->StaticWaitRd0 |= (0x1f<<0);//设置片选到读取的延时
LPC_EMC->StaticWaitTurn0 &= ~(0x1f<<0);
LPC_EMC->StaticWaitTurn0 |= (0x1f<<0);//设置总线周转周期
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 \r\n",SST_id1);
printf("SST_id2 = %x \r\n",SST_id2);
return( 1 );
}
}
//写入数据,只能16位写入
u32 norflash_write_word(u32 add, u16 data)
{
volatile uint16_t *ip;
ip = GET_ADDR(0x5555);
*ip = 0x00AA;
ip = GET_ADDR(0x2aaa);
*ip = 0x0055;
ip = GET_ADDR(0x5555);
*ip = 0x00A0;
ip = GET_ADDR(add); /* Program 16-bit word */
*ip = data;
return ( norflash_toggle_bit_check( add, data ) );
}
//数据写入检查
u32 norflash_toggle_bit_check(u32 addr,u16 data)
{
volatile u16 *ip;
u16 temp1, temp2;
u32 TimeOut = PROGRAM_TIMEOUT;
while( TimeOut > 0 )
{
ip = GET_ADDR(addr);
temp1 = *ip;
ip = GET_ADDR(addr);
temp2 = *ip;
if ( (temp1 == temp2) && (temp1 == data) )
{
return( 0 );
}
TimeOut--;
}
printf("temp1 = %x \r\n",temp1);
printf("temp2 = %x \r\n",temp2);
return ( 1 );
}
LPC1788的EMC驱动norflash的更多相关文章
- lPC1788的GPIO驱动
#include "led.h" void led_init(void) { //p1.14 p0.16 p1.13 p4.27 LPC_SC->PCONP |= (1< ...
- 单片机STM32在开发中常用库函数详解
1.GPIO初始化函数 用法: voidGPIO_Configuration(void) { GPIO_InitTypeDefGPIO_InitStructure;//GPIO状态恢复默认参数 GPI ...
- stm32中的串口通信你了解多少
在基础实验成功的基础上,对串口的调试方法进行实践.硬件代码顺利完成之后,对日后调试需要用到的printf重定义进行调试,固定在自己的库函数中. b) 初始化函数定义: void USART_Confi ...
- 嵌入式物联网之SPI接口原理与配置
本实验采用W25Q64芯片 W25Q64是华邦公司推出的大容量SPI FLASH产品,其容量为64Mb.该25Q系列的器件在灵活性和性能方面远远超过普通的串行闪存器件.W25Q64将8M字节的容量分为 ...
- stm32学习笔记之串口通信
在基础实验成功的基础上,对串口的调试方法进行实践.硬件代码顺利完成之后,对日后调试需要用到的printf重定义进行调试,固定在自己的库函数中. b) 初始化函数定义: void USART_Confi ...
- STM32的串口通信
本篇文章主要讲解一个在开发过程中经常使用到的一个外设---串口. 串口是绝大多数 MCU 中不可或缺的一个外设,同时也是我们开发中经常使用的一种调试手段,所以在STM32的学习中,串口的配置使用也是必 ...
- USART波特率 vs SPI速率--学习笔记
本篇文章将与大家探讨USART波特率 vs SPI速率.这里提出一个问题,为什么USART的波特率是内核时钟的1/8或者1/16,而SPI最快的频率可以是内核时钟的1/2. 请大家带着这个问题来阅读本 ...
- LPC1788 nand驱动
Lpc 1788自带有emc接口用于驱动nandflash,norflash,sdram设备,对于nandflash驱动因为配置简单,时序也简单 首先,针对nandflash而言应当在系统中有三个地址 ...
- lPC1788驱动SDRAM
Sdram型号为hy57v256 #ifndef __SRAM_H_ #define __SRAM_H_ #include "common.h" #include "de ...
随机推荐
- php sso 单点登录的实现 代码示例
先说一下这样做的好处吧,先来三个屌丝域名: www.openpoor.com myspace.openpoor.com passport.openpoor.com 大家都知道,虽然他们都是一个域名但主 ...
- Android中图片占用内存的计算
Android中图片占用内存的计算 原文链接 http://blog.sina.com.cn/s/blog_4e60b09d01016133.html 在Android开发中,我现在发现很多人还不 ...
- 【Python初学】深copy&浅copy
在python中,对象赋值实际上是对象的引用.当创建一个对象,然后把它赋给另一个变量的时候,python并没有拷贝这个对象,而只是拷贝了这个对象的引用. 1. copy.copy 浅拷贝 只拷贝父对象 ...
- sql server 2005导出数据
*/ EXEC sp_configure 'show advanced options', 1 GO */ 配置选项 'show advanced options' 已从 0 更改为 1.请运 ...
- android 垂直 SeekBar 源代码(VerticalSeekBar)[转]
主要是继承 AbsSeekBar 然后修改下面这些方法 onProgressRefresh() //当进度条数据更新的时候,例如我们拖动滑动条的时候,这个方法被调用 setThumbPos() //这 ...
- CentOS下编译安装Apache2(新)
官网下载apache,apr, apr-util,pcre httpd-2.4.16.tar.gz http://httpd.apache.org/download.cgi#apache24 apr- ...
- 彻底搞明白find命令的-mtime参数的含义【转载】
转自: 彻底搞明白find命令的-mtime参数的含义-goolen-ITPUB博客http://blog.itpub.net/23249684/viewspace-1156932/ 以前一直没有弄明 ...
- MQ日常维护操作手册
假设队列管理器为QMgrName,以下所有使用QMgrName的地方您都可以替换成您维护的mq队列管理器名称. 一.MQ的启动与停止 用root用户启/停需要root用户包含在mqm组中. 1.MQ的 ...
- Linux查看端口被哪个进程占用
netstat -lnp|awk 'BEGIN{prt=":443$"}{if ($4 ~ prt) print $0}' 查看443端口
- XML 从基础到精通
1.简介 XML(可扩展标记语言)语言是一种数据交换标准,用于存储数据:关键词是标记: XML具有以下优点: (1) 方便的穿过防火墙,在不同的操作系统之间通信,跨语言,跨平台.数据共享非常方便.(J ...