Syrostan-MCU/src/main.rs

376 lines
12 KiB
Rust
Raw Normal View History

2021-07-23 17:31:28 +08:00
#![no_std]
#![no_main]
2021-08-12 11:09:58 +08:00
// use cortex_m::{asm, singleton};
pub mod serial;
use core::str;
use core::fmt::Write;
// use nb::block;
2021-07-29 15:57:52 +08:00
extern crate panic_itm;
2021-08-12 11:09:58 +08:00
// use cortex_m::{iprintln, iprint};
use cortex_m_rt::entry;
2021-07-29 15:57:52 +08:00
use embedded_hal::{
digital::v2::OutputPin,
// blocking::delay::DelayMs
};
// use stm32f1xx_hal::spi::SpiRegisterBlock;
use stm32f1xx_hal::{
afio::AfioExt,
rcc::RccExt,
flash::FlashExt,
gpio::GpioExt,
time::U32Ext,
2021-08-12 11:09:58 +08:00
// stm32::ITM,
2021-07-29 15:57:52 +08:00
delay::Delay,
spi::Spi,
2021-08-12 11:09:58 +08:00
pac,
// adc,
prelude::*
2021-07-29 15:57:52 +08:00
// time::Hertz
};
use enc424j600::smoltcp_phy;
use smoltcp::wire::{
EthernetAddress, IpAddress, IpCidr, Ipv6Cidr
};
2021-08-12 11:09:58 +08:00
use smoltcp::iface::{
NeighborCache,
EthernetInterfaceBuilder,
// EthernetInterface
};
2021-07-29 15:57:52 +08:00
use smoltcp::socket::{SocketSet, TcpSocket, TcpSocketBuffer};
/// Timer
use core::cell::RefCell;
use cortex_m::interrupt::Mutex;
use cortex_m_rt::exception;
use stm32f1xx_hal::{
rcc::Clocks,
time::MilliSeconds,
timer::{Timer, Event as TimerEvent},
2021-08-12 11:09:58 +08:00
stm32::SYST,
serial::{
Config,
Serial,
// Tx
},
// dma::*,
// dma::dma1::*,
// pac::*
// dma::Half
2021-07-29 15:57:52 +08:00
};
use smoltcp::time::Instant;
/// Rate in Hz
const TIMER_RATE: u32 = 20;
/// Interval duration in milliseconds
const TIMER_DELTA: u32 = 1000 / TIMER_RATE;
/// Elapsed time in milliseconds
static TIMER_MS: Mutex<RefCell<u32>> = Mutex::new(RefCell::new(0));
/// Setup SysTick exception
fn timer_setup(syst: SYST, clocks: Clocks) {
let timer = Timer::syst(syst, &clocks);
timer.start_count_down(TIMER_RATE.hz()).listen(TimerEvent::Update);
}
/// SysTick exception (Timer)
#[exception]
fn SysTick() {
cortex_m::interrupt::free(|cs| {
*TIMER_MS.borrow(cs)
.borrow_mut() += TIMER_DELTA;
});
}
/// Obtain current time in milliseconds
pub fn timer_now() -> MilliSeconds {
let ms = cortex_m::interrupt::free(|cs| {
*TIMER_MS.borrow(cs)
.borrow()
});
ms.ms()
}
///spi
use stm32f1xx_hal::{
stm32::SPI1,
spi::Spi1Remap,
gpio::{
gpiob::{PB3, PB4, PB5},
gpioc::PC13,
Alternate, Output, PushPull, Input, Floating
2021-07-23 17:31:28 +08:00
}
2021-07-29 15:57:52 +08:00
};
type SpiEth = enc424j600::Enc424j600<
Spi<SPI1, Spi1Remap, (PB3<Alternate<PushPull>>, PB4<Input<Floating>>, PB5<Alternate<PushPull>>)>,
PC13<Output<PushPull>>
>;
pub struct NetStorage {
ip_addrs: [IpCidr; 1],
neighbor_cache: [Option<(IpAddress, smoltcp::iface::Neighbor)>; 8],
2021-07-23 17:31:28 +08:00
}
2021-07-29 15:57:52 +08:00
static mut NET_STORE: NetStorage = NetStorage {
// Placeholder for the real IP address, which is initialized at runtime.
ip_addrs: [IpCidr::Ipv6(
Ipv6Cidr::SOLICITED_NODE_PREFIX,
)],
neighbor_cache: [None; 8],
};
2021-08-12 11:09:58 +08:00
#[entry()]
fn main() -> ! {
let mut cp = cortex_m::Peripherals::take().unwrap();
let dp = pac::Peripherals::take().unwrap();
2021-07-29 15:57:52 +08:00
2021-08-12 11:09:58 +08:00
cp.SCB.enable_icache();
cp.SCB.enable_dcache(&mut cp.CPUID);
// Enable monotonic timer CYCCNT
cp.DWT.enable_cycle_counter();
cp.DCB.enable_trace();
let mut flash = dp.FLASH.constrain();
let mut rcc = dp.RCC.constrain();
2021-07-29 15:57:52 +08:00
2021-08-12 11:09:58 +08:00
let dma1_chs = dp.DMA1.split(&mut rcc.ahb);
let clocks = rcc
.cfgr
.use_hse(8.mhz())
.sysclk(72.mhz())
.hclk(72.mhz())
.pclk1(36.mhz())
.pclk2(72.mhz())
.adcclk(2.mhz())
.freeze(&mut flash.acr);
2021-07-29 15:57:52 +08:00
2021-08-12 11:09:58 +08:00
let mut delay = Delay::new(cp.SYST, clocks);
let mut gpioa = dp.GPIOA.split(&mut rcc.apb2);
let mut gpiob = dp.GPIOB.split(&mut rcc.apb2);
let mut gpioc = dp.GPIOC.split(&mut rcc.apb2);
let mut afio = dp.AFIO.constrain(&mut rcc.apb2);
// USART1
let tx = gpioa.pa9.into_alternate_push_pull(&mut gpioa.crh);
let rx = gpioa.pa10;
// Set up the usart device. Taks ownership over the USART register and tx/rx pins. The rest of
// the registers are used to enable and configure the device.
let serial = Serial::usart1(
dp.USART1,
(tx, rx),
&mut afio.mapr,
Config::default().baudrate(9600.bps()),
clocks,
&mut rcc.apb2,
);
// let mut serial_tx = serial.split().0.with_dma(dma1_chs.4);
let mut serial_tx = serial.split().0;
2021-07-29 15:57:52 +08:00
2021-08-12 11:09:58 +08:00
// let dma_ch1 = dma1_chs.1;
// // Setup ADC
// let adc1 = adc::Adc::adc1(dp.ADC1, &mut rcc.apb2, clocks);
// // Setup GPIOA
// // Configure pa0 as an analog input
// let adc_ch15 = gpioc.pc5.into_analog(&mut gpioc.crl);
// let adc_dma = adc1.with_dma(adc_ch15, dma_ch1);
// let buf = singleton!(: [u16; 8] = [0; 8]).unwrap();
// let (_buf, adc_dma) = adc_dma.read(buf).wait();
// let (_adc1, _adc_ch15, _dma_ch1) = adc_dma.split();
// // let buf = singleton!(: [[u16; 8]; 2] = [[0; 8]; 2]).unwrap();
// // let mut circ_buffer = adc_dma.circ_read(buf);
// // while circ_buffer.readable_half().unwrap() != Half::First {}
// // let _first_half = circ_buffer.peek(|half, _| *half).unwrap();
// // while circ_buffer.readable_half().unwrap() != Half::Second {}
// // let _second_half = circ_buffer.peek(|half, _| *half).unwrap();
// // let (_buf, adc_dma) = circ_buffer.stop();
// // let (_adc1, _adc_ch15, _dma_ch1) = adc_dma.split();
// Init ITM
// let mut itm = cp.ITM;
// let stim0 = &mut itm.stim[0];
// iprintln!(stim0,
// "Eth TCP Server on STM32-F103 via NIC100/ENC424J600");
// NIC100 / ENC424J600 Set-up
let spi1 = dp.SPI1;
let (_pa15, pb3, pb4) = afio.mapr.disable_jtag(gpioa.pa15, gpiob.pb3, gpiob.pb4);
let spi1_sck = pb3.into_alternate_push_pull(&mut gpiob.crl);
let spi1_miso = pb4;//.into_floating_input(&mut gpiob.crl);
let spi1_mosi = gpiob.pb5.into_alternate_push_pull(&mut gpiob.crl);
let spi1_nss = gpioc.pc13.into_push_pull_output(&mut gpioc.crh);
// Create SPI1 for HAL
let eth_iface = {
let mut spi_eth = {
let spi_eth_port = Spi::spi1(
spi1,
(spi1_sck, spi1_miso, spi1_mosi),
&mut afio.mapr,
enc424j600::spi::interfaces::SPI_MODE,
// Hertz(enc424j600::spi::interfaces::SPI_CLOCK_FREQ),
9.mhz(),
clocks,
&mut rcc.apb2,);
SpiEth::new(spi_eth_port, spi1_nss)
.cpu_freq_mhz(72)
};
2021-07-29 15:57:52 +08:00
2021-08-12 11:09:58 +08:00
// Init controller
match spi_eth.reset(&mut delay) {
Ok(_) => {
// iprintln!(stim0, "Initializing Ethernet...")
serial_tx.write_fmt(format_args!("Initializing Ethernet...\n")).unwrap();
2021-07-29 15:57:52 +08:00
}
2021-08-12 11:09:58 +08:00
Err(_) => {
panic!("Ethernet initialization failed!")
2021-07-29 15:57:52 +08:00
}
2021-08-12 11:09:58 +08:00
}
2021-07-29 15:57:52 +08:00
2021-08-12 11:09:58 +08:00
// Read MAC
let mut eth_mac_addr: [u8; 6] = [0; 6];
spi_eth.read_mac_addr(&mut eth_mac_addr).unwrap();
for i in 0..6 {
let byte = eth_mac_addr[i];
match i {
// 0 => iprint!(stim0, "MAC Address = {:02x}-", byte),
// 1..=4 => iprint!(stim0, "{:02x}-", byte),
// 5 => iprint!(stim0, "{:02x}\n", byte),
0 => {
serial_tx.write_fmt(format_args!("MAC Address = {:02x}-", byte)).unwrap();
},
1..=4 => {
serial_tx.write_fmt(format_args!("{:02x}-", byte)).unwrap();
},
5 => {
serial_tx.write_fmt(format_args!("{:02x}\n", byte)).unwrap();
},
_ => ()
};
}
2021-07-29 15:57:52 +08:00
2021-08-12 11:09:58 +08:00
// Init Rx/Tx buffers
spi_eth.init_rxbuf().unwrap();
spi_eth.init_txbuf().unwrap();
// iprintln!(stim0, "Ethernet controller initialized");
serial_tx.write_fmt(format_args!("Ethernet controller initialized\n")).unwrap();
2021-07-29 15:57:52 +08:00
2021-08-12 11:09:58 +08:00
// Init smoltcp interface
let eth_iface = {
let device = smoltcp_phy::SmoltcpDevice::new(spi_eth);
2021-07-29 15:57:52 +08:00
2021-08-12 11:09:58 +08:00
let store = unsafe { &mut NET_STORE };
store.ip_addrs[0] = IpCidr::new(IpAddress::v4(192, 168, 1, 88), 24);
let neighbor_cache = NeighborCache::new(&mut store.neighbor_cache[..]);
EthernetInterfaceBuilder::new(device)
.ethernet_addr(EthernetAddress(eth_mac_addr))
.neighbor_cache(neighbor_cache)
.ip_addrs(&mut store.ip_addrs[..])
.finalize()
2021-07-29 15:57:52 +08:00
};
2021-08-12 11:09:58 +08:00
// iprintln!(stim0, "Ethernet interface initialized");
serial_tx.write_fmt(format_args!("Ethernet interface initialized\n")).unwrap();
eth_iface
};
2021-07-29 15:57:52 +08:00
2021-08-12 11:09:58 +08:00
// Setup SysTick after releasing SYST from Delay
// Reference to stm32-eth:examples/ip.rs
timer_setup(delay.free(), clocks);
// iprintln!(stim0, "Timer initialized");
2021-07-29 15:57:52 +08:00
2021-08-12 11:09:58 +08:00
let mut led = gpioc.pc0.into_push_pull_output(&mut gpioc.crl);
led.set_high().unwrap();
2021-07-29 15:57:52 +08:00
2021-08-12 11:09:58 +08:00
loop {
// let stim0 = &mut c.resources.itm.stim[0];
let mut iface = eth_iface;
2021-07-29 15:57:52 +08:00
// Copied / modified from smoltcp:
// examples/loopback.rs
let echo_socket = {
static mut TCP_SERVER_RX_DATA: [u8; 1024] = [0; 1024];
static mut TCP_SERVER_TX_DATA: [u8; 1024] = [0; 1024];
let tcp_rx_buffer = TcpSocketBuffer::new(unsafe { &mut TCP_SERVER_RX_DATA[..] });
let tcp_tx_buffer = TcpSocketBuffer::new(unsafe { &mut TCP_SERVER_TX_DATA[..] });
TcpSocket::new(tcp_rx_buffer, tcp_tx_buffer)
};
let greet_socket = {
static mut TCP_SERVER_RX_DATA: [u8; 256] = [0; 256];
static mut TCP_SERVER_TX_DATA: [u8; 256] = [0; 256];
let tcp_rx_buffer = TcpSocketBuffer::new(unsafe { &mut TCP_SERVER_RX_DATA[..] });
let tcp_tx_buffer = TcpSocketBuffer::new(unsafe { &mut TCP_SERVER_TX_DATA[..] });
TcpSocket::new(tcp_rx_buffer, tcp_tx_buffer)
};
let mut socket_set_entries = [None, None];
let mut socket_set = SocketSet::new(&mut socket_set_entries[..]);
let greet_handle = socket_set.add(greet_socket);
{
let store = unsafe { &mut NET_STORE };
2021-08-12 11:09:58 +08:00
// iprintln!(stim0,
// "TCP sockets will listen at {}", store.ip_addrs[0].address());
serial_tx.write_fmt(format_args!("TCP sockets will listen at {}\n", store.ip_addrs[0].address())).unwrap();
2021-07-29 15:57:52 +08:00
}
// Copied / modified from:
// smoltcp:examples/loopback.rs, examples/server.rs;
// stm32-eth:examples/ip.rs,
// git.m-labs.hk/M-Labs/tnetplug
loop {
// Poll
let now = timer_now().0;
let instant = Instant::from_millis(now as i64);
match iface.poll(&mut socket_set, instant) {
Ok(_) => {
},
Err(e) => {
2021-08-12 11:09:58 +08:00
// iprintln!(stim0, "[{}] Poll error: {:?}", instant, e)
serial_tx.write_fmt(format_args!("[{}] Poll error: {:?}\n", instant, e)).unwrap();
2021-07-29 15:57:52 +08:00
}
}
// Control the "greeting" socket (:4321)
{
let mut socket = socket_set.get::<TcpSocket>(greet_handle);
if !socket.is_open() {
2021-08-12 11:09:58 +08:00
// iprintln!(stim0,
// "[{}] Listening to port 4321 for greeting, \
// please connect to the port", instant);
serial_tx.write_fmt(format_args!("[{}] Listening to port 4321 for greeting, please connect to the port\n", instant)).unwrap();
2021-07-29 15:57:52 +08:00
socket.listen(4321).unwrap();
2021-08-12 11:09:58 +08:00
// socket.set_timeout(Some(smoltcp::time::Duration::from_millis(10000)));
2021-07-29 15:57:52 +08:00
}
if socket.can_send() {
let greeting = "Welcome to the server demo for STM32F103!";
write!(socket, "{}\n", greeting).unwrap();
2021-08-12 11:09:58 +08:00
// iprintln!(stim0,
// "[{}] Greeting sent, socket closed", instant);
serial_tx.write_fmt(format_args!("[{}] Greeting sent, socket closed\n", instant)).unwrap();
2021-07-29 15:57:52 +08:00
socket.close();
}
2021-08-12 11:09:58 +08:00
if socket.can_recv() {
// iprintln!(stim0,
// "[{}] Received packet: {:?}", instant, socket.recv(|buffer| {
// (buffer.len(), str::from_utf8(buffer).unwrap())
// }));
serial_tx.write_fmt(format_args!("[{}] Received packet: {:?}\n",
instant, socket.recv(|buffer| {(buffer.len(), str::from_utf8(buffer).unwrap())}))).unwrap();
}
2021-07-29 15:57:52 +08:00
}
}
}
2021-08-12 11:09:58 +08:00
}