223 lines
6.3 KiB
Rust
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();
|
|
}
|
|
} |