Toon posts:

[Linux]rs232 en parity

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik ben bezig met een stukje code om (binaire) data in te lezen van de seriele poort. Dit gaat prima zonder parity, maar parity geeft me problemen.
In geval van een parity error, krijg ik nog steeds data (afhankelijk van de setup bv 0x00 ipv het gezonden karakter). Aangezien het (vaak) om binaire data gaat, is 0x00 echter een geldig waarde en kan ik die niet gebruiken om parity errors te ontdekken.

Zie ik iets over het hoofd? In de HOWTO en andere informatie (Michael Sweet's document) heb ik niet kunnen vinden hoe ik dit moet oplossen.

De volgende code wordt gebruikt om de seriele poort te openen en te initialiseren.
C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
static int setup_rs232(sCFG *pCfg, sINPUTINFO *ptr)
{
struct termios options;

  // open the device
  ptr->fd=open(ptr->device,O_RDWR,O_NOCTTY,O_NDELAY);
  if(ptr->fd==-1)
  {
    logit(pCfg->prog.logfile,pCfg->prog.verbose,errno,
          "INPUT ERROR: could not open '%s'",
          ptr->device);
    return -1;
  }
  fcntl(ptr->fd,F_SETFL,0);

  // set baudrate
  if(tcgetattr(ptr->fd,&options)==-1)
  {
    logit(pCfg->prog.logfile,pCfg->prog.verbose,errno,
          "INPUT ERROR: could not read current settings for '%s'",
          ptr->device);
    close(ptr->fd);
    ptr->fd=-1;
    return -1;
  }
  if(cfsetispeed(&options,ptr->data.rs232.baudrate)==-1)
  {
    logit(pCfg->prog.logfile,pCfg->prog.verbose,errno,
          "INPUT ERROR: could not modify input baudrate for '%s'",
          ptr->device);
    close(ptr->fd);
    ptr->fd=-1;
    return -1;
  }
  if(cfsetospeed(&options,ptr->data.rs232.baudrate)==-1)
  {
    logit(pCfg->prog.logfile,pCfg->prog.verbose,errno,
          "INPUT ERROR: could not modify output baudrate for '%s'",
          ptr->device);
    close(ptr->fd);
    ptr->fd=-1;
    return -1;
  }

  // set raw mode
  // 8Nx
  // NOTE: according to man pages, cfmakeraw returns an int
  //       according to termios.h, it does NOT
  cfmakeraw(&options);
  
  // enable receiver
  options.c_cflag|=(CLOCAL | CREAD);

  // parity; due to cfmakeraw, it's now disabled

  if(toupper(ptr->data.rs232.fmt[1])!='N')
  {
    options.c_cflag|=PARENB;            // enable
    options.c_iflag|=(INPCK|ISTRIP);
    if(toupper(ptr->data.rs232.fmt[1])=='E')
    {
      options.c_cflag&=~PARODD;         // even parity
    }
    else
    {
      options.c_cflag|=PARODD;          // odd parity
    }
  }

  // databits
  options.c_cflag&=~CSIZE;
  switch(ptr->data.rs232.fmt[0])
  {
  case '5':
    options.c_cflag|=CS5;
    break;
  case '6':
    options.c_cflag|=CS6;
    break;
  case '7':
    options.c_cflag|=CS7;
    break;
  case '8':
    options.c_cflag|=CS8;               // cfmakeraw already did this
    break;                              // tough luck
  }

  // stopbits
  if(ptr->data.rs232.fmt[2]=='1')
    options.c_cflag&=~CSTOPB;
  else
    options.c_cflag|=CSTOPB;

  // activate new settings (incl baudrate)
  if(tcsetattr(ptr->fd,TCSANOW,&options)==-1)
  {
    logit(pCfg->prog.logfile,pCfg->prog.verbose,errno,
          "INPUT ERROR: could not set new settings for '%s'",
          ptr->device);
    close(ptr->fd);
    ptr->fd=-1;
    return -1;
  }

  return 0;
}

[ Voor 7% gewijzigd door Verwijderd op 20-07-2004 11:13 ]


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 22-05 16:53
Er is een flag die IGNPAR en ook een die INPCK heet voor tcsetattr, misschien dat hiermee iets mis gaat ?

Zie ook hier: http://man.he.net/man2/tcsetattr

[ Voor 20% gewijzigd door farlane op 21-07-2004 09:16 ]

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Verwijderd

Topicstarter
Ik heb ~IGNPAR toegevoegd (voor de zekerheid); dat maakte geen verschil. Vervolgens IGNPAR toegevoegd en parity errors worden nu verborgen (maar ja, dat is niet echt de bedoeling).

Iemand enig idee hoe ik met ioctls (ofzo) aan de parity-error flag in de registers van de UART kan komen?

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 22-05 16:53
En die andere vlag ?

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.