mimxrt: Add support for MIMXRT1176 MCUs, and MIMXRT1170_EVK board.

The RT1176 has two cores, but the actual firmware supports only the CM7.
There are currently no good plans on how to use the CM4.

The actual MIMXRT1170_EVK board is on par with the existing MIMXRT boards,
with the following extensions:
- Use 64 MB RAM for the heap.
- Support both LAN interfaces as LAN(0) and LAN(1), with LAN(1)
  being the 1GB interface.

The dual LAN port interface can eventually be adapted as well for the
RT1062 MCU.

This work was done in collaboration with @alphaFred.
This commit is contained in:
robert-hh
2021-10-20 21:24:20 +02:00
committed by Damien George
parent d1ed0f1610
commit 5e990cc27f
53 changed files with 3013 additions and 352 deletions

View File

@@ -51,11 +51,11 @@ __attribute__((always_inline)) static inline void clock_disable_clock(clock_ip_n
static void SetFlexSPIDiv(uint32_t div) __attribute__((section(".ram_functions")));
static void SetFlexSPIDiv(uint32_t div) {
FLEXSPI_Enable(FLEXSPI, false);
FLEXSPI_Enable(BOARD_FLEX_SPI, false);
clock_disable_clock(kCLOCK_FlexSpi);
clock_set_div(kCLOCK_FlexspiDiv, div); /* flexspi clock 332M, DDR mode, internal clock 166M. */
clock_enable_clock(kCLOCK_FlexSpi);
FLEXSPI_Enable(FLEXSPI, true);
FLEXSPI_Enable(BOARD_FLEX_SPI, true);
}
status_t flexspi_nor_hyperbus_read(FLEXSPI_Type *base, uint32_t addr, uint32_t *buffer, uint32_t bytes) __attribute__((section(".ram_functions")));

View File

@@ -26,14 +26,24 @@
#ifndef MICROPY_INCLUDED_MIMXRT_HAL_FLEXSPI_HYPER_FLASH_H
#define MICROPY_INCLUDED_MIMXRT_HAL_FLEXSPI_HYPER_FLASH_H
#include "fsl_flexspi.h"
#include "mpconfigboard.h"
#include BOARD_FLASH_CONFIG_HEADER_H
#include "flexspi_flash_config.h"
#include "fsl_flexspi.h"
// #include BOARD_FLASH_CONFIG_HEADER_H
#if defined MIMXRT117x_SERIES
#define BOARD_FLEX_SPI FLEXSPI1
#define BOARD_FLEX_SPI_ADDR_BASE FlexSPI1_AMBA_BASE
#else
#define BOARD_FLEX_SPI FLEXSPI
#define BOARD_FLEX_SPI_ADDR_BASE FlexSPI_AMBA_BASE
#endif
// Defined in boards flash_config.c
extern flexspi_nor_config_t qspiflash_config;
status_t flexspi_nor_hyperflash_cfi(FLEXSPI_Type *base);
void flexspi_hyper_flash_init(void);
void flexspi_nor_update_lut(void);
status_t flexspi_nor_flash_erase_sector(FLEXSPI_Type *base, uint32_t address);
status_t flexspi_nor_flash_page_program(FLEXSPI_Type *base, uint32_t address, const uint32_t *src, uint32_t size);

View File

@@ -193,7 +193,7 @@ status_t flexspi_nor_flash_page_program(FLEXSPI_Type *base, uint32_t dstAddr, co
status = flexspi_nor_wait_bus_busy(base);
flexspi_nor_reset(FLEXSPI);
flexspi_nor_reset(BOARD_FLEX_SPI);
return status;
}

View File

@@ -27,36 +27,23 @@
#define MICROPY_INCLUDED_MIMXRT_HAL_FLEXSPI_NOR_FLASH_H
#include "fsl_flexspi.h"
#include "mpconfigboard.h"
#include BOARD_FLASH_CONFIG_HEADER_H
#if defined MIMXRT117x_SERIES
#define BOARD_FLEX_SPI FLEXSPI1
#define BOARD_FLEX_SPI_ADDR_BASE FlexSPI1_AMBA_BASE
#else
#define BOARD_FLEX_SPI FLEXSPI
#define BOARD_FLEX_SPI_ADDR_BASE FlexSPI_AMBA_BASE
#endif
// Defined in boards flash_config.c
extern flexspi_nor_config_t qspiflash_config;
status_t flexspi_nor_get_vendor_id(FLEXSPI_Type *base, uint8_t *vendorId);
status_t flexspi_nor_init(void);
void flexspi_nor_update_lut(void);
status_t flexspi_nor_flash_erase_sector(FLEXSPI_Type *base, uint32_t address);
status_t flexspi_nor_flash_page_program(FLEXSPI_Type *base, uint32_t address, const uint32_t *src, uint32_t size);
static inline uint32_t flexspi_get_frequency(void) {
uint32_t div;
uint32_t fre;
/* Clock divider:
000 divided by 1
001 divided by 2
010 divided by 3
011 divided by 4
100 divided by 5
101 divided by 6
110 divided by 7
111 divided by 8
*/
div = CLOCK_GetDiv(kCLOCK_FlexspiDiv);
/* Get frequency */
fre = CLOCK_GetFreq(kCLOCK_Usb1PllPfd0Clk) / (div + 0x01U);
return fre;
}
#endif // MICROPY_INCLUDED_MIMXRT_HAL_FLEXSPI_NOR_FLASH_H

View File

@@ -0,0 +1,387 @@
/*
* Copyright 2020 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_phyrtl8211f.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @brief Defines the PHY RTL8211F vendor defined registers. */
#define PHY_SPECIFIC_STATUS_REG 0x1AU /*!< The PHY specific status register. */
#define PHY_PAGE_SELECT_REG 0x1FU /*!< The PHY page select register. */
/*! @brief Defines the PHY RTL8211F ID number. */
#define PHY_CONTROL_ID1 0x001CU /*!< The PHY ID1 . */
/*! @brief Defines the mask flag in specific status register. */
#define PHY_SSTATUS_LINKSTATUS_MASK 0x04U /*!< The PHY link status mask. */
#define PHY_SSTATUS_LINKSPEED_MASK 0x30U /*!< The PHY link speed mask. */
#define PHY_SSTATUS_LINKDUPLEX_MASK 0x08U /*!< The PHY link duplex mask. */
#define PHY_SSTATUS_LINKSPEED_SHIFT 4U /*!< The link speed shift */
/*! @brief Defines the PHY RTL8211F extra page and the registers in specified page. */
#define PHY_PAGE_RGMII_TXRX_DELAY_ADDR 0xD08U /*!< The register page including RGMII TX/RX delay setting. */
#define PHY_RGMII_TX_DELAY_REG 0x11U /*!< The RGMII TXC delay register. */
#define PHY_RGMII_RX_DELAY_REG 0x15U /*!< The RGMII RXC delay register. */
#define PHY_RGMII_TX_DELAY_MASK 0x100U /*!< The RGMII TXC delay mask. */
#define PHY_RGMII_RX_DELAY_MASK 0x8U /*!< The RGMII RXC delay mask. */
/*! @brief MDIO MMD Devices .*/
#define PHY_MDIO_MMD_PCS 3U
#define PHY_MDIO_MMD_AN 7U
/*! @brief MDIO MMD Physical Coding layer device registers .*/
#define PHY_MDIO_PCS_EEE_CAP 0x14U /* EEE capability */
/*! @brief MDIO MMD AutoNegotiation device registers .*/
#define PHY_MDIO_AN_EEE_ADV 0x3CU /* EEE advertisement */
/*! @brief MDIO MMD EEE mask flags. (common for adv and cap) */
#define PHY_MDIO_EEE_100TX 0x2U
#define PHY_MDIO_EEE_1000T 0x4U
/*! @brief Defines the timeout macro. */
#define PHY_READID_TIMEOUT_COUNT 1000U
/*******************************************************************************
* Prototypes
******************************************************************************/
static status_t PHY_RTL8211F_MMD_SetDevice(phy_handle_t *handle,
uint8_t device,
uint16_t addr,
phy_mmd_access_mode_t mode);
static inline status_t PHY_RTL8211F_MMD_ReadData(phy_handle_t *handle, uint32_t *data);
static inline status_t PHY_RTL8211F_MMD_WriteData(phy_handle_t *handle, uint32_t data);
static status_t PHY_RTL8211F_MMD_Read(phy_handle_t *handle, uint8_t device, uint16_t addr, uint32_t *data);
static status_t PHY_RTL8211F_MMD_Write(phy_handle_t *handle, uint8_t device, uint16_t addr, uint32_t data);
/*******************************************************************************
* Variables
******************************************************************************/
const phy_operations_t phyrtl8211f_ops = {.phyInit = PHY_RTL8211F_Init,
.phyWrite = PHY_RTL8211F_Write,
.phyRead = PHY_RTL8211F_Read,
.getAutoNegoStatus = PHY_RTL8211F_GetAutoNegotiationStatus,
.getLinkStatus = PHY_RTL8211F_GetLinkStatus,
.getLinkSpeedDuplex = PHY_RTL8211F_GetLinkSpeedDuplex,
.setLinkSpeedDuplex = PHY_RTL8211F_SetLinkSpeedDuplex,
.enableLoopback = PHY_RTL8211F_EnableLoopback};
/*******************************************************************************
* Code
******************************************************************************/
status_t PHY_RTL8211F_Init(phy_handle_t *handle, const phy_config_t *config) {
uint32_t counter = PHY_READID_TIMEOUT_COUNT;
status_t result;
uint32_t regValue = 0U;
/* Init MDIO interface. */
MDIO_Init(handle->mdioHandle);
/* Assign phy address. */
handle->phyAddr = config->phyAddr;
/* Check PHY ID. */
do
{
result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_ID1_REG, &regValue);
if (result != kStatus_Success) {
return result;
}
counter--;
} while ((regValue != PHY_CONTROL_ID1) && (counter != 0U));
if (counter == 0U) {
return kStatus_Fail;
}
/* Reset PHY. */
result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, PHY_BCTL_RESET_MASK);
if (result != kStatus_Success) {
return result;
}
/* The RGMII specifies output TXC/RXC and TXD/RXD without any clock skew. Need to add skew on clock line
to make sure the other side sample right data. This can also be done in PCB traces. */
result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_PAGE_SELECT_REG, PHY_PAGE_RGMII_TXRX_DELAY_ADDR);
if (result != kStatus_Success) {
return result;
}
/* Set Tx Delay. */
result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_RGMII_TX_DELAY_REG, &regValue);
if (result == kStatus_Success) {
regValue |= PHY_RGMII_TX_DELAY_MASK;
result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_RGMII_TX_DELAY_REG, regValue);
if (result != kStatus_Success) {
return result;
}
} else {
return result;
}
/* Set Rx Delay. */
result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_RGMII_RX_DELAY_REG, &regValue);
if (result == kStatus_Success) {
regValue |= PHY_RGMII_RX_DELAY_MASK;
result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_RGMII_RX_DELAY_REG, regValue);
if (result != kStatus_Success) {
return result;
}
} else {
return result;
}
/* Restore to default page 0 */
result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_PAGE_SELECT_REG, 0x0);
if (result != kStatus_Success) {
return result;
}
/* Energy Efficient Ethernet configuration */
if (config->enableEEE) {
/* Get capabilities */
result = PHY_RTL8211F_MMD_Read(handle, PHY_MDIO_MMD_PCS, PHY_MDIO_PCS_EEE_CAP, &regValue);
if (result == kStatus_Success) {
/* Enable EEE for 100TX and 1000T */
result = PHY_RTL8211F_MMD_Write(handle, PHY_MDIO_MMD_AN, PHY_MDIO_AN_EEE_ADV,
regValue & (PHY_MDIO_EEE_1000T | PHY_MDIO_EEE_100TX));
}
} else {
result = PHY_RTL8211F_MMD_Write(handle, PHY_MDIO_MMD_AN, PHY_MDIO_AN_EEE_ADV, 0);
}
if (result != kStatus_Success) {
return result;
}
if (config->autoNeg) {
/* Set the auto-negotiation. */
result =
MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_AUTONEG_ADVERTISE_REG,
PHY_100BASETX_FULLDUPLEX_MASK | PHY_100BASETX_HALFDUPLEX_MASK | PHY_10BASETX_FULLDUPLEX_MASK |
PHY_10BASETX_HALFDUPLEX_MASK | PHY_IEEE802_3_SELECTOR_MASK);
if (result == kStatus_Success) {
result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_1000BASET_CONTROL_REG,
PHY_1000BASET_FULLDUPLEX_MASK);
if (result == kStatus_Success) {
result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, &regValue);
if (result == kStatus_Success) {
result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG,
(regValue | PHY_BCTL_AUTONEG_MASK | PHY_BCTL_RESTART_AUTONEG_MASK));
}
}
}
} else {
/* Disable isolate mode */
result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, &regValue);
if (result != kStatus_Success) {
return result;
}
regValue &= PHY_BCTL_ISOLATE_MASK;
result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, regValue);
if (result != kStatus_Success) {
return result;
}
/* Disable the auto-negotiation and set user-defined speed/duplex configuration. */
result = PHY_RTL8211F_SetLinkSpeedDuplex(handle, config->speed, config->duplex);
}
return result;
}
status_t PHY_RTL8211F_Write(phy_handle_t *handle, uint32_t phyReg, uint32_t data) {
return MDIO_Write(handle->mdioHandle, handle->phyAddr, phyReg, data);
}
status_t PHY_RTL8211F_Read(phy_handle_t *handle, uint32_t phyReg, uint32_t *dataPtr) {
return MDIO_Read(handle->mdioHandle, handle->phyAddr, phyReg, dataPtr);
}
status_t PHY_RTL8211F_GetAutoNegotiationStatus(phy_handle_t *handle, bool *status) {
assert(status);
status_t result;
uint32_t regValue;
*status = false;
/* Check auto negotiation complete. */
result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_BASICSTATUS_REG, &regValue);
if (result == kStatus_Success) {
if ((regValue & PHY_BSTATUS_AUTONEGCOMP_MASK) != 0U) {
*status = true;
}
}
return result;
}
status_t PHY_RTL8211F_GetLinkStatus(phy_handle_t *handle, bool *status) {
assert(status);
status_t result;
uint32_t regValue;
/* Read the basic status register. */
result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_SPECIFIC_STATUS_REG, &regValue);
if (result == kStatus_Success) {
if ((PHY_SSTATUS_LINKSTATUS_MASK & regValue) != 0U) {
/* Link up. */
*status = true;
} else {
/* Link down. */
*status = false;
}
}
return result;
}
status_t PHY_RTL8211F_GetLinkSpeedDuplex(phy_handle_t *handle, phy_speed_t *speed, phy_duplex_t *duplex) {
assert(!((speed == NULL) && (duplex == NULL)));
status_t result;
uint32_t regValue;
/* Read the status register. */
result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_SPECIFIC_STATUS_REG, &regValue);
if (result == kStatus_Success) {
if (speed != NULL) {
switch ((regValue & PHY_SSTATUS_LINKSPEED_MASK) >> PHY_SSTATUS_LINKSPEED_SHIFT)
{
case (uint32_t)kPHY_Speed10M:
*speed = kPHY_Speed10M;
break;
case (uint32_t)kPHY_Speed100M:
*speed = kPHY_Speed100M;
break;
case (uint32_t)kPHY_Speed1000M:
*speed = kPHY_Speed1000M;
break;
default:
*speed = kPHY_Speed10M;
break;
}
}
if (duplex != NULL) {
if ((regValue & PHY_SSTATUS_LINKDUPLEX_MASK) != 0U) {
*duplex = kPHY_FullDuplex;
} else {
*duplex = kPHY_HalfDuplex;
}
}
}
return result;
}
status_t PHY_RTL8211F_SetLinkSpeedDuplex(phy_handle_t *handle, phy_speed_t speed, phy_duplex_t duplex) {
status_t result;
uint32_t regValue;
result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, &regValue);
if (result == kStatus_Success) {
/* Disable the auto-negotiation and set according to user-defined configuration. */
regValue &= ~PHY_BCTL_AUTONEG_MASK;
if (speed == kPHY_Speed1000M) {
regValue &= PHY_BCTL_SPEED0_MASK;
regValue |= PHY_BCTL_SPEED1_MASK;
} else if (speed == kPHY_Speed100M) {
regValue |= PHY_BCTL_SPEED0_MASK;
regValue &= ~PHY_BCTL_SPEED1_MASK;
} else {
regValue &= ~PHY_BCTL_SPEED0_MASK;
regValue &= ~PHY_BCTL_SPEED1_MASK;
}
if (duplex == kPHY_FullDuplex) {
regValue |= PHY_BCTL_DUPLEX_MASK;
} else {
regValue &= ~PHY_BCTL_DUPLEX_MASK;
}
result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, regValue);
}
return result;
}
status_t PHY_RTL8211F_EnableLoopback(phy_handle_t *handle, phy_loop_t mode, phy_speed_t speed, bool enable) {
/* This PHY only supports local loopback. */
assert(mode == kPHY_LocalLoop);
status_t result;
uint32_t regValue;
/* Set the loop mode. */
if (enable) {
if (speed == kPHY_Speed1000M) {
regValue = PHY_BCTL_SPEED1_MASK | PHY_BCTL_DUPLEX_MASK | PHY_BCTL_LOOP_MASK;
} else if (speed == kPHY_Speed100M) {
regValue = PHY_BCTL_SPEED0_MASK | PHY_BCTL_DUPLEX_MASK | PHY_BCTL_LOOP_MASK;
} else {
regValue = PHY_BCTL_DUPLEX_MASK | PHY_BCTL_LOOP_MASK;
}
result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, regValue);
} else {
/* First read the current status in control register. */
result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, &regValue);
if (result == kStatus_Success) {
regValue &= ~PHY_BCTL_LOOP_MASK;
result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG,
(regValue | PHY_BCTL_RESTART_AUTONEG_MASK));
}
}
return result;
}
static status_t PHY_RTL8211F_MMD_SetDevice(phy_handle_t *handle,
uint8_t device,
uint16_t addr,
phy_mmd_access_mode_t mode) {
status_t result = kStatus_Success;
/* Set Function mode of address access(b00) and device address. */
result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_MMD_ACCESS_CONTROL_REG, device);
if (result != kStatus_Success) {
return result;
}
/* Set register address. */
result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_MMD_ACCESS_DATA_REG, addr);
if (result != kStatus_Success) {
return result;
}
/* Set Function mode of data access(b01~11) and device address. */
result =
MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_MMD_ACCESS_CONTROL_REG, (uint32_t)mode | (uint32_t)device);
return result;
}
static inline status_t PHY_RTL8211F_MMD_ReadData(phy_handle_t *handle, uint32_t *data) {
return MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_MMD_ACCESS_DATA_REG, data);
}
static inline status_t PHY_RTL8211F_MMD_WriteData(phy_handle_t *handle, uint32_t data) {
return MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_MMD_ACCESS_DATA_REG, data);
}
static status_t PHY_RTL8211F_MMD_Read(phy_handle_t *handle, uint8_t device, uint16_t addr, uint32_t *data) {
status_t result = kStatus_Success;
result = PHY_RTL8211F_MMD_SetDevice(handle, device, addr, kPHY_MMDAccessNoPostIncrement);
if (result == kStatus_Success) {
result = PHY_RTL8211F_MMD_ReadData(handle, data);
}
return result;
}
static status_t PHY_RTL8211F_MMD_Write(phy_handle_t *handle, uint8_t device, uint16_t addr, uint32_t data) {
status_t result = kStatus_Success;
result = PHY_RTL8211F_MMD_SetDevice(handle, device, addr, kPHY_MMDAccessNoPostIncrement);
if (result == kStatus_Success) {
result = PHY_RTL8211F_MMD_WriteData(handle, data);
}
return result;
}

View File

@@ -0,0 +1,163 @@
/*
* Copyright 2020 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/*****************************************************************************
* PHY RTL8211F driver change log
*****************************************************************************/
/*!
@page driver_log Driver Change Log
@section phyrtl8211 PHYRTL8211F
The current PHYRTL8211F driver version is 2.0.0.
- 2.0.0
- Initial version.
*/
#ifndef _FSL_PHYRTL8211F_H_
#define _FSL_PHYRTL8211F_H_
#include "fsl_phy.h"
/*!
* @addtogroup phy_driver
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @brief PHY driver version */
#define FSL_PHY_DRIVER_VERSION (MAKE_VERSION(2, 0, 0))
/*! @brief PHY operations structure. */
extern const phy_operations_t phyrtl8211f_ops;
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @name PHY Driver
* @{
*/
/*!
* @brief Initializes PHY.
*
* This function initialize PHY.
*
* @param handle PHY device handle.
* @param config Pointer to structure of phy_config_t.
* @retval kStatus_Success PHY initialization succeeds
* @retval kStatus_Fail PHY initialization fails
* @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out
*/
status_t PHY_RTL8211F_Init(phy_handle_t *handle, const phy_config_t *config);
/*!
* @brief PHY Write function. This function writes data over the SMI to
* the specified PHY register. This function is called by all PHY interfaces.
*
* @param handle PHY device handle.
* @param phyReg The PHY register.
* @param data The data written to the PHY register.
* @retval kStatus_Success PHY write success
* @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out
*/
status_t PHY_RTL8211F_Write(phy_handle_t *handle, uint32_t phyReg, uint32_t data);
/*!
* @brief PHY Read function. This interface reads data over the SMI from the
* specified PHY register. This function is called by all PHY interfaces.
*
* @param handle PHY device handle.
* @param phyReg The PHY register.
* @param dataPtr The address to store the data read from the PHY register.
* @retval kStatus_Success PHY read success
* @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out
*/
status_t PHY_RTL8211F_Read(phy_handle_t *handle, uint32_t phyReg, uint32_t *dataPtr);
/*!
* @brief Gets the PHY auto-negotiation status.
*
* @param handle PHY device handle.
* @param status The auto-negotiation status of the PHY.
* - true the auto-negotiation is over.
* - false the auto-negotiation is on-going or not started.
* @retval kStatus_Success PHY gets status success
* @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out
*/
status_t PHY_RTL8211F_GetAutoNegotiationStatus(phy_handle_t *handle, bool *status);
/*!
* @brief Gets the PHY link status.
*
* @param handle PHY device handle.
* @param status The link up or down status of the PHY.
* - true the link is up.
* - false the link is down.
* @retval kStatus_Success PHY gets link status success
* @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out
*/
status_t PHY_RTL8211F_GetLinkStatus(phy_handle_t *handle, bool *status);
/*!
* @brief Gets the PHY link speed and duplex.
*
* @brief This function gets the speed and duplex mode of PHY. User can give one of speed
* and duplex address paramter and set the other as NULL if only wants to get one of them.
*
* @param handle PHY device handle.
* @param speed The address of PHY link speed.
* @param duplex The link duplex of PHY.
* @retval kStatus_Success PHY gets link speed and duplex success
* @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out
*/
status_t PHY_RTL8211F_GetLinkSpeedDuplex(phy_handle_t *handle, phy_speed_t *speed, phy_duplex_t *duplex);
/*!
* @brief Sets the PHY link speed and duplex.
*
* @param handle PHY device handle.
* @param speed Specified PHY link speed.
* @param duplex Specified PHY link duplex.
* @retval kStatus_Success PHY gets status success
* @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out
*/
status_t PHY_RTL8211F_SetLinkSpeedDuplex(phy_handle_t *handle, phy_speed_t speed, phy_duplex_t duplex);
/*!
* @brief Enables/disables PHY loopback.
*
* @param handle PHY device handle.
* @param mode The loopback mode to be enabled, please see "phy_loop_t".
* All loopback modes should not be set together, when one loopback mode is set
* another should be disabled.
* @param speed PHY speed for loopback mode.
* @param enable True to enable, false to disable.
* @retval kStatus_Success PHY loopback success
* @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out
*/
status_t PHY_RTL8211F_EnableLoopback(phy_handle_t *handle, phy_loop_t mode, phy_speed_t speed, bool enable);
/* @} */
#if defined(__cplusplus)
}
#endif
/*! @}*/
#endif /* _FSL_PHY_H_ */

View File

@@ -37,6 +37,13 @@ Reset_Handler:
str r1,[r0] /* store FLEXRAM configuration value to IOMUXC_GPR17 */
dsb
isb
#if defined MIMXRT117x_SERIES
ldr r0, =__iomux_gpr18_adr /* load IOMUXC_GPR18 register address to R0 */
ldr r1, =__iomux_gpr18_value /* move FlexRAM configuration value to R1 */
str r1,[r0] /* store FLEXRAM configuration value to IOMUXC_GPR18 */
dsb
isb
#endif
ldr r0, =__iomux_gpr16_adr /* load IOMUXC_GPR16 register address to R0 */
ldr r1,[r0] /* load IOMUXC_GPR16 register value to R1 */
orr r1, r1, #4 /* set corresponding FLEXRAM_BANK_CFG_SEL bit */