stm32_rust_template/mcu/stm32f407/
spi.rs1use super::{PeripheralAccess, SPI1_BASEADDR, SPI2_BASEADDR, SPI3_BASEADDR};
5
6#[repr(C)]
8pub struct RegisterBlock {
9 pub cr1: u32, pub cr2: u32, pub sr: u32, pub dr: u32, pub crcpr: u32, pub rxcrcr: u32, pub txcrcr: u32, pub i2scfgr: u32, pub i2spr: u32, }
19
20pub struct SPI1;
22pub struct SPI2;
23pub struct SPI3;
24
25impl PeripheralAccess for SPI1 {
26 const BASE_ADDRESS: u32 = SPI1_BASEADDR;
27 type RegisterBlock = RegisterBlock;
28}
29
30impl PeripheralAccess for SPI2 {
31 const BASE_ADDRESS: u32 = SPI2_BASEADDR;
32 type RegisterBlock = RegisterBlock;
33}
34
35impl PeripheralAccess for SPI3 {
36 const BASE_ADDRESS: u32 = SPI3_BASEADDR;
37 type RegisterBlock = RegisterBlock;
38}
39
40pub const CR1_BIDIMODE_POS: u32 = 15;
44pub const CR1_BIDIMODE_WIDTH: u32 = 1;
45pub const CR1_BIDIMODE_MASK: u32 = 0x1 << 15;
46pub const CR1_BIDIMODE_UNIDIRECTIONAL: u32 = 0 << 15;
48pub const CR1_BIDIMODE_BIDIRECTIONAL: u32 = 1 << 15;
49
50pub const CR1_BIDIOE_POS: u32 = 14;
51pub const CR1_BIDIOE_WIDTH: u32 = 1;
52pub const CR1_BIDIOE_MASK: u32 = 0x1 << 14;
53pub const CR1_BIDIOE_OUTPUTDISABLED: u32 = 0 << 14;
55pub const CR1_BIDIOE_OUTPUTENABLED: u32 = 1 << 14;
56
57pub const CR1_CRCEN_POS: u32 = 13;
58pub const CR1_CRCEN_WIDTH: u32 = 1;
59pub const CR1_CRCEN_MASK: u32 = 0x1 << 13;
60pub const CR1_CRCEN_DISABLED: u32 = 0 << 13;
62pub const CR1_CRCEN_ENABLED: u32 = 1 << 13;
63
64pub const CR1_CRCNEXT_POS: u32 = 12;
65pub const CR1_CRCNEXT_WIDTH: u32 = 1;
66pub const CR1_CRCNEXT_MASK: u32 = 0x1 << 12;
67pub const CR1_CRCNEXT_TXBUFFER: u32 = 0 << 12;
69pub const CR1_CRCNEXT_CRC: u32 = 1 << 12;
70
71pub const CR1_DFF_POS: u32 = 11;
72pub const CR1_DFF_WIDTH: u32 = 1;
73pub const CR1_DFF_MASK: u32 = 0x1 << 11;
74pub const CR1_DFF_EIGHTBIT: u32 = 0 << 11;
76pub const CR1_DFF_SIXTEENBIT: u32 = 1 << 11;
77
78pub const CR1_RXONLY_POS: u32 = 10;
79pub const CR1_RXONLY_WIDTH: u32 = 1;
80pub const CR1_RXONLY_MASK: u32 = 0x1 << 10;
81pub const CR1_RXONLY_FULLDUPLEX: u32 = 0 << 10;
83pub const CR1_RXONLY_OUTPUTDISABLED: u32 = 1 << 10;
84
85pub const CR1_SSM_POS: u32 = 9;
86pub const CR1_SSM_WIDTH: u32 = 1;
87pub const CR1_SSM_MASK: u32 = 0x1 << 9;
88pub const CR1_SSM_DISABLED: u32 = 0 << 9;
90pub const CR1_SSM_ENABLED: u32 = 1 << 9;
91
92pub const CR1_SSI_POS: u32 = 8;
93pub const CR1_SSI_WIDTH: u32 = 1;
94pub const CR1_SSI_MASK: u32 = 0x1 << 8;
95pub const CR1_SSI_SLAVESELECTED: u32 = 0 << 8;
97pub const CR1_SSI_SLAVENOTSELECTED: u32 = 1 << 8;
98
99pub const CR1_LSBFIRST_POS: u32 = 7;
100pub const CR1_LSBFIRST_WIDTH: u32 = 1;
101pub const CR1_LSBFIRST_MASK: u32 = 0x1 << 7;
102pub const CR1_LSBFIRST_MSBFIRST: u32 = 0 << 7;
104pub const CR1_LSBFIRST_LSBFIRST: u32 = 1 << 7;
105
106pub const CR1_SPE_POS: u32 = 6;
107pub const CR1_SPE_WIDTH: u32 = 1;
108pub const CR1_SPE_MASK: u32 = 0x1 << 6;
109pub const CR1_SPE_DISABLED: u32 = 0 << 6;
111pub const CR1_SPE_ENABLED: u32 = 1 << 6;
112
113pub const CR1_BR_POS: u32 = 3;
114pub const CR1_BR_WIDTH: u32 = 3;
115pub const CR1_BR_MASK: u32 = 0x7 << 3;
116pub const CR1_BR_DIV2: u32 = 0 << 3;
118pub const CR1_BR_DIV4: u32 = 1 << 3;
119pub const CR1_BR_DIV8: u32 = 2 << 3;
120pub const CR1_BR_DIV16: u32 = 3 << 3;
121pub const CR1_BR_DIV32: u32 = 4 << 3;
122pub const CR1_BR_DIV64: u32 = 5 << 3;
123pub const CR1_BR_DIV128: u32 = 6 << 3;
124pub const CR1_BR_DIV256: u32 = 7 << 3;
125
126pub const CR1_MSTR_POS: u32 = 2;
127pub const CR1_MSTR_WIDTH: u32 = 1;
128pub const CR1_MSTR_MASK: u32 = 0x1 << 2;
129pub const CR1_MSTR_SLAVE: u32 = 0 << 2;
131pub const CR1_MSTR_MASTER: u32 = 1 << 2;
132
133pub const CR1_CPOL_POS: u32 = 1;
134pub const CR1_CPOL_WIDTH: u32 = 1;
135pub const CR1_CPOL_MASK: u32 = 0x1 << 1;
136pub const CR1_CPOL_IDLELOW: u32 = 0 << 1;
138pub const CR1_CPOL_IDLEHIGH: u32 = 1 << 1;
139
140pub const CR1_CPHA_POS: u32 = 0;
141pub const CR1_CPHA_WIDTH: u32 = 1;
142pub const CR1_CPHA_MASK: u32 = 0x1 << 0;
143pub const CR1_CPHA_FIRSTEDGE: u32 = 0 << 0;
145pub const CR1_CPHA_SECONDEDGE: u32 = 1 << 0;
146
147pub const CR2_TXEIE_POS: u32 = 7;
149pub const CR2_TXEIE_WIDTH: u32 = 1;
150pub const CR2_TXEIE_MASK: u32 = 0x1 << 7;
151pub const CR2_TXEIE_MASKED: u32 = 0 << 7;
153pub const CR2_TXEIE_NOTMASKED: u32 = 1 << 7;
154
155pub const CR2_RXNEIE_POS: u32 = 6;
156pub const CR2_RXNEIE_WIDTH: u32 = 1;
157pub const CR2_RXNEIE_MASK: u32 = 0x1 << 6;
158pub const CR2_RXNEIE_MASKED: u32 = 0 << 6;
160pub const CR2_RXNEIE_NOTMASKED: u32 = 1 << 6;
161
162pub const CR2_ERRIE_POS: u32 = 5;
163pub const CR2_ERRIE_WIDTH: u32 = 1;
164pub const CR2_ERRIE_MASK: u32 = 0x1 << 5;
165pub const CR2_ERRIE_MASKED: u32 = 0 << 5;
167pub const CR2_ERRIE_NOTMASKED: u32 = 1 << 5;
168
169pub const CR2_FRF_POS: u32 = 4;
170pub const CR2_FRF_WIDTH: u32 = 1;
171pub const CR2_FRF_MASK: u32 = 0x1 << 4;
172pub const CR2_FRF_MOTOROLA: u32 = 0 << 4;
174pub const CR2_FRF_TI: u32 = 1 << 4;
175
176pub const CR2_SSOE_POS: u32 = 2;
177pub const CR2_SSOE_WIDTH: u32 = 1;
178pub const CR2_SSOE_MASK: u32 = 0x1 << 2;
179pub const CR2_SSOE_DISABLED: u32 = 0 << 2;
181pub const CR2_SSOE_ENABLED: u32 = 1 << 2;
182
183pub const CR2_TXDMAEN_POS: u32 = 1;
184pub const CR2_TXDMAEN_WIDTH: u32 = 1;
185pub const CR2_TXDMAEN_MASK: u32 = 0x1 << 1;
186pub const CR2_TXDMAEN_DISABLED: u32 = 0 << 1;
188pub const CR2_TXDMAEN_ENABLED: u32 = 1 << 1;
189
190pub const CR2_RXDMAEN_POS: u32 = 0;
191pub const CR2_RXDMAEN_WIDTH: u32 = 1;
192pub const CR2_RXDMAEN_MASK: u32 = 0x1 << 0;
193pub const CR2_RXDMAEN_DISABLED: u32 = 0 << 0;
195pub const CR2_RXDMAEN_ENABLED: u32 = 1 << 0;
196
197pub const SR_FRE_POS: u32 = 8;
199pub const SR_FRE_WIDTH: u32 = 1;
200pub const SR_FRE_MASK: u32 = 0x1 << 8;
201pub const SR_FRE_NOERROR: u32 = 0 << 8;
203pub const SR_FRE_ERROR: u32 = 1 << 8;
204
205pub const SR_BSY_POS: u32 = 7;
206pub const SR_BSY_WIDTH: u32 = 1;
207pub const SR_BSY_MASK: u32 = 0x1 << 7;
208pub const SR_BSY_NOTBUSY: u32 = 0 << 7;
210pub const SR_BSY_BUSY: u32 = 1 << 7;
211
212pub const SR_OVR_POS: u32 = 6;
213pub const SR_OVR_WIDTH: u32 = 1;
214pub const SR_OVR_MASK: u32 = 0x1 << 6;
215pub const SR_OVR_NOOVERRUN: u32 = 0 << 6;
217pub const SR_OVR_OVERRUN: u32 = 1 << 6;
218
219pub const SR_MODF_POS: u32 = 5;
220pub const SR_MODF_WIDTH: u32 = 1;
221pub const SR_MODF_MASK: u32 = 0x1 << 5;
222pub const SR_MODF_NOFAULT: u32 = 0 << 5;
224pub const SR_MODF_FAULT: u32 = 1 << 5;
225
226pub const SR_CRCERR_POS: u32 = 4;
227pub const SR_CRCERR_WIDTH: u32 = 1;
228pub const SR_CRCERR_MASK: u32 = 0x1 << 4;
229pub const SR_CRCERR_MATCH: u32 = 0 << 4;
231pub const SR_CRCERR_NOMATCH: u32 = 1 << 4;
232
233pub const SR_UDR_POS: u32 = 3;
234pub const SR_UDR_WIDTH: u32 = 1;
235pub const SR_UDR_MASK: u32 = 0x1 << 3;
236pub const SR_UDR_NOUNDERRUN: u32 = 0 << 3;
238pub const SR_UDR_UNDERRUN: u32 = 1 << 3;
239
240pub const SR_CHSIDE_POS: u32 = 2;
241pub const SR_CHSIDE_WIDTH: u32 = 1;
242pub const SR_CHSIDE_MASK: u32 = 0x1 << 2;
243pub const SR_CHSIDE_LEFT: u32 = 0 << 2;
245pub const SR_CHSIDE_RIGHT: u32 = 1 << 2;
246
247pub const SR_TXE_POS: u32 = 1;
248pub const SR_TXE_WIDTH: u32 = 1;
249pub const SR_TXE_MASK: u32 = 0x1 << 1;
250pub const SR_TXE_NOTEMPTY: u32 = 0 << 1;
252pub const SR_TXE_EMPTY: u32 = 1 << 1;
253
254pub const SR_RXNE_POS: u32 = 0;
255pub const SR_RXNE_WIDTH: u32 = 1;
256pub const SR_RXNE_MASK: u32 = 0x1 << 0;
257pub const SR_RXNE_EMPTY: u32 = 0 << 0;
259pub const SR_RXNE_NOTEMPTY: u32 = 1 << 0;
260
261pub const DR_DR_POS: u32 = 0;
263pub const DR_DR_WIDTH: u32 = 16;
264pub const DR_DR_MASK: u32 = 0xFFFF << 0;
265
266pub const CRCPR_CRCPOLY_POS: u32 = 0;
268pub const CRCPR_CRCPOLY_WIDTH: u32 = 16;
269pub const CRCPR_CRCPOLY_MASK: u32 = 0xFFFF << 0;
270
271pub const RXCRCR_RXCRC_POS: u32 = 0;
273pub const RXCRCR_RXCRC_WIDTH: u32 = 16;
274pub const RXCRCR_RXCRC_MASK: u32 = 0xFFFF << 0;
275
276pub const TXCRCR_TXCRC_POS: u32 = 0;
278pub const TXCRCR_TXCRC_WIDTH: u32 = 16;
279pub const TXCRCR_TXCRC_MASK: u32 = 0xFFFF << 0;
280
281pub const I2SCFGR_I2SMOD_POS: u32 = 11;
283pub const I2SCFGR_I2SMOD_WIDTH: u32 = 1;
284pub const I2SCFGR_I2SMOD_MASK: u32 = 0x1 << 11;
285pub const I2SCFGR_I2SMOD_SPIMODE: u32 = 0 << 11;
287pub const I2SCFGR_I2SMOD_I2SMODE: u32 = 1 << 11;
288
289pub const I2SCFGR_I2SE_POS: u32 = 10;
290pub const I2SCFGR_I2SE_WIDTH: u32 = 1;
291pub const I2SCFGR_I2SE_MASK: u32 = 0x1 << 10;
292pub const I2SCFGR_I2SE_DISABLED: u32 = 0 << 10;
294pub const I2SCFGR_I2SE_ENABLED: u32 = 1 << 10;
295
296pub const I2SCFGR_I2SCFG_POS: u32 = 8;
297pub const I2SCFGR_I2SCFG_WIDTH: u32 = 2;
298pub const I2SCFGR_I2SCFG_MASK: u32 = 0x3 << 8;
299pub const I2SCFGR_I2SCFG_SLAVETX: u32 = 0 << 8;
301pub const I2SCFGR_I2SCFG_SLAVERX: u32 = 1 << 8;
302pub const I2SCFGR_I2SCFG_MASTERTX: u32 = 2 << 8;
303pub const I2SCFGR_I2SCFG_MASTERRX: u32 = 3 << 8;
304
305pub const I2SCFGR_PCMSYNC_POS: u32 = 7;
306pub const I2SCFGR_PCMSYNC_WIDTH: u32 = 1;
307pub const I2SCFGR_PCMSYNC_MASK: u32 = 0x1 << 7;
308pub const I2SCFGR_PCMSYNC_SHORT: u32 = 0 << 7;
310pub const I2SCFGR_PCMSYNC_LONG: u32 = 1 << 7;
311
312pub const I2SCFGR_I2SSTD_POS: u32 = 4;
313pub const I2SCFGR_I2SSTD_WIDTH: u32 = 2;
314pub const I2SCFGR_I2SSTD_MASK: u32 = 0x3 << 4;
315pub const I2SCFGR_I2SSTD_PHILIPS: u32 = 0 << 4;
317pub const I2SCFGR_I2SSTD_MSB: u32 = 1 << 4;
318pub const I2SCFGR_I2SSTD_LSB: u32 = 2 << 4;
319pub const I2SCFGR_I2SSTD_PCM: u32 = 3 << 4;
320
321pub const I2SCFGR_CKPOL_POS: u32 = 3;
322pub const I2SCFGR_CKPOL_WIDTH: u32 = 1;
323pub const I2SCFGR_CKPOL_MASK: u32 = 0x1 << 3;
324pub const I2SCFGR_CKPOL_IDLELOW: u32 = 0 << 3;
326pub const I2SCFGR_CKPOL_IDLEHIGH: u32 = 1 << 3;
327
328pub const I2SCFGR_DATLEN_POS: u32 = 1;
329pub const I2SCFGR_DATLEN_WIDTH: u32 = 2;
330pub const I2SCFGR_DATLEN_MASK: u32 = 0x3 << 1;
331pub const I2SCFGR_DATLEN_SIXTEENBIT: u32 = 0 << 1;
333pub const I2SCFGR_DATLEN_TWENTYFOURBIT: u32 = 1 << 1;
334pub const I2SCFGR_DATLEN_THIRTYTWOBIT: u32 = 2 << 1;
335
336pub const I2SCFGR_CHLEN_POS: u32 = 0;
337pub const I2SCFGR_CHLEN_WIDTH: u32 = 1;
338pub const I2SCFGR_CHLEN_MASK: u32 = 0x1 << 0;
339pub const I2SCFGR_CHLEN_SIXTEENBIT: u32 = 0 << 0;
341pub const I2SCFGR_CHLEN_THIRTYTWOBIT: u32 = 1 << 0;
342
343pub const I2SPR_MCKOE_POS: u32 = 9;
345pub const I2SPR_MCKOE_WIDTH: u32 = 1;
346pub const I2SPR_MCKOE_MASK: u32 = 0x1 << 9;
347pub const I2SPR_MCKOE_DISABLED: u32 = 0 << 9;
349pub const I2SPR_MCKOE_ENABLED: u32 = 1 << 9;
350
351pub const I2SPR_ODD_POS: u32 = 8;
352pub const I2SPR_ODD_WIDTH: u32 = 1;
353pub const I2SPR_ODD_MASK: u32 = 0x1 << 8;
354pub const I2SPR_ODD_EVEN: u32 = 0 << 8;
356pub const I2SPR_ODD_ODD: u32 = 1 << 8;
357
358pub const I2SPR_I2SDIV_POS: u32 = 0;
359pub const I2SPR_I2SDIV_WIDTH: u32 = 8;
360pub const I2SPR_I2SDIV_MASK: u32 = 0xFF << 0;
361
362#[derive(Copy, Clone, Debug, PartialEq)]
364pub enum SpiMode {
365 Mode0 = 0, Mode1 = 1, Mode2 = 2, Mode3 = 3, }
370
371#[derive(Copy, Clone, Debug, PartialEq)]
373pub enum SpiBaudRate {
374 Div2 = 0,
375 Div4 = 1,
376 Div8 = 2,
377 Div16 = 3,
378 Div32 = 4,
379 Div64 = 5,
380 Div128 = 6,
381 Div256 = 7,
382}
383
384impl RegisterBlock {
386 pub fn enable(&mut self) {
388 self.cr1 |= CR1_SPE_MASK;
389 }
390
391 pub fn disable(&mut self) {
393 self.cr1 &= !CR1_SPE_MASK;
394 }
395
396 pub fn set_mode(&mut self, mode: SpiMode) {
398 self.cr1 =
399 (self.cr1 & !(CR1_CPOL_MASK | CR1_CPHA_MASK)) | (((mode as u32) & 0x3) << CR1_CPHA_POS);
400 }
401
402 pub fn set_master(&mut self) {
404 self.cr1 |= CR1_MSTR_MASK;
405 }
406
407 pub fn set_slave(&mut self) {
409 self.cr1 &= !CR1_MSTR_MASK;
410 }
411
412 pub fn set_baud_rate(&mut self, baudrate: SpiBaudRate) {
414 self.cr1 = (self.cr1 & !CR1_BR_MASK) | ((baudrate as u32) << CR1_BR_POS);
415 }
416
417 pub fn is_tx_empty(&self) -> bool {
419 (self.sr & SR_TXE_MASK) != 0
420 }
421
422 pub fn is_rx_not_empty(&self) -> bool {
424 (self.sr & SR_RXNE_MASK) != 0
425 }
426
427 pub fn is_busy(&self) -> bool {
429 (self.sr & SR_BSY_MASK) != 0
430 }
431
432 pub fn write_data(&mut self, data: u16) {
434 self.dr = data as u32;
435 }
436
437 pub fn read_data(&self) -> u16 {
439 self.dr as u16
440 }
441
442 pub fn transfer_byte(&mut self, data: u8) -> u8 {
444 while !self.is_tx_empty() {}
446
447 self.write_data(data as u16);
449
450 while !self.is_rx_not_empty() {}
452
453 self.read_data() as u8
455 }
456}