/* * Copyright 2017, Data61 * Commonwealth Scientific and Industrial Research Organisation (CSIRO) * ABN 41 687 119 230. * * This software may be distributed and modified according to the terms of * the BSD 2-Clause license. Note that NO WARRANTY is provided. * See "LICENSE_BSD2.txt" for details. * * @TAG(DATA61_BSD) */ #include #include #include #include "../../chardev.h" #define IMXUART_DLL 0x000 #define IMXUART_RHR 0x000 /* UXRD */ #define IMXUART_THR 0x040 /* UTXD */ #define IMXUART_UCR1 0x080 /* Control reg */ #define IMXUART_LSR 0x094 /* USR1 -- status reg */ #define IMXUART_LSR_RXFIFIOE (1<<9) #define IMXUART_LSR_RXOE (1<<1) #define IMXUART_LSR_RXPE (1<<2) #define IMXUART_LSR_RXFE (1<<3) #define IMXUART_LSR_RXBI (1<<4) #define IMXUART_LSR_TXFIFOE (1<<13) #define IMXUART_LSR_TXSRE (1<<6) #define IMXUART_LSR_RXFIFOSTS (1<<7) #define UART_RHR_READY_MASK (BIT(15)) #define UART_BYTE_MASK 0xFF #define REG_PTR(base, offset) ((volatile uint32_t *)((char*)(base) + (offset))) int uart_getchar(ps_chardevice_t* d) { int character = -1; uint32_t data = 0; if (*REG_PTR(d->vaddr, IMXUART_LSR) & IMXUART_LSR_RXFIFIOE) { data = *REG_PTR(d->vaddr, IMXUART_RHR); if (data & UART_RHR_READY_MASK) { character = data & UART_BYTE_MASK; } } return character; } int uart_putchar(ps_chardevice_t* d, int c) { if (*REG_PTR(d->vaddr, IMXUART_LSR) & IMXUART_LSR_TXFIFOE) { *REG_PTR(d->vaddr, IMXUART_THR) = c; if (c == '\n' && (d->flags & SERIAL_AUTO_CR)) { uart_putchar(d, '\r'); } return c; } else { return -1; } } static void uart_handle_irq(ps_chardevice_t* d UNUSED) { /* TODO */ } int uart_init(const struct dev_defn* defn, const ps_io_ops_t* ops, ps_chardevice_t* dev) { void* vaddr = chardev_map(defn, ops); memset(dev, 0, sizeof(*dev)); if (vaddr == NULL) { return -1; } dev->id = defn->id; dev->vaddr = vaddr; dev->read = &uart_read; dev->write = &uart_write; dev->handle_irq = &uart_handle_irq; dev->irqs = defn->irqs; dev->ioops = *ops; dev->flags = SERIAL_AUTO_CR; /* * Enable interrupts for receiver */ *REG_PTR(dev->vaddr, IMXUART_UCR1) |= IMXUART_LSR_RXFIFIOE; return 0; }