Questions and discussions about the software that runs on the TD RF module itself.
omlu
 
Posts: 46
Joined: Tue Oct 06, 2015 8:27 am

TD_UART_SendBuffer() - PARITY BIT bug

by omlu Fri Aug 19, 2016 8:54 am

Hi all,

I have a weird behaviour when using TD_UART_SendBuffer();
The TD1208 is connected through its RX-TX pins to a microcontroller (LPC1768) and use Modbus protocol. The TD1208 is master and Reads Input Registers of the LPC.
I use two messages to read two sets of registers. I have no trouble with the first but with the second, the sent bytes are not the one expected. Let me explain:

First modbus message:
Code: Select all
void modbusConsumpt1Request (void) {
   uint8_t sfOutBuffer[8];
   uint16_t i = 0;
   sfOutBuffer[i++] = 0x02;   //address
   sfOutBuffer[i++] = 0x04;   //functioncode
   sfOutBuffer[i++] = 0x00;   //start add HI
   sfOutBuffer[i++] = 0x02;    //start add LO
   sfOutBuffer[i++] = 0x00;   //qt input reg HI
   sfOutBuffer[i++] = 0x02;    //qt input reg LO
   sfOutBuffer[i++] = 0xd0;   //CRC1
   sfOutBuffer[i++] = 0x38;   //CRC2

   TD_UART_SendBuffer (uartdescript, (void*) sfOutBuffer, i);
}

I have no trouble and the LPC answers correctly.

Second message:
Code: Select all
void modbusConsumpt2Request (void) {
   uint8_t sfOutBuffer2[8];
   uint16_t i = 0;
   sfOutBuffer2[i++] = 0x02;   //address
   sfOutBuffer2[i++] = 0x04;   //functioncode
   sfOutBuffer2[i++] = 0x00;   //start add HI
   sfOutBuffer2[i++] = 0x0c;    //start add LO
   sfOutBuffer2[i++] = 0x00;   //qt input reg HI
   sfOutBuffer2[i++] = 0x02;    //qt input reg LO
   sfOutBuffer2[i++] = 0xb1;   //CRC1
   sfOutBuffer2[i++] = 0xfb;   //CRC2

   TD_UART_SendBuffer (uartdescript, (void*) sfOutBuffer2, i);
}


With modbusConsumpt2Request, the four first bytes coming out of the TD1208 are correct but the following ones are incorrect. They have random values.

Does anyone have an explanation ? Maybe a method to debug this ?

Thank you,
Last edited by omlu on Fri Feb 10, 2017 8:17 am, edited 2 times in total.
User avatar
mstempin
 
Posts: 168
Joined: Thu May 07, 2015 9:24 am

Re: TD_UART_SendBuffer() unexpected bytes sent

by mstempin Wed Aug 24, 2016 9:08 am

This may be due to a baudrate accuracy problem. I have see nthis problem with som PIC MCUs which were not performing read oversampling and majority vote for sampling UART bits, causing these kind of errors.

The judge of peace would be to check with a oscilloscope and/or logic analyzer and see what is going on on the line.
omlu
 
Posts: 46
Joined: Tue Oct 06, 2015 8:27 am

Re: TD_UART_SendBuffer() unexpected bytes sent

by omlu Fri Jan 06, 2017 2:44 pm

So I checked the signals coming out of the TD1208 with a logic analyzer (the Logic from Saleae).

First, let me show you the UART settings and the functions sending modbus frame.
Code: Select all
void modbusInit (void) {
   uartdescript = TD_UART_InitGlobal ((void*) LEUART0,
         0,               //buslocation
         9600,            //busbaudrate
         true,            //busrxenable
         false,            //busshared
         8,               //busdatabits
         0,               //busparity
         1,               //busstopbits
         0,
         0,
         0);
   TD_UART_Start (uartdescript);
}

This is the function sending the modbus request and how it is called in TD_USER_Loop:
Code: Select all
static uint8_t sfOutBuffer[8];

void modbusConsumpt1Request (void) {
   modbusLoader = 1;
   uint16_t i = 0;
   sfOutBuffer[i++] = 0x02;   //address
   sfOutBuffer[i++] = 0x04;   //functioncode
   sfOutBuffer[i++] = 0x00;   //start add HI
   sfOutBuffer[i++] = 0x02;    //start add LO
   sfOutBuffer[i++] = 0x00;   //qt input reg HI
   sfOutBuffer[i++] = 0x02;    //qt input reg LO
   sfOutBuffer[i++] = 0xd0;   //CRC1
   sfOutBuffer[i++] = 0x38;   //CRC2

   TD_UART_SendBuffer (uartdescript, (void*) sfOutBuffer, i);
}

void modbusConsumpt2Request (void) {

   modbusLoader = 2;
   uint16_t i = 0;
   sfOutBuffer[i++] = 0x02;   //address
   sfOutBuffer[i++] = 0x04;   //functioncode
   sfOutBuffer[i++] = 0x00;   //start add HI
   sfOutBuffer[i++] = 0x0c;    //start add LO
   sfOutBuffer[i++] = 0x00;   //qt input reg HI
   sfOutBuffer[i++] = 0x02;    //qt input reg LO
   sfOutBuffer[i++] = 0xb1;   //CRC1
   sfOutBuffer[i++] = 0xfb;   //CRC2

   TD_UART_SendBuffer (uartdescript, (void*) sfOutBuffer, 8);
}

void TD_USER_Loop (void) {

   if ( consumpt == 1 ) {
      ledColor(OFF);
      modbusConsumpt1Request ();
      consumpt = 0;
   }

   if ( consumpt == 2 ) {
      ledColor(OFF);
      modbusConsumpt2Request ();
      consumpt = 0;
   }
}


Here are the results from the Logic analyzer; With the second request, the Logic analyzer understands the frame well but detects a framing error: the stop bit is missing in some bytes (see below the first three bytes)
0x02
0x04
0x00*
0x0C*
0x00*
0x02
0xB1*
0xFB
*bytes with framing error (stopbit missing)

first byte: 0x02 (correct)
byte0 - 0x02.PNG
byte0 - 0x02.PNG (3.92 KiB) Viewed 7528 times


second byte: 0x04 (correct)
byte1 - 0x04.PNG
byte1 - 0x04.PNG (3.91 KiB) Viewed 7528 times


third byte: 0x00 (correct but stop bit missing!)
byte2 - 0x00.PNG
byte2 - 0x00.PNG (4.63 KiB) Viewed 7528 times


While the slave of this modbus connection understands this:
Code: Select all
pos:00 byte:2
pos:01 byte:4
pos:02 byte:c
pos:03 byte:1
pos:04 byte:78
pos:05 byte:ff

So only the first two bytes are correct then it's all messed up... I'm guessing it has something to do with the stopbit.

Do you think is my logic analyzer who got it wrong or is there a known issue with stopbits and the TD1208 ?

Thank you
omlu
 
Posts: 46
Joined: Tue Oct 06, 2015 8:27 am

Re: TD_UART_SendBuffer() unexpected bytes sent

by omlu Thu Feb 09, 2017 12:56 pm

UP

Comme vous pouvez le constater, il n'y a pas de stopbit à la fin de certains bytes envoyés. Durant les nombreux essais effectués, les bytes 0x00 envoyés ne se terminent jamais par un stopbit. Concernant les bytes différents de 0x00, cela arrive de temps en temps...
omlu
 
Posts: 46
Joined: Tue Oct 06, 2015 8:27 am

Re: TD_UART_SendBuffer() - STOPBIT missing

by omlu Thu Feb 09, 2017 3:26 pm

So I looked further into it and I've been able to locate the issue: it concerns the PARITY BIT.

As a reminder, this is how I configure the UART:
Code: Select all
void busInit() {
   uartdescript = TD_UART_InitGlobal((void*) LEUART0,   //interface
         0,               //buslocation
         9600,            //busbaudrate
         true,            //busrxenable
         false,            //busshared
         8,               //busdatabits
         0,               //busparity
         1,               //busstopbits
         0,
         0,
         0);
   TD_UART_Start(uartdescript);
}


Here below, you can see the results with different configurations for the parity bit. For each parameter, you can see the signal and below a list of some bytes (correct and incorrect)


0 (NO) parity,
Despite the parity parameter sets at 0, the TD1204 still adds an EVEN PARITY bit.
(you can see which byte is displayed above each graphs, in the blue strip)
0 parity.png
Parity set: "0"
0 parity.png (32.43 KiB) Viewed 7479 times


1 (EVEN) parity
Here, everything works fine
1 EVEN parity.png
Parity set: "1"
1 EVEN parity.png (22.35 KiB) Viewed 7479 times


2 (ODD) parity
You can see below, the parity bit isn't correctly set for byte with "even count bits set"
2 ODD parity.png
Parity set: "2"
2 ODD parity.png (31.64 KiB) Viewed 7479 times



Please note that the TD1204 is going to be placed in an already existing circuit with a non-modifiable firmware. So I cannot change the parity of the other side of the modbus connection.

Would you have a solution ?

Thank you,
User avatar
mstempin
 
Posts: 168
Joined: Thu May 07, 2015 9:24 am

Re: TD_UART_SendBuffer() - STOPBIT missing

by mstempin Thu Feb 09, 2017 3:58 pm

If you look into "lib\libtdcore\src\td_uart.c" the source of the "TD_UART_InitGlobal()" function, this is how it uses the "parity" parameter:
Code: Select all
init.parity = (LEUART_Parity_TypeDef) parity;
...
LEUART_Reset(interface);
LEUART_Init(interface, &init);


The "LEUART_Parity_TypeDef)" type is defined in "lib\emlib\inc\em_leuart.h" as:
Code: Select all
/** Parity selection. */
typedef enum
{
  leuartNoParity   = LEUART_CTRL_PARITY_NONE,    /**< No parity. */
  leuartEvenParity = LEUART_CTRL_PARITY_EVEN,    /**< Even parity. */
  leuartOddParity  = LEUART_CTRL_PARITY_ODD      /**< Odd parity. */
} LEUART_Parity_TypeDef;


... which in turn are defined in "lib\Device\EnergyMicro\EFM32G\Include\efm32g_leuart.h" as:
Code: Select all
#define _LEUART_CTRL_PARITY_DEFAULT              0x00000000UL                         /**< Mode DEFAULT for LEUART_CTRL */
#define _LEUART_CTRL_PARITY_NONE                 0x00000000UL                         /**< Mode NONE for LEUART_CTRL */
#define _LEUART_CTRL_PARITY_EVEN                 0x00000002UL                         /**< Mode EVEN for LEUART_CTRL */
#define _LEUART_CTRL_PARITY_ODD                  0x00000003UL                         /**< Mode ODD for LEUART_CTRL */
#define LEUART_CTRL_PARITY_DEFAULT               (_LEUART_CTRL_PARITY_DEFAULT << 2)   /**< Shifted mode DEFAULT for LEUART_CTRL */
#define LEUART_CTRL_PARITY_NONE                  (_LEUART_CTRL_PARITY_NONE << 2)      /**< Shifted mode NONE for LEUART_CTRL */
#define LEUART_CTRL_PARITY_EVEN                  (_LEUART_CTRL_PARITY_EVEN << 2)      /**< Shifted mode EVEN for LEUART_CTRL */
#define LEUART_CTRL_PARITY_ODD                   (_LEUART_CTRL_PARITY_ODD << 2)       /**< Shifted mode ODD for LEUART_CTRL */


My guess is that you need to use the enum values leuartNoParity (0), leuartEvenParity (8) and leuartOddParity (12) instead of direct numeric values.

Please let us know how it goes!
omlu
 
Posts: 46
Joined: Tue Oct 06, 2015 8:27 am

Re: TD_UART_SendBuffer() - STOPBIT missing

by omlu Fri Feb 10, 2017 8:17 am

I tried with both leuartNoParity and LEUART_CTRL_PARITY_NONE: both don't work. (The parameter for No Parity is 'zero' in every define...)

For your information, I also tried with LEUART_CTRL_PARITY_ODD and it worked !

But still, I'd like no parity bit... :(
omlu
 
Posts: 46
Joined: Tue Oct 06, 2015 8:27 am

Re: TD_UART_SendBuffer() - STOPBIT missing

by omlu Thu Mar 23, 2017 9:06 am

mstempin wrote:Please let us know how it goes!


Hi,
Have you figured out a fix ?
Return to Firmware

Who is online

Users browsing this forum: No registered users and 7 guests