Adding refactor to support pounder hardware abstractions
This commit is contained in:
parent
87858a6e0a
commit
abf22676ce
94
Cargo.lock
generated
94
Cargo.lock
generated
@ -1,5 +1,19 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "ad9959"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/quartiq/ad9959.git?branch=feature/basic-driver#71f96bab751048aa944490b4b56463551025a21f"
|
||||
dependencies = [
|
||||
"bit_field 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"embedded-hal 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aligned"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "aligned"
|
||||
version = "0.3.2"
|
||||
@ -18,6 +32,16 @@ dependencies = [
|
||||
"stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "asm-delay"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bitrate 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cortex-m 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"embedded-hal 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.0.0"
|
||||
@ -31,11 +55,21 @@ dependencies = [
|
||||
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bit_field"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "bitrate"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.3.4"
|
||||
@ -54,6 +88,17 @@ name = "cfg-if"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "cortex-m"
|
||||
version = "0.5.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"aligned 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bare-metal 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cortex-m 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"volatile-register 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cortex-m"
|
||||
version = "0.6.2"
|
||||
@ -189,6 +234,17 @@ name = "managed"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "mcp23017"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cast 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"embedded-hal 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"generic-array 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"nb 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nb"
|
||||
version = "0.1.2"
|
||||
@ -299,6 +355,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"managed 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@ -306,6 +363,8 @@ dependencies = [
|
||||
name = "stabilizer"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"ad9959 0.1.0 (git+https://github.com/quartiq/ad9959.git?branch=feature/basic-driver)",
|
||||
"asm-delay 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cortex-m 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cortex-m-log 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cortex-m-rt 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -313,12 +372,14 @@ dependencies = [
|
||||
"embedded-hal 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"heapless 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mcp23017 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"nb 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"panic-halt 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"panic-semihosting 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.106 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde-json-core 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"smoltcp 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"stm32h7-ethernet 0.1.1",
|
||||
"stm32h7xx-hal 0.4.0 (git+https://github.com/quartiq/stm32h7xx-hal.git?branch=feature/quad-spi)",
|
||||
]
|
||||
|
||||
@ -338,6 +399,16 @@ dependencies = [
|
||||
"vcell 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "stm32h7-ethernet"
|
||||
version = "0.1.1"
|
||||
dependencies = [
|
||||
"cortex-m 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"smoltcp 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"stm32h7xx-hal 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "stm32h7xx-hal"
|
||||
version = "0.4.0"
|
||||
@ -353,6 +424,21 @@ dependencies = [
|
||||
"void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "stm32h7xx-hal"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bare-metal 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cast 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cortex-m 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cortex-m-rt 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"embedded-hal 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"nb 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"stm32h7 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.17"
|
||||
@ -392,14 +478,20 @@ dependencies = [
|
||||
]
|
||||
|
||||
[metadata]
|
||||
"checksum ad9959 0.1.0 (git+https://github.com/quartiq/ad9959.git?branch=feature/basic-driver)" = "<none>"
|
||||
"checksum aligned 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d39da9b88ae1a81c03c9c082b8db83f1d0e93914126041962af61034ab44c4a5"
|
||||
"checksum aligned 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eb1ce8b3382016136ab1d31a1b5ce807144f8b7eb2d5f16b2108f0f07edceb94"
|
||||
"checksum as-slice 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "37dfb65bc03b2bc85ee827004f14a6817e04160e3b1a28931986a666a9290e70"
|
||||
"checksum asm-delay 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0e0c8eec73de29ae94b2aff405a272304bc286204ddb1cdf20d7e2249078ae20"
|
||||
"checksum autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d"
|
||||
"checksum bare-metal 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "5deb64efa5bd81e31fcd1938615a6d98c82eafcbcd787162b6f63b91d6bac5b3"
|
||||
"checksum bit_field 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a165d606cf084741d4ac3a28fb6e9b1eb0bd31f6cd999098cfddb0b2ab381dc0"
|
||||
"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
||||
"checksum bitrate 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c147d86912d04bef727828fda769a76ca81629a46d8ba311a8d58a26aa91473d"
|
||||
"checksum byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
|
||||
"checksum cast 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4b9434b9a5aa1450faa3f9cb14ea0e8c53bb5d2b3c1bfd1ab4fc03e9f33fbfb0"
|
||||
"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
||||
"checksum cortex-m 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "3c0b159a1e8306949579de3698c841dba58058197b65c60807194e4fa1e7a554"
|
||||
"checksum cortex-m 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2954942fbbdd49996704e6f048ce57567c3e1a4e2dc59b41ae9fde06a01fc763"
|
||||
"checksum cortex-m-log 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "978caafe65d1023d38b00c76b83564788fc351d954a5005fb72cf992c0d61458"
|
||||
"checksum cortex-m-rt 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "00d518da72bba39496024b62607c1d8e37bcece44b2536664f1132a73a499a28"
|
||||
@ -415,6 +507,7 @@ dependencies = [
|
||||
"checksum indexmap 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "076f042c5b7b98f31d205f1249267e12a6518c1481e9dae9764af19b707d2292"
|
||||
"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
|
||||
"checksum managed 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fdcec5e97041c7f0f1c5b7d93f12e57293c831c646f4cc7a5db59460c7ea8de6"
|
||||
"checksum mcp23017 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7f4854484a74b626165c3f3cf5e15bfee2898c6b4d6eccc3ed5ee634850af4dd"
|
||||
"checksum nb 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b1411551beb3c11dedfb0a90a0fa256b47d28b9ec2cdff34c25a2fa59e45dbdc"
|
||||
"checksum panic-halt 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de96540e0ebde571dc55c73d60ef407c653844e6f9a1e2fdbd40c07b9252d812"
|
||||
"checksum panic-semihosting 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c03864ac862876c16a308f5286f4aa217f1a69ac45df87ad3cd2847f818a642c"
|
||||
@ -433,6 +526,7 @@ dependencies = [
|
||||
"checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8"
|
||||
"checksum stm32h7 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e5b0045066e082648e8a7ab1dd45c92efa8d7bec2beedf72ac7b62563911f82a"
|
||||
"checksum stm32h7xx-hal 0.4.0 (git+https://github.com/quartiq/stm32h7xx-hal.git?branch=feature/quad-spi)" = "<none>"
|
||||
"checksum stm32h7xx-hal 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "689aff61a1cf43e03cf821c5540bb540e6bd04b374e486be23b035c0afc3c15f"
|
||||
"checksum syn 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)" = "0df0eb663f387145cab623dea85b09c2c5b4b0aef44e945d928e682fce71bb03"
|
||||
"checksum typenum 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33"
|
||||
"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
|
||||
|
18
Cargo.toml
18
Cargo.toml
@ -36,9 +36,25 @@ serde = { version = "1.0", features = ["derive"], default-features = false }
|
||||
heapless = "0.5"
|
||||
serde-json-core = "0.1"
|
||||
cortex-m-rtfm = "0.5"
|
||||
smoltcp = { version = "0.6", features = ["ethernet", "proto-ipv4", "socket-tcp"], default-features = false }
|
||||
embedded-hal = "0.2.3"
|
||||
nb = "0.1.2"
|
||||
asm-delay = "0.7.0"
|
||||
mcp23017 = "0.1.1"
|
||||
|
||||
[dependencies.smoltcp]
|
||||
version = "0.6"
|
||||
features = ["ethernet", "proto-ipv4", "socket-tcp", "proto-ipv6"]
|
||||
default-features = false
|
||||
|
||||
[dependencies.ad9959]
|
||||
git = "https://github.com/quartiq/ad9959.git"
|
||||
branch = "feature/basic-driver"
|
||||
|
||||
[dependencies.stm32h7-ethernet]
|
||||
#git = "https://github.com/quartiq/stm32h7-ethernet.git"
|
||||
#branch = "feature/device-dependency"
|
||||
path = "../stm32h7-ethernet"
|
||||
features = ["stm32h743v"]
|
||||
|
||||
[dependencies.stm32h7xx-hal]
|
||||
git = "https://github.com/quartiq/stm32h7xx-hal.git"
|
||||
|
302
src/main.rs
302
src/main.rs
@ -30,8 +30,10 @@ extern crate log;
|
||||
use nb;
|
||||
|
||||
// use core::sync::atomic::{AtomicU32, AtomicBool, Ordering};
|
||||
use asm_delay;
|
||||
use rtfm::cyccnt::{Instant, U32Ext};
|
||||
use cortex_m_rt::exception;
|
||||
use cortex_m::asm;
|
||||
use cortex_m;
|
||||
use stm32h7xx_hal as hal;
|
||||
use stm32h7xx_hal::{
|
||||
prelude::*,
|
||||
@ -42,15 +44,31 @@ use embedded_hal::{
|
||||
digital::v2::OutputPin,
|
||||
};
|
||||
|
||||
/*
|
||||
use core::fmt::Write;
|
||||
use heapless::{consts::*, String, Vec};
|
||||
use stm32h7_ethernet as ethernet;
|
||||
use smoltcp as net;
|
||||
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
||||
use serde_json_core::{de::from_slice, ser::to_string};
|
||||
*/
|
||||
|
||||
use core::fmt::Write;
|
||||
use heapless::{
|
||||
consts::*,
|
||||
String,
|
||||
//Vec
|
||||
};
|
||||
|
||||
use serde::{
|
||||
//de::DeserializeOwned,
|
||||
Deserialize,
|
||||
Serialize
|
||||
};
|
||||
use serde_json_core::{
|
||||
//de::from_slice,
|
||||
ser::to_string
|
||||
};
|
||||
|
||||
#[link_section = ".sram3.eth"]
|
||||
static mut DES_RING: ethernet::DesRing = ethernet::DesRing::new();
|
||||
|
||||
mod eth;
|
||||
mod pounder;
|
||||
|
||||
mod iir;
|
||||
use iir::*;
|
||||
@ -81,30 +99,26 @@ mod build_info {
|
||||
// include!(concat!(env!("OUT_DIR"), "/built.rs"));
|
||||
}
|
||||
|
||||
pub struct NetStorage {
|
||||
ip_addrs: [net::wire::IpCidr; 1],
|
||||
neighbor_cache: [Option<(net::wire::IpAddress, net::iface::Neighbor)>; 8],
|
||||
}
|
||||
|
||||
static mut NET_STORE: NetStorage = NetStorage {
|
||||
// Placeholder for the real IP address, which is initialized at runtime.
|
||||
ip_addrs: [net::wire::IpCidr::Ipv6(net::wire::Ipv6Cidr::SOLICITED_NODE_PREFIX)],
|
||||
|
||||
neighbor_cache: [None; 8],
|
||||
};
|
||||
|
||||
const SCALE: f32 = ((1 << 15) - 1) as f32;
|
||||
|
||||
// static ETHERNET_PENDING: AtomicBool = AtomicBool::new(true);
|
||||
|
||||
/*
|
||||
const TCP_RX_BUFFER_SIZE: usize = 8192;
|
||||
const TCP_TX_BUFFER_SIZE: usize = 8192;
|
||||
|
||||
macro_rules! create_socket {
|
||||
($set:ident, $rx_storage:ident, $tx_storage:ident, $target:ident) => {
|
||||
let mut $rx_storage = [0; TCP_RX_BUFFER_SIZE];
|
||||
let mut $tx_storage = [0; TCP_TX_BUFFER_SIZE];
|
||||
let tcp_rx_buffer =
|
||||
net::socket::TcpSocketBuffer::new(&mut $rx_storage[..]);
|
||||
let tcp_tx_buffer =
|
||||
net::socket::TcpSocketBuffer::new(&mut $tx_storage[..]);
|
||||
let tcp_socket =
|
||||
net::socket::TcpSocket::new(tcp_rx_buffer, tcp_tx_buffer);
|
||||
let $target = $set.add(tcp_socket);
|
||||
};
|
||||
}
|
||||
*/
|
||||
|
||||
#[rtfm::app(device = stm32h7xx_hal::stm32, peripherals = true)]
|
||||
#[rtfm::app(device = stm32h7xx_hal::stm32, peripherals = true, monotonic = rtfm::cyccnt::CYCCNT)]
|
||||
const APP: () = {
|
||||
struct Resources {
|
||||
adc1: hal::spi::Spi<hal::stm32::SPI2>,
|
||||
@ -113,23 +127,22 @@ const APP: () = {
|
||||
adc2: hal::spi::Spi<hal::stm32::SPI3>,
|
||||
dac2: hal::spi::Spi<hal::stm32::SPI5>,
|
||||
|
||||
_eeprom_i2c: hal::i2c::I2c<hal::stm32::I2C2>,
|
||||
eeprom_i2c: hal::i2c::I2c<hal::stm32::I2C2>,
|
||||
|
||||
dbg_pin: hal::gpio::gpioc::PC6<hal::gpio::Output<hal::gpio::PushPull>>,
|
||||
dac_pin: hal::gpio::gpiob::PB15<hal::gpio::Output<hal::gpio::PushPull>>,
|
||||
timer: hal::timer::Timer<hal::stm32::TIM2>,
|
||||
net_interface: net::iface::EthernetInterface<'static, 'static, 'static,
|
||||
ethernet::EthernetDMA<'static>>,
|
||||
_eth_mac: ethernet::EthernetMAC,
|
||||
mac_addr: net::wire::EthernetAddress,
|
||||
|
||||
// TODO: Add in pounder hardware resources.
|
||||
pounder: pounder::PounderDevices<asm_delay::AsmDelay>,
|
||||
|
||||
//ethernet_periph:
|
||||
// (pac::ETHERNET_MAC, pac::ETHERNET_DMA, pac::ETHERNET_MTL),
|
||||
#[init([[0.; 5]; 2])]
|
||||
iir_state: [IIRState; 2],
|
||||
#[init([IIR { ba: [1., 0., 0., 0., 0.], y_offset: 0., y_min: -SCALE - 1., y_max: SCALE }; 2])]
|
||||
iir_ch: [IIR; 2],
|
||||
//#[link_section = ".sram3.eth"]
|
||||
//#[init(eth::Device::new())]
|
||||
//ethernet: eth::Device,
|
||||
}
|
||||
|
||||
#[init]
|
||||
@ -151,6 +164,9 @@ const APP: () = {
|
||||
.pll2_q_ck(100.mhz())
|
||||
.freeze(vos, &dp.SYSCFG);
|
||||
|
||||
// Enable SRAM3 for the ethernet descriptor ring.
|
||||
clocks.rb.ahb2enr.modify(|_, w| w.sram3en().set_bit());
|
||||
|
||||
clocks.rb.rsr.write(|w| w.rmvf().set_bit());
|
||||
|
||||
clocks.rb.d2ccip1r.modify(|_, w| w.spi123sel().pll2_p().spi45sel().pll2_q());
|
||||
@ -247,15 +263,63 @@ const APP: () = {
|
||||
dp.SPI5.spi((spi_sck, spi_miso, hal::spi::NoMosi), config, 25.mhz(), &clocks)
|
||||
};
|
||||
|
||||
// Instantiate the QUADSPI pins and peripheral interface.
|
||||
let pounder_devices = {
|
||||
let ad9959 = {
|
||||
let qspi_interface = {
|
||||
// Instantiate the QUADSPI pins and peripheral interface.
|
||||
// TODO: Place these into a pins structure that is provided to the QSPI
|
||||
// constructor.
|
||||
let _qspi_clk = gpiob.pb2.into_alternate_af9();
|
||||
let _qspi_ncs = gpioc.pc11.into_alternate_af9();
|
||||
let _qspi_io0 = gpioe.pe7.into_alternate_af10();
|
||||
let _qspi_io1 = gpioe.pe8.into_alternate_af10();
|
||||
let _qspi_io2 = gpioe.pe9.into_alternate_af10();
|
||||
let _qspi_io3 = gpioe.pe10.into_alternate_af10();
|
||||
|
||||
// TODO: Place these into a pins structure that is provided to the QSPI constructor.
|
||||
let _qspi_clk = gpiob.pb2.into_alternate_af9();
|
||||
let _qspi_ncs = gpioc.pc11.into_alternate_af9();
|
||||
let _qspi_io0 = gpioe.pe7.into_alternate_af10();
|
||||
let _qspi_io1 = gpioe.pe8.into_alternate_af10();
|
||||
let _qspi_io2 = gpioe.pe9.into_alternate_af10();
|
||||
let _qspi_io3 = gpioe.pe10.into_alternate_af10();
|
||||
let qspi = hal::qspi::Qspi::new(dp.QUADSPI, &mut clocks, 10.mhz()).unwrap();
|
||||
pounder::QspiInterface {qspi}
|
||||
};
|
||||
|
||||
let mut reset_pin = gpioa.pa0.into_push_pull_output();
|
||||
let io_update = gpiog.pg7.into_push_pull_output();
|
||||
|
||||
|
||||
let delay = {
|
||||
let frequency_hz = clocks.clocks.c_ck().0;
|
||||
asm_delay::AsmDelay::new(asm_delay::bitrate::Hertz (frequency_hz))
|
||||
};
|
||||
|
||||
ad9959::Ad9959::new(qspi_interface,
|
||||
&mut reset_pin,
|
||||
io_update,
|
||||
delay,
|
||||
ad9959::Mode::FourBitSerial,
|
||||
100_000_000).unwrap()
|
||||
};
|
||||
|
||||
let io_expander = {
|
||||
let sda = gpiob.pb7.into_alternate_af4().set_open_drain();
|
||||
let scl = gpiob.pb8.into_alternate_af4().set_open_drain();
|
||||
let i2c1 = dp.I2C1.i2c((scl, sda), 100.khz(), &clocks);
|
||||
mcp23017::MCP23017::default(i2c1).unwrap()
|
||||
};
|
||||
|
||||
let spi = {
|
||||
let spi_mosi = gpiod.pd7.into_alternate_af5();
|
||||
let spi_miso = gpioa.pa6.into_alternate_af5();
|
||||
let spi_sck = gpiog.pg11.into_alternate_af5();
|
||||
|
||||
let config = hal::spi::Config::new(hal::spi::Mode{
|
||||
polarity: hal::spi::Polarity::IdleHigh,
|
||||
phase: hal::spi::Phase::CaptureOnSecondTransition,
|
||||
})
|
||||
.frame_size(8);
|
||||
|
||||
dp.SPI1.spi((spi_sck, spi_miso, spi_mosi), config, 25.mhz(), &clocks)
|
||||
};
|
||||
|
||||
pounder::PounderDevices::new(io_expander, ad9959, spi).unwrap()
|
||||
};
|
||||
|
||||
let mut fp_led_0 = gpiod.pd5.into_push_pull_output();
|
||||
let mut fp_led_1 = gpiod.pd6.into_push_pull_output();
|
||||
@ -267,45 +331,63 @@ const APP: () = {
|
||||
fp_led_2.set_low().unwrap();
|
||||
fp_led_3.set_low().unwrap();
|
||||
|
||||
let _i2c1 = {
|
||||
let sda = gpiob.pb7.into_alternate_af4().set_open_drain();
|
||||
let scl = gpiob.pb8.into_alternate_af4().set_open_drain();
|
||||
dp.I2C1.i2c((scl, sda), 100.khz(), &clocks)
|
||||
};
|
||||
|
||||
let i2c2 = {
|
||||
let mut eeprom_i2c = {
|
||||
let sda = gpiof.pf0.into_alternate_af4().set_open_drain();
|
||||
let scl = gpiof.pf1.into_alternate_af4().set_open_drain();
|
||||
dp.I2C2.i2c((scl, sda), 100.khz(), &clocks)
|
||||
};
|
||||
|
||||
// Configure ethernet pins.
|
||||
{
|
||||
// Reset the PHY before configuring pins.
|
||||
let mut eth_phy_nrst = gpioe.pe3.into_push_pull_output();
|
||||
eth_phy_nrst.set_high().unwrap();
|
||||
eth_phy_nrst.set_low().unwrap();
|
||||
eth_phy_nrst.set_high().unwrap();
|
||||
let _rmii_ref_clk = gpioa.pa1.into_alternate_af11().set_speed(hal::gpio::Speed::VeryHigh);
|
||||
let _rmii_mdio = gpioa.pa2.into_alternate_af11().set_speed(hal::gpio::Speed::VeryHigh);
|
||||
let _rmii_mdc = gpioc.pc1.into_alternate_af11().set_speed(hal::gpio::Speed::VeryHigh);
|
||||
let _rmii_crs_dv = gpioa.pa7.into_alternate_af11().set_speed(hal::gpio::Speed::VeryHigh);
|
||||
let _rmii_rxd0 = gpioc.pc4.into_alternate_af11().set_speed(hal::gpio::Speed::VeryHigh);
|
||||
let _rmii_rxd1 = gpioc.pc5.into_alternate_af11().set_speed(hal::gpio::Speed::VeryHigh);
|
||||
let _rmii_tx_en = gpiob.pb11.into_alternate_af11().set_speed(hal::gpio::Speed::VeryHigh);
|
||||
let _rmii_txd0 = gpiob.pb12.into_alternate_af11().set_speed(hal::gpio::Speed::VeryHigh);
|
||||
let _rmii_txd1 = gpiog.pg14.into_alternate_af11().set_speed(hal::gpio::Speed::VeryHigh);
|
||||
}
|
||||
|
||||
// Reset the PHY before configuring pins.
|
||||
let mut eth_phy_nrst = gpioe.pe3.into_push_pull_output();
|
||||
eth_phy_nrst.set_high().unwrap();
|
||||
eth_phy_nrst.set_low().unwrap();
|
||||
eth_phy_nrst.set_high().unwrap();
|
||||
let _rmii_ref_clk = gpioa.pa1.into_alternate_af11().set_speed(hal::gpio::Speed::VeryHigh);
|
||||
let _rmii_mdio = gpioa.pa2.into_alternate_af11().set_speed(hal::gpio::Speed::VeryHigh);
|
||||
let _rmii_mdc = gpioc.pc1.into_alternate_af11().set_speed(hal::gpio::Speed::VeryHigh);
|
||||
let _rmii_crs_dv = gpioa.pa7.into_alternate_af11().set_speed(hal::gpio::Speed::VeryHigh);
|
||||
let _rmii_rxd0 = gpioc.pc4.into_alternate_af11().set_speed(hal::gpio::Speed::VeryHigh);
|
||||
let _rmii_rxd1 = gpioc.pc5.into_alternate_af11().set_speed(hal::gpio::Speed::VeryHigh);
|
||||
let _rmii_tx_en = gpiob.pb11.into_alternate_af11().set_speed(hal::gpio::Speed::VeryHigh);
|
||||
let _rmii_txd0 = gpiob.pb12.into_alternate_af11().set_speed(hal::gpio::Speed::VeryHigh);
|
||||
let _rmii_txd1 = gpiog.pg14.into_alternate_af11().set_speed(hal::gpio::Speed::VeryHigh);
|
||||
let mac_addr = match eeprom::read_eui48(&mut eeprom_i2c) {
|
||||
Err(_) => {
|
||||
info!("Could not read EEPROM, using default MAC address");
|
||||
net::wire::EthernetAddress([0x10, 0xE2, 0xD5, 0x00, 0x03, 0x00])
|
||||
}
|
||||
Ok(raw_mac) => net::wire::EthernetAddress(raw_mac),
|
||||
};
|
||||
|
||||
// TODO: Configure the ethernet controller
|
||||
// Enable the ethernet peripheral.
|
||||
//clocks.apb4.enr().modify(|_, w| w.syscfgen().set_bit());
|
||||
//clocks.ahb1.enr().modify(|_, w| {
|
||||
// w.eth1macen().set_bit()
|
||||
// .eth1txen().set_bit()
|
||||
// .eth1rxen().set_bit()
|
||||
//});
|
||||
let (network_interface, eth_mac) = {
|
||||
// Configure the ethernet controller
|
||||
let (eth_dma, eth_mac) = unsafe {
|
||||
ethernet::ethernet_init(
|
||||
dp.ETHERNET_MAC,
|
||||
dp.ETHERNET_MTL,
|
||||
dp.ETHERNET_DMA,
|
||||
&mut DES_RING,
|
||||
mac_addr.clone())
|
||||
};
|
||||
|
||||
//dp.SYSCFG.pmcr.modify(|_, w| unsafe { w.epis().bits(0b100) }); // RMII
|
||||
let store = unsafe { &mut NET_STORE };
|
||||
|
||||
store.ip_addrs[0] = net::wire::IpCidr::new(net::wire::IpAddress::v4(10, 0, 16, 99), 24);
|
||||
|
||||
let neighbor_cache = net::iface::NeighborCache::new(&mut store.neighbor_cache[..]);
|
||||
|
||||
let interface = net::iface::EthernetInterfaceBuilder::new(eth_dma)
|
||||
.ethernet_addr(mac_addr)
|
||||
.neighbor_cache(neighbor_cache)
|
||||
.ip_addrs(&mut store.ip_addrs[..])
|
||||
.finalize();
|
||||
|
||||
(interface, eth_mac)
|
||||
};
|
||||
|
||||
cp.SCB.enable_icache();
|
||||
|
||||
@ -314,6 +396,9 @@ const APP: () = {
|
||||
// info!("Built on {}", build_info::BUILT_TIME_UTC);
|
||||
// info!("{} {}", build_info::RUSTC_VERSION, build_info::TARGET);
|
||||
|
||||
// Utilize the cycle counter for RTFM scheduling.
|
||||
cp.DWT.enable_cycle_counter();
|
||||
|
||||
let mut debug_pin = gpioc.pc6.into_push_pull_output();
|
||||
debug_pin.set_low().unwrap();
|
||||
|
||||
@ -333,13 +418,12 @@ const APP: () = {
|
||||
dbg_pin: debug_pin,
|
||||
dac_pin: dac_pin,
|
||||
timer: timer2,
|
||||
pounder: pounder_devices,
|
||||
|
||||
_eeprom_i2c: i2c2,
|
||||
// ethernet_periph: (
|
||||
// dp.ETHERNET_MAC,
|
||||
// dp.ETHERNET_DMA,
|
||||
// dp.ETHERNET_MTL,
|
||||
// ),
|
||||
eeprom_i2c: eeprom_i2c,
|
||||
net_interface: network_interface,
|
||||
_eth_mac: eth_mac,
|
||||
mac_addr: mac_addr,
|
||||
}
|
||||
}
|
||||
|
||||
@ -386,11 +470,69 @@ const APP: () = {
|
||||
cortex_m::asm::bkpt();
|
||||
}
|
||||
|
||||
#[idle]
|
||||
fn idle(_c: idle::Context) -> ! {
|
||||
// TODO Implement and poll ethernet interface.
|
||||
#[idle(resources=[net_interface, mac_addr, iir_state])]
|
||||
fn idle(mut c: idle::Context) -> ! {
|
||||
|
||||
let interface = c.resources.net_interface;
|
||||
let mut socket_set_entries: [_; 8] = Default::default();
|
||||
let mut sockets = net::socket::SocketSet::new(&mut socket_set_entries[..]);
|
||||
|
||||
let mut rx_storage = [0; TCP_RX_BUFFER_SIZE];
|
||||
let mut tx_storage = [0; TCP_TX_BUFFER_SIZE];
|
||||
let tcp_handle0 = {
|
||||
let tcp_rx_buffer = net::socket::TcpSocketBuffer::new(&mut rx_storage[..]);
|
||||
let tcp_tx_buffer = net::socket::TcpSocketBuffer::new(&mut tx_storage[..]);
|
||||
let tcp_socket = net::socket::TcpSocket::new(tcp_rx_buffer, tcp_tx_buffer);
|
||||
sockets.add(tcp_socket)
|
||||
};
|
||||
|
||||
let mut time = 0u32;
|
||||
let mut next_ms = Instant::now();
|
||||
|
||||
// TODO: Replace with reference to CPU clock from CCDR.
|
||||
next_ms += 400_000.cycles();
|
||||
|
||||
loop {
|
||||
asm::nop();
|
||||
let tick = Instant::now() > next_ms;
|
||||
|
||||
if tick {
|
||||
next_ms += 400_000.cycles();
|
||||
time += 1;
|
||||
}
|
||||
|
||||
{
|
||||
let mut socket = sockets.get::<net::socket::TcpSocket>(tcp_handle0);
|
||||
if socket.state() == net::socket::TcpState::CloseWait {
|
||||
socket.close();
|
||||
} else if !(socket.is_open() || socket.is_listening()) {
|
||||
socket
|
||||
.listen(1234)
|
||||
.unwrap_or_else(|e| warn!("TCP listen error: {:?}", e));
|
||||
} else if tick && socket.can_send() {
|
||||
let s = c.resources.iir_state.lock(|iir_state| Status {
|
||||
t: time,
|
||||
x0: iir_state[0][0],
|
||||
y0: iir_state[0][2],
|
||||
x1: iir_state[1][0],
|
||||
y1: iir_state[1][2],
|
||||
});
|
||||
json_reply(&mut socket, &s);
|
||||
}
|
||||
}
|
||||
|
||||
let sleep = match interface.poll(&mut sockets,
|
||||
net::time::Instant::from_millis(time as i64)) {
|
||||
Ok(changed) => changed,
|
||||
Err(net::Error::Unrecognized) => true,
|
||||
Err(e) => {
|
||||
info!("iface poll error: {:?}", e);
|
||||
true
|
||||
}
|
||||
};
|
||||
|
||||
if sleep {
|
||||
cortex_m::asm::wfi();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -515,7 +657,6 @@ const APP: () = {
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
#[derive(Deserialize, Serialize)]
|
||||
struct Request {
|
||||
channel: u8,
|
||||
@ -543,6 +684,7 @@ fn json_reply<T: Serialize>(socket: &mut net::socket::TcpSocket, msg: &T) {
|
||||
socket.write_str(&u).unwrap();
|
||||
}
|
||||
|
||||
/*
|
||||
struct Server {
|
||||
data: Vec<u8, U256>,
|
||||
discard: bool,
|
||||
|
54
src/pounder/attenuators.rs
Normal file
54
src/pounder/attenuators.rs
Normal file
@ -0,0 +1,54 @@
|
||||
use super::error::Error;
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum Channel {
|
||||
One = 0,
|
||||
Two = 1,
|
||||
Three = 2,
|
||||
Four = 3,
|
||||
}
|
||||
|
||||
pub trait AttenuatorInterface {
|
||||
fn modify(&mut self, attenuation: f32, channel: Channel) -> Result<f32, Error> {
|
||||
if attenuation > 31.5 {
|
||||
return Err(Error::Bounds);
|
||||
}
|
||||
|
||||
// Calculate the attenuation code to program into the attenuator.
|
||||
let attenuation_code = (attenuation * 2.0) as u8;
|
||||
|
||||
// Read all the channels, modify the channel of interest, and write all the channels back.
|
||||
// This ensures the staging register and the output register are always in sync.
|
||||
let mut channels = [0_u8; 4];
|
||||
self.read_all(&mut channels)?;
|
||||
channels[channel as usize] = attenuation_code;
|
||||
self.write_all(&channels)?;
|
||||
|
||||
// Finally, latch the output of the updated channel to force it into an active state.
|
||||
self.latch(channel)?;
|
||||
|
||||
Ok(attenuation_code as f32 / 2.0)
|
||||
}
|
||||
|
||||
fn read(&mut self, channel: Channel) -> Result<f32, Error> {
|
||||
let mut channels = [0_u8; 4];
|
||||
|
||||
// Reading the data always shifts data out of the staging registers, so we perform a
|
||||
// duplicate write-back to ensure the staging register is always equal to the output
|
||||
// register.
|
||||
self.read_all(&mut channels)?;
|
||||
self.write_all(&channels)?;
|
||||
|
||||
// Convert the desired channel code into dB of attenuation.
|
||||
let attenuation_code = channels[channel as usize];
|
||||
|
||||
Ok(attenuation_code as f32 / 2.0)
|
||||
}
|
||||
|
||||
fn reset(&mut self) -> Result<(), Error>;
|
||||
|
||||
fn latch(&mut self, channel: Channel) -> Result<(), Error>;
|
||||
fn read_all(&mut self, channels: &mut [u8; 4]) -> Result<(), Error>;
|
||||
fn write_all(&mut self, channels: &[u8; 4]) -> Result<(), Error>;
|
||||
}
|
9
src/pounder/error.rs
Normal file
9
src/pounder/error.rs
Normal file
@ -0,0 +1,9 @@
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
Spi,
|
||||
I2c,
|
||||
DDS,
|
||||
Qspi,
|
||||
Bounds,
|
||||
InvalidAddress,
|
||||
}
|
148
src/pounder/mod.rs
Normal file
148
src/pounder/mod.rs
Normal file
@ -0,0 +1,148 @@
|
||||
use mcp23017;
|
||||
use ad9959;
|
||||
|
||||
pub mod error;
|
||||
pub mod attenuators;
|
||||
|
||||
use super::hal;
|
||||
|
||||
use error::Error;
|
||||
use attenuators::{AttenuatorInterface, Channel};
|
||||
|
||||
use embedded_hal::blocking::spi::Transfer;
|
||||
|
||||
#[allow(dead_code)]
|
||||
const OSC_EN_N_PIN: u8 = 8 + 7;
|
||||
|
||||
const EXT_CLK_SEL_PIN: u8 = 8 + 6;
|
||||
|
||||
const ATT_RST_N_PIN: u8 = 8 + 5;
|
||||
|
||||
const ATT_LE0_PIN: u8 = 8 + 0;
|
||||
const ATT_LE1_PIN: u8 = 8 + 1;
|
||||
const ATT_LE2_PIN: u8 = 8 + 2;
|
||||
const ATT_LE3_PIN: u8 = 8 + 3;
|
||||
|
||||
pub struct QspiInterface {
|
||||
pub qspi: hal::qspi::Qspi,
|
||||
}
|
||||
|
||||
impl ad9959::Interface for QspiInterface {
|
||||
type Error = Error;
|
||||
|
||||
fn configure_mode(&mut self, mode: ad9959::Mode) -> Result<(), Error> {
|
||||
let result = match mode {
|
||||
ad9959::Mode::SingleBitTwoWire | ad9959::Mode::SingleBitThreeWire =>
|
||||
self.qspi.configure_mode(hal::qspi::QspiMode::OneBit),
|
||||
ad9959::Mode::TwoBitSerial => self.qspi.configure_mode(hal::qspi::QspiMode::TwoBit),
|
||||
ad9959::Mode::FourBitSerial => self.qspi.configure_mode(hal::qspi::QspiMode::FourBit),
|
||||
};
|
||||
|
||||
result.map_err(|_| Error::Qspi)
|
||||
}
|
||||
|
||||
fn write(&mut self, addr: u8, data: &[u8]) -> Result<(), Error> {
|
||||
if (addr & 0x80) != 0 {
|
||||
return Err(Error::InvalidAddress);
|
||||
}
|
||||
|
||||
self.qspi.write(addr, &data).map_err(|_| Error::Qspi)
|
||||
}
|
||||
|
||||
fn read(&mut self, addr: u8, mut dest: &mut [u8]) -> Result<(), Error> {
|
||||
if (addr & 0x80) != 0 {
|
||||
return Err(Error::InvalidAddress);
|
||||
}
|
||||
self.qspi.read(0x80_u8 | addr, &mut dest).map_err(|_| Error::Qspi)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct PounderDevices<DELAY> {
|
||||
pub ad9959: ad9959::Ad9959<QspiInterface,
|
||||
DELAY,
|
||||
hal::gpio::gpiog::PG7<hal::gpio::Output<hal::gpio::PushPull>>>,
|
||||
mcp23017: mcp23017::MCP23017<hal::i2c::I2c<hal::stm32::I2C1>>,
|
||||
attenuator_spi: hal::spi::Spi<hal::stm32::SPI1>
|
||||
}
|
||||
|
||||
impl<DELAY> PounderDevices<DELAY>
|
||||
where
|
||||
DELAY: embedded_hal::blocking::delay::DelayMs<u8>,
|
||||
{
|
||||
pub fn new(mcp23017: mcp23017::MCP23017<hal::i2c::I2c<hal::stm32::I2C1>>,
|
||||
ad9959: ad9959::Ad9959<QspiInterface,
|
||||
DELAY,
|
||||
hal::gpio::gpiog::PG7<
|
||||
hal::gpio::Output<hal::gpio::PushPull>>>,
|
||||
attenuator_spi: hal::spi::Spi<hal::stm32::SPI1>) -> Result<Self, Error> {
|
||||
let mut devices = Self {
|
||||
mcp23017,
|
||||
ad9959,
|
||||
attenuator_spi
|
||||
};
|
||||
|
||||
// Configure power-on-default state for pounder. All LEDs are on, on-board oscillator
|
||||
// selected, attenuators out of reset.
|
||||
devices.mcp23017.write_gpioa(0xF).map_err(|_| Error::I2c)?;
|
||||
devices.mcp23017.write_gpiob(1_u8.wrapping_shl(5)).map_err(|_| Error::I2c)?;
|
||||
devices.mcp23017.all_pin_mode(mcp23017::PinMode::OUTPUT).map_err(|_| Error::I2c)?;
|
||||
|
||||
devices.select_onboard_clock()?;
|
||||
|
||||
Ok(devices)
|
||||
}
|
||||
|
||||
pub fn select_external_clock(&mut self, frequency: u32) -> Result<(), Error>{
|
||||
self.mcp23017.digital_write(EXT_CLK_SEL_PIN, 1).map_err(|_| Error::I2c)?;
|
||||
self.ad9959.set_clock_frequency(frequency).map_err(|_| Error::DDS)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn select_onboard_clock(&mut self) -> Result<(), Error> {
|
||||
self.mcp23017.digital_write(EXT_CLK_SEL_PIN, 0).map_err(|_| Error::I2c)?;
|
||||
self.ad9959.set_clock_frequency(100_000_000).map_err(|_| Error::DDS)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<DELAY> AttenuatorInterface for PounderDevices<DELAY>
|
||||
{
|
||||
fn reset(&mut self) -> Result<(), Error> {
|
||||
self.mcp23017.digital_write(ATT_RST_N_PIN, 1).map_err(|_| Error::I2c)?;
|
||||
// TODO: Delay here.
|
||||
self.mcp23017.digital_write(ATT_RST_N_PIN, 0).map_err(|_| Error::I2c)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn latch(&mut self, channel: Channel) -> Result<(), Error> {
|
||||
let pin = match channel {
|
||||
Channel::One => ATT_LE0_PIN,
|
||||
Channel::Two => ATT_LE1_PIN,
|
||||
Channel::Three => ATT_LE2_PIN,
|
||||
Channel::Four => ATT_LE3_PIN,
|
||||
};
|
||||
|
||||
self.mcp23017.digital_write(pin, 1).map_err(|_| Error::I2c)?;
|
||||
// TODO: Delay here.
|
||||
self.mcp23017.digital_write(pin, 0).map_err(|_| Error::I2c)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn read_all(&mut self, channels: &mut [u8; 4]) -> Result<(), Error> {
|
||||
self.attenuator_spi.transfer(channels).map_err(|_| Error::Spi)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn write_all(&mut self, channels: &[u8; 4]) -> Result<(), Error> {
|
||||
let mut result = [0_u8; 4];
|
||||
result.clone_from_slice(channels);
|
||||
self.attenuator_spi.transfer(&mut result).map_err(|_| Error::Spi)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user