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

📄 halat91rm9200emac.c

📁 包含8139
💻 C
📖 第 1 页 / 共 2 页
字号:
 * * @param[in	vpEtherDevData	设备数据块指针,该结构的类型由HAL定义。 * @param[out]	bpmacAddr		存放MAC地址的缓存。 * * @return TRUE	成功	(始终返回该值)。 */T_BOOL AT91RM9200EMAC_GetMacAddr(T_VOID *vpEtherDevData, T_CHAR *bpmacAddr){	T_HAL_AT91RM9200EMAC_DEV_DATA *tpEtherDevDataTable = (T_HAL_AT91RM9200EMAC_DEV_DATA *)vpEtherDevData;    memcpy(bpmacAddr, tpEtherDevDataTable->emacAddr, 6);	return TRUE;}/** * @brief *		获取设备的MAC地址。 * * @param[in	vpEtherDevData	设备数据块指针,该结构的类型由HAL定义。 * @param[out]	bpmacAddr		存放MAC地址的缓存。 * * @return TRUE	成功	(始终返回该值)。 */T_BOOL AT91RM9200EMAC_SetMacAddr(T_VOID *vpEtherDevData, T_CHAR *bpmacAddr){	T_HAL_AT91RM9200EMAC_DEV_DATA *tpEtherDevDataTable = (T_HAL_AT91RM9200EMAC_DEV_DATA *)vpEtherDevData;	tpAT91_EMAC pEmac;	memcpy(tpEtherDevDataTable->emacAddr,bpmacAddr, 6);	pEmac->EMAC_SA1L = ((int)tpEtherDevDataTable->emacAddr[2] << 24) | ((int)tpEtherDevDataTable->emacAddr[3] << 16) | ((int)tpEtherDevDataTable->emacAddr[4] << 8) |tpEtherDevDataTable->emacAddr[5];    pEmac->EMAC_SA1H = ((int)tpEtherDevDataTable->emacAddr[0] << 8) | tpEtherDevDataTable->emacAddr[1];	return TRUE;}/** * @brief *	  增加一个组播地址到该网卡 * * @param[in] vpHalDevData 设备数据块指针,该结构的类型由HAL定义 * * @param[in] bMacAddr 指向一个6字节的存储空间,内容为需要增加的组播MAC地址 * * @param[in] vMultiMacChain 指向一个组播地址链,该链上的组播地址应该都被设置进入该网卡.该链的结构是 *							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 AT91RM9200EMAC_AddMultiAddr(T_VOID *vpEtherDevData,  T_CHAR *bMacAddr, T_VOID *vMultiMacChain){	return TRUE;}/** * @brief *	  删除该网卡的一个组播地址 * * @param[in] vpHalDevData 设备数据块指针,该结构的类型由HAL定义 * * @param[in] bMacAddr 指向一个6字节的存储空间,内容为需要删除的组播MAC地址 * * @param[in] vMultiMacChain 指向一个组播地址链,该链上的组播地址应该都被设置进入该网卡.该链的结构是 *							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 AT91RM9200EMAC_DelMultiAddr(T_VOID *vpEtherDevData, T_CHAR *bMacAddr, T_VOID * vMultiMacChain){	return TRUE;}/** * @brief *		初始化AT91RM9200EMAC接收包。 * * @param[in] 无。 * * @return 0  成功; *         -1 失败. */T_MODULE T_WORD At91rm9200EmacEntry(){	T_UWORD i;	T_BYTE *rxPacket;	rxPacket = (T_BYTE *)baRxPacket;	//初始化描述结构	for (i = 0; i < NB_ETH_RX_PACKETS; ++i)	{		tdList[i].addr = ((unsigned int) (rxPacket + (i * ETH_PACKET_SIZE))) & 0xFFFFFFFC;		tdList[i].size = 0;	}	tdList[NB_ETH_RX_PACKETS-1].addr |= 0x02;   //设置最后一位。	return 0;}/** * @brief *		初始化AT91RM9200EMAC。 * * @param[in] pEmac   以太网MAC接口。 * @param[in] pTdList 传送描述符。 * * @return 0  成功; *         -1 失败. */T_MODULE T_WORD AT91F_EMAC_Init(T_VOID *vpEtherDevData, tpAT91_EMAC pEmac,T_UWORD uwTdList){	T_HAL_AT91RM9200EMAC_DEV_DATA *tpEtherDevDataTable = (T_HAL_AT91RM9200EMAC_DEV_DATA *)vpEtherDevData;	T_WORD status;	AT91EMACCfgPIO();                                                       //给EMAC分配引脚。    ///初始化MAC地址。    pEmac->EMAC_SA1L = ((int)tpEtherDevDataTable->emacAddr[2] << 24) | ((int)tpEtherDevDataTable->emacAddr[3] << 16) | ((int)tpEtherDevDataTable->emacAddr[4] << 8) | tpEtherDevDataTable->emacAddr[5];    pEmac->EMAC_SA1H = ((int)tpEtherDevDataTable->emacAddr[0] << 8) | tpEtherDevDataTable->emacAddr[1];    ///初始化寄存器    pEmac->EMAC_RBQP = uwTdList;                                            //接收缓冲队列指针寄存器。    pEmac->EMAC_RSR  &= ~(AT91C_EMAC_OVR | AT91C_EMAC_REC | AT91C_EMAC_BNA);//接收状态寄存器 RX溢出 桢接收 缓冲器无效 都是写1清除。    pEmac->EMAC_CFG  |= (AT91C_EMAC_CAF | AT91C_EMAC_NBC | AT91C_EMAC_RMII);//配置寄存器 接收所有有效祯 无广播 使能RMII模式。    pEmac->EMAC_CFG  |= AT91C_EMAC_CLK;                                     //MCK64位分频。    pEmac->EMAC_CTL  |= (AT91C_EMAC_TE | AT91C_EMAC_RE);                    //控制寄存器 发送使能 接收使能。	status = AT91F_MDIO_StartupPhy(tpEtherDevDataTable, pEmac);             //启动 PHY。	if ( status )	{		return status;	}    return 0;}/** * @brief *		启动PHY。 * * @param[in] pEmac   以太网MAC接口。 * * @return 0  成功; *         -1 失败. */T_MODULE T_WORD AT91F_MDIO_StartupPhy(T_VOID *vpEtherDevData, tpAT91_EMAC pEmac){	T_HAL_AT91RM9200EMAC_DEV_DATA *tpEtherDevDataTable = (T_HAL_AT91RM9200EMAC_DEV_DATA *)vpEtherDevData;	T_UWORD PhyRdData = 0 ;	T_UWORD i = 0;	if(pEmac->EMAC_SR & AT91C_EMAC_LINK)	{		return 0;	}	if (0 == tpEtherDevDataTable->mobileEtherType)	{		SetFHYState(tpEtherDevDataTable, MBPS_AUTO,AUTO_NEGOTIATE);	}	else if(1 == tpEtherDevDataTable->mobileEtherType)	{		SetFHYState(tpEtherDevDataTable, MBPS10,HALF_DUPLEX);	}	else if(2 == tpEtherDevDataTable->mobileEtherType)	{		SetFHYState(tpEtherDevDataTable, MBPS10,FULL_DUPLEX);	}	else if(3 == tpEtherDevDataTable->mobileEtherType)	{		SetFHYState(tpEtherDevDataTable, MBPS100,HALF_DUPLEX);	}	else if(4 == tpEtherDevDataTable->mobileEtherType)	{		SetFHYState(tpEtherDevDataTable, MBPS100,FULL_DUPLEX);	}	///phy操作	for (i = 0;i < 500;i++)	{		;                                         //空循环,延时。	}	pAT91C_BASE_AIC->AIC_IDCR = 0x1 << AT91C_ID_IRQ0;	pAT91C_BASE_AIC->AIC_ICCR = 0x1 << AT91C_ID_IRQ0;	pAT91C_BASE_EMAC->EMAC_CTL |= AT91C_EMAC_MPE; //使能管理端口。	rAT91C_EMAC_MAN = (PHY_INT_REG | PHYHWADDR0  |AT91C_EMAC_R | AT91C_EMAC_HIGH | CODE) & ~AT91C_EMAC_LOW;	for (i = 0;i < 1000;i++)	{		;                                         //空循环,延时。	}	PhyRdData = (rAT91C_EMAC_MAN) & AT91C_EMAC_DATA ;	pAT91C_BASE_EMAC->EMAC_CTL &= ~AT91C_EMAC_MPE;	pAT91C_BASE_AIC->AIC_IECR = 0x1 << AT91C_ID_IRQ0;	rAIC_ICCR |= (1 << AT91C_ID_IRQ0);	rAIC_EOICR = 1;	MiiStationWrite(PHY_INT_REG, PHYHWADDR0,PHY_LINKUP_EN);	return 0;}/** * @brief *		设置FHY。 * * @param[in] Speed 网络传输速度(10M ,100M)。 * @param[in] Mode  网络传输方式 。 * @return    无。 * */T_MODULE T_VOID SetFHYState(T_VOID *vpEtherDevData, T_WORD wSpeed,T_WORD wMode){	T_HAL_AT91RM9200EMAC_DEV_DATA *tpEtherDevDataTable = (T_HAL_AT91RM9200EMAC_DEV_DATA *)vpEtherDevData;	T_UWORD FHYState = 0;	FHYState = 0;	FHYState = MiiStationRead(PHY_CNTL_REG,PHYHWADDR0);                 //读取物理维护寄存器的值。	if (AUTO_NEGOTIATE == wMode)                                        //设置为自动协商。	{		MiiStationWrite(PHY_CNTL_REG, PHYHWADDR0, ENABLE_AN|RESTART_AN);		tpEtherDevDataTable->mobileEtherType = 0;	}	else                                                                //根据配置设置FHY。	{		FHYState = FHYState&~ENABLE_AN;		MiiStationWrite(PHY_CNTL_REG,PHYHWADDR0,FHYState);	}	if (MBPS10 == wSpeed)                                               //10M。	{		if (wMode == HALF_DUPLEX)                                       //半双工。		{			FHYState = FHYState&~PHY_FULLDUPLEX;                        //8			FHYState = FHYState&~DR_100MB;                              //13			MiiStationWrite(PHY_CNTL_REG,PHYHWADDR0,FHYState);			tpEtherDevDataTable->mobileEtherType = 1;		}		else if (FULL_DUPLEX == wMode)                                  //全双工。		{			FHYState = FHYState&~DR_100MB;			FHYState = FHYState|PHY_FULLDUPLEX;			MiiStationWrite(PHY_CNTL_REG,PHYHWADDR0,FHYState);			tpEtherDevDataTable->mobileEtherType = 2;		}	}	else if (MBPS100 == wSpeed)                                         //100M。	{		if (HALF_DUPLEX == wMode)                                       //半双工。		{			FHYState = FHYState&~PHY_FULLDUPLEX;			FHYState = FHYState|DR_100MB;			MiiStationWrite(PHY_CNTL_REG,PHYHWADDR0,FHYState);			tpEtherDevDataTable->mobileEtherType = 3;		}		else if (FULL_DUPLEX == wMode)                                  //全双工。		{			FHYState = FHYState|PHY_FULLDUPLEX;			FHYState = FHYState|DR_100MB;			MiiStationWrite(PHY_CNTL_REG,PHYHWADDR0,FHYState);			tpEtherDevDataTable->mobileEtherType = 4;		}	}	if (0 == tpEtherDevDataTable->mobileEtherType)	{		FHYState = MiiStationRead(PHY_STATUS_REG,PHYHWADDR0);		if (FHYState & LINK_ON)		{			FHYState = MiiStationRead(PHY_TXCNTL_REG,PHYHWADDR0);			while ((FHYState|PHY_STATE_AN_NOT_COMPLETE) == PHY_STATE_AN_NOT_COMPLETE)			{				FHYState = MiiStationRead(PHY_TXCNTL_REG,PHYHWADDR0);			}			if (FHYState & PHY_STATE_100)			{				pAT91C_BASE_EMAC->EMAC_CFG |= AT91C_EMAC_SPD;			}			else if (FHYState & PHY_STATE_10)			{				pAT91C_BASE_EMAC->EMAC_CFG &= ~AT91C_EMAC_SPD;			}			if (FHYState & PHY_STATE_FULL)			{				pAT91C_BASE_EMAC->EMAC_CFG |= AT91C_EMAC_FD;			}			else			{				pAT91C_BASE_EMAC->EMAC_CFG &= ~AT91C_EMAC_FD;			}		}	}	else if (1 == tpEtherDevDataTable->mobileEtherType)	{		pAT91C_BASE_EMAC->EMAC_CFG  &=  ~(AT91C_EMAC_SPD|AT91C_EMAC_FD);                             //十兆半双工。	}	else if(2 == tpEtherDevDataTable->mobileEtherType)	{		pAT91C_BASE_EMAC->EMAC_CFG = (pAT91C_BASE_EMAC->EMAC_CFG | AT91C_EMAC_FD ) & ~AT91C_EMAC_SPD;//十兆全双工。	}	else if(3 == tpEtherDevDataTable->mobileEtherType)	{		pAT91C_BASE_EMAC->EMAC_CFG = (pAT91C_BASE_EMAC->EMAC_CFG | AT91C_EMAC_SPD ) & ~AT91C_EMAC_FD;//百兆半双工。	}	else if(4 == tpEtherDevDataTable->mobileEtherType)	{		pAT91C_BASE_EMAC->EMAC_CFG |= (AT91C_EMAC_SPD| AT91C_EMAC_FD);                               //百兆全双工。	}}/** * @brief *		MII Interface Station Management Register Reads。 * * @param[in] PhyInAddr  PHY中断寄存器地址。 * @param[in] PhyAddr    PHY地址。 * @return    PhyRdData  成功。 * */T_MODULE T_UWORD MiiStationRead(T_UWORD uwPhyInAddr,T_UWORD uwPhyAddr){	T_UWORD	phyRdData;	pAT91C_BASE_EMAC->EMAC_CTL |= AT91C_EMAC_MPE;//管理端口使能。	//10为读(01为写) 必须写入1以保证PHY管理祯有效 IEEE标准必须写入10读与写一样  必须写入0以保证PHY管理祯有效。	rAT91C_EMAC_MAN = (uwPhyInAddr | uwPhyAddr  |AT91C_EMAC_R | AT91C_EMAC_HIGH | CODE) & ~AT91C_EMAC_LOW;    while (!(rEMAC_ISR &AT91C_EMAC_DONE))    {    	;                                         //空循环。    }	pAT91C_BASE_EMAC->EMAC_CTL &= ~AT91C_EMAC_MPE;//为0时强制MDIO为高阻态。	phyRdData = (rAT91C_EMAC_MAN) & AT91C_EMAC_DATA;	return phyRdData ;}/** * @brief *		MII Interface Station Management Register write。 * * @param[in] PhyInAddr  PHY中断寄存器地址。 * @param[in] PhyAddr    PHY地址。 * @param[in] PhyWrData  写入数据 * @return    无。 * */T_MODULE T_VOID MiiStationWrite(T_UWORD uwPhyInAddr,T_UWORD uwPhyAddr, T_UWORD uwPhyWrData){	 //必须写入1以保证PHY管理祯有效  IEEE标准必须写入10读与写一样 必须写入0以保证PHY管理祯有效。	T_UWORD tmp = (uwPhyWrData | uwPhyInAddr | uwPhyAddr | AT91C_EMAC_HIGH | CODE |AT91C_EMAC_W) & ~AT91C_EMAC_LOW ;	pAT91C_BASE_EMAC->EMAC_CTL |= AT91C_EMAC_MPE; //管理端口使能。	rAT91C_EMAC_MAN = tmp;                        //写物理维护寄存器。    while(!(rEMAC_ISR &AT91C_EMAC_DONE))    {    	;                                         //空循环。    }	pAT91C_BASE_EMAC->EMAC_CTL &= ~AT91C_EMAC_MPE;//为0时强制MDIO为高阻态。}/** * @brief *		通过读取芯片的vendor,判断AT91RM9200EMAC是否存在。 * * @param[in] tpEtherDevDataTable	设备数据块指针,该结构的类型由HAL定义。 * @param[in] wIndex				该设备在系统中相同设备的索引。 * * @return * 		FALSE 	失败 *		TRUE	成功 */T_MODULE T_BOOL Probe(T_HAL_AT91RM9200EMAC_DEV_DATA *tpEtherDevDataTable){	T_WORD addr =(T_WORD)&baAT91EmacTdlistBase;//指向数组空间。	if (0 == (addr & 0x0c))                    //偏移位 对齐(4位)。	{		tdList = (tpAT91RM9200EMAC_TdDescriptor)addr;	}	else	{		tdList = (tpAT91RM9200EMAC_TdDescriptor)((addr&0xfffffffc) + 4);	}	return TRUE;}/** * @brief    Mil延时 * * @param[in] MilSeconds 延时时间 * @return    无。 */T_MODULE T_VOID DelayMilSecs(T_WORD wMilSeconds){   T_WORD ii;   for (ii=0;ii<wMilSeconds;ii++)   {   	;   }}

⌨️ 快捷键说明

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