训练营PLSR题目
Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.
 
 
 
 
 
 

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