linux驱动gpio模拟spi

  • 附上驱动.c代码
  • 挑几个主要函数重点解析
  • 编写程序代码

附上驱动.c代码

#define GEC6818_522_Init_STA     _IO('K',  1)void __iomem      *gpioc_base_va;     //spi要用到引脚的虚拟基址
void __iomem        *gpioc_out_va;
void __iomem        *gpioc_outenb_va;
void __iomem        *gpioc_altfn0_va;
void __iomem        *gpioc_altfn1_va;
void __iomem        *gpioc_pad_va;void spi_init(void){//设置gpioc30输出模式(reset)iowrite32(ioread32(gpioc_altfn1_va)&(~(3<<28)),gpioc_altfn1_va);iowrite32(ioread32(gpioc_outenb_va)|(1<<30),gpioc_outenb_va);//设置gpioc31输出模式(MO)iowrite32(ioread32(gpioc_altfn1_va)&(~(3<<30)),gpioc_altfn1_va);iowrite32(ioread32(gpioc_outenb_va)|(1<<31),gpioc_outenb_va);printk("gec6818_spi_open \n");//设置gpioc8输出模式(片选)iowrite32(ioread32(gpioc_altfn0_va)&(~(3<<16)),gpioc_altfn0_va);iowrite32(ioread32(gpioc_altfn0_va)|(1<<16),gpioc_altfn0_va);iowrite32(ioread32(gpioc_outenb_va)|(1<<8),gpioc_outenb_va);printk("gec6818_spi_open \n");//设置gpioc17输出模式(clk)iowrite32(ioread32(gpioc_altfn1_va)&(~(3<<2)),gpioc_altfn1_va);iowrite32(ioread32(gpioc_altfn1_va)|(1<<2),gpioc_altfn1_va);iowrite32(ioread32(gpioc_outenb_va)|(1<<17),gpioc_outenb_va);//设置gpioc7输入模式(MI)iowrite32(ioread32(gpioc_altfn0_va)&(~(3<<14)),gpioc_altfn0_va);iowrite32(ioread32(gpioc_altfn0_va)|(1<<14),gpioc_altfn0_va);iowrite32(ioread32(gpioc_outenb_va)&(~(1<<7)),gpioc_outenb_va);printk("gec6818_spi_open \n");//看手册或者跟技术确认spi是模式3//片选初始应拉高iowrite32(ioread32(gpioc_out_va)|(1<<8),gpioc_out_va);MFRC522_Initializtion();
}static int  gec6818_spi_open (struct inode * inode, struct file *file)
{spi_init();printk("gec6818_key_release \n");return 0;
}static int  gec6818_spi_release (struct inode * inode, struct file *file)
{return 0;
}static long gec6818_spi_ioctl (struct file *filp, unsigned int cmd, unsigned long args)
{switch (cmd) {case GEC6818_522_Init_STA:{MFRC522_Initializtion();MFRC522Test();}break;}return 0;
}static struct file_operations spi_fops = {.owner      = THIS_MODULE,.open        = gec6818_spi_open,.release            = gec6818_spi_release,.unlocked_ioctl     = gec6818_spi_ioctl,
};static struct miscdevice s3c_adc_miscdev = {.minor       = MISC_DYNAMIC_MINOR,  //指定了ADC的次设备号为131,也可以MISC_DYNAMIC_MINOR,动态分配次设备号.name        = "spi",     //设备名称,/dev/adc.fops        = &spi_fops,//文件操作集
};static int __init spi_drv_init(void){int rt;struct resource *gpioe_res=NULL;rt = misc_register(&s3c_adc_miscdev);if (rt) {printk(KERN_ERR "cannot register miscdev on minor=%d (%d)\n",MISC_DYNAMIC_MINOR, rt);goto err_clk;}//起始地址GPIOE寄存器基址0xC001E000(这个地址可以参考之前那篇文章<三星6818基于uboot的流水灯程序>)//申请大小28字节//申请到的名字为GPIOE_MEMgpioe_res = request_mem_region(0xC001C000,0x28,"GPIOE_MEM");//申请物理内存区if(gpioe_res == NULL){printk("request_mem_region 0xC001E000,0x28 fail\n");goto fail_request_mem_region_gpioc;}//IO内存动态映射,得到物理地址相应的虚拟地址gpioc_base_va = ioremap(0xC001C000,0x28);if(gpioc_base_va == NULL){printk("ioremap 0xC001E000,0x28 fail\n");goto fail_ioremap_gpioc;}//得到每个寄存器的虚拟地址gpioc_out_va  = gpioc_base_va+0x00;gpioc_outenb_va  = gpioc_base_va+0x04;gpioc_pad_va        = gpioc_base_va+0x18;gpioc_altfn0_va   = gpioc_base_va+0x20;gpioc_altfn1_va  = gpioc_base_va+0x24;printk("gec6818 led init\n");return 0;
fail_ioremap_gpioc:release_mem_region(0xC001C000,0x28);//释放物理内存区fail_request_mem_region_gpioc:iounmap(gpioc_base_va);//解除IO内存的动态映射err_clk:misc_deregister(&s3c_adc_miscdev);return rt;
}static void __exit spi_drv_register(void){release_mem_region(0xC001C000,0x28);iounmap(gpioc_base_va);misc_register(&s3c_adc_miscdev);
}//驱动程序的入口:insmod led_drv.ko调用module_init,module_init又会去调用gec6818_key_init。
module_init(spi_drv_init);//驱动程序的出口:rmsmod led_drv调用module_exit,module_exit又会去调用gec6818_key_exit。
module_exit(spi_drv_register);//模块描述
MODULE_AUTHOR("stephenwen88@163.com");           //作者信息
MODULE_DESCRIPTION("gec6818 led driver");     //模块功能说明
MODULE_LICENSE("GPL");                            //许可证:驱动遵循GPL协议

挑几个主要函数重点解析

void spi_init(void){//设置gpioc30输出模式(reset)iowrite32(ioread32(gpioc_altfn1_va)&(~(3<<28)),gpioc_altfn1_va);iowrite32(ioread32(gpioc_outenb_va)|(1<<30),gpioc_outenb_va);//设置gpioc31输出模式(MO)iowrite32(ioread32(gpioc_altfn1_va)&(~(3<<30)),gpioc_altfn1_va);iowrite32(ioread32(gpioc_outenb_va)|(1<<31),gpioc_outenb_va);//设置gpioc8输出模式(片选)iowrite32(ioread32(gpioc_altfn0_va)&(~(3<<16)),gpioc_altfn0_va);iowrite32(ioread32(gpioc_altfn0_va)|(1<<16),gpioc_altfn0_va);iowrite32(ioread32(gpioc_outenb_va)|(1<<8),gpioc_outenb_va);//设置gpioc17输出模式(clk)iowrite32(ioread32(gpioc_altfn1_va)&(~(3<<2)),gpioc_altfn1_va);iowrite32(ioread32(gpioc_altfn1_va)|(1<<2),gpioc_altfn1_va);iowrite32(ioread32(gpioc_outenb_va)|(1<<17),gpioc_outenb_va);//设置gpioc7输入模式(MI)iowrite32(ioread32(gpioc_altfn0_va)&(~(3<<14)),gpioc_altfn0_va);iowrite32(ioread32(gpioc_altfn0_va)|(1<<14),gpioc_altfn0_va);iowrite32(ioread32(gpioc_outenb_va)&(~(1<<7)),gpioc_outenb_va);//看手册或者跟技术确认spi是模式3//片选初始应拉高iowrite32(ioread32(gpioc_out_va)|(1<<8),gpioc_out_va);MFRC522_Initializtion();
}
  1. 这个是模拟spi_Gpio初始化的函数,首先spi有四种模式,需要先查看模块资料确定它是哪个模式通信(附图),从图中就可判断开始片选(slave)引脚和clk的电平值
  2. 根据资料门禁模块为模式3,所以开始我们的clk和片选引脚电平都得为高,然后再根据时序图编写读写代码

    不管上下边缘,前边缘用来采集数据,后一边缘用来输出数据,注意这一点就很好弄了
unsigned char rc522_send_byte(unsigned int d)
{int i=0;unsigned char rx=0;for(i=7; i>=0; i--){//设置MOSI引脚电平if(d & (1<<i))iowrite32(ioread32(gpioc_out_va)|(1<<31),gpioc_out_va);elseiowrite32(ioread32(gpioc_out_va)&(~(1<<31)),gpioc_out_va);//时钟线输出低电平,就产生下降沿,主机通过MOSI引脚输出数据给从机iowrite32(ioread32(gpioc_out_va)&(~(1<<17)),gpioc_out_va);udelay(1);//时钟线输出高电平,就产生上升沿,主机就通过MISO引脚进行数据采样iowrite32(ioread32(gpioc_out_va)|(1<<17),gpioc_out_va);udelay(1);if((ioread32(gpioc_pad_va)&(1<<7)))//输入模式用pad这个寄存器地址去获取引脚电平rx|=1<<i;}return rx;
}

编写程序代码

int main(void){int spi_fd,distance;//打开gec6818_leds设备spi_fd = open("/dev/spi",O_RDWR);if(spi_fd < 0){perror("open /dev/spi:fail");return -1;}while (1) {ioctl(spi_fd,GEC6818_522_Init_STA);usleep(1000*100);}}

其他函数在之前驱动代码都已讲过,可自行参考

[三星6818]gpio模拟spi信号编写门禁卡识别模块驱动相关推荐

  1. 小米手环NFC模拟加密门禁卡

    小米手环NFC模拟加密门禁卡会提示"此卡为加密卡,无法模拟". 一个方法: 1.首先找一台带nfc功能的小米手机,模拟加密门禁卡. 2.打开另一台小米手机的小米运动,或者Zepp ...

  2. id门禁卡复制到手机_怎么将手机当做门禁卡使用?给大家详解手机设置门禁卡功能...

    随着科技的发展,手机的功能是越来越强大了 . 门禁卡,相信大家都不陌生.进出小区都需要刷卡,自从手机可以使用微信跟支付宝支付功能以来,很少人携带钱包出门,一部手机便可以打车.吃饭付钱 等.银行卡跟身份 ...

  3. 外设驱动库开发笔记43:GPIO模拟SPI驱动

      SPI总线是我们常用的串行设备接口,一般情况下我们都会适应硬件SPI接口,但有些时候当硬件端口不足时,我们也希望可以使用软件来模拟SPI硬件接口,特别是要求不是很高的时候.在这一篇中我们将来讨论如 ...

  4. 用GPIO模拟SPI接口读取传感器数据

    本文基于平头哥开发板RVB2601,简要介绍了用GPIO模拟SPI时序逻辑,实现SPI协议,按照特定温度传感器的时序,读取其数据,及示例程序 一.概述 SPI(Serial Peripheral In ...

  5. GPIO模拟SPI通讯接口

    一.SPI总述 SPI 是一种允许一个主设备启动一个与从设备的同步通讯的协议,从而完成数据的交换.也就是说,SPI是一种规定好的通讯方式.这种通信方式的优点是占用端口较少,一般4根就够基本通讯了.同时 ...

  6. SPI总线协议、SPI时序图详解、GPIO模拟SPI

    SPI,是英语Serial Peripheral Interface的缩写,顾名思义就是串行外围设备接口.SPI,是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚 ...

  7. 【全志T113-S3_100ask】15-2 linux系统gpio模拟spi驱动屏幕——ILI9341

    [全志T113-S3_100ask]15-2 linux系统gpio模拟spi驱动屏幕--ILI9341 背景 (一)查阅参考文档 (二)使能内核模块 (三)修改设备树 (四)测试 (五)后语 背景 ...

  8. 蓝色圆形门禁卡怎么模拟_手把手教你把门禁卡复制到手机,跟实体门禁卡说拜拜...

    前言 随着几年前NFC在手机上的逐渐普及,厂商针对NFC短距离即时通讯的特性发明了许多应用.比如我们可以通过手机的NFC功能模拟公交卡信号,从而实现用手机刷公交卡进站乘车.今天我就来和大家聊一聊NFC ...

  9. 小米手机、华为手机、小米手环模拟门禁卡 — 手机软件教程

    小米手机.华为手机.小米手环模拟门禁卡 - 手机软件教程 手机模拟门禁卡 - 手机软件教程 一.软硬件准备 NFC Tool 手机上的IC卡读写编辑软件,搭配蓝牙读卡器或者OTG读卡器,可实现在手机上 ...

  10. nfc pm3 模拟加密门禁卡_华为手机NFC的妙用,模拟门禁卡、公交卡、银行卡,电子证件等...

    你关注的才是晋圈 出门带门禁卡.银行卡.身份证--这些东西真的是很麻烦,有没有一种方法可以把它们都装下?有!只要一部手机,出门不带包,各种证件,各种卡通通装进手机. 首先要你的手机支持NFC功能,我们 ...

最新文章

  1. redhat 复制文件夹及子文件夹_python文件夹怎么操作呢??(建议详读)
  2. Android 自定义长按响应时间
  3. 使用伪指令#pragma pack
  4. 产品策划系列:洞察需求(四)
  5. c语言程序设计一元二次函数,计算一元二次函数的根,大家看看那里有错了。。。。...
  6. 计算机之父童年的故事ppt,《“计算机之父”童年的故事》PPT课件2
  7. 连接真机开发安卓(Android)移动app MUI框架 反馈意见、忘记密码、登录、底部选项卡、联系我们、导航等页面代码可拿——混合式开发(六)
  8. ASP.NET MVC 后台中 设置 js提示
  9. Linux中 查看mysql配置文件位置
  10. 什么是数据库?什么是数据库管理系统? 说明两者的区别和联系。
  11. scara机器人动荷载_【机器人在线】SCARA机械结构参数计算说明 下
  12. 08.音频系统:第006课_音频系统HAL分析:第001节_HAL之框架
  13. 起步 —— 种一棵树最好的时间是十年前
  14. java文件边读边写_[Java教程]node.js 利用流实现读写同步,边读边写
  15. dock接口_回看手机接口发展史:TypeC将实现大一统?
  16. 用于音频信号去噪的谱相减和陷波滤波的比较(Matlab代码实现)
  17. mysql误删除表后无法重建
  18. 论文阅读(13) 水母游泳过程中的神经机械波共振(2021)
  19. php实现远程下载文件到本地服务器指定目录
  20. 如何利用GitHub搜索敏感信息

热门文章

  1. apk编辑器找Android,教你用安卓神器APK编辑器去除程序广告
  2. RecyclerView自定义分割线实战
  3. 小技巧:两种方式快速实现平滑涂鸦画板
  4. latch: cache buffers chains问题分析
  5. 摄像机成像原理(模型)与标定
  6. Centos下查看和修改网卡Mac地址
  7. php5.4.45连接mssql2000,用php在linux下连接mssql2000(转)
  8. 金山云直播问答解决方案来了!让客户一天上线
  9. java 简繁体转换库_java简体字繁体字互相转换(附jar包下载资源~)
  10. 【系统】右键桌面图标,转圈后,资源管理器就崩溃,桌面就重新刷新