From 8c7ee88332652e7e79f6c1e4baacabe2183f7e8e Mon Sep 17 00:00:00 2001 From: root Date: Tue, 2 Mar 2021 12:54:03 +0000 Subject: working, with hybrid FLL/PLL, new refclk input and support for max7219 displays, neo 5 and neo 7 and a bazillion other fixes --- app/steth.c | 314 +++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 173 insertions(+), 141 deletions(-) (limited to 'app/steth.c') diff --git a/app/steth.c b/app/steth.c index 5b94e1d..9d56529 100644 --- a/app/steth.c +++ b/app/steth.c @@ -20,87 +20,131 @@ extern uint32_t TxBD; extern uint32_t RxBD; -#define FOO(a) \ - do { static uint32_t w; \ - uint32_t v=a; \ - if (v!=w) {\ - printf (" " #a": %08x (%08x +%08x -%08x)\r\n", \ - (unsigned) v,(unsigned) (v^w),(unsigned) ((v^w) &v),(unsigned) ((v^w)&w)); \ - }\ - w=v; \ - } while (0) +static void eth_smi_transact_wtimeo (void) +{ + int timeout = 200; + /* Begin transaction. */ + ETH_MACMIIAR |= ETH_MACMIIAR_MB; + /* Wait for not busy. */ + while (ETH_MACMIIAR & ETH_MACMIIAR_MB) { + if (! (timeout--)) return; -void steth_calculate_mac(void) + delay_us (10); + } +} + +static void eth_smi_write_wtimeo (uint8_t phy, uint8_t reg, uint16_t data) { - uint32_t uid[3]; - uint8_t *ptr; - unsigned i; - desig_get_unique_id (uid); + /* Write operation MW=1*/ + ETH_MACMIIAR = (ETH_MACMIIAR & ETH_MACMIIAR_CR) | /* save clocks */ + (phy << ETH_MACMIIAR_PA_SHIFT) | + (reg << ETH_MACMIIAR_MR_SHIFT) | + ETH_MACMIIAR_MW; - ptr=(uint8_t *)uid; + ETH_MACMIIDR = data & ETH_MACMIIDR_MD; - for (i=0;inext) return ERR_IF; - while (!eth_tx (p->payload, p->len)); + + while (!eth_tx (p->payload, p->len)) { + delay_us (10); + + if (! (tries--)) return ERR_IF; + } + return ERR_OK; } + +static bool eth_rx_ptp (uint8_t *ppkt, uint32_t *len, uint32_t maxlen, uint64_t *tstamp) +{ + bool fs = false; + bool ls = false; + bool overrun = false; + uint32_t l = 0; + + while (! (ETH_DES0 (RxBD) & ETH_RDES0_OWN) && !ls) { + l = (ETH_DES0 (RxBD) & ETH_RDES0_FL) >> ETH_RDES0_FL_SHIFT; + + fs |= ETH_DES0 (RxBD) & ETH_RDES0_FS; + ls |= ETH_DES0 (RxBD) & ETH_RDES0_LS; + /* frame buffer overrun ?*/ + overrun |= fs && (maxlen < l); + + if (fs && !overrun) { + memcpy (ppkt, (void *)ETH_DES2 (RxBD), l); + ppkt += l; + *len += l; + maxlen -= l; + } + + *tstamp = ptp_to_u64 (ETH_DES6 (RxBD), ETH_DES7 (RxBD)); + + ETH_DES0 (RxBD) = ETH_RDES0_OWN; + RxBD = ETH_DES3 (RxBD); + } + + if (ETH_DMASR & ETH_DMASR_RBUS) { + ETH_DMASR = ETH_DMASR_RBUS; + ETH_DMARPDR = 0; + } + + return fs && ls && !overrun; +} + + static err_t steth_rx (void) { struct pbuf *p; uint32_t len; - p = pbuf_alloc (PBUF_RAW, MTU, PBUF_POOL); if (!p) return ERR_MEM; len = 0; - if (!eth_rx (p->payload, &len, MTU)) { + p->ptp_timestamp = 0; //get_ptp(); + + if (!eth_rx_ptp (p->payload, &len, MTU, &p->ptp_timestamp)) { pbuf_free (p); return ERR_IF; } pbuf_realloc (p, len); + return if0.input (p, &if0); } @@ -239,36 +331,6 @@ static void my_eth_init (uint8_t phy, enum eth_clk clock) } - -#if 0 -static void phy_set_ignore_address (void) -{ - unsigned i; - - i = 0; - - while (eth_smi_read (PHY0, 0) == 0xffff) { - delay_us (1000); - i++; - - if (i > 10) break; - } - - eth_smi_write (PHY, 0x11, 0x8); - - i = 0; - - while (eth_smi_read (PHY1, 0) == 0xffff) { - delay_us (1000); - i++; - - if (i > 10) break; - } - - eth_smi_write (PHY1, 0x11, 0x8); -} -#endif - static void eth_reset (void) { unsigned i; @@ -286,18 +348,6 @@ static void eth_reset (void) rcc_periph_reset_release (RST_ETHMAC); -#ifdef NRST -#if 0 - delay_us (1000); - CLEAR (NRST); - delay_us (1); - SET (NRST); - delay_us (1000); -#endif -#endif - - - TRACE; ETH_DMABMR |= ETH_DMABMR_SR; i = 0; @@ -306,20 +356,18 @@ static void eth_reset (void) delay_us (1000); i++; - if (i > 1000) { + if (i > 10) { printf ("No 50MHz clock to ethernet MAC\n"); return; } } /*MDC = HCLK / 102 (0b100) => 1.6MHz */ - TRACE; - my_eth_init (PHY, ETH_CLK_150_168MHZ); + //phy_set_ignore_address(); - TRACE; - phy_stat(); + phy_debug(); eth_set_mac (sa); eth_desc_init (eth_buf, TX_BUFS, RX_BUFS, FRAME_SZ, FRAME_SZ, 1); @@ -328,19 +376,15 @@ static void eth_reset (void) eth_irq_enable (ETH_DMAIER_NISE); eth_irq_enable (ETH_DMAIER_RIE); eth_irq_enable (ETH_DMASR_TS); - - } static void eth_start_an (void) { printf ("starting autonegociation\r\n"); - eth_smi_write (PHY, PHY_REG_ANTX, 0x1e1); - phy_autoneg_enable (PHY); + eth_smi_write_wtimeo (PHY, PHY_REG_ANTX, 0x1e1); + phy_autoneg_enable_wtimeo (PHY); } - - void steth_init (void) { @@ -393,37 +437,23 @@ steth_init (void) MAP_AF_100 (RXD1, GPIO_AF11); - /* The switch to RMII has be done with steth under reset, with no clock */ - eth_reset(); - - phy_stat(); - mac_stat(); - - - - -#if 0 - eth_smi_write (PHY, PHY_REG_BCR, 0x2100); - printf ("Waiting for link\r\n"); - - while (!phy_link_isup (phy)) { - phy_stat(); - delay_ms (1000); - } - -#endif + phy_debug(); + eth_debug(); eth_start_an(); nvic_enable_irq (NVIC_ETH_IRQ); + /* Fire up timestamping hardware */ - ready++; - + ETH_PTPTSCR |= ETH_PTPTSCR_TSE | ETH_PTPTSCR_TSSARFE; + ETH_PTPTSCR &= ~ETH_PTPTSCR_TSFCU; + ETH_PTPSSIR = 1; + ready++; } @@ -438,27 +468,28 @@ static void eth_stop (void) void steth_slow_tick (void) { - phy_stat(); + //printf("eth slow tick an_clock=%d\r\n",an_clock); + + phy_debug(); + #if 0 - mac_stat(); + eth_debug(); #endif if (!ready) return; an_happy = phy_link_an_done (PHY); - if ((!phy_link_isup (PHY) || !an_happy) && running) { + if ((!phy_link_isup_wtimeo (PHY) || !an_happy) && running) { printf ("stopping nic\r\n"); //eth_reset(); ETH_MACCR |= ETH_MACCR_RD; - running = 0; - } - if (!phy_link_isup (PHY) && an_happy) { + if (!phy_link_isup_wtimeo (PHY) && an_happy) { eth_start_an(); an_clock = 0; } @@ -475,11 +506,11 @@ void steth_slow_tick (void) an_clock = 0; - if (phy_link_isup (PHY) && an_happy && !running) { + if (phy_link_isup_wtimeo (PHY) && an_happy && !running) { printf ("autonegociation done\r\n"); printf ("phy link status %x\r\n", phy_link_status (PHY)); - switch (phy_link_status (PHY)) { + switch (phy_link_status_wtimeo (PHY)) { case LINK_HD_10M: TRACE; break; @@ -496,11 +527,12 @@ void steth_slow_tick (void) ETH_MACCR &= ~ETH_MACCR_RD; eth_start(); + + printf ("starting nic\r\n"); running++; } - - + // printf("end slow tick\r\n"); } -- cgit v1.2.3