gd32f30x配置Enet接口示例代码
时间: 2023-08-21 09:04:14 浏览: 186
以下是一份gd32f30x配置Enet接口的示例代码,仅供参考:
```c
#include "gd32f30x.h"
#define ETH_MAC_ADDR0 (0x00)
#define ETH_MAC_ADDR1 (0x80)
#define ETH_MAC_ADDR2 (0xE1)
#define ETH_MAC_ADDR3 (0x00)
#define ETH_MAC_ADDR4 (0x00)
#define ETH_MAC_ADDR5 (0x01)
__IO uint32_t EthStatus = 0;
uint8_t MACAddr[6] = {ETH_MAC_ADDR0, ETH_MAC_ADDR1, ETH_MAC_ADDR2, ETH_MAC_ADDR3, ETH_MAC_ADDR4, ETH_MAC_ADDR5};
void ETH_GPIO_Config(void);
void ETH_MACDMA_Config(void);
void ETH_NVIC_Config(void);
void ETH_MACDMAInit(void);
void ETH_DMARxDescChainInit(void);
void ETH_DMATxDescChainInit(void);
void ETH_RxPkt_ChainMode(void);
void ETH_TxPkt_ChainMode(void);
int main(void)
{
/* configure ethernet GPIO */
ETH_GPIO_Config();
/* configure ethernet MAC/DMA */
ETH_MACDMA_Config();
/* configure ethernet NVIC */
ETH_NVIC_Config();
/* initialize ethernet MAC/DMA */
ETH_MACDMAInit();
/* initialize ethernet Rx descriptors */
ETH_DMARxDescChainInit();
/* initialize ethernet Tx descriptors */
ETH_DMATxDescChainInit();
/* receive packet in chain mode */
ETH_RxPkt_ChainMode();
/* transmit packet in chain mode */
ETH_TxPkt_ChainMode();
while(1){}
}
/**
* @brief configure ethernet GPIO
* @param None
* @retval None
*/
void ETH_GPIO_Config(void)
{
/* enable ethernet GPIO clocks */
rcu_periph_clock_enable(RCU_GPIOA);
rcu_periph_clock_enable(RCU_GPIOC);
rcu_periph_clock_enable(RCU_AF);
/* config ethernet pins (PA2/PA3/PA7/PC1/PC4/PC5) */
gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_7);
gpio_init(GPIOC, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_5);
}
/**
* @brief configure ethernet MAC/DMA
* @param None
* @retval None
*/
void ETH_MACDMA_Config(void)
{
/* enable ethernet MAC/DMA clocks */
rcu_periph_clock_enable(RCU_ETHMAC);
rcu_periph_clock_enable(RCU_DMA0);
/* reset ethernet MAC/DMA */
rcu_periph_reset_enable(RCU_ETHMAC);
rcu_periph_reset_enable(RCU_DMA0);
rcu_periph_reset_disable(RCU_ETHMAC);
rcu_periph_reset_disable(RCU_DMA0);
/* select MII interface mode */
ETH_MACInterfaceModeConfig(ETH_MAC_INTERFACE_MODE_MII);
/* configure ethernet MAC */
ETH_MACInitTypeDef MACInit;
MACInit.watchdog = ETH_WATCHDOG_ENABLE;
MACInit.jabber = ETH_JABBER_ENABLE;
MACInit.inter_frame_gap = ETH_INTER_FRAME_GAP_96BITS;
MACInit.checksum_offload = ETH_CHECKSUM_OFFLOAD_ENABLE;
MACInit.retry_transmission = ETH_RETRY_TRANSMISSION_DISABLE;
MACInit.auto_negotiation = ETH_AUTO_NEGOTIATION_DISABLE;
MACInit.power_down = ETH_POWER_DOWN_DISABLE;
MACInit.loopback_mode = ETH_LOOPBACK_MODE_DISABLE;
MACInit.duplex_mode = ETH_MODE_FULLDUPLEX;
MACInit.speed = ETH_SPEED_100M;
ETH_MACInit(&MACInit, MACAddr);
/* configure ethernet DMA */
ETH_DMATxInitTypeDef DMAInitTx;
DMAInitTx.dma_tx_queue = ETH_DMA_TX_QUEUE_0;
DMAInitTx.dma_tx_desc_segments = ETH_DMA_TX_SEGMENTS_1;
DMAInitTx.dma_tx_desc_size = ETH_DMA_TX_DESC_SIZE;
DMAInitTx.dma_tx_desc_addr = (uint32_t)tx_desc;
ETH_DMATxInit(&DMAInitTx);
ETH_DMARxInitTypeDef DMAInitRx;
DMAInitRx.dma_rx_queue = ETH_DMA_RX_QUEUE_0;
DMAInitRx.dma_rx_desc_segments = ETH_DMA_RX_SEGMENTS_1;
DMAInitRx.dma_rx_desc_size = ETH_DMA_RX_DESC_SIZE;
DMAInitRx.dma_rx_desc_addr = (uint32_t)rx_desc;
ETH_DMARxInit(&DMAInitRx);
}
/**
* @brief configure ethernet NVIC
* @param None
* @retval None
*/
void ETH_NVIC_Config(void)
{
nvic_irq_enable(ETH_IRQn, 0, 0);
}
/**
* @brief initialize ethernet MAC/DMA
* @param None
* @retval None
*/
void ETH_MACDMAInit(void)
{
ETH_Start();
ETH_DMATxEnable(ETH_DMA_TX_QUEUE_0);
ETH_DMARxEnable(ETH_DMA_RX_QUEUE_0);
}
/**
* @brief initialize ethernet Rx descriptors
* @param None
* @retval None
*/
void ETH_DMARxDescChainInit(void)
{
/* set Rx descriptors to zero */
memset(rx_desc, 0, sizeof(rx_desc));
/* Initialize Rx descriptors in chain mode */
for (int i = 0; i < ETH_DMA_RX_DESC_COUNT; i++) {
rx_desc[i].status |= ETH_DMARXDESC_OWN;
rx_desc[i].status &= ~(ETH_DMARXDESC_LS | ETH_DMARXDESC_FS);
rx_desc[i].basic.status = ETH_DMARXDESC_OWN;
rx_desc[i].basic.status |= ETH_DMARXDESC_BUF1V;
rx_desc[i].basic.length = ETH_RX_BUF_SIZE;
rx_desc[i].basic.buf1_addr = (uint32_t)rx_buf[i];
if (i == (ETH_DMA_RX_DESC_COUNT - 1)) {
rx_desc[i].basic.status |= ETH_DMARXDESC_EOP;
}
rx_desc[i].next = (uint32_t)&rx_desc[i+1];
}
/* set last descriptor with wrap flag */
rx_desc[ETH_DMA_RX_DESC_COUNT-1].basic.status |= ETH_DMARXDESC_WRAP;
rx_desc[ETH_DMA_RX_DESC_COUNT-1].next = (uint32_t)rx_desc;
ETH_DMARxDescListInit(rx_desc, ETH_DMA_RX_DESC_COUNT);
}
/**
* @brief initialize ethernet Tx descriptors
* @param None
* @retval None
*/
void ETH_DMATxDescChainInit(void)
{
/* set Tx descriptors to zero */
memset(tx_desc, 0, sizeof(tx_desc));
/* Initialize Tx descriptors in chain mode */
for (int i = 0; i < ETH_DMA_TX_DESC_COUNT; i++) {
tx_desc[i].status |= ETH_DMATXDESC_OWN;
tx_desc[i].status &= ~(ETH_DMATXDESC_FS | ETH_DMATXDESC_LS | ETH_DMATXDESC_IC | ETH_DMATXDESC_DC);
tx_desc[i].basic.status = ETH_DMATXDESC_OWN;
tx_desc[i].basic.status |= ETH_DMATXDESC_BUF1V;
if (i == (ETH_DMA_TX_DESC_COUNT - 1)) {
tx_desc[i].basic.status |= ETH_DMATXDESC_EOP;
}
tx_desc[i].basic.length = ETH_TX_BUF_SIZE;
tx_desc[i].basic.buf1_addr = (uint32_t)tx_buf[i];
tx_desc[i].next = (uint32_t)&tx_desc[i+1];
}
/* set last descriptor with wrap flag */
tx_desc[ETH_DMA_TX_DESC_COUNT-1].basic.status |= ETH_DMATXDESC_WRAP;
tx_desc[ETH_DMA_TX_DESC_COUNT-1].next = (uint32_t)tx_desc;
ETH_DMATxDescListInit(tx_desc, ETH_DMA_TX_DESC_COUNT);
}
/**
* @brief receive packet in chain mode
* @param None
* @retval None
*/
void ETH_RxPkt_ChainMode(void)
{
uint32_t framelength = 0;
uint32_t ethDestAddr[2];
uint32_t ethSrcAddr[2];
uint16_t ethType;
if ((rx_desc[ETH_DMA_RX_CURR_DESC_IDX].basic.status & ETH_DMARXDESC_OWN) == (uint32_t)RESET) {
if ((rx_desc[ETH_DMA_RX_CURR_DESC_IDX].basic.status & ETH_DMARXDESC_ES) == (uint32_t)RESET) {
framelength = ((rx_desc[ETH_DMA_RX_CURR_DESC_IDX].basic.status & ETH_DMARXDESC_FL) >> 16) & 0x3FFF;
ethDestAddr[0] = rx_desc[ETH_DMA_RX_CURR_DESC_IDX].basic.buf1_addr;
ethDestAddr[1] = rx_desc[ETH_DMA_RX_CURR_DESC_IDX].basic.buf2_addr;
ethSrcAddr[0] = rx_desc[ETH_DMA_RX_CURR_DESC_IDX].extended.status & 0xFFFF;
ethSrcAddr[1] = rx_desc[ETH_DMA_RX_CURR_DESC_IDX].extended.buf1_addr;
/* check ethernet packet type */
ethType = (uint16_t)(*(uint32_t *)(rx_desc[ETH_DMA_RX_CURR_DESC_IDX].basic.buf1_addr + 12));
if (ethType == 0x0800) { /* IPv4 */
/* process IPv4 packet */
} else if (ethType == 0x86DD) { /* IPv6 */
/* process IPv6 packet */
}
rx_desc[ETH_DMA_RX_CURR_DESC_IDX].basic.status = ETH_DMARXDESC_OWN;
rx_desc[ETH_DMA_RX_CURR_DESC_IDX].basic.status |= ETH_DMARXDESC_BUF1V;
rx_desc[ETH_DMA_RX_CURR_DESC_IDX].basic.length = ETH_RX_BUF_SIZE;
rx_desc[ETH_DMA_RX_CURR_DESC_IDX].basic.buf1_addr = (uint32_t)rx_buf[ETH_DMA_RX_CURR_DESC_IDX];
if (ETH_DMA_RX_CURR_DESC_IDX == (ETH_DMA_RX_DESC_COUNT - 1)) {
rx_desc[ETH_DMA_RX_CURR_DESC_IDX].basic.status |= ETH_DMARXDESC_EOP;
}
if ((ETH_DMA_RX_CURR_DESC_IDX % 2) == 0) {
rx_desc[ETH_DMA_RX_CURR_DESC_IDX].basic.status |= ETH_DMARXDESC_FS;
}
rx_desc[ETH_DMA_RX_CURR_DESC_IDX].next = (uint32_t)&rx_desc[ETH_DMA_RX_CURR_DESC_IDX+1];
ETH_DMA_RX_CURR_DESC_IDX = (ETH_DMA_RX_CURR_DESC_IDX + 1) % ETH_DMA_RX_DESC_COUNT;
}
}
}
/**
* @brief transmit packet in chain mode
* @param None
* @retval None
*/
void ETH_TxPkt_ChainMode(void)
{
/* fill Tx buffer with data to transmit */
memset(tx_buf[ETH_DMA_TX_CURR_DESC_IDX], 0, ETH_TX_BUF_SIZE);
memcpy(tx_buf[ETH_DMA_TX_CURR_DESC_IDX], "Hello world!", 12);
tx_desc[ETH_DMA_TX_CURR_DESC_IDX].basic.status = ETH_DMATXDESC_OWN;
tx_desc[ETH_DMA_TX_CURR_DESC_IDX].basic.status |= ETH_DMATXDESC_BUF1V;
tx_desc[ETH_DMA_TX_CURR_DESC_IDX].basic.length = 12;
tx_desc[ETH_DMA_TX_CURR_DESC_IDX].basic.buf1_addr = (uint32_t)tx_buf[ETH_DMA_TX_CURR_DESC_IDX];
tx_desc[ETH_DMA_TX_CURR_DESC_IDX].basic.status |= ETH_DMATXDESC_LS;
tx_desc[ETH_DMA_TX_CURR_DESC_IDX].basic.status |= ETH_DMATXDESC_FS;
tx_desc[ETH_DMA_TX_CURR_DESC_IDX].next = (uint32_t)&tx_desc[ETH_DMA_TX_CURR_DESC_IDX+1];
if (ETH_DMA_TX_CURR_DESC_IDX == (ETH_DMA_TX_DESC_COUNT - 1)) {
tx_desc[ETH_DMA_TX_CURR_DESC_IDX].basic.status |= ETH_DMATXDESC_EOP;
tx_desc[ETH_DMA_TX_CURR_DESC_IDX].basic.status |= ETH_DMATXDESC_IC;
}
ETH_DMA_TX_CURR_DESC_IDX = (ETH_DMA_TX_CURR_DESC_IDX + 1) % ETH_DMA_TX_DESC_COUNT;
ETH_DMATxDescListInit(tx_desc, ETH_DMA_TX_DESC_COUNT);
ETH_DMATxEnable(ETH_DMA_TX_QUEUE_0);
}
```
该示例代码的具体实现细节可以参考GD32F30x固件库的官方文档,也可以根据需要进行修改。
阅读全文