1 | #include "mac.h"
|
2 |
|
3 | #include "lpc2468.h"
|
4 |
|
5 | #include "ucos_ii.h"
|
6 | #include "os_cpu.h"
|
7 |
|
8 | SDRAM OS_EVENT *macsem;
|
9 | SDRAM OS_EVENT *macmbox;
|
10 |
|
11 | void MAC_fInitialize(OS_EVENT* m)
|
12 | {
|
13 | tDWord dwID;
|
14 | macsem = OSSemCreate(0);
|
15 | macmbox = m;
|
16 | tByte err;
|
17 |
|
18 | PCONP |= BIT_30; /* power up the mac */
|
19 | PINSEL2 |= (BIT_00 | BIT_02 | BIT_08 | BIT_16 | /* select the rmii pins */
|
20 | BIT_18 | BIT_20 | BIT_28 | BIT_30);
|
21 | PINSEL3 |= (BIT_00 | BIT_02); /* select the mdio and clk pins */
|
22 | MAC1 = (BIT_08 | BIT_09 | BIT_10 | BIT_11 | BIT_14 | BIT_15); /* reset */
|
23 | Command = (BIT_03 | BIT_04 | BIT_05); /* reset the mac */
|
24 | MAC1 = 0; /* deassert the resets */
|
25 | MAC2 = 0; /* set the mac into the default state */
|
26 | IPGR = IPGR_DEFAULT; /* set the back-to-back inter packet gap */
|
27 | CLRT = CLRT_DEFAULT; /* set the collision window and retransmission count */
|
28 | MAXF = MAX_FRAME; /* maximum frame length */
|
29 |
|
30 | MCFG = (BIT_02 | BIT_03 | BIT_04 | BIT_15); /* divide clk by 20, reset mii */
|
31 | MCFG ^= BIT_15; /* deassert the mii reset */
|
32 | MCMD = 0; /* clear the command register */
|
33 | Command = (BIT_09 | BIT_06 /*| BIT_07*/); /* enable the rmii */
|
34 | SUPP = BIT_08; /* enable 100MBit mode */
|
35 | MAC_fWritePHY(PHY_BCR, BIT_15); /* reset the phy */
|
36 | while(MAC_fReadPHY(PHY_BCR) & BIT_15); /* wait until reset is done */
|
37 | dwID = (MAC_fReadPHY(PHY_ID1) << 16); /* get PHY manufacturer and revision */
|
38 | dwID |= (MAC_fReadPHY(PHY_ID2) & 0xFFF0);
|
39 | if(dwID != KSZ8001_ID) /* check if this is a KSZ8001L PHY */
|
40 | {
|
41 | return; /* abort */
|
42 | }
|
43 | MAC_fWritePHY(PHY_ICS, BIT_08 | BIT_10); /* enable link interrupt */
|
44 | MAC_fWritePHY(PHY_CTL, BIT_14); /* enable the link and act LEDs */
|
45 | MAC_fWritePHY(PHY_BCR, BIT_12 | BIT_09); /* enable & start autonegotiation */
|
46 |
|
47 | PINSEL4 |= BIT_22; /* enable EINT1 interrupt */
|
48 | VICVectPriority15 = 0; /* set up the phy interrupt */
|
49 | VICVectAddr15 = (tDWord)MAC_fPHYInterrupt;
|
50 | VICIntEnable |= BIT_15; /* enable the link up/down interrupt */
|
51 |
|
52 | OSSemPend(macsem, 0, &err); /* wait until link established */
|
53 |
|
54 | SA0 = (MAC_ADDRESS1 << 8) | MAC_ADDRESS2; /* set up the mac address */
|
55 | SA1 = (MAC_ADDRESS3 << 8) | MAC_ADDRESS4;
|
56 | SA2 = (MAC_ADDRESS5 << 8) | MAC_ADDRESS6;
|
57 | MAC_fInitRxDescriptors(); /* initialize rx descriptors */
|
58 | MAC_fInitTxDescriptors(); /* initialize tx descriptors */
|
59 |
|
60 | RxFilterCtrl = (BIT_01 | BIT_02 | BIT_05); /* uni-, multi- and broadcast */
|
61 |
|
62 | Command |= (BIT_00 | BIT_01); /* enable receiver and transmitter */
|
63 | MAC1 |= BIT_00; /* enable the receiver */
|
64 |
|
65 | VICVectPriority21 = 0; /* set up the mac interrupt */
|
66 | VICVectAddr21 = (tDWord)MAC_fMACInterrupt;
|
67 | VICIntEnable |= BIT_21; /* enable the mac interrupt */
|
68 | IntClear = 0xFFFFFFFF;
|
69 | IntEnable = BIT_03;
|
70 | return;
|
71 | }
|
72 |
|
73 | static void MAC_fPHYInterrupt(void)
|
74 | {
|
75 | tWord wInterrupt = MAC_fReadPHY(PHY_ICS); /* get the interrupt source */
|
76 | if(wInterrupt & BIT_00)
|
77 | {
|
78 | tWord wMode = (MAC_fReadPHY(PHY_100BTX) & (BIT_04 | BIT_03 | BIT_02));
|
79 | switch(wMode)
|
80 | {
|
81 | case MODE_10M_HALF_DUPLEX:
|
82 | {
|
83 | MAC2 = (BIT_04 | BIT_05 | BIT_07); /* crc, padding, half duplex */
|
84 | SUPP = 0; /* 10MBit mode */
|
85 | Command &= ~BIT_10; /* issue half duplex command */
|
86 | IPGT = 0x12; /* default setting for 10 MBits, half duplex */
|
87 | break;
|
88 | }
|
89 | case MODE_10M_FULL_DUPLEX:
|
90 | {
|
91 | MAC2 = (BIT_00 | BIT_04 | BIT_05 | BIT_07); /* crc, padding, full duplex */
|
92 | SUPP = 0; /* 10MBit mode */
|
93 | Command |= BIT_10; /* issue full-duplex command */
|
94 | IPGT = 0x15; /* default setting for 10 MBits, full duplex */
|
95 | break;
|
96 | }
|
97 | case MODE_100M_HALF_DUPLEX:
|
98 | {
|
99 | MAC2 = (BIT_04 | BIT_05 | BIT_07); /* crc, padding, half duplex */
|
100 | SUPP = 0; /* enable 100MBit mode */
|
101 | Command &= ~BIT_10; /* issue half-duplex command */
|
102 | IPGT = 0x12; /* default setting for 100 MBits, half duplex */
|
103 | break;
|
104 | }
|
105 | case MODE_100M_FULL_DUPLEX:
|
106 | {
|
107 | MAC2 = (BIT_00 | BIT_04 | BIT_05 | BIT_07); /* crc, padding, full duplex */
|
108 | SUPP = BIT_08; /* enable 100MBit mode */
|
109 | Command |= BIT_10; /* issue full-duplex command */
|
110 | IPGT = 0x15; /* default setting for 100 MBits, full duplex */
|
111 | break;
|
112 | }
|
113 | }
|
114 | OSSemPost(macsem);
|
115 | }
|
116 | else if(wInterrupt & BIT_02)
|
117 | {
|
118 | }
|
119 | EXTINT |= BIT_01;
|
120 | }
|
121 |
|
122 | static void MAC_fMACInterrupt(void)
|
123 | {
|
124 | tDWord dwIntStatus = IntStatus; /* get the interrupt source */
|
125 | if(dwIntStatus & BIT_00) /* rx overrun */
|
126 | {
|
127 | IntClear = BIT_00; /* acknowledge interrupt */
|
128 | }
|
129 | if(dwIntStatus & BIT_01) /* rx error */
|
130 | {
|
131 | IntClear = BIT_01; /* acknowledge interrupt */
|
132 | }
|
133 | if(dwIntStatus & BIT_02) /* rx finished */
|
134 | {
|
135 | IntClear = BIT_02; /* acknowledge interrupt */
|
136 | }
|
137 | if(dwIntStatus & BIT_03) /* rx done */
|
138 | {
|
139 | tWord wIdx = RxConsumeIndex; /* get the index of the next received frame */
|
140 | OSMboxPost(macmbox, (void*)dwRxDescriptors[wIdx * 2]);
|
141 | wIdx++;
|
142 | if(wIdx == MAC_RX_FRAGMENTS)
|
143 | wIdx = 0;
|
144 | RxConsumeIndex = wIdx;
|
145 | IntClear = BIT_03;
|
146 | }
|
147 | if(dwIntStatus & BIT_04) /* tx underrun */
|
148 | {
|
149 | IntClear = BIT_04; /* acknowledge interrupt */
|
150 | }
|
151 | if(dwIntStatus & BIT_05) /* tx error */
|
152 | {
|
153 | IntClear = BIT_05; /* acknowledge interrupt */
|
154 | }
|
155 | if(dwIntStatus & BIT_06) /* tx finished */
|
156 | {
|
157 | IntClear = BIT_06; /* acknowledge interrupt */
|
158 | }
|
159 | if(dwIntStatus & BIT_07) /* tx done */
|
160 | {
|
161 | IntClear = BIT_07; /* acknowledge interrupt */
|
162 | }
|
163 | if(dwIntStatus & BIT_12) /* software interrupt */
|
164 | {
|
165 | IntClear = BIT_12; /* acknowledge interrupt */
|
166 | }
|
167 | if(dwIntStatus & BIT_13) /* wakeup */
|
168 | {
|
169 | IntClear = BIT_13; /* acknowledge interrupt */
|
170 | }
|
171 | }
|