2 * Copyright (C) 2012-2013 Czech Technical University in Prague
4 * Created on: 28.2.2013
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
25 * Test command for Ethernet PHY
34 #include "sys/phy_dp83848h.h"
36 unsigned int emacCtrlBase = EMAC_CTRL_BASE;
37 unsigned int emacBase = EMAC_BASE;
38 unsigned int emacCtrlRamBase = EMAC_CTRL_RAM_BASE;
39 unsigned int mdioBase = MDIO_BASE;
41 int rx_irq_cnt; /* Interrupt counters */
44 unsigned int phyalive;
48 unsigned int intvectraw;
50 uint8_t emacAddress[6] = {0x12, 0x34, 0x56, 0x78, 0x90, 0xab};
51 uint32_t emacPhyAddress = 0x1; /* Address of PHY on "MDIO bus"
52 (depends on PHY configuration) */
53 int channel = 0; /* Emac has 8 RX and TX channels; we use only one */
55 EMAC_Desc fr1 __attribute__((aligned(4))); /* Frame descriptor of Ethernet frame to be sent */
57 /* Frame descriptor used for receiving frames --
58 it might be placed in normal RAM or in CPPI ram of EMAC */
59 //EMAC_Desc rx_desc __attribute__((aligned(4)));
60 volatile EMAC_Desc *rx_desc = ((EMAC_Desc*) EMAC_CTRL_RAM_BASE);
63 #define BUFF_SIZE 2048
64 uint8_t rx_buff[BUFF_SIZE]; /* Buffer for data reception */
66 eth_frame_t efr1; /* Buffer for TX -- Before sending some data we have to
67 prepare it in "Ethernet frame" format */
74 for (i = 0; i < 65555; i ++)
78 int emac_test(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
81 unsigned char input = 0;
82 volatile unsigned int delay = 0xfff;
86 /* Deactivate reset pin of PHY */
87 dmmREG->PC4 = (1 << DMM_CLK); /* Set to H */
89 dmmREG->PC5 = (1 << DMM_CLK); /* Set to L */
91 dmmREG->PC4 = (1 << DMM_CLK); /* Set to H */
94 /* Prepare RX Packet buffer descriptor */
95 rx_desc->pBuffer = rx_buff;
96 rx_desc->PktFlgLen = EMAC_DSC_FLAG_OWNER;
97 rx_desc->pNext = NULL;
98 rx_desc->BufOffLen = BUFF_SIZE;
101 /* Fill some testing Ethernet frame with relevant data */
102 efr1.destination[0] = 0x00;
103 efr1.destination[1] = 0x21;
104 efr1.destination[2] = 0x70;
105 efr1.destination[3] = 0xb5;
106 efr1.destination[4] = 0x4b;
107 efr1.destination[5] = 0xea;
108 efr1.source[0] = 0xff;
109 efr1.source[1] = 0xff;
110 efr1.source[2] = 0xff;
111 efr1.source[3] = 0xff;
112 efr1.source[4] = 0xff;
113 efr1.source[5] = 0xff;
122 EMACInit(emacCtrlBase, emacBase);
123 MDIOInit(mdioBase, 0x0, 0x0);
124 dummy_wait(); // FIXME
126 EMACMACSrcAddrSet(emacBase, emacAddress);
127 /* Be sure to program all eight MAC address registers -
128 * whether the receive channel is to be enabled or not.
130 for (chan = 0; chan < 8; chan++)
131 EMACMACAddrSet(emacBase, chan, emacAddress, EMAC_MACADDR_NO_MATCH_NO_FILTER);
133 phyalive = MDIOPhyAliveStatusGet(mdioBase);
135 rpp_sci_printf("PHY not alive\r\n");
139 phylink = MDIOPhyLinkStatusGet(mdioBase);
141 rpp_sci_printf("PHY link down\r\n");
143 rpp_sci_printf("PHY link up\r\n");
145 rpp_sci_printf("Configuring PHY and EMAC...\r\n");
146 PHY_auto_negotiate(mdioBase, emacPhyAddress, PHY_100BASETXDUPL_m | PHY_100BASETX_m | PHY_10BASETDUPL_m | PHY_10BASET_m);
148 /* Set the EMAC with the negotiation results if it is successful */
149 PHY_partner_ability_get(mdioBase, emacPhyAddress, &data);
150 if (data & PHY_100BASETXDUPL_m) {
151 EMACDuplexSet(emacBase, EMAC_DUPLEX_FULL);
153 } else if (data & PHY_100BASETX_m) {
154 EMACDuplexSet(emacBase, EMAC_DUPLEX_HALF);
161 for (chan = 0; chan < 8; chan++) {
162 EMACTxHdrDescPtrWrite(emacBase, 0, chan);
163 EMACRxHdrDescPtrWrite(emacBase, 0, chan);
166 //EMACCoreIntAck(emacBase, EMAC_INT_CORE0_RX);
167 //EMACCoreIntAck(emacBase, EMAC_INT_CORE0_TX);
169 EMACRxBroadCastEnable(emacBase, channel);
170 EMACRxPromiscEnable(emacBase, channel);
172 EMACTxIntPulseEnable(emacBase, emacCtrlBase, 0, channel);
173 EMACRxIntPulseEnable(emacBase, emacCtrlBase, 0, channel);
175 EMACRxHdrDescPtrWrite(emacBase, (unsigned int)rx_desc, channel);
177 //EMACRxUnicastSet(emacBase, 0);
178 EMACTxEnable(emacBase);
179 EMACRxEnable(emacBase);
181 EMACMIIEnable(emacBase);
183 phylink = MDIOPhyLinkStatusGet(mdioBase);
185 rpp_sci_printf("PHY link down\r\n");
187 rpp_sci_printf("PHY link up\r\n");
191 for (j = 0; j < 8; j++) {
193 fr1.pBuffer = (uint8_t*)&efr1;
195 fr1.PktFlgLen = (EMAC_DSC_FLAG_SOP | EMAC_DSC_FLAG_EOP | EMAC_DSC_FLAG_OWNER | 65);
197 EMACTxHdrDescPtrWrite(emacBase, (unsigned int)&fr1, channel);
198 rpp_sci_printf("Packet sent\r\n");
199 while(fr1.PktFlgLen == EMAC_DSC_FLAG_OWNER){
200 if(rpp_sci_read_nb(1, &input) == SUCCESS){
205 intvect = EMACIntVectorGet(emacBase);
206 intvectraw = EMACIntVectorRawGet(emacBase);
214 rpp_sci_printf("Trying to receive some data\r\n");
215 EMACRxIntPulseEnable(emacBase, emacCtrlBase, 0, channel);
217 for (j = 0; j < 8; j++) {
218 while (!(rx_desc->PktFlgLen & EMAC_DSC_FLAG_SOP))
219 if(rpp_sci_read_nb(1, &input) == SUCCESS){
224 rpp_sci_printf("Received packet:\r\n");
225 rpp_sci_printf("Length: %d\r\n", rx_desc->PktFlgLen & 0xffff);
227 for (i = 0; i < (rx_desc->PktFlgLen & 0xffff); i++) {
228 i2str(rx_fr, rx_desc->pBuffer[i], 0, 16);
229 rpp_sci_printf("%x ", rx_desc->pBuffer[i]);
230 if (((i+1) % 8) == 0)
231 rpp_sci_printf("\r\n");
234 /* Reinitialize RX buffer */
235 rx_desc->pBuffer = rx_buff;
236 rx_desc->PktFlgLen = EMAC_DSC_FLAG_OWNER;
237 rx_desc->pNext = NULL;
238 rx_desc->BufOffLen = BUFF_SIZE;
239 EMACRxHdrDescPtrWrite(emacBase, (unsigned int)rx_desc, channel);
240 rpp_sci_printf("\r\n-------------------------------------------\r\n");
243 EMACRxIntPulseDisable(emacBase, emacCtrlBase, 0, channel);
253 cmd_des_t const cmd_des_test_ethernet={
255 "ethernet", "Temporary command to test Ethernet communication",
256 "=== Command syntax ===\n"
260 "=== Description ===\n"
262 "Command tries to send a few ethernet frames. No real connection or\n"
263 "meaningful packets are sent. This only tests, if Ethernet is just\n"
265 CMD_HANDLER(emac_test), (void *)&cmd_list_emac
268 cmd_des_t const *cmd_list_emac[]={
269 &cmd_des_test_ethernet,