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

📄 ahdlcavr.c

📁 avr上的RTOS
💻 C
📖 第 1 页 / 共 3 页
字号:
    case UART_GETSTATUS:        AhdlcAvrGetStatus(dev, lvp);        break;    case UART_SETSTATUS:        AhdlcAvrSetStatus(dev, *lvp);        break;    case UART_SETREADTIMEOUT:        dcb->dcb_rtimeout = *lvp;        break;    case UART_GETREADTIMEOUT:        *lvp = dcb->dcb_rtimeout;        break;    case UART_SETWRITETIMEOUT:        dcb->dcb_wtimeout = *lvp;        break;    case UART_GETWRITETIMEOUT:        *lvp = dcb->dcb_wtimeout;        break;    case UART_SETLOCALECHO:        bv = (u_char)(*lvp);        if (bv)            dcb->dcb_modeflags |= UART_MF_LOCALECHO;        else            dcb->dcb_modeflags &= ~UART_MF_LOCALECHO;        break;    case UART_GETLOCALECHO:        if (dcb->dcb_modeflags & UART_MF_LOCALECHO)            *lvp = 1;        else            *lvp = 0;        break;    case UART_SETFLOWCONTROL:        bv = (u_char)(*lvp);        if (bv)            dcb->dcb_modeflags |= UART_MF_LOCALECHO;        else            dcb->dcb_modeflags &= ~UART_MF_LOCALECHO;        break;    case UART_GETFLOWCONTROL:        break;    case UART_SETRAWMODE:        bv = (u_char)(*lvp);        if (bv)            dcb->dcb_modeflags |= UART_MF_RAWMODE;        else            dcb->dcb_modeflags &= ~UART_MF_RAWMODE;        break;    case UART_GETRAWMODE:        if (dcb->dcb_modeflags & UART_MF_RAWMODE)            *lvp = 1;        else            *lvp = 0;        break;    case HDLC_SETIFNET:        if (ppv && (*ppv != 0)) {            dev->dev_icb = *ppv;            dev->dev_type = IFTYP_NET;            NutEventPost(&dcb->dcb_mf_evt);        } else {            dev->dev_type = IFTYP_CHAR;            if (dev->dev_icb != 0)            {                dev->dev_icb = 0;                /*                 * Signal AHDLC Thread, so it can change it's state instantly                 */                NutEventPost(&dcb->dcb_rx_rdy);            }        }        break;    case HDLC_GETIFNET:        *ppv = dev->dev_icb;        break;    default:        rc = -1;        break;    }    return rc;}/*! * \brief Initialize asynchronous HDLC device. * * This function will be called during device registration. It * initializes the hardware, registers all required interrupt * handlers and initializes all internal data structures used by * this driver. * * \param dev  Identifies the device to initialize. * * \return 0 on success, -1 otherwise. */int AhdlcAvrInit(NUTDEVICE * dev){    int rc = 0;    AHDLCDCB *dcb;    u_long baudrate = 9600;    /* Disable UART. */    AhdlcAvrDisable(dev->dev_base);    /* Initialize driver control block. */    dcb = dev->dev_dcb;    memset(dcb, 0, sizeof(AHDLCDCB));    dcb->dcb_base = dev->dev_base;    dcb->dcb_rx_buf = NutHeapAlloc(256);    dcb->dcb_tx_buf = NutHeapAlloc(256);    dcb->dcb_rx_mru = 1500;    dcb->dcb_tx_mru = 1500;    dcb->dcb_tx_accm = 0xFFFFFFFF;    /*     * Initialize UART handshake hardware and register interrupt handlers.     */    if (dev->dev_base) {#ifdef __AVR_ENHANCED__#ifdef UART1_CTS_BIT        sbi(UART1_CTS_PORT, UART1_CTS_BIT);        cbi(UART1_CTS_DDR, UART1_CTS_BIT);        /* Falling edge will generate interrupts. */#if UART1_CTS_BIT == 4        sbi(EICR, 1);#elif UART1_CTS_BIT == 5        sbi(EICR, 3);#elif UART1_CTS_BIT == 6        sbi(EICR, 5);#elif UART1_CTS_BIT == 7        sbi(EICR, 7);#endif#endif#ifdef UART1_RTS_BIT        sbi(UART1_RTS_PORT, UART1_RTS_BIT);        sbi(UART1_RTS_DDR, UART1_RTS_BIT);#endif#ifdef UART1_DTR_BIT        sbi(UART1_DTR_PORT, UART1_DTR_BIT);        sbi(UART1_DTR_DDR, UART1_DTR_BIT);#endif        if (NutRegisterIrqHandler(&sig_UART1_RECV, Rx1Complete, dcb))            rc = -1;        else if (NutRegisterIrqHandler(&sig_UART1_DATA, Tx1Complete, dcb))#ifdef UART1_CTS_BIT            rc = -1;        else if (NutRegisterIrqHandler(&UART1_CTS_SIGNAL, Cts1Interrupt, dev))#endif#endif                          /* __AVR_ENHANCED__ */            rc = -1;    } else {#ifdef UART0_CTS_BIT        sbi(UART0_CTS_PORT, UART0_CTS_BIT);        cbi(UART0_CTS_DDR, UART0_CTS_BIT);#if UART0_CTS_BIT == 4        sbi(EICR, 1);#elif UART0_CTS_BIT == 5        sbi(EICR, 3);#elif UART0_CTS_BIT == 6        sbi(EICR, 5);#elif UART0_CTS_BIT == 7        sbi(EICR, 7);#endif#endif#ifdef UART0_RTS_BIT        sbi(UART0_RTS_PORT, UART0_RTS_BIT);        sbi(UART0_RTS_DDR, UART0_RTS_BIT);#endif#ifdef UART0_DTR_BIT        sbi(UART0_DTR_PORT, UART0_DTR_BIT);        sbi(UART0_DTR_DDR, UART0_DTR_BIT);#endif        if (NutRegisterIrqHandler(&sig_UART0_RECV, Rx0Complete, dcb))            rc = -1;        else if (NutRegisterIrqHandler(&sig_UART0_DATA, Tx0Complete, dcb))            rc = -1;#ifdef UART0_CTS_BIT        else if (NutRegisterIrqHandler(&UART0_CTS_SIGNAL, Cts0Interrupt, dev))            rc = -1;#endif    }    /*     * If we have been successful so far, start the HDLC receiver thread,     * set the initial baudrate and enable the UART.     */    if (rc == 0 && NutThreadCreate("ahdlcrx", AhdlcRx, dev, NUT_THREAD_AHDLCRXSTACK)) {        AhdlcAvrIOCtl(dev, UART_SETSPEED, &baudrate);        return 0;    }    /* We failed, clean up. */    if (dcb->dcb_rx_buf)        NutHeapFree((void *) dcb->dcb_rx_buf);    if (dcb->dcb_tx_buf)        NutHeapFree((void *) dcb->dcb_tx_buf);    return -1;}/*! * \brief Read from the asynchronous HDLC device. * * This function is called by the low level input routines of the * \ref xrCrtLowio "C runtime library", using the _NUTDEVICE::dev_read * entry. * * The function may block the calling thread until at least one * character has been received or a timeout occurs. * * It is recommended to set a proper read timeout with software handshake. * In this case a timeout may occur, if the communication peer lost our * last XON character. The application may then use ioctl() to disable the * receiver and do the read again. This will send out another XON. * * \param fp     Pointer to a \ref _NUTFILE structure, obtained by a *               previous call to AhdlcOpen(). * \param buffer Pointer to the buffer that receives the data. If zero, *               then all characters in the input buffer will be *               removed. * \param size   Maximum number of bytes to read. * * \return The number of bytes read, which may be less than the number *         of bytes specified. A return value of -1 indicates an error, *         while zero is returned in case of a timeout. */int AhdlcAvrRead(NUTFILE * fp, void *buffer, int size){    int rc = 0;    AHDLCDCB *dcb = fp->nf_dev->dev_dcb;    u_char *cp = buffer;    /*     * Get characters from receive buffer.     */    if (buffer) {        while (rc < size) {            if (dcb->dcb_rd_idx != dcb->dcb_rx_idx) {                *cp++ = dcb->dcb_rx_buf[dcb->dcb_rd_idx++];                rc++;            } else if (rc || NutEventWait(&dcb->dcb_rx_rdy, dcb->dcb_rtimeout))                break;        }    }    /*     * Call without data buffer discards receive buffer.     */    else        dcb->dcb_rd_idx = dcb->dcb_rx_idx;    return rc;}/*! * \brief Write to the asynchronous HDLC device. * * \param dev    Pointer to a previously registered NUTDEVICE structure. * \param buffer Pointer the data to write. * \param len    Number of data bytes to write. * \param pflg   If this flag is set, then the buffer is located in program *               space. * * \return The number of bytes written. In case of a write timeout, this *         may be less than the specified length. */int AhdlcAvrPut(NUTDEVICE * dev, CONST void *buffer, int len, int pflg){    int rc = 0;    AHDLCDCB *dcb = dev->dev_dcb;    CONST u_char *cp = buffer;    /*     * Put characters in transmit buffer.     */    if (buffer) {        while (rc < len) {            if (SendRawByte(dcb, pflg ? PRG_RDB(cp) : *cp, 0))                break;            cp++;            rc++;        }    }    /*     * Call without data pointer starts transmission.     */    else {        /*         * TODO: Check handshake.         */#ifdef __AVR_ENHANCED__        if (dev->dev_base)            sbi(UCSR1B, UDRIE);        else#endif            sbi(UCR, UDRIE);    }    return rc;}/*! * \brief Write to the asynchronous HDLC device. * * This function is called by the low level output routines of the * \ref xrCrtLowio "C runtime library", using the * \ref _NUTDEVICE::dev_write entry. * * The function may block the calling thread. * * \param fp     Pointer to a _NUTFILE structure, obtained by a previous *               call to AhldcOpen(). * \param buffer Pointer to the data to be written. If zero, then the *               output buffer will be flushed. * \param len    Number of bytes to write. * * \return The number of bytes written, which may be less than the number *         of bytes specified if a timeout occured. A return value of -1 *         indicates an error. */int AhdlcAvrWrite(NUTFILE * fp, CONST void *buffer, int len){    return AhdlcAvrPut(fp->nf_dev, buffer, len, 0);}/*! * \brief Write to the asynchronous HDLC device. * * Similar to AhdlcWrite() except that the data is located in program * memory. * * This function is called by the low level output routines of the * \ref xrCrtLowio "C runtime library", using the _NUTDEVICE::dev_write_P * entry. * * The function may block the calling thread. * * \param fp     Pointer to a NUTFILE structure, obtained by a previous *               call to AhdlcOpen(). * \param buffer Pointer to the data in program space to be written. * \param len    Number of bytes to write. * * \return The number of bytes written, which may be less than the number *         of bytes specified if a timeout occured. A return value of -1 *         indicates an error. */int AhdlcAvrWrite_P(NUTFILE * fp, PGM_P buffer, int len){    return AhdlcAvrPut(fp->nf_dev, (CONST char *) buffer, len, 1);}/*! * \brief Open the asynchronous HDLC device. * * This function is called by the low level open routine of the C runtime * library, using the _NUTDEVICE::dev_open entry. * * \param dev Pointer to the NUTDEVICE structure. * \param name Ignored, should point to an empty string. * \param mode Operation mode. Any of the following values may be or-ed: * - \ref _O_BINARY * - \ref _O_RDONLY * - \ref _O_WRONLY * \param acc Ignored, should be zero. * * \return Pointer to a NUTFILE structure if successful or NUTFILE_EOF otherwise. */NUTFILE *AhdlcAvrOpen(NUTDEVICE * dev, CONST char *name, int mode, int acc){    NUTFILE *fp;    if ((fp = NutHeapAlloc(sizeof(NUTFILE))) == 0)        return NUTFILE_EOF;    fp->nf_next = 0;    fp->nf_dev = dev;    fp->nf_fcb = 0;    /* Enable handshake outputs. */#ifdef __AVR_ENHANCED__    if (dev->dev_base) {#ifdef UART1_RTS_BIT        cbi(UART1_RTS_PORT, UART1_RTS_BIT);#endif#ifdef UART1_DTR_BIT        cbi(UART1_DTR_PORT, UART1_DTR_BIT);#endif    } else#endif                          /* __AVR_ENHANCED__ */    {#ifdef UART0_RTS_BIT        cbi(UART0_RTS_PORT, UART0_RTS_BIT);#endif#ifdef UART0_DTR_BIT        cbi(UART0_DTR_PORT, UART0_DTR_BIT);#endif    }    return fp;}/*! * \brief Close the asynchronous HDLC device. * * This function is called by the low level close routine of the C runtime * library, using the _NUTDEVICE::dev_close entry. * * \param fp Pointer to a _NUTFILE structure, obtained by a previous call *           to UsartOpen(). * * \return 0 on success or -1 otherwise. * * \todo We may support shared open and use dev_irq as an open counter. */int AhdlcAvrClose(NUTFILE * fp){    if (fp && fp != NUTFILE_EOF) {        /* Disable handshake outputs. */#ifdef __AVR_ENHANCED__        if (fp->nf_dev->dev_base) {#ifdef UART1_RTS_BIT            sbi(UART1_RTS_PORT, UART1_RTS_BIT);#endif#ifdef UART1_DTR_BIT            sbi(UART1_DTR_PORT, UART1_DTR_BIT);#endif        } else#endif                          /* __AVR_ENHANCED__ */        {#ifdef UART0_RTS_BIT            sbi(UART0_RTS_PORT, UART0_RTS_BIT);#endif#ifdef UART0_DTR_BIT            sbi(UART0_DTR_PORT, UART0_DTR_BIT);#endif        }        NutHeapFree(fp);        return 0;    }    return -1;}/*@}*/

⌨️ 快捷键说明

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