diff options
| author | Dario Nieuwenhuis <[email protected]> | 2023-03-07 15:28:27 +0100 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2023-03-07 15:28:27 +0100 |
| commit | 27e989afa95458aec4a48411dbaf58da565eaed0 (patch) | |
| tree | 67ad02ac48e52f93726c61f9fe5e28d5eb4563f4 /embassy-nrf | |
| parent | 18fe398673f55b07159d01a230910bb9689c1525 (diff) | |
nrf/uicr: only check lowest bit.
This mirrors what nrfx does. Also it won't reboot/warn if NFCPINS is set to either
0xFFFF_FFFE or 0x0000_0000, which are all valid.
Diffstat (limited to 'embassy-nrf')
| -rw-r--r-- | embassy-nrf/src/lib.rs | 22 |
1 files changed, 9 insertions, 13 deletions
diff --git a/embassy-nrf/src/lib.rs b/embassy-nrf/src/lib.rs index cb629902a..8defc551b 100644 --- a/embassy-nrf/src/lib.rs +++ b/embassy-nrf/src/lib.rs | |||
| @@ -273,28 +273,24 @@ enum WriteResult { | |||
| 273 | } | 273 | } |
| 274 | 274 | ||
| 275 | unsafe fn uicr_write(address: *mut u32, value: u32) -> WriteResult { | 275 | unsafe fn uicr_write(address: *mut u32, value: u32) -> WriteResult { |
| 276 | uicr_write_masked(address, value, 0xFFFF_FFFF) | ||
| 277 | } | ||
| 278 | |||
| 279 | unsafe fn uicr_write_masked(address: *mut u32, value: u32, mask: u32) -> WriteResult { | ||
| 276 | let curr_val = address.read_volatile(); | 280 | let curr_val = address.read_volatile(); |
| 277 | if curr_val == value { | 281 | if curr_val & mask == value & mask { |
| 278 | return WriteResult::Noop; | 282 | return WriteResult::Noop; |
| 279 | } | 283 | } |
| 280 | 284 | ||
| 281 | // We can only change `1` bits to `0` bits. | 285 | // We can only change `1` bits to `0` bits. |
| 282 | if curr_val & value != value { | 286 | if curr_val & value & mask != value & mask { |
| 283 | return WriteResult::Failed; | 287 | return WriteResult::Failed; |
| 284 | } | 288 | } |
| 285 | 289 | ||
| 286 | // Writing to UICR can only change `1` bits to `0` bits. | ||
| 287 | // If this write would change `0` bits to `1` bits, we can't do it. | ||
| 288 | // It is only possible to do when erasing UICR, which is forbidden if | ||
| 289 | // APPROTECT is enabled. | ||
| 290 | if (!curr_val) & value != 0 { | ||
| 291 | panic!("Cannot write UICR address={:08x} value={:08x}", address as u32, value) | ||
| 292 | } | ||
| 293 | |||
| 294 | let nvmc = &*pac::NVMC::ptr(); | 290 | let nvmc = &*pac::NVMC::ptr(); |
| 295 | nvmc.config.write(|w| w.wen().wen()); | 291 | nvmc.config.write(|w| w.wen().wen()); |
| 296 | while nvmc.ready.read().ready().is_busy() {} | 292 | while nvmc.ready.read().ready().is_busy() {} |
| 297 | address.write_volatile(value); | 293 | address.write_volatile(value | !mask); |
| 298 | while nvmc.ready.read().ready().is_busy() {} | 294 | while nvmc.ready.read().ready().is_busy() {} |
| 299 | nvmc.config.reset(); | 295 | nvmc.config.reset(); |
| 300 | while nvmc.ready.read().ready().is_busy() {} | 296 | while nvmc.ready.read().ready().is_busy() {} |
| @@ -393,8 +389,8 @@ pub fn init(config: config::Config) -> Peripherals { | |||
| 393 | 389 | ||
| 394 | #[cfg(any(feature = "_nrf52", feature = "_nrf5340-app"))] | 390 | #[cfg(any(feature = "_nrf52", feature = "_nrf5340-app"))] |
| 395 | unsafe { | 391 | unsafe { |
| 396 | let value = if cfg!(feature = "nfc-pins-as-gpio") { 0 } else { !0 }; | 392 | let value = if cfg!(feature = "nfc-pins-as-gpio") { 0 } else { 1 }; |
| 397 | let res = uicr_write(consts::UICR_NFCPINS, value); | 393 | let res = uicr_write_masked(consts::UICR_NFCPINS, value, 1); |
| 398 | needs_reset |= res == WriteResult::Written; | 394 | needs_reset |= res == WriteResult::Written; |
| 399 | if res == WriteResult::Failed { | 395 | if res == WriteResult::Failed { |
| 400 | // with nfc-pins-as-gpio, this can never fail because we're writing all zero bits. | 396 | // with nfc-pins-as-gpio, this can never fail because we're writing all zero bits. |
