@@ -1756,6 +1756,27 @@ where
17561756 pub fn set_priority ( & mut self , priority : DmaPriority ) {
17571757 self . rx_impl . set_priority ( priority) ;
17581758 }
1759+
1760+ fn do_prepare (
1761+ & mut self ,
1762+ preparation : Preparation ,
1763+ peri : DmaPeripheral ,
1764+ ) -> Result < ( ) , DmaError > {
1765+ debug_assert_eq ! ( preparation. direction, TransferDirection :: In ) ;
1766+
1767+ self . rx_impl . set_burst_mode ( preparation. burst_transfer ) ;
1768+ self . rx_impl . set_descr_burst_mode ( true ) ;
1769+ self . rx_impl . set_check_owner ( preparation. check_owner ) ;
1770+
1771+ compiler_fence ( core:: sync:: atomic:: Ordering :: SeqCst ) ;
1772+
1773+ self . rx_impl . clear_all ( ) ;
1774+ self . rx_impl . reset ( ) ;
1775+ self . rx_impl . set_link_addr ( preparation. start as u32 ) ;
1776+ self . rx_impl . set_peripheral ( peri as u8 ) ;
1777+
1778+ Ok ( ( ) )
1779+ }
17591780}
17601781
17611782impl < M , CH > crate :: private:: Sealed for ChannelRx < ' _ , M , CH >
@@ -1770,24 +1791,18 @@ where
17701791 M : Mode ,
17711792 CH : DmaChannel ,
17721793{
1794+ // TODO: used by I2S, which should be rewritten to use the Preparation-based
1795+ // API.
17731796 unsafe fn prepare_transfer_without_start (
17741797 & mut self ,
17751798 peri : DmaPeripheral ,
17761799 chain : & DescriptorChain ,
17771800 ) -> Result < ( ) , DmaError > {
1778- // if self.burst_mode
1779- // && chain
1780- // .descriptors
1781- // .iter()
1782- // .any(|d| d.len() % 4 != 0 || d.buffer as u32 % 4 != 0)
1783- //{
1784- // return Err(DmaError::InvalidAlignment);
1785- //}
1786-
1787- // for esp32s3 we check each descriptor buffer that points to psram for
1788- // alignment and invalidate the cache for that buffer
1801+ // For ESP32-S3 we check each descriptor buffer that points to PSRAM for
1802+ // alignment and invalidate the cache for that buffer.
17891803 // NOTE: for RX the `buffer` and `size` need to be aligned but the `len` does
17901804 // not. TRM section 3.4.9
1805+ // Note that DmaBuffer implementations are required to do this for us.
17911806 #[ cfg( esp32s3) ]
17921807 for des in chain. descriptors . iter ( ) {
17931808 // we are forcing the DMA alignment to the cache line size
@@ -1802,14 +1817,17 @@ where
18021817 }
18031818 }
18041819
1805- compiler_fence ( core:: sync:: atomic:: Ordering :: SeqCst ) ;
1806-
1807- self . rx_impl . clear_all ( ) ;
1808- self . rx_impl . reset ( ) ;
1809- self . rx_impl . set_link_addr ( chain. first ( ) as u32 ) ;
1810- self . rx_impl . set_peripheral ( peri as u8 ) ;
1811-
1812- Ok ( ( ) )
1820+ self . do_prepare (
1821+ Preparation {
1822+ start : chain. first ( ) . cast_mut ( ) ,
1823+ #[ cfg( esp32s3) ]
1824+ external_memory_block_size : None ,
1825+ direction : TransferDirection :: In ,
1826+ burst_transfer : BurstTransfer :: Disabled ,
1827+ check_owner : Some ( false ) ,
1828+ } ,
1829+ peri,
1830+ )
18131831 }
18141832
18151833 unsafe fn prepare_transfer < BUF : DmaRxBuffer > (
@@ -1819,20 +1837,7 @@ where
18191837 ) -> Result < ( ) , DmaError > {
18201838 let preparation = buffer. prepare ( ) ;
18211839
1822- debug_assert_eq ! ( preparation. direction, TransferDirection :: In ) ;
1823-
1824- self . rx_impl . set_burst_mode ( preparation. burst_transfer ) ;
1825- self . rx_impl . set_descr_burst_mode ( true ) ;
1826- self . rx_impl . set_check_owner ( preparation. check_owner ) ;
1827-
1828- compiler_fence ( core:: sync:: atomic:: Ordering :: SeqCst ) ;
1829-
1830- self . rx_impl . clear_all ( ) ;
1831- self . rx_impl . reset ( ) ;
1832- self . rx_impl . set_link_addr ( preparation. start as u32 ) ;
1833- self . rx_impl . set_peripheral ( peri as u8 ) ;
1834-
1835- Ok ( ( ) )
1840+ self . do_prepare ( preparation, peri)
18361841 }
18371842
18381843 fn start_transfer ( & mut self ) -> Result < ( ) , DmaError > {
@@ -2041,6 +2046,32 @@ where
20412046 pub fn set_priority ( & mut self , priority : DmaPriority ) {
20422047 self . tx_impl . set_priority ( priority) ;
20432048 }
2049+
2050+ fn do_prepare (
2051+ & mut self ,
2052+ preparation : Preparation ,
2053+ peri : DmaPeripheral ,
2054+ ) -> Result < ( ) , DmaError > {
2055+ debug_assert_eq ! ( preparation. direction, TransferDirection :: Out ) ;
2056+
2057+ #[ cfg( esp32s3) ]
2058+ if let Some ( block_size) = preparation. external_memory_block_size {
2059+ self . set_ext_mem_block_size ( block_size. into ( ) ) ;
2060+ }
2061+
2062+ self . tx_impl . set_burst_mode ( preparation. burst_transfer ) ;
2063+ self . tx_impl . set_descr_burst_mode ( true ) ;
2064+ self . tx_impl . set_check_owner ( preparation. check_owner ) ;
2065+
2066+ compiler_fence ( core:: sync:: atomic:: Ordering :: SeqCst ) ;
2067+
2068+ self . tx_impl . clear_all ( ) ;
2069+ self . tx_impl . reset ( ) ;
2070+ self . tx_impl . set_link_addr ( preparation. start as u32 ) ;
2071+ self . tx_impl . set_peripheral ( peri as u8 ) ;
2072+
2073+ Ok ( ( ) )
2074+ }
20442075}
20452076
20462077impl < M , CH > crate :: private:: Sealed for ChannelTx < ' _ , M , CH >
@@ -2055,6 +2086,8 @@ where
20552086 M : Mode ,
20562087 CH : DmaChannel ,
20572088{
2089+ // TODO: used by I2S, which should be rewritten to use the Preparation-based
2090+ // API.
20582091 unsafe fn prepare_transfer_without_start (
20592092 & mut self ,
20602093 peri : DmaPeripheral ,
@@ -2063,7 +2096,8 @@ where
20632096 // Based on the ESP32-S3 TRM the alignment check is not needed for TX
20642097
20652098 // For esp32s3 we check each descriptor buffer that points to PSRAM for
2066- // alignment and writeback the cache for that buffer
2099+ // alignment and writeback the cache for that buffer.
2100+ // Note that DmaBuffer implementations are required to do this for us.
20672101 #[ cfg( esp32s3) ]
20682102 for des in chain. descriptors . iter ( ) {
20692103 // we are forcing the DMA alignment to the cache line size
@@ -2078,12 +2112,17 @@ where
20782112 }
20792113 }
20802114
2081- compiler_fence ( core:: sync:: atomic:: Ordering :: SeqCst ) ;
2082-
2083- self . tx_impl . clear_all ( ) ;
2084- self . tx_impl . reset ( ) ;
2085- self . tx_impl . set_link_addr ( chain. first ( ) as u32 ) ;
2086- self . tx_impl . set_peripheral ( peri as u8 ) ;
2115+ self . do_prepare (
2116+ Preparation {
2117+ start : chain. first ( ) . cast_mut ( ) ,
2118+ #[ cfg( esp32s3) ]
2119+ external_memory_block_size : None ,
2120+ direction : TransferDirection :: Out ,
2121+ burst_transfer : BurstTransfer :: Disabled ,
2122+ check_owner : Some ( false ) ,
2123+ } ,
2124+ peri,
2125+ ) ?;
20872126
20882127 // enable descriptor write back in circular mode
20892128 self . tx_impl
@@ -2099,25 +2138,7 @@ where
20992138 ) -> Result < ( ) , DmaError > {
21002139 let preparation = buffer. prepare ( ) ;
21012140
2102- debug_assert_eq ! ( preparation. direction, TransferDirection :: Out ) ;
2103-
2104- #[ cfg( esp32s3) ]
2105- if let Some ( block_size) = preparation. external_memory_block_size {
2106- self . set_ext_mem_block_size ( block_size. into ( ) ) ;
2107- }
2108-
2109- self . tx_impl . set_burst_mode ( preparation. burst_transfer ) ;
2110- self . tx_impl . set_descr_burst_mode ( true ) ;
2111- self . tx_impl . set_check_owner ( preparation. check_owner ) ;
2112-
2113- compiler_fence ( core:: sync:: atomic:: Ordering :: SeqCst ) ;
2114-
2115- self . tx_impl . clear_all ( ) ;
2116- self . tx_impl . reset ( ) ;
2117- self . tx_impl . set_link_addr ( preparation. start as u32 ) ;
2118- self . tx_impl . set_peripheral ( peri as u8 ) ;
2119-
2120- Ok ( ( ) )
2141+ self . do_prepare ( preparation, peri)
21212142 }
21222143
21232144 fn start_transfer ( & mut self ) -> Result < ( ) , DmaError > {
0 commit comments