1use crate::clocks;
6use core::cell::Cell;
7use core::cmp;
8use kernel::hil;
9use kernel::hil::spi::cs::ChipSelectPolar;
10use kernel::hil::spi::SpiMaster;
11use kernel::hil::spi::SpiMasterClient;
12use kernel::hil::spi::{ClockPhase, ClockPolarity};
13use kernel::utilities::cells::MapCell;
14use kernel::utilities::cells::OptionalCell;
15use kernel::utilities::leasable_buffer::SubSliceMut;
16use kernel::utilities::registers::interfaces::{ReadWriteable, Readable, Writeable};
17use kernel::utilities::registers::{register_bitfields, register_structs, ReadOnly, ReadWrite};
18use kernel::utilities::StaticRef;
19use kernel::ErrorCode;
20
21const SPI_READ_IN_PROGRESS: u8 = 0b001;
22const SPI_WRITE_IN_PROGRESS: u8 = 0b010;
23const SPI_IN_PROGRESS: u8 = 0b100;
24const SPI_IDLE: u8 = 0b000;
25
26register_structs! {
27 SpiRegisters {
29 (0x000 => sspcr0: ReadWrite<u32, SSPCR0::Register>),
31 (0x004 => sspcr1: ReadWrite<u32, SSPCR1::Register>),
33 (0x008 => sspdr: ReadWrite<u32, SSPDR::Register>),
35 (0x00C => sspsr: ReadOnly<u32, SSPSR::Register>),
37 (0x010 => sspcpsr: ReadWrite<u32, SSPCPSR::Register>),
39 (0x014 => sspimsc: ReadWrite<u32, SSPIMSC::Register>),
41 (0x018 => sspris: ReadOnly<u32, SSPRIS::Register>),
43 (0x01C => sspmis: ReadOnly<u32, SSPMIS::Register>),
45 (0x020 => sspicr: ReadWrite<u32, SSPICR::Register>),
47 (0x024 => sspdmacr: ReadWrite<u32, SSPDMACR::Register>),
49 (0x028 => _reserved0),
50 (0xFE0 => sspperiphid0: ReadOnly<u32, SSPPERIPHID0::Register>),
52 (0xFE4 => sspperiphid1: ReadOnly<u32, SSPPERIPHID1::Register>),
54 (0xFE8 => sspperiphid2: ReadOnly<u32, SSPPERIPHID2::Register>),
56 (0xFEC => sspperiphid3: ReadOnly<u32, SSPPERIPHID3::Register>),
58 (0xFF0 => ssppcellid0: ReadOnly<u32, SSPPCELLID0::Register>),
60 (0xFF4 => ssppcellid1: ReadOnly<u32, SSPPCELLID1::Register>),
62 (0xFF8 => ssppcellid2: ReadOnly<u32, SSPPCELLID2::Register>),
64 (0xFFC => ssppcellid3: ReadOnly<u32, SSPPCELLID3::Register>),
66 (0x1000 => @END),
67 }
68}
69
70register_bitfields![u32,
71 SSPCR0 [
73 SCR OFFSET(8) NUMBITS(8) [],
75 SPH OFFSET(7) NUMBITS(1) [],
77 SPO OFFSET(6) NUMBITS(1) [],
79 FRF OFFSET(4) NUMBITS(2) [
81 MOTOROLA_SPI = 0b00,
82 TI_SINC_SERIAL = 0b01,
83 NAT_MICROWIRE = 0b10,
84 RESERVED = 0b11
85 ],
86 DSS OFFSET(0) NUMBITS(4) [
88 RESERVED_0 = 0b0000,
89 RESERVED_1 = 0b0001,
90 RESERVED_2 = 0b0010,
91 DATA_4_BIT = 0b0011,
92 DATA_5_BIT = 0b0100,
93 DATA_6_BIT = 0b0101,
94 DATA_7_BIT = 0b0110,
95 DATA_8_BIT = 0b0111,
96 DATA_9_BIT = 0b1000,
97 DATA_10_BIT = 0b1001,
98 DATA_11_BIT = 0b1010,
99 DATA_12_BIT = 0b1011,
100 DATA_13_BIT = 0b1100,
101 DATA_14_BIT = 0b1101,
102 DATA_15_BIT = 0b1110,
103 DATA_16_BIT = 0b1111
104 ]
105 ],
106 SSPCR1 [
108 SOD OFFSET(3) NUMBITS(1) [],
110 MS OFFSET(2) NUMBITS(1) [],
112 SSE OFFSET(1) NUMBITS(1) [],
114 LBM OFFSET(0) NUMBITS(1) []
116 ],
117 SSPDR [
119 DATA OFFSET(0) NUMBITS(16) []
121 ],
122 SSPSR [
124 BSY OFFSET(4) NUMBITS(1) [],
126 RFF OFFSET(3) NUMBITS(1) [],
128 RNE OFFSET(2) NUMBITS(1) [],
130 TNF OFFSET(1) NUMBITS(1) [],
132 TFE OFFSET(0) NUMBITS(1) []
134 ],
135 SSPCPSR [
137 CPSDVSR OFFSET(0) NUMBITS(8) []
139 ],
140 SSPIMSC [
142 TXIM OFFSET(3) NUMBITS(1) [],
144 RXIM OFFSET(2) NUMBITS(1) [],
146 RTIM OFFSET(1) NUMBITS(1) [],
148 RORIM OFFSET(0) NUMBITS(1) []
150 ],
151 SSPRIS [
153 TXRIS OFFSET(3) NUMBITS(1) [],
155 RXRIS OFFSET(2) NUMBITS(1) [],
157 RTRIS OFFSET(1) NUMBITS(1) [],
159 RORRIS OFFSET(0) NUMBITS(1) []
161 ],
162 SSPMIS [
164 TXMIS OFFSET(3) NUMBITS(1) [],
166 RXMIS OFFSET(2) NUMBITS(1) [],
168 RTMIS OFFSET(1) NUMBITS(1) [],
170 RORMIS OFFSET(0) NUMBITS(1) []
172 ],
173 SSPICR [
175 RTIC OFFSET(1) NUMBITS(1) [],
177 RORIC OFFSET(0) NUMBITS(1) []
179 ],
180 SSPDMACR [
182 TXDMAE OFFSET(1) NUMBITS(1) [],
184 RXDMAE OFFSET(0) NUMBITS(1) []
186 ],
187 SSPPERIPHID0 [
189 PARTNUMBER0 OFFSET(0) NUMBITS(8) []
191 ],
192 SSPPERIPHID1 [
194 DESIGNER0 OFFSET(4) NUMBITS(4) [],
196 PARTNUMBER1 OFFSET(0) NUMBITS(4) []
198 ],
199 SSPPERIPHID2 [
201 REVISION OFFSET(4) NUMBITS(4) [],
203 DESIGNER1 OFFSET(0) NUMBITS(4) []
205 ],
206 SSPPERIPHID3 [
208 CONFIGURATION OFFSET(0) NUMBITS(8) []
210 ],
211 SSPPCELLID0 [
213 SSPPCELLID0 OFFSET(0) NUMBITS(8) []
215 ],
216 SSPPCELLID1 [
218 SSPPCELLID1 OFFSET(0) NUMBITS(8) []
220 ],
221 SSPPCELLID2 [
223 SSPPCELLID2 OFFSET(0) NUMBITS(8) []
225 ],
226 SSPPCELLID3 [
228 SSPPCELLID3 OFFSET(0) NUMBITS(8) []
230 ]
231];
232
233const SPI0_BASE: StaticRef<SpiRegisters> =
234 unsafe { StaticRef::new(0x4003C000 as *const SpiRegisters) };
235
236const SPI1_BASE: StaticRef<SpiRegisters> =
237 unsafe { StaticRef::new(0x40040000 as *const SpiRegisters) };
238
239pub struct Spi<'a> {
240 registers: StaticRef<SpiRegisters>,
241 clocks: OptionalCell<&'a clocks::Clocks>,
242 master_client: OptionalCell<&'a dyn hil::spi::SpiMasterClient>,
243 active_slave: OptionalCell<ChipSelectPolar<'a, crate::gpio::RPGpioPin<'a>>>,
244
245 tx_buffer: MapCell<SubSliceMut<'static, u8>>,
246 tx_position: Cell<usize>,
247
248 rx_buffer: MapCell<SubSliceMut<'static, u8>>,
249 rx_position: Cell<usize>,
250 len: Cell<usize>,
251
252 transfers: Cell<u8>,
253 active_after: Cell<bool>,
254}
255
256impl<'a> Spi<'a> {
257 pub fn new_spi0() -> Self {
258 Self {
259 registers: SPI0_BASE,
260 clocks: OptionalCell::empty(),
261 master_client: OptionalCell::empty(),
262 active_slave: OptionalCell::empty(),
263
264 tx_buffer: MapCell::empty(),
265 tx_position: Cell::new(0),
266
267 rx_buffer: MapCell::empty(),
268 rx_position: Cell::new(0),
269
270 len: Cell::new(0),
271
272 transfers: Cell::new(SPI_IDLE),
273 active_after: Cell::new(false),
274 }
275 }
276
277 pub fn new_spi1() -> Self {
278 Self {
279 registers: SPI1_BASE,
280 clocks: OptionalCell::empty(),
281 master_client: OptionalCell::empty(),
282 active_slave: OptionalCell::empty(),
283
284 tx_buffer: MapCell::empty(),
285 tx_position: Cell::new(0),
286
287 rx_buffer: MapCell::empty(),
288 rx_position: Cell::new(0),
289
290 len: Cell::new(0),
291
292 transfers: Cell::new(SPI_IDLE),
293 active_after: Cell::new(false),
294 }
295 }
296
297 pub(crate) fn set_clocks(&self, clocks: &'a clocks::Clocks) {
298 self.clocks.set(clocks);
299 }
300
301 fn enable(&self) {
302 self.registers.sspcr1.modify(SSPCR1::SSE::SET);
303 }
304
305 fn disable(&self) {
306 self.registers.sspcr1.modify(SSPCR1::SSE::CLEAR);
307 }
308
309 pub fn handle_interrupt(&self) {
310 if self.registers.sspsr.is_set(SSPSR::TFE) {
311 if self.tx_buffer.is_some() {
313 while self.registers.sspsr.is_set(SSPSR::TNF)
314 && self.tx_position.get() < self.len.get()
315 {
316 self.tx_buffer.map(|buf| {
317 self.registers
319 .sspdr
320 .write(SSPDR::DATA.val(buf[self.tx_position.get()].into()));
321 self.tx_position.set(self.tx_position.get() + 1);
322 });
323 }
324 if self.tx_position.get() >= self.len.get() {
325 self.transfers
326 .set(self.transfers.get() & !SPI_WRITE_IN_PROGRESS);
327 }
328 } else {
329 self.registers.sspimsc.modify(SSPIMSC::TXIM::CLEAR);
330 }
331 }
332
333 while self.registers.sspsr.is_set(SSPSR::RNE) {
334 let byte = self.registers.sspdr.read(SSPDR::DATA) as u8;
335 if self.rx_buffer.is_some() {
336 if self.rx_position.get() < self.len.get() {
337 self.rx_buffer.map(|buf| {
338 buf[self.rx_position.get()] = byte;
339 });
340 self.rx_position.set(self.rx_position.get() + 1);
341 } else {
342 self.transfers
343 .set(self.transfers.get() & !SPI_READ_IN_PROGRESS);
344 }
345 }
346 }
347
348 if self.transfers.get() == SPI_IN_PROGRESS {
349 if !self.active_after.get() {
350 self.active_slave.map(|p| {
351 p.deactivate();
352 });
353 }
354 self.master_client.map(|client| {
355 self.registers.sspimsc.modify(SSPIMSC::TXIM::CLEAR);
356 self.registers.sspimsc.modify(SSPIMSC::RXIM::CLEAR);
357 self.disable();
358 self.transfers.set(SPI_IDLE);
359 self.tx_buffer.take().map(|buf| {
360 client.read_write_done(buf, self.rx_buffer.take(), Ok(self.len.get()))
361 });
362 });
363 }
364 }
365
366 fn read_write_bytes(
367 &self,
368 write_buffer: Option<SubSliceMut<'static, u8>>,
369 read_buffer: Option<SubSliceMut<'static, u8>>,
370 ) -> Result<
371 (),
372 (
373 ErrorCode,
374 Option<SubSliceMut<'static, u8>>,
375 Option<SubSliceMut<'static, u8>>,
376 ),
377 > {
378 if write_buffer.is_none() && read_buffer.is_none() {
379 return Err((ErrorCode::INVAL, write_buffer, read_buffer));
380 }
381
382 if self.transfers.get() == SPI_IDLE {
383 self.enable();
384 self.registers.sspimsc.modify(SSPIMSC::TXIM::CLEAR);
385 self.registers.sspimsc.modify(SSPIMSC::RXIM::CLEAR);
386 self.active_slave.map(|p| {
387 p.activate();
388 });
389
390 self.transfers.set(SPI_IN_PROGRESS);
391
392 let len = match (
393 write_buffer.as_ref().map(|b| b.len()),
394 read_buffer.as_ref().map(|b| b.len()),
395 ) {
396 (Some(wl), Some(rl)) => cmp::min(wl, rl),
397 (Some(wl), None) => wl,
398 (None, Some(rl)) => rl,
399 (None, None) => 0,
400 };
401
402 if write_buffer.is_some() {
403 self.transfers
404 .set(self.transfers.get() | SPI_WRITE_IN_PROGRESS);
405 }
406
407 if read_buffer.is_some() {
408 self.transfers
409 .set(self.transfers.get() | SPI_READ_IN_PROGRESS);
410 }
411
412 read_buffer.map(|buf| {
413 self.rx_buffer.replace(buf);
414 self.len.set(len);
415 self.rx_position.set(0);
416 self.registers.sspimsc.modify(SSPIMSC::RXIM::SET);
417 });
418
419 write_buffer.map(|buf| {
420 self.tx_buffer.replace(buf);
421 self.len.set(len);
422 self.tx_position.set(0);
423 self.registers.sspimsc.modify(SSPIMSC::TXIM::SET);
424 });
425
426 Ok(())
427 } else {
428 Err((ErrorCode::BUSY, write_buffer, read_buffer))
429 }
430 }
431
432 fn set_polarity(&self, polarity: ClockPolarity) -> Result<(), ErrorCode> {
435 if !self.is_busy() {
436 self.enable();
437 match polarity {
438 ClockPolarity::IdleHigh => self.registers.sspcr0.modify(SSPCR0::SPO::SET),
439 ClockPolarity::IdleLow => self.registers.sspcr0.modify(SSPCR0::SPO::CLEAR),
440 }
441 self.disable();
442 Ok(())
443 } else {
444 Err(ErrorCode::BUSY)
445 }
446 }
447
448 fn get_polarity(&self) -> ClockPolarity {
449 if !self.registers.sspcr0.is_set(SSPCR0::SPO) {
450 ClockPolarity::IdleLow
451 } else {
452 ClockPolarity::IdleHigh
453 }
454 }
455
456 fn set_phase(&self, phase: ClockPhase) -> Result<(), ErrorCode> {
459 if !self.is_busy() {
460 self.enable();
461 match phase {
462 ClockPhase::SampleLeading => self.registers.sspcr0.modify(SSPCR0::SPH::CLEAR),
463 ClockPhase::SampleTrailing => self.registers.sspcr0.modify(SSPCR0::SPH::SET),
464 }
465 self.disable();
466 Ok(())
467 } else {
468 Err(ErrorCode::BUSY)
469 }
470 }
471
472 fn get_phase(&self) -> ClockPhase {
473 if !self.registers.sspcr0.is_set(SSPCR0::SPH) {
474 ClockPhase::SampleLeading
475 } else {
476 ClockPhase::SampleTrailing
477 }
478 }
479
480 fn set_format(&self) {
481 self.registers.sspcr0.modify(SSPCR0::DSS::DATA_8_BIT);
482 self.registers.sspcr0.modify(SSPCR0::SPO::CLEAR);
483 self.registers.sspcr0.modify(SSPCR0::SPH::CLEAR);
484 }
485}
486
487impl<'a> SpiMaster<'a> for Spi<'a> {
488 type ChipSelect = ChipSelectPolar<'a, crate::gpio::RPGpioPin<'a>>;
489
490 fn set_client(&self, client: &'a dyn SpiMasterClient) {
491 self.master_client.set(client);
492 }
493
494 fn init(&self) -> Result<(), ErrorCode> {
495 match self.set_rate(16 * 1000 * 1000) {
496 Err(error) => Err(error),
497 Ok(_) => Ok(()),
498 }?;
499 self.set_format();
501
502 self.registers.sspdmacr.modify(SSPDMACR::TXDMAE::SET);
504 self.registers.sspdmacr.modify(SSPDMACR::RXDMAE::SET);
505
506 self.registers.sspcr1.modify(SSPCR1::MS::CLEAR);
508
509 Ok(())
510 }
511
512 fn is_busy(&self) -> bool {
513 self.transfers.get() != SPI_IDLE
515 }
516
517 fn read_write_bytes(
518 &self,
519 write_buffer: SubSliceMut<'static, u8>,
520 read_buffer: Option<SubSliceMut<'static, u8>>,
521 ) -> Result<
522 (),
523 (
524 ErrorCode,
525 SubSliceMut<'static, u8>,
526 Option<SubSliceMut<'static, u8>>,
527 ),
528 > {
529 if self.is_busy() {
530 return Err((ErrorCode::BUSY, write_buffer, read_buffer));
531 }
532
533 match self.read_write_bytes(Some(write_buffer), read_buffer) {
534 Err((error, some_write_buffer, read_buffer)) => {
536 Err((error, some_write_buffer.unwrap(), read_buffer))
537 }
538 Ok(()) => Ok(()),
539 }
540 }
541
542 fn write_byte(&self, out_val: u8) -> Result<(), ErrorCode> {
543 if !self.is_busy() {
544 while !self.registers.sspsr.is_set(SSPSR::TFE) {}
545
546 self.registers.sspdr.modify(SSPDR::DATA.val(out_val as u32));
547
548 Ok(())
549 } else {
550 Err(ErrorCode::BUSY)
551 }
552 }
553
554 fn read_byte(&self) -> Result<u8, ErrorCode> {
555 self.read_write_byte(0)
556 }
557
558 fn read_write_byte(&self, val: u8) -> Result<u8, ErrorCode> {
559 if !self.is_busy() {
560 self.write_byte(val)?;
561
562 while !self.registers.sspsr.is_set(SSPSR::RNE) {}
563
564 Ok(self.registers.sspdr.read(SSPDR::DATA) as u8)
565 } else {
566 Err(ErrorCode::BUSY)
567 }
568 }
569
570 fn specify_chip_select(&self, cs: Self::ChipSelect) -> Result<(), ErrorCode> {
571 if !self.is_busy() {
572 self.active_slave.set(cs);
573 Ok(())
574 } else {
575 Err(ErrorCode::BUSY)
576 }
577 }
578
579 fn set_rate(&self, baudrate: u32) -> Result<u32, ErrorCode> {
580 let freq_in = self.clocks.map_or(125_000_000, |clocks| {
581 clocks.get_frequency(clocks::Clock::Peripheral)
582 });
583
584 if baudrate > freq_in {
585 return Err(ErrorCode::INVAL);
586 }
587
588 let mut prescale = 0;
589 let mut postdiv = 0;
590
591 for p in (2..254).step_by(2) {
592 if (freq_in as u64) < (((p + 2) * 256) as u64 * baudrate as u64) {
593 prescale = p;
594 break;
595 }
596 }
597
598 for p in (2..256).rev() {
599 if (freq_in / (prescale * (p - 1))) > baudrate {
600 postdiv = p;
601 break;
602 }
603 }
604
605 if prescale > 0 && postdiv > 0 {
606 self.registers
607 .sspcpsr
608 .modify(SSPCPSR::CPSDVSR.val(prescale));
609 self.registers.sspcr0.modify(SSPCR0::SCR.val(postdiv - 1));
610
611 Ok(freq_in / (prescale * postdiv))
612 } else {
613 Err(ErrorCode::INVAL)
614 }
615 }
616
617 fn get_rate(&self) -> u32 {
618 let freq_in = self.clocks.map_or(125_000_000, |clocks| {
619 clocks.get_frequency(clocks::Clock::Peripheral)
620 });
621 let prescale = self.registers.sspcpsr.read(SSPCPSR::CPSDVSR);
622 let postdiv = self.registers.sspcr0.read(SSPCR0::SCR) + 1;
623 freq_in / (prescale * postdiv)
624 }
625
626 fn set_polarity(&self, polarity: ClockPolarity) -> Result<(), ErrorCode> {
627 self.set_polarity(polarity)
628 }
629
630 fn get_polarity(&self) -> ClockPolarity {
631 self.get_polarity()
632 }
633
634 fn set_phase(&self, phase: ClockPhase) -> Result<(), ErrorCode> {
635 self.set_phase(phase)
636 }
637
638 fn get_phase(&self) -> ClockPhase {
639 self.get_phase()
640 }
641
642 fn hold_low(&self) {
643 self.active_after.set(true);
644 }
645 fn release_low(&self) {
646 self.active_after.set(false);
647 }
648}