Adding refactor to support pounder hardware abstractions

This commit is contained in:
Ryan Summers 2020-04-28 19:07:19 +02:00
parent 87858a6e0a
commit abf22676ce
6 changed files with 544 additions and 81 deletions

94
Cargo.lock generated
View File

@ -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"

View File

@ -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"

View File

@ -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,

View 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
View File

@ -0,0 +1,9 @@
#[derive(Debug)]
pub enum Error {
Spi,
I2c,
DDS,
Qspi,
Bounds,
InvalidAddress,
}

148
src/pounder/mod.rs Normal file
View 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(())
}
}