1
\$\begingroup\$

I am using a FT232RL chip with FTD2XX_NET.dll I've made a program which writes and reads data to/from AVR atmega32 mcu. First writes data, then reads data as answer.

Now, i want to make an event which indicated me if there's available unreaded data, only when AVR sends data to FTDI buffer and ONLY then. Whithout forcing my program to making loops for checking available data. For my purpose, i want to do the mcu to sends data only when he wants, and the PC must to knows when there's new data in FTDI buffer's chip

\$\endgroup\$
4
  • \$\begingroup\$ Serial "data available" events are very unreliable, because the data gets stuck down in the USB-serial converter chip and Windows doesn't know about it. Better approach is to have a read call running in the background at all times. That way the converter sends the data to the PC promptly (when either the requested number of bytes are received or the inter-character timeout elapses). You can associate an event to "read finished" \$\endgroup\$
    – Ben Voigt
    Aug 26, 2014 at 15:35
  • \$\begingroup\$ The FTDI drivers event signaling is quite reliable in my experience. \$\endgroup\$ Aug 26, 2014 at 15:58
  • \$\begingroup\$ But there's SetEventNotification function in ftd2xx programmer's guide. So, i thinking may I can do something with this \$\endgroup\$
    – MrBit
    Aug 26, 2014 at 16:00
  • \$\begingroup\$ @whatsisname: It's still terribly wasteful compared to a read operation. \$\endgroup\$
    – Ben Voigt
    Aug 26, 2014 at 16:02

2 Answers 2

1
\$\begingroup\$

Well, first off, from the PC side, it is impossible to know when the AVR sends data to the FTDI chip, you only can know when the FTDI sends its data to the PC. I'm going to assume that is what you meant.

I don't remember what all functions are in the .NET wrapper for the D2XX interface, but in the raw ftd2xx.dll there is a function FT_SetEventNotification which will do what you want. I'm sure it's exposed in the .NET wrapper somehow or another.

Anyways you create an EventWaitHandle, pass it to that function, and as long as your device is opened, the FTDI driver will set it as signaled when a character arrives. Your program, or your reading loop, waits on that handle, then when a character arrives, you read whats in the buffer and parse away.

Keep in mind, you are still going to have to loop over and over while reading data, but what the event signaling is mostly good for is taking it easy on CPU usage.

\$\endgroup\$
19
  • \$\begingroup\$ "when the FTDI sends its data to the PC" That's exactly the point of my comment on the question. The FTDI sends its data if there is a read call on the PC. So always have a read call. If you use the OVERLAPPED structure, the read call won't block, and it will trigger an event when it completes. FT_SetEventNotification is useless for this. \$\endgroup\$
    – Ben Voigt
    Aug 26, 2014 at 16:04
  • 1
    \$\begingroup\$ @BenVoigt: The FTDI sends data to the PC immediately and it is put in a buffer maintained by the FTDI driver. It is at that moment the event is signaled. This is different than when you are using the device as a virtual COM port, which is what I think you are thinking about. When using the D2XX interface you don't use CreateFile() and you have a lot more direct access to the features of the chip. \$\endgroup\$ Aug 26, 2014 at 16:27
  • \$\begingroup\$ TO understand, FT_SetEventNotification is quite useful for this or must to find another way? May some other function? \$\endgroup\$
    – MrBit
    Aug 26, 2014 at 16:35
  • \$\begingroup\$ Is there more CPU usage with FT_SetEventNotification? \$\endgroup\$
    – MrBit
    Aug 26, 2014 at 16:37
  • 1
    \$\begingroup\$ @BenVoigt: It will send as many bytes per USB packet as it can. The Chip has a 256/128 byte RX/TX buffer, and the driver I believe has a 4096/4096 byte buffer. In any case you are not able to inspect the buffer of the chip itself, the driver takes care of that. \$\endgroup\$ Aug 26, 2014 at 18:19
0
\$\begingroup\$

The D2XX API basically is a way to make the Win32 File API available on other OSes. All its functions try to work exactly like the Win32 APIs.

A number of programmers have learned an inferior approach to communications, usually by bad examples written by framework programmers who don't actually use serial ports on a daily basis. Ask yourself which of these conversations is better:

  • > Tell me about incoming data.
  • < Ok.
  • < EVENT! Here's some data that just arrived.
  • > Thanks! Please tell me if you receive any more.

vs

  • > Tell me about incoming data.
  • < Ok.
  • < EVENT! I heard something!
  • > What did you hear?
  • < Here's the received data.
  • > Thanks! I'm ready to hear about more data.

Clearly the first version is a lot simpler and more efficient. That's why I discourage you from asking "How do I get that 'I heard something!' event?" Instead you should focus on how to get the "Here's the new data" event.

If you want an event when your serial-connected device sends you data, use FT_W32_ReadFile in overlapped mode. When you do that, the OVERLAPPED structure has an hEvent member, that event will be triggered when data arrives1. And the data itself will already be in your buffer, you won't need a separate operation to get it.

The .NET class AutoResetEvent is the way to create a kernel event object that you attach to the OVERLAPPED hEvent.

1 Actually, when the read operation completes. It can complete because the buffer was filled, or because a timeout (configured using FT_W32_SetCommTimeouts) occurred. The ReadIntervalTimeout is fantastic, because it causes the read to finish whenever there is a gap in the data. This generally corresponds to individual messages from the attached device. While you shouldn't rely on one read completion = one message, the fact is that having an event at the end of a message is the optimal combination of buffering and responsiveness.

\$\endgroup\$
4
  • \$\begingroup\$ The D2XX API is completely unlike the Win32 File API. You are thinking of the FT-Win32 functions which is specifically for porting serial port applications. \$\endgroup\$ Aug 26, 2014 at 18:59
  • \$\begingroup\$ @whatsisname: They are part of the D2XX API. The part with the best design, because they copied the Win32 design which is based on decades of serial port experience. \$\endgroup\$
    – Ben Voigt
    Aug 26, 2014 at 19:00
  • \$\begingroup\$ Is there any data on latency V message length for these methods ? \$\endgroup\$
    – Spoon
    Aug 26, 2014 at 20:14
  • \$\begingroup\$ @Spoon: With an overlapped read, the buffering latency is controlled by the timeouts set via FT_W32_SetCommTimeouts \$\endgroup\$
    – Ben Voigt
    Aug 26, 2014 at 20:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.