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

📄 haldm9000.c

📁 包含8139
💻 C
📖 第 1 页 / 共 2 页
字号:
	DM9000_IOW(DM9000_REG00, RegSave);	// Restore previous register address
	
	return ret;
}

/**
 * @brief
 *		获取设备当前接收到的数据包长度。当设备发生接收中断时,该接口将被调用。
 *
 * @param[in]	vpEtherDevData 设备数据块指针,该结构的类型由HAL定义。
 * @param[out]	wKtLen数据包的长度。 
 *
 * @return 
 * 		FALSE 	失败。
 *		TRUE	成功	。	
 */
T_BOOL DM9000_GetPktLen(T_VOID *vpEtherDevData, T_WORD *wKtLen)
{
	volatile T_UHWORD RxStatus;
	T_BYTE RxReady;
	T_HAL_DM9000_DEV_DATA *tpEtherDevDataTable = (T_HAL_DM9000_DEV_DATA *)vpEtherDevData;

	DM9000_IOR(MRCMDX, RxReady);    // Dummy read
	RxReady = *((T_BYTE *)(tpEtherDevDataTable->vbpDM9000Addr+4));
    
    if (RxReady == DM9000_PKT_RDY)
    {
		*((T_BYTE *)(tpEtherDevDataTable->vbpDM9000Addr)) = 0xf2;
		RxStatus= *((T_HWORD *)(tpEtherDevDataTable->vbpDM9000Addr+4));
		*wKtLen	= *((T_HWORD *)(tpEtherDevDataTable->vbpDM9000Addr+4));
		
		return TRUE;
    }
	 	
	return FALSE;
}

/**
 * @brief
 *		获取设备当前接收到的数据包的数据。当设备发生接收中断,
 *   且GetPktLen接口返回的数据包长度大于0时该接口将被调用。
 *
 * @param[in] vpEtherDevData	设备数据块指针,该结构的类型由HAL定义。
 * @param[in] wKtLen			数据包的长度 ,该参数即GetPktLen的返回值。
 *
 * @return TRUE	成功	(始终返回该值)	。
 */
T_BOOL DM9000_GetPktData(T_VOID *vpEtherDevData, T_CHAR * bpKtBuf, T_WORD wKtLen)
{
	T_HWORD	Tmplen = 0;
	T_WORD	i = 0;
	T_HAL_DM9000_DEV_DATA *tpEtherDevDataTable = (T_HAL_DM9000_DEV_DATA *)vpEtherDevData;

	Tmplen = (wKtLen + 1) / 2;	
	for (i = 0; i < Tmplen; i++)	
	{
		((T_HWORD *)bpKtBuf)[i] = *((T_HWORD *)(tpEtherDevDataTable->vbpDM9000Addr+4));	
	}

    return TRUE;
}

/**
 * @brief
 *		处理其他的中断类型。中断类型参数intInfo即在GetIntType中返回的中断。
 *	状态信息。该信息由HAL自己负责定义和解释。
 *
 * @param[in] vpEtherDevData 设备数据块指针,该结构的类型由HAL定义。
 * @param[in] wpIntInfo 中断状态信息。
 *
 * @return TRUE	成功	(始终返回该值)。	
 */
T_BOOL DM9000_HandleOtherIsrType(T_VOID *vpEtherDevData, T_WORD wIntInfo)
{
	return TRUE;	
}

/**
 * @brief
 *		停止(或暂停)设备的运行,就是让该IO设备不能(正常)输入输出。
 *	该函数一般就是要设置DISABLE位,或者把该设备设置为内循环模式
 *	等。
 *
 * @param[in] vpEtherDevData 设备数据块指针,该结构的类型由HAL定义。
 * 
 * @return TRUE	成功	(始终返回该值)。	
 */
T_BOOL DM9000_Stop(T_VOID *vpEtherDevData)
{
	T_HAL_DM9000_DEV_DATA *tpEtherDevDataTable = (T_HAL_DM9000_DEV_DATA *)vpEtherDevData;
	
	tpEtherDevDataTable->tEiStatus.start = 0;	// interface disable
	tpEtherDevDataTable->tEiStatus.tbusy = 1;	// 不能传输

	PhyWrite(vpEtherDevData, 0x00, 0x8000);	// PHY RESET
	DM9000_IOW(GPR, 0x01);	// Power-Down PHY
	DM9000_IOW(IMR, 0x80);	// Disable all interrupt
	DM9000_IOW(RCR, 0x00);	// Disable RX
	
	return TRUE;
}

/**
 * @brief
 *	  	释放HAL占用的资源(主要指在GetResource中获取到的资源)。 
 *
 * @param[in] vpEtherDevData 设备数据块指针,该结构的类型由HAL定义。
 * 
 * @return TRUE	成功	(始终返回该值)。	
 */
T_BOOL DM9000_ReleaseResource(T_VOID *vpEtherDevData)
{
	return TRUE;
}

/**
 * @brief
 *		获取该网络设备的网络连接情况。
 *
 * @param[in]	vpEtherDevData	设备数据块指针,该结构的类型由HAL定义。
 * @param[out]	wplineStatus	连接状态。
 				DNET_IFOPERSTATUS_UP 或者 DNET_IFOPERSTATUS_DOWN。
 *
 * @return FALSE 	失败(始终返回该值)。	
 */
T_BOOL DM9000_LineCheck(T_VOID *vpEtherDevData, T_WORD *wplineStatus)
{
	return FALSE;
}

/**
 * @brief
 *		获取设备的MAC地址。
 *
 * @param[in	vpEtherDevData	设备数据块指针,该结构的类型由HAL定义。
 * @param[out]	bpmacAddr		存放MAC地址的缓存。
 *
 * @return TRUE	成功	(始终返回该值)。	
 */
T_BOOL DM9000_GetMacAddr(T_VOID *vpEtherDevData, T_CHAR *bpmacAddr)
{
	T_WORD i;
	T_HAL_DM9000_DEV_DATA *tpEtherDevDataTable = (T_HAL_DM9000_DEV_DATA *)vpEtherDevData;
	
	for(i = 0; i < 6; i++)
	{
		bpmacAddr[i] = tpEtherDevDataTable->tEiStatus.local_mac_address[i];
	}
	return TRUE;
}


/**
 * @brief
 *		获取设备的MAC地址。
 *
 * @param[in	vpEtherDevData	设备数据块指针,该结构的类型由HAL定义。
 * @param[out]	bpmacAddr		存放MAC地址的缓存。
 *
 * @return TRUE	成功	(始终返回该值)。	
 */
T_BOOL DM9000_SetMacAddr( T_VOID *vpEtherDevData, T_CHAR *bpmacAddr )
{
	T_WORD i;
	T_HAL_DM9000_DEV_DATA *tpEtherDevDataTable = (T_HAL_DM9000_DEV_DATA *)vpEtherDevData;
	
	for(i = 0; i < 6; i++)
	{
		tpEtherDevDataTable->tEiStatus.local_mac_address[i] = bpmacAddr[i];
		DM9000_IOW(PAR + i, tpEtherDevDataTable->tEiStatus.local_mac_address[i]);	
	}
	
	return TRUE;
}


/**
 * @brief
 *	  	增加一个组播地址到该网卡
 *
 * @param[in] pEtherDevData 设备数据块指针,该结构的类型由HAL定义
 * 
 * @param[in] macAddr 指向一个6字节的存储空间,内容为需要增加的组播MAC地址
 * 
 * @param[in] multiMacChian 指向一个组播地址链,该链上的组播地址应该都被设置进入该网卡.该链的结构是
 *							typedef struct ether_multi{
 *											char haddr[6];							//组播地址
 *											unsigned short emc_users;   //该组播地址的用户数,对于驱动,不需要关心该参数
 *											struct ether_multi * next;  //指向下一节点
 *										}ETHER_MULTI;
 *
 *							typedef struct macforhash{
 *											unsigned char macaddr[6];		//要操作的组播MAC地址
 * 											ETHER_MULTI * chainpointer;	//该设备需要设置的组播地址链
 *										}T_MACHASH;
 *						multiMacChian为 T_MACHASH 指针类型,该参数的使用是可选的.
 *						即,HAL中,增加组播地址的实现既可仅根据macaddr参数进行操作,
 *								也可以根据multiMacChain来全部重新设定网卡组播地址
 *
 * @return 
 * 		FALSE 	失败
 *		TRUE		成功		
 */
T_BOOL DM9000_AddMultiAddr( T_VOID * vpEtherDevData, T_CHAR *bMacAddr, T_VOID * vMultiMacChain)
{
	return TRUE;
}				

/**
 * @brief
 *	  	删除该网卡的一个组播地址
 *
 * @param[in] pEtherDevData 设备数据块指针,该结构的类型由HAL定义
 * 
 * @param[in] macAddr 指向一个6字节的存储空间,内容为需要删除的组播MAC地址
 * 
 * @param[in] multiMacChian 指向一个组播地址链,该链上的组播地址应该都被设置进入该网卡.该链的结构是
 *							typedef struct ether_multi{
 *											char haddr[6];							//组播地址
 *											unsigned short emc_users;   //该组播地址的用户数,对于驱动,不需要关心该参数
 *											struct ether_multi * next;  //指向下一节点
 *										}ETHER_MULTI;
 *
 *							typedef struct macforhash{
 *											unsigned char macaddr[6];		//要操作的组播MAC地址
 * 											ETHER_MULTI * chainpointer;	//该设备需要设置的组播地址链
 *										}T_MACHASH;
 *						multiMacChian为 T_MACHASH 指针类型,该参数的使用是可选的.
 *						即,HAL中,删除组播地址的实现既可仅根据macaddr参数进行操作,
 *								也可以根据multiMacChain来全部重新设定网卡组播地址
 *
 * @return 
 * 		FALSE 	失败
 *		TRUE		成功		
 */
T_BOOL DM9000_DelMultiAddr( T_VOID * vpEtherDevData, T_CHAR *bMacAddr, T_VOID * vMultiMacChain)
{
	return TRUE;
}

/**
 * @brief
 *		通过读取芯片的vendor,判断DM9000是否存在。
 *
 * @param[in] tpEtherDevDataTable	设备数据块指针,该结构的类型由HAL定义。
 * @param[in] wIndex				该设备在系统中相同设备的索引。
 *
 * @return 
 * 		FALSE 	失败
 *		TRUE	成功		
 */
T_MODULE T_BOOL Probe(T_HAL_DM9000_DEV_DATA * vpEtherDevData)
{
	T_BYTE vid = 0;
	T_WORD IoMode;
	T_HAL_DM9000_DEV_DATA *tpEtherDevDataTable = (T_HAL_DM9000_DEV_DATA *)vpEtherDevData;

	//设置arm上的参数
	rPCONB &= 0x7df;	//set the PB5 be Output
	rPDATB &= 0x7df;	//set the PB5 be low level(not always RST DM9000)

	// make PB10 as GCS5
	rPCONB = rPCONB | 0x400;

	rPCONF = (rPCONF & 0x07ffff) | 0x080000;
	
	//make GPF8 pull up!
	rPUPF = rPUPF & 0xff;
	
	//make GPF8 bit as LOW
	rPDATF = rPDATF & 0xff;

	DM9000_IOR(ISR, IoMode);
	
	DM9000_IOR(VID_L, vid);
	if(vid != 0x46)
		return FALSE;
		
	DM9000_IOR(VID_H, vid);
	if(vid != 0xa)
		return FALSE;

	return TRUE;
}

/**
 * @brief
 *		写入phy。
 *
 * @param[in]	wReg	寄存器号。
 * @param[out]	uhValue	读出的值。
 * 
 * @return 	无。	
 */
T_MODULE T_VOID PhyRead(T_VOID *vpEtherDevData, T_WORD wReg, T_UHWORD *uhpValue)
{
	T_UHWORD vHValue;	
	T_UHWORD vLValue;
	T_WORD i;
	T_HAL_DM9000_DEV_DATA *tpEtherDevDataTable = (T_HAL_DM9000_DEV_DATA *)vpEtherDevData;

	//Fill the phyxcer register into REG_0C
	DM9000_IOW(EPAR, DM9000_PHY | wReg);

	DM9000_IOW(EPCR, 0xc);		// Issue phyxcer read command
	for( i = 0; i < 500; i++ );	// Wait write complete 100 us 
	DM9000_IOW(EPCR, 0x0);		// Clear phyxcer read command 

	//The read data keeps on REG_0D & REG_0E
	DM9000_IOR(EPDRH, vHValue);
	DM9000_IOR(EPDRL, vLValue);
	*uhpValue = ((vHValue << 8) | vLValue);
}

/**
 * @brief
 *		写入phy。
 *
 * @param[in] wReg		寄存器号。
 * @param[in] uhValue	要写入的值。
 * 
 * @return 	无。	
 */
T_MODULE T_VOID PhyWrite(T_VOID *vpEtherDevData, T_WORD wReg, T_UHWORD uhValue)
{
    T_WORD i;
    T_HAL_DM9000_DEV_DATA *tpEtherDevDataTable = (T_HAL_DM9000_DEV_DATA *)vpEtherDevData;

	DM9000_IOW(EPAR, DM9000_PHY | wReg);	// Fill the phyxcer register into REG_0C
	DM9000_IOW(EPDRL, (uhValue & 0xff));	// Fill the written data into REG_0D & REG_0E
    DM9000_IOW(EPDRH, ((uhValue >> 8) & 0xff) );
	DM9000_IOW(EPCR, 0xa );        		// Issue phyxcer write command 
	
	// Wait write complete 500 us
	for( i = 0; i < 3000; i++ )
	{
		;			
	}
	
	DM9000_IOW(EPCR, 0x0);				// Clear phyxcer write command
}

/**
 * @brief
 *		设置 PHY操作模式。
 *
 * @param	无。
 * 
 * @return 	无。	
 */
T_MODULE T_VOID SetPHYMode(T_VOID *vpEtherDevData)
{
	T_HAL_DM9000_DEV_DATA *tpEtherDevDataTable = (T_HAL_DM9000_DEV_DATA *)vpEtherDevData;
	T_UDWORD  PhyReg4	= 0x01e1;
	T_UDWORD  PhyReg0	= 0x1000;

	PhyWrite(vpEtherDevData, 0x00, 0x8000);		// PHY RESET
 	DM9000_IOW(GPR, 0x00);		// Power Down PHY
 	
    if (!(tpEtherDevDataTable->op_mode & DM9000_AUTO))
    {
		switch(tpEtherDevDataTable->op_mode)
		{
			case DM9000_10MHD:
				PhyReg4 = 0x21;
				PhyReg0 = 0x0000; 
				break;
			case DM9000_10MFD:
				PhyReg4 = 0x41; 
				PhyReg0 = 0x0100; 
				break;
			case DM9000_100MHD: 
				PhyReg4 = 0x81; 
				PhyReg0 = 0x2000; 
				break;
			case DM9000_100MFD: 
				PhyReg4 = 0x101; 
				PhyReg0 = 0x2100; 
				break;
			default:
				break;
		}
		
	    PhyWrite(vpEtherDevData,4, PhyReg4);	//Set PHY media mode
		PhyWrite(vpEtherDevData,0, PhyReg0);	//Tmp
	}

	DM9000_IOW(GPCR, 0x01);		// Register On PHY. GPIO0 output
	DM9000_IOW(GPR, 0x00);		// Power On PHY
}

⌨️ 快捷键说明

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