flash的dma操作

nand_init()
{//Flash_IO_dma_control  数据FIFO DMA使能和控制信息//将memory target设置为NAND Flash,就是主内存和nand flash之间进行DMA数据传输writel(FIO_DMACTR_REG,(readl(FIO_DMACTR_REG) & 0xcfffffff);//Force ReadID with 4-cycleswritel(NAND_CTR_REG,readl(NAND_CTR_REG)|NAND_CTR_I4);//Reset chip 这个函数实现及过程在下面给出nand_wait_cmd_done(NAND_CMD_RESET);//Read IDnand_wait_cmd_done(NAND_CMD_READID);id = readl(NAND_ID_REG);
}void nand_wait_cmd_done(u32 cmd)
{/*NAND_CMD_REG命令寄存器的后4位为命令标示位,具体命令详见芯片手册*/writel(NAND_CMD_REG,cmd);rct_timer2_reset_count();while(1){/*读命令完成中断状态寄存器,命令完成后该中断标志会自动置为1*/if(readl(NAND_INT_REG) & NAND_INT_DI)// 0x1{break;}if(rct_timer2_get_count() >= NAND_CMD_TIMEOUT){putstr("nand cmd timeout:");puthex(cmd);putstr("\r\n");while(1);}}/*将中断完成标志为重新置为0*/writel(NAND_INT_REG,0x0);
}nand_reset()
{/*Reset FIO FIFO,and Exit random read mode*/setbitsl(FIO_CTR_REG,FIO_CTR_RR);rct_timer2_dly_ms(1);/*delay is must have*/clrbitsl(FIO_CTR_REG,FIO_CTR_RR);/*Clear the FIO DMA Status Register*/writel(FIO_DMASTA_REG,0x0);/*Setup FIO DMA Control Register*//*FIO_DMACTR_TS4B Transfer size 在AHB总线上每次传输的数据大小4字节*/writel(FIO_DMACTR_REG,FIO_DMACTR_FL | FIO_DMACTR_TS4B);/*Setup NAND Flash Control Register*//*参考下面nand_control寄存器指定的相应位*/writel(NAND_CTR_REG,flnand.control);/*清中断状态位*/writel(NAND_INT_REG,0x0);/*Setup flash timing register*//*关于时序这块可参考下面详细的介绍*/writel(NAND_TIM0_REG,flnand.timing0);........return 0;
}//这些时序在nandflash的datasheet中可以查得
#define NAND_TCLS           12
#define NAND_TALS           12
#define NAND_TCS           20
#define NAND_TDS           12
#define NAND_TCLH           5
#define NAND_TALH           5
#define NAND_TCH           5
#define NAND_TDH           5
#define NAND_TWP           12
#define NAND_TWH           10
#define NAND_TWB           100
#define NAND_TRR           20
#define NAND_TRP           12
#define NAND_TREH           10
#define NAND_TRB           100    /*not defined in datasheet*/
#define NAND_TCEH           40    /*trhz - tchz = 60 - 20 = 40*/
#define NAND_TRDELAY           20  /*trea*/
#define NAND_TCLR           10
#define NAND_TWHR           60
#define NAND_TIR           0
#define NAND_TWW           100
#define NAND_TRHZ           60
#define NAND_TAR           10
#define NAND_TRHW           30
#define NAND_TADL           100   /*not defined in datasheet*/
#define NAND_TCRL           5    /*tcea - trea = 2*/

nand_control寄存器需要指定的功能位:
C2:列地址周期为2 2048-bytes pages
I4:ID读取需4个cycle
RC:read-confirm
CC:copy-confirm
IE:interrupt-enable
SZ:flash chip size 1G bit
EB:External banks 表面外部一共挂载的nandflash个数
WD:data bus width 8bit

/**
*Read data from NAND flash to memory
*dst - address in dram
*src - address in nand device
*len - length to be read from nand
*return - length of read data
*/
int nand_read_data(u8 *dst, u8 *src, int len)
{val = src;block = val / flnand.block_size;//src地址对应的起始blockval -= block * flnand.block_size;page = val / flnand.main_size;pos = val % flnand.main_size;pages = len / flnand.main_size;//读取数据长度占据的整页数if(pos == 0){first_ppage_size = 0;//读取地址是页的整数倍}else{first_ppage_size = flnand.main_size - pos;//非整数倍,算出该页应读大小}if(len >= first_ppage_size){pages = (len - first_ppage_size) / flnand.main_size;//读取的整页数last_ppage_size = (len - first_ppage_size) % flnand.main_size;//最后一页的大小}else//读取长度不足一页{first_ppage_size = len;pages = 0;last_ppage_seze = 0;}//读取长度被划分为以下三个部分,进行校验if(len != first_ppage_size + pages * flnand.main_size + last_ppage_size){return -1;}//接下来就是对应这三个部分分三步来进行数据读取//第一部分len = 0;//记录读取数据的实际长度if(first_ppage_size){rval = nand_read(block,page,1,buffer);if(rval < 0){return len;}//因最小的读取单位为页,buffer里为整页的内容,要去除首页偏移memcpy(dst, (void *)(buffer + pos), first_ppage_size);dst += first_ppage_size;len += first_ppage_size;nand_get_affset_adr(&block, &page, 1, rval);}//第二部分if(pages > 0){rval = nand_read(block, page, pages, dst);if(rval < 0){return len;}dst += pages * flnand.main_size;len += pages * flnand.main_size;nand_get_offset_adr(&block, &page, pages, rval);}//第三部分if(last_ppage_size > 0){rval = nand_read(block, page, 1, buffer);if(rval < 0) {return len;}memcpy(dst, (void *)buffer, last_ppage_size);len += last_ppage_size;}return len;
}//block和page后移void nand_get_offset_adr(u32 *block, u32 *page, u32 pages, u32 bad_blks){u32 blocks;blocks = pages / flnand.pages_per_block;pages = pages % flnand.pages_per_block;*block = *block + blocks;*page += pages;if(*page >= flnand.pages_per_block){*page -= flnand.pages_per_block;*block += 1;}*block += bad_blks;}/**block - 读取的起始block*page - 起始block中的起始页*pages - 需读取的页数*buf - 存放读回的数据*/static int nand_read(u32 block, u32 page, u32 pages, u8 *buf){/*起始block中需要读取的页数*/first_blk_pages = flnand.pages_per_block - page;if(pages > first_blk_pages){pages -= first_blk_pages;blocks = pages / flnand.pages_per_block;/*最后剩余的零页*/last_blk_pages = pages % flnand.pages_per_block;}else{first_blk_pages = pages;blocks = 0;last_blk_pages = 0;}/*该函数也是将读取分为三个部分,这个不同在于是基于block来划分,每次读取之前都会进行坏块检测*//*第一部分*/if(first_blk_pages){while(nand_is_bad_block(block)){block++;bad_blks++;}rval = nand_read_pages(block, page, first_blk_pages, buf, NULL, 1);if(rval < 0){return -1;}block++;buf += first_blk_pages * flnand.main_size;}/*第二部分*/while(blocks > 0){while(nand_is_bad_block(block)){block++;bad_blks++;}rval = nand_read_pages(block,0,flnand.pages_per_block,buf,NULL,1);if(rval < 0){return -1;}block++;blocks--;buf += flnand.block_size;}/*第三部分*/if(last_blk_pages){while(nand_is_bad_block(block)){block++;bad_blks++;}rval = nand_read_pages(block,0,last_blk_pages,buf,NULL,1);if(rval < 0){return -1;}}return bad_blks;}
坏块检测这里不打算展开讲,由于其实现相对简单,这里只简述下它的管理思路。
1、创建BBT(bad block table)
2、将BBT存储在flash的最后一个block的第一页(防止最后一个block为坏块,一共预留了4个block)
3、坏块分类:1)出厂坏块,在该block的第一页的OOB区域第6个字节标记为非0xff。2)使用中产生的坏块,可以效仿出厂坏块进行标记,但这里为了区分,在第三页和第四页的OOB区域的第6个字节进行了标记。
4、BBT和坏块之间的映射。1)出厂坏块bbt[block >> 2] &= ~(0x03 << ((block << 1) % 8));2)使用中产生坏块bbt[block >> 2] &= ~(0x01 << ((block << 1) % 8));3)从表中找出该block是否为坏块(逆操作)
bb = (bbt[block >> 2] >> ((block << 1) % 8)) & 0x03;
if(bb == 0x03)
{好块
}
else if(bb == 0x02 || bb == 0x01)
{使用中产生坏块
}
else if(bb == 0x0)
{出厂坏块
}

DMA操作相关:
地址:0xE000_0000 - 0xE000_0FFF Flash 4-KB DMA Data FIFO
读操作时0xE000_0000作为DMA传输的源地址,buffer作为目的地址
写操作时0xE000_0000作为DMA传输的目的地址,buffer作为源地址

看完关于DMA的操作,觉得乏善可陈,按着安霸SDK提供的代码进行操作即可,没有自己可操作的需要。

安霸flash dma操作相关推荐

  1. 安霸Ambarella CV系列芯片

    安霸Ambarella CV系列芯片 关于Ambarella(安霸半导体) Ambarella 的产品广泛应用于人类和计算机视觉领域,包括视频安防.高级驾驶辅助系统(ADAS).电子后视镜.行车记录仪 ...

  2. 在安霸s2lm上wifi定频测试

    最近项目中需要做wifi定频测试,用到了iwpriv. iwpriv是iwconfig的辅助工具,用来配置无线网络接口的各种私有可选参数.iwpriv针对不同种类的驱动实现特定的参数处理和设置.iwp ...

  3. 安霸ARM S2L板子烧写

    最近工作中,因为用到了安霸ARM S2L板子的虚拟内容,把mtdblock5和mtdblock6分区都用作了swap分区增加虚拟内存.结果程序在S2L上运行时,电脑蓝屏了,再重新上电启动后,板子无法正 ...

  4. 基建互联 | 安霸与飞桨深度合作,高性能算法落地简单高效!

    面对人工智能算法在端侧落地的需求,安霸在芯片产品线.工具链和软件开发包上都提供了完整成熟的解决方案.人工智能芯片CV2x系列提供了丰富多样的算力平台,完美适配从消费领域的智能门铃,工业安防领域的智能交 ...

  5. 高清网络摄像机主流芯片方案之安霸、TI和海思对比

    高清网络视频监控发展到今天,市场也开始进入真正的高清时代,诸多有实力的高清摄像机厂家的产品线也逐渐完善起来,高清网络视频监控的配套产品有更加丰富和成熟.与此同时困扰很多人的高清网络摄像机与后端平台或者 ...

  6. 求购安霸Ambarella IONE这颗料的SDK开发工具包 Software Development Kit

    @[Ambarella](求安霸Ambarella IONE这颗料的SDK开发工具包) Software Development Kit 本司仍剩余安霸Ambarella IONE大批,遗失开发工具包 ...

  7. 关于TI、海思(Hisilicon)、安霸(Ambarella)三家的百万高清方案的简单比较

    针对百万高清前端摄像机,TI.Hisilicon.Ambarella三家的方案都有各自的优劣,没有一家是所有维度都占优的. 1.TI: 作为之前的监控芯片占有率No.1,技术底蕴丰厚,不过感觉TI前些 ...

  8. 安霸Ambarella_海思Hisilicon_AI芯片参数对比

    安霸Ambarella_海思Hisilicon_AI芯片参数对比 安霸Ambarella_AI芯片方案成功应用于GoPro Hero 运动相机系列:大疆高端幻影无人机系列的摄像头:Ring.Nest. ...

  9. TI 海思 安霸 智利普 等顶级摄像机芯片简要介绍

    很多年以前业界就谈到安防视频监控领域的三个趋势:数字化.网络化.智能化.目前国内市场上安防视频监控系统的主流产品已经从十多年前的纯模拟视频监控系统,逐步转变成了纯数字的百万高清视频监控系统,即从视频采 ...

最新文章

  1. from selenium.webdriver.support.ui import Select
  2. LeetCode Rotate List
  3. Javascript Step by Step - 03
  4. SAP CRM系统里的附件存储逻辑
  5. 工业交换机安全性能的必要性
  6. xbox360fsd更新游戏封面_游戏类短视频创作指南
  7. python对比两个文件找出不同并显示_python difflib模块实现两个文件差异对比,并输出html格式。...
  8. mysql删除员工_数据库删除职工信息
  9. shell 除法 小数点
  10. mysql文件扩展名查询_如何通过MySQL查询获取文件的文件扩展名?
  11. 学了一年matlab,我到现在还不会读论文~
  12. [工具] Snipaste
  13. flex项目学习包括什么内容
  14. 【UVA1599】Ideal Path理想路径--两种约束条件(!!双向bfs+非简单图的最短路+无向图邻接记录法)
  15. Oracle客户端安装配置crystal reports注意
  16. HBuilder配置浏览器
  17. 获取股票简单数据:腾讯、新浪、东方财富。。。
  18. OJ1088: 手机短号 (多实例)(C语言)
  19. 高端大气的艺术海报的ps教程
  20. 盈一眸恬淡,在明媚的春天等你

热门文章

  1. 华为胖瘦AP切换方法
  2. 用条件编译方法实现以下功能:输入一行电报文字,可以任选两种输出,一为原文输出;一为将字母变成其下一个字母。用define命令控制
  3. 手握119亿美元捐赠基金!美国密歇根大学宣布正式进军加密市场
  4. IC功能芯片的封装和包装经验
  5. torch.mul() 和 torch.mm() 的区别
  6. 唐僧是怎么管理孙悟空的?
  7. 数学物理方法的matlab解法及可视化(一)复变函数图形
  8. 教你用Python将图片转化为字符画!附源代码
  9. 如何将搜狗拼音输入法键盘布局更改成日文106键布局
  10. 看图工具IrfanView