/* * Test converting termios baud constant to baud number */ void test_termios_baud2number(void) { int i; int number; puts( "\n" "Test termios_baud2number..." ); puts( "termios_baud_to_number(-2) - NOT OK" ); i = rtems_termios_baud_to_number( -2 ); rtems_test_assert( i == -1 ); puts( "termios_baud_to_number(572) - NOT OK" ); i = rtems_termios_baud_to_number( -2 ); rtems_test_assert( i == -1 ); for (i=0 ; baud_table[i].constant != -1 ; i++ ) { printf( "termios_baud_to_number(B%" PRIdrtems_termios_baud_t ") - OK\n", baud_table[i].baud ); number = rtems_termios_baud_to_number( baud_table[i].constant ); if ( number != baud_table[i].baud ) { printf( "ERROR - returned %d should be %" PRIdrtems_termios_baud_t "\n", number, baud_table[i].baud ); rtems_test_exit(0); } } }
/* * Test converting termios baud constant to baud number */ static void test_termios_baud2number(void) { int i; rtems_termios_baud_t number; puts( "\n" "Test termios_baud2number..." ); puts( "termios_baud_to_number(-2) - NOT OK" ); number = rtems_termios_baud_to_number( INVALID_CONSTANT ); rtems_test_assert( number == 0 ); for (i=0 ; baud_table[i].constant != INVALID_CONSTANT ; i++ ) { printf( "termios_baud_to_number(B%" PRIdrtems_termios_baud_t ") - OK\n", baud_table[i].baud ); number = rtems_termios_baud_to_number( baud_table[i].constant ); if ( number != baud_table[i].baud ) { printf( "ERROR - returned %" PRIdrtems_termios_baud_t " should be %" PRIdrtems_termios_baud_t "\n", number, baud_table[i].baud ); rtems_test_exit(0); } } }
/****************************************************** Name: SetAttributes Input parameters: termios structure, channel Output parameters: - Description: return whether there's a character in the receive buffer TO DO: add the channel # to check for!! *****************************************************/ static int SetAttributes (int minor, const struct termios *t) { rtems_interrupt_level level; float ispeed, ospeed; int isp, osp; /* output speed */ if (t->c_cflag & CBAUDEX) osp = (t->c_cflag & CBAUD) + CBAUD + 1; else osp = t->c_cflag & CBAUD; /* input speed */ isp = (t->c_cflag / (CIBAUD / CBAUD)) & CBAUD; /* convert it */ ispeed = rtems_termios_baud_to_number(isp); ospeed = rtems_termios_baud_to_number(osp); if (ispeed || ospeed) { /* update config table */ m340_uart_config[UART_CHANNEL_A].rx_baudrate = ((minor==UART_CHANNEL_A)&&(ispeed!=0)) ? ispeed : m340_uart_config[UART_CHANNEL_A].rx_baudrate; m340_uart_config[UART_CHANNEL_A].tx_baudrate = ((minor==UART_CHANNEL_A)&&(ospeed!=0)) ? ospeed : m340_uart_config[UART_CHANNEL_A].tx_baudrate; m340_uart_config[UART_CHANNEL_B].rx_baudrate = ((minor==UART_CHANNEL_B)&&(ispeed!=0)) ? ispeed : m340_uart_config[UART_CHANNEL_B].rx_baudrate; m340_uart_config[UART_CHANNEL_B].tx_baudrate = ((minor==UART_CHANNEL_B)&&(ospeed!=0)) ? ospeed : m340_uart_config[UART_CHANNEL_B].tx_baudrate; } /* change parity */ if (t->c_cflag & PARENB) { if (t->c_cflag & PARODD) m340_uart_config[minor].parity_mode = m340_Odd_Parity; else m340_uart_config[minor].parity_mode = m340_Even_Parity; } /* change bits per character */ if (t->c_cflag & CSIZE) { switch (t->c_cflag & CSIZE) { default: break; case CS5: m340_uart_config[minor].bits_per_char = m340_5bpc; break; case CS6: m340_uart_config[minor].bits_per_char = m340_6bpc; break; case CS7: m340_uart_config[minor].bits_per_char = m340_7bpc; break; case CS8: m340_uart_config[minor].bits_per_char = m340_8bpc; break; } } /* if serial module configuration has been changed */ if (t->c_cflag & (CBAUD | CIBAUD | CSIZE | PARENB)) { rtems_interrupt_disable(level); /* reinit the UART */ dbugInitialise(); rtems_interrupt_enable (level); } return 0; }
/** * @brief closes sci peripheral of interrupt driven driver * * calls tms570_sci_poll_last_close and disables interrupts * * @param[in] tty Termios control * @param[in] base context of the driver * @param[in] args * @retval false Error occured during initialization * @retval true Driver is open and ready */ static void tms570_sci_interrupt_last_close( rtems_termios_tty *tty, rtems_termios_device_context *base, rtems_libio_open_close_args_t *args ) { tms570_sci_context *ctx = (tms570_sci_context *) base; rtems_interrupt_lock_context lock_context; rtems_interval tw; int32_t baudrate; /* Turn off RX interrupts */ rtems_termios_device_lock_acquire(base, &lock_context); tms570_sci_disable_interrupts(ctx); rtems_termios_device_lock_release(base, &lock_context); tw = rtems_clock_get_ticks_per_second(); baudrate = rtems_termios_baud_to_number(cfgetospeed(&tty->termios)); tw = tw * 10 / baudrate + 1; while ( ( ctx->regs->FLR & TMS570_SCI_FLR_TX_EMPTY ) == 0 ) { rtems_task_wake_after(tw); } /* uninstall ISR */ rtems_interrupt_handler_remove(ctx->irq, tms570_sci_interrupt_handler, tty); tms570_sci_poll_last_close(tty, base, args); }
/* ARGSUSED */ int pppopen(struct rtems_termios_tty *tty) { int i; register struct ppp_softc *sc; struct mbuf *m = (struct mbuf *)0; if (tty->t_line == PPPDISC) { sc = (struct ppp_softc *)tty->t_sc; if (sc != NULL && sc->sc_devp == (void *)tty) { return (0); } } if ((sc = pppalloc(1)) == NULL) { return ENXIO; } if (sc->sc_relinq) (*sc->sc_relinq)(sc); /* get previous owner to relinquish the unit */ sc->sc_ilen = 0; sc->sc_m = NULL; bzero(sc->sc_asyncmap, sizeof(sc->sc_asyncmap)); sc->sc_asyncmap[0] = 0xffffffff; sc->sc_asyncmap[3] = 0x60000000; sc->sc_rasyncmap = 0; sc->sc_devp = tty; sc->sc_start = pppasyncstart; sc->sc_ctlp = pppasyncctlp; sc->sc_relinq = pppasyncrelinq; sc->sc_outm = NULL; sc->sc_outmc = NULL; /* preallocate mbufs for free queue */ rtems_bsdnet_semaphore_obtain(); for (i=0; i<NUM_MBUFQ; i++) { pppallocmbuf(sc, &m); if ( i == 0 ) { /* use first mbuf for rx iterrupt handling */ sc->sc_m = m; } else { /* enqueue mbuf for later use */ IF_ENQUEUE(&sc->sc_freeq, m); } m = (struct mbuf *)0; } rtems_bsdnet_semaphore_release(); /* initialize values */ sc->sc_if.if_flags |= IFF_RUNNING; sc->sc_if.if_baudrate = rtems_termios_baud_to_number(tty->termios.c_cflag & CBAUD); tty->t_sc = (void *)sc; return ( RTEMS_SUCCESSFUL ); }
/* This is for setting baud rate, bits, etc. */ static int imx_uart_set_attrs(int minor, const struct termios *t) { int baud; baud = rtems_termios_baud_to_number(t->c_cflag & CBAUD); imx_uart_set_baud(minor, baud); return 0; }
static bool atsam_usart_set_attributes( rtems_termios_device_context *base, const struct termios *term ) { atsam_usart_context *ctx = (atsam_usart_context *) base; Usart *regs = ctx->regs; rtems_termios_baud_t baud; uint32_t mr; baud = rtems_termios_baud_to_number(term->c_cflag); regs->US_BRGR = (BOARD_MCK / baud) / 16; if ((term->c_cflag & CREAD) != 0) { regs->US_CR = US_CR_RXEN | US_CR_TXEN; } else { regs->US_CR = US_CR_TXEN; } mr = US_MR_USART_MODE_NORMAL | US_MR_USCLKS_MCK; switch (term->c_cflag & CSIZE) { case CS5: mr |= US_MR_CHRL_5_BIT; break; case CS6: mr |= US_MR_CHRL_6_BIT; break; case CS7: mr |= US_MR_CHRL_7_BIT; break; default: mr |= US_MR_CHRL_8_BIT; break; } if ((term->c_cflag & PARENB) != 0) { if ((term->c_cflag & PARODD) != 0) { mr |= US_MR_PAR_ODD; } else { mr |= US_MR_PAR_EVEN; } } else { mr |= US_MR_PAR_NO; } if ((term->c_cflag & CSTOPB) != 0) { mr |= US_MR_NBSTOP_2_BIT; } else { mr |= US_MR_NBSTOP_1_BIT; } regs->US_MR = mr; return true; }
/* * Hardware-dependent portion of tcsetattr(). */ static int smc1SetAttributes (int minor, const struct termios *t) { int baud; baud = rtems_termios_baud_to_number(t->c_cflag & CBAUD); if (baud > 0) m360.brgc1 = smc1BRGC (baud); return 0; }
/* * Set Attributes Handler */ int termios_test_driver_set_attributes( int minor, const struct termios *t ) { int baud_requested; int number; const char *parity = "NONE"; const char *char_size = "5"; const char *stop = "NONE"; baud_requested = t->c_cflag & CBAUD; number = rtems_termios_baud_to_number( baud_requested ); /* * Parity */ if (t->c_cflag & PARENB) { parity = "EVEN"; if (!(t->c_cflag & PARODD)) parity = "ODD"; } /* * Character Size */ if (t->c_cflag & CSIZE) { switch (t->c_cflag & CSIZE) { case CS5: char_size = "5"; break; case CS6: char_size = "6"; break; case CS7: char_size = "7"; break; case CS8: char_size = "8"; break; } } /* * Stop Bits */ if (t->c_cflag & CSTOPB) stop = "2"; else stop = "1"; printf( "set_attributes - B%d %s-%s-%s\n", number, char_size, parity, stop ); return 0; }
static int conSetAttr(int minor, const struct termios *t) { rtems_termios_baud_t baud; baud = rtems_termios_baud_to_number(t->c_cflag & CBAUD); if ( baud > 115200 ) rtems_fatal_error_occurred (RTEMS_INTERNAL_ERROR); BSP_uart_set_baud(BSPConsolePort, baud); return 0; }
/** * @brief Set attributes of the HW peripheral * * Sets attributes of the HW peripheral (parity, baud rate, etc.) * * @param[in] base context of the driver * @param[in] t termios driver * @retval true peripheral setting is changed */ static bool tms570_sci_set_attributes( rtems_termios_device_context *base, const struct termios *t ) { tms570_sci_context *ctx = (tms570_sci_context *) base; rtems_interrupt_lock_context lock_context; int32_t bauddiv; int32_t baudrate; rtems_termios_device_lock_acquire(base, &lock_context); ctx->regs->GCR1 &= ~( TMS570_SCI_GCR1_SWnRST | TMS570_SCI_GCR1_TXENA | TMS570_SCI_GCR1_RXENA ); ctx->regs->GCR1 &= ~TMS570_SCI_GCR1_STOP; /*one stop bit*/ ctx->regs->FORMAT = TMS570_SCI_FORMAT_CHAR(0x7); switch ( t->c_cflag & ( PARENB|PARODD ) ) { case ( PARENB|PARODD ): /* Odd parity */ ctx->regs->GCR1 &= ~TMS570_SCI_GCR1_PARITY; ctx->regs->GCR1 |= TMS570_SCI_GCR1_PARITY_ENA; break; case PARENB: /* Even parity */ ctx->regs->GCR1 |= TMS570_SCI_GCR1_PARITY; ctx->regs->GCR1 |= TMS570_SCI_GCR1_PARITY_ENA; break; default: case 0: case PARODD: /* No Parity */ ctx->regs->GCR1 &= ~TMS570_SCI_GCR1_PARITY_ENA; } /* Baud rate */ baudrate = rtems_termios_baud_to_number(cfgetospeed(t)); baudrate *= 2 * 16; bauddiv = (BSP_PLL_OUT_CLOCK + baudrate / 2) / baudrate; ctx->regs->BRS = bauddiv; ctx->regs->GCR1 |= TMS570_SCI_GCR1_SWnRST | TMS570_SCI_GCR1_TXENA | TMS570_SCI_GCR1_RXENA; rtems_termios_device_lock_release(base, &lock_context); return true; }
/** * @brief Set attributes of the HW peripheral * * Sets attributes of the HW peripheral (parity, baud rate, etc.) * * @param[in] base context of the driver * @param[in] t termios driver * @retval true peripheral setting is changed */ static bool tms570_sci_set_attributes( rtems_termios_device_context *base, const struct termios *t ) { tms570_sci_context *ctx = (tms570_sci_context *) base; rtems_interrupt_lock_context lock_context; int32_t bauddiv; int32_t baudrate; rtems_termios_device_lock_acquire(base, &lock_context); ctx->regs->SCIGCR1 &= ~( (1<<7) | (1<<25) | (1<<24) ); ctx->regs->SCIGCR1 &= ~(1<<4); /*one stop bit*/ ctx->regs->SCIFORMAT = 0x7; switch ( t->c_cflag & ( PARENB|PARODD ) ) { case ( PARENB|PARODD ): /* Odd parity */ ctx->regs->SCIGCR1 &= ~(1<<3); ctx->regs->SCIGCR1 |= (1<<2); break; case PARENB: /* Even parity */ ctx->regs->SCIGCR1 |= (1<<3); ctx->regs->SCIGCR1 |= (1<<2); break; default: case 0: case PARODD: /* No Parity */ ctx->regs->SCIGCR1 &= ~(1<<2); } /* Baud rate */ baudrate = rtems_termios_baud_to_number(cfgetospeed(t)); baudrate *= 2 * 16; bauddiv = (BSP_PLL_OUT_CLOCK + baudrate / 2) / baudrate; ctx->regs->BRS = bauddiv; ctx->regs->SCIGCR1 |= (1<<7) | (1<<25) | (1<<24); rtems_termios_device_lock_release(base, &lock_context); return true; }
static int conSetAttr(int port, int minor, const struct termios *t) { unsigned long baud, databits, parity, stopbits; baud = rtems_termios_baud_to_number(t->c_cflag & CBAUD); if ( baud > 115200 ) rtems_fatal_error_occurred (RTEMS_INTERNAL_ERROR); if (t->c_cflag & PARENB) { /* Parity is enabled */ if (t->c_cflag & PARODD) { /* Parity is odd */ parity = PEN; } else { /* Parity is even */ parity = PEN | EPS; } } else { /* No parity */ parity = 0; } switch (t->c_cflag & CSIZE) { case CS5: databits = CHR_5_BITS; break; case CS6: databits = CHR_6_BITS; break; case CS7: databits = CHR_7_BITS; break; default: /* just to avoid warnings -- all cases are covered. */ case CS8: databits = CHR_8_BITS; break; } if (t->c_cflag & CSTOPB) { /* 2 stop bits */ stopbits = STB; } else { /* 1 stop bit */ stopbits = 0; } printk("Mouse baud, port=%X, baud=%d\n", port, baud ); BSP_uart_set_attributes(port, baud, databits, parity, stopbits); return 0; }
static bool atsam_uart_set_attributes( rtems_termios_device_context *base, const struct termios *term ) { atsam_uart_context *ctx = (atsam_uart_context *) base; Uart *regs = ctx->regs; rtems_termios_baud_t baud; uint32_t mr; baud = rtems_termios_baud_to_number(term->c_cflag); regs->UART_BRGR = (BOARD_MCK / baud) / 16; if ((term->c_cflag & CREAD) != 0) { regs->UART_CR = UART_CR_RXEN | UART_CR_TXEN; } else { regs->UART_CR = UART_CR_TXEN; } mr = UART_MR_FILTER_DISABLED | UART_MR_BRSRCCK_PERIPH_CLK; if ((term->c_cflag & CSIZE) != CS8) { return false; } if ((term->c_cflag & PARENB) != 0) { if ((term->c_cflag & PARODD) != 0) { mr |= UART_MR_PAR_ODD; } else { mr |= UART_MR_PAR_EVEN; } } else { mr |= UART_MR_PAR_NO; } if ((term->c_cflag & CSTOPB) != 0) { return false; } regs->UART_MR = mr; return true; }
static int lpc32xx_hsu_set_attributes(int minor, const struct termios *term) { console_tbl *ct = Console_Port_Tbl [minor]; volatile lpc32xx_hsu *hsu = (volatile lpc32xx_hsu *) ct->ulCtrlPort1; int baud_flags = term->c_cflag & CBAUD; if (baud_flags != 0) { int32_t baud = rtems_termios_baud_to_number(baud_flags); if (baud > 0) { uint32_t baud_divisor = 14 * (uint32_t) baud; uint32_t rate = LPC32XX_PERIPH_CLK / baud_divisor; uint32_t remainder = LPC32XX_PERIPH_CLK - rate * baud_divisor; if (2 * remainder >= baud_divisor) { ++rate; } hsu->rate = rate - 1; } } return 0; }
static bool apbuart_set_attributes( rtems_termios_device_context *base, const struct termios *t ) { struct apbuart_context *uart = (struct apbuart_context *) base; rtems_interrupt_lock_context lock_context; unsigned int scaler; unsigned int ctrl; int baud; switch (t->c_cflag & CSIZE) { default: case CS5: case CS6: case CS7: /* Hardware doesn't support other than CS8 */ return false; case CS8: break; } rtems_termios_device_lock_acquire(base, &lock_context); /* Read out current value */ ctrl = uart->regs->ctrl; switch (t->c_cflag & (PARENB|PARODD)) { case (PARENB|PARODD): /* Odd parity */ ctrl |= APBUART_CTRL_PE|APBUART_CTRL_PS; break; case PARENB: /* Even parity */ ctrl &= ~APBUART_CTRL_PS; ctrl |= APBUART_CTRL_PE; break; default: case 0: case PARODD: /* No Parity */ ctrl &= ~(APBUART_CTRL_PS|APBUART_CTRL_PE); } if (!(t->c_cflag & CLOCAL)) { ctrl |= APBUART_CTRL_FL; } else { ctrl &= ~APBUART_CTRL_FL; } /* Update new settings */ uart->regs->ctrl = ctrl; rtems_termios_device_lock_release(base, &lock_context); /* Baud rate */ baud = rtems_termios_baud_to_number(t->c_cflag); if (baud > 0) { /* Calculate Baud rate generator "scaler" number */ scaler = (((uart->freq_hz * 10) / (baud * 8)) - 5) / 10; /* Set new baud rate by setting scaler */ uart->regs->scaler = scaler; } return true; }
static int leon3_console_set_attributes(int minor, const struct termios *t) { struct apbuart_priv *uart = leon3_console_get_uart(minor); unsigned int scaler; unsigned int ctrl; int baud; switch (t->c_cflag & CSIZE) { default: case CS5: case CS6: case CS7: /* Hardware doesn't support other than CS8 */ return -1; case CS8: break; } /* * FIXME: This read-modify-write sequence is broken since interrupts may * interfere. */ /* Read out current value */ ctrl = uart->regs->ctrl; switch (t->c_cflag & (PARENB|PARODD)) { case (PARENB|PARODD): /* Odd parity */ ctrl |= LEON_REG_UART_CTRL_PE|LEON_REG_UART_CTRL_PS; break; case PARENB: /* Even parity */ ctrl &= ~LEON_REG_UART_CTRL_PS; ctrl |= LEON_REG_UART_CTRL_PE; break; default: case 0: case PARODD: /* No Parity */ ctrl &= ~(LEON_REG_UART_CTRL_PS|LEON_REG_UART_CTRL_PE); } if (!(t->c_cflag & CLOCAL)) { ctrl |= LEON_REG_UART_CTRL_FL; } else { ctrl &= ~LEON_REG_UART_CTRL_FL; } /* Update new settings */ uart->regs->ctrl = ctrl; /* Baud rate */ baud = rtems_termios_baud_to_number(t->c_cflag); if (baud > 0) { /* Calculate Baud rate generator "scaler" number */ scaler = (((uart->freq_hz * 10) / (baud * 8)) - 5) / 10; /* Set new baud rate by setting scaler */ uart->regs->scaler = scaler; } return 0; }
Z85C30_STATIC int z85c30_set_attributes( int minor, const struct termios *t ) { uintptr_t ulCtrlPort; uint32_t ulBaudDivisor; uint32_t wr3; uint32_t wr4; uint32_t wr5; int baud_requested; setRegister_f setReg; rtems_interrupt_level Irql; ulCtrlPort = Console_Port_Tbl[minor].ulCtrlPort1; setReg = Console_Port_Tbl[minor].setRegister; /* * Calculate the baud rate divisor */ baud_requested = t->c_cflag & CBAUD; if (!baud_requested) baud_requested = B9600; /* default to 9600 baud */ ulBaudDivisor = Z85C30_Baud( (uint32_t) Console_Port_Tbl[minor].ulClock, (uint32_t) rtems_termios_baud_to_number( baud_requested ) ); wr3 = SCC_WR3_RX_EN; wr4 = SCC_WR4_16_CLOCK; wr5 = SCC_WR5_TX_EN; /* * Parity */ if (t->c_cflag & PARENB) { wr4 |= SCC_WR4_PAR_EN; if (!(t->c_cflag & PARODD)) wr4 |= SCC_WR4_PAR_EVEN; } /* * Character Size */ if (t->c_cflag & CSIZE) { switch (t->c_cflag & CSIZE) { case CS5: break; case CS6: wr3 |= SCC_WR3_RX_6_BITS; wr5 |= SCC_WR5_TX_6_BITS; break; case CS7: wr3 |= SCC_WR3_RX_7_BITS; wr5 |= SCC_WR5_TX_7_BITS; break; case CS8: wr3 |= SCC_WR3_RX_8_BITS; wr5 |= SCC_WR5_TX_8_BITS; break; } } else { wr3 |= SCC_WR3_RX_8_BITS; /* default to 9600,8,N,1 */ wr5 |= SCC_WR5_TX_8_BITS; /* default to 9600,8,N,1 */ } /* * Stop Bits */ if (t->c_cflag & CSTOPB) { wr4 |= SCC_WR4_2_STOP; /* 2 stop bits */ } else { wr4 |= SCC_WR4_1_STOP; /* 1 stop bits */ } /* * Now actually set the chip */ rtems_interrupt_disable(Irql); (*setReg)( ulCtrlPort, SCC_WR0_SEL_WR4, wr4 ); (*setReg)( ulCtrlPort, SCC_WR0_SEL_WR3, wr3 ); (*setReg)( ulCtrlPort, SCC_WR0_SEL_WR5, wr5 ); /* * Setup the lower 8 bits time constants=1E. * If the time constans=1E, then the desire * baud rate will be equilvalent to 9600, via register 12. */ (*setReg)( ulCtrlPort, SCC_WR0_SEL_WR12, ulBaudDivisor & 0xff ); /* * using register 13 * Setup the upper 8 bits time constant */ (*setReg)( ulCtrlPort, SCC_WR0_SEL_WR13, (ulBaudDivisor>>8) & 0xff ); rtems_interrupt_enable(Irql); return 0; }
int ns16550_set_attributes( int minor, const struct termios *t ) { uint32_t pNS16550; uint32_t ulBaudDivisor; uint8_t ucLineControl; uint32_t baud_requested; setRegister_f setReg; rtems_interrupt_lock_context lock_context; const console_tbl *c = Console_Port_Tbl [minor]; pNS16550 = c->ulCtrlPort1; setReg = c->setRegister; /* * Calculate the baud rate divisor * * Assert ensures there is no division by 0. */ baud_requested = rtems_termios_baud_to_number(t->c_cflag); _Assert( baud_requested != 0 ); ulBaudDivisor = NS16550_GetBaudDivisor(c, baud_requested); ucLineControl = 0; /* * Parity */ if (t->c_cflag & PARENB) { ucLineControl |= SP_LINE_PAR; if (!(t->c_cflag & PARODD)) ucLineControl |= SP_LINE_ODD; } /* * Character Size */ if (t->c_cflag & CSIZE) { switch (t->c_cflag & CSIZE) { case CS5: ucLineControl |= FIVE_BITS; break; case CS6: ucLineControl |= SIX_BITS; break; case CS7: ucLineControl |= SEVEN_BITS; break; case CS8: ucLineControl |= EIGHT_BITS; break; } } else { ucLineControl |= EIGHT_BITS; /* default to 9600,8,N,1 */ } /* * Stop Bits */ if (t->c_cflag & CSTOPB) { ucLineControl |= SP_LINE_STOP; /* 2 stop bits */ } else { ; /* 1 stop bit */ } /* * Now actually set the chip */ rtems_interrupt_lock_acquire(&ns16550_lock, &lock_context); /* * Set the baud rate * * NOTE: When the Divisor Latch Access Bit (DLAB) is set to 1, * the transmit buffer and interrupt enable registers * turn into the LSB and MSB divisor latch registers. */ (*setReg)(pNS16550, NS16550_LINE_CONTROL, SP_LINE_DLAB); (*setReg)(pNS16550, NS16550_TRANSMIT_BUFFER, ulBaudDivisor&0xff); (*setReg)(pNS16550, NS16550_INTERRUPT_ENABLE, (ulBaudDivisor>>8)&0xff); /* * Now write the line control */ (*setReg)(pNS16550, NS16550_LINE_CONTROL, ucLineControl ); rtems_interrupt_lock_release(&ns16550_lock, &lock_context); return 0; }
int ns16550_set_attributes( int minor, const struct termios *t ) { uint32_t pNS16550; uint32_t ulBaudDivisor; uint8_t ucLineControl; uint32_t baud_requested; setRegister_f setReg; uint32_t Irql; const console_tbl *c = Console_Port_Tbl [minor]; pNS16550 = c->ulCtrlPort1; setReg = c->setRegister; /* * Calculate the baud rate divisor */ baud_requested = rtems_termios_baud_to_number(t->c_cflag); ulBaudDivisor = NS16550_GetBaudDivisor(c, baud_requested); ucLineControl = 0; /* * Parity */ if (t->c_cflag & PARENB) { ucLineControl |= SP_LINE_PAR; if (!(t->c_cflag & PARODD)) ucLineControl |= SP_LINE_ODD; } /* * Character Size */ if (t->c_cflag & CSIZE) { switch (t->c_cflag & CSIZE) { case CS5: ucLineControl |= FIVE_BITS; break; case CS6: ucLineControl |= SIX_BITS; break; case CS7: ucLineControl |= SEVEN_BITS; break; case CS8: ucLineControl |= EIGHT_BITS; break; } } else { ucLineControl |= EIGHT_BITS; /* default to 9600,8,N,1 */ } /* * Stop Bits */ if (t->c_cflag & CSTOPB) { ucLineControl |= SP_LINE_STOP; /* 2 stop bits */ } else { ; /* 1 stop bit */ } /* * Now actually set the chip */ rtems_interrupt_disable(Irql); /* * Set the baud rate */ (*setReg)(pNS16550, NS16550_LINE_CONTROL, SP_LINE_DLAB); /* XXX are these registers right? */ (*setReg)(pNS16550, NS16550_TRANSMIT_BUFFER, ulBaudDivisor&0xff); (*setReg)(pNS16550, NS16550_INTERRUPT_ENABLE, (ulBaudDivisor>>8)&0xff); /* * Now write the line control */ (*setReg)(pNS16550, NS16550_LINE_CONTROL, ucLineControl ); rtems_interrupt_enable(Irql); return 0; }
/** * @brief Set attributes of the HW peripheral * * Sets attributes of the HW peripheral (parity, baud rate, etc.) * * @param[in] base context of the driver * @param[in] t termios driver * @retval true peripheral setting is changed */ bool tms570_sci_set_attributes( rtems_termios_device_context *base, const struct termios *t ) { tms570_sci_context *ctx = (tms570_sci_context *) base; rtems_interrupt_lock_context lock_context; int32_t bauddiv; int32_t baudrate; uint32_t flr_tx_ready = TMS570_SCI_FLR_TX_EMPTY; /* * Test for TMS570_SCI_FLR_TXRDY is not necessary * because both SCITD and SCITXSHF has to be empty * to TX_EMPTY be asserted. But there is no interrupt * option for TX_EMPTY. Polling is used isntead. */ /* Baud rate */ baudrate = rtems_termios_baud_to_number(cfgetospeed(t)); rtems_termios_device_lock_acquire(base, &lock_context); while ( (ctx->regs->GCR1 & TMS570_SCI_GCR1_TXENA) && (ctx->regs->FLR & flr_tx_ready) != flr_tx_ready) { /* * There are pending characters in the hardware, * change in the middle of the character Tx leads * to disturb of the character and SCI engine */ rtems_interval tw; rtems_termios_device_lock_release(base, &lock_context); tw = rtems_clock_get_ticks_per_second(); tw = tw * 5 / baudrate + 1; rtems_task_wake_after( tw ); rtems_termios_device_lock_acquire(base, &lock_context); } ctx->regs->GCR1 &= ~( TMS570_SCI_GCR1_SWnRST | TMS570_SCI_GCR1_TXENA | TMS570_SCI_GCR1_RXENA ); ctx->regs->GCR1 &= ~TMS570_SCI_GCR1_STOP; /*one stop bit*/ ctx->regs->FORMAT = TMS570_SCI_FORMAT_CHAR(0x7); switch ( t->c_cflag & ( PARENB|PARODD ) ) { case ( PARENB|PARODD ): /* Odd parity */ ctx->regs->GCR1 &= ~TMS570_SCI_GCR1_PARITY; ctx->regs->GCR1 |= TMS570_SCI_GCR1_PARITY_ENA; break; case PARENB: /* Even parity */ ctx->regs->GCR1 |= TMS570_SCI_GCR1_PARITY; ctx->regs->GCR1 |= TMS570_SCI_GCR1_PARITY_ENA; break; default: case 0: case PARODD: /* No Parity */ ctx->regs->GCR1 &= ~TMS570_SCI_GCR1_PARITY_ENA; } /* Apply baudrate to the hardware */ baudrate *= 2 * 16; bauddiv = (BSP_PLL_OUT_CLOCK + baudrate / 2) / baudrate; ctx->regs->BRS = bauddiv? bauddiv - 1: 0; ctx->regs->GCR1 |= TMS570_SCI_GCR1_SWnRST | TMS570_SCI_GCR1_TXENA | TMS570_SCI_GCR1_RXENA; rtems_termios_device_lock_release(base, &lock_context); return true; }
/* This is for setting baud rate, bits, etc. */ static int usart_set_attributes(int minor, const struct termios *t) { uint32_t brgr; uint32_t mode, baud, baud_requested; at91rm9200_usart_regs_t *usart; usart = usart_get_base(minor); if ( !usart ) return -1; /* Get current mode register */ mode = usart->mr & ~(US_MR_USMODE | US_MR_USCLKS | US_MR_CHRL | US_MR_PAR | US_MR_NBSTOP); /* Byte size */ switch (t->c_cflag & CSIZE){ case CS5: mode |= US_MR_CHRL_5; break; case CS6: mode |= US_MR_CHRL_6; break; case CS7: mode |= US_MR_CHRL_7; break; default: mode |= US_MR_CHRL_8; break; } /* Stop bits */ if (t->c_cflag & CSTOPB){ mode |= US_MR_NBSTOP_2; /* 2 stop bits */ } else mode |= US_MR_NBSTOP_1; /* 1 stop bits */ /* Parity */ if (t->c_cflag & PARENB){ /* Mark or Space parity */ if (t->c_cflag & PARODD){ mode |= US_MR_PAR_ODD; } else mode |= US_MR_PAR_EVEN; } else mode |= US_MR_PAR_NONE; baud_requested = t->c_cflag & CBAUD; /* If not, set the dbgu console baud as USART baud default */ if (!baud_requested) baud_requested = BSP_get_baud(); baud = rtems_termios_baud_to_number(baud_requested); brgr = (at91rm9200_get_mck() / 16) / baud; if (brgr > 65535){ /* BRGR is 16-bit, so switch to slower clock */ brgr /= 8; mode |= US_MR_USCLKS_MCK_DIV8; } usart->mr = mode; usart->brgr = brgr; return 0; }
int m5xx_uart_setAttributes( int minor, const struct termios *t ) { uint16_t sccr0 = sci_descs[minor].regs->sccr0; uint16_t sccr1 = sci_descs[minor].regs->sccr1; int baud; /* * Check that port number is valid */ if ( (minor < SCI1_MINOR) || (minor > SCI2_MINOR) ) return RTEMS_INVALID_NUMBER; /* Baud rate */ baud = rtems_termios_baud_to_number( t->c_cflag & CBAUD ); if (baud > 0) { sccr0 &= ~QSMCM_SCI_BAUD(-1); sccr0 |= QSMCM_SCI_BAUD((bsp_clock_speed + (16 * baud)) / (32 * baud)); } /* Number of data bits -- not available with MPC5xx SCI */ switch ( t->c_cflag & CSIZE ) { case CS5: break; case CS6: break; case CS7: break; case CS8: break; } /* Stop bits -- not easily available with MPC5xx SCI */ if ( t->c_cflag & CSTOPB ) { /* Two stop bits */ } else { /* One stop bit */ } /* Parity */ if ( t->c_cflag & PARENB ) sccr1 |= QSMCM_SCI_PE; else sccr1 &= ~QSMCM_SCI_PE; if ( t->c_cflag & PARODD ) sccr1 |= QSMCM_SCI_PT; else sccr1 &= ~QSMCM_SCI_PT; /* Transmitter and receiver enable */ sccr1 |= QSMCM_SCI_TE; if ( t->c_cflag & CREAD ) sccr1 |= QSMCM_SCI_RE; else sccr1 &= ~QSMCM_SCI_RE; /* Write hardware registers */ sci_descs[minor].regs->sccr0 = sccr0; sci_descs[minor].regs->sccr1 = sccr1; return RTEMS_SUCCESSFUL; }
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_cflag); /* 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, 115200); if (rv != 0) { rtems_fatal_error_occurred(0xdeadbeef); } rv = mpc55xx_esci_set_attributes(minor, &tty->termios); if (rv != 0) { rtems_fatal_error_occurred(0xdeadbeef); } sc = mpc55xx_interrupt_handler_install( self->irq, "eSCI", RTEMS_INTERRUPT_UNIQUE, MPC55XX_INTC_DEFAULT_PRIORITY, mpc55xx_esci_interrupt_handler, self ); if (sc != RTEMS_SUCCESSFUL) { rtems_fatal_error_occurred(0xdeadbeef); } mpc55xx_esci_interrupts_clear_and_enable(self); self->transmit_in_progress = false; return 0; }