STM32F4 serial driver misses sometimes one or morecharacters

ChibiOS public support forum for topics related to the STMicroelectronics STM32 family of micro-controllers.

Moderator: RoccoMarco

Wafelijzer
Posts: 8
Joined: Mon Sep 21, 2015 9:09 am

STM32F4 serial driver misses sometimes one or morecharacters

Post by Wafelijzer »

Hi All,

Hardware info:
Custom board with STM32F407
Serial port running at 921600 baud and RTS/CTS flow control (voltage levels are fine and verified)
Sierra Wireless HL8547 3G modem with serial port AT command interface.

chconf.h: SERIAL_BUFFERS_SIZE 512

I'm implementating a driver for a 3G modem which uses the AT command specification. I wrote a cross-platform driver which has a hook to read/write of serial buffered data.
The driver will call the registered callbacks to fetch buffered data and I mapped it to use the ChibiOS HAL serial driver. And is defined as follows:

The callbacks:

Code: Select all

static int32_t dncm_modem_write_serial(const void *buf, size_t nbyte)
  {
    return sdWriteTimeout(&DNCM_MODEM_DEV, buf, nbyte, MS2ST(1));
  }

  static int32_t dncm_modem_read_serial(void *buf, size_t nbyte)
  {
    return sdReadTimeout(&DNCM_MODEM_DEV, buf, nbyte, MS2ST(1));
  }


I decided to use the read/write with a 1 millisecond timeout so the calling thread can sleep if there is no data.
On the serial port I see the following output:

Code: Select all

AT+KTCPSND=1,82\r\n
CONNECT\r\n


The "reader" which calls the read callbacks reports the following:

Code: Select all

reader(26): AT+KTCPSND=1,82\r\n
CONNCT\r\n


The "reader" should report:

Code: Select all

reader(27): AT+KTCPSND=1,82
CONNECT

RUN CB [CONNECT]


I'm 100% sure the thread is fast enough to read the data, because the buffer size is 512 bytes and the command I send will wait until the CONNECT is received
so no other serial port traffic is received.

As seen, I only mis one character most of the time. Then the driver stops working because it is not able to match the returned pattern.
I also used the sdReadTimeout because the BaseSequentialStream will not report zero length when reading nothing, this screws op the
multithreading because I would sleep a little after I got no data at all.

I'm a little lost for now, hopefully somebody can point me how to investigate further where the character(s) are lost.

Kind regards,
Wafel
User avatar
Giovanni
Site Admin
Posts: 14893
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 997 times

Re: STM32F4 serial driver misses sometimes one or morecharac

Post by Giovanni »

Hi,

Try TIME_IMMEDIATE as timeout, that makes the functions to read/write without waiting if the buffers are empty/full.

Your loop could use the Serial Driver event source to wait for data to be available (read) or for the buffer to have space (write), it also reports communication errors.

BTW, you may be experiencing communication errors, chars with wrong framing or parity are not queued. Your protocol should be able to handle that, you cannot assume the communication to be always errors-free.

Also enable in chconf.h: checks, assertions and state checker. Those are able to catch a lot of common mistakes.

Giovanni
Wafelijzer
Posts: 8
Joined: Mon Sep 21, 2015 9:09 am

Re: STM32F4 serial driver misses sometimes one or morecharac

Post by Wafelijzer »

Hi Giovanni,

Thanks for your reply. I already had all the needed checks enabled for ChibiOS. I switched to TIME_IMMEDIATE for sdReadTimeout (which is basicly the sdAsynchronousRead)
I created a event thread which checks for the available flags:

Code: Select all

static THD_WORKING_AREA(dncm_modem_event_wa, 128);
static THD_FUNCTION(dncm_modem_event_thr, arg)
{
   (void)arg;

   event_listener_t serial_listener;


  chEvtRegisterMaskWithFlags(chnGetEventSource(&DNCM_MODEM_DEV),
                             &serial_listener,
                             EVENT_MASK(1),
                             CHN_INPUT_AVAILABLE | SD_FRAMING_ERROR | SD_PARITY_ERROR);

  /* Thread activity.*/
  while (true) {
    /* Waiting for any of the events we're registered on.*/
    eventmask_t evt = chEvtWaitAny(ALL_EVENTS);
 
    /* Serving events.*/
    if (evt & EVENT_MASK(1)) {
      /* Event from the serial interface, getting serial
         flags as first thing.*/
      eventflags_t flags = chEvtGetAndClearFlags(&serial_listener);

      /* Handling errors first.*/
      if (flags & CHN_INPUT_AVAILABLE) {
         dncm_dbg_printf("INPUT AVAILABLE\r\n");
      }

      if (flags & SD_FRAMING_ERROR) {
         dncm_dbg_printf("FRAMING ERROR\r\n");
         chSysHalt("SD#FE");
      }

      if (flags & SD_PARITY_ERROR) {
         dncm_dbg_printf("PARITY ERROR\r\n");
         chSysHalt("SD#PE");
      }
   }
   }
}


I get:

Code: Select all

INPUT AVAILABLE
reader(16): AT+KTCPSND=1,38
INPUT AVAILABLE
reader(10):\r\n
CONECT\r\n


The FTDI reads:

Code: Select all

AT+KTCPSND=1,38\r\n
CONNECT\r\n


I still don't seem to get parity error or framing error and still a character is missed. The FTDI cable which is connected between
the modem and stm32f4 displays correctly the received data from the modem. This means the clocks of the USART seemed to be
configured correctly and we are not hitting the edge on bit recovery (else the USART MUST emit the parity or framing error).
User avatar
Giovanni
Site Admin
Posts: 14893
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 997 times

Re: STM32F4 serial driver misses sometimes one or morecharac

Post by Giovanni »

Try reducing speed and see if you get the same problem. Events should also report overflow errors, verify if you get any of those.

Giovanni
Wafelijzer
Posts: 8
Joined: Mon Sep 21, 2015 9:09 am

Re: STM32F4 serial driver misses sometimes one or morecharac

Post by Wafelijzer »

Hi Giovanni,

I have added `SD_OVERRUN_ERROR` and checked it. It seems to get into this state on higher baudrates.
When I run at 115200 baud it just runs fine (for the time I tested). It should no happen because the
buffer size is 512 bytes. I also seems to happen with a buffer twice as big (1KByte).
User avatar
Giovanni
Site Admin
Posts: 14893
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 997 times

Re: STM32F4 serial driver misses sometimes one or morecharac

Post by Giovanni »

There are two kind of overrun errors.

The first case is the CPU unable to serve ISRs fast enough, it is an HW overflow, the STM32 UARTs have no deep FIFOs to an IRQ is triggered for each received frame. The second case the the CPU unable to empty software queues fast enough. You may place breakpoints in the Serial driver and see what is happening exactly.

The alternative would be to use the UART driver with DMA but it is not very suited for line-oriented I/O.

Giovanni
Wafelijzer
Posts: 8
Joined: Mon Sep 21, 2015 9:09 am

Re: STM32F4 serial driver misses sometimes one or morecharac

Post by Wafelijzer »

Thanks for you reply.

I set breakpoints to STM32/LLD/USARTv1/serial_lld.c:148 where:

Code: Select all

   if (sr & USART_SR_ORE)
    sts |= SD_OVERRUN_ERROR;

https://github.com/ChibiOS/ChibiOS/blob ... lld.c#L148

And set breakpoint to the point where a byte is put onto the I/O queue at os/hal/src/serial.c:L207:

Code: Select all

  if (iqPutI(&sdp->iqueue, b) < Q_OK)
chnAddFlagsI(sdp, SD_OVERRUN_ERROR);

https://github.com/ChibiOS/ChibiOS/blob ... ial.c#L207

The debugger breaks at the point of the USART_SR_ORE bit and seems to be emitted from the hardware instread of an I/O overrun.
The value of USART_SR is 0x2a8:
- ORE (Overrun error): set
- RXNE (Read data register not empty): set
- TXE (Transmit data register empty): set
- CTS (CTS flag): set
Last edited by Wafelijzer on Mon Sep 21, 2015 3:52 pm, edited 1 time in total.
User avatar
Giovanni
Site Admin
Posts: 14893
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 997 times

Re: STM32F4 serial driver misses sometimes one or morecharac

Post by Giovanni »

Apparently interrupts spaced by just 10uS are close to the limit.

Try moving the UART IRQ priority to 3 in mcuconf.h, the default priority is quite low, this way it should not be preempted by other IRQs and will have less jitter.

Giovanni
Wafelijzer
Posts: 8
Joined: Mon Sep 21, 2015 9:09 am

Re: STM32F4 serial driver misses sometimes one or morecharac

Post by Wafelijzer »

You are right, I changed the UART IRQ priority to 3 and until now I didn't have had any issues running a few minutes (normaly 20 seconds I halted the system).

Giovanni, I would to thank you for your help and point me at the correct debug steps and is much appreciated!
User avatar
Giovanni
Site Admin
Posts: 14893
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 997 times

Re: STM32F4 serial driver misses sometimes one or morecharac

Post by Giovanni »

You are welcome.

It is good to know the limits of the system.

Giovanni
Post Reply