Skip to content

Commit

Permalink
Merge pull request #873 from quartiq/lints
Browse files Browse the repository at this point in the history
lints
  • Loading branch information
ryan-summers authored Apr 4, 2024
2 parents 4313cfa + e6ec334 commit fd4569c
Show file tree
Hide file tree
Showing 7 changed files with 66 additions and 56 deletions.
2 changes: 1 addition & 1 deletion src/bin/dual-iir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ mod app {

#[init]
fn init(c: init::Context) -> (Shared, Local) {
let clock = SystemTimer::new(|| Systick::now().ticks() as u32);
let clock = SystemTimer::new(|| Systick::now().ticks());

// Configure the microcontroller
let (stabilizer, _pounder) = hardware::setup::setup(
Expand Down
2 changes: 1 addition & 1 deletion src/bin/lockin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ mod app {

#[init]
fn init(c: init::Context) -> (Shared, Local) {
let clock = SystemTimer::new(|| Systick::now().ticks() as u32);
let clock = SystemTimer::new(|| Systick::now().ticks());

// Configure the microcontroller
let (mut stabilizer, _pounder) = hardware::setup::setup(
Expand Down
49 changes: 29 additions & 20 deletions src/hardware/adc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,13 @@
//! In this implementation, double buffer mode DMA transfers are used because the SPI RX FIFOs
//! have finite depth, FIFO access is slower than AXISRAM access, and because the single
//! buffer mode DMA disable/enable and buffer update sequence is slow.
use core::mem::MaybeUninit;

use stm32h7xx_hal as hal;

use mutex_trait::Mutex;

use super::design_parameters::{SampleBuffer, MAX_SAMPLE_BUFFER_SIZE};
use super::design_parameters::SampleBuffer;
use super::timers;

use hal::{
Expand Down Expand Up @@ -149,21 +151,20 @@ impl TryFrom<f32> for AdcCode {
// transfer. Data in AXI SRAM is not initialized on boot, so the contents are random. This value is
// initialized during setup.
#[link_section = ".axisram.buffers"]
static mut SPI_START: [u32; 1] = [0x00; 1];
static mut SPI_START: MaybeUninit<[u32; 1]> = MaybeUninit::uninit();

// The following data is written by the timer flag clear trigger into the SPI IFCR register to clear
// the EOT flag. Data in AXI SRAM is not initialized on boot, so the contents are random. This
// value is initialized during setup.
#[link_section = ".axisram.buffers"]
static mut SPI_EOT_CLEAR: [u32; 1] = [0x00];
static mut SPI_EOT_CLEAR: MaybeUninit<[u32; 1]> = MaybeUninit::uninit();

// The following global buffers are used for the ADC sample DMA transfers. Two buffers are used for
// each transfer in a ping-pong buffer configuration (one is being acquired while the other is being
// processed). Note that the contents of AXI SRAM is uninitialized, so the buffer contents on
// startup are undefined. The dimensions are `ADC_BUF[adc_index][ping_pong_index][sample_index]`.
#[link_section = ".axisram.buffers"]
static mut ADC_BUF: [[SampleBuffer; 2]; 2] =
[[[0; MAX_SAMPLE_BUFFER_SIZE]; 2]; 2];
static mut ADC_BUF: MaybeUninit<[[SampleBuffer; 2]; 2]> = MaybeUninit::uninit();

macro_rules! adc_input {
($name:ident, $index:literal, $trigger_stream:ident, $data_stream:ident, $clear_stream:ident,
Expand Down Expand Up @@ -290,9 +291,13 @@ macro_rules! adc_input {
.priority(Priority::VeryHigh)
.circular_buffer(true);

unsafe {
SPI_EOT_CLEAR[0] = 1 << 3;
}
// Note(unsafe): Because this is a Memory->Peripheral transfer, this data is
// never actually modified. It technically only needs to be immutably
// borrowed, but the current HAL API only supports mutable borrows.
let spi_eot_clear = unsafe {
SPI_EOT_CLEAR.write([1 << 3]);
SPI_EOT_CLEAR.assume_init_mut()
};

// Generate DMA events when the timer hits zero (roll-over). This must be before
// the trigger channel DMA occurs, as if the trigger occurs first, the
Expand All @@ -309,10 +314,7 @@ macro_rules! adc_input {
> = Transfer::init(
clear_stream,
[< $spi IFCR >]::new(clear_channel),
// Note(unsafe): Because this is a Memory->Peripheral transfer, this data is
// never actually modified. It technically only needs to be immutably
// borrowed, but the current HAL API only supports mutable borrows.
unsafe { &mut SPI_EOT_CLEAR },
spi_eot_clear,
None,
clear_config,
);
Expand All @@ -332,9 +334,13 @@ macro_rules! adc_input {

// Note(unsafe): This word is initialized once per ADC initialization to verify
// it is initialized properly.
unsafe {
// Note(unsafe): Because this is a Memory->Peripheral transfer, this data is never
// actually modified. It technically only needs to be immutably borrowed, but the
// current HAL API only supports mutable borrows.
let spi_start = unsafe {
// Write a binary code into the SPI control register to initiate a transfer.
SPI_START[0] = 0x201;
SPI_START.write([0x201]);
SPI_START.assume_init_mut()
};

// Construct the trigger stream to write from memory to the peripheral.
Expand All @@ -347,10 +353,7 @@ macro_rules! adc_input {
> = Transfer::init(
trigger_stream,
[< $spi CR >]::new(trigger_channel),
// Note(unsafe): Because this is a Memory->Peripheral transfer, this data is never
// actually modified. It technically only needs to be immutably borrowed, but the
// current HAL API only supports mutable borrows.
unsafe { &mut SPI_START },
spi_start,
None,
trigger_config,
);
Expand All @@ -373,6 +376,12 @@ macro_rules! adc_input {
let mut spi = spi.disable();
spi.listen(hal::spi::Event::Error);

let adc_buf = unsafe {
ADC_BUF.write(Default::default());
ADC_BUF.assume_init_mut()
};
let adc_bufs = adc_buf[$index].split_at_mut(1);

// The data transfer is always a transfer of data from the peripheral to a RAM
// buffer.
let data_transfer: Transfer<_, _, PeripheralToMemory, _, _> =
Expand All @@ -381,8 +390,8 @@ macro_rules! adc_input {
spi,
// Note(unsafe): The ADC_BUF[$index] is "owned" by this peripheral.
// It shall not be used anywhere else in the module.
unsafe { &mut ADC_BUF[$index][0][..batch_size] },
unsafe { Some(&mut ADC_BUF[$index][1][..batch_size]) },
&mut adc_bufs.0[0][..batch_size],
Some(&mut adc_bufs.1[0][..batch_size]),
data_config,
);

Expand Down
26 changes: 11 additions & 15 deletions src/hardware/platform.rs
Original file line number Diff line number Diff line change
@@ -1,34 +1,30 @@
/// Flag used to indicate that a reboot to DFU is requested.
const DFU_REBOOT_FLAG: u32 = 0xDEAD_BEEF;

extern "C" {
static mut _bootflag: u8;
}

/// Indicate a reboot to DFU is requested.
pub fn start_dfu_reboot() {
extern "C" {
static mut _bootflag: u8;
}

unsafe {
let start_ptr = &mut _bootflag as *mut u8;
core::ptr::write_unaligned(start_ptr.cast::<u32>(), DFU_REBOOT_FLAG);
core::ptr::write_unaligned(
core::ptr::addr_of_mut!(_bootflag).cast(),
DFU_REBOOT_FLAG,
);
}

cortex_m::peripheral::SCB::sys_reset();
}

/// Check if the DFU reboot flag is set, indicating a reboot to DFU is requested.
pub fn dfu_bootflag() -> bool {
// Obtain panic region start and end from linker symbol _panic_dump_start and _panic_dump_end
extern "C" {
static mut _bootflag: u8;
}

unsafe {
let start_ptr = &mut _bootflag as *mut u8;
let set = DFU_REBOOT_FLAG
== core::ptr::read_unaligned(start_ptr.cast::<u32>());
let start_ptr = core::ptr::addr_of_mut!(_bootflag).cast();
let set = DFU_REBOOT_FLAG == core::ptr::read_unaligned(start_ptr);

// Clear the boot flag after checking it to ensure it doesn't stick between reboots.
core::ptr::write_unaligned(start_ptr.cast::<u32>(), 0);
core::ptr::write_unaligned(start_ptr, 0);
set
}
}
Expand Down
28 changes: 18 additions & 10 deletions src/hardware/setup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
//!
//! This file contains all of the hardware-specific configuration of Stabilizer.
use bit_field::BitField;
use core::mem::MaybeUninit;
use core::sync::atomic::{self, AtomicBool, Ordering};
use core::{fmt::Write, ptr, slice};
use stm32h7xx_hal::{
Expand Down Expand Up @@ -159,10 +160,9 @@ pub struct PounderDevices {

#[link_section = ".sram3.eth"]
/// Static storage for the ethernet DMA descriptor ring.
static mut DES_RING: ethernet::DesRing<
{ super::TX_DESRING_CNT },
{ super::RX_DESRING_CNT },
> = ethernet::DesRing::new();
static mut DES_RING: MaybeUninit<
ethernet::DesRing<{ super::TX_DESRING_CNT }, { super::RX_DESRING_CNT }>,
> = MaybeUninit::uninit();

/// Setup ITCM and load its code from flash.
///
Expand Down Expand Up @@ -194,10 +194,13 @@ fn load_itcm() {
// Ensure ITCM is enabled before loading.
atomic::fence(Ordering::SeqCst);

let len =
(&__eitcm as *const u32).offset_from(&__sitcm as *const _) as usize;
let dst = slice::from_raw_parts_mut(&mut __sitcm as *mut _, len);
let src = slice::from_raw_parts(&__siitcm as *const _, len);
let sitcm = core::ptr::addr_of_mut!(__sitcm);
let eitcm = core::ptr::addr_of_mut!(__eitcm);
let siitcm = core::ptr::addr_of_mut!(__siitcm);

let len = eitcm.offset_from(sitcm) as usize;
let dst = slice::from_raw_parts_mut(sitcm, len);
let src = slice::from_raw_parts(siitcm, len);
// Load code into ITCM.
dst.copy_from_slice(src);
}
Expand Down Expand Up @@ -660,7 +663,7 @@ where
super::flash::Flash(flash_bank2.unwrap())
};

let mut settings = C::new(NetSettings::new(mac_addr.clone()));
let mut settings = C::new(NetSettings::new(mac_addr));
crate::settings::load_from_flash(&mut settings, &mut flash);
(flash, settings)
};
Expand All @@ -686,6 +689,11 @@ where
(ref_clk, mdio, mdc, crs_dv, rxd0, rxd1, tx_en, txd0, txd1)
};

let ring = unsafe {
DES_RING.write(ethernet::DesRing::new());
DES_RING.assume_init_mut()
};

// Configure the ethernet controller
let (mut eth_dma, eth_mac) = ethernet::new(
device.ETHERNET_MAC,
Expand All @@ -694,7 +702,7 @@ where
ethernet_pins,
// Note(unsafe): We only call this function once to take ownership of the
// descriptor ring.
unsafe { &mut DES_RING },
ring,
mac_addr,
ccdr.peripheral.ETH1MAC,
&ccdr.clocks,
Expand Down
10 changes: 3 additions & 7 deletions src/net/data_stream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,6 @@ const FRAME_SIZE: usize = 1500 - 40 - 8;
// allocated frame buffer should fit in the queue.
const FRAME_QUEUE_SIZE: usize = FRAME_COUNT * 2;

// Static storage used for a heapless::Pool of frame buffers.
static mut FRAME_DATA: [u8; core::mem::size_of::<u8>()
* FRAME_SIZE
* FRAME_COUNT] = [0; core::mem::size_of::<u8>() * FRAME_SIZE * FRAME_COUNT];

type Frame = [MaybeUninit<u8>; FRAME_SIZE];

/// Represents the destination for the UDP stream to send data to.
Expand Down Expand Up @@ -131,8 +126,9 @@ pub fn setup_streaming(

let frame_pool = cortex_m::singleton!(: Pool<Frame> = Pool::new()).unwrap();

// Note(unsafe): We guarantee that FRAME_DATA is only accessed once in this function.
let memory = unsafe { &mut FRAME_DATA };
let memory = cortex_m::singleton!(FRAME_DATA: [u8; core::mem::size_of::<u8>() * FRAME_SIZE * FRAME_COUNT] =
[0; core::mem::size_of::<u8>() * FRAME_SIZE * FRAME_COUNT]).unwrap();

frame_pool.grow(memory);

let generator = FrameGenerator::new(producer, frame_pool);
Expand Down
5 changes: 3 additions & 2 deletions src/net/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,11 +208,12 @@ where

// `settings_path` has to be at least as large as `miniconf::mqtt_client::MAX_TOPIC_LENGTH`.
let mut settings_path: String<128> = String::new();
match self.miniconf.handled_update(|path, old, new| {
let res = self.miniconf.handled_update(|path, old, new| {
settings_path = path.into();
*old = new.clone();
Result::<(), &'static str>::Ok(())
}) {
});
match res {
Ok(true) => NetworkState::SettingsChanged(settings_path),
_ => poll_result,
}
Expand Down

0 comments on commit fd4569c

Please sign in to comment.