• u-boot中网口处理--软件部分


    u-boot中DM9000驱动分析

    1. CSRs和PHY reg读写。

     1 static u16
     2 phy_read(int reg)
     3 {
     4     u16 val;
     5 
     6     /* Fill the phyxcer register into REG_0C */
     7     DM9000_iow(DM9000_EPAR, DM9000_PHY | reg);
     8     DM9000_iow(DM9000_EPCR, 0xc);    /* Issue phyxcer read command */
     9     udelay(100);        /* Wait read complete */
    10     DM9000_iow(DM9000_EPCR, 0x0);    /* Clear phyxcer read command */
    11     val = (DM9000_ior(DM9000_EPDRH) << 8) | DM9000_ior(DM9000_EPDRL);
    12 
    13     /* The read data keeps on REG_0D & REG_0E */
    14     DM9000_DBG("phy_read(%d): %d
    ", reg, val);
    15     return val;
    16 }
    phy_read
     1 static void
     2 phy_write(int reg, u16 value)
     3 {
     4 
     5     /* Fill the phyxcer register into REG_0C */
     6     DM9000_iow(DM9000_EPAR, DM9000_PHY | reg);
     7 
     8     /* Fill the written data into REG_0D & REG_0E */
     9     DM9000_iow(DM9000_EPDRL, (value & 0xff));
    10     DM9000_iow(DM9000_EPDRH, ((value >> 8) & 0xff));
    11     DM9000_iow(DM9000_EPCR, 0xa);    /* Issue phyxcer write command */
    12     udelay(500);        /* Wait write complete */
    13     DM9000_iow(DM9000_EPCR, 0x0);    /* Clear phyxcer write command */
    14     DM9000_DBG("phy_write(reg:%d, value:%d)
    ", reg, value);
    15 }
    phy_write
     1 static u8
     2 DM9000_ior(int reg)
     3 {
     4     u32     val;
     5     
     6     VALIDATE_ADDR_PORT(reg)
     7 
     8     val = *(u16*)DM9000_DATA;
     9 
    10     val &= 0xffff;
    11     
    12     return (u8)val;
    13 }
    DM9000_ior
    1 static void
    2 DM9000_iow(int reg, u8 value)
    3 {
    4     VALIDATE_ADDR_PORT(reg)
    5 
    6     *(u16*)(DM9000_DATA) =     (u16)value;
    7 }
    DM9000_iow
    1 #define    VALIDATE_ADDR_PORT(p) 
    2     if( m_uLastAddressPort != (p) ) 
    3         { 
    4             *(u16*)(DM9000_IO)  =(u16)(p);
    5             m_uLastAddressPort = (p);
    6         }
    VALIDATE_ADDR_PORT

    2. 网口收发

     1 int
     2 eth_rx(void)
     3 {
     4     u8 rxbyte, *rdptr = (u8 *) NetRxPackets[0];
     5     int     errors=0;
     6     u16        RxLen;
     7 
     8     u32     desc;
     9     PDM9000_RX_DESCRIPTOR    pdesc;
    10 
    11     DM9000_ior(DM9000_RSR);
    12     DM9000_ior(DM9000_ROCR);    
    13 
    14     for(pdesc=(PDM9000_RX_DESCRIPTOR)&desc;;)
    15     {
    16         // probe first byte
    17         desc = DeviceReadDataWithoutIncrement();    
    18         DM9000_DBG("1:	desc is 0x%x
    ",desc);
    19 
    20         // check if packet available, 01h means available, 00h means no data
    21         if(pdesc->bState != 0x01)
    22         {
    23             RxLen = 0;
    24             break;
    25         }
    26 
    27         // get the data descriptor again
    28         desc = DeviceReadData();
    29         DM9000_DBG("2:	desc is 0x%x
    ",desc);        
    30 
    31         DM9000_DBG("len is 0x%x
    ",pdesc->nLength);                
    32 
    33         DeviceReadString(rdptr,pdesc->nLength);
    34 
    35         // check status, as specified in DM9000_RXSR,
    36         // the following bits are error
    37         // <3> PLE
    38         // <2> AE
    39         // <1> CE
    40         // <0> FOE
    41         if(pdesc->bStatus & MAKE_MASK4(3,2,1,0))
    42         {
    43             errors++;
    44             continue;
    45         } // of error happens
    46 
    47         RxLen =pdesc->nLength;
    48         
    49         break;
    50     } // of forever read loop
    51 
    52     /* Pass to upper layer */
    53     DM9000_DBG("passing packet to upper layer
    ");
    54     NetReceive(NetRxPackets[0], RxLen);
    55     return RxLen;
    56 }
    eth_rx
     1 int
     2 eth_send(volatile void *packet, int length)
     3 {
     4     unsigned int loop;
     5 #if 0
     6     for(loop = 0; loop<length;loop++)
     7     {
     8         printf("%02x ",*((char *)packet+loop));    
     9     }
    10     printf("
    ");    
    11 #endif
    12     DeviceWriteString((u8*)packet,length);
    13 
    14     DM9000_iow(DM9000_TXPLH,HIGH_BYTE(length));
    15     DM9000_iow(DM9000_TXPLL,LOW_BYTE(length));
    16         
    17     // TXCR<0>, issue TX request
    18     DM9000_iow(DM9000_TCR, MAKE_MASK(0));
    19 
    20         
    21     DM9000_DBG("transmit done
    
    ");
    22     return 0;
    23 }
    eth_send

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

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

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

  • 相关阅读:
    GrapeCity Documents (服务端文档API组件) V3.0 正式发布
    js 手机号码正则表达式
    springMvc 注解@JsonFormat 日期格式化
    solr java代码
    solr全文检索
    在阿里云服务器CentOS7安装mysql提示“No package mysql-server available上安装mysql遇到的问题
    MockBean 单元测试
    redis缓存
    c3p0连接池
    springboot Transactional事务的使用
  • 原文地址:https://www.cnblogs.com/embedded-linux/p/4830764.html
Copyright © 2020-2023  润新知