📄 uart_hisr.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 "uart.h"
#include "string.h"
#include "nucleus.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];
#define UA_tx_buffer_size 8192
#define UA_TX_HISR_STACK_SIZE 4096
static char UA_tx_hisr_stack[UA_TX_HISR_STACK_SIZE];
NU_HISR UA_tx_hisr_ctrl_block;
static char UA_tx_buffer[UA_tx_buffer_size];
static Uint16 tx_in,tx_out;
/*--------------------------------------------------------------
Name: bsp_Usart_txCallback
Description: activing hisr when tx_fifo is empty.
Parameter: None
Return: None
//--------------------------------------------------------------*/
static BspUsart_ResultCode
bsp_Usart_txCallback( Uint16 irq,
BspUsart_ReInstallMode *reInstallPtr,
BspUtil_CircBuf_Handle cb,
Uint16 numBytesFree,
BspUsart_Id usartId )
{
(void) NU_Activate_HISR (&(UA_tx_hisr_ctrl_block));
*reInstallPtr = BSP_USART_REINSTALL_MODE_REINSTALL;
return 0;
}
/*--------------------------------------------------------------
Name: UA_hisr_execute_tx_operations
Description: Hisr to send chars in the driver buffer when tx_fifo
is empty.
Parameter: None
Return: None
//--------------------------------------------------------------*/
static VOID UA_hisr_execute_tx_operations(void)
{
Uint16 tx_size;
Uint16 i;
if(tx_in == tx_out)
{
return ;
}
if(tx_in > tx_out)
{
tx_size = tx_in-tx_out;
}
else
{
tx_size = tx_in+UA_tx_buffer_size-tx_out;
}
if(tx_size > FIFO_SIZE-1)
{
tx_size = FIFO_SIZE-1;
}
for(i=0;i<tx_size;i++)
{
dev_Uart_setTransmitHoldingRegister( 1, UA_tx_buffer[tx_out++] );
if(tx_out >= UA_tx_buffer_size)
{
tx_out %= UA_tx_buffer_size;
}
}
if(tx_size>0)
{
bspUsart_enableTxInterrupt(1);
}
}
/*--------------------------------------------------------------
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;
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 );
bspUsart_writeData((BspUsart_Id)uart_id, BSP_USART_SUSPEND_MODE_SUSPEND, bsp_Usart_txCallback );
//UA_WakeUp (uart_id) ;
tx_in = 0;
tx_out = 0;
memset (&(UA_tx_hisr_stack[0]), 0xFE, UA_TX_HISR_STACK_SIZE);
if (NU_Create_HISR (&(UA_tx_hisr_ctrl_block),
"UA_Tx",
UA_hisr_execute_tx_operations,
1,
&(UA_tx_hisr_stack[0]),
UA_TX_HISR_STACK_SIZE) != NU_SUCCESS)
;
}
/*--------------------------------------------------------------
Name: UA_WriteNChars
Description: putting the sent chars to the driver buffer.
Parameter:
uart_id : UART id.
buffer : buffer storing characters to written.
chars_to_write: number of bytes to send.
Return: Number of bytes written.
//--------------------------------------------------------------*/
SYS_UWORD32 UA_WriteNChars (T_tr_UartId uart_id,
char *buffer,
SYS_UWORD32 chars_to_write)
{
SYS_UWORD32 buffer_size,i;
static SYS_UWORD32 max_length = 0;
if(tx_in < tx_out) //computer the num that buffer storing chars
{
buffer_size = tx_out-tx_in-1;
}
else
{
buffer_size = tx_out+UA_tx_buffer_size-tx_in-1;
}
if(buffer_size > max_length)
{
max_length = UA_tx_buffer_size - buffer_size; //compute the max chars num in tx_buffer
}
if(chars_to_write <= buffer_size)
{
buffer_size = chars_to_write;
for(i=0;i<buffer_size;i++)
{
UA_tx_buffer[tx_in++] = *buffer++;
if(tx_in >= UA_tx_buffer_size)
{
tx_in %= UA_tx_buffer_size;
}
}
}
else
{
chars_to_write = 0;
}
bspUsart_enableTxInterrupt(1);
return chars_to_write;
}
/*--------------------------------------------------------------
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;
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;
}
}
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.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -