Skip to content
Open
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
10 changes: 6 additions & 4 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,13 @@ jobs:
runs-on: ubuntu-latest

steps:
- name: Set up Rust toolchain
run: rustup target add armv7a-none-eabi
- uses: actions/checkout@v3
- name: Set up Rust toolchain
run: rustup target add armv7a-none-eabi
-name: Check
run: cargo clippy -- -D clippy::pedantic
- name: Build
run: cargo build --verbose
run: cargo build --verbose
- name: Run tests
run: cargo test --verbose
run: cargo test --verbose

1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
/target
/kernel7.img
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "rustberrypie"
version = "0.1.0"
version = "0.2.0"
license = "MIT OR Apache-2.0"
edition = "2021"

Expand Down
18 changes: 18 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,8 +1,26 @@

RUSTFLAGS_PEDANTIC = -D warnings

all: kernel7.img
kernel7.img: target/armv7a-none-eabi/release/kernel
<<<<<<< Updated upstream
arm-none-eabi-objcopy -O binary target/armv7a-none-eabi/release/kernel ./kernel7.img
target/armv7a-none-eabi/release/kernel:
=======
rust-objcopy -O binary target/armv7a-none-eabi/release/kernel ./kernel7.img
target/armv7a-none-eabi/release/kernel: clippy
>>>>>>> Stashed changes
cargo build --release
clean:
cargo clean
rm -f kernel7.img
<<<<<<< Updated upstream
=======
objdump: target/armv7a-none-eabi/release/kernel
cargo objdump --bin kernel --release -- --disassemble --no-show-raw-insn --print-imm-hex

clippy:
cargo clippy -- -D clippy::pedantic
doc:
cargo doc --open
>>>>>>> Stashed changes
Binary file modified kernel7.img
Binary file not shown.
4 changes: 4 additions & 0 deletions rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[toolchain]
# channel = "nightly-2022-10-13"
components = ["rust-src", "llvm-tools-preview", "rustfmt", "rust-analyzer"]
targets = ["armv7a-none-eabi"]
22 changes: 22 additions & 0 deletions src/cpu.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
use core::{arch::asm, panic::PanicInfo};

pub fn wait_forever() -> ! {
loop {
unsafe {
asm!("wfe", options(nomem, nostack));
}
}
}

pub fn spin_for_cycles(n: usize) {
for _ in 0..n {
unsafe {
asm!("nop", options(nomem, nostack));
}
}
}

#[panic_handler]
fn panic(_info: &PanicInfo) -> ! {
wait_forever()
}
64 changes: 64 additions & 0 deletions src/gpio_pins.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
use core::ptr::read_volatile as read32;
use core::ptr::write_volatile as write32;
// 0x3F20 0008 fsel2 1<<3 turn pin into an output.
// 0x3F20 001C gpio1_set 1<<21 turn pin 21 on.
// 0x3F20 0028 gpio1_clear 1<<21 turn 21 off.
// Constants

/// This GPIO struct is use to interface with the gpio pin in
/// the Broadcom BCM2835 cpu in the raspberrypi w
#[allow(clippy::upper_case_acronyms)]
pub struct GPIO;

use crate::memory::mmio::{GPIO_CLEAR0, GPIO_FSEL0, GPIO_FSEL1, GPIO_FSEL2, GPIO_SET0};
impl GPIO {
pub fn set_output(pin: u32) {
let reg = pin / 10;
let register = match reg {
0 => GPIO_FSEL0,
1 => GPIO_FSEL1,
2 => GPIO_FSEL2,
_ => panic!("Something went wrong."),
};
let mut val: u32;
unsafe {
val = read32(register as *mut u32);
}
// Create a mask.
let mut mask: u32 = 0b111;
// Shift the mask to the right loocation.
let pinnum = pin % 10;
mask <<= pinnum * 3;
// and in the not of the mask.
val &= !(mask);
// Set OUR value.
val |= 1 << (pinnum * 3);

unsafe {
write32(register as *mut u32, val);
}
}
pub fn set_high(pin: u32) {
let bitpos = pin;
let mut val: u32;
unsafe {
val = read32(GPIO_SET0 as *mut u32);
}
val |= 1 << bitpos;
unsafe {
write32(GPIO_SET0 as *mut u32, val);
}
}

pub fn clear(pin: u32) {
let bitpos = pin;
let mut val: u32;
unsafe {
val = read32(GPIO_CLEAR0 as *mut u32);
}
val |= 1 << bitpos;
unsafe {
write32(GPIO_CLEAR0 as *mut u32, val);
}
}
}
99 changes: 12 additions & 87 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,105 +1,30 @@
//! This is a flat binary that blinks an led light
//! in the specified port.

#![no_std]
#![no_main]
use core::arch::asm;
use core::panic::PanicInfo;
use core::ptr::read_volatile as read32;
use core::ptr::write_volatile as write32;
// 0x3F20 0008 fsel2 1<<3 turn pin into an output.
// 0x3F20 001C gpio1_set 1<<21 turn pin 21 on.
// 0x3F20 0028 gpio1_clear 1<<21 turn 21 off.
// Constants
const GPIO_FSEL0: u32 = 0x3F20_0000;
const GPIO_FSEL1: u32 = 0x3F20_0004;
const GPIO_FSEL2: u32 = 0x3F20_0008;

const GPIO_SET0: u32 = 0x3F20_001C;
const GPIO_CLEAR0: u32 = 0x3F20_0028;

/// This GPIO struct is use to interface with the gpio pin in
/// the Broadcom BCM2835 cpu in the raspberrypi w
#[allow(clippy::upper_case_acronyms)]
struct GPIO;
//! This is a flat binary that blinks an led light
//! in the specified port.

impl GPIO {
pub fn set_output(pin: u32) {
let reg = pin / 10;
let register = match reg {
0 => GPIO_FSEL0,
1 => GPIO_FSEL1,
2 => GPIO_FSEL2,
_ => panic!("Something went wrong."),
};
let mut val: u32;
unsafe {
val = read32(register as *mut u32);
}
// Create a mask.
let mut mask: u32 = 0b111;
// Shift the mask to the right loocation.
let pinnum = pin % 10;
mask <<= pinnum * 3;
// and in the not of the mask.
val &= !(mask);
// Set OUR value.
val |= 1 << (pinnum * 3);
mod cpu;
mod gpio_pins;
mod memory;

unsafe {
write32(register as *mut u32, val);
}
}
pub fn set_high(pin: u32) {
let bitpos = pin;
let mut val: u32;
unsafe {
val = read32(GPIO_SET0 as *mut u32);
}
val |= 1 << bitpos;
unsafe {
write32(GPIO_SET0 as *mut u32, val);
}
}
use gpio_pins::GPIO;

pub fn clear(pin: u32) {
let bitpos = pin;
let mut val: u32;
unsafe {
val = read32(GPIO_CLEAR0 as *mut u32);
}
val |= 1 << bitpos;
unsafe {
write32(GPIO_CLEAR0 as *mut u32, val);
}
}
}
#[no_mangle]
#[link_section = ".text._start"]
pub extern "C" fn _start() -> ! {
const TIME: u32 = 0xC350; // about 1 second
const TIME: usize = 0xC350; // about 1 second
const PIN: u32 = 0x15; // pin 21
// Set pin into output.
GPIO::set_output(PIN);
loop {
// turn pin 21 on
GPIO::set_high(PIN);
unsafe {
for _ in 1..TIME {
asm!("nop");
}
}

cpu::spin_for_cycles(TIME);

// turn pin 21 off
GPIO::clear(PIN);
unsafe {
for _ in 1..TIME {
asm!("nop");
}
}
}
}

#[panic_handler]
fn panic(_info: &PanicInfo) -> ! {
loop {}
cpu::spin_for_cycles(TIME);
}
}
9 changes: 9 additions & 0 deletions src/memory.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
pub mod mmio {

pub const GPIO_FSEL0: u32 = 0x3F20_0000;
pub const GPIO_FSEL1: u32 = 0x3F20_0004;
pub const GPIO_FSEL2: u32 = 0x3F20_0008;

pub const GPIO_SET0: u32 = 0x3F20_001C;
pub const GPIO_CLEAR0: u32 = 0x3F20_0028;
}