STM32F4xx HAL Driver master
STM32CubeF4 HAL / LL Drivers API Reference
Loading...
Searching...
No Matches
stm32f4xx_hal_eth.c
Go to the documentation of this file.
1
177
178/* Includes ------------------------------------------------------------------*/
179#include "stm32f4xx_hal.h"
180
184#ifdef HAL_ETH_MODULE_ENABLED
185
186#if defined(ETH)
187
192
193/* Private typedef -----------------------------------------------------------*/
194/* Private define ------------------------------------------------------------*/
198#define ETH_MACCR_MASK 0xFFFB7F7CU
199#define ETH_MACECR_MASK 0x3F077FFFU
200#define ETH_MACFFR_MASK 0x800007FFU
201#define ETH_MACWTR_MASK 0x0000010FU
202#define ETH_MACTFCR_MASK 0xFFFF00F2U
203#define ETH_MACRFCR_MASK 0x00000003U
204#define ETH_MTLTQOMR_MASK 0x00000072U
205#define ETH_MTLRQOMR_MASK 0x0000007BU
206
207#define ETH_DMAMR_MASK 0x00007802U
208#define ETH_DMASBMR_MASK 0x0000D001U
209#define ETH_DMACCR_MASK 0x00013FFFU
210#define ETH_DMACTCR_MASK 0x003F1010U
211#define ETH_DMACRCR_MASK 0x803F0000U
212#define ETH_MACPMTCSR_MASK (ETH_MACPMTCSR_PD | ETH_MACPMTCSR_WFE | \
213 ETH_MACPMTCSR_MPE | ETH_MACPMTCSR_GU)
214
215/* Timeout values */
216#define ETH_SWRESET_TIMEOUT 500U
217#define ETH_MDIO_BUS_TIMEOUT 1000U
218
219#define ETH_DMARXDESC_ERRORS_MASK ((uint32_t)(ETH_DMARXDESC_DBE | ETH_DMARXDESC_RE | \
220 ETH_DMARXDESC_OE | ETH_DMARXDESC_RWT |\
221 ETH_DMARXDESC_LC | ETH_DMARXDESC_CE |\
222 ETH_DMARXDESC_DE | ETH_DMARXDESC_IPV4HCE))
223
224#define ETH_MAC_US_TICK 1000000U
225
226#define ETH_MACTSCR_MASK 0x0087FF2FU
227
228#define ETH_PTPTSHR_VALUE 0xFFFFFFFFU
229#define ETH_PTPTSLR_VALUE 0xBB9ACA00U
230
231/* Ethernet MACMIIAR register Mask */
232#define ETH_MACMIIAR_CR_MASK 0xFFFFFFE3U
233
234/* Delay to wait when writing to some Ethernet registers */
235#define ETH_REG_WRITE_DELAY 0x00000001U
236
237/* ETHERNET MACCR register Mask */
238#define ETH_MACCR_CLEAR_MASK 0xFD20810FU
239
240/* ETHERNET MACFCR register Mask */
241#define ETH_MACFCR_CLEAR_MASK 0x0000FF41U
242
243/* ETHERNET DMAOMR register Mask */
244#define ETH_DMAOMR_CLEAR_MASK 0xF8DE3F23U
245
246/* ETHERNET MAC address offsets */
247#define ETH_MAC_ADDR_HBASE (uint32_t)(ETH_MAC_BASE + 0x40U) /* ETHERNET MAC address high offset */
248#define ETH_MAC_ADDR_LBASE (uint32_t)(ETH_MAC_BASE + 0x44U) /* ETHERNET MAC address low offset */
249
250/* ETHERNET DMA Rx descriptors Frame length Shift */
251#define ETH_DMARXDESC_FRAMELENGTHSHIFT 16U
255
256/* Private macros ------------------------------------------------------------*/
260/* Helper macros for TX descriptor handling */
261#define INCR_TX_DESC_INDEX(inx, offset) do {\
262 (inx) += (offset);\
263 if ((inx) >= (uint32_t)ETH_TX_DESC_CNT){\
264 (inx) = ((inx) - (uint32_t)ETH_TX_DESC_CNT);}\
265 } while (0)
266
267/* Helper macros for RX descriptor handling */
268#define INCR_RX_DESC_INDEX(inx, offset) do {\
269 (inx) += (offset);\
270 if ((inx) >= (uint32_t)ETH_RX_DESC_CNT){\
271 (inx) = ((inx) - (uint32_t)ETH_RX_DESC_CNT);}\
272 } while (0)
276/* Private function prototypes -----------------------------------------------*/
280static void ETH_SetMACConfig(ETH_HandleTypeDef *heth, const ETH_MACConfigTypeDef *macconf);
281static void ETH_SetDMAConfig(ETH_HandleTypeDef *heth, const ETH_DMAConfigTypeDef *dmaconf);
282static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth);
283static void ETH_DMATxDescListInit(ETH_HandleTypeDef *heth);
284static void ETH_DMARxDescListInit(ETH_HandleTypeDef *heth);
285static uint32_t ETH_Prepare_Tx_Descriptors(ETH_HandleTypeDef *heth, const ETH_TxPacketConfigTypeDef *pTxConfig,
286 uint32_t ItMode);
287static void ETH_UpdateDescriptor(ETH_HandleTypeDef *heth);
288static void ETH_FlushTransmitFIFO(ETH_HandleTypeDef *heth);
289static void ETH_MACAddressConfig(ETH_HandleTypeDef *heth, uint32_t MacAddr, uint8_t *Addr);
290
291#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
292static void ETH_InitCallbacksToDefault(ETH_HandleTypeDef *heth);
293#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
294
295#ifdef HAL_ETH_USE_PTP
296static HAL_StatusTypeDef HAL_ETH_PTP_AddendUpdate(ETH_HandleTypeDef *heth, int32_t timeoffset);
297#endif /* HAL_ETH_USE_PTP */
298
302
303/* Exported functions ---------------------------------------------------------*/
307
335
342HAL_StatusTypeDef HAL_ETH_Init(ETH_HandleTypeDef *heth)
343{
344 uint32_t tickstart;
345
346 if (heth == NULL)
347 {
348 return HAL_ERROR;
349 }
350 if (heth->gState == HAL_ETH_STATE_RESET)
351 {
352 heth->gState = HAL_ETH_STATE_BUSY;
353
354#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
355
356 ETH_InitCallbacksToDefault(heth);
357
358 if (heth->MspInitCallback == NULL)
359 {
360 heth->MspInitCallback = HAL_ETH_MspInit;
361 }
362
363 /* Init the low level hardware */
364 heth->MspInitCallback(heth);
365#else
366 /* Init the low level hardware : GPIO, CLOCK, NVIC. */
367 HAL_ETH_MspInit(heth);
368
369#endif /* (USE_HAL_ETH_REGISTER_CALLBACKS) */
370 }
371
373
374 /* Select MII or RMII Mode*/
375 SYSCFG->PMC &= ~(SYSCFG_PMC_MII_RMII_SEL);
376 SYSCFG->PMC |= (uint32_t)heth->Init.MediaInterface;
377 /* Dummy read to sync SYSCFG with ETH */
378 (void)SYSCFG->PMC;
379
380 /* Ethernet Software reset */
381 /* Set the SWR bit: resets all MAC subsystem internal registers and logic */
382 /* After reset all the registers holds their respective reset values */
383 SET_BIT(heth->Instance->DMABMR, ETH_DMABMR_SR);
384
385 /* Get tick */
386 tickstart = HAL_GetTick();
387
388 /* Wait for software reset */
389 while (READ_BIT(heth->Instance->DMABMR, ETH_DMABMR_SR) > 0U)
390 {
391 if (((HAL_GetTick() - tickstart) > ETH_SWRESET_TIMEOUT))
392 {
393 /* Set Error Code */
394 heth->ErrorCode = HAL_ETH_ERROR_TIMEOUT;
395 /* Set State as Error */
396 heth->gState = HAL_ETH_STATE_ERROR;
397 /* Return Error */
398 return HAL_ERROR;
399 }
400 }
401
402
403 /*------------------ MAC, MTL and DMA default Configuration ----------------*/
404 ETH_MACDMAConfig(heth);
405
406
407 /*------------------ DMA Tx Descriptors Configuration ----------------------*/
408 ETH_DMATxDescListInit(heth);
409
410 /*------------------ DMA Rx Descriptors Configuration ----------------------*/
411 ETH_DMARxDescListInit(heth);
412
413 /*--------------------- ETHERNET MAC Address Configuration ------------------*/
414 ETH_MACAddressConfig(heth, ETH_MAC_ADDRESS0, heth->Init.MACAddr);
415
416 /* Disable MMC Interrupts */
417 SET_BIT(heth->Instance->MACIMR, ETH_MACIMR_TSTIM | ETH_MACIMR_PMTIM);
418
419 /* Disable Rx MMC Interrupts */
420 SET_BIT(heth->Instance->MMCRIMR, ETH_MMCRIMR_RGUFM | ETH_MMCRIMR_RFAEM | \
421 ETH_MMCRIMR_RFCEM);
422
423 /* Disable Tx MMC Interrupts */
424 SET_BIT(heth->Instance->MMCTIMR, ETH_MMCTIMR_TGFM | ETH_MMCTIMR_TGFMSCM | \
425 ETH_MMCTIMR_TGFSCM);
426
427 heth->ErrorCode = HAL_ETH_ERROR_NONE;
428 heth->gState = HAL_ETH_STATE_READY;
429
430 return HAL_OK;
431}
432
439HAL_StatusTypeDef HAL_ETH_DeInit(ETH_HandleTypeDef *heth)
440{
441 /* Set the ETH peripheral state to BUSY */
442 heth->gState = HAL_ETH_STATE_BUSY;
443
444#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
445
446 if (heth->MspDeInitCallback == NULL)
447 {
448 heth->MspDeInitCallback = HAL_ETH_MspDeInit;
449 }
450 /* DeInit the low level hardware */
451 heth->MspDeInitCallback(heth);
452#else
453
454 /* De-Init the low level hardware : GPIO, CLOCK, NVIC. */
455 HAL_ETH_MspDeInit(heth);
456
457#endif /* (USE_HAL_ETH_REGISTER_CALLBACKS) */
458
459 /* Set ETH HAL state to Disabled */
460 heth->gState = HAL_ETH_STATE_RESET;
461
462 /* Return function status */
463 return HAL_OK;
464}
465
472__weak void HAL_ETH_MspInit(ETH_HandleTypeDef *heth)
473{
474 /* Prevent unused argument(s) compilation warning */
475 UNUSED(heth);
476 /* NOTE : This function Should not be modified, when the callback is needed,
477 the HAL_ETH_MspInit could be implemented in the user file
478 */
479}
480
487__weak void HAL_ETH_MspDeInit(ETH_HandleTypeDef *heth)
488{
489 /* Prevent unused argument(s) compilation warning */
490 UNUSED(heth);
491 /* NOTE : This function Should not be modified, when the callback is needed,
492 the HAL_ETH_MspDeInit could be implemented in the user file
493 */
494}
495
496#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
513HAL_StatusTypeDef HAL_ETH_RegisterCallback(ETH_HandleTypeDef *heth, HAL_ETH_CallbackIDTypeDef CallbackID,
514 pETH_CallbackTypeDef pCallback)
515{
516 HAL_StatusTypeDef status = HAL_OK;
517
518 if (pCallback == NULL)
519 {
520 /* Update the error code */
521 heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK;
522 return HAL_ERROR;
523 }
524
525 if (heth->gState == HAL_ETH_STATE_READY)
526 {
527 switch (CallbackID)
528 {
529 case HAL_ETH_TX_COMPLETE_CB_ID :
530 heth->TxCpltCallback = pCallback;
531 break;
532
533 case HAL_ETH_RX_COMPLETE_CB_ID :
534 heth->RxCpltCallback = pCallback;
535 break;
536
537 case HAL_ETH_ERROR_CB_ID :
538 heth->ErrorCallback = pCallback;
539 break;
540
541 case HAL_ETH_PMT_CB_ID :
542 heth->PMTCallback = pCallback;
543 break;
544
545
546 case HAL_ETH_WAKEUP_CB_ID :
547 heth->WakeUpCallback = pCallback;
548 break;
549
550 case HAL_ETH_MSPINIT_CB_ID :
551 heth->MspInitCallback = pCallback;
552 break;
553
554 case HAL_ETH_MSPDEINIT_CB_ID :
555 heth->MspDeInitCallback = pCallback;
556 break;
557
558 default :
559 /* Update the error code */
560 heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK;
561 /* Return error status */
562 status = HAL_ERROR;
563 break;
564 }
565 }
566 else if (heth->gState == HAL_ETH_STATE_RESET)
567 {
568 switch (CallbackID)
569 {
570 case HAL_ETH_MSPINIT_CB_ID :
571 heth->MspInitCallback = pCallback;
572 break;
573
574 case HAL_ETH_MSPDEINIT_CB_ID :
575 heth->MspDeInitCallback = pCallback;
576 break;
577
578 default :
579 /* Update the error code */
580 heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK;
581 /* Return error status */
582 status = HAL_ERROR;
583 break;
584 }
585 }
586 else
587 {
588 /* Update the error code */
589 heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK;
590 /* Return error status */
591 status = HAL_ERROR;
592 }
593
594 return status;
595}
596
612HAL_StatusTypeDef HAL_ETH_UnRegisterCallback(ETH_HandleTypeDef *heth, HAL_ETH_CallbackIDTypeDef CallbackID)
613{
614 HAL_StatusTypeDef status = HAL_OK;
615
616 if (heth->gState == HAL_ETH_STATE_READY)
617 {
618 switch (CallbackID)
619 {
620 case HAL_ETH_TX_COMPLETE_CB_ID :
621 heth->TxCpltCallback = HAL_ETH_TxCpltCallback;
622 break;
623
624 case HAL_ETH_RX_COMPLETE_CB_ID :
625 heth->RxCpltCallback = HAL_ETH_RxCpltCallback;
626 break;
627
628 case HAL_ETH_ERROR_CB_ID :
629 heth->ErrorCallback = HAL_ETH_ErrorCallback;
630 break;
631
632 case HAL_ETH_PMT_CB_ID :
633 heth->PMTCallback = HAL_ETH_PMTCallback;
634 break;
635
636
637 case HAL_ETH_WAKEUP_CB_ID :
638 heth->WakeUpCallback = HAL_ETH_WakeUpCallback;
639 break;
640
641 case HAL_ETH_MSPINIT_CB_ID :
642 heth->MspInitCallback = HAL_ETH_MspInit;
643 break;
644
645 case HAL_ETH_MSPDEINIT_CB_ID :
646 heth->MspDeInitCallback = HAL_ETH_MspDeInit;
647 break;
648
649 default :
650 /* Update the error code */
651 heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK;
652 /* Return error status */
653 status = HAL_ERROR;
654 break;
655 }
656 }
657 else if (heth->gState == HAL_ETH_STATE_RESET)
658 {
659 switch (CallbackID)
660 {
661 case HAL_ETH_MSPINIT_CB_ID :
662 heth->MspInitCallback = HAL_ETH_MspInit;
663 break;
664
665 case HAL_ETH_MSPDEINIT_CB_ID :
666 heth->MspDeInitCallback = HAL_ETH_MspDeInit;
667 break;
668
669 default :
670 /* Update the error code */
671 heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK;
672 /* Return error status */
673 status = HAL_ERROR;
674 break;
675 }
676 }
677 else
678 {
679 /* Update the error code */
680 heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK;
681 /* Return error status */
682 status = HAL_ERROR;
683 }
684
685 return status;
686}
687#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
688
692
707
714HAL_StatusTypeDef HAL_ETH_Start(ETH_HandleTypeDef *heth)
715{
716 uint32_t tmpreg1;
717
718 if (heth->gState == HAL_ETH_STATE_READY)
719 {
720 heth->gState = HAL_ETH_STATE_BUSY;
721
722 /* Set number of descriptors to build */
723 heth->RxDescList.RxBuildDescCnt = ETH_RX_DESC_CNT;
724
725 /* Build all descriptors */
726 ETH_UpdateDescriptor(heth);
727
728 /* Enable the MAC transmission */
729 SET_BIT(heth->Instance->MACCR, ETH_MACCR_TE);
730
731 /* Wait until the write operation will be taken into account :
732 at least four TX_CLK/RX_CLK clock cycles */
733 tmpreg1 = (heth->Instance)->MACCR;
734 HAL_Delay(ETH_REG_WRITE_DELAY);
735 (heth->Instance)->MACCR = tmpreg1;
736
737 /* Enable the MAC reception */
738 SET_BIT(heth->Instance->MACCR, ETH_MACCR_RE);
739
740 /* Wait until the write operation will be taken into account :
741 at least four TX_CLK/RX_CLK clock cycles */
742 tmpreg1 = (heth->Instance)->MACCR;
743 HAL_Delay(ETH_REG_WRITE_DELAY);
744 (heth->Instance)->MACCR = tmpreg1;
745
746 /* Flush Transmit FIFO */
747 ETH_FlushTransmitFIFO(heth);
748
749 /* Enable the DMA transmission */
750 SET_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_ST);
751
752 /* Enable the DMA reception */
753 SET_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_SR);
754
755 heth->gState = HAL_ETH_STATE_STARTED;
756
757 return HAL_OK;
758 }
759 else
760 {
761 return HAL_ERROR;
762 }
763}
764
771HAL_StatusTypeDef HAL_ETH_Start_IT(ETH_HandleTypeDef *heth)
772{
773 uint32_t tmpreg1;
774
775 if (heth->gState == HAL_ETH_STATE_READY)
776 {
777 heth->gState = HAL_ETH_STATE_BUSY;
778
779 /* save IT mode to ETH Handle */
780 heth->RxDescList.ItMode = 1U;
781
782 /* Set number of descriptors to build */
783 heth->RxDescList.RxBuildDescCnt = ETH_RX_DESC_CNT;
784
785 /* Build all descriptors */
786 ETH_UpdateDescriptor(heth);
787
788 /* Wait until the write operation will be taken into account :
789 at least four TX_CLK/RX_CLK clock cycles */
790 tmpreg1 = (heth->Instance)->MACCR;
791 HAL_Delay(ETH_REG_WRITE_DELAY);
792 (heth->Instance)->MACCR = tmpreg1;
793
794 /* Enable the DMA transmission */
795 SET_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_ST);
796
797 /* Enable the DMA reception */
798 SET_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_SR);
799
800 /* Flush Transmit FIFO */
801 ETH_FlushTransmitFIFO(heth);
802
803
804 /* Enable the MAC transmission */
805 SET_BIT(heth->Instance->MACCR, ETH_MACCR_TE);
806
807 /* Wait until the write operation will be taken into account :
808 at least four TX_CLK/RX_CLK clock cycles */
809 tmpreg1 = (heth->Instance)->MACCR;
810 HAL_Delay(ETH_REG_WRITE_DELAY);
811 (heth->Instance)->MACCR = tmpreg1;
812
813 /* Enable the MAC reception */
814 SET_BIT(heth->Instance->MACCR, ETH_MACCR_RE);
815
816 /* Enable ETH DMA interrupts:
817 - Tx complete interrupt
818 - Rx complete interrupt
819 - Fatal bus interrupt
820 */
821 __HAL_ETH_DMA_ENABLE_IT(heth, (ETH_DMAIER_NISE | ETH_DMAIER_RIE | ETH_DMAIER_TIE |
822 ETH_DMAIER_FBEIE | ETH_DMAIER_AISE | ETH_DMAIER_RBUIE));
823
824 heth->gState = HAL_ETH_STATE_STARTED;
825 return HAL_OK;
826 }
827 else
828 {
829 return HAL_ERROR;
830 }
831}
832
839HAL_StatusTypeDef HAL_ETH_Stop(ETH_HandleTypeDef *heth)
840{
841 uint32_t tmpreg1;
842
843 if (heth->gState == HAL_ETH_STATE_STARTED)
844 {
845 /* Set the ETH peripheral state to BUSY */
846 heth->gState = HAL_ETH_STATE_BUSY;
847
848 /* Disable the DMA transmission */
849 CLEAR_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_ST);
850
851 /* Disable the DMA reception */
852 CLEAR_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_SR);
853
854 /* Disable the MAC reception */
855 CLEAR_BIT(heth->Instance->MACCR, ETH_MACCR_RE);
856
857 /* Wait until the write operation will be taken into account :
858 at least four TX_CLK/RX_CLK clock cycles */
859 tmpreg1 = (heth->Instance)->MACCR;
860 HAL_Delay(ETH_REG_WRITE_DELAY);
861 (heth->Instance)->MACCR = tmpreg1;
862
863 /* Flush Transmit FIFO */
864 ETH_FlushTransmitFIFO(heth);
865
866 /* Disable the MAC transmission */
867 CLEAR_BIT(heth->Instance->MACCR, ETH_MACCR_TE);
868
869 /* Wait until the write operation will be taken into account :
870 at least four TX_CLK/RX_CLK clock cycles */
871 tmpreg1 = (heth->Instance)->MACCR;
872 HAL_Delay(ETH_REG_WRITE_DELAY);
873 (heth->Instance)->MACCR = tmpreg1;
874
875 heth->gState = HAL_ETH_STATE_READY;
876
877 /* Return function status */
878 return HAL_OK;
879 }
880 else
881 {
882 return HAL_ERROR;
883 }
884}
885
892HAL_StatusTypeDef HAL_ETH_Stop_IT(ETH_HandleTypeDef *heth)
893{
894 ETH_DMADescTypeDef *dmarxdesc;
895 uint32_t descindex;
896 uint32_t tmpreg1;
897
898 if (heth->gState == HAL_ETH_STATE_STARTED)
899 {
900 /* Set the ETH peripheral state to BUSY */
901 heth->gState = HAL_ETH_STATE_BUSY;
902
903 __HAL_ETH_DMA_DISABLE_IT(heth, (ETH_DMAIER_NISE | ETH_DMAIER_RIE | ETH_DMAIER_TIE |
904 ETH_DMAIER_FBEIE | ETH_DMAIER_AISE | ETH_DMAIER_RBUIE));
905
906 /* Disable the DMA transmission */
907 CLEAR_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_ST);
908
909 /* Disable the DMA reception */
910 CLEAR_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_SR);
911
912 /* Disable the MAC reception */
913 CLEAR_BIT(heth->Instance->MACCR, ETH_MACCR_RE);
914
915
916 /* Wait until the write operation will be taken into account :
917 at least four TX_CLK/RX_CLK clock cycles */
918 tmpreg1 = (heth->Instance)->MACCR;
919 HAL_Delay(ETH_REG_WRITE_DELAY);
920 (heth->Instance)->MACCR = tmpreg1;
921
922 /* Flush Transmit FIFO */
923 ETH_FlushTransmitFIFO(heth);
924
925 /* Disable the MAC transmission */
926 CLEAR_BIT(heth->Instance->MACCR, ETH_MACCR_TE);
927
928 /* Wait until the write operation will be taken into account :
929 at least four TX_CLK/RX_CLK clock cycles */
930 tmpreg1 = (heth->Instance)->MACCR;
931 HAL_Delay(ETH_REG_WRITE_DELAY);
932 (heth->Instance)->MACCR = tmpreg1;
933
934 /* Clear IOC bit to all Rx descriptors */
935 for (descindex = 0; descindex < (uint32_t)ETH_RX_DESC_CNT; descindex++)
936 {
937 dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descindex];
938 SET_BIT(dmarxdesc->DESC1, ETH_DMARXDESC_DIC);
939 }
940
941 heth->RxDescList.ItMode = 0U;
942
943 heth->gState = HAL_ETH_STATE_READY;
944
945 /* Return function status */
946 return HAL_OK;
947 }
948 else
949 {
950 return HAL_ERROR;
951 }
952}
953
962HAL_StatusTypeDef HAL_ETH_Transmit(ETH_HandleTypeDef *heth, ETH_TxPacketConfigTypeDef *pTxConfig, uint32_t Timeout)
963{
964 uint32_t tickstart;
965 ETH_DMADescTypeDef *dmatxdesc;
966
967 if (pTxConfig == NULL)
968 {
969 heth->ErrorCode |= HAL_ETH_ERROR_PARAM;
970 return HAL_ERROR;
971 }
972
973 if (heth->gState == HAL_ETH_STATE_STARTED)
974 {
975 /* Config DMA Tx descriptor by Tx Packet info */
976 if (ETH_Prepare_Tx_Descriptors(heth, pTxConfig, 0) != HAL_ETH_ERROR_NONE)
977 {
978 /* Set the ETH error code */
979 heth->ErrorCode |= HAL_ETH_ERROR_BUSY;
980 return HAL_ERROR;
981 }
982
983 /* Ensure completion of descriptor preparation before transmission start */
984 __DSB();
985
986 dmatxdesc = (ETH_DMADescTypeDef *)(&heth->TxDescList)->TxDesc[heth->TxDescList.CurTxDesc];
987
988 /* Incr current tx desc index */
989 INCR_TX_DESC_INDEX(heth->TxDescList.CurTxDesc, 1U);
990
991 /* Start transmission */
992 /* issue a poll command to Tx DMA by writing address of next immediate free descriptor */
993 WRITE_REG(heth->Instance->DMATPDR, (uint32_t)(heth->TxDescList.TxDesc[heth->TxDescList.CurTxDesc]));
994
995 tickstart = HAL_GetTick();
996
997 /* Wait for data to be transmitted or timeout occurred */
998 while ((dmatxdesc->DESC0 & ETH_DMATXDESC_OWN) != (uint32_t)RESET)
999 {
1000 if ((heth->Instance->DMASR & ETH_DMASR_FBES) != (uint32_t)RESET)
1001 {
1002 heth->ErrorCode |= HAL_ETH_ERROR_DMA;
1003 heth->DMAErrorCode = heth->Instance->DMASR;
1004 /* Return function status */
1005 return HAL_ERROR;
1006 }
1007
1008 /* Check for the Timeout */
1009 if (Timeout != HAL_MAX_DELAY)
1010 {
1011 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
1012 {
1013 heth->ErrorCode |= HAL_ETH_ERROR_TIMEOUT;
1014 /* Clear TX descriptor so that we can proceed */
1015 dmatxdesc->DESC0 = (ETH_DMATXDESC_FS | ETH_DMATXDESC_LS);
1016 return HAL_ERROR;
1017 }
1018 }
1019 }
1020
1021 /* Return function status */
1022 return HAL_OK;
1023 }
1024 else
1025 {
1026 return HAL_ERROR;
1027 }
1028}
1029
1037HAL_StatusTypeDef HAL_ETH_Transmit_IT(ETH_HandleTypeDef *heth, ETH_TxPacketConfigTypeDef *pTxConfig)
1038{
1039 if (pTxConfig == NULL)
1040 {
1041 heth->ErrorCode |= HAL_ETH_ERROR_PARAM;
1042 return HAL_ERROR;
1043 }
1044
1045 if (heth->gState == HAL_ETH_STATE_STARTED)
1046 {
1047 /* Save the packet pointer to release. */
1048 heth->TxDescList.CurrentPacketAddress = (uint32_t *)pTxConfig->pData;
1049
1050 /* Config DMA Tx descriptor by Tx Packet info */
1051 if (ETH_Prepare_Tx_Descriptors(heth, pTxConfig, 1) != HAL_ETH_ERROR_NONE)
1052 {
1053 heth->ErrorCode |= HAL_ETH_ERROR_BUSY;
1054 return HAL_ERROR;
1055 }
1056
1057 /* Ensure completion of descriptor preparation before transmission start */
1058 __DSB();
1059
1060 /* Incr current tx desc index */
1061 INCR_TX_DESC_INDEX(heth->TxDescList.CurTxDesc, 1U);
1062
1063 /* Start transmission */
1064 /* issue a poll command to Tx DMA by writing address of next immediate free descriptor */
1065 if (((heth->Instance)->DMASR & ETH_DMASR_TBUS) != (uint32_t)RESET)
1066 {
1067 /* Clear TBUS ETHERNET DMA flag */
1068 (heth->Instance)->DMASR = ETH_DMASR_TBUS;
1069 /* Resume DMA transmission*/
1070 (heth->Instance)->DMATPDR = 0U;
1071 }
1072
1073 return HAL_OK;
1074
1075 }
1076 else
1077 {
1078 return HAL_ERROR;
1079 }
1080}
1081
1089HAL_StatusTypeDef HAL_ETH_ReadData(ETH_HandleTypeDef *heth, void **pAppBuff)
1090{
1091 uint32_t descidx;
1092 ETH_DMADescTypeDef *dmarxdesc;
1093 uint32_t desccnt = 0U;
1094 uint32_t desccntmax;
1095 uint32_t bufflength;
1096 uint8_t rxdataready = 0U;
1097
1098 if (pAppBuff == NULL)
1099 {
1100 heth->ErrorCode |= HAL_ETH_ERROR_PARAM;
1101 return HAL_ERROR;
1102 }
1103
1104 if (heth->gState != HAL_ETH_STATE_STARTED)
1105 {
1106 return HAL_ERROR;
1107 }
1108
1109 descidx = heth->RxDescList.RxDescIdx;
1110 dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descidx];
1111 desccntmax = ETH_RX_DESC_CNT - heth->RxDescList.RxBuildDescCnt;
1112
1113 /* Check if descriptor is not owned by DMA */
1114 while ((READ_BIT(dmarxdesc->DESC0, ETH_DMARXDESC_OWN) == (uint32_t)RESET) && (desccnt < desccntmax)
1115 && (rxdataready == 0U))
1116 {
1117 if (READ_BIT(dmarxdesc->DESC0, ETH_DMARXDESC_LS) != (uint32_t)RESET)
1118 {
1119 /* Get timestamp high */
1120 heth->RxDescList.TimeStamp.TimeStampHigh = dmarxdesc->DESC7;
1121 /* Get timestamp low */
1122 heth->RxDescList.TimeStamp.TimeStampLow = dmarxdesc->DESC6;
1123 }
1124 if ((READ_BIT(dmarxdesc->DESC0, ETH_DMARXDESC_FS) != (uint32_t)RESET) || (heth->RxDescList.pRxStart != NULL))
1125 {
1126 /* Check first descriptor */
1127 if (READ_BIT(dmarxdesc->DESC0, ETH_DMARXDESC_FS) != (uint32_t)RESET)
1128 {
1129 heth->RxDescList.RxDescCnt = 0;
1130 heth->RxDescList.RxDataLength = 0;
1131 }
1132
1133 /* Get the Frame Length of the received packet */
1134 bufflength = ((dmarxdesc->DESC0 & ETH_DMARXDESC_FL) >> ETH_DMARXDESC_FRAMELENGTHSHIFT);
1135
1136 /* Check if last descriptor */
1137 if (READ_BIT(dmarxdesc->DESC0, ETH_DMARXDESC_LS) != (uint32_t)RESET)
1138 {
1139 /* Save Last descriptor index */
1140 heth->RxDescList.pRxLastRxDesc = dmarxdesc->DESC0;
1141
1142 /* Packet ready */
1143 rxdataready = 1;
1144 }
1145
1146 /* Link data */
1147 WRITE_REG(dmarxdesc->BackupAddr0, dmarxdesc->DESC2);
1148#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1149 /*Call registered Link callback*/
1150 heth->rxLinkCallback(&heth->RxDescList.pRxStart, &heth->RxDescList.pRxEnd,
1151 (uint8_t *)dmarxdesc->BackupAddr0, bufflength);
1152#else
1153 /* Link callback */
1154 HAL_ETH_RxLinkCallback(&heth->RxDescList.pRxStart, &heth->RxDescList.pRxEnd,
1155 (uint8_t *)dmarxdesc->BackupAddr0, (uint16_t) bufflength);
1156#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
1157 heth->RxDescList.RxDescCnt++;
1158 heth->RxDescList.RxDataLength += bufflength;
1159
1160 /* Clear buffer pointer */
1161 dmarxdesc->BackupAddr0 = 0;
1162 }
1163
1164 /* Increment current rx descriptor index */
1165 INCR_RX_DESC_INDEX(descidx, 1U);
1166 /* Get current descriptor address */
1167 dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descidx];
1168 desccnt++;
1169 }
1170
1171 heth->RxDescList.RxBuildDescCnt += desccnt;
1172 if ((heth->RxDescList.RxBuildDescCnt) != 0U)
1173 {
1174 /* Update Descriptors */
1175 ETH_UpdateDescriptor(heth);
1176 }
1177
1178 heth->RxDescList.RxDescIdx = descidx;
1179
1180 if (rxdataready == 1U)
1181 {
1182 /* Return received packet */
1183 *pAppBuff = heth->RxDescList.pRxStart;
1184 /* Reset first element */
1185 heth->RxDescList.pRxStart = NULL;
1186
1187 return HAL_OK;
1188 }
1189
1190 /* Packet not ready */
1191 return HAL_ERROR;
1192}
1193
1202static void ETH_UpdateDescriptor(ETH_HandleTypeDef *heth)
1203{
1204 uint32_t descidx;
1205 uint32_t tailidx;
1206 uint32_t desccount;
1207 ETH_DMADescTypeDef *dmarxdesc;
1208 uint8_t *buff = NULL;
1209 uint8_t allocStatus = 1U;
1210
1211 descidx = heth->RxDescList.RxBuildDescIdx;
1212 dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descidx];
1213 desccount = heth->RxDescList.RxBuildDescCnt;
1214
1215 while ((desccount > 0U) && (allocStatus != 0U))
1216 {
1217 /* Check if a buffer's attached the descriptor */
1218 if (READ_REG(dmarxdesc->BackupAddr0) == 0U)
1219 {
1220 /* Get a new buffer. */
1221#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1222 /*Call registered Allocate callback*/
1223 heth->rxAllocateCallback(&buff);
1224#else
1225 /* Allocate callback */
1226 HAL_ETH_RxAllocateCallback(&buff);
1227#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
1228 if (buff == NULL)
1229 {
1230 allocStatus = 0U;
1231 }
1232 else
1233 {
1234 WRITE_REG(dmarxdesc->BackupAddr0, (uint32_t)buff);
1235 WRITE_REG(dmarxdesc->DESC2, (uint32_t)buff);
1236 }
1237 }
1238
1239 if (allocStatus != 0U)
1240 {
1241 if (heth->RxDescList.ItMode == 0U)
1242 {
1243 WRITE_REG(dmarxdesc->DESC1, heth->Init.RxBuffLen | ETH_DMARXDESC_DIC | ETH_DMARXDESC_RCH);
1244 }
1245 else
1246 {
1247 WRITE_REG(dmarxdesc->DESC1, heth->Init.RxBuffLen | ETH_DMARXDESC_RCH);
1248 }
1249
1250 SET_BIT(dmarxdesc->DESC0, ETH_DMARXDESC_OWN);
1251
1252 /* Increment current rx descriptor index */
1253 INCR_RX_DESC_INDEX(descidx, 1U);
1254 /* Get current descriptor address */
1255 dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descidx];
1256 desccount--;
1257 }
1258 }
1259
1260 if (heth->RxDescList.RxBuildDescCnt != desccount)
1261 {
1262 /* Set the tail pointer index */
1263 tailidx = (ETH_RX_DESC_CNT + descidx - 1U) % ETH_RX_DESC_CNT;
1264
1265 /* DMB instruction to avoid race condition */
1266 __DMB();
1267
1268 /* Set the Tail pointer address */
1269 WRITE_REG(heth->Instance->DMARPDR, ((uint32_t)(heth->Init.RxDesc + (tailidx))));
1270
1271 heth->RxDescList.RxBuildDescIdx = descidx;
1272 heth->RxDescList.RxBuildDescCnt = desccount;
1273 }
1274}
1275
1283HAL_StatusTypeDef HAL_ETH_RegisterRxAllocateCallback(ETH_HandleTypeDef *heth,
1284 pETH_rxAllocateCallbackTypeDef rxAllocateCallback)
1285{
1286 if (rxAllocateCallback == NULL)
1287 {
1288 /* No buffer to save */
1289 return HAL_ERROR;
1290 }
1291
1292 /* Set function to allocate buffer */
1293 heth->rxAllocateCallback = rxAllocateCallback;
1294
1295 return HAL_OK;
1296}
1297
1304HAL_StatusTypeDef HAL_ETH_UnRegisterRxAllocateCallback(ETH_HandleTypeDef *heth)
1305{
1306 /* Set function to allocate buffer */
1307 heth->rxAllocateCallback = HAL_ETH_RxAllocateCallback;
1308
1309 return HAL_OK;
1310}
1311
1317__weak void HAL_ETH_RxAllocateCallback(uint8_t **buff)
1318{
1319 /* Prevent unused argument(s) compilation warning */
1320 UNUSED(buff);
1321 /* NOTE : This function Should not be modified, when the callback is needed,
1322 the HAL_ETH_RxAllocateCallback could be implemented in the user file
1323 */
1324}
1325
1334__weak void HAL_ETH_RxLinkCallback(void **pStart, void **pEnd, uint8_t *buff, uint16_t Length)
1335{
1336 /* Prevent unused argument(s) compilation warning */
1337 UNUSED(pStart);
1338 UNUSED(pEnd);
1339 UNUSED(buff);
1340 UNUSED(Length);
1341 /* NOTE : This function Should not be modified, when the callback is needed,
1342 the HAL_ETH_RxLinkCallback could be implemented in the user file
1343 */
1344}
1345
1353HAL_StatusTypeDef HAL_ETH_RegisterRxLinkCallback(ETH_HandleTypeDef *heth, pETH_rxLinkCallbackTypeDef rxLinkCallback)
1354{
1355 if (rxLinkCallback == NULL)
1356 {
1357 /* No buffer to save */
1358 return HAL_ERROR;
1359 }
1360
1361 /* Set function to link data */
1362 heth->rxLinkCallback = rxLinkCallback;
1363
1364 return HAL_OK;
1365}
1366
1373HAL_StatusTypeDef HAL_ETH_UnRegisterRxLinkCallback(ETH_HandleTypeDef *heth)
1374{
1375 /* Set function to allocate buffer */
1376 heth->rxLinkCallback = HAL_ETH_RxLinkCallback;
1377
1378 return HAL_OK;
1379}
1380
1388HAL_StatusTypeDef HAL_ETH_GetRxDataErrorCode(const ETH_HandleTypeDef *heth, uint32_t *pErrorCode)
1389{
1390 /* Get error bits. */
1391 *pErrorCode = READ_BIT(heth->RxDescList.pRxLastRxDesc, ETH_DMARXDESC_ERRORS_MASK);
1392
1393 return HAL_OK;
1394}
1395
1403HAL_StatusTypeDef HAL_ETH_RegisterTxFreeCallback(ETH_HandleTypeDef *heth, pETH_txFreeCallbackTypeDef txFreeCallback)
1404{
1405 if (txFreeCallback == NULL)
1406 {
1407 /* No buffer to save */
1408 return HAL_ERROR;
1409 }
1410
1411 /* Set function to free transmmitted packet */
1412 heth->txFreeCallback = txFreeCallback;
1413
1414 return HAL_OK;
1415}
1416
1423HAL_StatusTypeDef HAL_ETH_UnRegisterTxFreeCallback(ETH_HandleTypeDef *heth)
1424{
1425 /* Set function to allocate buffer */
1426 heth->txFreeCallback = HAL_ETH_TxFreeCallback;
1427
1428 return HAL_OK;
1429}
1430
1436__weak void HAL_ETH_TxFreeCallback(uint32_t *buff)
1437{
1438 /* Prevent unused argument(s) compilation warning */
1439 UNUSED(buff);
1440 /* NOTE : This function Should not be modified, when the callback is needed,
1441 the HAL_ETH_TxFreeCallback could be implemented in the user file
1442 */
1443}
1444
1451HAL_StatusTypeDef HAL_ETH_ReleaseTxPacket(ETH_HandleTypeDef *heth)
1452{
1453 ETH_TxDescListTypeDef *dmatxdesclist = &heth->TxDescList;
1454 uint32_t numOfBuf = dmatxdesclist->BuffersInUse;
1455 uint32_t idx = dmatxdesclist->releaseIndex;
1456 uint8_t pktTxStatus = 1U;
1457 uint8_t pktInUse;
1458#ifdef HAL_ETH_USE_PTP
1459 ETH_TimeStampTypeDef *timestamp = &heth->TxTimestamp;
1460#endif /* HAL_ETH_USE_PTP */
1461
1462 /* Loop through buffers in use. */
1463 while ((numOfBuf != 0U) && (pktTxStatus != 0U))
1464 {
1465 pktInUse = 1U;
1466 numOfBuf--;
1467 /* If no packet, just examine the next packet. */
1468 if (dmatxdesclist->PacketAddress[idx] == NULL)
1469 {
1470 /* No packet in use, skip to next. */
1471 INCR_TX_DESC_INDEX(idx, 1U);
1472 pktInUse = 0U;
1473 }
1474
1475 if (pktInUse != 0U)
1476 {
1477 /* Determine if the packet has been transmitted. */
1478 if ((heth->Init.TxDesc[idx].DESC0 & ETH_DMATXDESC_OWN) == 0U)
1479 {
1480#ifdef HAL_ETH_USE_PTP
1481 if ((heth->Init.TxDesc[idx].DESC0 & ETH_DMATXDESC_LS)
1482 && (heth->Init.TxDesc[idx].DESC0 & ETH_DMATXDESC_TTSS))
1483 {
1484 /* Get timestamp low */
1485 timestamp->TimeStampLow = heth->Init.TxDesc[idx].DESC6;
1486 /* Get timestamp high */
1487 timestamp->TimeStampHigh = heth->Init.TxDesc[idx].DESC7;
1488 }
1489 else
1490 {
1491 timestamp->TimeStampHigh = timestamp->TimeStampLow = UINT32_MAX;
1492 }
1493#endif /* HAL_ETH_USE_PTP */
1494
1495#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1496 /*Call registered callbacks*/
1497#ifdef HAL_ETH_USE_PTP
1498 /* Handle Ptp */
1499 if (timestamp->TimeStampHigh != UINT32_MAX && timestamp->TimeStampLow != UINT32_MAX)
1500 {
1501 heth->txPtpCallback(dmatxdesclist->PacketAddress[idx], timestamp);
1502 }
1503#endif /* HAL_ETH_USE_PTP */
1504 /* Release the packet. */
1505 heth->txFreeCallback(dmatxdesclist->PacketAddress[idx]);
1506#else
1507 /* Call callbacks */
1508#ifdef HAL_ETH_USE_PTP
1509 /* Handle Ptp */
1510 if (timestamp->TimeStampHigh != UINT32_MAX && timestamp->TimeStampLow != UINT32_MAX)
1511 {
1512 HAL_ETH_TxPtpCallback(dmatxdesclist->PacketAddress[idx], timestamp);
1513 }
1514#endif /* HAL_ETH_USE_PTP */
1515 /* Release the packet. */
1516 HAL_ETH_TxFreeCallback(dmatxdesclist->PacketAddress[idx]);
1517#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
1518
1519 /* Clear the entry in the in-use array. */
1520 dmatxdesclist->PacketAddress[idx] = NULL;
1521
1522 /* Update the transmit relesae index and number of buffers in use. */
1523 INCR_TX_DESC_INDEX(idx, 1U);
1524 dmatxdesclist->BuffersInUse = numOfBuf;
1525 dmatxdesclist->releaseIndex = idx;
1526 }
1527 else
1528 {
1529 /* Get out of the loop! */
1530 pktTxStatus = 0U;
1531 }
1532 }
1533 }
1534 return HAL_OK;
1535}
1536
1537#ifdef HAL_ETH_USE_PTP
1546HAL_StatusTypeDef HAL_ETH_PTP_SetConfig(ETH_HandleTypeDef *heth, ETH_PTP_ConfigTypeDef *ptpconfig)
1547{
1548 uint32_t tmpTSCR;
1549 ETH_TimeTypeDef time;
1550
1551 if (ptpconfig == NULL)
1552 {
1553 return HAL_ERROR;
1554 }
1555
1556 /* Mask the Timestamp Trigger interrupt */
1557 CLEAR_BIT(heth->Instance->MACIMR, ETH_MACIMR_TSTIM);
1558
1559 tmpTSCR = ptpconfig->Timestamp |
1560 ((uint32_t)ptpconfig->TimestampUpdate << ETH_PTPTSCR_TSFCU_Pos) |
1561 ((uint32_t)ptpconfig->TimestampAll << ETH_PTPTSCR_TSSARFE_Pos) |
1562 ((uint32_t)ptpconfig->TimestampRolloverMode << ETH_PTPTSCR_TSSSR_Pos) |
1563 ((uint32_t)ptpconfig->TimestampV2 << ETH_PTPTSCR_TSPTPPSV2E_Pos) |
1564 ((uint32_t)ptpconfig->TimestampEthernet << ETH_PTPTSCR_TSSPTPOEFE_Pos) |
1565 ((uint32_t)ptpconfig->TimestampIPv6 << ETH_PTPTSCR_TSSIPV6FE_Pos) |
1566 ((uint32_t)ptpconfig->TimestampIPv4 << ETH_PTPTSCR_TSSIPV4FE_Pos) |
1567 ((uint32_t)ptpconfig->TimestampEvent << ETH_PTPTSCR_TSSEME_Pos) |
1568 ((uint32_t)ptpconfig->TimestampMaster << ETH_PTPTSCR_TSSMRME_Pos) |
1569 ((uint32_t)ptpconfig->TimestampFilter << ETH_PTPTSCR_TSPFFMAE_Pos) |
1570 ((uint32_t)ptpconfig->TimestampClockType << ETH_PTPTSCR_TSCNT_Pos);
1571
1572 /* Write to MACTSCR */
1573 MODIFY_REG(heth->Instance->PTPTSCR, ETH_MACTSCR_MASK, tmpTSCR);
1574
1575 /* Enable Timestamp */
1576 SET_BIT(heth->Instance->PTPTSCR, ETH_PTPTSCR_TSE);
1577 WRITE_REG(heth->Instance->PTPSSIR, ptpconfig->TimestampSubsecondInc);
1578 WRITE_REG(heth->Instance->PTPTSAR, ptpconfig->TimestampAddend);
1579
1580 /* Enable Timestamp */
1581 if (ptpconfig->TimestampAddendUpdate == ENABLE)
1582 {
1583 SET_BIT(heth->Instance->PTPTSCR, ETH_PTPTSCR_TSARU);
1584 while ((heth->Instance->PTPTSCR & ETH_PTPTSCR_TSARU) != 0)
1585 {
1586
1587 }
1588 }
1589
1590 /* Enable Update mode */
1591 if (ptpconfig->TimestampUpdateMode == ENABLE)
1592 {
1593 SET_BIT(heth->Instance->PTPTSCR, ETH_PTPTSCR_TSFCU);
1594 }
1595
1596 /* Set PTP Configuration done */
1597 heth->IsPtpConfigured = HAL_ETH_PTP_CONFIGURED;
1598
1599 /* Set Seconds */
1600 time.Seconds = heth->Instance->PTPTSHR;
1601 /* Set NanoSeconds */
1602 time.NanoSeconds = heth->Instance->PTPTSLR;
1603
1604 HAL_ETH_PTP_SetTime(heth, &time);
1605
1606 /* Ptp Init */
1607 SET_BIT(heth->Instance->PTPTSCR, ETH_PTPTSCR_TSSTI);
1608
1609 /* Return function status */
1610 return HAL_OK;
1611}
1612
1621HAL_StatusTypeDef HAL_ETH_PTP_GetConfig(ETH_HandleTypeDef *heth, ETH_PTP_ConfigTypeDef *ptpconfig)
1622{
1623 if (ptpconfig == NULL)
1624 {
1625 return HAL_ERROR;
1626 }
1627 ptpconfig->Timestamp = READ_BIT(heth->Instance->PTPTSCR, ETH_PTPTSCR_TSE);
1628 ptpconfig->TimestampUpdate = ((READ_BIT(heth->Instance->PTPTSCR,
1629 ETH_PTPTSCR_TSFCU) >> ETH_PTPTSCR_TSFCU_Pos) > 0U) ? ENABLE : DISABLE;
1630 ptpconfig->TimestampAll = ((READ_BIT(heth->Instance->PTPTSCR,
1631 ETH_PTPTSCR_TSSARFE) >> ETH_PTPTSCR_TSSARFE_Pos) > 0U) ? ENABLE : DISABLE;
1632 ptpconfig->TimestampRolloverMode = ((READ_BIT(heth->Instance->PTPTSCR,
1633 ETH_PTPTSCR_TSSSR) >> ETH_PTPTSCR_TSSSR_Pos) > 0U)
1634 ? ENABLE : DISABLE;
1635 ptpconfig->TimestampV2 = ((READ_BIT(heth->Instance->PTPTSCR,
1636 ETH_PTPTSCR_TSPTPPSV2E) >> ETH_PTPTSCR_TSPTPPSV2E_Pos) > 0U) ? ENABLE : DISABLE;
1637 ptpconfig->TimestampEthernet = ((READ_BIT(heth->Instance->PTPTSCR,
1638 ETH_PTPTSCR_TSSPTPOEFE) >> ETH_PTPTSCR_TSSPTPOEFE_Pos) > 0U)
1639 ? ENABLE : DISABLE;
1640 ptpconfig->TimestampIPv6 = ((READ_BIT(heth->Instance->PTPTSCR,
1641 ETH_PTPTSCR_TSSIPV6FE) >> ETH_PTPTSCR_TSSIPV6FE_Pos) > 0U) ? ENABLE : DISABLE;
1642 ptpconfig->TimestampIPv4 = ((READ_BIT(heth->Instance->PTPTSCR,
1643 ETH_PTPTSCR_TSSIPV4FE) >> ETH_PTPTSCR_TSSIPV4FE_Pos) > 0U) ? ENABLE : DISABLE;
1644 ptpconfig->TimestampEvent = ((READ_BIT(heth->Instance->PTPTSCR,
1645 ETH_PTPTSCR_TSSEME) >> ETH_PTPTSCR_TSSEME_Pos) > 0U) ? ENABLE : DISABLE;
1646 ptpconfig->TimestampMaster = ((READ_BIT(heth->Instance->PTPTSCR,
1647 ETH_PTPTSCR_TSSMRME) >> ETH_PTPTSCR_TSSMRME_Pos) > 0U) ? ENABLE : DISABLE;
1648 ptpconfig->TimestampFilter = ((READ_BIT(heth->Instance->PTPTSCR,
1649 ETH_PTPTSCR_TSPFFMAE) >> ETH_PTPTSCR_TSPFFMAE_Pos) > 0U) ? ENABLE : DISABLE;
1650 ptpconfig->TimestampClockType = ((READ_BIT(heth->Instance->PTPTSCR,
1651 ETH_PTPTSCR_TSCNT) >> ETH_PTPTSCR_TSCNT_Pos) > 0U) ? ENABLE : DISABLE;
1652
1653 /* Return function status */
1654 return HAL_OK;
1655}
1656
1665HAL_StatusTypeDef HAL_ETH_PTP_SetTime(ETH_HandleTypeDef *heth, ETH_TimeTypeDef *time)
1666{
1667 if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED)
1668 {
1669 /* Set Seconds */
1670 heth->Instance->PTPTSHUR = time->Seconds;
1671
1672 /* Set NanoSeconds */
1673 heth->Instance->PTPTSLUR = time->NanoSeconds;
1674
1675 /* the system time is updated */
1676 SET_BIT(heth->Instance->PTPTSCR, ETH_PTPTSCR_TSSTU);
1677
1678 /* Return function status */
1679 return HAL_OK;
1680 }
1681 else
1682 {
1683 /* Return function status */
1684 return HAL_ERROR;
1685 }
1686}
1687
1696HAL_StatusTypeDef HAL_ETH_PTP_GetTime(ETH_HandleTypeDef *heth, ETH_TimeTypeDef *time)
1697{
1698 if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED)
1699 {
1700 /* Get Seconds */
1701 time->Seconds = heth->Instance->PTPTSHR;
1702 /* Get NanoSeconds */
1703 time->NanoSeconds = heth->Instance->PTPTSLR;
1704
1705 /* Return function status */
1706 return HAL_OK;
1707 }
1708 else
1709 {
1710 /* Return function status */
1711 return HAL_ERROR;
1712 }
1713}
1714
1723HAL_StatusTypeDef HAL_ETH_PTP_AddTimeOffset(ETH_HandleTypeDef *heth, ETH_PtpUpdateTypeDef ptpoffsettype,
1724 ETH_TimeTypeDef *timeoffset)
1725{
1726 int32_t addendtime ;
1727 if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED)
1728 {
1729 if (ptpoffsettype == HAL_ETH_PTP_NEGATIVE_UPDATE)
1730 {
1731 /* Set Seconds update */
1732 heth->Instance->PTPTSHUR = ETH_PTPTSHR_VALUE - timeoffset->Seconds + 1U;
1733
1734 if (READ_BIT(heth->Instance->PTPTSCR, ETH_PTPTSCR_TSSSR) == ETH_PTPTSCR_TSSSR)
1735 {
1736 /* Set nanoSeconds update */
1737 heth->Instance->PTPTSLUR = ETH_PTPTSLR_VALUE - timeoffset->NanoSeconds;
1738 }
1739 else
1740 {
1741 heth->Instance->PTPTSLUR = ETH_PTPTSHR_VALUE - timeoffset->NanoSeconds + 1U;
1742 }
1743
1744 /* adjust negative addend register */
1745 addendtime = - timeoffset->NanoSeconds;
1746 HAL_ETH_PTP_AddendUpdate(heth, addendtime);
1747
1748 }
1749 else
1750 {
1751 /* Set Seconds update */
1752 heth->Instance->PTPTSHUR = timeoffset->Seconds;
1753 /* Set nanoSeconds update */
1754 heth->Instance->PTPTSLUR = timeoffset->NanoSeconds;
1755
1756 /* adjust positive addend register */
1757 addendtime = timeoffset->NanoSeconds;
1758 HAL_ETH_PTP_AddendUpdate(heth, addendtime);
1759
1760 }
1761
1762 SET_BIT(heth->Instance->PTPTSCR, ETH_PTPTSCR_TSSTU);
1763
1764 /* Return function status */
1765 return HAL_OK;
1766 }
1767 else
1768 {
1769 /* Return function status */
1770 return HAL_ERROR;
1771 }
1772}
1773
1782static HAL_StatusTypeDef HAL_ETH_PTP_AddendUpdate(ETH_HandleTypeDef *heth, int32_t timeoffset)
1783{
1784 uint32_t tmpreg;
1785 if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED)
1786 {
1787 /* update the addend register */
1788
1789 tmpreg = READ_REG(heth->Instance->PTPTSAR);
1790 tmpreg += timeoffset ;
1791 WRITE_REG(heth->Instance->PTPTSAR, tmpreg);
1792
1793 SET_BIT(heth->Instance->PTPTSCR, ETH_PTPTSCR_TSARU);
1794 while ((heth->Instance->PTPTSCR & ETH_PTPTSCR_TSARU) != 0)
1795 {
1796
1797 }
1798
1799 /* Return function status */
1800 return HAL_OK;
1801 }
1802 else
1803 {
1804 /* Return function status */
1805 return HAL_ERROR;
1806 }
1807}
1814HAL_StatusTypeDef HAL_ETH_PTP_InsertTxTimestamp(ETH_HandleTypeDef *heth)
1815{
1816 ETH_TxDescListTypeDef *dmatxdesclist = &heth->TxDescList;
1817 uint32_t descidx = dmatxdesclist->CurTxDesc;
1818 ETH_DMADescTypeDef *dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx];
1819
1820 if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED)
1821 {
1822 /* Enable Time Stamp transmission */
1823 SET_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_TTSE);
1824
1825 /* Return function status */
1826 return HAL_OK;
1827 }
1828 else
1829 {
1830 /* Return function status */
1831 return HAL_ERROR;
1832 }
1833}
1834
1843HAL_StatusTypeDef HAL_ETH_PTP_GetTxTimestamp(ETH_HandleTypeDef *heth, ETH_TimeStampTypeDef *timestamp)
1844{
1845 ETH_TxDescListTypeDef *dmatxdesclist = &heth->TxDescList;
1846 uint32_t idx = dmatxdesclist->releaseIndex;
1847 ETH_DMADescTypeDef *dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[idx];
1848
1849 if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED)
1850 {
1851 /* Get timestamp low */
1852 timestamp->TimeStampLow = dmatxdesc->DESC0;
1853 /* Get timestamp high */
1854 timestamp->TimeStampHigh = dmatxdesc->DESC1;
1855
1856 /* Return function status */
1857 return HAL_OK;
1858 }
1859 else
1860 {
1861 /* Return function status */
1862 return HAL_ERROR;
1863 }
1864}
1865
1874HAL_StatusTypeDef HAL_ETH_PTP_GetRxTimestamp(ETH_HandleTypeDef *heth, ETH_TimeStampTypeDef *timestamp)
1875{
1876 if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED)
1877 {
1878 /* Get timestamp low */
1879 timestamp->TimeStampLow = heth->RxDescList.TimeStamp.TimeStampLow;
1880 /* Get timestamp high */
1881 timestamp->TimeStampHigh = heth->RxDescList.TimeStamp.TimeStampHigh;
1882
1883 /* Return function status */
1884 return HAL_OK;
1885 }
1886 else
1887 {
1888 /* Return function status */
1889 return HAL_ERROR;
1890 }
1891}
1892
1900HAL_StatusTypeDef HAL_ETH_RegisterTxPtpCallback(ETH_HandleTypeDef *heth, pETH_txPtpCallbackTypeDef txPtpCallback)
1901{
1902 if (txPtpCallback == NULL)
1903 {
1904 /* No buffer to save */
1905 return HAL_ERROR;
1906 }
1907 /* Set Function to handle Tx Ptp */
1908 heth->txPtpCallback = txPtpCallback;
1909
1910 return HAL_OK;
1911}
1912
1919HAL_StatusTypeDef HAL_ETH_UnRegisterTxPtpCallback(ETH_HandleTypeDef *heth)
1920{
1921 /* Set function to allocate buffer */
1922 heth->txPtpCallback = HAL_ETH_TxPtpCallback;
1923
1924 return HAL_OK;
1925}
1926
1934__weak void HAL_ETH_TxPtpCallback(uint32_t *buff, ETH_TimeStampTypeDef *timestamp)
1935{
1936 /* Prevent unused argument(s) compilation warning */
1937 UNUSED(buff);
1938 /* NOTE : This function Should not be modified, when the callback is needed,
1939 the HAL_ETH_TxPtpCallback could be implemented in the user file
1940 */
1941}
1942#endif /* HAL_ETH_USE_PTP */
1943
1950void HAL_ETH_IRQHandler(ETH_HandleTypeDef *heth)
1951{
1952 uint32_t mac_flag = READ_REG(heth->Instance->MACSR);
1953 uint32_t dma_flag = READ_REG(heth->Instance->DMASR);
1954 uint32_t dma_itsource = READ_REG(heth->Instance->DMAIER);
1955 uint32_t exti_flag = READ_REG(EXTI->PR);
1956
1957 /* Packet received */
1958 if (((dma_flag & ETH_DMASR_RS) != 0U) && ((dma_itsource & ETH_DMAIER_RIE) != 0U))
1959 {
1960 /* Clear the Eth DMA Rx IT pending bits */
1961 __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMASR_RS | ETH_DMASR_NIS);
1962
1963#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1964 /*Call registered Receive complete callback*/
1965 heth->RxCpltCallback(heth);
1966#else
1967 /* Receive complete callback */
1968 HAL_ETH_RxCpltCallback(heth);
1969#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
1970 }
1971
1972 /* Packet transmitted */
1973 if (((dma_flag & ETH_DMASR_TS) != 0U) && ((dma_itsource & ETH_DMAIER_TIE) != 0U))
1974 {
1975 /* Clear the Eth DMA Tx IT pending bits */
1976 __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMASR_TS | ETH_DMASR_NIS);
1977
1978#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1979 /*Call registered Transmit complete callback*/
1980 heth->TxCpltCallback(heth);
1981#else
1982 /* Transfer complete callback */
1983 HAL_ETH_TxCpltCallback(heth);
1984#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
1985 }
1986
1987 /* ETH DMA Error */
1988 if (((dma_flag & ETH_DMASR_AIS) != 0U) && ((dma_itsource & ETH_DMAIER_AISE) != 0U))
1989 {
1990 heth->ErrorCode |= HAL_ETH_ERROR_DMA;
1991 /* if fatal bus error occurred */
1992 if ((dma_flag & ETH_DMASR_FBES) != 0U)
1993 {
1994 /* Get DMA error code */
1995 heth->DMAErrorCode = READ_BIT(heth->Instance->DMASR, (ETH_DMASR_FBES | ETH_DMASR_TPS | ETH_DMASR_RPS));
1996
1997 /* Disable all interrupts */
1998 __HAL_ETH_DMA_DISABLE_IT(heth, ETH_DMAIER_NISE | ETH_DMAIER_AISE);
1999
2000 /* Set HAL state to ERROR */
2001 heth->gState = HAL_ETH_STATE_ERROR;
2002 }
2003 else
2004 {
2005 /* Get DMA error status */
2006 heth->DMAErrorCode = READ_BIT(heth->Instance->DMASR, (ETH_DMASR_ETS | ETH_DMASR_RWTS |
2007 ETH_DMASR_RBUS | ETH_DMASR_AIS));
2008
2009 /* Clear the interrupt summary flag */
2010 __HAL_ETH_DMA_CLEAR_IT(heth, (ETH_DMASR_ETS | ETH_DMASR_RWTS |
2011 ETH_DMASR_RBUS | ETH_DMASR_AIS));
2012 }
2013#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
2014 /* Call registered Error callback*/
2015 heth->ErrorCallback(heth);
2016#else
2017 /* Ethernet DMA Error callback */
2018 HAL_ETH_ErrorCallback(heth);
2019#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
2020 }
2021
2022
2023 /* ETH PMT IT */
2024 if ((mac_flag & ETH_MAC_PMT_IT) != 0U)
2025 {
2026 /* Get MAC Wake-up source and clear the status register pending bit */
2027 heth->MACWakeUpEvent = READ_BIT(heth->Instance->MACPMTCSR, (ETH_MACPMTCSR_WFR | ETH_MACPMTCSR_MPR));
2028
2029#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
2030 /* Call registered PMT callback*/
2031 heth->PMTCallback(heth);
2032#else
2033 /* Ethernet PMT callback */
2034 HAL_ETH_PMTCallback(heth);
2035#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
2036
2037 heth->MACWakeUpEvent = (uint32_t)(0x0U);
2038 }
2039
2040
2041 /* check ETH WAKEUP exti flag */
2042 if ((exti_flag & ETH_WAKEUP_EXTI_LINE) != 0U)
2043 {
2044 /* Clear ETH WAKEUP Exti pending bit */
2045 __HAL_ETH_WAKEUP_EXTI_CLEAR_FLAG(ETH_WAKEUP_EXTI_LINE);
2046#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
2047 /* Call registered WakeUp callback*/
2048 heth->WakeUpCallback(heth);
2049#else
2050 /* ETH WAKEUP callback */
2051 HAL_ETH_WakeUpCallback(heth);
2052#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
2053 }
2054}
2055
2062__weak void HAL_ETH_TxCpltCallback(ETH_HandleTypeDef *heth)
2063{
2064 /* Prevent unused argument(s) compilation warning */
2065 UNUSED(heth);
2066 /* NOTE : This function Should not be modified, when the callback is needed,
2067 the HAL_ETH_TxCpltCallback could be implemented in the user file
2068 */
2069}
2070
2077__weak void HAL_ETH_RxCpltCallback(ETH_HandleTypeDef *heth)
2078{
2079 /* Prevent unused argument(s) compilation warning */
2080 UNUSED(heth);
2081 /* NOTE : This function Should not be modified, when the callback is needed,
2082 the HAL_ETH_RxCpltCallback could be implemented in the user file
2083 */
2084}
2085
2092__weak void HAL_ETH_ErrorCallback(ETH_HandleTypeDef *heth)
2093{
2094 /* Prevent unused argument(s) compilation warning */
2095 UNUSED(heth);
2096 /* NOTE : This function Should not be modified, when the callback is needed,
2097 the HAL_ETH_ErrorCallback could be implemented in the user file
2098 */
2099}
2100
2107__weak void HAL_ETH_PMTCallback(ETH_HandleTypeDef *heth)
2108{
2109 /* Prevent unused argument(s) compilation warning */
2110 UNUSED(heth);
2111 /* NOTE : This function Should not be modified, when the callback is needed,
2112 the HAL_ETH_PMTCallback could be implemented in the user file
2113 */
2114}
2115
2116
2123__weak void HAL_ETH_WakeUpCallback(ETH_HandleTypeDef *heth)
2124{
2125 /* Prevent unused argument(s) compilation warning */
2126 UNUSED(heth);
2127 /* NOTE : This function Should not be modified, when the callback is needed,
2128 the HAL_ETH_WakeUpCallback could be implemented in the user file
2129 */
2130}
2131
2141HAL_StatusTypeDef HAL_ETH_ReadPHYRegister(ETH_HandleTypeDef *heth, uint32_t PHYAddr, uint32_t PHYReg,
2142 uint32_t *pRegValue)
2143{
2144 uint32_t tmpreg1;
2145 uint32_t tickstart;
2146
2147 /* Get the ETHERNET MACMIIAR value */
2148 tmpreg1 = heth->Instance->MACMIIAR;
2149
2150 /* Keep only the CSR Clock Range CR[2:0] bits value */
2151 tmpreg1 &= ~ETH_MACMIIAR_CR_MASK;
2152
2153 /* Prepare the MII address register value */
2154 tmpreg1 |= ((PHYAddr << 11U) & ETH_MACMIIAR_PA); /* Set the PHY device address */
2155 tmpreg1 |= (((uint32_t)PHYReg << 6U) & ETH_MACMIIAR_MR); /* Set the PHY register address */
2156 tmpreg1 &= ~ETH_MACMIIAR_MW; /* Set the read mode */
2157 tmpreg1 |= ETH_MACMIIAR_MB; /* Set the MII Busy bit */
2158
2159 /* Write the result value into the MII Address register */
2160 heth->Instance->MACMIIAR = tmpreg1;
2161
2162
2163 tickstart = HAL_GetTick();
2164
2165 /* Check for the Busy flag */
2166 while ((tmpreg1 & ETH_MACMIIAR_MB) == ETH_MACMIIAR_MB)
2167 {
2168 /* Check for the Timeout */
2169 if ((HAL_GetTick() - tickstart) > PHY_READ_TO)
2170 {
2171 return HAL_ERROR;
2172 }
2173
2174 tmpreg1 = heth->Instance->MACMIIAR;
2175 }
2176
2177 /* Get MACMIIDR value */
2178 *pRegValue = (uint16_t)(heth->Instance->MACMIIDR);
2179
2180 return HAL_OK;
2181}
2182
2192HAL_StatusTypeDef HAL_ETH_WritePHYRegister(const ETH_HandleTypeDef *heth, uint32_t PHYAddr, uint32_t PHYReg,
2193 uint32_t RegValue)
2194{
2195 uint32_t tmpreg1;
2196 uint32_t tickstart;
2197
2198 /* Get the ETHERNET MACMIIAR value */
2199 tmpreg1 = heth->Instance->MACMIIAR;
2200
2201 /* Keep only the CSR Clock Range CR[2:0] bits value */
2202 tmpreg1 &= ~ETH_MACMIIAR_CR_MASK;
2203
2204 /* Prepare the MII register address value */
2205 tmpreg1 |= ((PHYAddr << 11U) & ETH_MACMIIAR_PA); /* Set the PHY device address */
2206 tmpreg1 |= (((uint32_t)PHYReg << 6U) & ETH_MACMIIAR_MR); /* Set the PHY register address */
2207 tmpreg1 |= ETH_MACMIIAR_MW; /* Set the write mode */
2208 tmpreg1 |= ETH_MACMIIAR_MB; /* Set the MII Busy bit */
2209
2210 /* Give the value to the MII data register */
2211 heth->Instance->MACMIIDR = (uint16_t)RegValue;
2212
2213 /* Write the result value into the MII Address register */
2214 heth->Instance->MACMIIAR = tmpreg1;
2215
2216 /* Get tick */
2217 tickstart = HAL_GetTick();
2218
2219 /* Check for the Busy flag */
2220 while ((tmpreg1 & ETH_MACMIIAR_MB) == ETH_MACMIIAR_MB)
2221 {
2222 /* Check for the Timeout */
2223 if ((HAL_GetTick() - tickstart) > PHY_WRITE_TO)
2224 {
2225 return HAL_ERROR;
2226 }
2227
2228 tmpreg1 = heth->Instance->MACMIIAR;
2229 }
2230
2231 return HAL_OK;
2232}
2233
2237
2260HAL_StatusTypeDef HAL_ETH_GetMACConfig(const ETH_HandleTypeDef *heth, ETH_MACConfigTypeDef *macconf)
2261{
2262 if (macconf == NULL)
2263 {
2264 return HAL_ERROR;
2265 }
2266
2267 /* Get MAC parameters */
2268 macconf->DeferralCheck = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_DC) >> 4) > 0U) ? ENABLE : DISABLE;
2269 macconf->BackOffLimit = READ_BIT(heth->Instance->MACCR, ETH_MACCR_BL);
2270 macconf->RetryTransmission = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_RD) >> 9) == 0U) ? ENABLE : DISABLE;
2271 macconf->CarrierSenseDuringTransmit = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_CSD) >> 16) > 0U)
2272 ? ENABLE : DISABLE;
2273 macconf->ReceiveOwn = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_ROD) >> 13) == 0U) ? ENABLE : DISABLE;
2274 macconf->LoopbackMode = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_LM) >> 12) > 0U) ? ENABLE : DISABLE;
2275 macconf->DuplexMode = READ_BIT(heth->Instance->MACCR, ETH_MACCR_DM);
2276 macconf->Speed = READ_BIT(heth->Instance->MACCR, ETH_MACCR_FES);
2277 macconf->Jabber = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_JD) >> 22) == 0U) ? ENABLE : DISABLE;
2278 macconf->Watchdog = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_WD) >> 23) == 0U) ? ENABLE : DISABLE;
2279 macconf->AutomaticPadCRCStrip = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_APCS) >> 7) > 0U) ? ENABLE : DISABLE;
2280 macconf->InterPacketGapVal = READ_BIT(heth->Instance->MACCR, ETH_MACCR_IFG);
2281 macconf->ChecksumOffload = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_IPCO) >> 10U) > 0U) ? ENABLE : DISABLE;
2282 macconf->CRCStripTypePacket = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_CSTF) >> 25U) > 0U) ? ENABLE : DISABLE;
2283
2284 macconf->TransmitFlowControl = ((READ_BIT(heth->Instance->MACFCR, ETH_MACFCR_TFCE) >> 1) > 0U) ? ENABLE : DISABLE;
2285 macconf->ZeroQuantaPause = ((READ_BIT(heth->Instance->MACFCR, ETH_MACFCR_ZQPD) >> 7) == 0U) ? ENABLE : DISABLE;
2286 macconf->PauseLowThreshold = READ_BIT(heth->Instance->MACFCR, ETH_MACFCR_PLT);
2287 macconf->PauseTime = (READ_BIT(heth->Instance->MACFCR, ETH_MACFCR_PT) >> 16);
2288 macconf->ReceiveFlowControl = ((READ_BIT(heth->Instance->MACFCR, ETH_MACFCR_RFCE) >> 2U) > 0U) ? ENABLE : DISABLE;
2289 macconf->UnicastPausePacketDetect = ((READ_BIT(heth->Instance->MACFCR, ETH_MACFCR_UPFD) >> 3U) > 0U)
2290 ? ENABLE : DISABLE;
2291
2292 return HAL_OK;
2293}
2294
2303HAL_StatusTypeDef HAL_ETH_GetDMAConfig(const ETH_HandleTypeDef *heth, ETH_DMAConfigTypeDef *dmaconf)
2304{
2305 if (dmaconf == NULL)
2306 {
2307 return HAL_ERROR;
2308 }
2309
2310 dmaconf->DMAArbitration = READ_BIT(heth->Instance->DMABMR,
2311 (ETH_DMAARBITRATION_RXPRIORTX | ETH_DMAARBITRATION_ROUNDROBIN_RXTX_4_1));
2312 dmaconf->AddressAlignedBeats = ((READ_BIT(heth->Instance->DMABMR, ETH_DMABMR_AAB) >> 25U) > 0U) ? ENABLE : DISABLE;
2313 dmaconf->BurstMode = READ_BIT(heth->Instance->DMABMR, ETH_DMABMR_FB | ETH_DMABMR_MB);
2314 dmaconf->RxDMABurstLength = READ_BIT(heth->Instance->DMABMR, ETH_DMABMR_RDP);
2315 dmaconf->TxDMABurstLength = READ_BIT(heth->Instance->DMABMR, ETH_DMABMR_PBL);
2316 dmaconf->EnhancedDescriptorFormat = ((READ_BIT(heth->Instance->DMABMR, ETH_DMABMR_EDE) >> 7) > 0U) ? ENABLE : DISABLE;
2317 dmaconf->DescriptorSkipLength = READ_BIT(heth->Instance->DMABMR, ETH_DMABMR_DSL) >> 2;
2318
2319 dmaconf->DropTCPIPChecksumErrorFrame = ((READ_BIT(heth->Instance->DMAOMR,
2320 ETH_DMAOMR_DTCEFD) >> 26) > 0U) ? DISABLE : ENABLE;
2321 dmaconf->ReceiveStoreForward = ((READ_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_RSF) >> 25) > 0U) ? ENABLE : DISABLE;
2322 dmaconf->FlushRxPacket = ((READ_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_FTF) >> 20) > 0U) ? DISABLE : ENABLE;
2323 dmaconf->TransmitStoreForward = ((READ_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_TSF) >> 21) > 0U) ? ENABLE : DISABLE;
2324 dmaconf->TransmitThresholdControl = READ_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_TTC);
2325 dmaconf->ForwardErrorFrames = ((READ_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_FEF) >> 7) > 0U) ? ENABLE : DISABLE;
2326 dmaconf->ForwardUndersizedGoodFrames = ((READ_BIT(heth->Instance->DMAOMR,
2327 ETH_DMAOMR_FUGF) >> 6) > 0U) ? ENABLE : DISABLE;
2328 dmaconf->ReceiveThresholdControl = READ_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_RTC);
2329 dmaconf->SecondFrameOperate = ((READ_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_OSF) >> 2) > 0U) ? ENABLE : DISABLE;
2330
2331 return HAL_OK;
2332}
2333
2342HAL_StatusTypeDef HAL_ETH_SetMACConfig(ETH_HandleTypeDef *heth, ETH_MACConfigTypeDef *macconf)
2343{
2344 if (macconf == NULL)
2345 {
2346 return HAL_ERROR;
2347 }
2348
2349 if (heth->gState == HAL_ETH_STATE_READY)
2350 {
2351 ETH_SetMACConfig(heth, macconf);
2352
2353 return HAL_OK;
2354 }
2355 else
2356 {
2357 return HAL_ERROR;
2358 }
2359}
2360
2369HAL_StatusTypeDef HAL_ETH_SetDMAConfig(ETH_HandleTypeDef *heth, ETH_DMAConfigTypeDef *dmaconf)
2370{
2371 if (dmaconf == NULL)
2372 {
2373 return HAL_ERROR;
2374 }
2375
2376 if (heth->gState == HAL_ETH_STATE_READY)
2377 {
2378 ETH_SetDMAConfig(heth, dmaconf);
2379
2380 return HAL_OK;
2381 }
2382 else
2383 {
2384 return HAL_ERROR;
2385 }
2386}
2387
2394void HAL_ETH_SetMDIOClockRange(ETH_HandleTypeDef *heth)
2395{
2396 uint32_t hclk;
2397 uint32_t tmpreg;
2398
2399 /* Get the ETHERNET MACMIIAR value */
2400 tmpreg = (heth->Instance)->MACMIIAR;
2401 /* Clear CSR Clock Range CR[2:0] bits */
2402 tmpreg &= ETH_MACMIIAR_CR_MASK;
2403
2404 /* Get hclk frequency value */
2405 hclk = HAL_RCC_GetHCLKFreq();
2406
2407 /* Set CR bits depending on hclk value */
2408 if (hclk < 35000000U)
2409 {
2410 /* CSR Clock Range between 0-35 MHz */
2411 tmpreg |= (uint32_t)ETH_MACMIIAR_CR_Div16;
2412 }
2413 else if (hclk < 60000000U)
2414 {
2415 /* CSR Clock Range between 35-60 MHz */
2416 tmpreg |= (uint32_t)ETH_MACMIIAR_CR_Div26;
2417 }
2418 else if (hclk < 100000000U)
2419 {
2420 /* CSR Clock Range between 60-100 MHz */
2421 tmpreg |= (uint32_t)ETH_MACMIIAR_CR_Div42;
2422 }
2423 else if (hclk < 150000000U)
2424 {
2425 /* CSR Clock Range between 100-150 MHz */
2426 tmpreg |= (uint32_t)ETH_MACMIIAR_CR_Div62;
2427 }
2428 else /* (hclk >= 150000000) */
2429 {
2430 /* CSR Clock >= 150 MHz */
2431 tmpreg |= (uint32_t)ETH_MACMIIAR_CR_Div102;
2432 }
2433
2434 /* Write to ETHERNET MAC MIIAR: Configure the ETHERNET CSR Clock Range */
2435 (heth->Instance)->MACMIIAR = (uint32_t)tmpreg;
2436}
2437
2446HAL_StatusTypeDef HAL_ETH_SetMACFilterConfig(ETH_HandleTypeDef *heth, const ETH_MACFilterConfigTypeDef *pFilterConfig)
2447{
2448 uint32_t filterconfig;
2449 uint32_t tmpreg1;
2450
2451 if (pFilterConfig == NULL)
2452 {
2453 return HAL_ERROR;
2454 }
2455
2456 filterconfig = ((uint32_t)pFilterConfig->PromiscuousMode |
2457 ((uint32_t)pFilterConfig->HashUnicast << 1) |
2458 ((uint32_t)pFilterConfig->HashMulticast << 2) |
2459 ((uint32_t)pFilterConfig->DestAddrInverseFiltering << 3) |
2460 ((uint32_t)pFilterConfig->PassAllMulticast << 4) |
2461 ((uint32_t)((pFilterConfig->BroadcastFilter == ENABLE) ? 1U : 0U) << 5) |
2462 ((uint32_t)pFilterConfig->SrcAddrInverseFiltering << 8) |
2463 ((uint32_t)pFilterConfig->SrcAddrFiltering << 9) |
2464 ((uint32_t)pFilterConfig->HachOrPerfectFilter << 10) |
2465 ((uint32_t)pFilterConfig->ReceiveAllMode << 31) |
2466 pFilterConfig->ControlPacketsFilter);
2467
2468 MODIFY_REG(heth->Instance->MACFFR, ETH_MACFFR_MASK, filterconfig);
2469
2470 /* Wait until the write operation will be taken into account :
2471 at least four TX_CLK/RX_CLK clock cycles */
2472 tmpreg1 = (heth->Instance)->MACFFR;
2473 HAL_Delay(ETH_REG_WRITE_DELAY);
2474 (heth->Instance)->MACFFR = tmpreg1;
2475
2476 return HAL_OK;
2477}
2478
2487HAL_StatusTypeDef HAL_ETH_GetMACFilterConfig(const ETH_HandleTypeDef *heth, ETH_MACFilterConfigTypeDef *pFilterConfig)
2488{
2489 if (pFilterConfig == NULL)
2490 {
2491 return HAL_ERROR;
2492 }
2493
2494 pFilterConfig->PromiscuousMode = ((READ_BIT(heth->Instance->MACFFR, ETH_MACFFR_PM)) > 0U) ? ENABLE : DISABLE;
2495 pFilterConfig->HashUnicast = ((READ_BIT(heth->Instance->MACFFR, ETH_MACFFR_HU) >> 1) > 0U) ? ENABLE : DISABLE;
2496 pFilterConfig->HashMulticast = ((READ_BIT(heth->Instance->MACFFR, ETH_MACFFR_HM) >> 2) > 0U) ? ENABLE : DISABLE;
2497 pFilterConfig->DestAddrInverseFiltering = ((READ_BIT(heth->Instance->MACFFR,
2498 ETH_MACFFR_DAIF) >> 3) > 0U) ? ENABLE : DISABLE;
2499 pFilterConfig->PassAllMulticast = ((READ_BIT(heth->Instance->MACFFR, ETH_MACFFR_PAM) >> 4) > 0U) ? ENABLE : DISABLE;
2500 pFilterConfig->BroadcastFilter = ((READ_BIT(heth->Instance->MACFFR, ETH_MACFFR_BFD) >> 5) > 0U) ? ENABLE : DISABLE;
2501 pFilterConfig->ControlPacketsFilter = READ_BIT(heth->Instance->MACFFR, ETH_MACFFR_PCF);
2502 pFilterConfig->SrcAddrInverseFiltering = ((READ_BIT(heth->Instance->MACFFR,
2503 ETH_MACFFR_SAIF) >> 8) > 0U) ? ENABLE : DISABLE;
2504 pFilterConfig->SrcAddrFiltering = ((READ_BIT(heth->Instance->MACFFR, ETH_MACFFR_SAF) >> 9) > 0U) ? ENABLE : DISABLE;
2505 pFilterConfig->HachOrPerfectFilter = ((READ_BIT(heth->Instance->MACFFR, ETH_MACFFR_HPF) >> 10) > 0U)
2506 ? ENABLE : DISABLE;
2507 pFilterConfig->ReceiveAllMode = ((READ_BIT(heth->Instance->MACFFR, ETH_MACFFR_RA) >> 31) > 0U) ? ENABLE : DISABLE;
2508
2509 return HAL_OK;
2510}
2511
2524HAL_StatusTypeDef HAL_ETH_SetSourceMACAddrMatch(const ETH_HandleTypeDef *heth, uint32_t AddrNbr,
2525 const uint8_t *pMACAddr)
2526{
2527 uint32_t macaddrlr;
2528 uint32_t macaddrhr;
2529
2530 if (pMACAddr == NULL)
2531 {
2532 return HAL_ERROR;
2533 }
2534
2535 /* Get mac addr high reg offset */
2536 macaddrhr = ((uint32_t) &(heth->Instance->MACA0HR) + AddrNbr);
2537 /* Get mac addr low reg offset */
2538 macaddrlr = ((uint32_t) &(heth->Instance->MACA0LR) + AddrNbr);
2539
2540 /* Set MAC addr bits 32 to 47 */
2541 (*(__IO uint32_t *)macaddrhr) = (((uint32_t)(pMACAddr[5]) << 8) | (uint32_t)pMACAddr[4]);
2542 /* Set MAC addr bits 0 to 31 */
2543 (*(__IO uint32_t *)macaddrlr) = (((uint32_t)(pMACAddr[3]) << 24) | ((uint32_t)(pMACAddr[2]) << 16) |
2544 ((uint32_t)(pMACAddr[1]) << 8) | (uint32_t)pMACAddr[0]);
2545
2546 /* Enable address and set source address bit */
2547 (*(__IO uint32_t *)macaddrhr) |= (ETH_MACA1HR_AE | ETH_MACA1HR_SA);
2548
2549 return HAL_OK;
2550}
2551
2560HAL_StatusTypeDef HAL_ETH_SetHashTable(ETH_HandleTypeDef *heth, uint32_t *pHashTable)
2561{
2562 uint32_t tmpreg1;
2563 if (pHashTable == NULL)
2564 {
2565 return HAL_ERROR;
2566 }
2567
2568 heth->Instance->MACHTHR = pHashTable[0];
2569
2570 /* Wait until the write operation will be taken into account :
2571 at least four TX_CLK/RX_CLK clock cycles */
2572 tmpreg1 = (heth->Instance)->MACHTHR;
2573 HAL_Delay(ETH_REG_WRITE_DELAY);
2574 (heth->Instance)->MACHTHR = tmpreg1;
2575
2576 heth->Instance->MACHTLR = pHashTable[1];
2577
2578 /* Wait until the write operation will be taken into account :
2579 at least four TX_CLK/RX_CLK clock cycles */
2580 tmpreg1 = (heth->Instance)->MACHTLR;
2581 HAL_Delay(ETH_REG_WRITE_DELAY);
2582 (heth->Instance)->MACHTLR = tmpreg1;
2583
2584 return HAL_OK;
2585}
2586
2596void HAL_ETH_SetRxVLANIdentifier(ETH_HandleTypeDef *heth, uint32_t ComparisonBits, uint32_t VLANIdentifier)
2597{
2598 uint32_t tmpreg1;
2599 MODIFY_REG(heth->Instance->MACVLANTR, ETH_MACVLANTR_VLANTI, VLANIdentifier);
2600 if (ComparisonBits == ETH_VLANTAGCOMPARISON_16BIT)
2601 {
2602 CLEAR_BIT(heth->Instance->MACVLANTR, ETH_MACVLANTR_VLANTC);
2603 }
2604 else
2605 {
2606 SET_BIT(heth->Instance->MACVLANTR, ETH_MACVLANTR_VLANTC);
2607 }
2608
2609 /* Wait until the write operation will be taken into account :
2610 at least four TX_CLK/RX_CLK clock cycles */
2611 tmpreg1 = (heth->Instance)->MACVLANTR;
2612 HAL_Delay(ETH_REG_WRITE_DELAY);
2613 (heth->Instance)->MACVLANTR = tmpreg1;
2614}
2615
2624void HAL_ETH_EnterPowerDownMode(ETH_HandleTypeDef *heth, const ETH_PowerDownConfigTypeDef *pPowerDownConfig)
2625{
2626 uint32_t powerdownconfig;
2627
2628 powerdownconfig = (((uint32_t)pPowerDownConfig->MagicPacket << ETH_MACPMTCSR_MPE_Pos) |
2629 ((uint32_t)pPowerDownConfig->WakeUpPacket << ETH_MACPMTCSR_WFE_Pos) |
2630 ((uint32_t)pPowerDownConfig->GlobalUnicast << ETH_MACPMTCSR_GU_Pos) |
2631 ETH_MACPMTCSR_PD);
2632
2633 MODIFY_REG(heth->Instance->MACPMTCSR, ETH_MACPMTCSR_MASK, powerdownconfig);
2634}
2635
2642void HAL_ETH_ExitPowerDownMode(ETH_HandleTypeDef *heth)
2643{
2644 uint32_t tmpreg1;
2645
2646 /* clear wake up sources */
2647 CLEAR_BIT(heth->Instance->MACPMTCSR, ETH_MACPMTCSR_WFE | ETH_MACPMTCSR_MPE | ETH_MACPMTCSR_GU);
2648
2649 /* Wait until the write operation will be taken into account :
2650 at least four TX_CLK/RX_CLK clock cycles */
2651 tmpreg1 = (heth->Instance)->MACPMTCSR;
2652 HAL_Delay(ETH_REG_WRITE_DELAY);
2653 (heth->Instance)->MACPMTCSR = tmpreg1;
2654
2655 if (READ_BIT(heth->Instance->MACPMTCSR, ETH_MACPMTCSR_PD) != 0U)
2656 {
2657 /* Exit power down mode */
2658 CLEAR_BIT(heth->Instance->MACPMTCSR, ETH_MACPMTCSR_PD);
2659
2660 /* Wait until the write operation will be taken into account :
2661 at least four TX_CLK/RX_CLK clock cycles */
2662 tmpreg1 = (heth->Instance)->MACPMTCSR;
2663 HAL_Delay(ETH_REG_WRITE_DELAY);
2664 (heth->Instance)->MACPMTCSR = tmpreg1;
2665 }
2666
2667 /* Disable PMT interrupt */
2668 SET_BIT(heth->Instance->MACIMR, ETH_MACIMR_PMTIM);
2669}
2670
2679HAL_StatusTypeDef HAL_ETH_SetWakeUpFilter(ETH_HandleTypeDef *heth, uint32_t *pFilter, uint32_t Count)
2680{
2681 uint32_t regindex;
2682
2683 if (pFilter == NULL)
2684 {
2685 return HAL_ERROR;
2686 }
2687
2688 /* Reset Filter Pointer */
2689 SET_BIT(heth->Instance->MACPMTCSR, ETH_MACPMTCSR_WFFRPR);
2690
2691 /* Wake up packet filter config */
2692 for (regindex = 0; regindex < Count; regindex++)
2693 {
2694 /* Write filter regs */
2695 WRITE_REG(heth->Instance->MACRWUFFR, pFilter[regindex]);
2696 }
2697
2698 return HAL_OK;
2699}
2700
2704
2721
2728HAL_ETH_StateTypeDef HAL_ETH_GetState(const ETH_HandleTypeDef *heth)
2729{
2730 return heth->gState;
2731}
2732
2739uint32_t HAL_ETH_GetError(const ETH_HandleTypeDef *heth)
2740{
2741 return heth->ErrorCode;
2742}
2743
2750uint32_t HAL_ETH_GetDMAError(const ETH_HandleTypeDef *heth)
2751{
2752 return heth->DMAErrorCode;
2753}
2754
2761uint32_t HAL_ETH_GetMACError(const ETH_HandleTypeDef *heth)
2762{
2763 return heth->MACErrorCode;
2764}
2765
2772uint32_t HAL_ETH_GetMACWakeUpSource(const ETH_HandleTypeDef *heth)
2773{
2774 return heth->MACWakeUpEvent;
2775}
2776
2783uint32_t HAL_ETH_GetTxBuffersNumber(const ETH_HandleTypeDef *heth)
2784{
2785 return heth->TxDescList.BuffersInUse;
2786}
2790
2794
2798
2805static void ETH_FlushTransmitFIFO(ETH_HandleTypeDef *heth)
2806{
2807 __IO uint32_t tmpreg = 0;
2808
2809 /* Set the Flush Transmit FIFO bit */
2810 (heth->Instance)->DMAOMR |= ETH_DMAOMR_FTF;
2811
2812 /* Wait until the write operation will be taken into account:
2813 at least four TX_CLK/RX_CLK clock cycles */
2814 tmpreg = (heth->Instance)->DMAOMR;
2815 HAL_Delay(ETH_REG_WRITE_DELAY);
2816 (heth->Instance)->DMAOMR = tmpreg;
2817}
2818
2819static void ETH_SetMACConfig(ETH_HandleTypeDef *heth, const ETH_MACConfigTypeDef *macconf)
2820{
2821 uint32_t tmpreg1;
2822
2823 /*------------------------ ETHERNET MACCR Configuration --------------------*/
2824 /* Get the ETHERNET MACCR value */
2825 tmpreg1 = (heth->Instance)->MACCR;
2826 /* Clear CSTF, WD, PCE, PS, TE and RE bits */
2827 tmpreg1 &= ETH_MACCR_CLEAR_MASK;
2828
2829 tmpreg1 |= (uint32_t)(((uint32_t)macconf->CRCStripTypePacket << 25U) |
2830 ((uint32_t)((macconf->Watchdog == DISABLE) ? 1U : 0U) << 23U) |
2831 ((uint32_t)((macconf->Jabber == DISABLE) ? 1U : 0U) << 22U) |
2832 (uint32_t)macconf->InterPacketGapVal |
2833 ((uint32_t)macconf->CarrierSenseDuringTransmit << 16U) |
2834 macconf->Speed |
2835 ((uint32_t)((macconf->ReceiveOwn == DISABLE) ? 1U : 0U) << 13U) |
2836 ((uint32_t)macconf->LoopbackMode << 12U) |
2837 macconf->DuplexMode |
2838 ((uint32_t)macconf->ChecksumOffload << 10U) |
2839 ((uint32_t)((macconf->RetryTransmission == DISABLE) ? 1U : 0U) << 9U) |
2840 ((uint32_t)macconf->AutomaticPadCRCStrip << 7U) |
2841 macconf->BackOffLimit |
2842 ((uint32_t)macconf->DeferralCheck << 4U));
2843
2844 /* Write to ETHERNET MACCR */
2845 (heth->Instance)->MACCR = (uint32_t)tmpreg1;
2846
2847 /* Wait until the write operation will be taken into account :
2848 at least four TX_CLK/RX_CLK clock cycles */
2849 tmpreg1 = (heth->Instance)->MACCR;
2850 HAL_Delay(ETH_REG_WRITE_DELAY);
2851 (heth->Instance)->MACCR = tmpreg1;
2852
2853 /*----------------------- ETHERNET MACFCR Configuration --------------------*/
2854
2855 /* Get the ETHERNET MACFCR value */
2856 tmpreg1 = (heth->Instance)->MACFCR;
2857 /* Clear xx bits */
2858 tmpreg1 &= ETH_MACFCR_CLEAR_MASK;
2859
2860 tmpreg1 |= (uint32_t)((macconf->PauseTime << 16U) |
2861 ((uint32_t)((macconf->ZeroQuantaPause == DISABLE) ? 1U : 0U) << 7U) |
2862 macconf->PauseLowThreshold |
2863 ((uint32_t)((macconf->UnicastPausePacketDetect == ENABLE) ? 1U : 0U) << 3U) |
2864 ((uint32_t)((macconf->ReceiveFlowControl == ENABLE) ? 1U : 0U) << 2U) |
2865 ((uint32_t)((macconf->TransmitFlowControl == ENABLE) ? 1U : 0U) << 1U));
2866
2867 /* Write to ETHERNET MACFCR */
2868 (heth->Instance)->MACFCR = (uint32_t)tmpreg1;
2869
2870 /* Wait until the write operation will be taken into account :
2871 at least four TX_CLK/RX_CLK clock cycles */
2872 tmpreg1 = (heth->Instance)->MACFCR;
2873 HAL_Delay(ETH_REG_WRITE_DELAY);
2874 (heth->Instance)->MACFCR = tmpreg1;
2875}
2876
2877static void ETH_SetDMAConfig(ETH_HandleTypeDef *heth, const ETH_DMAConfigTypeDef *dmaconf)
2878{
2879 uint32_t tmpreg1;
2880
2881 /*----------------------- ETHERNET DMAOMR Configuration --------------------*/
2882 /* Get the ETHERNET DMAOMR value */
2883 tmpreg1 = (heth->Instance)->DMAOMR;
2884 /* Clear xx bits */
2885 tmpreg1 &= ETH_DMAOMR_CLEAR_MASK;
2886
2887 tmpreg1 |= (uint32_t)(((uint32_t)((dmaconf->DropTCPIPChecksumErrorFrame == DISABLE) ? 1U : 0U) << 26U) |
2888 ((uint32_t)dmaconf->ReceiveStoreForward << 25U) |
2889 ((uint32_t)((dmaconf->FlushRxPacket == DISABLE) ? 1U : 0U) << 20U) |
2890 ((uint32_t)dmaconf->TransmitStoreForward << 21U) |
2891 dmaconf->TransmitThresholdControl |
2892 ((uint32_t)dmaconf->ForwardErrorFrames << 7U) |
2893 ((uint32_t)dmaconf->ForwardUndersizedGoodFrames << 6U) |
2894 dmaconf->ReceiveThresholdControl |
2895 ((uint32_t)dmaconf->SecondFrameOperate << 2U));
2896
2897 /* Write to ETHERNET DMAOMR */
2898 (heth->Instance)->DMAOMR = (uint32_t)tmpreg1;
2899
2900 /* Wait until the write operation will be taken into account:
2901 at least four TX_CLK/RX_CLK clock cycles */
2902 tmpreg1 = (heth->Instance)->DMAOMR;
2903 HAL_Delay(ETH_REG_WRITE_DELAY);
2904 (heth->Instance)->DMAOMR = tmpreg1;
2905
2906 /*----------------------- ETHERNET DMABMR Configuration --------------------*/
2907 (heth->Instance)->DMABMR = (uint32_t)(((uint32_t)dmaconf->AddressAlignedBeats << 25U) |
2908 dmaconf->BurstMode |
2909 dmaconf->RxDMABurstLength | /* !! if 4xPBL is selected for Tx or
2910 Rx it is applied for the other */
2911 dmaconf->TxDMABurstLength |
2912 ((uint32_t)dmaconf->EnhancedDescriptorFormat << 7U) |
2913 (dmaconf->DescriptorSkipLength << 2U) |
2914 dmaconf->DMAArbitration |
2915 ETH_DMABMR_USP); /* Enable use of separate PBL for Rx and Tx */
2916
2917 /* Wait until the write operation will be taken into account:
2918 at least four TX_CLK/RX_CLK clock cycles */
2919 tmpreg1 = (heth->Instance)->DMABMR;
2920 HAL_Delay(ETH_REG_WRITE_DELAY);
2921 (heth->Instance)->DMABMR = tmpreg1;
2922}
2923
2931static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth)
2932{
2933 ETH_MACConfigTypeDef macDefaultConf;
2934 ETH_DMAConfigTypeDef dmaDefaultConf;
2935
2936 /*--------------- ETHERNET MAC registers default Configuration --------------*/
2937 macDefaultConf.Watchdog = ENABLE;
2938 macDefaultConf.Jabber = ENABLE;
2939 macDefaultConf.InterPacketGapVal = ETH_INTERFRAMEGAP_96BIT;
2940 macDefaultConf.CarrierSenseDuringTransmit = DISABLE;
2941 macDefaultConf.ReceiveOwn = ENABLE;
2942 macDefaultConf.LoopbackMode = DISABLE;
2943 macDefaultConf.CRCStripTypePacket = ENABLE;
2944 macDefaultConf.ChecksumOffload = ENABLE;
2945 macDefaultConf.RetryTransmission = DISABLE;
2946 macDefaultConf.AutomaticPadCRCStrip = DISABLE;
2947 macDefaultConf.BackOffLimit = ETH_BACKOFFLIMIT_10;
2948 macDefaultConf.DeferralCheck = DISABLE;
2949 macDefaultConf.PauseTime = 0x0U;
2950 macDefaultConf.ZeroQuantaPause = DISABLE;
2951 macDefaultConf.PauseLowThreshold = ETH_PAUSELOWTHRESHOLD_MINUS4;
2952 macDefaultConf.ReceiveFlowControl = DISABLE;
2953 macDefaultConf.TransmitFlowControl = DISABLE;
2954 macDefaultConf.Speed = ETH_SPEED_100M;
2955 macDefaultConf.DuplexMode = ETH_FULLDUPLEX_MODE;
2956 macDefaultConf.UnicastPausePacketDetect = DISABLE;
2957
2958 /* MAC default configuration */
2959 ETH_SetMACConfig(heth, &macDefaultConf);
2960
2961 /*--------------- ETHERNET DMA registers default Configuration --------------*/
2962 dmaDefaultConf.DropTCPIPChecksumErrorFrame = ENABLE;
2963 dmaDefaultConf.ReceiveStoreForward = ENABLE;
2964 dmaDefaultConf.FlushRxPacket = ENABLE;
2965 dmaDefaultConf.TransmitStoreForward = ENABLE;
2966 dmaDefaultConf.TransmitThresholdControl = ETH_TRANSMITTHRESHOLDCONTROL_64BYTES;
2967 dmaDefaultConf.ForwardErrorFrames = DISABLE;
2968 dmaDefaultConf.ForwardUndersizedGoodFrames = DISABLE;
2969 dmaDefaultConf.ReceiveThresholdControl = ETH_RECEIVEDTHRESHOLDCONTROL_64BYTES;
2970 dmaDefaultConf.SecondFrameOperate = ENABLE;
2971 dmaDefaultConf.AddressAlignedBeats = ENABLE;
2972 dmaDefaultConf.BurstMode = ETH_BURSTLENGTH_FIXED;
2973 dmaDefaultConf.RxDMABurstLength = ETH_RXDMABURSTLENGTH_32BEAT;
2974 dmaDefaultConf.TxDMABurstLength = ETH_TXDMABURSTLENGTH_32BEAT;
2975 dmaDefaultConf.EnhancedDescriptorFormat = ENABLE;
2976 dmaDefaultConf.DescriptorSkipLength = 0x0U;
2977 dmaDefaultConf.DMAArbitration = ETH_DMAARBITRATION_ROUNDROBIN_RXTX_1_1;
2978
2979 /* DMA default configuration */
2980 ETH_SetDMAConfig(heth, &dmaDefaultConf);
2981}
2995static void ETH_MACAddressConfig(ETH_HandleTypeDef *heth, uint32_t MacAddr, uint8_t *Addr)
2996{
2997 uint32_t tmpreg1;
2998
2999 /* Prevent unused argument(s) compilation warning */
3000 UNUSED(heth);
3001
3002 /* Calculate the selected MAC address high register */
3003 tmpreg1 = ((uint32_t)Addr[5U] << 8U) | (uint32_t)Addr[4U];
3004 /* Load the selected MAC address high register */
3005 (*(__IO uint32_t *)((uint32_t)(ETH_MAC_ADDR_HBASE + MacAddr))) = tmpreg1;
3006 /* Calculate the selected MAC address low register */
3007 tmpreg1 = ((uint32_t)Addr[3U] << 24U) | ((uint32_t)Addr[2U] << 16U) | ((uint32_t)Addr[1U] << 8U) | Addr[0U];
3008
3009 /* Load the selected MAC address low register */
3010 (*(__IO uint32_t *)((uint32_t)(ETH_MAC_ADDR_LBASE + MacAddr))) = tmpreg1;
3011}
3012
3020static void ETH_DMATxDescListInit(ETH_HandleTypeDef *heth)
3021{
3022 ETH_DMADescTypeDef *dmatxdesc;
3023 uint32_t i;
3024
3025 /* Fill each DMATxDesc descriptor with the right values */
3026 for (i = 0; i < (uint32_t)ETH_TX_DESC_CNT; i++)
3027 {
3028 dmatxdesc = heth->Init.TxDesc + i;
3029
3030 WRITE_REG(dmatxdesc->DESC0, 0x0U);
3031 WRITE_REG(dmatxdesc->DESC1, 0x0U);
3032 WRITE_REG(dmatxdesc->DESC2, 0x0U);
3033 WRITE_REG(dmatxdesc->DESC3, 0x0U);
3034
3035 WRITE_REG(heth->TxDescList.TxDesc[i], (uint32_t)dmatxdesc);
3036
3037 /* Set Second Address Chained bit */
3038 SET_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_TCH);
3039
3040 if (i < ((uint32_t)ETH_TX_DESC_CNT - 1U))
3041 {
3042 WRITE_REG(dmatxdesc->DESC3, (uint32_t)(heth->Init.TxDesc + i + 1U));
3043 }
3044 else
3045 {
3046 WRITE_REG(dmatxdesc->DESC3, (uint32_t)(heth->Init.TxDesc));
3047 }
3048
3049 /* Set the DMA Tx descriptors checksum insertion */
3050 SET_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_CHECKSUMTCPUDPICMPFULL);
3051 }
3052
3053 heth->TxDescList.CurTxDesc = 0;
3054
3055 /* Set Transmit Descriptor List Address */
3056 WRITE_REG(heth->Instance->DMATDLAR, (uint32_t) heth->Init.TxDesc);
3057}
3058
3066static void ETH_DMARxDescListInit(ETH_HandleTypeDef *heth)
3067{
3068 ETH_DMADescTypeDef *dmarxdesc;
3069 uint32_t i;
3070
3071 for (i = 0; i < (uint32_t)ETH_RX_DESC_CNT; i++)
3072 {
3073 dmarxdesc = heth->Init.RxDesc + i;
3074
3075 WRITE_REG(dmarxdesc->DESC0, 0x0U);
3076 WRITE_REG(dmarxdesc->DESC1, 0x0U);
3077 WRITE_REG(dmarxdesc->DESC2, 0x0U);
3078 WRITE_REG(dmarxdesc->DESC3, 0x0U);
3079 WRITE_REG(dmarxdesc->BackupAddr0, 0x0U);
3080 WRITE_REG(dmarxdesc->BackupAddr1, 0x0U);
3081
3082 /* Set Own bit of the Rx descriptor Status */
3083 dmarxdesc->DESC0 = ETH_DMARXDESC_OWN;
3084
3085 /* Set Buffer1 size and Second Address Chained bit */
3086 dmarxdesc->DESC1 = heth->Init.RxBuffLen | ETH_DMARXDESC_RCH;
3087
3088 /* Enable Ethernet DMA Rx Descriptor interrupt */
3089 dmarxdesc->DESC1 &= ~ETH_DMARXDESC_DIC;
3090 /* Set Rx descritors addresses */
3091 WRITE_REG(heth->RxDescList.RxDesc[i], (uint32_t)dmarxdesc);
3092
3093 if (i < ((uint32_t)ETH_RX_DESC_CNT - 1U))
3094 {
3095 WRITE_REG(dmarxdesc->DESC3, (uint32_t)(heth->Init.RxDesc + i + 1U));
3096 }
3097 else
3098 {
3099 WRITE_REG(dmarxdesc->DESC3, (uint32_t)(heth->Init.RxDesc));
3100 }
3101 }
3102
3103 WRITE_REG(heth->RxDescList.RxDescIdx, 0U);
3104 WRITE_REG(heth->RxDescList.RxDescCnt, 0U);
3105 WRITE_REG(heth->RxDescList.RxBuildDescIdx, 0U);
3106 WRITE_REG(heth->RxDescList.RxBuildDescCnt, 0U);
3107 WRITE_REG(heth->RxDescList.ItMode, 0U);
3108
3109 /* Set Receive Descriptor List Address */
3110 WRITE_REG(heth->Instance->DMARDLAR, (uint32_t) heth->Init.RxDesc);
3111}
3112
3122static uint32_t ETH_Prepare_Tx_Descriptors(ETH_HandleTypeDef *heth, const ETH_TxPacketConfigTypeDef *pTxConfig,
3123 uint32_t ItMode)
3124{
3125 ETH_TxDescListTypeDef *dmatxdesclist = &heth->TxDescList;
3126 uint32_t descidx = dmatxdesclist->CurTxDesc;
3127 uint32_t firstdescidx = dmatxdesclist->CurTxDesc;
3128 uint32_t idx;
3129 uint32_t descnbr = 0;
3130 ETH_DMADescTypeDef *dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx];
3131
3132 ETH_BufferTypeDef *txbuffer = pTxConfig->TxBuffer;
3133 uint32_t bd_count = 0;
3134 uint32_t primask_bit;
3135
3136 /* Current Tx Descriptor Owned by DMA: cannot be used by the application */
3137 if ((READ_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_OWN) == ETH_DMATXDESC_OWN)
3138 || (dmatxdesclist->PacketAddress[descidx] != NULL))
3139 {
3140 return HAL_ETH_ERROR_BUSY;
3141 }
3142
3143
3144 descnbr += 1U;
3145
3146 /* Set header or buffer 1 address */
3147 WRITE_REG(dmatxdesc->DESC2, (uint32_t)txbuffer->buffer);
3148
3149 /* Set header or buffer 1 Length */
3150 MODIFY_REG(dmatxdesc->DESC1, ETH_DMATXDESC_TBS1, txbuffer->len);
3151
3152 if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_CSUM) != 0U)
3153 {
3154 MODIFY_REG(dmatxdesc->DESC0, ETH_DMATXDESC_CIC, pTxConfig->ChecksumCtrl);
3155 }
3156
3157 if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_CRCPAD) != 0U)
3158 {
3159 MODIFY_REG(dmatxdesc->DESC0, ETH_CRC_PAD_DISABLE, pTxConfig->CRCPadCtrl);
3160 }
3161
3162
3163 if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_VLANTAG) != 0U)
3164 {
3165 /* Set Vlan Type */
3166 SET_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_VF);
3167 }
3168
3169 /* Mark it as First Descriptor */
3170 SET_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_FS);
3171
3172 /* only if the packet is split into more than one descriptors > 1 */
3173 while (txbuffer->next != NULL)
3174 {
3175 /* Clear the LD bit of previous descriptor */
3176 CLEAR_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_LS);
3177 if (ItMode != ((uint32_t)RESET))
3178 {
3179 /* Set Interrupt on completion bit */
3180 SET_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_IC);
3181 }
3182 else
3183 {
3184 /* Clear Interrupt on completion bit */
3185 CLEAR_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_IC);
3186 }
3187 /* Increment current tx descriptor index */
3188 INCR_TX_DESC_INDEX(descidx, 1U);
3189 /* Get current descriptor address */
3190 dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx];
3191
3192 /* Current Tx Descriptor Owned by DMA: cannot be used by the application */
3193 if ((READ_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_OWN) == ETH_DMATXDESC_OWN)
3194 || (dmatxdesclist->PacketAddress[descidx] != NULL))
3195 {
3196 descidx = firstdescidx;
3197 dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx];
3198
3199 /* clear previous desc own bit */
3200 for (idx = 0; idx < descnbr; idx ++)
3201 {
3202 /* Ensure rest of descriptor is written to RAM before the OWN bit */
3203 __DMB();
3204
3205 CLEAR_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_OWN);
3206
3207 /* Increment current tx descriptor index */
3208 INCR_TX_DESC_INDEX(descidx, 1U);
3209 /* Get current descriptor address */
3210 dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx];
3211 }
3212
3213 return HAL_ETH_ERROR_BUSY;
3214 }
3215
3216 /* Clear the FD bit of new Descriptor */
3217 CLEAR_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_FS);
3218
3219 descnbr += 1U;
3220
3221 /* Get the next Tx buffer in the list */
3222 txbuffer = txbuffer->next;
3223
3224 /* Set header or buffer 1 address */
3225 WRITE_REG(dmatxdesc->DESC2, (uint32_t)txbuffer->buffer);
3226
3227 /* Set header or buffer 1 Length */
3228 MODIFY_REG(dmatxdesc->DESC1, ETH_DMATXDESC_TBS1, txbuffer->len);
3229
3230 bd_count += 1U;
3231
3232 /* Ensure rest of descriptor is written to RAM before the OWN bit */
3233 __DMB();
3234 /* Set Own bit */
3235 SET_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_OWN);
3236 }
3237
3238 if (ItMode != ((uint32_t)RESET))
3239 {
3240 /* Set Interrupt on completion bit */
3241 SET_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_IC);
3242 }
3243 else
3244 {
3245 /* Clear Interrupt on completion bit */
3246 CLEAR_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_IC);
3247 }
3248
3249 /* Mark it as LAST descriptor */
3250 SET_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_LS);
3251
3252 /* Get address of first descriptor */
3253 dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[firstdescidx];
3254 /* Ensure rest of descriptor is written to RAM before the OWN bit */
3255 __DMB();
3256 /* set OWN bit of FIRST descriptor */
3257 SET_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_OWN);
3258 /* Save the current packet address to expose it to the application */
3259 dmatxdesclist->PacketAddress[descidx] = dmatxdesclist->CurrentPacketAddress;
3260
3261 dmatxdesclist->CurTxDesc = descidx;
3262
3263 /* Enter critical section */
3264 primask_bit = __get_PRIMASK();
3265 __set_PRIMASK(1);
3266
3267 dmatxdesclist->BuffersInUse += bd_count + 1U;
3268
3269 /* Exit critical section: restore previous priority mask */
3270 __set_PRIMASK(primask_bit);
3271
3272 /* Return function status */
3273 return HAL_ETH_ERROR_NONE;
3274}
3275
3276#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
3277static void ETH_InitCallbacksToDefault(ETH_HandleTypeDef *heth)
3278{
3279 /* Init the ETH Callback settings */
3280 heth->TxCpltCallback = HAL_ETH_TxCpltCallback; /* Legacy weak TxCpltCallback */
3281 heth->RxCpltCallback = HAL_ETH_RxCpltCallback; /* Legacy weak RxCpltCallback */
3282 heth->ErrorCallback = HAL_ETH_ErrorCallback; /* Legacy weak ErrorCallback */
3283 heth->PMTCallback = HAL_ETH_PMTCallback; /* Legacy weak PMTCallback */
3284 heth->WakeUpCallback = HAL_ETH_WakeUpCallback; /* Legacy weak WakeUpCallback */
3285 heth->rxLinkCallback = HAL_ETH_RxLinkCallback; /* Legacy weak RxLinkCallback */
3286 heth->txFreeCallback = HAL_ETH_TxFreeCallback; /* Legacy weak TxFreeCallback */
3287#ifdef HAL_ETH_USE_PTP
3288 heth->txPtpCallback = HAL_ETH_TxPtpCallback; /* Legacy weak TxPtpCallback */
3289#endif /* HAL_ETH_USE_PTP */
3290 heth->rxAllocateCallback = HAL_ETH_RxAllocateCallback; /* Legacy weak RxAllocateCallback */
3291}
3292#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
3293
3297
3301
3302#endif /* ETH */
3303
3304#endif /* HAL_ETH_MODULE_ENABLED */
3305
void HAL_Delay(uint32_t Delay)
This function provides minimum delay (in milliseconds) based on variable incremented.
uint32_t HAL_GetTick(void)
Provides a tick value in millisecond.
#define __HAL_RCC_SYSCFG_CLK_ENABLE()
uint32_t HAL_RCC_GetHCLKFreq(void)
This file contains all the functions prototypes for the HAL module driver.
#define PHY_WRITE_TO
#define PHY_READ_TO
HAL_StatusTypeDef
HAL Status structures definition.
@ HAL_ERROR
@ HAL_OK
#define HAL_MAX_DELAY