[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH pic32 v3 11/16] pic32: add file pic32_uart.c
From: |
Peter Crosthwaite |
Subject: |
Re: [Qemu-devel] [PATCH pic32 v3 11/16] pic32: add file pic32_uart.c |
Date: |
Mon, 6 Jul 2015 01:08:57 -0700 |
On Sun, Jul 5, 2015 at 11:14 PM, Serge Vakulenko
<address@hidden> wrote:
> Implement pic32 UART peripheral interface.
>
> Signed-off-by: Serge Vakulenko <address@hidden>
> ---
> hw/mips/pic32_uart.c | 228
> +++++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 228 insertions(+)
> create mode 100644 hw/mips/pic32_uart.c
>
> diff --git a/hw/mips/pic32_uart.c b/hw/mips/pic32_uart.c
> new file mode 100644
> index 0000000..34056cf
> --- /dev/null
> +++ b/hw/mips/pic32_uart.c
> @@ -0,0 +1,228 @@
> +/*
> + * UART ports.
> + *
> + * Copyright (C) 2014-2015 Serge Vakulenko
> + *
> + * Permission to use, copy, modify, and distribute this software
> + * and its documentation for any purpose and without fee is hereby
> + * granted, provided that the above copyright notice appear in all
> + * copies and that both that the copyright notice and this
> + * permission notice and warranty disclaimer appear in supporting
> + * documentation, and that the name of the author not be used in
> + * advertising or publicity pertaining to distribution of the
> + * software without specific, written prior permission.
> + *
> + * The author disclaim all warranties with regard to this
> + * software, including all implied warranties of merchantability
> + * and fitness. In no event shall the author be liable for any
> + * special, indirect or consequential damages or any damages
> + * whatsoever resulting from loss of use, data or profits, whether
> + * in an action of contract, negligence or other tortious action,
> + * arising out of or in connection with the use or performance of
> + * this software.
> + */
> +#include "hw/hw.h"
> +#include "hw/char/serial.h"
> +#include "sysemu/char.h"
> +#include "pic32_peripherals.h"
> +
> +#include "pic32mz.h"
> +
> +#define UART_IRQ_ERR 0 /* error irq offset */
> +#define UART_IRQ_RX 1 /* receiver irq offset */
> +#define UART_IRQ_TX 2 /* transmitter irq offset */
> +
> +/*
> + * Read of UxRXREG register.
> + */
> +unsigned pic32_uart_get_char(pic32_t *s, int unit)
> +{
> + uart_t *u = &s->uart[unit];
> + unsigned value;
> +
> + /* Read a byte from input queue. */
> + value = u->rxbyte;
> + VALUE(u->sta) &= ~PIC32_USTA_URXDA;
> +
> + s->irq_clear(s, u->irq + UART_IRQ_RX);
> + return value;
> +}
> +
> +/*
> + * Write to UxTXREG register.
> + */
> +void pic32_uart_put_char(pic32_t *s, int unit, unsigned char byte)
> +{
> + uart_t *u = &s->uart[unit];
> +
> + if (!u->chr) {
> + printf("--- %s(unit = %u) serial port not configured\n",
> + __func__, unit);
helpful messages should use qemu_log. I would wrap this conditional
compile macro so it can be turned off.
> + return;
> + }
> +
> + /* Send the byte. */
> + if (qemu_chr_fe_write(u->chr, &byte, 1) != 1) {
qemu_chr_fe_write_all will brute force it for you with a busy-wait
which is probably better than dropping the char.
> + /* TODO: suspend simulation until serial port ready. */
> + printf("--- %s(unit = %u) failed\n", __func__, unit);
> + return;
> + }
> +
> + if ((VALUE(u->mode) & PIC32_UMODE_ON) &&
> + (VALUE(u->sta) & PIC32_USTA_UTXEN))
> + {
> + VALUE(u->sta) |= PIC32_USTA_UTXBF;
> + VALUE(u->sta) &= ~PIC32_USTA_TRMT;
> +
> + /* Generate TX interrupt with some delay. */
Why? generally we don't try and emulate such delays. Do you have
guests that depend on this delay?
Regards,
Peter
> + timer_mod(u->transmit_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
> + get_ticks_per_sec() / 5000);
> + u->oactive = 1;
> + }
> +}
> +
> +/*
> + * Called before reading a value of UxBRG, UxMODE or UxSTA registers.
> + */
> +void pic32_uart_poll_status(pic32_t *s, int unit)
> +{
> + uart_t *u = &s->uart[unit];
> +
> + /* Keep receiver idle, transmit shift register always empty. */
> + VALUE(u->sta) |= PIC32_USTA_RIDLE;
> +
> + /*printf("<%x>", VALUE(u->sta)); fflush(stdout);*/
> +}
> +
> +/*
> + * Write to UxMODE register.
> + */
> +void pic32_uart_update_mode(pic32_t *s, int unit)
> +{
> + uart_t *u = &s->uart[unit];
> +
> + if (!(VALUE(u->mode) & PIC32_UMODE_ON)) {
> + s->irq_clear(s, u->irq + UART_IRQ_RX);
> + s->irq_clear(s, u->irq + UART_IRQ_TX);
> + VALUE(u->sta) &= ~(PIC32_USTA_URXDA | PIC32_USTA_FERR |
> + PIC32_USTA_PERR | PIC32_USTA_UTXBF);
> + VALUE(u->sta) |= PIC32_USTA_RIDLE | PIC32_USTA_TRMT;
> + }
> +}
> +
> +/*
> + * Write to UxSTA register.
> + */
> +void pic32_uart_update_status(pic32_t *s, int unit)
> +{
> + uart_t *u = &s->uart[unit];
> +
> + if (!(VALUE(u->sta) & PIC32_USTA_URXEN)) {
> + s->irq_clear(s, u->irq + UART_IRQ_RX);
> + VALUE(u->sta) &= ~(PIC32_USTA_URXDA | PIC32_USTA_FERR |
> + PIC32_USTA_PERR);
> + }
> + if (!(VALUE(u->sta) & PIC32_USTA_UTXEN)) {
> + s->irq_clear(s, u->irq + UART_IRQ_TX);
> + VALUE(u->sta) &= ~PIC32_USTA_UTXBF;
> + VALUE(u->sta) |= PIC32_USTA_TRMT;
> + }
> +}
> +
> +/*
> + * Return a number of free bytes in the receive FIFO.
> + */
> +static int uart_can_receive(void *opaque)
> +{
> + uart_t *u = opaque;
> + pic32_t *s = u->mcu; /* used in VALUE() */
> +
> + /*printf("--- %s(%p) called\n", __func__, u);*/
> +
> + if (!(VALUE(u->mode) & PIC32_UMODE_ON) ||
> + !(VALUE(u->sta) & PIC32_USTA_URXEN)) {
> + /* UART disabled. */
> + return 0;
> + }
> +
> + if (VALUE(u->sta) & PIC32_USTA_URXDA) {
> + /* Receive buffer full. */
> + return 0;
> + }
> + return 1;
> +}
> +
> +/*
> + * Process the received data.
> + */
> +static void uart_receive(void *opaque, const uint8_t *buf, int size)
> +{
> + uart_t *u = opaque;
> + pic32_t *s = u->mcu; /* used in VALUE() */
> +
> + /*printf("--- %s(%p) called\n", __func__, u);*/
> + if (!(VALUE(u->mode) & PIC32_UMODE_ON) ||
> + !(VALUE(u->sta) & PIC32_USTA_URXEN)) {
> + /* UART disabled. */
> + return;
> + }
> +
> + if (VALUE(u->sta) & PIC32_USTA_URXDA) {
> + /* Receive buffer full. */
> + return;
> + }
> +
> + u->rxbyte = buf[0];
> + VALUE(u->sta) |= PIC32_USTA_URXDA;
> +
> + /* Activate receive interrupt. */
> + s->irq_raise(s, u->irq + UART_IRQ_RX);
> +}
> +
> +/*
> + * Activate the transmit interrupt.
> + */
> +static void uart_timeout(void *opaque)
> +{
> + uart_t *u = opaque;
> + pic32_t *s = u->mcu; /* used in VALUE() */
> +
> + /*printf("--- %s() called\n", __func__);*/
> + if (u->oactive) {
> + /* Activate transmit interrupt. */
> + /*printf("uart%u: raise tx irq %u\n", unit, u->irq + UART_IRQ_TX);*/
> + if ((VALUE(u->mode) & PIC32_UMODE_ON) &&
> + (VALUE(u->sta) & PIC32_USTA_UTXEN)) {
> + s->irq_raise(s, u->irq + UART_IRQ_TX);
> + }
> + VALUE(u->sta) &= ~PIC32_USTA_UTXBF;
> + VALUE(u->sta) |= PIC32_USTA_TRMT;
> + u->oactive = 0;
> + }
> +}
> +
> +/*
> + * Initialize the UART data structure.
> + */
> +void pic32_uart_init(pic32_t *s, int unit, int irq, int sta, int mode)
> +{
> + uart_t *u = &s->uart[unit];
> +
> + u->mcu = s;
> + u->irq = irq;
> + u->sta = sta;
> + u->mode = mode;
> + u->transmit_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, uart_timeout, u);
> +
> + if (unit >= MAX_SERIAL_PORTS) {
> + /* Cannot instantiate so many serial ports. */
> + u->chr = 0;
> + return;
> + }
> + u->chr = serial_hds[unit];
> +
> + /* Setup callback functions. */
> + if (u->chr) {
> + qemu_chr_add_handlers(u->chr, uart_can_receive, uart_receive, NULL,
> u);
> + }
> +}
> --
> 2.2.2
>
>
- Re: [Qemu-devel] [PATCH pic32 v3 03/16] pic32: add support for external interrupt controller mode (EIC), (continued)
- [Qemu-devel] [PATCH pic32 v3 04/16] pic32: add two MIPS processor variants: M4K and microAptivUP, Serge Vakulenko, 2015/07/06
- [Qemu-devel] [PATCH pic32 v3 05/16] pic32: add file pic32_peripherals.h, Serge Vakulenko, 2015/07/06
- [Qemu-devel] [PATCH pic32 v3 06/16] pic32: add file pic32mx.h, Serge Vakulenko, 2015/07/06
- [Qemu-devel] [PATCH pic32 v3 10/16] pic32: add file pic32_load_hex.c, Serge Vakulenko, 2015/07/06
- [Qemu-devel] [PATCH pic32 v3 12/16] pic32: add file pic32_gpio.c, Serge Vakulenko, 2015/07/06
- [Qemu-devel] [PATCH pic32 v3 11/16] pic32: add file pic32_uart.c, Serge Vakulenko, 2015/07/06
- Re: [Qemu-devel] [PATCH pic32 v3 11/16] pic32: add file pic32_uart.c,
Peter Crosthwaite <=
- [Qemu-devel] [PATCH pic32 v3 08/16] pic32: add file mips_pic32mx7.c, Serge Vakulenko, 2015/07/06
- [Qemu-devel] [PATCH pic32 v3 13/16] pic32: add file pic32_spi.c, Serge Vakulenko, 2015/07/06
- [Qemu-devel] [PATCH pic32 v3 07/16] pic32: add file pic32mz.h, Serge Vakulenko, 2015/07/06
- [Qemu-devel] [PATCH pic32 v3 14/16] pic32: add file pic32_sdcard.c, Serge Vakulenko, 2015/07/06
- [Qemu-devel] [PATCH pic32 v3 16/16] pic32: update makefiles to cover pic32 support, Serge Vakulenko, 2015/07/06
- [Qemu-devel] [PATCH pic32 v3 15/16] pic32: add file pic32_ethernet.c, Serge Vakulenko, 2015/07/06
- [Qemu-devel] [PATCH pic32 v3 09/16] pic32: add file mips_pic32mz.c, Serge Vakulenko, 2015/07/06