539 lines
18 KiB
C
539 lines
18 KiB
C
/**
|
|
**************************************************************************
|
|
* @file at32_emac.c
|
|
* @version v2.0.4
|
|
* @date 2021-12-31
|
|
* @brief emac config program
|
|
**************************************************************************
|
|
* Copyright notice & Disclaimer
|
|
*
|
|
* The software Board Support Package (BSP) that is made available to
|
|
* download from Artery official website is the copyrighted work of Artery.
|
|
* Artery authorizes customers to use, copy, and distribute the BSP
|
|
* software and its related documentation for the purpose of design and
|
|
* development in conjunction with Artery microcontrollers. Use of the
|
|
* software is governed by this copyright notice and the following disclaimer.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
|
|
* GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
|
|
* TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
|
|
* STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
|
|
* INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
|
|
*
|
|
**************************************************************************
|
|
*/
|
|
|
|
/* includes ------------------------------------------------------------------*/
|
|
#include "at32_emac.h"
|
|
#include "SystemDelayInterface.h"
|
|
#include "delay_sec.h"
|
|
|
|
/** @addtogroup AT32F437_periph_examples
|
|
* @{
|
|
*/
|
|
|
|
/** @addtogroup 437_EMAC_tcp_server
|
|
* @{
|
|
*/
|
|
|
|
/**
|
|
* @brief enable emac clock and gpio clock
|
|
* @param none
|
|
* @retval success or error
|
|
*/
|
|
error_status emac_system_init(void) {
|
|
error_status status;
|
|
|
|
emac_nvic_configuration();
|
|
|
|
/* emac periph clock enable */
|
|
crm_periph_clock_enable(CRM_EMAC_PERIPH_CLOCK, TRUE);
|
|
crm_periph_clock_enable(CRM_EMACTX_PERIPH_CLOCK, TRUE);
|
|
crm_periph_clock_enable(CRM_EMACRX_PERIPH_CLOCK, TRUE);
|
|
|
|
emac_pins_configuration();
|
|
status = emac_layer2_configuration();
|
|
|
|
return status;
|
|
}
|
|
|
|
error_status emac_system_init_eth(void) {
|
|
nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);
|
|
error_status status = emac_system_init();
|
|
|
|
return status;
|
|
}
|
|
|
|
/**
|
|
* @brief configures emac irq channel.
|
|
* @param none
|
|
* @retval none
|
|
*/
|
|
void emac_nvic_configuration(void) {
|
|
nvic_irq_enable(EMAC_IRQn, 1, 0);
|
|
NVIC_SetPriority((IRQn_Type) EMAC_IRQn, 0x59);
|
|
}
|
|
|
|
/**
|
|
* @brief configures emac required pins.
|
|
* @param none
|
|
* @retval none
|
|
*/
|
|
void emac_pins_configuration(void) {
|
|
gpio_init_type gpio_init_struct = {0};
|
|
|
|
/* emac pins clock enable */
|
|
crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);
|
|
crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE);
|
|
crm_periph_clock_enable(CRM_GPIOC_PERIPH_CLOCK, TRUE);
|
|
crm_periph_clock_enable(CRM_GPIOD_PERIPH_CLOCK, TRUE);
|
|
// crm_periph_clock_enable(CRM_GPIOE_PERIPH_CLOCK, TRUE);
|
|
crm_periph_clock_enable(CRM_GPIOF_PERIPH_CLOCK, TRUE);
|
|
crm_periph_clock_enable(CRM_GPIOG_PERIPH_CLOCK, TRUE);
|
|
crm_periph_clock_enable(CRM_GPIOH_PERIPH_CLOCK, TRUE);
|
|
|
|
/* pa2 -> mdio */
|
|
gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE2, GPIO_MUX_11);
|
|
gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
|
|
gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
|
|
gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
|
|
gpio_init_struct.gpio_pins = GPIO_PINS_2;
|
|
gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
|
|
gpio_init(GPIOA, &gpio_init_struct);
|
|
|
|
/* pc1 -> mdc */
|
|
gpio_pin_mux_config(GPIOC, GPIO_PINS_SOURCE1, GPIO_MUX_11);
|
|
gpio_init_struct.gpio_pins = GPIO_PINS_1;
|
|
gpio_init(GPIOC, &gpio_init_struct);
|
|
|
|
#ifdef MII_MODE
|
|
|
|
/*
|
|
pg13 -> tx_d0
|
|
pg14 -> tx_d1
|
|
pc2 -> tx_d2
|
|
pb8 -> tx_d3
|
|
pb11 -> tx_en
|
|
pc3 -> tx_clk
|
|
*/
|
|
gpio_pin_mux_config(GPIOG, GPIO_PINS_SOURCE13, GPIO_MUX_11); // pg13 -> tx_d0
|
|
gpio_pin_mux_config(GPIOG, GPIO_PINS_SOURCE14, GPIO_MUX_11); // pg14 -> tx_d1
|
|
gpio_init_struct.gpio_pins = GPIO_PINS_13 | GPIO_PINS_14;
|
|
gpio_init(GPIOG, &gpio_init_struct);
|
|
|
|
gpio_pin_mux_config(GPIOC, GPIO_PINS_SOURCE2, GPIO_MUX_11); // pc2 -> tx_d2
|
|
gpio_pin_mux_config(GPIOC, GPIO_PINS_SOURCE3, GPIO_MUX_11); // pc3 -> tx_clk
|
|
gpio_init_struct.gpio_pins = GPIO_PINS_2 | GPIO_PINS_3;
|
|
gpio_init(GPIOC, &gpio_init_struct);
|
|
|
|
gpio_pin_mux_config(GPIOB, GPIO_PINS_SOURCE8, GPIO_MUX_11); // pb8 -> tx_d3
|
|
gpio_pin_mux_config(GPIOB, GPIO_PINS_SOURCE11, GPIO_MUX_11); // pb11 -> tx_en
|
|
gpio_init_struct.gpio_pins = GPIO_PINS_8 | GPIO_PINS_11;
|
|
gpio_init(GPIOB, &gpio_init_struct);
|
|
|
|
/*
|
|
pa7 -> rx_dv
|
|
pc4 -> rx_d0
|
|
pc5 -> rx_d1
|
|
pb0 -> rx_d2
|
|
pb1 -> rx_d3
|
|
*/
|
|
gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE7, GPIO_MUX_11); // pa7 -> rx_dv
|
|
gpio_init_struct.gpio_pins = GPIO_PINS_7;
|
|
gpio_init(GPIOA, &gpio_init_struct);
|
|
|
|
gpio_pin_mux_config(GPIOC, GPIO_PINS_SOURCE4, GPIO_MUX_11); // pc4 -> rx_d0
|
|
gpio_pin_mux_config(GPIOC, GPIO_PINS_SOURCE5, GPIO_MUX_11); // pc5 -> rx_d1
|
|
gpio_init_struct.gpio_pins = GPIO_PINS_4 | GPIO_PINS_5;
|
|
gpio_init(GPIOC, &gpio_init_struct);
|
|
|
|
gpio_pin_mux_config(GPIOB, GPIO_PINS_SOURCE0, GPIO_MUX_11); // pb0 -> rx_d2
|
|
gpio_pin_mux_config(GPIOB, GPIO_PINS_SOURCE1, GPIO_MUX_11); // pb1 -> rx_d3
|
|
gpio_init_struct.gpio_pins = GPIO_PINS_0 | GPIO_PINS_1;
|
|
gpio_init(GPIOB, &gpio_init_struct);
|
|
|
|
/*
|
|
pa1 -> rx_clk
|
|
pa0 -> crs
|
|
pa3 -> col
|
|
pb10 -> rx_er
|
|
*/
|
|
gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE1, GPIO_MUX_11); // pa1 -> rx_clk
|
|
gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE0, GPIO_MUX_11); // pa0 -> crs
|
|
gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE3, GPIO_MUX_11); // pa3 -> col
|
|
gpio_init_struct.gpio_pins = GPIO_PINS_1 | GPIO_PINS_0 | GPIO_PINS_3;
|
|
gpio_init(GPIOA, &gpio_init_struct);
|
|
|
|
gpio_pin_mux_config(GPIOB, GPIO_PINS_SOURCE10, GPIO_MUX_11); // pb10 -> rx_er
|
|
gpio_init_struct.gpio_pins = GPIO_PINS_10;
|
|
gpio_init(GPIOB, &gpio_init_struct);
|
|
#endif /* MII_MODE */
|
|
|
|
#ifdef RMII_MODE
|
|
/*
|
|
pb12 -> tx_d0
|
|
pb13 -> tx_d1
|
|
pb11 -> tx_en
|
|
*/
|
|
gpio_pin_mux_config(GPIOG, GPIO_PINS_SOURCE11, GPIO_MUX_11);
|
|
gpio_pin_mux_config(GPIOG, GPIO_PINS_SOURCE13, GPIO_MUX_11);
|
|
gpio_pin_mux_config(GPIOG, GPIO_PINS_SOURCE14, GPIO_MUX_11);
|
|
gpio_init_struct.gpio_pins = GPIO_PINS_11 | GPIO_PINS_13 | GPIO_PINS_14;
|
|
gpio_init(GPIOG, &gpio_init_struct);
|
|
|
|
/*
|
|
pd8 -> rx_dv
|
|
pd9 -> rx_d0
|
|
pd10 -> rx_d1
|
|
*/
|
|
gpio_pin_mux_config(GPIOD, GPIO_PINS_SOURCE8, GPIO_MUX_11);
|
|
gpio_pin_mux_config(GPIOD, GPIO_PINS_SOURCE9, GPIO_MUX_11);
|
|
gpio_pin_mux_config(GPIOD, GPIO_PINS_SOURCE10, GPIO_MUX_11);
|
|
gpio_init_struct.gpio_pins = GPIO_PINS_8 | GPIO_PINS_9 | GPIO_PINS_10;
|
|
gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
|
|
gpio_init(GPIOD, &gpio_init_struct);
|
|
|
|
|
|
#endif /* RMII_MODE */
|
|
/*
|
|
pa1 -> ref_clk
|
|
*/
|
|
gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE1, GPIO_MUX_11);
|
|
gpio_init_struct.gpio_pins = GPIO_PINS_1;
|
|
gpio_init(GPIOA, &gpio_init_struct);
|
|
|
|
#if !CRYSTAL_ON_PHY
|
|
gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE8, GPIO_MUX_0);
|
|
gpio_init_struct.gpio_pins = GPIO_PINS_8;
|
|
gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
|
|
gpio_init(GPIOA, &gpio_init_struct);
|
|
#endif
|
|
}
|
|
|
|
/**
|
|
* @brief configures emac layer2
|
|
* @param none
|
|
* @retval error or success
|
|
*/
|
|
error_status emac_layer2_configuration(void) {
|
|
emac_control_config_type mac_control_para;
|
|
emac_dma_config_type dma_control_para;
|
|
crm_periph_clock_enable(CRM_SCFG_PERIPH_CLOCK, TRUE);
|
|
#ifdef MII_MODE
|
|
scfg_emac_interface_set(SCFG_EMAC_SELECT_MII);
|
|
#elif defined RMII_MODE
|
|
scfg_emac_interface_set(SCFG_EMAC_SELECT_RMII);
|
|
#endif
|
|
// crm_clock_out1_set(CRM_CLKOUT1_PLL);
|
|
// crm_clkout_div_set(CRM_CLKOUT_INDEX_1, CRM_CLKOUT_DIV1_5, CRM_CLKOUT_DIV2_2);
|
|
|
|
crm_clock_out1_set(CRM_CLKOUT1_HEXT);
|
|
crm_clkout_div_set(CRM_CLKOUT_INDEX_1, CRM_CLKOUT_DIV1_1, CRM_CLKOUT_DIV2_1);
|
|
|
|
/* reset phy */
|
|
reset_phy();
|
|
/* reset emac ahb bus */
|
|
emac_reset();
|
|
|
|
/* software reset emac dma */
|
|
emac_dma_software_reset_set();
|
|
|
|
while (emac_dma_software_reset_get() == SET);
|
|
|
|
emac_control_para_init(&mac_control_para);
|
|
|
|
|
|
// mac_control_para.auto_nego = EMAC_AUTO_NEGOTIATION_ON;
|
|
|
|
mac_control_para.auto_nego = EMAC_AUTO_NEGOTIATION_OFF;
|
|
|
|
mac_control_para.duplex_mode = EMAC_FULL_DUPLEX;
|
|
mac_control_para.fast_ethernet_speed = EMAC_SPEED_100MBPS;
|
|
|
|
|
|
// mac_control_para.fast_ethernet_speed = PHY_AUTO_NEGOTIATION_BIT;
|
|
// mac_control_para.auto_nego = EMAC_AUTO_NEGOTIATION_ON;
|
|
|
|
|
|
// mac_control_para.auto_nego = EMAC_AUTO_NEGOTIATION_OFF;
|
|
// mac_control_para.fast_ethernet_speed = PHY_HALF_DUPLEX_100MBPS_BIT;
|
|
// mac_control_para.duplex_mode = EMAC_HALF_DUPLEX;
|
|
|
|
|
|
// mac_control_para.auto_nego = EMAC_AUTO_NEGOTIATION_OFF;
|
|
// mac_control_para.fast_ethernet_speed = PHY_HALF_DUPLEX_100MBPS_BIT;
|
|
// mac_control_para.duplex_mode = EMAC_HALF_DUPLEX;
|
|
|
|
// mac_control_para.duplex_mode = EMAC_FULL_DUPLEX;
|
|
// mac_control_para.fast_ethernet_speed = EMAC_SPEED_10MBPS;
|
|
|
|
|
|
|
|
|
|
// mac_control_para.auto_nego = EMAC_AUTO_NEGOTIATION_OFF;
|
|
// mac_control_para.fast_ethernet_speed = PHY_FULL_DUPLEX_10MBPS_BIT;
|
|
// mac_control_para.duplex_mode = EMAC_FULL_DUPLEX;
|
|
|
|
if (emac_phy_init(&mac_control_para) == ERROR) {
|
|
return ERROR;
|
|
}
|
|
|
|
emac_dma_para_init(&dma_control_para);
|
|
|
|
dma_control_para.rsf_enable = TRUE;
|
|
dma_control_para.tsf_enable = TRUE;
|
|
dma_control_para.osf_enable = TRUE;
|
|
dma_control_para.aab_enable = TRUE;
|
|
dma_control_para.usp_enable = TRUE;
|
|
dma_control_para.fb_enable = TRUE;
|
|
dma_control_para.flush_rx_disable = TRUE;
|
|
dma_control_para.rx_dma_pal = EMAC_DMA_PBL_32;
|
|
dma_control_para.tx_dma_pal = EMAC_DMA_PBL_32;
|
|
dma_control_para.priority_ratio = EMAC_DMA_2_RX_1_TX;
|
|
|
|
|
|
emac_dma_config(&dma_control_para);
|
|
// emac_dma_interrupt_enable(EMAC_DMA_INTERRUPT_NORMAL_SUMMARY, TRUE);
|
|
// emac_dma_interrupt_enable(EMAC_DMA_INTERRUPT_RX, TRUE);
|
|
|
|
|
|
// emac_dma_interrupt_enable(EMAC_DMA_INTERRUPT_TX, TRUE); /*!< transmit interrupt */
|
|
// emac_dma_interrupt_enable(EMAC_DMA_INTERRUPT_TX_STOP, TRUE); /*!< transmit process stopped interrupt */
|
|
// emac_dma_interrupt_enable(EMAC_DMA_INTERRUPT_TX_UNAVAILABLE, TRUE); /*!< transmit buffer unavailable interrupt */
|
|
// emac_dma_interrupt_enable(EMAC_DMA_INTERRUPT_TX_JABBER, TRUE); /*!< transmit jabber timeout interrupt */
|
|
// emac_dma_interrupt_enable(EMAC_DMA_INTERRUPT_RX_OVERFLOW, TRUE); /*!< receive overflow interrupt */
|
|
// emac_dma_interrupt_enable(EMAC_DMA_INTERRUPT_TX_UNDERFLOW, TRUE); /*!< transmit underflow interrupt */
|
|
// emac_dma_interrupt_enable(EMAC_DMA_INTERRUPT_RX, TRUE); /*!< receive interrupt */
|
|
// emac_dma_interrupt_enable(EMAC_DMA_INTERRUPT_RX_UNAVAILABLE, TRUE); /*!< receive buffer unavailable interrupt */
|
|
// emac_dma_interrupt_enable(EMAC_DMA_INTERRUPT_RX_STOP, TRUE); /*!< receive process stopped interrupt */
|
|
// emac_dma_interrupt_enable(EMAC_DMA_INTERRUPT_RX_TIMEOUT, TRUE); /*!< receive watchdog timeout interrupt */
|
|
// emac_dma_interrupt_enable(EMAC_DMA_INTERRUPT_TX_EARLY, TRUE); /*!< early transmit interrupt */
|
|
// emac_dma_interrupt_enable(EMAC_DMA_INTERRUPT_FATAL_BUS_ERROR, TRUE); /*!< fatal bus error interrupt */
|
|
// emac_dma_interrupt_enable(EMAC_DMA_INTERRUPT_RX_EARLY, TRUE); /*!< early receive interrupt */
|
|
// emac_dma_interrupt_enable(EMAC_DMA_INTERRUPT_ABNORMAL_SUMMARY, TRUE); /*!< abnormal interrupt summary */
|
|
// emac_dma_interrupt_enable(EMAC_DMA_INTERRUPT_NORMAL_SUMMARY, TRUE); /*!< normal interrupt summary */
|
|
|
|
return SUCCESS;
|
|
}
|
|
|
|
/**
|
|
* @brief reset layer 1
|
|
* @param none
|
|
* @retval none
|
|
*/
|
|
void static reset_phy(void) {
|
|
gpio_init_type gpio_init_struct = {0};
|
|
crm_periph_clock_enable(CRM_GPIOG_PERIPH_CLOCK, TRUE);
|
|
|
|
gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
|
|
gpio_init_struct.gpio_mode = GPIO_MODE_OUTPUT;
|
|
gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
|
|
gpio_init_struct.gpio_pins = GPIO_PINS_12;
|
|
gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
|
|
gpio_init(GPIOG, &gpio_init_struct);
|
|
|
|
gpio_bits_reset(GPIOG, GPIO_PINS_12);
|
|
|
|
// SystemDelayMs(2);
|
|
delay_ms(2);
|
|
|
|
gpio_bits_set(GPIOG, GPIO_PINS_12);
|
|
|
|
// SystemDelayMs(2);
|
|
delay_ms(2);
|
|
|
|
/*
|
|
gpio_init_type gpio_init_struct = {0};
|
|
crm_periph_clock_enable(CRM_GPIOE_PERIPH_CLOCK, TRUE);
|
|
crm_periph_clock_enable(CRM_GPIOG_PERIPH_CLOCK, TRUE);
|
|
|
|
gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
|
|
gpio_init_struct.gpio_mode = GPIO_MODE_OUTPUT;
|
|
gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
|
|
gpio_init_struct.gpio_pins = GPIO_PINS_15;
|
|
gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
|
|
gpio_init(GPIOE, &gpio_init_struct);
|
|
|
|
gpio_init_struct.gpio_pins = GPIO_PINS_15;
|
|
gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
|
|
gpio_init(GPIOG, &gpio_init_struct);
|
|
gpio_bits_reset(GPIOG, GPIO_PINS_15);
|
|
gpio_bits_reset(GPIOE, GPIO_PINS_15);
|
|
|
|
// SystemDelayMs(2);
|
|
delay_ms(2);
|
|
|
|
gpio_bits_set(GPIOE, GPIO_PINS_15);
|
|
|
|
// SystemDelayMs(2);
|
|
delay_ms(2);
|
|
*/
|
|
|
|
}
|
|
|
|
/**
|
|
* @brief reset phy register
|
|
* @param none
|
|
* @retval SUCCESS or ERROR
|
|
*/
|
|
error_status emac_phy_register_reset(void) {
|
|
uint16_t data = 0;
|
|
uint32_t timeout = 0;
|
|
uint32_t i = 0;
|
|
|
|
if (emac_phy_register_write(PHY_ADDRESS, PHY_CONTROL_REG, PHY_RESET_BIT) == ERROR) {
|
|
return ERROR;
|
|
}
|
|
|
|
for (i = 0; i < 0x000FFFFF; i++);
|
|
|
|
do {
|
|
timeout++;
|
|
if (emac_phy_register_read(PHY_ADDRESS, PHY_CONTROL_REG, &data) == ERROR) {
|
|
return ERROR;
|
|
}
|
|
} while ((data & PHY_RESET_BIT) && (timeout < PHY_TIMEOUT));
|
|
|
|
for (i = 0; i < 0x00FFFFF; i++);
|
|
if (timeout == PHY_TIMEOUT) {
|
|
return ERROR;
|
|
}
|
|
return SUCCESS;
|
|
}
|
|
|
|
/**
|
|
* @brief set mac speed related parameters
|
|
* @param nego: auto negotiation on or off.
|
|
* this parameter can be one of the following values:
|
|
* - EMAC_AUTO_NEGOTIATION_OFF
|
|
* - EMAC_AUTO_NEGOTIATION_ON.
|
|
* @param mode: half-duplex or full-duplex.
|
|
* this parameter can be one of the following values:
|
|
* - EMAC_HALF_DUPLEX
|
|
* - EMAC_FULL_DUPLEX.
|
|
* @param speed: 10 mbps or 100 mbps
|
|
* this parameter can be one of the following values:
|
|
* - EMAC_SPEED_10MBPS
|
|
* - EMAC_SPEED_100MBPS.
|
|
* @retval none
|
|
*/
|
|
error_status emac_speed_config(emac_auto_negotiation_type nego, emac_duplex_type mode, emac_speed_type speed) {
|
|
uint16_t data = 0;
|
|
uint32_t timeout = 0;
|
|
if (nego == EMAC_AUTO_NEGOTIATION_ON) {
|
|
do {
|
|
timeout++;
|
|
if (emac_phy_register_read(PHY_ADDRESS, PHY_STATUS_REG, &data) == ERROR) {
|
|
return ERROR;
|
|
}
|
|
} while (!(data & PHY_LINKED_STATUS_BIT) && (timeout < PHY_TIMEOUT));
|
|
|
|
if (timeout == PHY_TIMEOUT) {
|
|
return ERROR;
|
|
}
|
|
|
|
timeout = 0;
|
|
|
|
if (emac_phy_register_write(PHY_ADDRESS, PHY_CONTROL_REG, PHY_AUTO_NEGOTIATION_BIT) == ERROR) {
|
|
return ERROR;
|
|
}
|
|
|
|
|
|
do {
|
|
timeout++;
|
|
if (emac_phy_register_read(PHY_ADDRESS, PHY_STATUS_REG, &data) == ERROR) {
|
|
return ERROR;
|
|
}
|
|
} while (!(data & PHY_NEGO_COMPLETE_BIT) && (timeout < PHY_TIMEOUT));
|
|
|
|
if (timeout == PHY_TIMEOUT) {
|
|
return ERROR;
|
|
}
|
|
|
|
// if (emac_phy_register_read(PHY_ADDRESS, PHY_SPECIFIED_CS_REG, &data) == ERROR) {
|
|
// return ERROR;
|
|
// }
|
|
|
|
if (emac_phy_register_read(PHY_ADDRESS, PHY_AUTO_NEG_REG, &data) == ERROR) {
|
|
return ERROR;
|
|
}
|
|
|
|
#ifdef DM9162
|
|
if (data & PHY_FULL_DUPLEX_100MBPS_BIT) {
|
|
emac_fast_speed_set(EMAC_SPEED_100MBPS);
|
|
emac_duplex_mode_set(EMAC_FULL_DUPLEX);
|
|
} else if (data & PHY_HALF_DUPLEX_100MBPS_BIT) {
|
|
emac_fast_speed_set(EMAC_SPEED_100MBPS);
|
|
emac_duplex_mode_set(EMAC_HALF_DUPLEX);
|
|
} else if (data & PHY_FULL_DUPLEX_10MBPS_BIT) {
|
|
emac_fast_speed_set(EMAC_SPEED_10MBPS);
|
|
emac_duplex_mode_set(EMAC_FULL_DUPLEX);
|
|
} else if (data & PHY_HALF_DUPLEX_10MBPS_BIT) {
|
|
emac_fast_speed_set(EMAC_SPEED_10MBPS);
|
|
emac_duplex_mode_set(EMAC_HALF_DUPLEX);
|
|
}
|
|
#else
|
|
if(data & PHY_DUPLEX_MODE)
|
|
{
|
|
emac_duplex_mode_set(EMAC_FULL_DUPLEX);
|
|
}
|
|
else
|
|
{
|
|
emac_duplex_mode_set(EMAC_HALF_DUPLEX);
|
|
}
|
|
if(data & PHY_SPEED_MODE)
|
|
{
|
|
emac_fast_speed_set(EMAC_SPEED_10MBPS);
|
|
}
|
|
else
|
|
{
|
|
emac_fast_speed_set(EMAC_SPEED_100MBPS);
|
|
}
|
|
#endif
|
|
} else {
|
|
if (emac_phy_register_write(PHY_ADDRESS, PHY_CONTROL_REG, (uint16_t) ((mode << 8) | (speed << 13))) == ERROR) {
|
|
return ERROR;
|
|
}
|
|
if (speed == EMAC_SPEED_100MBPS) {
|
|
emac_fast_speed_set(EMAC_SPEED_100MBPS);
|
|
} else {
|
|
emac_fast_speed_set(EMAC_SPEED_10MBPS);
|
|
}
|
|
if (mode == EMAC_FULL_DUPLEX) {
|
|
emac_duplex_mode_set(EMAC_FULL_DUPLEX);
|
|
} else {
|
|
emac_duplex_mode_set(EMAC_HALF_DUPLEX);
|
|
}
|
|
}
|
|
|
|
return SUCCESS;
|
|
}
|
|
|
|
/**
|
|
* @brief initialize emac phy
|
|
* @param none
|
|
* @retval SUCCESS or ERROR
|
|
*/
|
|
error_status emac_phy_init(emac_control_config_type *control_para) {
|
|
emac_clock_range_set();
|
|
if (emac_phy_register_reset() == ERROR) {
|
|
return ERROR;
|
|
}
|
|
if (emac_speed_config(control_para->auto_nego, control_para->duplex_mode, control_para->fast_ethernet_speed) ==
|
|
ERROR) {
|
|
return ERROR;
|
|
}
|
|
|
|
emac_control_config(control_para);
|
|
return SUCCESS;
|
|
}
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
/**
|
|
* @}
|
|
*/
|