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

📄 halat91rm9200emac.c

📁 包含8139
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * 修改记录: *	20060517	实现at91rm9200EMAC的HAL,该HAL目前支持网络组件的DLL。 *	20060706	修改at91rm9200EMAC在M4下实现,将mac地址和通讯方式提出让用户配置。 *//** * @file	halat91rm9200EMAC.c * @brief *	<li>功能:实现at91rm9200EMAC的HAL,该HAL目前支持网络组件的DLL</li> *	@date	20060517 *//****************************** 引用部分 *********************************/#include <board.h>              //引用at91rm9200目标板定义。#include <delta.h>              //标准库函数。#include <string.h>             //标准库函数。#include "halAt91rm9200EMAC.h"  //引用at91rm9200EMAC定义。/****************************** 声明部分 *********************************/T_MODULE T_WORD At91rm9200EmacEntry();T_MODULE T_WORD AT91F_EMAC_Init(T_VOID *vpEtherDevData, tpAT91_EMAC tpEmac,T_UWORD pTdList);T_MODULE T_WORD AT91F_MDIO_StartupPhy(T_VOID *vpEtherDevData, tpAT91_EMAC tpEmac);T_MODULE T_VOID SetFHYState(T_VOID *vpEtherDevData, T_WORD Speed,T_WORD Mode);T_MODULE T_UWORD MiiStationRead(T_UWORD PhyInAddr,T_UWORD PhyAddr);T_MODULE T_VOID MiiStationWrite(T_UWORD PhyInAddr,T_UWORD PhyAddr, T_UWORD PhyWrData);T_MODULE T_BOOL Probe(T_HAL_AT91RM9200EMAC_DEV_DATA *tpEtherDevDataTable);T_MODULE T_VOID DelayMilSecs(T_WORD MilSeconds);/****************************** 定义部分 *********************************/#define NB_ETH_RX_PACKETS		8			                  //以太网包缓冲器数量。#define ETH_PACKET_SIZE 		1536                          //一个以太网包大小。typedef struct T_AT91RM9200EMAC_TdDescriptor{	T_UWORD addr;	T_UWORD size;}tAT91RM9200EMAC_TdDescriptor, *tpAT91RM9200EMAC_TdDescriptor;//传输描述结构。T_MODULE T_BYTE baRxPacket[NB_ETH_RX_PACKETS*ETH_PACKET_SIZE];T_MODULE T_BYTE baAT91EmacTdlistBase[68];tpAT91RM9200EMAC_TdDescriptor tdList;/****************************** 实现部分 *********************************//** * @brief *	  确认设备的存在,对于需要动态获得系统参数的设备 *    需要在此处把系统资源占用信息更新。 * * @param[in] vpEtherDevData 设备数据块指针,该结构的类型由HAL定义。 * * @return	TRUE	成功。 *			FALSE	失败。 */T_BOOL AT91RM9200EMAC_Find(T_VOID *vpEtherDevData){	T_HAL_AT91RM9200EMAC_DEV_DATA *tpEtherDevDataTable = (T_HAL_AT91RM9200EMAC_DEV_DATA *)vpEtherDevData;	T_WORD retval;    //确认AT91RM9200EMAC的存在,更新配置表项。    retval = Probe(tpEtherDevDataTable);    if (retval != TRUE)    {		return FALSE;	}	return TRUE;}/** * @brief *     该接口用来获取HAL管理该设备需要的资源(主要指内存) *	   HAL不应该再再别的地方进行资源的获取工作,该接口获得的资源将都被传给HAL中其他接口使用。 * * @param[in] vpEtherDevData 设备数据块指针,该结构的类型由HAL定义。 * * @return	TRUE	成功。 *			FALSE	失败。 */T_BOOL AT91RM9200EMAC_GetResource(T_VOID *vpEtherDevData){	return TRUE;}/** * @brief *		关闭设备的中断。工作就是屏蔽在ChipIntEnable中使能的中断类型。 * * @param[in] vpEtherDevData 设备数据块指针,该结构的类型由HAL定义。 * * @return TRUE	成功(始终返回该值)。 */T_BOOL AT91RM9200EMAC_ChipIntDisable(T_VOID *vpEtherDevData){	pAT91C_BASE_AIC->AIC_IDCR = 0x1 << AT91C_ID_EMAC ;//关中断	pAT91C_BASE_AIC->AIC_ICCR = 0x1 << AT91C_ID_EMAC ;//清中断	return TRUE;}/** * @brief *	启动设备的运行,对设备进行基本初始化工作.主要工作包括: *	1.获取HAL为了驱动该设备所需要的系统资源,一般指内存空间; *	2.设置设备寄存器,让设备工作在正常状态下; *	3.注意该接口不要关心设备的中断开关状态。 * * @param[in] pEtherDevData 设备数据块指针,该结构的类型由HAL定义。 * * @return * 		FALSE 	失败 *		TRUE	成功 */T_BOOL AT91RM9200EMAC_Start(T_VOID *vpEtherDevData){	T_HAL_AT91RM9200EMAC_DEV_DATA *tpEtherDevDataTable = (T_HAL_AT91RM9200EMAC_DEV_DATA *)vpEtherDevData;	T_WORD status;    rIOPBENABLE |= RESET_PHY;                                                                         //PIOB 使能。    rIOPBOUTPUTEN |= RESET_PHY;                                                                       //PIOB 输出使能。    rIOPBModVal |= RESET_PHY;                                                                         //PIOB 写状态寄存器使能。    DelayMilSecs(800);    rIOPBDataVal &= (~RESET_PHY);    DelayMilSecs(1000);    rIOPBDataVal |= RESET_PHY;    DelayMilSecs(1000);                                                                               //重启 Mobile 和 PHY。	status = At91rm9200EmacEntry();                                                                   //初始化EMAC接收包。	if (status)	{		printk("Error EMAC init: 0x%x", status);		return FALSE;	}    rAT91C_EMAC_IDR = (T_UWORD) -1;                                                                   //EMAC中断禁用寄存器初始化	AT91EMACCfgPMC();                                                                                 //将电源控制器(PMC)提供给EMAC的外设时钟使能。	AT91PMCEnablePeriphClock(pAT91C_BASE_PMC, ((T_UWORD) 1 << AT91C_ID_PIOB));                        //使能PIOB时钟(PID3)。	AT91PIODisable(pAT91C_BASE_PIOB,AT91C_PB29_IRQ0);                                                 //关闭PB29的PIO控制使能外设控制IRQ0    rAT91C_EMAC_IER = AT91C_EMAC_RCOM|AT91C_EMAC_TCOM|AT91C_EMAC_ROVR|AT91C_EMAC_RBNA|AT91C_EMAC_TOVR|	                  AT91C_EMAC_TUND|AT91C_EMAC_RTRY|AT91C_EMAC_LINK |AT91C_EMAC_DONE;               //EMAC中断使能寄存器初始化	AT91F_EMAC_Init(tpEtherDevDataTable, pAT91C_BASE_EMAC, (T_UWORD) tdList);                         //初始化EMAC。	return TRUE;}/** * @brief *	使能设备中断。设备也许有多种类型的中断,网络组件只关心发送和接收中断而已 *	其他中断类型的处理将由HAL本身负责解释并响应。所以此处使能的中断类型应该包括 *	发送中断和接收中断,其他类型中断由HAL自行决定。 * * @param[in] vpEtherDevData 设备数据块指针,该结构的类型由HAL定义。 * * @return	TRUE	成功。 *			FALSE	失败。 */T_BOOL AT91RM9200EMAC_ChipIntEnable(T_VOID *vpEtherDevData){	pAT91C_BASE_AIC->AIC_IECR = 0x1 << AT91C_ID_EMAC;           //使能中断。	return TRUE;}/** * @brief *	  发送数据包,把从DLL传来的数据包发送出去。 * * @param[in] vpEtherDevData	设备数据块指针,该结构的类型由HAL定义。 * @param[in] bpKtBuf		数据包所在的缓存指针。 * @param[in] wKtLen		数据包大小。 * * @return * 		FALSE 	失败 *		TRUE	成功 */T_BOOL AT91RM9200EMAC_SendPkt(T_VOID *vpEtherDevData, T_BYTE *bpKtBuf, T_WORD wKtLen){	while(!pAT91C_BASE_EMAC->EMAC_TSR & AT91C_EMAC_BNQ)	{		;                                         //空循环(以太网发送缓冲器无队列一直循环直到有帧发送就绪)。	}	if(wKtLen<60)	{		wKtLen = 60;                              //以太网最小发包长度60,不够要补齐。	}	pAT91C_BASE_EMAC->EMAC_TAR = (T_UWORD)bpKtBuf;//帧首地址写入发送地址寄存器。	pAT91C_BASE_EMAC->EMAC_TCR = wKtLen;          //写入将要发送的字节数目 对写入的非0值初始化发送。	return TRUE;}/** * @brief *		获取中断类型。当设备发生中断时,该接口将被调用。 * * @param[in]	vpEtherDevData	设备数据块指针,该结构的类型由HAL定义。 * @param[in]	uwVector		产生中断的中断向量。 * @param[out]	*wpIntInfo		设备的中断信息,当返回的中断类型中包括"其他中断类型" *								时,该参数将被传给HandleOtherIntType的HAL接口。 * * @return  当发生多种中断类型时,把如下的返回值采用‘位或’运算后再返回。 * 		DEV_NO_INTERRUPT		该设备没有发生中断。 *		DEV_INT_HAD_HANDLED		设备发生了中断,但已经被处理了。 *      DEV_RECEIVE_INTERRUPT	设备发生了接收中断。 *		DEV_SENDOVER_INTERRUPT	设备发生了发生中断。 *		DEV_OHER_INTTYPE		设备发生了其他的中断类型。 */T_UWORD AT91RM9200EMAC_GetIntType(T_VOID *vpEtherDevData, T_UWORD uwVector, T_WORD *wpIntInfo){	T_UWORD ret = 0;	T_UWORD status = 0;	///判断是EMAC中断还是PHY中断	if (AT91C_ID_EMAC == uwVector) //EMAC中断。	{		status = rEMAC_ISR;        //获取中断寄存器状态。		//无中断		if ((status & (AT91C_EMAC_DONE|AT91C_EMAC_RCOM|AT91C_EMAC_TCOM|AT91C_EMAC_RBNA|AT91C_EMAC_TOVR|		      AT91C_EMAC_TUND|AT91C_EMAC_RTRY|AT91C_EMAC_TBRE|AT91C_EMAC_TIDLE|		      AT91C_EMAC_LINK|AT91C_EMAC_ROVR|AT91C_EMAC_HRESP)) == 0)  		{			return DEV_NO_INTERRUPT;		}		//接收完成		if (status & AT91C_EMAC_RCOM)		{			ret |= DEV_RECEIVE_INTERRUPT;		}		//发送完成		if ( status & AT91C_EMAC_TCOM )		{			if (pAT91C_BASE_EMAC->EMAC_TSR&AT91C_EMAC_COMP)           //发送完成。			{				pAT91C_BASE_EMAC->EMAC_TSR|=AT91C_EMAC_COMP;          //写1清除。			}			ret |= DEV_SENDOVER_INTERRUPT;		}		//优先处理故障中断		if (status & (AT91C_EMAC_ROVR|AT91C_EMAC_RBNA))               //RX溢出状态或接收缓冲器无效。		{			T_WORD i=0;			for (i=0;i<NB_ETH_RX_PACKETS;i++)			{				if (!(tdList[i].addr & 0x1))				{					pAT91C_BASE_EMAC->EMAC_RBQP = (T_UWORD)(tdList+i);//写入接收队列起始地址。					break;				}			}			if (i>=NB_ETH_RX_PACKETS)			{				pAT91C_BASE_EMAC->EMAC_RBQP = (T_WORD)tdList;         //写入接收队列起始地址。			}			ret |= DEV_INT_HAD_HANDLED;		}		*wpIntInfo = status;	    rAIC_ICCR |= (1<<24);                                         //中断清除。	    rAIC_EOICR = 1 ;                                              //写值标置中断处理结束。	}//end of if (AT91C_ID_EMAC == uwVector)	else                         //PHY中断。	{		ret = DEV_OHER_INTTYPE;	}	return ret;}/** * @brief *		获取设备当前接收到的数据包长度。当设备发生接收中断时,该接口将被调用。 * * @param[in]	vpEtherDevData 设备数据块指针,该结构的类型由HAL定义。 * @param[out]	wKtLen数据包的长度。 * * @return * 		FALSE 	失败。 *		TRUE	成功。 */T_BOOL AT91RM9200EMAC_GetPktLen(T_VOID *vpEtherDevData, T_WORD *wKtLen){//	T_HAL_AT91RM9200EMAC_DEV_DATA *tpEtherDevDataTable = (T_HAL_AT91RM9200EMAC_DEV_DATA *)vpEtherDevData;	if ((tdList->size) <= *wKtLen)	{		*wKtLen = tdList->size;		return TRUE;	}	else	{		return FALSE;	}}/** * @brief *		获取设备当前接收到的数据包的数据。当设备发生接收中断, *   且GetPktLen接口返回的数据包长度大于0时该接口将被调用。 * * @param[in] vpEtherDevData	设备数据块指针,该结构的类型由HAL定义。 * @param[in] wKtLen			数据包的长度 ,该参数即GetPktLen的返回值。 * * @return	TRUE	成功。 *			FALSE	失败。 */T_BOOL AT91RM9200EMAC_GetPktData(T_VOID *vpEtherDevData, T_BYTE * bpKtBuf, T_WORD wKtLen){//	T_HAL_AT91RM9200EMAC_DEV_DATA *tpEtherDevDataTable = (T_HAL_AT91RM9200EMAC_DEV_DATA *)vpEtherDevData;	T_WORD process = 0;	T_BYTE *taddr = NULL;	if(tdList->addr & 0x1)	{		taddr = (T_BYTE *)(tdList->addr & 0xFFFFFFFC);		memcpy(bpKtBuf, taddr, tdList->size);		tdList->addr &= ~0x01;		process = 1;	}	if (0 == process)	{		return FALSE;	}	if (rAT91C_EMAC_RSR & AT91C_EMAC_REC)   //已收到一个或多个帧,并置于存储器中。该位写 1 清除。	{		(rAT91C_EMAC_RSR) |= AT91C_EMAC_REC;	}    return TRUE;}/** * @brief *	处理其他的中断类型。中断类型参数intInfo即在GetIntType中返回的中断。 *	状态信息。该信息由HAL自己负责定义和解释。 * * @param[in] vpEtherDevData 设备数据块指针,该结构的类型由HAL定义。 * @param[in] wpIntInfo 中断状态信息。 * * @return	TRUE	成功。 *			FALSE	失败。 */T_BOOL AT91RM9200EMAC_HandleOtherIsrType(T_VOID *vpEtherDevData, T_WORD wIntInfo){//	T_HAL_AT91RM9200EMAC_DEV_DATA *tpEtherDevDataTable = (T_HAL_AT91RM9200EMAC_DEV_DATA *)vpEtherDevData;	if (0 == wIntInfo)	{		T_UWORD PhyRdData = 0;	    T_UWORD i;	    T_UWORD mask = 0x1 << AT91C_ID_IRQ0;		pAT91C_BASE_AIC->AIC_IDCR = mask;   //在AIC中禁止该中断。		pAT91C_BASE_AIC->AIC_ICCR = mask;   //在AIC中清除该中断。	    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 = mask;   //在AIC中使能该中断。	    rAIC_ICCR |= (1<<AT91C_ID_IRQ0);    //AIC中断清除寄存器置位清除中断。	    rAIC_EOICR = 1;                     //AIC中断结束寄存器置位结束中断。	}	return TRUE;}/** * @brief *	停止(或暂停)设备的运行,就是让该IO设备不能(正常)输入输出。 *	该函数一般就是要设置DISABLE位,或者把该设备设置为内循环模式 *	等。 * * @param[in] vpEtherDevData 设备数据块指针,该结构的类型由HAL定义。 * * @return TRUE	成功	(始终返回该值)。 */T_BOOL AT91RM9200EMAC_Stop(T_VOID *vpEtherDevData){	T_UWORD mask = 0x1 << AT91C_ID_SYS;	pAT91C_BASE_AIC->AIC_IDCR = mask;   //在AIC中禁止该中断。	pAT91C_BASE_AIC->AIC_ICCR = mask;   //在AIC中清除该中断。	return TRUE;}/** * @brief *	  释放HAL占用的资源(主要指在GetResource中获取到的资源)。 * * @param[in] vpEtherDevData 设备数据块指针,该结构的类型由HAL定义。 * * @return TRUE	成功。 *			FALSE	失败。 */ T_BOOL AT91RM9200EMAC_ReleaseResource(T_VOID *vpEtherDevData){	return TRUE;}/** * @brief *		获取该网络设备的网络连接情况。 * * @param[in]	vpEtherDevData	设备数据块指针,该结构的类型由HAL定义。 * @param[out]	wplineStatus	连接状态。 				DNET_IFOPERSTATUS_UP 或者 DNET_IFOPERSTATUS_DOWN。 * * @return	FALSE 	失败。 *			TRUE	成功。 */T_BOOL AT91RM9200EMAC_LineCheck(T_VOID *vpEtherDevData, T_WORD *wplineStatus){	return FALSE;}/** * @brief *		获取设备的MAC地址。

⌨️ 快捷键说明

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