1use crate::dma::DMAChannel;
14use crate::dma::DMAClient;
15use crate::dma::DMAPeripheral;
16use crate::pm;
17use core::cell::Cell;
18use core::cmp;
19use kernel::ErrorCode;
20use kernel::hil::spi;
21use kernel::hil::spi::ClockPhase;
22use kernel::hil::spi::ClockPolarity;
23use kernel::hil::spi::SpiMasterClient;
24use kernel::hil::spi::SpiSlaveClient;
25use kernel::platform::chip::ClockInterface;
26use kernel::utilities::StaticRef;
27use kernel::utilities::cells::OptionalCell;
28use kernel::utilities::leasable_buffer::SubSliceMut;
29use kernel::utilities::peripheral_management::{PeripheralManagement, PeripheralManager};
30use kernel::utilities::registers::interfaces::{ReadWriteable, Readable, Writeable};
31use kernel::utilities::registers::{
32 self, ReadOnly, ReadWrite, WriteOnly, register_bitfields, register_structs,
33};
34
35register_structs! {
36 pub SpiRegisters {
37 (0x000 => cr: WriteOnly<u32, Control::Register>),
38 (0x004 => mr: ReadWrite<u32, Mode::Register>),
39 (0x008 => rdr: ReadOnly<u32>),
40 (0x00C => tdr: WriteOnly<u32, TransmitData::Register>),
41 (0x010 => sr: ReadOnly<u32, Status::Register>),
42 (0x014 => ier: WriteOnly<u32, InterruptFlags::Register>),
43 (0x018 => idr: WriteOnly<u32, InterruptFlags::Register>),
44 (0x01C => imr: ReadOnly<u32, InterruptFlags::Register>),
45 (0x020 => _reserved0: [ReadOnly<u32>; 4]),
46 (0x030 => csr: [ReadWrite<u32, ChipSelectParams::Register>; 4]),
47 (0x040 => _reserved1: [ReadOnly<u32>; 41]),
48 (0x0E4 => wpcr: ReadWrite<u32, WriteProtectionControl::Register>),
49 (0x0E8 => wpsr: ReadOnly<u32>),
50 (0x0EC => _reserved2: [ReadOnly<u32>; 3]),
51 (0x0F8 => features: ReadOnly<u32>),
52 (0x0FC => version: ReadOnly<u32>),
53 (0x100 => @END),
54 }
55}
56
57register_bitfields![u32,
58 Control [
59 LASTXFER 24,
60 FLUSHFIFO 8,
61 SWRST 7,
62 SPIDIS 1,
63 SPIEN 0
64 ],
65
66 Mode [
68 DLYBCS OFFSET(24) NUMBITS(8) [],
70 PCS OFFSET(16) NUMBITS(4) [
72 PCS0 = 0b1110,
74 PCS1 = 0b1101,
75 PCS2 = 0b1011,
76 PCS3 = 0b0111
77 ],
78 LLB OFFSET( 7) NUMBITS(1) [],
80 RXFIFOEN OFFSET( 6) NUMBITS(1) [],
82 MODFDIS OFFSET( 4) NUMBITS(1) [],
84 PCSDEC OFFSET( 2) NUMBITS(1) [],
86 PS OFFSET( 1) NUMBITS(1) [],
88 MSTR OFFSET( 0) NUMBITS(1) []
90 ],
91
92 TransmitData [
93 LASTXFER OFFSET(24) NUMBITS(1),
94 PCS OFFSET(16) NUMBITS(4),
95 TD OFFSET(0) NUMBITS(16)
96 ],
97
98 Status [
99 SPIENS OFFSET(16),
100 UNDES OFFSET(10),
101 TXEMPTY OFFSET(9),
102 NSSR OFFSET(8),
103 OVRES OFFSET(3),
104 MODF OFFSET(2),
105 TDRE OFFSET(1),
106 RDRF OFFSET(0)
107 ],
108
109 InterruptFlags [
110 UNDES 10,
111 TXEMPTY 9,
112 NSSR 8,
113 OVRES 3,
114 MODF 2,
115 TDRE 1,
116 RDRF 0
117 ],
118
119 ChipSelectParams [
120 DLYBCT OFFSET(24) NUMBITS(8) [],
121 DLYBS OFFSET(16) NUMBITS(8) [],
122 SCBR OFFSET(8) NUMBITS(8) [],
123 BITS OFFSET(4) NUMBITS(8) [
124 Eight = 0,
125 Nine = 1,
126 Ten = 2,
127 Eleven = 3,
128 Twelve = 4,
129 Thirteen = 5,
130 Fourteen = 6,
131 Fifteen = 7,
132 Sixteen = 8,
133 Four = 9,
134 Five = 10,
135 Six = 11,
136 Seven = 12
137 ],
138 CSAAT OFFSET(3) NUMBITS(1) [
139 ActiveAfterTransfer = 1,
140 InactiveAfterTransfer = 0
141 ],
142 CSNAAT OFFSET(2) NUMBITS(1) [
143 DoNotRiseBetweenTransfers = 0,
144 RiseBetweenTransfers = 1
145 ],
146 NCPHA OFFSET(1) NUMBITS(1) [
147 CaptureLeading = 1,
148 CaptureTrailing = 0
149 ],
150 CPOL OFFSET(0) NUMBITS(1) [
151 InactiveHigh = 1,
152 InactiveLow = 0
153 ]
154 ],
155
156 WriteProtectionControl [
157 SPIWPKEY OFFSET(8) NUMBITS(24) [
158 Key = 0x535049
159 ],
160 SPIWPEN OFFSET(0) NUMBITS(1) []
161 ]
162];
163
164#[allow(unused_variables, dead_code)]
165mod spi_consts {
167 pub mod rdr {
168 pub const RD: u32 = 0xFFFF;
169 }
170
171 pub mod tdr {
172 pub const TD: u32 = 0xFFFF;
173 }
176}
177
178#[derive(Copy, Clone)]
180pub enum Peripheral {
181 Peripheral0,
182 Peripheral1,
183 Peripheral2,
184 Peripheral3,
185}
186
187impl spi::cs::IntoChipSelect<Peripheral, spi::cs::ActiveLow> for Peripheral {
188 fn into_cs(self) -> Peripheral {
189 self
190 }
191}
192
193#[derive(Copy, Clone, PartialEq)]
194pub enum SpiRole {
195 SpiMaster,
196 SpiSlave,
197}
198
199pub struct SpiHw<'a> {
201 client: OptionalCell<&'a dyn SpiMasterClient>,
202 dma_read: OptionalCell<&'static DMAChannel>,
203 dma_write: OptionalCell<&'static DMAChannel>,
204 transfers_in_progress: Cell<u8>,
207 dma_length: Cell<usize>,
208
209 slave_client: OptionalCell<&'a dyn SpiSlaveClient>,
211 role: Cell<SpiRole>,
212 pm: &'a pm::PowerManager,
213}
214
215const SPI_BASE: StaticRef<SpiRegisters> =
216 unsafe { StaticRef::new(0x40008000 as *const SpiRegisters) };
217
218impl PeripheralManagement<pm::Clock> for SpiHw<'_> {
219 type RegisterType = SpiRegisters;
220
221 fn get_registers(&self) -> &SpiRegisters {
222 &SPI_BASE
223 }
224
225 fn get_clock(&self) -> &pm::Clock {
226 &pm::Clock::PBA(pm::PBAClock::SPI)
227 }
228
229 fn before_peripheral_access(&self, clock: &pm::Clock, _: &SpiRegisters) {
230 clock.enable();
231 }
232
233 fn after_peripheral_access(&self, clock: &pm::Clock, registers: &SpiRegisters) {
234 if !registers.sr.is_set(Status::SPIENS) {
235 clock.disable();
236 }
237 }
238}
239
240type SpiRegisterManager<'a, 'm> = PeripheralManager<'m, SpiHw<'a>, pm::Clock>;
241
242impl<'a> SpiHw<'a> {
243 pub const fn new(pm: &'a pm::PowerManager) -> SpiHw<'a> {
245 SpiHw {
246 client: OptionalCell::empty(),
247 dma_read: OptionalCell::empty(),
248 dma_write: OptionalCell::empty(),
249 transfers_in_progress: Cell::new(0),
250 dma_length: Cell::new(0),
251
252 slave_client: OptionalCell::empty(),
253 role: Cell::new(SpiRole::SpiMaster),
254 pm,
255 }
256 }
257
258 fn init_as_role(&self, spi: &SpiRegisterManager<'a, '_>, role: SpiRole) {
259 self.role.set(role);
260
261 if role == SpiRole::SpiMaster {
262 spi.registers.cr.write(Control::LASTXFER::SET);
264 }
265
266 let csr = self.get_active_csr(spi);
268 csr.modify(ChipSelectParams::BITS::Eight);
269
270 let mode = match self.role.get() {
272 SpiRole::SpiMaster => Mode::MSTR::SET,
273 SpiRole::SpiSlave => Mode::MSTR::CLEAR,
274 };
275
276 spi.registers.mr.modify(mode + Mode::MODFDIS::SET);
278 }
279
280 fn enable(&self) {
281 let spi = &SpiRegisterManager::new(self);
282
283 spi.registers.cr.write(Control::SPIEN::SET);
284
285 if self.role.get() == SpiRole::SpiSlave {
286 spi.registers.ier.write(InterruptFlags::NSSR::SET); }
288 }
289
290 fn disable(&self) {
291 let spi = &SpiRegisterManager::new(self);
292
293 while !spi.registers.sr.is_set(Status::TXEMPTY) {}
297
298 self.dma_read.map(|read| read.disable());
299 self.dma_write.map(|write| write.disable());
300 spi.registers.cr.write(Control::SPIDIS::SET);
301
302 if self.role.get() == SpiRole::SpiSlave {
303 spi.registers.idr.write(InterruptFlags::NSSR::SET); }
305 }
306
307 pub fn set_baud_rate(&self, rate: u32) -> u32 {
318 let mut real_rate = rate;
320 let clock = self.pm.get_system_frequency();
321
322 if real_rate < 188235 {
323 real_rate = 188235;
324 }
325 if real_rate > clock {
326 real_rate = clock;
327 }
328
329 let mut scbr = clock / real_rate;
331 if !clock.is_multiple_of(real_rate) && scbr != 0xFF {
336 scbr += 1;
337 }
338 let spi = &SpiRegisterManager::new(self);
339 let csr = self.get_active_csr(spi);
340 csr.modify(ChipSelectParams::SCBR.val(scbr));
341 clock / scbr
342 }
343
344 fn get_baud_rate(&self) -> u32 {
345 let spi = &SpiRegisterManager::new(self);
346 let clock = 48000000;
347 let scbr = self.get_active_csr(spi).read(ChipSelectParams::SCBR);
348 clock / scbr
349 }
350
351 fn set_polarity(&self, polarity: ClockPolarity) {
352 let spi = &SpiRegisterManager::new(self);
353 let csr = self.get_active_csr(spi);
354 match polarity {
355 ClockPolarity::IdleHigh => csr.modify(ChipSelectParams::CPOL::InactiveHigh),
356 ClockPolarity::IdleLow => csr.modify(ChipSelectParams::CPOL::InactiveLow),
357 }
358 }
359
360 fn get_polarity(&self) -> ClockPolarity {
361 let spi = &SpiRegisterManager::new(self);
362 let csr = self.get_active_csr(spi);
363 if csr.matches_all(ChipSelectParams::CPOL::InactiveLow) {
364 ClockPolarity::IdleLow
365 } else {
366 ClockPolarity::IdleHigh
367 }
368 }
369
370 fn set_phase(&self, phase: ClockPhase) {
371 let spi = &SpiRegisterManager::new(self);
372 let csr = self.get_active_csr(spi);
373 match phase {
374 ClockPhase::SampleLeading => csr.modify(ChipSelectParams::NCPHA::CaptureLeading),
375 ClockPhase::SampleTrailing => csr.modify(ChipSelectParams::NCPHA::CaptureTrailing),
376 }
377 }
378
379 fn get_phase(&self) -> ClockPhase {
380 let spi = &SpiRegisterManager::new(self);
381 let csr = self.get_active_csr(spi);
382 if csr.matches_all(ChipSelectParams::NCPHA::CaptureTrailing) {
383 ClockPhase::SampleTrailing
384 } else {
385 ClockPhase::SampleLeading
386 }
387 }
388
389 fn get_active_peripheral(&self, spi: &SpiRegisterManager<'a, '_>) -> Peripheral {
391 if self.role.get() == SpiRole::SpiMaster {
392 if spi.registers.mr.matches_all(Mode::PCS::PCS3) {
393 Peripheral::Peripheral3
394 } else if spi.registers.mr.matches_all(Mode::PCS::PCS2) {
395 Peripheral::Peripheral2
396 } else if spi.registers.mr.matches_all(Mode::PCS::PCS1) {
397 Peripheral::Peripheral1
398 } else {
399 Peripheral::Peripheral0
401 }
402 } else {
403 Peripheral::Peripheral0
405 }
406 }
407
408 fn get_active_csr<'s>(
411 &'s self,
412 spi: &SpiRegisterManager<'a, 's>,
413 ) -> &'s registers::ReadWrite<u32, ChipSelectParams::Register> {
414 match self.get_active_peripheral(spi) {
415 Peripheral::Peripheral0 => &spi.registers.csr[0],
416 Peripheral::Peripheral1 => &spi.registers.csr[1],
417 Peripheral::Peripheral2 => &spi.registers.csr[2],
418 Peripheral::Peripheral3 => &spi.registers.csr[3],
419 }
420 }
421
422 pub fn set_dma(&self, read: &'static DMAChannel, write: &'static DMAChannel) {
424 self.dma_read.set(read);
425 self.dma_write.set(write);
426 }
427
428 pub fn handle_interrupt(&self) {
429 let spi = &SpiRegisterManager::new(self);
430
431 self.slave_client.map(|client| {
432 if spi.registers.sr.is_set(Status::NSSR) {
433 client.chip_selected()
435 }
436 });
439 }
440
441 fn read_write_bytes(
450 &self,
451 write_buffer: Option<SubSliceMut<'static, u8>>,
452 read_buffer: Option<SubSliceMut<'static, u8>>,
453 ) -> Result<
454 (),
455 (
456 ErrorCode,
457 Option<SubSliceMut<'static, u8>>,
458 Option<SubSliceMut<'static, u8>>,
459 ),
460 > {
461 let count = match (&write_buffer, &read_buffer) {
462 (Some(ref wb), Some(ref rb)) => cmp::min(wb.len(), rb.len()),
463 (Some(ref wb), None) => wb.len(),
464 (None, Some(ref rb)) => rb.len(),
465 (None, None) => return Err((ErrorCode::INVAL, write_buffer, read_buffer)),
466 };
467
468 self.enable();
470
471 self.dma_length.set(count);
473
474 self.transfers_in_progress.set(0);
477
478 read_buffer.map(|rbuf| {
486 self.transfers_in_progress
487 .set(self.transfers_in_progress.get() + 1);
488 self.dma_read.map(move |read| {
489 read.enable();
490 read.do_transfer(DMAPeripheral::SPI_RX, rbuf.take(), count);
491 });
492 });
493
494 write_buffer.map(|buf| {
498 self.transfers_in_progress
499 .set(self.transfers_in_progress.get() + 1);
500 self.dma_write.map(move |write| {
501 write.enable();
502 write.do_transfer(DMAPeripheral::SPI_TX, buf.take(), count);
503 });
504 });
505
506 Ok(())
507 }
508}
509
510impl<'a> spi::SpiMaster<'a> for SpiHw<'a> {
511 type ChipSelect = Peripheral;
512
513 fn set_client(&self, client: &'a dyn SpiMasterClient) {
514 self.client.set(client);
515 }
516
517 fn init(&self) -> Result<(), ErrorCode> {
520 let spi = &SpiRegisterManager::new(self);
521 self.init_as_role(spi, SpiRole::SpiMaster);
522 Ok(())
523 }
524
525 fn is_busy(&self) -> bool {
526 self.transfers_in_progress.get() != 0
527 }
528
529 fn read_write_bytes(
540 &self,
541 write_buffer: SubSliceMut<'static, u8>,
542 read_buffer: Option<SubSliceMut<'static, u8>>,
543 ) -> Result<
544 (),
545 (
546 ErrorCode,
547 SubSliceMut<'static, u8>,
548 Option<SubSliceMut<'static, u8>>,
549 ),
550 > {
551 if self.is_busy() {
553 return Err((ErrorCode::BUSY, write_buffer, read_buffer));
554 }
555
556 if let Err((err, write_buffer, read_buffer)) =
557 self.read_write_bytes(Some(write_buffer), read_buffer)
558 {
559 Err((
560 err,
561 write_buffer.unwrap_or((&mut [] as &mut [u8]).into()),
562 read_buffer,
563 ))
564 } else {
565 Ok(())
566 }
567 }
568
569 fn set_rate(&self, rate: u32) -> Result<u32, ErrorCode> {
570 Ok(self.set_baud_rate(rate))
571 }
572
573 fn get_rate(&self) -> u32 {
574 self.get_baud_rate()
575 }
576
577 fn set_polarity(&self, polarity: ClockPolarity) -> Result<(), ErrorCode> {
578 self.set_polarity(polarity);
579 Ok(())
580 }
581
582 fn get_polarity(&self) -> ClockPolarity {
583 self.get_polarity()
584 }
585
586 fn set_phase(&self, phase: ClockPhase) -> Result<(), ErrorCode> {
587 self.set_phase(phase);
588 Ok(())
589 }
590
591 fn get_phase(&self) -> ClockPhase {
592 self.get_phase()
593 }
594
595 fn hold_low(&self) {
596 let spi = &SpiRegisterManager::new(self);
597 let csr = self.get_active_csr(spi);
598 csr.modify(ChipSelectParams::CSAAT::ActiveAfterTransfer);
599 }
600
601 fn release_low(&self) {
602 let spi = &SpiRegisterManager::new(self);
603 let csr = self.get_active_csr(spi);
604 csr.modify(ChipSelectParams::CSAAT::InactiveAfterTransfer);
605 }
606
607 fn specify_chip_select(&self, cs: Self::ChipSelect) -> Result<(), ErrorCode> {
608 if self.role.get() == SpiRole::SpiMaster {
610 let spi = &SpiRegisterManager::new(self);
611 let mr = match cs {
612 Peripheral::Peripheral0 => Mode::PCS::PCS0,
613 Peripheral::Peripheral1 => Mode::PCS::PCS1,
614 Peripheral::Peripheral2 => Mode::PCS::PCS2,
615 Peripheral::Peripheral3 => Mode::PCS::PCS3,
616 };
617 spi.registers.mr.modify(mr);
618 Ok(())
619 } else {
620 Err(ErrorCode::INVAL)
621 }
622 }
623}
624
625impl<'a> spi::SpiSlave<'a> for SpiHw<'a> {
626 fn set_client(&self, client: Option<&'a dyn SpiSlaveClient>) {
628 self.slave_client.insert(client);
629 }
630
631 fn has_client(&self) -> bool {
632 self.slave_client.is_some()
633 }
634
635 fn init(&self) -> Result<(), ErrorCode> {
636 let spi = &SpiRegisterManager::new(self);
637 self.init_as_role(spi, SpiRole::SpiSlave);
638 Ok(())
639 }
640
641 fn set_write_byte(&self, write_byte: u8) {
644 let spi = SpiRegisterManager::new(self);
645 spi.registers.tdr.set(write_byte as u32);
646 }
647
648 fn read_write_bytes(
654 &self,
655 write_buffer: Option<&'static mut [u8]>,
656 read_buffer: Option<&'static mut [u8]>,
657 len: usize,
658 ) -> Result<
659 (),
660 (
661 ErrorCode,
662 Option<&'static mut [u8]>,
663 Option<&'static mut [u8]>,
664 ),
665 > {
666 let write_buffer = write_buffer.map(|b| {
667 let mut buf: SubSliceMut<u8> = b.into();
668 if buf.len() > len {
669 buf.slice(..len);
670 }
671 buf
672 });
673 let read_buffer = read_buffer.map(|b| {
674 let mut buf: SubSliceMut<u8> = b.into();
675 if buf.len() > len {
676 buf.slice(..len);
677 }
678 buf
679 });
680
681 if let Err((e, mwb, mrb)) = self.read_write_bytes(write_buffer, read_buffer) {
682 Err((e, mwb.map(|b| b.take()), mrb.map(|b| b.take())))
683 } else {
684 Ok(())
685 }
686 }
687
688 fn set_polarity(&self, polarity: ClockPolarity) -> Result<(), ErrorCode> {
689 self.set_polarity(polarity);
690 Ok(())
691 }
692
693 fn get_polarity(&self) -> ClockPolarity {
694 self.get_polarity()
695 }
696
697 fn set_phase(&self, phase: ClockPhase) -> Result<(), ErrorCode> {
698 self.set_phase(phase);
699 Ok(())
700 }
701
702 fn get_phase(&self) -> ClockPhase {
703 self.get_phase()
704 }
705}
706
707impl DMAClient for SpiHw<'_> {
708 fn transfer_done(&self, _pid: DMAPeripheral) {
709 self.transfers_in_progress
717 .set(self.transfers_in_progress.get() - 1);
718
719 if self.transfers_in_progress.get() == 0 {
720 let txbuf = self.dma_write.map_or(None, |dma| {
721 let buf = dma.abort_transfer();
722 dma.disable();
723 buf
724 });
725
726 let rxbuf = self.dma_read.map_or(None, |dma| {
727 let buf = dma.abort_transfer();
728 dma.disable();
729 buf
730 });
731
732 let len = self.dma_length.get();
733 self.dma_length.set(0);
734
735 match self.role.get() {
736 SpiRole::SpiMaster => {
737 self.client.map(|cb| {
738 txbuf.map(|txbuf| {
739 cb.read_write_done(txbuf.into(), rxbuf.map(|b| b.into()), Ok(len));
740 });
741 });
742 }
743 SpiRole::SpiSlave => {
744 self.slave_client.map(|cb| {
745 cb.read_write_done(txbuf, rxbuf, len, Ok(()));
746 });
747 }
748 }
749 if self.transfers_in_progress.get() == 0 {
750 self.disable();
751 }
752 }
753 }
754}