1use core::cell::Cell;
8use kernel::hil;
9use kernel::hil::gpio::Configure;
10use kernel::hil::i2c;
11use kernel::hil::spi::cs::ChipSelectPolar;
12use kernel::hil::spi::{ClockPhase, ClockPolarity, SpiMaster, SpiMasterClient};
13use kernel::utilities::cells::{MapCell, OptionalCell};
14use kernel::utilities::leasable_buffer::SubSliceMut;
15use kernel::utilities::registers::interfaces::{ReadWriteable, Readable, Writeable};
16use kernel::utilities::registers::{register_bitfields, register_structs, ReadOnly, ReadWrite};
17use kernel::utilities::StaticRef;
18use kernel::ErrorCode;
19
20const IOM0_BASE: StaticRef<IomRegisters> =
21 unsafe { StaticRef::new(0x5000_4000 as *const IomRegisters) };
22const IOM1_BASE: StaticRef<IomRegisters> =
23 unsafe { StaticRef::new(0x5000_5000 as *const IomRegisters) };
24const IOM2_BASE: StaticRef<IomRegisters> =
25 unsafe { StaticRef::new(0x5000_6000 as *const IomRegisters) };
26const IOM3_BASE: StaticRef<IomRegisters> =
27 unsafe { StaticRef::new(0x5000_7000 as *const IomRegisters) };
28const IOM4_BASE: StaticRef<IomRegisters> =
29 unsafe { StaticRef::new(0x5000_8000 as *const IomRegisters) };
30const IOM5_BASE: StaticRef<IomRegisters> =
31 unsafe { StaticRef::new(0x5000_9000 as *const IomRegisters) };
32
33register_structs! {
34 pub IomRegisters {
35 (0x000 => fifo: ReadWrite<u32, FIFO::Register>),
36 (0x004 => _reserved0),
37 (0x100 => fifoptr: ReadWrite<u32, FIFOPTR::Register>),
38 (0x104 => fifothr: ReadWrite<u32, FIFOTHR::Register>),
39 (0x108 => fifopop: ReadWrite<u32, FIFOPOP::Register>),
40 (0x10C => fifopush: ReadWrite<u32, FIFOPUSH::Register>),
41 (0x110 => fifoctrl: ReadWrite<u32, FIFOCTRL::Register>),
42 (0x114 => fifoloc: ReadWrite<u32, FIFOLOC::Register>),
43 (0x118 => _reserved1),
44 (0x200 => inten: ReadWrite<u32, INT::Register>),
45 (0x204 => intstat: ReadWrite<u32, INT::Register>),
46 (0x208 => intclr: ReadWrite<u32, INT::Register>),
47 (0x20C => intset: ReadWrite<u32, INT::Register>),
48 (0x210 => clkcfg: ReadWrite<u32, CLKCFG::Register>),
49 (0x214 => submodctrl: ReadWrite<u32, SUBMODCTRL::Register>),
50 (0x218 => cmd: ReadWrite<u32, CMD::Register>),
51 (0x21C => dcx: ReadWrite<u32, DCX::Register>),
52 (0x220 => offsethi: ReadWrite<u32, OFFSETHI::Register>),
53 (0x224 => cmdstat: ReadOnly<u32, CMDSTAT::Register>),
54 (0x228 => _reserved2),
55 (0x240 => dmatrigen: ReadWrite<u32, DMATRIGEN::Register>),
56 (0x244 => dmatrigstat: ReadWrite<u32, DMATRIGSTAT::Register>),
57 (0x248 => _reserved3),
58 (0x280 => dmacfg: ReadWrite<u32, DMACFG::Register>),
59 (0x284 => _reserved4),
60 (0x288 => dmatotcount: ReadWrite<u32, DMATOTCOUNT::Register>),
61 (0x28C => dmatargaddr: ReadWrite<u32, DMATARGADDR::Register>),
62 (0x290 => dmastat: ReadWrite<u32, DMASTAT::Register>),
63 (0x294 => cqcfg: ReadWrite<u32, CQCFG::Register>),
64 (0x298 => cqaddr: ReadWrite<u32, CQADDR::Register>),
65 (0x29C => cqstat: ReadWrite<u32, CQSTAT::Register>),
66 (0x2A0 => cqflags: ReadWrite<u32, CQFLAGS::Register>),
67 (0x2A4 => cqsetclear: ReadWrite<u32, CQSETCLEAR::Register>),
68 (0x2A8 => cqpauseen: ReadWrite<u32, CQPAUSEEN::Register>),
69 (0x2AC => cqcuridx: ReadWrite<u32, CQCURIDX::Register>),
70 (0x2B0 => cqendidx: ReadWrite<u32, CQENDIDX::Register>),
71 (0x2B4 => status: ReadOnly<u32, STATUS::Register>),
72 (0x2B8 => _reserved5),
73 (0x300 => mspicfg: ReadWrite<u32, MSPICFG::Register>),
74 (0x304 => _reserved6),
75 (0x400 => mi2ccfg: ReadWrite<u32, MI2CCFG::Register>),
76 (0x404 => devcfg: ReadWrite<u32, DEVCFG::Register>),
77 (0x408 => _reserved7),
78 (0x410 => iomdbg: ReadWrite<u32, IOMDBG::Register>),
79 (0x414 => @END),
80 }
81}
82
83register_bitfields![u32,
84 FIFO [
85 FIFO OFFSET(0) NUMBITS(32) []
86 ],
87 FIFOPTR [
88 FIFO0SIZ OFFSET(0) NUMBITS(8) [],
89 FIFO0REM OFFSET(8) NUMBITS(8) [],
90 FIFO1SIZ OFFSET(16) NUMBITS(8) [],
91 FIFO1REM OFFSET(24) NUMBITS(8) []
92 ],
93 FIFOTHR [
94 FIFORTHR OFFSET(0) NUMBITS(6) [],
95 FIFOWTHR OFFSET(8) NUMBITS(6) []
96 ],
97 FIFOPOP [
98 FIFODOUT OFFSET(0) NUMBITS(32) []
99 ],
100 FIFOPUSH [
101 FIFODIN OFFSET(0) NUMBITS(32) []
102 ],
103 FIFOCTRL [
104 POPWR OFFSET(0) NUMBITS(1) [],
105 FIFORSTN OFFSET(1) NUMBITS(1) []
106 ],
107 FIFOLOC [
108 FIFOWPTR OFFSET(0) NUMBITS(4) [],
109 FIFORPTR OFFSET(8) NUMBITS(4) []
110 ],
111 INT [
112 CMDCMP OFFSET(0) NUMBITS(1) [],
113 THR OFFSET(1) NUMBITS(1) [],
114 FUNDFL OFFSET(2) NUMBITS(1) [],
115 FOVFL OFFSET(3) NUMBITS(1) [],
116 NAK OFFSET(4) NUMBITS(1) [],
117 IACC OFFSET(5) NUMBITS(1) [],
118 ICMD OFFSET(6) NUMBITS(1) [],
119 START OFFSET(7) NUMBITS(1) [],
120 STOP OFFSET(8) NUMBITS(1) [],
121 ARB OFFSET(9) NUMBITS(1) [],
122 DCMP OFFSET(10) NUMBITS(1) [],
123 DERR OFFSET(11) NUMBITS(1) [],
124 CQPAUSED OFFSET(12) NUMBITS(1) [],
125 CQUPD OFFSET(13) NUMBITS(1) [],
126 CQERR OFFSET(14) NUMBITS(1) []
127 ],
128 CLKCFG [
129 IOCLKEN OFFSET(0) NUMBITS(1) [],
130 FSEL OFFSET(8) NUMBITS(3) [],
131 DIV3 OFFSET(11) NUMBITS(1) [],
132 DIVEN OFFSET(12) NUMBITS(1) [],
133 LOWPER OFFSET(16) NUMBITS(8) [],
134 TOTPER OFFSET(24) NUMBITS(8) []
135 ],
136 SUBMODCTRL [
137 SMOD0EN OFFSET(0) NUMBITS(1) [],
138 SMOD0TYPE OFFSET(1) NUMBITS(3) [],
139 SMOD1EN OFFSET(4) NUMBITS(1) [],
140 SMOD1TYPE OFFSET(5) NUMBITS(3) []
141 ],
142 CMD [
143 CMD OFFSET(0) NUMBITS(4) [
144 WRITE = 0x1,
145 READ = 0x2,
146 TMW = 0x3,
147 TMR = 0x4
148 ],
149 OFFSETCNT OFFSET(5) NUMBITS(2) [],
150 CONT OFFSET(7) NUMBITS(1) [],
151 TSIZE OFFSET(8) NUMBITS(12) [],
152 CMDSEL OFFSET(20) NUMBITS(2) [],
153 OFFSETLO OFFSET(24) NUMBITS(8) []
154 ],
155 DCX [
156 CE0OUT OFFSET(0) NUMBITS(1) [],
157 CE1OUT OFFSET(1) NUMBITS(1) [],
158 CE2OUT OFFSET(2) NUMBITS(1) [],
159 DCXEN OFFSET(4) NUMBITS(1) []
160 ],
161 OFFSETHI [
162 OFFSETHI OFFSET(0) NUMBITS(16) []
163 ],
164 CMDSTAT [
165 CCMD OFFSET(0) NUMBITS(4) [],
166 CMDSTAT OFFSET(5) NUMBITS(4) [],
167 CTSIZE OFFSET(8) NUMBITS(12) []
168 ],
169 DMATRIGEN [
170 DCMDCMPEN OFFSET(0) NUMBITS(1) [],
171 DTHREN OFFSET(1) NUMBITS(1) []
172 ],
173 DMATRIGSTAT [
174 DCMDCMP OFFSET(0) NUMBITS(1) [],
175 DTHR OFFSET(1) NUMBITS(1) [],
176 DTOTCMP OFFSET(2) NUMBITS(1) []
177 ],
178 DMACFG [
179 DMAEN OFFSET(0) NUMBITS(1) [],
180 DMADIR OFFSET(1) NUMBITS(1) [],
181 DMAPRI OFFSET(8) NUMBITS(1) [],
182 DPWROFF OFFSET(9) NUMBITS(1) []
183 ],
184 DMATOTCOUNT [
185 TOTCOUNT OFFSET(0) NUMBITS(12) []
186 ],
187 DMATARGADDR [
188 TARGADDR OFFSET(0) NUMBITS(21) [],
189 TARGADDR28 OFFSET(28) NUMBITS(1) []
190 ],
191 DMASTAT [
192 DMATIP OFFSET(0) NUMBITS(1) [],
193 DMACPL OFFSET(1) NUMBITS(1) [],
194 DMAERR OFFSET(2) NUMBITS(1) []
195 ],
196 CQCFG [
197 CQEN OFFSET(0) NUMBITS(1) [],
198 CQPRI OFFSET(1) NUMBITS(1) [],
199 MSPIFLGSEL OFFSET(2) NUMBITS(2) []
200 ],
201 CQADDR [
202 CQADDR OFFSET(2) NUMBITS(19) [],
203 CQADDR28 OFFSET(28) NUMBITS(1) []
204 ],
205 CQSTAT [
206 CQTIP OFFSET(0) NUMBITS(1) [],
207 CQPAUSED OFFSET(1) NUMBITS(1) [],
208 CQERR OFFSET(2) NUMBITS(1) []
209 ],
210 CQFLAGS [
211 CQFLAGS OFFSET(0) NUMBITS(16) [],
212 CQIRQMASK OFFSET(16) NUMBITS(16) []
213 ],
214 CQSETCLEAR [
215 CQFSET OFFSET(0) NUMBITS(8) [],
216 CQFTGL OFFSET(8) NUMBITS(8) [],
217 CQFCLR OFFSET(16) NUMBITS(8) []
218 ],
219 CQPAUSEEN [
220 CQPEN OFFSET(0) NUMBITS(16) []
221 ],
222 CQCURIDX [
223 CQCURIDX OFFSET(0) NUMBITS(8) []
224 ],
225 CQENDIDX [
226 CQENDIDX OFFSET(0) NUMBITS(8) []
227 ],
228 STATUS [
229 ERR OFFSET(0) NUMBITS(1) [],
230 CMDACT OFFSET(1) NUMBITS(2) [],
231 IDLESET OFFSET(2) NUMBITS(1) []
232 ],
233 MSPICFG [
234 SPOL OFFSET(0) NUMBITS(1) [],
235 SPHA OFFSET(1) NUMBITS(1) [],
236 FULLDUP OFFSET(2) NUMBITS(1) [],
237 WTFC OFFSET(16) NUMBITS(1) [],
238 RDFC OFFSET(17) NUMBITS(1) [],
239 MOSIINV OFFSET(18) NUMBITS(1) [],
240 WTFCIRQ OFFSET(20) NUMBITS(1) [],
241 WTFCPOL OFFSET(21) NUMBITS(1) [],
242 RDFCPOL OFFSET(22) NUMBITS(1) [],
243 SPILSB OFFSET(23) NUMBITS(1) [],
244 DINDLY OFFSET(24) NUMBITS(3) [],
245 DOUTDLY OFFSET(27) NUMBITS(3) [],
246 MSPIRST OFFSET(30) NUMBITS(1) []
247 ],
248 MI2CCFG [
249 ADDRSZ OFFSET(0) NUMBITS(1) [],
250 IOMLSB OFFSET(1) NUMBITS(1) [],
251 ARBEN OFFSET(2) NUMBITS(1) [],
252 SDADLY OFFSET(4) NUMBITS(2) [],
253 MI2CRST OFFSET(6) NUMBITS(1) [],
254 SCLENDLY OFFSET(8) NUMBITS(3) [],
255 SDAENDLY OFFSET(12) NUMBITS(3) [],
256 SMPCNT OFFSET(16) NUMBITS(8) [],
257 STRDIS OFFSET(24) NUMBITS(1) []
258 ],
259 DEVCFG [
260 DEVADDR OFFSET(0) NUMBITS(10) []
261 ],
262 IOMDBG [
263 DBGEN OFFSET(0) NUMBITS(1) [],
264 IOCLKON OFFSET(1) NUMBITS(1) [],
265 APBCLKON OFFSET(2) NUMBITS(1) [],
266 DBGDATA OFFSET(3) NUMBITS(29) []
267 ]
268];
269
270#[derive(Clone, Copy, PartialEq, Debug)]
271enum Operation {
272 None,
273 I2C,
274 SPI,
275}
276
277pub struct Iom<'a> {
278 registers: StaticRef<IomRegisters>,
279
280 i2c_master_client: OptionalCell<&'a dyn hil::i2c::I2CHwMasterClient>,
281 spi_master_client: OptionalCell<&'a dyn SpiMasterClient>,
282
283 buffer: MapCell<SubSliceMut<'static, u8>>,
284 spi_read_buffer: MapCell<SubSliceMut<'static, u8>>,
285 write_len: Cell<usize>,
286 write_index: Cell<usize>,
287
288 read_len: Cell<usize>,
289 read_index: Cell<usize>,
290
291 op: Cell<Operation>,
292 spi_phase: Cell<ClockPhase>,
293 spi_cs: OptionalCell<ChipSelectPolar<'a, crate::gpio::GpioPin<'a>>>,
294 smbus: Cell<bool>,
295}
296
297impl<'a> Iom<'_> {
298 pub fn new0() -> Iom<'a> {
299 Iom {
300 registers: IOM0_BASE,
301 i2c_master_client: OptionalCell::empty(),
302 spi_master_client: OptionalCell::empty(),
303 buffer: MapCell::empty(),
304 spi_read_buffer: MapCell::empty(),
305 write_len: Cell::new(0),
306 write_index: Cell::new(0),
307 read_len: Cell::new(0),
308 read_index: Cell::new(0),
309 op: Cell::new(Operation::None),
310 spi_phase: Cell::new(ClockPhase::SampleLeading),
311 spi_cs: OptionalCell::empty(),
312 smbus: Cell::new(false),
313 }
314 }
315 pub fn new1() -> Iom<'a> {
316 Iom {
317 registers: IOM1_BASE,
318 i2c_master_client: OptionalCell::empty(),
319 spi_master_client: OptionalCell::empty(),
320 buffer: MapCell::empty(),
321 spi_read_buffer: MapCell::empty(),
322 write_len: Cell::new(0),
323 write_index: Cell::new(0),
324 read_len: Cell::new(0),
325 read_index: Cell::new(0),
326 op: Cell::new(Operation::None),
327 spi_phase: Cell::new(ClockPhase::SampleLeading),
328 spi_cs: OptionalCell::empty(),
329 smbus: Cell::new(false),
330 }
331 }
332 pub fn new2() -> Iom<'a> {
333 Iom {
334 registers: IOM2_BASE,
335 i2c_master_client: OptionalCell::empty(),
336 spi_master_client: OptionalCell::empty(),
337 buffer: MapCell::empty(),
338 spi_read_buffer: MapCell::empty(),
339 write_len: Cell::new(0),
340 write_index: Cell::new(0),
341 read_len: Cell::new(0),
342 read_index: Cell::new(0),
343 op: Cell::new(Operation::None),
344 spi_phase: Cell::new(ClockPhase::SampleLeading),
345 spi_cs: OptionalCell::empty(),
346 smbus: Cell::new(false),
347 }
348 }
349 pub fn new3() -> Iom<'a> {
350 Iom {
351 registers: IOM3_BASE,
352 i2c_master_client: OptionalCell::empty(),
353 spi_master_client: OptionalCell::empty(),
354 buffer: MapCell::empty(),
355 spi_read_buffer: MapCell::empty(),
356 write_len: Cell::new(0),
357 write_index: Cell::new(0),
358 read_len: Cell::new(0),
359 read_index: Cell::new(0),
360 op: Cell::new(Operation::None),
361 spi_phase: Cell::new(ClockPhase::SampleLeading),
362 spi_cs: OptionalCell::empty(),
363 smbus: Cell::new(false),
364 }
365 }
366 pub fn new4() -> Iom<'a> {
367 Iom {
368 registers: IOM4_BASE,
369 i2c_master_client: OptionalCell::empty(),
370 spi_master_client: OptionalCell::empty(),
371 buffer: MapCell::empty(),
372 spi_read_buffer: MapCell::empty(),
373 write_len: Cell::new(0),
374 write_index: Cell::new(0),
375 read_len: Cell::new(0),
376 read_index: Cell::new(0),
377 op: Cell::new(Operation::None),
378 spi_phase: Cell::new(ClockPhase::SampleLeading),
379 spi_cs: OptionalCell::empty(),
380 smbus: Cell::new(false),
381 }
382 }
383 pub fn new5() -> Iom<'a> {
384 Iom {
385 registers: IOM5_BASE,
386 i2c_master_client: OptionalCell::empty(),
387 spi_master_client: OptionalCell::empty(),
388 buffer: MapCell::empty(),
389 spi_read_buffer: MapCell::empty(),
390 write_len: Cell::new(0),
391 write_index: Cell::new(0),
392 read_len: Cell::new(0),
393 read_index: Cell::new(0),
394 op: Cell::new(Operation::None),
395 spi_phase: Cell::new(ClockPhase::SampleLeading),
396 spi_cs: OptionalCell::empty(),
397 smbus: Cell::new(false),
398 }
399 }
400
401 fn i2c_reset_fifo(&self) {
402 let regs = self.registers;
403
404 regs.fifoctrl.modify(FIFOCTRL::FIFORSTN::CLEAR);
406
407 for _i in 0..30 {
409 cortexm4f::support::nop();
410 }
411
412 regs.fifoctrl.modify(FIFOCTRL::FIFORSTN::SET);
414 }
415
416 fn iom_fifo_errata_delay(&self) {
427 for _i in 0..3000 {
428 cortexm4f::support::nop();
429 }
430 }
431
432 fn i2c_write_data(&self) {
433 let regs = self.registers;
434 let mut data_pushed = self.write_index.get();
435 let len = self.write_len.get();
436
437 if data_pushed == len {
438 return;
439 }
440
441 self.buffer.map(|buf| {
442 for i in (data_pushed / 4)..(len / 4) {
444 let data_idx = i * 4;
445
446 if regs.fifoptr.read(FIFOPTR::FIFO0REM) <= 4 {
447 self.write_index.set(data_pushed);
448 break;
449 }
450
451 let mut d = (buf[data_idx + 0] as u32) << 0;
452 d |= (buf[data_idx + 1] as u32) << 8;
453 d |= (buf[data_idx + 2] as u32) << 16;
454 d |= (buf[data_idx + 3] as u32) << 24;
455
456 regs.fifopush.set(d);
457
458 data_pushed = data_idx + 4;
459 }
460
461 if len < 4 || data_pushed > (len - 4) {
463 if len % 4 == 1 {
465 let d = buf[len - 1] as u32;
466
467 regs.fifopush.set(d);
468 } else if len % 4 == 2 {
469 let mut d = (buf[len - 1] as u32) << 8;
470 d |= (buf[len - 2] as u32) << 0;
471
472 regs.fifopush.set(d);
473 } else if len % 4 == 3 {
474 let mut d = (buf[len - 1] as u32) << 16;
475 d |= (buf[len - 2] as u32) << 8;
476 d |= (buf[len - 3] as u32) << 0;
477
478 regs.fifopush.set(d);
479 }
480 self.write_index.set(len);
481 }
482 });
483 }
484
485 fn i2c_read_data(&self) {
486 let regs = self.registers;
487 let mut data_popped = self.read_index.get();
488 let len = self.read_len.get();
489
490 if data_popped == len {
491 return;
492 }
493
494 self.buffer.map(|buf| {
495 for i in (data_popped / 4)..(len / 4) {
497 let data_idx = i * 4;
498
499 self.iom_fifo_errata_delay();
500
501 if regs.fifoptr.read(FIFOPTR::FIFO1SIZ) < 4 {
502 self.read_index.set(data_popped);
503 break;
504 }
505
506 let d = regs.fifopop.get().to_ne_bytes();
507
508 buf[data_idx + 0] = d[0];
509 buf[data_idx + 1] = d[1];
510 buf[data_idx + 2] = d[2];
511 buf[data_idx + 3] = d[3];
512
513 data_popped = data_idx + 4;
514 }
515
516 if len < 4 || data_popped > (len - 4) {
518 self.iom_fifo_errata_delay();
519
520 if len % 4 == 1 {
522 let d = regs.fifopop.get().to_ne_bytes();
523
524 buf[len - 1] = d[0];
525 } else if len % 4 == 2 {
526 let d = regs.fifopop.get().to_ne_bytes();
527
528 buf[len - 2] = d[0];
529 buf[len - 1] = d[1];
530 } else if len % 4 == 3 {
531 let d = regs.fifopop.get().to_ne_bytes();
532
533 buf[len - 3] = d[0];
534 buf[len - 2] = d[1];
535 buf[len - 1] = d[2];
536 }
537 self.read_index.set(len);
538 }
539 });
540 }
541
542 pub fn handle_interrupt(&self) {
543 let regs = self.registers;
544 let irqs = regs.intstat.extract();
545
546 regs.intclr.set(0xFFFF_FFFF);
548 regs.inten.set(0xFFFF_FFFF);
550
551 if irqs.is_set(INT::NAK) {
552 if self.op.get() == Operation::I2C {
553 regs.inten.set(0x00);
555 self.i2c_reset_fifo();
556
557 self.i2c_master_client.map(|client| {
558 self.buffer.take().map(|buffer| {
559 client.command_complete(buffer.take(), Err(i2c::Error::DataNak));
560 });
561 });
562
563 if self.smbus.get() {
565 regs.clkcfg.write(
567 CLKCFG::TOTPER.val(0x1D)
568 + CLKCFG::LOWPER.val(0xE)
569 + CLKCFG::DIVEN.val(1)
570 + CLKCFG::DIV3.val(0)
571 + CLKCFG::FSEL.val(2)
572 + CLKCFG::IOCLKEN::SET,
573 );
574
575 self.smbus.set(false);
576 }
577 } else {
578 regs.inten.set(0x00);
580
581 self.spi_cs.map(|cs| cs.deactivate());
583
584 self.op.set(Operation::None);
585
586 self.spi_master_client.map(|client| {
587 self.buffer.take().map(|buffer| {
588 let read_buffer = self.spi_read_buffer.take();
589 client.read_write_done(buffer, read_buffer, Err(ErrorCode::NOACK));
590 });
591 });
592 }
593 return;
594 }
595
596 if self.op.get() == Operation::SPI {
597 if let Some(mut buf) = self.spi_read_buffer.take() {
599 while self.registers.fifoptr.read(FIFOPTR::FIFO1SIZ) > 0 {
600 self.iom_fifo_errata_delay();
601
602 let d = self.registers.fifopop.get().to_ne_bytes();
603 let data_idx = self.read_index.get();
604
605 if let Some(b) = buf.as_slice().get_mut(data_idx + 0) {
606 *b = d[0];
607 self.read_index.set(data_idx + 1);
608 }
609 if let Some(b) = buf.as_slice().get_mut(data_idx + 1) {
610 *b = d[1];
611 self.read_index.set(data_idx + 2);
612 }
613 if let Some(b) = buf.as_slice().get_mut(data_idx + 2) {
614 *b = d[2];
615 self.read_index.set(data_idx + 3);
616 }
617 if let Some(b) = buf.as_slice().get_mut(data_idx + 3) {
618 *b = d[3];
619 self.read_index.set(data_idx + 4);
620 }
621 }
622
623 self.spi_read_buffer.replace(buf);
624
625 if self.read_len.get() > self.read_index.get() {
626 let remaining_bytes = (self.read_len.get() - self.read_index.get()).min(32);
627 self.registers
628 .fifothr
629 .modify(FIFOTHR::FIFORTHR.val(remaining_bytes as u32));
630 } else {
631 self.registers.fifothr.modify(FIFOTHR::FIFORTHR.val(0));
632 }
633 } else {
634 while self.registers.fifoptr.read(FIFOPTR::FIFO1SIZ) > 0 {
635 self.iom_fifo_errata_delay();
636
637 let _d = self.registers.fifopop.get().to_ne_bytes();
638 }
639
640 self.registers.fifothr.modify(FIFOTHR::FIFORTHR.val(0));
641 }
642
643 if self.write_index.get() < self.write_len.get() {
645 if let Some(write_buffer) = self.buffer.take() {
646 let mut transfered_bytes = 0;
647
648 while self.registers.fifoptr.read(FIFOPTR::FIFO0REM) > 0
664 && self.registers.fifoptr.read(FIFOPTR::FIFO1REM) > 4
665 && self.write_index.get() < self.write_len.get()
666 && transfered_bytes < 24
667 {
668 let idx = self.write_index.get();
669
670 let chunk = write_buffer[idx..].chunks(4).next().unwrap_or(&[]);
671
672 let data = u32::from_le_bytes([
673 chunk.get(0).copied().unwrap_or(0),
674 chunk.get(1).copied().unwrap_or(0),
675 chunk.get(2).copied().unwrap_or(0),
676 chunk.get(3).copied().unwrap_or(0),
677 ]);
678
679 self.registers.fifopush.set(data);
680 self.write_index.set(idx + 4);
681 transfered_bytes += 4;
682 }
683
684 self.buffer.replace(write_buffer);
685 }
686
687 let remaining_bytes = (self.write_len.get() - self.write_index.get()).min(32);
688 self.registers
689 .fifothr
690 .modify(FIFOTHR::FIFOWTHR.val(remaining_bytes as u32));
691 } else {
692 self.registers.fifothr.modify(FIFOTHR::FIFOWTHR.val(0));
693 }
694
695 if (self.write_len.get() > 0
696 && self.write_index.get() >= self.write_len.get()
697 && self.read_len.get() > 0
698 && self.read_index.get() >= self.read_len.get())
699 || irqs.is_set(INT::CMDCMP)
700 {
701 regs.inten.set(0x00);
703
704 self.spi_cs.map(|cs| cs.deactivate());
706
707 self.op.set(Operation::None);
708
709 self.spi_master_client.map(|client| {
710 self.buffer.take().map(|buffer| {
711 let read_buffer = self.spi_read_buffer.take();
712 client.read_write_done(buffer, read_buffer, Ok(self.write_len.get()));
713 });
714 });
715 }
716
717 return;
718 }
719
720 if irqs.is_set(INT::CMDCMP) || irqs.is_set(INT::THR) {
721 if self.op.get() == Operation::I2C {
722 if irqs.is_set(INT::THR) {
723 if regs.fifothr.read(FIFOTHR::FIFOWTHR) > 0 {
724 let remaining = self.write_len.get() - self.write_index.get();
725
726 if remaining > 4 {
727 regs.fifothr.write(
728 FIFOTHR::FIFORTHR.val(0)
729 + FIFOTHR::FIFOWTHR.val(remaining as u32 / 2),
730 );
731 } else {
732 regs.fifothr
733 .write(FIFOTHR::FIFORTHR.val(0) + FIFOTHR::FIFOWTHR.val(1));
734 }
735
736 self.i2c_write_data();
737 } else if regs.fifothr.read(FIFOTHR::FIFORTHR) > 0 {
738 let remaining = self.read_len.get() - self.read_index.get();
739
740 if remaining > 4 {
741 regs.fifothr.write(
742 FIFOTHR::FIFORTHR.val(remaining as u32 / 2)
743 + FIFOTHR::FIFOWTHR.val(0),
744 );
745 } else {
746 regs.fifothr
747 .write(FIFOTHR::FIFORTHR.val(1) + FIFOTHR::FIFOWTHR.val(0));
748 }
749
750 self.i2c_read_data();
751 }
752 }
753
754 if irqs.is_set(INT::CMDCMP) {
755 if (self.read_len.get() > 0 && self.read_index.get() == self.read_len.get())
756 || (self.write_len.get() > 0
757 && self.write_index.get() == self.write_len.get())
758 {
759 regs.inten.set(0x00);
761 self.i2c_reset_fifo();
762
763 self.i2c_master_client.map(|client| {
764 self.buffer.take().map(|buffer| {
765 client.command_complete(buffer.take(), Ok(()));
766 });
767 });
768
769 if self.smbus.get() {
771 regs.clkcfg.write(
773 CLKCFG::TOTPER.val(0x1D)
774 + CLKCFG::LOWPER.val(0xE)
775 + CLKCFG::DIVEN.val(1)
776 + CLKCFG::DIV3.val(0)
777 + CLKCFG::FSEL.val(2)
778 + CLKCFG::IOCLKEN::SET,
779 );
780
781 self.smbus.set(false);
782 }
783 }
784 }
785 } else {
786 self.buffer.take().map(|write_buffer| {
787 let offset = self.write_index.get();
788 if self.write_len.get() > offset {
789 let burst_len = (self.write_len.get() - offset)
790 .min(self.registers.fifoptr.read(FIFOPTR::FIFO0REM) as usize);
791
792 self.registers.cmd.write(
794 CMD::TSIZE.val(burst_len as u32)
795 + CMD::CMDSEL.val(1)
796 + CMD::CONT::CLEAR
797 + CMD::CMD::WRITE
798 + CMD::OFFSETCNT.val(0_u32)
799 + CMD::OFFSETLO.val(0),
800 );
801
802 while self.registers.fifoptr.read(FIFOPTR::FIFO0REM) > 4
803 && self.registers.fifoptr.read(FIFOPTR::FIFO1SIZ) < 32
804 && self.write_index.get() < (((offset + burst_len) / 4) * 4)
805 && self.write_len.get() - self.write_index.get() > 4
806 {
807 let idx = self.write_index.get();
808 let data = u32::from_le_bytes(
809 write_buffer[idx..(idx + 4)].try_into().unwrap_or([0; 4]),
810 );
811
812 self.registers.fifopush.set(data);
813 self.write_index.set(idx + 4);
814 }
815
816 if self.write_len.get() - self.write_index.get() < 4
818 && self.write_index.get() < (offset + burst_len)
819 {
820 let len = self.write_len.get() - self.write_index.get();
821 let mut buf = [0; 4];
822 if len % 4 == 1 {
824 buf[len - 1] = write_buffer[self.write_index.get() + 0];
825 } else if len % 4 == 2 {
826 buf[len - 2] = write_buffer[self.write_index.get() + 0];
827 buf[len - 1] = write_buffer[self.write_index.get() + 1];
828 } else if len % 4 == 3 {
829 buf[len - 3] = write_buffer[self.write_index.get() + 0];
830 buf[len - 2] = write_buffer[self.write_index.get() + 1];
831 buf[len - 1] = write_buffer[self.write_index.get() + 2];
832 }
833 self.registers.fifopush.set(u32::from_le_bytes(buf));
834 self.write_index.set(self.write_index.get() + len);
835 }
836 }
837
838 self.buffer.replace(write_buffer);
839 });
840 }
841 }
842 }
843
844 fn i2c_tx_rx(
845 &self,
846 addr: u8,
847 data: &'static mut [u8],
848 write_len: usize,
849 read_len: usize,
850 ) -> Result<(), (i2c::Error, &'static mut [u8])> {
851 let regs = self.registers;
852 let mut offsetlo = 0;
853
854 regs.dmacfg.write(DMACFG::DMAEN::CLEAR);
856
857 regs.devcfg.write(DEVCFG::DEVADDR.val(addr as u32));
859
860 regs.dcx.set(0);
862
863 if read_len > 4 {
865 regs.fifothr
866 .write(FIFOTHR::FIFORTHR.val(read_len as u32 / 2) + FIFOTHR::FIFOWTHR.val(0));
867 } else {
868 regs.fifothr
869 .write(FIFOTHR::FIFORTHR.val(1) + FIFOTHR::FIFOWTHR.val(0));
870 }
871
872 self.i2c_reset_fifo();
873
874 if write_len > 0 {
875 offsetlo = data[0] as u32;
876 }
877
878 if write_len == 2 {
879 regs.offsethi.set(data[1] as u32);
880 } else if write_len == 3 {
881 regs.offsethi.set(data[1] as u32 | ((data[2] as u32) << 8));
882 }
883
884 if write_len > 3 {
885 Err((i2c::Error::NotSupported, data))
886 } else {
887 self.buffer.replace(data.into());
889 self.write_len.set(write_len);
890 self.read_len.set(read_len);
891 self.write_index.set(0);
892 self.read_index.set(0);
893 regs.intclr.set(0xFFFF_FFFF);
895 regs.inten.set(0xFFFF_FFFF);
896
897 regs.cmd.write(
899 CMD::TSIZE.val(read_len as u32)
900 + CMD::CMD::READ
901 + CMD::OFFSETCNT.val(write_len as u32)
902 + CMD::OFFSETLO.val(offsetlo),
903 );
904
905 Ok(())
906 }
907 }
908
909 fn i2c_tx(
910 &self,
911 addr: u8,
912 data: &'static mut [u8],
913 len: usize,
914 ) -> Result<(), (i2c::Error, &'static mut [u8])> {
915 let regs = self.registers;
916
917 regs.dmacfg.write(DMACFG::DMAEN::CLEAR);
919
920 regs.devcfg.write(DEVCFG::DEVADDR.val(addr as u32));
922
923 regs.dcx.set(0);
925
926 if len > 4 {
928 regs.fifothr
929 .write(FIFOTHR::FIFORTHR.val(0) + FIFOTHR::FIFOWTHR.val(len as u32 / 2));
930 } else {
931 regs.fifothr
932 .write(FIFOTHR::FIFORTHR.val(0) + FIFOTHR::FIFOWTHR.val(1));
933 }
934
935 self.i2c_reset_fifo();
936
937 self.buffer.replace(data.into());
939 self.write_len.set(len);
940 self.read_len.set(0);
941 self.write_index.set(0);
942
943 self.i2c_write_data();
944
945 regs.intclr.set(0xFFFF_FFFF);
947 regs.inten.set(0xFFFF_FFFF);
948
949 regs.cmd
951 .write(CMD::TSIZE.val(len as u32) + CMD::CMD::WRITE + CMD::CONT::CLEAR);
952 Ok(())
953 }
954
955 fn i2c_rx(
956 &self,
957 addr: u8,
958 buffer: &'static mut [u8],
959 len: usize,
960 ) -> Result<(), (i2c::Error, &'static mut [u8])> {
961 let regs = self.registers;
962
963 regs.dmacfg.modify(DMACFG::DMAEN::CLEAR);
965
966 regs.devcfg.write(DEVCFG::DEVADDR.val(addr as u32));
968
969 regs.dcx.set(0);
971
972 if len > 4 {
974 regs.fifothr
975 .write(FIFOTHR::FIFORTHR.val(len as u32 / 2) + FIFOTHR::FIFOWTHR.val(0));
976 } else {
977 regs.fifothr
978 .write(FIFOTHR::FIFORTHR.val(1) + FIFOTHR::FIFOWTHR.val(0));
979 }
980
981 self.i2c_reset_fifo();
982
983 regs.intclr.set(0xFFFF_FFFF);
985 regs.inten.set(0xFFFF_FFFF);
986
987 regs.cmd
989 .write(CMD::TSIZE.val(len as u32) + CMD::CMD::READ + CMD::CONT::CLEAR);
990
991 self.buffer.replace(buffer.into());
993 self.read_len.set(len);
994 self.write_len.set(0);
995 self.read_index.set(0);
996
997 self.i2c_read_data();
998
999 Ok(())
1000 }
1001}
1002
1003impl<'a> hil::i2c::I2CMaster<'a> for Iom<'a> {
1004 fn set_master_client(&self, i2c_master_client: &'a dyn i2c::I2CHwMasterClient) {
1005 self.i2c_master_client.set(i2c_master_client);
1006 }
1007
1008 fn enable(&self) {
1009 let regs = self.registers;
1010
1011 self.op.set(Operation::I2C);
1012
1013 regs.mi2ccfg.write(
1015 MI2CCFG::STRDIS.val(0)
1016 + MI2CCFG::SMPCNT.val(3)
1017 + MI2CCFG::SDAENDLY.val(15)
1018 + MI2CCFG::SCLENDLY.val(2)
1019 + MI2CCFG::SDADLY.val(3)
1020 + MI2CCFG::ARBEN::SET
1021 + MI2CCFG::IOMLSB::CLEAR
1022 + MI2CCFG::ADDRSZ::CLEAR,
1023 );
1024
1025 regs.clkcfg.write(
1027 CLKCFG::TOTPER.val(0x1D)
1028 + CLKCFG::LOWPER.val(0xE)
1029 + CLKCFG::DIVEN.val(1)
1030 + CLKCFG::DIV3.val(0)
1031 + CLKCFG::FSEL.val(2)
1032 + CLKCFG::IOCLKEN::SET,
1033 );
1034
1035 regs.submodctrl.write(SUBMODCTRL::SMOD1EN::SET);
1037
1038 regs.cqcfg.modify(CQCFG::CQEN::CLEAR);
1040 }
1041
1042 fn disable(&self) {
1043 let regs = self.registers;
1044
1045 if self.op.get() == Operation::I2C {
1046 regs.submodctrl.write(SUBMODCTRL::SMOD1EN::CLEAR);
1047
1048 self.op.set(Operation::None);
1049 }
1050 }
1051
1052 fn write_read(
1053 &self,
1054 addr: u8,
1055 data: &'static mut [u8],
1056 write_len: usize,
1057 read_len: usize,
1058 ) -> Result<(), (hil::i2c::Error, &'static mut [u8])> {
1059 if self.op.get() != Operation::I2C {
1060 return Err((hil::i2c::Error::Busy, data));
1061 }
1062 if data.len() < write_len {
1063 return Err((hil::i2c::Error::Overrun, data));
1064 }
1065 self.i2c_tx_rx(addr, data, write_len, read_len)
1066 }
1067
1068 fn write(
1069 &self,
1070 addr: u8,
1071 data: &'static mut [u8],
1072 len: usize,
1073 ) -> Result<(), (hil::i2c::Error, &'static mut [u8])> {
1074 if self.op.get() != Operation::I2C {
1075 return Err((hil::i2c::Error::Busy, data));
1076 }
1077 if data.len() < len {
1078 return Err((hil::i2c::Error::Overrun, data));
1079 }
1080 self.i2c_tx(addr, data, len)
1081 }
1082
1083 fn read(
1084 &self,
1085 addr: u8,
1086 buffer: &'static mut [u8],
1087 len: usize,
1088 ) -> Result<(), (hil::i2c::Error, &'static mut [u8])> {
1089 if self.op.get() != Operation::I2C {
1090 return Err((hil::i2c::Error::Busy, buffer));
1091 }
1092 if buffer.len() < len {
1093 return Err((hil::i2c::Error::Overrun, buffer));
1094 }
1095 self.i2c_rx(addr, buffer, len)
1096 }
1097}
1098
1099impl<'a> hil::i2c::SMBusMaster<'a> for Iom<'a> {
1100 fn smbus_write_read(
1101 &self,
1102 addr: u8,
1103 data: &'static mut [u8],
1104 write_len: usize,
1105 read_len: usize,
1106 ) -> Result<(), (hil::i2c::Error, &'static mut [u8])> {
1107 let regs = self.registers;
1108
1109 if self.op.get() != Operation::I2C {
1110 return Err((hil::i2c::Error::Busy, data));
1111 }
1112
1113 regs.clkcfg.write(
1115 CLKCFG::TOTPER.val(0x77)
1116 + CLKCFG::LOWPER.val(0x3B)
1117 + CLKCFG::DIVEN.val(1)
1118 + CLKCFG::DIV3.val(0)
1119 + CLKCFG::FSEL.val(2)
1120 + CLKCFG::IOCLKEN::SET,
1121 );
1122
1123 self.smbus.set(true);
1124
1125 self.i2c_tx_rx(addr, data, write_len, read_len)
1126 }
1127
1128 fn smbus_write(
1129 &self,
1130 addr: u8,
1131 data: &'static mut [u8],
1132 len: usize,
1133 ) -> Result<(), (hil::i2c::Error, &'static mut [u8])> {
1134 let regs = self.registers;
1135
1136 if self.op.get() != Operation::I2C {
1137 return Err((hil::i2c::Error::Busy, data));
1138 }
1139
1140 regs.clkcfg.write(
1142 CLKCFG::TOTPER.val(0x77)
1143 + CLKCFG::LOWPER.val(0x3B)
1144 + CLKCFG::DIVEN.val(1)
1145 + CLKCFG::DIV3.val(0)
1146 + CLKCFG::FSEL.val(2)
1147 + CLKCFG::IOCLKEN::SET,
1148 );
1149
1150 self.smbus.set(true);
1151
1152 self.i2c_tx(addr, data, len)
1153 }
1154
1155 fn smbus_read(
1156 &self,
1157 addr: u8,
1158 buffer: &'static mut [u8],
1159 len: usize,
1160 ) -> Result<(), (hil::i2c::Error, &'static mut [u8])> {
1161 let regs = self.registers;
1162
1163 if self.op.get() != Operation::I2C {
1164 return Err((hil::i2c::Error::Busy, buffer));
1165 }
1166
1167 regs.clkcfg.write(
1169 CLKCFG::TOTPER.val(0x77)
1170 + CLKCFG::LOWPER.val(0x3B)
1171 + CLKCFG::DIVEN.val(1)
1172 + CLKCFG::DIV3.val(0)
1173 + CLKCFG::FSEL.val(2)
1174 + CLKCFG::IOCLKEN::SET,
1175 );
1176
1177 self.smbus.set(true);
1178
1179 self.i2c_rx(addr, buffer, len)
1180 }
1181}
1182
1183impl<'a> SpiMaster<'a> for Iom<'a> {
1184 type ChipSelect = ChipSelectPolar<'a, crate::gpio::GpioPin<'a>>;
1185
1186 fn init(&self) -> Result<(), ErrorCode> {
1187 self.op.set(Operation::SPI);
1188
1189 self.registers.mspicfg.write(
1190 MSPICFG::FULLDUP::SET
1191 + MSPICFG::WTFC::CLEAR
1192 + MSPICFG::RDFC::CLEAR
1193 + MSPICFG::MOSIINV::CLEAR
1194 + MSPICFG::WTFCIRQ::CLEAR
1195 + MSPICFG::WTFCPOL::CLEAR
1196 + MSPICFG::RDFCPOL::CLEAR
1197 + MSPICFG::SPILSB::CLEAR
1198 + MSPICFG::DINDLY::CLEAR
1199 + MSPICFG::DOUTDLY::CLEAR
1200 + MSPICFG::MSPIRST::CLEAR,
1201 );
1202
1203 self.registers
1205 .submodctrl
1206 .write(SUBMODCTRL::SMOD1EN::CLEAR + SUBMODCTRL::SMOD0EN::SET);
1207
1208 self.registers.dmatrigen.write(DMATRIGEN::DTHREN::SET);
1209
1210 Ok(())
1211 }
1212
1213 fn set_client(&self, client: &'a dyn SpiMasterClient) {
1214 self.spi_master_client.set(client);
1215 }
1216
1217 fn is_busy(&self) -> bool {
1218 self.op.get() != Operation::None
1219 }
1220
1221 fn read_write_bytes(
1222 &self,
1223 write_buffer: SubSliceMut<'static, u8>,
1224 read_buffer: Option<SubSliceMut<'static, u8>>,
1225 ) -> Result<
1226 (),
1227 (
1228 ErrorCode,
1229 SubSliceMut<'static, u8>,
1230 Option<SubSliceMut<'static, u8>>,
1231 ),
1232 > {
1233 let (write_len, read_len) = if let Some(rb) = read_buffer.as_ref() {
1234 let min = write_buffer.len().min(rb.len());
1235 (min, min)
1236 } else {
1237 (write_buffer.len(), 0)
1238 };
1239
1240 self.registers.dmacfg.write(DMACFG::DMAEN::CLEAR);
1242
1243 self.registers.dcx.set(0);
1245
1246 self.write_index.set(0);
1247 self.read_index.set(0);
1248
1249 self.registers.intclr.set(0xFFFF_FFFF);
1251
1252 self.spi_cs.map(|cs| cs.activate());
1254
1255 self.registers.cmd.write(
1257 CMD::TSIZE.val(write_len as u32)
1258 + CMD::CMDSEL.val(1)
1259 + CMD::CONT::CLEAR
1260 + CMD::CMD::WRITE
1261 + CMD::OFFSETCNT.val(0_u32)
1262 + CMD::OFFSETLO.val(0),
1263 );
1264
1265 if let Some(buf) = read_buffer {
1266 self.spi_read_buffer.replace(buf);
1267 }
1268
1269 while self.registers.cmdstat.read(CMDSTAT::CMDSTAT) == 0x02 {}
1270
1271 let mut transfered_bytes = 0;
1272
1273 while self.registers.fifoptr.read(FIFOPTR::FIFO0REM) > 0
1289 && self.registers.fifoptr.read(FIFOPTR::FIFO1REM) > 4
1290 && self.write_index.get() < write_len
1291 && transfered_bytes < 24
1292 {
1293 let idx = self.write_index.get();
1294
1295 let chunk = write_buffer[idx..].chunks(4).next().unwrap_or(&[]);
1297
1298 let data = u32::from_le_bytes([
1299 chunk.get(0).copied().unwrap_or(0),
1300 chunk.get(1).copied().unwrap_or(0),
1301 chunk.get(2).copied().unwrap_or(0),
1302 chunk.get(3).copied().unwrap_or(0),
1303 ]);
1304
1305 self.iom_fifo_errata_delay();
1306
1307 self.registers.fifopush.set(data);
1308 self.write_index.set(idx + 4);
1309 transfered_bytes += 4;
1310
1311 if let Some(mut buf) = self.spi_read_buffer.take() {
1312 if self.registers.fifoptr.read(FIFOPTR::FIFO1SIZ) > 0
1313 && self.read_index.get() < read_len
1314 {
1315 let d = self.registers.fifopop.get().to_ne_bytes();
1316
1317 let data_idx = self.read_index.get();
1318
1319 buf[data_idx + 0] = d[0];
1320 buf[data_idx + 1] = d[1];
1321 buf[data_idx + 2] = d[2];
1322 buf[data_idx + 3] = d[3];
1323
1324 self.read_index.set(data_idx + 4);
1325 }
1326
1327 self.spi_read_buffer.replace(buf);
1328 } else {
1329 if self.registers.fifoptr.read(FIFOPTR::FIFO1SIZ) > 0 {
1330 let _d = self.registers.fifopop.get();
1331 }
1332 }
1333 }
1334
1335 self.buffer.replace(write_buffer);
1337 self.write_len.set(write_len);
1338 self.read_len.set(read_len);
1339 self.op.set(Operation::SPI);
1340
1341 if read_len > self.read_index.get() {
1342 let remaining_bytes = (read_len - self.read_index.get()).min(32);
1343 self.registers
1344 .fifothr
1345 .modify(FIFOTHR::FIFORTHR.val(remaining_bytes as u32));
1346 } else {
1347 self.registers.fifothr.modify(FIFOTHR::FIFORTHR.val(0));
1348 }
1349
1350 if write_len > self.write_index.get() {
1351 let remaining_bytes = (self.write_len.get() - self.write_index.get()).min(32);
1352
1353 self.registers
1354 .fifothr
1355 .modify(FIFOTHR::FIFOWTHR.val(remaining_bytes as u32));
1356 } else {
1357 self.registers.fifothr.modify(FIFOTHR::FIFOWTHR.val(0));
1358 }
1359
1360 self.registers.inten.set(0xFFFF_FFFF);
1362
1363 Ok(())
1364 }
1365
1366 fn write_byte(&self, val: u8) -> Result<(), ErrorCode> {
1367 let burst_len = 1;
1368
1369 self.registers.dmacfg.write(DMACFG::DMAEN::CLEAR);
1371
1372 self.registers.dcx.set(0);
1374
1375 self.registers.intclr.set(0xFFFF_FFFF);
1377
1378 self.spi_cs.map(|cs| cs.activate());
1380
1381 self.registers.cmd.write(
1383 CMD::TSIZE.val(burst_len as u32)
1384 + CMD::CMDSEL.val(1)
1385 + CMD::CONT::CLEAR
1386 + CMD::CMD::WRITE
1387 + CMD::OFFSETCNT.val(0_u32)
1388 + CMD::OFFSETLO.val(0),
1389 );
1390
1391 self.registers.fifopush.set(val as u32);
1392
1393 self.spi_cs.map(|cs| cs.deactivate());
1394
1395 Ok(())
1396 }
1397
1398 fn read_byte(&self) -> Result<u8, ErrorCode> {
1399 let burst_len = 1;
1400
1401 self.registers.dmacfg.write(DMACFG::DMAEN::CLEAR);
1403
1404 self.registers.dcx.set(0);
1406
1407 self.registers.intclr.set(0xFFFF_FFFF);
1409
1410 self.spi_cs.map(|cs| cs.activate());
1412
1413 self.registers.cmd.write(
1415 CMD::TSIZE.val(burst_len as u32)
1416 + CMD::CMDSEL.val(1)
1417 + CMD::CONT::CLEAR
1418 + CMD::CMD::READ
1419 + CMD::OFFSETCNT.val(0_u32)
1420 + CMD::OFFSETLO.val(0),
1421 );
1422
1423 if self.registers.fifoptr.read(FIFOPTR::FIFO1SIZ) > 0 {
1424 let d = self.registers.fifopop.get().to_ne_bytes();
1425
1426 self.spi_cs.map(|cs| cs.deactivate());
1427 return Ok(d[0]);
1428 }
1429
1430 self.spi_cs.map(|cs| cs.deactivate());
1431
1432 Err(ErrorCode::FAIL)
1433 }
1434
1435 fn read_write_byte(&self, val: u8) -> Result<u8, ErrorCode> {
1436 let burst_len = 1;
1437
1438 self.registers.dmacfg.write(DMACFG::DMAEN::CLEAR);
1440
1441 self.registers.dcx.set(0);
1443
1444 self.registers.intclr.set(0xFFFF_FFFF);
1446
1447 self.spi_cs.map(|cs| cs.activate());
1449
1450 self.registers.cmd.write(
1452 CMD::TSIZE.val(burst_len as u32)
1453 + CMD::CMDSEL.val(1)
1454 + CMD::CONT::CLEAR
1455 + CMD::CMD::WRITE
1456 + CMD::OFFSETCNT.val(0_u32)
1457 + CMD::OFFSETLO.val(0),
1458 );
1459
1460 self.registers.fifopush.set(val as u32);
1461
1462 if self.registers.fifoptr.read(FIFOPTR::FIFO1SIZ) > 0 {
1463 let d = self.registers.fifopop.get().to_ne_bytes();
1464
1465 self.spi_cs.map(|cs| cs.deactivate());
1466 return Ok(d[0]);
1467 }
1468
1469 self.spi_cs.map(|cs| cs.deactivate());
1470
1471 Err(ErrorCode::FAIL)
1472 }
1473
1474 fn specify_chip_select(&self, cs: Self::ChipSelect) -> Result<(), ErrorCode> {
1475 cs.pin.make_output();
1476 cs.deactivate();
1477 self.spi_cs.set(cs);
1478
1479 Ok(())
1480 }
1481
1482 fn set_rate(&self, rate: u32) -> Result<u32, ErrorCode> {
1483 if self.op.get() != Operation::SPI && self.op.get() != Operation::None {
1484 return Err(ErrorCode::BUSY);
1485 }
1486
1487 let div: u32 = 48000000 / rate; let n = div.trailing_zeros().max(6);
1489
1490 let div3 = u32::from(
1491 (rate < (48000000 / 16384))
1492 || ((rate >= (48000000 / 3)) && (rate <= ((48000000 / 2) - 1))),
1493 );
1494 let denom = (1 << n) * (1 + (div3 * 2));
1495 let tot_per = if div % denom > 0 {
1496 (div / denom) + 1
1497 } else {
1498 div / denom
1499 };
1500 let v1 = 31 - tot_per.leading_zeros();
1501 let fsel = if v1 > 7 { v1 + n - 6 } else { n + 1 };
1502
1503 if fsel > 7 {
1504 return Err(ErrorCode::NOSUPPORT);
1505 }
1506
1507 let diven = u32::from((rate >= (48000000 / 4)) || ((1 << (fsel - 1)) == div));
1508 let low_per = if self.spi_phase.get() == ClockPhase::SampleLeading {
1509 (tot_per - 1) / 2
1510 } else {
1511 (tot_per - 2) / 2
1512 };
1513
1514 self.registers.clkcfg.write(
1515 CLKCFG::TOTPER.val(tot_per - 1)
1516 + CLKCFG::LOWPER.val(low_per)
1517 + CLKCFG::DIVEN.val(diven)
1518 + CLKCFG::DIV3.val(div3)
1519 + CLKCFG::FSEL.val(fsel)
1520 + CLKCFG::IOCLKEN::SET,
1521 );
1522
1523 Ok(self.get_rate())
1524 }
1525
1526 fn get_rate(&self) -> u32 {
1527 let fsel = self.registers.clkcfg.read(CLKCFG::FSEL);
1528 let div3 = self.registers.clkcfg.read(CLKCFG::DIV3);
1529 let diven = self.registers.clkcfg.read(CLKCFG::DIVEN);
1530 let tot_per = self.registers.clkcfg.read(CLKCFG::TOTPER) + 1;
1531
1532 let denom_final = (1 << (fsel - 1)) * (1 + div3 * 2) * (1 + diven * (tot_per));
1533
1534 if ((48000000) % denom_final) > (denom_final / 2) {
1535 (48000000 / denom_final) + 1
1536 } else {
1537 48000000 / denom_final
1538 }
1539 }
1540
1541 fn set_polarity(&self, polarity: ClockPolarity) -> Result<(), ErrorCode> {
1542 if self.op.get() != Operation::SPI && self.op.get() != Operation::None {
1543 return Err(ErrorCode::BUSY);
1544 }
1545
1546 if polarity == ClockPolarity::IdleLow {
1547 self.registers.mspicfg.modify(MSPICFG::SPOL::CLEAR);
1548 } else {
1549 self.registers.mspicfg.modify(MSPICFG::SPOL::SET);
1550 }
1551
1552 Ok(())
1553 }
1554
1555 fn get_polarity(&self) -> ClockPolarity {
1556 if self.registers.mspicfg.is_set(MSPICFG::SPOL) {
1557 ClockPolarity::IdleHigh
1558 } else {
1559 ClockPolarity::IdleLow
1560 }
1561 }
1562
1563 fn set_phase(&self, phase: ClockPhase) -> Result<(), ErrorCode> {
1564 if self.op.get() != Operation::SPI && self.op.get() != Operation::None {
1565 return Err(ErrorCode::BUSY);
1566 }
1567
1568 let low_per = if self.spi_phase.get() == ClockPhase::SampleLeading {
1569 (self.registers.clkcfg.read(CLKCFG::LOWPER) * 2) + 1
1570 } else {
1571 (self.registers.clkcfg.read(CLKCFG::LOWPER) * 2) + 2
1572 };
1573
1574 if phase == ClockPhase::SampleLeading {
1575 self.registers
1576 .clkcfg
1577 .modify(CLKCFG::LOWPER.val((low_per - 1) / 2));
1578 } else {
1579 self.registers
1580 .clkcfg
1581 .modify(CLKCFG::LOWPER.val((low_per - 2) / 2));
1582 }
1583
1584 self.spi_phase.set(phase);
1585
1586 Ok(())
1587 }
1588
1589 fn get_phase(&self) -> ClockPhase {
1590 self.spi_phase.get()
1591 }
1592
1593 fn hold_low(&self) {
1594 self.spi_cs.map(|cs| cs.activate());
1595 }
1596
1597 fn release_low(&self) {
1598 self.spi_cs.map(|cs| cs.deactivate());
1599 }
1600}