hal_uart.c
来自「最新版IAR FOR ARM(EWARM)5.11中的代码例子」· C语言 代码 · 共 282 行
C
282 行
/**************************************************************************/
/* */
/* Copyright (C) 2006 Oki Electric Industry Co., LTD. */
/* */
/* System Name : uPLAT7D series */
/* Module Name : uPLAT7D uart HAL program */
/* File Name : hal_uart.c */
/* Revision : 01.00 */
/* Date : 2005/12/15 initial version */
/* */
/**************************************************************************/
#include "common.h"
#if defined(__arm)
#include "ml675050.h"
#else
#include "ml675050sim.h"
#endif
#include "hal_common.h"
#include "hal_interrupt.h"
#include "hal_uart.h"
/******************************/
/* Private defines */
/******************************/
/*--------- variable ---------*/
static volatile int16_t trans_status; /* transmit status */
static volatile uint8_t uart_rw_buf[UART_BUF_SIZE]; /* ring buffer */
static volatile uint16_t uart_rw_in;
static volatile uint16_t uart_rw_out;
static volatile uint16_t uart_rw_size;
/*--------- function ---------*/
static void _uart_handler(void); /* The handler of system timer. */
/******************************/
/* Public defines */
/******************************/
FP uart_handler = _uart_handler;
/************************************************************************/
/* */
/* Function Name : HalUart_UartInit */
/* Input : struct uPLAT_UartParam *param */
/* Output : int16_t HAL_OK(1) */
/* HAL_PARAM_ERROR(-2) */
/* */
/* Note : Initialize uart. */
/* */
/************************************************************************/
int16_t HalUart_UartInit(struct uPLAT_UartParam *param)
{
int16_t rtnVal = HAL_OK;
uint32_t uartdll0=0; /* UARTDLL0 register tmp buffer */
if (param->baudrate == 0) {
rtnVal = HAL_PARAM_ERROR;
}
if(rtnVal == HAL_OK){
trans_status = HAL_OK;
/* H/W control */
OkiCLib_set8bit(UARTLCR0, UARTLCR_DLAB); /* set DLAB */
uartdll0 = CLKUART / (16 * param->baudrate);
/* set baudrate (115200bps) */
OkiCLib_write8(UARTDLL0, (uint8_t)(uartdll0 & 0x000000FF));
OkiCLib_write8(UARTDLM0, (uint8_t)((uartdll0 >> 8) & 0x000000FF));
OkiCLib_write8(UARTDLH0, (uint8_t)((uartdll0 >> 16) & 0x000000FF));
OkiCLib_clr8bit(UARTLCR0, UARTLCR_DLAB); /* clear DLAB */
OkiCLib_write8(UARTLCR0, (UARTLCR_LEN8 /* data length : 8bit */
| UARTLCR_STB1)); /* stop bit : 1 */
OkiCLib_write8(UARTFCR0, (UARTFCR0_FIFOE /* FIFO enable */
| UARTFCR0_RFR /* Receiver FIFO reset */
| UARTFCR0_TFR /* Transmitter FIFO reset */
| UARTFCR_RFLV4)); /* RCVR FIFO interrupt trigger level : 4byte */
OkiCLib_write8(UARTIER0, (UARTIER0_ERBFI /* Enable Received Data Available Interruption */
| UARTIER0_ETBEI /* Enable Transmitter Holding Register Empty Interruption */
| UARTIER0_ELSI)); /* Enable Receiver Line Status Interruption */
OkiCLib_write8(UARTMCR0, 0x0);
}
return rtnVal;
}
/************************************************************************/
/* */
/* Function Name : HalUart_UartRxData */
/* Input : int8_t *buff */
/* Output : int16_t HAL_OK(1) */
/* HAL_PARAM_ERROR(-2) */
/* */
/* Note : uart receive data. */
/* */
/************************************************************************/
int16_t HalUart_UartRxData(int8_t *buff)
{
int16_t rtnVal = HAL_OK;
int16_t i;
/* Disable uart interrupt. */
OkiCLib_write8(UARTIER0, 0x0);
for (i = 0; i < UART_FIFO_MAX; i++) {
if (uart_rw_size > 0) {
buff[i] = (int8_t)uart_rw_buf[uart_rw_out];
uart_rw_out++;
uart_rw_size--;
if (uart_rw_out >= UART_BUF_SIZE) {
uart_rw_out = 0;
}
}
else {
buff[i] = '\0';
}
}
buff[UART_FIFO_MAX] = '\0';
/* Enable uart interrupt. */
OkiCLib_write8(UARTIER0, (UARTIER0_ERBFI /* Enable Received Data Available Interruption */
| UARTIER0_ETBEI /* Enable Transmitter Holding Register Empty Interruption */
| UARTIER0_ELSI)); /* Enable Receiver Line Status Interruption */
return rtnVal;
}
/************************************************************************/
/* */
/* Function Name : HalUart_UartTxData */
/* Input : int8_t *buff */
/* Output : int16_t HAL_OK(1) */
/* HAL_PARAM_ERROR(-2) */
/* */
/* Note : uart transmit data. */
/* */
/************************************************************************/
int16_t HalUart_UartTxData(int8_t *buff)
{
int16_t rtnVal = HAL_OK;
while ((OkiCLib_read8(UARTLSR0) & UARTLSR1_THRE) != UARTLSR1_THRE) {
;
}
OkiCLib_write8(UARTTHR0, (uint8_t)(*buff));
return rtnVal;
}
/************************************************************************/
/* */
/* Function Name : HalUart_UartReadStatus */
/* Input : uint16_t *status */
/* Output : int16_t HAL_OK(1) */
/* HAL_PARAM_ERROR(-2) */
/* */
/* Note : uart read status. */
/* */
/************************************************************************/
int16_t HalUart_UartReadStatus( int16_t *status )
{
int16_t rtnVal = HAL_OK;
if (status == NULL) {
rtnVal = HAL_PARAM_ERROR;
}
else {
*status = trans_status; /* State of TxD/RxD result */
}
return rtnVal;
}
/************************************************************************/
/* */
/* Function Name : _uart_handler */
/* Input : void */
/* Output : void */
/* */
/* Note : uart handler. */
/* */
/************************************************************************/
static void _uart_handler(void)
{
uint16_t i;
uint8_t uartiir0 = (uint8_t)(OkiCLib_read8(UARTIIR0) & UART_IIR0_MASK);
uint8_t uartlsr0 = OkiCLib_read8(UARTLSR0);
uint8_t rx_temp;
/* Received data error interrupt. */
if (uartiir0 == UARTIIR0_INTID4) {
/* Clear interrupt state. */
rx_temp = OkiCLib_read8(UARTRBR0);
trans_status = 0;
/* overrun error */
if ((uartlsr0 & UARTLSR0_OE) == UARTLSR0_OE) {
trans_status |= HAL_UART_OVR_ERROR;
}
/* parity error */
if ((uartlsr0 & UARTLSR0_PE) == UARTLSR0_PE) {
trans_status |= HAL_UART_PRT_ERROR;
}
/* framing error */
if ((uartlsr0 & UARTLSR0_FE) == UARTLSR0_FE) {
trans_status |= HAL_UART_FRM_ERROR;
}
if (trans_status == 0) {
trans_status = HAL_OK;
}
/* Notice receive completion interruption */
CALL_BACK_TABLE[INT_UART0](CALLBACK_STATE_UART_RXD);
}
/* received data interrupt */
if (uartiir0 == UARTIIR0_INTID3) {
for (i = 0; (i < UART_FIFO_MAX) && (trans_status == HAL_OK); i++) {
if (uart_rw_size > UART_BUF_SIZE) {
/* Receiver FIFO reset */
OkiCLib_set8bit(UARTFCR0, UARTFCR0_RFR);
/* overflow error */
if (trans_status == HAL_OK) {
trans_status = 0;
}
trans_status |= HAL_UART_OVF_ERROR;
}
else {
uart_rw_buf[uart_rw_in] = OkiCLib_read8(UARTRBR0);
uart_rw_size++;
uart_rw_in++;
if (uart_rw_in >= UART_BUF_SIZE) {
uart_rw_in = 0;
}
}
}
/* Notice receive completion interruption */
CALL_BACK_TABLE[INT_UART0](CALLBACK_STATE_UART_RXD);
}
/* Time out interrupt */
else if (uartiir0 == (UARTIIR0_TOI | UARTIIR0_INTID3)) {
while (((OkiCLib_read8(UARTLSR0) & UARTLSR1_DR) == UARTLSR1_DR)
&& (trans_status == HAL_OK)) {
if (uart_rw_size > UART_BUF_SIZE) {
/* Receiver FIFO reset */
OkiCLib_set8bit(UARTFCR0, UARTFCR0_RFR);
/* overflow error */
if (trans_status == HAL_OK) {
trans_status = 0;
}
trans_status |= HAL_UART_OVF_ERROR;
}
else {
uart_rw_buf[uart_rw_in] = OkiCLib_read8(UARTRBR0);
uart_rw_size++;
uart_rw_in++;
if (uart_rw_in >= UART_BUF_SIZE) {
uart_rw_in = 0;
}
}
}
/* Notice receive completion interruption */
CALL_BACK_TABLE[INT_UART0](CALLBACK_STATE_UART_TOI);
}
/* Send data interrupt */
if (uartiir0 == UARTIIR0_INTID2) {
/* Notice transmit completion interruption */
CALL_BACK_TABLE[INT_UART0](CALLBACK_STATE_UART_TXD);
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?