blob: f8bd56e926833da521d54335b463b7a0bd85789a (
plain) (
tree)
|
|
/*===============================================================*\
| File: termios_printk.c |
+-----------------------------------------------------------------+
| Copyright (c) 2002 IMD |
| Ingenieurbuero fuer Microcomputertechnik Th. Doerfler |
| Hebststr. 8, 82178 Puchheim, Germany |
| <Thomas.Doerfler@imd-systems.de> |
| The license and distribution terms for this file may be |
| found in the file LICENSE in this distribution or at |
| http://www.OARcorp.com/rtems/license.html. |
| all rights reserved |
+-----------------------------------------------------------------+
| TERMIOS printk support |
| this module performs low-level printk output using |
| a polled termios driver |
| |
+-----------------------------------------------------------------+
| date history ID |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 13.05.02 creation doe |
|*****************************************************************|
|* $Id$
*
|*****************************************************************|
\*===============================================================*/
#include <rtems.h>
#include <rtems/libio_.h>
#include <errno.h>
#include <stdio.h>
#include <fcntl.h>
#include <termios.h>
#include <rtems/termiostypes.h>
#include <rtems/bspIo.h>
#include <termios_printk.h>
/*
* internal variables
*/
int termios_printk_fd = -1;
struct rtems_termios_tty *termios_printk_tty;
static void _termios_printk_null_char( char c ) {return;}
BSP_output_char_function_type BSP_output_char = _termios_printk_null_char;
BSP_polling_getchar_function_type BSP_poll_char;
/*=========================================================================*\
| Function: |
\*-------------------------------------------------------------------------*/
void termios_printk_outputchar
/*-------------------------------------------------------------------------*\
| Purpose: |
| send one character to serial port |
+---------------------------------------------------------------------------+
| Input Parameters: |
\*-------------------------------------------------------------------------*/
(
char c /* character to print */
)
/*-------------------------------------------------------------------------*\
| Return Value: |
| <none> |
\*=========================================================================*/
{
static const char cr = '\r';
/*
* check, whether printk serial port is available
*/
if ((termios_printk_tty != NULL) &&
(termios_printk_tty->device.write != NULL)) {
/*
* call termios_printk polling callout, if available
*/
if (termios_printk_conf.callout != NULL) {
termios_printk_conf.callout();
}
/*
* send character to debug serial port
*/
if (c == '\n') {
termios_printk_tty->device.write(termios_printk_tty->minor,&cr,1);
}
termios_printk_tty->device.write(termios_printk_tty->minor,&c,1);
}
}
/*=========================================================================*\
| Function: |
\*-------------------------------------------------------------------------*/
char termios_printk_inputchar
/*-------------------------------------------------------------------------*\
| Purpose: |
| wait for one character from serial port |
+---------------------------------------------------------------------------+
| Input Parameters: |
\*-------------------------------------------------------------------------*/
(
void /* none */
)
/*-------------------------------------------------------------------------*\
| Return Value: |
| received character |
\*=========================================================================*/
{
int c = -1;
/*
* check, whether debug serial port is available
*/
if ((termios_printk_tty != NULL) &&
(termios_printk_tty->device.pollRead != NULL)) {
do {
/*
* call termios_printk polling callout, if available
*/
if (termios_printk_conf.callout != NULL) {
termios_printk_conf.callout();
}
/*
* get character from debug serial port
*/
c = termios_printk_tty->device.pollRead(termios_printk_tty->minor);
} while (c < 0);
}
return c;
}
/*=========================================================================*\
| Function: |
\*-------------------------------------------------------------------------*/
int termios_printk_open
/*-------------------------------------------------------------------------*\
| Purpose: |
| try to open given serial debug port |
+---------------------------------------------------------------------------+
| Input Parameters: |
\*-------------------------------------------------------------------------*/
(
const char *dev_name, /* name of device to open */
unsigned32 baudrate /* baud rate to use */
)
/*-------------------------------------------------------------------------*\
| Return Value: |
| 0 on success, -1 and errno otherwise |
\*=========================================================================*/
{
boolean err_occurred = FALSE;
rtems_libio_t *iop = NULL;
struct termios act_termios;
tcflag_t baudcode = B0;
if (termios_printk_fd >= 0) {
/*
* already initialized
*/
return 0;
}
/*
* translate baudrate into baud code
*/
switch(baudrate) {
case 50: baudcode = B50; break;
case 75: baudcode = B75; break;
case 110: baudcode = B110; break;
case 134: baudcode = B134; break;
case 150: baudcode = B150; break;
case 200: baudcode = B200; break;
case 300: baudcode = B300; break;
case 600: baudcode = B600; break;
case 1200: baudcode = B1200; break;
case 1800: baudcode = B1800; break;
case 2400: baudcode = B2400; break;
case 4800: baudcode = B4800; break;
case 9600: baudcode = B9600; break;
case 19200: baudcode = B19200; break;
case 38400: baudcode = B38400; break;
case 57600: baudcode = B57600; break;
case 115200: baudcode = B115200; break;
case 230400: baudcode = B230400; break;
case 460800: baudcode = B460800; break;
default : err_occurred = TRUE; errno = EINVAL; break;
}
/*
* open device for serdbg operation
*/
if (!err_occurred &&
(dev_name != NULL) &&
(dev_name[0] != '\0')) {
termios_printk_fd = open(dev_name,O_RDWR);
if (termios_printk_fd < 0) {
err_occurred = TRUE;
}
}
/*
* capture tty structure
*/
if (!err_occurred) {
iop = &rtems_libio_iops[termios_printk_fd];
termios_printk_tty = iop->data1;
}
/*
* set device baudrate
* (and transp mode, this is not really needed)
* ...
*/
/*
* ... get fd settings
*/
if (!err_occurred &&
(0 != tcgetattr(termios_printk_fd,&act_termios))) {
err_occurred = TRUE;
}
if (!err_occurred) {
cfsetospeed(&act_termios,baudcode);
cfsetispeed(&act_termios,baudcode);
if (0 != tcsetattr(termios_printk_fd,TCSANOW,&act_termios)) {
err_occurred = TRUE;
}
}
if (!err_occurred) {
BSP_output_char = termios_printk_outputchar;
BSP_poll_char = termios_printk_inputchar;
}
return (err_occurred
? -1
: 0);
}
|