📄 serial.cpp
字号:
#define SERIAL_GLOBALS
#include "includes.h"
/* Handle communications interrupts and put them in serialbuf */
void interrupt com1_int(...)
{
unsigned char temp;
disable();
temp =inportb(COM1BASE + IIR) ;
//接收
if ((temp& RX_ID)== RX_ID)
{
com1recvbufend->data =inportb(COM1BASE + RXR);
com1recvbufend=com1recvbufend->next;
}
//发送
else if ((temp&TX_ID)== TX_ID)
{
if(com1sendbufend !=com1sendbufstart)
{
outportb(COM1BASE +TXR ,com1sendbufstart->data);
com1sendbufstart =com1sendbufstart->next;
}
}
// Signal end of hardware interrupt
outportb(ICR8259A, EOI);
enable();
}
/* Handle communications interrupts and put them in serialbuf */
void interrupt com2_int(...)
{
unsigned char temp;
disable();
temp =inportb(COM2BASE + IIR) ;
//接收
if ((temp& RX_ID)== RX_ID)
{
com2recvbufend->data =inportb(COM2BASE + RXR);
com2recvbufend=com2recvbufend->next;
}
//发送
else if ((temp&TX_ID)== TX_ID)
{
if(com2sendbufend !=com2sendbufstart)
{
outportb(COM2BASE +TXR ,com2sendbufstart->data);
com2sendbufstart =com2sendbufstart->next;
}
}
// Signal end of hardware interrupt
outportb(ICR8259A, EOI);
enable();
}
//Handle communications interrupts and put them in serialbuf
void interrupt com3_int(...)
{
unsigned char temp;
disable();
temp =inportb(COM3BASE + IIR) ;
//接收
if ((temp& RX_ID)== RX_ID)
{
com3recvbufend->data =inportb(COM3BASE + RXR);
com3recvbufend=com3recvbufend->next;
}
//发送
else if ((temp&TX_ID)== TX_ID)
{
if(com3sendbufend !=com3sendbufstart)
{
outportb(COM3BASE +TXR ,com3sendbufstart->data);
com3sendbufstart =com3sendbufstart->next;
}
}
// Signal end of hardware interrupt
outportb(ICR8259A, EOI);
enable();
}
// Handle communications interrupts and put them in serialbuf
void interrupt com4_int(...)
{
unsigned char temp;
disable();
temp =inportb(COM4BASE + IIR) ;
//接收
if ((temp& RX_ID)== RX_ID)
{
com4recvbufend->data =inportb(COM4BASE + RXR);
com4recvbufend=com4recvbufend->next;
}
//发送
else if ((temp&TX_ID)== TX_ID)
{
if(com4sendbufend !=com4sendbufstart)
{
outportb(COM4BASE +TXR ,com4sendbufstart->data);
com4sendbufstart =com4sendbufstart->next;
}
}
// Signal end of hardware interrupt
outportb(ICR8259A, EOI);
enable();
}
int GetBaseAddr(int Port )
{
int baseaddr;
if (Port ==1)
{
baseaddr =COM1BASE;
}
else if (Port ==2)
{
baseaddr =COM2BASE;
}
else if (Port ==3)
{
baseaddr =COM3BASE;
}
else if (Port ==4)
{
baseaddr =COM4BASE;
}
return baseaddr;
}
/* This routine sets the speed; will accept funny baud rates. */
/* Setting the speed requires that the DLAB be set on. */
void SetSpeed(int Port,long int Speed)
{
char temp;
int divisor;
int baseaddr;
baseaddr =GetBaseAddr(Port);
divisor = (int) (115200/Speed);
disable();
temp= inportb(baseaddr + LCR);
outportb(baseaddr + LCR, (temp| 0x80)); //Set DLAB
outportb(baseaddr + DLL, (divisor & 0x00FF));
outportb(baseaddr + DLH, ((divisor >> 8) & 0x00FF));
outportb(baseaddr + LCR, temp); // Reset DLAB
enable();
}
/* Set other communications parameters */
void SetOthers(int Port,int Parity, int Bits, int StopBit)
{
int setting;
setting = Bits-5;
setting |= ((StopBit == 1) ? 0x00 : 0x04);
setting |= Parity;
disable();
outportb(GetBaseAddr(Port) + LCR, setting);
enable();
}
/* Turn off communications interrupts */
void DisableI(int Port)
{
int temp;
int baseaddr;
baseaddr =GetBaseAddr(Port);
disable();
temp= inportb(IMR8259A) | ~IRQ3 | ~IRQ4;
outportb(IMR8259A, temp);
outportb(baseaddr + IER, 0);
temp = inportb(baseaddr + MCR) & ~MC_INT;
outportb(baseaddr + MCR, temp);
enable();
}
/* Turn on communications interrupts */
void EnableI(int Port)
{
int temp,temp1;
int baseaddr;
baseaddr =GetBaseAddr(Port);
disable();
temp= inportb(baseaddr + MCR) | MC_INT;
outportb(baseaddr + MCR, temp);
outportb(baseaddr + IER, RX_INT|TX_INT);
if(Port == COM1)
{
temp1 =IRQ4;
}
else if(Port == COM2)
{
temp1 =IRQ3;
}
else if(Port == COM3)
{
temp1 =IRQ5;
}
else if(Port == COM4)
{
temp1 =IRQ6;
}
temp = inportb(IMR8259A) & temp1;
outportb(IMR8259A, temp);
enable();
}
/* Install our functions to handle communications */
void SetVects(int Port) //设置中断向量
{
switch(Port)
{
case COM1:
{
comoldvects[0] = getvect(0x0C);
setvect(0x0C, com1_int);
break;
}
case COM2:
{
comoldvects[1] = getvect(0x0B);
setvect(0x0B, com2_int);
break;
}
case COM3:
{
comoldvects[2] = getvect(0x0D);
setvect(0x0D, com3_int);
break;
}
case COM4:
{
comoldvects[3] = getvect(0x0E);
setvect(0x0E, com4_int);
break;
}
default:
break;
}
}
/* Uninstall our vectors before exiting the program */
void ResVects(int Port)//恢复原有的中断向量
{
switch(Port)
{
case COM1:
{
setvect(0x0C, comoldvects[0]);
break;
}
case COM2:
{
setvect(0x0B, comoldvects[1]);
break;
}
case COM3:
{
setvect(0x0D, comoldvects[2]);
break;
}
case COM4:
{
setvect(0x0E, comoldvects[3]);
break;
}
default:
break;
}
}
/* Go off-line */
void CommOff(int Port)
{
DisableI(Port);
outportb(GetBaseAddr(Port)+ MCR, 0);
}
/* Tell modem that we're ready to go */
void CommOn(int Port)
{
int temp, pnum;
int baseaddr;
if(Port <=4)
{
EnableI(Port);
}
baseaddr =GetBaseAddr(Port) ;
temp = inportb(baseaddr+ MCR) | DTR | RTS;
outportb(baseaddr + MCR, temp);
}
void CloseSerial(int Port)
{
CommOff(Port);
ResVects(Port);
}
void OpenSerial(int Port)
{
SetVects(Port);
CommOn(Port);
}
int InitSerial(int Port, long int Speed, int Parity, int Bits, int StopBit)
{
if((Port ==0)||(Port >4))
{
return PORTERROR;
}
if ((Speed == 0)||(Speed >115200)) /* Avoid divide by zero */
{
return SPEEDERROR;
}
if (Bits < 5 || Bits > 8)
{
return BITSERROR;
}
if((StopBit != 1) && (StopBit != 2))
{
return STOPBITERROR;
}
if (Parity != NO_PARITY && Parity != ODD_PARITY && Parity != EVEN_PARITY)
{
return PARITYERROR;
}
//COM3COM4需要设置IRQ
if((Port ==3)||(Port ==4))
{
outportb(COM34IRQADDR, COM34IRQ);//COM3=IRQ5,COM4=IRQ6
}
SetSpeed(Port,Speed);
SetOthers(Port,Parity, Bits, StopBit);
OpenSerial(Port);
return OK;
}
void InitComBuf(void)
{
int i;
//com1
for (i=0;i<COMBUFSIZE;i++)
{
com1sendbuf[i].next =&com1sendbuf[i+1];
com1recvbuf[i].next =&com1recvbuf[i+1];
}
com1sendbuf[COMBUFSIZE-1].next =com1sendbuf;
com1recvbuf[COMBUFSIZE-1].next =com1recvbuf;
com1sendbufstart =com1sendbuf;
com1sendbufend = com1sendbuf;
com1recvbufstart =com1recvbuf;
com1recvbufend = com1recvbuf;
//com2
for (i=0;i<COMBUFSIZE;i++)
{
com2sendbuf[i].next =&com2sendbuf[i+1];
com2recvbuf[i].next =&com2recvbuf[i+1];
}
com2sendbuf[COMBUFSIZE-1].next =com2sendbuf;
com2recvbuf[COMBUFSIZE-1].next =com2recvbuf;
com2sendbufstart =com2sendbuf;
com2sendbufend = com2sendbuf;
com2recvbufstart =com2recvbuf;
com2recvbufend = com2recvbuf;
//com3
for (i=0;i<COMBUFSIZE;i++)
{
com3sendbuf[i].next =&com3sendbuf[i+1];
com3recvbuf[i].next =&com3recvbuf[i+1];
}
com3sendbuf[COMBUFSIZE-1].next =com3sendbuf;
com3recvbuf[COMBUFSIZE-1].next =com3recvbuf;
com3sendbufstart =com3sendbuf;
com3sendbufend = com3sendbuf;
com3recvbufstart =com3recvbuf;
com3recvbufend = com3recvbuf;
//com4
for (i=0;i<COMBUFSIZE;i++)
{
com4sendbuf[i].next =&com4sendbuf[i+1];
com4recvbuf[i].next =&com4recvbuf[i+1];
}
com4sendbuf[COMBUFSIZE-1].next =com4sendbuf;
com4recvbuf[COMBUFSIZE-1].next =com4recvbuf;
com4sendbufstart =com4sendbuf;
com4sendbufend = com4sendbuf;
com4recvbufstart =com4recvbuf;
com4recvbufend = com4recvbuf;
}
void DisableSendInt( int baseaddr)
{
char temp;
temp = inportb(baseaddr + IER);
temp &=~TX_INT;
outportb(baseaddr + IER, temp);
}
void EnableSendInt(int baseaddr)
{
char temp;
temp = inportb(baseaddr + IER);
temp |=TX_INT;
outportb(baseaddr + IER, temp);
}
void ComSend(int Port,char *temp)
{
unsigned char temp2=0;
if(Port ==1)
{
if (com1sendbufend == com1sendbufstart) //发送缓冲为空时需要激活发送
{
temp2 =1;
}
else
{
temp2 =0;
}
DisableSendInt(COM1BASE);
while(*temp)
{
com1sendbufend->data =*temp;
com1sendbufend = com1sendbufend->next;
temp ++;
}
if(temp2)
{
outportb(COM1BASE +TXR ,com1sendbufstart->data);
com1sendbufstart =com1sendbufstart->next;
}
EnableSendInt(COM1BASE);
}
else if(Port ==2)
{
if (com2sendbufend == com2sendbufstart) //发送缓冲为空时需要激活发送
{
temp2 =1;
}
else
{
temp2 =0;
}
DisableSendInt(COM2BASE);
while(*temp)
{
com2sendbufend->data =*temp;
com2sendbufend = com2sendbufend->next;
temp ++;
}
if(temp2)
{
outportb(COM2BASE +TXR ,com2sendbufstart->data);
com2sendbufstart =com2sendbufstart->next;
}
EnableSendInt(COM2BASE);
}
else if(Port ==3)
{
if (com3sendbufend == com3sendbufstart) //发送缓冲为空时需要激活发送
{
temp2 =1;
}
else
{
temp2 =0;
}
DisableSendInt(COM3BASE);
while(*temp)
{
com3sendbufend->data =*temp;
com3sendbufend = com3sendbufend->next;
temp ++;
}
if(temp2)
{
outportb(COM3BASE +TXR ,com3sendbufstart->data);
com3sendbufstart =com3sendbufstart->next;
}
EnableSendInt(COM3BASE);
}
else if(Port ==4)
{
if (com4sendbufend == com4sendbufstart) //发送缓冲为空时需要激活发送
{
temp2 =1;
}
else
{
temp2 =0;
}
DisableSendInt(COM4BASE);
while(*temp)
{
com4sendbufend->data =*temp;
com4sendbufend = com4sendbufend->next;
temp ++;
}
if(temp2)
{
outportb(COM4BASE +TXR ,com4sendbufstart->data);
com4sendbufstart =com4sendbufstart->next;
}
EnableSendInt(COM4BASE);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -