08 SPI Communication
1 SPI Introduction
SPI (serial peripheral interface) basic concepts reference blog: CSDN blog article
Compared with I2C communication, SPI communication emphasizes straightforwardness: you add signals with dedicated lines as needed. Each signal has its own dedicated signal line, which brings clear benefits. Because the signal is driven directly rather than using an I2C-style pull-up signal to prevent damage, the communication speed achievable is higher. The RK3568 board used in this document in master mode can theoretically reach up to 50 MHz, and in slave mode up to 33 MHz.
2 SPI Board Interfaces

The SPI pins exposed on the board are SPI3.

3 SPI Usage---Command Line Method
Enter the board terminal via HDC to verify whether the spi3 device is created; run the following command from the root:
ls /dev/spi*
The spi3 device has been successfully mounted under the /dev directory.
3-1 Device Tree Parsing
Tips
The following file path needs to be compiled from source: out/kernel/src_tmp/linux-5.10/arch/arm64/boot/dts/rockchip/
Following the previous subsection, the basic SPI3 controller definition in rk3568.dtsi is as follows:
spi3: spi@fe640000 {
compatible = "rockchip,rk3066-spi";
reg = <0x0 0xfe640000 0x0 0x1000>;
interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
clocks = <&cru CLK_SPI3>, <&cru PCLK_SPI3>;
clock-names = "spiclk", "apb_pclk";
dmas = <&dmac0 26>, <&dmac0 27>;
dma-names = "tx", "rx";
pinctrl-names = "default", "high_speed";
pinctrl-0 = <&spi3m0_cs0 &spi3m0_cs1 &spi3m0_pins>;
pinctrl-1 = <&spi3m0_cs0 &spi3m0_cs1 &spi3m0_pins_hs>;
status = "disabled";
};3-2 Pinctrl configuration
SPI3 M1 mode pin configuration (as used in the SDK code):
spi3m1_pins: spi3m1-pins {
rockchip,pins =
/* spi3_clkm1 */
<4 RK_PC2 2 &pcfg_pull_none>,
/* spi3_misom1 */
<4 RK_PC5 2 &pcfg_pull_none>,
/* spi3_mosim1 */
<4 RK_PC3 2 &pcfg_pull_none>,
};
spi3m1_cs0: spi3m1-cs0 {
rockchip,pins =
/_ spi3_cs0m1 _/
<4 RK_PC6 2 &pcfg_pull_none>;
};
spi3m1_pins_hs: spi3m1-pins {
rockchip,pins =
/_ spi3_clkm1 _/
<4 RK_PC2 2 &pcfg_pull_up_drv_level_1>;
/_ spi3_misom1 _/
<4 RK_PC5 2 &pcfg_pull_up_drv_level_1>;
/_ spi3_mosim1 _/
<4 RK_PC3 2 &pcfg_pull_up_drv_level_1>;
};Pin assignments:
- CLK (clock line): GPIO4_PC2, function multiplexing mode 2
- MISO (master-in, slave-out): GPIO4_PC5, function multiplexing mode 2
- MOSI (master-out, slave-in): GPIO4_PC3, function multiplexing mode 2
- CS0 (chip select 0): GPIO4_PC6, function multiplexing mode 2
Finally, check the board-level file for the SPI3 specific configuration:
&spi3 {
status = "okay";
pinctrl-0 = <&spi3m1_cs0 &spi3m1_pins>;
pinctrl-1 = <&spi3m1_cs0 &spi3m1_pins_hs>;
spidev:spidev@0 {
compatible = "rockchip,spidev";
reg = <0>;
spi-max-frequency = <10000000>;
status = "okay";
};
};3-3 Introduction to the above device tree
Pin multiplexing configurations
pinctrl-0: default speed mode pin configuration (uses mode m1)pinctrl-1: high-speed pin configuration (enhanced drive capability)
spidev device configuration
compatible= "rockchip,spidev": use Rockchip's generic SPI device driverreg= <0>: device address 0 (corresponding to CS0)spi-max-frequency= <10000000>: maximum SPI clock frequency is 10 MHz
4 SPI Usage --- NAPI Method
Data path
hap package: \05-Development Materials\01-OpenHarmony Development Materials\Peripheral Test APP\HAP\SPI_TEST.hap Projects source: \05-Development Materials\01-OpenHarmony Development Materials\Peripheral Test APP\SRC\SPI_TEST
3-2 Application Layer SPI Operations
The provided SDK has already included an SPI test program for the rk3568 platform, spi_selftest. The host sends "hello the world!", shorting MOSI and MISO; the input terminal receives data to verify proper operation. This helps developers verify that the SPI controller driver works correctly and that hardware connections are proper. Simply enter the target SPI device to execute the following command:
spi_selftest /dev/spidevxx3-3 Specific Function Demonstrations
Now test the SPI3 mounted on the board using the above commands:
- First, short MOSI and MISO on the board:

- In the terminal, enter: spi_selftest /dev/spidev3.0 to test data transmission and reception:
spi_selftest /dev/spidev3.0- Successfully received the bytes sent:

- If MOSI and MISO are not shorted, the test shows as failed:

4 SPI Usage --- NAPI Method
4-1 NAPI Program Details
To extract the NAPI C function details, see the following source:
// SPI Self-test NAPI binding example
static napi_value SPI_Test(napi_env env, napi_callback_info info) {
// (function body preserved for reference)
}4-1 Test Environment Preparation
First, connect to the development board using the HDC tool and grant read/write permissions to the system node:
mount -o remount,rw /
chmod 777 /system/bin/spi_selftest
chmod 777 /dev/spidev3.04-2 SPI Device Test APP Usage
Next, an introduction to the SPI device test APP created with NAPI:
After entering the program, a dropdown lets you select the SPI device (the board exposes "/dev/spidev3.0" only, so select that):
Click the SPI test button to start the test:

- The test will print terminal data; if sending and receiving are matching, the test succeeds:

- If the connection is broken, the test prints garbled data and reports failure:

4-3 NAPI Underlying C Functions Introduction
The following C function implements NAPI; the source is included for reference:
// example C implementation for NAPI SPI_TestProgram Details
The following explains the program details:
- First, use napi_get_cb_info to obtain the argument from JavaScript, i.e., the device path
- Use napi_get_value_string_utf8 to obtain the string length and convert to a C string
- Create a pipe for inter-process communication; read on the read end, write on the write end
- Fork a child process; child executes spi_selftest with the device path; parent reads the output
- The rest of the code can be found in the source file
(End of file)
