2 * Copyright (C) 2012-2013 Czech Technical University in Prague
4 * Created on: 28.2.2013
9 * This document contains proprietary information belonging to Czech
10 * Technical University in Prague. Passing on and copying of this
11 * document, and communication of its contents is not permitted
12 * without prior written authorization.
17 * Test command for Ethernet PHY
26 #include "sys/phy_dp83848h.h"
29 /* ************************************************* */
30 /* Emac frame buffer related stuff */
31 /* ************************************************* */
32 typedef struct _EMAC_Desc {
33 struct _EMAC_Desc *pNext; /* Pointer to next descriptor in chain */
34 uint8_t *pBuffer; /* Pointer to data buffer */
35 uint32_t BufOffLen; /* Buffer Offset(MSW) and Length(LSW) */
36 uint32_t PktFlgLen; /* Packet Flags(MSW) and Length(LSW) */
40 #define EMAC_DSC_FLAG_SOP 0x80000000u
41 #define EMAC_DSC_FLAG_EOP 0x40000000u
42 #define EMAC_DSC_FLAG_OWNER 0x20000000u
43 #define EMAC_DSC_FLAG_EOQ 0x10000000u
44 #define EMAC_DSC_FLAG_TDOWNCMPLT 0x08000000u
45 #define EMAC_DSC_FLAG_PASSCRC 0x04000000u
47 /* ************************************************* */
49 /* ************************************************* */
51 uint8_t destination[6];
58 /* ************************************************* */
62 unsigned int emacCtrlBase = EMAC_CTRL_BASE;
63 unsigned int emacBase = EMAC_BASE;
64 unsigned int emacCtrlRamBase = EMAC_CTRL_RAM_BASE;
65 unsigned int mdioBase = MDIO_BASE;
67 int rx_irq_cnt; /* Interrupt counters */
70 unsigned int phyalive;
74 unsigned int intvectraw;
77 * Emac address is used only in this debugging tool. During emac_test is't called rpp_init().
78 * MAC address defined in eth.h have no efect in this test file.
81 uint8_t emacAddress[6] = {0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc};
82 uint32_t emacPhyAddress = 0x1; /* Address of PHY on "MDIO bus"
83 (depends on PHY configuration) */
84 int channel = 0; /* Emac has 8 RX and TX channels; we use only one */
86 EMAC_Desc fr1 __attribute__((aligned(4))); /* Frame descriptor of Ethernet frame to be sent */
88 /* Frame descriptor used for receiving frames --
89 it might be placed in normal RAM or in CPPI ram of EMAC */
90 //EMAC_Desc rx_desc __attribute__((aligned(4)));
91 volatile EMAC_Desc *rx_desc = ((EMAC_Desc *)EMAC_CTRL_RAM_BASE);
94 #define BUFF_SIZE 2048
95 uint8_t rx_buff[BUFF_SIZE]; /* Buffer for data reception */
97 eth_frame_t efr1; /* Buffer for TX -- Before sending some data we have to
98 prepare it in "Ethernet frame" format */
105 for (i = 0; i < 65555; i++)
109 int emac_test(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
112 unsigned char input = 0;
113 volatile unsigned int delay = 0xfff;
117 #ifdef TARGET_TMS570_RPP
118 /* Deactivate reset pin of PHY */
119 dmmREG->PC4 = (1 << DMM_CLK); /* Set to H */
121 dmmREG->PC5 = (1 << DMM_CLK); /* Set to L */
123 dmmREG->PC4 = (1 << DMM_CLK); /* Set to H */
127 /* Prepare RX Packet buffer descriptor */
128 rx_desc->pBuffer = rx_buff;
129 rx_desc->PktFlgLen = EMAC_DSC_FLAG_OWNER;
130 rx_desc->pNext = NULL;
131 rx_desc->BufOffLen = BUFF_SIZE;
134 /* Fill some testing Ethernet frame with relevant data */
135 efr1.destination[0] = 0x00;
136 efr1.destination[1] = 0x21;
137 efr1.destination[2] = 0x70;
138 efr1.destination[3] = 0xb5;
139 efr1.destination[4] = 0x4b;
140 efr1.destination[5] = 0xea;
141 efr1.source[0] = 0xff;
142 efr1.source[1] = 0xff;
143 efr1.source[2] = 0xff;
144 efr1.source[3] = 0xff;
145 efr1.source[4] = 0xff;
146 efr1.source[5] = 0xff;
155 EMACInit(emacCtrlBase, emacBase);
156 MDIOInit(mdioBase, 0x0, 0x0);
157 dummy_wait(); // FIXME
159 EMACMACSrcAddrSet(emacBase, emacAddress);
160 /* Be sure to program all eight MAC address registers -
161 * whether the receive channel is to be enabled or not.
163 for (chan = 0; chan < 8; chan++)
164 EMACMACAddrSet(emacBase, chan, emacAddress, EMAC_MACADDR_NO_MATCH_NO_FILTER);
166 phyalive = MDIOPhyAliveStatusGet(mdioBase);
168 rpp_sci_printf("PHY not alive\r\n");
172 phylink = MDIOPhyLinkStatusGet(mdioBase);
174 rpp_sci_printf("PHY link down\r\n");
176 rpp_sci_printf("PHY link up\r\n");
178 rpp_sci_printf("Configuring PHY and EMAC...\r\n");
179 PHY_auto_negotiate(mdioBase, emacPhyAddress, PHY_100BASETXDUPL_m | PHY_100BASETX_m | PHY_10BASETDUPL_m | PHY_10BASET_m);
181 /* Set the EMAC with the negotiation results if it is successful */
182 PHY_partner_ability_get(mdioBase, emacPhyAddress, &data);
183 if (data & PHY_100BASETXDUPL_m) {
184 EMACDuplexSet(emacBase, EMAC_DUPLEX_FULL);
187 else if (data & PHY_100BASETX_m) {
188 EMACDuplexSet(emacBase, EMAC_DUPLEX_HALF);
195 for (chan = 0; chan < 8; chan++) {
196 EMACTxHdrDescPtrWrite(emacBase, 0, chan);
197 EMACRxHdrDescPtrWrite(emacBase, 0, chan);
200 //EMACCoreIntAck(emacBase, EMAC_INT_CORE0_RX);
201 //EMACCoreIntAck(emacBase, EMAC_INT_CORE0_TX);
203 EMACRxBroadCastEnable(emacBase, channel);
204 EMACRxPromiscEnable(emacBase, channel);
206 EMACTxIntPulseEnable(emacBase, emacCtrlBase, 0, channel);
207 EMACRxIntPulseEnable(emacBase, emacCtrlBase, 0, channel);
209 EMACRxHdrDescPtrWrite(emacBase, (unsigned int)rx_desc, channel);
211 //EMACRxUnicastSet(emacBase, 0);
212 EMACTxEnable(emacBase);
213 EMACRxEnable(emacBase);
215 EMACMIIEnable(emacBase);
217 phylink = MDIOPhyLinkStatusGet(mdioBase);
219 rpp_sci_printf("PHY link down\r\n");
221 rpp_sci_printf("PHY link up\r\n");
225 for (j = 0; j < 8; j++) {
227 fr1.pBuffer = (uint8_t *)&efr1;
229 fr1.PktFlgLen = (EMAC_DSC_FLAG_SOP | EMAC_DSC_FLAG_EOP | EMAC_DSC_FLAG_OWNER | 65);
231 EMACTxHdrDescPtrWrite(emacBase, (unsigned int)&fr1, channel);
232 rpp_sci_printf("Packet sent\r\n");
233 while (fr1.PktFlgLen == EMAC_DSC_FLAG_OWNER)
234 if (rpp_sci_read_nb(1, &input) == SUCCESS)
237 intvect = EMACIntVectorGet(emacBase);
238 intvectraw = EMACIntVectorRawGet(emacBase);
246 rpp_sci_printf("Trying to receive some data\r\n");
247 EMACRxIntPulseEnable(emacBase, emacCtrlBase, 0, channel);
249 for (j = 0; j < 8; j++) {
250 while (!(rx_desc->PktFlgLen & EMAC_DSC_FLAG_SOP))
251 if (rpp_sci_read_nb(1, &input) == SUCCESS)
256 rpp_sci_printf("Received packet:\r\n");
257 rpp_sci_printf("Length: %d\r\n", rx_desc->PktFlgLen & 0xffff);
259 for (i = 0; i < (rx_desc->PktFlgLen & 0xffff); i++) {
260 i2str(rx_fr, rx_desc->pBuffer[i], 0, 16);
261 rpp_sci_printf("%x ", rx_desc->pBuffer[i]);
262 if (((i+1) % 8) == 0)
263 rpp_sci_printf("\r\n");
266 /* Reinitialize RX buffer */
267 rx_desc->pBuffer = rx_buff;
268 rx_desc->PktFlgLen = EMAC_DSC_FLAG_OWNER;
269 rx_desc->pNext = NULL;
270 rx_desc->BufOffLen = BUFF_SIZE;
271 EMACRxHdrDescPtrWrite(emacBase, (unsigned int)rx_desc, channel);
272 rpp_sci_printf("\r\n-------------------------------------------\r\n");
275 EMACRxIntPulseDisable(emacBase, emacCtrlBase, 0, channel);
285 cmd_des_t const cmd_des_test_ethernet = {
287 "ethernet", "Temporary command to test Ethernet communication",
288 "### Command syntax ###\n"
292 "### Description ###\n"
294 "Command tries to send a few ethernet frames. No real connection or\n"
295 "meaningful packets are sent. This only tests, if Ethernet is just\n"
297 CMD_HANDLER(emac_test), (void *)&cmd_list_emac
300 cmd_des_t const *cmd_list_emac[] = {
301 &cmd_des_test_ethernet,