mirror of
https://github.com/saymrwulf/xous-core.git
synced 2026-11-15 08:30:02 +00:00
Merge branch 'master' of github.com:betrusted-io/xous-core
This commit is contained in:
commit
be1687ffdd
16 changed files with 1578 additions and 453 deletions
92
Cargo.lock
generated
92
Cargo.lock
generated
|
|
@ -39,6 +39,18 @@ version = "1.0.33"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1fd36ffbb1fb7c834eac128ea8d0e310c5aeb635548f9d58861e1308d46e71c"
|
||||
|
||||
[[package]]
|
||||
name = "as-slice"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bb4d1c23475b74e3672afa8c2be22040b8b7783ad9b461021144ed10a46bb0e6"
|
||||
dependencies = [
|
||||
"generic-array 0.12.3",
|
||||
"generic-array 0.13.2",
|
||||
"generic-array 0.14.4",
|
||||
"stable_deref_trait",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "atty"
|
||||
version = "0.2.14"
|
||||
|
|
@ -214,15 +226,6 @@ version = "1.2.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650"
|
||||
|
||||
[[package]]
|
||||
name = "embedded-graphics"
|
||||
version = "0.6.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "40a69991ceb896bd4810a0cf2bcc46fc94b7860573c71f965d8e5b3d66942fed"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "env_logger"
|
||||
version = "0.7.1"
|
||||
|
|
@ -251,6 +254,34 @@ version = "0.1.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.12.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec"
|
||||
dependencies = [
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.13.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ed1e761351b56f54eb9dcd0cfaca9fd0daecf93918e1cfc01c8a3d26ee7adcd"
|
||||
dependencies = [
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.14.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817"
|
||||
dependencies = [
|
||||
"typenum",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.1.14"
|
||||
|
|
@ -279,6 +310,27 @@ dependencies = [
|
|||
"xous",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hash32"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d4041af86e63ac4298ce40e5cca669066e75b6f1aa3390fe2561ffa5e1d9f4cc"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "heapless"
|
||||
version = "0.5.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "74911a68a1658cfcfb61bc0ccfbd536e3b6e906f8c2f7883ee50157e3e2184f1"
|
||||
dependencies = [
|
||||
"as-slice",
|
||||
"generic-array 0.13.2",
|
||||
"hash32",
|
||||
"stable_deref_trait",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.1.15"
|
||||
|
|
@ -819,6 +871,12 @@ version = "1.4.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fbee7696b84bbf3d89a1c2eccff0850e3047ed46bfcd2e92c29a2d074d57e252"
|
||||
|
||||
[[package]]
|
||||
name = "stable_deref_trait"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.8.0"
|
||||
|
|
@ -890,7 +948,9 @@ dependencies = [
|
|||
name = "ticktimer-server"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"embedded-graphics",
|
||||
"heapless",
|
||||
"log",
|
||||
"log-server",
|
||||
"utralib",
|
||||
"xous",
|
||||
]
|
||||
|
|
@ -909,6 +969,12 @@ dependencies = [
|
|||
"xmas-elf",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.8"
|
||||
|
|
@ -934,6 +1000,12 @@ version = "0.8.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed"
|
||||
|
||||
[[package]]
|
||||
name = "void"
|
||||
version = "1.0.2"
|
||||
|
|
|
|||
101
buildpush.sh
101
buildpush.sh
|
|
@ -1,20 +1,61 @@
|
|||
#!/bin/sh
|
||||
#!/bin/bash
|
||||
|
||||
# argument 1 is the target for copy
|
||||
set -e # exit on any error
|
||||
|
||||
if [ -z "$1" ]
|
||||
then
|
||||
echo "Usage: $0 ssh-target [privatekey]"
|
||||
echo "Missing ssh-target argument."
|
||||
echo "Assumes betrusted-scripts repo is cloned on ssh-target at ~/code/betrused-scripts/"
|
||||
exit 0
|
||||
fi
|
||||
UPDATE_FPGA=1
|
||||
UPDATE_KERNEL=1
|
||||
USE_USB=1
|
||||
FPGA_IMAGE=../betrusted-soc/build/gateware/encrypted.bin
|
||||
KERNEL_IMAGE=target/riscv32imac-unknown-none-elf/release/xous.img
|
||||
CSR_CSV=../betrusted-soc/build/csr.csv.1
|
||||
USE_IDENITY=0
|
||||
|
||||
# notes:
|
||||
# xous-stage1.bin written to 0x2050_0000 (64k erase block size)
|
||||
# xous-kernel.bin written to 0x2051_0000 => passed as a0 arg to xous-stage1.bin
|
||||
# This is handled in part by betrusted-scripts, with provision-xous.sh
|
||||
# stage1 and kernel are merged into xous.img by this script.
|
||||
POSITIONAL=()
|
||||
while [[ $# -gt 0 ]]
|
||||
do
|
||||
key="$1"
|
||||
case $key in
|
||||
-k|--kernel-skip)
|
||||
UPDATE_KERNEL=0
|
||||
shift
|
||||
;;
|
||||
-f|--fpga-skip)
|
||||
UPDATE_FPGA=0
|
||||
shift
|
||||
;;
|
||||
-c|--copy-to)
|
||||
DEST_HOST=$2
|
||||
USE_USB=0
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
-i|--identity)
|
||||
USE_IDENTITY=1
|
||||
IDENTITY=$2
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
--current-csr)
|
||||
CSR_CSV=../betrusted-soc/build/csr.csv
|
||||
shift
|
||||
;;
|
||||
-h|--help)
|
||||
echo "$0 provisions betrusted. --kernel-skip skips the kernel, --fpga-skip skips the FPGA. --current-csr indicates to use the CSR for the new FPGA image to do the update (normally you want to use the one corresponding to the older, currently installed version)."
|
||||
echo "Alternatively, using --copy-to <hostname> copies the files to a remote host and skips provisioning."
|
||||
echo " --identity <id_file> supplies an identity file to the scp command."
|
||||
echo " Copying assumes betrusted-scripts repo is cloned on ssh-target at ~/code/betrused-scripts/"
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
POSITIONAL+=("$1")
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
set -- "${POSITIONAL[@]}"
|
||||
|
||||
DESTDIR=code/precursors
|
||||
|
||||
cargo xtask hw-image ../betrusted-soc/build/software/soc.svd
|
||||
|
||||
|
|
@ -24,19 +65,29 @@ then
|
|||
exit 1
|
||||
fi
|
||||
|
||||
echo "Copying to target..."
|
||||
if [ $# -gt 0 ]
|
||||
# case of no private key specified
|
||||
if [ $USE_USB -eq 1 ]
|
||||
then
|
||||
if [ -z "$2" ]
|
||||
if [ $UPDATE_FPGA -eq 1 ]
|
||||
then
|
||||
scp target/riscv32imac-unknown-none-elf/release/xous.img $1:code/betrusted-scripts/
|
||||
scp ../betrusted-soc/build/gateware/encrypted.bin $1:code/betrusted-scripts/
|
||||
scp ../betrusted-soc/build/csr.csv $1:code/betrusted-scripts/soc-csr.csv
|
||||
else
|
||||
scp -i $2 target/riscv32imac-unknown-none-elf/release/xous.img $1:code/betrusted-scripts/
|
||||
scp -i $2 ../betrusted-soc/build/gateware/encrypted.bin $1:code/betrusted-scripts/
|
||||
scp -i $2 ../betrusted-soc/build/csr.csv $1:code/betrusted-scripts/soc-csr.csv
|
||||
echo "Burning FPGA image"
|
||||
sudo wishbone-tool --csr-csv $CSR_CSV --load-name $FPGA_IMAGE --load-address 0x0 --load-flash
|
||||
echo "*** Manual power cycle required to reload SoC FPGA configuration ***"
|
||||
echo " -> Either issue a power cycle command, or insert paper clip in the hole on the right hand side!"
|
||||
fi
|
||||
if [ $UPDATE_KERNEL -eq 1 ]
|
||||
then
|
||||
echo "Burning firmware"
|
||||
sudo wishbone-tool --csr-csv $CSR_CSV --load-name $KERNEL_IMAGE --load-address 0x500000 --load-flash
|
||||
fi
|
||||
else
|
||||
echo "Copy to target with $0 <user@host> <ssh-id>"
|
||||
if [ $USE_IDENTITY -eq 1 ]
|
||||
then
|
||||
# there is a private key
|
||||
scp -i $IDENTITY $KERNEL_IMAGE $FPGA_IMAGE $DEST_HOST:$DESTDIR/
|
||||
scp -i $IDENTITY $CSR_CSV $DEST_HOST:$DESTDIR/soc-csr.csv
|
||||
else
|
||||
scp $KERNEL_IMAGE $FPGA_IMAGE $CSR_CSV $DEST_HOST:$DESTDIR/
|
||||
scp $CSR_CSV $DEST_HOST:$DESTDIR/soc-csr.csv
|
||||
fi
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -21,7 +21,8 @@ riscv = "0.5.6"
|
|||
debug-print = []
|
||||
print-panics = []
|
||||
report-memory = ["stats_alloc"]
|
||||
default = ["print-panics", "debug-print"]
|
||||
#default = ["print-panics", "debug-print"]
|
||||
default = []
|
||||
|
||||
[target.'cfg(any(windows, unix))'.dependencies]
|
||||
lazy_static = "1.4"
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ impl Uart {
|
|||
#[allow(dead_code)]
|
||||
pub fn enable_rx(self) {
|
||||
let mut uart_csr = CSR::new(self.base as *mut u32);
|
||||
uart_csr.wfo(utra::uart::EV_ENABLE_ENABLE, uart_csr.rf(utra::uart::EV_ENABLE_ENABLE) | 2);
|
||||
uart_csr.rmwf(utra::uart::EV_ENABLE_RX, 1);
|
||||
}
|
||||
|
||||
pub fn putc(&self, c: u8) {
|
||||
|
|
@ -68,7 +68,7 @@ impl Uart {
|
|||
let mut uart_csr = CSR::new(self.base as *mut u32);
|
||||
// If EV_PENDING_RX is 1, return the pending character.
|
||||
// Otherwise, return None.
|
||||
match uart_csr.r(utra::uart::EV_PENDING) & 2 {
|
||||
match uart_csr.rf(utra::uart::EV_PENDING_RX) {
|
||||
0 => None,
|
||||
ack => {
|
||||
let c = Some(uart_csr.r(utra::uart::RXTX) as u8);
|
||||
|
|
|
|||
|
|
@ -14,7 +14,8 @@ rand = "0.7.3"
|
|||
[features]
|
||||
debug-print = []
|
||||
earlyprintk = []
|
||||
default = ["debug-print"]
|
||||
#default = ["debug-print"]
|
||||
default = []
|
||||
|
||||
[profile.release]
|
||||
codegen-units = 1 # 1 better optimizations
|
||||
|
|
|
|||
|
|
@ -1,15 +1,497 @@
|
|||
use crate::op::PixelColor;
|
||||
use xous::{Message, ScalarMessage};
|
||||
use core::ops::{Add, AddAssign, Index, Neg, Sub, SubAssign};
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
/// 2D size.
|
||||
///
|
||||
/// `Size` is used to define the width and height of an object.
|
||||
///
|
||||
/// [Nalgebra] support can be enabled with the `nalgebra_support` feature. This implements
|
||||
/// `From<Vector2<N>>` and `From<&Vector2<N>>` where `N` is `Scalar + Into<u16>`. This allows use
|
||||
/// of Nalgebra's [`Vector2`] with embedded-graphics where `u16`, `u16` or `u8` is used for value
|
||||
/// storage.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ## Create a `Size` from two integers
|
||||
///
|
||||
///
|
||||
/// ```rust
|
||||
/// use embedded_graphics::geometry::Size;
|
||||
///
|
||||
/// // Create a size using the `new` constructor method
|
||||
/// let s = Size::new(10, 20);
|
||||
/// ```
|
||||
///
|
||||
/// ## Create a `Size` from a Nalgebra `Vector2`
|
||||
///
|
||||
/// _Be sure to enable the `nalgebra_support` feature to get [Nalgebra] integration._
|
||||
///
|
||||
/// Any `Vector2<N>` can be used where `N: Into<u16> + nalgebra::Scalar`. This includes the primitive types `u16`, `u16` and `u8`.
|
||||
///
|
||||
/// ```rust
|
||||
/// # #[cfg(feature = "nalgebra_support")] {
|
||||
/// use nalgebra::Vector2;
|
||||
/// use embedded_graphics::geometry::Size;
|
||||
///
|
||||
/// assert_eq!(Size::from(Vector2::new(10u16, 20)), Size::new(10u16, 20));
|
||||
/// assert_eq!(Size::from(Vector2::new(10u16, 20)), Size::new(10u16, 20));
|
||||
/// assert_eq!(Size::from(Vector2::new(10u8, 20)), Size::new(10u16, 20));
|
||||
/// # }
|
||||
/// ```
|
||||
///
|
||||
/// `.into()` can also be used, but may require more type annotations:
|
||||
///
|
||||
/// ```rust
|
||||
/// # #[cfg(feature = "nalgebra_support")] {
|
||||
/// use nalgebra::Vector2;
|
||||
/// use embedded_graphics::geometry::Size;
|
||||
///
|
||||
/// let c: Size = Vector2::new(10u16, 20).into();
|
||||
///
|
||||
/// assert_eq!(c, Size::new(10u16, 20));
|
||||
/// # }
|
||||
/// ```
|
||||
///
|
||||
/// [`Drawable`]: ../drawable/trait.Drawable.html
|
||||
/// [`Point`]: struct.Point.html
|
||||
/// [`Vector2<N>`]: https://docs.rs/nalgebra/0.18.0/nalgebra/base/type.Vector2.html
|
||||
/// [`Vector2`]: https://docs.rs/nalgebra/0.18.0/nalgebra/base/type.Vector2.html
|
||||
/// [Nalgebra]: https://docs.rs/nalgebra
|
||||
#[derive(Debug, Default, Copy, Clone, Eq, PartialEq)]
|
||||
pub struct Size {
|
||||
/// The width.
|
||||
pub width: u16,
|
||||
|
||||
/// The height.
|
||||
pub height: u16,
|
||||
}
|
||||
|
||||
impl Size {
|
||||
/// Creates a size from a width and a height.
|
||||
pub const fn new(width: u16, height: u16) -> Self {
|
||||
Size { width, height }
|
||||
}
|
||||
|
||||
/// Creates a size with width and height equal to zero.
|
||||
pub const fn zero() -> Self {
|
||||
Size {
|
||||
width: 0,
|
||||
height: 0,
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a size from two corner points of a bounding box.
|
||||
pub(crate) fn from_bounding_box(corner_1: Point, corner_2: Point) -> Self {
|
||||
let width = (corner_1.x - corner_2.x).abs() as u16;
|
||||
let height = (corner_1.y - corner_2.y).abs() as u16;
|
||||
|
||||
Self { width, height }
|
||||
}
|
||||
}
|
||||
|
||||
impl Add for Size {
|
||||
type Output = Size;
|
||||
|
||||
fn add(self, other: Size) -> Size {
|
||||
Size::new(self.width + other.width, self.height + other.height)
|
||||
}
|
||||
}
|
||||
|
||||
impl AddAssign for Size {
|
||||
fn add_assign(&mut self, other: Size) {
|
||||
self.width += other.width;
|
||||
self.height += other.height;
|
||||
}
|
||||
}
|
||||
|
||||
impl Sub for Size {
|
||||
type Output = Size;
|
||||
|
||||
fn sub(self, other: Size) -> Size {
|
||||
Size::new(self.width - other.width, self.height - other.height)
|
||||
}
|
||||
}
|
||||
|
||||
impl SubAssign for Size {
|
||||
fn sub_assign(&mut self, other: Size) {
|
||||
self.width -= other.width;
|
||||
self.height -= other.height;
|
||||
}
|
||||
}
|
||||
|
||||
impl Index<usize> for Size {
|
||||
type Output = u16;
|
||||
|
||||
fn index(&self, idx: usize) -> &u16 {
|
||||
match idx {
|
||||
0 => &self.width,
|
||||
1 => &self.height,
|
||||
_ => panic!("index out of bounds: the len is 2 but the index is {}", idx),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<(u16, u16)> for Size {
|
||||
fn from(other: (u16, u16)) -> Self {
|
||||
Size::new(other.0, other.1)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<[u16; 2]> for Size {
|
||||
fn from(other: [u16; 2]) -> Self {
|
||||
Size::new(other[0], other[1])
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&[u16; 2]> for Size {
|
||||
fn from(other: &[u16; 2]) -> Self {
|
||||
Size::new(other[0], other[1])
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Size> for (u16, u16) {
|
||||
fn from(other: Size) -> (u16, u16) {
|
||||
(other.width, other.height)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&Size> for (u16, u16) {
|
||||
fn from(other: &Size) -> (u16, u16) {
|
||||
(other.width, other.height)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "nalgebra_support")]
|
||||
use nalgebra::{base::Scalar, Vector2};
|
||||
|
||||
#[cfg(feature = "nalgebra_support")]
|
||||
impl<N> From<Vector2<N>> for Size
|
||||
where
|
||||
N: Into<u16> + Scalar,
|
||||
{
|
||||
fn from(other: Vector2<N>) -> Self {
|
||||
Self::new(other[0].into(), other[1].into())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "nalgebra_support")]
|
||||
impl<N> From<&Vector2<N>> for Size
|
||||
where
|
||||
N: Into<u16> + Scalar,
|
||||
{
|
||||
fn from(other: &Vector2<N>) -> Self {
|
||||
Self::new(other[0].into(), other[1].into())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn sizes_can_be_added() {
|
||||
let left = Size::new(10, 20);
|
||||
let right = Size::new(30, 40);
|
||||
|
||||
assert_eq!(left + right, Size::new(40, 60));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sizes_can_be_subtracted() {
|
||||
let left = Size::new(30, 40);
|
||||
let right = Size::new(10, 20);
|
||||
|
||||
assert_eq!(left - right, Size::new(20, 20));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn from_tuple() {
|
||||
assert_eq!(Size::from((20, 30)), Size::new(20, 30));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn from_array() {
|
||||
assert_eq!(Size::from([20, 30]), Size::new(20, 30));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn from_array_ref() {
|
||||
assert_eq!(Size::from(&[20, 30]), Size::new(20, 30));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn index() {
|
||||
let size = Size::new(1, 2);
|
||||
|
||||
assert_eq!(size.width, size[0]);
|
||||
assert_eq!(size.height, size[1]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn index_out_of_bounds() {
|
||||
let size = Size::new(1, 2);
|
||||
let _ = size[2];
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "nalgebra_support")]
|
||||
fn nalgebra_support() {
|
||||
let left = nalgebra::Vector2::new(30u16, 40);
|
||||
let right = nalgebra::Vector2::new(10, 20);
|
||||
|
||||
assert_eq!(Size::from(left - right), Size::new(20, 20));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// Style properties for an object
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct Style {
|
||||
/// Fill colour of the object
|
||||
///
|
||||
/// For fonts, this is the background colour of the text
|
||||
pub fill_color: Option<PixelColor>,
|
||||
|
||||
/// Stroke (border/line) color of the object
|
||||
///
|
||||
/// For fonts, this is the foreground colour of the text
|
||||
pub stroke_color: Option<PixelColor>,
|
||||
|
||||
/// Stroke width
|
||||
///
|
||||
/// Set the stroke width for an object. Has no effect on fonts.
|
||||
pub stroke_width: i16,
|
||||
}
|
||||
|
||||
impl Style
|
||||
{
|
||||
/// Create a new style with a given stroke value and defaults for everything else
|
||||
pub fn stroke_color(stroke_color: PixelColor) -> Self {
|
||||
Self {
|
||||
stroke_color: Some(stroke_color),
|
||||
..Style::default()
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the stroke width as an `i16`.
|
||||
///
|
||||
/// If the stroke width is too large to fit into an `i16` the maximum value
|
||||
/// for an `i16` is returned instead.
|
||||
pub(crate) fn stroke_width_i16(&self) -> i16 {
|
||||
self.stroke_width
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Style
|
||||
{
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
fill_color: None,
|
||||
stroke_color: None,
|
||||
stroke_width: 1,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Add a style to an object
|
||||
pub trait WithStyle
|
||||
{
|
||||
/// Add a complete style to the object
|
||||
fn style(self, style: Style) -> Self;
|
||||
|
||||
/// Set the stroke colour for the object
|
||||
///
|
||||
/// This can be a noop
|
||||
fn stroke_color(self, color: Option<PixelColor>) -> Self;
|
||||
|
||||
/// Set the stroke width for the object
|
||||
///
|
||||
/// A stroke with a width of zero will not be rendered
|
||||
fn stroke_width(self, width: u16) -> Self;
|
||||
|
||||
/// Set the fill property of the object's style
|
||||
///
|
||||
/// This can be a noop
|
||||
fn fill_color(self, color: Option<PixelColor>) -> Self;
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
pub struct Point {
|
||||
pub x: u16,
|
||||
pub y: u16,
|
||||
pub x: i16,
|
||||
pub y: i16,
|
||||
}
|
||||
|
||||
impl Point {
|
||||
pub fn new(x: u16, y: u16) -> Point {
|
||||
pub fn new(x: i16, y: i16) -> Point {
|
||||
Point { x, y }
|
||||
}
|
||||
|
||||
/// Creates a point with X and Y equal to zero.
|
||||
pub const fn zero() -> Self {
|
||||
Point { x: 0, y: 0 }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl Add for Point {
|
||||
type Output = Point;
|
||||
|
||||
fn add(self, other: Point) -> Point {
|
||||
Point::new(self.x + other.x, self.y + other.y)
|
||||
}
|
||||
}
|
||||
|
||||
impl Add<Size> for Point {
|
||||
type Output = Point;
|
||||
|
||||
/// Offsets a point by adding a size.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function will panic if `width` or `height` are too large to be represented as an `i16`
|
||||
/// and debug assertions are enabled.
|
||||
fn add(self, other: Size) -> Point {
|
||||
let width = other.width as i16;
|
||||
let height = other.height as i16;
|
||||
|
||||
debug_assert!(width >= 0, "width is too large");
|
||||
debug_assert!(height >= 0, "height is too large");
|
||||
|
||||
Point::new(self.x + width, self.y + height)
|
||||
}
|
||||
}
|
||||
|
||||
impl AddAssign for Point {
|
||||
fn add_assign(&mut self, other: Point) {
|
||||
self.x += other.x;
|
||||
self.y += other.y;
|
||||
}
|
||||
}
|
||||
|
||||
impl AddAssign<Size> for Point {
|
||||
/// Offsets a point by adding a size.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function will panic if `width` or `height` are too large to be represented as an `i16`
|
||||
/// and debug assertions are enabled.
|
||||
fn add_assign(&mut self, other: Size) {
|
||||
let width = other.width as i16;
|
||||
let height = other.height as i16;
|
||||
|
||||
debug_assert!(width >= 0, "width is too large");
|
||||
debug_assert!(height >= 0, "height is too large");
|
||||
|
||||
self.x += width;
|
||||
self.y += height;
|
||||
}
|
||||
}
|
||||
|
||||
impl Sub for Point {
|
||||
type Output = Point;
|
||||
|
||||
fn sub(self, other: Point) -> Point {
|
||||
Point::new(self.x - other.x, self.y - other.y)
|
||||
}
|
||||
}
|
||||
|
||||
impl Sub<Size> for Point {
|
||||
type Output = Point;
|
||||
|
||||
/// Offsets a point by subtracting a size.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function will panic if `width` or `height` are too large to be represented as an `i16`
|
||||
/// and debug assertions are enabled.
|
||||
fn sub(self, other: Size) -> Point {
|
||||
let width = other.width as i16;
|
||||
let height = other.height as i16;
|
||||
|
||||
debug_assert!(width >= 0, "width is too large");
|
||||
debug_assert!(height >= 0, "height is too large");
|
||||
|
||||
Point::new(self.x - width, self.y - height)
|
||||
}
|
||||
}
|
||||
|
||||
impl SubAssign for Point {
|
||||
fn sub_assign(&mut self, other: Point) {
|
||||
self.x -= other.x;
|
||||
self.y -= other.y;
|
||||
}
|
||||
}
|
||||
|
||||
impl SubAssign<Size> for Point {
|
||||
/// Offsets a point by subtracting a size.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function will panic if `width` or `height` are too large to be represented as an `i16`
|
||||
/// and debug assertions are enabled.
|
||||
fn sub_assign(&mut self, other: Size) {
|
||||
let width = other.width as i16;
|
||||
let height = other.height as i16;
|
||||
|
||||
debug_assert!(width >= 0, "width is too large");
|
||||
debug_assert!(height >= 0, "height is too large");
|
||||
|
||||
self.x -= width;
|
||||
self.y -= height;
|
||||
}
|
||||
}
|
||||
|
||||
impl Index<usize> for Point {
|
||||
type Output = i16;
|
||||
|
||||
fn index(&self, idx: usize) -> &i16 {
|
||||
match idx {
|
||||
0 => &self.x,
|
||||
1 => &self.y,
|
||||
_ => panic!("index out of bounds: the len is 2 but the index is {}", idx),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Neg for Point {
|
||||
type Output = Point;
|
||||
|
||||
fn neg(self) -> Self::Output {
|
||||
Point::new(-self.x, -self.y)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<(i16, i16)> for Point {
|
||||
fn from(other: (i16, i16)) -> Self {
|
||||
Point::new(other.0, other.1)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<[i16; 2]> for Point {
|
||||
fn from(other: [i16; 2]) -> Self {
|
||||
Point::new(other[0], other[1])
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&[i16; 2]> for Point {
|
||||
fn from(other: &[i16; 2]) -> Self {
|
||||
Point::new(other[0], other[1])
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Point> for (i16, i16) {
|
||||
fn from(other: Point) -> (i16, i16) {
|
||||
(other.x, other.y)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&Point> for (i16, i16) {
|
||||
fn from(other: &Point) -> (i16, i16) {
|
||||
(other.x, other.y)
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<usize> for Point {
|
||||
|
|
@ -18,16 +500,20 @@ impl Into<usize> for Point {
|
|||
}
|
||||
}
|
||||
|
||||
/// A single pixel
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
pub struct Pixel(pub Point, pub PixelColor);
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct Rect {
|
||||
pub x0: u16,
|
||||
pub y0: u16,
|
||||
pub x1: u16,
|
||||
pub y1: u16,
|
||||
pub x0: i16,
|
||||
pub y0: i16,
|
||||
pub x1: i16,
|
||||
pub y1: i16,
|
||||
}
|
||||
|
||||
impl Rect {
|
||||
pub fn new(x0: u16, y0: u16, x1: u16, y1: u16) -> Self {
|
||||
pub fn new(x0: i16, y0: i16, x1: i16, y1: i16) -> Self {
|
||||
Self { x0, y0, x1, y1 }
|
||||
}
|
||||
}
|
||||
|
|
@ -49,7 +535,7 @@ impl From<usize> for Point {
|
|||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct Color {
|
||||
pub color: u32,
|
||||
pub color: u16,
|
||||
}
|
||||
|
||||
impl From<usize> for Color {
|
||||
|
|
@ -58,6 +544,18 @@ impl From<usize> for Color {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct Rectangle {
|
||||
/// Top left point of the rect
|
||||
pub top_left: Point,
|
||||
|
||||
/// Bottom right point of the rect
|
||||
pub bottom_right: Point,
|
||||
|
||||
/// Object style
|
||||
pub style: PixelColor,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Opcode<'a> {
|
||||
/// Flush the buffer to the screen
|
||||
|
|
@ -73,11 +571,11 @@ pub enum Opcode<'a> {
|
|||
Rectangle(Point /* upper-left */, Point /* lower-right */),
|
||||
|
||||
/// Draw a circle with a specified radius
|
||||
Circle(Point, u32 /* radius */),
|
||||
Circle(Point, u16 /* radius */),
|
||||
|
||||
/// Change the style of the current pen
|
||||
Style(
|
||||
u32, /* stroke width */
|
||||
u16, /* stroke width */
|
||||
Color, /* stroke color */
|
||||
Color, /* fill color */
|
||||
),
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ impl Uart {
|
|||
pub fn enable_rx(&self) {
|
||||
if cfg!(feature = "debugprint") {
|
||||
let mut uart_csr = CSR::new(unsafe{DEFAULT_UART_ADDR as *mut u32});
|
||||
uart_csr.wfo(utra::uart::EV_ENABLE_ENABLE, uart_csr.rf(utra::uart::EV_ENABLE_ENABLE) | 2 );
|
||||
uart_csr.rmwf(utra::uart::EV_ENABLE_RX, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -89,7 +89,7 @@ impl Uart {
|
|||
self.map_uart();
|
||||
}
|
||||
let mut uart_csr = CSR::new(unsafe{DEFAULT_UART_ADDR as *mut u32});
|
||||
match uart_csr.rf(utra::uart::EV_PENDING_PENDING) & 2 {
|
||||
match uart_csr.rf(utra::uart::EV_PENDING_RX) {
|
||||
0 => None,
|
||||
ack => {
|
||||
let c = Some(uart_csr.rf(utra::uart::RXTX_RXTX) as u8);
|
||||
|
|
|
|||
|
|
@ -1,8 +1,11 @@
|
|||
#![cfg_attr(target_os = "none", no_std)]
|
||||
|
||||
// pub mod size;
|
||||
pub mod api;
|
||||
pub use api::{Point, Color, Rect};
|
||||
use xous::String;
|
||||
pub mod op;
|
||||
pub mod fonts;
|
||||
|
||||
use xous::{send_message, CID};
|
||||
|
||||
|
|
@ -10,7 +13,7 @@ pub fn draw_line(cid: CID, start: Point, end: Point) -> Result<(), xous::Error>
|
|||
send_message(cid, api::Opcode::Line(start, end).into()).map(|_| ())
|
||||
}
|
||||
|
||||
pub fn draw_circle(cid: CID, center: Point, radius: u32) -> Result<(), xous::Error> {
|
||||
pub fn draw_circle(cid: CID, center: Point, radius: u16) -> Result<(), xous::Error> {
|
||||
send_message(cid, api::Opcode::Circle(center, radius).into()).map(|_| ())
|
||||
}
|
||||
|
||||
|
|
@ -18,7 +21,7 @@ pub fn draw_rectangle(cid: CID, start: Point, end: Point) -> Result<(), xous::Er
|
|||
send_message(cid, api::Opcode::Rectangle(start, end).into()).map(|_| ())
|
||||
}
|
||||
|
||||
pub fn set_style(cid: CID, width: u32, stroke: Color, fill: Color) -> Result<(), xous::Error> {
|
||||
pub fn set_style(cid: CID, width: u16, stroke: Color, fill: Color) -> Result<(), xous::Error> {
|
||||
send_message(cid, api::Opcode::Style(width, stroke, fill).into()).map(|_| ())
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -56,7 +56,6 @@ fn xmain() -> ! {
|
|||
Opcode::Line(start, end) => {
|
||||
info!("GFX: Drawing line from {:?} to {:?}", start, end);
|
||||
op::line(display.native_buffer(), start.x as _, start.y as _, end.x as _, end.y as _, if current_color.color == 0 { op::PixelColor::Off } else {op::PixelColor::On });
|
||||
// todo!();
|
||||
}
|
||||
Opcode::Rectangle(start, end) => {
|
||||
todo!();
|
||||
|
|
@ -66,11 +65,8 @@ fn xmain() -> ! {
|
|||
// .ok();
|
||||
}
|
||||
Opcode::Circle(mid, radius) => {
|
||||
todo!();
|
||||
// Circle::new(mid.into(), radius)
|
||||
// .into_styled(current_style)
|
||||
// .draw(&mut display)
|
||||
// .unwrap();
|
||||
info!("GFX: Drawing cicrle at {:?} radius {:?}", mid, radius);
|
||||
op::circle(display.native_buffer(), mid.x as _, mid.y as _, radius as _, 0, op::PixelColor::On);
|
||||
}
|
||||
Opcode::Style(stroke_width, stroke_color, fill_color) => {
|
||||
current_color = stroke_color;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use super::fonts;
|
||||
use super::fonts::{Font, GlyphHeader};
|
||||
use crate::api::{Point, Style, Pixel};
|
||||
|
||||
/// LCD Frame buffer bounds
|
||||
pub const LCD_WORDS_PER_LINE: usize = 11;
|
||||
|
|
@ -10,7 +11,7 @@ pub const LCD_FRAME_BUF_SIZE: usize = LCD_WORDS_PER_LINE * LCD_LINES;
|
|||
const WIDTH: usize = 336;
|
||||
const HEIGHT: usize = 536;
|
||||
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
pub enum PixelColor {
|
||||
On,
|
||||
Off,
|
||||
|
|
@ -338,6 +339,86 @@ pub fn line(fb: &mut LcdFB, x0: usize, y0: usize, x1: usize, y1: usize, color: P
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/// Pixel iterator for each pixel in the circle border
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct CircleIterator {
|
||||
center: Point,
|
||||
radius: u16,
|
||||
style: Style,
|
||||
p: Point,
|
||||
}
|
||||
|
||||
impl Iterator for CircleIterator
|
||||
{
|
||||
type Item = Pixel;
|
||||
|
||||
// https://stackoverflow.com/questions/1201200/fast-algorithm-for-drawing-filled-circles
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
// If border or stroke colour is `None`, treat entire object as transparent and exit early
|
||||
if self.style.stroke_color.is_none() && self.style.fill_color.is_none() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let radius = self.radius as i16 - self.style.stroke_width_i16() + 1;
|
||||
let outer_radius = self.radius as i16;
|
||||
|
||||
let radius_sq = radius * radius;
|
||||
let outer_radius_sq = outer_radius * outer_radius;
|
||||
|
||||
loop {
|
||||
let t = self.p;
|
||||
let len = t.x * t.x + t.y * t.y;
|
||||
|
||||
let is_border = len > radius_sq - radius && len < outer_radius_sq + radius;
|
||||
|
||||
let is_fill = len <= outer_radius_sq + 1;
|
||||
|
||||
let item = if is_border && self.style.stroke_color.is_some() {
|
||||
Some(Pixel(
|
||||
self.center + t,
|
||||
self.style.stroke_color.expect("Border color not defined"),
|
||||
))
|
||||
} else if is_fill && self.style.fill_color.is_some() {
|
||||
Some(Pixel(
|
||||
self.center + t,
|
||||
self.style.fill_color.expect("Fill color not defined"),
|
||||
))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
self.p.x += 1;
|
||||
|
||||
if self.p.x > self.radius as i16 {
|
||||
self.p.x = -(self.radius as i16);
|
||||
self.p.y += 1;
|
||||
}
|
||||
|
||||
if self.p.y > self.radius as i16 {
|
||||
break None;
|
||||
}
|
||||
|
||||
if item.is_some() {
|
||||
break item;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn circle(fb: &mut LcdFB, x: usize, y: usize, r: usize, stroke_width: usize, color: PixelColor) {
|
||||
let c = CircleIterator {
|
||||
center: Point{x: x as i16, y: y as i16},
|
||||
radius: r as u16,
|
||||
style: Style{ fill_color: Some(color), stroke_color: Some(color), stroke_width: stroke_width as i16},
|
||||
p: Point::new(-(r as i16), -(r as i16)),
|
||||
};
|
||||
|
||||
for pixel in c {
|
||||
put_pixel(fb, pixel.0.x as usize, pixel.0.y as usize, pixel.1);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::fonts;
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ impl Uart {
|
|||
|
||||
pub fn enable_rx(&self) {
|
||||
let mut uart_csr = CSR::new(unsafe{DEFAULT_UART_ADDR as *mut u32});
|
||||
uart_csr.wfo(utra::uart::EV_ENABLE_ENABLE, uart_csr.rf(utra::uart::EV_ENABLE_ENABLE) | 2 );
|
||||
uart_csr.rmwf(utra::uart::EV_ENABLE_RX, 1 );
|
||||
}
|
||||
|
||||
pub fn getc(&self) -> Option<u8> {
|
||||
|
|
@ -84,7 +84,7 @@ impl Uart {
|
|||
self.map_uart();
|
||||
}
|
||||
let mut uart_csr = CSR::new(unsafe{DEFAULT_UART_ADDR as *mut u32});
|
||||
match uart_csr.rf(utra::uart::EV_PENDING_PENDING) & 2 {
|
||||
match uart_csr.rf(utra::uart::EV_PENDING_RX) {
|
||||
0 => None,
|
||||
ack => {
|
||||
let c = Some(uart_csr.rf(utra::uart::RXTX_RXTX) as u8);
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ impl Uart {
|
|||
pub fn enable_rx(&self) {
|
||||
if cfg!(feature = "debugprint") {
|
||||
let mut uart_csr = CSR::new(unsafe{DEFAULT_UART_ADDR as *mut u32});
|
||||
uart_csr.wfo(utra::uart::EV_ENABLE_ENABLE, uart_csr.rf(utra::uart::EV_ENABLE_ENABLE) | 2 );
|
||||
uart_csr.rmwf(utra::uart::EV_ENABLE_RX, 1 );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -89,7 +89,7 @@ impl Uart {
|
|||
self.map_uart();
|
||||
}
|
||||
let mut uart_csr = CSR::new(unsafe{DEFAULT_UART_ADDR as *mut u32});
|
||||
match uart_csr.rf(utra::uart::EV_PENDING_PENDING) & 2 {
|
||||
match uart_csr.rf(utra::uart::EV_PENDING_RX) {
|
||||
0 => None,
|
||||
ack => {
|
||||
let c = Some(uart_csr.rf(utra::uart::RXTX_RXTX) as u8);
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ mod timer;
|
|||
use core::fmt::Write;
|
||||
use log::{error, info};
|
||||
use xous::String;
|
||||
use graphics_server::Point;
|
||||
|
||||
// fn print_and_yield(index: *mut usize) -> ! {
|
||||
// let num = index as usize;
|
||||
|
|
@ -19,6 +20,29 @@ use xous::String;
|
|||
// }
|
||||
// }
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct Rectangle {
|
||||
/// Top left point of the rect
|
||||
pub top_left: Point,
|
||||
/// Bottom right point of the rect
|
||||
pub bottom_right: Point,
|
||||
}
|
||||
|
||||
impl Rectangle {
|
||||
pub fn top_left(&self) -> Point {
|
||||
self.top_left
|
||||
}
|
||||
pub fn bottom_right(&self) -> Point {
|
||||
self.bottom_right
|
||||
}
|
||||
pub fn new(top_left: Point, bottom_right: Point) -> Self {
|
||||
Rectangle {
|
||||
top_left,
|
||||
bottom_right,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(baremetal)]
|
||||
use utralib::generated::*;
|
||||
|
||||
|
|
@ -38,11 +62,72 @@ fn ensure_connection(server: xous::SID) -> xous::CID {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct Bounce {
|
||||
vector: Point,
|
||||
radius: u16,
|
||||
bounds: Rectangle,
|
||||
loc: Point,
|
||||
lfsr: u32,
|
||||
}
|
||||
|
||||
impl Bounce {
|
||||
pub fn new(radius: u16, bounds: Rectangle) -> Bounce {
|
||||
Bounce {
|
||||
vector: Point::new(2,3),
|
||||
radius: radius,
|
||||
bounds: bounds,
|
||||
loc: Point::new((bounds.bottom_right.x - bounds.top_left.x)/2, (bounds.bottom_right.y - bounds.top_left.y)/2),
|
||||
lfsr: 0xace1u32,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn next_rand(&mut self) -> i16 {
|
||||
let ret = move_lfsr(self.lfsr);
|
||||
self.lfsr = ret;
|
||||
|
||||
(ret % 8) as i16
|
||||
}
|
||||
|
||||
pub fn update(&mut self) -> &mut Self {
|
||||
let mut x: i16;
|
||||
let mut y: i16;
|
||||
// update the new ball location
|
||||
x = self.loc.x + self.vector.x; y = self.loc.y + self.vector.y;
|
||||
|
||||
let r: i16 = self.radius as i16;
|
||||
if (x >= (self.bounds.bottom_right().x - r)) ||
|
||||
(x <= (self.bounds.top_left().x + r)) ||
|
||||
(y >= (self.bounds.bottom_right().y - r)) ||
|
||||
(y <= (self.bounds.top_left().y + r)) {
|
||||
if x >= (self.bounds.bottom_right().x - r - 1) {
|
||||
self.vector.x = -self.next_rand();
|
||||
x = self.bounds.bottom_right().x - r;
|
||||
}
|
||||
if x <= self.bounds.top_left().x + r + 1 {
|
||||
self.vector.x = self.next_rand();
|
||||
x = self.bounds.top_left().x + r;
|
||||
}
|
||||
if y >= (self.bounds.bottom_right().y - r - 1) {
|
||||
self.vector.y = -self.next_rand();
|
||||
y = self.bounds.bottom_right().y - r;
|
||||
}
|
||||
if y <= (self.bounds.top_left().y + r + 1) {
|
||||
self.vector.y = self.next_rand();
|
||||
y = self.bounds.top_left().y + r;
|
||||
}
|
||||
}
|
||||
|
||||
self.loc.x = x;
|
||||
self.loc.y = y;
|
||||
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[xous::xous_main]
|
||||
fn shell_main() -> ! {
|
||||
timer::init();
|
||||
log_server::init_wait().unwrap();
|
||||
let mut loops = 0;
|
||||
|
||||
// let log_server_id = xous::SID::from_bytes(b"xous-logs-output").unwrap();
|
||||
let graphics_server_id = xous::SID::from_bytes(b"graphics-server ").unwrap();
|
||||
|
|
@ -71,9 +156,12 @@ fn shell_main() -> ! {
|
|||
|
||||
// let mut counter: usize = 0;
|
||||
let mut ls = logstr::LogStr::new();
|
||||
let mut lfsr = 0xace1u32;
|
||||
let dark = graphics_server::Color::from(0);
|
||||
let light = graphics_server::Color::from(!0);
|
||||
let mut bouncyball = Bounce::new(14,
|
||||
Rectangle::new(Point::new(0, 18 * 21),
|
||||
Point::new(336, 536-1))); // TODO: make API call to get screen size
|
||||
bouncyball.update();
|
||||
|
||||
#[cfg(baremetal)]
|
||||
{
|
||||
|
|
@ -88,6 +176,14 @@ fn shell_main() -> ! {
|
|||
gpio.wfo(utra::gpio::UARTSEL_UARTSEL, 2);
|
||||
}
|
||||
|
||||
graphics_server::set_style(
|
||||
graphics_conn,
|
||||
1,
|
||||
dark,
|
||||
dark,
|
||||
)
|
||||
.expect("unable to draw to screen: {:?}");
|
||||
|
||||
let mut last_time: u64 = 0;
|
||||
let mut string_buffer = String::new(4096);
|
||||
loop {
|
||||
|
|
@ -123,36 +219,28 @@ fn shell_main() -> ! {
|
|||
error!("error requesting ticktimer!")
|
||||
}
|
||||
|
||||
graphics_server::set_style(
|
||||
graphics_conn,
|
||||
5,
|
||||
if lfsr & 1 == 0 { dark } else { light },
|
||||
if lfsr & 1 == 0 { dark } else { light },
|
||||
)
|
||||
.expect("unable to draw to screen: {:?}");
|
||||
|
||||
let x1 = move_lfsr(lfsr);
|
||||
let y1 = move_lfsr(x1);
|
||||
let x2 = move_lfsr(y1);
|
||||
let y2 = move_lfsr(x2);
|
||||
lfsr = y2;
|
||||
|
||||
graphics_server::draw_line(
|
||||
graphics_conn,
|
||||
graphics_server::Point::new((x1 % 336) as _, (y1 % 536) as _),
|
||||
graphics_server::Point::new((x2 % 336) as _, (y2 % 536) as _),
|
||||
)
|
||||
.expect("unable to draw to screen");
|
||||
|
||||
string_buffer.clear();
|
||||
write!(&mut string_buffer, "Elapsed time: {}ms", last_time).expect("Can't write");
|
||||
graphics_server::clear_region(graphics_conn, 0, 0, 300, 40)
|
||||
.expect("unable to clear region");
|
||||
info!("drawing string: {}", string_buffer);
|
||||
graphics_server::draw_string(graphics_conn, &string_buffer).expect("unable to draw string");
|
||||
graphics_server::flush(graphics_conn).expect("unable to draw to screen");
|
||||
|
||||
ticktimer_server::sleep_ms(ticktimer_conn, 2000 + loops).expect("couldn't sleep");
|
||||
loops += 1;
|
||||
// ticktimer_server::sleep_ms(ticktimer_conn, 2000).expect("couldn't sleep");
|
||||
|
||||
// draw the ball
|
||||
bouncyball.update();
|
||||
graphics_server::clear_region(graphics_conn,
|
||||
bouncyball.bounds.top_left().x as _, bouncyball.bounds.top_left().y as _,
|
||||
bouncyball.bounds.bottom_right().x as _, bouncyball.bounds.bottom_right().y as usize + 1)
|
||||
.expect("unable to clear region");
|
||||
graphics_server::draw_circle(
|
||||
graphics_conn,
|
||||
bouncyball.loc,
|
||||
bouncyball.radius as u16,
|
||||
)
|
||||
.expect("unable to draw to screen");
|
||||
|
||||
graphics_server::flush(graphics_conn).expect("unable to draw to screen");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ fn timer_tick(_irq_no: usize, _arg: *mut usize) {
|
|||
xous::rsyscall(xous::SysCall::ReturnToParent(xous::PID::new(1).unwrap(), 0)).expect("couldn't return to parent");
|
||||
|
||||
// acknowledge the timer
|
||||
timer.wfo(utra::timer0::EV_PENDING_PENDING, 0b1);
|
||||
timer.wfo(utra::timer0::EV_PENDING_ZERO, 0b1);
|
||||
//println!("<<< Returning from timer_tick()");
|
||||
}
|
||||
|
||||
|
|
@ -45,7 +45,7 @@ pub fn init() {
|
|||
|
||||
// Set EV_ENABLE
|
||||
let mut timer = CSR::new(TIMER_BASE as *mut u32);
|
||||
timer.wfo(utra::timer0::EV_ENABLE_ENABLE, 0b1);
|
||||
timer.wfo(utra::timer0::EV_ENABLE_ZERO, 0b1);
|
||||
}
|
||||
|
||||
#[cfg(not(baremetal))]
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ impl Uart {
|
|||
pub fn enable_rx(&self) {
|
||||
if cfg!(feature = "debugprint") {
|
||||
let mut uart_csr = CSR::new(unsafe{DEFAULT_UART_ADDR as *mut u32});
|
||||
uart_csr.wfo(utra::uart::EV_ENABLE_ENABLE, uart_csr.rf(utra::uart::EV_ENABLE_ENABLE) | 2 );
|
||||
uart_csr.rmwf(utra::uart::EV_ENABLE_RX, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -89,7 +89,7 @@ impl Uart {
|
|||
self.map_uart();
|
||||
}
|
||||
let mut uart_csr = CSR::new(unsafe{DEFAULT_UART_ADDR as *mut u32});
|
||||
match uart_csr.rf(utra::uart::EV_PENDING_PENDING) & 2 {
|
||||
match uart_csr.rf(utra::uart::EV_PENDING_RX) {
|
||||
0 => None,
|
||||
ack => {
|
||||
let c = Some(uart_csr.rf(utra::uart::RXTX_RXTX) as u8);
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue