Going crazy with UART (witch hunt)

cancel
Showing results for 
Search instead for 
Did you mean: 

Going crazy with UART (witch hunt)

Jump to solution
2,233 Views
biafra
Contributor V

Hi everyone,

I'm going crazy using a (simple) UART: I'm spending a lot of hours searching for a bug that corrupts data.

I'm using a custom board with MK66F2M0 device, MCUXpresso 10.1.1, SDK 2.3.0 and UART FreeRTOS driver: the UART is connected to a GSM modem. The UART seems to work fine, the modem answers to several init AT commands: I say seems because the received strings are random corrupted. With a computer using another modem and a serial terminal program, I can establish the connection (ATD command), receiving the CONNECT string on both sides (said that on the embedded side the string can be randomly corrupted).

At this time I send several data all the same (0x01 char repeated 144 times): at the end of the transfer I break the execution to watch the received buffer (2k buffer size), I can see that some of the data are not what I expect them to be (on average 2/3 to 9/10 bytes are corrupted, sometimes even none).

I've made many trials to find the cause, but none of them was useful.

  • Changed board
  • Changed modem
  • Increased priority of the UART interrupt
  • Increased priority of the receiving task
  • Decreased the baud rate (from 57600 to 9600)
  • Verified the line from modem to K66 with an oscilloscope (all data are ok)
  • Added a check every time the data register is read to see if the data is received as I expect it to be:

uint8_t rcfifo1 = base->RCFIFO;
uint8_t a = base->D;
uint8_t rcfifo2 = base->RCFIFO;
*(data++) = a;
if( a != 1 )

a = rcfifo1 + rcfifo2; //an instruction to hit the breakpoint

  • If I put a breakpoint on the last line, the execution stops when there is the error: the corrupted data is read from the UART data register, it's not a buffer related problem; at this time rcfifo1 and rcfifo2 are always 1 and 0 respectively: the data in the RXFIFO was present, the data reading was not done when the FIFO was empty

The same board is used even for another project where there is another serial device instead of the modem: in this case the UART works fine with the same driver.

I ported the UART interrupt example supplied with the SDK (no FreeRTOS), and repeated the test: all the data are ok, no corruption is found.

At this point I suspect that some other task can accidentally access to the UART and produce the problem, but how can I find the cause?

I tried using some watchpoint, but with no success.

Does anyone have some suggestion, some method to use to discover the issue?

Many thanks

Biafra

1 Solution
631 Views
biafra
Contributor V

Hi everyone,

Whitch catched!:smileywink:

The problem was due to a resistor:smileyshocked::smileyshocked:

With this pullup resitor inserted, the level shfter between the modem and the K66 didn't work fine: level 0 voltage was 1.6 V instead 0 V. The images above show the signal at the modem side!

Many thanks to everyone

Biafra

View solution in original post

14 Replies
632 Views
biafra
Contributor V

Hi everyone,

Whitch catched!:smileywink:

The problem was due to a resistor:smileyshocked::smileyshocked:

With this pullup resitor inserted, the level shfter between the modem and the K66 didn't work fine: level 0 voltage was 1.6 V instead 0 V. The images above show the signal at the modem side!

Many thanks to everyone

Biafra

View solution in original post

631 Views
jingpan
NXP TechSupport
NXP TechSupport

Hi Biafra,

I think first you have to check if the baudrate is accurate enough. UART protocol allows 5% deviation.
Your code read UART_D twice. I think you should check whether receive FIFO is empty before read second time.
If you suspect other task disturb the UART, You can close those tasks to see if it works better. You can also try the Loop Mode so that you can do local debug.
If you still can't find the bug, you can post you code here. I'll try to debug for you.

Regards,

Jing

631 Views
biafra
Contributor V

Hi Jing,

Many thanks for your answer.

I already checked the baud rate: it's very precise.

Why do you say the UART->D register is read twice?

The matter about other tasks is a bit complicated: yesterday I break the code putting the UART test in many places. The UART test is a loop in the main task, so no other instructions are executed and no other tasks are created after the UART test.

do
{
      if(( UART_RTOS_Receive( &handle, &rcv, 1, &NRec ) == kStatus_Success ) && NRec )
      {
            demoRingBuffer[ rxIndex ] = rcv;
            rxIndex++;
            rxIndex %= sizeof( demoRingBuffer );
      }
} while( 1 );

If I put the UART test at the beginning of the application (after the initialization code) it works with no problem. Then I moved the UART test gradually forward: it continued working fine until I moved it after the creation of the ADC task. So I commented out the ADC task creation and it worked. I was very happy: I found the reason! But a further test put me back: if I put the UART test even further ahead, after the creation of another task, it started not working again. So I think the problem is not related to the UART, but to some kind of interaction between tasks.

Can you provide some example about using the loop mode?

I think I can't post the code because it's related to a commercial product: I have to talk with my boss.

Many thanks

Biafra

631 Views
jingpan
NXP TechSupport
NXP TechSupport

Hi,

Sorry I made a misunderstanding.

can you compare all of the UART registers in these two situations? I think there must be some difference there.

Set C1[LOOPS]=1 and C1{RSRC]=0 can enable the loop operation.

Regards,

Jing 

631 Views
biafra
Contributor V

Hi Jing,

I made the tests you have said.

The UART registers are the same in both cases.

With loop operation it works fine.

I've made another test with an oscilloscope, recording all the signals. The three images show what I found. The packet is the byte 0x01 repeated 144 times received from a GSM modem connected to the UART. The waves are the RX signal, the TX signal, the CTS signal and the RTS signal respectively. The UART is configured with RX FIFO enabled with a watermark of 1.

Start.PNG

This image shows the packet start: at the end of the stop bit of the first byte, the RTS signal goes high because the RXFIFO watermark is configured to 1 byte: the interrupt routine handle the RDRF flag, it reads the D register so the RTS signal goes low. At the end of every byte there is the same behaviour: after the stop bit there is the start bit of the subsequent character

Error.PNG

This image shows the error: the first RTS rise is at the end of the stop bit, then there is the start bit of another character. The strange thing is that the second RST rise is not at the end of the stop bit, but at the end of the first data bit of the subsequent character. From this point forward, all the charcters are received as 0x40, as if the first bit of data were actually the start bit.

End.PNG

This image shows the packet end: the last character is received as 0xC0.

I don't know how it can be generated: all the previous characters are received correctly and the waveforms are ever the same; I don't know why suddenly the RTS signal goes hig in the wrong place.

What esle can I verify?

Many thanks

Biafra

631 Views
jingpan
NXP TechSupport
NXP TechSupport

Hi,

Sorry for reply you so late.

From these three picture, I still doubt this is because the UART clock is not precise enough. Since you send data continuously, the deviation is accumulated. At some time, the sample point of last stop bit will move to next start bit. Then receive data will be slipped a bit.
1.Can you add a stop bit(two stop bit) in your GSM block to see if it can resolve this problem?
2.You said each time you send 2k byte. Is the number of correct data never change or only change 1 or 2? If yes, I think my doubt should be correct.
3.When incorrect data received, is there any error bit set in S1 register?

In addition, there is an e4647 in k66 errata which you should take care.

Regards,

Jing

631 Views
biafra
Contributor V

Hi Jing,

Many thanks for your answer.

I wil try your suggestions.

I have to correct you. I don't send 2k byte, the packet size is 144 byte (used only for test, to verify this problem), 2 kB is the size of the receiving buffer, where the received data are stored.

Another clarification: the packet data is 144 byte, but they are not received continuously: they are received in sub-packets, each of 24 byte size. This is due to different speeds: the baud rate between the UART and the receiving modem is 57600, but the one between the sending and the receiving modem is 9600 (the GSM data speed), so the receiving modem sends data to the UART in sub-packets.

I've tried even 9600 bps between the UART and the receiving modem, but the errors are the same: the only difference is that the 144 byte packet is not splitted in sub-packets.

The number of corrupted data is different between a test and another: sometimes the packet is received correctly, sometimes the error comes at the begin of the packet, sometimes in the middle, sometimes at the end, sometimes more than once.

About the not precise UART clock, I verified the BDH and BDL registers and there are the values I expect: with core clock of 180 MHz and a desired baud rate of 57600, there are the following values:

BDH[SBR] = 0

BDL[SBR] = 195 (0xC3)

C4[BRFA] = 10 (0x0A)

I mesured the bit time in TX line and RX line: both are 17.4 µs (0.2 % error compared to 17.36 µs).

I had already read the e4647 errata and the workaround was already done.

Many thanks

Biafra

631 Views
jingpan
NXP TechSupport
NXP TechSupport

Hi,

I have no idea about what is happened. Can you make a demo which can show this problem and post here or email to me?

BTW, have you ever tested to connect K66 to computer? Is the problem still there?

And, did you measure the GSM modem's UART bitrate?

 

Regards,

Jing

631 Views
biafra
Contributor V

Hi Jing,

Finally I've built a demo.

This demo initialize the modem and then waits for incoming messages.

Once the modem is initialized, I make a call with another modem, then I send a message and finally I hang up the line. In the rx buffer I should find:

  • The answers to modem init commands
  • The incoming call packets ("RING", "CONNECT 9600")
  • The packets I sent (144 bytes of 0x01 value)
  • The hang up packet ("NO CARRIER")

Instead I find these packets corrupted.

Many thanks

Biafra

631 Views
biafra
Contributor V

Hi Jing,

I'll try to build a demo.

I can't connect the K66 to a PC: I should build an interface board, because the modem is directly mounted on the board (it's a GSM embedded module).

I did the measures above directly on modem pins: both TX and RX bitrates are 17.4 µs, they are correct for a 57600 baud rate.

Many thanks

Biafra

631 Views
jingpan
NXP TechSupport
NXP TechSupport

Hi,

do you have other MCU board which has uart port? You can also try to connect to those board.

Regards,

Jing

631 Views
biafra
Contributor V

Hi Jing,

I did the same test on another board and the behaviour is the same.

Many thanks

Biafra

631 Views
jingpan
NXP TechSupport
NXP TechSupport

Hi,

I mean let them mutual talk.

Regards

Jing

631 Views
biafra
Contributor V

Hi Jing,

I'll try asap.

Many thanks

Biafra