1:  /*
   2:   * Add by xuyonghong for duotin car radio fm 
   3:   * Copyright (C) 2016-5-24    xuyonghong@duotin.com                                                                                 
   4:   *
   5:   */
   6:  #include <linux/init.h>
   7:  #include <linux/miscdevice.h>
   8:  #include <linux/version.h>
   9:  #include <linux/kernel.h>
  10:  #include <linux/slab.h>
  11:  #include <linux/fs.h>
  12:  #include <linux/errno.h>
  13:  #include <linux/types.h>
  14:  #include <asm/io.h>
  15:  #include <linux/wait.h>
  16:  #include <linux/sched.h>
  17:  #include <linux/interrupt.h>
  18:  #include <linux/delay.h>
  19:  #include <linux/gpio.h>
  20:  #include <linux/i2c-gpio.h>
  21:   
  22:  #define NCS      GPIO_PB(2)                     //定义SS所对应的GPIO接口编号  
  23:  #define SCLK     GPIO_PB(0)                     //定义SCLK所对应的GPIO接口编号  
  24:  #define MOSI     GPIO_PB(4)                     //定义SCLK所对应的GPIO接口编号  
  25:  #define MISO     GPIO_PB(01)                    //定义MISO所对应的GPIO接口编号  
  26:  #define OUTP    1                               //表示GPIO接口方向为输出  
  27:  #define INP     0                                   //表示GPIO接口方向为输入  
  28:   
  29:  //gpio_direction_output(unsigned gpio, int value)
  30:  //gpio_direction_input(unsigned gpio)
  31:  #define  set_gpio_value gpio_set_value
  32:  #define  get_gpio_value gpio_get_value
  33:   
  34:   
  35:  static int spi_request_gpio(void)
  36:  {
  37:   
  38:      if (gpio_request(NCS, "spi_ncs") < 0) {
  39:          return -1;
  40:      }
  41:      if (gpio_request(SCLK, "spi_sclk") < 0) {
  42:          return -1;
  43:      }
  44:      if (gpio_request(MOSI , "spi_mosi") < 0) {
  45:          return -1;
  46:      }
  47:      if (gpio_request(MISO, "spi_miso") < 0) {
  48:          return -1;
  49:      }
  50:      return 0;
  51:  }
  52:   
  53:  /* SPI端口初始化 */  
  54:  static void spi_init(void)  
  55:  {  
  56:      gpio_direction_output(NCS, 1);  
  57:      gpio_direction_output(SCLK, 1);  
  58:      gpio_direction_output(MOSI, 0);  
  59:      gpio_direction_input(MISO);  
  60:      gpio_set_value(SCLK, 1);                    
  61:      gpio_set_value(MOSI, 0);  
  62:  }  
  63:   
  64:  /*  
  65:  从设备使能  
  66:  enable:为1时,使能信号有效,SS低电平  
  67:  为0时,使能信号无效,SS高电平  
  68:  */  
  69:  void ss_enable(int enable)  
  70:  {  
  71:      if (enable)  
  72:          set_gpio_value(NCS, 0);                  //SS低电平,从设备使能有效  
  73:      else  
  74:          set_gpio_value(NCS, 1);                  //SS高电平,从设备使能无效  
  75:  }  
  76:   
  77:   
  78:  /* SPI字节写 */  
  79:  void spi_write_byte(unsigned char b)  
  80:  {  
  81:      int i;  
  82:      for (i=7; i>=0; i--) {  
  83:          set_gpio_value(SCLK, 0); 
  84:          udelay(5);//延时  
  85:          set_gpio_value(MOSI, b&(1<<i));         //从高位7到低位0进行串行写入  
  86:          udelay(5);//延时  
  87:          set_gpio_value(SCLK, 1);                // CPHA=1,在时钟的第一个跳变沿采样  
  88:          udelay(5);//延时       
  89:      }  
  90:  }  
  91:   
  92:   
  93:  /* SPI字节读 */  
  94:  unsigned char spi_read_byte(void)  
  95:  {  
  96:       int i;  
  97:       unsigned char r = 0;  
  98:       for (i=0; i<8; i++) {  
  99:           set_gpio_value(SCLK, 0);  
 100:          udelay(5);//延时                              //延时  
 101:          set_gpio_value(SCLK, 1);                // CPHA=1,在时钟的第一个跳变沿采样  
 102:          udelay(5);//延时  
 103:          r = (r <<1) | get_gpio_value(MISO);         //从高位7到低位0进行串行读出  
 104:          udelay(5);//延时   
 105:      }  
 106:      return r;
 107:  }
 108:   
 109:  /*  
 110:  SPI读操作  
 111:  buf:写缓冲区  
 112:  len:写入字节的长度  
 113:  */  
 114:  void spi_write (unsigned char reg_addr, unsigned char* buf, int len)
 115:  {
 116:      unsigned char reg_write_addr = reg_addr;
 117:      int i;  
 118:      
 119:      /* SPI端口初始化 */  
 120:      spi_init();
 121:      udelay(5);
 122:      
 123:      ss_enable(1);                       //从设备使能有效,通信开始  
 124:      udelay(5);                            //延时  
 125:      
 126:      spi_write_byte(reg_write_addr);        //写寄存器写地址
 127:                                  
 128:      //写入数据  
 129:      for (i=0; i<len; i++)  
 130:         spi_write_byte(buf[i]);  
 131:      udelay(5);//延时    
 132:      ss_enable(0);  
 133:  }
 134:   
 135:   
 136:  /*  
 137:  SPI读操作  
 138:  buf:读缓冲区  
 139:  len:读入字节的长度  
 140:  */  
 141:  void spi_read(unsigned char reg_addr, unsigned char* buf, int len)  
 142:  {  
 143:      int i;  
 144:      unsigned char reg_read_addr = 0x80 | reg_addr; //读的时候寄存地址最高位置1
 145:      
 146:      /* SPI端口初始化 */  
 147:      spi_init();
 148:      udelay(5);
 149:      
 150:      ss_enable(1);                           //从设备使能有效,通信开始  
 151:      udelay(5);//延时                                  //延时
 152:   
 153:      spi_write_byte(reg_read_addr);        //写寄存器读地址
 154:      
 155:      //读入数据  
 156:      for (i=0; i<len; i++)  
 157:          buf[i] = spi_read_byte();  
 158:      udelay(5);//延时    
 159:      ss_enable(0);                           //从设备使能无效,通信结束  
 160:  }
 161:   
 162:  static int __exit mpu9250_spi_init(void)
 163:  {
 164:      unsigned char data = 0x0;
 165:   
 166:      if (spi_request_gpio()) {
 167:          printk("mpu9250 spi initializer failure...\n");
 168:          return -1;
 169:      }
 170:      
 171:      spi_read(0x75, &data, 1);
 172:      printk("#################mpu9250 spi read id: 0x%x##############\n", data);
 173:   
 174:      return 0;
 175:  }
 176:   
 177:  static void __exit mpu9250_spi_exit(void)
 178:  {
 179:      printk("mpu9250 exit!\n");
 180:  }
 181:   
 182:  module_init(mpu9250_spi_init);
 183:  module_exit(mpu9250_spi_exit);
 184:  MODULE_AUTHOR("xuyonghong@duotin.com");
 185:  MODULE_LICENSE("GPL");
 186:   

测试结果:#################mpu9250 spi read id: 0x71##############

以上SPI设备工作在mode3模式

linux SPI驱动——简单的gpio模拟SPI驱动测试 (二)的更多相关文章

  1. linux SPI驱动——gpio模拟spi驱动(三)

    一:首先在我的平台注册platform_device,保证能让spi-gpio.c能执行到probe函数. 1: struct spi_gpio_platform_data { 2: unsigned ...

  2. GPIO模拟SPI

    上次用gpio模拟i2c理解i2c协议.相同的,我用gpio模拟spi来理解spi协议. 我用的是4线spi,四线各自是片选.时钟.命令/数据.数据. 数据在时钟上升沿传递,数据表示的是数据还是命令由 ...

  3. am335x gpio 模拟 spi 驱动添加

    kernel 内 make menuconfig // make menuconfig Device Drivers ---> [*] SPI support ---> <*> ...

  4. gpio模拟i2c驱动

    前段时间做项目,需要gpio模拟i2c通信,最后参考了一些资料,然后编写了一个程序.现在发出来,以免以后忘记,也为一些需要的朋友提供参考.不喜勿喷哈. /* 说明:该程序是基于atmel公司的sama ...

  5. linux enc28j60网卡驱动移植(硬件spi和模拟spi)

    本来想移植DM9000网卡的驱动,无奈硬件出了点问题,通过杜邦线链接开发板和DM9000网卡模块,系统上电,还没加载网卡驱动就直接崩溃了,找不到原因...刚好手上有一个enc28j60的网卡模块,于是 ...

  6. STM32-24位AD7799驱动之手册代码详解,支持模拟SPI和硬件SPI

    1.AD7799介绍 AD7799结构图如下所示: 其中REFIN参考电压建议为2.5V, REFIN电压低于0.1V时,则差分输入ad值就无法检测了,如下图所示: 注意: 如果REG_CONFIG的 ...

  7. LPC4370使用学习:GPIO的引脚功能使用,和12864OLED模拟I2C驱动

    一: 手中有块LPC4370的开发板,因为便宜,所以引脚引出的不多,而且只有基本的底板资源驱动代码和例程. 看着手册和例程看了老半天,写程序写了半天,结果GPIO老是驱动不起来,因为引脚配置寄存器中有 ...

  8. OLED的波形曲线、进度条、图片显示(STM32 HAL库 模拟SPI通信 5线OLED屏幕)详细篇

    少废话,先上效果图 屏幕显示效果         全家福 一.基础认识及引脚介绍 屏幕参数: 尺寸:0.96英寸 分辨率:128*64 驱动芯片:SSD1306 驱动接口协议:SPI 引脚说明: 二. ...

  9. S5PV210之GPIO模拟I2c时序之pcf8591与at24xx linux3.0.8驱动

    目录:一. 说明 二. 驱动程序说明及问题 三. 案例一       四. 案例二 一. 说明 mini210开发板上带了at24c08, 看了linux内核自带的at24.c的驱动程序,编译下载到看 ...

随机推荐

  1. 洛谷P4364 [九省联考2018]IIIDX 【线段树】

    题目 [题目背景] Osu听过没?那是Konano最喜欢的一款音乐游戏,而他的梦想就是有一天自己也能做个独特酷炫的音乐游戏.现在 ,他在世界知名游戏公司KONMAI内工作,离他的梦想也越来越近了.这款 ...

  2. Lua local function与function区别

    1 使用function声明的函数为全局函数,在被引用时可以不会因为声明的顺序而找不到 2 使用local function声明的函数为局部函数,在引用的时候必须要在声明的函数后面 例子: 下面这段代 ...

  3. 【NOIP2016练习】T2 跑跑步 (数论)

    : 这场的难度是从高到低的 ..]of longint; n,m,i,ans:longint; function gcd(x,y:longint):longint; var r:longint; be ...

  4. 【NOIP2016练习】T3 tree (树形DP)

    题意:一棵有N个结点的树,每个节点上有权值c[i] 需要选出若干结点,对于任意结点他的所有祖先都被选取且选取总个数不能超过lim 在此前提下使权值和最大 n,lim<=3000 思路:WA了1次 ...

  5. es6总结(七)--proxy & reflect

  6. gzip: stdin: unexpected end of file tar: 归档文件中异常的 EOF

    gzip: stdin: unexpected end of file tar: 归档文件中异常的 EOF 问题描述: 使用tar命令解压文件时,报错: gzip: stdin: unexpected ...

  7. WKWebView与js交互中产生的内存泄漏

    最近开发中突然发现富文本帖子详情内存没有释放掉,找了好久问题都没找到,终于今天发现了问题,先上一点代码片段 WKWebViewConfiguration *configuration = [[WKWe ...

  8. 微信关注事件bug记录

    年前研究了一下微信带参数的二维码,处理邀请注册成会员等的方式 通过带参数的二维码触发微信的 subscribe(订阅) 或者 SCAN  (已经订阅后)事件,然后抓取eventKey(记录邀请人的信息 ...

  9. R语言实战读书笔记(十三)广义线性模型

    # 婚外情数据集 data(Affairs, package = "AER") summary(Affairs) table(Affairs$affairs) # 用二值变量,是或 ...

  10. ABP开发框架前后端开发系列---(2)框架的初步介绍

    在前面随笔<ABP开发框架前后端开发系列---(1)框架的总体介绍>大概介绍了这个ABP框架的主要特点,以及介绍了我对这框架的Web API应用优先的一些看法,本篇继续探讨ABP框架的初步 ...