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

📄 ahdlcavr.c

📁 avr上的RTOS
💻 C
📖 第 1 页 / 共 3 页
字号:
             * If we are still connected to a network, fetch the next             * character from the buffer.             */            while (dcb->dcb_rd_idx == dcb->dcb_rx_idx) {                if (dev->dev_icb == 0)                    break;                /* TODO: Check for idle timeout. */                if (NutEventWait(&dcb->dcb_rx_rdy, dcb->dcb_rtimeout)) {                    continue;                }            }            /*             * Leave loop if network interface is detached             */            if (dev->dev_icb == 0)                break;            /*             * If RAW mode is active, we are not allowing any data encapsulation             * processing. So we just sleep for a while.             */            if (dcb->dcb_modeflags & UART_MF_RAWMODE) {                /*                 * It is a must to sleep here, because if we just yield it could create                 * too much processing in here and stall processing elsewhere. This gives                 * opportunity to other threads to process incoming data from USART.                 */                NutSleep(100);                continue;            }            /*             * Read next character from input buffer             */            ch = dcb->dcb_rx_buf[dcb->dcb_rd_idx++];            if (inframe) {                if (ch != AHDLC_FLAG) {                    if (ch == AHDLC_ESCAPE) {                        escaped = 1;                        continue;                    }                    if (escaped) {                        ch ^= AHDLC_TRANS;                        escaped = 0;                    }                    /*                     * Unless the peer lied to us about the negotiated MRU,                     * we should never get a frame which is too long. If it                     * happens, toss it away and grab the next incoming one.                     */                    if (rxcnt++ < dcb->dcb_rx_mru) {                        /* Update calculated checksum and store character in buffer. */                        tbx = (u_short) ((u_char) rxfcs ^ ch) << 1;                        rxfcs >>= 8;                        rxfcs ^= ((u_short) PRG_RDB(fcstab + tbx) << 8) | PRG_RDB(fcstab + tbx + 1);                        *rxptr++ = ch;                    } else                        inframe = 0;                    continue;                }                if (rxcnt > 6 && rxfcs == AHDLC_GOODFCS) {                    /*                     * If the frame checksum is valid, create a NETBUF                     * and pass it to the network specific receive handler.                     */                    rxcnt -= 2;                    if ((nb = NutNetBufAlloc(0, NBAF_DATALINK, rxcnt)) != 0) {                        memcpy(nb->nb_dl.vp, rxbuf, rxcnt);                        (*ifn->if_recv) (netdev, nb);                    }                }            }            /*             * If frame flag is received, resync frame processing             */            if (ch == AHDLC_FLAG) {                inframe = 1;                escaped = 0;                rxptr = rxbuf;                rxcnt = 0;                rxfcs = AHDLC_INITFCS;            }        }        /* Signal the link driver that we are down. */        netdev->dev_ioctl(netdev, LCP_LOWERDOWN, 0);        /* Disconnected, clean up. */        if (rxbuf) {            NutHeapFree(rxbuf);            rxbuf = 0;        }    }}/* * \param dev Indicates the UART device. * * \return 0 on success, -1 otherwise. */static int AhdlcAvrGetStatus(NUTDEVICE * dev, u_long * status){    AHDLCDCB *dcb = dev->dev_dcb;    u_char us;    *status = 0;#ifdef __AVR_ENHANCED__    if (dev->dev_base) {#ifdef UART1_CTS_BIT        if (bit_is_set(UART1_CTS_PIN, UART1_CTS_BIT))            *status |= UART_CTSDISABLED;        else            *status |= UART_CTSENABLED;#endif#ifdef UART1_RTS_BIT        if (bit_is_set(UART1_RTS_PORT, UART1_RTS_BIT))            *status |= UART_RTSDISABLED;        else            *status |= UART_RTSENABLED;#endif#ifdef UART1_DTR_BIT        if (bit_is_set(UART1_DTR_PORT, UART1_DTR_BIT))            *status |= UART_DTRDISABLED;        else            *status |= UART_DTRENABLED;#endif        us = inp(UCSR1A);    } else#endif                          /* __AVR_ENHANCED__ */    {#ifdef UART0_CTS_BIT        if (bit_is_set(UART0_CTS_PIN, UART0_CTS_BIT))            *status |= UART_CTSDISABLED;        else            *status |= UART_CTSENABLED;#endif#ifdef UART0_RTS_BIT        if (bit_is_set(UART0_RTS_PORT, UART0_RTS_BIT))            *status |= UART_RTSDISABLED;        else            *status |= UART_RTSENABLED;#endif#ifdef UART0_DTR_BIT        if (bit_is_set(UART0_DTR_PORT, UART0_DTR_BIT))            *status |= UART_DTRDISABLED;        else            *status |= UART_DTRENABLED;#endif        us = inp(USR);    }    if (us & FE)        *status |= UART_FRAMINGERROR;    if (us & DOR)        *status |= UART_OVERRUNERROR;    if (dcb->dcb_tx_idx == dcb->dcb_wr_idx)        *status |= UART_TXBUFFEREMPTY;    if (dcb->dcb_rd_idx == dcb->dcb_rx_idx)        *status |= UART_RXBUFFEREMPTY;    return 0;}/* * \param dev Indicates the UART device. * * \return 0 on success, -1 otherwise. */static int AhdlcAvrSetStatus(NUTDEVICE * dev, u_long status){#ifdef __AVR_ENHANCED__    if (dev->dev_base) {#ifdef UART1_RTS_BIT        if (status & UART_RTSDISABLED)            sbi(UART1_RTS_PORT, UART1_RTS_BIT);        else if (status & UART_RTSENABLED)            cbi(UART1_RTS_PORT, UART1_RTS_BIT);#endif#ifdef UART1_DTR_BIT        if (status & UART_DTRDISABLED)            sbi(UART1_DTR_PORT, UART1_DTR_BIT);        else if (status & UART_DTRENABLED)            cbi(UART1_DTR_PORT, UART1_DTR_BIT);#endif    } else#endif                          /* __AVR_ENHANCED__ */    {#ifdef UART0_RTS_BIT        if (status & UART_RTSDISABLED)            sbi(UART0_RTS_PORT, UART0_RTS_BIT);        else if (status & UART_RTSENABLED)            cbi(UART0_RTS_PORT, UART0_RTS_BIT);#endif#ifdef UART0_DTR_BIT        if (status & UART_DTRDISABLED)            sbi(UART0_DTR_PORT, UART0_DTR_BIT);        else if (status & UART_DTRENABLED)            cbi(UART0_DTR_PORT, UART0_DTR_BIT);#endif    }    return 0;}/* * Carefully enable UART functions. */static void AhdlcAvrEnable(u_short base){    NutEnterCritical();#ifdef __AVR_ENHANCED__    if (base) {#ifdef UART1_CTS_BIT        sbi(EIMSK, UART1_CTS_BIT);#endif        outp(BV(RXCIE) | BV(RXEN) | BV(TXEN), UCSR1B);    } else#endif                          /* __AVR_ENHANCED__ */    {#ifdef UART0_CTS_BIT        sbi(EIMSK, UART0_CTS_BIT);#endif        outp(BV(RXCIE) | BV(RXEN) | BV(TXEN), UCR);    }    NutExitCritical();}/* * Carefully disable UART functions. */static void AhdlcAvrDisable(u_short base){    /*     * Disable UART interrupts.     */    NutEnterCritical();#ifdef __AVR_ENHANCED__    if (base) {#ifdef UART1_CTS_BIT        cbi(EIMSK, UART1_CTS_BIT);#endif        outp(inp(UCSR1B) & ~(BV(RXCIE) | BV(UDRIE)), UCSR1B);    } else#endif                          /* __AVR_ENHANCED__ */    {#ifdef UART0_CTS_BIT        cbi(EIMSK, UART0_CTS_BIT);#endif        outp(inp(UCR) & ~(BV(RXCIE) | BV(UDRIE)), UCR);    }    NutExitCritical();    /*     * Allow incoming or outgoing character to finish.     */    NutDelay(10);    /*     * Now disable UART functions.     */#ifdef __AVR_ENHANCED__    if (base)        outp(inp(UCSR1B) & ~(BV(RXEN) | BV(TXEN)), UCSR1B);    else#endif                          /* __AVR_ENHANCED__ */        outp(inp(UCR) & ~(BV(RXEN) | BV(TXEN)), UCR);}/*! * \brief Perform on-chip UART control functions. * * \param dev  Identifies the device that receives the device-control *             function. * \param req  Requested control function. May be set to one of the *             following constants: *             - UART_SETSPEED, conf points to an u_long value containing the baudrate. *             - UART_GETSPEED, conf points to an u_long value receiving the current baudrate. *             - UART_SETDATABITS, conf points to an u_long value containing the number of data bits, 5, 6, 7 or 8. *             - UART_GETDATABITS, conf points to an u_long value receiving the number of data bits, 5, 6, 7 or 8. *             - UART_SETPARITY, conf points to an u_long value containing the parity, 0 (no), 1 (odd) or 2 (even). *             - UART_GETPARITY, conf points to an u_long value receiving the parity, 0 (no), 1 (odd) or 2 (even). *             - UART_SETSTOPBITS, conf points to an u_long value containing the number of stop bits 1 or 2. *             - UART_GETSTOPBITS, conf points to an u_long value receiving the number of stop bits 1 or 2. *             - UART_SETSTATUS, conf points to an u_long value containing the changes for the control lines. *             - UART_GETSTATUS, conf points to an u_long value receiving the state of the control lines and the device. *             - UART_SETREADTIMEOUT, conf points to an u_long value containing the read timeout. *             - UART_GETREADTIMEOUT, conf points to an u_long value receiving the read timeout. *             - UART_SETWRITETIMEOUT, conf points to an u_long value containing the write timeout. *             - UART_GETWRITETIMEOUT, conf points to an u_long value receiving the write timeout. *             - UART_SETLOCALECHO, conf points to an u_long value containing 0 (off) or 1 (on). *             - UART_GETLOCALECHO, conf points to an u_long value receiving 0 (off) or 1 (on). *             - UART_SETFLOWCONTROL, conf points to an u_long value containing combined UART_FCTL_ values. *             - UART_GETFLOWCONTROL, conf points to an u_long value containing receiving UART_FCTL_ values. *             - UART_SETCOOKEDMODE, conf points to an u_long value containing 0 (off) or 1 (on). *             - UART_GETCOOKEDMODE, conf points to an u_long value receiving 0 (off) or 1 (on). *             - UART_SETRAWMODE, conf points to an u_long value containing 0 (off) or 1 (on). *             - UART_GETRAWMODE, conf points to an u_long value receiving 0 (off) or 1 (on). *             - HDLC_SETIFNET, conf points to a pointer containing the address of the network device's NUTDEVICE structure. *             - HDLC_GETIFNET, conf points to a pointer receiving the address of the network device's NUTDEVICE structure. * * \param conf Points to a buffer that contains any data required for *             the given control function or receives data from that *             function. * \return 0 on success, -1 otherwise. * * \warning Timeout values are given in milliseconds and are limited to *          the granularity of the system timer. * * \bug For ATmega103, only 8 data bits, 1 stop bit and no parity are allowed. * */int AhdlcAvrIOCtl(NUTDEVICE * dev, int req, void *conf){    int rc = 0;    AHDLCDCB *dcb;    void **ppv = (void **) conf;    u_long *lvp = (u_long *) conf;    u_char bv;    u_short sv;    u_char devnum;    if (dev == 0)        dev = &devUart0;    devnum = dev->dev_base;    dcb = dev->dev_dcb;    switch (req) {    case UART_SETSPEED:        AhdlcAvrDisable(devnum);        sv = (u_short) ((((2UL * NutGetCpuClock()) / (*lvp * 16UL)) + 1UL) / 2UL) - 1;#ifdef __AVR_ENHANCED__        if (devnum) {            outp((u_char) sv, UBRR1L);            outp((u_char) (sv >> 8), UBRR1H);        } else {            outp((u_char) sv, UBRR0L);            outp((u_char) (sv >> 8), UBRR0H);        }#else        outp((u_char) sv, UBRR);#endif        AhdlcAvrEnable(devnum);        break;    case UART_GETSPEED:#ifdef __AVR_ENHANCED__        if (devnum)            sv = (u_short) inp(UBRR1H) << 8 | inp(UBRR1L);        else            sv = (u_short) inp(UBRR0H) << 8 | inp(UBRR0L);#else        sv = inp(UBRR);#endif        *lvp = NutGetCpuClock() / (16UL * (u_long) (sv + 1));        break;    case UART_SETDATABITS:        AhdlcAvrDisable(devnum);        bv = (u_char)(*lvp);#ifdef __AVR_ENHANCED__        if (bv >= 5 && bv <= 8) {            bv = (bv - 5) << 1;            if (devnum) {                outp((inp(UCSR1C) & 0xF9) | bv, UCSR1C);                outp(inp(UCSR1B) & 0xFB, UCSR1B);            } else {                outp((inp(UCSR0C) & 0xF9) | bv, UCSR0C);                outp(inp(UCSR0B) & 0xFB, UCSR0B);            }        } else            rc = -1;#else        if (bv != 8)            rc = -1;#endif        AhdlcAvrEnable(devnum);        break;    case UART_GETDATABITS:#ifdef __AVR_ENHANCED__        if (devnum)            *lvp = ((inp(UCSR1C) & 0x06) >> 1) + 5;        else            *lvp = ((inp(UCSR0C) & 0x06) >> 1) + 5;#else        *lvp = 8;#endif        break;    case UART_SETPARITY:        AhdlcAvrDisable(devnum);        bv = (u_char)(*lvp);#ifdef __AVR_ENHANCED__        if (bv <= 2) {            if (bv == 1)                bv = 3;            bv <<= 4;            if (devnum)                outp((inp(UCSR1C) & 0xCF) | bv, UCSR1C);            else                outp((inp(UCSR0C) & 0xCF) | bv, UCSR0C);        } else            rc = -1;#endif        if (bv)            rc = -1;        AhdlcAvrEnable(devnum);        break;    case UART_GETPARITY:#ifdef __AVR_ENHANCED__        if (devnum)            bv = (inp(UCSR1C) & 0x30) >> 4;        else            bv = (inp(UCSR0C) & 0x30) >> 4;        if (bv == 3)            bv = 1;#else        bv = 0;#endif        *lvp = bv;        break;    case UART_SETSTOPBITS:        AhdlcAvrDisable(devnum);        bv = (u_char)(*lvp);#ifdef __AVR_ENHANCED__        if (bv == 1 || bv == 2) {            bv = (bv - 1) << 3;            if (devnum)                outp((inp(UCSR1C) & 0xF7) | bv, UCSR1C);            else                outp((inp(UCSR0C) & 0xF7) | bv, UCSR0C);        } else            rc = -1;#else        if (bv != 1)            rc = -1;#endif        AhdlcAvrEnable(devnum);        break;    case UART_GETSTOPBITS:#ifdef __AVR_ENHANCED__        if (devnum)            *lvp = ((inp(UCSR1C) & 0x08) >> 3) + 1;        else            *lvp = ((inp(UCSR0C) & 0x08) >> 3) + 1;#else        *lvp = 1;#endif        break;

⌨️ 快捷键说明

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