📄 haldm9000.c
字号:
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 + -