stm32f107 Ethernet + rl-tcpnet

Source: Internet
Author: User
Tags goto

Copyright: Chengdu Heng Yuan Internet of Things Technology Co., Ltd.

Website: www.heryit.cn

Tel: 028-87657875 13060063607

Introduce the configuration of stm32f107 Ethernet and porting rl-tcpnet protocol stack, the official routine is LWIP, here is how to use rl-tcpnet. (need to include STM32_ETH.C and STM32_ETH.H)

Here is the descriptor definition, what is the descriptor please see the STM32 Chinese Reference Manual Ethernet Chapter

/* 描述符数量和缓存大小定义 */#define NUM_RX_BUF          4      //接收描述符数量和缓存数量#define NUM_TX_BUF          2      //发送描述符数量和缓存数量#define ETH_BUF_SIZE        1536   //每个缓存大小/* 接收描述符和发送描述符结构体类型定义(含义请参考STM32中文参考手册) */typedef struct {  U32 volatile Stat;  U32 Ctrl;  U32 Addr;  U32 Next;} RX_Desc;typedef struct {  U32 volatile CtrlStat;  U32 Size;  U32 Addr;  U32 Next;} TX_Desc;/* 当前使用的描述符序号 */static U8 TxBufIndex;static U8 RxBufIndex;/* DMA描述符声明 */static RX_Desc Rx_Desc[NUM_RX_BUF];static TX_Desc Tx_Desc[NUM_TX_BUF];/* 描述符所指向的内存 */static U32 rx_buf[NUM_RX_BUF][ETH_BUF_SIZE>>2];static U32 tx_buf[NUM_TX_BUF][ETH_BUF_SIZE>>2];

To use the Rl-tcpnet protocol stack, you need to provide an interface function for rl-tcpnet: void init_ethernet (void);     void Send_frame (Os_frame *frame);     void Int_enable_eth (void); void Int_disable_eth (void); The following are the corresponding functions:

Ethernet Hardware initialization (interface provided to rl-tcpnet) void init_ethernet (void) {nvic_inittypedef nvic_initstructure;    Gpio_inittypedef gpio_initstructure;    Eth_inittypedef eth_initstructure;    #define Time_out 0x0003fffful uint32_t time = 0; /* Enable clock */Rcc_ahbperiphclockcmd (Rcc_ahbperiph_eth_mac |                          Rcc_ahbperiph_eth_mac_tx |    RCC_AHBPERIPH_ETH_MAC_RX, ENABLE); /* Enable GPIO clock */rcc_apb2periphclockcmd (Rcc_apb2periph_gpioa | Rcc_apb2periph_gpiob |                           RCC_APB2PERIPH_GPIOC | Rcc_apb2periph_gpiod | Rcc_apb2periph_gpioe |    Rcc_apb2periph_afio, ENABLE);    /* Select interrupt vector table */nvic_setvectortable (Nvic_vecttab_flash, 0x0);     Nvic_prioritygroupconfig (nvic_prioritygroup_2);    /* Enable Ethernet Global Interrupt */Nvic_initstructure.nvic_irqchannel = ETH_IRQN;    Nvic_initstructure.nvic_irqchannelpreemptionpriority = 2;    nvic_initstructure.nvic_irqchannelsubpriority = 0;    Nvic_initstructure.nvic_irqchannelcmd = ENABLE; Nvic_init (&nvic_Initstructure); /* Ethernet PIN configuration currently using the RMII interface, no remapping required to use the Mii interface please modify */* AF Output Push Pull by yourself:-eth_rmii_mdio:pa2-eth_rmi  I_MDC:PC1-ETH_RMII_TX_EN:PB11-ETH_RMII_TXD0:PB12-ETH_RMII_TXD1:PB13 */* Configure PA2 as alternate    function Push-pull */gpio_initstructure.gpio_pin = gpio_pin_2;    Gpio_initstructure.gpio_speed = Gpio_speed_50mhz;    Gpio_initstructure.gpio_mode = gpio_mode_af_pp;    Gpio_init (Gpioa, &gpio_initstructure);    /* Configure PC1 as alternate function push-pull */gpio_initstructure.gpio_pin = gpio_pin_1;    Gpio_initstructure.gpio_speed = Gpio_speed_50mhz;    Gpio_initstructure.gpio_mode = gpio_mode_af_pp;    Gpio_init (GPIOC, &gpio_initstructure);  /* Configure PB5, PB8, PB11, PB12 and PB13 as alternate function push-pull */Gpio_initstructure.gpio_pin = Gpio_pin_11 | Gpio_pin_12 |    gpio_pin_13;    Gpio_initstructure.gpio_speed = Gpio_speed_50mhz;    Gpio_initstructure.gpio_mode = gpio_mode_af_pp; Gpio_iNIT (GPIOB, &gpio_initstructure); /* Input:-ETH_RMII_REF_CLK:PA1-ETH_RMII_CRS_DV:PA7-ETH_RMII_RXD0:PC4-ETH_RMII_RXD1:PC5 */* Con Figure PA1 and PA7 as input */Gpio_initstructure.gpio_pin = gpio_pin_1 |    gpio_pin_7;    Gpio_initstructure.gpio_speed = Gpio_speed_50mhz;    Gpio_initstructure.gpio_mode = gpio_mode_in_floating;    Gpio_init (Gpioa, &gpio_initstructure); /* Configure PC4 and PC5 as input */Gpio_initstructure.gpio_pin = Gpio_pin_4 |    Gpio_pin_5;    Gpio_initstructure.gpio_speed = Gpio_speed_50mhz;    Gpio_initstructure.gpio_mode = gpio_mode_in_floating;    Gpio_init (GPIOC, &gpio_initstructure);    /* Select configured as Mii or RMII, currently rmii*/gpio_eth_mediainterfaceconfig (GPIO_ETH_MEDIAINTERFACE_RMII);    /* Reset Ethernet */Eth_deinit ();    Eth_softwarereset ();    /* Wait for the reset to complete */while (eth_getsoftwareresetstatus () = = SET);    /* Ethernet configuration, populate the eth_initstructure structure, and finally call Eth_init () to configure Ethernet */Eth_structinit (&eth_initstructure); /*------------------------MAC-----------------------------------*/eth_initstructure.eth_autonegotiation = eth_autonegotiation_enable    ;    Eth_initstructure.eth_loopbackmode = eth_loopbackmode_disable;    Eth_initstructure.eth_retrytransmission = eth_retrytransmission_disable;    Eth_initstructure.eth_automaticpadcrcstrip = eth_automaticpadcrcstrip_disable;    Eth_initstructure.eth_receiveall = eth_receiveall_disable;    Eth_initstructure.eth_broadcastframesreception = eth_broadcastframesreception_enable;    Eth_initstructure.eth_promiscuousmode = eth_promiscuousmode_disable;    Eth_initstructure.eth_multicastframesfilter = Eth_multicastframesfilter_perfect;    Eth_initstructure.eth_unicastframesfilter = Eth_unicastframesfilter_perfect;    #ifdef Checksum_by_hardware eth_initstructure.eth_checksumoffload = eth_checksumoffload_enable; #endif/*------------------------DMA-----------------------------------*/Eth_initstructure.eth_droptcpipche Cksumerrorframe = Eth_droptcpipchecksumerrorframe_enable;             Eth_initstructure.eth_receivestoreforward = eth_receivestoreforward_enable;         Eth_initstructure.eth_transmitstoreforward = eth_transmitstoreforward_enable;           Eth_initstructure.eth_forwarderrorframes = eth_forwarderrorframes_disable;       Eth_initstructure.eth_forwardundersizedgoodframes = eth_forwardundersizedgoodframes_disable;                                                              Eth_initstructure.eth_secondframeoperate = eth_secondframeoperate_enable;          Eth_initstructure.eth_addressalignedbeats = eth_addressalignedbeats_enable;                    Eth_initstructure.eth_fixedburst = eth_fixedburst_enable;              Eth_initstructure.eth_rxdmaburstlength = Eth_rxdmaburstlength_32beat;                                                                     Eth_initstructure.eth_txdmaburstlength = Eth_txdmaburstlength_32beat;    Eth_initstructure.eth_dmaarbitration = Eth_dmaarbitration_roundrobin_rxtx_2_1; /* Initialize Ethernet, the second parameter is phY chip Address */Eth_init (&eth_initstructure, lan9303_vphy_addr);    Receive descriptor initialization rx_descr_init ();    Send descriptor initialization tx_descr_init (); /* Enable normal total interrupt and receive interrupt */Eth_dmaitconfig (Eth_dma_it_nis |    Eth_dma_it_r, ENABLE); Enable to send and receive ETH-&GT;DMAOMR |= Domr_st |    DOMR_SR; ETH-&GT;MACCR |= Mcr_re |    Mcr_te; Configure the MAC address, otherwise you can only receive broadcast data Eth_macaddressconfig (ETH_MAC_ADDRESS0, Own_hw_adr);} Enable and disable Ethernet interrupts void Int_enable_eth (void) {/* Ethernet Interrupt Enable function. */nvic->iser[1] = 1 << 29; }void Int_disable_eth (void) {/* Ethernet Interrupt Disable function. */nvic->icer[1] = 1 << 29;}    Send a frame of data (interface function provided to rl-tcpnet) void Send_frame (Os_frame *frame) {U32 *sp,*dp;    U32 i,j;    j = Txbufindex; /* Wait until the data is sent */while (Tx_desc[j].    Ctrlstat & Dma_tx_own);    SP =** (U32 *) &frame->data[0]; DP = (U32 *) tx_desc[j].    ADDR;    /* Copy the data that needs to be sent to the memory specified by the Send descriptor */for (i = (frame->length + 3) >> 2; i; i--) {*dp++ = *sp++;  }//Send data volume  TX_DESC[J].    Size = frame->length; Modify send descriptor belongs to DMA Tx_desc[j].    Ctrlstat |= Dma_tx_own; /* Write data to DMATPDR to begin DMA Transfer */if ((Eth->dmasr |        Dsr_tbus)!*= 0) {Eth->dmasr = Dsr_tbus;    ETH-&GT;DMATPDR = 0;    } if (++j = = num_tx_buf) j = 0; Txbufindex = j;}

The above is the interface function that needs to be provided to rl-tcpnet.

Interrupt Service function for receiving Ethernet data.

Ethernet Interrupt Service function (for receiving Ethernet data) void Eth_irqhandler (void) {/* Ethernet Controller Interrupt function. */Os_frame *frame;    U32 I,rxlen;    U32 *SP,*DP;    i = Rxbufindex; do {/* Valid frame has been received. */* if (Rx_desc[i].        Stat & Dma_rx_error_mask) {goto rel; } if ((Rx_desc[i].        Stat & dma_rx_seg_mask)! = dma_rx_seg_mask) {goto rel; } Rxlen = ((rx_desc[i).        Stat >>) & 0X3FFF)-4;        if (Rxlen > Eth_mtu) {/* Packet too big, ignore it and free buffer. */goto rel; }/* Flag 0x80000000 to skip Sys_error () call when out of memory.        */frame = Alloc_mem (Rxlen | 0x80000000); /* if ' alloc_mem () ' have failed, ignore this packet. */if (frame! = NULL) {SP = (U32 *) (Rx_desc[i].            Addr &);            DP = (U32 *) &frame->data[0]; for (Rxlen = (Rxlen + 3) >> 2; Rxlen; rxlen--) {*dp++ = *sp++;        } put_in_queue (frame); }/* Release this frame from ETH IO buffer. */rel:rx_desc[i].        Stat = Dma_rx_own;    if (++i = = num_rx_buf) i = 0; } while ((Rx_desc[i].    Stat & dma_rx_own) = = 0);    Rxbufindex = i; if (Eth->dmasr & Int_rbuie) {/* Rx DMA suspended, resume DMA reception. */Eth->dmasr = Int_rbu        IE;    ETH-&GT;DMARPDR = 0; }/* Clear the Interrupt pending bits. */Eth->dmasr = Int_nise | Int_rie;}

Receive descriptor Initialization

//接收描述符初始化static void rx_descr_init (void) {    /* Initialize Receive DMA Descriptor array. */    U32 i,next;    RxBufIndex = 0;    for (i = 0, next = 0; i < NUM_RX_BUF; i++) {        if (++next == NUM_RX_BUF) next = 0;        Rx_Desc[i].Stat = DMA_RX_OWN;        Rx_Desc[i].Ctrl = DMA_RX_RCH | ETH_BUF_SIZE;        Rx_Desc[i].Addr = (U32)&rx_buf[i];        Rx_Desc[i].Next = (U32)&Rx_Desc[next];    }    //指向第一个描述符    ETH->DMARDLAR = (U32)&Rx_Desc[0];}

Send Descriptor initialization

//发送描述符初始化static void tx_descr_init (void) {    /* Initialize Transmit DMA Descriptor array. */    U32 i,next;    TxBufIndex = 0;    for (i = 0, next = 0; i < NUM_TX_BUF; i++) {        if (++next == NUM_TX_BUF) next = 0;        Tx_Desc[i].CtrlStat = DMA_TX_TCH | DMA_TX_LS | DMA_TX_FS;        Tx_Desc[i].Addr     = (U32)&tx_buf[i];        Tx_Desc[i].Next     = (U32)&Tx_Desc[next];    }    //指向第一个描述符    ETH->DMATDLAR = (U32)&Tx_Desc[0];}

To do this, add the Rl-tcpnet library and configuration file to the project to use Rl-tcpnet, and refer to the Rl-arm Help documentation for use.

stm32f107 Ethernet + rl-tcpnet

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.