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

📄 uart_if.c

📁 epson usb2.0 控制芯片 S1R72V05 固件程序。
💻 C
字号:
/*
================================================================================
* @file   UART_IF.c
* @brief  UART interface module
* @author 2006/03/29 Michiru Kagaya
* Copyright (C)SEIKO EPSON Corp. All Rights Reserved.
================================================================================
*/

//=================================
// 	Include files
//=================================
#include <string.h>
#include "UART_UserConfig.h"
#include "UART_IF.h"

#ifdef TOYA2_C
	#include "reg_mx21.h"
#endif // TOYA2_C

//=================================
// 		enum declaration
//=================================

// Data transmission state
//---------------------------------
enum {
	STATE_READY,
	STATE_EXEC,
};

//=================================
// 		Structure declaration
//=================================

// Transmission information structure
//---------------------------------
typedef struct tagIF_TX_INFO {
	unsigned char STATE;
	unsigned short wTxSize;
	UART_IF_CALLBACK pfnCallback;
}IF_TX_INFO, *PIF_TX_INFO;

// Reception information structure
//---------------------------------
typedef struct tagRX_INFO {
	unsigned char STATE;
	UART_IF_CALLBACK pfnCallback;
	UART_IF_CALLBACK pfnRcvdCallback;
}IF_RX_INFO, *PIF_RX_INFO;

// Module management struture
//---------------------------------
typedef struct tagIF_MODULE_INFO {
	IF_RX_INFO	sRxInfo[MAX_UART_CHANNEL];
	IF_TX_INFO sTxInfo[MAX_UART_CHANNEL];
}IF_MODULE_INFO, *PIF_MODULE_INFO;

//=================================
// 		Variables declaration
//=================================

static IF_MODULE_INFO sModuleSts;

/*
 * UART1 - 4 control register operation table
 */
#ifdef TOYA2_C
	static volatile unsigned long* regUCR1[] = {
		&rlMX21_UCR1_1,
	//	  &rlMX21_UCR1_2,
	//	  &rlMX21_UCR1_3,
	//	  &rlMX21_UCR1_4
	} ;

	static volatile unsigned long* regUCR2[] = {
		&rlMX21_UCR2_1,
	//	  &rlMX21_UCR2_2,
	//	  &rlMX21_UCR2_3,
	//	  &rlMX21_UCR2_4
	} ;

	static volatile unsigned long* regUCR3[] = {
		&rlMX21_UCR3_1,
	//	  &rlMX21_UCR3_2,
	//	  &rlMX21_UCR3_3,
	//	  &rlMX21_UCR3_4
	} ;

	static volatile unsigned long* regUCR4[] = {
		&rlMX21_UCR4_1,
	//	  &rlMX21_UCR4_2,
	//	  &rlMX21_UCR4_3,
	//	  &rlMX21_UCR4_4
	} ;

	static volatile unsigned long* regUFCR[] = {
		&rlMX21_UFCR_1,
	//	&rlMX21_UFCR_2,
	//	&rlMX21_UFCR_3,
	//	&rlMX21_UFCR_4,
	};

	static volatile unsigned long* regURXD[] = {
		&rlMX21_URXD_1,
	//	&rlMX21_URXD_2,
	//	&rlMX21_URXD_3,
	//	&rlMX21_URXD_4,
	};

	static volatile unsigned long* regUTXD[] = {
		&rlMX21_UTXD_1,
	//	&rlMX21_UTXD_2,
	//	&rlMX21_UTXD_3,
	//	&rlMX21_UTXD_4,
	};


	static volatile unsigned long* regUBIR[] = {
		&rlMX21_UBIR_1,
	//	  &rlMX21_UBIR_2,
	//	  &rlMX21_UBIR_3,
	//	  &rlMX21_UBIR_4
	};

	static volatile unsigned long* regUBMR[] = {
		&rlMX21_UBMR_1,
	//	  &rlMX21_UBMR_2,
	//	  &rlMX21_UBMR_3,
	//	  &rlMX21_UBMR_4
	};


	static volatile unsigned long* regUSR1[] = {
		&rlMX21_USR1_1,
	//	  &rlMX21_USR1_2,
	//	  &rlMX21_USR1_3,
	//	  &rlMX21_USR1_4
	};


	static volatile unsigned long* regUSR2[] = {
		&rlMX21_USR2_1,
	//	  &rlMX21_USR2_2,
	//	  &rlMX21_USR2_3,
	//	  &rlMX21_USR2_4
	};
	static volatile unsigned long* regUTS[] = {
		&rlMX21_UTS_1,
	//	  &rlMX21_UTS_2,
	//	  &rlMX21_UTS_3,
	//	  &rlMX21_UTS_4
	};
#endif // TOYA2

//=================================
// 	Prototype declaration
//=================================
static void RxInterrupt( unsigned char bChannel );
static void TxInterrupt( unsigned char bChannel );

short UART_IFInit( void )
{
	/* Set the common pin */
#ifdef TOYA2_C
	/* UART1: PTE12-15	*/
	rlMX21_PTE_GUIS &= ~(0x0000F000) ;
	rlMX21_PTE_GPR	&= ~(0x0000F000) ;

	/* Set clock  */
	rlMX21_PCCR0	|=	0x00000001; 	/* UART1 CLK Enable: TOYA2 RS232C board */
	rlMX21_PCCR0	&= ~0x00000002; 	/* UART2 CLK Disable:Disconnect in default */
	rlMX21_PCCR0	&= ~0x00000004; 	/* UART3 CLK Disable:Disconnect in default */
	rlMX21_PCCR0	&= ~0x00000008; 	/* UART4 CLK Disable:Disconnect in default */
#endif // TOYA2

	return STATUS_SUCCESS;
}

/*
--------------------------------------------------------------------------------
*					  UART_IFOpen
* @brief   Open this module
* @param   const PUART_IF_PARAM psParam		: Setting information
*		   UART_IF_CALLBACK pfnRcvdCallback : Reception callback register
* @retval  unsigned short
*			STATUS_SUCCESS			: Complete normally
*			STATUS_INVALID_PARAMETER: Parameter error
--------------------------------------------------------------------------------
*/
short UART_IFOpen( const PUART_IF_PARAM psParam, UART_IF_CALLBACK pfnRcvdCallback )
{

	unsigned char	index;
#ifdef TOYA2_C
	unsigned long	baudrate = 0;	// Baud rate
	unsigned long	wkUFCR; 	/* Work variable used for setting register */
	unsigned long	txTrg = 2;	// Transmitter Trigger Level setting value (2-32)
	unsigned long	rxTrg = 1;	// Receiver Trigger Level setting value (1-32)
	unsigned long	divider;	// ulDivider: Setting of dividing frequency value of input clock(1-7)
	unsigned long	dcmMode = 0;	// DCE/DTE setting (0: DCE mode , 1:DTE mode)
	const unsigned long regval[] = { 0, 5, 4, 3, 2, 1, 0, 6 };
#endif // TOYA2_C

	// Check parameter
	if( psParam == NULL || pfnRcvdCallback == NULL
		|| psParam->bChannel == 0 || (psParam->bChannel > MAX_UART_CHANNEL) ){
		return STATUS_INVALID_PARAMETER;
	}
	index = psParam->bChannel-1;

#ifdef TOYA2_C
	// Configure information
	*regUCR1[index] = 0x00000000;
	*regUCR2[index] = 0x00007021;
	*regUCR3[index] = 0x00000004;
	*regUCR4[index] = 0x00000000;

	// FIFO setting
	txTrg = 2;
	rxTrg = 1;
	wkUFCR = *regUFCR[index] ;					/* Get current value */
	wkUFCR &= ~0x0000FC3F;						/* Clear TXTL,RXTL */
	wkUFCR |= ((txTrg<<10) | (rxTrg<<0)) ;	/* Reflect the setting value */

	// UART Clock Divider Set
	divider = 1;
	wkUFCR = *regUFCR[index] ;					/* Get current value */
	wkUFCR &= ~0x00000380;						/* Clear RFDIV */

	wkUFCR |= (regval[divider]<<7);				/* Reflect the setting value */
	*regUFCR[index] = wkUFCR ;					/* Set register */

	// DCE mode
	wkUFCR = *regUFCR[index];					/* Get current value */
	wkUFCR &= ~0x00000040;						/* Clear the value of RFDIV  */

	wkUFCR |= (dcmMode<<6);						/* Reflect the setting value */

	*regUFCR[index] = wkUFCR;					/* Set register */
	// Set baud rate
	switch( psParam->bBaudRate ){
		case UART_FUNC_BRATE_9600:		baudrate =	 9600; break;
		case UART_FUNC_BRATE_19200:		baudrate =	19200; break;
		case UART_FUNC_BRATE_38400:		baudrate =	38400; break;
		case UART_FUNC_BRATE_57600:		baudrate =	57600; break;
		case UART_FUNC_BRATE_115200:	baudrate = 115200; break;
		case UART_FUNC_BRATE_234000:	baudrate = 234000; break;
		case UART_FUNC_BRATE_468000:	baudrate = 468000; break;
		case UART_FUNC_BRATE_921600:	baudrate = 921600; break;
		default:
			break;
	}
	*regUBIR[index] = (baudrate/100) -1;			/* NUM:   Baudrate/100 -1*/
	*regUBMR[index] = 0x270F;					  /* NUM:	Baudrate/100 -1*/

	*regUCR1[index] |= 0x01;		/* UARTEN Bit Enable	 */
	*regUCR2[index] |= 0x06;		/* TXEN, RXEN bit Enable */

#endif // TOYA2_C

	// Initialize the management variables
	memset( &sModuleSts, 0x00, sizeof(sModuleSts) );
	sModuleSts.sRxInfo[index].pfnRcvdCallback = pfnRcvdCallback;	// Register the data reception callback
#ifdef TOYA2_C
	// Enable the interrupt
	*regUCR3[index] |= ((1<<12)|(1<<11));		//
	*regUCR4[index] |= (1<<1);					// Enable Receiver Overrun Int
	*regUCR4[index] |= (1<<2);					// Enable BRAK Condition Detect

	wkUFCR = *regUFCR[index];
	wkUFCR &= ~0x0000FC3F;						 /* Clear TXTL and RXTL */
	wkUFCR |= 0x00000801;						// FIFO 1byte Input Interrupt
	*regUFCR[index] = wkUFCR;

	*regUCR1[index] |= (1<<9);					// Enable Receiver Ready Int

	*regUCR1[index] |= (1<<0);					// UART Enable

#endif // TOYA2_C

	return STATUS_SUCCESS;
}

/*
--------------------------------------------------------------------------------
*					  UART_IFClose
* @brief   Close this module
* @param   unsigned char bChannel : the channel to close
* @retval  unsigned short
*			STATUS_SUCCESS			: complete normally
--------------------------------------------------------------------------------
*/

short UART_IFClose( unsigned char bChannel )
{
	unsigned char index = bChannel - 1;

	// check parameter
	if( bChannel == 0 || (bChannel > MAX_UART_CHANNEL) ){
		return STATUS_INVALID_PARAMETER;
	}


	sModuleSts.sRxInfo[index].pfnRcvdCallback = NULL;	// Register the data reception callback

	// Stop here because the hardware is stopped
	//--------------------------------------
	;

	return STATUS_SUCCESS;
}

/*
--------------------------------------------------------------------------------
*					  UART_IFReadData
* @brief   read the data from FIFO
* @param   unsigned char bChannel	 : The channel to use
*		   unsigned short wSize 	 : The size of read
*		   unsigned char* pData 	 : Set address
*		   unsigned short* wActSize  : The size actually read
* @retval  unsigned short
*			STATUS_SUCCESS		  : Complete normally
*			STATUS_UNSUCCESSFUL   : complete with error
--------------------------------------------------------------------------------
*/
short UART_IFReadData( unsigned char bChannel, unsigned short wSize, unsigned char* pData, unsigned short* wActSize )
{
	unsigned char index = bChannel - 1;
	unsigned short wCnt;
#ifdef TOYA2_C
	unsigned long dwRxData;
	unsigned long dwSts;
#endif // TOYA2_C
	if( wActSize != NULL ){
		*wActSize = 0;	// Intialize the read number
	}

#ifdef TOYA2_C
	// Check if FIFO is empty
	dwSts = *regUTS[index];
	if( dwSts & (1<<5) ){
		return UART_IF_RXFIFO_EMPTY;
	}
#endif // TOYA2_C

	// 		Read data
	//--------------------------------
	for( wCnt = 0; wCnt < wSize; wCnt++ ){
#ifdef TOYA2_C
		dwRxData = *regURXD[index];

		// Check if FIFO is empty
		if( (dwRxData& 0x00008000) == 0 ){
			// Detect the invalid data
			break;
		}
		*pData = (unsigned char)(dwRxData&0x000000FF);	  /* Save the read data */
#endif // TOYA2_C

		pData++;
	}

	if( wActSize != NULL ){
		*wActSize = wCnt;		// Set the actually read data number
	}

	return STATUS_SUCCESS;
}


/*
--------------------------------------------------------------------------------
*					  UART_IFWriteData
* @brief   Write data to FIFO
* @param   unsigned char bChannel	 : The channel to use
*		   unsigned short wSize 	 : The size to read
*		   unsigned char* pData 	 : Set address
*		   UART_IF_CALLBACK pfnCallback	: Function that does transmission completion notification
* @retval  unsigned short
*			STATUS_SUCCESS		  : Complet normally
*			STATUS_UNSUCCESSFUL   : Comp[lete with error
--------------------------------------------------------------------------------
*/
short UART_IFWriteData( unsigned char bChannel, unsigned short wSize, unsigned char* pData, UART_IF_CALLBACK pfnCallback )
{
	unsigned char index;
	unsigned short wCnt;

	// Check if it is enable to transmit
	index = bChannel-1;

#ifdef TOYA2_C
	if( 0 == (*regUSR1[index] & (1<<13)) )
	{
		return UART_IF_STATUS_TX_NOT_READY;
	}

#endif // TOYA2_C

	for( wCnt = 0; wCnt < wSize; wCnt++ ){
#ifdef TOYA2_C
		// Check if the TxFIFO is FULL
		if( *regUTS[index] & 0x00000010 ){
			break;
		}

		*regUTXD[index] = *pData;
#endif // TOYA2_C
		pData++;
	}

	sModuleSts.sTxInfo[index].wTxSize = wCnt;			// Number set to FIFO
	sModuleSts.sTxInfo[index].STATE = STATE_EXEC;		// Set to waiting for completion of transmission
	sModuleSts.sTxInfo[index].pfnCallback = pfnCallback;	//

#ifdef TOYA2_C
	// Enable the FIFO Empty interrupt
	*regUCR1[index] |= (1<<6);

#endif // TOYA2_C

	return STATUS_SUCCESS;
}

/*
--------------------------------------------------------------------------------
*					  UART_IF_Interrupt
* @brief   UART interrupt main process
* @param   none
* @retval  none
--------------------------------------------------------------------------------
*/
void UART_IF_Interrupt( void )
{
	RxInterrupt( 1 );
	TxInterrupt( 1 );
}

/*
--------------------------------------------------------------------------------
*					  RxInterrupt
* @brief   reception interrupt p
* @param   unsigned char bChannel
* @retval  none
--------------------------------------------------------------------------------
*/
static void RxInterrupt( unsigned char bChannel )
{
#ifdef TOYA2_C
	unsigned char index = bChannel - 1;
	unsigned long status;

	status = *regUSR2[index];

	if( status & 0x00000001 ){

		// receive data before UART_IF_ReadData is called.
		sModuleSts.sRxInfo[index].pfnRcvdCallback( UART_IF_RCVD_DATA, STATUS_SUCCESS, &bChannel );
	}
#endif // TOYA2_C

	return;
}

/*
--------------------------------------------------------------------------------
*					  TxInterrupt
* @brief   Process transmission interrupt
* @param   unsigned char bChannel
* @retval  none
--------------------------------------------------------------------------------
*/
static void TxInterrupt( unsigned char bChannel )
{
	unsigned char index = bChannel - 1;
#ifdef TOYA2_C
	unsigned long status;

	status = *regUSR2[index];

	// FIFO Empty Complete
	if( (status & 0x00004000) && ((*regUCR1[index] & (1<<6)) != 0) ){
		//Callbck notification of transmission completed
		UART_IF_TX_STS sTxSts;

		sTxSts.bChannel = bChannel;
		sTxSts.wActSize = sModuleSts.sTxInfo[index].wTxSize;
		sModuleSts.sTxInfo[index].STATE = STATE_READY;
		// Disable the FIFO Empty interrupt
		*regUCR1[index] &= ~(1<<6);
		sModuleSts.sTxInfo[index].pfnCallback( UART_IF_SND_DATA_CMP, STATUS_SUCCESS, &sTxSts );		// Completion callback notification

	}
#endif // TOYA2_C
	return;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -