一直以来都想搞个寄存器配置版本的ETH,最近时间充裕,花了近2周,昨天终于实现了以太网的连接,上图 % ^* J8 _5 q w* Q& ?+ G
6 K3 l) z; w5 p: W! m7 x8 l, `, ` E" Y6 i* c0 e, q; H4 T
j7 i" s# f6 ~# P$ {! Q* ^- N
* W3 J9 q& K8 _5 i8 n, C+ _
这是打印结果
1 [3 l5 c1 M- {# U 下面详细说明一下
& c1 ~" D( p. ] 首先实现lan8742的驱动
+ O: {7 W3 ^+ e) k4 W+ @- /* Ethernet pins configuration ************************************************/% e3 \+ G8 W7 X2 z7 {$ L6 V
- /*) p3 E ^- ~3 ]% Q" f+ @
- RMII_REF_CLK ----------------------> PA1. e. A3 h z) U/ v; M* u# I6 |
- RMII_MDIO -------------------------> PA2# i8 n5 r( i8 a# s9 _( N+ V9 O0 ]% z5 z
- RMII_MDC --------------------------> PC1* x4 f |/ h) M
- RMII_MII_CRS_DV -------------------> PA7
5 a* r8 c" N" s7 [+ T. b - RMII_MII_RXD0 ---------------------> PC4' O4 G5 q( R& ]5 ]0 ~! |
- RMII_MII_RXD1 ---------------------> PC5
& `1 i6 X' L1 i, o0 [* Z - RMII_MII_RXER ---------------------> PG2/PD5" u( Y8 F: }3 P" I
- RMII_MII_TX_EN --------------------> PG115 N1 T; K+ f4 b5 v2 X: S$ o; Y
- RMII_MII_TXD0 ---------------------> PG13
4 K+ x7 L# j% @( c5 _ - RMII_MII_TXD1 ---------------------> PG14# b% b. `3 v& a9 S5 |6 h) H
- */
9 \/ P1 d9 ~) F; G3 q4 f/ h/ `% { - *(uint32_t *)0x40023830 |= 0x45; //使能PORTA\C\G时钟 0x4d,ACDG
2 \+ S5 v; I# X: p% S. r6 h% r/ W - *(uint32_t *)0x40023830 |= 0xf000000; //使能ETH,TX,RX,MAC时钟 $ y4 G, X- w7 K$ s7 X F. b
- GPIO_Set(GPIOA,PIN1|PIN2|PIN7,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_100M,GPIO_PUPD_NONE); //PB3,PB4设置
- s/ r$ Z- y1 \7 R' j - GPIO_AF_Set(GPIOA,1,11); //PA1,AF11
) \' K7 K$ k4 ]! O - GPIO_AF_Set(GPIOA,2,11); //PA2,AF11& H* ?5 g% o5 F$ f) U% t2 f0 k: A5 K
- GPIO_AF_Set(GPIOA,7,11); //PA7,AF11
2 \* S3 j( }2 ^: r$ C& B- L& C - GPIO_Set(GPIOC,PIN1|PIN4|PIN5,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_100M,GPIO_PUPD_NONE); //PB3,PB4设置
- e. B& v/ `. H9 b - GPIO_AF_Set(GPIOC,1,11); //PC1,AF110 u/ W" N4 r# k
- GPIO_AF_Set(GPIOC,4,11); //PC4,AF11
4 E) _4 }" e" k9 s - GPIO_AF_Set(GPIOC,5,11); //PC5,AF117 X8 @# Z( A6 L5 V
- GPIO_Set(GPIOD,PIN5,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_100M,GPIO_PUPD_NONE); //PB3,PB4设置
2 g4 c i. {/ y$ q - GPIO_AF_Set(GPIOD,5,11); //PD5,AF11
$ ]: y8 Y) Y/ S! U$ w+ O6 k5 V2 X* W - GPIO_Set(GPIOG,PIN2|PIN11|PIN13|PIN14,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_100M,GPIO_PUPD_NONE); //PB3,PB4设置
4 p( S! w9 P: A+ [4 R v/ ~6 c - GPIO_AF_Set(GPIOG,2,11); //PG2,AF11
6 L" K$ {& _; F, ^% L9 i1 a- e1 E - GPIO_AF_Set(GPIOG,11,11); //PG11,AF115 D0 i; p4 I% R. E. z" r/ [3 s
- GPIO_AF_Set(GPIOG,13,11); //PG13,AF11* z8 ?6 t& G2 O
- GPIO_AF_Set(GPIOG,14,11); //PG14,AF11
: s3 a) _/ _! Y1 q, z5 s) N - , Y; z8 N5 g8 t( p- i
- MY_NVIC_Init(0,0,ETH_IRQn,2); //配置ETH中的分组
复制代码 然后实现LAN8742寄存器的配置
2 h3 C' G5 e' l+ d2 ~- *(uint32_t *)0x40023830 |= 0x400000;
/ j1 e* h F4 q5 {6 p - RCC->AHB1RSTR |= 0x02000000;
7 c) c& f. n$ s4 }" M: r* I% X- ]2 ~ - /* Enable SYSCFG Clock */
# y0 ^" w& u7 P2 { i0 | - *(uint32_t *)0x40023844 |= 0x4000;
0 A0 `' {, U3 I4 P% n) e/ Z - SYSCFG->PMC &= ~(SYSCFG_PMC_MII_RMII_SEL);
, R5 F/ G6 g' c8 f - SYSCFG->PMC |= 0x800000;//RMII
4 i4 i7 m2 O! ]# @6 W" T - RCC->AHB1RSTR &= ~ 0x02000000;" ?; j6 i, A; A
- ETH->DMABMR |= 0x1; //software reset
0 b* U* C4 o& T& y1 U - while (ETH->DMABMR & ETH_DMABMR_SR);
7 r& D+ t4 J- ] - 8 H7 [; |1 W5 b
- /* Write to ETHERNET MAC MIIAR: Configure the ETHERNET CSR Clock Range */! c* u) A6 b4 G: x) U2 v4 j5 n
- ETH->MACMIIAR = (uint32_t)(1<<4);
# t1 I, [# t7 K3 G* k - write_PHY(PHY_BCR, PHY_RESET);
+ X) Z: X( }2 O - /* 等待复位完成 */
0 _: }) g' }' ^3 h) _/ s/ L5 ] - for (tout = 0; tout < 0x10000; tout++)
$ K" {( F$ E& I# [ - {# `* Y( @" g6 V) w1 e# F& R; W
- read_PHY (PHY_BSR,®v);
! {8 `' w: c% Q+ `8 b. } - if (!(regv & PHY_LINKED_STATUS))- V9 O5 H1 \. R; \
- {( B- _0 a, D4 k% T) U
- /* 复位完成 */4 l5 Z; c& @' R- K- G
- printf("2. Reset Complete\r\n");
9 }& V2 D9 Y- r - break;
0 ^* r7 T* ~/ d% u" y8 E4 n - } % T5 S- _9 y8 _% D V3 y
- }
( ^! `' @" w ?6 c, v; E - write_PHY(PHY_BCR, PHY_AUTONEGOTIATION);
. Y+ ~" j7 j6 d8 v - for (tout = 0; tout < 0x10000; tout++)
& B3 l2 {: N o" O6 _0 I0 O - {4 P. l$ R- N5 @
- read_PHY (PHY_BSR,®v);* b' u E4 y. K. v9 X
- if (!(regv & PHY_AUTONEGO_COMPLETE))
8 O3 m) v2 p0 Y+ p3 U/ w - {
& i; ^/ G, Y" K& Y. |! l& K3 K - /* 复位完成 */
$ ]$ B& F4 e! j( D* t5 U - printf("3. Auto-Negotiation Complete\r\n");& T8 V# J( b, z
- break;( F$ |/ g# {% e* |: h$ b- I8 T1 O
- }
. R7 I6 i: O: T0 W% S1 l - }0 s: |) S' g2 C6 _$ [
- for (tout = 0; tout < 0x1000; tout++);1 C9 J9 s% z6 i5 p
- read_PHY (PHY_SR,®v);
+ s, _# {5 f1 |1 ^1 A# i" O - printf("%x\r\n",regv);- P N( R9 ^ z; I' `# {" I! N
- /* Configure the MAC with the Duplex Mode fixed by the auto-negotiation process */
' _2 J/ p _# e# ?+ _. e: r7 p - if((regv & PHY_DUPLEX_STATUS) != (uint32_t)RESET)
, I; [ I: u& u+ B) Q, r% x - {& E% ?" a) [! `1 g4 ?4 ^
- /* Set Ethernet duplex mode to Full-duplex following the auto-negotiation */
+ g% s0 e- \4 y8 j j) [4 |* u; E - printf("4. Full-duplex connection\r\n");
. X; n! O: n$ H5 u2 I - phyreg |= ETH_MODE_FULLDUPLEX;; s1 M8 v- \1 w
- }# M9 A6 K, I' B% ~- t4 W: e9 V7 e2 `4 ]
- else ?# Q5 q L7 g. _2 q7 v1 J
- {
) v! h- k+ o5 q: M; x - /* Set Ethernet duplex mode to Half-duplex following the auto-negotiation */9 f0 Q4 g5 s$ @4 n. d1 r# W
- printf("4. half-duplex connection\r\n"); 5 g7 u/ M" ?( u7 Z4 r" i- l
- phyreg |= ETH_MODE_HALFDUPLEX; 9 K8 j6 n9 C# e
- }
5 \; Q& Z& K6 j1 s0 X/ K - if((regv & PHY_SPEED_STATUS) != (uint32_t)RESET)
9 t$ G: n2 c5 q+ L8 f - {
% _% G) ?8 L) z, j" l6 {$ v - /* Set Ethernet duplex mode to Full-duplex following the auto-negotiation */
% R' {$ [! Y" L& x" A% [6 B8 \: W% ^ - printf("5. 10Mbps Mode\r\n"); / c( `8 e; Z- ]: B+ E+ ]
- phyreg |= ETH_SPEED_10M;
- ~& w; [8 C ]! g4 [# X - }
3 m" L4 G) X. C/ @. a - else% G8 d5 I* j9 ]' T0 h
- {
% ?/ Z7 }* w1 x+ V" J - /* Set Ethernet duplex mode to Half-duplex following the auto-negotiation */4 \5 t* N/ x9 V& J1 A
- printf("5. 100Mbps Mode\r\n");
& n( l% I& C$ ^2 n - phyreg |= ETH_SPEED_100M;
V3 B: `6 T) h0 n# P: w5 [ - }: [* _! s2 j/ y9 d+ b3 s
- & V# L j/ [# f4 P: Z
- /* Config MAC and DMA */ g \0 ]! [9 h
- ETH_MACDMAConfig(heth, phyreg);
复制代码 下面是实现读写的函数( Q% Q* R: y5 S, F7 @- w$ g- `6 M
- void write_PHY (uint32_t PhyReg, uint16_t RegValue)
9 B5 V' {- N! }5 y' R6 y, @) d( Q. N" y - {! s, ?5 y# e* R: T# R
- uint32_t tout;* W- K$ x m0 b* ^8 `" J) W
- uint32_t tmpreg = 0;
9 k. g' q2 S4 o, I! a- u" S
( @4 w5 D( R; T- ETH->MACMIIDR = (uint16_t)RegValue;5 B3 p* Q- q6 G) c4 f. @
9 V) \8 m0 j& f+ S J% n2 h- ! T1 j% t* Q% I9 ^3 Z9 ]
- /* Get the ETHERNET MACMIIAR value */1 P9 T$ s3 ]1 C' k" F2 b' {+ C1 C
- tmpreg = ETH->MACMIIAR;" S3 \& ]* @7 ]% t) P
- + v2 N; |" ~ ^% U7 B
- /* Keep only the CSR Clock Range CR[2:0] bits value */
1 o( W" O" ~! J: p% T0 y9 X! s" I - tmpreg &= ~ETH_MACMIIAR_CR_MASK;0 ~2 B; s* F1 ^1 a6 u' u ?
- ; T" L+ O0 u8 ]$ L3 U1 I
- /* Prepare the MII register address value */1 G6 ]6 Y. H% u) S9 V: }1 F9 }
- tmpreg |=(((uint32_t)(LAN8742A_PHY_ADDRESS << 11)) & ETH_MACMIIAR_PA); /* Set the PHY device address */
& a' t7 X5 X) E1 {: q3 f - tmpreg |=(((uint32_t)PhyReg<<6) & ETH_MACMIIAR_MR); /* Set the PHY register address */2 X3 x( {$ B) x
- tmpreg |= ETH_MACMIIAR_MW; /* Set the write mode */
# v6 T q; r0 h8 {( T. H - tmpreg |= ETH_MACMIIAR_MB; /* Set the MII Busy bit */7 v9 H5 C" G' s* g( X" `0 y
- 8 k5 E4 k0 Z9 W9 o. }) M' A6 P6 I& i
- /* Write the result value into the MII Address register */
. r9 M. h( p* }/ z1 t - ETH->MACMIIAR = tmpreg;
& _' V+ U0 j0 _* R- L: Z - /* 等待操作完成,即等待MMAR_MB位被清零 */$ A" V5 ?& ?3 m/ P3 D2 f
- tout = 0;
. h) D$ t- D4 e) ^ - for (tout = 0; tout < MII_WR_TOUT; tout++) 5 |( u% w2 ]& _5 c! Y# v
- {
) Q" i: S2 u# @/ c" ~, N& N - if ((ETH->MACMIIAR & ETH_MACMIIAR_MB) == 0) + e, U. h3 O7 ]' ?. `+ t
- {
. N6 z7 ?% A+ D8 f" P% o& u- {5 v# h - break;8 K- C( x- H% l; C, J; l* a
- }
( X9 Z _( v5 I1 m! T2 f/ K" N - }) s$ Y& C& j/ t4 C7 n* u% n
- }$ g# \' A# I6 a# R2 Z& b
3 P& c5 z, T7 j* R$ i5 B- void read_PHY (uint32_t PhyReg,uint32_t *RegValue) . A, F6 h+ B! y0 z) x/ W& {
- {( G+ r/ I% k) r% N' u0 q) X9 p5 t
- uint32_t tout;0 ?! E2 r, C2 O# y
- uint32_t tmpreg = 0; , r0 l" Q: {$ G# ^, H+ G
( P! a4 G7 _& ^- tmpreg = ETH->MACMIIAR; l4 c @& w9 K3 E$ A1 |
- : b9 L7 h# I4 Y% v# e. r
- /* Keep only the CSR Clock Range CR[2:0] bits value */
. t/ W, R$ L6 H7 X/ L) G h/ j - tmpreg &= ~ETH_MACMIIAR_CR_MASK;* O' C. n9 W9 `: G8 p* B" E4 P# j
- ) w7 O0 X% g4 {" m. ?, g6 s3 K- u) p
- /* Prepare the MII address register value */0 D- m x+ E9 A+ }3 a* t! h
- tmpreg |=(((uint32_t)(LAN8742A_PHY_ADDRESS << 11)) & ETH_MACMIIAR_PA); /* Set the PHY device address */
+ e P# j5 O5 W9 P$ Y) }, P- E - tmpreg |=(((uint32_t)PhyReg<<6) & ETH_MACMIIAR_MR); /* Set the PHY register address */
: h8 R9 C' y4 Y9 {" ]4 V; j - tmpreg &= ~ETH_MACMIIAR_MW; /* Set the read mode */" [. o/ B& D5 p. b) e$ v3 R2 e
- tmpreg |= ETH_MACMIIAR_MB; /* Set the MII Busy bit */7 F& u) u" \' _. h
- 4 b% _- `- |9 H! ^. Q1 f
- /* Write the result value into the MII Address register */
1 o; S$ C/ [) t4 R - ETH->MACMIIAR = tmpreg;
2 ^5 e' {: f% d8 j# |$ h3 \" C
3 _6 e" f5 i0 F7 ^# M- /* 等待操作完成,即等待MMAR_MB位被清零 */
0 V+ z4 F% B! `+ ?# l: r - tout = 0; f% c5 r/ J9 E, R
- for (tout = 0; tout < MII_RD_TOUT; tout++) : F5 v# e* v% L' d, F' _2 `
- {
0 \$ o0 ~1 M N$ W - if ((ETH->MACMIIAR & ETH_MACMIIAR_MB) == 0) + H i' w$ Q( e9 J' b
- {. U: V& l' L$ }% C5 j- ]
- break;
T2 e0 O/ e. I - }
1 ]$ |, a& k9 p9 _ ] - }9 z* B/ S& k5 M$ Y# R: I: Q
- /* Get MACMIIDR value */6 l% o$ w( s7 z
- *RegValue = (uint16_t)(ETH->MACMIIDR);
& v( T, V& V, s# y- h - /* 从 PHY 中读取16bit的数据值 */ D. J7 F* Y' {9 q
- }
复制代码 保存可以正常运行,并且连上lan8742芯片
' V3 b) V G; p4 B
9 l x b& C3 G8 y. d
# K4 D* h1 t) Y1 Q2 `8 Z |
下面开始移植lwp141,步骤就不说了,网上有 . T2 V1 X0 o# ]
; ~. k" K# d# b7 V: |+ f$ h! [
6 O. P# F3 U, P! l0 @2 L2 x' U6 f' R _9 w
) v' @- X: w" Q& L4 ~ 直接给出代码0 \) v- q. g; u8 v
- static void low_level_init(struct netif *netif)8 D% g, I% M3 z: R2 g6 z9 [* U
- {( h+ O5 F: e$ C) F9 A0 c* [1 C2 b
- uint8_t macaddress[6]= { MAC_ADDR0, MAC_ADDR1, MAC_ADDR2, MAC_ADDR3, MAC_ADDR4, MAC_ADDR5 };
- U; k9 i3 |3 ^, x+ _% | -
& F9 ?, d7 P" L) z, k2 g/ a- d - EthHandle.Instance = ETH;
% P9 m. j- N+ s) Y - EthHandle.Init.MACAddr = macaddress;; Y6 N- J% X5 Y3 V; [, S9 F( k0 ~
- EthHandle.Init.AutoNegotiation = ETH_AUTONEGOTIATION_ENABLE;8 e J8 [3 `: s/ j
- EthHandle.Init.Speed = ETH_SPEED_100M;
' u% T9 a: V L - EthHandle.Init.DuplexMode = ETH_MODE_FULLDUPLEX;6 V- z2 x/ A! _3 d' a* Z; |9 ? e
- EthHandle.Init.MediaInterface = ETH_MEDIA_INTERFACE_RMII;
/ l0 }3 C, E4 c* R# R3 P: I& W1 } - EthHandle.Init.RxMode = ETH_RXINTERRUPT_MODE;
7 R5 S- {% ?5 J4 w) O5 S% p' v; ^# Y% C - EthHandle.Init.ChecksumMode = ETH_CHECKSUM_BY_HARDWARE;) v/ L) p6 H f2 e% [' [
- EthHandle.Init.PhyAddress = LAN8742A_PHY_ADDRESS;8 m3 t: I- ` r2 s
- /* configure ethernet peripheral (GPIOs, clocks, MAC, DMA) */
2 ^* m" T! x7 L3 W% Y9 ]( x2 ~/ G - lan8742_init(&EthHandle);
5 ?& N" [6 W& q( H% U: ~6 q - /* Initialize Tx Descriptors list: Chain Mode */# }" X q2 d. P, m2 O7 t) X2 T, E
- HAL_ETH_DMATxDescListInit(&EthHandle, DMATxDscrTab, &Tx_Buff[0][0], ETH_TXBUFNB);1 Q$ Y t3 |! a
-
+ N9 }+ e4 r3 E - /* Initialize Rx Descriptors list: Chain Mode */4 L9 q* v! X) f# h3 |
- HAL_ETH_DMARxDescListInit(&EthHandle, DMARxDscrTab, &Rx_Buff[0][0], ETH_RXBUFNB);
. Z) |) S9 V* Y/ f- c -
0 }9 N3 V% K# E+ J - /* Set netif link flag */
6 h6 L- ~! |* o; n+ d+ u$ ]( q - netif->flags |= NETIF_FLAG_LINK_UP;
9 f7 ^5 _% o" K7 d - /* set netif MAC hardware address length */9 U3 C8 _! h5 j% v/ Y
- netif->hwaddr_len = ETHARP_HWADDR_LEN;0 D4 Y- g! ?7 `; G* u, ?
- 4 k# h1 E& y9 p2 q( I( K8 s8 K8 R2 L
- /* set netif MAC hardware address *// M3 R! t2 J8 T8 G
- netif->hwaddr[0] = MAC_ADDR0;
# d, N; Q" Q" D - netif->hwaddr[1] = MAC_ADDR1;8 T( P# g& n- e5 A7 @& E% g; c
- netif->hwaddr[2] = MAC_ADDR2;- e4 a6 y: A' K! o
- netif->hwaddr[3] = MAC_ADDR3;
; L7 T! }# q/ w; W& \7 h$ C - netif->hwaddr[4] = MAC_ADDR4;: S% C& T1 a0 b) f4 R3 O
- netif->hwaddr[5] = MAC_ADDR5;9 g9 H9 [+ _3 U. _
/ j5 y# i! t5 }& g- /* set netif maximum transfer unit */1 I* ~ j! U N: @6 f5 w9 m
- netif->mtu = 1500;2 n' }" i* F; E# b
+ I! W2 c- }9 h0 N8 s# [- /* Accept broadcast address and ARP traffic */
9 r0 G5 I! J' U" g8 f6 _2 l - netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP;
$ U* ]+ |, ?7 o -
* I( {* ]0 C o. ?7 e5 J8 Q$ I - }
1 X0 ?6 B* ?* a2 P/ e - err_t low_level_output(struct netif *netif, struct pbuf *p)' B7 i) i/ Y) r- o I+ a
- {) b# ]8 o( y# ]8 t3 h7 s I
- err_t errval;
* R1 _6 m/ k# l9 F& Z" x - struct pbuf *q;1 Z, g0 g! a! [" F- w! s. p
- uint8_t *buffer = (uint8_t *)(EthHandle.TxDesc->Buffer1Addr);6 H7 h w8 S C
- __IO ETH_DMADescTypeDef *DmaTxDesc;
/ K% Q; ^+ b' s2 L6 W" |- y5 P+ w A - uint32_t framelength = 0;* w6 ^4 n$ p' E6 K
- uint32_t bufferoffset = 0;
5 u. K8 F& O: s. g - uint32_t byteslefttocopy = 0;- N& U9 p# y9 B) E2 P% p
- uint32_t payloadoffset = 0;
: _$ k. d7 E7 A
$ Q, a" U) Z! ~6 b/ E0 u# A- DmaTxDesc = EthHandle.TxDesc;
' L" a! d0 n! I9 H) ? - bufferoffset = 0;
5 _/ X( j+ q- f! M$ [& ?# G: |# M9 h( L - , U6 q/ l% C- P$ N0 a
- /* copy frame from pbufs to driver buffers */
$ G8 P. S1 T$ e0 _ - for(q = p; q != NULL; q = q->next)' f- y) \- d3 r, Q. e! b
- {8 Q$ K9 Y8 Y- g
- /* Is this buffer available? If not, goto error */
0 |9 r/ `% i) f' X - if((DmaTxDesc->Status & ETH_DMATXDESC_OWN) != (uint32_t)RESET)9 y8 I* {% g' b! l
- {: I' P, K* C6 M( L! F
- errval = ERR_USE;
3 ]9 M( O! s4 o7 [ - goto error;* t, `9 a. @' k% ~- M
- }. ]& H1 \. k; H5 }$ S
- . V/ f& @% ~! z+ h4 ~, D1 D3 `
- /* Get bytes in current lwIP buffer */
$ V1 s( ?0 ]1 k9 P! k# p - byteslefttocopy = q->len;
. g* W3 d5 n& @4 t8 b - payloadoffset = 0;
% }# A& y4 s( c- D -
1 @7 j6 b0 w8 B& M n+ U/ Z/ B! ] - /* Check if the length of data to copy is bigger than Tx buffer size*/
) d) j# o' K" ]8 a - while( (byteslefttocopy + bufferoffset) > ETH_TX_BUF_SIZE )
4 j- i+ d$ s) M2 C$ V - {
' Z; } w6 f0 |1 a9 g- H6 _) l; d n - /* Copy data to Tx buffer*/- _; u+ x& g9 A9 U m1 @9 k0 j0 F" y' G
- memcpy( (uint8_t*)((uint8_t*)buffer + bufferoffset), (uint8_t*)((uint8_t*)q->payload + payloadoffset), (ETH_TX_BUF_SIZE - bufferoffset) );
0 E9 A" ?( Z& h - * U% `3 k! ^8 I: t
- /* Point to next descriptor */
/ z, g$ X9 e3 o M( v7 _; W - DmaTxDesc = (ETH_DMADescTypeDef *)(DmaTxDesc->Buffer2NextDescAddr);7 S2 \ e5 J E( p- I4 P
-
' K1 U7 a: \9 J* P, e' i, Z - /* Check if the buffer is available */
/ h0 n2 R6 P8 w! U - if((DmaTxDesc->Status & ETH_DMATXDESC_OWN) != (uint32_t)RESET)/ t1 L' T8 Q9 T3 v/ ?1 i; _
- {
# X; Y' [( s( Z. P" ], d - errval = ERR_USE;8 h5 @5 p) d. h% _
- goto error;
. y) ]4 A4 s& F. d# @' w' f: d5 c - }% a7 v7 n* f. {7 P
-
% J" k3 k2 ?! {& ` - buffer = (uint8_t *)(DmaTxDesc->Buffer1Addr);
( d0 r0 ]6 h, B" B# d9 s2 n -
6 }9 }" S8 w4 S# s - byteslefttocopy = byteslefttocopy - (ETH_TX_BUF_SIZE - bufferoffset);
! r( a* q' L/ T! d2 i - payloadoffset = payloadoffset + (ETH_TX_BUF_SIZE - bufferoffset);3 l! ?7 i7 f5 s7 f9 U
- framelength = framelength + (ETH_TX_BUF_SIZE - bufferoffset);& \9 \! J* _0 |* @
- bufferoffset = 0;$ L& I, c2 r' k* t9 H+ W7 I0 B8 t- n! u
- }
# ~" U* q( K4 ]9 F$ p8 T( C1 w5 g -
- F* l6 r$ a9 D2 g! l, U$ z - /* Copy the remaining bytes */& B) l% ^ @, {6 f0 o) i
- memcpy( (uint8_t*)((uint8_t*)buffer + bufferoffset), (uint8_t*)((uint8_t*)q->payload + payloadoffset), byteslefttocopy );" M' M/ e- \0 X; {, S4 D
- bufferoffset = bufferoffset + byteslefttocopy;$ }; F. W4 L$ B6 O+ Y/ a; _
- framelength = framelength + byteslefttocopy;
5 }( i2 h' f/ G; d) }3 L$ m - }$ u- S2 q4 G# c4 M+ w
6 D$ `1 N W8 j) w% P9 ~* c! t- /* Clean and Invalidate data cache */4 K8 B L _+ A6 g: d4 C! ?% d9 [/ T
- SCB_CleanInvalidateDCache ();
) X) C) G. W, o. `% ^ - /* Prepare transmit descriptors to give to DMA */ $ T# z' R* y/ n
- HAL_ETH_TransmitFrame(&EthHandle, framelength);6 H2 ]' P. F8 g6 h- U, e
- ! _7 H4 Z3 W G4 q5 K
- errval = ERR_OK; z2 U' ~9 G: H0 F7 s
- 7 D1 X& b- p/ k2 h) r. O# G
- error:- N9 G$ \5 Q0 D9 ?
-
4 S4 x& @" I- E* U5 Z% n - /* When Transmit Underflow flag is set, clear it and issue a Transmit Poll Demand to resume transmission */; P5 P& Y% t( o' ]: d+ u
- if ((EthHandle.Instance->DMASR & ETH_DMASR_TUS) != (uint32_t)RESET)1 Y+ z4 a1 i' G! S; T) i
- {
) s% e! t( B4 I* | - /* Clear TUS ETHERNET DMA flag */
6 G8 g" j5 [, C) c4 Y - EthHandle.Instance->DMASR = ETH_DMASR_TUS;
' r( r8 L/ {1 p8 s" U% q9 g - - C' Y* d6 |: x" R. i
- /* Resume DMA transmission*/2 h6 l. A# h, ^
- EthHandle.Instance->DMATPDR = 0;
7 R2 g! g) q. f- i5 C; U7 y+ j9 G - }
* o8 w: |9 `/ `: ^! A9 d - return errval;
% U* R- l7 O! v" ~6 S1 |; o6 r4 u - }
8 z7 q6 B- V/ }& G4 C9 |$ P - 7 [ }* a5 B* f: `
- /*** G+ \; `- t5 l
- * [url=home.php?mod=space&uid=159083]@brief[/url] Should allocate a pbuf and transfer the bytes of the incoming
5 [# Y; d( `& s - * packet from the interface into the pbuf.
7 y; q" k6 v( |6 b: u - *
0 ?3 k3 i- K/ c& |/ H - * @param netif the lwip network interface structure for this ethernetif
4 `" ]# c* @ {' _. w - * [url=home.php?mod=space&uid=784970]@return[/url] a pbuf filled with the received packet (including MAC header)% {) r, H0 h/ h1 Y. d4 [5 W3 s
- * NULL on memory error
) T& y& z0 q- {5 v# J3 ^3 D. _ - */) J2 [( W( H6 s% G- H* ]& _
- struct pbuf * low_level_input(struct netif *netif)
: E. Z- S9 i- [7 j - {
8 z( r6 u2 O: h" x - struct pbuf *p = NULL, *q = NULL;
; u( N& n9 F5 A! R( b - uint16_t len = 0;1 r. X) P6 y0 I9 ?# w5 `
- uint8_t *buffer;2 [2 `% i# F: M2 h. N! o) d6 `
- __IO ETH_DMADescTypeDef *dmarxdesc;% T0 q% j _) T5 T
- uint32_t bufferoffset = 0;) X7 `1 _; I& ]* Z# S" _
- uint32_t payloadoffset = 0;. i$ u3 }3 }, M9 Z, O2 n2 |% x
- uint32_t byteslefttocopy = 0;5 O) r. f, I2 J+ l: R4 k# E
- uint32_t i=0;
9 b# R7 m4 _) z -
# N8 N6 O; F6 A! Q8 ^ - /* get received frame */
- A! h( O8 }8 t- F5 l - if(ETH_GetReceivedFrame(&EthHandle) != 0)5 n0 X( Z1 x) Z( G
- return NULL;& @0 Q& @$ e: r' b
-
8 Y+ I& y3 r! t+ O0 a - /* Obtain the size of the packet and put it into the "len" variable. */& I& `" z9 Q4 {& {
- len = EthHandle.RxFrameInfos.length;
' ~, y7 u; K; Q) ~# M# g8 q- d - buffer = (uint8_t *)EthHandle.RxFrameInfos.buffer;% P1 d/ }' a, N. e
-
# e S, l1 n7 i; S - if (len > 0)
3 g! ? B* V K5 G - {
2 N; i( q/ _( H( F& H V - /* We allocate a pbuf chain of pbufs from the Lwip buffer pool */
. ^ Q( S4 U* h" u9 N" @ - p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);. e( X' G* f/ l; K( ^1 I9 D
- printf("recv is ok\r\n");) L# Q( M2 W, z6 F" m
- }0 }2 L8 K5 T) p! e
-
' I* ~/ k' V7 J4 g4 Y" O - /* Clean and Invalidate data cache */
/ t% k! u; e$ T2 ]; Q6 k6 Z1 l - SCB_CleanInvalidateDCache ();- K) Y3 E) Q2 \: A
- - r, M5 \6 { _+ s+ \9 O- O) r- b
- if (p != NULL)
7 j' ?+ B" p2 d - {% [# ]- I. ^) [: k; g9 p
- dmarxdesc = EthHandle.RxFrameInfos.FSRxDesc;
) ?8 b6 ~) M0 x+ u* Y9 V - bufferoffset = 0;
) O9 H% F$ P* J$ f ]& j -
$ u* R! b0 f3 I - for(q = p; q != NULL; q = q->next)2 Q' J! i0 H9 K2 D! D, c4 `% V
- {
2 D: h3 O3 j: r* ? E- y1 n: }4 ^5 ~ - byteslefttocopy = q->len;
( Y1 W# w& J; s' ^( G' k: L - payloadoffset = 0;- T& ?) i5 d ~; Z6 Y. X
- 2 E( [( U2 s+ q. D2 ^
- /* Check if the length of bytes to copy in current pbuf is bigger than Rx buffer size */
0 M1 |; H" S9 W5 H - while( (byteslefttocopy + bufferoffset) > ETH_RX_BUF_SIZE )) I8 u: j6 p( e0 w0 Y; ]) ]1 D! v4 Z
- {8 h" D, t3 O3 i$ w9 z% L5 u
- /* Copy data to pbuf */" e/ G) |: L6 z9 }2 \6 o
- memcpy( (uint8_t*)((uint8_t*)q->payload + payloadoffset), (uint8_t*)((uint8_t*)buffer + bufferoffset), (ETH_RX_BUF_SIZE - bufferoffset));6 y7 S/ }0 I8 J1 W( W
- . `0 Y8 G) { ]
- /* Point to next descriptor */
+ X9 u, Z, @4 ^1 [6 s( ~! B, u - dmarxdesc = (ETH_DMADescTypeDef *)(dmarxdesc->Buffer2NextDescAddr);
, k2 C9 O: p) o( k* @$ F+ G - buffer = (uint8_t *)(dmarxdesc->Buffer1Addr);( s, H; \8 \( F/ b# U! D3 q
-
7 n0 V, N8 v: v f8 R - byteslefttocopy = byteslefttocopy - (ETH_RX_BUF_SIZE - bufferoffset);- P) M; D0 A) N- a3 [: |6 G0 Y
- payloadoffset = payloadoffset + (ETH_RX_BUF_SIZE - bufferoffset);
4 K( q+ M# e: D# C - bufferoffset = 0;
4 j- Q0 a* v6 ?4 j - }
: U) t+ r- q. r) l- i) \ -
+ B. F7 Q9 v/ H+ ?9 L - /* Copy remaining data in pbuf */. q) _$ ^4 L7 L1 [9 k1 \
- memcpy( (uint8_t*)((uint8_t*)q->payload + payloadoffset), (uint8_t*)((uint8_t*)buffer + bufferoffset), byteslefttocopy);
) ]6 a0 t5 b6 {" Q - bufferoffset = bufferoffset + byteslefttocopy;* G! U: k9 K* w' C5 s
- }
3 b, K% A) a$ Z' L+ P E - }
, J0 ?+ W$ v' [: d$ ]1 T$ _ -
) t @& Q; v* _0 l3 X0 H - /* Release descriptors to DMA */
/ s5 R- }; F3 J$ } - /* Point to first descriptor */
8 e* r% n# x6 ^. y F - dmarxdesc = EthHandle.RxFrameInfos.FSRxDesc;
+ Z; A3 m$ P. Z8 ]) [' I - /* Set Own bit in Rx descriptors: gives the buffers back to DMA */
! z7 ^# u; {/ r- e( d - for (i=0; i< EthHandle.RxFrameInfos.SegCount; i++)
2 {- \" x4 S$ k/ t# b6 r: n' V* {( T - {
2 L% e7 O" |( _' U3 y) }( Y - dmarxdesc->Status |= ETH_DMARXDESC_OWN;5 {3 k0 }& J- y/ [
- dmarxdesc = (ETH_DMADescTypeDef *)(dmarxdesc->Buffer2NextDescAddr);- R( V, v o. G# _6 N, |3 M5 ^$ {
- }# F7 e4 I; c4 d: p) `* d7 c6 J
-
$ a* F' F0 F, l/ r# {6 T' M: U' t - /* Clear Segment_Count */9 \; g5 j' Y- a5 K1 c! V% Q1 ~+ A
- EthHandle.RxFrameInfos.SegCount =0;
\1 c1 {' K! W4 Q - + z# p# [( I1 D; s! Y. F
- /* When Rx Buffer unavailable flag is set: clear it and resume reception */
) d; u! H% b* E - if ((EthHandle.Instance->DMASR & ETH_DMASR_RBUS) != (uint32_t)RESET) - R( c; a9 {/ u3 }# J/ V1 y2 Y
- {' D I. c e0 i0 r$ U9 J( v
- /* Clear RBUS ETHERNET DMA flag */( h5 f8 ^9 i$ j% Z$ R
- EthHandle.Instance->DMASR = ETH_DMASR_RBUS;
1 U2 {# ?: b0 C8 w1 ]4 \ - /* Resume DMA reception */$ ~8 t% C3 c7 o
- EthHandle.Instance->DMARPDR = 0;& S* e l4 ~: z+ C, N
- }+ H q, g- X$ |# ]
- return p;% z' g2 q1 ]0 N: R
- }
3 D7 g6 Y' i1 _( C+ W# p+ E3 y: C# i - void ethernetif_input( void const * argument )
* I6 `+ I, w) J. L0 [ - {
3 e& R0 ^% Y. Z! g2 c - struct pbuf *p;" ]6 Z L7 C: Q* w, ?" ^
- struct netif *netif = (struct netif *) argument;% e* o/ l4 v) g9 r V# H' H' }
-
3 ~1 y& o$ E: Z( y -
1 R7 z) ~" ^% u. f' I0 T9 f5 { - " ?( \0 z* V# x. [1 c. \
- 8 k" j& K( W7 Q
- p = low_level_input( netif );
1 P6 |8 k2 Z0 y! Y0 ? - if (p != NULL)
: r, @% w' P# O% p& z* M - {) v" X, n! f+ `* i$ M$ [
- if (netif->input( p, netif) != ERR_OK )$ |5 w+ V- F8 L$ O( T8 ^
- {1 b3 {9 e# }" y+ }0 ` p2 s
- LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n"));
) c' g2 t W; t. C8 {4 k - pbuf_free(p);) M x6 [/ J, p$ R. O8 K' V
- }
0 y% A8 ]4 a6 h# r - }
0 |; R, v% t9 r7 } -
( U$ C& a3 ^8 U -
2 p/ l. k* o+ L- } - }7 m2 C$ x+ k1 E
- err_t ethernetif_init(struct netif *netif)
8 t3 j* r/ W4 v/ J; J3 z, I - {% j- ^2 {" b [( T# J4 Q
- LWIP_ASSERT("netif != NULL", (netif != NULL));
( F- w3 K/ D; T) W5 ] n, d/ g" {
* T" i& m. O1 ^- #if LWIP_NETIF_HOSTNAME
9 \; Z) \2 l( k5 ~ - /* Initialize interface hostname */
- j; s/ R! O8 X2 P/ p - netif->hostname = "lwip";
- t8 W" V! d9 N) _6 K0 i* j" J, f - #endif /* LWIP_NETIF_HOSTNAME */
! V @+ l- W' ?: c( T5 O L( a
) g3 x- t) v! k! ~4 I- netif->name[0] = IFNAME0;
' O) Z, g/ b: | - netif->name[1] = IFNAME1;
5 \3 x$ f' y. D; R - ( W# X' J8 }. a, Q5 K! n& K
- /* We directly use etharp_output() here to save a function call.8 H7 ] C# _, J: x
- * You can instead declare your own function an call etharp_output()3 I$ m) T3 g! C0 L2 P
- * from it if you have to do some checks before sending (e.g. if link
9 {+ T& o2 \+ V/ X2 z2 M( n7 F - * is available...) */: t3 ]' P( e0 t9 r+ Q
- netif->output = etharp_output;# U5 ~5 K8 ^+ J' k) x9 G/ n
- netif->linkoutput = low_level_output;) a* W. Y1 O5 Y! F& `1 S
- $ M# F3 R$ W0 G, r+ i) ~
- /* initialize the hardware */( `# Q, d2 c1 j
- low_level_init(netif);
7 S7 {/ o* n+ M7 l0 ^5 h5 G - 3 b% E$ H6 k' r* ?$ v
- return ERR_OK;2 g' N& f% L# u, V
- }& v, ^8 t Z! D. [0 F; b
复制代码 编译正常,然后开始网络的配置
$ B/ r' E/ L, o7 s( f4 v+ t- static void Netif_Config(void)$ v, s4 }2 b6 q- d. V( V) Q
- {7 Q9 G, J+ ?0 l# X) E5 d1 X, |4 F
- ip_addr_t ipaddr;: \- u! X9 A! Y ?# |( p: \$ f+ c8 W
- ip_addr_t netmask;7 q2 y2 N" q9 I( B/ g/ p5 B1 M, y
- ip_addr_t gw;5 ^- O+ N& q& i% b- r; t5 p% l' R
- uint8_t iptab[4] = {0};; T+ ?0 B$ c8 b1 W, y9 ^
- uint8_t iptxt[20];) ~- A/ S3 K& ?; s6 s
- uint8_t netmasktab[4]={0};
0 F; p9 |9 U# z& P8 n, n1 G% { - uint8_t netmasktxt[30];4 q- q7 W* S9 G. V: j
- 1 C" k9 j) ` L( ?
- uint8_t gwtab[4]={0};( ?% b/ E4 i; H3 @- g1 I
- uint8_t gwtxt[30];
1 [: a! `* P( P2 m9 ~ - ) v7 V* U8 K1 C
- - f( O9 S$ C# z
- mem_init(); //3?ê??ˉ?ˉì??ú′???6 k# U2 p: ~+ J* Q: |
- ; V4 D2 W7 H- X! l
- memp_init(); //3?ê??ˉ?ú′?3?3 x- s" ^& t0 h( ?' l
-
5 }& l' e9 k. W* }3 M - #ifdef USE_DHCP
+ X" X: _- e/ X; D2 E1 h! { - ipaddr.addr = 0;
! t- f/ J" T' `- o: F# l9 l( A& z: I - netmask.addr = 0;
- W- I! d& d) A' f; i# H! P( e& h - gw.addr = 0;
& m) ?& l( ^. \- I - #else) o) M$ X& o! {# f& k' b" f
- IP4_ADDR(&ipaddr,IP_ADDR0,IP_ADDR1,IP_ADDR2,IP_ADDR3);1 b7 {& X) u' d& z% f
- IP4_ADDR(&netmask,NETMASK_ADDR0,NETMASK_ADDR1,NETMASK_ADDR2,NETMASK_ADDR3);
, L$ B6 S4 a: R, ^: _% w - IP4_ADDR(&gw,GW_ADDR0,GW_ADDR1,GW_ADDR2,GW_ADDR3);
& F: R) a1 h1 K8 [, l6 V& g - #endif /* USE_DHCP */0 w2 J5 r" D( b* ?4 n) ]: a
-
1 u1 D8 L4 F! r6 o4 y q" ? - netif_add(&gnetif, &ipaddr, &netmask, &gw, NULL, eernetif_init, eernet_input);
5 n6 ^5 |; o6 z E9 L - ! q1 U5 f( W. h: \4 B% L c/ u% H9 C t
- /* Registers the default network interface. */
5 Y7 m3 n5 T( K$ n - netif_set_default(&gnetif);' F# W. o6 g8 F V8 U( L: G: v
- + K7 @: V$ W* i0 C. Q* w- r
- if (netif_is_link_up(&gnetif))% D: J7 _2 l/ z0 {+ x( c
- {. E) J/ r6 o* E' k$ t3 X: n4 \& r
- /* When the netif is fully configured this function must be called.*/
: l8 N" m1 a5 \: o) g! ? - netif_set_up(&gnetif);
4 I: n3 b( E! H* w - iptab[0] = IP_ADDR3;
$ {- x6 ^) b" F - iptab[1] = IP_ADDR2;- _! M: [# ~" e1 M3 V/ k) H
- iptab[2] = IP_ADDR1;
* Q7 F @- X" J5 ^( J5 i - iptab[3] = IP_ADDR0;
! `' f4 T* O( p& U# Q' R( m" n -
/ C1 C7 F+ V; {; u - netmasktab[0]=NETMASK_ADDR3;
+ r) c5 ?: L5 w+ N - netmasktab[1]=NETMASK_ADDR2;* b% X* d( H8 U+ C# x. T0 F
- netmasktab[2]=NETMASK_ADDR1;5 s* S: Z; O, a2 R
- netmasktab[3]=NETMASK_ADDR0;
5 W9 F+ h$ s$ a+ p6 N+ e9 } - & @" d s8 i; p6 i$ Q# v
- gwtab[0]=GW_ADDR3;
9 s* J+ ]$ S% C% v - gwtab[1]=GW_ADDR2;0 N: l1 Q" I& ~0 B/ z. z4 a
- gwtab[2]=GW_ADDR1;
. ?& Y% `+ ]) o0 Z, k* b1 v- D9 J - gwtab[3]=GW_ADDR0;
. [% I+ T6 p" n* ^9 g& Z- m5 h
- D9 ~1 U( ~6 q/ M- G- //
! H/ z5 N( w! f& D0 k3 W - sprintf((char*)iptxt, " %d.%d.%d.%d", iptab[3], iptab[2], iptab[1], iptab[0]);
, I5 B. A$ x+ `" b% { -
- n/ C3 x6 m6 n! n - sprintf((char*)netmasktxt, "%d.%d.%d.%d",netmasktab[3],netmasktab[2],netmasktab[1],netmasktab[0]);5 W7 x$ p2 V2 h- u5 v
- - r! s5 f+ V. N0 q0 ~' l5 q
- sprintf((char*)gwtxt,"%d.%d.%d.%d",gwtab[3],gwtab[2],gwtab[1],gwtab[0]);, N7 n8 \- ^8 m2 j3 {
- : r7 e5 n+ X/ u9 d4 _: ]& v
- //
0 |( `: Y# S. i# w9 m6 o" k# ^4 { - printf("\r\n");
6 ]3 K" Q$ q$ U5 \% A - printf("\r\n");
! }9 f5 g4 \2 z! C* m8 P4 M - printf(" Network Cable is connected \r\n");; b6 n3 q$ Z" x: j- ? b
- printf(" This is lwip1.4.1-ping demo test \r\n");
4 i) j. z- v( z: v5 p* m& Y0 B - printf(" The stm32f769 ip address is: %s\r\n",iptxt);
! H1 c) }( G+ u4 U7 @$ {" I - printf("The stm32f769 netmask address is: %s\r\n",netmasktxt);) `7 R5 v ?8 [1 m
- printf(" The stm32f769 gw address is: %s\r\n",gwtxt);
+ F; i7 q& |( C/ R/ K+ V - printf("\r\n");, A+ H% L' K9 y
- printf("\r\n");* {' t6 V( J1 ^6 J9 n3 Z2 ]5 f
- printf("\r\n");
7 h' \ c$ ^1 J1 U7 o! [ - }2 t( J1 h% A& {$ J, o" A
- else4 P) f2 e. f4 X& q) Y
- {
9 p% E0 f. W6 L: i# H - /* When the netif link is down this function must be called */
+ Z' D; u. }1 C! R5 Z( s$ i - netif_set_down(&gnetif);
' I5 I+ t# g. e - printf(" Network Cable is not connected \r\n");) n8 B6 h1 Z2 p# k& r: G
- }
" U) B7 b) C9 ~' ~" y - }
复制代码 完成后,实现网络数据的处理; D5 B9 _6 `" D$ C# e" w: z
- void LwIP_Pkt_Handle(void)8 I1 D6 C2 Y, R* m* h# x' z
- {/ u2 G& F6 t: z6 a
- /* Read a received packet from the Ethernet buffers and send it to the lwIP for handling */; ~1 o8 T" N0 D
- ethernetif_input(&gnetif);
/ [* s2 I2 s1 e1 \( ?3 u$ F - }
- N. m/ V- q0 a - void LwIP_Periodic_Handle(__IO uint32_t localtime)
: S) m$ P- Z& t - {
* g; f3 N. y0 k% H i - #if LWIP_TCP) v' Y: E% D L
- /* TCP periodic process every 250 ms */5 H9 K O7 x: ^7 } k4 T4 o: h9 {' v
- if (localtime - TCPTimer >= TCP_TMR_INTERVAL)
! f3 ]& ~, F ] - {
8 w4 R" K- h0 w% M - TCPTimer = localtime;" M+ b' v" _& A
- tcp_tmr();
* A/ D5 ?8 y' s6 R4 V2 a3 ? - }
- O) _8 z( e" b$ _ ~- @ - #endif7 u8 V. N/ ~% M2 u8 v
- ' d1 I/ V: D( }* j& Y
1 E$ j( @. F" R5 c' D6 y' c- etharp_tmr();$ u4 @. i( Q8 c: Z$ s
6 n( q# m. h$ m0 R" s- }
复制代码 在main函数添加网路初始化,及数据处理
' p9 k0 F" S) [) _- Netif_Config();, K6 h* L, @( h% O% Q4 n
- 7 @: V) r5 k2 f4 k- v
- while(1)
+ o0 i m: i( w4 a8 Q - {6 l/ S# r+ ?# b2 w
- if (ETH_GetReceivedFrame(&EthHandle)) //?ì2éê?·??óê?μ?êy?Y°ü7 K9 D6 g h! l5 t/ o
- { 8 l6 L0 R- L3 b$ \' t
- LwIP_Pkt_Handle(); //) N/ B k) F0 r- E: t. `
- }
7 n" l9 }) R7 b/ g3 X( Z) G - /* handle periodic timers for LwIP */0 d6 p) j, _7 T: m) P f1 R+ ~
- LwIP_Periodic_Handle(LocalTime);+ Q! i% W( T( b# m7 K$ ^0 ?
- led_toggle();
/ N6 U" B! j8 t9 C' X: U) ^ - delay_ms(5000);
, d9 q3 x4 y4 Q: R& t, q1 e4 V5 R - }
复制代码 3 _; t3 v& ]. J- a/ v5 J
t: }6 B8 y2 S8 q3 |6 X' X+ F其他功能目前还在研究
% x7 e; a" ~ X! | b8 V1 u. u% I1 p* [: R- ]
|
https://www.stmcu.org.cn/module/forum/thread-615497-1-1.html