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
30 changes: 30 additions & 0 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,21 @@ jobs:
- name: Fmt
run: cd ./examples/rust-examples/xtensa-esp32/scheduler/cooperative && cargo fmt --all -- --check

xtensa-esp32-rust-example-uart:
runs-on: ubuntu-latest
env:
CARGO_HOME: /root/.cargo
RUSTUP_HOME: /root/.rustup
container:
image: arkhipovivan1/xtensa-esp32-rust:latest
options: --user root
steps:
- uses: actions/checkout@v3
- name: Build
run: cd ./examples/rust-examples/xtensa-esp32/uart && . /root/export-esp.sh && cargo build
- name: Fmt
run: cd ./examples/rust-examples/xtensa-esp32/uart && cargo fmt --all -- --check

xtensa-esp32-static-library:
runs-on: ubuntu-latest
env:
Expand Down Expand Up @@ -231,6 +246,21 @@ jobs:
- name: Fmt
run: cd ./examples/rust-examples/risc-v-esp32-c6/wifi && cargo fmt --all -- --check

risc-v-esp32c6-rust-example-uart:
runs-on: ubuntu-latest
env:
CARGO_HOME: /root/.cargo
RUSTUP_HOME: /root/.rustup
container:
image: arkhipovivan1/xtensa-esp32-rust:latest
options: --user root
steps:
- uses: actions/checkout@v3
- name: Build
run: cd ./examples/rust-examples/risc-v-esp32-c6/uart && . /root/export-esp.sh && cargo build
- name: Fmt
run: cd ./examples/rust-examples/risc-v-esp32-c6/uart && cargo fmt --all -- --check

risc-v-esp32c6-rust-example-scheduler:
runs-on: ubuntu-latest
env:
Expand Down
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ default = []
c-library = []
cooperative = []
preemptive = []
uart = []
network = ["esp-wifi"]
mips64_timer_tests = []
cooperative_tests = []
Expand Down
2 changes: 1 addition & 1 deletion examples/c-examples/xtensa-esp32/ld/esp32.ld
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ MEMORY
/* TODO: Use human-readable lengths */
/* TODO: Use the full memory map - this is just a test */
iram_seg ( RX ) : ORIGIN = 0x40080400, len = 0xFC00
dram_seg ( RW ) : ORIGIN = 0x3FFF0000, len = 0x10120
dram_seg ( RW ) : ORIGIN = 0x3FFF0000, len = 0x10200
}

/* Define output sections */
Expand Down
13 changes: 13 additions & 0 deletions examples/rust-examples/risc-v-esp32-c6/uart/.cargo/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[build]
rustflags = [
"-C", "link-arg=-Tlinkall.x",
"-C", "force-frame-pointers",
]

target = "riscv32imac-unknown-none-elf"

[unstable]
build-std = ["core", "alloc"]

[target.'cfg(any(target_arch = "riscv32", target_arch = "xtensa"))']
runner = "espflash flash --monitor"
17 changes: 17 additions & 0 deletions examples/rust-examples/risc-v-esp32-c6/uart/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[package]
name = "example_risc_v_esp32c6"
version = "0.4.0"
edition = "2021"

[profile.release]
debug = true

[dependencies]
# Specifying current Martos version path for ci
martos = { path = "../../../../", features = ["uart"] }
esp-hal = "0.21.1"
esp-backtrace = { version = "0.14.1", features = ["esp32c6", "panic-handler", "exception-handler", "println"] }
esp-println = { version = "0.11.0", features = ["esp32c6"] }

[features]
default = ["esp-hal/esp32c6", "esp-backtrace/esp32c6", "esp-println/esp32c6"]
73 changes: 73 additions & 0 deletions examples/rust-examples/risc-v-esp32-c6/uart/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# UART Echo Example for ESP32-C6

This example demonstrates UART communication on ESP32-C6 using the Martos RTOS framework.

## Features

- UART echo functionality
- Receives bytes via UART and echoes them back
- Uses GPIO16 (RX) and GPIO17 (TX) pins
- Baud rate: 19200
- Configuration: 8N1 (8 data bits, no parity, 1 stop bit)

## Hardware Setup

Connect your ESP32-C6 to a UART-to-USB converter:
- ESP32-C6 GPIO16 → UART-to-USB RX
- ESP32-C6 GPIO17 → UART-to-USB TX
- GND → GND

## Building and Flashing

Make sure you have the ESP toolchain installed:

```bash
# Install ESP toolchain
rustup toolchain install esp

# Set the toolchain for this project
rustup override set esp
```

Build the project:

```bash
cargo build --release
```

Flash to ESP32-C6:

```bash
cargo run --release
```

Or use espflash directly:

```bash
espflash flash target/riscv32imac-unknown-none-elf/release/example_risc_v_esp32c6
```

## Usage

1. Flash the firmware to your ESP32-C6
2. Connect a UART-to-USB converter to GPIO16/GPIO17
3. Open a serial terminal (e.g., minicom, screen, or Arduino IDE Serial Monitor)
4. Set the terminal to 19200 baud, 8N1
5. Type characters - they will be echoed back with additional information

## Expected Output

The example will print debug information via the ESP32-C6's built-in USB serial (if available) and echo received bytes via the external UART pins.

## Architecture Notes

This example is specifically configured for ESP32-C6 (RISC-V architecture):
- Uses UART0 peripheral (ESP32-C6 uses UART0 instead of UART2)
- Targets `riscv32imac-unknown-none-elf`
- Uses ESP32-C6 specific HAL features

## Troubleshooting

- Make sure your UART-to-USB converter is set to 19200 baud
- Check that GPIO16 and GPIO17 are not being used by other peripherals
- Verify that the ESP32-C6 is properly powered and grounded
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[toolchain]
channel = "esp"
99 changes: 99 additions & 0 deletions examples/rust-examples/risc-v-esp32-c6/uart/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
#![no_std]
#![no_main]

use core::sync::atomic::{AtomicU32, Ordering};
use esp_backtrace as _;
use esp_hal::uart::config::{Config, DataBits, StopBits};
use esp_hal::Blocking;
use esp_hal::{entry, uart::Uart};
use esp_println::println;
use martos::{
get_io, get_uart2, init_system,
task_manager::{TaskManager, TaskManagerTrait},
};

/// Counter to track processed bytes
static BYTE_COUNTER: AtomicU32 = AtomicU32::new(0);

/// UART instance (initialized in setup)
static mut UART_INSTANCE: Option<Uart<'static, esp_hal::peripherals::UART0, Blocking>> = None;

/// Setup function for task to execute.
fn setup_fn() {
println!("UART Echo Setup started");

unsafe {
// Get UART0 and IO from Martos (ESP32-C6 uses UART0)
let uart0 = get_uart2();
let io = get_io();

// UART configuration: 19200 baud, 8N1
let config = Config::default()
.baudrate(19200)
.data_bits(DataBits::DataBits8)
.parity_none()
.stop_bits(StopBits::STOP1);

// Initialize UART
let uart = Uart::new_with_config(
uart0,
config,
io.pins.gpio16, // RX pin
io.pins.gpio17, // TX pin
)
.expect("UART init failed");

UART_INSTANCE = Some(uart);

println!("UART Echo ready on GPIO16(RX)/GPIO17(TX) at 19200 baud");
}
}

/// Loop function for task to execute.
fn loop_fn() {
unsafe {
if let Some(ref mut uart) = UART_INSTANCE {
let mut buffer = [0u8; 1];

// Try to read a byte using read_bytes method
if uart.read_bytes(&mut buffer).is_ok() {
let byte = buffer[0];
let count = BYTE_COUNTER.fetch_add(1, Ordering::Relaxed) + 1;

println!(
"Received byte #{}: 0x{:02X} ('{}') - echoing back",
count,
byte,
if byte.is_ascii_graphic() || byte == b' ' {
byte as char
} else {
'.'
}
);

// Echo the byte back using write_bytes method
if uart.write_bytes(&buffer).is_err() {
println!("Failed to echo byte!");
}
}
}
}
}

/// Stop condition function for task to execute.
fn stop_condition_fn() -> bool {
// Never stop - run forever
false
}

#[entry]
fn main() -> ! {
// Initialize Martos (including UART)
init_system();

// Add task to execute
TaskManager::add_task(setup_fn, loop_fn, stop_condition_fn);

// Start task manager
TaskManager::start_task_manager();
}
14 changes: 14 additions & 0 deletions examples/rust-examples/xtensa-esp32/uart/.cargo/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[build]
rustflags = [
"-C", "link-arg=-Tlinkall.x",

"-C", "link-arg=-nostartfiles",
]

target = "xtensa-esp32-none-elf"

[unstable]
build-std = ["core", "alloc"]

[target.'cfg(any(target_arch = "riscv32", target_arch = "xtensa"))']
runner = "espflash flash --monitor"
17 changes: 17 additions & 0 deletions examples/rust-examples/xtensa-esp32/uart/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[package]
name = "example_xtensa_esp32"
version = "0.4.0"
edition = "2021"

[profile.release]
debug = true

[dependencies]
# Specifying current Martos version path for ci
martos = { path = "../../../../", features = ["uart"] }
esp-hal = "0.21.1"
esp-backtrace = { version = "0.14.1", features = ["esp32", "panic-handler", "exception-handler", "println"] }
esp-println = { version = "0.11.0", features = ["esp32"] }

[features]
default = ["esp-hal/esp32", "esp-backtrace/esp32", "esp-println/esp32"]
37 changes: 37 additions & 0 deletions examples/rust-examples/xtensa-esp32/uart/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Rust example for xtensa esp32 architecture

Presented here is a straightforward UART echo Rust example utilizing Martos with UART functionality.

Within the setup function, the UART interface is initialized once on GPIO pins 16 (RX) and 17 (TX) with 19200 baud rate, 8 data bits, no parity, and 1 stop bit.
Additionally, within the loop function, incoming UART data is continuously read byte-by-byte and immediately echoed back to the sender, with each processed byte being logged along with a running counter for debugging purposes.

## How to install dependencies

For comprehensive guidance on installing the necessary dependencies for developing applications targeting the Xtensa ESP32 architecture,
please refer to [the official website](https://docs.esp-rs.org/book/installation/riscv-and-xtensa.html).
Below is an illustrative example demonstrating the installation of building toolchains on a Linux (Ubuntu/Debian):
```
apt-get -qq update
apt-get install -y -q build-essential curl
curl https://sh.rustup.rs -sSf | sh -s -- -y
cargo install espup
espup install
```

## How to build the example

For a thorough guide on developing projects for the Xtensa ESP32 architecture across various operating systems,
we recommend consulting [the official website](https://docs.esp-rs.org/book/installation/riscv-and-xtensa.html#3-set-up-the-environment-variables).
Below, you will find an illustrative example showcasing the building process on a Linux system (Ubuntu/Debian):
```
. $HOME/export-esp.sh
cargo build
```

## How to run the example
For detailed instructions on running projects for the Xtensa ESP32 architecture across various operating systems,
we recommend consulting [the official website](https://docs.esp-rs.org/book/tooling/espflash.html).
Below, you will find an illustrative example showcasing the running on a Linux system (Ubuntu/Debian):
```
cargo run
```
2 changes: 2 additions & 0 deletions examples/rust-examples/xtensa-esp32/uart/rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[toolchain]
channel = "esp"
Loading
Loading