2 * Copyright (c) 2010-2013 Xilinx, Inc. All rights reserved.
\r
5 * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
\r
6 * COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
\r
7 * ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
\r
8 * STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
\r
9 * IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
\r
10 * FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
\r
11 * XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
\r
12 * THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
\r
13 * ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
\r
14 * FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
\r
15 * AND FITNESS FOR A PARTICULAR PURPOSE.
\r
20 /* Standard includes. */
\r
25 /* FreeRTOS includes. */
\r
26 #include "FreeRTOS.h"
\r
30 /* FreeRTOS+TCP includes. */
\r
31 #include "FreeRTOS_IP.h"
\r
32 #include "FreeRTOS_Sockets.h"
\r
33 #include "FreeRTOS_IP_Private.h"
\r
34 #include "NetworkBufferManagement.h"
\r
35 #include "NetworkInterface.h"
\r
37 #include "Zynq/x_emacpsif.h"
\r
39 extern TaskHandle_t xEMACTaskHandle;
\r
41 /*** IMPORTANT: Define PEEP in xemacpsif.h and sys_arch_raw.c
\r
42 *** to run it on a PEEP board
\r
45 void setup_isr( xemacpsif_s *xemacpsif )
\r
50 XEmacPs_SetHandler(&xemacpsif->emacps, XEMACPS_HANDLER_DMASEND,
\r
51 (void *) emacps_send_handler,
\r
52 (void *) xemacpsif);
\r
54 XEmacPs_SetHandler(&xemacpsif->emacps, XEMACPS_HANDLER_DMARECV,
\r
55 (void *) emacps_recv_handler,
\r
56 (void *) xemacpsif);
\r
58 XEmacPs_SetHandler(&xemacpsif->emacps, XEMACPS_HANDLER_ERROR,
\r
59 (void *) emacps_error_handler,
\r
60 (void *) xemacpsif);
\r
63 void start_emacps (xemacpsif_s *xemacps)
\r
65 /* start the temac */
\r
66 XEmacPs_Start(&xemacps->emacps);
\r
69 extern struct xtopology_t xXTopology;
\r
71 volatile int error_msg_count = 0;
\r
72 volatile const char *last_err_msg = "";
\r
80 static struct xERROR_MSG xErrorList[ 8 ];
\r
81 static BaseType_t xErrorHead, xErrorTail;
\r
83 void emacps_error_handler(void *arg, u8 Direction, u32 ErrorWord)
\r
85 BaseType_t xHigherPriorityTaskWoken = pdFALSE;
\r
86 xemacpsif_s *xemacpsif;
\r
87 BaseType_t xNextHead = xErrorHead;
\r
89 xemacpsif = (xemacpsif_s *)(arg);
\r
91 if( ( Direction != XEMACPS_SEND ) || (ErrorWord != XEMACPS_TXSR_USEDREAD_MASK ) )
\r
93 if( ++xNextHead == ( sizeof( xErrorList ) / sizeof( xErrorList[ 0 ] ) ) )
\r
95 if( xNextHead != xErrorTail )
\r
98 xErrorList[ xErrorHead ].arg = arg;
\r
99 xErrorList[ xErrorHead ].Direction = Direction;
\r
100 xErrorList[ xErrorHead ].ErrorWord = ErrorWord;
\r
102 xErrorHead = xNextHead;
\r
104 xemacpsif = (xemacpsif_s *)(arg);
\r
105 xemacpsif->isr_events |= EMAC_IF_ERR_EVENT;
\r
108 if( xEMACTaskHandle != NULL )
\r
110 vTaskNotifyGiveFromISR( xEMACTaskHandle, &xHigherPriorityTaskWoken );
\r
115 portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
\r
118 static void emacps_handle_error(void *arg, u8 Direction, u32 ErrorWord);
\r
120 int emacps_check_errors( xemacpsif_s *xemacps )
\r
126 if( xErrorHead == xErrorTail )
\r
133 emacps_handle_error(
\r
134 xErrorList[ xErrorTail ].arg,
\r
135 xErrorList[ xErrorTail ].Direction,
\r
136 xErrorList[ xErrorTail ].ErrorWord );
\r
142 static void emacps_handle_error(void *arg, u8 Direction, u32 ErrorWord)
\r
144 xemacpsif_s *xemacpsif;
\r
145 struct xtopology_t *xtopologyp;
\r
148 xemacpsif = (xemacpsif_s *)(arg);
\r
150 xtopologyp = &xXTopology;
\r
152 xemacps = &xemacpsif->emacps;
\r
154 /* Do not appear to be used. */
\r
156 ( void ) xtopologyp;
\r
158 last_err_msg = NULL;
\r
160 if( ErrorWord != 0 )
\r
162 switch (Direction) {
\r
164 if( ( ErrorWord & XEMACPS_RXSR_HRESPNOK_MASK ) != 0 )
\r
166 last_err_msg = "Receive DMA error";
\r
167 xNetworkInterfaceInitialise( );
\r
169 if( ( ErrorWord & XEMACPS_RXSR_RXOVR_MASK ) != 0 )
\r
171 last_err_msg = "Receive over run";
\r
172 emacps_recv_handler(arg);
\r
174 if( ( ErrorWord & XEMACPS_RXSR_BUFFNA_MASK ) != 0 )
\r
176 last_err_msg = "Receive buffer not available";
\r
177 emacps_recv_handler(arg);
\r
181 if( ( ErrorWord & XEMACPS_TXSR_HRESPNOK_MASK ) != 0 )
\r
183 last_err_msg = "Transmit DMA error";
\r
184 xNetworkInterfaceInitialise( );
\r
186 if( ( ErrorWord & XEMACPS_TXSR_URUN_MASK ) != 0 )
\r
188 last_err_msg = "Transmit under run";
\r
189 HandleTxErrors( xemacpsif );
\r
191 if( ( ErrorWord & XEMACPS_TXSR_BUFEXH_MASK ) != 0 )
\r
193 last_err_msg = "Transmit buffer exhausted";
\r
194 HandleTxErrors( xemacpsif );
\r
196 if( ( ErrorWord & XEMACPS_TXSR_RXOVR_MASK ) != 0 )
\r
198 last_err_msg = "Transmit retry excessed limits";
\r
199 HandleTxErrors( xemacpsif );
\r
201 if( ( ErrorWord & XEMACPS_TXSR_FRAMERX_MASK ) != 0 )
\r
203 last_err_msg = "Transmit collision";
\r
204 emacps_check_tx( xemacpsif );
\r
209 // Break on this statement and inspect error_msg if you like
\r
210 if( last_err_msg != NULL )
\r
213 FreeRTOS_printf( ( "emacps_handle_error: %s\n", last_err_msg ) );
\r
217 void HandleTxErrors(xemacpsif_s *xemacpsif)
\r
221 //taskENTER_CRITICAL()
\r
223 netctrlreg = XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress,
\r
224 XEMACPS_NWCTRL_OFFSET);
\r
225 netctrlreg = netctrlreg & (~XEMACPS_NWCTRL_TXEN_MASK);
\r
226 XEmacPs_WriteReg(xemacpsif->emacps.Config.BaseAddress,
\r
227 XEMACPS_NWCTRL_OFFSET, netctrlreg);
\r
229 clean_dma_txdescs( xemacpsif );
\r
230 netctrlreg = XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress,
\r
231 XEMACPS_NWCTRL_OFFSET);
\r
232 netctrlreg = netctrlreg | (XEMACPS_NWCTRL_TXEN_MASK);
\r
233 XEmacPs_WriteReg(xemacpsif->emacps.Config.BaseAddress,
\r
234 XEMACPS_NWCTRL_OFFSET, netctrlreg);
\r
236 //taskEXIT_CRITICAL( );
\r