?? scc8530.c
字號:
/************************************************************************/
/* PROJECT : EFTPOS */
/* PROGRAM : SCC8530.C */
/* COMPILER : BORLAND C/C++ 3.1 FOR DOS */
/************************************************************************/
#include ".\header\main.h"
_SCC SCC[4];
byte WR[16], RR[16];
void static __interrupt far SCC_INT(void);
void SCC_write_command(int channel, byte waddr, byte wd);
byte SCC_read_status(int channel, byte raddr);
void SCC_write_data(int channel, byte wd);
byte SCC_read_data(int channel);
void SCC_Initialize(int, word, int, char, int);
void SCC_Putchar(int port, byte tc);
int SCC_Getchar(int port, byte *rc);
void SCC_ClearBuffer(int port);
int SCC_DtrControl(int port, int on_off);
/***********************************************************************/
/* NAME : int_INT0 */
/* FUNCTION : */
/* ARGS : */
/* RETURNS : */
/***********************************************************************/
void static __interrupt far SCC_INT(void)
{
byte status;
OSIntEnter();
status = SCC_read_status(0, RR0);
if (status & 0x01)
{
SCC[0].RxBuffer[SCC[0].head++] = SCC_read_data(0);
if (SCC[0].head >= SCC_BUF_SIZE) SCC[0].head = 0;
WR[0] |= RESET_ERROR;
SCC_write_command(0, WR0, WR[0]);
}
status = SCC_read_status(1, RR0);
if (status & 0x01)
{
SCC[1].RxBuffer[SCC[1].head++] = SCC_read_data(1);
if (SCC[1].head >= SCC_BUF_SIZE) SCC[1].head = 0;
WR[0] |= RESET_ERROR;
SCC_write_command(1, WR0, WR[0]);
}
outpw(INT_EOI, EOITYPE_INT0);
OSIntExit();
}
/***********************************************************************/
/* NAME : SCC_init */
/* FUNCTION : */
/* ARGS : */
/* RETURNS : */
/***********************************************************************/
void SCC_Initialize(int port, word speed, int databit, char parity, int stopbit)
{
unsigned int baud;
if (port)
WR[9] = CHANNEL_RESET_B ;
else
WR[9] = CHANNEL_RESET_A;
SCC_write_command(port, WR9, WR[9]);
switch (stopbit)
{
case 1: WR[4] = _1STOP; break;
case 2: WR[4] = _2STOP; break;
default: WR[4] = _1STOP; break;
}
switch (parity)
{
case 'E': WR[4] |= (PARITY_ENABLE | PARITY_EVEN); break;
case 'O': WR[4] |= (PARITY_ENABLE | PARITY_ODD); break;
default: break;
}
if (port == 0)
WR[4] |= X16_CLOCK;
else
WR[4] |= X1_CLOCK;
SCC_write_command(port, WR4, WR[4]);
WR[1] = SCC_RX_INT;
SCC_write_command(port, WR1, WR[1]);
SCC_write_command(port, WR2, 0x00);
switch (databit)
{
case 5:
WR[3] = RX_ENABLE | RX5;
WR[5] = TX_ENABLE | TX5;
break;
case 6:
WR[3] = RX_ENABLE | RX6;
WR[5] = TX_ENABLE | TX6;
break;
case 7:
WR[3] = RX_ENABLE | RX7;
WR[5] = TX_ENABLE | TX7;
break;
case 8:
WR[3] = RX_ENABLE | RX8;
WR[5] = TX_ENABLE | TX8;
break;
}
SCC_write_command(port, WR3, WR[3]);
SCC_write_command(port, WR5, WR[5]);
SCC_write_command(port, WR6, 0x00);
SCC_write_command(port, WR7, 0x00);
SCC_write_command(port, WR9, VIS);
SCC_write_command(port, WR10, 0x00);
if (port==0)
WR[11] = TRxC_OUTPUT | TRANSMIT_CLOCK | T_BR_GEN | R_BR_GEN;
else
WR[11] = TRANSMIT_CLOCK | T_TRxC | R_RTxC;
SCC_write_command(port, WR11, WR[11]);
switch (speed)
{
case 600:
SCC_write_command(port, WR12, 190);
SCC_write_command(port, WR13, 0);
break;
case 1200:
SCC_write_command(port, WR12, 94);
SCC_write_command(port, WR13, 0);
break;
case 2400:
SCC_write_command(port, WR12, 46);
SCC_write_command(port, WR13, 0);
break;
case 4800:
SCC_write_command(port, WR12, 22);
SCC_write_command(port, WR13, 0);
break;
case 9600:
SCC_write_command(port, WR12, 10);
SCC_write_command(port, WR13, 0);
break;
case 19200:
SCC_write_command(port, WR12, 4);
SCC_write_command(port, WR13, 0);
break;
case 38400:
SCC_write_command(port, WR12, 1);
SCC_write_command(port, WR13, 0);
break;
default :
baud = (unsigned int)(3686400L/(2L*16L*(long)speed)) - 2;
SCC_write_command(port, WR12, (byte)(baud%0x100));
SCC_write_command(port, WR13, (byte)(baud/0x100));
break;
}
if (port == 0)
WR[14] = BR_GEN_ENABLE | BR_GEN_SOURCE | DTR_REQ;
else
WR[14] = DTR_REQ;
SCC_write_command(port, WR14, WR[14]);
//WR[15] = BREAK_IE | TX_UNDERRUN_IE | DCD_IE;
WR[15] = DCD_IE;
SCC_write_command(port, WR15, WR[15]);
WR[0] = RESET_INT | RESET_ERROR | ENABLE_INT_NEXT_RX | RESET_TXINT_PENDING;
SCC_write_command(port, WR0, WR[0]);
WR[9] = (MIE | NV);
SCC_write_command(port, WR9, WR[9]);
/* flush receive buffer */
SCC_read_data(port);
SCC_read_data(port);
SCC_read_data(port);
SCC[port].head = SCC[port].tail = 0;
poke(0x0000, ITYPE_INT0*4, FP_OFF(SCC_INT));
poke(0x0000, ITYPE_INT0*4+2, FP_SEG(SCC_INT));
SCC_ClearBuffer(port);
}
/***********************************************************************/
/* NAME : SCC_write_command */
/* FUNCTION : */
/* ARGS : */
/* RETURNS : */
/***********************************************************************/
void SCC_write_command(int channel, byte waddr, byte wd)
{
switch (channel)
{
case 0:
outp(SCCBASE_AC, waddr);
outp(SCCBASE_AC, wd);
break;
case 1:
outp(SCCBASE_BC, waddr);
outp(SCCBASE_BC, wd);
break;
}
}
/***********************************************************************/
/* NAME : SCC_read_status */
/* FUNCTION : */
/* ARGS : */
/* RETURNS : */
/***********************************************************************/
byte SCC_read_status(int channel, byte raddr)
{
byte rd;
switch (channel)
{
case 0:
outp(SCCBASE_AC, raddr);
rd = inp(SCCBASE_AC);
break;
case 1:
outp(SCCBASE_BC, raddr);
rd = inp(SCCBASE_BC);
break;
}
return rd;
}
/***********************************************************************/
/* NAME : SCC_write_data */
/* FUNCTION : */
/* ARGS : */
/* RETURNS : */
/***********************************************************************/
void SCC_write_data(int channel, byte wd)
{
switch (channel)
{
case 0:
outp(SCCBASE_AD, wd);
break;
case 1:
outp(SCCBASE_BD, wd);
break;
}
}
/***********************************************************************/
/* NAME : SCC_read_data */
/* FUNCTION : */
/* ARGUMENT : */
/* RETURNS : */
/***********************************************************************/
byte SCC_read_data(int channel)
{
byte temp;
switch (channel)
{
case 0:
temp = inp(SCCBASE_AD);
break;
case 1:
temp = inp(SCCBASE_BD);
break;
}
return temp;
}
/***********************************************************************/
/* NAME : SCC_Putchar */
/* FUNCTION : */
/* ARGS : */
/* RETURNS : */
/***********************************************************************/
void SCC_Putchar(int port, byte tc)
{
byte temp;
TxTimer = 2;
TxTimeOutFlag = 0;
while (TRUE)
{
temp = SCC_read_status(port, RR0);
if (temp & TXB_EMPTY)
{
SCC_write_data(port, tc);
return ;
}
if (TxTimeOutFlag)
{
SCC_write_data(port, tc);
return ;
}
}
}
/***********************************************************************/
/* NAME : SCC_Getchar */
/* FUNCTION : */
/* ARGS : */
/* RETURNS : */
/***********************************************************************/
int SCC_Getchar(int port, byte *rc)
{
if (SCC[port].head != SCC[port].tail)
{
*rc = SCC[port].RxBuffer[SCC[port].tail++];
if (SCC[port].tail >= SCC_BUF_SIZE)
SCC[port].tail = 0;
return TRUE;
}
return FALSE;
}
/***********************************************************************/
/* NAME : SCC_Dtr */
/* FUNCTION : */
/* ARGS : */
/* RETURNS : */
/***********************************************************************/
int SCC_DtrControl(int port, int on_off)
{
if (port >= 2)
return FALSE;
if (on_off)
{
WR[5] |= SCC_DTR;
SCC_write_command(port, WR5, WR[5]);
}
else
{
WR[5] &= ~SCC_DTR;
SCC_write_command(port, WR5, WR[5]);
}
return TRUE;
}
/***********************************************************************/
/* NAME : SCC_clear_buffer */
/* FUNCTION : 烹腳 buffer甫 檬扁拳 */
/* ARGS : */
/* RETURNS : NONE */
/***********************************************************************/
void SCC_ClearBuffer(int port)
{
SCC[port].head = SCC[port].tail = 0;
memset(SCC[port].RxBuffer, 0x00, SCC_BUF_SIZE);
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -