- Master control: D1H
- Board: two Nezha development boards (hereinafter referred to as host and slave)
- Operating system: Tina Linux 2.0
Verify D1H chip SPI master-slave communication.
hardware wiring
Host SPI | Slave SPI | ||
---|---|---|---|
19 | SPI1_MOSI | SPI1_MOSI | 19 |
21 | SPI1_MISO | SPI1_MISO | 21 |
23 | SPI1_SCK | SPI1_SCK | 23 |
24 | SPI1_CE | SPI1_CE | 24 |
SPI overview
The SPI interface is a high-speed, full-duplex, synchronous communication bus. The
BSP-SDK (hereinafter referred to as SDK) of Tina Linux adapted to the D1H chip has included the relevant driver file: spi-sunxi.c.
It provides Only the simple communication verification experiment of the master and slave in the kernel state, this may be due to the relatively high communication rate of the SPI.
Verification operation
SPI master configuration
MENUCONFIG
After the SDK executes the environment variable loading, execute:
/mnt/tina-d1-h$ make kernel_menuconfig
●Open Device Drivers->SPI support
●Enter SPI support, open according to the icon:
device tree
Modify: ./device/config/chips/d1-h/configs/nezha/board.dts
Need to confirm the pin function according to the manual and schematic diagram:
SPI slave configuration
MENUCONFIG
(same as SPI master configuration)
device tree
Only spi_slave_mode is set to 0, and the rest are consistent with the configuration of the SPI master. spi_slave_mode = <0>;
SPI host sends and receives information
According to the above configuration, recompile the SDK, package, burn, and start the device, it will appear:
root@TinaLinux# ls -l /dev/spidev1.0
crw------- 1 root root 153, 0 Jan 1 08:00 /dev/spidev1.0
Then move the executable SPI test program (./lichee/linux-5.4/tools/spi/spidev_test) to the device (adb push, etc.) and grant executable permission:
# 主机以10MHz发送(即MOSI)发送16进制数据: 0x01 0x02 0x03 0x04
./spidev_test -v -D /dev/spidev1.0 -s 10000000 -p "\x01\x02\x03\x04"
# 主机以10MHz发送(即MOSI)发送ASCII字符串数据: "allwinner"
./spidev_test -v -D /dev/spidev1.0 -s 10000000 -p "allwinner"
spi mode: 0x0
bits per word: 8
max speed: 10000000 Hz (10000 KHz)
TX | 61 6C 6C 77 69 6E 6E 65 72 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ |allwinner|
Note that SPI is a synchronous communication interface, so data of the same length will be received while sending.
A common practice of SPI master-slave communication will be used below: the master sends the command header first, and then sends the command body to obtain the slave machine answer.
SPI slave sends and receives information
In spi-sunxi.c, a simple sending and receiving verification process is adopted for the SPI slave mode (SLAVE_MODE). Specifically, a kernel thread is created to execute int sunxi_spi_slave_task(void *data), and this function is controlled by the device interrupt (when receiving SPI data).
-
The main flow of the SPI slave receiving data:
sunxi_spi_slave_task() -> sunxi_spi_slave_handle_head(), and then:
if the command header is a write operation (0x01), then execute: sunxi_spi_slave_cpu_rx_config(), this function is only to output the written content.
If the command throws If it is a read operation (0x03), execute: sunxi_spi_slave_cpu_tx_config(), this function only sends (MISO) the value of the received instruction body + 0x80 to the host. -
For the slave, spi-sunxi.c can verify the SPI communication, but there is no method for the user layer to use directly.
User layer verifiable SPI slave transceiver scheme
feature design
The slave arranges a 32byte memory cache space (referred to as "cache space") for the host to perform read and write operations through instructions, and the slave can access the memory space at the user layer.
major changes
- spi.c:
- Add static struct class_attribute ye_spi_buf_attrs[] to create the spi_buf file under the /sys/class/spi_slave directory, and provide a method to realize the read/write cache space.
- spi-sunxi.c:
- Use the ye_spi_slave_set_txdata() method to replace sunxi_spi_slave_set_txdata() to implement read operations.
- Modify the sunxi_spi_slave_cpu_rx_config() method to implement write operations.
Please check the modification details: d1h_spi_driver.diff
Instructions
写操作: 操作:0x01(写) 地址:0x00 0x00 0x00 指令体长度:0x09
./spidev_test -v -D /dev/spidev1.0 -s 10000000 -p "\x01\x00\x00\x00\x09" && \
./spidev_test -v -D /dev/spidev1.0 -s 10000000 -p "allwinner"
读操作: 操作:0x03(读) 地址:0x00 0x00 0x00 指令体长度:0x09
./spidev_test -v -D /dev/spidev1.0 -s 10000000 -p "\x03\x00\x00\x00\x09" && \
./spidev_test -v -D /dev/spidev1.0 -s 10000000 -p "\x00\x00\x00\x00\x00\x00\x00\x00\x00"
从机读取缓存空间:
cat /sys/class/spi_slave/spi_buf
从机写入缓存空间:
echo "Hello world" > /sys/class/spi_slave/spi_buf