AT91SAM9G20的EMAC可用于控制外设PHY的工作模式,EMAC工作模式可以为MII和RMII。
DM9161连线说明:
分别说明了MII和RMII连线的方式。
可通过DM9161---RXD管脚以及第35号管脚配置PHY设备地址,EMAC在操作外接PYH设备的时候使用地址区别不同设备,RXD管脚说明:
DM9161实际原理图:
从原理图可看出PHY设备地址为3,并使用RMII接线模式(地址由RXD【0:3】四个引脚确定,RMII模式使用接线比MII少了一半)
AT91SAN9G20主要寄存器使用说明:
从Datasheet里Memories一章找到EMAC寄存器起址:
根据EMAC寄存器偏移表找出具体寄存器地址:
(AT91SAM9G20)
EMAC_NCR寄存器、
EMAC_MAN寄存器说明如下:
EMAC_NCR寄存器(重要位说明):
RE:接收使能位
TE:发送使能位
MPE:控制端口使能位
EMAC_MAN寄存器 (重要位说明):
DATA:操作PHY设备的指令
CODE:必须设置为10
REGA:PHY设备号
PHYA:PHY设备寄存器地址
RW:读写控制位
SOF:一帧数据开始前必须设置为01
本次设计主要操作这两个寄存器,调试代码如下:
static void macb_mdio_write(struct macb_device *macb, u8 reg, u16 value)
{
unsigned long netctl;
unsigned long netstat;
unsigned long frame;
netctl = macb_readl(macb, NCR);读NCR寄存器状态
netctl |= MACB_BIT(MPE);设置NCR寄存器(把MPE置位,使能控制端口)
macb_writel(macb, NCR, netctl);写数据到NCR寄存器
frame = (MACB_BF(SOF, 1)
| MACB_BF(RW, 1)
| MACB_BF(PHYA, macb->phy_addr)
| MACB_BF(REGA, reg)
| MACB_BF(CODE, 2)
| MACB_BF(DATA, value));构造一帧完整的的数据
macb_writel(macb, MAN, frame);把构造好的数据使用EMAC_MAN寄存器发送到PHY设备
do {
netstat = macb_readl(macb, NSR);
} while (!(netstat & MACB_BIT(IDLE)));检查状态寄存器
netctl = macb_readl(macb, NCR);
netctl &= ~MACB_BIT(MPE);
macb_writel(macb, NCR, netctl);
}