-
Notifications
You must be signed in to change notification settings - Fork 26
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #153 from ferrous-systems/fixup-arm-demos
Fixup arm demos
- Loading branch information
Showing
10 changed files
with
193 additions
and
107 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
manifest-version = 1 | ||
|
||
[products.ferrocene] | ||
release = "nightly-2024-04-24" | ||
packages = ["rustc-${rustc-host}", "rust-std-${rustc-host}", "cargo-${rustc-host}", "rustfmt-${rustc-host}", "rust-src", "rust-std-aarch64-unknown-none",] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
//! A driver the Arm PL011 Uart | ||
//! | ||
//! Written by Jonathan Pallant at Ferrous Systems | ||
//! | ||
//! Copyright (c) Ferrous Systems, 2024 | ||
/// A driver for a virtual PL011 Uart | ||
/// | ||
/// It skips almost all the important initialisation, but it works on QEMU. | ||
pub struct Uart<const ADDR: usize>(); | ||
|
||
impl Uart<0x0900_0000> { | ||
/// Create a new UART object for UART0 | ||
/// | ||
/// # Safety | ||
/// | ||
/// Only construct one object per UART at any given time. | ||
pub unsafe fn new_uart0() -> Self { | ||
let mut u = Uart(); | ||
u.set_control(Self::CONTROL_UARTEN | Self::CONTROL_TXE); | ||
u | ||
} | ||
} | ||
|
||
impl<const ADDR: usize> Uart<ADDR> { | ||
const FLAG_TXFF: u32 = 1 << 5; | ||
const CONTROL_UARTEN: u32 = 1 << 0; | ||
const CONTROL_TXE: u32 = 1 << 8; | ||
|
||
const DATA_OFFSET: usize = 0x000 >> 2; | ||
const FLAG_OFFSET: usize = 0x018 >> 2; | ||
const CONTROL_OFFSET: usize = 0x030 >> 2; | ||
|
||
/// Write a byte (blocking if there's no space) | ||
pub fn write(&mut self, byte: u8) { | ||
// Check the TX FIFO Full bit | ||
while (self.get_flags() & Self::FLAG_TXFF) != 0 {} | ||
self.write_data(byte); | ||
} | ||
|
||
/// Write to the data register | ||
fn write_data(&mut self, value: u8) { | ||
unsafe { | ||
let ptr = (ADDR as *mut u32).add(Self::DATA_OFFSET); | ||
ptr.write_volatile(value as u32); | ||
} | ||
} | ||
|
||
/// Read from the Flag Register | ||
fn get_flags(&mut self) -> u32 { | ||
unsafe { | ||
let ptr = (ADDR as *const u32).add(Self::FLAG_OFFSET); | ||
ptr.read_volatile() | ||
} | ||
} | ||
|
||
/// Write to the control register | ||
fn set_control(&mut self, value: u32) { | ||
unsafe { | ||
let ptr = (ADDR as *mut u32).add(Self::CONTROL_OFFSET); | ||
ptr.write_volatile(value); | ||
} | ||
} | ||
} | ||
|
||
impl<const N: usize> core::fmt::Write for Uart<N> { | ||
fn write_str(&mut self, s: &str) -> core::fmt::Result { | ||
for b in s.bytes() { | ||
self.write(b); | ||
} | ||
Ok(()) | ||
} | ||
} | ||
|
||
// End of file |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
manifest-version = 1 | ||
|
||
[products.ferrocene] | ||
release = "nightly-2024-04-24" | ||
packages = ["rustc-${rustc-host}", "rust-std-${rustc-host}", "cargo-${rustc-host}", "rustfmt-${rustc-host}", "rust-src", "rust-std-armv8r-none-eabihf",] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
//! A driver the Arm CMSDK Uart | ||
//! | ||
//! Written by Jonathan Pallant at Ferrous Systems | ||
//! | ||
//! Copyright (c) Ferrous Systems, 2024 | ||
/// A driver for CMSDK Uart | ||
pub struct Uart<const ADDR: usize>(); | ||
|
||
impl Uart<0xe7c0_0000> { | ||
/// Create a new UART object for UART0 | ||
/// | ||
/// # Safety | ||
/// | ||
/// Only construct one object per UART at any given time. | ||
pub unsafe fn new_uart0() -> Self { | ||
Uart() | ||
} | ||
} | ||
|
||
impl<const ADDR: usize> Uart<ADDR> { | ||
const STATUS_TX_FULL: u32 = 1 << 0; | ||
const CONTROL_TX_EN: u32 = 1 << 0; | ||
|
||
const DATA_OFFSET: usize = 0x000 >> 2; | ||
const STATUS_OFFSET: usize = 0x004 >> 2; | ||
const CONTROL_OFFSET: usize = 0x008 >> 2; | ||
const BAUD_OFFSET: usize = 0x010 >> 2; | ||
|
||
/// Turn on TX and RX | ||
pub fn enable(&mut self, baudrate: u32, system_clock: u32) { | ||
let divider = system_clock / baudrate; | ||
self.set_bauddiv(divider); | ||
self.set_control(Self::CONTROL_TX_EN); | ||
} | ||
|
||
/// Write a byte (blocking if there's no space) | ||
pub fn write(&mut self, byte: u8) { | ||
// Check the Buffer Full bit | ||
while (self.get_status() & Self::STATUS_TX_FULL) != 0 {} | ||
self.set_data(byte as u32); | ||
} | ||
|
||
/// Write the data register | ||
fn set_data(&mut self, data: u32) { | ||
unsafe { | ||
let ptr = (ADDR as *mut u32).add(Self::DATA_OFFSET); | ||
ptr.write_volatile(data) | ||
} | ||
} | ||
|
||
/// Read the status register | ||
fn get_status(&self) -> u32 { | ||
unsafe { | ||
let ptr = (ADDR as *mut u32).add(Self::STATUS_OFFSET); | ||
ptr.read_volatile() | ||
} | ||
} | ||
|
||
/// Set the control register | ||
fn set_control(&mut self, data: u32) { | ||
unsafe { | ||
let ptr = (ADDR as *mut u32).add(Self::CONTROL_OFFSET); | ||
ptr.write_volatile(data) | ||
} | ||
} | ||
|
||
/// Set the baud rate divider register | ||
fn set_bauddiv(&mut self, data: u32) { | ||
unsafe { | ||
let ptr = (ADDR as *mut u32).add(Self::BAUD_OFFSET); | ||
ptr.write_volatile(data) | ||
} | ||
} | ||
} | ||
|
||
impl<const N: usize> core::fmt::Write for Uart<N> { | ||
fn write_str(&mut self, s: &str) -> core::fmt::Result { | ||
for b in s.bytes() { | ||
self.write(b); | ||
} | ||
Ok(()) | ||
} | ||
} | ||
|
||
// End of file |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters