.. _uart_to_uart2-porting-guide:

UART to UART2 Porting Guide
===========================
This guide will briefly outline the significant changes when 
porting from UART to UART2.

Notable Changes
----------------

The improved UART2 driver replaces the UART driver, with small changes to the API, and porting 
existing code should be straight-forward. Some notable changes are:

   *  UART2 has two ring buffers, one for RX and one for TX to send/receive data.
   *  UART2 uses DMA to transfer data between the UART FIFOs and the RX and TX ring buffers.
   *  The UART2 APIs for reading and writing data have been made more posix-like.
   *  UART2 provides for event notification, allowing the application to receive TX start and 
      completion events, and RX error events.
   *  Minor changes in driver parameters and available modes.

UART/UART2 Code Examples
------------------------

A typical UART use-case in the classic UART driver would look like this, where the
driver is initialized, opened, and a read/write operation is performed.

.. code-block:: c

   // Import the UART driver definitions
   #include <ti/drivers/UART.h>

   // One-time initialization of UART driver
   UART_init();

   // Initialize UART parameters
   UART_Params params;
   UART_Params_init(&params);
   params.baudRate = 9600;
   params.readMode = UART_MODE_BLOCKING;
   params.writeMode = UART_MODE_BLOCKING;
   params.readTimeout = UART_WAIT_FOREVER;
   params.writeTimeout = UART_WAIT_FOREVER;

   // Open the UART
   UART_Handle uart;
   uart = UART_open(CONFIG_UART0, &params);

   // Read from the UART
   int32_t readCount;
   uint8_t buffer[BUFSIZE];
   readCount = UART_read(uart, buffer, BUFSIZE);

   // Write to the UART
   UART_write(uart, buffer, BUFSIZE);

   // Close the UART
   UART_close(uart);

The same example, but using the new UART2 driver would look like the following:

.. code-block:: c

   // Import the UART2 driver definitions
   #include <ti/drivers/UART2.h>

   // Initialize UART2 parameters
   UART2_Params params;
   UART2_Params_init(&params);
   params.baudRate = 9600;
   params.readMode = UART2_Mode_BLOCKING;
   params.writeMode = UART2_Mode_BLOCKING;

   // Open the UART
   UART2_Handle uart;
   uart = UART2_open(CONFIG_UART0, &params);

   // Read from the UART.
   size_t  bytesRead;
   uint8_t buffer[BUFSIZE];
   int32_t status;
   status = UART2_read(uart, buffer, BUFSIZE, &bytesRead);

   // Write to the UART
   // Instead of retrieving bytesWritten, NULL can also be passed
   status = UART2_write(uart, buffer, BUFSIZE, NULL);

   // Close the UART
   UART2_close(uart);

When comparing the two examples, one can see that the differences are minor
and the changes required are fairly straightforward.

API Changes
-----------

   *  **#include** - The include must be changed from UART.h to UART2.
   *  **Initializing UART** - It is not necessary to initialize UART when
      using the UART2 library. There is no equivalent to the ``UART_unit()``
      function in the UART2 library.
   *  **Params** - Within the UART2.h file, the parameter structure
      UART2_Params is defined. There are some key differences between the
      UART2_Params and the UART_Params structures. The following fields
      have been changed

      *  readTimeout and writeTimeout has been removed from the structure,
         and these values can instead be passed to ``UART2_readTime()`` and
         ``UART2_writeTimeout()``.
      *  eventCallback has been added, where the user can supply a
         callback function to receive events from the driver, as well as 
         an eventMask to mask which events to subscribe to.
      *  readDataMode and writeDataMode has been removed, and is no 
         longer a concept in the UART2 driver. All data is handled as 
         binary data, corresponding to the previous UART_DATA_BINARY.
      *  readEcho has been removed and, and setting the driver to 
         automatically echo received data is no longer supported
      *  custom has been replaced by userArg, which is passed to the
         readCallback, writeCallback, and eventCallback
         
      
      The default parameters set by the ``UART2_Params_init()`` are mostly
      the same as the parameters set by ``UART_Params_init()``, with one
      exepection

      *  readReturnMode = UART2_ReadReturnMode_PARTIAL

      
      This mode replaces UART_RETURN_NEWLINE as the default. In this 
      mode, instead of returning when a newline character is detected,
      a read-operation will now return when some data has been 
      received by the driver, and a read-timeout event occurs in the 
      low-level peripheral. A read-timeout event can vary between 
      devices, but is typically defined as *"when the RX FIFO is not 
      empty, and no further data is received over a 32-bit period."*
   
   *  **Opening the driver** - ``UART2_open()`` should be used instead of 
      ``UART_open()``, which is identical in return-type an arguments.
   *  **Reading and writing** - ``UART2_read()`` and ``UART2_write()`` should 
      be used instead of ``UART_read()`` and ``UART_write()``. The prototype 
      of these functions have changes one should be aware of when 
      porting existing code.

      *  The return-type for both functions is strictly a status-code,
         and has a greater number of status-codes available for more detail.
         The error codes can be found within :ref:`ti_driver_reference`.
      *  To get the number of bytes read/written, a variable is passed by 
         reference to the function. Alternatively, one can pass NULL if these 
         values are not needed

      In addition to these functions, one can also call ``UART2_readTimeout()``
      and ``UART2_writeTimeout()`` with an extra parameter specifying a 
      timeout-value

      See the UART2 documentation for more details
   *  **Closing** - ``UART2_close()`` should be used instead of ``UART_close()``,
      which is identical in return-type and arguments

Updating existing SysConfig files
----------------------------------

The SysConfig file must be updated to use the UART2 driver instead of the UART driver. This can be
done through the SysConfig GUI. Alternatively, if the SysConfig tool displays an error when opened in 
the GUI, open the file with a text editor instead modify the file as shown below (the commented lines
may be deleted)

.. code-block:: c

   // var UART = scripting.addModule("/ti/drivers/UART");
   // var uart = UART.addInstance();

   var UART2 = scripting.addModule("/ti/drivers/UART2");
   var uart2 = UART2.addInstance();