383 lines
13 KiB
C
383 lines
13 KiB
C
|
/**
|
||
|
*****************************************************************************
|
||
|
* @file cmem7_eth.h
|
||
|
*
|
||
|
* @brief CMEM7 ethernet header file
|
||
|
*
|
||
|
*
|
||
|
* @version V1.0
|
||
|
* @date 3. September 2013
|
||
|
*
|
||
|
* @note
|
||
|
*
|
||
|
*****************************************************************************
|
||
|
* @attention
|
||
|
*
|
||
|
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
|
||
|
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
|
||
|
* TIME. AS A RESULT, CAPITAL-MICRO SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
|
||
|
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
|
||
|
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
|
||
|
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
|
||
|
*
|
||
|
* <h2><center>© COPYRIGHT 2013 Capital-micro </center></h2>
|
||
|
*****************************************************************************
|
||
|
*/
|
||
|
|
||
|
#ifndef __CMEM7_ETH_H
|
||
|
#define __CMEM7_ETH_H
|
||
|
|
||
|
#ifdef __cplusplus
|
||
|
extern "C" {
|
||
|
#endif
|
||
|
|
||
|
#include "cmem7.h"
|
||
|
#include "cmem7_conf.h"
|
||
|
|
||
|
/** @defgroup ETH_SPEED
|
||
|
* @{
|
||
|
*/
|
||
|
#define ETH_SPEED_10M 0x0
|
||
|
#define ETH_SPEED_100M 0x1
|
||
|
#define ETH_SPEED_1000M 0x2
|
||
|
|
||
|
#define IS_ETH_SPEED(SPEED) (((SPEED) == ETH_SPEED_10M) || \
|
||
|
((SPEED) == ETH_SPEED_100M) || \
|
||
|
((SPEED) == ETH_SPEED_1000M))
|
||
|
/**
|
||
|
* @}
|
||
|
*/
|
||
|
|
||
|
/** @defgroup ETH_DUPLEX
|
||
|
* @{
|
||
|
*/
|
||
|
#define ETH_DUPLEX_HALF 0x0
|
||
|
#define ETH_DUPLEX_FULL 0x1
|
||
|
|
||
|
#define IS_ETH_DUPLEX(DUPLEX) (((DUPLEX) == ETH_DUPLEX_HALF) || \
|
||
|
((DUPLEX) == ETH_DUPLEX_FULL))
|
||
|
/**
|
||
|
* @}
|
||
|
*/
|
||
|
|
||
|
/** @defgroup ETH_INT
|
||
|
* @{
|
||
|
*/
|
||
|
#define ETH_INT_TX_COMPLETE_FRAME 0x0001
|
||
|
#define ETH_INT_TX_STOP 0x0002
|
||
|
#define ETH_INT_TX_BUF_UNAVAI 0x0004
|
||
|
#define ETH_INT_RX_OVERFLOW 0x0010
|
||
|
#define ETH_INT_TX_UNDERFLOW 0x0020
|
||
|
#define ETH_INT_RX_COMPLETE_FRAME 0x0040
|
||
|
#define ETH_INT_RX_BUF_UNAVAI 0x0080
|
||
|
#define ETH_INT_RX_STOP 0x0100
|
||
|
#define ETH_INT_BUS_FATAL_ERROR 0x2000
|
||
|
#define ETH_INT_ALL (ETH_INT_TX_COMPLETE_FRAME | \
|
||
|
ETH_INT_TX_STOP | \
|
||
|
ETH_INT_TX_BUF_UNAVAI | \
|
||
|
ETH_INT_RX_OVERFLOW | \
|
||
|
ETH_INT_TX_UNDERFLOW | \
|
||
|
ETH_INT_RX_COMPLETE_FRAME | \
|
||
|
ETH_INT_RX_BUF_UNAVAI | \
|
||
|
ETH_INT_RX_STOP | \
|
||
|
ETH_INT_BUS_FATAL_ERROR)
|
||
|
|
||
|
#define IS_ETH_INT(INT) (((INT) != 0) && (((INT) & ~ETH_INT_ALL) == 0))
|
||
|
/**
|
||
|
* @}
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @brief EFUSE receive filter structure
|
||
|
*/
|
||
|
typedef struct
|
||
|
{
|
||
|
BOOL ETH_BroadcastFilterEnable; /*!< Broadcast is dropped or passed */
|
||
|
BOOL ETH_OwnFilterEnable; /*!< source address filter is on or off */
|
||
|
BOOL ETH_SelfDrop; /*!< Only own address is dropped or passed */
|
||
|
BOOL ETH_SourceFilterEnable; /*!< source address filter is on or off */
|
||
|
BOOL ETH_SourceDrop; /*!< Only specific source address is dropped or passed */
|
||
|
uint8_t ETH_SourceMacAddr[6]; /*!< Source MAC address */
|
||
|
} ETH_FrameFilter;
|
||
|
|
||
|
/**
|
||
|
* @brief Ethernet initialization structure
|
||
|
*/
|
||
|
typedef struct
|
||
|
{
|
||
|
BOOL ETH_LinkUp; /*!< If ETH is linked up and it can be retrieved from PHY */
|
||
|
uint8_t ETH_Speed; /*!< speed of ETH, refer as @ref ETH_SPEED */
|
||
|
uint8_t ETH_Duplex; /*!< duplex mode of ETH, refer as @ref ETH_DUPLEX */
|
||
|
BOOL ETH_RxEn; /*!< Rx enable */
|
||
|
BOOL ETH_TxEn; /*!< Tx enable */
|
||
|
BOOL ETH_ChecksumOffload; /*!< Checksum offload enable */
|
||
|
BOOL ETH_JumboFrame; /*!< Jumbo Frame Enable */
|
||
|
uint8_t ETH_MacAddr[6]; /*!< MAC address */
|
||
|
ETH_FrameFilter *ETH_Filter; /*!< Received frame address filter, receive all if null */
|
||
|
} ETH_InitTypeDef;
|
||
|
|
||
|
/**
|
||
|
* @brief Ethernet Tx descriptor structure
|
||
|
*/
|
||
|
typedef struct {
|
||
|
union {
|
||
|
uint32_t TX0;
|
||
|
|
||
|
struct {
|
||
|
uint32_t : 1;
|
||
|
uint32_t UNDERFLOW_ERR : 1; /*!< [OUT] Underflow error */
|
||
|
uint32_t : 1;
|
||
|
uint32_t COLLISION_CNT : 4; /*!< [OUT] Collision count */
|
||
|
uint32_t : 1;
|
||
|
uint32_t EX_COLLISION : 1; /*!< [OUT] Excessive collision error */
|
||
|
uint32_t LATE_COLLISION : 1; /*!< [OUT] Late collision error */
|
||
|
uint32_t NO_CARRIER : 1; /*!< [OUT] No carrier error */
|
||
|
uint32_t LOSS_CARRIER : 1; /*!< [OUT] loss of carrier error */
|
||
|
uint32_t PAYLOAD_ERR : 1; /*!< [OUT] IP payload error */
|
||
|
uint32_t : 2;
|
||
|
uint32_t ERR_SUM : 1; /*!< [OUT] Error summary */
|
||
|
uint32_t HEADER_ERR : 1; /*!< [OUT] IP header error */
|
||
|
uint32_t : 8;
|
||
|
uint32_t TTSE : 1; /*!< enables IEEE1588 hardware timestamping in first segment */
|
||
|
uint32_t : 2;
|
||
|
uint32_t FS : 1; /*!< first segment flag */
|
||
|
uint32_t LS : 1; /*!< last segment flag */
|
||
|
uint32_t : 2;
|
||
|
} TX0_b;
|
||
|
} TX_0;
|
||
|
|
||
|
union {
|
||
|
uint32_t TX1;
|
||
|
|
||
|
struct {
|
||
|
uint32_t SIZE : 13; /*!< buffer size */
|
||
|
uint32_t : 19;
|
||
|
} TX1_b;
|
||
|
} TX_1;
|
||
|
|
||
|
uint32_t bufAddr; /*!< address of buffer */
|
||
|
uint32_t nextDescAddr; /*!< address of next descriptor */
|
||
|
uint64_t reserved;
|
||
|
uint64_t timeStamp; /*!< time stamp while last segment */
|
||
|
} ETH_TX_DESC;
|
||
|
|
||
|
/**
|
||
|
* @brief Ethernet Rx descriptor structure
|
||
|
*/
|
||
|
typedef struct {
|
||
|
union {
|
||
|
uint32_t RX0;
|
||
|
|
||
|
struct {
|
||
|
uint32_t : 1;
|
||
|
uint32_t CRC_ERR : 1; /*!< [OUT] CRC error while last segment */
|
||
|
uint32_t : 5;
|
||
|
uint32_t TTSE : 1; /*!< timestamp available while last segment */
|
||
|
uint32_t LS : 1; /*!< last segment flag */
|
||
|
uint32_t FS : 1; /*!< first segment flag */
|
||
|
uint32_t : 1;
|
||
|
uint32_t OVERFLOW_ERR : 1; /*!< [OUT] FIFO overflow while last segment */
|
||
|
uint32_t LENGTH_ERR : 1; /*!< [OUT] length error while last segment */
|
||
|
uint32_t : 2;
|
||
|
uint32_t ERR_SUM : 1; /*!< [OUT] Error summary while last segment */
|
||
|
uint32_t FL : 14; /*!< frame length while last segment */
|
||
|
uint32_t : 2;
|
||
|
} RX0_b;
|
||
|
} RX_0;
|
||
|
|
||
|
union {
|
||
|
uint32_t RX1;
|
||
|
|
||
|
struct {
|
||
|
uint32_t SIZE : 13; /*!< buffer size */
|
||
|
uint32_t : 19;
|
||
|
} RX1_b;
|
||
|
} RX_1;
|
||
|
|
||
|
uint32_t bufAddr; /*!< buffer address */
|
||
|
uint32_t nextDescAddr; /*!< address of next descriptor */
|
||
|
uint64_t reserved;
|
||
|
uint64_t timeStamp; /*!< time stamp while the last segment */
|
||
|
} ETH_RX_DESC;
|
||
|
|
||
|
/**
|
||
|
* @brief Read data from phy chip
|
||
|
* @param[in] phyAddr Address of phy chip
|
||
|
* @param[in] phyReg Address of phy's register to be read
|
||
|
* @retval uint32_t value of phy's register
|
||
|
*/
|
||
|
uint32_t ETH_PhyRead(uint32_t phyAddr, uint32_t phyReg);
|
||
|
|
||
|
/**
|
||
|
* @brief Write data to phy chip
|
||
|
* @param[in] phyAddr Address of phy chip
|
||
|
* @param[in] phyReg Address of phy's register to be written
|
||
|
* @param[in] data Data to be written
|
||
|
* @retval None
|
||
|
*/
|
||
|
void ETH_PhyWrite(uint32_t phyAddr, uint32_t phyReg, uint32_t data);
|
||
|
|
||
|
/**
|
||
|
* @brief Ethernet initialization
|
||
|
* @note This function should be called at first before any other interfaces.
|
||
|
* @param[in] init A pointer to structure ETH_InitTypeDef
|
||
|
* @retval BOOL The bit indicates if ethernet is initialized successfully
|
||
|
*/
|
||
|
BOOL ETH_Init(ETH_InitTypeDef *init);
|
||
|
|
||
|
/**
|
||
|
* @brief Enable or disable ethernet interrupt.
|
||
|
* @param[in] Int interrupt mask bits, which can be the combination of @ref ETH_INT
|
||
|
* @param[in] Enable The bit indicates if specific interrupts are enable or not
|
||
|
* @retval None
|
||
|
*/
|
||
|
void ETH_EnableInt(uint32_t Int, BOOL enable);
|
||
|
|
||
|
/**
|
||
|
* @brief Check specific interrupts are set or not
|
||
|
* @param[in] Int interrupt mask bits, which can be the combination of @ref ETH_INT
|
||
|
* @retval BOOL The bit indicates if specific interrupts are set or not
|
||
|
*/
|
||
|
BOOL ETH_GetIntStatus(uint32_t Int);
|
||
|
|
||
|
/**
|
||
|
* @brief Clear specific interrupts
|
||
|
* @param[in] Int interrupt mask bits, which can be the combination of @ref ETH_INT
|
||
|
* @retval None
|
||
|
*/
|
||
|
void ETH_ClearInt(uint32_t Int);
|
||
|
|
||
|
/**
|
||
|
* @brief Get ethernte MAC address
|
||
|
* @param[in] mac A user-allocated buffer to fetch MAC to be read, 6 bytes.
|
||
|
* @retval None
|
||
|
*/
|
||
|
void ETH_GetMacAddr(uint8_t *mac);
|
||
|
|
||
|
/**
|
||
|
* @brief Set ethernet transmission descriptor ring
|
||
|
* @note Make sure that memory occupied by descriptors should be in physical
|
||
|
* memory and keep valid before ethernet transmission is finished.
|
||
|
* @param[in] ring A pointer to header of ETH_TX_DESC ring, whose last node
|
||
|
* has a 'nextDescAddr' pointed to first node.
|
||
|
* @retval BOOL The bit indicates if valid ring is set
|
||
|
*/
|
||
|
BOOL ETH_SetTxDescRing(ETH_TX_DESC *ring);
|
||
|
|
||
|
/**
|
||
|
* @brief Start ethernet transmission
|
||
|
* @param None
|
||
|
* @retval None
|
||
|
*/
|
||
|
void ETH_StartTx(void);
|
||
|
|
||
|
/**
|
||
|
* @brief Stop ethernet transmission
|
||
|
* @param None
|
||
|
* @retval None
|
||
|
*/
|
||
|
void ETH_StopTx(void);
|
||
|
|
||
|
/**
|
||
|
* @brief Resume ethernet transmission\n
|
||
|
* While ethernet doesn't have enough buffer to transmit data, it will
|
||
|
* pause and inform users by interrupt 'ETH_INT_TX_BUF_UNAVAI'. Users
|
||
|
* must call this function to start ethernet again after new buffer
|
||
|
* prepared.
|
||
|
* @param None
|
||
|
* @retval None
|
||
|
*/
|
||
|
void ETH_ResumeTx(void);
|
||
|
|
||
|
/**
|
||
|
* @brief Get free transmission descriptor\n
|
||
|
* @param None
|
||
|
* @retval ETH_TX_DESC* A pointer of free transmission descriptor,
|
||
|
* NULL if no free descriptor
|
||
|
*/
|
||
|
ETH_TX_DESC *ETH_AcquireFreeTxDesc(void);
|
||
|
|
||
|
/**
|
||
|
* @brief Check if a transmission descriptor is free or not
|
||
|
* @param desc A pointer of a transmission descriptor
|
||
|
* @retval BOOL True if the transmission descriptor is free, or flase.
|
||
|
*/
|
||
|
BOOL ETH_IsFreeTxDesc(ETH_TX_DESC *desc);
|
||
|
|
||
|
/**
|
||
|
* @brief Release a transmission descriptor to ethernet\n
|
||
|
* After users prepared data in the buffer of a free descriptor,
|
||
|
* They must call this function to change ownership of the
|
||
|
* descriptor to hardware.
|
||
|
* @param desc A pointer of a transmission descriptor
|
||
|
* @retval None
|
||
|
*/
|
||
|
void ETH_ReleaseTxDesc(ETH_TX_DESC *desc);
|
||
|
|
||
|
/**
|
||
|
* @brief Set ethernet receive descriptor ring
|
||
|
* @note Make sure that memory occupied by descriptors should be in physical
|
||
|
* memory and keep valid before ethernet receive is finished.
|
||
|
* @param[in] ring A pointer to header of ETH_TX_DESC ring, whose last node
|
||
|
* has a 'nextDescAddr' pointed to first node.
|
||
|
* @retval BOOL The bit indicates if valid ring is set
|
||
|
*/
|
||
|
BOOL ETH_SetRxDescRing(ETH_RX_DESC *ring);
|
||
|
|
||
|
/**
|
||
|
* @brief Start ethernet receive
|
||
|
* @param None
|
||
|
* @retval None
|
||
|
*/
|
||
|
void ETH_StartRx(void);
|
||
|
|
||
|
/**
|
||
|
* @brief Stop ethernet receive
|
||
|
* @param None
|
||
|
* @retval None
|
||
|
*/
|
||
|
void ETH_StopRx(void);
|
||
|
|
||
|
/**
|
||
|
* @brief Resume ethernet receive\n
|
||
|
* While ethernet doesn't have enough buffer to receive data, it will
|
||
|
* pause and inform users by interrupt 'ETH_INT_RX_BUF_UNAVAI'. Users
|
||
|
* must call this function to start ethernet again after new buffer
|
||
|
* prepared.
|
||
|
* @param None
|
||
|
* @retval None
|
||
|
*/
|
||
|
void ETH_ResumeRx(void);
|
||
|
|
||
|
/**
|
||
|
* @brief Get the free descriptor which contains received data\n
|
||
|
* @param None
|
||
|
* @retval ETH_RX_DESC* A pointer of free receive descriptor,
|
||
|
* NULL if no free descriptor
|
||
|
*/
|
||
|
ETH_RX_DESC *ETH_AcquireFreeRxDesc(void);
|
||
|
|
||
|
/**
|
||
|
* @brief Check if a receive descriptor is free or not
|
||
|
* @param desc A pointer of a receive descriptor
|
||
|
* @retval BOOL True if the receive descriptor is free, or flase.
|
||
|
*/
|
||
|
BOOL ETH_IsFreeRxDesc(ETH_RX_DESC *desc);
|
||
|
|
||
|
/**
|
||
|
* @brief Release a receive descriptor to ethernet\n
|
||
|
* After users handled data in the buffer of a free descriptor,
|
||
|
* They must call this function to change ownership of the
|
||
|
* descriptor to hardware.
|
||
|
* @param desc A pointer of a transmission descriptor
|
||
|
* @retval None
|
||
|
*/
|
||
|
void ETH_ReleaseRxDesc(ETH_RX_DESC *desc);
|
||
|
|
||
|
#ifdef __cplusplus
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#endif /* __CMEM7_ETH_H */
|
||
|
|