@@ -54,6 +54,7 @@ void STM32EthMACv1::TxDMA::stopDMA() {
5454void STM32EthMACv1::TxDMA::cacheInvalidateDescriptor (const size_t descIdx) {
5555 SCB_InvalidateDCache_by_Addr (&txDescs[descIdx], sizeof (stm32_ethv1::TxDescriptor));
5656}
57+ #endif
5758
5859bool STM32EthMACv1::TxDMA::descOwnedByDMA (size_t descIdx) {
5960 return txDescs[descIdx].dmaOwn ;
@@ -80,10 +81,30 @@ bool STM32EthMACv1::TxDMA::isDMAReadableBuffer(uint8_t const *start, size_t size
8081}
8182
8283void STM32EthMACv1::TxDMA::giveToDMA (size_t descIdx, uint8_t const *buffer, size_t len, bool firstDesc, bool lastDesc) {
84+ // Configure descriptor with buffer and size
85+ txDescs[descIdx].buffer1 = buffer;
86+ txDescs[descIdx].buffer1Size = len;
87+ txDescs[descIdx].firstSegment = firstDesc;
88+ txDescs[descIdx].lastSegment = lastDesc;
89+ txDescs[descIdx].intrOnComplete = true ;
8390
84- }
91+ // Return to DMA
92+ txDescs[descIdx].dmaOwn = true ;
93+
94+ // Flush back to main memory
95+ #ifdef __DCACHE_PRESENT
96+ SCB_CleanDCache_by_Addr (&txDescs[descIdx], sizeof (stm32_ethv1::TxDescriptor));
97+ #else
98+ __DMB (); // Make sure descriptor is written before the below lines
8599#endif
86100
101+ // Clear buffer unavailable flag (I think this is for information only though)
102+ base->DMASR = ETH_DMASR_TBUS_Msk;
103+
104+ // Demand (good sir!) a Tx descriptor poll
105+ base->DMATPDR = 1 ;
106+ }
107+
87108void STM32EthMACv1::RxDMA::startDMA () {
88109
89110 // Rx buffer size must be a multiple of 4, per the descriptor definition
@@ -437,4 +458,52 @@ void STM32EthMACv1::MACDriver::setPromiscuous(bool enable) {
437458 base->MACFFR &= ~ETH_MACFFR_PM_Msk;
438459 }
439460}
461+
462+ STM32EthMACv1::STM32EthMACv1 ():
463+ CompositeEMAC (txDMA, rxDMA, macDriver),
464+ base (ETH),
465+ txDMA (base),
466+ rxDMA (base),
467+ macDriver (base)
468+ {
469+ instance = this ;
470+ }
471+
472+ void STM32EthMACv1::irqHandler () {
473+ const auto emacInst = instance;
474+ uint32_t dma_flag = emacInst->base ->DMASR ;
475+
476+ /* Packet received */
477+ if ((dma_flag & ETH_DMASR_RS_Msk) != 0U )
478+ {
479+ /* Clear the Eth DMA Rx IT pending bits */
480+ ETH->DMASR = ETH_DMASR_RS_Msk | ETH_DMASR_NIS_Msk;
481+
482+ emacInst->rxISR ();
483+ }
484+
485+ /* Packet transmitted */
486+ if ((dma_flag & ETH_DMASR_TS_Msk) != 0U )
487+ {
488+ /* Clear the Eth DMA Tx IT pending bits */
489+ ETH->DMASR = ETH_DMASR_TS_Msk | ETH_DMASR_NIS_Msk;
490+
491+ emacInst->txISR ();
492+ }
493+
494+ /* ETH DMA Error */
495+ if (dma_flag & ETH_DMASR_FBES_Msk)
496+ {
497+ MBED_ERROR (MBED_MAKE_ERROR (MBED_MODULE_DRIVER_ETHERNET, EIO), \
498+ " STM32 EMAC v2: Hardware reports fatal DMA error\n " );
499+ }
500+ }
501+
502+ // Provide default EMAC driver
503+ MBED_WEAK EMAC &EMAC::get_default_instance ()
504+ {
505+ static mbed::STM32EthMACv1 emac;
506+ return emac;
507+ }
508+
440509}
0 commit comments