@@ -1160,6 +1160,7 @@ impl DmaRxStreamBuf {
11601160 }
11611161
11621162 // Check that the last descriptor can hold the excess
1163+ // FIXME: shouldn't this be `buffer.len() % chunk_size` ?
11631164 let excess = buffer. len ( ) % descriptors. len ( ) ;
11641165 if chunk_size + excess > 4095 {
11651166 return Err ( DmaBufError :: InsufficientDescriptors ) ;
@@ -1415,12 +1416,44 @@ pub struct DmaTxStreamBuf {
14151416impl DmaTxStreamBuf {
14161417 /// Creates a new [DmaTxStreamBuf] evenly distributing the buffer between
14171418 /// the provided descriptors.
1418- pub fn new ( descriptors : & ' static mut [ DmaDescriptor ] , buffer : & ' static mut [ u8 ] ) -> Self {
1419- Self {
1419+ pub fn new (
1420+ descriptors : & ' static mut [ DmaDescriptor ] ,
1421+ buffer : & ' static mut [ u8 ] ,
1422+ ) -> Result < Self , DmaBufError > {
1423+ match ( ) {
1424+ _ if !is_slice_in_dram ( descriptors) => Err ( DmaBufError :: UnsupportedMemoryRegion ) ?,
1425+ _ if !is_slice_in_dram ( buffer) => Err ( DmaBufError :: UnsupportedMemoryRegion ) ?,
1426+ _ if descriptors. is_empty ( ) => Err ( DmaBufError :: InsufficientDescriptors ) ?,
1427+ _ => ( ) ,
1428+ } ;
1429+
1430+ // Evenly distribute the buffer between the descriptors.
1431+ let chunk_size = Some ( buffer. len ( ) / descriptors. len ( ) )
1432+ . filter ( |x| * x <= 4095 )
1433+ . ok_or ( DmaBufError :: InsufficientDescriptors ) ?;
1434+
1435+ let mut chunks = buffer. chunks_exact_mut ( chunk_size) ;
1436+ for ( desc, chunk) in descriptors. iter_mut ( ) . zip ( chunks. by_ref ( ) ) {
1437+ desc. buffer = chunk. as_mut_ptr ( ) ;
1438+ desc. set_size ( chunk. len ( ) ) ;
1439+ }
1440+ let remainder = chunks. into_remainder ( ) ;
1441+
1442+ if !remainder. is_empty ( ) {
1443+ // Append any excess to the last descriptor.
1444+ let last_descriptor = descriptors. last_mut ( ) . unwrap ( ) ;
1445+ let size = last_descriptor. size ( ) + remainder. len ( ) ;
1446+ if size > 4095 {
1447+ Err ( DmaBufError :: InsufficientDescriptors ) ?;
1448+ }
1449+ last_descriptor. set_size ( size) ;
1450+ }
1451+
1452+ Ok ( Self {
14201453 descriptors,
14211454 buffer,
14221455 burst : Default :: default ( ) ,
1423- }
1456+ } )
14241457 }
14251458
14261459 /// Consume the buf, returning the descriptors and buffer.
@@ -1430,7 +1463,7 @@ impl DmaTxStreamBuf {
14301463}
14311464
14321465unsafe impl DmaTxBuffer for DmaTxStreamBuf {
1433- type View = ( ) ;
1466+ type View = DmaTxStreamBufView ;
14341467
14351468 fn prepare ( & mut self ) -> Preparation {
14361469 // Link up all the descriptors (but not in a circle).
@@ -1439,7 +1472,7 @@ unsafe impl DmaTxBuffer for DmaTxStreamBuf {
14391472 desc. next = next;
14401473 next = desc;
14411474
1442- desc. reset_for_rx ( ) ;
1475+ desc. reset_for_tx ( desc . next . is_null ( ) ) ;
14431476 }
14441477 Preparation {
14451478 start : self . descriptors . as_mut_ptr ( ) ,
@@ -1458,11 +1491,15 @@ unsafe impl DmaTxBuffer for DmaTxStreamBuf {
14581491 }
14591492
14601493 fn into_view ( self ) -> Self :: View {
1461- todo ! ( )
1494+ DmaTxStreamBufView {
1495+ buf : self ,
1496+ descriptor_idx : 0 ,
1497+ descriptor_offset : 0 ,
1498+ }
14621499 }
14631500
14641501 fn from_view ( view : Self :: View ) -> Self {
1465- todo ! ( )
1502+ view . buf
14661503 }
14671504}
14681505
0 commit comments