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

📄 cs8900.c

📁 含有完整TCP/IP PPP协议的嵌入式操作系统
💻 C
📖 第 1 页 / 共 2 页
字号:
    cs_flags ^= 1;}static int CSEthPutPacket(NUTDEVICE * dev, NETBUF * nb){    u_short i;    u_short sz;    u_char *p;    NICINFO *ni;    ni = (NICINFO *) dev->dev_dcb;    //    // Calculate the number of bytes to be send. Do not    // send packets larger than 1536 bytes.    //    sz = nb->nb_dl.sz + nb->nb_nw.sz + nb->nb_tp.sz + nb->nb_ap.sz;    if (sz >= 0x600) {        NutNetBufFree(nb);        return -1;    }#if 0    if (tcp_trace) {        NutPrintFormat_P(dev_debug, PSTR("[ETHTX-%u]\r\n"), sz);        NutPrintFlush(dev_debug);    }#endif    // Start transmission after entire frame is loaded into CS8900    CSWrite16(CS_TX_CMD_I, 0xC0);    // Set frame size    CSWrite16(CS_TX_LEN_I, sz);    // Wait for buffer space, but only for a while (200ms)    // If the cable is disconnected this will never become true    // If we don't get the go ahead within 200ms return 0 (Sucess)    // And let the upper layers deal with re-transmission     // If we return failure TCP sockets will close straight away which probably    // isn't the correct behaviour    i = 0;    while ((CSReadPP16(CS_BUS_STAT) & 0x0100) == 0) {        i++;        if (i > 20)            return 0;        NutSleep(10);    }    //    // Transfer ethernet physical header.    //    CSBeginFrame();    p = nb->nb_dl.vp;    for (i = 0; i < nb->nb_dl.sz; i++) {        CSWriteFrameByte(*p++);    }    p = nb->nb_nw.vp;    for (i = 0; i < nb->nb_nw.sz; i++) {        CSWriteFrameByte(*p++);    }    p = nb->nb_tp.vp;    for (i = 0; i < nb->nb_tp.sz; i++) {        CSWriteFrameByte(*p++);    }    p = nb->nb_ap.vp;    for (i = 0; i < nb->nb_ap.sz; i++) {        CSWriteFrameByte(*p++);    }    CSEndFrame();    return 0;}/*! * \brief Send Ethernet packet. * * \param dev   Identifies the device to use. * \param nb    Network buffer structure containing the packet to be sent. *              The structure must have been allocated by a previous *              call NutNetBufAlloc(). This buffer will be automatically *              released in case of an error. *  * \return 0 on success, -1 in case of any errors. Errors *         will automatically release the network buffer  *         structure. */int CSNicOutput(NUTDEVICE * dev, NETBUF * nb){    int rc = -1;    NICINFO *ni;    ni = (NICINFO *) dev->dev_dcb;#if 0    if (tcp_trace) {        NutPrintFormat_P(dev_debug, PSTR("Enter EthOutput\r\n"));        NutPrintFlush(dev_debug);    }#endif    if ((rc = CSEthPutPacket(dev, nb)) == 0)        ni->ni_tx_packets++;    return rc;}/*! \fn PPPRx(void *arg) * \brief PPP receiver thread. * *  * It runs with high priority. */THREAD(CSNICrx, arg){    NUTDEVICE *dev;    IFNET *ifn;    NICINFO *ni;    NETBUF *nb;    u_char *p;    u_char *q;    u_short i, m;    volatile u_short l;    dev = arg;    ifn = (IFNET *) dev->dev_icb;    ni = (NICINFO *) dev->dev_dcb;#if 0    if (tcp_trace) {        NutPrintFormat_P(dev_debug, PSTR("Enter ETHReceive\r\n"));        NutPrintFlush(dev_debug);    }#endif    l = 0;    NutThreadSetPriority(8);    for (;;) {        while ((CSReadPP16(CS_RX_EVENT) & 0x0100) == 0) {            NutSleep(10);        }#ifdef NUT_CS8900_OLD        // Get the RxStatus But don't let the compiler do any optomisation        asm volatile ("lds __tmp_reg__, %3" "\n\t"                      "mov %B0, __tmp_reg__" "\n\t" "lds __tmp_reg__, %2" "\n\t" "mov %A0, __tmp_reg__" "\n\t":"=r" (l)                      :"0"(l), "n"((unsigned short) (CS_DATA_P0)), "n"((unsigned short) (CS_DATA_P0 + 1))            );        // Get the Packet Length But don't let the compiler do any optomisation        asm volatile ("lds __tmp_reg__, %3" "\n\t"                      "mov %B0, __tmp_reg__" "\n\t" "lds __tmp_reg__, %2" "\n\t" "mov %A0, __tmp_reg__" "\n\t":"=r" (l)                      :"0"(l), "n"((unsigned short) (CS_DATA_P0)), "n"((unsigned short) (CS_DATA_P0 + 1))            );#else        l = *(u_char *) (CS_DATA_P0 + 1) << 8 | *(u_char *) (CS_DATA_P0);        l = *(u_char *) (CS_DATA_P0 + 1) << 8 | *(u_char *) (CS_DATA_P0);#endif        //NutPrintFormat_P(dev_debug,PSTR("RxLength = %x \r\n"), l);        //NutPrintFlush(dev_debug);        // Account for odd length packets        if (l & 1)            m = l - 1;        else            m = l;        nb = NutNetBufAlloc(0, NBAF_DATALINK, l);        if (nb) {            q = nb->nb_dl.vp;            for (i = 0; i < m; i += 2) {                p = (u_char *) CS_DATA_P0;                *q++ = *p;                p = (u_char *) CS_DATA_P0 + 1;                *q++ = *p;            }            // Odd length packets            if (m != l) {                p = (u_char *) CS_DATA_P0;                *q++ = *p;                p = (u_char *) CS_DATA_P0 + 1;                m = *p;            }            ni->ni_rx_packets++;            (*ifn->if_recv) (dev, nb);        }    }}void CSSoftwareWakeup(void){    volatile u_short *p;    p = (u_short *) CS_PP_PTR;    *p = CS_SELF_CTRL;    NutDelay(10);}void CSSoftwareReset(void){    volatile u_short *p;    p = (u_short *) CS_PP_PTR;    *p = CS_SELF_CTRL;    p = (u_short *) CS_DATA_P0;    *p = 0x0040;}/*! * \brief Initialize Ethernet Interface. * * * Applications typically do not use this function, but * call NutNetIfConfig(). * * \param dev Identifies the device to initialize. The *            structure must be properly set. */int CSNicInit(NUTDEVICE * dev){    u_short i;    u_short j;    IFNET *ifn;    NICINFO *ni;#if 0    if (tcp_trace) {        NutPrintFormat_P(dev_debug, PSTR("Enter NicInit  \r\n"));        NutPrintFlush(dev_debug);    }#endif    cs_base = dev->dev_base;    if (confnet.cd_size == 0)        NutNetLoadConfig(dev->dev_name);    ifn = dev->dev_icb;    memcpy(ifn->if_mac, confnet.cdn_mac, 6);    memset(dev->dev_dcb, 0, sizeof(NICINFO));    ni = (NICINFO *) dev->dev_dcb;    // Take CS8900 out of reset and wait for internal reset to complete#ifdef NUT_CS8900_OLD    outp(inp(PORTD) & ~RESETE, PORTD);#else    CSSoftwareWakeup();    CSSoftwareReset();#endif    NutDelay(100);    // Check for presence    if (CSReadPP16(CS_PROD_ID) != 0x630E)        return -1;    //    //  Copy our MAC address to the NIC    //     for (i = 0; i < 6; i += 2) {        j = ifn->if_mac[i] << 8;        j |= ifn->if_mac[i + 1];        CSWritePP16(CS_IEEE_ADDR + i, j);        j = CSReadPP16(CS_IEEE_ADDR + i);#if 0        if (tcp_trace) {            NutPrintFormat_P(dev_debug, PSTR("ADDR = %x\r\n"), j);            NutPrintFlush(dev_debug);        }#endif    }    //    // Enable the Transmitter and Receiver    //    CSWritePP16(CS_LINE_CTRL, 0x00C0);    //i = CSReadPP16(CS_LINE_CTRL);    //NutPrintFormat_P(dev_debug,PSTR("CS_LINE_CTRL = %x\r\n"), i);    CSWritePP16(CS_RX_CTL, 0x0F40);    //i = CSReadPP16(CS_RX_CTL);    //NutPrintFormat_P(dev_debug,PSTR("CS_RX_CTL = %x\r\n"), i);    //     // Start receiver thread    //    NutThreadCreate("csnicrx", CSNICrx, dev, 500);    return 0;}/*@}*/#elsevoid keep_icc_happy(void){}#endif

⌨️ 快捷键说明

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