atsamd_hal/sercom/spi/
reg.rs
1use atsamd_hal_macros::{hal_cfg, hal_macro_helper};
2
3use crate::ehal;
4
5#[hal_cfg(any("sercom0-d11", "sercom0-d21"))]
6use crate::pac::sercom0::Spi;
7#[hal_cfg("sercom0-d5x")]
8use crate::pac::sercom0::Spim;
9
10#[hal_cfg(any("sercom0-d11", "sercom0-d21"))]
11use crate::pac::sercom0::spi::ctrla::Modeselect;
12#[hal_cfg("sercom0-d5x")]
13use crate::pac::sercom0::spim::ctrla::Modeselect;
14
15use crate::sercom::Sercom;
16use crate::time::Hertz;
17
18use super::{BitOrder, DataWidth, Error, Flags, Phase, Polarity, Status};
19
20pub(super) struct Registers<S: Sercom> {
31 pub sercom: S,
32}
33
34unsafe impl<S: Sercom> Sync for Registers<S> {}
37
38impl<S: Sercom> Registers<S> {
39 #[hal_cfg(any("sercom0-d11", "sercom0-d21"))]
40 #[inline]
41 pub fn spi(&self) -> &Spi {
42 self.sercom.spi()
43 }
44
45 #[hal_cfg("sercom0-d5x")]
46 #[inline]
47 pub fn spi(&self) -> &Spim {
48 self.sercom.spim()
49 }
50
51 #[inline]
53 pub fn reset(&mut self) {
54 self.spi().ctrla().write(|w| w.swrst().set_bit());
55 while self.spi().syncbusy().read().swrst().bit_is_set() {}
56 }
57
58 #[cfg(feature = "dma")]
59 pub fn data_ptr<Z: super::Size>(&self) -> *mut Z::Word {
61 self.spi().data().as_ptr() as *mut _
62 }
63
64 #[inline]
66 pub fn set_dipo_dopo(&mut self, dipo_dopo: (u8, u8)) {
67 let (dipo, dopo) = dipo_dopo;
68 self.spi().ctrla().modify(|_, w| unsafe {
69 w.dipo().bits(dipo);
70 w.dopo().bits(dopo)
71 });
72 }
73
74 #[inline]
81 #[hal_macro_helper]
82 pub fn set_op_mode(&mut self, mode: Modeselect, mssen: bool) {
83 self.spi().ctrla().modify(|_, w| w.mode().variant(mode));
84 self.spi().ctrlb().modify(|_, w| w.mssen().bit(mssen));
85 #[hal_cfg("sercom0-d5x")]
86 self.spi().ctrlc().write(|w| unsafe {
87 w.data32b().data_trans_32bit();
88 w.icspace().bits(1)
89 });
90 while self.spi().syncbusy().read().ctrlb().bit_is_set() {}
91 }
92
93 #[hal_cfg("sercom0-d5x")]
95 #[inline]
96 pub fn get_length(&self) -> u8 {
97 self.spi().length().read().len().bits()
98 }
99
100 #[hal_cfg("sercom0-d5x")]
102 #[inline]
103 pub fn set_length(&mut self, length: u8) {
104 let length = if length == 0 { 1 } else { length };
105 self.spi().length().write(|w| unsafe {
106 w.len().bits(length);
107 w.lenen().set_bit()
108 });
109 while self.spi().syncbusy().read().length().bit_is_set() {}
110 }
111
112 #[hal_cfg(any("sercom0-d11", "sercom0-d21"))]
114 #[inline]
115 pub fn set_char_size(&mut self, bits: u8) {
116 self.spi()
117 .ctrlb()
118 .modify(|_, w| unsafe { w.chsize().bits(bits) });
119 }
120
121 #[inline]
123 pub fn get_cpol(&self) -> Polarity {
124 let cpol = self.spi().ctrla().read().cpol().bit();
125 match cpol {
126 false => Polarity::IdleLow,
127 true => Polarity::IdleHigh,
128 }
129 }
130
131 #[inline]
133 pub fn set_cpol(&mut self, cpol: Polarity) {
134 let cpol = match cpol {
135 Polarity::IdleLow => false,
136 Polarity::IdleHigh => true,
137 };
138 self.spi().ctrla().modify(|_, w| w.cpol().bit(cpol));
139 }
140
141 #[inline]
143 pub fn get_cpha(&self) -> Phase {
144 let cpha = self.spi().ctrla().read().cpha().bit();
145 match cpha {
146 false => Phase::CaptureOnFirstTransition,
147 true => Phase::CaptureOnSecondTransition,
148 }
149 }
150
151 #[inline]
153 pub fn set_cpha(&mut self, cpha: Phase) {
154 let cpha = match cpha {
155 Phase::CaptureOnFirstTransition => false,
156 Phase::CaptureOnSecondTransition => true,
157 };
158 self.spi().ctrla().modify(|_, w| w.cpha().bit(cpha));
159 }
160
161 #[inline]
163 pub fn get_spi_mode(&self) -> ehal::spi::Mode {
164 let reg = self.spi().ctrla().read();
165 let cpol = reg.cpol().bit();
166 let cpha = reg.cpha().bit();
167 let polarity = match cpol {
168 false => Polarity::IdleLow,
169 true => Polarity::IdleHigh,
170 };
171 let phase = match cpha {
172 false => Phase::CaptureOnFirstTransition,
173 true => Phase::CaptureOnSecondTransition,
174 };
175 ehal::spi::Mode { polarity, phase }
176 }
177
178 #[inline]
180 pub fn set_spi_mode(&mut self, mode: ehal::spi::Mode) {
181 let cpol = match mode.polarity {
182 Polarity::IdleLow => false,
183 Polarity::IdleHigh => true,
184 };
185 let cpha = match mode.phase {
186 Phase::CaptureOnFirstTransition => false,
187 Phase::CaptureOnSecondTransition => true,
188 };
189 self.spi().ctrla().modify(|_, w| {
190 w.cpol().bit(cpol);
191 w.cpha().bit(cpha)
192 });
193 }
194
195 #[inline]
197 pub fn get_bit_order(&self) -> BitOrder {
198 let order = self.spi().ctrla().read().dord().bit();
199 match order {
200 false => BitOrder::MsbFirst,
201 true => BitOrder::LsbFirst,
202 }
203 }
204
205 #[inline]
207 pub fn set_bit_order(&mut self, order: BitOrder) {
208 let order = match order {
209 BitOrder::MsbFirst => false,
210 BitOrder::LsbFirst => true,
211 };
212 self.spi().ctrla().modify(|_, w| w.dord().bit(order));
213 }
214
215 #[inline]
217 pub fn get_baud(&mut self, freq: Hertz) -> Hertz {
218 let baud = self.spi().baud().read().baud().bits() as u32 + 1;
219 freq / 2 / baud
220 }
221
222 #[inline]
224 pub fn set_baud(&mut self, freq: Hertz, baud: Hertz) {
225 let baud = baud.to_Hz().max(1);
226 let bits = (freq.to_Hz() / 2 / baud).saturating_sub(1);
227 let bits = bits.try_into().unwrap_or(u8::MAX);
228 self.spi()
229 .baud()
230 .modify(|_, w| unsafe { w.baud().bits(bits) });
231 }
232
233 #[inline]
235 pub fn get_ibon(&self) -> bool {
236 self.spi().ctrla().read().ibon().bit()
237 }
238
239 #[inline]
241 pub fn set_ibon(&mut self, enabled: bool) {
242 self.spi().ctrla().modify(|_, w| w.ibon().bit(enabled));
243 }
244
245 #[inline]
247 pub fn get_run_in_standby(&self) -> bool {
248 self.spi().ctrla().read().runstdby().bit()
249 }
250
251 #[inline]
253 pub fn set_run_in_standby(&mut self, set: bool) {
254 self.spi().ctrla().modify(|_, w| w.runstdby().bit(set));
255 }
256
257 #[inline]
259 pub fn enable_interrupts(&mut self, flags: Flags) {
260 self.spi()
261 .intenset()
262 .write(|w| unsafe { w.bits(flags.bits()) });
263 }
264
265 #[inline]
267 pub fn disable_interrupts(&mut self, flags: Flags) {
268 self.spi()
269 .intenclr()
270 .write(|w| unsafe { w.bits(flags.bits()) });
271 }
272
273 #[inline]
275 pub fn rx_enable(&mut self) {
276 self.spi().ctrlb().modify(|_, w| w.rxen().set_bit());
277 while self.spi().syncbusy().read().ctrlb().bit_is_set() {}
278 }
279
280 #[inline]
282 pub fn rx_disable(&mut self) {
283 self.spi().ctrlb().modify(|_, w| w.rxen().clear_bit());
284 while self.spi().syncbusy().read().ctrlb().bit_is_set() {}
285 }
286
287 #[inline]
289 pub fn enable(&mut self) {
290 self.spi().ctrla().modify(|_, w| w.enable().set_bit());
291 while self.spi().syncbusy().read().enable().bit_is_set() {}
292 }
293
294 #[inline]
296 pub fn disable(&mut self) {
297 self.spi().ctrla().modify(|_, w| w.enable().clear_bit());
298 while self.spi().syncbusy().read().enable().bit_is_set() {}
299 }
300
301 #[inline]
303 pub fn read_data(&mut self) -> DataWidth {
304 self.spi().data().read().data().bits()
305 }
306
307 #[inline]
309 pub fn write_data(&mut self, data: DataWidth) {
310 self.spi().data().write(|w| unsafe { w.data().bits(data) })
312 }
313
314 #[inline]
316 pub fn read_flags(&self) -> Flags {
317 let bits = self.spi().intflag().read().bits();
318 Flags::from_bits_truncate(bits)
319 }
320
321 #[inline]
323 pub fn clear_flags(&mut self, flags: Flags) {
324 unsafe { self.spi().intflag().write(|w| w.bits(flags.bits())) };
325 }
326
327 #[inline]
329 pub fn read_status(&self) -> Status {
330 let bits = self.spi().status().read().bits();
331 Status::from_bits_truncate(bits)
332 }
333
334 #[inline]
336 pub fn clear_status(&mut self, status: Status) {
337 unsafe { self.spi().status().write(|w| w.bits(status.bits())) };
338 }
339
340 #[inline]
342 pub fn read_flags_errors(&self) -> Result<Flags, Error> {
343 self.read_status().check_bus_error()?;
344 Ok(self.read_flags())
345 }
346}