#include <string.h>
#include <stdio.h>
+#include <defines.h>
#include <console.h>
#include <comm/sercomm.h>
#include <calypso/irq.h>
-#include <calypso/uart.h>
+#include <uart.h>
#define BASE_ADDR_UART_MODEM 0xffff5000
#define OFFSET_IRDA 0x800
#define LCR7BIT 0x80
#define LCRBFBIT 0x40
#define MCR6BIT 0x20
-#define REG_OFFS(m) ((m) &= ~(LCR7BIT|LCRBFBIT|MCR6BIT))
+#define REG_OFFS(m) ((m) & ~(LCR7BIT|LCRBFBIT|MCR6BIT))
/* read access LCR[7] = 0 */
enum uart_reg {
RHR = 0,
static uint8_t old_lcr;
static void uart_set_lcr_bf(int uart, int on)
{
- old_lcr = readb(UART_REG(uart, LCR));
-
- if (on)
+ if (on) {
+ old_lcr = readb(UART_REG(uart, LCR));
writeb(0xBF, UART_REG(uart, LCR));
- else
+ } else {
writeb(old_lcr, UART_REG(uart, LCR));
+ }
}
/* Enable or disable the TCR_TLR latch bit in MCR[6] */
return ret;
}
-static void uart_irq_handler_cons(enum irq_nr irq)
+static void uart_irq_handler_cons(__unused enum irq_nr irqnr)
{
const uint8_t uart = CONS_UART_NR;
uint8_t iir;
}
}
-static void uart_irq_handler_sercomm(enum irq_nr irq)
+static void uart_irq_handler_sercomm(__unused enum irq_nr irqnr)
{
const uint8_t uart = SERCOMM_UART_NR;
uint8_t iir, ch;
}
break;
case IIR_INT_TYPE_MSR:
+ printf("UART IRQ MSR\n");
break;
case IIR_INT_TYPE_RX_STATUS_ERROR:
+ printf("UART IRQ RX_SE\n");
break;
case IIR_INT_TYPE_XOFF:
+ printf("UART IRQXOFF\n");
break;
}
}
[1] = IRQ_UART_MODEM,
};
-void uart_init(uint8_t uart)
+void uart_init(uint8_t uart, uint8_t interrupts)
{
uint8_t irq = uart2irq[uart];
uart_reg_write(uart, IER, 0x00);
if (uart == CONS_UART_NR) {
cons_init();
- irq_register_handler(irq, &uart_irq_handler_cons);
- irq_config(irq, 0, 0, 0xff);
- irq_enable(irq);
+ if(interrupts) {
+ irq_register_handler(irq, &uart_irq_handler_cons);
+ irq_config(irq, 0, 0, 0xff);
+ irq_enable(irq);
+ }
} else {
sercomm_init();
- irq_register_handler(irq, &uart_irq_handler_sercomm);
- irq_config(irq, 0, 0, 0xff);
- irq_enable(irq);
+ if(interrupts) {
+ irq_register_handler(irq, &uart_irq_handler_sercomm);
+ irq_config(irq, 0, 0, 0xff);
+ irq_enable(irq);
+ }
uart_irq_enable(uart, UART_IRQ_RX_CHAR, 1);
}
#if 0
writeb(UART_REG_UIR, 0x00);
}
#endif
+
+ /* if we don't initialize these, we get strange corruptions in the
+ received data... :-( */
+ uart_reg_write(uart, MDR1, 0x07); /* turn off UART */
+ uart_reg_write(uart, XON1, 0x00); /* Xon1/Addr Register */
+ uart_reg_write(uart, XON2, 0x00); /* Xon2/Addr Register */
+ uart_reg_write(uart, XOFF1, 0x00); /* Xoff1 Register */
+ uart_reg_write(uart, XOFF2, 0x00); /* Xoff2 Register */
+ uart_reg_write(uart, EFR, 0x00); /* Enhanced Features Register */
+
/* select UART mode */
uart_reg_write(uart, MDR1, 0);
/* no XON/XOFF flow control, ENHANCED_EN, no auto-RTS/CTS */
uart_set_lcr7bit(uart, 0);
}
+void uart_poll(uint8_t uart) {
+ if(uart == CONS_UART_NR) {
+ uart_irq_handler_cons(0);
+ } else {
+ uart_irq_handler_sercomm(0);
+ }
+}
+
void uart_irq_enable(uint8_t uart, enum uart_irq irq, int on)
{
uint8_t ier = uart_reg_read(uart, IER);
int uart_getchar_nb(uint8_t uart, uint8_t *ch)
{
- if (!(readb(UART_REG(uart, LSR)) & 0x01))
+ uint8_t lsr;
+
+ lsr = readb(UART_REG(uart, LSR));
+
+ /* something strange happened */
+ if (lsr & 0x02)
+ printf("LSR RX_OE\n");
+ if (lsr & 0x04)
+ printf("LSR RX_PE\n");
+ if (lsr & 0x08)
+ printf("LSR RX_FE\n");
+ if (lsr & 0x10)
+ printf("LSR RX_BI\n");
+ if (lsr & 0x80)
+ printf("LSR RX_FIFO_STS\n");
+
+ /* is the Rx FIFO empty? */
+ if (!(lsr & 0x01))
return 0;
*ch = readb(UART_REG(uart, RHR));
+ //printf("getchar_nb(%u) = %02x\n", uart, *ch);
return 1;
}
{
uint16_t div;
- if (bdrt > ARRAY_SIZE(divider))
+ if (bdrt >= ARRAY_SIZE(divider))
return -1;
div = divider[bdrt];