Statistics
| Branch: | Tag: | Revision:

amiro-blt / Target / Demo / ARMCM4_STM32F405_Power_Management_GCC / Boot / lib / uip / netdev.c @ 69661903

History | View | Annotate | Download (15.063 KB)

1 69661903 Thomas Schöpping
/*
2
 * Copyright (c) 2001, Swedish Institute of Computer Science.
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
7
 * are met:
8
 *
9
 * 1. Redistributions of source code must retain the above copyright
10
 *    notice, this list of conditions and the following disclaimer.
11
 *
12
 * 2. Redistributions in binary form must reproduce the above copyright
13
 *    notice, this list of conditions and the following disclaimer in the
14
 *    documentation and/or other materials provided with the distribution.
15
 *
16
 * 3. Neither the name of the Institute nor the names of its contributors
17
 *    may be used to endorse or promote products derived from this software
18
 *    without specific prior written permission.
19
 *
20
 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
21
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
24
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30
 * SUCH DAMAGE.
31
 *
32
 * Author: Adam Dunkels <adam@sics.se>
33
 *
34
 * $Id: netdev.c,v 1.8 2006/06/07 08:39:58 adam Exp $
35
 */
36
37
38
/*---------------------------------------------------------------------------*/
39
#include "uip.h"
40
#include "uip_arp.h"
41
#include "boot.h"
42
#include "stm32f4xx.h"                               /* STM32 registers                */
43
#include "stm32f4xx_conf.h"                          /* STM32 peripheral drivers       */
44
#include "stm32_eth.h"                               /* STM32 ethernet library         */
45
#include <string.h>                                  /* for memcpy                     */
46
47
48
/*---------------------------------------------------------------------------*/
49
#define NETDEV_DEFAULT_MACADDR0           (0x08)
50
#define NETDEV_DEFAULT_MACADDR1           (0x00)
51
#define NETDEV_DEFAULT_MACADDR2           (0x27)
52
#define NETDEV_DEFAULT_MACADDR3           (0x69)
53
#define NETDEV_DEFAULT_MACADDR4           (0x5B)
54
#define NETDEV_DEFAULT_MACADDR5           (0x45)
55
56
57
/*---------------------------------------------------------------------------*/
58
static void netdev_TxDscrInit(void);
59
static void netdev_RxDscrInit(void);
60
61
/*---------------------------------------------------------------------------*/
62
typedef union _TranDesc0_t
63
{
64
  uint32_t Data;
65
  struct {
66
    uint32_t  DB            : 1;
67
    uint32_t  UF            : 1;
68
    uint32_t  ED            : 1;
69
    uint32_t  CC            : 4;
70
    uint32_t  VF            : 1;
71
    uint32_t  EC            : 1;
72
    uint32_t  LC            : 1;
73
    uint32_t  NC            : 1;
74
    uint32_t  LSC           : 1;
75
    uint32_t  IPE           : 1;
76
    uint32_t  FF            : 1;
77
    uint32_t  JT            : 1;
78
    uint32_t  ES            : 1;
79
    uint32_t  IHE           : 1;
80
    uint32_t                : 3;
81
    uint32_t  TCH           : 1;
82
    uint32_t  TER           : 1;
83
    uint32_t  CIC           : 2;
84
    uint32_t                : 2;
85
    uint32_t  DP            : 1;
86
    uint32_t  DC            : 1;
87
    uint32_t  FS            : 1;
88
    uint32_t  LSEG          : 1;
89
    uint32_t  IC            : 1;
90
    uint32_t  OWN           : 1;
91
  };
92
} TranDesc0_t, * pTranDesc0_t;
93
94
typedef union _TranDesc1_t
95
{
96
  uint32_t Data;
97
  struct {
98
    uint32_t  TBS1          :13;
99
    uint32_t                : 3;
100
    uint32_t  TBS2          :12;
101
    uint32_t                : 3;
102
  };
103
} TranDesc1_t, * pTranDesc1_t;
104
105
typedef union _RecDesc0_t
106
{
107
  uint32_t Data;
108
  struct {
109
    uint32_t  RMAM_PCE      : 1;
110
    uint32_t  CE            : 1;
111
    uint32_t  DE            : 1;
112
    uint32_t  RE            : 1;
113
    uint32_t  RWT           : 1;
114
    uint32_t  FT            : 1;
115
    uint32_t  LC            : 1;
116
    uint32_t  IPHCE         : 1;
117
    uint32_t  LS            : 1;
118
    uint32_t  FS            : 1;
119
    uint32_t  VLAN          : 1;
120
    uint32_t  OE            : 1;
121
    uint32_t  LE            : 1;
122
    uint32_t  SAF           : 1;
123
    uint32_t  DERR          : 1;
124
    uint32_t  ES            : 1;
125
    uint32_t  FL            :14;
126
    uint32_t  AFM           : 1;
127
    uint32_t  OWN           : 1;
128
  };
129
} RecDesc0_t, * pRecDesc0_t;
130
131
typedef union _recDesc1_t
132
{
133
  uint32_t Data;
134
  struct {
135
    uint32_t  RBS1          :13;
136
    uint32_t                : 1;
137
    uint32_t  RCH           : 1;
138
    uint32_t  RER           : 1;
139
    uint32_t  RBS2          :14;
140
    uint32_t  DIC           : 1;
141
  };
142
} RecDesc1_t, * pRecDesc1_t;
143
144
typedef union _EnetDmaDesc_t
145
{
146
  uint32_t Data[4];
147
  // Rx DMA descriptor
148
  struct
149
  {
150
    RecDesc0_t                RxDesc0;
151
    RecDesc1_t                RxDesc1;
152
    uint32_t *                   pBuffer;
153
    union
154
    {
155
      uint32_t *                 pBuffer2;
156
      union _EnetDmaDesc_t *  pEnetDmaNextDesc;
157
    };
158
  } Rx;
159
  // Tx DMA descriptor
160
  struct
161
  {
162
    TranDesc0_t               TxDesc0;
163
    TranDesc1_t               TxDesc1;
164
    uint32_t *                   pBuffer1;
165
    union
166
    {
167
      uint32_t *                 pBuffer2;
168
      union _EnetDmaDesc_t *  pEnetDmaNextDesc;
169
    };
170
  } Tx;
171
} EnetDmaDesc_t, * pEnetDmaDesc_t;
172
173
174
/*---------------------------------------------------------------------------*/
175
uint8_t RxBuff[UIP_CONF_BUFFER_SIZE] __attribute__ ((aligned (4)));
176
uint8_t TxBuff[UIP_CONF_BUFFER_SIZE] __attribute__ ((aligned (4)));
177
178
EnetDmaDesc_t EnetDmaRx __attribute__((aligned (128)));
179
EnetDmaDesc_t EnetDmaTx __attribute__ ((aligned (128)));
180
181
182
/*---------------------------------------------------------------------------*/
183
void netdev_init(void)
184
{
185
  GPIO_InitTypeDef GPIO_InitStructure;
186
  ETH_InitTypeDef ETH_InitStructure;
187
188
  /* Enable ETHERNET clocks  */
189
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_ETH_MAC | RCC_AHB1Periph_ETH_MAC_Tx |
190
                         RCC_AHB1Periph_ETH_MAC_Rx | RCC_AHB1Periph_ETH_MAC_PTP, ENABLE);
191
192
  
193
  /* Enable GPIOs clocks */
194
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA |        RCC_AHB1Periph_GPIOB | 
195
                         RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOG, ENABLE);
196
197
  /* Enable SYSCFG clock */
198
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
199
  /*Select RMII Interface*/
200
  SYSCFG_ETH_MediaInterfaceConfig(SYSCFG_ETH_MediaInterface_RMII);
201
  
202
  /* ETHERNET pins configuration */
203
  /* PA
204
    ETH_RMII_REF_CLK: PA1
205
    ETH_RMII_MDIO: PA2
206
    ETH_RMII_MDINT: PA3
207
    ETH_RMII_CRS_DV: PA7
208
   */
209
210
  /* Configure PA1, PA2, PA3 and PA7*/
211
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_7;
212
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
213
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
214
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
215
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
216
  GPIO_Init(GPIOA, &GPIO_InitStructure);
217
218
  /* Connect PA1, PA2, PA3 and PA7 to ethernet module*/
219
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_ETH);
220
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_ETH);
221
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_ETH);
222
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_ETH);
223
224
  /* PB
225
    ETH_RMII_TX_EN: PG11
226
  */
227
228
  /* Configure PG11*/
229
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
230
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
231
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
232
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
233
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
234
  GPIO_Init(GPIOG, &GPIO_InitStructure);
235
236
  /* Connect PG11 to ethernet module*/
237
  GPIO_PinAFConfig(GPIOG, GPIO_PinSource11, GPIO_AF_ETH);
238
239
  /* PC
240
    ETH_RMII_MDC: PC1
241
    ETH_RMII_RXD0: PC4
242
    ETH_RMII_RXD1: PC5
243
  */
244
245
  /* Configure PC1, PC4 and PC5*/
246
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5;
247
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
248
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
249
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
250
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
251
  GPIO_Init(GPIOC, &GPIO_InitStructure);
252
253
  /* Connect PC1, PC4 and PC5 to ethernet module*/
254
  GPIO_PinAFConfig(GPIOC, GPIO_PinSource1, GPIO_AF_ETH);
255
  GPIO_PinAFConfig(GPIOC, GPIO_PinSource4, GPIO_AF_ETH);
256
  GPIO_PinAFConfig(GPIOC, GPIO_PinSource5, GPIO_AF_ETH);
257
258
  /* PG
259
    ETH_RMII_TXD0: PG13
260
    ETH_RMII_TXD1: PG14
261
  */
262
263
  /* Configure PG13 and PG14*/
264
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14;
265
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
266
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
267
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
268
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
269
  GPIO_Init(GPIOG, &GPIO_InitStructure);
270
271
  /* Connect PG13 and PG14 to ethernet module*/
272
  GPIO_PinAFConfig(GPIOG, GPIO_PinSource13, GPIO_AF_ETH);
273
  GPIO_PinAFConfig(GPIOG, GPIO_PinSource14, GPIO_AF_ETH);
274
275
  /* Reset ETHERNET on AHB Bus */
276
  ETH_DeInit();
277
  
278
  /* Software reset */ 
279
  ETH_SoftwareReset();
280
  
281
  /* Wait for software reset */
282
  while(ETH_GetSoftwareResetStatus()==SET);
283
284
  /* ETHERNET Configuration ------------------------------------------------------*/
285
  /* Call ETH_StructInit if you don't like to configure all ETH_InitStructure parameter */
286
  ETH_StructInit(&ETH_InitStructure);
287
  
288
  /* Fill ETH_InitStructure parametrs */
289
  /*------------------------   MAC   -----------------------------------*/
290
  ETH_InitStructure.ETH_AutoNegotiation = ETH_AutoNegotiation_Disable  ;  
291
  ETH_InitStructure.ETH_LoopbackMode = ETH_LoopbackMode_Disable;              
292
  ETH_InitStructure.ETH_RetryTransmission = ETH_RetryTransmission_Disable;                                                                                  
293
  ETH_InitStructure.ETH_AutomaticPadCRCStrip = ETH_AutomaticPadCRCStrip_Disable;                                                                                                                                                                        
294
  ETH_InitStructure.ETH_ReceiveAll = ETH_ReceiveAll_Enable;                                                                                                       
295
  ETH_InitStructure.ETH_BroadcastFramesReception = ETH_BroadcastFramesReception_Disable;      
296
  ETH_InitStructure.ETH_PromiscuousMode = ETH_PromiscuousMode_Disable;                                                             
297
  ETH_InitStructure.ETH_MulticastFramesFilter = ETH_MulticastFramesFilter_Perfect;      
298
  ETH_InitStructure.ETH_UnicastFramesFilter = ETH_UnicastFramesFilter_Perfect;                        
299
  ETH_InitStructure.ETH_Mode = ETH_Mode_FullDuplex;                        
300
  ETH_InitStructure.ETH_Speed = ETH_Speed_100M;                        
301
302
  unsigned int PhyAddr;
303
    union {
304
      uint32_t    HI_LO;
305
      struct
306
      {
307
        uint16_t  LO;
308
        uint16_t  HI;
309
      };
310
    } PHYID;
311
  for(PhyAddr = 0; 32 > PhyAddr; PhyAddr++)
312
  { 
313
    // datasheet for the ks8721bl ethernet controller (http://www.micrel.com/_PDF/Ethernet/datasheets/ks8721bl-sl.pdf)
314
    // page 20 --> PHY Identifier 1 and 2
315
    PHYID.HI = ETH_ReadPHYRegister(PhyAddr,2);  // 0x0022
316
    PHYID.LO = ETH_ReadPHYRegister(PhyAddr,3);  // 0x1619
317
    if ((0x00221619 == PHYID.HI_LO) || (0x0007C0F1 == PHYID.HI_LO))
318
      break;
319
  }
320
  if (32 < PhyAddr)
321
  {
322
    ASSERT_RT(BLT_FALSE);
323
  }
324
  /* Configure Ethernet */
325
  if(0 == ETH_Init(&ETH_InitStructure, PhyAddr))
326
  {
327
    ASSERT_RT(BLT_FALSE);
328
  }
329
330
  netdev_TxDscrInit();
331
  netdev_RxDscrInit();
332
  ETH_Start();
333
}
334
335
336
/*---------------------------------------------------------------------------*/
337
void netdev_init_mac(void)
338
{
339
  struct uip_eth_addr macAddress;
340
341
  /* set the default MAC address */
342
  macAddress.addr[0] = NETDEV_DEFAULT_MACADDR0;
343
  macAddress.addr[1] = NETDEV_DEFAULT_MACADDR1;
344
  macAddress.addr[2] = NETDEV_DEFAULT_MACADDR2;
345
  macAddress.addr[3] = NETDEV_DEFAULT_MACADDR3;
346
  macAddress.addr[4] = NETDEV_DEFAULT_MACADDR4;
347
  macAddress.addr[5] = NETDEV_DEFAULT_MACADDR5;
348
  uip_setethaddr(macAddress);
349
}
350
351
352
/*---------------------------------------------------------------------------*/
353
unsigned int netdev_read(void)
354
{
355
  uint32_t size;
356
  /*check for validity*/
357
  if(0 == EnetDmaRx.Rx.RxDesc0.OWN)
358
  {
359
    /*Get the size of the packet*/
360
    size = EnetDmaRx.Rx.RxDesc0.FL; // CRC
361
    memcpy(uip_buf, RxBuff, size);   //string.h library*/
362
  }
363
  else
364
  {
365
    return 0;
366
  }
367
  /* Give the buffer back to ENET */
368
  EnetDmaRx.Rx.RxDesc0.OWN = 1;
369
  /* Start the receive operation */
370
  ETH->DMARPDR = 1;
371
  /* Return no error */
372
  return size;
373
}
374
375
376
/*---------------------------------------------------------------------------*/
377
void netdev_send(void)
378
{
379
  while(EnetDmaTx.Tx.TxDesc0.OWN);
380
381
  /* Copy the  application buffer to the driver buffer
382
     Using this MEMCOPY_L2L_BY4 makes the copy routine faster
383
     than memcpy */
384
  memcpy(TxBuff, uip_buf, uip_len);
385
386
  /* Assign ENET address to Temp Tx Array */
387
  EnetDmaTx.Tx.pBuffer1 = (uint32_t *)TxBuff;
388
389
  /* Setting the Frame Length*/
390
  EnetDmaTx.Tx.TxDesc0.Data = 0;
391
  EnetDmaTx.Tx.TxDesc0.TCH  = 1;
392
  EnetDmaTx.Tx.TxDesc0.LSEG = 1;
393
  EnetDmaTx.Tx.TxDesc0.FS   = 1;
394
  EnetDmaTx.Tx.TxDesc0.DC   = 0;
395
  EnetDmaTx.Tx.TxDesc0.DP   = 0;
396
397
  EnetDmaTx.Tx.TxDesc1.Data = 0;
398
  EnetDmaTx.Tx.TxDesc1.TBS1 = (uip_len&0xFFF);
399
400
  /* Start the ENET by setting the VALID bit in dmaPackStatus of current descr*/
401
  EnetDmaTx.Tx.TxDesc0.OWN = 1;
402
403
  /* Start the transmit operation */
404
  ETH->DMATPDR = 1;
405
}
406
407
408
/*---------------------------------------------------------------------------*/
409
static void netdev_RxDscrInit(void)
410
{
411
  /* Initialization */
412
  /* Assign temp Rx array to the ENET buffer */
413
  EnetDmaRx.Rx.pBuffer = (uint32_t *)RxBuff;
414
415
  /* Initialize RX ENET Status and control */
416
  EnetDmaRx.Rx.RxDesc0.Data = 0;
417
418
  /* Initialize the next descriptor- In our case its single descriptor */
419
  EnetDmaRx.Rx.pEnetDmaNextDesc = &EnetDmaRx;
420
421
  EnetDmaRx.Rx.RxDesc1.Data = 0;
422
  EnetDmaRx.Rx.RxDesc1.RER  = 0; // end of ring
423
  EnetDmaRx.Rx.RxDesc1.RCH  = 1; // end of ring
424
425
  /* Set the max packet size  */
426
  EnetDmaRx.Rx.RxDesc1.RBS1 = UIP_CONF_BUFFER_SIZE;
427
428
  /* Setting the VALID bit */
429
  EnetDmaRx.Rx.RxDesc0.OWN = 1;
430
  /* Setting the RX NEXT Descriptor Register inside the ENET */
431
  ETH->DMARDLAR = (uint32_t)&EnetDmaRx;
432
}
433
434
435
/*---------------------------------------------------------------------------*/
436
static void netdev_TxDscrInit(void)
437
{
438
  /* ENET Start Address */
439
  EnetDmaTx.Tx.pBuffer1 = (uint32_t *)TxBuff;
440
441
  /* Next Descriptor Address */
442
  EnetDmaTx.Tx.pEnetDmaNextDesc = &EnetDmaTx;
443
444
  /* Initialize ENET status and control */
445
  EnetDmaTx.Tx.TxDesc0.TCH  = 1;
446
  EnetDmaTx.Tx.TxDesc0.Data = 0;
447
  EnetDmaTx.Tx.TxDesc1.Data = 0;
448
  /* Tx next set to Tx descriptor base */
449
  ETH->DMATDLAR = (uint32_t)&EnetDmaTx;
450
451
}