Chinaunix首页 | 论坛 | 博客
  • 博客访问: 20221
  • 博文数量: 8
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 10
  • 用 户 组: 普通用户
  • 注册时间: 2015-01-14 13:30
文章分类
文章存档

2016年(8)

我的朋友

分类: 嵌入式

2016-04-06 17:33:29

原文地址:2440中的spi通信 作者:zj47596731

近段时间在调试S3C2440板卡上SPI的驱动程序,主要是利用2440的SPI0控制一块BCM交换芯片(slave),本来想自己手写一个SPI驱动,但看了看linux 2.6.29内核里已经自带了2440的SPI驱动,所以就直接利用了内核自带的驱动,过程如下:

    第一步:在编译内核make menuconfig时选上进入驱动选项页;

2440中的spi通信 - shaohj_1999@126 - 南方的企鹅

2440中的spi通信 - shaohj_1999@126 - 南方的企鹅
    第二步:在驱动选项页里选择SPI,进入SPI页;

2440中的spi通信 - shaohj_1999@126 - 南方的企鹅
    第三步:选择上图带*号的选项,保存并退出配置界面;

    第四步:修改arch/arm/mach-s3c2440/mach-mini2440.c文件,在include头文件代码行之后增加如下代码

//add spi
#include
#include

static struct spi_board_info s3c2410_spi0_board[] = {
        [0] = {
                 .modalias = "spidev",
                .bus_num        = 0,
                .chip_select        = 0,
                .irq = IRQ_EINT9,
                .max_speed_hz         = 500*1000,
        },
};
//.pin_cs = S3C2410_GPB1,
static struct s3c2410_spi_info s3c2410_spi0_platdata = {
        .pin_cs = S3C2410_GPG2,
        .num_cs = 1,
        .bus_num = 0,
};
//end add spi

    这里需要注意的是片选管脚.pin_cs需要根据自己的硬件实际情况来定义,我的板卡用的是GPG2管脚作为片选。

    然后在函数__init mini2440_machine_init的开头增加下列代码

//add spi
s3c_device_spi0.dev.platform_data= &s3c2410_spi0_platdata;
spi_register_board_info(s3c2410_spi0_board, ARRAY_SIZE(s3c2410_spi0_board));
//end spi

    第五步:修改drivers/spi/spi_s3c24xx.c文件,在s3c24xx_spi_initialsetup函数结尾增加下列代码

s3c2410_gpio_cfgpin(hw->pdata->pin_cs, S3C2410_GPIO_OUTPUT);
s3c2410_gpio_cfgpin(0x8B, S3C2410_GPIO_SFN2);
s3c2410_gpio_cfgpin(0x8C, S3C2410_GPIO_SFN2);
s3c2410_gpio_cfgpin(0x8D, S3C2410_GPIO_SFN2);

    主要是为了防止有些板卡在硬件复位之后2440寄存器没有完全复位成默认值,所以需要手动进行配置;

    第六步:用make zImage编译内核。

    烧录新内核,板卡起来之后在/dev/目录下会产生一个新的设备文件spidev0.0,这时可以用内核自带的测试程序进行测试,内核测试程序在Documentation/spi目录下,直接修改并编译spidev_test.c文件即可。测试时可以用一根导线将SPI的out和in两根管脚连接起来形成环路——自发自收。这个测试程序有几个参数需要注意,

-D,这是让你选择spi设备名,我的是/dev/spidev0.0;

-s,选择速率,单位是Hz,默认是500000,一般可以设到2M;

-H,时钟相位,我的设备要求为1,即时钟信号为高时片选由高到低有效,默认为0,带该参数表示1;

-O,时钟极性,我的设备要求为1,即空闲时时钟信号要保持为高,默认为0,带该参数表示1;

-C,片选置高,我的设备要求0,即片选信号为低时有效,默认为0,带该参数表示1;

其它参数没有用过,不知道什么意思。当然如果是自发自收测试这些参数除了设备名外都可以不设置。

    其实SPI的原理很简单,主要有3根线(时钟,数据输入,数据输出),再加一个片选线,时钟始终由master发出,master发送字节的同时会产生时钟信号,由于slave不能产生时钟,所以为了从slave接收数据,master必须在接收数据时也发送数据(可以为全0)以产生时钟。

    我在驱动里是用中断的方式来发送和接收数据的,每发送一个字节数据,产生一次中断,在中断里查看状态寄存器,并读取接收寄存器里的值,然后继续下一个字节的发送,如此循环直到全部发送和接收完毕。

阅读(1049) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~