#![no_std] #![feature(asm, used, const_fn, naked_functions, alloc, box_syntax)] #![no_main] #![feature(extern_prelude)] #[macro_use] extern crate hcl; #[macro_use] extern crate alloc; use core::mem; use hcl::platform::gpio; use hcl::platform::rcc; use hcl::platform::scs; use hcl::platform::PeripheralRef; use hcl::platform::Location; use hcl::platform::spi; fn configure_clocks(rcc: &mut rcc::RCC) { rcc.clock_control.set_hse_on(true); while !rcc.clock_control.hse_ready() {} rcc.clock_config .configure(|c| { c.set_pll_multiplier(10) .set_pll_source(rcc::PllSource::HsiDiv2) }); rcc.clock_control.set_pll_on(true); while !rcc.clock_control.pll_ready() {} rcc.clock_config .switch_clock_source(rcc::SystemClockSource::Pll); } fn configure_peripherals(rcc: &mut hcl::platform::rcc::RCC, gpio_a: &mut gpio::GPIO, gpio_c: &mut gpio::GPIO) { rcc.apb2_enable .configure(|a| a.set_gpio_a(true).set_gpio_c(true).set_spi1(true)); gpio_a.configure(|g| { g.set_mode(2, gpio::PinMode::Output50MHz) .set_output_config(2, gpio::OutputConfig::AfPushPull) .set_mode(3, gpio::PinMode::Output50MHz) .set_output_config(3, gpio::OutputConfig::AfPushPull) // SCK1 .set_mode(5, gpio::PinMode::Output50MHz) .set_output_config(5, gpio::OutputConfig::AfPushPull) // MOSI1 .set_mode(7, gpio::PinMode::Output50MHz) .set_output_config(7, gpio::OutputConfig::AfPushPull) // MISO1 .set_mode(6, gpio::PinMode::Input) .set_input_config(6, gpio::InputConfig::PullUpDown) // ST7735 cs pin .set_mode(0, gpio::PinMode::Output50MHz) .set_output_config(0, gpio::OutputConfig::PushPull) }); gpio_c.configure(|g| { g.set_mode(13, gpio::PinMode::Output50MHz) .set_output_config(13, gpio::OutputConfig::PushPull) }); } fn write_byte(spi : &mut PeripheralRef, byte : u8) where SPIAddr: Location { spi.set_data(byte as u32); while !spi.tx_buffer_empty() {}; while spi.busy() {}; } const LOGO_PX: [u16; 11] = [0x4081, 0x4880, 0x4880, 0x2861, 0x38c1, 0x38c1, 0x30a1, 0x3081, 0x2861, 0x1861, 0x1061]; // allowing inlining into main() breaks the stack, since main() must be naked to set up a process stack. #[inline(never)] fn run(mut scs: scs::Instance, mut p: hcl::platform::Instance) { configure_clocks(&mut p.rcc); configure_peripherals(&mut p.rcc, &mut p.gpio_a, &mut p.gpio_c); let mut spi = p.spi1; let mut gpio = p.gpio_a; spi.configure(|s| { s.set_master_mode(true) .set_software_slave_select(true) .set_clock_divider(8) // required for master mode, even if ss is done manually .set_slave_select_output_enabled(true) .set_enabled(true) }); gpio.set_bit(0); loop { for i in 0..11 { let word = LOGO_PX[i]; let data0 = (word >> 8) as u8; let data1 = (word & 0xFF) as u8; gpio.reset_bit(0); write_byte(&mut spi, data0); write_byte(&mut spi, data1); gpio.set_bit(0); } } } entry_point!(main); fn main(scs: scs::Instance, p: hcl::platform::Instance) { declare_thread_stack!(stack, 3072); unsafe { hcl::set_process_stack(&stack); hcl::use_process_stack(true); } run(scs, p); }