This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Hello,
We are posting on behalf of Daniel Rush, who is not able to post his inquiry to this particular forum. Daniel will be notified once this post goes live, so he can join in and continue the discussion.
Post Description:
When a TX-Break signal is sent from my pc, the RXST bits are always set as a framing error. My interrupt resets the status bits after each interrupt but the BKDT flag is never set. I want to use the break detection to reset the processor. I've verified the TX-Break signal with a logic analyzer.
My peripheral setup is as follows:
{ sciA = SCI_init((void*)SCIA_BASE_ADDR, sizeof(SCI_Obj)); pieHandle = PIE_init((void*)PIE_BASE_ADDR, sizeof(PIE_Obj)); SCI_enable(sciA); // Protocol is 115200 BAUD, 8-N-1. sciA->SCIHBAUD = BAUD_115200 >> 8; // Set Baud rate sciA->SCILBAUD = BAUD_115200; // Set Baud rate SCI_disableParity(sciA); SCI_setNumStopBits(sciA, SCI_NumStopBits_One); SCI_setCharLength(sciA, SCI_CharLength_8_Bits); SCI_disableLoopBack(sciA); // FIFO and Interrupt setup SCI_enableTxFifo(sciA); SCI_enableRxFifo(sciA); SCI_enableRxErrorInt(sciA); SCI_enableRxInt(sciA); SCI_enableTxInt(sciA); // Enable interface SCI_enableRx(sciA); SCI_enableTx(sciA); // enable peripheral interrupts PIE_enableInt(pieHandle, PIE_GroupNumber_9, PIE_InterruptSource_SCIARX); PIE_enableInt(pieHandle, PIE_GroupNumber_9, PIE_InterruptSource_SCIATX); }
Hey Cody,
I have been using miniterm as a serial terminal which allows me to toggle on a tx-break, I can leave it on indefinitely(and verified that this just causes rx line to be low at the micro) with a stream of framing errors but never a BKDT flag. I had figured that after one framing error, and a reset of the flags, that I would recieve a BKDT flag, but it never ends up getting triggered.
Thanks
Daniel Rush
Daniel,
please confirm my understanding.
The only way to clear the FE/RXERROR flags is to reset the SCI, this will reset the logic that sets the BRKDT flag. Assuming that you are handling FE flags in a timely manner (less than 10 bit times) then you will reset the SCI module before a BRKDT condition could be detected.
Are you triggering an interrupt on a FE and resetting the SCI? I would expect this to happen much faster than the BRKDT detection.
Regards,
Cody
Cody,
Here is a code snippet from my interrupt:
if(char_index >= MAX_MESSAGE_LEN) { char_index = 0; memset(CMD_buf[write_index], '\0', MAX_MESSAGE_LEN); } else if(sciA->SCIRXST & SCI_SCIRXST_BRKDT_BITS) { // Break Detect: Handle Reset when break detected sendDebugMsg("Break"); return; } else if(sciA->SCIRXST & SCI_SCIRXST_OE_BITS) { // Overrun Error // TODO(DJR): This just discarding characters might change this in future SCI_reset(sciA); SCI_enable(sciA); return; } else if(sciA->SCIRXST & SCI_SCIRXST_FE_BITS) { // Framing Error SCI_reset(sciA); SCI_enable(sciA); // TODO(DJR): This just discarding characters might change this in future return; } else if(sciA->SCIRXST & SCI_SCIRXST_PE_BITS) { // Parity Error // TODO(DJR): Discard Char SCI_reset(sciA); SCI_enable(sciA); }
Daniel,
a FE always occurs 10 bit times before a BRKDT. With the way your code is written you will likely reset the SCI with every FE well before you would receive a BRKDT.
To prove this theory: comment the SCI reset and SCI enable lines in the else if statement for the FE, you should begin to see BRKDT errors.
Regards,
Cody
Cody,
This was one of my thoughts as well. So, after testing this, It does trigger the break detect after 10 bits, but, the reason that the SCI_reset is there is to clear the error bits so that another interrupt can be triggered, if they aren't cleared the first FE error is detected, and serviced, then all subsequent interrupts are ignored. As outlined in the technical reference, the bits are only cleared once a SW_Reset is set.
When running the debugger, I can step through the interrupt then once it returns to the main code keep stepping through and watching the RXST register, after some time the BKDT goes high but there's no way to know because it's not causing an interrupt. Not sure how I can keep getting interrupts without resetting the interface each time I receive an error.
Daniel,
yes, you understand correctly. I agree that the implementation is not good for identifying "Break Detects". If you would like to distinguish between FEs and BRKDTs you can setup a CPU timer when a FE is detected. The CPU timer should be configured to trigger an interrupt after more than 10 bit times. In the interrupt you can determine if a BRKDT happened or if only a FE occured, then reset the SCI module and synchronize to your UART transmitter accordingly.
I would suggest that you implement some sort of checksum for the transmitted data, this will help with robustness.
One other way around this issue is to define a series of transmission stop packets(instead of inteionally adding a break in communication), this series of packages shouldn't be common in your data.
As you are finding out one drawback of using UART is all of the handshaking is left to the application code.
Hope it helps,
Cody