想通过应用层操作spi
首先我保证这几个内核配置是开了的:
CONFIG_SPI_SUN6I=y
CONFIG_SPI=y
CONFIG_SPI_MASTER=y
CONFIG_SPI_SPIDEV=y然后因为我用spi flash启动 已经占用了spi0 所以要加新的接口spi1
改设备树文件suniv.dtsi 通过参考spi0来增加
spi0_pins_a: spi0-pins-pc {
	pins = "PC0", "PC1", "PC2", "PC3";
	function = "spi0";
};
spi1_pins_a: spi1-pins-pa {
	pins = "PA2", "PA0", "PA3", "PA1";
	function = "spi1";
};改设备树文件suniv-f1c100s-licheepi-nano.dts 通过参考spi0来增加
&spi0 {
	pinctrl-names = "default";
	pinctrl-0 = <&spi0_pins_a>;
	status = "okay";
	flash: w25q128@0 {
			#address-cells = <1>;
			#size-cells = <1>;
			compatible = "winbond,w25q128", "jedec,spi-nor";
			reg = <0>;
			spi-max-frequency = <50000000>;
			partitions{
					compatible = "fixed-partitions";
					#address-cells = <1>;
					#size-cells = <1>;
					partition@0 {
							lable = "u-boot";
							reg = <0x000000 0x100000>;
							read-only;
					};
					partition@100000 {
							lable = "dtb";
							reg = <0x100000 0x10000>;
							read-only;
					};
					partition@110000 {
							label = "kernel";
							reg = <0x110000 0x400000>;
							read-only;
					};
					partition@510000 {
							label = "rootfs";
							reg = <0x510000 0xAF0000>;
					};
			};
	};
};
&spi1 {
        pinctrl-names = "default";
        pinctrl-0 = <&spi1_pins_a>;
        status = "okay";
};然后编译内核和设备树重新打包下载进板子
如果添加spi1成功了 会多出来个/dev/spi1 但实际上没有 只有原来的spi0.0 说明可能哪里错了 大神来指点一下?
离线
操作一下 spi0.0 
有可能就是你需要的,
接逻辑分析仪到 cs# 引脚测试。
离线
操作一下 spi0.0
有可能就是你需要的,接逻辑分析仪到 cs# 引脚测试。
记错了 看了下 发现/dev/ 里面没有spi相关设备 是/sys/bus/spi/devices/spi0.0 这个应该不能操作吧
离线
原来是设备树没配好 重要的设备节点漏了
参考了链接 http://linux-sunxi.org/SPIdev
把/dev/spidev1.0配出来了
离线
原来是设备树没配好 重要的设备节点漏了
参考了链接 http://linux-sunxi.org/SPIdev
把/dev/spidev1.0配出来了
最后怎么搞掂的? 
我这里也是,有看到,SPI1 初始化信息,但在 /dev/ 没有 SPI1 设备, SPI0也没有
离线
在 /sys/class/spi_master 目录下,看得到 SPI0 SPI1, 在 /dev/目录下没有, 
如何是好了?
# ls
backlight     graphics      misc          pwm           spi_master
bdi           i2c-adapter   mmc_host      regulator     spidev
block         i2c-dev       mtd           scsi_changer  thermal
bsg           ieee80211     net           scsi_device   tty
dma           input         phy           scsi_disk     udc
drm           leds          power_supply  scsi_generic  vc
extcon        mdio_bus      pps           scsi_host     vtconsole
gpio          mem           ptp           sound
# cd spi_master
# ls
spi0  spi1离线
CONFIG_SPI_SPIDEV=y
这个勾选了吗?
在 config 文件里,,
#
# SPI Protocol Masters
#
CONFIG_SPI_SPIDEV=y
# CONFIG_SPI_LOOPBACK_TEST is not set
# CONFIG_SPI_TLE62X0 is not set离线
&spi1 {
        pinctrl-names = "default";
        pinctrl-0 = <&spi1_pins_a>;
        status = "okay";
	spidev@0x00 {
               compatible = "spidev";
               spi-max-frequency = <100000000>;
               reg = <0>;
	};
};加了 spidev@0x00 这个就可以显示了,谢谢大家!等下测试,行不行,起码现在可以在 dev 下看到了
离线
&spi1 {
pinctrl-names = "default";
pinctrl-0 = <&spi1_pins_a>;
status = "okay";
spidev@0x00 {
compatible = "spidev";
spi-max-frequency = <100000000>;
reg = <0>;
};
};加了 spidev@0x00 这个就可以显示了,谢谢大家!等下测试,行不行,起码现在可以在 dev 下看到了
你好 请问您方便提供一下开启spi1之后的启动log吗?
离线
&spi1 {
pinctrl-names = "default";
pinctrl-0 = <&spi1_pins_a>;
status = "okay";
spidev@0x00 {
compatible = "spidev";
spi-max-frequency = <100000000>;
reg = <0>;
};
};加了 spidev@0x00 这个就可以显示了,谢谢大家!等下测试,行不行,起码现在可以在 dev 下看到了
这个实际上就是把spi 设备接口暴露给应用层,让app去驱动spi设备了。
离线
浏览了楼主的帖子,我的 /dev/spidev0.0 也配出来了,现在可以在应用程序层为所欲为了。
参考树莓派例程:
https://www.raspberrypi.org/documentation/hardware/raspberrypi/spi/README.md
https://raw.githubusercontent.com/raspberrypi/linux/rpi-3.10.y/Documentation/spi/spidev_test.c
/*
 * 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.1";
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("");
}
static void print_usage(const char *prog)
{
	printf("Usage: %s [-DsbdlHOLC3]\n", prog);
	puts("  -D --device   device to use (default /dev/spidev1.1)\n"
	     "  -s --speed    max speed (Hz)\n"
	     "  -d --delay    delay (usec)\n"
	     "  -b --bpw      bits per word \n"
	     "  -l --loop     loopback\n"
	     "  -H --cpha     clock phase\n"
	     "  -O --cpol     clock polarity\n"
	     "  -L --lsb      least significant bit first\n"
	     "  -C --cs-high  chip select active high\n"
	     "  -3 --3wire    SI/SO signals shared\n");
	exit(1);
}
static void parse_opts(int argc, char *argv[])
{
	while (1) {
		static const struct option lopts[] = {
			{ "device",  1, 0, 'D' },
			{ "speed",   1, 0, 's' },
			{ "delay",   1, 0, 'd' },
			{ "bpw",     1, 0, 'b' },
			{ "loop",    0, 0, 'l' },
			{ "cpha",    0, 0, 'H' },
			{ "cpol",    0, 0, 'O' },
			{ "lsb",     0, 0, 'L' },
			{ "cs-high", 0, 0, 'C' },
			{ "3wire",   0, 0, '3' },
			{ "no-cs",   0, 0, 'N' },
			{ "ready",   0, 0, 'R' },
			{ NULL, 0, 0, 0 },
		};
		int c;
		c = getopt_long(argc, argv, "D:s:d:b:lHOLC3NR", lopts, NULL);
		if (c == -1)
			break;
		switch (c) {
		case 'D':
			device = optarg;
			break;
		case 's':
			speed = atoi(optarg);
			break;
		case 'd':
			delay = atoi(optarg);
			break;
		case 'b':
			bits = atoi(optarg);
			break;
		case 'l':
			mode |= SPI_LOOP;
			break;
		case 'H':
			mode |= SPI_CPHA;
			break;
		case 'O':
			mode |= SPI_CPOL;
			break;
		case 'L':
			mode |= SPI_LSB_FIRST;
			break;
		case 'C':
			mode |= SPI_CS_HIGH;
			break;
		case '3':
			mode |= SPI_3WIRE;
			break;
		case 'N':
			mode |= SPI_NO_CS;
			break;
		case 'R':
			mode |= SPI_READY;
			break;
		default:
			print_usage(argv[0]);
			break;
		}
	}
}
int main(int argc, char *argv[])
{
	int ret = 0;
	int fd;
	parse_opts(argc, argv);
	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;
}离线
谢谢分享,F1C100S没有以太网,一直在调这个SPI,想用在ENC28j60上,
离线
Linux内置了 enc28j60的驱动,只要配置menuconfig和dts就行。
内核配置知道,dts要怎么添加,能不能麻烦大神写一下添加的部分,万分感谢!~
离线
内核配置知道,dts要怎么添加,能不能麻烦大神写一下添加的部分,万分感谢!~
驱动:
https://github.com/torvalds/linux/blob/master/drivers/net/ethernet/microchip/enc28j60.c
树莓派dts demo:
https://github.com/eq-3/RaspberryMatic/blob/master/linux-4.1/arch/arm/boot/dts/overlays/enc28j60-overlay.dts
填好dts问题就不大了, 搞定了记得发个图分享一下。
离线
只加了spi1,在里面并没有加具体设备吧,所有没有spi1.0
离线
搞不掂,可以分享你那个DTS吗?
离线
不是在9楼已经搞定了吗?
上面是搞掂 SPI1, 我想弄的是, SPI1 驱动 ENC28J60, 这个没搞好
离线
不错,后面试试,正好有张吃灰的板子
离线
非常感觉!
现在启动时,
    [0.958407] enc28j60 spi1.0: enc28j60 Ethernet driver 1.02 loaded
    [0.975314] net eth0: enc28j60 driver registered
不过网络无法连接, 还得继续研究
离线
如 ENC28J60 SPI线,不连接或少连接,就会出现下面的情况,
[    0.971925] enc28j60 spi1.0: enc28j60 chip not found
[    0.977084] enc28j60: probe of spi1.0 failed with error -5
那说明,我这驱动应该是OK的
离线
中断接了吗?dts配了中断吗?
cat /proc/interrupts 显示enc28j60有多少次中断?
# cat /proc/interrupts
           CPU0
 16:        695  sun4i_irq  13 Edge      timer@1c20c00
 19:      90546  sun4i_irq  10 Edge      sun6i-spi
 20:         67  sun4i_irq  11 Edge      sun6i-spi
 22:        362  sun4i_irq  23 Edge      sunxi-mmc
 27:        244  sun4i_irq   2 Edge      ttyS1
 29:          0  sun4i_irq  26 Edge      musb-hdrc.1.auto
 65:          1  sunxi_pio_edge  34 Edge      usb0-id-det
 74:          0  sunxi_pio_edge  43 Edge      enc28j60
离线
不过那个 rst 脚 没有接,要不要接的?
离线
# cat /proc/interrupts
           CPU0
 16:        500  sun4i_irq  13 Edge      timer@1c20c00
 19:      90592  sun4i_irq  10 Edge      sun6i-spi
 20:        260  sun4i_irq  11 Edge      sun6i-spi
 22:        220  sun4i_irq  23 Edge      sunxi-mmc
 27:        331  sun4i_irq   2 Edge      ttyS1
 29:          0  sun4i_irq  26 Edge      musb-hdrc.1.auto
 65:          1  sunxi_pio_edge  34 Edge      usb0-id-det
 74:         24  sunxi_pio_edge  43 Edge      enc28j60
 拿导线,把 INT脚,接地,就有中断次数了
离线
淘宝的模块可以上电启动,应该不要RST.
手动短路中断线到GND,
再 cat /proc/interrupts 看enc28j60中断次数有没有增加。
手动有中断的,
enc28j60 接5V会发热,
接3.3V 就不发热,,,,,,
但都没有中断, 可能买的是假货?
离线
离线
有没有执行 ifconfig eth0 192.x.x.x
:cool 非常非常感谢! 可以正常网络通信了, 主要原因是没有配置本地IP和网关, 配置好了,就可以上网了。
我现在研究一下,怎么开启 DHCP
离线
离线
busybox里面开启 udhcpc 就可以了,
执行
udhcpc -i eth0
  太太太太太感谢了!可以正常工作了。
估计这里很多高手早就弄出来了, 不过我还是说一下流程吧,后面的朋友们可以参考参考
一、 在 arch/arm/boot/dts/suniv.dtsi
1. 添加头文件引用 #include <dt-bindings/interrupt-controller/irq.h>
2. 添加
        spi1: spi@1c06000 {
            compatible = "allwinner,suniv-spi",
                     "allwinner,sun8i-h3-spi";
            reg = <0x01c06000 0x1000>;
            interrupts = <11>;
            clocks = <&ccu CLK_BUS_SPI1>, <&ccu CLK_BUS_SPI1>;
            clock-names = "ahb", "mod";
            resets = <&ccu RST_BUS_SPI1>;
            status = "disabled";
            #address-cells = <1>;
            #size-cells = <0>;
        };
二、 在 arch/arm/boot/dts/suniv-f1c100s-licheepi-nano.dts
添加
&spi1 {
    pinctrl-names = "default";
    pinctrl-0 = <&spi1_pins_a>;
    status = "okay";
    eth1: enc28j60@0{
        compatible = "microchip,enc28j60";
        reg = <0x0>; /* CE0 */
        interrupt-parent = <&pio>;
        interrupts = <4 11 IRQ_TYPE_EDGE_FALLING>; /* (PE11) */
        gpios = <&pio 4 11 GPIO_ACTIVE_HIGH>;
        spi-max-frequency = <12000000>;
        status = "okay";
    };
};
前面两点,在uboot 和 内核 的dst 文件都添加
三、  在\include\generated\autoconf.h  
        文件添加 #define CONFIG_ENC28J60 1
就可以了。
离线
busybox里面开启 udhcpc 就可以了,
执行
udhcpc -i eth0感觉 f1c100s + enc28j60 不如用 V3s了。
主要考虑两点:
1. 总的成本
2. 一直研究  f1c100s, 对 v3s不熟悉, 怕来不及
离线
enc28j60啥年代的芯片,还有人用
离线