aboutsummaryrefslogtreecommitdiffstats
path: root/sw/demo1/src/main.rs
diff options
context:
space:
mode:
authorMatthias P. Braendli <matthias.braendli@mpb.li>2020-06-13 18:38:31 +0200
committerMatthias P. Braendli <matthias.braendli@mpb.li>2020-06-13 18:38:31 +0200
commit93220f99a52dc93f9a2d5b11074f60156ef70210 (patch)
tree0d4daab75694ba547a7c7699ffdfef16db512429 /sw/demo1/src/main.rs
parent4b75ca49a1715212fd059d2e0e9e988c2309b792 (diff)
downloadpicardy-93220f99a52dc93f9a2d5b11074f60156ef70210.tar.gz
picardy-93220f99a52dc93f9a2d5b11074f60156ef70210.tar.bz2
picardy-93220f99a52dc93f9a2d5b11074f60156ef70210.zip
Get LCD and Si5351 I2C to work
Diffstat (limited to 'sw/demo1/src/main.rs')
-rw-r--r--sw/demo1/src/main.rs134
1 files changed, 124 insertions, 10 deletions
diff --git a/sw/demo1/src/main.rs b/sw/demo1/src/main.rs
index 80e38b9..4f8ce6e 100644
--- a/sw/demo1/src/main.rs
+++ b/sw/demo1/src/main.rs
@@ -8,13 +8,15 @@ use panic_semihosting as _;
use stm32f1xx_hal::{
prelude::*,
pac,
- timer::Timer,
+ i2c::{BlockingI2c, Mode},
+ delay::Delay,
};
use embedded_hal::digital::v2::{OutputPin, ToggleableOutputPin};
+use hd44780_driver::{Cursor, CursorBlink, Display, DisplayMode, HD44780};
+use si5351::{Si5351, Si5351Device};
use core::fmt::Write;
-use nb::block;
fn print(step: usize) -> Result<(), core::fmt::Error> {
let mut stdout = match hio::hstdout() {
@@ -37,7 +39,9 @@ fn main() -> ! {
let mut flash = dp.FLASH.constrain();
let mut rcc = dp.RCC.constrain();
+ let mut afio = dp.AFIO.constrain(&mut rcc.apb2);
let clocks = rcc.cfgr.freeze(&mut flash.acr);
+ let mut delay = Delay::new(cp.SYST, clocks);
let mut gpiob = dp.GPIOB.split(&mut rcc.apb2);
@@ -45,28 +49,138 @@ fn main() -> ! {
let mut led = gpiob.pb14.into_push_pull_output(&mut gpiob.crh);
led.set_low().unwrap();
- let mut timer = Timer::syst(cp.SYST, &clocks).start_count_down(1.hz());
+ // Configure I2C1 to be used for Si5351 and display
+ let scl = gpiob.pb6.into_alternate_open_drain(&mut gpiob.crl);
+ let sda = gpiob.pb7.into_alternate_open_drain(&mut gpiob.crl);
+
+ let i2c = BlockingI2c::i2c1(
+ dp.I2C1,
+ (scl, sda),
+ &mut afio.mapr,
+ Mode::Standard {
+ frequency: 100_000.hz(),
+ },
+ clocks,
+ &mut rcc.apb1,
+ /* start_timeout_us */ 1000,
+ /* start_retries */ 10,
+ /* addr_timeout_us */ 1000,
+ /* data_timeout_us */ 1000,
+ );
+
+ let i2c_busmanager = shared_bus::CortexMBusManager::new(i2c);
+
+ /*
+ // Configure I2C2
+ let scl2 = gpiob.pb10.into_alternate_open_drain(&mut gpiob.crh);
+ let sda2 = gpiob.pb11.into_alternate_open_drain(&mut gpiob.crh);
+
+ let i2c2 = BlockingI2c::i2c2(
+ dp.I2C2,
+ (scl2, sda2),
+ Mode::Fast {
+ frequency: 400_000.hz(),
+ duty_cycle: DutyCycle::Ratio2to1,
+ },
+ clocks,
+ &mut rcc.apb1,
+ /* start_timeout_us */ 1000,
+ /* start_retries */ 10,
+ /* addr_timeout_us */ 1000,
+ /* data_timeout_us */ 1000,
+ );
+ */
+
+ const I2C_ADDRESS: u8 = 0b010_0000; // MCP23008, depending on solder bridges
+ let mut lcd = match HD44780::new_i2c_mcp23008(i2c_busmanager.acquire(), I2C_ADDRESS, &mut delay) {
+ Ok(lcd) => lcd,
+ Err(_) => panic!("HD44780 init fail"),
+ };
+
+ lcd.reset(&mut delay).unwrap();
+ lcd.clear(&mut delay).unwrap();
+ lcd.set_display_mode(
+ DisplayMode {
+ display: Display::On,
+ cursor_visibility: Cursor::Invisible,
+ cursor_blink: CursorBlink::Off,
+ },
+ &mut delay).unwrap();
+ lcd.set_cursor_pos(0, &mut delay).unwrap();
+ lcd.write_str("Hello, world!", &mut delay).unwrap();
+
+ let ref_clock = 25_000_000;
+ let mut siclock = Si5351Device::new(i2c_busmanager.acquire(), false, ref_clock);
+ siclock.init(si5351::CrystalLoad::_10).unwrap();
+ siclock.set_frequency(si5351::PLL::B, si5351::ClockOutput::Clk0, 28_000_000 + 4_915_200).unwrap();
+ siclock.set_frequency(si5351::PLL::A, si5351::ClockOutput::Clk1, 144_000_000 + 28_000_000).unwrap();
+ siclock.set_frequency(si5351::PLL::A, si5351::ClockOutput::Clk2, 4_915_100).unwrap();
+
+ lcd.set_cursor_pos(0, &mut delay).unwrap();
+ lcd.write_str("Clocks set. ", &mut delay).unwrap();
let mut step = 0;
print(step).unwrap();
loop {
- for _ in 0..5 {
- led.toggle().unwrap();
- block!(timer.wait()).ok();
- }
+ led.toggle().unwrap();
+ delay.delay_ms(600u32);
+
+ lcd.set_cursor_pos(40, &mut delay).unwrap();
+ let mut string = arrayvec::ArrayString::<[_; 16]>::new();
+ write!(string, "Step {} ", step).unwrap();
+ lcd.write_str(&string, &mut delay).unwrap();
- print(step).unwrap();
step += 1;
}
}
#[cortex_m_rt::exception]
fn HardFault(ef: &ExceptionFrame) -> ! {
- panic!("HardFault at {:#?}", ef);
+ let periph = unsafe { cortex_m::Peripherals::steal() };
+ let hfsr = periph.SCB.hfsr.read();
+ let cfsr = periph.SCB.cfsr.read();
+
+ let mut stdout = match hio::hstdout() {
+ Ok(fd) => fd,
+ Err(()) => panic!("no stdout"),
+ };
+
+ let _ = write!(stdout, "Hardfault {:x} {:x} at {:x}\n", hfsr, cfsr, ef.pc);
+ cortex_m::asm::bkpt();
+ loop { }
}
#[cortex_m_rt::exception]
fn DefaultHandler(irqn: i16) {
- panic!("Unhandled exception (IRQn = {})", irqn);
+ let mut stdout = match hio::hstdout() {
+ Ok(fd) => fd,
+ Err(()) => panic!("no stdout"),
+ };
+
+ let _ = write!(stdout, "Unhandled exception (IRQn = {})", irqn);
+ cortex_m::asm::bkpt();
+ loop { }
}
+
+
+
+ /* code to discover i2c device address
+ let mut stdout = hio::hstdout().unwrap();
+
+ loop {
+ for addr in 0..127usize {
+ let bytes = [0u8; 1];
+ let mut buffer = [0u8; 1];
+ match i2c.write_read(addr as u8, &bytes, &mut buffer) {
+ Ok(()) => {
+ write!(stdout, "{}: {}\n", addr, buffer[0]).unwrap();
+ },
+ Err(_) => {
+ write!(stdout, "{}: fail\n", addr).unwrap();
+ },
+ }
+ }
+ }
+ */
+