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

📄 tlc16c550.c

📁 含有完整TCP/IP PPP协议的嵌入式操作系统
💻 C
📖 第 1 页 / 共 2 页
字号:
            tv = *(u_char *) (dev->dev_base + ACE_LCTL_OFS);            tv &= (u_char) ~ (LCTL_WS0_MSK | LCTL_WS1_MSK);            tv |= (bv & (LCTL_WS0_MSK | LCTL_WS1_MSK));            *(u_char *) (dev->dev_base + ACE_LCTL_OFS) = tv;        }        AceEnable(devnum);        break;    case ACE_GETDATABITS:        *lvp = *(u_char *) (dev->dev_base + ACE_LCTL_OFS) & (LCTL_WS0_MSK | LCTL_WS1_MSK);        break;    case ACE_SETPARITY:        AceDisable(devnum);        if (bv <= 4) {            switch (bv) {            case 1:            // odd parity                bv = LCTL_PEN_MSK;                break;            case 2:            // event parity                bv = LCTL_PEN_MSK | LCTL_PRE_MSK;                break;            case 3:            // space                bv = LCTL_PEN_MSK;                break;            case 4:            // mark                bv = LCTL_PEN_MSK | LCTL_PRS_MSK;            default:           // no parity                bv = 0;                break;            }            tv = *(u_char *) (dev->dev_base + ACE_LCTL_OFS);            tv &= (u_char) ~ (LCTL_PEN_MSK | LCTL_PRE_MSK | LCTL_PRS_MSK);            tv |= bv;            *(u_char *) (dev->dev_base + ACE_LCTL_OFS) = tv;        }        AceEnable(devnum);        break;    case ACE_GETPARITY:        tv = *(u_char *) (dev->dev_base + ACE_LCTL_OFS) & (LCTL_PEN_MSK | LCTL_PRE_MSK | LCTL_PRS_MSK);        switch (tv) {        case 0:            *lvp = 0;           // no parity            break;        case LCTL_PEN_MSK:            *lvp = 1;           // odd parity            break;        case LCTL_PEN_MSK | LCTL_PRE_MSK:            *lvp = 2;           // event parity            break;        case LCTL_PEN_MSK | LCTL_PRS_MSK:            *lvp = 4;           // mark parity            break;        }        break;    case ACE_SETSTOPBITS:        AceDisable(devnum);        if (bv == 1 || bv == 2) {            tv = *(u_char *) (dev->dev_base + ACE_LCTL_OFS);            tv &= (u_char) ~ (LCTL_STB_MSK);            tv |= (bv == 2) ? LCTL_STB_MSK : 0;            *(u_char *) (dev->dev_base + ACE_LCTL_OFS) = tv;        }        AceEnable(devnum);        break;    case ACE_GETSTOPBITS:        tv = *(u_char *) (dev->dev_base + ACE_LCTL_OFS);        *lvp = (tv & LCTL_STB_MSK) ? 2 : 1;        break;    case ACE_SETFIFO:        AceDisable(devnum);        dcb->dcb_wfifo = 16;        switch (bv) {        case 1:            tv = FCTL_ENABLE | FCTL_LEVEL_1;            break;        case 4:            tv = FCTL_ENABLE | FCTL_LEVEL_4;            break;        case 8:            tv = FCTL_ENABLE | FCTL_LEVEL_8;            break;        case 14:            tv = FCTL_ENABLE | FCTL_LEVEL_14;            break;        default:            bv = 0;            tv = 0;            dcb->dcb_wfifo = 1;            break;        }        *(u_char *) (dev->dev_base + ACE_FCTL_OFS) = tv;        /* if enabling then must write the level after */        *(u_char *) (dev->dev_base + ACE_FCTL_OFS) = tv;        dcb->dcb_rfifo = bv;        /* must signal any active and waiting writer, discard pending data */        ifs = dev->dev_icb;        ifs->if_tx_act = 0;        ifs->if_tx_idx = ifs->if_wr_idx;        NutEventPostAsync(&(dcb->dcb_tx_rdy));        AceEnable(devnum);        break;    case ACE_GETFIFO:        *lvp = (u_long) (dcb->dcb_rfifo);        break;    case ACE_GETSTATUS:        AceGetStatus(dev, lvp);        break;    case ACE_SETSTATUS:        rc = -1;        break;    case ACE_SETREADTIMEOUT:        dcb->dcb_rtimeout = lv;        break;    case ACE_GETREADTIMEOUT:        *lvp = dcb->dcb_rtimeout;        break;    case ACE_SETWRITETIMEOUT:        dcb->dcb_wtimeout = lv;        break;    case ACE_GETWRITETIMEOUT:        *lvp = dcb->dcb_wtimeout;        break;    case ACE_SETLOCALECHO:        if (bv)            dcb->dcb_modeflags |= ACE_MF_LOCALECHO;        else            dcb->dcb_modeflags &= ~ACE_MF_LOCALECHO;        break;    case ACE_GETLOCALECHO:        *lvp = (dcb->dcb_modeflags & ACE_MF_LOCALECHO) ? 1 : 0;        break;    case ACE_SETFLOWCONTROL:        if (bv)            dcb->dcb_modeflags |= ACE_MF_LOCALECHO;        else            dcb->dcb_modeflags &= ~ACE_MF_LOCALECHO;        break;    case ACE_GETFLOWCONTROL:        break;    case ACE_SETCOOKEDMODE:        if (bv)            dcb->dcb_modeflags |= ACE_MF_COOKEDMODE;        else            dcb->dcb_modeflags &= ~ACE_MF_COOKEDMODE;        break;    case ACE_GETCOOKEDMODE:        *lvp = (dcb->dcb_modeflags & ACE_MF_COOKEDMODE) ? 1 : 0;        break;    default:        rc = -1;        break;    }    return rc;}/*! * \brief Initialize on chip ACE device. * * Prepares the device for subsequent reading or writing. * Enables ACE transmitter and receiver interrupts. * * \param dev  Identifies the device to initialize. * * \return 0 on success, -1 otherwise. */int AceInit(NUTDEVICE * dev){    IFSTREAM *ifs;    ACEDCB *dcb;    u_long baudrate = 9600;    u_long databits = 8;    u_long parity = 0;    u_long stopbits = 1;    IRQ_HANDLER *irq;    u_char *pnPort;    u_char nMask;    /*     * We only support character devices for on-chip ACEs.     */    if (dev->dev_type != IFTYP_STREAM) {        return -1;    }    /*     * Initialize interface control block.     */    ifs = dev->dev_icb;    memset(ifs, 0, sizeof(IFSTREAM));    ifs->if_input = AceInput;    ifs->if_output = AceOutput;    ifs->if_flush = AceFlush;    /*     * Initialize driver control block.     */    dcb = dev->dev_dcb;    memset(dcb, 0, sizeof(ACEDCB));    dcb->dcb_modeflags = ACE_MF_NOBUFFER;    dcb->dcb_rfifo = 0;    dcb->dcb_wfifo = 1;    dcb->dev_next = NULL;    /*     * Register interrupt handler.     */    if (dev->dev_base) {        /* if any ACE is already assigned to this interrupt */        if (atIrqDcb[dev->dev_irq] != NULL) {            /* put ourself on the end of the list */            (atIrqDcb[dev->dev_irq])->dev_next = dev;        } else {            // get the appropriate irq handler            irq = (IRQ_HANDLER *) pgm_read_word(&(atIrqDefs[dev->dev_irq].pvIrq));            if (NutRegisterIrqHandler(irq, AceIrqHandler, dev)) {                return -1;            }            // enable the interrupts            pnPort = (u_char *) pgm_read_word(&(atIrqDefs[dev->dev_irq].pnIrqMskPort));            nMask = pgm_read_byte(&(atIrqDefs[dev->dev_irq].nMask));            *pnPort |= nMask;        }        /* remember dcb of the recently initialized device */        atIrqDcb[dev->dev_irq] = dcb;    }    /*     * Set baudrate and handshake default. This will also     * enable the ACE functions.     */    AceIOCtl(dev, ACE_SETSPEED, (void *) &baudrate);    AceIOCtl(dev, ACE_SETDATABITS, (void *) &databits);    AceIOCtl(dev, ACE_SETPARITY, (void *) &parity);    AceIOCtl(dev, ACE_SETSTOPBITS, (void *) &stopbits);    sbi(EIMSK, dev->dev_irq);   /* dev->dev_irq to IRQ_INTx map should be used for a clean implementation but it looks like an overhead */    AceEnable(dev->dev_base);    return 0;}/*!  * \brief Read from device.  */int AceRead(NUTFILE * fp, void *buffer, int size){    int rc;    NUTDEVICE *dev;    IFSTREAM *ifs;    ACEDCB *dcb;    u_char elmode;    u_char ch;    u_char *cp = buffer;    dev = fp->nf_dev;    ifs = (IFSTREAM *) dev->dev_icb;    dcb = dev->dev_dcb;    if (dcb->dcb_modeflags & ACE_MF_COOKEDMODE)        elmode = 1;    else        elmode = 0;    /*     * Call without data pointer discards receive buffer.     */    if (buffer == 0) {        ifs->if_rd_idx = ifs->if_rx_idx;        return 0;    }    /*     * Get characters from receive buffer.     */    for (rc = 0; rc < size;) {        /* if nothing has been received yet */        if (ifs->if_rd_idx == ifs->if_rx_idx) {            /* while incomming buffer is empty */            while (ifs->if_rd_idx == ifs->if_rx_idx) {                /* wait (timeout) for incomming data */                if (AceInput(dev)) {                    /* if a timeout */                    return 0;                }            }        }        ch = ifs->if_rx_buf[ifs->if_rd_idx++];        if (elmode && (ch == '\r' || ch == '\n')) {            if ((ifs->if_last_eol == 0) || (ifs->if_last_eol == ch)) {                ifs->if_last_eol = ch;                *cp++ = '\n';                rc++;            }        } else {            ifs->if_last_eol = 0;            *cp++ = ch;            rc++;        }    }    return rc;}/*!  * \brief Write to device.  */int AcePut(NUTDEVICE * dev, CONST void *buffer, int len, int pflg){    int rc;    IFSTREAM *ifs;    ACEDCB *dcb;    CONST u_char *cp;    u_char lbmode;    u_char elmode;    u_char ch;    ifs = dev->dev_icb;    dcb = dev->dev_dcb;    if (dcb->dcb_modeflags & ACE_MF_LINEBUFFER)        lbmode = 1;    else        lbmode = 0;    if (dcb->dcb_modeflags & ACE_MF_COOKEDMODE)        elmode = 1;    else        elmode = 0;    /*     * Call without data pointer starts transmission.     */    if (buffer == 0) {        rc = AceFlush(dev);        return rc;    }    /*     * Put characters in transmit buffer.     */    cp = buffer;    for (rc = 0; rc < len;) {        if ((u_char) (ifs->if_wr_idx + 1) == ifs->if_tx_idx) {            if (AceFlush(dev)) {                return -1;            }        }        ch = pflg ? PRG_RDB(cp) : *cp;        if (elmode == 1 && ch == '\n') {            elmode = 2;            if (lbmode == 1)                lbmode = 2;            ch = '\r';        } else {            if (elmode == 2)                elmode = 1;            cp++;            rc++;        }        ifs->if_tx_buf[ifs->if_wr_idx++] = ch;    }    if (lbmode > 1 || (dcb->dcb_modeflags & ACE_MF_NOBUFFER) != 0) {        if (AceFlush(dev))            rc = -1;    }    return rc;}int AceWrite(NUTFILE * fp, CONST void *buffer, int len){    return AcePut(fp->nf_dev, buffer, len, 0);}int AceWrite_P(NUTFILE * fp, PGM_P buffer, int len){    return AcePut(fp->nf_dev, (CONST char *) buffer, len, 1);}/*!  * \brief Open a device or file. */NUTFILE *AceOpen(NUTDEVICE * dev, CONST char *name, int mode, int acc){    NUTFILE *fp = NutHeapAlloc(sizeof(NUTFILE));    ACEDCB *dcb;    if (fp == 0)        return NUTFILE_EOF;    dcb = dev->dev_dcb;    if (mode & _O_BINARY)        dcb->dcb_modeflags &= ~ACE_MF_COOKEDMODE;    else        dcb->dcb_modeflags |= ACE_MF_COOKEDMODE;    fp->nf_next = 0;    fp->nf_dev = dev;    fp->nf_fcb = 0;    return fp;}/*!  * \brief Close a device or file.  */int AceClose(NUTFILE * fp){    NutHeapFree(fp);    return 0;}/*!  * \brief Request file size. */long AceSize(NUTFILE * fp){    NUTDEVICE *dev;    IFSTREAM *ifs;    dev = fp->nf_dev;    ifs = (IFSTREAM *) dev->dev_icb;    return ((u_char) (ifs->if_rx_idx - ifs->if_rd_idx));}/*@}*/

⌨️ 快捷键说明

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