fix: works?
This commit is contained in:
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@@ -17,6 +17,7 @@
|
|||||||
"etharp.h": "c",
|
"etharp.h": "c",
|
||||||
"dhcp.h": "c",
|
"dhcp.h": "c",
|
||||||
"netif.h": "c",
|
"netif.h": "c",
|
||||||
"ch32v307gigabit.h": "c"
|
"ch32v307gigabit.h": "c",
|
||||||
|
"stats.h": "c"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
119
main.c
119
main.c
@@ -10,113 +10,132 @@
|
|||||||
#include "netif/ethernet.h"
|
#include "netif/ethernet.h"
|
||||||
#include "systick.h"
|
#include "systick.h"
|
||||||
|
|
||||||
#define LED1_PIN 0
|
#define LED1_PIN 0 // PA0
|
||||||
#define LED2_PIN 2
|
#define LED2_PIN 2 // PA2
|
||||||
|
|
||||||
|
#define HSE_STARTUP_TIMEOUT 10000
|
||||||
|
#define PLL_LOCK_TIMEOUT 10000
|
||||||
|
#define LED_TOGGLE_INTERVAL_MS 500
|
||||||
|
#define LINK_POLL_INTERVAL_MS 500
|
||||||
|
|
||||||
#define RCC_PREDIV1_OFFSET 0
|
#define RCC_PREDIV1_OFFSET 0
|
||||||
|
#define HSE_CLOCK_MHZ 32
|
||||||
|
#define PREDIV1_DIVISOR 4
|
||||||
|
#define PLL_MULTIPLIER 15
|
||||||
|
|
||||||
struct netif g_netif;
|
struct netif g_netif;
|
||||||
|
|
||||||
void init_leds() {
|
int clock_init(void);
|
||||||
RCC->APB2PCENR |= RCC_APB2Periph_GPIOA;
|
void led_init(void);
|
||||||
GPIOA->CFGLR &= ~((0xf << (4 * 0)) | (0xf << (4 * 2)));
|
void lwip_stack_init(void);
|
||||||
GPIOA->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP) << (4 * 0);
|
|
||||||
GPIOA->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP) << (4 * 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main() {
|
int clock_init(void) {
|
||||||
SystemInit();
|
RCC->INTR = 0x009f0000;
|
||||||
|
|
||||||
// 1. HSE (32MHz)
|
|
||||||
// 2. PREDIV1 / 4.
|
|
||||||
// 3. PLL source = HSE, PLL x15.
|
|
||||||
// 4. (32MHz / 4) * 15 = 120MHz SYSCLK
|
|
||||||
|
|
||||||
RCC->INTR = 0x009F0000;
|
|
||||||
RCC->CTLR &= ~(RCC_HSE_ON | RCC_PLLON);
|
RCC->CTLR &= ~(RCC_HSE_ON | RCC_PLLON);
|
||||||
RCC->CFGR0 = 0x00000000;
|
RCC->CFGR0 = 0x00000000;
|
||||||
RCC->CTLR |= RCC_HSE_ON;
|
|
||||||
|
|
||||||
int timeout;
|
RCC->CTLR |= RCC_HSE_ON;
|
||||||
for (timeout = 10000; timeout > 0; timeout--) {
|
for (int timeout = HSE_STARTUP_TIMEOUT; timeout > 0; timeout--) {
|
||||||
if (RCC->CTLR & RCC_HSERDY) break; // wait for HSE
|
if (RCC->CTLR & RCC_HSERDY) break;
|
||||||
}
|
if (timeout == 1) {
|
||||||
if (timeout == 0) {
|
|
||||||
printf("Error: HSE failed to start\n");
|
printf("Error: HSE failed to start\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||||
RCC->CFGR2 = ((3) << 0); // PREDIV1 divisor = 3+1 = 4
|
RCC->CFGR2 = (PREDIV1_DIVISOR - 1);
|
||||||
RCC->CFGR0 |= RCC_PLLSource_HSE_Div1 | RCC_PLLMul_15;
|
RCC->CFGR0 |= RCC_PLLSource_HSE_Div1 | RCC_PLLMul_15;
|
||||||
|
|
||||||
RCC->CTLR |= RCC_PLLON;
|
RCC->CTLR |= RCC_PLLON;
|
||||||
printf("Main PLL enabled. Waiting for lock...\n");
|
printf("Main PLL en. Waiting for lock...\n");
|
||||||
for (timeout = 10000; timeout > 0; timeout--) {
|
for (int timeout = PLL_LOCK_TIMEOUT; timeout > 0; timeout--) {
|
||||||
if (RCC->CTLR & RCC_PLLRDY) break;
|
if (RCC->CTLR & RCC_PLLRDY) break;
|
||||||
}
|
if (timeout == 1) {
|
||||||
if (timeout == 0) {
|
printf("Error: Main PLL lock failed\n");
|
||||||
printf("error: main pll lock failed\n");
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
printf("Main PLL Locked\n");
|
printf("Main PLL Locked\n");
|
||||||
|
|
||||||
RCC->CFGR0 = (RCC->CFGR0 & ~RCC_SW) | RCC_SW_PLL;
|
RCC->CFGR0 = (RCC->CFGR0 & ~RCC_SW) | RCC_SW_PLL;
|
||||||
|
|
||||||
while ((RCC->CFGR0 & RCC_SWS) != RCC_SWS_PLL);
|
while ((RCC->CFGR0 & RCC_SWS) != RCC_SWS_PLL);
|
||||||
|
|
||||||
printf("SysClock set to 120MHz\n");
|
printf("System clock set to %dMHz.\n",
|
||||||
|
(HSE_CLOCK_MHZ / PREDIV1_DIVISOR) * PLL_MULTIPLIER);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
systick_init();
|
void led_init(void) {
|
||||||
init_leds();
|
RCC->APB2PCENR |= RCC_APB2Periph_GPIOA;
|
||||||
|
GPIOA->CFGLR &= ~((0xf << (4 * LED1_PIN)) | (0xf << (4 * LED2_PIN)));
|
||||||
|
GPIOA->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP) << (4 * LED1_PIN);
|
||||||
|
GPIOA->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP) << (4 * LED2_PIN);
|
||||||
|
}
|
||||||
|
|
||||||
|
void lwip_stack_init(void) {
|
||||||
|
ip_addr_t ipaddr, netmask, gw;
|
||||||
|
|
||||||
lwip_init();
|
lwip_init();
|
||||||
|
|
||||||
ip_addr_t ipaddr, netmask, gw;
|
|
||||||
IP4_ADDR(&ipaddr, 0, 0, 0, 0);
|
IP4_ADDR(&ipaddr, 0, 0, 0, 0);
|
||||||
IP4_ADDR(&netmask, 0, 0, 0, 0);
|
IP4_ADDR(&netmask, 0, 0, 0, 0);
|
||||||
IP4_ADDR(&gw, 0, 0, 0, 0);
|
IP4_ADDR(&gw, 0, 0, 0, 0);
|
||||||
|
|
||||||
netif_add(&g_netif, &ipaddr, &netmask, &gw, NULL, ðernetif_init,
|
netif_add(&g_netif, &ipaddr, &netmask, &gw, NULL, ðernetif_init,
|
||||||
ðernet_input);
|
ðernet_input);
|
||||||
// netif_set_link_callback(&g_netif, link_status_callback);
|
|
||||||
netif_set_default(&g_netif);
|
netif_set_default(&g_netif);
|
||||||
netif_set_up(&g_netif);
|
netif_set_up(&g_netif);
|
||||||
|
|
||||||
|
printf("Starting DHCP client...\n");
|
||||||
dhcp_start(&g_netif);
|
dhcp_start(&g_netif);
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t last_led_toggle = 0;
|
int main() {
|
||||||
uint32_t last_send_time = 0;
|
SystemInit();
|
||||||
|
|
||||||
|
if (clock_init() != 0) {
|
||||||
|
// eating dirt?
|
||||||
|
while (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
systick_init();
|
||||||
|
led_init();
|
||||||
|
lwip_stack_init();
|
||||||
|
|
||||||
|
uint32_t last_led_toggle_time = 0;
|
||||||
|
uint32_t last_link_poll_time = 0;
|
||||||
int led_state = 0;
|
int led_state = 0;
|
||||||
|
int ip_address_printed = 0;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
ethernetif_link_poll(&g_netif);
|
|
||||||
|
|
||||||
if (netif_is_link_up(&g_netif)) {
|
|
||||||
ethernetif_input(&g_netif);
|
ethernetif_input(&g_netif);
|
||||||
|
|
||||||
|
if (millis() - last_link_poll_time > LINK_POLL_INTERVAL_MS) {
|
||||||
|
ethernetif_link_poll(&g_netif);
|
||||||
|
last_link_poll_time = millis();
|
||||||
}
|
}
|
||||||
|
|
||||||
sys_check_timeouts();
|
sys_check_timeouts();
|
||||||
|
|
||||||
// run_tx_test();
|
|
||||||
|
|
||||||
uint32_t now = millis();
|
uint32_t now = millis();
|
||||||
|
if (now - last_led_toggle_time > LED_TOGGLE_INTERVAL_MS) {
|
||||||
if (now - last_led_toggle > 500) {
|
|
||||||
if (led_state) {
|
if (led_state) {
|
||||||
GPIOA->BSHR = (1 << 0);
|
GPIOA->BSHR = (1 << LED1_PIN);
|
||||||
} else {
|
} else {
|
||||||
GPIOA->BSHR = (1 << (0 + 16));
|
GPIOA->BSHR = (1 << (LED1_PIN + 16));
|
||||||
}
|
}
|
||||||
led_state = !led_state;
|
led_state = !led_state;
|
||||||
last_led_toggle = now;
|
last_led_toggle_time = now;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ip_printed = 0;
|
if (!ip_address_printed && g_netif.ip_addr.addr != 0) {
|
||||||
if (g_netif.ip_addr.addr != 0 && !ip_printed) {
|
|
||||||
printf("IP address assigned: %s\n",
|
printf("IP address assigned: %s\n",
|
||||||
ip4addr_ntoa(netif_ip4_addr(&g_netif)));
|
ip4addr_ntoa(netif_ip4_addr(&g_netif)));
|
||||||
ip_printed = 1;
|
ip_address_printed = 1;
|
||||||
|
|
||||||
|
GPIOA->BSHR = (1 << LED2_PIN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,19 +1,13 @@
|
|||||||
#include "ethernetif.h"
|
#include "ethernetif.h"
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "ch32fun.h"
|
#include "ch32fun.h"
|
||||||
#include "ch32v20xhw.h"
|
#include "ch32v20xhw.h"
|
||||||
#include "lwip/def.h"
|
|
||||||
#include "lwip/etharp.h"
|
#include "lwip/etharp.h"
|
||||||
#include "lwip/ethip6.h"
|
|
||||||
#include "lwip/mem.h"
|
|
||||||
#include "lwip/opt.h"
|
|
||||||
#include "lwip/pbuf.h"
|
|
||||||
#include "lwip/snmp.h"
|
#include "lwip/snmp.h"
|
||||||
#include "lwip/stats.h"
|
|
||||||
#include "netif/ethernet.h"
|
|
||||||
#include "systick.h"
|
#include "systick.h"
|
||||||
|
|
||||||
#define IFNAME0 'e'
|
#define IFNAME0 'e'
|
||||||
@@ -35,101 +29,82 @@ __attribute__((aligned(4))) ETH_DMADESCTypeDef DMATxDscrTab[ETH_TXBUFNB];
|
|||||||
__attribute__((aligned(4))) uint8_t MACRxBuf[ETH_RXBUFNB * ETH_RX_BUF_SZE];
|
__attribute__((aligned(4))) uint8_t MACRxBuf[ETH_RXBUFNB * ETH_RX_BUF_SZE];
|
||||||
__attribute__((aligned(4))) uint8_t MACTxBuf[ETH_TXBUFNB * ETH_TX_BUF_SZE];
|
__attribute__((aligned(4))) uint8_t MACTxBuf[ETH_TXBUFNB * ETH_TX_BUF_SZE];
|
||||||
|
|
||||||
static volatile uint8_t g_rx_error_cnt = 0;
|
static volatile bool g_link_interrupt_flag = false;
|
||||||
volatile uint32_t g_isr_call_count = 0;
|
|
||||||
|
|
||||||
|
static void low_level_init(struct netif* netif);
|
||||||
static err_t low_level_output(struct netif* netif, struct pbuf* p);
|
static err_t low_level_output(struct netif* netif, struct pbuf* p);
|
||||||
static struct pbuf* low_level_input(struct netif* netif);
|
static struct pbuf* low_level_input(struct netif* netif);
|
||||||
static void low_level_init(struct netif* netif);
|
void WritePHYReg(uint8_t reg_add, uint16_t reg_val);
|
||||||
|
uint16_t ReadPHYReg(uint8_t reg_add);
|
||||||
|
|
||||||
void eth_dma_tx_desc_chain_init(struct ethernetif* ethernetif,
|
static void eth_get_mac_in_uc(uint8_t* mac) {
|
||||||
ETH_DMADESCTypeDef* DMATxDescTab,
|
// Mac is backwards.
|
||||||
uint8_t* TxBuff, uint32_t TxBuffCount) {
|
const uint8_t* macaddr = (const uint8_t*)(ROM_CFG_USERADR_ID + 5);
|
||||||
ethernetif->DMATxDescToSet = DMATxDescTab;
|
for (int i = 0; i < 6; i++) {
|
||||||
DMATxDescTab->Status = 0;
|
mac[i] = *(macaddr--);
|
||||||
DMATxDescTab->Buffer1Addr = (uint32_t)TxBuff;
|
|
||||||
DMATxDescTab->Buffer2NextDescAddr = (uint32_t)DMATxDescTab; // ring of 1
|
|
||||||
}
|
|
||||||
|
|
||||||
void eth_dma_rx_desc_chain_init(struct ethernetif* ethernetif,
|
|
||||||
ETH_DMADESCTypeDef* DMARxDescTab,
|
|
||||||
uint8_t* RxBuff, uint32_t RxBuffCount) {
|
|
||||||
ethernetif->DMARxDescToGet = DMARxDescTab;
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < RxBuffCount; i++) {
|
|
||||||
DMARxDescTab[i].Status = ETH_DMARxDesc_OWN; // give descriptor to DMA
|
|
||||||
DMARxDescTab[i].ControlBufferSize = ETH_RX_BUF_SZE;
|
|
||||||
|
|
||||||
DMARxDescTab[i].Buffer1Addr = (uint32_t)(&RxBuff[i * ETH_RX_BUF_SZE]);
|
|
||||||
|
|
||||||
if (i < (RxBuffCount - 1)) {
|
|
||||||
DMARxDescTab[i].Buffer2NextDescAddr = (uint32_t)(DMARxDescTab + i + 1);
|
|
||||||
} else {
|
|
||||||
DMARxDescTab[i].Buffer2NextDescAddr = (uint32_t)(DMARxDescTab);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ETH_IRQHandler(void) __attribute__((interrupt));
|
err_t ethernetif_init(struct netif* netif) {
|
||||||
void ETH_IRQHandler(void) {
|
struct ethernetif* ethernetif = mem_malloc(sizeof(struct ethernetif));
|
||||||
g_isr_call_count++;
|
if (ethernetif == NULL) {
|
||||||
uint8_t flags = ETH10M->EIR;
|
LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_init: out of memory\n"));
|
||||||
|
return ERR_MEM;
|
||||||
if (flags & RB_ETH_EIR_RXIF) {
|
|
||||||
printf("<<< RX Interrupt Fired. EIR=0x%02X >>>>>\n", flags);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// tx complete/error
|
#if LWIP_NETIF_HOSTNAME
|
||||||
if (flags & (RB_ETH_EIR_TXIF | RB_ETH_EIR_TXERIF)) {
|
netif->hostname = "lwip-ch32";
|
||||||
// release DMA descriptor back to cpu
|
#endif
|
||||||
if (DMATxDscrTab[0].Status & ETH_DMATxDesc_OWN) {
|
|
||||||
DMATxDscrTab[0].Status &= ~ETH_DMATxDesc_OWN;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flags & RB_ETH_EIR_RXERIF) {
|
netif->state = ethernetif;
|
||||||
if (g_rx_error_cnt < 255) {
|
netif->name[0] = IFNAME0;
|
||||||
g_rx_error_cnt++;
|
netif->name[1] = IFNAME1;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ETH10M->EIR = flags;
|
netif->output = etharp_output;
|
||||||
|
netif->linkoutput = low_level_output;
|
||||||
|
|
||||||
|
MIB2_INIT_NETIF(netif, snmp_ifType_ethernet_csmacd, 10000000); // 10Mbps
|
||||||
|
|
||||||
|
netif->hwaddr_len = ETH_HWADDR_LEN;
|
||||||
|
uint8_t mac_addr[6];
|
||||||
|
eth_get_mac_in_uc(mac_addr);
|
||||||
|
|
||||||
|
printf("MAC Address: %02X:%02X:%02X:%02X:%02X:%02X\n", mac_addr[0],
|
||||||
|
mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
|
||||||
|
|
||||||
|
/* set MAC hardware address */
|
||||||
|
netif->hwaddr[0] = mac_addr[0];
|
||||||
|
netif->hwaddr[1] = mac_addr[1];
|
||||||
|
netif->hwaddr[2] = mac_addr[2];
|
||||||
|
netif->hwaddr[3] = mac_addr[3];
|
||||||
|
netif->hwaddr[4] = mac_addr[4];
|
||||||
|
netif->hwaddr[5] = mac_addr[5];
|
||||||
|
|
||||||
|
netif->mtu = 1500;
|
||||||
|
netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP;
|
||||||
|
|
||||||
|
low_level_init(netif);
|
||||||
|
|
||||||
|
return ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void low_level_init(struct netif* netif) {
|
static void low_level_init(struct netif* netif) {
|
||||||
struct ethernetif* ethernetif = netif->state;
|
struct ethernetif* ethernetif = netif->state;
|
||||||
uint8_t i;
|
|
||||||
|
|
||||||
netif->hwaddr_len = ETH_HWADDR_LEN;
|
// clocks
|
||||||
netif->hwaddr[0] = 0x00;
|
|
||||||
netif->hwaddr[1] = 0x80;
|
|
||||||
netif->hwaddr[2] = 0xE1;
|
|
||||||
netif->hwaddr[3] = 0x00;
|
|
||||||
netif->hwaddr[4] = 0x00;
|
|
||||||
netif->hwaddr[5] = 0x01;
|
|
||||||
netif->mtu = 1500;
|
|
||||||
netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP;
|
|
||||||
|
|
||||||
// clock
|
|
||||||
RCC->APB2PCENR |= RCC_APB2Periph_AFIO;
|
RCC->APB2PCENR |= RCC_APB2Periph_AFIO;
|
||||||
RCC->CFGR0 &= ~((uint32_t)1 << 28);
|
RCC->CFGR0 = (RCC->CFGR0 & ~((uint32_t)1 << 28)) | (RCC_ETHCLK_Div2 << 28);
|
||||||
RCC->CFGR0 |= (RCC_ETHCLK_Div2 << 28);
|
EXTEN->EXTEN_CTR |= EXTEN_ETH_10M_EN;
|
||||||
|
|
||||||
// interrupts
|
// mac reset
|
||||||
ETH10M->EIE = 0; // clear
|
|
||||||
ETH10M->EIE = RB_ETH_EIE_INTIE | RB_ETH_EIE_LINKIE | RB_ETH_EIE_TXIE |
|
|
||||||
RB_ETH_EIE_TXERIE | RB_ETH_EIE_RXERIE;
|
|
||||||
ETH10M->EIE |= RB_ETH_EIE_R_EN50; // 50 ohm pull-up
|
|
||||||
|
|
||||||
ETH10M->EIR = 0xFF;
|
|
||||||
ETH10M->ESTAT |= RB_ETH_ESTAT_INT | RB_ETH_ESTAT_BUFER;
|
|
||||||
|
|
||||||
// reset mac
|
|
||||||
ETH10M->ECON1 |= (RB_ETH_ECON1_TXRST | RB_ETH_ECON1_RXRST);
|
ETH10M->ECON1 |= (RB_ETH_ECON1_TXRST | RB_ETH_ECON1_RXRST);
|
||||||
ETH10M->ECON1 &= ~(RB_ETH_ECON1_TXRST | RB_ETH_ECON1_RXRST);
|
ETH10M->ECON1 &= ~(RB_ETH_ECON1_TXRST | RB_ETH_ECON1_RXRST);
|
||||||
|
|
||||||
// // mac regs
|
// mac regs
|
||||||
ETH10M->ERXFON = 0; // accept unicast, multicast, broadcast
|
ETH10M->ERXFON = RB_ETH_ERXFCON_BCEN | RB_ETH_ERXFCON_MCEN;
|
||||||
|
ETH10M->MACON1 = RB_ETH_MACON1_MARXEN;
|
||||||
|
ETH10M->MACON2 = PADCFG_AUTO_3 | RB_ETH_MACON2_TXCRCEN;
|
||||||
|
ETH10M->MAMXFL = ETH_MAX_PACKET_SIZE;
|
||||||
|
|
||||||
R8_ETH_MAADRL1 = netif->hwaddr[5];
|
R8_ETH_MAADRL1 = netif->hwaddr[5];
|
||||||
R8_ETH_MAADRL2 = netif->hwaddr[4];
|
R8_ETH_MAADRL2 = netif->hwaddr[4];
|
||||||
@@ -138,209 +113,138 @@ static void low_level_init(struct netif* netif) {
|
|||||||
R8_ETH_MAADRL5 = netif->hwaddr[1];
|
R8_ETH_MAADRL5 = netif->hwaddr[1];
|
||||||
R8_ETH_MAADRL6 = netif->hwaddr[0];
|
R8_ETH_MAADRL6 = netif->hwaddr[0];
|
||||||
|
|
||||||
ETH10M->MACON1 = RB_ETH_MACON1_MARXEN;
|
|
||||||
|
|
||||||
ETH10M->MACON2 &= ~RB_ETH_MACON2_PADCFG;
|
|
||||||
ETH10M->MACON2 |= PADCFG_AUTO_3 | RB_ETH_MACON2_TXCRCEN;
|
|
||||||
ETH10M->MACON2 &= ~RB_ETH_MACON2_HFRMEN; // disable huge frames
|
|
||||||
ETH10M->MACON2 |= RB_ETH_MACON2_FULDPX;
|
|
||||||
|
|
||||||
ETH10M->MAMXFL = ETH_MAX_PACKET_SIZE;
|
|
||||||
|
|
||||||
// PHY analog block
|
// PHY analog block
|
||||||
ETH10M->ECON2 &= ~(0x07 << 1);
|
ETH10M->ECON2 = (ETH10M->ECON2 & ~(0x07 << 1)) | (5 << 1);
|
||||||
ETH10M->ECON2 |= (5 << 1);
|
|
||||||
|
|
||||||
// en PHY block
|
// DMA descriptors
|
||||||
EXTEN->EXTEN_CTR |= EXTEN_ETH_10M_EN;
|
ethernetif->DMATxDescToSet = &DMATxDscrTab[0];
|
||||||
|
DMATxDscrTab[0].Status = 0;
|
||||||
|
DMATxDscrTab[0].Buffer1Addr = (uint32_t)MACTxBuf;
|
||||||
|
DMATxDscrTab[0].Buffer2NextDescAddr = (uint32_t)&DMATxDscrTab[0];
|
||||||
|
|
||||||
// tx desc
|
ethernetif->DMARxDescToGet = &DMARxDscrTab[0];
|
||||||
eth_dma_tx_desc_chain_init(ethernetif, DMATxDscrTab, MACTxBuf, ETH_TXBUFNB);
|
for (int i = 0; i < ETH_RXBUFNB; i++) {
|
||||||
// rx desc
|
DMARxDscrTab[i].Status = 0;
|
||||||
eth_dma_rx_desc_chain_init(ethernetif, DMARxDscrTab, MACRxBuf, ETH_RXBUFNB);
|
DMARxDscrTab[i].Buffer1Addr = (uint32_t)(&MACRxBuf[i * ETH_RX_BUF_SZE]);
|
||||||
|
DMARxDscrTab[i].Buffer2NextDescAddr =
|
||||||
|
(uint32_t)(&DMARxDscrTab[(i + 1) % ETH_RXBUFNB]);
|
||||||
|
}
|
||||||
|
|
||||||
printf("set PHY to 10Mbps Full-Duplex mode\n");
|
ETH10M->ERXST = (uint32_t)ethernetif->DMARxDescToGet->Buffer1Addr;
|
||||||
|
ETH10M->ECON1 |= RB_ETH_ECON1_RXEN;
|
||||||
|
|
||||||
|
printf("Resetting PHY...\n");
|
||||||
|
WritePHYReg(PHY_BMCR, PHY_BMCR_RESET);
|
||||||
|
Delay_Ms(200);
|
||||||
|
|
||||||
|
printf("Starting PHY, Mode: 10BASE_T_FD\n");
|
||||||
WritePHYReg(PHY_BMCR, PHY_BMCR_FORCE_10BASE_T_FD);
|
WritePHYReg(PHY_BMCR, PHY_BMCR_FORCE_10BASE_T_FD);
|
||||||
|
|
||||||
// init phy and auto neg
|
ETH10M->EIE = RB_ETH_EIE_INTIE | RB_ETH_EIE_TXIE | RB_ETH_EIE_LINKIE;
|
||||||
// WritePHYReg(PHY_BMCR, PHY_BMCR_RESET);
|
ETH10M->EIR = 0xFF;
|
||||||
// Delay_Ms(200);
|
|
||||||
// WritePHYReg(PHY_BMCR, PHY_BMCR_FORCE_10BASE_T_FD | PHY_BMCR_AN_ENABLE |
|
|
||||||
// PHY_BMCR_AN_RESTART);
|
|
||||||
// Delay_Ms(1000);
|
|
||||||
|
|
||||||
NVIC_EnableIRQ(ETH_IRQn);
|
NVIC_EnableIRQ(ETH_IRQn);
|
||||||
printf("low_level_init : done\n");
|
printf("low_level_init: done\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static err_t low_level_output(struct netif* netif, struct pbuf* p) {
|
static err_t low_level_output(struct netif* netif, struct pbuf* p) {
|
||||||
struct ethernetif* ethernetif = netif->state;
|
if (DMATxDscrTab[0].Status & ETH_DMATxDesc_OWN) return ERR_BUF;
|
||||||
struct pbuf* q;
|
|
||||||
uint32_t len = 0;
|
uint32_t len = 0;
|
||||||
uint8_t* tx_buf_ptr = (uint8_t*)ethernetif->DMATxDescToSet->Buffer1Addr;
|
uint8_t* tx_buf_ptr = (uint8_t*)DMATxDscrTab[0].Buffer1Addr;
|
||||||
|
for (struct pbuf* q = p; q != NULL; q = q->next) {
|
||||||
if (ethernetif->DMATxDescToSet->Status & ETH_DMATxDesc_OWN) {
|
|
||||||
return ERR_BUF;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (q = p; q != NULL; q = q->next) {
|
|
||||||
memcpy(&tx_buf_ptr[len], q->payload, q->len);
|
memcpy(&tx_buf_ptr[len], q->payload, q->len);
|
||||||
len += q->len;
|
len += q->len;
|
||||||
}
|
}
|
||||||
|
|
||||||
ethernetif->DMATxDescToSet->Status |= ETH_DMATxDesc_OWN;
|
|
||||||
ETH10M->ETXLN = len;
|
ETH10M->ETXLN = len;
|
||||||
ETH10M->ETXST = (uint32_t)tx_buf_ptr;
|
ETH10M->ETXST = (uint32_t)tx_buf_ptr;
|
||||||
|
DMATxDscrTab[0].Status |= ETH_DMATxDesc_OWN;
|
||||||
ETH10M->ECON1 |= RB_ETH_ECON1_TXRTS;
|
ETH10M->ECON1 |= RB_ETH_ECON1_TXRTS;
|
||||||
|
|
||||||
ethernetif->DMATxDescToSet =
|
|
||||||
(ETH_DMADESCTypeDef*)ethernetif->DMATxDescToSet->Buffer2NextDescAddr;
|
|
||||||
|
|
||||||
MIB2_STATS_NETIF_ADD(netif, ifoutoctets, len);
|
MIB2_STATS_NETIF_ADD(netif, ifoutoctets, len);
|
||||||
return ERR_OK;
|
return ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct pbuf* low_level_input(struct netif* netif) {
|
static struct pbuf* low_level_input(struct netif* netif) {
|
||||||
struct ethernetif* ethernetif = netif->state;
|
struct ethernetif* ethernetif = netif->state;
|
||||||
struct pbuf *p = NULL, *q;
|
uint16_t len;
|
||||||
u16_t len;
|
uint8_t* current_rx_buffer_ptr;
|
||||||
ETH_DMADESCTypeDef* dmarxdesc;
|
|
||||||
|
|
||||||
if (ETH10M->EIR & RB_ETH_EIR_RXIF) {
|
if ((ETH10M->EIR & RB_ETH_EIR_RXIF) == 0) return NULL;
|
||||||
dmarxdesc = ethernetif->DMARxDescToGet;
|
|
||||||
|
|
||||||
if (ETH10M->ESTAT & (RB_ETH_ESTAT_BUFER | RB_ETH_ESTAT_RXCRCER)) {
|
|
||||||
len = 0;
|
|
||||||
printf("HW RX Error ESTAT: 0x%02X\n", (unsigned int)ETH10M->ESTAT);
|
|
||||||
ETH10M->ESTAT |= (RB_ETH_ESTAT_BUFER | RB_ETH_ESTAT_RXCRCER);
|
|
||||||
} else {
|
|
||||||
len = ETH10M->ERXLN;
|
len = ETH10M->ERXLN;
|
||||||
}
|
current_rx_buffer_ptr = (uint8_t*)ethernetif->DMARxDescToGet->Buffer1Addr;
|
||||||
|
|
||||||
|
ethernetif->DMARxDescToGet =
|
||||||
|
(ETH_DMADESCTypeDef*)ethernetif->DMARxDescToGet->Buffer2NextDescAddr;
|
||||||
|
ETH10M->ERXST = (uint32_t)ethernetif->DMARxDescToGet->Buffer1Addr;
|
||||||
|
ETH10M->ECON1 |= RB_ETH_ECON1_RXEN;
|
||||||
|
|
||||||
|
struct pbuf* p = NULL;
|
||||||
if (len > 0) {
|
if (len > 0) {
|
||||||
p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
|
p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
|
||||||
if (p != NULL) {
|
if (p != NULL) {
|
||||||
uint8_t* rx_buffer = (uint8_t*)dmarxdesc->Buffer1Addr;
|
|
||||||
uint32_t bytes_copied = 0;
|
uint32_t bytes_copied = 0;
|
||||||
for (q = p; q != NULL; q = q->next) {
|
for (struct pbuf* q = p; q != NULL; q = q->next) {
|
||||||
memcpy(q->payload, rx_buffer + bytes_copied, q->len);
|
memcpy(q->payload, current_rx_buffer_ptr + bytes_copied, q->len);
|
||||||
bytes_copied += q->len;
|
bytes_copied += q->len;
|
||||||
}
|
}
|
||||||
printf(
|
MIB2_STATS_NETIF_ADD(netif, ifinoctets, len);
|
||||||
"\n>>> Packet Received (len=%d, MAC len=%d). Copied to LwIP. "
|
|
||||||
"<<<\n\n",
|
|
||||||
len, ETH10M->ERXLN);
|
|
||||||
} else {
|
} else {
|
||||||
printf("pbuf_alloc failed. Dropping packet.\n");
|
MIB2_STATS_NETIF_INC(netif, ifindiscards);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dmarxdesc->Status = ETH_DMARxDesc_OWN;
|
|
||||||
ethernetif->DMARxDescToGet =
|
|
||||||
(ETH_DMADESCTypeDef*)dmarxdesc->Buffer2NextDescAddr;
|
|
||||||
|
|
||||||
ETH10M->ERXST = (uint32_t)ethernetif->DMARxDescToGet->Buffer1Addr;
|
|
||||||
ETH10M->EIR = RB_ETH_EIR_RXIF;
|
ETH10M->EIR = RB_ETH_EIR_RXIF;
|
||||||
|
return p;
|
||||||
return p; // return pbuf to LwIP
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL; // No packet was available.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ethernetif_input(struct netif* netif) {
|
void ethernetif_input(struct netif* netif) {
|
||||||
struct pbuf* p;
|
struct pbuf* p;
|
||||||
|
while ((p = low_level_input(netif)) != NULL) {
|
||||||
p = low_level_input(netif);
|
|
||||||
|
|
||||||
if (p != NULL) {
|
|
||||||
if (netif->input(p, netif) != ERR_OK) {
|
if (netif->input(p, netif) != ERR_OK) {
|
||||||
LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n"));
|
|
||||||
pbuf_free(p);
|
pbuf_free(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err_t ethernetif_init(struct netif* netif) {
|
|
||||||
struct ethernetif* ethernetif;
|
|
||||||
|
|
||||||
LWIP_ASSERT("netif != NULL", (netif != NULL));
|
|
||||||
|
|
||||||
ethernetif = mem_malloc(sizeof(struct ethernetif));
|
|
||||||
if (ethernetif == NULL) {
|
|
||||||
LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_init: out of memory\n"));
|
|
||||||
return ERR_MEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if LWIP_NETIF_HOSTNAME
|
|
||||||
netif->hostname = "lwip-wch";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
MIB2_INIT_NETIF(netif, snmp_ifType_ethernet_csmacd, 10000000); // 10 Mbps
|
|
||||||
|
|
||||||
netif->state = ethernetif;
|
|
||||||
netif->name[0] = IFNAME0;
|
|
||||||
netif->name[1] = IFNAME1;
|
|
||||||
#if LWIP_IPV4
|
|
||||||
netif->output = etharp_output;
|
|
||||||
#endif
|
|
||||||
#if LWIP_IPV6
|
|
||||||
netif->output_ip6 = ethip6_output;
|
|
||||||
#endif
|
|
||||||
netif->linkoutput = low_level_output;
|
|
||||||
|
|
||||||
low_level_init(netif);
|
|
||||||
|
|
||||||
return ERR_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ethernetif_link_poll(struct netif* netif) {
|
void ethernetif_link_poll(struct netif* netif) {
|
||||||
struct ethernetif* ethernetif = netif->state;
|
if (!g_link_interrupt_flag) {
|
||||||
static uint32_t last_poll_time = 0;
|
|
||||||
uint32_t now = millis();
|
|
||||||
|
|
||||||
// every 500ms
|
|
||||||
if (now - last_poll_time < 500) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
last_poll_time = now;
|
g_link_interrupt_flag = false;
|
||||||
|
|
||||||
uint16_t bmsr = ReadPHYReg(PHY_BMSR);
|
uint16_t bmsr = ReadPHYReg(PHY_BMSR);
|
||||||
|
|
||||||
if (bmsr & PHY_Linked_Status) {
|
if (bmsr & PHY_BMSR_LINK_STATUS) {
|
||||||
if (!netif_is_link_up(netif)) {
|
if (!netif_is_link_up(netif)) {
|
||||||
printf("Link is UP (10M-FD Mode)\n");
|
printf("Link is UP\n");
|
||||||
|
ETH10M->MACON2 |= RB_ETH_MACON2_FULDPX;
|
||||||
ETH10M->ERXST = (uint32_t)ethernetif->DMARxDescToGet->Buffer1Addr;
|
|
||||||
ETH10M->ECON1 |= RB_ETH_ECON1_RXEN;
|
|
||||||
|
|
||||||
netif_set_link_up(netif);
|
netif_set_link_up(netif);
|
||||||
g_rx_error_cnt = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// polarity check
|
|
||||||
// https://github.com/openwch/ch32v20x/blob/main/EVT/EXAM/ETH/NetLib/eth_driver.c#L262
|
|
||||||
if (g_rx_error_cnt > 5) {
|
|
||||||
printf("RX error count: %d. Flipping PHY polarity\n", g_rx_error_cnt);
|
|
||||||
uint16_t mdix_val = ReadPHYReg(PHY_MDIX);
|
|
||||||
if ((mdix_val >> 2) & 0x01) {
|
|
||||||
mdix_val &= ~(3 << 2); // normal
|
|
||||||
} else {
|
|
||||||
mdix_val |= (1 << 2); // reverse
|
|
||||||
}
|
|
||||||
WritePHYReg(PHY_MDIX, mdix_val);
|
|
||||||
g_rx_error_cnt = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (netif_is_link_up(netif)) {
|
if (netif_is_link_up(netif)) {
|
||||||
printf("Link is DOWN\n");
|
printf("Link is DOWN\n");
|
||||||
netif_set_link_down(netif);
|
netif_set_link_down(netif);
|
||||||
ETH10M->ECON1 &= ~RB_ETH_ECON1_RXEN;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ETH_IRQHandler(void) __attribute__((interrupt));
|
||||||
|
void ETH_IRQHandler(void) {
|
||||||
|
uint32_t flags = ETH10M->EIR;
|
||||||
|
|
||||||
|
if (flags & RB_ETH_EIR_TXIF) {
|
||||||
|
DMATxDscrTab[0].Status &= ~ETH_DMATxDesc_OWN;
|
||||||
|
ETH10M->EIR = RB_ETH_EIR_TXIF;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags & RB_ETH_EIR_LINKIF) {
|
||||||
|
g_link_interrupt_flag = true;
|
||||||
|
ETH10M->EIR = RB_ETH_EIR_LINKIF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void WritePHYReg(uint8_t reg_add, uint16_t reg_val) {
|
void WritePHYReg(uint8_t reg_add, uint16_t reg_val) {
|
||||||
R32_ETH_MIWR = (reg_add & RB_ETH_MIREGADR_MIRDL) | (1 << 8) | (reg_val << 16);
|
R32_ETH_MIWR = (reg_add & RB_ETH_MIREGADR_MIRDL) | (1 << 8) | (reg_val << 16);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ void run_tx_test(void);
|
|||||||
void WritePHYReg(uint8_t reg_add, uint16_t reg_val);
|
void WritePHYReg(uint8_t reg_add, uint16_t reg_val);
|
||||||
uint16_t ReadPHYReg(uint8_t reg_add);
|
uint16_t ReadPHYReg(uint8_t reg_add);
|
||||||
|
|
||||||
|
#define ROM_CFG_USERADR_ID 0x1FFFF7E8
|
||||||
|
|
||||||
#define PHY_BMCR_FORCE_10BASE_T_HD ((uint16_t)0x0000)
|
#define PHY_BMCR_FORCE_10BASE_T_HD ((uint16_t)0x0000)
|
||||||
#define PHY_BMCR_FORCE_10BASE_T_FD ((uint16_t)0x0100) // 10M, Full Duplex
|
#define PHY_BMCR_FORCE_10BASE_T_FD ((uint16_t)0x0100) // 10M, Full Duplex
|
||||||
|
|
||||||
@@ -15,55 +17,93 @@ uint16_t ReadPHYReg(uint8_t reg_add);
|
|||||||
#define PHY_ANAR_10BASET_HD 0x0020 // 10M Half-Duplex
|
#define PHY_ANAR_10BASET_HD 0x0020 // 10M Half-Duplex
|
||||||
#define PHY_ANAR_10BASET_FD 0x0040 // 10M Full-Duplex
|
#define PHY_ANAR_10BASET_FD 0x0040 // 10M Full-Duplex
|
||||||
|
|
||||||
|
#define PHY_PHYSR 0x10 // PHY Status Register
|
||||||
|
|
||||||
|
// Bits for CH32V20x PHYSR
|
||||||
|
#define PHY_PHYSR_FULL_10M (1 << 2)
|
||||||
|
|
||||||
#define PHY_BMCR_RESET ((uint16_t)0x8000) // Reset PHY
|
#define PHY_BMCR_RESET ((uint16_t)0x8000) // Reset PHY
|
||||||
#define PHY_BMCR_AN_ENABLE \
|
#define PHY_BMCR_AN_ENABLE \
|
||||||
((uint16_t)0x1000) // Enable Auto-Negotiation (Bit 12)
|
((uint16_t)0x1000) // Enable Auto-Negotiation (Bit 12)
|
||||||
#define PHY_BMCR_AN_RESTART \
|
#define PHY_BMCR_AN_RESTART \
|
||||||
((uint16_t)0x0200) // Restart Auto-Negotiation (Bit 9)
|
((uint16_t)0x0200) // Restart Auto-Negotiation (Bit 9)
|
||||||
|
|
||||||
|
#define PHY_BMSR_LINK_STATUS (1 << 2)
|
||||||
|
#define PHY_BMSR_AN_COMPLETE (1 << 5)
|
||||||
|
|
||||||
|
#define PHY_MDIX_PN_MASK (3 << 2) // Mask for bits [3:2] -> 0x0C
|
||||||
|
#define PHY_MDIX_PN_REVERSED \
|
||||||
|
(1 << 2) // Value for reversed polarity (01b) -> 0x04
|
||||||
|
|
||||||
/**
|
/**
|
||||||
DMA Tx Desciptor
|
DMA Tx Desciptor
|
||||||
-----------------------------------------------------------------------------------------------
|
-----------------------------------------------------------------------------------------------
|
||||||
TDES0 | OWN(31) | CTRL[30:26] | Reserved[25:24] | CTRL[23:20] | Reserved[19:17] | Status[16:0] |
|
TDES0 | OWN(31) | CTRL[30:26] | Reserved[25:24] | CTRL[23:20] |
|
||||||
|
Reserved[19:17] | Status[16:0] |
|
||||||
-----------------------------------------------------------------------------------------------
|
-----------------------------------------------------------------------------------------------
|
||||||
TDES1 | Reserved[31:29] | Buffer2 ByteCount[28:16] | Reserved[15:13] | Buffer1 ByteCount[12:0] |
|
TDES1 | Reserved[31:29] | Buffer2 ByteCount[28:16] | Reserved[15:13] | Buffer1
|
||||||
|
ByteCount[12:0] |
|
||||||
-----------------------------------------------------------------------------------------------
|
-----------------------------------------------------------------------------------------------
|
||||||
TDES2 | Buffer1 Address [31:0] |
|
TDES2 | Buffer1 Address [31:0] |
|
||||||
-----------------------------------------------------------------------------------------------
|
-----------------------------------------------------------------------------------------------
|
||||||
TDES3 | Buffer2 Address [31:0] / Next Desciptor Address [31:0] |
|
TDES3 | Buffer2 Address [31:0] / Next Desciptor Address
|
||||||
|
[31:0] |
|
||||||
------------------------------------------------------------------------------------------------
|
------------------------------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* Bit or field definition of TDES0 register (DMA Tx descriptor status
|
||||||
/* Bit or field definition of TDES0 register (DMA Tx descriptor status register)*/
|
* register)*/
|
||||||
#define ETH_DMATxDesc_OWN ((uint32_t)0x80000000) /* OWN bit: descriptor is owned by DMA engine */
|
#define ETH_DMATxDesc_OWN \
|
||||||
|
((uint32_t)0x80000000) /* OWN bit: descriptor is owned by DMA engine */
|
||||||
#define ETH_DMATxDesc_IC ((uint32_t)0x40000000) /* Interrupt on Completion */
|
#define ETH_DMATxDesc_IC ((uint32_t)0x40000000) /* Interrupt on Completion */
|
||||||
#define ETH_DMATxDesc_LS ((uint32_t)0x20000000) /* Last Segment */
|
#define ETH_DMATxDesc_LS ((uint32_t)0x20000000) /* Last Segment */
|
||||||
#define ETH_DMATxDesc_FS ((uint32_t)0x10000000) /* First Segment */
|
#define ETH_DMATxDesc_FS ((uint32_t)0x10000000) /* First Segment */
|
||||||
#define ETH_DMATxDesc_DC ((uint32_t)0x08000000) /* Disable CRC */
|
#define ETH_DMATxDesc_DC ((uint32_t)0x08000000) /* Disable CRC */
|
||||||
#define ETH_DMATxDesc_DP ((uint32_t)0x04000000) /* Disable Padding */
|
#define ETH_DMATxDesc_DP ((uint32_t)0x04000000) /* Disable Padding */
|
||||||
#define ETH_DMATxDesc_TTSE ((uint32_t)0x02000000) /* Transmit Time Stamp Enable */
|
#define ETH_DMATxDesc_TTSE \
|
||||||
#define ETH_DMATxDesc_CIC ((uint32_t)0x00C00000) /* Checksum Insertion Control: 4 cases */
|
((uint32_t)0x02000000) /* Transmit Time Stamp Enable */
|
||||||
#define ETH_DMATxDesc_CIC_ByPass ((uint32_t)0x00000000) /* Do Nothing: Checksum Engine is bypassed */
|
#define ETH_DMATxDesc_CIC \
|
||||||
#define ETH_DMATxDesc_CIC_IPV4Header ((uint32_t)0x00400000) /* IPV4 header Checksum Insertion */
|
((uint32_t)0x00C00000) /* Checksum Insertion Control: 4 cases */
|
||||||
#define ETH_DMATxDesc_CIC_TCPUDPICMP_Segment ((uint32_t)0x00800000) /* TCP/UDP/ICMP Checksum Insertion calculated over segment only */
|
#define ETH_DMATxDesc_CIC_ByPass \
|
||||||
#define ETH_DMATxDesc_CIC_TCPUDPICMP_Full ((uint32_t)0x00C00000) /* TCP/UDP/ICMP Checksum Insertion fully calculated */
|
((uint32_t)0x00000000) /* Do Nothing: Checksum Engine is bypassed */
|
||||||
|
#define ETH_DMATxDesc_CIC_IPV4Header \
|
||||||
|
((uint32_t)0x00400000) /* IPV4 header Checksum Insertion */
|
||||||
|
#define ETH_DMATxDesc_CIC_TCPUDPICMP_Segment \
|
||||||
|
((uint32_t)0x00800000) /* TCP/UDP/ICMP Checksum Insertion calculated over \
|
||||||
|
segment only */
|
||||||
|
#define ETH_DMATxDesc_CIC_TCPUDPICMP_Full \
|
||||||
|
((uint32_t)0x00C00000) /* TCP/UDP/ICMP Checksum Insertion fully calculated \
|
||||||
|
*/
|
||||||
#define ETH_DMATxDesc_TER ((uint32_t)0x00200000) /* Transmit End of Ring */
|
#define ETH_DMATxDesc_TER ((uint32_t)0x00200000) /* Transmit End of Ring */
|
||||||
#define ETH_DMATxDesc_TCH ((uint32_t)0x00100000) /* Second Address Chained */
|
#define ETH_DMATxDesc_TCH ((uint32_t)0x00100000) /* Second Address Chained */
|
||||||
#define ETH_DMATxDesc_TTSS ((uint32_t)0x00020000) /* Tx Time Stamp Status */
|
#define ETH_DMATxDesc_TTSS ((uint32_t)0x00020000) /* Tx Time Stamp Status */
|
||||||
#define ETH_DMATxDesc_IHE ((uint32_t)0x00010000) /* IP Header Error */
|
#define ETH_DMATxDesc_IHE ((uint32_t)0x00010000) /* IP Header Error */
|
||||||
#define ETH_DMATxDesc_ES ((uint32_t)0x00008000) /* Error summary: OR of the following bits: UE || ED || EC || LCO || NC || LCA || FF || JT */
|
#define ETH_DMATxDesc_ES \
|
||||||
|
((uint32_t)0x00008000) /* Error summary: OR of the following bits: UE || ED \
|
||||||
|
|| EC || LCO || NC || LCA || FF || JT */
|
||||||
#define ETH_DMATxDesc_JT ((uint32_t)0x00004000) /* Jabber Timeout */
|
#define ETH_DMATxDesc_JT ((uint32_t)0x00004000) /* Jabber Timeout */
|
||||||
#define ETH_DMATxDesc_FF ((uint32_t)0x00002000) /* Frame Flushed: DMA/MTL flushed the frame due to SW flush */
|
#define ETH_DMATxDesc_FF \
|
||||||
|
((uint32_t)0x00002000) /* Frame Flushed: DMA/MTL flushed the frame due to SW \
|
||||||
|
flush */
|
||||||
#define ETH_DMATxDesc_PCE ((uint32_t)0x00001000) /* Payload Checksum Error */
|
#define ETH_DMATxDesc_PCE ((uint32_t)0x00001000) /* Payload Checksum Error */
|
||||||
#define ETH_DMATxDesc_LCA ((uint32_t)0x00000800) /* Loss of Carrier: carrier lost during tramsmission */
|
#define ETH_DMATxDesc_LCA \
|
||||||
#define ETH_DMATxDesc_NC ((uint32_t)0x00000400) /* No Carrier: no carrier signal from the tranceiver */
|
((uint32_t)0x00000800) /* Loss of Carrier: carrier lost during tramsmission \
|
||||||
#define ETH_DMATxDesc_LCO ((uint32_t)0x00000200) /* Late Collision: transmission aborted due to collision */
|
*/
|
||||||
#define ETH_DMATxDesc_EC ((uint32_t)0x00000100) /* Excessive Collision: transmission aborted after 16 collisions */
|
#define ETH_DMATxDesc_NC \
|
||||||
|
((uint32_t)0x00000400) /* No Carrier: no carrier signal from the tranceiver \
|
||||||
|
*/
|
||||||
|
#define ETH_DMATxDesc_LCO \
|
||||||
|
((uint32_t)0x00000200) /* Late Collision: transmission aborted due to \
|
||||||
|
collision */
|
||||||
|
#define ETH_DMATxDesc_EC \
|
||||||
|
((uint32_t)0x00000100) /* Excessive Collision: transmission aborted after 16 \
|
||||||
|
collisions */
|
||||||
#define ETH_DMATxDesc_VF ((uint32_t)0x00000080) /* VLAN Frame */
|
#define ETH_DMATxDesc_VF ((uint32_t)0x00000080) /* VLAN Frame */
|
||||||
#define ETH_DMATxDesc_CC ((uint32_t)0x00000078) /* Collision Count */
|
#define ETH_DMATxDesc_CC ((uint32_t)0x00000078) /* Collision Count */
|
||||||
#define ETH_DMATxDesc_ED ((uint32_t)0x00000004) /* Excessive Deferral */
|
#define ETH_DMATxDesc_ED ((uint32_t)0x00000004) /* Excessive Deferral */
|
||||||
#define ETH_DMATxDesc_UF ((uint32_t)0x00000002) /* Underflow Error: late data arrival from the memory */
|
#define ETH_DMATxDesc_UF \
|
||||||
|
((uint32_t)0x00000002) /* Underflow Error: late data arrival from the memory \
|
||||||
|
*/
|
||||||
#define ETH_DMATxDesc_DB ((uint32_t)0x00000001) /* Deferred Bit */
|
#define ETH_DMATxDesc_DB ((uint32_t)0x00000001) /* Deferred Bit */
|
||||||
|
|
||||||
/* Field definition of TDES1 register */
|
/* Field definition of TDES1 register */
|
||||||
@@ -71,57 +111,90 @@ uint16_t ReadPHYReg(uint8_t reg_add);
|
|||||||
#define ETH_DMATxDesc_TBS1 ((uint32_t)0x00001FFF) /* Transmit Buffer1 Size */
|
#define ETH_DMATxDesc_TBS1 ((uint32_t)0x00001FFF) /* Transmit Buffer1 Size */
|
||||||
|
|
||||||
/* Field definition of TDES2 register */
|
/* Field definition of TDES2 register */
|
||||||
#define ETH_DMATxDesc_B1AP ((uint32_t)0xFFFFFFFF) /* Buffer1 Address Pointer */
|
#define ETH_DMATxDesc_B1AP ((uint32_t)0xFFFFFFFF) /* Buffer1 Address Pointer \
|
||||||
|
*/
|
||||||
|
|
||||||
/* Field definition of TDES3 register */
|
/* Field definition of TDES3 register */
|
||||||
#define ETH_DMATxDesc_B2AP ((uint32_t)0xFFFFFFFF) /* Buffer2 Address Pointer */
|
#define ETH_DMATxDesc_B2AP ((uint32_t)0xFFFFFFFF) /* Buffer2 Address Pointer \
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
DMA Rx Desciptor
|
DMA Rx Desciptor
|
||||||
---------------------------------------------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------------------------------------------
|
||||||
RDES0 | OWN(31) | Status [30:0] |
|
RDES0 | OWN(31) | Status [30:0] |
|
||||||
---------------------------------------------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------------------------------------------
|
||||||
RDES1 | CTRL(31) | Reserved[30:29] | Buffer2 ByteCount[28:16] | CTRL[15:14] | Reserved(13) | Buffer1 ByteCount[12:0] |
|
RDES1 | CTRL(31) | Reserved[30:29] | Buffer2 ByteCount[28:16] | CTRL[15:14] |
|
||||||
|
Reserved(13) | Buffer1 ByteCount[12:0] |
|
||||||
---------------------------------------------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------------------------------------------
|
||||||
RDES2 | Buffer1 Address [31:0] |
|
RDES2 | Buffer1 Address [31:0] |
|
||||||
---------------------------------------------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------------------------------------------
|
||||||
RDES3 | Buffer2 Address [31:0] / Next Desciptor Address [31:0] |
|
RDES3 | Buffer2 Address [31:0] / Next Desciptor
|
||||||
|
Address [31:0] |
|
||||||
----------------------------------------------------------------------------------------------------------------------
|
----------------------------------------------------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Bit or field definition of RDES0 register (DMA Rx descriptor status register) */
|
/* Bit or field definition of RDES0 register (DMA Rx descriptor status register)
|
||||||
#define ETH_DMARxDesc_OWN ((uint32_t)0x80000000) /* OWN bit: descriptor is owned by DMA engine */
|
*/
|
||||||
#define ETH_DMARxDesc_AFM ((uint32_t)0x40000000) /* DA Filter Fail for the rx frame */
|
#define ETH_DMARxDesc_OWN \
|
||||||
#define ETH_DMARxDesc_FL ((uint32_t)0x3FFF0000) /* Receive descriptor frame length */
|
((uint32_t)0x80000000) /* OWN bit: descriptor is owned by DMA engine */
|
||||||
#define ETH_DMARxDesc_ES ((uint32_t)0x00008000) /* Error summary: OR of the following bits: DE || OE || IPC || LC || RWT || RE || CE */
|
#define ETH_DMARxDesc_AFM \
|
||||||
#define ETH_DMARxDesc_DE ((uint32_t)0x00004000) /* Desciptor error: no more descriptors for receive frame */
|
((uint32_t)0x40000000) /* DA Filter Fail for the rx frame */
|
||||||
#define ETH_DMARxDesc_SAF ((uint32_t)0x00002000) /* SA Filter Fail for the received frame */
|
#define ETH_DMARxDesc_FL \
|
||||||
#define ETH_DMARxDesc_LE ((uint32_t)0x00001000) /* Frame size not matching with length field */
|
((uint32_t)0x3FFF0000) /* Receive descriptor frame length */
|
||||||
#define ETH_DMARxDesc_OE ((uint32_t)0x00000800) /* Overflow Error: Frame was damaged due to buffer overflow */
|
#define ETH_DMARxDesc_ES \
|
||||||
#define ETH_DMARxDesc_VLAN ((uint32_t)0x00000400) /* VLAN Tag: received frame is a VLAN frame */
|
((uint32_t)0x00008000) /* Error summary: OR of the following bits: DE || OE \
|
||||||
#define ETH_DMARxDesc_FS ((uint32_t)0x00000200) /* First descriptor of the frame */
|
|| IPC || LC || RWT || RE || CE */
|
||||||
#define ETH_DMARxDesc_LS ((uint32_t)0x00000100) /* Last descriptor of the frame */
|
#define ETH_DMARxDesc_DE \
|
||||||
#define ETH_DMARxDesc_IPV4HCE ((uint32_t)0x00000080) /* IPC Checksum Error: Rx Ipv4 header checksum error */
|
((uint32_t)0x00004000) /* Desciptor error: no more descriptors for receive \
|
||||||
#define ETH_DMARxDesc_LC ((uint32_t)0x00000040) /* Late collision occurred during reception */
|
frame */
|
||||||
#define ETH_DMARxDesc_FT ((uint32_t)0x00000020) /* Frame type - Ethernet, otherwise 802.3 */
|
#define ETH_DMARxDesc_SAF \
|
||||||
#define ETH_DMARxDesc_RWT ((uint32_t)0x00000010) /* Receive Watchdog Timeout: watchdog timer expired during reception */
|
((uint32_t)0x00002000) /* SA Filter Fail for the received frame */
|
||||||
#define ETH_DMARxDesc_RE ((uint32_t)0x00000008) /* Receive error: error reported by MII interface */
|
#define ETH_DMARxDesc_LE \
|
||||||
#define ETH_DMARxDesc_DBE ((uint32_t)0x00000004) /* Dribble bit error: frame contains non int multiple of 8 bits */
|
((uint32_t)0x00001000) /* Frame size not matching with length field */
|
||||||
|
#define ETH_DMARxDesc_OE \
|
||||||
|
((uint32_t)0x00000800) /* Overflow Error: Frame was damaged due to buffer \
|
||||||
|
overflow */
|
||||||
|
#define ETH_DMARxDesc_VLAN \
|
||||||
|
((uint32_t)0x00000400) /* VLAN Tag: received frame is a VLAN frame */
|
||||||
|
#define ETH_DMARxDesc_FS \
|
||||||
|
((uint32_t)0x00000200) /* First descriptor of the frame */
|
||||||
|
#define ETH_DMARxDesc_LS \
|
||||||
|
((uint32_t)0x00000100) /* Last descriptor of the frame */
|
||||||
|
#define ETH_DMARxDesc_IPV4HCE \
|
||||||
|
((uint32_t)0x00000080) /* IPC Checksum Error: Rx Ipv4 header checksum error \
|
||||||
|
*/
|
||||||
|
#define ETH_DMARxDesc_LC \
|
||||||
|
((uint32_t)0x00000040) /* Late collision occurred during reception */
|
||||||
|
#define ETH_DMARxDesc_FT \
|
||||||
|
((uint32_t)0x00000020) /* Frame type - Ethernet, otherwise 802.3 */
|
||||||
|
#define ETH_DMARxDesc_RWT \
|
||||||
|
((uint32_t)0x00000010) /* Receive Watchdog Timeout: watchdog timer expired \
|
||||||
|
during reception */
|
||||||
|
#define ETH_DMARxDesc_RE \
|
||||||
|
((uint32_t)0x00000008) /* Receive error: error reported by MII interface */
|
||||||
|
#define ETH_DMARxDesc_DBE \
|
||||||
|
((uint32_t)0x00000004) /* Dribble bit error: frame contains non int multiple \
|
||||||
|
of 8 bits */
|
||||||
#define ETH_DMARxDesc_CE ((uint32_t)0x00000002) /* CRC error */
|
#define ETH_DMARxDesc_CE ((uint32_t)0x00000002) /* CRC error */
|
||||||
#define ETH_DMARxDesc_MAMPCE ((uint32_t)0x00000001) /* Rx MAC Address/Payload Checksum Error: Rx MAC address matched/ Rx Payload Checksum Error */
|
#define ETH_DMARxDesc_MAMPCE \
|
||||||
|
((uint32_t)0x00000001) /* Rx MAC Address/Payload Checksum Error: Rx MAC \
|
||||||
|
address matched/ Rx Payload Checksum Error */
|
||||||
|
|
||||||
/* Bit or field definition of RDES1 register */
|
/* Bit or field definition of RDES1 register */
|
||||||
#define ETH_DMARxDesc_DIC ((uint32_t)0x80000000) /* Disable Interrupt on Completion */
|
#define ETH_DMARxDesc_DIC \
|
||||||
|
((uint32_t)0x80000000) /* Disable Interrupt on Completion */
|
||||||
#define ETH_DMARxDesc_RBS2 ((uint32_t)0x1FFF0000) /* Receive Buffer2 Size */
|
#define ETH_DMARxDesc_RBS2 ((uint32_t)0x1FFF0000) /* Receive Buffer2 Size */
|
||||||
#define ETH_DMARxDesc_RER ((uint32_t)0x00008000) /* Receive End of Ring */
|
#define ETH_DMARxDesc_RER ((uint32_t)0x00008000) /* Receive End of Ring */
|
||||||
#define ETH_DMARxDesc_RCH ((uint32_t)0x00004000) /* Second Address Chained */
|
#define ETH_DMARxDesc_RCH ((uint32_t)0x00004000) /* Second Address Chained */
|
||||||
#define ETH_DMARxDesc_RBS1 ((uint32_t)0x00001FFF) /* Receive Buffer1 Size */
|
#define ETH_DMARxDesc_RBS1 ((uint32_t)0x00001FFF) /* Receive Buffer1 Size */
|
||||||
|
|
||||||
/* Field definition of RDES2 register */
|
/* Field definition of RDES2 register */
|
||||||
#define ETH_DMARxDesc_B1AP ((uint32_t)0xFFFFFFFF) /* Buffer1 Address Pointer */
|
#define ETH_DMARxDesc_B1AP ((uint32_t)0xFFFFFFFF) /* Buffer1 Address Pointer \
|
||||||
|
*/
|
||||||
|
|
||||||
/* Field definition of RDES3 register */
|
/* Field definition of RDES3 register */
|
||||||
#define ETH_DMARxDesc_B2AP ((uint32_t)0xFFFFFFFF) /* Buffer2 Address Pointer */
|
#define ETH_DMARxDesc_B2AP ((uint32_t)0xFFFFFFFF) /* Buffer2 Address Pointer \
|
||||||
|
*/
|
||||||
|
|
||||||
#define ETH_DMARxDesc_FrameLengthShift 16
|
#define ETH_DMARxDesc_FrameLengthShift 16
|
||||||
|
|
||||||
|
|||||||
@@ -4,11 +4,11 @@
|
|||||||
#define LWIP_DEBUG 1
|
#define LWIP_DEBUG 1
|
||||||
#define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_ALL
|
#define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_ALL
|
||||||
|
|
||||||
#define UDP_DEBUG LWIP_DBG_ON
|
// #define UDP_DEBUG LWIP_DBG_ON
|
||||||
#define IP_DEBUG LWIP_DBG_ON
|
// #define IP_DEBUG LWIP_DBG_ON
|
||||||
#define DHCP_DEBUG LWIP_DBG_ON
|
#define DHCP_DEBUG LWIP_DBG_ON
|
||||||
#define NETIF_DEBUG LWIP_DBG_ON
|
#define NETIF_DEBUG LWIP_DBG_ON
|
||||||
#define ETHARP_DEBUG LWIP_DBG_ON
|
// #define ETHARP_DEBUG LWIP_DBG_ON
|
||||||
|
|
||||||
#define NO_SYS 1
|
#define NO_SYS 1
|
||||||
|
|
||||||
@@ -52,6 +52,6 @@
|
|||||||
// Statistics
|
// Statistics
|
||||||
#define LWIP_STATS 0
|
#define LWIP_STATS 0
|
||||||
|
|
||||||
#define LWIP_NETIF_LINK_CALLBACK 1
|
// #define LWIP_NETIF_LINK_CALLBACK 1
|
||||||
|
|
||||||
#endif /* __LWIPOPTS_H__ */
|
#endif /* __LWIPOPTS_H__ */
|
||||||
|
|||||||
Reference in New Issue
Block a user