atsamd_hal/sercom/spi/
reg.rs1use 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 #[inline]
60 pub fn set_dipo_dopo(&mut self, dipo_dopo: (u8, u8)) {
61 let (dipo, dopo) = dipo_dopo;
62 self.spi().ctrla().modify(|_, w| unsafe {
63 w.dipo().bits(dipo);
64 w.dopo().bits(dopo)
65 });
66 }
67
68 #[inline]
75 #[hal_macro_helper]
76 pub fn set_op_mode(&mut self, mode: Modeselect, mssen: bool) {
77 self.spi().ctrla().modify(|_, w| w.mode().variant(mode));
78 self.spi().ctrlb().modify(|_, w| w.mssen().bit(mssen));
79 #[hal_cfg("sercom0-d5x")]
80 self.spi().ctrlc().write(|w| unsafe {
81 w.data32b().data_trans_32bit();
82 w.icspace().bits(1)
83 });
84 while self.spi().syncbusy().read().ctrlb().bit_is_set() {}
85 }
86
87 #[hal_cfg("sercom0-d5x")]
89 #[inline]
90 pub fn get_length(&self) -> u8 {
91 self.spi().length().read().len().bits()
92 }
93
94 #[hal_cfg("sercom0-d5x")]
96 #[inline]
97 pub fn set_length(&mut self, length: u8) {
98 let length = if length == 0 { 1 } else { length };
99 self.spi().length().write(|w| unsafe {
100 w.len().bits(length);
101 w.lenen().set_bit()
102 });
103 while self.spi().syncbusy().read().length().bit_is_set() {}
104 }
105
106 #[hal_cfg(any("sercom0-d11", "sercom0-d21"))]
108 #[inline]
109 pub fn set_char_size(&mut self, bits: u8) {
110 self.spi()
111 .ctrlb()
112 .modify(|_, w| unsafe { w.chsize().bits(bits) });
113 }
114
115 #[inline]
117 pub fn get_cpol(&self) -> Polarity {
118 let cpol = self.spi().ctrla().read().cpol().bit();
119 match cpol {
120 false => Polarity::IdleLow,
121 true => Polarity::IdleHigh,
122 }
123 }
124
125 #[inline]
127 pub fn set_cpol(&mut self, cpol: Polarity) {
128 let cpol = match cpol {
129 Polarity::IdleLow => false,
130 Polarity::IdleHigh => true,
131 };
132 self.spi().ctrla().modify(|_, w| w.cpol().bit(cpol));
133 }
134
135 #[inline]
137 pub fn get_cpha(&self) -> Phase {
138 let cpha = self.spi().ctrla().read().cpha().bit();
139 match cpha {
140 false => Phase::CaptureOnFirstTransition,
141 true => Phase::CaptureOnSecondTransition,
142 }
143 }
144
145 #[inline]
147 pub fn set_cpha(&mut self, cpha: Phase) {
148 let cpha = match cpha {
149 Phase::CaptureOnFirstTransition => false,
150 Phase::CaptureOnSecondTransition => true,
151 };
152 self.spi().ctrla().modify(|_, w| w.cpha().bit(cpha));
153 }
154
155 #[inline]
157 pub fn get_spi_mode(&self) -> ehal::spi::Mode {
158 let reg = self.spi().ctrla().read();
159 let cpol = reg.cpol().bit();
160 let cpha = reg.cpha().bit();
161 let polarity = match cpol {
162 false => Polarity::IdleLow,
163 true => Polarity::IdleHigh,
164 };
165 let phase = match cpha {
166 false => Phase::CaptureOnFirstTransition,
167 true => Phase::CaptureOnSecondTransition,
168 };
169 ehal::spi::Mode { polarity, phase }
170 }
171
172 #[inline]
174 pub fn set_spi_mode(&mut self, mode: ehal::spi::Mode) {
175 let cpol = match mode.polarity {
176 Polarity::IdleLow => false,
177 Polarity::IdleHigh => true,
178 };
179 let cpha = match mode.phase {
180 Phase::CaptureOnFirstTransition => false,
181 Phase::CaptureOnSecondTransition => true,
182 };
183 self.spi().ctrla().modify(|_, w| {
184 w.cpol().bit(cpol);
185 w.cpha().bit(cpha)
186 });
187 }
188
189 #[inline]
191 pub fn get_bit_order(&self) -> BitOrder {
192 let order = self.spi().ctrla().read().dord().bit();
193 match order {
194 false => BitOrder::MsbFirst,
195 true => BitOrder::LsbFirst,
196 }
197 }
198
199 #[inline]
201 pub fn set_bit_order(&mut self, order: BitOrder) {
202 let order = match order {
203 BitOrder::MsbFirst => false,
204 BitOrder::LsbFirst => true,
205 };
206 self.spi().ctrla().modify(|_, w| w.dord().bit(order));
207 }
208
209 #[inline]
211 pub fn get_baud(&mut self, freq: Hertz) -> Hertz {
212 let baud = self.spi().baud().read().baud().bits() as u32 + 1;
213 freq / 2 / baud
214 }
215
216 #[inline]
218 pub fn set_baud(&mut self, freq: Hertz, baud: Hertz) {
219 let baud = baud.to_Hz().max(1);
220 let bits = (freq.to_Hz() / 2 / baud).saturating_sub(1);
221 let bits = bits.try_into().unwrap_or(u8::MAX);
222 self.spi()
223 .baud()
224 .modify(|_, w| unsafe { w.baud().bits(bits) });
225 }
226
227 #[inline]
229 pub fn get_ibon(&self) -> bool {
230 self.spi().ctrla().read().ibon().bit()
231 }
232
233 #[inline]
235 pub fn set_ibon(&mut self, enabled: bool) {
236 self.spi().ctrla().modify(|_, w| w.ibon().bit(enabled));
237 }
238
239 #[inline]
241 pub fn get_run_in_standby(&self) -> bool {
242 self.spi().ctrla().read().runstdby().bit()
243 }
244
245 #[inline]
247 pub fn set_run_in_standby(&mut self, set: bool) {
248 self.spi().ctrla().modify(|_, w| w.runstdby().bit(set));
249 }
250
251 #[inline]
253 pub fn enable_interrupts(&mut self, flags: Flags) {
254 self.spi()
255 .intenset()
256 .write(|w| unsafe { w.bits(flags.bits()) });
257 }
258
259 #[inline]
261 pub fn disable_interrupts(&mut self, flags: Flags) {
262 self.spi()
263 .intenclr()
264 .write(|w| unsafe { w.bits(flags.bits()) });
265 }
266
267 #[inline]
269 pub fn rx_enable(&mut self) {
270 self.spi().ctrlb().modify(|_, w| w.rxen().set_bit());
271 while self.spi().syncbusy().read().ctrlb().bit_is_set() {}
272 }
273
274 #[inline]
276 pub fn rx_disable(&mut self) {
277 self.spi().ctrlb().modify(|_, w| w.rxen().clear_bit());
278 while self.spi().syncbusy().read().ctrlb().bit_is_set() {}
279 }
280
281 #[inline]
283 pub fn enable(&mut self) {
284 self.spi().ctrla().modify(|_, w| w.enable().set_bit());
285 while self.spi().syncbusy().read().enable().bit_is_set() {}
286 }
287
288 #[inline]
290 pub fn disable(&mut self) {
291 self.spi().ctrla().modify(|_, w| w.enable().clear_bit());
292 while self.spi().syncbusy().read().enable().bit_is_set() {}
293 }
294
295 #[inline]
297 pub fn read_data(&mut self) -> DataWidth {
298 self.spi().data().read().data().bits()
299 }
300
301 #[inline]
303 pub fn write_data(&mut self, data: DataWidth) {
304 self.spi().data().write(|w| unsafe { w.data().bits(data) })
306 }
307
308 #[inline]
310 pub fn read_flags(&self) -> Flags {
311 let bits = self.spi().intflag().read().bits();
312 Flags::from_bits_truncate(bits)
313 }
314
315 #[inline]
317 pub fn clear_flags(&mut self, flags: Flags) {
318 unsafe { self.spi().intflag().write(|w| w.bits(flags.bits())) };
319 }
320
321 #[inline]
323 pub fn read_status(&self) -> Status {
324 let bits = self.spi().status().read().bits();
325 Status::from_bits_truncate(bits)
326 }
327
328 #[inline]
330 pub fn clear_status(&mut self, status: Status) {
331 unsafe { self.spi().status().write(|w| w.bits(status.bits())) };
332 }
333
334 #[inline]
336 pub fn read_flags_errors(&self) -> Result<Flags, Error> {
337 self.read_status().check_bus_error()?;
338 Ok(self.read_flags())
339 }
340}