|
21 | 21 | #include <Timer.h> |
22 | 22 | #include <mbed_trace.h> |
23 | 23 | #include "mbed_error.h" |
| 24 | +#include "mbed_events.h" |
| 25 | +#include "CriticalSectionLock.h" |
24 | 26 |
|
25 | 27 | #define TRACE_GROUP "STEMACv1" |
26 | 28 |
|
@@ -219,6 +221,29 @@ void STM32EthMACv1::MACDriver::ETH_SetMDIOClockRange(ETH_TypeDef * const base) { |
219 | 221 | base->MACMIIAR = (uint32_t)tempreg; |
220 | 222 | } |
221 | 223 |
|
| 224 | +#if ENABLE_ERRATA_2_21_6_WORKAROUND |
| 225 | +void STM32EthMACv1::MACDriver::rmiiWatchdog() { |
| 226 | + CriticalSectionLock lock; |
| 227 | + |
| 228 | + if(!rmiiWatchdogRunning) { |
| 229 | + // Already canceled by main thread, bail |
| 230 | + return; |
| 231 | + } |
| 232 | + |
| 233 | + /* some good packets are received */ |
| 234 | + if (base->MMCRGUFCR > 0) { |
| 235 | + /* RMII Init is OK - cancel watchdog task */ |
| 236 | + mbed_event_queue()->cancel(rmiiWatchdogRunning); |
| 237 | + rmiiWatchdogRunning = false; |
| 238 | + } else if (base->MMCRFCECR > 10) { |
| 239 | + /* ETH received too many packets with CRC errors, resetting RMII */ |
| 240 | + SYSCFG->PMC &= ~SYSCFG_PMC_MII_RMII_SEL; |
| 241 | + SYSCFG->PMC |= SYSCFG_PMC_MII_RMII_SEL; |
| 242 | + base->MMCCR |= ETH_MMCCR_CR; |
| 243 | + } |
| 244 | +} |
| 245 | +#endif |
| 246 | + |
222 | 247 | CompositeEMAC::ErrCode STM32EthMACv1::MACDriver::init() { |
223 | 248 | sleep_manager_lock_deep_sleep(); |
224 | 249 |
|
@@ -277,13 +302,29 @@ CompositeEMAC::ErrCode STM32EthMACv1::MACDriver::init() { |
277 | 302 | // in that case. |
278 | 303 | base->DMAIER = ETH_DMAIER_NISE | ETH_DMAIER_RIE | ETH_DMAIER_TIE | ETH_DMAIER_FBEIE | ETH_DMAIER_AISE; |
279 | 304 |
|
| 305 | +#if ENABLE_ERRATA_2_21_6_WORKAROUND |
| 306 | + // Start RMII watchdog task |
| 307 | + rmiiWatchdogHandle = mbed_event_queue()->call_every(std::chrono::milliseconds(MBED_CONF_NSAPI_EMAC_PHY_POLL_PERIOD), |
| 308 | + callback(this, &STM32EthMACv1::MACDriver::rmiiWatchdog)); |
| 309 | + rmiiWatchdogRunning = true; |
| 310 | +#endif |
| 311 | + |
280 | 312 | return CompositeEMAC::ErrCode::SUCCESS; |
281 | 313 | } |
282 | 314 |
|
283 | 315 | CompositeEMAC::ErrCode STM32EthMACv1::MACDriver::deinit() { |
284 | 316 | // Disable interrupt |
285 | 317 | HAL_NVIC_DisableIRQ(ETH_IRQn); |
286 | 318 |
|
| 319 | +#if ENABLE_ERRATA_2_21_6_WORKAROUND |
| 320 | + // Disable RMII watchdog if still running |
| 321 | + if(rmiiWatchdogRunning) { |
| 322 | + CriticalSectionLock lock; |
| 323 | + mbed_event_queue()->cancel(rmiiWatchdogRunning); |
| 324 | + rmiiWatchdogRunning = false; |
| 325 | + } |
| 326 | +#endif |
| 327 | + |
287 | 328 | // Unlock deep sleep |
288 | 329 | sleep_manager_unlock_deep_sleep(); |
289 | 330 |
|
|
0 commit comments