SAM4E单片机之旅——22、GMAC和PHY的介绍与初始化
001,即其地址为0x1。
特别指出,地址0可作为该芯片的广播地址,而开发板也做了这样的配置。另外,在ASF中,错误地将PHY的地址定义成了0。这样能正确工作的原因仅是0为广播地址,而开发板只有一个PHY芯片。严谨起见,将这个地址修改为正确的值:
#ifdef BOARD_GMAC_PHY_ADDR
#undef BOARD_GMAC_PHY_ADDR
#endif
#define BOARD_GMAC_PHY_ADDR 1
五、 在ASF中使用PHY
使用的模块为Ethernet Physical Transceiver。需要在conf_board.h 中声明宏:
/* 使用 ETH PHY: KSZ8051MNL */
#define CONF_BOARD_KSZ8051MNL
初始化。
在PHY上电后,需要等待一段时间让其运行稳定。之后就可以对其进行初始化了:
if (ethernet_phy_init(GMAC, BOARD_GMAC_PHY_ADDR,sysclk_get_cpu_hz())
!= GMAC_OK) {
puts("PHY Initialize ERROR!\r");
return -1;
}
在该ethernet_phy_init( ) 函数中,完成了以下工作:
设置MDIO的时钟MDC。
通过MDIO向PHY发送重置命令。
检查地址是否正确。检查的逻辑是先读取PHY的PHYID1的内容,再判断读出的内容是否正确。KSZ8051MNL芯片中,该寄存器的值是0x22。
如果地址无效的话,因为MDIO有效地址只有32个,就遍历这些地址。然后使用检查出的新地址重新发送一次重置命令。
如果初始化成功,则返回GMAC_OK。
自协商。
然后需要让PHY协商通信速率、双工模式:
ethernet_phy_auto_negotiate(GMAC, BOARD_GMAC_PHY_ADDR);
if (ethernet_phy_set_link(GMAC, BOARD_GMAC_PHY_ADDR, 0)
!= GMAC_OK) {
puts("Set link ERROR!\r");
return -1;
}
ethernet_phy_auto_negotiate() 函数就会完成PHY的协商工作,然后根据协商的结果设置GMAC的速率、双工模式。ethernet_phy_set_link() 函数则会检查链路的状态,同时可以根据参数(第3个)应用PHY的自协商结果至GMAC中。
中断处理。
ASF的GMAC模块需要获取相关的中断,以进行相关的工作:如更新发送缓冲区描述符相关的信息,或是调用用户定义的回调函数等。
// 需要在NVIC中启用相关中断
void GMAC_Handler(void)
{
gmac_handler(&gs_gmac_dev);
}
数据接收。
先准备好一个缓冲,然后就可以调用gmac_dev_read() 读取出接收到的帧的内容。
//#define GMAC_FRAME_LENTGH_MAX 1536
uint8_t eth_buffer[GMAC_FRAME_LENTGH_MAX];
uint32_t frm_size;
gmac_dev_read(&gmac_dev, (uint8_t *) eth_buffer,
sizeof(eth_buffer), &frm_size);
数据发送。
gmac_dev_write(&gmac_dev, (uint8_t *)eth_buffer, frm_size, NULL);
通过该函数即可使用GMAC发送数据,第4个参数是发送完成后的回调函数。该回调函数时是在gmac_handler() 中被调用的。
- SAM4E单片机之旅——24、使用DSP库求向量数量积(05-08)
- SAM4E单片机之旅——23、在AS6(GCC)中使用FPU(05-02)
- SAM4E单片机之旅——19、CAN间通信(04-19)
- SAM4E单片机之旅——20、DMAC之使用Multi-buffer进行内存拷贝(04-24)
- SAM4E单片机之旅——18、通过AFEC(ADC)获取输入的电压(04-17)
- SAM4E单片机之旅——21、DMAC之USART回显(04-26)