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

📄 drv_rs232.c

📁 Epson系列芯片开发的例子
💻 C
字号:
/********************************************************************************************************
 *													*
 *	Copyright (C) SEIKO EPSON CORP. 2002								*
 *													*
 *	File name: Drv_rs232.c										*
 *	  This is serial interface driver.								*
 *													*
  *	Revision history										*
 *		2002.05.30	Andrew Yin	Start.							*
 *													*
 ********************************************************************************************************/

#include "common.h"
#include "8timer.h"
#include "io.h"
#include "presc.h"
#include "sif.h"
#include "int.h"
#include "main.h"

// Prototype
void vInitRS232( unsigned char ucChannel, unsigned long ulBaudrate );
void vInitUart( unsigned char ucChannel, unsigned long ulBaudrate );
void vSetUartMode( unsigned char ucChannel, unsigned char ucIrDAData, unsigned char ucMode );
void vIntUart0TransmitData( void );
void vIntUart0ReceiveData( void );
void vIntUart1TransmitData( void);
void vIntUart1ReceiveData( void );
void vStartTransmit( unsigned char ucChannel );
void vStopTransmit( unsigned char ucChannel );
void vStartReceive( unsigned char ucChannel );
void vStopReceive( unsigned char ucChannel );
unsigned short usReadUartData( unsigned char ucChannel );
void vWriteUartData( unsigned char ucChannel, unsigned char ucTransmitData  );

unsigned char gucUart0ReceiveData;
unsigned char *gucpUart0TransmitString;
unsigned char gucUart1ReceiveData;
unsigned char *gucpUart1TransmitString;

unsigned char gucUartTransmitFinish0;
unsigned char gucUartTransmitFinish1;
unsigned char gucUartReceiveFinish0;
unsigned char gucUartReceiveFinish1;

/********************************************************************************************************
 * vInitRS232
 *   Type :	void
 *   Ret val :	none
 *   Argument :	
 *   Function :	Initialize rs232.
 *******************************************************************************************************/
void vInitRS232( unsigned char ucChannel, unsigned long ulBaudrate )
{
	unsigned char ucIrDAData, ucMode;
	
	// Asynchronous clock division ratio 1/16
	// UART interface
	ucIrDAData = SIF_DIVMD_16 | SIF_IRMD_ORD;
	
	// Input clock internal clock
	// Serial interface mode asynchronous 8bit
	// Parity even mode
	// Parity off
	ucMode = SIF_SMD_8BIT | SIF_SSCK_INT | SIF_STPB_1 | SIF_EPR_OFF | SIF_PMD_EVEN;
	
	vInitUart( ucChannel, ulBaudrate );
	vSetUartMode( ucChannel, ucIrDAData, ucMode );
}

/********************************************************************************************************
 * vStartTransmit
 *   Type :	void
 *   Ret val :	none
 *   Argument :	unsigned char ucChannel:	UART channel ( 0 and 1 )
 *   Function :	Start transmit ( open the transmit interrupt of the Uart ).
 *******************************************************************************************************/
void vStartTransmit( unsigned char ucChannel )
{
	// [0x40286] Clear receive buffer full interrupt flag
	*(volatile unsigned char *)INT_FS_ADDR |= INT_FSTX1 >> ( ucChannel * 3 );
	
	// [0x401e3] Set UART transmit enable
	*(volatile unsigned char *)( SIF_SMD0_ADDR + ucChannel * 5 ) |= SIF_TXEN_ENA;
}

/********************************************************************************************************
 * vStartReceive
 *   Type :	void
 *   Ret val :	none
 *   Argument :	unsigned char ucChannel:	UART channel ( 0 and 1 )
 *   Function :	Start transmit ( open the transmit interrupt of the Uart ).
 *******************************************************************************************************/
void vStartReceive( unsigned char ucChannel )
{
	// [0x40286] Clear receive buffer full interrupt flag
	*(volatile unsigned char *)INT_FS_ADDR |= INT_FSRX1 >> ( ucChannel * 3 );
	
	// [0x401e3] Set UART receive enable
	*(volatile unsigned char *)( SIF_SMD0_ADDR + ucChannel * 5 ) |= SIF_RXEN_ENA;
}

/********************************************************************************************************
 * vStopTransmit
 *   Type :	void
 *   Ret val :	none
 *   Argument :	unsigned char ucChannel:	UART channel ( 0 and 1 )
 *   Function :	Stop transmit ( Clear the transmit interrupt of the Uart ).
 *******************************************************************************************************/
void vStopTransmit( unsigned char ucChannel )
{
	// [0x401e2] waiting transmit completion
	while( *(volatile unsigned char *)(SIF_RDBF0_ADDR + ucChannel * 5 ) & SIF_TEND_ON )
	{;}
	
	// [0x401e3] Set UART Transmit disable
	*(volatile unsigned char *)( SIF_SMD0_ADDR + ucChannel * 5 ) &= ~SIF_TXEN_ENA;
}

/********************************************************************************************************
 * vStopReceive
 *   Type :	void
 *   Ret val :	none
 *   Argument :	unsigned char ucChannel:	UART channel ( 0 and 1 )
 *   Function :	Stop Receive ( Clear the transmit interrupt of the Uart ).
 *******************************************************************************************************/
void vStopReceive( unsigned char ucChannel )
{
	// [0x401e3] Set UART receive disable
	*(volatile unsigned char *)( SIF_SMD0_ADDR + ucChannel * 5 ) &= ~SIF_RXEN_ENA;
}

/********************************************************************************************************
 * vInitUart
 *   Type :	void
 *   Ret val :	none
 *   Argument :	unsigned char ucChannel:	UART channel ( 0 and 1 )
 *		unsigned long ulBaudrate: 	UART baudrate: 2400 ~ 115200bps
 *   Function :	Initialize asynchronous serial and 8bit timer used as Baudrate generator.
 *******************************************************************************************************/
void vInitUart( unsigned char ucChannel, unsigned long ulBaudrate )
{
	switch( ucChannel )
	{
		case	0:
			// [0x402d0] Set serial interface I/O port (P0 port) SOUT0, SIN0 port
			*(volatile unsigned char *)IO_CFP0_ADDR |= IO_CFP01_SOUT0 | IO_CFP00_SIN0;
		
			// [0x4014e] Set 8bit timer2 prescaler ( CLK / 4 )
			*(volatile unsigned char *)PRESC_P8TS2_P8TS3_ADDR &= 0x0F0;
			*(volatile unsigned char *)PRESC_P8TS2_P8TS3_ADDR |= PRESC_PTONL_ON | PRESC_CLKDIVL_SEL1;
		
			// [0x40169] Set 8bit timer2 reload data
			*(volatile unsigned char *)T8P_RLD2_ADDR = ( unsigned char )( MAINCLK / 4 / 16 / 2.0 / ulBaudrate - 0.5 );
		
			// [0x40168] Reset 8bit timer2 and timer start for serial interface ch.0
			*(volatile unsigned char *)T8P_PTRUN2_ADDR = T8P_PTOUT_ON | T8P_PSET_ON | T8P_PTRUN_RUN;
			
			// [0x40269] set SI/F ch.0 interrupt level to 4
			*(volatile unsigned char *)INT_P8TM_PSIO0_ADDR &= 0x0F;
			*(volatile unsigned char *)INT_P8TM_PSIO0_ADDR |= 0x40;
			
			// [0x40286] Clear receive buffer full and transmit buffer empty interrupt flag
			*(volatile unsigned char *)INT_FS_ADDR |= INT_FSRX0 | INT_FSTX0;
			
			// [0x40276] Set serial interface ch.0 receive buffer full and transmit buffer empty interrupt enable
			*(volatile unsigned char *)INT_ES_ADDR |= INT_ESRX0 | INT_ESTX0;
			break;
		case	1:
			// [0x402d0] Set serial interface I/O port (P0 port): SOUT1, SIN1 port
			*(volatile unsigned char *)IO_CFP0_ADDR |= IO_CFP04_SIN1 | IO_CFP05_SOUT1;
										
			// 0x4014e] Set 8bit timer3 prescaler ( CLK / 4 )
			*(volatile unsigned char *)PRESC_P8TS2_P8TS3_ADDR &= 0x0f;
			*(volatile unsigned char *)PRESC_P8TS2_P8TS3_ADDR |= PRESC_PTONH_ON | PRESC_CLKDIVH_SEL1;
        		
			// [0x4016d] Set 8bit timer3 reload data
			*(volatile unsigned char *)T8P_RLD3_ADDR = ( unsigned char )( MAINCLK / 4 / 16 / 2.0 / ulBaudrate - 0.5 );
        		
			// [0x4016c] Reset 8bit timer3 and timer start for serial interface ch.1
			*(volatile unsigned char *)T8P_PTRUN3_ADDR = T8P_PTOUT_ON | T8P_PSET_ON | T8P_PTRUN_RUN;
			
			// [0x4026a] set SI/F ch.1 interrupt level to 4
			*(volatile unsigned char *)INT_PSIO1_PAD_ADDR &= 0x0F0;
			*(volatile unsigned char *)INT_PSIO1_PAD_ADDR |= 0x04;
			
			// [0x40286] Clear receive buffer full and transmit buffer empty interrupt flag
			*(volatile unsigned char *)INT_FS_ADDR |= INT_FSRX1 | INT_FSTX1;
			
			// [0x40276] Set serial interface ch.1 receive buffer full and transmit buffer empty interrupt enable
			*(volatile unsigned char *)INT_ES_ADDR |= INT_ESRX1 | INT_ESTX1;
			break;
		default:
	}

	/*
		OSC3 = OSC3 clock (15 x 4 = 60MHz)
		BPS = Serial transfer speed (9600bps)
		PDR = Prescaler clock division (1/4)
		SDR = Serial interface internal clock division (1/16, asynchronous only)
		RLD = (OSC3 x PDR x SDR) / (2 x BPS) - 1
		    = (60 x 1000000 x 1/4 x 1/16) / (2 x 9600) - 1 = 47.8 = 0x30
		BPS		RLD		ERROR RATIO
		2400		0x0C2		0.3125 / 194 = 0.16%
		4800		0x61		0.65625 / 97 = -0.7%
		9600		0x30		0.2 / 47.8 = -0.4%
		19200		0x17		0.4 / 23.4 = 1.7%
		57600		0x7		0.14 / 7.14 = 2%
		115200		0x3    		0.07/3.07 = 2.28%
	*/
}

 /******************************************************************************************************
 * vSetUartMode
 *   Type :	void
 *   Ret val :	none
 *   Argument :	unsigned char ucChannel:	Serial channel number
 *		unsigned char ucIrDAData:	IrDA control data:IrDA 1.0 mode or General I/F; async. clk division ratio
 *		unsigned char ucMode:		Serial ucMode: async. or sync. etc.
 *   Function :	Set serial interface mode.
 *******************************************************************************************************/
void vSetUartMode( unsigned char ucChannel, unsigned char ucIrDAData, unsigned char ucMode )
{
	// [0x401e2] Clear serial status: overrun error flag, parity error flag, flaming error flag
	*(volatile unsigned char *)(SIF_RDBF0_ADDR + ucChannel * 5) = SIF_ERR_NON;
	// [0x401e4] Set IrDA control resister
	*(volatile unsigned char *)(SIF_IRMD0_ADDR + ucChannel * 5) = ucIrDAData;
	// [0x401e3] Set serial control register
	*(volatile unsigned char *)(SIF_SMD0_ADDR + ucChannel * 5) = ucMode;
}

/*******************************************************************************************************
 * vIntUart0TransmitData
 *   Type :	void
 *   Ret val :	none
 *   Argument :	none
 *   Function :	send a string.
 ******************************************************************************************************/
void vIntUart0TransmitData( void )
{
	asm("pushn	%r15");			// save r1,r2...r15
	asm("ld.w	%r9,%psr");		// EI,enable interrupt 
	asm("or 	%r9,0x10");
	asm("ld.w	%psr,%r9");
	
	if( *gucpUart0TransmitString != '\0' )
		// Write to serial transfer data register
		*(volatile unsigned char *)SIF_TXD0_ADDR = *gucpUart0TransmitString++;
	else
		gucUartTransmitFinish0 = FINISHED;

	// [0x40286] Clear interrupt flag
	*(volatile unsigned char *)INT_FS_ADDR |= INT_FSTX0;

	asm("popn	%r15");
	asm("reti");
}

/*******************************************************************************************************
 * vIntUart0ReceiveData
 *   Type :	void
 *   Ret val :	none
 *   Argument :	void 
 *   Function :	serail receive interrupt routine
 ******************************************************************************************************/
void vIntUart0ReceiveData( void )
{	
	asm("pushn	%r15");			// save r1,r2...r15
	asm("ld.w	%r9,%psr");		// EI,enable interrupt 
	asm("or 	%r9,0x10");
	asm("ld.w	%psr,%r9");
	
	gucUart0ReceiveData = *(volatile unsigned char *)SIF_RXD0_ADDR;
	gucUartReceiveFinish0 = FINISHED;
	
	// [0x401e2] clear receive flag if necessary
//	*(volatile unsigned char *)SIF_RDBF0_ADDR = 0;

	// [0x40286] Clear ch.0 receive buffer full interrupt flag
	*(volatile unsigned char *)INT_FS_ADDR |= INT_FSRX0;
	
	asm("popn	%r15");
	asm("reti");
}

/***********************************************************************************************************
 * vIntUart1TransmitData
 *   Type :	void
 *   Ret val :	none
 *   Argument :	none
 *   Function :	send a string.
 **********************************************************************************************************/
void vIntUart1TransmitData( void )
{
	asm("pushn	%r15");			// save r1,r2...r15
	asm("ld.w	%r9,%psr");		// EI,enable interrupt 
	asm("or 	%r9,0x10");
	asm("ld.w	%psr,%r9");
	
	if( *gucpUart1TransmitString != '\0' )
		// Write to serial transfer data register
		*(volatile unsigned char *)SIF_TXD1_ADDR = *gucpUart1TransmitString++;
	else
		gucUartTransmitFinish1 = FINISHED;
	
	// [0x40286] Clear interrupt flag
	*(volatile unsigned char *)INT_FS_ADDR |= INT_FSTX1;
	
	asm("popn	%r15");
	asm("reti");
}

/***********************************************************************************************************
 * vIntUart1ReceiveData
 *   Type :	void
 *   Ret val :	none
 *   Argument :	void 
 *   Function :	serail receive interrupt routine
 **********************************************************************************************************/
void vIntUart1ReceiveData( void )
{	
	asm("pushn	%r15");			// save r1,r2...r15
	asm("ld.w	%r9,%psr");		// EI,enable interrupt 
	asm("or 	%r9,0x10");
	asm("ld.w	%psr,%r9");
	
	gucUart1ReceiveData = *(volatile unsigned char *)SIF_RXD1_ADDR;
	gucUartReceiveFinish1 = FINISHED;
	
	// [0x401e2] clear receive flag if necessary
//	*(volatile unsigned char *)SIF_RDBF1_ADDR = 0;

	// [0x40286] Clear ch.0 receive buffer full interrupt flag
	*(volatile unsigned char *)INT_FS_ADDR |= INT_FSRX1;
	
	asm("popn	%r15");
	asm("reti");
}

/********************************************************************************************************
 * usReadUartData
 *   Type :	unsigned short
 *   Ret val :	read serial data, Data > 256 on receive error
 *   Argument :	unsigned char ucChannel:		Serial channel number
 *   Function :	Read serial data.
 *******************************************************************************************************/
unsigned short usReadUartData( unsigned char ucChannel )
{
	unsigned short usReceiveBufferFullFlag;
	while( 1 ) 
	{
		usReceiveBufferFullFlag = ( unsigned short )(*(volatile unsigned char *)( SIF_RDBF0_ADDR + ucChannel * 5 ));
		
		if( usReceiveBufferFullFlag & 0x01 )   // Check receive data buffer full status
		{	
			break;
		}
		else if( usReceiveBufferFullFlag & 0x1c )   // Set error status
		{	
			usReceiveBufferFullFlag = UARTRECEIVERERROR;
			return usReceiveBufferFullFlag;
		}
	}
	
	return (( unsigned short )(*(volatile unsigned char *)( SIF_RXD0_ADDR + ucChannel * 5 )));
}

/********************************************************************************************************
 * vWriteUartData
 *   Type :	void
 *   Ret val :	none
 *   Argument :	unsigned char ucChannel:		Serial channel number
 *		unsigned char ucTransmitData:		Write serial data
 *   Function :	Write serial data.
 *******************************************************************************************************/
void vWriteUartData( unsigned char ucChannel, unsigned char ucTransmitData )
{
	while( 1 )
		// Check transfer data buffer empty status
		if ((*(volatile unsigned char *)(SIF_RDBF0_ADDR + ucChannel * 5)) & 0x02) 
			break;	
	
	// Write to serial transfer data register	
	*(volatile unsigned char *)(SIF_TXD0_ADDR + ucChannel * 5) = ucTransmitData;

}

⌨️ 快捷键说明

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