📄 halrtl8019as.c
字号:
***************************************************************************/ /* * 修改记录: * * */ /** * @file halRtl8019as.c * @brief * <li>功能:</li> * <li>设计思想:</li> * @date */ /**************************** 引用部分 *****************************************/#include <delta.h>#include <string.h>#include "halRtl8019as.h"/*************************** 前向声明部分 ****************************************/T_MODULE T_WORD RTL8019AS_BlockInput( T_WORD wCount,T_BYTE *bpBuf,T_UWORD uwRingOffset,T_HAL_RTL8019AS_DEV_DATA *pDevData);T_MODULE T_WORD RTL8019AS_RingIndex(T_HAL_RTL8019AS_DEV_DATA *pDevData, T_WORD wPositionValue);T_MODULE T_WORD RTL8019AS_TriggerSend(T_HAL_RTL8019AS_DEV_DATA *pDevData, T_UWORD uwLength);T_MODULE T_WORD RTL8019AS_BlockOutput(T_HAL_RTL8019AS_DEV_DATA *pDevData,T_WORD wCount,T_BYTE *bpBuf,T_WORD wStartOffset);T_MODULE T_VOID RTL8019AS_HandlerOverflow(T_HAL_RTL8019AS_DEV_DATA *pDevData);T_MODULE T_WORD RTL8019AS_CheckFrame(T_HAL_RTL8019AS_DEV_DATA *pDevData,T_UWORD uwCurrFrame,EN_PKTHEADER_T *tpRcvFrame);T_MODULE T_VOID RTL8019AS_UpdateCounters(T_HAL_RTL8019AS_DEV_DATA *pDevData);/**************************** 定义部分 *****************************************//**************************** 实现部分 *****************************************//** * @brief * 功能: * 查询设备存在与否。 * * 实现内容: * 1、对某些设备进行初始化,如:对于PnP设备,为设备分配基地址和中断号。 * 2、根据读取到芯片的标志性数据(如Vendor ID或者Product ID),来探测设备存在与否。 * * @param[in] vpHalDevData:指针,指向HAL数据表(T_HAL_RTL8019AS_DEV_DATA)。 * * @return 成功返回TRUE;否则,返回FALSE。 */T_BOOL RTL8019AS_Find(T_VOID *vpHalDevData){ T_HAL_RTL8019AS_DEV_DATA *pDevData = (T_HAL_RTL8019AS_DEV_DATA *)vpHalDevData; T_BOOL retval = TRUE; //用户可在此处添加代码: T_BYTE id1; T_BYTE id2; T_BYTE id3; T_UWORD i; T_CHAR macBuf[32]; T_UBYTE keepCmd; /// 设置命令寄存器:register page:page0,abort DMA,stop reciever/transmit packages BSP_OutByte(pDevData->IoBaseAddr + EN_CMD, ENCMD_NODMA + ENCMD_PAGE0 + ENCMD_STOP); /// 检测标志寄存器,以确定基地址是否配置正确 BSP_InByte(pDevData->IoBaseAddr+EN0_ID0, id1); if (id1 != 'P') { return FALSE; } BSP_InByte(pDevData->IoBaseAddr+EN0_ID1, id2); if (id2 != 'p') { return FALSE; } id3 = RTL8019AS_BlockInput(0x16, macBuf, 0x00,pDevData); //读取上电后从93C46取出的MAC地址。 if(id3 == 0) { retval = FALSE; } BSP_InByte(pDevData->IoBaseAddr,keepCmd); //保存页面地址 BSP_OutByte(pDevData->IoBaseAddr + EN_CMD, ENCMD_NODMA + ENCMD_PAGE1 + ENCMD_STOP);//设置命令寄存器:寄存器页为1页,无DMA,关闭包接收/发送。 for(i = 0; i < 6; i++) { pDevData->macaddr[i] = macBuf[2*i]; BSP_OutByte(pDevData->IoBaseAddr + EN1_PHYS + i, pDevData->macaddr[i]); //将MAC地址写入RTL8019网卡设备的PAR0-PAR5寄存器。 } BSP_OutByte(pDevData->IoBaseAddr,keepCmd); //恢复页面地址 return retval;}/** * @brief * 功能: * 为设备分配资源。 * * 实现内容: * 对HAL中所需的内存资源进行分配。 * * @param[in] vpHalDevData:指针,指向HAL数据表(T_HAL_RTL8019AS_DEV_DATA)。 * * @return 成功返回TRUE;否则,返回FALSE。 */T_BOOL RTL8019AS_GetResource(T_VOID *vpHalDevData){ //用户可在此处添加代码: return TRUE;}/** * @brief * 功能: * 释放设备资源。 * * 实现内容: * 对HAL中已分配的内存资源进行释放。 * * @param[in] vpHalDevData:指针,指向HAL数据表(T_HAL_RTL8019AS_DEV_DATA)。 * * @return 成功返回TRUE;否则,返回FALSE。 */ T_BOOL RTL8019AS_ReleaseResource(T_VOID *vpHalDevData){ //用户可在此处添加代码: return TRUE;}/** * @brief * 功能: * 启动设备,初始化设备相关寄存器。 * * 实现内容: * 1、初始化设备相关数据结构的变量值; * 2、通过软件复位的方法来复位该设备; * 3、设置接收和发送等相关寄存器,如网络工作模式、MAC地址; * 注:以上工作完成后,通常需要延时一段时间,等待设备登录网络生效。 * * @param[in] vpHalDevData:指针,指向HAL数据表(T_HAL_RTL8019AS_DEV_DATA)。 * * @return 成功返回TRUE;否则,返回FALSE。 */T_BOOL RTL8019AS_Start(T_VOID *vpHalDevData){ T_HAL_RTL8019AS_DEV_DATA *pDevData = (T_HAL_RTL8019AS_DEV_DATA *)vpHalDevData; //用户可在此处添加代码: T_WORD i; ///初始化发送和接收页面 pDevData->word16 = ETHERNET_DMA_WORD; pDevData->txStartPage = TX_START_PAGE; pDevData->rxStartPage = RX_START_PAGE; pDevData->stopPage = RX_STOP_PAGE; BSP_OutByte(pDevData->IoBaseAddr + EN_CMD, ENCMD_NODMA+ENCMD_PAGE0+ENCMD_STOP); //设置命令寄存器:寄存器页为0页,无DMA,关闭包接收/发送。 BSP_OutByte(pDevData->IoBaseAddr + EN0_DCFG, DCR_FT | DCR_NO | DCR_WTS); //设置数据结构寄存器:FIFO片选,无Loopback正常模式,宽字DMA传送。 BSP_OutByte(pDevData->IoBaseAddr + EN0_RCNTLO, 0x00); //清远端RBCR0(DMA数据长度)寄存器。 BSP_OutByte(pDevData->IoBaseAddr + EN0_RCNTHI, 0x00); //清远端RBCR1(DMA数据长度)寄存器。 BSP_OutByte(pDevData->IoBaseAddr + EN0_RXCR,ENRXCR_RXOFF); //设置接收配置寄存器:监视模式。 BSP_OutByte(pDevData->IoBaseAddr + EN0_TXCR, ENTXCR_TXLOOKL); //设置传输配置寄存器:内部lookback。 /// 设置发送页和接收环状缓冲。 BSP_OutByte(pDevData->IoBaseAddr + EN0_TPSR, pDevData->txStartPage); //设置传送页面开始寄存器:传送数据包开始地址。 BSP_OutByte(pDevData->IoBaseAddr + EN0_STARTPG, pDevData->rxStartPage); //设置页面开始寄存器:接收缓冲区开始页面地址。 BSP_OutByte(pDevData->IoBaseAddr + EN0_BOUNDARY, pDevData->stopPage - 1); //设置边界寄存器:接收缓冲区最后页面指针。 pDevData->currentPage = pDevData->rxStartPage; //设置远端DMA读取指针(开始页面地址,BOUNDARY+1) BSP_OutByte(pDevData->IoBaseAddr + EN0_STOPPG, pDevData->stopPage); //设置页面停止寄存器:接收缓冲区停止页面地址。 BSP_OutByte(pDevData->IoBaseAddr + EN_CMD, ENCMD_NODMA + ENCMD_PAGE1 + ENCMD_STOP);//设置命令寄存器:寄存器页为1页,无DMA,关闭包接收/发送。 //设置 Multicast filter mask array (8 bytes),初始化 multicast list :0 accept-none ,0xff accept-all。 for(i = 0; i < 8; i++) { BSP_OutByte(pDevData->IoBaseAddr + EN1_MULT + i, 0); } /// set current start page BSP_OutByte(pDevData->IoBaseAddr + EN1_CURPAG, pDevData->rxStartPage); //设置接收缓冲区开始页面为当前开始页面。 BSP_OutByte(pDevData->IoBaseAddr + EN_CMD, ENCMD_NODMA+ENCMD_PAGE0+ENCMD_STOP); //设置命令寄存器:寄存器页为0页,无DMA,关闭包接收/发送。 /// Collision Offset Enable BSP_OutByte(pDevData->IoBaseAddr + EN0_TXCR, ENTXCR_TXCONFIG);//设置传输配置寄存器:使能冲突补偿。 ///在启动后设置 BSP_OutByte(pDevData->IoBaseAddr + EN_CMD, ENCMD_NODMA+ENCMD_PAGE0+ENCMD_START); //设置命令寄存器:寄存器页为0页,无DMA,打开包接收/发送。 BSP_OutByte( pDevData->IoBaseAddr + EN0_RXCR, ENRXCR_RXCONFIG); //设置接收配置寄存器:使能接收。 return TRUE;}/** * @brief * 功能: * 停止设备。 * * 实现内容: * 1、禁止设备的相关中断; * 2、使设备工作在低电源模式下,即设备不能正常的工作。 * * @param[in] vpHalDevData:指针,指向HAL数据表(T_HAL_RTL8019AS_DEV_DATA)。 * * @return 成功返回TRUE;否则,返回FALSE。 */T_BOOL RTL8019AS_Stop(T_VOID *vpHalDevData){ T_HAL_RTL8019AS_DEV_DATA *pDevData = (T_HAL_RTL8019AS_DEV_DATA *)vpHalDevData; //用户可在此处添加代码: BSP_OutByte(pDevData->IoBaseAddr + EN0_RXCR, ENRXCR_RXOFF); //设置接收配置寄存器:监视模式。 BSP_OutByte(pDevData->IoBaseAddr + EN0_TXCR, ENTXCR_TXLOOKL); //设置传输配置寄存器:内部lookback。 return TRUE;}/** * @brief * 功能: * 使能设备中断。 * * 实现内容: * 通过设置设备的控制寄存器来使能设备的中断,如接收、发送、错误检测等。 * 注:若用到系统中断控制器的外部中断,则置位系统中断控制器的相应位。 * * @param[in] vpHalDevData:指针,指向HAL数据表(T_HAL_RTL8019AS_DEV_DATA)。 * * @return 成功返回TRUE;否则,返回FALSE。 */T_BOOL RTL8019AS_ChipIntEnable(T_VOID *vpHalDevData){ T_HAL_RTL8019AS_DEV_DATA *pDevData = (T_HAL_RTL8019AS_DEV_DATA *)vpHalDevData; //用户可在此处添加代码: T_UBYTE keepCmd; BSP_InByte(pDevData->IoBaseAddr, keepCmd); //读出命令寄存器的值并保存。 BSP_OutByte(pDevData->IoBaseAddr + EN_CMD, ENCMD_NODMA+ENCMD_PAGE0);//设置命令寄存器:无DMA,寄存器页为0页。 BSP_OutByte(pDevData->IoBaseAddr + EN0_IMR, 0x35); //屏蔽发送中断。 BSP_OutByte(pDevData->IoBaseAddr, keepCmd); //恢复先前保存的命令寄存器的值。 return TRUE;}/** * @brief * 功能: * 禁止设备中断。 * * 实现内容: * 通过清除设备的控制寄存器来禁止设备的中断,如接收、发送、错误检测等。 * 注:若用到系统中断控制器的外部中断,则清除系统中断控制器的相应位。 * * @param[in] vpHalDevData:指针,指向HAL数据表(T_HAL_RTL8019AS_DEV_DATA)。 * * @return 成功返回TRUE;否则,返回FALSE。 */T_BOOL RTL8019AS_ChipIntDisable(T_VOID *vpHalDevData){ T_HAL_RTL8019AS_DEV_DATA *pDevData = (T_HAL_RTL8019AS_DEV_DATA *)vpHalDevData; //用户可在此处添加代码: T_UBYTE keepCmd; BSP_InByte(pDevData->IoBaseAddr, keepCmd); //读出命令寄存器的值并保存。 BSP_OutByte(pDevData->IoBaseAddr + EN_CMD, ENCMD_NODMA+ENCMD_PAGE0);//设置命令寄存器:无DMA,寄存器页为0页。 BSP_OutByte(pDevData->IoBaseAddr + EN0_IMR, 0x00); //屏蔽所有中断。 BSP_OutByte(pDevData->IoBaseAddr, keepCmd); //恢复先前保存的命令寄存器的值。 return TRUE;}/** * @brief * 功能: * 发送数据包。 * * 实现内容: * 1、读取发送状态; * 2、根据发送状态,决定是否将下一数据写入发送缓冲,若上一数据未发送完,则等待; * 同时也可以设置发送超时时间,若超时,返回发送失败; * 3、发送时,将数据包的大小也要写入到数据包长度寄存器。 * * @param[in] vpHalDevData:指针,指向HAL数据表(T_HAL_RTL8019AS_DEV_DATA)。 * @param[in] bpKtBuf:数据包所在的缓冲指针。 * @param[in] wKtLen:数据包长度。 * * @return 成功返回TRUE;否则,返回FALSE。 */T_BOOL RTL8019AS_SendPkt(T_VOID *vpHalDevData, T_BYTE *bpKtBuf, T_WORD wKtLen){ T_HAL_RTL8019AS_DEV_DATA *pDevData = (T_HAL_RTL8019AS_DEV_DATA *)vpHalDevData; //用户可在此处添加代码: T_UWORD currentOffset; T_UWORD outputPage = pDevData->txStartPage; T_UBYTE tsrStatus; T_UBYTE isrStatus; T_WORD wait = 0; T_WORD retval = 0; T_UBYTE keepCmd; BSP_InByte(pDevData->IoBaseAddr, keepCmd); BSP_OutByte(pDevData->IoBaseAddr + EN_CMD, ENCMD_NODMA+ENCMD_PAGE0); BSP_OutByte(pDevData->IoBaseAddr + EN0_ISR, 0xff); /// Copy the packet to the board's RAM. currentOffset = outputPage << 8; // 以256byte对齐,每页256byte if(wKtLen < 60) { wKtLen = 60; } //将用户BUF 中的数据发送到网卡发送缓冲中并判断复制是否成功 retval = RTL8019AS_BlockOutput(pDevData, wKtLen, (T_BYTE *)bpKtBuf, currentOffset); if (retval != 0) { BSP_OutByte(pDevData->IoBaseAddr, keepCmd); //恢复页面 return FALSE; } else { /// 复制成功,开始将板卡缓冲中数据发送到网络 retval = RTL8019AS_TriggerSend(pDevData, wKtLen); if(retval != 0) { BSP_OutByte(pDevData->IoBaseAddr, keepCmd); //恢复页面 return FALSE; } else { /// 等待发送完成(通过获取中断状态实现) BSP_OutByte(pDevData->IoBaseAddr + EN_CMD, ENCMD_NODMA+ENCMD_PAGE0); BSP_OutByte(pDevData->IoBaseAddr + EN0_ISR, isrStatus); while (!(isrStatus & 0xa) && (wait < 5000)) { wait++; } /// 获取中断状态,检查发送是否成功 BSP_OutByte(pDevData->IoBaseAddr + EN0_ISR, 0xa); BSP_InByte(pDevData->IoBaseAddr + EN0_TSR, tsrStatus); if(tsrStatus & (ENTSR_CRS | ENTSR_COL)) { BSP_OutByte(pDevData->IoBaseAddr, keepCmd); //恢复页面 return FALSE ; } } } //清中断,该处是disableinterrupt BSP_OutByte(pDevData->IoBaseAddr + EN_CMD, ENCMD_NODMA+ENCMD_PAGE0); BSP_OutByte(pDevData->IoBaseAddr + EN0_ISR, 0xff); BSP_OutByte(pDevData->IoBaseAddr, keepCmd); //恢复页面 return TRUE;}/** * @brief * 功能: * 获取接收到的数据包长度。 * * 实现内容:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -