diff --git a/Cargo.toml b/Cargo.toml index 3990888..7382304 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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 diff --git a/src/cpld.rs b/src/cpld.rs deleted file mode 100644 index 6fca3f7..0000000 --- a/src/cpld.rs +++ /dev/null @@ -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 { - SPI(E), - CSError, - GetRefMutDataError, -} - -/* - * Basic structure for CPLD signal multiplexing - */ -#[derive(Debug)] -pub struct CPLDData { - pub(crate) spi: SPI, - pub(crate) chip_select: (CS0, CS1, CS2), -} - -#[derive(Debug)] -pub struct CPLD { - pub(crate) data: cell::RefCell>, -} - -pub trait SelectChip { - type Error; - fn select_chip(&mut self, chip: u8) -> Result<(), Self::Error>; -} - -impl SelectChip for CPLDData -where - SPI: Transfer, - CS0: OutputPin, - CS1: OutputPin, - CS2: OutputPin, -{ - type Error = Error; - 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 { - fn do_on_get_ref_mut_data( - &self, - f: impl FnOnce(cell::RefMut>) -> Result>, - ) -> Result>; -} - -impl DoOnGetRefMutData for CPLD { - fn do_on_get_ref_mut_data( - &self, - f: impl FnOnce(cell::RefMut>) -> Result>, - ) -> Result> { - let dev = self - .data - .try_borrow_mut() - .map_err(|_| Error::GetRefMutDataError)?; - f(dev) - } -} - -impl Transfer for CPLD -where - SPI: Transfer, - CS0: OutputPin, - CS1: OutputPin, - CS2: OutputPin, -{ - type Error = Error; - - 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 CPLD where - SPI: Transfer, - 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> { - Parts::new(&self) - } - - // Select Chip - pub fn select_chip(&mut self, channel: u8) -> Result<(), Error> { - self.do_on_get_ref_mut_data(|mut dev| dev.select_chip(channel)) - } -} diff --git a/src/lib.rs b/src/lib.rs index 7392c21..dd52938 100644 --- a/src/lib.rs +++ b/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 { + SPI(E), + CSError, + GetRefMutDataError, +} + +/* + * Basic structure for CPLD signal multiplexing + */ +#[derive(Debug)] +pub struct CPLDData { + pub(crate) spi: SPI, + pub(crate) chip_select: (CS0, CS1, CS2), +} + +#[derive(Debug)] +pub struct CPLD { + pub(crate) data: cell::RefCell>, +} + +pub trait SelectChip { + type Error; + fn select_chip(&mut self, chip: u8) -> Result<(), Self::Error>; +} + +impl SelectChip for CPLDData +where + SPI: Transfer, + CS0: OutputPin, + CS1: OutputPin, + CS2: OutputPin, +{ + type Error = Error; + 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 { + fn do_on_get_ref_mut_data( + &self, + f: impl FnOnce(cell::RefMut>) -> Result>, + ) -> Result>; +} + +impl DoOnGetRefMutData for CPLD { + fn do_on_get_ref_mut_data( + &self, + f: impl FnOnce(cell::RefMut>) -> Result>, + ) -> Result> { + let dev = self + .data + .try_borrow_mut() + .map_err(|_| Error::GetRefMutDataError)?; + f(dev) + } +} + +impl Transfer for CPLD +where + SPI: Transfer, + CS0: OutputPin, + CS1: OutputPin, + CS2: OutputPin, +{ + type Error = Error; + + 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 CPLD where + SPI: Transfer, + 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> { + Parts::new(&self) + } + + // Select Chip + pub fn select_chip(&mut self, channel: u8) -> Result<(), Error> { + self.do_on_get_ref_mut_data(|mut dev| dev.select_chip(channel)) + } +} diff --git a/src/main.rs b/src/main.rs index b744aac..5eab81d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -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(), diff --git a/src/spi_slave.rs b/src/spi_slave.rs index 44baeaf..48e5d78 100644 --- a/src/spi_slave.rs +++ b/src/spi_slave.rs @@ -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,