serial: prepare for I/O thread integration

pull/1/head
Felix Kopp 4 years ago
parent 2a899210c6
commit dbda35d82a
No known key found for this signature in database
GPG Key ID: C478BA0A85F75728

@ -1,15 +1,18 @@
/* SPDX-License-Identifier: BSD-3-Clause */
/* See the end of this file for copyright, licensing, and warranty information. */
#include <ardix/io.h>
#include <ardix/ringbuf.h>
#include <ardix/serial.h>
#include <ardix/string.h>
#include <ardix/types.h>
#include <ardix/ringbuf.h>
#include <arch/at91sam3x8e/hardware.h>
#include <arch/at91sam3x8e/interrupt.h>
#include <arch/at91sam3x8e/sched.h>
#include <arch/serial.h>
#include <errno.h>
#include <stddef.h>
struct arch_serial_interface arch_serial_default_interface = {
@ -86,35 +89,49 @@ void arch_serial_exit(struct serial_interface *interface)
interface->id = -1;
}
int arch_serial_txbuf_rotate(struct serial_interface *interface)
int arch_serial_txbuf_rotate(struct arch_serial_interface *interface)
{
struct arch_serial_interface *arch_iface = to_arch_serial_interface(interface);
if (!arch_iface->hw_txrdy)
if (!interface->hw_txrdy)
return -EBUSY;
arch_iface->hw_txrdy = false;
interface->hw_txrdy = false;
if (arch_iface->current_txbuf == ARCH_SERIAL_BUF1) {
if (interface->current_txbuf == ARCH_SERIAL_BUF1) {
/* buf1 has been written to, DMA has been reading from buf2 */
arch_iface->current_txbuf = ARCH_SERIAL_BUF2;
interface->current_txbuf = ARCH_SERIAL_BUF2;
/* pass buf1 to the DMA controller */
REG_UART_PDC_TPR = (uint32_t)&arch_iface->tx1[0];
REG_UART_PDC_TPR = (uint32_t)&interface->tx1[0];
} else {
/* buf2 has been written to, DMA has been reading from buf1 */
arch_iface->current_txbuf = ARCH_SERIAL_BUF1;
interface->current_txbuf = ARCH_SERIAL_BUF1;
/* pass buf2 to the DMA controller */
REG_UART_PDC_TPR = (uint32_t)&arch_iface->tx2[0];
REG_UART_PDC_TPR = (uint32_t)&interface->tx2[0];
}
REG_UART_PDC_TCR = arch_iface->current_len;
arch_iface->current_len = 0;
/* re-enable the transmitter DMA controller */
REG_UART_PDC_PTCR = REG_UART_PDC_PTCR_TXTEN_MASK;
REG_UART_PDC_TCR = interface->current_len;
interface->current_len = 0;
return 0;
}
void io_serial_buf_update(struct serial_interface *interface)
{
void *buf;
struct arch_serial_interface *arch_iface = to_arch_serial_interface(interface);
if (arch_iface->current_len)
arch_serial_txbuf_rotate(arch_iface);
if (!arch_iface->current_len) {
if (arch_iface->current_txbuf == ARCH_SERIAL_BUF1)
buf = &arch_iface->tx1[0];
else
buf = &arch_iface->tx2[0];
sched_atomic_enter();
arch_iface->current_len = (uint16_t)ringbuf_read(buf, interface->tx, SERIAL_BUFSZ);
sched_atomic_leave();
}
}
void irq_uart(void)
{
uint8_t tmp;
@ -123,7 +140,7 @@ void irq_uart(void)
/* RX has received a byte, store it into the ring buffer */
if (state & REG_UART_SR_RXRDY_MASK) {
tmp = REG_UART_RHR;
ringbuf_write(serial_default_interface->rx, &tmp, sizeof(tmp));
ringbuf_write(arch_serial_default_interface.interface.rx, &tmp, sizeof(tmp));
}
/* TX buffer has been sent */

@ -4,7 +4,6 @@
#pragma once
#include <arch/at91sam3x8e/interrupt.h>
#include <ardix/sched.h>
#include <toolchain.h>
/** Enter atomic context, i.e. disable preemption */

@ -8,23 +8,6 @@
int arch_serial_init(struct serial_interface *interface);
void arch_serial_exit(struct serial_interface *interface);
/**
* Notify the serial interface about new data in the TX buffer.
* This is required because if the transmitter is sleeping due to the TX queue being empty,
* we need some way to tell it to turn on and fire interrupts again.
*
* @param interface: The serial interface to notify about new data.
*/
void arch_serial_notify(struct serial_interface *interface);
/**
* Copy the current TX ring buffer content to a new hardware buffer.
*
* @param interface: The serial interface to rotate the hardware buffer of.
* @returns 0 on success, or a negative number on failure.
*/
int arch_serial_txbuf_rotate(struct serial_interface *interface);
#ifdef ARCH_AT91SAM3X8E
#include <arch/at91sam3x8e/serial.h>
#else

@ -0,0 +1,49 @@
/* SPDX-License-Identifier: BSD-3-Clause */
/* See the end of this file for copyright, licensing, and warranty information. */
#pragma once
#include <ardix/serial.h>
/**
* Initialize the I/O thread and subsystems.
* Must be called after all I/O components have been initialized.
*
* @returns 0 on success, or a negative number on failure.
*/
int io_init(void);
void io_thread_entry(void);
/**
* Update the hardware serial buffers if necessary.
* This includes copying to and from the main ring buffers.
*
* @param interface: The serial interface.
*/
void io_serial_buf_update(struct serial_interface *interface);
/*
* Copyright (c) 2020 Felix Kopp <sandtler@sandtler.club>
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its contributors may be
* used to endorse or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
Loading…
Cancel
Save