Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Half Duplex

Status
Not open for further replies.

hennep

Programmer
Dec 10, 2000
429
I am working on a program that uses the serial port. The protocol uses a half duplex connection. The direction of the connection is switched with one of the pins DTR or CTS

I need to know the exact moment that the outputbuffers are empty to change the direction.
Can somebody tell if this can be done without the use of third party drivers ?
 
Are you working in Windows or DOS? If you are working in Windows, you have very little control over the hardware unless you are writing a specific device driver for it. It does not allow you to access the hardware directly.
 
Well, to amend xwb's statement: Up to and including Win95 You can access the hardware (ports and such) in the old facioned DOS-way by hooking into the interruptvectors but starting from Win98 MicroSoft uses the NT-approach: no direct port access without special driver!!!

Thus is it VERY hard to get what You want without a deep knowledge of drivers and such. There might be a way though, look at the TimeOut values keenly, in the serial-recieve TimeOuts it's possible to make it wait until anything is recieved, it might just be possible to get it to send and "hang the task" until whole buffer is transmittet. look carefully in the help-section. Totte
 
I was trying to do all the communication using the windows api's. The problem is that windows buffers the output. I was hoping there is some way to flush the buffers even if this means that the uart is still sending the last character when the function returns. I do not want to use third party drivers and I do not want to write a device driver myself either. This would mean that I have to start it all over again when microsoft releases a new OS version. Using the standard api's ther is a slightly bigger chance that my programs keep working.
 
Look closely at 'WriteTotalTimeoutMultiplier' and 'WriteTotalTimeoutConstant' in the 'COMMTIMEOUTS' of help, they MAY hold the solution for You, trial and error would give the result. Best of luck. Totte
 
I will have a look at your solution, hopefully i can solve the problem soon.

thanks,
Hennie
 
Please keep me informed about any progress, i haven't the time to test it myself and it might come handy some day... Totte
 
Totte,

I'm a little closer to the solution. I was able to borrow a digital two channel oscilliscope. With the use of the FlushFileBuffers API I could send all bytes except the last one.
The FlushFileBuffers function empties the windows transmit buffer and returns after the last byte is sent to the UART.
I was testing with 38400 baud and sending the last byte took another 250 µs. To create such a delay I used a very sophisticated algorhytm: for( int i=0; i<30000; i++ );
It got quite late last night. After a good night sleep I realized I could have sent one extra dummy byte.

I think I can finish this tonight.

best regards,
Hennie
 
OK, thanks for the info.
By the way you could do a Sleep(1) right after the Flush, that will give You 1 ms.....
Your solution with a do-nothing-wait would however also do the trick but the dummy character could be a problem depending on Your protocoll.
Do assume that a timeslot with another program !WILL! occur between Flush() and next command, this would give that the extra character will be output BEFORE You gets to the direction-switching thus it COULD garble the protocoll....
With the speed and simplex....i take that You are doing a RS485-network and that You sends a question to the &quot;other end&quot; and switches direction on the MAX485 (generic type). Please be sure that the time from the last char in the question till the first char in the reply is big enough, otherwise You will lack a bit of the answer.
Best of luck. Totte
 
I'm communicating with a microcontroller circuit using rs485. The controller sends a reply between 0 !!! and 5 ms after receiving the last bit. The single ms delay is not available.
The extra dummy byte does not disturb the protocol. Trailing characters will be ignored by the controller. It only reacts when it recognises the header, its device number and a fixed set of data.
The only thing that bothers me are windows events. I could miss the first character(s) of the answer when direction is not reversed quick enough. The only thing I can do about that is repeat the question and try to catch the next answer.
 
Tight timing!!! I do howevere have a recollection that it's possible to &quot;stretch&quot; the timeslot by declaring it as an important part (it won't break the timeslot in that program part), thus You can do the flush-and-change-direction as an classified part and thereby get the whole answer. I can however NOT remember how to declare it, i believe that i found in the Help-section under threads.....
As it is now i can't assist in finding it, i'm above my neck in work and got the kids when i come home.....but there IS a way!!!! Totte
 
It is always hacktic just before christmas, please let me know when you get a &quot;total recall&quot;.
 
Aw man...i remembered wrong! I found &quot;TCriticalSection&quot; but it's a memory-lock, not a time-slot lock!
There could however be a way:
do the question-sending;
Wait(0); // This terminates this slot
Flush(SerialPort); // This runs first at next slot
Change_Direction(); // and this ought to run in same slot

Just an idea.... Totte
 
This would work if the flush operation took only a few µs
In my case every byte sent to the serial port takes about 250 µs (at 38400 baud).
A packet of 12 bytes will need a timeslot of at least 3 ms.
Can somebody tell me the duration of a timeslot in windows ?
 
I dont need the full 3 ms, timing is critical only after the last byte is sent. Using the code I've posted below, the packet is sent except the last byte. From that moment only 250 µs are needed to finish, with a little luck this fits within a timeslot.

unsigned long ulPriorityClass = GetPriorityClass( Application->Handle );
SetPriorityClass( Application->Handle, HIGH_PRIORITY_CLASS );
com->ClrDTR(); // direction output
com->WriteBufferWait( &quot;\x82\x97\x01\x02\x01&quot;, 5 ); // on return, 250 µs until uart ready
SetPriorityClass( Application->Handle, REALTIME_PRIORITY_CLASS );
Sleep(0); // start new timeslot
com->WriteBufferWait( &quot;\x03\0x00&quot;, 2 ); // send last byte and dummy, max 250 µs (38400 baud)
com->SetDTR(); // direction input
SetPriorityClass( Application->Handle, ulPriorityClass ); // restore normal priority


Is the &quot;Application->Handle&quot; the proper handle to pass to these priority functions ?
 
Bright!
I'm a bit unsure about about what parameter, it !might! be 'this' (see help) but apart from that it looks sharp. Totte
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top