zoukankan      html  css  js  c++  java
  • linux SPI驱动——简单的gpio模拟SPI驱动测试 (二)

       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...
    ");
     168:          return -1;
     169:      }
     170:      
     171:      spi_read(0x75, &data, 1);
     172:      printk("#################mpu9250 spi read id: 0x%x##############
    ", data);
     173:   
     174:      return 0;
     175:  }
     176:   
     177:  static void __exit mpu9250_spi_exit(void)
     178:  {
     179:      printk("mpu9250 exit!
    ");
     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模式

  • 相关阅读:
    使用css的类名交集复合选择器 《转》
    在Web.config或App.config中的添加自定义配置 <转>
    [转]给ListView加上ComboBox或是TextBox控件
    WinForm Timer控件,三级联动[省,市,区]
    WinForm用户窗体
    WinForm 进程 ,线程
    WinForm MDI窗体容器
    WinForm 控件TabelControl对TabelPage页的添加,删除操作
    [转]C#重绘TabControl的Tabpage标签,添加图片及关闭按钮
    WinForm sender初级应用
  • 原文地址:https://www.cnblogs.com/xuyh/p/5956820.html
Copyright © 2011-2022 走看看