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

📄 xuartns550.c

📁 powerpc405下linux的串口驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
* polled or interrupt driven modes. This function is non-blocking such that* it will return before the data has been sent by the UART.** In a polled mode, this function will only send as much data as the UART can* buffer, either in the transmitter or in the FIFO if present and enabled.* The application may need to call it repeatedly to send a buffer.** In interrupt mode, this function will start sending the specified buffer and* then the interrupt handler of the driver will continue until the buffer* has been sent. A callback function, as specified by the application, will* be called to indicate the completion of sending the buffer.** @param    InstancePtr is a pointer to the XUartNs550 instance to be worked on.** @return** NumBytes is the number of bytes actually sent (put into the UART tranmitter* and/or FIFO).** @note** None.******************************************************************************/unsigned int XUartNs550_SendBuffer(XUartNs550 *InstancePtr){    unsigned int SentCount = 0;    unsigned int BytesToSend = 0;   /* default to not send anything */    unsigned int FifoSize;    Xuint8 LsrRegister;    Xuint8 IirRegister;    Xuint8 IerRegister;    /* Read the line status register to determine if the transmitter is     * empty     */    LsrRegister = XIo_In8(InstancePtr->BaseAddress + XUN_LSR_OFFSET);    /* If the transmitter is not empty then don't send any data, the empty     * room in the FIFO is not available     */    if (LsrRegister & XUN_LSR_TX_BUFFER_EMPTY)    {        /*         * Read the interrupt ID register to determine if FIFOs are enabled,         */        IirRegister = XIo_In8(InstancePtr->BaseAddress + XUN_IIR_OFFSET);        /* When there are FIFOs, send up to the FIFO size. When there are         * no FIFOs, only send 1 byte of data.         */        if (IirRegister & XUN_INT_ID_FIFOS_ENABLED)        {            /* Determine how many bytes can be sent depending on if the             * transmitter is empty, a FIFO size of N is really N - 1 plus             * the transmitter register             */            if (LsrRegister & XUN_LSR_TX_EMPTY)            {                FifoSize = XUN_FIFO_SIZE;            }            else            {                FifoSize = XUN_FIFO_SIZE - 1;            }            /* FIFOs are enabled, if the number of bytes to send is less than             * the size of the FIFO, then send all bytes, otherwise fill the             * FIFO             */            if (InstancePtr->SendBuffer.RemainingBytes < FifoSize)            {                BytesToSend = InstancePtr->SendBuffer.RemainingBytes;            }            else            {                BytesToSend = FifoSize;            }        }        else if (InstancePtr->SendBuffer.RemainingBytes > 0)        {            /*             * Without FIFOs, we can only send 1 byte. We needed to check             * for non-zero remaining bytes in case this routine was called             * only to kick the transmitter and enable the UART interrupt.             */            BytesToSend = 1;        }        /*         * Fill the FIFO if it's present or the transmitter only from the         * the buffer that was specified         */        for (SentCount = 0; SentCount < BytesToSend; SentCount++)        {            XIo_Out8(InstancePtr->BaseAddress + XUN_THR_OFFSET,                     InstancePtr->SendBuffer.NextBytePtr[SentCount]);        }    }    /*     * Update the buffer to reflect the bytes that were sent from it     */    InstancePtr->SendBuffer.NextBytePtr += SentCount;    InstancePtr->SendBuffer.RemainingBytes -= SentCount;    /*     * Increment associated counters     */     InstancePtr->Stats.CharactersTransmitted += SentCount;    /* If interrupts are enabled as indicated by the receive interrupt, then     * enable the transmit interrupt, it is not enabled continuously because it     * causes an interrupt whenever the FIFO is empty     */    IerRegister = XIo_In8(InstancePtr->BaseAddress + XUN_IER_OFFSET);    if (IerRegister & XUN_IER_RX_DATA)    {        XIo_Out8(InstancePtr->BaseAddress + XUN_IER_OFFSET,                 IerRegister | XUN_IER_TX_EMPTY);    }    /*     * Return the number of bytes that were sent, althought they really were     * only put into the FIFO, not completely sent yet     */    return SentCount;}/****************************************************************************//**** This function receives a buffer that has been previously specified by setting* up the instance variables of the instance. This function is designed to be* an internal function for the XUartNs550 component such that it may be called* from a shell function that sets up the buffer or from an interrupt handler.** This function will attempt to receive a specified number of bytes of data* from the UART and store it into the specified buffer. This function is* designed for either polled or interrupt driven modes. It is non-blocking* such that it will return if there is no data has already received by the* UART.** In a polled mode, this function will only receive as much data as the UART* can buffer, either in the receiver or in the FIFO if present and enabled.* The application may need to call it repeatedly to receive a buffer. Polled* mode is the default mode of operation for the driver.** In interrupt mode, this function will start receiving and then the interrupt* handler of the driver will continue until the buffer has been received. A* callback function, as specified by the application, will be called to indicate* the completion of receiving the buffer or when any receive errors or timeouts* occur. Interrupt mode must be enabled using the SetOptions function.** @param    InstancePtr is a pointer to the XUartNs550 instance to be worked on.** @return** The number of bytes received.** @note** None.******************************************************************************/unsigned int XUartNs550_ReceiveBuffer(XUartNs550 *InstancePtr){    Xuint8 LsrRegister;    unsigned int ReceivedCount = 0;    /* Loop until there is not more data buffered by the UART or the specified     * number of bytes is received     */    while (ReceivedCount < InstancePtr->ReceiveBuffer.RemainingBytes)    {        /* Read the Line Status Register to determine if there is any data in         * the receiver/FIFO         */        LsrRegister = XIo_In8(InstancePtr->BaseAddress +                  XUN_LSR_OFFSET);        /* If there is a break condition then a zero data byte was put into         * the receiver, just read it and dump it and update the stats         */        if (LsrRegister & XUN_LSR_BREAK_INT)        {            (void)XIo_In8(InstancePtr->BaseAddress + XUN_RBR_OFFSET);            XUartNs550_mUpdateStats(InstancePtr, LsrRegister);        }        /* If there is data ready to be removed, then put the next byte         * received into the specified buffer and update the stats to reflect         * any receive errors for the byte         */        else if (LsrRegister & XUN_LSR_DATA_READY)        {            InstancePtr->ReceiveBuffer.NextBytePtr[ReceivedCount++] =                XIo_In8(InstancePtr->BaseAddress + XUN_RBR_OFFSET);            XUartNs550_mUpdateStats(InstancePtr, LsrRegister);        }        /* There's no more data buffered, so exit such that this function does         * not block waiting for data         */        else        {            break;        }    }    /* Update the receive buffer to reflect the number of bytes that was     * received     */    InstancePtr->ReceiveBuffer.NextBytePtr += ReceivedCount;    InstancePtr->ReceiveBuffer.RemainingBytes -= ReceivedCount;    /*     * Increment associated counters in the statistics     */    InstancePtr->Stats.CharactersReceived += ReceivedCount;    return ReceivedCount;}/******************************************************************************* Sets the baud rate for the specified UART. Checks the input value for* validity and also verifies that the requested rate can be configured to* within the 3 percent error range for RS-232 communications. If the provided* rate is not valid, the current setting is unchanged.** This function is designed to be an internal function only used within the* XUartNs550 component. It is necessary for initialization and for the user* available function that sets the data format.** @param    InstancePtr is a pointer to the XUartNs550 instance to be worked on.* @param    BaudRate to be set in the hardware.** @return** - XST_SUCCESS if everything configures as expected* - XST_UART_BAUD_ERROR if the requested rate is not available because*       there was too much error due to the input clock** @note** None.******************************************************************************/XStatus XUartNs550_SetBaudRate(XUartNs550 *InstancePtr, Xuint32 BaudRate){    Xuint8 BaudLSB;    Xuint8 BaudMSB;    Xuint8 LcrRegister;    Xuint32 Divisor;    Xuint32 TargetRate;    Xuint32 Error;    Xuint32 PercentError;    /*     * Assert validates the input arguments     */    XASSERT_NONVOID(InstancePtr != XNULL);    XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);    /*     * Determine what the divisor should be to get the specified baud     * rater based upon the input clock frequency and a baud clock prescaler     * of 16     */    Divisor = InstancePtr->InputClockHz / (BaudRate * 16UL);    /*     * check for too much error between the baud rate that will be generated     * using the divisor and the expected baud rate, integer division also     * truncates always positive     */    TargetRate = Divisor * BaudRate * 16UL;    Error = InstancePtr->InputClockHz - TargetRate;    /*     * Error has total error now compute the percentage multiplied by 100 to     * avoid floating point calculations, should be less than 3% as per RS-232     * spec     */    PercentError = (Error * 100UL) / InstancePtr->InputClockHz;    if (PercentError > XUN_MAX_BAUD_ERROR_RATE)    {        return XST_UART_BAUD_ERROR;    }    /* Get the least significant and most significant bytes of the divisor     * so they can be written to 2 byte registers     */    BaudLSB = Divisor & XUN_DIVISOR_BYTE_MASK;    BaudMSB = (Divisor >> 8) & XUN_DIVISOR_BYTE_MASK;    /* Save the baud rate in the instance so that the get baud rate function     * won't have to calculate it from the divisor     */    InstancePtr->BaudRate = BaudRate;    /* Get the line control register contents and set the divisor latch     * access bit so the baud rate can be set     */    LcrRegister = XIo_In8(InstancePtr->BaseAddress + XUN_LCR_OFFSET);    XIo_Out8(InstancePtr->BaseAddress + XUN_LCR_OFFSET,             LcrRegister | XUN_LCR_DLAB);    /*     * Set the baud Divisors to set rate, the initial write of 0xFF is to keep     * the divisor from being 0 which is not recommended as per the NS16550D     * spec sheet     */    XIo_Out8(InstancePtr->BaseAddress + XUN_DRLS_OFFSET, 0xFF);    XIo_Out8(InstancePtr->BaseAddress + XUN_DRLM_OFFSET, BaudMSB);    XIo_Out8(InstancePtr->BaseAddress + XUN_DRLS_OFFSET, BaudLSB);    /*     * Clear the Divisor latch access bit, DLAB to allow nornal     * operation and write to the line control register     */    XIo_Out8(InstancePtr->BaseAddress + XUN_LCR_OFFSET, LcrRegister);    return XST_SUCCESS;}/****************************************************************************//**** This function is a stub handler that is the default handler such that if the* application has not set the handler when interrupts are enabled, this* function will be called. The function interface has to match the interface* specified for a handler even though none of the arguments are used.** @param    CallBackRef is unused by this function.* @param    Event is unused by this function.* @param    ByteCount is unused by this function.** @return** None.** @note** None.******************************************************************************/static void XUartNs550_StubHandler(void *CallBackRef, Xuint32 Event,                                   unsigned int ByteCount){    /*     * Assert occurs always since this is a stub and should never be called     */    XASSERT_VOID_ALWAYS();}

⌨️ 快捷键说明

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