pub mod persist;
use core::ops::{Deref, DerefMut};
#[cfg(feature="panicout")]
use crate::hal::generic::serial::SerialNoInterruptTx;
pub enum OwnOrBorrow<'a, T: 'a> {
Own(T),
Borrow(&'a T)
}
pub enum OwnOrBorrowMut<'a, T: 'a> {
Own(T),
Borrow(&'a mut T)
}
#[derive(Copy,Clone,Eq,PartialEq)]
pub struct BitField<const BYTES: usize>([u8; BYTES]);
#[derive(Copy,Clone,Eq,PartialEq)]
pub struct BitIndex(usize);
#[cfg(all(feature="panicout",target_arch="avr"))]
pub fn debug_print(string: &str){
#[cfg(target_arch="avr")]
crate::panic_stdout!().blocking_write_slice(string.as_bytes());
}
#[cfg(all(feature="panicout",target_arch="avr"))]
pub fn debug_print_u16(val: u16){
if val > 9 {
debug_print_u16(val/10);
}
crate::panic_stdout!().blocking_write_u8(((val % 10) + 0x30) as u8);
}
#[cfg(all(feature="panicout",target_arch="avr"))]
pub fn debug_print_u32(val: u32){
if val > 9 {
debug_print_u32(val/10);
}
crate::panic_stdout!().blocking_write_u8(((val % 10) + 0x30) as u8);
}
macro_rules! common_impl {
($name:ident) => {
impl<T> $name<'_,T>
where
T: Clone
{
pub fn into_owned(self) -> T {
match self {
Self::Own(v) => v,
Self::Borrow(r) => r.clone()
}
}
}
impl<T> $name<'_,T> {
pub fn is_owned(&self) -> bool {
match self {
Self::Own(_) => true,
Self::Borrow(_) => false
}
}
}
impl<T> Deref for $name<'_,T> {
type Target = T;
fn deref(&self) -> &Self::Target {
match self {
Self::Own(v) => v,
Self::Borrow(r) => *r
}
}
}
impl<T> From<T> for $name<'_,T> {
fn from(v: T) -> Self {
Self::Own(v)
}
}
}
}
common_impl!(OwnOrBorrow);
common_impl!(OwnOrBorrowMut);
impl<T> Clone for OwnOrBorrow<'_,T>
where
T: Clone
{
fn clone(&self) -> Self {
match self {
OwnOrBorrow::Own(v) => Self::Own(v.clone()),
OwnOrBorrow::Borrow(r) => Self::Borrow(r)
}
}
}
impl<'a, T> From<&'a T> for OwnOrBorrow<'a,T> {
fn from(r: &'a T) -> Self {
Self::Borrow(r)
}
}
impl<'a, T> From<&'a mut T> for OwnOrBorrowMut<'a,T> {
fn from(r: &'a mut T) -> Self {
Self::Borrow(r)
}
}
impl<T> DerefMut for OwnOrBorrowMut<'_,T> {
fn deref_mut(&mut self) -> &mut Self::Target {
match self {
Self::Own(v) => v,
Self::Borrow(r) => r
}
}
}
impl BitIndex {
pub const fn bit(b: usize) -> Self {
Self {
0: b
}
}
#[inline(always)]
pub fn byte_index<const BYTES: usize>(self) -> usize {
(BYTES-1) - (self.0 / 8)
}
#[inline(always)]
pub fn bit_index_in_byte(self) -> u8 {
(self.0 % 8) as u8
}
#[inline(always)]
pub fn positive_byte_mask(self) -> u8 {
0x01u8 << self.bit_index_in_byte()
}
#[inline(always)]
pub fn negative_byte_mask(self) -> u8 {
0xffu8 ^ self.positive_byte_mask()
}
}
impl<const BYTES: usize> BitField<BYTES> {
pub const fn with_initial(vals: [u8; BYTES]) -> Self {
BitField {
0: vals
}
}
pub fn with_bits_set(bits: &[BitIndex]) -> Self {
let mut new = Self::all_clr();
for bit in bits {
new.set(*bit);
}
new
}
pub const fn all_clr() -> Self {
BitField {
0: [0u8; BYTES]
}
}
pub const fn all_set() -> Self {
BitField {
0: [0xffu8; BYTES]
}
}
pub fn is_set(&self, bit: BitIndex) -> bool {
(self.0[bit.byte_index::<BYTES>()] & bit.positive_byte_mask()) > 0
}
pub fn is_clr(&self, bit: BitIndex) -> bool {
!self.is_set(bit)
}
pub fn set(&mut self, bit: BitIndex) {
self.0[bit.byte_index::<BYTES>()] |= bit.positive_byte_mask();
}
pub fn clr(&mut self, bit: BitIndex) {
self.0[bit.byte_index::<BYTES>()] &= bit.negative_byte_mask();
}
pub fn set_or_clr(&mut self, bit: BitIndex, set: bool) {
match set {
true => self.set(bit),
false => self.clr(bit)
}
}
}
#[cfg(test)]
mod tests {
use crate::util::{BitField, BitIndex};
#[test]
fn test_bitindex() {
let bit10 = BitIndex(10);
assert_eq!(bit10.byte_index::<4>(), 2);
assert_eq!(bit10.bit_index_in_byte(), 2);
assert_eq!(bit10.positive_byte_mask(), 0b00000100);
assert_eq!(bit10.negative_byte_mask(), 0b11111011);
let bit16 = BitIndex(16);
assert_eq!(bit16.byte_index::<4>(), 1);
assert_eq!(bit16.bit_index_in_byte(), 0);
assert_eq!(bit16.positive_byte_mask(), 0b00000001);
assert_eq!(bit16.negative_byte_mask(), 0b11111110);
}
#[test]
fn test_bitfield() {
let mut all_zero : BitField<2> = BitField::all_clr();
let mut all_one : BitField<2> = BitField::all_set();
assert!(all_zero == BitField::<2>::with_initial([ 0b00000000, 0b00000000 ]));
assert!(all_one == BitField::<2>::with_initial([ 0b11111111, 0b11111111 ]));
all_zero.set(BitIndex(3));
all_one.set(BitIndex(3));
assert!(all_zero == BitField::<2>::with_initial([ 0b00000000, 0b00001000 ]));
assert!(all_one == BitField::<2>::with_initial([ 0b11111111, 0b11111111 ]));
all_zero.clr(BitIndex(7));
all_one.clr(BitIndex(7));
assert!(all_zero == BitField::<2>::with_initial([ 0b00000000, 0b00001000 ]));
assert!(all_one == BitField::<2>::with_initial([ 0b11111111, 0b01111111 ]));
all_zero.set_or_clr(BitIndex(13), true);
all_one.set_or_clr(BitIndex(15),false);
assert!(all_zero == BitField::<2>::with_initial([ 0b00100000, 0b00001000 ]));
assert!(all_one == BitField::<2>::with_initial([ 0b01111111, 0b01111111 ]));
assert!(all_zero.is_set(BitIndex(13)));
assert!(all_zero.is_clr(BitIndex(15)));
assert!(all_one.is_set(BitIndex(6)));
assert!(all_one.is_clr(BitIndex(7)));
assert!(!all_zero.is_set(BitIndex(0)));
assert!(!all_one.is_clr(BitIndex(1)));
}
#[test]
pub fn test_bitfield_init() {
let some_set = BitField::<4>::with_bits_set(&[BitIndex(12),BitIndex(5),BitIndex(23),BitIndex(31)]);
assert!(some_set == BitField::<4>::with_initial([ 0b10000000, 0b10000000, 0b00010000, 0b00100000 ]));
}
}