From: "Michal Strelec" Newsgroups: comp.os.msdos.djgpp Subject: PmComm and 2 coms Date: Mon, 27 Mar 2000 08:54:18 +0200 Organization: Czech Technical University Lines: 173 Message-ID: <8bn0jc$dq3$1@ns.felk.cvut.cz> NNTP-Posting-Host: cl106161.osu.cz X-Newsreader: Microsoft Outlook Express 4.72.3155.0 X-MimeOLE: Produced By Microsoft MimeOLE V4.72.3155.0 To: djgpp AT delorie DOT com DJ-Gateway: from newsgroup comp.os.msdos.djgpp Reply-To: djgpp AT delorie DOT com Hi, I use DjGpp for about two years and I very appriciate your pmcomm library......I use it very frequently but know I tried to use in 2 com simultanious communication with very large traffic and strange thing start to happened... First I have few proncipal questions: 1. After interrupt (from COM1) ocuare and interrupt routin is called is automaticly other COM1 (or COMs) or every interrupt disabled? 2. When used "disable()" it is compiled in assembler as "cli", does it disable all hardware interrupts? 3. When used "enabled()" when exactly is interrupt enabled? After execution of NEXT intruction or imidiatly after enabled (sli instruction)? My problem folows: My program maintance 2 COMs. I have installed 1 PM timer interrupt, 2 PM communications interrupt routines. Evrything works when communication is just on one port, but when I have connected to my computers two others and is some traffic from each one. The systems crashs. I was completly lost so I put there some printf commands (I know it should be but I was lost). And systems works something like this. When crash ocuare system do this: interrupt from COM2 ocuare and interrupt routin is called BUT know interrupt from COM1 occuare ... before COM2 routine is finished. But it should NEVER do it. Because it is locked. Really don't get it. Helpppppppppppppp meeeeeeeeeeeeeeeeee Mikee ************************************************* I use pmcomm library and folowing code. ----------------------------- 1. I open ports and specify my interrupt routins where execution will be driven after specific interrupt ocuare void Com1Intr(int nEvent); void Com2Intr(int nEvent); void Com3Intr(int nEvent); void Com4Intr(int nEvent); void (*EventHandler[4])(int nEvent)={Com1Intr,Com2Intr,Com3Intr,Com4Intr}; ret=COMPortOpen(pParam->com,pParam->rate,pParam->databit,pParam->parity,pPar am->stpbit,0,EventHandler[pParam->com]); -------------------------------------- 2. I have code for user interrupt routines void Com1Intr(int nEvent) { CommIntr(COM1,nEvent); /* Interrupt routine for chan 1 */ } void Com2Intr(int nEvent) { CommIntr(COM2,nEvent); /* Interrupt routine for chan 2 */ } void Com3Intr(int nEvent) { CommIntr(COM3,nEvent); /* Interrupt routine for chan 2 */ } void Com4Intr(int nEvent) { CommIntr(COM4,nEvent); /* Interrupt routine for chan 3 */ } ---------------------- 3. and have function CommIntr which maintaince all interrupts whitch never should appeares in one time. void CommIntr(char com,int nEvent) { int ret,channel; char c; /* First check out what chennel is it */ for (channel=0;channel<4;channel++) if (COM[channel]==com) break; /* Now variable channel means channel */ switch (nEvent) { case evCOMRx: /* Receive byte interrupt */ COMReadChar(com,&c,NULL); Receive(channel,c); break; case evCOMTx: /* Transmited byte interrupt */ ret = Send(channel); if (ret!=-1) COMWriteChar(com,(unsigned char)ret,NULL); } } ----------------------------------------------------------- 4. functions Receive and Send are for all interrupt the same int Send(char channel) { if ( ! IsReschedFlag(RESCHED_COMs0+channel) ) { if ( SndIndex[channel] < ComLength[channel] ) return (unsigned char)SndBuffer[channel][SndIndex[channel]++]; else SetReschedFlag(RESCHED_COMs0+channel); } /* Enable sending messages */ return -1; } void Receive(char channel, char c) { if ( IsReschedFlag(RESCHED_COMr0+channel) ) return; if ( RecIndex[channel] >= nCOM[channel] ) RecIndex[channel] = nCOM[channel]-1; switch (c) { case DLE: /* Prefix for control chars */ if ( RecBegData[channel] ) RecDLE[channel] = TRUE; break; case ETX: /* End of the message */ if ( RecBegData[channel] ) { RecEndData[channel] = TRUE; RecBuffer[channel][RecIndex[channel]++] = c; } break; case STX: /* Start of the message */ if ( ! RecEndData[channel] && ! RecBegData[channel] ) { RecIndex[channel] = 0; RecAckNack[channel] = FALSE; /* Reset indicator of ACK, NACK */ RecBuffer[channel][RecIndex[channel]++] = c; CheckSum[channel] = 0; RecDLE[channel] = FALSE; RecBegData[channel] = TRUE; RecCheckSum[channel] = TRUE; break; } case ACK: case NAK: if (!RecDLE[channel] && !RecBegData[channel]) { RecIndex[channel] = 0; RecEndData[channel] = TRUE; /* Just finish */ RecAckNack[channel] = TRUE; /* Set indicator of ACK, NACK */ RecBuffer[channel][RecIndex[channel]++] = c; SetReschedFlag(RESCHED_COMr0+channel); break; } /* Not just AKC, NACK continue */ default: if ( RecEndData[channel] && RecBegData[channel] ) { if ( RecDLE[channel] ) c &= 0x7F; if ( CheckSum[channel] != c ) RecCheckSum[channel] = FALSE; /* Bad checksum */ SetReschedFlag(RESCHED_COMr0+channel); RecBegData[channel] = FALSE; RecEndData[channel] = FALSE; } else if ( RecBegData[channel] ) /* Data received in the message */ { RecBuffer[channel][RecIndex[channel]] = c; if ( RecDLE[channel] ) RecBuffer[channel][RecIndex[channel]] &= 0x7F; CheckSum[channel] ^= RecBuffer[channel][RecIndex[channel]++]; } RecDLE[channel] = FALSE; } }