Recent

Author Topic: Custom BAUD rate  (Read 2032 times)

ccrause

  • Full Member
  • ***
  • Posts: 185
Custom BAUD rate
« on: April 07, 2018, 12:57:38 pm »
I want to open serial connections and specify arbitrary BAUD rates. I can do this if I modify the SerSetParams procedure in serial.pp as follows:
Code: Pascal  [Select]
  1. const
  2.   TCGETS2 = $802C542A;  // Not defined in FPC
  3.   TCSETS2 = $402C542B; // Not defined in FPC
  4.   NCCS = 19; // value in FPC (32) doesn't work/seems incorrect
  5.  
  6. type
  7.   {$PACKRECORDS C}
  8.     Termios_ = record
  9.       c_iflag,
  10.       c_oflag,
  11.       c_cflag,
  12.       c_lflag  : cardinal;
  13.       c_line   : char;
  14.       c_cc     : array[0..NCCS-1] of byte;
  15.       c_ispeed,
  16.       c_ospeed : cardinal;
  17.     end;
  18.  
  19. procedure _SerSetParams(Handle: TSerialHandle; BitsPerSec: LongInt;
  20.   ByteSize: Integer; Parity: TParityType; StopBits: Integer;
  21.   Flags: TSerialFlags);
  22. var
  23.   tios: termios_;
  24.   customBAUD: boolean;
  25. begin
  26.   FillChar(tios, SizeOf(tios), #0);
  27.   customBAUD := false;
  28.  
  29.   case BitsPerSec of
  30.     50: tios.c_cflag := B50;
  31.     75: tios.c_cflag := B75;
  32.     110: tios.c_cflag := B110;
  33.     134: tios.c_cflag := B134;
  34.     150: tios.c_cflag := B150;
  35.     200: tios.c_cflag := B200;
  36.     300: tios.c_cflag := B300;
  37.     600: tios.c_cflag := B600;
  38.     1200: tios.c_cflag := B1200;
  39.     1800: tios.c_cflag := B1800;
  40.     2400: tios.c_cflag := B2400;
  41.     4800: tios.c_cflag := B4800;
  42.     19200: tios.c_cflag := B19200;
  43.     38400: tios.c_cflag := B38400;
  44.     57600: tios.c_cflag := B57600;
  45.     115200: tios.c_cflag := B115200;
  46.     230400: tios.c_cflag := B230400;
  47. {$ifndef BSD}
  48.     460800: tios.c_cflag := B460800;
  49. {$endif}
  50.     else
  51.     begin
  52.       customBAUD := true;
  53.       tios.c_cflag     := CBAUDEX;
  54.       tios.c_iflag     := IGNPAR or IGNBRK;
  55.       tios.c_oflag     := 0;
  56.       tios.c_lflag     := 0;
  57.       tios.c_ispeed    := BitsPerSec;
  58.       tios.c_ospeed    := BitsPerSec;
  59.       tios.c_cc[VMIN]  := 0;           // Return as soon as one byte is available
  60.       tios.c_cc[VTIME] := 5;           // 0.5 seconds timeout per byte
  61.     end;
  62.   end;
  63.  
  64.   tios.c_cflag := tios.c_cflag or CREAD or CLOCAL;
  65.  
  66.   case ByteSize of
  67.     5: tios.c_cflag := tios.c_cflag or CS5;
  68.     6: tios.c_cflag := tios.c_cflag or CS6;
  69.     7: tios.c_cflag := tios.c_cflag or CS7;
  70.     else tios.c_cflag := tios.c_cflag or CS8;
  71.   end;
  72.  
  73.   case Parity of
  74.     OddParity: tios.c_cflag := tios.c_cflag or PARENB or PARODD;
  75.     EvenParity: tios.c_cflag := tios.c_cflag or PARENB;
  76.   end;
  77.  
  78.   if StopBits = 2 then
  79.     tios.c_cflag := tios.c_cflag or CSTOPB;
  80.  
  81.   if RtsCtsFlowControl in Flags then
  82.     tios.c_cflag := tios.c_cflag or CRTSCTS;
  83.  
  84.   tcflush(Handle, TCIOFLUSH);
  85.   if customBAUD then
  86.     FpIOCtl(handle, TCSETS2, @tios)
  87.   else
  88.     tcsetattr(Handle, TCSANOW, Termios(pointer(@tios)^));
  89. end;
  90.  

My question is whether changing the value of NCCS in FPC is the correct way (the maximum constant value declared for c_cc is only 16), at least on Linux 64 target?

kupferstecher

  • Sr. Member
  • ****
  • Posts: 307
Re: Custom BAUD rate
« Reply #1 on: April 07, 2018, 03:30:47 pm »
I can't answer you, but doesn't the Baudrate depend on the clock frequency (of the serial controller)? So it maybe isn't possible to arbitrarily choose the baudrate?

ccrause

  • Full Member
  • ***
  • Posts: 185
Re: Custom BAUD rate
« Reply #2 on: April 07, 2018, 05:16:26 pm »
I can't answer you, but doesn't the Baudrate depend on the clock frequency (of the serial controller)? So it maybe isn't possible to arbitrarily choose the baudrate?
You are right, but that doesn't mean that a serial controller cannot run at many more possible baud rates than the "standard" values.  This is required for example by the debugwire protocol, which runs at the target MCU clock/128.  So if the controller is running at 8 MHz serial communication needs to occur at 62500 bit/s.  So far I've tested that the following serial-USB converters can handle custom data rates: CP2102, FT232, the serial-USB bridge on an Arduino Uno and the serial port of Pololu's USB AVR programmer. It seems fairly common nowadays.