]> rtime.felk.cvut.cz Git - pes-rpp/rpp-test-sw.git/blob - rpp/lib/cmdproc/src/commands/cmd_emac.c
40179695ff3780fe442adbc2ba6a2cd6bf863e8c
[pes-rpp/rpp-test-sw.git] / rpp / lib / cmdproc / src / commands / cmd_emac.c
1 #include "commands/cmd_emac.h"
2 #include "rpp/rpp.h"
3 #include "sys/sys.h"
4
5 unsigned int emacCtrlBase       = EMAC_CTRL_BASE;
6 unsigned int emacBase           = EMAC_BASE;
7 unsigned int emacCtrlRamBase    = EMAC_CTRL_RAM_BASE;
8 unsigned int mdioBase           = MDIO_BASE;
9
10 int rx_irq_cnt; /* Interrupt counters */
11 int tx_irq_cnt;
12
13 unsigned int phyalive;
14 unsigned int phylink;
15
16 unsigned int intvect;
17 unsigned int intvectraw;
18
19 uint8_t emacAddress[6]  = {0x12, 0x34, 0x56, 0x78, 0x90, 0xab};
20 uint32_t emacPhyAddress = 0x1;  /* Address of PHY on "MDIO bus"
21                                    (depends on PHY configuration) */
22 int channel = 0;        /* Emac has 8 RX and TX channels; we use only one */
23
24 EMAC_Desc fr1 __attribute__((aligned(4)));      /* Frame descriptor of Ethernet frame to be sent */
25
26 /* Frame descriptor used for receiving frames --
27    it might be placed in normal RAM or in CPPI ram of EMAC */
28 //EMAC_Desc rx_desc __attribute__((aligned(4)));
29 volatile EMAC_Desc *rx_desc = ((EMAC_Desc*) EMAC_CTRL_RAM_BASE);
30
31
32 #define BUFF_SIZE       2048
33 uint8_t rx_buff[BUFF_SIZE]; /* Buffer for data reception */
34
35 eth_frame_t efr1;       /* Buffer for TX -- Before sending some data we have to
36                            prepare it in "Ethernet frame" format */
37
38
39 void dummy_wait()
40 {
41         volatile int i;
42
43         for (i = 0; i < 65555; i ++)
44                 ;
45 }
46
47 #pragma INTERRUPT(EMACCore0RxIsr, FIQ)
48 void EMACCore0RxIsr(void)
49 {
50         rx_irq_cnt++;
51
52         /* We know we have only one RX Packet Buffer descriptor --
53            so we write it in CP to disable interrupt */
54         EMACRxCPWrite(emacBase, channel, (unsigned int)rx_desc);
55         EMACCoreIntAck(emacBase, EMAC_INT_CORE0_RX);
56 }
57
58 #pragma INTERRUPT(EMACCore0TxIsr, FIQ)
59 void EMACCore0TxIsr(void)
60 {
61         tx_irq_cnt++;
62         /* If is not being processed by the EMAC anymore */
63         if (!(fr1.PktFlgLen & EMAC_DSC_FLAG_OWNER)) {
64                 EMACTxCPWrite(emacBase, channel, (unsigned int)&fr1);
65                 EMACCoreIntAck(emacBase, EMAC_INT_CORE0_TX);
66         }
67 }
68
69 int emac_test(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
70 {
71         int chan;
72         volatile unsigned int delay = 0xfff;
73         unsigned short data;
74         int j;
75
76         /* Deactivate reset pin of PHY */
77         dmmREG->PC4 = (1 << DMM_CLK); /* Set to H */
78         dummy_wait();
79         dmmREG->PC5 = (1 << DMM_CLK); /* Set to L */
80         dummy_wait();
81         dmmREG->PC4 = (1 << DMM_CLK); /* Set to H */
82         dummy_wait();
83
84         /* Prepare RX Packet buffer descriptor */
85         rx_desc->pBuffer = rx_buff;
86         rx_desc->PktFlgLen = EMAC_DSC_FLAG_OWNER;
87         rx_desc->pNext = NULL;
88         rx_desc->BufOffLen = BUFF_SIZE;
89
90
91         /* Fill some testing Ethernet frame with relevant data */
92         efr1.destination[0] = 0x00;
93         efr1.destination[1] = 0x21;
94         efr1.destination[2] = 0x70;
95         efr1.destination[3] = 0xb5;
96         efr1.destination[4] = 0x4b;
97         efr1.destination[5] = 0xea;
98         efr1.source[0]      = 0xff;
99         efr1.source[1]      = 0xff;
100         efr1.source[2]      = 0xff;
101         efr1.source[3]      = 0xff;
102         efr1.source[4]      = 0xff;
103         efr1.source[5]      = 0xff;
104
105         efr1.len = 46;
106         efr1.data[0] = 0xaa;
107
108         _enable_IRQ();
109         _enable_FIQ();
110
111
112         EMACInit(emacCtrlBase, emacBase);
113         MDIOInit(mdioBase, 0x0, 0x0);
114         dummy_wait();   // FIXME
115
116         EMACMACSrcAddrSet(emacBase, emacAddress);
117         /*  Be sure to program all eight MAC address registers -
118          *  whether the receive channel is to be enabled or not.
119          */
120         for (chan = 0; chan < 8; chan++)
121                 EMACMACAddrSet(emacBase, chan, emacAddress, EMAC_MACADDR_NO_MATCH_NO_FILTER);
122
123         phyalive = MDIOPhyAliveStatusGet(mdioBase);
124         if (!phyalive) {
125                 rpp_sci_printf("PHY not alive\r\n");
126                 return -1;
127         }
128
129         phylink = MDIOPhyLinkStatusGet(mdioBase);
130         if (!phylink)
131                 rpp_sci_printf("PHY link down\r\n");
132         else
133                 rpp_sci_printf("PHY link up\r\n");
134
135         rpp_sci_printf("Configuring PHY and EMAC...\r\n");
136         PHY_configure(mdioBase, emacPhyAddress);
137
138         /* Set the EMAC with the negotiation results if it is successful */
139         PHY_partner_ability_get(mdioBase, emacPhyAddress, &data);
140         if (data & PHY_100BASETXDUPL_m) {
141                 EMACDuplexSet(emacBase, EMAC_DUPLEX_FULL);
142                 dummy_wait();
143         } else if (data & PHY_100BASETX_m) {
144                 EMACDuplexSet(emacBase, EMAC_DUPLEX_HALF);
145                 dummy_wait();
146         } else {
147                 while(1)
148                         ;
149         }
150
151         for (chan = 0; chan < 8; chan++) {
152                 EMACTxHdrDescPtrWrite(emacBase, 0, chan);
153                 EMACRxHdrDescPtrWrite(emacBase, 0, chan);
154         }
155
156         //EMACCoreIntAck(emacBase, EMAC_INT_CORE0_RX);
157         //EMACCoreIntAck(emacBase, EMAC_INT_CORE0_TX);
158
159         EMACRxBroadCastEnable(emacBase, channel);
160         EMACRxPromiscEnable(emacBase, channel);
161
162         EMACTxIntPulseEnable(emacBase, emacCtrlBase, 0, channel);
163         EMACRxIntPulseEnable(emacBase, emacCtrlBase, 0, channel);
164
165         EMACRxHdrDescPtrWrite(emacBase, (unsigned int)rx_desc, channel);
166
167         //EMACRxUnicastSet(emacBase, 0);
168         EMACTxEnable(emacBase);
169         EMACRxEnable(emacBase);
170
171         EMACMIIEnable(emacBase);
172
173         phylink = MDIOPhyLinkStatusGet(mdioBase);
174         if (!phylink)
175                 rpp_sci_printf("PHY link down\r\n");
176         else
177                 rpp_sci_printf("PHY link up\r\n");
178
179
180         /* TX */
181         for (j = 0; j < 8; j++) {
182                 fr1.pNext = NULL;
183                 fr1.pBuffer = (uint8_t*)&efr1;
184                 fr1.BufOffLen = 65;
185                 fr1.PktFlgLen = (EMAC_DSC_FLAG_SOP | EMAC_DSC_FLAG_EOP | EMAC_DSC_FLAG_OWNER | 65);
186
187                 EMACTxHdrDescPtrWrite(emacBase, (unsigned int)&fr1, channel);
188                 rpp_sci_printf("Packet sent\r\n");
189                 dummy_wait();
190                 intvect = EMACIntVectorGet(emacBase);
191                 intvectraw = EMACIntVectorRawGet(emacBase);
192         }
193
194         /* Dummy RX */
195         {
196                 char rx_fr[10];
197                 int i;
198
199                 rpp_sci_printf("Trying to receive some data\r\n");
200                 EMACRxIntPulseEnable(emacBase, emacCtrlBase, 0, channel);
201
202                 for (j = 0; j < 8; j++) {
203                         while (!(rx_desc->PktFlgLen & EMAC_DSC_FLAG_SOP))
204                                 ;
205
206                         rpp_sci_printf("Received packet:\r\n");
207                         rpp_sci_printf("Length: %d\r\n", rx_desc->PktFlgLen & 0xffff);
208
209                         for (i = 0; i < (rx_desc->PktFlgLen & 0xffff); i++) {
210                                 i2str(rx_fr, rx_desc->pBuffer[i], 0, 16);
211                                 rpp_sci_printf("%h ", rx_desc->pBuffer[i]);
212                                 if (((i+1) % 8) == 0)
213                                         rpp_sci_printf("\r\n");
214                         }
215
216                         /* Reinitialize RX buffer */
217                         rx_desc->pBuffer = rx_buff;
218                         rx_desc->PktFlgLen = EMAC_DSC_FLAG_OWNER;
219                         rx_desc->pNext = NULL;
220                         rx_desc->BufOffLen = BUFF_SIZE;
221                         EMACRxHdrDescPtrWrite(emacBase, (unsigned int)rx_desc, channel);
222                         rpp_sci_printf("\r\n-------------------------------------------\r\n");
223                 }
224
225                 EMACRxIntPulseDisable(emacBase, emacCtrlBase, 0, channel);
226         }
227
228
229
230         return 0;
231 }
232
233 cmd_des_t const cmd_des_test_ethernet={
234     0, 0,
235     "ethernet", "Try to send few ethernet frames",
236     emac_test, (void *)&cmd_list_emac
237 };
238
239 cmd_des_t const *cmd_list_emac[]={
240   &cmd_des_test_ethernet,
241   NULL
242 };