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

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