Page 1 of 1

USART timeout_cb

Posted: Sun Jul 14, 2019 1:36 pm
by vrollei
Hi,

I am trying to enable timeout_cb for Modbus communication timeout handling, but there is no call of timeout_cb

timeout_cb and timeout values are set in config
and RTOEN and RTOIE set to 1

How to enable timeout_cb?

Thanks!

Re: USART timeout_cb

Posted: Sun Jul 14, 2019 1:42 pm
by vrollei
It works!

Re: USART timeout_cb

Posted: Sun Jul 14, 2019 1:51 pm
by Giovanni
You need also to set the timeout field in the configuration structure, it initializes the RTOR register.

Edit: OK, great... :)

Giovanni

Re: USART timeout_cb

Posted: Sun Jul 14, 2019 2:03 pm
by vrollei
Is it possible to implement something like this:

1. Start receive
2. Wait first byte and if there is no one for some period T, then it is timeout.
3. If first byte received then use timeout_cb to determine end of frame.

Re: USART timeout_cb

Posted: Sun Jul 14, 2019 2:32 pm
by Giovanni
You can do that using a virtual timer, start the receive (of one byte) and the timer at same time within a critical section.

Giovanni

Re: USART timeout_cb

Posted: Sun Jul 14, 2019 2:38 pm
by vrollei
yes,

I tried to implement it using rxchar_cb, vt and uartStartReceive with rx buffer size 256 bytes (it is maximum Modbus frame size).
It would not work as I understand. rxchar_cb will not be called on char received.
Right?

EDIT: It is critical not to restart usart receive, otherwise there is chance to miss char....

Re: USART timeout_cb

Posted: Sun Jul 14, 2019 2:55 pm
by Giovanni
rxchar_cb is there to "consume" incoming unexpected data, it is better if you start an explicit 1 byte receive then start a receive for the rest.

Ideally you should never have an rxchar_cb.

Giovanni

Re: USART timeout_cb

Posted: Sun Jul 14, 2019 3:45 pm
by vrollei

Code: Select all

size_t n = 1; 
if (usartReceiveTimeout(usartDriver, &n, buffer, TIME_MS2I(MODBUS_RX_TIMEOUT_MS)) == MSG_OK) {
  usartStartReceive(usartDriver, MODBUS_BUFFER_SIZE - 1, buffer + 1);
  chSemWait(rxtimeout_sem);
  n = MODBUS_BUFFER_SIZE  - usartStopReceive(usartDriver);
} else {
  RX_TIMEOUT;
}



Does usartStopReceive count char from usartReceiveTimeout?

Re: USART timeout_cb

Posted: Sun Jul 14, 2019 4:02 pm
by vrollei
one more thing:

Code: Select all

  chSemWait(rxtimeout_sem);
  chThdSleepMilliseconds(500);
  n = MODBUS_BUFFER_SIZE  - usartStopReceive(usartDriver);



whithout chThdSleepMilliseconds n will be 1

It seems I set wrong timeout value...

Re: USART timeout_cb

Posted: Sun Jul 14, 2019 4:32 pm
by Giovanni
usartStopReceive() returns the number of frames still not received in the current receive operation.

I suggest you implement your protocol as a state machine and use (UART and timers) callbacks for transitions. The driver has been designed with that scenario in mind.

Giovanni