Compare commits

..

No commits in common. "d78f85721f205abb2f4557ca56cdaf4c2f2f4fe2" and "081622006558584d8f0fe30a88862bae900dd4cf" have entirely different histories.

7 changed files with 184 additions and 353 deletions

View File

@ -15,6 +15,7 @@ stm32h7xx-hal = {version = "0.6.0", features = [ "stm32h743v", "rt", "unproven"
stm32h7-ethernet = { version = "0.2.0", features = [ "phy_lan8742a", "stm32h743v" ] } 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" ] } smoltcp = { version = "0.6.0", default-features = false, features = [ "ethernet", "proto-ipv4", "proto-ipv6", "socket-raw" ] }
nb = "1.0.0" nb = "1.0.0"
# scpi = {path = "../scpi-rs/scpi", version = "0.3.4"}
scpi = { git = "https://github.com/occheung/scpi-rs", branch = "issue-4" } scpi = { git = "https://github.com/occheung/scpi-rs", branch = "issue-4" }
lexical-core = { version="0.7.1", features=["radix"], default-features=false } lexical-core = { version="0.7.1", features=["radix"], default-features=false }
libm = { version = "0.2.0" } libm = { version = "0.2.0" }

View File

@ -24,12 +24,9 @@ extern crate smoltcp;
extern crate stm32h7_ethernet as ethernet; extern crate stm32h7_ethernet as ethernet;
use stm32h7xx_hal::gpio::Speed; use stm32h7xx_hal::gpio::Speed;
use stm32h7xx_hal::hal::digital::v2::{ use stm32h7xx_hal::hal::digital::v2::OutputPin;
OutputPin,
InputPin,
};
use stm32h7xx_hal::rcc::CoreClocks; use stm32h7xx_hal::rcc::CoreClocks;
use stm32h7xx_hal::{pac, prelude::*, spi, stm32, stm32::interrupt}; use stm32h7xx_hal::{pac, prelude::*, stm32, stm32::interrupt};
use Speed::*; use Speed::*;
use libm::round; use libm::round;
@ -58,24 +55,7 @@ use smoltcp::socket::SocketSet;
use smoltcp::socket::{SocketHandle, TcpSocket, TcpSocketBuffer}; use smoltcp::socket::{SocketHandle, TcpSocket, TcpSocketBuffer};
use smoltcp::time::{Duration, Instant}; use smoltcp::time::{Duration, Instant};
use firmware; use firmware::scpi::{MyDevice, TREE};
use firmware::{
attenuator::Attenuator,
config_register::{
ConfigRegister,
CFGMask,
StatusMask,
},
dds::{
DDS,
DDSCFRMask,
},
cpld::{
CPLD,
},
scpi::TREE,
Urukul,
};
use scpi::prelude::*; use scpi::prelude::*;
/// Configure SYSTICK for 1ms timebase /// Configure SYSTICK for 1ms timebase
@ -131,7 +111,6 @@ fn main() -> ! {
.sys_ck(200.mhz()) .sys_ck(200.mhz())
.hclk(200.mhz()) .hclk(200.mhz())
.pll1_r_ck(100.mhz()) // for TRACECK .pll1_r_ck(100.mhz()) // for TRACECK
.pll1_q_ck(48.mhz())
.freeze(vos, &dp.SYSCFG); .freeze(vos, &dp.SYSCFG);
// Get the delay provider. // Get the delay provider.
@ -148,65 +127,14 @@ fn main() -> ! {
let gpioa = dp.GPIOA.split(ccdr.peripheral.GPIOA); let gpioa = dp.GPIOA.split(ccdr.peripheral.GPIOA);
let gpiob = dp.GPIOB.split(ccdr.peripheral.GPIOB); let gpiob = dp.GPIOB.split(ccdr.peripheral.GPIOB);
let gpioc = dp.GPIOC.split(ccdr.peripheral.GPIOC); let gpioc = dp.GPIOC.split(ccdr.peripheral.GPIOC);
let gpiod = dp.GPIOD.split(ccdr.peripheral.GPIOD);
let gpioe = dp.GPIOE.split(ccdr.peripheral.GPIOE); let gpioe = dp.GPIOE.split(ccdr.peripheral.GPIOE);
let gpiof = dp.GPIOF.split(ccdr.peripheral.GPIOF);
let gpiog = dp.GPIOG.split(ccdr.peripheral.GPIOG); let gpiog = dp.GPIOG.split(ccdr.peripheral.GPIOG);
// let mut link_led = gpiob.pb0.into_push_pull_output(); // LED1, green let mut link_led = gpiob.pb0.into_push_pull_output(); // LED1, green
// let mut status_led = gpioe.pe1.into_push_pull_output(); // LD2, yellow let mut status_led = gpioe.pe1.into_push_pull_output(); // LD2, yellow
// let mut listen_led = gpiob.pb14.into_push_pull_output(); // LD3, red let mut listen_led = gpiob.pb14.into_push_pull_output(); // LD3, red
// link_led.set_low().ok(); link_led.set_low().ok();
// status_led.set_low().ok(); status_led.set_low().ok();
// listen_led.set_low().ok(); listen_led.set_low().ok();
// Setup CDONE for checking
let fpga_cdone = gpiod.pd15.into_pull_up_input();
match fpga_cdone.is_high() {
Ok(true) => hprintln!("FPGA is ready."),
Ok(_) => hprintln!("FPGA is in reset state."),
Err(_) => hprintln!("Error: Cannot read C_DONE"),
}.unwrap();
// Setup Urukul
/*
* Using SPI1, AF5
* SCLK -> PA5
* MOSI -> PB5
* MISO -> PA6
* CS -> 0: PB12, 1: PA15, 2: PC7
*/
let sclk = gpioa.pa5.into_alternate_af5();
let mosi = gpiob.pb5.into_alternate_af5();
let miso = gpioa.pa6.into_alternate_af5();
let (cs0, cs1, cs2) = (
gpiob.pb12.into_push_pull_output(),
gpioa.pa15.into_push_pull_output(),
gpioc.pc7.into_push_pull_output(),
);
/*
* I/O_Update -> PB15
*/
let io_update = gpiob.pb15.into_push_pull_output();
let spi = dp.SPI1.spi(
(sclk, miso, mosi),
spi::MODE_0,
3.mhz(),
ccdr.peripheral.SPI1,
&ccdr.clocks,
);
let switch = CPLD::new(spi, (cs0, cs1, cs2), io_update);
let parts = switch.split();
let mut urukul = Urukul::new(
parts.spi1, parts.spi2, parts.spi3, parts.spi4, parts.spi5, parts.spi6, parts.spi7,
[25_000_000, 25_000_000, 25_000_000, 25_000_000]
);
// Setup ethernet pins // Setup ethernet pins
setup_ethernet_pins( setup_ethernet_pins(
@ -264,17 +192,18 @@ fn main() -> ! {
.finalize(); .finalize();
// SCPI configs // SCPI configs
// Device was declared in prior let mut my_device = MyDevice {};
let mut errors = ArrayErrorQueue::<[Error; 10]>::new(); let mut errors = ArrayErrorQueue::<[Error; 10]>::new();
let mut context = Context::new(&mut urukul, &mut errors, TREE); let mut context = Context::new(&mut my_device, &mut errors, TREE);
//Response bytebuffer //Response bytebuffer
let mut buf = ArrayVecFormatter::<[u8; 256]>::new(); let mut buf = ArrayVecFormatter::<[u8; 256]>::new();
// SCPI configs END // SCPI configs END
// TCP socket buffers // TODO: Need Iinitialize TCP socket storage?
// Yes cannot into vectors
let mut rx_storage = [0; BUFFER_SIZE]; let mut rx_storage = [0; BUFFER_SIZE];
let mut tx_storage = [0; BUFFER_SIZE]; let mut tx_storage = [0; BUFFER_SIZE];
@ -313,9 +242,11 @@ fn main() -> ! {
match iface.poll(&mut sockets, Instant::from_millis(_time as i64)) { match iface.poll(&mut sockets, Instant::from_millis(_time as i64)) {
Ok(_) => { Ok(_) => {
eth_up = true; eth_up = true;
link_led.set_high().unwrap();
}, },
Err(e) => { Err(e) => {
eth_up = false; eth_up = false;
link_led.set_low().unwrap();
}, },
}; };
@ -327,6 +258,16 @@ fn main() -> ! {
socket.set_timeout(Some(Duration::from_millis(5000))); socket.set_timeout(Some(Duration::from_millis(5000)));
} }
match socket.is_listening() {
false => listen_led.set_low().unwrap(),
_ => listen_led.set_high().unwrap(),
};
match socket.is_active() {
true => status_led.set_high().unwrap(),
_ => status_led.set_low().unwrap(),
};
if socket.can_recv() && receive_and_not_send { if socket.can_recv() && receive_and_not_send {
let data = socket.recv(|buffer| { let data = socket.recv(|buffer| {
(buffer.len(), buffer) (buffer.len(), buffer)
@ -352,7 +293,11 @@ fn main() -> ! {
socket.set_timeout(Some(Duration::from_millis(1000000))); socket.set_timeout(Some(Duration::from_millis(1000000)));
} }
if socket.can_recv() { if socket.can_recv() {
// hprintln!("{:?}", socket.recv(|buffer| {
// (buffer.len(), str::from_utf8(buffer).unwrap())
// })).unwrap();
let result = context.run(socket.recv(|buffer| { let result = context.run(socket.recv(|buffer| {
(buffer.len(), buffer) (buffer.len(), buffer)
}).unwrap(), &mut buf); }).unwrap(), &mut buf);
@ -360,6 +305,7 @@ fn main() -> ! {
writeln!(socket, "{}", str::from_utf8(err.get_message()).unwrap()); writeln!(socket, "{}", str::from_utf8(err.get_message()).unwrap());
} else { } else {
write!(socket, "{}", str::from_utf8(buf.as_slice()).unwrap()); write!(socket, "{}", str::from_utf8(buf.as_slice()).unwrap());
//break;
} }
} }
} }

View File

@ -1,165 +0,0 @@
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<SPI, CS0, CS1, CS2, GPIO> {
pub(crate) spi: SPI,
pub(crate) chip_select: (CS0, CS1, CS2),
pub(crate) io_update: GPIO,
}
#[derive(Debug)]
pub struct CPLD<SPI, CS0, CS1, CS2, GPIO> {
pub(crate) data: cell::RefCell<CPLDData<SPI, CS0, CS1, CS2, GPIO>>,
}
pub trait SelectChip {
type Error;
fn select_chip(&mut self, chip: u8) -> Result<(), Self::Error>;
}
impl<SPI, CS0, CS1, CS2, GPIO, E> SelectChip for CPLDData<SPI, CS0, CS1, CS2, GPIO>
where
SPI: Transfer<u8, Error = E>,
CS0: OutputPin,
CS1: OutputPin,
CS2: OutputPin,
GPIO: 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 IssueIOUpdate {
type Error;
fn issue_io_update(&mut self) -> Result<(), Self::Error>;
}
impl<SPI, CS0, CS1, CS2, GPIO, E> IssueIOUpdate for CPLDData<SPI, CS0, CS1, CS2, GPIO>
where
SPI: Transfer<u8>,
CS0: OutputPin,
CS1: OutputPin,
CS2: OutputPin,
GPIO: OutputPin<Error = E>,
{
type Error = Error<E>;
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<SPI, CS0, CS1, CS2, GPIO> {
fn do_on_get_ref_mut_data<R, E>(
&self,
f: impl FnOnce(cell::RefMut<CPLDData<SPI, CS0, CS1, CS2, GPIO>>) -> Result<R, Error<E>>,
) -> Result<R, Error<E>>;
}
impl<SPI, CS0, CS1, CS2, GPIO> DoOnGetRefMutData<SPI, CS0, CS1, CS2, GPIO> for CPLD<SPI, CS0, CS1, CS2, GPIO> {
fn do_on_get_ref_mut_data<R, E>(
&self,
f: impl FnOnce(cell::RefMut<CPLDData<SPI, CS0, CS1, CS2, GPIO>>) -> 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, GPIO, E> Transfer<u8> for CPLD<SPI, CS0, CS1, CS2, GPIO>
where
SPI: Transfer<u8, Error = E>,
CS0: OutputPin,
CS1: OutputPin,
CS2: OutputPin,
GPIO: 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, GPIO, E> CPLD<SPI, CS0, CS1, CS2, GPIO> where
SPI: Transfer<u8, Error = E>,
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>, SPI, CS0, CS1, CS2, GPIO> {
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))
}
}
impl<SPI, CS0, CS1, CS2, GPIO, E> CPLD<SPI, CS0, CS1, CS2, GPIO>
where
SPI: Transfer<u8>,
CS0: OutputPin,
CS1: OutputPin,
CS2: OutputPin,
GPIO: OutputPin<Error = E>
{
// Issue I/O Update
pub fn issue_io_update(&mut self) -> Result<(), Error<E>> {
self.do_on_get_ref_mut_data(|mut dev| dev.issue_io_update())
}
}

View File

@ -4,10 +4,9 @@ use embedded_hal::{
digital::v2::OutputPin, digital::v2::OutputPin,
blocking::spi::Transfer, blocking::spi::Transfer,
}; };
use core::{
cell, use core::cell;
marker::PhantomData,
};
use cortex_m; use cortex_m;
use cortex_m_semihosting::hprintln; use cortex_m_semihosting::hprintln;
@ -15,24 +14,11 @@ use cortex_m_semihosting::hprintln;
pub mod bitmask_macro; pub mod bitmask_macro;
pub mod spi_slave; pub mod spi_slave;
use crate::spi_slave::{ use crate::spi_slave::Parts;
Parts,
SPISlave,
};
pub mod cpld;
use crate::cpld::CPLD;
use crate::cpld::DoOnGetRefMutData;
pub mod config_register; pub mod config_register;
use crate::config_register::ConfigRegister;
pub mod attenuator; pub mod attenuator;
use crate::attenuator::Attenuator;
pub mod dds; pub mod dds;
use crate::dds::DDS;
pub mod scpi; pub mod scpi;
/* /*
@ -49,86 +35,158 @@ pub enum Error<E> {
} }
/* /*
* Struct for Urukul master device * Basic structure for CPLD signal multiplexing
*/ */
pub struct Urukul<SPI> { #[derive(Debug)]
config_register: ConfigRegister<SPI>, pub struct CPLDData<SPI, CS0, CS1, CS2, GPIO> {
attenuator: Attenuator<SPI>, pub(crate) spi: SPI,
dds: [DDS<SPI>; 4], pub(crate) chip_select: (CS0, CS1, CS2),
pub(crate) io_update: GPIO,
} }
impl<SPI, E> Urukul<SPI> #[derive(Debug)]
pub struct CPLD<SPI, CS0, CS1, CS2, GPIO> {
pub(crate) data: cell::RefCell<CPLDData<SPI, CS0, CS1, CS2, GPIO>>,
}
pub trait SelectChip {
type Error;
fn select_chip(&mut self, chip: u8) -> Result<(), Self::Error>;
}
impl<SPI, CS0, CS1, CS2, GPIO, E> SelectChip for CPLDData<SPI, CS0, CS1, CS2, GPIO>
where where
SPI: Transfer<u8, Error = E>, SPI: Transfer<u8, Error = E>,
CS0: OutputPin,
CS1: OutputPin,
CS2: OutputPin,
GPIO: OutputPin,
{ {
/* type Error = Error<E>;
* Master constructor for the entire Urukul device fn select_chip(&mut self, chip: u8) -> Result<(), Self::Error> {
* Supply 7 SPI channels to Urukul and 4 reference clock frequencies match chip & (1 << 0) {
*/ 0 => self.chip_select.0.set_low(),
pub fn new(spi1: SPI, spi2: SPI, spi3: SPI, spi4: SPI, spi5: SPI, spi6: SPI, spi7: SPI, f_ref_clks: [u64; 4]) -> Self { _ => self.chip_select.0.set_high(),
// Construct Urukul }.map_err(|_| Error::CSError)?;
Urukul { match chip & (1 << 1) {
config_register: ConfigRegister::new(spi1), 0 => self.chip_select.1.set_low(),
attenuator: Attenuator::new(spi2), _ => self.chip_select.1.set_high(),
dds: [ }.map_err(|_| Error::CSError)?;
DDS::new(spi4, f_ref_clks[1]), match chip & (1 << 2) {
DDS::new(spi5, f_ref_clks[1]), 0 => self.chip_select.2.set_low(),
DDS::new(spi6, f_ref_clks[2]), _ => self.chip_select.2.set_high(),
DDS::new(spi7, f_ref_clks[3]), }.map_err(|_| Error::CSError)?;
], Ok(())
} }
} }
trait IssueIOUpdate {
type Error;
fn issue_io_update(&mut self) -> Result<(), Self::Error>;
} }
// /* impl<SPI, CS0, CS1, CS2, GPIO, E> IssueIOUpdate for CPLDData<SPI, CS0, CS1, CS2, GPIO>
// * Struct for a better Urukul master device where
// */ SPI: Transfer<u8>,
// pub struct BetterUrukul<'a, SPI, CS0, CS1, CS2, GPIO> { CS0: OutputPin,
// cpld: CPLD<SPI, CS0, CS1, CS2, GPIO>, CS1: OutputPin,
// parts: Option<Parts<'a, CPLD<SPI, CS0, CS1, CS2, GPIO>, SPI, CS0, CS1, CS2, GPIO>>, CS2: OutputPin,
// config_register: Option<ConfigRegister<SPISlave<'a, CPLD<SPI, CS0, CS1, CS2, GPIO>, SPI, CS0, CS1, CS2, GPIO>>>, GPIO: OutputPin<Error = E>,
// attenuator: Option<Attenuator<SPISlave<'a, CPLD<SPI, CS0, CS1, CS2, GPIO>, SPI, CS0, CS1, CS2, GPIO>>>, {
// dds: [Option<DDS<SPISlave<'a, CPLD<SPI, CS0, CS1, CS2, GPIO>, SPI, CS0, CS1, CS2, GPIO>>>; 4], type Error = Error<E>;
// }
// impl<'a, SPI, CS0, CS1, CS2, GPIO> BetterUrukul<'a, SPI, CS0, CS1, CS2, GPIO> fn issue_io_update(&mut self) -> Result<(), Self::Error> {
// where self.io_update.set_high().map_err(|_| Error::IOUpdateError)?;
// SPI: Transfer<u8>, self.io_update.set_low().map_err(|_| Error::IOUpdateError)
// CS0: OutputPin, }
// CS1: OutputPin, }
// CS2: OutputPin,
// GPIO: OutputPin,
// {
// pub fn new(spi: SPI, chip_select: (CS0, CS1, CS2), io_update: GPIO) -> Self {
// // let switch = CPLD::new(spi, chip_select, io_update);
// // let parts = switch.split();
// // Construct Urukul pub trait DoOnGetRefMutData<SPI, CS0, CS1, CS2, GPIO> {
// BetterUrukul { fn do_on_get_ref_mut_data<R, E>(
// cpld: CPLD::new(spi, chip_select, io_update), &self,
// // parts: CPLD::new(spi, chip_select, io_update).split(), f: impl FnOnce(cell::RefMut<CPLDData<SPI, CS0, CS1, CS2, GPIO>>) -> Result<R, Error<E>>,
// // config_register: ConfigRegister::new(self.parts.spi1), ) -> Result<R, Error<E>>;
// // attenuator: Attenuator::new(self.parts.spi2), }
// // dds: [
// // DDS::new(self.parts.spi4, f_ref_clks[1]), impl<SPI, CS0, CS1, CS2, GPIO> DoOnGetRefMutData<SPI, CS0, CS1, CS2, GPIO> for CPLD<SPI, CS0, CS1, CS2, GPIO> {
// // DDS::new(self.parts.spi5, f_ref_clks[1]), fn do_on_get_ref_mut_data<R, E>(
// // DDS::new(self.parts.spi6, f_ref_clks[2]), &self,
// // DDS::new(self.parts.spi7, f_ref_clks[3]), f: impl FnOnce(cell::RefMut<CPLDData<SPI, CS0, CS1, CS2, GPIO>>) -> Result<R, Error<E>>,
// // ], ) -> Result<R, Error<E>> {
// parts: None, let dev = self
// config_register: None, .data
// attenuator: None, .try_borrow_mut()
// dds: [None, None, None, None], .map_err(|_| Error::GetRefMutDataError)?;
// } f(dev)
// } }
}
impl<SPI, CS0, CS1, CS2, GPIO, E> Transfer<u8> for CPLD<SPI, CS0, CS1, CS2, GPIO>
where
SPI: Transfer<u8, Error = E>,
CS0: OutputPin,
CS1: OutputPin,
CS2: OutputPin,
GPIO: 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, GPIO, E> CPLD<SPI, CS0, CS1, CS2, GPIO> where
SPI: Transfer<u8, Error = E>,
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>, SPI, CS0, CS1, CS2, GPIO> {
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))
}
}
impl<SPI, CS0, CS1, CS2, GPIO, E> CPLD<SPI, CS0, CS1, CS2, GPIO>
where
SPI: Transfer<u8>,
CS0: OutputPin,
CS1: OutputPin,
CS2: OutputPin,
GPIO: OutputPin<Error = E>
{
// Issue I/O Update
pub fn issue_io_update(&mut self) -> Result<(), Error<E>> {
self.do_on_get_ref_mut_data(|mut dev| dev.issue_io_update())
}
}
// pub fn init(&'a mut self, f_ref_clks:[u64; 4]) {
// self.parts = Some(self.cpld.split());
// self.config_register = Some(ConfigRegister::new(self.parts.unwrap().spi1));
// self.attenuator = Some(Attenuator::new(self.parts.unwrap().spi2));
// self.dds[0] = Some(DDS::new(self.parts.unwrap().spi4, f_ref_clks[0]));
// self.dds[1] = Some(DDS::new(self.parts.unwrap().spi5, f_ref_clks[1]));
// self.dds[2] = Some(DDS::new(self.parts.unwrap().spi6, f_ref_clks[2]));
// self.dds[3] = Some(DDS::new(self.parts.unwrap().spi7, f_ref_clks[3]));
// }
// }

View File

@ -15,6 +15,7 @@ use cortex_m_semihosting::hprintln;
use firmware; use firmware;
use firmware::{ use firmware::{
CPLD,
attenuator::Attenuator, attenuator::Attenuator,
config_register::{ config_register::{
ConfigRegister, ConfigRegister,
@ -25,9 +26,6 @@ use firmware::{
DDS, DDS,
DDSCFRMask, DDSCFRMask,
}, },
cpld::{
CPLD,
}
}; };
#[entry] #[entry]
@ -83,7 +81,7 @@ fn main() -> ! {
); );
/* /*
* I/O_Update -> PB15 * I/O_Update -> PB13
*/ */
let io_update = gpiob.pb15.into_push_pull_output(); let io_update = gpiob.pb15.into_push_pull_output();

View File

@ -28,9 +28,7 @@ use scpi::{
scpi_tree, scpi_tree,
}; };
use crate::Urukul; pub struct MyDevice;
// pub struct MyDevice;
pub struct HelloWorldCommand {} pub struct HelloWorldCommand {}
impl Command for HelloWorldCommand { impl Command for HelloWorldCommand {
@ -46,11 +44,7 @@ impl Command for HelloWorldCommand {
} }
} }
/* impl Device for MyDevice {
* Implement "Device" trait from SCPI
* TODO: Implement mandatory commands
*/
impl<SPI> Device for Urukul<SPI> {
fn cls(&mut self) -> Result<()> { fn cls(&mut self) -> Result<()> {
Ok(()) Ok(())
} }

View File

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