@@ -1405,6 +1405,144 @@ impl DmaRxStreamBufView {
14051405 }
14061406}
14071407
1408+ /// A continuous DMA transfer buffer for Tx.
1409+ pub struct DmaTxStreamBuf {
1410+ descriptors : & ' static mut [ DmaDescriptor ] ,
1411+ buffer : & ' static mut [ u8 ] ,
1412+ burst : BurstConfig ,
1413+ }
1414+
1415+ impl DmaTxStreamBuf {
1416+ /// Creates a new [DmaTxStreamBuf] evenly distributing the buffer between
1417+ /// the provided descriptors.
1418+ pub fn new ( descriptors : & ' static mut [ DmaDescriptor ] , buffer : & ' static mut [ u8 ] ) -> Self {
1419+ Self {
1420+ descriptors,
1421+ buffer,
1422+ burst : Default :: default ( ) ,
1423+ }
1424+ }
1425+
1426+ /// Consume the buf, returning the descriptors and buffer.
1427+ pub fn split ( self ) -> ( & ' static mut [ DmaDescriptor ] , & ' static mut [ u8 ] ) {
1428+ ( self . descriptors , self . buffer )
1429+ }
1430+ }
1431+
1432+ unsafe impl DmaTxBuffer for DmaTxStreamBuf {
1433+ type View = ( ) ;
1434+
1435+ fn prepare ( & mut self ) -> Preparation {
1436+ // Link up all the descriptors (but not in a circle).
1437+ let mut next = null_mut ( ) ;
1438+ for desc in self . descriptors . iter_mut ( ) . rev ( ) {
1439+ desc. next = next;
1440+ next = desc;
1441+
1442+ desc. reset_for_rx ( ) ;
1443+ }
1444+ Preparation {
1445+ start : self . descriptors . as_mut_ptr ( ) ,
1446+ direction : TransferDirection :: Out ,
1447+ #[ cfg( psram_dma) ]
1448+ accesses_psram : false ,
1449+ burst_transfer : self . burst ,
1450+
1451+ // Whilst we give ownership of the descriptors the DMA, the correctness of this buffer
1452+ // implementation doesn't rely on the DMA checking for descriptor ownership.
1453+ // No descriptor is added back to the end of the stream before it's ready for the DMA
1454+ // to consume it.
1455+ check_owner : None ,
1456+ auto_write_back : true ,
1457+ }
1458+ }
1459+
1460+ fn into_view ( self ) -> Self :: View {
1461+ todo ! ( )
1462+ }
1463+
1464+ fn from_view ( view : Self :: View ) -> Self {
1465+ todo ! ( )
1466+ }
1467+ }
1468+
1469+ /// A view into a [DmaRxStreamBuf]
1470+ pub struct DmaTxStreamBufView {
1471+ buf : DmaTxStreamBuf ,
1472+ descriptor_idx : usize ,
1473+ descriptor_offset : usize ,
1474+ }
1475+
1476+ impl DmaTxStreamBufView {
1477+ /// Returns the number of bytes available for writing.
1478+ pub fn available_bytes ( & self ) -> usize {
1479+ let ( tail, head) = self . buf . descriptors . split_at ( self . descriptor_idx ) ;
1480+ head. iter ( )
1481+ . chain ( tail)
1482+ . take_while ( |d| d. owner ( ) == Owner :: Cpu )
1483+ . map ( |d| d. len ( ) )
1484+ . sum :: < usize > ( )
1485+ - self . descriptor_offset
1486+ }
1487+
1488+ /// Pushes a buffer into the stream buffer.
1489+ /// Returns the number of bytes pushed.
1490+ pub fn push ( & mut self , buf : & [ u8 ] ) -> usize {
1491+ let chunk_size = self . buf . descriptors [ 0 ] . size ( ) ;
1492+ let n_descs = self . buf . descriptors . len ( ) ;
1493+
1494+ // Prepare descriptors and reorganize link list
1495+ let buf_start = chunk_size * self . descriptor_idx + self . descriptor_offset ;
1496+ let desc_start = self . descriptor_idx ;
1497+ let mut buf_idx = 0 ;
1498+ loop {
1499+ let d = & mut self . buf . descriptors [ self . descriptor_idx ] ;
1500+ if d. owner ( ) == Owner :: Dma {
1501+ break ;
1502+ }
1503+
1504+ let desc_remain = d. len ( ) - self . descriptor_offset ;
1505+ if buf_idx + desc_remain >= buf. len ( ) {
1506+ self . descriptor_offset += desc_remain;
1507+ break ;
1508+ }
1509+ buf_idx += desc_remain;
1510+
1511+ d. next = null_mut ( ) ;
1512+ let prev = self . descriptor_idx . checked_sub ( 1 ) . unwrap_or ( n_descs - 1 ) ;
1513+ self . buf . descriptors [ prev] . next = d;
1514+
1515+ self . descriptor_idx += 1 ;
1516+ if self . descriptor_idx > n_descs {
1517+ self . descriptor_idx = 0 ;
1518+ }
1519+ self . descriptor_offset = 0 ;
1520+ }
1521+ let buf_end = chunk_size * self . descriptor_idx + self . descriptor_offset ;
1522+ let desc_end = self . descriptor_idx ;
1523+
1524+ // Actually copy buffers
1525+ if buf_start < buf_end {
1526+ self . buf . buffer [ buf_start..buf_end] . copy_from_slice ( & buf[ ..buf_end - buf_start] ) ;
1527+ self . buf . descriptors [ desc_start..desc_end]
1528+ . iter_mut ( )
1529+ . for_each ( |d| d. set_owner ( Owner :: Dma ) ) ;
1530+ buf_end - buf_start
1531+ } else {
1532+ let buf_len = self . buf . buffer . len ( ) ;
1533+ self . buf . buffer [ buf_start..] . copy_from_slice ( & buf[ ..buf_len - buf_start] ) ;
1534+ self . buf . buffer [ ..buf_end] . copy_from_slice ( & buf[ buf_len - buf_start..] ) ;
1535+ self . buf . descriptors [ desc_start..]
1536+ . iter_mut ( )
1537+ . for_each ( |d| d. set_owner ( Owner :: Dma ) ) ;
1538+ self . buf . descriptors [ ..desc_end]
1539+ . iter_mut ( )
1540+ . for_each ( |d| d. set_owner ( Owner :: Dma ) ) ;
1541+ buf_len + buf_end - buf_start
1542+ }
1543+ }
1544+ }
1545+
14081546static mut EMPTY : [ DmaDescriptor ; 1 ] = [ DmaDescriptor :: EMPTY ] ;
14091547
14101548/// An empty buffer that can be used when you don't need to transfer any data.
0 commit comments