Skip to content

Format and fix typos in generic #432

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 9, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
201 changes: 116 additions & 85 deletions src/generate/generic.rs
Original file line number Diff line number Diff line change
@@ -1,65 +1,71 @@
use core::marker;

///This trait shows that register has `read` method
/// Trait implemented by readable registers to enable the `read` method.
///
///Registers marked with `Writable` can be also `modify`'ed
/// Registers marked with `Writable` can be also `modify`'ed.
pub trait Readable {}

///This trait shows that register has `write`, `write_with_zero` and `reset` method
/// Trait implemented by writeable registers.
///
///Registers marked with `Readable` can be also `modify`'ed
/// This enables the `write`, `write_with_zero` and `reset` methods.
///
/// Registers marked with `Readable` can be also `modify`'ed.
pub trait Writable {}

///Reset value of the register
/// Reset value of the register.
///
///This value is initial value for `write` method.
///It can be also directly writed to register by `reset` method.
/// This value is the initial value for the `write` method. It can also be directly written to the
/// register by using the `reset` method.
pub trait ResetValue {
///Register size
/// Raw register type (`u8`, `u16`, `u32`, ...).
type Type;
///Reset value of the register

/// Reset value of the register.
fn reset_value() -> Self::Type;
}

///This structure provides volatile access to register
/// This structure provides volatile access to registers.
pub struct Reg<U, REG> {
register: vcell::VolatileCell<U>,
_marker: marker::PhantomData<REG>,
}

unsafe impl<U: Send, REG> Send for Reg<U, REG> { }
unsafe impl<U: Send, REG> Send for Reg<U, REG> {}

impl<U, REG> Reg<U, REG>
where
Self: Readable,
U: Copy
U: Copy,
{
///Reads the contents of `Readable` register
/// Reads the contents of a `Readable` register.
///
///You can read the contents of a register in such way:
///```ignore
///let bits = periph.reg.read().bits();
///```
///or get the content of a particular field of a register.
///```ignore
///let reader = periph.reg.read();
///let bits = reader.field1().bits();
///let flag = reader.field2().bit_is_set();
///```
/// You can read the raw contents of a register by using `bits`:
/// ```ignore
/// let bits = periph.reg.read().bits();
/// ```
/// or get the content of a particular field of a register:
/// ```ignore
/// let reader = periph.reg.read();
/// let bits = reader.field1().bits();
/// let flag = reader.field2().bit_is_set();
/// ```
#[inline(always)]
pub fn read(&self) -> R<U, Self> {
R {bits: self.register.get(), _reg: marker::PhantomData}
R {
bits: self.register.get(),
_reg: marker::PhantomData,
}
}
}

impl<U, REG> Reg<U, REG>
where
Self: ResetValue<Type=U> + Writable,
Self: ResetValue<Type = U> + Writable,
U: Copy,
{
///Writes the reset value to `Writable` register
/// Writes the reset value to `Writable` register.
///
///Resets the register to its initial state
/// Resets the register to its initial state.
#[inline(always)]
pub fn reset(&self) {
self.register.set(Self::reset_value())
Expand All @@ -68,47 +74,59 @@ where

impl<U, REG> Reg<U, REG>
where
Self: ResetValue<Type=U> + Writable,
U: Copy
Self: ResetValue<Type = U> + Writable,
U: Copy,
{
///Writes bits to `Writable` register
/// Writes bits to a `Writable` register.
///
///You can write raw bits into a register:
///```ignore
///periph.reg.write(|w| unsafe { w.bits(rawbits) });
///```
///or write only the fields you need:
///```ignore
///periph.reg.write(|w| w
/// .field1().bits(newfield1bits)
/// .field2().set_bit()
/// .field3().variant(VARIANT)
///);
///```
///Other fields will have reset value.
/// You can write raw bits into a register:
/// ```ignore
/// periph.reg.write(|w| unsafe { w.bits(rawbits) });
/// ```
/// or write only the fields you need:
/// ```ignore
/// periph.reg.write(|w| w
/// .field1().bits(newfield1bits)
/// .field2().set_bit()
/// .field3().variant(VARIANT)
/// );
/// ```
/// In the latter case, other fields will be set to their reset value.
#[inline(always)]
pub fn write<F>(&self, f: F)
where
F: FnOnce(&mut W<U, Self>) -> &mut W<U, Self>
F: FnOnce(&mut W<U, Self>) -> &mut W<U, Self>,
{
self.register.set(f(&mut W {bits: Self::reset_value(), _reg: marker::PhantomData}).bits);
self.register.set(
f(&mut W {
bits: Self::reset_value(),
_reg: marker::PhantomData,
})
.bits,
);
}
}

impl<U, REG> Reg<U, REG>
where
Self: Writable,
U: Copy + Default
U: Copy + Default,
{
///Writes Zero to `Writable` register
/// Writes 0 to a `Writable` register.
///
///Similar to `write`, but unused bits will contain 0.
/// Similar to `write`, but unused bits will contain 0.
#[inline(always)]
pub fn write_with_zero<F>(&self, f: F)
where
F: FnOnce(&mut W<U, Self>) -> &mut W<U, Self>
F: FnOnce(&mut W<U, Self>) -> &mut W<U, Self>,
{
self.register.set(f(&mut W {bits: U::default(), _reg: marker::PhantomData }).bits);
self.register.set(
f(&mut W {
bits: U::default(),
_reg: marker::PhantomData,
})
.bits,
);
}
}

Expand All @@ -117,55 +135,68 @@ where
Self: Readable + Writable,
U: Copy,
{
///Modifies the contents of the register
/// Modifies the contents of the register by reading and then writing it.
///
///E.g. to do a read-modify-write sequence to change parts of a register:
///```ignore
///periph.reg.modify(|r, w| unsafe { w.bits(
/// r.bits() | 3
///) });
///```
///or
///```ignore
///periph.reg.modify(|_, w| w
/// .field1().bits(newfield1bits)
/// .field2().set_bit()
/// .field3().variant(VARIANT)
///);
///```
///Other fields will have value they had before call `modify`.
/// E.g. to do a read-modify-write sequence to change parts of a register:
/// ```ignore
/// periph.reg.modify(|r, w| unsafe { w.bits(
/// r.bits() | 3
/// ) });
/// ```
/// or
/// ```ignore
/// periph.reg.modify(|_, w| w
/// .field1().bits(newfield1bits)
/// .field2().set_bit()
/// .field3().variant(VARIANT)
/// );
/// ```
/// Other fields will have the value they had before the call to `modify`.
#[inline(always)]
pub fn modify<F>(&self, f: F)
where
for<'w> F: FnOnce(&R<U, Self>, &'w mut W<U, Self>) -> &'w mut W<U, Self>
for<'w> F: FnOnce(&R<U, Self>, &'w mut W<U, Self>) -> &'w mut W<U, Self>,
{
let bits = self.register.get();
self.register.set(f(&R {bits, _reg: marker::PhantomData}, &mut W {bits, _reg: marker::PhantomData}).bits);
self.register.set(
f(
&R {
bits,
_reg: marker::PhantomData,
},
&mut W {
bits,
_reg: marker::PhantomData,
},
)
.bits,
);
}
}

///Register/field reader
/// Register/field reader.
///
///Result of the [`read`](Reg::read) method of a register.
///Also it can be used in the [`modify`](Reg::read) method
/// Result of the `read` methods of registers. Also used as a closure argument in the `modify`
/// method.
pub struct R<U, T> {
pub(crate) bits: U,
_reg: marker::PhantomData<T>,
}

impl<U, T> R<U, T>
where
U: Copy
U: Copy,
{
///Create new instance of reader
/// Creates a new instance of the reader.
#[inline(always)]
pub(crate) fn new(bits: U) -> Self {
Self {
bits,
_reg: marker::PhantomData,
}
}
///Read raw bits from register/field

/// Reads raw bits from register/field.
#[inline(always)]
pub fn bits(&self) -> U {
self.bits
Expand All @@ -175,7 +206,7 @@ where
impl<U, T, FI> PartialEq<FI> for R<U, T>
where
U: PartialEq,
FI: Copy+Into<U>
FI: Copy + Into<U>,
{
#[inline(always)]
fn eq(&self, other: &FI) -> bool {
Expand All @@ -184,46 +215,46 @@ where
}

impl<FI> R<bool, FI> {
///Value of the field as raw bits
/// Value of the field as raw bits.
#[inline(always)]
pub fn bit(&self) -> bool {
self.bits
}
///Returns `true` if the bit is clear (0)
/// Returns `true` if the bit is clear (0).
#[inline(always)]
pub fn bit_is_clear(&self) -> bool {
!self.bit()
}
///Returns `true` if the bit is set (1)
/// Returns `true` if the bit is set (1).
#[inline(always)]
pub fn bit_is_set(&self) -> bool {
self.bit()
}
}

///Register writer
/// Register writer.
///
///Used as an argument to the closures in the [`write`](Reg::write) and [`modify`](Reg::modify) methods of the register
/// Used as an argument to the closures in the `write` and `modify` methods of the register.
pub struct W<U, REG> {
///Writable bits
pub(crate) bits: U,
_reg: marker::PhantomData<REG>,
}

impl<U, REG> W<U, REG> {
///Writes raw bits to the register
/// Writes raw bits to the register.
#[inline(always)]
pub unsafe fn bits(&mut self, bits: U) -> &mut Self {
self.bits = bits;
self
}
}

///Used if enumerated values cover not the whole range
#[derive(Clone,Copy,PartialEq)]
/// Used if enumerated values cover not the whole range.
#[derive(Clone, Copy, PartialEq)]
pub enum Variant<U, T> {
///Expected variant
/// Expected variant.
Val(T),
///Raw bits
/// Raw bits.
Res(U),
}