strange problem with parity bit (for odd) and stop bits (for two) in UART-KL25Z

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

strange problem with parity bit (for odd) and stop bits (for two) in UART-KL25Z

2,741 Views
ofiryaish
Contributor II

hey, 
(code is below)
I'm using UART to communicate with the computer (using both C# in visual studio and hyperterminal). First, I made the parity bit even and  one stop bit, and everything was working fine.
next I tried to change the parity bit to odd, and when sending one byte (one char) from PC it works fine, but when I send two bytes something went wrong and I sometimes gets framing error and sometimes parity error (usually both in same). the first char is detected well and the second is detected as something which I didn't send at all. when the KL25Z is sending chars to the PC, I get part of the letters, and the others are labeled with '?'

the question is why this can happen when the only change between the even option and the odd option is the bit PT in UART0_C2?

another problem occurs when I set 2 stop bit (even in parity)- it's doing the same a I described  with odd situation, but this time when sending from the KL25Z to the PC, the PC gets nothing.

worth mentioning: the setting of the UART in the PC and the KL25Z are changing as they should.  

here is the the code I wrote for changing the setting the the UART:

    /********************************************************************

changeUARTsetting- receive from PC the wanted bound rate, parity bit and stop bit and change the UART settings.

After receiving the info, KL25Z will send ACK char for PC.

*********************************************************************/

void changeUARTsetting(){

char settings_info[3]; //info array; settings_info[0]=bound rate, settings_info[1]=parity bit, settings_info[2]=stop bit.

UART0_C2 &= ~UART0_C2_RIE_MASK; //disable receiver interrupt 

/* Wait until character has been received -for first initial*/

while (!(UART_S1_REG(UART0_BASE_PTR) & UART_S1_RDRF_MASK));

settings_info[0]=uart_getchar (UART0_BASE_PTR);

settings_info[1]=uart_getchar (UART0_BASE_PTR);

settings_info[2]=uart_getchar (UART0_BASE_PTR);

sendACK((char)GenralACK);

while(!(UART_S1_REG(UART0_BASE_PTR) & UART_S1_TC_MASK)); /* Wait until trr is completed */

//disable transmitter and receiver 

UART0_C2 &= ~(UART_C2_TE_MASK

| UART_C2_RE_MASK );

switch (settings_info[0]){

case '1':

Uart0_Br_Sbr(CORE_CLOCK/2/1000, SDA_SERIAL_BAUD2400);

break;

case '2':

Uart0_Br_Sbr(CORE_CLOCK/2/1000, SDA_SERIAL_BAUD9600);

break;

case '3':

Uart0_Br_Sbr(CORE_CLOCK/2/1000, SDA_SERIAL_BAUD19200);

break;

case'4':

Uart0_Br_Sbr(CORE_CLOCK/2/1000, SDA_SERIAL_BAUD38400);

break;

}

switch(settings_info[1]){

case '0': //no parity

UART0_C1 &= ~(UART0_C1_PE_MASK | UART0_C1_M_MASK); //set also 8 bit data

break;

case '1': //even parity

UART0_C1 |= UART0_C1_PE_MASK | UART0_C1_M_MASK; //set also 9 bit data 

UART0_C1 &= ~UART_C1_PT_MASK;

break;

case '2': //odd bit

UART0_C1 |= UART0_C1_PE_MASK |UART_C1_PT_MASK | UART0_C1_M_MASK; //set also 9 bit data 

break;

}

switch(settings_info[2]){

case '1': //one stop bit 

UART0_BDH &= ~UART0_BDH_SBNS_MASK;

break;

case '2': //two stop bit

UART0_BDH |= UART0_BDH_SBNS_MASK;

break;

}

// Enable Transmitter, Receiver, Receive interrupt 

UART0_C2 = UARTLP_C2_RE_MASK | UARTLP_C2_TE_MASK | UART_C2_RIE_MASK; // Enable Transmitter, Receiver, Receive interrupt 

}

thank you

Tags (2)
0 Kudos
7 Replies

2,167 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi, Yaish,

Firstly, I suggest you use fixed char format protocol for example parity bit, stop bits number, otherwise, even the configuration information is incorrect, your code will clash, in other words, you have to use predefined parity bit(even with or without), stop bit.

Secondly, it seems that the code has issue:

while (!(UART_S1_REG(UART0_BASE_PTR) & UART_S1_RDRF_MASK));

settings_info[0]=uart_getchar (UART0_BASE_PTR);

settings_info[1]=uart_getchar (UART0_BASE_PTR);

settings_info[2]=uart_getchar (UART0_BASE_PTR);

I suppose that the uart of Kl25z does not support FIFO, you have to use the lines:

while (!(UART_S1_REG(UART0_BASE_PTR) & UART_S1_RDRF_MASK));

settings_info[0]=uart_getchar (UART0_BASE_PTR);

while (!(UART_S1_REG(UART0_BASE_PTR) & UART_S1_RDRF_MASK));

settings_info[1]=uart_getchar (UART0_BASE_PTR);

while (!(UART_S1_REG(UART0_BASE_PTR) & UART_S1_RDRF_MASK));

settings_info[2]=uart_getchar (UART0_BASE_PTR);

Hope it can help you.

BR

Xiangjun Rong

0 Kudos

2,167 Views
ofiryaish
Contributor II

hey,
the uart_getchar function is doing what you have mentioned:


char uart_getchar (UART_MemMapPtr channel)
{
/* Wait until character has been received */
while (!(UART_S1_REG(channel) & UART_S1_RDRF_MASK));

/* Return the 8-bit data from the receiver */
return UART_D_REG(channel);
}

As I said I get all the right char from the computer, and the UART registers are changed as I thought they would.

I managed to narrow the problem down

the problem with the even parity is gone (thanks to a delay made in the PC side (C#- visual studio)).
now the problem with the stop bit is still occurring. and this time I know that the problem is with the KL25Z, because I checked it both in visual studio and hyperterminal  (hyperterminal-outside software which should work for serial communication).

about the fixed char format protocol, know it's I should do in general, but this is what I have been asked for :smileysad:

thank you 

0 Kudos

2,167 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi, Ofir,

do you means that you have issue when you use two STOP bits for each byte transfer? Note that the receiver should also be configured to receive byte with two stop bits.

If it is the case, you can transfer multiple 0x55, then check the waveform of TX pin, check if the waveform is okay or not.

Hope it can help you

BR

Xiangjun Rong

0 Kudos

2,167 Views
ofiryaish
Contributor II

hey,
the problem occurs when I change to stop bit from 1 to 2, if I send only character (byte) from the PC the KL25z is reading it well, when sending more then one character at once, it popping an overrun error.
transmitting from KL25z is working fine, I think because of the fact the the KL25Z is sending byte by byte.

I added the configurations I made for 2 stop bit does I missing something?

thank you

0 Kudos

2,167 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi, Ofir,

The overrun error means that the KL25 uart is not fast enough to read the uart data register, I suppose that you use interrupt mode to read the uart data register, but the KL25 is overloaded. How about reducing the baudrate of uart?

BR

Xiangjun Rong

0 Kudos

2,167 Views
ofiryaish
Contributor II

if both systems has the same bound rate, why something like that can happen? 

thank you, 

0 Kudos

2,167 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi, Ofir,

Regarding the overrun error, I suppose that the KL25 is too busy to read the uart receiver data register before the next character arrive. Pls disable the other module, just enable uart work and have a try.

BR

Xiangjun Rong

0 Kudos