Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/device-tree-overlay/software-spi.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
title: Software SPI BUS
title: Software SPI Bus
---

import { GiscusDocComment } from '/src/components/GiscusComment';
Expand Down
169 changes: 169 additions & 0 deletions docs/guides/hardware-interfaces/using-spi-with-python.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
---
title: Using the SPI bus with Python
---

import { GiscusDocComment } from '/src/components/GiscusComment';

This guide will help you quickly get started using the Python `spidev` module to communicate with SPI devices on the Omega2.

## Step 0: Prerequisites

:::tip

If you haven't already, see the [quickstart guide](/quickstart/intro) for more information on setting up your Omega2.

:::

This guide assumes:
1. The Omega2 is connected to the internet via WiFi or ethernet
2. The Omega2 command line can be accessed

All commands listed in the guide should be run directly on the Omega2.

:::info

For a deeper dive into the Omega2's SPI functionality, see the [SPI article in the Hardware Interfaces chapter](/hardware-interfaces/spi.md).

:::

## Step 1: Install Python and the Spidev Module

To use SPI in Python, first install the necessary packages:

```
opkg update
opkg install python3-light python3-spidev
```

<!-- TODO: add a step where the user chooses between harware SPI or the sw spi? -->

## Step 2: Physically Connect an SPI Device

Before we can send data, we need to connect an SPI device to the Omega2's SPI bus.

### Pin Connections

Connect the SPI pins of your external device to the Omega2 according to this table:

| SPI Signal | Omega2 Pin |
|-------------|------------------|
| Clock / SCK | SPI_CLK / GPIO7 |
| MOSI | SPI_MOSI / GPIO8 |
| MISO | SPI_MISO / GPIO9 |
| CS | SPI_CS1 / GPIO6 |


Additionally, make sure the SPI device is supplied with power according to its specifications.

## Step 3: SPI Hello World - Write Bytes to the Device

To confirm that the SPI bus is working, we'll run a Python program that **writes 256 bytes of incremental data** over SPI in eight cycles.


### Download the Python Program

To do this, we will first download the `writebytes.py` example Python proscript from the [OnionIoT/python-spidev GitHub repo](https://github.com/OnionIoT/python-spidev/blob/master/examples/writebytes.py):

```
cd /root
wget https://raw.githubusercontent.com/OnionIoT/python-spidev/refs/heads/master/examples/writebytes.py
```

### Run the Program

Now, let’s run the script to send data over SPI:

```
python writebytes.py
```

This will send 256 bytes of incremental data (`0x00`, `0x01`, `0x02`, ...) over SPI, repeating 8 times. If you have a logic analyzer or oscilloscope connected, you should see activity.

<!-- TODO: add screenhot output of logic analyzer? -->

## Step 4: Half-Duplex SPI Transmission

Next, let's run a Python script that performs a half-duplex SPI transaction—meaning it writes a byte and immediately reads a specified number of bytes in return. This is useful for reading registers on an SPI device.

Next, let's run a Python program that performs a half-duplex SPI transaction - meaning it writes a number of bytes and immediately reads a specified number of bytes on the SPI bus. This is useful for reading registers on an SPI device.

### Download the Python Program

Download the `xfer3.py` example script from the [OnionIoT/python-spidev GitHub repo](https://github.com/OnionIoT/python-spidev/blob/master/examples/xfer3.py):

```
cd /root
wget https://raw.githubusercontent.com/OnionIoT/python-spidev/refs/heads/master/examples/xfer3.py
```

### Inspect the Program

Before running it, let's take a look at the script using the built-in `vi` text editor:

```
vi xfer3.py
```

We can see the program does the following:
- Opens SPI device 1 on bus 0, meaning it uses the CS1 chip select line on the SPI hardware bus
- Sets the SPI bus speed to 4MHz
- Performs a half-duplex transaction:
- Writes 1 byte: `0x42`
- Reads 2 bytes
- Prints the two bytes that were read

This kind of transaction is useful when interacting with SPI devices that store data in registers. In this example, the script reads two bytes from the register at address `0x42`.

To exit the vi editor without saving changes, type `:q!` and press Enter.

### Run the Program

How, execute the script:

```
python xfer3.py
```

### Observe the Output
The program will display the received bytes on the terminal:

```
root@Omega-FB94://# python xfer3.py
Half-duplex transmission: writing 1 byte, reading 2 bytes
Read: 0x11, 0x9a
Done
```

<!-- TODO: confirm above output -->

This confirms that the SPI device is responding to commands and returning data.



## Step 5: Off to the races!

You've seen how to:
1. Install the Python `spidev` module
2. Write data to the SPI bus.
3. Perform a half-duplex SPI transaction to write then read data from an SPI device.

These examples provide a strong foundation for working with SPI devices on the Omega2. You're now ready to modify these scripts or write your own SPI-based programs!

See the [README file in the OnionIoT/python-spidev GitHub repo](https://github.com/OnionIoT/python-spidev?tab=readme-ov-file#python-spidev) for more information on the methods available in the spidev module.

## Troubleshooting

If you're having issues, here are some things to check:

- Python module not found?
- Make sure `python3-spidev` is installed with `opkg list-installed | grep spidev`
- SPI device not responding?
- Double-check wiring with the [pinout table](#pin-connections)
- Verify that the SPI device is powered correctly.
- Ensure the correct chip select (CS) pin is being used.
- Unexpected data from the SPI device?
- Try adjusting the SPI clock speed in the script.
- Check if the SPI device requires specific initialization commands.


<GiscusDocComment />
31 changes: 29 additions & 2 deletions docs/hardware-interfaces/spi.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ The protocol is based on the **Master-Worker** architecture.

## Hardware

The Omega2 has one SPI interface available:
The Omega2 has one hardware SPI interface available:

- The interface supports half-duplex transmissions and can operate in host-mode only.
- The maximum SPI clock frequency is 40 MHz.
Expand Down Expand Up @@ -58,9 +58,36 @@ The SPI and CS1 pins are highlighted on the Omega2/2S diagrams below.
</TabItem>
</Tabs>


### Software-Based SPI Bus

In addition to the built-in hardware SPI bus, the Omega2 also supports **software-based SPI bus implementations**. This allows users to create additional SPI buses or use non-standard GPIOs for SPI communication, which is useful when:

- More than one SPI device needs to be connected
- Specific GPIOs need to be used for SPI communication
- Full-duplex SPI transactions are required (not supported on the Omega2’s hardware SPI bus)

#### How Software SPI Works
Unlike hardware SPI, which uses a dedicated controller to handle communication, software SPI "bit-bangs" GPIOs (manually toggling them on and off in software). This approach provides flexibility but is significantly slower and increases CPU load:

| Feature | Hardware SPI (CS1) | Software SPI |
|-------------------------|--------------------------------------|--------------|
| **Speed** | Up to **40MHz** (fast) | Slower, best for low-data applications |
| **Full-Duplex Support** | ❌ No on Omega2 | ✅ Yes |
| **SPI Configuration** | Limited; CS0 is reserved for flash | Flexible; can be configured as needed |
| **GPIO Flexibility** | Fixed to SPI pins | Any GPIOs can be used |
| **System Load** | Low (uses dedicated SPI controller) | Higher (CPU handles SPI signals) |


#### Enabling a Software SPI Bus
A software SPI bus can be enabled on the Omega2 by installing a **Device Tree Overlay** package. This allows developers to define which GPIOs should function as SPI signals when creating the Device Tree Overlay package.

For installation instructions and configuration details, see the [Software SPI Bus article in the Device Tree Overlay chapter](/device-tree-overlay/software-spi).


## Software

The Omega2 SPI interface is available at `/dev/spidev0.1`.
The Omega2 hardware SPI interface is available at `/dev/spidev0.1`.

- `spidev0` is the Omega2's SPI bus number.
- 1 indicates the device ID, which corresponds to the worker connected to the Omega2's CS1 pin.
Expand Down
8 changes: 8 additions & 0 deletions sidebars.js
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,14 @@ const sidebars = {
],
guides: [
'guides/intro',
{
type: 'category',
label: 'Hardware Interfaces',
collapsed: false,
items: [
'guides/hardware-interfaces/using-spi-with-python',
],
},
{
type: 'category',
label: 'Packages',
Expand Down