X-Authentication-Warning: delorie.com: mail set sender to djgpp-bounces using -f From: =?ISO-2022-JP?B?GyRCPi44UUBnGyhC?= 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: NNTP-Posting-Host: 58.38.3.10 Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit 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 #include #include #include #include #include #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; }