This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

DP83TC814R-Q1: dp83tc814r-q1 set code difference compared with DP83848CVV

Part Number: DP83TC814R-Q1

I have designed my ECU with dp83tc814r-q1

but it seems a little complicated than DP83848CVV

my demo board used DP83848CVV

I have got dp83tc814r-q1 linux code but it seems hard to read it

I want to know is there other supporting code or technical support ?

  • Hi Brandon,

    Are you having trouble reading/writing registers with your version of the linux driver?

    Try this version of the driver and let me know if it works. 

    8272.dp83tc812.c
    // SPDX-License-Identifier: GPL-2.0
    /*
     * Driver for the Texas Instruments DP83TC812 PHY
     *
     * Copyright (C) 2021 Texas Instruments Incorporated - http://www.ti.com/
     *
     */
    
    #include <linux/ethtool.h>
    #include <linux/etherdevice.h>
    #include <linux/kernel.h>
    #include <linux/mii.h>
    #include <linux/module.h>
    #include <linux/of.h>
    #include <linux/phy.h>
    #include <linux/netdevice.h>
    
    #define DP83TC812_CS1_0_PHY_ID	0x2000a270
    #define DP83TC812_CS2_0_PHY_ID	0x2000a271
    #define DP83TC813_CS2_0_PHY_ID	0x2000a211
    #define DP83TC814_CS2_0_PHY_ID	0x2000a261
    
    #define DP83812_DEVADDR		0x1f
    #define DP83812_DEVADDR_MMD1	0x1
    
    #define DP83812_STRAP		0x45d
    #define MII_DP83812_SGMII_CTRL	0x608
    #define SGMII_CONFIG_VAL	0x027B
    #define MII_DP83812_RGMII_CTRL	0x600
    #define MII_DP83812_INT_STAT1	0x12
    #define MII_DP83812_INT_STAT2	0x13
    #define MII_DP83812_INT_STAT3	0x18
    #define MII_DP83812_RESET_CTRL	0x1f
    
    #define DP83812_HW_RESET	BIT(15)
    #define DP83812_SW_RESET	BIT(14)
    
    /* INT_STAT1 bits */
    #define DP83812_RX_ERR_CNT_HALF_FULL_INT_EN	BIT(0)
    #define DP83812_TX_ERR_CNT_HALF_FULL_INT_EN	BIT(1)
    #define DP83812_MS_TRAIN_DONE_INT_EN		BIT(2)
    #define DP83812_ESD_EVENT_INT_EN		BIT(3)
    #define DP83812_LINK_STAT_INT_EN		BIT(5)
    #define DP83812_ENERGY_DET_INT_EN		BIT(6)
    #define DP83812_LINK_QUAL_INT_EN		BIT(7)
    
    /* INT_STAT2 bits */
    #define DP83812_JABBER_INT_EN		BIT(0)
    #define DP83812_POL_INT_EN		BIT(1)
    #define DP83812_SLEEP_MODE_INT_EN	BIT(2)
    #define DP83812_OVERTEMP_INT_EN		BIT(3)
    #define DP83812_FIFO_INT_EN		BIT(4)
    #define DP83812_PAGE_RXD_INT_EN		BIT(5)
    #define DP83812_OVERVOLTAGE_INT_EN	BIT(6)
    #define DP83812_UNDERVOLTAGE_INT_EN	BIT(7)
    
    /* INT_STAT3 bits */
    #define DP83812_LPS_INT_EN		BIT(0)
    #define DP83812_WUP_INT_EN		BIT(1)
    #define DP83812_WAKE_REQ_INT_EN		BIT(2)
    #define DP83811_NO_FRAME_INT_EN		BIT(3)
    #define DP83811_POR_DONE_INT_EN		BIT(4)
    #define DP83812_SLEEP_FAIL_INT_EN	BIT(5)
    
    /* RGMII_CTRL bits */
    #define DP83812_RGMII_EN		BIT(3)
    
    /* SGMII CTRL bits */
    #define DP83812_SGMII_AUTO_NEG_EN	BIT(0)
    #define DP83812_SGMII_EN		BIT(9)
    
    /* Strap bits */
    #define DP83812_MASTER_MODE	BIT(9)
    #define DP83812_RGMII_IS_EN	BIT(7)
    
    /* RGMII ID CTRL */
    #define DP83812_RGMII_ID_CTRL	0x602
    #define DP83812_RX_CLK_SHIFT	BIT(1)
    #define DP83812_TX_CLK_SHIFT	BIT(0)
    
    enum dp83812_chip_type {
    	DP83812_CS1 = 0,
    	DP83812_CS2,
    	DP83813_CS2,
    	DP83814_CS2,
    };
    
    struct dp83812_init_reg {
    	int	reg;
    	int	val;
    };
    
    static const struct dp83812_init_reg dp83812_master_cs1_0_init[] = {
    	{0x523, 0x0001},
    	{0x800, 0xf864},
    	{0x803, 0x1552},
    	{0x804, 0x1a66},
    	{0x805, 0x1f7b},
    	{0x81f, 0x2a88},
    	{0x825, 0x40e5},
    	{0x82b, 0x7f3f},
    	{0x830, 0x0543},
    	{0x836, 0x5008},
    	{0x83a, 0x08e0},
    	{0x83b, 0x0845},
    	{0x83e, 0x0445},
    	{0x855, 0x9b9a},
    	{0x85f, 0x2010},
    	{0x860, 0x6040},
    	{0x86c, 0x1333},
    	{0x86b, 0x3e10},
    	{0x872, 0x88c0},
    	{0x873, 0x0003},
    	{0x879, 0x000f},
    	{0x87b, 0x0070},
    	{0x87c, 0x003f},
    	{0x89e, 0x00aa},
    	{0x523, 0x0000},
    };
    
    static const struct dp83812_init_reg dp83812_master_cs2_0_init[] = {
    	{0x523, 0x0001},
    	{0x81C, 0x0fe2},
    	{0x872, 0x0300},
    	{0x879, 0x0f00},
    	{0x806, 0x2952},
    	{0x807, 0x3361},
    	{0x808, 0x3D7B},
    	{0x83E, 0x045F},
    	{0x834, 0x8000},
    	{0x862, 0x00E8},
    	{0x896, 0x32CB},
    	{0x03E, 0x0009},
    	{0x01f, 0x4000},
    	{0x523, 0x0000},
    };
    
    static const struct dp83812_init_reg dp83812_slave_cs1_0_init[] = {
    	{0x523, 0x0001},
    	{0x803, 0x1b52},
    	{0x804, 0x216c},
    	{0x805, 0x277b},
    	{0x827, 0x3000},
    	{0x830, 0x0543},
    	{0x83a, 0x0020},
    	{0x83c, 0x0001},
    	{0x855, 0x9b9a},
    	{0x85f, 0x2010},
    	{0x860, 0x6040},
    	{0x86c, 0x0333},
    	{0x872, 0x88c0},
    	{0x873, 0x0021},
    	{0x879, 0x000f},
    	{0x87b, 0x0070},
    	{0x87c, 0x0002},
    	{0x897, 0x003f},
    	{0x89e, 0x00a2},
    	{0x510, 0x000f},
    	{0x523, 0x0000},
    };
    
    static const struct dp83812_init_reg dp83812_slave_cs2_0_init[] = {
    	{0x523, 0x0001},
    	{0x873, 0x0821},
    	{0x896, 0x22ff},
    	{0x89E, 0x0000},
    	{0x01f, 0x4000},
    	{0x523, 0x0000},
    };
    
    struct dp83812_private {
    	int chip;
    	bool is_master;
    	bool is_rgmii;
    	bool is_sgmii;
    };
    
    static int dp83812_read_straps(struct phy_device *phydev)
    {
    	struct dp83812_private *dp83812 = phydev->priv;
    	int strap;
    
    	strap = phy_read_mmd(phydev, DP83812_DEVADDR, DP83812_STRAP);
    	if (strap < 0)
    		return strap;
    
    	printk("%s: Strap is 0x%X\n", __func__, strap);
    	if (strap & DP83812_MASTER_MODE)
    		dp83812->is_master = true;
    
    	if (strap & DP83812_RGMII_IS_EN)
    		dp83812->is_rgmii = true;
    	return 0;
    };
    
    static int dp83812_reset(struct phy_device *phydev, bool hw_reset)
    {
    	int ret;
    
    	if (hw_reset)
    		ret = phy_write_mmd(phydev, DP83812_DEVADDR, MII_DP83812_RESET_CTRL,
    				DP83812_HW_RESET);
    	else
    		ret = phy_write_mmd(phydev, DP83812_DEVADDR, MII_DP83812_RESET_CTRL,
    				DP83812_SW_RESET);
    
    	if (ret)
    		return ret;
    
    	mdelay(100);
    
    	return 0;
    }
    
    static int dp83812_phy_reset(struct phy_device *phydev)
    {
    	int err;
    	int ret;
    
    	err = phy_write_mmd(phydev, DP83812_DEVADDR, MII_DP83812_RESET_CTRL, DP83812_HW_RESET);
    	if (err < 0)
    		return err;
    
    	ret = dp83812_read_straps(phydev);
    	if (ret)
    		return ret;
    
    	return 0;
    }
    
    static int dp83812_write_seq(struct phy_device *phydev, const struct
    				dp83812_init_reg *init_data, int size)
    {
    	int ret;
    	int i;
    
    	for (i = 0; i < size; i++) {
    		ret = phy_write_mmd(phydev, DP83812_DEVADDR, init_data[i].reg,
    					init_data[i].val);
    	if (ret)
    		return ret;
    	}
    	return 0;
    }
    
    static int dp83812_chip_init(struct phy_device *phydev)
    {
    	struct dp83812_private *dp83812 = phydev->priv;
    	int ret;
    
    	ret = dp83812_reset(phydev, true);
    	if (ret)
    		return ret;
    
    	phydev->autoneg = AUTONEG_DISABLE;
    	phydev->speed = SPEED_100;
    	phydev->duplex = DUPLEX_FULL;
    	linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT,
    		 phydev->supported);
    
    	if (dp83812->is_master)
    		ret = phy_write_mmd(phydev, DP83812_DEVADDR_MMD1, 0x0834, 0xc001);
    		// ret = phy_write_mmd(phydev, DP83812_DEVADDR, 0x0834, 0xc001);
    	else
    		ret = phy_write_mmd(phydev, DP83812_DEVADDR_MMD1, 0x0834, 0x8001);
    		// ret = phy_write_mmd(phydev, DP83812_DEVADDR, 0x0834, 0x8001);
    
    	switch (dp83812->chip) {
    	case DP83812_CS1:
    		if (dp83812->is_master)
    			ret = dp83812_write_seq(phydev,
    						dp83812_master_cs1_0_init,
    						ARRAY_SIZE(dp83812_master_cs1_0_init));
    		else
    			ret = dp83812_write_seq(phydev,
    						dp83812_slave_cs1_0_init,
    						ARRAY_SIZE(dp83812_slave_cs1_0_init));
    	break;
    	case DP83812_CS2:
    		if (dp83812->is_master)
    			ret = dp83812_write_seq(phydev,
    						dp83812_master_cs2_0_init,
    						ARRAY_SIZE(dp83812_master_cs2_0_init));
    		else
    			ret = dp83812_write_seq(phydev,
    						dp83812_slave_cs2_0_init,
    						ARRAY_SIZE(dp83812_slave_cs2_0_init));
    	break;
    	case DP83813_CS2:
    		if (dp83812->is_master)
    			ret = dp83812_write_seq(phydev,
    						dp83812_master_cs2_0_init,
    						ARRAY_SIZE(dp83812_master_cs2_0_init));
    		else
    			ret = dp83812_write_seq(phydev,
    						dp83812_slave_cs2_0_init,
    						ARRAY_SIZE(dp83812_slave_cs2_0_init));
    	break;
    	case DP83814_CS2:
    		if (dp83812->is_master)
    			ret = dp83812_write_seq(phydev,
    						dp83812_master_cs2_0_init,
    						ARRAY_SIZE(dp83812_master_cs2_0_init));
    		else
    			ret = dp83812_write_seq(phydev,
    						dp83812_slave_cs2_0_init,
    						ARRAY_SIZE(dp83812_slave_cs2_0_init));
    	break;
    	default:
    		return -EINVAL;
    	};
    
    	if (ret)
    		return ret;
    
    	mdelay(10);
    	// phy_write_mmd(phydev, DP83812_DEVADDR, 0x523, 0x00);
    	/* Do a soft reset to restart the PHY with updated values */
    	return dp83812_reset(phydev, false);
    }
    
    static int dp83812_config_init(struct phy_device *phydev)
    {
    	struct device *dev = &phydev->mdio.dev;
    	s32 rx_int_delay;
    	s32 tx_int_delay;
    	int rgmii_delay;
    	int value, ret;
    
    	ret = dp83812_chip_init(phydev);
    	if (ret)
    		return ret;
    
    	if (phy_interface_is_rgmii(phydev)) {
    		rx_int_delay = phy_get_internal_delay(phydev, dev, NULL, 0,
    						      true);
    
    		if (rx_int_delay <= 0)
    			rgmii_delay = 0;
    		else
    			rgmii_delay = DP83812_RX_CLK_SHIFT;
    
    		tx_int_delay = phy_get_internal_delay(phydev, dev, NULL, 0,
    						      false);
    		if (tx_int_delay <= 0)
    			rgmii_delay &= ~DP83812_TX_CLK_SHIFT;
    		else
    			rgmii_delay |= DP83812_TX_CLK_SHIFT;
    
    		if (rgmii_delay) {
    			ret = phy_set_bits_mmd(phydev, DP83812_DEVADDR_MMD1,
    					       DP83812_RGMII_ID_CTRL,
    					       rgmii_delay);
    			if (ret)
    				return ret;
    		}
    	}
    
    	if (phydev->interface == PHY_INTERFACE_MODE_SGMII) {
    		value = phy_read(phydev, MII_DP83812_SGMII_CTRL);
    		ret = phy_write_mmd(phydev, DP83812_DEVADDR, MII_DP83812_SGMII_CTRL,
    				SGMII_CONFIG_VAL);
    	if (ret < 0)
    		return ret;
    	}
    
    	return 0;
    }
    
    static int dp83812_ack_interrupt(struct phy_device *phydev)
    {
    	int err;
    
    	err = phy_read(phydev, MII_DP83812_INT_STAT1);
    	if (err < 0)
    		return err;
    
    	err = phy_read(phydev, MII_DP83812_INT_STAT2);
    	if (err < 0)
    		return err;
    
    	err = phy_read(phydev, MII_DP83812_INT_STAT3);
    	if (err < 0)
    		return err;
    
    	return 0;
    }
    
    static int dp83812_config_intr(struct phy_device *phydev)
    {
    	int misr_status, err;
    
    	if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
    		misr_status = phy_read(phydev, MII_DP83812_INT_STAT1);
    		if (misr_status < 0)
    			return misr_status;
    
    		misr_status |= (DP83812_ESD_EVENT_INT_EN |
    				DP83812_LINK_STAT_INT_EN |
    				DP83812_ENERGY_DET_INT_EN |
    				DP83812_LINK_QUAL_INT_EN);
    
    		err = phy_write(phydev, MII_DP83812_INT_STAT1, misr_status);
    		if (err < 0)
    			return err;
    
    		misr_status = phy_read(phydev, MII_DP83812_INT_STAT2);
    		if (misr_status < 0)
    			return misr_status;
    
    		misr_status |= (DP83812_SLEEP_MODE_INT_EN |
    				DP83812_OVERTEMP_INT_EN |
    				DP83812_OVERVOLTAGE_INT_EN |
    				DP83812_UNDERVOLTAGE_INT_EN);
    
    		err = phy_write(phydev, MII_DP83812_INT_STAT2, misr_status);
    		if (err < 0)
    			return err;
    
    		misr_status = phy_read(phydev, MII_DP83812_INT_STAT3);
    		if (misr_status < 0)
    			return misr_status;
    
    		misr_status |= (DP83812_LPS_INT_EN |
    				DP83812_WAKE_REQ_INT_EN |
    				DP83811_NO_FRAME_INT_EN |
    				DP83811_POR_DONE_INT_EN);
    
    		err = phy_write(phydev, MII_DP83812_INT_STAT3, misr_status);
    
    	} else {
    		err = phy_write(phydev, MII_DP83812_INT_STAT1, 0);
    		if (err < 0)
    			return err;
    
    		err = phy_write(phydev, MII_DP83812_INT_STAT2, 0);
    		if (err < 0)
    			return err;
    
    		err = phy_write(phydev, MII_DP83812_INT_STAT3, 0);
    	}
    
    	return err;
    }
    
    #if 0
    static irqreturn_t dp83812_handle_interrupt(struct phy_device *phydev)
    {
    	bool trigger_machine = false;
    	int irq_status;
    
    	/* The INT_STAT registers 1, 2 and 3 are holding the interrupt status
    	 * in the upper half (15:8), while the lower half (7:0) is used for
    	 * controlling the interrupt enable state of those individual interrupt
    	 * sources. To determine the possible interrupt sources, just read the
    	 * INT_STAT* register and use it directly to know which interrupts have
    	 * been enabled previously or not.
    	 */
    	irq_status = phy_read(phydev, MII_DP83812_INT_STAT1);
    	if (irq_status < 0) {
    		phy_error(phydev);
    		return IRQ_NONE;
    	}
    	if (irq_status & ((irq_status & GENMASK(7, 0)) << 8))
    		trigger_machine = true;
    
    	irq_status = phy_read(phydev, MII_DP83812_INT_STAT2);
    	if (irq_status < 0) {
    		phy_error(phydev);
    		return IRQ_NONE;
    	}
    	if (irq_status & ((irq_status & GENMASK(7, 0)) << 8))
    		trigger_machine = true;
    
    	irq_status = phy_read(phydev, MII_DP83812_INT_STAT3);
    	if (irq_status < 0) {
    		phy_error(phydev);
    		return IRQ_NONE;
    	}
    	if (irq_status & ((irq_status & GENMASK(7, 0)) << 8))
    		trigger_machine = true;
    
    	if (!trigger_machine)
    		return IRQ_NONE;
    
    	phy_trigger_machine(phydev);
    
    	return IRQ_HANDLED;
    }
    #endif
    
    static int dp83812_config_aneg(struct phy_device *phydev)
    {
    	int value, ret;
    
    	if (phydev->interface == PHY_INTERFACE_MODE_SGMII) {
    		value = phy_read(phydev, MII_DP83812_SGMII_CTRL);
    		ret = phy_write_mmd(phydev, DP83812_DEVADDR, MII_DP83812_SGMII_CTRL,
    				SGMII_CONFIG_VAL);
    		if (ret < 0)
    			return ret;
    	}
    	
    	return genphy_config_aneg(phydev);
    }
    
    
    
    static int dp83812_probe(struct phy_device *phydev)
    {
    	struct dp83812_private *dp83812;
    	int ret;
    
    	dp83812 = devm_kzalloc(&phydev->mdio.dev, sizeof(*dp83812), GFP_KERNEL);
    	if (!dp83812)
    		return -ENOMEM;
    
    	phydev->priv = dp83812;					
    	ret = dp83812_read_straps(phydev);
    	if (ret)
    		return ret;
    
    	switch (phydev->phy_id) {
    	case DP83TC812_CS1_0_PHY_ID:
    		dp83812->chip = DP83812_CS1;
    	break;
    	case DP83TC812_CS2_0_PHY_ID:
    		dp83812->chip = DP83812_CS2;
    	break;
    	case DP83TC813_CS2_0_PHY_ID:
    		dp83812->chip = DP83813_CS2;
    		break;
    	case DP83TC814_CS2_0_PHY_ID:
    		dp83812->chip = DP83814_CS2;
    	break;
    	default:
    	return -EINVAL;
    	};
    /* vikram : above code added to switch between different phy ids */
    
    	return dp83812_config_init(phydev);
    }
    
    #define DP83812_PHY_DRIVER(_id, _name)				\
    	{							\
    		PHY_ID_MATCH_EXACT(_id),			\
    		.name           = (_name),			\
    		.probe          = dp83812_probe,		\
    		/* PHY_BASIC_FEATURES */			\
    		.soft_reset     = dp83812_phy_reset,		\
    		.config_init    = dp83812_config_init,		\
    		.config_aneg = dp83812_config_aneg,		\
    		.ack_interrupt = dp83812_ack_interrupt,		\
    /*if 0								\
    		.handle_interrupt = dp83812_handle_interrupt,	\
    #endif	*/							\
    		.config_intr = dp83812_config_intr,		\
    		.suspend = genphy_suspend,			\
    		.resume = genphy_resume,			\
    	}
    
    static struct phy_driver dp83812_driver[] = {
    	DP83812_PHY_DRIVER(DP83TC812_CS1_0_PHY_ID, "TI DP83TC812CS1.0"),
    	DP83812_PHY_DRIVER(DP83TC812_CS2_0_PHY_ID, "TI DP83TC812CS2.0"),
    	DP83812_PHY_DRIVER(DP83TC813_CS2_0_PHY_ID, "TI DP83TC813CS2.0"),
    	DP83812_PHY_DRIVER(DP83TC814_CS2_0_PHY_ID, "TI DP83TC814CS2.0"),
    	};
    
    module_phy_driver(dp83812_driver);
    
    static struct mdio_device_id __maybe_unused dp83812_tbl[] = {
    	{ PHY_ID_MATCH_EXACT(DP83TC812_CS1_0_PHY_ID) },
    	{ PHY_ID_MATCH_EXACT(DP83TC812_CS2_0_PHY_ID) },
    	{ PHY_ID_MATCH_EXACT(DP83TC813_CS2_0_PHY_ID) },
    	{ PHY_ID_MATCH_EXACT(DP83TC814_CS2_0_PHY_ID) },
    	{ },
    };
    MODULE_DEVICE_TABLE(mdio, dp83812_tbl);									   
    
    MODULE_DESCRIPTION("Texas Instruments DP83TC812 PHY driver");
    MODULE_AUTHOR("Hari Nagalla <hnagalla@ti.com");
    MODULE_LICENSE("GPL");
    

    Best regards,

    Melissa

  • We are using an autosar system, and the initialization procedure in this driver does not work when ported over.
    There are many registers used in the sample code that are not described in the chip manual.
    Is there any example for bare board?

  • Hi Brandon,

    Autosar drivers are managed and delivered by respective Autosar vendors. The TI PHY team doesn't develop and manage Autosar drivers.

    Please reach out directly to Electrobit or Vector for support for the Autosar drivers.

    Best regards,

    Melissa

  • if the PHY does not support autosar I can not get driver from vector

    what I need is the driver  same with the datasheet

    if I can not get driver I have to change the design

  • Hi Brandon,

    I can provide the linux driver for the 814 and answer any questions you might have about it (see the attached DP83TC812.c file above). This 812 driver can also be used for the 814. The 812 and 814 have almost all the same features, pins, and registers except the 814 does not have any TC10 support. 

    Since the Autosar driver is developed and maintained by Electrobit/Vector, I do not have any knowledge about using their driver. If you use the 812 Autosar driver for the 814, you will need to make sure the PHY ID is correct for the 814. 

    what I need is the driver  same with the datasheet

    The linux driver provided before is for the DP83TC812 and DP83TC814 aswell. Is that where your confusion is?

    Best regards,

    Melissa

  • so we have to do it step by step

    first about the bootstrap

    I want to use RMII slave mode

    first is about LED0 configuration,leave it OPEN

    the MAC configuration 010 to use a pullup resistor with pin 25

    anything else,or I can do the configuration through software ?

  • Hi Brandon,

    I'm a little bit confused on what the issue is.  So your old board used the DP83848 and now you have designed a new board with the DP83TC814.

    Are you asking about what hardware changes required are when switching from DP83848 to DP83TC812?

    • The DP83848 are two totally different parts with different packaging and pins - I'm not sure that you could easily replace the DP83848 with the DP83TC814 as they support different protocols. DP83848 supports 100Base-TX while 812 supports 100Base-T1. If you are designing a new board with the DP83TC814, it may be simpler to just start from a new design. 

    Are you asking about what the software changes required for switching to DP83TC812? 

    • Since they are two different parts, they have different SW requirements. The DP83TC812 requires on Open Alliance initialization script which is provided in the linux driver I attached above or can be found here: https://www.ti.com/lit/an/snla389a/snla389a.pdf If you are looking for an autosar version of the driver, please reach out to Electrobit or Vector. 
  • my design is DP83TC812 because the ECU is for the automotive 

    the best solution is autosar version,but as far as I know autosar doesnot support TI PHY DP83TC812  so I have to do it by myself

    now my question is about bootstrap t is about hardware and software configuration

    use RMII slave mode

    first is about LED0 configuration,leave it OPEN

    the MAC configuration 010 to use a pullup resistor with pin 25

    anything else,or I can do the configuration through software ?

  • Hi Brandon,

    There is an autosar driver for the DP83TC812 developed by Electrobit and Vector. You can reach out to them for it, however Both Vector and EB don’t have support for TC-10 yet.

    For hardware confiugration for these modes, you can refer to section, 8.5.1 Strap Configuration, of the datasheet. RMII Slave mode must be configured through hardware. You can configure the master/slave mode through software and/or hardware. You are correct, RMII Slave mode corresponds to MAC configuration 010. Note that the reference clock should be 50 MHz instead of 25 MHz in this mode. 

    Note the DP83TC812 requires an initialization script for Open Alliance, that can found in section 3 here: https://www.ti.com/lit/an/snla389a/snla389a.pdf?ts=1702588149229 (note there is a typo, 0x18b[6] should be set to 1 not 0 at the end of initializaiton)

    Best regards,

    Melissa

  • RMII Slave mode must be configured through hardware. 

    I read the datasheet

    RMII slave MODE is defined by MAC PIN 

    what I need to do is to pullup pin 25 (MAC[1])to VDD  with 2.49k resistor

    then MAC1 is mode2=1

    leave MAC [0] [2] open

    but software read the mode is SGMII

    any possible reason?

  • Hi Brandon,

    Yes, you are supposed to pull up pin 25 to mode 2.

    Incorrect strap values can be caused by many things, we can look at the register to narrow it down to a SW or HW issue. If the registers look fine except for straps, then it is likely a HW issue in which you will have to review the schematic.

    Could you provide the following information:

    • What is registers 0x45D and 0x0-0x1F reading? Are the MAC interface and master/slave mode the only straps you have configured?
    • What software/driver are you using?

    Best regards,

    Melissa