u-boot中DM9000驱动分析

1. CSRs和PHY reg读写。

 static u16
phy_read(int reg)
{
u16 val; /* Fill the phyxcer register into REG_0C */
DM9000_iow(DM9000_EPAR, DM9000_PHY | reg);
DM9000_iow(DM9000_EPCR, 0xc); /* Issue phyxcer read command */
udelay(); /* Wait read complete */
DM9000_iow(DM9000_EPCR, 0x0); /* Clear phyxcer read command */
val = (DM9000_ior(DM9000_EPDRH) << ) | DM9000_ior(DM9000_EPDRL); /* The read data keeps on REG_0D & REG_0E */
DM9000_DBG("phy_read(%d): %d\n", reg, val);
return val;
}

phy_read

 static void
phy_write(int reg, u16 value)
{ /* Fill the phyxcer register into REG_0C */
DM9000_iow(DM9000_EPAR, DM9000_PHY | reg); /* Fill the written data into REG_0D & REG_0E */
DM9000_iow(DM9000_EPDRL, (value & 0xff));
DM9000_iow(DM9000_EPDRH, ((value >> ) & 0xff));
DM9000_iow(DM9000_EPCR, 0xa); /* Issue phyxcer write command */
udelay(); /* Wait write complete */
DM9000_iow(DM9000_EPCR, 0x0); /* Clear phyxcer write command */
DM9000_DBG("phy_write(reg:%d, value:%d)\n", reg, value);
}

phy_write

 static u8
DM9000_ior(int reg)
{
u32 val; VALIDATE_ADDR_PORT(reg) val = *(u16*)DM9000_DATA; val &= 0xffff; return (u8)val;
}

DM9000_ior

 static void
DM9000_iow(int reg, u8 value)
{
VALIDATE_ADDR_PORT(reg) *(u16*)(DM9000_DATA) = (u16)value;
}

DM9000_iow

 #define    VALIDATE_ADDR_PORT(p) \
if( m_uLastAddressPort != (p) ) \
{ \
*(u16*)(DM9000_IO) =(u16)(p);\
m_uLastAddressPort = (p);\
}

VALIDATE_ADDR_PORT

2. 网口收发

 int
eth_rx(void)
{
u8 rxbyte, *rdptr = (u8 *) NetRxPackets[];
int errors=;
u16 RxLen; u32 desc;
PDM9000_RX_DESCRIPTOR pdesc; DM9000_ior(DM9000_RSR);
DM9000_ior(DM9000_ROCR); for(pdesc=(PDM9000_RX_DESCRIPTOR)&desc;;)
{
// probe first byte
desc = DeviceReadDataWithoutIncrement();
DM9000_DBG("1:\tdesc is 0x%x\n",desc); // check if packet available, 01h means available, 00h means no data
if(pdesc->bState != 0x01)
{
RxLen = ;
break;
} // get the data descriptor again
desc = DeviceReadData();
DM9000_DBG("2:\tdesc is 0x%x\n",desc); DM9000_DBG("len is 0x%x\n",pdesc->nLength); DeviceReadString(rdptr,pdesc->nLength); // check status, as specified in DM9000_RXSR,
// the following bits are error
// <3> PLE
// <2> AE
// <1> CE
// <0> FOE
if(pdesc->bStatus & MAKE_MASK4(,,,))
{
errors++;
continue;
} // of error happens RxLen =pdesc->nLength; break;
} // of forever read loop /* Pass to upper layer */
DM9000_DBG("passing packet to upper layer\n");
NetReceive(NetRxPackets[], RxLen);
return RxLen;
}

eth_rx

 int
eth_send(volatile void *packet, int length)
{
unsigned int loop;
#if 0
for(loop = ; loop<length;loop++)
{
printf("%02x ",*((char *)packet+loop));
}
printf("\n");
#endif
DeviceWriteString((u8*)packet,length); DM9000_iow(DM9000_TXPLH,HIGH_BYTE(length));
DM9000_iow(DM9000_TXPLL,LOW_BYTE(length)); // TXCR<0>, issue TX request
DM9000_iow(DM9000_TCR, MAKE_MASK()); DM9000_DBG("transmit done\n\n");
return ;
}

eth_send

数据接收时首先比对包头4个字节,第一个字节必须是0x01,第3,4字节是数据长度(减去开头的4个字节)。

接收完数据后再比对第二字节(DM9000 RSR),确认是否又错误发生。

用到的编程技巧是读取的包头4个字节直接赋值给一个u32,最低字节即为01,高两位为包长度。

最新文章

  1. AlloyTouch实战--60行代码搞定QQ看点资料卡
  2. dobbo zookeeper 认识
  3. 【rational rose】用例图
  4. Servlet上
  5. javascript组件化(转)
  6. 2进制,16进制,BCD,ascii,序列化对象相互转换
  7. Conversion to Dalvik format failed with error 1
  8. Java中String转换Double类型 Java小数点后留两位
  9. SpringMVC简版教程、部分功能
  10. MySQL备份说明
  11. Google Chrome 默认非安全端口列表
  12. 微信小程序统计分析
  13. python中的Matplot库和Gdal库绘制富士山三维地形图-参考了虾神的喜马拉雅山
  14. thinkphp框架 的 链接数据库和操作数据
  15. 我所知道的JS调试
  16. restful规范整理
  17. PAT 1025 反转链表
  18. openstack neutron 深入
  19. nautilus
  20. Koa 框架整理

热门文章

  1. springmvc异常统一处理
  2. jquery ajax例子
  3. Fork me on GitHub
  4. cxf之Caused by: java.lang.RuntimeException: Soap 1.1 endpoint already registered on address /rest
  5. HDUOJ-----1085Holding Bin-Laden Captive!
  6. 浅谈 JavaScriptCore
  7. selenium python学习笔记---添加等待时间
  8. React dva 的使用
  9. MYSQL 更改数据库data存储目录 创建用户 创建权限 设置远程访问的权限.
  10. SQL查询刚開始学习的人指南读书笔记(二)创建SQL查询