@@ -142,6 +142,8 @@ pub struct Config {
142
142
pub frequency : Hertz ,
143
143
/// Timings
144
144
pub timing : Timings ,
145
+ /// Half duplex mode, only MOSI is used.
146
+ pub half_duplex : bool ,
145
147
}
146
148
147
149
impl Default for Config {
@@ -151,6 +153,7 @@ impl Default for Config {
151
153
mode : MODE_0 ,
152
154
frequency : Hertz ( 10_000_000 ) ,
153
155
timing : Timings :: default ( ) ,
156
+ half_duplex : false ,
154
157
}
155
158
}
156
159
}
@@ -253,6 +256,36 @@ impl<'d> Spi<'d, Blocking> {
253
256
)
254
257
}
255
258
259
+ pub fn new_blocking_half_duplex < T : Instance > (
260
+ peri : impl Peripheral < P = T > + ' d ,
261
+ sclk : impl Peripheral < P = impl SclkPin < T > > + ' d ,
262
+ mosi : impl Peripheral < P = impl MosiPin < T > > + ' d ,
263
+ mut config : Config ,
264
+ ) -> Self {
265
+ into_ref ! ( sclk, mosi) ;
266
+
267
+ T :: add_resource_group ( 0 ) ;
268
+
269
+ mosi. set_as_alt ( mosi. alt_num ( ) ) ;
270
+ sclk. ioc_pad ( ) . func_ctl ( ) . modify ( |w| {
271
+ w. set_alt_select ( sclk. alt_num ( ) ) ;
272
+ w. set_loop_back ( true ) ;
273
+ } ) ;
274
+ config. half_duplex = true ;
275
+
276
+ Self :: new_inner (
277
+ peri,
278
+ Some ( sclk. map_into ( ) ) ,
279
+ Some ( mosi. map_into ( ) ) ,
280
+ None ,
281
+ None ,
282
+ None ,
283
+ None ,
284
+ None ,
285
+ config,
286
+ )
287
+ }
288
+
256
289
pub fn new_blocking_rxonly < T : Instance > (
257
290
peri : impl Peripheral < P = T > + ' d ,
258
291
sclk : impl Peripheral < P = impl SclkPin < T > > + ' d ,
@@ -406,6 +439,39 @@ impl<'d> Spi<'d, Async> {
406
439
)
407
440
}
408
441
442
+ pub fn new_half_duplex < T : Instance > (
443
+ peri : impl Peripheral < P = T > + ' d ,
444
+ sclk : impl Peripheral < P = impl SclkPin < T > > + ' d ,
445
+ mosi : impl Peripheral < P = impl MosiPin < T > > + ' d ,
446
+ tx_dma : impl Peripheral < P = impl TxDma < T > > + ' d ,
447
+ rx_dma : impl Peripheral < P = impl RxDma < T > > + ' d ,
448
+ mut config : Config ,
449
+ ) -> Self {
450
+ into_ref ! ( sclk, mosi) ;
451
+
452
+ T :: add_resource_group ( 0 ) ;
453
+
454
+ mosi. set_as_alt ( mosi. alt_num ( ) ) ;
455
+ sclk. ioc_pad ( ) . func_ctl ( ) . modify ( |w| {
456
+ w. set_alt_select ( sclk. alt_num ( ) ) ;
457
+ w. set_loop_back ( true ) ;
458
+ } ) ;
459
+
460
+ config. half_duplex = true ;
461
+
462
+ Self :: new_inner (
463
+ peri,
464
+ Some ( sclk. map_into ( ) ) ,
465
+ Some ( mosi. map_into ( ) ) ,
466
+ None ,
467
+ None ,
468
+ None ,
469
+ new_dma ! ( tx_dma) ,
470
+ new_dma ! ( rx_dma) ,
471
+ config,
472
+ )
473
+ }
474
+
409
475
pub fn new_rxonly < T : Instance > (
410
476
peri : impl Peripheral < P = T > + ' d ,
411
477
sclk : impl Peripheral < P = impl SclkPin < T > > + ' d ,
@@ -690,7 +756,11 @@ impl<'d, M: PeriMode> Spi<'d, M> {
690
756
// 32 bit data length only works when the data is 32bit aligned
691
757
w. set_datalen ( <u8 as SealedWord >:: CONFIG ) ;
692
758
w. set_datamerge ( false ) ;
693
- w. set_mosibidir ( false ) ;
759
+ if config. half_duplex {
760
+ w. set_mosibidir ( true ) ;
761
+ } else {
762
+ w. set_mosibidir ( false ) ;
763
+ }
694
764
w. set_lsb ( config. bit_order == BitOrder :: LsbFirst ) ;
695
765
w. set_slvmode ( false ) ; // default master mode
696
766
w. set_cpha ( cpha) ;
0 commit comments