This patch converts all files imported from ST to Unix line endings using dos2unix. --- rtemslwip/stm32f4/lwipopts.h | 294 ++--- stm32/driver/dp83848.c | 1328 +++++++++++------------ stm32/driver/dp83848.h | 872 +++++++-------- stm32/ethernetif.c | 1972 +++++++++++++++++----------------- stm32/ethernetif.h | 108 +- 5 files changed, 2287 insertions(+), 2287 deletions(-)
diff --git a/rtemslwip/stm32f4/lwipopts.h b/rtemslwip/stm32f4/lwipopts.h index aa6b95b..eec98c7 100644 --- a/rtemslwip/stm32f4/lwipopts.h +++ b/rtemslwip/stm32f4/lwipopts.h @@ -1,147 +1,147 @@ -/* USER CODE BEGIN Header */ -/** - ****************************************************************************** - * File Name : Target/lwipopts.h - * Description : This file overrides LwIP stack default configuration - * done in opt.h file. - ****************************************************************************** - * @attention - * - * Copyright (c) 2022 STMicroelectronics. - * All rights reserved. - * - * This software is licensed under terms that can be found in the LICENSE file - * in the root directory of this software component. - * If no LICENSE file comes with this software, it is provided AS-IS. - * - ****************************************************************************** - */ -/* USER CODE END Header */ - -/* Define to prevent recursive inclusion --------------------------------------*/ -#ifndef __LWIPOPTS__H__ -#define __LWIPOPTS__H__ - -/*-----------------------------------------------------------------------------*/ -/* Current version of LwIP supported by CubeMx: 2.1.2 -*/ -/*-----------------------------------------------------------------------------*/ - -/* Within 'USER CODE' section, code will be kept by default at each generation */ -/* USER CODE BEGIN 0 */ -#include <stm32f4xx_hal.h> -/* USER CODE END 0 */ - -#ifdef __cplusplus - extern "C" { -#endif - -/* STM32CubeMX Specific Parameters (not defined in opt.h) ---------------------*/ -/* Parameters set in STM32CubeMX LwIP Configuration GUI -*/ -/*----- WITH_RTOS disabled (Since FREERTOS is not set) -----*/ -#define WITH_RTOS 1 -/*----- CHECKSUM_BY_HARDWARE disabled -----*/ -#define CHECKSUM_BY_HARDWARE 0 -/*-----------------------------------------------------------------------------*/ - -/* LwIP Stack Parameters (modified compared to initialization value in opt.h) -*/ -/* Parameters set in STM32CubeMX LwIP Configuration GUI -*/ -/*----- Default value in ETH configuration GUI in CubeMx: 1524 -----*/ -#define ETH_RX_BUFFER_SIZE 1536 -/*----- Value in opt.h for NO_SYS: 0 -----*/ -#define NO_SYS 0 -/*----- Value in opt.h for SYS_LIGHTWEIGHT_PROT: 1 -----*/ -#define SYS_LIGHTWEIGHT_PROT 1 -/*----- Value in opt.h for MEM_ALIGNMENT: 1 -----*/ -#define MEM_ALIGNMENT 4 -/*----- Default Value for H7 devices: 0x30044000 -----*/ -//#define LWIP_RAM_HEAP_POINTER 0x20017f58 -/*----- Value supported for H7 devices: 1 -----*/ -#define LWIP_SUPPORT_CUSTOM_PBUF 1 -/*----- Value in opt.h for LWIP_ETHERNET: LWIP_ARP || PPPOE_SUPPORT -*/ -#define LWIP_ETHERNET 1 -/*----- Value in opt.h for LWIP_DNS_SECURE: (LWIP_DNS_SECURE_RAND_XID | LWIP_DNS_SECURE_NO_MULTIPLE_OUTSTANDING | LWIP_DNS_SECURE_RAND_SRC_PORT) -*/ -#define LWIP_DNS_SECURE 7 -/*----- Value in opt.h for TCP_SND_QUEUELEN: (4*TCP_SND_BUF + (TCP_MSS - 1))/TCP_MSS -----*/ -#define TCP_SND_QUEUELEN 9 -/*----- Value in opt.h for TCP_SNDLOWAT: LWIP_MIN(LWIP_MAX(((TCP_SND_BUF)/2), (2 * TCP_MSS) + 1), (TCP_SND_BUF) - 1) -*/ -#define TCP_SNDLOWAT 1071 -/*----- Value in opt.h for TCP_SNDQUEUELOWAT: LWIP_MAX(TCP_SND_QUEUELEN)/2, 5) -*/ -#define TCP_SNDQUEUELOWAT 5 -/*----- Value in opt.h for TCP_WND_UPDATE_THRESHOLD: LWIP_MIN(TCP_WND/4, TCP_MSS*4) -----*/ -#define TCP_WND_UPDATE_THRESHOLD 536 -/*----- Value in opt.h for LWIP_NETIF_LINK_CALLBACK: 0 -----*/ -//#define LWIP_NETIF_LINK_CALLBACK 0 -/*----- Value in opt.h for LWIP_NETCONN: 1 -----*/ -#define LWIP_NETCONN 1 -/*----- Value in opt.h for LWIP_SOCKET: 1 -----*/ -#define LWIP_SOCKET 1 -/*----- Value in opt.h for RECV_BUFSIZE_DEFAULT: INT_MAX -----*/ -//#define RECV_BUFSIZE_DEFAULT 2000000000 -/*----- Value in opt.h for LWIP_STATS: 1 -----*/ -#define LWIP_STATS 0 -/*----- Value in opt.h for CHECKSUM_GEN_IP: 1 -----*/ -#define CHECKSUM_GEN_IP 0 -/*----- Value in opt.h for CHECKSUM_GEN_UDP: 1 -----*/ -#define CHECKSUM_GEN_UDP 0 -/*----- Value in opt.h for CHECKSUM_GEN_TCP: 1 -----*/ -#define CHECKSUM_GEN_TCP 0 -/*----- Value in opt.h for CHECKSUM_GEN_ICMP: 1 -----*/ -#define CHECKSUM_GEN_ICMP 0 -/*----- Value in opt.h for CHECKSUM_GEN_ICMP6: 1 -----*/ -#define CHECKSUM_GEN_ICMP6 0 -/*----- Value in opt.h for CHECKSUM_CHECK_IP: 1 -----*/ -#define CHECKSUM_CHECK_IP 0 -/*----- Value in opt.h for CHECKSUM_CHECK_UDP: 1 -----*/ -#define CHECKSUM_CHECK_UDP 0 -/*----- Value in opt.h for CHECKSUM_CHECK_TCP: 1 -----*/ -#define CHECKSUM_CHECK_TCP 0 -/*----- Value in opt.h for CHECKSUM_CHECK_ICMP: 1 -----*/ -#define CHECKSUM_CHECK_ICMP 0 -/*----- Value in opt.h for CHECKSUM_CHECK_ICMP6: 1 -----*/ -#define CHECKSUM_CHECK_ICMP6 0 -/*----- Default Value for ETHARP_DEBUG: LWIP_DBG_OFF ---*/ -/*-----------------------------------------------------------------------------*/ -/* USER CODE BEGIN 1 */ -//#define LWIP_DEBUG 1 -#define LWIP_ARP 1 - -#define LWIP_NETIF_API 1 - -#define NO_SYS_NO_TIMERS 0 - -#define IP_REASSEMBLY 0 -#define IP_FRAG 0 -#define LWIP_IPV4 1 -#define LWIP_IPV6 1 - -#define LWIP_TCPIP_CORE_LOCKING 1 -#define TCPIP_THREAD_STACKSIZE 1024 -#define TCPIP_THREAD_PRIO 24 -#define TCPIP_MBOX_SIZE 6 -#define SLIPIF_THREAD_STACKSIZE 1024 -#define SLIPIF_THREAD_PRIO 3 -#define DEFAULT_THREAD_STACKSIZE 1024 -#define DEFAULT_THREAD_PRIO 3 -#define DEFAULT_UDP_RECVMBOX_SIZE 6 -#define DEFAULT_TCP_RECVMBOX_SIZE 6 -#define DEFAULT_ACCEPTMBOX_SIZE 6 - -#define LWIP_DHCP 1 -#define DHCP_DOES_ARP_CHECK 1 - -#define LWIP_DNS 1 - -#define LWIP_AUTOIP 1 -#define LWIP_DHCP_AUTOIP_COOP ((LWIP_DHCP) && (LWIP_AUTOIP)) - -#define LWIP_TIMEVAL_PRIVATE 0 -#define LWIP_COMPAT_SOCKETS 1 -#define LWIP_RAW 0 - -#define SO_REUSE 1 -/* USER CODE END 1 */ - -#ifdef __cplusplus -} -#endif -#endif /*__LWIPOPTS__H__ */ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * File Name : Target/lwipopts.h + * Description : This file overrides LwIP stack default configuration + * done in opt.h file. + ****************************************************************************** + * @attention + * + * Copyright (c) 2022 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Define to prevent recursive inclusion --------------------------------------*/ +#ifndef __LWIPOPTS__H__ +#define __LWIPOPTS__H__ + +/*-----------------------------------------------------------------------------*/ +/* Current version of LwIP supported by CubeMx: 2.1.2 -*/ +/*-----------------------------------------------------------------------------*/ + +/* Within 'USER CODE' section, code will be kept by default at each generation */ +/* USER CODE BEGIN 0 */ +#include <stm32f4xx_hal.h> +/* USER CODE END 0 */ + +#ifdef __cplusplus + extern "C" { +#endif + +/* STM32CubeMX Specific Parameters (not defined in opt.h) ---------------------*/ +/* Parameters set in STM32CubeMX LwIP Configuration GUI -*/ +/*----- WITH_RTOS disabled (Since FREERTOS is not set) -----*/ +#define WITH_RTOS 1 +/*----- CHECKSUM_BY_HARDWARE disabled -----*/ +#define CHECKSUM_BY_HARDWARE 0 +/*-----------------------------------------------------------------------------*/ + +/* LwIP Stack Parameters (modified compared to initialization value in opt.h) -*/ +/* Parameters set in STM32CubeMX LwIP Configuration GUI -*/ +/*----- Default value in ETH configuration GUI in CubeMx: 1524 -----*/ +#define ETH_RX_BUFFER_SIZE 1536 +/*----- Value in opt.h for NO_SYS: 0 -----*/ +#define NO_SYS 0 +/*----- Value in opt.h for SYS_LIGHTWEIGHT_PROT: 1 -----*/ +#define SYS_LIGHTWEIGHT_PROT 1 +/*----- Value in opt.h for MEM_ALIGNMENT: 1 -----*/ +#define MEM_ALIGNMENT 4 +/*----- Default Value for H7 devices: 0x30044000 -----*/ +//#define LWIP_RAM_HEAP_POINTER 0x20017f58 +/*----- Value supported for H7 devices: 1 -----*/ +#define LWIP_SUPPORT_CUSTOM_PBUF 1 +/*----- Value in opt.h for LWIP_ETHERNET: LWIP_ARP || PPPOE_SUPPORT -*/ +#define LWIP_ETHERNET 1 +/*----- Value in opt.h for LWIP_DNS_SECURE: (LWIP_DNS_SECURE_RAND_XID | LWIP_DNS_SECURE_NO_MULTIPLE_OUTSTANDING | LWIP_DNS_SECURE_RAND_SRC_PORT) -*/ +#define LWIP_DNS_SECURE 7 +/*----- Value in opt.h for TCP_SND_QUEUELEN: (4*TCP_SND_BUF + (TCP_MSS - 1))/TCP_MSS -----*/ +#define TCP_SND_QUEUELEN 9 +/*----- Value in opt.h for TCP_SNDLOWAT: LWIP_MIN(LWIP_MAX(((TCP_SND_BUF)/2), (2 * TCP_MSS) + 1), (TCP_SND_BUF) - 1) -*/ +#define TCP_SNDLOWAT 1071 +/*----- Value in opt.h for TCP_SNDQUEUELOWAT: LWIP_MAX(TCP_SND_QUEUELEN)/2, 5) -*/ +#define TCP_SNDQUEUELOWAT 5 +/*----- Value in opt.h for TCP_WND_UPDATE_THRESHOLD: LWIP_MIN(TCP_WND/4, TCP_MSS*4) -----*/ +#define TCP_WND_UPDATE_THRESHOLD 536 +/*----- Value in opt.h for LWIP_NETIF_LINK_CALLBACK: 0 -----*/ +//#define LWIP_NETIF_LINK_CALLBACK 0 +/*----- Value in opt.h for LWIP_NETCONN: 1 -----*/ +#define LWIP_NETCONN 1 +/*----- Value in opt.h for LWIP_SOCKET: 1 -----*/ +#define LWIP_SOCKET 1 +/*----- Value in opt.h for RECV_BUFSIZE_DEFAULT: INT_MAX -----*/ +//#define RECV_BUFSIZE_DEFAULT 2000000000 +/*----- Value in opt.h for LWIP_STATS: 1 -----*/ +#define LWIP_STATS 0 +/*----- Value in opt.h for CHECKSUM_GEN_IP: 1 -----*/ +#define CHECKSUM_GEN_IP 0 +/*----- Value in opt.h for CHECKSUM_GEN_UDP: 1 -----*/ +#define CHECKSUM_GEN_UDP 0 +/*----- Value in opt.h for CHECKSUM_GEN_TCP: 1 -----*/ +#define CHECKSUM_GEN_TCP 0 +/*----- Value in opt.h for CHECKSUM_GEN_ICMP: 1 -----*/ +#define CHECKSUM_GEN_ICMP 0 +/*----- Value in opt.h for CHECKSUM_GEN_ICMP6: 1 -----*/ +#define CHECKSUM_GEN_ICMP6 0 +/*----- Value in opt.h for CHECKSUM_CHECK_IP: 1 -----*/ +#define CHECKSUM_CHECK_IP 0 +/*----- Value in opt.h for CHECKSUM_CHECK_UDP: 1 -----*/ +#define CHECKSUM_CHECK_UDP 0 +/*----- Value in opt.h for CHECKSUM_CHECK_TCP: 1 -----*/ +#define CHECKSUM_CHECK_TCP 0 +/*----- Value in opt.h for CHECKSUM_CHECK_ICMP: 1 -----*/ +#define CHECKSUM_CHECK_ICMP 0 +/*----- Value in opt.h for CHECKSUM_CHECK_ICMP6: 1 -----*/ +#define CHECKSUM_CHECK_ICMP6 0 +/*----- Default Value for ETHARP_DEBUG: LWIP_DBG_OFF ---*/ +/*-----------------------------------------------------------------------------*/ +/* USER CODE BEGIN 1 */ +//#define LWIP_DEBUG 1 +#define LWIP_ARP 1 + +#define LWIP_NETIF_API 1 + +#define NO_SYS_NO_TIMERS 0 + +#define IP_REASSEMBLY 0 +#define IP_FRAG 0 +#define LWIP_IPV4 1 +#define LWIP_IPV6 1 + +#define LWIP_TCPIP_CORE_LOCKING 1 +#define TCPIP_THREAD_STACKSIZE 1024 +#define TCPIP_THREAD_PRIO 24 +#define TCPIP_MBOX_SIZE 6 +#define SLIPIF_THREAD_STACKSIZE 1024 +#define SLIPIF_THREAD_PRIO 3 +#define DEFAULT_THREAD_STACKSIZE 1024 +#define DEFAULT_THREAD_PRIO 3 +#define DEFAULT_UDP_RECVMBOX_SIZE 6 +#define DEFAULT_TCP_RECVMBOX_SIZE 6 +#define DEFAULT_ACCEPTMBOX_SIZE 6 + +#define LWIP_DHCP 1 +#define DHCP_DOES_ARP_CHECK 1 + +#define LWIP_DNS 1 + +#define LWIP_AUTOIP 1 +#define LWIP_DHCP_AUTOIP_COOP ((LWIP_DHCP) && (LWIP_AUTOIP)) + +#define LWIP_TIMEVAL_PRIVATE 0 +#define LWIP_COMPAT_SOCKETS 1 +#define LWIP_RAW 0 + +#define SO_REUSE 1 +/* USER CODE END 1 */ + +#ifdef __cplusplus +} +#endif +#endif /*__LWIPOPTS__H__ */ diff --git a/stm32/driver/dp83848.c b/stm32/driver/dp83848.c index 2c5d59b..b1d3150 100644 --- a/stm32/driver/dp83848.c +++ b/stm32/driver/dp83848.c @@ -1,664 +1,664 @@ -/** - ****************************************************************************** - * @file dp83848.c - * @author MCD Application Team - * @brief This file provides a set of functions needed to manage the DP83848 - * PHY devices. - ****************************************************************************** - * @attention - * - * <h2><center>© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.</center></h2> - * - * This software component is licensed by ST under BSD 3-Clause license, - * the "License"; You may not use this file except in compliance with the - * License. You may obtain a copy of the License at: - * opensource.org/licenses/BSD-3-Clause - * - ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "dp83848.h" - -/** @addtogroup BSP - * @{ - */ - -/** @addtogroup Component - * @{ - */ - -/** @defgroup DP83848 DP83848 - * @{ - */ - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -/** @defgroup DP83848_Private_Defines DP83848 Private Defines - * @{ - */ -#define DP83848_SW_RESET_TO ((uint32_t)500U) -#define DP83848_INIT_TO ((uint32_t)2000U) -#define DP83848_MAX_DEV_ADDR ((uint32_t)31U) -/** - * @} - */ - -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ -/** @defgroup DP83848_Private_Functions DP83848 Private Functions - * @{ - */ - -/** - * @brief Register IO functions to component object - * @param pObj: device object of DP83848_Object_t. - * @param ioctx: holds device IO functions. - * @retval DP83848_STATUS_OK if OK - * DP83848_STATUS_ERROR if missing mandatory function - */ -int32_t DP83848_RegisterBusIO(dp83848_Object_t *pObj, dp83848_IOCtx_t *ioctx) -{ - if(!pObj || !ioctx->ReadReg || !ioctx->WriteReg || !ioctx->GetTick) - { - return DP83848_STATUS_ERROR; - } - - pObj->IO.Init = ioctx->Init; - pObj->IO.DeInit = ioctx->DeInit; - pObj->IO.ReadReg = ioctx->ReadReg; - pObj->IO.WriteReg = ioctx->WriteReg; - pObj->IO.GetTick = ioctx->GetTick; - - return DP83848_STATUS_OK; -} - -/** - * @brief Initialize the DP83848 and configure the needed hardware resources - * @param pObj: device object DP83848_Object_t. - * @retval DP83848_STATUS_OK if OK - * DP83848_STATUS_ADDRESS_ERROR if cannot find device address - * DP83848_STATUS_READ_ERROR if connot read register - * DP83848_STATUS_WRITE_ERROR if connot write to register - * DP83848_STATUS_RESET_TIMEOUT if cannot perform a software reset - */ - int32_t DP83848_Init(dp83848_Object_t *pObj) - { - uint32_t tickstart = 0, regvalue = 0, addr = 0; - int32_t status = DP83848_STATUS_OK; - - if(pObj->Is_Initialized == 0) - { - if(pObj->IO.Init != 0) - { - /* GPIO and Clocks initialization */ - pObj->IO.Init(); - } - - /* for later check */ - pObj->DevAddr = DP83848_MAX_DEV_ADDR + 1; - - /* Get the device address from special mode register */ - for(addr = 0; addr <= DP83848_MAX_DEV_ADDR; addr ++) - { - if(pObj->IO.ReadReg(addr, DP83848_SMR, ®value) < 0) - { - status = DP83848_STATUS_READ_ERROR; - /* Can't read from this device address - continue with next address */ - continue; - } - - if((regvalue & DP83848_SMR_PHY_ADDR) == addr) - { - pObj->DevAddr = addr; - status = DP83848_STATUS_OK; - break; - } - } - - if(pObj->DevAddr > DP83848_MAX_DEV_ADDR) - { - status = DP83848_STATUS_ADDRESS_ERROR; - } - - /* if device address is matched */ - if(status == DP83848_STATUS_OK) - { - /* set a software reset */ - if(pObj->IO.WriteReg(pObj->DevAddr, DP83848_BCR, DP83848_BCR_SOFT_RESET) >= 0) - { - /* get software reset status */ - if(pObj->IO.ReadReg(pObj->DevAddr, DP83848_BCR, ®value) >= 0) - { - tickstart = pObj->IO.GetTick(); - - /* wait until software reset is done or timeout occured */ - while(regvalue & DP83848_BCR_SOFT_RESET) - { - if((pObj->IO.GetTick() - tickstart) <= DP83848_SW_RESET_TO) - { - if(pObj->IO.ReadReg(pObj->DevAddr, DP83848_BCR, ®value) < 0) - { - status = DP83848_STATUS_READ_ERROR; - break; - } - } - else - { - status = DP83848_STATUS_RESET_TIMEOUT; - break; - } - } - } - else - { - status = DP83848_STATUS_READ_ERROR; - } - } - else - { - status = DP83848_STATUS_WRITE_ERROR; - } - } - } - - if(status == DP83848_STATUS_OK) - { - tickstart = pObj->IO.GetTick(); - - /* Wait for 2s to perform initialization */ - while((pObj->IO.GetTick() - tickstart) <= DP83848_INIT_TO) - { - } - pObj->Is_Initialized = 1; - } - - return status; - } - -/** - * @brief De-Initialize the dp83848 and it's hardware resources - * @param pObj: device object DP83848_Object_t. - * @retval None - */ -int32_t DP83848_DeInit(dp83848_Object_t *pObj) -{ - if(pObj->Is_Initialized) - { - if(pObj->IO.DeInit != 0) - { - if(pObj->IO.DeInit() < 0) - { - return DP83848_STATUS_ERROR; - } - } - - pObj->Is_Initialized = 0; - } - - return DP83848_STATUS_OK; -} - -/** - * @brief Disable the DP83848 power down mode. - * @param pObj: device object DP83848_Object_t. - * @retval DP83848_STATUS_OK if OK - * DP83848_STATUS_READ_ERROR if connot read register - * DP83848_STATUS_WRITE_ERROR if connot write to register - */ -int32_t DP83848_DisablePowerDownMode(dp83848_Object_t *pObj) -{ - uint32_t readval = 0; - int32_t status = DP83848_STATUS_OK; - - if(pObj->IO.ReadReg(pObj->DevAddr, DP83848_BCR, &readval) >= 0) - { - readval &= ~DP83848_BCR_POWER_DOWN; - - /* Apply configuration */ - if(pObj->IO.WriteReg(pObj->DevAddr, DP83848_BCR, readval) < 0) - { - status = DP83848_STATUS_WRITE_ERROR; - } - } - else - { - status = DP83848_STATUS_READ_ERROR; - } - - return status; -} - -/** - * @brief Enable the DP83848 power down mode. - * @param pObj: device object DP83848_Object_t. - * @retval DP83848_STATUS_OK if OK - * DP83848_STATUS_READ_ERROR if connot read register - * DP83848_STATUS_WRITE_ERROR if connot write to register - */ -int32_t DP83848_EnablePowerDownMode(dp83848_Object_t *pObj) -{ - uint32_t readval = 0; - int32_t status = DP83848_STATUS_OK; - - if(pObj->IO.ReadReg(pObj->DevAddr, DP83848_BCR, &readval) >= 0) - { - readval |= DP83848_BCR_POWER_DOWN; - - /* Apply configuration */ - if(pObj->IO.WriteReg(pObj->DevAddr, DP83848_BCR, readval) < 0) - { - status = DP83848_STATUS_WRITE_ERROR; - } - } - else - { - status = DP83848_STATUS_READ_ERROR; - } - - return status; -} - -/** - * @brief Start the auto negotiation process. - * @param pObj: device object DP83848_Object_t. - * @retval DP83848_STATUS_OK if OK - * DP83848_STATUS_READ_ERROR if connot read register - * DP83848_STATUS_WRITE_ERROR if connot write to register - */ -int32_t DP83848_StartAutoNego(dp83848_Object_t *pObj) -{ - uint32_t readval = 0; - int32_t status = DP83848_STATUS_OK; - - if(pObj->IO.ReadReg(pObj->DevAddr, DP83848_BCR, &readval) >= 0) - { - readval |= DP83848_BCR_AUTONEGO_EN; - - /* Apply configuration */ - if(pObj->IO.WriteReg(pObj->DevAddr, DP83848_BCR, readval) < 0) - { - status = DP83848_STATUS_WRITE_ERROR; - } - } - else - { - status = DP83848_STATUS_READ_ERROR; - } - - return status; -} - -/** - * @brief Get the link state of DP83848 device. - * @param pObj: Pointer to device object. - * @param pLinkState: Pointer to link state - * @retval DP83848_STATUS_LINK_DOWN if link is down - * DP83848_STATUS_AUTONEGO_NOTDONE if Auto nego not completed - * DP83848_STATUS_100MBITS_FULLDUPLEX if 100Mb/s FD - * DP83848_STATUS_100MBITS_HALFDUPLEX if 100Mb/s HD - * DP83848_STATUS_10MBITS_FULLDUPLEX if 10Mb/s FD - * DP83848_STATUS_10MBITS_HALFDUPLEX if 10Mb/s HD - * DP83848_STATUS_READ_ERROR if connot read register - * DP83848_STATUS_WRITE_ERROR if connot write to register - */ -int32_t DP83848_GetLinkState(dp83848_Object_t *pObj) -{ - uint32_t readval = 0; - - /* Read Status register */ - if(pObj->IO.ReadReg(pObj->DevAddr, DP83848_BSR, &readval) < 0) - { - return DP83848_STATUS_READ_ERROR; - } - - /* Read Status register again */ - if(pObj->IO.ReadReg(pObj->DevAddr, DP83848_BSR, &readval) < 0) - { - return DP83848_STATUS_READ_ERROR; - } - - if((readval & DP83848_BSR_LINK_STATUS) == 0) - { - /* Return Link Down status */ - return DP83848_STATUS_LINK_DOWN; - } - - /* Check Auto negotiaition */ - if(pObj->IO.ReadReg(pObj->DevAddr, DP83848_BCR, &readval) < 0) - { - return DP83848_STATUS_READ_ERROR; - } - - if((readval & DP83848_BCR_AUTONEGO_EN) != DP83848_BCR_AUTONEGO_EN) - { - if(((readval & DP83848_BCR_SPEED_SELECT) == DP83848_BCR_SPEED_SELECT) && ((readval & DP83848_BCR_DUPLEX_MODE) == DP83848_BCR_DUPLEX_MODE)) - { - return DP83848_STATUS_100MBITS_FULLDUPLEX; - } - else if ((readval & DP83848_BCR_SPEED_SELECT) == DP83848_BCR_SPEED_SELECT) - { - return DP83848_STATUS_100MBITS_HALFDUPLEX; - } - else if ((readval & DP83848_BCR_DUPLEX_MODE) == DP83848_BCR_DUPLEX_MODE) - { - return DP83848_STATUS_10MBITS_FULLDUPLEX; - } - else - { - return DP83848_STATUS_10MBITS_HALFDUPLEX; - } - } - else /* Auto Nego enabled */ - { - if(pObj->IO.ReadReg(pObj->DevAddr, DP83848_PHYSCSR, &readval) < 0) - { - return DP83848_STATUS_READ_ERROR; - } - - /* Check if auto nego not done */ - if((readval & DP83848_PHYSCSR_AUTONEGO_DONE) == 0) - { - return DP83848_STATUS_AUTONEGO_NOTDONE; - } - - if((readval & DP83848_PHYSCSR_HCDSPEEDMASK) == DP83848_PHYSCSR_100BTX_FD) - { - return DP83848_STATUS_100MBITS_FULLDUPLEX; - } - else if ((readval & DP83848_PHYSCSR_HCDSPEEDMASK) == DP83848_PHYSCSR_100BTX_HD) - { - return DP83848_STATUS_100MBITS_HALFDUPLEX; - } - else if ((readval & DP83848_PHYSCSR_HCDSPEEDMASK) == DP83848_PHYSCSR_10BT_FD) - { - return DP83848_STATUS_10MBITS_FULLDUPLEX; - } - else - { - return DP83848_STATUS_10MBITS_HALFDUPLEX; - } - } -} - -/** - * @brief Set the link state of DP83848 device. - * @param pObj: Pointer to device object. - * @param pLinkState: link state can be one of the following - * DP83848_STATUS_100MBITS_FULLDUPLEX if 100Mb/s FD - * DP83848_STATUS_100MBITS_HALFDUPLEX if 100Mb/s HD - * DP83848_STATUS_10MBITS_FULLDUPLEX if 10Mb/s FD - * DP83848_STATUS_10MBITS_HALFDUPLEX if 10Mb/s HD - * @retval DP83848_STATUS_OK if OK - * DP83848_STATUS_ERROR if parameter error - * DP83848_STATUS_READ_ERROR if connot read register - * DP83848_STATUS_WRITE_ERROR if connot write to register - */ -int32_t DP83848_SetLinkState(dp83848_Object_t *pObj, uint32_t LinkState) -{ - uint32_t bcrvalue = 0; - int32_t status = DP83848_STATUS_OK; - - if(pObj->IO.ReadReg(pObj->DevAddr, DP83848_BCR, &bcrvalue) >= 0) - { - /* Disable link config (Auto nego, speed and duplex) */ - bcrvalue &= ~(DP83848_BCR_AUTONEGO_EN | DP83848_BCR_SPEED_SELECT | DP83848_BCR_DUPLEX_MODE); - - if(LinkState == DP83848_STATUS_100MBITS_FULLDUPLEX) - { - bcrvalue |= (DP83848_BCR_SPEED_SELECT | DP83848_BCR_DUPLEX_MODE); - } - else if (LinkState == DP83848_STATUS_100MBITS_HALFDUPLEX) - { - bcrvalue |= DP83848_BCR_SPEED_SELECT; - } - else if (LinkState == DP83848_STATUS_10MBITS_FULLDUPLEX) - { - bcrvalue |= DP83848_BCR_DUPLEX_MODE; - } - else - { - /* Wrong link status parameter */ - status = DP83848_STATUS_ERROR; - } - } - else - { - status = DP83848_STATUS_READ_ERROR; - } - - if(status == DP83848_STATUS_OK) - { - /* Apply configuration */ - if(pObj->IO.WriteReg(pObj->DevAddr, DP83848_BCR, bcrvalue) < 0) - { - status = DP83848_STATUS_WRITE_ERROR; - } - } - - return status; -} - -/** - * @brief Enable loopback mode. - * @param pObj: Pointer to device object. - * @retval DP83848_STATUS_OK if OK - * DP83848_STATUS_READ_ERROR if connot read register - * DP83848_STATUS_WRITE_ERROR if connot write to register - */ -int32_t DP83848_EnableLoopbackMode(dp83848_Object_t *pObj) -{ - uint32_t readval = 0; - int32_t status = DP83848_STATUS_OK; - - if(pObj->IO.ReadReg(pObj->DevAddr, DP83848_BCR, &readval) >= 0) - { - readval |= DP83848_BCR_LOOPBACK; - - /* Apply configuration */ - if(pObj->IO.WriteReg(pObj->DevAddr, DP83848_BCR, readval) < 0) - { - status = DP83848_STATUS_WRITE_ERROR; - } - } - else - { - status = DP83848_STATUS_READ_ERROR; - } - - return status; -} - -/** - * @brief Disable loopback mode. - * @param pObj: Pointer to device object. - * @retval DP83848_STATUS_OK if OK - * DP83848_STATUS_READ_ERROR if connot read register - * DP83848_STATUS_WRITE_ERROR if connot write to register - */ -int32_t DP83848_DisableLoopbackMode(dp83848_Object_t *pObj) -{ - uint32_t readval = 0; - int32_t status = DP83848_STATUS_OK; - - if(pObj->IO.ReadReg(pObj->DevAddr, DP83848_BCR, &readval) >= 0) - { - readval &= ~DP83848_BCR_LOOPBACK; - - /* Apply configuration */ - if(pObj->IO.WriteReg(pObj->DevAddr, DP83848_BCR, readval) < 0) - { - status = DP83848_STATUS_WRITE_ERROR; - } - } - else - { - status = DP83848_STATUS_READ_ERROR; - } - - return status; -} - -/** - * @brief Enable IT source. - * @param pObj: Pointer to device object. - * @param Interrupt: IT source to be enabled - * should be a value or a combination of the following: - * DP83848_WOL_IT - * DP83848_ENERGYON_IT - * DP83848_AUTONEGO_COMPLETE_IT - * DP83848_REMOTE_FAULT_IT - * DP83848_LINK_DOWN_IT - * DP83848_AUTONEGO_LP_ACK_IT - * DP83848_PARALLEL_DETECTION_FAULT_IT - * DP83848_AUTONEGO_PAGE_RECEIVED_IT - * @retval DP83848_STATUS_OK if OK - * DP83848_STATUS_READ_ERROR if connot read register - * DP83848_STATUS_WRITE_ERROR if connot write to register - */ -int32_t DP83848_EnableIT(dp83848_Object_t *pObj, uint32_t Interrupt) -{ - uint32_t readval = 0; - int32_t status = DP83848_STATUS_OK; - - if(pObj->IO.ReadReg(pObj->DevAddr, DP83848_IMR, &readval) >= 0) - { - readval |= Interrupt; - - /* Apply configuration */ - if(pObj->IO.WriteReg(pObj->DevAddr, DP83848_IMR, readval) < 0) - { - status = DP83848_STATUS_WRITE_ERROR; - } - } - else - { - status = DP83848_STATUS_READ_ERROR; - } - - return status; -} - -/** - * @brief Disable IT source. - * @param pObj: Pointer to device object. - * @param Interrupt: IT source to be disabled - * should be a value or a combination of the following: - * DP83848_WOL_IT - * DP83848_ENERGYON_IT - * DP83848_AUTONEGO_COMPLETE_IT - * DP83848_REMOTE_FAULT_IT - * DP83848_LINK_DOWN_IT - * DP83848_AUTONEGO_LP_ACK_IT - * DP83848_PARALLEL_DETECTION_FAULT_IT - * DP83848_AUTONEGO_PAGE_RECEIVED_IT - * @retval DP83848_STATUS_OK if OK - * DP83848_STATUS_READ_ERROR if connot read register - * DP83848_STATUS_WRITE_ERROR if connot write to register - */ -int32_t DP83848_DisableIT(dp83848_Object_t *pObj, uint32_t Interrupt) -{ - uint32_t readval = 0; - int32_t status = DP83848_STATUS_OK; - - if(pObj->IO.ReadReg(pObj->DevAddr, DP83848_IMR, &readval) >= 0) - { - readval &= ~Interrupt; - - /* Apply configuration */ - if(pObj->IO.WriteReg(pObj->DevAddr, DP83848_IMR, readval) < 0) - { - status = DP83848_STATUS_WRITE_ERROR; - } - } - else - { - status = DP83848_STATUS_READ_ERROR; - } - - return status; -} - -/** - * @brief Clear IT flag. - * @param pObj: Pointer to device object. - * @param Interrupt: IT flag to be cleared - * should be a value or a combination of the following: - * DP83848_WOL_IT - * DP83848_ENERGYON_IT - * DP83848_AUTONEGO_COMPLETE_IT - * DP83848_REMOTE_FAULT_IT - * DP83848_LINK_DOWN_IT - * DP83848_AUTONEGO_LP_ACK_IT - * DP83848_PARALLEL_DETECTION_FAULT_IT - * DP83848_AUTONEGO_PAGE_RECEIVED_IT - * @retval DP83848_STATUS_OK if OK - * DP83848_STATUS_READ_ERROR if connot read register - */ -int32_t DP83848_ClearIT(dp83848_Object_t *pObj, uint32_t Interrupt) -{ - uint32_t readval = 0; - int32_t status = DP83848_STATUS_OK; - - if(pObj->IO.ReadReg(pObj->DevAddr, DP83848_ISFR, &readval) < 0) - { - status = DP83848_STATUS_READ_ERROR; - } - - return status; -} - -/** - * @brief Get IT Flag status. - * @param pObj: Pointer to device object. - * @param Interrupt: IT Flag to be checked, - * should be a value or a combination of the following: - * DP83848_WOL_IT - * DP83848_ENERGYON_IT - * DP83848_AUTONEGO_COMPLETE_IT - * DP83848_REMOTE_FAULT_IT - * DP83848_LINK_DOWN_IT - * DP83848_AUTONEGO_LP_ACK_IT - * DP83848_PARALLEL_DETECTION_FAULT_IT - * DP83848_AUTONEGO_PAGE_RECEIVED_IT - * @retval 1 IT flag is SET - * 0 IT flag is RESET - * DP83848_STATUS_READ_ERROR if connot read register - */ -int32_t DP83848_GetITStatus(dp83848_Object_t *pObj, uint32_t Interrupt) -{ - uint32_t readval = 0; - int32_t status = 0; - - if(pObj->IO.ReadReg(pObj->DevAddr, DP83848_ISFR, &readval) >= 0) - { - status = ((readval & Interrupt) == Interrupt); - } - else - { - status = DP83848_STATUS_READ_ERROR; - } - - return status; -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - +/** + ****************************************************************************** + * @file dp83848.c + * @author MCD Application Team + * @brief This file provides a set of functions needed to manage the DP83848 + * PHY devices. + ****************************************************************************** + * @attention + * + * <h2><center>© Copyright (c) 2021 STMicroelectronics. + * All rights reserved.</center></h2> + * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "dp83848.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup Component + * @{ + */ + +/** @defgroup DP83848 DP83848 + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/** @defgroup DP83848_Private_Defines DP83848 Private Defines + * @{ + */ +#define DP83848_SW_RESET_TO ((uint32_t)500U) +#define DP83848_INIT_TO ((uint32_t)2000U) +#define DP83848_MAX_DEV_ADDR ((uint32_t)31U) +/** + * @} + */ + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ +/** @defgroup DP83848_Private_Functions DP83848 Private Functions + * @{ + */ + +/** + * @brief Register IO functions to component object + * @param pObj: device object of DP83848_Object_t. + * @param ioctx: holds device IO functions. + * @retval DP83848_STATUS_OK if OK + * DP83848_STATUS_ERROR if missing mandatory function + */ +int32_t DP83848_RegisterBusIO(dp83848_Object_t *pObj, dp83848_IOCtx_t *ioctx) +{ + if(!pObj || !ioctx->ReadReg || !ioctx->WriteReg || !ioctx->GetTick) + { + return DP83848_STATUS_ERROR; + } + + pObj->IO.Init = ioctx->Init; + pObj->IO.DeInit = ioctx->DeInit; + pObj->IO.ReadReg = ioctx->ReadReg; + pObj->IO.WriteReg = ioctx->WriteReg; + pObj->IO.GetTick = ioctx->GetTick; + + return DP83848_STATUS_OK; +} + +/** + * @brief Initialize the DP83848 and configure the needed hardware resources + * @param pObj: device object DP83848_Object_t. + * @retval DP83848_STATUS_OK if OK + * DP83848_STATUS_ADDRESS_ERROR if cannot find device address + * DP83848_STATUS_READ_ERROR if connot read register + * DP83848_STATUS_WRITE_ERROR if connot write to register + * DP83848_STATUS_RESET_TIMEOUT if cannot perform a software reset + */ + int32_t DP83848_Init(dp83848_Object_t *pObj) + { + uint32_t tickstart = 0, regvalue = 0, addr = 0; + int32_t status = DP83848_STATUS_OK; + + if(pObj->Is_Initialized == 0) + { + if(pObj->IO.Init != 0) + { + /* GPIO and Clocks initialization */ + pObj->IO.Init(); + } + + /* for later check */ + pObj->DevAddr = DP83848_MAX_DEV_ADDR + 1; + + /* Get the device address from special mode register */ + for(addr = 0; addr <= DP83848_MAX_DEV_ADDR; addr ++) + { + if(pObj->IO.ReadReg(addr, DP83848_SMR, ®value) < 0) + { + status = DP83848_STATUS_READ_ERROR; + /* Can't read from this device address + continue with next address */ + continue; + } + + if((regvalue & DP83848_SMR_PHY_ADDR) == addr) + { + pObj->DevAddr = addr; + status = DP83848_STATUS_OK; + break; + } + } + + if(pObj->DevAddr > DP83848_MAX_DEV_ADDR) + { + status = DP83848_STATUS_ADDRESS_ERROR; + } + + /* if device address is matched */ + if(status == DP83848_STATUS_OK) + { + /* set a software reset */ + if(pObj->IO.WriteReg(pObj->DevAddr, DP83848_BCR, DP83848_BCR_SOFT_RESET) >= 0) + { + /* get software reset status */ + if(pObj->IO.ReadReg(pObj->DevAddr, DP83848_BCR, ®value) >= 0) + { + tickstart = pObj->IO.GetTick(); + + /* wait until software reset is done or timeout occured */ + while(regvalue & DP83848_BCR_SOFT_RESET) + { + if((pObj->IO.GetTick() - tickstart) <= DP83848_SW_RESET_TO) + { + if(pObj->IO.ReadReg(pObj->DevAddr, DP83848_BCR, ®value) < 0) + { + status = DP83848_STATUS_READ_ERROR; + break; + } + } + else + { + status = DP83848_STATUS_RESET_TIMEOUT; + break; + } + } + } + else + { + status = DP83848_STATUS_READ_ERROR; + } + } + else + { + status = DP83848_STATUS_WRITE_ERROR; + } + } + } + + if(status == DP83848_STATUS_OK) + { + tickstart = pObj->IO.GetTick(); + + /* Wait for 2s to perform initialization */ + while((pObj->IO.GetTick() - tickstart) <= DP83848_INIT_TO) + { + } + pObj->Is_Initialized = 1; + } + + return status; + } + +/** + * @brief De-Initialize the dp83848 and it's hardware resources + * @param pObj: device object DP83848_Object_t. + * @retval None + */ +int32_t DP83848_DeInit(dp83848_Object_t *pObj) +{ + if(pObj->Is_Initialized) + { + if(pObj->IO.DeInit != 0) + { + if(pObj->IO.DeInit() < 0) + { + return DP83848_STATUS_ERROR; + } + } + + pObj->Is_Initialized = 0; + } + + return DP83848_STATUS_OK; +} + +/** + * @brief Disable the DP83848 power down mode. + * @param pObj: device object DP83848_Object_t. + * @retval DP83848_STATUS_OK if OK + * DP83848_STATUS_READ_ERROR if connot read register + * DP83848_STATUS_WRITE_ERROR if connot write to register + */ +int32_t DP83848_DisablePowerDownMode(dp83848_Object_t *pObj) +{ + uint32_t readval = 0; + int32_t status = DP83848_STATUS_OK; + + if(pObj->IO.ReadReg(pObj->DevAddr, DP83848_BCR, &readval) >= 0) + { + readval &= ~DP83848_BCR_POWER_DOWN; + + /* Apply configuration */ + if(pObj->IO.WriteReg(pObj->DevAddr, DP83848_BCR, readval) < 0) + { + status = DP83848_STATUS_WRITE_ERROR; + } + } + else + { + status = DP83848_STATUS_READ_ERROR; + } + + return status; +} + +/** + * @brief Enable the DP83848 power down mode. + * @param pObj: device object DP83848_Object_t. + * @retval DP83848_STATUS_OK if OK + * DP83848_STATUS_READ_ERROR if connot read register + * DP83848_STATUS_WRITE_ERROR if connot write to register + */ +int32_t DP83848_EnablePowerDownMode(dp83848_Object_t *pObj) +{ + uint32_t readval = 0; + int32_t status = DP83848_STATUS_OK; + + if(pObj->IO.ReadReg(pObj->DevAddr, DP83848_BCR, &readval) >= 0) + { + readval |= DP83848_BCR_POWER_DOWN; + + /* Apply configuration */ + if(pObj->IO.WriteReg(pObj->DevAddr, DP83848_BCR, readval) < 0) + { + status = DP83848_STATUS_WRITE_ERROR; + } + } + else + { + status = DP83848_STATUS_READ_ERROR; + } + + return status; +} + +/** + * @brief Start the auto negotiation process. + * @param pObj: device object DP83848_Object_t. + * @retval DP83848_STATUS_OK if OK + * DP83848_STATUS_READ_ERROR if connot read register + * DP83848_STATUS_WRITE_ERROR if connot write to register + */ +int32_t DP83848_StartAutoNego(dp83848_Object_t *pObj) +{ + uint32_t readval = 0; + int32_t status = DP83848_STATUS_OK; + + if(pObj->IO.ReadReg(pObj->DevAddr, DP83848_BCR, &readval) >= 0) + { + readval |= DP83848_BCR_AUTONEGO_EN; + + /* Apply configuration */ + if(pObj->IO.WriteReg(pObj->DevAddr, DP83848_BCR, readval) < 0) + { + status = DP83848_STATUS_WRITE_ERROR; + } + } + else + { + status = DP83848_STATUS_READ_ERROR; + } + + return status; +} + +/** + * @brief Get the link state of DP83848 device. + * @param pObj: Pointer to device object. + * @param pLinkState: Pointer to link state + * @retval DP83848_STATUS_LINK_DOWN if link is down + * DP83848_STATUS_AUTONEGO_NOTDONE if Auto nego not completed + * DP83848_STATUS_100MBITS_FULLDUPLEX if 100Mb/s FD + * DP83848_STATUS_100MBITS_HALFDUPLEX if 100Mb/s HD + * DP83848_STATUS_10MBITS_FULLDUPLEX if 10Mb/s FD + * DP83848_STATUS_10MBITS_HALFDUPLEX if 10Mb/s HD + * DP83848_STATUS_READ_ERROR if connot read register + * DP83848_STATUS_WRITE_ERROR if connot write to register + */ +int32_t DP83848_GetLinkState(dp83848_Object_t *pObj) +{ + uint32_t readval = 0; + + /* Read Status register */ + if(pObj->IO.ReadReg(pObj->DevAddr, DP83848_BSR, &readval) < 0) + { + return DP83848_STATUS_READ_ERROR; + } + + /* Read Status register again */ + if(pObj->IO.ReadReg(pObj->DevAddr, DP83848_BSR, &readval) < 0) + { + return DP83848_STATUS_READ_ERROR; + } + + if((readval & DP83848_BSR_LINK_STATUS) == 0) + { + /* Return Link Down status */ + return DP83848_STATUS_LINK_DOWN; + } + + /* Check Auto negotiaition */ + if(pObj->IO.ReadReg(pObj->DevAddr, DP83848_BCR, &readval) < 0) + { + return DP83848_STATUS_READ_ERROR; + } + + if((readval & DP83848_BCR_AUTONEGO_EN) != DP83848_BCR_AUTONEGO_EN) + { + if(((readval & DP83848_BCR_SPEED_SELECT) == DP83848_BCR_SPEED_SELECT) && ((readval & DP83848_BCR_DUPLEX_MODE) == DP83848_BCR_DUPLEX_MODE)) + { + return DP83848_STATUS_100MBITS_FULLDUPLEX; + } + else if ((readval & DP83848_BCR_SPEED_SELECT) == DP83848_BCR_SPEED_SELECT) + { + return DP83848_STATUS_100MBITS_HALFDUPLEX; + } + else if ((readval & DP83848_BCR_DUPLEX_MODE) == DP83848_BCR_DUPLEX_MODE) + { + return DP83848_STATUS_10MBITS_FULLDUPLEX; + } + else + { + return DP83848_STATUS_10MBITS_HALFDUPLEX; + } + } + else /* Auto Nego enabled */ + { + if(pObj->IO.ReadReg(pObj->DevAddr, DP83848_PHYSCSR, &readval) < 0) + { + return DP83848_STATUS_READ_ERROR; + } + + /* Check if auto nego not done */ + if((readval & DP83848_PHYSCSR_AUTONEGO_DONE) == 0) + { + return DP83848_STATUS_AUTONEGO_NOTDONE; + } + + if((readval & DP83848_PHYSCSR_HCDSPEEDMASK) == DP83848_PHYSCSR_100BTX_FD) + { + return DP83848_STATUS_100MBITS_FULLDUPLEX; + } + else if ((readval & DP83848_PHYSCSR_HCDSPEEDMASK) == DP83848_PHYSCSR_100BTX_HD) + { + return DP83848_STATUS_100MBITS_HALFDUPLEX; + } + else if ((readval & DP83848_PHYSCSR_HCDSPEEDMASK) == DP83848_PHYSCSR_10BT_FD) + { + return DP83848_STATUS_10MBITS_FULLDUPLEX; + } + else + { + return DP83848_STATUS_10MBITS_HALFDUPLEX; + } + } +} + +/** + * @brief Set the link state of DP83848 device. + * @param pObj: Pointer to device object. + * @param pLinkState: link state can be one of the following + * DP83848_STATUS_100MBITS_FULLDUPLEX if 100Mb/s FD + * DP83848_STATUS_100MBITS_HALFDUPLEX if 100Mb/s HD + * DP83848_STATUS_10MBITS_FULLDUPLEX if 10Mb/s FD + * DP83848_STATUS_10MBITS_HALFDUPLEX if 10Mb/s HD + * @retval DP83848_STATUS_OK if OK + * DP83848_STATUS_ERROR if parameter error + * DP83848_STATUS_READ_ERROR if connot read register + * DP83848_STATUS_WRITE_ERROR if connot write to register + */ +int32_t DP83848_SetLinkState(dp83848_Object_t *pObj, uint32_t LinkState) +{ + uint32_t bcrvalue = 0; + int32_t status = DP83848_STATUS_OK; + + if(pObj->IO.ReadReg(pObj->DevAddr, DP83848_BCR, &bcrvalue) >= 0) + { + /* Disable link config (Auto nego, speed and duplex) */ + bcrvalue &= ~(DP83848_BCR_AUTONEGO_EN | DP83848_BCR_SPEED_SELECT | DP83848_BCR_DUPLEX_MODE); + + if(LinkState == DP83848_STATUS_100MBITS_FULLDUPLEX) + { + bcrvalue |= (DP83848_BCR_SPEED_SELECT | DP83848_BCR_DUPLEX_MODE); + } + else if (LinkState == DP83848_STATUS_100MBITS_HALFDUPLEX) + { + bcrvalue |= DP83848_BCR_SPEED_SELECT; + } + else if (LinkState == DP83848_STATUS_10MBITS_FULLDUPLEX) + { + bcrvalue |= DP83848_BCR_DUPLEX_MODE; + } + else + { + /* Wrong link status parameter */ + status = DP83848_STATUS_ERROR; + } + } + else + { + status = DP83848_STATUS_READ_ERROR; + } + + if(status == DP83848_STATUS_OK) + { + /* Apply configuration */ + if(pObj->IO.WriteReg(pObj->DevAddr, DP83848_BCR, bcrvalue) < 0) + { + status = DP83848_STATUS_WRITE_ERROR; + } + } + + return status; +} + +/** + * @brief Enable loopback mode. + * @param pObj: Pointer to device object. + * @retval DP83848_STATUS_OK if OK + * DP83848_STATUS_READ_ERROR if connot read register + * DP83848_STATUS_WRITE_ERROR if connot write to register + */ +int32_t DP83848_EnableLoopbackMode(dp83848_Object_t *pObj) +{ + uint32_t readval = 0; + int32_t status = DP83848_STATUS_OK; + + if(pObj->IO.ReadReg(pObj->DevAddr, DP83848_BCR, &readval) >= 0) + { + readval |= DP83848_BCR_LOOPBACK; + + /* Apply configuration */ + if(pObj->IO.WriteReg(pObj->DevAddr, DP83848_BCR, readval) < 0) + { + status = DP83848_STATUS_WRITE_ERROR; + } + } + else + { + status = DP83848_STATUS_READ_ERROR; + } + + return status; +} + +/** + * @brief Disable loopback mode. + * @param pObj: Pointer to device object. + * @retval DP83848_STATUS_OK if OK + * DP83848_STATUS_READ_ERROR if connot read register + * DP83848_STATUS_WRITE_ERROR if connot write to register + */ +int32_t DP83848_DisableLoopbackMode(dp83848_Object_t *pObj) +{ + uint32_t readval = 0; + int32_t status = DP83848_STATUS_OK; + + if(pObj->IO.ReadReg(pObj->DevAddr, DP83848_BCR, &readval) >= 0) + { + readval &= ~DP83848_BCR_LOOPBACK; + + /* Apply configuration */ + if(pObj->IO.WriteReg(pObj->DevAddr, DP83848_BCR, readval) < 0) + { + status = DP83848_STATUS_WRITE_ERROR; + } + } + else + { + status = DP83848_STATUS_READ_ERROR; + } + + return status; +} + +/** + * @brief Enable IT source. + * @param pObj: Pointer to device object. + * @param Interrupt: IT source to be enabled + * should be a value or a combination of the following: + * DP83848_WOL_IT + * DP83848_ENERGYON_IT + * DP83848_AUTONEGO_COMPLETE_IT + * DP83848_REMOTE_FAULT_IT + * DP83848_LINK_DOWN_IT + * DP83848_AUTONEGO_LP_ACK_IT + * DP83848_PARALLEL_DETECTION_FAULT_IT + * DP83848_AUTONEGO_PAGE_RECEIVED_IT + * @retval DP83848_STATUS_OK if OK + * DP83848_STATUS_READ_ERROR if connot read register + * DP83848_STATUS_WRITE_ERROR if connot write to register + */ +int32_t DP83848_EnableIT(dp83848_Object_t *pObj, uint32_t Interrupt) +{ + uint32_t readval = 0; + int32_t status = DP83848_STATUS_OK; + + if(pObj->IO.ReadReg(pObj->DevAddr, DP83848_IMR, &readval) >= 0) + { + readval |= Interrupt; + + /* Apply configuration */ + if(pObj->IO.WriteReg(pObj->DevAddr, DP83848_IMR, readval) < 0) + { + status = DP83848_STATUS_WRITE_ERROR; + } + } + else + { + status = DP83848_STATUS_READ_ERROR; + } + + return status; +} + +/** + * @brief Disable IT source. + * @param pObj: Pointer to device object. + * @param Interrupt: IT source to be disabled + * should be a value or a combination of the following: + * DP83848_WOL_IT + * DP83848_ENERGYON_IT + * DP83848_AUTONEGO_COMPLETE_IT + * DP83848_REMOTE_FAULT_IT + * DP83848_LINK_DOWN_IT + * DP83848_AUTONEGO_LP_ACK_IT + * DP83848_PARALLEL_DETECTION_FAULT_IT + * DP83848_AUTONEGO_PAGE_RECEIVED_IT + * @retval DP83848_STATUS_OK if OK + * DP83848_STATUS_READ_ERROR if connot read register + * DP83848_STATUS_WRITE_ERROR if connot write to register + */ +int32_t DP83848_DisableIT(dp83848_Object_t *pObj, uint32_t Interrupt) +{ + uint32_t readval = 0; + int32_t status = DP83848_STATUS_OK; + + if(pObj->IO.ReadReg(pObj->DevAddr, DP83848_IMR, &readval) >= 0) + { + readval &= ~Interrupt; + + /* Apply configuration */ + if(pObj->IO.WriteReg(pObj->DevAddr, DP83848_IMR, readval) < 0) + { + status = DP83848_STATUS_WRITE_ERROR; + } + } + else + { + status = DP83848_STATUS_READ_ERROR; + } + + return status; +} + +/** + * @brief Clear IT flag. + * @param pObj: Pointer to device object. + * @param Interrupt: IT flag to be cleared + * should be a value or a combination of the following: + * DP83848_WOL_IT + * DP83848_ENERGYON_IT + * DP83848_AUTONEGO_COMPLETE_IT + * DP83848_REMOTE_FAULT_IT + * DP83848_LINK_DOWN_IT + * DP83848_AUTONEGO_LP_ACK_IT + * DP83848_PARALLEL_DETECTION_FAULT_IT + * DP83848_AUTONEGO_PAGE_RECEIVED_IT + * @retval DP83848_STATUS_OK if OK + * DP83848_STATUS_READ_ERROR if connot read register + */ +int32_t DP83848_ClearIT(dp83848_Object_t *pObj, uint32_t Interrupt) +{ + uint32_t readval = 0; + int32_t status = DP83848_STATUS_OK; + + if(pObj->IO.ReadReg(pObj->DevAddr, DP83848_ISFR, &readval) < 0) + { + status = DP83848_STATUS_READ_ERROR; + } + + return status; +} + +/** + * @brief Get IT Flag status. + * @param pObj: Pointer to device object. + * @param Interrupt: IT Flag to be checked, + * should be a value or a combination of the following: + * DP83848_WOL_IT + * DP83848_ENERGYON_IT + * DP83848_AUTONEGO_COMPLETE_IT + * DP83848_REMOTE_FAULT_IT + * DP83848_LINK_DOWN_IT + * DP83848_AUTONEGO_LP_ACK_IT + * DP83848_PARALLEL_DETECTION_FAULT_IT + * DP83848_AUTONEGO_PAGE_RECEIVED_IT + * @retval 1 IT flag is SET + * 0 IT flag is RESET + * DP83848_STATUS_READ_ERROR if connot read register + */ +int32_t DP83848_GetITStatus(dp83848_Object_t *pObj, uint32_t Interrupt) +{ + uint32_t readval = 0; + int32_t status = 0; + + if(pObj->IO.ReadReg(pObj->DevAddr, DP83848_ISFR, &readval) >= 0) + { + status = ((readval & Interrupt) == Interrupt); + } + else + { + status = DP83848_STATUS_READ_ERROR; + } + + return status; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + diff --git a/stm32/driver/dp83848.h b/stm32/driver/dp83848.h index d49496d..dd921f6 100644 --- a/stm32/driver/dp83848.h +++ b/stm32/driver/dp83848.h @@ -1,436 +1,436 @@ -/** - ****************************************************************************** - * @file dp83848.h - * @author MCD Application Team - * @brief This file contains all the functions prototypes for the - * dp83848.c PHY driver. - ****************************************************************************** - * @attention - * - * <h2><center>© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.</center></h2> - * - * This software component is licensed by ST under BSD 3-Clause license, - * the "License"; You may not use this file except in compliance with the - * License. You may obtain a copy of the License at: - * opensource.org/licenses/BSD-3-Clause - * - ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef DP83848_H -#define DP83848_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include <stdint.h> - -/** @addtogroup BSP - * @{ - */ - -/** @addtogroup Component - * @{ - */ - -/** @defgroup DP83848 - * @{ - */ -/* Exported constants --------------------------------------------------------*/ -/** @defgroup DP83848_Exported_Constants DP83848 Exported Constants - * @{ - */ - -/** @defgroup DP83848_Registers_Mapping DP83848 Registers Mapping - * @{ - */ -#define DP83848_BCR ((uint16_t)0x0000U) -#define DP83848_BSR ((uint16_t)0x0001U) -#define DP83848_PHYI1R ((uint16_t)0x0002U) -#define DP83848_PHYI2R ((uint16_t)0x0003U) -#define DP83848_ANAR ((uint16_t)0x0004U) -#define DP83848_ANLPAR ((uint16_t)0x0005U) -#define DP83848_ANER ((uint16_t)0x0006U) -#define DP83848_ANNPTR ((uint16_t)0x0007U) -#define DP83848_SMR ((uint16_t)0x0019U) -#define DP83848_ISFR ((uint16_t)0x0012U) -#define DP83848_IMR ((uint16_t)0x0011U) -#define DP83848_PHYSCSR ((uint16_t)0x0010U) -/** - * @} - */ - -/** @defgroup DP83848_BCR_Bit_Definition DP83848 BCR Bit Definition - * @{ - */ -#define DP83848_BCR_SOFT_RESET ((uint16_t)0x8000U) -#define DP83848_BCR_LOOPBACK ((uint16_t)0x4000U) -#define DP83848_BCR_SPEED_SELECT ((uint16_t)0x2000U) -#define DP83848_BCR_AUTONEGO_EN ((uint16_t)0x1000U) -#define DP83848_BCR_POWER_DOWN ((uint16_t)0x0800U) -#define DP83848_BCR_ISOLATE ((uint16_t)0x0400U) -#define DP83848_BCR_RESTART_AUTONEGO ((uint16_t)0x0200U) -#define DP83848_BCR_DUPLEX_MODE ((uint16_t)0x0100U) -/** - * @} - */ - -/** @defgroup DP83848_BSR_Bit_Definition DP83848 BSR Bit Definition - * @{ - */ -#define DP83848_BSR_100BASE_T4 ((uint16_t)0x8000U) -#define DP83848_BSR_100BASE_TX_FD ((uint16_t)0x4000U) -#define DP83848_BSR_100BASE_TX_HD ((uint16_t)0x2000U) -#define DP83848_BSR_10BASE_T_FD ((uint16_t)0x1000U) -#define DP83848_BSR_10BASE_T_HD ((uint16_t)0x0800U) -#define DP83848_BSR_MF_PREAMBLE ((uint16_t)0x0040U) -#define DP83848_BSR_AUTONEGO_CPLT ((uint16_t)0x0020U) -#define DP83848_BSR_REMOTE_FAULT ((uint16_t)0x0010U) -#define DP83848_BSR_AUTONEGO_ABILITY ((uint16_t)0x0008U) -#define DP83848_BSR_LINK_STATUS ((uint16_t)0x0004U) -#define DP83848_BSR_JABBER_DETECT ((uint16_t)0x0002U) -#define DP83848_BSR_EXTENDED_CAP ((uint16_t)0x0001U) -/** - * @} - */ - -/** @defgroup DP83848_PHYI1R_Bit_Definition DP83848 PHYI1R Bit Definition - * @{ - */ -#define DP83848_PHYI1R_OUI_3_18 ((uint16_t)0xFFFFU) -/** - * @} - */ - -/** @defgroup DP83848_PHYI2R_Bit_Definition DP83848 PHYI2R Bit Definition - * @{ - */ -#define DP83848_PHYI2R_OUI_19_24 ((uint16_t)0xFC00U) -#define DP83848_PHYI2R_MODEL_NBR ((uint16_t)0x03F0U) -#define DP83848_PHYI2R_REVISION_NBR ((uint16_t)0x000FU) -/** - * @} - */ - -/** @defgroup DP83848_ANAR_Bit_Definition DP83848 ANAR Bit Definition - * @{ - */ -#define DP83848_ANAR_NEXT_PAGE ((uint16_t)0x8000U) -#define DP83848_ANAR_REMOTE_FAULT ((uint16_t)0x2000U) -#define DP83848_ANAR_PAUSE_OPERATION ((uint16_t)0x0C00U) -#define DP83848_ANAR_PO_NOPAUSE ((uint16_t)0x0000U) -#define DP83848_ANAR_PO_SYMMETRIC_PAUSE ((uint16_t)0x0400U) -#define DP83848_ANAR_PO_ASYMMETRIC_PAUSE ((uint16_t)0x0800U) -#define DP83848_ANAR_PO_ADVERTISE_SUPPORT ((uint16_t)0x0C00U) -#define DP83848_ANAR_100BASE_TX_FD ((uint16_t)0x0100U) -#define DP83848_ANAR_100BASE_TX ((uint16_t)0x0080U) -#define DP83848_ANAR_10BASE_T_FD ((uint16_t)0x0040U) -#define DP83848_ANAR_10BASE_T ((uint16_t)0x0020U) -#define DP83848_ANAR_SELECTOR_FIELD ((uint16_t)0x000FU) -/** - * @} - */ - -/** @defgroup DP83848_ANLPAR_Bit_Definition DP83848 ANLPAR Bit Definition - * @{ - */ -#define DP83848_ANLPAR_NEXT_PAGE ((uint16_t)0x8000U) -#define DP83848_ANLPAR_REMOTE_FAULT ((uint16_t)0x2000U) -#define DP83848_ANLPAR_PAUSE_OPERATION ((uint16_t)0x0C00U) -#define DP83848_ANLPAR_PO_NOPAUSE ((uint16_t)0x0000U) -#define DP83848_ANLPAR_PO_SYMMETRIC_PAUSE ((uint16_t)0x0400U) -#define DP83848_ANLPAR_PO_ASYMMETRIC_PAUSE ((uint16_t)0x0800U) -#define DP83848_ANLPAR_PO_ADVERTISE_SUPPORT ((uint16_t)0x0C00U) -#define DP83848_ANLPAR_100BASE_TX_FD ((uint16_t)0x0100U) -#define DP83848_ANLPAR_100BASE_TX ((uint16_t)0x0080U) -#define DP83848_ANLPAR_10BASE_T_FD ((uint16_t)0x0040U) -#define DP83848_ANLPAR_10BASE_T ((uint16_t)0x0020U) -#define DP83848_ANLPAR_SELECTOR_FIELD ((uint16_t)0x000FU) -/** - * @} - */ - -/** @defgroup DP83848_ANER_Bit_Definition DP83848 ANER Bit Definition - * @{ - */ -#define DP83848_ANER_RX_NP_LOCATION_ABLE ((uint16_t)0x0040U) -#define DP83848_ANER_RX_NP_STORAGE_LOCATION ((uint16_t)0x0020U) -#define DP83848_ANER_PARALLEL_DETECT_FAULT ((uint16_t)0x0010U) -#define DP83848_ANER_LP_NP_ABLE ((uint16_t)0x0008U) -#define DP83848_ANER_NP_ABLE ((uint16_t)0x0004U) -#define DP83848_ANER_PAGE_RECEIVED ((uint16_t)0x0002U) -#define DP83848_ANER_LP_AUTONEG_ABLE ((uint16_t)0x0001U) -/** - * @} - */ - -/** @defgroup DP83848_ANNPTR_Bit_Definition DP83848 ANNPTR Bit Definition - * @{ - */ -#define DP83848_ANNPTR_NEXT_PAGE ((uint16_t)0x8000U) -#define DP83848_ANNPTR_MESSAGE_PAGE ((uint16_t)0x2000U) -#define DP83848_ANNPTR_ACK2 ((uint16_t)0x1000U) -#define DP83848_ANNPTR_TOGGLE ((uint16_t)0x0800U) -#define DP83848_ANNPTR_MESSAGE_CODE ((uint16_t)0x07FFU) -/** - * @} - */ - -/** @defgroup DP83848_ANNPRR_Bit_Definition DP83848 ANNPRR Bit Definition - * @{ - */ -#define DP83848_ANNPRR_NEXT_PAGE ((uint16_t)0x8000U) -#define DP83848_ANNPRR_ACK ((uint16_t)0x4000U) -#define DP83848_ANNPRR_MESSAGE_PAGE ((uint16_t)0x2000U) -#define DP83848_ANNPRR_ACK2 ((uint16_t)0x1000U) -#define DP83848_ANNPRR_TOGGLE ((uint16_t)0x0800U) -#define DP83848_ANNPRR_MESSAGE_CODE ((uint16_t)0x07FFU) -/** - * @} - */ - -/** @defgroup DP83848_MMDACR_Bit_Definition DP83848 MMDACR Bit Definition - * @{ - */ -#define DP83848_MMDACR_MMD_FUNCTION ((uint16_t)0xC000U) -#define DP83848_MMDACR_MMD_FUNCTION_ADDR ((uint16_t)0x0000U) -#define DP83848_MMDACR_MMD_FUNCTION_DATA ((uint16_t)0x4000U) -#define DP83848_MMDACR_MMD_DEV_ADDR ((uint16_t)0x001FU) -/** - * @} - */ - -/** @defgroup DP83848_ENCTR_Bit_Definition DP83848 ENCTR Bit Definition - * @{ - */ -#define DP83848_ENCTR_TX_ENABLE ((uint16_t)0x8000U) -#define DP83848_ENCTR_TX_TIMER ((uint16_t)0x6000U) -#define DP83848_ENCTR_TX_TIMER_1S ((uint16_t)0x0000U) -#define DP83848_ENCTR_TX_TIMER_768MS ((uint16_t)0x2000U) -#define DP83848_ENCTR_TX_TIMER_512MS ((uint16_t)0x4000U) -#define DP83848_ENCTR_TX_TIMER_265MS ((uint16_t)0x6000U) -#define DP83848_ENCTR_RX_ENABLE ((uint16_t)0x1000U) -#define DP83848_ENCTR_RX_MAX_INTERVAL ((uint16_t)0x0C00U) -#define DP83848_ENCTR_RX_MAX_INTERVAL_64MS ((uint16_t)0x0000U) -#define DP83848_ENCTR_RX_MAX_INTERVAL_256MS ((uint16_t)0x0400U) -#define DP83848_ENCTR_RX_MAX_INTERVAL_512MS ((uint16_t)0x0800U) -#define DP83848_ENCTR_RX_MAX_INTERVAL_1S ((uint16_t)0x0C00U) -#define DP83848_ENCTR_EX_CROSS_OVER ((uint16_t)0x0002U) -#define DP83848_ENCTR_EX_MANUAL_CROSS_OVER ((uint16_t)0x0001U) -/** - * @} - */ - -/** @defgroup DP83848_MCSR_Bit_Definition DP83848 MCSR Bit Definition - * @{ - */ -#define DP83848_MCSR_EDPWRDOWN ((uint16_t)0x2000U) -#define DP83848_MCSR_FARLOOPBACK ((uint16_t)0x0200U) -#define DP83848_MCSR_ALTINT ((uint16_t)0x0040U) -#define DP83848_MCSR_ENERGYON ((uint16_t)0x0002U) -/** - * @} - */ - -/** @defgroup DP83848_SMR_Bit_Definition DP83848 SMR Bit Definition - * @{ - */ -#define DP83848_SMR_MODE ((uint16_t)0x00E0U) -#define DP83848_SMR_PHY_ADDR ((uint16_t)0x001FU) -/** - * @} - */ - -/** @defgroup DP83848_TPDCR_Bit_Definition DP83848 TPDCR Bit Definition - * @{ - */ -#define DP83848_TPDCR_DELAY_IN ((uint16_t)0x8000U) -#define DP83848_TPDCR_LINE_BREAK_COUNTER ((uint16_t)0x7000U) -#define DP83848_TPDCR_PATTERN_HIGH ((uint16_t)0x0FC0U) -#define DP83848_TPDCR_PATTERN_LOW ((uint16_t)0x003FU) -/** - * @} - */ - -/** @defgroup DP83848_TCSR_Bit_Definition DP83848 TCSR Bit Definition - * @{ - */ -#define DP83848_TCSR_TDR_ENABLE ((uint16_t)0x8000U) -#define DP83848_TCSR_TDR_AD_FILTER_ENABLE ((uint16_t)0x4000U) -#define DP83848_TCSR_TDR_CH_CABLE_TYPE ((uint16_t)0x0600U) -#define DP83848_TCSR_TDR_CH_CABLE_DEFAULT ((uint16_t)0x0000U) -#define DP83848_TCSR_TDR_CH_CABLE_SHORTED ((uint16_t)0x0200U) -#define DP83848_TCSR_TDR_CH_CABLE_OPEN ((uint16_t)0x0400U) -#define DP83848_TCSR_TDR_CH_CABLE_MATCH ((uint16_t)0x0600U) -#define DP83848_TCSR_TDR_CH_STATUS ((uint16_t)0x0100U) -#define DP83848_TCSR_TDR_CH_LENGTH ((uint16_t)0x00FFU) -/** - * @} - */ - -/** @defgroup DP83848_SCSIR_Bit_Definition DP83848 SCSIR Bit Definition - * @{ - */ -#define DP83848_SCSIR_AUTO_MDIX_ENABLE ((uint16_t)0x8000U) -#define DP83848_SCSIR_CHANNEL_SELECT ((uint16_t)0x2000U) -#define DP83848_SCSIR_SQE_DISABLE ((uint16_t)0x0800U) -#define DP83848_SCSIR_XPOLALITY ((uint16_t)0x0010U) -/** - * @} - */ - -/** @defgroup DP83848_CLR_Bit_Definition DP83848 CLR Bit Definition - * @{ - */ -#define DP83848_CLR_CABLE_LENGTH ((uint16_t)0xF000U) -/** - * @} - */ - -/** @defgroup DP83848_IMR_ISFR_Bit_Definition DP83848 IMR ISFR Bit Definition - * @{ - */ -#define DP83848_INT_8 ((uint16_t)0x0100U) -#define DP83848_INT_7 ((uint16_t)0x0080U) -#define DP83848_INT_6 ((uint16_t)0x0040U) -#define DP83848_INT_5 ((uint16_t)0x0020U) -#define DP83848_INT_4 ((uint16_t)0x0010U) -#define DP83848_INT_3 ((uint16_t)0x0008U) -#define DP83848_INT_2 ((uint16_t)0x0004U) -#define DP83848_INT_1 ((uint16_t)0x0002U) -/** - * @} - */ - -/** @defgroup DP83848_PHYSCSR_Bit_Definition DP83848 PHYSCSR Bit Definition - * @{ - */ -#define DP83848_PHYSCSR_AUTONEGO_DONE ((uint16_t)0x100U) -#define DP83848_PHYSCSR_HCDSPEEDMASK ((uint16_t)0x006U) -#define DP83848_PHYSCSR_10BT_HD ((uint16_t)0x002U) -#define DP83848_PHYSCSR_10BT_FD ((uint16_t)0x006U) -#define DP83848_PHYSCSR_100BTX_HD ((uint16_t)0x000U) -#define DP83848_PHYSCSR_100BTX_FD ((uint16_t)0x004U) -/** - * @} - */ - -/** @defgroup DP83848_Status DP83848 Status - * @{ - */ - -#define DP83848_STATUS_READ_ERROR ((int32_t)-5) -#define DP83848_STATUS_WRITE_ERROR ((int32_t)-4) -#define DP83848_STATUS_ADDRESS_ERROR ((int32_t)-3) -#define DP83848_STATUS_RESET_TIMEOUT ((int32_t)-2) -#define DP83848_STATUS_ERROR ((int32_t)-1) -#define DP83848_STATUS_OK ((int32_t) 0) -#define DP83848_STATUS_LINK_DOWN ((int32_t) 1) -#define DP83848_STATUS_100MBITS_FULLDUPLEX ((int32_t) 2) -#define DP83848_STATUS_100MBITS_HALFDUPLEX ((int32_t) 3) -#define DP83848_STATUS_10MBITS_FULLDUPLEX ((int32_t) 4) -#define DP83848_STATUS_10MBITS_HALFDUPLEX ((int32_t) 5) -#define DP83848_STATUS_AUTONEGO_NOTDONE ((int32_t) 6) -/** - * @} - */ - -/** @defgroup DP83848_IT_Flags DP83848 IT Flags - * @{ - */ -#define DP83848_WOL_IT DP83848_INT_8 -#define DP83848_ENERGYON_IT DP83848_INT_7 -#define DP83848_AUTONEGO_COMPLETE_IT DP83848_INT_6 -#define DP83848_REMOTE_FAULT_IT DP83848_INT_5 -#define DP83848_LINK_DOWN_IT DP83848_INT_4 -#define DP83848_AUTONEGO_LP_ACK_IT DP83848_INT_3 -#define DP83848_PARALLEL_DETECTION_FAULT_IT DP83848_INT_2 -#define DP83848_AUTONEGO_PAGE_RECEIVED_IT DP83848_INT_1 -/** - * @} - */ - -/** - * @} - */ - -/* Exported types ------------------------------------------------------------*/ -/** @defgroup DP83848_Exported_Types DP83848 Exported Types - * @{ - */ -typedef int32_t (*dp83848_Init_Func) (void); -typedef int32_t (*dp83848_DeInit_Func) (void); -typedef int32_t (*dp83848_ReadReg_Func) (uint32_t, uint32_t, uint32_t *); -typedef int32_t (*dp83848_WriteReg_Func) (uint32_t, uint32_t, uint32_t); -typedef int32_t (*dp83848_GetTick_Func) (void); - -typedef struct -{ - dp83848_Init_Func Init; - dp83848_DeInit_Func DeInit; - dp83848_WriteReg_Func WriteReg; - dp83848_ReadReg_Func ReadReg; - dp83848_GetTick_Func GetTick; -} dp83848_IOCtx_t; - - -typedef struct -{ - uint32_t DevAddr; - uint32_t Is_Initialized; - dp83848_IOCtx_t IO; - void *pData; -}dp83848_Object_t; -/** - * @} - */ - -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions --------------------------------------------------------*/ -/** @defgroup DP83848_Exported_Functions DP83848 Exported Functions - * @{ - */ -int32_t DP83848_RegisterBusIO(dp83848_Object_t *pObj, dp83848_IOCtx_t *ioctx); -int32_t DP83848_Init(dp83848_Object_t *pObj); -int32_t DP83848_DeInit(dp83848_Object_t *pObj); -int32_t DP83848_DisablePowerDownMode(dp83848_Object_t *pObj); -int32_t DP83848_EnablePowerDownMode(dp83848_Object_t *pObj); -int32_t DP83848_StartAutoNego(dp83848_Object_t *pObj); -int32_t DP83848_GetLinkState(dp83848_Object_t *pObj); -int32_t DP83848_SetLinkState(dp83848_Object_t *pObj, uint32_t LinkState); -int32_t DP83848_EnableLoopbackMode(dp83848_Object_t *pObj); -int32_t DP83848_DisableLoopbackMode(dp83848_Object_t *pObj); -int32_t DP83848_EnableIT(dp83848_Object_t *pObj, uint32_t Interrupt); -int32_t DP83848_DisableIT(dp83848_Object_t *pObj, uint32_t Interrupt); -int32_t DP83848_ClearIT(dp83848_Object_t *pObj, uint32_t Interrupt); -int32_t DP83848_GetITStatus(dp83848_Object_t *pObj, uint32_t Interrupt); -/** - * @} - */ - -#ifdef __cplusplus -} -#endif -#endif /* DP83848_H */ - - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - +/** + ****************************************************************************** + * @file dp83848.h + * @author MCD Application Team + * @brief This file contains all the functions prototypes for the + * dp83848.c PHY driver. + ****************************************************************************** + * @attention + * + * <h2><center>© Copyright (c) 2021 STMicroelectronics. + * All rights reserved.</center></h2> + * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef DP83848_H +#define DP83848_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include <stdint.h> + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup Component + * @{ + */ + +/** @defgroup DP83848 + * @{ + */ +/* Exported constants --------------------------------------------------------*/ +/** @defgroup DP83848_Exported_Constants DP83848 Exported Constants + * @{ + */ + +/** @defgroup DP83848_Registers_Mapping DP83848 Registers Mapping + * @{ + */ +#define DP83848_BCR ((uint16_t)0x0000U) +#define DP83848_BSR ((uint16_t)0x0001U) +#define DP83848_PHYI1R ((uint16_t)0x0002U) +#define DP83848_PHYI2R ((uint16_t)0x0003U) +#define DP83848_ANAR ((uint16_t)0x0004U) +#define DP83848_ANLPAR ((uint16_t)0x0005U) +#define DP83848_ANER ((uint16_t)0x0006U) +#define DP83848_ANNPTR ((uint16_t)0x0007U) +#define DP83848_SMR ((uint16_t)0x0019U) +#define DP83848_ISFR ((uint16_t)0x0012U) +#define DP83848_IMR ((uint16_t)0x0011U) +#define DP83848_PHYSCSR ((uint16_t)0x0010U) +/** + * @} + */ + +/** @defgroup DP83848_BCR_Bit_Definition DP83848 BCR Bit Definition + * @{ + */ +#define DP83848_BCR_SOFT_RESET ((uint16_t)0x8000U) +#define DP83848_BCR_LOOPBACK ((uint16_t)0x4000U) +#define DP83848_BCR_SPEED_SELECT ((uint16_t)0x2000U) +#define DP83848_BCR_AUTONEGO_EN ((uint16_t)0x1000U) +#define DP83848_BCR_POWER_DOWN ((uint16_t)0x0800U) +#define DP83848_BCR_ISOLATE ((uint16_t)0x0400U) +#define DP83848_BCR_RESTART_AUTONEGO ((uint16_t)0x0200U) +#define DP83848_BCR_DUPLEX_MODE ((uint16_t)0x0100U) +/** + * @} + */ + +/** @defgroup DP83848_BSR_Bit_Definition DP83848 BSR Bit Definition + * @{ + */ +#define DP83848_BSR_100BASE_T4 ((uint16_t)0x8000U) +#define DP83848_BSR_100BASE_TX_FD ((uint16_t)0x4000U) +#define DP83848_BSR_100BASE_TX_HD ((uint16_t)0x2000U) +#define DP83848_BSR_10BASE_T_FD ((uint16_t)0x1000U) +#define DP83848_BSR_10BASE_T_HD ((uint16_t)0x0800U) +#define DP83848_BSR_MF_PREAMBLE ((uint16_t)0x0040U) +#define DP83848_BSR_AUTONEGO_CPLT ((uint16_t)0x0020U) +#define DP83848_BSR_REMOTE_FAULT ((uint16_t)0x0010U) +#define DP83848_BSR_AUTONEGO_ABILITY ((uint16_t)0x0008U) +#define DP83848_BSR_LINK_STATUS ((uint16_t)0x0004U) +#define DP83848_BSR_JABBER_DETECT ((uint16_t)0x0002U) +#define DP83848_BSR_EXTENDED_CAP ((uint16_t)0x0001U) +/** + * @} + */ + +/** @defgroup DP83848_PHYI1R_Bit_Definition DP83848 PHYI1R Bit Definition + * @{ + */ +#define DP83848_PHYI1R_OUI_3_18 ((uint16_t)0xFFFFU) +/** + * @} + */ + +/** @defgroup DP83848_PHYI2R_Bit_Definition DP83848 PHYI2R Bit Definition + * @{ + */ +#define DP83848_PHYI2R_OUI_19_24 ((uint16_t)0xFC00U) +#define DP83848_PHYI2R_MODEL_NBR ((uint16_t)0x03F0U) +#define DP83848_PHYI2R_REVISION_NBR ((uint16_t)0x000FU) +/** + * @} + */ + +/** @defgroup DP83848_ANAR_Bit_Definition DP83848 ANAR Bit Definition + * @{ + */ +#define DP83848_ANAR_NEXT_PAGE ((uint16_t)0x8000U) +#define DP83848_ANAR_REMOTE_FAULT ((uint16_t)0x2000U) +#define DP83848_ANAR_PAUSE_OPERATION ((uint16_t)0x0C00U) +#define DP83848_ANAR_PO_NOPAUSE ((uint16_t)0x0000U) +#define DP83848_ANAR_PO_SYMMETRIC_PAUSE ((uint16_t)0x0400U) +#define DP83848_ANAR_PO_ASYMMETRIC_PAUSE ((uint16_t)0x0800U) +#define DP83848_ANAR_PO_ADVERTISE_SUPPORT ((uint16_t)0x0C00U) +#define DP83848_ANAR_100BASE_TX_FD ((uint16_t)0x0100U) +#define DP83848_ANAR_100BASE_TX ((uint16_t)0x0080U) +#define DP83848_ANAR_10BASE_T_FD ((uint16_t)0x0040U) +#define DP83848_ANAR_10BASE_T ((uint16_t)0x0020U) +#define DP83848_ANAR_SELECTOR_FIELD ((uint16_t)0x000FU) +/** + * @} + */ + +/** @defgroup DP83848_ANLPAR_Bit_Definition DP83848 ANLPAR Bit Definition + * @{ + */ +#define DP83848_ANLPAR_NEXT_PAGE ((uint16_t)0x8000U) +#define DP83848_ANLPAR_REMOTE_FAULT ((uint16_t)0x2000U) +#define DP83848_ANLPAR_PAUSE_OPERATION ((uint16_t)0x0C00U) +#define DP83848_ANLPAR_PO_NOPAUSE ((uint16_t)0x0000U) +#define DP83848_ANLPAR_PO_SYMMETRIC_PAUSE ((uint16_t)0x0400U) +#define DP83848_ANLPAR_PO_ASYMMETRIC_PAUSE ((uint16_t)0x0800U) +#define DP83848_ANLPAR_PO_ADVERTISE_SUPPORT ((uint16_t)0x0C00U) +#define DP83848_ANLPAR_100BASE_TX_FD ((uint16_t)0x0100U) +#define DP83848_ANLPAR_100BASE_TX ((uint16_t)0x0080U) +#define DP83848_ANLPAR_10BASE_T_FD ((uint16_t)0x0040U) +#define DP83848_ANLPAR_10BASE_T ((uint16_t)0x0020U) +#define DP83848_ANLPAR_SELECTOR_FIELD ((uint16_t)0x000FU) +/** + * @} + */ + +/** @defgroup DP83848_ANER_Bit_Definition DP83848 ANER Bit Definition + * @{ + */ +#define DP83848_ANER_RX_NP_LOCATION_ABLE ((uint16_t)0x0040U) +#define DP83848_ANER_RX_NP_STORAGE_LOCATION ((uint16_t)0x0020U) +#define DP83848_ANER_PARALLEL_DETECT_FAULT ((uint16_t)0x0010U) +#define DP83848_ANER_LP_NP_ABLE ((uint16_t)0x0008U) +#define DP83848_ANER_NP_ABLE ((uint16_t)0x0004U) +#define DP83848_ANER_PAGE_RECEIVED ((uint16_t)0x0002U) +#define DP83848_ANER_LP_AUTONEG_ABLE ((uint16_t)0x0001U) +/** + * @} + */ + +/** @defgroup DP83848_ANNPTR_Bit_Definition DP83848 ANNPTR Bit Definition + * @{ + */ +#define DP83848_ANNPTR_NEXT_PAGE ((uint16_t)0x8000U) +#define DP83848_ANNPTR_MESSAGE_PAGE ((uint16_t)0x2000U) +#define DP83848_ANNPTR_ACK2 ((uint16_t)0x1000U) +#define DP83848_ANNPTR_TOGGLE ((uint16_t)0x0800U) +#define DP83848_ANNPTR_MESSAGE_CODE ((uint16_t)0x07FFU) +/** + * @} + */ + +/** @defgroup DP83848_ANNPRR_Bit_Definition DP83848 ANNPRR Bit Definition + * @{ + */ +#define DP83848_ANNPRR_NEXT_PAGE ((uint16_t)0x8000U) +#define DP83848_ANNPRR_ACK ((uint16_t)0x4000U) +#define DP83848_ANNPRR_MESSAGE_PAGE ((uint16_t)0x2000U) +#define DP83848_ANNPRR_ACK2 ((uint16_t)0x1000U) +#define DP83848_ANNPRR_TOGGLE ((uint16_t)0x0800U) +#define DP83848_ANNPRR_MESSAGE_CODE ((uint16_t)0x07FFU) +/** + * @} + */ + +/** @defgroup DP83848_MMDACR_Bit_Definition DP83848 MMDACR Bit Definition + * @{ + */ +#define DP83848_MMDACR_MMD_FUNCTION ((uint16_t)0xC000U) +#define DP83848_MMDACR_MMD_FUNCTION_ADDR ((uint16_t)0x0000U) +#define DP83848_MMDACR_MMD_FUNCTION_DATA ((uint16_t)0x4000U) +#define DP83848_MMDACR_MMD_DEV_ADDR ((uint16_t)0x001FU) +/** + * @} + */ + +/** @defgroup DP83848_ENCTR_Bit_Definition DP83848 ENCTR Bit Definition + * @{ + */ +#define DP83848_ENCTR_TX_ENABLE ((uint16_t)0x8000U) +#define DP83848_ENCTR_TX_TIMER ((uint16_t)0x6000U) +#define DP83848_ENCTR_TX_TIMER_1S ((uint16_t)0x0000U) +#define DP83848_ENCTR_TX_TIMER_768MS ((uint16_t)0x2000U) +#define DP83848_ENCTR_TX_TIMER_512MS ((uint16_t)0x4000U) +#define DP83848_ENCTR_TX_TIMER_265MS ((uint16_t)0x6000U) +#define DP83848_ENCTR_RX_ENABLE ((uint16_t)0x1000U) +#define DP83848_ENCTR_RX_MAX_INTERVAL ((uint16_t)0x0C00U) +#define DP83848_ENCTR_RX_MAX_INTERVAL_64MS ((uint16_t)0x0000U) +#define DP83848_ENCTR_RX_MAX_INTERVAL_256MS ((uint16_t)0x0400U) +#define DP83848_ENCTR_RX_MAX_INTERVAL_512MS ((uint16_t)0x0800U) +#define DP83848_ENCTR_RX_MAX_INTERVAL_1S ((uint16_t)0x0C00U) +#define DP83848_ENCTR_EX_CROSS_OVER ((uint16_t)0x0002U) +#define DP83848_ENCTR_EX_MANUAL_CROSS_OVER ((uint16_t)0x0001U) +/** + * @} + */ + +/** @defgroup DP83848_MCSR_Bit_Definition DP83848 MCSR Bit Definition + * @{ + */ +#define DP83848_MCSR_EDPWRDOWN ((uint16_t)0x2000U) +#define DP83848_MCSR_FARLOOPBACK ((uint16_t)0x0200U) +#define DP83848_MCSR_ALTINT ((uint16_t)0x0040U) +#define DP83848_MCSR_ENERGYON ((uint16_t)0x0002U) +/** + * @} + */ + +/** @defgroup DP83848_SMR_Bit_Definition DP83848 SMR Bit Definition + * @{ + */ +#define DP83848_SMR_MODE ((uint16_t)0x00E0U) +#define DP83848_SMR_PHY_ADDR ((uint16_t)0x001FU) +/** + * @} + */ + +/** @defgroup DP83848_TPDCR_Bit_Definition DP83848 TPDCR Bit Definition + * @{ + */ +#define DP83848_TPDCR_DELAY_IN ((uint16_t)0x8000U) +#define DP83848_TPDCR_LINE_BREAK_COUNTER ((uint16_t)0x7000U) +#define DP83848_TPDCR_PATTERN_HIGH ((uint16_t)0x0FC0U) +#define DP83848_TPDCR_PATTERN_LOW ((uint16_t)0x003FU) +/** + * @} + */ + +/** @defgroup DP83848_TCSR_Bit_Definition DP83848 TCSR Bit Definition + * @{ + */ +#define DP83848_TCSR_TDR_ENABLE ((uint16_t)0x8000U) +#define DP83848_TCSR_TDR_AD_FILTER_ENABLE ((uint16_t)0x4000U) +#define DP83848_TCSR_TDR_CH_CABLE_TYPE ((uint16_t)0x0600U) +#define DP83848_TCSR_TDR_CH_CABLE_DEFAULT ((uint16_t)0x0000U) +#define DP83848_TCSR_TDR_CH_CABLE_SHORTED ((uint16_t)0x0200U) +#define DP83848_TCSR_TDR_CH_CABLE_OPEN ((uint16_t)0x0400U) +#define DP83848_TCSR_TDR_CH_CABLE_MATCH ((uint16_t)0x0600U) +#define DP83848_TCSR_TDR_CH_STATUS ((uint16_t)0x0100U) +#define DP83848_TCSR_TDR_CH_LENGTH ((uint16_t)0x00FFU) +/** + * @} + */ + +/** @defgroup DP83848_SCSIR_Bit_Definition DP83848 SCSIR Bit Definition + * @{ + */ +#define DP83848_SCSIR_AUTO_MDIX_ENABLE ((uint16_t)0x8000U) +#define DP83848_SCSIR_CHANNEL_SELECT ((uint16_t)0x2000U) +#define DP83848_SCSIR_SQE_DISABLE ((uint16_t)0x0800U) +#define DP83848_SCSIR_XPOLALITY ((uint16_t)0x0010U) +/** + * @} + */ + +/** @defgroup DP83848_CLR_Bit_Definition DP83848 CLR Bit Definition + * @{ + */ +#define DP83848_CLR_CABLE_LENGTH ((uint16_t)0xF000U) +/** + * @} + */ + +/** @defgroup DP83848_IMR_ISFR_Bit_Definition DP83848 IMR ISFR Bit Definition + * @{ + */ +#define DP83848_INT_8 ((uint16_t)0x0100U) +#define DP83848_INT_7 ((uint16_t)0x0080U) +#define DP83848_INT_6 ((uint16_t)0x0040U) +#define DP83848_INT_5 ((uint16_t)0x0020U) +#define DP83848_INT_4 ((uint16_t)0x0010U) +#define DP83848_INT_3 ((uint16_t)0x0008U) +#define DP83848_INT_2 ((uint16_t)0x0004U) +#define DP83848_INT_1 ((uint16_t)0x0002U) +/** + * @} + */ + +/** @defgroup DP83848_PHYSCSR_Bit_Definition DP83848 PHYSCSR Bit Definition + * @{ + */ +#define DP83848_PHYSCSR_AUTONEGO_DONE ((uint16_t)0x100U) +#define DP83848_PHYSCSR_HCDSPEEDMASK ((uint16_t)0x006U) +#define DP83848_PHYSCSR_10BT_HD ((uint16_t)0x002U) +#define DP83848_PHYSCSR_10BT_FD ((uint16_t)0x006U) +#define DP83848_PHYSCSR_100BTX_HD ((uint16_t)0x000U) +#define DP83848_PHYSCSR_100BTX_FD ((uint16_t)0x004U) +/** + * @} + */ + +/** @defgroup DP83848_Status DP83848 Status + * @{ + */ + +#define DP83848_STATUS_READ_ERROR ((int32_t)-5) +#define DP83848_STATUS_WRITE_ERROR ((int32_t)-4) +#define DP83848_STATUS_ADDRESS_ERROR ((int32_t)-3) +#define DP83848_STATUS_RESET_TIMEOUT ((int32_t)-2) +#define DP83848_STATUS_ERROR ((int32_t)-1) +#define DP83848_STATUS_OK ((int32_t) 0) +#define DP83848_STATUS_LINK_DOWN ((int32_t) 1) +#define DP83848_STATUS_100MBITS_FULLDUPLEX ((int32_t) 2) +#define DP83848_STATUS_100MBITS_HALFDUPLEX ((int32_t) 3) +#define DP83848_STATUS_10MBITS_FULLDUPLEX ((int32_t) 4) +#define DP83848_STATUS_10MBITS_HALFDUPLEX ((int32_t) 5) +#define DP83848_STATUS_AUTONEGO_NOTDONE ((int32_t) 6) +/** + * @} + */ + +/** @defgroup DP83848_IT_Flags DP83848 IT Flags + * @{ + */ +#define DP83848_WOL_IT DP83848_INT_8 +#define DP83848_ENERGYON_IT DP83848_INT_7 +#define DP83848_AUTONEGO_COMPLETE_IT DP83848_INT_6 +#define DP83848_REMOTE_FAULT_IT DP83848_INT_5 +#define DP83848_LINK_DOWN_IT DP83848_INT_4 +#define DP83848_AUTONEGO_LP_ACK_IT DP83848_INT_3 +#define DP83848_PARALLEL_DETECTION_FAULT_IT DP83848_INT_2 +#define DP83848_AUTONEGO_PAGE_RECEIVED_IT DP83848_INT_1 +/** + * @} + */ + +/** + * @} + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup DP83848_Exported_Types DP83848 Exported Types + * @{ + */ +typedef int32_t (*dp83848_Init_Func) (void); +typedef int32_t (*dp83848_DeInit_Func) (void); +typedef int32_t (*dp83848_ReadReg_Func) (uint32_t, uint32_t, uint32_t *); +typedef int32_t (*dp83848_WriteReg_Func) (uint32_t, uint32_t, uint32_t); +typedef int32_t (*dp83848_GetTick_Func) (void); + +typedef struct +{ + dp83848_Init_Func Init; + dp83848_DeInit_Func DeInit; + dp83848_WriteReg_Func WriteReg; + dp83848_ReadReg_Func ReadReg; + dp83848_GetTick_Func GetTick; +} dp83848_IOCtx_t; + + +typedef struct +{ + uint32_t DevAddr; + uint32_t Is_Initialized; + dp83848_IOCtx_t IO; + void *pData; +}dp83848_Object_t; +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ +/** @defgroup DP83848_Exported_Functions DP83848 Exported Functions + * @{ + */ +int32_t DP83848_RegisterBusIO(dp83848_Object_t *pObj, dp83848_IOCtx_t *ioctx); +int32_t DP83848_Init(dp83848_Object_t *pObj); +int32_t DP83848_DeInit(dp83848_Object_t *pObj); +int32_t DP83848_DisablePowerDownMode(dp83848_Object_t *pObj); +int32_t DP83848_EnablePowerDownMode(dp83848_Object_t *pObj); +int32_t DP83848_StartAutoNego(dp83848_Object_t *pObj); +int32_t DP83848_GetLinkState(dp83848_Object_t *pObj); +int32_t DP83848_SetLinkState(dp83848_Object_t *pObj, uint32_t LinkState); +int32_t DP83848_EnableLoopbackMode(dp83848_Object_t *pObj); +int32_t DP83848_DisableLoopbackMode(dp83848_Object_t *pObj); +int32_t DP83848_EnableIT(dp83848_Object_t *pObj, uint32_t Interrupt); +int32_t DP83848_DisableIT(dp83848_Object_t *pObj, uint32_t Interrupt); +int32_t DP83848_ClearIT(dp83848_Object_t *pObj, uint32_t Interrupt); +int32_t DP83848_GetITStatus(dp83848_Object_t *pObj, uint32_t Interrupt); +/** + * @} + */ + +#ifdef __cplusplus +} +#endif +#endif /* DP83848_H */ + + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + diff --git a/stm32/ethernetif.c b/stm32/ethernetif.c index ac023a0..c32ad45 100644 --- a/stm32/ethernetif.c +++ b/stm32/ethernetif.c @@ -1,986 +1,986 @@ -/* USER CODE BEGIN Header */ -/** - ****************************************************************************** - * File Name : ethernetif.c - * Description : This file provides code for the configuration - * of the ethernetif.c MiddleWare. - ****************************************************************************** - * @attention - * - * Copyright (c) 2022 STMicroelectronics. - * All rights reserved. - * - * This software is licensed under terms that can be found in the LICENSE file - * in the root directory of this software component. - * If no LICENSE file comes with this software, it is provided AS-IS. - * - ****************************************************************************** - */ -/* USER CODE END Header */ - -/* Includes ------------------------------------------------------------------*/ -#ifndef __rtems__ -#include "main.h" -#else -#include <bsp.h> -#include <bsp/irq.h> -#endif /* __rtems__ */ -#include "lwip/opt.h" -#include "lwip/timeouts.h" -#include "netif/ethernet.h" -#include "netif/etharp.h" -#include "lwip/ethip6.h" -#include "ethernetif.h" -#include "dp83848.h" -#include <string.h> -#ifndef __rtems__ -#include "cmsis_os.h" -#endif /* __rtems__ */ -#include "lwip/tcpip.h" - -/* Within 'USER CODE' section, code will be kept by default at each generation */ -/* USER CODE BEGIN 0 */ - -/* USER CODE END 0 */ - -/* Private define ------------------------------------------------------------*/ -/* The time to block waiting for input. */ -#ifndef __rtems__ -#define TIME_WAITING_FOR_INPUT ( portMAX_DELAY ) -#else -#define TIME_WAITING_FOR_INPUT ( RTEMS_NO_TIMEOUT ) -#endif /* __rtems__ */ - -/* USER CODE BEGIN OS_THREAD_STACK_SIZE_WITH_RTOS */ -/* Stack size of the interface thread */ -#define INTERFACE_THREAD_STACK_SIZE ( 350 ) -/* USER CODE END OS_THREAD_STACK_SIZE_WITH_RTOS */ -/* Network interface name */ -#define IFNAME0 's' -#define IFNAME1 't' - -/* ETH Setting */ -#define ETH_DMA_TRANSMIT_TIMEOUT ( 20U ) -#define ETH_TX_BUFFER_MAX ((ETH_TX_DESC_CNT) * 2U) -/* ETH_RX_BUFFER_SIZE parameter is defined in lwipopts.h */ - -/* USER CODE BEGIN 1 */ - -/* USER CODE END 1 */ - -/* Private variables ---------------------------------------------------------*/ -/* -@Note: This interface is implemented to operate in zero-copy mode only: - - Rx buffers are allocated statically and passed directly to the LwIP stack - they will return back to ETH DMA after been processed by the stack. - - Tx Buffers will be allocated from LwIP stack memory heap, - then passed to ETH HAL driver. - -@Notes: - 1.a. ETH DMA Rx descriptors must be contiguous, the default count is 4, - to customize it please redefine ETH_RX_DESC_CNT in ETH GUI (Rx Descriptor Length) - so that updated value will be generated in stm32xxxx_hal_conf.h - 1.b. ETH DMA Tx descriptors must be contiguous, the default count is 4, - to customize it please redefine ETH_TX_DESC_CNT in ETH GUI (Tx Descriptor Length) - so that updated value will be generated in stm32xxxx_hal_conf.h - - 2.a. Rx Buffers number must be between ETH_RX_DESC_CNT and 2*ETH_RX_DESC_CNT - 2.b. Rx Buffers must have the same size: ETH_RX_BUFFER_SIZE, this value must - passed to ETH DMA in the init field (heth.Init.RxBuffLen) - 2.c The RX Ruffers addresses and sizes must be properly defined to be aligned - to L1-CACHE line size (32 bytes). -*/ - -/* Data Type Definitions */ -typedef enum -{ - RX_ALLOC_OK = 0x00, - RX_ALLOC_ERROR = 0x01 -} RxAllocStatusTypeDef; - -typedef struct -{ - struct pbuf_custom pbuf_custom; - uint8_t buff[(ETH_RX_BUFFER_SIZE + 31) & ~31] __ALIGNED(32); -} RxBuff_t; - -/* Memory Pool Declaration */ -#define ETH_RX_BUFFER_CNT 12U -LWIP_MEMPOOL_DECLARE(RX_POOL, ETH_RX_BUFFER_CNT, sizeof(RxBuff_t), "Zero-copy RX PBUF pool"); - -/* Variable Definitions */ -static uint8_t RxAllocStatus; - -__IO uint32_t TxPkt = 0; -__IO uint32_t RxPkt = 0; - -ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT]; /* Ethernet Rx DMA Descriptors */ -ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT]; /* Ethernet Tx DMA Descriptors */ - -/* USER CODE BEGIN 2 */ - -/* USER CODE END 2 */ - -#ifndef __rtems__ -osSemaphoreId RxPktSemaphore = NULL; /* Semaphore to signal incoming packets */ -osSemaphoreId TxPktSemaphore = NULL; /* Semaphore to signal transmit packet complete */ -#else -rtems_id RxPktSemaphore; /* Semaphore to signal incoming packets */ -rtems_id TxPktSemaphore; /* Semaphore to signal transmit packet complete */ -#endif /* __rtems__ */ - -/* Global Ethernet handle */ -ETH_HandleTypeDef heth; -ETH_TxPacketConfig TxConfig; -#ifdef __rtems__ -static uint8_t *MACAddr; -#endif /* __rtems__ */ - -/* Private function prototypes -----------------------------------------------*/ -int32_t ETH_PHY_IO_Init(void); -int32_t ETH_PHY_IO_DeInit (void); -int32_t ETH_PHY_IO_ReadReg(uint32_t DevAddr, uint32_t RegAddr, uint32_t *pRegVal); -int32_t ETH_PHY_IO_WriteReg(uint32_t DevAddr, uint32_t RegAddr, uint32_t RegVal); -int32_t ETH_PHY_IO_GetTick(void); - -dp83848_Object_t DP83848; -dp83848_IOCtx_t DP83848_IOCtx = {ETH_PHY_IO_Init, - ETH_PHY_IO_DeInit, - ETH_PHY_IO_WriteReg, - ETH_PHY_IO_ReadReg, - ETH_PHY_IO_GetTick}; - -/* USER CODE BEGIN 3 */ - -/* USER CODE END 3 */ - -/* Private functions ---------------------------------------------------------*/ -void pbuf_free_custom(struct pbuf *p); - -/** - * @brief Ethernet Rx Transfer completed callback - * @param handlerEth: ETH handler - * @retval None - */ -void HAL_ETH_RxCpltCallback(ETH_HandleTypeDef *handlerEth) -{ -#ifndef __rtems__ - osSemaphoreRelease(RxPktSemaphore); -#else - rtems_semaphore_release(RxPktSemaphore); -#endif /* __rtems__ */ -} -/** - * @brief Ethernet Tx Transfer completed callback - * @param handlerEth: ETH handler - * @retval None - */ -void HAL_ETH_TxCpltCallback(ETH_HandleTypeDef *handlerEth) -{ -#ifndef __rtems__ - osSemaphoreRelease(TxPktSemaphore); -#else - rtems_semaphore_release(TxPktSemaphore); -#endif /* __rtems__ */ -} -/** - * @brief Ethernet DMA transfer error callback - * @param handlerEth: ETH handler - * @retval None - */ -void HAL_ETH_ErrorCallback(ETH_HandleTypeDef *handlerEth) -{ - if((HAL_ETH_GetDMAError(handlerEth) & ETH_DMASR_RBUS) == ETH_DMASR_RBUS) - { -#ifndef __rtems__ - osSemaphoreRelease(RxPktSemaphore); -#else - rtems_semaphore_release(RxPktSemaphore); -#endif /* __rtems__ */ - } -} - -/* USER CODE BEGIN 4 */ - -#ifdef __rtems__ -void set_mac_addr(uint8_t *mac_addr) -{ - MACAddr = mac_addr; -} -#endif /* __rtems__ */ -/* USER CODE END 4 */ - -/******************************************************************************* - LL Driver Interface ( LwIP stack --> ETH) -*******************************************************************************/ -/** - * @brief In this function, the hardware should be initialized. - * Called from ethernetif_init(). - * - * @param netif the already initialized lwip network interface structure - * for this ethernetif - */ -static void low_level_init(struct netif *netif) -{ - HAL_StatusTypeDef hal_eth_init_status = HAL_OK; -/* USER CODE BEGIN OS_THREAD_ATTR_CMSIS_RTOS_V2 */ -#ifndef __rtems__ - osThreadAttr_t attributes; -#endif /* __rtems__ */ -/* USER CODE END OS_THREAD_ATTR_CMSIS_RTOS_V2 */ - uint32_t duplex, speed = 0; - int32_t PHYLinkState = 0; - ETH_MACConfigTypeDef MACConf = {0}; - /* Start ETH HAL Init */ - -#ifndef __rtems__ - uint8_t MACAddr[6] ; -#endif /* __rtems__ */ - heth.Instance = ETH; -#ifndef __rtems__ - MACAddr[0] = 0x02; - MACAddr[1] = 0x00; - MACAddr[2] = 0x00; - MACAddr[3] = 0x00; - MACAddr[4] = 0x00; - MACAddr[5] = 0x01; - heth.Init.MACAddr = &MACAddr[0]; -#else - heth.Init.MACAddr = MACAddr; -#endif /* __rtems__ */ - heth.Init.MediaInterface = HAL_ETH_RMII_MODE; - heth.Init.TxDesc = DMATxDscrTab; - heth.Init.RxDesc = DMARxDscrTab; - heth.Init.RxBuffLen = 1536; - - /* USER CODE BEGIN MACADDRESS */ - - /* USER CODE END MACADDRESS */ - - hal_eth_init_status = HAL_ETH_Init(&heth); - - memset(&TxConfig, 0 , sizeof(ETH_TxPacketConfig)); - TxConfig.Attributes = ETH_TX_PACKETS_FEATURES_CSUM | ETH_TX_PACKETS_FEATURES_CRCPAD; - TxConfig.ChecksumCtrl = ETH_CHECKSUM_IPHDR_PAYLOAD_INSERT_PHDR_CALC; - TxConfig.CRCPadCtrl = ETH_CRC_PAD_INSERT; - - /* End ETH HAL Init */ - - /* Initialize the RX POOL */ - LWIP_MEMPOOL_INIT(RX_POOL); - -#if LWIP_ARP || LWIP_ETHERNET - - /* set MAC hardware address length */ - netif->hwaddr_len = ETH_HWADDR_LEN; - - /* set MAC hardware address */ - netif->hwaddr[0] = heth.Init.MACAddr[0]; - netif->hwaddr[1] = heth.Init.MACAddr[1]; - netif->hwaddr[2] = heth.Init.MACAddr[2]; - netif->hwaddr[3] = heth.Init.MACAddr[3]; - netif->hwaddr[4] = heth.Init.MACAddr[4]; - netif->hwaddr[5] = heth.Init.MACAddr[5]; - - /* maximum transfer unit */ - netif->mtu = ETH_MAX_PAYLOAD; - - /* Accept broadcast address and ARP traffic */ - /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */ - #if LWIP_ARP - netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP; - #else - netif->flags |= NETIF_FLAG_BROADCAST; - #endif /* LWIP_ARP */ - - /* create a binary semaphore used for informing ethernetif of frame reception */ -#ifndef __rtems__ - RxPktSemaphore = osSemaphoreNew(1, 1, NULL); -#else - rtems_semaphore_create( - rtems_build_name('R', 'x', 'p', 'k'), - 1, - RTEMS_SIMPLE_BINARY_SEMAPHORE, - 0, - &RxPktSemaphore - ); -#endif /* __rtems__ */ - - /* create a binary semaphore used for informing ethernetif of frame transmission */ -#ifndef __rtems__ - TxPktSemaphore = osSemaphoreNew(1, 1, NULL); -#else - rtems_semaphore_create( - rtems_build_name('T', 'x', 'p', 'k'), - 1, - RTEMS_SIMPLE_BINARY_SEMAPHORE, - 0, - &TxPktSemaphore - ); -#endif /* __rtems__ */ - - /* create the task that handles the ETH_MAC */ -/* USER CODE BEGIN OS_THREAD_NEW_CMSIS_RTOS_V2 */ -#ifndef __rtems__ - memset(&attributes, 0x0, sizeof(osThreadAttr_t)); - attributes.name = "EthIf"; - attributes.stack_size = INTERFACE_THREAD_STACK_SIZE; - attributes.priority = osPriorityRealtime; - osThreadNew(ethernetif_input, netif, &attributes); -#else - sys_thread_new( - "ethernetif_input_thread", - ethernetif_input, - netif, - RTEMS_MINIMUM_STACK_SIZE, - DEFAULT_THREAD_PRIO - ); -#endif /* __rtem__ */ -/* USER CODE END OS_THREAD_NEW_CMSIS_RTOS_V2 */ - -/* USER CODE BEGIN PHY_PRE_CONFIG */ - -/* USER CODE END PHY_PRE_CONFIG */ - /* Set PHY IO functions */ - DP83848_RegisterBusIO(&DP83848, &DP83848_IOCtx); - - /* Initialize the DP83848 ETH PHY */ - DP83848_Init(&DP83848); - - if (hal_eth_init_status == HAL_OK) - { - PHYLinkState = DP83848_GetLinkState(&DP83848); - - /* Get link state */ - if(PHYLinkState <= DP83848_STATUS_LINK_DOWN) - { - netif_set_link_down(netif); - netif_set_down(netif); - } - else - { - switch (PHYLinkState) - { - case DP83848_STATUS_100MBITS_FULLDUPLEX: - duplex = ETH_FULLDUPLEX_MODE; - speed = ETH_SPEED_100M; - break; - case DP83848_STATUS_100MBITS_HALFDUPLEX: - duplex = ETH_HALFDUPLEX_MODE; - speed = ETH_SPEED_100M; - break; - case DP83848_STATUS_10MBITS_FULLDUPLEX: - duplex = ETH_FULLDUPLEX_MODE; - speed = ETH_SPEED_10M; - break; - case DP83848_STATUS_10MBITS_HALFDUPLEX: - duplex = ETH_HALFDUPLEX_MODE; - speed = ETH_SPEED_10M; - break; - default: - duplex = ETH_FULLDUPLEX_MODE; - speed = ETH_SPEED_100M; - break; - } - - /* Get MAC Config MAC */ - HAL_ETH_GetMACConfig(&heth, &MACConf); - MACConf.DuplexMode = duplex; - MACConf.Speed = speed; - HAL_ETH_SetMACConfig(&heth, &MACConf); - -#ifdef __rtems__ - rtems_interrupt_handler_install( - STM32F4_IRQ_ETH, - NULL, - RTEMS_INTERRUPT_UNIQUE, - HAL_ETH_IRQHandler, - &heth - ); -#endif /* __rtems__ */ - HAL_ETH_Start_IT(&heth); - netif_set_up(netif); - netif_set_link_up(netif); - -/* USER CODE BEGIN PHY_POST_CONFIG */ - -/* USER CODE END PHY_POST_CONFIG */ - } - - } - else - { - Error_Handler(); - } -#endif /* LWIP_ARP || LWIP_ETHERNET */ - -/* USER CODE BEGIN LOW_LEVEL_INIT */ - -/* USER CODE END LOW_LEVEL_INIT */ -} - -/** - * This function should do the actual transmission of the packet. The packet is - * contained in the pbuf that is passed to the function. This pbuf - * might be chained. - * - * @param netif the lwip network interface structure for this ethernetif - * @param p the MAC packet to send (e.g. IP packet including MAC addresses and type) - * @return ERR_OK if the packet could be sent - * an err_t value if the packet couldn't be sent - * - * @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to - * strange results. You might consider waiting for space in the DMA queue - * to become available since the stack doesn't retry to send a packet - * dropped because of memory failure (except for the TCP timers). - */ - -static err_t low_level_output(struct netif *netif, struct pbuf *p) -{ - uint32_t i = 0U; - struct pbuf *q = NULL; - err_t errval = ERR_OK; - ETH_BufferTypeDef Txbuffer[ETH_TX_DESC_CNT]; - - memset(Txbuffer, 0 , ETH_TX_DESC_CNT*sizeof(ETH_BufferTypeDef)); - - for(q = p; q != NULL; q = q->next) - { - if(i >= ETH_TX_DESC_CNT) - return ERR_IF; - - Txbuffer[i].buffer = q->payload; - Txbuffer[i].len = q->len; - - if(i>0) - { - Txbuffer[i-1].next = &Txbuffer[i]; - } - - if(q->next == NULL) - { - Txbuffer[i].next = NULL; - } - - i++; - } - - TxConfig.Length = p->tot_len; - TxConfig.TxBuffer = Txbuffer; - TxConfig.pData = p; - - pbuf_ref(p); - - HAL_ETH_Transmit_IT(&heth, &TxConfig); -#ifndef __rtems__ - while(osSemaphoreAcquire(TxPktSemaphore, TIME_WAITING_FOR_INPUT)!=osOK) -#else - while (rtems_semaphore_obtain(TxPktSemaphore, RTEMS_DEFAULT_OPTIONS, - TIME_WAITING_FOR_INPUT) != RTEMS_SUCCESSFUL) -#endif /* __rtems__ */ - - { - } - - HAL_ETH_ReleaseTxPacket(&heth); - - return errval; -} - -/** - * Should allocate a pbuf and transfer the bytes of the incoming - * packet from the interface into the pbuf. - * - * @param netif the lwip network interface structure for this ethernetif - * @return a pbuf filled with the received packet (including MAC header) - * NULL on memory error - */ -static struct pbuf * low_level_input(struct netif *netif) -{ - struct pbuf *p = NULL; - - if(RxAllocStatus == RX_ALLOC_OK) - { - HAL_ETH_ReadData(&heth, (void **)&p); - } - - return p; -} - -/** - * This function should be called when a packet is ready to be read - * from the interface. It uses the function low_level_input() that - * should handle the actual reception of bytes from the network - * interface. Then the type of the received packet is determined and - * the appropriate input function is called. - * - * @param netif the lwip network interface structure for this ethernetif - */ -void ethernetif_input(void* argument) -{ - struct pbuf *p = NULL; - struct netif *netif = (struct netif *) argument; - - for( ;; ) - { -#ifndef __rtems__ - if (osSemaphoreAcquire(RxPktSemaphore, TIME_WAITING_FOR_INPUT) == osOK) -#else - if (rtems_semaphore_obtain(RxPktSemaphore, RTEMS_DEFAULT_OPTIONS, - TIME_WAITING_FOR_INPUT) == RTEMS_SUCCESSFUL) -#endif /* __rtems__ */ - { - do - { - p = low_level_input( netif ); - if (p != NULL) - { - if (netif->input( p, netif) != ERR_OK ) - { - pbuf_free(p); - } - } - } while(p!=NULL); - } - } -} - -#if !LWIP_ARP -/** - * This function has to be completed by user in case of ARP OFF. - * - * @param netif the lwip network interface structure for this ethernetif - * @return ERR_OK if ... - */ -static err_t low_level_output_arp_off(struct netif *netif, struct pbuf *q, const ip4_addr_t *ipaddr) -{ - err_t errval; - errval = ERR_OK; - -/* USER CODE BEGIN 5 */ - -/* USER CODE END 5 */ - - return errval; - -} -#endif /* LWIP_ARP */ - -/** - * Should be called at the beginning of the program to set up the - * network interface. It calls the function low_level_init() to do the - * actual setup of the hardware. - * - * This function should be passed as a parameter to netif_add(). - * - * @param netif the lwip network interface structure for this ethernetif - * @return ERR_OK if the loopif is initialized - * ERR_MEM if private data couldn't be allocated - * any other err_t on error - */ -err_t ethernetif_init(struct netif *netif) -{ - LWIP_ASSERT("netif != NULL", (netif != NULL)); - -#if LWIP_NETIF_HOSTNAME - /* Initialize interface hostname */ - netif->hostname = "lwip"; -#endif /* LWIP_NETIF_HOSTNAME */ - - /* - * Initialize the snmp variables and counters inside the struct netif. - * The last argument should be replaced with your link speed, in units - * of bits per second. - */ - // MIB2_INIT_NETIF(netif, snmp_ifType_ethernet_csmacd, LINK_SPEED_OF_YOUR_NETIF_IN_BPS); - - netif->name[0] = IFNAME0; - netif->name[1] = IFNAME1; - /* We directly use etharp_output() here to save a function call. - * You can instead declare your own function an call etharp_output() - * from it if you have to do some checks before sending (e.g. if link - * is available...) */ - -#if LWIP_IPV4 -#if LWIP_ARP || LWIP_ETHERNET -#if LWIP_ARP - netif->output = etharp_output; -#else - /* The user should write its own code in low_level_output_arp_off function */ - netif->output = low_level_output_arp_off; -#endif /* LWIP_ARP */ -#endif /* LWIP_ARP || LWIP_ETHERNET */ -#endif /* LWIP_IPV4 */ - -#if LWIP_IPV6 - netif->output_ip6 = ethip6_output; -#endif /* LWIP_IPV6 */ - - netif->linkoutput = low_level_output; - - /* initialize the hardware */ - low_level_init(netif); - - return ERR_OK; -} - -/** - * @brief Custom Rx pbuf free callback - * @param pbuf: pbuf to be freed - * @retval None - */ -void pbuf_free_custom(struct pbuf *p) -{ - struct pbuf_custom* custom_pbuf = (struct pbuf_custom*)p; - LWIP_MEMPOOL_FREE(RX_POOL, custom_pbuf); - - /* If the Rx Buffer Pool was exhausted, signal the ethernetif_input task to - * call HAL_ETH_GetRxDataBuffer to rebuild the Rx descriptors. */ - - if (RxAllocStatus == RX_ALLOC_ERROR) - { - RxAllocStatus = RX_ALLOC_OK; -#ifndef __rtems__ - osSemaphoreRelease(RxPktSemaphore); -#else - rtems_semaphore_release(RxPktSemaphore); -#endif /* __rtems__ */ - } -} - -/* USER CODE BEGIN 6 */ - -#ifndef __rtems__ -/** -* @brief Returns the current time in milliseconds -* when LWIP_TIMERS == 1 and NO_SYS == 1 -* @param None -* @retval Current Time value -*/ -u32_t sys_now(void) -{ - return HAL_GetTick(); -} -#endif /* __rtems__ */ - -/* USER CODE END 6 */ - -void HAL_ETH_MspInit(ETH_HandleTypeDef* ethHandle) -{ - GPIO_InitTypeDef GPIO_InitStruct = {0}; - if(ethHandle->Instance==ETH) - { - /* USER CODE BEGIN ETH_MspInit 0 */ - - /* USER CODE END ETH_MspInit 0 */ - /* Enable Peripheral clock */ - __HAL_RCC_ETH_CLK_ENABLE(); - - __HAL_RCC_GPIOC_CLK_ENABLE(); - __HAL_RCC_GPIOA_CLK_ENABLE(); - __HAL_RCC_GPIOB_CLK_ENABLE(); - /**ETH GPIO Configuration - PC1 ------> ETH_MDC - PA1 ------> ETH_REF_CLK - PA2 ------> ETH_MDIO - PA7 ------> ETH_CRS_DV - PC4 ------> ETH_RXD0 - PC5 ------> ETH_RXD1 - PB11 ------> ETH_TX_EN - PB12 ------> ETH_TXD0 - PB13 ------> ETH_TXD1 - */ - GPIO_InitStruct.Pin = GPIO_PIN_1|GPIO_PIN_4|GPIO_PIN_5; - GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; - GPIO_InitStruct.Alternate = GPIO_AF11_ETH; - HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); - - GPIO_InitStruct.Pin = GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_7; - GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; - GPIO_InitStruct.Alternate = GPIO_AF11_ETH; - HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); - - GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13; - GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; - GPIO_InitStruct.Alternate = GPIO_AF11_ETH; - HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); - - /* Peripheral interrupt init */ -#ifndef __rtems__ - HAL_NVIC_SetPriority(ETH_IRQn, 5, 0); - HAL_NVIC_EnableIRQ(ETH_IRQn); -#endif /* __rtems__ */ - /* USER CODE BEGIN ETH_MspInit 1 */ - - /* USER CODE END ETH_MspInit 1 */ - } -} - -void HAL_ETH_MspDeInit(ETH_HandleTypeDef* ethHandle) -{ - if(ethHandle->Instance==ETH) - { - /* USER CODE BEGIN ETH_MspDeInit 0 */ - - /* USER CODE END ETH_MspDeInit 0 */ - /* Peripheral clock disable */ - __HAL_RCC_ETH_CLK_DISABLE(); - - /**ETH GPIO Configuration - PC1 ------> ETH_MDC - PA1 ------> ETH_REF_CLK - PA2 ------> ETH_MDIO - PA7 ------> ETH_CRS_DV - PC4 ------> ETH_RXD0 - PC5 ------> ETH_RXD1 - PB11 ------> ETH_TX_EN - PB12 ------> ETH_TXD0 - PB13 ------> ETH_TXD1 - */ - HAL_GPIO_DeInit(GPIOC, GPIO_PIN_1|GPIO_PIN_4|GPIO_PIN_5); - - HAL_GPIO_DeInit(GPIOA, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_7); - - HAL_GPIO_DeInit(GPIOB, GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13); - - /* Peripheral interrupt Deinit*/ - HAL_NVIC_DisableIRQ(ETH_IRQn); - - /* USER CODE BEGIN ETH_MspDeInit 1 */ - - /* USER CODE END ETH_MspDeInit 1 */ - } -} - -/******************************************************************************* - PHI IO Functions -*******************************************************************************/ -/** - * @brief Initializes the MDIO interface GPIO and clocks. - * @param None - * @retval 0 if OK, -1 if ERROR - */ -int32_t ETH_PHY_IO_Init(void) -{ - /* We assume that MDIO GPIO configuration is already done - in the ETH_MspInit() else it should be done here - */ - - /* Configure the MDIO Clock */ - HAL_ETH_SetMDIOClockRange(&heth); - - return 0; -} - -/** - * @brief De-Initializes the MDIO interface . - * @param None - * @retval 0 if OK, -1 if ERROR - */ -int32_t ETH_PHY_IO_DeInit (void) -{ - return 0; -} - -/** - * @brief Read a PHY register through the MDIO interface. - * @param DevAddr: PHY port address - * @param RegAddr: PHY register address - * @param pRegVal: pointer to hold the register value - * @retval 0 if OK -1 if Error - */ -int32_t ETH_PHY_IO_ReadReg(uint32_t DevAddr, uint32_t RegAddr, uint32_t *pRegVal) -{ - if(HAL_ETH_ReadPHYRegister(&heth, DevAddr, RegAddr, pRegVal) != HAL_OK) - { - return -1; - } - - return 0; -} - -/** - * @brief Write a value to a PHY register through the MDIO interface. - * @param DevAddr: PHY port address - * @param RegAddr: PHY register address - * @param RegVal: Value to be written - * @retval 0 if OK -1 if Error - */ -int32_t ETH_PHY_IO_WriteReg(uint32_t DevAddr, uint32_t RegAddr, uint32_t RegVal) -{ - if(HAL_ETH_WritePHYRegister(&heth, DevAddr, RegAddr, RegVal) != HAL_OK) - { - return -1; - } - - return 0; -} - -/** - * @brief Get the time in millisecons used for internal PHY driver process. - * @retval Time value - */ -int32_t ETH_PHY_IO_GetTick(void) -{ - return HAL_GetTick(); -} - -/** - * @brief Check the ETH link state then update ETH driver and netif link accordingly. - * @param argument: netif - * @retval None - */ -void ethernet_link_thread(void* argument) -{ - ETH_MACConfigTypeDef MACConf = {0}; - int32_t PHYLinkState = 0; - uint32_t linkchanged = 0U, speed = 0U, duplex = 0U; - - struct netif *netif = (struct netif *) argument; -/* USER CODE BEGIN ETH link init */ - -/* USER CODE END ETH link init */ - - for(;;) - { - PHYLinkState = DP83848_GetLinkState(&DP83848); - - if(netif_is_link_up(netif) && (PHYLinkState <= DP83848_STATUS_LINK_DOWN)) - { - HAL_ETH_Stop_IT(&heth); - netif_set_down(netif); - netif_set_link_down(netif); - } - else if(!netif_is_link_up(netif) && (PHYLinkState > DP83848_STATUS_LINK_DOWN)) - { - switch (PHYLinkState) - { - case DP83848_STATUS_100MBITS_FULLDUPLEX: - duplex = ETH_FULLDUPLEX_MODE; - speed = ETH_SPEED_100M; - linkchanged = 1; - break; - case DP83848_STATUS_100MBITS_HALFDUPLEX: - duplex = ETH_HALFDUPLEX_MODE; - speed = ETH_SPEED_100M; - linkchanged = 1; - break; - case DP83848_STATUS_10MBITS_FULLDUPLEX: - duplex = ETH_FULLDUPLEX_MODE; - speed = ETH_SPEED_10M; - linkchanged = 1; - break; - case DP83848_STATUS_10MBITS_HALFDUPLEX: - duplex = ETH_HALFDUPLEX_MODE; - speed = ETH_SPEED_10M; - linkchanged = 1; - break; - default: - break; - } - - if(linkchanged) - { - /* Get MAC Config MAC */ - HAL_ETH_GetMACConfig(&heth, &MACConf); - MACConf.DuplexMode = duplex; - MACConf.Speed = speed; - HAL_ETH_SetMACConfig(&heth, &MACConf); - HAL_ETH_Start(&heth); - netif_set_up(netif); - netif_set_link_up(netif); - } - } - -/* USER CODE BEGIN ETH link Thread core code for User BSP */ - -/* USER CODE END ETH link Thread core code for User BSP */ - -#ifndef __rtems__ - osDelay(100); -#else - sys_arch_delay(100); -#endif /* __rtems__ */ - } -} - -void HAL_ETH_RxAllocateCallback(uint8_t **buff) -{ -/* USER CODE BEGIN HAL ETH RxAllocateCallback */ - - struct pbuf_custom *p = LWIP_MEMPOOL_ALLOC(RX_POOL); - if (p) - { - /* Get the buff from the struct pbuf address. */ - *buff = (uint8_t *)p + offsetof(RxBuff_t, buff); - p->custom_free_function = pbuf_free_custom; - /* Initialize the struct pbuf. - * This must be performed whenever a buffer's allocated because it may be - * changed by lwIP or the app, e.g., pbuf_free decrements ref. */ - pbuf_alloced_custom(PBUF_RAW, 0, PBUF_REF, p, *buff, ETH_RX_BUFFER_SIZE); - } - else - { - RxAllocStatus = RX_ALLOC_ERROR; - *buff = NULL; - } -/* USER CODE END HAL ETH RxAllocateCallback */ -} - -void HAL_ETH_RxLinkCallback(void **pStart, void **pEnd, uint8_t *buff, uint16_t Length) -{ -/* USER CODE BEGIN HAL ETH RxLinkCallback */ - - struct pbuf **ppStart = (struct pbuf **)pStart; - struct pbuf **ppEnd = (struct pbuf **)pEnd; - struct pbuf *p = NULL; - - /* Get the struct pbuf from the buff address. */ - p = (struct pbuf *)(buff - offsetof(RxBuff_t, buff)); - p->next = NULL; - p->tot_len = 0; - p->len = Length; - - /* Chain the buffer. */ - if (!*ppStart) - { - /* The first buffer of the packet. */ - *ppStart = p; - } - else - { - /* Chain the buffer to the end of the packet. */ - (*ppEnd)->next = p; - } - *ppEnd = p; - - /* Update the total length of all the buffers of the chain. Each pbuf in the chain should have its tot_len - * set to its own length, plus the length of all the following pbufs in the chain. */ - for (p = *ppStart; p != NULL; p = p->next) - { - p->tot_len += Length; - } - -/* USER CODE END HAL ETH RxLinkCallback */ -} - -void HAL_ETH_TxFreeCallback(uint32_t * buff) -{ -/* USER CODE BEGIN HAL ETH TxFreeCallback */ - - pbuf_free((struct pbuf *)buff); - -/* USER CODE END HAL ETH TxFreeCallback */ -} - -/* USER CODE BEGIN 8 */ - -/* USER CODE END 8 */ - - +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * File Name : ethernetif.c + * Description : This file provides code for the configuration + * of the ethernetif.c MiddleWare. + ****************************************************************************** + * @attention + * + * Copyright (c) 2022 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Includes ------------------------------------------------------------------*/ +#ifndef __rtems__ +#include "main.h" +#else +#include <bsp.h> +#include <bsp/irq.h> +#endif /* __rtems__ */ +#include "lwip/opt.h" +#include "lwip/timeouts.h" +#include "netif/ethernet.h" +#include "netif/etharp.h" +#include "lwip/ethip6.h" +#include "ethernetif.h" +#include "dp83848.h" +#include <string.h> +#ifndef __rtems__ +#include "cmsis_os.h" +#endif /* __rtems__ */ +#include "lwip/tcpip.h" + +/* Within 'USER CODE' section, code will be kept by default at each generation */ +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +/* Private define ------------------------------------------------------------*/ +/* The time to block waiting for input. */ +#ifndef __rtems__ +#define TIME_WAITING_FOR_INPUT ( portMAX_DELAY ) +#else +#define TIME_WAITING_FOR_INPUT ( RTEMS_NO_TIMEOUT ) +#endif /* __rtems__ */ + +/* USER CODE BEGIN OS_THREAD_STACK_SIZE_WITH_RTOS */ +/* Stack size of the interface thread */ +#define INTERFACE_THREAD_STACK_SIZE ( 350 ) +/* USER CODE END OS_THREAD_STACK_SIZE_WITH_RTOS */ +/* Network interface name */ +#define IFNAME0 's' +#define IFNAME1 't' + +/* ETH Setting */ +#define ETH_DMA_TRANSMIT_TIMEOUT ( 20U ) +#define ETH_TX_BUFFER_MAX ((ETH_TX_DESC_CNT) * 2U) +/* ETH_RX_BUFFER_SIZE parameter is defined in lwipopts.h */ + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ + +/* Private variables ---------------------------------------------------------*/ +/* +@Note: This interface is implemented to operate in zero-copy mode only: + - Rx buffers are allocated statically and passed directly to the LwIP stack + they will return back to ETH DMA after been processed by the stack. + - Tx Buffers will be allocated from LwIP stack memory heap, + then passed to ETH HAL driver. + +@Notes: + 1.a. ETH DMA Rx descriptors must be contiguous, the default count is 4, + to customize it please redefine ETH_RX_DESC_CNT in ETH GUI (Rx Descriptor Length) + so that updated value will be generated in stm32xxxx_hal_conf.h + 1.b. ETH DMA Tx descriptors must be contiguous, the default count is 4, + to customize it please redefine ETH_TX_DESC_CNT in ETH GUI (Tx Descriptor Length) + so that updated value will be generated in stm32xxxx_hal_conf.h + + 2.a. Rx Buffers number must be between ETH_RX_DESC_CNT and 2*ETH_RX_DESC_CNT + 2.b. Rx Buffers must have the same size: ETH_RX_BUFFER_SIZE, this value must + passed to ETH DMA in the init field (heth.Init.RxBuffLen) + 2.c The RX Ruffers addresses and sizes must be properly defined to be aligned + to L1-CACHE line size (32 bytes). +*/ + +/* Data Type Definitions */ +typedef enum +{ + RX_ALLOC_OK = 0x00, + RX_ALLOC_ERROR = 0x01 +} RxAllocStatusTypeDef; + +typedef struct +{ + struct pbuf_custom pbuf_custom; + uint8_t buff[(ETH_RX_BUFFER_SIZE + 31) & ~31] __ALIGNED(32); +} RxBuff_t; + +/* Memory Pool Declaration */ +#define ETH_RX_BUFFER_CNT 12U +LWIP_MEMPOOL_DECLARE(RX_POOL, ETH_RX_BUFFER_CNT, sizeof(RxBuff_t), "Zero-copy RX PBUF pool"); + +/* Variable Definitions */ +static uint8_t RxAllocStatus; + +__IO uint32_t TxPkt = 0; +__IO uint32_t RxPkt = 0; + +ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT]; /* Ethernet Rx DMA Descriptors */ +ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT]; /* Ethernet Tx DMA Descriptors */ + +/* USER CODE BEGIN 2 */ + +/* USER CODE END 2 */ + +#ifndef __rtems__ +osSemaphoreId RxPktSemaphore = NULL; /* Semaphore to signal incoming packets */ +osSemaphoreId TxPktSemaphore = NULL; /* Semaphore to signal transmit packet complete */ +#else +rtems_id RxPktSemaphore; /* Semaphore to signal incoming packets */ +rtems_id TxPktSemaphore; /* Semaphore to signal transmit packet complete */ +#endif /* __rtems__ */ + +/* Global Ethernet handle */ +ETH_HandleTypeDef heth; +ETH_TxPacketConfig TxConfig; +#ifdef __rtems__ +static uint8_t *MACAddr; +#endif /* __rtems__ */ + +/* Private function prototypes -----------------------------------------------*/ +int32_t ETH_PHY_IO_Init(void); +int32_t ETH_PHY_IO_DeInit (void); +int32_t ETH_PHY_IO_ReadReg(uint32_t DevAddr, uint32_t RegAddr, uint32_t *pRegVal); +int32_t ETH_PHY_IO_WriteReg(uint32_t DevAddr, uint32_t RegAddr, uint32_t RegVal); +int32_t ETH_PHY_IO_GetTick(void); + +dp83848_Object_t DP83848; +dp83848_IOCtx_t DP83848_IOCtx = {ETH_PHY_IO_Init, + ETH_PHY_IO_DeInit, + ETH_PHY_IO_WriteReg, + ETH_PHY_IO_ReadReg, + ETH_PHY_IO_GetTick}; + +/* USER CODE BEGIN 3 */ + +/* USER CODE END 3 */ + +/* Private functions ---------------------------------------------------------*/ +void pbuf_free_custom(struct pbuf *p); + +/** + * @brief Ethernet Rx Transfer completed callback + * @param handlerEth: ETH handler + * @retval None + */ +void HAL_ETH_RxCpltCallback(ETH_HandleTypeDef *handlerEth) +{ +#ifndef __rtems__ + osSemaphoreRelease(RxPktSemaphore); +#else + rtems_semaphore_release(RxPktSemaphore); +#endif /* __rtems__ */ +} +/** + * @brief Ethernet Tx Transfer completed callback + * @param handlerEth: ETH handler + * @retval None + */ +void HAL_ETH_TxCpltCallback(ETH_HandleTypeDef *handlerEth) +{ +#ifndef __rtems__ + osSemaphoreRelease(TxPktSemaphore); +#else + rtems_semaphore_release(TxPktSemaphore); +#endif /* __rtems__ */ +} +/** + * @brief Ethernet DMA transfer error callback + * @param handlerEth: ETH handler + * @retval None + */ +void HAL_ETH_ErrorCallback(ETH_HandleTypeDef *handlerEth) +{ + if((HAL_ETH_GetDMAError(handlerEth) & ETH_DMASR_RBUS) == ETH_DMASR_RBUS) + { +#ifndef __rtems__ + osSemaphoreRelease(RxPktSemaphore); +#else + rtems_semaphore_release(RxPktSemaphore); +#endif /* __rtems__ */ + } +} + +/* USER CODE BEGIN 4 */ + +#ifdef __rtems__ +void set_mac_addr(uint8_t *mac_addr) +{ + MACAddr = mac_addr; +} +#endif /* __rtems__ */ +/* USER CODE END 4 */ + +/******************************************************************************* + LL Driver Interface ( LwIP stack --> ETH) +*******************************************************************************/ +/** + * @brief In this function, the hardware should be initialized. + * Called from ethernetif_init(). + * + * @param netif the already initialized lwip network interface structure + * for this ethernetif + */ +static void low_level_init(struct netif *netif) +{ + HAL_StatusTypeDef hal_eth_init_status = HAL_OK; +/* USER CODE BEGIN OS_THREAD_ATTR_CMSIS_RTOS_V2 */ +#ifndef __rtems__ + osThreadAttr_t attributes; +#endif /* __rtems__ */ +/* USER CODE END OS_THREAD_ATTR_CMSIS_RTOS_V2 */ + uint32_t duplex, speed = 0; + int32_t PHYLinkState = 0; + ETH_MACConfigTypeDef MACConf = {0}; + /* Start ETH HAL Init */ + +#ifndef __rtems__ + uint8_t MACAddr[6] ; +#endif /* __rtems__ */ + heth.Instance = ETH; +#ifndef __rtems__ + MACAddr[0] = 0x02; + MACAddr[1] = 0x00; + MACAddr[2] = 0x00; + MACAddr[3] = 0x00; + MACAddr[4] = 0x00; + MACAddr[5] = 0x01; + heth.Init.MACAddr = &MACAddr[0]; +#else + heth.Init.MACAddr = MACAddr; +#endif /* __rtems__ */ + heth.Init.MediaInterface = HAL_ETH_RMII_MODE; + heth.Init.TxDesc = DMATxDscrTab; + heth.Init.RxDesc = DMARxDscrTab; + heth.Init.RxBuffLen = 1536; + + /* USER CODE BEGIN MACADDRESS */ + + /* USER CODE END MACADDRESS */ + + hal_eth_init_status = HAL_ETH_Init(&heth); + + memset(&TxConfig, 0 , sizeof(ETH_TxPacketConfig)); + TxConfig.Attributes = ETH_TX_PACKETS_FEATURES_CSUM | ETH_TX_PACKETS_FEATURES_CRCPAD; + TxConfig.ChecksumCtrl = ETH_CHECKSUM_IPHDR_PAYLOAD_INSERT_PHDR_CALC; + TxConfig.CRCPadCtrl = ETH_CRC_PAD_INSERT; + + /* End ETH HAL Init */ + + /* Initialize the RX POOL */ + LWIP_MEMPOOL_INIT(RX_POOL); + +#if LWIP_ARP || LWIP_ETHERNET + + /* set MAC hardware address length */ + netif->hwaddr_len = ETH_HWADDR_LEN; + + /* set MAC hardware address */ + netif->hwaddr[0] = heth.Init.MACAddr[0]; + netif->hwaddr[1] = heth.Init.MACAddr[1]; + netif->hwaddr[2] = heth.Init.MACAddr[2]; + netif->hwaddr[3] = heth.Init.MACAddr[3]; + netif->hwaddr[4] = heth.Init.MACAddr[4]; + netif->hwaddr[5] = heth.Init.MACAddr[5]; + + /* maximum transfer unit */ + netif->mtu = ETH_MAX_PAYLOAD; + + /* Accept broadcast address and ARP traffic */ + /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */ + #if LWIP_ARP + netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP; + #else + netif->flags |= NETIF_FLAG_BROADCAST; + #endif /* LWIP_ARP */ + + /* create a binary semaphore used for informing ethernetif of frame reception */ +#ifndef __rtems__ + RxPktSemaphore = osSemaphoreNew(1, 1, NULL); +#else + rtems_semaphore_create( + rtems_build_name('R', 'x', 'p', 'k'), + 1, + RTEMS_SIMPLE_BINARY_SEMAPHORE, + 0, + &RxPktSemaphore + ); +#endif /* __rtems__ */ + + /* create a binary semaphore used for informing ethernetif of frame transmission */ +#ifndef __rtems__ + TxPktSemaphore = osSemaphoreNew(1, 1, NULL); +#else + rtems_semaphore_create( + rtems_build_name('T', 'x', 'p', 'k'), + 1, + RTEMS_SIMPLE_BINARY_SEMAPHORE, + 0, + &TxPktSemaphore + ); +#endif /* __rtems__ */ + + /* create the task that handles the ETH_MAC */ +/* USER CODE BEGIN OS_THREAD_NEW_CMSIS_RTOS_V2 */ +#ifndef __rtems__ + memset(&attributes, 0x0, sizeof(osThreadAttr_t)); + attributes.name = "EthIf"; + attributes.stack_size = INTERFACE_THREAD_STACK_SIZE; + attributes.priority = osPriorityRealtime; + osThreadNew(ethernetif_input, netif, &attributes); +#else + sys_thread_new( + "ethernetif_input_thread", + ethernetif_input, + netif, + RTEMS_MINIMUM_STACK_SIZE, + DEFAULT_THREAD_PRIO + ); +#endif /* __rtem__ */ +/* USER CODE END OS_THREAD_NEW_CMSIS_RTOS_V2 */ + +/* USER CODE BEGIN PHY_PRE_CONFIG */ + +/* USER CODE END PHY_PRE_CONFIG */ + /* Set PHY IO functions */ + DP83848_RegisterBusIO(&DP83848, &DP83848_IOCtx); + + /* Initialize the DP83848 ETH PHY */ + DP83848_Init(&DP83848); + + if (hal_eth_init_status == HAL_OK) + { + PHYLinkState = DP83848_GetLinkState(&DP83848); + + /* Get link state */ + if(PHYLinkState <= DP83848_STATUS_LINK_DOWN) + { + netif_set_link_down(netif); + netif_set_down(netif); + } + else + { + switch (PHYLinkState) + { + case DP83848_STATUS_100MBITS_FULLDUPLEX: + duplex = ETH_FULLDUPLEX_MODE; + speed = ETH_SPEED_100M; + break; + case DP83848_STATUS_100MBITS_HALFDUPLEX: + duplex = ETH_HALFDUPLEX_MODE; + speed = ETH_SPEED_100M; + break; + case DP83848_STATUS_10MBITS_FULLDUPLEX: + duplex = ETH_FULLDUPLEX_MODE; + speed = ETH_SPEED_10M; + break; + case DP83848_STATUS_10MBITS_HALFDUPLEX: + duplex = ETH_HALFDUPLEX_MODE; + speed = ETH_SPEED_10M; + break; + default: + duplex = ETH_FULLDUPLEX_MODE; + speed = ETH_SPEED_100M; + break; + } + + /* Get MAC Config MAC */ + HAL_ETH_GetMACConfig(&heth, &MACConf); + MACConf.DuplexMode = duplex; + MACConf.Speed = speed; + HAL_ETH_SetMACConfig(&heth, &MACConf); + +#ifdef __rtems__ + rtems_interrupt_handler_install( + STM32F4_IRQ_ETH, + NULL, + RTEMS_INTERRUPT_UNIQUE, + HAL_ETH_IRQHandler, + &heth + ); +#endif /* __rtems__ */ + HAL_ETH_Start_IT(&heth); + netif_set_up(netif); + netif_set_link_up(netif); + +/* USER CODE BEGIN PHY_POST_CONFIG */ + +/* USER CODE END PHY_POST_CONFIG */ + } + + } + else + { + Error_Handler(); + } +#endif /* LWIP_ARP || LWIP_ETHERNET */ + +/* USER CODE BEGIN LOW_LEVEL_INIT */ + +/* USER CODE END LOW_LEVEL_INIT */ +} + +/** + * This function should do the actual transmission of the packet. The packet is + * contained in the pbuf that is passed to the function. This pbuf + * might be chained. + * + * @param netif the lwip network interface structure for this ethernetif + * @param p the MAC packet to send (e.g. IP packet including MAC addresses and type) + * @return ERR_OK if the packet could be sent + * an err_t value if the packet couldn't be sent + * + * @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to + * strange results. You might consider waiting for space in the DMA queue + * to become available since the stack doesn't retry to send a packet + * dropped because of memory failure (except for the TCP timers). + */ + +static err_t low_level_output(struct netif *netif, struct pbuf *p) +{ + uint32_t i = 0U; + struct pbuf *q = NULL; + err_t errval = ERR_OK; + ETH_BufferTypeDef Txbuffer[ETH_TX_DESC_CNT]; + + memset(Txbuffer, 0 , ETH_TX_DESC_CNT*sizeof(ETH_BufferTypeDef)); + + for(q = p; q != NULL; q = q->next) + { + if(i >= ETH_TX_DESC_CNT) + return ERR_IF; + + Txbuffer[i].buffer = q->payload; + Txbuffer[i].len = q->len; + + if(i>0) + { + Txbuffer[i-1].next = &Txbuffer[i]; + } + + if(q->next == NULL) + { + Txbuffer[i].next = NULL; + } + + i++; + } + + TxConfig.Length = p->tot_len; + TxConfig.TxBuffer = Txbuffer; + TxConfig.pData = p; + + pbuf_ref(p); + + HAL_ETH_Transmit_IT(&heth, &TxConfig); +#ifndef __rtems__ + while(osSemaphoreAcquire(TxPktSemaphore, TIME_WAITING_FOR_INPUT)!=osOK) +#else + while (rtems_semaphore_obtain(TxPktSemaphore, RTEMS_DEFAULT_OPTIONS, + TIME_WAITING_FOR_INPUT) != RTEMS_SUCCESSFUL) +#endif /* __rtems__ */ + + { + } + + HAL_ETH_ReleaseTxPacket(&heth); + + return errval; +} + +/** + * Should allocate a pbuf and transfer the bytes of the incoming + * packet from the interface into the pbuf. + * + * @param netif the lwip network interface structure for this ethernetif + * @return a pbuf filled with the received packet (including MAC header) + * NULL on memory error + */ +static struct pbuf * low_level_input(struct netif *netif) +{ + struct pbuf *p = NULL; + + if(RxAllocStatus == RX_ALLOC_OK) + { + HAL_ETH_ReadData(&heth, (void **)&p); + } + + return p; +} + +/** + * This function should be called when a packet is ready to be read + * from the interface. It uses the function low_level_input() that + * should handle the actual reception of bytes from the network + * interface. Then the type of the received packet is determined and + * the appropriate input function is called. + * + * @param netif the lwip network interface structure for this ethernetif + */ +void ethernetif_input(void* argument) +{ + struct pbuf *p = NULL; + struct netif *netif = (struct netif *) argument; + + for( ;; ) + { +#ifndef __rtems__ + if (osSemaphoreAcquire(RxPktSemaphore, TIME_WAITING_FOR_INPUT) == osOK) +#else + if (rtems_semaphore_obtain(RxPktSemaphore, RTEMS_DEFAULT_OPTIONS, + TIME_WAITING_FOR_INPUT) == RTEMS_SUCCESSFUL) +#endif /* __rtems__ */ + { + do + { + p = low_level_input( netif ); + if (p != NULL) + { + if (netif->input( p, netif) != ERR_OK ) + { + pbuf_free(p); + } + } + } while(p!=NULL); + } + } +} + +#if !LWIP_ARP +/** + * This function has to be completed by user in case of ARP OFF. + * + * @param netif the lwip network interface structure for this ethernetif + * @return ERR_OK if ... + */ +static err_t low_level_output_arp_off(struct netif *netif, struct pbuf *q, const ip4_addr_t *ipaddr) +{ + err_t errval; + errval = ERR_OK; + +/* USER CODE BEGIN 5 */ + +/* USER CODE END 5 */ + + return errval; + +} +#endif /* LWIP_ARP */ + +/** + * Should be called at the beginning of the program to set up the + * network interface. It calls the function low_level_init() to do the + * actual setup of the hardware. + * + * This function should be passed as a parameter to netif_add(). + * + * @param netif the lwip network interface structure for this ethernetif + * @return ERR_OK if the loopif is initialized + * ERR_MEM if private data couldn't be allocated + * any other err_t on error + */ +err_t ethernetif_init(struct netif *netif) +{ + LWIP_ASSERT("netif != NULL", (netif != NULL)); + +#if LWIP_NETIF_HOSTNAME + /* Initialize interface hostname */ + netif->hostname = "lwip"; +#endif /* LWIP_NETIF_HOSTNAME */ + + /* + * Initialize the snmp variables and counters inside the struct netif. + * The last argument should be replaced with your link speed, in units + * of bits per second. + */ + // MIB2_INIT_NETIF(netif, snmp_ifType_ethernet_csmacd, LINK_SPEED_OF_YOUR_NETIF_IN_BPS); + + netif->name[0] = IFNAME0; + netif->name[1] = IFNAME1; + /* We directly use etharp_output() here to save a function call. + * You can instead declare your own function an call etharp_output() + * from it if you have to do some checks before sending (e.g. if link + * is available...) */ + +#if LWIP_IPV4 +#if LWIP_ARP || LWIP_ETHERNET +#if LWIP_ARP + netif->output = etharp_output; +#else + /* The user should write its own code in low_level_output_arp_off function */ + netif->output = low_level_output_arp_off; +#endif /* LWIP_ARP */ +#endif /* LWIP_ARP || LWIP_ETHERNET */ +#endif /* LWIP_IPV4 */ + +#if LWIP_IPV6 + netif->output_ip6 = ethip6_output; +#endif /* LWIP_IPV6 */ + + netif->linkoutput = low_level_output; + + /* initialize the hardware */ + low_level_init(netif); + + return ERR_OK; +} + +/** + * @brief Custom Rx pbuf free callback + * @param pbuf: pbuf to be freed + * @retval None + */ +void pbuf_free_custom(struct pbuf *p) +{ + struct pbuf_custom* custom_pbuf = (struct pbuf_custom*)p; + LWIP_MEMPOOL_FREE(RX_POOL, custom_pbuf); + + /* If the Rx Buffer Pool was exhausted, signal the ethernetif_input task to + * call HAL_ETH_GetRxDataBuffer to rebuild the Rx descriptors. */ + + if (RxAllocStatus == RX_ALLOC_ERROR) + { + RxAllocStatus = RX_ALLOC_OK; +#ifndef __rtems__ + osSemaphoreRelease(RxPktSemaphore); +#else + rtems_semaphore_release(RxPktSemaphore); +#endif /* __rtems__ */ + } +} + +/* USER CODE BEGIN 6 */ + +#ifndef __rtems__ +/** +* @brief Returns the current time in milliseconds +* when LWIP_TIMERS == 1 and NO_SYS == 1 +* @param None +* @retval Current Time value +*/ +u32_t sys_now(void) +{ + return HAL_GetTick(); +} +#endif /* __rtems__ */ + +/* USER CODE END 6 */ + +void HAL_ETH_MspInit(ETH_HandleTypeDef* ethHandle) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + if(ethHandle->Instance==ETH) + { + /* USER CODE BEGIN ETH_MspInit 0 */ + + /* USER CODE END ETH_MspInit 0 */ + /* Enable Peripheral clock */ + __HAL_RCC_ETH_CLK_ENABLE(); + + __HAL_RCC_GPIOC_CLK_ENABLE(); + __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_GPIOB_CLK_ENABLE(); + /**ETH GPIO Configuration + PC1 ------> ETH_MDC + PA1 ------> ETH_REF_CLK + PA2 ------> ETH_MDIO + PA7 ------> ETH_CRS_DV + PC4 ------> ETH_RXD0 + PC5 ------> ETH_RXD1 + PB11 ------> ETH_TX_EN + PB12 ------> ETH_TXD0 + PB13 ------> ETH_TXD1 + */ + GPIO_InitStruct.Pin = GPIO_PIN_1|GPIO_PIN_4|GPIO_PIN_5; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF11_ETH; + HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_7; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF11_ETH; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF11_ETH; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + /* Peripheral interrupt init */ +#ifndef __rtems__ + HAL_NVIC_SetPriority(ETH_IRQn, 5, 0); + HAL_NVIC_EnableIRQ(ETH_IRQn); +#endif /* __rtems__ */ + /* USER CODE BEGIN ETH_MspInit 1 */ + + /* USER CODE END ETH_MspInit 1 */ + } +} + +void HAL_ETH_MspDeInit(ETH_HandleTypeDef* ethHandle) +{ + if(ethHandle->Instance==ETH) + { + /* USER CODE BEGIN ETH_MspDeInit 0 */ + + /* USER CODE END ETH_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_ETH_CLK_DISABLE(); + + /**ETH GPIO Configuration + PC1 ------> ETH_MDC + PA1 ------> ETH_REF_CLK + PA2 ------> ETH_MDIO + PA7 ------> ETH_CRS_DV + PC4 ------> ETH_RXD0 + PC5 ------> ETH_RXD1 + PB11 ------> ETH_TX_EN + PB12 ------> ETH_TXD0 + PB13 ------> ETH_TXD1 + */ + HAL_GPIO_DeInit(GPIOC, GPIO_PIN_1|GPIO_PIN_4|GPIO_PIN_5); + + HAL_GPIO_DeInit(GPIOA, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_7); + + HAL_GPIO_DeInit(GPIOB, GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13); + + /* Peripheral interrupt Deinit*/ + HAL_NVIC_DisableIRQ(ETH_IRQn); + + /* USER CODE BEGIN ETH_MspDeInit 1 */ + + /* USER CODE END ETH_MspDeInit 1 */ + } +} + +/******************************************************************************* + PHI IO Functions +*******************************************************************************/ +/** + * @brief Initializes the MDIO interface GPIO and clocks. + * @param None + * @retval 0 if OK, -1 if ERROR + */ +int32_t ETH_PHY_IO_Init(void) +{ + /* We assume that MDIO GPIO configuration is already done + in the ETH_MspInit() else it should be done here + */ + + /* Configure the MDIO Clock */ + HAL_ETH_SetMDIOClockRange(&heth); + + return 0; +} + +/** + * @brief De-Initializes the MDIO interface . + * @param None + * @retval 0 if OK, -1 if ERROR + */ +int32_t ETH_PHY_IO_DeInit (void) +{ + return 0; +} + +/** + * @brief Read a PHY register through the MDIO interface. + * @param DevAddr: PHY port address + * @param RegAddr: PHY register address + * @param pRegVal: pointer to hold the register value + * @retval 0 if OK -1 if Error + */ +int32_t ETH_PHY_IO_ReadReg(uint32_t DevAddr, uint32_t RegAddr, uint32_t *pRegVal) +{ + if(HAL_ETH_ReadPHYRegister(&heth, DevAddr, RegAddr, pRegVal) != HAL_OK) + { + return -1; + } + + return 0; +} + +/** + * @brief Write a value to a PHY register through the MDIO interface. + * @param DevAddr: PHY port address + * @param RegAddr: PHY register address + * @param RegVal: Value to be written + * @retval 0 if OK -1 if Error + */ +int32_t ETH_PHY_IO_WriteReg(uint32_t DevAddr, uint32_t RegAddr, uint32_t RegVal) +{ + if(HAL_ETH_WritePHYRegister(&heth, DevAddr, RegAddr, RegVal) != HAL_OK) + { + return -1; + } + + return 0; +} + +/** + * @brief Get the time in millisecons used for internal PHY driver process. + * @retval Time value + */ +int32_t ETH_PHY_IO_GetTick(void) +{ + return HAL_GetTick(); +} + +/** + * @brief Check the ETH link state then update ETH driver and netif link accordingly. + * @param argument: netif + * @retval None + */ +void ethernet_link_thread(void* argument) +{ + ETH_MACConfigTypeDef MACConf = {0}; + int32_t PHYLinkState = 0; + uint32_t linkchanged = 0U, speed = 0U, duplex = 0U; + + struct netif *netif = (struct netif *) argument; +/* USER CODE BEGIN ETH link init */ + +/* USER CODE END ETH link init */ + + for(;;) + { + PHYLinkState = DP83848_GetLinkState(&DP83848); + + if(netif_is_link_up(netif) && (PHYLinkState <= DP83848_STATUS_LINK_DOWN)) + { + HAL_ETH_Stop_IT(&heth); + netif_set_down(netif); + netif_set_link_down(netif); + } + else if(!netif_is_link_up(netif) && (PHYLinkState > DP83848_STATUS_LINK_DOWN)) + { + switch (PHYLinkState) + { + case DP83848_STATUS_100MBITS_FULLDUPLEX: + duplex = ETH_FULLDUPLEX_MODE; + speed = ETH_SPEED_100M; + linkchanged = 1; + break; + case DP83848_STATUS_100MBITS_HALFDUPLEX: + duplex = ETH_HALFDUPLEX_MODE; + speed = ETH_SPEED_100M; + linkchanged = 1; + break; + case DP83848_STATUS_10MBITS_FULLDUPLEX: + duplex = ETH_FULLDUPLEX_MODE; + speed = ETH_SPEED_10M; + linkchanged = 1; + break; + case DP83848_STATUS_10MBITS_HALFDUPLEX: + duplex = ETH_HALFDUPLEX_MODE; + speed = ETH_SPEED_10M; + linkchanged = 1; + break; + default: + break; + } + + if(linkchanged) + { + /* Get MAC Config MAC */ + HAL_ETH_GetMACConfig(&heth, &MACConf); + MACConf.DuplexMode = duplex; + MACConf.Speed = speed; + HAL_ETH_SetMACConfig(&heth, &MACConf); + HAL_ETH_Start(&heth); + netif_set_up(netif); + netif_set_link_up(netif); + } + } + +/* USER CODE BEGIN ETH link Thread core code for User BSP */ + +/* USER CODE END ETH link Thread core code for User BSP */ + +#ifndef __rtems__ + osDelay(100); +#else + sys_arch_delay(100); +#endif /* __rtems__ */ + } +} + +void HAL_ETH_RxAllocateCallback(uint8_t **buff) +{ +/* USER CODE BEGIN HAL ETH RxAllocateCallback */ + + struct pbuf_custom *p = LWIP_MEMPOOL_ALLOC(RX_POOL); + if (p) + { + /* Get the buff from the struct pbuf address. */ + *buff = (uint8_t *)p + offsetof(RxBuff_t, buff); + p->custom_free_function = pbuf_free_custom; + /* Initialize the struct pbuf. + * This must be performed whenever a buffer's allocated because it may be + * changed by lwIP or the app, e.g., pbuf_free decrements ref. */ + pbuf_alloced_custom(PBUF_RAW, 0, PBUF_REF, p, *buff, ETH_RX_BUFFER_SIZE); + } + else + { + RxAllocStatus = RX_ALLOC_ERROR; + *buff = NULL; + } +/* USER CODE END HAL ETH RxAllocateCallback */ +} + +void HAL_ETH_RxLinkCallback(void **pStart, void **pEnd, uint8_t *buff, uint16_t Length) +{ +/* USER CODE BEGIN HAL ETH RxLinkCallback */ + + struct pbuf **ppStart = (struct pbuf **)pStart; + struct pbuf **ppEnd = (struct pbuf **)pEnd; + struct pbuf *p = NULL; + + /* Get the struct pbuf from the buff address. */ + p = (struct pbuf *)(buff - offsetof(RxBuff_t, buff)); + p->next = NULL; + p->tot_len = 0; + p->len = Length; + + /* Chain the buffer. */ + if (!*ppStart) + { + /* The first buffer of the packet. */ + *ppStart = p; + } + else + { + /* Chain the buffer to the end of the packet. */ + (*ppEnd)->next = p; + } + *ppEnd = p; + + /* Update the total length of all the buffers of the chain. Each pbuf in the chain should have its tot_len + * set to its own length, plus the length of all the following pbufs in the chain. */ + for (p = *ppStart; p != NULL; p = p->next) + { + p->tot_len += Length; + } + +/* USER CODE END HAL ETH RxLinkCallback */ +} + +void HAL_ETH_TxFreeCallback(uint32_t * buff) +{ +/* USER CODE BEGIN HAL ETH TxFreeCallback */ + + pbuf_free((struct pbuf *)buff); + +/* USER CODE END HAL ETH TxFreeCallback */ +} + +/* USER CODE BEGIN 8 */ + +/* USER CODE END 8 */ + + diff --git a/stm32/ethernetif.h b/stm32/ethernetif.h index a7b2a55..9905835 100644 --- a/stm32/ethernetif.h +++ b/stm32/ethernetif.h @@ -1,54 +1,54 @@ -/* USER CODE BEGIN Header */ -/** - ****************************************************************************** - * File Name : ethernetif.h - * Description : This file provides initialization code for LWIP - * middleWare. - ****************************************************************************** - * @attention - * - * Copyright (c) 2022 STMicroelectronics. - * All rights reserved. - * - * This software is licensed under terms that can be found in the LICENSE file - * in the root directory of this software component. - * If no LICENSE file comes with this software, it is provided AS-IS. - * - ****************************************************************************** - */ -/* USER CODE END Header */ - -#ifndef __ETHERNETIF_H__ -#define __ETHERNETIF_H__ - -#include "lwip/err.h" -#include "lwip/netif.h" -#ifndef __rtems__ -#include "cmsis_os.h" -#endif /* __rtems__ */ - -/* Within 'USER CODE' section, code will be kept by default at each generation */ -/* USER CODE BEGIN 0 */ - -#ifdef __rtems__ -void set_mac_addr(uint8_t *mac_addr); -#endif /* __rtems__ */ -/* USER CODE END 0 */ - -/* Exported functions ------------------------------------------------------- */ -err_t ethernetif_init(struct netif *netif); - -void ethernetif_input(void* argument); -void ethernet_link_thread(void* argument ); - -void Error_Handler(void); -u32_t sys_jiffies(void); -#ifndef __rtems__ -u32_t sys_now(void); -#endif /* __rtems__ */ - -/* USER CODE BEGIN 1 */ - -/* USER CODE END 1 */ -#endif - +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * File Name : ethernetif.h + * Description : This file provides initialization code for LWIP + * middleWare. + ****************************************************************************** + * @attention + * + * Copyright (c) 2022 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +#ifndef __ETHERNETIF_H__ +#define __ETHERNETIF_H__ + +#include "lwip/err.h" +#include "lwip/netif.h" +#ifndef __rtems__ +#include "cmsis_os.h" +#endif /* __rtems__ */ + +/* Within 'USER CODE' section, code will be kept by default at each generation */ +/* USER CODE BEGIN 0 */ + +#ifdef __rtems__ +void set_mac_addr(uint8_t *mac_addr); +#endif /* __rtems__ */ +/* USER CODE END 0 */ + +/* Exported functions ------------------------------------------------------- */ +err_t ethernetif_init(struct netif *netif); + +void ethernetif_input(void* argument); +void ethernet_link_thread(void* argument ); + +void Error_Handler(void); +u32_t sys_jiffies(void); +#ifndef __rtems__ +u32_t sys_now(void); +#endif /* __rtems__ */ + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ +#endif + -- 2.37.2 _______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel