//! Interacts with AXP173 present on my custom board #![no_std] #![no_main] #[macro_use] extern crate cortex_m; #[macro_use] extern crate cortex_m_rt as rt; extern crate panic_semihosting; extern crate stm32wb_hal as hal; use crate::hal::pac; use cortex_m_semihosting::hprintln; use crate::hal::i2c::I2c; use crate::rt::entry; use hal::prelude::*; use hal::rcc::{ApbDivider, Config, HDivider, HseDivider, PllConfig, PllSrc, SysClkSrc, UsbClkSrc}; use rt::ExceptionFrame; use axp173::{ AdcSampleRate, AdcSettings, Axp173, ChargingCurrent, Ldo, LdoKind, ShutdownLongPressTime, TsPinMode, }; use hal::flash::FlashExt; use embedded_hal::digital::v2::InputPin; use hal::dma::{DmaExt, ReadDma, WriteDma}; use hal::interrupt; use stm32wb_pac::Interrupt; #[exception] #[allow(non_snake_case)] fn HardFault(ef: &ExceptionFrame) -> ! { panic!("HardFault at {:#?}", ef); } #[exception] #[allow(non_snake_case)] fn DefaultHandler(irqn: i16) { panic!("Unhandled exception (IRQn = {})", irqn); } #[interrupt] #[allow(non_snake_case)] fn DMA1_CHANNEL1() { hprintln!("DMA1 CH1 IRQ").ok(); let dma1 = unsafe { pac::Peripherals::steal().DMA1 }; let tc_flag = dma1.isr.read().tcif1().bit(); if tc_flag { dma1.ifcr.write(|w| w.ctcif1().set_bit()); hprintln!("TX complete!").ok(); } let te_flag = dma1.isr.read().teif1().bit(); if te_flag { dma1.ifcr.write(|w| w.cteif1().set_bit()); hprintln!("TX error!").ok(); } } #[interrupt] #[allow(non_snake_case)] fn DMA1_CHANNEL2() { hprintln!("DMA1 CH2 IRQ").ok(); let dma1 = unsafe { pac::Peripherals::steal().DMA1 }; let tc_flag = dma1.isr.read().tcif2().bit(); if tc_flag { dma1.ifcr.write(|w| w.ctcif2().set_bit()); hprintln!("RX complete!").ok(); } let te_flag = dma1.isr.read().teif2().bit(); if te_flag { dma1.ifcr.write(|w| w.cteif2().set_bit()); hprintln!("RX error!").ok(); } } #[entry] #[inline(never)] fn main() -> ! { let cp = cortex_m::Peripherals::take().unwrap(); let syst = cp.SYST; let dp = pac::Peripherals::take().unwrap(); let rcc = dp.RCC.constrain(); let clock_config = Config::new(SysClkSrc::Pll(PllSrc::Hse(HseDivider::NotDivided))) .cpu1_hdiv(HDivider::NotDivided) .cpu2_hdiv(HDivider::Div2) .apb1_div(ApbDivider::NotDivided) .apb2_div(ApbDivider::NotDivided) .pll_cfg(PllConfig { m: 2, n: 12, r: 3, q: Some(4), p: Some(3), }) .usb_src(UsbClkSrc::PllQ); let mut rcc = rcc.apply_clock_config(clock_config, &mut dp.FLASH.constrain().acr); let mut gpiob = dp.GPIOB.split(&mut rcc); let mut pull_ups = gpiob .pb5 .into_push_pull_output(&mut gpiob.moder, &mut gpiob.otyper); let _ = pull_ups.set_high(); let scl = gpiob .pb6 .into_floating_input(&mut gpiob.moder, &mut gpiob.pupdr); if scl.is_low().unwrap() { hprintln!("SCL is LOW").unwrap(); } let sda = gpiob .pb7 .into_floating_input(&mut gpiob.moder, &mut gpiob.pupdr); if sda.is_low().unwrap() { hprintln!("SDA is LOW").unwrap(); } let scl = scl.into_open_drain_output(&mut gpiob.moder, &mut gpiob.otyper); let scl = scl.into_af4(&mut gpiob.moder, &mut gpiob.afrl); let sda = sda.into_open_drain_output(&mut gpiob.moder, &mut gpiob.otyper); let sda = sda.into_af4(&mut gpiob.moder, &mut gpiob.afrl); hprintln!("txe: {:?}", dp.I2C1.isr.read().txe().bit()).ok(); let i2c = I2c::i2c1(dp.I2C1, (scl, sda), 100.khz(), &mut rcc); unsafe { cortex_m::peripheral::NVIC::unmask(Interrupt::DMA1_CHANNEL1) } unsafe { cortex_m::peripheral::NVIC::unmask(Interrupt::DMA1_CHANNEL2) } unsafe { cortex_m::peripheral::NVIC::unmask(Interrupt::DMA1_CHANNEL3) } hprintln!("dma ccr1: {:032b}", dp.DMA1.ccr1.read().bits()).ok(); let dma_channels = dp.DMA1.split(&mut rcc, dp.DMAMUX1); let dma_c1 = dma_channels.ch1; let tx_buf = singleton!(: [u8; 1] = [0x06]).unwrap(); // reg address let rx_buf = singleton!(: [u8; 6] = [0x00; 6]).unwrap(); // result buffer let tx_transfer = i2c.with_tx_dma(dma_c1, 0x34, false); let (_, tx_dma) = tx_transfer.write(tx_buf).wait(); hprintln!("TX done").ok(); let (dma_c1, i2c) = tx_dma.free(); let rx_transfer = i2c.with_rx_dma(dma_c1, 0x34, true); let (rx_buf, rx_dma) = rx_transfer.read(rx_buf).wait(); hprintln!("RX done, buf: {:?}", rx_buf); loop { let i2c1 = unsafe { pac::Peripherals::steal().I2C1 }; let isr = i2c1.isr.read(); let dma1 = unsafe { pac::Peripherals::steal().DMA1 }; let dmamux = unsafe { pac::Peripherals::steal().DMAMUX1 }; let c1cr = dmamux.c1cr.read(); hprintln!( "dmamux c1cr: id = {}, ege: {:?}", c1cr.dmareq_id().bits(), c1cr.ege().bit() ); hprintln!("dma ccr1: {:032b}", dma1.ccr1.read().bits()); hprintln!("{:024b}, busy: {:?}", isr.bits(), isr.busy().bit()).ok(); cortex_m::asm::nop(); } }