Skip to content

Commit

Permalink
bugfix(broken atomic): Remove all uses of atomic
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
Codetector1374 authored and andelf committed Nov 4, 2024
1 parent 5596607 commit 14e5007
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 23 deletions.
24 changes: 11 additions & 13 deletions src/dma/dma_bdma.rs
Original file line number Diff line number Diff line change
@@ -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};
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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) {
Expand Down
19 changes: 9 additions & 10 deletions src/embassy/time_driver_systick.rs
Original file line number Diff line number Diff line change
@@ -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};
Expand All @@ -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;

Expand Down Expand Up @@ -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<AlarmHandle> {
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);
Expand All @@ -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;
Expand Down

0 comments on commit 14e5007

Please sign in to comment.