V853 buildroot系统,SPI通信超时
-
spi从设备是20MHz的频率,CS是低电平有效。dts配置如下:
&spi3 { clock-frequency = <100000000>; pinctrl-0 = <&spi3_pins_a &spi3_pins_b>; pinctrl-1 = <&spi3_pins_c>; pinctrl-names = "default", "sleep"; spi_slave_mode = <0>; spi_dbi_enable = <1>; spi_cs_bitmap = <1>; spi3_cs_number = <1>; status = "okay"; spidev@0 { device_type = "spidev"; compatible = "rohm,dh2228fv"; spi-max-frequency = <100000000>; reg = <0x0>; spi-cs-high; spi-rx-bus-width = <0x8>; spi-tx-bus-width = <0x8>; status = "okay"; }; }; ... spi3_pins_a: spi3@0 { allwinner,pins = "PH11", "PH12", "PH13"; allwinner,pname = "spi3_sclk", "spi3_mosi","spi3_miso"; allwinner,function = "spi3"; allwinner,muxsel = <6>; allwinner,drive = <1>; allwinner,pull = <0>; }; spi3_pins_b: spi3@1 { allwinner,pins = "PH14"; allwinner,pname = "spi3_cs0"; allwinner,function = "spi3"; allwinner,muxsel = <6>; allwinner,drive = <1>; allwinner,pull = <1>; // only CS should be pulled up }; spi3_pins_c: spi3@2 { allwinner,pins = "PH11", "PH12", "PH13", "PH14"; allwinner,function = "io_disabled"; allwinner,muxsel = <0xf>; allwinner,drive = <1>; allwinner,pull = <0>; };
测试程序是这样的:
#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> static uint8_t mode = 0; /* SPI通信使用全双工,设置CPOL=0,CPHA=0。 */ static uint8_t bits = 8; /* 8bits读写,MSB first。*/ static uint32_t speed = 20 * 1000 * 1000;/* 设置20M传输速度 */ static uint16_t delay = 0; static int g_SPI_Fd = 0; unsigned char r_buf[256]; unsigned char w_buf[256]; int SPI_Write(uint8_t *TxBuf, int len) { int ret; int fd = g_SPI_Fd; ret = write(fd, TxBuf, len); if (ret < 0) printf("SPI Write error\n"); else { int i; printf("\nSPI Write [Len:%d]: ", len); for (i = 0; i < len; i++) { if (i % 8 == 0) printf("\n\t"); printf("0x%02X ", TxBuf[i]); } printf("\n"); } return ret; } static int SPI_Open(const char* device) { int fd; int ret = 0; if (g_SPI_Fd != 0) /* 设备已打开 */ return 0xF1; fd = open(device, O_RDWR); if (fd < 0) printf("can't open device"); else printf("SPI - Open Succeed. Start Init SPI...\n"); g_SPI_Fd = fd; /* * spi mode */ ret = ioctl(fd, SPI_IOC_WR_MODE, &mode); if (ret == -1) printf("can't set spi mode"); ret = ioctl(fd, SPI_IOC_RD_MODE, &mode); if (ret == -1) printf("can't get spi mode"); /* * bits per word */ ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits); if (ret == -1) printf("can't set bits per word"); ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits); if (ret == -1) printf("can't get bits per word"); /* * max speed hz */ ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed); if (ret == -1) printf("can't set max speed hz"); ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed); if (ret == -1) printf("can't get max speed hz"); printf("spi mode: %d\n", mode); printf("bits per word: %d\n", bits); printf("max speed: %d KHz (%d MHz)\n", speed / 1000, speed / 1000 / 1000); return ret; } int SPI_Close(void) { int fd = g_SPI_Fd; if (fd == 0) /* SPI是否已经打开*/ return 0; close(fd); g_SPI_Fd = 0; return 0; } int main(int argc, char* argv[]) { char *str="hello"; int len = 5; SPI_Open("/dev/spidev3.0"); SPI_Write(str, len); SPI_Close(); return 0; }
交叉编译后放到板子上运行,会出现这样的超时报错,想问问看各位有没有什么思路解决,十分感谢。
root:/root# ./spi SPI - Open Succeed. Start Init S[ 586.085918] spi_set_clk()459 - set spi clock 100000000, mclk 20000000 PI... [ 586.095997] spi_set_clk()459 - set spi clock 100000000, mclk 100000000 [ 586.104382] spi_set_clk()459 - set spi clock 20000000, mclk 100000000 spi mode: 0[ 586.111792] sunxi_spi_transfer_one()1433 - [spi3] begin transfer, txbuf df6ab000, rxbuf (null), len 5 bits per word: 8 max speed: 2[ 586.123289] spi_set_clk()459 - set spi clock 20000000, mclk 20000000 0000 KHz (20 MHz) [ 586.133363] sunxi_spi_mode_check()1166 - [spi3] Single mode Half duplex tx [ 586.142730] spi_config_dbi()376 - DBI mode configurate : 40 [ 586.148979] sunxi_spi_xfer()1376 - [spi3] tx -> by ahb [ 586.155060] sunxi_spi_cpu_writel()1250 - t->len = 5 [ 586.160602] 000: 68 65 6c 6c 6f [ 596.275684] sunxi_spi_cpu_writel()1276 - [spi3] cpu transfer data time out! [ 596.283516] sunxi_spi_transfer_one()1462 - [spi3] dump reg: [ 596.289762] 0x04028000: 00010001 00000098 00002104 00000000 [ 596.296582] 0x04028010: 00000000 00000012 00200020 000f0000 [ 596.303189] 0x04028020: 00000000 00000002 00002000 00000000 [ 596.309535] 0x04028030: 00000005 00000005 00000005 00000000 [ 601.351828] sunxi_spi_transfer_one()1471 - [spi3] xfer timeout [ 601.358391] spidev spi3.0: SPI transfer failed: -1 [ 601.364475] spi_master spi3: failed to transfer one message from queue SPI Write error
启动时的spi log
[ 0.650370] sunxi_spi_probe()2251 - [spi3] SPI DBI INTERFACE [ 0.656168] sunxi_spi_probe()2260 - [spi3] SPI MASTER MODE [ 0.661799] sunxi_spi_resource_get()1909 - Failed to get sample mode [ 0.668268] sunxi_spi_resource_get()1914 - Failed to get sample delay [ 0.674824] sunxi_spi_resource_get()1918 - sample_mode:aaaaffff sample_delay:aaaaffff [ 0.682785] spi3 supply spi not found, using dummy regulator [ 0.688624] sunxi_spi_request_gpio()1884 - [spi3] Pinctrl init spi3 [ 0.695128] sunxi_spi_clk_init()1955 - [spi3] mclk 100000000 [ 0.701466] spi_master spi3: spi-tx-bus-width 8 not supported [ 0.707476] spi_master spi3: spi-rx-bus-width 8 not supported [ 0.713865] sunxi_spi_probe()2340 - [spi3]: driver probe succeed, base e0834000, irq 295
-
想知道DTS里面的这个参数是什么含义呢?
spi_dbi_enable = <1>;我是把这个注释掉之后,就正常了。
-
将spi_dbi_enable = <1> 注释掉就可以了
照着前边的spi节点写的dts,不知道这个是做什么用的。 -
@negro 这个一般的spi设备去掉就好,di是用来接spi屏的,我们一般的spi设备都不需要开启。
-
@chengwei_peng
感谢回复。
现在这个测试程序是显示可正常发数据了,但是我用示波器量SPI的时钟,发现一直都是低电压,没有方波,MISO,MOSI,CS0三根线都是一只低电平,我甚至是可以echo 235~238 > /sys/class/gpio/export
导出GPIO并控制IO口输出高低电频。这样是正常的吗?虽然设备节/dev/spidev3.0
点出来了,但是总感觉好像这几个IO口没有正确配置成SPI接口。
我用的是buildroot系统。 -
@negro 你能正常的读到正确的数据,那么引脚配置肯定没问题的。至于你说的波形问题,倾向于你没有抓到波形。
而引脚问题,你看看你export后,引脚的功能属性是不是发生变化了。 -
@chengwei_peng
export后查看引脚属性,依旧是spi3功能没变,我再检查一下是不是我的测波形的方法不对,感谢指导。谢谢 -
此回复已被删除! -
来个教程啊来个教程啊
Copyright © 2024 深圳全志在线有限公司 粤ICP备2021084185号 粤公网安备44030502007680号