Serial Communication using D2XX library and FT232 chip
This is a short tutorial on how to use the D2XX library from FTDI to setup a serial connection with a microcontroller board. In this tutorial we will use a PC/Laptop running Windows OS to communicate with a MSP430 development board (Launchpad). The PC side uses a FT232RL based USB2SERIAL Converter board to convert the USB signals to Serial, which is then send to the UART of the MSP430 microcontroller.
The tutorial is written in C language and compiled using GCC.
The software running on the PC side uses the API's provided by the D2XX library to communicate with the microcontroller. Please note that FTDI provides D2XX libraries for both Linux and Windows, this tutorial deals only with the windows version (ftd2xx.lib).
The tutorial is specific to USB to Serial chips manufactured by FTDI (FT232RL, FT232RQ etc).
On the PC side I am using a USB2SERIAL converter board based on FT232 (details are here) on the MSP430 side I am using MSP430 Launchpad development board (Contains a 20 pin MSP430G2553) manufactured by Texas Instruments.
The devices are connected in null mode configuration (Tx of USB2SERIAL goes to Rx of the MSP430 UART and vice versa)
All the C sourefiles along with D2XX library used in this tutorial can be downloaded from our GitHub Page.For this Tutorial use the "Comm_Serial " Directory inside the code repository.
USB2SERIAL Converter Board – An FT232 based USB to Serial(TTL 3V/5V) /RS232 /RS485 converter board with all the required pins brought out using headers. The board can also be used for creating a USB to RS485 network or USB to RS232 Connection. For details you can click on the above link.
If you already have a FT232 based USB to Serial converter you a use that too. Only connections required are Tx, Rx and Ground.
Please note that USB to Serial converters using chips other than FT232 may not work with this tutorial.
Any Microcontroller with a UART – You can use any microcontroller with a UART to communicate with the PC using the serial port. In this example I will be using MSP430G2553 from Texas instruments along with the Launchpad development board.
If your microcontroller development platform does not provide access to the UART pins but has an RS232 interface you can connect to the RS232 side of the USB2SERIAL converter board.
On the PC side,
Software is written using C and compiled using Open source C compiler GCC on Windows Platform (Windows 7). The D2XX library can be freely downloaded from the FTDI website or along with source codes from this site.
If you want to use an IDE for proper software development, Eclipse CDT and Code::Blocks are good choices. Here is link to configure the Eclipse IDE and Code::Blocks IDE with D2XX library.
On the Microcontroller Side,
Since any microcontroller of your choice can be used, choice for the development environment is in your hands.
Here I am using MSP430G2553 microcontroller along with the Launchpad Development environment. Software is written using IAR Embedded workbench for MSP430 in Embedded C.
Energia IDE(Open source) and Code Composer Studio from TI are two other IDE's you can use.
The Microcontroller and the FT232 are connected in Null Modem configuration.
The TXD of the FT232RL is connected to the RXD of the MSP430G2533 (UCA0RXD) and the RXD of the FT232RL is connected to the TXD of the MSP430G2533 (UCA0TXD).Check the image below.
Below figure shows the connection between USB2SERIAL and MSP430 Launchpad.RXD and TXD from the FT232 are taken from CONN1 connector of USB2SERIAL after removing the jumpers.
The PC side (FT232RL) transmits the data to MSP430 which is received by the Receive buffer of the MSP430 UART (USCI_A0) during a write operation (FT_Write()) .
Please note that you should connect the grounds together for the serial communication to occur.
Functions and API's used
In this tutorial we are going to use the API's provided by the D2XX library (ftd2xx.lib) to set up a serial connection between FT232 (PC) and a MSP430 microcontroller. For details about the API's used, refer the “D2XX Programmers Manual” from FTDI.
We also use some of the Win32 API's to create an Event and wait for something to happen(receive a character, change in line status etc).
Writing into Serial Port
The PC will send a byte ('A') through the serial port into the MSP430 using the API's provided by the D2XX library. The MSP430 is configured to receive the byte and light up an LED.
Please note that the microcontroller code along with the IAR workspace is present in the zip file containing the source code. In this section only the code running on the PC side is discussed .
First thing to do is to open a connection to the FT232 chip using the FT_Open() function call, FT_Open() takes two parameters first one is zero and the second one is the handle(ft_handle) which will be used to refer the connection by other functions in the future. ft_handle is a variable of type FT_HANDLE which is defined in ftd2xx.h header file.
ft_status = FT_Open(0,&ft_handle);
ft_status is used to store the status of the operation FT_Open(), ft_status can be used to check whether a function has returned successfully or not. If the function returns successfully FT_OK is returned otherwise an ERROR code is returned.
| if(ft_status == FT_OK)
// function succeeded
// some error
After the connection is opened successfully we can set the baud rate (bps) using the FT_SetBaudRate() function. FT_SetBaudRate() function has two parameters a handle to the chip (ft_handle) and the BaudRate value.
BaudRate can be any standard value like 4800,9600,19200 bits/second.Here BaudRate = 9600.
After the Baud Rate is successfully set the next step is to set proper data characteristics, parity and no of stop/Start bits. Here we are going to use the 8N1 format,8bits, No Parity, 1 stop bit.
|FT_SetDataCharacteristics(ft_handle, // Handle of the chip(FT232)
FT_BITS_8, // No of Data bits = 8
FT_STOP_BITS_1, // No of Stop Bits = 1
FT_PARITY_NONE // Parity = NONE
FT_SetFlowControl() is used to select the type of flow control (Hardware or Software) to be used to control the flow of data from one device to another. Usually RTS, CTS signals are used to implement a hardware based flow control. In this case we are not using any flow control so they can be left as NULL.
|FT_SetFlowControl( ft_handle, // Handle of the chip(FT232)
FT_FLOW_NONE, // No Flow control
NULL, // Null since no Flow control
NULL // Null since no Flow control
After all the parameters for serial communication are correctly set its time to send some data through serial port to MSP430.For sending data we are going to use FT_Write() function.
FT_Write( ft_handle, // Handle to the chip
Here TxByte holds the data to be transmitted and the address of that variable is given to the FT_Write() function to be written to the serial port.
NoOfBytesWritten returns the total number of bytes that were successfully written to the serial port.
Before the program exits call FT_Close() to close the connection to the chip.
Compiling the Program
Compile the program using GCC (How to setup GCC/MinGW).
D:\>gcc -o SerialPort_Write_D2XX SerialPort_Write_D2XX.c ftd2xx.lib
Make sure that ftd2xx.lib, ftd2xx.h and SerialPort_Write_D2XX.c are in the same directory .On compiling you will get some warning messages ,Ignore it.
If compiling is successful you will get an exe file named SerialPort_Write_D2XX.exe
On the MSP430 side,
Compile and download MSP430_recieve_mode.c into the launchpad using IAR Embedded Workbench. The file MSP430_recieve_mode.c is present in the source code zip file under “Writing into Serial Port\MSP430 Side\Code”.Now reset the MSP430 microcontroller and let the program to run.
MSP430 initializes it's UART and waits until the character 'A' is received. On reception of 'A', LED connected to P1.0 is toggled.
On the PC side
Double click on SerialPort_Write_D2XX.exe on the PC to sent character 'A' to MSP430.
You can see the LED connected to P1.0 lighting up as the character 'A' is received by MSP430.
Reading from Serial Port
In this section MSP430 will send a string of characters to the PC @ 9600bps which is received and displayed on the PC screen.
Reading from serial port consists of the following steps which are same as in “Writing to Serial Port”.
1. Opening a connection with FT232 using FT_Open() function.
2. Setting the Baud rate of the transmission/reception using FT_SetBaudRate() function.
3. Setting the Data characteristics using FT_SetDataCharacteristics() function.
4. Setting flow control using FT_SetFlowControl()
After you have configured,
Baud rate = 9600bps
Data Characteristics = 8 Data bits, No Parity,1 Stop Bit (8N1)
Flow Control = None
If you are building a single program that would receive and transmit, you only has to do the above steps once.
We are going to configure our program in such a way that Windows OS will notify us, when a character is received in the Receive Buffer of the PC serial port. This is achieved by creating a Windows Event that would notify us when a character is received.
A Windows Event is a kernel synchronization object whose state can be explicitly set by other functions.It means that you can create an Event using the CreateEvent() system call and ask your program to wait (using Windows wait functions like WaitForSingleObject()) until the conditions specified in the CreateEvent() call is met.
handle = CreateEvent(); // Creating an Event
In the above example an Event is created using CreateEvent() function and then the WaitForSingleObject(handle, INFINITE) is called to wait for the Event to be set or Signaled. Program execution stops until the Event is set and the wait function WaitForSingleObject() returns. Then only the function DoSomething() is executed.
Events are kernel objects which cannot be directly accessed so we has to create a handle to manipulate the Event object.
Please note that “HANDLE” is different from the “FT_HANDLE“ we had used earlier.
HANDLE is defined in the header file windows.h and is a part of Windows API
FT_HANDLE is defined in the header file ftd2xx.h and is a part of ftd2xx.lib
There are two different types of events
- Manual Reset Event
- Auto Reset Event
In the case of Manual Reset Event we have to explicitly reset the event using a ResetEvent() function after it is set or signaled.
In the case of Auto Reset Event, the Event gets automatically reset after it is set or signaled.
In our code
we are going to create an event using CreateEvent(); function call.
WinHandle = CreateEvent( NULL, // Default Security Attributes
The first parameter of the CreateEvent() function deals with the security attributes which can be set as NULL. The system will load the default security settings.
Second parameter deals with the type of the event, Manual Reset or Auto Reset.Here we set it as an Auto Reset Event.
Third parameter deals with the initial state of the created Event, whether it is Signaled(set) or Non Signaled(not set).In our case we will make the initial state Non Signaled(not set).
Last parameter is used to give a name to the event. You can leave it empty as we are not going to use it.
Next step is to set up the conditions that would trigger the Event like reception of a character, change in line status, change in modem status etc using FT_SetEventNotification() API from ftd2xx.lib.
FT_SetEventNotification( ft_handle, // Handle of the Chip (FT232)
dwEventMask, // Used to Select which action should trigger the Event
WinHandle // Handle of the Windows Event
dwEventMask is used to specify the conditions that would cause the Event to get signaled.
Since we want to signal the event when a character is received it is set as below.
dwEventMask = FT_EVENT_RXCHAR
WinHandle is the handle to the Windows event that we had created earlier using CreateEvent() function.
After the conditions for signaling the event are setup we call a Windows Wait function to wait until the character is received. Here we are using WaitForSingleObject() function.
WaitForSingleObject( WinHandle, INFINITE);
WaitForSingleObject() function waits until the Event gets signaled.
FT_GetStatus() function is used to check whether anything has been received after the event gets signaled and WaitForSingleObject() returns. FT_GetStatus() function gets the status of both TX and RX queue.
|FT_GetStatus( ft_handle, // Handle to the Chip
&RxQueueBytes, // No Of Bytes in Receive Queue
&TxQueueBytes, // No Of Bytes in Transmit Queue
&EventStatus // current event status.
RxQueueBytes contains the number of bytes received by the FT232.
If the number of bytes in the RxQueueBytes > 0 call the read function FT_Read() to read the received data.
|FT_Read( ft_handle, // Handle to the Chip
RxBuffer, // Pointer to the Buffer for storing Rx'd data
RxQueueBytes, // No of Bytes in Receive Queue
&BytesReceived // number of bytes read from the device.
RxBuffer is a char Array for storing the received data.
RxQueueBytes gives the number of bytes that FT_Read() function should read.
Call FT_Close() to close the connection to the chip.
Compiling the Code
Compile the source file using GCC as shown below.
D:\>gcc -o SerialPort_Read_D2XX SerialPort_Read_D2XX.c ftd2xx.lib
If compiling is successful you will get an exe file named SerialPort_Read_D2XX.exe
Double click on SerialPort_Read_D2XX.exe on the PC. The Program will wait for the reception of characters from MSP430.
On the MSP430 side,
Compile and download MSP430_transmit_string.c into the launchpad using IAR Embedded Workbench. The file MSP430_transmit_string.c is present in the source code zip file under “Reading from Serial Port\MSP430 Side\Code”.Now reset the MSP430 microcontroller and let the program to run.
MSP430 initializes it's UART and transmits a string of characters to PC.
After the characters are successfully received by SerialPort_Read_D2XX.exe program they are printed on to the screen.