@@ -13,6 +13,9 @@ use embassy_embedded_hal::SetConfig;
13
13
use embassy_hal_internal:: { Peri , PeripheralType } ;
14
14
use embassy_sync:: waitqueue:: AtomicWaker ;
15
15
pub use embedded_hal_02:: spi:: { Mode , Phase , Polarity , MODE_0 , MODE_1 , MODE_2 , MODE_3 } ;
16
+ #[ cfg( feature = "_nrf54l" ) ]
17
+ pub use pac:: spim:: vals:: Order as BitOrder ;
18
+ #[ cfg( not( feature = "_nrf54l" ) ) ]
16
19
pub use pac:: spim:: vals:: { Frequency , Order as BitOrder } ;
17
20
18
21
use crate :: chip:: { EASY_DMA_SIZE , FORCE_COPY_BUFFER_SIZE } ;
@@ -36,9 +39,17 @@ pub enum Error {
36
39
#[ non_exhaustive]
37
40
#[ derive( Clone ) ]
38
41
pub struct Config {
42
+ #[ cfg( not( feature = "_nrf54l" ) ) ]
39
43
/// Frequency
40
44
pub frequency : Frequency ,
41
45
46
+ #[ cfg( feature = "_nrf54l" ) ]
47
+ /// The prescaler is used to set the SPI frequency. The frequency is `core_clock/prescaler`.
48
+ /// The core_clock in the MCU PD is 128 MHz. In the PERI and LP PDs, it is 16 MHz. The
49
+ /// prescaler must be an *even* value in the range [4,126] for the MCD PD and [2,126] for the
50
+ /// PERI and LP PDs.
51
+ pub prescaler : u8 ,
52
+
42
53
/// SPI mode
43
54
pub mode : Mode ,
44
55
@@ -58,10 +69,27 @@ pub struct Config {
58
69
pub mosi_drive : OutputDrive ,
59
70
}
60
71
72
+ #[ cfg( not( feature = "_nrf54l" ) ) ]
73
+ /// SPIM configuration error
74
+ pub type ConfigError = ( ) ;
75
+
76
+ #[ cfg( feature = "_nrf54l" ) ]
77
+ /// SPIM configuration error
78
+ #[ derive( Debug , Clone , Copy , PartialEq , Eq ) ]
79
+ #[ cfg_attr( feature = "defmt" , derive( defmt:: Format ) ) ]
80
+ #[ non_exhaustive]
81
+ pub enum ConfigError {
82
+ /// Invalid prescaler
83
+ InvalidPrescaler ( u8 ) ,
84
+ }
85
+
61
86
impl Default for Config {
62
87
fn default ( ) -> Self {
63
88
Self {
89
+ #[ cfg( not( feature = "_nrf54l" ) ) ]
64
90
frequency : Frequency :: M1 ,
91
+ #[ cfg( feature = "_nrf54l" ) ]
92
+ prescaler : 16 , // 8 MHz in MCU PD and 1 MHz in PERI and LP PDs
65
93
mode : MODE_0 ,
66
94
bit_order : BitOrder :: MSB_FIRST ,
67
95
orc : 0x00 ,
@@ -230,13 +258,29 @@ impl<'d, T: Instance> Spim<'d, T> {
230
258
231
259
// Set up the DMA read.
232
260
let ( rx_ptr, rx_len) = xfer_params ( rx as * mut u8 as _ , rx. len ( ) as _ , offset, length) ;
233
- r. rxd ( ) . ptr ( ) . write_value ( rx_ptr) ;
234
- r. rxd ( ) . maxcnt ( ) . write ( |w| w. set_maxcnt ( rx_len as _ ) ) ;
261
+ #[ cfg( not( feature = "_nrf54l" ) ) ]
262
+ {
263
+ r. rxd ( ) . ptr ( ) . write_value ( rx_ptr) ;
264
+ r. rxd ( ) . maxcnt ( ) . write ( |w| w. set_maxcnt ( rx_len as _ ) ) ;
265
+ }
266
+ #[ cfg( feature = "_nrf54l" ) ]
267
+ {
268
+ r. dma ( ) . rx ( ) . ptr ( ) . write_value ( rx_ptr) ;
269
+ r. dma ( ) . rx ( ) . maxcnt ( ) . write ( |w| w. set_maxcnt ( rx_len as _ ) ) ;
270
+ }
235
271
236
272
// Set up the DMA write.
237
273
let ( tx_ptr, tx_len) = xfer_params ( tx as * const u8 as _ , tx. len ( ) as _ , offset, length) ;
238
- r. txd ( ) . ptr ( ) . write_value ( tx_ptr) ;
239
- r. txd ( ) . maxcnt ( ) . write ( |w| w. set_maxcnt ( tx_len as _ ) ) ;
274
+ #[ cfg( not( feature = "_nrf54l" ) ) ]
275
+ {
276
+ r. txd ( ) . ptr ( ) . write_value ( tx_ptr) ;
277
+ r. txd ( ) . maxcnt ( ) . write ( |w| w. set_maxcnt ( tx_len as _ ) ) ;
278
+ }
279
+ #[ cfg( feature = "_nrf54l" ) ]
280
+ {
281
+ r. dma ( ) . tx ( ) . ptr ( ) . write_value ( tx_ptr) ;
282
+ r. dma ( ) . tx ( ) . maxcnt ( ) . write ( |w| w. set_maxcnt ( tx_len as _ ) ) ;
283
+ }
240
284
241
285
/*
242
286
trace!("XFER: offset: {}, length: {}", offset, length);
@@ -601,9 +645,18 @@ impl<'d, T: Instance> embedded_hal_async::spi::SpiBus<u8> for Spim<'d, T> {
601
645
602
646
impl < ' d , T : Instance > SetConfig for Spim < ' d , T > {
603
647
type Config = Config ;
604
- type ConfigError = ( ) ;
648
+ type ConfigError = ConfigError ;
605
649
fn set_config ( & mut self , config : & Self :: Config ) -> Result < ( ) , Self :: ConfigError > {
606
650
let r = T :: regs ( ) ;
651
+
652
+ #[ cfg( feature = "_nrf54l" ) ]
653
+ {
654
+ let min = if r. as_ptr ( ) == pac:: SPIM00 . as_ptr ( ) { 4 } else { 2 } ;
655
+ if config. prescaler % 2 != 0 || config. prescaler < min || config. prescaler > 126 {
656
+ return Err ( Self :: ConfigError :: InvalidPrescaler ( config. prescaler ) ) ;
657
+ }
658
+ }
659
+
607
660
// Configure mode.
608
661
let mode = config. mode ;
609
662
r. config ( ) . write ( |w| {
@@ -629,8 +682,10 @@ impl<'d, T: Instance> SetConfig for Spim<'d, T> {
629
682
} ) ;
630
683
631
684
// Configure frequency.
632
- let frequency = config. frequency ;
633
- r. frequency ( ) . write ( |w| w. set_frequency ( frequency) ) ;
685
+ #[ cfg( not( feature = "_nrf54l" ) ) ]
686
+ r. frequency ( ) . write ( |w| w. set_frequency ( config. frequency ) ) ;
687
+ #[ cfg( feature = "_nrf54l" ) ]
688
+ r. prescaler ( ) . write ( |w| w. set_divisor ( config. prescaler ) ) ;
634
689
635
690
// Set over-read character
636
691
let orc = config. orc ;
0 commit comments