mac.c


1
/******************************************************************************
2
 * Company:        
3
 *
4
 * Project:        
5
 *
6
 * Target:         
7
 *
8
 * Type:           
9
 *
10
 * Description:    
11
 *
12
 * Compiler:       
13
 *
14
 * Filename:       
15
 *
16
 * Version:        
17
 *
18
 * Author:         
19
 *
20
 * Creation-Date:  16.09.2010
21
 ******************************************************************************
22
 *****************************************************************************/
23
24
/******************************************************************************
25
 * INCLUDE FILES
26
 *****************************************************************************/
27
28
#include "mac.h"
29
30
/******************************************************************************
31
 * PRIVATE FUNCTION PROTOTYPES (STATIC)
32
 *****************************************************************************/
33
34
static void MAC_fInitRxDescriptors(void);
35
36
static void MAC_fInitTxDescriptors(void);
37
38
static void MAC_fWritePHY(tWord wReg, tWord wValue);
39
40
static tWord MAC_fReadPHY(tWord wReg);
41
42
static void MAC_fLinkInterrupt(void);
43
44
static void MAC_fEthernetInterrupt(void);
45
46
/******************************************************************************
47
 * PRIVATE VARIABLES
48
 *****************************************************************************/
49
50
#pragma data_alignment = 4
51
static tByte bRxBuffer[MAC_RX_FRAGMENTS * ETH_FRAG_SIZE];
52
53
#pragma data_alignment = 4
54
static tByte bTxBuffer[MAC_TX_FRAGMENTS * ETH_FRAG_SIZE];
55
56
/******************************************************************************
57
 * OTHER DEFINITIONS
58
 *****************************************************************************/
59
60
/******************************************************************************
61
 * MODULE FUNCTIONS (PUBLIC)
62
 *****************************************************************************/
63
64
/*===========================================================================*/
65
tenBool MAC_fInitMAC(void)
66
/*-----------------------------------------------------------------------------
67
  Function:
68
  basic initialization of the ethernet mac and the phy. this routine
69
  will work only with the micrel KSZ8001L phy.
70
  in:  none
71
  out: enTrue if the mac and phy are working, enFalse if there was an error.
72
=============================================================================*/
73
{
74
  tDWord dwID;
75
  PCONP |= BIT_30; /* power up the mac */
76
  PINSEL2 |= (BIT_00 | BIT_02 | BIT_08 | BIT_16 | BIT_18 | BIT_20 |
77
    BIT_28 | BIT_30); /* select the rmii pins */
78
  PINSEL3 |= (BIT_00 | BIT_02); /* select the mdio and clk pins */
79
  MAC1 =  (BIT_08 | BIT_09 | BIT_10 | BIT_11 | BIT_14 | BIT_15); /* reset mac */
80
  Command = (BIT_03 | BIT_04 | BIT_05); /* reset the mac */
81
  MAC1 = BIT_01; /* pass all frames */
82
  MAC2 = (BIT_04 | BIT_05 | BIT_07); /* enable crc and padding */
83
  MAXF = MAX_FRAME; /* maximum frame length */
84
  CLRT = CLRT_DEFAULT; /* set the collision window and retransmission count */
85
  IPGR = IPGR_DEFAULT; /* set the back-to-back inter packet gap */
86
  MCFG = (BIT_02 | BIT_03 | BIT_04 | BIT_15); /* divide host clk by 20 and reset mii */
87
  MCFG ^= BIT_15; /* release the reset from the mii hardware */
88
  Command = (BIT_09 | BIT_06 /*| BIT_07*/); /* enable the rmii */
89
  SUPP = BIT_08; /* enable 100MBit mode */
90
  MAC_fWritePHY(PHY_BCR, BIT_15); /* reset the phy */
91
  while(MAC_fReadPHY(PHY_BCR) & (BIT_15 | BIT_11)); /* wait until reset done */
92
  MAC_fWritePHY(PHY_CTL, BIT_14); /* enable the link and act LEDs */
93
  dwID = (MAC_fReadPHY(PHY_ID1) << 16); /* get PHY manufacturer and revision */
94
  dwID |= (MAC_fReadPHY(PHY_ID2) & 0xFFF0);
95
  if(dwID != KSZ8001_ID) /* check if this is a KSZ8001L PHY */
96
    return enFalse; /* abort */
97
  MAC_fWritePHY(PHY_BCR, BIT_12); /* enable auto-negotiation */
98
  MAC_fWritePHY(PHY_ICS, BIT_08 | BIT_10); /* enable link up / down interrupt */
99
  PINSEL4 |= BIT_22; /* enable EINT1 interrupt */
100
  VICVectPriority15 = 0; /* set up the phy interrupt */
101
  VICVectAddr15 = (tDWord)MAC_fLinkInterrupt;
102
  VICIntEnable |= BIT_15; /* enable the link up/down interrupt */
103
  SA0 = (MAC_ADDRESS1 << 8) | MAC_ADDRESS2; /* set up the mac address */
104
  SA1 = (MAC_ADDRESS3 << 8) | MAC_ADDRESS4;
105
  SA2 = (MAC_ADDRESS5 << 8) | MAC_ADDRESS6;
106
  RxFilterCtrl = (/*BIT_01 | BIT_02 |*/ BIT_05); /* uni-, multi- and broadcast */
107
  MAC_fInitRxDescriptors(); /* initialize rx descriptors */
108
  MAC_fInitTxDescriptors(); /* initialize tx descriptors */
109
  Command |= (BIT_00 | BIT_01); /* enable receiver and transmitter */
110
  MAC1 |= BIT_00; /* enable the receiver */
111
  VICVectPriority21 = 0; /* set up the mac interrupt */
112
  VICVectAddr21 = (tDWord)MAC_fEthernetInterrupt;
113
  VICIntEnable |= BIT_21;
114
  return enTrue; /* finished initialization */
115
116
 //  if (regv & 0x0004) {   
117
    /* 10MBit mode. */
118
//    SUPP = 0;
119
//  }
120
//  else {
121
    /* 100MBit mode. */
122
//    SUPP = SUPP_SPEED;
123
//  }
124
125
} /* end MAC_fInitMAC */
126
127
/*============================================================================*/
128
tenBool MAC_fGetLinkStatus(void)
129
/*-----------------------------------------------------------------------------
130
  Function:
131
  send a packet.
132
  in:  pData -> pointer to the packet data to be transmitted.
133
       dwSize -> size of the packet data.
134
  out: enTrue -> packet sent or is being transmitted, enFalse otherwise
135
=============================================================================*/
136
{
137
  tWord wStatus = MAC_fReadPHY(PHY_STATUS); /* get the status word */
138
  if(wStatus & BIT_02) /* check the link status bit */
139
    return enTrue;
140
  else
141
    return enFalse;
142
} /* end MAC_fGetLinkStatus */
143
144
/*============================================================================*/
145
tenBool MAC_fSendPacket(tpByte pData, tDWord dwSize)
146
/*-----------------------------------------------------------------------------
147
  Function:
148
  send a packet.
149
  in:  pData -> pointer to the packet data to be transmitted.
150
       dwSize -> size of the packet data.
151
  out: enTrue -> packet sent or is being transmitted, enFalse otherwise
152
=============================================================================*/
153
{
154
  tDWord dwTempSize = dwSize;
155
  tWord wIdx = TxProduceIndex; /* get the next tx descriptor index */
156
  tpByte pTxBuffer = (tpByte)TxPacketDescriptor(wIdx);
157
  if(!dwSize)
158
    return enFalse;
159
  while(dwTempSize)
160
  {
161
    *pTxBuffer = *pData;
162
    pTxBuffer++;
163
    pData++;
164
    dwTempSize--;
165
  }
166
  TxControlDescriptor(wIdx) = ((BIT_30 | BIT_29 | BIT_28 | BIT_26) | (dwSize - 1));
167
  if(wIdx)
168
    wIdx = 0;
169
  else
170
    wIdx = 1;
171
  TxProduceIndex = wIdx;
172
  return enTrue;
173
} /* end MAC_fSendPacket */
174
175
/*============================================================================*/
176
tDWord MAC_fReceivePacket(tpByte pData)
177
/*-----------------------------------------------------------------------------
178
  Function:
179
  send a packet.
180
  in:  pData -> pointer to the packet data to be transmitted.
181
       dwSize -> size of the packet data.
182
  out: enTrue -> packet sent or is being transmitted, enFalse otherwise
183
=============================================================================*/
184
{
185
  tDWord dwSize, dwCopySize;
186
  tpByte pRxFrameBuffer;
187
  tDWord dwIdx = RxConsumeIndex; /* get the index of the next received frame */
188
  if(dwIdx == RxProduceIndex) /* check if new data is available */
189
    return 0; /* no new frames have been received */
190
  dwSize = (RxStatusDescriptor(dwIdx) & 0x7FF) - 3; /* ignore the frame's crc */
191
  dwCopySize = dwSize;
192
  pRxFrameBuffer = (tpByte)(RxPacketDescriptor(dwIdx));
193
  while(dwCopySize--)
194
  {
195
    *pData = *pRxFrameBuffer;
196
    pData++;
197
    pRxFrameBuffer++;
198
  }
199
  dwIdx++;
200
  if(dwIdx == MAC_RX_FRAGMENTS)
201
    dwIdx = 0;
202
  RxConsumeIndex = dwIdx;
203
  return dwSize;
204
} /* end MAC_fReceivePacket */
205
206
/*============================================================================*/
207
tAddress MAC_fCreatePacket(void)
208
/*-----------------------------------------------------------------------------
209
  Function:
210
  send a packet.
211
  in:  pData -> pointer to the packet data to be transmitted.
212
       dwSize -> size of the packet data.
213
  out: enTrue -> packet sent or is being transmitted, enFalse otherwise
214
=============================================================================*/
215
{
216
  tWord wIdx = TxProduceIndex;
217
  return (tAddress)TxPacketDescriptor(wIdx);;
218
} /* end MAC_fCreatePacket */
219
220
/******************************************************************************
221
 * PRIVATE FUNCTIONS (STATIC)
222
 *****************************************************************************/
223
224
/*============================================================================*/
225
static void MAC_fInitRxDescriptors(void)
226
/*-----------------------------------------------------------------------------
227
  Function:
228
  initializes the RxDescriptors.
229
  in:  none
230
  out: none
231
232
  sa 10.00 
233
=============================================================================*/
234
{
235
  tDWord dwIdx;
236
  tpDWord pdwRxDesc = (tpDWord)RX_DESC_BASE; /* rx descriptors are in eth ram */
237
  RxDescriptor = RX_DESC_BASE;
238
  for(dwIdx = 0; dwIdx < MAC_RX_FRAGMENTS; dwIdx++)
239
  {
240
    *pdwRxDesc = (tDWord)&bRxBuffer[dwIdx * ETH_FRAG_SIZE]; /* packet */
241
    pdwRxDesc++;
242
    *pdwRxDesc = BIT_31 | (ETH_FRAG_SIZE - 1); /* control */
243
    pdwRxDesc++;
244
  }
245
  RxStatus = (tDWord)pdwRxDesc; /* rx status immediately follows rx desc */
246
  RxDescriptorNumber = MAC_RX_FRAGMENTS - 1; /* number of rx descriptors */
247
  RxConsumeIndex = 0; /* begin at the first rx descriptor */
248
} /* end MAC_fInitRxDescriptors */
249
250
/*============================================================================*/
251
static void MAC_fInitTxDescriptors(void)
252
/*-----------------------------------------------------------------------------
253
  Function:
254
  initializes the TxDescriptors.
255
  in:  none
256
  out: none
257
=============================================================================*/
258
{
259
  tDWord dwIdx;
260
  tpDWord pdwTxDesc = (tpDWord)TX_DESC_BASE;
261
  TxDescriptor = TX_DESC_BASE;
262
  for(dwIdx = 0; dwIdx < MAC_TX_FRAGMENTS; dwIdx++)
263
  {
264
    *pdwTxDesc = (tDWord)&bTxBuffer[dwIdx * ETH_FRAG_SIZE];  /* packet */
265
    pdwTxDesc++;
266
    *pdwTxDesc = ((BIT_30 | BIT_29 | BIT_28 | BIT_26) | (ETH_FRAG_SIZE - 1)); /* control */
267
    pdwTxDesc++;
268
  }
269
  TxStatus = (tDWord)pdwTxDesc; /* tx status immediately follows tx desc */
270
  TxDescriptorNumber = MAC_TX_FRAGMENTS - 1; /* number of tx descriptors */
271
  TxProduceIndex = 0; /* begin at the first tx descriptor */
272
} /* end MAC_fInitTxDescriptors */
273
274
/*============================================================================*/
275
static void MAC_fWritePHY(tWord wReg, tWord wValue)
276
/*-----------------------------------------------------------------------------
277
  Function:
278
  writes the given value to a specific register in the phy.
279
  in:  wReg -> register to write to
280
       wValue -> value to write
281
  out: none
282
=============================================================================*/
283
{
284
  MADR = (wReg & 0x1F); /* the register address. only bits 0..5 are valid. */
285
  MWTD = wValue; /* write data */
286
  while(MIND & BIT_00); /* wait until write cycle is complete */
287
} /* end MAC_fWritePHY */
288
289
/*============================================================================*/
290
static tWord MAC_fReadPHY(tWord wReg)
291
/*-----------------------------------------------------------------------------
292
  Function:
293
  read the value from a specific phy register.
294
  in:  wReg -> register to read
295
  out: read data
296
=============================================================================*/
297
{
298
  MADR = (wReg & 0x1F); /* the register address. only bits 0..5 are valid. */
299
  MCMD = BIT_00; /* issue a read command */
300
  while(MIND & BIT_00); /* wait until read operation is complete */
301
  MCMD = 0;
302
  return MRDD;
303
} /* end MAC_fReadPHY */
304
305
/*============================================================================*/
306
static void MAC_fLinkInterrupt(void)
307
/*-----------------------------------------------------------------------------
308
  Function:
309
  called when the link is up or down.
310
  in:  none
311
  out: none
312
=============================================================================*/
313
{
314
  tWord wInterrupt = MAC_fReadPHY(PHY_ICS); /* get the interrupt source */
315
  if(wInterrupt & BIT_00)
316
  {
317
    //(*(tpByte)0x81000000) = 0x02; //FIXME
318
    if(MAC_fReadPHY(PHY_STATUS) & BIT_02) /* wait until link is up */
319
    {
320
      if(MAC_fReadPHY(PHY_100BTX) & BIT_04) /* if full duplex is enabled */
321
      {
322
        MAC2 |= BIT_00; /* put the mac into full-duplex mode */
323
        Command |= BIT_10; /* issue full-duplex command */
324
        IPGT = 0x15; /* recommended setting; see LPC2468 User's Manual p. 223 */
325
      }
326
      else
327
      {
328
        IPGT = 0x12; /* recommended setting; see LPC2468 User's Manual p. 223 */
329
      }
330
    }
331
  }
332
  else if(wInterrupt & BIT_02)
333
  {
334
    //(*(tpByte)0x81000000) = 0x01; //FIXME
335
  }
336
  EXTINT |= BIT_01;
337
} /* end MAC_fLinkInterrupt */
338
339
/*============================================================================*/
340
static void MAC_fEthernetInterrupt(void)
341
/*-----------------------------------------------------------------------------
342
  Function:
343
  called when the mac raises an interrupt.
344
  in:  none
345
  out: none
346
=============================================================================*/
347
{
348
} /* end MAC_fEthernetInterrupt */
349
350
/******************************************************************************
351
 * END OF CODE
352
 *****************************************************************************/