summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/powerpc/mpc55xxevb/console/console-linflex.c
diff options
context:
space:
mode:
Diffstat (limited to 'c/src/lib/libbsp/powerpc/mpc55xxevb/console/console-linflex.c')
-rw-r--r--c/src/lib/libbsp/powerpc/mpc55xxevb/console/console-linflex.c417
1 files changed, 0 insertions, 417 deletions
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 */