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

📄 uarthw_dsk5402.c

📁 DSP/BIOS Driver Developer Kit 1.11 The DSP/BIOS Driver Developer Kit (DDK) provides a selection of
💻 C
字号:
/*
 *  Copyright 2003 by Texas Instruments Incorporated.
 *  All rights reserved. Property of Texas Instruments Incorporated.
 *  Restricted rights to use, duplicate or disclose this code are
 *  granted through contract.
 *  
 */
/* "@(#) DDK 1.11.00.00 11-04-03 (ddk-b13)" */
/*
 *  ======== uarthw_dsk5402.c ========
 */
 
#define CHIP_5402 1

#include <std.h>

#include <hwi.h>
#include <iom.h>

#include <csl.h>
#include <csl_irq.h>

#include <uarthw.h>
#include <uarthw_dsk5402.h>

/* uart register definitions */
#define RBRREG port4000
#define THRREG port4000
#define DLLREG port4000
#define DLMREG port4001
#define IERREG port4001
#define IIRREG port4002
#define FCRREG port4002
#define LCRREG port4003
#define MCRREG port4004
#define LSRREG port4005
#define MSRREG port4006
#define SCRREG port4007

#define getLineStatus()        (LSRREG & 0xff)
#define getModemControlReg()   (MCRREG & 0xff)
#define setModemControlReg(c)   MCRREG =(c)
#define getLineControlReg()    (LCRREG & 0xff)
#define setLineControlReg(c)    LCRREG =(c)
#define disableRx()            (IERREG = IERREG & 0xFe)
#define disableTx()            (IERREG = IERREG & 0xFd)
#define enableRx()             (IERREG = IERREG | 0x01)
#define enableTx()             (IERREG = IERREG | 0x02)
#define getInt()               (IIRREG & 0xf)

#define NOINTPENDING       0x01
#define IDENTIFYINT(id)    ((id>>1)&0x03)

#define MCRDTRMASK        0xFE
#define MCRRTSMASK        0xFD
#define LCRBRKMASK        0xBF

#define AFERTSCTSMASK     0xDD
#define AFERTSCTSFLW      0x22
#define AFECTSFLW         0x20
#define AFEDISFLW         0x00

#define LCRBREAKPOS       6
#define MCRRTSPOS         1

#define UARTINTERRUPT  IRQ_EVT_INT1

#define UARTHW_DSK5402_INTR_MASK_DEFAULT  1
/* uart register addresses */
extern volatile ioport unsigned int port4000;
extern volatile ioport unsigned int port4001;
extern volatile ioport unsigned int port4002;
extern volatile ioport unsigned int port4003;
extern volatile ioport unsigned int port4004;
extern volatile ioport unsigned int port4005;
extern volatile ioport unsigned int port4006;
extern volatile ioport unsigned int port4007;

static void setupFlowParams(Uns flowParam);
static void uartIsr(Ptr cbArg);
static Int uartRxFull();

static UARTHW_DSK5402_Params defaultParams = {          \
    UARTHW_DSK5402_FLOW_AFE_RTSCTS,                             \
    UARTHW_DSK5402_DISABLE_PARITY,                      \
    UARTHW_DSK5402_WORD8,                               \
    UARTHW_DSK5402_STOP1,                               \
    UARTHW_DSK5402_BAUD_115200,                         \
    UARTHW_DSK5402_INTR_MASK_DEFAULT                    \
};

static UARTHW_Tcallback *callbacks;

/*
 *  ======== UARTHW_open ========
 *
 *  This function is used to attach to the UART 16550.
 *  Typically this function plugs the UART interrupt vector with
 *  the internal driver supplied isr routine.
 *  Initializes the UART, UART flow parameters and UART communication parameters
 *
 */
UARTHW_Handle UARTHW_open(Int uartId, Ptr params, Ptr cbArg, UARTHW_Tcallback *cbFxns)
{
    HWI_Attrs   hwattr;
    volatile Char c;
    UARTHW_DSK5402_Params *uartParams = (UARTHW_DSK5402_Params *)params;

    if (uartId > 0) {
        return (NULL);          /* only supports one UART */
    }

    /* 
     * Initialize the isrhandler to the one given by
     * generic uart.
     */
    callbacks = cbFxns;
       
    hwattr.intrMask = uartParams->intrMask;
    hwattr.arg = (Arg)cbArg;
 
    HWI_dispatchPlug(UARTINTERRUPT, (Fxn)uartIsr, &hwattr);

    /* 
     * Use the default attributes if one is not given
     */
    if (uartParams == NULL) {
        uartParams = &defaultParams;
    }
    
    /* 
     * Setup the baud and other communication parameters
     */ 
    LCRREG = 0x80;      
    DLLREG = uartParams->baud;
    DLMREG = uartParams->baud >> 8;

    /* deselect divisor latch register */
    LCRREG = uartParams->wordSize | (uartParams->stopBits << 2) |
        (uartParams->parity << 3);

    /* 
     * Initialize the rest of the UART
     */
    
    FCRREG = 0x87;      /* FIFO control register */
    IERREG = 0xff;      /* enable all interrupts */
    LSRREG = 0x00;      /* to clear the previous line status */
    MSRREG = 0x00;      /* modem status register */
    MCRREG = 0x00;
    
    /* read the UART receive buffer to clear it */
    while (uartRxFull()) {
        c = (RBRREG & 0xFF);
    }

      
    setupFlowParams((uartParams->flowControl) & UARTHW_DSK5402_HW_FLOW_MASK);
    
    enableRx();
    enableTx();
  
    IRQ_enable(UARTINTERRUPT);
    
    return ((UARTHW_Handle)1);          /* non-zero means success */
}

/*
 *  ======== UARTHW_getModemStatus ========
 *
 *  This function is used to get the modem status for the UART 16550 
 */
 
Int UARTHW_getModemStatus(UARTHW_Handle hUart, char *pmodemStatus)
{
    *pmodemStatus = (char)(MSRREG & 0xff);
   
    return (IOM_COMPLETED);
}

/*
 *  ======== UARTHW_resetDevice ========
 *
 *  This function is used to reset the UART 16550.
 *  Ideally this function should clear the transmit and 
 *  receive fifos if the fifos are being used.
 */
void UARTHW_resetDevice(UARTHW_Handle hUart)
{
    FCRREG |= 0x06;
}

/*
 *  ======== UARTHW_setBreak ========
 *
 *  This function is used to set the break on/off for the UART 16550 
 */
Int UARTHW_setBreak(UARTHW_Handle hUart, Int bBreak)
{
    char lcrVal;

    lcrVal = getLineControlReg();
    lcrVal = (lcrVal& LCRBRKMASK)|(bBreak<<LCRBREAKPOS);
    setLineControlReg(lcrVal);
   
    return (IOM_COMPLETED);
}

/*
 *  ======== UARTHW_setDTR ========
 *
 *  This function is used to set the DTR signal for the UART 16550 
 */
Int UARTHW_setDTR(UARTHW_Handle hUart, int dtrval)
{
    char mcrVal;
  
    mcrVal = getModemControlReg();
    mcrVal = (mcrVal& MCRDTRMASK)|dtrval;
    setModemControlReg(mcrVal); 

    return (IOM_COMPLETED);
}

/*
 *  ======== UARTHW_setRTS ========
 *
 *  This function is used to set the RTS signal for the UART 16550 
 */
Int UARTHW_setRTS(UARTHW_Handle hUart, int rtsval)
{
    char mcrVal;

    mcrVal = getModemControlReg();
    mcrVal = (mcrVal& MCRRTSMASK)|(rtsval<<MCRRTSPOS);
    setModemControlReg(mcrVal);
    
    return (IOM_COMPLETED);
}

/*
 *  ======== UARTHW_txEmpty ========
 *
 *  This function is used to get the transmit buffer empty condition 
 */
Int UARTHW_txEmpty(UARTHW_Handle hUart)
{
    return (LSRREG & 0x20);
}

/*
 *  ======== UARTHW_writeChar ========
 *
 *  This function is used to write a character to the transmit register 
 */
void UARTHW_writeChar(UARTHW_Handle hUart, char c)
{
    THRREG = c;
}

/*
 *  ======== UARTHW_enableRx ========
 *
 *  This function is used to enable the Rx interrupt Handler 
 */
void UARTHW_enableRx(UARTHW_Handle hUart)
{
    enableRx();
}

/*
 *  ======== UARTHW_disableRx ========
 *
 *  This function is used to disable the Rx interrupt Handler 
 */
void UARTHW_disableRx(UARTHW_Handle hUart)
{
    disableRx();
}


/*
 *  ======== setupFlowParams ========
 *
 *  This function is used to setup the UART 16550 flow paramaters
 */
static void setupFlowParams(Uns flowParam)
{
    char mcrVal;
 
    mcrVal = getModemControlReg();
 
    if (flowParam & UARTHW_DSK5402_FLOW_AFE_RTSCTS) {
        mcrVal=(mcrVal & AFERTSCTSMASK)|AFERTSCTSFLW;
    }
    else if (flowParam & UARTHW_DSK5402_FLOW_AFE_CTS) {
        mcrVal=(mcrVal & AFERTSCTSMASK)|AFECTSFLW;
    } 
    else {
        mcrVal=(mcrVal & AFERTSCTSMASK)|AFEDISFLW;  
    } 

    setModemControlReg(mcrVal);                
}

/* 
 *  ======== uartIsr ========
 *
 *  This is the interrupt service handler used by the DSK 5402
 *  UART driver.
 */
static void uartIsr(Ptr cbArg)
{
    Int         id;
    Int         argval;
    
    /*
     * While loop here since 16550 holds interrupt line high until
     * all interrupt conditions are handled (2 or more may be pending
     * at same time).  'C54x uses edge-triggered interrupts and would
     * miss interrupts otherwise.
     */
    while ((id = getInt()) != NOINTPENDING) {
        id = IDENTIFYINT(id);
    
        if (id == UARTHW_RXFULL_STATUSHANDLER) {
            if (uartRxFull()) { 
                argval=(RBRREG & 0xff); 
                (*callbacks[id])(cbArg, argval); 
            }
        } 
        else if (id == UARTHW_TXEMPTY_STATUSHANDLER) {
            (*callbacks[id])(cbArg, 0);
        } 
        else if (id == UARTHW_LINE_STATUSHANDLER) {
            argval = (LSRREG & 0xff);
        
            while ((argval & 0x0E) && (argval & 0x01)) {
                (RBRREG & 0xff);
                argval = (LSRREG & 0xff);
            }
            (*callbacks[id])(cbArg, argval); 
        }
        else if (id == UARTHW_MODEM_STATUSHANDLER) {
            argval = (MSRREG & 0xff);
            (*callbacks[id])(cbArg, argval); 
        }
    }
}

/*
 *  ======== uartRxFull ========
 *
 *  This function is used to get the Receive Buffer Full condition 
 */
static Int uartRxFull()
{
    return (LSRREG & 0x01);
}

⌨️ 快捷键说明

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