]> git.sur5r.net Git - freertos/blob - FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_hw.c
commit 9f316c246baafa15c542a5aea81a94f26e3d6507
[freertos] / FreeRTOS-Plus / Source / FreeRTOS-Plus-TCP / portable / NetworkInterface / Zynq / x_emacpsif_hw.c
1 /*\r
2  * Copyright (c) 2010-2013 Xilinx, Inc.  All rights reserved.\r
3  *\r
4  * Xilinx, Inc.\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
16  *\r
17  */\r
18 \r
19 \r
20 /* Standard includes. */\r
21 #include <stdint.h>\r
22 #include <stdio.h>\r
23 #include <stdlib.h>\r
24 \r
25 /* FreeRTOS includes. */\r
26 #include "FreeRTOS.h"\r
27 #include "task.h"\r
28 #include "queue.h"\r
29 \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
36 \r
37 #include "Zynq/x_emacpsif.h"\r
38 \r
39 extern TaskHandle_t xEMACTaskHandle;\r
40 \r
41 /*** IMPORTANT: Define PEEP in xemacpsif.h and sys_arch_raw.c\r
42  *** to run it on a PEEP board\r
43  ***/\r
44 \r
45 void setup_isr( xemacpsif_s *xemacpsif )\r
46 {\r
47         /*\r
48          * Setup callbacks\r
49          */\r
50         XEmacPs_SetHandler(&xemacpsif->emacps, XEMACPS_HANDLER_DMASEND,\r
51                 (void *) emacps_send_handler,\r
52                 (void *) xemacpsif);\r
53 \r
54         XEmacPs_SetHandler(&xemacpsif->emacps, XEMACPS_HANDLER_DMARECV,\r
55                 (void *) emacps_recv_handler,\r
56                 (void *) xemacpsif);\r
57 \r
58         XEmacPs_SetHandler(&xemacpsif->emacps, XEMACPS_HANDLER_ERROR,\r
59                 (void *) emacps_error_handler,\r
60                 (void *) xemacpsif);\r
61 }\r
62 \r
63 void start_emacps (xemacpsif_s *xemacps)\r
64 {\r
65         /* start the temac */\r
66         XEmacPs_Start(&xemacps->emacps);\r
67 }\r
68 \r
69 extern struct xtopology_t xXTopology;\r
70 \r
71 volatile int error_msg_count = 0;\r
72 volatile const char *last_err_msg = "";\r
73 \r
74 struct xERROR_MSG {\r
75         void *arg;\r
76         u8 Direction;\r
77         u32 ErrorWord;\r
78 };\r
79 \r
80 static struct xERROR_MSG xErrorList[ 8 ];\r
81 static BaseType_t xErrorHead, xErrorTail;\r
82 \r
83 void emacps_error_handler(void *arg, u8 Direction, u32 ErrorWord)\r
84 {\r
85         BaseType_t xHigherPriorityTaskWoken = pdFALSE;\r
86         xemacpsif_s *xemacpsif;\r
87         BaseType_t xNextHead = xErrorHead;\r
88 \r
89         xemacpsif = (xemacpsif_s *)(arg);\r
90 \r
91         if( ( Direction != XEMACPS_SEND ) || (ErrorWord != XEMACPS_TXSR_USEDREAD_MASK ) )\r
92         {\r
93                 if( ++xNextHead == ( sizeof( xErrorList ) / sizeof( xErrorList[ 0 ] ) ) )\r
94                         xNextHead = 0;\r
95                 if( xNextHead != xErrorTail )\r
96                 {\r
97 \r
98                         xErrorList[ xErrorHead ].arg = arg;\r
99                         xErrorList[ xErrorHead ].Direction = Direction;\r
100                         xErrorList[ xErrorHead ].ErrorWord = ErrorWord;\r
101 \r
102                         xErrorHead = xNextHead;\r
103 \r
104                         xemacpsif = (xemacpsif_s *)(arg);\r
105                         xemacpsif->isr_events |= EMAC_IF_ERR_EVENT;\r
106                 }\r
107 \r
108                 if( xEMACTaskHandle != NULL )\r
109                 {\r
110                         vTaskNotifyGiveFromISR( xEMACTaskHandle, &xHigherPriorityTaskWoken );\r
111                 }\r
112 \r
113         }\r
114 \r
115         portYIELD_FROM_ISR( xHigherPriorityTaskWoken );\r
116 }\r
117 \r
118 static void emacps_handle_error(void *arg, u8 Direction, u32 ErrorWord);\r
119 \r
120 int emacps_check_errors( xemacpsif_s *xemacps )\r
121 {\r
122 int xResult;\r
123 \r
124         ( void ) xemacps;\r
125 \r
126         if( xErrorHead == xErrorTail )\r
127         {\r
128                 xResult = 0;\r
129         }\r
130         else\r
131         {\r
132                 xResult = 1;\r
133                 emacps_handle_error(\r
134                         xErrorList[ xErrorTail ].arg,\r
135                         xErrorList[ xErrorTail ].Direction,\r
136                         xErrorList[ xErrorTail ].ErrorWord );\r
137         }\r
138 \r
139         return xResult;\r
140 }\r
141 \r
142 static void emacps_handle_error(void *arg, u8 Direction, u32 ErrorWord)\r
143 {\r
144         xemacpsif_s   *xemacpsif;\r
145         struct xtopology_t *xtopologyp;\r
146         XEmacPs *xemacps;\r
147 \r
148         xemacpsif = (xemacpsif_s *)(arg);\r
149 \r
150         xtopologyp = &xXTopology;\r
151 \r
152         xemacps = &xemacpsif->emacps;\r
153 \r
154         /* Do not appear to be used. */\r
155         ( void ) xemacps;\r
156         ( void ) xtopologyp;\r
157 \r
158         last_err_msg = NULL;\r
159 \r
160         if( ErrorWord != 0 )\r
161         {\r
162                 switch (Direction) {\r
163                 case XEMACPS_RECV:\r
164                         if( ( ErrorWord & XEMACPS_RXSR_HRESPNOK_MASK ) != 0 )\r
165                         {\r
166                                 last_err_msg = "Receive DMA error";\r
167                                 xNetworkInterfaceInitialise( );\r
168                         }\r
169                         if( ( ErrorWord & XEMACPS_RXSR_RXOVR_MASK ) != 0 )\r
170                         {\r
171                                 last_err_msg = "Receive over run";\r
172                                 emacps_recv_handler(arg);\r
173                         }\r
174                         if( ( ErrorWord & XEMACPS_RXSR_BUFFNA_MASK ) != 0 )\r
175                         {\r
176                                 last_err_msg = "Receive buffer not available";\r
177                                 emacps_recv_handler(arg);\r
178                         }\r
179                         break;\r
180                 case XEMACPS_SEND:\r
181                         if( ( ErrorWord & XEMACPS_TXSR_HRESPNOK_MASK ) != 0 )\r
182                         {\r
183                                 last_err_msg = "Transmit DMA error";\r
184                                 xNetworkInterfaceInitialise( );\r
185                         }\r
186                         if( ( ErrorWord & XEMACPS_TXSR_URUN_MASK ) != 0 )\r
187                         {\r
188                                 last_err_msg = "Transmit under run";\r
189                                 HandleTxErrors( xemacpsif );\r
190                         }\r
191                         if( ( ErrorWord & XEMACPS_TXSR_BUFEXH_MASK ) != 0 )\r
192                         {\r
193                                 last_err_msg = "Transmit buffer exhausted";\r
194                                 HandleTxErrors( xemacpsif );\r
195                         }\r
196                         if( ( ErrorWord & XEMACPS_TXSR_RXOVR_MASK ) != 0 )\r
197                         {\r
198                                 last_err_msg = "Transmit retry excessed limits";\r
199                                 HandleTxErrors( xemacpsif );\r
200                         }\r
201                         if( ( ErrorWord & XEMACPS_TXSR_FRAMERX_MASK ) != 0 )\r
202                         {\r
203                                 last_err_msg = "Transmit collision";\r
204                                 emacps_check_tx( xemacpsif );\r
205                         }\r
206                         break;\r
207                 }\r
208         }\r
209         // Break on this statement and inspect error_msg if you like\r
210         if( last_err_msg != NULL )\r
211         {\r
212                 error_msg_count++;\r
213                 FreeRTOS_printf( ( "emacps_handle_error: %s\n", last_err_msg ) );\r
214         }\r
215 }\r
216 \r
217 void HandleTxErrors(xemacpsif_s *xemacpsif)\r
218 {\r
219         u32 netctrlreg;\r
220 \r
221         //taskENTER_CRITICAL()\r
222         {\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
228 \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
235         }\r
236         //taskEXIT_CRITICAL( );\r
237 }\r