LINUX.ORG.RU

CMSPAR and PARODD

 , ,


0

1

necromant, получилось ли у тебя решить вопрос с отправкой данных в uart по 9-битному протоколу этим способом: http://www.lothosoft.ch/thomas/libmip/markspaceparity.php ?

Приветствую всех.
Я реализую 9-битный протокол пердачи данных по последовательному интерфейсу в формате: START DATA7...DATA0 MODE STOP (Parity-bit определяет признак адреса устройств и конца сообщения). Я нашёл как устанавливать этот бит в 1 или 0 с помощью техники описанной здесь

Как ты решил вопрос с чтением данных (игнором+проверкой пришедшего бита чётности)?

У меня такой отладочный код не работает. Данные уходят, но устройства молчат, ничего от них не получаю. Логического анализатора нет, чтобы линию проверить.

#ifndef CMSPAR
#warning Your kernel does not appear to support CMSPAR. Will try anyway.
#endif

struct termios tty; // настройки порта на i/o
struct termios rtty;

...

  memset (&tty, 0, sizeof tty);
  memset (&rtty, 0, sizeof rtty);

  cfsetospeed (&tty, B9600);

  tty.c_cflag &= ~CRTSCTS;  // Не использовать линию управления потоком RTS-CTS
  tty.c_cflag |= CLOCAL;    // Игнорируем контрольные линии модема?
  tty.c_cflag &= ~CSIZE;    // clean data bits
  tty.c_cflag |= CS8;       // set 8 data bits
  tty.c_cflag &= ~CSTOPB;   // set 1 stop bits by cleaning CSTOPB
  tty.c_cflag |= CREAD;     // Разрешает приём символов
  tty.c_oflag &= ~OPOST;    // Отключаем режим ввода, определяемый реализацией
  tty.c_iflag &= ~IGNPAR;   // Не игнорировать байты с ошибками чётности
  tty.c_cflag |=  PARENB;     // Enable parity generation
  tty.c_iflag &= ~INPCK;      // Disable parity checking
  tty.c_iflag |=  PARMRK;     // Enable in-band marking 
  tty.c_cflag |=  CMSPAR;

  if (tcsetattr (fd, TCSADRAIN, &tty) != 0) return;

void first() {
  tty.c_cflag |= PARODD;
  if (tcsetattr (fd, TCSADRAIN, &tty) != 0) return;
}

void next() {
  tty.c_cflag &= ~PARODD;
  if (tcsetattr (fd, TCSADRAIN, &tty) != 0) return;
}

void sendByte(unsigned char c) {
  wbuf[0] = c;
  int n = write(fd, wbuf, 1);
  printf("ret = %d bytes SEND [0x%02X]\n", n, wbuf[0]);
}

unsigned char recvBytes(int wait) {
  tty.c_cflag &= ~PARENB;
  tty.c_cflag |= CMSPAR;
  if (tcsetattr (fd, TCSADRAIN, &tty) != 0) return;

  for(int k = 0; k < MAXBUF; k++) rbuf[k] = 0x55;
  for(;;) {
    int n = read(fd, rbuf, 1);
    if (tcgetattr (fd, &rtty) != 0) {
      printf("Can not get attrs\n");
      break;
    }
    int mode = (rtty.c_cflag & PARODD) ? 1 : 0;
    if (n > 0) {
      printf("ret = %d bytes RECV [0x%02X] OK\n", n, rbuf[0]);
      printf("ret = %d bytes RECV [0x%02X] OK mode = %d\n", n, rbuf[0], mode);
      if (mode == wait)
        break;
    }
  }
  return rbuf[0];
}

Если для первого байта (ADDRESS) поставить бит чётности = 0, то устройства начинают отвечать, но иногда фризятся, и молчат. Приходится снова цепочку команд посылать, начиная с инициализации.

Ответ на: комментарий от a1batross

Я просто дам определения из советского справочника.

PARENB  Контроль чётности возможен.
PARODD  Контроль по нечётности, иначе по чётности.

\ Вот с пониманием второй опции у меня были проблемы.

Mirage1_ ()
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.