mini2440 SPI驱动移植 既自己总结的应用层的操作

mini2440 SPI驱动移植

分类: Linux 嵌入式 SPI   674人阅读  评论(6)  收藏  举报

最近项目需要,需要在mini2440上移植SPI驱动,板子需要驱动SPI设备,上网找了很多资源,但是很多都是有问题,最终在基本理解驱动结构的前提下,将SPI驱动顺利移植到mini2440。

,我使用的内核版本是2.6.32.2,这个版本和2.6。29不一样,网上很多版本都是关于2.6.29,如果完全按照网上步骤,编译会出现问题,我做的步骤如下:

1,在Linux Source Code中修改arch/arm/mach-s3c2440/mach-mini2440.c文件,加入头文件:

[cpp]  view plain copy
  1. #include <linux/spi/spi.h>  
  2. #include <../mach-s3c2410/include/mach/spi.h>  
然后加入如下代码:

[cpp]  view plain copy
  1. static struct spi_board_info s3c2410_spi0_board[] =  
  2. {  
  3.         [0] = {  
  4.                 .modalias = "spidev",  
  5.                 .bus_num = 0,  
  6.                 .chip_select = 0,  
  7.                 .irq = IRQ_EINT9,  
  8.                 .max_speed_hz = 500 * 1000,  
  9.                 }  
  10. };  
  11.   
  12. static struct s3c2410_spi_info s3c2410_spi0_platdata = {  
  13.         .pin_cs = S3C2410_GPG(2),  
  14.         .num_cs = 1,  
  15.         .bus_num = 0,  
  16.         .gpio_setup = s3c24xx_spi_gpiocfg_bus0_gpe11_12_13,  
  17. };  
  18.   
  19. static struct spi_board_info s3c2410_spi1_board[] =  
  20. {  
  21.         [0] = {  
  22.                 .modalias = "spidev",  
  23.                 .bus_num = 1,  
  24.                 .chip_select = 0,  
  25.                 .irq = IRQ_EINT2,  
  26.                 .max_speed_hz = 500 * 1000,  
  27.                 }  
  28. };  
  29.   
  30.   
  31. static struct s3c2410_spi_info s3c2410_spi1_platdata = {  
  32.         .pin_cs = S3C2410_GPG(3),  
  33.         .num_cs = 1,  
  34.         .bus_num = 1,  
  35.         .gpio_setup = s3c24xx_spi_gpiocfg_bus1_gpg5_6_7,  
  36. };  
这里需要了解驱动架构,其中移植过程中容易出问题的地方时S3C2410_GPG(2)和S3C2410_GPG(3)两处地方,网上一般给的源代码是S3C2410_GPG2,这在2.6.29中可行,但是在2.6.32源代码中没有定义S3C2410_GPG2宏定义,要使用S3C2410_GPG(2)宏定义。

在mini2440_devices[]平台数组中添加如下代码:

[cpp]  view plain copy
  1. &s3c_device_spi0,  
  2. &s3c_device_spi1,  
最后在mini2440_machine_init函数中加入如下代码:

[cpp]  view plain copy
  1. s3c_device_spi0.dev.platform_data= &s3c2410_spi0_platdata;  
  2. spi_register_board_info(s3c2410_spi0_board, ARRAY_SIZE(s3c2410_spi0_board));  
  3. s3c_device_spi1.dev.platform_data= &s3c2410_spi1_platdata;  
  4. spi_register_board_info(s3c2410_spi1_board, ARRAY_SIZE(s3c2410_spi1_board));  

最后需要修改arch/arm/plat-s3c24xx/KConfig文件

找到如下代码段:

[cpp]  view plain copy
  1. config S3C24XX_SPI_BUS0_GPE11_GPE12_GPE13  
  2.         bool   
  3.         help  
  4.           SPI GPIO configuration code for BUS0 when connected to  
  5.           GPE11, GPE12 and GPE13.  
  6.   
  7. config S3C24XX_SPI_BUS1_GPG5_GPG6_GPG7  
  8.         bool   
  9.         help  
  10.           SPI GPIO configuration code for BUS 1 when connected to  
  11.           GPG5, GPG6 and GPG7.  

修改为
[cpp]  view plain copy
  1. config S3C24XX_SPI_BUS0_GPE11_GPE12_GPE13  
  2.         bool "S3C24XX_SPI_BUS0_GPE11_GPE12_GPE13"  
  3.         help  
  4.           SPI GPIO configuration code for BUS0 when connected to  
  5.           GPE11, GPE12 and GPE13.  
  6.   
  7. config S3C24XX_SPI_BUS1_GPG5_GPG6_GPG7  
  8.         bool "S3C24XX_SPI_BUS1_GPG5_GPG6_GPG7"  
  9.         help  
  10.           SPI GPIO configuration code for BUS 1 when connected to  
  11.           GPG5, GPG6 and GPG7.  
最后我们配置编译文件:

[cpp]  view plain copy
  1. make menuconfig  
图1

mini2440 SPI驱动移植 既自己总结的应用层的操作_第1张图片

图2

mini2440 SPI驱动移植 既自己总结的应用层的操作_第2张图片

图3

mini2440 SPI驱动移植 既自己总结的应用层的操作_第3张图片

图4

mini2440 SPI驱动移植 既自己总结的应用层的操作_第4张图片

图5

mini2440 SPI驱动移植 既自己总结的应用层的操作_第5张图片

最后编译内核

[cpp]  view plain copy
  1. make zImage  
将编译好的内核导入开发板,并且编译Linux Source自带的测试程序,在( linux2.6.32目录下 )Documentation/spi下,修改spidev_test.c文件,将device name改为/dev/spidev1.0

交叉编译:

[cpp]  view plain copy
  1. arm-linux-gcc -I ~/linux-2.6.32.2/include/ spidev_test.c  
将编译好的文件下载到开发板上,并且将开发板的SPI MOI和MIO短接,也就是让SPI自己发送自己接收,执行文件,我们看到如下结果:

[cpp]  view plain copy
  1. FF FF FF FF FF FF  
  2. 40 00 00 00 00 95  
  3. FF FF FF FF FF FF  
  4. FF FF FF FF FF FF  
  5. FF FF FF FF FF FF  
  6. DE AD BE EF BA AD  
  7. F0 0D  
说明驱动移植成功。


总结:这里叙述的是驱动移植详细过程,代码的具体含义以及开发板的针脚对应图需要自己去查阅相关资料,这里不再详述。


转载自:http://blog.csdn.net/lxmky/article/details/6858322


//-------------------------------------------------

一下是自己总结的应用层的操作



S3C2440的SPI驱动只是做了一个驱动总线,不关心读取或写入时,最高位的变化,如看手册才明白,有些芯片的SPI协议写操作最高位是1,则 写地址0x6d,则写入的数据是0xed;!!!!


static void write_data(int fd)
{
int ret;

  uint8_t tx[2];
tx[0]=0xed;  //write 0x6d address  SI4432 spi protel  write MSB is 1;so is 0xed
tx[1]=0x09;

struct spi_ioc_transfer tr = {
 .tx_buf = (unsigned long)&tx,
      .rx_buf = (unsigned long)NULL,  //
      .len = 2,
      .delay_usecs = delay,
      .speed_hz = speed,
      .bits_per_word = bits,
      .cs_change = 0,
};
ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
if (ret == 1)
pabort("can't send spi message");
printf("ioctl write data operation return is %d---------\n",ret);
}
static void read_data(int fd)
{
int ret; 
uint8_t address=0x6d; //from  0x6d address start read

uint8_t din[100];
memset(din,0,100);//only test
struct spi_ioc_transfer read[2] = 
{
{
            .tx_buf = (unsigned long)&address,
            .rx_buf = (unsigned long)NULL,  //when only write data operation, rx_buf must be null
            .len = 1,
            .delay_usecs = delay,
            .speed_hz = speed,
            .bits_per_word = bits,
            .cs_change = 0,
    },
    {
            .tx_buf = (unsigned long)NULL,  // when only read data operation ,tx_buf must be null 
            .rx_buf = (unsigned long)din,
            .len =1,
            .delay_usecs = delay,
            .speed_hz = speed,
            .bits_per_word = bits,
            .cs_change =0,   // =0 or =1 ,result is same !!snoguo
    }
};
ret = ioctl(fd, SPI_IOC_MESSAGE(2), read);
if (ret == 1)
pabort("can't send spi message");


printf("ioctl read return is %d\n",ret);
// for (ret = 0; ret < ARRAY_SIZE(din); ret++) {
// if (!(ret % 6))
// puts("");
printf("%.2X ", din[0]);
  //}
puts("");
}

你可能感兴趣的:(c,linux,linux,IOC,null,嵌入式,嵌入式,SPI,delay)