PHY芯片简介
PHY芯片简介:收发电、光模拟信号,经过解调和A/D转换通过介质接口(MII 或者 RMII)将信号转发到MAC内核
LAN8720A和YT8512C简介:
1、通过收发光电信号实现以太网MAC内核通信。
2、PHY地址设置:
a、LAN8720根据PIN10 引脚的 上拉(0x01) 下拉(0x00) 来确定PHY地址;
b、YT8512C根据PIN24 和 PIN25 引脚的 上拉(0x10) 下拉(0x00)来确定PHY地址;
3、RMII模式选择:
a、硬件连接方式一样,LAN8720和YT8512C支持两种RMII模式。
b、LAN8720A具有 REF_CLK IN模式 和 REF_CLK OUT模式由2号引脚的电平控制。
REF_CLK IN模式:外部提供50MHz给MAC内核以及PHY芯片;
PHY外接一个5MHz,由内部PLL输出50MHZ;
REF_CLK OUT模式:外部提供25MHZ时钟给PHY芯片,REFCLK引脚输出50MMHZ
c、YT8512C具有 RMII1模式 和 RMII2模式。
RMII1模式:PHY外接一个25MHZ,经过PHY内部PLL只提供50MHz;
RMII2模式:PHY外接25MHz情况下,PHY芯片的15号引脚(TXC)输出50MHz时钟;
4、PHY寄存器:相同寄存器和自由定义的寄存器
a、相同的寄存器,根据IEEE802.3标准定义的0~15个寄存器。
b、自由定义的寄存器,16~31寄存器由芯片制造商决定
5、特殊功能寄存器:通过确定网速及全双工模式来设置BCR寄存器的bit8税bit13位。
配置项 | 数值 |
PHY_SR | 0x1F |
PHY_SPEED_STATUS | 0x0004 |
PHY_DUPLEX_STATUS | 0x0010 |
PHY_DUPLEX_STATUS 判断双工:
BITS | Speed Indication | |
4:2 由第二位决定网速 由第四位决定双工 | HCDSPEED value | |
001 = 10BASE-T | half-duplex | |
101 = 10BASE-T | full-duplex | |
010 = 100BASE-TX | half-duplex | |
110 = 100BASE-TX | full-duplex |
第一列0 1 0 1 代表的是半 全 半 全(双工),第四位为0则半双工,反之全双工,因此设置数值为0x0010。
第二列01 01 10 10 代表网速是10M 和 100M 的区别
DMA描述简介
TX DMA描述符成员变量简介
TDESO[31]置0:CPU可将数据拷贝到描述符中,拷贝完成之后把该位置1,告诉DMA可以发送数据
TDESO[20]置1:描述符中的第二个地址是下一个描述符地址,ST以太网驱动库是把TDES0[20]置1
TDES1[28:16]:如果TDESO[20] 位置则该字段无效
TDES3[31:0]:取决于TDESO[20]的值,为1,则保存下一个描述符地址
RX DMA描述符成员变量简介
RDESO[31]置1:MAC将数据从RX FIFO传输到RX描述符中,拷贝完成之后该位置0,告诉CPU可以接收数据
RDESO[14]置1:描述符中的第二个地址是下一个描述符地址ST以太网驱动库是把RDESO[14]置1
RDES1[28:16]:如果RDESO[14]位置1,则该字段无效
RDES3[31:0]:取决于RDESO[14]的值,为1,则指向下一个描述符地址
追踪描述符
ETH_InitTypeDef中定义了RxDesc和TxDesc指针,它们是用来追踪Rx/Tx的DMA描述符
RXDESC指针 指向地址查询Buffer Address数据(MAC内核接收到的数据保存到里面)
TXDesc指针 指向地址查询Buffer Address(保存了网络层上传的数据),最后通过DMA(以太网)转发到Tx FFO中
申请内存
发送流程:Tx 缓冲区 保存了 网络层 下达的 Pbuf(保存了用户下达的数据),网络实现的功能是将Pbuf里面数据进行拷贝到Tx缓冲区里面,数据传输完成口使用以太网DMA发到TxFIFO里面,最后转发到MAC内核,MAC内核再通过介质接口发往PHY设备当中
接收流程:Rx缓冲区,PHY接收到一个光电信号经过解调和AD转换,使用介质的接口发往到MAC内核,之后转发到RxFIFO,接着使用以太网DMA发往到Rx缓冲区,最后转发到网络层
管理缓冲区: g_eth_dma_rx_dscr_tab
g_eth_dma_tx_dscr_tab
接收以太网数据包:g_eth_rx_buf
保存网络下达的数据包: g_eth_tx_buf
/**
* @breif 为ETH底层驱动申请内存
* @param 无
* @retval 0 正常
* 1 失败
*
*/
uint8_t ethernet_mem_malloc(void)
{
g_eth_dma_rx_dscr_tab = mymalloc(SRAMIN, ETH_RXBUFNB * sizeof(ETH_DMADescTypeDef); //申请内存
g_eth_dma_tx_dscr_tab = mymalloc(SRAMIN, ETH_RXBUFNB * sizeof(ETH_DMADescTypeDef); //申请内存
g_eth_dma_rx_buf = mymalloc(SRAMIN, ETH_RX_BUF_SIZE * ETH_RXBUFNB); //申请内存
g_eth_dma_tx_buf = mymalloc(SRAMIN, ETH_RX_BUF_SIZE * ETH_RXBUFNB); //申请内存
if (!(uint32_t)&g_eth_dma_rx_dscr_tab || !(uint32_t)&g_eth_dma_tx_dscr_tab || !(uint32_t)&g_eth_dma_rx_buf || !(uint32_t)&g_eth_dma_rx_buf )
{
ethernet_mem_free();
return 1; //申请失败
}
return 0; //申请成功
}
发送&接收描述符初始化
HAL_ETH _DMATxDesclistinit(&g_eth_handler, g_eth_dma_tx_dscr_tab, g_eth_tx_buf, ETH_TXBUFNB); //初始化发送描述符
HAL_ETH _DMARxDesclistinit(&g_eth_handler, g_eth_dma_tx_dscr_tab, g_eth_tx_buf, ETH_TXBUFNB); //初始化接收描述符
以第一个为例子(框图+代码)
整理代码:
HAL_StatusTypeDef HAL_ETH_DMATxDescListInit(ETH_HandleTypeDef *heth,
ETH_DMAdescTypeDef *DMATxDescTab,
uint8_t *TxBuff,
uint32_t TxBuffCount)
{
uint32_t i = 0U;
ETH_DMADescTypeDef *dmatxdesc;
heth -> State = HAL_ETH_STATE_BUSY; //设置状态等于BUSY
heth -> TxDesc = DMATxDescTab; //指向第一个描述符
for(i = 0U; i < TxBuffCount; i++) //通过for循环来添加每一个描述符
{
dmatxdesc = DMATxDescTab + i; //获取Tx Desc 列表的第 i 个成员的指针
dmatxdesc -> Status = ETH_DMATXDESC_TCH; //TDES0[20]置1:设置第二个地址链接位
dmatxdesc -> Buffer1Addr = (uint32_t)(&TxBuff{i*ETH_TX_BUF_SIZE}); //给描述符的buffer赋值地址
if(i < (TxBuffCount - 1U)) //如果小于最大值
{
//描述符的 next 就指向下一个,否则就指向第一个描述符
dmatxdesc -> Buffer2NextDescAddr = (uint32_t)(DMATxDescTab + i + 1U);
}
else
{
//最后一个描述符,设置下一个描述符地址寄存器等于第一个描述符基地址
dmatxdesc -> Buffer2NextDescAddr = (uint32_t)DMATxDescTab;
}
}
//把描述符的地址赋值给DMA的寄存器
(heth -> Instance) -> DMATDLAR = (uint32_t) DMATxDescTab;
//设置状态等于Rest
heth -> State = HAL_ETH_STATE_READY;
}
先定义一个指针 dmatxdesc
TxDesc 是用来追踪描述符,指向描述符DMATxDescTab的首地址
i = 0 dmatxdesc 指向第一个地址,
DMA描述符是用来管理缓冲区,缓冲区保存了网络层下达的Pbuf(首部+数据)里面保存的是用户端下发的数据
Pbuf里面的数据会被拷贝到缓冲区,经过以太网DMA(存储器到存储器)发往到TxFIFO里面,最后转发到MAC内核,MAC内核以介质接口发送给PHY