probe_rs/vendor/st/sequences/
stm32_armv6.rsuse std::sync::Arc;
use probe_rs_target::CoreType;
use crate::architecture::arm::{
memory::ArmMemoryInterface, sequences::ArmDebugSequence, ArmError, ArmProbeInterface,
FullyQualifiedApAddress,
};
#[derive(Debug)]
pub enum Stm32Armv6Family {
F0,
L0,
G0,
}
#[derive(Debug)]
pub struct Stm32Armv6 {
family: Stm32Armv6Family,
}
impl Stm32Armv6 {
pub fn create(family: Stm32Armv6Family) -> Arc<Self> {
Arc::new(Self { family })
}
}
mod rcc {
use crate::architecture::arm::{memory::ArmMemoryInterface, ArmError};
use bitfield::bitfield;
const RCC: u64 = 0x40021000;
macro_rules! enable_reg {
($name:ident, $offset:literal, $bit:literal) => {
bitfield! {
pub struct $name(u32);
impl Debug;
pub u8, dbgen, enable_dbg: $bit;
}
impl $name {
const ADDRESS: u64 = $offset;
pub fn read(memory: &mut dyn ArmMemoryInterface) -> Result<Self, ArmError> {
let contents = memory.read_word_32(RCC + Self::ADDRESS)?;
Ok(Self(contents))
}
pub fn write(
&mut self,
memory: &mut dyn ArmMemoryInterface,
) -> Result<(), ArmError> {
memory.write_word_32(RCC + Self::ADDRESS, self.0)
}
}
};
}
enable_reg!(EnrF0, 0x18, 22);
enable_reg!(EnrL0, 0x34, 22);
enable_reg!(EnrG0, 0x3c, 27);
}
mod dbgmcu {
use crate::architecture::arm::{memory::ArmMemoryInterface, ArmError};
use bitfield::bitfield;
const DBGMCU: u64 = 0x40015800;
bitfield! {
pub struct Control(u32);
impl Debug;
pub u8, dbg_standby, enable_standby_debug: 2;
pub u8, dbg_stop, enable_stop_debug: 1;
}
impl Control {
const ADDRESS: u64 = 0x04;
pub fn read(memory: &mut dyn ArmMemoryInterface) -> Result<Self, ArmError> {
let contents = memory.read_word_32(DBGMCU + Self::ADDRESS)?;
Ok(Self(contents))
}
pub fn write(&mut self, memory: &mut dyn ArmMemoryInterface) -> Result<(), ArmError> {
memory.write_word_32(DBGMCU + Self::ADDRESS, self.0)
}
}
}
impl ArmDebugSequence for Stm32Armv6 {
fn debug_device_unlock(
&self,
interface: &mut dyn ArmProbeInterface,
default_ap: &FullyQualifiedApAddress,
_permissions: &crate::Permissions,
) -> Result<(), ArmError> {
let mut memory = interface.memory_interface(default_ap)?;
match self.family {
Stm32Armv6Family::F0 => {
let mut enr = rcc::EnrF0::read(&mut *memory)?;
enr.enable_dbg(true);
enr.write(&mut *memory)?;
}
Stm32Armv6Family::L0 => {
let mut enr = rcc::EnrL0::read(&mut *memory)?;
enr.enable_dbg(true);
enr.write(&mut *memory)?;
}
Stm32Armv6Family::G0 => {
let mut enr = rcc::EnrG0::read(&mut *memory)?;
enr.enable_dbg(true);
enr.write(&mut *memory)?;
}
}
let mut cr = dbgmcu::Control::read(&mut *memory)?;
cr.enable_standby_debug(true);
cr.enable_stop_debug(true);
cr.write(&mut *memory)?;
Ok(())
}
fn debug_core_stop(
&self,
memory: &mut dyn ArmMemoryInterface,
_core_type: CoreType,
) -> Result<(), ArmError> {
match self.family {
Stm32Armv6Family::F0 => {
let mut enr = rcc::EnrF0::read(&mut *memory)?;
enr.enable_dbg(false);
enr.write(&mut *memory)?;
}
Stm32Armv6Family::L0 => {
let mut enr = rcc::EnrL0::read(&mut *memory)?;
enr.enable_dbg(false);
enr.write(&mut *memory)?;
}
Stm32Armv6Family::G0 => {
let mut enr = rcc::EnrG0::read(&mut *memory)?;
enr.enable_dbg(false);
enr.write(&mut *memory)?;
}
}
let mut cr = dbgmcu::Control::read(&mut *memory)?;
cr.enable_standby_debug(false);
cr.enable_stop_debug(false);
cr.write(&mut *memory)?;
Ok(())
}
}