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

📄 uart_hisr.c

📁 手机底层驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
//==================================================================================
#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 + -