spi 学习

      对于SPI,感觉熟悉协议比较重要,SPI总线可以配置成单主单从,单主多从,互为主从。
以下网页比较简单的介绍了该协议。
http://www.dzkf.cn/html/zonghejishu/2007/0829/2544.html

     简单的,对主极端来说,发送数据的同时也在从slave接受数据,比如说:MCU上升沿发送,下降沿接收。

下面就以同事写的spi_eeprom.c(spi 读写 EEPROM)程序来分析,SPI总线配置的是单主单从的模式:

1.模块初始化
static int __init ssi_eeprom_init(void)
{
    int  result;

    //注册字符设备
    result = clx_register_chrdev(MAJOR_NR,  DEVICE_NAME,  &ssi_eeprom_fops, NULL);
    if (result < 0)
    {
        printk(KERN_ERR DEVICE_NAME ":SSI Unable to get major %d/n", MAJOR_NR );
        return result;
    }
    printk("SSI: SSI EEPROM driver registered !MAJOR_NR=%d, DEVICE_NAME=%s/n",MAJOR_NR,DEVICE_NAME);

    return 0;
}

static void __exit ssi_eeprom_exit(void)
{
    clx_unregister_chrdev(MAJOR_NR, DEVICE_NAME);
}

module_init(ssi_eeprom_init);
module_exit(ssi_eeprom_exit);

2.文件操作
static struct file_operations ssi_eeprom_fops =
{
    open:       ssi_eeprom_open,
    release:    ssi_eeprom_release,
    read:       ssi_eeprom_read,
    write:      ssi_eeprom_write
};

*******************************************
//spi 初始化

static int ssi_eeprom_open(struct inode *inode, struct file *filp)
{

    printk("---ssi eeprom open---/n");
    if (SpiDevices.usage == 0)
    {
        printk("----SpiDevices.usage == 0---/n");
//       __gpio_as_ssi();  
       ssi_set_spi_fix();
       __ssi_select_ce();
       __ssi_enable();
    }
       __ssi_enable_receive();
       SpiDevices.usage++;
       __ssi_disable_receive();
    return 0;
}

********************************************


********************************************

 //spi读操作
static ssize_t ssi_eeprom_read(struct file *filp, char *buf, size_t size, loff_t *l)
{
    
    unsigned char *kbuf,*kbufa;
        unsigned char temp;
    size_t ADDR;

    if(size>256)
        return -EINVAL;
    kbuf = kmalloc(size, GFP_KERNEL);
    if (!kbuf)
    {
        return -ENOMEM;
    }
    ADDR = 0x00;
    kbufa = kbuf ;
    __ssi_enable_receive();

 //从EEPROM 读取 SIZE大小的数据
    while(ADDR<size)
    {
          __ssi_flush_rxfifo();
          __ssi_transmit_data(0x03);  //向SSI DATA REGISTER 写0x03,ADDR,OXFF告诉EEPROM,我spi要来read数据了,至于为什么要写这些个值EEPROM datasheet上有说明
          __ssi_transmit_data(ADDR);
          __ssi_transmit_data(0xff);
          while((!(__ssi_transfer_end())) || __ssi_is_busy());

          temp = REG_SSI_DR;   // 读 SSI DATA REGISTER ,获得数据
          temp = REG_SSI_DR;
          *kbuf = REG_SSI_DR;

          ADDR++ ;
          kbuf++ ;
    }
    __ssi_disable_receive();
   kbuf = kbufa ;

    if (copy_to_user(buf, kbuf, size)) {
        kfree(kbuf);
        return -EFAULT;
    }

    kfree(kbuf);

    return size;
}

***************************************
  //spi 写也差不多,关键是要看从设备对应的规定

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值