aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2024-12-02 22:50:48 +0000
committerGitHub <[email protected]>2024-12-02 22:50:48 +0000
commit333284588a4c2639913df47099220d2dece50834 (patch)
treed9fdb374eebb68a722dba06e2b6bc1b1ae73d41d
parentdb9ad1c30cdd3e07d4b41eb4bd136e01d6125ff3 (diff)
parent69cb30ebf3772a20612f53202ab4b8e880b0583c (diff)
Merge pull request #3543 from ionspin/rp2350_otp_write
RP235X Add OTP write functions
-rw-r--r--embassy-rp/src/otp.rs71
1 files changed, 69 insertions, 2 deletions
diff --git a/embassy-rp/src/otp.rs b/embassy-rp/src/otp.rs
index cdaf5bded..6091f71b2 100644
--- a/embassy-rp/src/otp.rs
+++ b/embassy-rp/src/otp.rs
@@ -3,15 +3,24 @@
3// Credit: taken from `rp-hal` (also licensed Apache+MIT) 3// Credit: taken from `rp-hal` (also licensed Apache+MIT)
4// https://github.com/rp-rs/rp-hal/blob/main/rp235x-hal/src/rom_data.rs 4// https://github.com/rp-rs/rp-hal/blob/main/rp235x-hal/src/rom_data.rs
5 5
6/// The ways in which we can fail to read OTP 6use crate::rom_data::otp_access;
7
8/// The ways in which we can fail to access OTP
7#[derive(Debug, Clone)] 9#[derive(Debug, Clone)]
8#[cfg_attr(feature = "defmt", derive(defmt::Format))] 10#[cfg_attr(feature = "defmt", derive(defmt::Format))]
9pub enum Error { 11pub enum Error {
10 /// The user passed an invalid index to a function. 12 /// The user passed an invalid index to a function.
11 InvalidIndex, 13 InvalidIndex,
12 /// The hardware refused to let us read this word, probably due to 14 /// The hardware refused to let us read this word, probably due to
13 /// read lock set earlier in the boot process. 15 /// read or write lock set earlier in the boot process.
14 InvalidPermissions, 16 InvalidPermissions,
17 /// Modification is impossible based on current state; e.g.
18 /// attempted to clear an OTP bit.
19 UnsupportedModification,
20 /// Value being written is bigger than 24 bits allowed for raw writes.
21 Overflow,
22 /// An unexpected failure that contains the exact return code
23 UnexpectedFailure(i32),
15} 24}
16 25
17/// OTP read address, using automatic Error Correction. 26/// OTP read address, using automatic Error Correction.
@@ -34,6 +43,9 @@ pub const NUM_ROWS_PER_PAGE: usize = 64;
34/// How many rows in OTP (post error-correction) 43/// How many rows in OTP (post error-correction)
35pub const NUM_ROWS: usize = NUM_PAGES * NUM_ROWS_PER_PAGE; 44pub const NUM_ROWS: usize = NUM_PAGES * NUM_ROWS_PER_PAGE;
36 45
46/// 24bit mask for raw writes
47pub const RAW_WRITE_BIT_MASK: u32 = 0x00FF_FFFF;
48
37/// Read one ECC protected word from the OTP 49/// Read one ECC protected word from the OTP
38pub fn read_ecc_word(row: usize) -> Result<u16, Error> { 50pub fn read_ecc_word(row: usize) -> Result<u16, Error> {
39 if row >= NUM_ROWS { 51 if row >= NUM_ROWS {
@@ -72,6 +84,61 @@ pub fn read_raw_word(row: usize) -> Result<u32, Error> {
72 Ok(value) 84 Ok(value)
73 } 85 }
74} 86}
87/// Write one raw word to the OTP
88///
89/// 24 bit value will be written to the OTP
90pub fn write_raw_word(row: usize, data: u32) -> Result<(), Error> {
91 if data > RAW_WRITE_BIT_MASK {
92 return Err(Error::Overflow);
93 }
94 if row >= NUM_ROWS {
95 return Err(Error::InvalidIndex);
96 }
97 let row_with_write_bit = row | 0x00010000;
98 // # Safety
99 //
100 // We checked this row was in range already.
101 let result = unsafe { otp_access(data.to_le_bytes().as_mut_ptr(), 4, row_with_write_bit as u32) };
102 if result == 0 {
103 Ok(())
104 } else {
105 // 5.4.3. API Function Return Codes
106 let error = match result {
107 -4 => Error::InvalidPermissions,
108 -18 => Error::UnsupportedModification,
109 _ => Error::UnexpectedFailure(result),
110 };
111 Err(error)
112 }
113}
114
115/// Write one raw word to the OTP with ECC
116///
117/// 16 bit value will be written + ECC
118pub fn write_ecc_word(row: usize, data: u16) -> Result<(), Error> {
119 if row >= NUM_ROWS {
120 return Err(Error::InvalidIndex);
121 }
122 let row_with_write_and_ecc_bit = row | 0x00030000;
123
124 // # Safety
125 //
126 // We checked this row was in range already.
127
128 let result = unsafe { otp_access(data.to_le_bytes().as_mut_ptr(), 2, row_with_write_and_ecc_bit as u32) };
129 if result == 0 {
130 Ok(())
131 } else {
132 // 5.4.3. API Function Return Codes
133 // 5.4.3. API Function Return Codes
134 let error = match result {
135 -4 => Error::InvalidPermissions,
136 -18 => Error::UnsupportedModification,
137 _ => Error::UnexpectedFailure(result),
138 };
139 Err(error)
140 }
141}
75 142
76/// Get the random 64bit chipid from rows 0x0-0x3. 143/// Get the random 64bit chipid from rows 0x0-0x3.
77pub fn get_chipid() -> Result<u64, Error> { 144pub fn get_chipid() -> Result<u64, Error> {