linux spi驱动
硬件平台:三星s5pv210
软件环境:linux系统2.6.32.9内核
在下使用的是a8开发板,linux2.6.32。正在使用spi0驱动一个温度模块(tmp122 半双工),本人没有用iomap的方法直接配置spi寄存器,而是想利用linux自己的spi驱动体系来编写设备驱动。
(1)已经在加上了spi0总线,在/sys/device/platform/下有了spi目录,
(2)将spidev.h,spidev.c抠出来加以修改,编译.ko驱动模块,insmod模块。然后短接MISO-MOSI,在测试的应用程序中使用 ioctl (fd, SPI_IOC_MESSAGE (1), &tr)进行IO同步的方法可以读写数据。应用层的测试代码:
static void
transfer (int fd)
{
int ret;
uint8_t tx[] = {
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0x40, 0x00, 0x00, 0x00, 0x00, 0x95,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xDE, 0xAD, 0xBE, 0xEF, 0xBA, 0xAD,
0xF0, 0x0D,
};
uint8_t rx[ARRAY_SIZE (tx)] = { 0, };
struct spi_ioc_transfer tr = {
.tx_buf = (unsigned long) tx,
.rx_buf = (unsigned long) rx,
.len = ARRAY_SIZE (tx),
.delay_usecs = delay,
.speed_hz = speed,
.bits_per_word = bits,
};
ret = ioctl (fd, SPI_IOC_MESSAGE (1), &tr);
if (ret == 1)
pabort ("can't send spi message");
for (ret = 0; ret < ARRAY_SIZE (tx); ret++)
{
if (!(ret % 6))
puts ("");
printf ("%.2X ", rx[ret]);
}
puts ("");
}
(3)问题来了!为了在内核使用spidev_read,spidev_write等接口,我在spidev_test.c中加入其测试代码后发现spidev_read,spidev_write根本没有读写成功!spidev.c添加的测试代码如下:
static int spidev_probe(struct spi_device *spi)
{
。。。省略。。。
/*test code*/
printk("test 3 start!\n");
if(write(spidev->spi,tx_buf,8)< 0){
printk("spi_write write error!\n");
}
if(read (spidev->spi,rx_buf,8)){
printk("spi_write read error!\n");
}
for(i = 0; i < 8; i++){
printk("{%2x}\n",rx_buf);
}
printk("test 4 start!\n");
for(i = 0; i < 8; i++){
printk("{%2x}\n",spi_w8r8(spidev->spi,i));
}
printk("test end!\n");
。。。省略。。。
return status;
}
小弟就不明白了,由于(2)测试成功,说明spi总线加上了,硬件层的配置也没问题了,而使用probe中传入的spi_device设备在内核进行spidev_read,spidev_write操作却没有成功?难道是那个地方没有设置的原因?
因为是半双工操作,有人提出是需要忽略cs,我不知道是什么意思?