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

📄 serialio.c

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
        InterruptRTag->RTLink = RS232RTag->RTLink;
        RS232RTag->RTLink = RS232RTag->RTModule->LDResourceList;
   RS232RTag->RTModule->LDResourceList = RS232RTag;

        Disable();
   rc = SetHardwareInterrupt( p->IrqNumber,
                              irqRoutine[p->ComPort],
                              InterruptRTag, 0, 0, &eoi);


        // rc=1 for invalid parms rc = 2 for interrupt not available
   // and rc = 3 for out of memory
   Enable();

        if (rc != 0)
           {
                Free(p);
                return rc;
                }

        else
           {
                p-> InputBuffer = (char *)Alloc( RCV_FIFO_LENGTH, NLMAllocRTag );
                p-> OutputBuffer = (char *)Alloc( XMT_FIFO_LENGTH, NLMAllocRTag );
                if ( p-> InputBuffer == NULL || p-> OutputBuffer == NULL )
                   {
                        Free(p);
                        return ERR_OUT_MEMORY;
                        }

                p->ComPortLink = ComPortListHead;
           ComPortListHead = p;

           p-> EnableMask = 0;
           p-> RS232IORTag = RS232RTag;
           p-> ComStructID = ComStructSignature;
                p-> MemAllocRTag = NLMAllocRTag;

                /* initialize FIFO pointers */

                p-> RcvErrors[0] = 0;
                p-> RcvErrors[1] = 0;
                p-> RcvErrors[2] = 0;
                p-> RcvErrors[3] = 0;

                p-> XmitBufferSize = XMT_FIFO_LENGTH;
      p-> ComOutputPtr = p-> OutputBuffer;
      p-> PCOutputPtr  = p-> OutputBuffer;
           p-> RcvBufferSize = RCV_FIFO_LENGTH;
      p-> ComInputPtr = p-> InputBuffer;
      p-> PCInputPtr  = p-> InputBuffer;
                p-> RcvByteCount = 0;
                p-> RTS_OFFthreshold = HW_XOFF_THRESHOLD;
                p-> FlowControl = TRUE;
                p->RS232IORTag->RTResourceCount++;
                p->InterruptRTag = InterruptRTag;
                *ComPortHandle = (int)p;
                return 0;
                }


   }

/****************************************************************************/
WORD InitSerialPort( T_ComPortStruct *ComPortHandle, BYTE UserBitRate,
                     BYTE UserDataBits, BYTE UserStopBits, BYTE UserParity,
                                                        BYTE UserFlowControl)
{
        WORD rc;
        WORD rate, id;
        BYTE controlValue;

        if ( ComPortListHead == NULL ||
             ComPortHandle->ComStructID != ComStructSignature )
      return ERR_BAD_HANDLE;

        /* save settings in the Port Control Block */

        ComPortHandle-> BitRate =  UserBitRate;
        ComPortHandle-> DataBits = UserDataBits;
        ComPortHandle-> StopBits = UserStopBits;
        ComPortHandle-> Parity =  UserParity;

        if ((rc = ValidateParameters( ComPortHandle )) == 0)
                {
                /* if BitRate is -1 don't change callers selected rate, data bits, etc */
                if (ComPortHandle-> BitRate != -1)
                        {
                        ComPortHandle-> FlowControl =  UserFlowControl;

                        /* translate Bit Rate */
                        rate = BitRateTable[ComPortHandle-> BitRate];

                        /* translate Data Bits */
                controlValue = CharacterLengthTable[ComPortHandle-> DataBits];

                        /* translate Parity Bits */
                        controlValue |= ParityTable[ComPortHandle-> Parity];

                        /* translate Stop Bits */
                        controlValue |= StopBitTable[ComPortHandle-> StopBits];

                        /* output bit rate to the hardware */
                        outportb(ComPortHandle->IOAddress + SER_LINE_CTL, 0x80);
                        outportb(ComPortHandle->IOAddress + SER_BAUD_LSB, rate % 256);
                        outportb(ComPortHandle->IOAddress + SER_BAUD_MSB, rate / 256);

                        /* output parity, stop bits, character length to hardware */
                        outportb(ComPortHandle->IOAddress + SER_LINE_CTL, controlValue);
                        }

                /* Setting Receive Data interrupts */

                ComPortHandle-> EnableMask |= SER_DATA_ENABLE;
                outportb(ComPortHandle->IOAddress + SER_INT_ENABLE,
                         ComPortHandle-> EnableMask);
                outportb(ComPortHandle->IOAddress + SER_MODEM_CTL, OUT2 | RTS | DTR);

           ComPortHandle->RTS_ON=TRUE;
                /* Tell the interrupt controller to allow IRQ for serial port */
                outportb(INT_MASK_PORT,
                                         inportb(INT_MASK_PORT) & ~(1 << ComPortHandle->IrqNumber));

                // Make sure no outstanding pending interrupts

                id = inportb ( ComPortHandle-> IOAddress+SER_ID ) & NO_PENDING_INTR;
                if ( !id )   // there is a pending interrupt
                   {
         inportb ( ComPortHandle-> IOAddress+SER_MODEM_STATUS );
                        inportb ( ComPortHandle-> IOAddress+SER_LINE_STATUS );
                        inportb ( ComPortHandle-> IOAddress + SER_RECEIVE);
                        }
                }

        return (rc);
}
/****************************************************************************/
static WORD ValidateParameters( T_ComPortStruct *p)
{
        WORD rc;

        rc = 0;

        if ((p-> BitRate >= MaxBitRateIndex)  && (p-> BitRate != -1))
                rc = ERR_INVALID_PARAMETER;

        if (p-> DataBits >= MaxDataBitsIndex)
                rc = ERR_INVALID_PARAMETER;

        if (p-> StopBits >= MaxStopBitsIndex)
                rc = ERR_INVALID_PARAMETER;

        if (p-> Parity >= MaxParityIndex)
                rc = ERR_INVALID_PARAMETER;

        return rc;
}
/****************************************************************************/
WORD ReleasePort(T_ComPortStruct *ComPortHandle)
{
        T_ComPortStruct  *p1;

        if ( ComPortListHead == NULL ||
             ComPortHandle->ComStructID != ComStructSignature )
      return ERR_BAD_HANDLE;

        /* Disable Interrupts from serial chip */
        Disable();
        ComPortHandle-> EnableMask = 0;
        outportb(ComPortHandle->IOAddress + SER_INT_ENABLE, ComPortHandle-> EnableMask);
        outportb(ComPortHandle->IOAddress + SER_MODEM_CTL, 0x00);

        /* Disable interrupt controller for this device */
        outportb(INT_MASK_PORT,
                                 inportb(INT_MASK_PORT) | (1 << ComPortHandle->IrqNumber));
        /* Restore Interrupt Vector */
        Disable();

        ClearHardwareInterrupt(ComPortHandle->IrqNumber,
                               irqRoutine[ComPortHandle->ComPort] );

        Enable();

        ComPortHandle->RS232IORTag->RTResourceCount--;

        // delink the current acquired port from list

        if ( ComPortHandle == ComPortListHead )
           ComPortListHead = ComPortHandle->ComPortLink;
        else
           {
                p1 = ComPortListHead;
                while (p1 != NULL)
                   {
                        if (p1->ComPortLink == ComPortHandle)
                           {
                                p1->ComPortLink = ComPortHandle->ComPortLink;
                                break;
                                }
                        else
                           p1 = p1->ComPortLink;
                        }
                }

        Free(ComPortHandle->InputBuffer);
        Free(ComPortHandle->OutputBuffer);
        Free(ComPortHandle);


        return 0;
}

/***************************************************************************

   SetReceiveBufferSize(T_ComPortStruct *ComPortHandle, WORD BufferSize)

      Allocate a buffer of size BufferSize and copy the buffer pointer
      into the structure PORT for COM port given by PortNumber. This
      function will return an error code if it is called before
      AcquireSerialPort(). The function will return the size of buffer
      that has actually been allocated which may be different from
      BufferSize.

***************************************************************************/

WORD SetReceiveBufferSize(T_ComPortStruct *ComPortHandle, WORD BufferSize)
   {
        char *tmp;

        if ( ComPortListHead == NULL ||
             ComPortHandle->ComStructID != ComStructSignature )
      return ERR_BAD_HANDLE;

        if ( BufferSize < BUFFER_MIN )  BufferSize = BUFFER_MIN;
        if ( BufferSize > BUFFER_MAX )  BufferSize = BUFFER_MAX;

        tmp = (char *)Alloc( BufferSize, ComPortHandle->MemAllocRTag );

        if ( tmp != NULL )              // allocate ok, use new buffer
                {
        Free(ComPortHandle->InputBuffer);
           ComPortHandle->InputBuffer = tmp;
                }

        else                                                    // cannot allocate, use old buffer
           {
                if  ( BufferSize > ComPortHandle->RcvBufferSize )
                    BufferSize = ComPortHandle->RcvBufferSize;
                            // use old buffersize
                }

        ComPortHandle-> RcvBufferSize = BufferSize;
   ComPortHandle-> ComInputPtr = ComPortHandle-> InputBuffer;
   ComPortHandle-> PCInputPtr = ComPortHandle-> InputBuffer;
        ComPortHandle-> RcvByteCount = 0;

        return BufferSize;
        }

WORD SetTransmitBufferSize(T_ComPortStruct *ComPortHandle, WORD BufferSize)
   {
        char *tmp;

        if ( ComPortListHead == NULL ||
             ComPortHandle->ComStructID != ComStructSignature )
      return ERR_BAD_HANDLE;

        if ( BufferSize < BUFFER_MIN )  BufferSize = BUFFER_MIN;
        if ( BufferSize > BUFFER_MAX )  BufferSize = BUFFER_MAX;

        tmp = (char *)Alloc( BufferSize, ComPortHandle->MemAllocRTag );

        if ( tmp != NULL )              // allocate ok, use new buffer
                {
        Free(ComPortHandle->OutputBuffer);
           ComPortHandle->OutputBuffer = tmp;
                }

        else                                                    // cannot allocate, use old buffer
           {
                if  ( BufferSize > ComPortHandle->XmitBufferSize )
                    BufferSize = ComPortHandle->XmitBufferSize;
                            // use old buffersize
                }

        ComPortHandle-> XmitBufferSize = BufferSize;
   ComPortHandle-> ComOutputPtr = ComPortHandle-> OutputBuffer;
   ComPortHandle-> PCOutputPtr = ComPortHandle-> OutputBuffer;

        return BufferSize;
        }


/****************************************************************************/
/* returns Number of characters written                                                                                                  */
/****************************************************************************/
WORD WriteData(T_ComPortStruct *ComPortHandle, char *Buffer, WORD Length)
{
        char *NewPCOutput;
        WORD i;

        if ( ComPortListHead == NULL ||
             ComPortHandle->ComStructID != ComStructSignature )
      return ERR_BAD_HANDLE;

        i = 0;

        for ( ; i < Length; i++)
                {
                NewPCOutput = ComPortHandle-> PCOutputPtr + 1;
                   /* Make pointer circular */
           if ( NewPCOutput == (ComPortHandle-> OutputBuffer) +
                                ComPortHandle->XmitBufferSize )
                NewPCOutput = ComPortHandle-> OutputBuffer;

                if (NewPCOutput == ComPortHandle-> ComOutputPtr)
                   break;
                else
                        {
                        ComPortHandle-> PCOutputPtr[0] = Buffer[i];
                        ComPortHandle-> PCOutputPtr = NewPCOutput;
                        }
           }
        StartTransmit(ComPortHandle);

        return i;
}

/*********)******************************************************************/
/* returns Number of read                                                                                                                                        */
/****************************************************************************/
WORD ReadData(T_ComPortStruct *ComPortHandle, char *Buffer, WORD Length)
{
        char *NewPCInput;
        WORD i;

        if ( ComPortListHead == NULL ||
             ComPortHandle->ComStructID != ComStructSignature )
      return ERR_BAD_HANDLE;

        i = 0;

        Disable();
        if ( ComPortHandle->RcvByteCount == 0 ) return i;
        Enable();

        while( ComPortHandle-> PCInputPtr != ComPortHandle->ComInputPtr &&
               i < Length && ComPortHandle->RcvByteCount > 0)
                {
                Buffer[i] = ComPortHandle-> PCInputPtr[0];
                i++;
      ComPortHandle->RcvByteCount--;

                /* Update circular buffer Pointer */
                NewPCInput = ComPortHandle-> PCInputPtr + 1;
           if ( NewPCInput == (ComPortHandle-> InputBuffer) +
                                       ComPortHandle->RcvBufferSize )
                        NewPCInput = ComPortHandle-> InputBuffer;
                ComPortHandle-> PCInputPtr = NewPCInput;
           if (ComPortHandle->FlowControl && ComPortHandle->RTS_ON == FALSE)
                       // Handware Handshake and RTS was off
                   {
                   if ( ComPortHandle->RcvBufferSize - ComPortHandle->RcvByteCount >
                        ComPortHandle->RTS_OFFthreshold )   // there is more room
                                {
                                WriteModemControlRegister ( ComPortHandle,
                                  inportb(ComPortHandle->IOAddress+SER_MODEM_CTL) | RTS );
                                  // Turn RTS on
                                ComPortHandle->RTS_ON=TRUE;

                                }
                   }

⌨️ 快捷键说明

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