/* UART7.C demo program dor write user own ISR for COM1/COM2 */ #include #include #include"uart7.h" #include"..\lib\7188.h" #ifndef __TURBOC__ /* for MSC */ #define enable() _enable() #define disable() _disable() #else #include #define outpw outport #define inpw inport #endif #define INT_MASK 0xff28 /* Interrupt mask register */ #define INT_EOI 0xff22 /* End-of-interrupt register */ #define EOITYPE_INT0 0x0c /* for COM1 */ #define EOITYPE_INT1 0x0d /* for COM2 */ #define InBufSize 1024 #define OutBufSize 128 int iBase1=0x200; /* com1 base address */ /*int iBase2=0x100; */ /* com2 base address */ int _err1=0; static unsigned long OldIntVect1=0L; static unsigned char InData1[InBufSize]; static unsigned char OutData1[OutBufSize]; int In_InIdx1,In_OutIdx1,Out_InIdx1,Out_OutIdx1; int save232[4]; static unsigned long far *IntVect=(unsigned long far *)0L; static void interrupt Serial1_Isr(void) { do{ switch(inp(iBase1+Iir)&0x07){ case 0: /* inp(iBase1+Msr); */ break; case 1: /* No interrupt to be service */ goto end; case 2: /* can send data */ if(Out_InIdx1!=Out_OutIdx1){ outp(iBase1,OutData1[Out_OutIdx1++]); Out_OutIdx1&=OutBufSize-1; if(Out_OutIdx1==Out_InIdx1) outp(iBase1+Ier, 0x01); } else { outp(iBase1+Ier, 0x01); } break; case 4: /* receive data */ ReadAgain: InData1[In_InIdx1++]=inp(iBase1); /* receive next char */ In_InIdx1&=(InBufSize-1); if(In_InIdx1==In_OutIdx1) { In_InIdx1--; In_InIdx1&=(InBufSize-1); _err1=1; } if(inp(iBase1+Lsr) & 1) goto ReadAgain; break; case 6: inp(iBase1+Lsr); break; default: /* error status */ goto end; } }while(1); end: outp(INT_EOI,EOITYPE_INT0); /* send EOI to 7188's INT-0 */ /* if COM2 use outp(INT_EOI,EOITYPE_INT1); */ } static unsigned char ratehi,ratelo,format; int GetBaudData(unsigned long baud, int data, int parity, int stop) { int cc; format=0; switch(data) { case 5: break; /* format+=0; */ case 6: format+=1; break; case 7: format+=2; break; case 8: format+=3; break; default: return(DataError); } switch(parity) { case 0: break; /* format+=0; No Parity*/ case 1: format+=0x18; break; /* Even parity */ case 2: format+=0x08; break; /* Odd parity */ case 3: format+=0x28; break; /* Mark parity */ case 4: format+=0x38; break; /* Space parity */ default: return(ParityError); } switch(stop) { case 1: break; /* format+=0; */ case 2: format+=4; break; default: return(StopError); } switch(baud){ case 1200L : ratehi=0; ratelo=96; break; case 2400L : ratehi=0; ratelo=48; break; case 4800L : ratehi=0; ratelo=24; break; case 9600L : ratehi=0; ratelo=12; break; case 19200L: ratehi=0; ratelo=6; break; case 38400L: ratehi=0; ratelo=3; break; case 57600L: ratehi=0; ratelo=2; break; case 115200L: ratehi=0; ratelo=1; break; default : return BaudRateError; /* baud rate error */ } return NoError; } /* baud:1200,2400,4800,9600,19200,38400,57600,115200 parity: 0-> None,1->Even,2->Odd,3->Mark,4->Space data:5,6,7,8 stop:1,2 if use COM2 change iBase1 to iBase2 */ int _InstallCom1(unsigned long baud, int data, int parity, int stop) { int cc; if(OldIntVect1) _RestoreCom1(); _err1=0; cc=GetBaudData(baud,data,parity,stop); if(cc) return cc; /* _asm cli */ disable(); save232[2]=inp(iBase1+Lcr); /* format */ outp(iBase1+Lcr,0x80); /* 1 set DLAB (baud rate) */ save232[0]=inp(iBase1+Dll); /* baud rate */ save232[1]=inp(iBase1+Dlh); outp(iBase1+Dll,ratelo); outp(iBase1+Dlh,ratehi); outp(iBase1+Lcr,format); /* 2. data format */ save232[3]=inp(iBase1+Ier); /* interrupt status*/ outp(iBase1+Fcr, 0x81); /* 3. enable & clear FIFO */ outp(iBase1+Ier, 0x01); /* 4. enable COM1 interrupt */ outp(iBase1+Mcr,0x0b); /* set DTR line active */ In_InIdx1=In_OutIdx1=Out_InIdx1=Out_OutIdx1=0; /* 5. init QUEUE */ OldIntVect1=IntVect[0x0c]; /* save old ISR */ /* if use COM2 -->IntVect[0x0d] */ IntVect[0x0c]=(unsigned long)Serial1_Isr; /* install new ISR */ outpw(INT_MASK,inpw(INT_MASK)&0xffef);/* 6. enable INT-0 of 7188 interrupt */ /* if use COM2 -->outpw(INT_MASK,inpw(INT_MASK)&0xffdf); */ Set485DirToReceive(1); /* 7. 485 initial in receive direction */ /*_asm sti */ enable(); return(NoError); } int _RestoreCom1(void) { if(!OldIntVect1) return NoError; /* _asm cli */ disable(); IntVect[0x0c]=OldIntVect1; /* 1. restore OLD ISR */ /* if use COM2 -->IntVect[0x0d] */ OldIntVect1=0L; outp(iBase1+Lcr,0x80); /* 2. restore baud rate */ outp(iBase1+Dll,save232[0]); outp(iBase1+Dlh,save232[1]); outp(iBase1+Lcr,(save232[2])&0x7f); /* 3. restore data format */ outp(iBase1+Ier, save232[3]);/* 4. restore enable COM1's interrupt */ outpw(INT_MASK,inpw(INT_MASK)|0x0010);/* 6. disable INT-0 of 7188 interrupt */ /* if use COM2 -->outpw(INT_MASK,inpw(INT_MASK)|0x0020); */ /* outp(0x21,inp(0x21) | 0x10); */ /* mask IRQ 4 for COM1 */ /* _asm sti */ enable(); return NoError; } int _IsCom1(void) { return In_InIdx1-In_OutIdx1; } long ToComTimeOut=100000L; int _ToCom1(char data) { long t=ToComTimeOut; int nextidx,done; do{ /* _asm cli */ disable(); done=(nextidx=(Out_InIdx1+1)&(OutBufSize-1)) != Out_OutIdx1; if(done){ OutData1[Out_InIdx1]=data; Out_InIdx1=nextidx; } /* _asm sti */ enable(); t--; if(!t) break; } while(!done); if(done){ outp(iBase1+Lcr,inp(iBase1+Lcr)&0x7f); outp(iBase1+Ier, 0x03); /* enable COM1 interrupt */ return NoError; } else return TimeOut; } int _ReadCom1(void) { unsigned data; while(!_IsCom1()){ ; } data=InData1[In_OutIdx1++]; In_OutIdx1&=(InBufSize-1); return data; } int _ClearCom1(void) { In_OutIdx1=In_InIdx1=0; return NoError; } void _ToCom1Str(char *str) { while(*str) _ToCom1(*str++); } void SetDtrHigh(void) { outp(iBase1+Mcr,inp(iBase1+Mcr)|1); } void SetDtrLow(void) { outp(iBase1+Mcr,inp(iBase1+Mcr)&~1); } void SetRtsHigh(void) { outp(iBase1+Mcr,inp(iBase1+Mcr)|2); } void SetRtsLow(void) { outp(iBase1+Mcr,inp(iBase1+Mcr)&~2); } /* void CheckModemStatus(void) { static int msts=0; int newmsts=inp(iBase1+Msr); if(newmsts!=msts){ printf("DCTS="); if(newmsts&1) putchar('1'); else putchar('0'); printf(" DDSR="); if(newmsts&2) putchar('1'); else putchar('0'); printf(" TERI="); if(newmsts&4) putchar('1'); else putchar('0'); printf(" DDCD="); if(newmsts&8) putchar('1'); else putchar('0'); printf(" CTS="); if(newmsts&16) putchar('1'); else putchar('0'); printf(" DSR="); if(newmsts&32) putchar('1'); else putchar('0'); printf(" RI="); if(newmsts&64) putchar('1'); else putchar('0'); printf(" DCD="); if(newmsts&128) putchar('1'); else putchar('0'); puts("\n"); msts=newmsts; } } */