commit af7ac02a5a4b0b91e3f4a8bf0f7744c9046484d3 Author: cfif Date: Fri Jan 24 13:22:32 2025 +0300 Перенос на новую организацию GONEC diff --git a/Inc/at32_emac.h b/Inc/at32_emac.h new file mode 100644 index 0000000..e29bf0e --- /dev/null +++ b/Inc/at32_emac.h @@ -0,0 +1,120 @@ +/** + ************************************************************************** + * @file at32_emac.h + * @version v2.0.4 + * @date 2021-12-31 + * @brief header file of 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. + * + ************************************************************************** + */ + +/* define to prevent recursive inclusion -------------------------------------*/ +#ifndef __AT32_EMAC_H +#define __AT32_EMAC_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* includes ------------------------------------------------------------------*/ +#include "at32f435_437.h" + +/** @addtogroup AT32F437_periph_examples + * @{ + */ + +/** @addtogroup 437_EMAC_tcp_server + * @{ + */ + +#define RX_REMAP (1) +#define CRYSTAL_ON_PHY (0) + +#define MII_MODE +//#define RMII_MODE + +#define DM9162 +//#define DP83848 + +#if defined (DM9162) + #define PHY_ADDRESS (0x03) /*!< relative to at32 board */ + #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 */ + + #define PHY_AUTO_NEG_REG (0x05) /*!< Auto-Negotiation Link Partner Ability Register */ + + /* 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_FULL_DUPLEX_100MBPS_BIT (0x0100) /*!< full duplex 100 mbps */ + #define PHY_HALF_DUPLEX_100MBPS_BIT (0x0080) /*!< half duplex 100 mbps */ + #define PHY_FULL_DUPLEX_10MBPS_BIT (0x0040) /*!< full duplex 10 mbps */ + #define PHY_HALF_DUPLEX_10MBPS_BIT (0x0020) /*!< half duplex 10 mbps */ + +#elif defined (DP83848) + #define PHY_ADDRESS (0x01) /*!< relative to at32 board */ + #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 */ +#endif + +error_status emac_system_init(void); +error_status emac_system_init_eth(void); +void emac_nvic_configuration(void); +void emac_pins_configuration(void); +error_status emac_layer2_configuration(void); +void static reset_phy(void); +error_status emac_phy_register_reset(void); +error_status emac_speed_config(emac_auto_negotiation_type nego, emac_duplex_type mode, emac_speed_type speed); +error_status emac_phy_init(emac_control_config_type *control_para); + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Inc/netconf.h b/Inc/netconf.h new file mode 100644 index 0000000..ab4b491 --- /dev/null +++ b/Inc/netconf.h @@ -0,0 +1,70 @@ +/** + ************************************************************************** + * @file netconf.h + * @version v2.0.4 + * @date 2021-12-31 + * @brief This file contains all the functions prototypes for the netconf.c + * file. + ************************************************************************** + * 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. + * + ************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __NETCONF_H +#define __NETCONF_H + +#ifdef __cplusplus + extern "C" { +#endif + +/** @addtogroup AT32F437_periph_examples + * @{ + */ + +/** @addtogroup 437_EMAC_tcp_server + * @{ + */ + +/** @addtogroup network_configuration_prototype + * @{ + */ +/* Includes ------------------------------------------------------------------*/ +void tcpip_stack_init(uint16_t data); +void lwip_pkt_handle(void); +void lwip_periodic_handle(volatile uint32_t localtime); +void lwip_pkt_set_queue_handle(osMessageQueueId_t EthDataQueue); +void lwip_pkt_get_queue_handle(struct pbuf *p); + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +/** + * @} + */ +#endif /* __NETCONF_H */ +/** + * @} + */ + + diff --git a/Src/at32_emac.c b/Src/at32_emac.c new file mode 100644 index 0000000..dc66a6c --- /dev/null +++ b/Src/at32_emac.c @@ -0,0 +1,538 @@ +/** + ************************************************************************** + * @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; +} + +/** + * @} + */ + +/** + * @} + */ diff --git a/Src/netconf.c b/Src/netconf.c new file mode 100644 index 0000000..e927433 --- /dev/null +++ b/Src/netconf.c @@ -0,0 +1,299 @@ +/** + ************************************************************************** + * @file netconf.c + * @version v2.0.4 + * @date 2021-12-31 + * @brief network connection configuration + ************************************************************************** + * 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 "lwip/memp.h" +#include "lwip/tcp.h" +#include "lwip/priv/tcp_priv.h" +#include "lwip/udp.h" +#include "netif/etharp.h" +#include "lwip/dhcp.h" +#include "ethernetif.h" +#include "../Inc/netconf.h" +#include "stdio.h" +#include "SystemDelayInterface.h" + +/** @addtogroup AT32F437_periph_examples + * @{ + */ + +/** @addtogroup 437_EMAC_tcp_server + * @{ + */ + +/** @addtogroup network_configuration + * @{ + */ + +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +#define MAC_ADDR_LENGTH (6) +#define ADDR_LENGTH (4) +/* Private variables ---------------------------------------------------------*/ +struct netif netif; +volatile uint32_t tcp_timer = 0; +volatile uint32_t arp_timer = 0; + +#include "MainModesArbiter.h" + +extern tMma MAIN_ENV; + +static uint8_t mac_address[MAC_ADDR_LENGTH] = {0, 0, 0x45, 0x45, 0x55, 3}; +#if LWIP_DHCP +volatile uint32_t dhcp_fine_timer = 0; +volatile uint32_t dhcp_coarse_timer = 0; +#else +static uint8_t local_ip[ADDR_LENGTH] = {192, 168, 1, 99}; +static uint8_t local_gw[ADDR_LENGTH] = {192, 168, 1, 1}; +static uint8_t local_mask[ADDR_LENGTH] = {255, 255, 255, 0}; +#endif + +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +int extract_ip_ex_parameters(char *params, char *param_names[], char *param_vals[], int params_max); + +/** + * @brief initializes the lwip stack + * @param none + * @retval none + */ +void tcpip_stack_init(uint16_t data) { + ip_addr_t ipaddr; + ip_addr_t netmask; + ip_addr_t gw; + + mac_address[4] = data >> 8; + mac_address[5] = data; + + + /* Initializes the dynamic memory heap defined by MEM_SIZE.*/ + mem_init(); + + /* Initializes the memory pools defined by MEMP_NUM_x.*/ + memp_init(); + + +#if LWIP_DHCP //need DHCP server + ipaddr.addr = 0; + netmask.addr = 0; + gw.addr = 0; + +#else + + char MyIPadres_v[32]; + char MyIPmask_v[32]; + char MyGateway_v[32]; + + + memcpy(MyIPadres_v, MAIN_ENV.storageIni.nvm.Settings_Network.MyIPadres_v, 32); + memcpy(MyIPmask_v, MAIN_ENV.storageIni.nvm.Settings_Network.MyIPmask_v, 32); + memcpy(MyGateway_v, MAIN_ENV.storageIni.nvm.Settings_Network.MyGateway_v, 32); + + + struct { + int paramcount; + char *params_names[4]; + char *params_vals[4]; + } params_grp; + + params_grp.paramcount = extract_ip_ex_parameters(MyIPadres_v, + params_grp.params_names, + params_grp.params_vals, + 4); + + if (params_grp.paramcount == 4) { + + uint32_t local_ip0 = atoi(params_grp.params_names[0]); + uint32_t local_ip1 = atoi(params_grp.params_names[1]); + uint32_t local_ip2 = atoi(params_grp.params_names[2]); + uint32_t local_ip3 = atoi(params_grp.params_names[3]); + + if (((local_ip0 < 255) && (local_ip0 > 0)) && ((local_ip1 < 255) && (local_ip1 > 0)) && + ((local_ip2 < 255) && (local_ip2 > 0)) && ((local_ip3 < 255) && (local_ip3 > 0))) { + + local_ip[0] = atoi(params_grp.params_names[0]); + local_ip[1] = atoi(params_grp.params_names[1]); + local_ip[2] = atoi(params_grp.params_names[2]); + local_ip[3] = atoi(params_grp.params_names[3]); + + } + } + + params_grp.paramcount = extract_ip_ex_parameters(MyIPmask_v, + params_grp.params_names, + params_grp.params_vals, + 4); + + if (params_grp.paramcount == 4) { + + uint32_t local_mask0 = atoi(params_grp.params_names[0]); + uint32_t local_mask1 = atoi(params_grp.params_names[1]); + uint32_t local_mask2 = atoi(params_grp.params_names[2]); + uint32_t local_mask3 = atoi(params_grp.params_names[3]); + + if (((local_mask0 <= 255) && (local_mask0 >= 0)) && ((local_mask1 <= 255) && (local_mask1 >= 0)) && + ((local_mask2 <= 255) && (local_mask2 >= 0)) && ((local_mask3 <= 255) && (local_mask3 >= 0))) { + + local_mask[0] = atoi(params_grp.params_names[0]); + local_mask[1] = atoi(params_grp.params_names[1]); + local_mask[2] = atoi(params_grp.params_names[2]); + local_mask[3] = atoi(params_grp.params_names[3]); + } + } + + params_grp.paramcount = extract_ip_ex_parameters(MyGateway_v, + params_grp.params_names, + params_grp.params_vals, + 4); + + if (params_grp.paramcount == 4) { + uint32_t local_gw0 = atoi(params_grp.params_names[0]); + uint32_t local_gw1 = atoi(params_grp.params_names[1]); + uint32_t local_gw2 = atoi(params_grp.params_names[2]); + uint32_t local_gw3 = atoi(params_grp.params_names[3]); + + if (((local_gw0 < 255) && (local_gw0 > 0)) && ((local_gw1 < 255) && (local_gw1 > 0)) && + ((local_gw2 < 255) && (local_gw2 > 0)) && ((local_gw3 < 255) && (local_gw3 > 0))) { + + local_gw[0] = atoi(params_grp.params_names[0]); + local_gw[1] = atoi(params_grp.params_names[1]); + local_gw[2] = atoi(params_grp.params_names[2]); + local_gw[3] = atoi(params_grp.params_names[3]); + } + } + + IP4_ADDR(&ipaddr, local_ip[0], local_ip[1], local_ip[2], local_ip[3]); + IP4_ADDR(&netmask, local_mask[0], local_mask[1], local_mask[2], local_mask[3]); + IP4_ADDR(&gw, local_gw[0], local_gw[1], local_gw[2], local_gw[3]); +#endif + + lwip_set_mac_address(mac_address); + + /* - netif_add(struct netif *netif, struct ip_addr *ipaddr, + struct ip_addr *netmask, struct ip_addr *gw, + void *state, err_t (* init)(struct netif *netif), + err_t (* input)(struct pbuf *p, struct netif *netif)) + + Adds your network interface to the netif_list. Allocate a struct + netif and pass a pointer to this structure as the first argument. + Give pointers to cleared ip_addr structures when using DHCP, + or fill them with sane numbers otherwise. The state pointer may be NULL. + + The init function pointer must point to a initialization function for + your ethernet netif interface. The following code illustrates it's use.*/ + + if (netif_add(&netif, &ipaddr, &netmask, &gw, NULL, ðernetif_init, &netif_input) == NULL) { + while (1); + } + + /* Registers the default network interface.*/ + netif_set_default(&netif); + +#if LWIP_DHCP + /* Creates a new DHCP client for this interface on the first call. + Note: you must call dhcp_fine_tmr() and dhcp_coarse_tmr() at + the predefined regular intervals after starting the client. + You can peek in the netif->dhcp struct for the actual DHCP status.*/ + dhcp_start(&netif); +#endif + + /* When the netif is fully configured this function must be called.*/ + netif_set_up(&netif); +} + +/** + * @brief called when a frame is received + * @param none + * @retval none + */ +void lwip_pkt_handle(void) { + /* Read a received packet from the Ethernet buffers and send it to the lwIP for handling */ + if (ethernetif_input(&netif) != ERR_OK) { + while (1); + } +} + +void lwip_pkt_set_queue_handle(osMessageQueueId_t EthDataQueue) { + /* Read a received packet from the Ethernet buffers and send it to the lwIP for handling */ + if (ethernetif_set_queue_input(&netif, EthDataQueue) != ERR_OK) { +// while (1); + } +} + + +void lwip_pkt_get_queue_handle(struct pbuf *p) { + /* Read a received packet from the Ethernet buffers and send it to the lwIP for handling */ + if (ethernetif_get_queue_input(&netif, p) != ERR_OK) { +// while (1); + } +} + + +/** + * @brief lwip periodic tasks + * @param localtime the current localtime value + * @retval none + */ +void lwip_periodic_handle(volatile uint32_t localtime) { + + /* TCP periodic process every 250 ms */ + if (localtime - tcp_timer >= TCP_TMR_INTERVAL) { + tcp_timer = localtime; + tcp_tmr(); + } + /* ARP periodic process every 5s */ + if (localtime - arp_timer >= ARP_TMR_INTERVAL) { + arp_timer = localtime; + etharp_tmr(); + } + +#if LWIP_DHCP + /* Fine DHCP periodic process every 500ms */ + if (localtime - dhcp_fine_timer >= DHCP_FINE_TIMER_MSECS) + { + dhcp_fine_timer = localtime; + dhcp_fine_tmr(); + } + /* DHCP Coarse periodic process every 60s */ + if (localtime - dhcp_coarse_timer >= DHCP_COARSE_TIMER_MSECS) + { + dhcp_coarse_timer = localtime; + dhcp_coarse_tmr(); + } +#endif +} + +/** + * @} + */ + +/** + * @} + */ +/** + * @} + */ diff --git a/modular.json b/modular.json new file mode 100644 index 0000000..5c93012 --- /dev/null +++ b/modular.json @@ -0,0 +1,17 @@ +{ + "dep": [ + { + "type": "git", + "provider": "GONEC", + "repo": "lwip_ARTERY_AT32" + } + ], + "cmake": { + "inc_dirs": [ + "Inc" + ], + "srcs": [ + "Src/**.c" + ] + } +} \ No newline at end of file