写在前面:
SPI驱动常常被人习惯性的认为很简单,所以专门讲解SPI调试的资料不多。结合自身调试过程一路走来,做个总结,备忘。
1. SPI驱动代码
SPI控制器驱动代码(drivers/spi/spi.c)及SPI设备驱动代码(drivers/spi/spidev.c)详尽解析,参考这里
static int dspi_probe(struct platform_device *pdev)函数会从dts中解析node信息从而得到bus_num及cs值。
static int dspi_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct spi_master *master;
struct fsl_dspi *dspi;
struct resource *res;
void __iomem *base;
int ret = 0, cs_num, bus_num;
master = spi_alloc_master(&pdev->dev, sizeof(struct fsl_dspi));
if (!master)
return -ENOMEM;
dspi = spi_master_get_devdata(master);
dspi->pdev = pdev;
dspi->master = master;
master->transfer = NULL;
master->setup = dspi_setup;
master->transfer_one_message = dspi_transfer_one_message;
master->dev.of_node = pdev->dev.of_node;
master->cleanup = dspi_cleanup;
master->mode_bits = SPI_CPOL | SPI_CPHA;
master->bits_per_word_mask = SPI_BPW_MASK(4) | SPI_BPW_MASK(8) |
SPI_BPW_MASK(16);
ret = of_property_read_u32(np, "spi-num-chipselects", &cs_num);
if (ret < 0) {
dev_err(&pdev->dev, "can't get spi-num-chipselects\n");
goto out_master_put;
}
master->num_chipselect = cs_num;
ret = of_property_read_u32(np, "bus-num", &bus_num);
if (ret < 0) {
dev_err(&pdev->dev, "can't get bus-num\n");
goto out_master_put;
}
master->bus_num = bus_num;
...
...
2. DTS
spi@400C2000 {
compatible = "fsl,s32v234-dspi";
reg = <0x0 0x400c2000 0x0 0x1000>;
interrupts = <0x0 0x40 0x4>;
clocks = <0x6 0x95>;
clock-names = "dspi";
spi-num-chipselects = <0x4>; // /dev/spidev 0.xxx
bus-num = <0x3>; // /dev/spidev xxx.0
spi-cpol;
spi-cpha;
status = "okay"; // 是否打开此路SPI
#address-cells = <0x1>;
#size-cells = <0x0>;
pinctrl-names = "default";
pinctrl-0 = <0x1f>;
tja1145@0 {
compatible = "spidev"; // SPI设备驱动匹配此字符串
spi-max-frequency = <0x3d0900>;reg = <0x0>;
};
};
3. 环回测试
首先,将in out短接。
其次,编译测试代码:
Documentation/spi/spidev_test.c
最后,输出结果与输入相同即为正确。
(完)