1212use embedded_hal:: spi:: SpiBus ;
1313use embedded_hal_async:: spi:: SpiBus as SpiBusAsync ;
1414use esp_hal:: {
15+ gpio:: Input ,
16+ peripheral:: Peripheral ,
1517 spi:: master:: { Config , Spi } ,
1618 time:: Rate ,
1719 Blocking ,
@@ -26,10 +28,7 @@ cfg_if::cfg_if! {
2628 gpio:: { Level , NoPin } ,
2729 } ;
2830 #[ cfg( pcnt) ]
29- use esp_hal:: {
30- gpio:: interconnect:: InputSignal ,
31- pcnt:: { channel:: EdgeMode , unit:: Unit , Pcnt } ,
32- } ;
31+ use esp_hal:: pcnt:: { channel:: EdgeMode , unit:: Unit , Pcnt } ;
3332 }
3433}
3534
@@ -53,8 +52,7 @@ struct Context {
5352 tx_buffer : & ' static mut [ u8 ] ,
5453 #[ cfg( feature = "unstable" ) ]
5554 tx_descriptors : & ' static mut [ DmaDescriptor ] ,
56- #[ cfg( all( pcnt, feature = "unstable" ) ) ]
57- pcnt_source : InputSignal ,
55+ miso_input : Input < ' static > ,
5856 #[ cfg( all( pcnt, feature = "unstable" ) ) ]
5957 pcnt_unit : Unit < ' static , 0 > ,
6058}
@@ -70,7 +68,13 @@ mod tests {
7068 esp_hal:: Config :: default ( ) . with_cpu_clock ( esp_hal:: clock:: CpuClock :: max ( ) ) ,
7169 ) ;
7270
73- let ( _, mosi) = hil_test:: common_test_pins!( peripherals) ;
71+ let ( _, miso) = hil_test:: common_test_pins!( peripherals) ;
72+
73+ // A bit ugly but the peripheral interconnect APIs aren't yet stable.
74+ let mosi = unsafe { miso. clone_unchecked ( ) } ;
75+ let miso_input = unsafe { miso. clone_unchecked ( ) } ;
76+ // Will be used later to detect edges directly or through PCNT.
77+ let miso_input = Input :: new ( miso_input, Default :: default ( ) ) ;
7478
7579 #[ cfg( feature = "unstable" ) ]
7680 cfg_if:: cfg_if! {
@@ -83,16 +87,8 @@ mod tests {
8387
8488 cfg_if:: cfg_if! {
8589 if #[ cfg( feature = "unstable" ) ] {
86- let ( miso, mosi) = mosi. split( ) ;
87-
88- #[ cfg( pcnt) ]
89- let mosi_loopback_pcnt = miso. clone( ) ;
90-
9190 let ( rx_buffer, rx_descriptors, tx_buffer, tx_descriptors) = dma_buffers!( 32000 ) ;
9291 } else {
93- use esp_hal:: peripheral:: Peripheral ;
94- let miso = unsafe { mosi. clone_unchecked( ) } ;
95-
9692 static mut TX_BUFFER : [ u8 ; 4096 ] = [ 0 ; 4096 ] ;
9793 static mut RX_BUFFER : [ u8 ; 4096 ] = [ 0 ; 4096 ] ;
9894
@@ -121,19 +117,19 @@ mod tests {
121117 spi,
122118 rx_buffer,
123119 tx_buffer,
120+ miso_input,
124121 dma_channel,
125122 rx_descriptors,
126123 tx_descriptors,
127124 #[ cfg( pcnt) ]
128- pcnt_source: mosi_loopback_pcnt,
129- #[ cfg( pcnt) ]
130125 pcnt_unit: pcnt. unit0,
131126 }
132127 } else {
133128 Context {
134129 spi,
135130 rx_buffer,
136131 tx_buffer,
132+ miso_input,
137133 }
138134 }
139135 }
@@ -192,7 +188,8 @@ mod tests {
192188
193189 let unit = ctx. pcnt_unit ;
194190
195- unit. channel0 . set_edge_signal ( ctx. pcnt_source ) ;
191+ unit. channel0
192+ . set_edge_signal ( ctx. miso_input . peripheral_input ( ) ) ;
196193 unit. channel0
197194 . set_input_mode ( EdgeMode :: Hold , EdgeMode :: Increment ) ;
198195
@@ -210,7 +207,8 @@ mod tests {
210207
211208 let unit = ctx. pcnt_unit ;
212209
213- unit. channel0 . set_edge_signal ( ctx. pcnt_source ) ;
210+ unit. channel0
211+ . set_edge_signal ( ctx. miso_input . peripheral_input ( ) ) ;
214212 unit. channel0
215213 . set_input_mode ( EdgeMode :: Hold , EdgeMode :: Increment ) ;
216214
@@ -229,7 +227,8 @@ mod tests {
229227
230228 let unit = ctx. pcnt_unit ;
231229
232- unit. channel0 . set_edge_signal ( ctx. pcnt_source ) ;
230+ unit. channel0
231+ . set_edge_signal ( ctx. miso_input . peripheral_input ( ) ) ;
233232 unit. channel0
234233 . set_input_mode ( EdgeMode :: Hold , EdgeMode :: Increment ) ;
235234
@@ -254,7 +253,8 @@ mod tests {
254253
255254 let unit = ctx. pcnt_unit ;
256255
257- unit. channel0 . set_edge_signal ( ctx. pcnt_source ) ;
256+ unit. channel0
257+ . set_edge_signal ( ctx. miso_input . peripheral_input ( ) ) ;
258258 unit. channel0
259259 . set_input_mode ( EdgeMode :: Hold , EdgeMode :: Increment ) ;
260260
@@ -272,7 +272,8 @@ mod tests {
272272
273273 let unit = ctx. pcnt_unit ;
274274
275- unit. channel0 . set_edge_signal ( ctx. pcnt_source ) ;
275+ unit. channel0
276+ . set_edge_signal ( ctx. miso_input . peripheral_input ( ) ) ;
276277 unit. channel0
277278 . set_input_mode ( EdgeMode :: Hold , EdgeMode :: Increment ) ;
278279
@@ -356,7 +357,8 @@ mod tests {
356357 let unit = ctx. pcnt_unit ;
357358 let mut spi = ctx. spi . with_dma ( ctx. dma_channel ) ;
358359
359- unit. channel0 . set_edge_signal ( ctx. pcnt_source ) ;
360+ unit. channel0
361+ . set_edge_signal ( ctx. miso_input . peripheral_input ( ) ) ;
360362 unit. channel0
361363 . set_input_mode ( EdgeMode :: Hold , EdgeMode :: Increment ) ;
362364
@@ -396,7 +398,8 @@ mod tests {
396398 let unit = ctx. pcnt_unit ;
397399 let mut spi = ctx. spi . with_dma ( ctx. dma_channel ) ;
398400
399- unit. channel0 . set_edge_signal ( ctx. pcnt_source ) ;
401+ unit. channel0
402+ . set_edge_signal ( ctx. miso_input . peripheral_input ( ) ) ;
400403 unit. channel0
401404 . set_input_mode ( EdgeMode :: Hold , EdgeMode :: Increment ) ;
402405
@@ -500,7 +503,9 @@ mod tests {
500503 let dma_rx_buf = DmaRxBuf :: new ( rx_descriptors, rx_buffer) . unwrap ( ) ;
501504 let dma_tx_buf = DmaTxBuf :: new ( tx_descriptors, tx_buffer) . unwrap ( ) ;
502505
503- ctx. pcnt_unit . channel0 . set_edge_signal ( ctx. pcnt_source ) ;
506+ ctx. pcnt_unit
507+ . channel0
508+ . set_edge_signal ( ctx. miso_input . peripheral_input ( ) ) ;
504509 ctx. pcnt_unit
505510 . channel0
506511 . set_input_mode ( EdgeMode :: Hold , EdgeMode :: Increment ) ;
@@ -601,7 +606,9 @@ mod tests {
601606 . with_buffers ( dma_rx_buf, dma_tx_buf)
602607 . into_async ( ) ;
603608
604- ctx. pcnt_unit . channel0 . set_edge_signal ( ctx. pcnt_source ) ;
609+ ctx. pcnt_unit
610+ . channel0
611+ . set_edge_signal ( ctx. miso_input . peripheral_input ( ) ) ;
605612 ctx. pcnt_unit
606613 . channel0
607614 . set_input_mode ( EdgeMode :: Hold , EdgeMode :: Increment ) ;
@@ -635,7 +642,9 @@ mod tests {
635642 . with_buffers ( dma_rx_buf, dma_tx_buf)
636643 . into_async ( ) ;
637644
638- ctx. pcnt_unit . channel0 . set_edge_signal ( ctx. pcnt_source ) ;
645+ ctx. pcnt_unit
646+ . channel0
647+ . set_edge_signal ( ctx. miso_input . peripheral_input ( ) ) ;
639648 ctx. pcnt_unit
640649 . channel0
641650 . set_input_mode ( EdgeMode :: Hold , EdgeMode :: Increment ) ;
@@ -701,9 +710,53 @@ mod tests {
701710 assert_eq ! ( & [ 0xff , 0xff , 0xff , 0xff ] , dma_rx_buf. as_slice( ) ) ;
702711 }
703712
713+ #[ test]
714+ async fn cancel_stops_basic_async_spi_transfer ( mut ctx : Context ) {
715+ // Slow down. At 80kHz, the transfer is supposed to take a bit over 3 seconds.
716+ // We don't rely on the transfer speed much, just that it's slow enough
717+ // that we can detect pulses if cancelling the future leaves the transfer
718+ // running.
719+ ctx. spi
720+ . apply_config ( & Config :: default ( ) . with_frequency ( Rate :: from_khz ( 800 ) ) )
721+ . unwrap ( ) ;
722+
723+ let mut spi = ctx. spi . into_async ( ) ;
724+
725+ for i in 0 ..ctx. tx_buffer . len ( ) {
726+ ctx. tx_buffer [ i] = ( i % 256 ) as u8 ;
727+ }
728+
729+ let transfer = spi. transfer_in_place_async ( ctx. tx_buffer ) ;
730+
731+ // Wait for a bit before cancelling
732+ let cancel = async {
733+ for _ in 0 ..100 {
734+ embassy_futures:: yield_now ( ) . await ;
735+ }
736+ } ;
737+
738+ embassy_futures:: select:: select ( transfer, cancel) . await ;
739+
740+ // Listen for a while to see if the SPI peripheral correctly stopped.
741+ let detect_edge = ctx. miso_input . wait_for_any_edge ( ) ;
742+ let wait = async {
743+ for _ in 0 ..10000 {
744+ embassy_futures:: yield_now ( ) . await ;
745+ }
746+ } ;
747+
748+ let result = embassy_futures:: select:: select ( detect_edge, wait) . await ;
749+
750+ // Assert that we timed out - we should not have detected any edges
751+ assert ! (
752+ matches!( result, embassy_futures:: select:: Either :: Second ( _) ) ,
753+ "Detected edge after cancellation"
754+ ) ;
755+ }
756+
704757 #[ test]
705758 #[ cfg( feature = "unstable" ) ]
706- fn cancel_stops_transaction ( mut ctx : Context ) {
759+ fn cancel_stops_dma_transaction ( mut ctx : Context ) {
707760 // Slow down. At 80kHz, the transfer is supposed to take a bit over 3 seconds.
708761 // This means that without working cancellation, the test case should
709762 // fail.
0 commit comments