#[cfg(target_arch = "avr")]
use core::arch::asm;
#[inline(always)]
pub fn nop() {
cfg_if::cfg_if! {
if #[cfg(target_arch = "avr")] {
unsafe {
asm!(
"nop",
options(preserves_flags)
)
}
} else {
unimplemented!()
}
}
}
#[inline(always)]
pub fn nop2() {
cfg_if::cfg_if! {
if #[cfg(target_arch = "avr")] {
unsafe {
asm!(
"rjmp 1f",
"1:",
options(preserves_flags)
)
}
} else {
unimplemented!()
}
}
}
#[inline(always)]
pub fn nop3() {
cfg_if::cfg_if! {
if #[cfg(target_arch = "avr")] {
unsafe {
asm!(
"rjmp 1f",
"1: nop",
options(preserves_flags)
)
}
} else {
unimplemented!()
}
}
}
#[inline(always)]
pub fn nop4() {
cfg_if::cfg_if! {
if #[cfg(target_arch = "avr")] {
unsafe {
asm!(
"rjmp 1f",
"1: rjmp 2f",
"2:",
options(preserves_flags)
)
}
} else {
unimplemented!()
}
}
}
#[inline(always)]
pub fn nop5() {
cfg_if::cfg_if! {
if #[cfg(target_arch = "avr")] {
unsafe {
asm!(
"rjmp 1f",
"1: rjmp 2f",
"2: nop",
options(preserves_flags)
)
}
} else {
unimplemented!()
}
}
}
#[inline(always)]
pub fn sleep() {
cfg_if::cfg_if! {
if #[cfg(target_arch = "avr")] {
unsafe {
asm!(
"sleep",
options(preserves_flags)
)
}
} else {
unimplemented!()
}
}
}
#[inline(always)]
pub fn wdr() {
cfg_if::cfg_if! {
if #[cfg(target_arch = "avr")] {
unsafe {
asm!(
"wdr",
options(preserves_flags)
)
}
} else {
unimplemented!()
}
}
}
#[cfg(feature = "rt")]
#[inline(always)]
pub fn get_stack_size() -> usize {
extern "C" {
static __DATA_REGION_ORIGIN__: usize;
static __DATA_REGION_LENGTH__: usize;
}
use core::ptr::addr_of;
cfg_if::cfg_if! {
if #[cfg(target_arch = "avr")] {
unsafe {
let data_region_end = addr_of!(__DATA_REGION_ORIGIN__) as usize + addr_of!(__DATA_REGION_LENGTH__) as usize;
let sp: usize;
if data_region_end > u8::MAX as usize {
let spl: u8;
let sph: u8;
core::arch::asm!(
"in {}, 0x3d",
"in {}, 0x3e",
out(reg) spl,
out(reg) sph,
options(nostack, nomem, pure),
);
sp = usize::from_le_bytes([spl, sph]);
} else {
let spl: u8;
core::arch::asm!(
"in {}, 0x3d",
out(reg) spl,
options(nostack, nomem, pure),
);
sp = spl as usize;
}
data_region_end - sp
}
} else {
unimplemented!()
}
}
}
#[inline(always)]
pub fn delay_cycles(cycles: u32) {
cfg_if::cfg_if! {
if #[cfg(target_arch = "avr")] {
let mut cycles_bytes = cycles.to_le_bytes();
unsafe {
asm!(
"1:",
"subi {r0}, 6",
"sbci {r1}, 0",
"sbci {r2}, 0",
"sbci {r3}, 0",
"brcc 1b",
r0 = inout(reg_upper) cycles_bytes[0],
r1 = inout(reg_upper) cycles_bytes[1],
r2 = inout(reg_upper) cycles_bytes[2],
r3 = inout(reg_upper) cycles_bytes[3],
)
}
} else {
let _ = cycles;
unimplemented!()
}
}
}