Skip to content

Commit 5ea9fe1

Browse files
authored
Merge pull request #88 from Neotron-Compute/add-graphics
Add graphics
2 parents 293f2b1 + 5621412 commit 5ea9fe1

8 files changed

Lines changed: 416 additions & 96 deletions

Cargo.lock

Lines changed: 4 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,18 @@ version = "0.6.0"
1010
[dependencies]
1111
# Useful Cortex-M specific functions (e.g. SysTick)
1212
cortex-m = "0.7"
13-
# The Raspberry Pi Pico HAL
13+
# The Raspberry Pi Pico BSP
1414
rp-pico = { version = "0.7", default-features = false, features = [
1515
"rt",
1616
"critical-section-impl",
1717
"rom-func-cache"
1818
] }
19+
# The Raspberry Pi RP2040 HAL
20+
rp2040-hal = { version = "0.8", features = [ "defmt" ] }
1921
# Cortex-M run-time (or start-up) code
2022
cortex-m-rt = "0.7"
2123
# The BIOS to OS API
22-
neotron-common-bios = "0.11.0"
24+
neotron-common-bios = "0.11.1"
2325
# For the RP2040 bootloader
2426
rp2040-boot2 = "0.3.0"
2527
# For hardware abstraction traits
@@ -62,7 +64,7 @@ embedded-sdmmc = { version = "0.5", default-features = false, features = [
6264
tlv320aic23 = "0.1.0"
6365

6466
[build-dependencies]
65-
neotron-common-bios = "0.11.0"
67+
neotron-common-bios = "0.11.1"
6668
vte = "0.11"
6769

6870
[[bin]]

memory.x

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,18 @@ MEMORY {
2525
/*
2626
* This is the bottom of the four striped banks of SRAM in the RP2040.
2727
*/
28-
RAM_OS : ORIGIN = 0x20000000, LENGTH = 0x38FE0
28+
RAM_OS : ORIGIN = 0x20000000, LENGTH = 0x42000 - 0x9080
2929
/*
3030
* This is the top of the four striped banks of SRAM in the RP2040, plus
3131
* SRAM_BANK4 and SRAM_BANK5.
3232
*
3333
* This is carefully calculated to give us 8 KiB of stack space and ensure
3434
* the defmt buffer doesn't span across SRAM_BANK3 and SRAM_BANK4.
35+
*
36+
* 0x9080 should be the (size of .data + size of .bss + size of .uninit +
37+
* 0x2000 for the stack).
3538
*/
36-
RAM : ORIGIN = 0x20038FE0, LENGTH = 0x9020
39+
RAM : ORIGIN = 0x20042000 - 0x9080, LENGTH = 0x9080
3740
}
3841

3942
/*

src/main.rs

Lines changed: 59 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1734,15 +1734,57 @@ pub extern "C" fn time_clock_set(time: common::Time) {
17341734
/// Configuration data is, to the BIOS, just a block of bytes of a given
17351735
/// length. How it stores them is up to the BIOS - it could be EEPROM, or
17361736
/// battery-backed SRAM.
1737-
pub extern "C" fn configuration_get(_buffer: FfiBuffer) -> ApiResult<usize> {
1738-
ApiResult::Err(CError::Unimplemented)
1737+
pub extern "C" fn configuration_get(mut buffer: FfiBuffer) -> ApiResult<usize> {
1738+
let mut lock = HARDWARE.lock();
1739+
let hw = lock.as_mut().unwrap();
1740+
let Some(slice) = buffer.as_mut_slice() else {
1741+
return ApiResult::Err(CError::Unimplemented);
1742+
};
1743+
match hw.rtc.configuration_get(hw.i2c.acquire_i2c(), slice) {
1744+
Ok(n) => {
1745+
defmt::info!("Config Read {:x}", &slice[0..usize::from(n)]);
1746+
ApiResult::Ok(usize::from(n))
1747+
}
1748+
Err(rtc::Error::NoRtcFound) => {
1749+
defmt::info!("Can't get config - no RTC present");
1750+
ApiResult::Err(CError::InvalidDevice)
1751+
}
1752+
Err(rtc::Error::DriverBug) => {
1753+
defmt::warn!("Can't get config - Driver Bug");
1754+
ApiResult::Err(CError::DeviceError(0))
1755+
}
1756+
Err(rtc::Error::Bus(e)) => {
1757+
defmt::warn!("Can't get config - bus error {:?}", e);
1758+
ApiResult::Err(CError::DeviceError(1))
1759+
}
1760+
}
17391761
}
17401762

17411763
/// Set the configuration data block.
17421764
///
17431765
/// See `configuration_get`.
1744-
pub extern "C" fn configuration_set(_buffer: FfiByteSlice) -> ApiResult<()> {
1745-
ApiResult::Err(CError::Unimplemented)
1766+
pub extern "C" fn configuration_set(buffer: FfiByteSlice) -> ApiResult<()> {
1767+
defmt::info!("Config save {:x}", buffer.as_slice());
1768+
let mut lock = HARDWARE.lock();
1769+
let hw = lock.as_mut().unwrap();
1770+
match hw
1771+
.rtc
1772+
.configuration_set(hw.i2c.acquire_i2c(), buffer.as_slice())
1773+
{
1774+
Ok(()) => ApiResult::Ok(()),
1775+
Err(rtc::Error::NoRtcFound) => {
1776+
defmt::info!("Can't save config - no RTC present");
1777+
ApiResult::Err(CError::InvalidDevice)
1778+
}
1779+
Err(rtc::Error::DriverBug) => {
1780+
defmt::warn!("Can't save config - Driver Bug");
1781+
ApiResult::Err(CError::DeviceError(0))
1782+
}
1783+
Err(rtc::Error::Bus(e)) => {
1784+
defmt::warn!("Can't save config - bus error {:?}", e);
1785+
ApiResult::Err(CError::DeviceError(0))
1786+
}
1787+
}
17461788
}
17471789

17481790
/// Does this Neotron BIOS support this video mode?
@@ -1760,6 +1802,7 @@ pub extern "C" fn video_is_valid_mode(mode: common::video::Mode) -> bool {
17601802
/// pointer to a block of size `Mode::frame_size_bytes()` to
17611803
/// `video_set_framebuffer` before any video will appear.
17621804
pub extern "C" fn video_set_mode(mode: common::video::Mode) -> ApiResult<()> {
1805+
defmt::info!("Changing to mode {}", mode.as_u8());
17631806
if vga::set_video_mode(mode) {
17641807
ApiResult::Ok(())
17651808
} else {
@@ -1790,7 +1833,12 @@ pub extern "C" fn video_get_mode() -> common::video::Mode {
17901833
/// to provide the 'basic' text buffer experience from reserves, so this
17911834
/// function will never return `null` on start-up.
17921835
pub extern "C" fn video_get_framebuffer() -> *mut u8 {
1793-
unsafe { vga::GLYPH_ATTR_ARRAY.as_mut_ptr() as *mut u8 }
1836+
let ptr = vga::CUSTOM_FB.load(Ordering::Relaxed);
1837+
if ptr.is_null() {
1838+
unsafe { vga::GLYPH_ATTR_ARRAY.as_mut_ptr() as *mut u8 }
1839+
} else {
1840+
ptr
1841+
}
17941842
}
17951843

17961844
/// Set the framebuffer address.
@@ -1804,8 +1852,9 @@ pub extern "C" fn video_get_framebuffer() -> *mut u8 {
18041852
///
18051853
/// The pointer must point to enough video memory to handle the current video
18061854
/// mode, and any future video mode you set.
1807-
pub unsafe extern "C" fn video_set_framebuffer(_buffer: *const u8) -> ApiResult<()> {
1808-
ApiResult::Err(CError::Unimplemented)
1855+
pub unsafe extern "C" fn video_set_framebuffer(buffer: *const u8) -> ApiResult<()> {
1856+
vga::CUSTOM_FB.store(buffer as *mut u8, Ordering::Relaxed);
1857+
ApiResult::Ok(())
18091858
}
18101859

18111860
/// Find out whether the given video mode needs more VRAM than we currently have.
@@ -2398,7 +2447,9 @@ extern "C" fn block_dev_eject(_dev_id: u8) -> ApiResult<()> {
23982447
/// Sleep the CPU until the next interrupt.
23992448
extern "C" fn power_idle() {
24002449
if !INTERRUPT_PENDING.load(Ordering::Relaxed) {
2401-
cortex_m::asm::wfe();
2450+
unsafe {
2451+
core::arch::asm!("wfe");
2452+
}
24022453
}
24032454
}
24042455

src/rtc.rs

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,95 @@ impl Rtc {
151151
Self::None => Err(Error::NoRtcFound),
152152
}
153153
}
154+
155+
/// Store configuration in the RTC's RAM
156+
pub fn configuration_set<T, E>(&mut self, bus: T, data: &[u8]) -> Result<(), Error<E>>
157+
where
158+
T: embedded_hal::blocking::i2c::WriteRead<Error = E>
159+
+ embedded_hal::blocking::i2c::Write<Error = E>,
160+
{
161+
match self {
162+
Self::Ds1307 => {
163+
let mut driver = ds1307::Ds1307::new(bus);
164+
driver.write_ram(1, data).map_err(|e| match e {
165+
ds1307::Error::I2C(bus_error) => Error::Bus(bus_error),
166+
ds1307::Error::InvalidInputData => Error::DriverBug,
167+
})?;
168+
driver
169+
.write_ram(0, &[data.len() as u8])
170+
.map_err(|e| match e {
171+
ds1307::Error::I2C(bus_error) => Error::Bus(bus_error),
172+
ds1307::Error::InvalidInputData => Error::DriverBug,
173+
})
174+
}
175+
Self::Mcp7940n => {
176+
let mut driver = mcp794xx::Mcp794xx::new_mcp7940n(bus);
177+
driver.write_sram_data(1, data).map_err(|e| match e {
178+
mcp794xx::Error::Comm(bus_error) => Error::Bus(bus_error),
179+
mcp794xx::Error::InvalidInputData => Error::DriverBug,
180+
})?;
181+
driver
182+
.write_sram_byte(0, data.len() as u8)
183+
.map_err(|e| match e {
184+
mcp794xx::Error::Comm(bus_error) => Error::Bus(bus_error),
185+
mcp794xx::Error::InvalidInputData => Error::DriverBug,
186+
})
187+
}
188+
Self::None => Err(Error::NoRtcFound),
189+
}
190+
}
191+
192+
/// Get configuration from the RTC's RAM
193+
pub fn configuration_get<T, E>(&mut self, bus: T, mut data: &mut [u8]) -> Result<u8, Error<E>>
194+
where
195+
T: embedded_hal::blocking::i2c::WriteRead<Error = E>
196+
+ embedded_hal::blocking::i2c::Write<Error = E>,
197+
{
198+
match self {
199+
Self::Ds1307 => {
200+
let mut driver = ds1307::Ds1307::new(bus);
201+
if data.len() > 55 {
202+
// This chip can only read 56 bytes (inc our count byte)
203+
data = &mut data[0..55];
204+
}
205+
let mut count = [0u8; 1];
206+
driver.read_ram(0, &mut count).map_err(|e| match e {
207+
ds1307::Error::I2C(bus_error) => Error::Bus(bus_error),
208+
ds1307::Error::InvalidInputData => Error::DriverBug,
209+
})?;
210+
driver.read_ram(1, data).map_err(|e| match e {
211+
ds1307::Error::I2C(bus_error) => Error::Bus(bus_error),
212+
ds1307::Error::InvalidInputData => Error::DriverBug,
213+
})?;
214+
if usize::from(count[0]) <= data.len() {
215+
Ok(count[0])
216+
} else {
217+
Ok(0)
218+
}
219+
}
220+
Self::Mcp7940n => {
221+
if data.len() > 63 {
222+
// This chip can only read 64 bytes (inc our count byte)
223+
data = &mut data[0..63];
224+
}
225+
let mut driver = mcp794xx::Mcp794xx::new_mcp7940n(bus);
226+
let count = driver.read_sram_byte(0).map_err(|e| match e {
227+
mcp794xx::Error::Comm(bus_error) => Error::Bus(bus_error),
228+
mcp794xx::Error::InvalidInputData => Error::DriverBug,
229+
})?;
230+
driver.read_sram_data(1, data).map_err(|e| match e {
231+
mcp794xx::Error::Comm(bus_error) => Error::Bus(bus_error),
232+
mcp794xx::Error::InvalidInputData => Error::DriverBug,
233+
})?;
234+
if usize::from(count) <= data.len() {
235+
Ok(count)
236+
} else {
237+
Ok(0)
238+
}
239+
}
240+
Self::None => Err(Error::NoRtcFound),
241+
}
242+
}
154243
}
155244

156245
// -----------------------------------------------------------------------------
-30 KB
Binary file not shown.

src/thumbv6m-none-eabi-flash1002-libneotron_os.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
This is Neotron OS version v0.5.0
1+
This is Neotron OS version v0.6.0
22

3-
Taken from https://github.com/Neotron-Compute/Neotron-OS/releases/tag/v0.5.0
3+
Taken from https://github.com/Neotron-Compute/Neotron-OS/releases/tag/v0.6.0
44

55
This program is free software: you can redistribute it and/or modify
66
it under the terms of the GNU General Public License as published by

0 commit comments

Comments
 (0)