gpio模拟SPI

来源:互联网 发布:linux交叉编译环境 编辑:程序博客网 时间:2024/05/19 12:12

gpio_spi bus总线驱动

Device Drivers —>
[*] SPI support —>
这里写图片描述
主要配置蓝色那个选项,就是配置的gpio模拟的spi总线驱动


注册spi_board_info

在bsp中需要添加如下代码

#include <linux/kernel.h>#include <linux/types.h>#include <linux/interrupt.h>#include <linux/list.h>#include <linux/timer.h>#include <linux/init.h>#include <linux/delay.h>#include <linux/device.h>#include <linux/platform_device.h>#include <linux/spi/spi.h>#include <linux/spi/spi_gpio.h>#include "bspchip.h"#define SPI_GPIO_BUS_NUM        1#define SPI_GPIO_SCK            2 /* set gpio 2 as sck */#define SPI_GPIO_MOSI           3 /* set gpio 3 as MOSI */#define SPI_GPIO_MISO           4 /* set gpio 4 as MISO */#define SPI_GPIO_NUM_CHIPSELECT                 2#define SPI_GPIO_CHIP_SELECT_SPIDEV             0#define SPI_GPIO_CHIP_SELECT_RT5514             1#define SPI_GPIO_CONTROLLER_DATA_SPIDEV         (void *)5 /* set gpio 5 as CS for spidev */#define SPI_GPIO_CONTROLLER_DATA_RT5514         (void *)6 /* set gpio 6 as CS for rt5514 */struct spi_gpio_platform_data spi_gpio_info = {        .sck = SPI_GPIO_SCK,        .mosi = SPI_GPIO_MOSI,        .miso = SPI_GPIO_MISO,        .num_chipselect = SPI_GPIO_NUM_CHIPSELECT,};struct platform_device bsp_spi_gpio_device = {        .name          = "spi_gpio",        .id            = SPI_GPIO_BUS_NUM,        .dev    = {                .platform_data  = &spi_gpio_info,        }};static struct platform_device *bsp_spi_gpio_devs[] __initdata = {        &bsp_spi_gpio_device,};static struct spi_board_info rts_spi_gpio_board_info[] __initdata = {        {                .modalias               = "spidev",                .mode                   = SPI_MODE_0, /* CPOL=0, CPHA=0 */                .bus_num                = SPI_GPIO_BUS_NUM,                .chip_select            = SPI_GPIO_CHIP_SELECT_SPIDEV,                .controller_data        = SPI_GPIO_CONTROLLER_DATA_SPIDEV,                .max_speed_hz           = 10000000,        }, {                .modalias               = "rt5514",                .mode                   = SPI_MODE_0, /* CPOL=0, CPHA=0 */                .bus_num                = SPI_GPIO_BUS_NUM,                .chip_select            = SPI_GPIO_CHIP_SELECT_RT5514,                .controller_data        = SPI_GPIO_CONTROLLER_DATA_RT5514,                .max_speed_hz           = 25000000,        },};static int __init spi_gpio_device_init(void){        int ret;        /* core init */        printk("INFO: initializing spi_gpio ...\n");        ret = platform_add_devices(bsp_spi_gpio_devs,                ARRAY_SIZE(bsp_spi_gpio_devs));        if (ret < 0) {                printk("ERROR: unable to add spi_gpio\n");                return ret;        }        spi_register_board_info(rts_spi_gpio_board_info,                ARRAY_SIZE(rts_spi_gpio_board_info));        return 0;}arch_initcall(spi_gpio_device_init);

这里添加了两个spi_board_info,
一个是spidev,另外一个是rt5514,两者都使用gpio2作为SPI_GPIO_SCK,gpio3作为SPI_GPIO_MOSI,gpio4作为SPI_GPIO_MISO,管脚上的唯一差别在于spidev使用gpio5作为CS,rt5514使用gpio6作为CS,不同的spi_board_info不能使用相同的gpio作为CS,否则后面的spi_board_info会注册不上去。

spi_board_info注册完了之后会寻找匹配的spi总线并生成一个新的struct spi_device,这个设备是挂载在那个匹配的spi总线上的。


spidev设备驱动

这里写图片描述
为了在不接spi外设的情况下测试spi的功能,需要配置User mode SPI device driver support那个选项,配置完之后编译,烧写,再次启动内核后发现多了/dev/spidev1.0这个设备节点,1代表spi总线1,0代表这个总线上的第0个设备。

我们这里主要说明一下spidev驱动,他是spidev的设备驱动,需要在内核配置如上图所示,对应linux-3.10/drivers/spi/spidev.c,代码中注册了一个name为spidev的struct spi_driver。这个spi_driver在注册的时候会寻找匹配的struct spi_device(是上一步生成的spi_device)。


spidev测试

内核提供了一个测试spidev的用户空间的代码,位置在Document/spi/spidev_test.c
$(cc) spidev_test.c -o spidev_test生成可执行文件spidev_test,这个设备用于SPI的MOSI和MISO回环测试。

根据在linux-3.10/arch/rlx/bsp/spi_gpio.c文件中指定,MOSI对应gpio3,MISO对应gpio4,将这两个gpio短接在一起,然后执行如下测试:
这里写图片描述

这个传输的数据与spidev_test.c文件中的tx数组中的数据对比是一致的

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,        };

这样,gpio模拟的基本功能就算ok了

0 0