历史上的今天
返回首页

历史上的今天

今天是:2024年10月12日(星期六)

正在发生

2018年10月12日 | Tiny210驱动之NAND_FLASH驱动程序

2018-10-12 来源:eefocus

tiny_nand.c驱动源码:

#include "linux/module.h"

#include "linux/types.h"

#include "linux/init.h"

#include "linux/kernel.h"

#include "linux/string.h"

#include "linux/ioport.h"

#include "linux/platform_device.h"

#include "linux/delay.h"

#include "linux/err.h"

#include "linux/slab.h"

#include "linux/clk.h"

#include "linux/cpufreq.h"

#include "linux/mtd/mtd.h"

#include "linux/mtd/nand.h"

#include "linux/mtd/nand_ecc.h"

#include "linux/mtd/partitions.h"

#include "asm/io.h"

#include "plat/regs-nand.h"

#include "plat/nand.h"

static unsigned long *clk_gate_ip1;

static unsigned long *clk_gate_block;

static unsigned long *mp0_3con;

static struct mtd_partition tiny_nand_part[] = {

    [0] = {

        .name    = "bootloader",

        .size    = SZ_4M,

        .offset    = 0,

    },

    [1] = {

        .name    = "kernel",

        .size    = SZ_8M,

        .offset    = MTDPART_OFS_APPEND,

    },

    [2] = {

        .name    = "root",

        .size    = MTDPART_SIZ_FULL,

        .offset    = MTDPART_OFS_APPEND,

    },

};

struct nand_regs {

    unsigned long nfconf;

    unsigned long nfcont;

    unsigned long nfcmmd;

    unsigned long nfaddr;

    unsigned long nfdata;

    unsigned long nfmeccd0;

    unsigned long nfmeccd1;

    unsigned long nfseccd;

    unsigned long nfsblk;

    unsigned long nfeblk;

    unsigned long nfstat;

    unsigned long nfeccerr0;

    unsigned long nfeccerr1;

};

static struct nand_regs *nand_regs;

static struct nand_chip *tiny_nand_chip;

static struct mtd_info *tiny_nand_mtd;

static void tiny_nand_select_chip(struct mtd_info *mtd, int chipnr)

{

    if(chipnr == -1)

    {

        //取消选择

        nand_regs->nfcont |= (1<<1);

    }

    else

    {

        //选中芯片

        nand_regs->nfcont &= ~(1<<1);

    }

}

static void tiny_nand_cmd_ctrl(struct mtd_info *mtd, int dat,unsigned int ctrl)

{

    if (ctrl & NAND_CLE)

    {

        //发命令

        nand_regs->nfcmmd = dat;

    }

    else

    {

        //发地址

        nand_regs->nfaddr = dat;

    }

}

static int tiny_nand_dev_ready(struct mtd_info *mtd)

{

    //等待命令的操作完成

    return (nand_regs->nfstat & (1<<0));

}

static int tiny_nand_init(void)

{

    //1.分配一个nand_chip结构体

    tiny_nand_chip = kzalloc(sizeof(struct nand_chip),GFP_KERNEL);

    nand_regs = ioremap(0xB0E00000,sizeof(struct nand_regs));

    mp0_3con         = ioremap(0xE0200320,4);

    clk_gate_ip1     = ioremap(0xE0100464,4);

    clk_gate_block = ioremap(0xE0100480,4);

    //2.设置

    //

    // 初始化nand_chip结构体中的函数指针

    // 提供选中芯片,发命令,发地址,读数据,写数据,等待等操作

    tiny_nand_chip->select_chip    = tiny_nand_select_chip;

    tiny_nand_chip->cmd_ctrl        = tiny_nand_cmd_ctrl;

    tiny_nand_chip->IO_ADDR_R   = &nand_regs->nfdata;

    tiny_nand_chip->IO_ADDR_W  = &nand_regs->nfdata;

    tiny_nand_chip->dev_ready     = tiny_nand_dev_ready;

    tiny_nand_chip->ecc.mode      = NAND_ECC_SOFT;

    //tiny_nand_chip->ecc.mode      = NAND_ECC_NONE;

    

    //3.硬件相关

    //使能时钟

    *clk_gate_ip1     = 0xffffffff;

    *clk_gate_block = 0xffffffff;

    // 设置相应GPIO管脚用于Nand 

    *mp0_3con = 0x22222222;

    // 设置时序 

#define TWRPH1    1

#define TWRPH0    1

#define TACLS        1

    nand_regs->nfconf |= (TACLS<<12) | (TWRPH0<<8) | (TWRPH1<<4);

    // AddrCycle[1]:1 = 发送地址需要5个周期

    nand_regs->nfconf |= 1<<1;

    // MODE[0]:1     = 使能Nand Flash控制器

    // Reg_nCE0[1]:1 = 取消片选

    nand_regs->nfcont |= (1<<1)|(1<<0);

        

    //4.使用

    tiny_nand_mtd = kzalloc(sizeof(struct mtd_info), GFP_KERNEL);

    tiny_nand_mtd->owner = THIS_MODULE;

    tiny_nand_mtd->priv = tiny_nand_chip;

    nand_scan(tiny_nand_mtd, 1);

    //5.添加分区

    add_mtd_partitions(tiny_nand_mtd, tiny_nand_part, 3);

    return 0;

}

static void tiny_nand_exit(void)

{

    del_mtd_partitions(tiny_nand_mtd);

    kfree(tiny_nand_mtd);

    iounmap(nand_regs);

    kfree(tiny_nand_chip);

}

module_init(tiny_nand_init);

module_exit(tiny_nand_exit);

MODULE_LICENSE("GPL");


推荐阅读

史海拾趣

Densei-Lambda (TDK)公司的发展小趣事

以下是关于Densei-Lambda(现更名为TDK-Lambda)公司在电子行业发展的五个相关故事,每个故事都尽可能客观地描述了事实,没有加入主观评价:

  1. 日本电子存储器工业株式会社的起步

TDK-Lambda的前身可以追溯到1970年成立的日本电子存储器工业株式会社。当时,该公司主要致力于电子存储器的研发和生产。在创始人及团队的共同努力下,公司逐渐在电子存储领域取得了一席之地,为后续的发展奠定了坚实的基础。

  1. 电盛兰达株式会社的成立与成长

随着时间的推移,日本电子存储器工业株式会社逐渐将业务重心转向电源领域,并于1990年代更名为电盛兰达株式会社。在电源领域,电盛兰达凭借其出色的技术实力和产品品质,迅速获得了市场的认可。同时,公司不断扩大生产规模,提高生产效率,逐渐在电源市场上占据了一席之地。

  1. TDK集团的收购与融合

2005年,TDK集团宣布收购英国Invensys旗下的Lambda集团,包括Lambda USA、Lambda Europe以及电盛兰达株式会社。这一收购不仅扩大了TDK集团的业务范围,也进一步巩固了其在电源领域的领先地位。随后,TDK集团和电盛兰达宣布将双方的电源产品统一为TDK-Lambda品牌,共同进行推广和销售。

  1. 无锡东电化兰达电子有限公司的成立与发展

1995年,电盛兰达株式会社在中国投资设立了全资子公司——无锡东电化兰达电子有限公司。该公司位于无锡新加坡工业园,专注于开关稳压电源的开发、生产和销售。多年来,无锡东电化兰达电子有限公司凭借总公司强大的技术后盾和先进的管理理念,不断提高生产效率和产品质量,已成为集团内最重要的基地之一。

  1. TDK-Lambda电源新品的创新与发展

近年来,TDK-Lambda不断推出具有创新性的电源产品,以满足市场的多样化需求。例如,公司推出的DRB系列DIN导轨安装电源新增了三相交流输入和高功率型号,具有过流保护、低输入浪涌电流等特点,广泛应用于开关柜、分布式机械和工业系统等领域。这些新品的推出不仅进一步巩固了TDK-Lambda在电源领域的领先地位,也为公司带来了更广阔的发展空间。

驰芯微(CHIPWISE)公司的发展小趣事

驰芯微公司一直注重技术研发和产品创新。公司拥有一支高素质的研发团队,不断在芯片设计、制造和封装等领域取得突破。其中,车规级霍尔传感器芯片XL3600系列和车规级32位微控制器MCU芯片XL6600系列是公司的明星产品。这些产品不仅性能卓越,而且可靠性高,赢得了客户的广泛认可。此外,驰芯微还不断推出新产品,如新能源动力多节电池组监控器BMS AFE芯片XL8812/XL8820系列等,进一步丰富了公司的产品线。

Elpac公司的发展小趣事

Elpac公司深知人才是企业发展的核心动力。因此,公司高度重视人才培养和团队建设。公司建立了完善的人才培训体系,为员工提供多样化的培训和发展机会。同时,公司还鼓励员工积极参与各种创新活动和竞赛,激发员工的创新精神和创造力。这种积极向上的企业文化吸引了大量优秀人才加入Elpac公司,为公司的持续发展提供了有力保障。

AMI Semiconductor公司的发展小趣事

在电子行业的激烈竞争中,Elpac公司凭借其在电源管理领域的技术革新,逐渐崭露头角。公司创始人李明在创办之初就坚信,只有不断创新才能在市场中立足。他带领团队深入研究市场需求,不断推出具有创新性的电源管理产品。其中,一款高效节能的电源转换器在市场上引起了广泛关注,其出色的性能和稳定性赢得了客户的青睐。随着产品的热销,Elpac公司逐渐在电子行业中建立了自己的品牌地位。

Etron公司的发展小趣事

进入21世纪,电子行业的竞争日益激烈,钰创科技意识到必须不断进行技术创新才能保持竞争优势。公司加大了研发投入,成功开发出了一系列先进的内存芯片和系统芯片技术。这些技术突破不仅提升了产品的性能和质量,也帮助公司赢得了更多国际客户的认可和信任。

Gaomi Xinghe Electronics公司的发展小趣事

背景:在电子产品市场竞争日益激烈的背景下,Galaxy深知技术创新和品质提升的重要性。为了进一步提升产品性能,公司决定寻求与行业顶尖厂商的合作。

行动:Galaxy与瑞士著名散热器厂商“Arctic Cooling”建立了战略合作伙伴关系,共同推出了备受瞩目的影驰GeForce6系列产品。这款产品在散热性能上实现了重大突破,为用户带来了更加稳定、高效的使用体验。

成果:凭借出色的性能和口碑,影驰GeForce6系列产品迅速在市场上走红,不仅巩固了Galaxy在显卡市场的领先地位,还极大地提升了公司在行业内的影响力。

问答坊 | AI 解惑

FPGA小工具整理——32位小数计数器

32位小数计数器 用于仿真,实现任意分频。…

查看全部问答>

编译错误 command line error D8004 '/I' requires an argument

各位达人, 编译时出现如上错误,究竟怎么回事? 谢谢解答!…

查看全部问答>

WINCE6.0驱动问题

有篇文章(具体原文在那,我找不到了)提到在FLASH驱动中函数 BOOL  FMD_OEMIoControl(DWORD dwIoControlCode, PBYTE pInBuf, DWORD nInBufSize, PBYTE pOutBuf, DWORD nOutBufSize, PDWORD pBytesReturned) { ......... ......... ...…

查看全部问答>

行情还得猜猜猜!

     阿牛哥十二月份拜访客户,参加芯片原厂研讨会,看到很多大厦和酒店里圣诞树已经竖起,新年快到了。新年值得憧憬,新年值得期待,2011年电子元器件原厂和分销会有哪些值得期待和预测的事情呢?先举几个例子说说猜测和预测 ...…

查看全部问答>

急,FPGA编程求助

我想编一个数码管动态显示的程序,但是下到板子(epm240t100c5)里一直跑不起来,也不知道是什么问题,求高手指导,谢谢。     module dig_show(clk,rst,csm_1,csm_2,db);input clk;         ...…

查看全部问答>

【MSP430共享】MSP430经典讲解

初学单片机的时候就是看的这个资料  很详细  很适合新手入门让你学习的  但若干配上一个开发板  学习起来效果更好  …

查看全部问答>

易电源试用报告3.2:LMZ12010初试大电流输出:纹波较大,滤波用电感烧毁(芯片外)

从同学那儿弄来的500W 20Ω瓷盘变阻器派上用场了,但是要让LMZ12010输出吓人的10A电流的话,这个电阻值还是有点大,滑动端转到边缘上达到几欧姆,再小就要碰到另一端了。由于时间匆忙,今晚只粗略观察了一下,并没有正式测量数据。使用的最小电阻是 ...…

查看全部问答>

对TI官方MBUS主机端发送电路的疑问

本帖最后由 yushengjiexy 于 2014-10-9 08:29 编辑 芯片IC202是如何检测总线电流变化,从而通过TIP117扩流的?为什么手册上说“The starting point for such regulation is the charged state of the capacitor C202. Voltage changes on the bus ...…

查看全部问答>

大家来看图

自己画的PT100温度测量电路,希望大神给点指导意见 …

查看全部问答>

采样信号的数字滤波设计和DSP 实现

采样信号的数字滤波设计和DSP 实现 …

查看全部问答>