Skip to content
Snippets Groups Projects
Commit d395a548 authored by Rob Swindell's avatar Rob Swindell :speech_balloon:
Browse files

Better RTS support

Reducing log output (lowering log level of line 437 from LOG_INFO to LOG_DEBUG) highlighted an issue with Telix stopping RX. That was fixed by checking RTS in input_thread(). Qmodem needs RTS checked when writing the MCR.

This improved RTS support has been tested with Telix, Qmodem, Telemate, and Banacom at full data rates.
parent dc0d401d
No related branches found
No related tags found
1 merge request!463MRC mods by Codefenix (2024-10-20)
...@@ -178,6 +178,23 @@ void set_interrupt_pending(BYTE intr, BOOL assert) ...@@ -178,6 +178,23 @@ void set_interrupt_pending(BYTE intr, BOOL assert)
#define assert_interrupt(i) set_interrupt_pending(i, TRUE) #define assert_interrupt(i) set_interrupt_pending(i, TRUE)
#define deassert_interrupt(i) set_interrupt_pending(i, FALSE) #define deassert_interrupt(i) set_interrupt_pending(i, FALSE)
void data_waiting(BOOL waiting)
{
if(waiting && (uart_mcr_reg & UART_MCR_RTS)) {
/* Set the "Data ready" bit in the LSR */
uart_lsr_reg |= UART_LSR_DATA_READY;
/* assert rx data interrupt */
assert_interrupt(UART_IER_RX_DATA);
} else {
/* Clear the data ready bit in the LSR */
uart_lsr_reg &= ~UART_LSR_DATA_READY;
/* Clear data ready interrupt identification in IIR */
deassert_interrupt(UART_IER_RX_DATA);
}
}
void _cdecl interrupt_thread(void *arg) void _cdecl interrupt_thread(void *arg)
{ {
HANDLE handles[] = {interrupt_event, carrier_event}; HANDLE handles[] = {interrupt_event, carrier_event};
...@@ -241,10 +258,7 @@ void _cdecl input_thread(void* arg) ...@@ -241,10 +258,7 @@ void _cdecl input_thread(void* arg)
RingBufWrite(&rdbuf,buf,count); RingBufWrite(&rdbuf,buf,count);
if(virtualize_uart) { if(virtualize_uart) {
/* Set the "Data ready" bit in the LSR */ data_waiting(TRUE);
uart_lsr_reg |= UART_LSR_DATA_READY;
assert_interrupt(UART_IER_RX_DATA); /* assert rx data interrupt */
} }
} }
lputs(LOG_DEBUG,"input_thread: terminated"); lputs(LOG_DEBUG,"input_thread: terminated");
...@@ -321,7 +335,8 @@ VOID uart_wrport(WORD port, BYTE data) ...@@ -321,7 +335,8 @@ VOID uart_wrport(WORD port, BYTE data)
if(uart_lcr_reg&UART_LCR_DLAB) { if(uart_lcr_reg&UART_LCR_DLAB) {
uart_divisor_latch_lsb = data; uart_divisor_latch_lsb = data;
lprintf(LOG_DEBUG,"set divisor latch low byte: %02X", data); lprintf(LOG_DEBUG,"set divisor latch low byte: %02X", data);
} else { } else { // Transmitter Holding Register
if(log_level >= LOG_DEBUG)
lprintf(LOG_DEBUG,"WRITE DATA: %s", chr(data)); lprintf(LOG_DEBUG,"WRITE DATA: %s", chr(data));
if(!WriteFile(wrslot,&data,sizeof(BYTE),&retval,NULL)) { if(!WriteFile(wrslot,&data,sizeof(BYTE),&retval,NULL)) {
lprintf(LOG_ERR,"!VDD_WRITE: WriteFile Error %d (size=%d)" lprintf(LOG_ERR,"!VDD_WRITE: WriteFile Error %d (size=%d)"
...@@ -338,7 +353,7 @@ VOID uart_wrport(WORD port, BYTE data) ...@@ -338,7 +353,7 @@ VOID uart_wrport(WORD port, BYTE data)
lprintf(LOG_DEBUG,"set divisor latch high byte: %02X", data); lprintf(LOG_DEBUG,"set divisor latch high byte: %02X", data);
} else { } else {
uart_ier_reg = data; uart_ier_reg = data;
lprintf(LOG_INFO, "Set IER to %02X", data); lprintf(LOG_DEBUG, "Set IER to %02X", data);
} }
assert_interrupt(UART_IER_TX_EMPTY); /* should this be re-asserted for all writes? */ assert_interrupt(UART_IER_TX_EMPTY); /* should this be re-asserted for all writes? */
break; break;
...@@ -354,12 +369,7 @@ VOID uart_wrport(WORD port, BYTE data) ...@@ -354,12 +369,7 @@ VOID uart_wrport(WORD port, BYTE data)
uart_mcr_reg = data; uart_mcr_reg = data;
if((uart_mcr_reg&UART_MCR_DTR) == 0) /* Dropping DTR (i.e. "hangup") */ if((uart_mcr_reg&UART_MCR_DTR) == 0) /* Dropping DTR (i.e. "hangup") */
hangup(); hangup();
if((uart_mcr_reg & UART_MCR_RTS) && RingBufFull(&rdbuf) > 0) { data_waiting(RingBufFull(&rdbuf));
assert_interrupt(UART_IER_RX_DATA);
} else {
deassert_interrupt(UART_IER_RX_DATA);
uart_lsr_reg &= ~UART_LSR_DATA_READY;
}
lprintf(LOG_INFO, "Set MCR to %02X", data); lprintf(LOG_INFO, "Set MCR to %02X", data);
break; break;
case UART_SCRATCH: case UART_SCRATCH:
...@@ -394,15 +404,7 @@ VOID uart_rdport(WORD port, PBYTE data) ...@@ -394,15 +404,7 @@ VOID uart_rdport(WORD port, PBYTE data)
reset_yield(); reset_yield();
} else } else
*data=0; *data=0;
if(avail==0) { data_waiting(avail);
lputs(LOG_DEBUG,"No more data");
/* Clear the data ready bit in the LSR */
uart_lsr_reg &= ~UART_LSR_DATA_READY;
/* Clear data ready interrupt identification in IIR */
deassert_interrupt(UART_IER_RX_DATA);
} else /* re-assert RX data (increment the semaphore) */
assert_interrupt(UART_IER_RX_DATA);
break; break;
case UART_IER: case UART_IER:
if(uart_lcr_reg&UART_LCR_DLAB) { if(uart_lcr_reg&UART_LCR_DLAB) {
...@@ -432,7 +434,7 @@ VOID uart_rdport(WORD port, PBYTE data) ...@@ -432,7 +434,7 @@ VOID uart_rdport(WORD port, PBYTE data)
SetEvent(interrupt_event); SetEvent(interrupt_event);
if(uart_fifo_enabled) if(uart_fifo_enabled)
*data |= UART_IIR_FIFO_ENABLED; *data |= UART_IIR_FIFO_ENABLED;
lprintf(LOG_INFO, "IIR: %02X (pending: %02X)", *data, pending_interrupts); lprintf(LOG_DEBUG, "IIR: %02X (pending: %02X)", *data, pending_interrupts);
break; break;
} }
case UART_LCR: case UART_LCR:
...@@ -447,7 +449,7 @@ VOID uart_rdport(WORD port, PBYTE data) ...@@ -447,7 +449,7 @@ VOID uart_rdport(WORD port, PBYTE data)
*data = uart_lsr_reg; *data = uart_lsr_reg;
/* Clear line status interrupt pending */ /* Clear line status interrupt pending */
deassert_interrupt(UART_IER_LINE_STATUS); deassert_interrupt(UART_IER_LINE_STATUS);
lprintf(LOG_INFO, "LSR: %02X", *data); lprintf(LOG_DEBUG, "LSR: %02X", *data);
break; break;
case UART_MSR: case UART_MSR:
if(WaitForSingleObject(hungup_event,0)==WAIT_OBJECT_0) if(WaitForSingleObject(hungup_event,0)==WAIT_OBJECT_0)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment