X-Git-Url: http://git.rot13.org/?p=osmocom-bb.git;a=blobdiff_plain;f=src%2Ftarget%2Ffirmware%2Fcalypso%2Fuart.c;h=bcb56bd069467bf9ed4f19a17cfb757c63c1cdeb;hp=7e68edc32e26c99d6a97386f5d907f620ea23992;hb=c9297d28e0484f58b4672e528610b7ba9e5aa073;hpb=8eedad77c7f71d1181693de3cb9cd8a9e782618b diff --git a/src/target/firmware/calypso/uart.c b/src/target/firmware/calypso/uart.c index 7e68edc..bcb56bd 100644 --- a/src/target/firmware/calypso/uart.c +++ b/src/target/firmware/calypso/uart.c @@ -28,11 +28,12 @@ #include #include +#include #include #include #include -#include +#include #define BASE_ADDR_UART_MODEM 0xffff5000 #define OFFSET_IRDA 0x800 @@ -42,7 +43,7 @@ #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, @@ -126,12 +127,12 @@ static void uart_set_lcr7bit(int uart, int on) 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] */ @@ -190,7 +191,7 @@ static uint8_t uart_reg_read(int uart, enum uart_reg reg) 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; @@ -223,7 +224,7 @@ static void uart_irq_handler_cons(enum irq_nr irq) } } -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; @@ -259,10 +260,13 @@ static void uart_irq_handler_sercomm(enum irq_nr irq) } 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; } } @@ -272,21 +276,25 @@ static const uint8_t uart2irq[] = { [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 @@ -295,6 +303,16 @@ void uart_init(uint8_t uart) 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 */ @@ -312,6 +330,14 @@ void uart_init(uint8_t uart) 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); @@ -356,10 +382,28 @@ int uart_putchar_nb(uint8_t uart, int c) 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; } @@ -383,7 +427,7 @@ int uart_baudrate(uint8_t uart, enum uart_baudrate bdrt) { uint16_t div; - if (bdrt > ARRAY_SIZE(divider)) + if (bdrt >= ARRAY_SIZE(divider)) return -1; div = divider[bdrt];