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

📄 serraw.c

📁 ARM入门的好帮手.包含了从简单到相对较复杂的程序.
💻 C
字号:
/* -*-C-*- * * $Revision: 1.7.6.2 $ *   $Author: rivimey $ *     $Date: 1997/12/19 15:54:51 $ * * Copyright (c) 1996 Advanced RISC Machines Limited. * All Rights Reserved. * *   Project: ANGEL * *     Title: High-level raw device driver for serial (or similar) devices. *              Interfaces to low-level drivers via serring.h. */#include "devappl.h"            /* application device support */#include "devdriv.h"            /* device driver support */#include "logging.h"#include "serring.h"/* General purpose constants, macros, enums, typedefs *//* Publically-accessible globals *//* none *//* Private globals *//* none *//* *  Function: serraw_fill_tx_ring *   Purpose: Fill up a transmit ring buffer from the Tx engine * *  Pre-conditions: Interrupts should be disabled * *    Params: *       Input: devid   device ID of the driver * *      In/Out: ring    the ring buffer to be filled * *   Returns: Nothing */static void serraw_fill_tx_ring(const DeviceID devid,                    RingBuffer * const ring){    volatile unsigned int *const status = angel_DeviceStatus + devid;    RawState *const raw_state = SerCtrl(devid)->raw_state;    bool eod = *status & SER_TX_EOD;    while ((eod == 0) && !ringBufFull(ring))    {        ringBufPutChar(ring, raw_state->tx_data[raw_state->tx_n_done++]);        eod = (raw_state->tx_n_done == raw_state->tx_length);    }    if (eod)        *status |= SER_TX_EOD;    /*     * if ring buffer was empty when we started filling it, then     * we need to kick start the first character     */    if ((*status & SER_TX_KICKSTART) != 0)    {        *status |= SER_TX_DATA;        *status &= ~SER_TX_KICKSTART;        SerCtrl(devid)->control_tx(devid);        SerCtrl(devid)->kick_start(devid);    }}/* *  Function: serraw_Write *   Purpose: Entry point for blocking writes to the serial device. *            See documentation for angel_DeviceWrite in devdriv.h */DevError serraw_Write(DeviceID devid, p_Buffer buffer, unsigned int length){    RingBuffer *const ring = SerCtrl(devid)->tx_ring;    RawState *const raw_state = SerCtrl(devid)->raw_state;    LogInfo(LOG_SERRAW, ( "serraw_Write\n"));    if (raw_state->tx_data != NULL)        return DE_BUSY;    raw_state->tx_data = buffer;    raw_state->tx_length = length;    raw_state->tx_n_done = 0;    /* need to protect this bit */    Angel_EnterSVC();    angel_DeviceStatus[devid] |= SER_TX_KICKSTART;    serraw_fill_tx_ring(devid, ring);    Angel_ExitToUSR();    while (raw_state->tx_data != NULL)        Angel_ApplDeviceYield();    /* clear busy flag used by higher levels */    Angel_EnterSVC();    angel_DeviceStatus[devid] &= ~DEV_WRITE_BUSY;    Angel_ExitToUSR();    return DE_OKAY;}/* *  Function: serraw_Read *   Purpose: Entry point for asynchronous reads from the serial device. *            See documentation for angel_Read in devdriv.h */DevError serraw_Read(DeviceID devid, p_Buffer buff, unsigned length){    RawState *const raw_state = SerCtrl(devid)->raw_state;    RingBuffer *rx_ring = SerCtrl(devid)->rx_ring;    LogInfo(LOG_SERRAW, ( "serraw_Read\n"));    Angel_EnterSVC();    raw_state->rx_data = buff;    raw_state->rx_to_go = length;    raw_state->rx_copied = length;    /* see if there is anything left over in the ring buffer */    while (ringBufNotEmpty(rx_ring) && raw_state->rx_copied > 0)    {        *raw_state->rx_data = ringBufGetChar(rx_ring);        ++raw_state->rx_data;        --raw_state->rx_to_go;        --raw_state->rx_copied;    }    if (raw_state->rx_copied == 0)        raw_state->rx_data = NULL;    /* enable reception */    SerCtrl(devid)->control_rx(devid);    Angel_ExitToUSR();    /* block */    while (raw_state->rx_data != NULL)        Angel_ApplDeviceYield();    /* clear busy flag used by higher levels */    Angel_EnterSVC();    angel_DeviceStatus[devid] &= ~DEV_READ_APPL_BUSY;    Angel_ExitToUSR();    return DE_OKAY;}/* *  Function: serraw_Control *   Purpose: Entry point for device control functions *            See documentation for angel_DeviceControl in devdriv.h */DevError serraw_Control(DeviceID devid,               DeviceControl op,               void *arg){    DevError ret_code;#if DEBUG == 1    LogInfo(LOG_SERRAW, ( "serraw_Control: op %d arg %x\n", op, arg));#endif    Angel_EnterSVC();    /* all passed through */    ret_code = SerCtrl(devid)->control(devid, op, arg);    Angel_ExitToUSR();    return ret_code;}/* *  Function: serraw_int_rx_processing *   Purpose: Deferred Rx processing for interrupt handler * *    Params: (via args) *       Input: devid           device ID of the driver * *   Returns: Nothing */void serraw_int_rx_processing(void *args){    const DeviceID devid = (DeviceID) args;    RingBuffer *ring = SerCtrl(devid)->rx_ring;    RawState *const raw_state = SerCtrl(devid)->raw_state;    unsigned int s;    ASSERT(devid < DI_NUM_DEVICES, ("devid"));    /*      * We need to disable IRQ & FIQ whenever we modify critical data     * shared with the interrupt handler     */    s = Angel_DisableInterruptsFromSVC();    /*     * If there are characters in the rx ring buffer, copy them     * to the recipient.     */    while (ringBufNotEmpty(ring) && raw_state->rx_copied > 0)    {        *raw_state->rx_data = ringBufGetChar(ring);        ++raw_state->rx_data;        --raw_state->rx_copied;        if (raw_state->rx_copied == 0)        {            raw_state->rx_data = NULL;  /* done */            SerCtrl(devid)->control_rx(devid);        }    }    /*     * call rx control to reenable interrupts in case they were disabled     */    SerCtrl(devid)->control_rx(devid);    /*     * need to clear the flag to say we have been here     */    angel_DeviceStatus[devid] &= ~SER_RX_QUEUED;    /*     * remember to reenable interrupts before we leave     */    Angel_RestoreInterruptsFromSVC(s);}/* *  Function: serraw_int_tx_processing *   Purpose: Deferred Tx processing for interrupt handler * *    Params: (via args) *       Input: devid           device ID of the driver * *   Returns: Nothing */void serraw_int_tx_processing(void *args){    const DeviceID devid = (DeviceID) args;    volatile unsigned int *const status = angel_DeviceStatus + devid;    RingBuffer *ring = SerCtrl(devid)->tx_ring;    unsigned int s;    ASSERT(devid < DI_NUM_DEVICES, ("devid"));    /*      * We need to disable IRQ & FIQ whenever we modify critical data     * shared with the interrupt handler     */    s = Angel_DisableInterruptsFromSVC();    /*     * If we are called with SER_TX_EOD set then we need to handle     * TX completion callback      */    if (((*status & SER_TX_EOD) != 0) && ringBufEmpty(ring))    {        *status &= ~SER_TX_EOD;        SerCtrl(devid)->raw_state->tx_data = NULL;  /* done */    }    /* need to clear the flag to say we have been here */    *status &= ~SER_TX_QUEUED;    /*     * If there is space in the tx ring buffer, fill it up     * as far as possible.     */    if ((*status & SER_TX_DATA) != 0)        serraw_fill_tx_ring(devid, ring);    /* remember to reenable interrupts before we leave */    Angel_RestoreInterruptsFromSVC(s);}/* EOF serraw.c */

⌨️ 快捷键说明

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