Mail Archives: djgpp/2009/05/14/08:45:44
X-Authentication-Warning: | delorie.com: mail set sender to djgpp-bounces using -f
|
From: | =?ISO-2022-JP?B?GyRCPi44UUBnGyhC?= <foxapple AT gmail DOT com>
|
Newsgroups: | comp.os.msdos.djgpp
|
Subject: | An interrupt drived uart program dead
|
Date: | Thu, 14 May 2009 05:34:46 -0700 (PDT)
|
Organization: | http://groups.google.com
|
Lines: | 178
|
Message-ID: | <dcff139d-32b8-4f22-ab4a-6f7e78f81324@c18g2000prh.googlegroups.com>
|
NNTP-Posting-Host: | 58.38.3.10
|
Mime-Version: | 1.0
|
X-Trace: | posting.google.com 1242304487 31211 127.0.0.1 (14 May 2009 12:34:47 GMT)
|
X-Complaints-To: | groups-abuse AT google DOT com
|
NNTP-Posting-Date: | Thu, 14 May 2009 12:34:47 +0000 (UTC)
|
Complaints-To: | groups-abuse AT google DOT com
|
Injection-Info: | c18g2000prh.googlegroups.com; posting-host=58.38.3.10;
|
| posting-account=qc6pEAoAAACyFixjIDHUvf8HsKSt31ce
|
User-Agent: | G2/1.0
|
X-HTTP-UserAgent: | Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR
|
| 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022;
|
| InfoPath.2; aff-kingsoft-ciba; TheWorld),gzip(gfe),gzip(gfe)
|
To: | djgpp AT delorie DOT com
|
DJ-Gateway: | from newsgroup comp.os.msdos.djgpp
|
Reply-To: | djgpp AT delorie DOT com
|
I wrote a program under djgpp to drive PC UART. the program is
interrupt-drived. When run the program, the data has sent, but then
the PC halt. I can't find any bug in the program. So ask for help.
below is the program code.
#include <dos.h>
#include <stdio.h>
#include <stddef.h>
#include <pc.h>
#include <dpmi.h>
#include <go32.h>
#define LOCK_VARIABLE(x) _go32_dpmi_lock_data((void *)&x,(long)
sizeof(x));
#define LOCK_FUNCTION(x) _go32_dpmi_lock_code(x,(long)sizeof(x));
typedef unsigned char byte;
typedef unsigned short uint16_t;
enum RegisterOffset
{
OFFSET_RBR = 0,
OFFSET_THR = 0,
OFFSET_IER = 1,
OFFSET_IIR = 2,
OFFSET_FCR = 2,
OFFSET_LCR = 3,
OFFSET_MCR = 4,
OFFSET_LSR = 5,
OFFSET_MSR = 6,
OFFSET_SCR = 7,
OFFSET_DLL = 0,
OFFSET_DLM = 1
};
enum RegisterConst
{
LCR_BREAKOFF = 0, LCR_BREAKON = 0x40, LCR_DLABOFF = 0, LCR_DLABON =
0x80,
FCR_CLEARENB = 0x1, FCR_RCLEAR = 0x2, FCR_XCLEAR = 0x4, FCR_MODE =
0x8,
FCR_LEVEL1 = 0x0, FCR_LEVEL4 = 0x40, FCR_LEVEL8 = 0x80, FCR_LEVEL13
= 0xc0,
MCR_ACTDTR = 0x1, MCR_ACTRTS = 0x2, MCR_OUT1 = 0x4, MCR_OUT2 = 0x8,
MCR_LOOPBACK = 0x10,
IER_ERBFI = 0x1, IER_ETBEI = 0x2, IER_ELSI = 0x4, IER_EDSSI = 0x8,
IER_DISALL = 0, IER_ENBALL = 0x0f,
LSR_DR = 0x1, LSR_OE = 0x2, LSR_PE = 0x4, LSR_FE=0x8, LSR_BI=0x10,
LSR_THRE=0x20, LSR_TEMT=0x40, LSR_TIMEOUT=0x80,
MSR_DCTS=0x1, MSR_DDSR=0x2, MSR_TERI=0x4, MSR_DDCD=0x8,
MSR_CTS=0x10, MSR_DSR=0x20, MSR_RI=0x40, MSR_DCD=0x80,
IIR_NOINT = 0x1, IIR_IMSC = 0x0, IIR_ITBE = 0x2, IIR_IRBF = 0x4,
IIR_ILS = 0x6, IIR_TIMEOUT = 0x8, IIR_IMASK = 0x0e
};
const unsigned int baseAddress = 0x3f8;
const byte commIrq = 0x04;
const byte commIntr = 0x0c;
bool txIdle = true;
_go32_dpmi_seginfo OldISR, NewISR;
byte oldIMR;
void commISR();
int initComm()
{
const byte wordSize = 0x03; // 8-bit
const byte stopBits = 0x00; // 1-stop bit
const byte parity = 0x00; // none
byte lcrSet = LCR_DLABON;
outportb(baseAddress + OFFSET_LCR, lcrSet);
uint16_t baudWord = 1843200 / (115200 * 16);
outportb(baseAddress + OFFSET_DLL, baudWord & 0xff); // set
low byte of baud rate word.
outportb(baseAddress + OFFSET_DLM, (baudWord >> 8) & 0xff); // set
high byte of baud rate word.
lcrSet = wordSize + stopBits + parity;
outportb(baseAddress + OFFSET_LCR, lcrSet); // set
LCR to specified config.
// disable FIFO
outportb(baseAddress + OFFSET_FCR, 0);
outportb(baseAddress + OFFSET_SCR, 0);
outportb(baseAddress + OFFSET_MCR, MCR_ACTDTR+MCR_ACTRTS
+MCR_OUT1+MCR_OUT2); // enable COM output gate.
// clear the status.
inportb(baseAddress + OFFSET_RBR);
inportb(baseAddress + OFFSET_LSR);
inportb(baseAddress + OFFSET_MSR);
inportb(baseAddress + OFFSET_IIR);
txIdle = true;
_go32_dpmi_get_protected_mode_interrupt_vector(commIntr, &OldISR);
NewISR.pm_offset = (int)commISR;
NewISR.pm_selector = _go32_my_cs();
_go32_dpmi_allocate_iret_wrapper(&NewISR);
_go32_dpmi_set_protected_mode_interrupt_vector(commIntr, &NewISR);
oldIMR = inportb(0x21);
byte newIMR = oldIMR & (~(0x01 << 4));
outportb(0x21, newIMR);
}
void restoreComm()
{
_go32_dpmi_set_protected_mode_interrupt_vector(commIntr, &OldISR);
_go32_dpmi_free_iret_wrapper(&NewISR);
outportb(0x21, oldIMR);
}
#define QUEUE_CAPABILITY 16
byte writeQueue[QUEUE_CAPABILITY];
uint16_t queueHead = 0, queueTail = 0;
uint16_t queueSize = 0;
int asyWriteComm()
{
for(int count = 0; count < QUEUE_CAPABILITY; count ++)
{
writeQueue[queueTail] = 'a' + count;
queueTail = (queueTail + 1) % QUEUE_CAPABILITY;
queueSize ++;
}
byte data = writeQueue[queueHead];
queueHead = (queueHead + 1) % QUEUE_CAPABILITY;
queueSize --;
outportb(baseAddress + OFFSET_THR, data);
txIdle = false;
do {
} while(queueSize != 0);
}
void commISR()
{
byte iir = inportb(baseAddress + OFFSET_IIR);
if ((iir & 0x02) != 0)
{
byte lsr;
do {
if (queueSize > 0)
{
byte data = writeQueue[queueHead];
queueHead = (queueHead + 1) % QUEUE_CAPABILITY;
queueSize --;
outportb(baseAddress + OFFSET_THR, data);
txIdle = false;
}
else
{
txIdle = true;
}
lsr = inportb(baseAddress + OFFSET_LSR);
} while((lsr & (LSR_THRE | LSR_TEMT)) != 0);
}
outportb(0x20, 0x20);
}
int main()
{
initComm();
asyWriteComm();
restoreComm();
return 0;
}
- Raw text -