Skip to content

Commit 20a1cca

Browse files
committed
Use immutable refs for internal duty buffers
1 parent 006b1d9 commit 20a1cca

File tree

1 file changed

+33
-31
lines changed

1 file changed

+33
-31
lines changed

nrf-hal-common/src/pwm.rs

Lines changed: 33 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -285,10 +285,9 @@ where
285285
/// Sets duty cycle (15 bit) for all PWM channels.
286286
/// Will replace any ongoing sequence playback.
287287
pub fn set_duty_on_common(&self, duty: u16) {
288-
compiler_fence(Ordering::SeqCst);
289-
T::buffer()
290-
.get_mut()
291-
.copy_from_slice(&[duty.min(self.max_duty()) & 0x7FFF; 4][..]);
288+
let mut buffer = T::buffer().take();
289+
buffer.copy_from_slice(&[duty.min(self.max_duty()) & 0x7FFF; 4][..]);
290+
T::buffer().set(buffer);
292291
self.one_shot();
293292
self.set_load_mode(LoadMode::Common);
294293
self.pwm
@@ -302,10 +301,9 @@ where
302301
/// Sets inverted duty cycle (15 bit) for all PWM channels.
303302
/// Will replace any ongoing sequence playback.
304303
pub fn set_duty_off_common(&self, duty: u16) {
305-
compiler_fence(Ordering::SeqCst);
306-
T::buffer()
307-
.get_mut()
308-
.copy_from_slice(&[duty.min(self.max_duty()) | 0x8000; 4][..]);
304+
let mut buffer = T::buffer().take();
305+
buffer.copy_from_slice(&[duty.min(self.max_duty()) | 0x8000; 4][..]);
306+
T::buffer().set(buffer);
309307
self.one_shot();
310308
self.set_load_mode(LoadMode::Common);
311309
self.pwm
@@ -331,8 +329,9 @@ where
331329
/// Sets duty cycle (15 bit) for a PWM group.
332330
/// Will replace any ongoing sequence playback.
333331
pub fn set_duty_on_group(&self, group: Group, duty: u16) {
334-
compiler_fence(Ordering::SeqCst);
335-
T::buffer().get_mut()[usize::from(group)] = duty.min(self.max_duty()) & 0x7FFF;
332+
let mut buffer = T::buffer().take();
333+
buffer[usize::from(group)] = duty.min(self.max_duty()) & 0x7FFF;
334+
T::buffer().set(buffer);
336335
self.one_shot();
337336
self.set_load_mode(LoadMode::Grouped);
338337
self.pwm
@@ -346,8 +345,9 @@ where
346345
/// Sets inverted duty cycle (15 bit) for a PWM group.
347346
/// Will replace any ongoing sequence playback.
348347
pub fn set_duty_off_group(&self, group: Group, duty: u16) {
349-
compiler_fence(Ordering::SeqCst);
350-
T::buffer().get_mut()[usize::from(group)] = duty.min(self.max_duty()) | 0x8000;
348+
let mut buffer = T::buffer().take();
349+
buffer[usize::from(group)] = duty.min(self.max_duty()) | 0x8000;
350+
T::buffer().set(buffer);
351351
self.one_shot();
352352
self.set_load_mode(LoadMode::Grouped);
353353
self.pwm
@@ -373,25 +373,27 @@ where
373373
/// Sets duty cycle (15 bit) for a PWM channel.
374374
/// Will replace any ongoing sequence playback and the other channels will return to their previously set value.
375375
pub fn set_duty_on(&self, channel: Channel, duty: u16) {
376-
compiler_fence(Ordering::SeqCst);
377-
T::buffer().get_mut()[usize::from(channel)] = duty.min(self.max_duty()) & 0x7FFF;
376+
let mut buffer = T::buffer().take();
377+
buffer[usize::from(channel)] = duty.min(self.max_duty()) & 0x7FFF;
378+
T::buffer().set(buffer);
378379
self.one_shot();
379380
self.set_load_mode(LoadMode::Individual);
380-
if self.load_seq(Seq::Seq0, T::buffer().get_mut()).is_ok() {
381-
self.start_seq(Seq::Seq0);
382-
}
381+
self.pwm.seq0.ptr.write(|w| unsafe { w.bits(T::buffer().as_ptr() as u32) });
382+
self.pwm.seq0.cnt.write(|w| unsafe { w.bits(4) });
383+
self.start_seq(Seq::Seq0);
383384
}
384385

385386
/// Sets inverted duty cycle (15 bit) for a PWM channel.
386387
/// Will replace any ongoing sequence playback and the other channels will return to their previously set value.
387388
pub fn set_duty_off(&self, channel: Channel, duty: u16) {
388-
compiler_fence(Ordering::SeqCst);
389-
T::buffer().get_mut()[usize::from(channel)] = duty.min(self.max_duty()) | 0x8000;
389+
let mut buffer = T::buffer().take();
390+
buffer[usize::from(channel)] = duty.min(self.max_duty()) | 0x8000;
391+
T::buffer().set(buffer);
390392
self.one_shot();
391393
self.set_load_mode(LoadMode::Individual);
392-
if self.load_seq(Seq::Seq0, T::buffer().get_mut()).is_ok() {
393-
self.start_seq(Seq::Seq0);
394-
}
394+
self.pwm.seq0.ptr.write(|w| unsafe { w.bits(T::buffer().as_ptr() as u32) });
395+
self.pwm.seq0.cnt.write(|w| unsafe { w.bits(4) });
396+
self.start_seq(Seq::Seq0);
395397
}
396398

397399
/// Returns the duty cycle value for a PWM channel.
@@ -1094,7 +1096,7 @@ pub trait Instance: private::Sealed + Deref<Target = crate::pac::pwm0::RegisterB
10941096
const INTERRUPT: Interrupt;
10951097

10961098
/// Provides access to the associated internal duty buffer for the instance.
1097-
fn buffer() -> &'static mut Cell<[u16; 4]>;
1099+
fn buffer() -> &'static Cell<[u16; 4]>;
10981100
}
10991101

11001102
// Internal static duty buffers. One per instance.
@@ -1109,32 +1111,32 @@ static mut BUF3: Cell<[u16; 4]> = Cell::new([0; 4]);
11091111
impl Instance for PWM0 {
11101112
const INTERRUPT: Interrupt = Interrupt::PWM0;
11111113
#[inline(always)]
1112-
fn buffer() -> &'static mut Cell<[u16; 4]> {
1113-
unsafe { &mut BUF0 }
1114+
fn buffer() -> &'static Cell<[u16; 4]> {
1115+
unsafe { &BUF0 }
11141116
}
11151117
}
11161118

11171119
#[cfg(not(any(feature = "52810", feature = "52811")))]
11181120
impl Instance for PWM1 {
11191121
const INTERRUPT: Interrupt = Interrupt::PWM1;
1120-
fn buffer() -> &'static mut Cell<[u16; 4]> {
1121-
unsafe { &mut BUF1 }
1122+
fn buffer() -> &'static Cell<[u16; 4]> {
1123+
unsafe { &BUF1 }
11221124
}
11231125
}
11241126

11251127
#[cfg(not(any(feature = "52810", feature = "52811")))]
11261128
impl Instance for PWM2 {
11271129
const INTERRUPT: Interrupt = Interrupt::PWM2;
1128-
fn buffer() -> &'static mut Cell<[u16; 4]> {
1129-
unsafe { &mut BUF2 }
1130+
fn buffer() -> &'static Cell<[u16; 4]> {
1131+
unsafe { &BUF2 }
11301132
}
11311133
}
11321134

11331135
#[cfg(not(any(feature = "52810", feature = "52811", feature = "52832")))]
11341136
impl Instance for PWM3 {
11351137
const INTERRUPT: Interrupt = Interrupt::PWM3;
1136-
fn buffer() -> &'static mut Cell<[u16; 4]> {
1137-
unsafe { &mut BUF3 }
1138+
fn buffer() -> &'static Cell<[u16; 4]> {
1139+
unsafe { &BUF3 }
11381140
}
11391141
}
11401142

0 commit comments

Comments
 (0)