I am playing with serial port under windows 2k trying to implement modbus master working over rs485 in halfduplex mode . 232-485 covnerters transmit direction is controlled via RTS line (similar to described in Serial port complete).
My problem is - i can not properly detect end of transmission (when last character has been transmitted from com port ).
Writing done as (just tried with 8 bytes):
- Escape communiaction function to assert RTS
- Writing data via WriteFile (write timeouts do not affect transmission currently set to 0)
- Waiting on comm events tx empty (comm mask has been set on tx empty event previously )
- Escape comm funtion to deassert RTS
Measured RTS line pulse for above procedure - 100 microseconds. COM port speed 19200 . But 8 byte transfer actually takes 4.5 millseconds. I assume - WriteFile returns upon sending last character in software tx buffer , but not last character from hardware buffer .
Then setting RTS control to TOGGLE in DCB structure extends RTS pulse up to 15 millseconds against 4.5 miliseconds of actual transfer which is too big - i loose 10 millisecond of transfer time per packet, while actual modbus turnaround for mentioned speed should not be more than 1.75 milliseconds (t3.5 timer).
Then i have tried to set a Sleep() for 1 millisecond after transfer - but again RTS pulse delayed up to 15 milliseconds , whch is about poor windows timing resolution for Sleep() .
Microsoft MSDN says - to detect end of transfer for last character port driver should be told, but as ioctl codes are not available - it is impossible to check whether it can be done in that way .
Till now 2 workaournds can be done :
- receive while transmit and match received packet towards sent to detect end when last transmitted character is received .
- After sending signal high resolution timer (MM timer) to have a 1-3 millisecond accuracy
Is there any other ways to detect end of actual transfer for com port?