@@ -18507,6 +18507,243 @@ struct mg_tcpip_driver mg_tcpip_driver_tm4c = {mg_tcpip_driver_tm4c_init,
18507
18507
mg_tcpip_driver_tm4c_up};
18508
18508
#endif
18509
18509
18510
+ #ifdef MG_ENABLE_LINES
18511
+ #line 1 "src/drivers/tms570.c"
18512
+ #endif
18513
+
18514
+
18515
+ #if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_TMS570) && MG_ENABLE_DRIVER_TMS570
18516
+ struct tms570_emac_ctrl {
18517
+ volatile uint32_t REVID, SOFTRESET, RESERVED1[1], INTCONTROL, C0RXTHRESHEN,
18518
+ C0RXEN, C0TXEN, C0MISCEN, RESERVED2[8],
18519
+ C0RXTHRESHSTAT, C0RXSTAT, C0TXSTAT, C0MISCSTAT,
18520
+ RESERVED3[8],
18521
+ C0RXIMAX, C0TXIMAX;
18522
+ };
18523
+ struct tms570_emac {
18524
+ volatile uint32_t TXREVID, TXCONTROL, TXTEARDOWN, RESERVED1[1], RXREVID,
18525
+ RXCONTROL, RXTEARDOWN, RESERVED2[25], TXINTSTATRAW,TXINTSTATMASKED,
18526
+ TXINTMASKSET, TXINTMASKCLEAR, MACINVECTOR, MACEOIVECTOR, RESERVED8[2], RXINTSTATRAW,
18527
+ RXINTSTATMASKED, RXINTMASKSET, RXINTMASKCLEAR, MACINTSTATRAW, MACINTSTATMASKED,
18528
+ MACINTMASKSET, MACINTMASKCLEAR, RESERVED3[16], RXMBPENABLE, RXUNICASTSET,
18529
+ RXUNICASTCLEAR, RXMAXLEN, RXBUFFEROFFSET, RXFILTERLOWTHRESH, RESERVED9[2], RXFLOWTHRESH[8],
18530
+ RXFREEBUFFER[8], MACCONTROL, MACSTATUS, EMCONTROL, FIFOCONTROL, MACCONFIG,
18531
+ SOFTRESET, RESERVED4[22], MACSRCADDRLO, MACSRCADDRHI, MACHASH1, MACHASH2,
18532
+ BOFFTEST, TPACETEST, RXPAUSE, TXPAUSE, RESERVED5[4], RXGOODFRAMES, RXBCASTFRAMES,
18533
+ RXMCASTFRAMES, RXPAUSEFRAMES, RXCRCERRORS, RXALIGNCODEERRORS, RXOVERSIZED,
18534
+ RXJABBER, RXUNDERSIZED, RXFRAGMENTS, RXFILTERED, RXQOSFILTERED, RXOCTETS,
18535
+ TXGOODFRAMES, TXBCASTFRAMES, TXMCASTFRAMES, TXPAUSEFRAMES, TXDEFERRED,
18536
+ TXCOLLISION, TXSINGLECOLL, TXMULTICOLL, TXEXCESSIVECOLL, TXLATECOLL,
18537
+ TXUNDERRUN, TXCARRIERSENSE, TXOCTETS, FRAME64, FRAME65T127, FRAME128T255,
18538
+ FRAME256T511, FRAME512T1023, FRAME1024TUP, NETOCTETS, RXSOFOVERRUNS,
18539
+ RXMOFOVERRUNS, RXDMAOVERRUNS, RESERVED6[156], MACADDRLO, MACADDRHI,
18540
+ MACINDEX, RESERVED7[61], TXHDP[8], RXHDP[8], TXCP[8], RXCP[8];
18541
+ };
18542
+ struct tms570_mdio {
18543
+ volatile uint32_t REVID, CONTROL, ALIVE, LINK, LINKINTRAW, LINKINTMASKED,
18544
+ RESERVED1[2], USERINTRAW, USERINTMASKED, USERINTMASKSET, USERINTMASKCLEAR,
18545
+ RESERVED2[20], USERACCESS0, USERPHYSEL0, USERACCESS1, USERPHYSEL1;
18546
+ };
18547
+ #define SWAP32(x) ( (((x) & 0x000000FF) << 24) | \
18548
+ (((x) & 0x0000FF00) << 8) | \
18549
+ (((x) & 0x00FF0000) >> 8) | \
18550
+ (((x) & 0xFF000000) >> 24) )
18551
+ #undef EMAC
18552
+ #undef EMAC_CTRL
18553
+ #undef MDIO
18554
+ #define EMAC ((struct tms570_emac *) (uintptr_t) 0xFCF78000)
18555
+ #define EMAC_CTRL ((struct tms570_emac_ctrl *) (uintptr_t) 0xFCF78800)
18556
+ #define MDIO ((struct tms570_mdio *) (uintptr_t) 0xFCF78900)
18557
+ #define ETH_PKT_SIZE 1540 // Max frame size
18558
+ #define ETH_DESC_CNT 4 // Descriptors count
18559
+ #define ETH_DS 4 // Descriptor size (words)
18560
+ static uint32_t s_txdesc[ETH_DESC_CNT][ETH_DS]
18561
+ __attribute__((section(".ETH_CPPI"), aligned(4))); // TX descriptors
18562
+ static uint32_t s_rxdesc[ETH_DESC_CNT][ETH_DS]
18563
+ __attribute__((section(".ETH_CPPI"), aligned(4))); // RX descriptors
18564
+ static uint8_t s_rxbuf[ETH_DESC_CNT][ETH_PKT_SIZE]
18565
+ __attribute__((aligned(4))); // RX ethernet buffers
18566
+ static uint8_t s_txbuf[ETH_DESC_CNT][ETH_PKT_SIZE]
18567
+ __attribute__((aligned(4))); // TX ethernet buffers
18568
+ static struct mg_tcpip_if *s_ifp; // MIP interface
18569
+ static uint16_t emac_read_phy(uint8_t addr, uint8_t reg) {
18570
+ while(MDIO->USERACCESS0 & MG_BIT(31)) (void) 0;
18571
+ MDIO->USERACCESS0 = MG_BIT(31) | ((reg & 0x1f) << 21) |
18572
+ ((addr & 0x1f) << 16);
18573
+ while(MDIO->USERACCESS0 & MG_BIT(31)) (void) 0;
18574
+ return MDIO->USERACCESS0 & 0xffff;
18575
+ }
18576
+ static void emac_write_phy(uint8_t addr, uint8_t reg, uint16_t val) {
18577
+ while(MDIO->USERACCESS0 & MG_BIT(31)) (void) 0;
18578
+ MDIO->USERACCESS0 = MG_BIT(31) | MG_BIT(30) | ((reg & 0x1f) << 21) |
18579
+ ((addr & 0x1f) << 16) | (val & 0xffff);
18580
+ while(MDIO->USERACCESS0 & MG_BIT(31)) (void) 0;
18581
+ }
18582
+ static bool mg_tcpip_driver_tms570_init(struct mg_tcpip_if *ifp) {
18583
+ struct mg_tcpip_driver_tms570_data *d =
18584
+ (struct mg_tcpip_driver_tms570_data *) ifp->driver_data;
18585
+ s_ifp = ifp;
18586
+ EMAC_CTRL->SOFTRESET = MG_BIT(0); // Reset the EMAC Control Module
18587
+ while(EMAC_CTRL->SOFTRESET & MG_BIT(0)) (void) 0; // wait
18588
+ EMAC->SOFTRESET = MG_BIT(0); // Reset the EMAC Module
18589
+ while(EMAC->SOFTRESET & MG_BIT(0)) (void) 0;
18590
+ EMAC->MACCONTROL = 0;
18591
+ EMAC->RXCONTROL = 0;
18592
+ EMAC->TXCONTROL = 0;
18593
+ // Initialize all the header descriptor pointer registers
18594
+ uint32_t i;
18595
+ for(i = 0; i < ETH_DESC_CNT; i++) {
18596
+ EMAC->RXHDP[i] = 0;
18597
+ EMAC->TXHDP[i] = 0;
18598
+ EMAC->RXCP[i] = 0;
18599
+ EMAC->TXCP[i] = 0;
18600
+ ///EMAC->RXFREEBUFFER[i] = 0xff;
18601
+ }
18602
+ // Clear the interrupt enable for all the channels
18603
+ EMAC->TXINTMASKCLEAR = 0xff;
18604
+ EMAC->RXINTMASKCLEAR = 0xff;
18605
+ EMAC->MACHASH1 = 0;
18606
+ EMAC->MACHASH2 = 0;
18607
+ EMAC->RXBUFFEROFFSET = 0;
18608
+ EMAC->RXUNICASTCLEAR = 0xff;
18609
+ EMAC->RXUNICASTSET = 0;
18610
+ EMAC->RXMBPENABLE = 0;
18611
+ // init MDIO
18612
+ // MDIO_CLK frequency = VCLK3/(CLKDIV + 1). (MDIO must be between 1.0 - 2.5Mhz)
18613
+ uint32_t clkdiv = 75; // VCLK is configured to 75Mhz
18614
+ // CLKDIV, ENABLE, PREAMBLE, FAULTENB
18615
+ MDIO->CONTROL = (clkdiv - 1) | MG_BIT(30) | MG_BIT(20) | MG_BIT(18);
18616
+ volatile int delay = 0xfff;
18617
+ while (delay-- != 0) (void) 0;
18618
+ struct mg_phy phy = {emac_read_phy, emac_write_phy};
18619
+ mg_phy_init(&phy, d->phy_addr, MG_PHY_CLOCKS_MAC);
18620
+ // set the mac address
18621
+ EMAC->MACSRCADDRHI = ifp->mac[0] | (ifp->mac[1] << 8) | (ifp->mac[2] << 16) |
18622
+ (ifp->mac[3] << 24);
18623
+ EMAC->MACSRCADDRLO = ifp->mac[4] | (ifp->mac[5] << 8);
18624
+ uint32_t channel;
18625
+ for (channel = 0; channel < 8; channel++) {
18626
+ EMAC->MACINDEX = channel;
18627
+ EMAC->MACADDRHI = ifp->mac[0] | (ifp->mac[1] << 8) | (ifp->mac[2] << 16) |
18628
+ (ifp->mac[3] << 24);
18629
+ EMAC->MACADDRLO = ifp->mac[4] | (ifp->mac[5] << 8) | MG_BIT(20) |
18630
+ MG_BIT(19) | (channel << 16);
18631
+ }
18632
+ EMAC->RXUNICASTSET = 1; // accept unicast frames;
18633
+ EMAC->RXMBPENABLE = MG_BIT(30) | MG_BIT(13); // CRC, broadcast;
18634
+
18635
+ // Initialize the descriptors
18636
+ for (i = 0; i < ETH_DESC_CNT; i++) {
18637
+ if (i < ETH_DESC_CNT - 1) {
18638
+ s_txdesc[i][0] = 0;
18639
+ s_rxdesc[i][0] = SWAP32(((uint32_t) &s_rxdesc[i + 1][0]));
18640
+ }
18641
+ s_txdesc[i][1] = SWAP32(((uint32_t) s_txbuf[i]));
18642
+ s_rxdesc[i][1] = SWAP32(((uint32_t) s_rxbuf[i]));
18643
+ s_txdesc[i][2] = 0;
18644
+ s_rxdesc[i][2] = SWAP32(ETH_PKT_SIZE);
18645
+ s_txdesc[i][3] = 0;
18646
+ s_rxdesc[i][3] = SWAP32(MG_BIT(29)); // OWN
18647
+ }
18648
+ s_txdesc[ETH_DESC_CNT - 1][0] = 0;
18649
+ s_rxdesc[ETH_DESC_CNT - 1][0] = 0;
18650
+
18651
+ EMAC->MACCONTROL = MG_BIT(5) | MG_BIT(0); // Enable MII, Full-duplex
18652
+ //EMAC->TXINTMASKSET = 1; // Enable TX interrupt
18653
+ EMAC->RXINTMASKSET = 1; // Enable RX interrupt
18654
+ //EMAC_CTRL->C0TXEN = 1; // TX completion interrupt
18655
+ EMAC_CTRL->C0RXEN = 1; // RX completion interrupt
18656
+ EMAC->TXCONTROL = 1; // TXEN
18657
+ EMAC->RXCONTROL = 1; // RXEN
18658
+ EMAC->RXHDP[0] = (uint32_t) &s_rxdesc[0][0];
18659
+ return true;
18660
+ }
18661
+ static uint32_t s_txno;
18662
+ static size_t mg_tcpip_driver_tms570_tx(const void *buf, size_t len,
18663
+ struct mg_tcpip_if *ifp) {
18664
+ if (len > sizeof(s_txbuf[s_txno])) {
18665
+ MG_ERROR(("Frame too big, %ld", (long) len));
18666
+ len = 0; // fail
18667
+ } else if ((s_txdesc[s_txno][3] & SWAP32(MG_BIT(29)))) {
18668
+ ifp->nerr++;
18669
+ MG_ERROR(("No descriptors available"));
18670
+ len = 0; // fail
18671
+ } else {
18672
+ memcpy(s_txbuf[s_txno], buf, len); // Copy data
18673
+ if (len < 128) len = 128;
18674
+ s_txdesc[s_txno][2] = SWAP32((uint32_t) len); // Set data len
18675
+ s_txdesc[s_txno][3] =
18676
+ SWAP32(MG_BIT(31) | MG_BIT(30) | MG_BIT(29) | len); // SOP, EOP, OWN, length
18677
+
18678
+ while(EMAC->TXHDP[0] != 0) (void) 0;
18679
+ EMAC->TXHDP[0] = (uint32_t) &s_txdesc[s_txno][0];
18680
+ if(++s_txno == ETH_DESC_CNT) {
18681
+ s_txno = 0;
18682
+ }
18683
+ }
18684
+ return len;
18685
+ (void) ifp;
18686
+ }
18687
+ static bool mg_tcpip_driver_tms570_up(struct mg_tcpip_if *ifp) {
18688
+ struct mg_tcpip_driver_tms570_data *d =
18689
+ (struct mg_tcpip_driver_tms570_data *) ifp->driver_data;
18690
+ uint8_t speed = MG_PHY_SPEED_10M;
18691
+ bool up = false, full_duplex = false;
18692
+ struct mg_phy phy = {emac_read_phy, emac_write_phy};
18693
+ up = mg_phy_up(&phy, d->phy_addr, &full_duplex, &speed);
18694
+ if ((ifp->state == MG_TCPIP_STATE_DOWN) && up) {
18695
+ // link state just went up
18696
+ MG_DEBUG(("Link is %uM %s-duplex", speed == MG_PHY_SPEED_10M ? 10 : 100,
18697
+ full_duplex ? "full" : "half"));
18698
+ }
18699
+ return up;
18700
+ }
18701
+ #pragma CODE_STATE(EMAC_TX_IRQHandler, 32)
18702
+ #pragma INTERRUPT(EMAC_TX_IRQHandler, IRQ)
18703
+ void EMAC_TX_IRQHandler(void) {
18704
+ uint32_t status = EMAC_CTRL->C0TXSTAT;
18705
+ if (status & 1) { // interrupt caused on channel 0
18706
+ while(s_txdesc[s_txno][3] & SWAP32(MG_BIT(29))) (void) 0;
18707
+ EMAC->TXCP[0] = (uint32_t) &s_txdesc[s_txno][0];
18708
+ }
18709
+ //Write the DMA end of interrupt vector
18710
+ EMAC->MACEOIVECTOR = 2;
18711
+ }
18712
+ static uint32_t s_rxno;
18713
+ #pragma CODE_STATE(EMAC_RX_IRQHandler, 32)
18714
+ #pragma INTERRUPT(EMAC_RX_IRQHandler, IRQ)
18715
+ void EMAC_RX_IRQHandler(void) {
18716
+ uint32_t status = EMAC_CTRL->C0RXSTAT;
18717
+ if (status & 1) { // Frame received, loop
18718
+ uint32_t i;
18719
+ //MG_INFO(("RX interrupt"));
18720
+ for (i = 0; i < 10; i++) { // read as they arrive but not forever
18721
+ if ((s_rxdesc[s_rxno][3] & SWAP32(MG_BIT(29))) == 0) {
18722
+ uint32_t len = SWAP32(s_rxdesc[s_rxno][3]) & 0xffff;
18723
+ //MG_INFO(("recv len: %d", len));
18724
+ //mg_hexdump(s_rxbuf[s_rxno], len);
18725
+ mg_tcpip_qwrite(s_rxbuf[s_rxno], len > 4 ? len - 4 : len, s_ifp);
18726
+ uint32_t flags = s_rxdesc[s_rxno][3];
18727
+ s_rxdesc[s_rxno][3] = SWAP32(MG_BIT(29));
18728
+ s_rxdesc[s_rxno][2] = SWAP32(ETH_PKT_SIZE);
18729
+ EMAC->RXCP[0] = (uint32_t) &s_rxdesc[s_rxno][0];
18730
+ if (flags & SWAP32(MG_BIT(28))) {
18731
+ //MG_INFO(("EOQ detected"));
18732
+ EMAC->RXHDP[0] = (uint32_t) &s_rxdesc[0][0];
18733
+ }
18734
+ }
18735
+ if (++s_rxno >= ETH_DESC_CNT) s_rxno = 0;
18736
+ }
18737
+ }
18738
+ //Write the DMA end of interrupt vector
18739
+ EMAC->MACEOIVECTOR = 1;
18740
+ }
18741
+ struct mg_tcpip_driver mg_tcpip_driver_tms570 = {mg_tcpip_driver_tms570_init,
18742
+ mg_tcpip_driver_tms570_tx, NULL,
18743
+ mg_tcpip_driver_tms570_up};
18744
+ #endif
18745
+
18746
+
18510
18747
#ifdef MG_ENABLE_LINES
18511
18748
#line 1 "src/drivers/w5500.c"
18512
18749
#endif
0 commit comments