very basic battery monitoring via COM

This commit is contained in:
bunnie 2020-11-25 05:11:32 +08:00
parent 471befa970
commit d583e20b18
8 changed files with 220 additions and 150 deletions

2
Cargo.lock generated
View file

@ -142,6 +142,8 @@ dependencies = [
"heapless",
"log",
"log-server",
"ticktimer-server",
"typenum",
"utralib",
"xous",
]

View file

@ -12,68 +12,9 @@
<resetMask>0xFFFFFFFF</resetMask>
<peripherals>
<peripheral>
<name>CTRL</name>
<baseAddress>0xF0000000</baseAddress>
<groupName>CTRL</groupName>
<registers>
<register>
<name>RESET</name>
<description><![CDATA[Write a ``1`` to this register to reset the SoC.]]></description>
<addressOffset>0x0000</addressOffset>
<resetValue>0x00</resetValue>
<size>32</size>
<fields>
<field>
<name>reset</name>
<msb>0</msb>
<bitRange>[0:0]</bitRange>
<lsb>0</lsb>
</field>
</fields>
</register>
<register>
<name>SCRATCH</name>
<description><![CDATA[Use this register as a scratch space to verify that software read/write accesses
to the Wishbone/CSR bus are working correctly. The initial reset value of
0x1234578 can be used to verify endianness.]]></description>
<addressOffset>0x0004</addressOffset>
<resetValue>0x12345678</resetValue>
<size>32</size>
<fields>
<field>
<name>scratch</name>
<msb>31</msb>
<bitRange>[31:0]</bitRange>
<lsb>0</lsb>
</field>
</fields>
</register>
<register>
<name>BUS_ERRORS</name>
<description><![CDATA[Total number of Wishbone bus errors (timeouts) since start.]]></description>
<addressOffset>0x0008</addressOffset>
<resetValue>0x00</resetValue>
<size>32</size>
<fields>
<field>
<name>bus_errors</name>
<msb>31</msb>
<bitRange>[31:0]</bitRange>
<lsb>0</lsb>
</field>
</fields>
</register>
</registers>
<addressBlock>
<offset>0</offset>
<size>0xc</size>
<usage>registers</usage>
</addressBlock>
</peripheral>
<peripheral>
<name>IDENTIFIER_MEM</name>
<baseAddress>0xF0002000</baseAddress>
<baseAddress>0xF0001000</baseAddress>
<groupName>IDENTIFIER_MEM</groupName>
<registers>
<register>
@ -100,7 +41,7 @@ to the Wishbone/CSR bus are working correctly. The initial reset value of
</peripheral>
<peripheral>
<name>TIMER0</name>
<baseAddress>0xF0003000</baseAddress>
<baseAddress>0xF0002000</baseAddress>
<groupName>TIMER0</groupName>
<registers>
<register>
@ -246,17 +187,19 @@ register to disable individual events.]]></description>
</peripheral>
<peripheral>
<name>REBOOT</name>
<baseAddress>0xF0004000</baseAddress>
<baseAddress>0xF0003000</baseAddress>
<groupName>REBOOT</groupName>
<registers>
<register>
<name>CTRL</name>
<name>SOC_RESET</name>
<description><![CDATA[Writing 0xAC to this register will do a full SoC reset, including CRGs and
peripherals]]></description>
<addressOffset>0x0000</addressOffset>
<resetValue>0x00</resetValue>
<size>32</size>
<fields>
<field>
<name>ctrl</name>
<name>soc_reset</name>
<msb>7</msb>
<bitRange>[7:0]</bitRange>
<lsb>0</lsb>
@ -265,6 +208,7 @@ register to disable individual events.]]></description>
</register>
<register>
<name>ADDR</name>
<description><![CDATA[The address written here will be used as the next reset vector]]></description>
<addressOffset>0x0004</addressOffset>
<resetValue>0x00</resetValue>
<size>32</size>
@ -277,16 +221,32 @@ register to disable individual events.]]></description>
</field>
</fields>
</register>
<register>
<name>CPU_RESET</name>
<description><![CDATA[Writing anything to this register resets the CPU, and the CPU only; does not
affect CRG or peripherals]]></description>
<addressOffset>0x0008</addressOffset>
<resetValue>0x00</resetValue>
<size>32</size>
<fields>
<field>
<name>cpu_reset</name>
<msb>0</msb>
<bitRange>[0:0]</bitRange>
<lsb>0</lsb>
</field>
</fields>
</register>
</registers>
<addressBlock>
<offset>0</offset>
<size>0x8</size>
<size>0xc</size>
<usage>registers</usage>
</addressBlock>
</peripheral>
<peripheral>
<name>CRG</name>
<baseAddress>0xF0005000</baseAddress>
<baseAddress>0xF0004000</baseAddress>
<groupName>CRG</groupName>
<registers>
<register>
@ -410,7 +370,7 @@ register to disable individual events.]]></description>
</peripheral>
<peripheral>
<name>GPIO</name>
<baseAddress>0xF0006000</baseAddress>
<baseAddress>0xF0005000</baseAddress>
<groupName>GPIO</groupName>
<registers>
<register>
@ -724,7 +684,7 @@ register to disable individual events.]]></description>
</peripheral>
<peripheral>
<name>UART_PHY</name>
<baseAddress>0xF0007000</baseAddress>
<baseAddress>0xF0006000</baseAddress>
<groupName>UART_PHY</groupName>
<registers>
<register>
@ -750,7 +710,7 @@ register to disable individual events.]]></description>
</peripheral>
<peripheral>
<name>UART</name>
<baseAddress>0xF0008000</baseAddress>
<baseAddress>0xF0007000</baseAddress>
<groupName>UART</groupName>
<registers>
<register>
@ -908,7 +868,7 @@ register to disable individual events.]]></description>
</peripheral>
<peripheral>
<name>CONSOLE_PHY</name>
<baseAddress>0xF0009000</baseAddress>
<baseAddress>0xF0008000</baseAddress>
<groupName>CONSOLE_PHY</groupName>
<registers>
<register>
@ -934,7 +894,7 @@ register to disable individual events.]]></description>
</peripheral>
<peripheral>
<name>CONSOLE</name>
<baseAddress>0xF000A000</baseAddress>
<baseAddress>0xF0009000</baseAddress>
<groupName>CONSOLE</groupName>
<registers>
<register>
@ -1092,7 +1052,7 @@ register to disable individual events.]]></description>
</peripheral>
<peripheral>
<name>SERVER0_PHY</name>
<baseAddress>0xF000B000</baseAddress>
<baseAddress>0xF000A000</baseAddress>
<groupName>SERVER0_PHY</groupName>
<registers>
<register>
@ -1118,7 +1078,7 @@ register to disable individual events.]]></description>
</peripheral>
<peripheral>
<name>SERVER0</name>
<baseAddress>0xF000C000</baseAddress>
<baseAddress>0xF000B000</baseAddress>
<groupName>SERVER0</groupName>
<registers>
<register>
@ -1276,7 +1236,7 @@ register to disable individual events.]]></description>
</peripheral>
<peripheral>
<name>SERVER1_PHY</name>
<baseAddress>0xF000D000</baseAddress>
<baseAddress>0xF000C000</baseAddress>
<groupName>SERVER1_PHY</groupName>
<registers>
<register>
@ -1302,7 +1262,7 @@ register to disable individual events.]]></description>
</peripheral>
<peripheral>
<name>SERVER1</name>
<baseAddress>0xF000E000</baseAddress>
<baseAddress>0xF000D000</baseAddress>
<groupName>SERVER1</groupName>
<registers>
<register>
@ -1460,7 +1420,7 @@ register to disable individual events.]]></description>
</peripheral>
<peripheral>
<name>INFO</name>
<baseAddress>0xF000F000</baseAddress>
<baseAddress>0xF000E000</baseAddress>
<groupName>INFO</groupName>
<registers>
<register>
@ -1856,7 +1816,7 @@ VCCBRAM (V) = ``Value`` x 3 / 4096.]]></description>
</peripheral>
<peripheral>
<name>SRAM_EXT</name>
<baseAddress>0xF0010000</baseAddress>
<baseAddress>0xF000F000</baseAddress>
<groupName>SRAM_EXT</groupName>
<registers>
<register>
@ -1898,7 +1858,7 @@ VCCBRAM (V) = ``Value`` x 3 / 4096.]]></description>
</peripheral>
<peripheral>
<name>MEMLCD</name>
<baseAddress>0xF0011000</baseAddress>
<baseAddress>0xF0010000</baseAddress>
<groupName>MEMLCD</groupName>
<registers>
<register>
@ -2014,7 +1974,7 @@ register to disable individual events.]]></description>
</peripheral>
<peripheral>
<name>COM</name>
<baseAddress>0xF0012000</baseAddress>
<baseAddress>0xF0011000</baseAddress>
<groupName>COM</groupName>
<registers>
<register>
@ -2171,10 +2131,14 @@ register to disable individual events.]]></description>
<size>0x1c</size>
<usage>registers</usage>
</addressBlock>
<interrupt>
<name>com</name>
<value>6</value>
</interrupt>
</peripheral>
<peripheral>
<name>I2C</name>
<baseAddress>0xF0013000</baseAddress>
<baseAddress>0xF0012000</baseAddress>
<groupName>I2C</groupName>
<registers>
<register>
@ -2422,12 +2386,12 @@ register to disable individual events.]]></description>
</addressBlock>
<interrupt>
<name>i2c</name>
<value>6</value>
<value>7</value>
</interrupt>
</peripheral>
<peripheral>
<name>BTEVENTS</name>
<baseAddress>0xF0014000</baseAddress>
<baseAddress>0xF0013000</baseAddress>
<groupName>BTEVENTS</groupName>
<registers>
<register>
@ -2511,12 +2475,12 @@ register to disable individual events.]]></description>
</addressBlock>
<interrupt>
<name>btevents</name>
<value>7</value>
<value>8</value>
</interrupt>
</peripheral>
<peripheral>
<name>MESSIBLE</name>
<baseAddress>0xF0015000</baseAddress>
<baseAddress>0xF0014000</baseAddress>
<groupName>MESSIBLE</groupName>
<registers>
<register>
@ -2582,7 +2546,7 @@ register advances the read pointer automatically.]]></description>
</peripheral>
<peripheral>
<name>MESSIBLE2</name>
<baseAddress>0xF0016000</baseAddress>
<baseAddress>0xF0015000</baseAddress>
<groupName>MESSIBLE2</groupName>
<registers>
<register>
@ -2648,7 +2612,7 @@ register advances the read pointer automatically.]]></description>
</peripheral>
<peripheral>
<name>TICKTIMER</name>
<baseAddress>0xF0017000</baseAddress>
<baseAddress>0xF0016000</baseAddress>
<groupName>TICKTIMER</groupName>
<registers>
<register>
@ -2793,12 +2757,12 @@ register to disable individual events.]]></description>
</addressBlock>
<interrupt>
<name>ticktimer</name>
<value>8</value>
<value>9</value>
</interrupt>
</peripheral>
<peripheral>
<name>POWER</name>
<baseAddress>0xF0018000</baseAddress>
<baseAddress>0xF0017000</baseAddress>
<groupName>POWER</groupName>
<registers>
<register>
@ -2958,7 +2922,7 @@ reset fashion]]></description>
</peripheral>
<peripheral>
<name>SPINOR</name>
<baseAddress>0xF0019000</baseAddress>
<baseAddress>0xF0018000</baseAddress>
<groupName>SPINOR</groupName>
<registers>
<register>
@ -3239,7 +3203,7 @@ checked]]></description>
</peripheral>
<peripheral>
<name>KEYBOARD</name>
<baseAddress>0xF001A000</baseAddress>
<baseAddress>0xF0019000</baseAddress>
<groupName>KEYBOARD</groupName>
<registers>
<register>
@ -3449,19 +3413,19 @@ again until the interrupt is serviced.]]></description>
</addressBlock>
<interrupt>
<name>keyboard</name>
<value>9</value>
<value>10</value>
</interrupt>
</peripheral>
<peripheral>
<name>SEED</name>
<baseAddress>0xF001B000</baseAddress>
<baseAddress>0xF001A000</baseAddress>
<groupName>SEED</groupName>
<registers>
<register>
<name>SEED1</name>
<description><![CDATA[Bits 32-63 of `SEED_SEED`. Seed used for the build]]></description>
<addressOffset>0x0000</addressOffset>
<resetValue>0x20483d3b</resetValue>
<resetValue>0x2c552c3f</resetValue>
<size>32</size>
<fields>
<field>
@ -3476,7 +3440,7 @@ again until the interrupt is serviced.]]></description>
<name>SEED0</name>
<description><![CDATA[Bits 0-31 of `SEED_SEED`.]]></description>
<addressOffset>0x0004</addressOffset>
<resetValue>0x1febda0d</resetValue>
<resetValue>0x3e20093a</resetValue>
<size>32</size>
<fields>
<field>
@ -3496,7 +3460,7 @@ again until the interrupt is serviced.]]></description>
</peripheral>
<peripheral>
<name>ROMTEST</name>
<baseAddress>0xF001C000</baseAddress>
<baseAddress>0xF001B000</baseAddress>
<groupName>ROMTEST</groupName>
<registers>
<register>
@ -3538,7 +3502,7 @@ again until the interrupt is serviced.]]></description>
</peripheral>
<peripheral>
<name>AUDIO</name>
<baseAddress>0xF001D000</baseAddress>
<baseAddress>0xF001C000</baseAddress>
<groupName>AUDIO</groupName>
<registers>
<register>
@ -3905,12 +3869,12 @@ I2S_FORMAT.I2S_STANDARD is I2S standard]]></description>
</addressBlock>
<interrupt>
<name>audio</name>
<value>10</value>
<value>11</value>
</interrupt>
</peripheral>
<peripheral>
<name>TRNG_OSC</name>
<baseAddress>0xF001E000</baseAddress>
<baseAddress>0xF001D000</baseAddress>
<groupName>TRNG_OSC</groupName>
<registers>
<register>
@ -3996,7 +3960,7 @@ reading the `rand` register]]></description>
</peripheral>
<peripheral>
<name>AES</name>
<baseAddress>0xF001F000</baseAddress>
<baseAddress>0xF001E000</baseAddress>
<groupName>AES</groupName>
<registers>
<register>
@ -4459,7 +4423,7 @@ automatically on data and IV ready]]></description>
</peripheral>
<peripheral>
<name>SHA512</name>
<baseAddress>0xF0020000</baseAddress>
<baseAddress>0xF001F000</baseAddress>
<groupName>SHA512</groupName>
<registers>
<register>
@ -4949,12 +4913,12 @@ in bits]]></description>
</addressBlock>
<interrupt>
<name>sha512</name>
<value>11</value>
<value>12</value>
</interrupt>
</peripheral>
<peripheral>
<name>ENGINE</name>
<baseAddress>0xF0021000</baseAddress>
<baseAddress>0xF0020000</baseAddress>
<groupName>ENGINE</groupName>
<registers>
<register>
@ -5178,12 +5142,12 @@ exactly reflects the binary layout of an Engine instruction.]]></description>
</addressBlock>
<interrupt>
<name>engine</name>
<value>12</value>
<value>13</value>
</interrupt>
</peripheral>
<peripheral>
<name>JTAG</name>
<baseAddress>0xF0022000</baseAddress>
<baseAddress>0xF0021000</baseAddress>
<groupName>JTAG</groupName>
<registers>
<register>

View file

@ -9,9 +9,12 @@ description = "COM interface to the EC"
xous = { path = "../../xous-rs" }
heapless = "0.5"
log-server = { path = "../log-server" }
ticktimer-server = { path = "../ticktimer-server" }
log = "0.4"
com_rs = { path = "com_rs" }
#[target.'cfg(not(any(windows,unix)))'.dependencies]
typenum = "1.12"
[target.'cfg(not(any(windows,unix)))'.dependencies]
utralib = { path = "../../utralib"}
[target.'cfg(any(windows,unix))'.dependencies]

View file

@ -4,12 +4,44 @@ use xous::{Message, ScalarMessage};
// It's just a convenient abuse of already-defined constants. However, it's intended that
// the COM server on the SoC side abstracts much of the EC bus complexity away.
use com_rs::*;
#[derive(Debug, Default)]
pub struct BattStats {
/// instantaneous voltage in mV
pub voltage: u16,
/// state of charge in %, as inferred by impedance tracking
pub soc: u8,
/// instantaneous current draw in mA
pub current: i16,
/// remaining capacity in mA, as measured by coulomb counting
pub remaining_capacity: u16,
}
impl From<[usize; 2]> for BattStats {
fn from(a: [usize; 2]) -> BattStats {
BattStats {
voltage: (a[0] & 0xFFFF) as u16,
soc: ((a[0] >> 16) & 0xFF) as u8,
current: ((a[1] >> 16) & 0xFFFF) as i16,
remaining_capacity: (a[1] & 0xFFFF) as u16,
}
}
}
impl Into<[usize; 2]> for BattStats {
fn into(self) -> [usize; 2] {
[ (self.voltage as usize & 0xffff) | ((self.soc as usize) << 16) & 0xFF_0000,
(self.remaining_capacity as usize & 0xffff) | ((self.current as usize) << 16) & 0xffff_0000 ]
}
}
#[derive(Debug)]
pub enum Opcode {
/// Battery stats
BattStats,
/// Query Full charge capacity of the battery
BattFullCapacity,
/// Turn Boost Mode On
BoostOn,

View file

@ -1,13 +1,27 @@
#![cfg_attr(target_os = "none", no_std)]
/// This is the API that other servers use to call the COM. Read this code as if you
/// are calling these functions inside a different process.
pub mod api;
use api::BattStats;
use xous::{send_message, Error, CID};
pub fn power_off_soc(cid: CID) -> Result<(), xous::Error> {
send_message(cid, api::Opcode::PowerOffSoc.into()).map(|_| ())
}
pub fn get_batt_stats(cid: CID) -> Result<BattStats, xous::Error> {
let response = send_message(cid, api::Opcode::BattStats.into())?;
if let xous::Result::Scalar2(upper, lower) = response {
let raw_stats: [usize; 2] = [lower, upper];
Ok(raw_stats.into())
} else {
panic!("unexpected return value: {:#?}", response);
}
}
/*
pub fn elapsed_ms(cid: CID) -> Result<u64, Error> {
let response = send_message(cid, api::Opcode::ElapsedMs.into())?;

View file

@ -10,28 +10,39 @@ use api::Opcode;
use core::convert::TryFrom;
/*
use heapless::binary_heap::{BinaryHeap, Min};
use heapless::Vec;
use heapless::consts::*;
type U1280 = UInt<UInt<UInt<UInt<UInt<UInt<UInt<UInt<UInt<UInt<UInt<UTerm, B1>, B0>, B1>, B0>, B0>, B0>, B0>, B0>, B0>, B0>, B0>;
*/
use log::{error, info};
use com_rs::*;
//#[cfg(target_os = "none")]
#[cfg(target_os = "none")]
mod implementation {
use crate::api::BattStats;
use ticktimer_server::*;
use com_rs::*;
use utralib::generated::*;
use xous::CID;
/*
#[macro_use]
use heapless::Vec;
use typenum::{UInt, UTerm};
use typenum::bit::{B0, B1};
type U1280 = UInt<UInt<UInt<UInt<UInt<UInt<UInt<UInt<UInt<UInt<UInt<UTerm, B1>, B0>, B1>, B0>, B0>, B0>, B0>, B0>, B0>, B0>, B0>;
*/
const STD_TIMEOUT: u32 = 100;
pub struct XousCom {
csr: utralib::CSR<u32>,
ticktimer: CID,
}
fn handle_irq(_irq_no: usize, arg: *mut usize) {
let _xc = unsafe { &mut *(arg as *mut XousCom) };
let xc = unsafe { &mut *(arg as *mut XousCom) };
println!("COM IRQ");
// just clear the pending request, as this is used as a "wait" until request function
xc.csr.wo(utra::com::EV_PENDING, xc.csr.r(utra::com::EV_PENDING));
}
impl XousCom {
@ -44,8 +55,15 @@ mod implementation {
)
.expect("couldn't map COM CSR range");
let ticktimer_server_id = xous::SID::from_bytes(b"ticktimer-server").unwrap();
let ticktimer_conn = xous::connect(ticktimer_server_id).unwrap();
let mut xc = XousCom {
csr: CSR::new(csr.as_mut_ptr() as *mut u32),
ticktimer: ticktimer_conn,
//tx_queue: Vec::new(),
//rx_queue: Vec::new(),
//in_progress: false,
};
xous::claim_interrupt(
@ -68,12 +86,53 @@ mod implementation {
// grab the RX value and return it
self.csr.rf(utra::com::RX_RX) as u16
}
pub fn wait_txrx(&mut self, tx: u16, timeout: Option<u32>) -> u16 {
self.csr.wfo(utra::com::EV_ENABLE_SPI_HOLD, 1);
if timeout.is_some() {
let curtime = ticktimer_server::elapsed_ms(self.ticktimer).expect("couldn't connect to ticktimer");
let mut timed_out = false;
let to = timeout.unwrap() as u64;
// timeout after 0.25 second to avoid hangs in case of a bug in the protocol
while self.csr.rf(utra::com::STATUS_HOLD) == 1 && !timed_out {
if (ticktimer_server::elapsed_ms(self.ticktimer).expect("couldn't connect to ticktimer") - curtime) > to {
timed_out = true;
}
xous::wait_event();
}
} else {
while self.csr.rf(utra::com::STATUS_HOLD) == 1 {
xous::wait_event();
}
}
self.csr.wfo(utra::com::EV_ENABLE_SPI_HOLD, 0);
self.txrx(tx)
}
pub fn get_battstats(&mut self) -> BattStats {
let mut stats = BattStats::default();
self.txrx(ComState::GAS_GAUGE.verb);
stats.current = self.wait_txrx(ComState::LINK_READ.verb, Some(STD_TIMEOUT)) as i16;
self.wait_txrx(ComState::LINK_READ.verb, Some(100)); // stby_current, not used here
stats.voltage = self.wait_txrx(ComState::LINK_READ.verb, Some(STD_TIMEOUT));
self.wait_txrx(ComState::LINK_READ.verb, Some(100)); // power register value, not used
self.txrx(ComState::GG_SOC.verb);
stats.soc = self.wait_txrx(ComState::LINK_READ.verb, Some(STD_TIMEOUT)) as u8;
self.txrx(ComState::GG_REMAINING.verb);
stats.remaining_capacity = self.wait_txrx(ComState::LINK_READ.verb, Some(STD_TIMEOUT));
stats
}
}
}
// a stub to try to avoid breaking hosted mode for as long as possible.
#[cfg(not(target_os = "none"))]
mod implementation {
use crate::api::BattStats;
pub struct XousCom {
}
@ -83,9 +142,18 @@ mod implementation {
}
}
pub fn txrx(tx: u16) -> u16 {
pub fn txrx(&mut self, _tx: u16) -> u16 {
0xDEAD as u16
}
pub fn get_battstats(&mut self) -> BattStats {
BattStats {
voltage: 3700,
current: -150,
soc: 50,
remaining_capacity: 750,
}
}
}
}
@ -113,6 +181,17 @@ fn xmain() -> ! {
info!("COM: power off called");
com.txrx(ComState::POWER_OFF.verb);
}
Opcode::BattStats => {
info!("COM: batt stats request received");
let stats = com.get_battstats();
let raw_stats: [usize; 2] = stats.into();
xous::return_scalar2(
envelope.sender,
raw_stats[1],
raw_stats[0]
).expect("COM: couldn't return batt stats request");
info!("COM: done returning batt stats request");
}
_ => error!("unknown opcode"),
}
} else {
@ -120,5 +199,3 @@ fn xmain() -> ! {
}
}
}
// xous::wait_event()

View file

@ -14,5 +14,5 @@ utralib = { path = "../../utralib"}
[features]
debugprint = []
default = []
#default = ["debugprint"]
#default = []
default = ["debugprint"]

View file

@ -12,6 +12,8 @@ use log::{error, info};
use xous::String;
use graphics_server::Point;
use graphics_server::GlyphSet;
use com::api::BattStats;
use com::*;
// fn print_and_yield(index: *mut usize) -> ! {
// let num = index as usize;
@ -148,8 +150,6 @@ fn shell_main() -> ! {
let screensize = graphics_server::screen_size(graphics_conn).expect("Couldn't get screen size");
// let mut counter: usize = 0;
let mut ls = logstr::LogStr::new();
let dark = graphics_server::Color::from(0);
let light = graphics_server::Color::from(!0);
let mut bouncyball = Bounce::new(14,
@ -157,8 +157,10 @@ fn shell_main() -> ! {
Point::new(screensize.x as _, screensize.y as i16 - 1)));
bouncyball.update();
let mut batt_stats: BattStats = BattStats::default();
#[cfg(baremetal)]
{
{ // use this to select which UART to monitor in the main loop
use utralib::generated::*;
let gpio_base = xous::syscall::map_memory(
xous::MemoryAddress::new(utra::gpio::HW_GPIO_BASE),
@ -183,40 +185,19 @@ fn shell_main() -> ! {
ticktimer_server::reset(ticktimer_conn).unwrap();
let mut string_buffer = String::new(4096);
loop {
// a message passing demo -- checking time
// update battery status periodically
if let Ok(elapsed_time) = ticktimer_server::elapsed_ms(ticktimer_conn) {
info!("SHELL: {}ms", elapsed_time);
if elapsed_time - last_time > 40 {
if elapsed_time - last_time > 500 {
last_time = elapsed_time;
/*
xous::try_send_message(log_conn,
xous::Message::Scalar(xous::ScalarMessage{id:256, arg1: elapsed_time as usize, arg2: 257, arg3: 258, arg4: 259}));
*/
info!("Preparing a mutable borrow message");
ls.clear();
write!(
ls,
"Hello, Server! This memory is borrowed from another process. Elapsed: {}",
elapsed_time as usize
)
.expect("couldn't send hello message");
let mm = ls
.as_memory_message(0)
.expect("couldn't form memory message");
info!("Sending a mutable borrow message");
xous::syscall::send_message(log_conn, xous::Message::MutableBorrow(mm))
.expect("couldn't send memory message");
batt_stats = get_batt_stats(com_conn).expect("Can't get battery stats from COM");
}
} else {
error!("error requesting ticktimer!")
}
string_buffer.clear();
write!(&mut string_buffer, "Uptime: {:.2}s", last_time as f32 / 1000f32).expect("Can't write");
write!(&mut string_buffer, "{}mV Uptime: {:.2}s", batt_stats.voltage, last_time as f32 / 1000f32).expect("Can't write");
graphics_server::set_glyph(graphics_conn, GlyphSet::Small).expect("unable to set glyph");
let (_, h) = graphics_server::query_glyph(graphics_conn).expect("unable to query glyph");
graphics_server::clear_region(graphics_conn, 0, 0, screensize.x as usize - 1, h)
@ -225,9 +206,6 @@ fn shell_main() -> ! {
graphics_server::draw_string(graphics_conn, &string_buffer).expect("unable to draw string");
// ticktimer_server::sleep_ms(ticktimer_conn, 500).expect("couldn't sleep");
if last_time > 10_000 { // after 10 seconds issue a shutdown command
com::power_off_soc(com_conn).expect("Couldn't issue powerdown command to COM");
}
// draw the ball
bouncyball.update();