ethernet: minimal impl for urukul as scpi device

This commit is contained in:
occheung 2020-08-31 13:32:08 +08:00
parent b0272a6fc2
commit d78f85721f
4 changed files with 94 additions and 35 deletions

View File

@ -24,9 +24,12 @@ 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::OutputPin; use stm32h7xx_hal::hal::digital::v2::{
OutputPin,
InputPin,
};
use stm32h7xx_hal::rcc::CoreClocks; use stm32h7xx_hal::rcc::CoreClocks;
use stm32h7xx_hal::{pac, prelude::*, stm32, stm32::interrupt}; use stm32h7xx_hal::{pac, prelude::*, spi, stm32, stm32::interrupt};
use Speed::*; use Speed::*;
use libm::round; use libm::round;
@ -55,7 +58,24 @@ 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::scpi::{MyDevice, TREE}; use firmware;
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
@ -111,6 +131,7 @@ 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.
@ -127,14 +148,65 @@ 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 gpioe = dp.GPIOE.split(ccdr.peripheral.GPIOE); let gpiod = dp.GPIOD.split(ccdr.peripheral.GPIOD);
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(
@ -192,18 +264,17 @@ fn main() -> ! {
.finalize(); .finalize();
// SCPI configs // SCPI configs
let mut my_device = MyDevice {}; // Device was declared in prior
let mut errors = ArrayErrorQueue::<[Error; 10]>::new(); let mut errors = ArrayErrorQueue::<[Error; 10]>::new();
let mut context = Context::new(&mut my_device, &mut errors, TREE); let mut context = Context::new(&mut urukul, &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
// TODO: Need Iinitialize TCP socket storage? // TCP socket buffers
// 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];
@ -242,11 +313,9 @@ 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();
}, },
}; };
@ -258,16 +327,6 @@ 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)
@ -293,11 +352,7 @@ 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);
@ -305,7 +360,6 @@ 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

@ -8,7 +8,6 @@ use core::{
cell, cell,
marker::PhantomData, marker::PhantomData,
}; };
use cortex_m; use cortex_m;
use cortex_m_semihosting::hprintln; use cortex_m_semihosting::hprintln;

View File

@ -83,7 +83,7 @@ fn main() -> ! {
); );
/* /*
* I/O_Update -> PB13 * I/O_Update -> PB15
*/ */
let io_update = gpiob.pb15.into_push_pull_output(); let io_update = gpiob.pb15.into_push_pull_output();

View File

@ -28,7 +28,9 @@ use scpi::{
scpi_tree, scpi_tree,
}; };
pub struct MyDevice; use crate::Urukul;
// pub struct MyDevice;
pub struct HelloWorldCommand {} pub struct HelloWorldCommand {}
impl Command for HelloWorldCommand { impl Command for HelloWorldCommand {
@ -44,7 +46,11 @@ 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(())
} }