summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/powerpc/mpc55xxevb
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2018-04-19 06:28:01 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2018-04-20 13:08:32 +0200
commitd7d66d7d4523b904c8ccc6aea3709dc0d5aa5bdc (patch)
treecaa54b4229e86a68c84ab5961af34e087dce5302 /c/src/lib/libbsp/powerpc/mpc55xxevb
parentbsps/powerpc: Move shared btimer support (diff)
downloadrtems-d7d66d7d4523b904c8ccc6aea3709dc0d5aa5bdc.tar.bz2
bsps: Move console drivers to bsps
This patch is a part of the BSP source reorganization. Update #3285.
Diffstat (limited to 'c/src/lib/libbsp/powerpc/mpc55xxevb')
-rw-r--r--c/src/lib/libbsp/powerpc/mpc55xxevb/Makefile.am8
-rw-r--r--c/src/lib/libbsp/powerpc/mpc55xxevb/console/console-config.c41
-rw-r--r--c/src/lib/libbsp/powerpc/mpc55xxevb/console/console-esci.c354
-rw-r--r--c/src/lib/libbsp/powerpc/mpc55xxevb/console/console-generic.c168
-rw-r--r--c/src/lib/libbsp/powerpc/mpc55xxevb/console/console-linflex.c417
5 files changed, 4 insertions, 984 deletions
diff --git a/c/src/lib/libbsp/powerpc/mpc55xxevb/Makefile.am b/c/src/lib/libbsp/powerpc/mpc55xxevb/Makefile.am
index a33b0c6c23..9f6798c1bb 100644
--- a/c/src/lib/libbsp/powerpc/mpc55xxevb/Makefile.am
+++ b/c/src/lib/libbsp/powerpc/mpc55xxevb/Makefile.am
@@ -72,10 +72,10 @@ librtemsbsp_a_SOURCES += startup/start-watchdog.c
librtemsbsp_a_SOURCES +=../../../../../../bsps/powerpc/mpc55xxevb/clock/clock-config.c
# console
-librtemsbsp_a_SOURCES += console/console-config.c
-librtemsbsp_a_SOURCES += console/console-esci.c
-librtemsbsp_a_SOURCES += console/console-generic.c
-librtemsbsp_a_SOURCES += console/console-linflex.c
+librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/mpc55xxevb/console/console-config.c
+librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/mpc55xxevb/console/console-esci.c
+librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/mpc55xxevb/console/console-generic.c
+librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/mpc55xxevb/console/console-linflex.c
# irq_generic
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/irq/irq-default-handler.c
diff --git a/c/src/lib/libbsp/powerpc/mpc55xxevb/console/console-config.c b/c/src/lib/libbsp/powerpc/mpc55xxevb/console/console-config.c
deleted file mode 100644
index d0ea250917..0000000000
--- a/c/src/lib/libbsp/powerpc/mpc55xxevb/console/console-config.c
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (c) 2011-2012 embedded brains GmbH. All rights reserved.
- *
- * embedded brains GmbH
- * Obere Lagerstr. 30
- * 82178 Puchheim
- * Germany
- * <rtems@embedded-brains.de>
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
- */
-
-#include <bsp.h>
-#include <bsp/console-generic.h>
-#include <bsp/console-esci.h>
-#include <bsp/console-linflex.h>
-
-CONSOLE_GENERIC_INFO_TABLE = {
- #ifdef MPC55XX_HAS_ESCI
- CONSOLE_GENERIC_INFO(mpc55xx_esci_devices + 0, &mpc55xx_esci_callbacks, "/dev/ttyS0")
- #ifdef ESCI_B
- , CONSOLE_GENERIC_INFO(mpc55xx_esci_devices + 1, &mpc55xx_esci_callbacks, "/dev/ttyS1")
- #endif
- #ifdef ESCI_C
- , CONSOLE_GENERIC_INFO(mpc55xx_esci_devices + 2, &mpc55xx_esci_callbacks, "/dev/ttyS2")
- #endif
- #ifdef ESCI_D
- , CONSOLE_GENERIC_INFO(mpc55xx_esci_devices + 3, &mpc55xx_esci_callbacks, "/dev/ttyS3")
- #endif
- #endif
- #ifdef MPC55XX_HAS_LINFLEX
- CONSOLE_GENERIC_INFO(mpc55xx_linflex_devices + 0, &mpc55xx_linflex_callbacks, "/dev/ttyS0"),
- CONSOLE_GENERIC_INFO(mpc55xx_linflex_devices + 1, &mpc55xx_linflex_callbacks, "/dev/ttyS1")
- #endif
-};
-
-CONSOLE_GENERIC_INFO_COUNT;
-
-CONSOLE_GENERIC_MINOR(MPC55XX_CONSOLE_MINOR);
diff --git a/c/src/lib/libbsp/powerpc/mpc55xxevb/console/console-esci.c b/c/src/lib/libbsp/powerpc/mpc55xxevb/console/console-esci.c
deleted file mode 100644
index 9e6646fb65..0000000000
--- a/c/src/lib/libbsp/powerpc/mpc55xxevb/console/console-esci.c
+++ /dev/null
@@ -1,354 +0,0 @@
-/**
- * @file
- *
- * @brief Console ESCI implementation.
- */
-
-/*
- * Copyright (c) 2008-2012 embedded brains GmbH. All rights reserved.
- *
- * embedded brains GmbH
- * Obere Lagerstr. 30
- * 82178 Puchheim
- * Germany
- * <rtems@embedded-brains.de>
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
- */
-
-#include <bsp/console-esci.h>
-
-#include <bsp.h>
-#include <bsp/fatal.h>
-#include <bsp/irq.h>
-
-#ifdef MPC55XX_HAS_ESCI
-
-mpc55xx_esci_context mpc55xx_esci_devices [] = {
- {
- .regs = &ESCI_A,
- .irq = MPC55XX_IRQ_ESCI(0)
- }
- #ifdef ESCI_B
- , {
- .regs = &ESCI_B,
- .irq = MPC55XX_IRQ_ESCI(1)
- }
- #endif
- #ifdef ESCI_C
- , {
- .regs = &ESCI_C,
- .irq = MPC55XX_IRQ_ESCI(2)
- }
- #endif
- #ifdef ESCI_D
- , {
- .regs = &ESCI_D,
- .irq = MPC55XX_IRQ_ESCI(3)
- }
- #endif
-};
-
-static void mpc55xx_esci_poll_write(int minor, char c)
-{
- mpc55xx_esci_context *self = console_generic_get_context(minor);
- const union ESCI_SR_tag clear_tdre = { .B = { .TDRE = 1 } };
- volatile struct ESCI_tag *regs = self->regs;
- rtems_interrupt_level level;
- bool done = false;
- bool wait_for_transmit_done = false;
-
- rtems_interrupt_disable(level);
- if (self->transmit_nest_level == 0) {
- union ESCI_CR1_tag cr1 = { .R = regs->CR1.R };
-
- if (cr1.B.TIE != 0) {
- cr1.B.TIE = 0;
- regs->CR1.R = cr1.R;
- wait_for_transmit_done = !self->transmit_in_progress;
- self->transmit_nest_level = 1;
- }
- } else {
- ++self->transmit_nest_level;
- }
- rtems_interrupt_enable(level);
-
- while (!done) {
- rtems_interrupt_disable(level);
- bool tx = self->transmit_in_progress;
- if (!tx || (tx && regs->SR.B.TDRE)) {
- regs->SR.R = clear_tdre.R;
- regs->DR.B.D = c;
- self->transmit_in_progress = true;
- done = true;
- }
- rtems_interrupt_enable(level);
- }
-
- done = false;
- while (!done) {
- rtems_interrupt_disable(level);
- if (wait_for_transmit_done) {
- if (regs->SR.B.TDRE) {
- regs->SR.R = clear_tdre.R;
- self->transmit_in_progress = false;
- done = true;
- }
- } else {
- done = true;
- }
-
- if (done && self->transmit_nest_level > 0) {
- --self->transmit_nest_level;
-
- if (self->transmit_nest_level == 0) {
- union ESCI_CR1_tag cr1 = { .R = regs->CR1.R };
-
- cr1.B.TIE = 1;
- regs->CR1.R = cr1.R;
- }
- }
- rtems_interrupt_enable(level);
- }
-}
-
-static inline void mpc55xx_esci_interrupts_clear_and_enable(
- mpc55xx_esci_context *self
-)
-{
- volatile struct ESCI_tag *regs = self->regs;
- union ESCI_CR1_tag cr1 = MPC55XX_ZERO_FLAGS;
- rtems_interrupt_level level;
-
- rtems_interrupt_disable(level);
- cr1.R = regs->CR1.R;
- cr1.B.RIE = 1;
- cr1.B.TIE = 1;
- regs->CR1.R = cr1.R;
- regs->SR.R = regs->SR.R;
- rtems_interrupt_enable(level);
-}
-
-static inline void mpc55xx_esci_interrupts_disable(mpc55xx_esci_context *self)
-{
- volatile struct ESCI_tag *regs = self->regs;
- union ESCI_CR1_tag cr1 = MPC55XX_ZERO_FLAGS;
- rtems_interrupt_level level;
-
- rtems_interrupt_disable(level);
- cr1.R = regs->CR1.R;
- cr1.B.RIE = 0;
- cr1.B.TIE = 0;
- regs->CR1.R = cr1.R;
- rtems_interrupt_enable(level);
-}
-
-static void mpc55xx_esci_interrupt_handler(void *arg)
-{
- mpc55xx_esci_context *self = arg;
- volatile struct ESCI_tag *regs = self->regs;
- union ESCI_SR_tag sr = MPC55XX_ZERO_FLAGS;
- union ESCI_SR_tag active = MPC55XX_ZERO_FLAGS;
- rtems_interrupt_level level;
-
- /* Status */
- sr.R = regs->SR.R;
-
- /* Receive data register full? */
- if (sr.B.RDRF != 0) {
- active.B.RDRF = 1;
- }
-
- /* Transmit data register empty? */
- if (sr.B.TDRE != 0) {
- active.B.TDRE = 1;
- }
-
- /* Clear flags */
- rtems_interrupt_disable(level);
- regs->SR.R = active.R;
- self->transmit_in_progress = false;
- rtems_interrupt_enable(level);
-
- /* Enqueue */
- if (active.B.RDRF != 0) {
- char c = regs->DR.B.D;
- rtems_termios_enqueue_raw_characters(self->tty, &c, 1);
- }
-
- /* Dequeue */
- if (active.B.TDRE != 0) {
- rtems_termios_dequeue_characters(self->tty, 1);
- }
-}
-
-static int mpc55xx_esci_set_attributes(int minor, const struct termios *t)
-{
- mpc55xx_esci_context *self = console_generic_get_context(minor);
- volatile struct ESCI_tag *regs = self->regs;
- union ESCI_CR1_tag cr1 = { .R = regs->CR1.R };
- union ESCI_CR2_tag cr2 = MPC55XX_ZERO_FLAGS;
- rtems_termios_baud_t br = rtems_termios_baud_to_number(t->c_ospeed);
-
- /* Enable module */
- cr2.B.MDIS = 0;
-
- /* Interrupts */
- cr1.B.TCIE = 0;
- cr1.B.ILIE = 0;
- cr2.B.IEBERR = 0;
- cr2.B.ORIE = 0;
- cr2.B.NFIE = 0;
- cr2.B.FEIE = 0;
- cr2.B.PFIE = 0;
-
- /* Disable receiver wake-up standby */
- cr1.B.RWU = 0;
-
- /* Disable DMA channels */
- cr2.B.RXDMA = 0;
- cr2.B.TXDMA = 0;
-
- /* Idle line type */
- cr1.B.ILT = 0;
-
- /* Disable loops */
- cr1.B.LOOPS = 0;
-
- /* Enable or disable receiver */
- cr1.B.RE = (t->c_cflag & CREAD) ? 1 : 0;
-
- /* Enable transmitter */
- cr1.B.TE = 1;
-
- /* Baud rate */
- if (br > 0) {
- br = bsp_clock_speed / (16 * br);
- br = (br > 8191) ? 8191 : br;
- } else {
- br = 0;
- }
- cr1.B.SBR = br;
-
- /* Number of data bits */
- if ((t->c_cflag & CSIZE) != CS8) {
- return -1;
- }
- cr1.B.M = 0;
-
- /* Parity */
- cr1.B.PE = (t->c_cflag & PARENB) ? 1 : 0;
- cr1.B.PT = (t->c_cflag & PARODD) ? 1 : 0;
-
- /* Stop bits */
- if (t->c_cflag & CSTOPB ) {
- /* Two stop bits */
- return -1;
- }
-
- /* Disable LIN */
- regs->LCR.R = 0;
-
- /* Set control registers */
- regs->CR2.R = cr2.R;
- regs->CR1.R = cr1.R;
-
- return 0;
-}
-
-static int mpc55xx_esci_first_open(int major, int minor, void *arg)
-{
- rtems_status_code sc = RTEMS_SUCCESSFUL;
- int rv = 0;
- mpc55xx_esci_context *self = console_generic_get_context(minor);
- struct rtems_termios_tty *tty = console_generic_get_tty_at_open(arg);
-
- self->tty = tty;
-
- rv = rtems_termios_set_initial_baud(tty, BSP_DEFAULT_BAUD_RATE);
- if (rv != 0) {
- bsp_fatal(MPC55XX_FATAL_CONSOLE_ESCI_BAUD);
- }
-
- rv = mpc55xx_esci_set_attributes(minor, &tty->termios);
- if (rv != 0) {
- bsp_fatal(MPC55XX_FATAL_CONSOLE_ESCI_ATTRIBUTES);
- }
-
- sc = mpc55xx_interrupt_handler_install(
- self->irq,
- "eSCI",
- RTEMS_INTERRUPT_UNIQUE,
- MPC55XX_INTC_DEFAULT_PRIORITY,
- mpc55xx_esci_interrupt_handler,
- self
- );
- if (sc != RTEMS_SUCCESSFUL) {
- bsp_fatal(MPC55XX_FATAL_CONSOLE_ESCI_IRQ_INSTALL);
- }
-
- mpc55xx_esci_interrupts_clear_and_enable(self);
- self->transmit_in_progress = false;
-
- return 0;
-}
-
-static int mpc55xx_esci_last_close(int major, int minor, void* arg)
-{
- mpc55xx_esci_context *self = console_generic_get_context(minor);
-
- mpc55xx_esci_interrupts_disable(self);
- self->tty = NULL;
-
- return 0;
-}
-
-static int mpc55xx_esci_poll_read(int minor)
-{
- mpc55xx_esci_context *self = console_generic_get_context(minor);
- volatile struct ESCI_tag *regs = self->regs;
- union ESCI_SR_tag sr = MPC55XX_ZERO_FLAGS;
- rtems_interrupt_level level;
- int c = -1;
-
- rtems_interrupt_disable(level);
- if (regs->SR.B.RDRF != 0) {
- /* Clear flag */
- sr.B.RDRF = 1;
- regs->SR.R = sr.R;
-
- /* Read */
- c = regs->DR.B.D;
- }
- rtems_interrupt_enable(level);
-
- return c;
-}
-
-static int mpc55xx_esci_write(int minor, const char *out, size_t n)
-{
- if (n > 0) {
- mpc55xx_esci_context *self = console_generic_get_context(minor);
-
- self->regs->DR.B.D = out [0];
- self->transmit_in_progress = true;
- }
-
- return 0;
-}
-
-const console_generic_callbacks mpc55xx_esci_callbacks = {
- .termios_callbacks = {
- .firstOpen = mpc55xx_esci_first_open,
- .lastClose = mpc55xx_esci_last_close,
- .write = mpc55xx_esci_write,
- .setAttributes = mpc55xx_esci_set_attributes,
- .outputUsesInterrupts = TERMIOS_IRQ_DRIVEN
- },
- .poll_read = mpc55xx_esci_poll_read,
- .poll_write = mpc55xx_esci_poll_write
-};
-
-#endif /* MPC55XX_HAS_ESCI */
diff --git a/c/src/lib/libbsp/powerpc/mpc55xxevb/console/console-generic.c b/c/src/lib/libbsp/powerpc/mpc55xxevb/console/console-generic.c
deleted file mode 100644
index 71385adf2b..0000000000
--- a/c/src/lib/libbsp/powerpc/mpc55xxevb/console/console-generic.c
+++ /dev/null
@@ -1,168 +0,0 @@
-/**
- * @file
- *
- * @brief Generic console driver implementation.
- */
-
-/*
- * Copyright (c) 2011 embedded brains GmbH. All rights reserved.
- *
- * embedded brains GmbH
- * Obere Lagerstr. 30
- * 82178 Puchheim
- * Germany
- * <rtems@embedded-brains.de>
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
- */
-
-#include <sys/cdefs.h>
-
-#include <bsp.h>
-#include <bsp/console-generic.h>
-#include <bsp/fatal.h>
-
-#include <rtems/bspIo.h>
-#include <rtems/console.h>
-
-static const struct termios console_generic_termios = {
- .c_cflag = CS8 | CREAD | CLOCAL | __CONCAT(B, BSP_DEFAULT_BAUD_RATE)
-};
-
-static void console_generic_char_out(char c)
-{
- int minor = (int) console_generic_minor;
- const console_generic_callbacks *cb =
- console_generic_info_table [minor].callbacks;
-
- (*cb->poll_write)(minor, c);
-}
-
-static int console_generic_char_in(void)
-{
- int minor = (int) console_generic_minor;
- const console_generic_callbacks *cb =
- console_generic_info_table [minor].callbacks;
-
- return (*cb->poll_read)(minor);
-}
-
-static void console_generic_char_out_do_init(void)
-{
- int minor = (int) console_generic_minor;
- const console_generic_callbacks *cb =
- console_generic_info_table [minor].callbacks;
- const struct termios *term = &console_generic_termios;
-
- BSP_output_char = console_generic_char_out;
- (*cb->termios_callbacks.setAttributes)(minor, term);
-}
-
-static void console_generic_char_out_init(char c)
-{
- console_generic_char_out_do_init();
- console_generic_char_out(c);
-}
-
-rtems_device_driver console_initialize(
- rtems_device_major_number major,
- rtems_device_minor_number minor,
- void *arg
-)
-{
- rtems_status_code sc = RTEMS_SUCCESSFUL;
- const console_generic_info *info_table = console_generic_info_table;
- rtems_device_minor_number count = console_generic_info_count;
- rtems_device_minor_number console = console_generic_minor;
-
- if (count <= 0) {
- bsp_fatal(MPC55XX_FATAL_CONSOLE_GENERIC_COUNT);
- }
-
- rtems_termios_initialize();
-
- for (minor = 0; minor < count; ++minor) {
- const console_generic_info *info = info_table + minor;
-
- sc = rtems_io_register_name(info->device_path, major, minor);
- if (sc != RTEMS_SUCCESSFUL) {
- bsp_fatal(MPC55XX_FATAL_CONSOLE_GENERIC_REGISTER);
- }
- }
-
- sc = rtems_io_register_name(CONSOLE_DEVICE_NAME, major, console);
- if (sc != RTEMS_SUCCESSFUL) {
- bsp_fatal(MPC55XX_FATAL_CONSOLE_GENERIC_REGISTER_CONSOLE);
- }
-
- console_generic_char_out_do_init();
-
- return sc;
-}
-
-rtems_device_driver console_open(
- rtems_device_major_number major,
- rtems_device_minor_number minor,
- void *arg
-)
-{
- rtems_status_code sc = RTEMS_SUCCESSFUL;
- rtems_device_minor_number count = console_generic_info_count;
-
- if (minor < count) {
- const console_generic_info *info = &console_generic_info_table [minor];
-
- sc = rtems_termios_open(
- major,
- minor,
- arg,
- &info->callbacks->termios_callbacks
- );
- } else {
- sc = RTEMS_INVALID_ID;
- }
-
- return sc;
-}
-
-rtems_device_driver console_close(
- rtems_device_major_number major,
- rtems_device_minor_number minor,
- void *arg
-)
-{
- return rtems_termios_close(arg);
-}
-
-rtems_device_driver console_read(
- rtems_device_major_number major,
- rtems_device_minor_number minor,
- void *arg
-)
-{
- return rtems_termios_read(arg);
-}
-
-rtems_device_driver console_write(
- rtems_device_major_number major,
- rtems_device_minor_number minor,
- void *arg
-)
-{
- return rtems_termios_write(arg);
-}
-
-rtems_device_driver console_control(
- rtems_device_major_number major,
- rtems_device_minor_number minor,
- void *arg
-)
-{
- return rtems_termios_ioctl(arg);
-}
-
-BSP_output_char_function_type BSP_output_char = console_generic_char_out_init;
-
-BSP_polling_getchar_function_type BSP_poll_char = console_generic_char_in;
diff --git a/c/src/lib/libbsp/powerpc/mpc55xxevb/console/console-linflex.c b/c/src/lib/libbsp/powerpc/mpc55xxevb/console/console-linflex.c
deleted file mode 100644
index 02978be524..0000000000
--- a/c/src/lib/libbsp/powerpc/mpc55xxevb/console/console-linflex.c
+++ /dev/null
@@ -1,417 +0,0 @@
-/**
- * @file
- *
- * @brief Console LINFlexD implementation.
- */
-
-/*
- * Copyright (c) 2011-2014 embedded brains GmbH. All rights reserved.
- *
- * embedded brains GmbH
- * Dornierstr. 4
- * 82178 Puchheim
- * Germany
- * <rtems@embedded-brains.de>
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
- */
-
-#include <bsp/console-linflex.h>
-
-#include <bsp.h>
-#include <bsp/fatal.h>
-#include <bsp/irq.h>
-
-#ifdef MPC55XX_HAS_LINFLEX
-
-mpc55xx_linflex_context mpc55xx_linflex_devices [] = {
- {
- .regs = &LINFLEX0,
- .irq_rxi = MPC55XX_IRQ_LINFLEX_RXI(0),
- .irq_txi = MPC55XX_IRQ_LINFLEX_TXI(0),
- .irq_err = MPC55XX_IRQ_LINFLEX_ERR(0),
- .tx_pcr_register = &((SIU_tag *) &SIUL)->PCR18,
- .tx_pa_value = 1,
- .rx_pcr_register = &((SIU_tag *) &SIUL)->PCR19,
- .rx_psmi_register = &((SIU_tag *) &SIUL)->PSMI31,
- .rx_padsel_value = 0
- }, {
- .regs = &LINFLEX1,
- .irq_rxi = MPC55XX_IRQ_LINFLEX_RXI(1),
- .irq_txi = MPC55XX_IRQ_LINFLEX_TXI(1),
- .irq_err = MPC55XX_IRQ_LINFLEX_ERR(1),
- .tx_pcr_register = &((SIU_tag *) &SIUL)->PCR94,
- .tx_pa_value = 1,
- .rx_pcr_register = &((SIU_tag *) &SIUL)->PCR95,
- .rx_psmi_register = &((SIU_tag *) &SIUL)->PSMI32,
- .rx_padsel_value = 2
- }
-};
-
-static void enter_init_mode(volatile LINFLEX_tag *regs)
-{
- LINFLEX_LINCR1_32B_tag cr1 = { .R = regs->LINCR1.R };
- cr1.B.SLEEP = 0;
- cr1.B.INIT = 1;
- regs->LINCR1.R = cr1.R;
-}
-
-static void enter_active_mode(volatile LINFLEX_tag *regs)
-{
- LINFLEX_LINCR1_32B_tag cr1 = { .R = regs->LINCR1.R };
- cr1.B.SLEEP = 0;
- cr1.B.INIT = 0;
- regs->LINCR1.R = cr1.R;
-}
-
-static void enter_sleep_mode(volatile LINFLEX_tag *regs)
-{
- LINFLEX_LINCR1_32B_tag cr1 = { .R = regs->LINCR1.R };
- cr1.B.SLEEP = 1;
- cr1.B.INIT = 0;
- regs->LINCR1.R = cr1.R;
-}
-
-static void mpc55xx_linflex_poll_write(int minor, char c)
-{
- mpc55xx_linflex_context *self = console_generic_get_context(minor);
- volatile LINFLEX_tag *regs = self->regs;
- const LINFLEX_UARTSR_32B_tag clear_dtf = { .B = { .DTF_TFF = 1 } };
- rtems_interrupt_level level;
- bool done = false;
- bool wait_for_transmit_done = false;
-
- rtems_interrupt_disable(level);
- if (self->transmit_nest_level == 0) {
- LINFLEX_LINIER_32B_tag ier = { .R = regs->LINIER.R };
-
- if (ier.B.DTIE != 0) {
- ier.B.DTIE = 0;
- regs->LINIER.R = ier.R;
- wait_for_transmit_done = !self->transmit_in_progress;
- self->transmit_nest_level = 1;
- }
- } else {
- ++self->transmit_nest_level;
- }
- rtems_interrupt_enable(level);
-
- while (!done) {
- rtems_interrupt_disable(level);
- bool tx = self->transmit_in_progress;
- if (!tx || (tx && regs->UARTSR.B.DTF_TFF)) {
- regs->UARTSR.R = clear_dtf.R;
- regs->BDRL.B.DATA0 = c;
- self->transmit_in_progress = true;
- done = true;
- }
- rtems_interrupt_enable(level);
- }
-
- done = false;
- while (!done) {
- rtems_interrupt_disable(level);
- if (wait_for_transmit_done) {
- if (regs->UARTSR.B.DTF_TFF) {
- regs->UARTSR.R = clear_dtf.R;
- self->transmit_in_progress = false;
- done = true;
- }
- } else {
- done = true;
- }
-
- if (done && self->transmit_nest_level > 0) {
- --self->transmit_nest_level;
-
- if (self->transmit_nest_level == 0) {
- LINFLEX_LINIER_32B_tag ier = { .R = regs->LINIER.R };
-
- ier.B.DTIE = 1;
- regs->LINIER.R = ier.R;
- }
- }
- rtems_interrupt_enable(level);
- }
-}
-
-static void mpc55xx_linflex_rx_interrupt_handler(void *arg)
-{
- mpc55xx_linflex_context *self = arg;
- volatile LINFLEX_tag *regs = self->regs;
- char c = regs->BDRM.B.DATA4;
- const LINFLEX_UARTSR_32B_tag clear_flags = { .B = { .RMB = 1, .DRF_RFE = 1 } };
-
- regs->UARTSR.R = clear_flags.R;
-
- rtems_termios_enqueue_raw_characters(self->tty, &c, 1);
-}
-
-static void mpc55xx_linflex_tx_interrupt_handler(void *arg)
-{
- mpc55xx_linflex_context *self = arg;
- volatile LINFLEX_tag *regs = self->regs;
-
- regs->UARTSR.B.DTF_TFF = 1; /* clear flag */
- self->transmit_in_progress = false;
-
- rtems_termios_dequeue_characters(self->tty, 1);
-}
-
-/*
-static void mpc55xx_linflex_err_interrupt_handler(void *arg)
-{
- mpc55xx_linflex_context *self = arg;
-}
-*/
-
-static int mpc55xx_linflex_set_attributes(int minor, const struct termios *t)
-{
- mpc55xx_linflex_context *self = console_generic_get_context(minor);
- volatile LINFLEX_tag *regs = self->regs;
- LINFLEX_UARTCR_32B_tag uartcr = { .R = 0 };
- LINFLEX_GCR_32B_tag gcr = { .R = 0 };
- LINFLEX_LINIER_32B_tag ier = { .R = 0 };
- rtems_termios_baud_t br = rtems_termios_baud_to_number(t->c_ospeed);
- LINFLEX_LINFBRR_32B_tag fbrr = { .R = 0 };
- LINFLEX_LINIBRR_32B_tag ibrr = { .R = 0 };
-
- enter_init_mode(regs);
-
- /* Set to UART-mode */
- uartcr.B.UART = 1;
- regs->UARTCR.R = uartcr.R;
-
- /* Set to buffer mode with size 1 */
- uartcr.B.TDFL_TFC = 0;
- uartcr.B.RDFL_RFC0 = 0;
- uartcr.B.RFBM = 0;
- uartcr.B.TFBM = 0;
-
- /* Enable receiver and transmitter */
- uartcr.B.RXEN = 1;
- uartcr.B.TXEN = 1;
-
- /* Number of data bits */
- uartcr.B.WL1 = 0;
- if ((t->c_cflag & CSIZE) == CS8) {
- uartcr.B.WL0 = 1;
- } else if ((t->c_cflag & CSIZE) == CS7) {
- uartcr.B.WL0 = 0;
- } else {
- return -1;
- }
-
- /* Parity */
- uartcr.B.PCE = (t->c_cflag & PARENB) ? 1 : 0;
- uartcr.B.PC1 = 0;
- uartcr.B.PC0 = (t->c_cflag & PARODD) ? 1 : 0;
-
- /* Stop bits */
- gcr.B.STOP = (t->c_cflag & CSTOPB) ? 1 : 0;
-
- /* Set control registers */
- regs->UARTCR.R = uartcr.R;
- regs->GCR.R = gcr.R;
-
- /* Interrupts */
- ier.B.DTIE = 1;
- ier.B.DRIE = 1;
- regs->LINIER.R = ier.R;
-
- /* Baud rate */
- if (br > 0) {
- uint32_t lfdiv_mult_32 = bsp_clock_speed * 2 / br;
- if((lfdiv_mult_32 & 0x1) != 0) {
- ++lfdiv_mult_32;
- }
- fbrr.B.FBR = (lfdiv_mult_32 >> 1) & 0xF;
- ibrr.B.IBR = lfdiv_mult_32 >> 5;
- } else {
- return -1;
- }
- regs->LINFBRR.R = fbrr.R;
- regs->LINIBRR.R = ibrr.R;
-
- enter_active_mode(regs);
-
- return 0;
-}
-
-static int mpc55xx_linflex_first_open(int major, int minor, void *arg)
-{
- rtems_status_code sc = RTEMS_SUCCESSFUL;
- int rv = 0;
- mpc55xx_linflex_context *self = console_generic_get_context(minor);
- struct rtems_termios_tty *tty = console_generic_get_tty_at_open(arg);
- SIU_PCR_tag pcr = { .R = 0 };
- SIUL_PSMI_8B_tag psmi = { .R = 0 };
-
- self->tty = tty;
-
- pcr.B.IBE = 1;
- self->rx_pcr_register->R = pcr.R;
- psmi.B.PADSEL = self->rx_padsel_value;
- self->rx_psmi_register->R = psmi.R;
- pcr.R = 0;
- pcr.B.OBE = 1;
- pcr.B.PA = self->tx_pa_value;
- self->tx_pcr_register->R = pcr.R;
-
- rv = rtems_termios_set_initial_baud(tty, BSP_DEFAULT_BAUD_RATE);
- if (rv != 0) {
- bsp_fatal(MPC55XX_FATAL_CONSOLE_LINFLEX_BAUD);
- }
-
- rv = mpc55xx_linflex_set_attributes(minor, &tty->termios);
- if (rv != 0) {
- bsp_fatal(MPC55XX_FATAL_CONSOLE_LINFLEX_ATTRIBUTES);
- }
-
- sc = mpc55xx_interrupt_handler_install(
- self->irq_rxi,
- "LINFlexD RXI",
- RTEMS_INTERRUPT_UNIQUE,
- MPC55XX_INTC_DEFAULT_PRIORITY,
- mpc55xx_linflex_rx_interrupt_handler,
- self
- );
- if (sc != RTEMS_SUCCESSFUL) {
- bsp_fatal(MPC55XX_FATAL_CONSOLE_LINFLEX_RX_IRQ_INSTALL);
- }
-
- sc = mpc55xx_interrupt_handler_install(
- self->irq_txi,
- "LINFlexD TXI",
- RTEMS_INTERRUPT_UNIQUE,
- MPC55XX_INTC_DEFAULT_PRIORITY,
- mpc55xx_linflex_tx_interrupt_handler,
- self
- );
- if (sc != RTEMS_SUCCESSFUL) {
- bsp_fatal(MPC55XX_FATAL_CONSOLE_LINFLEX_TX_IRQ_INSTALL);
- }
-
- /*
- sc = mpc55xx_interrupt_handler_install(
- self->irq_err,
- "LINFlexD ERR",
- RTEMS_INTERRUPT_UNIQUE,
- MPC55XX_INTC_DEFAULT_PRIORITY,
- mpc55xx_linflex_err_interrupt_handler,
- self
- );
- if (sc != RTEMS_SUCCESSFUL) {
- bsp_fatal(MPC55XX_FATAL_CONSOLE_LINFLEX_ERR_IRQ_INSTALL);
- }
- */
-
- return 0;
-}
-
-static int mpc55xx_linflex_last_close(int major, int minor, void* arg)
-{
- rtems_status_code sc = RTEMS_SUCCESSFUL;
- mpc55xx_linflex_context *self = console_generic_get_context(minor);
- volatile LINFLEX_tag *regs = self->regs;
- SIU_PCR_tag pcr = { .R = 0 };
- SIUL_PSMI_8B_tag psmi = { .R = 0 };
-
- /* enter initialization mode */
- enter_init_mode(regs);
-
- /* disable interrupts */
- regs->LINIER.R = 0;
-
- /* set module to sleep mode */
- enter_sleep_mode(regs);
-
- sc = rtems_interrupt_handler_remove(
- self->irq_rxi,
- mpc55xx_linflex_rx_interrupt_handler,
- self
- );
- if (sc != RTEMS_SUCCESSFUL) {
- bsp_fatal(MPC55XX_FATAL_CONSOLE_LINFLEX_RX_IRQ_REMOVE);
- }
-
- sc = rtems_interrupt_handler_remove(
- self->irq_txi,
- mpc55xx_linflex_tx_interrupt_handler,
- self
- );
- if (sc != RTEMS_SUCCESSFUL) {
- bsp_fatal(MPC55XX_FATAL_CONSOLE_LINFLEX_TX_IRQ_REMOVE);
- }
-
- /*
- sc = rtems_interrupt_handler_remove(
- self->irq_err,
- mpc55xx_linflex_err_interrupt_handler,
- self
- );
- if (sc != RTEMS_SUCCESSFUL) {
- bsp_fatal(MPC55XX_FATAL_CONSOLE_LINFLEX_ERR_IRQ_REMOVE);
- }
- */
-
- pcr.B.IBE = 1;
- self->rx_pcr_register->R = pcr.R;
- self->tx_pcr_register->R = pcr.R;
- psmi.R = 0;
- self->rx_psmi_register->R = psmi.R;
-
- self->tty = NULL;
-
- return 0;
-}
-
-static int mpc55xx_linflex_poll_read(int minor)
-{
- mpc55xx_linflex_context *self = console_generic_get_context(minor);
- volatile LINFLEX_tag *regs = self->regs;
- rtems_interrupt_level level;
- int c = -1;
-
- rtems_interrupt_disable(level);
- if (regs->UARTSR.B.DRF_RFE != 0) {
- /* Clear flag */
- regs->UARTSR.B.DRF_RFE = 1;
-
- /* Read */
- c = regs->BDRM.B.DATA4;
- }
- rtems_interrupt_enable(level);
-
- return c;
-}
-
-static int mpc55xx_linflex_write(int minor, const char *out, size_t n)
-{
- if (n > 0) {
- mpc55xx_linflex_context *self = console_generic_get_context(minor);
- volatile LINFLEX_tag *regs = self->regs;
-
- regs->BDRL.B.DATA0 = out [0];
- self->transmit_in_progress = true;
- /* TODO: send more then one byte */
- }
-
- return 0;
-}
-
-const console_generic_callbacks mpc55xx_linflex_callbacks = {
- .termios_callbacks = {
- .firstOpen = mpc55xx_linflex_first_open,
- .lastClose = mpc55xx_linflex_last_close,
- .write = mpc55xx_linflex_write,
- .setAttributes = mpc55xx_linflex_set_attributes,
- .outputUsesInterrupts = TERMIOS_IRQ_DRIVEN
- },
- .poll_read = mpc55xx_linflex_poll_read,
- .poll_write = mpc55xx_linflex_poll_write
-};
-
-#endif /* MPC55XX_HAS_LINFLEX */