rust: changed crate structure
This commit is contained in:
parent
429fbb7443
commit
2def3ed95d
|
@ -2,7 +2,7 @@
|
|||
authors = ["occheung"]
|
||||
edition = "2018"
|
||||
readme = "README.md"
|
||||
name = "firmware-dev"
|
||||
name = "firmware"
|
||||
version = "0.1.0"
|
||||
|
||||
[dependencies]
|
||||
|
@ -34,7 +34,7 @@ name = "fpga_config"
|
|||
|
||||
# this lets you use `cargo fix`!
|
||||
[[bin]]
|
||||
name = "firmware-dev"
|
||||
name = "firmware"
|
||||
test = false
|
||||
bench = false
|
||||
|
||||
|
|
151
src/cpld.rs
151
src/cpld.rs
|
@ -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))
|
||||
}
|
||||
}
|
154
src/lib.rs
154
src/lib.rs
|
@ -1,7 +1,153 @@
|
|||
#![no_std]
|
||||
|
||||
mod cpld;
|
||||
pub use cpld::{CPLDData, CPLD, Error};
|
||||
use stm32h7xx_hal::{
|
||||
hal::{
|
||||
digital::v2::{
|
||||
InputPin,
|
||||
OutputPin,
|
||||
},
|
||||
blocking::spi::Transfer,
|
||||
spi::FullDuplex,
|
||||
},
|
||||
pac,
|
||||
prelude::*,
|
||||
spi,
|
||||
};
|
||||
|
||||
mod spi_slave;
|
||||
pub use spi_slave::{SPISlave, Parts};
|
||||
use core::cell;
|
||||
|
||||
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))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ use cortex_m_semihosting::hprintln;
|
|||
use core::ptr;
|
||||
use nb::block;
|
||||
|
||||
mod cpld;
|
||||
use firmware::CPLD;
|
||||
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
|
@ -73,7 +73,7 @@ fn main() -> ! {
|
|||
|
||||
let mut data :u8 = 0xAD;
|
||||
|
||||
let mut switch = cpld::CPLD::new(spi, (
|
||||
let mut switch = CPLD::new(spi, (
|
||||
gpiob.pb12.into_push_pull_output(),
|
||||
gpioa.pa15.into_push_pull_output(),
|
||||
gpioc.pc7.into_push_pull_output(),
|
||||
|
|
|
@ -13,7 +13,7 @@ use stm32h7xx_hal::{
|
|||
|
||||
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> (
|
||||
&'a DEV,
|
||||
|
|
Loading…
Reference in New Issue