Compare commits

...

9 Commits

3 changed files with 134 additions and 154 deletions

View File

@ -15,14 +15,12 @@
#include <lwipopts.h>
/* debug option */
//#define EMAC_RX_DUMP
//#define EMAC_TX_DUMP
//#define DRV_DEBUG
#define EMAC_RX_DUMP
#define EMAC_TX_DUMP
#define DRV_DEBUG
#define LOG_TAG "drv.emac"
#include <drv_log.h>
#define CRYSTAL_ON_PHY 0
/* emac memory buffer configuration */
#define EMAC_NUM_RX_BUF 5 /* rx (5 * 1500) */
#define EMAC_NUM_TX_BUF 5 /* tx (5 * 1500) */
@ -78,92 +76,6 @@ static void dump_hex(const rt_uint8_t *ptr, rt_size_t buflen)
}
#endif
/**
* @brief phy reset
*/
static void phy_reset(void)
{
gpio_init_type gpio_init_struct;
#if defined (SOC_SERIES_AT32F437)
crm_periph_clock_enable(CRM_GPIOE_PERIPH_CLOCK, TRUE);
crm_periph_clock_enable(CRM_GPIOG_PERIPH_CLOCK, TRUE);
gpio_default_para_init(&gpio_init_struct);
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_pull = GPIO_PULL_NONE;
gpio_init_struct.gpio_pins = GPIO_PINS_15;
gpio_init(GPIOE, &gpio_init_struct);
gpio_init_struct.gpio_pins = GPIO_PINS_15;
gpio_init(GPIOG, &gpio_init_struct);
gpio_bits_reset(GPIOE, GPIO_PINS_15);
gpio_bits_reset(GPIOG, GPIO_PINS_15);
rt_thread_mdelay(2);
gpio_bits_set(GPIOE, GPIO_PINS_15);
#endif
#if defined (SOC_SERIES_AT32F407)
crm_periph_clock_enable(CRM_GPIOC_PERIPH_CLOCK, TRUE);
gpio_default_para_init(&gpio_init_struct);
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_pull = GPIO_PULL_NONE;
gpio_init_struct.gpio_pins = GPIO_PINS_8;
gpio_init(GPIOC, &gpio_init_struct);
gpio_bits_reset(GPIOC, GPIO_PINS_8);
rt_thread_mdelay(2);
gpio_bits_set(GPIOC, GPIO_PINS_8);
#endif
rt_thread_mdelay(2000);
}
/**
* @brief phy clock config
*/
static void phy_clock_config(void)
{
#if (CRYSTAL_ON_PHY == 0)
/* if CRYSTAL_NO_PHY, output clock with pa8 of mcu */
gpio_init_type gpio_init_struct;
crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);
gpio_default_para_init(&gpio_init_struct);
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_pull = GPIO_PULL_NONE;
gpio_init_struct.gpio_pins = GPIO_PINS_8;
gpio_init(GPIOA, &gpio_init_struct);
/* 9162 clkout output 25 mhz */
/* 83848 clkout output 50 mhz */
#if defined (SOC_SERIES_AT32F407)
crm_clock_out_set(CRM_CLKOUT_SCLK);
#if defined (PHY_USING_DM9162)
crm_clkout_div_set(CRM_CLKOUT_DIV_8);
#elif defined (PHY_USING_DP83848)
crm_clkout_div_set(CRM_CLKOUT_DIV_4);
#endif
#endif
#if defined (SOC_SERIES_AT32F437)
crm_clock_out1_set(CRM_CLKOUT1_PLL);
#if defined (PHY_USING_DM9162)
crm_clkout_div_set(CRM_CLKOUT_INDEX_1, CRM_CLKOUT_DIV1_5, CRM_CLKOUT_DIV2_2);
#elif defined (PHY_USING_DP83848)
crm_clkout_div_set(CRM_CLKOUT_INDEX_1, CRM_CLKOUT_DIV1_5, CRM_CLKOUT_DIV2_1);
#endif
#endif
#endif
}
/**
* @brief reset phy register
*/
@ -284,6 +196,31 @@ static error_status emac_speed_config(emac_auto_negotiation_type nego, emac_dupl
{
emac_fast_speed_set(EMAC_SPEED_100MBPS);
}
#endif
#ifdef PHY_USING_LAN8720A
if ((data & PHY_DUPLEX_MBPS_MSK) == PHY_FULL_DUPLEX_100MBPS_BIT)
{
emac_duplex_mode_set(EMAC_FULL_DUPLEX);
emac_fast_speed_set(EMAC_SPEED_100MBPS);
}
if ((data & PHY_DUPLEX_MBPS_MSK) == PHY_HALF_DUPLEX_100MBPS_BIT)
{
emac_duplex_mode_set(EMAC_HALF_DUPLEX);
emac_fast_speed_set(EMAC_SPEED_100MBPS);
}
if ((data & PHY_DUPLEX_MBPS_MSK) == PHY_FULL_DUPLEX_10MBPS_BIT)
{
emac_duplex_mode_set(EMAC_FULL_DUPLEX);
emac_fast_speed_set(EMAC_SPEED_100MBPS);
}
if ((data & PHY_DUPLEX_MBPS_MSK) == PHY_FULL_DUPLEX_10MBPS_BIT)
{
emac_duplex_mode_set(EMAC_HALF_DUPLEX);
emac_fast_speed_set(EMAC_SPEED_100MBPS);
}
#endif
}
else
@ -764,6 +701,8 @@ static void phy_monitor_thread_entry(void *parameter)
#endif /* PHY_USING_INTERRUPT_MODE */
}
extern void phy_reset(void);
/* Register the EMAC device */
static int rt_hw_at32_emac_init(void)
{
@ -802,8 +741,8 @@ static int rt_hw_at32_emac_init(void)
goto __exit;
}
/* phy clock */
phy_clock_config();
// /* phy clock */
// phy_clock_config();
/* enable periph clock */
crm_periph_clock_enable(CRM_EMAC_PERIPH_CLOCK, TRUE);
@ -845,6 +784,7 @@ static int rt_hw_at32_emac_init(void)
/* reset phy */
phy_reset();
rt_thread_mdelay(2000);
/* start phy monitor */
rt_thread_t tid;

View File

@ -11,79 +11,100 @@
#ifndef __DRV_EMAC_H__
#define __DRV_EMAC_H__
#include <rtthread.h>
#include <rthw.h>
#include <rtdevice.h>
#include "drv_common.h"
#define CRYSTAL_ON_PHY 0 /* phy does not with crystal */
#include <rtdevice.h>
#include <rthw.h>
#include <rtthread.h>
/* the phy basic control register */
#define PHY_BASIC_CONTROL_REG 0x00U
#define PHY_RESET_MASK (1<<15)
#define PHY_AUTO_NEGOTIATION_MASK (1<<12)
#define PHY_BASIC_CONTROL_REG 0x00U
#define PHY_RESET_MASK (1 << 15)
#define PHY_AUTO_NEGOTIATION_MASK (1 << 12)
/* the phy basic status register */
#define PHY_BASIC_STATUS_REG 0x01U
#define PHY_LINKED_STATUS_MASK (1<<2)
#define PHY_AUTONEGO_COMPLETE_MASK (1<<5)
#define PHY_BASIC_STATUS_REG 0x01U
#define PHY_LINKED_STATUS_MASK (1 << 2)
#define PHY_AUTONEGO_COMPLETE_MASK (1 << 5)
/* the phy id one register */
#define PHY_ID1_REG 0x02U
#define PHY_ID1_REG 0x02U
/* the phy id two register */
#define PHY_ID2_REG 0x03U
#define PHY_ID2_REG 0x03U
/* the phy auto-negotiate advertise register */
#define PHY_AUTONEG_ADVERTISE_REG 0x04U
#define PHY_AUTONEG_ADVERTISE_REG 0x04U
#if defined (PHY_USING_DM9162)
#define PHY_CONTROL_REG (0x00) /*!< basic mode control register */
#define PHY_STATUS_REG (0x01) /*!< basic mode status register */
#define PHY_SPECIFIED_CS_REG (0x11) /*!< specified configuration and status register */
/* phy control register */
#define PHY_AUTO_NEGOTIATION_BIT (0x1000) /*!< enable auto negotiation */
#define PHY_LOOPBACK_BIT (0x4000) /*!< enable loopback */
#define PHY_RESET_BIT (0x8000) /*!< reset phy */
/* phy status register */
#define PHY_LINKED_STATUS_BIT (0x0004) /*!< link status */
#define PHY_NEGO_COMPLETE_BIT (0x0020) /*!< auto negotiation complete */
/* phy specified control/status register */
#define PHY_FULL_DUPLEX_100MBPS_BIT (0x8000) /*!< full duplex 100 mbps */
#define PHY_HALF_DUPLEX_100MBPS_BIT (0x4000) /*!< half duplex 100 mbps */
#define PHY_FULL_DUPLEX_10MBPS_BIT (0x2000) /*!< full duplex 10 mbps */
#define PHY_HALF_DUPLEX_10MBPS_BIT (0x1000) /*!< half duplex 10 mbps */
#define PHY_DUPLEX_MODE (PHY_FULL_DUPLEX_100MBPS_BIT | PHY_FULL_DUPLEX_10MBPS_BIT) /*!< full duplex mode */
#define PHY_SPEED_MODE (PHY_FULL_DUPLEX_10MBPS_BIT | PHY_HALF_DUPLEX_10MBPS_BIT) /*!< 10 mbps */
/* the phy interrupt source flag register. */
#define PHY_INTERRUPT_FLAG_REG 0x15U
/* the phy interrupt mask register. */
#define PHY_INTERRUPT_MASK_REG 0x15U
#define PHY_LINK_CHANGE_FLAG (1<<2)
#define PHY_LINK_CHANGE_MASK (1<<9)
#define PHY_INT_MASK 0
#elif defined (PHY_USING_DP83848)
#define PHY_CONTROL_REG (0x00) /*!< basic mode control register */
#define PHY_STATUS_REG (0x01) /*!< basic mode status register */
#define PHY_SPECIFIED_CS_REG (0x10) /*!< phy status register */
/* phy control register */
#define PHY_AUTO_NEGOTIATION_BIT (0x1000) /*!< enable auto negotiation */
#define PHY_LOOPBACK_BIT (0x4000) /*!< enable loopback */
#define PHY_RESET_BIT (0x8000) /*!< reset phy */
/* phy status register */
#define PHY_LINKED_STATUS_BIT (0x0004) /*!< link status */
#define PHY_NEGO_COMPLETE_BIT (0x0020) /*!< auto negotiation complete */
#if defined(PHY_USING_DM9162)
#define PHY_CONTROL_REG (0x00) /*!< basic mode control register */
#define PHY_STATUS_REG (0x01) /*!< basic mode status register */
#define PHY_SPECIFIED_CS_REG (0x11) /*!< specified configuration and status register */
/* phy control register */
#define PHY_AUTO_NEGOTIATION_BIT (0x1000) /*!< enable auto negotiation */
#define PHY_LOOPBACK_BIT (0x4000) /*!< enable loopback */
#define PHY_RESET_BIT (0x8000) /*!< reset phy */
/* phy status register */
#define PHY_LINKED_STATUS_BIT (0x0004) /*!< link status */
#define PHY_NEGO_COMPLETE_BIT (0x0020) /*!< auto negotiation complete */
/* phy specified control/status register */
#define PHY_FULL_DUPLEX_100MBPS_BIT (0x8000) /*!< full duplex 100 mbps */
#define PHY_HALF_DUPLEX_100MBPS_BIT (0x4000) /*!< half duplex 100 mbps */
#define PHY_FULL_DUPLEX_10MBPS_BIT (0x2000) /*!< full duplex 10 mbps */
#define PHY_HALF_DUPLEX_10MBPS_BIT (0x1000) /*!< half duplex 10 mbps */
#define PHY_DUPLEX_MODE \
(PHY_FULL_DUPLEX_100MBPS_BIT | PHY_FULL_DUPLEX_10MBPS_BIT) /*!< full duplex mode */
#define PHY_SPEED_MODE (PHY_FULL_DUPLEX_10MBPS_BIT | PHY_HALF_DUPLEX_10MBPS_BIT) /*!< 10 mbps */
/* the phy interrupt source flag register. */
#define PHY_INTERRUPT_FLAG_REG 0x15U
/* the phy interrupt mask register. */
#define PHY_INTERRUPT_MASK_REG 0x15U
#define PHY_LINK_CHANGE_FLAG (1 << 2)
#define PHY_LINK_CHANGE_MASK (1 << 9)
#define PHY_INT_MASK 0
#elif defined(PHY_USING_DP83848)
#define PHY_CONTROL_REG (0x00) /*!< basic mode control register */
#define PHY_STATUS_REG (0x01) /*!< basic mode status register */
#define PHY_SPECIFIED_CS_REG (0x10) /*!< phy status register */
/* phy control register */
#define PHY_AUTO_NEGOTIATION_BIT (0x1000) /*!< enable auto negotiation */
#define PHY_LOOPBACK_BIT (0x4000) /*!< enable loopback */
#define PHY_RESET_BIT (0x8000) /*!< reset phy */
/* phy status register */
#define PHY_LINKED_STATUS_BIT (0x0004) /*!< link status */
#define PHY_NEGO_COMPLETE_BIT (0x0020) /*!< auto negotiation complete */
#define PHY_DUPLEX_MODE (0x0004) /*!< full duplex mode */
#define PHY_SPEED_MODE (0x0002) /*!< 10 mbps */
#define PHY_DUPLEX_MODE (0x0004) /*!< full duplex mode */
#define PHY_SPEED_MODE (0x0002) /*!< 10 mbps */
/* the phy interrupt source flag register. */
#define PHY_INTERRUPT_FLAG_REG 0x12U
#define PHY_LINK_CHANGE_FLAG (1<<13)
/* the phy interrupt control register. */
#define PHY_INTERRUPT_CTRL_REG 0x11U
#define PHY_INTERRUPT_EN ((1<<0)|(1<<1))
/* the phy interrupt mask register. */
#define PHY_INTERRUPT_MASK_REG 0x12U
#define PHY_INT_MASK (1<<5)
/* the phy interrupt source flag register. */
#define PHY_INTERRUPT_FLAG_REG 0x12U
#define PHY_LINK_CHANGE_FLAG (1 << 13)
/* the phy interrupt control register. */
#define PHY_INTERRUPT_CTRL_REG 0x11U
#define PHY_INTERRUPT_EN ((1 << 0) | (1 << 1))
/* the phy interrupt mask register. */
#define PHY_INTERRUPT_MASK_REG 0x12U
#define PHY_INT_MASK (1 << 5)
#elif defined(PHY_USING_LAN8720A)
#define PHY_CONTROL_REG (0x00) /*!< basic mode control register */
#define PHY_STATUS_REG (0x01) /*!< basic mode status register */
#define PHY_SPECIFIED_CS_REG (0x1F) /*!< phy status register */
/* phy control register */
#define PHY_AUTO_NEGOTIATION_BIT (0x1000) /*!< enable auto negotiation */
#define PHY_LOOPBACK_BIT (0x4000) /*!< enable loopback */
#define PHY_RESET_BIT (0x8000) /*!< reset phy */
/* phy status register */
#define PHY_LINKED_STATUS_BIT (0x0004) /*!< link status */
#define PHY_NEGO_COMPLETE_BIT (0x0020) /*!< auto negotiation complete */
#define PHY_DUPLEX_MODE (0x0100) /*!< full duplex mode */
#define PHY_SPEED_MODE (0x2000) /*!< 100 mbps */
#define PHY_FULL_DUPLEX_100MBPS_BIT (0x0018) /*!< full duplex 100 mbps */
#define PHY_HALF_DUPLEX_100MBPS_BIT (0x0008) /*!< half duplex 100 mbps */
#define PHY_FULL_DUPLEX_10MBPS_BIT (0x0014) /*!< full duplex 10 mbps */
#define PHY_HALF_DUPLEX_10MBPS_BIT (0x0004) /*!< half duplex 10 mbps */
#define PHY_DUPLEX_MBPS_MSK (0x001C)
/* The PHY interrupt source flag register. */
#define PHY_INTERRUPT_FLAG_REG (0x01DU)
#endif
#endif /* __DRV_EMAC_H__ */

View File

@ -367,6 +367,12 @@ static rt_size_t stm32_dma_transmit(struct rt_serial_device *serial, rt_uint8_t
return 0;
}
typedef struct err_count
{
rt_uint32_t count:16;
rt_uint32_t error_count:16;
} uart_err_count_t;
/**
* Uart common interrupt process. This need add to uart ISR.
*
@ -375,6 +381,7 @@ static rt_size_t stm32_dma_transmit(struct rt_serial_device *serial, rt_uint8_t
static void uart_isr(struct rt_serial_device *serial)
{
struct stm32_uart *uart;
rt_bool_t err_flag = RT_FALSE;
#ifdef RT_SERIAL_USING_DMA
rt_size_t recv_total_index, recv_len;
rt_base_t level;
@ -383,6 +390,7 @@ static void uart_isr(struct rt_serial_device *serial)
RT_ASSERT(serial != RT_NULL);
uart = rt_container_of(serial, struct stm32_uart, serial);
err_flag = (&(uart->handle))->Instance->SR & (UART_FLAG_NE | UART_FLAG_FE | UART_FLAG_PE);
/* UART in mode Receiver -------------------------------------------------*/
if ((__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_RXNE) != RESET) &&
(__HAL_UART_GET_IT_SOURCE(&(uart->handle), UART_IT_RXNE) != RESET))
@ -423,14 +431,17 @@ static void uart_isr(struct rt_serial_device *serial)
}
if (__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_NE) != RESET)
{
err_flag = RT_TRUE;
__HAL_UART_CLEAR_NEFLAG(&uart->handle);
}
if (__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_FE) != RESET)
{
err_flag = RT_TRUE;
__HAL_UART_CLEAR_FEFLAG(&uart->handle);
}
if (__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_PE) != RESET)
{
err_flag = RT_TRUE;
__HAL_UART_CLEAR_PEFLAG(&uart->handle);
}
#if !defined(SOC_SERIES_STM32L4) && !defined(SOC_SERIES_STM32WL) && !defined(SOC_SERIES_STM32F7) && !defined(SOC_SERIES_STM32F0) \
@ -466,6 +477,14 @@ static void uart_isr(struct rt_serial_device *serial)
UART_INSTANCE_CLEAR_FUNCTION(&(uart->handle), UART_FLAG_RXNE);
}
}
uart_err_count_t *err_count = (uart_err_count_t *)&uart->serial.parent.user_data;
err_count->count++;
if (err_flag)
{
err_count->error_count++;
__HAL_UART_CLEAR_PEFLAG(&uart->handle);
}
}
#ifdef RT_SERIAL_USING_DMA