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

📄 mbxlptdrv.c

📁 仍然是MBX860中的通用配置文件源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
            else                {                tx->dataLen = MAX_PIP_CHARS;		/* load size */                size -= MAX_PIP_CHARS;                pBuf += MAX_PIP_CHARS;                }             /* Clear events register  */            PIP_WRITE(*SMCE2(immrVal), ~0);             /* issue restart transmit command */            pipCcr(CPM_CR_OPCODE_RESTART);            /* synchronize all data */            syncdata();            /* Start PIP Transmit */            PIP_OR(*PIPC(immrVal), 0x8000);	    /* Wait for interrupt (on last character sent). */            if (semTake (&pDrv->syncSem,                         pDev->timeout * sysClkRateGet () * size)                == ERROR)                {                errnoSet (S_ioLib_DEVICE_ERROR);                semGive (&pDrv->muteSem);                return (ERROR);                }            else                {                pDev->charsPrinted += size;                while (lptBusy(pDrv)) 		    /* do nothing */;                 if (done)                    {                    semGive (&pDrv->muteSem);                    return((PIP_TX(tx->bdCsr)) ? size : ERROR);                     }                }            }        }    else        {        do             {            wait = 0;            sysOutByte (pDrv->data, *pBuf);            /* assert strobe */            lptStrobe(pDrv,STB_ENABLE);            /* wait for ACK, negate data strobe */            for(rdata = (UINT32)pDrv->lptRegRead (pDrv->stat),                 ackWait = ACK_TOUT;                (!(rdata & pDrv->ackValue) & ackWait--);                rdata = (UINT32)pDrv->lptRegRead(pDrv->stat));            if (ackWait != ACK_TOUT - 1)                printf("ACK Failed to occur. Status: %x\r\n", rdata);            /* Hold strobe */            while (wait != pDrv->strobeWait)                wait++;            /* Deassert strobe */            lptStrobe(pDrv,STB_DISABLE);            if (semTake (&pDrv->syncSem, pDev->timeout * sysClkRateGet ())                 == ERROR)                {                if (retry++ > pDev->retryCnt)                    {                    errnoSet (S_ioLib_DEVICE_ERROR);                    semGive (&pDrv->muteSem);                    return (ERROR);                    }                }            else                {                pBuf++;                byteCnt++;                pDev->charsPrinted++;                }            }         while (byteCnt < size)	    /* do nothing */;        semGive (&pDrv->muteSem);        }    return (size);    }/********************************************************************************* lptIoctl - special device control** This routine handles LPT_SETCONTROL and LPT_GETSTATUS requests.** RETURNS: OK or ERROR if invalid request.*/LOCAL STATUS lptIoctl    (    LPT_DEV *pDev,	/* device to control */    int function,	/* request code */    int arg		/* some argument */    )    {    LPT_DRV *pDrv = &lptDrvData[pDev->instance];    int status = OK;    semTake (&pDrv->muteSem, WAIT_FOREVER);    switch (function)	{	case LPT_SETCONTROL:    	    pDrv->lptRegWrite (pDrv->ctrl, arg);	    break;	case LPT_GETSTATUS:    	    *(int *)arg = pDrv->lptRegRead (pDrv->stat);	    break;	default:	    (void) errnoSet (S_ioLib_UNKNOWN_REQUEST);	    status = ERROR;	    break;	}    semGive (&pDrv->muteSem);    return (status);    }/********************************************************************************* lptIntr - handle an interrupt** This routine gets called to handle interrupts.* If there is another character to be transmitted, it sends it.  If* not, or if a device has never been created for this channel, just* return.** RETURNS: none.**/LOCAL void lptIntr    (    LPT_DEV *pDev    )    {    UINT immrVal = vxImmrGet ();    LPT_DRV *pDrv = &lptDrvData[pDev->instance];    pDev->inservice = TRUE;    pDev->intCnt++;    pDev->inservice = FALSE;    /* Clear PIP(SMC2) events register  */    if (!sysQspanPresent)         *SMCE2(immrVal) = ~0;     semGive (&pDrv->syncSem);    }/********************************************************************************* lptInit - initialize the specified LPT port** initialize the specified LPT port.** RETURNS: none.**/LOCAL void lptInit    (    LPT_DRV *pDrv    )    {    UINT immrVal = vxImmrGet ();    PIP_TXBD *tx = (PIP_TXBD *)PIP_PARARAM;	/* TX BD base addr */    if (!sysQspanPresent)         {        /* issue stop transmit command */        pipCcr (CPM_CR_OPCODE_STOP);         /* issue close receive buffer descriptor command */        pipCcr (CPM_CR_OPCODE_CLOSE);        /*         * Configure Transmit Buffer Descriptor         *         * Control and Status Register Settings:         *     Wrap=1      -- Final BD         *     Interrupt=1 -- Interrupts Generated         *     Last=1      -- Last (and only) Buffer Descriptor in Chain         *         * Data Length: 0 (reset)         *         */        tx->bdCsr = 0x3800;        tx->dataLen = 0;        /* Set SMC2 Transmitter Parameter RAM */        PIP_WRITE (*PIP_TBASE (PPC860_DPR_SMC2 (MPC860_DPRAM_BASE (immrVal))),                    (UINT)tx);        /* Set PIP function code register to Moto byte mode  */        PIP_WRITE (*PIP_CFCR (PPC860_DPR_SMC2 (MPC860_DPRAM_BASE (immrVal))),                   0x15);        /* Enable Fault, Sel  */        PIP_WRITE (*PIP_SMASK (PPC860_DPR_SMC2 (MPC860_DPRAM_BASE (immrVal))),                    (1<<3)|(1<<1));        /* negate strobe (no false starts) */        PIP_OR (*PBDAT(immrVal), CPM_PIP_STB);         /* Clear data lines */        PIP_AND (*PBDAT(immrVal), ~(0x0000FF00));         /*         * configure the port lines (general-purpose I/O)         *         * inputs:         *     PB14 (ACK*)         *     PB28 (F*)         *     PB29 (PE)         *     PB30 (SEL)         *     PB31 (BSY)         * outputs:         *     PB15 (STB*)         *     PB16-PB23 (DATA)         */        PIP_AND (*PBDIR(immrVal), PIP_INPUTS);	/* the inputs */        PIP_OR (*PBDIR(immrVal), PIP_OUTPUTS);	/* the outputs */        PIP_AND (*PBPAR(immrVal), PIP_GPIO);	/* general-purpose I/O */        /*         * Configure PIP Timing Parameters Register         * Assume Clock Period of 41 ns --> 24 MHz System Clock         * According to Centronics Spec:  TPAR1=TPAR2 >= 1.0 usec  (25)         */        PIP_WRITE (*PTPR(immrVal), (25<<8) |25);        /*         * PIP control register:         * all data control and data movement is handled by the         * CPU (i.e., host control)         */         PIP_WRITE (*PIPC(immrVal), 0x0D);	        /* issue initialize Tx parameters command */        pipCcr (CPM_CR_OPCODE_INIT_T);         /*         * clear any previous interrupt status         * disable all interrupts (polled mode)         */        PIP_WRITE (*SMCE2(immrVal), 0xff);        PIP_WRITE (*SMCM2(immrVal), 0x00);        /* issue restart transmit command */        pipCcr (CPM_CR_OPCODE_RESTART);        /*         * Program CPM Command Register:         *         * INIT Transmit (SMC2)         *         * NOTE:  Always issue this command after programming the PIP PRAM.         *         * wait for any pending commands to complete         */        while (PIP_READ (*CPCR(immrVal)) & CPM_CR_FLG)	    /* do nothing */;        /* issue command */        PIP_OR (*CPCR(immrVal),                 (CPM_CR_CHANNEL_PIP | (0x2<<8) | (0xd<<4) | CPM_CR_FLG));        /* wait for issued command to complete */        while (PIP_READ (*CPCR(immrVal)) & CPM_CR_FLG)	    /* do nothing */;        /* Enable Interrupt on TX. */        PIP_WRITE (*SMCM2(immrVal), 0x01);        }    else        {        pDrv->lptRegWrite (pDrv->ctrl, 0);		/* init */        if (pDrv->pDev->autofeed)            pDrv->lptRegWrite (pDrv->ctrl,                                (C_ENABLE | C_NOINIT | C_SELECT | C_AUTOFEED));        else            pDrv->lptRegWrite (pDrv->ctrl, (C_ENABLE | C_NOINIT | C_SELECT));        }    }/********************************************************************************* pipCcr - execute channel command** This routine to execute a specified channel command.  The channel command* register is read prior to execution to verify that there are no outstanding* commands, this is done by waiting for a zero status.  The channel command* register is also read after the command execution to insure command* completion prior to returning.* * RETURNS: none*/ void pipCcr    (    UINT32 cmd			/* command to execute */    )    {    UINT32 immrVal = vxImmrGet ();    /* wait for any pending commands to complete */    while (PIP_READ (*CPCR(immrVal)) & CPM_CR_FLG)	/* do nothing */;    /* issue command */    PIP_WRITE(*CPCR (immrVal), (CPM_CR_CHANNEL_PIP | cmd | CPM_CR_FLG));    /* wait for issued command to complete */     while ( PIP_READ( *CPCR(immrVal)) & CPM_CR_FLG)	/* do nothing */;    return;}/********************************************************************************* lptShow - show LPT statistics** This routine shows statistics for a specified LPT port.** RETURNS: None*/void lptShow    (    UINT channel	/* channel (0 - 2) */    )    {    LPT_DEV *pDev = &lptDevData[channel];    LPT_DRV *pDrv = &lptDrvData[channel];    if (channel > N_LPT_CHANNELS)	return;    printf ("controlReg        = 0x%x\n", pDrv->lptRegRead (pDrv->ctrl));    printf ("statusize         = 0x%x\n", pDrv->lptRegRead (pDrv->stat));    printf ("created           = %s\n",   pDev->created ? "TRUE" : "FALSE");    printf ("autofeed          = %s\n",   pDev->autofeed ? "TRUE" : "FALSE");    printf ("inservice         = %s\n",   pDev->inservice ? "TRUE" : "FALSE");    printf ("normalInt         = %d\n",   pDev->intCnt);    printf ("retryCnt          = %d\n",   pDev->retryCnt);    printf ("busyWait   (loop) = %d\n",   pDrv->busyWait);    printf ("strobeWait (loop) = %d\n",   pDrv->strobeWait);    printf ("timeout    (sec)  = %d\n",   pDev->timeout);    printf ("intLevel   (IRQ)  = %d\n",   pDev->intLevel);    printf ("charsPrinted      = %d\n",   pDev->charsPrinted);    }/********************************************************************************* pipIoctl - I/O control** This routine performs the specified PIP IO actions.** The parameter `ioctlflg' specifies the type of IO to be performed, and may* be set to any one of the following,** .CS*   PIP_IOCTL_W -- write*   PIP_IOCTL_R -- read*   PIP_IOCTL_O -- read/or/write*   PIP_IOCTL_A -- read/and/write*   PIP_IOCTL_AO -- read/and/or/write* .CE** Parameter `pReg' specifies the register address, `size' is the register size* in bytes (1, 2, or 4), `wdata1' is the data to write #1 and is not used for* a read operation, `wdata2' is the data to write #2 and is also not used for* a read operation.** RETURNS: data read on a read operation, and zero for non-read.*/LOCAL UINT pipIoctl    (    UINT ioctlflg,	/* io control flag */    UINT pReg,		/* register pointer */    UINT size,		/* register size (1/2/4 bytes) */    UINT wdata1,	/* write data #1 */    UINT wdata2		/* write data #2 */    )    {    UINT rdata;    UINT8 *pReg1;    UINT16 *pReg2;    register UINT*pReg4;    rdata = 0;           /* make the compiler happy */    switch (size)         {        case 1:            pReg1 = (UINT8 *)pReg;            switch (ioctlflg)                 {                case PIP_IOCTL_W:           /* write */                    *pReg1 = wdata1;                    break;                case PIP_IOCTL_R:           /* read */                    rdata = *pReg1;                    break;                case PIP_IOCTL_O:           /* read/or/write */                    *pReg1 |= wdata1;                    break;                case PIP_IOCTL_A:           /* read/and/write */                    *pReg1 &= wdata1;                    break;                case PIP_IOCTL_AO:          /* read/and/or/write */                    *pReg1 = (*pReg1 & wdata1) | wdata2;                    break;                }            break;        case 2:            pReg2 = (UINT16 *)pReg;            switch (ioctlflg)                 {                case PIP_IOCTL_W:           /* write */                    *pReg2 = wdata1;                    break;                case PIP_IOCTL_R:           /* read */                    rdata = *pReg2;                    break;                case PIP_IOCTL_O:           /* read/or/write */                    *pReg2 |= wdata1;                    break;                case PIP_IOCTL_A:           /* read/and/write */                    *pReg2 &= wdata1;                    break;                case PIP_IOCTL_AO:          /* read/and/or/write */                    *pReg2 = (*pReg2 & wdata1) | wdata2;                    break;                }            break;        case 4:            pReg4 = (UINT *)pReg;            switch (ioctlflg)                 {                case PIP_IOCTL_W:           /* write */                    *pReg4 = wdata1;                    break;                case PIP_IOCTL_R:           /* read */                    rdata = *pReg4;                    break;                case PIP_IOCTL_O:           /* read/or/write */                    *pReg4 |= wdata1;                    break;                case PIP_IOCTL_A:           /* read/and/write */                    *pReg4 &= wdata1;                    break;                case PIP_IOCTL_AO:          /* read/and/or/write */                    *pReg4 = (*pReg4 & wdata1) | wdata2;                    break;                }            break;       }   /* synchronize all data */   syncdata ();   return (rdata);   }#ifdef DEBUG_LPT/********************************************************************************* lptDebug - PIP/FDC LPT Debug Function** This routine continuously sends all printable characters to printer.**/UINT lptDebug     (     UINT channel	/* channel (0 - 2) */    )    {    UINT8 ii;    LPT_DRV *pDrv;    pDrv = &(lptDrvData[channel]);    FOREVER        {        /* Fill buffer */                  for(ii=0; ii<60; ii++)             debugBuf[ii] = ii + 0x41;        debugBuf[ii++] = CR;         debugBuf[ii++] = NL;         lptWrite(pDrv->pDev,debugBuf,62);        }    return (0);    }#endif /* defined(DEBUG_LPT) */#endif /* defined(INCLUDE_LPT) */

⌨️ 快捷键说明

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