Mail Archives: djgpp/2000/03/27/02:21:39
From: | "Michal Strelec" <strelec AT abik DOT osu DOT cz>
|
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;
}
}
- Raw text -