📄 uart.c
字号:
//==================================================================================
#include "main_system.h"
#include "bspUtil_BitUtil.h"
#include "bspUtil_MemUtil.h"
//#include "esfio.h"
#include "bspIntC.h"
#include "dev_Uart.h"
#include "bspUsart.h"
#include "USB_VSP.h"
#include "uart.h"
#include "string.h"
/*
* This macro allows to know if the RX buffer is full. It must be called only
* from the RX interrupt handler. If it is called from the application, the
* rx_in pointer may be updated if a RX interrupt occurs.
*/
#define RX_BUFFER_FULL(UART) \
(((UART)->rx_in == (UART)->rx_out - 1) || \
((UART)->rx_in == (UART)->rx_out + BUFFER_SIZE))
typedef struct s_uart
{
SYS_UWORD32 base_address;
/*
* Buffers management.
*/
char rx_buffer[BUFFER_SIZE + 1];
char *rx_in; //pointer to the current position to receive
char *rx_out; //pointer to the current position for read
void (*callback_function) (void);
/*
* Errors counters.
*/
SYS_UWORD32 framing_error;
SYS_UWORD32 parity_error;
SYS_UWORD32 overrun_error;
/*
* Framing flags.
*/
SYS_BOOL dle_detected;
SYS_BOOL inframe;
SYS_BOOL encapsulation_flag;
unsigned char frame_length;
} t_uart;
static t_uart uart_parameter[NUMBER_OF_TR_UART];
T_tr_UartType UA_GetPortType(T_tr_UartId uart_id);
void UA_USB_setTransmitHoldingRegister(const Dev_Uart_Id uartId,
const Dev_Uart_RegisterValue datum);
/*--------------------------------------------------------------
Name: UA_Init
Description: Initializes the module and the UART.
Parameter:
uart_id : UART id.
baudrate: baud rate selected.
callback: user's function called characters are received.
Return: None
//--------------------------------------------------------------*/
void UA_Init (T_tr_UartId uart_id,
T_tr_Baudrate baudrate,
void (callback_function(void)))
{
t_uart *uart;
if(UA_GetPortType(uart_id) == UA_TYPE_UART)
{
uart = &(uart_parameter[uart_id]);
uart_id += 1;
UA_Open(uart_id,baudrate);
uart->rx_in = &(uart->rx_buffer[0]);
uart->rx_out = &(uart->rx_buffer[0]);
uart->framing_error = 0;
uart->parity_error = 0;
uart->overrun_error = 0;
uart->dle_detected = 0;
uart->inframe = 0;
uart->encapsulation_flag = 0;
uart->frame_length = 0;
uart->callback_function = callback_function;
bspUsart_readData((BspUsart_Id) uart_id, BSP_USART_SUSPEND_MODE_SUSPEND, bsp_Usart_rxCallback );
//UA_WakeUp (uart_id) ;
}
else if(UA_GetPortType(uart_id) == UA_TYPE_USB) /* USB virtual serial ports */
{
uart = &(uart_parameter[uart_id]);
uart->rx_in = &(uart->rx_buffer[0]);
uart->rx_out = &(uart->rx_buffer[0]);
uart->framing_error = 0;
uart->parity_error = 0;
uart->overrun_error = 0;
uart->dle_detected = 0;
uart->inframe = 0;
uart->encapsulation_flag = 0;
uart->frame_length = 0;
uart->callback_function = callback_function;
//pUSBDeviceObject = USB_OpenDevice(uart_id);
}
}
/*--------------------------------------------------------------
Name: UA_WriteNChars
Description: Writes N characters in the TX FIFO.
Parameter:
uart_id : UART id.
buffer : buffer address from which characters are
written.
bytes_to_write: number of bytes to write.
Return: Number of bytes written.
//--------------------------------------------------------------*/
SYS_UWORD32 UA_WriteNChars (T_tr_UartId uart_id,
char *buffer,
SYS_UWORD32 chars_to_write)
{
SYS_UWORD32 chars_written;
unsigned char status;
chars_written = 0;
// return;
/* physical serial ports */
if(UA_GetPortType(uart_id) == UA_TYPE_UART)
{
uart_id += 1;
//UA_WakeUp (uart_id);
while(chars_to_write != 0)
{
do{
status = dev_Uart_getLineStatusRegister(uart_id);
}while((status&0x20) == 0);
if((dev_Uart_getSupplementaryStatusRegister( uart_id ) & 0x1) == 0 )
{
dev_Uart_setTransmitHoldingRegister( uart_id, *buffer++ );
chars_to_write --;
chars_written ++;
}
}
do
{
status = dev_Uart_getLineStatusRegister(uart_id);
}while((status&0x20) == 0 || (status&0x40) == 0);
// UA_EnterSleep (uart_id);
}
else if(UA_GetPortType(uart_id) == UA_TYPE_USB) /* USB virtual serial ports */
{
chars_written = COSTENOtoUSB_Write(USB_PCO,
(unsigned char *)buffer,
(unsigned short)chars_to_write
);
}
// return(chars_to_write);
return(chars_written);
}
/*--------------------------------------------------------------
Name: UA_WriteNBytes
Description: Writes N bytes in the TX FIFO in encapsulating with 2 STX bytes
at the beginning and the end of the frame, and in making byte
stuffing. Used for FRAMING_PROTOCOL
Parameter:
uart_id : UART id.
buffer : buffer address from which bytes are
written.
bytes_to_write: number of bytes to write.
Return: None
//--------------------------------------------------------------*/
SYS_UWORD32 UA_WriteNBytes (T_tr_UartId uart_id,
SYS_UWORD8 *buffer,
SYS_UWORD32 bytes_to_write)
{
SYS_UWORD32 bytes_written;
SYS_UWORD32 bytes_in_tx_fifo;
t_uart *uart;
bytes_written = 0;
if(UA_GetPortType(uart_id) == UA_TYPE_UART)
{
uart = &(uart_parameter[uart_id]);
uart_id += 1;
if (dev_Uart_getLineStatusRegister(uart_id)&0x20)
{
bytes_in_tx_fifo = 0;
if (!uart->encapsulation_flag)
{
/*
* Write STX in the TX FIFO and set the flag.
*/
dev_Uart_setTransmitHoldingRegister(uart_id, STX);
bytes_in_tx_fifo++;
uart->encapsulation_flag = 1;
}
while ((bytes_written < bytes_to_write) &&
(bytes_in_tx_fifo < (FIFO_SIZE-2)))
{
if ((*(buffer) == STX) || (*(buffer) == DLE))
{
dev_Uart_setTransmitHoldingRegister(uart_id, DLE);
bytes_in_tx_fifo++;
}
dev_Uart_setTransmitHoldingRegister(uart_id, *(buffer++));
bytes_written++;
bytes_in_tx_fifo++;
}
if (bytes_written == bytes_to_write)
{
dev_Uart_setTransmitHoldingRegister(uart_id, STX);
uart->encapsulation_flag = 0;
}
}
}
else if(UA_GetPortType(uart_id) == UA_TYPE_USB) /* USB virtual serial ports */
{
bytes_in_tx_fifo = 0;
if (!uart->encapsulation_flag)
{
/*
|| Write STX in the TX FIFO and set the flag.
*/
UA_USB_setTransmitHoldingRegister(uart_id, STX);
bytes_in_tx_fifo++;
uart->encapsulation_flag = 1;
}
while ((bytes_written < bytes_to_write) &&
(bytes_in_tx_fifo < (FIFO_SIZE-2)))
{
if ((*(buffer) == STX) || (*(buffer) == DLE))
{
UA_USB_setTransmitHoldingRegister(uart_id, DLE);
bytes_in_tx_fifo++;
}
UA_USB_setTransmitHoldingRegister(uart_id, *(buffer++));
bytes_written++;
bytes_in_tx_fifo++;
}
if (bytes_written == bytes_to_write)
{
UA_USB_setTransmitHoldingRegister(uart_id, STX);
uart->encapsulation_flag = 0;
}
}
return bytes_written;
}
/*--------------------------------------------------------------
Name: UA_WriteChar
Description: Writes a character in the TX FIFO.
Parameter:
uart: UART id.
char character
Return: None
//--------------------------------------------------------------*/
void UA_WriteChar (T_tr_UartId uart_id,
char character)
{
(void) UA_WriteNChars (uart_id, &character, 1);
}
/*--------------------------------------------------------------
Name: UA_WriteString
Description: Writes a null terminated string in the TX FIFO.
Parameter:
uart_id: UART id.
buffer : buffer address from which characters are written.
Return: None
//--------------------------------------------------------------*/
void UA_WriteString (T_tr_UartId uart_id,
char *buffer)
{
(void) UA_WriteNChars (uart_id, buffer, strlen (buffer));
}
/*--------------------------------------------------------------
Name: UA_ReadNBytes
Description: Reads and destuff N bytes from the RX buffer.
Parameter:
uart_id : UART id.
buffer : buffer address where the bytes are copied.
chars_to_read: number of bytes to read.
BspViking_Tsp_Llif_Spi_ClockEdge activeClockEdge
Return: The number of bytes read.
//--------------------------------------------------------------*/
SYS_UWORD32 UA_ReadNBytes (T_tr_UartId uart_id,
char *buffer,
SYS_UWORD32 bytes_to_read,
SYS_BOOL *eof_detected)
{
SYS_UWORD32 bytes_in_rx_buffer;
SYS_UWORD32 bytes_to_process;
SYS_UWORD32 bytes_written;
char *rx_in;
t_uart *uart;
bytes_written = 0;
uart = &(uart_parameter[uart_id]);
/*
* A copy of the rx_in pointer is used because it may be updated by
* the interrupt handler.
* Get the number of bytes available in the RX buffer.
*/
rx_in = uart->rx_in;
if (uart->rx_out <= rx_in)
bytes_in_rx_buffer = (SYS_UWORD32) (rx_in - uart->rx_out);
else
bytes_in_rx_buffer = (SYS_UWORD32) (rx_in - uart->rx_out + BUFFER_SIZE + 1);
/*
* No more bytes than those received may be processed and then written in
* the output buffer.
*/
if (bytes_in_rx_buffer >= bytes_to_read)
bytes_to_process = bytes_to_read;
else
bytes_to_process = bytes_in_rx_buffer;
/*
* Perform the byte destuffing and then write the "valid" received bytes in
* the output buffer.
*/
while ((bytes_to_process) && !(*eof_detected))
{
switch (*(uart->rx_out))
{
/*
* Current byte is DLE.
*/
case DLE:
if (!uart->dle_detected)
{
/*
* No DLE previously detected =>
* Skip the current byte and set the flag.
*/
uart->dle_detected = 1;
bytes_to_process--;
uart->rx_out++;
}
else
{ /* if (uart->dle_detected) */
if (uart->inframe)
{
/*
* DLE previously detected AND currently inside of a frame =>
* Copy the current byte in the output buffer, reset the flag
* and increase the frame length.
*/
uart->dle_detected = 0;
bytes_to_process--;
uart->frame_length++;
*(buffer++) = *(uart->rx_out++);
bytes_written++;
}
else
{ /* if (!uart->inframe) */
/*
* DLE previously detected AND currently outside of a frame =>
* Skip the current byte.
*/
bytes_to_process--;
uart->rx_out++;
}
}
break; /* case DLE */
/*
* Current byte is STX.
*/
case STX:
if ((!uart->dle_detected) && (uart->inframe))
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -