rust: changed crate structure

This commit is contained in:
occheung 2020-08-10 18:06:15 +08:00
parent 429fbb7443
commit 2def3ed95d
5 changed files with 155 additions and 160 deletions

View File

@ -2,7 +2,7 @@
authors = ["occheung"] authors = ["occheung"]
edition = "2018" edition = "2018"
readme = "README.md" readme = "README.md"
name = "firmware-dev" name = "firmware"
version = "0.1.0" version = "0.1.0"
[dependencies] [dependencies]
@ -34,7 +34,7 @@ name = "fpga_config"
# this lets you use `cargo fix`! # this lets you use `cargo fix`!
[[bin]] [[bin]]
name = "firmware-dev" name = "firmware"
test = false test = false
bench = false bench = false

View File

@ -1,151 +0,0 @@
#![no_std]
use stm32h7xx_hal::{
hal::{
digital::v2::{
InputPin,
OutputPin,
},
blocking::spi::Transfer,
spi::FullDuplex,
},
pac,
prelude::*,
spi,
};
use core::cell;
use cortex_m;
use cortex_m::asm::nop;
use cortex_m_semihosting::hprintln;
use nb::block;
use crate::spi_slave::Parts;
/*
* Enum for structuring error
*/
#[derive(Debug)]
pub enum Error<E> {
SPI(E),
CSError,
GetRefMutDataError,
}
/*
* Basic structure for CPLD signal multiplexing
*/
#[derive(Debug)]
pub struct CPLDData<SPI, CS0, CS1, CS2> {
pub(crate) spi: SPI,
pub(crate) chip_select: (CS0, CS1, CS2),
}
#[derive(Debug)]
pub struct CPLD<SPI, CS0, CS1, CS2> {
pub(crate) data: cell::RefCell<CPLDData<SPI, CS0, CS1, CS2>>,
}
pub trait SelectChip {
type Error;
fn select_chip(&mut self, chip: u8) -> Result<(), Self::Error>;
}
impl<SPI, CS0, CS1, CS2, E> SelectChip for CPLDData<SPI, CS0, CS1, CS2>
where
SPI: Transfer<u8, Error = E>,
CS0: OutputPin,
CS1: OutputPin,
CS2: OutputPin,
{
type Error = Error<E>;
fn select_chip(&mut self, chip: u8) -> Result<(), Self::Error> {
match chip & (1 << 0) {
0 => self.chip_select.0.set_low(),
_ => self.chip_select.0.set_high(),
}.map_err(|_| Error::CSError)?;
match chip & (1 << 1) {
0 => self.chip_select.1.set_low(),
_ => self.chip_select.1.set_high(),
}.map_err(|_| Error::CSError)?;
match chip & (1 << 2) {
0 => self.chip_select.2.set_low(),
_ => self.chip_select.2.set_high(),
}.map_err(|_| Error::CSError)?;
Ok(())
}
}
pub trait DoOnGetRefMutData<SPI, CS0, CS1, CS2> {
fn do_on_get_ref_mut_data<R, E>(
&self,
f: impl FnOnce(cell::RefMut<CPLDData<SPI, CS0, CS1, CS2>>) -> Result<R, Error<E>>,
) -> Result<R, Error<E>>;
}
impl<SPI, CS0, CS1, CS2> DoOnGetRefMutData<SPI, CS0, CS1, CS2> for CPLD<SPI, CS0, CS1, CS2> {
fn do_on_get_ref_mut_data<R, E>(
&self,
f: impl FnOnce(cell::RefMut<CPLDData<SPI, CS0, CS1, CS2>>) -> Result<R, Error<E>>,
) -> Result<R, Error<E>> {
let dev = self
.data
.try_borrow_mut()
.map_err(|_| Error::GetRefMutDataError)?;
f(dev)
}
}
impl<SPI, CS0, CS1, CS2, E> Transfer<u8> for CPLD<SPI, CS0, CS1, CS2>
where
SPI: Transfer<u8, Error = E>,
CS0: OutputPin,
CS1: OutputPin,
CS2: OutputPin,
{
type Error = Error<E>;
fn transfer<'w>(&mut self, words: &'w mut [u8]) -> Result<&'w [u8], Self::Error> {
self.do_on_get_ref_mut_data(move |mut dev| dev.spi.transfer(words).map_err(Error::SPI))
}
}
impl<SPI, CS0, CS1, CS2, E> CPLD<SPI, CS0, CS1, CS2> where
SPI: Transfer<u8, Error = E>,
CS0: OutputPin,
CS1: OutputPin,
CS2: OutputPin,
{
// Constructor for CPLD
pub fn new(spi: SPI, chip_select: (CS0, CS1, CS2)) -> Self {
// Init data
let data = CPLDData {
spi,
chip_select,
};
// Init CPLD
CPLD {
data: cell::RefCell::new(data),
}
}
// Destroy the wrapper, return the CPLD data
pub fn destroy(self) -> (SPI, (CS0, CS1, CS2)) {
let cpld = self.data.into_inner();
(cpld.spi, cpld.chip_select)
}
// Split SPI into chips, wrapped by Parts struct
pub fn split<'a>(&'a self) -> Parts<'a, CPLD<SPI, CS0, CS1, CS2>, SPI, CS0, CS1, CS2> {
Parts::new(&self)
}
// Select Chip
pub fn select_chip(&mut self, channel: u8) -> Result<(), Error<E>> {
self.do_on_get_ref_mut_data(|mut dev| dev.select_chip(channel))
}
}

View File

@ -1,7 +1,153 @@
#![no_std] #![no_std]
mod cpld; use stm32h7xx_hal::{
pub use cpld::{CPLDData, CPLD, Error}; hal::{
digital::v2::{
InputPin,
OutputPin,
},
blocking::spi::Transfer,
spi::FullDuplex,
},
pac,
prelude::*,
spi,
};
mod spi_slave; use core::cell;
pub use spi_slave::{SPISlave, Parts};
use cortex_m;
use cortex_m::asm::nop;
use cortex_m_semihosting::hprintln;
use nb::block;
pub mod spi_slave;
use crate::spi_slave::{SPISlave, Parts};
/*
* Enum for structuring error
*/
#[derive(Debug)]
pub enum Error<E> {
SPI(E),
CSError,
GetRefMutDataError,
}
/*
* Basic structure for CPLD signal multiplexing
*/
#[derive(Debug)]
pub struct CPLDData<SPI, CS0, CS1, CS2> {
pub(crate) spi: SPI,
pub(crate) chip_select: (CS0, CS1, CS2),
}
#[derive(Debug)]
pub struct CPLD<SPI, CS0, CS1, CS2> {
pub(crate) data: cell::RefCell<CPLDData<SPI, CS0, CS1, CS2>>,
}
pub trait SelectChip {
type Error;
fn select_chip(&mut self, chip: u8) -> Result<(), Self::Error>;
}
impl<SPI, CS0, CS1, CS2, E> SelectChip for CPLDData<SPI, CS0, CS1, CS2>
where
SPI: Transfer<u8, Error = E>,
CS0: OutputPin,
CS1: OutputPin,
CS2: OutputPin,
{
type Error = Error<E>;
fn select_chip(&mut self, chip: u8) -> Result<(), Self::Error> {
match chip & (1 << 0) {
0 => self.chip_select.0.set_low(),
_ => self.chip_select.0.set_high(),
}.map_err(|_| Error::CSError)?;
match chip & (1 << 1) {
0 => self.chip_select.1.set_low(),
_ => self.chip_select.1.set_high(),
}.map_err(|_| Error::CSError)?;
match chip & (1 << 2) {
0 => self.chip_select.2.set_low(),
_ => self.chip_select.2.set_high(),
}.map_err(|_| Error::CSError)?;
Ok(())
}
}
pub trait DoOnGetRefMutData<SPI, CS0, CS1, CS2> {
fn do_on_get_ref_mut_data<R, E>(
&self,
f: impl FnOnce(cell::RefMut<CPLDData<SPI, CS0, CS1, CS2>>) -> Result<R, Error<E>>,
) -> Result<R, Error<E>>;
}
impl<SPI, CS0, CS1, CS2> DoOnGetRefMutData<SPI, CS0, CS1, CS2> for CPLD<SPI, CS0, CS1, CS2> {
fn do_on_get_ref_mut_data<R, E>(
&self,
f: impl FnOnce(cell::RefMut<CPLDData<SPI, CS0, CS1, CS2>>) -> Result<R, Error<E>>,
) -> Result<R, Error<E>> {
let dev = self
.data
.try_borrow_mut()
.map_err(|_| Error::GetRefMutDataError)?;
f(dev)
}
}
impl<SPI, CS0, CS1, CS2, E> Transfer<u8> for CPLD<SPI, CS0, CS1, CS2>
where
SPI: Transfer<u8, Error = E>,
CS0: OutputPin,
CS1: OutputPin,
CS2: OutputPin,
{
type Error = Error<E>;
fn transfer<'w>(&mut self, words: &'w mut [u8]) -> Result<&'w [u8], Self::Error> {
self.do_on_get_ref_mut_data(move |mut dev| dev.spi.transfer(words).map_err(Error::SPI))
}
}
impl<SPI, CS0, CS1, CS2, E> CPLD<SPI, CS0, CS1, CS2> where
SPI: Transfer<u8, Error = E>,
CS0: OutputPin,
CS1: OutputPin,
CS2: OutputPin,
{
// Constructor for CPLD
pub fn new(spi: SPI, chip_select: (CS0, CS1, CS2)) -> Self {
// Init data
let data = CPLDData {
spi,
chip_select,
};
// Init CPLD
CPLD {
data: cell::RefCell::new(data),
}
}
// Destroy the wrapper, return the CPLD data
pub fn destroy(self) -> (SPI, (CS0, CS1, CS2)) {
let cpld = self.data.into_inner();
(cpld.spi, cpld.chip_select)
}
// Split SPI into chips, wrapped by Parts struct
pub fn split<'a>(&'a self) -> Parts<'a, CPLD<SPI, CS0, CS1, CS2>, SPI, CS0, CS1, CS2> {
Parts::new(&self)
}
// Select Chip
pub fn select_chip(&mut self, channel: u8) -> Result<(), Error<E>> {
self.do_on_get_ref_mut_data(|mut dev| dev.select_chip(channel))
}
}

View File

@ -17,7 +17,7 @@ use cortex_m_semihosting::hprintln;
use core::ptr; use core::ptr;
use nb::block; use nb::block;
mod cpld; use firmware::CPLD;
#[entry] #[entry]
fn main() -> ! { fn main() -> ! {
@ -73,7 +73,7 @@ fn main() -> ! {
let mut data :u8 = 0xAD; let mut data :u8 = 0xAD;
let mut switch = cpld::CPLD::new(spi, ( let mut switch = CPLD::new(spi, (
gpiob.pb12.into_push_pull_output(), gpiob.pb12.into_push_pull_output(),
gpioa.pa15.into_push_pull_output(), gpioa.pa15.into_push_pull_output(),
gpioc.pc7.into_push_pull_output(), gpioc.pc7.into_push_pull_output(),

View File

@ -13,7 +13,7 @@ use stm32h7xx_hal::{
use core::marker::PhantomData; use core::marker::PhantomData;
use crate::cpld::{DoOnGetRefMutData, Error, SelectChip}; use crate::{DoOnGetRefMutData, Error, SelectChip};
pub struct SPISlave<'a, DEV: 'a, SPI, CS0, CS1, CS2> ( pub struct SPISlave<'a, DEV: 'a, SPI, CS0, CS1, CS2> (
&'a DEV, &'a DEV,