Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 144a644

Browse files
committedNov 3, 2024
bugfix(broken atomic): DMA Driver atomic removal
This change remvoes all use of atomic from ch32-hal As discovered in ch32-rs#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.
1 parent d7f1b26 commit 144a644

File tree

11 files changed

+40
-49
lines changed

11 files changed

+40
-49
lines changed
 

‎.github/workflows/build-examples.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ jobs:
2323
rustup default nightly
2424
rustup component add rust-src
2525
rustup update
26-
rustup target add riscv32imac-unknown-none-elf
27-
rustup target add riscv32imafc-unknown-none-elf
26+
rustup target add riscv32imc-unknown-none-elf
27+
rustup target add riscv32imfc-unknown-none-elf
2828
rustup target add riscv32i-unknown-none-elf
2929
- name: Fetch Deps
3030
# if this is a pull request

‎.github/workflows/build.yml

+10-10
Original file line numberDiff line numberDiff line change
@@ -30,23 +30,23 @@ jobs:
3030
- ch641
3131
include:
3232
- chip: ch32l103f8u6
33-
target: riscv32imac-unknown-none-elf
33+
target: riscv32imc-unknown-none-elf
3434
- chip: ch32v003f4u6
3535
target: riscv32i-unknown-none-elf
3636
- chip: ch32v103c8t6
37-
target: riscv32imac-unknown-none-elf
37+
target: riscv32imc-unknown-none-elf
3838
- chip: ch32v203f8u6
39-
target: riscv32imac-unknown-none-elf
39+
target: riscv32imc-unknown-none-elf
4040
- chip: ch32v208wbu6
41-
target: riscv32imac-unknown-none-elf
41+
target: riscv32imc-unknown-none-elf
4242
- chip: ch32v303vct6
43-
target: riscv32imafc-unknown-none-elf
43+
target: riscv32imfc-unknown-none-elf
4444
- chip: ch32v305fbp6
45-
target: riscv32imafc-unknown-none-elf
45+
target: riscv32imfc-unknown-none-elf
4646
- chip: ch32v307vct6
47-
target: riscv32imafc-unknown-none-elf
47+
target: riscv32imfc-unknown-none-elf
4848
- chip: ch32x035f7p6
49-
target: riscv32imafc-unknown-none-elf
49+
target: riscv32imfc-unknown-none-elf
5050
- chip: ch641
5151
target: riscv32i-unknown-none-elf
5252
runs-on: ubuntu-latest
@@ -57,8 +57,8 @@ jobs:
5757
rustup default nightly
5858
rustup component add rust-src
5959
rustup update
60-
rustup target add riscv32imac-unknown-none-elf
61-
rustup target add riscv32imafc-unknown-none-elf
60+
rustup target add riscv32imc-unknown-none-elf
61+
rustup target add riscv32imfc-unknown-none-elf
6262
rustup target add riscv32i-unknown-none-elf
6363
- name: Fetch Deps
6464
# if this is a pull request

‎Cargo.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ ch32-metapac = { features = [
1717
"rt",
1818
], git = "https://github.com/ch32-rs/ch32-metapac", rev = "cef1944dadf3a5d198e687500b8f5964f29efdf6" }
1919

20-
qingke = { version = "0.4.0", features = ["critical-section-impl"] }
21-
qingke-rt = { version = "0.4.0", optional = true }
20+
qingke = { version = "0.5.0", features = ["critical-section-impl"] }
21+
qingke-rt = { version = "0.5.0", optional = true }
2222

2323
# TODO: remove this
2424
embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = [

‎examples/ch32l103/.cargo/config.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[build]
2-
target = "riscv32imac-unknown-none-elf"
2+
target = "riscv32imc-unknown-none-elf"
33

4-
[target."riscv32imac-unknown-none-elf"]
4+
[target."riscv32imc-unknown-none-elf"]
55
runner = "wlink -v flash --enable-sdi-print --watch-serial"
66
# runner = "wlink -v flash"

‎examples/ch32v103/.cargo/config.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[build]
2-
target = "riscv32imac-unknown-none-elf"
2+
target = "riscv32imc-unknown-none-elf"
33

4-
[target."riscv32imac-unknown-none-elf"]
4+
[target."riscv32imc-unknown-none-elf"]
55
rustflags = [
66
# "-C", "link-arg=-Tlink.x",
77
]

‎examples/ch32v203/.cargo/config.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[build]
2-
target = "riscv32imac-unknown-none-elf"
2+
target = "riscv32imc-unknown-none-elf"
33

4-
[target."riscv32imac-unknown-none-elf"]
4+
[target."riscv32imc-unknown-none-elf"]
55
rustflags = [
66
# "-C", "link-arg=-Tlink.x",
77
]

‎examples/ch32v208/.cargo/config.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[build]
2-
target = "riscv32imac-unknown-none-elf"
2+
target = "riscv32imc-unknown-none-elf"
33

4-
[target."riscv32imac-unknown-none-elf"]
4+
[target."riscv32imc-unknown-none-elf"]
55
runner = "wlink -v flash --enable-sdi-print --watch-serial"
66
# runner = "wlink -v flash"

‎examples/ch32v305/.cargo/config.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[build]
2-
target = "riscv32imafc-unknown-none-elf"
2+
target = "riscv32imfc-unknown-none-elf"
33

4-
[target.riscv32imafc-unknown-none-elf]
4+
[target.riscv32imfc-unknown-none-elf]
55
# runner = "wlink flash --enable-sdi-print --watch-serial"
66
runner = "wlink flash"
77

‎examples/ch32v307/.cargo/config.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[build]
2-
target = "riscv32imafc-unknown-none-elf"
2+
target = "riscv32imfc-unknown-none-elf"
33

4-
[target.riscv32imafc-unknown-none-elf]
4+
[target.riscv32imfc-unknown-none-elf]
55
runner = "wlink flash --enable-sdi-print --watch-serial"
66
# runner = "wlink -v flash --no-erase --dry-run"
77
# runner = "probe-rs run --chip CH32V307"

‎examples/ch32x035/.cargo/config.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[build]
2-
target = "riscv32imac-unknown-none-elf"
2+
target = "riscv32imc-unknown-none-elf"
33

4-
[target.riscv32imac-unknown-none-elf]
4+
[target.riscv32imc-unknown-none-elf]
55
runner = "wlink flash --enable-sdi-print --watch-serial"
66
# runner = "wlink -v flash --no-erase --dry-run"
77
# runner = "probe-rs run --chip CH32V307"

‎src/dma/dma_bdma.rs

+12-21
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
use core::cell::Cell;
12
use core::future::{poll_fn, Future};
23
use core::pin::Pin;
3-
use core::sync::atomic::{compiler_fence, fence, AtomicUsize, Ordering};
4+
use core::sync::atomic::{compiler_fence, fence, Ordering};
45
use core::task::{Context, Poll, Waker};
56

7+
use embassy_sync::blocking_mutex::CriticalSectionMutex;
68
use embassy_sync::waitqueue::AtomicWaker;
79

810
use super::ringbuffer::{DmaCtrl, OverrunError, ReadableDmaRingBuffer, WritableDmaRingBuffer};
@@ -103,13 +105,13 @@ mod bdma_only {
103105

104106
pub(crate) struct ChannelState {
105107
waker: AtomicWaker,
106-
complete_count: AtomicUsize,
108+
complete_count: CriticalSectionMutex<Cell<usize>>,
107109
}
108110

109111
impl ChannelState {
110112
pub(crate) const NEW: Self = Self {
111113
waker: AtomicWaker::new(),
112-
complete_count: AtomicUsize::new(0),
114+
complete_count: CriticalSectionMutex::new(Cell::new(0)),
113115
};
114116
}
115117

@@ -144,13 +146,9 @@ impl AnyChannel {
144146
} else if isr.tcif(info.num) && cr.read().tcie() {
145147
// Acknowledge transfer complete interrupt
146148
r.ifcr().write(|w| w.set_tcif(info.num, true));
147-
#[cfg(not(qingke_v2))]
148-
state.complete_count.fetch_add(1, Ordering::Release);
149-
#[cfg(qingke_v2)]
150-
critical_section::with(|_| {
151-
let x = state.complete_count.load(Ordering::Relaxed);
152-
state.complete_count.store(x + 1, Ordering::Release);
153-
})
149+
state.complete_count.lock(|v| {
150+
v.set(v.get() + 1);
151+
});
154152
} else {
155153
return;
156154
}
@@ -180,7 +178,7 @@ impl AnyChannel {
180178
let state: &ChannelState = &STATE[self.id as usize];
181179
let ch = r.ch(info.num);
182180

183-
state.complete_count.store(0, Ordering::Release);
181+
state.complete_count.lock(|c| c.set(0));
184182
self.clear_irqs();
185183

186184
ch.par().write_value(peri_addr as u32); // PADDR
@@ -246,7 +244,7 @@ impl AnyChannel {
246244
let ch = r.ch(info.num);
247245
let en = ch.cr().read().en();
248246
let circular = ch.cr().read().circ();
249-
let tcif = state.complete_count.load(Ordering::Acquire) != 0;
247+
let tcif = state.complete_count.lock(|c| c.get()) != 0;
250248
en && (circular || !tcif)
251249
}
252250
}
@@ -471,19 +469,12 @@ impl<'a> DmaCtrl for DmaCtrlImpl<'a> {
471469
}
472470

473471
fn get_complete_count(&self) -> usize {
474-
STATE[self.0.id as usize].complete_count.load(Ordering::Acquire)
472+
STATE[self.0.id as usize].complete_count.lock(|c| c.get())
475473
}
476474

477475
fn reset_complete_count(&mut self) -> usize {
478476
let state = &STATE[self.0.id as usize];
479-
#[cfg(not(qingke_v2))]
480-
return state.complete_count.swap(0, Ordering::AcqRel);
481-
#[cfg(qingke_v2)]
482-
return critical_section::with(|_| {
483-
let x = state.complete_count.load(Ordering::Acquire);
484-
state.complete_count.store(0, Ordering::Release);
485-
x
486-
});
477+
state.complete_count.lock(|c| c.replace(0))
487478
}
488479

489480
fn set_waker(&mut self, waker: &Waker) {

0 commit comments

Comments
 (0)
Please sign in to comment.