25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.
 
 
 
 
 

3309 satır
110 KiB

  1. /**
  2. ******************************************************************************
  3. * @file stm32f4xx_hal_eth.c
  4. * @author MCD Application Team
  5. * @brief ETH HAL module driver.
  6. * This file provides firmware functions to manage the following
  7. * functionalities of the Ethernet (ETH) peripheral:
  8. * + Initialization and deinitialization functions
  9. * + IO operation functions
  10. * + Peripheral Control functions
  11. * + Peripheral State and Errors functions
  12. *
  13. ******************************************************************************
  14. * @attention
  15. *
  16. * Copyright (c) 2016 STMicroelectronics.
  17. * All rights reserved.
  18. *
  19. * This software is licensed under terms that can be found in the LICENSE file
  20. * in the root directory of this software component.
  21. * If no LICENSE file comes with this software, it is provided AS-IS.
  22. *
  23. ******************************************************************************
  24. @verbatim
  25. ==============================================================================
  26. ##### How to use this driver #####
  27. ==============================================================================
  28. [..]
  29. The ETH HAL driver can be used as follows:
  30. (#)Declare a ETH_HandleTypeDef handle structure, for example:
  31. ETH_HandleTypeDef heth;
  32. (#)Fill parameters of Init structure in heth handle
  33. (#)Call HAL_ETH_Init() API to initialize the Ethernet peripheral (MAC, DMA, ...)
  34. (#)Initialize the ETH low level resources through the HAL_ETH_MspInit() API:
  35. (##) Enable the Ethernet interface clock using
  36. (+++) __HAL_RCC_ETH1MAC_CLK_ENABLE()
  37. (+++) __HAL_RCC_ETH1TX_CLK_ENABLE()
  38. (+++) __HAL_RCC_ETH1RX_CLK_ENABLE()
  39. (##) Initialize the related GPIO clocks
  40. (##) Configure Ethernet pinout
  41. (##) Configure Ethernet NVIC interrupt (in Interrupt mode)
  42. (#) Ethernet data reception is asynchronous, so call the following API
  43. to start the listening mode:
  44. (##) HAL_ETH_Start():
  45. This API starts the MAC and DMA transmission and reception process,
  46. without enabling end of transfer interrupts, in this mode user
  47. has to poll for data reception by calling HAL_ETH_ReadData()
  48. (##) HAL_ETH_Start_IT():
  49. This API starts the MAC and DMA transmission and reception process,
  50. end of transfer interrupts are enabled in this mode,
  51. HAL_ETH_RxCpltCallback() will be executed when an Ethernet packet is received
  52. (#) When data is received user can call the following API to get received data:
  53. (##) HAL_ETH_ReadData(): Read a received packet
  54. (#) For transmission path, two APIs are available:
  55. (##) HAL_ETH_Transmit(): Transmit an ETH frame in blocking mode
  56. (##) HAL_ETH_Transmit_IT(): Transmit an ETH frame in interrupt mode,
  57. HAL_ETH_TxCpltCallback() will be executed when end of transfer occur
  58. (#) Communication with an external PHY device:
  59. (##) HAL_ETH_ReadPHYRegister(): Read a register from an external PHY
  60. (##) HAL_ETH_WritePHYRegister(): Write data to an external RHY register
  61. (#) Configure the Ethernet MAC after ETH peripheral initialization
  62. (##) HAL_ETH_GetMACConfig(): Get MAC actual configuration into ETH_MACConfigTypeDef
  63. (##) HAL_ETH_SetMACConfig(): Set MAC configuration based on ETH_MACConfigTypeDef
  64. (#) Configure the Ethernet DMA after ETH peripheral initialization
  65. (##) HAL_ETH_GetDMAConfig(): Get DMA actual configuration into ETH_DMAConfigTypeDef
  66. (##) HAL_ETH_SetDMAConfig(): Set DMA configuration based on ETH_DMAConfigTypeDef
  67. (#) Configure the Ethernet PTP after ETH peripheral initialization
  68. (##) Define HAL_ETH_USE_PTP to use PTP APIs.
  69. (##) HAL_ETH_PTP_GetConfig(): Get PTP actual configuration into ETH_PTP_ConfigTypeDef
  70. (##) HAL_ETH_PTP_SetConfig(): Set PTP configuration based on ETH_PTP_ConfigTypeDef
  71. (##) HAL_ETH_PTP_GetTime(): Get Seconds and Nanoseconds for the Ethernet PTP registers
  72. (##) HAL_ETH_PTP_SetTime(): Set Seconds and Nanoseconds for the Ethernet PTP registers
  73. (##) HAL_ETH_PTP_AddTimeOffset(): Add Seconds and Nanoseconds offset for the Ethernet PTP registers
  74. (##) HAL_ETH_PTP_AddendUpdate(): Update the Addend register
  75. (##) HAL_ETH_PTP_InsertTxTimestamp(): Insert Timestamp in transmission
  76. (##) HAL_ETH_PTP_GetTxTimestamp(): Get transmission timestamp
  77. (##) HAL_ETH_PTP_GetRxTimestamp(): Get reception timestamp
  78. -@- The ARP offload feature is not supported in this driver.
  79. -@- The PTP offload feature is not supported in this driver.
  80. *** Callback registration ***
  81. =============================================
  82. The compilation define USE_HAL_ETH_REGISTER_CALLBACKS when set to 1
  83. allows the user to configure dynamically the driver callbacks.
  84. Use Function HAL_ETH_RegisterCallback() to register an interrupt callback.
  85. Function HAL_ETH_RegisterCallback() allows to register following callbacks:
  86. (+) TxCpltCallback : Tx Complete Callback.
  87. (+) RxCpltCallback : Rx Complete Callback.
  88. (+) ErrorCallback : Error Callback.
  89. (+) PMTCallback : Power Management Callback
  90. (+) EEECallback : EEE Callback.
  91. (+) WakeUpCallback : Wake UP Callback
  92. (+) MspInitCallback : MspInit Callback.
  93. (+) MspDeInitCallback: MspDeInit Callback.
  94. This function takes as parameters the HAL peripheral handle, the Callback ID
  95. and a pointer to the user callback function.
  96. For specific callbacks RxAllocateCallback use dedicated register callbacks:
  97. respectively HAL_ETH_RegisterRxAllocateCallback().
  98. For specific callbacks RxLinkCallback use dedicated register callbacks:
  99. respectively HAL_ETH_RegisterRxLinkCallback().
  100. For specific callbacks TxFreeCallback use dedicated register callbacks:
  101. respectively HAL_ETH_RegisterTxFreeCallback().
  102. For specific callbacks TxPtpCallback use dedicated register callbacks:
  103. respectively HAL_ETH_RegisterTxPtpCallback().
  104. Use function HAL_ETH_UnRegisterCallback() to reset a callback to the default
  105. weak function.
  106. HAL_ETH_UnRegisterCallback takes as parameters the HAL peripheral handle,
  107. and the Callback ID.
  108. This function allows to reset following callbacks:
  109. (+) TxCpltCallback : Tx Complete Callback.
  110. (+) RxCpltCallback : Rx Complete Callback.
  111. (+) ErrorCallback : Error Callback.
  112. (+) PMTCallback : Power Management Callback
  113. (+) EEECallback : EEE Callback.
  114. (+) WakeUpCallback : Wake UP Callback
  115. (+) MspInitCallback : MspInit Callback.
  116. (+) MspDeInitCallback: MspDeInit Callback.
  117. For specific callbacks RxAllocateCallback use dedicated unregister callbacks:
  118. respectively HAL_ETH_UnRegisterRxAllocateCallback().
  119. For specific callbacks RxLinkCallback use dedicated unregister callbacks:
  120. respectively HAL_ETH_UnRegisterRxLinkCallback().
  121. For specific callbacks TxFreeCallback use dedicated unregister callbacks:
  122. respectively HAL_ETH_UnRegisterTxFreeCallback().
  123. For specific callbacks TxPtpCallback use dedicated unregister callbacks:
  124. respectively HAL_ETH_UnRegisterTxPtpCallback().
  125. By default, after the HAL_ETH_Init and when the state is HAL_ETH_STATE_RESET
  126. all callbacks are set to the corresponding weak functions:
  127. examples HAL_ETH_TxCpltCallback(), HAL_ETH_RxCpltCallback().
  128. Exception done for MspInit and MspDeInit functions that are
  129. reset to the legacy weak function in the HAL_ETH_Init/ HAL_ETH_DeInit only when
  130. these callbacks are null (not registered beforehand).
  131. if not, MspInit or MspDeInit are not null, the HAL_ETH_Init/ HAL_ETH_DeInit
  132. keep and use the user MspInit/MspDeInit callbacks (registered beforehand)
  133. Callbacks can be registered/unregistered in HAL_ETH_STATE_READY state only.
  134. Exception done MspInit/MspDeInit that can be registered/unregistered
  135. in HAL_ETH_STATE_READY or HAL_ETH_STATE_RESET state,
  136. thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
  137. In that case first register the MspInit/MspDeInit user callbacks
  138. using HAL_ETH_RegisterCallback() before calling HAL_ETH_DeInit
  139. or HAL_ETH_Init function.
  140. When The compilation define USE_HAL_ETH_REGISTER_CALLBACKS is set to 0 or
  141. not defined, the callback registration feature is not available and all callbacks
  142. are set to the corresponding weak functions.
  143. @endverbatim
  144. ******************************************************************************
  145. */
  146. /* Includes ------------------------------------------------------------------*/
  147. #include "stm32f4xx_hal.h"
  148. /** @addtogroup STM32F4xx_HAL_Driver
  149. * @{
  150. */
  151. #ifdef HAL_ETH_MODULE_ENABLED
  152. #if defined(ETH)
  153. /** @defgroup ETH ETH
  154. * @brief ETH HAL module driver
  155. * @{
  156. */
  157. /* Private typedef -----------------------------------------------------------*/
  158. /* Private define ------------------------------------------------------------*/
  159. /** @addtogroup ETH_Private_Constants ETH Private Constants
  160. * @{
  161. */
  162. #define ETH_MACCR_MASK 0xFFFB7F7CU
  163. #define ETH_MACECR_MASK 0x3F077FFFU
  164. #define ETH_MACFFR_MASK 0x800007FFU
  165. #define ETH_MACWTR_MASK 0x0000010FU
  166. #define ETH_MACTFCR_MASK 0xFFFF00F2U
  167. #define ETH_MACRFCR_MASK 0x00000003U
  168. #define ETH_MTLTQOMR_MASK 0x00000072U
  169. #define ETH_MTLRQOMR_MASK 0x0000007BU
  170. #define ETH_DMAMR_MASK 0x00007802U
  171. #define ETH_DMASBMR_MASK 0x0000D001U
  172. #define ETH_DMACCR_MASK 0x00013FFFU
  173. #define ETH_DMACTCR_MASK 0x003F1010U
  174. #define ETH_DMACRCR_MASK 0x803F0000U
  175. #define ETH_MACPMTCSR_MASK (ETH_MACPMTCSR_PD | ETH_MACPMTCSR_WFE | \
  176. ETH_MACPMTCSR_MPE | ETH_MACPMTCSR_GU)
  177. /* Timeout values */
  178. #define ETH_SWRESET_TIMEOUT 500U
  179. #define ETH_MDIO_BUS_TIMEOUT 1000U
  180. #define ETH_DMARXDESC_ERRORS_MASK ((uint32_t)(ETH_DMARXDESC_DBE | ETH_DMARXDESC_RE | \
  181. ETH_DMARXDESC_OE | ETH_DMARXDESC_RWT |\
  182. ETH_DMARXDESC_LC | ETH_DMARXDESC_CE |\
  183. ETH_DMARXDESC_DE | ETH_DMARXDESC_IPV4HCE))
  184. #define ETH_MAC_US_TICK 1000000U
  185. #define ETH_MACTSCR_MASK 0x0087FF2FU
  186. #define ETH_PTPTSHR_VALUE 0xFFFFFFFFU
  187. #define ETH_PTPTSLR_VALUE 0xBB9ACA00U
  188. /* Ethernet MACMIIAR register Mask */
  189. #define ETH_MACMIIAR_CR_MASK 0xFFFFFFE3U
  190. /* Delay to wait when writing to some Ethernet registers */
  191. #define ETH_REG_WRITE_DELAY 0x00000001U
  192. /* ETHERNET MACCR register Mask */
  193. #define ETH_MACCR_CLEAR_MASK 0xFD20810FU
  194. /* ETHERNET MACFCR register Mask */
  195. #define ETH_MACFCR_CLEAR_MASK 0x0000FF41U
  196. /* ETHERNET DMAOMR register Mask */
  197. #define ETH_DMAOMR_CLEAR_MASK 0xF8DE3F23U
  198. /* ETHERNET MAC address offsets */
  199. #define ETH_MAC_ADDR_HBASE (uint32_t)(ETH_MAC_BASE + 0x40U) /* ETHERNET MAC address high offset */
  200. #define ETH_MAC_ADDR_LBASE (uint32_t)(ETH_MAC_BASE + 0x44U) /* ETHERNET MAC address low offset */
  201. /* ETHERNET DMA Rx descriptors Frame length Shift */
  202. #define ETH_DMARXDESC_FRAMELENGTHSHIFT 16U
  203. /**
  204. * @}
  205. */
  206. /* Private macros ------------------------------------------------------------*/
  207. /** @defgroup ETH_Private_Macros ETH Private Macros
  208. * @{
  209. */
  210. /* Helper macros for TX descriptor handling */
  211. #define INCR_TX_DESC_INDEX(inx, offset) do {\
  212. (inx) += (offset);\
  213. if ((inx) >= (uint32_t)ETH_TX_DESC_CNT){\
  214. (inx) = ((inx) - (uint32_t)ETH_TX_DESC_CNT);}\
  215. } while (0)
  216. /* Helper macros for RX descriptor handling */
  217. #define INCR_RX_DESC_INDEX(inx, offset) do {\
  218. (inx) += (offset);\
  219. if ((inx) >= (uint32_t)ETH_RX_DESC_CNT){\
  220. (inx) = ((inx) - (uint32_t)ETH_RX_DESC_CNT);}\
  221. } while (0)
  222. /**
  223. * @}
  224. */
  225. /* Private function prototypes -----------------------------------------------*/
  226. /** @defgroup ETH_Private_Functions ETH Private Functions
  227. * @{
  228. */
  229. static void ETH_SetMACConfig(ETH_HandleTypeDef *heth, const ETH_MACConfigTypeDef *macconf);
  230. static void ETH_SetDMAConfig(ETH_HandleTypeDef *heth, const ETH_DMAConfigTypeDef *dmaconf);
  231. static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth);
  232. static void ETH_DMATxDescListInit(ETH_HandleTypeDef *heth);
  233. static void ETH_DMARxDescListInit(ETH_HandleTypeDef *heth);
  234. static uint32_t ETH_Prepare_Tx_Descriptors(ETH_HandleTypeDef *heth, const ETH_TxPacketConfigTypeDef *pTxConfig,
  235. uint32_t ItMode);
  236. static void ETH_UpdateDescriptor(ETH_HandleTypeDef *heth);
  237. static void ETH_FlushTransmitFIFO(ETH_HandleTypeDef *heth);
  238. static void ETH_MACAddressConfig(ETH_HandleTypeDef *heth, uint32_t MacAddr, uint8_t *Addr);
  239. #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
  240. static void ETH_InitCallbacksToDefault(ETH_HandleTypeDef *heth);
  241. #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
  242. #ifdef HAL_ETH_USE_PTP
  243. static HAL_StatusTypeDef HAL_ETH_PTP_AddendUpdate(ETH_HandleTypeDef *heth, int32_t timeoffset);
  244. #endif /* HAL_ETH_USE_PTP */
  245. /**
  246. * @}
  247. */
  248. /* Exported functions ---------------------------------------------------------*/
  249. /** @defgroup ETH_Exported_Functions ETH Exported Functions
  250. * @{
  251. */
  252. /** @defgroup ETH_Exported_Functions_Group1 Initialization and deinitialization functions
  253. * @brief Initialization and Configuration functions
  254. *
  255. @verbatim
  256. ===============================================================================
  257. ##### Initialization and Configuration functions #####
  258. ===============================================================================
  259. [..] This subsection provides a set of functions allowing to initialize and
  260. deinitialize the ETH peripheral:
  261. (+) User must Implement HAL_ETH_MspInit() function in which he configures
  262. all related peripherals resources (CLOCK, GPIO and NVIC ).
  263. (+) Call the function HAL_ETH_Init() to configure the selected device with
  264. the selected configuration:
  265. (++) MAC address
  266. (++) Media interface (MII or RMII)
  267. (++) Rx DMA Descriptors Tab
  268. (++) Tx DMA Descriptors Tab
  269. (++) Length of Rx Buffers
  270. (+) Call the function HAL_ETH_DeInit() to restore the default configuration
  271. of the selected ETH peripheral.
  272. @endverbatim
  273. * @{
  274. */
  275. /**
  276. * @brief Initialize the Ethernet peripheral registers.
  277. * @param heth: pointer to a ETH_HandleTypeDef structure that contains
  278. * the configuration information for ETHERNET module
  279. * @retval HAL status
  280. */
  281. HAL_StatusTypeDef HAL_ETH_Init(ETH_HandleTypeDef *heth)
  282. {
  283. uint32_t tickstart;
  284. if (heth == NULL)
  285. {
  286. return HAL_ERROR;
  287. }
  288. if (heth->gState == HAL_ETH_STATE_RESET)
  289. {
  290. heth->gState = HAL_ETH_STATE_BUSY;
  291. #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
  292. ETH_InitCallbacksToDefault(heth);
  293. if (heth->MspInitCallback == NULL)
  294. {
  295. heth->MspInitCallback = HAL_ETH_MspInit;
  296. }
  297. /* Init the low level hardware */
  298. heth->MspInitCallback(heth);
  299. #else
  300. /* Init the low level hardware : GPIO, CLOCK, NVIC. */
  301. HAL_ETH_MspInit(heth);
  302. #endif /* (USE_HAL_ETH_REGISTER_CALLBACKS) */
  303. }
  304. __HAL_RCC_SYSCFG_CLK_ENABLE();
  305. /* Select MII or RMII Mode*/
  306. SYSCFG->PMC &= ~(SYSCFG_PMC_MII_RMII_SEL);
  307. SYSCFG->PMC |= (uint32_t)heth->Init.MediaInterface;
  308. /* Dummy read to sync SYSCFG with ETH */
  309. (void)SYSCFG->PMC;
  310. /* Ethernet Software reset */
  311. /* Set the SWR bit: resets all MAC subsystem internal registers and logic */
  312. /* After reset all the registers holds their respective reset values */
  313. SET_BIT(heth->Instance->DMABMR, ETH_DMABMR_SR);
  314. /* Get tick */
  315. tickstart = HAL_GetTick();
  316. /* Wait for software reset */
  317. while (READ_BIT(heth->Instance->DMABMR, ETH_DMABMR_SR) > 0U)
  318. {
  319. if (((HAL_GetTick() - tickstart) > ETH_SWRESET_TIMEOUT))
  320. {
  321. /* Set Error Code */
  322. heth->ErrorCode = HAL_ETH_ERROR_TIMEOUT;
  323. /* Set State as Error */
  324. heth->gState = HAL_ETH_STATE_ERROR;
  325. /* Return Error */
  326. return HAL_ERROR;
  327. }
  328. }
  329. /*------------------ MAC, MTL and DMA default Configuration ----------------*/
  330. ETH_MACDMAConfig(heth);
  331. /*------------------ DMA Tx Descriptors Configuration ----------------------*/
  332. ETH_DMATxDescListInit(heth);
  333. /*------------------ DMA Rx Descriptors Configuration ----------------------*/
  334. ETH_DMARxDescListInit(heth);
  335. /*--------------------- ETHERNET MAC Address Configuration ------------------*/
  336. ETH_MACAddressConfig(heth, ETH_MAC_ADDRESS0, heth->Init.MACAddr);
  337. /* Disable MMC Interrupts */
  338. SET_BIT(heth->Instance->MACIMR, ETH_MACIMR_TSTIM | ETH_MACIMR_PMTIM);
  339. /* Disable Rx MMC Interrupts */
  340. SET_BIT(heth->Instance->MMCRIMR, ETH_MMCRIMR_RGUFM | ETH_MMCRIMR_RFAEM | \
  341. ETH_MMCRIMR_RFCEM);
  342. /* Disable Tx MMC Interrupts */
  343. SET_BIT(heth->Instance->MMCTIMR, ETH_MMCTIMR_TGFM | ETH_MMCTIMR_TGFMSCM | \
  344. ETH_MMCTIMR_TGFSCM);
  345. heth->ErrorCode = HAL_ETH_ERROR_NONE;
  346. heth->gState = HAL_ETH_STATE_READY;
  347. return HAL_OK;
  348. }
  349. /**
  350. * @brief DeInitializes the ETH peripheral.
  351. * @param heth: pointer to a ETH_HandleTypeDef structure that contains
  352. * the configuration information for ETHERNET module
  353. * @retval HAL status
  354. */
  355. HAL_StatusTypeDef HAL_ETH_DeInit(ETH_HandleTypeDef *heth)
  356. {
  357. /* Set the ETH peripheral state to BUSY */
  358. heth->gState = HAL_ETH_STATE_BUSY;
  359. #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
  360. if (heth->MspDeInitCallback == NULL)
  361. {
  362. heth->MspDeInitCallback = HAL_ETH_MspDeInit;
  363. }
  364. /* DeInit the low level hardware */
  365. heth->MspDeInitCallback(heth);
  366. #else
  367. /* De-Init the low level hardware : GPIO, CLOCK, NVIC. */
  368. HAL_ETH_MspDeInit(heth);
  369. #endif /* (USE_HAL_ETH_REGISTER_CALLBACKS) */
  370. /* Set ETH HAL state to Disabled */
  371. heth->gState = HAL_ETH_STATE_RESET;
  372. /* Return function status */
  373. return HAL_OK;
  374. }
  375. /**
  376. * @brief Initializes the ETH MSP.
  377. * @param heth: pointer to a ETH_HandleTypeDef structure that contains
  378. * the configuration information for ETHERNET module
  379. * @retval None
  380. */
  381. __weak void HAL_ETH_MspInit(ETH_HandleTypeDef *heth)
  382. {
  383. /* Prevent unused argument(s) compilation warning */
  384. UNUSED(heth);
  385. /* NOTE : This function Should not be modified, when the callback is needed,
  386. the HAL_ETH_MspInit could be implemented in the user file
  387. */
  388. }
  389. /**
  390. * @brief DeInitializes ETH MSP.
  391. * @param heth: pointer to a ETH_HandleTypeDef structure that contains
  392. * the configuration information for ETHERNET module
  393. * @retval None
  394. */
  395. __weak void HAL_ETH_MspDeInit(ETH_HandleTypeDef *heth)
  396. {
  397. /* Prevent unused argument(s) compilation warning */
  398. UNUSED(heth);
  399. /* NOTE : This function Should not be modified, when the callback is needed,
  400. the HAL_ETH_MspDeInit could be implemented in the user file
  401. */
  402. }
  403. #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
  404. /**
  405. * @brief Register a User ETH Callback
  406. * To be used instead of the weak predefined callback
  407. * @param heth eth handle
  408. * @param CallbackID ID of the callback to be registered
  409. * This parameter can be one of the following values:
  410. * @arg @ref HAL_ETH_TX_COMPLETE_CB_ID Tx Complete Callback ID
  411. * @arg @ref HAL_ETH_RX_COMPLETE_CB_ID Rx Complete Callback ID
  412. * @arg @ref HAL_ETH_ERROR_CB_ID Error Callback ID
  413. * @arg @ref HAL_ETH_PMT_CB_ID Power Management Callback ID
  414. * @arg @ref HAL_ETH_WAKEUP_CB_ID Wake UP Callback ID
  415. * @arg @ref HAL_ETH_MSPINIT_CB_ID MspInit callback ID
  416. * @arg @ref HAL_ETH_MSPDEINIT_CB_ID MspDeInit callback ID
  417. * @param pCallback pointer to the Callback function
  418. * @retval status
  419. */
  420. HAL_StatusTypeDef HAL_ETH_RegisterCallback(ETH_HandleTypeDef *heth, HAL_ETH_CallbackIDTypeDef CallbackID,
  421. pETH_CallbackTypeDef pCallback)
  422. {
  423. HAL_StatusTypeDef status = HAL_OK;
  424. if (pCallback == NULL)
  425. {
  426. /* Update the error code */
  427. heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK;
  428. return HAL_ERROR;
  429. }
  430. if (heth->gState == HAL_ETH_STATE_READY)
  431. {
  432. switch (CallbackID)
  433. {
  434. case HAL_ETH_TX_COMPLETE_CB_ID :
  435. heth->TxCpltCallback = pCallback;
  436. break;
  437. case HAL_ETH_RX_COMPLETE_CB_ID :
  438. heth->RxCpltCallback = pCallback;
  439. break;
  440. case HAL_ETH_ERROR_CB_ID :
  441. heth->ErrorCallback = pCallback;
  442. break;
  443. case HAL_ETH_PMT_CB_ID :
  444. heth->PMTCallback = pCallback;
  445. break;
  446. case HAL_ETH_WAKEUP_CB_ID :
  447. heth->WakeUpCallback = pCallback;
  448. break;
  449. case HAL_ETH_MSPINIT_CB_ID :
  450. heth->MspInitCallback = pCallback;
  451. break;
  452. case HAL_ETH_MSPDEINIT_CB_ID :
  453. heth->MspDeInitCallback = pCallback;
  454. break;
  455. default :
  456. /* Update the error code */
  457. heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK;
  458. /* Return error status */
  459. status = HAL_ERROR;
  460. break;
  461. }
  462. }
  463. else if (heth->gState == HAL_ETH_STATE_RESET)
  464. {
  465. switch (CallbackID)
  466. {
  467. case HAL_ETH_MSPINIT_CB_ID :
  468. heth->MspInitCallback = pCallback;
  469. break;
  470. case HAL_ETH_MSPDEINIT_CB_ID :
  471. heth->MspDeInitCallback = pCallback;
  472. break;
  473. default :
  474. /* Update the error code */
  475. heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK;
  476. /* Return error status */
  477. status = HAL_ERROR;
  478. break;
  479. }
  480. }
  481. else
  482. {
  483. /* Update the error code */
  484. heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK;
  485. /* Return error status */
  486. status = HAL_ERROR;
  487. }
  488. return status;
  489. }
  490. /**
  491. * @brief Unregister an ETH Callback
  492. * ETH callback is redirected to the weak predefined callback
  493. * @param heth eth handle
  494. * @param CallbackID ID of the callback to be unregistered
  495. * This parameter can be one of the following values:
  496. * @arg @ref HAL_ETH_TX_COMPLETE_CB_ID Tx Complete Callback ID
  497. * @arg @ref HAL_ETH_RX_COMPLETE_CB_ID Rx Complete Callback ID
  498. * @arg @ref HAL_ETH_ERROR_CB_ID Error Callback ID
  499. * @arg @ref HAL_ETH_PMT_CB_ID Power Management Callback ID
  500. * @arg @ref HAL_ETH_WAKEUP_CB_ID Wake UP Callback ID
  501. * @arg @ref HAL_ETH_MSPINIT_CB_ID MspInit callback ID
  502. * @arg @ref HAL_ETH_MSPDEINIT_CB_ID MspDeInit callback ID
  503. * @retval status
  504. */
  505. HAL_StatusTypeDef HAL_ETH_UnRegisterCallback(ETH_HandleTypeDef *heth, HAL_ETH_CallbackIDTypeDef CallbackID)
  506. {
  507. HAL_StatusTypeDef status = HAL_OK;
  508. if (heth->gState == HAL_ETH_STATE_READY)
  509. {
  510. switch (CallbackID)
  511. {
  512. case HAL_ETH_TX_COMPLETE_CB_ID :
  513. heth->TxCpltCallback = HAL_ETH_TxCpltCallback;
  514. break;
  515. case HAL_ETH_RX_COMPLETE_CB_ID :
  516. heth->RxCpltCallback = HAL_ETH_RxCpltCallback;
  517. break;
  518. case HAL_ETH_ERROR_CB_ID :
  519. heth->ErrorCallback = HAL_ETH_ErrorCallback;
  520. break;
  521. case HAL_ETH_PMT_CB_ID :
  522. heth->PMTCallback = HAL_ETH_PMTCallback;
  523. break;
  524. case HAL_ETH_WAKEUP_CB_ID :
  525. heth->WakeUpCallback = HAL_ETH_WakeUpCallback;
  526. break;
  527. case HAL_ETH_MSPINIT_CB_ID :
  528. heth->MspInitCallback = HAL_ETH_MspInit;
  529. break;
  530. case HAL_ETH_MSPDEINIT_CB_ID :
  531. heth->MspDeInitCallback = HAL_ETH_MspDeInit;
  532. break;
  533. default :
  534. /* Update the error code */
  535. heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK;
  536. /* Return error status */
  537. status = HAL_ERROR;
  538. break;
  539. }
  540. }
  541. else if (heth->gState == HAL_ETH_STATE_RESET)
  542. {
  543. switch (CallbackID)
  544. {
  545. case HAL_ETH_MSPINIT_CB_ID :
  546. heth->MspInitCallback = HAL_ETH_MspInit;
  547. break;
  548. case HAL_ETH_MSPDEINIT_CB_ID :
  549. heth->MspDeInitCallback = HAL_ETH_MspDeInit;
  550. break;
  551. default :
  552. /* Update the error code */
  553. heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK;
  554. /* Return error status */
  555. status = HAL_ERROR;
  556. break;
  557. }
  558. }
  559. else
  560. {
  561. /* Update the error code */
  562. heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK;
  563. /* Return error status */
  564. status = HAL_ERROR;
  565. }
  566. return status;
  567. }
  568. #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
  569. /**
  570. * @}
  571. */
  572. /** @defgroup ETH_Exported_Functions_Group2 IO operation functions
  573. * @brief ETH Transmit and Receive functions
  574. *
  575. @verbatim
  576. ==============================================================================
  577. ##### IO operation functions #####
  578. ==============================================================================
  579. [..]
  580. This subsection provides a set of functions allowing to manage the ETH
  581. data transfer.
  582. @endverbatim
  583. * @{
  584. */
  585. /**
  586. * @brief Enables Ethernet MAC and DMA reception and transmission
  587. * @param heth: pointer to a ETH_HandleTypeDef structure that contains
  588. * the configuration information for ETHERNET module
  589. * @retval HAL status
  590. */
  591. HAL_StatusTypeDef HAL_ETH_Start(ETH_HandleTypeDef *heth)
  592. {
  593. uint32_t tmpreg1;
  594. if (heth->gState == HAL_ETH_STATE_READY)
  595. {
  596. heth->gState = HAL_ETH_STATE_BUSY;
  597. /* Set number of descriptors to build */
  598. heth->RxDescList.RxBuildDescCnt = ETH_RX_DESC_CNT;
  599. /* Build all descriptors */
  600. ETH_UpdateDescriptor(heth);
  601. /* Enable the MAC transmission */
  602. SET_BIT(heth->Instance->MACCR, ETH_MACCR_TE);
  603. /* Wait until the write operation will be taken into account :
  604. at least four TX_CLK/RX_CLK clock cycles */
  605. tmpreg1 = (heth->Instance)->MACCR;
  606. HAL_Delay(ETH_REG_WRITE_DELAY);
  607. (heth->Instance)->MACCR = tmpreg1;
  608. /* Enable the MAC reception */
  609. SET_BIT(heth->Instance->MACCR, ETH_MACCR_RE);
  610. /* Wait until the write operation will be taken into account :
  611. at least four TX_CLK/RX_CLK clock cycles */
  612. tmpreg1 = (heth->Instance)->MACCR;
  613. HAL_Delay(ETH_REG_WRITE_DELAY);
  614. (heth->Instance)->MACCR = tmpreg1;
  615. /* Flush Transmit FIFO */
  616. ETH_FlushTransmitFIFO(heth);
  617. /* Enable the DMA transmission */
  618. SET_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_ST);
  619. /* Enable the DMA reception */
  620. SET_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_SR);
  621. heth->gState = HAL_ETH_STATE_STARTED;
  622. return HAL_OK;
  623. }
  624. else
  625. {
  626. return HAL_ERROR;
  627. }
  628. }
  629. /**
  630. * @brief Enables Ethernet MAC and DMA reception/transmission in Interrupt mode
  631. * @param heth: pointer to a ETH_HandleTypeDef structure that contains
  632. * the configuration information for ETHERNET module
  633. * @retval HAL status
  634. */
  635. HAL_StatusTypeDef HAL_ETH_Start_IT(ETH_HandleTypeDef *heth)
  636. {
  637. uint32_t tmpreg1;
  638. if (heth->gState == HAL_ETH_STATE_READY)
  639. {
  640. heth->gState = HAL_ETH_STATE_BUSY;
  641. /* save IT mode to ETH Handle */
  642. heth->RxDescList.ItMode = 1U;
  643. /* Set number of descriptors to build */
  644. heth->RxDescList.RxBuildDescCnt = ETH_RX_DESC_CNT;
  645. /* Build all descriptors */
  646. ETH_UpdateDescriptor(heth);
  647. /* Wait until the write operation will be taken into account :
  648. at least four TX_CLK/RX_CLK clock cycles */
  649. tmpreg1 = (heth->Instance)->MACCR;
  650. HAL_Delay(ETH_REG_WRITE_DELAY);
  651. (heth->Instance)->MACCR = tmpreg1;
  652. /* Enable the DMA transmission */
  653. SET_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_ST);
  654. /* Enable the DMA reception */
  655. SET_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_SR);
  656. /* Flush Transmit FIFO */
  657. ETH_FlushTransmitFIFO(heth);
  658. /* Enable the MAC transmission */
  659. SET_BIT(heth->Instance->MACCR, ETH_MACCR_TE);
  660. /* Wait until the write operation will be taken into account :
  661. at least four TX_CLK/RX_CLK clock cycles */
  662. tmpreg1 = (heth->Instance)->MACCR;
  663. HAL_Delay(ETH_REG_WRITE_DELAY);
  664. (heth->Instance)->MACCR = tmpreg1;
  665. /* Enable the MAC reception */
  666. SET_BIT(heth->Instance->MACCR, ETH_MACCR_RE);
  667. /* Enable ETH DMA interrupts:
  668. - Tx complete interrupt
  669. - Rx complete interrupt
  670. - Fatal bus interrupt
  671. */
  672. __HAL_ETH_DMA_ENABLE_IT(heth, (ETH_DMAIER_NISE | ETH_DMAIER_RIE | ETH_DMAIER_TIE |
  673. ETH_DMAIER_FBEIE | ETH_DMAIER_AISE | ETH_DMAIER_RBUIE));
  674. heth->gState = HAL_ETH_STATE_STARTED;
  675. return HAL_OK;
  676. }
  677. else
  678. {
  679. return HAL_ERROR;
  680. }
  681. }
  682. /**
  683. * @brief Stop Ethernet MAC and DMA reception/transmission
  684. * @param heth: pointer to a ETH_HandleTypeDef structure that contains
  685. * the configuration information for ETHERNET module
  686. * @retval HAL status
  687. */
  688. HAL_StatusTypeDef HAL_ETH_Stop(ETH_HandleTypeDef *heth)
  689. {
  690. uint32_t tmpreg1;
  691. if (heth->gState == HAL_ETH_STATE_STARTED)
  692. {
  693. /* Set the ETH peripheral state to BUSY */
  694. heth->gState = HAL_ETH_STATE_BUSY;
  695. /* Disable the DMA transmission */
  696. CLEAR_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_ST);
  697. /* Disable the DMA reception */
  698. CLEAR_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_SR);
  699. /* Disable the MAC reception */
  700. CLEAR_BIT(heth->Instance->MACCR, ETH_MACCR_RE);
  701. /* Wait until the write operation will be taken into account :
  702. at least four TX_CLK/RX_CLK clock cycles */
  703. tmpreg1 = (heth->Instance)->MACCR;
  704. HAL_Delay(ETH_REG_WRITE_DELAY);
  705. (heth->Instance)->MACCR = tmpreg1;
  706. /* Flush Transmit FIFO */
  707. ETH_FlushTransmitFIFO(heth);
  708. /* Disable the MAC transmission */
  709. CLEAR_BIT(heth->Instance->MACCR, ETH_MACCR_TE);
  710. /* Wait until the write operation will be taken into account :
  711. at least four TX_CLK/RX_CLK clock cycles */
  712. tmpreg1 = (heth->Instance)->MACCR;
  713. HAL_Delay(ETH_REG_WRITE_DELAY);
  714. (heth->Instance)->MACCR = tmpreg1;
  715. heth->gState = HAL_ETH_STATE_READY;
  716. /* Return function status */
  717. return HAL_OK;
  718. }
  719. else
  720. {
  721. return HAL_ERROR;
  722. }
  723. }
  724. /**
  725. * @brief Stop Ethernet MAC and DMA reception/transmission in Interrupt mode
  726. * @param heth: pointer to a ETH_HandleTypeDef structure that contains
  727. * the configuration information for ETHERNET module
  728. * @retval HAL status
  729. */
  730. HAL_StatusTypeDef HAL_ETH_Stop_IT(ETH_HandleTypeDef *heth)
  731. {
  732. ETH_DMADescTypeDef *dmarxdesc;
  733. uint32_t descindex;
  734. uint32_t tmpreg1;
  735. if (heth->gState == HAL_ETH_STATE_STARTED)
  736. {
  737. /* Set the ETH peripheral state to BUSY */
  738. heth->gState = HAL_ETH_STATE_BUSY;
  739. __HAL_ETH_DMA_DISABLE_IT(heth, (ETH_DMAIER_NISE | ETH_DMAIER_RIE | ETH_DMAIER_TIE |
  740. ETH_DMAIER_FBEIE | ETH_DMAIER_AISE | ETH_DMAIER_RBUIE));
  741. /* Disable the DMA transmission */
  742. CLEAR_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_ST);
  743. /* Disable the DMA reception */
  744. CLEAR_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_SR);
  745. /* Disable the MAC reception */
  746. CLEAR_BIT(heth->Instance->MACCR, ETH_MACCR_RE);
  747. /* Wait until the write operation will be taken into account :
  748. at least four TX_CLK/RX_CLK clock cycles */
  749. tmpreg1 = (heth->Instance)->MACCR;
  750. HAL_Delay(ETH_REG_WRITE_DELAY);
  751. (heth->Instance)->MACCR = tmpreg1;
  752. /* Flush Transmit FIFO */
  753. ETH_FlushTransmitFIFO(heth);
  754. /* Disable the MAC transmission */
  755. CLEAR_BIT(heth->Instance->MACCR, ETH_MACCR_TE);
  756. /* Wait until the write operation will be taken into account :
  757. at least four TX_CLK/RX_CLK clock cycles */
  758. tmpreg1 = (heth->Instance)->MACCR;
  759. HAL_Delay(ETH_REG_WRITE_DELAY);
  760. (heth->Instance)->MACCR = tmpreg1;
  761. /* Clear IOC bit to all Rx descriptors */
  762. for (descindex = 0; descindex < (uint32_t)ETH_RX_DESC_CNT; descindex++)
  763. {
  764. dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descindex];
  765. SET_BIT(dmarxdesc->DESC1, ETH_DMARXDESC_DIC);
  766. }
  767. heth->RxDescList.ItMode = 0U;
  768. heth->gState = HAL_ETH_STATE_READY;
  769. /* Return function status */
  770. return HAL_OK;
  771. }
  772. else
  773. {
  774. return HAL_ERROR;
  775. }
  776. }
  777. /**
  778. * @brief Sends an Ethernet Packet in polling mode.
  779. * @param heth: pointer to a ETH_HandleTypeDef structure that contains
  780. * the configuration information for ETHERNET module
  781. * @param pTxConfig: Hold the configuration of packet to be transmitted
  782. * @param Timeout: timeout value
  783. * @retval HAL status
  784. */
  785. HAL_StatusTypeDef HAL_ETH_Transmit(ETH_HandleTypeDef *heth, ETH_TxPacketConfigTypeDef *pTxConfig, uint32_t Timeout)
  786. {
  787. uint32_t tickstart;
  788. ETH_DMADescTypeDef *dmatxdesc;
  789. if (pTxConfig == NULL)
  790. {
  791. heth->ErrorCode |= HAL_ETH_ERROR_PARAM;
  792. return HAL_ERROR;
  793. }
  794. if (heth->gState == HAL_ETH_STATE_STARTED)
  795. {
  796. /* Config DMA Tx descriptor by Tx Packet info */
  797. if (ETH_Prepare_Tx_Descriptors(heth, pTxConfig, 0) != HAL_ETH_ERROR_NONE)
  798. {
  799. /* Set the ETH error code */
  800. heth->ErrorCode |= HAL_ETH_ERROR_BUSY;
  801. return HAL_ERROR;
  802. }
  803. /* Ensure completion of descriptor preparation before transmission start */
  804. __DSB();
  805. dmatxdesc = (ETH_DMADescTypeDef *)(&heth->TxDescList)->TxDesc[heth->TxDescList.CurTxDesc];
  806. /* Incr current tx desc index */
  807. INCR_TX_DESC_INDEX(heth->TxDescList.CurTxDesc, 1U);
  808. /* Start transmission */
  809. /* issue a poll command to Tx DMA by writing address of next immediate free descriptor */
  810. WRITE_REG(heth->Instance->DMATPDR, (uint32_t)(heth->TxDescList.TxDesc[heth->TxDescList.CurTxDesc]));
  811. tickstart = HAL_GetTick();
  812. /* Wait for data to be transmitted or timeout occurred */
  813. while ((dmatxdesc->DESC0 & ETH_DMATXDESC_OWN) != (uint32_t)RESET)
  814. {
  815. if ((heth->Instance->DMASR & ETH_DMASR_FBES) != (uint32_t)RESET)
  816. {
  817. heth->ErrorCode |= HAL_ETH_ERROR_DMA;
  818. heth->DMAErrorCode = heth->Instance->DMASR;
  819. /* Return function status */
  820. return HAL_ERROR;
  821. }
  822. /* Check for the Timeout */
  823. if (Timeout != HAL_MAX_DELAY)
  824. {
  825. if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
  826. {
  827. heth->ErrorCode |= HAL_ETH_ERROR_TIMEOUT;
  828. /* Clear TX descriptor so that we can proceed */
  829. dmatxdesc->DESC0 = (ETH_DMATXDESC_FS | ETH_DMATXDESC_LS);
  830. return HAL_ERROR;
  831. }
  832. }
  833. }
  834. /* Return function status */
  835. return HAL_OK;
  836. }
  837. else
  838. {
  839. return HAL_ERROR;
  840. }
  841. }
  842. /**
  843. * @brief Sends an Ethernet Packet in interrupt mode.
  844. * @param heth: pointer to a ETH_HandleTypeDef structure that contains
  845. * the configuration information for ETHERNET module
  846. * @param pTxConfig: Hold the configuration of packet to be transmitted
  847. * @retval HAL status
  848. */
  849. HAL_StatusTypeDef HAL_ETH_Transmit_IT(ETH_HandleTypeDef *heth, ETH_TxPacketConfigTypeDef *pTxConfig)
  850. {
  851. if (pTxConfig == NULL)
  852. {
  853. heth->ErrorCode |= HAL_ETH_ERROR_PARAM;
  854. return HAL_ERROR;
  855. }
  856. if (heth->gState == HAL_ETH_STATE_STARTED)
  857. {
  858. /* Save the packet pointer to release. */
  859. heth->TxDescList.CurrentPacketAddress = (uint32_t *)pTxConfig->pData;
  860. /* Config DMA Tx descriptor by Tx Packet info */
  861. if (ETH_Prepare_Tx_Descriptors(heth, pTxConfig, 1) != HAL_ETH_ERROR_NONE)
  862. {
  863. heth->ErrorCode |= HAL_ETH_ERROR_BUSY;
  864. return HAL_ERROR;
  865. }
  866. /* Ensure completion of descriptor preparation before transmission start */
  867. __DSB();
  868. /* Incr current tx desc index */
  869. INCR_TX_DESC_INDEX(heth->TxDescList.CurTxDesc, 1U);
  870. /* Start transmission */
  871. /* issue a poll command to Tx DMA by writing address of next immediate free descriptor */
  872. if (((heth->Instance)->DMASR & ETH_DMASR_TBUS) != (uint32_t)RESET)
  873. {
  874. /* Clear TBUS ETHERNET DMA flag */
  875. (heth->Instance)->DMASR = ETH_DMASR_TBUS;
  876. /* Resume DMA transmission*/
  877. (heth->Instance)->DMATPDR = 0U;
  878. }
  879. return HAL_OK;
  880. }
  881. else
  882. {
  883. return HAL_ERROR;
  884. }
  885. }
  886. /**
  887. * @brief Read a received packet.
  888. * @param heth: pointer to a ETH_HandleTypeDef structure that contains
  889. * the configuration information for ETHERNET module
  890. * @param pAppBuff: Pointer to an application buffer to receive the packet.
  891. * @retval HAL status
  892. */
  893. HAL_StatusTypeDef HAL_ETH_ReadData(ETH_HandleTypeDef *heth, void **pAppBuff)
  894. {
  895. uint32_t descidx;
  896. ETH_DMADescTypeDef *dmarxdesc;
  897. uint32_t desccnt = 0U;
  898. uint32_t desccntmax;
  899. uint32_t bufflength;
  900. uint8_t rxdataready = 0U;
  901. if (pAppBuff == NULL)
  902. {
  903. heth->ErrorCode |= HAL_ETH_ERROR_PARAM;
  904. return HAL_ERROR;
  905. }
  906. if (heth->gState != HAL_ETH_STATE_STARTED)
  907. {
  908. return HAL_ERROR;
  909. }
  910. descidx = heth->RxDescList.RxDescIdx;
  911. dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descidx];
  912. desccntmax = ETH_RX_DESC_CNT - heth->RxDescList.RxBuildDescCnt;
  913. /* Check if descriptor is not owned by DMA */
  914. while ((READ_BIT(dmarxdesc->DESC0, ETH_DMARXDESC_OWN) == (uint32_t)RESET) && (desccnt < desccntmax)
  915. && (rxdataready == 0U))
  916. {
  917. if (READ_BIT(dmarxdesc->DESC0, ETH_DMARXDESC_LS) != (uint32_t)RESET)
  918. {
  919. /* Get timestamp high */
  920. heth->RxDescList.TimeStamp.TimeStampHigh = dmarxdesc->DESC7;
  921. /* Get timestamp low */
  922. heth->RxDescList.TimeStamp.TimeStampLow = dmarxdesc->DESC6;
  923. }
  924. if ((READ_BIT(dmarxdesc->DESC0, ETH_DMARXDESC_FS) != (uint32_t)RESET) || (heth->RxDescList.pRxStart != NULL))
  925. {
  926. /* Check first descriptor */
  927. if (READ_BIT(dmarxdesc->DESC0, ETH_DMARXDESC_FS) != (uint32_t)RESET)
  928. {
  929. heth->RxDescList.RxDescCnt = 0;
  930. heth->RxDescList.RxDataLength = 0;
  931. }
  932. /* Get the Frame Length of the received packet */
  933. bufflength = ((dmarxdesc->DESC0 & ETH_DMARXDESC_FL) >> ETH_DMARXDESC_FRAMELENGTHSHIFT);
  934. /* Check if last descriptor */
  935. if (READ_BIT(dmarxdesc->DESC0, ETH_DMARXDESC_LS) != (uint32_t)RESET)
  936. {
  937. /* Save Last descriptor index */
  938. heth->RxDescList.pRxLastRxDesc = dmarxdesc->DESC0;
  939. /* Packet ready */
  940. rxdataready = 1;
  941. }
  942. /* Link data */
  943. WRITE_REG(dmarxdesc->BackupAddr0, dmarxdesc->DESC2);
  944. #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
  945. /*Call registered Link callback*/
  946. heth->rxLinkCallback(&heth->RxDescList.pRxStart, &heth->RxDescList.pRxEnd,
  947. (uint8_t *)dmarxdesc->BackupAddr0, bufflength);
  948. #else
  949. /* Link callback */
  950. HAL_ETH_RxLinkCallback(&heth->RxDescList.pRxStart, &heth->RxDescList.pRxEnd,
  951. (uint8_t *)dmarxdesc->BackupAddr0, (uint16_t) bufflength);
  952. #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
  953. heth->RxDescList.RxDescCnt++;
  954. heth->RxDescList.RxDataLength += bufflength;
  955. /* Clear buffer pointer */
  956. dmarxdesc->BackupAddr0 = 0;
  957. }
  958. /* Increment current rx descriptor index */
  959. INCR_RX_DESC_INDEX(descidx, 1U);
  960. /* Get current descriptor address */
  961. dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descidx];
  962. desccnt++;
  963. }
  964. heth->RxDescList.RxBuildDescCnt += desccnt;
  965. if ((heth->RxDescList.RxBuildDescCnt) != 0U)
  966. {
  967. /* Update Descriptors */
  968. ETH_UpdateDescriptor(heth);
  969. }
  970. heth->RxDescList.RxDescIdx = descidx;
  971. if (rxdataready == 1U)
  972. {
  973. /* Return received packet */
  974. *pAppBuff = heth->RxDescList.pRxStart;
  975. /* Reset first element */
  976. heth->RxDescList.pRxStart = NULL;
  977. return HAL_OK;
  978. }
  979. /* Packet not ready */
  980. return HAL_ERROR;
  981. }
  982. /**
  983. * @brief This function gives back Rx Desc of the last received Packet
  984. * to the DMA, so ETH DMA will be able to use these descriptors
  985. * to receive next Packets.
  986. * @param heth: pointer to a ETH_HandleTypeDef structure that contains
  987. * the configuration information for ETHERNET module
  988. * @retval HAL status
  989. */
  990. static void ETH_UpdateDescriptor(ETH_HandleTypeDef *heth)
  991. {
  992. uint32_t descidx;
  993. uint32_t tailidx;
  994. uint32_t desccount;
  995. ETH_DMADescTypeDef *dmarxdesc;
  996. uint8_t *buff = NULL;
  997. uint8_t allocStatus = 1U;
  998. descidx = heth->RxDescList.RxBuildDescIdx;
  999. dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descidx];
  1000. desccount = heth->RxDescList.RxBuildDescCnt;
  1001. while ((desccount > 0U) && (allocStatus != 0U))
  1002. {
  1003. /* Check if a buffer's attached the descriptor */
  1004. if (READ_REG(dmarxdesc->BackupAddr0) == 0U)
  1005. {
  1006. /* Get a new buffer. */
  1007. #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
  1008. /*Call registered Allocate callback*/
  1009. heth->rxAllocateCallback(&buff);
  1010. #else
  1011. /* Allocate callback */
  1012. HAL_ETH_RxAllocateCallback(&buff);
  1013. #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
  1014. if (buff == NULL)
  1015. {
  1016. allocStatus = 0U;
  1017. }
  1018. else
  1019. {
  1020. WRITE_REG(dmarxdesc->BackupAddr0, (uint32_t)buff);
  1021. WRITE_REG(dmarxdesc->DESC2, (uint32_t)buff);
  1022. }
  1023. }
  1024. if (allocStatus != 0U)
  1025. {
  1026. if (heth->RxDescList.ItMode == 0U)
  1027. {
  1028. WRITE_REG(dmarxdesc->DESC1, heth->Init.RxBuffLen | ETH_DMARXDESC_DIC | ETH_DMARXDESC_RCH);
  1029. }
  1030. else
  1031. {
  1032. WRITE_REG(dmarxdesc->DESC1, heth->Init.RxBuffLen | ETH_DMARXDESC_RCH);
  1033. }
  1034. SET_BIT(dmarxdesc->DESC0, ETH_DMARXDESC_OWN);
  1035. /* Increment current rx descriptor index */
  1036. INCR_RX_DESC_INDEX(descidx, 1U);
  1037. /* Get current descriptor address */
  1038. dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descidx];
  1039. desccount--;
  1040. }
  1041. }
  1042. if (heth->RxDescList.RxBuildDescCnt != desccount)
  1043. {
  1044. /* Set the tail pointer index */
  1045. tailidx = (ETH_RX_DESC_CNT + descidx - 1U) % ETH_RX_DESC_CNT;
  1046. /* DMB instruction to avoid race condition */
  1047. __DMB();
  1048. /* Set the Tail pointer address */
  1049. WRITE_REG(heth->Instance->DMARPDR, ((uint32_t)(heth->Init.RxDesc + (tailidx))));
  1050. heth->RxDescList.RxBuildDescIdx = descidx;
  1051. heth->RxDescList.RxBuildDescCnt = desccount;
  1052. }
  1053. }
  1054. /**
  1055. * @brief Register the Rx alloc callback.
  1056. * @param heth: pointer to a ETH_HandleTypeDef structure that contains
  1057. * the configuration information for ETHERNET module
  1058. * @param rxAllocateCallback: pointer to function to alloc buffer
  1059. * @retval HAL status
  1060. */
  1061. HAL_StatusTypeDef HAL_ETH_RegisterRxAllocateCallback(ETH_HandleTypeDef *heth,
  1062. pETH_rxAllocateCallbackTypeDef rxAllocateCallback)
  1063. {
  1064. if (rxAllocateCallback == NULL)
  1065. {
  1066. /* No buffer to save */
  1067. return HAL_ERROR;
  1068. }
  1069. /* Set function to allocate buffer */
  1070. heth->rxAllocateCallback = rxAllocateCallback;
  1071. return HAL_OK;
  1072. }
  1073. /**
  1074. * @brief Unregister the Rx alloc callback.
  1075. * @param heth: pointer to a ETH_HandleTypeDef structure that contains
  1076. * the configuration information for ETHERNET module
  1077. * @retval HAL status
  1078. */
  1079. HAL_StatusTypeDef HAL_ETH_UnRegisterRxAllocateCallback(ETH_HandleTypeDef *heth)
  1080. {
  1081. /* Set function to allocate buffer */
  1082. heth->rxAllocateCallback = HAL_ETH_RxAllocateCallback;
  1083. return HAL_OK;
  1084. }
  1085. /**
  1086. * @brief Rx Allocate callback.
  1087. * @param buff: pointer to allocated buffer
  1088. * @retval None
  1089. */
  1090. __weak void HAL_ETH_RxAllocateCallback(uint8_t **buff)
  1091. {
  1092. /* Prevent unused argument(s) compilation warning */
  1093. UNUSED(buff);
  1094. /* NOTE : This function Should not be modified, when the callback is needed,
  1095. the HAL_ETH_RxAllocateCallback could be implemented in the user file
  1096. */
  1097. }
  1098. /**
  1099. * @brief Rx Link callback.
  1100. * @param pStart: pointer to packet start
  1101. * @param pEnd: pointer to packet end
  1102. * @param buff: pointer to received data
  1103. * @param Length: received data length
  1104. * @retval None
  1105. */
  1106. __weak void HAL_ETH_RxLinkCallback(void **pStart, void **pEnd, uint8_t *buff, uint16_t Length)
  1107. {
  1108. /* Prevent unused argument(s) compilation warning */
  1109. UNUSED(pStart);
  1110. UNUSED(pEnd);
  1111. UNUSED(buff);
  1112. UNUSED(Length);
  1113. /* NOTE : This function Should not be modified, when the callback is needed,
  1114. the HAL_ETH_RxLinkCallback could be implemented in the user file
  1115. */
  1116. }
  1117. /**
  1118. * @brief Set the Rx link data function.
  1119. * @param heth: pointer to a ETH_HandleTypeDef structure that contains
  1120. * the configuration information for ETHERNET module
  1121. * @param rxLinkCallback: pointer to function to link data
  1122. * @retval HAL status
  1123. */
  1124. HAL_StatusTypeDef HAL_ETH_RegisterRxLinkCallback(ETH_HandleTypeDef *heth, pETH_rxLinkCallbackTypeDef rxLinkCallback)
  1125. {
  1126. if (rxLinkCallback == NULL)
  1127. {
  1128. /* No buffer to save */
  1129. return HAL_ERROR;
  1130. }
  1131. /* Set function to link data */
  1132. heth->rxLinkCallback = rxLinkCallback;
  1133. return HAL_OK;
  1134. }
  1135. /**
  1136. * @brief Unregister the Rx link callback.
  1137. * @param heth: pointer to a ETH_HandleTypeDef structure that contains
  1138. * the configuration information for ETHERNET module
  1139. * @retval HAL status
  1140. */
  1141. HAL_StatusTypeDef HAL_ETH_UnRegisterRxLinkCallback(ETH_HandleTypeDef *heth)
  1142. {
  1143. /* Set function to allocate buffer */
  1144. heth->rxLinkCallback = HAL_ETH_RxLinkCallback;
  1145. return HAL_OK;
  1146. }
  1147. /**
  1148. * @brief Get the error state of the last received packet.
  1149. * @param heth: pointer to a ETH_HandleTypeDef structure that contains
  1150. * the configuration information for ETHERNET module
  1151. * @param pErrorCode: pointer to uint32_t to hold the error code
  1152. * @retval HAL status
  1153. */
  1154. HAL_StatusTypeDef HAL_ETH_GetRxDataErrorCode(const ETH_HandleTypeDef *heth, uint32_t *pErrorCode)
  1155. {
  1156. /* Get error bits. */
  1157. *pErrorCode = READ_BIT(heth->RxDescList.pRxLastRxDesc, ETH_DMARXDESC_ERRORS_MASK);
  1158. return HAL_OK;
  1159. }
  1160. /**
  1161. * @brief Set the Tx free function.
  1162. * @param heth: pointer to a ETH_HandleTypeDef structure that contains
  1163. * the configuration information for ETHERNET module
  1164. * @param txFreeCallback: pointer to function to release the packet
  1165. * @retval HAL status
  1166. */
  1167. HAL_StatusTypeDef HAL_ETH_RegisterTxFreeCallback(ETH_HandleTypeDef *heth, pETH_txFreeCallbackTypeDef txFreeCallback)
  1168. {
  1169. if (txFreeCallback == NULL)
  1170. {
  1171. /* No buffer to save */
  1172. return HAL_ERROR;
  1173. }
  1174. /* Set function to free transmmitted packet */
  1175. heth->txFreeCallback = txFreeCallback;
  1176. return HAL_OK;
  1177. }
  1178. /**
  1179. * @brief Unregister the Tx free callback.
  1180. * @param heth: pointer to a ETH_HandleTypeDef structure that contains
  1181. * the configuration information for ETHERNET module
  1182. * @retval HAL status
  1183. */
  1184. HAL_StatusTypeDef HAL_ETH_UnRegisterTxFreeCallback(ETH_HandleTypeDef *heth)
  1185. {
  1186. /* Set function to allocate buffer */
  1187. heth->txFreeCallback = HAL_ETH_TxFreeCallback;
  1188. return HAL_OK;
  1189. }
  1190. /**
  1191. * @brief Tx Free callback.
  1192. * @param buff: pointer to buffer to free
  1193. * @retval None
  1194. */
  1195. __weak void HAL_ETH_TxFreeCallback(uint32_t *buff)
  1196. {
  1197. /* Prevent unused argument(s) compilation warning */
  1198. UNUSED(buff);
  1199. /* NOTE : This function Should not be modified, when the callback is needed,
  1200. the HAL_ETH_TxFreeCallback could be implemented in the user file
  1201. */
  1202. }
  1203. /**
  1204. * @brief Release transmitted Tx packets.
  1205. * @param heth: pointer to a ETH_HandleTypeDef structure that contains
  1206. * the configuration information for ETHERNET module
  1207. * @retval HAL status
  1208. */
  1209. HAL_StatusTypeDef HAL_ETH_ReleaseTxPacket(ETH_HandleTypeDef *heth)
  1210. {
  1211. ETH_TxDescListTypeDef *dmatxdesclist = &heth->TxDescList;
  1212. uint32_t numOfBuf = dmatxdesclist->BuffersInUse;
  1213. uint32_t idx = dmatxdesclist->releaseIndex;
  1214. uint8_t pktTxStatus = 1U;
  1215. uint8_t pktInUse;
  1216. #ifdef HAL_ETH_USE_PTP
  1217. ETH_TimeStampTypeDef *timestamp = &heth->TxTimestamp;
  1218. #endif /* HAL_ETH_USE_PTP */
  1219. /* Loop through buffers in use. */
  1220. while ((numOfBuf != 0U) && (pktTxStatus != 0U))
  1221. {
  1222. pktInUse = 1U;
  1223. numOfBuf--;
  1224. /* If no packet, just examine the next packet. */
  1225. if (dmatxdesclist->PacketAddress[idx] == NULL)
  1226. {
  1227. /* No packet in use, skip to next. */
  1228. INCR_TX_DESC_INDEX(idx, 1U);
  1229. pktInUse = 0U;
  1230. }
  1231. if (pktInUse != 0U)
  1232. {
  1233. /* Determine if the packet has been transmitted. */
  1234. if ((heth->Init.TxDesc[idx].DESC0 & ETH_DMATXDESC_OWN) == 0U)
  1235. {
  1236. #ifdef HAL_ETH_USE_PTP
  1237. if ((heth->Init.TxDesc[idx].DESC0 & ETH_DMATXDESC_LS)
  1238. && (heth->Init.TxDesc[idx].DESC0 & ETH_DMATXDESC_TTSS))
  1239. {
  1240. /* Get timestamp low */
  1241. timestamp->TimeStampLow = heth->Init.TxDesc[idx].DESC6;
  1242. /* Get timestamp high */
  1243. timestamp->TimeStampHigh = heth->Init.TxDesc[idx].DESC7;
  1244. }
  1245. else
  1246. {
  1247. timestamp->TimeStampHigh = timestamp->TimeStampLow = UINT32_MAX;
  1248. }
  1249. #endif /* HAL_ETH_USE_PTP */
  1250. #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
  1251. /*Call registered callbacks*/
  1252. #ifdef HAL_ETH_USE_PTP
  1253. /* Handle Ptp */
  1254. if (timestamp->TimeStampHigh != UINT32_MAX && timestamp->TimeStampLow != UINT32_MAX)
  1255. {
  1256. heth->txPtpCallback(dmatxdesclist->PacketAddress[idx], timestamp);
  1257. }
  1258. #endif /* HAL_ETH_USE_PTP */
  1259. /* Release the packet. */
  1260. heth->txFreeCallback(dmatxdesclist->PacketAddress[idx]);
  1261. #else
  1262. /* Call callbacks */
  1263. #ifdef HAL_ETH_USE_PTP
  1264. /* Handle Ptp */
  1265. if (timestamp->TimeStampHigh != UINT32_MAX && timestamp->TimeStampLow != UINT32_MAX)
  1266. {
  1267. HAL_ETH_TxPtpCallback(dmatxdesclist->PacketAddress[idx], timestamp);
  1268. }
  1269. #endif /* HAL_ETH_USE_PTP */
  1270. /* Release the packet. */
  1271. HAL_ETH_TxFreeCallback(dmatxdesclist->PacketAddress[idx]);
  1272. #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
  1273. /* Clear the entry in the in-use array. */
  1274. dmatxdesclist->PacketAddress[idx] = NULL;
  1275. /* Update the transmit relesae index and number of buffers in use. */
  1276. INCR_TX_DESC_INDEX(idx, 1U);
  1277. dmatxdesclist->BuffersInUse = numOfBuf;
  1278. dmatxdesclist->releaseIndex = idx;
  1279. }
  1280. else
  1281. {
  1282. /* Get out of the loop! */
  1283. pktTxStatus = 0U;
  1284. }
  1285. }
  1286. }
  1287. return HAL_OK;
  1288. }
  1289. #ifdef HAL_ETH_USE_PTP
  1290. /**
  1291. * @brief Set the Ethernet PTP configuration.
  1292. * @param heth: pointer to a ETH_HandleTypeDef structure that contains
  1293. * the configuration information for ETHERNET module
  1294. * @param ptpconfig: pointer to a ETH_PTP_ConfigTypeDef structure that contains
  1295. * the configuration information for PTP
  1296. * @retval HAL status
  1297. */
  1298. HAL_StatusTypeDef HAL_ETH_PTP_SetConfig(ETH_HandleTypeDef *heth, ETH_PTP_ConfigTypeDef *ptpconfig)
  1299. {
  1300. uint32_t tmpTSCR;
  1301. ETH_TimeTypeDef time;
  1302. if (ptpconfig == NULL)
  1303. {
  1304. return HAL_ERROR;
  1305. }
  1306. /* Mask the Timestamp Trigger interrupt */
  1307. CLEAR_BIT(heth->Instance->MACIMR, ETH_MACIMR_TSTIM);
  1308. tmpTSCR = ptpconfig->Timestamp |
  1309. ((uint32_t)ptpconfig->TimestampUpdate << ETH_PTPTSCR_TSFCU_Pos) |
  1310. ((uint32_t)ptpconfig->TimestampAll << ETH_PTPTSCR_TSSARFE_Pos) |
  1311. ((uint32_t)ptpconfig->TimestampRolloverMode << ETH_PTPTSCR_TSSSR_Pos) |
  1312. ((uint32_t)ptpconfig->TimestampV2 << ETH_PTPTSCR_TSPTPPSV2E_Pos) |
  1313. ((uint32_t)ptpconfig->TimestampEthernet << ETH_PTPTSCR_TSSPTPOEFE_Pos) |
  1314. ((uint32_t)ptpconfig->TimestampIPv6 << ETH_PTPTSCR_TSSIPV6FE_Pos) |
  1315. ((uint32_t)ptpconfig->TimestampIPv4 << ETH_PTPTSCR_TSSIPV4FE_Pos) |
  1316. ((uint32_t)ptpconfig->TimestampEvent << ETH_PTPTSCR_TSSEME_Pos) |
  1317. ((uint32_t)ptpconfig->TimestampMaster << ETH_PTPTSCR_TSSMRME_Pos) |
  1318. ((uint32_t)ptpconfig->TimestampFilter << ETH_PTPTSCR_TSPFFMAE_Pos) |
  1319. ((uint32_t)ptpconfig->TimestampClockType << ETH_PTPTSCR_TSCNT_Pos);
  1320. /* Write to MACTSCR */
  1321. MODIFY_REG(heth->Instance->PTPTSCR, ETH_MACTSCR_MASK, tmpTSCR);
  1322. /* Enable Timestamp */
  1323. SET_BIT(heth->Instance->PTPTSCR, ETH_PTPTSCR_TSE);
  1324. WRITE_REG(heth->Instance->PTPSSIR, ptpconfig->TimestampSubsecondInc);
  1325. WRITE_REG(heth->Instance->PTPTSAR, ptpconfig->TimestampAddend);
  1326. /* Enable Timestamp */
  1327. if (ptpconfig->TimestampAddendUpdate == ENABLE)
  1328. {
  1329. SET_BIT(heth->Instance->PTPTSCR, ETH_PTPTSCR_TSARU);
  1330. while ((heth->Instance->PTPTSCR & ETH_PTPTSCR_TSARU) != 0)
  1331. {
  1332. }
  1333. }
  1334. /* Enable Update mode */
  1335. if (ptpconfig->TimestampUpdateMode == ENABLE)
  1336. {
  1337. SET_BIT(heth->Instance->PTPTSCR, ETH_PTPTSCR_TSFCU);
  1338. }
  1339. /* Set PTP Configuration done */
  1340. heth->IsPtpConfigured = HAL_ETH_PTP_CONFIGURED;
  1341. /* Set Seconds */
  1342. time.Seconds = heth->Instance->PTPTSHR;
  1343. /* Set NanoSeconds */
  1344. time.NanoSeconds = heth->Instance->PTPTSLR;
  1345. HAL_ETH_PTP_SetTime(heth, &time);
  1346. /* Ptp Init */
  1347. SET_BIT(heth->Instance->PTPTSCR, ETH_PTPTSCR_TSSTI);
  1348. /* Return function status */
  1349. return HAL_OK;
  1350. }
  1351. /**
  1352. * @brief Get the Ethernet PTP configuration.
  1353. * @param heth: pointer to a ETH_HandleTypeDef structure that contains
  1354. * the configuration information for ETHERNET module
  1355. * @param ptpconfig: pointer to a ETH_PTP_ConfigTypeDef structure that contains
  1356. * the configuration information for PTP
  1357. * @retval HAL status
  1358. */
  1359. HAL_StatusTypeDef HAL_ETH_PTP_GetConfig(ETH_HandleTypeDef *heth, ETH_PTP_ConfigTypeDef *ptpconfig)
  1360. {
  1361. if (ptpconfig == NULL)
  1362. {
  1363. return HAL_ERROR;
  1364. }
  1365. ptpconfig->Timestamp = READ_BIT(heth->Instance->PTPTSCR, ETH_PTPTSCR_TSE);
  1366. ptpconfig->TimestampUpdate = ((READ_BIT(heth->Instance->PTPTSCR,
  1367. ETH_PTPTSCR_TSFCU) >> ETH_PTPTSCR_TSFCU_Pos) > 0U) ? ENABLE : DISABLE;
  1368. ptpconfig->TimestampAll = ((READ_BIT(heth->Instance->PTPTSCR,
  1369. ETH_PTPTSCR_TSSARFE) >> ETH_PTPTSCR_TSSARFE_Pos) > 0U) ? ENABLE : DISABLE;
  1370. ptpconfig->TimestampRolloverMode = ((READ_BIT(heth->Instance->PTPTSCR,
  1371. ETH_PTPTSCR_TSSSR) >> ETH_PTPTSCR_TSSSR_Pos) > 0U)
  1372. ? ENABLE : DISABLE;
  1373. ptpconfig->TimestampV2 = ((READ_BIT(heth->Instance->PTPTSCR,
  1374. ETH_PTPTSCR_TSPTPPSV2E) >> ETH_PTPTSCR_TSPTPPSV2E_Pos) > 0U) ? ENABLE : DISABLE;
  1375. ptpconfig->TimestampEthernet = ((READ_BIT(heth->Instance->PTPTSCR,
  1376. ETH_PTPTSCR_TSSPTPOEFE) >> ETH_PTPTSCR_TSSPTPOEFE_Pos) > 0U)
  1377. ? ENABLE : DISABLE;
  1378. ptpconfig->TimestampIPv6 = ((READ_BIT(heth->Instance->PTPTSCR,
  1379. ETH_PTPTSCR_TSSIPV6FE) >> ETH_PTPTSCR_TSSIPV6FE_Pos) > 0U) ? ENABLE : DISABLE;
  1380. ptpconfig->TimestampIPv4 = ((READ_BIT(heth->Instance->PTPTSCR,
  1381. ETH_PTPTSCR_TSSIPV4FE) >> ETH_PTPTSCR_TSSIPV4FE_Pos) > 0U) ? ENABLE : DISABLE;
  1382. ptpconfig->TimestampEvent = ((READ_BIT(heth->Instance->PTPTSCR,
  1383. ETH_PTPTSCR_TSSEME) >> ETH_PTPTSCR_TSSEME_Pos) > 0U) ? ENABLE : DISABLE;
  1384. ptpconfig->TimestampMaster = ((READ_BIT(heth->Instance->PTPTSCR,
  1385. ETH_PTPTSCR_TSSMRME) >> ETH_PTPTSCR_TSSMRME_Pos) > 0U) ? ENABLE : DISABLE;
  1386. ptpconfig->TimestampFilter = ((READ_BIT(heth->Instance->PTPTSCR,
  1387. ETH_PTPTSCR_TSPFFMAE) >> ETH_PTPTSCR_TSPFFMAE_Pos) > 0U) ? ENABLE : DISABLE;
  1388. ptpconfig->TimestampClockType = ((READ_BIT(heth->Instance->PTPTSCR,
  1389. ETH_PTPTSCR_TSCNT) >> ETH_PTPTSCR_TSCNT_Pos) > 0U) ? ENABLE : DISABLE;
  1390. /* Return function status */
  1391. return HAL_OK;
  1392. }
  1393. /**
  1394. * @brief Set Seconds and Nanoseconds for the Ethernet PTP registers.
  1395. * @param heth: pointer to a ETH_HandleTypeDef structure that contains
  1396. * the configuration information for ETHERNET module
  1397. * @param time: pointer to a ETH_TimeTypeDef structure that contains
  1398. * time to set
  1399. * @retval HAL status
  1400. */
  1401. HAL_StatusTypeDef HAL_ETH_PTP_SetTime(ETH_HandleTypeDef *heth, ETH_TimeTypeDef *time)
  1402. {
  1403. if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED)
  1404. {
  1405. /* Set Seconds */
  1406. heth->Instance->PTPTSHUR = time->Seconds;
  1407. /* Set NanoSeconds */
  1408. heth->Instance->PTPTSLUR = time->NanoSeconds;
  1409. /* the system time is updated */
  1410. SET_BIT(heth->Instance->PTPTSCR, ETH_PTPTSCR_TSSTU);
  1411. /* Return function status */
  1412. return HAL_OK;
  1413. }
  1414. else
  1415. {
  1416. /* Return function status */
  1417. return HAL_ERROR;
  1418. }
  1419. }
  1420. /**
  1421. * @brief Get Seconds and Nanoseconds for the Ethernet PTP registers.
  1422. * @param heth: pointer to a ETH_HandleTypeDef structure that contains
  1423. * the configuration information for ETHERNET module
  1424. * @param time: pointer to a ETH_TimeTypeDef structure that contains
  1425. * time to get
  1426. * @retval HAL status
  1427. */
  1428. HAL_StatusTypeDef HAL_ETH_PTP_GetTime(ETH_HandleTypeDef *heth, ETH_TimeTypeDef *time)
  1429. {
  1430. if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED)
  1431. {
  1432. /* Get Seconds */
  1433. time->Seconds = heth->Instance->PTPTSHR;
  1434. /* Get NanoSeconds */
  1435. time->NanoSeconds = heth->Instance->PTPTSLR;
  1436. /* Return function status */
  1437. return HAL_OK;
  1438. }
  1439. else
  1440. {
  1441. /* Return function status */
  1442. return HAL_ERROR;
  1443. }
  1444. }
  1445. /**
  1446. * @brief Update time for the Ethernet PTP registers.
  1447. * @param heth: pointer to a ETH_HandleTypeDef structure that contains
  1448. * the configuration information for ETHERNET module
  1449. * @param timeoffset: pointer to a ETH_PtpUpdateTypeDef structure that contains
  1450. * the time update information
  1451. * @retval HAL status
  1452. */
  1453. HAL_StatusTypeDef HAL_ETH_PTP_AddTimeOffset(ETH_HandleTypeDef *heth, ETH_PtpUpdateTypeDef ptpoffsettype,
  1454. ETH_TimeTypeDef *timeoffset)
  1455. {
  1456. int32_t addendtime ;
  1457. if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED)
  1458. {
  1459. if (ptpoffsettype == HAL_ETH_PTP_NEGATIVE_UPDATE)
  1460. {
  1461. /* Set Seconds update */
  1462. heth->Instance->PTPTSHUR = ETH_PTPTSHR_VALUE - timeoffset->Seconds + 1U;
  1463. if (READ_BIT(heth->Instance->PTPTSCR, ETH_PTPTSCR_TSSSR) == ETH_PTPTSCR_TSSSR)
  1464. {
  1465. /* Set nanoSeconds update */
  1466. heth->Instance->PTPTSLUR = ETH_PTPTSLR_VALUE - timeoffset->NanoSeconds;
  1467. }
  1468. else
  1469. {
  1470. heth->Instance->PTPTSLUR = ETH_PTPTSHR_VALUE - timeoffset->NanoSeconds + 1U;
  1471. }
  1472. /* adjust negative addend register */
  1473. addendtime = - timeoffset->NanoSeconds;
  1474. HAL_ETH_PTP_AddendUpdate(heth, addendtime);
  1475. }
  1476. else
  1477. {
  1478. /* Set Seconds update */
  1479. heth->Instance->PTPTSHUR = timeoffset->Seconds;
  1480. /* Set nanoSeconds update */
  1481. heth->Instance->PTPTSLUR = timeoffset->NanoSeconds;
  1482. /* adjust positive addend register */
  1483. addendtime = timeoffset->NanoSeconds;
  1484. HAL_ETH_PTP_AddendUpdate(heth, addendtime);
  1485. }
  1486. SET_BIT(heth->Instance->PTPTSCR, ETH_PTPTSCR_TSSTU);
  1487. /* Return function status */
  1488. return HAL_OK;
  1489. }
  1490. else
  1491. {
  1492. /* Return function status */
  1493. return HAL_ERROR;
  1494. }
  1495. }
  1496. /**
  1497. * @brief Update the Addend register
  1498. * @param heth: Pointer to a ETH_HandleTypeDef structure that contains
  1499. * the configuration information for ETHERNET module
  1500. * @param timeoffset: The value of the time offset to be added to
  1501. * the addend register in Nanoseconds
  1502. * @retval HAL status
  1503. */
  1504. static HAL_StatusTypeDef HAL_ETH_PTP_AddendUpdate(ETH_HandleTypeDef *heth, int32_t timeoffset)
  1505. {
  1506. uint32_t tmpreg;
  1507. if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED)
  1508. {
  1509. /* update the addend register */
  1510. tmpreg = READ_REG(heth->Instance->PTPTSAR);
  1511. tmpreg += timeoffset ;
  1512. WRITE_REG(heth->Instance->PTPTSAR, tmpreg);
  1513. SET_BIT(heth->Instance->PTPTSCR, ETH_PTPTSCR_TSARU);
  1514. while ((heth->Instance->PTPTSCR & ETH_PTPTSCR_TSARU) != 0)
  1515. {
  1516. }
  1517. /* Return function status */
  1518. return HAL_OK;
  1519. }
  1520. else
  1521. {
  1522. /* Return function status */
  1523. return HAL_ERROR;
  1524. }
  1525. }
  1526. /**
  1527. * @brief Insert Timestamp in transmission.
  1528. * @param heth: pointer to a ETH_HandleTypeDef structure that contains
  1529. * the configuration information for ETHERNET module
  1530. * @retval HAL status
  1531. */
  1532. HAL_StatusTypeDef HAL_ETH_PTP_InsertTxTimestamp(ETH_HandleTypeDef *heth)
  1533. {
  1534. ETH_TxDescListTypeDef *dmatxdesclist = &heth->TxDescList;
  1535. uint32_t descidx = dmatxdesclist->CurTxDesc;
  1536. ETH_DMADescTypeDef *dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx];
  1537. if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED)
  1538. {
  1539. /* Enable Time Stamp transmission */
  1540. SET_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_TTSE);
  1541. /* Return function status */
  1542. return HAL_OK;
  1543. }
  1544. else
  1545. {
  1546. /* Return function status */
  1547. return HAL_ERROR;
  1548. }
  1549. }
  1550. /**
  1551. * @brief Get transmission timestamp.
  1552. * @param heth: pointer to a ETH_HandleTypeDef structure that contains
  1553. * the configuration information for ETHERNET module
  1554. * @param timestamp: pointer to ETH_TIMESTAMPTypeDef structure that contains
  1555. * transmission timestamp
  1556. * @retval HAL status
  1557. */
  1558. HAL_StatusTypeDef HAL_ETH_PTP_GetTxTimestamp(ETH_HandleTypeDef *heth, ETH_TimeStampTypeDef *timestamp)
  1559. {
  1560. ETH_TxDescListTypeDef *dmatxdesclist = &heth->TxDescList;
  1561. uint32_t idx = dmatxdesclist->releaseIndex;
  1562. ETH_DMADescTypeDef *dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[idx];
  1563. if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED)
  1564. {
  1565. /* Get timestamp low */
  1566. timestamp->TimeStampLow = dmatxdesc->DESC0;
  1567. /* Get timestamp high */
  1568. timestamp->TimeStampHigh = dmatxdesc->DESC1;
  1569. /* Return function status */
  1570. return HAL_OK;
  1571. }
  1572. else
  1573. {
  1574. /* Return function status */
  1575. return HAL_ERROR;
  1576. }
  1577. }
  1578. /**
  1579. * @brief Get receive timestamp.
  1580. * @param heth: pointer to a ETH_HandleTypeDef structure that contains
  1581. * the configuration information for ETHERNET module
  1582. * @param timestamp: pointer to ETH_TIMESTAMPTypeDef structure that contains
  1583. * receive timestamp
  1584. * @retval HAL status
  1585. */
  1586. HAL_StatusTypeDef HAL_ETH_PTP_GetRxTimestamp(ETH_HandleTypeDef *heth, ETH_TimeStampTypeDef *timestamp)
  1587. {
  1588. if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED)
  1589. {
  1590. /* Get timestamp low */
  1591. timestamp->TimeStampLow = heth->RxDescList.TimeStamp.TimeStampLow;
  1592. /* Get timestamp high */
  1593. timestamp->TimeStampHigh = heth->RxDescList.TimeStamp.TimeStampHigh;
  1594. /* Return function status */
  1595. return HAL_OK;
  1596. }
  1597. else
  1598. {
  1599. /* Return function status */
  1600. return HAL_ERROR;
  1601. }
  1602. }
  1603. /**
  1604. * @brief Register the Tx Ptp callback.
  1605. * @param heth: pointer to a ETH_HandleTypeDef structure that contains
  1606. * the configuration information for ETHERNET module
  1607. * @param txPtpCallback: Function to handle Ptp transmission
  1608. * @retval HAL status
  1609. */
  1610. HAL_StatusTypeDef HAL_ETH_RegisterTxPtpCallback(ETH_HandleTypeDef *heth, pETH_txPtpCallbackTypeDef txPtpCallback)
  1611. {
  1612. if (txPtpCallback == NULL)
  1613. {
  1614. /* No buffer to save */
  1615. return HAL_ERROR;
  1616. }
  1617. /* Set Function to handle Tx Ptp */
  1618. heth->txPtpCallback = txPtpCallback;
  1619. return HAL_OK;
  1620. }
  1621. /**
  1622. * @brief Unregister the Tx Ptp callback.
  1623. * @param heth: pointer to a ETH_HandleTypeDef structure that contains
  1624. * the configuration information for ETHERNET module
  1625. * @retval HAL status
  1626. */
  1627. HAL_StatusTypeDef HAL_ETH_UnRegisterTxPtpCallback(ETH_HandleTypeDef *heth)
  1628. {
  1629. /* Set function to allocate buffer */
  1630. heth->txPtpCallback = HAL_ETH_TxPtpCallback;
  1631. return HAL_OK;
  1632. }
  1633. /**
  1634. * @brief Tx Ptp callback.
  1635. * @param buff: pointer to application buffer
  1636. * @param timestamp: pointer to ETH_TimeStampTypeDef structure that contains
  1637. * transmission timestamp
  1638. * @retval None
  1639. */
  1640. __weak void HAL_ETH_TxPtpCallback(uint32_t *buff, ETH_TimeStampTypeDef *timestamp)
  1641. {
  1642. /* Prevent unused argument(s) compilation warning */
  1643. UNUSED(buff);
  1644. /* NOTE : This function Should not be modified, when the callback is needed,
  1645. the HAL_ETH_TxPtpCallback could be implemented in the user file
  1646. */
  1647. }
  1648. #endif /* HAL_ETH_USE_PTP */
  1649. /**
  1650. * @brief This function handles ETH interrupt request.
  1651. * @param heth: pointer to a ETH_HandleTypeDef structure that contains
  1652. * the configuration information for ETHERNET module
  1653. * @retval HAL status
  1654. */
  1655. void HAL_ETH_IRQHandler(ETH_HandleTypeDef *heth)
  1656. {
  1657. uint32_t mac_flag = READ_REG(heth->Instance->MACSR);
  1658. uint32_t dma_flag = READ_REG(heth->Instance->DMASR);
  1659. uint32_t dma_itsource = READ_REG(heth->Instance->DMAIER);
  1660. uint32_t exti_flag = READ_REG(EXTI->PR);
  1661. /* Packet received */
  1662. if (((dma_flag & ETH_DMASR_RS) != 0U) && ((dma_itsource & ETH_DMAIER_RIE) != 0U))
  1663. {
  1664. /* Clear the Eth DMA Rx IT pending bits */
  1665. __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMASR_RS | ETH_DMASR_NIS);
  1666. #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
  1667. /*Call registered Receive complete callback*/
  1668. heth->RxCpltCallback(heth);
  1669. #else
  1670. /* Receive complete callback */
  1671. HAL_ETH_RxCpltCallback(heth);
  1672. #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
  1673. }
  1674. /* Packet transmitted */
  1675. if (((dma_flag & ETH_DMASR_TS) != 0U) && ((dma_itsource & ETH_DMAIER_TIE) != 0U))
  1676. {
  1677. /* Clear the Eth DMA Tx IT pending bits */
  1678. __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMASR_TS | ETH_DMASR_NIS);
  1679. #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
  1680. /*Call registered Transmit complete callback*/
  1681. heth->TxCpltCallback(heth);
  1682. #else
  1683. /* Transfer complete callback */
  1684. HAL_ETH_TxCpltCallback(heth);
  1685. #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
  1686. }
  1687. /* ETH DMA Error */
  1688. if (((dma_flag & ETH_DMASR_AIS) != 0U) && ((dma_itsource & ETH_DMAIER_AISE) != 0U))
  1689. {
  1690. heth->ErrorCode |= HAL_ETH_ERROR_DMA;
  1691. /* if fatal bus error occurred */
  1692. if ((dma_flag & ETH_DMASR_FBES) != 0U)
  1693. {
  1694. /* Get DMA error code */
  1695. heth->DMAErrorCode = READ_BIT(heth->Instance->DMASR, (ETH_DMASR_FBES | ETH_DMASR_TPS | ETH_DMASR_RPS));
  1696. /* Disable all interrupts */
  1697. __HAL_ETH_DMA_DISABLE_IT(heth, ETH_DMAIER_NISE | ETH_DMAIER_AISE);
  1698. /* Set HAL state to ERROR */
  1699. heth->gState = HAL_ETH_STATE_ERROR;
  1700. }
  1701. else
  1702. {
  1703. /* Get DMA error status */
  1704. heth->DMAErrorCode = READ_BIT(heth->Instance->DMASR, (ETH_DMASR_ETS | ETH_DMASR_RWTS |
  1705. ETH_DMASR_RBUS | ETH_DMASR_AIS));
  1706. /* Clear the interrupt summary flag */
  1707. __HAL_ETH_DMA_CLEAR_IT(heth, (ETH_DMASR_ETS | ETH_DMASR_RWTS |
  1708. ETH_DMASR_RBUS | ETH_DMASR_AIS));
  1709. }
  1710. #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
  1711. /* Call registered Error callback*/
  1712. heth->ErrorCallback(heth);
  1713. #else
  1714. /* Ethernet DMA Error callback */
  1715. HAL_ETH_ErrorCallback(heth);
  1716. #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
  1717. }
  1718. /* ETH PMT IT */
  1719. if ((mac_flag & ETH_MAC_PMT_IT) != 0U)
  1720. {
  1721. /* Get MAC Wake-up source and clear the status register pending bit */
  1722. heth->MACWakeUpEvent = READ_BIT(heth->Instance->MACPMTCSR, (ETH_MACPMTCSR_WFR | ETH_MACPMTCSR_MPR));
  1723. #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
  1724. /* Call registered PMT callback*/
  1725. heth->PMTCallback(heth);
  1726. #else
  1727. /* Ethernet PMT callback */
  1728. HAL_ETH_PMTCallback(heth);
  1729. #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
  1730. heth->MACWakeUpEvent = (uint32_t)(0x0U);
  1731. }
  1732. /* check ETH WAKEUP exti flag */
  1733. if ((exti_flag & ETH_WAKEUP_EXTI_LINE) != 0U)
  1734. {
  1735. /* Clear ETH WAKEUP Exti pending bit */
  1736. __HAL_ETH_WAKEUP_EXTI_CLEAR_FLAG(ETH_WAKEUP_EXTI_LINE);
  1737. #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
  1738. /* Call registered WakeUp callback*/
  1739. heth->WakeUpCallback(heth);
  1740. #else
  1741. /* ETH WAKEUP callback */
  1742. HAL_ETH_WakeUpCallback(heth);
  1743. #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
  1744. }
  1745. }
  1746. /**
  1747. * @brief Tx Transfer completed callbacks.
  1748. * @param heth: pointer to a ETH_HandleTypeDef structure that contains
  1749. * the configuration information for ETHERNET module
  1750. * @retval None
  1751. */
  1752. __weak void HAL_ETH_TxCpltCallback(ETH_HandleTypeDef *heth)
  1753. {
  1754. /* Prevent unused argument(s) compilation warning */
  1755. UNUSED(heth);
  1756. /* NOTE : This function Should not be modified, when the callback is needed,
  1757. the HAL_ETH_TxCpltCallback could be implemented in the user file
  1758. */
  1759. }
  1760. /**
  1761. * @brief Rx Transfer completed callbacks.
  1762. * @param heth: pointer to a ETH_HandleTypeDef structure that contains
  1763. * the configuration information for ETHERNET module
  1764. * @retval None
  1765. */
  1766. __weak void HAL_ETH_RxCpltCallback(ETH_HandleTypeDef *heth)
  1767. {
  1768. /* Prevent unused argument(s) compilation warning */
  1769. UNUSED(heth);
  1770. /* NOTE : This function Should not be modified, when the callback is needed,
  1771. the HAL_ETH_RxCpltCallback could be implemented in the user file
  1772. */
  1773. }
  1774. /**
  1775. * @brief Ethernet transfer error callbacks
  1776. * @param heth: pointer to a ETH_HandleTypeDef structure that contains
  1777. * the configuration information for ETHERNET module
  1778. * @retval None
  1779. */
  1780. __weak void HAL_ETH_ErrorCallback(ETH_HandleTypeDef *heth)
  1781. {
  1782. /* Prevent unused argument(s) compilation warning */
  1783. UNUSED(heth);
  1784. /* NOTE : This function Should not be modified, when the callback is needed,
  1785. the HAL_ETH_ErrorCallback could be implemented in the user file
  1786. */
  1787. }
  1788. /**
  1789. * @brief Ethernet Power Management module IT callback
  1790. * @param heth: pointer to a ETH_HandleTypeDef structure that contains
  1791. * the configuration information for ETHERNET module
  1792. * @retval None
  1793. */
  1794. __weak void HAL_ETH_PMTCallback(ETH_HandleTypeDef *heth)
  1795. {
  1796. /* Prevent unused argument(s) compilation warning */
  1797. UNUSED(heth);
  1798. /* NOTE : This function Should not be modified, when the callback is needed,
  1799. the HAL_ETH_PMTCallback could be implemented in the user file
  1800. */
  1801. }
  1802. /**
  1803. * @brief ETH WAKEUP interrupt callback
  1804. * @param heth: pointer to a ETH_HandleTypeDef structure that contains
  1805. * the configuration information for ETHERNET module
  1806. * @retval None
  1807. */
  1808. __weak void HAL_ETH_WakeUpCallback(ETH_HandleTypeDef *heth)
  1809. {
  1810. /* Prevent unused argument(s) compilation warning */
  1811. UNUSED(heth);
  1812. /* NOTE : This function Should not be modified, when the callback is needed,
  1813. the HAL_ETH_WakeUpCallback could be implemented in the user file
  1814. */
  1815. }
  1816. /**
  1817. * @brief Read a PHY register
  1818. * @param heth: pointer to a ETH_HandleTypeDef structure that contains
  1819. * the configuration information for ETHERNET module
  1820. * @param PHYAddr: PHY port address, must be a value from 0 to 31
  1821. * @param PHYReg: PHY register address, must be a value from 0 to 31
  1822. * @param pRegValue: parameter to hold read value
  1823. * @retval HAL status
  1824. */
  1825. HAL_StatusTypeDef HAL_ETH_ReadPHYRegister(ETH_HandleTypeDef *heth, uint32_t PHYAddr, uint32_t PHYReg,
  1826. uint32_t *pRegValue)
  1827. {
  1828. uint32_t tmpreg1;
  1829. uint32_t tickstart;
  1830. /* Get the ETHERNET MACMIIAR value */
  1831. tmpreg1 = heth->Instance->MACMIIAR;
  1832. /* Keep only the CSR Clock Range CR[2:0] bits value */
  1833. tmpreg1 &= ~ETH_MACMIIAR_CR_MASK;
  1834. /* Prepare the MII address register value */
  1835. tmpreg1 |= ((PHYAddr << 11U) & ETH_MACMIIAR_PA); /* Set the PHY device address */
  1836. tmpreg1 |= (((uint32_t)PHYReg << 6U) & ETH_MACMIIAR_MR); /* Set the PHY register address */
  1837. tmpreg1 &= ~ETH_MACMIIAR_MW; /* Set the read mode */
  1838. tmpreg1 |= ETH_MACMIIAR_MB; /* Set the MII Busy bit */
  1839. /* Write the result value into the MII Address register */
  1840. heth->Instance->MACMIIAR = tmpreg1;
  1841. tickstart = HAL_GetTick();
  1842. /* Check for the Busy flag */
  1843. while ((tmpreg1 & ETH_MACMIIAR_MB) == ETH_MACMIIAR_MB)
  1844. {
  1845. /* Check for the Timeout */
  1846. if ((HAL_GetTick() - tickstart) > PHY_READ_TO)
  1847. {
  1848. return HAL_ERROR;
  1849. }
  1850. tmpreg1 = heth->Instance->MACMIIAR;
  1851. }
  1852. /* Get MACMIIDR value */
  1853. *pRegValue = (uint16_t)(heth->Instance->MACMIIDR);
  1854. return HAL_OK;
  1855. }
  1856. /**
  1857. * @brief Writes to a PHY register.
  1858. * @param heth: pointer to a ETH_HandleTypeDef structure that contains
  1859. * the configuration information for ETHERNET module
  1860. * @param PHYAddr: PHY port address, must be a value from 0 to 31
  1861. * @param PHYReg: PHY register address, must be a value from 0 to 31
  1862. * @param RegValue: the value to write
  1863. * @retval HAL status
  1864. */
  1865. HAL_StatusTypeDef HAL_ETH_WritePHYRegister(const ETH_HandleTypeDef *heth, uint32_t PHYAddr, uint32_t PHYReg,
  1866. uint32_t RegValue)
  1867. {
  1868. uint32_t tmpreg1;
  1869. uint32_t tickstart;
  1870. /* Get the ETHERNET MACMIIAR value */
  1871. tmpreg1 = heth->Instance->MACMIIAR;
  1872. /* Keep only the CSR Clock Range CR[2:0] bits value */
  1873. tmpreg1 &= ~ETH_MACMIIAR_CR_MASK;
  1874. /* Prepare the MII register address value */
  1875. tmpreg1 |= ((PHYAddr << 11U) & ETH_MACMIIAR_PA); /* Set the PHY device address */
  1876. tmpreg1 |= (((uint32_t)PHYReg << 6U) & ETH_MACMIIAR_MR); /* Set the PHY register address */
  1877. tmpreg1 |= ETH_MACMIIAR_MW; /* Set the write mode */
  1878. tmpreg1 |= ETH_MACMIIAR_MB; /* Set the MII Busy bit */
  1879. /* Give the value to the MII data register */
  1880. heth->Instance->MACMIIDR = (uint16_t)RegValue;
  1881. /* Write the result value into the MII Address register */
  1882. heth->Instance->MACMIIAR = tmpreg1;
  1883. /* Get tick */
  1884. tickstart = HAL_GetTick();
  1885. /* Check for the Busy flag */
  1886. while ((tmpreg1 & ETH_MACMIIAR_MB) == ETH_MACMIIAR_MB)
  1887. {
  1888. /* Check for the Timeout */
  1889. if ((HAL_GetTick() - tickstart) > PHY_WRITE_TO)
  1890. {
  1891. return HAL_ERROR;
  1892. }
  1893. tmpreg1 = heth->Instance->MACMIIAR;
  1894. }
  1895. return HAL_OK;
  1896. }
  1897. /**
  1898. * @}
  1899. */
  1900. /** @defgroup ETH_Exported_Functions_Group3 Peripheral Control functions
  1901. * @brief ETH control functions
  1902. *
  1903. @verbatim
  1904. ==============================================================================
  1905. ##### Peripheral Control functions #####
  1906. ==============================================================================
  1907. [..]
  1908. This subsection provides a set of functions allowing to control the ETH
  1909. peripheral.
  1910. @endverbatim
  1911. * @{
  1912. */
  1913. /**
  1914. * @brief Get the configuration of the MAC and MTL subsystems.
  1915. * @param heth: pointer to a ETH_HandleTypeDef structure that contains
  1916. * the configuration information for ETHERNET module
  1917. * @param macconf: pointer to a ETH_MACConfigTypeDef structure that will hold
  1918. * the configuration of the MAC.
  1919. * @retval HAL Status
  1920. */
  1921. HAL_StatusTypeDef HAL_ETH_GetMACConfig(const ETH_HandleTypeDef *heth, ETH_MACConfigTypeDef *macconf)
  1922. {
  1923. if (macconf == NULL)
  1924. {
  1925. return HAL_ERROR;
  1926. }
  1927. /* Get MAC parameters */
  1928. macconf->DeferralCheck = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_DC) >> 4) > 0U) ? ENABLE : DISABLE;
  1929. macconf->BackOffLimit = READ_BIT(heth->Instance->MACCR, ETH_MACCR_BL);
  1930. macconf->RetryTransmission = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_RD) >> 9) == 0U) ? ENABLE : DISABLE;
  1931. macconf->CarrierSenseDuringTransmit = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_CSD) >> 16) > 0U)
  1932. ? ENABLE : DISABLE;
  1933. macconf->ReceiveOwn = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_ROD) >> 13) == 0U) ? ENABLE : DISABLE;
  1934. macconf->LoopbackMode = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_LM) >> 12) > 0U) ? ENABLE : DISABLE;
  1935. macconf->DuplexMode = READ_BIT(heth->Instance->MACCR, ETH_MACCR_DM);
  1936. macconf->Speed = READ_BIT(heth->Instance->MACCR, ETH_MACCR_FES);
  1937. macconf->Jabber = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_JD) >> 22) == 0U) ? ENABLE : DISABLE;
  1938. macconf->Watchdog = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_WD) >> 23) == 0U) ? ENABLE : DISABLE;
  1939. macconf->AutomaticPadCRCStrip = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_APCS) >> 7) > 0U) ? ENABLE : DISABLE;
  1940. macconf->InterPacketGapVal = READ_BIT(heth->Instance->MACCR, ETH_MACCR_IFG);
  1941. macconf->ChecksumOffload = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_IPCO) >> 10U) > 0U) ? ENABLE : DISABLE;
  1942. macconf->CRCStripTypePacket = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_CSTF) >> 25U) > 0U) ? ENABLE : DISABLE;
  1943. macconf->TransmitFlowControl = ((READ_BIT(heth->Instance->MACFCR, ETH_MACFCR_TFCE) >> 1) > 0U) ? ENABLE : DISABLE;
  1944. macconf->ZeroQuantaPause = ((READ_BIT(heth->Instance->MACFCR, ETH_MACFCR_ZQPD) >> 7) == 0U) ? ENABLE : DISABLE;
  1945. macconf->PauseLowThreshold = READ_BIT(heth->Instance->MACFCR, ETH_MACFCR_PLT);
  1946. macconf->PauseTime = (READ_BIT(heth->Instance->MACFCR, ETH_MACFCR_PT) >> 16);
  1947. macconf->ReceiveFlowControl = ((READ_BIT(heth->Instance->MACFCR, ETH_MACFCR_RFCE) >> 2U) > 0U) ? ENABLE : DISABLE;
  1948. macconf->UnicastPausePacketDetect = ((READ_BIT(heth->Instance->MACFCR, ETH_MACFCR_UPFD) >> 3U) > 0U)
  1949. ? ENABLE : DISABLE;
  1950. return HAL_OK;
  1951. }
  1952. /**
  1953. * @brief Get the configuration of the DMA.
  1954. * @param heth: pointer to a ETH_HandleTypeDef structure that contains
  1955. * the configuration information for ETHERNET module
  1956. * @param dmaconf: pointer to a ETH_DMAConfigTypeDef structure that will hold
  1957. * the configuration of the ETH DMA.
  1958. * @retval HAL Status
  1959. */
  1960. HAL_StatusTypeDef HAL_ETH_GetDMAConfig(const ETH_HandleTypeDef *heth, ETH_DMAConfigTypeDef *dmaconf)
  1961. {
  1962. if (dmaconf == NULL)
  1963. {
  1964. return HAL_ERROR;
  1965. }
  1966. dmaconf->DMAArbitration = READ_BIT(heth->Instance->DMABMR,
  1967. (ETH_DMAARBITRATION_RXPRIORTX | ETH_DMAARBITRATION_ROUNDROBIN_RXTX_4_1));
  1968. dmaconf->AddressAlignedBeats = ((READ_BIT(heth->Instance->DMABMR, ETH_DMABMR_AAB) >> 25U) > 0U) ? ENABLE : DISABLE;
  1969. dmaconf->BurstMode = READ_BIT(heth->Instance->DMABMR, ETH_DMABMR_FB | ETH_DMABMR_MB);
  1970. dmaconf->RxDMABurstLength = READ_BIT(heth->Instance->DMABMR, ETH_DMABMR_RDP);
  1971. dmaconf->TxDMABurstLength = READ_BIT(heth->Instance->DMABMR, ETH_DMABMR_PBL);
  1972. dmaconf->EnhancedDescriptorFormat = ((READ_BIT(heth->Instance->DMABMR, ETH_DMABMR_EDE) >> 7) > 0U) ? ENABLE : DISABLE;
  1973. dmaconf->DescriptorSkipLength = READ_BIT(heth->Instance->DMABMR, ETH_DMABMR_DSL) >> 2;
  1974. dmaconf->DropTCPIPChecksumErrorFrame = ((READ_BIT(heth->Instance->DMAOMR,
  1975. ETH_DMAOMR_DTCEFD) >> 26) > 0U) ? DISABLE : ENABLE;
  1976. dmaconf->ReceiveStoreForward = ((READ_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_RSF) >> 25) > 0U) ? ENABLE : DISABLE;
  1977. dmaconf->FlushRxPacket = ((READ_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_FTF) >> 20) > 0U) ? DISABLE : ENABLE;
  1978. dmaconf->TransmitStoreForward = ((READ_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_TSF) >> 21) > 0U) ? ENABLE : DISABLE;
  1979. dmaconf->TransmitThresholdControl = READ_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_TTC);
  1980. dmaconf->ForwardErrorFrames = ((READ_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_FEF) >> 7) > 0U) ? ENABLE : DISABLE;
  1981. dmaconf->ForwardUndersizedGoodFrames = ((READ_BIT(heth->Instance->DMAOMR,
  1982. ETH_DMAOMR_FUGF) >> 6) > 0U) ? ENABLE : DISABLE;
  1983. dmaconf->ReceiveThresholdControl = READ_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_RTC);
  1984. dmaconf->SecondFrameOperate = ((READ_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_OSF) >> 2) > 0U) ? ENABLE : DISABLE;
  1985. return HAL_OK;
  1986. }
  1987. /**
  1988. * @brief Set the MAC configuration.
  1989. * @param heth: pointer to a ETH_HandleTypeDef structure that contains
  1990. * the configuration information for ETHERNET module
  1991. * @param macconf: pointer to a ETH_MACConfigTypeDef structure that contains
  1992. * the configuration of the MAC.
  1993. * @retval HAL status
  1994. */
  1995. HAL_StatusTypeDef HAL_ETH_SetMACConfig(ETH_HandleTypeDef *heth, ETH_MACConfigTypeDef *macconf)
  1996. {
  1997. if (macconf == NULL)
  1998. {
  1999. return HAL_ERROR;
  2000. }
  2001. if (heth->gState == HAL_ETH_STATE_READY)
  2002. {
  2003. ETH_SetMACConfig(heth, macconf);
  2004. return HAL_OK;
  2005. }
  2006. else
  2007. {
  2008. return HAL_ERROR;
  2009. }
  2010. }
  2011. /**
  2012. * @brief Set the ETH DMA configuration.
  2013. * @param heth: pointer to a ETH_HandleTypeDef structure that contains
  2014. * the configuration information for ETHERNET module
  2015. * @param dmaconf: pointer to a ETH_DMAConfigTypeDef structure that will hold
  2016. * the configuration of the ETH DMA.
  2017. * @retval HAL status
  2018. */
  2019. HAL_StatusTypeDef HAL_ETH_SetDMAConfig(ETH_HandleTypeDef *heth, ETH_DMAConfigTypeDef *dmaconf)
  2020. {
  2021. if (dmaconf == NULL)
  2022. {
  2023. return HAL_ERROR;
  2024. }
  2025. if (heth->gState == HAL_ETH_STATE_READY)
  2026. {
  2027. ETH_SetDMAConfig(heth, dmaconf);
  2028. return HAL_OK;
  2029. }
  2030. else
  2031. {
  2032. return HAL_ERROR;
  2033. }
  2034. }
  2035. /**
  2036. * @brief Configures the Clock range of ETH MDIO interface.
  2037. * @param heth: pointer to a ETH_HandleTypeDef structure that contains
  2038. * the configuration information for ETHERNET module
  2039. * @retval None
  2040. */
  2041. void HAL_ETH_SetMDIOClockRange(ETH_HandleTypeDef *heth)
  2042. {
  2043. uint32_t hclk;
  2044. uint32_t tmpreg;
  2045. /* Get the ETHERNET MACMIIAR value */
  2046. tmpreg = (heth->Instance)->MACMIIAR;
  2047. /* Clear CSR Clock Range CR[2:0] bits */
  2048. tmpreg &= ETH_MACMIIAR_CR_MASK;
  2049. /* Get hclk frequency value */
  2050. hclk = HAL_RCC_GetHCLKFreq();
  2051. /* Set CR bits depending on hclk value */
  2052. if (hclk < 35000000U)
  2053. {
  2054. /* CSR Clock Range between 0-35 MHz */
  2055. tmpreg |= (uint32_t)ETH_MACMIIAR_CR_Div16;
  2056. }
  2057. else if (hclk < 60000000U)
  2058. {
  2059. /* CSR Clock Range between 35-60 MHz */
  2060. tmpreg |= (uint32_t)ETH_MACMIIAR_CR_Div26;
  2061. }
  2062. else if (hclk < 100000000U)
  2063. {
  2064. /* CSR Clock Range between 60-100 MHz */
  2065. tmpreg |= (uint32_t)ETH_MACMIIAR_CR_Div42;
  2066. }
  2067. else if (hclk < 150000000U)
  2068. {
  2069. /* CSR Clock Range between 100-150 MHz */
  2070. tmpreg |= (uint32_t)ETH_MACMIIAR_CR_Div62;
  2071. }
  2072. else /* (hclk >= 150000000) */
  2073. {
  2074. /* CSR Clock >= 150 MHz */
  2075. tmpreg |= (uint32_t)ETH_MACMIIAR_CR_Div102;
  2076. }
  2077. /* Write to ETHERNET MAC MIIAR: Configure the ETHERNET CSR Clock Range */
  2078. (heth->Instance)->MACMIIAR = (uint32_t)tmpreg;
  2079. }
  2080. /**
  2081. * @brief Set the ETH MAC (L2) Filters configuration.
  2082. * @param heth: pointer to a ETH_HandleTypeDef structure that contains
  2083. * the configuration information for ETHERNET module
  2084. * @param pFilterConfig: pointer to a ETH_MACFilterConfigTypeDef structure that contains
  2085. * the configuration of the ETH MAC filters.
  2086. * @retval HAL status
  2087. */
  2088. HAL_StatusTypeDef HAL_ETH_SetMACFilterConfig(ETH_HandleTypeDef *heth, const ETH_MACFilterConfigTypeDef *pFilterConfig)
  2089. {
  2090. uint32_t filterconfig;
  2091. uint32_t tmpreg1;
  2092. if (pFilterConfig == NULL)
  2093. {
  2094. return HAL_ERROR;
  2095. }
  2096. filterconfig = ((uint32_t)pFilterConfig->PromiscuousMode |
  2097. ((uint32_t)pFilterConfig->HashUnicast << 1) |
  2098. ((uint32_t)pFilterConfig->HashMulticast << 2) |
  2099. ((uint32_t)pFilterConfig->DestAddrInverseFiltering << 3) |
  2100. ((uint32_t)pFilterConfig->PassAllMulticast << 4) |
  2101. ((uint32_t)((pFilterConfig->BroadcastFilter == ENABLE) ? 1U : 0U) << 5) |
  2102. ((uint32_t)pFilterConfig->SrcAddrInverseFiltering << 8) |
  2103. ((uint32_t)pFilterConfig->SrcAddrFiltering << 9) |
  2104. ((uint32_t)pFilterConfig->HachOrPerfectFilter << 10) |
  2105. ((uint32_t)pFilterConfig->ReceiveAllMode << 31) |
  2106. pFilterConfig->ControlPacketsFilter);
  2107. MODIFY_REG(heth->Instance->MACFFR, ETH_MACFFR_MASK, filterconfig);
  2108. /* Wait until the write operation will be taken into account :
  2109. at least four TX_CLK/RX_CLK clock cycles */
  2110. tmpreg1 = (heth->Instance)->MACFFR;
  2111. HAL_Delay(ETH_REG_WRITE_DELAY);
  2112. (heth->Instance)->MACFFR = tmpreg1;
  2113. return HAL_OK;
  2114. }
  2115. /**
  2116. * @brief Get the ETH MAC (L2) Filters configuration.
  2117. * @param heth: pointer to a ETH_HandleTypeDef structure that contains
  2118. * the configuration information for ETHERNET module
  2119. * @param pFilterConfig: pointer to a ETH_MACFilterConfigTypeDef structure that will hold
  2120. * the configuration of the ETH MAC filters.
  2121. * @retval HAL status
  2122. */
  2123. HAL_StatusTypeDef HAL_ETH_GetMACFilterConfig(const ETH_HandleTypeDef *heth, ETH_MACFilterConfigTypeDef *pFilterConfig)
  2124. {
  2125. if (pFilterConfig == NULL)
  2126. {
  2127. return HAL_ERROR;
  2128. }
  2129. pFilterConfig->PromiscuousMode = ((READ_BIT(heth->Instance->MACFFR, ETH_MACFFR_PM)) > 0U) ? ENABLE : DISABLE;
  2130. pFilterConfig->HashUnicast = ((READ_BIT(heth->Instance->MACFFR, ETH_MACFFR_HU) >> 1) > 0U) ? ENABLE : DISABLE;
  2131. pFilterConfig->HashMulticast = ((READ_BIT(heth->Instance->MACFFR, ETH_MACFFR_HM) >> 2) > 0U) ? ENABLE : DISABLE;
  2132. pFilterConfig->DestAddrInverseFiltering = ((READ_BIT(heth->Instance->MACFFR,
  2133. ETH_MACFFR_DAIF) >> 3) > 0U) ? ENABLE : DISABLE;
  2134. pFilterConfig->PassAllMulticast = ((READ_BIT(heth->Instance->MACFFR, ETH_MACFFR_PAM) >> 4) > 0U) ? ENABLE : DISABLE;
  2135. pFilterConfig->BroadcastFilter = ((READ_BIT(heth->Instance->MACFFR, ETH_MACFFR_BFD) >> 5) > 0U) ? ENABLE : DISABLE;
  2136. pFilterConfig->ControlPacketsFilter = READ_BIT(heth->Instance->MACFFR, ETH_MACFFR_PCF);
  2137. pFilterConfig->SrcAddrInverseFiltering = ((READ_BIT(heth->Instance->MACFFR,
  2138. ETH_MACFFR_SAIF) >> 8) > 0U) ? ENABLE : DISABLE;
  2139. pFilterConfig->SrcAddrFiltering = ((READ_BIT(heth->Instance->MACFFR, ETH_MACFFR_SAF) >> 9) > 0U) ? ENABLE : DISABLE;
  2140. pFilterConfig->HachOrPerfectFilter = ((READ_BIT(heth->Instance->MACFFR, ETH_MACFFR_HPF) >> 10) > 0U)
  2141. ? ENABLE : DISABLE;
  2142. pFilterConfig->ReceiveAllMode = ((READ_BIT(heth->Instance->MACFFR, ETH_MACFFR_RA) >> 31) > 0U) ? ENABLE : DISABLE;
  2143. return HAL_OK;
  2144. }
  2145. /**
  2146. * @brief Set the source MAC Address to be matched.
  2147. * @param heth: pointer to a ETH_HandleTypeDef structure that contains
  2148. * the configuration information for ETHERNET module
  2149. * @param AddrNbr: The MAC address to configure
  2150. * This parameter must be a value of the following:
  2151. * ETH_MAC_ADDRESS1
  2152. * ETH_MAC_ADDRESS2
  2153. * ETH_MAC_ADDRESS3
  2154. * @param pMACAddr: Pointer to MAC address buffer data (6 bytes)
  2155. * @retval HAL status
  2156. */
  2157. HAL_StatusTypeDef HAL_ETH_SetSourceMACAddrMatch(const ETH_HandleTypeDef *heth, uint32_t AddrNbr,
  2158. const uint8_t *pMACAddr)
  2159. {
  2160. uint32_t macaddrlr;
  2161. uint32_t macaddrhr;
  2162. if (pMACAddr == NULL)
  2163. {
  2164. return HAL_ERROR;
  2165. }
  2166. /* Get mac addr high reg offset */
  2167. macaddrhr = ((uint32_t) &(heth->Instance->MACA0HR) + AddrNbr);
  2168. /* Get mac addr low reg offset */
  2169. macaddrlr = ((uint32_t) &(heth->Instance->MACA0LR) + AddrNbr);
  2170. /* Set MAC addr bits 32 to 47 */
  2171. (*(__IO uint32_t *)macaddrhr) = (((uint32_t)(pMACAddr[5]) << 8) | (uint32_t)pMACAddr[4]);
  2172. /* Set MAC addr bits 0 to 31 */
  2173. (*(__IO uint32_t *)macaddrlr) = (((uint32_t)(pMACAddr[3]) << 24) | ((uint32_t)(pMACAddr[2]) << 16) |
  2174. ((uint32_t)(pMACAddr[1]) << 8) | (uint32_t)pMACAddr[0]);
  2175. /* Enable address and set source address bit */
  2176. (*(__IO uint32_t *)macaddrhr) |= (ETH_MACA1HR_AE | ETH_MACA1HR_SA);
  2177. return HAL_OK;
  2178. }
  2179. /**
  2180. * @brief Set the ETH Hash Table Value.
  2181. * @param heth: pointer to a ETH_HandleTypeDef structure that contains
  2182. * the configuration information for ETHERNET module
  2183. * @param pHashTable: pointer to a table of two 32 bit values, that contains
  2184. * the 64 bits of the hash table.
  2185. * @retval HAL status
  2186. */
  2187. HAL_StatusTypeDef HAL_ETH_SetHashTable(ETH_HandleTypeDef *heth, uint32_t *pHashTable)
  2188. {
  2189. uint32_t tmpreg1;
  2190. if (pHashTable == NULL)
  2191. {
  2192. return HAL_ERROR;
  2193. }
  2194. heth->Instance->MACHTHR = pHashTable[0];
  2195. /* Wait until the write operation will be taken into account :
  2196. at least four TX_CLK/RX_CLK clock cycles */
  2197. tmpreg1 = (heth->Instance)->MACHTHR;
  2198. HAL_Delay(ETH_REG_WRITE_DELAY);
  2199. (heth->Instance)->MACHTHR = tmpreg1;
  2200. heth->Instance->MACHTLR = pHashTable[1];
  2201. /* Wait until the write operation will be taken into account :
  2202. at least four TX_CLK/RX_CLK clock cycles */
  2203. tmpreg1 = (heth->Instance)->MACHTLR;
  2204. HAL_Delay(ETH_REG_WRITE_DELAY);
  2205. (heth->Instance)->MACHTLR = tmpreg1;
  2206. return HAL_OK;
  2207. }
  2208. /**
  2209. * @brief Set the VLAN Identifier for Rx packets
  2210. * @param heth: pointer to a ETH_HandleTypeDef structure that contains
  2211. * the configuration information for ETHERNET module
  2212. * @param ComparisonBits: 12 or 16 bit comparison mode
  2213. must be a value of @ref ETH_VLAN_Tag_Comparison
  2214. * @param VLANIdentifier: VLAN Identifier value
  2215. * @retval None
  2216. */
  2217. void HAL_ETH_SetRxVLANIdentifier(ETH_HandleTypeDef *heth, uint32_t ComparisonBits, uint32_t VLANIdentifier)
  2218. {
  2219. uint32_t tmpreg1;
  2220. MODIFY_REG(heth->Instance->MACVLANTR, ETH_MACVLANTR_VLANTI, VLANIdentifier);
  2221. if (ComparisonBits == ETH_VLANTAGCOMPARISON_16BIT)
  2222. {
  2223. CLEAR_BIT(heth->Instance->MACVLANTR, ETH_MACVLANTR_VLANTC);
  2224. }
  2225. else
  2226. {
  2227. SET_BIT(heth->Instance->MACVLANTR, ETH_MACVLANTR_VLANTC);
  2228. }
  2229. /* Wait until the write operation will be taken into account :
  2230. at least four TX_CLK/RX_CLK clock cycles */
  2231. tmpreg1 = (heth->Instance)->MACVLANTR;
  2232. HAL_Delay(ETH_REG_WRITE_DELAY);
  2233. (heth->Instance)->MACVLANTR = tmpreg1;
  2234. }
  2235. /**
  2236. * @brief Enters the Power down mode.
  2237. * @param heth: pointer to a ETH_HandleTypeDef structure that contains
  2238. * the configuration information for ETHERNET module
  2239. * @param pPowerDownConfig: a pointer to ETH_PowerDownConfigTypeDef structure
  2240. * that contains the Power Down configuration
  2241. * @retval None.
  2242. */
  2243. void HAL_ETH_EnterPowerDownMode(ETH_HandleTypeDef *heth, const ETH_PowerDownConfigTypeDef *pPowerDownConfig)
  2244. {
  2245. uint32_t powerdownconfig;
  2246. powerdownconfig = (((uint32_t)pPowerDownConfig->MagicPacket << ETH_MACPMTCSR_MPE_Pos) |
  2247. ((uint32_t)pPowerDownConfig->WakeUpPacket << ETH_MACPMTCSR_WFE_Pos) |
  2248. ((uint32_t)pPowerDownConfig->GlobalUnicast << ETH_MACPMTCSR_GU_Pos) |
  2249. ETH_MACPMTCSR_PD);
  2250. MODIFY_REG(heth->Instance->MACPMTCSR, ETH_MACPMTCSR_MASK, powerdownconfig);
  2251. }
  2252. /**
  2253. * @brief Exits from the Power down mode.
  2254. * @param heth: pointer to a ETH_HandleTypeDef structure that contains
  2255. * the configuration information for ETHERNET module
  2256. * @retval None.
  2257. */
  2258. void HAL_ETH_ExitPowerDownMode(ETH_HandleTypeDef *heth)
  2259. {
  2260. uint32_t tmpreg1;
  2261. /* clear wake up sources */
  2262. CLEAR_BIT(heth->Instance->MACPMTCSR, ETH_MACPMTCSR_WFE | ETH_MACPMTCSR_MPE | ETH_MACPMTCSR_GU);
  2263. /* Wait until the write operation will be taken into account :
  2264. at least four TX_CLK/RX_CLK clock cycles */
  2265. tmpreg1 = (heth->Instance)->MACPMTCSR;
  2266. HAL_Delay(ETH_REG_WRITE_DELAY);
  2267. (heth->Instance)->MACPMTCSR = tmpreg1;
  2268. if (READ_BIT(heth->Instance->MACPMTCSR, ETH_MACPMTCSR_PD) != 0U)
  2269. {
  2270. /* Exit power down mode */
  2271. CLEAR_BIT(heth->Instance->MACPMTCSR, ETH_MACPMTCSR_PD);
  2272. /* Wait until the write operation will be taken into account :
  2273. at least four TX_CLK/RX_CLK clock cycles */
  2274. tmpreg1 = (heth->Instance)->MACPMTCSR;
  2275. HAL_Delay(ETH_REG_WRITE_DELAY);
  2276. (heth->Instance)->MACPMTCSR = tmpreg1;
  2277. }
  2278. /* Disable PMT interrupt */
  2279. SET_BIT(heth->Instance->MACIMR, ETH_MACIMR_PMTIM);
  2280. }
  2281. /**
  2282. * @brief Set the WakeUp filter.
  2283. * @param heth: pointer to a ETH_HandleTypeDef structure that contains
  2284. * the configuration information for ETHERNET module
  2285. * @param pFilter: pointer to filter registers values
  2286. * @param Count: number of filter registers, must be from 1 to 8.
  2287. * @retval None.
  2288. */
  2289. HAL_StatusTypeDef HAL_ETH_SetWakeUpFilter(ETH_HandleTypeDef *heth, uint32_t *pFilter, uint32_t Count)
  2290. {
  2291. uint32_t regindex;
  2292. if (pFilter == NULL)
  2293. {
  2294. return HAL_ERROR;
  2295. }
  2296. /* Reset Filter Pointer */
  2297. SET_BIT(heth->Instance->MACPMTCSR, ETH_MACPMTCSR_WFFRPR);
  2298. /* Wake up packet filter config */
  2299. for (regindex = 0; regindex < Count; regindex++)
  2300. {
  2301. /* Write filter regs */
  2302. WRITE_REG(heth->Instance->MACRWUFFR, pFilter[regindex]);
  2303. }
  2304. return HAL_OK;
  2305. }
  2306. /**
  2307. * @}
  2308. */
  2309. /** @defgroup ETH_Exported_Functions_Group4 Peripheral State and Errors functions
  2310. * @brief ETH State and Errors functions
  2311. *
  2312. @verbatim
  2313. ==============================================================================
  2314. ##### Peripheral State and Errors functions #####
  2315. ==============================================================================
  2316. [..]
  2317. This subsection provides a set of functions allowing to return the State of
  2318. ETH communication process, return Peripheral Errors occurred during communication
  2319. process
  2320. @endverbatim
  2321. * @{
  2322. */
  2323. /**
  2324. * @brief Returns the ETH state.
  2325. * @param heth: pointer to a ETH_HandleTypeDef structure that contains
  2326. * the configuration information for ETHERNET module
  2327. * @retval HAL state
  2328. */
  2329. HAL_ETH_StateTypeDef HAL_ETH_GetState(const ETH_HandleTypeDef *heth)
  2330. {
  2331. return heth->gState;
  2332. }
  2333. /**
  2334. * @brief Returns the ETH error code
  2335. * @param heth: pointer to a ETH_HandleTypeDef structure that contains
  2336. * the configuration information for ETHERNET module
  2337. * @retval ETH Error Code
  2338. */
  2339. uint32_t HAL_ETH_GetError(const ETH_HandleTypeDef *heth)
  2340. {
  2341. return heth->ErrorCode;
  2342. }
  2343. /**
  2344. * @brief Returns the ETH DMA error code
  2345. * @param heth: pointer to a ETH_HandleTypeDef structure that contains
  2346. * the configuration information for ETHERNET module
  2347. * @retval ETH DMA Error Code
  2348. */
  2349. uint32_t HAL_ETH_GetDMAError(const ETH_HandleTypeDef *heth)
  2350. {
  2351. return heth->DMAErrorCode;
  2352. }
  2353. /**
  2354. * @brief Returns the ETH MAC error code
  2355. * @param heth: pointer to a ETH_HandleTypeDef structure that contains
  2356. * the configuration information for ETHERNET module
  2357. * @retval ETH MAC Error Code
  2358. */
  2359. uint32_t HAL_ETH_GetMACError(const ETH_HandleTypeDef *heth)
  2360. {
  2361. return heth->MACErrorCode;
  2362. }
  2363. /**
  2364. * @brief Returns the ETH MAC WakeUp event source
  2365. * @param heth: pointer to a ETH_HandleTypeDef structure that contains
  2366. * the configuration information for ETHERNET module
  2367. * @retval ETH MAC WakeUp event source
  2368. */
  2369. uint32_t HAL_ETH_GetMACWakeUpSource(const ETH_HandleTypeDef *heth)
  2370. {
  2371. return heth->MACWakeUpEvent;
  2372. }
  2373. /**
  2374. * @brief Returns the ETH Tx Buffers in use number
  2375. * @param heth: pointer to a ETH_HandleTypeDef structure that contains
  2376. * the configuration information for ETHERNET module
  2377. * @retval ETH Tx Buffers in use number
  2378. */
  2379. uint32_t HAL_ETH_GetTxBuffersNumber(const ETH_HandleTypeDef *heth)
  2380. {
  2381. return heth->TxDescList.BuffersInUse;
  2382. }
  2383. /**
  2384. * @}
  2385. */
  2386. /**
  2387. * @}
  2388. */
  2389. /** @addtogroup ETH_Private_Functions ETH Private Functions
  2390. * @{
  2391. */
  2392. /**
  2393. * @brief Clears the ETHERNET transmit FIFO.
  2394. * @param heth pointer to a ETH_HandleTypeDef structure that contains
  2395. * the configuration information for ETHERNET module
  2396. * @retval None
  2397. */
  2398. static void ETH_FlushTransmitFIFO(ETH_HandleTypeDef *heth)
  2399. {
  2400. __IO uint32_t tmpreg = 0;
  2401. /* Set the Flush Transmit FIFO bit */
  2402. (heth->Instance)->DMAOMR |= ETH_DMAOMR_FTF;
  2403. /* Wait until the write operation will be taken into account:
  2404. at least four TX_CLK/RX_CLK clock cycles */
  2405. tmpreg = (heth->Instance)->DMAOMR;
  2406. HAL_Delay(ETH_REG_WRITE_DELAY);
  2407. (heth->Instance)->DMAOMR = tmpreg;
  2408. }
  2409. static void ETH_SetMACConfig(ETH_HandleTypeDef *heth, const ETH_MACConfigTypeDef *macconf)
  2410. {
  2411. uint32_t tmpreg1;
  2412. /*------------------------ ETHERNET MACCR Configuration --------------------*/
  2413. /* Get the ETHERNET MACCR value */
  2414. tmpreg1 = (heth->Instance)->MACCR;
  2415. /* Clear CSTF, WD, PCE, PS, TE and RE bits */
  2416. tmpreg1 &= ETH_MACCR_CLEAR_MASK;
  2417. tmpreg1 |= (uint32_t)(((uint32_t)macconf->CRCStripTypePacket << 25U) |
  2418. ((uint32_t)((macconf->Watchdog == DISABLE) ? 1U : 0U) << 23U) |
  2419. ((uint32_t)((macconf->Jabber == DISABLE) ? 1U : 0U) << 22U) |
  2420. (uint32_t)macconf->InterPacketGapVal |
  2421. ((uint32_t)macconf->CarrierSenseDuringTransmit << 16U) |
  2422. macconf->Speed |
  2423. ((uint32_t)((macconf->ReceiveOwn == DISABLE) ? 1U : 0U) << 13U) |
  2424. ((uint32_t)macconf->LoopbackMode << 12U) |
  2425. macconf->DuplexMode |
  2426. ((uint32_t)macconf->ChecksumOffload << 10U) |
  2427. ((uint32_t)((macconf->RetryTransmission == DISABLE) ? 1U : 0U) << 9U) |
  2428. ((uint32_t)macconf->AutomaticPadCRCStrip << 7U) |
  2429. macconf->BackOffLimit |
  2430. ((uint32_t)macconf->DeferralCheck << 4U));
  2431. /* Write to ETHERNET MACCR */
  2432. (heth->Instance)->MACCR = (uint32_t)tmpreg1;
  2433. /* Wait until the write operation will be taken into account :
  2434. at least four TX_CLK/RX_CLK clock cycles */
  2435. tmpreg1 = (heth->Instance)->MACCR;
  2436. HAL_Delay(ETH_REG_WRITE_DELAY);
  2437. (heth->Instance)->MACCR = tmpreg1;
  2438. /*----------------------- ETHERNET MACFCR Configuration --------------------*/
  2439. /* Get the ETHERNET MACFCR value */
  2440. tmpreg1 = (heth->Instance)->MACFCR;
  2441. /* Clear xx bits */
  2442. tmpreg1 &= ETH_MACFCR_CLEAR_MASK;
  2443. tmpreg1 |= (uint32_t)((macconf->PauseTime << 16U) |
  2444. ((uint32_t)((macconf->ZeroQuantaPause == DISABLE) ? 1U : 0U) << 7U) |
  2445. macconf->PauseLowThreshold |
  2446. ((uint32_t)((macconf->UnicastPausePacketDetect == ENABLE) ? 1U : 0U) << 3U) |
  2447. ((uint32_t)((macconf->ReceiveFlowControl == ENABLE) ? 1U : 0U) << 2U) |
  2448. ((uint32_t)((macconf->TransmitFlowControl == ENABLE) ? 1U : 0U) << 1U));
  2449. /* Write to ETHERNET MACFCR */
  2450. (heth->Instance)->MACFCR = (uint32_t)tmpreg1;
  2451. /* Wait until the write operation will be taken into account :
  2452. at least four TX_CLK/RX_CLK clock cycles */
  2453. tmpreg1 = (heth->Instance)->MACFCR;
  2454. HAL_Delay(ETH_REG_WRITE_DELAY);
  2455. (heth->Instance)->MACFCR = tmpreg1;
  2456. }
  2457. static void ETH_SetDMAConfig(ETH_HandleTypeDef *heth, const ETH_DMAConfigTypeDef *dmaconf)
  2458. {
  2459. uint32_t tmpreg1;
  2460. /*----------------------- ETHERNET DMAOMR Configuration --------------------*/
  2461. /* Get the ETHERNET DMAOMR value */
  2462. tmpreg1 = (heth->Instance)->DMAOMR;
  2463. /* Clear xx bits */
  2464. tmpreg1 &= ETH_DMAOMR_CLEAR_MASK;
  2465. tmpreg1 |= (uint32_t)(((uint32_t)((dmaconf->DropTCPIPChecksumErrorFrame == DISABLE) ? 1U : 0U) << 26U) |
  2466. ((uint32_t)dmaconf->ReceiveStoreForward << 25U) |
  2467. ((uint32_t)((dmaconf->FlushRxPacket == DISABLE) ? 1U : 0U) << 20U) |
  2468. ((uint32_t)dmaconf->TransmitStoreForward << 21U) |
  2469. dmaconf->TransmitThresholdControl |
  2470. ((uint32_t)dmaconf->ForwardErrorFrames << 7U) |
  2471. ((uint32_t)dmaconf->ForwardUndersizedGoodFrames << 6U) |
  2472. dmaconf->ReceiveThresholdControl |
  2473. ((uint32_t)dmaconf->SecondFrameOperate << 2U));
  2474. /* Write to ETHERNET DMAOMR */
  2475. (heth->Instance)->DMAOMR = (uint32_t)tmpreg1;
  2476. /* Wait until the write operation will be taken into account:
  2477. at least four TX_CLK/RX_CLK clock cycles */
  2478. tmpreg1 = (heth->Instance)->DMAOMR;
  2479. HAL_Delay(ETH_REG_WRITE_DELAY);
  2480. (heth->Instance)->DMAOMR = tmpreg1;
  2481. /*----------------------- ETHERNET DMABMR Configuration --------------------*/
  2482. (heth->Instance)->DMABMR = (uint32_t)(((uint32_t)dmaconf->AddressAlignedBeats << 25U) |
  2483. dmaconf->BurstMode |
  2484. dmaconf->RxDMABurstLength | /* !! if 4xPBL is selected for Tx or
  2485. Rx it is applied for the other */
  2486. dmaconf->TxDMABurstLength |
  2487. ((uint32_t)dmaconf->EnhancedDescriptorFormat << 7U) |
  2488. (dmaconf->DescriptorSkipLength << 2U) |
  2489. dmaconf->DMAArbitration |
  2490. ETH_DMABMR_USP); /* Enable use of separate PBL for Rx and Tx */
  2491. /* Wait until the write operation will be taken into account:
  2492. at least four TX_CLK/RX_CLK clock cycles */
  2493. tmpreg1 = (heth->Instance)->DMABMR;
  2494. HAL_Delay(ETH_REG_WRITE_DELAY);
  2495. (heth->Instance)->DMABMR = tmpreg1;
  2496. }
  2497. /**
  2498. * @brief Configures Ethernet MAC and DMA with default parameters.
  2499. * called by HAL_ETH_Init() API.
  2500. * @param heth: pointer to a ETH_HandleTypeDef structure that contains
  2501. * the configuration information for ETHERNET module
  2502. * @retval HAL status
  2503. */
  2504. static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth)
  2505. {
  2506. ETH_MACConfigTypeDef macDefaultConf;
  2507. ETH_DMAConfigTypeDef dmaDefaultConf;
  2508. /*--------------- ETHERNET MAC registers default Configuration --------------*/
  2509. macDefaultConf.Watchdog = ENABLE;
  2510. macDefaultConf.Jabber = ENABLE;
  2511. macDefaultConf.InterPacketGapVal = ETH_INTERFRAMEGAP_96BIT;
  2512. macDefaultConf.CarrierSenseDuringTransmit = DISABLE;
  2513. macDefaultConf.ReceiveOwn = ENABLE;
  2514. macDefaultConf.LoopbackMode = DISABLE;
  2515. macDefaultConf.CRCStripTypePacket = ENABLE;
  2516. macDefaultConf.ChecksumOffload = ENABLE;
  2517. macDefaultConf.RetryTransmission = DISABLE;
  2518. macDefaultConf.AutomaticPadCRCStrip = DISABLE;
  2519. macDefaultConf.BackOffLimit = ETH_BACKOFFLIMIT_10;
  2520. macDefaultConf.DeferralCheck = DISABLE;
  2521. macDefaultConf.PauseTime = 0x0U;
  2522. macDefaultConf.ZeroQuantaPause = DISABLE;
  2523. macDefaultConf.PauseLowThreshold = ETH_PAUSELOWTHRESHOLD_MINUS4;
  2524. macDefaultConf.ReceiveFlowControl = DISABLE;
  2525. macDefaultConf.TransmitFlowControl = DISABLE;
  2526. macDefaultConf.Speed = ETH_SPEED_100M;
  2527. macDefaultConf.DuplexMode = ETH_FULLDUPLEX_MODE;
  2528. macDefaultConf.UnicastPausePacketDetect = DISABLE;
  2529. /* MAC default configuration */
  2530. ETH_SetMACConfig(heth, &macDefaultConf);
  2531. /*--------------- ETHERNET DMA registers default Configuration --------------*/
  2532. dmaDefaultConf.DropTCPIPChecksumErrorFrame = ENABLE;
  2533. dmaDefaultConf.ReceiveStoreForward = ENABLE;
  2534. dmaDefaultConf.FlushRxPacket = ENABLE;
  2535. dmaDefaultConf.TransmitStoreForward = ENABLE;
  2536. dmaDefaultConf.TransmitThresholdControl = ETH_TRANSMITTHRESHOLDCONTROL_64BYTES;
  2537. dmaDefaultConf.ForwardErrorFrames = DISABLE;
  2538. dmaDefaultConf.ForwardUndersizedGoodFrames = DISABLE;
  2539. dmaDefaultConf.ReceiveThresholdControl = ETH_RECEIVEDTHRESHOLDCONTROL_64BYTES;
  2540. dmaDefaultConf.SecondFrameOperate = ENABLE;
  2541. dmaDefaultConf.AddressAlignedBeats = ENABLE;
  2542. dmaDefaultConf.BurstMode = ETH_BURSTLENGTH_FIXED;
  2543. dmaDefaultConf.RxDMABurstLength = ETH_RXDMABURSTLENGTH_32BEAT;
  2544. dmaDefaultConf.TxDMABurstLength = ETH_TXDMABURSTLENGTH_32BEAT;
  2545. dmaDefaultConf.EnhancedDescriptorFormat = ENABLE;
  2546. dmaDefaultConf.DescriptorSkipLength = 0x0U;
  2547. dmaDefaultConf.DMAArbitration = ETH_DMAARBITRATION_ROUNDROBIN_RXTX_1_1;
  2548. /* DMA default configuration */
  2549. ETH_SetDMAConfig(heth, &dmaDefaultConf);
  2550. }
  2551. /**
  2552. * @brief Configures the selected MAC address.
  2553. * @param heth pointer to a ETH_HandleTypeDef structure that contains
  2554. * the configuration information for ETHERNET module
  2555. * @param MacAddr The MAC address to configure
  2556. * This parameter can be one of the following values:
  2557. * @arg ETH_MAC_Address0: MAC Address0
  2558. * @arg ETH_MAC_Address1: MAC Address1
  2559. * @arg ETH_MAC_Address2: MAC Address2
  2560. * @arg ETH_MAC_Address3: MAC Address3
  2561. * @param Addr Pointer to MAC address buffer data (6 bytes)
  2562. * @retval HAL status
  2563. */
  2564. static void ETH_MACAddressConfig(ETH_HandleTypeDef *heth, uint32_t MacAddr, uint8_t *Addr)
  2565. {
  2566. uint32_t tmpreg1;
  2567. /* Prevent unused argument(s) compilation warning */
  2568. UNUSED(heth);
  2569. /* Calculate the selected MAC address high register */
  2570. tmpreg1 = ((uint32_t)Addr[5U] << 8U) | (uint32_t)Addr[4U];
  2571. /* Load the selected MAC address high register */
  2572. (*(__IO uint32_t *)((uint32_t)(ETH_MAC_ADDR_HBASE + MacAddr))) = tmpreg1;
  2573. /* Calculate the selected MAC address low register */
  2574. tmpreg1 = ((uint32_t)Addr[3U] << 24U) | ((uint32_t)Addr[2U] << 16U) | ((uint32_t)Addr[1U] << 8U) | Addr[0U];
  2575. /* Load the selected MAC address low register */
  2576. (*(__IO uint32_t *)((uint32_t)(ETH_MAC_ADDR_LBASE + MacAddr))) = tmpreg1;
  2577. }
  2578. /**
  2579. * @brief Initializes the DMA Tx descriptors.
  2580. * called by HAL_ETH_Init() API.
  2581. * @param heth: pointer to a ETH_HandleTypeDef structure that contains
  2582. * the configuration information for ETHERNET module
  2583. * @retval None
  2584. */
  2585. static void ETH_DMATxDescListInit(ETH_HandleTypeDef *heth)
  2586. {
  2587. ETH_DMADescTypeDef *dmatxdesc;
  2588. uint32_t i;
  2589. /* Fill each DMATxDesc descriptor with the right values */
  2590. for (i = 0; i < (uint32_t)ETH_TX_DESC_CNT; i++)
  2591. {
  2592. dmatxdesc = heth->Init.TxDesc + i;
  2593. WRITE_REG(dmatxdesc->DESC0, 0x0U);
  2594. WRITE_REG(dmatxdesc->DESC1, 0x0U);
  2595. WRITE_REG(dmatxdesc->DESC2, 0x0U);
  2596. WRITE_REG(dmatxdesc->DESC3, 0x0U);
  2597. WRITE_REG(heth->TxDescList.TxDesc[i], (uint32_t)dmatxdesc);
  2598. /* Set Second Address Chained bit */
  2599. SET_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_TCH);
  2600. if (i < ((uint32_t)ETH_TX_DESC_CNT - 1U))
  2601. {
  2602. WRITE_REG(dmatxdesc->DESC3, (uint32_t)(heth->Init.TxDesc + i + 1U));
  2603. }
  2604. else
  2605. {
  2606. WRITE_REG(dmatxdesc->DESC3, (uint32_t)(heth->Init.TxDesc));
  2607. }
  2608. /* Set the DMA Tx descriptors checksum insertion */
  2609. SET_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_CHECKSUMTCPUDPICMPFULL);
  2610. }
  2611. heth->TxDescList.CurTxDesc = 0;
  2612. /* Set Transmit Descriptor List Address */
  2613. WRITE_REG(heth->Instance->DMATDLAR, (uint32_t) heth->Init.TxDesc);
  2614. }
  2615. /**
  2616. * @brief Initializes the DMA Rx descriptors in chain mode.
  2617. * called by HAL_ETH_Init() API.
  2618. * @param heth: pointer to a ETH_HandleTypeDef structure that contains
  2619. * the configuration information for ETHERNET module
  2620. * @retval None
  2621. */
  2622. static void ETH_DMARxDescListInit(ETH_HandleTypeDef *heth)
  2623. {
  2624. ETH_DMADescTypeDef *dmarxdesc;
  2625. uint32_t i;
  2626. for (i = 0; i < (uint32_t)ETH_RX_DESC_CNT; i++)
  2627. {
  2628. dmarxdesc = heth->Init.RxDesc + i;
  2629. WRITE_REG(dmarxdesc->DESC0, 0x0U);
  2630. WRITE_REG(dmarxdesc->DESC1, 0x0U);
  2631. WRITE_REG(dmarxdesc->DESC2, 0x0U);
  2632. WRITE_REG(dmarxdesc->DESC3, 0x0U);
  2633. WRITE_REG(dmarxdesc->BackupAddr0, 0x0U);
  2634. WRITE_REG(dmarxdesc->BackupAddr1, 0x0U);
  2635. /* Set Own bit of the Rx descriptor Status */
  2636. dmarxdesc->DESC0 = ETH_DMARXDESC_OWN;
  2637. /* Set Buffer1 size and Second Address Chained bit */
  2638. dmarxdesc->DESC1 = heth->Init.RxBuffLen | ETH_DMARXDESC_RCH;
  2639. /* Enable Ethernet DMA Rx Descriptor interrupt */
  2640. dmarxdesc->DESC1 &= ~ETH_DMARXDESC_DIC;
  2641. /* Set Rx descritors addresses */
  2642. WRITE_REG(heth->RxDescList.RxDesc[i], (uint32_t)dmarxdesc);
  2643. if (i < ((uint32_t)ETH_RX_DESC_CNT - 1U))
  2644. {
  2645. WRITE_REG(dmarxdesc->DESC3, (uint32_t)(heth->Init.RxDesc + i + 1U));
  2646. }
  2647. else
  2648. {
  2649. WRITE_REG(dmarxdesc->DESC3, (uint32_t)(heth->Init.RxDesc));
  2650. }
  2651. }
  2652. WRITE_REG(heth->RxDescList.RxDescIdx, 0U);
  2653. WRITE_REG(heth->RxDescList.RxDescCnt, 0U);
  2654. WRITE_REG(heth->RxDescList.RxBuildDescIdx, 0U);
  2655. WRITE_REG(heth->RxDescList.RxBuildDescCnt, 0U);
  2656. WRITE_REG(heth->RxDescList.ItMode, 0U);
  2657. /* Set Receive Descriptor List Address */
  2658. WRITE_REG(heth->Instance->DMARDLAR, (uint32_t) heth->Init.RxDesc);
  2659. }
  2660. /**
  2661. * @brief Prepare Tx DMA descriptor before transmission.
  2662. * called by HAL_ETH_Transmit_IT and HAL_ETH_Transmit_IT() API.
  2663. * @param heth: pointer to a ETH_HandleTypeDef structure that contains
  2664. * the configuration information for ETHERNET module
  2665. * @param pTxConfig: Tx packet configuration
  2666. * @param ItMode: Enable or disable Tx EOT interrupt
  2667. * @retval Status
  2668. */
  2669. static uint32_t ETH_Prepare_Tx_Descriptors(ETH_HandleTypeDef *heth, const ETH_TxPacketConfigTypeDef *pTxConfig,
  2670. uint32_t ItMode)
  2671. {
  2672. ETH_TxDescListTypeDef *dmatxdesclist = &heth->TxDescList;
  2673. uint32_t descidx = dmatxdesclist->CurTxDesc;
  2674. uint32_t firstdescidx = dmatxdesclist->CurTxDesc;
  2675. uint32_t idx;
  2676. uint32_t descnbr = 0;
  2677. ETH_DMADescTypeDef *dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx];
  2678. ETH_BufferTypeDef *txbuffer = pTxConfig->TxBuffer;
  2679. uint32_t bd_count = 0;
  2680. uint32_t primask_bit;
  2681. /* Current Tx Descriptor Owned by DMA: cannot be used by the application */
  2682. if ((READ_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_OWN) == ETH_DMATXDESC_OWN)
  2683. || (dmatxdesclist->PacketAddress[descidx] != NULL))
  2684. {
  2685. return HAL_ETH_ERROR_BUSY;
  2686. }
  2687. descnbr += 1U;
  2688. /* Set header or buffer 1 address */
  2689. WRITE_REG(dmatxdesc->DESC2, (uint32_t)txbuffer->buffer);
  2690. /* Set header or buffer 1 Length */
  2691. MODIFY_REG(dmatxdesc->DESC1, ETH_DMATXDESC_TBS1, txbuffer->len);
  2692. if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_CSUM) != 0U)
  2693. {
  2694. MODIFY_REG(dmatxdesc->DESC0, ETH_DMATXDESC_CIC, pTxConfig->ChecksumCtrl);
  2695. }
  2696. if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_CRCPAD) != 0U)
  2697. {
  2698. MODIFY_REG(dmatxdesc->DESC0, ETH_CRC_PAD_DISABLE, pTxConfig->CRCPadCtrl);
  2699. }
  2700. if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_VLANTAG) != 0U)
  2701. {
  2702. /* Set Vlan Type */
  2703. SET_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_VF);
  2704. }
  2705. /* Mark it as First Descriptor */
  2706. SET_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_FS);
  2707. /* only if the packet is split into more than one descriptors > 1 */
  2708. while (txbuffer->next != NULL)
  2709. {
  2710. /* Clear the LD bit of previous descriptor */
  2711. CLEAR_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_LS);
  2712. if (ItMode != ((uint32_t)RESET))
  2713. {
  2714. /* Set Interrupt on completion bit */
  2715. SET_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_IC);
  2716. }
  2717. else
  2718. {
  2719. /* Clear Interrupt on completion bit */
  2720. CLEAR_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_IC);
  2721. }
  2722. /* Increment current tx descriptor index */
  2723. INCR_TX_DESC_INDEX(descidx, 1U);
  2724. /* Get current descriptor address */
  2725. dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx];
  2726. /* Current Tx Descriptor Owned by DMA: cannot be used by the application */
  2727. if ((READ_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_OWN) == ETH_DMATXDESC_OWN)
  2728. || (dmatxdesclist->PacketAddress[descidx] != NULL))
  2729. {
  2730. descidx = firstdescidx;
  2731. dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx];
  2732. /* clear previous desc own bit */
  2733. for (idx = 0; idx < descnbr; idx ++)
  2734. {
  2735. /* Ensure rest of descriptor is written to RAM before the OWN bit */
  2736. __DMB();
  2737. CLEAR_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_OWN);
  2738. /* Increment current tx descriptor index */
  2739. INCR_TX_DESC_INDEX(descidx, 1U);
  2740. /* Get current descriptor address */
  2741. dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx];
  2742. }
  2743. return HAL_ETH_ERROR_BUSY;
  2744. }
  2745. /* Clear the FD bit of new Descriptor */
  2746. CLEAR_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_FS);
  2747. descnbr += 1U;
  2748. /* Get the next Tx buffer in the list */
  2749. txbuffer = txbuffer->next;
  2750. /* Set header or buffer 1 address */
  2751. WRITE_REG(dmatxdesc->DESC2, (uint32_t)txbuffer->buffer);
  2752. /* Set header or buffer 1 Length */
  2753. MODIFY_REG(dmatxdesc->DESC1, ETH_DMATXDESC_TBS1, txbuffer->len);
  2754. bd_count += 1U;
  2755. /* Ensure rest of descriptor is written to RAM before the OWN bit */
  2756. __DMB();
  2757. /* Set Own bit */
  2758. SET_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_OWN);
  2759. }
  2760. if (ItMode != ((uint32_t)RESET))
  2761. {
  2762. /* Set Interrupt on completion bit */
  2763. SET_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_IC);
  2764. }
  2765. else
  2766. {
  2767. /* Clear Interrupt on completion bit */
  2768. CLEAR_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_IC);
  2769. }
  2770. /* Mark it as LAST descriptor */
  2771. SET_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_LS);
  2772. /* Get address of first descriptor */
  2773. dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[firstdescidx];
  2774. /* Ensure rest of descriptor is written to RAM before the OWN bit */
  2775. __DMB();
  2776. /* set OWN bit of FIRST descriptor */
  2777. SET_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_OWN);
  2778. /* Save the current packet address to expose it to the application */
  2779. dmatxdesclist->PacketAddress[descidx] = dmatxdesclist->CurrentPacketAddress;
  2780. dmatxdesclist->CurTxDesc = descidx;
  2781. /* Enter critical section */
  2782. primask_bit = __get_PRIMASK();
  2783. __set_PRIMASK(1);
  2784. dmatxdesclist->BuffersInUse += bd_count + 1U;
  2785. /* Exit critical section: restore previous priority mask */
  2786. __set_PRIMASK(primask_bit);
  2787. /* Return function status */
  2788. return HAL_ETH_ERROR_NONE;
  2789. }
  2790. #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
  2791. static void ETH_InitCallbacksToDefault(ETH_HandleTypeDef *heth)
  2792. {
  2793. /* Init the ETH Callback settings */
  2794. heth->TxCpltCallback = HAL_ETH_TxCpltCallback; /* Legacy weak TxCpltCallback */
  2795. heth->RxCpltCallback = HAL_ETH_RxCpltCallback; /* Legacy weak RxCpltCallback */
  2796. heth->ErrorCallback = HAL_ETH_ErrorCallback; /* Legacy weak ErrorCallback */
  2797. heth->PMTCallback = HAL_ETH_PMTCallback; /* Legacy weak PMTCallback */
  2798. heth->WakeUpCallback = HAL_ETH_WakeUpCallback; /* Legacy weak WakeUpCallback */
  2799. heth->rxLinkCallback = HAL_ETH_RxLinkCallback; /* Legacy weak RxLinkCallback */
  2800. heth->txFreeCallback = HAL_ETH_TxFreeCallback; /* Legacy weak TxFreeCallback */
  2801. #ifdef HAL_ETH_USE_PTP
  2802. heth->txPtpCallback = HAL_ETH_TxPtpCallback; /* Legacy weak TxPtpCallback */
  2803. #endif /* HAL_ETH_USE_PTP */
  2804. heth->rxAllocateCallback = HAL_ETH_RxAllocateCallback; /* Legacy weak RxAllocateCallback */
  2805. }
  2806. #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
  2807. /**
  2808. * @}
  2809. */
  2810. /**
  2811. * @}
  2812. */
  2813. #endif /* ETH */
  2814. #endif /* HAL_ETH_MODULE_ENABLED */
  2815. /**
  2816. * @}
  2817. */