Hi,
...
sammel ich Zeichen für Zeichen geht mir am PI manchmal eines durch die Lappen weil der PI nicht
...
warum machst Du das dann nicht über Interrupt?
Spoiler anzeigen
...
typedef struct serial_param_t {
unsigned char device[256];
int dev_fd;
struct termios oldtio;
struct termios rawtio;
unsigned int baud;
unsigned char databit;
unsigned char parity;
unsigned char stoppbits;
unsigned char handshake;
} serial_param;
int inp_present;
#define COMPORT "/dev/ttyAMA0"
#define E_PARAM_BAUDRATE -10
#define E_PARAM_DATABIT -11
#define E_PARAM_PARITY -12
#define E_PARAM_STOPPBITS -13
#define E_PARAM_HANDSHAKE -14
#define E_PARAM_DEVICE -15
#define E_PARAM_NULL -16
#define E_PARAM_NOFD -17
/* ---------------------------------------------------------------------------------
| void set_defaults( struct serial_param_t *ctl_param )
|
| clear structure and set defaults
-----------------------------------------------------------------------------------
*/
void set_defaults( struct serial_param_t *ctl_param )
{
if( ctl_param != NULL )
{
memset( ctl_param->device, '\0', sizeof(ctl_param->device) );
strcpy( ctl_param->device, COMPORT );
ctl_param->baud = 9600;
ctl_param->databit = 8;
ctl_param->parity = 'N';
ctl_param->stoppbits = 1;
ctl_param->handshake = 'N';
}
...
/* ---------------------------------------------------------------------------------
| typedef void (*sighandler_t)(int);
|
| Declaration for a signal handler
-----------------------------------------------------------------------------------
*/
typedef void (*sighandler_t)(int);
/* ---------------------------------------------------------------------------------
| static sighandler_t handle_signal (int sig_nr, sighandler_t signalhandler)
|
| setup a new signal handling for a specific signal
-----------------------------------------------------------------------------------
*/
static sighandler_t handle_signal (int sig_nr, sighandler_t signalhandler)
{
struct sigaction neu_sig, alt_sig;
neu_sig.sa_handler = signalhandler;
sigemptyset (&neu_sig.sa_mask);
neu_sig.sa_flags = SA_RESTART;
if (sigaction (sig_nr, &neu_sig, &alt_sig) < 0)
return SIG_ERR;
return alt_sig.sa_handler;
}
/* ---------------------------------------------------------------------------------
| static void catch_SIGIO(int val)
|
| A simple handler that can be installed using handle_signal
-----------------------------------------------------------------------------------
*/
static void catch_SIGIO(int val)
{
inp_present = 1;
return;
}
...
/* ---------------------------------------------------------------------------------
| int open_device( struct serial_param_t *ctl_param )
|
| open serial device
-----------------------------------------------------------------------------------
*/
int open_device( struct serial_param_t *ctl_param )
{
// open non-blocking
if( ctl_param != NULL )
{
ctl_param->dev_fd = open( ctl_param->device, O_RDWR|O_NOCTTY|O_NONBLOCK);
return( ctl_param->dev_fd );
}
return( E_PARAM_NULL );
}
/* ---------------------------------------------------------------------------------
| void close_device( struct serial_param_t *ctl_param )
|
| close the serial device
-----------------------------------------------------------------------------------
*/
void close_device( struct serial_param_t *ctl_param )
{
if( ctl_param != NULL )
{
if( ctl_param->dev_fd > 0 )
{
close( ctl_param->dev_fd );
ctl_param->dev_fd = 0;
}
}
}
/* ---------------------------------------------------------------------------------
| int reset_device( struct serial_param_t *ctl_param )
|
| reset old parameter of serial port
-----------------------------------------------------------------------------------
*/
int reset_device( struct serial_param_t *ctl_param )
{
int fail;
if( ctl_param != NULL )
{
fail = tcsetattr( ctl_param->dev_fd, TCSANOW, &ctl_param->oldtio );
}
else
{
fail = E_PARAM_NULL;
}
return(fail);
}
/* ---------------------------------------------------------------------------------
| int setup_device( struct serial_param_t *ctl_param )
|
| set parameter for serial communication, save current settings
-----------------------------------------------------------------------------------
*/
int setup_device( struct serial_param_t *ctl_param )
{
int fail = 0;
if( ctl_param != NULL )
{
if( ctl_param->dev_fd > 0 )
{
fail = tcgetattr( ctl_param->dev_fd, &ctl_param->oldtio );
fail = tcgetattr( ctl_param->dev_fd, &ctl_param->rawtio );
cfmakeraw( &ctl_param->rawtio );
switch( ctl_param->baud )
{
case 50:
cfsetspeed ( &ctl_param->rawtio, B50 );
break;
...
}
switch( ctl_param->databit )
{
...
case 8:
ctl_param->rawtio.c_cflag |= CS8;
break;
default:
fail = E_PARAM_DATABIT;
}
switch( ctl_param->parity )
{
...
case 'n':
case 'N':
ctl_param->rawtio.c_cflag |= IGNPAR;
ctl_param->rawtio.c_cflag &= ~PARENB;
break;
default:
fail = E_PARAM_PARITY;
}
switch( ctl_param->stoppbits )
{
case 1:
break;
case 2:
ctl_param->rawtio.c_cflag |= CSTOPB;
break;
default:
fail = E_PARAM_STOPPBITS;
}
switch( ctl_param->handshake )
{
case 'n':
case 'N':
ctl_param->rawtio.c_cflag |= CLOCAL;
break;
case 'x':
case 'X':
ctl_param->rawtio.c_iflag |= IXON;
break;
default:
fail = E_PARAM_HANDSHAKE;
}
...
if( !fail )
{
tcflush( ctl_param->dev_fd, TCIFLUSH);
fail = tcsetattr( ctl_param->dev_fd, TCSANOW, &ctl_param->rawtio );
}
...
...
if( (failed = open_device( &ctl_param )) > 0 )
{
if( (failed = setup_device( &ctl_param )) == 0 )
{
loop = 1;
inp_present = 0;
handle_signal( SIGIO, catch_SIGIO );
fcntl(ctl_param.dev_fd, F_SETOWN, getpid());
fcntl(ctl_param.dev_fd, F_SETFL, FASYNC);
...
salü,
-ds-