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

📄 halrtl8019as.c

📁 包含8139
💻 C
📖 第 1 页 / 共 3 页
字号:
 *		根据读取接收计数寄存器的值,来得到接收数据包的长度。 * * @param[in] 	vpHalDevData:指针,指向HAL数据表(T_HAL_RTL8019AS_DEV_DATA)。 * @param[out]	wpKtLen:指针,数据包的长度。 * * @return	成功返回TRUE;否则,返回FALSE。 */T_BOOL RTL8019AS_GetPktLen(T_VOID *vpHalDevData, T_WORD *wpKtLen){	T_HAL_RTL8019AS_DEV_DATA	*pDevData = (T_HAL_RTL8019AS_DEV_DATA *)vpHalDevData;	//用户可在此处添加代码:	T_UWORD       thisFrame;	T_UWORD       currentOffset;	T_UWORD       headSize;	T_UHWORD      count = 0;	T_UBYTE       keepCmd;	T_UBYTE       frame;	EN_PKTHEADER_T rxFrame;	BSP_InByte(pDevData->IoBaseAddr,keepCmd);                                     //读出命令寄存器的值并保存。	/// Get the rx page (incoming packet pointer).	BSP_OutByte(pDevData->IoBaseAddr + EN_CMD, ENCMD_NODMA + ENCMD_PAGE1);        //设置命令寄存器:无DMA,寄存器页为1页。	BSP_InByte(pDevData->IoBaseAddr + EN1_CURPAG,pDevData->rxingPage);            //读取当前写入页面指针(写入网卡缓存的数据首地址)。	if(!pDevData->flag)                                                      //如果没有接收到正确的数据。	{NonCopy_Return:		pDevData->currentPage = pDevData->rxingPage;                         //重新设定当前页面位置。		BSP_OutByte(pDevData->IoBaseAddr + EN_CMD, ENCMD_NODMA + ENCMD_PAGE0);    //设置命令寄存器:无DMA,寄存器页为0页。		BSP_OutByte(pDevData->IoBaseAddr + EN0_BOUNDARY, pDevData->rxingPage - 1);//设置边界寄存器:当前写入地址-1。		BSP_OutByte(pDevData->IoBaseAddr,  keepCmd);                              //恢复先前保存的命令寄存器的值。		return FALSE;	}	else									                                 //接收到了正确的信息。	{		if(pDevData->currentPage == pDevData->rxingPage)                     //写入页面指针无变化。		{			BSP_OutByte(pDevData->IoBaseAddr, keepCmd);                           //恢复先前保存的命令寄存器的值。			return FALSE;		}		BSP_OutByte(pDevData->IoBaseAddr + EN_CMD, ENCMD_NODMA + ENCMD_PAGE0);    //设置命令寄存器:无DMA,寄存器页为0页。		BSP_InByte(pDevData->IoBaseAddr + EN0_BOUNDARY,frame);                    //读页指针移动一,到当前写入数据地址(写页指针)。		thisFrame = frame + 1;		thisFrame = RTL8019AS_RingIndex(pDevData, thisFrame);                //设定指针的循环(接收循环FIFO队列)。		if(thisFrame != pDevData->currentPage)                               //读页指针不等于写页指针。		{			thisFrame = pDevData->currentPage;                               //调整读页指针等于写页指针。		}		currentOffset = thisFrame << 8;                                      //由页(256byte)地址的到实际地址。		headSize = sizeof(rxFrame);		RTL8019AS_BlockInput(headSize, (T_BYTE*) & rxFrame, currentOffset,pDevData); //获取包头数据。		if(!RTL8019AS_CheckFrame(pDevData, thisFrame ,(EN_PKTHEADER_T*) & rxFrame))//检查包头信息判断这个包中的数据是否正确。		{            BSP_OutByte(pDevData->IoBaseAddr, keepCmd);                           //恢复先前保存的命令寄存器的值。			return FALSE;		}		pDevData->currentPage = rxFrame.next;                        //设定当前页面为接收包的下一页。		if((rxFrame.status & 0x0F) == ENRSR_RXOK)                    //接收到正确的包。		{			count = rxFrame.count - headSize;                        //有效数据长度:接收到的数据长度减去包头长度。		}		else                                                         //如果没有接收到正确的包		{			goto NonCopy_Return;		}		//记录下在GetPktData中需要使用到的数据		pDevData->next = rxFrame.next;		pDevData->curOffset = currentOffset;		pDevData->headSize = headSize;	}	*wpKtLen = count;                                                //将数据包长度值传给上层提供的参数。	BSP_OutByte(pDevData->IoBaseAddr + EN_CMD, ENCMD_NODMA + ENCMD_PAGE0);//设置命令寄存器:无DMA,寄存器页为0页。	BSP_OutByte(pDevData->IoBaseAddr + EN0_ISR,ENISR_PRX + ENISR_RXE);    //清中断状态寄存器。	BSP_OutByte(pDevData->IoBaseAddr, keepCmd);                           //恢复先前保存的命令寄存器的值。	pDevData->flag = 0;	return TRUE;}/** * @brief *	功能: *		获取接收到的数据。 * *  实现内容: *		拷贝已经接收的数据到指针(bpKtBuf)所指向的内存空间。 * * @param[in] vpHalDevData:指针,指向HAL数据表(T_HAL_RTL8019AS_DEV_DATA)。 * @param[in] bpKtBuf:指针,指向数据缓冲区。 * @param[in] wKtLen:数据包的长度,该参数即GetPktLen的返回值。 * * @return	成功返回TRUE;否则,返回FALSE。 */T_BOOL RTL8019AS_GetPktData(T_VOID *vpHalDevData, T_BYTE *bpKtBuf, T_WORD wKtLen){	T_HAL_RTL8019AS_DEV_DATA	*pDevData = (T_HAL_RTL8019AS_DEV_DATA *)vpHalDevData;	//用户可在此处添加代码:	T_UWORD        current_offset;	T_UBYTE        keepCmd;	BSP_InByte(pDevData->IoBaseAddr, keepCmd);                                  //记录基地址	//设置参数	current_offset = pDevData->curOffset + pDevData->headSize;	RTL8019AS_BlockInput(wKtLen , bpKtBuf , current_offset,pDevData);               //接收数据到分配的缓冲区中	/// set next recieve page 重新设定指针,指向当前最后1个数据所在的位置	BSP_OutByte(pDevData->IoBaseAddr + EN_CMD, ENCMD_NODMA+ENCMD_PAGE0);	BSP_OutByte(pDevData->IoBaseAddr + EN0_BOUNDARY, pDevData->next - 1);	BSP_OutByte(pDevData->IoBaseAddr,keepCmd);	return TRUE;}/** * @brief *	功能: *		获取设备的中断类型。 * *  实现内容: *		通过读取中断状态寄存器,来判断设备有无中断发生,若有中断产生,则判断是接收、发送、错误中断。 *	注:如果产生相应的设备中断,清除对应的中断标志位。 * * @param[in]	vpHalDevData:指针,指向HAL数据表(T_HAL_RTL8019AS_DEV_DATA)。 * @param[in]	uwVector:中断向量。 * @param[out]	wpIntInfo:指针,中断信息。 * * @return * 		DEV_NO_INTERRUPT:			无中断产生。 *		DEV_INT_HAD_HANDLED:		硬件中断处理。 *      DEV_RECEIVE_INTERRUPT:	    接收中断产生。 *		DEV_SENDOVER_INTERRUPT:	    发送中断产生。 *		DEV_OTHER_INTTYPE:		    其他的中断类型。 *		当发生多种中断时,把相应中断类型位或运算后返回。 */T_UWORD RTL8019AS_GetIntType(T_VOID *vpHalDevData, T_UWORD uwVector, T_WORD *wpIntInfo){	T_HAL_RTL8019AS_DEV_DATA *pDevData = (T_HAL_RTL8019AS_DEV_DATA *)vpHalDevData;    //用户可在此处添加代码:	T_UBYTE keepCmd;	T_WORD  isrStatus;	T_UWORD ret = 0;	BSP_InByte(pDevData->IoBaseAddr,keepCmd);                               //读出命令寄存器的值并保存。	BSP_OutByte(pDevData->IoBaseAddr + EN_CMD, ENCMD_NODMA + ENCMD_PAGE0);  //设置命令寄存器:无DMA,寄存器页为0页。	BSP_InByte(pDevData->IoBaseAddr + EN0_ISR,isrStatus);    isrStatus = (isrStatus & ENISR_PART);                              //读中断状态寄存器获取中断类型(不处理发送完成中断)。	BSP_OutByte(pDevData->IoBaseAddr  +EN0_ISR,0xff);                       //清中断状态寄存器。	if(isrStatus & ENISR_OVW)                                          //网卡接收缓冲区溢出,做重启芯片处理。	{		RTL8019AS_HandlerOverflow(pDevData);		ret |= DEV_INT_HAD_HANDLED;	}	if(0 == (isrStatus & (ENISR_PRX | ENISR_RXE | ENISR_TXE | ENISR_OVW | ENISR_CNT)))	{		ret |= DEV_NO_INTERRUPT;	}	if(isrStatus & (ENISR_PRX | ENISR_RXE))//接收中断。	{		ret|= DEV_RECEIVE_INTERRUPT;		if( isrStatus & ENISR_PRX ) 	    //正确接收数据,做接收处理。		{			pDevData->flag = 1;		}		else						 	    //接受错误过多,调整指针,但不接收数据。		{			 pDevData->flag = 0;		}	}	if(isrStatus & (ENISR_TXE | ENISR_CNT))//冲突过多导致传送失败,网络记数器记数。	{		ret |= DEV_OHER_INTTYPE ;	}	BSP_OutByte(pDevData->IoBaseAddr, keepCmd); //恢复先前保存的命令寄存器的值。	*wpIntInfo = isrStatus;                //将中断状态传给上层传入的参数。	BSP_OutByte(pDevData->IoBaseAddr + EN_CMD, ENCMD_NODMA + ENCMD_PAGE0 + ENCMD_START);//调试时添加	return ret;}/** * @brief *	功能: *		处理其他类型的中断。 * *  实现内容: *		根据中断类型,作相应的处理。 * * @param[in] vpHalDevData:指针,指向HAL数据表(T_HAL_RTL8019AS_DEV_DATA)。 * @param[in] wpIntInfo: 中断状态信息。 * * @return	成功返回TRUE;否则,返回FALSE。 */T_BOOL RTL8019AS_HandleOtherIsrType(T_VOID *vpHalDevData, T_WORD wIntInfo){	T_HAL_RTL8019AS_DEV_DATA *pDevData = (T_HAL_RTL8019AS_DEV_DATA *)vpHalDevData;	//用户可在此处添加代码:	T_WORD isrStatus;	isrStatus = wIntInfo;	if(isrStatus & ENISR_TXE)	                           //冲突过多导致传送失败,重发INT judge	{		BSP_OutByte(pDevData->IoBaseAddr + EN0_ISR, ENISR_TXE); //清中断中断状态寄存器。	}	if(isrStatus & ENISR_CNT)                              //网络记数器的MSB设置完成。	{		RTL8019AS_UpdateCounters(pDevData);                        //刷新网络记数器。	}	return TRUE;}/** * @brief *	功能: *		获取设备的网络连接情况。 * *  实现内容: *		读取相关寄存器的值,来判断网络的连接情况。 * * @param[in]	vpHalDevData:指针,指向HAL数据表(T_HAL_RTL8019AS_DEV_DATA)。 * @param[out]	wplineStatus:连接状态。 *				ETHER_IFOPERSTATUS_UP:	在线。 *				ETHER_IFOPERSTATUS_DOWN:离线。 * * @return	成功返回TRUE;否则,返回FALSE。 */T_BOOL RTL8019AS_LineCheck(T_VOID *vpHalDevData, T_WORD *wplineStatus){	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_BYTE  buf[60];	T_WORD  i;	T_WORD  wait = 0;	T_WORD  retval = 0;	for(i = 0; i < 60; i++)	{		buf[i] = i;	}	BSP_OutByte(pDevData->IoBaseAddr + EN_CMD, ENCMD_PAGE0 + ENCMD_START + ENCMD_NODMA);//设置命令寄存器:寄存器页为0页,打开包接收/发送,无DMA。	BSP_OutByte(pDevData->IoBaseAddr + EN0_IMR,0x00);                                   //设置中断控制寄存器:屏蔽所有中断。	currentOffset = outputPage << 8;   	RTL8019AS_BlockOutput(pDevData, 60,(T_BYTE *)buf, currentOffset);                   //将用户BUF 中的数据发送到网卡发送缓冲中。	retval = RTL8019AS_TriggerSend(pDevData, 60);                                       //将网卡缓冲中数据发送到网络并判断是否成功。	if (retval != 0)	{		*wplineStatus = DNET_IFOPERSTATUS_DOWN;		return FALSE;	}	BSP_OutByte(pDevData->IoBaseAddr + EN_CMD,ENCMD_NODMA + ENCMD_PAGE0);               //设置命令寄存器:无DMA,寄存器页为0页。	BSP_InByte(pDevData->IoBaseAddr + EN0_ISR,isrStatus);                               //读中断状态寄存器。	while (!(isrStatus & 0xa) && (wait < 5000))	{		BSP_InByte(pDevData->IoBaseAddr + EN0_ISR,isrStatus);                           //等待发送完成(通过获取发送完成中断状态实现)。		wait++;	}	BSP_OutByte(pDevData->IoBaseAddr + EN0_ISR,0xa);                                    //清中断状态寄存器。	BSP_InByte(pDevData->IoBaseAddr + EN0_TSR,tsrStatus);                               //读传输状态寄存器获取数据包传输状态。	if(tsrStatus & (ENTSR_CRS | ENTSR_CDH))                                             //传输过程中数据包丢失或者传送器传送信号失败。	{		*wplineStatus = DNET_IFOPERSTATUS_DOWN;		return FALSE;	}	*wplineStatus = DNET_IFOPERSTATUS_UP;	return TRUE;}/** * @brief *		获取设备的MAC地址 * * @param[in]  vpHalDevData:设备数据块指针,该结构的类型由HAL定义 * @param[out] cpMacAddr:存放MAC地址的缓存 * * @return * 		FALSE 	失败 *		TRUE	成功 */T_BOOL RTL8019AS_GetMacAddr(T_VOID *vpHalDevData, T_CHAR *cpMacAddr){	T_HAL_RTL8019AS_DEV_DATA *pDevData = (T_HAL_RTL8019AS_DEV_DATA *)vpHalDevData;	//用户可在此处添加代码:	T_WORD 	i;	T_CHAR keepCmd;	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++)	{		BSP_InByte(pDevData->IoBaseAddr + EN1_PHYS + i, pDevData->macaddr[i]);          //将MAC地址从寄存器中取出存放到数组中。	}	memcpy(cpMacAddr,pDevData->macaddr,6);                                         //将MAC地址传给上层提供的参数。	BSP_OutByte(pDevData->IoBaseAddr,keepCmd);                                          //恢复先前保存的命令寄存器的值。    return TRUE;}/** * @brief *		设置设备的MAC地址 * * @param[in] vpHalDevData:设备数据块指针,该结构的类型由HAL定义 * @param[in] cpMacAddr:存放MAC地址的缓存 * * @return * 		FALSE 	失败 *		TRUE	成功 */T_BOOL RTL8019AS_SetMacAddr(T_VOID *vpHalDevData, T_CHAR *cpMacAddr){	T_HAL_RTL8019AS_DEV_DATA *pDevData = (T_HAL_RTL8019AS_DEV_DATA *)vpHalDevData;	//用户可在此处添加代码:	T_WORD 	i;	T_UBYTE keep_cmd;	BSP_InByte(pDevData->IoBaseAddr, keep_cmd );                                        //读出命令寄存器的值并保存。	BSP_OutByte(pDevData->IoBaseAddr + EN_CMD, ENCMD_NODMA + ENCMD_PAGE1 + ENCMD_STOP);	for(i = 0; i < 6; i++)	{		pDevData->macaddr[i] = cpMacAddr[i];                                       //将MAC地址写入RTL8019网卡设备的PAR0-PAR5寄存器。		BSP_OutByte(pDevData->IoBaseAddr + EN1_PHYS + i, pDevData->macaddr[i]);	}	BSP_OutByte(pDevData->IoBaseAddr,keep_cmd);                                         //恢复先前保存的命令寄存器的值。    return TRUE;}/** * @brief *	  增加一个组播地址到该网卡 * * @param[in] vpHalDevData 设备数据块指针,该结构的类型由HAL定义 * * @param[in] bMacAddr 指向一个6字节的存储空间,内容为需要增加的组播MAC地址 *

⌨️ 快捷键说明

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