Forum: Mikrocontroller und Digitale Elektronik AT91SAM9260 EMAC Treiber Problem


von Daniel G. (motello)


Lesenswert?

Hallo!

Ich habe einen einfachen Treiber für das EMAC meines AT91SAM9260 
Mikrocontroller geschrieben, der leider nicht funktioniert. Ich bin 
schon länger erfolglos am Fehlersuchen und hoffe Ihr könnt mir helfen.

1. Kein Betriebssystem
2. ICache ist an, DCache nicht, MMU ist aus
3. PHY connection läuft, wird ja im Programm getestet
4. Auf einen Link wird gewartet (nicht zu sehen) und er ist da!
5. Die Pakete versuche ich mit Wireshark zu empfangen, leider vergebens.
6. Beim ersten senden eines Pakets zählt Frames Transmitted OK Register 
noch, dann nicht mehr. Also demnach sollte ein Paket gesendet werden.
7. PHY ist Micrel KSZ8721BL (habe das Olimex Board SAM9-9260)

Wo könnte der Fehler bloß liegen? Was sind häufige Fehlerquellen? Ich 
bin für jeden Hinweis dankbar!

Viele Grüße
Daniel

Hier der Treiber-Code
1
/*****************************************************************************
2
 *                                       *
3
 *  EMAC DRIVER                                 *
4
 *                                       *
5
 *****************************************************************************/
6
7
#include "eth.h"
8
#include "endian.h"
9
#include "part.h"
10
#include "main.h"
11
#include "gpio.h"
12
#include <stdio.h>
13
#include <stdlib.h>
14
#include <string.h>
15
16
/************************************************
17
 * VARIABLES AND STRUCTS            *
18
 ************************************************/
19
20
/* setting up the buffer descriptor list */
21
unsigned int RxBd[2048];        //1024 buffer descriptors of 2 words
22
23
/* setting up the receive buffer */
24
unsigned int RxB[1024][32];        //1024 buffer of 128byte
25
26
27
/* setting up 128 transmit buffer descriptors, thats enough! */
28
unsigned int TxBd[256];          //128 two word buffer descriptors
29
30
/* setting up the transmit buffer */
31
unsigned int TxB[128][512];          //128 buffers of 2048 byte
32
33
34
/* HEADER DEFINITIONS */
35
36
/* ethernet encapsulation */
37
struct ethheader {
38
  unsigned char destMAC[6];
39
  unsigned char srcMAC[6];
40
  unsigned char type[2];
41
} __attribute__ ((packed)) *eth;
42
43
/* ip header */
44
struct ipheader {
45
  unsigned char version_header;    //4bit version, 4 bit header length in 32bit-words
46
  unsigned char TOS;          //0x0 for default
47
  unsigned short length;        //total length of ip datagram
48
  unsigned short id;          //normally incrementet by every sent packet
49
  unsigned short flags_offset;    //3bit flags, 13bit offset
50
  unsigned char TTL;          //time to live, normally 32 or 64
51
  unsigned char prot;          //17 for UDP
52
  unsigned short chksum;        //header checksum
53
  unsigned int sourceIP;
54
  unsigned int destIP;
55
}__attribute__ ((packed)) *ip;
56
57
/* udp header */
58
struct udpheader {
59
  unsigned short srcPort;        //source portnumber
60
  unsigned short destPort;      //destination port number
61
  unsigned short length;        //total length of udp datagram
62
  unsigned short chksum;        //checksum (optional) pseudo-header, header and data
63
} __attribute__ ((packed)) *udp;
64
65
66
/************************************************
67
 * INITIALIZATION                *
68
 ************************************************/
69
70
int eth_init ( )
71
{
72
  int i;
73
74
  /* enable emac in power management controller PMC */
75
  writel( 1 << AT91C_ID_EMAC, AT91C_PMC_PCER);
76
  
77
   /* disable transmit and receive circuits */
78
   writel( 0, AT91C_EMACB_NCR );    //disabling by reset network control register
79
80
  /* disable all interrupts */
81
  writel( ~0, AT91C_EMACB_IDR );    //disabling by writing 0xffffffff to the interrupt disable register
82
83
  /* set the MAC address of this device */
84
  //necessary to receive packets
85
  
86
  /* clear statistics register, enable management port, make status registers writable */
87
  writel( AT91C_EMAC_CLRSTAT | 
88
      AT91C_EMAC_MPE |
89
      AT91C_EMAC_WESTAT
90
        , AT91C_EMACB_NCR );
91
92
  /* configure network */
93
  writel( AT91C_EMAC_SPD |      //set speed to 100Mbit/s
94
      AT91C_EMAC_FD |        //set full duplex mode
95
      AT91C_EMAC_CLK_HCLK_64    //set clock divider according MCK
96
        , AT91C_EMACB_NCFGR );
97
98
  /* enable transreceiver input clock and set to MII mode */
99
  writel( AT91C_EMAC_CLKEN, AT91C_EMACB_USRIO );
100
101
102
/************************************************
103
 * PHY SETUP                  *
104
 ************************************************/
105
106
  /* basic control register 0x0 */
107
  writel (  PHY_SOF |
108
        PHY_WRITE |
109
        PHY_ADDRESS |
110
        PHY_BCR |
111
        PHY_CODE |
112
        PHY_BCR_AUTONEG |
113
        PHY_BCR_AUTONEG_RESTART
114
          , AT91C_EMACB_MAN );
115
  while ( !(readl(AT91C_EMACB_NSR) & AT91C_EMAC_IDLE) );    //wait for transmission completed
116
117
  /* read and verify PHY register entry */
118
  /* read PHY identifier, shold be 0x0022 in register 0x2 */
119
  writel (  PHY_SOF |
120
        PHY_READ |
121
        PHY_ADDRESS |
122
        PHY_ID1 |
123
        PHY_CODE
124
          , AT91C_EMACB_MAN );
125
  while ( !(readl(AT91C_EMACB_NSR) & AT91C_EMAC_IDLE) );    //wait for transmission completed
126
  if ( (readl(AT91C_EMACB_MAN) & PHY_DATA_MASK) != 0x0022 )  //read and verify ID
127
    pio_set_value(AT91C_PIN_PA(9), 0);            //if doesn't match switch power LED off
128
129
130
/************************************************
131
 * BUFFER CONFIGURATION              *
132
 ************************************************/
133
134
  /* RECEIVE BUFFER */
135
136
  /* received frames are written into 128byte long receive buffers. these buffers 
137
   * are stored in memory. every start location of a buffer is stored in a list.
138
   * each entry of this list consists of 2 words and is called buffer desciptor.
139
   */
140
141
  /* initialize descriptor list */
142
  for (i = 0; i < 1024; i++) {
143
    RxBd[i*2] = ((unsigned int) RxB[i]) & ~3;      //mask the two least significant bits
144
  }
145
  RxBd[2047] |= 2;            //set wrap bit of the last descriptor
146
147
  /* write start address of descriptor list to receive buffer queue pointer register */
148
  writel( (unsigned int) RxBd & ~3, AT91C_EMACB_RBQP );  //mask the two least significant bits of the address
149
150
  /* enable receiver */
151
  writel( readl(AT91C_EMACB_NCR) | AT91C_EMAC_RE, AT91C_EMACB_NCR );
152
153
154
  /* TRANSMIT BUFFER */
155
156
  /* Frames to be transmitted are stored in one or more buffers. the buffer size is
157
   * between 0 and 2047 byte. the start location of each transmit buffer is stored
158
   * in a tramsmit buffer descriptor list. the transmit buffer queue pointer register
159
   * points to one of the descriptors.
160
   * each descriptor entry consists of two words. the first word contains the address
161
   * and the second control and status information.
162
   */
163
164
  /* initialize descriptor list */
165
  for (i = 0; i < 128; i++) {
166
    TxBd[i*2] = (unsigned int) TxB[i];          //write start address of each buffer to the descriptor
167
    TxBd[i*2+1] = TxBd_USED;              //set used bit, there's no frame to be sent
168
  }
169
  TxBd[255] |= TxBd_WRAP;                  //set wrap bit of the last buffer descriptor
170
171
  /* write start address of descriptor list to transmit buffer queue pointer register */
172
  writel( (unsigned int) TxBd, AT91C_EMACB_TBQP );
173
174
  /* enable transmitter */
175
  writel( readl(AT91C_EMACB_NCR) | AT91C_EMAC_TE, AT91C_EMACB_NCR );
176
  
177
  packet_setup();
178
179
  return 0;
180
}
181
182
/************************************************
183
 * PACKET SETUP                  *
184
 ************************************************/
185
186
void packet_setup () {
187
188
  /* ETHERNET HEADER */
189
  /* destination MAC Address */
190
  eth->destMAC[0] = 0xff;          //MAC: little endian
191
  eth->destMAC[1] = 0xff;
192
  eth->destMAC[2] = 0xff;
193
  eth->destMAC[3] = 0xff;
194
  eth->destMAC[4] = 0xff;
195
  eth->destMAC[5] = 0xff;
196
  /* Source MAC Address */
197
  eth->srcMAC[5] = 0x00;
198
  eth->srcMAC[4] = 0x2e;
199
  eth->srcMAC[3] = 0x44;
200
  eth->srcMAC[2] = 0xa2;
201
  eth->srcMAC[1] = 0x43;
202
  eth->srcMAC[0] = 0x00;
203
  /* Type */
204
  eth->type[0] = 0x08;          //big endian
205
  eth->type[1] = 0x00;
206
207
  /* IP HEADER */
208
  /* Version and Header length */
209
  ip->version_header = 4 << 4;      //version on higher-half-byte
210
  ip->version_header += 5 << 0;      //header length on lower-half-byte
211
  /* TOS */
212
  ip->TOS = 0x0;              //normal service
213
  /* total length */
214
  ip->length = endians(68);
215
  /* identification */
216
  ip->id = endians(0);
217
  /* flags and offset */
218
  ip->flags_offset = endians(0);
219
  /* Time To Live */
220
  ip->TTL = 32;
221
  /* Protocol */
222
  ip->prot = 17;              //17 means UDP
223
  /* source IP */
224
  ip->sourceIP = endianl(10 << 0 | 0 << 8 | 168 << 16 | 192 << 24);
225
  /* destination IP (broadcast) */
226
  ip->destIP = endianl(0xffffffff);
227
  /* checksum */
228
  ip->chksum = 0;                    //to calculate chksum, this field has to be zero
229
  ip->chksum = endians(ip_chksum(20, (char*)ip));    //calculate IP checksum
230
231
  /* UDP HEADER */
232
  /* source port */
233
  udp->srcPort = endians(1044);
234
  /* destination port */
235
  udp->destPort = endians(1044);
236
  /* length */
237
  udp->length = endians(48);
238
  /* checksum */
239
  udp->chksum = endians(0);        //checksum is not used
240
241
}
242
243
/* IP CHECKSUM CALCULATION */
244
short ip_chksum (short header_length, char header[])
245
{
246
  short word16;
247
  long sum = 0;
248
  short i;
249
    
250
  /* make 16 bit words out of every two adjacent 8 bit words in the packet
251
   * and add them up */
252
  for (i = 0; i < header_length; i += 2) {
253
    word16 = ((header[i] << 8) & 0xFF00) + (header[i+1] & 0xFF);
254
    sum = sum + (long) word16;
255
  }
256
  
257
  /* take only 16 bits out of the 32 bit sum and add up the carries */
258
  while (sum >> 16)
259
    sum = (sum & 0xFFFF) + (sum >> 16);
260
261
    /* one's complement the result */
262
  sum = ~sum;
263
                  
264
  return ((short) sum);
265
}
266
267
268
/************************************************
269
 * TRANSMIT                    *
270
 ************************************************/
271
272
int eth_send () //(*pBuffer, int length)
273
{
274
275
  if (readl(AT91C_EMACB_FTO) >= 3)
276
    return 1;
277
//  writel(0, AT91C_EMACB_FTO);
278
279
  if ( TxBd[1] & (TxBd_ERR | TxBd_UNDERRUN | TxBd_BUFFEXH ))
280
    return 1;
281
  if ( !(TxBd[1] & TxBd_USED) )
282
    return 1;
283
284
  writel (AT91C_EMAC_COMP, AT91C_EMACB_TSR);    //clear COMPLETE bit of transmit status register
285
286
  char *bptr = (char*) &TxB[0][0];
287
  /* copy frame in buffer */
288
  memcpy( bptr, eth, 14 );
289
    bptr += 14;
290
  memcpy( bptr, ip, 20 );
291
    bptr += 20;
292
  memcpy( bptr, udp, 8 );
293
    bptr += 8;
294
  memcpy( bptr, "1234567890helloworld1234567890helloworld", 40);
295
296
  /* write status and control information to TxBd */
297
  TxBd[1] = TxBd_NOCRC | TxBd_LASTBUF | 82;
298
  writel( (unsigned int) &TxBd[0], AT91C_EMACB_TBQP );
299
300
  writel( readl(AT91C_EMACB_NCR) | AT91C_EMAC_TSTART, AT91C_EMACB_NCR );
301
302
  while ( !(readl(AT91C_EMACB_TSR) & AT91C_EMAC_COMP) );
303
304
  /* check for error */
305
  return 0;
306
}

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.