aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMateusz Butkiewicz <[email protected]>2023-03-29 13:27:20 +0200
committerMateusz Butkiewicz <[email protected]>2023-03-29 14:28:25 +0200
commit87898501a2f66ee179562fa88bfc9a1b4a2ada9b (patch)
tree404eb92cc078251d5596ecb124e17adcf251bb68
parent6a802c47083e4f6bb7b7c6c06fd2ef3e291a5212 (diff)
feat(stm32:qspi): convert some u8 to enum variants
-rw-r--r--embassy-stm32/src/qspi/enums.rs294
-rw-r--r--embassy-stm32/src/qspi/mod.rs116
2 files changed, 350 insertions, 60 deletions
diff --git a/embassy-stm32/src/qspi/enums.rs b/embassy-stm32/src/qspi/enums.rs
new file mode 100644
index 000000000..2dbe2b061
--- /dev/null
+++ b/embassy-stm32/src/qspi/enums.rs
@@ -0,0 +1,294 @@
1#[allow(dead_code)]
2#[derive(Copy, Clone)]
3pub(crate) enum QspiMode {
4 IndirectWrite,
5 IndirectRead,
6 AutoPolling,
7 MemoryMapped,
8}
9
10impl Into<u8> for QspiMode {
11 fn into(self) -> u8 {
12 match self {
13 QspiMode::IndirectWrite => 0b00,
14 QspiMode::IndirectRead => 0b01,
15 QspiMode::AutoPolling => 0b10,
16 QspiMode::MemoryMapped => 0b11,
17 }
18 }
19}
20
21#[allow(dead_code)]
22#[derive(Copy, Clone)]
23pub enum QspiWidth {
24 NONE,
25 SING,
26 DUAL,
27 QUAD,
28}
29
30impl Into<u8> for QspiWidth {
31 fn into(self) -> u8 {
32 match self {
33 QspiWidth::NONE => 0b00,
34 QspiWidth::SING => 0b01,
35 QspiWidth::DUAL => 0b10,
36 QspiWidth::QUAD => 0b11,
37 }
38 }
39}
40
41#[derive(Copy, Clone)]
42pub enum MemorySize {
43 _1KiB,
44 _2KiB,
45 _4KiB,
46 _8KiB,
47 _16KiB,
48 _32KiB,
49 _64KiB,
50 _128KiB,
51 _256KiB,
52 _512KiB,
53 _1MiB,
54 _2MiB,
55 _4MiB,
56 _8MiB,
57 _16MiB,
58 _32MiB,
59 _64MiB,
60 _128MiB,
61 _256MiB,
62 _512MiB,
63 _1GiB,
64 _2GiB,
65 _4GiB,
66 Other(u8),
67}
68
69impl Into<u8> for MemorySize {
70 fn into(self) -> u8 {
71 match self {
72 MemorySize::_1KiB => 9,
73 MemorySize::_2KiB => 10,
74 MemorySize::_4KiB => 11,
75 MemorySize::_8KiB => 12,
76 MemorySize::_16KiB => 13,
77 MemorySize::_32KiB => 14,
78 MemorySize::_64KiB => 15,
79 MemorySize::_128KiB => 16,
80 MemorySize::_256KiB => 17,
81 MemorySize::_512KiB => 18,
82 MemorySize::_1MiB => 19,
83 MemorySize::_2MiB => 20,
84 MemorySize::_4MiB => 21,
85 MemorySize::_8MiB => 22,
86 MemorySize::_16MiB => 23,
87 MemorySize::_32MiB => 24,
88 MemorySize::_64MiB => 25,
89 MemorySize::_128MiB => 26,
90 MemorySize::_256MiB => 27,
91 MemorySize::_512MiB => 28,
92 MemorySize::_1GiB => 29,
93 MemorySize::_2GiB => 30,
94 MemorySize::_4GiB => 31,
95 MemorySize::Other(val) => val,
96 }
97 }
98}
99
100#[derive(Copy, Clone)]
101pub enum AddressSize {
102 _8Bit,
103 _16Bit,
104 _24bit,
105 _32bit,
106}
107
108impl Into<u8> for AddressSize {
109 fn into(self) -> u8 {
110 match self {
111 AddressSize::_8Bit => 0b00,
112 AddressSize::_16Bit => 0b01,
113 AddressSize::_24bit => 0b10,
114 AddressSize::_32bit => 0b11,
115 }
116 }
117}
118
119#[derive(Copy, Clone)]
120pub enum ChipSelectHightTime {
121 _1Cycle,
122 _2Cycle,
123 _3Cycle,
124 _4Cycle,
125 _5Cycle,
126 _6Cycle,
127 _7Cycle,
128 _8Cycle,
129}
130
131impl Into<u8> for ChipSelectHightTime {
132 fn into(self) -> u8 {
133 match self {
134 ChipSelectHightTime::_1Cycle => 0,
135 ChipSelectHightTime::_2Cycle => 1,
136 ChipSelectHightTime::_3Cycle => 2,
137 ChipSelectHightTime::_4Cycle => 3,
138 ChipSelectHightTime::_5Cycle => 4,
139 ChipSelectHightTime::_6Cycle => 5,
140 ChipSelectHightTime::_7Cycle => 6,
141 ChipSelectHightTime::_8Cycle => 7,
142 }
143 }
144}
145
146#[derive(Copy, Clone)]
147pub enum FIFOThresholdLevel {
148 _1Bytes,
149 _2Bytes,
150 _3Bytes,
151 _4Bytes,
152 _5Bytes,
153 _6Bytes,
154 _7Bytes,
155 _8Bytes,
156 _9Bytes,
157 _10Bytes,
158 _11Bytes,
159 _12Bytes,
160 _13Bytes,
161 _14Bytes,
162 _15Bytes,
163 _16Bytes,
164 _17Bytes,
165 _18Bytes,
166 _19Bytes,
167 _20Bytes,
168 _21Bytes,
169 _22Bytes,
170 _23Bytes,
171 _24Bytes,
172 _25Bytes,
173 _26Bytes,
174 _27Bytes,
175 _28Bytes,
176 _29Bytes,
177 _30Bytes,
178 _31Bytes,
179 _32Bytes,
180}
181
182impl Into<u8> for FIFOThresholdLevel {
183 fn into(self) -> u8 {
184 match self {
185 FIFOThresholdLevel::_1Bytes => 0,
186 FIFOThresholdLevel::_2Bytes => 1,
187 FIFOThresholdLevel::_3Bytes => 2,
188 FIFOThresholdLevel::_4Bytes => 3,
189 FIFOThresholdLevel::_5Bytes => 4,
190 FIFOThresholdLevel::_6Bytes => 5,
191 FIFOThresholdLevel::_7Bytes => 6,
192 FIFOThresholdLevel::_8Bytes => 7,
193 FIFOThresholdLevel::_9Bytes => 8,
194 FIFOThresholdLevel::_10Bytes => 9,
195 FIFOThresholdLevel::_11Bytes => 10,
196 FIFOThresholdLevel::_12Bytes => 11,
197 FIFOThresholdLevel::_13Bytes => 12,
198 FIFOThresholdLevel::_14Bytes => 13,
199 FIFOThresholdLevel::_15Bytes => 14,
200 FIFOThresholdLevel::_16Bytes => 15,
201 FIFOThresholdLevel::_17Bytes => 16,
202 FIFOThresholdLevel::_18Bytes => 17,
203 FIFOThresholdLevel::_19Bytes => 18,
204 FIFOThresholdLevel::_20Bytes => 19,
205 FIFOThresholdLevel::_21Bytes => 20,
206 FIFOThresholdLevel::_22Bytes => 21,
207 FIFOThresholdLevel::_23Bytes => 22,
208 FIFOThresholdLevel::_24Bytes => 23,
209 FIFOThresholdLevel::_25Bytes => 24,
210 FIFOThresholdLevel::_26Bytes => 25,
211 FIFOThresholdLevel::_27Bytes => 26,
212 FIFOThresholdLevel::_28Bytes => 27,
213 FIFOThresholdLevel::_29Bytes => 28,
214 FIFOThresholdLevel::_30Bytes => 29,
215 FIFOThresholdLevel::_31Bytes => 30,
216 FIFOThresholdLevel::_32Bytes => 31,
217 }
218 }
219}
220
221#[derive(Copy, Clone)]
222pub enum DummyCycles {
223 _0,
224 _1,
225 _2,
226 _3,
227 _4,
228 _5,
229 _6,
230 _7,
231 _8,
232 _9,
233 _10,
234 _11,
235 _12,
236 _13,
237 _14,
238 _15,
239 _16,
240 _17,
241 _18,
242 _19,
243 _20,
244 _21,
245 _22,
246 _23,
247 _24,
248 _25,
249 _26,
250 _27,
251 _28,
252 _29,
253 _30,
254 _31,
255}
256
257impl Into<u8> for DummyCycles {
258 fn into(self) -> u8 {
259 match self {
260 DummyCycles::_0 => 0,
261 DummyCycles::_1 => 1,
262 DummyCycles::_2 => 2,
263 DummyCycles::_3 => 3,
264 DummyCycles::_4 => 4,
265 DummyCycles::_5 => 5,
266 DummyCycles::_6 => 6,
267 DummyCycles::_7 => 7,
268 DummyCycles::_8 => 8,
269 DummyCycles::_9 => 9,
270 DummyCycles::_10 => 10,
271 DummyCycles::_11 => 11,
272 DummyCycles::_12 => 12,
273 DummyCycles::_13 => 13,
274 DummyCycles::_14 => 14,
275 DummyCycles::_15 => 15,
276 DummyCycles::_16 => 16,
277 DummyCycles::_17 => 17,
278 DummyCycles::_18 => 18,
279 DummyCycles::_19 => 19,
280 DummyCycles::_20 => 20,
281 DummyCycles::_21 => 21,
282 DummyCycles::_22 => 22,
283 DummyCycles::_23 => 23,
284 DummyCycles::_24 => 24,
285 DummyCycles::_25 => 25,
286 DummyCycles::_26 => 26,
287 DummyCycles::_27 => 27,
288 DummyCycles::_28 => 28,
289 DummyCycles::_29 => 29,
290 DummyCycles::_30 => 30,
291 DummyCycles::_31 => 31,
292 }
293 }
294}
diff --git a/embassy-stm32/src/qspi/mod.rs b/embassy-stm32/src/qspi/mod.rs
index f375d1b46..f33319620 100644
--- a/embassy-stm32/src/qspi/mod.rs
+++ b/embassy-stm32/src/qspi/mod.rs
@@ -1,6 +1,9 @@
1#![macro_use] 1#![macro_use]
2 2
3pub mod enums;
4
3use embassy_hal_common::{into_ref, PeripheralRef}; 5use embassy_hal_common::{into_ref, PeripheralRef};
6use enums::*;
4 7
5use crate::dma::TransferOptions; 8use crate::dma::TransferOptions;
6use crate::gpio::sealed::AFType; 9use crate::gpio::sealed::AFType;
@@ -9,37 +12,24 @@ use crate::pac::quadspi::Quadspi as Regs;
9use crate::rcc::RccPeripheral; 12use crate::rcc::RccPeripheral;
10use crate::{peripherals, Peripheral}; 13use crate::{peripherals, Peripheral};
11 14
12pub struct QspiWidth; 15pub struct TransferConfig {
13 16 /// Instraction width (IMODE)
14#[allow(dead_code)] 17 pub iwidth: QspiWidth,
15impl QspiWidth { 18 /// Address width (ADMODE)
16 pub const NONE: u8 = 0b00; 19 pub awidth: QspiWidth,
17 pub const SING: u8 = 0b01; 20 /// Data width (DMODE)
18 pub const DUAL: u8 = 0b10; 21 pub dwidth: QspiWidth,
19 pub const QUAD: u8 = 0b11; 22 /// Instruction Id
20}
21
22struct QspiMode;
23
24#[allow(dead_code)]
25impl QspiMode {
26 pub const INDIRECT_WRITE: u8 = 0b00;
27 pub const INDIRECT_READ: u8 = 0b01;
28 pub const AUTO_POLLING: u8 = 0b10;
29 pub const MEMORY_MAPPED: u8 = 0b11;
30}
31
32pub struct QspiTransaction {
33 pub iwidth: u8,
34 pub awidth: u8,
35 pub dwidth: u8,
36 pub instruction: u8, 23 pub instruction: u8,
24 /// Flash memory address
37 pub address: Option<u32>, 25 pub address: Option<u32>,
38 pub dummy: u8, 26 /// Number of dummy cycles (DCYC)
27 pub dummy: DummyCycles,
28 /// Length of data
39 pub data_len: Option<usize>, 29 pub data_len: Option<usize>,
40} 30}
41 31
42impl Default for QspiTransaction { 32impl Default for TransferConfig {
43 fn default() -> Self { 33 fn default() -> Self {
44 Self { 34 Self {
45 iwidth: QspiWidth::NONE, 35 iwidth: QspiWidth::NONE,
@@ -47,28 +37,34 @@ impl Default for QspiTransaction {
47 dwidth: QspiWidth::NONE, 37 dwidth: QspiWidth::NONE,
48 instruction: 0, 38 instruction: 0,
49 address: None, 39 address: None,
50 dummy: 0, 40 dummy: DummyCycles::_0,
51 data_len: None, 41 data_len: None,
52 } 42 }
53 } 43 }
54} 44}
55 45
56pub struct Config { 46pub struct Config {
57 pub memory_size: u8, 47 /// Flash memory size representend as 2^[0-32], as reasonable minimum 1KiB(9) was chosen.
58 pub address_size: u8, 48 /// If you need other value the whose predefined use `Other` variant.
49 pub memory_size: MemorySize,
50 /// Address size (8/16/24/32-bit)
51 pub address_size: AddressSize,
52 /// Scalar factor for generating CLK [0-255]
59 pub prescaler: u8, 53 pub prescaler: u8,
60 pub fifo_threshold: u8, 54 /// Number of bytes to trigger FIFO threshold flag.
61 pub cs_high_time: u8, 55 pub fifo_threshold: FIFOThresholdLevel,
56 /// Minimum number of cycles that chip select must be high between issued commands
57 pub cs_high_time: ChipSelectHightTime,
62} 58}
63 59
64impl Default for Config { 60impl Default for Config {
65 fn default() -> Self { 61 fn default() -> Self {
66 Self { 62 Self {
67 memory_size: 0, 63 memory_size: MemorySize::Other(0),
68 address_size: 2, 64 address_size: AddressSize::_24bit,
69 prescaler: 128, 65 prescaler: 128,
70 fifo_threshold: 16, 66 fifo_threshold: FIFOThresholdLevel::_17Bytes,
71 cs_high_time: 4, 67 cs_high_time: ChipSelectHightTime::_5Cycle,
72 } 68 }
73 } 69 }
74} 70}
@@ -143,7 +139,7 @@ impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> {
143 139
144 T::enable(); 140 T::enable();
145 unsafe { 141 unsafe {
146 T::REGS.cr().write(|w| w.set_fthres(config.fifo_threshold)); 142 T::REGS.cr().write(|w| w.set_fthres(config.fifo_threshold.into()));
147 143
148 while T::REGS.sr().read().busy() {} 144 while T::REGS.sr().read().busy() {}
149 145
@@ -152,8 +148,8 @@ impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> {
152 w.set_en(true); 148 w.set_en(true);
153 }); 149 });
154 T::REGS.dcr().write(|w| { 150 T::REGS.dcr().write(|w| {
155 w.set_fsize(config.memory_size); 151 w.set_fsize(config.memory_size.into());
156 w.set_csht(config.cs_high_time); 152 w.set_csht(config.cs_high_time.into());
157 w.set_ckmode(false); 153 w.set_ckmode(false);
158 }); 154 });
159 } 155 }
@@ -171,25 +167,25 @@ impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> {
171 } 167 }
172 } 168 }
173 169
174 pub fn command(&mut self, transaction: QspiTransaction) { 170 pub fn command(&mut self, transaction: TransferConfig) {
175 unsafe { 171 unsafe {
176 T::REGS.cr().modify(|v| v.set_dmaen(false)); 172 T::REGS.cr().modify(|v| v.set_dmaen(false));
177 self.setup_transaction(QspiMode::INDIRECT_WRITE, &transaction); 173 self.setup_transaction(QspiMode::IndirectWrite, &transaction);
178 174
179 while !T::REGS.sr().read().tcf() {} 175 while !T::REGS.sr().read().tcf() {}
180 T::REGS.fcr().modify(|v| v.set_ctcf(true)); 176 T::REGS.fcr().modify(|v| v.set_ctcf(true));
181 } 177 }
182 } 178 }
183 179
184 pub fn read(&mut self, buf: &mut [u8], transaction: QspiTransaction) { 180 pub fn blocking_read(&mut self, buf: &mut [u8], transaction: TransferConfig) {
185 unsafe { 181 unsafe {
186 T::REGS.cr().modify(|v| v.set_dmaen(false)); 182 T::REGS.cr().modify(|v| v.set_dmaen(false));
187 self.setup_transaction(QspiMode::INDIRECT_WRITE, &transaction); 183 self.setup_transaction(QspiMode::IndirectWrite, &transaction);
188 184
189 if let Some(len) = transaction.data_len { 185 if let Some(len) = transaction.data_len {
190 let current_ar = T::REGS.ar().read().address(); 186 let current_ar = T::REGS.ar().read().address();
191 T::REGS.ccr().modify(|v| { 187 T::REGS.ccr().modify(|v| {
192 v.set_fmode(QspiMode::INDIRECT_READ); 188 v.set_fmode(QspiMode::IndirectRead.into());
193 }); 189 });
194 T::REGS.ar().write(|v| { 190 T::REGS.ar().write(|v| {
195 v.set_address(current_ar); 191 v.set_address(current_ar);
@@ -206,14 +202,14 @@ impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> {
206 } 202 }
207 } 203 }
208 204
209 pub fn write(&mut self, buf: &[u8], transaction: QspiTransaction) { 205 pub fn blocking_write(&mut self, buf: &[u8], transaction: TransferConfig) {
210 unsafe { 206 unsafe {
211 T::REGS.cr().modify(|v| v.set_dmaen(false)); 207 T::REGS.cr().modify(|v| v.set_dmaen(false));
212 self.setup_transaction(QspiMode::INDIRECT_WRITE, &transaction); 208 self.setup_transaction(QspiMode::IndirectWrite, &transaction);
213 209
214 if let Some(len) = transaction.data_len { 210 if let Some(len) = transaction.data_len {
215 T::REGS.ccr().modify(|v| { 211 T::REGS.ccr().modify(|v| {
216 v.set_fmode(QspiMode::INDIRECT_WRITE); 212 v.set_fmode(QspiMode::IndirectWrite.into());
217 }); 213 });
218 214
219 for idx in 0..len { 215 for idx in 0..len {
@@ -227,18 +223,18 @@ impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> {
227 } 223 }
228 } 224 }
229 225
230 pub fn read_dma(&mut self, buf: &mut [u8], transaction: QspiTransaction) 226 pub fn blocking_read_dma(&mut self, buf: &mut [u8], transaction: TransferConfig)
231 where 227 where
232 Dma: QuadDma<T>, 228 Dma: QuadDma<T>,
233 { 229 {
234 unsafe { 230 unsafe {
235 self.setup_transaction(QspiMode::INDIRECT_WRITE, &transaction); 231 self.setup_transaction(QspiMode::IndirectWrite, &transaction);
236 232
237 let request = self.dma.request(); 233 let request = self.dma.request();
238 let options = TransferOptions::default(); 234 let options = TransferOptions::default();
239 235
240 T::REGS.ccr().modify(|v| { 236 T::REGS.ccr().modify(|v| {
241 v.set_fmode(QspiMode::INDIRECT_READ); 237 v.set_fmode(QspiMode::IndirectRead.into());
242 }); 238 });
243 let current_ar = T::REGS.ar().read().address(); 239 let current_ar = T::REGS.ar().read().address();
244 T::REGS.ar().write(|v| { 240 T::REGS.ar().write(|v| {
@@ -254,18 +250,18 @@ impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> {
254 } 250 }
255 } 251 }
256 252
257 pub fn write_dma(&mut self, buf: &[u8], transaction: QspiTransaction) 253 pub fn blocking_write_dma(&mut self, buf: &[u8], transaction: TransferConfig)
258 where 254 where
259 Dma: QuadDma<T>, 255 Dma: QuadDma<T>,
260 { 256 {
261 unsafe { 257 unsafe {
262 self.setup_transaction(QspiMode::INDIRECT_WRITE, &transaction); 258 self.setup_transaction(QspiMode::IndirectWrite, &transaction);
263 259
264 let request = self.dma.request(); 260 let request = self.dma.request();
265 let options = TransferOptions::default(); 261 let options = TransferOptions::default();
266 262
267 T::REGS.ccr().modify(|v| { 263 T::REGS.ccr().modify(|v| {
268 v.set_fmode(QspiMode::INDIRECT_WRITE); 264 v.set_fmode(QspiMode::IndirectWrite.into());
269 }); 265 });
270 266
271 self.dma 267 self.dma
@@ -277,7 +273,7 @@ impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> {
277 } 273 }
278 } 274 }
279 275
280 fn setup_transaction(&mut self, fmode: u8, transaction: &QspiTransaction) { 276 fn setup_transaction(&mut self, fmode: QspiMode, transaction: &TransferConfig) {
281 unsafe { 277 unsafe {
282 T::REGS.fcr().modify(|v| { 278 T::REGS.fcr().modify(|v| {
283 v.set_csmf(true); 279 v.set_csmf(true);
@@ -293,14 +289,14 @@ impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> {
293 } 289 }
294 290
295 T::REGS.ccr().write(|v| { 291 T::REGS.ccr().write(|v| {
296 v.set_fmode(fmode); 292 v.set_fmode(fmode.into());
297 v.set_imode(transaction.iwidth); 293 v.set_imode(transaction.iwidth.into());
298 v.set_instruction(transaction.instruction); 294 v.set_instruction(transaction.instruction);
299 v.set_admode(transaction.awidth); 295 v.set_admode(transaction.awidth.into());
300 v.set_adsize(self.config.address_size); 296 v.set_adsize(self.config.address_size.into());
301 v.set_dmode(transaction.dwidth); 297 v.set_dmode(transaction.dwidth.into());
302 v.set_abmode(QspiWidth::NONE); 298 v.set_abmode(QspiWidth::NONE.into());
303 v.set_dcyc(transaction.dummy); 299 v.set_dcyc(transaction.dummy.into());
304 }); 300 });
305 301
306 if let Some(addr) = transaction.address { 302 if let Some(addr) = transaction.address {