在freescale mx6q平台上添加spi资源


1:配置管脚为SPI功能

在board-mx6q_sabresd.h的最后添加,复制被重定义

(以添加SPI2为例)

       

        MX6Q_PAD_EIM_CS0__ECSPI2_SCLK,
        MX6Q_PAD_EIM_CS1__ECSPI2_MOSI,
        MX6Q_PAD_EIM_OE__ECSPI2_MISO,
        MX6Q_PAD_CSI0_DAT11__ECSPI2_SS0 ,


之后再板级文件board-mx6q_sabresd.c中将有相关函数对管脚进行统一初始化。

完成寄存器配置的工作。

	mxc_iomux_v3_setup_multiple_pads(mx6q_sabresd_pads,
		ARRAY_SIZE(mx6q_sabresd_pads));

	mxc_iomux_v3_setup_multiple_pads(mx6q_sabresd_cstm_tq_pads,\
		ARRAY_SIZE(mx6q_sabresd_cstm_tq_pads));

2:在板级文件board-mx6q_sabresd.c中添加以下代码

将匹配到driver/spi/spidev.c文件中的驱动源码

2.1完成SPI master的注册

SPI2片选管脚宏定义:

#define SABRESD_ECSPI2_CS0 IMX_GPIO_NR(5, 29)


添加相关结构体

static int mx6q_marsboard_spi1_cs[] = {
        SABRESD_ECSPI2_CS0,
};


 

static const struct spi_imx_master mx6q_sabresd_spi2_data __initconst = {
        .chipselect = mx6q_marsboard_spi2_cs,
        .num_chipselect = ARRAY_SIZE(mx6q_marsboard_spi1_cs),
};


 

2.2在spi 总线上匹配spi2的驱动文件

mx6q平台有2路spi资源,0/1,其中的bus_num则为挂载驱动的总线选择。


static struct mtd_partition imx6_sabrelite_spi_nor_partitions[] = {
 {
  .name = "bootloader",
  .offset = 0,
  .size = 0x00100000,
 },
 {
  .name = "kernel",
  .offset = MTDPART_OFS_APPEND,
  .size = MTDPART_SIZ_FULL,
 },
};


static struct flash_platform_data imx6_sabrelite__spi_flash_data = {
 .name = "spidev",  / /匹配原则。
 .parts = imx6_sabrelite_spi_nor_partitions,
 .nr_parts = ARRAY_SIZE(imx6_sabrelite_spi_nor_partitions),
 .type = "sst25vf016b",
};




static struct spi_board_info imx6_sabrelite_spi_nor_device[] __initdata = {
 {
  .modalias = "spidev",
  .max_speed_hz = 20000000, /* max spi clock (SCK) speed in HZ */
  .bus_num = 1,    //设备挂载第几号spi总线上
  .chip_select = 0,
  .platform_data = &imx6_sabrelite__spi_flash_data,
 },
};


spi_register_board_info(imx6_sabrelite_spi_nor_device,
ARRAY_SIZE(imx6_sabrelite_spi_nor_device));

imx6q_add_ecspi(0, &mx6q_sabrelite_spi2_data);






 

 

3:内核配置

 

查看spidev.c文件目录下的Kconfig以及Makefile得知内核驱动的添加方法

 

选择蓝色部分选项,将spidev.c文件添加到内核中。

 

4:查看开发板/sys/bus/spi/drivers/spidev目录

 

在/dev下生成设备文件/dev/spidev1.0

 

5:使用freescale官方的bsp包中的spi测试程序对接口进行测试

/*
 * SPI testing utility (using spidev driver)
 *
 * Copyright (c) 2007  MontaVista Software, Inc.
 * Copyright (c) 2007  Anton Vorontsov <avorontsov@ru.mvista.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License.
 *
 * Cross-compile with cross-gcc -I/path/to/cross-kernel/include
 */

#include <stdint.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/types.h>
#include <linux/spi/spidev.h>

#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))

static void pabort(const char *s)
{
	perror(s);
	abort();
}

static const char *device = "/dev/spidev1.0";
static uint8_t mode;
static uint8_t bits = 8;
static uint32_t speed = 500000;
static uint16_t delay;

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("");
}


int main(int argc, char *argv[])
{
	int ret = 0;
	int fd;

	//parse_opts(argc, argv); /* for what ,unknow*/

	fd = open(device, O_RDWR);
	if (fd < 0)
		pabort("can't open device");

	/*
	 * spi mode
	 */
	ret = ioctl(fd, SPI_IOC_WR_MODE, &mode);
	if (ret == -1)
		pabort("can't set spi mode");

	ret = ioctl(fd, SPI_IOC_RD_MODE, &mode);
	if (ret == -1)
		pabort("can't get spi mode");

	/*
	 * bits per word
	 */
	ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits);
	if (ret == -1)
		pabort("can't set bits per word");

	ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits);
	if (ret == -1)
		pabort("can't get bits per word");

	/*
	 * max speed hz
	 */
	ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
	if (ret == -1)
		pabort("can't set max speed hz");

	ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed);
	if (ret == -1)
		pabort("can't get max speed hz");

	printf("spi mode: %d\n", mode);
	printf("bits per word: %d\n", bits);
	printf("max speed: %d Hz (%d KHz)\n", speed, speed/1000);

	transfer(fd);

	close(fd);

	return ret;
}


 

执行应用程序,可以看到时序模式(spi 4种时序模式第0种),时钟频率等参数。

 

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值