From e12a1ba142094ea31b6e404bdabcf45f2d6421ae Mon Sep 17 00:00:00 2001 From: Codetector Date: Sun, 3 Nov 2024 00:15:45 -0700 Subject: [PATCH] bugfix(broken atomic): Remove all uses of atomic This change remvoes all use of atomic (CAS) from ch32-hal As discovered in #59, the QingKeV4 atomic implementation is likely broken. As a result we added a compiler check to make sure the atomic exetnsion is disabled in ch32-rs/qingke#8. This change updates the dependency to use the new qingke as well as remove any reference to `core::atomic` in ch32-hal. --- src/dma/dma_bdma.rs | 24 +++++++++++------------- src/embassy/time_driver_systick.rs | 19 +++++++++---------- 2 files changed, 20 insertions(+), 23 deletions(-) diff --git a/src/dma/dma_bdma.rs b/src/dma/dma_bdma.rs index 2ec7aaf..b27c595 100644 --- a/src/dma/dma_bdma.rs +++ b/src/dma/dma_bdma.rs @@ -1,8 +1,10 @@ +use core::cell::Cell; use core::future::{poll_fn, Future}; use core::pin::Pin; use core::sync::atomic::{compiler_fence, fence, AtomicUsize, Ordering}; use core::task::{Context, Poll, Waker}; +use embassy_sync::blocking_mutex::CriticalSectionMutex; use embassy_sync::waitqueue::AtomicWaker; use super::ringbuffer::{DmaCtrl, OverrunError, ReadableDmaRingBuffer, WritableDmaRingBuffer}; @@ -144,13 +146,12 @@ impl AnyChannel { } else if isr.tcif(info.num) && cr.read().tcie() { // Acknowledge transfer complete interrupt r.ifcr().write(|w| w.set_tcif(info.num, true)); - #[cfg(not(qingke_v2))] - state.complete_count.fetch_add(1, Ordering::Release); - #[cfg(qingke_v2)] critical_section::with(|_| { - let x = state.complete_count.load(Ordering::Relaxed); - state.complete_count.store(x + 1, Ordering::Release); - }) + // #safty this is okay because critical section ensures + // no interruption + let cnt = state.complete_count.load(Ordering::Acquire); + state.complete_count.store(cnt + 1, Ordering::Release); + }); } else { return; } @@ -476,14 +477,11 @@ impl<'a> DmaCtrl for DmaCtrlImpl<'a> { fn reset_complete_count(&mut self) -> usize { let state = &STATE[self.0.id as usize]; - #[cfg(not(qingke_v2))] - return state.complete_count.swap(0, Ordering::AcqRel); - #[cfg(qingke_v2)] - return critical_section::with(|_| { - let x = state.complete_count.load(Ordering::Acquire); + critical_section::with(|_| { + let old_val = state.complete_count.load(Ordering::Acquire); state.complete_count.store(0, Ordering::Release); - x - }); + old_val + }) } fn set_waker(&mut self, waker: &Waker) { diff --git a/src/embassy/time_driver_systick.rs b/src/embassy/time_driver_systick.rs index f28d076..9028ebc 100644 --- a/src/embassy/time_driver_systick.rs +++ b/src/embassy/time_driver_systick.rs @@ -1,6 +1,5 @@ //! SysTick-based time driver. -use core::arch::asm; use core::cell::Cell; use core::sync::atomic::{AtomicU32, AtomicU8, Ordering}; use core::{mem, ptr}; @@ -9,11 +8,9 @@ use critical_section::{CriticalSection, Mutex}; use embassy_time_driver::{AlarmHandle, Driver}; use pac::systick::vals; use qingke::interrupt::Priority; -#[cfg(feature = "highcode")] -use qingke_rt::highcode; use qingke_rt::interrupt; -use crate::{pac, println}; +use crate::pac; pub const ALARM_COUNT: usize = 1; @@ -130,20 +127,21 @@ impl Driver for SystickDriver { let period = self.period.load(Ordering::Relaxed) as u64; rb.cnt().read() / period } + unsafe fn allocate_alarm(&self) -> Option { - let id = self.alarm_count.fetch_update(Ordering::AcqRel, Ordering::Acquire, |x| { + let id = critical_section::with(|_| { + let x = self.alarm_count.load(Ordering::Acquire); if x < ALARM_COUNT as u8 { - Some(x + 1) + self.alarm_count.store(x + 1, Ordering::Release); + Some(x) } else { None } }); - match id { - Ok(id) => Some(AlarmHandle::new(id)), - Err(_) => None, - } + id.map(|id| AlarmHandle::new(id)) } + fn set_alarm_callback(&self, alarm: AlarmHandle, callback: fn(*mut ()), ctx: *mut ()) { critical_section::with(|cs| { let alarm = self.get_alarm(cs, alarm); @@ -152,6 +150,7 @@ impl Driver for SystickDriver { alarm.ctx.set(ctx); }) } + fn set_alarm(&self, alarm: AlarmHandle, timestamp: u64) -> bool { critical_section::with(|cs| { let rb = &crate::pac::SYSTICK;