[HAL][ETH] Ensure a delay of 4 TX_CLK/RX_CLK cycles between two successive write operations to the same register
diff --git a/Src/stm32f4xx_hal_eth.c b/Src/stm32f4xx_hal_eth.c
index 38e54ad..0c7e02a 100644
--- a/Src/stm32f4xx_hal_eth.c
+++ b/Src/stm32f4xx_hal_eth.c
@@ -696,6 +696,8 @@
*/
HAL_StatusTypeDef HAL_ETH_Start(ETH_HandleTypeDef *heth)
{
+ uint32_t tmpreg1;
+
if (heth->gState == HAL_ETH_STATE_READY)
{
heth->gState = HAL_ETH_STATE_BUSY;
@@ -709,9 +711,21 @@
/* Enable the MAC transmission */
SET_BIT(heth->Instance->MACCR, ETH_MACCR_TE);
+ /* Wait until the write operation will be taken into account :
+ at least four TX_CLK/RX_CLK clock cycles */
+ tmpreg1 = (heth->Instance)->MACCR;
+ HAL_Delay(ETH_REG_WRITE_DELAY);
+ (heth->Instance)->MACCR = tmpreg1;
+
/* Enable the MAC reception */
SET_BIT(heth->Instance->MACCR, ETH_MACCR_RE);
+ /* Wait until the write operation will be taken into account :
+ at least four TX_CLK/RX_CLK clock cycles */
+ tmpreg1 = (heth->Instance)->MACCR;
+ HAL_Delay(ETH_REG_WRITE_DELAY);
+ (heth->Instance)->MACCR = tmpreg1;
+
/* Flush Transmit FIFO */
ETH_FlushTransmitFIFO(heth);
@@ -739,6 +753,8 @@
*/
HAL_StatusTypeDef HAL_ETH_Start_IT(ETH_HandleTypeDef *heth)
{
+ uint32_t tmpreg1;
+
if (heth->gState == HAL_ETH_STATE_READY)
{
heth->gState = HAL_ETH_STATE_BUSY;
@@ -765,9 +781,21 @@
/* Enable the MAC transmission */
SET_BIT(heth->Instance->MACCR, ETH_MACCR_TE);
+ /* Wait until the write operation will be taken into account :
+ at least four TX_CLK/RX_CLK clock cycles */
+ tmpreg1 = (heth->Instance)->MACCR;
+ HAL_Delay(ETH_REG_WRITE_DELAY);
+ (heth->Instance)->MACCR = tmpreg1;
+
/* Enable the MAC reception */
SET_BIT(heth->Instance->MACCR, ETH_MACCR_RE);
+ /* Wait until the write operation will be taken into account :
+ at least four TX_CLK/RX_CLK clock cycles */
+ tmpreg1 = (heth->Instance)->MACCR;
+ HAL_Delay(ETH_REG_WRITE_DELAY);
+ (heth->Instance)->MACCR = tmpreg1;
+
/* Flush Transmit FIFO */
ETH_FlushTransmitFIFO(heth);
@@ -802,6 +830,8 @@
*/
HAL_StatusTypeDef HAL_ETH_Stop(ETH_HandleTypeDef *heth)
{
+ uint32_t tmpreg1;
+
if (heth->gState == HAL_ETH_STATE_STARTED)
{
/* Set the ETH peripheral state to BUSY */
@@ -815,12 +845,24 @@
/* Disable the MAC reception */
CLEAR_BIT(heth->Instance->MACCR, ETH_MACCR_RE);
+ /* Wait until the write operation will be taken into account :
+ at least four TX_CLK/RX_CLK clock cycles */
+ tmpreg1 = (heth->Instance)->MACCR;
+ HAL_Delay(ETH_REG_WRITE_DELAY);
+ (heth->Instance)->MACCR = tmpreg1;
+
/* Flush Transmit FIFO */
ETH_FlushTransmitFIFO(heth);
/* Disable the MAC transmission */
CLEAR_BIT(heth->Instance->MACCR, ETH_MACCR_TE);
+ /* Wait until the write operation will be taken into account :
+ at least four TX_CLK/RX_CLK clock cycles */
+ tmpreg1 = (heth->Instance)->MACCR;
+ HAL_Delay(ETH_REG_WRITE_DELAY);
+ (heth->Instance)->MACCR = tmpreg1;
+
heth->gState = HAL_ETH_STATE_READY;
/* Return function status */
@@ -842,6 +884,7 @@
{
ETH_DMADescTypeDef *dmarxdesc;
uint32_t descindex;
+ uint32_t tmpreg1;
if (heth->gState == HAL_ETH_STATE_STARTED)
{
@@ -859,12 +902,25 @@
/* Disable the MAC reception */
CLEAR_BIT(heth->Instance->MACCR, ETH_MACCR_RE);
+
+ /* Wait until the write operation will be taken into account :
+ at least four TX_CLK/RX_CLK clock cycles */
+ tmpreg1 = (heth->Instance)->MACCR;
+ HAL_Delay(ETH_REG_WRITE_DELAY);
+ (heth->Instance)->MACCR = tmpreg1;
+
/* Flush Transmit FIFO */
ETH_FlushTransmitFIFO(heth);
/* Disable the MAC transmission */
CLEAR_BIT(heth->Instance->MACCR, ETH_MACCR_TE);
+ /* Wait until the write operation will be taken into account :
+ at least four TX_CLK/RX_CLK clock cycles */
+ tmpreg1 = (heth->Instance)->MACCR;
+ HAL_Delay(ETH_REG_WRITE_DELAY);
+ (heth->Instance)->MACCR = tmpreg1;
+
/* Clear IOC bit to all Rx descriptors */
for (descindex = 0; descindex < (uint32_t)ETH_RX_DESC_CNT; descindex++)
{
@@ -2313,6 +2369,7 @@
HAL_StatusTypeDef HAL_ETH_SetMACFilterConfig(ETH_HandleTypeDef *heth, ETH_MACFilterConfigTypeDef *pFilterConfig)
{
uint32_t filterconfig;
+ uint32_t tmpreg1;
if (pFilterConfig == NULL)
{
@@ -2333,6 +2390,12 @@
MODIFY_REG(heth->Instance->MACFFR, ETH_MACFFR_MASK, filterconfig);
+ /* Wait until the write operation will be taken into account :
+ at least four TX_CLK/RX_CLK clock cycles */
+ tmpreg1 = (heth->Instance)->MACFFR;
+ HAL_Delay(ETH_REG_WRITE_DELAY);
+ (heth->Instance)->MACFFR = tmpreg1;
+
return HAL_OK;
}
@@ -2418,14 +2481,28 @@
*/
HAL_StatusTypeDef HAL_ETH_SetHashTable(ETH_HandleTypeDef *heth, uint32_t *pHashTable)
{
+ uint32_t tmpreg1;
if (pHashTable == NULL)
{
return HAL_ERROR;
}
heth->Instance->MACHTHR = pHashTable[0];
+
+ /* Wait until the write operation will be taken into account :
+ at least four TX_CLK/RX_CLK clock cycles */
+ tmpreg1 = (heth->Instance)->MACHTHR;
+ HAL_Delay(ETH_REG_WRITE_DELAY);
+ (heth->Instance)->MACHTHR = tmpreg1;
+
heth->Instance->MACHTLR = pHashTable[1];
+ /* Wait until the write operation will be taken into account :
+ at least four TX_CLK/RX_CLK clock cycles */
+ tmpreg1 = (heth->Instance)->MACHTLR;
+ HAL_Delay(ETH_REG_WRITE_DELAY);
+ (heth->Instance)->MACHTLR = tmpreg1;
+
return HAL_OK;
}
@@ -2440,6 +2517,7 @@
*/
void HAL_ETH_SetRxVLANIdentifier(ETH_HandleTypeDef *heth, uint32_t ComparisonBits, uint32_t VLANIdentifier)
{
+ uint32_t tmpreg1;
MODIFY_REG(heth->Instance->MACVLANTR, ETH_MACVLANTR_VLANTI, VLANIdentifier);
if (ComparisonBits == ETH_VLANTAGCOMPARISON_16BIT)
{
@@ -2449,6 +2527,12 @@
{
SET_BIT(heth->Instance->MACVLANTR, ETH_MACVLANTR_VLANTC);
}
+
+ /* Wait until the write operation will be taken into account :
+ at least four TX_CLK/RX_CLK clock cycles */
+ tmpreg1 = (heth->Instance)->MACVLANTR;
+ HAL_Delay(ETH_REG_WRITE_DELAY);
+ (heth->Instance)->MACVLANTR = tmpreg1;
}
/**
@@ -2479,13 +2563,27 @@
*/
void HAL_ETH_ExitPowerDownMode(ETH_HandleTypeDef *heth)
{
+ uint32_t tmpreg1;
+
/* clear wake up sources */
CLEAR_BIT(heth->Instance->MACPMTCSR, ETH_MACPMTCSR_WFE | ETH_MACPMTCSR_MPE | ETH_MACPMTCSR_GU);
+ /* Wait until the write operation will be taken into account :
+ at least four TX_CLK/RX_CLK clock cycles */
+ tmpreg1 = (heth->Instance)->MACPMTCSR;
+ HAL_Delay(ETH_REG_WRITE_DELAY);
+ (heth->Instance)->MACPMTCSR = tmpreg1;
+
if (READ_BIT(heth->Instance->MACPMTCSR, ETH_MACPMTCSR_PD) != 0U)
{
/* Exit power down mode */
CLEAR_BIT(heth->Instance->MACPMTCSR, ETH_MACPMTCSR_PD);
+
+ /* Wait until the write operation will be taken into account :
+ at least four TX_CLK/RX_CLK clock cycles */
+ tmpreg1 = (heth->Instance)->MACPMTCSR;
+ HAL_Delay(ETH_REG_WRITE_DELAY);
+ (heth->Instance)->MACPMTCSR = tmpreg1;
}
/* Disable PMT interrupt */