SC-OBC Module A1 Software Manual

1. Setup the Development Environment

1.1. Prepare the Software

1.1.1. Target Platform

This document is focused on Ubuntu 24.04 x86_64 systems.

You can use any of the following setups:

  • A PC with Ubuntu installed

  • A system container (e.g., Incus)

  • A virtual machine (e.g., QEMU, VirtualBox, VMware)

  • WSL2 (see TIP)

For Windows or macOS users, refer to the official Zephyr documentation.

According to the Zephyr documentation, WSL is currently not supported. However, we have confirmed that the procedures in this document can be executed by enabling USB device attached to WSL2 using the steps described below.
- Connect USB devices
The following two USB devices need to be attached to WSL2:
- USB Serial Converter A, USB Serial Converter B
- CMSIS-DAP v2 Interface, USB Serial Device
We have confirmed that the west flash command takes longer to complete on WSL2 compared to native Linux. (65 KBytes writing: WSL2 - about 1 minute / Native Linux – about 20 seconds)

1.1.2. Install Required Dependencies

This section is mostly the same as Zephyr official documentation.
Update your system
sudo apt update && sudo apt upgrade
Install dependencies
sudo apt install --no-install-recommends git cmake ninja-build gperf \
  ccache dfu-util device-tree-compiler wget \
  python3-dev python3-pip python3-setuptools python3-tk python3-wheel xz-utils file \
  make gcc gcc-multilib g++-multilib libsdl2-dev libmagic1

1.1.3. Get Zephyr and Python Requirements

Create your working directory
mkdir -p ~/myproject && cd ~/myproject
Install the Python venv package
sudo apt install python3-venv
Create a new virtual environment
python3 -m venv ~/myproject/.venv
Activate the virtual environment
source ~/myproject/.venv/bin/activate
Install the west
pip install west
Clone the SC-OBC Module A1 sample repository using west
cd ~/myproject
west init -m https://github.com/spacecubics/scobc-a1-sample
west update
west zephyr-export
Install the Python requirements
west packages pip --install

1.1.4. Install the Zephyr SDK

west sdk install

1.1.5. Install udev rules

Install the udev rules, which allow you to flash most Zephyr boards as a regular user.

sudo cp ~/zephyr-sdk-[VERSION]/sysroots/x86_64-pokysdk-linux/usr/share/openocd/contrib/60-openocd.rules \
        /etc/udev/rules.d
sudo udevadm control --reload

Install the packages required for flashing via OpenOCD.

sudo apt install libftdi1 libgpiod2 libhidapi-hidraw0 libcapstone4

1.1.7. Install the tio package

Although there are several tools available for working with a serial console, this document uses tio.

sudo apt install tio

1.2. Connect the Hardware

Before starting development, make sure you have the following components:

  • ✔️ SC-OBC Module A1

  • ✔️ SC-OBC Module A1 Development Board

  • ✔️ USB Cable

    • ✔️ Console Cable (TypeA - microB)

    • ✔️ OpenOCD Cable

  • ✔️ AC Adapter (5V/3.0A PL03B)

Refer to SC-OBC Module A1 Development Board Product Manual for detailed instructions on how to make the connection.

The OpenOCD cable should be connected to a device such as the Raspberry Pi Debug Probe.
Connect each signal line from the Raspberry Pi Debug Probe to the following connector:
- UIO4_01: SWCLK (SC)
- UIO4_02: SWDIO (SD)
- Any GND: GND
This document does not require a connection between the MPLAB PICkit and the Platform Cable USB II.

1.3. Check the DIP Switch status

To use the Zephyr console, bit3 (TX) and bit4 (RX) of DIP Switch (SW1) must be turned ON. If they are currently OFF, please switch them ON.

1.4. Power ON the SC-OBC Module A1 Development Board

Once all connections and checks have been completed, switch ON the power switch (SW2) on the Development Board to apply power.

2. Try Sample Applications on SC-OBC Module A1

Zephyr provides many so-called sample applications. The Zephyr documentation has a dedicated page called Samples and Demos.
In this section, we’ll build a few samples from Zephyr and run them on your SC-OBC Module A1.

On the Samples and Demos page, you can interactively search samples. There are over 500 samples in Zephyr v4.1.
Using the web interface is much easier than checking each sample’s README.rst.

If you haven’t created your workspace yet, go back to the previous section and do so.
In this section, we assume you have already set up your development environment and are ready to proceed.

2.1. Blinky sample

The first sample is Blinky. This application blinks an LED on your Development Board.

2.1.1. Build

cd ~/myproject
python3 -m venv ~/zephyrproject/.venv
west build -p always -b scobc_a1 --shield scobc_a1_dev zephyr/samples/basic/blinky

This should build your first application, Blinky.

These steps match the Build the Blinky Sample section in the Zephyr documentation.

2.1.2. Flash

Next, we’ll flash the SC-OBC Module A1:

west flash

2.1.3. Confirm

After flashing, power-cycle the SC-OBC Module A1. You should see the blinking LED (LED11).

2.2. Hello World sample

Next is the ever-popular Hello World sample. Before running Hello World, we need to set up the serial connection so the module can send output to your PC.

2.2.1. Open Console

Connect the cable between your SC-OBC Module A1 and your PC, then open the console on terminal:

tio /dev/ttyUSB0
To use the Zephyr console, bit3 (TX) and bit4 (RX) of DIP Switch (SW1) must be turned ON. If they are currently OFF, please switch them ON.

2.2.2. Build

Then open the another terminal, and build the sample.

cd ~/myproject
python3 -m venv ~/zephyrproject/.venv
west build -p always -b scobc_a1 --shield scobc_a1_dev zephyr/samples/hello_world

2.2.3. Flash

Next, we’ll flash the SC-OBC Module A1:

west flash

2.2.4. Confirm

After power-cycle the SC-OBC Module A1, you should see the Hello World string on your serial console. If you want to exit the tio console, first press Ctrl + t, followed by q.

3. Try developing applications on SC-OBC Module A1

3.1. Introduction

This section explains how to develop applications using Zephyr’s T2 topology.
Several sample applications are provided to help explain the source code structure, build process, and other development practices.

3.2. What is T2 topology

Details of the T2 topology can be found in T2 topology, but it has the following characteristics:

  • Applications can be managed in a dedicated (custom) repository

  • Zephyr and other projects can be managed as sub modules

  • Zephyr drivers can be managed out-of-tree in a dedicated (custom) repository

3.3. Hello World sample

This section provides an example of building and running the simplest Hello World application within a T2 topology-based repository.
The sample application is available in Hello World sample.

3.3.1. Explain the sample code

Directory name

The directory name and structure for the sample application can be chosen freely.
In this example, we use the directory name sample/hello_world.

CMakefile.txt

A CMakeLists.txt file must be placed directly under the application directory.

# Copyright (c) 2025 Space Cubics Inc.
# SPDX-License-Identifier: Apache-2.0

cmake_minimum_required(VERSION 3.20.0)

find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(hello-world)

target_sources(app PRIVATE src/main.c)

Here, the parts that need to be modified for each application are explained.

  • project: Specify the desired project name

  • target_sources: Specify the source code file(s)

prj.conf

Additional Kconfig parameters required for running the application can be specified.
For this Hello World application, no additional parameters are required, so leaving it empty is fine.

# nothing here
Source code

The source code is equivalent to the sample code provided by Zephyr, but the displayed parameters have been modified.
In the Zephyr sample code, CONFIG_BOARD_TARGET was displayed, but in this sample, the board name (CONFIG_BOARD) and the revision (CONFIG_BOARD_REVISION) are displayed separately.

/*
 * Copyright (c) 2025 Space Cubics Inc.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <stdio.h>

int main(void)
{
	printf("Hello World! %s Rev %s\n", CONFIG_BOARD, CONFIG_BOARD_REVISION);

	return 0;
}
The variable names starting with CONFIG_ store parameters specified in Zephyr’s Kconfig. To know all the Kconfig parameters, you can refer to the ~/myproject/build/zephyr/zephyr.dts file.

3.3.2. Open console

Connect the cable between your SC-OBC Module A1 and your PC, then open the console on terminal:

tio /dev/ttyUSB0
To use the Zephyr console, bit3 (TX) and bit4 (RX) of DIP Switch (SW1) must be turned ON. If they are currently OFF, please switch them ON.

3.3.3. Build

Specify the sample application directory where CMakeLists.txt and prj.conf are placed, and then build as shown below.

cd ~/myproject
python3 -m venv ~/zephyrproject/.venv
west build -p always -b scobc_a1 --shield scobc_a1_dev scobc-a1-sample/samples/hello_world

3.3.4. Flash

Next, we’ll flash the SC-OBC Module A1:

west flash

3.3.5. Confirm

After power-cycle the SC-OBC Module A1, you should see the "Hello World" string on the console along with the board name and revision.

*** Booting Zephyr OS build 60e8eb54f7ae ***
Hello World! scobc_a1 Rev 2.0.0

If you want to exit the tio console, first press Ctrl + t, followed by q.

3.4. System Monitor sample

This section provides an example of building and running the System Monitor application within a T2 topology-based repository.

3.4.1. What is the System Monitor

Details of the System Monitor can be found in System Monitor, but it has the following characteristics:

FPGA Watchdog

The system of the SC-OBC Module A1 is monitored by the TRCH (Timing, Reset, Config & Health Controller), and the FPGA reports its internal status to the TRCH via the watchdog signal.

the Monitoring by TRCH is disabled by default, so using the FPGA Watchdog feature is not mandatory.
SEM Controller

The SEM (Soft Error Mitigation) Controller is a solution provided by AMD for detecting and correcting errors that occur in the configuration memory of AMD FPGAs.
The SC-OBC Module A1 FPGA integrates this functionality into the system and provides access to the SEM Controller’s status through the System Monitor registers.

Board Health Monitor (BHM)

The Board Health Monitor (BHM) is a feature that enables easy retrieval of data from sensors mounted on the SC-OBC Module A1.
The OBC module is equipped with two current and voltage monitors and three temperature sensors.
The BHM allows automatic data acquisition from these sensors without requiring complex I2C operations in software.

System Monitor driver

Currently, the following Zephyr driver APIs are provided for controlling the FPGA’s System Monitor.

Table 1. System Monitor Driver API List
Function API Summary Parameters Returns

FPGA Watchdog

sc_kick_wdt_timer

Toggle the FPGA Watch Dog Timer

SEM Controller

sc_sem_get_error_count

Get the SEM error count

Current SEM error count

Board Health Monitor (BHM)

sc_bhm_enable

Enable the monitoring by BHM
NOTE: Currently monitoring interval is fixed by 1 seconds

0: Success
-ETIMEDOUT: Timeout for sensor device initializing

sc_bhm_disable

Disable the monitoring by BHM

0: Success

sc_bhm_get_obc_temp

Get the on board temperature sensor value

pos: Position for sensor device
<Selectable parameter>
SCOBC_A1_TEMP_1
SCOBC_A1_TEMP_2
SCOBC_A1_TEMP_3

temp Temperature [degree]

0: Success
-ENODEV: Wrong parameter
--EAGAIN: No updated sensor values

sc_bhm_get_xadc_temp

Get the FPGA DAI temperature sensor value

temp: Temperature [degree]

0: Success
--EAGAIN: No updated sensor values

sc_bhm_get_obc_cv

Get the on board Current/Voltage sensor value

pos: Position for sensor device
<Selectable parameter>
SCOBC_A1_1V0_SHUNT
SCOBC_A1_1V0_BUS
SCOBC_A1_1V8_SHUNT
SCOBC_A1_1V8_BUS
SCOBC_A1_3V3_SHUNT
SCOBC_A1_3V3_BUS
SCOBC_A1_3V3_SYSA_SHUNT
SCOBC_A1_3V3_SYSA_BUS
SCOBC_A1_3V3_SYSB_SHUNT
SCOBC_A1_3V3_SYSB_BUS
SCOBC_A1_3V3_IO_SHUNT
SCOBC_A1_3V3_IO_BUS

cv: Current sensor value [mA] / Voltage sensor value [mV]

0: Success
--EAGAIN: No updated sensor values

sc_bhm_get_xadc_cv

Get the FPGA voltage value

pos: Position for sensor device
<Selectable parameter>
SCOBC_A1_XADC_VCCINT
SCOBC_A1_XADC_VCCAUX
SCOBC_A1_XADC_VCCBRAM

cv: FPGA Voltage value [mV]

0: Success
--EAGAIN: No updated sensor values

These APIs are provided as an out-of-tree driver and are available in System Monitor Driver.

System Monitor sample

The sample application is available in System Monitor sample.

3.4.2. Explain the sample code

Directory name

The directory name and structure for the sample application can be chosen freely.
In this example, we use the directory name sample/sysmon.

CMakefile.txt

A CMakeLists.txt file must be placed directly under the application directory.

# Copyright (c) 2025 Space Cubics Inc.
# SPDX-License-Identifier: Apache-2.0

cmake_minimum_required(VERSION 3.20.0)

find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(system-monitor)

target_sources(app PRIVATE src/main.c)

Here, the parts that need to be modified for each application are explained.

  • project: Specify the desired project name

  • target_sources: Specify the source code file(s)

prj.conf

Additional Kconfig parameters required for running the application can be specified.
In this sample, to display temperature data of type float using printf, it is necessary to enable CONFIG_PICOLIBC_IO_FLOAT.
For more information about CONFIG_PICOLIBC_IO_FLOAT, refer to CONFIG_PICOLIBC_IO_FLOAT.

CONFIG_PICOLIBC_IO_FLOAT=y
Source code

The source code is shown below. Details will be explained separately.

/*
 * Copyright (c) 2025 Space Cubics Inc.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/kernel.h>
#include "sc_sysmon.h"

int main(void)
{
	int ret;
	float temp;
	int32_t bus;

	ret = sc_bhm_enable();
	if (ret < 0) {
		printf("Failed to enable the Board Health Monitor: %d\n", ret);
		goto end;
	}

	/* Wait for the first monitoring to finish */
	k_sleep(K_SECONDS(1));

	while (true) {
		ret = sc_bhm_get_obc_temp(SCOBC_A1_TEMP_1, &temp);
		if (ret < 0) {
			printf("Failed to get the on Board Temperature 1: %d\n", ret);
			goto end;
		}
		printf("On Board Tempareture 1 : %.4f [deg]\n", (double)temp);

		ret = sc_bhm_get_obc_cv(SCOBC_A1_3V3_BUS, &bus);
		if (ret < 0) {
			printf("Failed to get the 3V3SYS Bus voltage: %d\n", ret);
			goto end;
		}
		printf("3V3SYS Bus voltage     : %d [mv]\n", bus);

		k_sleep(K_SECONDS(1));
	}

end:
	sc_bhm_disable();

	return ret;
}
Include System Monitor driver header

Include the header file for the System Monitor driver.

#include "sc_sysmon.h"
Enable BHM

Enable the System Monitor by FPGA BHM. If a non-zero value is returned, sensor initialization has failed.

	ret = sc_bhm_enable();
	if (ret < 0) {
		printf("Failed to enable the Board Health Monitor: %d\n", ret);
		goto end;
	}
Wait 1 seconds

The current System Monitor driver API does not allow customization of the monitoring interval via BHM;
it is fixed at 1 second. Therefore, waits for 1 second until the first data collection is completed.

	k_sleep(K_SECONDS(1));
Get the on board temperature sensor value

Get the temperature data from onboard temperature sensor 1 and display it on the console.
If a non-zero value is returned, it may indicate that the temperature sensor data has not been updated within the FPGA.
If you’d like to get other values, try changing the SCOBC_A1_TEMP_1 to a different parameter of your choice, as referenced in Table 1. System Monitor Driver API List

		ret = sc_bhm_get_obc_temp(SCOBC_A1_TEMP_1, &temp);
		if (ret < 0) {
			printf("Failed to get the on Board temperature 1: %d\n", ret);
			goto end;
		}
		printf("On Board tempareture 1 : %.4f [deg]\n", (double)temp);
Get the on board voltage sensor value

Get the 3V3SYS BUS voltage value data from onboard voltage sensor and display it on the console.
If a non-zero value is returned, it may indicate that the temperature sensor data has not been updated within the FPGA.
If you’d like to get other values, try changing the SCOBC_A1_3V3_BUS to a different parameter of your choice, as referenced in Table 1. System Monitor Driver API List

		ret = sc_bhm_get_obc_cv(SCOBC_A1_3V3_BUS, &bus);
		if (ret < 0) {
			printf("Failed to get the 3V3SYS Bus voltage: %d\n", ret);
			goto end;
		}
		printf("3V3SYS Bus voltage     : %d [mv]\n", bus);

3.4.3. Open console

Connect the cable between your SC-OBC Module A1 and your PC, then open the console on terminal:

tio /dev/ttyUSB0
To use the Zephyr console, bit3 (TX) and bit4 (RX) of DIP Switch (SW1) must be turned ON. If they are currently OFF, please switch them ON.

3.4.4. Build

Specify the sample application directory where CMakeLists.txt and prj.conf are placed, and then build as shown below.

cd ~/myproject
python3 -m venv ~/zephyrproject/.venv
west build -p always -b scobc_a1 --shield scobc_a1_dev scobc-a1-sample/samples/sysmon

3.4.5. Flash

Next, we’ll flash the SC-OBC Module A1:

west flash

3.4.6. Confirm

Confirm that the temperature from the on board temperature sensor and the 3V3SYS bus voltage are displayed on the console every second.

*** Booting Zephyr OS build 60e8eb54f7ae ***
On Board Tempareture 1 : 28.5000 [deg]
3V3SYS Bus voltage     : 3256 [mv]
On Board Tempareture 1 : 28.5000 [deg]
3V3SYS Bus voltage     : 3256 [mv]
On Board Tempareture 1 : 28.5000 [deg]
3V3SYS Bus voltage     : 3256 [mv]

If you want to exit the tio console, first press Ctrl + t, followed by q.

4. Device Tree

Before introducing a sample application that uses a Zephyr driver, we believe it is helpful to first explain the Device Tree, as this will aid in understanding the source code more effectively.

4.1. What is the Device Tree?

The Device Tree is a data structure originally developed as part of the Open Firmware specification (IEEE 1275), where it was used to describe the hardware layout of systems such as PowerPC-based workstations and servers.

This concept was later adopted and popularized in the Linux kernel, particularly for platforms like ARM and PowerPC, to enable the kernel to support multiple hardware configurations without requiring separate builds or hardcoded board-specific initialization.

A Device Tree describes the physical components of a system — such as CPUs, memory, buses, and peripheral devices — in a structured and hierarchical format. This hardware description is typically written in a human-readable Device Tree Source (DTS) file, which is compiled into a binary Device Tree Blob (DTB) using the Device Tree Compiler (DTC). The DTB is then passed to the Linux kernel at boot time to guide hardware initialization.

4.2. Device Tree in Zephyr

In Zephyr, the Device Tree model was adopted to improve scalability and modularity across a wide variety of supported boards and SoCs. Unlike in Linux, where the DTB is loaded at runtime, Zephyr parses the DTS at build time to generate static configuration headers.

This enables lightweight and efficient hardware abstraction, while still benefiting from the flexibility and reusability that Device Tree provides.

  • Hardware Abstraction

    • Describes hardware outside application code, reducing hardware-specific logic in C files.

  • Portability

    • A single source tree can support multiple hardware variants by simply switching DTS files.

  • Maintainability

    • Easier to add support for new boards or SoCs without modifying existing drivers or core logic.

  • Scalability

    • Makes it easier to manage families of devices with similar but not identical hardware configurations.

4.3. Common Usage of the Device Tree in Zephyr

In Zephyr, the Device Tree is used to:

  • Define and configure peripherals like UART, I2C, SPI, GPIO, CAN, and more.

  • Bind drivers to hardware automatically based on compatible strings.

  • Pass hardware parameters to applications via macros generated from the DTS (e.g., base addresses, interrupts, labels).

  • Manage multiple board variants using overlays.

4.4. Basic Structure

A Device Tree is structured like a filesystem, with nodes and properties: Nodes represent hardware components (e.g., /cpu, /memory, /soc/gpio@40020000)

Properties are key-value pairs describing attributes like addresses, interrupts, clocks, and more.

This introduction is a starting point. For deeper understanding, consider reviewing the official Zephyr device tree documentation.

5. Try applications development using Zephyr Driver

5.1. Introduction

This section explains how to develop applications using Zephyr Driver.
Several sample applications are provided to explain how to check the Device Tree and how to use drivers.

5.2. GPIO Driver sample

Using this GPIO driver, the LED on the Development Board will blink. The sample application is available in Blinky sample.

5.2.1. Explain the sample code

Directory Name

The directory name and structure for the sample application can be chosen freely.
In this example, we use the directory name sample/blinky.

CMakefile.txt

A CMakeLists.txt file must be placed directly under the application directory.

# Copyright (c) 2025 Space Cubics Inc.
# SPDX-License-Identifier: Apache-2.0

cmake_minimum_required(VERSION 3.20.0)

find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(blinky)

target_sources(app PRIVATE src/main.c)

Here, the parts that need to be modified for each application are explained.

  • project: Specify the desired project name

  • target_sources: Specify the source code file(s)

prj.conf

Additional Kconfig parameters required for running the application can be specified.
As this example uses GPIO, it is necessary to set CONFIG_GPIO=y.

CONFIG_GPIO=y
Source code

The source code is shown below. Details will be explained separately.

/*
 * Copyright (c) 2025 Space Cubics Inc.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/drivers/gpio.h>

int main(void)
{
	int ret;
	const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(DT_ALIAS(led0), gpios);
	bool led_state = true;

	if (!gpio_is_ready_dt(&led)) {
		printf("GPIO device is not ready\n");
		return -1;
	}

	ret = gpio_pin_configure_dt(&led, GPIO_OUTPUT_ACTIVE);
	if (ret < 0) {
		printf("Failed to configure a GPIO pin (%d)\n", ret);
		return -1;
	}

	while (true) {
		ret = gpio_pin_toggle_dt(&led);
		if (ret < 0) {
			printf("Failed to toggle a GPIO pin (%d)\n", ret);
			return -1;
		}

		led_state = !led_state;
		printf("LED state: %s\n", led_state ? "ON" : "OFF");
		k_sleep(K_SECONDS(1));
	}

	return 0;
}
GPIO Device structure

The SC-OBC Module A1 is equipped with AMD (formerly Xilinx)'s AXI GPIO IP core, which connects to 10 GPIOs.
The relationship between the GPIOs and the User IO pins is as follows, with GPIO15 connected to the _LED11_on the Development Board.

Table 2. GPIO pins List
User IO pin name GPIO name in AMD GPIO IP core

UIO2_15

GPIO15

UIO2_14

GPIO14

UIO2_13

GPIO13

UIO2_12

GPIO12

UIO2_11

GPIO11

UIO2_10

GPIO10

UIO2_09

GPIO9

UIO2_08

GPIO8

UIO2_07

GPIO7

UIO2_06

GPIO6

Referring to the DTS overlay file for Development Board, it can be seen that GPIO15 of the GPIO IP core is defined with the device name user_led_0.
Additionally, an led0 is assigned using the alias, which is used by Zephyr’s blinky sample. However, this alias is not mandatory.

	aliases {
		led0 = &user_led_0;
		sw0 = &user_sw_0;
	};

	leds {
		compatible = "gpio-leds";
		user_led_0: led_0 {
			gpios = <&gpio0 15 GPIO_ACTIVE_LOW>;
		};
	};

Therefore, in this example, the GPIO device structure is obtained using GPIO_DT_SPEC_GET and DT_ALIAS.

	const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(DT_ALIAS(led0), gpios);
Validate that GPIO port is ready

Validate that GPIO port is ready. If the GPIO device is not properly initialized, it will return false.

	if (!gpio_is_ready_dt(&led)) {
		printf("GPIO device is not ready\n");
		return -1;
	}
Configure a GPIO pin

The GPIO is configured to its initial state as OUTPUT_ACTIVE. If the configuration fails, a non-zero value will be returned.

	ret = gpio_pin_configure_dt(&led, GPIO_OUTPUT_ACTIVE);
	if (ret < 0) {
		printf("Failed to configure a GPIO pin (%d)\n", ret);
		return -1;
	}
Toggle a GPIO pin

Toggle the GPIO pin. If the toggle fails, a non-zero value will be returned.

	ret = gpio_pin_toggle_dt(&led);
	if (ret < 0) {
		printf("Failed to toggle a GPIO pin (%d)\n", ret);
		return -1;
	}

5.2.2. Open console

Connect the cable between your SC-OBC Module A1 and your PC, then open the console on terminal:

tio /dev/ttyUSB0
To use the Zephyr console, bit3 (TX) and bit4 (RX) of DIP Switch (SW1) must be turned ON. If they are currently OFF, please switch them ON.

5.2.3. Build

Specify the sample application directory where CMakeLists.txt and prj.conf are placed, and then build as shown below.

cd ~/myproject
python3 -m venv ~/zephyrproject/.venv
west build -p always -b scobc_a1 --shield scobc_a1_dev scobc-a1-sample/samples/blinky

5.2.4. Flash

Next, we’ll flash the SC-OBC Module A1:

west flash

5.2.5. Confirm

After power-cycle the SC-OBC Module A1, you should see that the LED11 will blink on and off every second, and the LED state will be displayed on the console.

*** Booting Zephyr OS build 60e8eb54f7ae ***
LED state: OFF
LED state: ON
LED state: OFF
LED state: ON

If you want to exit the tio console, first press Ctrl + t, followed by q.

5.3. I2C Driver sample

Using the I2C driver for the SC-OBC Module A1, this application gets a temperature data from the sensor on the Development Board and displays it on the console. The sample application is available in I2C sample.

5.3.1. Explain the sample code

Directory Name

The directory name and structure for the sample application can be chosen freely.
In this example, we use the directory name sample/i2c.

CMakefile.txt

A CMakeLists.txt file must be placed directly under the application directory.

# Copyright (c) 2025 Space Cubics Inc.
# SPDX-License-Identifier: Apache-2.0

cmake_minimum_required(VERSION 3.20.0)

find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(i2c-sample)

target_sources(app PRIVATE src/main.c)

Here, the parts that need to be modified for each application are explained.

  • project: Specify the desired project name

  • target_sources: Specify the source code file(s)

prj.conf

Additional Kconfig parameters required for running the application can be specified.
As this example uses I2C, it is necessary to set CONFIG_I2C=y.
And, to display temperature data of type float using printf, it is necessary to enable CONFIG_PICOLIBC_IO_FLOAT.
For more information about CONFIG_PICOLIBC_IO_FLOAT, refer to CONFIG_PICOLIBC_IO_FLOAT.

CONFIG_I2C=y
CONFIG_PICOLIBC_IO_FLOAT=y
Source code

The source code is shown below. Details will be explained separately.

/*
 * Copyright (c) 2025 Space Cubics Inc.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/drivers/i2c.h>

#define TMP175_I2C_ADDR (0x4B)
#define TMP175_TEMP_REG (0x00)

int main(void)
{
	int ret;
	uint8_t data[2];
	float temp;

	const struct device *i2c = DEVICE_DT_GET(DT_NODELABEL(i2c0));

	if (!device_is_ready(i2c)) {
		printf("I2C device is not ready\n");
		ret = -1;
		goto end;
	}

	ret = i2c_burst_read(i2c, TMP175_I2C_ADDR, TMP175_TEMP_REG, data, ARRAY_SIZE(data));
	if (ret < 0) {
		printf("Failed to read from Temperature Sensor (%d)\n", ret);
		goto end;
	}

	/*
	 * The TMP175 temperature sensor provides temperature data with a 12-bit, and resolution
	 * is 0.0625°C. Since the data is transmitted over I2C as 16 bits, the lower 4 bits of
	 * the second byte should be discarded. For more details, please refer to the TMP175
	 * datasheet.
	 */
	data[1] = data[1] >> 4;
	temp = (int8_t)data[0] + (float)data[1] * 0.0625f;

	printf("Temperature: %.4f [deg]\n", (double)temp);

end:
	return ret;
}
Device structure

To use the I2C driver API, it is necessary to obtain the corresponding device structure.
There are several APIs available for retrieving a device structure, but in this sample, DEVICE_DT_GET and DT_NODELABEL are used.
The label name specified in DT_NODELABEL must match the label defined in the DTS file. The I2C device connected to the temperature sensor on the Development Board is defined in DTS overlay file for Development Board.

Although tree FPGA I2C cores are available on the Development Board, the temperature sensor is connected to i2c0.

	const struct device *i2c = DEVICE_DT_GET(DT_NODELABEL(i2c0));
Because the DTS file may be defined across multiple sources via overlays, you may want to inspect the final merged DTS.
This merged DTS is available in the following file under the build directory.

~/myproject/build/zephyr/zephyr.dts
Validate that I2C device is ready

Validate that I2C device is ready. If the I2C device is not properly initialized, it will return false.

	if (!device_is_ready(i2c)) {
		printf("I2C device is not ready\n");
		ret = -1;
		goto end;
	}
I2C driver API

The APIs provided by the I2C driver are documented in the I2C interface.
In this example, it is necessary to read 2 bytes of temperature data from the sensor, so the i2c_burst_read API is used to perform a multi-byte read from the I2C device.
The second argument specifies the slave address of the I2C device. For the TMP175 temperature sensor used in this example, the slave address is set to 0x4B.
The third argument specifies the register address from which the temperature data will be read. This register address must be obtained from the TMP175 datasheet. For TMP175, the temperature register address is 0x00.

	ret = i2c_burst_read(i2c, TMP175_I2C_ADDR, TMP175_TEMP_REG, data, ARRAY_SIZE(data));
Calculate temperature data

The TMP175 temperature data is represented in 12 bits, and its resolution is 0.0625. Therefore, the raw value is converted before being printed to the console.
For more details, please refer to the TMP175 datasheet.

	data[1] = data[1] >> 4;
	temp = (int8_t)data[0] + (float)data[1] * 0.0625f;

5.4. Check the DIP Switch status

To access the temperature sensor on the Development Board, bit5 (SCL) and bit6 (SDA) of DIP Switch (SW1) must be turned ON. If they are currently OFF, please switch them ON.

5.4.1. Open console

Connect the cable between your SC-OBC Module A1 and your PC, then open the console on terminal:

tio /dev/ttyUSB0
To use the Zephyr console, bit3 (TX) and bit4 (RX) of DIP Switch (SW1) must be turned ON. If they are currently OFF, please switch them ON.

5.4.2. Build

Specify the sample application directory where CMakeLists.txt and prj.conf are placed, and then build as shown below.

cd ~/myproject
python3 -m venv ~/zephyrproject/.venv
west build -p always -b scobc_a1 --shield scobc_a1_dev scobc-a1-sample/samples/i2c

5.4.3. Flash

Next, we’ll flash the SC-OBC Module A1:

west flash

5.4.4. Confirm

After power-cycle the SC-OBC Module A1, you should see the temperature data retrieved from the sensor is displayed on the serial console.

*** Booting Zephyr OS build 60e8eb54f7ae ***
Temperature: 31.5000 [deg]

If you want to exit the tio console, first press Ctrl + t, followed by q.