📄 drv_rs232.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 + -