📄 uart.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 + -