#![no_std] #![no_main] use cortex_m::{singleton}; pub mod ethernet; use ethernet::{ ethernet_init, // ethernet_test }; pub mod serial; // use core::str; // use core::fmt::Write; // use nb::block; extern crate panic_itm; use cortex_m_rt::entry; 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, delay::Delay, spi::Spi, pac, adc, prelude::* // time::Hertz }; /// Timer use core::cell::RefCell; use cortex_m::interrupt::Mutex; // use cortex_m_rt::exception; use stm32f1xx_hal::{ timer::{Timer}, serial::{ Config, Serial, // Tx }, // dma::*, // dma::dma1::*, // pac::* // dma::Half }; use stm32f1xx_hal::{ gpio::{gpioc}, pac::{interrupt, Interrupt, TIM3}, timer::{CountDownTimer, Event}, }; ///spi use stm32f1xx_hal::{ stm32::SPI1, spi::Spi1Remap, gpio::{ gpiob::{PB3, PB4, PB5}, gpioc::PC13, Alternate, Output, PushPull, Input, Floating } }; type SpiEth = enc424j600::Enc424j600< Spi>, PB4>, PB5>)>, PC13> >; // A type definition for the GPIO pin to be used for our LED type LEDPIN = gpioc::PC0>; // Make LED pin globally available static G_LED: Mutex>> = Mutex::new(RefCell::new(None)); // Make timer interrupt registers globally available static G_TIM: Mutex>>> = Mutex::new(RefCell::new(None)); // Define an interupt handler, i.e. function to call when interrupt occurs. // This specific interrupt will "trip" when the timer TIM2 times out #[interrupt] fn TIM3() { static mut LED: Option = None; static mut TIM: Option> = None; let led = LED.get_or_insert_with(|| { cortex_m::interrupt::free(|cs| { // Move LED pin here, leaving a None in its place G_LED.borrow(cs).replace(None).unwrap() }) }); let tim = TIM.get_or_insert_with(|| { cortex_m::interrupt::free(|cs| { G_TIM.borrow(cs).replace(None).unwrap() }) }); let _ = led.toggle(); let _ = tim.wait(); } #[entry()] fn main() -> ! { let mut cp = cortex_m::Peripherals::take().unwrap(); let dp = pac::Peripherals::take().unwrap(); 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(); // 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); 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, mut _serial_rx) = serial.split(); // //ADC1 // 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(); // 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 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 spi_eth = SpiEth::new(spi_eth_port, spi1_nss).cpu_freq_mhz(72); ethernet_init(spi_eth, delay, &clocks); let mut led = gpioc.pc0.into_push_pull_output(&mut gpioc.crl); led.set_high().unwrap(); // Move the pin into our global storage cortex_m::interrupt::free(|cs| *G_LED.borrow(cs).borrow_mut() = Some(led)); // Set up a timer expiring after 1s let mut timer = Timer::tim3(dp.TIM3, &clocks, &mut rcc.apb1).start_count_down(1.hz()); // Generate an interrupt when the timer expires timer.listen(Event::Update); // Move the timer into our global storage cortex_m::interrupt::free(|cs| *G_TIM.borrow(cs).borrow_mut() = Some(timer)); unsafe { cortex_m::peripheral::NVIC::unmask(Interrupt::TIM3); } loop { // ethernet_test(); } }