From 4852fc54ea5418745655d46748ba34aa5062ad26 Mon Sep 17 00:00:00 2001 From: occheung Date: Mon, 31 Aug 2020 09:31:56 +0800 Subject: [PATCH] cpld: detach from lib.rs --- Cargo.toml | 1 - src/cpld.rs | 165 +++++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 163 +--------------------------------------------- src/main.rs | 4 +- src/spi_slave.rs | 3 +- 5 files changed, 172 insertions(+), 164 deletions(-) create mode 100644 src/cpld.rs diff --git a/Cargo.toml b/Cargo.toml index 41e4a57..b4cb8d6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,6 @@ stm32h7xx-hal = {version = "0.6.0", features = [ "stm32h743v", "rt", "unproven" stm32h7-ethernet = { version = "0.2.0", features = [ "phy_lan8742a", "stm32h743v" ] } smoltcp = { version = "0.6.0", default-features = false, features = [ "ethernet", "proto-ipv4", "proto-ipv6", "socket-raw" ] } nb = "1.0.0" -# scpi = {path = "../scpi-rs/scpi", version = "0.3.4"} scpi = { git = "https://github.com/occheung/scpi-rs", branch = "issue-4" } lexical-core = { version="0.7.1", features=["radix"], default-features=false } libm = { version = "0.2.0" } diff --git a/src/cpld.rs b/src/cpld.rs new file mode 100644 index 0000000..504bf04 --- /dev/null +++ b/src/cpld.rs @@ -0,0 +1,165 @@ +use crate::Error; +use crate::spi_slave::Parts; + +use embedded_hal::{ + digital::v2::OutputPin, + blocking::spi::Transfer, +}; + +use core::cell; + +/* + * Basic structure for CPLD signal multiplexing + */ + #[derive(Debug)] + pub struct CPLDData { + pub(crate) spi: SPI, + pub(crate) chip_select: (CS0, CS1, CS2), + pub(crate) io_update: GPIO, + } + + #[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, + GPIO: 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 IssueIOUpdate { + type Error; + fn issue_io_update(&mut self) -> Result<(), Self::Error>; + } + + impl IssueIOUpdate for CPLDData + where + SPI: Transfer, + CS0: OutputPin, + CS1: OutputPin, + CS2: OutputPin, + GPIO: OutputPin, + { + type Error = Error; + + fn issue_io_update(&mut self) -> Result<(), Self::Error> { + self.io_update.set_high().map_err(|_| Error::IOUpdateError)?; + self.io_update.set_low().map_err(|_| Error::IOUpdateError) + } + } + + 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, + GPIO: 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, + GPIO: OutputPin + { + // Constructor for CPLD + pub fn new(spi: SPI, chip_select: (CS0, CS1, CS2), io_update: GPIO) -> Self { + + // Init data + let data = CPLDData { + spi, + chip_select, + io_update, + }; + + // Init CPLD + CPLD { + data: cell::RefCell::new(data), + } + } + + // Destroy the wrapper, return the CPLD data + pub fn destroy(self) -> (SPI, (CS0, CS1, CS2), GPIO) { + let cpld = self.data.into_inner(); + (cpld.spi, cpld.chip_select, cpld.io_update) + } + + // Split SPI into chips, wrapped by Parts struct + pub fn split<'a>(&'a self) -> Parts<'a, CPLD, SPI, CS0, CS1, CS2, GPIO> { + 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)) + } + } + + impl CPLD + where + SPI: Transfer, + CS0: OutputPin, + CS1: OutputPin, + CS2: OutputPin, + GPIO: OutputPin + { + // Issue I/O Update + pub fn issue_io_update(&mut self) -> Result<(), Error> { + self.do_on_get_ref_mut_data(|mut dev| dev.issue_io_update()) + } + } \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index 0beeb4e..1e0b61e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,9 +1,5 @@ #![no_std] extern crate embedded_hal; -use embedded_hal::{ - digital::v2::OutputPin, - blocking::spi::Transfer, -}; use core::cell; @@ -16,6 +12,8 @@ pub mod bitmask_macro; pub mod spi_slave; use crate::spi_slave::Parts; +pub mod cpld; + pub mod config_register; pub mod attenuator; pub mod dds; @@ -33,160 +31,3 @@ pub enum Error { IOUpdateError, DDSError, } - -/* - * Basic structure for CPLD signal multiplexing - */ -#[derive(Debug)] -pub struct CPLDData { - pub(crate) spi: SPI, - pub(crate) chip_select: (CS0, CS1, CS2), - pub(crate) io_update: GPIO, -} - -#[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, - GPIO: 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(()) - } -} - -trait IssueIOUpdate { - type Error; - fn issue_io_update(&mut self) -> Result<(), Self::Error>; -} - -impl IssueIOUpdate for CPLDData -where - SPI: Transfer, - CS0: OutputPin, - CS1: OutputPin, - CS2: OutputPin, - GPIO: OutputPin, -{ - type Error = Error; - - fn issue_io_update(&mut self) -> Result<(), Self::Error> { - self.io_update.set_high().map_err(|_| Error::IOUpdateError)?; - self.io_update.set_low().map_err(|_| Error::IOUpdateError) - } -} - -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, - GPIO: 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, - GPIO: OutputPin -{ - // Constructor for CPLD - pub fn new(spi: SPI, chip_select: (CS0, CS1, CS2), io_update: GPIO) -> Self { - - // Init data - let data = CPLDData { - spi, - chip_select, - io_update, - }; - - // Init CPLD - CPLD { - data: cell::RefCell::new(data), - } - } - - // Destroy the wrapper, return the CPLD data - pub fn destroy(self) -> (SPI, (CS0, CS1, CS2), GPIO) { - let cpld = self.data.into_inner(); - (cpld.spi, cpld.chip_select, cpld.io_update) - } - - // Split SPI into chips, wrapped by Parts struct - pub fn split<'a>(&'a self) -> Parts<'a, CPLD, SPI, CS0, CS1, CS2, GPIO> { - 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)) - } -} - -impl CPLD -where - SPI: Transfer, - CS0: OutputPin, - CS1: OutputPin, - CS2: OutputPin, - GPIO: OutputPin -{ - // Issue I/O Update - pub fn issue_io_update(&mut self) -> Result<(), Error> { - self.do_on_get_ref_mut_data(|mut dev| dev.issue_io_update()) - } -} - diff --git a/src/main.rs b/src/main.rs index 2541b54..aad2e74 100644 --- a/src/main.rs +++ b/src/main.rs @@ -15,7 +15,6 @@ use cortex_m_semihosting::hprintln; use firmware; use firmware::{ - CPLD, attenuator::Attenuator, config_register::{ ConfigRegister, @@ -26,6 +25,9 @@ use firmware::{ DDS, DDSCFRMask, }, + cpld::{ + CPLD, + } }; #[entry] diff --git a/src/spi_slave.rs b/src/spi_slave.rs index ded1c3c..cf46a8a 100644 --- a/src/spi_slave.rs +++ b/src/spi_slave.rs @@ -4,7 +4,8 @@ use embedded_hal::{ }; use core::marker::PhantomData; -use crate::{DoOnGetRefMutData, Error, SelectChip, IssueIOUpdate}; +use crate::cpld::{DoOnGetRefMutData, SelectChip, IssueIOUpdate}; +use crate::Error; pub struct SPISlave<'a, DEV: 'a, SPI, CS0, CS1, CS2, GPIO> ( &'a DEV,