diff --git a/conts/libc/include/sys-userspace/arch-arm/arch/pl011_uart.h b/conts/libc/include/sys-userspace/arch-arm/arch/pl011_uart.h index 341aac3..9b30683 100644 --- a/conts/libc/include/sys-userspace/arch-arm/arch/pl011_uart.h +++ b/conts/libc/include/sys-userspace/arch-arm/arch/pl011_uart.h @@ -2,19 +2,19 @@ #ifndef __PL011__UART__H__ #define __PL011__UART__H__ -/* +/* * PL011 UART Generic driver implementation. * Copyright Bahadir Balban (C) 2006 * - * The particular intention of this code is that it has been carefully + * The particular intention of this code is that it has been carefully * written as decoupled from os-specific code and in a verbose way such - * that it clearly demonstrates how the device operates, reducing the - * amount of time to be spent for understanding the operational model + * that it clearly demonstrates how the device operates, reducing the + * amount of time to be spent for understanding the operational model * and implementing a driver from scratch. This is the very first to be * such a driver so far, hopefully it will turn out to be useful. */ -/* Default base address for this chip */ +/* FIXME: Take this value in agreement from kernel, or from kernel only */ #define PL011_USR_BASE 0x500000 #define PL011_BASE PL011_USR_BASE @@ -23,21 +23,21 @@ #define write(val, address) *((volatile unsigned int *) address) = val /* Register offsets */ -#define PL011_UARTDR (PL011_BASE + 0x00) -#define PL011_UARTRSR (PL011_BASE + 0x04) -#define PL011_UARTECR (PL011_BASE + 0x04) -#define PL011_UARTFR (PL011_BASE + 0x18) -#define PL011_UARTILPR (PL011_BASE + 0x20) -#define PL011_UARTIBRD (PL011_BASE + 0x24) -#define PL011_UARTFBRD (PL011_BASE + 0x28) -#define PL011_UARTLCR_H (PL011_BASE + 0x2C) -#define PL011_UARTCR (PL011_BASE + 0x30) -#define PL011_UARTIFLS (PL011_BASE + 0x34) -#define PL011_UARTIMSC (PL011_BASE + 0x38) -#define PL011_UARTRIS (PL011_BASE + 0x3C) -#define PL011_UARTMIS (PL011_BASE + 0x40) -#define PL011_UARTICR (PL011_BASE + 0x44) -#define PL011_UARTDMACR (PL011_BASE + 0x48) +#define PL011_UARTDR 0x00 +#define PL011_UARTRSR 0x04 +#define PL011_UARTECR 0x04 +#define PL011_UARTFR 0x18 +#define PL011_UARTILPR 0x20 +#define PL011_UARTIBRD 0x24 +#define PL011_UARTFBRD 0x28 +#define PL011_UARTLCR_H 0x2C +#define PL011_UARTCR 0x30 +#define PL011_UARTIFLS 0x34 +#define PL011_UARTIMSC 0x38 +#define PL011_UARTRIS 0x3C +#define PL011_UARTMIS 0x40 +#define PL011_UARTICR 0x44 +#define PL011_UARTDMACR 0x48 /* IRQ bits for each uart irq event */ #define PL011_RXIRQ (1 << 4) @@ -48,262 +48,228 @@ #define PL011_BEIRQ (1 << 9) #define PL011_OEIRQ (1 << 10) +/* FIXME: Need to define this somewhere else */ struct pl011_uart; -int pl011_initialise(struct pl011_uart *); -int pl011_tx_char(char); -int pl011_rx_char(char *); +int pl011_initialise(struct pl011_uart *uart); +int pl011_tx_char(unsigned int base, char c); +int pl011_rx_char(unsigned int base, char *c); + +void pl011_set_baudrate(unsigned int base, unsigned int baud, + unsigned int clkrate); +void pl011_set_irq_mask(unsigned int base, unsigned int flags); +void pl011_clr_irq_mask(unsigned int base, unsigned int flags); -void pl011_set_baudrate(unsigned int, unsigned int); -void pl011_set_irq_mask(unsigned int); -void pl011_clr_irq_mask(unsigned int); - void pl011_irq_handler(struct pl011_uart *); -void pl011_tx_irq_handler(struct pl011_uart *, unsigned int); -void pl011_rx_irq_handler(struct pl011_uart *, unsigned int); -void pl011_error_irq_handler(struct pl011_uart *, unsigned int); +void pl011_tx_irq_handler(struct pl011_uart *uart, unsigned int); +void pl011_rx_irq_handler(struct pl011_uart *uart, unsigned int); +void pl011_error_irq_handler(struct pl011_uart *uart, unsigned int); -static inline void pl011_uart_enable(void); -static inline void pl011_uart_disable(void); -static inline void pl011_tx_enable(void); -static inline void pl011_tx_disable(void); -static inline void pl011_rx_enable(void); -static inline void pl011_rx_disable(void); -static inline void pl011_irq_clear(unsigned int flags); -static inline unsigned int pl011_read_irqstat(void); -static inline unsigned int pl011_read_irqmask(void); -static inline void pl011_rx_dma_disable(void); -static inline void pl011_rx_dma_enable(void); -static inline void pl011_tx_dma_enable(void); -static inline void pl011_tx_dma_disable(void); -static inline void pl011_set_irq_fifolevel(unsigned int xfer, - unsigned int level); -static inline void pl011_set_word_width(int size); -static inline void pl011_disable_fifos(void); -static inline void pl011_set_parity_even(void); -static inline void pl011_parity_enable(void); -static inline void pl011_set_stopbits(int stopbits); +static inline void pl011_uart_enable(unsigned int base); +static inline void pl011_uart_disable(unsigned int base); +static inline void pl011_tx_enable(unsigned int base); +static inline void pl011_tx_disable(unsigned int base); +static inline void pl011_rx_enable(unsigned int base); +static inline void pl011_rx_disable(unsigned int base); +static inline void pl011_irq_clear(unsigned int base, unsigned int flags); +static inline unsigned int pl011_read_irqstat(unsigned int base); +static inline unsigned int pl011_read_irqmask(unsigned int base); +static inline void pl011_rx_dma_disable(unsigned int base); +static inline void pl011_rx_dma_enable(unsigned int base); +static inline void pl011_tx_dma_enable(unsigned int base); +static inline void pl011_tx_dma_disable(unsigned int base); +static inline void pl011_set_irq_fifolevel(unsigned int base, + unsigned int xfer, unsigned int level); +static inline void pl011_set_word_width(unsigned int base, int size); +static inline void pl011_disable_fifos(unsigned int base); +static inline void pl011_set_parity_even(unsigned int base); +static inline void pl011_parity_enable(unsigned int base); +static inline void pl011_set_stopbits(unsigned int base, int stopbits); -static inline void pl011_set_parity_odd(void); -static inline void pl011_enable_fifos(void); -static inline void pl011_parity_disable(void); - -struct pl011_uart_ops { - int (*initialise)(struct pl011_uart *); - - int (*tx_char)(char); - int (*rx_char)(char *); - - void (*set_baudrate)(unsigned int, unsigned int); - void (*set_irq_mask)(unsigned int); - void (*clr_irq_mask)(unsigned int); - - void (*irq_handler)(struct pl011_uart *); - void (*tx_irq_handler)(struct pl011_uart *, unsigned int); - void (*rx_irq_handler)(struct pl011_uart *, unsigned int); - void (*error_irq_handler)(struct pl011_uart *, unsigned int); -}; +static inline void pl011_set_parity_odd(unsigned int base); +static inline void pl011_enable_fifos(unsigned int base); +static inline void pl011_parity_disable(unsigned int base); struct pl011_uart { - const unsigned int base; - struct pl011_uart_ops ops; + unsigned int base; unsigned int frame_errors; unsigned int parity_errors; unsigned int break_errors; unsigned int overrun_errors; unsigned int rx_timeout_errors; -}; - - +}; #define PL011_UARTEN (1 << 0) -static inline void pl011_uart_enable() +static inline void pl011_uart_enable(unsigned int base) { - unsigned int val; - val = 0; - - read(val, PL011_UARTCR); + unsigned int val = 0; + + read(val, (base + PL011_UARTCR)); val |= PL011_UARTEN; - write(val, PL011_UARTCR); - - return; + write(val, (base + PL011_UARTCR)); + + return; } -static inline void pl011_uart_disable() +static inline void pl011_uart_disable(unsigned int base) { - unsigned int val; - val = 0; - - read(val, PL011_UARTCR); + unsigned int val = 0; + + read(val, (base + PL011_UARTCR)); val &= ~PL011_UARTEN; - write(val, PL011_UARTCR); - + write(val, (base + PL011_UARTCR)); + return; } #define PL011_TXE (1 << 8) -static inline void pl011_tx_enable() +static inline void pl011_tx_enable(unsigned int base) { - unsigned int val; - val = 0; - - read(val, PL011_UARTCR); + unsigned int val = 0; + + read(val, (base + PL011_UARTCR)); val |= PL011_TXE; - write(val, PL011_UARTCR); + write(val, (base + PL011_UARTCR)); return; } -static inline void pl011_tx_disable() +static inline void pl011_tx_disable(unsigned int base) { - unsigned int val; - val = 0; - - read(val, PL011_UARTCR); + unsigned int val = 0; + + read(val, (base + PL011_UARTCR)); val &= ~PL011_TXE; - write(val, PL011_UARTCR); + write(val, (base + PL011_UARTCR)); return; } - #define PL011_RXE (1 << 9) -static inline void pl011_rx_enable() +static inline void pl011_rx_enable(unsigned int base) { - unsigned int val; - val = 0; - - read(val, PL011_UARTCR); + unsigned int val = 0; + + read(val, (base + PL011_UARTCR)); val |= PL011_RXE; - write(val, PL011_UARTCR); + write(val, (base + PL011_UARTCR)); return; } -static inline void pl011_rx_disable() +static inline void pl011_rx_disable(unsigned int base) { - unsigned int val; - val = 0; - - read(val, PL011_UARTCR); + unsigned int val = 0; + + read(val, (base + PL011_UARTCR)); val &= ~PL011_RXE; - write(val, PL011_UARTCR); + write(val, (base + PL011_UARTCR)); return; } #define PL011_TWO_STOPBITS_SELECT (1 << 3) -static inline void pl011_set_stopbits(int stopbits) +static inline void pl011_set_stopbits(unsigned int base, int stopbits) { - unsigned int val; - val = 0; - - read(val, PL011_UARTLCR_H); - + unsigned int val = 0; + read(val, (base + PL011_UARTLCR_H)); + if(stopbits == 2) { /* Set to two bits */ val |= PL011_TWO_STOPBITS_SELECT; } else { /* Default is 1 */ val &= ~PL011_TWO_STOPBITS_SELECT; } - write(val, PL011_UARTLCR_H); - return; -} - -#define PL011_PARITY_ENABLE (1 << 1) -static inline void pl011_parity_enable() -{ - unsigned int val; - val = 0; - - read(val, PL011_UARTLCR_H); - val |= PL011_PARITY_ENABLE; - write(val, PL011_UARTLCR_H); + write(val, (base + PL011_UARTLCR_H)); return; } -static inline void pl011_parity_disable() +#define PL011_PARITY_ENABLE (1 << 1) +static inline void pl011_parity_enable(unsigned int base) { - unsigned int val; - val = 0; - - read(val, PL011_UARTLCR_H); + unsigned int val = 0; + + read(val, (base +PL011_UARTLCR_H)); + val |= PL011_PARITY_ENABLE; + write(val, (base + PL011_UARTLCR_H)); + return; +} + +static inline void pl011_parity_disable(unsigned int base) +{ + unsigned int val = 0; + + read(val, (base + PL011_UARTLCR_H)); val &= ~PL011_PARITY_ENABLE; - write(val, PL011_UARTLCR_H); + write(val, (base + PL011_UARTLCR_H)); return; } #define PL011_PARITY_EVEN (1 << 2) -static inline void pl011_set_parity_even() +static inline void pl011_set_parity_even(unsigned int base) { - unsigned int val; - val = 0; - - read(val, PL011_UARTLCR_H); + unsigned int val = 0; + + read(val, (base + PL011_UARTLCR_H)); val |= PL011_PARITY_EVEN; - write(val, PL011_UARTLCR_H); + write(val, (base + PL011_UARTLCR_H)); return; } -static inline void pl011_set_parity_odd() +static inline void pl011_set_parity_odd(unsigned int base) { - unsigned int val; - val = 0; - - read(val, PL011_UARTLCR_H); + unsigned int val = 0; + + read(val, (base + PL011_UARTLCR_H)); val &= ~PL011_PARITY_EVEN; - write(val, PL011_UARTLCR_H); + write(val, (base + PL011_UARTLCR_H)); return; } #define PL011_ENABLE_FIFOS (1 << 4) -static inline void pl011_enable_fifos() +static inline void pl011_enable_fifos(unsigned int base) { - unsigned int val; - val = 0; - - read(val, PL011_UARTLCR_H); + unsigned int val = 0; + + read(val, (base + PL011_UARTLCR_H)); val |= PL011_ENABLE_FIFOS; - write(val, PL011_UARTLCR_H); + write(val, (base + PL011_UARTLCR_H)); return; } -static inline void pl011_disable_fifos() +static inline void pl011_disable_fifos(unsigned int base) { - unsigned int val; - val = 0; - - read(val, PL011_UARTLCR_H); + unsigned int val = 0; + + read(val, (base + PL011_UARTLCR_H)); val &= ~PL011_ENABLE_FIFOS; - write(val, PL011_UARTLCR_H); + write(val, (base + PL011_UARTLCR_H)); return; } - #define PL011_WORD_WIDTH_SHIFT (5) /* Sets the transfer word width for the data register. */ -static inline void pl011_set_word_width(int size) +static inline void pl011_set_word_width(unsigned int base, int size) { - unsigned int val; - val = 0; - + unsigned int val = 0; if(size < 5 || size > 8) /* Default is 8 */ size = 8; - - /* Clear size field */ - read(val, PL011_UARTLCR_H); - val &= ~(0x3 << PL011_WORD_WIDTH_SHIFT); - write(val, PL011_UARTLCR_H); - /* The formula is to write 5 less of size given: + /* Clear size field */ + read(val, (base + PL011_UARTLCR_H)); + val &= ~(0x3 << PL011_WORD_WIDTH_SHIFT); + write(val, (base + PL011_UARTLCR_H)); + + /* + * The formula is to write 5 less of size given: * 11 = 8 bits * 10 = 7 bits * 01 = 6 bits * 00 = 5 bits */ - read(val, PL011_UARTLCR_H); + read(val, (base + PL011_UARTLCR_H)); val |= (size - 5) << PL011_WORD_WIDTH_SHIFT; - write(val, PL011_UARTLCR_H); - + write(val, (base + PL011_UARTLCR_H)); + return; } -/* +/* * Defines at which level of fifo fullness an irq will be generated. * @xfer: tx fifo = 0, rx fifo = 1 * @level: Generate irq if: @@ -314,95 +280,92 @@ static inline void pl011_set_word_width(int size) * 4 rxfifo >= 7/8 full txfifo <= 7/8 full * 5-7 reserved reserved */ -static inline void pl011_set_irq_fifolevel(unsigned int xfer, unsigned int level) +static inline void pl011_set_irq_fifolevel(unsigned int base, \ + unsigned int xfer, unsigned int level) { if(xfer != 1 && xfer != 0) /* Invalid fifo */ return; - if(level > 4) /* Invalid level */ - return; - - write(level << (xfer * 3), PL011_UARTIFLS); + return; + + write(level << (xfer * 3), (base + PL011_UARTIFLS)); return; } /* returns which irqs are masked */ -static inline unsigned int pl011_read_irqmask(void) +static inline unsigned int pl011_read_irqmask(unsigned int base) { unsigned int flags; - read(flags, PL011_UARTIMSC); + read(flags, (base + PL011_UARTIMSC)); return flags; } /* returns masked irq status */ -static inline unsigned int pl011_read_irqstat(void) +static inline unsigned int pl011_read_irqstat(unsigned int base) { unsigned int irqstatus; - read(irqstatus, PL011_UARTMIS); - return irqstatus; + read(irqstatus, (base + PL011_UARTMIS)); + return irqstatus; } + /* Clears the given asserted irqs */ -static inline void pl011_irq_clear(unsigned int flags) +static inline void pl011_irq_clear(unsigned int base, unsigned int flags) { - if(flags > 0x3FF) { /* Invalid irq clearing bitvector */ + if(flags > 0x3FF) { + /* Invalid irq clearing bitvector */ return; } /* Simply write the flags since it's a write-only register */ - write(flags, PL011_UARTICR); + write(flags, (base + PL011_UARTICR)); return; } #define PL011_TXDMAEN (1 << 1) #define PL011_RXDMAEN (1 << 0) - -/* Enables dma transfers for uart. The dma controller - * must be initialised, set-up and enabled separately. +/* + * Enables dma transfers for uart. The dma controller + * must be initialised, set-up and enabled separately. */ -static inline void pl011_tx_dma_enable() +static inline void pl011_tx_dma_enable(unsigned int base) { - unsigned int val; - val = 0; - - read(val, PL011_UARTDMACR); + unsigned int val = 0; + + read(val, (base + PL011_UARTDMACR)); val |= PL011_TXDMAEN; - write(val, PL011_UARTDMACR); + write(val, (base + PL011_UARTDMACR)); return; } /* Disables dma transfers for uart */ -static inline void pl011_tx_dma_disable() +static inline void pl011_tx_dma_disable(unsigned int base) { - unsigned int val; - val = 0; - - read(val, PL011_UARTDMACR); + unsigned int val = 0; + + read(val, (base + PL011_UARTDMACR)); val &= ~PL011_TXDMAEN; - write(val, PL011_UARTDMACR); + write(val, (base + PL011_UARTDMACR)); return; } -static inline void pl011_rx_dma_enable() +static inline void pl011_rx_dma_enable(unsigned int base) { - unsigned int val; - val = 0; - - read(val, PL011_UARTDMACR); + unsigned int val = 0; + + read(val, (base + PL011_UARTDMACR)); val |= PL011_RXDMAEN; - write(val, PL011_UARTDMACR); + write(val, (base + PL011_UARTDMACR)); return; } -static inline void pl011_rx_dma_disable() +static inline void pl011_rx_dma_disable(unsigned int base) { - unsigned int val; - val = 0; - - read(val, PL011_UARTDMACR); + unsigned int val = 0; + + read(val, (base + PL011_UARTDMACR)); val &= ~PL011_RXDMAEN; - write(val, PL011_UARTDMACR); + write(val, (base +PL011_UARTDMACR)); return; } - #endif /* __PL011__UART__ */ diff --git a/conts/libc/src/sys-userspace/arch-arm/plat-pb926/platform_init.c b/conts/libc/src/sys-userspace/arch-arm/plat-pb926/platform_init.c index b732a58..b0ad567 100644 --- a/conts/libc/src/sys-userspace/arch-arm/plat-pb926/platform_init.c +++ b/conts/libc/src/sys-userspace/arch-arm/plat-pb926/platform_init.c @@ -1,50 +1,53 @@ #include +/* TODO: May need to remove this */ struct pl011_uart uart; void platform_init(void); void platform_init(void) { + uart.base = PL011_USR_BASE; pl011_initialise(&uart); } -/* Initialises the uart class data structures, and the device. - * Terminal-like operation is assumed for default settings. +/* + * Initialises the uart class data structures, and the device. + * Terminal-like operation is assumed for default settings. */ int pl011_initialise(struct pl011_uart * uart) { - uart->frame_errors = 0; uart->parity_errors = 0; uart->break_errors = 0; uart->overrun_errors = 0; - + /* Initialise data register for 8 bit data read/writes */ - pl011_set_word_width(8); - - /* Fifos are disabled because by default it is assumed the port - * will be used as a user terminal, and in that case the typed + pl011_set_word_width(uart->base, 8); + + /* + * Fifos are disabled because by default it is assumed the port + * will be used as a user terminal, and in that case the typed * characters will only show up when fifos are flushed, rather than * when each character is typed. We avoid this by not using fifos. */ - pl011_disable_fifos(); - + pl011_disable_fifos(uart->base); + /* Set default baud rate of 38400 */ - pl011_set_baudrate(38400, 24000000); - + pl011_set_baudrate(uart->base, 38400, 24000000); + /* Set default settings of 1 stop bit, no parity, no hw flow ctrl */ - pl011_set_stopbits(1); - pl011_parity_disable(); + pl011_set_stopbits(uart->base, 1); + pl011_parity_disable(uart->base); /* Disable all irqs */ - pl011_set_irq_mask(0x3FF); - + pl011_set_irq_mask(uart->base, 0x3FF); + /* Enable rx, tx, and uart chip */ - pl011_tx_enable(); - pl011_rx_enable(); - pl011_uart_enable(); - + pl011_tx_enable(uart->base); + pl011_rx_enable(uart->base); + pl011_uart_enable(uart->base); + return 0; } diff --git a/conts/libc/src/sys-userspace/arch-arm/plat-pb926/sys_fputc.c b/conts/libc/src/sys-userspace/arch-arm/plat-pb926/sys_fputc.c index ab9e008..1cdc629 100644 --- a/conts/libc/src/sys-userspace/arch-arm/plat-pb926/sys_fputc.c +++ b/conts/libc/src/sys-userspace/arch-arm/plat-pb926/sys_fputc.c @@ -76,86 +76,11 @@ * The construction, validity and performance of this licence is governed * by the laws in force in New South Wales, Australia. */ -#define MACHINE_PB926 - #include #include #include -//#define iPAQ /* FIXME: this is ugly */ -//#undef XSCALE -//#define XSCALE -// #undef iPAQ -// #define XSCALE - extern int __fputc(int c, FILE *stream); -/* Put character for elf-loader */ -int -__fputc(int c, FILE *stream) -{ - -/* ---------------------------------- iPAQ & PLEB1 (SA-1100)--------------------------- */ -#ifdef MACHINE_IPAQ_H3800 //iPAQ // SA-1100 - volatile char *base = (char *)0x80050000; // base serial interface address - /* volatile int *base2 = (int *)0x80030000; // the other serial Arm serial i/f */ - -/* -UTSR1 32 @ 0x20: - tby <0> # Transmitter busy - rne <1> # Refeive FIFO not empty - tnf <2> # Transmitter not full - pre <3> # Parity error - fre <4> # Framing error - ror <5> # Receive FIFO overrun -*/ - -#define UTDR 0x14 // data register -#define UTSR1 0x20 // status register 1 offset -#define UTSR1_TNF (1 << 2) // tx FIFO not full (status bit) - - while ( ! ( * ( (volatile long *) (base + UTSR1)) & UTSR1_TNF )) - ; // busy wait while TX FIFO is full - *(volatile unsigned char *) (base + UTDR) = c; - // *base2 = c; -#endif - -/* ---------------------------------- PLEB2 (XSCALE PXA-255) --------------------------- */ -#ifdef MACHINE_PLEB2 //XSCALE /* PXA 255 on PLEB2 */ - -/* Console port -- taken from kernel/include/platform/pleb2/console.h */ -#define CONSOLE_OFFSET 0x100000 - -/* IO Base -- taken from kernel/include/arch/arm/xscale/cpu.h */ -#define XSCALE_PXA255_IO_BASE 0x40000000 - -#define DATAR 0x00000000 -#define STATUSR 0x00000014 - -/* TX empty bit -- uboot/include/asm/arch/hardware.h */ -#define LSR_TEMT (1 << 6) /* Transmitter Empty */ - -volatile char *base = (char *) (XSCALE_PXA255_IO_BASE + CONSOLE_OFFSET); - - /* wait for room in the tx FIFO on FFUART */ - while ( ! ( * ( (volatile long *) (base + STATUSR)) & LSR_TEMT )) - ; // busy wait while TX FIFO is full - *(volatile unsigned char *) (base + DATAR) = c; - -#endif /* XSCALE */ -#ifdef MACHINE_PB926 - { - int res; - do { - res = pl011_tx_char(c); - } while( res < 0); - } -#endif /* MACHINE_PB926 */ - return(0); -} - -/* --------------------------------- PB926 UART Driver -------------------------------- */ -#ifdef MACHINE_PB926 - extern struct pl011_uart uart; /* UART-specific internal error codes */ @@ -178,56 +103,47 @@ extern struct pl011_uart uart; #define PL011_DSR (1 << 1) #define PL011_CTS (1 << 0) -int pl011_tx_char(char c) +int pl011_tx_char(unsigned int base, char c) { - unsigned int val; - val = 0; - - read(val, PL011_UARTFR); + unsigned int val = 0; + + read(val, (base + PL011_UARTFR)); if(val & PL011_TXFF) { /* TX FIFO Full */ return -PL011_EAGAIN; } - write(c, PL011_UARTDR); + write(c, (base + PL011_UARTDR)); return 0; } -int pl011_rx_char(char * c) +int pl011_rx_char(unsigned int base, char * c) { unsigned int data; - unsigned int val; - val = 0; - - read(val, PL011_UARTFR); + unsigned int val = 0; + + read(val, (base + PL011_UARTFR)); if(val & PL011_RXFE) { /* RX FIFO Empty */ return -PL011_EAGAIN; } - - read(data, PL011_UARTDR); + + read(data, (base + PL011_UARTDR)); *c = (char) data; - + if((data >> 8) & 0xF) { /* There were errors */ return -1; /* Signal error in xfer */ } return 0; /* No error return */ } - -/* - * Sets the baud rate in kbps. It is recommended to use - * standard rates such as: 1200, 2400, 3600, 4800, 7200, +/* + * Sets the baud rate in kbps. It is recommended to use + * standard rates such as: 1200, 2400, 3600, 4800, 7200, * 9600, 14400, 19200, 28800, 38400, 57600 76800, 115200. */ -void pl011_set_baudrate(unsigned int baud, unsigned int clkrate) +void pl011_set_baudrate(unsigned int base, unsigned int baud, + unsigned int clkrate) { const unsigned int uartclk = 24000000; /* 24Mhz clock fixed on pb926 */ - unsigned int val; - unsigned int ipart, fpart; - unsigned int remainder; - - remainder = 0; - ipart = 0; - fpart = 0; - val = 0; + unsigned int val = 0, ipart = 0, fpart = 0; /* Use default pb926 rate if no rate is supplied */ if(clkrate == 0) { @@ -239,52 +155,58 @@ void pl011_set_baudrate(unsigned int baud, unsigned int clkrate) /* 24000000 / (38400 * 16) */ ipart = 39; - write(ipart, PL011_UARTIBRD); - write(fpart, PL011_UARTFBRD); + write(ipart, (base + PL011_UARTIBRD)); + write(fpart, (base + PL011_UARTFBRD)); - /* For the IBAUD and FBAUD to update, we need to + /* + * For the IBAUD and FBAUD to update, we need to * write to UARTLCR_H because the 3 registers are * actually part of a single register in hardware - * which only updates by a write to UARTLCR_H */ - read(val, PL011_UARTLCR_H); - write(val, PL011_UARTLCR_H); + * which only updates by a write to UARTLCR_H + */ + read(val, (base + PL011_UARTLCR_H)); + write(val, (base + PL011_UARTLCR_H)); return; } - /* Masks the irqs given in the flags bitvector. */ -void pl011_set_irq_mask(unsigned int flags) +void pl011_set_irq_mask(unsigned int base, unsigned int flags) { - unsigned int val; - val = 0; - + unsigned int val = 0; + if(flags > 0x3FF) { /* Invalid irqmask bitvector */ return; } - - read(val, PL011_UARTIMSC); + + read(val, (base + PL011_UARTIMSC)); val |= flags; - write(val, PL011_UARTIMSC); + write(val, (base + PL011_UARTIMSC)); return; } - /* Clears the irqs given in flags from masking */ -void pl011_clr_irq_mask(unsigned int flags) +void pl011_clr_irq_mask(unsigned int base, unsigned int flags) { - unsigned int val; - val = 0; - - if(flags > 0x3FF) { /* Invalid irqmask bitvector */ + unsigned int val = 0; + + if(flags > 0x3FF) { + /* Invalid irqmask bitvector */ return; } - - read(val, PL011_UARTIMSC); + + read(val, (base + PL011_UARTIMSC)); val &= ~flags; - write(val, PL011_UARTIMSC); + write(val, (base + PL011_UARTIMSC)); return; } +int __fputc(int c, FILE *stream) +{ + int res; + do { + res = pl011_tx_char(uart.base, c); + } while( res < 0); -#endif + return(0); +}