-1

This is the relevant part of my C program (in Linux):

while (input != ' '){
 write(serial_port, msg, sizeof(msg));
 //1. here I would like to wait at least 100 us with the Tx line high
 //2. followed by at least 8us with the Tx line low
 //3. and then repeat the message
 input = mygetch();
}

As you can see, after each send of msg through the serial port, I would like to set the Tx line high for 100 microseconds and then low for 8 microseconds and then repeat the message until the user presses the space-bar.

Do I have this kind of control on the serial port using C in Linux?

TIA for your help.

Rui Alves
  • 172
  • 1
  • 7
  • 1
    `tcdrain(serial_port);` will wait until serial port has finished transmitting and the Tx line has returned to the quiescent 'high' level. `usleep(100);` will delay for at least 100 microseconds. On Linux, `tcsendbreak(serial_port, 1)` will set the Tx line 'low' for at least 1 millisecond (1000 microseconds) (the effect of non-zero duration varies on other operating systems). If 1000 microseconds is too long, you will need to use `ioctl(serial_port, TIOCSBRK); usleep(8); ioctl(serial_port, TIOCCBRK);` to turn "break" on, delay, then turn "break" off. – Ian Abbott Apr 26 '22 at 10:37
  • "//1. here I would like to wait at least 100 us with the Tx line high" looks like a mistake. You likely want to "... after transmission is done, wait at least 100 us with the Tx line high". Perhaps executing some _flush_ operation before waiting. – chux - Reinstate Monica Apr 26 '22 at 10:50
  • Rui Alves, "followed by at least 8us with the Tx line low ...and then repeat the message" is also a problem. Line needs to be allow to go high, for some time, before the message. IAC, the 8us goal is likely sensitive to the baud. – chux - Reinstate Monica Apr 26 '22 at 10:51
  • See comments in https://stackoverflow.com/questions/38350430/flushing-on-uart-doesnt-work-as-expected – sawdust Apr 26 '22 at 19:21
  • Note that in my earlier comment I used the terms 'high' and 'low' when I should have used the terms 'logic 1 level' and 'logic 0 level'. Note that in RS-232, 'logic 1 level' is negative voltage (w.r.t. signal ground) and 'logic 0 level' is positive voltage. So if you meant 'high' to mean positive voltage and 'low' to mean negative voltage then you will have to adjust what I wrote in my previous comment, but the same techniques can be used in a different order. However, for TTL (or TTL3v3) serial lines, 'logic 1 level' will be 5V (or 3.3V) and 'logic 0 level' will be 0V. – Ian Abbott Apr 27 '22 at 16:28

1 Answers1

1

Yes. The default state of a serial line when not sending any data is "mark" (high, for a single-ended line). To send a space (low), set the break bit. Clear the break bit to restore the idle state.

As pointed out in the comments, the tty device ioctls TIOCSBRK and TIOCCBRK may be used to send and clear break.

https://linux.die.net/man/4/tty_ioctl

stark
  • 12,615
  • 3
  • 33
  • 50
  • Thank you. I have not done this yet but have investigated and seems to be the way to go for my needs. Will come back if I find anything of note as I implement this solution. – Rui Alves Apr 27 '22 at 01:10