uc-sdk
Main Page
Related Pages
Modules
Classes
Files
File List
File Members
All
Classes
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
lpc17xx-if.c
Go to the documentation of this file.
1
#include "
lwip/opt.h
"
2
3
#include "
lwip/def.h
"
4
#include "
lwip/mem.h
"
5
#include "
lwip/pbuf.h
"
6
#include "
lwip/sys.h
"
7
#include <
lwip/stats.h
>
8
#include <
lwip/snmp.h
>
9
#include "
netif/etharp.h
"
10
#include "
netif/ppp_oe.h
"
11
#include "
netif/lpc17xx-if.h
"
12
13
#include <
lpc17xx_emac.h
>
14
#include <
lpc17xx_nvic.h
>
15
#include <
lpc17xx_pinsel.h
>
16
17
#define IFNAME0 'e'
18
#define IFNAME1 'x'
19
20
extern
uint8_t
mac_address
[6];
21
22
/* Forward declarations. */
23
static
void
lpc17xx_if_input(
struct
netif
*
netif
);
24
static
void
wait_DMA_slot();
25
33
static
int
34
low_level_init(
struct
netif
*
netif
)
35
{
36
EMAC_CFG_Type
EMAC_Config;
37
PINSEL_CFG_Type
PinCfg;
38
uint32_t delay, retry;
39
40
/* set MAC hardware address length */
41
netif->
hwaddr_len
= ETHARP_HWADDR_LEN;
42
43
/* set MAC hardware address */
44
memcpy(netif->
hwaddr
, mac_address, 6);
45
46
/* maximum transfer unit */
47
netif->
mtu
= 1500;
48
49
/* device capabilities */
50
netif->
flags
=
NETIF_FLAG_BROADCAST
|
NETIF_FLAG_ETHARP
|
NETIF_FLAG_LINK_UP
;
51
52
/* initializing lpc17xx's emac. */
53
PinCfg.
Funcnum
= 1;
54
PinCfg.
OpenDrain
= 0;
55
PinCfg.
Pinmode
= 0;
56
PinCfg.
Portnum
= 1;
57
58
PinCfg.
Pinnum
= 0;
PINSEL_ConfigPin
(&PinCfg);
59
PinCfg.
Pinnum
= 1;
PINSEL_ConfigPin
(&PinCfg);
60
PinCfg.
Pinnum
= 4;
PINSEL_ConfigPin
(&PinCfg);
61
PinCfg.
Pinnum
= 8;
PINSEL_ConfigPin
(&PinCfg);
62
PinCfg.
Pinnum
= 9;
PINSEL_ConfigPin
(&PinCfg);
63
PinCfg.
Pinnum
= 10;
PINSEL_ConfigPin
(&PinCfg);
64
PinCfg.
Pinnum
= 14;
PINSEL_ConfigPin
(&PinCfg);
65
PinCfg.
Pinnum
= 15;
PINSEL_ConfigPin
(&PinCfg);
66
PinCfg.
Pinnum
= 16;
PINSEL_ConfigPin
(&PinCfg);
67
PinCfg.
Pinnum
= 17;
PINSEL_ConfigPin
(&PinCfg);
68
EMAC_Config.
Mode
=
EMAC_MODE_AUTO
;
69
EMAC_Config.
pbEMAC_Addr
= netif->
hwaddr
;
70
for
(retry = 0; retry < 500; retry++) {
71
if
(
EMAC_Init
(&EMAC_Config) !=
ERROR
)
72
return
1;
73
for
(delay = 0x100000; delay; delay--);
74
}
75
return
0;
76
}
77
94
static
err_t
95
low_level_output(
struct
netif *netif,
struct
pbuf
*p)
96
{
97
struct
pbuf
*q;
98
EMAC_PACKETBUF_Type
TxPack;
99
100
#if ETH_PAD_SIZE
101
pbuf_header
(p, -
ETH_PAD_SIZE
);
/* drop the padding word */
102
#endif
103
104
if
(
EMAC_CheckTransmitIndex
() ==
FALSE
) {
105
wait_DMA_slot();
106
}
107
108
for
(q = p; q !=
NULL
; q = q->
next
) {
109
/* Send the data from the pbuf to the interface, one pbuf at a
110
time. The size of the data in each pbuf is kept in the ->len
111
variable. */
112
TxPack.
ulDataLen
= q->
len
;
113
TxPack.
pbDataBuf
= q->
payload
;
114
EMAC_WritePacketBuffer
(&TxPack,
FALSE
);
115
}
116
TxPack.
ulDataLen
= 0;
117
TxPack.
pbDataBuf
=
NULL
;
118
EMAC_WritePacketBuffer
(&TxPack,
TRUE
);
119
EMAC_UpdateTxProduceIndex
();
120
121
#if ETH_PAD_SIZE
122
pbuf_header
(p,
ETH_PAD_SIZE
);
/* reclaim the padding word */
123
#endif
124
125
LINK_STATS_INC
(link.xmit);
126
127
return
ERR_OK
;
128
}
129
138
static
struct
pbuf
*
139
low_level_input(
struct
netif *netif)
140
{
141
struct
pbuf
*p, *q;
142
u16_t
len
;
143
144
if
(
EMAC_CheckReceiveIndex
() ==
FALSE
)
145
return
NULL
;
146
147
/* Obtain the size of the packet and put it into the "len"
148
variable. */
149
len =
EMAC_GetReceiveDataSize
() + 1;
150
151
#if ETH_PAD_SIZE
152
len +=
ETH_PAD_SIZE
;
/* allow room for Ethernet padding */
153
#endif
154
155
/* We allocate a pbuf chain of pbufs from the pool. */
156
p =
pbuf_alloc
(
PBUF_RAW
, len,
PBUF_POOL
);
157
158
if
(p !=
NULL
) {
159
160
#if ETH_PAD_SIZE
161
pbuf_header
(p, -
ETH_PAD_SIZE
);
/* drop the padding word */
162
#endif
163
164
/* We iterate over the pbuf chain until we have read the entire
165
* packet into the pbuf. */
166
for
(q = p; q !=
NULL
; q = q->
next
) {
167
/* Read enough bytes to fill this pbuf in the chain. The
168
* available data in the pbuf is given by the q->len
169
* variable.
170
* This does not necessarily have to be a memcpy, you can also preallocate
171
* pbufs for a DMA-enabled MAC and after receiving truncate it to the
172
* actually received size. In this case, ensure the tot_len member of the
173
* pbuf is the sum of the chained pbuf len members.
174
*/
175
EMAC_PACKETBUF_Type
RxPack;
176
RxPack.
pbDataBuf
= q->
payload
;
177
RxPack.
ulDataLen
= q->
len
;
178
EMAC_ReadPacketBuffer
(&RxPack);
179
}
180
181
#if ETH_PAD_SIZE
182
pbuf_header
(p,
ETH_PAD_SIZE
);
/* reclaim the padding word */
183
#endif
184
185
LINK_STATS_INC
(link.recv);
186
}
else
{
187
LINK_STATS_INC
(link.memerr);
188
LINK_STATS_INC
(link.drop);
189
}
190
EMAC_UpdateRxConsumeIndex
();
191
192
return
p;
193
}
194
204
static
void
205
lpc17xx_if_input(
struct
netif *netif)
206
{
207
struct
eth_hdr *ethhdr;
208
struct
pbuf
*p;
209
210
/* move received packet into a new pbuf */
211
p = low_level_input(netif);
212
/* no packet could be read, silently ignore this */
213
if
(p ==
NULL
)
return
;
214
/* points to packet payload, which starts with an Ethernet header */
215
ethhdr = p->
payload
;
216
217
switch
(
htons
(ethhdr->type)) {
218
/* IP or ARP packet? */
219
case
ETHTYPE_IP:
220
case
ETHTYPE_ARP:
221
#if PPPOE_SUPPORT
222
/* PPPoE packet? */
223
case
ETHTYPE_PPPOEDISC:
224
case
ETHTYPE_PPPOE:
225
#endif
/* PPPOE_SUPPORT */
226
/* full packet send to tcpip_thread to process */
227
if
(netif->
input
(p, netif)!=
ERR_OK
)
228
{
LWIP_DEBUGF
(
NETIF_DEBUG
, (
"lpc17xx_if_input: IP input error\n"
));
229
pbuf_free
(p);
230
p =
NULL
;
231
}
232
break
;
233
234
default
:
235
pbuf_free
(p);
236
p =
NULL
;
237
break
;
238
}
239
}
240
253
static
int
lpc17xx_if_got_init = 0;
254
255
err_t
256
lpc17xx_if_init
(
struct
netif *netif)
257
{
258
LWIP_ASSERT
(
"netif != NULL"
, (netif !=
NULL
));
259
/* We only have one EMAC on the lpc17xx, so... */
260
if
(!__sync_bool_compare_and_swap(&lpc17xx_if_got_init, 0, 1))
261
return
ERR_VAL
;
262
263
#if LWIP_NETIF_HOSTNAME
264
/* Initialize interface hostname */
265
netif->hostname =
"lwip"
;
266
#endif
/* LWIP_NETIF_HOSTNAME */
267
268
/*
269
* Initialize the snmp variables and counters inside the struct netif.
270
* The last argument should be replaced with your link speed, in units
271
* of bits per second.
272
*/
273
NETIF_INIT_SNMP
(netif,
snmp_ifType_ethernet_csmacd
, 746);
274
275
netif->
state
=
NULL
;
276
netif->
name
[0] =
IFNAME0
;
277
netif->
name
[1] =
IFNAME1
;
278
/* We directly use etharp_output() here to save a function call.
279
* You can instead declare your own function an call etharp_output()
280
* from it if you have to do some checks before sending (e.g. if link
281
* is available...) */
282
netif->
output
= etharp_output;
283
netif->
linkoutput
= low_level_output;
284
285
/* initialize the hardware */
286
if
(!low_level_init(netif)) {
287
lpc17xx_if_got_init = 0;
288
return
ERR_IF
;
289
}
290
291
return
ERR_OK
;
292
}
293
294
lpc17xx_if_waitdma_t
lpc17xx_if_waitdma
=
NULL
;
295
296
static
void
wait_DMA_slot(
void
) {
297
if
(lpc17xx_if_waitdma)
298
lpc17xx_if_waitdma
();
299
while
(
EMAC_CheckTransmitIndex
() ==
FALSE
);
300
}
301
302
void
lpc17xx_if_check_input
(
struct
netif * netif) {
303
lpc17xx_if_input(netif);
304
}
305
306
__attribute__
((section(
".eth_ram"
))) uint8_t lwip_ram_heap[5632];
307
308
err_t
interface_init
(struct netif *netif)
__attribute__
((weak, alias ("
lpc17xx_if_init
")));
309
void
interface_check_input
(struct netif * netif)
__attribute__
((weak, alias ("
lpc17xx_if_check_input
")));
lwip
src
netif
lpc17xx-if.c
Generated on Fri Nov 15 2013 05:00:22 for uc-sdk by
1.8.4