⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 i2c.c

📁 该源码为mpc8248处理器的BSP
💻 C
字号:
/*
 * GPIO pins used for bit-banged MII communications
 */
#define MDIO_PORT	2		/* Port C */
/*注意我这儿懒得写程序,你要改成其他的port的GPIO信号,如PB或者PA,
请自行把IOP_PC替换成IOP_PB或者IOP_PA */

#define CFG_MDIO_PIN	0x08000000	/* PC4	*/
#define CFG_MDC_PIN	0x04000000	/* PC5 */


#define MDIO_ACTIVE	(* M8260_IOP_PCDIR(vxImmrGet())  |=  CFG_MDIO_PIN)
#define MDIO_TRISTATE	(* M8260_IOP_PCDIR(vxImmrGet())  &= ~CFG_MDIO_PIN)
#define MDIO_READ	((* M8260_IOP_PCDAT(vxImmrGet())  &  CFG_MDIO_PIN) != 0)

#define MDIO(bit)	if(bit) * M8260_IOP_PCDAT(vxImmrGet()) |=  CFG_MDIO_PIN; \
			else	* M8260_IOP_PCDAT(vxImmrGet()) &= ~CFG_MDIO_PIN

#define MDC(bit)	if(bit) * M8260_IOP_PCDAT(vxImmrGet()) |=  CFG_MDC_PIN; \
			else	* M8260_IOP_PCDAT(vxImmrGet()) &= ~CFG_MDC_PIN

#define MIIDELAY	    NSDELAY (200);

/*****************************************************************************
 *
 * Utility to send the preamble, address, and register (common to read
 * and write).
 */
static void miiphy_pre (char read, unsigned char addr, unsigned char reg)
{
	int j;			/* counter */


	/*
	 * Send a 32 bit preamble ('1's) with an extra '1' bit for good measure.
	 * The IEEE spec says this is a PHY optional requirement.  The AMD
	 * 79C874 requires one after power up and one after a MII communications
	 * error.  This means that we are doing more preambles than we need,
	 * but it is safer and will be much more robust.
	 */

	MDIO_ACTIVE;
	MDIO (1);
	for (j = 0; j < 32; j++) {
		MDC (0);
		MIIDELAY;
		MDC (1);
		MIIDELAY;
	}

	/* send the start bit (01) and the read opcode (10) or write (10) */
	MDC (0);
	MDIO (0);
	MIIDELAY;
	MDC (1);
	MIIDELAY;
	MDC (0);
	MDIO (1);
	MIIDELAY;
	MDC (1);
	MIIDELAY;
	MDC (0);
	MDIO (read);
	MIIDELAY;
	MDC (1);
	MIIDELAY;
	MDC (0);
	MDIO (!read);
	MIIDELAY;
	MDC (1);
	MIIDELAY;

	/* send the PHY address */
	for (j = 0; j < 5; j++) {
		MDC (0);
		if ((addr & 0x10) == 0) {
			MDIO (0);
		} else {
			MDIO (1);
		}
		MIIDELAY;
		MDC (1);
		MIIDELAY;
		addr <<= 1;
	}

	/* send the register address */
	for (j = 0; j < 5; j++) {
		MDC (0);
		if ((reg & 0x10) == 0) {
			MDIO (0);
		} else {
			MDIO (1);
		}
		MIIDELAY;
		MDC (1);
		MIIDELAY;
		reg <<= 1;
	}
}


/*****************************************************************************
 *
 * Read a MII PHY register.
 *
 * Returns:
 *   0 on success
 */
int bb_miiphy_read (char *devname, unsigned char addr,
		unsigned char reg, unsigned short *value)
{
	short rdreg;		/* register working value */
	int j;			/* counter */

	miiphy_pre (1, addr, reg);

	/* tri-state our MDIO I/O pin so we can read */
	MDC (0);
	MDIO_TRISTATE;
	MIIDELAY;
	MDC (1);
	MIIDELAY;

	/* check the turnaround bit: the PHY should be driving it to zero */
	if (MDIO_READ != 0) {
		/* puts ("PHY didn't drive TA low\n"); */
		for (j = 0; j < 32; j++) {
			MDC (0);
			MIIDELAY;
			MDC (1);
			MIIDELAY;
		}
		return (-1);
	}

	MDC (0);
	MIIDELAY;

	/* read 16 bits of register data, MSB first */
	rdreg = 0;
	for (j = 0; j < 16; j++) {
		MDC (1);
		MIIDELAY;
		rdreg <<= 1;
		rdreg |= MDIO_READ;
		MDC (0);
		MIIDELAY;
	}

	MDC (1);
	MIIDELAY;
	MDC (0);
	MIIDELAY;
	MDC (1);
	MIIDELAY;

	*value = rdreg;


	return 0;
}


/*****************************************************************************
 *
 * Write a MII PHY register.
 *
 * Returns:
 *   0 on success
 */
int bb_miiphy_write (char *devname, unsigned char addr,
		unsigned char reg, unsigned short value)
{
	int j;			/* counter */


	miiphy_pre (0, addr, reg);

	/* send the turnaround (10) */
	MDC (0);
	MDIO (1);
	MIIDELAY;
	MDC (1);
	MIIDELAY;
	MDC (0);
	MDIO (0);
	MIIDELAY;
	MDC (1);
	MIIDELAY;

	/* write 16 bits of register data, MSB first */
	for (j = 0; j < 16; j++) {
		MDC (0);
		if ((value & 0x00008000) == 0) {
			MDIO (0);
		} else {
			MDIO (1);
		}
		MIIDELAY;
		MDC (1);
		MIIDELAY;
		value <<= 1;
	}

	/*
	 * Tri-state the MDIO line.
	 */
	MDIO_TRISTATE;
	MDC (0);
	MIIDELAY;
	MDC (1);
	MIIDELAY;

	return 0;
}

void i2cInit(void)
{
* M8260_IOP_PCPAR(vxImmrGet())  &= ~( CFG_MDIO_PIN+CFG_MDC_PIN);

* M8260_IOP_PCDIR(vxImmrGet())  |=  CFG_MDC_PIN;
}

void phytest (void)
{

    unsigned short phyid;

    phyid=0;

    i2cInit();
    
    bb_miiphy_read(NULL, 1, 2, &phyid);

    printf("I get phyid0 = 0x%x \n",phyid);

    bb_miiphy_read(NULL, 1, 3, &phyid);

    printf("I get phyid1 = 0x%x \n",phyid);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -