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

📄 uart.c

📁 vt6528芯片交换机API函数和文档运行程序
💻 C
字号:
/*
 * File:    uart.c
 *
 * Purpose: UART routines
 */


#if !defined(__KERNEL_H__)
#include "kernel.h"
#endif
#if !defined(__MACRO_H__)
#include "macro.h"
#endif
#if !defined(__STRTYPE_H__)
#include "strtype.h"
#endif
#if !defined(__SPRINTF_H__)
#include "sprintf.h"
#endif
#if !defined(__DEVICE_H__)
#include "device.h"
#endif
#if !defined(__TIMER_H__)
#include "timer.h"
#endif
#if !defined(__UART_H__)
#include "uart.h"
#endif




/*---------------------  Static Definitions  ------------------------*/
#define UART_RX_BUF_LEN         128

/*---------------------  Static Types  ------------------------------*/

/*---------------------  Static Macros  -----------------------------*/

/*---------------------  Static Classes  ----------------------------*/

/*---------------------  Static Variables  --------------------------*/
UINT32          sg_u32RxBufEnque;
UINT32          sg_u32RxBufDeque;
volatile UINT32 sg_u32RxBufQueueLen;
UINT8           sg_au8UartRxRing[UART_RX_BUF_LEN];

static PFN_HOOK         sg_pfnHookUart;

/*---------------------  Static Functions  --------------------------*/

/*---------------------  Export Variables  --------------------------*/




//
// Interrupt Service Routines: UART
//
void UART_vIsrUart (void)
{
    // there is an input key
    while (ASIC_UART_STAT0 & STAT_RX_READY) {
        // if rx buffer is full then drop and exit
        if (sg_u32RxBufQueueLen >= UART_RX_BUF_LEN) {
            UINT8 u8Tmp;
            u8Tmp = ASIC_UART_RXB0;
            break;
        }

        sg_au8UartRxRing[sg_u32RxBufEnque] = ASIC_UART_RXB0;
        // enque with index wrap around
        ADD_ONE_WITH_WRAP_AROUND(sg_u32RxBufEnque, UART_RX_BUF_LEN);
        sg_u32RxBufQueueLen++;

        // if got any input key, calling the callback function
        if (sg_pfnHookUart != NULL)
            sg_pfnHookUart();
    }
}


void UART_vInit (void)
{
    // init variable
    sg_u32RxBufEnque = 0;
    sg_u32RxBufDeque = 0;
    sg_u32RxBufQueueLen = 0;
    sg_pfnHookUart = NULL;

    // Initialize UART0 register
    // 8 bits, 1 stop bit, no parity, internal clock
    ASIC_UART_LCON0 = (LCON_DATA_BITS_8 | LCON_STOP_BITS_1 | LCON_PARITY_NONE | LCON_UART_CLK_INR);
    // enable rx, rx err status, and tx interrupt mode
    ASIC_UART_CONT0 = (CONT_RX_INT_ENABLE | CONT_ERR_INT_ENABLE | CONT_TX_INT_ENABLE);
    ASIC_UART_BRD0 = BRD_BAUDRATE_9600;

    INTR_vSetHandler(VEC_UART0_RX_ERR_INT, UART_vIsrUart);
    ASIC_INT_MASK &= ~MASK_UART0_RX_ERR_INT;
}


void UART_vSetHookFunc (PFN_HOOK pfnHook)
{
    INTR_vCriticalSectionEnter();
    sg_pfnHookUart = pfnHook;
    INTR_vCriticalSectionLeave();
}


BOOL UART_bSetBaudRate (UINT32 u32BaudRateMode)
{
    switch (u32BaudRateMode) {

    case MODE_BAUDRATE_9600:
        ASIC_UART_BRD0 = BRD_BAUDRATE_9600;
        break;
    case MODE_BAUDRATE_19200:
        ASIC_UART_BRD0 = BRD_BAUDRATE_19200;
        break;
    case MODE_BAUDRATE_38400:
        ASIC_UART_BRD0 = BRD_BAUDRATE_38400;
        break;
    case MODE_BAUDRATE_57600:
        ASIC_UART_BRD0 = BRD_BAUDRATE_57600;
        break;
    case MODE_BAUDRATE_115200:
        ASIC_UART_BRD0 = BRD_BAUDRATE_115200;
        break;
    case MODE_BAUDRATE_230400:
        ASIC_UART_BRD0 = BRD_BAUDRATE_230400;
        break;
    case MODE_BAUDRATE_460800:
        ASIC_UART_BRD0 = BRD_BAUDRATE_460800;
        break;

    case MODE_BAUDRATE_921600:
    default:
        return FALSE;
    }
    
    return TRUE;
}


//
// unit of u32TimeOut is 10 ms
//
// if u32TimeOut == 0, means no wait and return immediately
//
INT16 UART_i16GetCharRawTimed (UINT32 u32TimeOut)
{
    UINT32  u32StampTick = TMR_u32GetSysTick();
    INT16   i16Key = FAILED;


    // while when UART Ring buf is empty
    while (sg_u32RxBufQueueLen == 0) {
        // check if time out, if no key input during this period, thus return -1
        if (TMR_u32Diff(TMR_u32GetSysTick(), u32StampTick) >= u32TimeOut) {
            return FAILED;
        }
    }

    i16Key = (INT16)sg_au8UartRxRing[sg_u32RxBufDeque];
    // deque with wrap around
    ADD_ONE_WITH_WRAP_AROUND(sg_u32RxBufDeque, UART_RX_BUF_LEN);
    sg_u32RxBufQueueLen--;
    return i16Key;
}


void UART_vPutCharRaw(CHAR c)
{
    //check if the Tx buffer is empty, wait for sent out
    do {} while (!(ASIC_UART_STAT0 & STAT_TX_EMPTY));
    ASIC_UART_TXB0 = c;
}


void UART_vPutChar(CHAR c)
{
    UART_vPutCharRaw(c);
    // if '\n', send an extra '\r' for carriage return
    if (c == '\n')
        UART_vPutCharRaw('\r');
}


void UART_vPutStrPoll (PSTR pszStr)
{
    while (*pszStr != '\0') {
        UART_vPutCharRaw(*pszStr);
        if (*pszStr == '\n')
            UART_vPutCharRaw('\r');
        pszStr++;
    }
}


void UART_vPutStr (PSTR pszStr)
{
    while (*pszStr != '\0') {
        UART_vPutChar(*pszStr);
        pszStr++;
    }
}


INT UART_iPrintk (PCSTR pszFormat, ...)
{
    CHAR    aszBuf[MAX_STRING_LEN];
    PSTR    pszBuf = aszBuf;
    INT     iRetVal;


    PSTR piVarg = (PSTR)(&pszFormat);
    iRetVal = PRNT_iPrintFmt(&pszBuf, NULL, (PINT)piVarg);
    UART_vPutStrPoll(aszBuf);
    return iRetVal;
}


INT UART_iPrintf (PCSTR pszFormat, ...)
{
    CHAR    aszBuf[MAX_STRING_LEN];
    PSTR    pszBuf = aszBuf;
    INT     iRetVal;


    PSTR piVarg = (PSTR)(&pszFormat);
    iRetVal = PRNT_iPrintFmt(&pszBuf, NULL, (PINT)piVarg);
    UART_vPutStr(aszBuf);
    return iRetVal;
}


⌨️ 快捷键说明

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