2020#include < mbed_power_mgmt.h>
2121#include < Timer.h>
2222#include < mbed_trace.h>
23+ #include " mbed_error.h"
2324
2425#define TRACE_GROUP " STEMACv1"
2526
@@ -31,7 +32,129 @@ extern "C" void EthDeinitPinmappings();
3132extern " C" PinName EthGetPhyResetPin ();
3233
3334namespace mbed {
34- void STM32EthMACv1::MACDriver::ETH_SetMDIOClockRange (ETH_TypeDef * const base) {
35+ void STM32EthMACv1::TxDMA::startDMA () {
36+ // Zero all the Tx descriptors
37+ memset (txDescs.data (), 0 , sizeof (stm32_ethv1::TxDescriptor) * TX_NUM_DESCS);
38+
39+ // Set the end-of-ring bit on the last descriptor
40+ txDescs[TX_NUM_DESCS - 1 ].endOfRing = true ;
41+
42+ // Set descriptor list address register
43+ base->DMARDLAR = reinterpret_cast <ptrdiff_t >(&txDescs[0 ]);
44+
45+ // Start Tx DMA
46+ base->DMAOMR |= ETH_DMAOMR_ST_Msk;
47+ }
48+
49+ void STM32EthMACv1::TxDMA::stopDMA () {
50+ base->DMAOMR &= ~ETH_DMAOMR_ST_Msk;
51+ }
52+
53+ #if __DCACHE_PRESENT
54+ void STM32EthMACv1::TxDMA::cacheInvalidateDescriptor (const size_t descIdx) {
55+ SCB_InvalidateDCache_by_Addr (&txDescs[descIdx], sizeof (stm32_ethv1::TxDescriptor));
56+ }
57+
58+ bool STM32EthMACv1::TxDMA::descOwnedByDMA (size_t descIdx) {
59+ return txDescs[descIdx].dmaOwn ;
60+ }
61+
62+ bool STM32EthMACv1::TxDMA::isDMAReadableBuffer (uint8_t const *start, size_t size) const {
63+ #ifdef TARGET_STM32F7
64+ if (reinterpret_cast <ptrdiff_t >(start) < 1024 *16 ) {
65+ // In ITCM memory, not accessible by DMA. Note that ITCM is not included in the CMSIS memory map (yet).
66+ return false ;
67+ }
68+ #endif
69+
70+ #if TARGET_STM32F2 || TARGET_STM32F4
71+ // On STM32F2 and F2, ethernet DMA cannot access the flash memory.
72+ if (reinterpret_cast <ptrdiff_t >(start) >= MBED_ROM_START ||
73+ reinterpret_cast <ptrdiff_t >(start + size) <= MBED_ROM_START + MBED_ROM_SIZE)
74+ {
75+ return false ;
76+ }
77+ #endif
78+
79+ return true ;
80+ }
81+
82+ void STM32EthMACv1::TxDMA::giveToDMA (size_t descIdx, uint8_t const *buffer, size_t len, bool firstDesc, bool lastDesc) {
83+
84+ }
85+ #endif
86+
87+ void STM32EthMACv1::RxDMA::startDMA () {
88+
89+ // Rx buffer size must be a multiple of 4, per the descriptor definition
90+ MBED_ASSERT (rxPoolPayloadSize % sizeof (uint32_t ) == 0 );
91+
92+ // Zero all the Rx descriptors
93+ memset (rxDescs.data (), 0 , sizeof (stm32_ethv1::RxDescriptor) * RX_NUM_DESCS);
94+
95+ // Set the end-of-ring bit on the last descriptor
96+ rxDescs[RX_NUM_DESCS - 1 ].endOfRing = true ;
97+
98+ // Set descriptor list address register
99+ base->DMARDLAR = reinterpret_cast <ptrdiff_t >(&rxDescs[0 ]);
100+
101+ // Start Rx DMA
102+ base->DMAOMR |= ETH_DMAOMR_SR_Msk;
103+ }
104+
105+ void STM32EthMACv1::RxDMA::stopDMA () {
106+ base->DMAOMR &= ~ETH_DMAOMR_SR_Msk;
107+ }
108+
109+ #if __DCACHE_PRESENT
110+ void STM32EthMACv1::RxDMA::cacheInvalidateDescriptor (const size_t descIdx) {
111+ SCB_InvalidateDCache_by_Addr (&rxDescs[descIdx], sizeof (stm32_ethv1::RxDescriptor));
112+ }
113+ #endif
114+
115+ bool STM32EthMACv1::RxDMA::descOwnedByDMA (const size_t descIdx) {
116+ return rxDescs[descIdx].dmaOwn ;
117+ }
118+
119+ bool STM32EthMACv1::RxDMA::isFirstDesc (const size_t descIdx) {
120+ return rxDescs[descIdx].firstDescriptor ;
121+ }
122+
123+ bool STM32EthMACv1::RxDMA::isLastDesc (const size_t descIdx) {
124+ return rxDescs[descIdx].lastDescriptor ;
125+ }
126+
127+ bool STM32EthMACv1::RxDMA::isErrorDesc (const size_t descIdx) {
128+ return rxDescs[descIdx].errSummary ;
129+ }
130+
131+ void STM32EthMACv1::RxDMA::returnDescriptor (const size_t descIdx, uint8_t *buffer)
132+ {
133+ // Configure descriptor
134+ rxDescs[descIdx].buffer1 = buffer;
135+ rxDescs[descIdx].buffer1Size = rxPoolPayloadSize;
136+ rxDescs[descIdx].dmaOwn = true ;
137+
138+ // Flush back to main memory
139+ #ifdef __DCACHE_PRESENT
140+ SCB_CleanDCache_by_Addr (&rxDescs[descIdx], sizeof (stm32_ethv1::RxDescriptor));
141+ #else
142+ __DMB (); // Make sure descriptor is written before the below lines
143+ #endif
144+
145+ // Clear buffer unavailable flag (I think this is for information only though)
146+ base->DMASR = ETH_DMASR_RBUS_Msk;
147+
148+ // Demand (good sir!) an Rx descriptor poll
149+ base->DMARPDR = 1 ;
150+ }
151+
152+ size_t STM32EthMACv1::RxDMA::getTotalLen (const size_t firstDescIdx, const size_t lastDescIdx) {
153+ // Total length of the packet is in the last descriptor
154+ return rxDescs[lastDescIdx].frameLen ;
155+ }
156+
157+ void STM32EthMACv1::MACDriver::ETH_SetMDIOClockRange (ETH_TypeDef * const base) {
35158 /* Get the ETHERNET MACMIIAR value */
36159 uint32_t tempreg = base->MACMIIAR ;
37160 /* Clear CSR Clock Range CR[2:0] bits */
@@ -61,11 +184,17 @@ namespace mbed {
61184 /* CSR Clock Range between 100-150 MHz */
62185 tempreg |= (uint32_t )ETH_MACMIIAR_CR_Div62;
63186 }
64- else /* ((hclk >= 150000000)&&(hclk <= 216000000)) */
187+ #ifdef ETH_MACMIIAR_CR_Div102
188+ else if ((hclk >= 150000000 )&&(hclk <= 216000000 ))
65189 {
66190 /* CSR Clock Range between 150-216 MHz */
67191 tempreg |= (uint32_t )ETH_MACMIIAR_CR_Div102;
68192 }
193+ #endif
194+ else {
195+ MBED_ERROR (MBED_MAKE_ERROR (MBED_MODULE_DRIVER_ETHERNET, EIO), \
196+ " STM32 EMAC v1: Unsupported HCLK range\n " );
197+ }
69198
70199 /* Write to ETHERNET MAC MIIAR: Configure the ETHERNET CSR Clock Range */
71200 base->MACMIIAR = (uint32_t )tempreg;
0 commit comments