Jump to content
43oh

Howto send break signal on UART?


Recommended Posts

I have a custom board with a device hooked up to the hardware UART on a MSP430G2553 and need to send a break signal followed by a specific character and wonder how to do that correctly in Arduino/Energia.

 

After some experimenting with help of a logic analyzer I came up with the following code snippet:

// Start hardware serial communication
Serial.begin(57600);

/* Do stuff like Serial.print("blabla"); here */

// Ok, now we need to send a break to the other device

// Stop serial communication
Serial.end();

// Start break signal on MCU TX pin
digitalWrite(P1_2, LOW);

// Wait a while. Must be longer than a single character at the last baudrate.
// One character at 57600 baud takes ~1000 us, so 200 ms should be way more than enough.
delay(200);

// Don't use digital I/O to finish the break signal because 
//   Serial.begin() already sends a start bit.
// By not pulling the line up the start bit will just lengthen the 
//   break condition a little bit and then return the line to high level.
//digitalWrite(P1_2, HIGH);

// Restart serial communication. This will pull the signal on the TX line up again.
// Serial.begin is needed because Serial communication is broken after digital I/O.
Serial.begin(57600);

// Send special break character so that de other device can do auto baud detection.
Serial.print(0x55);

/* Continue normally and do more Serial.print("blabla"); here */

Questions:

Is it correct Energia behavior that Serial.begin(57600) always sends a start bit?

Is it correct that Serial.end() and Serial.begin() is needed before digital I/O is performed on the Tx pin of the MSP?

Is there a better way to implement this? E.g. change baudrate to e.g. 300 baud, send 0x00 and switch back to 57600 baud?

 

Thanks for your input.

Link to post
Share on other sites

The User's Guide says:

 

To transmit a break set the UCTXBRK bit, then write 0h to UCAxTXBUF. UCAxTXBUF must be ready for new data (UCAxTXIFG = 1). This generates a break with all bits low. UCTXBRK is automatically cleared when the start bit is generated.

 

When using Energia, call flush(), set UCTXBRK, and write() a 0 byte.

(How long must the break be? Longer than what the G2553 sends?)

 

begin() is needed to connect the UART to the pin. (end() is needed only if you want to use the pin as GPIO later.)

 

begin() does not yet send any data, so the output is in the idle state (high).

Link to post
Share on other sites

Thanks both!

 

Thanks for the Users Guide bit (I should have RTFM first :huh: ). While the code in the TS works, I'll try an implementation of that as well.

 

 

 

(How long must the break be? Longer than what the G2553 sends?)

I was transmitting on 57600 baud, so the break should be longer than ~1000 us, my 100 ms is a bit over the top admittedly :)

 

 


begin() does not yet send any data, so the output is in the idle state (high).

Well, I'm not so sure about that. When the output is in high idle state (using digitalWrite) and then begin() is called, my logic analyzer sees a start bit: the level changes from high to low (few microseconds) to high again. Perhaps this is a side effect from attaching the UART logic to the pin?

 

Screenshot of the bit transmitted by Serial.begin(), bit length = 4 us:

23gzf4p.png

Link to post
Share on other sites

Try: 

sendbreak()
{
 digialWrite(1, LOW);  // Set pin to serial "idle" state.
 endSerial();
 pinMode(1, OUTPUT);
 digitalWrite(1, HIGH);  // Send BREAK
 delay(10);              // for 10ms
 serial.Begin(BITRATE);  // back to serial mode
}

Also see: http://forum.arduino.cc/index.php?topic=39579.0

I had seen that topic and the code snippet is wrong in my opinion. A break on RS232 is a prolonged LOW level (not HIGH as in this example). RS232 idle level is HIGH, see e.g. here:

 

The diagram shows the next bit after the Stop Bit to be Logic 0. This means another word is following, and this is its Start Bit. If there are no more data coming then the receive line will stay idle (logic 1). We have encountered something called a "Break" Signal. This is when the data line is held in a Logic 0 state for a time long enough to send an entire word. Therefore if you don't make the line idle again, then the receiving end will interpret this as a break signal.

Also, to me it's weird that pinMode() is only used after the first digitalWrite()?

 

Anyway, the above example is quite old. The custom endSerial() function seems to be replaced by current Arduino's flush() and end() functions. So I can rewrite the function as follows:

sendbreak()
{
digialWrite(1, LOW); // Set pin to serial "idle" state.
Serial.flush();
Serial.end();
pinMode(1, OUTPUT);
digitalWrite(1, HIGH); // Send BREAK
delay(10); // for 10ms
Serial.Begin(BITRATE); // back to serial mode
}

This looks a lot like what I already tried, see lines 18 to 22 in the top post.

 

Anyway, @@energia, forget the break stuff for a moment and just answer this question please, if you can:

Is it correct Energia behavior that Serial.begin(57600) always sends a start bit?

 

Edit:

I've gone back to just a G2 launchpad and a simple sketch just to test the serial.begin together with digital I/O and the behavior in my logic analyser is not consistent. Sometimes the analyser sees an extra bit, sometimes not. Don't know what to think of this.

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...