pounder_test/src/main.rs

670 lines
22 KiB
Rust
Raw Normal View History

2019-11-11 19:04:50 +08:00
#![deny(warnings)]
#![allow(clippy::missing_safety_doc)]
2019-03-18 19:56:26 +08:00
#![no_std]
#![no_main]
2019-10-22 21:43:49 +08:00
#![cfg_attr(feature = "nightly", feature(asm))]
2019-03-18 19:56:26 +08:00
// Enable returning `!`
2019-10-22 21:43:49 +08:00
#![cfg_attr(feature = "nightly", feature(never_type))]
#![cfg_attr(feature = "nightly", feature(core_intrinsics))]
2019-03-18 19:56:26 +08:00
2019-06-07 17:26:24 +08:00
#[inline(never)]
#[panic_handler]
2019-10-22 21:43:49 +08:00
#[cfg(all(feature = "nightly", not(feature = "semihosting")))]
2019-06-07 17:26:24 +08:00
fn panic(_info: &core::panic::PanicInfo) -> ! {
2019-06-07 22:28:22 +08:00
let gpiod = unsafe { &*pac::GPIOD::ptr() };
2019-11-24 22:09:52 +08:00
gpiod.odr.modify(|_, w| w.odr6().high().odr12().high()); // FP_LED_1, FP_LED_3
unsafe {
core::intrinsics::abort();
}
2019-06-07 17:26:24 +08:00
}
2019-03-18 19:56:26 +08:00
#[cfg(feature = "semihosting")]
extern crate panic_semihosting;
2019-10-22 21:43:49 +08:00
#[cfg(not(any(feature = "nightly", feature = "semihosting")))]
extern crate panic_halt;
2019-03-18 19:56:26 +08:00
#[macro_use]
extern crate log;
2019-06-03 23:06:11 +08:00
// use core::sync::atomic::{AtomicU32, AtomicBool, Ordering};
use cortex_m_rt::exception;
2020-04-22 01:02:52 +08:00
use rtfm::cyccnt::{U32Ext as _};
2020-04-19 19:37:03 +08:00
use stm32h7xx_hal as hal;
use stm32h7xx_hal::{
prelude::*,
stm32 as pac,
};
use embedded_hal::{
digital::v2::OutputPin,
};
2019-03-18 19:56:26 +08:00
2020-04-22 01:02:52 +08:00
/*
use core::fmt::Write;
use heapless::{consts::*, String, Vec};
use smoltcp as net;
2019-11-24 22:09:52 +08:00
use serde::{de::DeserializeOwned, Deserialize, Serialize};
use serde_json_core::{de::from_slice, ser::to_string};
2020-04-22 01:02:52 +08:00
*/
2019-05-24 00:57:00 +08:00
mod eth;
2019-03-28 02:48:22 +08:00
mod iir;
use iir::*;
mod board;
2019-11-24 22:09:52 +08:00
mod eeprom;
2019-09-05 07:54:00 +08:00
2019-03-18 19:56:26 +08:00
#[cfg(not(feature = "semihosting"))]
fn init_log() {}
#[cfg(feature = "semihosting")]
fn init_log() {
2019-11-24 22:09:52 +08:00
use cortex_m_log::log::{init as init_log, Logger};
use cortex_m_log::printer::semihosting::{hio::HStdout, InterruptOk};
2019-03-18 19:56:26 +08:00
use log::LevelFilter;
static mut LOGGER: Option<Logger<InterruptOk<HStdout>>> = None;
let logger = Logger {
2019-04-13 00:13:18 +08:00
inner: InterruptOk::<_>::stdout().unwrap(),
2019-03-18 19:56:26 +08:00
level: LevelFilter::Info,
};
2019-11-24 22:09:52 +08:00
let logger = unsafe { LOGGER.get_or_insert(logger) };
2019-03-18 19:56:26 +08:00
2019-05-31 00:03:48 +08:00
init_log(logger).unwrap();
2019-03-18 19:56:26 +08:00
}
// Pull in build information (from `built` crate)
mod build_info {
#![allow(dead_code)]
2019-05-24 00:57:00 +08:00
// include!(concat!(env!("OUT_DIR"), "/built.rs"));
2019-03-18 19:56:26 +08:00
}
2019-05-31 00:03:48 +08:00
const SCALE: f32 = ((1 << 15) - 1) as f32;
2019-03-25 17:08:27 +08:00
2019-06-03 23:06:11 +08:00
// static ETHERNET_PENDING: AtomicBool = AtomicBool::new(true);
2020-04-22 01:02:52 +08:00
/*
2019-04-30 19:42:05 +08:00
const TCP_RX_BUFFER_SIZE: usize = 8192;
const TCP_TX_BUFFER_SIZE: usize = 8192;
macro_rules! create_socket {
2019-11-24 22:09:52 +08:00
($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];
2019-11-24 22:09:52 +08:00
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);
2019-11-24 22:09:52 +08:00
};
}
2020-04-22 01:02:52 +08:00
*/
2020-04-19 19:37:03 +08:00
static DAT: u32 = 0x30; // EN | CSTART
#[rtfm::app(device = stm32h7xx_hal::stm32, peripherals = true, monotonic = rtfm::cyccnt::CYCCNT)]
2019-05-31 00:03:48 +08:00
const APP: () = {
2019-08-26 21:47:42 +08:00
struct Resources {
2020-04-22 01:02:52 +08:00
adc1: hal::spi::Spi<hal::stm32::SPI2>,
dac1: hal::spi::Spi<hal::stm32::SPI4>,
2020-04-19 19:37:03 +08:00
2020-04-22 01:02:52 +08:00
adc2: hal::spi::Spi<hal::stm32::SPI3>,
dac2: hal::spi::Spi<hal::stm32::SPI5>,
2020-04-19 19:37:03 +08:00
2020-04-22 01:02:52 +08:00
_eeprom_i2c: hal::i2c::I2c<hal::stm32::I2C2>,
2020-04-19 19:37:03 +08:00
// TODO: Add in pounder hardware resources.
2020-04-22 01:02:52 +08:00
//ethernet_periph:
// (pac::ETHERNET_MAC, pac::ETHERNET_DMA, pac::ETHERNET_MTL),
2019-08-26 21:47:42 +08:00
#[init([[0.; 5]; 2])]
iir_state: [IIRState; 2],
2019-11-24 21:10:01 +08:00
#[init([IIR { ba: [1., 0., 0., 0., 0.], y_offset: 0., y_min: -SCALE - 1., y_max: SCALE }; 2])]
2019-08-26 21:47:42 +08:00
iir_ch: [IIR; 2],
2020-04-22 01:02:52 +08:00
//#[link_section = ".sram3.eth"]
//#[init(eth::Device::new())]
//ethernet: eth::Device,
2019-08-26 21:47:42 +08:00
}
2019-05-31 00:03:48 +08:00
2019-05-31 00:18:59 +08:00
#[init(schedule = [tick])]
2019-05-31 00:03:48 +08:00
fn init(c: init::Context) -> init::LateResources {
2020-04-19 19:37:03 +08:00
let dp = c.device;
let mut cp = cortex_m::Peripherals::take().unwrap();
let pwr = dp.PWR.constrain();
let vos = pwr.freeze();
let rcc = dp.RCC.constrain();
let mut clocks = rcc
2020-04-22 01:02:52 +08:00
// .use_hse(8.mhz())
2020-04-19 19:37:03 +08:00
.sysclk(400.mhz())
.hclk(200.mhz())
.per_ck(100.mhz())
.pll2_p_ck(100.mhz())
.pll2_q_ck(100.mhz())
.freeze(vos, &dp.SYSCFG);
2020-04-22 01:02:52 +08:00
clocks.rb.rsr.write(|w| w.rmvf().set_bit());
2020-04-19 19:37:03 +08:00
clocks.rb.d2ccip1r.modify(|_, w| w.spi123sel().pll2_p().spi45sel().pll2_q());
let gpioa = dp.GPIOA.split(&mut clocks.ahb4);
let gpiob = dp.GPIOB.split(&mut clocks.ahb4);
let gpioc = dp.GPIOC.split(&mut clocks.ahb4);
let gpiod = dp.GPIOD.split(&mut clocks.ahb4);
let gpioe = dp.GPIOE.split(&mut clocks.ahb4);
let gpiof = dp.GPIOF.split(&mut clocks.ahb4);
let gpiog = dp.GPIOG.split(&mut clocks.ahb4);
// Configure the SPI interfaces to the ADCs and DACs.
2020-04-22 01:02:52 +08:00
let (adc1_spi, adc1_cr_address) = {
2020-04-19 19:37:03 +08:00
let spi_miso = gpiob.pb14.into_alternate_af5();
let spi_sck = gpiob.pb10.into_alternate_af5();
let _spi_nss = gpiob.pb9.into_alternate_af5();
2020-04-22 01:02:52 +08:00
let _config = hal::spi::Config::new(hal::spi::Mode{
2020-04-19 19:37:03 +08:00
polarity: hal::spi::Polarity::IdleHigh,
2020-04-22 01:02:52 +08:00
phase: hal::spi::Phase::CaptureOnSecondTransition,
})
.manage_cs()
2020-04-19 19:37:03 +08:00
.cs_delay(220e-9)
2020-04-22 01:02:52 +08:00
.frame_size(16);
let cr_address = &dp.SPI2.cr1 as *const _ as usize;
2020-04-19 19:37:03 +08:00
2020-04-22 01:02:52 +08:00
let mut spi = dp.SPI2.spi(
2020-04-19 19:37:03 +08:00
(spi_sck, spi_miso, hal::spi::NoMosi),
2020-04-22 01:02:52 +08:00
hal::spi::MODE_0, //config,
2020-04-19 19:37:03 +08:00
25.mhz(),
&clocks);
2020-04-22 01:02:52 +08:00
spi.listen(hal::spi::Event::Rxp);
2020-04-19 19:37:03 +08:00
2020-04-22 01:02:52 +08:00
(spi, cr_address)
2020-04-19 19:37:03 +08:00
};
2020-04-22 01:02:52 +08:00
let (adc2_spi, adc2_cr_address) = {
2020-04-19 19:37:03 +08:00
let spi_miso = gpiob.pb4.into_alternate_af6();
let spi_sck = gpioc.pc10.into_alternate_af6();
2020-04-22 01:02:52 +08:00
let mut cs = gpioa.pa15.into_push_pull_output();
cs.set_high().unwrap();
let _spi_nss = cs.into_alternate_af6();
let config = hal::spi::Config::new(hal::spi::Mode{
2020-04-19 19:37:03 +08:00
polarity: hal::spi::Polarity::IdleHigh,
2020-04-22 01:02:52 +08:00
phase: hal::spi::Phase::CaptureOnSecondTransition,
})
.manage_cs()
2020-04-19 19:37:03 +08:00
.frame_size(16)
2020-04-22 01:02:52 +08:00
.cs_delay(220e-9);
let cr_address = &dp.SPI3.cr1 as *const _ as usize;
2020-04-19 19:37:03 +08:00
2020-04-22 01:02:52 +08:00
let mut spi = dp.SPI3.spi(
2020-04-19 19:37:03 +08:00
(spi_sck, spi_miso, hal::spi::NoMosi),
config,
25.mhz(),
&clocks);
2020-04-22 01:02:52 +08:00
spi.send(8_u8).unwrap();
2020-04-19 19:37:03 +08:00
2020-04-22 01:02:52 +08:00
spi.listen(hal::spi::Event::Rxp);
(spi, cr_address)
2020-04-19 19:37:03 +08:00
};
let dac1_spi = {
let spi_miso = gpioe.pe5.into_alternate_af5();
let spi_sck = gpioe.pe2.into_alternate_af5();
let _spi_nss = gpioe.pe4.into_alternate_af5();
2020-04-22 01:02:52 +08:00
let config = hal::spi::Config::new(hal::spi::Mode{
2020-04-19 19:37:03 +08:00
polarity: hal::spi::Polarity::IdleHigh,
2020-04-22 01:02:52 +08:00
phase: hal::spi::Phase::CaptureOnSecondTransition,
})
.manage_cs()
2020-04-19 19:37:03 +08:00
.frame_size(16)
2020-04-22 01:02:52 +08:00
.swap_mosi_miso();
2020-04-19 19:37:03 +08:00
2020-04-22 01:02:52 +08:00
dp.SPI4.spi((spi_sck, spi_miso, hal::spi::NoMosi), config, 25.mhz(), &clocks)
2020-04-19 19:37:03 +08:00
};
let dac2_spi = {
let spi_miso = gpiof.pf8.into_alternate_af5();
let spi_sck = gpiof.pf7.into_alternate_af5();
let _spi_nss = gpiof.pf6.into_alternate_af5();
2020-04-22 01:02:52 +08:00
let config = hal::spi::Config::new(hal::spi::Mode{
2020-04-19 19:37:03 +08:00
polarity: hal::spi::Polarity::IdleHigh,
2020-04-22 01:02:52 +08:00
phase: hal::spi::Phase::CaptureOnSecondTransition,
})
.manage_cs()
2020-04-19 19:37:03 +08:00
.frame_size(16)
2020-04-22 01:02:52 +08:00
.swap_mosi_miso();
2020-04-19 19:37:03 +08:00
2020-04-22 01:02:52 +08:00
dp.SPI5.spi((spi_sck, spi_miso, hal::spi::NoMosi), config, 25.mhz(), &clocks)
2020-04-19 19:37:03 +08:00
};
2020-04-22 01:02:52 +08:00
// Configure timer 2 to trigger conversions for the ADC
let mut timer2 = hal::timer::Timer::tim2(dp.TIM2, 500.khz(), &mut clocks);
//timer2.listen(hal::timer::Event::TimeOut);
timer2.listen(hal::timer::Event::DmaRequest);
2020-04-19 19:37:03 +08:00
cortex_m::asm::dsb();
let dat_addr = &DAT as *const _ as usize;
cp.SCB.clean_dcache_by_address(dat_addr, 4);
2020-04-22 01:02:52 +08:00
// Enable the DMA.
// TODO: Refactor the DMA API to be a bit cleaner.
clocks.ahb1.enr().modify(|_, w| w.dma1en().set_bit());
2020-04-19 19:37:03 +08:00
board::dma1_setup(
&dp.DMA1,
&dp.DMAMUX1,
dat_addr,
2020-04-22 01:02:52 +08:00
adc1_cr_address,
adc2_cr_address,
2020-04-19 19:37:03 +08:00
);
// 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();
let mut fp_led_0 = gpiod.pd5.into_push_pull_output();
let mut fp_led_1 = gpiod.pd6.into_push_pull_output();
let mut fp_led_2 = gpiod.pd12.into_push_pull_output();
let mut fp_led_3 = gpiog.pg4.into_push_pull_output();
fp_led_0.set_low().unwrap();
fp_led_1.set_low().unwrap();
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();
2020-04-22 01:02:52 +08:00
dp.I2C1.i2c((scl, sda), 100.khz(), &clocks)
2020-04-19 19:37:03 +08:00
};
let i2c2 = {
let sda = gpiof.pf0.into_alternate_af4().set_open_drain();
let scl = gpiof.pf1.into_alternate_af4().set_open_drain();
2020-04-22 01:02:52 +08:00
dp.I2C2.i2c((scl, sda), 100.khz(), &clocks)
2020-04-19 19:37:03 +08:00
};
// Configure ethernet pins.
2020-04-22 01:02:52 +08:00
// 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();
2020-04-19 19:37:03 +08:00
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);
2020-04-22 01:02:52 +08:00
let _rmii_txd1 = gpiog.pg14.into_alternate_af11().set_speed(hal::gpio::Speed::VeryHigh);
2020-04-19 19:37:03 +08:00
2020-04-22 01:02:52 +08:00
// TODO: Configure the ethernet controller
2020-04-19 19:37:03 +08:00
// Enable the ethernet peripheral.
2020-04-22 01:02:52 +08:00
//clocks.apb4.enr().modify(|_, w| w.syscfgen().set_bit());
//clocks.ahb1.enr().modify(|_, w| {
// w.eth1macen().set_bit()
// .eth1txen().set_bit()
// .eth1rxen().set_bit()
//});
2020-04-19 19:37:03 +08:00
2020-04-22 01:02:52 +08:00
//dp.SYSCFG.pmcr.modify(|_, w| unsafe { w.epis().bits(0b100) }); // RMII
2020-04-19 19:37:03 +08:00
cp.SCB.enable_icache();
// The cycle counter is used for RTFM scheduling.
cp.DWT.enable_cycle_counter();
2019-05-31 00:03:48 +08:00
init_log();
// info!("Version {} {}", build_info::PKG_VERSION, build_info::GIT_VERSION.unwrap());
// info!("Built on {}", build_info::BUILT_TIME_UTC);
// info!("{} {}", build_info::RUSTC_VERSION, build_info::TARGET);
2019-08-26 21:47:42 +08:00
// c.schedule.tick(Instant::now()).unwrap();
2019-05-31 04:57:41 +08:00
init::LateResources {
2020-04-19 19:37:03 +08:00
adc1: adc1_spi,
dac1: dac1_spi,
adc2: adc2_spi,
dac2: dac2_spi,
2020-04-22 01:02:52 +08:00
_eeprom_i2c: i2c2,
// ethernet_periph: (
// dp.ETHERNET_MAC,
// dp.ETHERNET_DMA,
// dp.ETHERNET_MTL,
// ),
2019-05-31 04:57:41 +08:00
}
}
2020-04-22 01:02:52 +08:00
#[idle]
fn idle(_c: idle::Context) -> ! {
// TODO Implement and poll ethernet interface.
loop {}
}
/*
2019-09-05 07:54:00 +08:00
#[idle(resources = [ethernet, ethernet_periph, iir_state, iir_ch, i2c])]
2019-05-31 04:57:41 +08:00
fn idle(c: idle::Context) -> ! {
2019-08-26 21:47:42 +08:00
let (MAC, DMA, MTL) = c.resources.ethernet_periph;
2019-05-31 04:57:41 +08:00
2019-09-05 07:54:00 +08:00
let hardware_addr = match eeprom::read_eui48(c.resources.i2c) {
Err(_) => {
info!("Could not read EEPROM, using default MAC address");
net::wire::EthernetAddress([0x10, 0xE2, 0xD5, 0x00, 0x03, 0x00])
2019-11-24 22:09:52 +08:00
}
Ok(raw_mac) => net::wire::EthernetAddress(raw_mac),
2019-09-05 07:54:00 +08:00
};
info!("MAC: {}", hardware_addr);
2019-08-26 21:47:42 +08:00
unsafe { c.resources.ethernet.init(hardware_addr, MAC, DMA, MTL) };
2019-05-31 00:03:48 +08:00
let mut neighbor_cache_storage = [None; 8];
2019-11-24 22:09:52 +08:00
let neighbor_cache =
net::iface::NeighborCache::new(&mut neighbor_cache_storage[..]);
2019-05-31 00:03:48 +08:00
let local_addr = net::wire::IpAddress::v4(10, 0, 16, 99);
let mut ip_addrs = [net::wire::IpCidr::new(local_addr, 24)];
2019-11-24 22:09:52 +08:00
let mut iface =
net::iface::EthernetInterfaceBuilder::new(c.resources.ethernet)
.ethernet_addr(hardware_addr)
.neighbor_cache(neighbor_cache)
.ip_addrs(&mut ip_addrs[..])
.finalize();
2019-05-31 00:03:48 +08:00
let mut socket_set_entries: [_; 8] = Default::default();
2019-11-24 22:09:52 +08:00
let mut sockets =
net::socket::SocketSet::new(&mut socket_set_entries[..]);
2019-05-31 00:03:48 +08:00
create_socket!(sockets, tcp_rx_storage0, tcp_tx_storage0, tcp_handle0);
create_socket!(sockets, tcp_rx_storage0, tcp_tx_storage0, tcp_handle1);
2019-05-31 04:57:41 +08:00
// unsafe { eth::enable_interrupt(DMA); }
2019-06-03 23:06:11 +08:00
let mut time = 0u32;
2019-08-26 21:47:42 +08:00
let mut next_ms = Instant::now();
next_ms += 400_000.cycles();
2019-06-03 23:06:11 +08:00
let mut server = Server::new();
2019-08-26 21:47:42 +08:00
let mut iir_state: resources::iir_state = c.resources.iir_state;
let mut iir_ch: resources::iir_ch = c.resources.iir_ch;
2019-05-31 00:03:48 +08:00
loop {
2019-05-31 04:57:41 +08:00
// if ETHERNET_PENDING.swap(false, Ordering::Relaxed) { }
2019-08-26 21:47:42 +08:00
let tick = Instant::now() > next_ms;
2019-06-03 23:06:11 +08:00
if tick {
next_ms += 400_000.cycles();
2019-05-31 04:57:41 +08:00
time += 1;
}
{
2019-11-24 22:09:52 +08:00
let socket =
&mut *sockets.get::<net::socket::TcpSocket>(tcp_handle0);
2019-06-03 23:06:11 +08:00
if socket.state() == net::socket::TcpState::CloseWait {
socket.close();
} else if !(socket.is_open() || socket.is_listening()) {
2019-11-24 22:09:52 +08:00
socket
.listen(1234)
.unwrap_or_else(|e| warn!("TCP listen error: {:?}", e));
2019-06-03 23:06:11 +08:00
} else if tick && socket.can_send() {
2019-05-31 05:50:18 +08:00
let s = iir_state.lock(|iir_state| Status {
t: time,
x0: iir_state[0][0],
y0: iir_state[0][2],
x1: iir_state[1][0],
2019-11-24 22:09:52 +08:00
y1: iir_state[1][2],
2019-05-31 05:50:18 +08:00
});
2019-06-03 23:06:11 +08:00
json_reply(socket, &s);
2019-05-31 04:57:41 +08:00
}
}
{
2019-11-24 22:09:52 +08:00
let socket =
&mut *sockets.get::<net::socket::TcpSocket>(tcp_handle1);
2019-06-03 23:06:11 +08:00
if socket.state() == net::socket::TcpState::CloseWait {
socket.close();
} else if !(socket.is_open() || socket.is_listening()) {
2019-11-24 22:09:52 +08:00
socket
.listen(1235)
.unwrap_or_else(|e| warn!("TCP listen error: {:?}", e));
2019-05-31 04:57:41 +08:00
} else {
2019-06-03 23:54:35 +08:00
server.poll(socket, |req: &Request| {
2019-06-03 23:06:11 +08:00
if req.channel < 2 {
2019-11-24 22:09:52 +08:00
iir_ch.lock(|iir_ch| {
iir_ch[req.channel as usize] = req.iir
});
2019-06-03 23:06:11 +08:00
}
});
2019-05-31 04:57:41 +08:00
}
}
2019-11-24 22:09:52 +08:00
if !match iface.poll(
&mut sockets,
net::time::Instant::from_millis(time as i64),
) {
2019-05-31 04:57:41 +08:00
Ok(changed) => changed,
Err(net::Error::Unrecognized) => true,
2019-11-24 22:09:52 +08:00
Err(e) => {
info!("iface poll error: {:?}", e);
true
}
2019-05-31 04:57:41 +08:00
} {
// cortex_m::asm::wfi();
}
2019-05-31 00:03:48 +08:00
}
}
2020-04-22 01:02:52 +08:00
*/
2019-04-28 19:37:14 +08:00
2019-05-31 05:50:18 +08:00
#[task(priority = 1, schedule = [tick])]
2019-05-31 00:18:59 +08:00
fn tick(c: tick::Context) {
2019-05-31 04:57:41 +08:00
static mut TIME: u32 = 0;
*TIME += 1;
2019-05-31 00:18:59 +08:00
const PERIOD: u32 = 200_000_000;
c.schedule.tick(c.scheduled + PERIOD.cycles()).unwrap();
}
2020-04-22 01:02:52 +08:00
#[task(binds = TIM2)]
fn tim2(_c: tim2::Context) {
info!("TIM2 interrupt");
}
2019-05-31 00:03:48 +08:00
// seems to slow it down
// #[link_section = ".data.spi1"]
2020-04-19 19:37:03 +08:00
#[task(binds = SPI2, resources = [adc1, dac1, iir_state, iir_ch], priority = 2)]
fn spi2(c: spi2::Context) {
2019-05-31 00:03:48 +08:00
#[cfg(feature = "bkpt")]
cortex_m::asm::bkpt();
2020-04-19 19:37:03 +08:00
let adc = c.resources.adc1;
let dac = c.resources.dac1;
2019-08-26 21:47:42 +08:00
let iir_ch = c.resources.iir_ch;
let iir_state = c.resources.iir_state;
2019-05-31 00:03:48 +08:00
2020-04-19 19:37:03 +08:00
// TODO: Doesn't make sense if RXP is unset.
if adc.is_rxp() {
let a: u16 = adc.read().unwrap();
2019-05-31 00:03:48 +08:00
let x0 = f32::from(a as i16);
2019-05-31 00:18:59 +08:00
let y0 = iir_ch[0].update(&mut iir_state[0], x0);
2019-05-31 00:03:48 +08:00
let d = y0 as i16 as u16 ^ 0x8000;
2019-05-28 02:43:39 +08:00
2020-04-19 19:37:03 +08:00
// TODO: Handle errors.
dac.send(d).unwrap();
}
2020-04-19 19:37:03 +08:00
#[cfg(feature = "bkpt")]
cortex_m::asm::bkpt();
}
#[task(binds = SPI3, resources = [adc2, dac2, iir_state, iir_ch], priority = 2)]
fn spi3(c: spi3::Context) {
#[cfg(feature = "bkpt")]
cortex_m::asm::bkpt();
let adc = c.resources.adc2;
let dac = c.resources.dac2;
let iir_ch = c.resources.iir_ch;
let iir_state = c.resources.iir_state;
// TODO: Doesn't make sense if RXP is unset.
if adc.is_rxp() {
let a: u16 = adc.read().unwrap();
2019-05-31 00:03:48 +08:00
let x0 = f32::from(a as i16);
2019-05-31 00:18:59 +08:00
let y0 = iir_ch[1].update(&mut iir_state[1], x0);
2019-05-31 00:03:48 +08:00
let d = y0 as i16 as u16 ^ 0x8000;
2020-04-19 19:37:03 +08:00
// TODO: Handle errors.
dac.send(d).unwrap();
2019-05-31 00:03:48 +08:00
}
#[cfg(feature = "bkpt")]
cortex_m::asm::bkpt();
2019-03-18 19:56:26 +08:00
}
2019-05-31 00:03:48 +08:00
2019-05-31 04:57:41 +08:00
/*
2019-08-26 21:47:42 +08:00
#[task(binds = ETH, resources = [ethernet_periph], priority = 1)]
fn eth(c: eth::Context) {
let dma = &c.resources.ethernet_periph.1;
2019-05-31 00:03:48 +08:00
ETHERNET_PENDING.store(true, Ordering::Relaxed);
unsafe { eth::interrupt_handler(dma) }
}
2019-05-31 04:57:41 +08:00
*/
2019-05-31 00:03:48 +08:00
extern "C" {
2019-05-31 04:57:41 +08:00
// hw interrupt handlers for RTFM to use for scheduling tasks
// one per priority
2019-05-31 00:03:48 +08:00
fn DCMI();
fn JPEG();
fn SDMMC();
}
};
2020-04-22 01:02:52 +08:00
/*
2019-11-24 22:09:52 +08:00
#[derive(Deserialize, Serialize)]
2019-05-28 02:43:39 +08:00
struct Request {
2019-05-28 18:15:15 +08:00
channel: u8,
2019-05-24 00:57:00 +08:00
iir: IIR,
}
2019-05-28 02:43:39 +08:00
#[derive(Serialize)]
struct Response<'a> {
code: i32,
message: &'a str,
}
2019-05-31 04:57:41 +08:00
#[derive(Serialize)]
struct Status {
t: u32,
x0: f32,
y0: f32,
x1: f32,
2019-11-24 22:09:52 +08:00
y1: f32,
2019-05-28 02:43:39 +08:00
}
2019-06-03 23:06:11 +08:00
fn json_reply<T: Serialize>(socket: &mut net::socket::TcpSocket, msg: &T) {
2019-05-31 04:57:41 +08:00
let mut u: String<U128> = to_string(msg).unwrap();
u.push('\n').unwrap();
socket.write_str(&u).unwrap();
}
2019-06-03 23:06:11 +08:00
struct Server {
data: Vec<u8, U256>,
discard: bool,
}
2019-05-28 18:59:26 +08:00
impl Server {
fn new() -> Self {
2019-11-24 22:09:52 +08:00
Self {
data: Vec::new(),
discard: false,
}
2019-05-28 18:59:26 +08:00
}
2019-11-24 22:09:52 +08:00
fn poll<T, F, R>(
&mut self,
socket: &mut net::socket::TcpSocket,
f: F,
) -> Option<R>
where
T: DeserializeOwned,
F: FnOnce(&T) -> R,
2019-06-03 23:54:35 +08:00
{
2019-05-28 18:59:26 +08:00
while socket.can_recv() {
2019-11-24 22:09:52 +08:00
let found = socket
.recv(|buf| {
let (len, found) =
match buf.iter().position(|&c| c as char == '\n') {
Some(end) => (end + 1, true),
None => (buf.len(), false),
};
if self.data.len() + len >= self.data.capacity() {
self.discard = true;
self.data.clear();
} else if !self.discard && len > 0 {
self.data.extend_from_slice(&buf[..len]).unwrap();
}
(len, found)
})
.unwrap();
2019-06-03 23:06:11 +08:00
if found {
if self.discard {
self.discard = false;
2019-11-24 22:09:52 +08:00
json_reply(
socket,
&Response {
code: 520,
message: "command buffer overflow",
},
);
2019-06-04 01:08:21 +08:00
self.data.clear();
2019-06-03 23:06:11 +08:00
} else {
let r = from_slice::<T>(&self.data[..self.data.len() - 1]);
2019-06-03 23:06:11 +08:00
self.data.clear();
match r {
Ok(res) => {
2019-06-04 01:08:21 +08:00
let r = f(&res);
2019-11-24 22:09:52 +08:00
json_reply(
socket,
&Response {
code: 200,
message: "ok",
},
);
2019-06-04 01:08:21 +08:00
return Some(r);
2019-11-24 22:09:52 +08:00
}
2019-06-03 23:06:11 +08:00
Err(err) => {
warn!("parse error {:?}", err);
2019-11-24 22:09:52 +08:00
json_reply(
socket,
&Response {
code: 550,
message: "parse error",
},
);
}
2019-06-03 23:06:11 +08:00
}
2019-05-28 02:43:39 +08:00
}
2019-06-03 23:06:11 +08:00
}
2019-05-28 02:43:39 +08:00
}
2019-06-04 01:08:21 +08:00
None
2019-05-28 02:43:39 +08:00
}
}
2020-04-22 01:02:52 +08:00
*/
2019-05-24 00:57:00 +08:00
2019-03-18 19:56:26 +08:00
#[exception]
fn HardFault(ef: &cortex_m_rt::ExceptionFrame) -> ! {
panic!("HardFault at {:#?}", ef);
}
#[exception]
fn DefaultHandler(irqn: i16) {
panic!("Unhandled exception (IRQn = {})", irqn);
}