📄 serial.c
字号:
in_msg_length = 0; in_byte_count = 0; /* initialize parallel port */ if (lpt_initialize) return (init_parport(tip_config.par_port)); return((INT32) 0); } /* end init_comm_serial() *//*** This function is used to send bytes over the serial line.** If the bytes are successfully sent, a zero is returned. ** If the bytes are not sent, a -1 is returned.*/INT32send_bfr_serial(bfr_ptr, length, port_base, comm_err) BYTE *bfr_ptr; INT32 length; INT32 port_base; INT32 *comm_err; { int retries; INT32 byte_count = 0; unsigned int comm_status; unsigned int result; /* Send message */ retries = 0; do { /* check user interrupt */ SIGINT_POLL /* Check if data ready */ comm_status = inp(serial_io.port+LSR_OFFSET); /* Check for communication errors */ if ((comm_status & (FE | PE | OE)) != 0) { *comm_err = 1; return (-1); } /* If Transmitter Holding Register Empty (THRE) */ /* send out data */ if ((comm_status & THRE) != 0) { result = outp(serial_io.port, bfr_ptr[byte_count]); byte_count = byte_count + 1; retries = 0; } else { retries = retries + 1; if (retries >= 20000) return (-1); /* EMNOSEND); */ } } while (byte_count < length ); return(0); } /* end send_bfr_serial() *//*** This function is used to receive bytes over a serial line.**** If block equals NONBLOCK then the function returns as soon** there are no bytes remaining in the UART. ** If block equals BLOCK then the function waits until all** bytes are gotten before returning.** ** If all bytes requested are gotten, 0 is returned, else -1.*/INT32recv_bfr_serial(bfr_ptr, length, block, port_base, comm_err) BYTE *bfr_ptr; INT32 length; INT32 block; INT32 port_base; INT32 *comm_err; { int comm_status; int c; int result; int bytes_free; int block_count = 0; /* Loop as long as characters keep coming */ for (;;) { /* Check for communication errors */ comm_status = inp(serial_io.port+LSR_OFFSET); if ((comm_status & (FE | PE | OE)) != 0) { *comm_err = 1; return (-1); } /* Check for buffer overflow */ if (serial_io.error == TRUE) { *comm_err = 1; return (-1); } /* Do flow control. If the buffer is 9/10 full, */ /* deassert DTR and RTS. If the buffer becomes */ /* 1/10 full, reassert DTR and RTS. */ bytes_free = (int) (serial_io.start - serial_io.end); if (bytes_free <= 0) bytes_free = BUF_SIZE + bytes_free; comm_status = inp(serial_io.port+MCR_OFFSET); if (bytes_free <= (BUF_SIZE/10)) result = outp((serial_io.port+MCR_OFFSET), (comm_status & ~DTR & ~RTS)); if (bytes_free >= ((9*BUF_SIZE)/10)) result = outp((serial_io.port+MCR_OFFSET), (comm_status | DTR | RTS)); /* Get character */ c = get_byte_serial(); /* return if no char & not blocking */ if ((c == -1) && (block == NONBLOCK)) return (-1); /* return if no char, blocking, and past block count */ if ((c == -1) && (block == BLOCK) && (block_count++ > BlockCount)) return (-1); /* Save byte in bfr_ptr buffer */ if (c != -1) { bfr_ptr[in_byte_count] = (BYTE) c; block_count = 0; in_byte_count = in_byte_count + 1; } /* Message received ? */ if (in_byte_count == length) { in_byte_count = 0; return(0); } } /* end for(;;) */ } /* end recv_bfr_serial() *//*** This function is used to reset the communication** channel. This is used when resyncing the host and** target and when exiting the monitor.*/INT32reset_comm_serial(ignore1, ignore2)INT32 ignore1;INT32 ignore2; { unsigned int status;#define CLEAR_STAT (int) 1 do { /* Clear LSR */ inp(serial_io.port+LSR_OFFSET); /* Clear RX reg */ inp (serial_io.port); /* Clear MSR */ inp (serial_io.port+MSR_OFFSET); /* interrupt pending ? */ status = inp(serial_io.port+IID_OFFSET); } while (status != CLEAR_STAT);#if 0 /* reset any communication errors */ outp(serial_io.port+LSR_OFFSET, (unsigned int) (comm_status & ~(FE|PE|OE)));#endif /* Initialize serial_io */ serial_io.error = FALSE; /* Initialize ring buffer */ serial_io.start = serial_io_buffer; serial_io.end = serial_io_buffer; /* Set global message indices */ in_msg_length = 0; in_byte_count = 0; return((INT32) 0); } /* end reset_comm_serial() */INT32exit_comm_serial(ignore1, ignore2)INT32 ignore1;INT32 ignore2; { /* Initialize serial_io */ serial_io.error = FALSE; /* Initialize ring buffer */ serial_io.start = serial_io_buffer; serial_io.end = serial_io_buffer; /* Set global message indices */ in_msg_length = 0; in_byte_count = 0; /* install old handler back */ _dos_setvect(serial_io.int_number, OldVector); return((INT32) 0); } /* end reset_comm_serial() *//*** This function is usually used to "kick-start" the target.** This is nesessary when targets are shared memory boards.** With serial communications, this function does nothing.*/voidgo_serial(ignore1, ignore2)INT32 ignore1;INT32 ignore2; { return; } /* end go_serial() *//*** This function is used to get a byte from the the** serial_io_buffer. The data in this buffer is written** by the interrupt handler.**** If no data is available, a -1 is returned. Otherwise** a character is returned.*/intget_byte_serial() { int result=-1; /* Turn interrupts off while reading buffer */ _disable(); /* No bytes available */ if (serial_io.start == serial_io.end) result = -1; else { /* Return character */ result = (int) *serial_io.start; serial_io.start++; /* Check for wrap around */ if (serial_io.start >= (serial_io_buffer+BUF_SIZE)) { serial_io.start = serial_io_buffer; } } /* Turn interrupts back on */ _enable(); return (result); } /* end get_byte_serial() *//*** This function is the interrupt handler which buffers** incoming characters.**** Note: The "interrupt" keyword is not well documented.** It produces a procedure which returns with an** "iret" instead of the usual "ret".*/void interrupt serial_int() { int c; /* Get character */ c = inp(serial_io.port); *serial_io.end = (unsigned char) c; serial_io.end++; /* Check for wrap around */ if (serial_io.end >= (serial_io_buffer+BUF_SIZE)) serial_io.end = serial_io_buffer; /* Has the buffer overflowed? */ if (serial_io.start == serial_io.end) serial_io.error = TRUE; /* Send EOI to 8259 */ (void) outp(INTR_EOI, 0x20); } /* end serial_int() */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -