From 6b6e79ddfc6580f395cae0668949ecc2d7eeb657 Mon Sep 17 00:00:00 2001 From: Zheng-Jiakun Date: Thu, 12 Aug 2021 11:09:58 +0800 Subject: [PATCH] add serial port to print debug message --- Cargo.toml | 1 - src/main.rs | 359 ++++++++++++++++++++++++++++++---------------------- 2 files changed, 207 insertions(+), 153 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 4669915..00fde3a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,4 +20,3 @@ panic-halt = "0.2.0" stm32f1xx-hal = {version = "0.6.1", features = ["rt", "stm32f103", "high"]} enc424j600 = { git = "https://git.m-labs.hk/M-Labs/ENC424J600.git", features = ["smoltcp-examples", "cortex-m-cpu"]} - diff --git a/src/main.rs b/src/main.rs index 3d9920f..a8225cc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,8 +1,15 @@ #![no_std] #![no_main] +// use cortex_m::{asm, singleton}; + +pub mod serial; +use core::str; +use core::fmt::Write; +// use nb::block; extern crate panic_itm; -use cortex_m::{iprintln, iprint}; +// use cortex_m::{iprintln, iprint}; +use cortex_m_rt::entry; use embedded_hal::{ digital::v2::OutputPin, @@ -15,9 +22,12 @@ use stm32f1xx_hal::{ flash::FlashExt, gpio::GpioExt, time::U32Ext, - stm32::ITM, + // stm32::ITM, delay::Delay, spi::Spi, + pac, + // adc, + prelude::* // time::Hertz }; use enc424j600::smoltcp_phy; @@ -25,10 +35,12 @@ use enc424j600::smoltcp_phy; use smoltcp::wire::{ EthernetAddress, IpAddress, IpCidr, Ipv6Cidr }; -use smoltcp::iface::{NeighborCache, EthernetInterfaceBuilder, EthernetInterface}; +use smoltcp::iface::{ + NeighborCache, + EthernetInterfaceBuilder, + // EthernetInterface +}; use smoltcp::socket::{SocketSet, TcpSocket, TcpSocketBuffer}; -use core::str; -use core::fmt::Write; /// Timer use core::cell::RefCell; @@ -38,7 +50,16 @@ use stm32f1xx_hal::{ rcc::Clocks, time::MilliSeconds, timer::{Timer, Event as TimerEvent}, - stm32::SYST + stm32::SYST, + serial::{ + Config, + Serial, + // Tx + }, + // dma::*, + // dma::dma1::*, + // pac::* + // dma::Half }; use smoltcp::time::Instant; @@ -101,141 +122,182 @@ static mut NET_STORE: NetStorage = NetStorage { neighbor_cache: [None; 8], }; +#[entry()] +fn main() -> ! { + let mut cp = cortex_m::Peripherals::take().unwrap(); + let dp = pac::Peripherals::take().unwrap(); -#[rtic::app(device = stm32f1xx_hal::stm32, peripherals = true, monotonic = rtic::cyccnt::CYCCNT)] -const APP: () = { - struct Resources { - eth_iface: EthernetInterface< - 'static, - smoltcp_phy::SmoltcpDevice>, - itm: ITM - } + cp.SCB.enable_icache(); + cp.SCB.enable_dcache(&mut cp.CPUID); - #[init()] - fn init(mut c: init::Context) -> init::LateResources { - c.core.SCB.enable_icache(); - c.core.SCB.enable_dcache(&mut c.core.CPUID); + // Enable monotonic timer CYCCNT + cp.DWT.enable_cycle_counter(); + cp.DCB.enable_trace(); - // Enable monotonic timer CYCCNT - c.core.DWT.enable_cycle_counter(); - c.core.DCB.enable_trace(); + let mut flash = dp.FLASH.constrain(); + let mut rcc = dp.RCC.constrain(); - let mut flash = c.device.FLASH.constrain(); - let mut rcc = c.device.RCC.constrain(); + 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()) - .freeze(&mut flash.acr); - - let mut delay = Delay::new(c.core.SYST, clocks); - - // Init ITM - let mut itm = c.core.ITM; - let stim0 = &mut itm.stim[0]; - - iprintln!(stim0, - "Eth TCP Server on STM32-F103 via NIC100/ENC424J600"); - - // NIC100 / ENC424J600 Set-up - let spi1 = c.device.SPI1; - let gpioa = c.device.GPIOA.split(&mut rcc.apb2); - let mut gpiob = c.device.GPIOB.split(&mut rcc.apb2); - let mut gpioc = c.device.GPIOC.split(&mut rcc.apb2); - let mut afio = c.device.AFIO.constrain(&mut rcc.apb2); + 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); - 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); + let mut delay = Delay::new(cp.SYST, clocks); - // 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,); + 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); - SpiEth::new(spi_eth_port, spi1_nss) - .cpu_freq_mhz(72) - }; + // USART1 + let tx = gpioa.pa9.into_alternate_push_pull(&mut gpioa.crh); + let rx = gpioa.pa10; - // Init controller - match spi_eth.reset(&mut delay) { - Ok(_) => { - iprintln!(stim0, "Initializing Ethernet...") - } - Err(_) => { - panic!("Ethernet initialization failed!") - } - } + // 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, + ); - // Read MAC - let mut eth_mac_addr: [u8; 6] = [0; 6]; - spi_eth.read_mac_addr(&mut eth_mac_addr); - 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), - _ => () - }; - } + // let mut serial_tx = serial.split().0.with_dma(dma1_chs.4); + let mut serial_tx = serial.split().0; - // Init Rx/Tx buffers - spi_eth.init_rxbuf(); - spi_eth.init_txbuf(); - iprintln!(stim0, "Ethernet controller initialized"); + + // 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 smoltcp interface - let eth_iface = { - let device = smoltcp_phy::SmoltcpDevice::new(spi_eth); - 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[..]); + // Init ITM + // let mut itm = cp.ITM; + // let stim0 = &mut itm.stim[0]; - EthernetInterfaceBuilder::new(device) - .ethernet_addr(EthernetAddress(eth_mac_addr)) - .neighbor_cache(neighbor_cache) - .ip_addrs(&mut store.ip_addrs[..]) - .finalize() - }; - iprintln!(stim0, "Ethernet interface initialized"); + // iprintln!(stim0, + // "Eth TCP Server on STM32-F103 via NIC100/ENC424J600"); - let mut led = gpioc.pc0.into_push_pull_output(&mut gpioc.crl); - led.set_high().unwrap(); - - eth_iface + // 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) }; - // Setup SysTick after releasing SYST from Delay - // Reference to stm32-eth:examples/ip.rs - timer_setup(delay.free(), clocks); - iprintln!(stim0, "Timer initialized"); - - init::LateResources { - eth_iface, - itm + // Init controller + match spi_eth.reset(&mut delay) { + Ok(_) => { + // iprintln!(stim0, "Initializing Ethernet...") + serial_tx.write_fmt(format_args!("Initializing Ethernet...\n")).unwrap(); + } + Err(_) => { + panic!("Ethernet initialization failed!") + } } - } - #[idle(resources=[eth_iface, itm])] - fn idle(c: idle::Context) -> ! { - let stim0 = &mut c.resources.itm.stim[0]; - let iface = c.resources.eth_iface; + // 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(); + }, + _ => () + }; + } + + // 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(); + + // Init smoltcp interface + let eth_iface = { + let device = smoltcp_phy::SmoltcpDevice::new(spi_eth); + + 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() + }; + // iprintln!(stim0, "Ethernet interface initialized"); + serial_tx.write_fmt(format_args!("Ethernet interface initialized\n")).unwrap(); + + eth_iface + }; + + // Setup SysTick after releasing SYST from Delay + // Reference to stm32-eth:examples/ip.rs + timer_setup(delay.free(), clocks); + // iprintln!(stim0, "Timer initialized"); + + let mut led = gpioc.pc0.into_push_pull_output(&mut gpioc.crl); + led.set_high().unwrap(); + + loop { + // let stim0 = &mut c.resources.itm.stim[0]; + let mut iface = eth_iface; // Copied / modified from smoltcp: // examples/loopback.rs @@ -255,12 +317,12 @@ const APP: () = { }; let mut socket_set_entries = [None, None]; let mut socket_set = SocketSet::new(&mut socket_set_entries[..]); - let echo_handle = socket_set.add(echo_socket); let greet_handle = socket_set.add(greet_socket); { let store = unsafe { &mut NET_STORE }; - iprintln!(stim0, - "TCP sockets will listen at {}", store.ip_addrs[0].address()); + // 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(); } // Copied / modified from: @@ -275,47 +337,40 @@ const APP: () = { Ok(_) => { }, Err(e) => { - iprintln!(stim0, "[{}] Poll error: {:?}", instant, e) - } - } - // Control the "echoing" socket (:1234) - { - let mut socket = socket_set.get::(echo_handle); - if !socket.is_open() { - iprintln!(stim0, - "[{}] Listening to port 1234 for echoing, time-out in 10s", instant); - socket.listen(1234).unwrap(); - socket.set_timeout(Some(smoltcp::time::Duration::from_millis(10000))); - } - if socket.can_recv() { - iprintln!(stim0, - "[{}] Received packet: {:?}", instant, socket.recv(|buffer| { - (buffer.len(), str::from_utf8(buffer).unwrap()) - })); + // iprintln!(stim0, "[{}] Poll error: {:?}", instant, e) + serial_tx.write_fmt(format_args!("[{}] Poll error: {:?}\n", instant, e)).unwrap(); } } // Control the "greeting" socket (:4321) { let mut socket = socket_set.get::(greet_handle); if !socket.is_open() { - iprintln!(stim0, - "[{}] Listening to port 4321 for greeting, \ - please connect to the port", instant); + // 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(); socket.listen(4321).unwrap(); + // socket.set_timeout(Some(smoltcp::time::Duration::from_millis(10000))); } if socket.can_send() { let greeting = "Welcome to the server demo for STM32F103!"; write!(socket, "{}\n", greeting).unwrap(); - iprintln!(stim0, - "[{}] Greeting sent, socket closed", instant); + // iprintln!(stim0, + // "[{}] Greeting sent, socket closed", instant); + serial_tx.write_fmt(format_args!("[{}] Greeting sent, socket closed\n", instant)).unwrap(); socket.close(); } + + 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(); + } } } } - - extern "C" { - fn EXTI0(); - } -}; +} \ No newline at end of file