SPI
Serial Peripheral Interface (SPI) is a de facto standard (with many variants) for synchronous serial communication, mainly used for short-distance wired communication between integrated circuits in embedded systems.
Preparation
- A Rhino Pi-A1
- A female-to-female jumper wire
Connection
| No. | Board Silkscreen | GPIO/System Mapping | Description |
|---|---|---|---|
| 12 | SPI1_MISO | SPI1_MISO | SPI1 master-in slave-out, serial data receive channel |
| 14 | SPI1_MOSI | SPI1_MOSI | SPI1 master-out slave-in, serial data transmit channel |
| 16 | SPI1_CLK | SPI1_CLK | SPI1 serial clock, synchronizes bus data transmission |
| 18 | SPI1_CS_N | SPI1_CS_N | SPI1 chip select signal, active low, selects slave device |
Use a jumper wire to short-circuit pins 12 and 14 (MISO and MOSI loopback test).
Testing
- Check the spidev devices
shell
ls /dev/spidev*- Open a terminal and enter the command to install the required Python library.
shell
sudo pip3 install spidev- Create a file named spitest.py and paste the following code into it:
python
import spidev
import time
class SPILoopbackTester:
def __init__(self, bus=0, device=0, speed=1000000):
"""
Initialize the SPI loopback tester
:param bus: SPI bus number
:param device: SPI device number
:param speed: Communication speed (Hz)
"""
self.spi = spidev.SpiDev()
self.bus = bus
self.device = device
self.speed = speed
self.connected = False
def connect(self):
"""Connect to the SPI device"""
try:
self.spi.open(self.bus, self.device)
self.spi.max_speed_hz = self.speed
self.connected = True
print(f"Successfully connected to SPI bus {self.bus}, device {self.device}, speed {self.speed}Hz")
return True
except Exception as e:
print(f"SPI connection failed: {e}")
return False
def test_single_byte(self, test_byte):
"""Test the loopback of a single byte"""
if not self.connected:
print("Please connect the SPI device first")
return False
try:
# Send and receive data
rx_data = self.spi.xfer2([test_byte])
received_byte = rx_data[0]
# Verify the result
if received_byte == test_byte:
print(f"Test passed - sent: 0x{test_byte:02X}, received: 0x{received_byte:02X}")
return True
else:
print(f"Test failed - sent: 0x{test_byte:02X}, received: 0x{received_byte:02X}")
return False
except Exception as e:
print(f"Test error: {e}")
return False
def test_multiple_bytes(self, test_data):
"""Test the loopback of multiple bytes"""
if not self.connected:
print("Please connect the SPI device first")
return False
try:
# Send and receive data
rx_data = self.spi.xfer2(test_data)
# Verify the result
success = True
print("Multi-byte test results:")
print("Sent\tReceived\tResult")
print("-" * 30)
for tx, rx in zip(test_data, rx_data):
status = "Passed" if tx == rx else "Failed"
if tx != rx:
success = False
print(f"0x{tx:02X}\t0x{rx:02X}\t{status}")
return success
except Exception as e:
print(f"Test error: {e}")
return False
def run_complete_test(self):
"""Run the complete test suite"""
print("\n===== Starting SPI loopback test =====")
print(f"Test configuration: bus={self.bus}, device={self.device}, speed={self.speed}Hz")
# Test individual special bytes
test_bytes = [0x00, 0xFF, 0xAA, 0x55, 0x33, 0xCC]
single_byte_result = True
print("\n----- Single-byte test -----")
for b in test_bytes:
if not self.test_single_byte(b):
single_byte_result = False
# Test a random sequence
print("\n----- Multi-byte sequence test -----")
sequence = list(range(0, 256, 16)) # 0x00, 0x10, 0x20, ..., 0xF0
multi_byte_result = self.test_multiple_bytes(sequence)
# Test continuous data
print("\n----- Continuous data test -----")
continuous_data = list(range(10, 20)) # Consecutive numbers from 10 to 19
continuous_result = self.test_multiple_bytes(continuous_data)
# Overall result
print("\n===== Test summary =====")
overall_result = single_byte_result and multi_byte_result and continuous_result
if overall_result:
print("✅ All SPI loopback tests passed!")
else:
print("❌ Some SPI loopback tests failed!")
return overall_result
def close(self):
"""Close the SPI connection"""
if self.connected:
self.spi.close()
self.connected = False
print("\nSPI connection closed")
if __name__ == "__main__":
# Create the tester instance (default uses SPI0, CE0)
tester = SPILoopbackTester(bus=1, device=0, speed=1000000)
try:
if tester.connect():
# Run the complete test
tester.run_complete_test()
time.sleep(1)
finally:
# Ensure resources are released properly
tester.close()- After saving, enter the following command to test
shell
sudo python3 spitest.py- Check the output result
The result will print "All SPI loopback tests passed!"