1 /**
2     *****************************************************************************
3     * @file     cmem7_eth.h
4     *
5     * @brief    CMEM7 ethernet header file
6     *
7     *
8     * @version  V1.0
9     * @date     3. September 2013
10     *
11     * @note
12     *
13     *****************************************************************************
14     * @attention
15     *
16     * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
17     * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
18     * TIME. AS A RESULT, CAPITAL-MICRO SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
19     * INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
20     * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
21     * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
22     *
23     * <h2><center>&copy; COPYRIGHT 2013 Capital-micro </center></h2>
24     *****************************************************************************
25     */
26 
27 #ifndef __CMEM7_ETH_H
28 #define __CMEM7_ETH_H
29 
30 #ifdef __cplusplus
31  extern "C" {
32 #endif
33 
34 #include "cmem7.h"
35 #include "cmem7_conf.h"
36 
37 /** @defgroup ETH_SPEED
38   * @{
39   */
40 #define ETH_SPEED_10M               0x0
41 #define ETH_SPEED_100M              0x1
42 #define ETH_SPEED_1000M             0x2
43 
44 #define IS_ETH_SPEED(SPEED)             (((SPEED) == ETH_SPEED_10M)  || \
45                                      ((SPEED) == ETH_SPEED_100M) || \
46                                                                          ((SPEED) == ETH_SPEED_1000M))
47 /**
48   * @}
49   */
50 
51 /** @defgroup ETH_DUPLEX
52   * @{
53   */
54 #define ETH_DUPLEX_HALF             0x0
55 #define ETH_DUPLEX_FULL             0x1
56 
57 #define IS_ETH_DUPLEX(DUPLEX)           (((DUPLEX) == ETH_DUPLEX_HALF) || \
58                                                                          ((DUPLEX) == ETH_DUPLEX_FULL))
59 /**
60   * @}
61   */
62 
63 /** @defgroup ETH_INT
64   * @{
65   */
66 #define ETH_INT_TX_COMPLETE_FRAME       0x0001
67 #define ETH_INT_TX_STOP             0x0002
68 #define ETH_INT_TX_BUF_UNAVAI       0x0004
69 #define ETH_INT_RX_OVERFLOW                 0x0010
70 #define ETH_INT_TX_UNDERFLOW                0x0020
71 #define ETH_INT_RX_COMPLETE_FRAME   0x0040
72 #define ETH_INT_RX_BUF_UNAVAI       0x0080
73 #define ETH_INT_RX_STOP             0x0100
74 #define ETH_INT_BUS_FATAL_ERROR     0x2000
75 #define ETH_INT_ALL                 (ETH_INT_TX_COMPLETE_FRAME | \
76                                      ETH_INT_TX_STOP           | \
77                                                                          ETH_INT_TX_BUF_UNAVAI     | \
78                                                                          ETH_INT_RX_OVERFLOW       | \
79                                                                          ETH_INT_TX_UNDERFLOW      | \
80                                                                          ETH_INT_RX_COMPLETE_FRAME | \
81                                                                          ETH_INT_RX_BUF_UNAVAI     | \
82                                                                          ETH_INT_RX_STOP           | \
83                                                                          ETH_INT_BUS_FATAL_ERROR)
84 
85 #define IS_ETH_INT(INT)             (((INT) != 0) && (((INT) & ~ETH_INT_ALL) == 0))
86 /**
87   * @}
88   */
89 /**
90   * @brief  EFUSE receive filter structure
91     */
92 typedef struct
93 {
94     BOOL ETH_BroadcastFilterEnable;   /*!< Broadcast is dropped or passed                                       */
95     BOOL ETH_OwnFilterEnable;           /*!< source address filter is on or off                                 */
96     BOOL ETH_SelfDrop;                          /*!< Only own address is dropped or passed                              */
97     BOOL ETH_SourceFilterEnable;        /*!< source address filter is on or off                                 */
98     BOOL ETH_SourceDrop;                      /*!< Only specific source address is dropped or passed    */
99     uint8_t ETH_SourceMacAddr[6];     /*!< Source MAC address                                   */
100 } ETH_FrameFilter;
101 
102 /**
103   * @brief  Ethernet initialization structure
104     */
105 typedef struct
106 {
107     BOOL ETH_LinkUp;                   /*!< If ETH is linked up and it can be retrieved from PHY */
108     uint8_t ETH_Speed;                 /*!< speed of ETH, refer as @ref ETH_SPEED                */
109     uint8_t ETH_Duplex;                /*!< duplex mode of ETH, refer as @ref ETH_DUPLEX                 */
110     BOOL ETH_RxEn;                     /*!< Rx enable                                            */
111     BOOL ETH_TxEn;                     /*!< Tx enable                                            */
112     BOOL ETH_ChecksumOffload;          /*!< Checksum offload enable                              */
113     BOOL ETH_JumboFrame;               /*!< Jumbo Frame Enable                                   */
114     uint8_t ETH_MacAddr[6];            /*!< MAC address                                          */
115     ETH_FrameFilter *ETH_Filter;       /*!< Received frame address filter, receive all if null   */
116 } ETH_InitTypeDef;
117 
118 /**
119   * @brief  Ethernet Tx descriptor structure
120     */
121 typedef struct {
122     union {
123     uint32_t  TX0;
124 
125         struct {
126             uint32_t                                :  1;
127             uint32_t UNDERFLOW_ERR  :  1;    /*!< [OUT] Underflow error                                                     */
128             uint32_t                                :  1;
129             uint32_t COLLISION_CNT  :  4;        /*!< [OUT] Collision count                                       */
130             uint32_t                                :  1;
131             uint32_t EX_COLLISION   :  1;        /*!< [OUT] Excessive collision error                         */
132             uint32_t LATE_COLLISION :  1;        /*!< [OUT] Late collision error                              */
133             uint32_t NO_CARRIER     :  1;        /*!< [OUT] No carrier error                                    */
134             uint32_t LOSS_CARRIER   :  1;        /*!< [OUT] loss of carrier error                           */
135             uint32_t PAYLOAD_ERR        :  1;        /*!< [OUT] IP payload error                                    */
136             uint32_t                                :  2;
137             uint32_t ERR_SUM                :  1;        /*!< [OUT] Error summary                                           */
138             uint32_t HEADER_ERR         :  1;        /*!< [OUT] IP header error                                         */
139             uint32_t                                :  8;
140             uint32_t TTSE           :  1;    /*!< enables IEEE1588 hardware timestamping in first segment */
141             uint32_t                                :  2;
142             uint32_t FS             :  1;    /*!< first segment flag                                    */
143             uint32_t LS             :  1;    /*!< last segment flag                                     */
144             uint32_t                                :  2;
145         } TX0_b;
146     } TX_0;
147 
148     union {
149     uint32_t  TX1;
150 
151         struct {
152             uint32_t SIZE                       : 13;       /*!< buffer size                                       */
153             uint32_t                : 19;
154         } TX1_b;
155     } TX_1;
156 
157     uint32_t bufAddr;                                           /*!< address of buffer                                           */
158     uint32_t nextDescAddr;                              /*!< address of next descriptor                          */
159   uint64_t reserved;
160     uint64_t timeStamp;                                     /*!< time stamp while last segment                     */
161 } ETH_TX_DESC;
162 
163 /**
164   * @brief  Ethernet Rx descriptor structure
165     */
166 typedef struct {
167     union {
168     uint32_t  RX0;
169 
170         struct {
171             uint32_t                                :  1;
172             uint32_t CRC_ERR        :  1;    /*!< [OUT] CRC error while last segment                        */
173             uint32_t                                :  5;
174             uint32_t TTSE           :  1;    /*!< timestamp available while last segment                */
175             uint32_t LS             :  1;    /*!< [OUT] last segment flag                               */
176             uint32_t FS             :  1;    /*!< [OUT] first segment flag                              */
177             uint32_t                                :  1;
178             uint32_t OVERFLOW_ERR   :  1;    /*!< [OUT] FIFO overflow while last segment                */
179             uint32_t LENGTH_ERR     :  1;    /*!< [OUT] length error while last segment                 */
180             uint32_t                                :  2;
181             uint32_t ERR_SUM        :  1;    /*!< [OUT] Error summary while last segment                */
182             uint32_t FL             : 14;    /*!< [OUT] frame length while last segment                 */
183             uint32_t                    :  2;
184         } RX0_b;
185     } RX_0;
186 
187     union {
188     uint32_t  RX1;
189 
190         struct {
191             uint32_t SIZE                       : 13;       /*!< buffer size                                       */
192             uint32_t                : 19;
193         } RX1_b;
194     } RX_1;
195 
196     uint32_t bufAddr;                                           /*!< buffer address                                    */
197     uint32_t nextDescAddr;                              /*!< address of next descriptor                        */
198   uint64_t reserved;
199     uint64_t timeStamp;                                     /*!< time stamp while the last segment                 */
200 } ETH_RX_DESC;
201 
202 /**
203   * @brief  Read data from phy chip
204     * @param[in] phyAddr Address of phy chip
205     * @param[in] phyReg Address of phy's register to be read
206   * @retval uint32_t value of phy's register
207     */
208 uint32_t ETH_PhyRead(uint32_t phyAddr, uint32_t phyReg);
209 
210 /**
211   * @brief  Write data to phy chip
212     * @param[in] phyAddr Address of phy chip
213     * @param[in] phyReg Address of phy's register to be written
214     * @param[in] data Data to be written
215   * @retval None
216     */
217 void ETH_PhyWrite(uint32_t phyAddr, uint32_t phyReg, uint32_t data);
218 /**
219   * @brief  Fills each ETH_InitStruct member with its default value.
220   * @param ETH_InitStruct: pointer to a ETH_InitTypeDef structure
221   *   which will be initialized.
222   * @retval : None
223   */
224 void ETH_StructInit(ETH_InitTypeDef* init);
225 /**
226   * @brief  Ethernet initialization
227   * @note   This function should be called at first before any other interfaces.
228     * @param[in] init A pointer to structure ETH_InitTypeDef
229   * @retval BOOL The bit indicates if ethernet is initialized successfully
230     */
231 BOOL ETH_Init(ETH_InitTypeDef *init);
232 
233 /**
234   * @brief  Enable or disable ethernet interrupt.
235     * @param[in] Int interrupt mask bits, which can be the combination of @ref ETH_INT
236     * @param[in] Enable The bit indicates if specific interrupts are enable or not
237   * @retval None
238     */
239 void ETH_ITConfig(uint32_t Int, BOOL enable);
240 
241 /**
242   * @brief  Check specific interrupts are set or not
243     * @param[in] Int interrupt mask bits, which can be the combination of @ref ETH_INT
244   * @retval BOOL The bit indicates if specific interrupts are set or not
245     */
246 BOOL ETH_GetITStatus(uint32_t Int);
247 
248 /**
249   * @brief  Clear specific interrupts
250     * @param[in] Int interrupt mask bits, which can be the combination of @ref ETH_INT
251   * @retval None
252     */
253 void ETH_ClearITPendingBit(uint32_t Int);
254 
255 /**
256   * @brief  Get ethernte MAC address
257     * @param[in] mac A user-allocated buffer to fetch MAC to be read, 6 bytes.
258     * @retval None
259     */
260 void ETH_GetMacAddr(uint8_t *mac);
261 
262 /**
263   * @brief  Set ethernet transmission descriptor ring
264     * @note     Make sure that memory occupied by descriptors should be in physical
265     *                   memory and keep valid before ethernet transmission is finished.
266     * @param[in] ring A pointer to header of ETH_TX_DESC ring, whose last node
267     *                   has a 'nextDescAddr' pointed to first node.
268   * @retval BOOL The bit indicates if valid ring is set
269     */
270 BOOL ETH_SetTxDescRing(ETH_TX_DESC *ring);
271 
272 /**
273   * @brief  Start ethernet transmission
274     * @param    None
275   * @retval None
276     */
277 void ETH_StartTx(void);
278 
279 /**
280   * @brief  Stop ethernet transmission
281     * @param    None
282   * @retval None
283     */
284 void ETH_StopTx(void);
285 
286 /**
287   * @brief  Resume ethernet transmission\n
288     *               While ethernet doesn't have enough buffer to transmit data, it will
289     *                   pause and inform users by interrupt 'ETH_INT_TX_BUF_UNAVAI'. Users
290     *                   must call this function to start ethernet again after new buffer
291     *                   prepared.
292     * @param    None
293   * @retval None
294     */
295 void ETH_ResumeTx(void);
296 
297 /**
298   * @brief  Get free transmission descriptor\n
299     * @param    None
300   * @retval ETH_TX_DESC* A pointer of free transmission descriptor,
301     *                   NULL if no free descriptor
302     */
303 ETH_TX_DESC *ETH_AcquireFreeTxDesc(void);
304 
305 /**
306   * @brief  Check if a transmission descriptor is free or not
307     * @param[in] desc A pointer of a transmission descriptor
308   * @retval BOOL True if the transmission descriptor is free, or flase.
309     */
310 BOOL ETH_IsFreeTxDesc(ETH_TX_DESC *desc);
311 
312 /**
313   * @brief  Release a transmission descriptor to ethernet\n
314     *                   After users prepared data in the buffer of a free descriptor,
315     *                   They must call this function to change ownership of the
316     *                   descriptor to hardware.
317     * @param[in] desc A pointer of a transmission descriptor
318   * @retval None
319     */
320 void ETH_ReleaseTxDesc(ETH_TX_DESC *desc);
321 
322 /**
323   * @brief  Set buffer address of the specific TX descriptor
324     * @param[in] desc A pointer of a transmission descriptor
325   * @param[in] bufAddr buffer address to be sent
326   * @retval None
327     */
328 void ETH_SetTxDescBufAddr(ETH_TX_DESC *desc, uint32_t bufAddr);
329 
330 /**
331   * @brief  Get buffer address of the specific TX descriptor
332     * @param[in] desc A pointer of a transmission descriptor
333   * @retval uint32_t buffer address to be gotten
334     */
335 uint32_t ETH_GetTxDescBufAddr(ETH_TX_DESC *desc);
336 
337 /**
338   * @brief  Set ethernet receive descriptor ring
339     * @note     Make sure that memory occupied by descriptors should be in physical
340     *                   memory and keep valid before ethernet receive is finished.
341     * @param[in] ring A pointer to header of ETH_TX_DESC ring, whose last node
342     *                   has a 'nextDescAddr' pointed to first node.
343   * @retval BOOL The bit indicates if valid ring is set
344     */
345 BOOL ETH_SetRxDescRing(ETH_RX_DESC *ring);
346 
347 /**
348   * @brief  Start ethernet receive
349     * @param    None
350   * @retval None
351     */
352 void ETH_StartRx(void);
353 
354 /**
355   * @brief  Stop ethernet receive
356     * @param    None
357   * @retval None
358     */
359 void ETH_StopRx(void);
360 
361 /**
362   * @brief  Resume ethernet receive\n
363     *               While ethernet doesn't have enough buffer to receive data, it will
364     *                   pause and inform users by interrupt 'ETH_INT_RX_BUF_UNAVAI'. Users
365     *                   must call this function to start ethernet again after new buffer
366     *                   prepared.
367     * @param    None
368   * @retval None
369     */
370 void ETH_ResumeRx(void);
371 
372 /**
373   * @brief  Get the free descriptor which contains received data\n
374     * @param    None
375   * @retval ETH_RX_DESC* A pointer of free receive descriptor,
376     *                   NULL if no free descriptor
377     */
378 ETH_RX_DESC *ETH_AcquireFreeRxDesc(void);
379 
380 /**
381   * @brief  Check if a receive descriptor is free or not
382     * @param[in] desc A pointer of a receive descriptor
383   * @retval BOOL True if the receive descriptor is free, or flase.
384     */
385 BOOL ETH_IsFreeRxDesc(ETH_RX_DESC *desc);
386 
387 /**
388   * @brief  Release a receive descriptor to ethernet\n
389     *                   After users handled data in the buffer of a free descriptor,
390     *                   They must call this function to change ownership of the
391     *                   descriptor to hardware.
392     * @param[in] desc A pointer of a transmission descriptor
393   * @retval None
394     */
395 void ETH_ReleaseRxDesc(ETH_RX_DESC *desc);
396 
397 /**
398   * @brief  Set buffer address of the specific RX descriptor
399     * @param[in] desc A pointer of a receive descriptor
400   * @param[in] bufAddr buffer address to be received
401   * @retval None
402     */
403 void ETH_SetRxDescBufAddr(ETH_RX_DESC *desc, uint32_t bufAddr);
404 
405 /**
406   * @brief  Get buffer address of the specific RX descriptor
407     * @param[in] desc A pointer of a receive descriptor
408   * @retval uint32_t buffer address to be gotten
409     */
410 uint32_t ETH_GetRxDescBufAddr(ETH_RX_DESC *desc);
411 
412 #ifdef __cplusplus
413 }
414 #endif
415 
416 #endif /* __CMEM7_ETH_H */
417 
418