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

📄 halrtl8139.c

📁 包含8139
💻 C
📖 第 1 页 / 共 3 页
字号:
   	   	{
				//if((txbusy & 0x0f) == 0x0f)
				//{
					// 处理超时,复位设备
					Rtl8139_TxTmo( pEtherDevDataTable );
					return FALSE;
				//}
   		}
   	}

   		// 计算下一个发送描述块的地址
	txbusy |= (1<<txentry);
	i = txentry + 1;

	i = (i)%NUM_TX_DESC;
  if( txbusy & (1<<i) )
  {
  	pEtherDevDataTable->tx_full = 1;
  	pEtherDevDataTable->txentry = i;
  }
  else
  {
  	pEtherDevDataTable->txentry = i;
	}


  pEtherDevDataTable->txbusy = txbusy;

	memcpy(pEtherDevDataTable->tx_buf[txentry], pktBuf, pktLen);
	BSP_OutLong( pEtherDevDataTable->IoBaseAddr + R8139_TSAD0+txentry*4,(unsigned long)(pEtherDevDataTable->tx_buf[txentry]));
	BSP_OutLong( pEtherDevDataTable->IoBaseAddr +R8139_TSD0+txentry*4,(pEtherDevDataTable->tx_flag )|(pktLen >= ETH_ZLEN ? pktLen : ETH_ZLEN));



	return TRUE;
}


/**
 * @brief
 *	    	使能设备中断。设备也许有多种类型的中断,网络组件只关心发送和接收中断而已
 *    其他中断类型的处理将由HAL本身负责解释并响应。所以此处使能的中断类型应该包括
 *    发送中断和接收中断,其他类型中断由HAL自行决定。
 *
 * @param[in] pEtherDevData:设备数据块指针,该结构的类型由HAL定义。
 *
 * @return 成功返回TRUE;否则,返回FALSE。
 */
T_BOOL rtl8139_ChipIntEnable( T_VOID *pEtherDevData )
{
	T_HAL_RTL8139_DEV_DATA *pEtherDevDataTable = (T_HAL_RTL8139_DEV_DATA *)pEtherDevData;
    // 清除现有中断标志位,置使能中断掩码
	BSP_OutHWord(pEtherDevDataTable->IoBaseAddr+R8139_IMR,
		PCIErr|PCSTimeout|RxUnderrun|RxOverflow|RxFIFOOver|TxErr|TxOK|RxErr|RxOK);
    //BSP_OutHWord( pEtherDevDataTable->IoBaseAddr + R8139_ISR, 0xffff );
	return TRUE;
}



/**
 * @brief
 *		关闭设备的中断。工作就是屏蔽在ChipIntEnable中使能的中断类型。
 *
 * @param[in] pEtherDevData 设备数据块指针,该结构的类型由HAL定义。
 *
 * @return 成功返回TRUE;否则,返回FALSE。
 */
T_BOOL rtl8139_ChipIntDisable( T_VOID *pEtherDevData )
{
	T_HAL_RTL8139_DEV_DATA *pEtherDevDataTable = (T_HAL_RTL8139_DEV_DATA *)pEtherDevData;
    // 设置中断屏蔽
	BSP_OutHWord( pEtherDevDataTable->IoBaseAddr + R8139_IMR, 0x0000 );
    return TRUE;
}


/**
 * @brief
 *		获取中断类型。当设备发生中断时,该接口将被调用。
 *
 * @param[in] pEtherDevData :设备数据块指针,该结构的类型由HAL定义。
 * @param[in] vector:产生中断的中断向量。
 * @param[out] *intInfo: 设备的中断信息,当返回的中断类型中包括"其他中断类型"
 					    时,该参数将被传给HandleOtherIntType的HAL接口。
 *
 * @return  当发生多种中断类型时,把如下的返回值采用‘位或’运算后再返回。
 * 			DEV_NO_INTERRUPT:该设备没有发生中断
 *			DEV_INT_HAD_HANDLED:设备发生了中断,但已经被处理了
 *			DEV_RECEIVE_INTERRUPT:设备发生了接收中断
 *			DEV_SENDOVER_INTERRUPT:设备发生了发生中断
 *			DEV_OHER_INTTYPE: 设备发生了其他的中断类型
 */
T_UWORD rtl8139_GetIntType( T_VOID *pEtherDevData, T_UWORD vector, T_WORD *intInfo )
{
	T_HAL_RTL8139_DEV_DATA *pEtherDevDataTable = (T_HAL_RTL8139_DEV_DATA *)pEtherDevData;
	int						ISRstatus = 0;
	T_UWORD  				ret = 0;
	T_UWORD					ioHWord;

	// 查询中断标志
  	BSP_InHWord( pEtherDevDataTable->IoBaseAddr +R8139_ISR, ISRstatus);

    // 清除中断标志
  	BSP_OutHWord( pEtherDevDataTable->IoBaseAddr +R8139_ISR,0xffff);

  	//Acknowledge all of the current interrupt sources ASAP.
  	if ((ISRstatus & (PCIErr|PCSTimeout|RxUnderrun|RxOverflow|RxFIFOOver
  					   |TxErr|TxOK|RxErr|RxOK)) == 0)
  	{
		return DEV_NO_INTERRUPT;
	}

	//优先处理故障中断
	if (ISRstatus & RxOverflow)
	{
		BSP_InHWord( pEtherDevDataTable->IoBaseAddr + R8139_CBR, ioHWord);
		pEtherDevDataTable->cur_rx = ioHWord % pEtherDevDataTable->rxBufLen;
		BSP_OutHWord( pEtherDevDataTable->IoBaseAddr +R8139_CAPR,pEtherDevDataTable->cur_rx-16);
		ret |= DEV_INT_HAD_HANDLED;
	}

  	if (ISRstatus & (RxOK|RxUnderrun|RxOverflow/*| RxErr*/|RxFIFOOver))/* Rx interrupt */
  	{
		ret |= DEV_RECEIVE_INTERRUPT;
	}
  	if (ISRstatus & (TxOK | TxErr))
  	{
  		Rtl8139_Tx( pEtherDevDataTable );
		//ret |= DEV_SENDOVER_INTERRUPT;
	  }

	*intInfo = ISRstatus;

    return ret;
}


/**
 * @brief
 *		获取设备当前接收到的数据包长度。当设备发生接收中断时,该接口将被调用。
 *
 * @param[in]		pEtherDevData: 设备数据块指针,该结构的类型由HAL定义。
 * @param[out]		pktLen:指针,指向数据包的长度
 *
 * @return 成功返回TRUE;否则,返回FALSE。
 */
T_BOOL rtl8139_GetPktLen( T_VOID *pEtherDevData, T_WORD *pktLen)
{
	T_HAL_RTL8139_DEV_DATA *pEtherDevDataTable = (T_HAL_RTL8139_DEV_DATA *)pEtherDevData;
	unsigned char 	*rx_ring = NULL;
	unsigned short	cur_rx = 0;

	unsigned long   rx_status;
	int 			ring_offset = 0;
    int 			rx_size = 0;
    T_WORD   		count = 0;
    T_BYTE			ioByte;
    T_HWORD			ioHWord;


	rx_ring = pEtherDevDataTable->rx_ring;
	cur_rx = pEtherDevDataTable->cur_rx;

	BSP_InByte( pEtherDevDataTable->IoBaseAddr + R8139_CR, ioByte);

	if( (ioByte & 1)==0 )
	{
		ring_offset = cur_rx % pEtherDevDataTable->rxBufLen;
		rx_status = *(unsigned long*)(rx_ring + ring_offset);
		rx_size = rx_status >> 16;

        if (!(rx_status&(RxBadSymbol|RxRunt|RxTooLong|RxCRCErr|RxBadAlign)))
		{
			// 接收到数据
			if( ( rx_size >= 64 ) && (rx_size <= 1518 ) )
			{
				count = rx_size-4;
			}
			else
			{
				BSP_InHWord( pEtherDevDataTable->IoBaseAddr +R8139_CBR, ioHWord);
				cur_rx = ioHWord % pEtherDevDataTable->rxBufLen;
				BSP_OutHWord( pEtherDevDataTable->IoBaseAddr +R8139_CAPR,cur_rx-16);
				pEtherDevDataTable->cur_rx = cur_rx ;
				count = 0;
            }
		}
		else
		{
			// 接收错误,丢弃所有数据包

			pEtherDevDataTable->cur_rx = 0;
			BSP_OutByte( pEtherDevDataTable->IoBaseAddr +R8139_CR,0x04);   /*enable tx*/
			BSP_OutByte( pEtherDevDataTable->IoBaseAddr +R8139_CR,0x0c);  /*enable tx and rx*/
			BSP_OutLong( pEtherDevDataTable->IoBaseAddr +R8139_RCR,
				(RX_FIFO_THRESH<<13)|(pEtherDevDataTable->rxBufSize<<11)|(RX_DMA_BURST<<8)|RX_OPTION);

			cur_rx += rx_size + 4;
			cur_rx = (cur_rx + 3) & ~3;
			BSP_OutHWord( pEtherDevDataTable->IoBaseAddr +R8139_CAPR,cur_rx-16);
			pEtherDevDataTable->cur_rx = cur_rx ;

			count = 0;
		}
	}
	else
	{
		return FALSE;
		}
	*pktLen =  count;

	return TRUE;
}



/**
 * @brief
 *		获取设备当前接收到的数据包的数据。当设备发生接收中断,
 *   且GetPktLen接口返回的数据包长度大于0时该接口将被调用。
 *
 * @param[in] pEtherDevData:设备数据块指针,该结构的类型由HAL定义。
 * @param[in] pktLen:数据包的长度 ,该参数即GetPktLen的返回值。
 *
 * @return 成功返回TRUE;否则,返回FALSE。
 */
T_BOOL rtl8139_GetPktData( T_VOID *pEtherDevData, T_CHAR * pktBuf, T_WORD pktLen )
{
	T_HAL_RTL8139_DEV_DATA *pEtherDevDataTable = (T_HAL_RTL8139_DEV_DATA *)pEtherDevData;
	unsigned char 	*rx_ring = NULL;
	unsigned short	cur_rx = 0;
	int 			ring_offset = 0;
	int 			semi_count = 0;
	int 			semi_count2 = 0;


	rx_ring = pEtherDevDataTable->rx_ring;
	cur_rx = pEtherDevDataTable->cur_rx;
	ring_offset = cur_rx % pEtherDevDataTable->rxBufLen;

	// 拷贝数据
	if (ring_offset+pktLen > pEtherDevDataTable->rxBufLen)
	{
		semi_count = pEtherDevDataTable->rxBufLen - ring_offset - 4;
		semi_count2 = pktLen - semi_count;
		if(semi_count>0)
		{
			memcpy(pktBuf , &rx_ring[ring_offset + 4],semi_count);
			memcpy(pktBuf+semi_count , rx_ring,semi_count2);
		}
		else
			memcpy(pktBuf , &rx_ring[-semi_count],pktLen);
	}
	else
		memcpy(pktBuf, &rx_ring[ring_offset + 4],pktLen);

	// 更新读写指针
	cur_rx += pktLen + 8;
	cur_rx = (cur_rx + 3) & ~3;
	BSP_OutHWord(pEtherDevDataTable->IoBaseAddr+R8139_CAPR,cur_rx-16);


	// 更新控制状态
	pEtherDevDataTable->cur_rx = cur_rx ;

    return TRUE;



}


/**
 * @brief
 *		处理其他的中断类型。中断类型参数intInfo即在GetIntType中返回的中断
 *	状态信息。该信息由HAL自己负责定义和解释。
 *
 * @param[in] pEtherDevData:设备数据块指针,该结构的类型由HAL定义。
 * @param[in] intInfo:中断状态信息。
 *
 * @return
 * 		FALSE 	失败
 *		TRUE	成功
 */
T_BOOL rtl8139_HandleOtherIsrType( T_VOID *pEtherDevData, T_WORD intInfo)
{
	T_HAL_RTL8139_DEV_DATA *pEtherDevDataTable = (T_HAL_RTL8139_DEV_DATA *)pEtherDevData;

  	if (intInfo & (TxOK | TxErr))
  	{
		//Rtl8139_Tx( pEtherDevDataTable );
	}
	return TRUE;

}



/**
 * @brief
 *		获取设备的MAC地址。
 *
 * @param[in]	pEtherDevData:设备数据块指针,该结构的类型由HAL定义。
 * @param[out]	macAddr:存放MAC地址的缓存。
 *
 * @return 成功返回TRUE;否则,返回FALSE。
 */
T_BOOL rtl8139_GetMacAddr( T_VOID *pEtherDevData, T_CHAR *macAddr )
{
	T_HAL_RTL8139_DEV_DATA *pEtherDevDataTable = (T_HAL_RTL8139_DEV_DATA *)pEtherDevData;
    T_WORD 		i = 0;

	// Bring the chip out of low-power mode.
	BSP_OutByte(pEtherDevDataTable->IoBaseAddr + R8139_CONFIG1,0x00);

    for(i = 0; i < 6; i++)
    {
        BSP_InByte( pEtherDevDataTable->IoBaseAddr + R8139_IDR0 + i, pEtherDevDataTable->macaddr[i] );

    }

	memcpy(macAddr,pEtherDevDataTable->macaddr,6);

    return TRUE;
}

/**
 * @brief
 *		设置设备的MAC地址。
 *
 * @param[in]	pEtherDevData:设备数据块指针,该结构的类型由HAL定义。
 * @param[out]	macAddr:存放MAC地址的缓存。
 *
 * @return 成功返回TRUE;否则,返回FALSE。
 */
T_BOOL rtl8139_SetMacAddr( T_VOID *pEtherDevData, T_CHAR *macAddr )
{
	T_HAL_RTL8139_DEV_DATA *pEtherDevDataTable = (T_HAL_RTL8139_DEV_DATA *)pEtherDevData;
    T_WORD 		i = 0;

	// Bring the chip out of low-power mode.
	BSP_OutByte(pEtherDevDataTable->IoBaseAddr + R8139_CONFIG1,0x00);

	BSP_OutByte( pEtherDevDataTable->IoBaseAddr + R8139_9346CR, 0xc0);

⌨️ 快捷键说明

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