Skip to content

Commit

Permalink
Make internal delay functions private
Browse files Browse the repository at this point in the history
  • Loading branch information
lord-ne committed Aug 25, 2021
1 parent b95c87e commit 1016f1a
Showing 1 changed file with 46 additions and 51 deletions.
97 changes: 46 additions & 51 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
#[inline(always)]
pub fn delay_ms(ms: u32) {
let ticks: u64 = (u64::from(avr_config::CPU_FREQUENCY_HZ) * u64::from(ms)) / 4_000;
internal_delay_functions::delay(ticks);
delay_impl(ticks);
}

///delay for N microseconds
Expand All @@ -36,62 +36,57 @@ pub fn delay_ms(ms: u32) {
#[inline(always)]
pub fn delay_us(us: u32) {
let ticks: u64 = (u64::from(avr_config::CPU_FREQUENCY_HZ) * u64::from(us)) / 4_000_000;
internal_delay_functions::delay(ticks);
delay_impl(ticks);
}

/// Deprecated: If necesarry, use internal_delay_functions::delay instead
///delay for N*4 clock cycles, not including setup overhead
/// # Arguments
/// * 'count' - a u32, number of iterations to busy-wait (4 cycles per iteration)
#[inline(always)]
#[deprecated(since = "0.3.3", note = "If necesarry, users can instead use internal_delay_functions::delay")]
pub fn delay(count: u32) {
internal_delay_functions::delay(u64::from(count));
delay_impl(u64::from(count));
}

/// Functions used internally for our busy-wait loop.
///
/// These are not primarily intended to be used in user code, but are left public for
/// use in making longer or more precise delays.
pub mod internal_delay_functions {
/// Internal function to implement a variable busy-wait loop.
/// Delays for up up to 2^48 iterations, not including setup overhead.
/// # Arguments
/// * 'count' - a u64, the number of times to iterate the loop.
/// The top 16 bits of count are ignored.
///
#[inline(always)]
pub fn delay(count: u64) {
// Casting truncates, so this is equivalent to `(count & 0xFFFF) as u16`
let remaining_count: u16 = count as u16;
// if remaining_count is zero, calling delay_loop_4_cycles would delay for 2^16 cycles,
// so we don't loop in this case
if remaining_count != 0 {
delay_loop_4_cycles(remaining_count);
}
// Casting truncates, so this is equivalent to `((count >> 16) & 0xFFFF_FFFF) as u32`
let outer_count: u32 = (count >> 16) as u32;
for _ in 0..outer_count {
// Each loop through should be 4 cycles, so we're getting 262,144 cycles per outer loop.
delay_loop_4_cycles(0);
}

/// Internal function to implement a variable busy-wait loop.
/// Delays for up up to 2^48 iterations, not including setup overhead.
/// # Arguments
/// * 'count' - a u64, the number of times to iterate the loop.
/// The top 16 bits of count are ignored.
#[inline(always)]
fn delay_impl(count: u64) {
// Casting truncates, so this is equivalent to `(count & 0xFFFF) as u16`
let remaining_count: u16 = count as u16;
// if remaining_count is zero, calling delay_loop_4_cycles would delay for 2^16 cycles,
// so we don't loop in this case
if remaining_count != 0 {
delay_loop_4_cycles(remaining_count);
}
// Casting truncates, so this is equivalent to `((count >> 16) & 0xFFFF_FFFF) as u32`
let outer_count: u32 = (count >> 16) as u32;
for _ in 0..outer_count {
// Each loop through should be 4 cycles, so we're getting 262,144 cycles per outer loop.
delay_loop_4_cycles(0);
}

/// Internal function to implement a 16-bit busy-wait loop in assembly.
/// Delays for 4 cycles per iteration, not including setup overhead.
/// Up to 2^16 iterations (the value 2^16 would have to be passed as 0).
/// # Arguments
/// * 'count' - a u16, the number of times to cycle the loop.
#[inline(always)]
#[allow(unused_variables, unused_mut, unused_assignments)]
fn delay_loop_4_cycles(mut count: u16) {
#[cfg(target_arch = "avr")]
unsafe {
llvm_asm!(
"1: sbiw $0,1\n\tbrne 1b"
: "=w" (count)
: "0" (count)
:
: "volatile"
);
}
// Allow compilation even on non-avr targets, for testing purposes
}

/// Internal function to implement a 16-bit busy-wait loop in assembly.
/// Delays for 4 cycles per iteration, not including setup overhead.
/// Up to 2^16 iterations (the value 2^16 would have to be passed as 0).
/// # Arguments
/// * 'count' - a u16, the number of times to cycle the loop.
#[inline(always)]
#[allow(unused_variables, unused_mut, unused_assignments)]
fn delay_loop_4_cycles(mut count: u16) {
#[cfg(target_arch = "avr")]
unsafe {
llvm_asm!(
"1: sbiw $0,1\n\tbrne 1b"
: "=w" (count)
: "0" (count)
:
: "volatile"
);
}
// Allow compilation even on non-avr targets, for testing purposes
}

0 comments on commit 1016f1a

Please sign in to comment.