Fixed Rust drivers

This commit is contained in:
Kevin Thomas
2026-04-02 11:36:06 -04:00
parent 2792583302
commit 9834d5c96c
245 changed files with 1110 additions and 650 deletions
+122 -26
View File
@@ -183,37 +183,133 @@ pub(crate) fn init_delay(clocks: &hal::clocks::ClocksManager) -> cortex_m::delay
///
/// Number of bytes written into the buffer.
pub(crate) fn format_adc_line(buf: &mut [u8], mv: u32, temp_int: i32, temp_frac: u8) -> usize {
let prefix = b"ADC0: ";
buf[..6].copy_from_slice(prefix);
buf[..6].copy_from_slice(b"ADC0: ");
let mut pos = 6;
let thousands = ((mv / 1000) % 10) as u8;
let hundreds = ((mv / 100) % 10) as u8;
let tens = ((mv / 10) % 10) as u8;
let ones = (mv % 10) as u8;
buf[pos] = b'0' + thousands; pos += 1;
buf[pos] = b'0' + hundreds; pos += 1;
buf[pos] = b'0' + tens; pos += 1;
buf[pos] = b'0' + ones; pos += 1;
let mid = b" mV | Chip temp: ";
buf[pos..pos + 19].copy_from_slice(mid);
pos += write_mv_digits(&mut buf[pos..], mv);
buf[pos..pos + 19].copy_from_slice(b" mV | Chip temp: ");
pos += 19;
let abs_temp = if temp_int < 0 { -temp_int } else { temp_int } as u32;
if temp_int < 0 {
buf[pos] = b'-'; pos += 1;
}
if abs_temp >= 100 {
buf[pos] = b'0' + ((abs_temp / 100) % 10) as u8; pos += 1;
}
if abs_temp >= 10 {
buf[pos] = b'0' + ((abs_temp / 10) % 10) as u8; pos += 1;
}
buf[pos] = b'0' + (abs_temp % 10) as u8; pos += 1;
pos += write_temp(&mut buf[pos..], temp_int, temp_frac);
buf[pos..pos + 4].copy_from_slice(b" C\r\n");
pos + 4
}
/// Write 4-digit millivolt value into `buf`.
fn write_mv_digits(buf: &mut [u8], mv: u32) -> usize {
buf[0] = b'0' + ((mv / 1000) % 10) as u8;
buf[1] = b'0' + ((mv / 100) % 10) as u8;
buf[2] = b'0' + ((mv / 10) % 10) as u8;
buf[3] = b'0' + (mv % 10) as u8;
4
}
/// Write temperature as "[-]NN.F" into `buf`.
fn write_temp(buf: &mut [u8], temp_int: i32, temp_frac: u8) -> usize {
let mut pos = 0;
let abs_temp = if temp_int < 0 { buf[pos] = b'-'; pos += 1; -temp_int } else { temp_int } as u32;
pos += write_min_digits(&mut buf[pos..], abs_temp);
buf[pos] = b'.'; pos += 1;
buf[pos] = b'0' + temp_frac; pos += 1;
let suffix = b" C\r\n";
buf[pos..pos + 4].copy_from_slice(suffix);
pos += 4;
pos
}
/// Write a u32 with minimum digits (no leading zeros).
fn write_min_digits(buf: &mut [u8], val: u32) -> usize {
let mut pos = 0;
if val >= 100 { buf[pos] = b'0' + ((val / 100) % 10) as u8; pos += 1; }
if val >= 10 { buf[pos] = b'0' + ((val / 10) % 10) as u8; pos += 1; }
buf[pos] = b'0' + (val % 10) as u8;
pos + 1
}
/// Type alias for the ADC input pin on GPIO 26.
type Gpio26Adc = hal::adc::AdcPin<Pin<hal::gpio::bank0::Gpio26, FunctionNull, PullDown>>;
/// Initialise all peripherals and run the ADC demo.
///
/// # Arguments
///
/// * `pac` - PAC Peripherals singleton (consumed).
pub(crate) fn run(mut pac: hal::pac::Peripherals) -> ! {
let mut wd = hal::Watchdog::new(pac.WATCHDOG);
let clocks = init_clocks(pac.XOSC, pac.CLOCKS, pac.PLL_SYS, pac.PLL_USB, &mut pac.RESETS, &mut wd);
let pins = init_pins(pac.IO_BANK0, pac.PADS_BANK0, pac.SIO, &mut pac.RESETS);
let uart = init_uart(pac.UART0, pins.gpio0, pins.gpio1, &mut pac.RESETS, &clocks);
let mut delay = init_delay(&clocks);
let (mut adc, mut adc_pin, mut temp) = init_adc(pac.ADC, pins.gpio26, &mut pac.RESETS);
uart.write_full_blocking(b"ADC driver initialized: GPIO26 (channel 0)\r\n");
adc_loop(&uart, &mut adc, &mut adc_pin, &mut temp, &mut delay)
}
/// Create the ADC peripheral, GPIO 26 input channel, and temperature sensor.
///
/// # Arguments
///
/// * `adc_pac` - PAC ADC peripheral singleton.
/// * `gpio26` - Default GPIO 26 pin to use as ADC input.
/// * `resets` - Mutable reference to the RESETS peripheral.
///
/// # Returns
///
/// Tuple of (ADC driver, ADC pin channel, temperature sensor channel).
fn init_adc(
adc_pac: hal::pac::ADC,
gpio26: Pin<hal::gpio::bank0::Gpio26, FunctionNull, PullDown>,
resets: &mut hal::pac::RESETS,
) -> (hal::Adc, Gpio26Adc, hal::adc::TempSense) {
let mut adc = hal::Adc::new(adc_pac, resets);
let pin = hal::adc::AdcPin::new(gpio26).unwrap();
let temp = adc.take_temp_sensor().unwrap();
(adc, pin, temp)
}
/// Sample voltage and temperature, format, and print in a loop.
///
/// # Arguments
///
/// * `uart` - Reference to the enabled UART peripheral for serial output.
/// * `adc` - Mutable reference to the ADC driver.
/// * `adc_pin` - Mutable reference to the GPIO 26 ADC channel.
/// * `temp` - Mutable reference to the temperature sensor channel.
/// * `delay` - Mutable reference to the blocking delay provider.
fn adc_loop(
uart: &EnabledUart,
adc: &mut hal::Adc,
adc_pin: &mut Gpio26Adc,
temp: &mut hal::adc::TempSense,
delay: &mut cortex_m::delay::Delay,
) -> ! {
let mut buf = [0u8; 48];
loop {
let (mv, temp_int, temp_frac) = read_adc(adc, adc_pin, temp);
let n = format_adc_line(&mut buf, mv, temp_int, temp_frac);
uart.write_full_blocking(&buf[..n]);
delay.delay_ms(POLL_MS);
}
}
/// Read voltage and temperature from the ADC.
///
/// # Arguments
///
/// * `adc` - Mutable reference to the ADC driver.
/// * `adc_pin` - Mutable reference to the GPIO 26 ADC channel.
/// * `temp` - Mutable reference to the temperature sensor channel.
///
/// # Returns
///
/// Tuple of (millivolts, integer temperature, fractional temperature digit).
fn read_adc(
adc: &mut hal::Adc,
adc_pin: &mut Gpio26Adc,
temp: &mut hal::adc::TempSense,
) -> (u32, i32, u8) {
let raw_v: u16 = adc.read(adc_pin).unwrap();
let mv = crate::adc::raw_to_mv(raw_v);
let raw_t: u16 = adc.read(temp).unwrap();
let celsius = crate::adc::raw_to_celsius(raw_t);
let temp_int = celsius as i32;
let temp_frac = (((celsius - temp_int as f32) * 10.0) as u8).min(9);
(mv, temp_int, temp_frac)
}
// End of file
+1 -31
View File
@@ -78,39 +78,9 @@ pub static BOOT2: [u8; 256] = rp2040_boot2::BOOT_LOADER_W25Q080;
pub static IMAGE_DEF: hal::block::ImageDef = hal::block::ImageDef::secure_exe();
/// Application entry point for the ADC voltage and temperature demo.
///
/// Initializes the ADC on GPIO26 channel 0 and prints readings
/// every 500 ms over UART.
///
/// # Returns
///
/// Does not return.
#[entry]
fn main() -> ! {
let mut pac = hal::pac::Peripherals::take().unwrap();
let clocks = board::init_clocks(
pac.XOSC, pac.CLOCKS, pac.PLL_SYS, pac.PLL_USB, &mut pac.RESETS,
&mut hal::Watchdog::new(pac.WATCHDOG),
);
let pins = board::init_pins(pac.IO_BANK0, pac.PADS_BANK0, pac.SIO, &mut pac.RESETS);
let uart = board::init_uart(pac.UART0, pins.gpio0, pins.gpio1, &mut pac.RESETS, &clocks);
let mut delay = board::init_delay(&clocks);
let mut adc_hw = hal::Adc::new(pac.ADC, &mut pac.RESETS);
let mut adc_pin = hal::adc::AdcPin::new(pins.gpio26).unwrap();
let mut temp_sensor = adc_hw.take_temp_sensor().unwrap();
uart.write_full_blocking(b"ADC driver initialized: GPIO26 (channel 0)\r\n");
let mut buf = [0u8; 48];
loop {
let raw_v: u16 = adc_hw.read(&mut adc_pin).unwrap();
let mv = adc::raw_to_mv(raw_v);
let raw_t: u16 = adc_hw.read(&mut temp_sensor).unwrap();
let temp = adc::raw_to_celsius(raw_t);
let temp_int = temp as i32;
let temp_frac = (((temp - temp_int as f32) * 10.0) as u8).min(9);
let n = board::format_adc_line(&mut buf, mv, temp_int, temp_frac);
uart.write_full_blocking(&buf[..n]);
delay.delay_ms(board::POLL_MS);
}
board::run(hal::pac::Peripherals::take().unwrap())
}
// Picotool binary info metadata