#![allow(non_snake_case, non_upper_case_globals, non_camel_case_types)]
use register::Register;
#[cfg(not(feature = "nosync"))]
use core::marker::PhantomData;
static mut ENDPOINT_LIST_ATTACHED: bool = false;
pub use super::constants::USB1_SRAM_ADDR;
pub const DA_BUF_ADDR: u32 = 0x4000_0000; pub const DA_BUF: u32 = (DA_BUF_ADDR >> 22); pub const ENDPOINT_LIST_SIZE: usize = 80;
#[repr(C)]
pub struct EndpointList {
pub EP0OUT: Register<u32>,
pub SETUP: Register<u32>,
pub EP0IN: Register<u32>,
_reserved: Register<u32>, pub EP: [Register<u32>; 4*4],
}
#[cfg(not(feature = "nosync"))]
pub struct Instance {
pub(crate) addr: u32,
pub(crate) _marker: PhantomData<*const EndpointList>,
}
unsafe impl Send for Instance {}
unsafe impl Send for EndpointList {}
impl Instance {
pub fn addr(&self) -> u32 {
self.addr
}
}
#[cfg(not(feature = "nosync"))]
#[inline]
fn zero(instance: &Instance) {
(*instance).EP0OUT.write(0x0);
(*instance).SETUP.write(0x0);
(*instance)._reserved.write(0);
(*instance).EP0IN.write(0x0);
for EP in (*instance).EP.iter() {
EP.write(0x0);
}
}
#[cfg(not(feature = "nosync"))]
#[inline]
fn new(addr: u32) -> Instance {
let instance = Instance {
addr,
_marker: PhantomData,
};
zero(&instance);
instance
}
#[cfg(not(feature = "nosync"))]
#[inline]
pub fn attach() -> Option<Instance> {
cortex_m::interrupt::free(|_| unsafe {
if ENDPOINT_LIST_ATTACHED {
None
} else {
ENDPOINT_LIST_ATTACHED = true;
Some(new(USB1_SRAM_ADDR))
}
})
}
#[cfg(not(feature = "nosync"))]
#[inline]
pub unsafe fn steal() -> Instance {
ENDPOINT_LIST_ATTACHED = true;
Instance {
addr: USB1_SRAM_ADDR,
_marker: PhantomData,
}
}
pub mod EP0OUT {
pub mod A {
pub const offset: u32 = 31;
pub const mask: u32 = 1 << offset;
pub mod R {}
pub mod W {}
pub mod RW {
pub const NotActive: u32 = 0b0;
pub const Active: u32 = 0b1;
}
}
pub mod D {
pub const offset: u32 = 30;
pub const mask: u32 = 1 << offset;
pub mod R {}
pub mod W {}
pub mod RW {
pub const Enabled: u32 = 0b0;
pub const Disabled: u32 = 0b1;
}
}
pub mod S {
pub const offset: u32 = 29;
pub const mask: u32 = 1 << offset;
pub mod R {}
pub mod W {}
pub mod RW {
pub const NotStalled: u32 = 0b0;
pub const Stalled: u32 = 0b1;
}
}
pub mod TR {
pub const offset: u32 = 28;
pub const mask: u32 = 1 << offset;
pub mod R {}
pub mod W {
pub const ToggleReset: u32 = 0b1;
}
pub mod RW {}
}
pub mod RFTV {
pub const offset: u32 = 27;
pub const mask: u32 = 1 << offset;
pub mod R {}
pub mod W {
pub const ToggleValue0: u32 = 0b0;
pub const ToggleValue1: u32 = 0b1;
}
pub mod RW {}
}
pub mod T {
pub const offset: u32 = 26;
pub const mask: u32 = 1 << offset;
pub mod R {}
pub mod W {}
pub mod RW {
pub const Generic: u32 = 0b0;
pub const Isochronous: u32 = 0b1;
}
}
pub mod NBYTES {
pub const offset: u32 = 16;
pub const mask: u32 = ((1 << 10) - 1) << offset;
pub mod R {}
pub mod W {}
pub mod RW {}
}
pub mod ADDROFF {
pub const offset: u32 = 0;
pub const mask: u32 = ((1 << 16) - 1) << offset;
pub mod R {}
pub mod W {}
pub mod RW {}
}
}
pub mod SETUP {
pub use super::EP0OUT::ADDROFF;
}
pub mod EP0IN {
pub use super::EP0OUT::A;
pub use super::EP0OUT::D;
pub use super::EP0OUT::S;
pub use super::EP0OUT::TR;
pub use super::EP0OUT::RFTV;
pub use super::EP0OUT::T;
pub use super::EP0OUT::NBYTES;
pub use super::EP0OUT::ADDROFF;
}
pub mod EP {
pub mod A {
pub const offset: u32 = 31;
pub const mask: u32 = 1 << offset;
pub mod R {
pub const NotActive: u32 = 0b0;
}
pub mod W {}
pub mod RW {
pub const Active: u32 = 0b1;
}
}
pub use super::EP0OUT::D;
pub use super::EP0OUT::S;
pub use super::EP0OUT::TR;
pub use super::EP0OUT::RFTV;
pub use super::EP0OUT::T;
pub use super::EP0OUT::NBYTES;
pub use super::EP0OUT::ADDROFF;
}
#[cfg(not(feature = "nosync"))]
impl ::core::ops::Deref for Instance {
type Target = EndpointList;
#[inline(always)]
fn deref(&self) -> &EndpointList {
unsafe { &*(self.addr as *const _) }
}
}
pub mod register {
use core::cell::UnsafeCell;
use core::ptr::{read_volatile, write_volatile};
pub struct Register<T> {
register: UnsafeCell<T>,
}
impl<T: Copy> Register<T> {
#[inline(always)]
pub fn read(&self) -> T {
unsafe { read_volatile(self.register.get()) }
}
#[inline(always)]
pub fn write(&self, val: T) {
unsafe { write_volatile(self.register.get(), val) }
}
}
#[macro_export]
macro_rules! read_endpoint {
( $periph:path, $instance:expr, $reg:ident, $( $field:ident ),+ ) => {{
#[allow(unused_imports)]
use $periph::*;
let val = (*$instance).$reg.read();
( $({
#[allow(unused_imports)]
use $periph::{$reg::$field::{mask, offset, R::*, RW::*}};
(val & mask) >> offset
}) , *)
}};
( $periph:path, $instance:expr, $reg:ident, $field:ident $($cmp:tt)* ) => {{
#[allow(unused_imports)]
use $periph::*;
#[allow(unused_imports)]
use $periph::{$reg::$field::{mask, offset, R::*, RW::*}};
(((*$instance).$reg.read() & mask) >> offset) $($cmp)*
}};
( $periph:path, $instance:expr, $reg:ident ) => {{
#[allow(unused_imports)]
use $periph::{*};
(*$instance).$reg.read()
}};
}
#[macro_export]
macro_rules! read_out_endpoint_i {
( $periph:path, $instance:expr, $i:expr, $( $field:ident ),+ ) => {{
#[allow(unused_imports)]
use $periph::*;
let j = ($i - 1) << 2;
let val = (*$instance).EP[j].read();
( $({
#[allow(unused_imports)]
use $periph::{EP::$field::{mask, offset, R::*, RW::*}};
(val & mask) >> offset
}) , *)
}};
( $periph:path, $instance:expr, $i:expr, $field:ident $($cmp:tt)* ) => {{
#[allow(unused_imports)]
use $periph::*;
#[allow(unused_imports)]
use $periph::{EP::$field::{mask, offset, R::*, RW::*}};
let j = ($i - 1) << 2;
(((*$instance).EP[j].read() & mask) >> offset) $($cmp)*
}};
( $periph:path, $instance:expr, $i:expr) => {{
#[allow(unused_imports)]
use $periph::{*};
let j = ($i - 1) << 2;
(*$instance).EP[j].read()
}};
}
#[macro_export]
macro_rules! read_in_endpoint_i {
( $periph:path, $instance:expr, $i:expr, $( $field:ident ),+ ) => {{
#[allow(unused_imports)]
use $periph::*;
let j = (($i - 1) << 2) + 2;
let val = (*$instance).EP[j].read();
( $({
#[allow(unused_imports)]
use $periph::{EP::$field::{mask, offset, R::*, RW::*}};
(val & mask) >> offset
}) , *)
}};
( $periph:path, $instance:expr, $i:expr,$field:ident $($cmp:tt)* ) => {{
#[allow(unused_imports)]
use $periph::*;
#[allow(unused_imports)]
use $periph::{EP::$field::{mask, offset, R::*, RW::*}};
let j = (($i - 1) << 2) + 2;
(((*$instance).EP[j].read() & mask) >> offset) $($cmp)*
}};
( $periph:path, $instance:expr, $i:expr) => {{
#[allow(unused_imports)]
use $periph::{*};
let j = (($i - 1) << 2) + 2;
(*$instance).EP[j].read()
}};
}
#[macro_export]
macro_rules! read_endpoint_i {
( $periph:path, $instance:expr, $i:expr, $dir:expr, $buffer:expr, $( $field:ident ),+ ) => {{
#[allow(unused_imports)]
use $periph::*;
let j = (($i - 1) << 2) + ($dir << 1) + $buffer;
let val = (*$instance).EP[j].read();
( $({
#[allow(unused_imports)]
use $periph::{EP::$field::{mask, offset, R::*, RW::*}};
(val & mask) >> offset
}) , *)
}};
( $periph:path, $instance:expr, $i:expr, $dir:expr, $buffer:expr, $field:ident $($cmp:tt)* ) => {{
#[allow(unused_imports)]
use $periph::*;
#[allow(unused_imports)]
use $periph::{EP::$field::{mask, offset, R::*, RW::*}};
let j = (($i - 1) << 2) + ($dir << 1) + $buffer;
(((*$instance).EP[j].read() & mask) >> offset) $($cmp)*
}};
( $periph:path, $instance:expr, $i:expr, $dir:expr, $buffer:expr ) => {{
#[allow(unused_imports)]
use $periph::{*};
let j = (($i - 1) << 2) + ($dir << 1) + $buffer;
(*$instance).EP[j].read()
}};
}
#[macro_export]
macro_rules! modify_endpoint_i {
( $periph:path, $instance:expr, $i:expr, $dir:expr, $buffer:expr, $( $field:ident : $value:expr ),+ ) => {{
#[allow(unused_imports)]
use $periph::{*};
let j = (($i - 1) << 2) + ($dir << 1) + $buffer;
#[allow(unused_imports)]
(*$instance).EP[j].write(
((*$instance).EP[j].read() & !( $({ use $periph::{EP::$field::mask}; mask }) | * ))
| $({ use $periph::{EP::$field::{mask, offset, W::*, RW::*}}; ($value << offset) & mask }) | *);
}};
( $periph:path, $instance:expr, $i:expr, $dir:expr, $buffer:expr, $fn:expr ) => {{
#[allow(unused_imports)]
use $periph::*;
let j = (($i - 1) << 2) + ($dir << 1) + $buffer;
(*$instance).EP[j].write($fn((*$instance).EP[j].read()));
}};
}
#[macro_export]
macro_rules! write_endpoint {
( $periph:path, $instance:expr, $reg:ident, $( $field:ident : $value:expr ),+ ) => {{
#[allow(unused_imports)]
use $periph::*;
#[allow(unused_imports)]
(*$instance).$reg.write(
$({ use $periph::{$reg::$field::{mask, offset, W::*, RW::*}}; ($value << offset) & mask }) | *
);
}};
( $periph:path, $instance:expr, $reg:ident, $value:expr ) => {{
#[allow(unused_imports)]
use $periph::*;
(*$instance).$reg.write($value);
}};
}
#[macro_export]
macro_rules! modify_endpoint {
( $periph:path, $instance:expr, $reg:ident, $( $field:ident : $value:expr ),+ ) => {{
#[allow(unused_imports)]
use $periph::{*};
#[allow(unused_imports)]
(*$instance).$reg.write(
((*$instance).$reg.read() & !( $({ use $periph::{$reg::$field::mask}; mask }) | * ))
| $({ use $periph::{$reg::$field::{mask, offset, W::*, RW::*}}; ($value << offset) & mask }) | *);
}};
( $periph:path, $instance:expr, $reg:ident, $fn:expr ) => {{
#[allow(unused_imports)]
use $periph::*;
(*$instance).$reg.write($fn((*$instance).$reg.read()));
}};
}
}