diff --git a/Cargo.lock b/Cargo.lock index 63e4f01aa..8230ae93a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -336,8 +336,10 @@ version = "0.1.0" dependencies = [ "cram-hal-service", "cramium-api", + "cramium-emu", "cramium-hal", "log", + "modals", "num-derive 0.4.2", "num-traits", "usb-cramium", @@ -953,7 +955,6 @@ version = "0.1.0" dependencies = [ "cram-hal-service", "cramium-hal", - "gam", "ime-plugin-shell", "locales", "log", @@ -968,7 +969,6 @@ dependencies = [ "xous-api-names", "xous-api-ticktimer", "xous-ipc 0.10.4 (registry+https://github.com/rust-lang/crates.io-index)", - "xous-pl230", "xous-swapper", ] @@ -982,8 +982,6 @@ dependencies = [ "log", "num-derive 0.4.2", "num-traits", - "pio", - "pio-proc", "rand_chacha 0.3.1", "rand_core 0.6.4", "rkyv 0.8.8", @@ -993,7 +991,6 @@ dependencies = [ "xous-api-names", "xous-api-ticktimer", "xous-ipc 0.10.4 (registry+https://github.com/rust-lang/crates.io-index)", - "xous-pl230", ] [[package]] @@ -3241,6 +3238,7 @@ dependencies = [ "bit_field", "blitstr2", "cram-hal-service", + "cramium-api", "cramium-emu", "cramium-hal", "gam", @@ -5866,6 +5864,7 @@ name = "usb-cramium" version = "0.1.0" dependencies = [ "cram-hal-service", + "cramium-emu", "cramium-hal", "frunk_core", "locales", diff --git a/libs/cramium-hal/src/axp2101.rs b/libs/cramium-hal/src/axp2101.rs index fd041bde8..06ac8cb2f 100644 --- a/libs/cramium-hal/src/axp2101.rs +++ b/libs/cramium-hal/src/axp2101.rs @@ -3,6 +3,7 @@ use cramium_api::*; pub const AXP2101_DEV: u8 = 0x34; const REG_DCDC_ENA: usize = 0x80; +const REG_DCDC_PWM: usize = 0x81; const REG_DCDC1_V: usize = 0x82; const REG_DCDC2_V: usize = 0x83; const REG_DCDC3_V: usize = 0x84; @@ -281,6 +282,39 @@ impl Axp2101 { let data = VBUS_INSERT_MASK | VBUS_REMOVE_MASK; i2c.i2c_write(AXP2101_DEV, REG_IRQ_STATUS1, &[data]).map(|_| ()) } + + pub fn set_pwm_mode( + &mut self, + i2c: &mut dyn I2cApi, + which: WhichDcDc, + always: bool, + ) -> Result<(), xous::Error> { + match which { + WhichDcDc::Dcdc5 => Err(xous::Error::BadAddress), + _ => { + let mut buf = [0u8]; + i2c.i2c_read(AXP2101_DEV, REG_DCDC_PWM as u8, &mut buf, false).map(|_| ())?; + if always { + buf[0] |= 4u8 << (which as usize as u8); + } else { + buf[0] &= !(4u8 << (which as usize as u8)); + } + i2c.i2c_write(AXP2101_DEV, REG_DCDC_PWM as u8, &buf).map(|_| ()) + } + } + } + + pub fn debug(&mut self, i2c: &mut dyn I2cApi) { + let mut buf = [0u8, 0u8]; + i2c.i2c_read(AXP2101_DEV, REG_DCDC_ENA as u8, &mut buf, false).unwrap(); + crate::println!("ena|pwm bef: {:x?}", buf); + // force CCM mode + i2c.i2c_write(AXP2101_DEV, REG_DCDC_ENA as u8, &[buf[0] | 0b0100_0000]).unwrap(); + // disable spreading, force PWM on DCDC2 + i2c.i2c_write(AXP2101_DEV, REG_DCDC_PWM as u8, &[(buf[1] & 0b0011_1111) | 0b0000_1000]).unwrap(); + i2c.i2c_read(AXP2101_DEV, REG_DCDC_ENA as u8, &mut buf, false).unwrap(); + crate::println!("ena|pwm aft: {:x?}", buf); + } } pub fn parse_dcdc_ena(d: u8) -> ([bool; 4], bool, bool) { diff --git a/libs/ux-api/src/lib.rs b/libs/ux-api/src/lib.rs index d8195e65f..30a2c7aee 100644 --- a/libs/ux-api/src/lib.rs +++ b/libs/ux-api/src/lib.rs @@ -5,7 +5,7 @@ pub mod cursor; mod fontmap; pub mod minigfx; pub mod platform; -#[cfg(all(feature = "std", any(feature = "cramium-soc", feature = "hosted-baosec")))] +#[cfg(all(feature = "std", any(feature = "board-baosec", feature = "hosted-baosec")))] pub mod widgets; #[cfg(feature = "std")] pub mod wordwrap; diff --git a/libs/ux-api/src/minigfx/clip.rs b/libs/ux-api/src/minigfx/clip.rs index aab79a69c..8a57cb714 100644 --- a/libs/ux-api/src/minigfx/clip.rs +++ b/libs/ux-api/src/minigfx/clip.rs @@ -41,3 +41,35 @@ impl ClipObjectList { } } } + +#[cfg_attr(feature = "derive-rkyv", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[derive(Debug, Clone)] +/// This API relies on an upgraded version of rkyv that was not available when the ClipObjectList +/// API was defined: we can now just use a `Vec` to do the trick. +#[cfg(feature = "std")] +pub struct ObjectList { + pub list: Vec, +} +#[cfg(feature = "std")] +impl ObjectList { + pub fn new() -> Self { Self { list: Vec::new() } } + + /// The intent was for the push() to be infalliable, but in practice, draw lists could get + /// arbitrarily large and some back-pressure is needed to keep the memory allocation within + /// bounds that the system can handle. Thus, this method can fail returning the pushed object, + /// at which point one should send the draw list to the graphics engine, and retry the push. + pub fn push(&mut self, item: ClipObjectType) -> Result<(), ClipObjectType> { + // TODO: export the capacity limit of a buffer. The origin of the capacity limit is equal to + // the size of a page of memory, plus 256 bytes for "scratch" area for rkyv to work in. I did + // try to use the .replace() method with an allocation of a large enough buffer to hold the whole + // Vec, but it seems to fail. I think it could be that the scratch space hard-coded into the IPC + // library is not big enough... + if self.list.capacity() * size_of::() + size_of::>() < 4096 - 256 + { + self.list.push(item); + Ok(()) + } else { + Err(item) + } + } +} diff --git a/libs/ux-api/src/minigfx/handlers.rs b/libs/ux-api/src/minigfx/handlers.rs index e73a39293..8ee397ddf 100644 --- a/libs/ux-api/src/minigfx/handlers.rs +++ b/libs/ux-api/src/minigfx/handlers.rs @@ -70,6 +70,34 @@ pub fn draw_clip_object_list(display: &mut T, msg: &mut xous::en } } +pub fn draw_object_list(display: &mut T, msg: &mut xous::envelope::Envelope) { + let buffer = unsafe { Buffer::from_memory_message(msg.body.memory_message().unwrap()) }; + let list_ipc = buffer.to_original::().unwrap(); + for &item in list_ipc.list.iter() { + match item { + ClipObjectType::Line(line) => { + op::line(display, line, None, false); + } + ClipObjectType::XorLine(line) => { + op::line(display, line, None, true); + } + ClipObjectType::Circ(circ) => { + op::circle(display, circ, None); + } + ClipObjectType::Rect(rect) => { + op::rectangle(display, rect, None, false); + } + ClipObjectType::RoundRect(rr) => { + op::rounded_rectangle(display, rr, None); + } + #[cfg(feature = "ditherpunk")] + _ => { + unimplemented!("Object type not yet implemented"); + } + } + } +} + pub fn line( display: &mut T, screen_clip: Option, @@ -166,7 +194,12 @@ pub fn draw_text_view(display: &mut T, msg: &mut xous::envelope: let mut tv = buffer.to_original::().unwrap(); if tv.clip_rect.is_none() { - return; + if cfg!(feature = "hosted-baosec") || cfg!(feature = "cramium-soc") || cfg!(feature = "board-baosec") + { + tv.clip_rect = Some(Rectangle::new(Point::new(0, 0), display.dimensions())); + } else { + return; + } } // if no clipping rectangle is specified, nothing to draw // this is the clipping rectangle of the canvas in screen coordinates diff --git a/libs/ux-api/src/service/api.rs b/libs/ux-api/src/service/api.rs index 9cd9568f5..c64cd4f43 100644 --- a/libs/ux-api/src/service/api.rs +++ b/libs/ux-api/src/service/api.rs @@ -12,6 +12,8 @@ impl Gid { pub fn new(id: [u32; 4]) -> Self { Gid { gid: id } } pub fn gid(&self) -> [u32; 4] { self.gid } + + pub fn dummy() -> Self { Gid { gid: [0xdead, 0xbeef, 0xdead, 0xbeef] } } } impl Hash for Gid { fn hash(&self, state: &mut H) @@ -89,6 +91,12 @@ pub enum GfxOpcode { /// Handle Camera IRQs CamIrq, + /// V2 API for claiming ownership of screen for modal operation + AcquireModal, + ReleaseModal, + /// V2 API for fast drawing of multiple objects + UnclippedObjectList, + /// Gutter for invalid calls InvalidCall, diff --git a/libs/ux-api/src/service/gfx.rs b/libs/ux-api/src/service/gfx.rs index f70a095c3..3f3b20a0b 100644 --- a/libs/ux-api/src/service/gfx.rs +++ b/libs/ux-api/src/service/gfx.rs @@ -310,6 +310,31 @@ impl Gfx { Ok(()) } + /// Bounds computation does no checks on security since it's a non-drawing operation. While normal drawing + /// always takes the bounds from the canvas, the caller can specify a clip_rect in this tv, instead of + /// drawing the clip_rect from the Canvas associated with the tv. + pub fn bounds_compute_textview(&self, tv: &mut TextView) -> Result<(), xous::Error> { + let mut tv_query = tv.clone(); + tv_query.set_dry_run(true); + let mut buf = Buffer::into_buf(tv_query).or(Err(xous::Error::InternalError))?; + buf.lend_mut(self.conn, GfxOpcode::DrawTextView.to_u32().unwrap()) + .or(Err(xous::Error::InternalError))?; + let tvr = buf.to_original::().unwrap(); + + tv.cursor = tvr.cursor; + tv.bounds_computed = tvr.bounds_computed; + tv.overflow = tvr.overflow; + // don't update the animation state when just computing the textview bounds + // tv.busy_animation_state = tvr.busy_animation_state; + Ok(()) + } + + /// Clear the screen in a device-optimized fashion. The exact background color depends on the device. + pub fn clear(&self) -> Result<(), xous::Error> { + send_message(self.conn, Message::new_scalar(GfxOpcode::Clear.to_usize().unwrap(), 0, 0, 0, 0)) + .map(|_| ()) + } + /// Draws a line with clipping. /// /// This function sends a message to the graphics server to draw the specified `Line` within the specified @@ -665,6 +690,33 @@ impl Gfx { .expect("couldn't pop"); } } + + /// This will cause the caller to block until it is granted a lock on the modal state. + /// + /// This is a v2-only API. Calling it on a v1 system will cause a panic. + pub fn acquire_modal(&self) -> Result { + send_message( + self.conn, + Message::new_blocking_scalar(GfxOpcode::AcquireModal.to_usize().unwrap(), 0, 0, 0, 0), + ) + } + + /// This is a v2-only API. Calling it on a v1 system will cause a panic. + pub fn release_modal(&self) -> Result { + send_message(self.conn, Message::new_scalar(GfxOpcode::ReleaseModal.to_usize().unwrap(), 0, 0, 0, 0)) + } + + /// V2-only API + pub fn draw_object_list(&self, list: ObjectList) -> Result<(), xous::Error> { + let buf = match Buffer::into_buf(list) { + Ok(b) => b, + Err(e) => { + log::error!("err: {:?}", e); + panic!("error") + } + }; + buf.lend(self.conn, GfxOpcode::UnclippedObjectList.to_u32().unwrap()).map(|_| ()) + } } use core::sync::atomic::{AtomicU32, Ordering}; diff --git a/libs/ux-api/src/widgets/action.rs b/libs/ux-api/src/widgets/action.rs index 854ed07af..15694e583 100644 --- a/libs/ux-api/src/widgets/action.rs +++ b/libs/ux-api/src/widgets/action.rs @@ -24,8 +24,10 @@ pub enum ActionType { #[enum_dispatch] pub trait ActionApi { - fn height(&self, glyph_height: i16, margin: i16, _modal: &Modal) -> i16 { glyph_height + margin * 2 } - fn redraw(&self, _at_height: i16, _modal: &Modal) { unimplemented!() } + fn height(&self, glyph_height: isize, margin: isize, _modal: &Modal) -> isize { + glyph_height + margin * 2 + } + fn redraw(&self, _at_height: isize, _modal: &Modal) { unimplemented!() } fn close(&mut self) {} fn is_password(&self) -> bool { false } /// navigation is one of '∴' | '←' | '→' | '↑' | '↓' diff --git a/libs/ux-api/src/widgets/modal.rs b/libs/ux-api/src/widgets/modal.rs index f230c1c98..275fe9b3e 100644 --- a/libs/ux-api/src/widgets/modal.rs +++ b/libs/ux-api/src/widgets/modal.rs @@ -4,10 +4,23 @@ use blitstr2::{GlyphStyle, glyph_height_hint}; use xous_ipc::Buffer; use super::*; +use crate::minigfx::op::HEIGHT; use crate::minigfx::*; use crate::platform::{LINES, WIDTH}; +use crate::service::api::Gid; +use crate::service::gfx::Gfx; + +#[derive(Debug, num_derive::FromPrimitive, num_derive::ToPrimitive)] +pub enum ModalOpcode { + // if changes are made here, also update MenuOpcode + Redraw = 0x4000_0000, /* set the high bit so that "standard" enums don't conflict with the + * Modal-specific opcodes */ + Rawkeys, + Quit, +} pub struct Modal<'a> { + pub gfx: Gfx, pub top_text: Option, pub bot_text: Option, pub action: ActionType, @@ -56,7 +69,9 @@ impl<'a> Modal<'a> { // we now have a canvas that is some minimal height, but with the final width as allowed by the GAM. // compute the final height based upon the contents within. + let xns = xous_names::XousNames::new().unwrap(); let mut modal = Modal { + gfx: Gfx::new(&xns).unwrap(), top_text: None, bot_text: None, action, @@ -82,18 +97,88 @@ impl<'a> Modal<'a> { modal } - pub fn activate(&self) { - todo!(); + pub fn activate(&mut self) { + self.gfx.acquire_modal().expect("Couldn't acquire lock on graphics subsystem"); + self.gfx.clear().ok(); + self.redraw(); + self.gfx.flush().ok(); } pub fn redraw(&mut self) { + let do_redraw = self.top_dirty || self.bot_dirty || self.inverted; + if do_redraw { + self.gfx.clear().unwrap(); + } + let mut cur_height = self.margin; + if let Some(mut tv) = self.top_text.as_mut() { + if do_redraw { + self.gfx.draw_textview(&mut tv).expect("couldn't draw text"); + if let Some(bounds) = tv.bounds_computed { + let y = bounds.br.y - bounds.tl.y; + let y_clip = if y > HEIGHT - self.line_height * 3 { + log::warn!("overside text, clipping back {}", HEIGHT - (self.line_height * 2)); + HEIGHT - (self.line_height * 2) + } else { + y + }; + cur_height += y_clip; + log::trace!("top_tv height: {}", y_clip); + self.top_memoized_height = Some(y_clip); + } else { + log::warn!("text bounds didn't compute setting to max"); + self.top_memoized_height = Some(HEIGHT - (self.line_height * 2)); + } + self.top_dirty = false; + } else { + cur_height += + self.top_memoized_height.expect("internal error: memoization didn't work correctly"); + } + } else { + self.top_dirty = false; + } + + let action_height = self.action.height(self.line_height, self.margin, &self); + if !do_redraw { + self.gfx.clear().unwrap(); + } + let action_resolver: Box<&dyn ActionApi> = Box::new(&self.action); - action_resolver.redraw(0, &self); - todo!(); + action_resolver.redraw(cur_height, &self); + + cur_height += action_height; + + if let Some(mut tv) = self.bot_text.as_mut() { + if do_redraw { + self.gfx.draw_textview(&mut tv).expect("couldn't draw text"); + if let Some(bounds) = tv.bounds_computed { + cur_height += bounds.br.y - bounds.tl.y; + self.bot_memoized_height = Some(bounds.br.y - bounds.tl.y); + } + self.bot_dirty = false; + } else { + cur_height += + self.bot_memoized_height.expect("internal error: memoization didn't work correctly"); + } + } else { + self.bot_dirty = false; + } + log::trace!("total height: {}", cur_height); + log::trace!("modal redraw##"); + self.gfx.flush().unwrap(); } pub fn key_event(&mut self, keys: [char; 4]) { - todo!(); + for &k in keys.iter() { + if k != '\u{0}' { + log::debug!("got key '{}'", k); + let action_resolver: Box<&mut dyn ActionApi> = Box::new(&mut self.action); + let err = action_resolver.key_action(k); + if let Some(err_msg) = err { + self.modify(None, None, false, Some(&err_msg), false, None); + } + } + } + self.redraw(); } /// This empowers an action within a modal to potentially consume all the available height in a canvas @@ -169,14 +254,13 @@ impl<'a> Modal<'a> { } else { self.style }; + layout(self, top_text, bot_text, style); } } pub fn screen_bounds() -> Point { Point::new(WIDTH as isize, LINES as isize) } // comment this out while I figure out how to shim in the HAL layer for the graphics emulation -fn layout(modal: &mut Modal, top_text: Option<&str>, bot_text: Option<&str>, style: GlyphStyle) {} -/* fn layout(modal: &mut Modal, top_text: Option<&str>, bot_text: Option<&str>, style: GlyphStyle) { // we need to set a "max" size to our modal box, so that the text computations don't fail later on let current_bounds = screen_bounds(); @@ -194,34 +278,41 @@ fn layout(modal: &mut Modal, top_text: Option<&str>, bot_text: Option<&str>, sty log::trace!("step 0 total_height: {}", total_height); // compute height of top_text, if any if let Some(top_str) = top_text { - let mut top_tv = TextView::new(TextBounds::GrowableFromTl( - Point::new(modal.margin, modal.margin), - (modal.canvas_width - modal.margin * 2) as u16, - )); - top_tv.draw_border = false; - top_tv.style = style; - top_tv.margin = Point::new(0, 0); // all margin already accounted for in the raw bounds of the text drawing - top_tv.ellipsis = false; - top_tv.invert = modal.inverted; - // specify a clip rect that's the biggest possible allowed. If we don't do this, the current canvas - // bounds are used, and the operation will fail if the text has to get bigger. - top_tv.clip_rect = Some(Rectangle::new( - Point::new(0, 0), - Point::new(current_bounds.x, LINES - 2 * modal.line_height), - )); - write!(top_tv.text, "{}", top_str).unwrap(); + if top_str.len() > 0 { + let mut top_tv = TextView::new( + Gid::dummy(), + TextBounds::GrowableFromTl( + Point::new(modal.margin, modal.margin), + (modal.canvas_width - modal.margin * 2) as u16, + ), + ); + top_tv.draw_border = false; + top_tv.style = style; + top_tv.margin = Point::new(0, 0); // all margin already accounted for in the raw bounds of the text drawing + top_tv.ellipsis = false; + top_tv.invert = true; + // specify a clip rect that's the biggest possible allowed. If we don't do this, the current + // canvas bounds are used, and the operation will fail if the text has to get bigger. + top_tv.clip_rect = Some(Rectangle::new( + Point::new(0, 0), + Point::new(current_bounds.x, LINES - 2 * modal.line_height), + )); + write!(top_tv.text, "{}", top_str).unwrap(); - log::trace!("posting top tv: {:?}", top_tv); - modal.gam.bounds_compute_textview(&mut top_tv).expect("couldn't simulate top text size"); - if let Some(bounds) = top_tv.bounds_computed { - log::trace!("top_tv bounds computed {}", bounds.br.y - bounds.tl.y); - total_height += bounds.br.y - bounds.tl.y; + log::trace!("posting top tv: {:?}", top_tv); + modal.gfx.bounds_compute_textview(&mut top_tv).expect("couldn't simulate top text size"); + if let Some(bounds) = top_tv.bounds_computed { + log::trace!("top_tv bounds computed {}", bounds.br.y - bounds.tl.y); + total_height += bounds.br.y - bounds.tl.y; + } else { + log::warn!("couldn't compute height for modal top_text: {:?}", top_tv); + // probably should find a better way to deal with this. + total_height += LINES - (modal.line_height * 2); + } + modal.top_text = Some(top_tv); } else { - log::warn!("couldn't compute height for modal top_text: {:?}", top_tv); - // probably should find a better way to deal with this. - total_height += LINES - (modal.line_height * 2); + modal.top_text = None; } - modal.top_text = Some(top_tv); } total_height += modal.margin; @@ -235,15 +326,18 @@ fn layout(modal: &mut Modal, top_text: Option<&str>, bot_text: Option<&str>, sty // compute height of bot_text, if any log::trace!("step 2 total_height: {}", total_height); if let Some(bot_str) = bot_text { - let mut bot_tv = TextView::new(TextBounds::GrowableFromTl( - Point::new(modal.margin, total_height), - (modal.canvas_width - modal.margin * 2) as u16, - )); + let mut bot_tv = TextView::new( + Gid::dummy(), + TextBounds::GrowableFromTl( + Point::new(modal.margin, total_height), + (modal.canvas_width - modal.margin * 2) as u16, + ), + ); bot_tv.draw_border = false; bot_tv.style = style; bot_tv.margin = Point::new(0, 0); // all margin already accounted for in the raw bounds of the text drawing bot_tv.ellipsis = false; - bot_tv.invert = modal.inverted; + bot_tv.invert = true; // specify a clip rect that's the biggest possible allowed. If we don't do this, the current canvas // bounds are used, and the operation will fail if the text has to get bigger. bot_tv.clip_rect = Some(Rectangle::new( @@ -253,7 +347,7 @@ fn layout(modal: &mut Modal, top_text: Option<&str>, bot_text: Option<&str>, sty write!(bot_tv.text, "{}", bot_str).unwrap(); log::trace!("posting bot tv: {:?}", bot_tv); - modal.gam.bounds_compute_textview(&mut bot_tv).expect("couldn't simulate bot text size"); + modal.gfx.bounds_compute_textview(&mut bot_tv).expect("couldn't simulate bot text size"); if let Some(bounds) = bot_tv.bounds_computed { total_height += bounds.br.y - bounds.tl.y; } else { @@ -265,4 +359,3 @@ fn layout(modal: &mut Modal, top_text: Option<&str>, bot_text: Option<&str>, sty } log::trace!("step 3 total_height: {}", total_height); } -*/ diff --git a/libs/ux-api/src/widgets/notification.rs b/libs/ux-api/src/widgets/notification.rs index 2598ba613..0452fe2d9 100644 --- a/libs/ux-api/src/widgets/notification.rs +++ b/libs/ux-api/src/widgets/notification.rs @@ -4,12 +4,16 @@ use locales::t; use qrcode::{Color, QrCode}; use super::*; +use crate::minigfx::op::{HEIGHT, WIDTH}; use crate::minigfx::*; +use crate::service::api::*; +use crate::service::gfx::Gfx; -pub(crate) const QUIET_MODULES: i16 = 2; +pub(crate) const QUIET_MODULES: isize = 2; #[derive(Debug)] pub struct Notification { + pub gfx: Gfx, pub action_conn: xous::CID, pub action_opcode: u32, pub is_password: bool, @@ -19,7 +23,9 @@ pub struct Notification { } impl Notification { pub fn new(action_conn: xous::CID, action_opcode: u32) -> Self { + let xns = xous_names::XousNames::new().unwrap(); Notification { + gfx: Gfx::new(&xns).unwrap(), action_conn, action_opcode, is_password: false, @@ -62,14 +68,137 @@ impl Notification { } } - fn draw_text(&self, at_height: i16, modal: &Modal) { - todo!(); + fn draw_text(&self, at_height: isize, modal: &Modal) { + // prime a textview with the correct general style parameters + let mut tv = TextView::new(Gid::dummy(), TextBounds::BoundingBox(Rectangle::new_coords(0, 0, 1, 1))); + tv.ellipsis = true; + tv.style = modal.style; + tv.invert = true; + tv.draw_border = false; + tv.margin = Point::new(0, 0); + tv.insertion = None; + + tv.bounds_computed = None; + tv.bounds_hint = TextBounds::GrowableFromTl( + Point::new(modal.margin, at_height + modal.margin * 2), + (modal.canvas_width - modal.margin * 2) as u16, + ); + write!(tv, "{}", t!("notification.dismiss", locales::LANG)).unwrap(); + self.gfx.bounds_compute_textview(&mut tv).expect("couldn't simulate text size"); + let textwidth = if let Some(bounds) = tv.bounds_computed { + bounds.br.x - bounds.tl.x + } else { + modal.canvas_width - modal.margin * 2 + }; + let offset = (modal.canvas_width - textwidth) / 2; + tv.bounds_computed = None; + tv.bounds_hint = TextBounds::BoundingBox(Rectangle::new( + Point::new(offset, at_height + modal.margin * 2), + Point::new(modal.canvas_width - modal.margin, at_height + modal.line_height + modal.margin * 2), + )); + self.gfx.draw_textview(&mut tv).expect("couldn't post tv"); } - fn draw_qrcode(&self, at_height: i16, modal: &Modal) { - todo!(); + fn draw_qrcode(&self, at_height: isize, modal: &Modal) { + // calculate pixel size of each module in the qrcode + let qrcode_modules: isize = self.qrwidth.try_into().unwrap(); + let modules: isize = qrcode_modules + 2 * QUIET_MODULES; + let canvas_width = modal.canvas_width - 2 * modal.margin; + let mod_size_px: isize = canvas_width / modules; + let qrcode_width_px = qrcode_modules * mod_size_px; + let quiet_px: isize = (canvas_width - qrcode_width_px) / 2; + + // Iterate thru qrcode and stamp each square module like a typewriter + let black = DrawStyle::new(PixelColor::Dark, PixelColor::Dark, 1); + let top = at_height + quiet_px; + + // draw a white background over the whole screen + self.gfx + .draw_rectangle(Rectangle::new_with_style( + Point::new(0, at_height), + Point::new(WIDTH, HEIGHT), + DrawStyle::new(PixelColor::Light, PixelColor::Light, 1), + )) + .unwrap(); + + let left = modal.margin + quiet_px; + let right = left + qrcode_modules * mod_size_px; + let mut module = + Rectangle::new_with_style(Point::new(0, 0), Point::new(mod_size_px - 1, mod_size_px - 1), black); + let step = Point::new(mod_size_px, 0); + let cr_lf = Point::new(-qrcode_modules * mod_size_px, mod_size_px); + let mut j: isize; + let mut obj_list = ObjectList::new(); + module.translate(Point::new(right, top)); + for (i, stamp) in self.qrcode.iter().enumerate() { + j = i.try_into().unwrap(); + if j % qrcode_modules == 0 { + module.translate(cr_lf); + } + if *stamp { + if obj_list.push(ClipObjectType::Rect(module.clone())).is_err() { + // the capacity of the list has exceeded the capacity of the buffer, send it and make a + // new one + self.gfx.draw_object_list(obj_list).expect("couldn't draw qrcode module"); + obj_list = ObjectList::new(); + obj_list.push(ClipObjectType::Rect(module.clone())).unwrap(); + }; + } + module.translate(step); + } + self.gfx.draw_object_list(obj_list).expect("couldn't draw qrcode module"); } } use crate::widgets::ActionApi; -impl ActionApi for Notification {} +impl ActionApi for Notification { + fn redraw(&self, at_height: isize, modal: &Modal) { + if self.qrwidth > 0 { + self.draw_qrcode(at_height, modal); + } else { + if self.manual_dismiss { + self.draw_text(at_height, modal); + modal + .gfx + .draw_line(Line::new_with_style( + Point::new(modal.margin, at_height + modal.margin), + Point::new(modal.canvas_width - modal.margin, at_height + modal.margin), + DrawStyle::new(PixelColor::Light, PixelColor::Light, 1), + )) + .expect("couldn't draw entry line"); + } + } + } + + fn key_action(&mut self, k: char) -> Option { + log::trace!("key_action: {}", k); + match k { + '\u{0}' => { + // ignore null messages + } + _ => { + // relinquish focus before returning the result + if self.manual_dismiss { + self.gfx.release_modal().unwrap(); + xous::yield_slice(); + } + + xous::send_message( + self.action_conn, + xous::Message::new_scalar(self.action_opcode as usize, k as u32 as usize, 0, 0, 0), + ) + .expect("couldn't pass on dismissal"); + if self.manual_dismiss { + return None; + } + } + } + None + } + + fn height(&self, _glyph_height: isize, margin: isize, _modal: &Modal) -> isize { + if self.qrwidth > 0 { HEIGHT } else { margin } + } + + fn set_action_opcode(&mut self, op: u32) { self.action_opcode = op } +} diff --git a/libs/ux-api/src/wordwrap.rs b/libs/ux-api/src/wordwrap.rs index e0057a89e..d9a5ebcda 100644 --- a/libs/ux-api/src/wordwrap.rs +++ b/libs/ux-api/src/wordwrap.rs @@ -160,18 +160,20 @@ impl ComposedType { let cr = ClipRect::new(clip_rect.tl().x, clip_rect.tl().y, clip_rect.br().x, clip_rect.br().y); let rawbuf = unsafe { frbuf.raw_mut() }; - if glyph.large { - blitstr2::xor_glyph_large( - rawbuf, - (maybe_x, maybe_y), - glyph, - glyph.invert ^ invert, - cr, - ); - } else if !glyph.double { - blitstr2::xor_glyph(rawbuf, (maybe_x, maybe_y), glyph, glyph.invert ^ invert, cr); + let char_invert = if cfg!(feature = "hosted-baosec") || cfg!(feature = "board-baosec") { + // OLED display background is black for power savings, so all polarities of drawing + // need to be allowed + true } else { - blitstr2::xor_glyph_2x(rawbuf, (maybe_x, maybe_y), glyph, glyph.invert ^ invert, cr); + glyph.invert ^ invert + }; + + if glyph.large { + blitstr2::xor_glyph_large(rawbuf, (maybe_x, maybe_y), glyph, char_invert, cr); + } else if !glyph.double { + blitstr2::xor_glyph(rawbuf, (maybe_x, maybe_y), glyph, char_invert, cr); + } else { + blitstr2::xor_glyph_2x(rawbuf, (maybe_x, maybe_y), glyph, char_invert, cr); } // Platform-dependent cursor inversion because the color scheme for sh1107 doesn't comply // to precursor norms diff --git a/loader/src/platform/cramium/cramium.rs b/loader/src/platform/cramium/cramium.rs index 301fdcf7d..d311709da 100644 --- a/loader/src/platform/cramium/cramium.rs +++ b/loader/src/platform/cramium/cramium.rs @@ -329,6 +329,9 @@ pub fn early_init() -> u32 { }; } if let Some(mut pmic) = pmic { + // disable CCM, force PWM on for DCDC2 - required for rail stability + pmic.set_pwm_mode(&mut i2c, cramium_hal::axp2101::WhichDcDc::Dcdc2, true).unwrap(); + pmic.set_ldo(&mut i2c, Some(2.5), cramium_hal::axp2101::WhichLdo::Aldo2).unwrap(); pmic.set_dcdc(&mut i2c, Some((1.2, false)), cramium_hal::axp2101::WhichDcDc::Dcdc4).unwrap(); crate::println!("AXP2101 configure: {:?}", pmic); diff --git a/services/bao-console/Cargo.toml b/services/bao-console/Cargo.toml index 0a6af484b..cc52dbf19 100644 --- a/services/bao-console/Cargo.toml +++ b/services/bao-console/Cargo.toml @@ -12,11 +12,32 @@ log-server = { package = "xous-api-log", version = "0.1.63" } log = "0.4.14" num-derive = { version = "0.4.2", default-features = false } num-traits = { version = "0.2.14", default-features = false } -cramium-hal = { path = "../../libs/cramium-hal", features = ["std"] } +cramium-hal = { path = "../../libs/cramium-hal", features = [ + "std", +], optional = true } cramium-api = { path = "../../libs/cramium-api" } -cram-hal-service = { path = "../cram-hal-service" } +cram-hal-service = { path = "../cram-hal-service", optional = true } +cramium-emu = { path = "../cramium-emu", optional = true } usb-cramium = { path = "../usb-cramium" } +modals = { path = "../modals", default-features = false } [features] -cramium-soc = ["utralib/cramium-soc"] +cramium-soc = [ + "utralib/cramium-soc", + "modals/cramium-soc", + "usb-cramium/cramium-soc", +] +board-baosec = [ + "modals/board-baosec", + "cram-hal-service", + "cramium-hal", + "usb-cramium/board-baosec", +] +hosted-baosec = [ + "modals/hosted-baosec", + "usb-cramium/hosted-baosec", + "cramium-emu", +] + +modal-testing = [] default = [] diff --git a/services/bao-console/src/cmds.rs b/services/bao-console/src/cmds.rs index 771074c7d..ebf2ebd1c 100644 --- a/services/bao-console/src/cmds.rs +++ b/services/bao-console/src/cmds.rs @@ -2,7 +2,10 @@ use core::fmt::Write; use std::collections::HashMap; use String; +#[cfg(feature = "cramium-soc")] use cram_hal_service::trng; +#[cfg(feature = "hosted-baosec")] +use cramium_emu::trng; use xous::MessageEnvelope; /////////////////////////// Common items to all commands diff --git a/services/bao-console/src/main.rs b/services/bao-console/src/main.rs index 6758ad36d..ec8034a13 100644 --- a/services/bao-console/src/main.rs +++ b/services/bao-console/src/main.rs @@ -12,6 +12,12 @@ fn main() { let tt = ticktimer::Ticktimer::new().unwrap(); shell::start_shell(); + #[cfg(feature = "modal-testing")] + { + log::set_max_level(log::LevelFilter::Debug); + modals::tests::spawn_test(); + } + loop { // just sleep as this is the parent thread tt.sleep_ms(120_000).ok(); diff --git a/services/bao-video/src/main.rs b/services/bao-video/src/main.rs index 9e5c129c7..d4a060a96 100644 --- a/services/bao-video/src/main.rs +++ b/services/bao-video/src/main.rs @@ -9,9 +9,12 @@ mod qr; #[cfg(feature = "gfx-testing")] mod testing; -use std::sync::{ - Arc, - atomic::{AtomicBool, Ordering}, +use std::{ + collections::VecDeque, + sync::{ + Arc, + atomic::{AtomicBool, Ordering}, + }, }; use blitstr2::fontmap; @@ -37,6 +40,7 @@ use utralib::utra; use ux_api::minigfx::{self, FrameBuffer}; use ux_api::service::api::*; use xous::MemoryRange; +use xous::sender::Sender; use xous_ipc::Buffer; // Scope of this crate: *No calls to modals* this can create dependency lockups. @@ -189,7 +193,7 @@ fn main() -> ! { pub fn wrapped_main(main_thread_token: MainThreadToken) -> ! { log_server::init_wait().unwrap(); - log::set_max_level(log::LevelFilter::Info); + log::set_max_level(log::LevelFilter::Trace); log::info!("my PID is {}", xous::process::id()); // ---- Xous setup @@ -299,6 +303,7 @@ pub fn wrapped_main(main_thread_token: MainThreadToken) -> ! { cam.capture_async(); } + let mut modal_queue = VecDeque::::new(); let mut frames = 0; let mut frame = [0u8; IMAGE_WIDTH * IMAGE_HEIGHT]; let mut decode_success; @@ -636,6 +641,41 @@ pub fn wrapped_main(main_thread_token: MainThreadToken) -> ! { log::error!("Invalid call to bao video server: {:?}", msg); } + // ---- v2 graphics API + GfxOpcode::AcquireModal => { + if let Some(scalar) = msg.body.scalar_message_mut() { + let sender = msg.sender; + log::debug!("Acquirer Sender: {:x?}", sender); + modal_queue.push_back(sender); + if modal_queue.len() > 1 { + // Prevents `msg` from being "dropped" which would cause the blocking scalar to + // return + core::mem::forget(msg_opt.take()); + } else { + scalar.arg1 = 0; + // the message is responded to, which allows the caller to unblock + } + } + } + GfxOpcode::ReleaseModal => { + if let Some(_scalar) = msg.body.scalar_message() { + let sender = msg.sender; + log::debug!("Release Sender: {:x?}", sender); + if let Some(pos) = modal_queue + .iter() + .position(|x| x.to_usize() & 0xffff_0000 == sender.to_usize() & 0xffff_0000) + { + modal_queue.remove(pos); + } else { + log::error!("Release modal called but sender {:x?} was not found", sender); + }; + if let Some(sender) = modal_queue.front() { + // Notify the waiter that it is allowed to run + xous::return_scalar(*sender, 0).unwrap(); + } + } + } + // ---- "regular" graphics API GfxOpcode::DrawClipObject => { minigfx::handlers::draw_clip_object(&mut display, msg); @@ -643,6 +683,9 @@ pub fn wrapped_main(main_thread_token: MainThreadToken) -> ! { GfxOpcode::DrawClipObjectList => { minigfx::handlers::draw_clip_object_list(&mut display, msg); } + GfxOpcode::UnclippedObjectList => { + minigfx::handlers::draw_object_list(&mut display, msg); + } GfxOpcode::DrawTextView => { minigfx::handlers::draw_text_view(&mut display, msg); } @@ -651,9 +694,7 @@ pub fn wrapped_main(main_thread_token: MainThreadToken) -> ! { display.redraw(); } GfxOpcode::Clear => { - let mut r = Rectangle::full_screen(); - r.style = DrawStyle::new(PixelColor::Light, PixelColor::Light, 0); - op::rectangle(&mut display, r, screen_clip.into(), false) + display.clear(); } GfxOpcode::Line => { minigfx::handlers::line(&mut display, screen_clip.into(), msg); diff --git a/services/cram-console/Cargo.toml b/services/cram-console/Cargo.toml index ab06c4980..355e60b4d 100644 --- a/services/cram-console/Cargo.toml +++ b/services/cram-console/Cargo.toml @@ -17,11 +17,10 @@ num-derive = { version = "0.4.2", default-features = false } num-traits = { version = "0.2.14", default-features = false } # xous-pio = { path = "../../libs/xous-pio", optional = true } -xous-pl230 = { path = "../../libs/xous-pl230", optional = true } +# xous-pl230 = { path = "../../libs/xous-pl230", optional = true } # this is temporary, until we get GAM/modals pulled in ux-api = { path = "../../libs/ux-api" } modals = { path = "../modals", features = ["cramium-soc"] } -gam = { path = "../gam" } locales = { path = "../../locales" } usb-device-xous = { path = "../usb-device-xous", default-features = false, optional = true } cramium-hal = { path = "../../libs/cramium-hal", features = ["std"] } @@ -30,8 +29,11 @@ ime-plugin-shell = { path = "../ime-plugin-shell" } xous-swapper = { path = "../xous-swapper" } [features] -"cramium-fpga" = ["utralib/cramium-fpga", "xous-pl230/cramium-fpga"] -"cramium-soc" = ["utralib/cramium-soc", "xous-pl230/cramium-soc"] +"cramium-fpga" = ["utralib/cramium-fpga"] +"cramium-soc" = ["utralib/cramium-soc"] +"board-baosec" = ["modals/board-baosec"] +"hosted-baosec" = ["modals/hosted-baosec"] + "hwsim" = [] "shellperf" = [] "mass-storage" = [] @@ -39,7 +41,7 @@ xous-swapper = { path = "../xous-swapper" } "tts" = [] "early-ball" = [] # "pio-test" = ["xous-pio"] -"pl230-test" = ["xous-pl230"] +# "pl230-test" = ["xous-pl230"] "hwtest" = [] "pddb" = [] "gam" = [] diff --git a/services/cram-hal-service/Cargo.toml b/services/cram-hal-service/Cargo.toml index 2ff1207ee..f259059e5 100644 --- a/services/cram-hal-service/Cargo.toml +++ b/services/cram-hal-service/Cargo.toml @@ -23,12 +23,12 @@ cramium-api = { path = "../../libs/cramium-api", features = [ "derive-rkyv", "std", ] } -xous-pl230 = { path = "../../libs/xous-pl230", features = ["cramium-soc"] } +# xous-pl230 = { path = "../../libs/xous-pl230", features = ["cramium-soc"] } # xous-pio = { path = "../../libs/xous-pio", default-features = false, features = [ # "cramium-soc", # ] } -pio-proc = "0.2.2" -pio = "0.2.1" +# pio-proc = "0.2.2" +# pio = "0.2.1" rand_core = "0.6.4" rand_chacha = "0.3.1" bitfield = "0.13.2" diff --git a/services/cramium-emu/src/trng.rs b/services/cramium-emu/src/trng.rs index 245310145..fcde8bfe9 100644 --- a/services/cramium-emu/src/trng.rs +++ b/services/cramium-emu/src/trng.rs @@ -50,3 +50,13 @@ impl RngCore for Trng { } impl CryptoRng for Trng {} + +pub mod api { + #[derive(Debug, num_derive::FromPrimitive, num_derive::ToPrimitive, PartialEq, Eq, Copy, Clone)] + pub enum TrngTestMode { + // No test mode configured. Whitened data is sampled. + None, + // Raw TRNG output. + Raw, + } +} diff --git a/services/graphics-server/src/main.rs b/services/graphics-server/src/main.rs index 85792b790..7b5fc5c05 100644 --- a/services/graphics-server/src/main.rs +++ b/services/graphics-server/src/main.rs @@ -471,6 +471,9 @@ fn wrapped_main(main_thread_token: backend::MainThreadToken) -> ! { } // no failure if it's not } + GfxOpcode::AcquireModal | GfxOpcode::ReleaseModal | GfxOpcode::UnclippedObjectList => { + unimplemented!("{:?} is not supported for this target. Use the GAM instead.", op); + } GfxOpcode::Quit => break, GfxOpcode::InvalidCall => { log::error!("Received invalid GfxOpcode. Ignoring."); diff --git a/services/modals/Cargo.toml b/services/modals/Cargo.toml index 31c3fe5f9..c8e971e07 100644 --- a/services/modals/Cargo.toml +++ b/services/modals/Cargo.toml @@ -28,6 +28,7 @@ bit_field = "0.9.0" cramium-hal = { path = "../../libs/cramium-hal", optional = true, features = [ "std", ] } +cramium-api = { path = "../../libs/cramium-api", optional = true } cramium-emu = { path = "../cramium-emu", optional = true } blitstr2 = { path = "../../libs/blitstr2" } ux-api = { path = "../../libs/ux-api", optional = true, features = ["std"] } @@ -40,9 +41,10 @@ hosted = ["utralib/hosted", "trng", "gam", "tts-frontend"] renode = ["utralib/renode", "trng", "gam", "tts-frontend"] cramium-soc = ["utralib/cramium-soc", "cram-hal-service"] -hosted-baosec = ["ux-api/hosted-baosec", "cramium-emu"] -board-baosec = ["ux-api/board-baosec"] +hosted-baosec = ["ux-api/hosted-baosec", "cramium-emu", "cramium-api"] +board-baosec = ["ux-api/board-baosec", "cramium-api"] doc-deps = ["gam", "ux-api/doc-deps"] +modal-testing = [] tts = [] ditherpunk = [] diff --git a/services/modals/src/api.rs b/services/modals/src/api.rs index 69fbb947f..35e82a3b7 100644 --- a/services/modals/src/api.rs +++ b/services/modals/src/api.rs @@ -1,8 +1,8 @@ #[cfg(feature = "ditherpunk")] use gam::Tile; -#[cfg(not(any(feature = "hosted-baosec", feature = "cramium-soc")))] +#[cfg(not(any(feature = "hosted-baosec", feature = "board-baosec")))] use gam::modal::*; -#[cfg(any(feature = "hosted-baosec", feature = "cramium-soc"))] +#[cfg(any(feature = "hosted-baosec", feature = "board-baosec"))] use ux_api::widgets::*; pub(crate) const SERVER_NAME_MODALS: &str = "_Modal Dialog Server_"; diff --git a/services/modals/src/lib.rs b/services/modals/src/lib.rs index 999614426..137012c06 100644 --- a/services/modals/src/lib.rs +++ b/services/modals/src/lib.rs @@ -2,7 +2,7 @@ pub mod api; use api::*; -#[cfg(feature = "ditherpunk")] +#[cfg(any(feature = "ditherpunk", feature = "modal-testing"))] pub mod tests; use core::cell::Cell; @@ -16,12 +16,12 @@ use bit_field::BitField; use cram_hal_service::trng::Trng; #[cfg(feature = "hosted-baosec")] use cramium_emu::trng::Trng; -#[cfg(not(any(feature = "hosted-baosec", feature = "cramium-soc")))] +#[cfg(not(any(feature = "hosted-baosec", feature = "board-baosec")))] use gam::*; use num_traits::*; #[cfg(all(not(feature = "cramium-soc"), not(feature = "doc-deps"), not(feature = "hosted-baosec")))] use trng::Trng; -#[cfg(any(feature = "hosted-baosec", feature = "cramium-soc"))] +#[cfg(any(feature = "hosted-baosec", feature = "board-baosec"))] use ux_api::widgets::*; use xous::{CID, Message, send_message}; use xous_ipc::Buffer; diff --git a/services/modals/src/main.rs b/services/modals/src/main.rs index b95a66f59..8197bfb40 100644 --- a/services/modals/src/main.rs +++ b/services/modals/src/main.rs @@ -36,14 +36,14 @@ use cram_hal_service::trng::Trng; use cramium_emu::trng::Trng; #[cfg(feature = "ditherpunk")] use gam::Bitmap; -#[cfg(not(any(feature = "hosted-baosec", feature = "cramium-soc")))] +#[cfg(not(any(feature = "hosted-baosec", feature = "board-baosec")))] use gam::modal::*; use locales::t; #[cfg(all(not(feature = "cramium-soc"), not(feature = "doc-deps"), not(feature = "hosted-baosec")))] use trng::Trng; #[cfg(feature = "tts")] use tts_frontend::TtsFrontend; -#[cfg(any(feature = "hosted-baosec", feature = "cramium-soc"))] +#[cfg(any(feature = "hosted-baosec", feature = "board-baosec"))] use ux_api::widgets::*; use xous::{Message, msg_blocking_scalar_unpack, msg_scalar_unpack, send_message}; use xous_ipc::Buffer; @@ -144,6 +144,11 @@ fn wrapped_main() -> ! { #[cfg(any(feature = "hosted-baosec", feature = "cramium-soc"))] let mut renderer_modal = Modal::new(ActionType::TextEntry(text_action.clone()), Some("Placeholder"), None, DEFAULT_STYLE, 8); + #[cfg(any(feature = "hosted-baosec", feature = "cramium-soc"))] + { + let kbd = cramium_api::keyboard::Keyboard::new(&xns).unwrap(); + kbd.register_listener(api::SERVER_NAME_MODALS, Opcode::ModalKeypress.to_u32().unwrap() as usize); + } #[cfg(not(any(feature = "hosted-baosec", feature = "cramium-soc")))] renderer_modal.spawn_helper( modals_sid, diff --git a/services/modals/src/tests.rs b/services/modals/src/tests.rs index 3a8b7cf91..1064c60e3 100644 --- a/services/modals/src/tests.rs +++ b/services/modals/src/tests.rs @@ -2,7 +2,10 @@ use std::thread; #[cfg(feature = "ditherpunk")] use bitmap::PixelType; +#[cfg(not(any(feature = "hosted-baosec", feature = "cramium-soc")))] use gam::*; +#[cfg(any(feature = "hosted-baosec", feature = "cramium-soc"))] +use ux_api::widgets::*; use xous_names::XousNames; use super::*; diff --git a/services/usb-cramium/Cargo.toml b/services/usb-cramium/Cargo.toml index 3af1d7e28..e1c54ae39 100644 --- a/services/usb-cramium/Cargo.toml +++ b/services/usb-cramium/Cargo.toml @@ -18,8 +18,9 @@ cramium-hal = { path = "../../libs/cramium-hal", features = [ "debug-print-usb", # "verbose-debug", "axp2101", -] } -cram-hal-service = { path = "../cram-hal-service" } +], optional = true } +cram-hal-service = { path = "../cram-hal-service", optional = true } +cramium-emu = { path = "../cramium-emu", optional = true } xous-usb-hid = { git = "https://github.com/betrusted-io/xous-usb-hid.git", branch = "main" } rkyv = { version = "0.8.8", default-features = false, features = [ "std", @@ -37,7 +38,14 @@ version = "0.2.8" features = ["log"] [features] -cramium-soc = ["utralib/cramium-soc", "utralib/std"] +cramium-soc = [] +board-baosec = [ + "utralib/cramium-soc", + "utralib/std", + "cramium-hal", + "cram-hal-service", +] +hosted-baosec = ["utralib/hosted", "utralib/std", "cramium-emu"] # none of these other modes are actually supported, but are listed here # to allow direct re-use of API code precursor = ["utralib/precursor", "utralib/std"] diff --git a/services/usb-cramium/src/lib.rs b/services/usb-cramium/src/lib.rs index 87a1bafe9..8d1e4716f 100644 --- a/services/usb-cramium/src/lib.rs +++ b/services/usb-cramium/src/lib.rs @@ -1,6 +1,9 @@ #![cfg_attr(target_os = "none", no_std)] +#[cfg(feature = "cramium-soc")] use cram_hal_service::trng; +#[cfg(feature = "hosted-baosec")] +use cramium_emu::trng; pub mod api; pub use api::*; diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 04f1478fe..ba1791691 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -365,7 +365,15 @@ fn main() -> Result<(), Box> { .add_apps(&get_cratespecs()); } Some("baosec-emu") => { - let bao_pkgs = ["xous-ticktimer", "xous-log", "xous-names", "modals", "bao-video", "cramium-emu"]; + let bao_pkgs = [ + "xous-ticktimer", + "xous-log", + "xous-names", + "modals", + "bao-video", + "cramium-emu", + "bao-console", + ]; builder // hosted-baosec feature added below .target_hosted_baosec() @@ -598,7 +606,7 @@ fn main() -> Result<(), Box> { // - [planned] pddb server // - [planned] vault application let bao_rram_pkgs = ["xous-ticktimer", "xous-log", "xous-names" /* "usb-cramium" */].to_vec(); /* "usb-cramium" */ - let bao_swap_pkgs = ["cram-hal-service", "bao-console", "bao-video", "pddb"].to_vec(); /* "bao-video" */ + let bao_swap_pkgs = ["cram-hal-service", "bao-console", "bao-video", "modals", "pddb"].to_vec(); /* "bao-video" */ if !builder.is_swap_set() { builder.set_swap(0, 8 * 1024 * 1024); } @@ -676,7 +684,7 @@ fn main() -> Result<(), Box> { "default = []", ) .expect("couldn't patch AES"); - builder::search_and_replace_in_file( + builder::search_and_replace_in_file(WIP modals refactoring "Cargo.toml", "# [patch.crates-io.curve25519-dalek]", "[patch.crates-io.curve25519-dalek]",