Syrostan-MCU/src/main.rs

223 lines
6.3 KiB
Rust

#![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<SPI1, Spi1Remap, (PB3<Alternate<PushPull>>, PB4<Input<Floating>>, PB5<Alternate<PushPull>>)>,
PC13<Output<PushPull>>
>;
// A type definition for the GPIO pin to be used for our LED
type LEDPIN = gpioc::PC0<Output<PushPull>>;
// Make LED pin globally available
static G_LED: Mutex<RefCell<Option<LEDPIN>>> = Mutex::new(RefCell::new(None));
// Make timer interrupt registers globally available
static G_TIM: Mutex<RefCell<Option<CountDownTimer<TIM3>>>> = 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<LEDPIN> = None;
static mut TIM: Option<CountDownTimer<TIM3>> = 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();
}
}