mirror of https://github.com/ARMmbed/mbed-os.git
				
				
				
			Merge pull request #7206 from mikaleppanen/k64f_async_powerup
K64f non-blocking poweruppull/7271/head
						commit
						e8005f6d72
					
				| 
						 | 
					@ -186,7 +186,6 @@ bool Kinetis_EMAC::low_level_init_successful()
 | 
				
			||||||
    phy_speed_t phy_speed;
 | 
					    phy_speed_t phy_speed;
 | 
				
			||||||
    phy_duplex_t phy_duplex;
 | 
					    phy_duplex_t phy_duplex;
 | 
				
			||||||
    uint32_t phyAddr = 0;
 | 
					    uint32_t phyAddr = 0;
 | 
				
			||||||
    bool link = false;
 | 
					 | 
				
			||||||
    enet_config_t config;
 | 
					    enet_config_t config;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Allocate RX descriptors
 | 
					    // Allocate RX descriptors
 | 
				
			||||||
| 
						 | 
					@ -231,16 +230,16 @@ bool Kinetis_EMAC::low_level_init_successful()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ENET_GetDefaultConfig(&config);
 | 
					    ENET_GetDefaultConfig(&config);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    PHY_Init(ENET, 0, sysClock);
 | 
					    if (PHY_Init(ENET, phyAddr, sysClock) != kStatus_Success) {
 | 
				
			||||||
    PHY_GetLinkStatus(ENET, phyAddr, &link);
 | 
					        return false;
 | 
				
			||||||
    if (link) {
 | 
					 | 
				
			||||||
        /* Get link information from PHY */
 | 
					 | 
				
			||||||
        PHY_GetLinkSpeedDuplex(ENET, phyAddr, &phy_speed, &phy_duplex);
 | 
					 | 
				
			||||||
        /* Change the MII speed and duplex for actual link status. */
 | 
					 | 
				
			||||||
        config.miiSpeed = (enet_mii_speed_t)phy_speed;
 | 
					 | 
				
			||||||
        config.miiDuplex = (enet_mii_duplex_t)phy_duplex;
 | 
					 | 
				
			||||||
        config.interrupt = kENET_RxFrameInterrupt | kENET_TxFrameInterrupt;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Get link information from PHY */
 | 
				
			||||||
 | 
					    PHY_GetLinkSpeedDuplex(ENET, phyAddr, &phy_speed, &phy_duplex);
 | 
				
			||||||
 | 
					    /* Change the MII speed and duplex for actual link status. */
 | 
				
			||||||
 | 
					    config.miiSpeed = (enet_mii_speed_t)phy_speed;
 | 
				
			||||||
 | 
					    config.miiDuplex = (enet_mii_duplex_t)phy_duplex;
 | 
				
			||||||
 | 
					    config.interrupt = kENET_RxFrameInterrupt | kENET_TxFrameInterrupt;
 | 
				
			||||||
    config.rxMaxFrameLen = ENET_ETH_MAX_FLEN;
 | 
					    config.rxMaxFrameLen = ENET_ETH_MAX_FLEN;
 | 
				
			||||||
    config.macSpecialConfig = kENET_ControlFlowControlEnable;
 | 
					    config.macSpecialConfig = kENET_ControlFlowControlEnable;
 | 
				
			||||||
    config.txAccelerConfig = 0;
 | 
					    config.txAccelerConfig = 0;
 | 
				
			||||||
| 
						 | 
					@ -262,7 +261,6 @@ bool Kinetis_EMAC::low_level_init_successful()
 | 
				
			||||||
    return true;
 | 
					    return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
/** \brief  Allocates a emac_mem_buf_t and returns the data from the incoming packet.
 | 
					/** \brief  Allocates a emac_mem_buf_t and returns the data from the incoming packet.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 *  \param[in] idx   index of packet to be read
 | 
					 *  \param[in] idx   index of packet to be read
 | 
				
			||||||
| 
						 | 
					@ -413,8 +411,8 @@ bool Kinetis_EMAC::link_out(emac_mem_buf_t *buf)
 | 
				
			||||||
        buf = copy_buf;
 | 
					        buf = copy_buf;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Check if a descriptor is available for the transfer. */
 | 
					    /* Check if a descriptor is available for the transfer (wait 10ms before dropping the buffer) */
 | 
				
			||||||
    if (xTXDCountSem.wait(0) == 0) {
 | 
					    if (xTXDCountSem.wait(10) == 0) {
 | 
				
			||||||
        memory_manager->free(buf);
 | 
					        memory_manager->free(buf);
 | 
				
			||||||
        return false;
 | 
					        return false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -452,41 +450,42 @@ bool Kinetis_EMAC::link_out(emac_mem_buf_t *buf)
 | 
				
			||||||
*******************************************************************************/
 | 
					*******************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define STATE_UNKNOWN           (-1)
 | 
					#define STATE_UNKNOWN           (-1)
 | 
				
			||||||
 | 
					#define STATE_LINK_DOWN         (0)
 | 
				
			||||||
int phy_link_status(void) {
 | 
					#define STATE_LINK_UP           (1)
 | 
				
			||||||
    bool connection_status;
 | 
					 | 
				
			||||||
    uint32_t phyAddr = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    PHY_GetLinkStatus(ENET, phyAddr, &connection_status);
 | 
					 | 
				
			||||||
    return (int)connection_status;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Kinetis_EMAC::phy_task()
 | 
					void Kinetis_EMAC::phy_task()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    static PHY_STATE prev_state = {STATE_UNKNOWN, (phy_speed_t)STATE_UNKNOWN, (phy_duplex_t)STATE_UNKNOWN};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    uint32_t phyAddr = 0;
 | 
					    uint32_t phyAddr = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Get current status
 | 
					    // Get current status
 | 
				
			||||||
    PHY_STATE crt_state;
 | 
					    PHY_STATE crt_state;
 | 
				
			||||||
    bool connection_status;
 | 
					    bool connection_status;
 | 
				
			||||||
    PHY_GetLinkStatus(ENET, phyAddr, &connection_status);
 | 
					    PHY_GetLinkStatus(ENET, phyAddr, &connection_status);
 | 
				
			||||||
    crt_state.connected = connection_status;
 | 
					
 | 
				
			||||||
    // Get the actual PHY link speed
 | 
					    if (connection_status) {
 | 
				
			||||||
    PHY_GetLinkSpeedDuplex(ENET, phyAddr, &crt_state.speed, &crt_state.duplex);
 | 
					        crt_state.connected = STATE_LINK_UP;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        crt_state.connected = STATE_LINK_DOWN;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (crt_state.connected == STATE_LINK_UP) {
 | 
				
			||||||
 | 
					        if (prev_state.connected != STATE_LINK_UP) {
 | 
				
			||||||
 | 
					            PHY_AutoNegotiation(ENET, phyAddr);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        PHY_GetLinkSpeedDuplex(ENET, phyAddr, &crt_state.speed, &crt_state.duplex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (prev_state.connected != STATE_LINK_UP || crt_state.speed != prev_state.speed) {
 | 
				
			||||||
 | 
					            /* Poke the registers*/
 | 
				
			||||||
 | 
					            ENET_SetMII(ENET, (enet_mii_speed_t)crt_state.speed, (enet_mii_duplex_t)crt_state.duplex);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Compare with previous state
 | 
					    // Compare with previous state
 | 
				
			||||||
    if (crt_state.connected != prev_state.connected && emac_link_state_cb) {
 | 
					    if (crt_state.connected != prev_state.connected && emac_link_state_cb) {
 | 
				
			||||||
        emac_link_state_cb(crt_state.connected);
 | 
					        emac_link_state_cb(crt_state.connected);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (crt_state.speed != prev_state.speed) {
 | 
					 | 
				
			||||||
      uint32_t rcr = ENET->RCR;
 | 
					 | 
				
			||||||
      rcr &= ~ENET_RCR_RMII_10T_MASK;
 | 
					 | 
				
			||||||
      rcr |= ENET_RCR_RMII_10T(!crt_state.speed);
 | 
					 | 
				
			||||||
      ENET->RCR = rcr;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    prev_state = crt_state;
 | 
					    prev_state = crt_state;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -504,19 +503,20 @@ bool Kinetis_EMAC::power_up()
 | 
				
			||||||
    rx_isr();
 | 
					    rx_isr();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* PHY monitoring task */
 | 
					    /* PHY monitoring task */
 | 
				
			||||||
    prev_state.connected = STATE_UNKNOWN;
 | 
					    prev_state.connected = STATE_LINK_DOWN;
 | 
				
			||||||
    prev_state.speed = (phy_speed_t)STATE_UNKNOWN;
 | 
					    prev_state.speed = (phy_speed_t)STATE_UNKNOWN;
 | 
				
			||||||
    prev_state.duplex = (phy_duplex_t)STATE_UNKNOWN;
 | 
					    prev_state.duplex = (phy_duplex_t)STATE_UNKNOWN;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    phy_task_handle = mbed::mbed_event_queue()->call_every(PHY_TASK_PERIOD_MS, mbed::callback(this, &Kinetis_EMAC::phy_task));
 | 
					    mbed::mbed_event_queue()->call(mbed::callback(this, &Kinetis_EMAC::phy_task));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Allow the PHY task to detect the initial link state and set up the proper flags */
 | 
					    /* Allow the PHY task to detect the initial link state and set up the proper flags */
 | 
				
			||||||
    osDelay(10);
 | 
					    osDelay(10);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    phy_task_handle = mbed::mbed_event_queue()->call_every(PHY_TASK_PERIOD_MS, mbed::callback(this, &Kinetis_EMAC::phy_task));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return true;
 | 
					    return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
uint32_t Kinetis_EMAC::get_mtu_size() const
 | 
					uint32_t Kinetis_EMAC::get_mtu_size() const
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return KINETIS_ETH_MTU_SIZE;
 | 
					    return KINETIS_ETH_MTU_SIZE;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -64,7 +64,6 @@ extern clock_ip_name_t s_enetClock[FSL_FEATURE_SOC_ENET_COUNT];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
status_t PHY_Init(ENET_Type *base, uint32_t phyAddr, uint32_t srcClock_Hz)
 | 
					status_t PHY_Init(ENET_Type *base, uint32_t phyAddr, uint32_t srcClock_Hz)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    uint32_t bssReg;
 | 
					 | 
				
			||||||
    uint32_t counter = PHY_TIMEOUT_COUNT;
 | 
					    uint32_t counter = PHY_TIMEOUT_COUNT;
 | 
				
			||||||
    uint32_t idReg = 0;
 | 
					    uint32_t idReg = 0;
 | 
				
			||||||
    status_t result = kStatus_Success;
 | 
					    status_t result = kStatus_Success;
 | 
				
			||||||
| 
						 | 
					@ -89,36 +88,42 @@ status_t PHY_Init(ENET_Type *base, uint32_t phyAddr, uint32_t srcClock_Hz)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Reset PHY. */
 | 
					    /* Reset PHY. */
 | 
				
			||||||
    counter = PHY_TIMEOUT_COUNT;
 | 
					 | 
				
			||||||
    result = PHY_Write(base, phyAddr, PHY_BASICCONTROL_REG, PHY_BCTL_RESET_MASK);
 | 
					    result = PHY_Write(base, phyAddr, PHY_BASICCONTROL_REG, PHY_BCTL_RESET_MASK);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					status_t PHY_AutoNegotiation(ENET_Type *base, uint32_t phyAddr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    status_t result = kStatus_Success;
 | 
				
			||||||
 | 
					    uint32_t bssReg;
 | 
				
			||||||
 | 
					    uint32_t counter = PHY_TIMEOUT_COUNT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Set the negotiation. */
 | 
				
			||||||
 | 
					    result = PHY_Write(base, phyAddr, PHY_AUTONEG_ADVERTISE_REG,
 | 
				
			||||||
 | 
					                       (PHY_100BASETX_FULLDUPLEX_MASK | PHY_100BASETX_HALFDUPLEX_MASK |
 | 
				
			||||||
 | 
					                        PHY_10BASETX_FULLDUPLEX_MASK | PHY_10BASETX_HALFDUPLEX_MASK | 0x1U));
 | 
				
			||||||
    if (result == kStatus_Success)
 | 
					    if (result == kStatus_Success)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        /* Set the negotiation. */
 | 
					        result = PHY_Write(base, phyAddr, PHY_BASICCONTROL_REG,
 | 
				
			||||||
        result = PHY_Write(base, phyAddr, PHY_AUTONEG_ADVERTISE_REG,
 | 
					                           (PHY_BCTL_AUTONEG_MASK | PHY_BCTL_RESTART_AUTONEG_MASK));
 | 
				
			||||||
                           (PHY_100BASETX_FULLDUPLEX_MASK | PHY_100BASETX_HALFDUPLEX_MASK |
 | 
					 | 
				
			||||||
                            PHY_10BASETX_FULLDUPLEX_MASK | PHY_10BASETX_HALFDUPLEX_MASK | 0x1U));
 | 
					 | 
				
			||||||
        if (result == kStatus_Success)
 | 
					        if (result == kStatus_Success)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            result = PHY_Write(base, phyAddr, PHY_BASICCONTROL_REG,
 | 
					            /* Check auto negotiation complete. */
 | 
				
			||||||
                               (PHY_BCTL_AUTONEG_MASK | PHY_BCTL_RESTART_AUTONEG_MASK));
 | 
					            while (counter --)
 | 
				
			||||||
            if (result == kStatus_Success)
 | 
					 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                /* Check auto negotiation complete. */
 | 
					                result = PHY_Read(base, phyAddr, PHY_BASICSTATUS_REG, &bssReg);
 | 
				
			||||||
                while (counter --)
 | 
					                if ( result == kStatus_Success)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    result = PHY_Read(base, phyAddr, PHY_BASICSTATUS_REG, &bssReg);
 | 
					                    if ((bssReg & PHY_BSTATUS_AUTONEGCOMP_MASK) != 0)
 | 
				
			||||||
                    if ( result == kStatus_Success)
 | 
					 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        if ((bssReg & PHY_BSTATUS_AUTONEGCOMP_MASK) != 0)
 | 
					                        break;
 | 
				
			||||||
                        {
 | 
					 | 
				
			||||||
                            break;
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    if (!counter)
 | 
					                if (!counter)
 | 
				
			||||||
                    {
 | 
					                {
 | 
				
			||||||
                        return kStatus_PHY_AutoNegotiateFail;
 | 
					                    return kStatus_PHY_AutoNegotiateFail;
 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -136,10 +136,19 @@ extern "C" {
 | 
				
			||||||
 * @param srcClock_Hz  The module clock frequency - system clock for MII management interface - SMI.
 | 
					 * @param srcClock_Hz  The module clock frequency - system clock for MII management interface - SMI.
 | 
				
			||||||
 * @retval kStatus_Success  PHY initialize success
 | 
					 * @retval kStatus_Success  PHY initialize success
 | 
				
			||||||
 * @retval kStatus_PHY_SMIVisitTimeout  PHY SMI visit time out
 | 
					 * @retval kStatus_PHY_SMIVisitTimeout  PHY SMI visit time out
 | 
				
			||||||
 * @retval kStatus_PHY_AutoNegotiateFail  PHY auto negotiate fail
 | 
					 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
status_t PHY_Init(ENET_Type *base, uint32_t phyAddr, uint32_t srcClock_Hz);
 | 
					status_t PHY_Init(ENET_Type *base, uint32_t phyAddr, uint32_t srcClock_Hz);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*!
 | 
				
			||||||
 | 
					 * @brief Initiates auto negotiation.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @param base       ENET peripheral base address.
 | 
				
			||||||
 | 
					 * @param phyAddr    The PHY address.
 | 
				
			||||||
 | 
					 * @retval kStatus_Success  PHY auto negotiation success
 | 
				
			||||||
 | 
					 * @retval kStatus_PHY_AutoNegotiateFail  PHY auto negotiate fail
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					status_t PHY_AutoNegotiation(ENET_Type *base, uint32_t phyAddr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*!
 | 
					/*!
 | 
				
			||||||
 * @brief PHY Write function. This function write data over the SMI to
 | 
					 * @brief PHY Write function. This function write data over the SMI to
 | 
				
			||||||
 * the specified PHY register. This function is called by all PHY interfaces.
 | 
					 * the specified PHY register. This function is called by all PHY interfaces.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,32 +1,32 @@
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
 | 
					 * Copyright (c) 2015, Freescale Semiconductor, Inc.
 | 
				
			||||||
* All rights reserved.
 | 
					 * Copyright 2016-2017 NXP
 | 
				
			||||||
*
 | 
					 *
 | 
				
			||||||
* Redistribution and use in source and binary forms, with or without modification,
 | 
					 * Redistribution and use in source and binary forms, with or without modification,
 | 
				
			||||||
* are permitted provided that the following conditions are met:
 | 
					 * are permitted provided that the following conditions are met:
 | 
				
			||||||
*
 | 
					 *
 | 
				
			||||||
* o Redistributions of source code must retain the above copyright notice, this list
 | 
					 * o Redistributions of source code must retain the above copyright notice, this list
 | 
				
			||||||
*   of conditions and the following disclaimer.
 | 
					 *   of conditions and the following disclaimer.
 | 
				
			||||||
*
 | 
					 *
 | 
				
			||||||
* o Redistributions in binary form must reproduce the above copyright notice, this
 | 
					 * o Redistributions in binary form must reproduce the above copyright notice, this
 | 
				
			||||||
*   list of conditions and the following disclaimer in the documentation and/or
 | 
					 *   list of conditions and the following disclaimer in the documentation and/or
 | 
				
			||||||
*   other materials provided with the distribution.
 | 
					 *   other materials provided with the distribution.
 | 
				
			||||||
*
 | 
					 *
 | 
				
			||||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
 | 
					 * o Neither the name of the copyright holder nor the names of its
 | 
				
			||||||
*   contributors may be used to endorse or promote products derived from this
 | 
					 *   contributors may be used to endorse or promote products derived from this
 | 
				
			||||||
*   software without specific prior written permission.
 | 
					 *   software without specific prior written permission.
 | 
				
			||||||
*
 | 
					 *
 | 
				
			||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 | 
					 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 | 
				
			||||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 | 
					 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 | 
				
			||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 | 
					 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 | 
				
			||||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
 | 
					 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
 | 
				
			||||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 | 
					 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 | 
				
			||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 | 
					 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 | 
				
			||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 | 
					 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 | 
				
			||||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
					 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
				
			||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 | 
					 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 | 
				
			||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
					 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
				
			||||||
*/
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "fsl_phy.h"
 | 
					#include "fsl_phy.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -53,8 +53,10 @@ extern uint32_t ENET_GetInstance(ENET_Type *base);
 | 
				
			||||||
 * Variables
 | 
					 * Variables
 | 
				
			||||||
 ******************************************************************************/
 | 
					 ******************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
 | 
				
			||||||
/*! @brief Pointers to enet clocks for each instance. */
 | 
					/*! @brief Pointers to enet clocks for each instance. */
 | 
				
			||||||
extern clock_ip_name_t s_enetClock[FSL_FEATURE_SOC_ENET_COUNT];
 | 
					extern clock_ip_name_t s_enetClock[FSL_FEATURE_SOC_ENET_COUNT];
 | 
				
			||||||
 | 
					#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*******************************************************************************
 | 
					/*******************************************************************************
 | 
				
			||||||
 * Code
 | 
					 * Code
 | 
				
			||||||
| 
						 | 
					@ -62,45 +64,66 @@ extern clock_ip_name_t s_enetClock[FSL_FEATURE_SOC_ENET_COUNT];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
status_t PHY_Init(ENET_Type *base, uint32_t phyAddr, uint32_t srcClock_Hz)
 | 
					status_t PHY_Init(ENET_Type *base, uint32_t phyAddr, uint32_t srcClock_Hz)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    uint32_t bssReg;
 | 
					 | 
				
			||||||
    uint32_t counter = PHY_TIMEOUT_COUNT;
 | 
					    uint32_t counter = PHY_TIMEOUT_COUNT;
 | 
				
			||||||
 | 
					    uint32_t idReg = 0;
 | 
				
			||||||
    status_t result = kStatus_Success;
 | 
					    status_t result = kStatus_Success;
 | 
				
			||||||
    uint32_t instance = ENET_GetInstance(base);
 | 
					    uint32_t instance = ENET_GetInstance(base);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
 | 
				
			||||||
    /* Set SMI first. */
 | 
					    /* Set SMI first. */
 | 
				
			||||||
    CLOCK_EnableClock(s_enetClock[instance]);
 | 
					    CLOCK_EnableClock(s_enetClock[instance]);
 | 
				
			||||||
 | 
					#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
 | 
				
			||||||
    ENET_SetSMI(base, srcClock_Hz, false);
 | 
					    ENET_SetSMI(base, srcClock_Hz, false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Initialization after PHY stars to work. */
 | 
				
			||||||
 | 
					    while ((idReg != PHY_CONTROL_ID1) && (counter != 0))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        PHY_Read(base, phyAddr, PHY_ID1_REG, &idReg);
 | 
				
			||||||
 | 
					        counter --;       
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!counter)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return kStatus_Fail;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Reset PHY. */
 | 
					    /* Reset PHY. */
 | 
				
			||||||
    result = PHY_Write(base, phyAddr, PHY_BASICCONTROL_REG, PHY_BCTL_RESET_MASK);
 | 
					    result = PHY_Write(base, phyAddr, PHY_BASICCONTROL_REG, PHY_BCTL_RESET_MASK);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					status_t PHY_AutoNegotiation(ENET_Type *base, uint32_t phyAddr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    status_t result = kStatus_Success;
 | 
				
			||||||
 | 
					    uint32_t bssReg;
 | 
				
			||||||
 | 
					    uint32_t counter = PHY_TIMEOUT_COUNT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Set the negotiation. */
 | 
				
			||||||
 | 
					    result = PHY_Write(base, phyAddr, PHY_AUTONEG_ADVERTISE_REG,
 | 
				
			||||||
 | 
					                       (PHY_100BASETX_FULLDUPLEX_MASK | PHY_100BASETX_HALFDUPLEX_MASK |
 | 
				
			||||||
 | 
					                        PHY_10BASETX_FULLDUPLEX_MASK | PHY_10BASETX_HALFDUPLEX_MASK | 0x1U));
 | 
				
			||||||
    if (result == kStatus_Success)
 | 
					    if (result == kStatus_Success)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        /* Set the negotiation. */
 | 
					        result = PHY_Write(base, phyAddr, PHY_BASICCONTROL_REG,
 | 
				
			||||||
        result = PHY_Write(base, phyAddr, PHY_AUTONEG_ADVERTISE_REG,
 | 
					                           (PHY_BCTL_AUTONEG_MASK | PHY_BCTL_RESTART_AUTONEG_MASK));
 | 
				
			||||||
                           (PHY_100BASETX_FULLDUPLEX_MASK | PHY_100BASETX_HALFDUPLEX_MASK |
 | 
					 | 
				
			||||||
                            PHY_10BASETX_FULLDUPLEX_MASK | PHY_10BASETX_HALFDUPLEX_MASK | 0x1U));
 | 
					 | 
				
			||||||
        if (result == kStatus_Success)
 | 
					        if (result == kStatus_Success)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            result = PHY_Write(base, phyAddr, PHY_BASICCONTROL_REG,
 | 
					            /* Check auto negotiation complete. */
 | 
				
			||||||
                               (PHY_BCTL_AUTONEG_MASK | PHY_BCTL_RESTART_AUTONEG_MASK));
 | 
					            while (counter --)
 | 
				
			||||||
            if (result == kStatus_Success)
 | 
					 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                /* Check auto negotiation complete. */
 | 
					                result = PHY_Read(base, phyAddr, PHY_BASICSTATUS_REG, &bssReg);
 | 
				
			||||||
                while (counter --)
 | 
					                if ( result == kStatus_Success)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    result = PHY_Read(base, phyAddr, PHY_BASICSTATUS_REG, &bssReg);
 | 
					                    if ((bssReg & PHY_BSTATUS_AUTONEGCOMP_MASK) != 0)
 | 
				
			||||||
                    if ( result == kStatus_Success)
 | 
					 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        if ((bssReg & PHY_BSTATUS_AUTONEGCOMP_MASK) != 0)
 | 
					                        break;
 | 
				
			||||||
                        {
 | 
					 | 
				
			||||||
                            break;
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    if (!counter)
 | 
					                if (!counter)
 | 
				
			||||||
                    {
 | 
					                {
 | 
				
			||||||
                        return kStatus_PHY_AutoNegotiateFail;
 | 
					                    return kStatus_PHY_AutoNegotiateFail;
 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -136,10 +136,19 @@ extern "C" {
 | 
				
			||||||
 * @param srcClock_Hz  The module clock frequency - system clock for MII management interface - SMI.
 | 
					 * @param srcClock_Hz  The module clock frequency - system clock for MII management interface - SMI.
 | 
				
			||||||
 * @retval kStatus_Success  PHY initialize success
 | 
					 * @retval kStatus_Success  PHY initialize success
 | 
				
			||||||
 * @retval kStatus_PHY_SMIVisitTimeout  PHY SMI visit time out
 | 
					 * @retval kStatus_PHY_SMIVisitTimeout  PHY SMI visit time out
 | 
				
			||||||
 * @retval kStatus_PHY_AutoNegotiateFail  PHY auto negotiate fail
 | 
					 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
status_t PHY_Init(ENET_Type *base, uint32_t phyAddr, uint32_t srcClock_Hz);
 | 
					status_t PHY_Init(ENET_Type *base, uint32_t phyAddr, uint32_t srcClock_Hz);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*!
 | 
				
			||||||
 | 
					 * @brief Initiates auto negotiation.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @param base       ENET peripheral base address.
 | 
				
			||||||
 | 
					 * @param phyAddr    The PHY address.
 | 
				
			||||||
 | 
					 * @retval kStatus_Success  PHY auto negotiation success
 | 
				
			||||||
 | 
					 * @retval kStatus_PHY_AutoNegotiateFail  PHY auto negotiate fail
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					status_t PHY_AutoNegotiation(ENET_Type *base, uint32_t phyAddr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*!
 | 
					/*!
 | 
				
			||||||
 * @brief PHY Write function. This function write data over the SMI to
 | 
					 * @brief PHY Write function. This function write data over the SMI to
 | 
				
			||||||
 * the specified PHY register. This function is called by all PHY interfaces.
 | 
					 * the specified PHY register. This function is called by all PHY interfaces.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue