原创 这时才知道W3100A的SHADOW_REG是怎么用的。

2008-4-30 09:33 2586 13 13 分类: 通信

例程中的一个函数,由此我明白了它的shadow register是怎么用的。说实在的,它这款芯片真的不怎么地,datasheet中的bug多不说,想shadow register这中用法还是头一次见到,这种用法感觉很不可理喻。

怪不得他们公司都不宣传W3100A了,也不更新它的datasheet了。可能没人用这款老芯片了。新款芯片取代了老的。

u_int select(SOCKET s, u_char func)
{
    u_int val;
    un_l2cval rd_ptr, wr_ptr, ack_ptr;
    u_char k;

    EX0 = 0;
    switch (func) {
    case SEL_CONTROL :                   // socket status information
        val = IndirectReadByte(SOCK_STATUS(s));
        break;

    case SEL_SEND :                // Calculate send free buffer size
        k = IndirectReadByte(SHADOW_TXWR_PTR(s)); // Shadow Register needs to be read before reading buffer register
        wait_1us(2);
        IndirectReadBuf(TX_WR_PTR(s),(u_char*)&wr_ptr,4);

        if( (IndirectReadByte(OPT_PROTOCOL(s)) & 0x07) != SOCK_STREAM)
        {
            k = IndirectReadByte(SHADOW_TXRD_PTR(s));  // Shadow Register needs to be read before reading buffer register
            wait_1us(2);
            IndirectReadBuf(TX_RD_PTR(s),(u_char*)&ack_ptr,4);
        }
        else
        {
            k = IndirectReadByte(SHADOW_TXACK_PTR(s));  // Shadow Register needs to be read before reading buffer register
            wait_1us(2);
            IndirectReadBuf(TX_ACK_PTR(s),(u_char*)&ack_ptr,4);
        }

        if (wr_ptr.lVal >= ack_ptr.lVal) val = SSIZE - (wr_ptr.lVal - ack_ptr.lVal);
        else val = SSIZE - (0 - ack_ptr.lVal + wr_ptr.lVal);
        break;
    case SEL_RECV :                  // Calculate received data size    
        k = IndirectReadByte(SHADOW_RXWR_PTR(s));    // Shadow Register needs to be read before reading buffer register
        wait_1us(2);
        IndirectReadBuf(RX_WR_PTR(s),(u_char*)&wr_ptr,4);

        k = IndirectReadByte(SHADOW_RXRD_PTR(s));    // Shadow Register needs to be read before reading buffer register
        wait_1us(2);
        IndirectReadBuf(RX_RD_PTR(s),(u_char*)&rd_ptr,4);

        if (wr_ptr.lVal == rd_ptr.lVal){ val = 0;}
        else if (wr_ptr.lVal > rd_ptr.lVal) val = wr_ptr.lVal - rd_ptr.lVal;
        else val = 0 - rd_ptr.lVal + wr_ptr.lVal;
        
#ifdef DEBUG
   
    PutString("wr_ptr.lVal = ");PutLTOA(wr_ptr.lVal);PutString(" :
rd_ptr.lVal = ");PutLTOA(rd_ptr.lVal);PutString(" : size =
");PutITOA(val);PutStringLn("");
#endif       
        break;
    default :
        val = -1;
        break;
    }
    EX0 = 1;
    return    ( val );
}
 

这里的计算buffer大小还不太明白。



文章评论0条评论)

登录后参与讨论
我要评论
0
13
关闭 站长推荐上一条 /2 下一条