diff --git a/.vscode/settings.json b/.vscode/settings.json index 238bb1e..5d16f79 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -18,6 +18,23 @@ "dhcp.h": "c", "netif.h": "c", "ch32v307gigabit.h": "c", - "stats.h": "c" + "stats.h": "c", + "bitset": "c", + "forward_list": "c", + "functional": "c", + "format": "c", + "fstream": "c", + "istream": "c", + "ranges": "c", + "streambuf": "c", + "variant": "c", + "__hash_table": "c", + "__tree": "c", + "deque": "c", + "iterator": "c", + "list": "c", + "locale": "c", + "regex": "c", + "vector": "c" } } \ No newline at end of file diff --git a/ch32fun b/ch32fun index 57b2ad6..08885a5 160000 --- a/ch32fun +++ b/ch32fun @@ -1 +1 @@ -Subproject commit 57b2ad6b56ffe25be2ef0903980e8b58f2b3fd9f +Subproject commit 08885a5ea4553f783b60ae9efb76676b86af85f4 diff --git a/main.c b/main.c index d52b38e..0304042 100644 --- a/main.c +++ b/main.c @@ -24,6 +24,8 @@ #define PREDIV1_DIVISOR 4 #define PLL_MULTIPLIER 15 +#define STATS_PRINT_INTERVAL_MS 10000 + struct netif g_netif; int clock_init(void); @@ -115,6 +117,30 @@ void lwip_stack_init(void) { dhcp_start(&g_netif); } +#if LWIP_STATS + +void ethernetif_print_stats(void) { + printf("\n# Ethernet stats\n"); + printf("Link Layer:\n"); + printf(" TX: %u packets, %u errors, %u drops\n", lwip_stats.link.xmit, + lwip_stats.link.err, lwip_stats.link.drop); + printf(" RX: %u packets\n", lwip_stats.link.recv); + printf(" Errors: CRC=%u, Len=%u, Mem=%u\n", lwip_stats.link.chkerr, + lwip_stats.link.lenerr, lwip_stats.link.memerr); + +#if MIB2_STATS + printf("\nMIB-2 Stats:\n"); + printf(" In Octets: %u\n", (uint32_t)lwip_stats.mib2.ifinoctets); + printf(" Out Octets: %u\n", (uint32_t)lwip_stats.mib2.ifoutoctets); + printf(" In Errors: %u, Discards: %u\n", lwip_stats.mib2.ifinerrors, + lwip_stats.mib2.ifindiscards); + printf(" Out Errors: %u, Discards: %u\n", lwip_stats.mib2.ifouterrors, + lwip_stats.mib2.ifoutdiscards); +#endif +} + +#endif // LWIP_STATS + int main() { SystemInit(); @@ -129,6 +155,7 @@ int main() { uint32_t last_led_toggle_time = 0; uint32_t last_link_poll_time = 0; + uint32_t last_stats_print_time = 0; int led_state = 0; while (1) { @@ -140,6 +167,13 @@ int main() { last_link_poll_time = millis(); } +#if LWIP_STATS + if (millis() - last_stats_print_time > STATS_PRINT_INTERVAL_MS) { + ethernetif_print_stats(); + last_stats_print_time = millis(); + } +#endif + uint32_t now = millis(); if (now - last_led_toggle_time > LED_TOGGLE_INTERVAL_MS) { if (led_state) { diff --git a/port/ethernetif.c b/port/ethernetif.c index e55418c..6867232 100644 --- a/port/ethernetif.c +++ b/port/ethernetif.c @@ -15,7 +15,6 @@ #define ETH_RXBUFNB 4 #define ETH_TXBUFNB 1 -#define ETH_MAX_PACKET_SIZE 1520 #define ETH_RX_BUF_SZE ETH_MAX_PACKET_SIZE #define ETH_TX_BUF_SZE ETH_MAX_PACKET_SIZE @@ -30,6 +29,7 @@ __attribute__((aligned(4))) uint8_t MACRxBuf[ETH_RXBUFNB * ETH_RX_BUF_SZE]; __attribute__((aligned(4))) uint8_t MACTxBuf[ETH_TXBUFNB * ETH_TX_BUF_SZE]; static volatile bool g_link_interrupt_flag = false; +static struct ethernetif eth_state; static void low_level_init(struct netif* netif); static err_t low_level_output(struct netif* netif, struct pbuf* p); @@ -46,17 +46,11 @@ static void eth_get_mac_in_uc(uint8_t* mac) { } err_t ethernetif_init(struct netif* netif) { - struct ethernetif* 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-ch32"; #endif - netif->state = ethernetif; + netif->state = ð_state; netif->name[0] = IFNAME0; netif->name[1] = IFNAME1; @@ -66,19 +60,11 @@ err_t ethernetif_init(struct netif* netif) { 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); + eth_get_mac_in_uc(netif->hwaddr); - 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]; + printf("MAC Address: %02X:%02X:%02X:%02X:%02X:%02X\n", netif->hwaddr[0], + netif->hwaddr[1], netif->hwaddr[2], netif->hwaddr[3], netif->hwaddr[4], + netif->hwaddr[5]); netif->mtu = 1500; netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP; @@ -93,15 +79,15 @@ static void low_level_init(struct netif* netif) { // clocks RCC->APB2PCENR |= RCC_APB2Periph_AFIO; - RCC->CFGR0 = (RCC->CFGR0 & ~((uint32_t)1 << 28)) | (RCC_ETHCLK_Div2 << 28); + RCC->CFGR0 |= RCC_ETHPRE; // div 2 EXTEN->EXTEN_CTR |= EXTEN_ETH_10M_EN; - // mac reset - ETH10M->ECON1 |= (RB_ETH_ECON1_TXRST | RB_ETH_ECON1_RXRST); - ETH10M->ECON1 &= ~(RB_ETH_ECON1_TXRST | RB_ETH_ECON1_RXRST); + // reset mac rx and tx + ETH10M->ECON1 = RB_ETH_ECON1_TXRST | RB_ETH_ECON1_RXRST; + ETH10M->ECON1 = 0; // mac regs - ETH10M->ERXFON = RB_ETH_ERXFCON_BCEN | RB_ETH_ERXFCON_MCEN; + ETH10M->ERXFCON = 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; @@ -114,43 +100,56 @@ static void low_level_init(struct netif* netif) { R8_ETH_MAADRL6 = netif->hwaddr[0]; // PHY analog block - ETH10M->ECON2 = (ETH10M->ECON2 & ~(0x07 << 1)) | (5 << 1); + ETH10M->ECON2 = RB_ETH_ECON2_DEFAULT; - // DMA descriptors - ethernetif->DMATxDescToSet = &DMATxDscrTab[0]; - DMATxDscrTab[0].Status = 0; - DMATxDscrTab[0].Buffer1Addr = (uint32_t)MACTxBuf; - DMATxDscrTab[0].Buffer2NextDescAddr = (uint32_t)&DMATxDscrTab[0]; - - ethernetif->DMARxDescToGet = &DMARxDscrTab[0]; - for (int i = 0; i < ETH_RXBUFNB; i++) { - DMARxDscrTab[i].Status = 0; - DMARxDscrTab[i].Buffer1Addr = (uint32_t)(&MACRxBuf[i * ETH_RX_BUF_SZE]); - DMARxDscrTab[i].Buffer2NextDescAddr = - (uint32_t)(&DMARxDscrTab[(i + 1) % ETH_RXBUFNB]); + // init TX descriptors + ethernetif->DMATxDescToSet = DMATxDscrTab; + for (int i = 0; i < ETH_TXBUFNB; i++) { + DMATxDscrTab[i].Status = 0; + DMATxDscrTab[i].Buffer1Addr = (uint32_t)&MACTxBuf[i * ETH_TX_BUF_SZE]; + DMATxDscrTab[i].Buffer2NextDescAddr = + (uint32_t)&DMATxDscrTab[(i + 1) % ETH_TXBUFNB]; } - ETH10M->ERXST = (uint32_t)ethernetif->DMARxDescToGet->Buffer1Addr; - ETH10M->ECON1 |= RB_ETH_ECON1_RXEN; + // init RX descriptors + ethernetif->DMARxDescToGet = DMARxDscrTab; + for (int i = 0; i < ETH_RXBUFNB; i++) { + DMARxDscrTab[i].Status = 0; + DMARxDscrTab[i].Buffer1Addr = (uint32_t)&MACRxBuf[i * ETH_RX_BUF_SZE]; + DMARxDscrTab[i].Buffer2NextDescAddr = + (uint32_t)&DMARxDscrTab[(i + 1) % ETH_RXBUFNB]; + } + + // set RX buffer start and enable receiver + ETH10M->ERXST = 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_FULL_DUPLEX); + + ETH10M->EIR = 0xFF; // clear all interrupt flags + ETH10M->EIE = RB_ETH_EIE_INTIE | RB_ETH_EIE_TXIE | RB_ETH_EIE_LINKIE | + RB_ETH_EIE_TXERIE | RB_ETH_EIE_RXERIE | RB_ETH_EIE_R_EN50; - ETH10M->EIE = RB_ETH_EIE_INTIE | RB_ETH_EIE_TXIE | RB_ETH_EIE_LINKIE; - ETH10M->EIR = 0xFF; NVIC_EnableIRQ(ETH_IRQn); printf("low_level_init: done\n"); } static err_t low_level_output(struct netif* netif, struct pbuf* p) { - if (DMATxDscrTab[0].Status & ETH_DMATxDesc_OWN) return ERR_BUF; + if (DMATxDscrTab[0].Status & ETH_DMATxDesc_OWN) { +#if LWIP_STATS + LINK_STATS_INC(link.drop); +#endif + return ERR_BUF; + } uint32_t len = 0; uint8_t* tx_buf_ptr = (uint8_t*)DMATxDscrTab[0].Buffer1Addr; + for (struct pbuf* q = p; q != NULL; q = q->next) { memcpy(&tx_buf_ptr[len], q->payload, q->len); len += q->len; @@ -161,41 +160,61 @@ static err_t low_level_output(struct netif* netif, struct pbuf* p) { DMATxDscrTab[0].Status |= ETH_DMATxDesc_OWN; ETH10M->ECON1 |= RB_ETH_ECON1_TXRTS; +#if LWIP_STATS + LINK_STATS_INC(link.xmit); +#endif MIB2_STATS_NETIF_ADD(netif, ifoutoctets, len); + return ERR_OK; } static struct pbuf* low_level_input(struct netif* netif) { struct ethernetif* ethernetif = netif->state; - uint16_t len; - uint8_t* current_rx_buffer_ptr; - if ((ETH10M->EIR & RB_ETH_EIR_RXIF) == 0) return NULL; + if (!(ETH10M->EIR & RB_ETH_EIR_RXIF)) { + return NULL; + } - len = ETH10M->ERXLN; - current_rx_buffer_ptr = (uint8_t*)ethernetif->DMARxDescToGet->Buffer1Addr; + uint16_t len = ETH10M->ERXLN; + if (len < MIN_ETH_FRAME_SIZE || len > ETH_MAX_PACKET_SIZE) { +#if LWIP_STATS + LINK_STATS_INC(link.lenerr); +#endif + ETH10M->EIR = RB_ETH_EIR_RXIF; + ETH10M->ECON1 |= RB_ETH_ECON1_RXEN; + return NULL; + } + + uint8_t* current_rx_buffer_ptr = + (uint8_t*)ethernetif->DMARxDescToGet->Buffer1Addr; + + struct pbuf* p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL); + if (p != NULL) { + uint32_t offset = 0; + for (struct pbuf* q = p; q != NULL; q = q->next) { + memcpy(q->payload, current_rx_buffer_ptr + offset, q->len); + offset += q->len; + } +#if LWIP_STATS + LINK_STATS_INC(link.recv); +#endif + MIB2_STATS_NETIF_ADD(netif, ifinoctets, len); + } else { +#if LWIP_STATS + LINK_STATS_INC(link.memerr); + LINK_STATS_INC(link.drop); +#endif + MIB2_STATS_NETIF_INC(netif, ifindiscards); + } + + // move to next descriptor ethernetif->DMARxDescToGet = (ETH_DMADESCTypeDef*)ethernetif->DMARxDescToGet->Buffer2NextDescAddr; ETH10M->ERXST = (uint32_t)ethernetif->DMARxDescToGet->Buffer1Addr; + ETH10M->EIR = RB_ETH_EIR_RXIF; ETH10M->ECON1 |= RB_ETH_ECON1_RXEN; - struct pbuf* p = NULL; - if (len > 0) { - p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL); - if (p != NULL) { - uint32_t bytes_copied = 0; - for (struct pbuf* q = p; q != NULL; q = q->next) { - memcpy(q->payload, current_rx_buffer_ptr + bytes_copied, q->len); - bytes_copied += q->len; - } - MIB2_STATS_NETIF_ADD(netif, ifinoctets, len); - } else { - MIB2_STATS_NETIF_INC(netif, ifindiscards); - } - } - - ETH10M->EIR = RB_ETH_EIR_RXIF; return p; } @@ -209,11 +228,11 @@ void ethernetif_input(struct netif* netif) { } void ethernetif_link_poll(struct netif* netif) { - if (!g_link_interrupt_flag) { - return; - } + if (!g_link_interrupt_flag) return; g_link_interrupt_flag = false; + // supposedly, first read latches link status 2nd get cur val + (void)ReadPHYReg(PHY_BMSR); uint16_t bmsr = ReadPHYReg(PHY_BMSR); if (bmsr & PHY_BMSR_LINK_STATUS) { @@ -230,7 +249,7 @@ void ethernetif_link_poll(struct netif* netif) { } } -void ETH_IRQHandler(void) __attribute__((interrupt)); +void ETH_IRQHandler(void) __attribute__((interrupt)) __attribute__((used)); void ETH_IRQHandler(void) { uint32_t flags = ETH10M->EIR; @@ -239,6 +258,22 @@ void ETH_IRQHandler(void) { ETH10M->EIR = RB_ETH_EIR_TXIF; } + if (flags & RB_ETH_EIR_TXERIF) { + DMATxDscrTab[0].Status &= ~ETH_DMATxDesc_OWN; + ETH10M->EIR = RB_ETH_EIR_TXERIF; +#if LWIP_STATS + LINK_STATS_INC(link.err); +#endif + } + + if (flags & RB_ETH_EIR_RXERIF) { + ETH10M->EIR = RB_ETH_EIR_RXERIF; + ETH10M->ECON1 |= RB_ETH_ECON1_RXEN; +#if LWIP_STATS + LINK_STATS_INC(link.err); +#endif + } + if (flags & RB_ETH_EIR_LINKIF) { g_link_interrupt_flag = true; ETH10M->EIR = RB_ETH_EIR_LINKIF; @@ -246,7 +281,8 @@ void ETH_IRQHandler(void) { } 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_MASK) | RB_ETH_MIWR_MIIWR | + RB_ETH_MIWR_DATA_SHIFT; } uint16_t ReadPHYReg(uint8_t reg_add) { diff --git a/port/ethernetif.h b/port/ethernetif.h index 9a50f1f..d3d00e7 100644 --- a/port/ethernetif.h +++ b/port/ethernetif.h @@ -8,196 +8,22 @@ void run_tx_test(void); void WritePHYReg(uint8_t reg_add, uint16_t reg_val); 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_FD ((uint16_t)0x0100) // 10M, Full Duplex - -#define PHY_ANAR_SELECTOR_FIELD 0x0001 // Selector for 802.3 -#define PHY_ANAR_10BASET_HD 0x0020 // 10M Half-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_AN_ENABLE \ - ((uint16_t)0x1000) // Enable Auto-Negotiation (Bit 12) -#define PHY_BMCR_AN_RESTART \ - ((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 - ----------------------------------------------------------------------------------------------- - 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] | - ----------------------------------------------------------------------------------------------- - TDES2 | Buffer1 Address [31:0] | - ----------------------------------------------------------------------------------------------- - TDES3 | Buffer2 Address [31:0] / Next Desciptor Address - [31:0] | - ------------------------------------------------------------------------------------------------ -*/ - -/* Bit or field definition of TDES0 register (DMA Tx descriptor status - * register)*/ -#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_LS ((uint32_t)0x20000000) /* Last Segment */ -#define ETH_DMATxDesc_FS ((uint32_t)0x10000000) /* First Segment */ -#define ETH_DMATxDesc_DC ((uint32_t)0x08000000) /* Disable CRC */ -#define ETH_DMATxDesc_DP ((uint32_t)0x04000000) /* Disable Padding */ -#define ETH_DMATxDesc_TTSE \ - ((uint32_t)0x02000000) /* Transmit Time Stamp Enable */ -#define ETH_DMATxDesc_CIC \ - ((uint32_t)0x00C00000) /* Checksum Insertion Control: 4 cases */ -#define ETH_DMATxDesc_CIC_ByPass \ - ((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_TCH ((uint32_t)0x00100000) /* Second Address Chained */ -#define ETH_DMATxDesc_TTSS ((uint32_t)0x00020000) /* Tx Time Stamp Status */ -#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_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_PCE ((uint32_t)0x00001000) /* Payload Checksum Error */ -#define ETH_DMATxDesc_LCA \ - ((uint32_t)0x00000800) /* Loss of Carrier: carrier lost during tramsmission \ - */ -#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_CC ((uint32_t)0x00000078) /* Collision Count */ -#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_DB ((uint32_t)0x00000001) /* Deferred Bit */ - -/* Field definition of TDES1 register */ -#define ETH_DMATxDesc_TBS2 ((uint32_t)0x1FFF0000) /* Transmit Buffer2 Size */ -#define ETH_DMATxDesc_TBS1 ((uint32_t)0x00001FFF) /* Transmit Buffer1 Size */ - -/* Field definition of TDES2 register */ -#define ETH_DMATxDesc_B1AP ((uint32_t)0xFFFFFFFF) /* Buffer1 Address Pointer \ - */ - -/* Field definition of TDES3 register */ -#define ETH_DMATxDesc_B2AP ((uint32_t)0xFFFFFFFF) /* Buffer2 Address Pointer \ - */ - -/** - DMA Rx Desciptor - --------------------------------------------------------------------------------------------------------------------- - 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] | - --------------------------------------------------------------------------------------------------------------------- - RDES2 | Buffer1 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) - */ -#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_FL \ - ((uint32_t)0x3FFF0000) /* Receive descriptor frame length */ -#define ETH_DMARxDesc_ES \ - ((uint32_t)0x00008000) /* Error summary: OR of the following bits: DE || OE \ - || IPC || LC || RWT || RE || CE */ -#define ETH_DMARxDesc_DE \ - ((uint32_t)0x00004000) /* Desciptor error: no more descriptors for receive \ - frame */ -#define ETH_DMARxDesc_SAF \ - ((uint32_t)0x00002000) /* SA Filter Fail for the received frame */ -#define ETH_DMARxDesc_LE \ - ((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_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 */ -#define ETH_DMARxDesc_DIC \ - ((uint32_t)0x80000000) /* Disable Interrupt on Completion */ -#define ETH_DMARxDesc_RBS2 ((uint32_t)0x1FFF0000) /* Receive Buffer2 Size */ -#define ETH_DMARxDesc_RER ((uint32_t)0x00008000) /* Receive End of Ring */ -#define ETH_DMARxDesc_RCH ((uint32_t)0x00004000) /* Second Address Chained */ -#define ETH_DMARxDesc_RBS1 ((uint32_t)0x00001FFF) /* Receive Buffer1 Size */ - -/* Field definition of RDES2 register */ -#define ETH_DMARxDesc_B1AP ((uint32_t)0xFFFFFFFF) /* Buffer1 Address Pointer \ - */ - -/* Field definition of RDES3 register */ -#define ETH_DMARxDesc_B2AP ((uint32_t)0xFFFFFFFF) /* Buffer2 Address Pointer \ - */ +#define ROM_CFG_USERADR_ID 0x1FFFF7E8 #define ETH_DMARxDesc_FrameLengthShift 16 +#define ETH_MAX_PACKET_SIZE \ + 1536 /* ETH_HEADER + VLAN_TAG + MAX_ETH_PAYLOAD + ETH_CRC */ +#define ETH_HEADER \ + 14 /* 6 byte Dest addr, 6 byte Src addr, 2 byte length/type \ + */ +#define ETH_CRC 4 /* Ethernet CRC */ +#define ETH_EXTRA 2 /* Extra bytes in some cases */ +#define VLAN_TAG 4 /* optional 802.1q VLAN Tag */ +#define MIN_ETH_PAYLOAD 46 /* Minimum Ethernet payload size */ +#define MAX_ETH_PAYLOAD 1500 /* Maximum Ethernet payload size */ +#define MIN_ETH_FRAME_SIZE (ETH_HEADER + MIN_ETH_PAYLOAD) /* 60 bytes */ + typedef struct { uint32_t volatile Status; /* Status */ uint32_t ControlBufferSize; /* Control and Buffer1, Buffer2 lengths */ diff --git a/port/lwipopts.h b/port/lwipopts.h index ee4765c..85c0d31 100644 --- a/port/lwipopts.h +++ b/port/lwipopts.h @@ -1,13 +1,13 @@ #ifndef __LWIPOPTS_H__ #define __LWIPOPTS_H__ -#define LWIP_DEBUG 1 -#define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_ALL +// #define LWIP_DEBUG 1 +// #define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_ALL // #define UDP_DEBUG LWIP_DBG_ON // #define IP_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 NO_SYS 1 @@ -20,8 +20,8 @@ #define MEM_SIZE (10 * 1024) // 4KB of RAM for lwIP heap // Pbuf options -#define PBUF_POOL_SIZE 8 -#define PBUF_POOL_BUFSIZE 1524 +#define PBUF_POOL_SIZE 24 // Enough for bursts +#define PBUF_POOL_BUFSIZE 600 // ~500 byte typical packet + header // TCP options #define LWIP_TCP 1 @@ -50,7 +50,8 @@ #define LWIP_SOCKET 0 // Statistics -#define LWIP_STATS 0 +#define LWIP_STATS 1 +#define LINK_STATS 1 #define LWIP_HTTPD 1 // Use a read-only filesystem populated by makefsdata @@ -62,4 +63,6 @@ // #define LWIP_NETIF_LINK_CALLBACK 1 #define LWIP_NETIF_STATUS_CALLBACK 1 +#define LWIP_SUPPORT_CUSTOM_PBUF 1 + #endif /* __LWIPOPTS_H__ */