对于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 写也差不多,关键是要看从设备对应的规定
spi 学习
最新推荐文章于 2009-04-20 10:49:00 发布