summaryrefslogtreecommitdiff
path: root/bsp/nuvoton/libraries/nuc980/Driver/Include/nu_emac.h
blob: 5db55a6e71456ac511586528623e7d58ed9129ec (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
/**************************************************************************//**
 * @file     nu_emac.h
 * @version  V1.00
 * @brief    EMAC driver header file
 *
 * SPDX-License-Identifier: Apache-2.0
 * @copyright (C) 2016-2020 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#ifndef __NU_EMAC_H__
#define __NU_EMAC_H__

#ifdef __cplusplus
extern "C"
{
#endif

#include <stdint.h>
#include "emac_reg.h"

/** @addtogroup Standard_Driver Standard Driver
  @{
*/

/** @addtogroup EMAC_Driver EMAC Driver
  @{
*/

/** @addtogroup EMAC_EXPORTED_CONSTANTS EMAC Exported Constants
  @{
*/

#define EMAC_PHY_ADDR      1UL    /*!<  PHY address, this address is board dependent \hideinitializer */
#define EMAC_RX_DESC_SIZE  128UL  /*!<  Number of Rx Descriptors, should be 2 at least \hideinitializer */
#define EMAC_TX_DESC_SIZE  64UL   /*!<  Number of Tx Descriptors, should be 2 at least \hideinitializer */
#define EMAC_CAMENTRY_NB   16UL   /*!<  Number of CAM \hideinitializer */
#define EMAC_MAX_PKT_SIZE  1536UL /*!<  Number of HDR + EXTRA + VLAN_TAG + PAYLOAD + CRC \hideinitializer */

#define EMAC_LINK_DOWN    0UL    /*!<  Ethernet link is down \hideinitializer */
#define EMAC_LINK_100F    1UL    /*!<  Ethernet link is 100Mbps full duplex \hideinitializer */
#define EMAC_LINK_100H    2UL    /*!<  Ethernet link is 100Mbps half duplex \hideinitializer */
#define EMAC_LINK_10F     3UL    /*!<  Ethernet link is 10Mbps full duplex \hideinitializer */
#define EMAC_LINK_10H     4UL    /*!<  Ethernet link is 10Mbps half duplex \hideinitializer */

/*@}*/ /* end of group EMAC_EXPORTED_CONSTANTS */


/** Tx/Rx buffer descriptor structure */
typedef struct
{
    uint32_t u32Status1;   /*!<  Status word 1 */
    uint32_t u32Data;      /*!<  Pointer to data buffer */
    uint32_t u32Status2;   /*!<  Status word 2 */
    uint32_t u32Next;      /*!<  Pointer to next descriptor */
    uint32_t u32Backup1;   /*!<  For backup descriptor fields over written by time stamp */
    uint32_t u32Backup2;   /*!<  For backup descriptor fields over written by time stamp */
    uint32_t u32Reserved1; /*!<  For Reserved */
    uint32_t u32Reserved2; /*!<  For Reserved */
} EMAC_DESCRIPTOR_T;

/** Tx/Rx buffer structure */
typedef struct
{
    uint8_t au8Buf[EMAC_MAX_PKT_SIZE];
} EMAC_FRAME_T;

typedef struct
{
    EMAC_T  *psEmac;

    uint32_t u32TxDescSize;
    uint32_t u32RxDescSize;

    EMAC_DESCRIPTOR_T *psRXDescs;
    EMAC_FRAME_T *psRXFrames;
    EMAC_DESCRIPTOR_T *psTXDescs;
    EMAC_FRAME_T *psTXFrames;

    EMAC_DESCRIPTOR_T *psCurrentTxDesc;
    EMAC_DESCRIPTOR_T *psNextTxDesc;
    EMAC_DESCRIPTOR_T *psCurrentRxDesc;

} EMAC_MEMMGR_T;

/** @addtogroup EMAC_EXPORTED_FUNCTIONS EMAC Exported Functions
  @{
*/


/**
  * @brief  Enable EMAC Tx function
  * @param  None
  * @return None
  * \hideinitializer
  */
#define EMAC_ENABLE_TX(EMAC) (EMAC->CTL |= EMAC_CTL_TXON_Msk)


/**
  * @brief  Enable EMAC Rx function
  * @param  The pointer of the specified EMAC module
  * @return None
  * \hideinitializer
  */
#define EMAC_ENABLE_RX(EMAC) do{EMAC->CTL |= EMAC_CTL_RXON_Msk; EMAC->RXST = 0;}while(0)

/**
  * @brief  Disable EMAC Tx function
  * @param  The pointer of the specified EMAC module
  * @return None
  * \hideinitializer
  */
#define EMAC_DISABLE_TX(EMAC) (EMAC->CTL &= ~EMAC_CTL_TXON_Msk)


/**
  * @brief  Disable EMAC Rx function
  * @param  The pointer of the specified EMAC module
  * @return None
  * \hideinitializer
  */
#define EMAC_DISABLE_RX(EMAC) (EMAC->CTL &= ~EMAC_CTL_RXON_Msk)

/**
  * @brief  Enable EMAC Magic Packet Wakeup function
  * @param  The pointer of the specified EMAC module
  * @return None
  * \hideinitializer
  */
#define EMAC_ENABLE_MAGIC_PKT_WAKEUP(EMAC) (EMAC->CTL |= EMAC_CTL_WOLEN_Msk)

/**
  * @brief  Disable EMAC Magic Packet Wakeup function
  * @param  The pointer of the specified EMAC module
  * @return None
  * \hideinitializer
  */
#define EMAC_DISABLE_MAGIC_PKT_WAKEUP(EMAC) (EMAC->CTL &= ~EMAC_CTL_WOLEN_Msk)

/**
  * @brief  Enable EMAC to receive broadcast packets
  * @param  The pointer of the specified EMAC module
  * @return None
  * \hideinitializer
  */
#define EMAC_ENABLE_RECV_BCASTPKT(EMAC) (EMAC->CAMCTL |= EMAC_CAMCTL_ABP_Msk)

/**
  * @brief  Disable EMAC to receive broadcast packets
  * @param  The pointer of the specified EMAC module
  * @return None
  * \hideinitializer
  */
#define EMAC_DISABLE_RECV_BCASTPKT(EMAC) (EMAC->CAMCTL &= ~EMAC_CAMCTL_ABP_Msk)

/**
  * @brief  Enable EMAC to receive multicast packets
  * @param  The pointer of the specified EMAC module
  * @return None
  * \hideinitializer
  */
#define EMAC_ENABLE_RECV_MCASTPKT(EMAC) (EMAC->CAMCTL |= EMAC_CAMCTL_AMP_Msk)

/**
  * @brief  Disable EMAC Magic Packet Wakeup function
  * @param  The pointer of the specified EMAC module
  * @return None
  * \hideinitializer
  */
#define EMAC_DISABLE_RECV_MCASTPKT(EMAC) (EMAC->CAMCTL &= ~EMAC_CAMCTL_AMP_Msk)

/**
  * @brief  Check if EMAC time stamp alarm interrupt occurred or not
  * @param  The pointer of the specified EMAC module
  * @return If time stamp alarm interrupt occurred or not
  * @retval 0 Alarm interrupt does not occur
  * @retval 1 Alarm interrupt occurred
  * \hideinitializer
  */
#define EMAC_GET_ALARM_FLAG(EMAC) (EMAC->INTSTS & EMAC_INTSTS_TSALMIF_Msk ? 1 : 0)

/**
  * @brief  Clear EMAC time stamp alarm interrupt flag
  * @param  The pointer of the specified EMAC module
  * @return None
  * \hideinitializer
  */
#define EMAC_CLR_ALARM_FLAG(EMAC) (EMAC->INTSTS = EMAC_INTSTS_TSALMIF_Msk)

/**
  * @brief  Trigger EMAC Rx function
  * @param  The pointer of the specified EMAC module
  * @return None
  */
#define EMAC_TRIGGER_RX(EMAC) do{EMAC->RXST = 0UL;}while(0)

/**
  * @brief  Trigger EMAC Tx function
  * @param  The pointer of the specified EMAC module
  * @return None
  */
#define EMAC_TRIGGER_TX(EMAC) do{EMAC->TXST = 0UL;}while(0)

/**
 *    @brief        Enable specified EMAC interrupt
 *
 *    @param[in]    EMAC        The pointer of the specified EMAC module
 *    @param[in]    u32eIntSel  Interrupt type select
 *                              - \ref EMAC_INTEN_RXIEN_Msk    : Receive
 *                              - \ref EMAC_INTEN_CRCEIEN_Msk  : CRC Error
 *                              - \ref EMAC_INTEN_RXOVIEN_Msk  : Receive FIFO Overflow
 *                              - \ref EMAC_INTEN_LPIEN_Msk    : Long Packet
 *                              - \ref EMAC_INTEN_RXGDIEN_Msk  : Receive Good
 *                              - \ref EMAC_INTEN_ALIEIEN_Msk  : Alignment Error
 *                              - \ref EMAC_INTEN_RPIEN_Msk    : Runt Packet
 *                              - \ref EMAC_INTEN_MPCOVIEN_Msk : Miss Packet Counter Overrun
 *                              - \ref EMAC_INTEN_MFLEIEN_Msk  : Maximum Frame Length Exceed
 *                              - \ref EMAC_INTEN_DENIEN_Msk   : DMA Early Notification
 *                              - \ref EMAC_INTEN_RDUIEN_Msk   : Receive Descriptor Unavailable
 *                              - \ref EMAC_INTEN_RXBEIEN_Msk  : Receive Bus Error
 *                              - \ref EMAC_INTEN_CFRIEN_Msk   : Control Frame Receive
 *                              - \ref EMAC_INTEN_WOLIEN_Msk   : Wake on LAN Interrupt
 *                              - \ref EMAC_INTEN_TXIEN_Msk    : Transmit
 *                              - \ref EMAC_INTEN_TXUDIEN_Msk  : Transmit FIFO Underflow
 *                              - \ref EMAC_INTEN_TXCPIEN_Msk  : Transmit Completion
 *                              - \ref EMAC_INTEN_EXDEFIEN_Msk : Defer Exceed
 *                              - \ref EMAC_INTEN_NCSIEN_Msk   : No Carrier Sense
 *                              - \ref EMAC_INTEN_TXABTIEN_Msk : Transmit Abort
 *                              - \ref EMAC_INTEN_LCIEN_Msk    : Late Collision
 *                              - \ref EMAC_INTEN_TDUIEN_Msk   : Transmit Descriptor Unavailable
 *                              - \ref EMAC_INTEN_TXBEIEN_Msk  : Transmit Bus Error
 *                              - \ref EMAC_INTEN_TSALMIEN_Msk : Time Stamp Alarm
 *
 *    @return       None
 *
 *    @details      This macro enable specified EMAC interrupt.
 *    \hideinitializer
 */
#define EMAC_ENABLE_INT(EMAC, u32eIntSel)    ((EMAC)->INTEN |= (u32eIntSel))

/**
 *    @brief        Disable specified EMAC interrupt
 *
 *    @param[in]    emac        The pointer of the specified EMAC module
 *    @param[in]    u32eIntSel  Interrupt type select
 *                              - \ref EMAC_INTEN_RXIEN_Msk    : Receive
 *                              - \ref EMAC_INTEN_CRCEIEN_Msk  : CRC Error
 *                              - \ref EMAC_INTEN_RXOVIEN_Msk  : Receive FIFO Overflow
 *                              - \ref EMAC_INTEN_LPIEN_Msk    : Long Packet
 *                              - \ref EMAC_INTEN_RXGDIEN_Msk  : Receive Good
 *                              - \ref EMAC_INTEN_ALIEIEN_Msk  : Alignment Error
 *                              - \ref EMAC_INTEN_RPIEN_Msk    : Runt Packet
 *                              - \ref EMAC_INTEN_MPCOVIEN_Msk : Miss Packet Counter Overrun
 *                              - \ref EMAC_INTEN_MFLEIEN_Msk  : Maximum Frame Length Exceed
 *                              - \ref EMAC_INTEN_DENIEN_Msk   : DMA Early Notification
 *                              - \ref EMAC_INTEN_RDUIEN_Msk   : Receive Descriptor Unavailable
 *                              - \ref EMAC_INTEN_RXBEIEN_Msk  : Receive Bus Error
 *                              - \ref EMAC_INTEN_CFRIEN_Msk   : Control Frame Receive
 *                              - \ref EMAC_INTEN_WOLIEN_Msk   : Wake on LAN Interrupt
 *                              - \ref EMAC_INTEN_TXIEN_Msk    : Transmit
 *                              - \ref EMAC_INTEN_TXUDIEN_Msk  : Transmit FIFO Underflow
 *                              - \ref EMAC_INTEN_TXCPIEN_Msk  : Transmit Completion
 *                              - \ref EMAC_INTEN_EXDEFIEN_Msk : Defer Exceed
 *                              - \ref EMAC_INTEN_NCSIEN_Msk   : No Carrier Sense
 *                              - \ref EMAC_INTEN_TXABTIEN_Msk : Transmit Abort
 *                              - \ref EMAC_INTEN_LCIEN_Msk    : Late Collision
 *                              - \ref EMAC_INTEN_TDUIEN_Msk   : Transmit Descriptor Unavailable
 *                              - \ref EMAC_INTEN_TXBEIEN_Msk  : Transmit Bus Error
 *                              - \ref EMAC_INTEN_TSALMIEN_Msk : Time Stamp Alarm
 *
 *    @return       None
 *
 *    @details      This macro disable specified EMAC interrupt.
 *    \hideinitializer
 */
#define EMAC_DISABLE_INT(EMAC, u32eIntSel)    ((EMAC)->INTEN &= ~ (u32eIntSel))

/**
 *    @brief        Get specified interrupt flag/status
 *
 *    @param[in]    emac            The pointer of the specified EMAC module
 *    @param[in]    u32eIntTypeFlag Interrupt Type Flag, should be
 *                                  - \ref EMAC_INTSTS_RXIF_Msk : Receive
 *                                  - \ref EMAC_INTSTS_CRCEIF_Msk : CRC Error
 *                                  - \ref EMAC_INTSTS_RXOVIF_Msk : Receive FIFO Overflow
 *                                  - \ref EMAC_INTSTS_LPIF_Msk : Long Packet
 *                                  - \ref EMAC_INTSTS_RXGDIF_Msk : Receive Good
 *                                  - \ref EMAC_INTSTS_ALIEIF_Msk : Alignment Error
 *                                  - \ref EMAC_INTSTS_RPIF_Msk : Runt Packet
 *                                  - \ref EMAC_INTSTS_MPCOVIF_Msk : Missed Packet Counter
 *                                  - \ref EMAC_INTSTS_MFLEIF_Msk : Maximum Frame Length Exceed
 *                                  - \ref EMAC_INTSTS_DENIF_Msk : DMA Early Notification
 *                                  - \ref EMAC_INTSTS_RDUIF_Msk : Receive Descriptor Unavailable
 *                                  - \ref EMAC_INTSTS_RXBEIF_Msk : Receive Bus Error
 *                                  - \ref EMAC_INTSTS_CFRIF_Msk : Control Frame Receive
 *                                  - \ref EMAC_INTSTS_WOLIF_Msk : Wake on LAN
 *                                  - \ref EMAC_INTSTS_TXIF_Msk : Transmit
 *                                  - \ref EMAC_INTSTS_TXUDIF_Msk : Transmit FIFO Underflow
 *                                  - \ref EMAC_INTSTS_TXCPIF_Msk : Transmit Completion
 *                                  - \ref EMAC_INTSTS_EXDEFIF_Msk : Defer Exceed
 *                                  - \ref EMAC_INTSTS_NCSIF_Msk : No Carrier Sense
 *                                  - \ref EMAC_INTSTS_TXABTIF_Msk : Transmit Abort
 *                                  - \ref EMAC_INTSTS_LCIF_Msk : Late Collision
 *                                  - \ref EMAC_INTSTS_TDUIF_Msk : Transmit Descriptor Unavailable
 *                                  - \ref EMAC_INTSTS_TXBEIF_Msk : Transmit Bus Error
 *                                  - \ref EMAC_INTSTS_TSALMIF_Msk : Time Stamp Alarm
 *
 *    @return       None
 *
 *    @details      This macro get specified interrupt flag or interrupt indicator status.
 *    \hideinitializer
 */
#define EMAC_GET_INT_FLAG(EMAC, u32eIntTypeFlag)    (((EMAC)->INTSTS & (u32eIntTypeFlag))?1:0)

/**
 *    @brief        Clear specified interrupt flag/status
 *
 *    @param[in]    emac            The pointer of the specified EMAC module
 *    @param[in]    u32eIntTypeFlag Interrupt Type Flag, should be
 *                                  - \ref EMAC_INTSTS_RXIF_Msk : Receive
 *                                  - \ref EMAC_INTSTS_CRCEIF_Msk : CRC Error
 *                                  - \ref EMAC_INTSTS_RXOVIF_Msk : Receive FIFO Overflow
 *                                  - \ref EMAC_INTSTS_LPIF_Msk : Long Packet
 *                                  - \ref EMAC_INTSTS_RXGDIF_Msk : Receive Good
 *                                  - \ref EMAC_INTSTS_ALIEIF_Msk : Alignment Error
 *                                  - \ref EMAC_INTSTS_RPIF_Msk : Runt Packet
 *                                  - \ref EMAC_INTSTS_MPCOVIF_Msk : Missed Packet Counter
 *                                  - \ref EMAC_INTSTS_MFLEIF_Msk : Maximum Frame Length Exceed
 *                                  - \ref EMAC_INTSTS_DENIF_Msk : DMA Early Notification
 *                                  - \ref EMAC_INTSTS_RDUIF_Msk : Receive Descriptor Unavailable
 *                                  - \ref EMAC_INTSTS_RXBEIF_Msk : Receive Bus Error
 *                                  - \ref EMAC_INTSTS_CFRIF_Msk : Control Frame Receive
 *                                  - \ref EMAC_INTSTS_WOLIF_Msk : Wake on LAN
 *                                  - \ref EMAC_INTSTS_TXIF_Msk : Transmit
 *                                  - \ref EMAC_INTSTS_TXUDIF_Msk : Transmit FIFO Underflow
 *                                  - \ref EMAC_INTSTS_TXCPIF_Msk : Transmit Completion
 *                                  - \ref EMAC_INTSTS_EXDEFIF_Msk : Defer Exceed
 *                                  - \ref EMAC_INTSTS_NCSIF_Msk : No Carrier Sense
 *                                  - \ref EMAC_INTSTS_TXABTIF_Msk : Transmit Abort
 *                                  - \ref EMAC_INTSTS_LCIF_Msk : Late Collision
 *                                  - \ref EMAC_INTSTS_TDUIF_Msk : Transmit Descriptor Unavailable
 *                                  - \ref EMAC_INTSTS_TXBEIF_Msk : Transmit Bus Error
 *                                  - \ref EMAC_INTSTS_TSALMIF_Msk : Time Stamp Alarm
 *
 *    @retval       0 The specified interrupt is not happened.
 *                  1 The specified interrupt is happened.
 *
 *    @details      This macro clear specified interrupt flag or interrupt indicator status.
 *    \hideinitializer
 */
#define EMAC_CLEAR_INT_FLAG(EMAC, u32eIntTypeFlag)    ((EMAC)->INTSTS |= (u32eIntTypeFlag))
#define EMAC_CLEAR_ALL_INT_FLAG(EMAC)                 ((EMAC)->INTSTS |= (EMAC)->INTSTS)


void EMAC_Open(EMAC_MEMMGR_T *psMemMgr, uint8_t *pu8MacAddr);
void EMAC_Close(EMAC_T *EMAC);
void EMAC_SetMacAddr(EMAC_T *EMAC, uint8_t *pu8MacAddr);
void EMAC_EnableCamEntry(EMAC_T *EMAC, uint32_t u32Entry, uint8_t pu8MacAddr[]);
void EMAC_DisableCamEntry(EMAC_T *EMAC, uint32_t u32Entry);

uint32_t EMAC_RecvPkt(EMAC_MEMMGR_T *psMemMgr, uint8_t *pu8Data, uint32_t *pu32Size);
uint32_t EMAC_RecvPktTS(EMAC_MEMMGR_T *psMemMgr, uint8_t *pu8Data, uint32_t *pu32Size, uint32_t *pu32Sec, uint32_t *pu32Nsec);
void EMAC_RecvPktDone(EMAC_MEMMGR_T *psMemMgr);

uint32_t EMAC_SendPkt(EMAC_MEMMGR_T *psMemMgr, uint8_t *pu8Data, uint32_t u32Size);
uint32_t EMAC_SendPktDone(EMAC_MEMMGR_T *psMemMgr);
uint32_t EMAC_SendPktDoneTS(EMAC_MEMMGR_T *psMemMgr, uint32_t *pu32Sec, uint32_t *pu32Nsec);

void EMAC_EnableTS(EMAC_T *EMAC, uint32_t u32Sec, uint32_t u32Nsec);
void EMAC_DisableTS(EMAC_T *EMAC);
void EMAC_GetTime(EMAC_T *EMAC, uint32_t *pu32Sec, uint32_t *pu32Nsec);
void EMAC_SetTime(EMAC_T *EMAC, uint32_t u32Sec, uint32_t u32Nsec);
void EMAC_UpdateTime(EMAC_T *EMAC, uint32_t u32Neg, uint32_t u32Sec, uint32_t u32Nsec);
void EMAC_EnableAlarm(EMAC_T *EMAC, uint32_t u32Sec, uint32_t u32Nsec);
void EMAC_DisableAlarm(EMAC_T *EMAC);

uint32_t EMAC_CheckLinkStatus(EMAC_T *EMAC);

void EMAC_Reset(EMAC_T *EMAC);
void EMAC_PhyInit(EMAC_T *EMAC);
int32_t EMAC_FillCamEntry(EMAC_T *EMAC, uint8_t pu8MacAddr[]);
uint8_t *EMAC_ClaimFreeTXBuf(EMAC_MEMMGR_T *psMemMgr);
uint32_t EMAC_GetAvailRXBufSize(EMAC_MEMMGR_T *psMemMgr, uint8_t **ppuDataBuf);
uint32_t EMAC_SendPktWoCopy(EMAC_MEMMGR_T *psMemMgr, uint32_t u32Size);
EMAC_DESCRIPTOR_T * EMAC_RecvPktDoneWoRxTrigger(EMAC_MEMMGR_T *psMemMgr);
void EMAC_RxTrigger(EMAC_MEMMGR_T *psMemMgr, EMAC_DESCRIPTOR_T * rx_desc);

/*@}*/ /* end of group EMAC_EXPORTED_FUNCTIONS */

/*@}*/ /* end of group EMAC_Driver */

/*@}*/ /* end of group Standard_Driver */

#ifdef __cplusplus
}
#endif

#endif /* __NU_EMAC_H__ */

/*** (C) COPYRIGHT 2016 Nuvoton Technology Corp. ***/