[rtems commit] bsp/altera-cyclone-v: Add DMA support hwlib files

Sebastian Huber sebh at rtems.org
Tue Aug 26 15:12:22 UTC 2014


Module:    rtems
Branch:    master
Commit:    76386c1047ea15a05965adcab371bba2147831ba
Changeset: http://git.rtems.org/rtems/commit/?id=76386c1047ea15a05965adcab371bba2147831ba

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Tue Aug 26 16:00:44 2014 +0200

bsp/altera-cyclone-v: Add DMA support hwlib files

---

 c/src/lib/libbsp/arm/altera-cyclone-v/Makefile.am  |   21 +-
 .../hwlib/include/alt_16550_uart.h                 | 1555 +++++
 .../arm/altera-cyclone-v/hwlib/include/alt_cache.h |  964 ++++
 .../arm/altera-cyclone-v/hwlib/include/alt_dma.h   | 1007 ++++
 .../hwlib/include/alt_dma_common.h                 |  162 +
 .../hwlib/include/alt_dma_program.h                |  951 ++++
 .../arm/altera-cyclone-v/hwlib/include/alt_qspi.h  | 1535 +++++
 .../hwlib/include/alt_qspi_private.h               |  167 +
 .../hwlib/include/socal/alt_dmanonsecure.h         |  144 +
 .../hwlib/include/socal/alt_dmasecure.h            |  144 +
 .../hwlib/include/socal/alt_qspi.h                 | 5951 ++++++++++++++++++++
 .../hwlib/include/socal/alt_qspidata.h             |   52 +
 .../hwlib/src/hwmgr/alt_16550_uart.c               | 1179 ++++
 .../arm/altera-cyclone-v/hwlib/src/hwmgr/alt_dma.c | 3749 ++++++++++++
 .../hwlib/src/hwmgr/alt_dma_program.c              | 1064 ++++
 .../altera-cyclone-v/hwlib/src/hwmgr/alt_qspi.c    | 2619 +++++++++
 .../lib/libbsp/arm/altera-cyclone-v/preinstall.am  |   40 +
 17 files changed, 21297 insertions(+), 7 deletions(-)

diff --git a/c/src/lib/libbsp/arm/altera-cyclone-v/Makefile.am b/c/src/lib/libbsp/arm/altera-cyclone-v/Makefile.am
index a581dee..aad1db1 100644
--- a/c/src/lib/libbsp/arm/altera-cyclone-v/Makefile.am
+++ b/c/src/lib/libbsp/arm/altera-cyclone-v/Makefile.am
@@ -51,23 +51,25 @@ include_bsp_HEADERS += include/irq.h
 include_bsp_HEADERS += include/nocache-heap.h
 
 # Altera hwlib
+include_bsp_HEADERS += hwlib/include/alt_16550_uart.h
 include_bsp_HEADERS += hwlib/include/alt_address_space.h
+include_bsp_HEADERS += hwlib/include/alt_cache.h
 include_bsp_HEADERS += hwlib/include/alt_clock_group.h
 include_bsp_HEADERS += hwlib/include/alt_clock_manager.h
+include_bsp_HEADERS += hwlib/include/alt_dma_common.h
+include_bsp_HEADERS += hwlib/include/alt_dma.h
+include_bsp_HEADERS += hwlib/include/alt_dma_program.h
 include_bsp_HEADERS += hwlib/include/alt_generalpurpose_io.h
 include_bsp_HEADERS += hwlib/include/alt_hwlibs_ver.h
 include_bsp_HEADERS += hwlib/include/alt_i2c.h
 include_bsp_HEADERS += hwlib/include/alt_interrupt_common.h
 include_bsp_HEADERS += hwlib/include/alt_mpu_registers.h
+include_bsp_HEADERS += hwlib/include/alt_qspi_private.h
 include_bsp_HEADERS += hwlib/include/alt_reset_manager.h
 include_bsp_HEADERS += hwlib/include/hwlib.h
 #The following Altera hwlib header files have been left out because so far 
 #they are not required:
-#include_bsp_HEADERS += hwlib/include/alt_16550_uart.h
 #include_bsp_HEADERS += hwlib/include/alt_bridge_manager.h
-#include_bsp_HEADERS += hwlib/include/alt_dma_common.h
-#include_bsp_HEADERS += hwlib/include/alt_dma_program.h
-#include_bsp_HEADERS += hwlib/include/alt_dma.h
 #include_bsp_HEADERS += hwlib/include/alt_fpga_manager.h
 #include_bsp_HEADERS += hwlib/include/alt_globaltmr.h
 #include_bsp_HEADERS += hwlib/include/alt_system_manager.h
@@ -79,9 +81,13 @@ include_bsp_HEADERS += hwlib/include/hwlib.h
 # Some of the headers from hwlib need the files from socal. Install them.
 include_bsp_socal_HEADERS += hwlib/include/socal/alt_acpidmap.h
 include_bsp_socal_HEADERS += hwlib/include/socal/alt_clkmgr.h
+include_bsp_socal_HEADERS += hwlib/include/socal/alt_dmanonsecure.h
+include_bsp_socal_HEADERS += hwlib/include/socal/alt_dmasecure.h
 include_bsp_socal_HEADERS += hwlib/include/socal/alt_gpio.h
 include_bsp_socal_HEADERS += hwlib/include/socal/alt_i2c.h
 include_bsp_socal_HEADERS += hwlib/include/socal/alt_l3.h
+include_bsp_socal_HEADERS += hwlib/include/socal/alt_qspidata.h
+include_bsp_socal_HEADERS += hwlib/include/socal/alt_qspi.h
 include_bsp_socal_HEADERS += hwlib/include/socal/alt_rstmgr.h
 include_bsp_socal_HEADERS += hwlib/include/socal/alt_sdr.h
 include_bsp_socal_HEADERS += hwlib/include/socal/alt_sysmgr.h
@@ -124,17 +130,18 @@ libbsp_a_CPPFLAGS += -std=gnu99
 CFLAGS += -Wno-missing-prototypes
 
 # hwlib from Altera
+libbsp_a_SOURCES += hwlib/src/hwmgr/alt_16550_uart.c
 libbsp_a_SOURCES += hwlib/src/hwmgr/alt_address_space.c
 libbsp_a_SOURCES += hwlib/src/hwmgr/alt_clock_manager.c
+libbsp_a_SOURCES += hwlib/src/hwmgr/alt_dma.c
+libbsp_a_SOURCES += hwlib/src/hwmgr/alt_dma_program.c
 libbsp_a_SOURCES += hwlib/src/hwmgr/alt_generalpurpose_io.c
 libbsp_a_SOURCES += hwlib/src/hwmgr/alt_i2c.c
+libbsp_a_SOURCES += hwlib/src/hwmgr/alt_qspi.c
 libbsp_a_SOURCES += hwlib/src/hwmgr/alt_reset_manager.c
 #The following Altera hwlib source files have been left out because so far 
 #they are not required:
-#libbsp_a_SOURCES += hwlib/src/hwmgr/alt_16550_uart.c
 #libbsp_a_SOURCES += hwlib/src/hwmgr/alt_bridge_manager.c
-#libbsp_a_SOURCES += hwlib/src/hwmgr/alt_dma_program.c
-#libbsp_a_SOURCES += hwlib/src/hwmgr/alt_dma.c
 #libbsp_a_SOURCES += hwlib/src/hwmgr/alt_fpga_manager.c
 #libbsp_a_SOURCES += hwlib/src/hwmgr/alt_globaltmr.c
 #libbsp_a_SOURCES += hwlib/src/hwmgr/alt_system_manager.c
diff --git a/c/src/lib/libbsp/arm/altera-cyclone-v/hwlib/include/alt_16550_uart.h b/c/src/lib/libbsp/arm/altera-cyclone-v/hwlib/include/alt_16550_uart.h
new file mode 100644
index 0000000..bca6f63
--- /dev/null
+++ b/c/src/lib/libbsp/arm/altera-cyclone-v/hwlib/include/alt_16550_uart.h
@@ -0,0 +1,1555 @@
+/*
+ * Altera - SoC UART Manager
+ */
+
+/*****************************************************************************
+ *
+ * Copyright 2013 Altera Corporation. All Rights Reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 
+ *****************************************************************************/
+
+#ifndef __ALT_16550_UART_H__
+#define __ALT_16550_UART_H__
+
+#include "hwlib.h"
+#include "alt_clock_manager.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*!
+ * \addtogroup UART UART Driver API
+ *
+ * This module defines the Universal Asynchronous Receiver/Transmitter (UART)
+ * API for accessing and using the UART resources. The API allows for general
+ * control of a 16550 compatible UART controller.
+ *
+ * This implementation can control the following UARTs:
+ *  * SoCFPGA On-board UARTs
+ *  * Altera 16550 Compatible Soft IP UART
+ *
+ * The following reference materials were used in the design of this API:
+ *  * Synopsys® DesignWare DW_apb_uart Databook v3.10a
+ *
+ * @{
+ */
+
+/*!
+ * \addtogroup UART_BASIC UART Basic
+ *
+ * This group of APIs provides basic access to the UART to initialize,
+ * uninitialize, read, write, and reset the UART.
+ *
+ * @{
+ */
+
+/*!
+ * This type definition enumerates the list of UARTs available on the system.
+ */
+typedef enum ALT_16550_DEVICE_e
+{
+    /*!
+     * This option selects UART0 in the SoC FPGA.
+     */
+    ALT_16550_DEVICE_SOCFPGA_UART0 = 0,
+
+    /*!
+     * This option selects UART1 in the SoC FPGA.
+     */
+    ALT_16550_DEVICE_SOCFPGA_UART1 = 1,
+
+    /*!
+     * This option selects an Altera 16550 Compatible soft IP UART. The memory
+     * location of the device must be provided as part of the initialization.
+     */
+    ALT_16550_DEVICE_ALTERA_16550_UART = 0x100
+}
+ALT_16550_DEVICE_t;
+
+/*!
+ * This structure is used to represent a handle to a specific UART on the
+ * system. The internal members are undocumented and should be not altered
+ * outside of this API.
+ */
+typedef struct ALT_16550_HANDLE_s
+{
+    ALT_16550_DEVICE_t device;
+    void *             location;
+    alt_freq_t         clock_freq;
+    uint32_t           data;
+    uint32_t           fcr;
+}
+ALT_16550_HANDLE_t;
+
+/*!
+ * Performs the initialization steps needed by the UART. This should be the
+ * first API call made when accessing a particular UART
+ *
+ * The default UART setting is 8 databits, no parity, 1 stopbit, and 57600
+ * baud.
+ *
+ * For the SoCFPGA UARTs, The ALT_CLK_L4_SP clock needs to be setup before
+ * initialization.
+ *
+ * \param       device
+ *              The UART device identifier.
+ *
+ * \param       location
+ *              The memory of the location for the given UART. For SoCFPGA
+ *              UARTs, this parameter is ignored.
+ *
+ * \param       clock_freq
+ *              The clock frequency of the serial clock for the given UART.
+ *              For SoCFPGA UARTs, this paramter is ignored.
+ *
+ * \param       handle
+ *              [out] A pointer to a handle that will represent the UART. This
+ *              handle should subsequently be used when calling other UART
+ *              APIs.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The given UART device identifier is invalid.
+ * \retval      ALT_E_BAD_CLK   The required clock is not yet setup.
+ */
+ALT_STATUS_CODE alt_16550_init(ALT_16550_DEVICE_t device,
+                               void * location,
+                               alt_freq_t clock_freq,
+                               ALT_16550_HANDLE_t * handle);
+
+/*!
+ * Performs the uninitialization steps for the UART. This should be the last
+ * API call made to cleanup the UART.
+ *
+ * After calling this function, the handle will need to be initialized again
+ * before being used by calling alt_16550_init().
+ *
+ * \param       handle
+ *              The UART device handle.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The given UART device handle is invalid.
+ */
+ALT_STATUS_CODE alt_16550_uninit(ALT_16550_HANDLE_t * handle);
+
+/*!
+ * Resets the UART to the default configuration. The UART will be reset and
+ * reinitialized.
+ *
+ * \param       handle
+ *              The UART device handle.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The given UART device handle is invalid.
+ */
+ALT_STATUS_CODE alt_16550_reset(ALT_16550_HANDLE_t * handle);
+
+/*!
+ * Starts the UART after all configuration has been completed.
+ *
+ * \param       handle
+ *              The UART device handle.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The given UART device handle is invalid.
+ */
+ALT_STATUS_CODE alt_16550_enable(ALT_16550_HANDLE_t * handle);
+
+/*!
+ * Stops the UART. While UART configuration can be done while enabled, it is
+ * not recommended.
+ *
+ * \param       handle
+ *              The UART device handle.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The given UART device handle is invalid.
+ */
+ALT_STATUS_CODE alt_16550_disable(ALT_16550_HANDLE_t * handle);
+
+/*!
+ * Reads a single character from the UART receiver buffer. This API should
+ * only be used when FIFOs are disabled.
+ *
+ * \param       handle
+ *              The UART device handle.
+ *
+ * \param       item
+ *              [out] Pointer to an output parameter that contains the in
+ *              receiver buffer of the UART.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The given UART device handle is invalid.
+ */
+ALT_STATUS_CODE alt_16550_read(ALT_16550_HANDLE_t * handle,
+                               char * item);
+
+/*!
+ * Writes a single character to the UART transmitter buffer. This API should
+ * only be used when FIFOs are disabled.
+ *
+ * \param       handle
+ *              The UART device handle.
+ *
+ * \param       item
+ *              The character to write to the transmitter buffer of the UART.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The given UART device handle is invalid.
+ */
+ALT_STATUS_CODE alt_16550_write(ALT_16550_HANDLE_t * handle,
+                                char item);
+
+/*!
+ * @}
+ */
+
+/*!
+ * \addtogroup UART_FIFO UART FIFO Interface
+ *
+ * This group of APIs provides access, configuration, and control of the UART
+ * FIFO. The FIFO allows the UART to buffer received data and data to be
+ * transmitted.
+ *
+ * @{
+ */
+
+/*!
+ * This type definition enumerates the receiver FIFO level conditions that
+ * will trigger the receiver FIFO to issue a receiver FIFO full event.
+ */
+typedef enum ALT_16550_FIFO_TRIGGER_RX_e
+{
+    /*!
+     * 1 or more character(s) in the receiver FIFO will trigger an event.
+     */
+    ALT_16550_FIFO_TRIGGER_RX_ANY = 0,
+
+    /*!
+     * 25% or higher capacity usage in the receiver FIFO will trigger an
+     * event.
+     */
+    ALT_16550_FIFO_TRIGGER_RX_QUARTER_FULL = 1,
+
+    /*!
+     * 50% or higher capacity usage in the receiver FIFO will trigger an
+     * event.
+     */
+    ALT_16550_FIFO_TRIGGER_RX_HALF_FULL = 2,
+
+    /*!
+     * 2 characters less than the receiver FIFO capacity will trigger an
+     * event.
+     */
+    ALT_16550_FIFO_TRIGGER_RX_ALMOST_FULL = 3
+}
+ALT_16550_FIFO_TRIGGER_RX_t;
+
+/*!
+ * This type definition enumerates the transmitter FIFO level conditions that
+ * will trigger the transmitter FIFO to issue a transmitter FIFO empty event.
+ */
+typedef enum ALT_16550_FIFO_TRIGGER_TX_e
+{
+    /*!
+     * Transmitter FIFO being completely empty will trigger an event.
+     */
+    ALT_16550_FIFO_TRIGGER_TX_EMPTY = 0,
+
+    /*!
+     * 2 or less character(s) in the transmitter FIFO will trigger an event.
+     */
+    ALT_16550_FIFO_TRIGGER_TX_ALMOST_EMPTY = 1,
+
+    /*!
+     * 25% or less capacity usage in the transmitter FIFO will trigger an
+     * event.
+     */
+    ALT_16550_FIFO_TRIGGER_TX_QUARTER_FULL = 2,
+
+    /*!
+     * 50% or less capacity usage in the transmitter FIFO will trigger an
+     * event.
+     */
+    ALT_16550_FIFO_TRIGGER_TX_HALF_FULL = 3
+}
+ALT_16550_FIFO_TRIGGER_TX_t;
+
+/*!
+ * Enables FIFO on the UART. This will enable both the receiver FIFO and
+ * transmitter FIFO. Both FIFOs will be cleared.
+ *
+ * \param       handle
+ *              The UART device handle.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The given UART device handle is invalid.
+ */
+ALT_STATUS_CODE alt_16550_fifo_enable(ALT_16550_HANDLE_t * handle);
+
+/*!
+ * Disables FIFOs on the UART. This will disable both the receiver FIFO and
+ * transmitter FIFO. Any data left in the FIFOs will be lost.
+ *
+ * \param       handle
+ *              The UART device handle.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The given UART device handle is invalid.
+ */
+ALT_STATUS_CODE alt_16550_fifo_disable(ALT_16550_HANDLE_t * handle);
+
+/*!
+ * Reads the given buffer from the receiver FIFO in the UART.
+ *
+ * The available characters in the FIFO can be determined by a few ways. Users
+ * can determine the number of items by calling alt_16550_fifo_level_get_rx().
+ *
+ * Another way is by using the RX trigger and RX interrupt. First determine the
+ * RX FIFO size by calling alt_16550_fifo_size_get_rx(). Then set the desired
+ * trigger level by calling alt_16550_fifo_trigger_set_rx(). Calculate the
+ * triggering point by applying trigger description on the FIFO size. Enable RX
+ * interrupts by calling alt_16550_int_enable_rx(). When the RX interrupt fires
+ * due to the ALT_16550_INT_STATUS_RX_DATA condition, the calculated triggering
+ * point value can be used to determine the RX FIFO level. If the interrupt
+ * fires due to the ALT_16550_INT_STATUS_RX_TIMEOUT, the RX FIFO can be
+ * completely emptied by repeatedly polling the Line Status
+ * ALT_16550_LINE_STATUS_DR condition by calling alt_16550_line_status_get().
+ * These steps are necessary if the UART does not implement FIFO level query
+ * functionality. As of 13.0sp1, this applies to the Altera 16550 Compatible
+ * Soft UART.
+ *
+ * Reading more data than that which is available can result in invalid data
+ * appearing like valid data.
+ *
+ * The FIFO must first be enabled before calling this function by calling
+ * alt_16550_fifo_enable().
+ *
+ * \param       handle
+ *              The UART device handle.
+ *
+ * \param       buffer
+ *              [out] Pointer to a buffer where the specified count of
+ *              characters from the receiver FIFO will be copied to.
+ *
+ * \param       count
+ *              The count of characters from the receiver FIFO to be copied.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The given UART device handle is invalid.
+ */
+ALT_STATUS_CODE alt_16550_fifo_read(ALT_16550_HANDLE_t * handle,
+                                    char * buffer,
+                                    size_t count);
+
+/*!
+ * Writes the given buffer to the transmitter FIFO in the UART.
+ *
+ * The available space in the FIFO can be determined by a few ways. Users can
+ * determine the number of items by calculating the FIFO capacity minus the
+ * FIFO level. This can be done by calling  alt_16550_fifo_size_get_tx() and
+ * alt_16550_fifo_level_get_tx() respectively.
+ *
+ * Another way is by using the TX trigger and TX interrupt. First determine the
+ * TX FIFO size by calling alt_16550_fifo_size_get_tx(). The set the desired
+ * trigger level by calling alt_16550_fifo_trigger_set_tx(). Calculate the
+ * triggering point by applying the trigger description on the FIFO size.
+ * Enable TX interrupts by calling alt_16550_int_enable_tx(). When the TX
+ * interrupt fires, calculate the empty entries in the FIFO by subtracting the
+ * TX FIFO size and the calculated value. These steps are necessary if the UART
+ * does not implement FIFO level query functionality. As of 13.0sp1, this
+ * applies to the Altera 16550 Compatible Soft UART.
+ *
+ * Writing more data that there is space can result in data lost due to
+ * overflowing.
+ *
+ * The FIFOs must first be enabled before calling this function by calling
+ * alt_16550_fifo_enable().
+ *
+ * \param       handle
+ *              The UART device handle.
+ *
+ * \param       buffer
+ *              Pointer to a buffer from where the specified count of
+ *              characters will be copied to the transmitter FIFO.
+ *
+ * \param       count
+ *              The count of characters from the given buffer to be copied.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The given UART device handle is invalid.
+ */
+ALT_STATUS_CODE alt_16550_fifo_write(ALT_16550_HANDLE_t * handle,
+                                     const char * buffer,
+                                     size_t count);
+
+/*!
+ * Clears the contents of the receiver FIFO. Any characters which were
+ * previously contained in that FIFO will be discarded.
+ *
+ * The FIFOs must first be enabled before calling this function by calling
+ * alt_16550_fifo_enable().
+ *
+ * \param       handle
+ *              The UART device handle.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The given UART device handle is invalid.
+ */
+ALT_STATUS_CODE alt_16550_fifo_clear_rx(ALT_16550_HANDLE_t * handle);
+
+/*!
+ * Clears the contents of the transmitter FIFO. Any characters which were
+ * previously contained in that FIFO will be discarded.
+ *
+ * The FIFOs must first be enabled before calling this function by calling
+ * alt_16550_fifo_enable().
+ *
+ * \param       handle
+ *              The UART device handle.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The given UART device handle is invalid.
+ */
+ALT_STATUS_CODE alt_16550_fifo_clear_tx(ALT_16550_HANDLE_t * handle);
+
+/*!
+ * Clears the contents of the receiver and transmitter FIFO. Any characters
+ * which were previously contained on those FIFOs will be discarded.
+ *
+ * The FIFOs must first be enabled before calling this function by calling
+ * alt_16550_fifo_enable().
+ *
+ * \param       handle
+ *              The UART device handle.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The given UART device handle is invalid.
+ */
+ALT_STATUS_CODE alt_16550_fifo_clear_all(ALT_16550_HANDLE_t * handle);
+
+/*!
+ * Queries the size of the receiver FIFO. 
+ *
+ * \param       handle
+ *              The UART device handle.
+ *
+ * \param       size
+ *              [out] Pointer to an output parameter that contains the size of
+ *              the receiver FIFO.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The given UART device handle is invalid.
+ */
+ALT_STATUS_CODE alt_16550_fifo_size_get_rx(ALT_16550_HANDLE_t * handle,
+                                           uint32_t * size);
+
+/*!
+ * Queries the size of the transmitter FIFO. 
+ *
+ * \param       handle
+ *              The UART device handle.
+ *
+ * \param       size
+ *              [out] Pointer to an output parameter that contains the size of
+ *              the transmitter FIFO.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The given UART device handle is invalid.
+ */
+ALT_STATUS_CODE alt_16550_fifo_size_get_tx(ALT_16550_HANDLE_t * handle,
+                                           uint32_t * size);
+
+/*!
+ * Queries the current level of the receiver FIFO.
+ *
+ * The FIFOs must first be enabled before calling this function by calling
+ * alt_16550_fifo_enable().
+ *
+ * For the Altera 16550 Compatible UART, it may not be possible to read the
+ * FIFO level and this function may always report 0. For more information on
+ * interacting with the FIFO in this situation, see documentation for
+ * alt_16550_fifo_read().
+ *
+ * \param       handle
+ *              The UART device handle.
+ *
+ * \param       level
+ *              [out] Pointer to an output parameter that contains the level
+ *              or number of characters in the receiver FIFO.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The given UART device handle is invalid.
+ */
+ALT_STATUS_CODE alt_16550_fifo_level_get_rx(ALT_16550_HANDLE_t * handle,
+                                            uint32_t * level);
+
+/*!
+ * Queries the current level of the transmitter FIFO.
+ *
+ * The FIFOs must first be enabled before calling this function by calling
+ * alt_16550_fifo_enable().
+ *
+ * For the Altera 16550 Compatible UART, it may not be possible to read the
+ * FIFO level and this function may always report 0. For more information on
+ * interacting with the FIFO in this situation, see documentation for
+ * alt_16550_fifo_write().
+ *
+ * \param       handle
+ *              The UART device handle.
+ *
+ * \param       level
+ *              [out] Pointer to an output parameter that contains the level
+ *              or number of characters in the transmitter FIFO.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The given UART device handle is invalid.
+ */
+ALT_STATUS_CODE alt_16550_fifo_level_get_tx(ALT_16550_HANDLE_t * handle,
+                                            uint32_t * level);
+
+/*!
+ * Sets the receiver FIFO level which will trigger the receiver FIFO to issue
+ * receiver FIFO full event. For the list of available receiver FIFO trigger
+ * levels, see the documentation for ALT_16550_FIFO_TRIGGER_RX_t.
+ *
+ * The FIFOs must first be enabled before calling this function by calling
+ * alt_16550_fifo_enable().
+ *
+ * \param       handle
+ *              The UART device handle.
+ *
+ * \param       trigger
+ *              The level of the receiver FIFO which is needed to trigger a
+ *              receiver FIFO full event.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The given UART device handle is invalid.
+ */
+ALT_STATUS_CODE alt_16550_fifo_trigger_set_rx(ALT_16550_HANDLE_t * handle,
+                                              ALT_16550_FIFO_TRIGGER_RX_t trigger);
+
+/*!
+ * Sets the transmitter FIFO level which will trigger the transmitter FIFO to
+ * transmitter FIFO empty event. For the list of available transmitter FIFO
+ * trigger levels, see the documentation for ALT_16550_FIFO_TRIGGER_TX_t.
+ *
+ * The FIFOs must first be enabled before calling this function by calling
+ * alt_16550_fifo_enable().
+ *
+ * \param       handle
+ *              The UART device handle.
+ *
+ * \param       trigger
+ *              The level of the transmitter FIFO which is needed to trigger a
+ *              transmitter FIFO empty event.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The given UART device handle is invalid.
+ */
+ALT_STATUS_CODE alt_16550_fifo_trigger_set_tx(ALT_16550_HANDLE_t * handle,
+                                              ALT_16550_FIFO_TRIGGER_TX_t trigger);
+
+/*!
+ * @}
+ */
+
+/*!
+ * \addtogroup UART_BAUD UART Baudrate Interface
+ *
+ * This group of APIs allows for the configuration of the UART's baudrate
+ * generation related functions.
+ *
+ * The UART baudrate is determined by dividing the ALT_CLK_L4_SP clock with
+ * the configured divisor.
+ *
+ * @{
+ */
+
+/*!
+ * This enumeration lists out the common baudrates used with modem and serial
+ * ports. Not every baudrate is available for the UART due to the limits of
+ * the serial clock frequency and divisor value.
+ */
+typedef enum ALT_16550_BAUDRATE_e
+{
+    ALT_16550_BAUDRATE_50     =     50, /*!< 50 bps baudrate. */
+    ALT_16550_BAUDRATE_75     =     75, /*!< 75 bps baudrate. */
+    ALT_16550_BAUDRATE_150    =    150, /*!< 150 bps baudrate. */
+    ALT_16550_BAUDRATE_300    =    300, /*!< 300 bps baudrate. */
+    ALT_16550_BAUDRATE_600    =    600, /*!< 600 bps baudrate. */
+    ALT_16550_BAUDRATE_900    =    900, /*!< 900 bps baudrate. */
+    ALT_16550_BAUDRATE_1200   =   1200, /*!< 1200 bps baudrate. */
+    ALT_16550_BAUDRATE_1800   =   1800, /*!< 1800 bps baudrate. */
+    ALT_16550_BAUDRATE_2400   =   2400, /*!< 2400 bps baudrate. */
+    ALT_16550_BAUDRATE_3600   =   3600, /*!< 3600 bps baudrate. */
+    ALT_16550_BAUDRATE_4800   =   4800, /*!< 4800 bps baudrate. */
+    ALT_16550_BAUDRATE_7200   =   7200, /*!< 7200 bps baudrate. */
+    ALT_16550_BAUDRATE_9600   =   9600, /*!< 9600 bps baudrate. */
+    ALT_16550_BAUDRATE_14400  =  14400, /*!< 14400 bps baudrate. */
+    ALT_16550_BAUDRATE_19200  =  19200, /*!< 19200 bps baudrate. */
+    ALT_16550_BAUDRATE_28800  =  28800, /*!< 28800 bps baudrate. */
+    ALT_16550_BAUDRATE_38400  =  38400, /*!< 38400 bps baudrate. */
+    ALT_16550_BAUDRATE_57600  =  57600, /*!< 57600 bps baudrate. */
+    ALT_16550_BAUDRATE_115200 = 115200  /*!< 115200 bps baudrate. */
+}
+ALT_16550_BAUDRATE_t;
+
+/*!
+ * Gets the baudrate for the UART.
+ *
+ * This is done by calculating the baudrate from the divisor and the serial
+ * clock. The reported baudrate may not correspond exactly to the request
+ * baudrate.
+ *
+ * \param       handle
+ *              The UART device handle.
+ *
+ * \param       baudrate
+ *              [out] Pointer to an output paramter that contains the current
+ *              baudrate of the UART.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The given UART device handle is invalid.
+ */
+ALT_STATUS_CODE alt_16550_baudrate_get(ALT_16550_HANDLE_t * handle,
+                                       uint32_t * baudrate);
+
+/*!
+ * Sets the baudrate for the UART. This change will take effect when the UART
+ * moves from disabled to enabled.
+ *
+ * This is done by calculating the correct divisor using the request baudrate
+ * and the known serial clock.
+ *
+ * \param       handle
+ *              The UART device handle.
+ *
+ * \param       baudrate
+ *              The requested baudrate for the UART.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The given UART device handle is invalid.
+ * \retval      ALT_E_ARG_RANGE The given baudrate is not possible due to
+ *                              limitations of the baudrate divisor and/or
+ *                              serial clock.
+ */
+ALT_STATUS_CODE alt_16550_baudrate_set(ALT_16550_HANDLE_t * handle,
+                                       uint32_t baudrate);
+
+/*!
+ * Gets the baudrate divisor for the UART.
+ *
+ * The baudrate is determined by the following formula:
+ *  * Baudrate = (serial clock frequency) / (16 * divisor)
+ *
+ * \param       handle
+ *              The UART device handle.
+ *
+ * \param       divisor
+ *              [out] Pointer to an output parameter that contains the current
+ *              divisor used for baudrate generation.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The given UART device handle is invalid.
+ */
+ALT_STATUS_CODE alt_16550_divisor_get(ALT_16550_HANDLE_t * handle,
+                                      uint32_t * divisor);
+
+/*!
+ * Sets the baudrate divisor for the UART. This change will take effect when
+ * the UART moves from disabled to enabled.
+ *
+ * The baudrate is determined by the following formula:
+ *  * Baudrate = (serial clock frequency) / (16 * divisor)
+ *
+ * \param       handle
+ *              The UART device handle.
+ *
+ * \param       divisor
+ *              The specified divisor value to use for baudrate generation.
+ *              Valid values are 1 - 65535.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The given UART identifier is invalid or the
+ *                              specified divisor is not supported by the
+ *                              UART.
+ */
+ALT_STATUS_CODE alt_16550_divisor_set(ALT_16550_HANDLE_t * handle,
+                                      uint32_t divisor);
+
+/*!
+ * @}
+ */
+
+/*!
+ * \addtogroup UART_INT UART Interrupt Interface
+ *
+ * This group of APIs provides access, configuration, and control of the 
+ * UART interrupts. 
+ *
+ * @{
+ */
+
+/*!
+ * This type definition enumerates the different interrupt conditions that can
+ * be generated by the UART controller.
+ *
+ * Interrupts are listed in highest to lowest priority order.
+ */
+typedef enum ALT_16550_INT_STATUS_e
+{
+    /*!
+     * This interrupt signals that a overrun, parity, or framing error 
+     * occurred, or a break event occured. The interrupt is cleared by reading
+     * the line status by calling alt_16550_line_status_get() or by disabling
+     * line status interrupts by calling alt_16550_int_disable_line().
+     */
+    ALT_16550_INT_STATUS_LINE = 0x6,
+
+    /*!
+     * This interrupt signals that some data is available to be read from the
+     * UART. The definition of some depends on whether FIFOs are enabled or
+     * not.
+     *
+     * If FIFOs are disabled, this interrupt signals that the receiver
+     * contains data. In this case, the interrupt is cleared by reading the
+     * data from the UART by calling alt_16550_read().
+     *
+     * If FIFOs are enabled, this interrupt signals that the receiver FIFO
+     * level is above the receiver trigger level specified. In this case, the
+     * interrupt is cleared by reading a sufficiently large buffer from the
+     * receiver FIFO such that the FIFO is filled below the receiver trigger
+     * level specified by calling alt_16550_fifo_read() or by adjusting the
+     * receiver trigger level appropriately by calling
+     * alt_16550_fifo_trigger_set_rx().
+     *
+     * In either case, this interrupt can also be cleared by disabling
+     * receiver interrupts by calling alt_16550_int_disable_rx().
+     */
+    ALT_16550_INT_STATUS_RX_DATA = 0x4,
+
+    /*!
+     * This interrupt signals that data is available in the receiver FIFO and
+     * that there has been no activity with the receiver FIFO for the last 4
+     * character frames. In essence, the receiver FIFO has temporarily settled
+     * thus it may be a good time to empty the receiver FIFO. This interrupt
+     * is only available if FIFOs are enabled. The interrupt is cleared by
+     * reading from the receiver FIFO by calling alt_16550_fifo_read() or by
+     * disabling receiver interrupts by calling alt_16550_int_disable_rx().
+     */
+    ALT_16550_INT_STATUS_RX_TIMEOUT = 0xC,
+
+    /*!
+     * This interrupt signals that the transmitter is idling. The definition
+     * of idling depends on whether FIFOs are enabled or not.
+     *
+     * If FIFOs are disabled, this interrupt signals that the transmitter
+     * shift register is empty. In this case, the interrupt is cleared by
+     * writing data to the UART by calling alt_16550_write().
+     *
+     * If FIFO are enabled, this interrupt signals that the transmitter FIFO
+     * level is below the transmitter trigger level specified. In this case,
+     * the interrupt is cleared by writing a sufficiently large buffer to the
+     * transmitter FIFO such that the FIFO is filled above the transmitter
+     * trigger level specified by calling alt_16550_fifo_write() or by
+     * adjusting the transmitter trigger level appropriately by calling
+     * alt_16550_fifo_trigger_set_tx().
+     *
+     * In either case, this interrupt can also be cleared by disabling
+     * transmitter interrupts by calling alt_16550_int_disable_tx().
+     */
+    ALT_16550_INT_STATUS_TX_IDLE = 0x2,
+
+    /*!
+     * Modem status interrupt pending. The interrupt is cleared by reading the
+     * modem status by calling alt_16550_modem_status_get() or by disabling
+     * modem status interrupts by calling alt_16550_int_disable_modem().
+     */
+    ALT_16550_INT_STATUS_MODEM = 0x0,
+
+    /*!
+     * No interrupts pending.
+     */
+    ALT_16550_INT_STATUS_NONE = 0x1
+}
+ALT_16550_INT_STATUS_t;
+
+/*!
+ * Enables the receiver FIFO to generate interrupts. Enabling this interrupt
+ * allows for the following interrupt signal(s):
+ *  * ALT_16550_INT_STATUS_RX_DATA
+ *  * ALT_16550_INT_STATUS_RX_TIMEOUT
+ *
+ * This interrupt is disabled by default.
+ *
+ * The FIFOs must also be enabled for this interrupt to actually be generated.
+ *
+ * \param       handle
+ *              The UART device handle.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The given UART device handle is invalid.
+ */
+ALT_STATUS_CODE alt_16550_int_enable_rx(ALT_16550_HANDLE_t * handle);
+
+/*!
+ * Disables the receiver FIFO from generating interrupts.
+ *
+ * \param       handle
+ *              The UART device handle.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The given UART device handle is invalid.
+ */
+ALT_STATUS_CODE alt_16550_int_disable_rx(ALT_16550_HANDLE_t * handle);
+
+/*!
+ * Enables the transmitter FIFO to generate interrupts. Enabling this
+ * interrupt allows for the following interrupt signal(s):
+ *  * ALT_16550_INT_STATUS_TX_IDLE
+ *
+ * This interrupt is disabled by default.
+ *
+ * The FIFOs must also be enabled for this interrupt to actually be generated.
+ *
+ * \param       handle
+ *              The UART device handle.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The given UART device handle is invalid.
+ */
+ALT_STATUS_CODE alt_16550_int_enable_tx(ALT_16550_HANDLE_t * handle);
+
+/*!
+ * Disables the transmitter FIFO from generating interrupts.
+ *
+ * \param       handle
+ *              The UART device handle.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The given UART device handle is invalid.
+ */
+ALT_STATUS_CODE alt_16550_int_disable_tx(ALT_16550_HANDLE_t * handle);
+
+/*!
+ * Enables the receiver to generate line status interrupts. Enabling this
+ * interrupt allows for the following interrupt signal(s):
+ *  * ALT_16550_INT_STATUS_LINE
+ *
+ * This interrupt is disabled by default.
+ *
+ * \param       handle
+ *              The UART device handle.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The given UART device handle is invalid.
+ */
+ALT_STATUS_CODE alt_16550_int_enable_line(ALT_16550_HANDLE_t * handle);
+
+/*!
+ * Disables the receiver from generating line status interrupts.
+ *
+ * \param       handle
+ *              The UART device handle.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The given UART device handle is invalid.
+ */
+ALT_STATUS_CODE alt_16550_int_disable_line(ALT_16550_HANDLE_t * handle);
+
+/*!
+ * Enables the UART to generate modem status interrupts. Enabling this
+ * interrupt allows for the following interrupt signal(s):
+ *  * ALT_16550_INT_STATUS_MODEM
+ *
+ * This interrupt is disabled by default.
+ *
+ * \param       handle
+ *              The UART device handle.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The given UART device handle is invalid.
+ */
+ALT_STATUS_CODE alt_16550_int_enable_modem(ALT_16550_HANDLE_t * handle);
+
+/*!
+ * Disables the UART from generate modem status interrupts.
+ *
+ * \param       handle
+ *              The UART device handle.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The given UART device handle is invalid.
+ */
+ALT_STATUS_CODE alt_16550_int_disable_modem(ALT_16550_HANDLE_t * handle);
+
+/*!
+ * Disables all interrupts on the UART.
+ *
+ * \param       handle
+ *              The UART device handle.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The given UART device handle is invalid.
+ */
+ALT_STATUS_CODE alt_16550_int_disable_all(ALT_16550_HANDLE_t * handle);
+
+/*!
+ * Queries the interrupt status of the UART. This returns the highest priority
+ * interrupt pending. The appropriate interrupts must be enabled for them be
+ * generated in the UART.
+ *
+ * \param       handle
+ *              The UART device handle.
+ *
+ * \param       status
+ *              [out] Pointer to an output parameter that contains the current
+ *              interrupt status of the UART.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The given UART device handle is invalid.
+ */
+ALT_STATUS_CODE  alt_16550_int_status_get(ALT_16550_HANDLE_t * handle,
+                                          ALT_16550_INT_STATUS_t * status);
+
+/*!
+ * @}
+ */
+
+/*!
+ * \addtogroup UART_MODEM UART Modem Interface
+ *
+ * This group of APIs provides access, configuration, and control of the UART
+ * Modem interface.
+ *
+ * @{
+ */
+
+/*!
+ * This type definition enumerates the set of UART modem status conditions as
+ * register mask values.
+ */
+typedef enum ALT_16550_MODEM_STATUS_e
+{
+    /*!
+     * Data Carrier Detect. This status indicates that the carrier has been
+     * detected by the modem. It corresponds to an inverted dcd_n input. DCD
+     * is unasserted when dcd_n is logic 1 and asserted when dcd_n is logic 0.
+     */
+    ALT_16550_MODEM_STATUS_DCD = 1 << 7,
+
+    /*!
+     * Ring Indicator. This status indicates that the telephone ringing signal
+     * has been redeived by the modem. It corresponds to an inverted ri_n
+     * input. RI is unasserted when ri_n is logic 1 and asserted when ri_n is
+     * logic 0.
+     */
+    ALT_16550_MODEM_STATUS_RI = 1 << 6,
+
+    /*!
+     * Data Set Ready. This status indicates that the modem is ready to
+     * establish communications with the UART. It corresponds to an inverted
+     * dsr_n input. DSR is unasserted when dsr_n is logic 1 and asserted when
+     * dsr_n is logic 0.
+     */
+    ALT_16550_MODEM_STATUS_DSR = 1 << 5,
+
+    /*!
+     * Clear To Send. This status indicates the current state of the modem
+     * cts_n line. It corresponds to an inverted cts_n input. CTS is
+     * unasserted when cts_n is logic 1 and asserted when cts_n is logic 0.
+     */
+    ALT_16550_MODEM_STATUS_CTS = 1 << 4,
+
+    /*!
+     * Delta Data Carrier Detect. This status condition indicates that the
+     * Data Carrier Detect has changed since the last time the modem status
+     * was read. Reading the modem status clears this status. For more
+     * information about the Data Carrier Detect status, see
+     * ALT_16550_MODEM_STATUS_DCD.
+     */
+    ALT_16550_MODEM_STATUS_DDCD = 1 << 3,
+
+    /*!
+     * Trailing Edge of Ring Indicator. This status indicates that the Ring
+     * Indicator has changed from asserted to unasserted. Reading the modem
+     * status will clear this status. For more information about the Ring
+     * Indicator status, reference ALT_16550_MODEM_STATUS_RI.
+     */
+    ALT_16550_MODEM_STATUS_TERI = 1 << 2,
+
+    /*!
+     * Delta Data Set Ready. This status condition indicates that the Data Set
+     * Ready has changed since the last time the modem status was read.
+     * Reading the modem status will clear this status. For more information
+     * about the Data Set Ready status, see ALT_16550_MODEM_STATUS_DSR.
+     */
+    ALT_16550_MODEM_STATUS_DDSR = 1 << 1,
+
+    /*!
+     * Delta Clear To Send. This status condition indicates that the Clear To
+     * Send has changed since the last time the modem status was read. Reading
+     * the modem status will clear this status. For more information about the
+     * Clear To Send status, see ALT_16550_MODEM_STATUS_CTS.
+     */
+    ALT_16550_MODEM_STATUS_DCTS = 1 << 0
+}
+ALT_16550_MODEM_STATUS_t;
+
+/*!
+ * Enables automatic flow control in the UART modem. When in this mode, the
+ * rts_n is gated with the threshold trigger condition of the receiver FIFO.
+ *
+ * The Altera 16550 Compatible Soft IP UART may not have this option enabled.
+ *
+ * The FIFOs must be enabled for flow control to be used.
+ *
+ * The recommended bring up for flow control is as follows:
+ *  * Enable automatic flow control by calling alt_16550_flowcontrol_enable().
+ *    This will allow both the receiver FIFO and user RTS to control the rts_n
+ *    output. Because the user RTS is not enabled, the rts_n will be inactive
+ *    high.
+ *  * Enable RTS by calling alt_16550_modem_enable_rts(). This will give the
+ *    receiver FIFO to have full control of the rts_n output.
+ *
+ * \param       handle
+ *              The UART device handle.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The given UART device handle is invalid.
+ */
+ALT_STATUS_CODE alt_16550_flowcontrol_enable(ALT_16550_HANDLE_t * handle);
+
+/*!
+ * Disables automatic flow control in the UART modem.
+ *
+ * The recommended bring down for flow control is as follows:
+ *  * Disable RTS by calling alt_16550_modem_disable_rts(). This will disable
+ *    generation of the rts_n ouput.
+ *  * Disable automatic flow control by calling
+ *    alt_16550_flowcontrol_disable().
+ *
+ * The receiver FIFO will still be active after these steps.
+ *
+ * \param       handle
+ *              The UART device handle.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The given UART device handle is invalid.
+ */
+ALT_STATUS_CODE alt_16550_flowcontrol_disable(ALT_16550_HANDLE_t * handle);
+
+/*!
+ * Puts the UART in loopback mode. This is used for diagnostic and test
+ * purposes.
+ *
+ * The SoCFPGA UARTs does not support automatic flow control when in loopback
+ * mode.
+ *
+ * The Altera 16550 Compatible Soft IP UART implements this in 13.0sp1 and
+ * later. Setting this has no effect with 13.0.
+ *
+ * When in this mode, the modem control inputs (dsr_n, cts_n, ri_n, dcd_n) are
+ * disconnected and the modem control outputs (dtr_n, rts_n, out1_n, out2_n)
+ * are held inactive high externally and internally looped back to the inputs.
+ *
+ * \param       handle
+ *              The UART device handle.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The given UART device handle is invalid.
+ */
+ALT_STATUS_CODE alt_16550_loopback_enable(ALT_16550_HANDLE_t * handle);
+
+/*!
+ * Takes the UART out of loopback mode.
+ *
+ * \param       handle
+ *              The UART device handle.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The given UART device handle is invalid.
+ */
+ALT_STATUS_CODE alt_16550_loopback_disable(ALT_16550_HANDLE_t * handle);
+
+/*!
+ * Asserts the OUT1 output. OUT1 is inverted then driven out to out1_n.
+ *
+ * There are special considerations when the UART is in loopback mode. See
+ * alt_16550_loopback_enable() for more information.
+ *
+ * \param       handle
+ *              The UART device handle.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The given UART device handle is invalid.
+ */
+ALT_STATUS_CODE alt_16550_modem_enable_out1(ALT_16550_HANDLE_t * handle);
+
+/*!
+ * Unasserts the OUT1 output.  OUT1 is inverted then driven out to out1_n.
+ *
+ * There are special considerations when the UART is in loopback mode. See
+ * alt_16550_loopback_enable() for more information.
+ *
+ * \param       handle
+ *              The UART device handle.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The given UART device handle is invalid.
+ */
+ALT_STATUS_CODE alt_16550_modem_disable_out1(ALT_16550_HANDLE_t * handle);
+
+/*!
+ * Asserts the OUT2 output. OUT2 is inverted then driven out to out2_n.
+ *
+ * There are special considerations when the UART is in loopback mode. See
+ * alt_16550_loopback_enable() for more information.
+ *
+ * \param       handle
+ *              The UART device handle.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The given UART device handle is invalid.
+ */
+ALT_STATUS_CODE alt_16550_modem_enable_out2(ALT_16550_HANDLE_t * handle);
+
+/*!
+ * Unasserts the OUT2 output. OUT2 is inverted then driven out to out2_n.
+ *
+ * There are special considerations when the UART is in loopback mode. See
+ * alt_16550_loopback_enable() for more information.
+ *
+ * \param       handle
+ *              The UART device handle.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The given UART device handle is invalid.
+ */
+ALT_STATUS_CODE alt_16550_modem_disable_out2(ALT_16550_HANDLE_t * handle);
+
+/*!
+ * Asserts the RTS (Request To Send) output. RTS is inverted then driven out
+ * to rts_n. RTS is used to inform the modem that the UART is ready to receive
+ * data.
+ *
+ * There are special considerations when the UART is in automatic flow control
+ * mode. See alt_16550_flowcontrol_enable() for more information.
+ *
+ * There are special considerations when the UART is in loopback mode. See
+ * alt_16550_loopback_enable() for more information.
+ *
+ * \param       handle
+ *              The UART device handle.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The given UART device handle is invalid.
+ */
+ALT_STATUS_CODE alt_16550_modem_enable_rts(ALT_16550_HANDLE_t * handle);
+
+/*!
+ * Deaserts the RTS (Request To Send) output. RTS is inverted then driven out
+ * to rts_n.
+ *
+ * There are special considerations when the UART is in automatic flow control
+ * mode. See alt_16550_flowcontrol_enable() for more information.
+ *
+ * There are special considerations when the UART is in loopback mode. See
+ * alt_16550_loopback_enable() for more information.
+ *
+ * \param       handle
+ *              The UART device handle.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The given UART device handle is invalid.
+ */
+ALT_STATUS_CODE alt_16550_modem_disable_rts(ALT_16550_HANDLE_t * handle);
+
+/*!
+ * Asserts the DTR (Data Terminal Ready) output. DTR is inverted then driven
+ * out to dtr_n. DTR is used to inform the modem that UART is ready to
+ * establish communications.
+ *
+ * There are special considerations when the UART is in loopback mode. See
+ * alt_16550_loopback_enable() for more information.
+ *
+ * \param       handle
+ *              The UART device handle.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The given UART device handle is invalid.
+ */
+ALT_STATUS_CODE alt_16550_modem_enable_dtr(ALT_16550_HANDLE_t * handle);
+
+/*!
+ * Deasserts the DTR (Data Terminal Ready) output. DTR is inverted then driven
+ * out to dtr_n.
+ *
+ * There are special considerations when the UART is in loopback mode. See
+ * alt_16550_loopback_enable() for more information.
+ *
+ * \param       handle
+ *              The UART device handle.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The given UART device handle is invalid.
+ */
+ALT_STATUS_CODE alt_16550_modem_disable_dtr(ALT_16550_HANDLE_t * handle);
+
+/*!
+ * Reads the modem status from the UART.
+ *
+ * \param       handle
+ *              The UART device handle.
+ *
+ * \param       status
+ *              [out] Pointer to an output parameter that contains the current
+ *              modem status of the UART as a register mask.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The given UART device handle is invalid.
+ */
+ALT_STATUS_CODE alt_16550_modem_status_get(ALT_16550_HANDLE_t * handle,
+                                           uint32_t * status);
+
+/*!
+ * @}
+ */
+
+/*!
+ * \addtogroup UART_LINE UART Line Interface
+ *
+ * This group of APIs provides access, configuration, and control of the UART
+ * Line interface.
+ *
+ * @{
+ */
+
+/*!
+ * This type definition enumerates the supported databits per frame.
+ */
+typedef enum ALT_16550_DATABITS_e
+{
+    /*!
+     * This option selects 5 databits per frame.
+     */
+    ALT_16550_DATABITS_5 = 0,
+
+    /*!
+     * This option selects 6 databits per frame.
+     */
+    ALT_16550_DATABITS_6 = 1,
+
+    /*!
+     * This option selects 7 databits per frame.
+     */
+    ALT_16550_DATABITS_7 = 2,
+
+    /*!
+     * This option selects 8 databits per frame.
+     */
+    ALT_16550_DATABITS_8 = 3
+}
+ALT_16550_DATABITS_t;
+
+/*!
+ * This type definition enumerates the supported stopbits per frame.
+ */
+typedef enum ALT_16550_STOPBITS_e
+{
+    /*!
+     * This options specifies 1 stopbit per frame.
+     */
+    ALT_16550_STOPBITS_1 = 0,
+
+    /*!
+     * This options specifies 2 stopbits per frame. If the frame is
+     * configured with 5 databits, 1.5 stopbits is used instead.
+     */
+    ALT_16550_STOPBITS_2 = 1
+}
+ALT_16550_STOPBITS_t;
+
+/*!
+ * This type definition enumerates the possible parity to use per frame.
+ */
+typedef enum ALT_16550_PARITY_e
+{
+    /*!
+     * This option disables the parity error detection bit in the data frame.
+     */
+    ALT_16550_PARITY_DISABLE = 0,
+
+    /*!
+     * This option enables the odd parity error detection bit in the data
+     * frame.
+     */
+    ALT_16550_PARITY_ODD = 1,
+
+    /*!
+     * This option enables the even parity error detection bit in the data
+     * frame.
+     */
+    ALT_16550_PARITY_EVEN = 2
+}
+ALT_16550_PARITY_t;
+
+/*!
+ * This type definition enumerates the set of UART line status conditions as
+ * register mask values.
+ */
+typedef enum ALT_16550_LINE_STATUS_e
+{
+    /*!
+     * Receiver FIFO Error. This status indicates that one or more parity
+     * error, framing error, or break indication exists in the receiver FIFO.
+     * It is only set when FIFO is enabled. This status cleared when line
+     * status is read, the character with the issue is at the top of the FIFO,
+     * and when no other issues exist in the FIFO.
+     */
+    ALT_16550_LINE_STATUS_RFE = 1 << 7,
+
+    /*!
+     * Transmitter EMpTy (Empty). This status indicates that transmitter shift
+     * register is empty. If FIFOs are enabled, the status is set when the
+     * transmitter FIFO is also empty. This status is cleared when the
+     * transmitter shift registers is loaded by writing to the UART
+     * transmitter buffer or transmitter FIFO if FIFOs are enabled. This is
+     * done by calling alt_16550_write() and alt_16550_fifo_write()
+     * respectively.
+     */
+    ALT_16550_LINE_STATUS_TEMT = 1 << 6,
+
+    /*!
+     * Transmitter Holding Register Empty. This status indicates that the 
+     * transmitter will run out of data soon. The definition of soon depends
+     * on whether the FIFOs are enabled.
+     *
+     * If FIFOs are disabled, this status indicates that the transmitter will
+     * run out of data to send after the current transmit shift register
+     * completes. In this case, this status is cleared when the data is
+     * written to the UART. This can be done by calling alt_16550_write().
+     *
+     * If FIFOs are enabled, this status indicates that the transmitter FIFO
+     * level is below the transmitter trigger level specified. In this case,
+     * this status is cleared by writing a sufficiently large buffer to the
+     * transmitter FIFO such that the FIFO is filled above the transmitter
+     * trigger level specified by calling alt_16550_fifo_write() or by
+     * adjusting the transmitter trigger level appropriately by calling 
+     * alt_16550_fifo_trigger_set_tx().
+     *
+     * \internal
+     * The implementation of the UART driver always ensures that IER[7] is
+     * set. This means that the UART always has Programmable THRE (Transmitter
+     * Holding Register Empty) Interrupt Mode Enable (PTIME) enabled.
+     * \endinternal
+     */
+    ALT_16550_LINE_STATUS_THRE = 1 << 5,
+
+    /*!
+     * Break Interrupt. This status indicates that a break interrupt sequence
+     * is detected in the incoming serial data. This happens when the the data
+     * is 0 for longer than a frame would normally be transmitted. The break
+     * interrupt status is cleared by reading the line status by calling
+     * alt_16550_line_status_get().
+     *
+     * If FIFOs are enabled, this status will be set when the character with
+     * the break interrupt status is at the top of the receiver FIFO.
+     */
+    ALT_16550_LINE_STATUS_BI = 1 << 4,
+
+    /*!
+     * Framing Error. This status indicates that a framing error occurred in
+     * the receiver. This happens when the receiver detects a missing or
+     * incorrect number of stopbit(s).
+     *
+     * If FIFOs are enabled, this status will be set when the character with
+     * the framing error is at the top of the FIFO. When a framing error
+     * occurs, the UART attempts to resynchronize with the transmitting UART.
+     * This status is also set if break interrupt occurred.
+     */
+    ALT_16550_LINE_STATUS_FE = 1 << 3,
+
+    /*!
+     * Parity Error. This status indicates that a parity error occurred in the
+     * receiver.
+     *
+     * If FIFOs are enabled, this status will be set when the character with
+     * the parity error is at the top of the receiver FIFO. This status is
+     * also set if a break interrupt occurred.
+     */
+    ALT_16550_LINE_STATUS_PE = 1 << 2,
+
+    /*!
+     * Overrun Error. This status indicates that an overrun occurred in the
+     * receiver.
+     *
+     * If FIFOs are disabled, the arriving character will overwrite the
+     * existing character in the receiver. Any previously existing
+     * character(s) will be lost.
+     *
+     * If FIFOs are disabled, the arriving character will be discarded. The
+     * buffer will continue to contain the preexisting characters.
+     */
+    ALT_16550_LINE_STATUS_OE = 1 << 1,
+
+    /*!
+     * Data Ready. This status indicates that the receiver or receiver FIFO
+     * contains at least one character.
+     */
+    ALT_16550_LINE_STATUS_DR = 1 << 0
+}
+ALT_16550_LINE_STATUS_t;
+
+/*!
+ * Sets the configuration for a given character frame.
+ *
+ * \param       handle
+ *              The UART device handle.
+ *
+ * \param       databits
+ *              The number of databits for each character frame.
+ *
+ * \param       parity
+ *              The parity to use for each character frame.
+ *
+ * \param       stopbits
+ *              The number of stopbits for each character frame.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The given UART device handle is invalid.
+ */
+ALT_STATUS_CODE alt_16550_line_config_set(ALT_16550_HANDLE_t * handle,
+                                          ALT_16550_DATABITS_t databits,
+                                          ALT_16550_PARITY_t parity,
+                                          ALT_16550_STOPBITS_t stopbits);
+
+/*!
+ * Starts transmitting a break condition by transmitting a logic 0 state
+ * longer than a frame would normally be transmitted.
+ *
+ * \param       handle
+ *              The UART device handle.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The given UART device handle is invalid.
+ */
+ALT_STATUS_CODE alt_16550_line_break_enable(ALT_16550_HANDLE_t * handle);
+
+/*!
+ * Stops transmitting a break condition.
+ *
+ * \param       handle
+ *              The UART device handle.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The given UART device handle is invalid.
+ */
+ALT_STATUS_CODE alt_16550_line_break_disable(ALT_16550_HANDLE_t * handle);
+
+/*!
+ * Reads the line status from the UART.
+ *
+ * \param       handle
+ *              The UART device handle.
+ *
+ * \param       status
+ *              [out] Pointer to an output parameter that contains the current
+ *              line status of the UART.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The given UART device handle is invalid.
+ */
+ALT_STATUS_CODE alt_16550_line_status_get(ALT_16550_HANDLE_t * handle,
+                                          uint32_t * status);
+
+/*!
+ * @}
+ */
+
+/*!
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ALT_16550_UART_H__ */
diff --git a/c/src/lib/libbsp/arm/altera-cyclone-v/hwlib/include/alt_cache.h b/c/src/lib/libbsp/arm/altera-cyclone-v/hwlib/include/alt_cache.h
new file mode 100644
index 0000000..8d088ab
--- /dev/null
+++ b/c/src/lib/libbsp/arm/altera-cyclone-v/hwlib/include/alt_cache.h
@@ -0,0 +1,964 @@
+/******************************************************************************
+ *
+ * Copyright 2013 Altera Corporation. All Rights Reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ * 
+ ******************************************************************************/
+
+#ifndef __ALT_CACHE_H__
+#define __ALT_CACHE_H__
+
+#include "hwlib.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*!
+ * \addtogroup CACHE_MGR Cache Management API
+ *
+ * This module defines the cache management API for enabling and disabling L1
+ * data cache, L1 instruction cache, L1 dynamic branch prediction caches, L1
+ * TLB cache, and L2 cache in the SoC. As well, many it allows users to perform
+ * cache maintenance operations on these caches. This includes the following
+ * operations:
+ *  * Invalidate: Marks the cache line as being invalid, freeing up the space
+ *    to cache other data. All APIs which enable caches invalidates the memory
+ *    before being enabling the cache.
+ *  * Clean: If the cache line is dirty, it synchronizes the cache line data
+ *    with the upper level memory system and marks that line as clean. All APIs
+ *    which disable caches cleans the memory before disabling the cache.
+ *  * Purge: A term used in this API as a short form for clean and invalidate.
+ *    This operation cleans and invalidates a cache line in that order, as a
+ *    single command to the cache controller.
+ *
+ * The following reference materials were used in the design of this API:
+ *  * ARM® Architecture Reference Manual, ARMv7-A and ARMv7-R edition
+ *  * Cortex™-A9 Technical Reference Manual
+ *  * Cortex™-A9 MPCore Technical Reference Manual
+ *  * CoreLink™ Level 2 Cache Controller L2C-310 Technical Reference
+ *    Manual
+ *
+ * @{
+ */
+
+/*!
+ * \addtogroup CACHE_SYS System Level Cache Management API
+ *
+ * This API group provides cache maintenance operations which affects multiple
+ * cache levels.
+ *
+ * The enable and disable functions enables and disables all caches in the
+ * system respectively. For caches shared by the CPU core(s), particularly the
+ * L2 cache, once that cache is enabled or disabled it will not be invalidated
+ * or cleaned again respectively. This allows the safe system-wide enable and
+ * disable to be used in single-core and multi-core scenarios.
+ *
+ * For cache maintenance operations, this API implements the procedures
+ * outlined in the L2C-310 Technical Reference Manual, section 3.3.10,
+ * subsection "System cache maintenance considerations". This allows for a
+ * convenient way to invalidate, clean, or clean and invalidate cache data from
+ * the L1 to L2 to L3 while avoiding any potential race conditions in
+ * mutli-core or multi-master scenarios. It assumes that the L1 and L2 cache is
+ * set in "non-exclusive" mode. This means a segment of data can reside in both
+ * the L1 and L2 simultaneously. This is the default mode for caches in the
+ * system.
+ *
+ * The current implementation of the system cache APIs assumes that the MMU is
+ * configured with a flat memory mapping or that every virtual address matches
+ * perfectly with the physical address. This restriction may be lifted in a
+ * future release of the cache API implementation.
+ *
+ * @{
+ */
+
+/*!
+ * Enables support for a non-flat virtual memory. A flat virtual memory is
+ * where every virtual address matches exactly to the physical address, making
+ * the virtual to physical translation trivial. Adding support for non-flat
+ * adds some overhead for the VA to PA translation and error detection.
+ *
+ * To enable non-flat virtual memory support, defined
+ * ALT_CACHE_SUPPORT_NON_FLAT_VIRTUAL_MEMORY=1 in your Makefile when compiling
+ * HWLibs.
+ */
+#ifndef ALT_CACHE_SUPPORT_NON_FLAT_VIRTUAL_MEMORY
+#define ALT_CACHE_SUPPORT_NON_FLAT_VIRTUAL_MEMORY (0)
+#endif
+
+/*!
+ * This is the system wide cache line size, given in bytes.
+ */
+#define ALT_CACHE_LINE_SIZE         32
+
+/*!
+ * Enables all caches and features which improve reliability and speed on all
+ * cache controllers visible to the current CPU core. This includes parity
+ * error detection. Cache controllers visible to multiple CPU cores, for
+ * example the L2, will first be checked to be disabled before being enabled.
+ * All necessary cache maintenance operations will be done automatically.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ */
+ALT_STATUS_CODE alt_cache_system_enable(void);
+
+/*!
+ * Disables all cache controllers visible to the current CPU core. Cache
+ * controllers visible to multiple CPU cores, for example the L2, will first
+ * be checked to be enabled before being disabled. All necessary cache
+ * maintenance operations will be done automatically.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ */
+ALT_STATUS_CODE alt_cache_system_disable(void);
+
+/*!
+ * Invalidates the specified contents of all cache levels visible to the
+ * current CPU core for the given memory segment.
+ *
+ * The memory segment address and length specified must align to the
+ * characteristics of the cache line. This means the address and length must be
+ * multiples of the cache line size. To determine the cache line size, use the
+ * \b ALT_CACHE_LINE_SIZE macro.
+ *
+ * The following pseudocode outlines the operations carried out by this
+ * function:
+ *  -# L2 invalidate address(es)
+ *  -# L2 cache sync
+ *  -# L1 invalidate address(es)
+ *  -# DSB instruction
+ *
+ * The current implementation of the system cache APIs assumes that the MMU is
+ * configured with a flat memory mapping or that every virtual address matches
+ * perfectly with the physical address. This restriction may be lifted in a
+ * future release of the cache API implementation.
+ *
+ * \param       vaddress
+ *              The virtual address of the memory segment to be invalidated.
+ *
+ * \param       length
+ *              The length of the memory segment to be invalidated.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The memory segment is invalid.
+ * \retval      ALT_E_TMO       The memory operation timed out.
+ */
+ALT_STATUS_CODE alt_cache_system_invalidate(void * vaddress, size_t length);
+
+/*!
+ * Cleans the specified contents of all cache levels visible to the current
+ * CPU core for the given memory segment.
+ *
+ * The memory segment address and length specified must align to the
+ * characteristics of the cache line. This means the address and length must be
+ * multiples of the cache line size. To determine the cache line size, use the
+ * \b ALT_CACHE_LINE_SIZE macro.
+ *
+ * The following pseudocode outlines the operations carried out by this
+ * function:
+ *  -# L1 clean address(es)
+ *  -# DSB instruction
+ *  -# L2 clean address(es)
+ *  -# L2 cache sync
+ *
+ * The current implementation of the system cache APIs assumes that the MMU is
+ * configured with a flat memory mapping or that every virtual address matches
+ * perfectly with the physical address. This restriction may be lifted in a
+ * future release of the cache API implementation.
+ *
+ * \param       vaddress
+ *              The virtual address of the memory segment to be cleaned.
+ *
+ * \param       length
+ *              The length of the memory segment to be cleaned.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The memory segment is invalid.
+ * \retval      ALT_E_TMO       The memory operation timed out.
+ */
+ALT_STATUS_CODE alt_cache_system_clean(void * vaddress, size_t length);
+
+/*!
+ * Cleans and invalidates the specified contents of all cache levels visible
+ * to the current CPU core for the given memory segment.
+ *
+ * The memory segment address and length specified must align to the
+ * characteristics of the cache line. This means the address and length must be
+ * multiples of the cache line size. To determine the cache line size, use the
+ * \b ALT_CACHE_LINE_SIZE macro.
+ *
+ * The following pseudocode outlines the operations carried out by this
+ * function:
+ *  -# L1 clean address(es)
+ *  -# DSB instruction
+ *  -# L2 clean and invalidate address(es)
+ *  -# L2 cache sync
+ *  -# L1 invalidate address(es)
+ *  -# DSB instruction
+ *
+ * The current implementation of the system cache APIs assumes that the MMU is
+ * configured with a flat memory mapping or that every virtual address matches
+ * perfectly with the physical address. This restriction may be lifted in a
+ * future release of the cache API implementation.
+ *
+ * \param       vaddress
+ *              The virtual address of the memory segment to be purged.
+ *
+ * \param       length
+ *              The length of the memory segment to be purged.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The memory segment is invalid.
+ * \retval      ALT_E_TMO       The memory operation timed out.
+ */
+ALT_STATUS_CODE alt_cache_system_purge(void * vaddress, size_t length);
+
+/*!
+ * @}
+ */
+
+/*!
+ * \addtogroup CACHE_L1 L1 Cache Management API
+ *
+ * This API group provides functions to interact with various components of the
+ * L1 cache on the SoCFPGA. This includes the following cache components:
+ *  * Instruction Cache
+ *  * Data Cache
+ *  * Parity error detection
+ *  * Dynamic branch prediction
+ *  * Data prefetching
+ *
+ * The API within this group only affects the L1 cache on the current CPU. To
+ * interact the L1 cache on another CPU, the API must be called from that other
+ * CPU.
+ *
+ * With respect to bring-up, the L1 and L2 cache controller setups are fully
+ * independent. The L2 can be setup at any time, before or after the L1 is setup.
+ * \internal
+ * Source: Cortex-A9 MPCore TRM, section 5.3.4 "Multiprocessor bring-up".
+ * \endinternal
+ *
+ * @{
+ */
+
+/*!
+ * Enables all L1 caches and features on the current CPU core. This includes
+ * the instruction cache, data cache, parity error detection, branch target
+ * address cache, global history buffer, and data prefetching. All necessary
+ * maintenance tasks will be taken care of.
+ *
+ * This function should not be mixed with other L1 cache related functions
+ * which enable or disable caches individually.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ */
+ALT_STATUS_CODE alt_cache_l1_enable_all(void);
+
+/*!
+ * Disables all L1 caches and features on the current CPU core. This includes
+ * the instruction cache, data cache, parity error detection, branch target
+ * address cache, global history buffer, and data prefetching. All necessary
+ * maintenance tasks will be taken care of.
+ *
+ * This function should not be mixed with other L1 cache related functions
+ * which enable or disable caches individually.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ */
+ALT_STATUS_CODE alt_cache_l1_disable_all(void);
+
+/*!
+ * Enables the L1 instruction cache on the current CPU core. If the cache is
+ * already enabled, nothing is done. Otherwise the instruction cache is first
+ * invalidated before being enabled.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ */
+ALT_STATUS_CODE alt_cache_l1_instruction_enable(void);
+
+/*!
+ * Disables the L1 instruction cache on the current CPU core.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ */
+ALT_STATUS_CODE alt_cache_l1_instruction_disable(void);
+
+/*!
+ * Returns \b true when the L1 instruction cache is enabled and \b false when
+ * it is disabled on the current CPU core.
+ *
+ * \retval      true            The L1 instruction cache is enabled.
+ * \retval      false           The L1 instruction cache is disabled.
+ */
+bool alt_cache_l1_instruction_is_enabled(void);
+
+/*!
+ * Invalidates the contents of the L1 instruction cache on the current CPU
+ * core.
+ *
+ * Normally this is done automatically as part of
+ * alt_cache_l1_instruction_enable(), but in certain circumstances it may be
+ * necessary to invalidate it manually. An example of this situation is when
+ * the address space is remapped and the processor executes instructions from
+ * the new memory area.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ */
+ALT_STATUS_CODE alt_cache_l1_instruction_invalidate(void);
+
+/*!
+ * Enables the L1 data cache on the current CPU core.
+ *
+ * If the cache is already enabled nothing is done. Otherwise the data cache is
+ * first invalidated before being enabled.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ */
+ALT_STATUS_CODE alt_cache_l1_data_enable(void);
+
+/*!
+ * Disables the L1 data cache on the current CPU core.
+ *
+ * If the cache is already disabled nothing is done. Otherwise the data cache
+ * is first cleaned before being disabled.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ */
+ALT_STATUS_CODE alt_cache_l1_data_disable(void);
+
+/*!
+ * Returns \b true when the L1 data cache is enabled and \b false when it is
+ * disabled on the current CPU core.
+ *
+ * \retval      true            The L1 data cache is enabled.
+ * \retval      false           The L1 data cache is disabled.
+ */
+bool alt_cache_l1_data_is_enabled(void);
+
+/*!
+ * Invalidates the specified contents of the L1 data cache on the current CPU
+ * core for the given memory segment.
+ *
+ * The memory segment address and length specified must align to the
+ * characteristics of the cache line. This means the address and length must be
+ * multiples of the cache line size. To determine the cache line size, use the
+ * \b ALT_CACHE_LINE_SIZE macro.
+ *
+ * \param       vaddress
+ *              The virtual address of the memory segment to be invalidated.
+ *
+ * \param       length
+ *              The length of the memory segment to be invalidated.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The memory segment is invalid.
+ */
+ALT_STATUS_CODE alt_cache_l1_data_invalidate(void * vaddress, size_t length);
+
+/*!
+ * Invalidates the entire contents of the L1 data cache on the current CPU
+ * core.
+ *
+ * Normally this is done automatically as part of alt_cache_l1_data_enable(),
+ * but in certain circumstances it may be necessary to invalidate it manually.
+ * An example of this situation is when the address space is remapped and the
+ * processor accesses memory from the new memory area.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ */
+ALT_STATUS_CODE alt_cache_l1_data_invalidate_all(void);
+
+/*!
+ * Cleans the specified contents of the L1 data cache on the current CPU core
+ * for the given memory segment.
+ *
+ * The memory segment address and length specified must align to the
+ * characteristics of the cache line. This means the address and length must be
+ * multiples of the cache line size. To determine the cache line size, use the
+ * \b ALT_CACHE_LINE_SIZE macro.
+ *
+ * \param       vaddress
+ *              The virtual address of the memory segment to be cleaned.
+ *
+ * \param       length
+ *              The length of the memory segment to be cleaned.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The memory segment is invalid.
+ */
+ALT_STATUS_CODE alt_cache_l1_data_clean(void * vaddress, size_t length);
+
+/*!
+ * Cleans the entire L1 data cache for the current CPU core.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ */
+ALT_STATUS_CODE alt_cache_l1_data_clean_all(void);
+
+/*!
+ * Cleans and invalidates the specified contents of the L1 data cache on the
+ * current CPU core for the given memory segment.
+ *
+ * The memory segment address and length specified must align to the
+ * characteristics of the cache line. This means the address and length must be
+ * multiples of the cache line size. To determine the cache line size, use the
+ * \b ALT_CACHE_LINE_SIZE macro.
+ *
+ * Normally this is done automatically as part of alt_cache_l1_data_disable(),
+ * but in certain circumstances it may be necessary to purged it manually.
+ * An example of this situation is when the address space is remapped and the
+ * processor accesses memory from the new memory area.
+ *
+ * \param       vaddress
+ *              The virtual address of the memory segment to be purged.
+ *
+ * \param       length
+ *              The length of the memory segment to be purged.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The memory segment is invalid.
+ */
+ALT_STATUS_CODE alt_cache_l1_data_purge(void * vaddress, size_t length);
+
+/*!
+ * Cleans and invalidates the entire L1 data cache for the current CPU core.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ */
+ALT_STATUS_CODE alt_cache_l1_data_purge_all(void);
+
+/*!
+ * Enables the parity error detection feature in the L1 caches on the current
+ * CPU core.
+ *
+ * Ideally parity should be enabled before any L1 caches are enabled. If the
+ * instruction, data, and / or dynamic branch predictor caches are already
+ * enabled, they will first be cleaned (if needed) and disabled before parity
+ * is enabled in hardware. Afterwards, the affected caches will be invalidated
+ * and enabled.
+ *
+ * Parity and TLB interaction deserves special attention. The TLB is considered
+ * to be a L1 cache but is enabled when the MMU, which is grouped in another
+ * API, is enabled. Due to the system-wide influence of the MMU, it cannot be
+ * disabled and enabled with impunity as the other L1 caches, which are
+ * designed to operate as transparently as possible. Thus parity error
+ * detection must be enabled before the L1 TLB cache, and by extension the MMU,
+ * is enabled.
+ *
+ * For a parity error to be reported, the appropriate CPU PARITYFAIL interrupt
+ * for the current CPU core must be enabled using the interrupt controller API.
+ * For CPU0, ALT_INT_INTERRUPT_CPU0_PARITYFAIL is asserted if any parity error
+ * is detected while the other PARITYFAIL interrupts are for parity errors in a
+ * specific memory. Refer to the interrupt controller API for more details
+ * about programming the interrupt controller.
+ *
+ * In the event of a parity error is detected, the appropriate CPU parity
+ * interrupt will be raised. CPU parity interrupts are all edge triggered and
+ * are cleared by acknowledging them in the interrupt controller API.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ */
+ALT_STATUS_CODE alt_cache_l1_parity_enable(void);
+
+/*!
+ * Disables parity error detection in the L1 caches.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ */
+ALT_STATUS_CODE alt_cache_l1_parity_disable(void);
+
+/*!
+ * Returns \b true when parity error detection is enabled and \b false when it
+ * is disabled on the current CPU core.
+ *
+ * \retval      true            Parity error detection for L1 caches is
+ *                              enabled.
+ * \retval      false           Parity error detection for L1 caches is
+ *                              disabled.
+ */
+bool alt_cache_l1_parity_is_enabled(void);
+
+/*!
+ * Enables the dynamic branch predictor features on the current CPU core.
+ *
+ * This operation enables both the Branch Target Address Cache (BTAC) and
+ * the Global History Buffer (GHB). Affected caches are automatically
+ * invalidated before use.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ */
+ALT_STATUS_CODE alt_cache_l1_branch_enable(void);
+
+/*!
+ * Disables the dynamic branch predictor features on the current CPU core.
+ *
+ * This operation disables both the Branch Target Address Cache (BTAC) and
+ * the Global History Buffer (GHB).
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ */
+ALT_STATUS_CODE alt_cache_l1_branch_disable(void);
+
+/*!
+ * Returns \b true when both the dynamic predictor features are enabled and
+ * \b false when they are disabled on the current CPU core.
+ *
+ * \retval      true            The L1 branch predictor caches are all enabled.
+ * \retval      false           Some or all L1 branch predictor caches are
+ *                              disabled.
+ */
+bool alt_cache_l1_branch_is_enabled(void);
+
+/*!
+ * Invalidates the dynamic branch predictor feature caches on the current CPU
+ * core.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ */
+ALT_STATUS_CODE alt_cache_l1_branch_invalidate(void);
+
+/*!
+ * Enables the L1 cache data prefetch feature on the current CPU core.
+ *
+ * This allows data to be prefetched into the data cache before it is to be
+ * used. For example in a loop the current iteration may want to preload the
+ * data which will be used in the next teration. This is done by using the PLD
+ * instructions.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ */
+ALT_STATUS_CODE alt_cache_l1_prefetch_enable(void);
+
+/*!
+ * Disables the L1 cache data prefetch feature on the current CPU core.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ */
+ALT_STATUS_CODE alt_cache_l1_prefetch_disable(void);
+
+/*!
+ * Returns \b true if the L1 cache data prefetch feature is enabled and
+ * \b false if it is disabled on the current CPU core.
+ *
+ * \retval      true            The L1 data cache prefetch feature is enabled.
+ * \retval      false           The L1 data cache prefetch feature is disabled.
+ */
+bool alt_cache_l1_prefetch_is_enabled(void);
+
+/*!
+ * @}
+ */
+
+/*!
+ * \addtogroup CACHE_L2 L2 Cache Management API
+ *
+ * This API group provides functions to interact with various features of the
+ * L2 cache on the SoCFPGA. This includes the following features:
+ *  * L2 cache
+ *  * Parity error detection
+ *  * Data prefetching
+ *  * Interrupt Management
+ *
+ * \internal
+ * Additional features that may be implemented in the future:
+ *  * Lockdown
+ *  * Event counter
+ * \endinternal
+ *
+ * The API within this group affects the L2 cache which is visible to all CPUs
+ * on the system.
+ *
+ * With respect to bring-up, the L1 and L2 cache controller setups are fully
+ * independent. The L2 can be setup at any time, before or after the L1 is setup.
+ * \internal
+ * Source: Cortex-A9 MPCore TRM, section 5.3.4 "Multiprocessor bring-up".
+ * \endinternal
+ *
+ * @{
+ */
+
+/*!
+ * Initializes the L2 cache controller.
+ *
+ * \retval      ALT_E_SUCCESS   Successful status.
+ * \retval      ALT_E_ERROR     Details about error status code
+ */
+ALT_STATUS_CODE alt_cache_l2_init(void);
+
+/*!
+ * Uninitializes the L2 cache controller.
+ *
+ * \retval      ALT_E_SUCCESS   Successful status.
+ * \retval      ALT_E_ERROR     Details about error status code
+ */
+ALT_STATUS_CODE alt_cache_l2_uninit(void);
+
+/*!
+ * Enables the L2 cache features for data and instruction prefetching.
+ *
+ * Prefetching can be enabled or disabled while the L2 cache is enabled.
+ * \internal
+ * Source: Use the Prefetch Control Register.
+ * \endinternal
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ */
+ALT_STATUS_CODE alt_cache_l2_prefetch_enable(void);
+
+/*!
+ * Disables the L2 cache features for data and instruction prefetching.
+ *
+ * Prefetching can be enabled or disabled while the L2 cache is enabled.
+ * \internal
+ * Source: Use the Prefetch Control Register.
+ * \endinternal
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ */
+ALT_STATUS_CODE alt_cache_l2_prefetch_disable(void);
+
+/*!
+ * Returns \b true if either L2 cache data or instruction prefetch features are
+ * enabled and \b false if no prefetching features are enabled.
+ *
+ * \retval      true            The L2 data and instruction prefetch features
+ *                              are enabled.
+ * \retval      false           Some L2 data and instruction prefetch features
+ *                              are disabled.
+ */
+bool alt_cache_l2_prefetch_is_enabled(void);
+
+/*!
+ * Enables parity error detection in the L2 cache.
+ *
+ * Ideally parity should be enabled before the L2 cache is enabled. If the
+ * cache is already enabled, it will first be cleaned and disabled before
+ * parity is enabled in hardware. Afterwards, the cache will be invalidated and
+ * enabled.
+ *
+ * For a parity error to be reported, the ALT_CACHE_L2_INTERRUPT_PARRD and / or
+ * ALT_CACHE_L2_INTERRUPT_PARRT interrupt condition(s) must be enabled. This is
+ * done by calling alt_cache_l2_int_enable(). As well, the L2 cache interrupt
+ * must be enabled using the interrupt controller API. Refer to the interrupt
+ * controller API for more details about programming the interrupt controller.
+ *
+ * In the event of a parity error is detected, the appropriate L2 cache parity
+ * interrupt will be raised. To clear the parity interrupt(s), the appropriate
+ * L2 cache parity interrupt must be cleared by calling
+ * alt_cache_l2_int_status_clear().
+ *
+ * For ECC support, refer to the ECC related API documentation for more
+ * information.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ */
+ALT_STATUS_CODE alt_cache_l2_parity_enable(void);
+
+/*!
+ * Disables parity error detection in the L2 cache.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ */
+ALT_STATUS_CODE alt_cache_l2_parity_disable(void);
+
+/*!
+ * Returns \b true when parity error detection is enabled and \b false when it
+ * is disabled.
+ *
+ * \retval      true            The L2 cache parity error detection feature is
+ *                              enabled.
+ * \retval      false           The L2 cache parity error detection feature is
+ *                              disabled.
+ */
+bool alt_cache_l2_parity_is_enabled(void);
+
+/*!
+ * Enables the L2 cache.
+ *
+ * If the L2 cache is already enabled, nothing is done. Otherwise the entire
+ * contents of the cache is first invalidated before being enabled.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ */
+ALT_STATUS_CODE alt_cache_l2_enable(void);
+
+/*!
+ * Disables the L2 cache.
+ *
+ * If the L2 cache is already disabled, nothing is done. Otherwise the entire
+ * contents of the cache is first cleaned before being disabled.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ */
+ALT_STATUS_CODE alt_cache_l2_disable(void);
+
+/*!
+ * Returns \b true when the L2 cache is enabled and \b false when it is
+ * disabled.
+ *
+ * \retval      true            The L2 cache is enabled.
+ * \retval      false           The L2 cache is disabled.
+ */
+bool alt_cache_l2_is_enabled(void);
+
+/*!
+ * Flushes the L2 cache controller hardware buffers.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_TMO       The memory operation timed out.
+ */
+ALT_STATUS_CODE alt_cache_l2_sync(void);
+
+/*!
+ * Invalidates the specified contents of the L2 cache for the given memory
+ * segment.
+ *
+ * The memory segment address and length specified must align to the
+ * characteristics of the cache line. This means the address and length must be
+ * multiples of the cache line size. To determine the cache line size, use the
+ * \b ALT_CACHE_LINE_SIZE macro.
+ *
+ * \param       paddress
+ *              The physical address of the memory segment to be invalidated.
+ *
+ * \param       length
+ *              The length of the memory segment to be invalidated.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The memory segment is invalid.
+ * \retval      ALT_E_TMO       The memory operation timed out.
+ */
+ALT_STATUS_CODE alt_cache_l2_invalidate(void * paddress, size_t length);
+
+/*!
+ * Invalidates th entire contents of the L2 cache.
+ *
+ * Normally this is done automatically as part of alt_cache_l2_enable(), but
+ * in certain circumstances it may be necessary to invalidate it manually. An
+ * example of this situation is when the address space is remapped and the
+ * processor accesses memory from the new memory area.
+
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_TMO       The memory operation timed out.
+ */
+ALT_STATUS_CODE alt_cache_l2_invalidate_all(void);
+
+/*!
+ * Cleans the specified contents of the L2 cache for the given memory segment.
+ *
+ * The memory segment address and length specified must align to the
+ * characteristics of the cache line. This means the address and length must be
+ * multiples of the cache line size. To determine the cache line size, use the
+ * \b ALT_CACHE_LINE_SIZE macro.
+ *
+ * \param       paddress
+ *              The physical address of the memory segment to be cleaned.
+ *
+ * \param       length
+ *              The length of the memory segment to be cleaned.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The memory segment is invalid.
+ * \retval      ALT_E_TMO       The memory operation timed out.
+ */
+ALT_STATUS_CODE alt_cache_l2_clean(void * paddress, size_t length);
+
+/*!
+ * Cleans the entire L2 cache. All L2 cache controller interrupts will be
+ * temporarily disabled while the clean operation is in progress and restored
+ * once the it is finished.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_TMO       The memory operation timed out.
+ */
+ALT_STATUS_CODE alt_cache_l2_clean_all(void);
+
+/*!
+ * Cleans and invalidates the specified contents of the L2 cache for the
+ * given memory segment.
+ *
+ * The memory segment address and length specified must align to the
+ * characteristics of the cache line. This means the address and length must be
+ * multiples of the cache line size. To determine the cache line size, use the
+ * \b ALT_CACHE_LINE_SIZE macro.
+ *
+ * \param       paddress
+ *              The physical address of the memory segment to be purged.
+ *
+ * \param       length
+ *              The length of the memory segment to be purged.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The memory segment is invalid.
+ */
+ALT_STATUS_CODE alt_cache_l2_purge(void * paddress, size_t length);
+
+/*!
+ * Cleans and invalidates the entire L2 cache. All L2 cache controller
+ * interrupts will be temporarily disabled while the clean and invalidate
+ * operation is in progress and restored once the it is finished.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_TMO       The memory operation timed out.
+ */
+ALT_STATUS_CODE alt_cache_l2_purge_all(void);
+
+/*!
+ * This type definition enumerates all the interrupt conditions that can be
+ * generated by the L2 cache controller as register mask values.
+ */
+enum ALT_CACHE_L2_INTERRUPT_e
+{
+    /*! Decode error received on the master ports from L3. */
+    ALT_CACHE_L2_INTERRUPT_DECERR = 1 << 8,
+
+    /*! Slave error received on the master ports from L3.  */
+    ALT_CACHE_L2_INTERRUPT_SLVERR = 1 << 7,
+
+    /*! Error on the L2 data RAM read.                     */
+    ALT_CACHE_L2_INTERRUPT_ERRRD  = 1 << 6,
+
+    /*! Error on the L2 tag RAM read.                      */
+    ALT_CACHE_L2_INTERRUPT_ERRRT  = 1 << 5,
+
+    /*! Error on the L2 data RAM write.                    */
+    ALT_CACHE_L2_INTERRUPT_ERRWD  = 1 << 4,
+
+    /*! Error on the L2 tag RAM write.                     */
+    ALT_CACHE_L2_INTERRUPT_ERRWT  = 1 << 3,
+
+    /*! Parity error on the L2 data RAM read.              */
+    ALT_CACHE_L2_INTERRUPT_PARRD  = 1 << 2,
+
+    /*! Parity error on the L2 tag RAM read.               */
+    ALT_CACHE_L2_INTERRUPT_PARRT  = 1 << 1,
+
+    /*! Event counter overflow or increment.               */
+    ALT_CACHE_L2_INTERRUPT_ECNTR  = 1 << 0
+};
+typedef enum ALT_CACHE_L2_INTERRUPT_e ALT_CACHE_L2_INTERRUPT_t;
+
+/*!
+ * Enables the L2 cache controller interrupts for the specified set of
+ * condition(s).
+ *
+ * \param       interrupt
+ *              A register mask of the selected L2 cache controller
+ *              interrupting conditions.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ */
+ALT_STATUS_CODE alt_cache_l2_int_enable(uint32_t interrupt);
+
+/*!
+ * Disables the L2 cache controller interrupts for the specified set of
+ * condition(s).
+ *
+ * \param       interrupt
+ *              A register mask of the selected L2 cache controller
+ *              interrupting conditions.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ */
+ALT_STATUS_CODE alt_cache_l2_int_disable(uint32_t interrupt);
+
+/*!
+ * Gets the condition(s) causing the L2 cache controller to interrupt as a
+ * register mask.
+ *
+ * \returns     A register mask of the currently asserted and enabled
+ *              conditions resulting in an interrupt being generated.
+ */
+uint32_t alt_cache_l2_int_status_get(void);
+
+/*!
+ * Clears the specified conditon(s) causing the L2 cache controller to
+ * interrupt as a mask. Condition(s) specified which are not causing an
+ * interrupt or condition(s) specified which are not enabled are ignored.
+ *
+ * \param       interrupt
+ *              A register mask of the selected L2 cache controller
+ *              interrupting conditions.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ */
+ALT_STATUS_CODE alt_cache_l2_int_status_clear(uint32_t interrupt);
+
+/*!
+ * @}
+ */
+
+/*!
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ALT_CACHE_H__ */
diff --git a/c/src/lib/libbsp/arm/altera-cyclone-v/hwlib/include/alt_dma.h b/c/src/lib/libbsp/arm/altera-cyclone-v/hwlib/include/alt_dma.h
new file mode 100644
index 0000000..6be93fb
--- /dev/null
+++ b/c/src/lib/libbsp/arm/altera-cyclone-v/hwlib/include/alt_dma.h
@@ -0,0 +1,1007 @@
+/******************************************************************************
+*
+* Copyright 2013 Altera Corporation. All Rights Reserved.
+* 
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+* 
+* 1. Redistributions of source code must retain the above copyright notice,
+* this list of conditions and the following disclaimer.
+* 
+* 2. Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following disclaimer in the documentation
+* and/or other materials provided with the distribution.
+* 
+* 3. The name of the author may not be used to endorse or promote products
+* derived from this software without specific prior written permission.
+* 
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY EXPRESS OR
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED. IN NO
+* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+* OF SUCH DAMAGE.
+* 
+******************************************************************************/
+
+#ifndef __ALT_DMA_H__
+#define __ALT_DMA_H__
+
+#include "hwlib.h"
+#include "alt_dma_common.h"
+#include "alt_dma_program.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+/*!
+ * \addtogroup ALT_DMA DMA Controller API
+ *
+ * This module defines the API for configuration and use of the general purpose
+ * DMA controller for the SoC. The DMA controller is an instance of the ARM
+ * Corelink DMA Controller (DMA-330).
+ *
+ * References:
+ *  * ARM DDI 0424C, CoreLink DMA Controller DMA-330 Technical Reference
+ *    Manual.
+ *  * ARM DAI 0239A, Application Note 239 Example Programs for the CoreLink
+ *    DMA Controller DMA-330.
+ *  * Altera, Cyclone V Device Handbook Volume 3: Hard Processor System
+ *    Technical Reference Manual, DMA Controller.
+ *
+ * @{
+ */
+
+/*!
+ * \addtogroup ALT_DMA_COMPILE DMA API Compile Options
+ *
+ * This API provides control over the compile time inclusion of selected
+ * modules. This can allow for a smaller resulting binary.
+ *
+ * @{
+ */
+
+#ifndef ALT_DMA_PERIPH_PROVISION_16550_SUPPORT
+#define ALT_DMA_PERIPH_PROVISION_16550_SUPPORT (1)
+#endif
+
+#ifndef ALT_DMA_PERIPH_PROVISION_QSPI_SUPPORT
+#define ALT_DMA_PERIPH_PROVISION_QSPI_SUPPORT (1)
+#endif
+
+/*!
+ * @}
+ */
+
+/*!
+ * \addtogroup ALT_DMA_CSR DMA API for Configuration, Control, and Status
+ *
+ * This API provides functions for configuration, control, and status queries
+ * of the DMA controller.
+ *
+ * @{
+ */
+
+/*!
+ * This type definition enumerates the operational states that the DMA manager
+ * may have.
+ */
+typedef enum ALT_DMA_MANAGER_STATE_e
+{
+    ALT_DMA_MANAGER_STATE_STOPPED     = 0, /*!< Stopped */
+    ALT_DMA_MANAGER_STATE_EXECUTING   = 1, /*!< Executing */
+    ALT_DMA_MANAGER_STATE_CACHE_MISS  = 2, /*!< Cache Miss */
+    ALT_DMA_MANAGER_STATE_UPDATING_PC = 3, /*!< Updating PC */
+    ALT_DMA_MANAGER_STATE_WFE         = 4, /*!< Waiting for Event */
+    ALT_DMA_MANAGER_STATE_FAULTING    = 15 /*!< Faulting */
+}
+ALT_DMA_MANAGER_STATE_t;
+
+/*!
+ * This type definition enumerates the operational states that a DMA channel
+ * may have.
+ */
+typedef enum ALT_DMA_CHANNEL_STATE_e
+{
+    ALT_DMA_CHANNEL_STATE_STOPPED             = 0,  /*!< Stopped */
+    ALT_DMA_CHANNEL_STATE_EXECUTING           = 1,  /*!< Executing */
+    ALT_DMA_CHANNEL_STATE_CACHE_MISS          = 2,  /*!< Cache Miss */
+    ALT_DMA_CHANNEL_STATE_UPDATING_PC         = 3,  /*!< Updating PC */
+    ALT_DMA_CHANNEL_STATE_WFE                 = 4,  /*!< Waiting for Event */
+    ALT_DMA_CHANNEL_STATE_AT_BARRIER          = 5,  /*!< At Barrier */
+    ALT_DMA_CHANNEL_STATE_WFP                 = 7,  /*!< Waiting for Peripheral */
+    ALT_DMA_CHANNEL_STATE_KILLING             = 8,  /*!< Killing */
+    ALT_DMA_CHANNEL_STATE_COMPLETING          = 9,  /*!< Completing */
+    ALT_DMA_CHANNEL_STATE_FAULTING_COMPLETING = 14, /*!< Faulting Completing */
+    ALT_DMA_CHANNEL_STATE_FAULTING            = 15  /*!< Faulting */
+}
+ALT_DMA_CHANNEL_STATE_t;
+
+/*!
+ * This type definition enumerates the possible fault status that the DMA
+ * manager can have as a register mask.
+ */
+typedef enum ALT_DMA_MANAGER_FAULT_e
+{
+    /*!
+     * The DMA manager abort occured because of an instruction issued through
+     * the debug interface.
+     */
+    ALT_DMA_MANAGER_FAULT_DBG_INSTR       = (int32_t)(1UL << 30),
+
+    /*!
+     * The DMA manager instruction fetch AXI bus response was not OKAY.
+     */
+    ALT_DMA_MANAGER_FAULT_INSTR_FETCH_ERR = (int32_t)(1UL << 16),
+
+    /*!
+     * The DMA manager attempted to execute DMAWFE or DMASEV with
+     * inappropriate security permissions.
+     */
+    ALT_DMA_MANAGER_FAULT_MGR_EVNT_ERR    = (int32_t)(1UL <<  5),
+
+    /*!
+     * The DMA manager attempted to execute DMAGO with inappropriate security
+     * permissions.
+     */
+    ALT_DMA_MANAGER_FAULT_DMAGO_ERR       = (int32_t)(1UL <<  4),
+
+    /*!
+     * The DMA manager attempted to execute an instruction operand that was
+     * not valid for the DMA configuration.
+     */
+    ALT_DMA_MANAGER_FAULT_OPERAND_INVALID = (int32_t)(1UL <<  1),
+
+    /*!
+     * The DMA manager attempted to execute an undefined instruction.
+     */
+    ALT_DMA_MANAGER_FAULT_UNDEF_INSTR     = (int32_t)(1UL <<  0)
+}
+ALT_DMA_MANAGER_FAULT_t;
+
+/*!
+ * This type definition enumerates the possible fault status that a channel
+ * may have as a register mask.
+ */
+typedef enum ALT_DMA_CHANNEL_FAULT_e
+{
+    /*!
+     * The DMA channel has locked up due to resource starvation.
+     */
+    ALT_DMA_CHANNEL_FAULT_LOCKUP_ERR          = (int32_t)(1UL << 31),
+
+    /*!
+     * The DMA channel abort occured because of an instruction issued through
+     * the debug interface.
+     */
+    ALT_DMA_CHANNEL_FAULT_DBG_INSTR           = (int32_t)(1UL << 30),
+
+    /*!
+     * The DMA channel data read AXI bus reponse was not OKAY.
+     */
+    ALT_DMA_CHANNEL_FAULT_DATA_READ_ERR       = (int32_t)(1UL << 18),
+
+    /*!
+     * The DMA channel data write AXI bus response was not OKAY.
+     */
+    ALT_DMA_CHANNEL_FAULT_DATA_WRITE_ERR      = (int32_t)(1UL << 17),
+
+    /*!
+     * The DMA channel instruction fetch AXI bus response was not OKAY.
+     */
+    ALT_DMA_CHANNEL_FAULT_INSTR_FETCH_ERR     = (int32_t)(1UL << 16),
+
+    /*!
+     * The DMA channel MFIFO did not have the data for the DMAST instruction.
+     */
+    ALT_DMA_CHANNEL_FAULT_ST_DATA_UNAVAILABLE = (int32_t)(1UL << 13),
+
+    /*!
+     * The DMA channel MFIFO is too small to hold the DMALD instruction data,
+     * or too small to servic the DMAST instruction request.
+     */
+    ALT_DMA_CHANNEL_FAULT_MFIFO_ERR           = (int32_t)(1UL << 12),
+
+    /*!
+     * The DMA channel in non-secure state attempted to perform a secure read
+     * or write.
+     */
+    ALT_DMA_CHANNEL_FAULT_CH_RDWR_ERR         = (int32_t)(1UL <<  7),
+
+    /*!
+     * The DMA channel in non-secure state attempted to execute the DMAWFP,
+     * DMALDP, DMASTP, or DMAFLUSHP instruction involving a secure peripheral.
+     */
+    ALT_DMA_CHANNEL_FAULT_CH_PERIPH_ERR       = (int32_t)(1UL <<  6),
+
+    /*!
+     * The DMA channel in non-secure state attempted to execute the DMAWFE or
+     * DMASEV instruction for a secure event or secure interrupt (if
+     * applicable).
+     */
+    ALT_DMA_CHANNEL_FAULT_CH_EVNT_ERR         = (int32_t)(1UL <<  5),
+
+    /*!
+     * The DMA channel attempted to execute an instruction operand that was
+     * not valid for the DMA configuration.
+     */
+    ALT_DMA_CHANNEL_FAULT_OPERAND_INVALID     = (int32_t)(1UL <<  1),
+
+    /*!
+     * The DMA channel attempted to execute an undefined instruction.
+     */
+    ALT_DMA_CHANNEL_FAULT_UNDEF_INSTR         = (int32_t)(1UL <<  0)
+}
+ALT_DMA_CHANNEL_FAULT_t;
+
+/*!
+ * This type definition enumerates the possible DMA event-interrupt behavior
+ * option selections when a DMASEV instruction is executed.
+ */
+typedef enum ALT_DMA_EVENT_SELECT_e
+{
+    /*!
+     * If the DMA controller executes DMASEV for the event-interrupt resource
+     * then the DMA sends the event to all of the channel threads.
+     */
+    ALT_DMA_EVENT_SELECT_SEND_EVT,
+
+    /*!
+     * If the DMA controller executes DMASEV for the event-interrupt resource
+     * then the DMA sets the \b irq[N] HIGH.
+     */
+    ALT_DMA_EVENT_SELECT_SIG_IRQ
+}
+ALT_DMA_EVENT_SELECT_t;
+
+/*!
+ * This type enumerates the DMA peripheral interface MUX selection options
+ * available.
+ */
+typedef enum ALT_DMA_PERIPH_MUX_e
+{
+    /*! 
+     * Accept the reset default MUX selection
+     */ 
+    ALT_DMA_PERIPH_MUX_DEFAULT = 0,
+
+    /*!
+     * Select FPGA as the peripheral interface
+     */
+    ALT_DMA_PERIPH_MUX_FPGA    = 1,
+
+    /*!
+     * Select CAN as the peripheral interface
+     */
+    ALT_DMA_PERIPH_MUX_CAN     = 2
+}
+ALT_DMA_PERIPH_MUX_t;
+
+/*!
+ * This type defines the structure used to specify the configuration of the
+ * security states and peripheral interface MUX selections for the DMA
+ * controller.
+ */
+typedef struct ALT_DMA_CFG_s
+{
+    /*!
+     * DMA Manager security state configuration.
+     */
+    ALT_DMA_SECURITY_t manager_sec;
+
+    /*!
+     * DMA interrupt output security state configurations. Security state
+     * configurations are 0-based index-aligned with the enumeration values
+     * ALT_DMA_EVENT_0 through ALT_DMA_EVENT_7 of the ALT_DMA_EVENT_t type.
+     */
+    ALT_DMA_SECURITY_t irq_sec[8];
+
+    /*!
+     * Peripheral request interface security state configurations. Security
+     * state configurations are 0-based index-aligned with the enumeration
+     * values of the ALT_DMA_PERIPH_t type.
+     */
+    ALT_DMA_SECURITY_t periph_sec[32];
+
+    /*!
+     * DMA Peripheral Register Interface MUX Selections. MUX selections are
+     * 0-based index-aligned with the enumeration values
+     * ALT_DMA_PERIPH_FPGA_4_OR_CAN0_IF1 through
+     * ALT_DMA_PERIPH_FPGA_7_OR_CAN1_IF2 of the ALT_DMA_PERIPH_t type.
+     */
+    ALT_DMA_PERIPH_MUX_t periph_mux[4];
+}
+ALT_DMA_CFG_t;
+
+/*!
+ * Initialize the DMA controller.
+ *
+ * Initializes the DMA controller by setting the necessary control values to
+ * establish the security state and MUXed peripheral request interface selection
+ * configurations before taking the DMA controller out of reset.
+ *
+ * After the DMA is initialized, the following conditions hold true:
+ *  * All DMA channel threads are in the Stopped state.
+ *  * All DMA channel threads are available for allocation.
+ *  * DMA Manager thread is waiting for an instruction from either APB
+ *    interface.
+ *  * The security state configurations of the DMA Manager, interrupt outputs,
+ *    and peripheral request interfaces are established and immutable until the
+ *    DMA is reset.
+ *  * The MUXed peripheral request interface selection configurations are
+ *    established and immutable until the DMA is reset.
+ *
+ * \param       dma_cfg
+ *              A pointer to a ALT_DMA_CFG_t structure containing the desired
+ *              DMA controller security state and peripheral request interface
+ *              MUX selections.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ */
+ALT_STATUS_CODE alt_dma_init(const ALT_DMA_CFG_t * dma_cfg);
+
+/*!
+ * Uninitializes the DMA controller.
+ *
+ * Uninitializes the DMA controller by killing any running channel threads and
+ * putting the DMA controller into reset.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ */
+ALT_STATUS_CODE alt_dma_uninit(void);
+
+/*!
+ * Allocate a DMA channel resource for use.
+ *
+ * \param       channel
+ *              A DMA controller channel.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ */
+ALT_STATUS_CODE alt_dma_channel_alloc(ALT_DMA_CHANNEL_t channel);
+
+/*!
+ * Allocate a free DMA channel resource for use if there are any.
+ *
+ * \param       allocated
+ *              [out] A pointer to an output parameter that will contain the
+ *              channel allocated.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed. An unallocated channel
+ *                              may not be available at the time of the API
+ *                              call.
+ */
+ALT_STATUS_CODE alt_dma_channel_alloc_any(ALT_DMA_CHANNEL_t * allocated);
+
+/*!
+ * Free a DMA channel resource for reuse.
+ *
+ * \param       channel
+ *              The DMA controller channel resource to free.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed. The channel may not be in
+ *                              the STOPPED state.
+ */
+ALT_STATUS_CODE alt_dma_channel_free(ALT_DMA_CHANNEL_t channel);
+
+/*!
+ * Start execution of a DMA microcode program on the specified DMA channel
+ * thread resource.
+ *
+ * \param       channel
+ *              The DMA channel thread used to execute the microcode program.
+ *
+ * \param       pgm
+ *              The DMA microcode program.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ */
+ALT_STATUS_CODE alt_dma_channel_exec(ALT_DMA_CHANNEL_t channel,
+                                     ALT_DMA_PROGRAM_t * pgm);
+
+/*!
+ * Kill (abort) execution of any microcode program executing on the specified
+ * DMA channel thread resource.
+ *
+ * Terminates the channel thread of execution by issuing a DMAKILL instruction
+ * using the DMA APB slave interface.
+ *
+ * \param       channel
+ *              The DMA channel thread to abort any executing microcode program
+ *              on.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_TMO       Timeout waiting for the channel to change into
+ *                              KILLING or STOPPED state.
+ */
+ALT_STATUS_CODE alt_dma_channel_kill(ALT_DMA_CHANNEL_t channel);
+
+/*!
+ * Returns the current register value for the given DMA channel.
+ *
+ * \param       channel
+ *              The DMA channel thread to abort any executing microcode program
+ *              on.
+ *
+ * \param       reg
+ *              Register to get the value for.
+ *
+ * \param       val
+ *              [out] The current value of the requested register.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The specified channel or register is invalid.
+ */
+ALT_STATUS_CODE alt_dma_channel_reg_get(ALT_DMA_CHANNEL_t channel,
+                                        ALT_DMA_PROGRAM_REG_t reg, uint32_t * val);
+
+/*!
+ * Signals the occurrence of an event or interrupt, using the specified event
+ * number.
+ *
+ * Causes the CPU to issue a DMASEV instruction using the DMA APB slave
+ * interface.
+ *
+ * The Interrupt Enable Register (INTEN) register is used to control if each
+ * event-interrupt resource is either an event or an interrupt. The INTEN
+ * register sets the event-interrupt resource to function as an:
+ *  * Event - The DMAC generates an event for the specified event-interrupt
+ *            resource. When the DMAC executes a DMAWFE instruction for the
+ *            same event-interrupt resource then it clears the event.
+ *  * Interrupt - The DMAC sets the \b IRQ[N] signal high, where
+ *                \e evt_num is the number of the specified event
+ *                resource. The interrupt must be cleared after being handled.
+ *
+ * When the configured to generate an event, this function may be used to
+ * restart one or more waiting DMA channels (i.e. having executed a DMAWFE
+ * instruction).
+ *
+ * See the following sections from the \e ARM DDI 0424C, CoreLink DMA Controller
+ * DMA-330 Technical Reference Manual for implementation details and use cases:
+ *  * 2.5.1, Issuing Instructions to the DMAC using a Slave Interface
+ *  * 2.7, Using Events and Interrupts
+ *
+ * \param       evt_num   
+ *              A DMA event-interrupt resource. Allowable event values may be
+ *              ALT_DMA_EVENT_0 .. ALT_DMA_EVENT_7 but ALT_DMA_EVENT_ABORT is
+ *              not.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The given event number is invalid.
+ */
+ALT_STATUS_CODE alt_dma_send_event(ALT_DMA_EVENT_t evt_num);
+
+/*!
+ * Returns the current operational state of the DMA manager thread.
+ *
+ * \param       state
+ *              [out] Pointer to an output parameter to contain the DMA
+ *              channel thread state.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ */
+ALT_STATUS_CODE alt_dma_manager_state_get(ALT_DMA_MANAGER_STATE_t * state);
+
+/*!
+ * Returns the current operational state of the specified DMA channel thread.
+ *
+ * \param       channel
+ *              The DMA channel thread to return the operational state of.
+ *
+ * \param       state
+ *              [out] Pointer to an output parameter to contain the DMA
+ *              channel thread state.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The given channel identifier is invalid.
+ */
+ALT_STATUS_CODE alt_dma_channel_state_get(ALT_DMA_CHANNEL_t channel,
+                                          ALT_DMA_CHANNEL_STATE_t * state);
+
+/*!
+ * Return the current fault status of the DMA manager thread.
+ *
+ * \param       fault
+ *              [out] Pointer to an output parameter to contain the DMA
+ *              manager fault status.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ */
+ALT_STATUS_CODE alt_dma_manager_fault_status_get(ALT_DMA_MANAGER_FAULT_t * fault);
+
+/*!
+ * Return the current fault status of the specified DMA channel thread.
+ *
+ * \param       channel
+ *              The DMA channel thread to return the fault status of.
+ *
+ * \param       fault
+ *              [out] Pointer to an output parameter to contain the DMA
+ *              channel fault status.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The given channel identifier is invalid.
+ */
+ALT_STATUS_CODE alt_dma_channel_fault_status_get(ALT_DMA_CHANNEL_t channel,
+                                                 ALT_DMA_CHANNEL_FAULT_t * fault);
+
+/*!
+ * Select whether the DMA controller sends the specific event to all channel
+ * threads or signals an interrupt using the corressponding \b irq when a DMASEV
+ * instruction is executed for the specified event-interrupt resource number.
+ *
+ * \param       evt_num
+ *              The event-interrupt resource number. Valid values are
+ *              ALT_DMA_EVENT_0 .. ALT_DMA_EVENT_7 and ALT_DMA_EVENT_ABORT.
+ *
+ * \param       opt
+ *              The desired behavior selection for \e evt_num when a DMASEV is
+ *              executed.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The given selection identifier is invalid.
+ */
+ALT_STATUS_CODE alt_dma_event_int_select(ALT_DMA_EVENT_t evt_num,
+                                         ALT_DMA_EVENT_SELECT_t opt);
+
+/*!
+ * Returns the status of the specified event-interrupt resource.
+ *
+ * Returns ALT_E_TRUE if event is active or \b irq[N] is HIGH and returns
+ * ALT_E_FALSE if event is inactive or \b irq[N] is LOW.
+ *
+ * \param       evt_num
+ *              The event-interrupt resource number. Valid values are
+ *              ALT_DMA_EVENT_0 .. ALT_DMA_EVENT_7 and ALT_DMA_EVENT_ABORT.
+ *
+ * \retval      ALT_E_TRUE      Event is active or \b irq[N] is HIGH.
+ * \retval      ALT_E_FALSE     Event is inactive or \b irq[N] is LOW.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The given event identifier is invalid.
+ */
+ALT_STATUS_CODE alt_dma_event_int_status_get_raw(ALT_DMA_EVENT_t evt_num);
+
+/*!
+ * Returns the status of the specified interrupt resource.
+ *
+ * Returns ALT_E_TRUE if interrupt is active and therfore \b irq[N] is HIGH and
+ * returns ALT_E_FALSE if interrupt is inactive and therfore \b irq[N] is LOW.
+ *
+ * \param       irq_num
+ *              The interrupt resource number. Valid values are
+ *              ALT_DMA_EVENT_0 .. ALT_DMA_EVENT_7 and ALT_DMA_EVENT_ABORT.
+ *
+ * \retval      ALT_E_TRUE      Event is active or \b irq[N] is HIGH.
+ * \retval      ALT_E_FALSE     Event is inactive or \b irq[N] is LOW.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The given event identifier is invalid.
+ */
+ALT_STATUS_CODE alt_dma_int_status_get(ALT_DMA_EVENT_t irq_num);
+
+/*!
+ * Clear the active (HIGH) status of the specified interrupt resource.
+ *
+ * If the specified interrupt is HIGH, then sets \b irq[N] to LOW if the
+ * event-interrupt resource is configured (see: alt_dma_event_int_enable()) 
+ * to signal an interrupt. Otherwise, the status of \b irq[N] does not change.
+ *
+ * \param       irq_num
+ *              The interrupt resource number. Valid values are
+ *              ALT_DMA_EVENT_0 .. ALT_DMA_EVENT_7 and ALT_DMA_EVENT_ABORT.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The given event identifier is invalid.
+ */
+ALT_STATUS_CODE alt_dma_int_clear(ALT_DMA_EVENT_t irq_num);
+
+/*!
+ * @}
+ */
+
+/*!
+ * \addtogroup ALT_DMA_STD_OPS DMA API for Standard Operations
+ *
+ * The functions in this group provide common DMA operations for common bulk
+ * data transfers between:
+ *  * Memory to Memory
+ *  * Zero to Memory
+ *  * Memory to Peripheral
+ *  * Peripheral to Memory
+ *
+ * All DMA operations are asynchronous. The following are the ways to receive
+ * notification of a DMA transfer complete operation:
+ *  * Use alt_dma_channel_state_get() and poll for the 
+ *    ALT_DMA_CHANNEL_STATE_STOPPED status.
+ *  * In conjunction with the interrupt API, use DMA events to signal an
+ *    interrupt. The event first must be configured to signal an interrupt
+ *    using alt_dma_event_int_select(). Configure the DMA program to send an
+ *    event.
+ *  * Construct a custom program which waits for a particular event number by
+ *    assemblying a DMAWFE using alt_dma_program_DMAWFE(). Then run the custom
+ *    program on a different channel. The custom program will wait until the
+ *    DMA program sends the event. Configure the DMA program to send an event.
+ *
+ * Cache related maintenance on the source and/or destinatino buffer are not
+ * handled the DMA API and are the responsibility of the programmer. This is
+ * because the DMA API does not have visibility into the current configuration
+ * of the MMU or know about any special considerations regarding the source
+ * and/or destination memory. The following are some example scenarios and
+ * cache maintenance related precautions that may need to be taken:
+ *  * alt_dma_memory_to_memory(): Source buffer should be cleaned or purged,
+ *    destination buffer should be invalidated.
+ *  * alt_dma_zero_to_memory(): Destination buffer should be invalidated.
+ *  * alt_dma_memory_to_register(): Source buffer should be cleaned or purged.
+ *  * alt_dma_register_to_memory(): Destination buffer should be invalidated.
+ *  * alt_dma_memory_to_periph(): Source buffer should be cleaned or purged.
+ *  * alt_dma_periph_to_memory(): Destination buffer should be invalidated.
+ *
+ * @{
+ */
+
+/*!
+ * Uses the DMA engine to asynchronously copy the specified memory from the
+ * given source address to the given destination address.
+ *
+ * Overlapping memory regions are not supported.
+ *
+ * \param       channel
+ *              The DMA channel thread to use for the transfer.
+ *
+ * \param       program
+ *              An allocated DMA program buffer to use for the life of the
+ *              transfer.
+ *
+ * \param       dest
+ *              The destination memory address to copy to.
+ *
+ * \param       src
+ *              The source memory address to copy from.
+ *
+ * \param       size
+ *              The size of the transfer in bytes.
+ *
+ * \param       send_evt
+ *              If set to true, the DMA engine will be instructed to send an
+ *              event upon completion or fault.
+ *
+ * \param       evt
+ *              If send_evt is true, the event specified will be sent.
+ *              Otherwise the parameter is ignored.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The given channel or event identifier (if
+ *                              used) is invalid, or the memory regions
+ *                              specified are overlapping.
+ */
+ALT_STATUS_CODE alt_dma_memory_to_memory(ALT_DMA_CHANNEL_t channel,
+                                         ALT_DMA_PROGRAM_t * program,
+                                         void * dest,
+                                         const void * src,
+                                         size_t size,
+                                         bool send_evt,
+                                         ALT_DMA_EVENT_t evt);
+
+/*!
+ * Uses the DMA engine to asynchronously zero out the specified memory buffer.
+ *
+ * \param       channel
+ *              The DMA channel thread to use for the transfer.
+ *
+ * \param       program
+ *              An allocated DMA program buffer to use for the life of the
+ *              transfer.
+ *
+ * \param       buf
+ *              The buffer memory address to zero out.
+ *
+ * \param       size
+ *              The size of the buffer in bytes.
+ *
+ * \param       send_evt
+ *              If set to true, the DMA engine will be instructed to send an
+ *              event upon completion or fault.
+ *
+ * \param       evt
+ *              If send_evt is true, the event specified will be sent.
+ *              Otherwise the parameter is ignored.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The given channel or event identifier (if
+ *                              used) is invalid.
+ */
+ALT_STATUS_CODE alt_dma_zero_to_memory(ALT_DMA_CHANNEL_t channel,
+                                       ALT_DMA_PROGRAM_t * program,
+                                       void * buf,
+                                       size_t size,
+                                       bool send_evt,
+                                       ALT_DMA_EVENT_t evt);
+
+/*!
+ * Uses the DMA engine to asynchronously transfer the contents of a memory
+ * buffer to a keyhole register.
+ *
+ * \param       channel
+ *              The DMA channel thread to use for the transfer.
+ *
+ * \param       program
+ *              An allocated DMA program buffer to use for the life of the
+ *              transfer.
+ *
+ * \param       dst_reg
+ *              The address of the register to write buffer to.
+ *
+ * \param       src_buf
+ *              The address of the memory buffer for the data.
+ *
+ * \param       count
+ *              The number of transfers to make.
+ *
+ * \param       register_width_bits
+ *              The width of the register to transfer to in bits. Valid values
+ *              are 8, 16, 32, and 64.
+ *
+ * \param       send_evt
+ *              If set to true, the DMA engine will be instructed to send an
+ *              event upon completion or fault.
+ *
+ * \param       evt
+ *              If send_evt is true, the event specified will be sent.
+ *              Otherwise the parameter is ignored.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The given channel, event identifier (if used),
+ *                              or register width are invalid, or if the
+ *                              destination register or source buffer is
+ *                              unaligned to the register width.
+ */
+ALT_STATUS_CODE alt_dma_memory_to_register(ALT_DMA_CHANNEL_t channel,
+                                           ALT_DMA_PROGRAM_t * program,
+                                           void * dst_reg,
+                                           const void * src_buf,
+                                           size_t count,
+                                           uint32_t register_width_bits,
+                                           bool send_evt,
+                                           ALT_DMA_EVENT_t evt);
+
+/*!
+ * Uses the DMA engine to asynchronously transfer the contents of a keyhole
+ * register to a memory buffer.
+ *
+ * \param       channel
+ *              The DMA channel thread to use for the transfer.
+ *
+ * \param       program
+ *              An allocated DMA program buffer to use for the life of the
+ *              transfer.
+ *
+ * \param       dst_buf
+ *              The address of the memory buffer to copy to.
+ *
+ * \param       src_reg
+ *              The address of the keyhole register to read from.
+ *
+ * \param       count
+ *              The number of transfers to make.
+ *
+ * \param       register_width_bits
+ *              The width of the register to transfer to in bits. Valid values
+ *              are 8, 16, 32, and 64.
+ *
+ * \param       send_evt
+ *              If set to true, the DMA engine will be instructed to send an
+ *              event upon completion or fault.
+ *
+ * \param       evt
+ *              If send_evt is true, the event specified will be sent.
+ *              Otherwise the parameter is ignored.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The given channel, event identifier (if used),
+ *                              or register width are invalid, or if the
+ *                              destination buffer or source register is
+ *                              unaligned to the register width.
+ */
+ALT_STATUS_CODE alt_dma_register_to_memory(ALT_DMA_CHANNEL_t channel,
+                                           ALT_DMA_PROGRAM_t * program,
+                                           void * dst_buf,
+                                           const void * src_reg,
+                                           size_t count,
+                                           uint32_t register_width_bits,
+                                           bool send_evt,
+                                           ALT_DMA_EVENT_t evt);
+
+/*!
+ * Uses the DMA engine to asynchronously copy memory from the given source
+ * address to the specified peripheral. Because different peripheral has
+ * different characteristics, individual peripherals need to be explicitly
+ * supported.
+ *
+ * The following lists the peripheral IDs supported by this API:
+ *  * ALT_DMA_PERIPH_QSPI_FLASH_TX
+ *  * ALT_DMA_PERIPH_UART0_TX
+ *  * ALT_DMA_PERIPH_UART1_TX
+ *
+ * \param       channel
+ *              The DMA channel thread to use for the transfer.
+ *
+ * \param       program
+ *              An allocated DMA program buffer to use for the life of the
+ *              transfer.
+ *
+ * \param       dest
+ *              The destination peripheral to copy memory to.
+ *
+ * \param       src
+ *              The source memory address to copy from.
+ *
+ * \param       size
+ *              The size of the transfer in bytes.
+ *
+ * \param       periph_info
+ *              A pointer to a peripheral specific data structure. The
+ *              following list shows what data structure should be used for
+ *              peripherals:
+ *               * ALT_DMA_PERIPH_QSPI_FLASH_TX: This parameter is ignored.
+ *               * ALT_DMA_PERIPH_UART0_TX: Use a pointer to the
+ *                 ALT_16550_HANDLE_t used to interact with that UART.
+ *               * ALT_DMA_PERIPH_UART1_TX: Use a pointer to the
+ *                 ALT_16550_HANDLE_t used to interact with that UART.
+ *
+ * \param       send_evt
+ *              If set to true, the DMA engine will be instructed to send an
+ *              event upon completion or fault.
+ *
+ * \param       evt
+ *              If send_evt is true, the event specified will be sent.
+ *              Otherwise the parameter is ignored.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The given channel, peripheral, or event
+ *                              identifier (if used) is invalid.
+ *
+ * \internal
+ * Priority peripheral IDs to be supported:
+ *  * ALT_DMA_PERIPH_FPGA_0
+ *  * ALT_DMA_PERIPH_FPGA_1
+ *  * ALT_DMA_PERIPH_FPGA_2
+ *  * ALT_DMA_PERIPH_FPGA_3
+ *  * ALT_DMA_PERIPH_FPGA_4
+ *  * ALT_DMA_PERIPH_FPGA_5
+ *  * ALT_DMA_PERIPH_FPGA_6
+ *  * ALT_DMA_PERIPH_FPGA_7
+ *  * ALT_DMA_PERIPH_I2C0_TX
+ *  * ALT_DMA_PERIPH_I2C1_TX
+ *  * ALT_DMA_PERIPH_I2C2_TX
+ *  * ALT_DMA_PERIPH_I2C3_TX
+ *  * ALT_DMA_PERIPH_SPI0_MASTER_TX
+ *  * ALT_DMA_PERIPH_SPI0_SLAVE_TX
+ *  * ALT_DMA_PERIPH_SPI1_MASTER_TX
+ *  * ALT_DMA_PERIPH_SPI1_SLAVE_TX
+ * \endinternal
+ */
+ALT_STATUS_CODE alt_dma_memory_to_periph(ALT_DMA_CHANNEL_t channel,
+                                         ALT_DMA_PROGRAM_t * program,
+                                         ALT_DMA_PERIPH_t dest,
+                                         const void * src,
+                                         size_t size,
+                                         void * periph_info,
+                                         bool send_evt,
+                                         ALT_DMA_EVENT_t evt);
+
+/*!
+ * Uses the DMA engine to copy memory from the specified peripheral to the
+ * given destination address. Because different peripheral has different
+ * characteristics, individual peripherals need to be explicitly supported.
+ *
+ * The following lists the peripheral IDs supported by this API:
+ *  * ALT_DMA_PERIPH_QSPI_FLASH_RX
+ *  * ALT_DMA_PERIPH_UART0_RX
+ *  * ALT_DMA_PERIPH_UART1_RX
+ *
+ * \param       channel
+ *              The DMA channel thread to use for the transfer.
+ *
+ * \param       program
+ *              An allocated DMA program buffer to use for the life of the
+ *              transfer.
+ *
+ * \param       dest
+ *              The destination memory address to copy to.
+ *
+ * \param       src
+ *              The source peripheral to copy memory from.
+ *
+ * \param       size
+ *              The size of the transfer in bytes.
+ *
+ * \param       periph_info
+ *              A pointer to a peripheral specific data structure. The
+ *              following list shows what data structure should be used for
+ *              peripherals:
+ *               * ALT_DMA_PERIPH_QSPI_FLASH_RX: This parameter is ignored.
+ *               * ALT_DMA_PERIPH_UART0_RX: Use a pointer to the
+ *                 ALT_16550_HANDLE_t used to interact with that UART.
+ *               * ALT_DMA_PERIPH_UART1_RX: Use a pointer to the
+ *                 ALT_16550_HANDLE_t used to interact with that UART.
+ *
+ * \param       send_evt
+ *              If set to true, the DMA engine will be instructed to send an
+ *              event upon completion or fault.
+ *
+ * \param       evt
+ *              If send_evt is true, the event specified will be sent.
+ *              Otherwise the parameter is ignored.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     The operation failed.
+ * \retval      ALT_E_BAD_ARG   The given channel, peripheral, or event
+ *                              identifier (if used) is invalid.
+*
+ * \internal
+ * Priority peripheral IDs to be supported:
+ *  * ALT_DMA_PERIPH_FPGA_0
+ *  * ALT_DMA_PERIPH_FPGA_1
+ *  * ALT_DMA_PERIPH_FPGA_2
+ *  * ALT_DMA_PERIPH_FPGA_3
+ *  * ALT_DMA_PERIPH_FPGA_4
+ *  * ALT_DMA_PERIPH_FPGA_5
+ *  * ALT_DMA_PERIPH_FPGA_6
+ *  * ALT_DMA_PERIPH_FPGA_7
+ *  * ALT_DMA_PERIPH_I2C0_RX
+ *  * ALT_DMA_PERIPH_I2C1_RX
+ *  * ALT_DMA_PERIPH_I2C2_RX
+ *  * ALT_DMA_PERIPH_I2C3_RX
+ *  * ALT_DMA_PERIPH_SPI0_MASTER_RX
+ *  * ALT_DMA_PERIPH_SPI0_SLAVE_RX
+ *  * ALT_DMA_PERIPH_SPI1_MASTER_RX
+ *  * ALT_DMA_PERIPH_SPI1_SLAVE_RX
+ * \endinternal
+ */
+ALT_STATUS_CODE alt_dma_periph_to_memory(ALT_DMA_CHANNEL_t channel,
+                                         ALT_DMA_PROGRAM_t * program,
+                                         void * dest,
+                                         ALT_DMA_PERIPH_t src,
+                                         size_t size,
+                                         void * periph_info,
+                                         bool send_evt,
+                                         ALT_DMA_EVENT_t evt);
+
+/*!
+ * @}
+ */
+
+/*!
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif  /* __cplusplus */
+
+#endif  /* __ALT_DMA_H__ */
diff --git a/c/src/lib/libbsp/arm/altera-cyclone-v/hwlib/include/alt_dma_common.h b/c/src/lib/libbsp/arm/altera-cyclone-v/hwlib/include/alt_dma_common.h
new file mode 100644
index 0000000..e82bc1a
--- /dev/null
+++ b/c/src/lib/libbsp/arm/altera-cyclone-v/hwlib/include/alt_dma_common.h
@@ -0,0 +1,162 @@
+/******************************************************************************
+ *
+ * Copyright 2013 Altera Corporation. All Rights Reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ * 
+ ******************************************************************************/
+
+#ifndef __ALT_DMA_COMMON_H__
+#define __ALT_DMA_COMMON_H__
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif  /* __cplusplus */
+
+/*!
+ * \addtogroup ALT_DMA_COMMON DMA Controller Common API Definitions
+ *
+ * This module contains the common definitions for the DMA controller related
+ * APIs.
+ *
+ * @{
+ */
+
+/*!
+ * This type definition enumerates the DMA controller channel threads.
+ */
+typedef enum ALT_DMA_CHANNEL_e
+{
+    ALT_DMA_CHANNEL_0 = 0, /*!< DMA Channel Thread 0 */
+    ALT_DMA_CHANNEL_1 = 1, /*!< DMA Channel Thread 1 */
+    ALT_DMA_CHANNEL_2 = 2, /*!< DMA Channel Thread 2 */
+    ALT_DMA_CHANNEL_3 = 3, /*!< DMA Channel Thread 3 */
+    ALT_DMA_CHANNEL_4 = 4, /*!< DMA Channel Thread 4 */
+    ALT_DMA_CHANNEL_5 = 5, /*!< DMA Channel Thread 5 */
+    ALT_DMA_CHANNEL_6 = 6, /*!< DMA Channel Thread 6 */
+    ALT_DMA_CHANNEL_7 = 7  /*!< DMA Channel Thread 7 */
+}
+ALT_DMA_CHANNEL_t;
+
+/*!
+ * This type definition enumerates the SoC system peripherals implementing the
+ * required request interface that enables direct DMA transfers to/from the
+ * device.
+ *
+ * FPGA soft IP interface to the DMA are required to comply with the Synopsys
+ * protocol.
+ *
+ * Request interface numbers 4 through 7 are multiplexed between the CAN
+ * controllers and soft logic implemented in the FPGA fabric. The selection
+ * between the CAN controller and FPGA interfaces is determined at DMA
+ * initialization.
+ */
+typedef enum ALT_DMA_PERIPH_e
+{
+    ALT_DMA_PERIPH_FPGA_0             = 0,  /*!< FPGA soft IP interface 0 */
+    ALT_DMA_PERIPH_FPGA_1             = 1,  /*!< FPGA soft IP interface 1 */
+    ALT_DMA_PERIPH_FPGA_2             = 2,  /*!< FPGA soft IP interface 2 */
+    ALT_DMA_PERIPH_FPGA_3             = 3,  /*!< FPGA soft IP interface 3 */
+
+    ALT_DMA_PERIPH_FPGA_4_OR_CAN0_IF1 = 4,  /*!< Selectively MUXed FPGA 4 or CAN 0 interface 1 */
+    ALT_DMA_PERIPH_FPGA_5_OR_CAN0_IF2 = 5,  /*!< Selectively MUXed FPGA 5 or CAN 0 interface 2 */
+    ALT_DMA_PERIPH_FPGA_6_OR_CAN1_IF1 = 6,  /*!< Selectively MUXed FPGA 6 or CAN 1 interface 1 */
+    ALT_DMA_PERIPH_FPGA_7_OR_CAN1_IF2 = 7,  /*!< Selectively MUXed FPGA 7 or CAN 1 interface 2 */
+
+    ALT_DMA_PERIPH_FPGA_4             = 4,  /*!< Alias for ALT_DMA_PERIPH_FPGA_4_OR_CAN0_IF1 */
+    ALT_DMA_PERIPH_FPGA_5             = 5,  /*!< Alias for ALT_DMA_PERIPH_FPGA_5_OR_CAN0_IF2 */
+    ALT_DMA_PERIPH_FPGA_6             = 6,  /*!< Alias for ALT_DMA_PERIPH_FPGA_6_OR_CAN1_IF1 */
+    ALT_DMA_PERIPH_FPGA_7             = 7,  /*!< Alias for ALT_DMA_PERIPH_FPGA_7_OR_CAN1_IF2 */
+
+    ALT_DMA_PERIPH_CAN0_IF1           = 4,  /*!< Alias for ALT_DMA_PERIPH_FPGA_4_OR_CAN0_IF1 */
+    ALT_DMA_PERIPH_CAN0_IF2           = 5,  /*!< Alias for ALT_DMA_PERIPH_FPGA_5_OR_CAN0_IF2 */
+    ALT_DMA_PERIPH_CAN1_IF1           = 6,  /*!< Alias for ALT_DMA_PERIPH_FPGA_6_OR_CAN1_IF1 */
+    ALT_DMA_PERIPH_CAN1_IF2           = 7,  /*!< Alias for ALT_DMA_PERIPH_FPGA_7_OR_CAN1_IF2 */
+
+    ALT_DMA_PERIPH_I2C0_TX            = 8,  /*!< I<sup>2</sup>C 0 TX */
+    ALT_DMA_PERIPH_I2C0_RX            = 9,  /*!< I<sup>2</sup>C 0 RX */
+    ALT_DMA_PERIPH_I2C1_TX            = 10, /*!< I<sup>2</sup>C 1 TX */
+    ALT_DMA_PERIPH_I2C1_RX            = 11, /*!< I<sup>2</sup>C 1 RX */
+    ALT_DMA_PERIPH_I2C2_TX            = 12, /*!< I<sup>2</sup>C 2 TX */
+    ALT_DMA_PERIPH_I2C2_RX            = 13, /*!< I<sup>2</sup>C 2 RX */
+    ALT_DMA_PERIPH_I2C3_TX            = 14, /*!< I<sup>2</sup>C 3 TX */
+    ALT_DMA_PERIPH_I2C3_RX            = 15, /*!< I<sup>2</sup>C 3 RX */
+    ALT_DMA_PERIPH_SPI0_MASTER_TX     = 16, /*!< SPI 0 Master TX */
+    ALT_DMA_PERIPH_SPI0_MASTER_RX     = 17, /*!< SPI 0 Master RX */
+    ALT_DMA_PERIPH_SPI0_SLAVE_TX      = 18, /*!< SPI 0 Slave TX */
+    ALT_DMA_PERIPH_SPI0_SLAVE_RX      = 19, /*!< SPI 0 Slave RX */
+    ALT_DMA_PERIPH_SPI1_MASTER_TX     = 20, /*!< SPI 1 Master TX */
+    ALT_DMA_PERIPH_SPI1_MASTER_RX     = 21, /*!< SPI 1 Master RX */
+    ALT_DMA_PERIPH_SPI1_SLAVE_TX      = 22, /*!< SPI 1 Slave TX */
+    ALT_DMA_PERIPH_SPI1_SLAVE_RX      = 23, /*!< SPI 1 Slave RX */
+    ALT_DMA_PERIPH_QSPI_FLASH_TX      = 24, /*!< QSPI Flash TX */
+    ALT_DMA_PERIPH_QSPI_FLASH_RX      = 25, /*!< QSPI Flash RX */
+    ALT_DMA_PERIPH_STM                = 26, /*!< System Trace Macrocell */
+    ALT_DMA_PERIPH_RESERVED           = 27, /*!< Reserved */
+    ALT_DMA_PERIPH_UART0_TX           = 28, /*!< UART 0 TX */
+    ALT_DMA_PERIPH_UART0_RX           = 29, /*!< UART 0 RX */
+    ALT_DMA_PERIPH_UART1_TX           = 30, /*!< UART 1 TX */
+    ALT_DMA_PERIPH_UART1_RX           = 31  /*!< UART 1 RX */
+}
+ALT_DMA_PERIPH_t;
+
+/*!
+ * This type enumerates the DMA security state options available.
+ */
+typedef enum ALT_DMA_SECURITY_e
+{
+    ALT_DMA_SECURITY_DEFAULT   = 0, /*!< Use the default security value (e.g. reset default) */
+    ALT_DMA_SECURITY_SECURE    = 1, /*!< Secure */
+    ALT_DMA_SECURITY_NONSECURE = 2  /*!< Non-secure */
+}
+ALT_DMA_SECURITY_t;
+
+/*!
+ * This type definition enumerates the DMA event-interrupt resources.
+ */
+typedef enum ALT_DMA_EVENT_e
+{
+    ALT_DMA_EVENT_0     = 0, /*!< DMA Event 0 */
+    ALT_DMA_EVENT_1     = 1, /*!< DMA Event 1 */
+    ALT_DMA_EVENT_2     = 2, /*!< DMA Event 2 */
+    ALT_DMA_EVENT_3     = 3, /*!< DMA Event 3 */
+    ALT_DMA_EVENT_4     = 4, /*!< DMA Event 4 */
+    ALT_DMA_EVENT_5     = 5, /*!< DMA Event 5 */
+    ALT_DMA_EVENT_6     = 6, /*!< DMA Event 6 */
+    ALT_DMA_EVENT_7     = 7, /*!< DMA Event 7 */
+    ALT_DMA_EVENT_ABORT = 8  /*!< DMA Abort Event */
+}
+ALT_DMA_EVENT_t;
+
+/*!
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __ALT_DMA_COMMON_H__ */
diff --git a/c/src/lib/libbsp/arm/altera-cyclone-v/hwlib/include/alt_dma_program.h b/c/src/lib/libbsp/arm/altera-cyclone-v/hwlib/include/alt_dma_program.h
new file mode 100644
index 0000000..5fa876f
--- /dev/null
+++ b/c/src/lib/libbsp/arm/altera-cyclone-v/hwlib/include/alt_dma_program.h
@@ -0,0 +1,951 @@
+/******************************************************************************
+ *
+ * Copyright 2013 Altera Corporation. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ ******************************************************************************/
+
+#ifndef __ALT_DMA_PROGRAM_H__
+#define __ALT_DMA_PROGRAM_H__
+
+#include "hwlib.h"
+#include "alt_dma_common.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif  /* __cplusplus */
+
+/*!
+ * \addtogroup ALT_DMA_PRG DMA Controller Programming API
+ *
+ * This API provides functions for dynamically defining and assembling microcode
+ * programs for execution on the DMA controller.
+ *
+ * The microcode program assembly API provides users with the ability to develop
+ * highly optimized and tailored algorithms for data transfer between SoC FPGA
+ * IP blocks and/or system memory.
+ *
+ * The same microcode program assembly facilities are also used to implement the
+ * functions found in the HWLIB Common DMA Operations functional API.
+ *
+ * An ALT_DMA_PROGRAM_t structure is used to contain and assemble a DMA
+ * microcode program. The storage for an ALT_DMA_PROGRAM_t stucture is allocated
+ * from used specified system memory. Once a microcode program has been
+ * assembled in a ALT_DMA_PROGRAM_t it may be excecuted on a designated DMA
+ * channel thread. The microcode program may be rerun on any DMA channel thread
+ * whenever required as long as the integrity of the ALT_DMA_PROGRAM_t
+ * containing the program is maintained.
+ *
+ * @{
+ */
+
+/*!
+ * This preprocessor declares the DMA channel thread microcode instruction
+ * cache line width in bytes. It is recommended that the program buffers be
+ * sized to a multiple of the cache line size. This will allow for the most
+ * efficient microcode speed and space utilization.
+ */
+#define ALT_DMA_PROGRAM_CACHE_LINE_SIZE     (32)
+
+/*!
+ * This preprocessor declares the DMA channel thread microcode instruction
+ * cache line count. Thus the total size of the cache is the cache line size
+ * multipled by the cache line count. Programs larger than the cache size risk
+ * having a cache miss while executing.
+ */
+#define ALT_DMA_PROGRAM_CACHE_LINE_COUNT    (16)
+
+/*!
+ * This preprocessor definition determines the size of the program buffer
+ * within the ALT_DMA_PROGRAM_t structure. This size should provide adequate
+ * size for most DMA microcode programs. If calls within this API are
+ * reporting out of memory response codes, consider increasing the provisioned
+ * program buffersize.
+ *
+ * To specify another DMA microcode program buffer size, redefine the macro
+ * below by defining ALT_DMA_PROGRAM_PROVISION_BUFFER_SIZE to another size in
+ * your Makefile. It is recommended that the size be a multiple of the
+ * microcode engine cache line size. See ALT_DMA_PROGRAM_CACHE_LINE_SIZE for
+ * more information. The largest supported buffer size is 65536 bytes.
+ */
+#ifndef ALT_DMA_PROGRAM_PROVISION_BUFFER_SIZE
+#define ALT_DMA_PROGRAM_PROVISION_BUFFER_SIZE   (ALT_DMA_PROGRAM_CACHE_LINE_SIZE * ALT_DMA_PROGRAM_CACHE_LINE_COUNT)
+#endif
+
+/*!
+ * This type defines the structure used to assemble and contain a microcode
+ * program which can be executed by the DMA controller. The internal members
+ * are undocumented and should not be altered outside of this API.
+ */
+typedef struct ALT_DMA_PROGRAM_s
+{
+    uint32_t flag;
+
+    uint16_t buffer_start;
+    uint16_t code_size;
+
+    uint16_t loop0;
+    uint16_t loop1;
+
+    uint16_t sar;
+    uint16_t dar;
+
+    /*
+     * Add a little extra space so that regardless of where this structure
+     * sits in memory, a suitable start address can be aligned to the cache
+     * line stride while providing the requested buffer space.
+     */
+    uint8_t program[ALT_DMA_PROGRAM_PROVISION_BUFFER_SIZE +
+                    ALT_DMA_PROGRAM_CACHE_LINE_SIZE];
+}
+ALT_DMA_PROGRAM_t;
+
+/*!
+ * This type definition enumerates the DMA controller register names for use in
+ * microcode program definition.
+ */
+typedef enum ALT_DMA_PROGRAM_REG_e
+{
+    /*! Source Address Register */
+    ALT_DMA_PROGRAM_REG_SAR = 0x0,
+
+    /*! Destination Address Register */
+    ALT_DMA_PROGRAM_REG_DAR = 0x2,
+
+    /*! Channel Control Register */
+    ALT_DMA_PROGRAM_REG_CCR = 0x1
+}
+ALT_DMA_PROGRAM_REG_t;
+
+/*!
+ * This type definition enumerates the instruction modifier options available
+ * for use with selected DMA microcode instructions.
+ *
+ * The enumerations values are context dependent upon the instruction being
+ * modified.
+ *
+ * For the <b>DMALD[S|B]</b>, <b>DMALDP\<S|B></b>, <b>DMAST[S|B]</b>, and
+ * <b>DMASTP\<S|B></b> microcode instructions, the enumeration
+ * ALT_DMA_PROGRAM_INST_MOD_SINGLE specifies the <b>S</b> option modifier
+ * while the enumeration ALT_DMA_PROGRAM_INST_MOD_BURST specifies the <b>B</b>
+ * option modifier. The enumeration ALT_DMA_PROGRAM_INST_MOD_NONE specifies
+ * that no modifier is present for instructions where use of <b>[S|B]</b> is
+ * optional.
+ *
+ * For the <b>DMAWFP</b> microcode instruction, the enumerations
+ * ALT_DMA_PROGRAM_INST_MOD_SINGLE, ALT_DMA_PROGRAM_INST_MOD_BURST, or
+ * ALT_DMA_PROGRAM_INST_MOD_PERIPH each specify one of the corresponding
+ * options <b>\<single|burst|periph></b>.
+ */
+typedef enum ALT_DMA_PROGRAM_INST_MOD_e
+{
+    /*!
+     * This DMA instruction modifier specifies that no special modifier is
+     * added to the instruction.
+     */
+    ALT_DMA_PROGRAM_INST_MOD_NONE,
+
+    /*!
+     * Depending on the DMA microcode instruction modified, this modifier
+     * specifies <b>S</b> case for a <b>[S|B]</b> or a <b>\<single></b> for a
+     * <b>\<single|burst|periph></b>.
+     */
+    ALT_DMA_PROGRAM_INST_MOD_SINGLE,
+
+    /*!
+     * Depending on the DMA microcode instruction modified, this modifier
+     * specifies <b>B</b> case for a <b>[S|B]</b> or a <b>\<burst></b> for a
+     * <b>\<single|burst|periph></b>.
+     */
+    ALT_DMA_PROGRAM_INST_MOD_BURST,
+
+    /*!
+     * This DMA instruction modifier specifies a <b>\<periph></b> for a
+     * <b>\<single|burst|periph></b>.
+     */
+    ALT_DMA_PROGRAM_INST_MOD_PERIPH
+}
+ALT_DMA_PROGRAM_INST_MOD_t;
+
+/*!
+ * This function initializes a system memory buffer for use as a DMA microcode
+ * program buffer. This should be the first API call made on the program
+ * buffer type.
+ *
+ * \param       pgm
+ *              A pointer to a DMA program buffer structure.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     Details about error status code
+ */
+ALT_STATUS_CODE alt_dma_program_init(ALT_DMA_PROGRAM_t * pgm);
+
+/*!
+ * This function verifies that the DMA microcode program buffer is no longer
+ * in use and performs any needed uninitialization steps.
+ *
+ * \param       pgm
+ *              A pointer to a DMA program buffer structure.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     Details about error status code
+ */
+ALT_STATUS_CODE alt_dma_program_uninit(ALT_DMA_PROGRAM_t * pgm);
+
+/*!
+ * This function clears the existing DMA microcode program in the given
+ * program buffer.
+ *
+ * \param       pgm
+ *              A pointer to a DMA program buffer structure.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     Details about error status code.
+ */
+ALT_STATUS_CODE alt_dma_program_clear(ALT_DMA_PROGRAM_t * pgm);
+
+/*!
+ * This function validate that the given DMA microcode program buffer contains
+ * a well formed program. If caches are enabled, the program buffer contents
+ * will be cleaned to RAM.
+ *
+ * \param       pgm
+ *              A pointer to a DMA program buffer structure.
+ *
+ * \retval      ALT_E_SUCCESS   The given program is well formed.
+ * \retval      ALT_E_ERROR     The given program is not well formed.
+ * \retval      ALT_E_TMO       The cache operation timed out.
+ */
+ALT_STATUS_CODE alt_dma_program_validate(const ALT_DMA_PROGRAM_t * pgm);
+
+/*!
+ * This function reports the number bytes incremented for the register
+ * specified. The purpose is to determine the progress of an ongoing DMA
+ * transfer.
+ *
+ * It is implemented by calculating the difference of the programmed SAR or DAR
+ * with the current channel SAR or DAR register value.
+ *
+ * \param       pgm
+ *              A pointer to a DMA program buffer structure.
+ *
+ * \param       channel
+ *              The channel that the program is running on.
+ *
+ * \param       reg
+ *              Register to change the value for. Valid for only
+ *              ALT_DMA_PROGRAM_REG_SAR and ALT_DMA_PROGRAM_REG_DAR.
+ *
+ * \param       current
+ *              The current snapshot value of the register read from the DMA
+ *              channel.
+ *
+ * \param       progress
+ *              [out] A pointer to a memory location that will be used to store
+ *              the number of bytes transfered.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     Details about error status code.
+ * \retval      ALT_E_BAD_ARG   The specified channel is invalid, the specified
+ *                              register is invalid, or the DMAMOV for the
+ *                              specified register has not yet been assembled
+ *                              in the current program buffer.
+ */
+ALT_STATUS_CODE alt_dma_program_progress_reg(ALT_DMA_PROGRAM_t * pgm,
+                                             ALT_DMA_PROGRAM_REG_t reg,
+                                             uint32_t current, uint32_t * progress);
+
+/*!
+ * This function updates a pre-existing DMAMOV value affecting the SAR or DAR
+ * registers. This allows for pre-assembled programs that can be used on
+ * different source and destination addresses.
+ *
+ * \param       pgm
+ *              A pointer to a DMA program buffer structure.
+ *
+ * \param       reg
+ *              Register to change the value for. Valid for only
+ *              ALT_DMA_PROGRAM_REG_SAR and ALT_DMA_PROGRAM_REG_DAR.
+ *
+ * \param       val
+ *              The value to update to.
+ *
+ * \retval      ALT_E_SUCCESS   The operation was successful.
+ * \retval      ALT_E_ERROR     Details about error status code.
+ * \retval      ALT_E_BAD_ARG   The specified register is invalid or the DMAMOV
+ *                              for the specified register has not yet been
+ *                              assembled in the current program buffer.
+ */
+ALT_STATUS_CODE alt_dma_program_update_reg(ALT_DMA_PROGRAM_t * pgm,
+                                           ALT_DMA_PROGRAM_REG_t reg, uint32_t val);
+
+/*!
+ */
+
+/*!
+ * Assembles a DMAADDH (Add Halfword) instruction into the microcode program
+ * buffer. This instruction uses 3 bytes of buffer space.
+ *
+ * \param       pgm
+ *              The DMA program buffer to contain the assembled instruction.
+ *
+ * \param       addr_reg
+ *              The channel address register (ALT_DMA_PROGRAM_REG_DAR or
+ *              ALT_DMA_PROGRAM_REG_SAR) to add the value to.
+ *
+ * \param       val
+ *              The 16-bit unsigned value to add to the channel address
+ *              register.
+ *
+ * \retval      ALT_E_SUCCESS       Successful instruction assembly status.
+ * \retval      ALT_E_DMA_BUF_OVF   DMA program buffer overflow.
+ * \retval      ALT_E_BAD_ARG       Invalid channel register specified.
+ */
+// Assembler Syntax: DMAADDH <address_register>, <16-bit immediate>
+ALT_STATUS_CODE alt_dma_program_DMAADDH(ALT_DMA_PROGRAM_t * pgm,
+                                        ALT_DMA_PROGRAM_REG_t addr_reg, uint16_t val);
+
+/*!
+ * Assembles a DMAADNH (Add Negative Halfword) instruction into the microcode
+ * program buffer. This instruction uses 3 bytes of buffer space.
+ *
+ * \param       pgm
+ *              The DMA programm buffer to contain the assembled instruction.
+ *
+ * \param       addr_reg
+ *              The channel address register (ALT_DMA_PROGRAM_REG_DAR or
+ *              ALT_DMA_PROGRAM_REG_SAR) to add the value to.
+ *
+ * \param       val
+ *              The 16-bit unsigned value to add to the channel address
+ *              register.
+ *
+ * \retval      ALT_E_SUCCESS       Successful instruction assembly status.
+ * \retval      ALT_E_DMA_BUF_OVF   DMA program buffer overflow.
+ * \retval      ALT_E_BAD_ARG       Invalid channel register specified.
+ */
+// Assembler Syntax: DMAADNH <address_register>, <16-bit immediate>
+ALT_STATUS_CODE alt_dma_program_DMAADNH(ALT_DMA_PROGRAM_t * pgm,
+                                        ALT_DMA_PROGRAM_REG_t addr_reg, uint16_t val);
+
+/*!
+ * Assembles a DMAEND (End) instruction into the microcode program buffer.
+ * This instruction uses 1 byte of buffer space.
+ *
+ * \param       pgm
+ *              The DMA programm buffer to contain the assembled instruction.
+ *
+ * \retval      ALT_E_SUCCESS       Successful instruction assembly status.
+ * \retval      ALT_E_DMA_BUF_OVF   DMA program buffer overflow.
+ */
+// Assembler Syntax: DMAEND
+ALT_STATUS_CODE alt_dma_program_DMAEND(ALT_DMA_PROGRAM_t * pgm);
+
+/*!
+ * Assembles a DMAFLUSHP (Flush Peripheral) instruction into the microcode
+ * program buffer. This instruction uses 2 bytes of buffer space.
+ *
+ * \param       pgm
+ *              The DMA programm buffer to contain the assembled instruction.
+ *
+ * \param       periph
+ *              The peripheral to flush.
+ *
+ * \retval      ALT_E_SUCCESS       Successful instruction assembly status.
+ * \retval      ALT_E_DMA_BUF_OVF   DMA program buffer overflow.
+ * \retval      ALT_E_BAD_ARG       Invalid peripheral specified.
+ */
+// Assembler Syntax: DMAFLUSHP <peripheral>
+ALT_STATUS_CODE alt_dma_program_DMAFLUSHP(ALT_DMA_PROGRAM_t * pgm,
+                                          ALT_DMA_PERIPH_t periph);
+
+/*!
+ * Assembles a DMAGO (Go) instruction into the microcode program buffer. This
+ * instruction uses 6 bytes of buffer space.
+ *
+ * \param       pgm
+ *              The DMA programm buffer to contain the assembled instruction.
+ *
+ * \param       channel
+ *              The stopped channel to act upon.
+ *
+ * \param       val
+ *              The value to write to the channel program counter register.
+ *
+ * \param       sec
+ *              The security state for the operation.
+ *
+ * \retval      ALT_E_SUCCESS       Successful instruction assembly status.
+ * \retval      ALT_E_DMA_BUF_OVF   DMA program buffer overflow.
+ * \retval      ALT_E_BAD_ARG       Invalid channel or security specified.
+ */
+// Assembler Syntax: DMAGO <channel_number>, <32-bit_immediate> [, ns]
+ALT_STATUS_CODE alt_dma_program_DMAGO(ALT_DMA_PROGRAM_t * pgm,
+                                      ALT_DMA_CHANNEL_t channel, uint32_t val,
+                                      ALT_DMA_SECURITY_t sec);
+
+/*!
+ * Assembles a DMAKILL (Kill) instruction into the microcode program buffer.
+ * This instruction uses 1 byte of buffer space.
+ *
+ * \param       pgm
+ *              The DMA programm buffer to contain the assembled instruction.
+ *
+ * \retval      ALT_E_SUCCESS       Successful instruction assembly status.
+ * \retval      ALT_E_DMA_BUF_OVF   DMA program buffer overflow.
+ */
+// Assembler Syntax: DMAKILL
+ALT_STATUS_CODE alt_dma_program_DMAKILL(ALT_DMA_PROGRAM_t * pgm);
+
+/*!
+ * Assembles a DMALD (Load) instruction into the microcode program buffer.
+ * This instruction uses 1 byte of buffer space.
+ *
+ * \param       pgm
+ *              The DMA programm buffer to contain the assembled instruction.
+ *
+ * \param       mod
+ *              The program instruction modifier for the type of transfer.
+ *              Only ALT_DMA_PROGRAM_INST_MOD_SINGLE and 
+ *              ALT_DMA_PROGRAM_INST_MOD_BURST are valid options.
+ *
+ * \retval      ALT_E_SUCCESS       Successful instruction assembly status.
+ * \retval      ALT_E_DMA_BUF_OVF   DMA program buffer overflow.
+ * \retval      ALT_E_BAD_ARG       Invalid instruction modifier specified.
+ */
+// Assembler Syntax: DMALD[S|B]
+ALT_STATUS_CODE alt_dma_program_DMALD(ALT_DMA_PROGRAM_t * pgm,
+                                      ALT_DMA_PROGRAM_INST_MOD_t mod);
+
+/*!
+ * Assembles a DMALDP (Load and notify Peripheral) instruction into the
+ * microcode program buffer. This instruction uses 2 bytes of buffer space.
+ *
+ * \param       pgm
+ *              The DMA programm buffer to contain the assembled instruction.
+ *
+ * \param       mod
+ *              The program instruction modifier for the type of transfer.
+ *              Only ALT_DMA_PROGRAM_INST_MOD_SINGLE and 
+ *              ALT_DMA_PROGRAM_INST_MOD_BURST are valid options.
+ *
+ * \param       periph
+ *              The peripheral to notify.
+ *
+ * \retval      ALT_E_SUCCESS       Successful instruction assembly status.
+ * \retval      ALT_E_DMA_BUF_OVF   DMA program buffer overflow.
+ * \retval      ALT_E_BAD_ARG       Invalid instruction modifier or peripheral
+ *                                  specified.
+ */
+// Assembler Syntax: DMALDP<S|B> <peripheral>
+ALT_STATUS_CODE alt_dma_program_DMALDP(ALT_DMA_PROGRAM_t * pgm,
+                                       ALT_DMA_PROGRAM_INST_MOD_t mod, ALT_DMA_PERIPH_t periph);
+
+/*!
+ * Assembles a DMALP (Loop) instruction into the microcode program buffer.
+ * This instruction uses 2 bytes of buffer space.
+ *
+ * \param       pgm
+ *              The DMA programm buffer to contain the assembled instruction.
+ *
+ * \param       iterations
+ *              The number of iterations to run for. Valid values are 1 - 256.
+ *
+ * \retval      ALT_E_SUCCESS       Successful instruction assembly status.
+ * \retval      ALT_E_DMA_BUF_OVF   DMA program buffer overflow.
+ * \retval      ALT_E_BAD_ARG       Invalid iterations specified.
+ * \retval      ALT_E_BAD_OPERATION All loop registers are in use.
+ */
+// Assembler Syntax: DMALP [<LC0>|<LC1>] <loop_iterations>
+ALT_STATUS_CODE alt_dma_program_DMALP(ALT_DMA_PROGRAM_t * pgm,
+                                      uint32_t iterations);
+
+/*!
+ * Assembles a DMALPEND (Loop End) instruction into the microcode program
+ * buffer. This instruction uses 2 bytes of buffer space.
+ *
+ * \param       pgm
+ *              The DMA programm buffer to contain the assembled instruction.
+ *
+ * \param       mod
+ *              The program instruction modifier for the loop terminator. Only
+ *              ALT_DMA_PROGRAM_INST_MOD_NONE, ALT_DMA_PROGRAM_INST_MOD_SINGLE
+ *              and ALT_DMA_PROGRAM_INST_MOD_BURST are valid options.
+ *
+ * \retval      ALT_E_SUCCESS       Successful instruction assembly status.
+ * \retval      ALT_E_DMA_BUF_OVF   DMA program buffer overflow.
+ * \retval      ALT_E_BAD_ARG       Invalid instruction modifier specified.
+ * \retval      ALT_E_ARG_RANGE     Loop size is too large to be supported.
+ * \retval      ALT_E_BAD_OPERATION A valid DMALP or DMALPFE was not added to
+ *                                  the program buffer before adding this
+ *                                  DMALPEND instruction.
+ */
+// Assembler Syntax: DMALPEND[S|B]
+ALT_STATUS_CODE alt_dma_program_DMALPEND(ALT_DMA_PROGRAM_t * pgm,
+                                         ALT_DMA_PROGRAM_INST_MOD_t mod);
+
+/*!
+ * Assembles a DMALPFE (Loop Forever) instruction into the microcode program
+ * buffer. No instruction is added to the buffer but a previous DMALPEND to
+ * create an infinite loop.
+ *
+ * \param       pgm
+ *              The DMA programm buffer to contain the assembled instruction.
+ *
+ * \retval      ALT_E_SUCCESS       Successful instruction assembly status.
+ * \retval      ALT_E_DMA_BUF_OVF   DMA program buffer overflow.
+ */
+// Assembler Syntax: DMALPFE
+ALT_STATUS_CODE alt_dma_program_DMALPFE(ALT_DMA_PROGRAM_t * pgm);
+
+/*!
+ * Assembles a DMAMOV (Move) instruction into the microcode program buffer.
+ * This instruction uses 6 bytes of buffer space.
+ *
+ * \param       pgm
+ *              The DMA programm buffer to contain the assembled instruction.
+ *
+ * \param       chan_reg
+ *              The channel non-looping register (ALT_DMA_PROGRAM_REG_SAR,
+ *              ALT_DMA_PROGRAM_REG_DAR or ALT_DMA_PROGRAM_REG_CCR) to copy
+ *              the value to.
+ *
+ * \param       val
+ *              The value to write to the specified register.
+ *
+ * \retval      ALT_E_SUCCESS       Successful instruction assembly status.
+ * \retval      ALT_E_DMA_BUF_OVF   DMA program buffer overflow.
+ * \retval      ALT_E_BAD_ARG       Invalid channel register specified.
+ */
+// Assembler Syntax: DMAMOV <destination_register>, <32-bit_immediate>
+ALT_STATUS_CODE alt_dma_program_DMAMOV(ALT_DMA_PROGRAM_t * pgm,
+                                       ALT_DMA_PROGRAM_REG_t chan_reg, uint32_t val);
+
+/*!
+ * Assembles a DMANOP (No Operation) instruction into the microcode program
+ * buffer. This instruction uses 1 byte of buffer space.
+ *
+ * \param       pgm
+ *              The DMA programm buffer to contain the assembled instruction.
+ *
+ * \retval      ALT_E_SUCCESS       Successful instruction assembly status.
+ * \retval      ALT_E_DMA_BUF_OVF   DMA program buffer overflow.
+ */
+// Assembler Syntax: DMANOP
+ALT_STATUS_CODE alt_dma_program_DMANOP(ALT_DMA_PROGRAM_t * pgm);
+
+/*!
+ * Assembles a DMARMB (Read Memory Barrier) instruction into the microcode
+ * program buffer. This instruction uses 1 byte of buffer space.
+ *
+ * \param       pgm
+ *              The DMA programm buffer to contain the assembled instruction.
+ *
+ * \retval      ALT_E_SUCCESS       Successful instruction assembly status.
+ * \retval      ALT_E_DMA_BUF_OVF   DMA program buffer overflow.
+ */
+// Assembler Syntax: DMARMB
+ALT_STATUS_CODE alt_dma_program_DMARMB(ALT_DMA_PROGRAM_t * pgm);
+
+/*!
+ * Assembles a DMASEV (Send Event) instruction into the microcode program
+ * buffer. This instruction uses 2 byte of buffer space.
+ *
+ * \param       pgm
+ *              The DMA programm buffer to contain the assembled instruction.
+ *
+ * \param       evt
+ *              The event to send.
+ *
+ * \retval      ALT_E_SUCCESS       Successful instruction assembly status.
+ * \retval      ALT_E_DMA_BUF_OVF   DMA program buffer overflow.
+ * \retval      ALT_E_BAD_ARG       Invalid event specified.
+ */
+// Assembler Syntax: DMASEV <event_num>
+ALT_STATUS_CODE alt_dma_program_DMASEV(ALT_DMA_PROGRAM_t * pgm,
+                                       ALT_DMA_EVENT_t evt);
+
+/*!
+ * Assembles a DMAST (Store) instruction into the microcode program buffer.
+ * This instruction uses 1 byte of buffer space.
+ *
+ * \param       pgm
+ *              The DMA programm buffer to contain the assembled instruction.
+ *
+ * \param       mod
+ *              The program instruction modifier for the type of transfer.
+ *              Only ALT_DMA_PROGRAM_INST_MOD_SINGLE and 
+ *              ALT_DMA_PROGRAM_INST_MOD_BURST are valid options.
+ *
+ * \retval      ALT_E_SUCCESS       Successful instruction assembly status.
+ * \retval      ALT_E_DMA_BUF_OVF   DMA program buffer overflow.
+ */
+// Assembler Syntax: DMAST[S|B]
+ALT_STATUS_CODE alt_dma_program_DMAST(ALT_DMA_PROGRAM_t * pgm,
+                                      ALT_DMA_PROGRAM_INST_MOD_t mod);
+
+/*!
+ * Assembles a DMASTP (Store and notify Peripheral) instruction into the
+ * microcode program buffer. This instruction uses 2 bytes of buffer space.
+ *
+ * \param       pgm
+ *              The DMA programm buffer to contain the assembled instruction.
+ *
+ * \param       mod
+ *              The program instruction modifier for the type of transfer.
+ *              Only ALT_DMA_PROGRAM_INST_MOD_SINGLE and 
+ *              ALT_DMA_PROGRAM_INST_MOD_BURST are valid options.
+ *
+ * \param       periph
+ *              The peripheral to notify.
+ *
+ * \retval      ALT_E_SUCCESS       Successful instruction assembly status.
+ * \retval      ALT_E_DMA_BUF_OVF   DMA program buffer overflow.
+ * \retval      ALT_E_BAD_ARG       Invalid instruction modifier or peripheral
+ *                                  specified.
+ */
+// Assembler Syntax: DMASTP<S|B> <peripheral>
+ALT_STATUS_CODE alt_dma_program_DMASTP(ALT_DMA_PROGRAM_t * pgm,
+                                       ALT_DMA_PROGRAM_INST_MOD_t mod, ALT_DMA_PERIPH_t periph);
+
+/*!
+ * Assembles a DMASTZ (Store Zero) instruction into the microcode program
+ * buffer. This instruction uses 1 byte of buffer space.
+ *
+ * \param       pgm
+ *              The DMA programm buffer to contain the assembled instruction.
+ *
+ * \retval      ALT_E_SUCCESS       Successful instruction assembly status.
+ * \retval      ALT_E_DMA_BUF_OVF   DMA program buffer overflow.
+ */
+// Assembler Syntax: DMASTZ
+ALT_STATUS_CODE alt_dma_program_DMASTZ(ALT_DMA_PROGRAM_t * pgm);
+
+/*!
+ * Assembles a DMAWFE (Wait For Event) instruction into the microcode program
+ * buffer. This instruction uses 2 byte of buffer space.
+ *
+ * \param       pgm
+ *              The DMA programm buffer to contain the assembled instruction.
+ *
+ * \param       evt
+ *              The event to wait for.
+ *
+ * \param       invalid
+ *              If invalid is set to true, the instruction will be configured
+ *              to invalidate the instruction cache for the current DMA
+ *              thread.
+ *
+ * \retval      ALT_E_SUCCESS       Successful instruction assembly status.
+ * \retval      ALT_E_DMA_BUF_OVF   DMA program buffer overflow.
+ * \retval      ALT_E_BAD_ARG       Invalid event specified.
+ */
+// Assembler Syntax: DMAWFE <event_num>[, invalid]
+ALT_STATUS_CODE alt_dma_program_DMAWFE(ALT_DMA_PROGRAM_t * pgm,
+                                       ALT_DMA_EVENT_t evt, bool invalid);
+
+/*!
+ * Assembles a DMAWFP (Wait for Peripheral) instruction into the microcode
+ * program buffer. This instruction uses 2 bytes of buffer space.
+ *
+ * \param       pgm
+ *              The DMA programm buffer to contain the assembled instruction.
+ *
+ * \param       periph
+ *              The peripheral to wait on.
+ *
+ * \param       mod
+ *              The program instruction modifier for the type of transfer.
+ *              Only ALT_DMA_PROGRAM_INST_MOD_SINGLE,
+ *              ALT_DMA_PROGRAM_INST_MOD_BURST, or
+ *              ALT_DMA_PROGRAM_INST_MOD_PERIPH are valid options.
+ *
+ * \retval      ALT_E_SUCCESS       Successful instruction assembly status.
+ * \retval      ALT_E_DMA_BUF_OVF   DMA program buffer overflow.
+ * \retval      ALT_E_BAD_ARG       Invalid peripheral or instruction modifier
+ *                                  specified.
+ */
+// Assembler Syntax: DMAWFP <peripheral>, <single|burst|periph>
+ALT_STATUS_CODE alt_dma_program_DMAWFP(ALT_DMA_PROGRAM_t * pgm,
+                                       ALT_DMA_PERIPH_t periph, ALT_DMA_PROGRAM_INST_MOD_t mod);
+
+/*!
+ * Assembles a DMAWMB (Write Memory Barrier) instruction into the microcode
+ * program buffer. This instruction uses 1 byte of buffer space.
+ *
+ * \param       pgm
+ *              The DMA programm buffer to contain the assembled instruction.
+ *
+ * \retval      ALT_E_SUCCESS       Successful instruction assembly status.
+ * \retval      ALT_E_DMA_BUF_OVF   DMA program buffer overflow.
+ */
+// Assembler Syntax: DMAWMB
+ALT_STATUS_CODE alt_dma_program_DMAWMB(ALT_DMA_PROGRAM_t * pgm);
+
+/*!
+ * \addtogroup DMA_CCR Support for DMAMOV CCR
+ *
+ * The ALT_DMA_CCR_OPT_* macro definitions are defined here to facilitate the
+ * dynamic microcode programming of the assembler directive:
+\verbatim
+
+DMAMOV CCR, [SB<1-16>] [SS<8|16|32|64|128>] [SA<I|F>]
+            [SP<imm3>] [SC<imm4>]
+            [DB<1-16>] [DS<8|16|32|64|128>] [DA<I|F>]
+            [DP<imm3>] [DC<imm4>]
+            [ES<8|16|32|64|128>]
+
+\endverbatim
+* with a DMAMOV instruction (see: alt_dma_program_DMAMOV()).
+*
+* For example the assembler directive:
+\verbatim
+DMAMOV CCR SB1 SS32 DB1 DS32
+\endverbatim
+* would be dynamically programmed with the following API call:
+\verbatim
+alt_dma_program_DMAMOV( pgm,
+                        ALT_DMA_PROGRAM_REG_CCR,
+                        (   ALT_DMA_CCR_OPT_SB1
+                          | ALT_DMA_CCR_OPT_SS32
+                          | ALT_DMA_CCR_OPT_SA_DEFAULT
+                          | ALT_DMA_CCR_OPT_SP_DEFAULT
+                          | ALT_DMA_CCR_OPT_SC_DEFAULT
+                          | ALT_DMA_CCR_OPT_DB1
+                          | ALT_DMA_CCR_OPT_DS32
+                          | ALT_DMA_CCR_OPT_DA_DEFAULT
+                          | ALT_DMA_CCR_OPT_DP_DEFAULT
+                          | ALT_DMA_CCR_OPT_DC_DEFAULT
+                          | ALT_DMA_CCR_OPT_ES8
+                        )
+                      );
+\endverbatim
+*
+* Each CCR option category should be specified regardless of whether it
+* specifies a custom value or the normal default value (i.e. an
+* ALT_DMA_CCR_OPT_*_DEFAULT.
+*
+* @{
+*/
+
+/*
+ * Source Address {Fixed,Incrementing}
+ */
+/*! Source Address Fixed address burst. */
+#define ALT_DMA_CCR_OPT_SAF         (0 << 0)
+/*! Source Address Incrementing address burst. */
+#define ALT_DMA_CCR_OPT_SAI         (1 << 0)
+/*! Source Address Default value. */
+#define ALT_DMA_CCR_OPT_SA_DEFAULT  ALT_DMA_CCR_OPT_SAI
+
+/*
+ * Source burst Size (in bits)
+ */
+/*! Source burst Size of 8 bits. */
+#define ALT_DMA_CCR_OPT_SS8         (0 << 1)
+/*! Source burst Size of 16 bits. */
+#define ALT_DMA_CCR_OPT_SS16        (1 << 1)
+/*! Source burst Size of 32 bits. */
+#define ALT_DMA_CCR_OPT_SS32        (2 << 1)
+/*! Source burst Size of 64 bits. */
+#define ALT_DMA_CCR_OPT_SS64        (3 << 1)
+/*! Source burst Size of 128 bits. */
+#define ALT_DMA_CCR_OPT_SS128       (4 << 1)
+/*! Source burst Size default bits. */
+#define ALT_DMA_CCR_OPT_SS_DEFAULT  ALT_DMA_CCR_OPT_SS8
+
+/*
+ * Source burst Length (in transfer(s))
+ */
+/*! Source Burst length of 1 transfer. */
+#define ALT_DMA_CCR_OPT_SB1         (0x0 << 4)
+/*! Source Burst length of 2 transfers. */
+#define ALT_DMA_CCR_OPT_SB2         (0x1 << 4)
+/*! Source Burst length of 3 transfers. */
+#define ALT_DMA_CCR_OPT_SB3         (0x2 << 4)
+/*! Source Burst length of 4 transfers. */
+#define ALT_DMA_CCR_OPT_SB4         (0x3 << 4)
+/*! Source Burst length of 5 transfers. */
+#define ALT_DMA_CCR_OPT_SB5         (0x4 << 4)
+/*! Source Burst length of 6 transfers. */
+#define ALT_DMA_CCR_OPT_SB6         (0x5 << 4)
+/*! Source Burst length of 7 transfers. */
+#define ALT_DMA_CCR_OPT_SB7         (0x6 << 4)
+/*! Source Burst length of 8 transfers. */
+#define ALT_DMA_CCR_OPT_SB8         (0x7 << 4)
+/*! Source Burst length of 9 transfers. */
+#define ALT_DMA_CCR_OPT_SB9         (0x8 << 4)
+/*! Source Burst length of 10 transfers. */
+#define ALT_DMA_CCR_OPT_SB10        (0x9 << 4)
+/*! Source Burst length of 11 transfers. */
+#define ALT_DMA_CCR_OPT_SB11        (0xa << 4)
+/*! Source Burst length of 12 transfers. */
+#define ALT_DMA_CCR_OPT_SB12        (0xb << 4)
+/*! Source Burst length of 13 transfers. */
+#define ALT_DMA_CCR_OPT_SB13        (0xc << 4)
+/*! Source Burst length of 14 transfers. */
+#define ALT_DMA_CCR_OPT_SB14        (0xd << 4)
+/*! Source Burst length of 15 transfers. */
+#define ALT_DMA_CCR_OPT_SB15        (0xe << 4)
+/*! Source Burst length of 16 transfers. */
+#define ALT_DMA_CCR_OPT_SB16        (0xf << 4)
+/*! Source Burst length default transfers. */
+#define ALT_DMA_CCR_OPT_SB_DEFAULT  ALT_DMA_CCR_OPT_SB1
+
+/*
+ * Source Protection
+ */
+/*! Source Protection bits for AXI bus ARPROT[2:0]. */
+#define ALT_DMA_CCR_OPT_SP(imm3)    ((imm3) << 8)
+/*! Source Protection bits default value. */
+#define ALT_DMA_CCR_OPT_SP_DEFAULT  ALT_DMA_CCR_OPT_SP(0)
+
+/*
+ * Source cache
+ */
+/*! Source Cache bits for AXI bus ARCACHE[2:0]. */
+#define ALT_DMA_CCR_OPT_SC(imm4)    ((imm4) << 11)
+/*! Source Cache bits default value. */
+#define ALT_DMA_CCR_OPT_SC_DEFAULT  ALT_DMA_CCR_OPT_SC(0)
+
+/*
+ * Destination Address {Fixed,Incrementing}
+ */
+/*! Destination Address Fixed address burst. */
+#define ALT_DMA_CCR_OPT_DAF         (0 << 14)
+/*! Destination Address Incrementing address burst. */
+#define ALT_DMA_CCR_OPT_DAI         (1 << 14)
+/*! Destination Address Default value. */
+#define ALT_DMA_CCR_OPT_DA_DEFAULT  ALT_DMA_CCR_OPT_DAI
+
+/*
+ * Destination burst Size (in bits)
+ */
+/*! Destination burst Size of 8 bits. */
+#define ALT_DMA_CCR_OPT_DS8         (0 << 15)
+/*! Destination burst Size of 16 bits. */
+#define ALT_DMA_CCR_OPT_DS16        (1 << 15)
+/*! Destination burst Size of 32 bits. */
+#define ALT_DMA_CCR_OPT_DS32        (2 << 15)
+/*! Destination burst Size of 64 bits. */
+#define ALT_DMA_CCR_OPT_DS64        (3 << 15)
+/*! Destination burst Size of 128 bits. */
+#define ALT_DMA_CCR_OPT_DS128       (4 << 15)
+/*! Destination burst Size default bits. */
+#define ALT_DMA_CCR_OPT_DS_DEFAULT  ALT_DMA_CCR_OPT_DS8
+
+/*
+ * Destination Burst length (in transfer(s))
+ */
+/*! Destination Burst length of 1 transfer. */
+#define ALT_DMA_CCR_OPT_DB1         (0x0 << 18)
+/*! Destination Burst length of 2 transfers. */
+#define ALT_DMA_CCR_OPT_DB2         (0x1 << 18)
+/*! Destination Burst length of 3 transfers. */
+#define ALT_DMA_CCR_OPT_DB3         (0x2 << 18)
+/*! Destination Burst length of 4 transfers. */
+#define ALT_DMA_CCR_OPT_DB4         (0x3 << 18)
+/*! Destination Burst length of 5 transfers. */
+#define ALT_DMA_CCR_OPT_DB5         (0x4 << 18)
+/*! Destination Burst length of 6 transfers. */
+#define ALT_DMA_CCR_OPT_DB6         (0x5 << 18)
+/*! Destination Burst length of 7 transfers. */
+#define ALT_DMA_CCR_OPT_DB7         (0x6 << 18)
+/*! Destination Burst length of 8 transfers. */
+#define ALT_DMA_CCR_OPT_DB8         (0x7 << 18)
+/*! Destination Burst length of 9 transfers. */
+#define ALT_DMA_CCR_OPT_DB9         (0x8 << 18)
+/*! Destination Burst length of 10 transfers. */
+#define ALT_DMA_CCR_OPT_DB10        (0x9 << 18)
+/*! Destination Burst length of 11 transfers. */
+#define ALT_DMA_CCR_OPT_DB11        (0xa << 18)
+/*! Destination Burst length of 12 transfers. */
+#define ALT_DMA_CCR_OPT_DB12        (0xb << 18)
+/*! Destination Burst length of 13 transfers. */
+#define ALT_DMA_CCR_OPT_DB13        (0xc << 18)
+/*! Destination Burst length of 14 transfers. */
+#define ALT_DMA_CCR_OPT_DB14        (0xd << 18)
+/*! Destination Burst length of 15 transfers. */
+#define ALT_DMA_CCR_OPT_DB15        (0xe << 18)
+/*! Destination Burst length of 16 transfers. */
+#define ALT_DMA_CCR_OPT_DB16        (0xf << 18)
+/*! Destination Burst length default transfers. */
+#define ALT_DMA_CCR_OPT_DB_DEFAULT  ALT_DMA_CCR_OPT_DB1
+
+/*
+ * Destination Protection
+ */
+/*! Destination Protection bits for AXI bus AWPROT[2:0]. */
+#define ALT_DMA_CCR_OPT_DP(imm3)    ((imm3) << 22)
+/*! Destination Protection bits default value. */
+#define ALT_DMA_CCR_OPT_DP_DEFAULT  ALT_DMA_CCR_OPT_DP(0)
+
+/*
+ * Destination Cache
+ */
+/*! Destination Cache bits for AXI bus AWCACHE[3,1:0]. */
+#define ALT_DMA_CCR_OPT_DC(imm4)    ((imm4) << 25)
+/*! Destination Cache bits default value. */
+#define ALT_DMA_CCR_OPT_DC_DEFAULT  ALT_DMA_CCR_OPT_DC(0)
+
+/*
+ * Endian Swap size (in bits)
+ */
+/*! Endian Swap: No swap, 8-bit data. */
+#define ALT_DMA_CCR_OPT_ES8         (0 << 28)
+/*! Endian Swap: Swap bytes within 16-bit data. */
+#define ALT_DMA_CCR_OPT_ES16        (1 << 28)
+/*! Endian Swap: Swap bytes within 32-bit data. */
+#define ALT_DMA_CCR_OPT_ES32        (2 << 28)
+/*! Endian Swap: Swap bytes within 64-bit data. */
+#define ALT_DMA_CCR_OPT_ES64        (3 << 28)
+/*! Endian Swap: Swap bytes within 128-bit data. */
+#define ALT_DMA_CCR_OPT_ES128       (4 << 28)
+/*! Endian Swap: Default byte swap. */
+#define ALT_DMA_CCR_OPT_ES_DEFAULT  ALT_DMA_CCR_OPT_ES8
+
+/*! Default CCR register options for a DMAMOV CCR assembler directive. */
+#define ALT_DMA_CCR_OPT_DEFAULT \
+    (ALT_DMA_CCR_OPT_SB1 | ALT_DMA_CCR_OPT_SS8 | ALT_DMA_CCR_OPT_SAI | \
+     ALT_DMA_CCR_OPT_SP(0) | ALT_DMA_CCR_OPT_SC(0) | \
+     ALT_DMA_CCR_OPT_DB1 | ALT_DMA_CCR_OPT_DS8 | ALT_DMA_CCR_OPT_DAI | \
+     ALT_DMA_CCR_OPT_DP(0) | ALT_DMA_CCR_OPT_DC(0) | \
+     ALT_DMA_CCR_OPT_ES8)
+
+/*!
+ * @}
+ */
+
+/*!
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif  /* __cplusplus */
+
+#endif /* __ALT_DMA_PROGRAM_H__ */
diff --git a/c/src/lib/libbsp/arm/altera-cyclone-v/hwlib/include/alt_qspi.h b/c/src/lib/libbsp/arm/altera-cyclone-v/hwlib/include/alt_qspi.h
new file mode 100644
index 0000000..d09ccf2
--- /dev/null
+++ b/c/src/lib/libbsp/arm/altera-cyclone-v/hwlib/include/alt_qspi.h
@@ -0,0 +1,1535 @@
+/******************************************************************************
+*
+* Copyright 2013 Altera Corporation. All Rights Reserved.
+* 
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+* 
+* 1. Redistributions of source code must retain the above copyright notice,
+* this list of conditions and the following disclaimer.
+* 
+* 2. Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following disclaimer in the documentation
+* and/or other materials provided with the distribution.
+* 
+* 3. The name of the author may not be used to endorse or promote products
+* derived from this software without specific prior written permission.
+* 
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY EXPRESS OR
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED. IN NO
+* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+* OF SUCH DAMAGE.
+* 
+******************************************************************************/
+
+/******************************************************************************
+* 
+* !!!! Customer Be Aware, Exception!!!
+*
+* 1. Qspi Direct Access Mode is not working!
+*
+*    This is because the qspi flash memory installed on our DevKit board, Micro 
+*    part N25Q00xx, 8 Gb, is not completely compatible with our embedded Synopsis 
+*    QSPI controller IP. Therefore there is no viable direct access code offered
+*    in the lib.  All the memory rea/write functionality is offered with indirect
+*    access only.   
+*
+*    Should you install a different flash memory part in your custom board, and 
+*    wondering wether direct access mode works, please contact with us.
+* 
+******************************************************************************/
+
+/*! \file
+ *  Altera - QSPI Flash Controller Module
+ */
+
+#ifndef __ALT_QSPI_H__
+#define __ALT_QSPI_H__
+
+#include "hwlib.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif  /* __cplusplus */
+
+/******************************************************************************/
+/*! \addtogroup ALT_QSPI QSPI Flash Controller Module
+ *
+ * This module defines a low level driver API for the hardware processor system
+ * (HPS) quad serial peripheral interface (QSPI) flash controller for access to
+ * serial NOR flash devices. The quad SPI flash controller supports standard SPI
+ * flash devices as well as high-performance dual and quad SPI flash
+ * devices.
+ *
+ * @{
+ */
+
+/******************************************************************************/
+/*! \addtogroup ALT_QSPI_CSR General Control and Status Functions
+ *
+ * The declarations and functions in this group provide general purpose control
+ * and status functions for the QSPI Flash Controller.
+ *
+ * @{
+ */
+
+/******************************************************************************/
+/*!
+ * Initialize the QSPI flash controller for use.
+ *
+ * \internal
+ * Implementation Notes:
+ *  * The QSPI Controller has been designed to wake up in a state that is
+ *    suitable for performing basic reads and writes using the direct access
+ *    controller.
+ *  * Bring out of reset
+ *  * QSPI reference clock validation
+ *  * See Programmer's Guide, Configuring the QSPI Controller for use after
+ *    reset, in QSPI_FLASH_CTRL for full initialization details.
+ * \endinternal
+ *
+ * \retval      ALT_E_SUCCESS   Indicates successful completion.
+ * \retval      ALT_E_ERROR     Indicates an error occurred.
+ */
+ALT_STATUS_CODE alt_qspi_init(void);
+
+/******************************************************************************/
+/*!
+ * Uninitialize the QSPI flash controller.
+ *
+ * Uninitialize the QSPI flash controller by cancelling any indirect transfers
+ * in progress and putting the QSPI controller into reset.
+ *
+ * \retval      ALT_E_SUCCESS   Indicates successful completion.
+ * \retval      ALT_E_ERROR     Indicates an error occurred.
+ */
+ALT_STATUS_CODE alt_qspi_uninit(void);
+
+/******************************************************************************/
+/*!
+ * Disable the QSPI Controller.
+ *
+ * Disable the QSPI once the current transfer of the data word (FF_W) is
+ * complete. All output enables are inactive and all pins are set to input 
+ * mode.
+ *
+ * \retval      ALT_E_SUCCESS   Indicates successful completion.
+ * \retval      ALT_E_ERROR     Indicates an error occurred.
+ */
+ALT_STATUS_CODE alt_qspi_disable(void);
+
+/******************************************************************************/
+/*!
+ * Enable the QSPI Controller.
+ *
+ * \retval      ALT_E_SUCCESS   Indicates successful completion.
+ * \retval      ALT_E_ERROR     Indicates an error occurred.
+ */
+ALT_STATUS_CODE alt_qspi_enable(void);
+
+/******************************************************************************/
+/*!
+ * This type definition enumerates the interrupt status conditions for the QSPI
+ * controller.
+ *
+ * The enumerations serve as masks for the QSPI controller events that can be
+ * set when the designated conditions occur and the corresponding event is
+ * enabled.  When any of these event source conditions are true, the \b
+ * ALT_INT_INTERRUPT_QSPI_IRQ interrupt output is asserted high.
+ *
+ * Interrupt sources are cleared when software calls alt_qspi_int_clear(). The
+ * interrupt sources are individually maskable using alt_qspi_int_disable() and
+ * alt_qspi_int_enable().
+ */
+typedef enum ALT_QSPI_INT_STATUS_e
+{
+    /*!
+     * Mode fail M - indicates the voltage on pin n_ss_in is inconsistent with
+     * the SPI mode. Set = 1 if n_ss_in is low in master mode (multi-master
+     * contention). These conditions will clear the spi_enable bit and disable
+     * the SPI.
+     *  * 0 = no mode fault has been detected.
+     *  * 1 = a mode fault has occurred.
+     */
+    ALT_QSPI_INT_STATUS_MODE_FAIL         = (0x1 << 0),
+
+    /*!
+     * Underflow Detected.
+     *  * 0 = no underflow has been detected.
+     *  * 1 = underflow is detected and an attempt to transfer data is made
+     *        when the small TX FIFO is empty. This may occur when AHB write
+     *        data is being supplied too slowly to keep up with the requested
+     *        write operation.
+     */
+    ALT_QSPI_INT_STATUS_UFL               = (0x1 << 1),
+
+    /*!
+     * Controller has completed last triggered indirect operation.
+     */
+    ALT_QSPI_INT_STATUS_IDAC_OP_COMPLETE  = (0x1 << 2),
+
+    /*!
+     * Indirect operation was requested but could not be accepted. Two indirect
+     * operations already in storage.
+     */
+    ALT_QSPI_INT_STATUS_IDAC_OP_REJECT    = (0x1 << 3),
+
+    /*!
+     * Write to protected area was attempted and rejected.
+     */
+    ALT_QSPI_INT_STATUS_WR_PROT_VIOL      = (0x1 << 4),
+
+    /*!
+     * Illegal AHB Access Detected. AHB write wrapping bursts and the use of
+     * SPLIT/RETRY accesses will cause this interrupt to trigger.
+     */
+    ALT_QSPI_INT_STATUS_ILL_AHB_ACCESS    = (0x1 << 5),
+
+    /*!
+     * Indirect Transfer Watermark Level Breached.
+     */
+    ALT_QSPI_INT_STATUS_IDAC_WTRMK_TRIG   = (0x1 << 6),
+
+    /*!
+     * Receive Overflow. This should only occur in Legacy SPI mode.
+     *
+     * Set if an attempt is made to push the RX FIFO when it is full. This bit
+     * is reset only by a system reset and cleared only when this register is
+     * read. If a new push to the RX FIFO occurs coincident with a register read
+     * this flag will remain set.
+     *  * 0 = no overflow has been detected.
+     *  * 1 = an overflow has occurred.
+     */
+    ALT_QSPI_INT_STATUS_RX_OVF            = (0x1 << 7),
+
+    /*!
+     * Small TX FIFO not full (current FIFO status). Can be ignored in non-SPI
+     * legacy mode.
+     *  * 0 = FIFO has >= THRESHOLD entries.
+     *  * 1 = FIFO has < THRESHOLD entries.
+     */
+    ALT_QSPI_INT_STATUS_TX_FIFO_NOT_FULL  = (0x1 << 8),
+
+    /*!
+     * Small TX FIFO full (current FIFO status). Can be ignored in non-SPI
+     * legacy mode.
+     *  * 0 = FIFO is not full.
+     *  * 1 = FIFO is full.
+     */
+    ALT_QSPI_INT_STATUS_TX_FIFO_FULL      = (0x1 << 9),
+
+    /*!
+     * Small RX FIFO not empty (current FIFO status). Can be ignored in non-SPI
+     * legacy mode.
+     *  * 0 = FIFO has < RX THRESHOLD entries.
+     *  * 1 = FIFO has >= THRESHOLD entries.
+     */
+    ALT_QSPI_INT_STATUS_RX_FIFO_NOT_EMPTY = (0x1 << 10),
+
+    /*!
+     * Small RX FIFO full (current FIFO status). Can be ignored in non-SPI
+     * legacy mode.
+     *  * 0 = FIFO is not full.
+     *  * 1 = FIFO is full.
+     */
+    ALT_QSPI_INT_STATUS_RX_FIFO_FULL      = (0x1 << 11),
+
+    /*!
+     * Indirect Read partition of SRAM is full and unable to immediately
+     * complete indirect operation.
+     */
+    ALT_QSPI_INT_STATUS_IDAC_RD_FULL      = (0x1 << 12)
+
+} ALT_QSPI_INT_STATUS_t;
+
+/******************************************************************************/
+/*!
+ * Returns the QSPI controller interrupt status register value.
+ *
+ * This function returns the current value of the QSPI controller interrupt
+ * status register value which reflects the current QSPI controller status
+ * conditions.
+ *
+ * \returns     The current value of the QSPI controller interrupt status
+ *              register value which reflects the current QSPI controller status
+ *              conditions as defined by the \ref ALT_QSPI_INT_STATUS_t mask.
+ *              If the corresponding bit is set then the condition is asserted.
+ */
+uint32_t alt_qspi_int_status_get(void);
+
+/******************************************************************************/
+/*!
+ * Clears the specified QSPI controller interrupt status conditions identified
+ * in the mask.
+ *
+ * This function clears one or more of the status conditions as contributors to
+ * the \b ALT_INT_INTERRUPT_QSPI_IRQ interrupt signal state.
+ *
+ * \param       mask
+ *              Specifies the QSPI interrupt status conditions to clear.  \e
+ *              mask is a mask of logically OR'ed \ref ALT_QSPI_INT_STATUS_t
+ *              values that designate the status conditions to clear.
+ *
+ * \retval      ALT_E_SUCCESS   Indicates successful completion.
+ * \retval      ALT_E_ERROR     Indicates an error occurred.
+ */
+ALT_STATUS_CODE alt_qspi_int_clear(const uint32_t mask);
+
+/******************************************************************************/
+/*!
+ * Disable the specified QSPI controller interrupt status conditions identified
+ * in the mask.
+ *
+ * This function disables one or more of the status conditions as contributors
+ * to the \b ALT_INT_INTERRUPT_QSPI_IRQ interrupt signal state.
+ *
+ * This API requires that the QSPI controller be idle, as determined by
+ * alt_qspi_is_idle().
+ *
+ * NOTE: A cleared bit for any status condition in the mask value does not have
+ * the effect of enabling it as a contributor to the \b
+ * ALT_INT_INTERRUPT_QSPI_IRQ interrupt signal state. The function
+ * alt_qspi_int_enable() is used to enable status source conditions.
+ *
+ * \param       mask
+ *              Specifies the status conditions to disable as interrupt source
+ *              contributors. \e mask is a mask of logically OR'ed
+ *              \ref ALT_QSPI_INT_STATUS_t values that designate the status
+ *              conditions to disable.
+ *
+ * \retval      ALT_E_SUCCESS   Indicates successful completion.
+ * \retval      ALT_E_ERROR     Indicates an error occurred.
+ */
+ALT_STATUS_CODE alt_qspi_int_disable(const uint32_t mask);
+
+/******************************************************************************/
+/*!
+ * Enable the specified QSPI controller interrupt status conditions identified
+ * in the mask.
+ *
+ * This function enables one or more of the status conditions as contributors to
+ * the \b ALT_INT_INTERRUPT_QSPI_IRQ interrupt signal state.
+ *
+ * This API requires that the QSPI controller be idle, as determined by
+ * alt_qspi_is_idle().
+ *
+ * NOTE: A cleared bit for any status condition in the mask value does not have
+ * the effect of disabling it as a contributor to the \b
+ * ALT_INT_INTERRUPT_QSPI_IRQ interrupt signal state. The function
+ * alt_qspi_int_disable() is used to disable status source conditions.
+ *
+ * \param       mask
+ *              Specifies the status conditions to enable as interrupt source
+ *              contributors. \e mask is a mask of logically OR'ed
+ *              \ref ALT_QSPI_INT_STATUS_t values that designate the status
+ *              conditions to enable.
+ *
+ * \retval      ALT_E_SUCCESS   Indicates successful completion.
+ * \retval      ALT_E_ERROR     Indicates an error occurred.
+ */
+ALT_STATUS_CODE alt_qspi_int_enable(const uint32_t mask);
+
+/******************************************************************************/
+/*!
+ * Returns true the serial interface and QSPI pipeline is IDLE.
+ *
+ * \returns     Returns true the serial interface and QSPI pipeline is IDLE.
+ */
+bool alt_qspi_is_idle(void);
+
+/*! @} */
+
+/******************************************************************************/
+/*! \addtogroup ALT_QSPI_GP_BLKIO General Purpose Block I/O
+ *
+ * The functions in this group provide general purpose block read and
+ * write flash functions.
+ *
+ * \internal
+ * These functions use Indirect Read/Write transfers to read and write block
+ * data to the flash device. An outline of the operational flow for these
+ * operations can be found in:
+ * //depot/soc/hhp_sw/baremetal_fw/drivers/qspi/qspi.c
+ * 
+ * The general flow for an indirect block read is to call
+ * qspi_configure_mode_indirect_read_start() to initiate the read transfer from
+ * the flash device into the SRAM buffer and follow with a call to either
+ * qpsi_write_sram_fifo_poll() or qspi_read_sram_fifo_irq() to copy the data
+ * from SRAM into the user's buffer.
+ * 
+ * The general flow for an indirect block write is to call
+ * qspi_configure_mode_indirect_write_start() to initiate the write transfer
+ * from the SRAM buffer to the flash device and follow with a call to either
+ * qpsi_write_sram_fifo_poll() or qspi_write_sram_fifo_irq() to fill the SRAM
+ * buffer with the user's data as space becomes available.
+ * \endinternal
+ *
+ * @{
+ */
+
+/******************************************************************************/
+/*!
+ * Read a block of data from the specified flash address.
+ *
+ * Reads a block of \e n data bytes from the flash \e src address into the user
+ * supplied \e dest buffer. The memory address, flash address, and size must be
+ * word aligned.
+ *
+ * \param       dest
+ *              The address of a caller supplied destination buffer large enough
+ *              to contain the requested block of flash data.
+ *
+ * \param       src
+ *              The flash device address to start reading data from.
+ *
+ * \param       size
+ *              The requested number of data bytes to read from the flash device.
+ *
+ * \retval      ALT_E_SUCCESS   Indicates successful completion.
+ * \retval      ALT_E_ERROR     Indicates an error occurred.
+ */
+ALT_STATUS_CODE alt_qspi_read(void * dest, uint32_t src, size_t size);
+
+/******************************************************************************/
+/*!
+ * Write a block of data to the specified flash address.
+ *
+ * Writes a block of \e n data bytes to the flash \e dest address from the
+ * designated \e src buffer. The applicable destination flash address range
+ * should have been erased prior to calling this function. The flash address,
+ * memory address, and size must be word aligned.
+ *
+ * \param       dest
+ *              The destination flash address to begin writing data to.
+ *
+ * \param       src
+ *              The source address to start writing data from.
+ *
+ * \param       size
+ *              The requested number of data bytes to write to the flash device.
+ *
+ * \retval      ALT_E_SUCCESS   Indicates successful completion.
+ * \retval      ALT_E_ERROR     Indicates an error occurred.
+ */
+ALT_STATUS_CODE alt_qspi_write(uint32_t dest, const void * src, size_t size);
+
+/*! @} */
+
+/******************************************************************************/
+/*! \addtogroup ALT_QSPI_DEV_CFG Flash Device Configuration
+ *
+ * The declarations and functions in this group are used to configure the QSPI
+ * controller interface to external flash devices.
+ *
+ * The following steps describe how to initialize and configure the
+ * QSPI controller to operate with a flash device.
+ *
+ * * Wait until any pending QSPI operations have completed.
+ * * Disable the QSPI controller using alt_qspi_disable().
+ * * Configure the device for optimal read transaction performance using
+ *   alt_qspi_device_read_config_set().
+ * * Configure the device for optimal write transaction performance using
+ *   alt_qspi_device_write_config_set().
+ * * Enable (alt_qspi_mode_bit_disable()) or disable
+ *   (alt_qspi_mode_bit_disable()) the mode bits per the device
+ *   requirements. If mode bits are enabled, then configure the mode
+ *   bit values using alt_qspi_mode_bit_config_set().
+ * * Configure the device size and write protection information using
+ *   alt_qspi_device_size_config_set().
+ * * Configure the QSPI device delay and timing settings using
+ *   alt_qspi_device_write_config_set().
+ * * Configure the baud divisor setting to define the required clock frequency
+ *   to the device using alt_qspi_baud_rate_div_set().
+ * * Enable the QSPI controller using alt_qspi_enable().
+ *
+ * @{
+ */
+
+/******************************************************************************/
+/*!
+ * This type enumerates the operational modes the QSPI controller can be
+ * configured for. It may apply to instruction, address, and/or data width
+ * interactions between the QSPI controller and the flash device.
+ */
+typedef enum ALT_QSPI_MODE_e
+{
+  ALT_QSPI_MODE_SINGLE = 0,     /*!< Use Standard Single SPI (SIO-SPI) mode (bits 
+                                 *   always transferred into the device on DQ0 
+                                 *   only). Supported by all SPI flash devices.
+                                 */
+  ALT_QSPI_MODE_DUAL   = 1,     /*!< Use Dual SPI (DIO-SPI) SPI mode where bits are
+                                 *   transferred on DQ0 and DQ1.
+                                 */
+  ALT_QSPI_MODE_QUAD   = 2      /*!< Use Dual SPI (QIO-SPI) SPI mode where bits are
+                                 *   transferred on DQ0, DQ1, DQ3, and DQ3.
+                                 */
+} ALT_QSPI_MODE_t;
+
+/******************************************************************************/
+/*!
+ * This type enumerates the mode configurations available for driving the
+ * ss_n[3:0] device chip selects.  The chip selects may be controlled as either
+ * in a '1 of 4' or '4 to 16 decode' mode.
+ */
+typedef enum ALT_QSPI_CS_MODE_e
+{
+  ALT_QSPI_CS_MODE_SINGLE_SELECT = 0,   /*!< Select 1 of 4 chip select ss_n[3:0]
+                                         */
+  ALT_QSPI_CS_MODE_DECODE        = 1    /*!< Select external 4 to 16 decode of
+                                         *   ss_n[3:0].
+                                         */
+} ALT_QSPI_CS_MODE_t;
+
+/******************************************************************************/
+/*!
+ * This type enumerates the QSPI controller master baud rate divisor selections.
+ */
+typedef enum ALT_QSPI_BAUD_DIV_e
+{
+  ALT_QSPI_BAUD_DIV_2            = 0x0, /*!< Divide by 2 */
+  ALT_QSPI_BAUD_DIV_4            = 0x1, /*!< Divide by 4 */
+  ALT_QSPI_BAUD_DIV_6            = 0x2, /*!< Divide by 6 */
+  ALT_QSPI_BAUD_DIV_8            = 0x3, /*!< Divide by 8 */
+  ALT_QSPI_BAUD_DIV_10           = 0x4, /*!< Divide by 10 */
+  ALT_QSPI_BAUD_DIV_12           = 0x5, /*!< Divide by 12 */
+  ALT_QSPI_BAUD_DIV_14           = 0x6, /*!< Divide by 14 */
+  ALT_QSPI_BAUD_DIV_16           = 0x7, /*!< Divide by 16 */
+  ALT_QSPI_BAUD_DIV_18           = 0x8, /*!< Divide by 18 */
+  ALT_QSPI_BAUD_DIV_20           = 0x9, /*!< Divide by 20 */
+  ALT_QSPI_BAUD_DIV_22           = 0xA, /*!< Divide by 22 */
+  ALT_QSPI_BAUD_DIV_24           = 0xB, /*!< Divide by 24 */
+  ALT_QSPI_BAUD_DIV_26           = 0xC, /*!< Divide by 26 */
+  ALT_QSPI_BAUD_DIV_28           = 0xD, /*!< Divide by 28 */
+  ALT_QSPI_BAUD_DIV_30           = 0xE, /*!< Divide by 30 */
+  ALT_QSPI_BAUD_DIV_32           = 0xF  /*!< Divide by 32 */
+} ALT_QSPI_BAUD_DIV_t;
+
+/******************************************************************************/
+/*!
+ * Device Size Configuration
+ *
+ * This type defines the structure used to specify flash device size and write
+ * protect regions.
+ */
+typedef struct ALT_QSPI_DEV_SIZE_CONFIG_s
+{
+  uint32_t      block_size;         /*!< Number of bytes per device block. The
+                                     *   number is specified as a power of 2.
+                                     *   That is 0 = 1 byte, 1 = 2 bytes, ...
+                                     *   16 = 65535 bytes, etc.
+                                     */
+  uint32_t      page_size;          /*!< Number of bytes per device page.  This
+                                     *   is required by the controller for
+                                     *   performing flash writes up to and
+                                     *   across page boundaries.
+                                     */
+  uint32_t      addr_size;          /*!< Number of bytes used for the flash
+                                     *   address. The value is \e n + 1
+                                     *   based. That is 0 = 1 byte, 1 = 2 bytes,
+                                     *   2 = 3 bytes, 3 = 4 bytes.
+                                     */
+  uint32_t      lower_wrprot_block; /*!< The block number that defines the lower
+                                     *   block in the range of blocks that is
+                                     *   protected from writing. This field
+                                     *   is ignored it write protection is 
+                                     *   disabled.
+                                     */
+  uint32_t      upper_wrprot_block; /*!< The block number that defines the upper
+                                     *   block in the range of blocks that is
+                                     *   protected from writing. This field
+                                     *   is ignored it write protection is 
+                                     *   disabled.
+                                     */
+  bool          wrprot_enable;      /*!< The write region enable value. A value
+                                     *   of \b true enables write protection
+                                     *   on the region specified by the
+                                     *   \e lower_wrprot_block and
+                                     *   \e upper_wrprot_block range.
+                                     */
+} ALT_QSPI_DEV_SIZE_CONFIG_t;
+
+/******************************************************************************/
+/*!
+ * This type enumerates the QSPI clock phase activity options outside the SPI
+ * word.
+ */
+typedef enum ALT_QSPI_CLK_PHASE_e
+{
+  ALT_QSPI_CLK_PHASE_ACTIVE     = 0,    /*!< The SPI clock is active outside the
+                                         *   word
+                                         */
+  ALT_QSPI_CLK_PHASE_INACTIVE   = 1     /*!< The SPI clock is inactive outside the
+                                         *   word
+                                         */
+} ALT_QSPI_CLK_PHASE_t;
+
+/******************************************************************************/
+/*!
+ * This type enumerates the QSPI clock polarity options outside the SPI word.
+ */
+typedef enum ALT_QSPI_CLK_POLARITY_e
+{
+  ALT_QSPI_CLK_POLARITY_LOW     = 0,    /*!< SPI clock is quiescent low outside the
+                                         *   word.
+                                         */
+  ALT_QSPI_CLK_POLARITY_HIGH    = 1     /*!< SPI clock is quiescent high outside the
+                                         *   word.
+                                         */
+} ALT_QSPI_CLK_POLARITY_t;
+
+/******************************************************************************/
+/*!
+ * QSPI Controller Timing Configuration
+ *
+ * This type defines the structure used to configure timing paramaters used by
+ * the QSPI controller to communicate with a target flash device.
+ *
+ * All timing values are defined in cycles of the SPI master ref clock.
+ */
+typedef struct ALT_QSPI_TIMING_CONFIG_s
+{
+  ALT_QSPI_CLK_PHASE_t      clk_phase;  /*!< Selects whether the clock is in an
+                                         *   active or inactive phase outside the
+                                         *   SPI word.
+                                         */
+
+  ALT_QSPI_CLK_POLARITY_t   clk_pol;    /*!< Selects whether the clock is quiescent
+                                         *   low or high outside the SPI word.
+                                         */
+
+  uint32_t                  cs_da;      /*!< Chip Select De-Assert. Added delay in
+                                         *   master reference clocks for the length
+                                         *   that the master mode chip select
+                                         *   outputs are de-asserted between
+                                         *   transactions. If CSDA = \e X, then the
+                                         *   chip select de-assert time will be: 1
+                                         *   sclk_out + 1 ref_clk + \e X ref_clks.
+                                         */
+  uint32_t                  cs_dads;    /*!< Chip Select De-Assert Different
+                                         *   Slaves. Delay in master reference
+                                         *   clocks between one chip select being
+                                         *   de-activated and the activation of
+                                         *   another. This is used to ensure a quiet
+                                         *   period between the selection of two
+                                         *   different slaves.  CSDADS is only
+                                         *   relevant when switching between 2
+                                         *   different external flash devices. If
+                                         *   CSDADS = \e X, then the delay will be:
+                                         *   1 sclk_out + 3 ref_clks + \e X
+                                         *   ref_clks.
+                                         */
+  uint32_t                  cs_eot;     /*!< Chip Select End Of Transfer. Delay in
+                                         *   master reference clocks between last
+                                         *   bit of current transaction and
+                                         *   de-asserting the device chip select
+                                         *   (n_ss_out). By default (when CSEOT=0),
+                                         *   the chip select will be de-asserted on
+                                         *   the last falling edge of sclk_out at
+                                         *   the completion of the current
+                                         *   transaction. If CSEOT = \e X, then chip
+                                         *   selected will de-assert \e X ref_clks
+                                         *   after the last falling edge of
+                                         *   sclk_out.
+                                         */
+  uint32_t                  cs_sot;     /*!< Chip Select Start Of Transfer. Delay in
+                                         *   master reference clocks between setting
+                                         *   n_ss_out low and first bit transfer. By
+                                         *   default (CSSOT=0), chip select will be
+                                         *   asserted half a SCLK period before the
+                                         *   first rising edge of sclk_out. If CSSOT
+                                         *   = \e X, chip select will be asserted
+                                         *   half an sclk_out period before the
+                                         *   first rising edge of sclk_out + \e X
+                                         *   ref_clks.
+                                         */
+
+  uint32_t                  rd_datacap; /*!< The additional number of read data
+                                         *   capture cycles (ref_clk) that should be
+                                         *   applied to the internal read data
+                                         *   capture circuit.  The large
+                                         *   clock-to-out delay of the flash memory
+                                         *   together with trace delays as well as
+                                         *   other device delays may impose a
+                                         *   maximum flash clock frequency which is
+                                         *   less than the flash memory device
+                                         *   itself can operate at. To compensate,
+                                         *   software should set this register to a
+                                         *   value that guarantees robust data
+                                         *   captures.
+                                         */
+} ALT_QSPI_TIMING_CONFIG_t;
+
+/******************************************************************************/
+/*!
+ * Device Instruction Configuration
+ *
+ * This type defines a structure for specifying the optimal instruction set
+ * configuration to use with a target flash device.
+ */
+typedef struct ALT_QSPI_DEV_INST_CONFIG_s
+{
+  uint32_t              op_code;            /*!< The read or write op code to use
+                                             *   for the device transaction.
+                                             */
+  ALT_QSPI_MODE_t       inst_type;          /*!< Instruction mode type for the
+                                             *   controller to use with the
+                                             *   device. The instruction type
+                                             *   applies to all instructions
+                                             *   (reads and writes) issued from
+                                             *   either the Direct Access
+                                             *   Controller or the Indirect
+                                             *   Acces Controller.
+                                             */
+  ALT_QSPI_MODE_t       addr_xfer_type;     /*!< Address transfer mode type. The
+                                             *   value of this field is ignored
+                                             *   if the \e inst_type data member
+                                             *   is set to anything other than
+                                             *   ALT_QSPI_MODE_SINGLE. In that
+                                             *   case, the addr_xfer_type
+                                             *   assumes the same mode as the \e
+                                             *   inst_type.
+                                             */
+  ALT_QSPI_MODE_t       data_xfer_type;     /*!< Data transfer mode type. The
+                                             *   value of this field is ignored
+                                             *   if the \e inst_type data member
+                                             *   is set to anything other than
+                                             *   ALT_QSPI_MODE_SINGLE. In that
+                                             *   case, the data_xfer_type
+                                             *   assumes the same mode as the \e
+                                             *   inst_type.
+                                             */
+  uint32_t              dummy_cycles;       /*!< Number of dummy clock cycles
+                                             *   required by device for a read
+                                             *   or write instruction.
+                                             */
+
+} ALT_QSPI_DEV_INST_CONFIG_t;
+
+/******************************************************************************/
+/*!
+ * Get the current value of the QSPI master baud rate divisor.
+ *
+ * \returns     The value of the QSPI master baud rate divisor.
+ */
+ALT_QSPI_BAUD_DIV_t alt_qspi_baud_rate_div_get(void);
+
+/******************************************************************************/
+/*!
+ * Set the current value of the QSPI master baud rate divisor.
+ *
+ * Sets the value of the QSPI master baud rate divisor.
+ *
+ * \param       baud_rate_div
+ *              The master baud rate divisor. Valid range includes
+ *              even values 2 to 32.
+ *
+ * \retval      ALT_E_SUCCESS   Indicates successful completion.
+ * \retval      ALT_E_ERROR     Indicates an error occurred.
+ */
+ALT_STATUS_CODE alt_qspi_baud_rate_div_set(const ALT_QSPI_BAUD_DIV_t baud_rate_div);
+
+/******************************************************************************/
+/*!
+ * Get the current QSPI device peripheral chip select output and decode function
+ * configuration values.
+ *
+ * \param       cs
+ *              [out] The chip select line output values.
+ *
+ * \param       cs_mode
+ *              [out] The decode mode to use for the chip selects.
+ *
+ * \retval      ALT_E_SUCCESS   Indicates successful completion.
+ * \retval      ALT_E_ERROR     Indicates an error occurred.
+ */
+ALT_STATUS_CODE alt_qspi_chip_select_config_get(uint32_t* cs, ALT_QSPI_CS_MODE_t* cs_mode);
+
+/******************************************************************************/
+/*!
+ * Set the QSPI device peripheral chip select outputs and decode function
+ * configuration.
+ *
+ * The chip select lines output values operate according to the selected chip
+ * select decode mode. If \e cs_mode is ALT_QSPI_CS_MODE_SINGLE_SELECT then
+ * cs[3:0] are output thus:
+ *
+ *  cs[3:0]  | n_ss_out[3:0]
+ * :---------|:----------------------------
+ *  xxx0     | 1110
+ *  xx01     | 1101
+ *  x011     | 1011
+ *  0111     | 0111
+ *  1111     | 1111 (no peripheral selected)
+ *
+ * Otherwise if \e cs_mode is ALT_QSPI_CS_MODE_DECODE then cs[3:0] directly
+ * drives n_ss_out[3:0].
+ *
+ * \param       cs
+ *              The chip select line output values.
+ *
+ * \param       cs_mode
+ *              The decode mode to use for the chip selects.
+ *
+ * \retval      ALT_E_SUCCESS   Indicates successful completion.
+ * \retval      ALT_E_ERROR     Indicates an error occurred.
+ */
+ALT_STATUS_CODE alt_qspi_chip_select_config_set(const uint32_t cs,
+                                                const ALT_QSPI_CS_MODE_t cs_mode);
+
+/******************************************************************************/
+/*!
+ * Disable the mode bits from being sent after the address bytes.
+ *
+ * Prevent the mode bits defined in the Mode Bit Configuration register from
+ * being sent following the address bytes.
+ *
+ * \retval      ALT_E_SUCCESS   Indicates successful completion.
+ * \retval      ALT_E_ERROR     Indicates an error occurred.
+ */
+ALT_STATUS_CODE alt_qspi_mode_bit_disable(void);
+
+/******************************************************************************/
+/*!
+ * Enable the mode bits to be sent after the address bytes.
+ *
+ * Ensure the mode bits defined in the Mode Bit Configuration register to
+ * be sent following the address bytes.
+ *
+ * \retval      ALT_E_SUCCESS   Indicates successful completion.
+ * \retval      ALT_E_ERROR     Indicates an error occurred.
+ */
+ALT_STATUS_CODE alt_qspi_mode_bit_enable(void);
+
+/******************************************************************************/
+/*!
+ * Get the current value of the Mode Bit Configuration register.
+ *
+ * \returns     The 8 bit value that is sent to the device following the address
+ *              bytes when the mode bit is enabled (see: alt_qspi_mode_bit_enable())
+ */
+uint32_t alt_qspi_mode_bit_config_get(void);
+
+/******************************************************************************/
+/*!
+ * Set the value of the Mode Bit Configuration register.
+ *
+ * Set the value of the 8 bits that are sent to the device following the address
+ * bytes when the mode bit is enabled (see: alt_qspi_mode_bit_enable())
+ *
+ * This API requires that the QSPI controller be idle, as determined by
+ * alt_qspi_is_idle().
+ *
+ * \param       mode_bits
+ *              The 8 bit value sent to the device following the address bytes.
+ *
+ * \retval      ALT_E_SUCCESS   Indicates successful completion.
+ * \retval      ALT_E_ERROR     Indicates an error occurred.
+ */
+ALT_STATUS_CODE alt_qspi_mode_bit_config_set(const uint32_t mode_bits);
+
+/******************************************************************************/
+/*!
+ * Get the current flash device size and write protection configuration.
+ *
+ * \param       cfg
+ *              [out] Pointer to a ALT_QSPI_DEV_SIZE_CONFIG_t structure to
+ *              contain the returned flash device size and write protection
+ *              configuration.
+ *
+ * \retval      ALT_E_SUCCESS   Indicates successful completion.
+ * \retval      ALT_E_ERROR     Indicates an error occurred.
+ */
+ALT_STATUS_CODE alt_qspi_device_size_config_get(ALT_QSPI_DEV_SIZE_CONFIG_t * cfg);
+
+/******************************************************************************/
+/*!
+ * Set the flash device size and write protection configuration.
+ *
+ * \param       cfg
+ *              Pointer to a ALT_QSPI_DEV_SIZE_CONFIG_t structure containing the
+ *              flash device size and write protection configuration.
+ *
+ * \retval      ALT_E_SUCCESS   Indicates successful completion.
+ * \retval      ALT_E_ERROR     Indicates an error occurred.
+ */
+ALT_STATUS_CODE alt_qspi_device_size_config_set(const ALT_QSPI_DEV_SIZE_CONFIG_t * cfg);
+
+/******************************************************************************/
+/*!
+ * Get the current QSPI device read instruction configuration.
+ *
+ * \param       cfg
+ *              [out] Pointer to a ALT_QSPI_DEV_INST_CONFIG_t structure to
+ *              contain the returned QSPI controller instruction configuration
+ *              used when performing read transactions with the device.
+ *
+ * \retval      ALT_E_SUCCESS   Indicates successful completion.
+ * \retval      ALT_E_ERROR     Indicates an error occurred.
+ */
+ALT_STATUS_CODE alt_qspi_device_read_config_get(ALT_QSPI_DEV_INST_CONFIG_t * cfg);
+
+/******************************************************************************/
+/*!
+ * Set the QSPI device read instruction configuration.
+ *
+ * This API requires that the QSPI controller be idle, as determined by
+ * alt_qspi_is_idle().
+ *
+ * \param       cfg
+ *              Pointer to a ALT_QSPI_DEV_INST_CONFIG_t structure specifying the
+ *              desired op code, transfer widths, and dummy cycles for the QSPI
+ *              controller to use when performing read transactions with the
+ *              device.
+ *
+ * \retval      ALT_E_SUCCESS   Indicates successful completion.
+ * \retval      ALT_E_ERROR     Indicates an error occurred.
+ */
+ALT_STATUS_CODE alt_qspi_device_read_config_set(const ALT_QSPI_DEV_INST_CONFIG_t * cfg);
+
+/******************************************************************************/
+/*!
+ * Get the current QSPI device write instruction configuration.
+ *
+ * \param       cfg
+ *              [out] Pointer to a ALT_QSPI_DEV_INST_CONFIG_t structure to
+ *              contain the returned QSPI controller instruction configuration
+ *              used when performing write transactions with the device.
+ *
+ * \retval      ALT_E_SUCCESS   Indicates successful completion.
+ * \retval      ALT_E_ERROR     Indicates an error occurred.
+ */
+ALT_STATUS_CODE alt_qspi_device_write_config_get(ALT_QSPI_DEV_INST_CONFIG_t * cfg);
+
+/******************************************************************************/
+/*!
+ * Set the QSPI device write instruction configuration.
+ *
+ * This API requires that the QSPI controller be idle, as determined by
+ * alt_qspi_is_idle().
+ *
+ * \param       cfg
+ *              Pointer to a ALT_QSPI_DEV_INST_CONFIG_t structure specifying the
+ *              desired op code, transfer widths, and dummy cycles for the QSPI
+ *              controller to use when performing write transactions with the
+ *              device.
+ *
+ * \retval      ALT_E_SUCCESS   Indicates successful completion.
+ * \retval      ALT_E_ERROR     Indicates an error occurred.
+ */
+ALT_STATUS_CODE alt_qspi_device_write_config_set(const ALT_QSPI_DEV_INST_CONFIG_t * cfg);
+
+/******************************************************************************/
+/*!
+ * Get the QSPI device delay and timing configuration parameters.
+ *
+ * This function returns the settings of the chip select delay and timing
+ * configurations.
+ *
+ * \param       cfg
+ *              [out] Pointer to a ALT_QSPI_TIMING_CONFIG_t structure to return
+ *              the device timing and delay settings.
+ *
+ * \retval      ALT_E_SUCCESS   Indicates successful completion.
+ * \retval      ALT_E_ERROR     Indicates an error occurred.
+ */
+ALT_STATUS_CODE alt_qspi_timing_config_get(ALT_QSPI_TIMING_CONFIG_t * cfg);
+
+/******************************************************************************/
+/*!
+ * Set the QSPI device delay and timing configuration parameters.
+ *
+ * This function allows the user to configure how the chip select is driven
+ * after each flash access. This is required as each device may have different
+ * timing requirements.  As the serial clock frequency is increased, these
+ * timing parameters become more important and can be adjusted to meet the
+ * requirements of a specific flash device.  All timings are defined in cycles
+ * of the SPI master ref clock.
+ *
+ * This API requires that the QSPI controller be idle, as determined by
+ * alt_qspi_is_idle().
+ *
+ * \param       cfg
+ *              Pointer to a ALT_QSPI_TIMING_CONFIG_t structure specifying the
+ *              desired timing and delay settings.
+ *
+ * \retval      ALT_E_SUCCESS   Indicates successful completion.
+ * \retval      ALT_E_ERROR     Indicates an error occurred.
+ */
+ALT_STATUS_CODE alt_qspi_timing_config_set(const ALT_QSPI_TIMING_CONFIG_t * cfg);
+
+/*! @} */
+
+/******************************************************************************/
+/*! \addtogroup ALT_QSPI_DAC Direct Access Mode
+ *
+ * In direct access mode, an access to the AHB data slave triggers a read or
+ * write command to the flash memory. To use the direct access mode, enable the
+ * direct access controller with the alt_qspi_direct_enable() function. An
+ * external master, for example a processor, triggers the direct access
+ * controller with a read or write operation to the AHB data slave
+ * interface. The data slave exposes a 1MB window into the flash device. You can
+ * remap this window to any 1MB location within the flash device address range.
+ *
+ * To remap the AHB data slave to access other 1MB regions of the flash device,
+ * enable address remapping by calling alt_qspi_ahb_address_remap_enable(). All
+ * incoming data slave accesses remap to the offset specified in the remap
+ * address register which is configured by alt_qspi_ahb_remap_address_set().
+ *
+ * The 20 LSBs of incoming addresses are used for accessing the 1MB region and
+ * the higher bits are ignored.
+ *
+ * The quad SPI controller does not issue any error status for accesses that lie
+ * outside the connected flash memory space.
+ *
+ * @{
+ */
+
+/******************************************************************************/
+/*!
+ * Disable the QSPI Direct Access Controller.
+ *
+ * \retval      ALT_E_SUCCESS   Indicates successful completion.
+ * \retval      ALT_E_ERROR     Indicates an error occurred.
+ */
+ALT_STATUS_CODE alt_qspi_direct_disable(void);
+
+/******************************************************************************/
+/*!
+ * Enable the QSPI Direct Access Controller.
+ *
+ * \retval      ALT_E_SUCCESS   Indicates successful completion.
+ * \retval      ALT_E_ERROR     Indicates an error occurred.
+ */
+ALT_STATUS_CODE alt_qspi_direct_enable(void);
+
+/******************************************************************************/
+/*!
+ * Get the current AHB address remap value.
+ *
+ * Returns the current value of the AHB remap address register.
+ *
+ * \returns     The value used to remap an incoming AHB address to a
+ *              different address used by the flash device.
+ */
+uint32_t alt_qspi_ahb_remap_address_get(void);
+
+/******************************************************************************/
+/*!
+ * Set the AHB address remap value.
+ *
+ * Sets the value of the AHB remap address register.
+ *
+ * This API requires that the QSPI controller be idle, as determined by
+ * alt_qspi_is_idle().
+ *
+ * \param       ahb_remap_addr
+ *              The value used to remap an incoming AHB address to a different
+ *              address used by the flash device.
+ *
+ * \retval      ALT_E_SUCCESS   Indicates successful completion.
+ * \retval      ALT_E_ERROR     Indicates an error occurred.
+ */
+ALT_STATUS_CODE alt_qspi_ahb_remap_address_set(const uint32_t ahb_remap_addr);
+
+/******************************************************************************/
+/*!
+ * Disable AHB address remapping.
+ *
+ * Disables remapping of incoming AHB addresses so they are sent unmodified to
+ * the flash device. The incoming AHB address maps directly to the address
+ * serially sent to the flash device.
+ *
+ * \retval      ALT_E_SUCCESS   Indicates successful completion.
+ * \retval      ALT_E_ERROR     Indicates an error occurred.
+ */
+ALT_STATUS_CODE alt_qspi_ahb_address_remap_disable(void);
+
+/******************************************************************************/
+/*!
+ * Enable AHB address remapping.
+ *
+ * Enables remapping of incoming AHB addresses so they are modified to 
+ * \<address\> + \e N, where \e N is the configured remap address value. 
+ *
+ * See: alt_qspi_ahb_remap_address_set().
+ *
+ * \retval      ALT_E_SUCCESS   Indicates successful completion.
+ * \retval      ALT_E_ERROR     Indicates an error occurred.
+ */
+ALT_STATUS_CODE alt_qspi_ahb_address_remap_enable(void);
+
+/*! @} */
+
+/******************************************************************************/
+/*! \addtogroup ALT_QSPI_INDAC Indirect Access Mode
+ *
+ * In indirect access mode, flash data is temporarily buffered in the QSPI
+ * controller's SRAM. Software controls and triggers indirect accesses through
+ * the APB register slave interface. The controller transfers data through the
+ * AHB data slave interface.
+ *
+ * An indirect read operation reads data from the flash memory, places the data
+ * into the SRAM, and transfers the data to an external master through the AHB
+ * data slave interface.
+ *
+ * An indirect write operation programs data from the SRAM to the flash memory.
+ *
+ * @{
+ */
+
+/******************************************************************************/
+/*!
+ * Starts an indirect read transfer.
+ *
+ * Initiates an indirect read transfer of the requested number of bytes from the
+ * designated flash address.
+ *
+ * After calling this function, flash data may be read from the QSPI SRAM buffer
+ * as it becomes available via one of the following methods:
+ *  * Directly from the AHB data slave interface at the configured AHB trigger
+ *    address. If the requested data is not immediately available in the SRAM
+ *    buffer then AHB wait states will be applied until the data has been read
+ *    from flash into the SRAM buffer. Alternatively, data may be read from the
+ *    AHB data slave as the SRAM is filled. The availability of data in the SRAM
+ *    buffer may be determined by an SRAM watermark interrupt notification or by
+ *    polling the SRAM fill level.
+ *  * Configuring and enabling the QSPI DMA peripheral controller.
+ *
+ * The following is a list of restrictions:
+ *  * flash_addr must be word aligned.
+ *  * num_bytes must be word aligned.
+ *  * The transfer must not cross the 3-byte addressing boundary. This
+ *    restriction may be device specific and may be lifted in the future.
+ *
+ * \param       flash_addr
+ *              The flash source address to read data from.
+ *
+ * \param       num_bytes
+ *              The number of bytes to read from the flash source address.
+ *
+ * \retval      ALT_E_SUCCESS   Indicates successful completion.
+ * \retval      ALT_E_ERROR     Indicates an error occurred.
+ */
+ALT_STATUS_CODE alt_qspi_indirect_read_start(const uint32_t flash_addr,
+                                             const size_t num_bytes);
+
+/******************************************************************************/
+/*!
+ * Finish the indirect read operation that was completed or canceled. This
+ * function should be called before another indirect read is started.
+ *
+ * \retval      ALT_E_SUCCESS   Indicates successful completion.
+ * \retval      ALT_E_ERROR     Indicates an error occurred.
+ */
+ALT_STATUS_CODE alt_qspi_indirect_read_finish(void);
+
+/******************************************************************************/
+/*!
+ * Cancel all indirect read transfers in progress.
+ *
+ * \retval      ALT_E_SUCCESS   Indicates successful completion.
+ * \retval      ALT_E_ERROR     Indicates an error occurred.
+ */
+ALT_STATUS_CODE alt_qspi_indirect_read_cancel(void);
+
+/******************************************************************************/
+/*!
+ * Get the current indirect read SRAM fill level value.
+ *
+ * Returns the SRAM fill level for the indirect read partition in units of SRAM
+ * words (4 bytes).
+ *
+ * \returns     The SRAM fill level for the indirect read partition in units of 
+ *              SRAM words (4 bytes).
+ */
+uint32_t alt_qspi_indirect_read_fill_level(void);
+
+/******************************************************************************/
+/*!
+ * Get the current indirect read watermark value.
+ *
+ * The watermark value (in bytes) represents the minimum fill level of the SRAM
+ * before a DMA peripheral access is permitted. When the SRAM fill level passes
+ * the watermark, an interrupt source is also generated. This can be disabled by
+ * writing a value of all zeroes.
+ *
+ * \returns     The current indirect read watermark value.
+ */
+uint32_t alt_qspi_indirect_read_watermark_get(void);
+
+/******************************************************************************/
+/*!
+ * Set the indirect read watermark value.
+ *
+ * The watermark value (in bytes) represents the minimum fill level of the SRAM
+ * before a DMA peripheral access is permitted. When the SRAM fill level passes
+ * the watermark, an interrupt source is also generated. This can be disabled by
+ * writing a value of all zeroes. The watermark can only be set when no indirect
+ * read is in progress.
+ *
+ * \param       watermark
+ *              The watermark value (in bytes).
+ *
+ * \retval      ALT_E_SUCCESS   Indicates successful completion.
+ * \retval      ALT_E_ERROR     Indicates an error occurred.
+ */
+ALT_STATUS_CODE alt_qspi_indirect_read_watermark_set(const uint32_t watermark);
+
+/******************************************************************************/
+/*!
+ * Returns true when an indirect read has completed otherwise false.
+ *
+ * \internal
+ * Returns Indirect Read Transfer Control Register bit 5 "Indirect Completion Status".
+ * \endinternal
+ *
+ * \returns     Returns true when an indirect read has completed otherwise false.
+ */
+bool alt_qspi_indirect_read_is_complete(void);
+
+/******************************************************************************/
+/*!
+ * Starts an indirect write transfer.
+ *
+ * Initiates an indirect write transfer of the requested number of bytes to the
+ * designated flash address.
+ *
+ * After calling this function, flash data may be written to the QSPI SRAM
+ * buffer there is space via one of the following methods:
+ *  * Directly from the AHB data slave interface at the configured AHB trigger
+ *    address. If the requested space is not immediately available in the SRAM
+ *    buffer then AHB wait states will be applied until the space becomes
+ *    available. Alternatively, the data may be written to the AHB data slave
+ *    as the SRAM is drained. The space in the SRAM buffer may be determined by
+ *    an SRAM watermark interrupt notification or by polling the SRAM fill
+ *    level and subtracting that value from the SRAM space devoted to writes.
+ *  * Configuring and enabling the QSPI DMA peripheral controller.
+ *
+ * The following is a list of restrictions:
+ *  * flash_addr must be word aligned.
+ *  * num_bytes must be word aligned.
+ *  * num_bytes must be 256 or below. This is due to a device specific
+ *    limitation and may be lifted in the future.
+ *  * The transfer must not cross the page (256 byte) addressing boundary. This
+ *    restriction may be device specific and may be lifted in the future.
+ *
+ * \param       flash_addr
+ *              The flash destination address to write data to.
+ *
+ * \param       num_bytes
+ *              The number of bytes to write to the flash.
+ *
+ * \retval      ALT_E_SUCCESS   Indicates successful completion.
+ * \retval      ALT_E_ERROR     Indicates an error occurred.
+ */
+ALT_STATUS_CODE alt_qspi_indirect_write_start(const uint32_t flash_addr,
+                                              const size_t num_bytes);
+
+/******************************************************************************/
+/*!
+ * Finish the indirect write operation that was completed or canceled. This
+ * function should be called before another indirect write is started.
+ *
+ * \retval      ALT_E_SUCCESS   Indicates successful completion.
+ * \retval      ALT_E_ERROR     Indicates an error occurred.
+ */
+ALT_STATUS_CODE alt_qspi_indirect_write_finish(void);
+
+/******************************************************************************/
+/*!
+ * Cancel all indirect write transfers in progress.
+ *
+ * \retval      ALT_E_SUCCESS   Indicates successful completion.
+ * \retval      ALT_E_ERROR     Indicates an error occurred.
+ */
+ALT_STATUS_CODE alt_qspi_indirect_write_cancel(void);
+
+/******************************************************************************/
+/*!
+ * Get the current indirect write SRAM fill level value.
+ *
+ * Returns the SRAM fill level for the indirect write partition in units of SRAM
+ * words (4 bytes).
+ *
+ * \returns     The SRAM fill level for the indirect write partition in units of 
+ *              SRAM words (4 bytes).
+ */
+uint32_t alt_qspi_indirect_write_fill_level(void);
+
+/******************************************************************************/
+/*!
+ * Get the current indirect write watermark value.
+ *
+ * The watermark value (in bytes) represents the maximum fill level of the SRAM
+ * before a DMA peripheral access is permitted.  When the SRAM fill level falls
+ * below the watermark, an interrupt is also generated. This can be disabled by
+ * writing a value of all ones.
+ *
+ * \returns     The current indirect write watermark value.
+ */
+uint32_t alt_qspi_indirect_write_watermark_get(void);
+
+/******************************************************************************/
+/*!
+ * Set the indirect write watermark value.
+ *
+ * The watermark value (in bytes) represents the maximum fill level of the SRAM
+ * before a DMA peripheral access is permitted.  When the SRAM fill level falls
+ * below the watermark, an interrupt is also generated. This can be disabled by
+ * writing a value of all ones. The watermark can only be set when no indirect
+ * write is in progress.
+ *
+ * \param       watermark
+ *              The watermark value (in bytes).
+ *
+ * \retval      ALT_E_SUCCESS   Indicates successful completion.
+ * \retval      ALT_E_ERROR     Indicates an error occurred.
+ */
+ALT_STATUS_CODE alt_qspi_indirect_write_watermark_set(const uint32_t watermark);
+
+/******************************************************************************/
+/*!
+ * Returns true when an indirect write has completed otherwise false.
+ *
+ * \internal
+ * Returns Indirect Write Transfer Control Register bit 5 "Indirect Completion
+ * Status".
+ * \endinternal
+ *
+ * \returns     Returns true when an indirect write has completed otherwise
+ *              false.
+ */
+bool alt_qspi_indirect_write_is_complete(void);
+
+/******************************************************************************/
+/*! \addtogroup ALT_QSPI_CFG_SRAM SRAM Partition
+ *
+ * The SRAM local memory buffer is a 128 by 32-bit (512 total bytes) memory. The
+ * SRAM has two partitions, with the lower partition reserved for indirect read
+ * operations and the upper partition for indirect write operations. The size of
+ * the partitions is specified in the SRAM partition register, based on 32-bit
+ * word sizes. For example, to specify four bytes of storage, write the value 1.
+ * The value written to the indirect read partition size field ( addr ) defines
+ * the number of entries reserved for indirect read operations. For example, write
+ * the value 32 (0x20) to partition the 128-entry SRAM to 32 entries (25%) for
+ * read usage and 96 entries (75%) for write usage.
+ *
+ * The functions in this section provide accces to configure the SRAM read
+ * partition allocation.
+ *
+ * @{
+ */
+
+/*!
+ * The size of the onboard SRAM in bytes.
+ */
+#define ALT_QSPI_SRAM_FIFO_SIZE           (512)
+
+/*
+ * The size of the onboard SRAM in entries. Each entry is word (32-bit) sized.
+ */
+#define ALT_QSPI_SRAM_FIFO_ENTRY_COUNT    (512 / sizeof(uint32_t))
+
+/******************************************************************************/
+/*!
+ * Get the entry count (words) of the indirect read partition in the QSPI
+ * controller SRAM.
+ *
+ * There is an additional word of read memory not in the SRAM but used to
+ * buffer the SRAM and the AHB. As such, the total on board memory buffer for
+ * indirect read is 1 more than the value reported by this function.
+ *
+ * \returns     The count of 32-bit words of the indirect read partition in the
+ *              QSPI controller SRAM.
+ *
+ * \internal
+ * The documentation states that the number of locations allocated to indirect
+ * read = SRAM_PARTITION_REG + 1. Cadence clarified that the +1 comes from an
+ * additional register slice for read's, implemented in FLOPs, which was done
+ * to avoid connection the SRAM directly to the AHB interface. This was done
+ * for performance / timing reasons. The +1 will not be included in the return
+ * value but documented as an additional entry.
+ * \endinternal
+ */
+uint32_t alt_qspi_sram_partition_get(void);
+
+/******************************************************************************/
+/*!
+ * Set the entry count (words) of the indirect read partition in the QSPI
+ * controller SRAM.
+ *
+ * Note: It is recommended that setting SRAM partition to 0 or 127 should be
+ * avoided although it is not prohibited.
+ *
+ * \param       read_part_size
+ *              The count of 32-bit words to allocate to the indirect read
+ *              partition in the QSPI controller SRAM.
+ *
+ * \retval      ALT_E_SUCCESS   Indicates successful completion.
+ * \retval      ALT_E_ERROR     Indicates an error occurred.
+ */
+ALT_STATUS_CODE alt_qspi_sram_partition_set(const uint32_t read_part_size);
+
+/*! @} */
+
+/*! @} */
+
+/******************************************************************************/
+/*! \addtogroup ALT_QSPI_ERASE Flash Erase
+ *
+ * The functions in this group are used to erase selected portions of a flash
+ * device.
+ * @{
+ */
+
+/******************************************************************************/
+/*!
+ * This function erases the designated flash device subsector.
+ *
+ * This function erases the flash device subsector containing the designated
+ * flash address. Any address within the subsector is valid.
+ *
+ * \param       addr
+ *              A flash address contained within the the subsector to be erased.
+ *
+ * \retval      ALT_E_SUCCESS   Indicates successful completion.
+ * \retval      ALT_E_ERROR     Indicates an error occurred.
+ */
+ALT_STATUS_CODE alt_qspi_erase_subsector(const uint32_t addr);
+
+/******************************************************************************/
+/*!
+ * This function erases the designated flash device sector.
+ *
+ * This function erases the flash device sector containing the designated flash
+ * address. Any address within the sector is valid.
+ *
+ * \param       addr
+ *              A flash address contained within the the sector to be erased.
+ *
+ * \retval      ALT_E_SUCCESS   Indicates successful completion.
+ * \retval      ALT_E_ERROR     Indicates an error occurred.
+ */
+ALT_STATUS_CODE alt_qspi_erase_sector(const uint32_t addr);
+
+/******************************************************************************/
+/*!
+ * This function erases the entire flash device.
+ *
+ * \retval      ALT_E_SUCCESS   Indicates successful completion.
+ * \retval      ALT_E_ERROR     Indicates an error occurred.
+ */
+ALT_STATUS_CODE alt_qspi_erase_chip(void);
+
+/*! @} */
+
+/******************************************************************************/
+/*! \addtogroup ALT_QSPI_DMA DMA Peripheral Interface
+ *
+ * The DMA peripheral request controller is only used for the indirect mode of
+ * operation where data is temporarily stored in the SRAM. The QSPI flash
+ * controller uses the DMA peripheral request interface to trigger the external
+ * DMA into performing data transfers between memory and the QSPI
+ * controller.
+ *
+ * There are two DMA peripheral request interfaces, one for indirect reads and
+ * one for indirect writes. The DMA peripheral request controller can issue two
+ * types of DMA requests, single or burst, to the external DMA. The number of
+ * bytes for each single or burst request is specified using the
+ * alt_qspi_dma_config_set(). The DMA peripheral request controller splits the
+ * total amount of data to be transferred into a number of DMA burst and single
+ * requests by dividing the total number of bytes by the number of bytes
+ * specified in the burst request, and then dividing the remainder by the number
+ * of bytes in a single request.
+ *
+ * When programming the DMA controller, the burst request size must match the
+ * burst request size set in the quad SPI controller to avoid quickly reaching
+ * an overflow or underflow condition.
+ * @{
+ */
+
+/******************************************************************************/
+/*!
+ * Disable the QSPI DMA peripheral interface.
+ *
+ * \retval      ALT_E_SUCCESS   Indicates successful completion.
+ * \retval      ALT_E_ERROR     Indicates an error occurred.
+ */
+ALT_STATUS_CODE alt_qspi_dma_disable(void);
+
+/******************************************************************************/
+/*!
+ * Enable the QSPI DMA peripheral interface.
+ *
+ * Enable the QSPI DMA handshaking logic. When enabled the QSPI will trigger DMA
+ * transfer requests via the DMA peripheral interface.
+ *
+ * \retval      ALT_E_SUCCESS   Indicates successful completion.
+ * \retval      ALT_E_ERROR     Indicates an error occurred.
+ */
+ALT_STATUS_CODE alt_qspi_dma_enable(void);
+
+/******************************************************************************/
+/*!
+ * Get the current DMA peripheral configuration.
+ *
+ * This function returns the QSPI DMA peripheral interface single and burst type
+ * transfer size configurations.
+ *
+ * \param       single_type_sz
+ *              [out] The number of bytes for each DMA single type
+ *              request. Value must be a power of 2 between 1 and 32728.
+ *
+ * \param       burst_type_sz
+ *              [out] The number of bytes for each DMA burst type request. Value
+ *              must be a power of 2 between 1 and 32728.
+ *
+ * \retval      ALT_E_SUCCESS   Indicates successful completion.
+ * \retval      ALT_E_ERROR     Indicates an error occurred.
+ */
+ALT_STATUS_CODE alt_qspi_dma_config_get(uint32_t * single_type_sz,
+                                        uint32_t * burst_type_sz);
+
+/******************************************************************************/
+/*!
+ * Set the DMA peripheral configuration.
+ *
+ * This function configures the QSPI DMA peripheral interface single and burst
+ * type transfer sizes.  The DMA configruation should be setup while the
+ * controller is idle. Because all transfers are required to be word aligned,
+ * the smallest DMA request is 4 bytes. 
+ *
+ * This API requires that the QSPI controller be idle, as determined by
+ * alt_qspi_is_idle().
+ *
+ * \param       single_type_sz
+ *              The number of bytes for each DMA single type request. Value must
+ *              be a power of 2 between 4 and 32768.
+ *
+ * \param       burst_type_sz
+ *              The number of bytes for each DMA burst type request. Value must
+ *              be a power of 2 between 4 and 32768. Bursts must be equal or
+ *              larger than single requests.
+ *
+ * \retval      ALT_E_SUCCESS   Indicates successful completion.
+ * \retval      ALT_E_ERROR     Indicates an error occurred.
+ */
+ALT_STATUS_CODE alt_qspi_dma_config_set(const uint32_t single_type_sz,
+                                        const uint32_t burst_type_sz);
+
+
+/*! @} */
+
+/*! @} */
+
+#ifdef __cplusplus
+}
+#endif  /* __cplusplus */
+#endif  /* __ALT_QSPI_H__ */
diff --git a/c/src/lib/libbsp/arm/altera-cyclone-v/hwlib/include/alt_qspi_private.h b/c/src/lib/libbsp/arm/altera-cyclone-v/hwlib/include/alt_qspi_private.h
new file mode 100644
index 0000000..21fd3a9
--- /dev/null
+++ b/c/src/lib/libbsp/arm/altera-cyclone-v/hwlib/include/alt_qspi_private.h
@@ -0,0 +1,167 @@
+/******************************************************************************
+ *
+ * Copyright 2013 Altera Corporation. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ ******************************************************************************/
+
+/*! \file
+ *  Altera - QSPI Flash Controller Module
+ */
+
+#ifndef __ALT_QSPI_PRIVATE_H__
+#define __ALT_QSPI_PRIVATE_H__
+
+#include "socal/socal.h"
+
+//
+// This section provisions support for various flash devices.
+//
+
+#define ALT_QSPI_PROVISION_MICRON_N25Q_SUPPORT 1
+
+/////
+
+#define ALT_QSPI_PAGE_ADDR_MSK          0xFFFFFF00
+#define ALT_QSPI_PAGE_SIZE              0x00000100 // 256 B
+#define ALT_QSPI_SUBSECTOR_ADDR_MSK     0xFFFFF000
+#define ALT_QSPI_SUBSECTOR_SIZE         0x00001000 // 4096 B
+#define ALT_QSPI_SECTOR_ADDR_MSK        0xFFFF0000
+#define ALT_QSPI_SECTOR_SIZE            0x00010000 // 64 KiB
+#define ALT_QSPI_BANK_ADDR_MSK          0xFF000000
+#define ALT_QSPI_BANK_SIZE              0x01000000 // 16 MiB
+
+#if ALT_QSPI_PROVISION_MICRON_N25Q_SUPPORT
+#define ALT_QSPI_N25Q_DIE_ADDR_MSK      0xFE000000
+#define ALT_QSPI_N25Q_DIE_SIZE          0x02000000 // 32 MiB
+#endif
+
+/////
+
+// Default delay timing (in ns) for N25Q.
+// These values are from the N25Q handbook. The timing correctness is difficult
+// to test because the test setup does not feature mutliple chips.
+#define ALT_QSPI_TSHSL_NS_DEF       (50)
+#define ALT_QSPI_TSD2D_NS_DEF       (0)
+#define ALT_QSPI_TCHSH_NS_DEF       (4)
+#define ALT_QSPI_TSLCH_NS_DEF       (4)
+
+/*
+// Default delay timing (in ns)
+#define ALT_QSPI_TSHSL_NS_DEF       (200)
+#define ALT_QSPI_TSD2D_NS_DEF       (255)
+#define ALT_QSPI_TCHSH_NS_DEF       (20)
+#define ALT_QSPI_TSLCH_NS_DEF       (20)
+*/
+
+// Flash commands
+#define ALT_QSPI_STIG_OPCODE_READ                 (0x03)
+#define ALT_QSPI_STIG_OPCODE_4BYTE_READ           (0x13)
+#define ALT_QSPI_STIG_OPCODE_FASTREAD             (0x0B)
+#define ALT_QSPI_STIG_OPCODE_FASTREAD_DUAL_OUTPUT (0x3B)
+#define ALT_QSPI_STIG_OPCODE_FASTREAD_QUAD_OUTPUT (0x6B)
+#define ALT_QSPI_STIG_OPCODE_FASTREAD_DUAL_IO     (0xBB)
+#define ALT_QSPI_STIG_OPCODE_FASTREAD_QUAD_IO     (0xEB)
+#define ALT_QSPI_STIG_OPCODE_PP                   (0x02)
+#define ALT_QSPI_STIG_OPCODE_DUAL_PP              (0xA2)
+#define ALT_QSPI_STIG_OPCODE_QUAD_PP              (0x32)
+#define ALT_QSPI_STIG_OPCODE_RDID                 (0x9F)
+#define ALT_QSPI_STIG_OPCODE_WREN                 (0x06)
+#define ALT_QSPI_STIG_OPCODE_WRDIS                (0x04)
+#define ALT_QSPI_STIG_OPCODE_RDSR                 (0x05)
+#define ALT_QSPI_STIG_OPCODE_WRSR                 (0x01)
+#define ALT_QSPI_STIG_OPCODE_SUBSEC_ERASE         (0x20)
+#define ALT_QSPI_STIG_OPCODE_SEC_ERASE            (0xD8)
+#define ALT_QSPI_STIG_OPCODE_BULK_ERASE           (0xC7)
+#define ALT_QSPI_STIG_OPCODE_DIE_ERASE            (0xC4)
+#define ALT_QSPI_STIG_OPCODE_CHIP_ERASE           (0x60)
+#define ALT_QSPI_STIG_OPCODE_RD_EXT_REG           (0xC8)
+#define ALT_QSPI_STIG_OPCODE_WR_EXT_REG           (0xC5)
+#define ALT_QSPI_STIG_OPCODE_RD_STAT_REG          (0x05)
+#define ALT_QSPI_STIG_OPCODE_WR_STAT_REG          (0x01)
+#define ALT_QSPI_STIG_OPCODE_ENTER_4BYTE_MODE     (0xB7)
+#define ALT_QSPI_STIG_OPCODE_EXIT_4BYTE_MODE      (0xE9)
+
+// Micron commands, for 512 Mib, 1 Gib (64 MiB, 128 MiB) parts.
+#if ALT_QSPI_PROVISION_MICRON_N25Q_SUPPORT
+#define ALT_QSPI_STIG_OPCODE_RESET_EN             (0x66)
+#define ALT_QSPI_STIG_OPCODE_RESET_MEM            (0x99)
+#define ALT_QSPI_STIG_OPCODE_RDFLGSR              (0x70)
+#define ALT_QSPI_STIG_OPCODE_CLRFLGSR             (0x50)
+#define ALT_QSPI_STIG_OPCODE_DISCVR_PARAM         (0x5A)
+#endif
+
+// Spansion commands
+// #define OPCODE_ECRM                 (0xFF) // Exit continuous read mode
+
+#define QSPI_READ_CLK_MHZ           (50)
+#define QSPI_FASTREAD_CLK_MHZ       (100)
+
+// Manufacturer ID
+#define ALT_QSPI_STIG_RDID_JEDECID_MICRON      (0x20)
+#define ALT_QSPI_STIG_RDID_JEDECID_NUMONYX     (0x20) // Same as Micron
+#define ALT_QSPI_STIG_RDID_JEDECID_SPANSION    (0xEF)
+#define ALT_QSPI_STIG_RDID_JEDECID_WINBOND     (0xEF) // Same as Spansion
+#define ALT_QSPI_STIG_RDID_JEDECID_MACRONIC    (0xC2)
+#define ALT_QSPI_STIG_RDID_JEDECID_ATMEL       (0x1F)
+
+#define ALT_QSPI_STIG_RDID_JEDECID_GET(value)    ((value >>  0) & 0xff)
+#define ALT_QSPI_STIG_RDID_CAPACITYID_GET(value) ((value >> 16) & 0xff)
+
+#define ALT_QSPI_STIG_FLAGSR_ERASEPROGRAMREADY_GET(value) ((value >> 7) & 0x1)
+#define ALT_QSPI_STIG_FLAGSR_ERASEREADY_GET(value)        ((value >> 7) & 0x1)
+#define ALT_QSPI_STIG_FLAGSR_PROGRAMREADY_GET(value)      ((value >> 7) & 0x1)
+#define ALT_QSPI_STIG_FLAGSR_ERASEERROR_GET(value)        ((value >> 5) & 0x1)
+#define ALT_QSPI_STIG_FLAGSR_PROGRAMERROR_GET(value)      ((value >> 4) & 0x1)
+#define ALT_QSPI_STIG_FLAGSR_ADDRESSINGMODE_GET(value)    ((value >> 1) & 0x1)
+#define ALT_QSPI_STIG_FLAGSR_PROTECTIONERROR_GET(value)   ((value >> 0) & 0x1)
+
+#define ALT_QSPI_STIG_SR_BUSY_GET(value)       		  	  ((value >> 0) & 0x1)
+
+/////
+
+#define ALT_QSPI_TIMEOUT_INFINITE (0xffffffff)
+
+ALT_STATUS_CODE alt_qspi_replace(uint32_t dst, const void * src, size_t size);
+
+ALT_STATUS_CODE alt_qspi_stig_cmd(uint32_t opcode, uint32_t dummy, uint32_t timeout);
+ALT_STATUS_CODE alt_qspi_stig_rd_cmd(uint8_t opcode, uint32_t dummy,
+                                     uint32_t num_bytes, uint32_t * output,
+                                     uint32_t timeout);
+ALT_STATUS_CODE alt_qspi_stig_wr_cmd(uint8_t opcode, uint32_t dummy,
+                                     uint32_t num_bytes, const uint32_t * input,
+                                     uint32_t timeout);
+ALT_STATUS_CODE alt_qspi_stig_addr_cmd(uint8_t opcode, uint32_t dummy,
+                                       uint32_t address,
+                                       uint32_t timeout);
+
+ALT_STATUS_CODE alt_qspi_device_wren(void);
+ALT_STATUS_CODE alt_qspi_device_wrdis(void);
+ALT_STATUS_CODE alt_qspi_device_rdid(uint32_t * rdid);
+ALT_STATUS_CODE alt_qspi_discovery_parameter(uint32_t * param);
+ALT_STATUS_CODE alt_qspi_device_bank_select(uint32_t bank);
+
+#endif // __ALT_PRIVATE_QSPI_H__
diff --git a/c/src/lib/libbsp/arm/altera-cyclone-v/hwlib/include/socal/alt_dmanonsecure.h b/c/src/lib/libbsp/arm/altera-cyclone-v/hwlib/include/socal/alt_dmanonsecure.h
new file mode 100644
index 0000000..1425708
--- /dev/null
+++ b/c/src/lib/libbsp/arm/altera-cyclone-v/hwlib/include/socal/alt_dmanonsecure.h
@@ -0,0 +1,144 @@
+/*******************************************************************************
+*                                                                              *
+* Copyright 2013 Altera Corporation. All Rights Reserved.                      *
+*                                                                              *
+* Redistribution and use in source and binary forms, with or without           *
+* modification, are permitted provided that the following conditions are met:  *
+*                                                                              *
+* 1. Redistributions of source code must retain the above copyright notice,    *
+*    this list of conditions and the following disclaimer.                     *
+*                                                                              *
+* 2. Redistributions in binary form must reproduce the above copyright notice, *
+*    this list of conditions and the following disclaimer in the documentation *
+*    and/or other materials provided with the distribution.                    *
+*                                                                              *
+* 3. The name of the author may not be used to endorse or promote products     *
+*    derived from this software without specific prior written permission.     *
+*                                                                              *
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY EXPRESS OR *
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
+* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED. IN NO  *
+* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,       *
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
+* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;  *
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,     *
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR      *
+* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF       *
+* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                                   *
+*                                                                              *
+*******************************************************************************/
+
+/* Altera - ALT_DMANONSECURE */
+
+#ifndef __ALTERA_ALT_DMANONSECURE_H__
+#define __ALTERA_ALT_DMANONSECURE_H__
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif  /* __cplusplus */
+
+/*
+ * Component : nonsecure DMA Module Address Space - ALT_DMANONSECURE
+ * nonsecure DMA Module Address Space
+ * 
+ * Address space allocated to the nonsecure DMA. For detailed information about the
+ * use of this address space,
+ * [url=http://infocenter.arm.com/help/topic/com.arm.doc.ddi0424b/index.html]click
+ * here[/url] to access the ARM documentation for the DMA-330.
+ * 
+ */
+/*
+ * Register : Empty - reg
+ * 
+ * Placeholder
+ * 
+ * Register Layout
+ * 
+ *  Bits   | Access | Reset   | Description
+ * :-------|:-------|:--------|:------------
+ *  [31:0] | RW     | Unknown | Empty      
+ * 
+ */
+/*
+ * Field : Empty - fld
+ * 
+ * Placeholder
+ * 
+ * Field Access Macros:
+ * 
+ */
+/* The Least Significant Bit (LSB) position of the ALT_DMANONSECURE_REG_FLD register field. */
+#define ALT_DMANONSECURE_REG_FLD_LSB        0
+/* The Most Significant Bit (MSB) position of the ALT_DMANONSECURE_REG_FLD register field. */
+#define ALT_DMANONSECURE_REG_FLD_MSB        31
+/* The width in bits of the ALT_DMANONSECURE_REG_FLD register field. */
+#define ALT_DMANONSECURE_REG_FLD_WIDTH      32
+/* The mask used to set the ALT_DMANONSECURE_REG_FLD register field value. */
+#define ALT_DMANONSECURE_REG_FLD_SET_MSK    0xffffffff
+/* The mask used to clear the ALT_DMANONSECURE_REG_FLD register field value. */
+#define ALT_DMANONSECURE_REG_FLD_CLR_MSK    0x00000000
+/* The reset value of the ALT_DMANONSECURE_REG_FLD register field is UNKNOWN. */
+#define ALT_DMANONSECURE_REG_FLD_RESET      0x0
+/* Extracts the ALT_DMANONSECURE_REG_FLD field value from a register. */
+#define ALT_DMANONSECURE_REG_FLD_GET(value) (((value) & 0xffffffff) >> 0)
+/* Produces a ALT_DMANONSECURE_REG_FLD register field value suitable for setting the register. */
+#define ALT_DMANONSECURE_REG_FLD_SET(value) (((value) << 0) & 0xffffffff)
+
+#ifndef __ASSEMBLY__
+/*
+ * WARNING: The C register and register group struct declarations are provided for
+ * convenience and illustrative purposes. They should, however, be used with
+ * caution as the C language standard provides no guarantees about the alignment or
+ * atomicity of device memory accesses. The recommended practice for writing
+ * hardware drivers is to use the SoCAL access macros and alt_read_word() and
+ * alt_write_word() functions.
+ * 
+ * The struct declaration for register ALT_DMANONSECURE_REG.
+ */
+struct ALT_DMANONSECURE_REG_s
+{
+    uint32_t  fld : 32;  /* Empty */
+};
+
+/* The typedef declaration for register ALT_DMANONSECURE_REG. */
+typedef volatile struct ALT_DMANONSECURE_REG_s  ALT_DMANONSECURE_REG_t;
+#endif  /* __ASSEMBLY__ */
+
+/* The byte offset of the ALT_DMANONSECURE_REG register from the beginning of the component. */
+#define ALT_DMANONSECURE_REG_OFST        0x0
+
+#ifndef __ASSEMBLY__
+/*
+ * WARNING: The C register and register group struct declarations are provided for
+ * convenience and illustrative purposes. They should, however, be used with
+ * caution as the C language standard provides no guarantees about the alignment or
+ * atomicity of device memory accesses. The recommended practice for writing
+ * hardware drivers is to use the SoCAL access macros and alt_read_word() and
+ * alt_write_word() functions.
+ * 
+ * The struct declaration for register group ALT_DMANONSECURE.
+ */
+struct ALT_DMANONSECURE_s
+{
+    volatile ALT_DMANONSECURE_REG_t  reg;  /* ALT_DMANONSECURE_REG */
+};
+
+/* The typedef declaration for register group ALT_DMANONSECURE. */
+typedef volatile struct ALT_DMANONSECURE_s  ALT_DMANONSECURE_t;
+/* The struct declaration for the raw register contents of register group ALT_DMANONSECURE. */
+struct ALT_DMANONSECURE_raw_s
+{
+    volatile uint32_t  reg;  /* ALT_DMANONSECURE_REG */
+};
+
+/* The typedef declaration for the raw register contents of register group ALT_DMANONSECURE. */
+typedef volatile struct ALT_DMANONSECURE_raw_s  ALT_DMANONSECURE_raw_t;
+#endif  /* __ASSEMBLY__ */
+
+
+#ifdef __cplusplus
+}
+#endif  /* __cplusplus */
+#endif  /* __ALTERA_ALT_DMANONSECURE_H__ */
+
diff --git a/c/src/lib/libbsp/arm/altera-cyclone-v/hwlib/include/socal/alt_dmasecure.h b/c/src/lib/libbsp/arm/altera-cyclone-v/hwlib/include/socal/alt_dmasecure.h
new file mode 100644
index 0000000..5941433
--- /dev/null
+++ b/c/src/lib/libbsp/arm/altera-cyclone-v/hwlib/include/socal/alt_dmasecure.h
@@ -0,0 +1,144 @@
+/*******************************************************************************
+*                                                                              *
+* Copyright 2013 Altera Corporation. All Rights Reserved.                      *
+*                                                                              *
+* Redistribution and use in source and binary forms, with or without           *
+* modification, are permitted provided that the following conditions are met:  *
+*                                                                              *
+* 1. Redistributions of source code must retain the above copyright notice,    *
+*    this list of conditions and the following disclaimer.                     *
+*                                                                              *
+* 2. Redistributions in binary form must reproduce the above copyright notice, *
+*    this list of conditions and the following disclaimer in the documentation *
+*    and/or other materials provided with the distribution.                    *
+*                                                                              *
+* 3. The name of the author may not be used to endorse or promote products     *
+*    derived from this software without specific prior written permission.     *
+*                                                                              *
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY EXPRESS OR *
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
+* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED. IN NO  *
+* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,       *
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
+* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;  *
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,     *
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR      *
+* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF       *
+* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                                   *
+*                                                                              *
+*******************************************************************************/
+
+/* Altera - ALT_DMASECURE */
+
+#ifndef __ALTERA_ALT_DMASECURE_H__
+#define __ALTERA_ALT_DMASECURE_H__
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif  /* __cplusplus */
+
+/*
+ * Component : secure DMA Module Address Space - ALT_DMASECURE
+ * secure DMA Module Address Space
+ * 
+ * Address space allocated to the secure DMA. For detailed information about the
+ * use of this address space,
+ * [url=http://infocenter.arm.com/help/topic/com.arm.doc.ddi0424b/index.html]click
+ * here[/url] to access the ARM documentation for the DMA-330.
+ * 
+ */
+/*
+ * Register : Empty - reg
+ * 
+ * Placeholder
+ * 
+ * Register Layout
+ * 
+ *  Bits   | Access | Reset   | Description
+ * :-------|:-------|:--------|:------------
+ *  [31:0] | RW     | Unknown | Empty      
+ * 
+ */
+/*
+ * Field : Empty - fld
+ * 
+ * Placeholder
+ * 
+ * Field Access Macros:
+ * 
+ */
+/* The Least Significant Bit (LSB) position of the ALT_DMASECURE_REG_FLD register field. */
+#define ALT_DMASECURE_REG_FLD_LSB        0
+/* The Most Significant Bit (MSB) position of the ALT_DMASECURE_REG_FLD register field. */
+#define ALT_DMASECURE_REG_FLD_MSB        31
+/* The width in bits of the ALT_DMASECURE_REG_FLD register field. */
+#define ALT_DMASECURE_REG_FLD_WIDTH      32
+/* The mask used to set the ALT_DMASECURE_REG_FLD register field value. */
+#define ALT_DMASECURE_REG_FLD_SET_MSK    0xffffffff
+/* The mask used to clear the ALT_DMASECURE_REG_FLD register field value. */
+#define ALT_DMASECURE_REG_FLD_CLR_MSK    0x00000000
+/* The reset value of the ALT_DMASECURE_REG_FLD register field is UNKNOWN. */
+#define ALT_DMASECURE_REG_FLD_RESET      0x0
+/* Extracts the ALT_DMASECURE_REG_FLD field value from a register. */
+#define ALT_DMASECURE_REG_FLD_GET(value) (((value) & 0xffffffff) >> 0)
+/* Produces a ALT_DMASECURE_REG_FLD register field value suitable for setting the register. */
+#define ALT_DMASECURE_REG_FLD_SET(value) (((value) << 0) & 0xffffffff)
+
+#ifndef __ASSEMBLY__
+/*
+ * WARNING: The C register and register group struct declarations are provided for
+ * convenience and illustrative purposes. They should, however, be used with
+ * caution as the C language standard provides no guarantees about the alignment or
+ * atomicity of device memory accesses. The recommended practice for writing
+ * hardware drivers is to use the SoCAL access macros and alt_read_word() and
+ * alt_write_word() functions.
+ * 
+ * The struct declaration for register ALT_DMASECURE_REG.
+ */
+struct ALT_DMASECURE_REG_s
+{
+    uint32_t  fld : 32;  /* Empty */
+};
+
+/* The typedef declaration for register ALT_DMASECURE_REG. */
+typedef volatile struct ALT_DMASECURE_REG_s  ALT_DMASECURE_REG_t;
+#endif  /* __ASSEMBLY__ */
+
+/* The byte offset of the ALT_DMASECURE_REG register from the beginning of the component. */
+#define ALT_DMASECURE_REG_OFST        0x0
+
+#ifndef __ASSEMBLY__
+/*
+ * WARNING: The C register and register group struct declarations are provided for
+ * convenience and illustrative purposes. They should, however, be used with
+ * caution as the C language standard provides no guarantees about the alignment or
+ * atomicity of device memory accesses. The recommended practice for writing
+ * hardware drivers is to use the SoCAL access macros and alt_read_word() and
+ * alt_write_word() functions.
+ * 
+ * The struct declaration for register group ALT_DMASECURE.
+ */
+struct ALT_DMASECURE_s
+{
+    volatile ALT_DMASECURE_REG_t  reg;  /* ALT_DMASECURE_REG */
+};
+
+/* The typedef declaration for register group ALT_DMASECURE. */
+typedef volatile struct ALT_DMASECURE_s  ALT_DMASECURE_t;
+/* The struct declaration for the raw register contents of register group ALT_DMASECURE. */
+struct ALT_DMASECURE_raw_s
+{
+    volatile uint32_t  reg;  /* ALT_DMASECURE_REG */
+};
+
+/* The typedef declaration for the raw register contents of register group ALT_DMASECURE. */
+typedef volatile struct ALT_DMASECURE_raw_s  ALT_DMASECURE_raw_t;
+#endif  /* __ASSEMBLY__ */
+
+
+#ifdef __cplusplus
+}
+#endif  /* __cplusplus */
+#endif  /* __ALTERA_ALT_DMASECURE_H__ */
+
diff --git a/c/src/lib/libbsp/arm/altera-cyclone-v/hwlib/include/socal/alt_qspi.h b/c/src/lib/libbsp/arm/altera-cyclone-v/hwlib/include/socal/alt_qspi.h
new file mode 100644
index 0000000..cbec31b
--- /dev/null
+++ b/c/src/lib/libbsp/arm/altera-cyclone-v/hwlib/include/socal/alt_qspi.h
@@ -0,0 +1,5951 @@
+/*******************************************************************************
+*                                                                              *
+* Copyright 2013 Altera Corporation. All Rights Reserved.                      *
+*                                                                              *
+* Redistribution and use in source and binary forms, with or without           *
+* modification, are permitted provided that the following conditions are met:  *
+*                                                                              *
+* 1. Redistributions of source code must retain the above copyright notice,    *
+*    this list of conditions and the following disclaimer.                     *
+*                                                                              *
+* 2. Redistributions in binary form must reproduce the above copyright notice, *
+*    this list of conditions and the following disclaimer in the documentation *
+*    and/or other materials provided with the distribution.                    *
+*                                                                              *
+* 3. The name of the author may not be used to endorse or promote products     *
+*    derived from this software without specific prior written permission.     *
+*                                                                              *
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY EXPRESS OR *
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
+* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED. IN NO  *
+* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,       *
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
+* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;  *
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,     *
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR      *
+* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF       *
+* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                                   *
+*                                                                              *
+*******************************************************************************/
+
+/* Altera - ALT_QSPI */
+
+#ifndef __ALTERA_ALT_QSPI_H__
+#define __ALTERA_ALT_QSPI_H__
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif  /* __cplusplus */
+
+/*
+ * Component : QSPI Flash Controller Module Registers - ALT_QSPI
+ * QSPI Flash Controller Module Registers
+ * 
+ * Registers in the QSPI Flash Controller module accessible via its APB slave
+ * 
+ */
+/*
+ * Register : QSPI Configuration Register - cfg
+ * 
+ * Register Layout
+ * 
+ *  Bits    | Access | Reset | Description                               
+ * :--------|:-------|:------|:-------------------------------------------
+ *  [0]     | RW     | 0x0   | QSPI Enable                               
+ *  [1]     | RW     | 0x0   | Clock Polarity                            
+ *  [2]     | RW     | 0x0   | Select Clock Phase                        
+ *  [6:3]   | ???    | 0x0   | *UNDEFINED*                               
+ *  [7]     | RW     | 0x0   | Enable Direct Access Controller           
+ *  [8]     | RW     | 0x0   | Legacy IP Mode Enable                     
+ *  [9]     | RW     | 0x0   | Peripheral select decode                  
+ *  [13:10] | RW     | 0x0   | Peripheral Chip Select Lines              
+ *  [14]    | RW     | 0x0   | Write Protect Flash Pin                   
+ *  [15]    | RW     | 0x0   | Enable DMA Peripheral Interface           
+ *  [16]    | RW     | 0x0   | Enable AHB Address Re-mapping             
+ *  [17]    | RW     | 0x0   | Enter XIP Mode on next READ               
+ *  [18]    | RW     | 0x0   | Enter XIP Mode Immediately                
+ *  [22:19] | RW     | 0xf   | Master Mode Baud Rate Divisor             
+ *  [30:23] | ???    | 0x0   | *UNDEFINED*                               
+ *  [31]    | R      | 0x0   | Serial interface and QSPI pipeline is IDLE
+ * 
+ */
+/*
+ * Field : QSPI Enable - en
+ * 
+ * If this bit is disabled, the QSPI will finish the current transfer of the data
+ * word (FF_W) and stop sending. When Enabled, and qspi_n_mo_en = 0, all output
+ * enables are inactive and all pins are set to input mode.
+ * 
+ * Field Enumeration Values:
+ * 
+ *  Enum                  | Value | Description     
+ * :----------------------|:------|:-----------------
+ *  ALT_QSPI_CFG_EN_E_DIS | 0x0   | Disable the QSPI
+ *  ALT_QSPI_CFG_EN_E_EN  | 0x1   | Enable the QSPI 
+ * 
+ * Field Access Macros:
+ * 
+ */
+/*
+ * Enumerated value for register field ALT_QSPI_CFG_EN
+ * 
+ * Disable the QSPI
+ */
+#define ALT_QSPI_CFG_EN_E_DIS   0x0
+/*
+ * Enumerated value for register field ALT_QSPI_CFG_EN
+ * 
+ * Enable the QSPI
+ */
+#define ALT_QSPI_CFG_EN_E_EN    0x1
+
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_CFG_EN register field. */
+#define ALT_QSPI_CFG_EN_LSB        0
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_CFG_EN register field. */
+#define ALT_QSPI_CFG_EN_MSB        0
+/* The width in bits of the ALT_QSPI_CFG_EN register field. */
+#define ALT_QSPI_CFG_EN_WIDTH      1
+/* The mask used to set the ALT_QSPI_CFG_EN register field value. */
+#define ALT_QSPI_CFG_EN_SET_MSK    0x00000001
+/* The mask used to clear the ALT_QSPI_CFG_EN register field value. */
+#define ALT_QSPI_CFG_EN_CLR_MSK    0xfffffffe
+/* The reset value of the ALT_QSPI_CFG_EN register field. */
+#define ALT_QSPI_CFG_EN_RESET      0x0
+/* Extracts the ALT_QSPI_CFG_EN field value from a register. */
+#define ALT_QSPI_CFG_EN_GET(value) (((value) & 0x00000001) >> 0)
+/* Produces a ALT_QSPI_CFG_EN register field value suitable for setting the register. */
+#define ALT_QSPI_CFG_EN_SET(value) (((value) << 0) & 0x00000001)
+
+/*
+ * Field : Clock Polarity - selclkpol
+ * 
+ * Controls spiclk modes of operation.
+ * 
+ * Field Enumeration Values:
+ * 
+ *  Enum                          | Value | Description                
+ * :------------------------------|:------|:----------------------------
+ *  ALT_QSPI_CFG_SELCLKPOL_E_LOW  | 0x1   | SPI clock is quiescent low 
+ *  ALT_QSPI_CFG_SELCLKPOL_E_HIGH | 0x0   | SPI clock is quiescent high
+ * 
+ * Field Access Macros:
+ * 
+ */
+/*
+ * Enumerated value for register field ALT_QSPI_CFG_SELCLKPOL
+ * 
+ * SPI clock is quiescent low
+ */
+#define ALT_QSPI_CFG_SELCLKPOL_E_LOW    0x1
+/*
+ * Enumerated value for register field ALT_QSPI_CFG_SELCLKPOL
+ * 
+ * SPI clock is quiescent high
+ */
+#define ALT_QSPI_CFG_SELCLKPOL_E_HIGH   0x0
+
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_CFG_SELCLKPOL register field. */
+#define ALT_QSPI_CFG_SELCLKPOL_LSB        1
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_CFG_SELCLKPOL register field. */
+#define ALT_QSPI_CFG_SELCLKPOL_MSB        1
+/* The width in bits of the ALT_QSPI_CFG_SELCLKPOL register field. */
+#define ALT_QSPI_CFG_SELCLKPOL_WIDTH      1
+/* The mask used to set the ALT_QSPI_CFG_SELCLKPOL register field value. */
+#define ALT_QSPI_CFG_SELCLKPOL_SET_MSK    0x00000002
+/* The mask used to clear the ALT_QSPI_CFG_SELCLKPOL register field value. */
+#define ALT_QSPI_CFG_SELCLKPOL_CLR_MSK    0xfffffffd
+/* The reset value of the ALT_QSPI_CFG_SELCLKPOL register field. */
+#define ALT_QSPI_CFG_SELCLKPOL_RESET      0x0
+/* Extracts the ALT_QSPI_CFG_SELCLKPOL field value from a register. */
+#define ALT_QSPI_CFG_SELCLKPOL_GET(value) (((value) & 0x00000002) >> 1)
+/* Produces a ALT_QSPI_CFG_SELCLKPOL register field value suitable for setting the register. */
+#define ALT_QSPI_CFG_SELCLKPOL_SET(value) (((value) << 1) & 0x00000002)
+
+/*
+ * Field : Select Clock Phase - selclkphase
+ * 
+ * Selects whether the clock is in an active or inactive phase outside the SPI
+ * word.
+ * 
+ * Field Enumeration Values:
+ * 
+ *  Enum                             | Value | Description               
+ * :---------------------------------|:------|:---------------------------
+ *  ALT_QSPI_CFG_SELCLKPHASE_E_ACT   | 0x0   | SPI clock is quiescent low
+ *  ALT_QSPI_CFG_SELCLKPHASE_E_INACT | 0x1   | Clock Inactive            
+ * 
+ * Field Access Macros:
+ * 
+ */
+/*
+ * Enumerated value for register field ALT_QSPI_CFG_SELCLKPHASE
+ * 
+ * SPI clock is quiescent low
+ */
+#define ALT_QSPI_CFG_SELCLKPHASE_E_ACT      0x0
+/*
+ * Enumerated value for register field ALT_QSPI_CFG_SELCLKPHASE
+ * 
+ * Clock Inactive
+ */
+#define ALT_QSPI_CFG_SELCLKPHASE_E_INACT    0x1
+
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_CFG_SELCLKPHASE register field. */
+#define ALT_QSPI_CFG_SELCLKPHASE_LSB        2
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_CFG_SELCLKPHASE register field. */
+#define ALT_QSPI_CFG_SELCLKPHASE_MSB        2
+/* The width in bits of the ALT_QSPI_CFG_SELCLKPHASE register field. */
+#define ALT_QSPI_CFG_SELCLKPHASE_WIDTH      1
+/* The mask used to set the ALT_QSPI_CFG_SELCLKPHASE register field value. */
+#define ALT_QSPI_CFG_SELCLKPHASE_SET_MSK    0x00000004
+/* The mask used to clear the ALT_QSPI_CFG_SELCLKPHASE register field value. */
+#define ALT_QSPI_CFG_SELCLKPHASE_CLR_MSK    0xfffffffb
+/* The reset value of the ALT_QSPI_CFG_SELCLKPHASE register field. */
+#define ALT_QSPI_CFG_SELCLKPHASE_RESET      0x0
+/* Extracts the ALT_QSPI_CFG_SELCLKPHASE field value from a register. */
+#define ALT_QSPI_CFG_SELCLKPHASE_GET(value) (((value) & 0x00000004) >> 2)
+/* Produces a ALT_QSPI_CFG_SELCLKPHASE register field value suitable for setting the register. */
+#define ALT_QSPI_CFG_SELCLKPHASE_SET(value) (((value) << 2) & 0x00000004)
+
+/*
+ * Field : Enable Direct Access Controller - endiracc
+ * 
+ * If disabled, the Direct Access Controller becomes inactive once the current
+ * transfer of the data word (FF_W) is complete. When the Direct Access Controller
+ * and Indirect Access Controller are both disabled, all AHB requests are completed
+ * with an error response.
+ * 
+ * Field Enumeration Values:
+ * 
+ *  Enum                        | Value | Description               
+ * :----------------------------|:------|:---------------------------
+ *  ALT_QSPI_CFG_ENDIRACC_E_DIS | 0x0   | Disable Direct Access Ctrl
+ *  ALT_QSPI_CFG_ENDIRACC_E_EN  | 0x1   | Enable Direct Access Ctrl 
+ * 
+ * Field Access Macros:
+ * 
+ */
+/*
+ * Enumerated value for register field ALT_QSPI_CFG_ENDIRACC
+ * 
+ * Disable Direct Access Ctrl
+ */
+#define ALT_QSPI_CFG_ENDIRACC_E_DIS 0x0
+/*
+ * Enumerated value for register field ALT_QSPI_CFG_ENDIRACC
+ * 
+ * Enable Direct Access Ctrl
+ */
+#define ALT_QSPI_CFG_ENDIRACC_E_EN  0x1
+
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_CFG_ENDIRACC register field. */
+#define ALT_QSPI_CFG_ENDIRACC_LSB        7
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_CFG_ENDIRACC register field. */
+#define ALT_QSPI_CFG_ENDIRACC_MSB        7
+/* The width in bits of the ALT_QSPI_CFG_ENDIRACC register field. */
+#define ALT_QSPI_CFG_ENDIRACC_WIDTH      1
+/* The mask used to set the ALT_QSPI_CFG_ENDIRACC register field value. */
+#define ALT_QSPI_CFG_ENDIRACC_SET_MSK    0x00000080
+/* The mask used to clear the ALT_QSPI_CFG_ENDIRACC register field value. */
+#define ALT_QSPI_CFG_ENDIRACC_CLR_MSK    0xffffff7f
+/* The reset value of the ALT_QSPI_CFG_ENDIRACC register field. */
+#define ALT_QSPI_CFG_ENDIRACC_RESET      0x0
+/* Extracts the ALT_QSPI_CFG_ENDIRACC field value from a register. */
+#define ALT_QSPI_CFG_ENDIRACC_GET(value) (((value) & 0x00000080) >> 7)
+/* Produces a ALT_QSPI_CFG_ENDIRACC register field value suitable for setting the register. */
+#define ALT_QSPI_CFG_ENDIRACC_SET(value) (((value) << 7) & 0x00000080)
+
+/*
+ * Field : Legacy IP Mode Enable - enlegacyip
+ * 
+ * This bit can select the Direct Access Controller/Indirect Access Controller or
+ * legacy mode.If legacy mode is selected, any write to the controller via the AHB
+ * interface is serialized and sent to the FLASH device. Any valid AHB read will
+ * pop the internal RX-FIFO, retrieving data that was forwarded by the external
+ * FLASH device on the SPI lines, byte transfers of 4, 2 or 1 are permitted and
+ * controlled via the HSIZE input.
+ * 
+ * Field Enumeration Values:
+ * 
+ *  Enum                             | Value | Description                          
+ * :---------------------------------|:------|:--------------------------------------
+ *  ALT_QSPI_CFG_ENLEGACYIP_E_LEGMOD | 0x1   | Legacy Mode                          
+ *  ALT_QSPI_CFG_ENLEGACYIP_E_DIMOD  | 0x0   | Use Direct/Indirect Access Controller
+ * 
+ * Field Access Macros:
+ * 
+ */
+/*
+ * Enumerated value for register field ALT_QSPI_CFG_ENLEGACYIP
+ * 
+ * Legacy Mode
+ */
+#define ALT_QSPI_CFG_ENLEGACYIP_E_LEGMOD    0x1
+/*
+ * Enumerated value for register field ALT_QSPI_CFG_ENLEGACYIP
+ * 
+ * Use Direct/Indirect Access Controller
+ */
+#define ALT_QSPI_CFG_ENLEGACYIP_E_DIMOD     0x0
+
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_CFG_ENLEGACYIP register field. */
+#define ALT_QSPI_CFG_ENLEGACYIP_LSB        8
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_CFG_ENLEGACYIP register field. */
+#define ALT_QSPI_CFG_ENLEGACYIP_MSB        8
+/* The width in bits of the ALT_QSPI_CFG_ENLEGACYIP register field. */
+#define ALT_QSPI_CFG_ENLEGACYIP_WIDTH      1
+/* The mask used to set the ALT_QSPI_CFG_ENLEGACYIP register field value. */
+#define ALT_QSPI_CFG_ENLEGACYIP_SET_MSK    0x00000100
+/* The mask used to clear the ALT_QSPI_CFG_ENLEGACYIP register field value. */
+#define ALT_QSPI_CFG_ENLEGACYIP_CLR_MSK    0xfffffeff
+/* The reset value of the ALT_QSPI_CFG_ENLEGACYIP register field. */
+#define ALT_QSPI_CFG_ENLEGACYIP_RESET      0x0
+/* Extracts the ALT_QSPI_CFG_ENLEGACYIP field value from a register. */
+#define ALT_QSPI_CFG_ENLEGACYIP_GET(value) (((value) & 0x00000100) >> 8)
+/* Produces a ALT_QSPI_CFG_ENLEGACYIP register field value suitable for setting the register. */
+#define ALT_QSPI_CFG_ENLEGACYIP_SET(value) (((value) << 8) & 0x00000100)
+
+/*
+ * Field : Peripheral select decode - perseldec
+ * 
+ * Select between '1 of 4 selects' or 'external 4-to-16 decode'. The
+ * qspi_n_ss_out[3:0] output signals are controlled.
+ * 
+ * Field Enumeration Values:
+ * 
+ *  Enum                              | Value | Description                      
+ * :----------------------------------|:------|:----------------------------------
+ *  ALT_QSPI_CFG_PERSELDEC_E_SEL4TO16 | 0x1   | Select external 4-to-16 decode   
+ *  ALT_QSPI_CFG_PERSELDEC_E_SEL1OF4  | 0x0   | Selects 1 of 4 qspi_n_ss_out[3:0]
+ * 
+ * Field Access Macros:
+ * 
+ */
+/*
+ * Enumerated value for register field ALT_QSPI_CFG_PERSELDEC
+ * 
+ * Select external 4-to-16 decode
+ */
+#define ALT_QSPI_CFG_PERSELDEC_E_SEL4TO16   0x1
+/*
+ * Enumerated value for register field ALT_QSPI_CFG_PERSELDEC
+ * 
+ * Selects 1 of 4 qspi_n_ss_out[3:0]
+ */
+#define ALT_QSPI_CFG_PERSELDEC_E_SEL1OF4    0x0
+
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_CFG_PERSELDEC register field. */
+#define ALT_QSPI_CFG_PERSELDEC_LSB        9
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_CFG_PERSELDEC register field. */
+#define ALT_QSPI_CFG_PERSELDEC_MSB        9
+/* The width in bits of the ALT_QSPI_CFG_PERSELDEC register field. */
+#define ALT_QSPI_CFG_PERSELDEC_WIDTH      1
+/* The mask used to set the ALT_QSPI_CFG_PERSELDEC register field value. */
+#define ALT_QSPI_CFG_PERSELDEC_SET_MSK    0x00000200
+/* The mask used to clear the ALT_QSPI_CFG_PERSELDEC register field value. */
+#define ALT_QSPI_CFG_PERSELDEC_CLR_MSK    0xfffffdff
+/* The reset value of the ALT_QSPI_CFG_PERSELDEC register field. */
+#define ALT_QSPI_CFG_PERSELDEC_RESET      0x0
+/* Extracts the ALT_QSPI_CFG_PERSELDEC field value from a register. */
+#define ALT_QSPI_CFG_PERSELDEC_GET(value) (((value) & 0x00000200) >> 9)
+/* Produces a ALT_QSPI_CFG_PERSELDEC register field value suitable for setting the register. */
+#define ALT_QSPI_CFG_PERSELDEC_SET(value) (((value) << 9) & 0x00000200)
+
+/*
+ * Field : Peripheral Chip Select Lines - percslines
+ * 
+ * Peripheral chip select line output decode type. As per perseldec, if perseldec =
+ * 0, the decode is select 1 of 4 decoding on signals, qspi_n_ss_out[3:0], The
+ * asserted decode line goes to 0. If perseldec = 1, the signals qspi_n_ss_out[3:0]
+ * require an external 4 to 16 decoder.
+ * 
+ * Field Access Macros:
+ * 
+ */
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_CFG_PERCSLINES register field. */
+#define ALT_QSPI_CFG_PERCSLINES_LSB        10
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_CFG_PERCSLINES register field. */
+#define ALT_QSPI_CFG_PERCSLINES_MSB        13
+/* The width in bits of the ALT_QSPI_CFG_PERCSLINES register field. */
+#define ALT_QSPI_CFG_PERCSLINES_WIDTH      4
+/* The mask used to set the ALT_QSPI_CFG_PERCSLINES register field value. */
+#define ALT_QSPI_CFG_PERCSLINES_SET_MSK    0x00003c00
+/* The mask used to clear the ALT_QSPI_CFG_PERCSLINES register field value. */
+#define ALT_QSPI_CFG_PERCSLINES_CLR_MSK    0xffffc3ff
+/* The reset value of the ALT_QSPI_CFG_PERCSLINES register field. */
+#define ALT_QSPI_CFG_PERCSLINES_RESET      0x0
+/* Extracts the ALT_QSPI_CFG_PERCSLINES field value from a register. */
+#define ALT_QSPI_CFG_PERCSLINES_GET(value) (((value) & 0x00003c00) >> 10)
+/* Produces a ALT_QSPI_CFG_PERCSLINES register field value suitable for setting the register. */
+#define ALT_QSPI_CFG_PERCSLINES_SET(value) (((value) << 10) & 0x00003c00)
+
+/*
+ * Field : Write Protect Flash Pin - wp
+ * 
+ * This bit controls the write protect pin of the flash devices. The signal
+ * qspi_mo2_wpn needs to be resynchronized to the generated memory clock as
+ * necessary.
+ * 
+ * Field Enumeration Values:
+ * 
+ *  Enum                         | Value | Description          
+ * :-----------------------------|:------|:----------------------
+ *  ALT_QSPI_CFG_WP_E_WRPROTON   | 0x1   | Enable Write Protect 
+ *  ALT_QSPI_CFG_WP_E_WRTPROTOFF | 0x0   | Disable Write Protect
+ * 
+ * Field Access Macros:
+ * 
+ */
+/*
+ * Enumerated value for register field ALT_QSPI_CFG_WP
+ * 
+ * Enable Write Protect
+ */
+#define ALT_QSPI_CFG_WP_E_WRPROTON      0x1
+/*
+ * Enumerated value for register field ALT_QSPI_CFG_WP
+ * 
+ * Disable Write Protect
+ */
+#define ALT_QSPI_CFG_WP_E_WRTPROTOFF    0x0
+
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_CFG_WP register field. */
+#define ALT_QSPI_CFG_WP_LSB        14
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_CFG_WP register field. */
+#define ALT_QSPI_CFG_WP_MSB        14
+/* The width in bits of the ALT_QSPI_CFG_WP register field. */
+#define ALT_QSPI_CFG_WP_WIDTH      1
+/* The mask used to set the ALT_QSPI_CFG_WP register field value. */
+#define ALT_QSPI_CFG_WP_SET_MSK    0x00004000
+/* The mask used to clear the ALT_QSPI_CFG_WP register field value. */
+#define ALT_QSPI_CFG_WP_CLR_MSK    0xffffbfff
+/* The reset value of the ALT_QSPI_CFG_WP register field. */
+#define ALT_QSPI_CFG_WP_RESET      0x0
+/* Extracts the ALT_QSPI_CFG_WP field value from a register. */
+#define ALT_QSPI_CFG_WP_GET(value) (((value) & 0x00004000) >> 14)
+/* Produces a ALT_QSPI_CFG_WP register field value suitable for setting the register. */
+#define ALT_QSPI_CFG_WP_SET(value) (((value) << 14) & 0x00004000)
+
+/*
+ * Field : Enable DMA Peripheral Interface - endma
+ * 
+ * Allows DMA handshaking mode. When enabled the QSPI will trigger DMA transfer
+ * requests via the DMA peripheral interface.
+ * 
+ * Field Enumeration Values:
+ * 
+ *  Enum                     | Value | Description     
+ * :-------------------------|:------|:-----------------
+ *  ALT_QSPI_CFG_ENDMA_E_EN  | 0x1   | Enable DMA Mode 
+ *  ALT_QSPI_CFG_ENDMA_E_DIS | 0x0   | Disable DMA Mode
+ * 
+ * Field Access Macros:
+ * 
+ */
+/*
+ * Enumerated value for register field ALT_QSPI_CFG_ENDMA
+ * 
+ * Enable DMA Mode
+ */
+#define ALT_QSPI_CFG_ENDMA_E_EN     0x1
+/*
+ * Enumerated value for register field ALT_QSPI_CFG_ENDMA
+ * 
+ * Disable DMA Mode
+ */
+#define ALT_QSPI_CFG_ENDMA_E_DIS    0x0
+
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_CFG_ENDMA register field. */
+#define ALT_QSPI_CFG_ENDMA_LSB        15
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_CFG_ENDMA register field. */
+#define ALT_QSPI_CFG_ENDMA_MSB        15
+/* The width in bits of the ALT_QSPI_CFG_ENDMA register field. */
+#define ALT_QSPI_CFG_ENDMA_WIDTH      1
+/* The mask used to set the ALT_QSPI_CFG_ENDMA register field value. */
+#define ALT_QSPI_CFG_ENDMA_SET_MSK    0x00008000
+/* The mask used to clear the ALT_QSPI_CFG_ENDMA register field value. */
+#define ALT_QSPI_CFG_ENDMA_CLR_MSK    0xffff7fff
+/* The reset value of the ALT_QSPI_CFG_ENDMA register field. */
+#define ALT_QSPI_CFG_ENDMA_RESET      0x0
+/* Extracts the ALT_QSPI_CFG_ENDMA field value from a register. */
+#define ALT_QSPI_CFG_ENDMA_GET(value) (((value) & 0x00008000) >> 15)
+/* Produces a ALT_QSPI_CFG_ENDMA register field value suitable for setting the register. */
+#define ALT_QSPI_CFG_ENDMA_SET(value) (((value) << 15) & 0x00008000)
+
+/*
+ * Field : Enable AHB Address Re-mapping - enahbremap
+ * 
+ * (Direct Access Mode Only) When enabled, the incoming AHB address will be adapted
+ * and sent to the FLASH device as (address + N), where N is the value stored in
+ * the remap address register.
+ * 
+ * Field Enumeration Values:
+ * 
+ *  Enum                          | Value | Description           
+ * :------------------------------|:------|:-----------------------
+ *  ALT_QSPI_CFG_ENAHBREMAP_E_EN  | 0x1   | Enable AHB Re-mapping 
+ *  ALT_QSPI_CFG_ENAHBREMAP_E_DIS | 0x0   | Disable AHB Re-mapping
+ * 
+ * Field Access Macros:
+ * 
+ */
+/*
+ * Enumerated value for register field ALT_QSPI_CFG_ENAHBREMAP
+ * 
+ * Enable AHB Re-mapping
+ */
+#define ALT_QSPI_CFG_ENAHBREMAP_E_EN    0x1
+/*
+ * Enumerated value for register field ALT_QSPI_CFG_ENAHBREMAP
+ * 
+ * Disable AHB Re-mapping
+ */
+#define ALT_QSPI_CFG_ENAHBREMAP_E_DIS   0x0
+
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_CFG_ENAHBREMAP register field. */
+#define ALT_QSPI_CFG_ENAHBREMAP_LSB        16
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_CFG_ENAHBREMAP register field. */
+#define ALT_QSPI_CFG_ENAHBREMAP_MSB        16
+/* The width in bits of the ALT_QSPI_CFG_ENAHBREMAP register field. */
+#define ALT_QSPI_CFG_ENAHBREMAP_WIDTH      1
+/* The mask used to set the ALT_QSPI_CFG_ENAHBREMAP register field value. */
+#define ALT_QSPI_CFG_ENAHBREMAP_SET_MSK    0x00010000
+/* The mask used to clear the ALT_QSPI_CFG_ENAHBREMAP register field value. */
+#define ALT_QSPI_CFG_ENAHBREMAP_CLR_MSK    0xfffeffff
+/* The reset value of the ALT_QSPI_CFG_ENAHBREMAP register field. */
+#define ALT_QSPI_CFG_ENAHBREMAP_RESET      0x0
+/* Extracts the ALT_QSPI_CFG_ENAHBREMAP field value from a register. */
+#define ALT_QSPI_CFG_ENAHBREMAP_GET(value) (((value) & 0x00010000) >> 16)
+/* Produces a ALT_QSPI_CFG_ENAHBREMAP register field value suitable for setting the register. */
+#define ALT_QSPI_CFG_ENAHBREMAP_SET(value) (((value) << 16) & 0x00010000)
+
+/*
+ * Field : Enter XIP Mode on next READ - enterxipnextrd
+ * 
+ * If XIP is enabled, then setting to disabled will cause the controller to exit
+ * XIP mode on the next READ instruction. If XIP is disabled, then setting to
+ * enabled will inform the controller that the device is ready to enter XIP on the
+ * next READ instruction. The controller will therefore send the appropriate
+ * command sequence, including mode bits to cause the device to enter XIP mode. Use
+ * this register after the controller has ensured the FLASH device has been
+ * configured to be ready to enter XIP mode. Note : To exit XIP mode, this bit
+ * should be set to 0. This will take effect in the attached device only AFTER the
+ * next READ instruction is executed. Software should therefore ensure that at
+ * least one READ instruction is requested after resetting this bit before it can
+ * be sure XIP mode in the device is exited.
+ * 
+ * Field Enumeration Values:
+ * 
+ *  Enum                              | Value | Description                            
+ * :----------------------------------|:------|:----------------------------------------
+ *  ALT_QSPI_CFG_ENTERXIPNEXTRD_E_EN  | 0x1   | Enter XIP Mode on next READ instruction
+ *  ALT_QSPI_CFG_ENTERXIPNEXTRD_E_DIS | 0x0   | Exit XIP Mode on next READ instruction 
+ * 
+ * Field Access Macros:
+ * 
+ */
+/*
+ * Enumerated value for register field ALT_QSPI_CFG_ENTERXIPNEXTRD
+ * 
+ * Enter XIP Mode on next READ instruction
+ */
+#define ALT_QSPI_CFG_ENTERXIPNEXTRD_E_EN    0x1
+/*
+ * Enumerated value for register field ALT_QSPI_CFG_ENTERXIPNEXTRD
+ * 
+ * Exit XIP Mode on next READ instruction
+ */
+#define ALT_QSPI_CFG_ENTERXIPNEXTRD_E_DIS   0x0
+
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_CFG_ENTERXIPNEXTRD register field. */
+#define ALT_QSPI_CFG_ENTERXIPNEXTRD_LSB        17
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_CFG_ENTERXIPNEXTRD register field. */
+#define ALT_QSPI_CFG_ENTERXIPNEXTRD_MSB        17
+/* The width in bits of the ALT_QSPI_CFG_ENTERXIPNEXTRD register field. */
+#define ALT_QSPI_CFG_ENTERXIPNEXTRD_WIDTH      1
+/* The mask used to set the ALT_QSPI_CFG_ENTERXIPNEXTRD register field value. */
+#define ALT_QSPI_CFG_ENTERXIPNEXTRD_SET_MSK    0x00020000
+/* The mask used to clear the ALT_QSPI_CFG_ENTERXIPNEXTRD register field value. */
+#define ALT_QSPI_CFG_ENTERXIPNEXTRD_CLR_MSK    0xfffdffff
+/* The reset value of the ALT_QSPI_CFG_ENTERXIPNEXTRD register field. */
+#define ALT_QSPI_CFG_ENTERXIPNEXTRD_RESET      0x0
+/* Extracts the ALT_QSPI_CFG_ENTERXIPNEXTRD field value from a register. */
+#define ALT_QSPI_CFG_ENTERXIPNEXTRD_GET(value) (((value) & 0x00020000) >> 17)
+/* Produces a ALT_QSPI_CFG_ENTERXIPNEXTRD register field value suitable for setting the register. */
+#define ALT_QSPI_CFG_ENTERXIPNEXTRD_SET(value) (((value) << 17) & 0x00020000)
+
+/*
+ * Field : Enter XIP Mode Immediately - enterxipimm
+ * 
+ * If XIP is enabled, then setting to disabled will cause the controller to exit
+ * XIP mode on the next READ instruction. If XIP is disabled, then setting enable
+ * will operate the device in XIP mode immediately. Use this register when the
+ * external device wakes up in XIP mode (as per the contents of its non- volatile
+ * configuration register). The controller will assume the next READ instruction
+ * will be passed to the device as an XIP instruction, and therefore will not
+ * require the READ opcode to be transferred. Note: To exit XIP mode, this bit
+ * should be set to 0. This will take effect in the attached device only after the
+ * next READ instruction is executed. Software therefore should ensure that at
+ * least one READ instruction is requested after resetting this bit in order to be
+ * sure that XIP mode is exited.
+ * 
+ * Field Enumeration Values:
+ * 
+ *  Enum                           | Value | Description                           
+ * :-------------------------------|:------|:---------------------------------------
+ *  ALT_QSPI_CFG_ENTERXIPIMM_E_EN  | 0x1   | Enter XIP Mode immediately            
+ *  ALT_QSPI_CFG_ENTERXIPIMM_E_DIS | 0x0   | Exit XIP Mode on next READ instruction
+ * 
+ * Field Access Macros:
+ * 
+ */
+/*
+ * Enumerated value for register field ALT_QSPI_CFG_ENTERXIPIMM
+ * 
+ * Enter XIP Mode immediately
+ */
+#define ALT_QSPI_CFG_ENTERXIPIMM_E_EN   0x1
+/*
+ * Enumerated value for register field ALT_QSPI_CFG_ENTERXIPIMM
+ * 
+ * Exit XIP Mode on next READ instruction
+ */
+#define ALT_QSPI_CFG_ENTERXIPIMM_E_DIS  0x0
+
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_CFG_ENTERXIPIMM register field. */
+#define ALT_QSPI_CFG_ENTERXIPIMM_LSB        18
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_CFG_ENTERXIPIMM register field. */
+#define ALT_QSPI_CFG_ENTERXIPIMM_MSB        18
+/* The width in bits of the ALT_QSPI_CFG_ENTERXIPIMM register field. */
+#define ALT_QSPI_CFG_ENTERXIPIMM_WIDTH      1
+/* The mask used to set the ALT_QSPI_CFG_ENTERXIPIMM register field value. */
+#define ALT_QSPI_CFG_ENTERXIPIMM_SET_MSK    0x00040000
+/* The mask used to clear the ALT_QSPI_CFG_ENTERXIPIMM register field value. */
+#define ALT_QSPI_CFG_ENTERXIPIMM_CLR_MSK    0xfffbffff
+/* The reset value of the ALT_QSPI_CFG_ENTERXIPIMM register field. */
+#define ALT_QSPI_CFG_ENTERXIPIMM_RESET      0x0
+/* Extracts the ALT_QSPI_CFG_ENTERXIPIMM field value from a register. */
+#define ALT_QSPI_CFG_ENTERXIPIMM_GET(value) (((value) & 0x00040000) >> 18)
+/* Produces a ALT_QSPI_CFG_ENTERXIPIMM register field value suitable for setting the register. */
+#define ALT_QSPI_CFG_ENTERXIPIMM_SET(value) (((value) << 18) & 0x00040000)
+
+/*
+ * Field : Master Mode Baud Rate Divisor - bauddiv
+ * 
+ * SPI baud rate = ref_clk / (2 * baud_rate_divisor)
+ * 
+ * Field Enumeration Values:
+ * 
+ *  Enum                          | Value | Description     
+ * :------------------------------|:------|:-----------------
+ *  ALT_QSPI_CFG_BAUDDIV_E_BAUD2  | 0x0   | Baud Rate Div/2 
+ *  ALT_QSPI_CFG_BAUDDIV_E_BAUD4  | 0x1   | Baud Rate Div/4 
+ *  ALT_QSPI_CFG_BAUDDIV_E_BAUD6  | 0x2   | Baud Rate Div/6 
+ *  ALT_QSPI_CFG_BAUDDIV_E_BAUD8  | 0x3   | Baud Rate Div/8 
+ *  ALT_QSPI_CFG_BAUDDIV_E_BAUD10 | 0x4   | Baud Rate Div/10
+ *  ALT_QSPI_CFG_BAUDDIV_E_BAUD12 | 0x5   | Baud Rate Div/12
+ *  ALT_QSPI_CFG_BAUDDIV_E_BAUD14 | 0x6   | Baud Rate Div/14
+ *  ALT_QSPI_CFG_BAUDDIV_E_BAUD16 | 0x7   | Baud Rate Div/16
+ *  ALT_QSPI_CFG_BAUDDIV_E_BAUD18 | 0x8   | Baud Rate Div/18
+ *  ALT_QSPI_CFG_BAUDDIV_E_BAUD20 | 0x9   | Baud Rate Div/20
+ *  ALT_QSPI_CFG_BAUDDIV_E_BAUD22 | 0xa   | Baud Rate Div/22
+ *  ALT_QSPI_CFG_BAUDDIV_E_BAUD24 | 0xb   | Baud Rate Div/24
+ *  ALT_QSPI_CFG_BAUDDIV_E_BAUD26 | 0xc   | Baud Rate Div/26
+ *  ALT_QSPI_CFG_BAUDDIV_E_BAUD28 | 0xd   | Baud Rate Div/28
+ *  ALT_QSPI_CFG_BAUDDIV_E_BAUD30 | 0xe   | Baud Rate Div/30
+ *  ALT_QSPI_CFG_BAUDDIV_E_BAUD32 | 0xf   | Baud Rate Div/32
+ * 
+ * Field Access Macros:
+ * 
+ */
+/*
+ * Enumerated value for register field ALT_QSPI_CFG_BAUDDIV
+ * 
+ * Baud Rate Div/2
+ */
+#define ALT_QSPI_CFG_BAUDDIV_E_BAUD2    0x0
+/*
+ * Enumerated value for register field ALT_QSPI_CFG_BAUDDIV
+ * 
+ * Baud Rate Div/4
+ */
+#define ALT_QSPI_CFG_BAUDDIV_E_BAUD4    0x1
+/*
+ * Enumerated value for register field ALT_QSPI_CFG_BAUDDIV
+ * 
+ * Baud Rate Div/6
+ */
+#define ALT_QSPI_CFG_BAUDDIV_E_BAUD6    0x2
+/*
+ * Enumerated value for register field ALT_QSPI_CFG_BAUDDIV
+ * 
+ * Baud Rate Div/8
+ */
+#define ALT_QSPI_CFG_BAUDDIV_E_BAUD8    0x3
+/*
+ * Enumerated value for register field ALT_QSPI_CFG_BAUDDIV
+ * 
+ * Baud Rate Div/10
+ */
+#define ALT_QSPI_CFG_BAUDDIV_E_BAUD10   0x4
+/*
+ * Enumerated value for register field ALT_QSPI_CFG_BAUDDIV
+ * 
+ * Baud Rate Div/12
+ */
+#define ALT_QSPI_CFG_BAUDDIV_E_BAUD12   0x5
+/*
+ * Enumerated value for register field ALT_QSPI_CFG_BAUDDIV
+ * 
+ * Baud Rate Div/14
+ */
+#define ALT_QSPI_CFG_BAUDDIV_E_BAUD14   0x6
+/*
+ * Enumerated value for register field ALT_QSPI_CFG_BAUDDIV
+ * 
+ * Baud Rate Div/16
+ */
+#define ALT_QSPI_CFG_BAUDDIV_E_BAUD16   0x7
+/*
+ * Enumerated value for register field ALT_QSPI_CFG_BAUDDIV
+ * 
+ * Baud Rate Div/18
+ */
+#define ALT_QSPI_CFG_BAUDDIV_E_BAUD18   0x8
+/*
+ * Enumerated value for register field ALT_QSPI_CFG_BAUDDIV
+ * 
+ * Baud Rate Div/20
+ */
+#define ALT_QSPI_CFG_BAUDDIV_E_BAUD20   0x9
+/*
+ * Enumerated value for register field ALT_QSPI_CFG_BAUDDIV
+ * 
+ * Baud Rate Div/22
+ */
+#define ALT_QSPI_CFG_BAUDDIV_E_BAUD22   0xa
+/*
+ * Enumerated value for register field ALT_QSPI_CFG_BAUDDIV
+ * 
+ * Baud Rate Div/24
+ */
+#define ALT_QSPI_CFG_BAUDDIV_E_BAUD24   0xb
+/*
+ * Enumerated value for register field ALT_QSPI_CFG_BAUDDIV
+ * 
+ * Baud Rate Div/26
+ */
+#define ALT_QSPI_CFG_BAUDDIV_E_BAUD26   0xc
+/*
+ * Enumerated value for register field ALT_QSPI_CFG_BAUDDIV
+ * 
+ * Baud Rate Div/28
+ */
+#define ALT_QSPI_CFG_BAUDDIV_E_BAUD28   0xd
+/*
+ * Enumerated value for register field ALT_QSPI_CFG_BAUDDIV
+ * 
+ * Baud Rate Div/30
+ */
+#define ALT_QSPI_CFG_BAUDDIV_E_BAUD30   0xe
+/*
+ * Enumerated value for register field ALT_QSPI_CFG_BAUDDIV
+ * 
+ * Baud Rate Div/32
+ */
+#define ALT_QSPI_CFG_BAUDDIV_E_BAUD32   0xf
+
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_CFG_BAUDDIV register field. */
+#define ALT_QSPI_CFG_BAUDDIV_LSB        19
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_CFG_BAUDDIV register field. */
+#define ALT_QSPI_CFG_BAUDDIV_MSB        22
+/* The width in bits of the ALT_QSPI_CFG_BAUDDIV register field. */
+#define ALT_QSPI_CFG_BAUDDIV_WIDTH      4
+/* The mask used to set the ALT_QSPI_CFG_BAUDDIV register field value. */
+#define ALT_QSPI_CFG_BAUDDIV_SET_MSK    0x00780000
+/* The mask used to clear the ALT_QSPI_CFG_BAUDDIV register field value. */
+#define ALT_QSPI_CFG_BAUDDIV_CLR_MSK    0xff87ffff
+/* The reset value of the ALT_QSPI_CFG_BAUDDIV register field. */
+#define ALT_QSPI_CFG_BAUDDIV_RESET      0xf
+/* Extracts the ALT_QSPI_CFG_BAUDDIV field value from a register. */
+#define ALT_QSPI_CFG_BAUDDIV_GET(value) (((value) & 0x00780000) >> 19)
+/* Produces a ALT_QSPI_CFG_BAUDDIV register field value suitable for setting the register. */
+#define ALT_QSPI_CFG_BAUDDIV_SET(value) (((value) << 19) & 0x00780000)
+
+/*
+ * Field : Serial interface and QSPI pipeline is IDLE - idle
+ * 
+ * This is a STATUS read-only bit. Note this is a retimed signal, so there will be
+ * some inherent delay on the generation of this status signal.
+ * 
+ * Field Enumeration Values:
+ * 
+ *  Enum                       | Value | Description  
+ * :---------------------------|:------|:--------------
+ *  ALT_QSPI_CFG_IDLE_E_SET    | 0x1   | Idle Mode    
+ *  ALT_QSPI_CFG_IDLE_E_NOTSET | 0x0   | Non-Idle Mode
+ * 
+ * Field Access Macros:
+ * 
+ */
+/*
+ * Enumerated value for register field ALT_QSPI_CFG_IDLE
+ * 
+ * Idle Mode
+ */
+#define ALT_QSPI_CFG_IDLE_E_SET     0x1
+/*
+ * Enumerated value for register field ALT_QSPI_CFG_IDLE
+ * 
+ * Non-Idle Mode
+ */
+#define ALT_QSPI_CFG_IDLE_E_NOTSET  0x0
+
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_CFG_IDLE register field. */
+#define ALT_QSPI_CFG_IDLE_LSB        31
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_CFG_IDLE register field. */
+#define ALT_QSPI_CFG_IDLE_MSB        31
+/* The width in bits of the ALT_QSPI_CFG_IDLE register field. */
+#define ALT_QSPI_CFG_IDLE_WIDTH      1
+/* The mask used to set the ALT_QSPI_CFG_IDLE register field value. */
+#define ALT_QSPI_CFG_IDLE_SET_MSK    0x80000000
+/* The mask used to clear the ALT_QSPI_CFG_IDLE register field value. */
+#define ALT_QSPI_CFG_IDLE_CLR_MSK    0x7fffffff
+/* The reset value of the ALT_QSPI_CFG_IDLE register field. */
+#define ALT_QSPI_CFG_IDLE_RESET      0x0
+/* Extracts the ALT_QSPI_CFG_IDLE field value from a register. */
+#define ALT_QSPI_CFG_IDLE_GET(value) (((value) & 0x80000000) >> 31)
+/* Produces a ALT_QSPI_CFG_IDLE register field value suitable for setting the register. */
+#define ALT_QSPI_CFG_IDLE_SET(value) (((value) << 31) & 0x80000000)
+
+#ifndef __ASSEMBLY__
+/*
+ * WARNING: The C register and register group struct declarations are provided for
+ * convenience and illustrative purposes. They should, however, be used with
+ * caution as the C language standard provides no guarantees about the alignment or
+ * atomicity of device memory accesses. The recommended practice for writing
+ * hardware drivers is to use the SoCAL access macros and alt_read_word() and
+ * alt_write_word() functions.
+ * 
+ * The struct declaration for register ALT_QSPI_CFG.
+ */
+struct ALT_QSPI_CFG_s
+{
+    uint32_t        en             :  1;  /* QSPI Enable */
+    uint32_t        selclkpol      :  1;  /* Clock Polarity */
+    uint32_t        selclkphase    :  1;  /* Select Clock Phase */
+    uint32_t                       :  4;  /* *UNDEFINED* */
+    uint32_t        endiracc       :  1;  /* Enable Direct Access Controller */
+    uint32_t        enlegacyip     :  1;  /* Legacy IP Mode Enable */
+    uint32_t        perseldec      :  1;  /* Peripheral select decode */
+    uint32_t        percslines     :  4;  /* Peripheral Chip Select Lines */
+    uint32_t        wp             :  1;  /* Write Protect Flash Pin */
+    uint32_t        endma          :  1;  /* Enable DMA Peripheral Interface */
+    uint32_t        enahbremap     :  1;  /* Enable AHB Address Re-mapping */
+    uint32_t        enterxipnextrd :  1;  /* Enter XIP Mode on next READ */
+    uint32_t        enterxipimm    :  1;  /* Enter XIP Mode Immediately */
+    uint32_t        bauddiv        :  4;  /* Master Mode Baud Rate Divisor */
+    uint32_t                       :  8;  /* *UNDEFINED* */
+    const uint32_t  idle           :  1;  /* Serial interface and QSPI pipeline is IDLE */
+};
+
+/* The typedef declaration for register ALT_QSPI_CFG. */
+typedef volatile struct ALT_QSPI_CFG_s  ALT_QSPI_CFG_t;
+#endif  /* __ASSEMBLY__ */
+
+/* The byte offset of the ALT_QSPI_CFG register from the beginning of the component. */
+#define ALT_QSPI_CFG_OFST        0x0
+
+/*
+ * Register : Device Read Instruction Register - devrd
+ * 
+ * Register Layout
+ * 
+ *  Bits    | Access | Reset | Description                
+ * :--------|:-------|:------|:----------------------------
+ *  [7:0]   | RW     | 0x3   | Read Opcode in non-XIP mode
+ *  [9:8]   | RW     | 0x0   | Instruction Transfer Width 
+ *  [11:10] | ???    | 0x0   | *UNDEFINED*                
+ *  [13:12] | RW     | 0x0   | Address Transfer Width     
+ *  [15:14] | ???    | 0x0   | *UNDEFINED*                
+ *  [17:16] | RW     | 0x0   | Data Transfer Width        
+ *  [19:18] | ???    | 0x0   | *UNDEFINED*                
+ *  [20]    | RW     | 0x0   | Mode Bit Enable            
+ *  [23:21] | ???    | 0x0   | *UNDEFINED*                
+ *  [28:24] | RW     | 0x0   | Dummy Read Clock Cycles    
+ *  [31:29] | ???    | 0x0   | *UNDEFINED*                
+ * 
+ */
+/*
+ * Field : Read Opcode in non-XIP mode - rdopcode
+ * 
+ * Read Opcode to use when not in XIP mode
+ * 
+ * Field Enumeration Values:
+ * 
+ *  Enum                             | Value | Description                
+ * :---------------------------------|:------|:----------------------------
+ *  ALT_QSPI_DEVRD_RDOPCODE_E_RD     | 0x3   | Read Opcode in Non-XIP mode
+ *  ALT_QSPI_DEVRD_RDOPCODE_E_FASTRD | 0xb   | Fast Read in Non-XIP mode  
+ * 
+ * Field Access Macros:
+ * 
+ */
+/*
+ * Enumerated value for register field ALT_QSPI_DEVRD_RDOPCODE
+ * 
+ * Read Opcode in Non-XIP mode
+ */
+#define ALT_QSPI_DEVRD_RDOPCODE_E_RD        0x3
+/*
+ * Enumerated value for register field ALT_QSPI_DEVRD_RDOPCODE
+ * 
+ * Fast Read in Non-XIP mode
+ */
+#define ALT_QSPI_DEVRD_RDOPCODE_E_FASTRD    0xb
+
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_DEVRD_RDOPCODE register field. */
+#define ALT_QSPI_DEVRD_RDOPCODE_LSB        0
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_DEVRD_RDOPCODE register field. */
+#define ALT_QSPI_DEVRD_RDOPCODE_MSB        7
+/* The width in bits of the ALT_QSPI_DEVRD_RDOPCODE register field. */
+#define ALT_QSPI_DEVRD_RDOPCODE_WIDTH      8
+/* The mask used to set the ALT_QSPI_DEVRD_RDOPCODE register field value. */
+#define ALT_QSPI_DEVRD_RDOPCODE_SET_MSK    0x000000ff
+/* The mask used to clear the ALT_QSPI_DEVRD_RDOPCODE register field value. */
+#define ALT_QSPI_DEVRD_RDOPCODE_CLR_MSK    0xffffff00
+/* The reset value of the ALT_QSPI_DEVRD_RDOPCODE register field. */
+#define ALT_QSPI_DEVRD_RDOPCODE_RESET      0x3
+/* Extracts the ALT_QSPI_DEVRD_RDOPCODE field value from a register. */
+#define ALT_QSPI_DEVRD_RDOPCODE_GET(value) (((value) & 0x000000ff) >> 0)
+/* Produces a ALT_QSPI_DEVRD_RDOPCODE register field value suitable for setting the register. */
+#define ALT_QSPI_DEVRD_RDOPCODE_SET(value) (((value) << 0) & 0x000000ff)
+
+/*
+ * Field : Instruction Transfer Width - instwidth
+ * 
+ * Sets instruction transfer width (1, 2, or 4 bits). Applies to all instructions
+ * sent to SPI flash device (not just read instructions).
+ * 
+ * Field Enumeration Values:
+ * 
+ *  Enum                              | Value | Description                                     
+ * :----------------------------------|:------|:-------------------------------------------------
+ *  ALT_QSPI_DEVRD_INSTWIDTH_E_SINGLE | 0x0   | Instruction transferred on DQ0. Supported by all
+ * :                                  |       | SPI flash devices.                              
+ *  ALT_QSPI_DEVRD_INSTWIDTH_E_DUAL   | 0x1   | Instruction transferred on DQ0 and DQ1.         
+ * :                                  |       | Supported by all SPI flash devices that support 
+ * :                                  |       | the Dual SP (DIO-SPI) Protocol.                 
+ *  ALT_QSPI_DEVRD_INSTWIDTH_E_QUAD   | 0x2   | Instruction transferred on DQ0, DQ1, DQ2, and   
+ * :                                  |       | DQ3. Supported by all SPI flash devices that    
+ * :                                  |       | support the Quad SP (QIO-SPI) Protocol.         
+ * 
+ * Field Access Macros:
+ * 
+ */
+/*
+ * Enumerated value for register field ALT_QSPI_DEVRD_INSTWIDTH
+ * 
+ * Instruction transferred on DQ0. Supported by all SPI flash devices.
+ */
+#define ALT_QSPI_DEVRD_INSTWIDTH_E_SINGLE   0x0
+/*
+ * Enumerated value for register field ALT_QSPI_DEVRD_INSTWIDTH
+ * 
+ * Instruction transferred on DQ0 and DQ1. Supported by all SPI flash devices that
+ * support the Dual SP (DIO-SPI) Protocol.
+ */
+#define ALT_QSPI_DEVRD_INSTWIDTH_E_DUAL     0x1
+/*
+ * Enumerated value for register field ALT_QSPI_DEVRD_INSTWIDTH
+ * 
+ * Instruction transferred on DQ0, DQ1, DQ2, and DQ3. Supported by all SPI flash
+ * devices that support the Quad SP (QIO-SPI) Protocol.
+ */
+#define ALT_QSPI_DEVRD_INSTWIDTH_E_QUAD     0x2
+
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_DEVRD_INSTWIDTH register field. */
+#define ALT_QSPI_DEVRD_INSTWIDTH_LSB        8
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_DEVRD_INSTWIDTH register field. */
+#define ALT_QSPI_DEVRD_INSTWIDTH_MSB        9
+/* The width in bits of the ALT_QSPI_DEVRD_INSTWIDTH register field. */
+#define ALT_QSPI_DEVRD_INSTWIDTH_WIDTH      2
+/* The mask used to set the ALT_QSPI_DEVRD_INSTWIDTH register field value. */
+#define ALT_QSPI_DEVRD_INSTWIDTH_SET_MSK    0x00000300
+/* The mask used to clear the ALT_QSPI_DEVRD_INSTWIDTH register field value. */
+#define ALT_QSPI_DEVRD_INSTWIDTH_CLR_MSK    0xfffffcff
+/* The reset value of the ALT_QSPI_DEVRD_INSTWIDTH register field. */
+#define ALT_QSPI_DEVRD_INSTWIDTH_RESET      0x0
+/* Extracts the ALT_QSPI_DEVRD_INSTWIDTH field value from a register. */
+#define ALT_QSPI_DEVRD_INSTWIDTH_GET(value) (((value) & 0x00000300) >> 8)
+/* Produces a ALT_QSPI_DEVRD_INSTWIDTH register field value suitable for setting the register. */
+#define ALT_QSPI_DEVRD_INSTWIDTH_SET(value) (((value) << 8) & 0x00000300)
+
+/*
+ * Field : Address Transfer Width - addrwidth
+ * 
+ * Sets read address transfer width (1, 2, or 4 bits).
+ * 
+ * Field Enumeration Values:
+ * 
+ *  Enum                              | Value | Description                                     
+ * :----------------------------------|:------|:-------------------------------------------------
+ *  ALT_QSPI_DEVRD_ADDRWIDTH_E_SINGLE | 0x0   | Read address transferred on DQ0. Supported by   
+ * :                                  |       | all SPI flash devices                           
+ *  ALT_QSPI_DEVRD_ADDRWIDTH_E_DUAL   | 0x1   | Read address transferred on DQ0 and DQ1.        
+ * :                                  |       | Supported by some SPI flash devices that support
+ * :                                  |       | the Extended SPI Protocol and by all SPI flash  
+ * :                                  |       | devices that support the Dual SP (DIO-SPI)      
+ * :                                  |       | Protocol.                                       
+ *  ALT_QSPI_DEVRD_ADDRWIDTH_E_QUAD   | 0x2   | Read address transferred on DQ0, DQ1, DQ2, and  
+ * :                                  |       | DQ3. Supported by some SPI flash devices that   
+ * :                                  |       | support the Extended SPI Protocol and by all SPI
+ * :                                  |       | flash devices that support the Quad SP (QIO-SPI)
+ * :                                  |       | Protocol.                                       
+ * 
+ * Field Access Macros:
+ * 
+ */
+/*
+ * Enumerated value for register field ALT_QSPI_DEVRD_ADDRWIDTH
+ * 
+ * Read address transferred on DQ0. Supported by all SPI flash devices
+ */
+#define ALT_QSPI_DEVRD_ADDRWIDTH_E_SINGLE   0x0
+/*
+ * Enumerated value for register field ALT_QSPI_DEVRD_ADDRWIDTH
+ * 
+ * Read address transferred on DQ0 and DQ1. Supported by some SPI flash devices
+ * that support the Extended SPI Protocol and by all SPI flash devices that support
+ * the Dual SP (DIO-SPI) Protocol.
+ */
+#define ALT_QSPI_DEVRD_ADDRWIDTH_E_DUAL     0x1
+/*
+ * Enumerated value for register field ALT_QSPI_DEVRD_ADDRWIDTH
+ * 
+ * Read address transferred on DQ0, DQ1, DQ2, and DQ3. Supported by some SPI flash
+ * devices that support the Extended SPI Protocol and by all SPI flash devices that
+ * support the Quad SP (QIO-SPI) Protocol.
+ */
+#define ALT_QSPI_DEVRD_ADDRWIDTH_E_QUAD     0x2
+
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_DEVRD_ADDRWIDTH register field. */
+#define ALT_QSPI_DEVRD_ADDRWIDTH_LSB        12
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_DEVRD_ADDRWIDTH register field. */
+#define ALT_QSPI_DEVRD_ADDRWIDTH_MSB        13
+/* The width in bits of the ALT_QSPI_DEVRD_ADDRWIDTH register field. */
+#define ALT_QSPI_DEVRD_ADDRWIDTH_WIDTH      2
+/* The mask used to set the ALT_QSPI_DEVRD_ADDRWIDTH register field value. */
+#define ALT_QSPI_DEVRD_ADDRWIDTH_SET_MSK    0x00003000
+/* The mask used to clear the ALT_QSPI_DEVRD_ADDRWIDTH register field value. */
+#define ALT_QSPI_DEVRD_ADDRWIDTH_CLR_MSK    0xffffcfff
+/* The reset value of the ALT_QSPI_DEVRD_ADDRWIDTH register field. */
+#define ALT_QSPI_DEVRD_ADDRWIDTH_RESET      0x0
+/* Extracts the ALT_QSPI_DEVRD_ADDRWIDTH field value from a register. */
+#define ALT_QSPI_DEVRD_ADDRWIDTH_GET(value) (((value) & 0x00003000) >> 12)
+/* Produces a ALT_QSPI_DEVRD_ADDRWIDTH register field value suitable for setting the register. */
+#define ALT_QSPI_DEVRD_ADDRWIDTH_SET(value) (((value) << 12) & 0x00003000)
+
+/*
+ * Field : Data Transfer Width - datawidth
+ * 
+ * Sets read data transfer width (1, 2, or 4 bits).
+ * 
+ * Field Enumeration Values:
+ * 
+ *  Enum                              | Value | Description                                     
+ * :----------------------------------|:------|:-------------------------------------------------
+ *  ALT_QSPI_DEVRD_DATAWIDTH_E_SINGLE | 0x0   | Read data transferred on DQ0. Supported by all  
+ * :                                  |       | SPI flash devices                               
+ *  ALT_QSPI_DEVRD_DATAWIDTH_E_DUAL   | 0x1   | Read data transferred on DQ0 and DQ1. Supported 
+ * :                                  |       | by some SPI flash devices that support the      
+ * :                                  |       | Extended SPI Protocol and by all SPI flash      
+ * :                                  |       | devices that support the Dual SP (DIO-SPI)      
+ * :                                  |       | Protocol.                                       
+ *  ALT_QSPI_DEVRD_DATAWIDTH_E_QUAD   | 0x2   | Read data transferred on DQ0, DQ1, DQ2, and DQ3.
+ * :                                  |       | Supported by some SPI flash devices that support
+ * :                                  |       | the Extended SPI Protocol and by all SPI flash  
+ * :                                  |       | devices that support the Quad SP (QIO-SPI)      
+ * :                                  |       | Protocol.                                       
+ * 
+ * Field Access Macros:
+ * 
+ */
+/*
+ * Enumerated value for register field ALT_QSPI_DEVRD_DATAWIDTH
+ * 
+ * Read data transferred on DQ0. Supported by all SPI flash devices
+ */
+#define ALT_QSPI_DEVRD_DATAWIDTH_E_SINGLE   0x0
+/*
+ * Enumerated value for register field ALT_QSPI_DEVRD_DATAWIDTH
+ * 
+ * Read data transferred on DQ0 and DQ1. Supported by some SPI flash devices that
+ * support the Extended SPI Protocol and by all SPI flash devices that support the
+ * Dual SP (DIO-SPI) Protocol.
+ */
+#define ALT_QSPI_DEVRD_DATAWIDTH_E_DUAL     0x1
+/*
+ * Enumerated value for register field ALT_QSPI_DEVRD_DATAWIDTH
+ * 
+ * Read data transferred on DQ0, DQ1, DQ2, and DQ3. Supported by some SPI flash
+ * devices that support the Extended SPI Protocol and by all SPI flash devices that
+ * support the Quad SP (QIO-SPI) Protocol.
+ */
+#define ALT_QSPI_DEVRD_DATAWIDTH_E_QUAD     0x2
+
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_DEVRD_DATAWIDTH register field. */
+#define ALT_QSPI_DEVRD_DATAWIDTH_LSB        16
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_DEVRD_DATAWIDTH register field. */
+#define ALT_QSPI_DEVRD_DATAWIDTH_MSB        17
+/* The width in bits of the ALT_QSPI_DEVRD_DATAWIDTH register field. */
+#define ALT_QSPI_DEVRD_DATAWIDTH_WIDTH      2
+/* The mask used to set the ALT_QSPI_DEVRD_DATAWIDTH register field value. */
+#define ALT_QSPI_DEVRD_DATAWIDTH_SET_MSK    0x00030000
+/* The mask used to clear the ALT_QSPI_DEVRD_DATAWIDTH register field value. */
+#define ALT_QSPI_DEVRD_DATAWIDTH_CLR_MSK    0xfffcffff
+/* The reset value of the ALT_QSPI_DEVRD_DATAWIDTH register field. */
+#define ALT_QSPI_DEVRD_DATAWIDTH_RESET      0x0
+/* Extracts the ALT_QSPI_DEVRD_DATAWIDTH field value from a register. */
+#define ALT_QSPI_DEVRD_DATAWIDTH_GET(value) (((value) & 0x00030000) >> 16)
+/* Produces a ALT_QSPI_DEVRD_DATAWIDTH register field value suitable for setting the register. */
+#define ALT_QSPI_DEVRD_DATAWIDTH_SET(value) (((value) << 16) & 0x00030000)
+
+/*
+ * Field : Mode Bit Enable - enmodebits
+ * 
+ * If this bit is set, the mode bits as defined in the Mode Bit Configuration
+ * register are sent following the address bytes.
+ * 
+ * Field Enumeration Values:
+ * 
+ *  Enum                               | Value | Description                   
+ * :-----------------------------------|:------|:-------------------------------
+ *  ALT_QSPI_DEVRD_ENMODBITS_E_NOORDER | 0x0   | No Order                      
+ *  ALT_QSPI_DEVRD_ENMODBITS_E_ORDER   | 0x1   | Mode Bits follow address bytes
+ * 
+ * Field Access Macros:
+ * 
+ */
+/*
+ * Enumerated value for register field ALT_QSPI_DEVRD_ENMODBITS
+ * 
+ * No Order
+ */
+#define ALT_QSPI_DEVRD_ENMODBITS_E_NOORDER  0x0
+/*
+ * Enumerated value for register field ALT_QSPI_DEVRD_ENMODBITS
+ * 
+ * Mode Bits follow address bytes
+ */
+#define ALT_QSPI_DEVRD_ENMODBITS_E_ORDER    0x1
+
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_DEVRD_ENMODBITS register field. */
+#define ALT_QSPI_DEVRD_ENMODBITS_LSB        20
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_DEVRD_ENMODBITS register field. */
+#define ALT_QSPI_DEVRD_ENMODBITS_MSB        20
+/* The width in bits of the ALT_QSPI_DEVRD_ENMODBITS register field. */
+#define ALT_QSPI_DEVRD_ENMODBITS_WIDTH      1
+/* The mask used to set the ALT_QSPI_DEVRD_ENMODBITS register field value. */
+#define ALT_QSPI_DEVRD_ENMODBITS_SET_MSK    0x00100000
+/* The mask used to clear the ALT_QSPI_DEVRD_ENMODBITS register field value. */
+#define ALT_QSPI_DEVRD_ENMODBITS_CLR_MSK    0xffefffff
+/* The reset value of the ALT_QSPI_DEVRD_ENMODBITS register field. */
+#define ALT_QSPI_DEVRD_ENMODBITS_RESET      0x0
+/* Extracts the ALT_QSPI_DEVRD_ENMODBITS field value from a register. */
+#define ALT_QSPI_DEVRD_ENMODBITS_GET(value) (((value) & 0x00100000) >> 20)
+/* Produces a ALT_QSPI_DEVRD_ENMODBITS register field value suitable for setting the register. */
+#define ALT_QSPI_DEVRD_ENMODBITS_SET(value) (((value) << 20) & 0x00100000)
+
+/*
+ * Field : Dummy Read Clock Cycles - dummyrdclks
+ * 
+ * Number of dummy clock cycles required by device for read instruction.
+ * 
+ * Field Access Macros:
+ * 
+ */
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_DEVRD_DUMMYRDCLKS register field. */
+#define ALT_QSPI_DEVRD_DUMMYRDCLKS_LSB        24
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_DEVRD_DUMMYRDCLKS register field. */
+#define ALT_QSPI_DEVRD_DUMMYRDCLKS_MSB        28
+/* The width in bits of the ALT_QSPI_DEVRD_DUMMYRDCLKS register field. */
+#define ALT_QSPI_DEVRD_DUMMYRDCLKS_WIDTH      5
+/* The mask used to set the ALT_QSPI_DEVRD_DUMMYRDCLKS register field value. */
+#define ALT_QSPI_DEVRD_DUMMYRDCLKS_SET_MSK    0x1f000000
+/* The mask used to clear the ALT_QSPI_DEVRD_DUMMYRDCLKS register field value. */
+#define ALT_QSPI_DEVRD_DUMMYRDCLKS_CLR_MSK    0xe0ffffff
+/* The reset value of the ALT_QSPI_DEVRD_DUMMYRDCLKS register field. */
+#define ALT_QSPI_DEVRD_DUMMYRDCLKS_RESET      0x0
+/* Extracts the ALT_QSPI_DEVRD_DUMMYRDCLKS field value from a register. */
+#define ALT_QSPI_DEVRD_DUMMYRDCLKS_GET(value) (((value) & 0x1f000000) >> 24)
+/* Produces a ALT_QSPI_DEVRD_DUMMYRDCLKS register field value suitable for setting the register. */
+#define ALT_QSPI_DEVRD_DUMMYRDCLKS_SET(value) (((value) << 24) & 0x1f000000)
+
+#ifndef __ASSEMBLY__
+/*
+ * WARNING: The C register and register group struct declarations are provided for
+ * convenience and illustrative purposes. They should, however, be used with
+ * caution as the C language standard provides no guarantees about the alignment or
+ * atomicity of device memory accesses. The recommended practice for writing
+ * hardware drivers is to use the SoCAL access macros and alt_read_word() and
+ * alt_write_word() functions.
+ * 
+ * The struct declaration for register ALT_QSPI_DEVRD.
+ */
+struct ALT_QSPI_DEVRD_s
+{
+    uint32_t  rdopcode    :  8;  /* Read Opcode in non-XIP mode */
+    uint32_t  instwidth   :  2;  /* Instruction Transfer Width */
+    uint32_t              :  2;  /* *UNDEFINED* */
+    uint32_t  addrwidth   :  2;  /* Address Transfer Width */
+    uint32_t              :  2;  /* *UNDEFINED* */
+    uint32_t  datawidth   :  2;  /* Data Transfer Width */
+    uint32_t              :  2;  /* *UNDEFINED* */
+    uint32_t  enmodebits  :  1;  /* Mode Bit Enable */
+    uint32_t              :  3;  /* *UNDEFINED* */
+    uint32_t  dummyrdclks :  5;  /* Dummy Read Clock Cycles */
+    uint32_t              :  3;  /* *UNDEFINED* */
+};
+
+/* The typedef declaration for register ALT_QSPI_DEVRD. */
+typedef volatile struct ALT_QSPI_DEVRD_s  ALT_QSPI_DEVRD_t;
+#endif  /* __ASSEMBLY__ */
+
+/* The byte offset of the ALT_QSPI_DEVRD register from the beginning of the component. */
+#define ALT_QSPI_DEVRD_OFST        0x4
+
+/*
+ * Register : Device Write Instruction Register - devwr
+ * 
+ * Register Layout
+ * 
+ *  Bits    | Access | Reset | Description             
+ * :--------|:-------|:------|:-------------------------
+ *  [7:0]   | RW     | 0x2   | Write Opcode            
+ *  [11:8]  | ???    | 0x0   | *UNDEFINED*             
+ *  [13:12] | RW     | 0x0   | Address Transfer Width  
+ *  [15:14] | ???    | 0x0   | *UNDEFINED*             
+ *  [17:16] | RW     | 0x0   | Data Transfer Width     
+ *  [23:18] | ???    | 0x0   | *UNDEFINED*             
+ *  [28:24] | RW     | 0x0   | Dummy Write Clock Cycles
+ *  [31:29] | ???    | 0x0   | *UNDEFINED*             
+ * 
+ */
+/*
+ * Field : Write Opcode - wropcode
+ * 
+ * Write Opcode
+ * 
+ * Field Access Macros:
+ * 
+ */
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_DEVWR_WROPCODE register field. */
+#define ALT_QSPI_DEVWR_WROPCODE_LSB        0
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_DEVWR_WROPCODE register field. */
+#define ALT_QSPI_DEVWR_WROPCODE_MSB        7
+/* The width in bits of the ALT_QSPI_DEVWR_WROPCODE register field. */
+#define ALT_QSPI_DEVWR_WROPCODE_WIDTH      8
+/* The mask used to set the ALT_QSPI_DEVWR_WROPCODE register field value. */
+#define ALT_QSPI_DEVWR_WROPCODE_SET_MSK    0x000000ff
+/* The mask used to clear the ALT_QSPI_DEVWR_WROPCODE register field value. */
+#define ALT_QSPI_DEVWR_WROPCODE_CLR_MSK    0xffffff00
+/* The reset value of the ALT_QSPI_DEVWR_WROPCODE register field. */
+#define ALT_QSPI_DEVWR_WROPCODE_RESET      0x2
+/* Extracts the ALT_QSPI_DEVWR_WROPCODE field value from a register. */
+#define ALT_QSPI_DEVWR_WROPCODE_GET(value) (((value) & 0x000000ff) >> 0)
+/* Produces a ALT_QSPI_DEVWR_WROPCODE register field value suitable for setting the register. */
+#define ALT_QSPI_DEVWR_WROPCODE_SET(value) (((value) << 0) & 0x000000ff)
+
+/*
+ * Field : Address Transfer Width - addrwidth
+ * 
+ * Sets write address transfer width (1, 2, or 4 bits).
+ * 
+ * Field Enumeration Values:
+ * 
+ *  Enum                              | Value | Description                                     
+ * :----------------------------------|:------|:-------------------------------------------------
+ *  ALT_QSPI_DEVWR_ADDRWIDTH_E_SINGLE | 0x0   | Write address transferred on DQ0. Supported by  
+ * :                                  |       | all SPI flash devices                           
+ *  ALT_QSPI_DEVWR_ADDRWIDTH_E_DUAL   | 0x1   | Read address transferred on DQ0 and DQ1.        
+ * :                                  |       | Supported by some SPI flash devices that support
+ * :                                  |       | the Extended SPI Protocol and by all SPI flash  
+ * :                                  |       | devices that support the Dual SP (DIO-SPI)      
+ * :                                  |       | Protocol.                                       
+ *  ALT_QSPI_DEVWR_ADDRWIDTH_E_QUAD   | 0x2   | Read address transferred on DQ0, DQ1, DQ2, and  
+ * :                                  |       | DQ3. Supported by some SPI flash devices that   
+ * :                                  |       | support the Extended SPI Protocol and by all SPI
+ * :                                  |       | flash devices that support the Quad SP (QIO-SPI)
+ * :                                  |       | Protocol.                                       
+ * 
+ * Field Access Macros:
+ * 
+ */
+/*
+ * Enumerated value for register field ALT_QSPI_DEVWR_ADDRWIDTH
+ * 
+ * Write address transferred on DQ0. Supported by all SPI flash devices
+ */
+#define ALT_QSPI_DEVWR_ADDRWIDTH_E_SINGLE   0x0
+/*
+ * Enumerated value for register field ALT_QSPI_DEVWR_ADDRWIDTH
+ * 
+ * Read address transferred on DQ0 and DQ1. Supported by some SPI flash devices
+ * that support the Extended SPI Protocol and by all SPI flash devices that support
+ * the Dual SP (DIO-SPI) Protocol.
+ */
+#define ALT_QSPI_DEVWR_ADDRWIDTH_E_DUAL     0x1
+/*
+ * Enumerated value for register field ALT_QSPI_DEVWR_ADDRWIDTH
+ * 
+ * Read address transferred on DQ0, DQ1, DQ2, and DQ3. Supported by some SPI flash
+ * devices that support the Extended SPI Protocol and by all SPI flash devices that
+ * support the Quad SP (QIO-SPI) Protocol.
+ */
+#define ALT_QSPI_DEVWR_ADDRWIDTH_E_QUAD     0x2
+
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_DEVWR_ADDRWIDTH register field. */
+#define ALT_QSPI_DEVWR_ADDRWIDTH_LSB        12
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_DEVWR_ADDRWIDTH register field. */
+#define ALT_QSPI_DEVWR_ADDRWIDTH_MSB        13
+/* The width in bits of the ALT_QSPI_DEVWR_ADDRWIDTH register field. */
+#define ALT_QSPI_DEVWR_ADDRWIDTH_WIDTH      2
+/* The mask used to set the ALT_QSPI_DEVWR_ADDRWIDTH register field value. */
+#define ALT_QSPI_DEVWR_ADDRWIDTH_SET_MSK    0x00003000
+/* The mask used to clear the ALT_QSPI_DEVWR_ADDRWIDTH register field value. */
+#define ALT_QSPI_DEVWR_ADDRWIDTH_CLR_MSK    0xffffcfff
+/* The reset value of the ALT_QSPI_DEVWR_ADDRWIDTH register field. */
+#define ALT_QSPI_DEVWR_ADDRWIDTH_RESET      0x0
+/* Extracts the ALT_QSPI_DEVWR_ADDRWIDTH field value from a register. */
+#define ALT_QSPI_DEVWR_ADDRWIDTH_GET(value) (((value) & 0x00003000) >> 12)
+/* Produces a ALT_QSPI_DEVWR_ADDRWIDTH register field value suitable for setting the register. */
+#define ALT_QSPI_DEVWR_ADDRWIDTH_SET(value) (((value) << 12) & 0x00003000)
+
+/*
+ * Field : Data Transfer Width - datawidth
+ * 
+ * Sets write data transfer width (1, 2, or 4 bits).
+ * 
+ * Field Enumeration Values:
+ * 
+ *  Enum                              | Value | Description                                     
+ * :----------------------------------|:------|:-------------------------------------------------
+ *  ALT_QSPI_DEVWR_DATAWIDTH_E_SINGLE | 0x0   | Write data transferred on DQ0. Supported by all 
+ * :                                  |       | SPI flash devices                               
+ *  ALT_QSPI_DEVWR_DATAWIDTH_E_DUAL   | 0x1   | Read data transferred on DQ0 and DQ1. Supported 
+ * :                                  |       | by some SPI flash devices that support the      
+ * :                                  |       | Extended SPI Protocol and by all SPI flash      
+ * :                                  |       | devices that support the Dual SP (DIO-SPI)      
+ * :                                  |       | Protocol.                                       
+ *  ALT_QSPI_DEVWR_DATAWIDTH_E_QUAD   | 0x2   | Read data transferred on DQ0, DQ1, DQ2, and DQ3.
+ * :                                  |       | Supported by some SPI flash devices that support
+ * :                                  |       | the Extended SPI Protocol and by all SPI flash  
+ * :                                  |       | devices that support the Quad SP (QIO-SPI)      
+ * :                                  |       | Protocol.                                       
+ * 
+ * Field Access Macros:
+ * 
+ */
+/*
+ * Enumerated value for register field ALT_QSPI_DEVWR_DATAWIDTH
+ * 
+ * Write data transferred on DQ0. Supported by all SPI flash devices
+ */
+#define ALT_QSPI_DEVWR_DATAWIDTH_E_SINGLE   0x0
+/*
+ * Enumerated value for register field ALT_QSPI_DEVWR_DATAWIDTH
+ * 
+ * Read data transferred on DQ0 and DQ1. Supported by some SPI flash devices that
+ * support the Extended SPI Protocol and by all SPI flash devices that support the
+ * Dual SP (DIO-SPI) Protocol.
+ */
+#define ALT_QSPI_DEVWR_DATAWIDTH_E_DUAL     0x1
+/*
+ * Enumerated value for register field ALT_QSPI_DEVWR_DATAWIDTH
+ * 
+ * Read data transferred on DQ0, DQ1, DQ2, and DQ3. Supported by some SPI flash
+ * devices that support the Extended SPI Protocol and by all SPI flash devices that
+ * support the Quad SP (QIO-SPI) Protocol.
+ */
+#define ALT_QSPI_DEVWR_DATAWIDTH_E_QUAD     0x2
+
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_DEVWR_DATAWIDTH register field. */
+#define ALT_QSPI_DEVWR_DATAWIDTH_LSB        16
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_DEVWR_DATAWIDTH register field. */
+#define ALT_QSPI_DEVWR_DATAWIDTH_MSB        17
+/* The width in bits of the ALT_QSPI_DEVWR_DATAWIDTH register field. */
+#define ALT_QSPI_DEVWR_DATAWIDTH_WIDTH      2
+/* The mask used to set the ALT_QSPI_DEVWR_DATAWIDTH register field value. */
+#define ALT_QSPI_DEVWR_DATAWIDTH_SET_MSK    0x00030000
+/* The mask used to clear the ALT_QSPI_DEVWR_DATAWIDTH register field value. */
+#define ALT_QSPI_DEVWR_DATAWIDTH_CLR_MSK    0xfffcffff
+/* The reset value of the ALT_QSPI_DEVWR_DATAWIDTH register field. */
+#define ALT_QSPI_DEVWR_DATAWIDTH_RESET      0x0
+/* Extracts the ALT_QSPI_DEVWR_DATAWIDTH field value from a register. */
+#define ALT_QSPI_DEVWR_DATAWIDTH_GET(value) (((value) & 0x00030000) >> 16)
+/* Produces a ALT_QSPI_DEVWR_DATAWIDTH register field value suitable for setting the register. */
+#define ALT_QSPI_DEVWR_DATAWIDTH_SET(value) (((value) << 16) & 0x00030000)
+
+/*
+ * Field : Dummy Write Clock Cycles - dummywrclks
+ * 
+ * Number of dummy clock cycles required by device for write instruction.
+ * 
+ * Field Access Macros:
+ * 
+ */
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_DEVWR_DUMMYWRCLKS register field. */
+#define ALT_QSPI_DEVWR_DUMMYWRCLKS_LSB        24
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_DEVWR_DUMMYWRCLKS register field. */
+#define ALT_QSPI_DEVWR_DUMMYWRCLKS_MSB        28
+/* The width in bits of the ALT_QSPI_DEVWR_DUMMYWRCLKS register field. */
+#define ALT_QSPI_DEVWR_DUMMYWRCLKS_WIDTH      5
+/* The mask used to set the ALT_QSPI_DEVWR_DUMMYWRCLKS register field value. */
+#define ALT_QSPI_DEVWR_DUMMYWRCLKS_SET_MSK    0x1f000000
+/* The mask used to clear the ALT_QSPI_DEVWR_DUMMYWRCLKS register field value. */
+#define ALT_QSPI_DEVWR_DUMMYWRCLKS_CLR_MSK    0xe0ffffff
+/* The reset value of the ALT_QSPI_DEVWR_DUMMYWRCLKS register field. */
+#define ALT_QSPI_DEVWR_DUMMYWRCLKS_RESET      0x0
+/* Extracts the ALT_QSPI_DEVWR_DUMMYWRCLKS field value from a register. */
+#define ALT_QSPI_DEVWR_DUMMYWRCLKS_GET(value) (((value) & 0x1f000000) >> 24)
+/* Produces a ALT_QSPI_DEVWR_DUMMYWRCLKS register field value suitable for setting the register. */
+#define ALT_QSPI_DEVWR_DUMMYWRCLKS_SET(value) (((value) << 24) & 0x1f000000)
+
+#ifndef __ASSEMBLY__
+/*
+ * WARNING: The C register and register group struct declarations are provided for
+ * convenience and illustrative purposes. They should, however, be used with
+ * caution as the C language standard provides no guarantees about the alignment or
+ * atomicity of device memory accesses. The recommended practice for writing
+ * hardware drivers is to use the SoCAL access macros and alt_read_word() and
+ * alt_write_word() functions.
+ * 
+ * The struct declaration for register ALT_QSPI_DEVWR.
+ */
+struct ALT_QSPI_DEVWR_s
+{
+    uint32_t  wropcode    :  8;  /* Write Opcode */
+    uint32_t              :  4;  /* *UNDEFINED* */
+    uint32_t  addrwidth   :  2;  /* Address Transfer Width */
+    uint32_t              :  2;  /* *UNDEFINED* */
+    uint32_t  datawidth   :  2;  /* Data Transfer Width */
+    uint32_t              :  6;  /* *UNDEFINED* */
+    uint32_t  dummywrclks :  5;  /* Dummy Write Clock Cycles */
+    uint32_t              :  3;  /* *UNDEFINED* */
+};
+
+/* The typedef declaration for register ALT_QSPI_DEVWR. */
+typedef volatile struct ALT_QSPI_DEVWR_s  ALT_QSPI_DEVWR_t;
+#endif  /* __ASSEMBLY__ */
+
+/* The byte offset of the ALT_QSPI_DEVWR register from the beginning of the component. */
+#define ALT_QSPI_DEVWR_OFST        0x8
+
+/*
+ * Register : QSPI Device Delay Register - delay
+ * 
+ * This register is used to introduce relative delays into the generation of the
+ * master output signals. All timings are defined in cycles of the qspi_clk.
+ * 
+ * Register Layout
+ * 
+ *  Bits    | Access | Reset | Description                             
+ * :--------|:-------|:------|:-----------------------------------------
+ *  [7:0]   | RW     | 0x0   | Clock Delay with qspi_n_ss_out          
+ *  [15:8]  | RW     | 0x0   | Clock Delay for Last Transaction Bit    
+ *  [23:16] | RW     | 0x0   | Clock Delay for Chip Select Deactivation
+ *  [31:24] | RW     | 0x0   | Clock Delay for Chip Select Deassert    
+ * 
+ */
+/*
+ * Field : Clock Delay with qspi_n_ss_out - init
+ * 
+ * Delay in master reference clocks between setting qspi_n_ss_out low and first bit
+ * transfer.
+ * 
+ * Field Access Macros:
+ * 
+ */
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_DELAY_INIT register field. */
+#define ALT_QSPI_DELAY_INIT_LSB        0
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_DELAY_INIT register field. */
+#define ALT_QSPI_DELAY_INIT_MSB        7
+/* The width in bits of the ALT_QSPI_DELAY_INIT register field. */
+#define ALT_QSPI_DELAY_INIT_WIDTH      8
+/* The mask used to set the ALT_QSPI_DELAY_INIT register field value. */
+#define ALT_QSPI_DELAY_INIT_SET_MSK    0x000000ff
+/* The mask used to clear the ALT_QSPI_DELAY_INIT register field value. */
+#define ALT_QSPI_DELAY_INIT_CLR_MSK    0xffffff00
+/* The reset value of the ALT_QSPI_DELAY_INIT register field. */
+#define ALT_QSPI_DELAY_INIT_RESET      0x0
+/* Extracts the ALT_QSPI_DELAY_INIT field value from a register. */
+#define ALT_QSPI_DELAY_INIT_GET(value) (((value) & 0x000000ff) >> 0)
+/* Produces a ALT_QSPI_DELAY_INIT register field value suitable for setting the register. */
+#define ALT_QSPI_DELAY_INIT_SET(value) (((value) << 0) & 0x000000ff)
+
+/*
+ * Field : Clock Delay for Last Transaction Bit - after
+ * 
+ * Delay in master reference clocks between last bit of current transaction and
+ * deasserting the device chip select (qspi_n_ss_out). By default, the chip select
+ * will be deasserted on the cycle following the completion of the current
+ * transaction.
+ * 
+ * Field Access Macros:
+ * 
+ */
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_DELAY_AFTER register field. */
+#define ALT_QSPI_DELAY_AFTER_LSB        8
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_DELAY_AFTER register field. */
+#define ALT_QSPI_DELAY_AFTER_MSB        15
+/* The width in bits of the ALT_QSPI_DELAY_AFTER register field. */
+#define ALT_QSPI_DELAY_AFTER_WIDTH      8
+/* The mask used to set the ALT_QSPI_DELAY_AFTER register field value. */
+#define ALT_QSPI_DELAY_AFTER_SET_MSK    0x0000ff00
+/* The mask used to clear the ALT_QSPI_DELAY_AFTER register field value. */
+#define ALT_QSPI_DELAY_AFTER_CLR_MSK    0xffff00ff
+/* The reset value of the ALT_QSPI_DELAY_AFTER register field. */
+#define ALT_QSPI_DELAY_AFTER_RESET      0x0
+/* Extracts the ALT_QSPI_DELAY_AFTER field value from a register. */
+#define ALT_QSPI_DELAY_AFTER_GET(value) (((value) & 0x0000ff00) >> 8)
+/* Produces a ALT_QSPI_DELAY_AFTER register field value suitable for setting the register. */
+#define ALT_QSPI_DELAY_AFTER_SET(value) (((value) << 8) & 0x0000ff00)
+
+/*
+ * Field : Clock Delay for Chip Select Deactivation - btwn
+ * 
+ * Delay in master reference clocks between one chip select being de-activated and
+ * the activation of another. This is used to ensure a quiet period between the
+ * selection of two different slaves and requires the transmit FIFO to be empty.
+ * 
+ * Field Access Macros:
+ * 
+ */
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_DELAY_BTWN register field. */
+#define ALT_QSPI_DELAY_BTWN_LSB        16
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_DELAY_BTWN register field. */
+#define ALT_QSPI_DELAY_BTWN_MSB        23
+/* The width in bits of the ALT_QSPI_DELAY_BTWN register field. */
+#define ALT_QSPI_DELAY_BTWN_WIDTH      8
+/* The mask used to set the ALT_QSPI_DELAY_BTWN register field value. */
+#define ALT_QSPI_DELAY_BTWN_SET_MSK    0x00ff0000
+/* The mask used to clear the ALT_QSPI_DELAY_BTWN register field value. */
+#define ALT_QSPI_DELAY_BTWN_CLR_MSK    0xff00ffff
+/* The reset value of the ALT_QSPI_DELAY_BTWN register field. */
+#define ALT_QSPI_DELAY_BTWN_RESET      0x0
+/* Extracts the ALT_QSPI_DELAY_BTWN field value from a register. */
+#define ALT_QSPI_DELAY_BTWN_GET(value) (((value) & 0x00ff0000) >> 16)
+/* Produces a ALT_QSPI_DELAY_BTWN register field value suitable for setting the register. */
+#define ALT_QSPI_DELAY_BTWN_SET(value) (((value) << 16) & 0x00ff0000)
+
+/*
+ * Field : Clock Delay for Chip Select Deassert - nss
+ * 
+ * Delay in master reference clocks for the length that the master mode chip select
+ * outputs are de-asserted between transactions. The minimum delay is always
+ * qspi_sck_out period to ensure the chip select is never re-asserted within an
+ * qspi_sck_out period.
+ * 
+ * Field Access Macros:
+ * 
+ */
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_DELAY_NSS register field. */
+#define ALT_QSPI_DELAY_NSS_LSB        24
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_DELAY_NSS register field. */
+#define ALT_QSPI_DELAY_NSS_MSB        31
+/* The width in bits of the ALT_QSPI_DELAY_NSS register field. */
+#define ALT_QSPI_DELAY_NSS_WIDTH      8
+/* The mask used to set the ALT_QSPI_DELAY_NSS register field value. */
+#define ALT_QSPI_DELAY_NSS_SET_MSK    0xff000000
+/* The mask used to clear the ALT_QSPI_DELAY_NSS register field value. */
+#define ALT_QSPI_DELAY_NSS_CLR_MSK    0x00ffffff
+/* The reset value of the ALT_QSPI_DELAY_NSS register field. */
+#define ALT_QSPI_DELAY_NSS_RESET      0x0
+/* Extracts the ALT_QSPI_DELAY_NSS field value from a register. */
+#define ALT_QSPI_DELAY_NSS_GET(value) (((value) & 0xff000000) >> 24)
+/* Produces a ALT_QSPI_DELAY_NSS register field value suitable for setting the register. */
+#define ALT_QSPI_DELAY_NSS_SET(value) (((value) << 24) & 0xff000000)
+
+#ifndef __ASSEMBLY__
+/*
+ * WARNING: The C register and register group struct declarations are provided for
+ * convenience and illustrative purposes. They should, however, be used with
+ * caution as the C language standard provides no guarantees about the alignment or
+ * atomicity of device memory accesses. The recommended practice for writing
+ * hardware drivers is to use the SoCAL access macros and alt_read_word() and
+ * alt_write_word() functions.
+ * 
+ * The struct declaration for register ALT_QSPI_DELAY.
+ */
+struct ALT_QSPI_DELAY_s
+{
+    uint32_t  init  :  8;  /* Clock Delay with qspi_n_ss_out */
+    uint32_t  after :  8;  /* Clock Delay for Last Transaction Bit */
+    uint32_t  btwn  :  8;  /* Clock Delay for Chip Select Deactivation */
+    uint32_t  nss   :  8;  /* Clock Delay for Chip Select Deassert */
+};
+
+/* The typedef declaration for register ALT_QSPI_DELAY. */
+typedef volatile struct ALT_QSPI_DELAY_s  ALT_QSPI_DELAY_t;
+#endif  /* __ASSEMBLY__ */
+
+/* The byte offset of the ALT_QSPI_DELAY register from the beginning of the component. */
+#define ALT_QSPI_DELAY_OFST        0xc
+
+/*
+ * Register : Read Data Capture Register - rddatacap
+ * 
+ * Register Layout
+ * 
+ *  Bits   | Access | Reset | Description
+ * :-------|:-------|:------|:------------
+ *  [0]    | RW     | 0x1   | Bypass     
+ *  [4:1]  | RW     | 0x0   | Read Delay 
+ *  [31:5] | ???    | 0x0   | *UNDEFINED*
+ * 
+ */
+/*
+ * Field : Bypass - byp
+ * 
+ * Controls bypass of the adapted loopback clock circuit
+ * 
+ * Field Enumeration Values:
+ * 
+ *  Enum                              | Value | Description                  
+ * :----------------------------------|:------|:------------------------------
+ *  ALT_QSPI_RDDATACAP_BYP_E_NOBYPASS | 0x0   | No Bypass                    
+ *  ALT_QSPI_RDDATACAP_BYP_E_BYPASS   | 0x1   | Bypass loopback clock circuit
+ * 
+ * Field Access Macros:
+ * 
+ */
+/*
+ * Enumerated value for register field ALT_QSPI_RDDATACAP_BYP
+ * 
+ * No Bypass
+ */
+#define ALT_QSPI_RDDATACAP_BYP_E_NOBYPASS   0x0
+/*
+ * Enumerated value for register field ALT_QSPI_RDDATACAP_BYP
+ * 
+ * Bypass loopback clock circuit
+ */
+#define ALT_QSPI_RDDATACAP_BYP_E_BYPASS     0x1
+
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_RDDATACAP_BYP register field. */
+#define ALT_QSPI_RDDATACAP_BYP_LSB        0
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_RDDATACAP_BYP register field. */
+#define ALT_QSPI_RDDATACAP_BYP_MSB        0
+/* The width in bits of the ALT_QSPI_RDDATACAP_BYP register field. */
+#define ALT_QSPI_RDDATACAP_BYP_WIDTH      1
+/* The mask used to set the ALT_QSPI_RDDATACAP_BYP register field value. */
+#define ALT_QSPI_RDDATACAP_BYP_SET_MSK    0x00000001
+/* The mask used to clear the ALT_QSPI_RDDATACAP_BYP register field value. */
+#define ALT_QSPI_RDDATACAP_BYP_CLR_MSK    0xfffffffe
+/* The reset value of the ALT_QSPI_RDDATACAP_BYP register field. */
+#define ALT_QSPI_RDDATACAP_BYP_RESET      0x1
+/* Extracts the ALT_QSPI_RDDATACAP_BYP field value from a register. */
+#define ALT_QSPI_RDDATACAP_BYP_GET(value) (((value) & 0x00000001) >> 0)
+/* Produces a ALT_QSPI_RDDATACAP_BYP register field value suitable for setting the register. */
+#define ALT_QSPI_RDDATACAP_BYP_SET(value) (((value) << 0) & 0x00000001)
+
+/*
+ * Field : Read Delay - delay
+ * 
+ * Delay the read data capturing logic by the programmed number of qspi_clk cycles
+ * 
+ * Field Access Macros:
+ * 
+ */
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_RDDATACAP_DELAY register field. */
+#define ALT_QSPI_RDDATACAP_DELAY_LSB        1
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_RDDATACAP_DELAY register field. */
+#define ALT_QSPI_RDDATACAP_DELAY_MSB        4
+/* The width in bits of the ALT_QSPI_RDDATACAP_DELAY register field. */
+#define ALT_QSPI_RDDATACAP_DELAY_WIDTH      4
+/* The mask used to set the ALT_QSPI_RDDATACAP_DELAY register field value. */
+#define ALT_QSPI_RDDATACAP_DELAY_SET_MSK    0x0000001e
+/* The mask used to clear the ALT_QSPI_RDDATACAP_DELAY register field value. */
+#define ALT_QSPI_RDDATACAP_DELAY_CLR_MSK    0xffffffe1
+/* The reset value of the ALT_QSPI_RDDATACAP_DELAY register field. */
+#define ALT_QSPI_RDDATACAP_DELAY_RESET      0x0
+/* Extracts the ALT_QSPI_RDDATACAP_DELAY field value from a register. */
+#define ALT_QSPI_RDDATACAP_DELAY_GET(value) (((value) & 0x0000001e) >> 1)
+/* Produces a ALT_QSPI_RDDATACAP_DELAY register field value suitable for setting the register. */
+#define ALT_QSPI_RDDATACAP_DELAY_SET(value) (((value) << 1) & 0x0000001e)
+
+#ifndef __ASSEMBLY__
+/*
+ * WARNING: The C register and register group struct declarations are provided for
+ * convenience and illustrative purposes. They should, however, be used with
+ * caution as the C language standard provides no guarantees about the alignment or
+ * atomicity of device memory accesses. The recommended practice for writing
+ * hardware drivers is to use the SoCAL access macros and alt_read_word() and
+ * alt_write_word() functions.
+ * 
+ * The struct declaration for register ALT_QSPI_RDDATACAP.
+ */
+struct ALT_QSPI_RDDATACAP_s
+{
+    uint32_t  byp   :  1;  /* Bypass */
+    uint32_t  delay :  4;  /* Read Delay */
+    uint32_t        : 27;  /* *UNDEFINED* */
+};
+
+/* The typedef declaration for register ALT_QSPI_RDDATACAP. */
+typedef volatile struct ALT_QSPI_RDDATACAP_s  ALT_QSPI_RDDATACAP_t;
+#endif  /* __ASSEMBLY__ */
+
+/* The byte offset of the ALT_QSPI_RDDATACAP register from the beginning of the component. */
+#define ALT_QSPI_RDDATACAP_OFST        0x10
+
+/*
+ * Register : Device Size Register - devsz
+ * 
+ * Register Layout
+ * 
+ *  Bits    | Access | Reset | Description                    
+ * :--------|:-------|:------|:--------------------------------
+ *  [3:0]   | RW     | 0x2   | Number of address Bytes        
+ *  [15:4]  | RW     | 0x100 | Number of Bytes per Device Page
+ *  [20:16] | RW     | 0x10  | Number of Bytes per Block      
+ *  [31:21] | ???    | 0x0   | *UNDEFINED*                    
+ * 
+ */
+/*
+ * Field : Number of address Bytes - numaddrbytes
+ * 
+ * Number of address bytes. A value of 0 indicates 1 byte.
+ * 
+ * Field Access Macros:
+ * 
+ */
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_DEVSZ_NUMADDRBYTES register field. */
+#define ALT_QSPI_DEVSZ_NUMADDRBYTES_LSB        0
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_DEVSZ_NUMADDRBYTES register field. */
+#define ALT_QSPI_DEVSZ_NUMADDRBYTES_MSB        3
+/* The width in bits of the ALT_QSPI_DEVSZ_NUMADDRBYTES register field. */
+#define ALT_QSPI_DEVSZ_NUMADDRBYTES_WIDTH      4
+/* The mask used to set the ALT_QSPI_DEVSZ_NUMADDRBYTES register field value. */
+#define ALT_QSPI_DEVSZ_NUMADDRBYTES_SET_MSK    0x0000000f
+/* The mask used to clear the ALT_QSPI_DEVSZ_NUMADDRBYTES register field value. */
+#define ALT_QSPI_DEVSZ_NUMADDRBYTES_CLR_MSK    0xfffffff0
+/* The reset value of the ALT_QSPI_DEVSZ_NUMADDRBYTES register field. */
+#define ALT_QSPI_DEVSZ_NUMADDRBYTES_RESET      0x2
+/* Extracts the ALT_QSPI_DEVSZ_NUMADDRBYTES field value from a register. */
+#define ALT_QSPI_DEVSZ_NUMADDRBYTES_GET(value) (((value) & 0x0000000f) >> 0)
+/* Produces a ALT_QSPI_DEVSZ_NUMADDRBYTES register field value suitable for setting the register. */
+#define ALT_QSPI_DEVSZ_NUMADDRBYTES_SET(value) (((value) << 0) & 0x0000000f)
+
+/*
+ * Field : Number of Bytes per Device Page - bytesperdevicepage
+ * 
+ * Number of bytes per device page. This is required by the controller for
+ * performing FLASH writes up to and across page boundaries.
+ * 
+ * Field Access Macros:
+ * 
+ */
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_DEVSZ_BYTESPERDEVICEPAGE register field. */
+#define ALT_QSPI_DEVSZ_BYTESPERDEVICEPAGE_LSB        4
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_DEVSZ_BYTESPERDEVICEPAGE register field. */
+#define ALT_QSPI_DEVSZ_BYTESPERDEVICEPAGE_MSB        15
+/* The width in bits of the ALT_QSPI_DEVSZ_BYTESPERDEVICEPAGE register field. */
+#define ALT_QSPI_DEVSZ_BYTESPERDEVICEPAGE_WIDTH      12
+/* The mask used to set the ALT_QSPI_DEVSZ_BYTESPERDEVICEPAGE register field value. */
+#define ALT_QSPI_DEVSZ_BYTESPERDEVICEPAGE_SET_MSK    0x0000fff0
+/* The mask used to clear the ALT_QSPI_DEVSZ_BYTESPERDEVICEPAGE register field value. */
+#define ALT_QSPI_DEVSZ_BYTESPERDEVICEPAGE_CLR_MSK    0xffff000f
+/* The reset value of the ALT_QSPI_DEVSZ_BYTESPERDEVICEPAGE register field. */
+#define ALT_QSPI_DEVSZ_BYTESPERDEVICEPAGE_RESET      0x100
+/* Extracts the ALT_QSPI_DEVSZ_BYTESPERDEVICEPAGE field value from a register. */
+#define ALT_QSPI_DEVSZ_BYTESPERDEVICEPAGE_GET(value) (((value) & 0x0000fff0) >> 4)
+/* Produces a ALT_QSPI_DEVSZ_BYTESPERDEVICEPAGE register field value suitable for setting the register. */
+#define ALT_QSPI_DEVSZ_BYTESPERDEVICEPAGE_SET(value) (((value) << 4) & 0x0000fff0)
+
+/*
+ * Field : Number of Bytes per Block - bytespersubsector
+ * 
+ * Number of bytes per Block. This is required by the controller for performing the
+ * write protection logic. The number of bytes per block must be a power of 2
+ * number.
+ * 
+ * Field Access Macros:
+ * 
+ */
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_DEVSZ_BYTESPERSUBSECTOR register field. */
+#define ALT_QSPI_DEVSZ_BYTESPERSUBSECTOR_LSB        16
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_DEVSZ_BYTESPERSUBSECTOR register field. */
+#define ALT_QSPI_DEVSZ_BYTESPERSUBSECTOR_MSB        20
+/* The width in bits of the ALT_QSPI_DEVSZ_BYTESPERSUBSECTOR register field. */
+#define ALT_QSPI_DEVSZ_BYTESPERSUBSECTOR_WIDTH      5
+/* The mask used to set the ALT_QSPI_DEVSZ_BYTESPERSUBSECTOR register field value. */
+#define ALT_QSPI_DEVSZ_BYTESPERSUBSECTOR_SET_MSK    0x001f0000
+/* The mask used to clear the ALT_QSPI_DEVSZ_BYTESPERSUBSECTOR register field value. */
+#define ALT_QSPI_DEVSZ_BYTESPERSUBSECTOR_CLR_MSK    0xffe0ffff
+/* The reset value of the ALT_QSPI_DEVSZ_BYTESPERSUBSECTOR register field. */
+#define ALT_QSPI_DEVSZ_BYTESPERSUBSECTOR_RESET      0x10
+/* Extracts the ALT_QSPI_DEVSZ_BYTESPERSUBSECTOR field value from a register. */
+#define ALT_QSPI_DEVSZ_BYTESPERSUBSECTOR_GET(value) (((value) & 0x001f0000) >> 16)
+/* Produces a ALT_QSPI_DEVSZ_BYTESPERSUBSECTOR register field value suitable for setting the register. */
+#define ALT_QSPI_DEVSZ_BYTESPERSUBSECTOR_SET(value) (((value) << 16) & 0x001f0000)
+
+#ifndef __ASSEMBLY__
+/*
+ * WARNING: The C register and register group struct declarations are provided for
+ * convenience and illustrative purposes. They should, however, be used with
+ * caution as the C language standard provides no guarantees about the alignment or
+ * atomicity of device memory accesses. The recommended practice for writing
+ * hardware drivers is to use the SoCAL access macros and alt_read_word() and
+ * alt_write_word() functions.
+ * 
+ * The struct declaration for register ALT_QSPI_DEVSZ.
+ */
+struct ALT_QSPI_DEVSZ_s
+{
+    uint32_t  numaddrbytes       :  4;  /* Number of address Bytes */
+    uint32_t  bytesperdevicepage : 12;  /* Number of Bytes per Device Page */
+    uint32_t  bytespersubsector  :  5;  /* Number of Bytes per Block */
+    uint32_t                     : 11;  /* *UNDEFINED* */
+};
+
+/* The typedef declaration for register ALT_QSPI_DEVSZ. */
+typedef volatile struct ALT_QSPI_DEVSZ_s  ALT_QSPI_DEVSZ_t;
+#endif  /* __ASSEMBLY__ */
+
+/* The byte offset of the ALT_QSPI_DEVSZ register from the beginning of the component. */
+#define ALT_QSPI_DEVSZ_OFST        0x14
+
+/*
+ * Register : SRAM Partition Register - srampart
+ * 
+ * Register Layout
+ * 
+ *  Bits   | Access | Reset | Description                 
+ * :-------|:-------|:------|:-----------------------------
+ *  [6:0]  | RW     | 0x40  | Indirect Read Partition Size
+ *  [31:7] | ???    | 0x0   | *UNDEFINED*                 
+ * 
+ */
+/*
+ * Field : Indirect Read Partition Size - addr
+ * 
+ * Defines the size of the indirect read partition in the SRAM, in units of SRAM
+ * locations. By default, half of the SRAM is reserved for indirect read operations
+ * and half for indirect write operations.
+ * 
+ * Field Access Macros:
+ * 
+ */
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_SRAMPART_ADDR register field. */
+#define ALT_QSPI_SRAMPART_ADDR_LSB        0
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_SRAMPART_ADDR register field. */
+#define ALT_QSPI_SRAMPART_ADDR_MSB        6
+/* The width in bits of the ALT_QSPI_SRAMPART_ADDR register field. */
+#define ALT_QSPI_SRAMPART_ADDR_WIDTH      7
+/* The mask used to set the ALT_QSPI_SRAMPART_ADDR register field value. */
+#define ALT_QSPI_SRAMPART_ADDR_SET_MSK    0x0000007f
+/* The mask used to clear the ALT_QSPI_SRAMPART_ADDR register field value. */
+#define ALT_QSPI_SRAMPART_ADDR_CLR_MSK    0xffffff80
+/* The reset value of the ALT_QSPI_SRAMPART_ADDR register field. */
+#define ALT_QSPI_SRAMPART_ADDR_RESET      0x40
+/* Extracts the ALT_QSPI_SRAMPART_ADDR field value from a register. */
+#define ALT_QSPI_SRAMPART_ADDR_GET(value) (((value) & 0x0000007f) >> 0)
+/* Produces a ALT_QSPI_SRAMPART_ADDR register field value suitable for setting the register. */
+#define ALT_QSPI_SRAMPART_ADDR_SET(value) (((value) << 0) & 0x0000007f)
+
+#ifndef __ASSEMBLY__
+/*
+ * WARNING: The C register and register group struct declarations are provided for
+ * convenience and illustrative purposes. They should, however, be used with
+ * caution as the C language standard provides no guarantees about the alignment or
+ * atomicity of device memory accesses. The recommended practice for writing
+ * hardware drivers is to use the SoCAL access macros and alt_read_word() and
+ * alt_write_word() functions.
+ * 
+ * The struct declaration for register ALT_QSPI_SRAMPART.
+ */
+struct ALT_QSPI_SRAMPART_s
+{
+    uint32_t  addr :  7;  /* Indirect Read Partition Size */
+    uint32_t       : 25;  /* *UNDEFINED* */
+};
+
+/* The typedef declaration for register ALT_QSPI_SRAMPART. */
+typedef volatile struct ALT_QSPI_SRAMPART_s  ALT_QSPI_SRAMPART_t;
+#endif  /* __ASSEMBLY__ */
+
+/* The byte offset of the ALT_QSPI_SRAMPART register from the beginning of the component. */
+#define ALT_QSPI_SRAMPART_OFST        0x18
+
+/*
+ * Register : Indirect AHB Address Trigger Register - indaddrtrig
+ * 
+ * Register Layout
+ * 
+ *  Bits   | Access | Reset | Description    
+ * :-------|:-------|:------|:----------------
+ *  [31:0] | RW     | 0x0   | Trigger Address
+ * 
+ */
+/*
+ * Field : Trigger Address - addr
+ * 
+ * This is the base address that will be used by the AHB controller. When the
+ * incoming AHB read access address matches a range of addresses from this trigger
+ * address to the trigger address + 15, then the AHB request will be completed by
+ * fetching data from the Indirect Controllers SRAM.
+ * 
+ * Field Access Macros:
+ * 
+ */
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_INDADDRTRIG_ADDR register field. */
+#define ALT_QSPI_INDADDRTRIG_ADDR_LSB        0
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_INDADDRTRIG_ADDR register field. */
+#define ALT_QSPI_INDADDRTRIG_ADDR_MSB        31
+/* The width in bits of the ALT_QSPI_INDADDRTRIG_ADDR register field. */
+#define ALT_QSPI_INDADDRTRIG_ADDR_WIDTH      32
+/* The mask used to set the ALT_QSPI_INDADDRTRIG_ADDR register field value. */
+#define ALT_QSPI_INDADDRTRIG_ADDR_SET_MSK    0xffffffff
+/* The mask used to clear the ALT_QSPI_INDADDRTRIG_ADDR register field value. */
+#define ALT_QSPI_INDADDRTRIG_ADDR_CLR_MSK    0x00000000
+/* The reset value of the ALT_QSPI_INDADDRTRIG_ADDR register field. */
+#define ALT_QSPI_INDADDRTRIG_ADDR_RESET      0x0
+/* Extracts the ALT_QSPI_INDADDRTRIG_ADDR field value from a register. */
+#define ALT_QSPI_INDADDRTRIG_ADDR_GET(value) (((value) & 0xffffffff) >> 0)
+/* Produces a ALT_QSPI_INDADDRTRIG_ADDR register field value suitable for setting the register. */
+#define ALT_QSPI_INDADDRTRIG_ADDR_SET(value) (((value) << 0) & 0xffffffff)
+
+#ifndef __ASSEMBLY__
+/*
+ * WARNING: The C register and register group struct declarations are provided for
+ * convenience and illustrative purposes. They should, however, be used with
+ * caution as the C language standard provides no guarantees about the alignment or
+ * atomicity of device memory accesses. The recommended practice for writing
+ * hardware drivers is to use the SoCAL access macros and alt_read_word() and
+ * alt_write_word() functions.
+ * 
+ * The struct declaration for register ALT_QSPI_INDADDRTRIG.
+ */
+struct ALT_QSPI_INDADDRTRIG_s
+{
+    uint32_t  addr : 32;  /* Trigger Address */
+};
+
+/* The typedef declaration for register ALT_QSPI_INDADDRTRIG. */
+typedef volatile struct ALT_QSPI_INDADDRTRIG_s  ALT_QSPI_INDADDRTRIG_t;
+#endif  /* __ASSEMBLY__ */
+
+/* The byte offset of the ALT_QSPI_INDADDRTRIG register from the beginning of the component. */
+#define ALT_QSPI_INDADDRTRIG_OFST        0x1c
+
+/*
+ * Register : DMA Peripheral Register - dmaper
+ * 
+ * Register Layout
+ * 
+ *  Bits    | Access | Reset | Description           
+ * :--------|:-------|:------|:-----------------------
+ *  [3:0]   | RW     | 0x0   | Number of Single Bytes
+ *  [7:4]   | ???    | 0x0   | *UNDEFINED*           
+ *  [11:8]  | RW     | 0x0   | Number of Burst Bytes 
+ *  [31:12] | ???    | 0x0   | *UNDEFINED*           
+ * 
+ */
+/*
+ * Field : Number of Single Bytes - numsglreqbytes
+ * 
+ * Number of bytes in a single type request on the DMA peripheral request. A
+ * programmed value of 0 represents a single byte. This should be setup before
+ * starting the indirect read or write operation. The actual number of bytes used
+ * is 2**(value in this register) which will simplify implementation.
+ * 
+ * Field Access Macros:
+ * 
+ */
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_DMAPER_NUMSGLREQBYTES register field. */
+#define ALT_QSPI_DMAPER_NUMSGLREQBYTES_LSB        0
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_DMAPER_NUMSGLREQBYTES register field. */
+#define ALT_QSPI_DMAPER_NUMSGLREQBYTES_MSB        3
+/* The width in bits of the ALT_QSPI_DMAPER_NUMSGLREQBYTES register field. */
+#define ALT_QSPI_DMAPER_NUMSGLREQBYTES_WIDTH      4
+/* The mask used to set the ALT_QSPI_DMAPER_NUMSGLREQBYTES register field value. */
+#define ALT_QSPI_DMAPER_NUMSGLREQBYTES_SET_MSK    0x0000000f
+/* The mask used to clear the ALT_QSPI_DMAPER_NUMSGLREQBYTES register field value. */
+#define ALT_QSPI_DMAPER_NUMSGLREQBYTES_CLR_MSK    0xfffffff0
+/* The reset value of the ALT_QSPI_DMAPER_NUMSGLREQBYTES register field. */
+#define ALT_QSPI_DMAPER_NUMSGLREQBYTES_RESET      0x0
+/* Extracts the ALT_QSPI_DMAPER_NUMSGLREQBYTES field value from a register. */
+#define ALT_QSPI_DMAPER_NUMSGLREQBYTES_GET(value) (((value) & 0x0000000f) >> 0)
+/* Produces a ALT_QSPI_DMAPER_NUMSGLREQBYTES register field value suitable for setting the register. */
+#define ALT_QSPI_DMAPER_NUMSGLREQBYTES_SET(value) (((value) << 0) & 0x0000000f)
+
+/*
+ * Field : Number of Burst Bytes - numburstreqbytes
+ * 
+ * Number of bytes in a burst type request on the DMA peripheral request. A
+ * programmed value of 0 represents a single byte. This should be setup before
+ * starting the indirect read or write operation. The actual number of bytes used
+ * is 2**(value in this register) which will simplify implementation.
+ * 
+ * Field Access Macros:
+ * 
+ */
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_DMAPER_NUMBURSTREQBYTES register field. */
+#define ALT_QSPI_DMAPER_NUMBURSTREQBYTES_LSB        8
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_DMAPER_NUMBURSTREQBYTES register field. */
+#define ALT_QSPI_DMAPER_NUMBURSTREQBYTES_MSB        11
+/* The width in bits of the ALT_QSPI_DMAPER_NUMBURSTREQBYTES register field. */
+#define ALT_QSPI_DMAPER_NUMBURSTREQBYTES_WIDTH      4
+/* The mask used to set the ALT_QSPI_DMAPER_NUMBURSTREQBYTES register field value. */
+#define ALT_QSPI_DMAPER_NUMBURSTREQBYTES_SET_MSK    0x00000f00
+/* The mask used to clear the ALT_QSPI_DMAPER_NUMBURSTREQBYTES register field value. */
+#define ALT_QSPI_DMAPER_NUMBURSTREQBYTES_CLR_MSK    0xfffff0ff
+/* The reset value of the ALT_QSPI_DMAPER_NUMBURSTREQBYTES register field. */
+#define ALT_QSPI_DMAPER_NUMBURSTREQBYTES_RESET      0x0
+/* Extracts the ALT_QSPI_DMAPER_NUMBURSTREQBYTES field value from a register. */
+#define ALT_QSPI_DMAPER_NUMBURSTREQBYTES_GET(value) (((value) & 0x00000f00) >> 8)
+/* Produces a ALT_QSPI_DMAPER_NUMBURSTREQBYTES register field value suitable for setting the register. */
+#define ALT_QSPI_DMAPER_NUMBURSTREQBYTES_SET(value) (((value) << 8) & 0x00000f00)
+
+#ifndef __ASSEMBLY__
+/*
+ * WARNING: The C register and register group struct declarations are provided for
+ * convenience and illustrative purposes. They should, however, be used with
+ * caution as the C language standard provides no guarantees about the alignment or
+ * atomicity of device memory accesses. The recommended practice for writing
+ * hardware drivers is to use the SoCAL access macros and alt_read_word() and
+ * alt_write_word() functions.
+ * 
+ * The struct declaration for register ALT_QSPI_DMAPER.
+ */
+struct ALT_QSPI_DMAPER_s
+{
+    uint32_t  numsglreqbytes   :  4;  /* Number of Single Bytes */
+    uint32_t                   :  4;  /* *UNDEFINED* */
+    uint32_t  numburstreqbytes :  4;  /* Number of Burst Bytes */
+    uint32_t                   : 20;  /* *UNDEFINED* */
+};
+
+/* The typedef declaration for register ALT_QSPI_DMAPER. */
+typedef volatile struct ALT_QSPI_DMAPER_s  ALT_QSPI_DMAPER_t;
+#endif  /* __ASSEMBLY__ */
+
+/* The byte offset of the ALT_QSPI_DMAPER register from the beginning of the component. */
+#define ALT_QSPI_DMAPER_OFST        0x20
+
+/*
+ * Register : Remap Address Register - remapaddr
+ * 
+ * This register is used to remap an incoming AHB address to a different address
+ * used by the FLASH device.
+ * 
+ * Register Layout
+ * 
+ *  Bits   | Access | Reset | Description         
+ * :-------|:-------|:------|:---------------------
+ *  [31:0] | RW     | 0x0   | Remap Address Offset
+ * 
+ */
+/*
+ * Field : Remap Address Offset - value
+ * 
+ * This offset is added to the incoming AHB address to determine the address used
+ * by the FLASH device.
+ * 
+ * Field Access Macros:
+ * 
+ */
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_REMAPADDR_VALUE register field. */
+#define ALT_QSPI_REMAPADDR_VALUE_LSB        0
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_REMAPADDR_VALUE register field. */
+#define ALT_QSPI_REMAPADDR_VALUE_MSB        31
+/* The width in bits of the ALT_QSPI_REMAPADDR_VALUE register field. */
+#define ALT_QSPI_REMAPADDR_VALUE_WIDTH      32
+/* The mask used to set the ALT_QSPI_REMAPADDR_VALUE register field value. */
+#define ALT_QSPI_REMAPADDR_VALUE_SET_MSK    0xffffffff
+/* The mask used to clear the ALT_QSPI_REMAPADDR_VALUE register field value. */
+#define ALT_QSPI_REMAPADDR_VALUE_CLR_MSK    0x00000000
+/* The reset value of the ALT_QSPI_REMAPADDR_VALUE register field. */
+#define ALT_QSPI_REMAPADDR_VALUE_RESET      0x0
+/* Extracts the ALT_QSPI_REMAPADDR_VALUE field value from a register. */
+#define ALT_QSPI_REMAPADDR_VALUE_GET(value) (((value) & 0xffffffff) >> 0)
+/* Produces a ALT_QSPI_REMAPADDR_VALUE register field value suitable for setting the register. */
+#define ALT_QSPI_REMAPADDR_VALUE_SET(value) (((value) << 0) & 0xffffffff)
+
+#ifndef __ASSEMBLY__
+/*
+ * WARNING: The C register and register group struct declarations are provided for
+ * convenience and illustrative purposes. They should, however, be used with
+ * caution as the C language standard provides no guarantees about the alignment or
+ * atomicity of device memory accesses. The recommended practice for writing
+ * hardware drivers is to use the SoCAL access macros and alt_read_word() and
+ * alt_write_word() functions.
+ * 
+ * The struct declaration for register ALT_QSPI_REMAPADDR.
+ */
+struct ALT_QSPI_REMAPADDR_s
+{
+    uint32_t  value : 32;  /* Remap Address Offset */
+};
+
+/* The typedef declaration for register ALT_QSPI_REMAPADDR. */
+typedef volatile struct ALT_QSPI_REMAPADDR_s  ALT_QSPI_REMAPADDR_t;
+#endif  /* __ASSEMBLY__ */
+
+/* The byte offset of the ALT_QSPI_REMAPADDR register from the beginning of the component. */
+#define ALT_QSPI_REMAPADDR_OFST        0x24
+
+/*
+ * Register : Mode Bit Register - modebit
+ * 
+ * Register Layout
+ * 
+ *  Bits   | Access | Reset | Description
+ * :-------|:-------|:------|:------------
+ *  [7:0]  | RW     | 0x0   | Mode       
+ *  [31:8] | ???    | 0x0   | *UNDEFINED*
+ * 
+ */
+/*
+ * Field : Mode - mode
+ * 
+ * These are the 8 mode bits that are sent to the device following the address
+ * bytes if mode bit transmission has been enabled.
+ * 
+ * Field Access Macros:
+ * 
+ */
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_MODBIT_MOD register field. */
+#define ALT_QSPI_MODBIT_MOD_LSB        0
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_MODBIT_MOD register field. */
+#define ALT_QSPI_MODBIT_MOD_MSB        7
+/* The width in bits of the ALT_QSPI_MODBIT_MOD register field. */
+#define ALT_QSPI_MODBIT_MOD_WIDTH      8
+/* The mask used to set the ALT_QSPI_MODBIT_MOD register field value. */
+#define ALT_QSPI_MODBIT_MOD_SET_MSK    0x000000ff
+/* The mask used to clear the ALT_QSPI_MODBIT_MOD register field value. */
+#define ALT_QSPI_MODBIT_MOD_CLR_MSK    0xffffff00
+/* The reset value of the ALT_QSPI_MODBIT_MOD register field. */
+#define ALT_QSPI_MODBIT_MOD_RESET      0x0
+/* Extracts the ALT_QSPI_MODBIT_MOD field value from a register. */
+#define ALT_QSPI_MODBIT_MOD_GET(value) (((value) & 0x000000ff) >> 0)
+/* Produces a ALT_QSPI_MODBIT_MOD register field value suitable for setting the register. */
+#define ALT_QSPI_MODBIT_MOD_SET(value) (((value) << 0) & 0x000000ff)
+
+#ifndef __ASSEMBLY__
+/*
+ * WARNING: The C register and register group struct declarations are provided for
+ * convenience and illustrative purposes. They should, however, be used with
+ * caution as the C language standard provides no guarantees about the alignment or
+ * atomicity of device memory accesses. The recommended practice for writing
+ * hardware drivers is to use the SoCAL access macros and alt_read_word() and
+ * alt_write_word() functions.
+ * 
+ * The struct declaration for register ALT_QSPI_MODBIT.
+ */
+struct ALT_QSPI_MODBIT_s
+{
+    uint32_t  mode :  8;  /* Mode */
+    uint32_t       : 24;  /* *UNDEFINED* */
+};
+
+/* The typedef declaration for register ALT_QSPI_MODBIT. */
+typedef volatile struct ALT_QSPI_MODBIT_s  ALT_QSPI_MODBIT_t;
+#endif  /* __ASSEMBLY__ */
+
+/* The byte offset of the ALT_QSPI_MODBIT register from the beginning of the component. */
+#define ALT_QSPI_MODBIT_OFST        0x28
+
+/*
+ * Register : SRAM Fill Register - sramfill
+ * 
+ * Register Layout
+ * 
+ *  Bits    | Access | Reset | Description                                                       
+ * :--------|:-------|:------|:-------------------------------------------------------------------
+ *  [15:0]  | R      | 0x0   | SRAM Fill Level (Indirect Read Partition). In units of SRAM WORDS 
+ *  [31:16] | R      | 0x0   | SRAM Fill Level (Indirect Write Partition). In units of SRAM WORDS
+ * 
+ */
+/*
+ * Field : SRAM Fill Level (Indirect Read Partition). In units of SRAM WORDS - indrdpart
+ * 
+ * Field Access Macros:
+ * 
+ */
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_SRAMFILL_INDRDPART register field. */
+#define ALT_QSPI_SRAMFILL_INDRDPART_LSB        0
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_SRAMFILL_INDRDPART register field. */
+#define ALT_QSPI_SRAMFILL_INDRDPART_MSB        15
+/* The width in bits of the ALT_QSPI_SRAMFILL_INDRDPART register field. */
+#define ALT_QSPI_SRAMFILL_INDRDPART_WIDTH      16
+/* The mask used to set the ALT_QSPI_SRAMFILL_INDRDPART register field value. */
+#define ALT_QSPI_SRAMFILL_INDRDPART_SET_MSK    0x0000ffff
+/* The mask used to clear the ALT_QSPI_SRAMFILL_INDRDPART register field value. */
+#define ALT_QSPI_SRAMFILL_INDRDPART_CLR_MSK    0xffff0000
+/* The reset value of the ALT_QSPI_SRAMFILL_INDRDPART register field. */
+#define ALT_QSPI_SRAMFILL_INDRDPART_RESET      0x0
+/* Extracts the ALT_QSPI_SRAMFILL_INDRDPART field value from a register. */
+#define ALT_QSPI_SRAMFILL_INDRDPART_GET(value) (((value) & 0x0000ffff) >> 0)
+/* Produces a ALT_QSPI_SRAMFILL_INDRDPART register field value suitable for setting the register. */
+#define ALT_QSPI_SRAMFILL_INDRDPART_SET(value) (((value) << 0) & 0x0000ffff)
+
+/*
+ * Field : SRAM Fill Level (Indirect Write Partition). In units of SRAM WORDS - indwrpart
+ * 
+ * Field Access Macros:
+ * 
+ */
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_SRAMFILL_INDWRPART register field. */
+#define ALT_QSPI_SRAMFILL_INDWRPART_LSB        16
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_SRAMFILL_INDWRPART register field. */
+#define ALT_QSPI_SRAMFILL_INDWRPART_MSB        31
+/* The width in bits of the ALT_QSPI_SRAMFILL_INDWRPART register field. */
+#define ALT_QSPI_SRAMFILL_INDWRPART_WIDTH      16
+/* The mask used to set the ALT_QSPI_SRAMFILL_INDWRPART register field value. */
+#define ALT_QSPI_SRAMFILL_INDWRPART_SET_MSK    0xffff0000
+/* The mask used to clear the ALT_QSPI_SRAMFILL_INDWRPART register field value. */
+#define ALT_QSPI_SRAMFILL_INDWRPART_CLR_MSK    0x0000ffff
+/* The reset value of the ALT_QSPI_SRAMFILL_INDWRPART register field. */
+#define ALT_QSPI_SRAMFILL_INDWRPART_RESET      0x0
+/* Extracts the ALT_QSPI_SRAMFILL_INDWRPART field value from a register. */
+#define ALT_QSPI_SRAMFILL_INDWRPART_GET(value) (((value) & 0xffff0000) >> 16)
+/* Produces a ALT_QSPI_SRAMFILL_INDWRPART register field value suitable for setting the register. */
+#define ALT_QSPI_SRAMFILL_INDWRPART_SET(value) (((value) << 16) & 0xffff0000)
+
+#ifndef __ASSEMBLY__
+/*
+ * WARNING: The C register and register group struct declarations are provided for
+ * convenience and illustrative purposes. They should, however, be used with
+ * caution as the C language standard provides no guarantees about the alignment or
+ * atomicity of device memory accesses. The recommended practice for writing
+ * hardware drivers is to use the SoCAL access macros and alt_read_word() and
+ * alt_write_word() functions.
+ * 
+ * The struct declaration for register ALT_QSPI_SRAMFILL.
+ */
+struct ALT_QSPI_SRAMFILL_s
+{
+    const uint32_t  indrdpart : 16;  /* SRAM Fill Level (Indirect Read Partition). In units of SRAM WORDS */
+    const uint32_t  indwrpart : 16;  /* SRAM Fill Level (Indirect Write Partition). In units of SRAM WORDS */
+};
+
+/* The typedef declaration for register ALT_QSPI_SRAMFILL. */
+typedef volatile struct ALT_QSPI_SRAMFILL_s  ALT_QSPI_SRAMFILL_t;
+#endif  /* __ASSEMBLY__ */
+
+/* The byte offset of the ALT_QSPI_SRAMFILL register from the beginning of the component. */
+#define ALT_QSPI_SRAMFILL_OFST        0x2c
+
+/*
+ * Register : TX Threshold Register - txthresh
+ * 
+ * Register Layout
+ * 
+ *  Bits   | Access | Reset | Description
+ * :-------|:-------|:------|:------------
+ *  [3:0]  | RW     | 0x1   | Level      
+ *  [31:4] | ???    | 0x0   | *UNDEFINED*
+ * 
+ */
+/*
+ * Field : Level - level
+ * 
+ * Defines the level at which the transmit FIFO not full interrupt is generated
+ * 
+ * Field Access Macros:
+ * 
+ */
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_TXTHRESH_LEVEL register field. */
+#define ALT_QSPI_TXTHRESH_LEVEL_LSB        0
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_TXTHRESH_LEVEL register field. */
+#define ALT_QSPI_TXTHRESH_LEVEL_MSB        3
+/* The width in bits of the ALT_QSPI_TXTHRESH_LEVEL register field. */
+#define ALT_QSPI_TXTHRESH_LEVEL_WIDTH      4
+/* The mask used to set the ALT_QSPI_TXTHRESH_LEVEL register field value. */
+#define ALT_QSPI_TXTHRESH_LEVEL_SET_MSK    0x0000000f
+/* The mask used to clear the ALT_QSPI_TXTHRESH_LEVEL register field value. */
+#define ALT_QSPI_TXTHRESH_LEVEL_CLR_MSK    0xfffffff0
+/* The reset value of the ALT_QSPI_TXTHRESH_LEVEL register field. */
+#define ALT_QSPI_TXTHRESH_LEVEL_RESET      0x1
+/* Extracts the ALT_QSPI_TXTHRESH_LEVEL field value from a register. */
+#define ALT_QSPI_TXTHRESH_LEVEL_GET(value) (((value) & 0x0000000f) >> 0)
+/* Produces a ALT_QSPI_TXTHRESH_LEVEL register field value suitable for setting the register. */
+#define ALT_QSPI_TXTHRESH_LEVEL_SET(value) (((value) << 0) & 0x0000000f)
+
+#ifndef __ASSEMBLY__
+/*
+ * WARNING: The C register and register group struct declarations are provided for
+ * convenience and illustrative purposes. They should, however, be used with
+ * caution as the C language standard provides no guarantees about the alignment or
+ * atomicity of device memory accesses. The recommended practice for writing
+ * hardware drivers is to use the SoCAL access macros and alt_read_word() and
+ * alt_write_word() functions.
+ * 
+ * The struct declaration for register ALT_QSPI_TXTHRESH.
+ */
+struct ALT_QSPI_TXTHRESH_s
+{
+    uint32_t  level :  4;  /* Level */
+    uint32_t        : 28;  /* *UNDEFINED* */
+};
+
+/* The typedef declaration for register ALT_QSPI_TXTHRESH. */
+typedef volatile struct ALT_QSPI_TXTHRESH_s  ALT_QSPI_TXTHRESH_t;
+#endif  /* __ASSEMBLY__ */
+
+/* The byte offset of the ALT_QSPI_TXTHRESH register from the beginning of the component. */
+#define ALT_QSPI_TXTHRESH_OFST        0x30
+
+/*
+ * Register : RX Threshold Register - rxthresh
+ * 
+ * Device Instruction Register
+ * 
+ * Register Layout
+ * 
+ *  Bits   | Access | Reset | Description
+ * :-------|:-------|:------|:------------
+ *  [3:0]  | RW     | 0x1   | Level      
+ *  [31:4] | ???    | 0x0   | *UNDEFINED*
+ * 
+ */
+/*
+ * Field : Level - level
+ * 
+ * Defines the level at which the receive FIFO not empty interrupt is generated
+ * 
+ * Field Access Macros:
+ * 
+ */
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_RXTHRESH_LEVEL register field. */
+#define ALT_QSPI_RXTHRESH_LEVEL_LSB        0
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_RXTHRESH_LEVEL register field. */
+#define ALT_QSPI_RXTHRESH_LEVEL_MSB        3
+/* The width in bits of the ALT_QSPI_RXTHRESH_LEVEL register field. */
+#define ALT_QSPI_RXTHRESH_LEVEL_WIDTH      4
+/* The mask used to set the ALT_QSPI_RXTHRESH_LEVEL register field value. */
+#define ALT_QSPI_RXTHRESH_LEVEL_SET_MSK    0x0000000f
+/* The mask used to clear the ALT_QSPI_RXTHRESH_LEVEL register field value. */
+#define ALT_QSPI_RXTHRESH_LEVEL_CLR_MSK    0xfffffff0
+/* The reset value of the ALT_QSPI_RXTHRESH_LEVEL register field. */
+#define ALT_QSPI_RXTHRESH_LEVEL_RESET      0x1
+/* Extracts the ALT_QSPI_RXTHRESH_LEVEL field value from a register. */
+#define ALT_QSPI_RXTHRESH_LEVEL_GET(value) (((value) & 0x0000000f) >> 0)
+/* Produces a ALT_QSPI_RXTHRESH_LEVEL register field value suitable for setting the register. */
+#define ALT_QSPI_RXTHRESH_LEVEL_SET(value) (((value) << 0) & 0x0000000f)
+
+#ifndef __ASSEMBLY__
+/*
+ * WARNING: The C register and register group struct declarations are provided for
+ * convenience and illustrative purposes. They should, however, be used with
+ * caution as the C language standard provides no guarantees about the alignment or
+ * atomicity of device memory accesses. The recommended practice for writing
+ * hardware drivers is to use the SoCAL access macros and alt_read_word() and
+ * alt_write_word() functions.
+ * 
+ * The struct declaration for register ALT_QSPI_RXTHRESH.
+ */
+struct ALT_QSPI_RXTHRESH_s
+{
+    uint32_t  level :  4;  /* Level */
+    uint32_t        : 28;  /* *UNDEFINED* */
+};
+
+/* The typedef declaration for register ALT_QSPI_RXTHRESH. */
+typedef volatile struct ALT_QSPI_RXTHRESH_s  ALT_QSPI_RXTHRESH_t;
+#endif  /* __ASSEMBLY__ */
+
+/* The byte offset of the ALT_QSPI_RXTHRESH register from the beginning of the component. */
+#define ALT_QSPI_RXTHRESH_OFST        0x34
+
+/*
+ * Register : Interrupt Status Register - irqstat
+ * 
+ * The status fields in this register are set when the described event occurs and
+ * the interrupt is enabled in the mask register. When any of these bit fields are
+ * set, the interrupt output is asserted high. The fields are each cleared by
+ * writing a 1 to the field. Note that bit fields 7 thru 11 are only valid when
+ * legacy SPI mode is active.
+ * 
+ * Register Layout
+ * 
+ *  Bits    | Access | Reset | Description                        
+ * :--------|:-------|:------|:------------------------------------
+ *  [0]     | ???    | 0x0   | *UNDEFINED*                        
+ *  [1]     | RW     | 0x0   | Underflow Detected                 
+ *  [2]     | RW     | 0x0   | Indirect Operation Complete        
+ *  [3]     | RW     | 0x0   | Indirect Read Reject               
+ *  [4]     | RW     | 0x0   | Protected Area Write Attempt       
+ *  [5]     | RW     | 0x0   | Illegal AHB Access Detected        
+ *  [6]     | RW     | 0x0   | Transfer Watermark Reached         
+ *  [7]     | RW     | 0x0   | Receive Overflow                   
+ *  [8]     | RW     | 0x1   | Transmit FIFO Compared to Threshold
+ *  [9]     | RW     | 0x0   | Transmit FIFO Full                 
+ *  [10]    | RW     | 0x0   | Receive FIFO Compared to Threshold 
+ *  [11]    | RW     | 0x0   | Receive FIFO Full                  
+ *  [12]    | RW     | 0x0   | Indirect Read Partition overflow   
+ *  [31:13] | ???    | 0x0   | *UNDEFINED*                        
+ * 
+ */
+/*
+ * Field : Underflow Detected - underflowdet
+ * 
+ * An underflow is detected when an attempt to transfer data is made when the
+ * transmit FIFO is empty. This may occur when the AHB write data is being supplied
+ * too slowly to keep up with the requested write operation. This bit is reset only
+ * by a system reset and cleared only when the register is read.
+ * 
+ * Field Enumeration Values:
+ * 
+ *  Enum                                        | Value | Description 
+ * :--------------------------------------------|:------|:-------------
+ *  ALT_QSPI_IRQSTAT_UNDERFLOWDET_E_UNDERFLOW   | 0x1   | Underflow   
+ *  ALT_QSPI_IRQSTAT_UNDERFLOWDET_E_NOUNDERFLOW | 0x0   | No Underflow
+ * 
+ * Field Access Macros:
+ * 
+ */
+/*
+ * Enumerated value for register field ALT_QSPI_IRQSTAT_UNDERFLOWDET
+ * 
+ * Underflow
+ */
+#define ALT_QSPI_IRQSTAT_UNDERFLOWDET_E_UNDERFLOW   0x1
+/*
+ * Enumerated value for register field ALT_QSPI_IRQSTAT_UNDERFLOWDET
+ * 
+ * No Underflow
+ */
+#define ALT_QSPI_IRQSTAT_UNDERFLOWDET_E_NOUNDERFLOW 0x0
+
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_IRQSTAT_UNDERFLOWDET register field. */
+#define ALT_QSPI_IRQSTAT_UNDERFLOWDET_LSB        1
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_IRQSTAT_UNDERFLOWDET register field. */
+#define ALT_QSPI_IRQSTAT_UNDERFLOWDET_MSB        1
+/* The width in bits of the ALT_QSPI_IRQSTAT_UNDERFLOWDET register field. */
+#define ALT_QSPI_IRQSTAT_UNDERFLOWDET_WIDTH      1
+/* The mask used to set the ALT_QSPI_IRQSTAT_UNDERFLOWDET register field value. */
+#define ALT_QSPI_IRQSTAT_UNDERFLOWDET_SET_MSK    0x00000002
+/* The mask used to clear the ALT_QSPI_IRQSTAT_UNDERFLOWDET register field value. */
+#define ALT_QSPI_IRQSTAT_UNDERFLOWDET_CLR_MSK    0xfffffffd
+/* The reset value of the ALT_QSPI_IRQSTAT_UNDERFLOWDET register field. */
+#define ALT_QSPI_IRQSTAT_UNDERFLOWDET_RESET      0x0
+/* Extracts the ALT_QSPI_IRQSTAT_UNDERFLOWDET field value from a register. */
+#define ALT_QSPI_IRQSTAT_UNDERFLOWDET_GET(value) (((value) & 0x00000002) >> 1)
+/* Produces a ALT_QSPI_IRQSTAT_UNDERFLOWDET register field value suitable for setting the register. */
+#define ALT_QSPI_IRQSTAT_UNDERFLOWDET_SET(value) (((value) << 1) & 0x00000002)
+
+/*
+ * Field : Indirect Operation Complete - indopdone
+ * 
+ * Controller has completed last triggered indirect operation
+ * 
+ * Field Enumeration Values:
+ * 
+ *  Enum                                      | Value | Description                 
+ * :------------------------------------------|:------|:-----------------------------
+ *  ALT_QSPI_IRQSTAT_INDOPDONE_E_INDIRECTOP   | 0x1   | Completed Indirect Operation
+ *  ALT_QSPI_IRQSTAT_INDOPDONE_E_NOINDIRECTOP | 0x0   | No Indirect Operation       
+ * 
+ * Field Access Macros:
+ * 
+ */
+/*
+ * Enumerated value for register field ALT_QSPI_IRQSTAT_INDOPDONE
+ * 
+ * Completed Indirect Operation
+ */
+#define ALT_QSPI_IRQSTAT_INDOPDONE_E_INDIRECTOP     0x1
+/*
+ * Enumerated value for register field ALT_QSPI_IRQSTAT_INDOPDONE
+ * 
+ * No Indirect Operation
+ */
+#define ALT_QSPI_IRQSTAT_INDOPDONE_E_NOINDIRECTOP   0x0
+
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_IRQSTAT_INDOPDONE register field. */
+#define ALT_QSPI_IRQSTAT_INDOPDONE_LSB        2
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_IRQSTAT_INDOPDONE register field. */
+#define ALT_QSPI_IRQSTAT_INDOPDONE_MSB        2
+/* The width in bits of the ALT_QSPI_IRQSTAT_INDOPDONE register field. */
+#define ALT_QSPI_IRQSTAT_INDOPDONE_WIDTH      1
+/* The mask used to set the ALT_QSPI_IRQSTAT_INDOPDONE register field value. */
+#define ALT_QSPI_IRQSTAT_INDOPDONE_SET_MSK    0x00000004
+/* The mask used to clear the ALT_QSPI_IRQSTAT_INDOPDONE register field value. */
+#define ALT_QSPI_IRQSTAT_INDOPDONE_CLR_MSK    0xfffffffb
+/* The reset value of the ALT_QSPI_IRQSTAT_INDOPDONE register field. */
+#define ALT_QSPI_IRQSTAT_INDOPDONE_RESET      0x0
+/* Extracts the ALT_QSPI_IRQSTAT_INDOPDONE field value from a register. */
+#define ALT_QSPI_IRQSTAT_INDOPDONE_GET(value) (((value) & 0x00000004) >> 2)
+/* Produces a ALT_QSPI_IRQSTAT_INDOPDONE register field value suitable for setting the register. */
+#define ALT_QSPI_IRQSTAT_INDOPDONE_SET(value) (((value) << 2) & 0x00000004)
+
+/*
+ * Field : Indirect Read Reject - indrdreject
+ * 
+ * Indirect operation was requested but could not be accepted. Two indirect
+ * operations already in storage.
+ * 
+ * Field Enumeration Values:
+ * 
+ *  Enum                                         | Value | Description                 
+ * :---------------------------------------------|:------|:-----------------------------
+ *  ALT_QSPI_IRQSTAT_INDRDREJECT_E_INDIRECTREQ   | 0x1   | Indirect Operation Requested
+ *  ALT_QSPI_IRQSTAT_INDRDREJECT_E_NOINDIRECTREQ | 0x0   | No Indirect Operation       
+ * 
+ * Field Access Macros:
+ * 
+ */
+/*
+ * Enumerated value for register field ALT_QSPI_IRQSTAT_INDRDREJECT
+ * 
+ * Indirect Operation Requested
+ */
+#define ALT_QSPI_IRQSTAT_INDRDREJECT_E_INDIRECTREQ      0x1
+/*
+ * Enumerated value for register field ALT_QSPI_IRQSTAT_INDRDREJECT
+ * 
+ * No Indirect Operation
+ */
+#define ALT_QSPI_IRQSTAT_INDRDREJECT_E_NOINDIRECTREQ    0x0
+
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_IRQSTAT_INDRDREJECT register field. */
+#define ALT_QSPI_IRQSTAT_INDRDREJECT_LSB        3
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_IRQSTAT_INDRDREJECT register field. */
+#define ALT_QSPI_IRQSTAT_INDRDREJECT_MSB        3
+/* The width in bits of the ALT_QSPI_IRQSTAT_INDRDREJECT register field. */
+#define ALT_QSPI_IRQSTAT_INDRDREJECT_WIDTH      1
+/* The mask used to set the ALT_QSPI_IRQSTAT_INDRDREJECT register field value. */
+#define ALT_QSPI_IRQSTAT_INDRDREJECT_SET_MSK    0x00000008
+/* The mask used to clear the ALT_QSPI_IRQSTAT_INDRDREJECT register field value. */
+#define ALT_QSPI_IRQSTAT_INDRDREJECT_CLR_MSK    0xfffffff7
+/* The reset value of the ALT_QSPI_IRQSTAT_INDRDREJECT register field. */
+#define ALT_QSPI_IRQSTAT_INDRDREJECT_RESET      0x0
+/* Extracts the ALT_QSPI_IRQSTAT_INDRDREJECT field value from a register. */
+#define ALT_QSPI_IRQSTAT_INDRDREJECT_GET(value) (((value) & 0x00000008) >> 3)
+/* Produces a ALT_QSPI_IRQSTAT_INDRDREJECT register field value suitable for setting the register. */
+#define ALT_QSPI_IRQSTAT_INDRDREJECT_SET(value) (((value) << 3) & 0x00000008)
+
+/*
+ * Field : Protected Area Write Attempt - protwrattempt
+ * 
+ * Write to protected area was attempted and rejected.
+ * 
+ * Field Enumeration Values:
+ * 
+ *  Enum                                      | Value | Description                    
+ * :------------------------------------------|:------|:--------------------------------
+ *  ALT_QSPI_IRQSTAT_PROTWRATTEMPT_E_WRPROT   | 0x1   | Write Attempt to protected area
+ *  ALT_QSPI_IRQSTAT_PROTWRATTEMPT_E_NOWRPROT | 0x0   | No Write Attempt               
+ * 
+ * Field Access Macros:
+ * 
+ */
+/*
+ * Enumerated value for register field ALT_QSPI_IRQSTAT_PROTWRATTEMPT
+ * 
+ * Write Attempt to protected area
+ */
+#define ALT_QSPI_IRQSTAT_PROTWRATTEMPT_E_WRPROT     0x1
+/*
+ * Enumerated value for register field ALT_QSPI_IRQSTAT_PROTWRATTEMPT
+ * 
+ * No Write Attempt
+ */
+#define ALT_QSPI_IRQSTAT_PROTWRATTEMPT_E_NOWRPROT   0x0
+
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_IRQSTAT_PROTWRATTEMPT register field. */
+#define ALT_QSPI_IRQSTAT_PROTWRATTEMPT_LSB        4
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_IRQSTAT_PROTWRATTEMPT register field. */
+#define ALT_QSPI_IRQSTAT_PROTWRATTEMPT_MSB        4
+/* The width in bits of the ALT_QSPI_IRQSTAT_PROTWRATTEMPT register field. */
+#define ALT_QSPI_IRQSTAT_PROTWRATTEMPT_WIDTH      1
+/* The mask used to set the ALT_QSPI_IRQSTAT_PROTWRATTEMPT register field value. */
+#define ALT_QSPI_IRQSTAT_PROTWRATTEMPT_SET_MSK    0x00000010
+/* The mask used to clear the ALT_QSPI_IRQSTAT_PROTWRATTEMPT register field value. */
+#define ALT_QSPI_IRQSTAT_PROTWRATTEMPT_CLR_MSK    0xffffffef
+/* The reset value of the ALT_QSPI_IRQSTAT_PROTWRATTEMPT register field. */
+#define ALT_QSPI_IRQSTAT_PROTWRATTEMPT_RESET      0x0
+/* Extracts the ALT_QSPI_IRQSTAT_PROTWRATTEMPT field value from a register. */
+#define ALT_QSPI_IRQSTAT_PROTWRATTEMPT_GET(value) (((value) & 0x00000010) >> 4)
+/* Produces a ALT_QSPI_IRQSTAT_PROTWRATTEMPT register field value suitable for setting the register. */
+#define ALT_QSPI_IRQSTAT_PROTWRATTEMPT_SET(value) (((value) << 4) & 0x00000010)
+
+/*
+ * Field : Illegal AHB Access Detected - illegalacc
+ * 
+ * Illegal AHB access has been detected. AHB wrapping bursts and the use of
+ * SPLIT/RETRY accesses will cause this error interrupt to trigger.
+ * 
+ * Field Enumeration Values:
+ * 
+ *  Enum                                       | Value | Description           
+ * :-------------------------------------------|:------|:-----------------------
+ *  ALT_QSPI_IRQSTAT_ILLEGALACC_E_ILLEGALAHB   | 0x1   | Illegal AHB attempt   
+ *  ALT_QSPI_IRQSTAT_ILLEGALACC_E_NOILLEGALAHB | 0x0   | No Illegal AHB attempt
+ * 
+ * Field Access Macros:
+ * 
+ */
+/*
+ * Enumerated value for register field ALT_QSPI_IRQSTAT_ILLEGALACC
+ * 
+ * Illegal AHB attempt
+ */
+#define ALT_QSPI_IRQSTAT_ILLEGALACC_E_ILLEGALAHB    0x1
+/*
+ * Enumerated value for register field ALT_QSPI_IRQSTAT_ILLEGALACC
+ * 
+ * No Illegal AHB attempt
+ */
+#define ALT_QSPI_IRQSTAT_ILLEGALACC_E_NOILLEGALAHB  0x0
+
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_IRQSTAT_ILLEGALACC register field. */
+#define ALT_QSPI_IRQSTAT_ILLEGALACC_LSB        5
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_IRQSTAT_ILLEGALACC register field. */
+#define ALT_QSPI_IRQSTAT_ILLEGALACC_MSB        5
+/* The width in bits of the ALT_QSPI_IRQSTAT_ILLEGALACC register field. */
+#define ALT_QSPI_IRQSTAT_ILLEGALACC_WIDTH      1
+/* The mask used to set the ALT_QSPI_IRQSTAT_ILLEGALACC register field value. */
+#define ALT_QSPI_IRQSTAT_ILLEGALACC_SET_MSK    0x00000020
+/* The mask used to clear the ALT_QSPI_IRQSTAT_ILLEGALACC register field value. */
+#define ALT_QSPI_IRQSTAT_ILLEGALACC_CLR_MSK    0xffffffdf
+/* The reset value of the ALT_QSPI_IRQSTAT_ILLEGALACC register field. */
+#define ALT_QSPI_IRQSTAT_ILLEGALACC_RESET      0x0
+/* Extracts the ALT_QSPI_IRQSTAT_ILLEGALACC field value from a register. */
+#define ALT_QSPI_IRQSTAT_ILLEGALACC_GET(value) (((value) & 0x00000020) >> 5)
+/* Produces a ALT_QSPI_IRQSTAT_ILLEGALACC register field value suitable for setting the register. */
+#define ALT_QSPI_IRQSTAT_ILLEGALACC_SET(value) (((value) << 5) & 0x00000020)
+
+/*
+ * Field : Transfer Watermark Reached - indxfrlvl
+ * 
+ * Indirect Transfer Watermark Level Reached
+ * 
+ * Field Enumeration Values:
+ * 
+ *  Enum                                    | Value | Description           
+ * :----------------------------------------|:------|:-----------------------
+ *  ALT_QSPI_IRQSTAT_INDXFRLVL_E_WATERLEVL  | 0x1   | Water level reached   
+ *  ALT_QSPI_IRQSTAT_INDXFRLVL_E_NOWATERLVL | 0x0   | No water level reached
+ * 
+ * Field Access Macros:
+ * 
+ */
+/*
+ * Enumerated value for register field ALT_QSPI_IRQSTAT_INDXFRLVL
+ * 
+ * Water level reached
+ */
+#define ALT_QSPI_IRQSTAT_INDXFRLVL_E_WATERLEVL  0x1
+/*
+ * Enumerated value for register field ALT_QSPI_IRQSTAT_INDXFRLVL
+ * 
+ * No water level reached
+ */
+#define ALT_QSPI_IRQSTAT_INDXFRLVL_E_NOWATERLVL 0x0
+
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_IRQSTAT_INDXFRLVL register field. */
+#define ALT_QSPI_IRQSTAT_INDXFRLVL_LSB        6
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_IRQSTAT_INDXFRLVL register field. */
+#define ALT_QSPI_IRQSTAT_INDXFRLVL_MSB        6
+/* The width in bits of the ALT_QSPI_IRQSTAT_INDXFRLVL register field. */
+#define ALT_QSPI_IRQSTAT_INDXFRLVL_WIDTH      1
+/* The mask used to set the ALT_QSPI_IRQSTAT_INDXFRLVL register field value. */
+#define ALT_QSPI_IRQSTAT_INDXFRLVL_SET_MSK    0x00000040
+/* The mask used to clear the ALT_QSPI_IRQSTAT_INDXFRLVL register field value. */
+#define ALT_QSPI_IRQSTAT_INDXFRLVL_CLR_MSK    0xffffffbf
+/* The reset value of the ALT_QSPI_IRQSTAT_INDXFRLVL register field. */
+#define ALT_QSPI_IRQSTAT_INDXFRLVL_RESET      0x0
+/* Extracts the ALT_QSPI_IRQSTAT_INDXFRLVL field value from a register. */
+#define ALT_QSPI_IRQSTAT_INDXFRLVL_GET(value) (((value) & 0x00000040) >> 6)
+/* Produces a ALT_QSPI_IRQSTAT_INDXFRLVL register field value suitable for setting the register. */
+#define ALT_QSPI_IRQSTAT_INDXFRLVL_SET(value) (((value) << 6) & 0x00000040)
+
+/*
+ * Field : Receive Overflow - rxover
+ * 
+ * This should only occur in Legacy SPI mode. Set if an attempt is made to push the
+ * RX FIFO when it is full. This bit is reset only by a system reset and cleared
+ * only when this register is read. If a new push to the RX FIFO occurs coincident
+ * with a register read this flag will remain set. 0 : no overflow has been
+ * detected. 1 : an overflow has occurred.
+ * 
+ * Field Enumeration Values:
+ * 
+ *  Enum                                | Value | Description        
+ * :------------------------------------|:------|:--------------------
+ *  ALT_QSPI_IRQSTAT_RXOVER_E_RCVOVER   | 0x1   | Receive Overflow   
+ *  ALT_QSPI_IRQSTAT_RXOVER_E_NORCVOVER | 0x0   | No Receive Overflow
+ * 
+ * Field Access Macros:
+ * 
+ */
+/*
+ * Enumerated value for register field ALT_QSPI_IRQSTAT_RXOVER
+ * 
+ * Receive Overflow
+ */
+#define ALT_QSPI_IRQSTAT_RXOVER_E_RCVOVER   0x1
+/*
+ * Enumerated value for register field ALT_QSPI_IRQSTAT_RXOVER
+ * 
+ * No Receive Overflow
+ */
+#define ALT_QSPI_IRQSTAT_RXOVER_E_NORCVOVER 0x0
+
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_IRQSTAT_RXOVER register field. */
+#define ALT_QSPI_IRQSTAT_RXOVER_LSB        7
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_IRQSTAT_RXOVER register field. */
+#define ALT_QSPI_IRQSTAT_RXOVER_MSB        7
+/* The width in bits of the ALT_QSPI_IRQSTAT_RXOVER register field. */
+#define ALT_QSPI_IRQSTAT_RXOVER_WIDTH      1
+/* The mask used to set the ALT_QSPI_IRQSTAT_RXOVER register field value. */
+#define ALT_QSPI_IRQSTAT_RXOVER_SET_MSK    0x00000080
+/* The mask used to clear the ALT_QSPI_IRQSTAT_RXOVER register field value. */
+#define ALT_QSPI_IRQSTAT_RXOVER_CLR_MSK    0xffffff7f
+/* The reset value of the ALT_QSPI_IRQSTAT_RXOVER register field. */
+#define ALT_QSPI_IRQSTAT_RXOVER_RESET      0x0
+/* Extracts the ALT_QSPI_IRQSTAT_RXOVER field value from a register. */
+#define ALT_QSPI_IRQSTAT_RXOVER_GET(value) (((value) & 0x00000080) >> 7)
+/* Produces a ALT_QSPI_IRQSTAT_RXOVER register field value suitable for setting the register. */
+#define ALT_QSPI_IRQSTAT_RXOVER_SET(value) (((value) << 7) & 0x00000080)
+
+/*
+ * Field : Transmit FIFO Compared to Threshold - txthreshcmp
+ * 
+ * Indicates the number of entries in the transmit FIFO with respect to the
+ * threshold specified in the TXTHRESH register. Only relevant in SPI legacy mode.
+ * 
+ * Field Enumeration Values:
+ * 
+ *  Enum                              | Value | Description                 
+ * :----------------------------------|:------|:-----------------------------
+ *  ALT_QSPI_IRQSTAT_TXTHRESHCMP_E_GT | 0x0   | FIFO has > TXTHRESH entries 
+ *  ALT_QSPI_IRQSTAT_TXTHRESHCMP_E_LE | 0x1   | FIFO has <= TXTHRESH entries
+ * 
+ * Field Access Macros:
+ * 
+ */
+/*
+ * Enumerated value for register field ALT_QSPI_IRQSTAT_TXTHRESHCMP
+ * 
+ * FIFO has > TXTHRESH entries
+ */
+#define ALT_QSPI_IRQSTAT_TXTHRESHCMP_E_GT   0x0
+/*
+ * Enumerated value for register field ALT_QSPI_IRQSTAT_TXTHRESHCMP
+ * 
+ * FIFO has <= TXTHRESH entries
+ */
+#define ALT_QSPI_IRQSTAT_TXTHRESHCMP_E_LE   0x1
+
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_IRQSTAT_TXTHRESHCMP register field. */
+#define ALT_QSPI_IRQSTAT_TXTHRESHCMP_LSB        8
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_IRQSTAT_TXTHRESHCMP register field. */
+#define ALT_QSPI_IRQSTAT_TXTHRESHCMP_MSB        8
+/* The width in bits of the ALT_QSPI_IRQSTAT_TXTHRESHCMP register field. */
+#define ALT_QSPI_IRQSTAT_TXTHRESHCMP_WIDTH      1
+/* The mask used to set the ALT_QSPI_IRQSTAT_TXTHRESHCMP register field value. */
+#define ALT_QSPI_IRQSTAT_TXTHRESHCMP_SET_MSK    0x00000100
+/* The mask used to clear the ALT_QSPI_IRQSTAT_TXTHRESHCMP register field value. */
+#define ALT_QSPI_IRQSTAT_TXTHRESHCMP_CLR_MSK    0xfffffeff
+/* The reset value of the ALT_QSPI_IRQSTAT_TXTHRESHCMP register field. */
+#define ALT_QSPI_IRQSTAT_TXTHRESHCMP_RESET      0x1
+/* Extracts the ALT_QSPI_IRQSTAT_TXTHRESHCMP field value from a register. */
+#define ALT_QSPI_IRQSTAT_TXTHRESHCMP_GET(value) (((value) & 0x00000100) >> 8)
+/* Produces a ALT_QSPI_IRQSTAT_TXTHRESHCMP register field value suitable for setting the register. */
+#define ALT_QSPI_IRQSTAT_TXTHRESHCMP_SET(value) (((value) << 8) & 0x00000100)
+
+/*
+ * Field : Transmit FIFO Full - txfull
+ * 
+ * Indicates that the transmit FIFO is full or not. Only relevant in SPI legacy
+ * mode.
+ * 
+ * Field Enumeration Values:
+ * 
+ *  Enum                              | Value | Description           
+ * :----------------------------------|:------|:-----------------------
+ *  ALT_QSPI_IRQSTAT_TXFULL_E_NOTFULL | 0x0   | Transmit FIFO Not Full
+ *  ALT_QSPI_IRQSTAT_TXFULL_E_FULL    | 0x1   | Transmit FIFO Full    
+ * 
+ * Field Access Macros:
+ * 
+ */
+/*
+ * Enumerated value for register field ALT_QSPI_IRQSTAT_TXFULL
+ * 
+ * Transmit FIFO Not Full
+ */
+#define ALT_QSPI_IRQSTAT_TXFULL_E_NOTFULL   0x0
+/*
+ * Enumerated value for register field ALT_QSPI_IRQSTAT_TXFULL
+ * 
+ * Transmit FIFO Full
+ */
+#define ALT_QSPI_IRQSTAT_TXFULL_E_FULL      0x1
+
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_IRQSTAT_TXFULL register field. */
+#define ALT_QSPI_IRQSTAT_TXFULL_LSB        9
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_IRQSTAT_TXFULL register field. */
+#define ALT_QSPI_IRQSTAT_TXFULL_MSB        9
+/* The width in bits of the ALT_QSPI_IRQSTAT_TXFULL register field. */
+#define ALT_QSPI_IRQSTAT_TXFULL_WIDTH      1
+/* The mask used to set the ALT_QSPI_IRQSTAT_TXFULL register field value. */
+#define ALT_QSPI_IRQSTAT_TXFULL_SET_MSK    0x00000200
+/* The mask used to clear the ALT_QSPI_IRQSTAT_TXFULL register field value. */
+#define ALT_QSPI_IRQSTAT_TXFULL_CLR_MSK    0xfffffdff
+/* The reset value of the ALT_QSPI_IRQSTAT_TXFULL register field. */
+#define ALT_QSPI_IRQSTAT_TXFULL_RESET      0x0
+/* Extracts the ALT_QSPI_IRQSTAT_TXFULL field value from a register. */
+#define ALT_QSPI_IRQSTAT_TXFULL_GET(value) (((value) & 0x00000200) >> 9)
+/* Produces a ALT_QSPI_IRQSTAT_TXFULL register field value suitable for setting the register. */
+#define ALT_QSPI_IRQSTAT_TXFULL_SET(value) (((value) << 9) & 0x00000200)
+
+/*
+ * Field : Receive FIFO Compared to Threshold - rxthreshcmp
+ * 
+ * Indicates the number of entries in the receive FIFO with respect to the
+ * threshold specified in the RXTHRESH register. Only relevant in SPI legacy mode.
+ * 
+ * Field Enumeration Values:
+ * 
+ *  Enum                              | Value | Description                 
+ * :----------------------------------|:------|:-----------------------------
+ *  ALT_QSPI_IRQSTAT_RXTHRESHCMP_E_LE | 0x0   | FIFO has <= RXTHRESH entries
+ *  ALT_QSPI_IRQSTAT_RXTHRESHCMP_E_GT | 0x1   | FIFO has > RXTHRESH entries 
+ * 
+ * Field Access Macros:
+ * 
+ */
+/*
+ * Enumerated value for register field ALT_QSPI_IRQSTAT_RXTHRESHCMP
+ * 
+ * FIFO has <= RXTHRESH entries
+ */
+#define ALT_QSPI_IRQSTAT_RXTHRESHCMP_E_LE   0x0
+/*
+ * Enumerated value for register field ALT_QSPI_IRQSTAT_RXTHRESHCMP
+ * 
+ * FIFO has > RXTHRESH entries
+ */
+#define ALT_QSPI_IRQSTAT_RXTHRESHCMP_E_GT   0x1
+
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_IRQSTAT_RXTHRESHCMP register field. */
+#define ALT_QSPI_IRQSTAT_RXTHRESHCMP_LSB        10
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_IRQSTAT_RXTHRESHCMP register field. */
+#define ALT_QSPI_IRQSTAT_RXTHRESHCMP_MSB        10
+/* The width in bits of the ALT_QSPI_IRQSTAT_RXTHRESHCMP register field. */
+#define ALT_QSPI_IRQSTAT_RXTHRESHCMP_WIDTH      1
+/* The mask used to set the ALT_QSPI_IRQSTAT_RXTHRESHCMP register field value. */
+#define ALT_QSPI_IRQSTAT_RXTHRESHCMP_SET_MSK    0x00000400
+/* The mask used to clear the ALT_QSPI_IRQSTAT_RXTHRESHCMP register field value. */
+#define ALT_QSPI_IRQSTAT_RXTHRESHCMP_CLR_MSK    0xfffffbff
+/* The reset value of the ALT_QSPI_IRQSTAT_RXTHRESHCMP register field. */
+#define ALT_QSPI_IRQSTAT_RXTHRESHCMP_RESET      0x0
+/* Extracts the ALT_QSPI_IRQSTAT_RXTHRESHCMP field value from a register. */
+#define ALT_QSPI_IRQSTAT_RXTHRESHCMP_GET(value) (((value) & 0x00000400) >> 10)
+/* Produces a ALT_QSPI_IRQSTAT_RXTHRESHCMP register field value suitable for setting the register. */
+#define ALT_QSPI_IRQSTAT_RXTHRESHCMP_SET(value) (((value) << 10) & 0x00000400)
+
+/*
+ * Field : Receive FIFO Full - rxfull
+ * 
+ * Indicates that the receive FIFO is full or not. Only relevant in SPI legacy
+ * mode.
+ * 
+ * Field Enumeration Values:
+ * 
+ *  Enum                              | Value | Description          
+ * :----------------------------------|:------|:----------------------
+ *  ALT_QSPI_IRQSTAT_RXFULL_E_NOTFULL | 0x0   | Receive FIFO Not Full
+ *  ALT_QSPI_IRQSTAT_RXFULL_E_FULL    | 0x1   | Receive FIFO Full    
+ * 
+ * Field Access Macros:
+ * 
+ */
+/*
+ * Enumerated value for register field ALT_QSPI_IRQSTAT_RXFULL
+ * 
+ * Receive FIFO Not Full
+ */
+#define ALT_QSPI_IRQSTAT_RXFULL_E_NOTFULL   0x0
+/*
+ * Enumerated value for register field ALT_QSPI_IRQSTAT_RXFULL
+ * 
+ * Receive FIFO Full
+ */
+#define ALT_QSPI_IRQSTAT_RXFULL_E_FULL      0x1
+
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_IRQSTAT_RXFULL register field. */
+#define ALT_QSPI_IRQSTAT_RXFULL_LSB        11
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_IRQSTAT_RXFULL register field. */
+#define ALT_QSPI_IRQSTAT_RXFULL_MSB        11
+/* The width in bits of the ALT_QSPI_IRQSTAT_RXFULL register field. */
+#define ALT_QSPI_IRQSTAT_RXFULL_WIDTH      1
+/* The mask used to set the ALT_QSPI_IRQSTAT_RXFULL register field value. */
+#define ALT_QSPI_IRQSTAT_RXFULL_SET_MSK    0x00000800
+/* The mask used to clear the ALT_QSPI_IRQSTAT_RXFULL register field value. */
+#define ALT_QSPI_IRQSTAT_RXFULL_CLR_MSK    0xfffff7ff
+/* The reset value of the ALT_QSPI_IRQSTAT_RXFULL register field. */
+#define ALT_QSPI_IRQSTAT_RXFULL_RESET      0x0
+/* Extracts the ALT_QSPI_IRQSTAT_RXFULL field value from a register. */
+#define ALT_QSPI_IRQSTAT_RXFULL_GET(value) (((value) & 0x00000800) >> 11)
+/* Produces a ALT_QSPI_IRQSTAT_RXFULL register field value suitable for setting the register. */
+#define ALT_QSPI_IRQSTAT_RXFULL_SET(value) (((value) << 11) & 0x00000800)
+
+/*
+ * Field : Indirect Read Partition overflow - indsramfull
+ * 
+ * Indirect Read Partition of SRAM is full and unable to immediately complete
+ * indirect operation
+ * 
+ * Field Enumeration Values:
+ * 
+ *  Enum                                         | Value | Description     
+ * :---------------------------------------------|:------|:-----------------
+ *  ALT_QSPI_IRQSTAT_INDSRAMFULL_E_RDPARTFULL    | 0x1   | SRAM is full    
+ *  ALT_QSPI_IRQSTAT_INDSRAMFULL_E_RDPARTNOTFULL | 0x0   | SRAM is not full
+ * 
+ * Field Access Macros:
+ * 
+ */
+/*
+ * Enumerated value for register field ALT_QSPI_IRQSTAT_INDSRAMFULL
+ * 
+ * SRAM is full
+ */
+#define ALT_QSPI_IRQSTAT_INDSRAMFULL_E_RDPARTFULL       0x1
+/*
+ * Enumerated value for register field ALT_QSPI_IRQSTAT_INDSRAMFULL
+ * 
+ * SRAM is not full
+ */
+#define ALT_QSPI_IRQSTAT_INDSRAMFULL_E_RDPARTNOTFULL    0x0
+
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_IRQSTAT_INDSRAMFULL register field. */
+#define ALT_QSPI_IRQSTAT_INDSRAMFULL_LSB        12
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_IRQSTAT_INDSRAMFULL register field. */
+#define ALT_QSPI_IRQSTAT_INDSRAMFULL_MSB        12
+/* The width in bits of the ALT_QSPI_IRQSTAT_INDSRAMFULL register field. */
+#define ALT_QSPI_IRQSTAT_INDSRAMFULL_WIDTH      1
+/* The mask used to set the ALT_QSPI_IRQSTAT_INDSRAMFULL register field value. */
+#define ALT_QSPI_IRQSTAT_INDSRAMFULL_SET_MSK    0x00001000
+/* The mask used to clear the ALT_QSPI_IRQSTAT_INDSRAMFULL register field value. */
+#define ALT_QSPI_IRQSTAT_INDSRAMFULL_CLR_MSK    0xffffefff
+/* The reset value of the ALT_QSPI_IRQSTAT_INDSRAMFULL register field. */
+#define ALT_QSPI_IRQSTAT_INDSRAMFULL_RESET      0x0
+/* Extracts the ALT_QSPI_IRQSTAT_INDSRAMFULL field value from a register. */
+#define ALT_QSPI_IRQSTAT_INDSRAMFULL_GET(value) (((value) & 0x00001000) >> 12)
+/* Produces a ALT_QSPI_IRQSTAT_INDSRAMFULL register field value suitable for setting the register. */
+#define ALT_QSPI_IRQSTAT_INDSRAMFULL_SET(value) (((value) << 12) & 0x00001000)
+
+#ifndef __ASSEMBLY__
+/*
+ * WARNING: The C register and register group struct declarations are provided for
+ * convenience and illustrative purposes. They should, however, be used with
+ * caution as the C language standard provides no guarantees about the alignment or
+ * atomicity of device memory accesses. The recommended practice for writing
+ * hardware drivers is to use the SoCAL access macros and alt_read_word() and
+ * alt_write_word() functions.
+ * 
+ * The struct declaration for register ALT_QSPI_IRQSTAT.
+ */
+struct ALT_QSPI_IRQSTAT_s
+{
+    uint32_t                :  1;  /* *UNDEFINED* */
+    uint32_t  underflowdet  :  1;  /* Underflow Detected */
+    uint32_t  indopdone     :  1;  /* Indirect Operation Complete */
+    uint32_t  indrdreject   :  1;  /* Indirect Read Reject */
+    uint32_t  protwrattempt :  1;  /* Protected Area Write Attempt */
+    uint32_t  illegalacc    :  1;  /* Illegal AHB Access Detected */
+    uint32_t  indxfrlvl     :  1;  /* Transfer Watermark Reached */
+    uint32_t  rxover        :  1;  /* Receive Overflow */
+    uint32_t  txthreshcmp   :  1;  /* Transmit FIFO Compared to Threshold */
+    uint32_t  txfull        :  1;  /* Transmit FIFO Full */
+    uint32_t  rxthreshcmp   :  1;  /* Receive FIFO Compared to Threshold */
+    uint32_t  rxfull        :  1;  /* Receive FIFO Full */
+    uint32_t  indsramfull   :  1;  /* Indirect Read Partition overflow */
+    uint32_t                : 19;  /* *UNDEFINED* */
+};
+
+/* The typedef declaration for register ALT_QSPI_IRQSTAT. */
+typedef volatile struct ALT_QSPI_IRQSTAT_s  ALT_QSPI_IRQSTAT_t;
+#endif  /* __ASSEMBLY__ */
+
+/* The byte offset of the ALT_QSPI_IRQSTAT register from the beginning of the component. */
+#define ALT_QSPI_IRQSTAT_OFST        0x40
+
+/*
+ * Register : Interrupt Mask - irqmask
+ * 
+ * If disabled, the interrupt for the corresponding interrupt status register bit
+ * is disabled. If enabled, the interrupt for the corresponding interrupt status
+ * register bit is enabled.
+ * 
+ * Register Layout
+ * 
+ *  Bits    | Access | Reset | Description                          
+ * :--------|:-------|:------|:--------------------------------------
+ *  [0]     | ???    | 0x0   | *UNDEFINED*                          
+ *  [1]     | RW     | 0x0   | Underflow Detected Mask              
+ *  [2]     | RW     | 0x0   | Mask                                 
+ *  [3]     | RW     | 0x0   | Indirect Read Reject Mask            
+ *  [4]     | RW     | 0x0   | Protected Area Write Attempt Mask    
+ *  [5]     | RW     | 0x0   | Illegal Access Detected Mask         
+ *  [6]     | RW     | 0x0   | Transfer Watermark Breach Mask       
+ *  [7]     | RW     | 0x0   | Receive Overflow Mask                
+ *  [8]     | RW     | 0x0   | Transmit FIFO Threshold Compare Mask 
+ *  [9]     | RW     | 0x0   | Transmit FIFO Full Mask              
+ *  [10]    | RW     | 0x0   | Receive FIFO Threshold Compare Mask  
+ *  [11]    | RW     | 0x0   | Receive FIFO full Mask               
+ *  [12]    | RW     | 0x0   | Indirect Read Partition overflow mask
+ *  [31:13] | ???    | 0x0   | *UNDEFINED*                          
+ * 
+ */
+/*
+ * Field : Underflow Detected Mask - underflowdet
+ * 
+ * Field Enumeration Values:
+ * 
+ *  Enum                                | Value | Description                 
+ * :------------------------------------|:------|:-----------------------------
+ *  ALT_QSPI_IRQMSK_UNDERFLOWDET_E_DISD | 0x0   | Disable Interrupt by Masking
+ *  ALT_QSPI_IRQMSK_UNDERFLOWDET_E_END  | 0x1   | Enable Interrupt            
+ * 
+ * Field Access Macros:
+ * 
+ */
+/*
+ * Enumerated value for register field ALT_QSPI_IRQMSK_UNDERFLOWDET
+ * 
+ * Disable Interrupt by Masking
+ */
+#define ALT_QSPI_IRQMSK_UNDERFLOWDET_E_DISD 0x0
+/*
+ * Enumerated value for register field ALT_QSPI_IRQMSK_UNDERFLOWDET
+ * 
+ * Enable Interrupt
+ */
+#define ALT_QSPI_IRQMSK_UNDERFLOWDET_E_END  0x1
+
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_IRQMSK_UNDERFLOWDET register field. */
+#define ALT_QSPI_IRQMSK_UNDERFLOWDET_LSB        1
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_IRQMSK_UNDERFLOWDET register field. */
+#define ALT_QSPI_IRQMSK_UNDERFLOWDET_MSB        1
+/* The width in bits of the ALT_QSPI_IRQMSK_UNDERFLOWDET register field. */
+#define ALT_QSPI_IRQMSK_UNDERFLOWDET_WIDTH      1
+/* The mask used to set the ALT_QSPI_IRQMSK_UNDERFLOWDET register field value. */
+#define ALT_QSPI_IRQMSK_UNDERFLOWDET_SET_MSK    0x00000002
+/* The mask used to clear the ALT_QSPI_IRQMSK_UNDERFLOWDET register field value. */
+#define ALT_QSPI_IRQMSK_UNDERFLOWDET_CLR_MSK    0xfffffffd
+/* The reset value of the ALT_QSPI_IRQMSK_UNDERFLOWDET register field. */
+#define ALT_QSPI_IRQMSK_UNDERFLOWDET_RESET      0x0
+/* Extracts the ALT_QSPI_IRQMSK_UNDERFLOWDET field value from a register. */
+#define ALT_QSPI_IRQMSK_UNDERFLOWDET_GET(value) (((value) & 0x00000002) >> 1)
+/* Produces a ALT_QSPI_IRQMSK_UNDERFLOWDET register field value suitable for setting the register. */
+#define ALT_QSPI_IRQMSK_UNDERFLOWDET_SET(value) (((value) << 1) & 0x00000002)
+
+/*
+ * Field : Mask - indopdone
+ * 
+ * Field Enumeration Values:
+ * 
+ *  Enum                             | Value | Description                 
+ * :---------------------------------|:------|:-----------------------------
+ *  ALT_QSPI_IRQMSK_INDOPDONE_E_DISD | 0x0   | Disable Interrupt by Masking
+ *  ALT_QSPI_IRQMSK_INDOPDONE_E_END  | 0x1   | Enable Interrupt            
+ * 
+ * Field Access Macros:
+ * 
+ */
+/*
+ * Enumerated value for register field ALT_QSPI_IRQMSK_INDOPDONE
+ * 
+ * Disable Interrupt by Masking
+ */
+#define ALT_QSPI_IRQMSK_INDOPDONE_E_DISD    0x0
+/*
+ * Enumerated value for register field ALT_QSPI_IRQMSK_INDOPDONE
+ * 
+ * Enable Interrupt
+ */
+#define ALT_QSPI_IRQMSK_INDOPDONE_E_END     0x1
+
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_IRQMSK_INDOPDONE register field. */
+#define ALT_QSPI_IRQMSK_INDOPDONE_LSB        2
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_IRQMSK_INDOPDONE register field. */
+#define ALT_QSPI_IRQMSK_INDOPDONE_MSB        2
+/* The width in bits of the ALT_QSPI_IRQMSK_INDOPDONE register field. */
+#define ALT_QSPI_IRQMSK_INDOPDONE_WIDTH      1
+/* The mask used to set the ALT_QSPI_IRQMSK_INDOPDONE register field value. */
+#define ALT_QSPI_IRQMSK_INDOPDONE_SET_MSK    0x00000004
+/* The mask used to clear the ALT_QSPI_IRQMSK_INDOPDONE register field value. */
+#define ALT_QSPI_IRQMSK_INDOPDONE_CLR_MSK    0xfffffffb
+/* The reset value of the ALT_QSPI_IRQMSK_INDOPDONE register field. */
+#define ALT_QSPI_IRQMSK_INDOPDONE_RESET      0x0
+/* Extracts the ALT_QSPI_IRQMSK_INDOPDONE field value from a register. */
+#define ALT_QSPI_IRQMSK_INDOPDONE_GET(value) (((value) & 0x00000004) >> 2)
+/* Produces a ALT_QSPI_IRQMSK_INDOPDONE register field value suitable for setting the register. */
+#define ALT_QSPI_IRQMSK_INDOPDONE_SET(value) (((value) << 2) & 0x00000004)
+
+/*
+ * Field : Indirect Read Reject Mask - indrdreject
+ * 
+ * Field Enumeration Values:
+ * 
+ *  Enum                               | Value | Description                 
+ * :-----------------------------------|:------|:-----------------------------
+ *  ALT_QSPI_IRQMSK_INDRDREJECT_E_DISD | 0x0   | Disable Interrupt by Masking
+ *  ALT_QSPI_IRQMSK_INDRDREJECT_E_END  | 0x1   | Enable Interrupt            
+ * 
+ * Field Access Macros:
+ * 
+ */
+/*
+ * Enumerated value for register field ALT_QSPI_IRQMSK_INDRDREJECT
+ * 
+ * Disable Interrupt by Masking
+ */
+#define ALT_QSPI_IRQMSK_INDRDREJECT_E_DISD  0x0
+/*
+ * Enumerated value for register field ALT_QSPI_IRQMSK_INDRDREJECT
+ * 
+ * Enable Interrupt
+ */
+#define ALT_QSPI_IRQMSK_INDRDREJECT_E_END   0x1
+
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_IRQMSK_INDRDREJECT register field. */
+#define ALT_QSPI_IRQMSK_INDRDREJECT_LSB        3
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_IRQMSK_INDRDREJECT register field. */
+#define ALT_QSPI_IRQMSK_INDRDREJECT_MSB        3
+/* The width in bits of the ALT_QSPI_IRQMSK_INDRDREJECT register field. */
+#define ALT_QSPI_IRQMSK_INDRDREJECT_WIDTH      1
+/* The mask used to set the ALT_QSPI_IRQMSK_INDRDREJECT register field value. */
+#define ALT_QSPI_IRQMSK_INDRDREJECT_SET_MSK    0x00000008
+/* The mask used to clear the ALT_QSPI_IRQMSK_INDRDREJECT register field value. */
+#define ALT_QSPI_IRQMSK_INDRDREJECT_CLR_MSK    0xfffffff7
+/* The reset value of the ALT_QSPI_IRQMSK_INDRDREJECT register field. */
+#define ALT_QSPI_IRQMSK_INDRDREJECT_RESET      0x0
+/* Extracts the ALT_QSPI_IRQMSK_INDRDREJECT field value from a register. */
+#define ALT_QSPI_IRQMSK_INDRDREJECT_GET(value) (((value) & 0x00000008) >> 3)
+/* Produces a ALT_QSPI_IRQMSK_INDRDREJECT register field value suitable for setting the register. */
+#define ALT_QSPI_IRQMSK_INDRDREJECT_SET(value) (((value) << 3) & 0x00000008)
+
+/*
+ * Field : Protected Area Write Attempt Mask - protwrattempt
+ * 
+ * Field Enumeration Values:
+ * 
+ *  Enum                                 | Value | Description                 
+ * :-------------------------------------|:------|:-----------------------------
+ *  ALT_QSPI_IRQMSK_PROTWRATTEMPT_E_DISD | 0x0   | Disable Interrupt by Masking
+ *  ALT_QSPI_IRQMSK_PROTWRATTEMPT_E_END  | 0x1   | Enable Interrupt            
+ * 
+ * Field Access Macros:
+ * 
+ */
+/*
+ * Enumerated value for register field ALT_QSPI_IRQMSK_PROTWRATTEMPT
+ * 
+ * Disable Interrupt by Masking
+ */
+#define ALT_QSPI_IRQMSK_PROTWRATTEMPT_E_DISD    0x0
+/*
+ * Enumerated value for register field ALT_QSPI_IRQMSK_PROTWRATTEMPT
+ * 
+ * Enable Interrupt
+ */
+#define ALT_QSPI_IRQMSK_PROTWRATTEMPT_E_END     0x1
+
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_IRQMSK_PROTWRATTEMPT register field. */
+#define ALT_QSPI_IRQMSK_PROTWRATTEMPT_LSB        4
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_IRQMSK_PROTWRATTEMPT register field. */
+#define ALT_QSPI_IRQMSK_PROTWRATTEMPT_MSB        4
+/* The width in bits of the ALT_QSPI_IRQMSK_PROTWRATTEMPT register field. */
+#define ALT_QSPI_IRQMSK_PROTWRATTEMPT_WIDTH      1
+/* The mask used to set the ALT_QSPI_IRQMSK_PROTWRATTEMPT register field value. */
+#define ALT_QSPI_IRQMSK_PROTWRATTEMPT_SET_MSK    0x00000010
+/* The mask used to clear the ALT_QSPI_IRQMSK_PROTWRATTEMPT register field value. */
+#define ALT_QSPI_IRQMSK_PROTWRATTEMPT_CLR_MSK    0xffffffef
+/* The reset value of the ALT_QSPI_IRQMSK_PROTWRATTEMPT register field. */
+#define ALT_QSPI_IRQMSK_PROTWRATTEMPT_RESET      0x0
+/* Extracts the ALT_QSPI_IRQMSK_PROTWRATTEMPT field value from a register. */
+#define ALT_QSPI_IRQMSK_PROTWRATTEMPT_GET(value) (((value) & 0x00000010) >> 4)
+/* Produces a ALT_QSPI_IRQMSK_PROTWRATTEMPT register field value suitable for setting the register. */
+#define ALT_QSPI_IRQMSK_PROTWRATTEMPT_SET(value) (((value) << 4) & 0x00000010)
+
+/*
+ * Field : Illegal Access Detected Mask - illegalacc
+ * 
+ * Field Enumeration Values:
+ * 
+ *  Enum                              | Value | Description                 
+ * :----------------------------------|:------|:-----------------------------
+ *  ALT_QSPI_IRQMSK_ILLEGALACC_E_DISD | 0x0   | Disable Interrupt by Masking
+ *  ALT_QSPI_IRQMSK_ILLEGALACC_E_END  | 0x1   | Enable Interrupt            
+ * 
+ * Field Access Macros:
+ * 
+ */
+/*
+ * Enumerated value for register field ALT_QSPI_IRQMSK_ILLEGALACC
+ * 
+ * Disable Interrupt by Masking
+ */
+#define ALT_QSPI_IRQMSK_ILLEGALACC_E_DISD   0x0
+/*
+ * Enumerated value for register field ALT_QSPI_IRQMSK_ILLEGALACC
+ * 
+ * Enable Interrupt
+ */
+#define ALT_QSPI_IRQMSK_ILLEGALACC_E_END    0x1
+
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_IRQMSK_ILLEGALACC register field. */
+#define ALT_QSPI_IRQMSK_ILLEGALACC_LSB        5
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_IRQMSK_ILLEGALACC register field. */
+#define ALT_QSPI_IRQMSK_ILLEGALACC_MSB        5
+/* The width in bits of the ALT_QSPI_IRQMSK_ILLEGALACC register field. */
+#define ALT_QSPI_IRQMSK_ILLEGALACC_WIDTH      1
+/* The mask used to set the ALT_QSPI_IRQMSK_ILLEGALACC register field value. */
+#define ALT_QSPI_IRQMSK_ILLEGALACC_SET_MSK    0x00000020
+/* The mask used to clear the ALT_QSPI_IRQMSK_ILLEGALACC register field value. */
+#define ALT_QSPI_IRQMSK_ILLEGALACC_CLR_MSK    0xffffffdf
+/* The reset value of the ALT_QSPI_IRQMSK_ILLEGALACC register field. */
+#define ALT_QSPI_IRQMSK_ILLEGALACC_RESET      0x0
+/* Extracts the ALT_QSPI_IRQMSK_ILLEGALACC field value from a register. */
+#define ALT_QSPI_IRQMSK_ILLEGALACC_GET(value) (((value) & 0x00000020) >> 5)
+/* Produces a ALT_QSPI_IRQMSK_ILLEGALACC register field value suitable for setting the register. */
+#define ALT_QSPI_IRQMSK_ILLEGALACC_SET(value) (((value) << 5) & 0x00000020)
+
+/*
+ * Field : Transfer Watermark Breach Mask - indxfrlvl
+ * 
+ * Field Enumeration Values:
+ * 
+ *  Enum                             | Value | Description                 
+ * :---------------------------------|:------|:-----------------------------
+ *  ALT_QSPI_IRQMSK_INDXFRLVL_E_DISD | 0x0   | Disable Interrupt by Masking
+ *  ALT_QSPI_IRQMSK_INDXFRLVL_E_END  | 0x1   | Enable Interrupt            
+ * 
+ * Field Access Macros:
+ * 
+ */
+/*
+ * Enumerated value for register field ALT_QSPI_IRQMSK_INDXFRLVL
+ * 
+ * Disable Interrupt by Masking
+ */
+#define ALT_QSPI_IRQMSK_INDXFRLVL_E_DISD    0x0
+/*
+ * Enumerated value for register field ALT_QSPI_IRQMSK_INDXFRLVL
+ * 
+ * Enable Interrupt
+ */
+#define ALT_QSPI_IRQMSK_INDXFRLVL_E_END     0x1
+
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_IRQMSK_INDXFRLVL register field. */
+#define ALT_QSPI_IRQMSK_INDXFRLVL_LSB        6
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_IRQMSK_INDXFRLVL register field. */
+#define ALT_QSPI_IRQMSK_INDXFRLVL_MSB        6
+/* The width in bits of the ALT_QSPI_IRQMSK_INDXFRLVL register field. */
+#define ALT_QSPI_IRQMSK_INDXFRLVL_WIDTH      1
+/* The mask used to set the ALT_QSPI_IRQMSK_INDXFRLVL register field value. */
+#define ALT_QSPI_IRQMSK_INDXFRLVL_SET_MSK    0x00000040
+/* The mask used to clear the ALT_QSPI_IRQMSK_INDXFRLVL register field value. */
+#define ALT_QSPI_IRQMSK_INDXFRLVL_CLR_MSK    0xffffffbf
+/* The reset value of the ALT_QSPI_IRQMSK_INDXFRLVL register field. */
+#define ALT_QSPI_IRQMSK_INDXFRLVL_RESET      0x0
+/* Extracts the ALT_QSPI_IRQMSK_INDXFRLVL field value from a register. */
+#define ALT_QSPI_IRQMSK_INDXFRLVL_GET(value) (((value) & 0x00000040) >> 6)
+/* Produces a ALT_QSPI_IRQMSK_INDXFRLVL register field value suitable for setting the register. */
+#define ALT_QSPI_IRQMSK_INDXFRLVL_SET(value) (((value) << 6) & 0x00000040)
+
+/*
+ * Field : Receive Overflow Mask - rxover
+ * 
+ * Field Enumeration Values:
+ * 
+ *  Enum                          | Value | Description                 
+ * :------------------------------|:------|:-----------------------------
+ *  ALT_QSPI_IRQMSK_RXOVER_E_DISD | 0x0   | Disable Interrupt by Masking
+ *  ALT_QSPI_IRQMSK_RXOVER_E_END  | 0x1   | Enable Interrupt            
+ * 
+ * Field Access Macros:
+ * 
+ */
+/*
+ * Enumerated value for register field ALT_QSPI_IRQMSK_RXOVER
+ * 
+ * Disable Interrupt by Masking
+ */
+#define ALT_QSPI_IRQMSK_RXOVER_E_DISD   0x0
+/*
+ * Enumerated value for register field ALT_QSPI_IRQMSK_RXOVER
+ * 
+ * Enable Interrupt
+ */
+#define ALT_QSPI_IRQMSK_RXOVER_E_END    0x1
+
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_IRQMSK_RXOVER register field. */
+#define ALT_QSPI_IRQMSK_RXOVER_LSB        7
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_IRQMSK_RXOVER register field. */
+#define ALT_QSPI_IRQMSK_RXOVER_MSB        7
+/* The width in bits of the ALT_QSPI_IRQMSK_RXOVER register field. */
+#define ALT_QSPI_IRQMSK_RXOVER_WIDTH      1
+/* The mask used to set the ALT_QSPI_IRQMSK_RXOVER register field value. */
+#define ALT_QSPI_IRQMSK_RXOVER_SET_MSK    0x00000080
+/* The mask used to clear the ALT_QSPI_IRQMSK_RXOVER register field value. */
+#define ALT_QSPI_IRQMSK_RXOVER_CLR_MSK    0xffffff7f
+/* The reset value of the ALT_QSPI_IRQMSK_RXOVER register field. */
+#define ALT_QSPI_IRQMSK_RXOVER_RESET      0x0
+/* Extracts the ALT_QSPI_IRQMSK_RXOVER field value from a register. */
+#define ALT_QSPI_IRQMSK_RXOVER_GET(value) (((value) & 0x00000080) >> 7)
+/* Produces a ALT_QSPI_IRQMSK_RXOVER register field value suitable for setting the register. */
+#define ALT_QSPI_IRQMSK_RXOVER_SET(value) (((value) << 7) & 0x00000080)
+
+/*
+ * Field : Transmit FIFO Threshold Compare Mask - txthreshcmp
+ * 
+ * Field Enumeration Values:
+ * 
+ *  Enum                               | Value | Description                 
+ * :-----------------------------------|:------|:-----------------------------
+ *  ALT_QSPI_IRQMSK_TXTHRESHCMP_E_DISD | 0x0   | Disable Interrupt by Masking
+ *  ALT_QSPI_IRQMSK_TXTHRESHCMP_E_END  | 0x1   | Enable Interrupt            
+ * 
+ * Field Access Macros:
+ * 
+ */
+/*
+ * Enumerated value for register field ALT_QSPI_IRQMSK_TXTHRESHCMP
+ * 
+ * Disable Interrupt by Masking
+ */
+#define ALT_QSPI_IRQMSK_TXTHRESHCMP_E_DISD  0x0
+/*
+ * Enumerated value for register field ALT_QSPI_IRQMSK_TXTHRESHCMP
+ * 
+ * Enable Interrupt
+ */
+#define ALT_QSPI_IRQMSK_TXTHRESHCMP_E_END   0x1
+
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_IRQMSK_TXTHRESHCMP register field. */
+#define ALT_QSPI_IRQMSK_TXTHRESHCMP_LSB        8
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_IRQMSK_TXTHRESHCMP register field. */
+#define ALT_QSPI_IRQMSK_TXTHRESHCMP_MSB        8
+/* The width in bits of the ALT_QSPI_IRQMSK_TXTHRESHCMP register field. */
+#define ALT_QSPI_IRQMSK_TXTHRESHCMP_WIDTH      1
+/* The mask used to set the ALT_QSPI_IRQMSK_TXTHRESHCMP register field value. */
+#define ALT_QSPI_IRQMSK_TXTHRESHCMP_SET_MSK    0x00000100
+/* The mask used to clear the ALT_QSPI_IRQMSK_TXTHRESHCMP register field value. */
+#define ALT_QSPI_IRQMSK_TXTHRESHCMP_CLR_MSK    0xfffffeff
+/* The reset value of the ALT_QSPI_IRQMSK_TXTHRESHCMP register field. */
+#define ALT_QSPI_IRQMSK_TXTHRESHCMP_RESET      0x0
+/* Extracts the ALT_QSPI_IRQMSK_TXTHRESHCMP field value from a register. */
+#define ALT_QSPI_IRQMSK_TXTHRESHCMP_GET(value) (((value) & 0x00000100) >> 8)
+/* Produces a ALT_QSPI_IRQMSK_TXTHRESHCMP register field value suitable for setting the register. */
+#define ALT_QSPI_IRQMSK_TXTHRESHCMP_SET(value) (((value) << 8) & 0x00000100)
+
+/*
+ * Field : Transmit FIFO Full Mask - txfull
+ * 
+ * Field Enumeration Values:
+ * 
+ *  Enum                          | Value | Description                 
+ * :------------------------------|:------|:-----------------------------
+ *  ALT_QSPI_IRQMSK_TXFULL_E_DISD | 0x0   | Disable Interrupt by Masking
+ *  ALT_QSPI_IRQMSK_TXFULL_E_END  | 0x1   | Enable Interrupt            
+ * 
+ * Field Access Macros:
+ * 
+ */
+/*
+ * Enumerated value for register field ALT_QSPI_IRQMSK_TXFULL
+ * 
+ * Disable Interrupt by Masking
+ */
+#define ALT_QSPI_IRQMSK_TXFULL_E_DISD   0x0
+/*
+ * Enumerated value for register field ALT_QSPI_IRQMSK_TXFULL
+ * 
+ * Enable Interrupt
+ */
+#define ALT_QSPI_IRQMSK_TXFULL_E_END    0x1
+
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_IRQMSK_TXFULL register field. */
+#define ALT_QSPI_IRQMSK_TXFULL_LSB        9
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_IRQMSK_TXFULL register field. */
+#define ALT_QSPI_IRQMSK_TXFULL_MSB        9
+/* The width in bits of the ALT_QSPI_IRQMSK_TXFULL register field. */
+#define ALT_QSPI_IRQMSK_TXFULL_WIDTH      1
+/* The mask used to set the ALT_QSPI_IRQMSK_TXFULL register field value. */
+#define ALT_QSPI_IRQMSK_TXFULL_SET_MSK    0x00000200
+/* The mask used to clear the ALT_QSPI_IRQMSK_TXFULL register field value. */
+#define ALT_QSPI_IRQMSK_TXFULL_CLR_MSK    0xfffffdff
+/* The reset value of the ALT_QSPI_IRQMSK_TXFULL register field. */
+#define ALT_QSPI_IRQMSK_TXFULL_RESET      0x0
+/* Extracts the ALT_QSPI_IRQMSK_TXFULL field value from a register. */
+#define ALT_QSPI_IRQMSK_TXFULL_GET(value) (((value) & 0x00000200) >> 9)
+/* Produces a ALT_QSPI_IRQMSK_TXFULL register field value suitable for setting the register. */
+#define ALT_QSPI_IRQMSK_TXFULL_SET(value) (((value) << 9) & 0x00000200)
+
+/*
+ * Field : Receive FIFO Threshold Compare Mask - rxthreshcmp
+ * 
+ * Field Enumeration Values:
+ * 
+ *  Enum                               | Value | Description                 
+ * :-----------------------------------|:------|:-----------------------------
+ *  ALT_QSPI_IRQMSK_RXTHRESHCMP_E_DISD | 0x0   | Disable Interrupt by Masking
+ *  ALT_QSPI_IRQMSK_RXTHRESHCMP_E_END  | 0x1   | Enable Interrupt            
+ * 
+ * Field Access Macros:
+ * 
+ */
+/*
+ * Enumerated value for register field ALT_QSPI_IRQMSK_RXTHRESHCMP
+ * 
+ * Disable Interrupt by Masking
+ */
+#define ALT_QSPI_IRQMSK_RXTHRESHCMP_E_DISD  0x0
+/*
+ * Enumerated value for register field ALT_QSPI_IRQMSK_RXTHRESHCMP
+ * 
+ * Enable Interrupt
+ */
+#define ALT_QSPI_IRQMSK_RXTHRESHCMP_E_END   0x1
+
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_IRQMSK_RXTHRESHCMP register field. */
+#define ALT_QSPI_IRQMSK_RXTHRESHCMP_LSB        10
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_IRQMSK_RXTHRESHCMP register field. */
+#define ALT_QSPI_IRQMSK_RXTHRESHCMP_MSB        10
+/* The width in bits of the ALT_QSPI_IRQMSK_RXTHRESHCMP register field. */
+#define ALT_QSPI_IRQMSK_RXTHRESHCMP_WIDTH      1
+/* The mask used to set the ALT_QSPI_IRQMSK_RXTHRESHCMP register field value. */
+#define ALT_QSPI_IRQMSK_RXTHRESHCMP_SET_MSK    0x00000400
+/* The mask used to clear the ALT_QSPI_IRQMSK_RXTHRESHCMP register field value. */
+#define ALT_QSPI_IRQMSK_RXTHRESHCMP_CLR_MSK    0xfffffbff
+/* The reset value of the ALT_QSPI_IRQMSK_RXTHRESHCMP register field. */
+#define ALT_QSPI_IRQMSK_RXTHRESHCMP_RESET      0x0
+/* Extracts the ALT_QSPI_IRQMSK_RXTHRESHCMP field value from a register. */
+#define ALT_QSPI_IRQMSK_RXTHRESHCMP_GET(value) (((value) & 0x00000400) >> 10)
+/* Produces a ALT_QSPI_IRQMSK_RXTHRESHCMP register field value suitable for setting the register. */
+#define ALT_QSPI_IRQMSK_RXTHRESHCMP_SET(value) (((value) << 10) & 0x00000400)
+
+/*
+ * Field : Receive FIFO full Mask - rxfull
+ * 
+ * Field Enumeration Values:
+ * 
+ *  Enum                          | Value | Description                 
+ * :------------------------------|:------|:-----------------------------
+ *  ALT_QSPI_IRQMSK_RXFULL_E_DISD | 0x0   | Disable Interrupt by Masking
+ *  ALT_QSPI_IRQMSK_RXFULL_E_END  | 0x1   | Enable Interrupt            
+ * 
+ * Field Access Macros:
+ * 
+ */
+/*
+ * Enumerated value for register field ALT_QSPI_IRQMSK_RXFULL
+ * 
+ * Disable Interrupt by Masking
+ */
+#define ALT_QSPI_IRQMSK_RXFULL_E_DISD   0x0
+/*
+ * Enumerated value for register field ALT_QSPI_IRQMSK_RXFULL
+ * 
+ * Enable Interrupt
+ */
+#define ALT_QSPI_IRQMSK_RXFULL_E_END    0x1
+
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_IRQMSK_RXFULL register field. */
+#define ALT_QSPI_IRQMSK_RXFULL_LSB        11
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_IRQMSK_RXFULL register field. */
+#define ALT_QSPI_IRQMSK_RXFULL_MSB        11
+/* The width in bits of the ALT_QSPI_IRQMSK_RXFULL register field. */
+#define ALT_QSPI_IRQMSK_RXFULL_WIDTH      1
+/* The mask used to set the ALT_QSPI_IRQMSK_RXFULL register field value. */
+#define ALT_QSPI_IRQMSK_RXFULL_SET_MSK    0x00000800
+/* The mask used to clear the ALT_QSPI_IRQMSK_RXFULL register field value. */
+#define ALT_QSPI_IRQMSK_RXFULL_CLR_MSK    0xfffff7ff
+/* The reset value of the ALT_QSPI_IRQMSK_RXFULL register field. */
+#define ALT_QSPI_IRQMSK_RXFULL_RESET      0x0
+/* Extracts the ALT_QSPI_IRQMSK_RXFULL field value from a register. */
+#define ALT_QSPI_IRQMSK_RXFULL_GET(value) (((value) & 0x00000800) >> 11)
+/* Produces a ALT_QSPI_IRQMSK_RXFULL register field value suitable for setting the register. */
+#define ALT_QSPI_IRQMSK_RXFULL_SET(value) (((value) << 11) & 0x00000800)
+
+/*
+ * Field : Indirect Read Partition overflow mask - indsramfull
+ * 
+ * Field Enumeration Values:
+ * 
+ *  Enum                               | Value | Description                 
+ * :-----------------------------------|:------|:-----------------------------
+ *  ALT_QSPI_IRQMSK_INDSRAMFULL_E_DISD | 0x0   | Disable Interrupt by Masking
+ *  ALT_QSPI_IRQMSK_INDSRAMFULL_E_END  | 0x1   | Enable Interrupt            
+ * 
+ * Field Access Macros:
+ * 
+ */
+/*
+ * Enumerated value for register field ALT_QSPI_IRQMSK_INDSRAMFULL
+ * 
+ * Disable Interrupt by Masking
+ */
+#define ALT_QSPI_IRQMSK_INDSRAMFULL_E_DISD  0x0
+/*
+ * Enumerated value for register field ALT_QSPI_IRQMSK_INDSRAMFULL
+ * 
+ * Enable Interrupt
+ */
+#define ALT_QSPI_IRQMSK_INDSRAMFULL_E_END   0x1
+
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_IRQMSK_INDSRAMFULL register field. */
+#define ALT_QSPI_IRQMSK_INDSRAMFULL_LSB        12
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_IRQMSK_INDSRAMFULL register field. */
+#define ALT_QSPI_IRQMSK_INDSRAMFULL_MSB        12
+/* The width in bits of the ALT_QSPI_IRQMSK_INDSRAMFULL register field. */
+#define ALT_QSPI_IRQMSK_INDSRAMFULL_WIDTH      1
+/* The mask used to set the ALT_QSPI_IRQMSK_INDSRAMFULL register field value. */
+#define ALT_QSPI_IRQMSK_INDSRAMFULL_SET_MSK    0x00001000
+/* The mask used to clear the ALT_QSPI_IRQMSK_INDSRAMFULL register field value. */
+#define ALT_QSPI_IRQMSK_INDSRAMFULL_CLR_MSK    0xffffefff
+/* The reset value of the ALT_QSPI_IRQMSK_INDSRAMFULL register field. */
+#define ALT_QSPI_IRQMSK_INDSRAMFULL_RESET      0x0
+/* Extracts the ALT_QSPI_IRQMSK_INDSRAMFULL field value from a register. */
+#define ALT_QSPI_IRQMSK_INDSRAMFULL_GET(value) (((value) & 0x00001000) >> 12)
+/* Produces a ALT_QSPI_IRQMSK_INDSRAMFULL register field value suitable for setting the register. */
+#define ALT_QSPI_IRQMSK_INDSRAMFULL_SET(value) (((value) << 12) & 0x00001000)
+
+#ifndef __ASSEMBLY__
+/*
+ * WARNING: The C register and register group struct declarations are provided for
+ * convenience and illustrative purposes. They should, however, be used with
+ * caution as the C language standard provides no guarantees about the alignment or
+ * atomicity of device memory accesses. The recommended practice for writing
+ * hardware drivers is to use the SoCAL access macros and alt_read_word() and
+ * alt_write_word() functions.
+ * 
+ * The struct declaration for register ALT_QSPI_IRQMSK.
+ */
+struct ALT_QSPI_IRQMSK_s
+{
+    uint32_t                :  1;  /* *UNDEFINED* */
+    uint32_t  underflowdet  :  1;  /* Underflow Detected Mask */
+    uint32_t  indopdone     :  1;  /* Mask */
+    uint32_t  indrdreject   :  1;  /* Indirect Read Reject Mask */
+    uint32_t  protwrattempt :  1;  /* Protected Area Write Attempt Mask */
+    uint32_t  illegalacc    :  1;  /* Illegal Access Detected Mask */
+    uint32_t  indxfrlvl     :  1;  /* Transfer Watermark Breach Mask */
+    uint32_t  rxover        :  1;  /* Receive Overflow Mask */
+    uint32_t  txthreshcmp   :  1;  /* Transmit FIFO Threshold Compare Mask */
+    uint32_t  txfull        :  1;  /* Transmit FIFO Full Mask */
+    uint32_t  rxthreshcmp   :  1;  /* Receive FIFO Threshold Compare Mask */
+    uint32_t  rxfull        :  1;  /* Receive FIFO full Mask */
+    uint32_t  indsramfull   :  1;  /* Indirect Read Partition overflow mask */
+    uint32_t                : 19;  /* *UNDEFINED* */
+};
+
+/* The typedef declaration for register ALT_QSPI_IRQMSK. */
+typedef volatile struct ALT_QSPI_IRQMSK_s  ALT_QSPI_IRQMSK_t;
+#endif  /* __ASSEMBLY__ */
+
+/* The byte offset of the ALT_QSPI_IRQMSK register from the beginning of the component. */
+#define ALT_QSPI_IRQMSK_OFST        0x44
+
+/*
+ * Register : Lower Write Protection Register - lowwrprot
+ * 
+ * Register Layout
+ * 
+ *  Bits   | Access | Reset | Description 
+ * :-------|:-------|:------|:-------------
+ *  [31:0] | RW     | 0x0   | Block Number
+ * 
+ */
+/*
+ * Field : Block Number - subsector
+ * 
+ * The block number that defines the lower block in the range of blocks that is to
+ * be locked from writing. The definition of a block in terms of number of bytes is
+ * programmable via the Device Size Configuration register.
+ * 
+ * Field Access Macros:
+ * 
+ */
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_LOWWRPROT_SUBSECTOR register field. */
+#define ALT_QSPI_LOWWRPROT_SUBSECTOR_LSB        0
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_LOWWRPROT_SUBSECTOR register field. */
+#define ALT_QSPI_LOWWRPROT_SUBSECTOR_MSB        31
+/* The width in bits of the ALT_QSPI_LOWWRPROT_SUBSECTOR register field. */
+#define ALT_QSPI_LOWWRPROT_SUBSECTOR_WIDTH      32
+/* The mask used to set the ALT_QSPI_LOWWRPROT_SUBSECTOR register field value. */
+#define ALT_QSPI_LOWWRPROT_SUBSECTOR_SET_MSK    0xffffffff
+/* The mask used to clear the ALT_QSPI_LOWWRPROT_SUBSECTOR register field value. */
+#define ALT_QSPI_LOWWRPROT_SUBSECTOR_CLR_MSK    0x00000000
+/* The reset value of the ALT_QSPI_LOWWRPROT_SUBSECTOR register field. */
+#define ALT_QSPI_LOWWRPROT_SUBSECTOR_RESET      0x0
+/* Extracts the ALT_QSPI_LOWWRPROT_SUBSECTOR field value from a register. */
+#define ALT_QSPI_LOWWRPROT_SUBSECTOR_GET(value) (((value) & 0xffffffff) >> 0)
+/* Produces a ALT_QSPI_LOWWRPROT_SUBSECTOR register field value suitable for setting the register. */
+#define ALT_QSPI_LOWWRPROT_SUBSECTOR_SET(value) (((value) << 0) & 0xffffffff)
+
+#ifndef __ASSEMBLY__
+/*
+ * WARNING: The C register and register group struct declarations are provided for
+ * convenience and illustrative purposes. They should, however, be used with
+ * caution as the C language standard provides no guarantees about the alignment or
+ * atomicity of device memory accesses. The recommended practice for writing
+ * hardware drivers is to use the SoCAL access macros and alt_read_word() and
+ * alt_write_word() functions.
+ * 
+ * The struct declaration for register ALT_QSPI_LOWWRPROT.
+ */
+struct ALT_QSPI_LOWWRPROT_s
+{
+    uint32_t  subsector : 32;  /* Block Number */
+};
+
+/* The typedef declaration for register ALT_QSPI_LOWWRPROT. */
+typedef volatile struct ALT_QSPI_LOWWRPROT_s  ALT_QSPI_LOWWRPROT_t;
+#endif  /* __ASSEMBLY__ */
+
+/* The byte offset of the ALT_QSPI_LOWWRPROT register from the beginning of the component. */
+#define ALT_QSPI_LOWWRPROT_OFST        0x50
+
+/*
+ * Register : Upper Write Protection Register - uppwrprot
+ * 
+ * Register Layout
+ * 
+ *  Bits   | Access | Reset | Description 
+ * :-------|:-------|:------|:-------------
+ *  [31:0] | RW     | 0x0   | Block Number
+ * 
+ */
+/*
+ * Field : Block Number - subsector
+ * 
+ * The block number that defines the upper block in the range of blocks that is to
+ * be locked from writing. The definition of a block in terms of number of bytes is
+ * programmable via the Device Size Configuration register.
+ * 
+ * Field Access Macros:
+ * 
+ */
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_UPPWRPROT_SUBSECTOR register field. */
+#define ALT_QSPI_UPPWRPROT_SUBSECTOR_LSB        0
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_UPPWRPROT_SUBSECTOR register field. */
+#define ALT_QSPI_UPPWRPROT_SUBSECTOR_MSB        31
+/* The width in bits of the ALT_QSPI_UPPWRPROT_SUBSECTOR register field. */
+#define ALT_QSPI_UPPWRPROT_SUBSECTOR_WIDTH      32
+/* The mask used to set the ALT_QSPI_UPPWRPROT_SUBSECTOR register field value. */
+#define ALT_QSPI_UPPWRPROT_SUBSECTOR_SET_MSK    0xffffffff
+/* The mask used to clear the ALT_QSPI_UPPWRPROT_SUBSECTOR register field value. */
+#define ALT_QSPI_UPPWRPROT_SUBSECTOR_CLR_MSK    0x00000000
+/* The reset value of the ALT_QSPI_UPPWRPROT_SUBSECTOR register field. */
+#define ALT_QSPI_UPPWRPROT_SUBSECTOR_RESET      0x0
+/* Extracts the ALT_QSPI_UPPWRPROT_SUBSECTOR field value from a register. */
+#define ALT_QSPI_UPPWRPROT_SUBSECTOR_GET(value) (((value) & 0xffffffff) >> 0)
+/* Produces a ALT_QSPI_UPPWRPROT_SUBSECTOR register field value suitable for setting the register. */
+#define ALT_QSPI_UPPWRPROT_SUBSECTOR_SET(value) (((value) << 0) & 0xffffffff)
+
+#ifndef __ASSEMBLY__
+/*
+ * WARNING: The C register and register group struct declarations are provided for
+ * convenience and illustrative purposes. They should, however, be used with
+ * caution as the C language standard provides no guarantees about the alignment or
+ * atomicity of device memory accesses. The recommended practice for writing
+ * hardware drivers is to use the SoCAL access macros and alt_read_word() and
+ * alt_write_word() functions.
+ * 
+ * The struct declaration for register ALT_QSPI_UPPWRPROT.
+ */
+struct ALT_QSPI_UPPWRPROT_s
+{
+    uint32_t  subsector : 32;  /* Block Number */
+};
+
+/* The typedef declaration for register ALT_QSPI_UPPWRPROT. */
+typedef volatile struct ALT_QSPI_UPPWRPROT_s  ALT_QSPI_UPPWRPROT_t;
+#endif  /* __ASSEMBLY__ */
+
+/* The byte offset of the ALT_QSPI_UPPWRPROT register from the beginning of the component. */
+#define ALT_QSPI_UPPWRPROT_OFST        0x54
+
+/*
+ * Register : Write Protection Register - wrprot
+ * 
+ * Register Layout
+ * 
+ *  Bits   | Access | Reset | Description                   
+ * :-------|:-------|:------|:-------------------------------
+ *  [0]    | RW     | 0x0   | Write Protection Inversion Bit
+ *  [1]    | RW     | 0x0   | Write Protection Enable Bit   
+ *  [31:2] | ???    | 0x0   | *UNDEFINED*                   
+ * 
+ */
+/*
+ * Field : Write Protection Inversion Bit - inv
+ * 
+ * When enabled, the protection region defined in the lower and upper write
+ * protection registers is inverted meaning it is the region that the system is
+ * permitted to write to. When disabled, the protection region defined in the lower
+ * and upper write protection registers is the region that the system is not
+ * permitted to write to.
+ * 
+ * Field Enumeration Values:
+ * 
+ *  Enum                      | Value | Description             
+ * :--------------------------|:------|:-------------------------
+ *  ALT_QSPI_WRPROT_INV_E_EN  | 0x1   | Write Region allowed    
+ *  ALT_QSPI_WRPROT_INV_E_DIS | 0x0   | Write Region not allowed
+ * 
+ * Field Access Macros:
+ * 
+ */
+/*
+ * Enumerated value for register field ALT_QSPI_WRPROT_INV
+ * 
+ * Write Region allowed
+ */
+#define ALT_QSPI_WRPROT_INV_E_EN    0x1
+/*
+ * Enumerated value for register field ALT_QSPI_WRPROT_INV
+ * 
+ * Write Region not allowed
+ */
+#define ALT_QSPI_WRPROT_INV_E_DIS   0x0
+
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_WRPROT_INV register field. */
+#define ALT_QSPI_WRPROT_INV_LSB        0
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_WRPROT_INV register field. */
+#define ALT_QSPI_WRPROT_INV_MSB        0
+/* The width in bits of the ALT_QSPI_WRPROT_INV register field. */
+#define ALT_QSPI_WRPROT_INV_WIDTH      1
+/* The mask used to set the ALT_QSPI_WRPROT_INV register field value. */
+#define ALT_QSPI_WRPROT_INV_SET_MSK    0x00000001
+/* The mask used to clear the ALT_QSPI_WRPROT_INV register field value. */
+#define ALT_QSPI_WRPROT_INV_CLR_MSK    0xfffffffe
+/* The reset value of the ALT_QSPI_WRPROT_INV register field. */
+#define ALT_QSPI_WRPROT_INV_RESET      0x0
+/* Extracts the ALT_QSPI_WRPROT_INV field value from a register. */
+#define ALT_QSPI_WRPROT_INV_GET(value) (((value) & 0x00000001) >> 0)
+/* Produces a ALT_QSPI_WRPROT_INV register field value suitable for setting the register. */
+#define ALT_QSPI_WRPROT_INV_SET(value) (((value) << 0) & 0x00000001)
+
+/*
+ * Field : Write Protection Enable Bit - en
+ * 
+ * When enabled, any AHB write access with an address within the protection region
+ * defined in the lower and upper write protection registers is rejected. An AHB
+ * error response is generated and an interrupt source triggered. When disabled,
+ * the protection region is disabled.
+ * 
+ * Field Enumeration Values:
+ * 
+ *  Enum                     | Value | Description               
+ * :-------------------------|:------|:---------------------------
+ *  ALT_QSPI_WRPROT_EN_E_EN  | 0x1   | AHB Write Access rejected 
+ *  ALT_QSPI_WRPROT_EN_E_DIS | 0x0   | Protection Region Disabled
+ * 
+ * Field Access Macros:
+ * 
+ */
+/*
+ * Enumerated value for register field ALT_QSPI_WRPROT_EN
+ * 
+ * AHB Write Access rejected
+ */
+#define ALT_QSPI_WRPROT_EN_E_EN     0x1
+/*
+ * Enumerated value for register field ALT_QSPI_WRPROT_EN
+ * 
+ * Protection Region Disabled
+ */
+#define ALT_QSPI_WRPROT_EN_E_DIS    0x0
+
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_WRPROT_EN register field. */
+#define ALT_QSPI_WRPROT_EN_LSB        1
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_WRPROT_EN register field. */
+#define ALT_QSPI_WRPROT_EN_MSB        1
+/* The width in bits of the ALT_QSPI_WRPROT_EN register field. */
+#define ALT_QSPI_WRPROT_EN_WIDTH      1
+/* The mask used to set the ALT_QSPI_WRPROT_EN register field value. */
+#define ALT_QSPI_WRPROT_EN_SET_MSK    0x00000002
+/* The mask used to clear the ALT_QSPI_WRPROT_EN register field value. */
+#define ALT_QSPI_WRPROT_EN_CLR_MSK    0xfffffffd
+/* The reset value of the ALT_QSPI_WRPROT_EN register field. */
+#define ALT_QSPI_WRPROT_EN_RESET      0x0
+/* Extracts the ALT_QSPI_WRPROT_EN field value from a register. */
+#define ALT_QSPI_WRPROT_EN_GET(value) (((value) & 0x00000002) >> 1)
+/* Produces a ALT_QSPI_WRPROT_EN register field value suitable for setting the register. */
+#define ALT_QSPI_WRPROT_EN_SET(value) (((value) << 1) & 0x00000002)
+
+#ifndef __ASSEMBLY__
+/*
+ * WARNING: The C register and register group struct declarations are provided for
+ * convenience and illustrative purposes. They should, however, be used with
+ * caution as the C language standard provides no guarantees about the alignment or
+ * atomicity of device memory accesses. The recommended practice for writing
+ * hardware drivers is to use the SoCAL access macros and alt_read_word() and
+ * alt_write_word() functions.
+ * 
+ * The struct declaration for register ALT_QSPI_WRPROT.
+ */
+struct ALT_QSPI_WRPROT_s
+{
+    uint32_t  inv :  1;  /* Write Protection Inversion Bit */
+    uint32_t  en  :  1;  /* Write Protection Enable Bit */
+    uint32_t      : 30;  /* *UNDEFINED* */
+};
+
+/* The typedef declaration for register ALT_QSPI_WRPROT. */
+typedef volatile struct ALT_QSPI_WRPROT_s  ALT_QSPI_WRPROT_t;
+#endif  /* __ASSEMBLY__ */
+
+/* The byte offset of the ALT_QSPI_WRPROT register from the beginning of the component. */
+#define ALT_QSPI_WRPROT_OFST        0x58
+
+/*
+ * Register : Indirect Read Transfer Register - indrd
+ * 
+ * Register Layout
+ * 
+ *  Bits   | Access | Reset   | Description                    
+ * :-------|:-------|:--------|:--------------------------------
+ *  [0]    | RW     | 0x0     | Start Indirect Read            
+ *  [1]    | RW     | 0x0     | Cancel Indirect Read           
+ *  [2]    | R      | Unknown | Indirect Read Status           
+ *  [3]    | RW     | Unknown | SRAM Full                      
+ *  [4]    | R      | Unknown | Queued Indirect Read Operations
+ *  [5]    | RW     | Unknown | Indirect Completion Status     
+ *  [7:6]  | R      | Unknown | Completed Indirect Operations  
+ *  [31:8] | ???    | 0x0     | *UNDEFINED*                    
+ * 
+ */
+/*
+ * Field : Start Indirect Read - start
+ * 
+ * When this bit is enabled, it will trigger an indirect read operation. The
+ * assumption is that the indirect start address and the indirect number of bytes
+ * register is setup before triggering the indirect read operation.
+ * 
+ * Field Enumeration Values:
+ * 
+ *  Enum                        | Value | Description          
+ * :----------------------------|:------|:----------------------
+ *  ALT_QSPI_INDRD_START_E_END  | 0x1   | Trigger Indirect Read
+ *  ALT_QSPI_INDRD_START_E_DISD | 0x0   | No Indirect Read     
+ * 
+ * Field Access Macros:
+ * 
+ */
+/*
+ * Enumerated value for register field ALT_QSPI_INDRD_START
+ * 
+ * Trigger Indirect Read
+ */
+#define ALT_QSPI_INDRD_START_E_END  0x1
+/*
+ * Enumerated value for register field ALT_QSPI_INDRD_START
+ * 
+ * No Indirect Read
+ */
+#define ALT_QSPI_INDRD_START_E_DISD 0x0
+
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_INDRD_START register field. */
+#define ALT_QSPI_INDRD_START_LSB        0
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_INDRD_START register field. */
+#define ALT_QSPI_INDRD_START_MSB        0
+/* The width in bits of the ALT_QSPI_INDRD_START register field. */
+#define ALT_QSPI_INDRD_START_WIDTH      1
+/* The mask used to set the ALT_QSPI_INDRD_START register field value. */
+#define ALT_QSPI_INDRD_START_SET_MSK    0x00000001
+/* The mask used to clear the ALT_QSPI_INDRD_START register field value. */
+#define ALT_QSPI_INDRD_START_CLR_MSK    0xfffffffe
+/* The reset value of the ALT_QSPI_INDRD_START register field. */
+#define ALT_QSPI_INDRD_START_RESET      0x0
+/* Extracts the ALT_QSPI_INDRD_START field value from a register. */
+#define ALT_QSPI_INDRD_START_GET(value) (((value) & 0x00000001) >> 0)
+/* Produces a ALT_QSPI_INDRD_START register field value suitable for setting the register. */
+#define ALT_QSPI_INDRD_START_SET(value) (((value) << 0) & 0x00000001)
+
+/*
+ * Field : Cancel Indirect Read - cancel
+ * 
+ * This bit will cancel all ongoing indirect read operations.
+ * 
+ * Field Enumeration Values:
+ * 
+ *  Enum                             | Value | Description                
+ * :---------------------------------|:------|:----------------------------
+ *  ALT_QSPI_INDRD_CANCEL_E_CANCEL   | 0x1   | Cancel Indirect Read       
+ *  ALT_QSPI_INDRD_CANCEL_E_NOACTION | 0x0   | Do Not Cancel Indirect Read
+ * 
+ * Field Access Macros:
+ * 
+ */
+/*
+ * Enumerated value for register field ALT_QSPI_INDRD_CANCEL
+ * 
+ * Cancel Indirect Read
+ */
+#define ALT_QSPI_INDRD_CANCEL_E_CANCEL      0x1
+/*
+ * Enumerated value for register field ALT_QSPI_INDRD_CANCEL
+ * 
+ * Do Not Cancel Indirect Read
+ */
+#define ALT_QSPI_INDRD_CANCEL_E_NOACTION    0x0
+
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_INDRD_CANCEL register field. */
+#define ALT_QSPI_INDRD_CANCEL_LSB        1
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_INDRD_CANCEL register field. */
+#define ALT_QSPI_INDRD_CANCEL_MSB        1
+/* The width in bits of the ALT_QSPI_INDRD_CANCEL register field. */
+#define ALT_QSPI_INDRD_CANCEL_WIDTH      1
+/* The mask used to set the ALT_QSPI_INDRD_CANCEL register field value. */
+#define ALT_QSPI_INDRD_CANCEL_SET_MSK    0x00000002
+/* The mask used to clear the ALT_QSPI_INDRD_CANCEL register field value. */
+#define ALT_QSPI_INDRD_CANCEL_CLR_MSK    0xfffffffd
+/* The reset value of the ALT_QSPI_INDRD_CANCEL register field. */
+#define ALT_QSPI_INDRD_CANCEL_RESET      0x0
+/* Extracts the ALT_QSPI_INDRD_CANCEL field value from a register. */
+#define ALT_QSPI_INDRD_CANCEL_GET(value) (((value) & 0x00000002) >> 1)
+/* Produces a ALT_QSPI_INDRD_CANCEL register field value suitable for setting the register. */
+#define ALT_QSPI_INDRD_CANCEL_SET(value) (((value) << 1) & 0x00000002)
+
+/*
+ * Field : Indirect Read Status - rd_status
+ * 
+ * Indirect read operation in progress (status)
+ * 
+ * Field Enumeration Values:
+ * 
+ *  Enum                              | Value | Description                  
+ * :----------------------------------|:------|:------------------------------
+ *  ALT_QSPI_INDRD_RD_STAT_E_RDOP     | 0x1   | Read Operation in progress   
+ *  ALT_QSPI_INDRD_RD_STAT_E_NOACTION | 0x0   | No read operation in progress
+ * 
+ * Field Access Macros:
+ * 
+ */
+/*
+ * Enumerated value for register field ALT_QSPI_INDRD_RD_STAT
+ * 
+ * Read Operation in progress
+ */
+#define ALT_QSPI_INDRD_RD_STAT_E_RDOP       0x1
+/*
+ * Enumerated value for register field ALT_QSPI_INDRD_RD_STAT
+ * 
+ * No read operation in progress
+ */
+#define ALT_QSPI_INDRD_RD_STAT_E_NOACTION   0x0
+
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_INDRD_RD_STAT register field. */
+#define ALT_QSPI_INDRD_RD_STAT_LSB        2
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_INDRD_RD_STAT register field. */
+#define ALT_QSPI_INDRD_RD_STAT_MSB        2
+/* The width in bits of the ALT_QSPI_INDRD_RD_STAT register field. */
+#define ALT_QSPI_INDRD_RD_STAT_WIDTH      1
+/* The mask used to set the ALT_QSPI_INDRD_RD_STAT register field value. */
+#define ALT_QSPI_INDRD_RD_STAT_SET_MSK    0x00000004
+/* The mask used to clear the ALT_QSPI_INDRD_RD_STAT register field value. */
+#define ALT_QSPI_INDRD_RD_STAT_CLR_MSK    0xfffffffb
+/* The reset value of the ALT_QSPI_INDRD_RD_STAT register field is UNKNOWN. */
+#define ALT_QSPI_INDRD_RD_STAT_RESET      0x0
+/* Extracts the ALT_QSPI_INDRD_RD_STAT field value from a register. */
+#define ALT_QSPI_INDRD_RD_STAT_GET(value) (((value) & 0x00000004) >> 2)
+/* Produces a ALT_QSPI_INDRD_RD_STAT register field value suitable for setting the register. */
+#define ALT_QSPI_INDRD_RD_STAT_SET(value) (((value) << 2) & 0x00000004)
+
+/*
+ * Field : SRAM Full - sram_full
+ * 
+ * SRAM full and unable to immediately complete an indirect operation. Write a 1 to
+ * this field to clear it. ; indirect operation (status)
+ * 
+ * Field Enumeration Values:
+ * 
+ *  Enum                                | Value | Description                       
+ * :------------------------------------|:------|:-----------------------------------
+ *  ALT_QSPI_INDRD_SRAM_FULL_E_SRAMFULL | 0x1   | Sram Full- Cant complete operation
+ *  ALT_QSPI_INDRD_SRAM_FULL_E_NOACTION | 0x0   | SRram Not Full                    
+ * 
+ * Field Access Macros:
+ * 
+ */
+/*
+ * Enumerated value for register field ALT_QSPI_INDRD_SRAM_FULL
+ * 
+ * Sram Full- Cant complete operation
+ */
+#define ALT_QSPI_INDRD_SRAM_FULL_E_SRAMFULL 0x1
+/*
+ * Enumerated value for register field ALT_QSPI_INDRD_SRAM_FULL
+ * 
+ * SRram Not Full
+ */
+#define ALT_QSPI_INDRD_SRAM_FULL_E_NOACTION 0x0
+
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_INDRD_SRAM_FULL register field. */
+#define ALT_QSPI_INDRD_SRAM_FULL_LSB        3
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_INDRD_SRAM_FULL register field. */
+#define ALT_QSPI_INDRD_SRAM_FULL_MSB        3
+/* The width in bits of the ALT_QSPI_INDRD_SRAM_FULL register field. */
+#define ALT_QSPI_INDRD_SRAM_FULL_WIDTH      1
+/* The mask used to set the ALT_QSPI_INDRD_SRAM_FULL register field value. */
+#define ALT_QSPI_INDRD_SRAM_FULL_SET_MSK    0x00000008
+/* The mask used to clear the ALT_QSPI_INDRD_SRAM_FULL register field value. */
+#define ALT_QSPI_INDRD_SRAM_FULL_CLR_MSK    0xfffffff7
+/* The reset value of the ALT_QSPI_INDRD_SRAM_FULL register field is UNKNOWN. */
+#define ALT_QSPI_INDRD_SRAM_FULL_RESET      0x0
+/* Extracts the ALT_QSPI_INDRD_SRAM_FULL field value from a register. */
+#define ALT_QSPI_INDRD_SRAM_FULL_GET(value) (((value) & 0x00000008) >> 3)
+/* Produces a ALT_QSPI_INDRD_SRAM_FULL register field value suitable for setting the register. */
+#define ALT_QSPI_INDRD_SRAM_FULL_SET(value) (((value) << 3) & 0x00000008)
+
+/*
+ * Field : Queued Indirect Read Operations - rd_queued
+ * 
+ * Two indirect read operations have been queued
+ * 
+ * Field Enumeration Values:
+ * 
+ *  Enum                                    | Value | Description         
+ * :----------------------------------------|:------|:---------------------
+ *  ALT_QSPI_INDRD_RD_QUEUED_E_QUINDIRECTRD | 0x1   | Queued Indirect Read
+ *  ALT_QSPI_INDRD_RD_QUEUED_E_NOACTION     | 0x0   | No Queued Read      
+ * 
+ * Field Access Macros:
+ * 
+ */
+/*
+ * Enumerated value for register field ALT_QSPI_INDRD_RD_QUEUED
+ * 
+ * Queued Indirect Read
+ */
+#define ALT_QSPI_INDRD_RD_QUEUED_E_QUINDIRECTRD 0x1
+/*
+ * Enumerated value for register field ALT_QSPI_INDRD_RD_QUEUED
+ * 
+ * No Queued Read
+ */
+#define ALT_QSPI_INDRD_RD_QUEUED_E_NOACTION     0x0
+
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_INDRD_RD_QUEUED register field. */
+#define ALT_QSPI_INDRD_RD_QUEUED_LSB        4
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_INDRD_RD_QUEUED register field. */
+#define ALT_QSPI_INDRD_RD_QUEUED_MSB        4
+/* The width in bits of the ALT_QSPI_INDRD_RD_QUEUED register field. */
+#define ALT_QSPI_INDRD_RD_QUEUED_WIDTH      1
+/* The mask used to set the ALT_QSPI_INDRD_RD_QUEUED register field value. */
+#define ALT_QSPI_INDRD_RD_QUEUED_SET_MSK    0x00000010
+/* The mask used to clear the ALT_QSPI_INDRD_RD_QUEUED register field value. */
+#define ALT_QSPI_INDRD_RD_QUEUED_CLR_MSK    0xffffffef
+/* The reset value of the ALT_QSPI_INDRD_RD_QUEUED register field is UNKNOWN. */
+#define ALT_QSPI_INDRD_RD_QUEUED_RESET      0x0
+/* Extracts the ALT_QSPI_INDRD_RD_QUEUED field value from a register. */
+#define ALT_QSPI_INDRD_RD_QUEUED_GET(value) (((value) & 0x00000010) >> 4)
+/* Produces a ALT_QSPI_INDRD_RD_QUEUED register field value suitable for setting the register. */
+#define ALT_QSPI_INDRD_RD_QUEUED_SET(value) (((value) << 4) & 0x00000010)
+
+/*
+ * Field : Indirect Completion Status - ind_ops_done_status
+ * 
+ * This field is set to 1 when an indirect operation has completed. Write a 1 to
+ * this field to clear it.
+ * 
+ * Field Enumeration Values:
+ * 
+ *  Enum                                        | Value | Description                   
+ * :--------------------------------------------|:------|:-------------------------------
+ *  ALT_QSPI_INDRD_IND_OPS_DONE_STAT_E_INDCOMP  | 0x1   | Indirect Op Complete operation
+ *  ALT_QSPI_INDRD_IND_OPS_DONE_STAT_E_NOACTION | 0x0   | Indirect Op Not Complete      
+ * 
+ * Field Access Macros:
+ * 
+ */
+/*
+ * Enumerated value for register field ALT_QSPI_INDRD_IND_OPS_DONE_STAT
+ * 
+ * Indirect Op Complete operation
+ */
+#define ALT_QSPI_INDRD_IND_OPS_DONE_STAT_E_INDCOMP  0x1
+/*
+ * Enumerated value for register field ALT_QSPI_INDRD_IND_OPS_DONE_STAT
+ * 
+ * Indirect Op Not Complete
+ */
+#define ALT_QSPI_INDRD_IND_OPS_DONE_STAT_E_NOACTION 0x0
+
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_INDRD_IND_OPS_DONE_STAT register field. */
+#define ALT_QSPI_INDRD_IND_OPS_DONE_STAT_LSB        5
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_INDRD_IND_OPS_DONE_STAT register field. */
+#define ALT_QSPI_INDRD_IND_OPS_DONE_STAT_MSB        5
+/* The width in bits of the ALT_QSPI_INDRD_IND_OPS_DONE_STAT register field. */
+#define ALT_QSPI_INDRD_IND_OPS_DONE_STAT_WIDTH      1
+/* The mask used to set the ALT_QSPI_INDRD_IND_OPS_DONE_STAT register field value. */
+#define ALT_QSPI_INDRD_IND_OPS_DONE_STAT_SET_MSK    0x00000020
+/* The mask used to clear the ALT_QSPI_INDRD_IND_OPS_DONE_STAT register field value. */
+#define ALT_QSPI_INDRD_IND_OPS_DONE_STAT_CLR_MSK    0xffffffdf
+/* The reset value of the ALT_QSPI_INDRD_IND_OPS_DONE_STAT register field is UNKNOWN. */
+#define ALT_QSPI_INDRD_IND_OPS_DONE_STAT_RESET      0x0
+/* Extracts the ALT_QSPI_INDRD_IND_OPS_DONE_STAT field value from a register. */
+#define ALT_QSPI_INDRD_IND_OPS_DONE_STAT_GET(value) (((value) & 0x00000020) >> 5)
+/* Produces a ALT_QSPI_INDRD_IND_OPS_DONE_STAT register field value suitable for setting the register. */
+#define ALT_QSPI_INDRD_IND_OPS_DONE_STAT_SET(value) (((value) << 5) & 0x00000020)
+
+/*
+ * Field : Completed Indirect Operations - num_ind_ops_done
+ * 
+ * This field contains the number of indirect operations which have been completed.
+ * This is used in conjunction with the indirect completion status field (bit 5).
+ * 
+ * Field Access Macros:
+ * 
+ */
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_INDRD_NUM_IND_OPS_DONE register field. */
+#define ALT_QSPI_INDRD_NUM_IND_OPS_DONE_LSB        6
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_INDRD_NUM_IND_OPS_DONE register field. */
+#define ALT_QSPI_INDRD_NUM_IND_OPS_DONE_MSB        7
+/* The width in bits of the ALT_QSPI_INDRD_NUM_IND_OPS_DONE register field. */
+#define ALT_QSPI_INDRD_NUM_IND_OPS_DONE_WIDTH      2
+/* The mask used to set the ALT_QSPI_INDRD_NUM_IND_OPS_DONE register field value. */
+#define ALT_QSPI_INDRD_NUM_IND_OPS_DONE_SET_MSK    0x000000c0
+/* The mask used to clear the ALT_QSPI_INDRD_NUM_IND_OPS_DONE register field value. */
+#define ALT_QSPI_INDRD_NUM_IND_OPS_DONE_CLR_MSK    0xffffff3f
+/* The reset value of the ALT_QSPI_INDRD_NUM_IND_OPS_DONE register field is UNKNOWN. */
+#define ALT_QSPI_INDRD_NUM_IND_OPS_DONE_RESET      0x0
+/* Extracts the ALT_QSPI_INDRD_NUM_IND_OPS_DONE field value from a register. */
+#define ALT_QSPI_INDRD_NUM_IND_OPS_DONE_GET(value) (((value) & 0x000000c0) >> 6)
+/* Produces a ALT_QSPI_INDRD_NUM_IND_OPS_DONE register field value suitable for setting the register. */
+#define ALT_QSPI_INDRD_NUM_IND_OPS_DONE_SET(value) (((value) << 6) & 0x000000c0)
+
+#ifndef __ASSEMBLY__
+/*
+ * WARNING: The C register and register group struct declarations are provided for
+ * convenience and illustrative purposes. They should, however, be used with
+ * caution as the C language standard provides no guarantees about the alignment or
+ * atomicity of device memory accesses. The recommended practice for writing
+ * hardware drivers is to use the SoCAL access macros and alt_read_word() and
+ * alt_write_word() functions.
+ * 
+ * The struct declaration for register ALT_QSPI_INDRD.
+ */
+struct ALT_QSPI_INDRD_s
+{
+    uint32_t        start               :  1;  /* Start Indirect Read */
+    uint32_t        cancel              :  1;  /* Cancel Indirect Read */
+    const uint32_t  rd_status           :  1;  /* Indirect Read Status */
+    uint32_t        sram_full           :  1;  /* SRAM Full */
+    const uint32_t  rd_queued           :  1;  /* Queued Indirect Read Operations */
+    uint32_t        ind_ops_done_status :  1;  /* Indirect Completion Status */
+    const uint32_t  num_ind_ops_done    :  2;  /* Completed Indirect Operations */
+    uint32_t                            : 24;  /* *UNDEFINED* */
+};
+
+/* The typedef declaration for register ALT_QSPI_INDRD. */
+typedef volatile struct ALT_QSPI_INDRD_s  ALT_QSPI_INDRD_t;
+#endif  /* __ASSEMBLY__ */
+
+/* The byte offset of the ALT_QSPI_INDRD register from the beginning of the component. */
+#define ALT_QSPI_INDRD_OFST        0x60
+
+/*
+ * Register : Indirect Read Transfer Watermark Register - indrdwater
+ * 
+ * Register Layout
+ * 
+ *  Bits   | Access | Reset | Description    
+ * :-------|:-------|:------|:----------------
+ *  [31:0] | RW     | 0x0   | Watermark Value
+ * 
+ */
+/*
+ * Field : Watermark Value - level
+ * 
+ * This represents the minimum fill level of the SRAM before a DMA peripheral
+ * access is permitted. When the SRAM fill level passes the watermark, an interrupt
+ * is also generated. This field can be disabled by writing a value of all zeroes.
+ * The units of this register are BYTES
+ * 
+ * Field Access Macros:
+ * 
+ */
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_INDRDWATER_LEVEL register field. */
+#define ALT_QSPI_INDRDWATER_LEVEL_LSB        0
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_INDRDWATER_LEVEL register field. */
+#define ALT_QSPI_INDRDWATER_LEVEL_MSB        31
+/* The width in bits of the ALT_QSPI_INDRDWATER_LEVEL register field. */
+#define ALT_QSPI_INDRDWATER_LEVEL_WIDTH      32
+/* The mask used to set the ALT_QSPI_INDRDWATER_LEVEL register field value. */
+#define ALT_QSPI_INDRDWATER_LEVEL_SET_MSK    0xffffffff
+/* The mask used to clear the ALT_QSPI_INDRDWATER_LEVEL register field value. */
+#define ALT_QSPI_INDRDWATER_LEVEL_CLR_MSK    0x00000000
+/* The reset value of the ALT_QSPI_INDRDWATER_LEVEL register field. */
+#define ALT_QSPI_INDRDWATER_LEVEL_RESET      0x0
+/* Extracts the ALT_QSPI_INDRDWATER_LEVEL field value from a register. */
+#define ALT_QSPI_INDRDWATER_LEVEL_GET(value) (((value) & 0xffffffff) >> 0)
+/* Produces a ALT_QSPI_INDRDWATER_LEVEL register field value suitable for setting the register. */
+#define ALT_QSPI_INDRDWATER_LEVEL_SET(value) (((value) << 0) & 0xffffffff)
+
+#ifndef __ASSEMBLY__
+/*
+ * WARNING: The C register and register group struct declarations are provided for
+ * convenience and illustrative purposes. They should, however, be used with
+ * caution as the C language standard provides no guarantees about the alignment or
+ * atomicity of device memory accesses. The recommended practice for writing
+ * hardware drivers is to use the SoCAL access macros and alt_read_word() and
+ * alt_write_word() functions.
+ * 
+ * The struct declaration for register ALT_QSPI_INDRDWATER.
+ */
+struct ALT_QSPI_INDRDWATER_s
+{
+    uint32_t  level : 32;  /* Watermark Value */
+};
+
+/* The typedef declaration for register ALT_QSPI_INDRDWATER. */
+typedef volatile struct ALT_QSPI_INDRDWATER_s  ALT_QSPI_INDRDWATER_t;
+#endif  /* __ASSEMBLY__ */
+
+/* The byte offset of the ALT_QSPI_INDRDWATER register from the beginning of the component. */
+#define ALT_QSPI_INDRDWATER_OFST        0x64
+
+/*
+ * Register : Indirect Read Transfer Start Address Register - indrdstaddr
+ * 
+ * Register Layout
+ * 
+ *  Bits   | Access | Reset | Description                     
+ * :-------|:-------|:------|:---------------------------------
+ *  [31:0] | RW     | 0x0   | Start Address of Indirect Access
+ * 
+ */
+/*
+ * Field : Start Address of Indirect Access - addr
+ * 
+ * This is the start address from which the indirect access will commence its READ
+ * operation.
+ * 
+ * Field Access Macros:
+ * 
+ */
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_INDRDSTADDR_ADDR register field. */
+#define ALT_QSPI_INDRDSTADDR_ADDR_LSB        0
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_INDRDSTADDR_ADDR register field. */
+#define ALT_QSPI_INDRDSTADDR_ADDR_MSB        31
+/* The width in bits of the ALT_QSPI_INDRDSTADDR_ADDR register field. */
+#define ALT_QSPI_INDRDSTADDR_ADDR_WIDTH      32
+/* The mask used to set the ALT_QSPI_INDRDSTADDR_ADDR register field value. */
+#define ALT_QSPI_INDRDSTADDR_ADDR_SET_MSK    0xffffffff
+/* The mask used to clear the ALT_QSPI_INDRDSTADDR_ADDR register field value. */
+#define ALT_QSPI_INDRDSTADDR_ADDR_CLR_MSK    0x00000000
+/* The reset value of the ALT_QSPI_INDRDSTADDR_ADDR register field. */
+#define ALT_QSPI_INDRDSTADDR_ADDR_RESET      0x0
+/* Extracts the ALT_QSPI_INDRDSTADDR_ADDR field value from a register. */
+#define ALT_QSPI_INDRDSTADDR_ADDR_GET(value) (((value) & 0xffffffff) >> 0)
+/* Produces a ALT_QSPI_INDRDSTADDR_ADDR register field value suitable for setting the register. */
+#define ALT_QSPI_INDRDSTADDR_ADDR_SET(value) (((value) << 0) & 0xffffffff)
+
+#ifndef __ASSEMBLY__
+/*
+ * WARNING: The C register and register group struct declarations are provided for
+ * convenience and illustrative purposes. They should, however, be used with
+ * caution as the C language standard provides no guarantees about the alignment or
+ * atomicity of device memory accesses. The recommended practice for writing
+ * hardware drivers is to use the SoCAL access macros and alt_read_word() and
+ * alt_write_word() functions.
+ * 
+ * The struct declaration for register ALT_QSPI_INDRDSTADDR.
+ */
+struct ALT_QSPI_INDRDSTADDR_s
+{
+    uint32_t  addr : 32;  /* Start Address of Indirect Access */
+};
+
+/* The typedef declaration for register ALT_QSPI_INDRDSTADDR. */
+typedef volatile struct ALT_QSPI_INDRDSTADDR_s  ALT_QSPI_INDRDSTADDR_t;
+#endif  /* __ASSEMBLY__ */
+
+/* The byte offset of the ALT_QSPI_INDRDSTADDR register from the beginning of the component. */
+#define ALT_QSPI_INDRDSTADDR_OFST        0x68
+
+/*
+ * Register : Indirect Read Transfer Number Bytes Register - indrdcnt
+ * 
+ * Register Layout
+ * 
+ *  Bits   | Access | Reset | Description   
+ * :-------|:-------|:------|:---------------
+ *  [31:0] | RW     | 0x0   | Indirect Count
+ * 
+ */
+/*
+ * Field : Indirect Count - value
+ * 
+ * This is the number of bytes that the indirect access will consume. This can be
+ * bigger than the configured size of SRAM.
+ * 
+ * Field Access Macros:
+ * 
+ */
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_INDRDCNT_VALUE register field. */
+#define ALT_QSPI_INDRDCNT_VALUE_LSB        0
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_INDRDCNT_VALUE register field. */
+#define ALT_QSPI_INDRDCNT_VALUE_MSB        31
+/* The width in bits of the ALT_QSPI_INDRDCNT_VALUE register field. */
+#define ALT_QSPI_INDRDCNT_VALUE_WIDTH      32
+/* The mask used to set the ALT_QSPI_INDRDCNT_VALUE register field value. */
+#define ALT_QSPI_INDRDCNT_VALUE_SET_MSK    0xffffffff
+/* The mask used to clear the ALT_QSPI_INDRDCNT_VALUE register field value. */
+#define ALT_QSPI_INDRDCNT_VALUE_CLR_MSK    0x00000000
+/* The reset value of the ALT_QSPI_INDRDCNT_VALUE register field. */
+#define ALT_QSPI_INDRDCNT_VALUE_RESET      0x0
+/* Extracts the ALT_QSPI_INDRDCNT_VALUE field value from a register. */
+#define ALT_QSPI_INDRDCNT_VALUE_GET(value) (((value) & 0xffffffff) >> 0)
+/* Produces a ALT_QSPI_INDRDCNT_VALUE register field value suitable for setting the register. */
+#define ALT_QSPI_INDRDCNT_VALUE_SET(value) (((value) << 0) & 0xffffffff)
+
+#ifndef __ASSEMBLY__
+/*
+ * WARNING: The C register and register group struct declarations are provided for
+ * convenience and illustrative purposes. They should, however, be used with
+ * caution as the C language standard provides no guarantees about the alignment or
+ * atomicity of device memory accesses. The recommended practice for writing
+ * hardware drivers is to use the SoCAL access macros and alt_read_word() and
+ * alt_write_word() functions.
+ * 
+ * The struct declaration for register ALT_QSPI_INDRDCNT.
+ */
+struct ALT_QSPI_INDRDCNT_s
+{
+    uint32_t  value : 32;  /* Indirect Count */
+};
+
+/* The typedef declaration for register ALT_QSPI_INDRDCNT. */
+typedef volatile struct ALT_QSPI_INDRDCNT_s  ALT_QSPI_INDRDCNT_t;
+#endif  /* __ASSEMBLY__ */
+
+/* The byte offset of the ALT_QSPI_INDRDCNT register from the beginning of the component. */
+#define ALT_QSPI_INDRDCNT_OFST        0x6c
+
+/*
+ * Register : Indirect Write Transfer Register - indwr
+ * 
+ * Register Layout
+ * 
+ *  Bits   | Access | Reset   | Description                     
+ * :-------|:-------|:--------|:---------------------------------
+ *  [0]    | RW     | 0x0     | Start Indirect Write            
+ *  [1]    | RW     | 0x0     | Cancel Indirect Write           
+ *  [2]    | R      | Unknown | Indirect Write Status           
+ *  [3]    | R      | 0x0     | Reserved                        
+ *  [4]    | R      | Unknown | Queued Indirect Write Operations
+ *  [5]    | RW     | Unknown | Indirect Completion Status      
+ *  [7:6]  | R      | Unknown | Completed Indirect Operations   
+ *  [31:8] | ???    | 0x0     | *UNDEFINED*                     
+ * 
+ */
+/*
+ * Field : Start Indirect Write - start
+ * 
+ * Writing a 1 to this bit will trigger an indirect write operation. The assumption
+ * is that the indirect start address and the indirect number of bytes register is
+ * setup before triggering the indirect write operation.
+ * 
+ * Field Enumeration Values:
+ * 
+ *  Enum                        | Value | Description                     
+ * :----------------------------|:------|:---------------------------------
+ *  ALT_QSPI_INDWR_START_E_END  | 0x1   | Trigger indirect write operation
+ *  ALT_QSPI_INDWR_START_E_DISD | 0x0   | No Action                       
+ * 
+ * Field Access Macros:
+ * 
+ */
+/*
+ * Enumerated value for register field ALT_QSPI_INDWR_START
+ * 
+ * Trigger indirect write operation
+ */
+#define ALT_QSPI_INDWR_START_E_END  0x1
+/*
+ * Enumerated value for register field ALT_QSPI_INDWR_START
+ * 
+ * No Action
+ */
+#define ALT_QSPI_INDWR_START_E_DISD 0x0
+
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_INDWR_START register field. */
+#define ALT_QSPI_INDWR_START_LSB        0
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_INDWR_START register field. */
+#define ALT_QSPI_INDWR_START_MSB        0
+/* The width in bits of the ALT_QSPI_INDWR_START register field. */
+#define ALT_QSPI_INDWR_START_WIDTH      1
+/* The mask used to set the ALT_QSPI_INDWR_START register field value. */
+#define ALT_QSPI_INDWR_START_SET_MSK    0x00000001
+/* The mask used to clear the ALT_QSPI_INDWR_START register field value. */
+#define ALT_QSPI_INDWR_START_CLR_MSK    0xfffffffe
+/* The reset value of the ALT_QSPI_INDWR_START register field. */
+#define ALT_QSPI_INDWR_START_RESET      0x0
+/* Extracts the ALT_QSPI_INDWR_START field value from a register. */
+#define ALT_QSPI_INDWR_START_GET(value) (((value) & 0x00000001) >> 0)
+/* Produces a ALT_QSPI_INDWR_START register field value suitable for setting the register. */
+#define ALT_QSPI_INDWR_START_SET(value) (((value) << 0) & 0x00000001)
+
+/*
+ * Field : Cancel Indirect Write - cancel
+ * 
+ * Writing a 1 to this bit will cancel all ongoing indirect write operations.
+ * 
+ * Field Enumeration Values:
+ * 
+ *  Enum                               | Value | Description                    
+ * :-----------------------------------|:------|:--------------------------------
+ *  ALT_QSPI_INDWR_CANCEL_E_CANCEINDWR | 0x1   | Cancel Indirect write operation
+ *  ALT_QSPI_INDWR_CANCEL_E_NOACTION   | 0x0   | No Action                      
+ * 
+ * Field Access Macros:
+ * 
+ */
+/*
+ * Enumerated value for register field ALT_QSPI_INDWR_CANCEL
+ * 
+ * Cancel Indirect write operation
+ */
+#define ALT_QSPI_INDWR_CANCEL_E_CANCEINDWR  0x1
+/*
+ * Enumerated value for register field ALT_QSPI_INDWR_CANCEL
+ * 
+ * No Action
+ */
+#define ALT_QSPI_INDWR_CANCEL_E_NOACTION    0x0
+
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_INDWR_CANCEL register field. */
+#define ALT_QSPI_INDWR_CANCEL_LSB        1
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_INDWR_CANCEL register field. */
+#define ALT_QSPI_INDWR_CANCEL_MSB        1
+/* The width in bits of the ALT_QSPI_INDWR_CANCEL register field. */
+#define ALT_QSPI_INDWR_CANCEL_WIDTH      1
+/* The mask used to set the ALT_QSPI_INDWR_CANCEL register field value. */
+#define ALT_QSPI_INDWR_CANCEL_SET_MSK    0x00000002
+/* The mask used to clear the ALT_QSPI_INDWR_CANCEL register field value. */
+#define ALT_QSPI_INDWR_CANCEL_CLR_MSK    0xfffffffd
+/* The reset value of the ALT_QSPI_INDWR_CANCEL register field. */
+#define ALT_QSPI_INDWR_CANCEL_RESET      0x0
+/* Extracts the ALT_QSPI_INDWR_CANCEL field value from a register. */
+#define ALT_QSPI_INDWR_CANCEL_GET(value) (((value) & 0x00000002) >> 1)
+/* Produces a ALT_QSPI_INDWR_CANCEL register field value suitable for setting the register. */
+#define ALT_QSPI_INDWR_CANCEL_SET(value) (((value) << 1) & 0x00000002)
+
+/*
+ * Field : Indirect Write Status - rdstat
+ * 
+ * Indirect write operation in progress (status)
+ * 
+ * Field Enumeration Values:
+ * 
+ *  Enum                              | Value | Description             
+ * :----------------------------------|:------|:-------------------------
+ *  ALT_QSPI_INDWR_RDSTAT_E_INDWRSTAT | 0x1   | Indirect write operation
+ *  ALT_QSPI_INDWR_RDSTAT_E_NOACTION  | 0x0   | No Action               
+ * 
+ * Field Access Macros:
+ * 
+ */
+/*
+ * Enumerated value for register field ALT_QSPI_INDWR_RDSTAT
+ * 
+ * Indirect write operation
+ */
+#define ALT_QSPI_INDWR_RDSTAT_E_INDWRSTAT   0x1
+/*
+ * Enumerated value for register field ALT_QSPI_INDWR_RDSTAT
+ * 
+ * No Action
+ */
+#define ALT_QSPI_INDWR_RDSTAT_E_NOACTION    0x0
+
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_INDWR_RDSTAT register field. */
+#define ALT_QSPI_INDWR_RDSTAT_LSB        2
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_INDWR_RDSTAT register field. */
+#define ALT_QSPI_INDWR_RDSTAT_MSB        2
+/* The width in bits of the ALT_QSPI_INDWR_RDSTAT register field. */
+#define ALT_QSPI_INDWR_RDSTAT_WIDTH      1
+/* The mask used to set the ALT_QSPI_INDWR_RDSTAT register field value. */
+#define ALT_QSPI_INDWR_RDSTAT_SET_MSK    0x00000004
+/* The mask used to clear the ALT_QSPI_INDWR_RDSTAT register field value. */
+#define ALT_QSPI_INDWR_RDSTAT_CLR_MSK    0xfffffffb
+/* The reset value of the ALT_QSPI_INDWR_RDSTAT register field is UNKNOWN. */
+#define ALT_QSPI_INDWR_RDSTAT_RESET      0x0
+/* Extracts the ALT_QSPI_INDWR_RDSTAT field value from a register. */
+#define ALT_QSPI_INDWR_RDSTAT_GET(value) (((value) & 0x00000004) >> 2)
+/* Produces a ALT_QSPI_INDWR_RDSTAT register field value suitable for setting the register. */
+#define ALT_QSPI_INDWR_RDSTAT_SET(value) (((value) << 2) & 0x00000004)
+
+/*
+ * Field : Reserved - sramfull
+ * 
+ * Field Access Macros:
+ * 
+ */
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_INDWR_SRAMFULL register field. */
+#define ALT_QSPI_INDWR_SRAMFULL_LSB        3
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_INDWR_SRAMFULL register field. */
+#define ALT_QSPI_INDWR_SRAMFULL_MSB        3
+/* The width in bits of the ALT_QSPI_INDWR_SRAMFULL register field. */
+#define ALT_QSPI_INDWR_SRAMFULL_WIDTH      1
+/* The mask used to set the ALT_QSPI_INDWR_SRAMFULL register field value. */
+#define ALT_QSPI_INDWR_SRAMFULL_SET_MSK    0x00000008
+/* The mask used to clear the ALT_QSPI_INDWR_SRAMFULL register field value. */
+#define ALT_QSPI_INDWR_SRAMFULL_CLR_MSK    0xfffffff7
+/* The reset value of the ALT_QSPI_INDWR_SRAMFULL register field. */
+#define ALT_QSPI_INDWR_SRAMFULL_RESET      0x0
+/* Extracts the ALT_QSPI_INDWR_SRAMFULL field value from a register. */
+#define ALT_QSPI_INDWR_SRAMFULL_GET(value) (((value) & 0x00000008) >> 3)
+/* Produces a ALT_QSPI_INDWR_SRAMFULL register field value suitable for setting the register. */
+#define ALT_QSPI_INDWR_SRAMFULL_SET(value) (((value) << 3) & 0x00000008)
+
+/*
+ * Field : Queued Indirect Write Operations - rdqueued
+ * 
+ * Two indirect write operations have been queued
+ * 
+ * Field Enumeration Values:
+ * 
+ *  Enum                               | Value | Description                 
+ * :-----------------------------------|:------|:-----------------------------
+ *  ALT_QSPI_INDWR_RDQUEUED_E_INDWROP  | 0x1   | Two Indirect write operation
+ *  ALT_QSPI_INDWR_RDQUEUED_E_NOACTION | 0x0   | No Action                   
+ * 
+ * Field Access Macros:
+ * 
+ */
+/*
+ * Enumerated value for register field ALT_QSPI_INDWR_RDQUEUED
+ * 
+ * Two Indirect write operation
+ */
+#define ALT_QSPI_INDWR_RDQUEUED_E_INDWROP   0x1
+/*
+ * Enumerated value for register field ALT_QSPI_INDWR_RDQUEUED
+ * 
+ * No Action
+ */
+#define ALT_QSPI_INDWR_RDQUEUED_E_NOACTION  0x0
+
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_INDWR_RDQUEUED register field. */
+#define ALT_QSPI_INDWR_RDQUEUED_LSB        4
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_INDWR_RDQUEUED register field. */
+#define ALT_QSPI_INDWR_RDQUEUED_MSB        4
+/* The width in bits of the ALT_QSPI_INDWR_RDQUEUED register field. */
+#define ALT_QSPI_INDWR_RDQUEUED_WIDTH      1
+/* The mask used to set the ALT_QSPI_INDWR_RDQUEUED register field value. */
+#define ALT_QSPI_INDWR_RDQUEUED_SET_MSK    0x00000010
+/* The mask used to clear the ALT_QSPI_INDWR_RDQUEUED register field value. */
+#define ALT_QSPI_INDWR_RDQUEUED_CLR_MSK    0xffffffef
+/* The reset value of the ALT_QSPI_INDWR_RDQUEUED register field is UNKNOWN. */
+#define ALT_QSPI_INDWR_RDQUEUED_RESET      0x0
+/* Extracts the ALT_QSPI_INDWR_RDQUEUED field value from a register. */
+#define ALT_QSPI_INDWR_RDQUEUED_GET(value) (((value) & 0x00000010) >> 4)
+/* Produces a ALT_QSPI_INDWR_RDQUEUED register field value suitable for setting the register. */
+#define ALT_QSPI_INDWR_RDQUEUED_SET(value) (((value) << 4) & 0x00000010)
+
+/*
+ * Field : Indirect Completion Status - inddone
+ * 
+ * This field is set to 1 when an indirect operation has completed. Write a 1 to
+ * this field to clear it.
+ * 
+ * Field Enumeration Values:
+ * 
+ *  Enum                               | Value | Description                 
+ * :-----------------------------------|:------|:-----------------------------
+ *  ALT_QSPI_INDWR_INDDONE_E_INDCOMPST | 0x1   | Indirect operation completed
+ *  ALT_QSPI_INDWR_INDDONE_E_NOACTION  | 0x0   | No Action                   
+ * 
+ * Field Access Macros:
+ * 
+ */
+/*
+ * Enumerated value for register field ALT_QSPI_INDWR_INDDONE
+ * 
+ * Indirect operation completed
+ */
+#define ALT_QSPI_INDWR_INDDONE_E_INDCOMPST  0x1
+/*
+ * Enumerated value for register field ALT_QSPI_INDWR_INDDONE
+ * 
+ * No Action
+ */
+#define ALT_QSPI_INDWR_INDDONE_E_NOACTION   0x0
+
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_INDWR_INDDONE register field. */
+#define ALT_QSPI_INDWR_INDDONE_LSB        5
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_INDWR_INDDONE register field. */
+#define ALT_QSPI_INDWR_INDDONE_MSB        5
+/* The width in bits of the ALT_QSPI_INDWR_INDDONE register field. */
+#define ALT_QSPI_INDWR_INDDONE_WIDTH      1
+/* The mask used to set the ALT_QSPI_INDWR_INDDONE register field value. */
+#define ALT_QSPI_INDWR_INDDONE_SET_MSK    0x00000020
+/* The mask used to clear the ALT_QSPI_INDWR_INDDONE register field value. */
+#define ALT_QSPI_INDWR_INDDONE_CLR_MSK    0xffffffdf
+/* The reset value of the ALT_QSPI_INDWR_INDDONE register field is UNKNOWN. */
+#define ALT_QSPI_INDWR_INDDONE_RESET      0x0
+/* Extracts the ALT_QSPI_INDWR_INDDONE field value from a register. */
+#define ALT_QSPI_INDWR_INDDONE_GET(value) (((value) & 0x00000020) >> 5)
+/* Produces a ALT_QSPI_INDWR_INDDONE register field value suitable for setting the register. */
+#define ALT_QSPI_INDWR_INDDONE_SET(value) (((value) << 5) & 0x00000020)
+
+/*
+ * Field : Completed Indirect Operations - indcnt
+ * 
+ * This field contains the count of indirect operations which have been completed.
+ * This is used in conjunction with the indirect completion status field (bit 5).
+ * 
+ * Field Access Macros:
+ * 
+ */
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_INDWR_INDCNT register field. */
+#define ALT_QSPI_INDWR_INDCNT_LSB        6
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_INDWR_INDCNT register field. */
+#define ALT_QSPI_INDWR_INDCNT_MSB        7
+/* The width in bits of the ALT_QSPI_INDWR_INDCNT register field. */
+#define ALT_QSPI_INDWR_INDCNT_WIDTH      2
+/* The mask used to set the ALT_QSPI_INDWR_INDCNT register field value. */
+#define ALT_QSPI_INDWR_INDCNT_SET_MSK    0x000000c0
+/* The mask used to clear the ALT_QSPI_INDWR_INDCNT register field value. */
+#define ALT_QSPI_INDWR_INDCNT_CLR_MSK    0xffffff3f
+/* The reset value of the ALT_QSPI_INDWR_INDCNT register field is UNKNOWN. */
+#define ALT_QSPI_INDWR_INDCNT_RESET      0x0
+/* Extracts the ALT_QSPI_INDWR_INDCNT field value from a register. */
+#define ALT_QSPI_INDWR_INDCNT_GET(value) (((value) & 0x000000c0) >> 6)
+/* Produces a ALT_QSPI_INDWR_INDCNT register field value suitable for setting the register. */
+#define ALT_QSPI_INDWR_INDCNT_SET(value) (((value) << 6) & 0x000000c0)
+
+#ifndef __ASSEMBLY__
+/*
+ * WARNING: The C register and register group struct declarations are provided for
+ * convenience and illustrative purposes. They should, however, be used with
+ * caution as the C language standard provides no guarantees about the alignment or
+ * atomicity of device memory accesses. The recommended practice for writing
+ * hardware drivers is to use the SoCAL access macros and alt_read_word() and
+ * alt_write_word() functions.
+ * 
+ * The struct declaration for register ALT_QSPI_INDWR.
+ */
+struct ALT_QSPI_INDWR_s
+{
+    uint32_t        start    :  1;  /* Start Indirect Write */
+    uint32_t        cancel   :  1;  /* Cancel Indirect Write */
+    const uint32_t  rdstat   :  1;  /* Indirect Write Status */
+    const uint32_t  sramfull :  1;  /* Reserved */
+    const uint32_t  rdqueued :  1;  /* Queued Indirect Write Operations */
+    uint32_t        inddone  :  1;  /* Indirect Completion Status */
+    const uint32_t  indcnt   :  2;  /* Completed Indirect Operations */
+    uint32_t                 : 24;  /* *UNDEFINED* */
+};
+
+/* The typedef declaration for register ALT_QSPI_INDWR. */
+typedef volatile struct ALT_QSPI_INDWR_s  ALT_QSPI_INDWR_t;
+#endif  /* __ASSEMBLY__ */
+
+/* The byte offset of the ALT_QSPI_INDWR register from the beginning of the component. */
+#define ALT_QSPI_INDWR_OFST        0x70
+
+/*
+ * Register : Indirect Write Transfer Watermark Register - indwrwater
+ * 
+ * Register Layout
+ * 
+ *  Bits   | Access | Reset      | Description    
+ * :-------|:-------|:-----------|:----------------
+ *  [31:0] | RW     | 0xffffffff | Watermark Value
+ * 
+ */
+/*
+ * Field : Watermark Value - level
+ * 
+ * This represents the maximum fill level of the SRAM before a DMA peripheral
+ * access is permitted. When the SRAM fill level falls below the watermark, an
+ * interrupt is also generated. This field can be disabled by writing a value of
+ * all ones. The units of this register are bytes.
+ * 
+ * Field Access Macros:
+ * 
+ */
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_INDWRWATER_LEVEL register field. */
+#define ALT_QSPI_INDWRWATER_LEVEL_LSB        0
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_INDWRWATER_LEVEL register field. */
+#define ALT_QSPI_INDWRWATER_LEVEL_MSB        31
+/* The width in bits of the ALT_QSPI_INDWRWATER_LEVEL register field. */
+#define ALT_QSPI_INDWRWATER_LEVEL_WIDTH      32
+/* The mask used to set the ALT_QSPI_INDWRWATER_LEVEL register field value. */
+#define ALT_QSPI_INDWRWATER_LEVEL_SET_MSK    0xffffffff
+/* The mask used to clear the ALT_QSPI_INDWRWATER_LEVEL register field value. */
+#define ALT_QSPI_INDWRWATER_LEVEL_CLR_MSK    0x00000000
+/* The reset value of the ALT_QSPI_INDWRWATER_LEVEL register field. */
+#define ALT_QSPI_INDWRWATER_LEVEL_RESET      0xffffffff
+/* Extracts the ALT_QSPI_INDWRWATER_LEVEL field value from a register. */
+#define ALT_QSPI_INDWRWATER_LEVEL_GET(value) (((value) & 0xffffffff) >> 0)
+/* Produces a ALT_QSPI_INDWRWATER_LEVEL register field value suitable for setting the register. */
+#define ALT_QSPI_INDWRWATER_LEVEL_SET(value) (((value) << 0) & 0xffffffff)
+
+#ifndef __ASSEMBLY__
+/*
+ * WARNING: The C register and register group struct declarations are provided for
+ * convenience and illustrative purposes. They should, however, be used with
+ * caution as the C language standard provides no guarantees about the alignment or
+ * atomicity of device memory accesses. The recommended practice for writing
+ * hardware drivers is to use the SoCAL access macros and alt_read_word() and
+ * alt_write_word() functions.
+ * 
+ * The struct declaration for register ALT_QSPI_INDWRWATER.
+ */
+struct ALT_QSPI_INDWRWATER_s
+{
+    uint32_t  level : 32;  /* Watermark Value */
+};
+
+/* The typedef declaration for register ALT_QSPI_INDWRWATER. */
+typedef volatile struct ALT_QSPI_INDWRWATER_s  ALT_QSPI_INDWRWATER_t;
+#endif  /* __ASSEMBLY__ */
+
+/* The byte offset of the ALT_QSPI_INDWRWATER register from the beginning of the component. */
+#define ALT_QSPI_INDWRWATER_OFST        0x74
+
+/*
+ * Register : Indirect Write Transfer Start Address Register - indwrstaddr
+ * 
+ * Register Layout
+ * 
+ *  Bits   | Access | Reset | Description             
+ * :-------|:-------|:------|:-------------------------
+ *  [31:0] | RW     | 0x0   | Start of Indirect Access
+ * 
+ */
+/*
+ * Field : Start of Indirect Access - addr
+ * 
+ * This is the start address from which the indirect access will commence its write
+ * operation.
+ * 
+ * Field Access Macros:
+ * 
+ */
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_INDWRSTADDR_ADDR register field. */
+#define ALT_QSPI_INDWRSTADDR_ADDR_LSB        0
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_INDWRSTADDR_ADDR register field. */
+#define ALT_QSPI_INDWRSTADDR_ADDR_MSB        31
+/* The width in bits of the ALT_QSPI_INDWRSTADDR_ADDR register field. */
+#define ALT_QSPI_INDWRSTADDR_ADDR_WIDTH      32
+/* The mask used to set the ALT_QSPI_INDWRSTADDR_ADDR register field value. */
+#define ALT_QSPI_INDWRSTADDR_ADDR_SET_MSK    0xffffffff
+/* The mask used to clear the ALT_QSPI_INDWRSTADDR_ADDR register field value. */
+#define ALT_QSPI_INDWRSTADDR_ADDR_CLR_MSK    0x00000000
+/* The reset value of the ALT_QSPI_INDWRSTADDR_ADDR register field. */
+#define ALT_QSPI_INDWRSTADDR_ADDR_RESET      0x0
+/* Extracts the ALT_QSPI_INDWRSTADDR_ADDR field value from a register. */
+#define ALT_QSPI_INDWRSTADDR_ADDR_GET(value) (((value) & 0xffffffff) >> 0)
+/* Produces a ALT_QSPI_INDWRSTADDR_ADDR register field value suitable for setting the register. */
+#define ALT_QSPI_INDWRSTADDR_ADDR_SET(value) (((value) << 0) & 0xffffffff)
+
+#ifndef __ASSEMBLY__
+/*
+ * WARNING: The C register and register group struct declarations are provided for
+ * convenience and illustrative purposes. They should, however, be used with
+ * caution as the C language standard provides no guarantees about the alignment or
+ * atomicity of device memory accesses. The recommended practice for writing
+ * hardware drivers is to use the SoCAL access macros and alt_read_word() and
+ * alt_write_word() functions.
+ * 
+ * The struct declaration for register ALT_QSPI_INDWRSTADDR.
+ */
+struct ALT_QSPI_INDWRSTADDR_s
+{
+    uint32_t  addr : 32;  /* Start of Indirect Access */
+};
+
+/* The typedef declaration for register ALT_QSPI_INDWRSTADDR. */
+typedef volatile struct ALT_QSPI_INDWRSTADDR_s  ALT_QSPI_INDWRSTADDR_t;
+#endif  /* __ASSEMBLY__ */
+
+/* The byte offset of the ALT_QSPI_INDWRSTADDR register from the beginning of the component. */
+#define ALT_QSPI_INDWRSTADDR_OFST        0x78
+
+/*
+ * Register : Indirect Write Transfer Count Register - indwrcnt
+ * 
+ * Register Layout
+ * 
+ *  Bits   | Access | Reset | Description             
+ * :-------|:-------|:------|:-------------------------
+ *  [31:0] | RW     | 0x0   | Indirect Number of Bytes
+ * 
+ */
+/*
+ * Field : Indirect Number of Bytes - value
+ * 
+ * This is the number of bytes that the indirect access will consume. This can be
+ * bigger than the configured size of SRAM.
+ * 
+ * Field Access Macros:
+ * 
+ */
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_INDWRCNT_VALUE register field. */
+#define ALT_QSPI_INDWRCNT_VALUE_LSB        0
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_INDWRCNT_VALUE register field. */
+#define ALT_QSPI_INDWRCNT_VALUE_MSB        31
+/* The width in bits of the ALT_QSPI_INDWRCNT_VALUE register field. */
+#define ALT_QSPI_INDWRCNT_VALUE_WIDTH      32
+/* The mask used to set the ALT_QSPI_INDWRCNT_VALUE register field value. */
+#define ALT_QSPI_INDWRCNT_VALUE_SET_MSK    0xffffffff
+/* The mask used to clear the ALT_QSPI_INDWRCNT_VALUE register field value. */
+#define ALT_QSPI_INDWRCNT_VALUE_CLR_MSK    0x00000000
+/* The reset value of the ALT_QSPI_INDWRCNT_VALUE register field. */
+#define ALT_QSPI_INDWRCNT_VALUE_RESET      0x0
+/* Extracts the ALT_QSPI_INDWRCNT_VALUE field value from a register. */
+#define ALT_QSPI_INDWRCNT_VALUE_GET(value) (((value) & 0xffffffff) >> 0)
+/* Produces a ALT_QSPI_INDWRCNT_VALUE register field value suitable for setting the register. */
+#define ALT_QSPI_INDWRCNT_VALUE_SET(value) (((value) << 0) & 0xffffffff)
+
+#ifndef __ASSEMBLY__
+/*
+ * WARNING: The C register and register group struct declarations are provided for
+ * convenience and illustrative purposes. They should, however, be used with
+ * caution as the C language standard provides no guarantees about the alignment or
+ * atomicity of device memory accesses. The recommended practice for writing
+ * hardware drivers is to use the SoCAL access macros and alt_read_word() and
+ * alt_write_word() functions.
+ * 
+ * The struct declaration for register ALT_QSPI_INDWRCNT.
+ */
+struct ALT_QSPI_INDWRCNT_s
+{
+    uint32_t  value : 32;  /* Indirect Number of Bytes */
+};
+
+/* The typedef declaration for register ALT_QSPI_INDWRCNT. */
+typedef volatile struct ALT_QSPI_INDWRCNT_s  ALT_QSPI_INDWRCNT_t;
+#endif  /* __ASSEMBLY__ */
+
+/* The byte offset of the ALT_QSPI_INDWRCNT register from the beginning of the component. */
+#define ALT_QSPI_INDWRCNT_OFST        0x7c
+
+/*
+ * Register : Flash Command Register - flashcmd
+ * 
+ * Register Layout
+ * 
+ *  Bits    | Access | Reset | Description               
+ * :--------|:-------|:------|:---------------------------
+ *  [0]     | RW     | 0x0   | Execute Command           
+ *  [1]     | R      | 0x0   | Command Execution Status  
+ *  [6:2]   | ???    | 0x0   | *UNDEFINED*               
+ *  [11:7]  | RW     | 0x0   | Number of Dummy Bytes     
+ *  [14:12] | RW     | 0x0   | Number of Write Data Bytes
+ *  [15]    | RW     | 0x0   | Write Data Enable         
+ *  [17:16] | RW     | 0x0   | Number of Address Bytes   
+ *  [18]    | RW     | 0x0   | Mode Bit Enable           
+ *  [19]    | RW     | 0x0   | Command Address Enable    
+ *  [22:20] | RW     | 0x0   | Number of Read Data Bytes 
+ *  [23]    | RW     | 0x0   | Read Data Enable          
+ *  [31:24] | RW     | 0x0   | Command Opcode            
+ * 
+ */
+/*
+ * Field : Execute Command - execcmd
+ * 
+ * Execute the command.
+ * 
+ * Field Enumeration Values:
+ * 
+ *  Enum                                | Value | Description    
+ * :------------------------------------|:------|:----------------
+ *  ALT_QSPI_FLSHCMD_EXECCMD_E_EXECUTE  | 0x1   | Execute Command
+ *  ALT_QSPI_FLSHCMD_EXECCMD_E_NOACTION | 0x0   | No Action      
+ * 
+ * Field Access Macros:
+ * 
+ */
+/*
+ * Enumerated value for register field ALT_QSPI_FLSHCMD_EXECCMD
+ * 
+ * Execute Command
+ */
+#define ALT_QSPI_FLSHCMD_EXECCMD_E_EXECUTE  0x1
+/*
+ * Enumerated value for register field ALT_QSPI_FLSHCMD_EXECCMD
+ * 
+ * No Action
+ */
+#define ALT_QSPI_FLSHCMD_EXECCMD_E_NOACTION 0x0
+
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_FLSHCMD_EXECCMD register field. */
+#define ALT_QSPI_FLSHCMD_EXECCMD_LSB        0
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_FLSHCMD_EXECCMD register field. */
+#define ALT_QSPI_FLSHCMD_EXECCMD_MSB        0
+/* The width in bits of the ALT_QSPI_FLSHCMD_EXECCMD register field. */
+#define ALT_QSPI_FLSHCMD_EXECCMD_WIDTH      1
+/* The mask used to set the ALT_QSPI_FLSHCMD_EXECCMD register field value. */
+#define ALT_QSPI_FLSHCMD_EXECCMD_SET_MSK    0x00000001
+/* The mask used to clear the ALT_QSPI_FLSHCMD_EXECCMD register field value. */
+#define ALT_QSPI_FLSHCMD_EXECCMD_CLR_MSK    0xfffffffe
+/* The reset value of the ALT_QSPI_FLSHCMD_EXECCMD register field. */
+#define ALT_QSPI_FLSHCMD_EXECCMD_RESET      0x0
+/* Extracts the ALT_QSPI_FLSHCMD_EXECCMD field value from a register. */
+#define ALT_QSPI_FLSHCMD_EXECCMD_GET(value) (((value) & 0x00000001) >> 0)
+/* Produces a ALT_QSPI_FLSHCMD_EXECCMD register field value suitable for setting the register. */
+#define ALT_QSPI_FLSHCMD_EXECCMD_SET(value) (((value) << 0) & 0x00000001)
+
+/*
+ * Field : Command Execution Status - cmdexecstat
+ * 
+ * Command execution in progress.
+ * 
+ * Field Enumeration Values:
+ * 
+ *  Enum                                       | Value | Description             
+ * :-------------------------------------------|:------|:-------------------------
+ *  ALT_QSPI_FLSHCMD_CMDEXECSTAT_E_EXECUTESTAT | 0x1   | Command Execution Status
+ *  ALT_QSPI_FLSHCMD_CMDEXECSTAT_E_NOACTION    | 0x0   | No Action               
+ * 
+ * Field Access Macros:
+ * 
+ */
+/*
+ * Enumerated value for register field ALT_QSPI_FLSHCMD_CMDEXECSTAT
+ * 
+ * Command Execution Status
+ */
+#define ALT_QSPI_FLSHCMD_CMDEXECSTAT_E_EXECUTESTAT  0x1
+/*
+ * Enumerated value for register field ALT_QSPI_FLSHCMD_CMDEXECSTAT
+ * 
+ * No Action
+ */
+#define ALT_QSPI_FLSHCMD_CMDEXECSTAT_E_NOACTION     0x0
+
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_FLSHCMD_CMDEXECSTAT register field. */
+#define ALT_QSPI_FLSHCMD_CMDEXECSTAT_LSB        1
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_FLSHCMD_CMDEXECSTAT register field. */
+#define ALT_QSPI_FLSHCMD_CMDEXECSTAT_MSB        1
+/* The width in bits of the ALT_QSPI_FLSHCMD_CMDEXECSTAT register field. */
+#define ALT_QSPI_FLSHCMD_CMDEXECSTAT_WIDTH      1
+/* The mask used to set the ALT_QSPI_FLSHCMD_CMDEXECSTAT register field value. */
+#define ALT_QSPI_FLSHCMD_CMDEXECSTAT_SET_MSK    0x00000002
+/* The mask used to clear the ALT_QSPI_FLSHCMD_CMDEXECSTAT register field value. */
+#define ALT_QSPI_FLSHCMD_CMDEXECSTAT_CLR_MSK    0xfffffffd
+/* The reset value of the ALT_QSPI_FLSHCMD_CMDEXECSTAT register field. */
+#define ALT_QSPI_FLSHCMD_CMDEXECSTAT_RESET      0x0
+/* Extracts the ALT_QSPI_FLSHCMD_CMDEXECSTAT field value from a register. */
+#define ALT_QSPI_FLSHCMD_CMDEXECSTAT_GET(value) (((value) & 0x00000002) >> 1)
+/* Produces a ALT_QSPI_FLSHCMD_CMDEXECSTAT register field value suitable for setting the register. */
+#define ALT_QSPI_FLSHCMD_CMDEXECSTAT_SET(value) (((value) << 1) & 0x00000002)
+
+/*
+ * Field : Number of Dummy Bytes - numdummybytes
+ * 
+ * Set to the number of dummy bytes required This should be setup before triggering
+ * the command via the execute field of this register.
+ * 
+ * Field Access Macros:
+ * 
+ */
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_FLSHCMD_NUMDUMMYBYTES register field. */
+#define ALT_QSPI_FLSHCMD_NUMDUMMYBYTES_LSB        7
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_FLSHCMD_NUMDUMMYBYTES register field. */
+#define ALT_QSPI_FLSHCMD_NUMDUMMYBYTES_MSB        11
+/* The width in bits of the ALT_QSPI_FLSHCMD_NUMDUMMYBYTES register field. */
+#define ALT_QSPI_FLSHCMD_NUMDUMMYBYTES_WIDTH      5
+/* The mask used to set the ALT_QSPI_FLSHCMD_NUMDUMMYBYTES register field value. */
+#define ALT_QSPI_FLSHCMD_NUMDUMMYBYTES_SET_MSK    0x00000f80
+/* The mask used to clear the ALT_QSPI_FLSHCMD_NUMDUMMYBYTES register field value. */
+#define ALT_QSPI_FLSHCMD_NUMDUMMYBYTES_CLR_MSK    0xfffff07f
+/* The reset value of the ALT_QSPI_FLSHCMD_NUMDUMMYBYTES register field. */
+#define ALT_QSPI_FLSHCMD_NUMDUMMYBYTES_RESET      0x0
+/* Extracts the ALT_QSPI_FLSHCMD_NUMDUMMYBYTES field value from a register. */
+#define ALT_QSPI_FLSHCMD_NUMDUMMYBYTES_GET(value) (((value) & 0x00000f80) >> 7)
+/* Produces a ALT_QSPI_FLSHCMD_NUMDUMMYBYTES register field value suitable for setting the register. */
+#define ALT_QSPI_FLSHCMD_NUMDUMMYBYTES_SET(value) (((value) << 7) & 0x00000f80)
+
+/*
+ * Field : Number of Write Data Bytes - numwrdatabytes
+ * 
+ * Up to 8 Data bytes may be written using this command.
+ * 
+ * Field Enumeration Values:
+ * 
+ *  Enum                                      | Value | Description 
+ * :------------------------------------------|:------|:-------------
+ *  ALT_QSPI_FLSHCMD_NUMWRDATABYTES_E_WRBYTE1 | 0x0   | Write 1 Byte
+ *  ALT_QSPI_FLSHCMD_NUMWRDATABYTES_E_WRBYTE2 | 0x1   | Write 2 Byte
+ *  ALT_QSPI_FLSHCMD_NUMWRDATABYTES_E_WRBYTE3 | 0x2   | Write 3 Byte
+ *  ALT_QSPI_FLSHCMD_NUMWRDATABYTES_E_WRBYTE4 | 0x3   | Write 4 Byte
+ *  ALT_QSPI_FLSHCMD_NUMWRDATABYTES_E_WRBYTE5 | 0x4   | Write 5 Byte
+ *  ALT_QSPI_FLSHCMD_NUMWRDATABYTES_E_WRBYTE6 | 0x5   | Write 6 Byte
+ *  ALT_QSPI_FLSHCMD_NUMWRDATABYTES_E_WRBYTE7 | 0x6   | Write 7 Byte
+ *  ALT_QSPI_FLSHCMD_NUMWRDATABYTES_E_WRBYTE8 | 0x7   | Write 8 Byte
+ * 
+ * Field Access Macros:
+ * 
+ */
+/*
+ * Enumerated value for register field ALT_QSPI_FLSHCMD_NUMWRDATABYTES
+ * 
+ * Write 1 Byte
+ */
+#define ALT_QSPI_FLSHCMD_NUMWRDATABYTES_E_WRBYTE1   0x0
+/*
+ * Enumerated value for register field ALT_QSPI_FLSHCMD_NUMWRDATABYTES
+ * 
+ * Write 2 Byte
+ */
+#define ALT_QSPI_FLSHCMD_NUMWRDATABYTES_E_WRBYTE2   0x1
+/*
+ * Enumerated value for register field ALT_QSPI_FLSHCMD_NUMWRDATABYTES
+ * 
+ * Write 3 Byte
+ */
+#define ALT_QSPI_FLSHCMD_NUMWRDATABYTES_E_WRBYTE3   0x2
+/*
+ * Enumerated value for register field ALT_QSPI_FLSHCMD_NUMWRDATABYTES
+ * 
+ * Write 4 Byte
+ */
+#define ALT_QSPI_FLSHCMD_NUMWRDATABYTES_E_WRBYTE4   0x3
+/*
+ * Enumerated value for register field ALT_QSPI_FLSHCMD_NUMWRDATABYTES
+ * 
+ * Write 5 Byte
+ */
+#define ALT_QSPI_FLSHCMD_NUMWRDATABYTES_E_WRBYTE5   0x4
+/*
+ * Enumerated value for register field ALT_QSPI_FLSHCMD_NUMWRDATABYTES
+ * 
+ * Write 6 Byte
+ */
+#define ALT_QSPI_FLSHCMD_NUMWRDATABYTES_E_WRBYTE6   0x5
+/*
+ * Enumerated value for register field ALT_QSPI_FLSHCMD_NUMWRDATABYTES
+ * 
+ * Write 7 Byte
+ */
+#define ALT_QSPI_FLSHCMD_NUMWRDATABYTES_E_WRBYTE7   0x6
+/*
+ * Enumerated value for register field ALT_QSPI_FLSHCMD_NUMWRDATABYTES
+ * 
+ * Write 8 Byte
+ */
+#define ALT_QSPI_FLSHCMD_NUMWRDATABYTES_E_WRBYTE8   0x7
+
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_FLSHCMD_NUMWRDATABYTES register field. */
+#define ALT_QSPI_FLSHCMD_NUMWRDATABYTES_LSB        12
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_FLSHCMD_NUMWRDATABYTES register field. */
+#define ALT_QSPI_FLSHCMD_NUMWRDATABYTES_MSB        14
+/* The width in bits of the ALT_QSPI_FLSHCMD_NUMWRDATABYTES register field. */
+#define ALT_QSPI_FLSHCMD_NUMWRDATABYTES_WIDTH      3
+/* The mask used to set the ALT_QSPI_FLSHCMD_NUMWRDATABYTES register field value. */
+#define ALT_QSPI_FLSHCMD_NUMWRDATABYTES_SET_MSK    0x00007000
+/* The mask used to clear the ALT_QSPI_FLSHCMD_NUMWRDATABYTES register field value. */
+#define ALT_QSPI_FLSHCMD_NUMWRDATABYTES_CLR_MSK    0xffff8fff
+/* The reset value of the ALT_QSPI_FLSHCMD_NUMWRDATABYTES register field. */
+#define ALT_QSPI_FLSHCMD_NUMWRDATABYTES_RESET      0x0
+/* Extracts the ALT_QSPI_FLSHCMD_NUMWRDATABYTES field value from a register. */
+#define ALT_QSPI_FLSHCMD_NUMWRDATABYTES_GET(value) (((value) & 0x00007000) >> 12)
+/* Produces a ALT_QSPI_FLSHCMD_NUMWRDATABYTES register field value suitable for setting the register. */
+#define ALT_QSPI_FLSHCMD_NUMWRDATABYTES_SET(value) (((value) << 12) & 0x00007000)
+
+/*
+ * Field : Write Data Enable - enwrdata
+ * 
+ * Set to 1 if the command specified in the command opcode field requires write
+ * data bytes to be sent to the device.
+ * 
+ * Field Enumeration Values:
+ * 
+ *  Enum                                    | Value | Description                      
+ * :----------------------------------------|:------|:----------------------------------
+ *  ALT_QSPI_FLSHCMD_ENWRDATA_E_WRDATABYTES | 0x1   | Command requires write data bytes
+ *  ALT_QSPI_FLSHCMD_ENWRDATA_E_NOACTION    | 0x0   | No Action                        
+ * 
+ * Field Access Macros:
+ * 
+ */
+/*
+ * Enumerated value for register field ALT_QSPI_FLSHCMD_ENWRDATA
+ * 
+ * Command requires write data bytes
+ */
+#define ALT_QSPI_FLSHCMD_ENWRDATA_E_WRDATABYTES 0x1
+/*
+ * Enumerated value for register field ALT_QSPI_FLSHCMD_ENWRDATA
+ * 
+ * No Action
+ */
+#define ALT_QSPI_FLSHCMD_ENWRDATA_E_NOACTION    0x0
+
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_FLSHCMD_ENWRDATA register field. */
+#define ALT_QSPI_FLSHCMD_ENWRDATA_LSB        15
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_FLSHCMD_ENWRDATA register field. */
+#define ALT_QSPI_FLSHCMD_ENWRDATA_MSB        15
+/* The width in bits of the ALT_QSPI_FLSHCMD_ENWRDATA register field. */
+#define ALT_QSPI_FLSHCMD_ENWRDATA_WIDTH      1
+/* The mask used to set the ALT_QSPI_FLSHCMD_ENWRDATA register field value. */
+#define ALT_QSPI_FLSHCMD_ENWRDATA_SET_MSK    0x00008000
+/* The mask used to clear the ALT_QSPI_FLSHCMD_ENWRDATA register field value. */
+#define ALT_QSPI_FLSHCMD_ENWRDATA_CLR_MSK    0xffff7fff
+/* The reset value of the ALT_QSPI_FLSHCMD_ENWRDATA register field. */
+#define ALT_QSPI_FLSHCMD_ENWRDATA_RESET      0x0
+/* Extracts the ALT_QSPI_FLSHCMD_ENWRDATA field value from a register. */
+#define ALT_QSPI_FLSHCMD_ENWRDATA_GET(value) (((value) & 0x00008000) >> 15)
+/* Produces a ALT_QSPI_FLSHCMD_ENWRDATA register field value suitable for setting the register. */
+#define ALT_QSPI_FLSHCMD_ENWRDATA_SET(value) (((value) << 15) & 0x00008000)
+
+/*
+ * Field : Number of Address Bytes - numaddrbytes
+ * 
+ * Set to the number of address bytes required (the address itself is programmed in
+ * the FLASH COMMAND ADDRESS REGISTERS). This should be setup before triggering the
+ * command via bit 0 of this register. 2'b00 : 1 address byte 2'b01 : 2 address
+ * bytes 2'b10 : 3 address bytes 2'b11 : 4 address bytes
+ * 
+ * Field Enumeration Values:
+ * 
+ *  Enum                                      | Value | Description          
+ * :------------------------------------------|:------|:----------------------
+ *  ALT_QSPI_FLSHCMD_NUMADDRBYTES_E_ADDRBYTE1 | 0x0   | Write 1 Address Byte 
+ *  ALT_QSPI_FLSHCMD_NUMADDRBYTES_E_ADDRBYTE2 | 0x1   | Write 2 Address Bytes
+ *  ALT_QSPI_FLSHCMD_NUMADDRBYTES_E_ADDRBYTE3 | 0x2   | Write 3 Address Bytes
+ *  ALT_QSPI_FLSHCMD_NUMADDRBYTES_E_ADDRBYTE4 | 0x3   | Write 4 Address Bytes
+ * 
+ * Field Access Macros:
+ * 
+ */
+/*
+ * Enumerated value for register field ALT_QSPI_FLSHCMD_NUMADDRBYTES
+ * 
+ * Write 1 Address Byte
+ */
+#define ALT_QSPI_FLSHCMD_NUMADDRBYTES_E_ADDRBYTE1   0x0
+/*
+ * Enumerated value for register field ALT_QSPI_FLSHCMD_NUMADDRBYTES
+ * 
+ * Write 2 Address Bytes
+ */
+#define ALT_QSPI_FLSHCMD_NUMADDRBYTES_E_ADDRBYTE2   0x1
+/*
+ * Enumerated value for register field ALT_QSPI_FLSHCMD_NUMADDRBYTES
+ * 
+ * Write 3 Address Bytes
+ */
+#define ALT_QSPI_FLSHCMD_NUMADDRBYTES_E_ADDRBYTE3   0x2
+/*
+ * Enumerated value for register field ALT_QSPI_FLSHCMD_NUMADDRBYTES
+ * 
+ * Write 4 Address Bytes
+ */
+#define ALT_QSPI_FLSHCMD_NUMADDRBYTES_E_ADDRBYTE4   0x3
+
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_FLSHCMD_NUMADDRBYTES register field. */
+#define ALT_QSPI_FLSHCMD_NUMADDRBYTES_LSB        16
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_FLSHCMD_NUMADDRBYTES register field. */
+#define ALT_QSPI_FLSHCMD_NUMADDRBYTES_MSB        17
+/* The width in bits of the ALT_QSPI_FLSHCMD_NUMADDRBYTES register field. */
+#define ALT_QSPI_FLSHCMD_NUMADDRBYTES_WIDTH      2
+/* The mask used to set the ALT_QSPI_FLSHCMD_NUMADDRBYTES register field value. */
+#define ALT_QSPI_FLSHCMD_NUMADDRBYTES_SET_MSK    0x00030000
+/* The mask used to clear the ALT_QSPI_FLSHCMD_NUMADDRBYTES register field value. */
+#define ALT_QSPI_FLSHCMD_NUMADDRBYTES_CLR_MSK    0xfffcffff
+/* The reset value of the ALT_QSPI_FLSHCMD_NUMADDRBYTES register field. */
+#define ALT_QSPI_FLSHCMD_NUMADDRBYTES_RESET      0x0
+/* Extracts the ALT_QSPI_FLSHCMD_NUMADDRBYTES field value from a register. */
+#define ALT_QSPI_FLSHCMD_NUMADDRBYTES_GET(value) (((value) & 0x00030000) >> 16)
+/* Produces a ALT_QSPI_FLSHCMD_NUMADDRBYTES register field value suitable for setting the register. */
+#define ALT_QSPI_FLSHCMD_NUMADDRBYTES_SET(value) (((value) << 16) & 0x00030000)
+
+/*
+ * Field : Mode Bit Enable - enmodebit
+ * 
+ * Set to 1 to ensure the mode bits as defined in the Mode Bit Configuration
+ * register are sent following the address bytes.
+ * 
+ * Field Enumeration Values:
+ * 
+ *  Enum                             | Value | Description                   
+ * :---------------------------------|:------|:-------------------------------
+ *  ALT_QSPI_FLSHCMD_ENMODBIT_E_END  | 0x1   | Mode Bit follows address bytes
+ *  ALT_QSPI_FLSHCMD_ENMODBIT_E_DISD | 0x0   | No Action                     
+ * 
+ * Field Access Macros:
+ * 
+ */
+/*
+ * Enumerated value for register field ALT_QSPI_FLSHCMD_ENMODBIT
+ * 
+ * Mode Bit follows address bytes
+ */
+#define ALT_QSPI_FLSHCMD_ENMODBIT_E_END     0x1
+/*
+ * Enumerated value for register field ALT_QSPI_FLSHCMD_ENMODBIT
+ * 
+ * No Action
+ */
+#define ALT_QSPI_FLSHCMD_ENMODBIT_E_DISD    0x0
+
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_FLSHCMD_ENMODBIT register field. */
+#define ALT_QSPI_FLSHCMD_ENMODBIT_LSB        18
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_FLSHCMD_ENMODBIT register field. */
+#define ALT_QSPI_FLSHCMD_ENMODBIT_MSB        18
+/* The width in bits of the ALT_QSPI_FLSHCMD_ENMODBIT register field. */
+#define ALT_QSPI_FLSHCMD_ENMODBIT_WIDTH      1
+/* The mask used to set the ALT_QSPI_FLSHCMD_ENMODBIT register field value. */
+#define ALT_QSPI_FLSHCMD_ENMODBIT_SET_MSK    0x00040000
+/* The mask used to clear the ALT_QSPI_FLSHCMD_ENMODBIT register field value. */
+#define ALT_QSPI_FLSHCMD_ENMODBIT_CLR_MSK    0xfffbffff
+/* The reset value of the ALT_QSPI_FLSHCMD_ENMODBIT register field. */
+#define ALT_QSPI_FLSHCMD_ENMODBIT_RESET      0x0
+/* Extracts the ALT_QSPI_FLSHCMD_ENMODBIT field value from a register. */
+#define ALT_QSPI_FLSHCMD_ENMODBIT_GET(value) (((value) & 0x00040000) >> 18)
+/* Produces a ALT_QSPI_FLSHCMD_ENMODBIT register field value suitable for setting the register. */
+#define ALT_QSPI_FLSHCMD_ENMODBIT_SET(value) (((value) << 18) & 0x00040000)
+
+/*
+ * Field : Command Address Enable - encmdaddr
+ * 
+ * If enabled, the command specified in bits 31:24 requires an address. This should
+ * be setup before triggering the command via writing a 1 to the execute field.
+ * 
+ * Field Enumeration Values:
+ * 
+ *  Enum                              | Value | Description                           
+ * :----------------------------------|:------|:---------------------------------------
+ *  ALT_QSPI_FLSHCMD_ENCMDADDR_E_END  | 0x1   | Command in bits 31:24 requires address
+ *  ALT_QSPI_FLSHCMD_ENCMDADDR_E_DISD | 0x0   | No Action                             
+ * 
+ * Field Access Macros:
+ * 
+ */
+/*
+ * Enumerated value for register field ALT_QSPI_FLSHCMD_ENCMDADDR
+ * 
+ * Command in bits 31:24 requires address
+ */
+#define ALT_QSPI_FLSHCMD_ENCMDADDR_E_END    0x1
+/*
+ * Enumerated value for register field ALT_QSPI_FLSHCMD_ENCMDADDR
+ * 
+ * No Action
+ */
+#define ALT_QSPI_FLSHCMD_ENCMDADDR_E_DISD   0x0
+
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_FLSHCMD_ENCMDADDR register field. */
+#define ALT_QSPI_FLSHCMD_ENCMDADDR_LSB        19
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_FLSHCMD_ENCMDADDR register field. */
+#define ALT_QSPI_FLSHCMD_ENCMDADDR_MSB        19
+/* The width in bits of the ALT_QSPI_FLSHCMD_ENCMDADDR register field. */
+#define ALT_QSPI_FLSHCMD_ENCMDADDR_WIDTH      1
+/* The mask used to set the ALT_QSPI_FLSHCMD_ENCMDADDR register field value. */
+#define ALT_QSPI_FLSHCMD_ENCMDADDR_SET_MSK    0x00080000
+/* The mask used to clear the ALT_QSPI_FLSHCMD_ENCMDADDR register field value. */
+#define ALT_QSPI_FLSHCMD_ENCMDADDR_CLR_MSK    0xfff7ffff
+/* The reset value of the ALT_QSPI_FLSHCMD_ENCMDADDR register field. */
+#define ALT_QSPI_FLSHCMD_ENCMDADDR_RESET      0x0
+/* Extracts the ALT_QSPI_FLSHCMD_ENCMDADDR field value from a register. */
+#define ALT_QSPI_FLSHCMD_ENCMDADDR_GET(value) (((value) & 0x00080000) >> 19)
+/* Produces a ALT_QSPI_FLSHCMD_ENCMDADDR register field value suitable for setting the register. */
+#define ALT_QSPI_FLSHCMD_ENCMDADDR_SET(value) (((value) << 19) & 0x00080000)
+
+/*
+ * Field : Number of Read Data Bytes - numrddatabytes
+ * 
+ * Up to 8 data bytes may be read using this command. Set to 0 for 1 byte and 7 for
+ * 8 bytes.
+ * 
+ * Field Enumeration Values:
+ * 
+ *  Enum                                      | Value | Description
+ * :------------------------------------------|:------|:------------
+ *  ALT_QSPI_FLSHCMD_NUMRDDATABYTES_E_RDBYTE1 | 0x0   | Read 1 Byte
+ *  ALT_QSPI_FLSHCMD_NUMRDDATABYTES_E_RDBYTE2 | 0x1   | Read 2 Byte
+ *  ALT_QSPI_FLSHCMD_NUMRDDATABYTES_E_RDBYTE3 | 0x2   | Read 3 Byte
+ *  ALT_QSPI_FLSHCMD_NUMRDDATABYTES_E_RDBYTE4 | 0x3   | Read 4 Byte
+ *  ALT_QSPI_FLSHCMD_NUMRDDATABYTES_E_RDBYTE5 | 0x4   | Read 5 Byte
+ *  ALT_QSPI_FLSHCMD_NUMRDDATABYTES_E_RDBYTE6 | 0x5   | Read 6 Byte
+ *  ALT_QSPI_FLSHCMD_NUMRDDATABYTES_E_RDBYTE7 | 0x6   | Read 7 Byte
+ *  ALT_QSPI_FLSHCMD_NUMRDDATABYTES_E_RDBYTE8 | 0x7   | Read 8 Byte
+ * 
+ * Field Access Macros:
+ * 
+ */
+/*
+ * Enumerated value for register field ALT_QSPI_FLSHCMD_NUMRDDATABYTES
+ * 
+ * Read 1 Byte
+ */
+#define ALT_QSPI_FLSHCMD_NUMRDDATABYTES_E_RDBYTE1   0x0
+/*
+ * Enumerated value for register field ALT_QSPI_FLSHCMD_NUMRDDATABYTES
+ * 
+ * Read 2 Byte
+ */
+#define ALT_QSPI_FLSHCMD_NUMRDDATABYTES_E_RDBYTE2   0x1
+/*
+ * Enumerated value for register field ALT_QSPI_FLSHCMD_NUMRDDATABYTES
+ * 
+ * Read 3 Byte
+ */
+#define ALT_QSPI_FLSHCMD_NUMRDDATABYTES_E_RDBYTE3   0x2
+/*
+ * Enumerated value for register field ALT_QSPI_FLSHCMD_NUMRDDATABYTES
+ * 
+ * Read 4 Byte
+ */
+#define ALT_QSPI_FLSHCMD_NUMRDDATABYTES_E_RDBYTE4   0x3
+/*
+ * Enumerated value for register field ALT_QSPI_FLSHCMD_NUMRDDATABYTES
+ * 
+ * Read 5 Byte
+ */
+#define ALT_QSPI_FLSHCMD_NUMRDDATABYTES_E_RDBYTE5   0x4
+/*
+ * Enumerated value for register field ALT_QSPI_FLSHCMD_NUMRDDATABYTES
+ * 
+ * Read 6 Byte
+ */
+#define ALT_QSPI_FLSHCMD_NUMRDDATABYTES_E_RDBYTE6   0x5
+/*
+ * Enumerated value for register field ALT_QSPI_FLSHCMD_NUMRDDATABYTES
+ * 
+ * Read 7 Byte
+ */
+#define ALT_QSPI_FLSHCMD_NUMRDDATABYTES_E_RDBYTE7   0x6
+/*
+ * Enumerated value for register field ALT_QSPI_FLSHCMD_NUMRDDATABYTES
+ * 
+ * Read 8 Byte
+ */
+#define ALT_QSPI_FLSHCMD_NUMRDDATABYTES_E_RDBYTE8   0x7
+
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_FLSHCMD_NUMRDDATABYTES register field. */
+#define ALT_QSPI_FLSHCMD_NUMRDDATABYTES_LSB        20
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_FLSHCMD_NUMRDDATABYTES register field. */
+#define ALT_QSPI_FLSHCMD_NUMRDDATABYTES_MSB        22
+/* The width in bits of the ALT_QSPI_FLSHCMD_NUMRDDATABYTES register field. */
+#define ALT_QSPI_FLSHCMD_NUMRDDATABYTES_WIDTH      3
+/* The mask used to set the ALT_QSPI_FLSHCMD_NUMRDDATABYTES register field value. */
+#define ALT_QSPI_FLSHCMD_NUMRDDATABYTES_SET_MSK    0x00700000
+/* The mask used to clear the ALT_QSPI_FLSHCMD_NUMRDDATABYTES register field value. */
+#define ALT_QSPI_FLSHCMD_NUMRDDATABYTES_CLR_MSK    0xff8fffff
+/* The reset value of the ALT_QSPI_FLSHCMD_NUMRDDATABYTES register field. */
+#define ALT_QSPI_FLSHCMD_NUMRDDATABYTES_RESET      0x0
+/* Extracts the ALT_QSPI_FLSHCMD_NUMRDDATABYTES field value from a register. */
+#define ALT_QSPI_FLSHCMD_NUMRDDATABYTES_GET(value) (((value) & 0x00700000) >> 20)
+/* Produces a ALT_QSPI_FLSHCMD_NUMRDDATABYTES register field value suitable for setting the register. */
+#define ALT_QSPI_FLSHCMD_NUMRDDATABYTES_SET(value) (((value) << 20) & 0x00700000)
+
+/*
+ * Field : Read Data Enable - enrddata
+ * 
+ * If enabled, the command specified in the command opcode field (bits 31:24)
+ * requires read data bytes to be received from the device.
+ * 
+ * Field Enumeration Values:
+ * 
+ *  Enum                                 | Value | Description               
+ * :-------------------------------------|:------|:---------------------------
+ *  ALT_QSPI_FLSHCMD_ENRDDATA_E_EN       | 0x1   | Command Requires read data
+ *  ALT_QSPI_FLSHCMD_ENRDDATA_E_NOACTION | 0x0   | No Action                 
+ * 
+ * Field Access Macros:
+ * 
+ */
+/*
+ * Enumerated value for register field ALT_QSPI_FLSHCMD_ENRDDATA
+ * 
+ * Command Requires read data
+ */
+#define ALT_QSPI_FLSHCMD_ENRDDATA_E_EN          0x1
+/*
+ * Enumerated value for register field ALT_QSPI_FLSHCMD_ENRDDATA
+ * 
+ * No Action
+ */
+#define ALT_QSPI_FLSHCMD_ENRDDATA_E_NOACTION    0x0
+
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_FLSHCMD_ENRDDATA register field. */
+#define ALT_QSPI_FLSHCMD_ENRDDATA_LSB        23
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_FLSHCMD_ENRDDATA register field. */
+#define ALT_QSPI_FLSHCMD_ENRDDATA_MSB        23
+/* The width in bits of the ALT_QSPI_FLSHCMD_ENRDDATA register field. */
+#define ALT_QSPI_FLSHCMD_ENRDDATA_WIDTH      1
+/* The mask used to set the ALT_QSPI_FLSHCMD_ENRDDATA register field value. */
+#define ALT_QSPI_FLSHCMD_ENRDDATA_SET_MSK    0x00800000
+/* The mask used to clear the ALT_QSPI_FLSHCMD_ENRDDATA register field value. */
+#define ALT_QSPI_FLSHCMD_ENRDDATA_CLR_MSK    0xff7fffff
+/* The reset value of the ALT_QSPI_FLSHCMD_ENRDDATA register field. */
+#define ALT_QSPI_FLSHCMD_ENRDDATA_RESET      0x0
+/* Extracts the ALT_QSPI_FLSHCMD_ENRDDATA field value from a register. */
+#define ALT_QSPI_FLSHCMD_ENRDDATA_GET(value) (((value) & 0x00800000) >> 23)
+/* Produces a ALT_QSPI_FLSHCMD_ENRDDATA register field value suitable for setting the register. */
+#define ALT_QSPI_FLSHCMD_ENRDDATA_SET(value) (((value) << 23) & 0x00800000)
+
+/*
+ * Field : Command Opcode - cmdopcode
+ * 
+ * The command opcode field should be setup before triggering the command. For
+ * example, 0x20 maps to SubSector Erase. Writeing to the execute field (bit 0) of
+ * this register launches the command. NOTE : Using this approach to issue commands
+ * to the device will make use of the instruction type of the device instruction
+ * configuration register. If this field is set to 2'b00, then the command opcode,
+ * command address, command dummy bytes and command data will all be transferred in
+ * a serial fashion. If this field is set to 2'b01, then the command opcode,
+ * command address, command dummy bytes and command data will all be transferred in
+ * parallel using DQ0 and DQ1 pins. If this field is set to 2'b10, then the command
+ * opcode, command address, command dummy bytes and command data will all be
+ * transferred in parallel using DQ0, DQ1, DQ2 and DQ3 pins.
+ * 
+ * Field Access Macros:
+ * 
+ */
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_FLSHCMD_CMDOPCODE register field. */
+#define ALT_QSPI_FLSHCMD_CMDOPCODE_LSB        24
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_FLSHCMD_CMDOPCODE register field. */
+#define ALT_QSPI_FLSHCMD_CMDOPCODE_MSB        31
+/* The width in bits of the ALT_QSPI_FLSHCMD_CMDOPCODE register field. */
+#define ALT_QSPI_FLSHCMD_CMDOPCODE_WIDTH      8
+/* The mask used to set the ALT_QSPI_FLSHCMD_CMDOPCODE register field value. */
+#define ALT_QSPI_FLSHCMD_CMDOPCODE_SET_MSK    0xff000000
+/* The mask used to clear the ALT_QSPI_FLSHCMD_CMDOPCODE register field value. */
+#define ALT_QSPI_FLSHCMD_CMDOPCODE_CLR_MSK    0x00ffffff
+/* The reset value of the ALT_QSPI_FLSHCMD_CMDOPCODE register field. */
+#define ALT_QSPI_FLSHCMD_CMDOPCODE_RESET      0x0
+/* Extracts the ALT_QSPI_FLSHCMD_CMDOPCODE field value from a register. */
+#define ALT_QSPI_FLSHCMD_CMDOPCODE_GET(value) (((value) & 0xff000000) >> 24)
+/* Produces a ALT_QSPI_FLSHCMD_CMDOPCODE register field value suitable for setting the register. */
+#define ALT_QSPI_FLSHCMD_CMDOPCODE_SET(value) (((value) << 24) & 0xff000000)
+
+#ifndef __ASSEMBLY__
+/*
+ * WARNING: The C register and register group struct declarations are provided for
+ * convenience and illustrative purposes. They should, however, be used with
+ * caution as the C language standard provides no guarantees about the alignment or
+ * atomicity of device memory accesses. The recommended practice for writing
+ * hardware drivers is to use the SoCAL access macros and alt_read_word() and
+ * alt_write_word() functions.
+ * 
+ * The struct declaration for register ALT_QSPI_FLSHCMD.
+ */
+struct ALT_QSPI_FLSHCMD_s
+{
+    uint32_t        execcmd        :  1;  /* Execute Command */
+    const uint32_t  cmdexecstat    :  1;  /* Command Execution Status */
+    uint32_t                       :  5;  /* *UNDEFINED* */
+    uint32_t        numdummybytes  :  5;  /* Number of Dummy Bytes */
+    uint32_t        numwrdatabytes :  3;  /* Number of Write Data Bytes */
+    uint32_t        enwrdata       :  1;  /* Write Data Enable */
+    uint32_t        numaddrbytes   :  2;  /* Number of Address Bytes */
+    uint32_t        enmodebit      :  1;  /* Mode Bit Enable */
+    uint32_t        encmdaddr      :  1;  /* Command Address Enable */
+    uint32_t        numrddatabytes :  3;  /* Number of Read Data Bytes */
+    uint32_t        enrddata       :  1;  /* Read Data Enable */
+    uint32_t        cmdopcode      :  8;  /* Command Opcode */
+};
+
+/* The typedef declaration for register ALT_QSPI_FLSHCMD. */
+typedef volatile struct ALT_QSPI_FLSHCMD_s  ALT_QSPI_FLSHCMD_t;
+#endif  /* __ASSEMBLY__ */
+
+/* The byte offset of the ALT_QSPI_FLSHCMD register from the beginning of the component. */
+#define ALT_QSPI_FLSHCMD_OFST        0x90
+
+/*
+ * Register : Flash Command Address Registers - flashcmdaddr
+ * 
+ * Register Layout
+ * 
+ *  Bits   | Access | Reset | Description    
+ * :-------|:-------|:------|:----------------
+ *  [31:0] | RW     | 0x0   | Command Address
+ * 
+ */
+/*
+ * Field : Command Address - addr
+ * 
+ * This should be setup before triggering the command with execute field (bit 0) of
+ * the Flash Command Control register. It is the address used by the command
+ * specified in the opcode field (bits 31:24) of the Flash Command Control
+ * register.
+ * 
+ * Field Access Macros:
+ * 
+ */
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_FLSHCMDADDR_ADDR register field. */
+#define ALT_QSPI_FLSHCMDADDR_ADDR_LSB        0
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_FLSHCMDADDR_ADDR register field. */
+#define ALT_QSPI_FLSHCMDADDR_ADDR_MSB        31
+/* The width in bits of the ALT_QSPI_FLSHCMDADDR_ADDR register field. */
+#define ALT_QSPI_FLSHCMDADDR_ADDR_WIDTH      32
+/* The mask used to set the ALT_QSPI_FLSHCMDADDR_ADDR register field value. */
+#define ALT_QSPI_FLSHCMDADDR_ADDR_SET_MSK    0xffffffff
+/* The mask used to clear the ALT_QSPI_FLSHCMDADDR_ADDR register field value. */
+#define ALT_QSPI_FLSHCMDADDR_ADDR_CLR_MSK    0x00000000
+/* The reset value of the ALT_QSPI_FLSHCMDADDR_ADDR register field. */
+#define ALT_QSPI_FLSHCMDADDR_ADDR_RESET      0x0
+/* Extracts the ALT_QSPI_FLSHCMDADDR_ADDR field value from a register. */
+#define ALT_QSPI_FLSHCMDADDR_ADDR_GET(value) (((value) & 0xffffffff) >> 0)
+/* Produces a ALT_QSPI_FLSHCMDADDR_ADDR register field value suitable for setting the register. */
+#define ALT_QSPI_FLSHCMDADDR_ADDR_SET(value) (((value) << 0) & 0xffffffff)
+
+#ifndef __ASSEMBLY__
+/*
+ * WARNING: The C register and register group struct declarations are provided for
+ * convenience and illustrative purposes. They should, however, be used with
+ * caution as the C language standard provides no guarantees about the alignment or
+ * atomicity of device memory accesses. The recommended practice for writing
+ * hardware drivers is to use the SoCAL access macros and alt_read_word() and
+ * alt_write_word() functions.
+ * 
+ * The struct declaration for register ALT_QSPI_FLSHCMDADDR.
+ */
+struct ALT_QSPI_FLSHCMDADDR_s
+{
+    uint32_t  addr : 32;  /* Command Address */
+};
+
+/* The typedef declaration for register ALT_QSPI_FLSHCMDADDR. */
+typedef volatile struct ALT_QSPI_FLSHCMDADDR_s  ALT_QSPI_FLSHCMDADDR_t;
+#endif  /* __ASSEMBLY__ */
+
+/* The byte offset of the ALT_QSPI_FLSHCMDADDR register from the beginning of the component. */
+#define ALT_QSPI_FLSHCMDADDR_OFST        0x94
+
+/*
+ * Register : Flash Command Read Data Register (Lower) - flashcmdrddatalo
+ * 
+ * Register Layout
+ * 
+ *  Bits   | Access | Reset | Description                   
+ * :-------|:-------|:------|:-------------------------------
+ *  [31:0] | RW     | 0x0   | Command Read Data (Lower byte)
+ * 
+ */
+/*
+ * Field : Command Read Data (Lower byte) - data
+ * 
+ * This is the data that is returned by the flash device for any status or
+ * configuration read operation carried out by triggering the event in the control
+ * register. The register will be valid when the polling bit in the control
+ * register is low.
+ * 
+ * Field Access Macros:
+ * 
+ */
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_FLSHCMDRDDATALO_DATA register field. */
+#define ALT_QSPI_FLSHCMDRDDATALO_DATA_LSB        0
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_FLSHCMDRDDATALO_DATA register field. */
+#define ALT_QSPI_FLSHCMDRDDATALO_DATA_MSB        31
+/* The width in bits of the ALT_QSPI_FLSHCMDRDDATALO_DATA register field. */
+#define ALT_QSPI_FLSHCMDRDDATALO_DATA_WIDTH      32
+/* The mask used to set the ALT_QSPI_FLSHCMDRDDATALO_DATA register field value. */
+#define ALT_QSPI_FLSHCMDRDDATALO_DATA_SET_MSK    0xffffffff
+/* The mask used to clear the ALT_QSPI_FLSHCMDRDDATALO_DATA register field value. */
+#define ALT_QSPI_FLSHCMDRDDATALO_DATA_CLR_MSK    0x00000000
+/* The reset value of the ALT_QSPI_FLSHCMDRDDATALO_DATA register field. */
+#define ALT_QSPI_FLSHCMDRDDATALO_DATA_RESET      0x0
+/* Extracts the ALT_QSPI_FLSHCMDRDDATALO_DATA field value from a register. */
+#define ALT_QSPI_FLSHCMDRDDATALO_DATA_GET(value) (((value) & 0xffffffff) >> 0)
+/* Produces a ALT_QSPI_FLSHCMDRDDATALO_DATA register field value suitable for setting the register. */
+#define ALT_QSPI_FLSHCMDRDDATALO_DATA_SET(value) (((value) << 0) & 0xffffffff)
+
+#ifndef __ASSEMBLY__
+/*
+ * WARNING: The C register and register group struct declarations are provided for
+ * convenience and illustrative purposes. They should, however, be used with
+ * caution as the C language standard provides no guarantees about the alignment or
+ * atomicity of device memory accesses. The recommended practice for writing
+ * hardware drivers is to use the SoCAL access macros and alt_read_word() and
+ * alt_write_word() functions.
+ * 
+ * The struct declaration for register ALT_QSPI_FLSHCMDRDDATALO.
+ */
+struct ALT_QSPI_FLSHCMDRDDATALO_s
+{
+    uint32_t  data : 32;  /* Command Read Data (Lower byte) */
+};
+
+/* The typedef declaration for register ALT_QSPI_FLSHCMDRDDATALO. */
+typedef volatile struct ALT_QSPI_FLSHCMDRDDATALO_s  ALT_QSPI_FLSHCMDRDDATALO_t;
+#endif  /* __ASSEMBLY__ */
+
+/* The byte offset of the ALT_QSPI_FLSHCMDRDDATALO register from the beginning of the component. */
+#define ALT_QSPI_FLSHCMDRDDATALO_OFST        0xa0
+
+/*
+ * Register : Flash Command Read Data Register (Upper) - flashcmdrddataup
+ * 
+ * Device Instruction Register
+ * 
+ * Register Layout
+ * 
+ *  Bits   | Access | Reset | Description                   
+ * :-------|:-------|:------|:-------------------------------
+ *  [31:0] | RW     | 0x0   | Command Read Data (Upper byte)
+ * 
+ */
+/*
+ * Field : Command Read Data (Upper byte) - data
+ * 
+ * This is the data that is returned by the FLASH device for any status or
+ * configuration read operation carried out by triggering the event in the control
+ * register. The register will be valid when the polling bit in the control
+ * register is low.
+ * 
+ * Field Access Macros:
+ * 
+ */
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_FLSHCMDRDDATAUP_DATA register field. */
+#define ALT_QSPI_FLSHCMDRDDATAUP_DATA_LSB        0
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_FLSHCMDRDDATAUP_DATA register field. */
+#define ALT_QSPI_FLSHCMDRDDATAUP_DATA_MSB        31
+/* The width in bits of the ALT_QSPI_FLSHCMDRDDATAUP_DATA register field. */
+#define ALT_QSPI_FLSHCMDRDDATAUP_DATA_WIDTH      32
+/* The mask used to set the ALT_QSPI_FLSHCMDRDDATAUP_DATA register field value. */
+#define ALT_QSPI_FLSHCMDRDDATAUP_DATA_SET_MSK    0xffffffff
+/* The mask used to clear the ALT_QSPI_FLSHCMDRDDATAUP_DATA register field value. */
+#define ALT_QSPI_FLSHCMDRDDATAUP_DATA_CLR_MSK    0x00000000
+/* The reset value of the ALT_QSPI_FLSHCMDRDDATAUP_DATA register field. */
+#define ALT_QSPI_FLSHCMDRDDATAUP_DATA_RESET      0x0
+/* Extracts the ALT_QSPI_FLSHCMDRDDATAUP_DATA field value from a register. */
+#define ALT_QSPI_FLSHCMDRDDATAUP_DATA_GET(value) (((value) & 0xffffffff) >> 0)
+/* Produces a ALT_QSPI_FLSHCMDRDDATAUP_DATA register field value suitable for setting the register. */
+#define ALT_QSPI_FLSHCMDRDDATAUP_DATA_SET(value) (((value) << 0) & 0xffffffff)
+
+#ifndef __ASSEMBLY__
+/*
+ * WARNING: The C register and register group struct declarations are provided for
+ * convenience and illustrative purposes. They should, however, be used with
+ * caution as the C language standard provides no guarantees about the alignment or
+ * atomicity of device memory accesses. The recommended practice for writing
+ * hardware drivers is to use the SoCAL access macros and alt_read_word() and
+ * alt_write_word() functions.
+ * 
+ * The struct declaration for register ALT_QSPI_FLSHCMDRDDATAUP.
+ */
+struct ALT_QSPI_FLSHCMDRDDATAUP_s
+{
+    uint32_t  data : 32;  /* Command Read Data (Upper byte) */
+};
+
+/* The typedef declaration for register ALT_QSPI_FLSHCMDRDDATAUP. */
+typedef volatile struct ALT_QSPI_FLSHCMDRDDATAUP_s  ALT_QSPI_FLSHCMDRDDATAUP_t;
+#endif  /* __ASSEMBLY__ */
+
+/* The byte offset of the ALT_QSPI_FLSHCMDRDDATAUP register from the beginning of the component. */
+#define ALT_QSPI_FLSHCMDRDDATAUP_OFST        0xa4
+
+/*
+ * Register : Flash Command Write Data Register (Lower) - flashcmdwrdatalo
+ * 
+ * Register Layout
+ * 
+ *  Bits   | Access | Reset | Description                  
+ * :-------|:-------|:------|:------------------------------
+ *  [31:0] | RW     | 0x0   | Command Write Data Lower Byte
+ * 
+ */
+/*
+ * Field : Command Write Data Lower Byte - data
+ * 
+ * This is the command write data lower byte. This should be setup before
+ * triggering the command with execute field (bit 0) of the Flash Command Control
+ * register. It is the data that is to be written to the flash for any status or
+ * configuration write operation carried out by triggering the event in the Flash
+ * Command Control register.
+ * 
+ * Field Access Macros:
+ * 
+ */
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_FLSHCMDWRDATALO_DATA register field. */
+#define ALT_QSPI_FLSHCMDWRDATALO_DATA_LSB        0
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_FLSHCMDWRDATALO_DATA register field. */
+#define ALT_QSPI_FLSHCMDWRDATALO_DATA_MSB        31
+/* The width in bits of the ALT_QSPI_FLSHCMDWRDATALO_DATA register field. */
+#define ALT_QSPI_FLSHCMDWRDATALO_DATA_WIDTH      32
+/* The mask used to set the ALT_QSPI_FLSHCMDWRDATALO_DATA register field value. */
+#define ALT_QSPI_FLSHCMDWRDATALO_DATA_SET_MSK    0xffffffff
+/* The mask used to clear the ALT_QSPI_FLSHCMDWRDATALO_DATA register field value. */
+#define ALT_QSPI_FLSHCMDWRDATALO_DATA_CLR_MSK    0x00000000
+/* The reset value of the ALT_QSPI_FLSHCMDWRDATALO_DATA register field. */
+#define ALT_QSPI_FLSHCMDWRDATALO_DATA_RESET      0x0
+/* Extracts the ALT_QSPI_FLSHCMDWRDATALO_DATA field value from a register. */
+#define ALT_QSPI_FLSHCMDWRDATALO_DATA_GET(value) (((value) & 0xffffffff) >> 0)
+/* Produces a ALT_QSPI_FLSHCMDWRDATALO_DATA register field value suitable for setting the register. */
+#define ALT_QSPI_FLSHCMDWRDATALO_DATA_SET(value) (((value) << 0) & 0xffffffff)
+
+#ifndef __ASSEMBLY__
+/*
+ * WARNING: The C register and register group struct declarations are provided for
+ * convenience and illustrative purposes. They should, however, be used with
+ * caution as the C language standard provides no guarantees about the alignment or
+ * atomicity of device memory accesses. The recommended practice for writing
+ * hardware drivers is to use the SoCAL access macros and alt_read_word() and
+ * alt_write_word() functions.
+ * 
+ * The struct declaration for register ALT_QSPI_FLSHCMDWRDATALO.
+ */
+struct ALT_QSPI_FLSHCMDWRDATALO_s
+{
+    uint32_t  data : 32;  /* Command Write Data Lower Byte */
+};
+
+/* The typedef declaration for register ALT_QSPI_FLSHCMDWRDATALO. */
+typedef volatile struct ALT_QSPI_FLSHCMDWRDATALO_s  ALT_QSPI_FLSHCMDWRDATALO_t;
+#endif  /* __ASSEMBLY__ */
+
+/* The byte offset of the ALT_QSPI_FLSHCMDWRDATALO register from the beginning of the component. */
+#define ALT_QSPI_FLSHCMDWRDATALO_OFST        0xa8
+
+/*
+ * Register : Flash Command Write Data Register (Upper) - flashcmdwrdataup
+ * 
+ * Register Layout
+ * 
+ *  Bits   | Access | Reset | Description                  
+ * :-------|:-------|:------|:------------------------------
+ *  [31:0] | RW     | 0x0   | ALT_QSPI_FLSHCMDWRDATAUP_DATA
+ * 
+ */
+/*
+ * Field : data
+ * 
+ * This is the command write data upper byte. This should be setup before
+ * triggering the command with execute field (bit 0) of the Flash Command Control
+ * register. It is the data that is to be written to the flash for any status or
+ * configuration write operation carried out by triggering the event in the Flash
+ * Command Control register.
+ * 
+ * Field Access Macros:
+ * 
+ */
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_FLSHCMDWRDATAUP_DATA register field. */
+#define ALT_QSPI_FLSHCMDWRDATAUP_DATA_LSB        0
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_FLSHCMDWRDATAUP_DATA register field. */
+#define ALT_QSPI_FLSHCMDWRDATAUP_DATA_MSB        31
+/* The width in bits of the ALT_QSPI_FLSHCMDWRDATAUP_DATA register field. */
+#define ALT_QSPI_FLSHCMDWRDATAUP_DATA_WIDTH      32
+/* The mask used to set the ALT_QSPI_FLSHCMDWRDATAUP_DATA register field value. */
+#define ALT_QSPI_FLSHCMDWRDATAUP_DATA_SET_MSK    0xffffffff
+/* The mask used to clear the ALT_QSPI_FLSHCMDWRDATAUP_DATA register field value. */
+#define ALT_QSPI_FLSHCMDWRDATAUP_DATA_CLR_MSK    0x00000000
+/* The reset value of the ALT_QSPI_FLSHCMDWRDATAUP_DATA register field. */
+#define ALT_QSPI_FLSHCMDWRDATAUP_DATA_RESET      0x0
+/* Extracts the ALT_QSPI_FLSHCMDWRDATAUP_DATA field value from a register. */
+#define ALT_QSPI_FLSHCMDWRDATAUP_DATA_GET(value) (((value) & 0xffffffff) >> 0)
+/* Produces a ALT_QSPI_FLSHCMDWRDATAUP_DATA register field value suitable for setting the register. */
+#define ALT_QSPI_FLSHCMDWRDATAUP_DATA_SET(value) (((value) << 0) & 0xffffffff)
+
+#ifndef __ASSEMBLY__
+/*
+ * WARNING: The C register and register group struct declarations are provided for
+ * convenience and illustrative purposes. They should, however, be used with
+ * caution as the C language standard provides no guarantees about the alignment or
+ * atomicity of device memory accesses. The recommended practice for writing
+ * hardware drivers is to use the SoCAL access macros and alt_read_word() and
+ * alt_write_word() functions.
+ * 
+ * The struct declaration for register ALT_QSPI_FLSHCMDWRDATAUP.
+ */
+struct ALT_QSPI_FLSHCMDWRDATAUP_s
+{
+    uint32_t  data : 32;  /* ALT_QSPI_FLSHCMDWRDATAUP_DATA */
+};
+
+/* The typedef declaration for register ALT_QSPI_FLSHCMDWRDATAUP. */
+typedef volatile struct ALT_QSPI_FLSHCMDWRDATAUP_s  ALT_QSPI_FLSHCMDWRDATAUP_t;
+#endif  /* __ASSEMBLY__ */
+
+/* The byte offset of the ALT_QSPI_FLSHCMDWRDATAUP register from the beginning of the component. */
+#define ALT_QSPI_FLSHCMDWRDATAUP_OFST        0xac
+
+/*
+ * Register : Module ID Register - moduleid
+ * 
+ * Register Layout
+ * 
+ *  Bits    | Access | Reset  | Description     
+ * :--------|:-------|:-------|:-----------------
+ *  [24:0]  | R      | 0x1001 | Module ID number
+ *  [31:25] | ???    | 0x0    | *UNDEFINED*     
+ * 
+ */
+/*
+ * Field : Module ID number - value
+ * 
+ * Field Access Macros:
+ * 
+ */
+/* The Least Significant Bit (LSB) position of the ALT_QSPI_MODULEID_VALUE register field. */
+#define ALT_QSPI_MODULEID_VALUE_LSB        0
+/* The Most Significant Bit (MSB) position of the ALT_QSPI_MODULEID_VALUE register field. */
+#define ALT_QSPI_MODULEID_VALUE_MSB        24
+/* The width in bits of the ALT_QSPI_MODULEID_VALUE register field. */
+#define ALT_QSPI_MODULEID_VALUE_WIDTH      25
+/* The mask used to set the ALT_QSPI_MODULEID_VALUE register field value. */
+#define ALT_QSPI_MODULEID_VALUE_SET_MSK    0x01ffffff
+/* The mask used to clear the ALT_QSPI_MODULEID_VALUE register field value. */
+#define ALT_QSPI_MODULEID_VALUE_CLR_MSK    0xfe000000
+/* The reset value of the ALT_QSPI_MODULEID_VALUE register field. */
+#define ALT_QSPI_MODULEID_VALUE_RESET      0x1001
+/* Extracts the ALT_QSPI_MODULEID_VALUE field value from a register. */
+#define ALT_QSPI_MODULEID_VALUE_GET(value) (((value) & 0x01ffffff) >> 0)
+/* Produces a ALT_QSPI_MODULEID_VALUE register field value suitable for setting the register. */
+#define ALT_QSPI_MODULEID_VALUE_SET(value) (((value) << 0) & 0x01ffffff)
+
+#ifndef __ASSEMBLY__
+/*
+ * WARNING: The C register and register group struct declarations are provided for
+ * convenience and illustrative purposes. They should, however, be used with
+ * caution as the C language standard provides no guarantees about the alignment or
+ * atomicity of device memory accesses. The recommended practice for writing
+ * hardware drivers is to use the SoCAL access macros and alt_read_word() and
+ * alt_write_word() functions.
+ * 
+ * The struct declaration for register ALT_QSPI_MODULEID.
+ */
+struct ALT_QSPI_MODULEID_s
+{
+    const uint32_t  value : 25;  /* Module ID number */
+    uint32_t              :  7;  /* *UNDEFINED* */
+};
+
+/* The typedef declaration for register ALT_QSPI_MODULEID. */
+typedef volatile struct ALT_QSPI_MODULEID_s  ALT_QSPI_MODULEID_t;
+#endif  /* __ASSEMBLY__ */
+
+/* The byte offset of the ALT_QSPI_MODULEID register from the beginning of the component. */
+#define ALT_QSPI_MODULEID_OFST        0xfc
+
+#ifndef __ASSEMBLY__
+/*
+ * WARNING: The C register and register group struct declarations are provided for
+ * convenience and illustrative purposes. They should, however, be used with
+ * caution as the C language standard provides no guarantees about the alignment or
+ * atomicity of device memory accesses. The recommended practice for writing
+ * hardware drivers is to use the SoCAL access macros and alt_read_word() and
+ * alt_write_word() functions.
+ * 
+ * The struct declaration for register group ALT_QSPI.
+ */
+struct ALT_QSPI_s
+{
+    volatile ALT_QSPI_CFG_t              cfg;                 /* ALT_QSPI_CFG */
+    volatile ALT_QSPI_DEVRD_t            devrd;               /* ALT_QSPI_DEVRD */
+    volatile ALT_QSPI_DEVWR_t            devwr;               /* ALT_QSPI_DEVWR */
+    volatile ALT_QSPI_DELAY_t            delay;               /* ALT_QSPI_DELAY */
+    volatile ALT_QSPI_RDDATACAP_t        rddatacap;           /* ALT_QSPI_RDDATACAP */
+    volatile ALT_QSPI_DEVSZ_t            devsz;               /* ALT_QSPI_DEVSZ */
+    volatile ALT_QSPI_SRAMPART_t         srampart;            /* ALT_QSPI_SRAMPART */
+    volatile ALT_QSPI_INDADDRTRIG_t      indaddrtrig;         /* ALT_QSPI_INDADDRTRIG */
+    volatile ALT_QSPI_DMAPER_t           dmaper;              /* ALT_QSPI_DMAPER */
+    volatile ALT_QSPI_REMAPADDR_t        remapaddr;           /* ALT_QSPI_REMAPADDR */
+    volatile ALT_QSPI_MODBIT_t           modebit;             /* ALT_QSPI_MODBIT */
+    volatile ALT_QSPI_SRAMFILL_t         sramfill;            /* ALT_QSPI_SRAMFILL */
+    volatile ALT_QSPI_TXTHRESH_t         txthresh;            /* ALT_QSPI_TXTHRESH */
+    volatile ALT_QSPI_RXTHRESH_t         rxthresh;            /* ALT_QSPI_RXTHRESH */
+    volatile uint32_t                    _pad_0x38_0x3f[2];   /* *UNDEFINED* */
+    volatile ALT_QSPI_IRQSTAT_t          irqstat;             /* ALT_QSPI_IRQSTAT */
+    volatile ALT_QSPI_IRQMSK_t           irqmask;             /* ALT_QSPI_IRQMSK */
+    volatile uint32_t                    _pad_0x48_0x4f[2];   /* *UNDEFINED* */
+    volatile ALT_QSPI_LOWWRPROT_t        lowwrprot;           /* ALT_QSPI_LOWWRPROT */
+    volatile ALT_QSPI_UPPWRPROT_t        uppwrprot;           /* ALT_QSPI_UPPWRPROT */
+    volatile ALT_QSPI_WRPROT_t           wrprot;              /* ALT_QSPI_WRPROT */
+    volatile uint32_t                    _pad_0x5c_0x5f;      /* *UNDEFINED* */
+    volatile ALT_QSPI_INDRD_t            indrd;               /* ALT_QSPI_INDRD */
+    volatile ALT_QSPI_INDRDWATER_t       indrdwater;          /* ALT_QSPI_INDRDWATER */
+    volatile ALT_QSPI_INDRDSTADDR_t      indrdstaddr;         /* ALT_QSPI_INDRDSTADDR */
+    volatile ALT_QSPI_INDRDCNT_t         indrdcnt;            /* ALT_QSPI_INDRDCNT */
+    volatile ALT_QSPI_INDWR_t            indwr;               /* ALT_QSPI_INDWR */
+    volatile ALT_QSPI_INDWRWATER_t       indwrwater;          /* ALT_QSPI_INDWRWATER */
+    volatile ALT_QSPI_INDWRSTADDR_t      indwrstaddr;         /* ALT_QSPI_INDWRSTADDR */
+    volatile ALT_QSPI_INDWRCNT_t         indwrcnt;            /* ALT_QSPI_INDWRCNT */
+    volatile uint32_t                    _pad_0x80_0x8f[4];   /* *UNDEFINED* */
+    volatile ALT_QSPI_FLSHCMD_t          flashcmd;            /* ALT_QSPI_FLSHCMD */
+    volatile ALT_QSPI_FLSHCMDADDR_t      flashcmdaddr;        /* ALT_QSPI_FLSHCMDADDR */
+    volatile uint32_t                    _pad_0x98_0x9f[2];   /* *UNDEFINED* */
+    volatile ALT_QSPI_FLSHCMDRDDATALO_t  flashcmdrddatalo;    /* ALT_QSPI_FLSHCMDRDDATALO */
+    volatile ALT_QSPI_FLSHCMDRDDATAUP_t  flashcmdrddataup;    /* ALT_QSPI_FLSHCMDRDDATAUP */
+    volatile ALT_QSPI_FLSHCMDWRDATALO_t  flashcmdwrdatalo;    /* ALT_QSPI_FLSHCMDWRDATALO */
+    volatile ALT_QSPI_FLSHCMDWRDATAUP_t  flashcmdwrdataup;    /* ALT_QSPI_FLSHCMDWRDATAUP */
+    volatile uint32_t                    _pad_0xb0_0xfb[19];  /* *UNDEFINED* */
+    volatile ALT_QSPI_MODULEID_t         moduleid;            /* ALT_QSPI_MODULEID */
+};
+
+/* The typedef declaration for register group ALT_QSPI. */
+typedef volatile struct ALT_QSPI_s  ALT_QSPI_t;
+/* The struct declaration for the raw register contents of register group ALT_QSPI. */
+struct ALT_QSPI_raw_s
+{
+    volatile uint32_t  cfg;                 /* ALT_QSPI_CFG */
+    volatile uint32_t  devrd;               /* ALT_QSPI_DEVRD */
+    volatile uint32_t  devwr;               /* ALT_QSPI_DEVWR */
+    volatile uint32_t  delay;               /* ALT_QSPI_DELAY */
+    volatile uint32_t  rddatacap;           /* ALT_QSPI_RDDATACAP */
+    volatile uint32_t  devsz;               /* ALT_QSPI_DEVSZ */
+    volatile uint32_t  srampart;            /* ALT_QSPI_SRAMPART */
+    volatile uint32_t  indaddrtrig;         /* ALT_QSPI_INDADDRTRIG */
+    volatile uint32_t  dmaper;              /* ALT_QSPI_DMAPER */
+    volatile uint32_t  remapaddr;           /* ALT_QSPI_REMAPADDR */
+    volatile uint32_t  modebit;             /* ALT_QSPI_MODBIT */
+    volatile uint32_t  sramfill;            /* ALT_QSPI_SRAMFILL */
+    volatile uint32_t  txthresh;            /* ALT_QSPI_TXTHRESH */
+    volatile uint32_t  rxthresh;            /* ALT_QSPI_RXTHRESH */
+    volatile uint32_t  _pad_0x38_0x3f[2];   /* *UNDEFINED* */
+    volatile uint32_t  irqstat;             /* ALT_QSPI_IRQSTAT */
+    volatile uint32_t  irqmask;             /* ALT_QSPI_IRQMSK */
+    volatile uint32_t  _pad_0x48_0x4f[2];   /* *UNDEFINED* */
+    volatile uint32_t  lowwrprot;           /* ALT_QSPI_LOWWRPROT */
+    volatile uint32_t  uppwrprot;           /* ALT_QSPI_UPPWRPROT */
+    volatile uint32_t  wrprot;              /* ALT_QSPI_WRPROT */
+    volatile uint32_t  _pad_0x5c_0x5f;      /* *UNDEFINED* */
+    volatile uint32_t  indrd;               /* ALT_QSPI_INDRD */
+    volatile uint32_t  indrdwater;          /* ALT_QSPI_INDRDWATER */
+    volatile uint32_t  indrdstaddr;         /* ALT_QSPI_INDRDSTADDR */
+    volatile uint32_t  indrdcnt;            /* ALT_QSPI_INDRDCNT */
+    volatile uint32_t  indwr;               /* ALT_QSPI_INDWR */
+    volatile uint32_t  indwrwater;          /* ALT_QSPI_INDWRWATER */
+    volatile uint32_t  indwrstaddr;         /* ALT_QSPI_INDWRSTADDR */
+    volatile uint32_t  indwrcnt;            /* ALT_QSPI_INDWRCNT */
+    volatile uint32_t  _pad_0x80_0x8f[4];   /* *UNDEFINED* */
+    volatile uint32_t  flashcmd;            /* ALT_QSPI_FLSHCMD */
+    volatile uint32_t  flashcmdaddr;        /* ALT_QSPI_FLSHCMDADDR */
+    volatile uint32_t  _pad_0x98_0x9f[2];   /* *UNDEFINED* */
+    volatile uint32_t  flashcmdrddatalo;    /* ALT_QSPI_FLSHCMDRDDATALO */
+    volatile uint32_t  flashcmdrddataup;    /* ALT_QSPI_FLSHCMDRDDATAUP */
+    volatile uint32_t  flashcmdwrdatalo;    /* ALT_QSPI_FLSHCMDWRDATALO */
+    volatile uint32_t  flashcmdwrdataup;    /* ALT_QSPI_FLSHCMDWRDATAUP */
+    volatile uint32_t  _pad_0xb0_0xfb[19];  /* *UNDEFINED* */
+    volatile uint32_t  moduleid;            /* ALT_QSPI_MODULEID */
+};
+
+/* The typedef declaration for the raw register contents of register group ALT_QSPI. */
+typedef volatile struct ALT_QSPI_raw_s  ALT_QSPI_raw_t;
+#endif  /* __ASSEMBLY__ */
+
+
+#ifdef __cplusplus
+}
+#endif  /* __cplusplus */
+#endif  /* __ALTERA_ALT_QSPI_H__ */
+
diff --git a/c/src/lib/libbsp/arm/altera-cyclone-v/hwlib/include/socal/alt_qspidata.h b/c/src/lib/libbsp/arm/altera-cyclone-v/hwlib/include/socal/alt_qspidata.h
new file mode 100644
index 0000000..19383ee
--- /dev/null
+++ b/c/src/lib/libbsp/arm/altera-cyclone-v/hwlib/include/socal/alt_qspidata.h
@@ -0,0 +1,52 @@
+/*******************************************************************************
+*                                                                              *
+* Copyright 2013 Altera Corporation. All Rights Reserved.                      *
+*                                                                              *
+* Redistribution and use in source and binary forms, with or without           *
+* modification, are permitted provided that the following conditions are met:  *
+*                                                                              *
+* 1. Redistributions of source code must retain the above copyright notice,    *
+*    this list of conditions and the following disclaimer.                     *
+*                                                                              *
+* 2. Redistributions in binary form must reproduce the above copyright notice, *
+*    this list of conditions and the following disclaimer in the documentation *
+*    and/or other materials provided with the distribution.                    *
+*                                                                              *
+* 3. The name of the author may not be used to endorse or promote products     *
+*    derived from this software without specific prior written permission.     *
+*                                                                              *
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY EXPRESS OR *
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
+* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED. IN NO  *
+* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,       *
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
+* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;  *
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,     *
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR      *
+* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF       *
+* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                                   *
+*                                                                              *
+*******************************************************************************/
+
+/* Altera - ALT_QSPIDATA */
+
+#ifndef __ALTERA_ALT_QSPIDATA_H__
+#define __ALTERA_ALT_QSPIDATA_H__
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif  /* __cplusplus */
+
+/*
+ * Component : QSPI Flash Module Data (AHB Slave) - ALT_QSPIDATA
+ * QSPI Flash Module Data (AHB Slave)
+ * 
+ * 
+ */
+
+#ifdef __cplusplus
+}
+#endif  /* __cplusplus */
+#endif  /* __ALTERA_ALT_QSPIDATA_H__ */
+
diff --git a/c/src/lib/libbsp/arm/altera-cyclone-v/hwlib/src/hwmgr/alt_16550_uart.c b/c/src/lib/libbsp/arm/altera-cyclone-v/hwlib/src/hwmgr/alt_16550_uart.c
new file mode 100644
index 0000000..a5dfc5f
--- /dev/null
+++ b/c/src/lib/libbsp/arm/altera-cyclone-v/hwlib/src/hwmgr/alt_16550_uart.c
@@ -0,0 +1,1179 @@
+/******************************************************************************
+ *
+ * Copyright 2013 Altera Corporation. All Rights Reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 
+ ******************************************************************************/
+
+#include "alt_16550_uart.h"
+#include "alt_clock_manager.h"
+#include "socal/alt_rstmgr.h"
+#include "socal/alt_uart.h"
+#include "socal/hps.h"
+#include "socal/socal.h"
+
+/////
+
+#define ALT_16550_HANDLE_DATA_UART_ENABLED_MSK   (1UL << 31)
+#define ALT_16550_HANDLE_DATA_DIVISOR_VALUE_GET(value) (value & 0xffff)
+
+#define ALT_ALTERA_16550_CPR_OFST        (0xF4)
+#define ALT_ALTERA_16550_CPR_ADDR(base)  ALT_CAST(void *, (ALT_CAST(char *, (base)) + ALT_ALTERA_16550_CPR_OFST))
+#define ALT_ALTERA_16550_CPR_FIFO_MODE_GET(value) (((value) >> 16) & 0xff)
+#define ALT_ALTERA_16550_CPR_AFCE_MODE_SET_MSK (1 << 4)
+
+/////
+
+// Remove these macros as part of case:123835.
+#define ALT_UART_IER_DLH_VALUE_SET(value) ((value) & 0xff)
+#define ALT_UART_IER_DLH_ETBEI_DLH1_SET_MSK ALT_UART_IER_DLH_ETBEI_DLHL_SET_MSK
+
+/////
+
+//
+// Helper function which resets the UART and if requested, initializes the UART
+// to the default settings. Currently the default settings are:
+//  - 8 databits
+//  - no parity
+//  - 1 stopbit
+//  - 57600 baudrate
+// The reset routines depends on the hardware implementation of the UART.
+//
+
+// This helper is needed because the regular alt_read_word(src) essentially
+// resolves to "*(volatile uint32_t *)src". As there is no assignment, this
+// could potentially be optimized away. With the helper, the actual register
+// read should occur and be returned (and subsequently discarded).
+static inline uint32_t alt_read_word_helper(const void * addr)
+{
+    return alt_read_word(addr);
+}
+
+//
+// Helper function write the divisor in hardware.
+//
+static ALT_STATUS_CODE alt_16550_write_divisor_helper(ALT_16550_HANDLE_t * handle,
+                                                      uint32_t divisor)
+{
+    // Validate the divisor parameter.
+    if (divisor > 0xffff)
+    {
+        // This should never happen as it is verified in divisor_set.
+        return ALT_E_ERROR;
+    }
+
+    switch (handle->device)
+    {
+    case ALT_16550_DEVICE_SOCFPGA_UART0:
+    case ALT_16550_DEVICE_SOCFPGA_UART1:
+    case ALT_16550_DEVICE_ALTERA_16550_UART:
+        // Set LCR::DLAB (Line Control Register :: Divisor Latch Access Bit)
+        alt_setbits_word(ALT_UART_LCR_ADDR(handle->location), ALT_UART_LCR_DLAB_SET_MSK);
+
+        // Write DLL (Divisor Latch Low).
+        alt_write_word(ALT_UART_RBR_THR_DLL_ADDR(handle->location), ALT_UART_RBR_THR_DLL_VALUE_SET(divisor));
+
+        // Write DLH (Divisor Latch High).
+        alt_write_word(ALT_UART_IER_DLH_ADDR(handle->location), ALT_UART_IER_DLH_VALUE_SET(divisor >> 8));
+
+        // Clear LCR::DLAB (Line Control Register :: Divisor Latch Access Bit)
+        alt_clrbits_word(ALT_UART_LCR_ADDR(handle->location), ALT_UART_LCR_DLAB_SET_MSK);
+
+        break;
+
+    default:
+        return ALT_E_ERROR;
+    }
+
+    // Update the enabled state in the handle data.
+    if (divisor != 0)
+    {
+        handle->data |= ALT_16550_HANDLE_DATA_UART_ENABLED_MSK;
+    }
+    else
+    {
+        handle->data &= ~ALT_16550_HANDLE_DATA_UART_ENABLED_MSK;
+    }
+
+    return ALT_E_SUCCESS;
+}
+
+//
+// Helper function to reset the UART.
+//
+static ALT_STATUS_CODE alt_16550_reset_helper(ALT_16550_HANDLE_t * handle, bool enable_init)
+{
+    switch (handle->device)
+    {
+    case ALT_16550_DEVICE_SOCFPGA_UART0:
+    case ALT_16550_DEVICE_SOCFPGA_UART1:
+        // Write SRR::UR (Shadow Reset Register :: UART Reset)
+        alt_write_word(ALT_UART_SRR_ADDR(handle->location), ALT_UART_SRR_UR_SET_MSK);
+
+        // Read the MSR to work around case:119085.
+        alt_read_word_helper(ALT_UART_MSR_ADDR(handle->location));
+        break;
+
+    case ALT_16550_DEVICE_ALTERA_16550_UART:
+        alt_16550_write_divisor_helper(handle, 0); // Disable UART
+        alt_16550_int_disable_all(handle);         // Disable interrupts
+        alt_16550_fifo_disable(handle);            // Disable FIFOs
+        alt_write_word(ALT_UART_MCR_ADDR(handle->location), 0); // 0 -> MCR (AFCE, LP, OUT2, OUT1, RTS, DTR)
+        break;
+
+    default:
+        return ALT_E_ERROR;
+    }
+
+    // If we are initializing (as opposed to just uninitializing)
+    if (enable_init)
+    {
+        ALT_STATUS_CODE status;
+
+        // Set bit IER::PTIME (Interrupt Enable Register :: Programmable THRE Mode Enable)
+        alt_setbits_word(ALT_UART_IER_DLH_ADDR(handle->location), ALT_UART_IER_DLH_PTIME_DLH7_SET_MSK);
+
+        // Set the line configuration to use 8-N-1.
+        status = alt_16550_line_config_set(handle, ALT_16550_DATABITS_8,
+                                                   ALT_16550_PARITY_DISABLE,
+                                                   ALT_16550_STOPBITS_1);
+        if (status != ALT_E_SUCCESS)
+        {
+            return status;
+        }
+
+        uint32_t divisor = ALT_16550_HANDLE_DATA_DIVISOR_VALUE_GET(handle->data);
+        if (divisor == 0)
+        {
+            // Set the default baudrate to 57600.
+            status = alt_16550_baudrate_set(handle, ALT_16550_BAUDRATE_57600);
+            if (status != ALT_E_SUCCESS)
+            {
+                return status;
+            }
+        }
+    }
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_16550_init(ALT_16550_DEVICE_t device,
+                               void * location,
+                               alt_freq_t clock_freq,
+                               ALT_16550_HANDLE_t * handle)
+{
+    handle->device = device;
+    handle->data   = 0;
+    handle->fcr    = 0;
+
+    switch (device)
+    {
+    case ALT_16550_DEVICE_SOCFPGA_UART0:
+    case ALT_16550_DEVICE_SOCFPGA_UART1:
+        // The ALT_CLK_L4_SP is required for all SoCFPGA UARTs. Check that it's enabled.
+        if (alt_clk_is_enabled(ALT_CLK_L4_SP) != ALT_E_TRUE)
+        {
+            return ALT_E_BAD_CLK;
+        }
+        else
+        {
+            ALT_STATUS_CODE status;
+            status = alt_clk_freq_get(ALT_CLK_L4_SP, &handle->clock_freq);
+            if (status != ALT_E_SUCCESS)
+            {
+                return status;
+            }
+
+            if (device == ALT_16550_DEVICE_SOCFPGA_UART0)
+            {
+                handle->location = ALT_UART0_ADDR;
+
+                // Bring UART0 out of reset.
+                alt_clrbits_word(ALT_RSTMGR_PERMODRST_ADDR, ALT_RSTMGR_PERMODRST_UART0_SET_MSK);
+            }
+            else // device == ALT_16550_DEVICE_SOCFPGA_UART1
+            {
+                handle->location = ALT_UART1_ADDR;
+
+                // Bring UART1 out of reset.
+                alt_clrbits_word(ALT_RSTMGR_PERMODRST_ADDR, ALT_RSTMGR_PERMODRST_UART1_SET_MSK);
+            } 
+
+            // Verify the UCR (UART Component Version)
+            uint32_t ucr = alt_read_word(ALT_UART_UCV_ADDR(handle->location));
+            if (ucr != ALT_UART_UCV_UART_COMPONENT_VER_RESET)
+            {
+                return ALT_E_ERROR;
+            }
+        }
+        break;
+    case ALT_16550_DEVICE_ALTERA_16550_UART:
+        handle->location   = location;
+        handle->clock_freq = clock_freq;
+        break;
+    default:
+        return ALT_E_BAD_ARG;
+    }
+
+    return alt_16550_reset_helper(handle, true);
+}
+
+ALT_STATUS_CODE alt_16550_uninit(ALT_16550_HANDLE_t * handle)
+{
+    switch (handle->device)
+    {
+    case ALT_16550_DEVICE_SOCFPGA_UART0:
+        alt_setbits_word(ALT_RSTMGR_PERMODRST_ADDR, ALT_RSTMGR_PERMODRST_UART0_SET_MSK);
+        return ALT_E_SUCCESS;
+    case ALT_16550_DEVICE_SOCFPGA_UART1:
+        alt_setbits_word(ALT_RSTMGR_PERMODRST_ADDR, ALT_RSTMGR_PERMODRST_UART1_SET_MSK);
+        return ALT_E_SUCCESS;
+    case ALT_16550_DEVICE_ALTERA_16550_UART:
+    default:
+        return alt_16550_reset_helper(handle, false);
+    }
+}
+
+ALT_STATUS_CODE alt_16550_reset(ALT_16550_HANDLE_t * handle)
+{
+    return alt_16550_reset_helper(handle, true);
+}
+
+ALT_STATUS_CODE alt_16550_enable(ALT_16550_HANDLE_t * handle)
+{
+    // Write the divisor cached in the handle data to the divisor registers.
+    // This will effectively enable the UART.
+    return alt_16550_write_divisor_helper(handle,
+                                          ALT_16550_HANDLE_DATA_DIVISOR_VALUE_GET(handle->data));
+}
+
+ALT_STATUS_CODE alt_16550_disable(ALT_16550_HANDLE_t * handle)
+{
+    // Write 0 to the divisor the divisor registers. This will effectively
+    // disable the UART.
+    return alt_16550_write_divisor_helper(handle, 0);
+}
+
+ALT_STATUS_CODE alt_16550_read(ALT_16550_HANDLE_t * handle,
+                               char * item)
+{
+    // Verify that the UART is enabled
+    if (!(handle->data & ALT_16550_HANDLE_DATA_UART_ENABLED_MSK))
+    {
+        return ALT_E_ERROR;
+    }
+
+    // Verify that the FIFO is disabled
+    if (handle->fcr & ALT_UART_FCR_FIFOE_SET_MSK)
+    {
+        return ALT_E_ERROR;
+    }
+
+    switch (handle->device)
+    {
+    case ALT_16550_DEVICE_SOCFPGA_UART0:
+    case ALT_16550_DEVICE_SOCFPGA_UART1:
+    case ALT_16550_DEVICE_ALTERA_16550_UART:
+        // Read the RBR (Receive Buffer Register) into *item.
+        *item = ALT_UART_RBR_THR_DLL_VALUE_GET(alt_read_word(ALT_UART_RBR_THR_DLL_ADDR(handle->location)));
+        break;
+    default:
+        return ALT_E_ERROR;
+    }
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_16550_write(ALT_16550_HANDLE_t * handle,
+                                char item)
+{
+    // Verify that the UART is enabled
+    if (!(handle->data & ALT_16550_HANDLE_DATA_UART_ENABLED_MSK))
+    {
+        return ALT_E_ERROR;
+    }
+
+    // Verify that the FIFO is disabled
+    if (handle->fcr & ALT_UART_FCR_FIFOE_SET_MSK)
+    {
+        return ALT_E_ERROR;
+    }
+
+    switch (handle->device)
+    {
+    case ALT_16550_DEVICE_SOCFPGA_UART0:
+    case ALT_16550_DEVICE_SOCFPGA_UART1:
+    case ALT_16550_DEVICE_ALTERA_16550_UART:
+        // Write the buffer into the THR (Transmit Holding Register)
+        alt_write_word(ALT_UART_RBR_THR_DLL_ADDR(handle->location), item);
+        break;
+    default:
+        return ALT_E_ERROR;
+    }
+
+    return ALT_E_SUCCESS;
+}
+
+/////
+
+ALT_STATUS_CODE alt_16550_fifo_enable(ALT_16550_HANDLE_t * handle)
+{
+    switch (handle->device)
+    {
+    case ALT_16550_DEVICE_SOCFPGA_UART0:
+    case ALT_16550_DEVICE_SOCFPGA_UART1:
+    case ALT_16550_DEVICE_ALTERA_16550_UART:
+        // Set FCR::FIFOE (FIFO Control Register :: FIFO Enable) bit.
+        handle->fcr |= ALT_UART_FCR_FIFOE_SET_MSK;
+        alt_write_word(ALT_UART_FCR_ADDR(handle->location), handle->fcr);
+        break;
+    default:
+        return ALT_E_ERROR;
+    }
+
+    // No need to reset / clear the FIFOs. This is done automatically when
+    // FCR::FIFOE is changed.
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_16550_fifo_disable(ALT_16550_HANDLE_t * handle)
+{
+    switch (handle->device)
+    {
+    case ALT_16550_DEVICE_SOCFPGA_UART0:
+    case ALT_16550_DEVICE_SOCFPGA_UART1:
+    case ALT_16550_DEVICE_ALTERA_16550_UART:
+        // Clear FCR::FIFOE (FIFO Control Register :: FIFO Enable) bit.
+        handle->fcr &= ~ALT_UART_FCR_FIFOE_SET_MSK;
+        alt_write_word(ALT_UART_FCR_ADDR(handle->location), handle->fcr);
+        break;
+    default:
+        return ALT_E_ERROR;
+    }
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_16550_fifo_read(ALT_16550_HANDLE_t * handle,
+                                    char * buffer,
+                                    size_t count)
+{
+    // Verify that the UART is enabled
+    if (!(handle->data & ALT_16550_HANDLE_DATA_UART_ENABLED_MSK))
+    {
+        return ALT_E_ERROR;
+    }
+
+    // Verify that the FIFO is enabled
+    if (!(handle->fcr & ALT_UART_FCR_FIFOE_SET_MSK))
+    {
+        return ALT_E_ERROR;
+    }
+
+    switch (handle->device)
+    {
+    case ALT_16550_DEVICE_SOCFPGA_UART0:
+    case ALT_16550_DEVICE_SOCFPGA_UART1:
+    case ALT_16550_DEVICE_ALTERA_16550_UART:
+        // Read the RBR (Receive Buffer Register) into the buffer
+        for (size_t i = 0; i < count; ++i)
+        {
+            buffer[i] = ALT_UART_RBR_THR_DLL_VALUE_GET(alt_read_word(ALT_UART_RBR_THR_DLL_ADDR(handle->location)));
+        }
+        break;
+    default:
+        return ALT_E_ERROR;
+    }
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_16550_fifo_write(ALT_16550_HANDLE_t * handle,
+                                     const char * buffer,
+                                     size_t count)
+{
+    // Verify that the UART is enabled
+    if (!(handle->data & ALT_16550_HANDLE_DATA_UART_ENABLED_MSK))
+    {
+        return ALT_E_ERROR;
+    }
+
+    // Verify that the FIFO is enabled
+    if (!(handle->fcr & ALT_UART_FCR_FIFOE_SET_MSK))
+    {
+        return ALT_E_ERROR;
+    }
+
+    switch (handle->device)
+    {
+    case ALT_16550_DEVICE_SOCFPGA_UART0:
+    case ALT_16550_DEVICE_SOCFPGA_UART1:
+    case ALT_16550_DEVICE_ALTERA_16550_UART:
+        // Write the buffer into the THR (Transmit Holding Register)
+        for (size_t i = 0; i < count; ++i)
+        {
+            alt_write_word(ALT_UART_RBR_THR_DLL_ADDR(handle->location), buffer[i]);
+        }
+        break;
+    default:
+        return ALT_E_ERROR;
+    }
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_16550_fifo_clear_rx(ALT_16550_HANDLE_t * handle)
+{
+    // Verify that the FIFO is enabled
+    if (!(handle->fcr & ALT_UART_FCR_FIFOE_SET_MSK))
+    {
+        return ALT_E_ERROR;
+    }
+
+    switch (handle->device)
+    {
+    case ALT_16550_DEVICE_SOCFPGA_UART0:
+    case ALT_16550_DEVICE_SOCFPGA_UART1:
+        // Write SRR::RFR (Shadow Reset Register :: Receiver FIFO Reset) bit.
+        alt_write_word(ALT_UART_SRR_ADDR(handle->location), ALT_UART_SRR_RFR_SET_MSK);
+        break;
+    case ALT_16550_DEVICE_ALTERA_16550_UART:
+        // Write FCR::RFIFOR (FIFO Control Register :: Receiver FIFO Reset) bit.
+        alt_write_word(ALT_UART_FCR_ADDR(handle->location), handle->fcr | ALT_UART_FCR_RFIFOR_SET_MSK);
+        break;
+    default:
+        return ALT_E_ERROR;
+    }
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_16550_fifo_clear_tx(ALT_16550_HANDLE_t * handle)
+{
+    // Verify that the FIFO is enabled
+    if (!(handle->fcr & ALT_UART_FCR_FIFOE_SET_MSK))
+    {
+        return ALT_E_ERROR;
+    }
+
+    switch (handle->device)
+    {
+    case ALT_16550_DEVICE_SOCFPGA_UART0:
+    case ALT_16550_DEVICE_SOCFPGA_UART1:
+        // Write SRR::XFR (Shadow Reset Register :: Xmitter FIFO Reset) bit.
+        alt_write_word(ALT_UART_SRR_ADDR(handle->location), ALT_UART_SRR_XFR_SET_MSK);
+        break;
+    case ALT_16550_DEVICE_ALTERA_16550_UART:
+        // Write FCR::XFIFOR (FIFO Control Register :: Xmitter FIFO Reset) bit.
+        alt_write_word(ALT_UART_FCR_ADDR(handle->location), handle->fcr | ALT_UART_FCR_XFIFOR_SET_MSK);
+        break;
+    default:
+        return ALT_E_ERROR;
+    }
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_16550_fifo_clear_all(ALT_16550_HANDLE_t * handle)
+{
+    // Verify that the FIFO is enabled
+    if (!(handle->fcr & ALT_UART_FCR_FIFOE_SET_MSK))
+    {
+        return ALT_E_ERROR;
+    }
+
+    switch (handle->device)
+    {
+    case ALT_16550_DEVICE_SOCFPGA_UART0:
+    case ALT_16550_DEVICE_SOCFPGA_UART1:
+        // Write SRR::(RFR | XFR)
+        //   (Shadow Reset Register :: (Receiver FIFO Reset | Xmitter FIFO Reset)) bits.
+        alt_write_word(ALT_UART_SRR_ADDR(handle->location),
+                       ALT_UART_SRR_RFR_SET_MSK | ALT_UART_SRR_XFR_SET_MSK);
+        break;
+    case ALT_16550_DEVICE_ALTERA_16550_UART:
+        // Write FCR::(RFIFOR |XFIFOR)
+        //   (FIFO Control Register :: (Receiver FIFO Reset | Xmitter FIFO Reset)) bits.
+        alt_write_word(ALT_UART_FCR_ADDR(handle->location),
+                       handle->fcr | ALT_UART_FCR_RFIFOR_SET_MSK | ALT_UART_FCR_XFIFOR_SET_MSK);
+        break;
+    default:
+        return ALT_E_ERROR;
+    }
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_16550_fifo_size_get_rx(ALT_16550_HANDLE_t * handle,
+                                           uint32_t * size)
+{
+    switch (handle->device)
+    {
+    case ALT_16550_DEVICE_SOCFPGA_UART0:
+    case ALT_16550_DEVICE_SOCFPGA_UART1:
+        // Read the CPR::FIFO_Mod (Component Parameter Register :: FIFO Mode).
+        // The FIFO size is 16x this value.
+        *size = ALT_UART_CPR_FIFO_MOD_GET(alt_read_word(ALT_UART_CPR_ADDR(handle->location))) << 4;
+        break;
+    case ALT_16550_DEVICE_ALTERA_16550_UART:
+        // Altera 16550 Compatible Soft UARTs have a configurable size and is
+        // stored in the CPR::FIFO_Mode (Component Parameter Register :: FIFO Depth).
+        *size = ALT_ALTERA_16550_CPR_FIFO_MODE_GET(alt_read_word(ALT_ALTERA_16550_CPR_ADDR(handle->location))) << 4;
+        break;
+    default:
+        return ALT_E_ERROR;
+    }
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_16550_fifo_size_get_tx(ALT_16550_HANDLE_t * handle,
+                                           uint32_t * size)
+{
+    switch (handle->device)
+    {
+    case ALT_16550_DEVICE_SOCFPGA_UART0:
+    case ALT_16550_DEVICE_SOCFPGA_UART1:
+        // Read the CPR::FIFO_Mod (Component Parameter Register :: FIFO Mode).
+        // The FIFO size is 16x this value.
+        *size = ALT_UART_CPR_FIFO_MOD_GET(alt_read_word(ALT_UART_CPR_ADDR(handle->location))) << 4;
+        break;
+    case ALT_16550_DEVICE_ALTERA_16550_UART:
+        // Altera 16550 Compatible Soft UARTs have a configurable size and is
+        // stored in the CPR::FIFO_Mode (Component Parameter Register :: FIFO Depth).
+        // The FIFO size is 16x this value.
+        *size = ALT_ALTERA_16550_CPR_FIFO_MODE_GET(alt_read_word(ALT_ALTERA_16550_CPR_ADDR(handle->location))) << 4;
+        break;
+    default:
+        return ALT_E_ERROR;
+    }
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_16550_fifo_level_get_rx(ALT_16550_HANDLE_t * handle,
+                                            uint32_t * level)
+{
+    // Verify that the FIFO is enabled
+    if (!(handle->fcr & ALT_UART_FCR_FIFOE_SET_MSK))
+    {
+        return ALT_E_ERROR;
+    }
+
+    switch (handle->device)
+    {
+    case ALT_16550_DEVICE_SOCFPGA_UART0:
+    case ALT_16550_DEVICE_SOCFPGA_UART1:
+        // Read RFL (Receive FIFO Level).
+        *level = alt_read_word(ALT_UART_RFL_ADDR(handle->location));
+        break;
+    case ALT_16550_DEVICE_ALTERA_16550_UART:
+        // RFL not implemented. Return 0.
+        *level = 0;
+        break;
+    default:
+        return ALT_E_ERROR;
+    }
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_16550_fifo_level_get_tx(ALT_16550_HANDLE_t * handle,
+                                            uint32_t * level)
+{
+    // Verify that the FIFO is enabled
+    if (!(handle->fcr & ALT_UART_FCR_FIFOE_SET_MSK))
+    {
+        return ALT_E_ERROR;
+    }
+
+    switch (handle->device)
+    {
+    case ALT_16550_DEVICE_SOCFPGA_UART0:
+    case ALT_16550_DEVICE_SOCFPGA_UART1:
+        // Read TFL (Transmit FIFO Level).
+        *level = alt_read_word(ALT_UART_TFL_ADDR(handle->location));
+        break;
+    case ALT_16550_DEVICE_ALTERA_16550_UART:
+        // TFL not implemented. Return 0.
+        *level = 0;
+        break;
+    default:
+        return ALT_E_ERROR;
+    }
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_16550_fifo_trigger_set_rx(ALT_16550_HANDLE_t * handle,
+                                              ALT_16550_FIFO_TRIGGER_RX_t trigger)
+{
+    // Verify that the FIFO is enabled
+    if (!(handle->fcr & ALT_UART_FCR_FIFOE_SET_MSK))
+    {
+        return ALT_E_ERROR;
+    }
+
+    // Verify triggering parameter
+    switch (trigger)
+    {
+    case ALT_16550_FIFO_TRIGGER_RX_ANY:
+    case ALT_16550_FIFO_TRIGGER_RX_QUARTER_FULL:
+    case ALT_16550_FIFO_TRIGGER_RX_HALF_FULL:
+    case ALT_16550_FIFO_TRIGGER_RX_ALMOST_FULL:
+        break;
+    default:
+        return ALT_E_BAD_ARG;
+    }
+
+    switch (handle->device)
+    {
+    case ALT_16550_DEVICE_SOCFPGA_UART0:
+    case ALT_16550_DEVICE_SOCFPGA_UART1:
+    case ALT_16550_DEVICE_ALTERA_16550_UART:
+        // Update FCR::RT (FIFO Control Register :: Receiver Trigger)
+        handle->fcr &= ~ALT_UART_FCR_RT_SET_MSK;
+        handle->fcr |= ALT_UART_FCR_RT_SET(trigger);
+        alt_write_word(ALT_UART_FCR_ADDR(handle->location), handle->fcr);
+        break;
+    default:
+        return ALT_E_ERROR;
+    }
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_16550_fifo_trigger_set_tx(ALT_16550_HANDLE_t * handle,
+                                              ALT_16550_FIFO_TRIGGER_TX_t trigger)
+{
+    // Verify that the FIFO is enabled
+    if (!(handle->fcr & ALT_UART_FCR_FIFOE_SET_MSK))
+    {
+        return ALT_E_ERROR;
+    }
+
+    // Verify triggering parameter
+    switch (trigger)
+    {
+    case ALT_16550_FIFO_TRIGGER_TX_EMPTY:
+    case ALT_16550_FIFO_TRIGGER_TX_ALMOST_EMPTY:
+    case ALT_16550_FIFO_TRIGGER_TX_QUARTER_FULL:
+    case ALT_16550_FIFO_TRIGGER_TX_HALF_FULL:
+        break;
+    default:
+        return ALT_E_BAD_ARG;
+    }
+
+    switch (handle->device)
+    {
+    case ALT_16550_DEVICE_SOCFPGA_UART0:
+    case ALT_16550_DEVICE_SOCFPGA_UART1:
+    case ALT_16550_DEVICE_ALTERA_16550_UART:
+        // Update FCR::TET (FIFO Control Register :: Transmit Empty Trigger)
+        handle->fcr &= ~ALT_UART_FCR_TET_SET_MSK;
+        handle->fcr |= ALT_UART_FCR_TET_SET(trigger);
+        alt_write_word(ALT_UART_FCR_ADDR(handle->location), handle->fcr);
+        break;
+    default:
+        return ALT_E_ERROR;
+    }
+
+    return ALT_E_SUCCESS;
+}
+
+/////
+
+ALT_STATUS_CODE alt_16550_baudrate_get(ALT_16550_HANDLE_t * handle,
+                                       uint32_t * baudrate)
+{
+    // Query the divisor cached in the handle data
+    uint32_t divisor = ALT_16550_HANDLE_DATA_DIVISOR_VALUE_GET(handle->data);
+
+    // The divisor should never be zero. It is set to allow for a baud of 57600
+    // on initialization and a valid value is checked at
+    // alt_16550_divisor_set(). We do not check for users altering the data in
+    // the handle structure.
+
+    // Formula for calculating the baudrate:
+    //    baudrate = clock / (16 * divisor)
+
+    *baudrate = (handle->clock_freq >> 4) / divisor;
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_16550_baudrate_set(ALT_16550_HANDLE_t * handle,
+                                       uint32_t baudrate)
+{
+    if (baudrate == 0)
+    {
+        return ALT_E_ARG_RANGE;
+    }
+
+    // Formula for calculating the divisor:
+    //    baudrate = clock / (16 * divisor)
+    // => baudrate * 16 * divisor = clock
+    // => divisor = clock / (baudrate * 16)
+    // => divisor = (clock / 16) / baudrate
+
+    // Add half of the denominator to address rounding errors.
+    uint32_t divisor = ((handle->clock_freq + (8 * baudrate)) / (16 * baudrate));
+
+    // Check for divisor range is in alt_16550_divisor_set().
+    return alt_16550_divisor_set(handle, divisor);
+}
+
+ALT_STATUS_CODE alt_16550_divisor_get(ALT_16550_HANDLE_t * handle,
+                                      uint32_t * divisor)
+{
+    // Just read the divisor portion of the handle data.
+    *divisor = ALT_16550_HANDLE_DATA_DIVISOR_VALUE_GET(handle->data);
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_16550_divisor_set(ALT_16550_HANDLE_t * handle,
+                                      uint32_t divisor)
+{
+    // Verify divisor value is in range.
+    if ((divisor > 0xffff) || (divisor == 0))
+    {
+        return ALT_E_ARG_RANGE;
+    }
+
+    // Set the divisor portion of the handle data.
+    handle->data &= ~(0xffff);
+    handle->data |= divisor;
+
+    // Even if the UART is enabled, don't do anything. It is documented that
+    // the change will take effect when the UART move to the enabled state.
+
+    return ALT_E_SUCCESS;
+}
+
+/////
+
+static ALT_STATUS_CODE alt_16550_ier_mask_set_helper(ALT_16550_HANDLE_t * handle, uint32_t setmask)
+{
+    switch (handle->device)
+    {
+    case ALT_16550_DEVICE_SOCFPGA_UART0:
+    case ALT_16550_DEVICE_SOCFPGA_UART1:
+    case ALT_16550_DEVICE_ALTERA_16550_UART:
+        // Set bit in IER (Interrupt Enable Register)
+        alt_setbits_word(ALT_UART_IER_DLH_ADDR(handle->location), setmask);
+        break;
+    default:
+        return ALT_E_ERROR;
+    }
+
+    return ALT_E_SUCCESS;
+}
+
+static ALT_STATUS_CODE alt_16550_ier_mask_clr_helper(ALT_16550_HANDLE_t * handle, uint32_t setmask)
+{
+    switch (handle->device)
+    {
+    case ALT_16550_DEVICE_SOCFPGA_UART0:
+    case ALT_16550_DEVICE_SOCFPGA_UART1:
+    case ALT_16550_DEVICE_ALTERA_16550_UART:
+        // Clear bit in IER (Interrupt Enable Register)
+        alt_clrbits_word(ALT_UART_IER_DLH_ADDR(handle->location), setmask);
+        break;
+    default:
+        return ALT_E_ERROR;
+    }
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_16550_int_enable_rx(ALT_16550_HANDLE_t * handle)
+{
+    // Set the IER::ERBFI (Interrupt Enable Register :: Enable Receive Buffer Full Interrupt) bit.
+    return alt_16550_ier_mask_set_helper(handle, ALT_UART_IER_DLH_ERBFI_DLH0_SET_MSK);
+}
+
+ALT_STATUS_CODE alt_16550_int_disable_rx(ALT_16550_HANDLE_t * handle)
+{
+    // Clear the IER::ERBFI (Interrupt Enable Register :: Enable Receive Buffer Full Interrupt) bit.
+    return alt_16550_ier_mask_clr_helper(handle, ALT_UART_IER_DLH_ERBFI_DLH0_SET_MSK);
+}
+
+ALT_STATUS_CODE alt_16550_int_enable_tx(ALT_16550_HANDLE_t * handle)
+{
+    // Set the IER::ETBEI (Interrupt Enable Register :: Enable Transmit Buffer Empty Interrupt) bit.
+    return alt_16550_ier_mask_set_helper(handle, ALT_UART_IER_DLH_ETBEI_DLH1_SET_MSK);
+}
+
+ALT_STATUS_CODE alt_16550_int_disable_tx(ALT_16550_HANDLE_t * handle)
+{
+    // Clear the IER::ETBEI (Interrupt Enable Register :: Enable Transmit Buffer Empty Interrupt) bit.
+    return alt_16550_ier_mask_clr_helper(handle, ALT_UART_IER_DLH_ETBEI_DLH1_SET_MSK);
+}
+
+ALT_STATUS_CODE alt_16550_int_enable_line(ALT_16550_HANDLE_t * handle)
+{
+    // Set the IER::ELSI (Interrupt Enable Register :: Enable Line Status Interrupt) bit.
+    return alt_16550_ier_mask_set_helper(handle, ALT_UART_IER_DLH_ELSI_DHL2_SET_MSK);
+}
+
+ALT_STATUS_CODE alt_16550_int_disable_line(ALT_16550_HANDLE_t * handle)
+{
+    // Clear the IER::ELSI (Interrupt Enable Register :: Enable Line Status Interrupt) bit.
+    return alt_16550_ier_mask_clr_helper(handle, ALT_UART_IER_DLH_ELSI_DHL2_SET_MSK);
+}
+
+ALT_STATUS_CODE alt_16550_int_enable_modem(ALT_16550_HANDLE_t * handle)
+{
+    // Set the IER::EDSSI (Interrupt Enable Register :: Enable Modem Status Interrupt) bit.
+    return alt_16550_ier_mask_set_helper(handle, ALT_UART_IER_DLH_EDSSI_DHL3_SET_MSK);
+}
+
+ALT_STATUS_CODE alt_16550_int_disable_modem(ALT_16550_HANDLE_t * handle)
+{
+    // Clear the IER::EDSSI (Interrupt Enable Register :: Enable Modem Status Interrupt) bit.
+    return alt_16550_ier_mask_clr_helper(handle, ALT_UART_IER_DLH_EDSSI_DHL3_SET_MSK);
+}
+
+ALT_STATUS_CODE alt_16550_int_disable_all(ALT_16550_HANDLE_t * handle)
+{
+    // Clear the IER::(ERBFI | ETBEI | ELSI | EDSSI)
+    //   (Interrupt Enable Register :: (Enable Receive Buffer Full Interrupt   |
+    //                                  Enable Transmit Buffer Empty Interrupt |
+    //                                  Enable Line Status Interrupt           |
+    //                                  Enable Modem Status Interrupt)) bits
+    return alt_16550_ier_mask_clr_helper(handle, ALT_UART_IER_DLH_ERBFI_DLH0_SET_MSK |
+                                                 ALT_UART_IER_DLH_ETBEI_DLH1_SET_MSK |
+                                                 ALT_UART_IER_DLH_ELSI_DHL2_SET_MSK  |
+                                                 ALT_UART_IER_DLH_EDSSI_DHL3_SET_MSK);
+}
+
+ALT_STATUS_CODE alt_16550_int_status_get(ALT_16550_HANDLE_t * handle,
+                                         ALT_16550_INT_STATUS_t * status)
+{
+    switch (handle->device)
+    {
+    case ALT_16550_DEVICE_SOCFPGA_UART0:
+    case ALT_16550_DEVICE_SOCFPGA_UART1:
+    case ALT_16550_DEVICE_ALTERA_16550_UART:
+        // Read IIR::IID (Interrupt Identity Register :: Interrupt ID)
+        *status = (ALT_16550_INT_STATUS_t) ALT_UART_IIR_ID_GET(alt_read_word(ALT_UART_IIR_ADDR(handle->location)));
+        break;
+    default:
+        return ALT_E_ERROR;
+    }
+
+    return ALT_E_SUCCESS;
+}
+
+/////
+
+ALT_STATUS_CODE alt_16550_line_config_set(ALT_16550_HANDLE_t * handle,
+                                          ALT_16550_DATABITS_t databits,
+                                          ALT_16550_PARITY_t parity,
+                                          ALT_16550_STOPBITS_t stopbits)
+{
+    // Validate the databits parameter.
+    switch (databits)
+    {
+    case ALT_16550_DATABITS_5:
+    case ALT_16550_DATABITS_6:
+    case ALT_16550_DATABITS_7:
+    case ALT_16550_DATABITS_8:
+        break;
+    default:
+        return ALT_E_ERROR;
+    }
+
+    // Validate the parity parameter.
+    switch (parity)
+    {
+    case ALT_16550_PARITY_DISABLE:
+    case ALT_16550_PARITY_ODD:
+    case ALT_16550_PARITY_EVEN:
+        break;
+    default:
+        return ALT_E_ERROR;
+    }
+
+    // Validate the stopbits parameter.
+    switch (stopbits)
+    {
+    case ALT_16550_STOPBITS_1:
+    case ALT_16550_STOPBITS_2:
+        break;
+    default:
+        return ALT_E_ERROR;
+    }
+
+    // LCR (Line Control Register) cache.
+    uint32_t lcr = 0;
+
+    switch (handle->device)
+    {
+    case ALT_16550_DEVICE_SOCFPGA_UART0:
+    case ALT_16550_DEVICE_SOCFPGA_UART1:
+    case ALT_16550_DEVICE_ALTERA_16550_UART:
+
+        // Configure the number of databits
+        lcr |= ALT_UART_LCR_DLS_SET(databits);
+
+        // Configure the number of stopbits
+        lcr |= ALT_UART_LCR_STOP_SET(stopbits);
+
+        // Configure the parity
+        if (parity != ALT_16550_PARITY_DISABLE)
+        {
+            // Enable parity in LCR
+            lcr |= ALT_UART_LCR_PEN_SET_MSK;
+
+            if (parity == ALT_16550_PARITY_EVEN)
+            {
+                // Enable even parity in LCR; otherwise it's odd parity.
+                lcr |= ALT_UART_LCR_EPS_SET_MSK;
+            }
+        }
+
+        // Update LCR (Line Control Register)
+        alt_replbits_word(ALT_UART_LCR_ADDR(handle->location), 
+                          ALT_UART_LCR_DLS_SET_MSK
+                        | ALT_UART_LCR_STOP_SET_MSK
+                        | ALT_UART_LCR_PEN_SET_MSK
+                        | ALT_UART_LCR_EPS_SET_MSK,
+                        lcr);
+
+        break;
+
+    default:
+        return ALT_E_ERROR;
+    }
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_16550_line_break_enable(ALT_16550_HANDLE_t * handle)
+{
+    switch (handle->device)
+    {
+    case ALT_16550_DEVICE_SOCFPGA_UART0:
+    case ALT_16550_DEVICE_SOCFPGA_UART1:
+    case ALT_16550_DEVICE_ALTERA_16550_UART:
+        // Set the LCR::Break (Line Control Register :: Break) bit.
+        alt_setbits_word(ALT_UART_LCR_ADDR(handle->location), ALT_UART_LCR_BREAK_SET_MSK);
+        break;
+
+    default:
+        return ALT_E_ERROR;
+    }
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_16550_line_break_disable(ALT_16550_HANDLE_t * handle)
+{
+    switch (handle->device)
+    {
+    case ALT_16550_DEVICE_SOCFPGA_UART0:
+    case ALT_16550_DEVICE_SOCFPGA_UART1:
+    case ALT_16550_DEVICE_ALTERA_16550_UART:
+        // Clear the LCR::Break (Line Control Register :: Break) bit.
+        alt_clrbits_word(ALT_UART_LCR_ADDR(handle->location), ALT_UART_LCR_BREAK_SET_MSK);
+        break;
+
+    default:
+        return ALT_E_ERROR;
+    }
+
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_16550_line_status_get(ALT_16550_HANDLE_t * handle,
+                                          uint32_t * status)
+{
+    switch (handle->device)
+    {
+    case ALT_16550_DEVICE_SOCFPGA_UART0:
+    case ALT_16550_DEVICE_SOCFPGA_UART1:
+    case ALT_16550_DEVICE_ALTERA_16550_UART:
+        // Read the LSR (Line Status Register).
+        *status = alt_read_word(ALT_UART_LSR_ADDR(handle->location));
+        break;
+    default:
+        return ALT_E_ERROR;
+    }
+
+    return ALT_E_SUCCESS;
+}
+
+/////
+
+static ALT_STATUS_CODE alt_16550_mcr_mask_set_helper(ALT_16550_HANDLE_t * handle,
+                                                     uint32_t setmask)
+{
+    switch (handle->device)
+    {
+    case ALT_16550_DEVICE_SOCFPGA_UART0:
+    case ALT_16550_DEVICE_SOCFPGA_UART1:
+    case ALT_16550_DEVICE_ALTERA_16550_UART:
+        // Set the bit in MCR (Modem Control Register).
+        alt_setbits_word(ALT_UART_MCR_ADDR(handle->location), setmask);
+        break;
+    default:
+        return ALT_E_ERROR;
+    }
+
+    return ALT_E_SUCCESS;
+}
+
+static ALT_STATUS_CODE alt_16550_mcr_mask_clr_helper(ALT_16550_HANDLE_t * handle, uint32_t setmask)
+{
+    switch (handle->device)
+    {
+    case ALT_16550_DEVICE_SOCFPGA_UART0:
+    case ALT_16550_DEVICE_SOCFPGA_UART1:
+    case ALT_16550_DEVICE_ALTERA_16550_UART:
+        // Clear the bit in MCR (Modem Control Register).
+        alt_clrbits_word(ALT_UART_MCR_ADDR(handle->location), setmask);
+        break;
+    default:
+        return ALT_E_ERROR;
+    }
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_16550_flowcontrol_enable(ALT_16550_HANDLE_t * handle)
+{
+    // Verify that the FIFO is enabled
+    if (!(handle->fcr & ALT_UART_FCR_FIFOE_SET_MSK))
+    {
+        return ALT_E_ERROR;
+    }
+
+    // For the Altera 16550 Compatible Soft UART, check that Hardware Flowcontrol is enabled.
+    if (handle->device == ALT_16550_DEVICE_ALTERA_16550_UART)
+    {
+        // Read the CPR::AFCE_Mode (Component Parameter Register :: Auto Flow Control mode) bit.
+        uint32_t cpr = alt_read_word(ALT_ALTERA_16550_CPR_ADDR(handle->location));
+        if (!(ALT_ALTERA_16550_CPR_AFCE_MODE_SET_MSK & cpr))
+        {
+            return ALT_E_ERROR;
+        }
+    }
+
+    // Set MCR::AFCE (Modem Control Register :: Automatic FlowControl Enable) bit.
+    return alt_16550_mcr_mask_set_helper(handle, ALT_UART_MCR_AFCE_SET_MSK);
+}
+
+ALT_STATUS_CODE alt_16550_flowcontrol_disable(ALT_16550_HANDLE_t * handle)
+{
+    // Clear MCR::AFCE (Modem Control Register :: Automatic FlowControl Enable) bit.
+    return alt_16550_mcr_mask_clr_helper(handle, ALT_UART_MCR_AFCE_SET_MSK);
+}
+
+ALT_STATUS_CODE alt_16550_loopback_enable(ALT_16550_HANDLE_t * handle)
+{
+    // Loopback is not implemented in the Altera 16550 Compatible Soft UART.
+    if (handle->device == ALT_16550_DEVICE_ALTERA_16550_UART)
+    {
+        return ALT_E_ERROR;
+    }
+
+    // Set MCR::Loopback (Modem Control Register :: Loopback) bit.
+    return alt_16550_mcr_mask_set_helper(handle, ALT_UART_MCR_LOOPBACK_SET_MSK);
+}
+
+ALT_STATUS_CODE alt_16550_loopback_disable(ALT_16550_HANDLE_t * handle)
+{
+    // Clear MCR::Loopback (Modem Control Register :: Loopback) bit.
+    return alt_16550_mcr_mask_clr_helper(handle, ALT_UART_MCR_LOOPBACK_SET_MSK);
+}
+
+ALT_STATUS_CODE alt_16550_modem_enable_out1(ALT_16550_HANDLE_t * handle)
+{
+    // Set MCR::Out1 (Modem Control Register :: Out1) bit.
+    return alt_16550_mcr_mask_set_helper(handle, ALT_UART_MCR_OUT1_SET_MSK);
+}
+
+ALT_STATUS_CODE alt_16550_modem_disable_out1(ALT_16550_HANDLE_t * handle)
+{
+    // Clear MCR::Out1 (Modem Control Register :: Out1) bit.
+    return alt_16550_mcr_mask_clr_helper(handle, ALT_UART_MCR_OUT1_SET_MSK);
+}
+
+ALT_STATUS_CODE alt_16550_modem_enable_out2(ALT_16550_HANDLE_t * handle)
+{
+    // Set MCR::Out2 (Modem Control Register :: Out2) bit.
+    return alt_16550_mcr_mask_set_helper(handle, ALT_UART_MCR_OUT2_SET_MSK);
+}
+
+ALT_STATUS_CODE alt_16550_modem_disable_out2(ALT_16550_HANDLE_t * handle)
+{
+    // Clear MCR::Out2 (Modem Control Register :: Out2) bit.
+    return alt_16550_mcr_mask_clr_helper(handle, ALT_UART_MCR_OUT2_SET_MSK);
+}
+
+ALT_STATUS_CODE alt_16550_modem_enable_rts(ALT_16550_HANDLE_t * handle)
+{
+    // Set MCR::RTS (Modem Control Register :: Request To Send) bit.
+    return alt_16550_mcr_mask_set_helper(handle, ALT_UART_MCR_RTS_SET_MSK);
+}
+
+ALT_STATUS_CODE alt_16550_modem_disable_rts(ALT_16550_HANDLE_t * handle)
+{
+    // Clear MCR::RTS (Modem Control Register :: Request To Send) bit.
+    return alt_16550_mcr_mask_clr_helper(handle, ALT_UART_MCR_RTS_SET_MSK);
+}
+
+ALT_STATUS_CODE alt_16550_modem_enable_dtr(ALT_16550_HANDLE_t * handle)
+{
+    // Set MCR::DTR (Modem Control Register :: Data Terminal Ready) bit.
+    return alt_16550_mcr_mask_set_helper(handle, ALT_UART_MCR_DTR_SET_MSK);
+}
+
+ALT_STATUS_CODE alt_16550_modem_disable_dtr(ALT_16550_HANDLE_t * handle)
+{
+    // Clear MCR::DTR (Modem Control Register :: Data Terminal Ready) bit.
+    return alt_16550_mcr_mask_clr_helper(handle, ALT_UART_MCR_DTR_SET_MSK);
+}
+
+ALT_STATUS_CODE alt_16550_modem_status_get(ALT_16550_HANDLE_t * handle,
+                                          uint32_t * status)
+{
+    switch (handle->device)
+    {
+    case ALT_16550_DEVICE_SOCFPGA_UART0:
+    case ALT_16550_DEVICE_SOCFPGA_UART1:
+    case ALT_16550_DEVICE_ALTERA_16550_UART:
+        // Read the MSR (Modem Status Register).
+        *status = alt_read_word(ALT_UART_MSR_ADDR(handle->location));
+        break;
+    default:
+        return ALT_E_ERROR;
+    }
+
+    return ALT_E_SUCCESS;
+}
diff --git a/c/src/lib/libbsp/arm/altera-cyclone-v/hwlib/src/hwmgr/alt_dma.c b/c/src/lib/libbsp/arm/altera-cyclone-v/hwlib/src/hwmgr/alt_dma.c
new file mode 100644
index 0000000..2bdc519
--- /dev/null
+++ b/c/src/lib/libbsp/arm/altera-cyclone-v/hwlib/src/hwmgr/alt_dma.c
@@ -0,0 +1,3749 @@
+/******************************************************************************
+ *
+ * Copyright 2013 Altera Corporation. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ ******************************************************************************/
+
+#include <stdio.h>
+#include "alt_dma.h"
+#include "socal/socal.h"
+#include "socal/hps.h"
+#include "socal/alt_rstmgr.h"
+#include "socal/alt_sysmgr.h"
+
+#if ALT_DMA_PERIPH_PROVISION_16550_SUPPORT
+#include "alt_16550_uart.h"
+#include "socal/alt_uart.h"
+#endif
+
+#if ALT_DMA_PERIPH_PROVISION_QSPI_SUPPORT
+#include "socal/alt_qspi.h"
+#endif
+
+/////
+
+#ifndef MIN
+#define MIN(a, b) ((a) > (b) ? (b) : (a))
+#endif // MIN
+
+#ifndef ARRAY_COUNT
+#define ARRAY_COUNT(array) (sizeof(array) / sizeof(array[0]))
+#endif
+
+// NOTE: To enable debugging output, delete the next line and uncomment the
+//   line after.
+#define dprintf(...)
+// #define dprintf(fmt, ...) printf(fmt, ##__VA_ARGS__)
+
+/////
+
+//
+// SoCAL stand in for DMA Controller registers
+//
+// The base can be one of the following: 
+//  - ALT_DMANONSECURE_ADDR
+//  - ALT_DMASECURE_ADDR
+//
+// Macros which have a channel parameter does no validation.
+//
+
+// DMA Manager Status Register
+#define ALT_DMA_DSR_OFST 0x0
+#define ALT_DMA_DSR_ADDR(base) ALT_CAST(void *, (ALT_CAST(char *, (base)) + ALT_DMA_DSR_OFST))
+#define ALT_DMA_DSR_DMASTATUS_SET_MSK 0x0000000f
+#define ALT_DMA_DSR_DMASTATUS_GET(value) ((value) & 0x0000000f)
+
+// DMA Program Counter Register
+#define ALT_DMA_DPC_OFST 0x4
+#define ALT_DMA_DPC_ADDR(base) ALT_CAST(void *, (ALT_CAST(char *, (base)) + ALT_DMA_DPC_OFST))
+
+// Interrupt Enable Register
+#define ALT_DMA_INTEN_OFST 0x20
+#define ALT_DMA_INTEN_ADDR(base) ALT_CAST(void *, (ALT_CAST(char *, (base)) + ALT_DMA_INTEN_OFST))
+
+// Event-Interrupt Raw Status Register
+#define ALT_DMA_INT_EVENT_RIS_OFST 0x24
+#define ALT_DMA_INT_EVENT_RIS_ADDR(base) ALT_CAST(void *, (ALT_CAST(char *, (base)) + ALT_DMA_INT_EVENT_RIS_OFST))
+
+// Interrupt Status Register
+#define ALT_DMA_INTMIS_OFST 0x28
+#define ALT_DMA_INTMIS_ADDR(base) ALT_CAST(void *, (ALT_CAST(char *, (base)) + ALT_DMA_INTMIS_OFST))
+
+// Interrupt Clear Register
+#define ALT_DMA_INTCLR_OFST 0x2c
+#define ALT_DMA_INTCLR_ADDR(base) ALT_CAST(void *, (ALT_CAST(char *, (base)) + ALT_DMA_INTCLR_OFST))
+
+// Fault Status DMA Manager Register
+#define ALT_DMA_FSRD_OFST 0x30
+#define ALT_DMA_FSRD_ADDR(base) ALT_CAST(void *, (ALT_CAST(char *, (base)) + ALT_DMA_FSRD_OFST))
+
+// Fault Status DMA Channel Register
+#define ALT_DMA_FSRC_OFST 0x34
+#define ALT_DMA_FSRC_ADDR(base) ALT_CAST(void *, (ALT_CAST(char *, (base)) + ALT_DMA_FSRC_OFST))
+
+// Fault Type DMA Manager Register
+#define ALT_DMA_FTRD_OFST 0x38
+#define ALT_DMA_FTRD_ADDR(base) ALT_CAST(void *, (ALT_CAST(char *, (base)) + ALT_DMA_FSRD_OFST))
+
+// Fault Type DMA Channel Registers
+#define ALT_DMA_FTRx_OFST(channel) (0x40 + 0x4 * (channel))
+#define ALT_DMA_FTRx_ADDR(base, channel) ALT_CAST(void *, (ALT_CAST(char *, (base)) + ALT_DMA_FTRx_OFST(channel)))
+
+// Channel Status Registers
+#define ALT_DMA_CSRx_OFST(channel) (0x100 + 0x8 * (channel))
+#define ALT_DMA_CSRx_ADDR(base, channel) ALT_CAST(void *, (ALT_CAST(char *, (base)) + ALT_DMA_CSRx_OFST(channel)))
+#define ALT_DMA_CSRx_CHANNELSTATUS_SET_MSK 0x0000000f
+#define ALT_DMA_CSRx_CHANNELSTATUS_GET(value) ((value) & 0x0000000f)
+
+// Channel Program Counter Registers
+#define ALT_DMA_CPCx_OFST(channel) (0x104 + 0x8 * (channel))
+#define ALT_DMA_CPCx_ADDR(base, channel) ALT_CAST(void *, (ALT_CAST(char *, (base)) + ALT_DMA_CPCx_OFST(channel)))
+
+// Source Address Registers
+#define ALT_DMA_SARx_OFST(channel) (0x400 + 0x20 * (channel))
+#define ALT_DMA_SARx_ADDR(base, channel) ALT_CAST(void *, (ALT_CAST(char *, (base)) + ALT_DMA_SARx_OFST(channel)))
+
+// Destination Address Registers
+#define ALT_DMA_DARx_OFST(channel) (0x404 + 0x20 * (channel))
+#define ALT_DMA_DARx_ADDR(base, channel) ALT_CAST(void *, (ALT_CAST(char *, (base)) + ALT_DMA_DARx_OFST(channel)))
+
+// Channel Control Registers
+#define ALT_DMA_CCRx_OFST(channel) (0x408 + 0x20 * (channel))
+#define ALT_DMA_CCRx_ADDR(base, channel) ALT_CAST(void *, (ALT_CAST(char *, (base)) + ALT_DMA_CCRx_OFST(channel)))
+
+// Loop Counter 0 Registers
+#define ALT_DMA_LC0_x_OFST(channel) (0x40c + 0x20 * (channel))
+#define ALT_DMA_LC0_x_ADDR(base, channel) ALT_CAST(void *, (ALT_CAST(char *, (base)) + ALT_DMA_LC0_x_OFST(channel)))
+
+// Loop Counter 1 Registers
+#define ALT_DMA_LC1_x_OFST(channel) (0x410 + 0x20 * (channel))
+#define ALT_DMA_LC1_x_ADDR(base, channel) ALT_CAST(void *, (ALT_CAST(char *, (base)) + ALT_DMA_LC1_x_OFST(channel)))
+
+// Debug Status Register
+#define ALT_DMA_DBGSTATUS_OFST 0xd00
+#define ALT_DMA_DBGSTATUS_ADDR(base) ALT_CAST(void *, (ALT_CAST(char *, (base)) + ALT_DMA_DBGSTATUS_OFST))
+
+// Debug Command Register
+#define ALT_DMA_DBGCMD_OFST 0xd04
+#define ALT_DMA_DBGCMD_ADDR(base) ALT_CAST(void *, (ALT_CAST(char *, (base)) + ALT_DMA_DBGCMD_OFST))
+
+// Debug Instruction-0 Register
+#define ALT_DMA_DBGINST0_OFST 0xd08
+#define ALT_DMA_DBGINST0_ADDR(base) ALT_CAST(void *, (ALT_CAST(char *, (base)) + ALT_DMA_DBGINST0_OFST))
+#define ALT_DMA_DBGINST0_CHANNELNUMBER_SET(value) (((value) & 0x7) << 8)
+#define ALT_DMA_DBGINST0_DEBUGTHREAD_SET(value) ((value) & 0x1)
+#define ALT_DMA_DBGINST0_DEBUGTHREAD_E_MANAGER 0
+#define ALT_DMA_DBGINST0_DEBUGTHREAD_E_CHANNEL 1
+#define ALT_DMA_DBGINST0_INSTRUCTIONBYTE0_SET(value) (((value) & 0xff) << 16)
+#define ALT_DMA_DBGINST0_INSTRUCTIONBYTE1_SET(value) (((value) & 0xff) << 24)
+
+// Debug Instruction-1 Register
+#define ALT_DMA_DBGINST1_OFST 0xd0c
+#define ALT_DMA_DBGINST1_ADDR(base) ALT_CAST(void *, (ALT_CAST(char *, (base)) + ALT_DMA_DBGINST1_OFST))
+
+// Configuration Registers 0 - 4
+#define ALT_DMA_CR0_OFST 0xe00
+#define ALT_DMA_CR1_OFST 0xe04
+#define ALT_DMA_CR2_OFST 0xe08
+#define ALT_DMA_CR3_OFST 0xe0c
+#define ALT_DMA_CR4_OFST 0xe10
+#define ALT_DMA_CR0_ADDR(base) ALT_CAST(void *, (ALT_CAST(char *, (base)) + ALT_DMA_CR0_OFST))
+#define ALT_DMA_CR1_ADDR(base) ALT_CAST(void *, (ALT_CAST(char *, (base)) + ALT_DMA_CR1_OFST))
+#define ALT_DMA_CR2_ADDR(base) ALT_CAST(void *, (ALT_CAST(char *, (base)) + ALT_DMA_CR2_OFST))
+#define ALT_DMA_CR3_ADDR(base) ALT_CAST(void *, (ALT_CAST(char *, (base)) + ALT_DMA_CR3_OFST))
+#define ALT_DMA_CR4_ADDR(base) ALT_CAST(void *, (ALT_CAST(char *, (base)) + ALT_DMA_CR4_OFST))
+
+// DMA Configuration Register
+#define ALT_DMA_CRD_OFST 0xe14
+#define ALT_DMA_CRD_ADDR(base) ALT_CAST(void *, (ALT_CAST(char *, (base)) + ALT_DMA_CRD_OFST))
+
+// Watchdog Register
+#define ALT_DMA_WD_OFST 0xe80
+#define ALT_DMA_WD_ADDR(base) ALT_CAST(void *, (ALT_CAST(char *, (base)) + ALT_DMA_WD_OFST))
+
+/////
+
+//
+// Internal Data structures
+//
+
+// This flag marks the channel as being allocated.
+#define ALT_DMA_CHANNEL_INFO_FLAG_ALLOCED (1 << 0)
+
+typedef struct ALT_DMA_CHANNEL_INFO_s
+{
+    uint8_t flag;
+}
+ALT_DMA_CHANNEL_INFO_t;
+
+static ALT_DMA_CHANNEL_INFO_t channel_info_array[8];
+
+/////
+
+ALT_STATUS_CODE alt_dma_init(const ALT_DMA_CFG_t * dma_cfg)
+{
+    // Initialize the channel information array
+    for (int i = 0; i < 8; ++i)
+    {
+        channel_info_array[i].flag = 0;
+    }
+
+    // Update the System Manager DMA configuration items
+    
+    uint32_t dmactrl = 0;
+
+    // Handle FPGA / CAN muxing
+    for (int i = 0; i < 4; ++i)
+    {
+        // The default is FPGA.
+        switch (dma_cfg->periph_mux[i])
+        {
+        case ALT_DMA_PERIPH_MUX_DEFAULT:
+        case ALT_DMA_PERIPH_MUX_FPGA:
+            break;
+        case ALT_DMA_PERIPH_MUX_CAN:
+            dmactrl |= (ALT_SYSMGR_DMA_CTL_CHANSEL_0_SET_MSK << i);
+            break;
+        default:
+            return ALT_E_ERROR;
+        }
+    }
+
+    // Handle Manager security
+    // Default is Secure state.
+    switch (dma_cfg->manager_sec)
+    {
+    case ALT_DMA_SECURITY_DEFAULT:
+    case ALT_DMA_SECURITY_SECURE:
+        break;
+    case ALT_DMA_SECURITY_NONSECURE:
+        dmactrl |= ALT_SYSMGR_DMA_CTL_MGRNONSECURE_SET_MSK;
+        break;
+    default:
+        return ALT_E_ERROR;
+    }
+
+    // Handle IRQ security
+    for (int i = 0; i < ALT_SYSMGR_DMA_CTL_IRQNONSECURE_WIDTH; ++i)
+    {
+        // Default is Secure state.
+        switch (dma_cfg->irq_sec[i])
+        {
+        case ALT_DMA_SECURITY_DEFAULT:
+        case ALT_DMA_SECURITY_SECURE:
+            break;
+        case ALT_DMA_SECURITY_NONSECURE:
+            dmactrl |= (1 << (i + ALT_SYSMGR_DMA_CTL_IRQNONSECURE_LSB));
+            break;
+        default:
+            return ALT_E_ERROR;
+        }
+    }
+
+    alt_write_word(ALT_SYSMGR_DMA_CTL_ADDR, dmactrl);
+
+    // Update the System Manager DMA peripheral security items
+
+    uint32_t dmapersecurity = 0;
+
+    for (int i = 0; i < 32; ++i)
+    {
+        // Default is Secure state.
+        switch (dma_cfg->periph_sec[i])
+        {
+        case ALT_DMA_SECURITY_DEFAULT:
+        case ALT_DMA_SECURITY_SECURE:
+            break;
+        case ALT_DMA_SECURITY_NONSECURE:
+            dmapersecurity |= (1 << i);
+            break;
+        default:
+            return ALT_E_ERROR;
+        }
+    }
+
+    alt_write_word(ALT_SYSMGR_DMA_PERSECURITY_ADDR, dmapersecurity);
+
+    // Take DMA out of reset.
+
+    alt_clrbits_word(ALT_RSTMGR_PERMODRST_ADDR, ALT_RSTMGR_PERMODRST_DMA_SET_MSK);
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_dma_uninit(void)
+{
+    // DMAKILL all channel and free all allocated channels.
+    for (int i = 0; i < 8; ++i)
+    {
+        if (channel_info_array[i].flag & ALT_DMA_CHANNEL_INFO_FLAG_ALLOCED)
+        {
+            alt_dma_channel_kill((ALT_DMA_CHANNEL_t)i);
+            alt_dma_channel_free((ALT_DMA_CHANNEL_t)i);
+        }
+    }
+
+    // Put DMA into reset.
+
+    alt_setbits_word(ALT_RSTMGR_PERMODRST_ADDR, ALT_RSTMGR_PERMODRST_DMA_SET_MSK);
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_dma_channel_alloc(ALT_DMA_CHANNEL_t channel)
+{
+    // Validate channel
+    switch (channel)
+    {
+    case ALT_DMA_CHANNEL_0:
+    case ALT_DMA_CHANNEL_1:
+    case ALT_DMA_CHANNEL_2:
+    case ALT_DMA_CHANNEL_3:
+    case ALT_DMA_CHANNEL_4:
+    case ALT_DMA_CHANNEL_5:
+    case ALT_DMA_CHANNEL_6:
+    case ALT_DMA_CHANNEL_7:
+        break;
+    default:
+        return ALT_E_BAD_ARG;
+    }
+
+    // Verify channel is unallocated
+
+    if (channel_info_array[channel].flag & ALT_DMA_CHANNEL_INFO_FLAG_ALLOCED)
+    {
+        return ALT_E_ERROR;
+    }
+
+    // Mark channel as allocated
+
+    channel_info_array[channel].flag |= ALT_DMA_CHANNEL_INFO_FLAG_ALLOCED;
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_dma_channel_alloc_any(ALT_DMA_CHANNEL_t * allocated)
+{
+    // Sweep channel array for unallocated channel
+
+    for (int i = 0; i < 8; ++i)
+    {
+        if (!(channel_info_array[i].flag & ALT_DMA_CHANNEL_INFO_FLAG_ALLOCED))
+        {
+            // Allocate that free channel.
+
+            ALT_STATUS_CODE status = alt_dma_channel_alloc((ALT_DMA_CHANNEL_t)i);
+            if (status == ALT_E_SUCCESS)
+            {
+                *allocated = (ALT_DMA_CHANNEL_t)i;
+            }
+            return status;
+        }
+    }
+
+    // No free channels found.
+
+    return ALT_E_ERROR;
+}
+
+ALT_STATUS_CODE alt_dma_channel_free(ALT_DMA_CHANNEL_t channel)
+{
+    // Validate channel
+    switch (channel)
+    {
+    case ALT_DMA_CHANNEL_0:
+    case ALT_DMA_CHANNEL_1:
+    case ALT_DMA_CHANNEL_2:
+    case ALT_DMA_CHANNEL_3:
+    case ALT_DMA_CHANNEL_4:
+    case ALT_DMA_CHANNEL_5:
+    case ALT_DMA_CHANNEL_6:
+    case ALT_DMA_CHANNEL_7:
+        break;
+    default:
+        return ALT_E_BAD_ARG;
+    }
+
+    // Verify channel is allocated
+
+    if (!(channel_info_array[channel].flag & ALT_DMA_CHANNEL_INFO_FLAG_ALLOCED))
+    {
+        return ALT_E_ERROR;
+    }
+
+    // Verify channel is stopped
+
+    ALT_DMA_CHANNEL_STATE_t state;
+    ALT_STATUS_CODE status = alt_dma_channel_state_get(channel, &state);
+    if (status != ALT_E_SUCCESS)
+    {
+        return status;
+    }
+    if (state != ALT_DMA_CHANNEL_STATE_STOPPED)
+    {
+        return ALT_E_ERROR;
+    }
+
+    // Mark channel as unallocated.
+
+    channel_info_array[channel].flag &= ~ALT_DMA_CHANNEL_INFO_FLAG_ALLOCED;
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_dma_channel_exec(ALT_DMA_CHANNEL_t channel, ALT_DMA_PROGRAM_t * pgm)
+{
+    // Validate channel
+    switch (channel)
+    {
+    case ALT_DMA_CHANNEL_0:
+    case ALT_DMA_CHANNEL_1:
+    case ALT_DMA_CHANNEL_2:
+    case ALT_DMA_CHANNEL_3:
+    case ALT_DMA_CHANNEL_4:
+    case ALT_DMA_CHANNEL_5:
+    case ALT_DMA_CHANNEL_6:
+    case ALT_DMA_CHANNEL_7:
+        break;
+    default:
+        return ALT_E_BAD_ARG;
+    }
+
+    // Verify channel is allocated
+
+    if (!(channel_info_array[channel].flag & ALT_DMA_CHANNEL_INFO_FLAG_ALLOCED))
+    {
+        return ALT_E_ERROR;
+    }
+
+    // Verify channel is stopped
+
+    ALT_DMA_CHANNEL_STATE_t state;
+    ALT_STATUS_CODE status = alt_dma_channel_state_get(channel, &state);
+    if (status != ALT_E_SUCCESS)
+    {
+        return status;
+    }
+    if (state != ALT_DMA_CHANNEL_STATE_STOPPED)
+    {
+        return ALT_E_ERROR;
+    }
+
+    // Validate the program
+
+    if (alt_dma_program_validate(pgm) != ALT_E_SUCCESS)
+    {
+        return ALT_E_ERROR;
+    }
+
+    //
+    // Execute the program
+    //
+
+    // Get the start address
+
+    uint32_t start = (uint32_t) &pgm->program[pgm->buffer_start];
+
+    dprintf("DMA[exec]: pgm->program = %p.\n", pgm->program);
+    dprintf("DMA[exec]: start        = %p.\n", (void *)start);
+
+    // Configure DBGINST0 and DBGINST1 to execute DMAGO targetting the requested channel.
+
+    // For information on APB Interface, see PL330, section 2.5.1.
+    // For information on DBGINSTx, see PL330, section 3.3.20 - 3.3.21.
+    // For information on DMAGO, see PL330, section 4.3.5.
+
+    alt_write_word(ALT_DMA_DBGINST0_ADDR(ALT_DMASECURE_ADDR),
+                   ALT_DMA_DBGINST0_INSTRUCTIONBYTE0_SET(0xa0) | 
+                   ALT_DMA_DBGINST0_INSTRUCTIONBYTE1_SET(channel));
+
+    alt_write_word(ALT_DMA_DBGINST1_ADDR(ALT_DMASECURE_ADDR), start);
+
+    // Execute the instruction held in DBGINST{0,1}
+
+    // For information on DBGCMD, see PL330, section 3.3.19.
+
+    alt_write_word(ALT_DMA_DBGCMD_ADDR(ALT_DMASECURE_ADDR), 0);
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_dma_channel_kill(ALT_DMA_CHANNEL_t channel)
+{
+    // Validate channel
+    switch (channel)
+    {
+    case ALT_DMA_CHANNEL_0:
+    case ALT_DMA_CHANNEL_1:
+    case ALT_DMA_CHANNEL_2:
+    case ALT_DMA_CHANNEL_3:
+    case ALT_DMA_CHANNEL_4:
+    case ALT_DMA_CHANNEL_5:
+    case ALT_DMA_CHANNEL_6:
+    case ALT_DMA_CHANNEL_7:
+        break;
+    default:
+        return ALT_E_BAD_ARG;
+    }
+
+    // Verify channel is allocated
+
+    if (!(channel_info_array[channel].flag & ALT_DMA_CHANNEL_INFO_FLAG_ALLOCED))
+    {
+        return ALT_E_ERROR;
+    }
+
+    // NOTE: Don't worry about the current channel state. Just issue DMAKILL
+    //   instruction. The channel state cannot move from from Stopped back to
+    //   Killing.
+
+    // Configure DBGINST0 to execute DMAKILL on the requested channel thread.
+    // DMAKILL is short enough not to use DBGINST1 register.
+
+    // For information on APB Interface, see PL330, section 2.5.1.
+    // For information on DBGINSTx, see PL330, section 3.3.20 - 3.3.21.
+    // For information on DMAKILL, see PL330, section 4.3.6.
+
+    alt_write_word(ALT_DMA_DBGINST0_ADDR(ALT_DMASECURE_ADDR),
+                   ALT_DMA_DBGINST0_INSTRUCTIONBYTE0_SET(0x1) |
+                   ALT_DMA_DBGINST0_CHANNELNUMBER_SET(channel) |
+                   ALT_DMA_DBGINST0_DEBUGTHREAD_SET(ALT_DMA_DBGINST0_DEBUGTHREAD_E_CHANNEL));
+
+    // Execute the instruction held in DBGINST0
+
+    // For information on DBGCMD, see PL330, section 3.3.19.
+
+    alt_write_word(ALT_DMA_DBGCMD_ADDR(ALT_DMASECURE_ADDR), 0);
+
+    // Wait for channel to move to KILLING or STOPPED state. Do not wait for
+    // the STOPPED only. If the AXI transaction hangs permanently, it can be
+    // waiting indefinately.
+
+    ALT_STATUS_CODE status = ALT_E_SUCCESS;
+    ALT_DMA_CHANNEL_STATE_t current;
+    uint32_t i = 20000;
+
+    while (--i)
+    {
+        status = alt_dma_channel_state_get(channel, &current);
+        if (status != ALT_E_SUCCESS)
+        {
+            break;
+        }
+        if (   (current == ALT_DMA_CHANNEL_STATE_KILLING)
+            || (current == ALT_DMA_CHANNEL_STATE_STOPPED))
+        {
+            break;
+        }
+    }
+
+    if (i == 0)
+    {
+        status = ALT_E_TMO;
+    }
+
+    return status;
+}
+
+ALT_STATUS_CODE alt_dma_channel_reg_get(ALT_DMA_CHANNEL_t channel,
+                                        ALT_DMA_PROGRAM_REG_t reg, uint32_t * val)
+{
+    // Validate channel
+    switch (channel)
+    {
+    case ALT_DMA_CHANNEL_0:
+    case ALT_DMA_CHANNEL_1:
+    case ALT_DMA_CHANNEL_2:
+    case ALT_DMA_CHANNEL_3:
+    case ALT_DMA_CHANNEL_4:
+    case ALT_DMA_CHANNEL_5:
+    case ALT_DMA_CHANNEL_6:
+    case ALT_DMA_CHANNEL_7:
+        break;
+    default:
+        return ALT_E_BAD_ARG;
+    }
+
+    // For information on SAR, see PL330, section 3.3.13.
+    // For information on DAR, see PL330, section 3.3.14.
+    // For information on CCR, see PL330, section 3.3.15.
+
+    switch (reg)
+    {
+    case ALT_DMA_PROGRAM_REG_SAR:
+        *val = alt_read_word(ALT_DMA_SARx_ADDR(ALT_DMASECURE_ADDR, channel));
+        break;
+    case ALT_DMA_PROGRAM_REG_DAR:
+        *val = alt_read_word(ALT_DMA_DARx_ADDR(ALT_DMASECURE_ADDR, channel));
+        break;
+    case ALT_DMA_PROGRAM_REG_CCR:
+        *val = alt_read_word(ALT_DMA_CCRx_ADDR(ALT_DMASECURE_ADDR, channel));
+        break;
+    default:
+        return ALT_E_BAD_ARG;
+    }
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_dma_send_event(ALT_DMA_EVENT_t evt_num)
+{
+    // Validate evt_num
+
+    switch (evt_num)
+    {
+    case ALT_DMA_EVENT_0:
+    case ALT_DMA_EVENT_1:
+    case ALT_DMA_EVENT_2:
+    case ALT_DMA_EVENT_3:
+    case ALT_DMA_EVENT_4:
+    case ALT_DMA_EVENT_5:
+    case ALT_DMA_EVENT_6:
+    case ALT_DMA_EVENT_7:
+    case ALT_DMA_EVENT_ABORT:
+        break;
+    default:
+        return ALT_E_BAD_ARG;
+    }
+
+    // Issue the DMASEV on the DMA manager thread.
+    // DMASEV is short enough not to use DBGINST1 register.
+
+    // For information on APB Interface, see PL330, section 2.5.1.
+    // For information on DBGINSTx, see PL330, section 3.3.20 - 3.3.21.
+    // For information on DMASEV, see PL330, section 4.3.15.
+
+    alt_write_word(ALT_DMA_DBGINST0_ADDR(ALT_DMASECURE_ADDR),
+                   ALT_DMA_DBGINST0_INSTRUCTIONBYTE0_SET(0x34) | // opcode for DMASEV
+                   ALT_DMA_DBGINST0_INSTRUCTIONBYTE1_SET(evt_num << 3) |
+                   ALT_DMA_DBGINST0_DEBUGTHREAD_SET(ALT_DMA_DBGINST0_DEBUGTHREAD_E_MANAGER)
+        );
+
+    // Execute the instruction held in DBGINST0
+
+    // For information on DBGCMD, see PL330, section 3.3.19.
+
+    alt_write_word(ALT_DMA_DBGCMD_ADDR(ALT_DMASECURE_ADDR), 0);
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_dma_manager_state_get(ALT_DMA_MANAGER_STATE_t * state)
+{
+    // For information on DSR, see PL330, section 3.3.1.
+
+    uint32_t raw_state = alt_read_word(ALT_DMA_DSR_ADDR(ALT_DMASECURE_ADDR));
+
+    *state = (ALT_DMA_MANAGER_STATE_t)ALT_DMA_DSR_DMASTATUS_GET(raw_state);
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_dma_channel_state_get(ALT_DMA_CHANNEL_t channel,
+                                          ALT_DMA_CHANNEL_STATE_t * state)
+{
+    // Validate channel
+    switch (channel)
+    {
+    case ALT_DMA_CHANNEL_0:
+    case ALT_DMA_CHANNEL_1:
+    case ALT_DMA_CHANNEL_2:
+    case ALT_DMA_CHANNEL_3:
+    case ALT_DMA_CHANNEL_4:
+    case ALT_DMA_CHANNEL_5:
+    case ALT_DMA_CHANNEL_6:
+    case ALT_DMA_CHANNEL_7:
+        break;
+    default:
+        return ALT_E_BAD_ARG;
+    }
+
+    // For information on CSR, see PL330, section 3.3.11.
+
+    uint32_t raw_state = alt_read_word(ALT_DMA_CSRx_ADDR(ALT_DMASECURE_ADDR, channel));
+
+    *state = (ALT_DMA_CHANNEL_STATE_t)ALT_DMA_CSRx_CHANNELSTATUS_GET(raw_state);
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_dma_manager_fault_status_get(ALT_DMA_MANAGER_FAULT_t * fault)
+{
+    // For information on FTRD, see PL330, section 3.3.9.
+
+    *fault = (ALT_DMA_MANAGER_FAULT_t)alt_read_word(ALT_DMA_FTRD_ADDR(ALT_DMASECURE_ADDR));
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_dma_channel_fault_status_get(ALT_DMA_CHANNEL_t channel,
+                                                 ALT_DMA_CHANNEL_FAULT_t * fault)
+{
+    // Validate channel
+    switch (channel)
+    {
+    case ALT_DMA_CHANNEL_0:
+    case ALT_DMA_CHANNEL_1:
+    case ALT_DMA_CHANNEL_2:
+    case ALT_DMA_CHANNEL_3:
+    case ALT_DMA_CHANNEL_4:
+    case ALT_DMA_CHANNEL_5:
+    case ALT_DMA_CHANNEL_6:
+    case ALT_DMA_CHANNEL_7:
+        break;
+    default:
+        return ALT_E_BAD_ARG;
+    }
+
+    // For information on FTR, see PL330, section 3.3.10.
+
+    *fault = (ALT_DMA_CHANNEL_FAULT_t)alt_read_word(ALT_DMA_FTRx_ADDR(ALT_DMASECURE_ADDR, channel));
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_dma_event_int_select(ALT_DMA_EVENT_t evt_num,
+                                         ALT_DMA_EVENT_SELECT_t opt)
+{
+    // Validate evt_num
+    switch (evt_num)
+    {
+    case ALT_DMA_EVENT_0:
+    case ALT_DMA_EVENT_1:
+    case ALT_DMA_EVENT_2:
+    case ALT_DMA_EVENT_3:
+    case ALT_DMA_EVENT_4:
+    case ALT_DMA_EVENT_5:
+    case ALT_DMA_EVENT_6:
+    case ALT_DMA_EVENT_7:
+    case ALT_DMA_EVENT_ABORT:
+        break;
+    default:
+        return ALT_E_BAD_ARG;
+    }
+
+    // For information on INTEN, see PL330, section 3.3.3.
+
+    switch (opt)
+    {
+    case ALT_DMA_EVENT_SELECT_SEND_EVT:
+        alt_clrbits_word(ALT_DMA_INTEN_ADDR(ALT_DMASECURE_ADDR), 1 << evt_num);
+        break;
+    case ALT_DMA_EVENT_SELECT_SIG_IRQ:
+        alt_setbits_word(ALT_DMA_INTEN_ADDR(ALT_DMASECURE_ADDR), 1 << evt_num);
+        break;
+    default:
+        return ALT_E_BAD_ARG;
+    }
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_dma_event_int_status_get_raw(ALT_DMA_EVENT_t evt_num)
+{
+    // Validate evt_num
+    switch (evt_num)
+    {
+    case ALT_DMA_EVENT_0:
+    case ALT_DMA_EVENT_1:
+    case ALT_DMA_EVENT_2:
+    case ALT_DMA_EVENT_3:
+    case ALT_DMA_EVENT_4:
+    case ALT_DMA_EVENT_5:
+    case ALT_DMA_EVENT_6:
+    case ALT_DMA_EVENT_7:
+    case ALT_DMA_EVENT_ABORT:
+        break;
+    default:
+        return ALT_E_BAD_ARG;
+    }
+
+    // For information on INT_EVENT_RIS, see PL330, section 3.3.4.
+
+    uint32_t status_raw = alt_read_word(ALT_DMA_INT_EVENT_RIS_ADDR(ALT_DMASECURE_ADDR));
+
+    if (status_raw & (1 << evt_num))
+    {
+        return ALT_E_TRUE;
+    }
+    else
+    {
+        return ALT_E_FALSE;
+    }
+}
+
+ALT_STATUS_CODE alt_dma_int_status_get(ALT_DMA_EVENT_t irq_num)
+{
+    // Validate evt_num
+    switch (irq_num)
+    {
+    case ALT_DMA_EVENT_0:
+    case ALT_DMA_EVENT_1:
+    case ALT_DMA_EVENT_2:
+    case ALT_DMA_EVENT_3:
+    case ALT_DMA_EVENT_4:
+    case ALT_DMA_EVENT_5:
+    case ALT_DMA_EVENT_6:
+    case ALT_DMA_EVENT_7:
+    case ALT_DMA_EVENT_ABORT:
+        break;
+    default:
+        return ALT_E_BAD_ARG;
+    }
+
+    // For information on INTMIS, see PL330, section 3.3.5.
+
+    uint32_t int_status = alt_read_word(ALT_DMA_INTMIS_ADDR(ALT_DMASECURE_ADDR));
+
+    if (int_status & (1 << irq_num))
+    {
+        return ALT_E_TRUE;
+    }
+    else
+    {
+        return ALT_E_FALSE;
+    }
+}
+
+ALT_STATUS_CODE alt_dma_int_clear(ALT_DMA_EVENT_t irq_num)
+{
+    // Validate evt_num
+    switch (irq_num)
+    {
+    case ALT_DMA_EVENT_0:
+    case ALT_DMA_EVENT_1:
+    case ALT_DMA_EVENT_2:
+    case ALT_DMA_EVENT_3:
+    case ALT_DMA_EVENT_4:
+    case ALT_DMA_EVENT_5:
+    case ALT_DMA_EVENT_6:
+    case ALT_DMA_EVENT_7:
+    case ALT_DMA_EVENT_ABORT:
+        break;
+    default:
+        return ALT_E_BAD_ARG;
+    }
+
+    // For information on INTCLR, see PL330, section 3.3.6.
+
+    alt_write_word(ALT_DMA_INTCLR_ADDR(ALT_DMASECURE_ADDR), 1 << irq_num);
+
+    return ALT_E_SUCCESS;
+}
+
+/////
+
+ALT_STATUS_CODE alt_dma_memory_to_memory(ALT_DMA_CHANNEL_t channel,
+                                         ALT_DMA_PROGRAM_t * program,
+                                         void * dst,
+                                         const void * src,
+                                         size_t size,
+                                         bool send_evt,
+                                         ALT_DMA_EVENT_t evt)
+{
+    ALT_STATUS_CODE status = ALT_E_SUCCESS;
+
+    // If the size is zero, and no event is requested, just return success.
+    if ((size == 0) && (send_evt == false))
+    {
+        return status;
+    }
+
+    if (status == ALT_E_SUCCESS)
+    {
+        status = alt_dma_program_init(program);
+    }
+
+    if (size != 0)
+    {
+        uintptr_t udst = (uintptr_t)dst;
+        uintptr_t usrc = (uintptr_t)src;
+
+        dprintf("DMA[M->M]: dst  = %p.\n", dst);
+        dprintf("DMA[M->M]: src  = %p.\n", src);
+        dprintf("DMA[M->M]: size = 0x%x.\n", size);
+        
+        // Detect if memory regions overshoots the address space.
+
+        if (udst + size - 1 < udst)
+        {
+            return ALT_E_BAD_ARG;
+        }
+        if (usrc + size - 1 < usrc)
+        {
+            return ALT_E_BAD_ARG;
+        }
+
+        // Detect if memory regions overlaps.
+
+        if (udst > usrc)
+        {
+            if (usrc + size - 1 > udst)
+            {
+                return ALT_E_BAD_ARG;
+            }
+        }
+        else
+        {
+            if (udst + size - 1 > usrc)
+            {
+                return ALT_E_BAD_ARG;
+            }
+        }
+
+        if (status == ALT_E_SUCCESS)
+        {
+            status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_SAR, usrc);
+        }
+        if (status == ALT_E_SUCCESS)
+        {
+            status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_DAR, udst);
+        }
+
+        size_t sizeleft = size;
+
+        //
+        // The algorithm uses the strategy described in PL330 B.3.1.
+        // It is extended for 2-byte and 1-byte unaligned cases.
+        //
+
+        // First see how many byte(s) we need to transfer to get src to be 8 byte aligned
+        if (usrc & 0x7)
+        {
+            uint32_t aligncount = MIN(8 - (usrc & 0x7), sizeleft);
+            sizeleft -= aligncount;
+
+            dprintf("DMA[M->M]: Total pre-alignment 1-byte burst size tranfer(s): %lu.\n", aligncount);
+
+            // Program in the following parameters:
+            //  - SS8 (Source      burst size of 1-byte)
+            //  - DS8 (Destination burst size of 1-byte)
+            //  - SBx (Source      burst length of [aligncount] transfers)
+            //  - DBx (Destination burst length of [aligncount] transfers)
+            //  - All other options default.
+
+            if (status == ALT_E_SUCCESS)
+            {
+                status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_CCR,
+                                                (   ((aligncount - 1) << 4) // SB
+                                                  | ALT_DMA_CCR_OPT_SS8
+                                                  | ALT_DMA_CCR_OPT_SA_DEFAULT
+                                                  | ALT_DMA_CCR_OPT_SP_DEFAULT
+                                                  | ALT_DMA_CCR_OPT_SC_DEFAULT
+                                                  | ((aligncount - 1) << 18) // DB
+                                                  | ALT_DMA_CCR_OPT_DS8
+                                                  | ALT_DMA_CCR_OPT_DA_DEFAULT
+                                                  | ALT_DMA_CCR_OPT_DP_DEFAULT
+                                                  | ALT_DMA_CCR_OPT_DC_DEFAULT
+                                                  | ALT_DMA_CCR_OPT_ES_DEFAULT
+                                                )
+                    );
+            }
+            if (status == ALT_E_SUCCESS)
+            {
+                status = alt_dma_program_DMALD(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
+            }
+            if (status == ALT_E_SUCCESS)
+            {
+                status = alt_dma_program_DMAST(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
+            }
+        }
+
+        // This is the number of 8-byte bursts
+        uint32_t burstcount = sizeleft >> 3;
+
+        bool correction = (burstcount != 0);
+
+        // Update the size left to transfer
+        sizeleft &= 0x7;
+
+        dprintf("DMA[M->M]: Total Main 8-byte burst size transfer(s): %lu.\n", burstcount);
+        dprintf("DMA[M->M]: Total Main 1-byte burst size transfer(s): %u.\n", sizeleft);
+
+        // Determine how many 16 length bursts can be done
+
+        if (burstcount >> 4)
+        {
+            uint32_t length16burstcount = burstcount >> 4;
+            burstcount &= 0xf;
+
+            dprintf("DMA[M->M]:   Number of 16 burst length 8-byte transfer(s): %lu.\n", length16burstcount);
+            dprintf("DMA[M->M]:   Number of remaining 8-byte transfer(s):       %lu.\n", burstcount);
+
+            // Program in the following parameters:
+            //  - SS64 (Source      burst size of 8-byte)
+            //  - DS64 (Destination burst size of 8-byte)
+            //  - SB16 (Source      burst length of 16 transfers)
+            //  - DB16 (Destination burst length of 16 transfers)
+            //  - All other options default.
+
+            if (status == ALT_E_SUCCESS)
+            {
+                status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_CCR,
+                                                (   ALT_DMA_CCR_OPT_SB16
+                                                  | ALT_DMA_CCR_OPT_SS64
+                                                  | ALT_DMA_CCR_OPT_SA_DEFAULT
+                                                  | ALT_DMA_CCR_OPT_SP_DEFAULT
+                                                  | ALT_DMA_CCR_OPT_SC_DEFAULT
+                                                  | ALT_DMA_CCR_OPT_DB16
+                                                  | ALT_DMA_CCR_OPT_DS64
+                                                  | ALT_DMA_CCR_OPT_DA_DEFAULT
+                                                  | ALT_DMA_CCR_OPT_DP_DEFAULT
+                                                  | ALT_DMA_CCR_OPT_DC_DEFAULT
+                                                  | ALT_DMA_CCR_OPT_ES_DEFAULT
+                                                )
+                    );
+            }
+
+            while (length16burstcount > 0)
+            {
+                if (status != ALT_E_SUCCESS)
+                {
+                    break;
+                }
+
+                uint32_t loopcount = MIN(length16burstcount, 256);
+                length16burstcount -= loopcount;
+
+                dprintf("DMA[M->M]:   Looping %lux 16 burst length 8-byte transfer(s).\n", loopcount);
+
+                if ((status == ALT_E_SUCCESS) && (loopcount > 1))
+                {
+                    status = alt_dma_program_DMALP(program, loopcount);
+                }
+                if (status == ALT_E_SUCCESS)
+                {
+                    status = alt_dma_program_DMALD(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
+                }
+                if (status == ALT_E_SUCCESS)
+                {
+                    status = alt_dma_program_DMAST(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
+                }
+                if ((status == ALT_E_SUCCESS) && (loopcount > 1))
+                {
+                    status = alt_dma_program_DMALPEND(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
+                }
+            }
+        }
+
+        // At this point, we should have [burstcount] 8-byte transfer(s)
+        // remaining. [burstcount] should be less than 16.
+
+        // Do one more burst with a SB / DB of length [burstcount].
+
+        if (burstcount)
+        {
+            // Program in the following parameters:
+            //  - SS64 (Source      burst size of 8-byte)
+            //  - DS64 (Destination burst size of 8-byte)
+            //  - SBx  (Source      burst length of [burstlength] transfers)
+            //  - DBx  (Destination burst length of [burstlength] transfers)
+            //  - All other options default.
+
+            if (status == ALT_E_SUCCESS)
+            {
+                status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_CCR,
+                                                (   ((burstcount - 1) << 4) // SB
+                                                  | ALT_DMA_CCR_OPT_SS64
+                                                  | ALT_DMA_CCR_OPT_SA_DEFAULT
+                                                  | ALT_DMA_CCR_OPT_SP_DEFAULT
+                                                  | ALT_DMA_CCR_OPT_SC_DEFAULT
+                                                  | ((burstcount - 1) << 18) // DB
+                                                  | ALT_DMA_CCR_OPT_DS64
+                                                  | ALT_DMA_CCR_OPT_DA_DEFAULT
+                                                  | ALT_DMA_CCR_OPT_DP_DEFAULT
+                                                  | ALT_DMA_CCR_OPT_DC_DEFAULT
+                                                  | ALT_DMA_CCR_OPT_ES_DEFAULT
+                                                )
+                    );
+            }
+            if (status == ALT_E_SUCCESS)
+            {
+                status = alt_dma_program_DMALD(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
+            }
+            if (status == ALT_E_SUCCESS)
+            {
+                status = alt_dma_program_DMAST(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
+            }
+        }
+
+        // This is where the last DMAMOV CCR and DMAST is done if an
+        // alignment correction required.
+
+        if (   (correction == true)
+            && ((usrc & 0x7) != (udst & 0x7)) // If src and dst are mod-8 congruent, no correction is needed.
+           )
+        {
+            if (status == ALT_E_SUCCESS)
+            {
+                // Determine what type of correction.
+
+                // Set the source parameters to match that of the destination
+                // parameters. This way the SAR is increment in the same fashion as
+                // DAR. This will allow the non 8-byte transfers to copy correctly.
+
+                uint32_t ccr;
+
+                if ((usrc & 0x3) == (udst & 0x3))
+                {
+                    dprintf("DMA[M->M]: Single correction 4-byte burst size tranfer.\n");
+
+                    // Program in the following parameters:
+                    //  - SS32 (Source      burst size of 4-byte)
+                    //  - DS32 (Destination burst size of 4-byte)
+                    //  - SB1  (Source      burst length of 1 transfer)
+                    //  - DB1  (Destination burst length of 1 transfer)
+                    //  - All other options default.
+
+                    ccr = (   ALT_DMA_CCR_OPT_SB1
+                            | ALT_DMA_CCR_OPT_SS32
+                            | ALT_DMA_CCR_OPT_SA_DEFAULT
+                            | ALT_DMA_CCR_OPT_SP_DEFAULT
+                            | ALT_DMA_CCR_OPT_SC_DEFAULT
+                            | ALT_DMA_CCR_OPT_DB1
+                            | ALT_DMA_CCR_OPT_DS32
+                            | ALT_DMA_CCR_OPT_DA_DEFAULT
+                            | ALT_DMA_CCR_OPT_DP_DEFAULT
+                            | ALT_DMA_CCR_OPT_DC_DEFAULT
+                            | ALT_DMA_CCR_OPT_ES_DEFAULT
+                          );
+                }
+                else if ((usrc & 0x1) == (udst & 0x1))
+                {
+                    dprintf("DMA[M->M]: Single correction 2-byte burst size tranfer.\n");
+
+                    // Program in the following parameters:
+                    //  - SS16 (Source      burst size of 2-byte)
+                    //  - DS16 (Destination burst size of 2-byte)
+                    //  - SB1  (Source      burst length of 1 transfer)
+                    //  - DB1  (Destination burst length of 1 transfer)
+                    //  - All other options default.
+
+                    ccr = (   ALT_DMA_CCR_OPT_SB1
+                            | ALT_DMA_CCR_OPT_SS16
+                            | ALT_DMA_CCR_OPT_SA_DEFAULT
+                            | ALT_DMA_CCR_OPT_SP_DEFAULT
+                            | ALT_DMA_CCR_OPT_SC_DEFAULT
+                            | ALT_DMA_CCR_OPT_DB1
+                            | ALT_DMA_CCR_OPT_DS16
+                            | ALT_DMA_CCR_OPT_DA_DEFAULT
+                            | ALT_DMA_CCR_OPT_DP_DEFAULT
+                            | ALT_DMA_CCR_OPT_DC_DEFAULT
+                            | ALT_DMA_CCR_OPT_ES_DEFAULT
+                          );
+                }
+                else
+                {
+                    dprintf("DMA[M->M]: Single correction 1-byte burst size tranfer.\n");
+
+                    // Program in the following parameters:
+                    //  - SS8 (Source      burst size of 1-byte)
+                    //  - DS8 (Destination burst size of 1-byte)
+                    //  - SB1 (Source      burst length of 1 transfer)
+                    //  - DB1 (Destination burst length of 1 transfer)
+                    //  - All other options default.
+
+                    ccr = (   ALT_DMA_CCR_OPT_SB1
+                            | ALT_DMA_CCR_OPT_SS8
+                            | ALT_DMA_CCR_OPT_SA_DEFAULT
+                            | ALT_DMA_CCR_OPT_SP_DEFAULT
+                            | ALT_DMA_CCR_OPT_SC_DEFAULT
+                            | ALT_DMA_CCR_OPT_DB1
+                            | ALT_DMA_CCR_OPT_DS8
+                            | ALT_DMA_CCR_OPT_DA_DEFAULT
+                            | ALT_DMA_CCR_OPT_DP_DEFAULT
+                            | ALT_DMA_CCR_OPT_DC_DEFAULT
+                            | ALT_DMA_CCR_OPT_ES_DEFAULT
+                          );
+                }
+
+                status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_CCR,
+                                                ccr);
+            }
+            if (status == ALT_E_SUCCESS)
+            {
+                status = alt_dma_program_DMAST(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
+            }
+        }
+
+        // At this point, there should be 0 - 7 1-byte transfers remaining.
+
+        if (sizeleft)
+        {
+            dprintf("DMA[M->M]: Total post 1-byte burst size tranfer(s): %u.\n", sizeleft);
+
+            // Program in the following parameters:
+            //  - SS8 (Source      burst size of 1-byte)
+            //  - DS8 (Destination burst size of 1-byte)
+            //  - SBx (Source      burst length of [sizeleft] transfers)
+            //  - DBx (Destination burst length of [sizeleft] transfers)
+            //  - All other options default.
+
+            if (status == ALT_E_SUCCESS)
+            {
+                status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_CCR,
+                                                (   ((sizeleft - 1) << 4) // SB
+                                                  | ALT_DMA_CCR_OPT_SS8
+                                                  | ALT_DMA_CCR_OPT_SA_DEFAULT
+                                                  | ALT_DMA_CCR_OPT_SP_DEFAULT
+                                                  | ALT_DMA_CCR_OPT_SC_DEFAULT
+                                                  | ((sizeleft - 1) << 18) // DB
+                                                  | ALT_DMA_CCR_OPT_DS8
+                                                  | ALT_DMA_CCR_OPT_DA_DEFAULT
+                                                  | ALT_DMA_CCR_OPT_DP_DEFAULT
+                                                  | ALT_DMA_CCR_OPT_DC_DEFAULT
+                                                  | ALT_DMA_CCR_OPT_ES_DEFAULT
+                                                )
+                    );
+            }
+            if (status == ALT_E_SUCCESS)
+            {
+                status = alt_dma_program_DMALD(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
+            }
+            if (status == ALT_E_SUCCESS)
+            {
+                status = alt_dma_program_DMAST(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
+            }
+        }
+    } // if (size != 0)
+
+    // Send event if requested.
+    if (send_evt)
+    {
+        if (status == ALT_E_SUCCESS)
+        {
+            dprintf("DMA[M->M]: Adding event ...\n");
+            status = alt_dma_program_DMASEV(program, evt);
+        }
+    }
+
+    // Now that everything is done, end the program.
+    if (status == ALT_E_SUCCESS)
+    {
+        status = alt_dma_program_DMAEND(program);
+    }
+
+    // If there was a problem assembling the program, clean up the buffer and exit.
+    if (status != ALT_E_SUCCESS)
+    {
+        // Do not report the status for the clear operation. A failure should be
+        // reported regardless of if the clear is successful.
+        alt_dma_program_clear(program);
+        return status;
+    }
+
+    // Execute the program on the given channel.
+    return alt_dma_channel_exec(channel, program);
+}
+
+ALT_STATUS_CODE alt_dma_zero_to_memory(ALT_DMA_CHANNEL_t channel,
+                                       ALT_DMA_PROGRAM_t * program,
+                                       void * buf,
+                                       size_t size,
+                                       bool send_evt,
+                                       ALT_DMA_EVENT_t evt)
+{
+    ALT_STATUS_CODE status = ALT_E_SUCCESS;
+
+    // If the size is zero, and no event is requested, just return success.
+    if ((size == 0) && (send_evt == false))
+    {
+        return status;
+    }
+
+    if (status == ALT_E_SUCCESS)
+    {
+        status = alt_dma_program_init(program);
+    }
+
+    if (size != 0)
+    {
+        if (status == ALT_E_SUCCESS)
+        {
+            status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_DAR, (uint32_t)buf);
+        }
+
+        dprintf("DMA[Z->M]: buf  = %p.\n", buf);
+        dprintf("DMA[Z->M]: size = 0x%x.\n", size);
+
+        size_t sizeleft = size;
+
+        // First see how many byte(s) we need to transfer to get dst to be 8 byte aligned.
+        if ((uint32_t)buf & 0x7)
+        {
+            uint32_t aligncount = MIN(8 - ((uint32_t)buf & 0x7), sizeleft);
+            sizeleft -= aligncount;
+
+            dprintf("DMA[Z->M]: Total pre-alignment 1-byte burst size tranfer(s): %lu.\n", aligncount);
+
+            // Program in the following parameters:
+            //  - DS8 (Destination burst size of 1-byte)
+            //  - DBx (Destination burst length of [aligncount] transfers)
+            //  - All other options default.
+
+            if (status == ALT_E_SUCCESS)
+            {
+                status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_CCR,
+                                                (   ALT_DMA_CCR_OPT_SB_DEFAULT
+                                                  | ALT_DMA_CCR_OPT_SS_DEFAULT
+                                                  | ALT_DMA_CCR_OPT_SA_DEFAULT
+                                                  | ALT_DMA_CCR_OPT_SP_DEFAULT
+                                                  | ALT_DMA_CCR_OPT_SC_DEFAULT
+                                                  | ((aligncount - 1) << 18) // DB
+                                                  | ALT_DMA_CCR_OPT_DS8
+                                                  | ALT_DMA_CCR_OPT_DA_DEFAULT
+                                                  | ALT_DMA_CCR_OPT_DP_DEFAULT
+                                                  | ALT_DMA_CCR_OPT_DC_DEFAULT
+                                                  | ALT_DMA_CCR_OPT_ES_DEFAULT
+                                                )
+                    );
+            }
+            if (status == ALT_E_SUCCESS)
+            {
+                status = alt_dma_program_DMASTZ(program);
+            }
+        }
+
+        // This is the number of 8-byte bursts left
+        uint32_t burstcount = sizeleft >> 3;
+
+        // Update the size left to transfer
+        sizeleft &= 0x7;
+
+        dprintf("DMA[Z->M]: Total Main 8-byte burst size transfer(s): %lu.\n", burstcount);
+        dprintf("DMA[Z->M]: Total Main 1-byte burst size transfer(s): %u.\n", sizeleft);
+
+        // Determine how many 16 length bursts can be done
+        if (burstcount >> 4)
+        {
+            uint32_t length16burstcount = burstcount >> 4;
+            burstcount &= 0xf;
+
+            dprintf("DMA[Z->M]:   Number of 16 burst length 8-byte transfer(s): %lu.\n", length16burstcount);
+            dprintf("DMA[Z->M]:   Number of remaining 8-byte transfer(s):       %lu.\n", burstcount);
+
+            // Program in the following parameters:
+            //  - DS64 (Destination burst size of 8-byte)
+            //  - DB16 (Destination burst length of 16 transfers)
+            //  - All other options default.
+
+            if (status == ALT_E_SUCCESS)
+            {
+                status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_CCR,
+                                                (   ALT_DMA_CCR_OPT_SB_DEFAULT
+                                                  | ALT_DMA_CCR_OPT_SS_DEFAULT
+                                                  | ALT_DMA_CCR_OPT_SA_DEFAULT
+                                                  | ALT_DMA_CCR_OPT_SP_DEFAULT
+                                                  | ALT_DMA_CCR_OPT_SC_DEFAULT
+                                                  | ALT_DMA_CCR_OPT_DB16
+                                                  | ALT_DMA_CCR_OPT_DS64
+                                                  | ALT_DMA_CCR_OPT_DA_DEFAULT
+                                                  | ALT_DMA_CCR_OPT_DP_DEFAULT
+                                                  | ALT_DMA_CCR_OPT_DC_DEFAULT
+                                                  | ALT_DMA_CCR_OPT_ES_DEFAULT
+                                                )
+                    );
+            }
+
+            while (length16burstcount > 0)
+            {
+                if (status != ALT_E_SUCCESS)
+                {
+                    break;
+                }
+
+                uint32_t loopcount = MIN(length16burstcount, 256);
+                length16burstcount -= loopcount;
+
+                dprintf("DMA[Z->M]:   Looping %lux 16 burst length 8-byte transfer(s).\n", loopcount);
+
+                if ((status == ALT_E_SUCCESS) && (loopcount > 1))
+                {
+                    status = alt_dma_program_DMALP(program, loopcount);
+                }
+                if (status == ALT_E_SUCCESS)
+                {
+                    status = alt_dma_program_DMASTZ(program);
+                }
+                if ((status == ALT_E_SUCCESS) && (loopcount > 1))
+                {
+                    status = alt_dma_program_DMALPEND(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
+                }
+            }
+        }
+
+        // At this point, we should have [burstcount] 8-byte transfer(s)
+        // remaining. [burstcount] should be less than 16.
+
+        // Do one more burst with a SB / DB of length [burstcount].
+
+        if (burstcount)
+        {
+            // Program in the following parameters:
+            //  - DS64 (Destination burst size of 8-byte)
+            //  - DBx  (Destination burst length of [burstlength] transfers)
+            //  - All other options default.
+
+            if (status == ALT_E_SUCCESS)
+            {
+                status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_CCR,
+                                                (   ALT_DMA_CCR_OPT_SB_DEFAULT
+                                                  | ALT_DMA_CCR_OPT_SS_DEFAULT
+                                                  | ALT_DMA_CCR_OPT_SA_DEFAULT
+                                                  | ALT_DMA_CCR_OPT_SP_DEFAULT
+                                                  | ALT_DMA_CCR_OPT_SC_DEFAULT
+                                                  | ((burstcount - 1) << 18) // DB
+                                                  | ALT_DMA_CCR_OPT_DS64
+                                                  | ALT_DMA_CCR_OPT_DA_DEFAULT
+                                                  | ALT_DMA_CCR_OPT_DP_DEFAULT
+                                                  | ALT_DMA_CCR_OPT_DC_DEFAULT
+                                                  | ALT_DMA_CCR_OPT_ES_DEFAULT
+                                                )
+                    );
+            }
+            if (status == ALT_E_SUCCESS)
+            {
+                status = alt_dma_program_DMASTZ(program);
+            }
+        }
+
+        // At this point, there should be 0 - 7 1-byte transfers remaining.
+
+        if (sizeleft)
+        {
+            dprintf("DMA[Z->M]: Total post 1-byte burst size tranfer(s): %u.\n", sizeleft);
+
+            // Program in the following parameters:
+            //  - DS8 (Destination burst size of 1-byte)
+            //  - DBx (Destination burst length of [sizeleft] transfers)
+            //  - All other options default.
+
+            if (status == ALT_E_SUCCESS)
+            {
+                status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_CCR,
+                                                (   ALT_DMA_CCR_OPT_SB_DEFAULT
+                                                  | ALT_DMA_CCR_OPT_SS_DEFAULT
+                                                  | ALT_DMA_CCR_OPT_SA_DEFAULT
+                                                  | ALT_DMA_CCR_OPT_SP_DEFAULT
+                                                  | ALT_DMA_CCR_OPT_SC_DEFAULT
+                                                  | ((sizeleft - 1) << 18) // DB
+                                                  | ALT_DMA_CCR_OPT_DS8
+                                                  | ALT_DMA_CCR_OPT_DA_DEFAULT
+                                                  | ALT_DMA_CCR_OPT_DP_DEFAULT
+                                                  | ALT_DMA_CCR_OPT_DC_DEFAULT
+                                                  | ALT_DMA_CCR_OPT_ES_DEFAULT
+                                                )
+                    );
+            }
+            if (status == ALT_E_SUCCESS)
+            {
+                status = alt_dma_program_DMASTZ(program);
+            }
+        }
+    } // if (size != 0)
+
+    // Send event if requested.
+    if (send_evt)
+    {
+        if (status == ALT_E_SUCCESS)
+        {
+            dprintf("DMA[Z->M]: Adding event ...\n");
+            status = alt_dma_program_DMASEV(program, evt);
+        }
+    }
+
+    // Now that everything is done, end the program.
+    if (status == ALT_E_SUCCESS)
+    {
+        status = alt_dma_program_DMAEND(program);
+    }
+
+    // If there was a problem assembling the program, clean up the buffer and exit.
+    if (status != ALT_E_SUCCESS)
+    {
+        // Do not report the status for the clear operation. A failure should be
+        // reported regardless of if the clear is successful.
+        alt_dma_program_clear(program);
+        return status;
+    }
+
+    // Execute the program on the given channel.
+    return alt_dma_channel_exec(channel, program);
+}
+
+ALT_STATUS_CODE alt_dma_memory_to_register(ALT_DMA_CHANNEL_t channel,
+                                           ALT_DMA_PROGRAM_t * program,
+                                           void * dst_reg,
+                                           const void * src_buf,
+                                           size_t count,
+                                           uint32_t register_width_bits,
+                                           bool send_evt,
+                                           ALT_DMA_EVENT_t evt)
+{
+    ALT_STATUS_CODE status = ALT_E_SUCCESS;
+
+    // If the count is zero, and no event is requested, just return success.
+    if ((count == 0) && (send_evt == false))
+    {
+        return status;
+    }
+
+    if (status == ALT_E_SUCCESS)
+    {
+        status = alt_dma_program_init(program);
+    }
+
+    if (count != 0)
+    {
+        // Verify valid register_width_bits and construct the CCR SS and DS parameters.
+        uint32_t ccr_ss_ds_mask = 0;
+
+        if (status == ALT_E_SUCCESS)
+        {
+            switch (register_width_bits)
+            {
+            case 8:
+                // Program in the following parameters:
+                //  - SS8 (Source      burst size of 8 bits)
+                //  - DS8 (Destination burst size of 8 bits)
+                ccr_ss_ds_mask = ALT_DMA_CCR_OPT_SS8 | ALT_DMA_CCR_OPT_DS8;
+                break;
+            case 16:
+                // Program in the following parameters:
+                //  - SS16 (Source      burst size of 16 bits)
+                //  - DS16 (Destination burst size of 16 bits)
+                ccr_ss_ds_mask = ALT_DMA_CCR_OPT_SS16 | ALT_DMA_CCR_OPT_DS16;
+                break;
+            case 32:
+                // Program in the following parameters:
+                //  - SS32 (Source      burst size of 32 bits)
+                //  - DS32 (Destination burst size of 32 bits)
+                ccr_ss_ds_mask = ALT_DMA_CCR_OPT_SS32 | ALT_DMA_CCR_OPT_DS32;
+                break;
+            case 64:
+                // Program in the following parameters:
+                //  - SS64 (Source      burst size of 64 bits)
+                //  - DS64 (Destination burst size of 64 bits)
+                ccr_ss_ds_mask = ALT_DMA_CCR_OPT_SS64 | ALT_DMA_CCR_OPT_DS64;
+                break;
+            default:
+                status = ALT_E_BAD_ARG;
+                break;
+            }
+        }
+
+        // Verify that the dst_reg and src_buf are aligned to the register width
+        if (status == ALT_E_SUCCESS)
+        {
+            if      (((uintptr_t)dst_reg & ((register_width_bits >> 3) - 1)) != 0)
+            {
+                status = ALT_E_BAD_ARG;
+            }
+            else if (((uintptr_t)src_buf & ((register_width_bits >> 3) - 1)) != 0)
+            {
+                status = ALT_E_BAD_ARG;
+            }
+            else
+            {
+                dprintf("DMA[M->R]: dst_reg = %p.\n",   dst_reg);
+                dprintf("DMA[M->R]: src_buf = %p.\n",   src_buf);
+                dprintf("DMA[M->R]: count   = 0x%x.\n", count);
+            }
+        }
+
+        if (status == ALT_E_SUCCESS)
+        {
+            status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_SAR, (uint32_t)src_buf);
+        }
+        if (status == ALT_E_SUCCESS)
+        {
+            status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_DAR, (uint32_t)dst_reg);
+        }
+
+        // This is the remaining count left to process.
+        uint32_t countleft = count;
+
+        // See how many 16-length bursts we can use
+        if (countleft >> 4)
+        {
+            // Program in the following parameters:
+            //  - SSx  (Source      burst size of [ccr_ss_ds_mask])
+            //  - DSx  (Destination burst size of [ccr_ss_ds_mask])
+            //  - DAF  (Destination address fixed)
+            //  - SB16 (Source      burst length of 16 transfers)
+            //  - DB16 (Destination burst length of 16 transfers)
+            //  - All other options default.
+
+            if (status == ALT_E_SUCCESS)
+            {
+                status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_CCR,
+                                                (   ccr_ss_ds_mask
+                                                  | ALT_DMA_CCR_OPT_SB16
+                                                  | ALT_DMA_CCR_OPT_SA_DEFAULT
+                                                  | ALT_DMA_CCR_OPT_SP_DEFAULT
+                                                  | ALT_DMA_CCR_OPT_SC_DEFAULT
+                                                  | ALT_DMA_CCR_OPT_DB16
+                                                  | ALT_DMA_CCR_OPT_DAF
+                                                  | ALT_DMA_CCR_OPT_DP_DEFAULT
+                                                  | ALT_DMA_CCR_OPT_DC_DEFAULT
+                                                  | ALT_DMA_CCR_OPT_ES_DEFAULT
+                                                )
+                    );
+            }
+
+            uint32_t length16burst = countleft >> 4;
+            countleft &= 0xf;
+
+            dprintf("DMA[M->R]:   Number of 16 burst length transfer(s): %lu.\n", length16burst);
+            dprintf("DMA[M->R]:   Number of remaining transfer(s):       %lu.\n", countleft);
+
+            // See how many 256x 16-length bursts we can use
+            if (length16burst >> 8)
+            {
+                uint32_t loop256length16burst = length16burst >> 8;
+                length16burst &= ((1 << 8) - 1);
+
+                dprintf("DMA[M->R]:     Number of 256-looped 16 burst length transfer(s): %lu.\n", loop256length16burst);
+                dprintf("DMA[M->R]:     Number of remaining 16 burst length transfer(s):  %lu.\n", length16burst);
+
+                while (loop256length16burst > 0)
+                {
+                    if (status != ALT_E_SUCCESS)
+                    {
+                        break;
+                    }
+
+                    uint32_t loopcount = MIN(loop256length16burst, 256);
+                    loop256length16burst -= loopcount;
+
+                    dprintf("DMA[M->R]:     Looping %lux super loop transfer(s).\n", loopcount);
+
+                    if ((status == ALT_E_SUCCESS) && (loopcount > 1))
+                    {
+                        status = alt_dma_program_DMALP(program, loopcount);
+                    }
+
+                    if (status == ALT_E_SUCCESS)
+                    {
+                        status = alt_dma_program_DMALP(program, 256);
+                    }
+                    if (status == ALT_E_SUCCESS)
+                    {
+                        status = alt_dma_program_DMALD(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
+                    }
+                    if (status == ALT_E_SUCCESS)
+                    {
+                        status = alt_dma_program_DMAST(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
+                    }
+                    if (status == ALT_E_SUCCESS)
+                    {
+                        status = alt_dma_program_DMALPEND(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
+                    }
+
+                    if ((status == ALT_E_SUCCESS) && (loopcount > 1))
+                    {
+                        status = alt_dma_program_DMALPEND(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
+                    }
+                }
+            }
+
+            // The super loop above ensures that the length16burst is below 256.
+            if (length16burst > 0)
+            {
+                uint32_t loopcount = length16burst;
+                length16burst = 0;
+
+                dprintf("DMA[M->R]:   Looping %lux 16 burst length transfer(s).\n", loopcount);
+
+                if ((status == ALT_E_SUCCESS) && (loopcount > 1))
+                {
+                    status = alt_dma_program_DMALP(program, loopcount);
+                }
+                if (status == ALT_E_SUCCESS)
+                {
+                    status = alt_dma_program_DMALD(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
+                }
+                if (status == ALT_E_SUCCESS)
+                {
+                    status = alt_dma_program_DMAST(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
+                }
+                if ((status == ALT_E_SUCCESS) && (loopcount > 1))
+                {
+                    status = alt_dma_program_DMALPEND(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
+                }
+            }
+        }
+
+        // At this point, we should have [countleft] transfer(s) remaining.
+        // [countleft] should be less than 16.
+
+        if (countleft)
+        {
+            // Program in the following parameters:
+            //  - SSx (Source      burst size of [ccr_ss_ds_mask])
+            //  - DSx (Destination burst size of [ccr_ss_ds_mask])
+            //  - DAF (Destination address fixed)
+            //  - SBx (Source      burst length of [countleft] transfer(s))
+            //  - DBx (Destination burst length of [countleft] transfer(s))
+            //  - All other options default.
+
+            if (status == ALT_E_SUCCESS)
+            {
+                dprintf("DMA[M->R]:   Tail end %lux transfer(s).\n", countleft);
+
+                status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_CCR,
+                                                (   ccr_ss_ds_mask
+                                                  | ((countleft - 1) << 4) // SB
+                                                  | ALT_DMA_CCR_OPT_SA_DEFAULT
+                                                  | ALT_DMA_CCR_OPT_SP_DEFAULT
+                                                  | ALT_DMA_CCR_OPT_SC_DEFAULT
+                                                  | ((countleft - 1) << 18) // DB
+                                                  | ALT_DMA_CCR_OPT_DAF
+                                                  | ALT_DMA_CCR_OPT_DP_DEFAULT
+                                                  | ALT_DMA_CCR_OPT_DC_DEFAULT
+                                                  | ALT_DMA_CCR_OPT_ES_DEFAULT
+                                                )
+                    );
+            }
+            if (status == ALT_E_SUCCESS)
+            {
+                status = alt_dma_program_DMALD(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
+            }
+            if (status == ALT_E_SUCCESS)
+            {
+                status = alt_dma_program_DMAST(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
+            }
+        }
+
+    } // if (count != 0)
+
+    // Send event if requested.
+    if (send_evt)
+    {
+        if (status == ALT_E_SUCCESS)
+        {
+            dprintf("DMA[M->R]: Adding event ...\n");
+            status = alt_dma_program_DMASEV(program, evt);
+        }
+    }
+
+    // Now that everything is done, end the program.
+    if (status == ALT_E_SUCCESS)
+    {
+        dprintf("DMA[M->R]: DMAEND program.\n");
+        status = alt_dma_program_DMAEND(program);
+    }
+
+    // If there was a problem assembling the program, clean up the buffer and exit.
+    if (status != ALT_E_SUCCESS)
+    {
+        // Do not report the status for the clear operation. A failure should be
+        // reported regardless of if the clear is successful.
+        alt_dma_program_clear(program);
+        return status;
+    }
+
+    // Execute the program on the given channel.
+    return alt_dma_channel_exec(channel, program);
+}
+
+ALT_STATUS_CODE alt_dma_register_to_memory(ALT_DMA_CHANNEL_t channel,
+                                           ALT_DMA_PROGRAM_t * program,
+                                           void * dst_buf,
+                                           const void * src_reg,
+                                           size_t count,
+                                           uint32_t register_width_bits,
+                                           bool send_evt,
+                                           ALT_DMA_EVENT_t evt)
+{
+    ALT_STATUS_CODE status = ALT_E_SUCCESS;
+
+    // If the count is zero, and no event is requested, just return success.
+    if ((count == 0) && (send_evt == false))
+    {
+        return status;
+    }
+
+    if (status == ALT_E_SUCCESS)
+    {
+        status = alt_dma_program_init(program);
+    }
+
+    if (count != 0)
+    {
+        // Verify valid register_width_bits and construct the CCR SS and DS parameters.
+        uint32_t ccr_ss_ds_mask = 0;
+
+        if (status == ALT_E_SUCCESS)
+        {
+            switch (register_width_bits)
+            {
+            case 8:
+                // Program in the following parameters:
+                //  - SS8 (Source      burst size of 8 bits)
+                //  - DS8 (Destination burst size of 8 bits)
+                ccr_ss_ds_mask = ALT_DMA_CCR_OPT_SS8 | ALT_DMA_CCR_OPT_DS8;
+                break;
+            case 16:
+                // Program in the following parameters:
+                //  - SS16 (Source      burst size of 16 bits)
+                //  - DS16 (Destination burst size of 16 bits)
+                ccr_ss_ds_mask = ALT_DMA_CCR_OPT_SS16 | ALT_DMA_CCR_OPT_DS16;
+                break;
+            case 32:
+                // Program in the following parameters:
+                //  - SS32 (Source      burst size of 32 bits)
+                //  - DS32 (Destination burst size of 32 bits)
+                ccr_ss_ds_mask = ALT_DMA_CCR_OPT_SS32 | ALT_DMA_CCR_OPT_DS32;
+                break;
+            case 64:
+                // Program in the following parameters:
+                //  - SS64 (Source      burst size of 64 bits)
+                //  - DS64 (Destination burst size of 64 bits)
+                ccr_ss_ds_mask = ALT_DMA_CCR_OPT_SS64 | ALT_DMA_CCR_OPT_DS64;
+                break;
+            default:
+                dprintf("DMA[R->M]: Invalid register width.\n");
+                status = ALT_E_BAD_ARG;
+                break;
+            }
+        }
+
+        // Verify that the dst_buf and src_reg are aligned to the register width
+        if (status == ALT_E_SUCCESS)
+        {
+            if      (((uintptr_t)dst_buf & ((register_width_bits >> 3) - 1)) != 0)
+            {
+                status = ALT_E_BAD_ARG;
+            }
+            else if (((uintptr_t)src_reg & ((register_width_bits >> 3) - 1)) != 0)
+            {
+                status = ALT_E_BAD_ARG;
+            }
+            else
+            {
+                dprintf("DMA[R->M]: dst_reg = %p.\n",   dst_buf);
+                dprintf("DMA[R->M]: src_buf = %p.\n",   src_reg);
+                dprintf("DMA[R->M]: count   = 0x%x.\n", count);
+            }
+        }
+
+        if (status == ALT_E_SUCCESS)
+        {
+            status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_SAR, (uint32_t)src_reg);
+        }
+        if (status == ALT_E_SUCCESS)
+        {
+            status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_DAR, (uint32_t)dst_buf);
+        }
+
+        // This is the remaining count left to process.
+        uint32_t countleft = count;
+
+        // See how many 16-length bursts we can use
+        if (countleft >> 4)
+        {
+            uint32_t length16burst = countleft >> 4;
+            countleft &= 0xf;
+
+            dprintf("DMA[R->M]:   Number of 16 burst length transfer(s): %lu.\n", length16burst);
+            dprintf("DMA[R->M]:   Number of remaining transfer(s):       %lu.\n", countleft);
+
+            //
+            // The algorithm uses the strategy described in PL330 B.2.3.
+            // Not sure if registers will accept burst transfers so read the register in its own transfer.
+            //
+
+            // Program in the following parameters:
+            //  - SAF  (Source      address fixed)
+            //  - SSx  (Source      burst size of [ccr_ss_ds_mask])
+            //  - DSx  (Destination burst size of [ccr_ss_ds_mask])
+            //  - SB16 (Source      burst length of 16 transfers)
+            //  - DB16 (Destination burst length of 16 transfers)
+            //  - All other options default.
+
+            if (status == ALT_E_SUCCESS)
+            {
+                status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_CCR,
+                                                (   ccr_ss_ds_mask
+                                                  | ALT_DMA_CCR_OPT_SB16
+                                                  | ALT_DMA_CCR_OPT_SAF
+                                                  | ALT_DMA_CCR_OPT_SP_DEFAULT
+                                                  | ALT_DMA_CCR_OPT_SC_DEFAULT
+                                                  | ALT_DMA_CCR_OPT_DB16
+                                                  | ALT_DMA_CCR_OPT_DA_DEFAULT
+                                                  | ALT_DMA_CCR_OPT_DP_DEFAULT
+                                                  | ALT_DMA_CCR_OPT_DC_DEFAULT
+                                                  | ALT_DMA_CCR_OPT_ES_DEFAULT
+                                                )
+                    );
+            }
+
+            // See how many 256x 16-length bursts we can do
+            if (length16burst >> 8)
+            {
+                uint32_t loop256length16burst = length16burst >> 8;
+                length16burst &= ((1 << 8) - 1);
+
+                dprintf("DMA[R->M]:     Number of 256-looped 16 burst length transfer(s): %lu.\n", loop256length16burst);
+                dprintf("DMA[R->M]:     Number of remaining 16 burst length transfer(s):  %lu.\n", length16burst);
+
+                while (loop256length16burst > 0)
+                {
+                    if (status != ALT_E_SUCCESS)
+                    {
+                        break;
+                    }
+
+                    uint32_t loopcount = MIN(loop256length16burst, 256);
+                    loop256length16burst -= loopcount;
+
+                    dprintf("DMA[R->M]:     Looping %lux super loop transfer(s).\n", loopcount);
+
+                    if ((status == ALT_E_SUCCESS) && (loopcount > 1))
+                    {
+                        status = alt_dma_program_DMALP(program, loopcount);
+                    }
+
+                    if (status == ALT_E_SUCCESS)
+                    {
+                        status = alt_dma_program_DMALP(program, 256);
+                    }
+                    if (status == ALT_E_SUCCESS)
+                    {
+                        status = alt_dma_program_DMALD(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
+                    }
+                    if (status == ALT_E_SUCCESS)
+                    {
+                        status = alt_dma_program_DMAST(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
+                    }
+                    if (status == ALT_E_SUCCESS)
+                    {
+                        status = alt_dma_program_DMALPEND(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
+                    }
+
+                    if ((status == ALT_E_SUCCESS) && (loopcount > 1))
+                    {
+                        status = alt_dma_program_DMALPEND(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
+                    }
+                }
+            }
+
+            // The super loop above ensures that the length16burst is below 256.
+            if (length16burst > 0)
+            {
+                uint32_t loopcount = length16burst;
+                length16burst = 0;
+
+                dprintf("DMA[R->M]:   Looping %lux 16 burst length transfer(s).\n", loopcount);
+
+                if ((status == ALT_E_SUCCESS) && (loopcount > 1))
+                {
+                    status = alt_dma_program_DMALP(program, loopcount);
+                }
+                if (status == ALT_E_SUCCESS)
+                {
+                    status = alt_dma_program_DMALD(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
+                }
+                if (status == ALT_E_SUCCESS)
+                {
+                    status = alt_dma_program_DMAST(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
+                }
+                if ((status == ALT_E_SUCCESS) && (loopcount > 1))
+                {
+                    status = alt_dma_program_DMALPEND(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
+                }
+            }
+        }
+
+        // At this point, we should have [countleft] transfer(s) remaining.
+        // [countleft] should be less than 16.
+
+        if (countleft)
+        {
+            dprintf("DMA[R->M]:   Tail end %lux transfer(s).\n", countleft);
+
+            // Program in the following parameters:
+            //  - SAF (Source      address fixed)
+            //  - SSx (Source      burst size of [ccr_ss_ds_mask])
+            //  - DSx (Destination burst size of [ccr_ss_ds_mask])
+            //  - SBx (Source      burst length of [countleft] transfer(s))
+            //  - DBx (Destination burst length of [countleft] transfer(s))
+            //  - All other options default.
+
+            if (status == ALT_E_SUCCESS)
+            {
+                status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_CCR,
+                                                (   ccr_ss_ds_mask
+                                                  | ((countleft - 1) << 4) // SB
+                                                  | ALT_DMA_CCR_OPT_SAF
+                                                  | ALT_DMA_CCR_OPT_SP_DEFAULT
+                                                  | ALT_DMA_CCR_OPT_SC_DEFAULT
+                                                  | ((countleft - 1) << 18) // DB
+                                                  | ALT_DMA_CCR_OPT_DA_DEFAULT
+                                                  | ALT_DMA_CCR_OPT_DP_DEFAULT
+                                                  | ALT_DMA_CCR_OPT_DC_DEFAULT
+                                                  | ALT_DMA_CCR_OPT_ES_DEFAULT
+                                                )
+                    );
+            }
+
+            if (status == ALT_E_SUCCESS)
+            {
+                status = alt_dma_program_DMALD(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
+            }
+            if (status == ALT_E_SUCCESS)
+            {
+                status = alt_dma_program_DMAST(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
+            }
+        }
+
+    } // if (count != 0)
+
+    // Send event if requested.
+    if (send_evt)
+    {
+        if (status == ALT_E_SUCCESS)
+        {
+            dprintf("DMA[R->M]: Adding event ...\n");
+            status = alt_dma_program_DMASEV(program, evt);
+        }
+    }
+
+    // Now that everything is done, end the program.
+    if (status == ALT_E_SUCCESS)
+    {
+        status = alt_dma_program_DMAEND(program);
+    }
+
+    // If there was a problem assembling the program, clean up the buffer and exit.
+    if (status != ALT_E_SUCCESS)
+    {
+        // Do not report the status for the clear operation. A failure should be
+        // reported regardless of if the clear is successful.
+        alt_dma_program_clear(program);
+        return status;
+    }
+
+    // Execute the program on the given channel.
+    return alt_dma_channel_exec(channel, program);
+}
+
+#if ALT_DMA_PERIPH_PROVISION_QSPI_SUPPORT
+static ALT_STATUS_CODE alt_dma_memory_to_qspi(ALT_DMA_PROGRAM_t * program,
+                                              const char * src,
+                                              size_t size)
+{
+    if ((uintptr_t)src & 0x3)
+    {
+        return ALT_E_ERROR;
+    }
+
+    if (size & 0x3)
+    {
+        return ALT_E_ERROR;
+    }
+
+    /////
+
+    ALT_STATUS_CODE status = ALT_E_SUCCESS;
+
+    if (status == ALT_E_SUCCESS)
+    {
+        status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_DAR,
+                                        (uint32_t)ALT_QSPIDATA_ADDR);
+    }
+    if (status == ALT_E_SUCCESS)
+    {
+        status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_SAR,
+                                        (uint32_t)src);
+    }
+
+    /////
+
+    uint32_t dmaper = alt_read_word(ALT_QSPI_DMAPER_ADDR);
+    uint32_t qspi_single_size_log2 = ALT_QSPI_DMAPER_NUMSGLREQBYTES_GET(dmaper);
+    uint32_t qspi_burst_size_log2  = ALT_QSPI_DMAPER_NUMBURSTREQBYTES_GET(dmaper);
+    uint32_t qspi_single_size      = 1 << qspi_single_size_log2;
+    uint32_t qspi_burst_size       = 1 << qspi_burst_size_log2;
+
+    dprintf("DMA[M->P][QSPI]: QSPI Single = %lu; Burst = %lu.\n", qspi_single_size, qspi_burst_size);
+
+    // Because single transfers are equal or smaller than burst (and in the
+    // smaller case, it is always a clean multiple), only the single size
+    // check is needed for transfer composability.
+    if (size & (qspi_single_size - 1))
+    {
+        dprintf("DMA[M->P][QSPI]: QSPI DMA size configuration not suitable for transfer request.\n");
+        return ALT_E_ERROR;
+    }
+
+    /////
+
+    if ((uintptr_t)src & 0x7)
+    {
+        // Source address is not 8-byte aligned. Do 1x 32-bit transfer to get it 8-byte aligned.
+
+        dprintf("DMA[M->P][QSPI]: Creating 1x 4-byte aligning transfer.\n");
+
+        if (status == ALT_E_SUCCESS)
+        {
+            status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_CCR,
+                                            (   ALT_DMA_CCR_OPT_SAI
+                                              | ALT_DMA_CCR_OPT_SS32
+                                              | ALT_DMA_CCR_OPT_SB1
+                                              | ALT_DMA_CCR_OPT_SP_DEFAULT
+                                              | ALT_DMA_CCR_OPT_SC_DEFAULT
+                                              | ALT_DMA_CCR_OPT_DAF
+                                              | ALT_DMA_CCR_OPT_DS32
+                                              | ALT_DMA_CCR_OPT_DB1
+                                              | ALT_DMA_CCR_OPT_DP_DEFAULT
+                                              | ALT_DMA_CCR_OPT_DC_DEFAULT
+                                              | ALT_DMA_CCR_OPT_ES_DEFAULT
+                                            )
+                );
+        }
+
+        if (status == ALT_E_SUCCESS)
+        {
+            status = alt_dma_program_DMAFLUSHP(program, ALT_DMA_PERIPH_QSPI_FLASH_TX);
+        }
+
+        if (status == ALT_E_SUCCESS)
+        {
+            status = alt_dma_program_DMAWFP(program, ALT_DMA_PERIPH_QSPI_FLASH_TX, ALT_DMA_PROGRAM_INST_MOD_SINGLE);
+        }
+
+        if (status == ALT_E_SUCCESS)
+        {
+            status = alt_dma_program_DMALD(program, ALT_DMA_PROGRAM_INST_MOD_SINGLE);
+        }
+
+        if (status == ALT_E_SUCCESS)
+        {
+            status = alt_dma_program_DMAST(program, ALT_DMA_PROGRAM_INST_MOD_SINGLE);
+        }
+
+        size -= sizeof(uint32_t);
+    }
+
+    uint32_t qspi_single_count = 0;
+    uint32_t qspi_burst_count  = size >> qspi_burst_size_log2;
+
+    // Use QSPI burst transfers if:
+    //  - QSPI bursts are larger than QSPI singles [AND]
+    //  - Size is large enough that at least 1 burst will be used.
+
+    if (   (qspi_burst_size_log2 > qspi_single_size_log2)
+        && (qspi_burst_count != 0)
+       )
+    {
+        // qspi_burst_count = size >> qspi_burst_size_log2;
+        qspi_single_count   = (size & (qspi_burst_size - 1)) >> qspi_single_size_log2;
+
+        dprintf("DMA[M->P][QSPI][B]: Burst size = %lu bytes, count = %lu.\n", qspi_burst_size, qspi_burst_count);
+
+        // 1 << 3 => 8 bytes => 64 bits, which is the width of the AXI bus.
+        uint32_t src_size_log2 = MIN(3, qspi_burst_size_log2);
+
+        uint32_t src_length   = 0;
+        uint32_t src_multiple = 0;
+
+        if ((qspi_burst_size >> src_size_log2) <= 16)
+        {
+            src_length   = qspi_burst_size >> src_size_log2;
+            src_multiple = 1;
+        }
+        else
+        {
+            src_length   = 16;
+            src_multiple = (qspi_burst_size >> src_size_log2) >> 4; // divide by 16
+
+            if (src_multiple == 0)
+            {
+                dprintf("DEBUG[QSPI][B]: src_multiple is 0.\n");
+                status = ALT_E_ERROR;
+            }
+        }
+
+        // uint32_t dst_length = 1; // dst_length is always 1 because the address is fixed.
+        uint32_t dst_multiple = qspi_burst_size >> 2; // divide by sizeof(uint32_t)
+
+        dprintf("DMA[M->P][QSPI][B]: dst_size = %u bits, dst_length = %u, dst_multiple = %lu.\n",
+                32,                       1,          dst_multiple);
+        dprintf("DMA[M->P][QSPI][B]: src_size = %u bits, src_length = %lu, src_multiple = %lu.\n",
+                (1 << src_size_log2) * 8, src_length, src_multiple);
+
+        /////
+
+        // Program in the following parameters:
+        //  - SAI  (Source      address increment)
+        //  - SSx  (Source      burst size of [1 << src_size_log2]-bytes)
+        //  - SBx  (Source      burst length of [src_length] transfer(s))
+        //  - DAF  (Destination address fixed)
+        //  - DS32 (Destination burst size of 4-bytes)
+        //  - DB1  (Destination burst length of 1 transfer)
+        //  - All other parameters default
+
+        if (status == ALT_E_SUCCESS)
+        {
+            status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_CCR,
+                                            (   ALT_DMA_CCR_OPT_SAI
+                                              | (src_size_log2 << 1) // SS
+                                              | ((src_length - 1) << 4) // SB
+                                              | ALT_DMA_CCR_OPT_SP_DEFAULT
+                                              | ALT_DMA_CCR_OPT_SC_DEFAULT
+                                              | ALT_DMA_CCR_OPT_DAF
+                                              | ALT_DMA_CCR_OPT_DS32
+                                              | ALT_DMA_CCR_OPT_DB1
+                                              | ALT_DMA_CCR_OPT_DP_DEFAULT
+                                              | ALT_DMA_CCR_OPT_DC_DEFAULT
+                                              | ALT_DMA_CCR_OPT_ES_DEFAULT
+                                            )
+                );
+        }
+
+        // NOTE: We do not do the 256x bursts for M->P case because we only
+        //   write up to 256 B at a time.
+
+        while (qspi_burst_count > 0)
+        {
+            if (status != ALT_E_SUCCESS)
+            {
+                break;
+            }
+
+            uint32_t loopcount = MIN(qspi_burst_count, 256);
+            qspi_burst_count -= loopcount;
+
+            dprintf("DMA[M->P][QSPI][B]: Creating %lu burst-type transfer(s).\n", loopcount);
+
+            if ((status == ALT_E_SUCCESS) && (loopcount > 1))
+            {
+                status = alt_dma_program_DMALP(program, loopcount);
+            }
+
+            if (status == ALT_E_SUCCESS)
+            {
+                status = alt_dma_program_DMAFLUSHP(program, ALT_DMA_PERIPH_QSPI_FLASH_TX);
+            }
+            if (status == ALT_E_SUCCESS)
+            {
+                status = alt_dma_program_DMAWFP(program, ALT_DMA_PERIPH_QSPI_FLASH_TX, ALT_DMA_PROGRAM_INST_MOD_BURST);
+            }
+            for (uint32_t j = 0; j < src_multiple; ++j)
+            {
+                if (status == ALT_E_SUCCESS)
+                {
+                    status = alt_dma_program_DMALD(program, ALT_DMA_PROGRAM_INST_MOD_BURST);
+                }
+            }
+            for (uint32_t k = 0; k < dst_multiple; ++k)
+            {
+                if (status == ALT_E_SUCCESS)
+                {
+                    status = alt_dma_program_DMAST(program, ALT_DMA_PROGRAM_INST_MOD_BURST);
+                }
+            }
+
+            if ((status == ALT_E_SUCCESS) && (loopcount > 1))
+            {
+                status = alt_dma_program_DMALPEND(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
+            }
+        }
+    }
+    else
+    {
+        qspi_single_count = size >> qspi_single_size_log2;
+    }
+
+    // Assemble the single portion of the DMA program.
+    if (qspi_single_count)
+    {
+        dprintf("DMA[M->P][QSPI][S]: Single size = %lu bytes, count = %lu.\n", qspi_single_size, qspi_single_count);
+
+        // 1 << 3 => 8 bytes => 64 bits, which is the width of the AXI bus.
+        uint32_t src_size_log2 = MIN(3, qspi_single_size_log2);
+
+        uint32_t src_length   = 0;
+        uint32_t src_multiple = 0;
+
+        if ((qspi_single_size >> src_size_log2) <= 16)
+        {
+            src_length   = qspi_single_size >> src_size_log2;
+            src_multiple = 1;
+        }
+        else
+        {
+            src_length   = 16;
+            src_multiple = (qspi_single_size >> src_size_log2) >> 4; // divide by 16
+
+            if (src_multiple == 0)
+            {
+                dprintf("DEBUG[QSPI][S]: src_multiple is 0.\n");
+                status = ALT_E_ERROR;
+            }
+        }
+
+        // uint32_t dst_length = 1; // dst_length is always 1 becaus the address is fixed.
+        uint32_t dst_multiple = qspi_single_size >> 2; // divide by sizeof(uint32_t)
+
+        dprintf("DMA[M->P][QSPI][S]: dst_size = %u bits, dst_length = %u, dst_multiple = %lu.\n",
+                32,                      1,          dst_multiple);
+        dprintf("DMA[M->P][QSPI][S]: src_size = %u bits, src_length = %lu, src_multiple = %lu.\n",
+                (1 <<src_size_log2) * 8, src_length, src_multiple);
+
+        /////
+
+        // Program in the following parameters:
+        //  - SAI  (Source      address increment)
+        //  - SSx  (Source      burst size of [1 << src_size_log2]-bytes)
+        //  - SBx  (Source      burst length of [src_length] transfer(s))
+        //  - DAF  (Destination address fixed)
+        //  - DS32 (Destination burst size of 4-bytes)
+        //  - DB1  (Destination burst length of 1 transfer)
+        //  - All other parameters default
+
+        if (status == ALT_E_SUCCESS)
+        {
+            status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_CCR,
+                                            (   ALT_DMA_CCR_OPT_SAI
+                                              | (src_size_log2 << 1) // SS
+                                              | ((src_length - 1) << 4) // SB
+                                              | ALT_DMA_CCR_OPT_SP_DEFAULT
+                                              | ALT_DMA_CCR_OPT_SC_DEFAULT
+                                              | ALT_DMA_CCR_OPT_DAF
+                                              | ALT_DMA_CCR_OPT_DS32
+                                              | ALT_DMA_CCR_OPT_DB1
+                                              | ALT_DMA_CCR_OPT_DP_DEFAULT
+                                              | ALT_DMA_CCR_OPT_DC_DEFAULT
+                                              | ALT_DMA_CCR_OPT_ES_DEFAULT
+                                            )
+                );
+        }
+
+        // NOTE: We do not do the 256x bursts for M->P case because we only
+        //   write up to 256 B at a time.
+
+        while (qspi_single_count > 0)
+        {
+            if (status != ALT_E_SUCCESS)
+            {
+                break;
+            }
+
+            uint32_t loopcount = MIN(qspi_single_count, 256);
+            qspi_single_count -= loopcount;
+
+            dprintf("DMA[M->P][QSPI][S]: Creating %lu single-type transfer(s).\n", loopcount);
+
+            if ((status == ALT_E_SUCCESS) && (loopcount > 1))
+            {
+                status = alt_dma_program_DMALP(program, loopcount);
+            }
+
+            if (status == ALT_E_SUCCESS)
+            {
+                status = alt_dma_program_DMAFLUSHP(program, ALT_DMA_PERIPH_QSPI_FLASH_TX);
+            }
+            if (status == ALT_E_SUCCESS)
+            {
+                status = alt_dma_program_DMAWFP(program, ALT_DMA_PERIPH_QSPI_FLASH_TX, ALT_DMA_PROGRAM_INST_MOD_SINGLE);
+            }
+            for (uint32_t j = 0; j < src_multiple; ++j)
+            {
+                if (status == ALT_E_SUCCESS)
+                {
+                    status = alt_dma_program_DMALD(program, ALT_DMA_PROGRAM_INST_MOD_SINGLE);
+                }
+            }
+            for (uint32_t k = 0; k < dst_multiple; ++k)
+            {
+                if (status == ALT_E_SUCCESS)
+                {
+                    status = alt_dma_program_DMAST(program, ALT_DMA_PROGRAM_INST_MOD_SINGLE);
+                }
+            }
+
+            if ((status == ALT_E_SUCCESS) && (loopcount > 1))
+            {
+                status = alt_dma_program_DMALPEND(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
+            }
+        }
+
+    } // if (qspi_single_count != 0)
+
+    return status;
+}
+
+static ALT_STATUS_CODE alt_dma_qspi_to_memory(ALT_DMA_PROGRAM_t * program,
+                                              char * dst,
+                                              size_t size)
+{
+    if ((uintptr_t)dst & 0x3)
+    {
+        return ALT_E_ERROR;
+    }
+
+    if (size & 0x3)
+    {
+        return ALT_E_ERROR;
+    }
+
+    /////
+
+    ALT_STATUS_CODE status = ALT_E_SUCCESS;
+
+    if (status == ALT_E_SUCCESS)
+    {
+        status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_DAR,
+                                        (uint32_t)dst);
+    }
+    if (status == ALT_E_SUCCESS)
+    {
+        status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_SAR,
+                                        (uint32_t)ALT_QSPIDATA_ADDR);
+    }
+
+    /////
+
+    uint32_t dmaper = alt_read_word(ALT_QSPI_DMAPER_ADDR);
+    uint32_t qspi_single_size_log2 = ALT_QSPI_DMAPER_NUMSGLREQBYTES_GET(dmaper);
+    uint32_t qspi_burst_size_log2  = ALT_QSPI_DMAPER_NUMBURSTREQBYTES_GET(dmaper);
+    uint32_t qspi_single_size      = 1 << qspi_single_size_log2;
+    uint32_t qspi_burst_size       = 1 << qspi_burst_size_log2;
+
+    dprintf("DMA[P->M][QSPI]: QSPI Single = %lu; Burst = %lu.\n", qspi_single_size, qspi_burst_size);
+
+    // Because single transfers are equal or smaller than burst (and in the
+    // smaller case, it is always a clean multiple), only the single size
+    // check is needed for transfer composability.
+    if (size & (qspi_single_size - 1))
+    {
+        dprintf("DMA[P->M][QSPI]: QSPI DMA size configuration not suitable for transfer request.\n");
+        return ALT_E_ERROR;
+    }
+
+    /////
+
+    if ((uintptr_t)dst & 0x7)
+    {
+        // Destination address is not 8-byte aligned. Do 1x 32-bit transfer to get it 8-byte aligned.
+
+        dprintf("DMA[P->M][QSPI]: Creating 1x 4-byte aligning transfer.\n");
+
+        if (status == ALT_E_SUCCESS)
+        {
+            status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_CCR,
+                                            (   ALT_DMA_CCR_OPT_SAF
+                                              | ALT_DMA_CCR_OPT_SS32
+                                              | ALT_DMA_CCR_OPT_SB1
+                                              | ALT_DMA_CCR_OPT_SP_DEFAULT
+                                              | ALT_DMA_CCR_OPT_SC_DEFAULT
+                                              | ALT_DMA_CCR_OPT_DAI
+                                              | ALT_DMA_CCR_OPT_DS32
+                                              | ALT_DMA_CCR_OPT_DB1
+                                              | ALT_DMA_CCR_OPT_DP_DEFAULT
+                                              | ALT_DMA_CCR_OPT_DC_DEFAULT
+                                              | ALT_DMA_CCR_OPT_ES_DEFAULT
+                                            )
+                );
+        }
+
+        if (status == ALT_E_SUCCESS)
+        {
+            status = alt_dma_program_DMAFLUSHP(program, ALT_DMA_PERIPH_QSPI_FLASH_RX);
+        }
+
+        if (status == ALT_E_SUCCESS)
+        {
+            status = alt_dma_program_DMAWFP(program, ALT_DMA_PERIPH_QSPI_FLASH_RX, ALT_DMA_PROGRAM_INST_MOD_SINGLE);
+        }
+
+        if (status == ALT_E_SUCCESS)
+        {
+            status = alt_dma_program_DMALD(program, ALT_DMA_PROGRAM_INST_MOD_SINGLE);
+        }
+
+        if (status == ALT_E_SUCCESS)
+        {
+            status = alt_dma_program_DMAST(program, ALT_DMA_PROGRAM_INST_MOD_SINGLE);
+        }
+
+        size -= sizeof(uint32_t);
+    }
+
+    uint32_t qspi_single_count = 0;
+    uint32_t qspi_burst_count  = size >> qspi_burst_size_log2;
+
+    // Use QSPI burst transfers if:
+    //  - QSPI bursts are larger than QSPI singles [AND]
+    //  - Size is large enough that at least 1 burst will be used.
+
+    if (   (qspi_burst_size_log2 > qspi_single_size_log2)
+        && (qspi_burst_count != 0)
+       )
+    {
+        // qspi_burst_count = size >> qspi_burst_size_log2;
+        qspi_single_count   = (size & (qspi_burst_size - 1)) >> qspi_single_size_log2;
+
+        dprintf("DMA[P->M][QSPI][B]: Burst size = %lu bytes, count = %lu.\n", qspi_burst_size, qspi_burst_count);
+
+        // 1 << 3 => 8 bytes => 64 bits, which is the width of the AXI bus.
+        uint32_t dst_size_log2 = MIN(3, qspi_burst_size_log2);
+
+        uint32_t dst_length   = 0;
+        uint32_t dst_multiple = 0;
+
+        if ((qspi_burst_size >> dst_size_log2) <= 16)
+        {
+            dst_length   = qspi_burst_size >> dst_size_log2;
+            dst_multiple = 1;
+        }
+        else
+        {
+            dst_length   = 16;
+            dst_multiple = (qspi_burst_size >> dst_size_log2) >> 4; // divide by 16
+
+            if (dst_multiple == 0)
+            {
+                dprintf("DEBUG[QSPI][B]: dst_multiple is 0.\n");
+                status = ALT_E_ERROR;
+            }
+        }
+
+        // uint32_t src_length = 1; // src_length is always 1 because the address is fixed.
+        uint32_t src_multiple = qspi_burst_size >> 2; // divide by sizeof(uint32_t)
+
+        dprintf("DMA[P->M][QSPI][B]: dst_size = %u bits, dst_length = %lu, dst_multiple = %lu.\n", 
+                (1 << dst_size_log2) * 8, dst_length, dst_multiple);
+        dprintf("DMA[P->M][QSPI][B]: src_size = %u bits, src_length = %u, src_multiple = %lu.\n",
+                32,                       1,          src_multiple);
+
+        /////
+
+        // Program in the following parameters:
+        //  - SAF  (Source      address fixed)
+        //  - SS32 (Source      burst size of 4-bytes)
+        //  - SB1  (Source      burst length of 1 transfer)
+        //  - DAI  (Destination address increment)
+        //  - DSx  (Destination burst size of [1 << dst_size_log2]-bytes])
+        //  - DBx  (Destination burst length of [dst_length] transfer(s))
+        //  - All other parameters default
+
+        if (status == ALT_E_SUCCESS)
+        {
+            status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_CCR,
+                                            (   ALT_DMA_CCR_OPT_SAF
+                                              | ALT_DMA_CCR_OPT_SS32
+                                              | ALT_DMA_CCR_OPT_SB1
+                                              | ALT_DMA_CCR_OPT_SP_DEFAULT
+                                              | ALT_DMA_CCR_OPT_SC_DEFAULT
+                                              | ALT_DMA_CCR_OPT_DAI
+                                              | (dst_size_log2 << 15) // DS
+                                              | ((dst_length - 1) << 18) // DB
+                                              | ALT_DMA_CCR_OPT_DP_DEFAULT
+                                              | ALT_DMA_CCR_OPT_DC_DEFAULT
+                                              | ALT_DMA_CCR_OPT_ES_DEFAULT
+                                            )
+                );
+        }
+
+        // See how many 256x bursts we can construct. This will allow for extremely large requests.
+
+        if (qspi_burst_count >> 8)
+        {
+            uint32_t qspi_burst256_count = qspi_burst_count >> 8;
+            qspi_burst_count &= (1 << 8) - 1;
+
+            while (qspi_burst256_count > 0)
+            {
+                if (status != ALT_E_SUCCESS)
+                {
+                    break;
+                }
+
+                uint32_t loopcount = MIN(qspi_burst256_count, 256);
+                qspi_burst256_count -= loopcount;
+
+                dprintf("DMA[P->M][QSPI][B]: Creating %lu 256x burst-type transfer(s).\n", loopcount);
+
+                // Outer loop {
+
+                if ((status == ALT_E_SUCCESS) && (loopcount > 1))
+                {
+                    status = alt_dma_program_DMALP(program, loopcount);
+                }
+
+                // Inner loop {
+
+                if (status == ALT_E_SUCCESS)
+                {
+                    status = alt_dma_program_DMALP(program, 256);
+                }
+
+                if (status == ALT_E_SUCCESS)
+                {
+                    status = alt_dma_program_DMAFLUSHP(program, ALT_DMA_PERIPH_QSPI_FLASH_RX);
+                }
+                if (status == ALT_E_SUCCESS)
+                {
+                    status = alt_dma_program_DMAWFP(program, ALT_DMA_PERIPH_QSPI_FLASH_RX, ALT_DMA_PROGRAM_INST_MOD_BURST);
+                }
+                for (uint32_t j = 0; j < src_multiple; ++j)
+                {
+                    if (status == ALT_E_SUCCESS)
+                    {
+                        status = alt_dma_program_DMALD(program, ALT_DMA_PROGRAM_INST_MOD_BURST);
+                    }
+                }
+                for (uint32_t k = 0; k < dst_multiple; ++k)
+                {
+                    if (status == ALT_E_SUCCESS)
+                    {
+                        status = alt_dma_program_DMAST(program, ALT_DMA_PROGRAM_INST_MOD_BURST);
+                    }
+                }
+
+                if (status == ALT_E_SUCCESS)
+                {
+                    status = alt_dma_program_DMALPEND(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
+                }
+
+                // } Inner loop
+
+                if ((status == ALT_E_SUCCESS) && (loopcount > 1))
+                {
+                    status = alt_dma_program_DMALPEND(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
+                }
+
+                // } Outer loop
+            }
+        }
+
+        while (qspi_burst_count > 0)
+        {
+            if (status != ALT_E_SUCCESS)
+            {
+                break;
+            }
+
+            uint32_t loopcount = MIN(qspi_burst_count, 256);
+            qspi_burst_count -= loopcount;
+
+            dprintf("DMA[P->M][QSPI][B]: Creating %lu burst-type transfer(s).\n", loopcount);
+
+            if ((status == ALT_E_SUCCESS) && (loopcount > 1))
+            {
+                status = alt_dma_program_DMALP(program, loopcount);
+            }
+
+            if (status == ALT_E_SUCCESS)
+            {
+                status = alt_dma_program_DMAFLUSHP(program, ALT_DMA_PERIPH_QSPI_FLASH_RX);
+            }
+            if (status == ALT_E_SUCCESS)
+            {
+                status = alt_dma_program_DMAWFP(program, ALT_DMA_PERIPH_QSPI_FLASH_RX, ALT_DMA_PROGRAM_INST_MOD_BURST);
+            }
+            for (uint32_t j = 0; j < src_multiple; ++j)
+            {
+                if (status == ALT_E_SUCCESS)
+                {
+                    status = alt_dma_program_DMALD(program, ALT_DMA_PROGRAM_INST_MOD_BURST);
+                }
+            }
+            for (uint32_t k = 0; k < dst_multiple; ++k)
+            {
+                if (status == ALT_E_SUCCESS)
+                {
+                    status = alt_dma_program_DMAST(program, ALT_DMA_PROGRAM_INST_MOD_BURST);
+                }
+            }
+
+            if ((status == ALT_E_SUCCESS) && (loopcount > 1))
+            {
+                status = alt_dma_program_DMALPEND(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
+            }
+        }
+    }
+    else
+    {
+        qspi_single_count = size >> qspi_single_size_log2;
+    }
+
+    // Assemble the single portion of the DMA program.
+    if (qspi_single_count)
+    {
+        dprintf("DMA[P->M][QSPI][S]: Single size = %lu bytes, count = %lu.\n", qspi_single_size, qspi_single_count);
+
+        // 1 << 3 => 8 bytes => 64 bits, which is the width of the AXI bus.
+        uint32_t dst_size_log2 = MIN(3, qspi_single_size_log2);
+
+        uint32_t dst_length   = 0;
+        uint32_t dst_multiple = 0;
+
+        if ((qspi_single_size >> dst_size_log2) <= 16)
+        {
+            dst_length   = qspi_single_size >> dst_size_log2;
+            dst_multiple = 1;
+        }
+        else
+        {
+            dst_length   = 16;
+            dst_multiple = (qspi_single_size >> dst_size_log2) >> 4; // divide by 16
+
+            if (dst_multiple == 0)
+            {
+                dprintf("DEBUG[QSPI][S]: dst_multiple is 0.\n");
+                status = ALT_E_ERROR;
+            }
+        }
+
+        // uint32_t src_length = 1; // src_length is always 1 because the address is fixed.
+        uint32_t src_multiple = qspi_single_size >> 2; // divide by sizeof(uint32_t)
+
+        dprintf("DMA[P->M][QSPI][S]: dst_size = %u bits, dst_length = %lu, dst_multiple = %lu.\n",
+                (1 << dst_size_log2) * 8, dst_length, dst_multiple);
+        dprintf("DMA[P->M][QSPI][S]: src_size = %u bits, src_length = %u, src_multiple = %lu.\n",
+                32,                       1,          src_multiple);
+
+        /////
+
+        // Program in the following parameters:
+        //  - SAF  (Source      address fixed)
+        //  - SS32 (Source      burst size of 4-bytes)
+        //  - SB1  (Source      burst length of 1 transfer)
+        //  - DAI  (Destination address increment)
+        //  - DSx  (Destination burst size of [1 << dst_size_log2]-bytes])
+        //  - DBx  (Destination burst length of [dst_length] transfer(s))
+        //  - All other parameters default
+
+        if (status == ALT_E_SUCCESS)
+        {
+            status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_CCR,
+                                            (   ALT_DMA_CCR_OPT_SAF
+                                              | ALT_DMA_CCR_OPT_SS32
+                                              | ALT_DMA_CCR_OPT_SB1
+                                              | ALT_DMA_CCR_OPT_SP_DEFAULT
+                                              | ALT_DMA_CCR_OPT_SC_DEFAULT
+                                              | ALT_DMA_CCR_OPT_DAI
+                                              | (dst_size_log2 << 15) // DS
+                                              | ((dst_length - 1) << 18) // DB
+                                              | ALT_DMA_CCR_OPT_DP_DEFAULT
+                                              | ALT_DMA_CCR_OPT_DC_DEFAULT
+                                              | ALT_DMA_CCR_OPT_ES_DEFAULT
+                                            )
+                );
+        }
+
+        // See how many 256x bursts we can construct. This will allow for extremely large requests.
+
+        if (qspi_single_count >> 8)
+        {
+            uint32_t qspi_single256_count = qspi_single_count >> 8;
+            qspi_single_count &= (1 << 8) - 1;
+
+            while (qspi_single256_count > 0)
+            {
+                if (status != ALT_E_SUCCESS)
+                {
+                    break;
+                }
+
+                uint32_t loopcount = MIN(qspi_single256_count, 256);
+                qspi_single256_count -= loopcount;
+
+                dprintf("DMA[P->M][QSPI][S]: Creating %lu 256x single-type transfer(s).\n", loopcount);
+
+                // Outer loop {
+
+                if ((status == ALT_E_SUCCESS) && (loopcount > 1))
+                {
+                    status = alt_dma_program_DMALP(program, loopcount);
+                }
+
+                // Inner loop {
+
+                if (status == ALT_E_SUCCESS)
+                {
+                    status = alt_dma_program_DMALP(program, 256);
+                }
+
+                if (status == ALT_E_SUCCESS)
+                {
+                    status = alt_dma_program_DMAFLUSHP(program, ALT_DMA_PERIPH_QSPI_FLASH_RX);
+                }
+                if (status == ALT_E_SUCCESS)
+                {
+                    status = alt_dma_program_DMAWFP(program, ALT_DMA_PERIPH_QSPI_FLASH_RX, ALT_DMA_PROGRAM_INST_MOD_SINGLE);
+                }
+                for (uint32_t j = 0; j < src_multiple; ++j)
+                {
+                    if (status == ALT_E_SUCCESS)
+                    {
+                        status = alt_dma_program_DMALD(program, ALT_DMA_PROGRAM_INST_MOD_SINGLE);
+                    }
+                }
+                for (uint32_t k = 0; k < dst_multiple; ++k)
+                {
+                    if (status == ALT_E_SUCCESS)
+                    {
+                        status = alt_dma_program_DMAST(program, ALT_DMA_PROGRAM_INST_MOD_SINGLE);
+                    }
+                }
+
+                if (status == ALT_E_SUCCESS)
+                {
+                    status = alt_dma_program_DMALPEND(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
+                }
+
+                // } Inner loop
+
+                if ((status == ALT_E_SUCCESS) && (loopcount > 1))
+                {
+                    status = alt_dma_program_DMALPEND(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
+                }
+
+                // } Outer loop
+            }
+        }
+
+        while (qspi_single_count > 0)
+        {
+            if (status != ALT_E_SUCCESS)
+            {
+                break;
+            }
+
+            uint32_t loopcount = MIN(qspi_single_count, 256);
+            qspi_single_count -= loopcount;
+
+            dprintf("DMA[P->M][QSPI][S]: Creating %lu single-type transfer(s).\n", loopcount);
+
+            if ((status == ALT_E_SUCCESS) && (loopcount > 1))
+            {
+                status = alt_dma_program_DMALP(program, loopcount);
+            }
+
+            if (status == ALT_E_SUCCESS)
+            {
+                status = alt_dma_program_DMAFLUSHP(program, ALT_DMA_PERIPH_QSPI_FLASH_RX);
+            }
+            if (status == ALT_E_SUCCESS)
+            {
+                status = alt_dma_program_DMAWFP(program, ALT_DMA_PERIPH_QSPI_FLASH_RX, ALT_DMA_PROGRAM_INST_MOD_SINGLE);
+            }
+            for (uint32_t j = 0; j < src_multiple; ++j)
+            {
+                if (status == ALT_E_SUCCESS)
+                {
+                    status = alt_dma_program_DMALD(program, ALT_DMA_PROGRAM_INST_MOD_SINGLE);
+                }
+            }
+            for (uint32_t k = 0; k < dst_multiple; ++k)
+            {
+                if (status == ALT_E_SUCCESS)
+                {
+                    status = alt_dma_program_DMAST(program, ALT_DMA_PROGRAM_INST_MOD_SINGLE);
+                }
+            }
+
+            if ((status == ALT_E_SUCCESS) && (loopcount > 1))
+            {
+                status = alt_dma_program_DMALPEND(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
+            }
+        }
+
+    } // if (qspi_single_count != 0)
+
+    return status;
+}
+#endif // ALT_DMA_PERIPH_PROVISION_QSPI_SUPPORT
+
+#if ALT_DMA_PERIPH_PROVISION_16550_SUPPORT
+static ALT_STATUS_CODE alt_dma_memory_to_16550_single(ALT_DMA_PROGRAM_t * program,
+                                                      ALT_DMA_PERIPH_t periph,
+                                                      size_t size)
+{
+    ALT_STATUS_CODE status = ALT_E_SUCCESS;
+
+    // Program in the following parameters:
+    //  - SS8 (Source      burst size of 1-byte)
+    //  - DS8 (Destination burst size of 1-byte)
+    //  - SB1 (Source      burst length of 1 transfer)
+    //  - DB1 (Destination burst length of 1 transfer)
+    //  - DAF (Destination address fixed)
+    //  - All other options default.
+
+    if (status == ALT_E_SUCCESS)
+    {
+        status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_CCR,
+                                        (   ALT_DMA_CCR_OPT_SB1
+                                          | ALT_DMA_CCR_OPT_SS8
+                                          | ALT_DMA_CCR_OPT_SA_DEFAULT
+                                          | ALT_DMA_CCR_OPT_SP_DEFAULT
+                                          | ALT_DMA_CCR_OPT_SC_DEFAULT
+                                          | ALT_DMA_CCR_OPT_DB1
+                                          | ALT_DMA_CCR_OPT_DS8
+                                          | ALT_DMA_CCR_OPT_DAF
+                                          | ALT_DMA_CCR_OPT_DP_DEFAULT
+                                          | ALT_DMA_CCR_OPT_DC_DEFAULT
+                                          | ALT_DMA_CCR_OPT_ES_DEFAULT
+                                        )
+            );
+    }
+
+    uint32_t sizeleft = size;
+
+    while (sizeleft > 0)
+    {
+        if (status != ALT_E_SUCCESS)
+        {
+            break;
+        }
+
+        uint32_t loopcount = MIN(sizeleft, 256);
+        sizeleft -= loopcount;
+
+        dprintf("DMA[M->P][16550][S]: Creating %lu transfer(s).\n", loopcount);
+
+        if ((status == ALT_E_SUCCESS) && (loopcount > 1))
+        {
+            status = alt_dma_program_DMALP(program, loopcount);
+        }
+
+        if (status == ALT_E_SUCCESS)
+        {
+            status = alt_dma_program_DMAFLUSHP(program, periph);
+        }
+        if (status == ALT_E_SUCCESS)
+        {
+            status = alt_dma_program_DMAWFP(program, periph, ALT_DMA_PROGRAM_INST_MOD_SINGLE);
+        }
+        if (status == ALT_E_SUCCESS)
+        {
+            status = alt_dma_program_DMALD(program, ALT_DMA_PROGRAM_INST_MOD_SINGLE);
+        }
+        if (status == ALT_E_SUCCESS)
+        {
+            status = alt_dma_program_DMAST(program, ALT_DMA_PROGRAM_INST_MOD_SINGLE);
+        }
+
+        if ((status == ALT_E_SUCCESS) && (loopcount > 1))
+        {
+            status = alt_dma_program_DMALPEND(program, ALT_DMA_PROGRAM_INST_MOD_SINGLE);
+        }
+    }
+
+    return status;
+}
+
+static ALT_STATUS_CODE alt_dma_memory_to_16550_burst(ALT_DMA_PROGRAM_t * program,
+                                                     ALT_DMA_PERIPH_t periph,
+                                                     size_t burst_size,
+                                                     size_t burst_count)
+{
+    ALT_STATUS_CODE status = ALT_E_SUCCESS;
+
+    // Program in the following parameters:
+    //  - SS8  (Source      burst size of 1-byte)
+    //  - DS8  (Destination burst size of 1-byte)
+    //  - SB16 (Source      burst length of 16 transfers)
+    //  - DB16 (Destination burst length of 16 transfers)
+    //  - DAF  (Source      address fixed)
+    //  - All other options default.
+
+    if (status == ALT_E_SUCCESS)
+    {
+        status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_CCR,
+                                        (   ALT_DMA_CCR_OPT_SB16
+                                          | ALT_DMA_CCR_OPT_SS8
+                                          | ALT_DMA_CCR_OPT_SA_DEFAULT
+                                          | ALT_DMA_CCR_OPT_SP_DEFAULT
+                                          | ALT_DMA_CCR_OPT_SC_DEFAULT
+                                          | ALT_DMA_CCR_OPT_DB16
+                                          | ALT_DMA_CCR_OPT_DS8
+                                          | ALT_DMA_CCR_OPT_DAF
+                                          | ALT_DMA_CCR_OPT_DP_DEFAULT
+                                          | ALT_DMA_CCR_OPT_DC_DEFAULT
+                                          | ALT_DMA_CCR_OPT_ES_DEFAULT
+                                        )
+            );
+    }
+
+    while (burst_count > 0)
+    {
+        if (status != ALT_E_SUCCESS)
+        {
+            break;
+        }
+
+        uint32_t loopcount = MIN(burst_count, 256);
+        burst_count -= loopcount;
+
+        dprintf("DMA[M->P][16550][B]: Creating outer %lu inner loop(s).\n", loopcount);
+
+        // Outer loop {
+
+        if ((status == ALT_E_SUCCESS) && (loopcount > 1))
+        {
+            status = alt_dma_program_DMALP(program, loopcount);
+        }
+        if (status == ALT_E_SUCCESS)
+        {
+            status = alt_dma_program_DMAFLUSHP(program, periph);
+        }
+        if (status == ALT_E_SUCCESS)
+        {
+            status = alt_dma_program_DMAWFP(program, periph, ALT_DMA_PROGRAM_INST_MOD_BURST);
+        }
+
+        // Inner loop {
+
+        // Loop [burst_size / 16] times. The burst_size was trimmed to the
+        // nearest multiple of 16 by the caller. Each burst does 16 transfers
+        // hence the need for the divide.
+
+        dprintf("DMA[M->P][16550][B]: Creating inner %u transfer(s).\n", burst_size >> 4);
+
+        if (status == ALT_E_SUCCESS)
+        {
+            status = alt_dma_program_DMALP(program, burst_size >> 4); // divide by 16.
+        }
+        if (status == ALT_E_SUCCESS)
+        {
+            status = alt_dma_program_DMALD(program, ALT_DMA_PROGRAM_INST_MOD_BURST);
+        }
+        if (status == ALT_E_SUCCESS)
+        {
+            status = alt_dma_program_DMAST(program, ALT_DMA_PROGRAM_INST_MOD_BURST);
+        }
+        if (status == ALT_E_SUCCESS)
+        {
+            status = alt_dma_program_DMALPEND(program, ALT_DMA_PROGRAM_INST_MOD_BURST);
+        }
+
+        // } Inner loop
+
+        if ((status == ALT_E_SUCCESS) && (loopcount > 1))
+        {
+            status = alt_dma_program_DMALPEND(program, ALT_DMA_PROGRAM_INST_MOD_BURST);
+        }
+
+        // } Outer loop
+    }
+
+    return status;
+}
+
+static ALT_STATUS_CODE alt_dma_memory_to_16550(ALT_DMA_PROGRAM_t * program,
+                                               ALT_DMA_PERIPH_t periph,
+                                               ALT_16550_HANDLE_t * handle,
+                                               const void * src,
+                                               size_t size)
+{
+    ALT_STATUS_CODE status = ALT_E_SUCCESS;
+
+    if (status == ALT_E_SUCCESS)
+    {
+        status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_DAR,
+                                        (uint32_t)ALT_UART_RBR_THR_DLL_ADDR(handle->location));
+    }
+    if (status == ALT_E_SUCCESS)
+    {
+        status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_SAR,
+                                        (uint32_t)src);
+    }
+
+    // Determine if FIFOs are enabled from the FCR cache
+
+    if (ALT_UART_FCR_FIFOE_GET(handle->fcr) != 0)
+    {
+        dprintf("DMA[M->P][16550]: FIFOs enabled.\n");
+
+        //
+        // FIFOs are enabled.
+        //
+
+        uint32_t tx_size;
+        uint32_t burst_size;
+        ALT_16550_FIFO_TRIGGER_TX_t trig_tx;
+
+        // Get the TX FIFO Size
+        // Use the register interface to avoid coupling the 16550 and DMA.
+        tx_size = ALT_UART_CPR_FIFO_MOD_GET(alt_read_word(ALT_UART_CPR_ADDR(handle->location))) << 4;
+
+        // Get the TX FIFO Trigger Level from the FCR cache
+        trig_tx = (ALT_16550_FIFO_TRIGGER_TX_t)ALT_UART_FCR_TET_GET(handle->fcr);
+
+        switch (trig_tx)
+        {
+        case ALT_16550_FIFO_TRIGGER_TX_EMPTY:
+            burst_size = tx_size;
+            break;
+        case ALT_16550_FIFO_TRIGGER_TX_ALMOST_EMPTY:
+            burst_size = tx_size - 2;
+            break;
+        case ALT_16550_FIFO_TRIGGER_TX_QUARTER_FULL:
+            burst_size = 3 * (tx_size >> 2);
+            break;
+        case ALT_16550_FIFO_TRIGGER_TX_HALF_FULL:
+            burst_size = tx_size >> 1;
+            break;
+        default:
+            // This case should never happen.
+            return ALT_E_ERROR;
+        }
+
+        if (burst_size < 16)
+        {
+            // There's no point bursting 1 byte at a time per notify, so just do single transfers.
+            if (status == ALT_E_SUCCESS)
+            {
+                status = alt_dma_memory_to_16550_single(program,
+                                                        periph,
+                                                        size);
+            }
+        }
+        else
+        {
+            uint32_t sizeleft = size;
+
+            // Now trip the burst size to a multiple of 16.
+            // This will optimize the bursting in the fewest possible commands.
+            dprintf("DMA[M->P][16550]: Untrimmed burst size = %lu.\n", burst_size);
+            burst_size &= ~0xf;
+            dprintf("DMA[M->P][16550]: Trimmed burst size   = %lu.\n", burst_size);
+
+            // Determine how many burst transfers can be done
+            uint32_t burst_count = 0;
+
+            burst_count = sizeleft / burst_size;
+            sizeleft -= burst_count * burst_size;
+
+            if (burst_count == 0)
+            {
+                // Do the transfer
+                if (status == ALT_E_SUCCESS)
+                {
+                    status = alt_dma_memory_to_16550_single(program,
+                                                            periph,
+                                                            sizeleft);
+                }
+            }
+            else
+            {
+                // Do the burst transfers
+                if (status == ALT_E_SUCCESS)
+                {
+                    status = alt_dma_memory_to_16550_burst(program,
+                                                           periph,
+                                                           burst_size,
+                                                           burst_count);
+                }
+
+                // Program the DMA engine to transfer the non-burstable items in single tranfers
+                if (status == ALT_E_SUCCESS)
+                {
+                    status = alt_dma_memory_to_16550_single(program,
+                                                            periph,
+                                                            sizeleft);
+                }
+
+            } // else if (burst_count == 0)
+        }
+    }
+    else
+    {
+        dprintf("DMA[M->P][16550]: FIFOs disabled.\n");
+
+        //
+        // FIFOs are disabled.
+        //
+
+        status = alt_dma_memory_to_16550_single(program,
+                                                periph,
+                                                size);
+    }
+
+    return status;
+}
+
+static ALT_STATUS_CODE alt_dma_16550_to_memory_single(ALT_DMA_PROGRAM_t * program,
+                                                      ALT_DMA_PERIPH_t periph,
+                                                      size_t size)
+{
+    ALT_STATUS_CODE status = ALT_E_SUCCESS;
+
+    // Program in the following parameters:
+    //  - SS8 (Source      burst size of 1-byte)
+    //  - DS8 (Destination burst size of 1-byte)
+    //  - SB1 (Source      burst length of 1 transfer)
+    //  - DB1 (Destination burst length of 1 transfer)
+    //  - SAF (Source      address fixed)
+    //  - All other options default.
+
+    if (status == ALT_E_SUCCESS)
+    {
+        status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_CCR,
+                                        (   ALT_DMA_CCR_OPT_SB1
+                                          | ALT_DMA_CCR_OPT_SS8
+                                          | ALT_DMA_CCR_OPT_SAF
+                                          | ALT_DMA_CCR_OPT_SP_DEFAULT
+                                          | ALT_DMA_CCR_OPT_SC_DEFAULT
+                                          | ALT_DMA_CCR_OPT_DB1
+                                          | ALT_DMA_CCR_OPT_DS8
+                                          | ALT_DMA_CCR_OPT_DA_DEFAULT
+                                          | ALT_DMA_CCR_OPT_DP_DEFAULT
+                                          | ALT_DMA_CCR_OPT_DC_DEFAULT
+                                          | ALT_DMA_CCR_OPT_ES_DEFAULT
+                                        )
+            );
+    }
+
+    uint32_t sizeleft = size;
+
+    while (sizeleft > 0)
+    {
+        if (status != ALT_E_SUCCESS)
+        {
+            break;
+        }
+
+        uint32_t loopcount = MIN(sizeleft, 256);
+        sizeleft -= loopcount;
+
+        dprintf("DMA[P->M][16550][S]: Creating %lu transfer(s).\n", loopcount);
+
+        if ((status == ALT_E_SUCCESS) && (loopcount > 1))
+        {
+            status = alt_dma_program_DMALP(program, loopcount);
+        }
+        if (status == ALT_E_SUCCESS)
+        {
+            status = alt_dma_program_DMAFLUSHP(program, periph);
+        }
+        if (status == ALT_E_SUCCESS)
+        {
+            status = alt_dma_program_DMAWFP(program, periph, ALT_DMA_PROGRAM_INST_MOD_SINGLE);
+        }
+        if (status == ALT_E_SUCCESS)
+        {
+            status = alt_dma_program_DMALD(program, ALT_DMA_PROGRAM_INST_MOD_SINGLE);
+        }
+        if (status == ALT_E_SUCCESS)
+        {
+            status = alt_dma_program_DMAST(program, ALT_DMA_PROGRAM_INST_MOD_SINGLE);
+        }
+        if ((status == ALT_E_SUCCESS) && (loopcount > 1))
+        {
+            status = alt_dma_program_DMALPEND(program, ALT_DMA_PROGRAM_INST_MOD_SINGLE);
+        }
+    }
+
+    return status;
+}                                              
+
+static ALT_STATUS_CODE alt_dma_16550_to_memory_burst(ALT_DMA_PROGRAM_t * program,
+                                                     ALT_DMA_PERIPH_t periph,
+                                                     size_t burst_size,
+                                                     size_t burst_count)
+{
+    ALT_STATUS_CODE status = ALT_E_SUCCESS;
+
+    // Program in the following parameters:
+    //  - SS8  (Source      burst size of 1-byte)
+    //  - DS8  (Destination burst size of 1-byte)
+    //  - SB16 (Source      burst length of 16 transfers)
+    //  - DB16 (Destination burst length of 16 transfers)
+    //  - SAF  (Source      address fixed)
+    //  - All other options default.
+
+    if (status == ALT_E_SUCCESS)
+    {
+        status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_CCR,
+                                        (   ALT_DMA_CCR_OPT_SB16
+                                          | ALT_DMA_CCR_OPT_SS8
+                                          | ALT_DMA_CCR_OPT_SAF
+                                          | ALT_DMA_CCR_OPT_SP_DEFAULT
+                                          | ALT_DMA_CCR_OPT_SC_DEFAULT
+                                          | ALT_DMA_CCR_OPT_DB16
+                                          | ALT_DMA_CCR_OPT_DS8
+                                          | ALT_DMA_CCR_OPT_DA_DEFAULT
+                                          | ALT_DMA_CCR_OPT_DP_DEFAULT
+                                          | ALT_DMA_CCR_OPT_DC_DEFAULT
+                                          | ALT_DMA_CCR_OPT_ES_DEFAULT
+                                        )
+            );
+    }
+
+    while (burst_count > 0)
+    {
+        if (status != ALT_E_SUCCESS)
+        {
+            break;
+        }
+
+        uint32_t loopcount = MIN(burst_count, 256);
+        burst_count -= loopcount;
+
+        dprintf("DMA[P->M][16550][B]: Creating outer %lu inner loop(s).\n", loopcount);
+
+        // Outer loop {
+
+        if ((status == ALT_E_SUCCESS) && (loopcount > 1))
+        {
+            status = alt_dma_program_DMALP(program, loopcount);
+        }
+        if (status == ALT_E_SUCCESS)
+        {
+            status = alt_dma_program_DMAFLUSHP(program, periph);
+        }
+        if (status == ALT_E_SUCCESS)
+        {
+            status = alt_dma_program_DMAWFP(program, periph, ALT_DMA_PROGRAM_INST_MOD_BURST);
+        }
+
+        // Inner loop {
+
+        // Loop [burst_size / 16] times. The burst_size was trimmed to the
+        // nearest multiple of 16 by the caller. Each burst does 16 transfers
+        // hence the need for the divide.
+
+        dprintf("DMA[P->M][16550][B]: Creating inner %u transfer(s).\n", burst_size >> 4);
+
+        if (status == ALT_E_SUCCESS)
+        {
+            status = alt_dma_program_DMALP(program, burst_size >> 4); // divide by 16.
+        }
+        if (status == ALT_E_SUCCESS)
+        {
+            status = alt_dma_program_DMALD(program, ALT_DMA_PROGRAM_INST_MOD_BURST);
+        }
+        if (status == ALT_E_SUCCESS)
+        {
+            status = alt_dma_program_DMAST(program, ALT_DMA_PROGRAM_INST_MOD_BURST);
+        }
+        if (status == ALT_E_SUCCESS)
+        {
+            status = alt_dma_program_DMALPEND(program, ALT_DMA_PROGRAM_INST_MOD_BURST);
+        }
+
+        // } Inner loop
+
+        if ((status == ALT_E_SUCCESS) && (loopcount > 1))
+        {
+            status = alt_dma_program_DMALPEND(program, ALT_DMA_PROGRAM_INST_MOD_BURST);
+        }
+
+        // } Outer loop
+    }
+
+    return status;
+}
+
+static ALT_STATUS_CODE alt_dma_16550_to_memory(ALT_DMA_PROGRAM_t * program,
+                                               ALT_DMA_PERIPH_t periph,
+                                               ALT_16550_HANDLE_t * handle,
+                                               void * dst,
+                                               size_t size)
+{
+    ALT_STATUS_CODE status = ALT_E_SUCCESS;
+
+    if (status == ALT_E_SUCCESS)
+    {
+        status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_DAR, (uint32_t)dst);
+    }
+    if (status == ALT_E_SUCCESS)
+    {
+        status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_SAR, (uint32_t)ALT_UART_RBR_THR_DLL_ADDR(handle->location));
+    }
+
+    // Determine if FIFOs are enabled from the FCR cache
+
+    if (ALT_UART_FCR_FIFOE_GET(handle->fcr) != 0)
+    {
+        dprintf("DMA[P->M][16550]: FIFOs enabled.\n");
+
+        //
+        // FIFOs are enabled.
+        //
+
+        uint32_t rx_size;
+        uint32_t burst_size;
+        ALT_16550_FIFO_TRIGGER_RX_t trig_rx;
+
+        // Get the RX FIFO Size
+        // Use the register interface to avoid coupling the 16550 and DMA.
+        rx_size = ALT_UART_CPR_FIFO_MOD_GET(alt_read_word(ALT_UART_CPR_ADDR(handle->location))) << 4;
+
+        // Get the RX FIFO Trigger Level from the FCR cache
+        trig_rx = (ALT_16550_FIFO_TRIGGER_RX_t)ALT_UART_FCR_RT_GET(handle->fcr);
+
+        switch (trig_rx)
+        {
+        case ALT_16550_FIFO_TRIGGER_RX_ANY:
+            burst_size = 1;
+            break;
+        case ALT_16550_FIFO_TRIGGER_RX_QUARTER_FULL:
+            burst_size = rx_size >> 2; // divide by 4
+            break;
+        case ALT_16550_FIFO_TRIGGER_RX_HALF_FULL:
+            burst_size = rx_size >> 1; // divide by 2
+            break;
+        case ALT_16550_FIFO_TRIGGER_RX_ALMOST_FULL:
+            burst_size = rx_size - 2;
+            break;
+        default:
+            // This case should never happen.
+            return ALT_E_ERROR;
+        }
+
+        if (burst_size < 16)
+        {
+            // There's no point bursting 1 byte at a time per notify, so just do single transfers.
+            if (status == ALT_E_SUCCESS)
+            {
+                status = alt_dma_16550_to_memory_single(program,
+                                                        periph,
+                                                        size);
+            }
+        }
+        else
+        {
+            uint32_t sizeleft = size;
+
+            // Now trim the burst size to a multiple of 16.
+            // This will optimize the bursting in the fewest possible commands.
+            dprintf("DMA[P->M][16550]: Untrimmed burst size = %lu.\n", burst_size);
+            burst_size &= ~0xf;
+            dprintf("DMA[P->M][16550]: Trimmed burst size   = %lu.\n", burst_size);
+
+            // Determine how many burst transfers can be done
+            uint32_t burst_count = 0;
+
+            burst_count = sizeleft / burst_size;
+            sizeleft -= burst_count * burst_size;
+
+            if (burst_count == 0)
+            {
+                // Do the transfer.
+                if (status == ALT_E_SUCCESS)
+                {
+                    status = alt_dma_16550_to_memory_single(program,
+                                                            periph,
+                                                            sizeleft);
+                }
+            }
+            else
+            {
+                // Do the burst transfers
+                if (status == ALT_E_SUCCESS)
+                {
+                    status = alt_dma_16550_to_memory_burst(program,
+                                                           periph,
+                                                           burst_size,
+                                                           burst_count);
+                }
+
+                // Program the DMA engine to transfer the non-burstable items in single transfers.
+                if (status == ALT_E_SUCCESS)
+                {
+                    status = alt_dma_16550_to_memory_single(program,
+                                                            periph,
+                                                            sizeleft);
+                }
+
+            } // if (burst_count == 0)
+        }
+    }
+    else
+    {
+        dprintf("DMA[P->M][16550]: FIFOs disabled.\n");
+
+        //
+        // FIFOs are disabled.
+        //
+
+        status = alt_dma_16550_to_memory_single(program,
+                                                periph,
+                                                size);
+    }
+
+    return status;
+}
+#endif // ALT_DMA_PERIPH_PROVISION_16550_SUPPORT
+
+ALT_STATUS_CODE alt_dma_memory_to_periph(ALT_DMA_CHANNEL_t channel,
+                                         ALT_DMA_PROGRAM_t * program,
+                                         ALT_DMA_PERIPH_t dstp,
+                                         const void * src,
+                                         size_t size,
+                                         void * periph_info,
+                                         bool send_evt,
+                                         ALT_DMA_EVENT_t evt)
+{
+    ALT_STATUS_CODE status = ALT_E_SUCCESS;
+
+    if ((size == 0) && (send_evt == false))
+    {
+        return status;
+    }
+
+    if (status == ALT_E_SUCCESS)
+    {
+        dprintf("DMA[M->P]: Init Program.\n");
+        status = alt_dma_program_init(program);
+    }
+
+    if ((status == ALT_E_SUCCESS) && (size != 0))
+    {
+        switch (dstp)
+        {
+#if ALT_DMA_PERIPH_PROVISION_QSPI_SUPPORT
+        case ALT_DMA_PERIPH_QSPI_FLASH_TX:
+            status = alt_dma_memory_to_qspi(program, src, size);
+            break;
+#endif
+
+#if ALT_DMA_PERIPH_PROVISION_16550_SUPPORT
+        case ALT_DMA_PERIPH_UART0_TX:
+        case ALT_DMA_PERIPH_UART1_TX:
+            status = alt_dma_memory_to_16550(program, dstp,
+                                             (ALT_16550_HANDLE_t *)periph_info, src, size);
+            break;
+#endif
+
+        case ALT_DMA_PERIPH_FPGA_0:
+        case ALT_DMA_PERIPH_FPGA_1:
+        case ALT_DMA_PERIPH_FPGA_2:
+        case ALT_DMA_PERIPH_FPGA_3:
+        case ALT_DMA_PERIPH_FPGA_4:
+        case ALT_DMA_PERIPH_FPGA_5:
+        case ALT_DMA_PERIPH_FPGA_6:
+        case ALT_DMA_PERIPH_FPGA_7:
+        case ALT_DMA_PERIPH_I2C0_TX:
+        case ALT_DMA_PERIPH_I2C1_TX:
+        case ALT_DMA_PERIPH_I2C2_TX:
+        case ALT_DMA_PERIPH_I2C3_TX:
+        case ALT_DMA_PERIPH_SPI0_MASTER_TX:
+        case ALT_DMA_PERIPH_SPI0_SLAVE_TX:
+        case ALT_DMA_PERIPH_SPI1_MASTER_TX:
+        case ALT_DMA_PERIPH_SPI1_SLAVE_TX:
+
+        default:
+            status = ALT_E_BAD_ARG;
+            break;
+        }
+    }
+
+    // Send event if requested.
+    if (send_evt)
+    {
+        if (status == ALT_E_SUCCESS)
+        {
+            dprintf("DMA[M->P]: Adding event.\n");
+            status = alt_dma_program_DMASEV(program, evt);
+        }
+    }
+
+    // Now that everything is done, end the program.
+    if (status == ALT_E_SUCCESS)
+    {
+        status = alt_dma_program_DMAEND(program);
+    }
+
+    // If there was a problem assembling the program, clean up the buffer and exit.
+    if (status != ALT_E_SUCCESS)
+    {
+        // Do not report the status for the clear operation. A failure should be
+        // reported regardless of if the clear is successful.
+        alt_dma_program_clear(program);
+        return status;
+    }
+
+    // Execute the program on the given channel.
+
+    return alt_dma_channel_exec(channel, program);
+}
+
+ALT_STATUS_CODE alt_dma_periph_to_memory(ALT_DMA_CHANNEL_t channel,
+                                         ALT_DMA_PROGRAM_t * program,
+                                         void * dst,
+                                         ALT_DMA_PERIPH_t srcp,
+                                         size_t size,
+                                         void * periph_info,
+                                         bool send_evt,
+                                         ALT_DMA_EVENT_t evt)
+{
+    ALT_STATUS_CODE status = ALT_E_SUCCESS;
+
+    if ((size == 0) && (send_evt == false))
+    {
+        return ALT_E_SUCCESS;
+    }
+
+    if (status == ALT_E_SUCCESS)
+    {
+        dprintf("DMA[P->M]: Init Program.\n");
+        status = alt_dma_program_init(program);
+    }
+
+    if ((status == ALT_E_SUCCESS) && (size != 0))
+    {
+        switch (srcp)
+        {
+#if ALT_DMA_PERIPH_PROVISION_QSPI_SUPPORT
+        case ALT_DMA_PERIPH_QSPI_FLASH_RX:
+            status = alt_dma_qspi_to_memory(program, dst, size);
+            break;
+#endif
+
+#if ALT_DMA_PERIPH_PROVISION_16550_SUPPORT
+        case ALT_DMA_PERIPH_UART0_RX:
+        case ALT_DMA_PERIPH_UART1_RX:
+            status = alt_dma_16550_to_memory(program, srcp,
+                                             (ALT_16550_HANDLE_t *)periph_info, dst, size);
+            break;
+#endif
+
+        case ALT_DMA_PERIPH_FPGA_0:
+        case ALT_DMA_PERIPH_FPGA_1:
+        case ALT_DMA_PERIPH_FPGA_2:
+        case ALT_DMA_PERIPH_FPGA_3:
+        case ALT_DMA_PERIPH_FPGA_4:
+        case ALT_DMA_PERIPH_FPGA_5:
+        case ALT_DMA_PERIPH_FPGA_6:
+        case ALT_DMA_PERIPH_FPGA_7:
+        case ALT_DMA_PERIPH_I2C0_RX:
+        case ALT_DMA_PERIPH_I2C1_RX:
+        case ALT_DMA_PERIPH_I2C2_RX:
+        case ALT_DMA_PERIPH_I2C3_RX:
+        case ALT_DMA_PERIPH_SPI0_MASTER_RX:
+        case ALT_DMA_PERIPH_SPI0_SLAVE_RX:
+        case ALT_DMA_PERIPH_SPI1_MASTER_RX:
+        case ALT_DMA_PERIPH_SPI1_SLAVE_RX:
+
+        default:
+            status = ALT_E_BAD_ARG;
+            break;
+        }
+    }
+
+    // Send event if requested.
+    if (send_evt)
+    {
+        if (status == ALT_E_SUCCESS)
+        {
+            dprintf("DMA[P->M]: Adding event.\n");
+            status = alt_dma_program_DMASEV(program, evt);
+        }
+    }
+
+    // Now that everything is done, end the program.
+    if (status == ALT_E_SUCCESS)
+    {
+        status = alt_dma_program_DMAEND(program);
+    }
+
+    // If there was a problem assembling the program, clean up the buffer and exit.
+    if (status != ALT_E_SUCCESS)
+    {
+        // Do not report the status for the clear operation. A failure should be
+        // reported regardless of if the clear is successful.
+        alt_dma_program_clear(program);
+        return status;
+    }
+
+    // Execute the program on the given channel.
+
+    return alt_dma_channel_exec(channel, program);
+}
+
+/////
+
+static bool alt_dma_is_init(void)
+{
+    uint32_t permodrst = alt_read_word(ALT_RSTMGR_PERMODRST_ADDR);
+
+    if (permodrst & ALT_RSTMGR_PERMODRST_DMA_SET_MSK)
+    {
+        return false;
+    }
+    else
+    {
+        return true;
+    }
+}
+
+ALT_STATUS_CODE alt_dma_ecc_start(void * block, size_t size)
+{
+    if (alt_dma_is_init() == false)
+    {
+        return ALT_E_ERROR;
+    }
+
+    if ((uintptr_t)block & (sizeof(uint64_t) - 1))
+    {
+        return ALT_E_ERROR;
+    }
+
+    // Verify that all channels are either unallocated or allocated and idle.
+
+    for (int i = 0; i < ARRAY_COUNT(channel_info_array); ++i)
+    {
+        if (channel_info_array[i].flag & ALT_DMA_CHANNEL_INFO_FLAG_ALLOCED)
+        {
+            ALT_DMA_CHANNEL_STATE_t state;
+            alt_dma_channel_state_get((ALT_DMA_CHANNEL_t)i, &state);
+
+            if (state != ALT_DMA_CHANNEL_STATE_STOPPED)
+            {
+                dprintf("DMA[ECC]: Error: Channel %d state is non-stopped (%d).\n", i, (int)state);
+                return ALT_E_ERROR;
+            }
+        }
+    }
+
+    /////
+
+    // Enable ECC for DMA RAM
+
+    dprintf("DEBUG[DMA][ECC]: Enable ECC in SysMgr.\n");
+    alt_write_word(ALT_SYSMGR_ECC_DMA_ADDR, ALT_SYSMGR_ECC_DMA_EN_SET_MSK);
+
+    // Clear any pending spurious DMA ECC interrupts.
+
+    dprintf("DEBUG[DMA][ECC]: Clear any pending spurious ECC status in SysMgr.\n");
+    alt_write_word(ALT_SYSMGR_ECC_DMA_ADDR,
+                     ALT_SYSMGR_ECC_DMA_EN_SET_MSK
+                   | ALT_SYSMGR_ECC_DMA_SERR_SET_MSK
+                   | ALT_SYSMGR_ECC_DMA_DERR_SET_MSK);
+
+    return ALT_E_SUCCESS;
+}
diff --git a/c/src/lib/libbsp/arm/altera-cyclone-v/hwlib/src/hwmgr/alt_dma_program.c b/c/src/lib/libbsp/arm/altera-cyclone-v/hwlib/src/hwmgr/alt_dma_program.c
new file mode 100644
index 0000000..26de4c7
--- /dev/null
+++ b/c/src/lib/libbsp/arm/altera-cyclone-v/hwlib/src/hwmgr/alt_dma_program.c
@@ -0,0 +1,1064 @@
+/******************************************************************************
+ *
+ * Copyright 2013 Altera Corporation. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ ******************************************************************************/
+
+#include "alt_dma_program.h"
+#include "alt_cache.h"
+#include <stdio.h>
+
+/////
+
+// NOTE: To enable debugging output, delete the next line and uncomment the
+//   line after.
+#define dprintf(...)
+// #define dprintf(fmt, ...) printf(fmt, ##__VA_ARGS__)
+
+/////
+
+//
+// The following section describes how the bits are used in the "flag" field:
+//
+
+// [17:16] Which loop registers (LOOP0, LOOP1) are currently being used by a
+//   partially assembled program. LOOP0 is always used before LOOP1. LOOP1 is
+//   always ended before LOOP0.
+#define ALT_DMA_PROGRAM_FLAG_LOOP0 (1UL << 16)
+#define ALT_DMA_PROGRAM_FLAG_LOOP1 (1UL << 17)
+#define ALT_DMA_PROGRAM_FLAG_LOOP_ALL (ALT_DMA_PROGRAM_FLAG_LOOP0 | ALT_DMA_PROGRAM_FLAG_LOOP1)
+
+// [18] Flag that marks LOOP0 as a forever loop. Said another way, LOOP0 is
+//   being used to execute the DMALPFE directive.
+#define ALT_DMA_PROGRAM_FLAG_LOOP0_IS_FE (1UL << 18)
+// [19] Flag that marks LOOP1 as a forever loop. Said another way, LOOP1 is
+//   being used to execute the DMALPFE directive.
+#define ALT_DMA_PROGRAM_FLAG_LOOP1_IS_FE (1UL << 19)
+
+// [24] Flag that the first SAR has been programmed. The SAR field is valid and
+//    is the offset from the start of the buffer where SAR is located.
+#define ALT_DMA_PROGRAM_FLAG_SAR (1UL << 24)
+// [25] Flag that the first DAR has been programmed. The DAR field is valid and
+//    is the offset from the start of the buffer where DAR is located.
+#define ALT_DMA_PROGRAM_FLAG_DAR (1UL << 25)
+
+// [31] Flag that marks the last assembled instruction as DMAEND.
+#define ALT_DMA_PROGRAM_FLAG_ENDED (1UL << 31)
+
+/////
+
+ALT_STATUS_CODE alt_dma_program_init(ALT_DMA_PROGRAM_t * pgm)
+{
+    // Clear the variables that matter.
+    pgm->flag      = 0;
+    pgm->code_size = 0;
+
+    // Calculate the cache aligned start location of the buffer.
+    size_t buffer = (size_t)pgm->program;
+    size_t offset = ((buffer + ALT_DMA_PROGRAM_CACHE_LINE_SIZE - 1) & ~(ALT_DMA_PROGRAM_CACHE_LINE_SIZE - 1)) - buffer;
+
+    // It is safe to cast to uint16_t because the extra offset can only be up to
+    // (ALT_DMA_PROGRAM_CACHE_LINE_SIZE - 1) or 31, which is within range of the
+    // uint16_t.
+    pgm->buffer_start = (uint16_t)offset;
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_dma_program_uninit(ALT_DMA_PROGRAM_t * pgm)
+{
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_dma_program_clear(ALT_DMA_PROGRAM_t * pgm)
+{
+    // Clear the variables that matter
+    pgm->flag      = 0;
+    pgm->code_size = 0;
+
+    return ALT_E_SUCCESS;
+}
+
+__attribute__((weak)) ALT_STATUS_CODE alt_cache_system_clean(void * address, size_t length)
+{
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_dma_program_validate(const ALT_DMA_PROGRAM_t * pgm)
+{
+    // Verify that at least one instruction is in the buffer
+    if (pgm->code_size == 0)
+    {
+        return ALT_E_ERROR;
+    }
+
+    // Verify all loops are completed.
+    if (pgm->flag & ALT_DMA_PROGRAM_FLAG_LOOP_ALL)
+    {
+        return ALT_E_ERROR;
+    }
+
+    // Verify last item is DMAEND
+    if (!(pgm->flag & ALT_DMA_PROGRAM_FLAG_ENDED))
+    {
+        return ALT_E_ERROR;
+    }
+
+    // Sync the DMA program to RAM.
+    void * vaddr  = (void *)((uintptr_t)(pgm->program + pgm->buffer_start) & ~(ALT_CACHE_LINE_SIZE - 1));
+    size_t length = (pgm->code_size + ALT_CACHE_LINE_SIZE) & ~(ALT_CACHE_LINE_SIZE - 1);
+
+    dprintf("DEBUG[DMAP]: Program (real) @ %p, length = 0x%x.\n", pgm->program + pgm->buffer_start, pgm->code_size);
+    dprintf("DEBUG[DMAP]: Clean: addr = %p, length = 0x%x.\n", vaddr, length);
+
+    return alt_cache_system_clean(vaddr, length);
+}
+
+ALT_STATUS_CODE alt_dma_program_progress_reg(ALT_DMA_PROGRAM_t * pgm,
+                                             ALT_DMA_PROGRAM_REG_t reg,
+                                             uint32_t current, uint32_t * progress)
+{
+    // Pointer to where the register is initialized in the program buffer.
+    uint8_t * buffer = NULL;
+
+    switch (reg)
+    {
+    case ALT_DMA_PROGRAM_REG_SAR:
+        if (!(pgm->flag & ALT_DMA_PROGRAM_FLAG_SAR))
+        {
+            return ALT_E_BAD_ARG;
+        }
+        buffer = pgm->program + pgm->buffer_start + pgm->sar;
+        break;
+
+    case ALT_DMA_PROGRAM_REG_DAR:
+        if (!(pgm->flag & ALT_DMA_PROGRAM_FLAG_DAR))
+        {
+            return ALT_E_BAD_ARG;
+        }
+        buffer = pgm->program + pgm->buffer_start + pgm->dar;
+        break;
+
+    default:
+        return ALT_E_BAD_ARG;
+    }
+
+    uint32_t initial =
+        (buffer[3] << 24) |
+        (buffer[2] << 16) |
+        (buffer[1] <<  8) |
+        (buffer[0] <<  0);
+
+    *progress = current - initial;
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_dma_program_update_reg(ALT_DMA_PROGRAM_t * pgm,
+                                           ALT_DMA_PROGRAM_REG_t reg, uint32_t val)
+{
+    uint8_t * buffer = NULL;
+
+    switch (reg)
+    {
+    case ALT_DMA_PROGRAM_REG_SAR:
+        if (!(pgm->flag & ALT_DMA_PROGRAM_FLAG_SAR))
+        {
+            return ALT_E_BAD_ARG;
+        }
+        buffer = pgm->program + pgm->buffer_start + pgm->sar;
+        break;
+
+    case ALT_DMA_PROGRAM_REG_DAR:
+        if (!(pgm->flag & ALT_DMA_PROGRAM_FLAG_DAR))
+        {
+            return ALT_E_BAD_ARG;
+        }
+        buffer = pgm->program + pgm->buffer_start + pgm->dar;
+        break;
+
+    default:
+        return ALT_E_BAD_ARG;
+    }
+
+    buffer[0] = (uint8_t)((val >>  0) & 0xff);
+    buffer[1] = (uint8_t)((val >>  8) & 0xff);
+    buffer[2] = (uint8_t)((val >> 16) & 0xff);
+    buffer[3] = (uint8_t)((val >> 24) & 0xff);
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_dma_program_DMAADDH(ALT_DMA_PROGRAM_t * pgm,
+                                        ALT_DMA_PROGRAM_REG_t addr_reg, uint16_t val)
+{
+    // For information on DMAADDH, see PL330, section 4.3.1.
+
+    // Check for sufficient space in buffer
+    if ((pgm->code_size + 3) > ALT_DMA_PROGRAM_PROVISION_BUFFER_SIZE)
+    {
+        return ALT_E_BUF_OVF;
+    }
+
+    // Verify valid register; construct instruction modifier.
+    uint8_t ra_mask = 0;
+    switch (addr_reg)
+    {
+    case ALT_DMA_PROGRAM_REG_SAR:
+        ra_mask = 0x0;
+        break;
+    case ALT_DMA_PROGRAM_REG_DAR:
+        ra_mask = 0x2;
+        break;
+    default:
+        return ALT_E_BAD_ARG;
+    }
+
+    // Buffer of where to assemble the instruction.
+    uint8_t * buffer = pgm->program + pgm->buffer_start + pgm->code_size;
+
+    // Assemble DMAADDH
+    buffer[0] = 0x54 | ra_mask;
+    buffer[1] = (uint8_t)(val & 0xff);
+    buffer[2] = (uint8_t)(val >> 8);
+
+    // Update the code size.
+    pgm->code_size += 3;
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_dma_program_DMAADNH(ALT_DMA_PROGRAM_t * pgm,
+                                        ALT_DMA_PROGRAM_REG_t addr_reg, uint16_t val)
+{
+    // For information on DMAADNH, see PL330, section 4.3.2.
+
+    // Check for sufficient space in buffer
+    if ((pgm->code_size + 3) > ALT_DMA_PROGRAM_PROVISION_BUFFER_SIZE)
+    {
+        return ALT_E_BUF_OVF;
+    }
+
+    // Verify valid register; construct instruction modifier.
+    uint8_t ra_mask = 0;
+    switch (addr_reg)
+    {
+    case ALT_DMA_PROGRAM_REG_SAR:
+        ra_mask = 0x0;
+        break;
+    case ALT_DMA_PROGRAM_REG_DAR:
+        ra_mask = 0x2;
+        break;
+    default:
+        return ALT_E_BAD_ARG;
+    }
+
+    // Buffer of where to assemble the instruction.
+    uint8_t * buffer = pgm->program + pgm->buffer_start + pgm->code_size;
+
+    // Assemble DMAADNH
+    buffer[0] = 0x5c | ra_mask;
+    buffer[1] = (uint8_t)(val & 0xff);
+    buffer[2] = (uint8_t)(val >> 8);
+
+    // Update the code size.
+    pgm->code_size += 3;
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_dma_program_DMAEND(ALT_DMA_PROGRAM_t * pgm)
+{
+    // For information on DMAEND, see PL330, section 4.3.3.
+
+    // Check for sufficient space in buffer
+    if ((pgm->code_size + 1) > ALT_DMA_PROGRAM_PROVISION_BUFFER_SIZE)
+    {
+        return ALT_E_BUF_OVF;
+    }
+
+    // Buffer of where to assemble the instruction.
+    uint8_t * buffer = pgm->program + pgm->buffer_start + pgm->code_size;
+
+    // Assemble DMAEND
+    buffer[0] = 0x00;
+
+    // Update the code size.
+    pgm->code_size += 1;
+
+    // Mark program as ended.
+    pgm->flag |= ALT_DMA_PROGRAM_FLAG_ENDED;
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_dma_program_DMAFLUSHP(ALT_DMA_PROGRAM_t * pgm,
+                                          ALT_DMA_PERIPH_t periph)
+{
+    // For information on DMAFLUSHP, see PL330, section 4.3.4.
+
+    // Check for sufficient space in buffer
+    if ((pgm->code_size + 2) > ALT_DMA_PROGRAM_PROVISION_BUFFER_SIZE)
+    {
+        return ALT_E_BUF_OVF;
+    }
+
+    // Verify valid peripheral identifier.
+    if (periph > ((1 << 5) - 1))
+    {
+        return ALT_E_BAD_ARG;
+    }
+
+    // Buffer of where to assemble the instruction.
+    uint8_t * buffer = pgm->program + pgm->buffer_start + pgm->code_size;
+
+    // Assemble DMAFLUSHP
+    buffer[0] = 0x35;
+    buffer[1] = (uint8_t)(periph) << 3;
+
+    // Update the code size.
+    pgm->code_size += 2;
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_dma_program_DMAGO(ALT_DMA_PROGRAM_t * pgm,
+                                      ALT_DMA_CHANNEL_t channel, uint32_t val,
+                                      ALT_DMA_SECURITY_t sec)
+{
+    // For information on DMAGO, see PL330, section 4.3.5.
+
+    // Check for sufficient space in buffer
+    if ((pgm->code_size + 6) > ALT_DMA_PROGRAM_PROVISION_BUFFER_SIZE)
+    {
+        return ALT_E_BUF_OVF;
+    }
+
+    // Verify channel
+    switch (channel)
+    {
+    case ALT_DMA_CHANNEL_0:
+    case ALT_DMA_CHANNEL_1:
+    case ALT_DMA_CHANNEL_2:
+    case ALT_DMA_CHANNEL_3:
+    case ALT_DMA_CHANNEL_4:
+    case ALT_DMA_CHANNEL_5:
+    case ALT_DMA_CHANNEL_6:
+    case ALT_DMA_CHANNEL_7:
+        break;
+    default:
+        return ALT_E_BAD_ARG;
+    }
+
+    // Verify security; construct ns mask value
+    uint8_t ns_mask = 0;
+    switch (sec)
+    {
+    case ALT_DMA_SECURITY_DEFAULT:
+    case ALT_DMA_SECURITY_SECURE:
+        ns_mask = 0x0;
+        break;
+    case ALT_DMA_SECURITY_NONSECURE:
+        ns_mask = 0x2;
+        break;
+    default:
+        return ALT_E_BAD_ARG;
+    }
+
+    // Buffer of where to assemble the instruction.
+    uint8_t * buffer = pgm->program + pgm->buffer_start + pgm->code_size;
+
+    // Assemble DMAGO
+    buffer[0] = 0xa0 | ns_mask;
+    buffer[1] = (uint8_t)channel;
+    buffer[2] = (uint8_t)((val >>  0) & 0xff);
+    buffer[3] = (uint8_t)((val >>  8) & 0xff);
+    buffer[4] = (uint8_t)((val >> 16) & 0xff);
+    buffer[5] = (uint8_t)((val >> 24) & 0xff);
+
+    // Update the code size.
+    pgm->code_size += 6;
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_dma_program_DMAKILL(ALT_DMA_PROGRAM_t * pgm)
+{
+    // For information on DMAKILL, see PL330, section 4.3.6.
+
+    // Check for sufficient space in buffer
+    if ((pgm->code_size + 1) > ALT_DMA_PROGRAM_PROVISION_BUFFER_SIZE)
+    {
+        return ALT_E_BUF_OVF;
+    }
+
+    // Buffer of where to assemble the instruction.
+    uint8_t * buffer = pgm->program + pgm->buffer_start + pgm->code_size;
+
+    // Assemble DMAKILL
+    buffer[0] = 0x01;
+
+    // Update the code size.
+    pgm->code_size += 1;
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_dma_program_DMALD(ALT_DMA_PROGRAM_t * pgm,
+                                      ALT_DMA_PROGRAM_INST_MOD_t mod)
+{
+    // For information on DMALD, see PL330, section 4.3.7.
+
+    // Check for sufficient space in buffer
+    if ((pgm->code_size + 1) > ALT_DMA_PROGRAM_PROVISION_BUFFER_SIZE)
+    {
+        return ALT_E_BUF_OVF;
+    }
+
+    // Verify instruction modifier; construct bs, x mask value.
+    uint8_t bsx_mask = 0;
+    switch (mod)
+    {
+    case ALT_DMA_PROGRAM_INST_MOD_NONE:
+        bsx_mask = 0x0;
+        break;
+    case ALT_DMA_PROGRAM_INST_MOD_SINGLE:
+        bsx_mask = 0x1;
+        break;
+    case ALT_DMA_PROGRAM_INST_MOD_BURST:
+        bsx_mask = 0x3;
+        break;
+    default:
+        return ALT_E_BAD_ARG;
+    }
+
+    // Buffer of where to assemble the instruction.
+    uint8_t * buffer = pgm->program + pgm->buffer_start + pgm->code_size;
+
+    // Assemble DMALD
+    buffer[0] = 0x04 | bsx_mask;
+
+    // Update the code size.
+    pgm->code_size += 1;
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_dma_program_DMALDP(ALT_DMA_PROGRAM_t * pgm,
+                                       ALT_DMA_PROGRAM_INST_MOD_t mod, ALT_DMA_PERIPH_t periph)
+{
+    // For information on DMALDP, see PL330, section 4.3.8.
+
+    // Check for sufficient space in buffer
+    if ((pgm->code_size + 2) > ALT_DMA_PROGRAM_PROVISION_BUFFER_SIZE)
+    {
+        return ALT_E_BUF_OVF;
+    }
+
+    // Verify instruction modifier; construct bs mask value.
+    uint8_t bs_mask = 0;
+    switch (mod)
+    {
+    case ALT_DMA_PROGRAM_INST_MOD_SINGLE:
+        bs_mask = 0x0;
+        break;
+    case ALT_DMA_PROGRAM_INST_MOD_BURST:
+        bs_mask = 0x2;
+        break;
+    default:
+        return ALT_E_BAD_ARG;
+    }
+
+    // Verify valid peripheral identifier.
+    if (periph > ((1 << 5) - 1))
+    {
+        return ALT_E_BAD_ARG;
+    }
+
+    // Buffer of where to assemble the instruction.
+    uint8_t * buffer = pgm->program + pgm->buffer_start + pgm->code_size;
+
+    // Assemble DMALDP
+    buffer[0] = 0x25 | bs_mask;
+    buffer[1] = (uint8_t)(periph) << 3;
+
+    // Update the code size.
+    pgm->code_size += 2;
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_dma_program_DMALP(ALT_DMA_PROGRAM_t * pgm,
+                                      uint32_t iterations)
+{
+    // For information on DMALP, see PL330, section 4.3.9.
+
+    // Check for sufficient space in buffer
+    if ((pgm->code_size + 2) > ALT_DMA_PROGRAM_PROVISION_BUFFER_SIZE)
+    {
+        return ALT_E_BUF_OVF;
+    }
+
+    // Verify iterations in range
+    if ((iterations == 0) || (iterations > 256))
+    {
+        return ALT_E_BAD_ARG;
+    }
+
+    // Find suitable LOOPx register to use; construct lc mask value.
+    uint8_t lc_mask = 0;
+    switch (pgm->flag & ALT_DMA_PROGRAM_FLAG_LOOP_ALL)
+    {
+    case 0:                              // No LOOPx in use. Use LOOP0.
+        pgm->flag |= ALT_DMA_PROGRAM_FLAG_LOOP0;
+        pgm->loop0 = pgm->code_size + 2; // This is the first instruction after the DMALP
+        lc_mask = 0x0;
+        break;
+
+    case ALT_DMA_PROGRAM_FLAG_LOOP0:     // LOOP0 in use. Use LOOP1.
+        pgm->flag |= ALT_DMA_PROGRAM_FLAG_LOOP1;
+        pgm->loop1 = pgm->code_size + 2; // This is the first instruction after the DMALP
+        lc_mask = 0x2;
+        break;
+
+    case ALT_DMA_PROGRAM_FLAG_LOOP_ALL: // All LOOPx in use. Report error.
+        return ALT_E_BAD_OPERATION;
+
+    default:                            // Catastrophic error !!!
+        return ALT_E_ERROR;
+    }
+
+    // Buffer of where to assemble the instruction.
+    uint8_t * buffer = pgm->program + pgm->buffer_start + pgm->code_size;
+
+    // Assemble DMALP
+    buffer[0] = 0x20 | lc_mask;
+    buffer[1] = (uint8_t)(iterations - 1);
+
+    // Update the code size.
+    pgm->code_size += 2;
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_dma_program_DMALPEND(ALT_DMA_PROGRAM_t * pgm,
+                                         ALT_DMA_PROGRAM_INST_MOD_t mod)
+{
+    // For information on DMALPEND, see PL330, section 4.3.10.
+
+    // Check for sufficient space in buffer
+    if ((pgm->code_size + 2) > ALT_DMA_PROGRAM_PROVISION_BUFFER_SIZE)
+    {
+        return ALT_E_BUF_OVF;
+    }
+
+    // Verify instruction modifier; construct bs, x mask value.
+    uint8_t bsx_mask = 0;
+    switch (mod)
+    {
+    case ALT_DMA_PROGRAM_INST_MOD_NONE:
+        bsx_mask = 0x0;
+        break;
+    case ALT_DMA_PROGRAM_INST_MOD_SINGLE:
+        bsx_mask = 0x1;
+        break;
+    case ALT_DMA_PROGRAM_INST_MOD_BURST:
+        bsx_mask = 0x3;
+        break;
+    default:
+        return ALT_E_BAD_ARG;
+    }
+
+    // Determine the loop to end, if it is a forever loop; construct lc mask, nf mask, and backwards jump value.
+    uint8_t lc_mask = 0;
+    uint8_t nf_mask = 0;
+    uint16_t backwards_jump = 0;
+    switch (pgm->flag & ALT_DMA_PROGRAM_FLAG_LOOP_ALL)
+    {
+    case ALT_DMA_PROGRAM_FLAG_LOOP0:    // LOOP0 in use. End LOOP0.
+
+        backwards_jump = pgm->code_size - pgm->loop0;
+
+        pgm->flag &= ~ALT_DMA_PROGRAM_FLAG_LOOP0;
+        pgm->loop0 = 0;
+
+        lc_mask = 0x0;
+
+        if (pgm->flag & ALT_DMA_PROGRAM_FLAG_LOOP0_IS_FE)
+        {
+            pgm->flag &= ~ALT_DMA_PROGRAM_FLAG_LOOP0_IS_FE;
+        }
+        else
+        {
+            nf_mask = 0x10;
+        }
+        break;
+
+    case ALT_DMA_PROGRAM_FLAG_LOOP_ALL: // All LOOPx in use. End LOOP1.
+
+        backwards_jump = pgm->code_size - pgm->loop1;
+
+        pgm->flag &= ~ALT_DMA_PROGRAM_FLAG_LOOP1;
+        pgm->loop1 = 0;
+
+        lc_mask = 0x4;
+
+        if (pgm->flag & ALT_DMA_PROGRAM_FLAG_LOOP1_IS_FE)
+        {
+            pgm->flag &= ~ALT_DMA_PROGRAM_FLAG_LOOP1_IS_FE;
+        }
+        else
+        {
+            nf_mask = 0x10;
+        }
+        break;
+
+    case 0:                             // No LOOPx in use. Report error!
+        return ALT_E_BAD_OPERATION;
+
+    default:                            // Catastrophic error !!!
+        return ALT_E_ERROR;
+    }
+
+    // Verify that the jump size is suitable
+    if (backwards_jump > 255)
+    {
+        return ALT_E_ARG_RANGE;
+    }
+
+    // Buffer of where to assemble the instruction.
+    uint8_t * buffer = pgm->program + pgm->buffer_start + pgm->code_size;
+
+    // Assemble DMALPEND
+    buffer[0] = 0x28 | nf_mask | lc_mask | bsx_mask;
+    buffer[1] = (uint8_t)(backwards_jump);
+
+    // Update the code size.
+    pgm->code_size += 2;
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_dma_program_DMALPFE(ALT_DMA_PROGRAM_t * pgm)
+{
+    // For information on DMALPFE, see PL330, section 4.3.11.
+
+    // Find suitable LOOPx register to use;
+    switch (pgm->flag & ALT_DMA_PROGRAM_FLAG_LOOP_ALL)
+    {
+    case 0:                             // No LOOPx in use. Use LOOP0.
+        pgm->flag |= ALT_DMA_PROGRAM_FLAG_LOOP0;
+        pgm->flag |= ALT_DMA_PROGRAM_FLAG_LOOP0_IS_FE;
+        pgm->loop0 = pgm->code_size;
+        break;
+
+    case ALT_DMA_PROGRAM_FLAG_LOOP0:    // LOOP0 in use. Use LOOP1.
+        pgm->flag |= ALT_DMA_PROGRAM_FLAG_LOOP1;
+        pgm->flag |= ALT_DMA_PROGRAM_FLAG_LOOP1_IS_FE;
+        pgm->loop1 = pgm->code_size;
+        break;
+
+    case ALT_DMA_PROGRAM_FLAG_LOOP_ALL: // All LOOPx in use. Report error.
+        return ALT_E_BAD_OPERATION;
+
+    default:                            // Catastrophic error !!!
+        return ALT_E_ERROR;
+    }
+
+    // Nothing to assemble.
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_dma_program_DMAMOV(ALT_DMA_PROGRAM_t * pgm,
+                                       ALT_DMA_PROGRAM_REG_t chan_reg, uint32_t val)
+{
+    // For information on DMAMOV, see PL330, section 4.3.12.
+
+    // Check for sufficient space in buffer
+    if ((pgm->code_size + 6) > ALT_DMA_PROGRAM_PROVISION_BUFFER_SIZE)
+    {
+        return ALT_E_BUF_OVF;
+    }
+
+    // Verify channel register; construct rd mask value
+    uint8_t rd_mask = 0;
+    switch (chan_reg)
+    {
+    case ALT_DMA_PROGRAM_REG_SAR:
+        rd_mask = 0;
+        // If SAR has not been set before, mark the location of where SAR is in the buffer.
+        if (!(pgm->flag & ALT_DMA_PROGRAM_FLAG_SAR))
+        {
+            pgm->flag |= ALT_DMA_PROGRAM_FLAG_SAR;
+            pgm->sar = pgm->code_size + 2;
+        }
+        break;
+
+    case ALT_DMA_PROGRAM_REG_CCR:
+        rd_mask = 1;
+        break;
+
+    case ALT_DMA_PROGRAM_REG_DAR:
+        rd_mask = 2;
+        // If DAR has not been set before, mark the location of where DAR is in the buffer.
+        if (!(pgm->flag & ALT_DMA_PROGRAM_FLAG_DAR))
+        {
+            pgm->flag |= ALT_DMA_PROGRAM_FLAG_DAR;
+            pgm->dar = pgm->code_size + 2;
+        }
+        break;
+
+    default:
+        return ALT_E_BAD_ARG;
+    }
+
+    // Buffer of where to assemble the instruction.
+    uint8_t * buffer = pgm->program + pgm->buffer_start + pgm->code_size;
+
+    // Assemble DMAMOV
+    buffer[0] = 0xbc;;
+    buffer[1] = rd_mask;
+    buffer[2] = (uint8_t)((val >>  0) & 0xff);
+    buffer[3] = (uint8_t)((val >>  8) & 0xff);
+    buffer[4] = (uint8_t)((val >> 16) & 0xff);
+    buffer[5] = (uint8_t)((val >> 24) & 0xff);
+
+    // Update the code size.
+    pgm->code_size += 6;
+
+    return ALT_E_SUCCESS;
+
+}
+
+ALT_STATUS_CODE alt_dma_program_DMANOP(ALT_DMA_PROGRAM_t * pgm)
+{
+    // For information on DMANOP, see PL330, section 4.3.13.
+
+    // Check for sufficient space in buffer
+    if ((pgm->code_size + 1) > ALT_DMA_PROGRAM_PROVISION_BUFFER_SIZE)
+    {
+        return ALT_E_BUF_OVF;
+    }
+
+    // Buffer of where to assemble the instruction.
+    uint8_t * buffer = pgm->program + pgm->buffer_start + pgm->code_size;
+
+    // Assemble DMANOP
+    buffer[0] = 0x18;
+
+    // Update the code size.
+    pgm->code_size += 1;
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_dma_program_DMARMB(ALT_DMA_PROGRAM_t * pgm)
+{
+    // For information on DMARMB, see PL330, section 4.3.14.
+
+    // Check for sufficient space in buffer
+    if ((pgm->code_size + 1) > ALT_DMA_PROGRAM_PROVISION_BUFFER_SIZE)
+    {
+        return ALT_E_BUF_OVF;
+    }
+
+    // Buffer of where to assemble the instruction.
+    uint8_t * buffer = pgm->program + pgm->buffer_start + pgm->code_size;
+
+    // Assemble DMARMB
+    buffer[0] = 0x12;
+
+    // Update the code size.
+    pgm->code_size += 1;
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_dma_program_DMASEV(ALT_DMA_PROGRAM_t * pgm,
+                                       ALT_DMA_EVENT_t evt)
+{
+    // For information on DMA, see PL330, section 4.3.15.
+
+    // Check for sufficient space in buffer
+    if ((pgm->code_size + 2) > ALT_DMA_PROGRAM_PROVISION_BUFFER_SIZE)
+    {
+        return ALT_E_BUF_OVF;
+    }
+
+    // Validate evt selection
+    switch (evt)
+    {
+    case ALT_DMA_EVENT_0:
+    case ALT_DMA_EVENT_1:
+    case ALT_DMA_EVENT_2:
+    case ALT_DMA_EVENT_3:
+    case ALT_DMA_EVENT_4:
+    case ALT_DMA_EVENT_5:
+    case ALT_DMA_EVENT_6:
+    case ALT_DMA_EVENT_7:
+    case ALT_DMA_EVENT_ABORT:
+        break;
+    default:
+        return ALT_E_BAD_ARG;
+    }
+
+    // Buffer of where to assemble the instruction.
+    uint8_t * buffer = pgm->program + pgm->buffer_start + pgm->code_size;
+
+    // Assemble DMASEV
+    buffer[0] = 0x34;
+    buffer[1] = (uint8_t)(evt) << 3;
+
+    // Update the code size.
+    pgm->code_size += 2;
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_dma_program_DMAST(ALT_DMA_PROGRAM_t * pgm,
+                                      ALT_DMA_PROGRAM_INST_MOD_t mod)
+{
+    // For information on DMAST, see PL330, section 4.3.16.
+
+    // Check for sufficient space in buffer
+    if ((pgm->code_size + 1) > ALT_DMA_PROGRAM_PROVISION_BUFFER_SIZE)
+    {
+        return ALT_E_BUF_OVF;
+    }
+
+    // Verify instruction modifier; construct bs, x mask value.
+    uint8_t bsx_mask = 0;
+    switch (mod)
+    {
+    case ALT_DMA_PROGRAM_INST_MOD_NONE:
+        bsx_mask = 0x0;
+        break;
+    case ALT_DMA_PROGRAM_INST_MOD_SINGLE:
+        bsx_mask = 0x1;
+        break;
+    case ALT_DMA_PROGRAM_INST_MOD_BURST:
+        bsx_mask = 0x3;
+        break;
+    default:
+        return ALT_E_BAD_ARG;
+    }
+
+    // Buffer of where to assemble the instruction.
+    uint8_t * buffer = pgm->program + pgm->buffer_start + pgm->code_size;
+
+    // Assemble DMAST
+    buffer[0] = 0x08 | bsx_mask;
+
+    // Update the code size.
+    pgm->code_size += 1;
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_dma_program_DMASTP(ALT_DMA_PROGRAM_t * pgm,
+                                       ALT_DMA_PROGRAM_INST_MOD_t mod, ALT_DMA_PERIPH_t periph)
+{
+    // For information on DMASTP, see PL330, section 4.3.17.
+
+    // Check for sufficient space in buffer
+    if ((pgm->code_size + 2) > ALT_DMA_PROGRAM_PROVISION_BUFFER_SIZE)
+    {
+        return ALT_E_BUF_OVF;
+    }
+
+    // Verify instruction modifier; construct bs mask value.
+    uint8_t bs_mask = 0;
+    switch (mod)
+    {
+    case ALT_DMA_PROGRAM_INST_MOD_SINGLE:
+        bs_mask = 0x0;
+        break;
+    case ALT_DMA_PROGRAM_INST_MOD_BURST:
+        bs_mask = 0x2;
+        break;
+    default:
+        return ALT_E_BAD_ARG;
+    }
+
+    // Verify valid peripheral identifier.
+    if (periph > ((1 << 5) - 1))
+    {
+        return ALT_E_BAD_ARG;
+    }
+
+    // Buffer of where to assemble the instruction.
+    uint8_t * buffer = pgm->program + pgm->buffer_start + pgm->code_size;
+
+    // Assemble DMASTP
+    buffer[0] = 0x29 | bs_mask;
+    buffer[1] = (uint8_t)(periph) << 3;
+
+    // Update the code size.
+    pgm->code_size += 2;
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_dma_program_DMASTZ(ALT_DMA_PROGRAM_t * pgm)
+{
+    // For information on DMASTZ, see PL330, section 4.3.18.
+
+    // Check for sufficient space in buffer
+    if ((pgm->code_size + 1) > ALT_DMA_PROGRAM_PROVISION_BUFFER_SIZE)
+    {
+        return ALT_E_BUF_OVF;
+    }
+
+    // Buffer of where to assemble the instruction.
+    uint8_t * buffer = pgm->program + pgm->buffer_start + pgm->code_size;
+
+    // Assemble DMASTZ
+    buffer[0] = 0x0c;
+
+    // Update the code size.
+    pgm->code_size += 1;
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_dma_program_DMAWFE(ALT_DMA_PROGRAM_t * pgm,
+                                       ALT_DMA_EVENT_t evt, bool invalid)
+{
+    // For information on DMAWFE, see PL330, section 4.3.19.
+
+    // Check for sufficient space in buffer
+    if ((pgm->code_size + 2) > ALT_DMA_PROGRAM_PROVISION_BUFFER_SIZE)
+    {
+        return ALT_E_BUF_OVF;
+    }
+
+    // Validate evt selection
+    switch (evt)
+    {
+    case ALT_DMA_EVENT_0:
+    case ALT_DMA_EVENT_1:
+    case ALT_DMA_EVENT_2:
+    case ALT_DMA_EVENT_3:
+    case ALT_DMA_EVENT_4:
+    case ALT_DMA_EVENT_5:
+    case ALT_DMA_EVENT_6:
+    case ALT_DMA_EVENT_7:
+    case ALT_DMA_EVENT_ABORT:
+        break;
+    default:
+        return ALT_E_BAD_ARG;
+    }
+
+    // Construct i mask value
+    uint8_t i_mask = 0;
+    if (invalid)
+    {
+        i_mask = 0x2;
+    }
+
+    // Buffer of where to assemble the instruction.
+    uint8_t * buffer = pgm->program + pgm->buffer_start + pgm->code_size;
+
+    // Assemble DMAWFE
+    buffer[0] = 0x36;
+    buffer[1] = ((uint8_t)(evt) << 3) | i_mask;
+
+    // Update the code size.
+    pgm->code_size += 2;
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_dma_program_DMAWFP(ALT_DMA_PROGRAM_t * pgm,
+                                       ALT_DMA_PERIPH_t periph, ALT_DMA_PROGRAM_INST_MOD_t mod)
+{
+    // For information on DMAWFP, see PL330, section 4.3.20.
+
+    // Check for sufficient space in buffer
+    if ((pgm->code_size + 2) > ALT_DMA_PROGRAM_PROVISION_BUFFER_SIZE)
+    {
+        return ALT_E_BUF_OVF;
+    }
+
+    // Verify valid peripheral identifier.
+    if (periph > ((1 << 5) - 1))
+    {
+        return ALT_E_BAD_ARG;
+    }
+
+    // Verify instruction modifier; construct bs, p mask value.
+    uint8_t bsp_mask = 0;
+    switch (mod)
+    {
+    case ALT_DMA_PROGRAM_INST_MOD_SINGLE:
+        bsp_mask = 0x0;
+        break;
+    case ALT_DMA_PROGRAM_INST_MOD_BURST:
+        bsp_mask = 0x2;
+        break;
+    case ALT_DMA_PROGRAM_INST_MOD_PERIPH:
+        bsp_mask = 0x1;
+        break;
+    default:
+        return ALT_E_BAD_ARG;
+    }
+
+    // Buffer of where to assemble the instruction.
+    uint8_t * buffer = pgm->program + pgm->buffer_start + pgm->code_size;
+
+    // Assemble DMAWFP
+    buffer[0] = 0x30 | bsp_mask;
+    buffer[1] = (uint8_t)(periph) << 3;
+
+    // Update the code size.
+    pgm->code_size += 2;
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_dma_program_DMAWMB(ALT_DMA_PROGRAM_t * pgm)
+{
+    // For information on DMAWMB, see PL330, section 4.3.21.
+
+    // Check for sufficient space in buffer
+    if ((pgm->code_size + 1) > ALT_DMA_PROGRAM_PROVISION_BUFFER_SIZE)
+    {
+        return ALT_E_BUF_OVF;
+    }
+
+    // Buffer of where to assemble the instruction.
+    uint8_t * buffer = pgm->program + pgm->buffer_start + pgm->code_size;
+
+    // Assemble DMAWMB
+    buffer[0] = 0x13;
+
+    // Update the code size.
+    pgm->code_size += 1;
+
+    return ALT_E_SUCCESS;
+}
diff --git a/c/src/lib/libbsp/arm/altera-cyclone-v/hwlib/src/hwmgr/alt_qspi.c b/c/src/lib/libbsp/arm/altera-cyclone-v/hwlib/src/hwmgr/alt_qspi.c
new file mode 100644
index 0000000..458ef71
--- /dev/null
+++ b/c/src/lib/libbsp/arm/altera-cyclone-v/hwlib/src/hwmgr/alt_qspi.c
@@ -0,0 +1,2619 @@
+/******************************************************************************
+*
+* alt_qspi.c - API for the Altera SoC FPGA QSPI device.
+*
+******************************************************************************/
+
+/******************************************************************************
+ *
+ * Copyright 2013 Altera Corporation. All Rights Reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ * 
+ ******************************************************************************/
+
+#include <string.h>
+#include <stdio.h>
+#include <inttypes.h>
+#include "hwlib.h"
+#include "alt_clock_manager.h"
+#include "alt_qspi.h"
+#include "alt_qspi_private.h"
+#include "socal/alt_qspi.h"
+#include "socal/alt_rstmgr.h"
+#include "socal/alt_sysmgr.h"
+#include "socal/hps.h"
+#include "socal/socal.h"
+
+/////
+
+// NOTE: To enable debugging output, delete the next line and uncomment the
+//   line after.
+#define dprintf(...)
+// #define dprintf printf
+
+/////
+
+#define MIN(a, b) ((a) > (b) ? (b) : (a))
+
+// qspi_clk operating frequency range.
+#define ALT_QSPI_CLK_FREQ_MIN ((alt_freq_t)0)
+#define ALT_QSPI_CLK_FREQ_MAX ((alt_freq_t)432000000)
+
+// The set of all valid QSPI controller interrupt status mask values.
+#define ALT_QSPI_INT_STATUS_ALL ( \
+        ALT_QSPI_INT_STATUS_MODE_FAIL         | \
+        ALT_QSPI_INT_STATUS_UFL               | \
+        ALT_QSPI_INT_STATUS_IDAC_OP_COMPLETE  | \
+        ALT_QSPI_INT_STATUS_IDAC_OP_REJECT    | \
+        ALT_QSPI_INT_STATUS_WR_PROT_VIOL      | \
+        ALT_QSPI_INT_STATUS_ILL_AHB_ACCESS    | \
+        ALT_QSPI_INT_STATUS_IDAC_WTRMK_TRIG   | \
+        ALT_QSPI_INT_STATUS_RX_OVF            | \
+        ALT_QSPI_INT_STATUS_TX_FIFO_NOT_FULL  | \
+        ALT_QSPI_INT_STATUS_TX_FIFO_FULL      | \
+        ALT_QSPI_INT_STATUS_RX_FIFO_NOT_EMPTY | \
+        ALT_QSPI_INT_STATUS_RX_FIFO_FULL      | \
+        ALT_QSPI_INT_STATUS_IDAC_RD_FULL        \
+        )
+
+static uint32_t qspi_device_size = 0;
+
+/////
+
+static ALT_STATUS_CODE alt_qspi_device_status(uint32_t * status)
+{
+    // Read flag status register through STIG
+    return alt_qspi_stig_rd_cmd(ALT_QSPI_STIG_OPCODE_RDSR, 0, 1, status, 10000);
+}
+
+#if ALT_QSPI_PROVISION_MICRON_N25Q_SUPPORT
+static ALT_STATUS_CODE alt_qspi_N25Q_device_flag(uint32_t * flagsr)
+{
+    if (qspi_device_size < 0x4000000)
+    {
+        return ALT_E_SUCCESS;
+    }
+
+    // Read flag status register through STIG
+    return alt_qspi_stig_rd_cmd(ALT_QSPI_STIG_OPCODE_RDFLGSR, 0, 1, flagsr, 10000);
+}
+
+// NOTE: This must be called after QSPI has been enabled. Communications with
+//   the device will not happen until QSPI is enabled.
+static inline ALT_STATUS_CODE alt_qspi_N25Q_enable(void)
+{
+    ALT_STATUS_CODE status = ALT_E_SUCCESS;
+
+    // Reset the volatile memory on the N25Q
+
+    if (status == ALT_E_SUCCESS)
+    {
+        status = alt_qspi_stig_cmd(ALT_QSPI_STIG_OPCODE_RESET_EN, 0, 10000);
+    }
+
+    if (status == ALT_E_SUCCESS)
+    {
+        status = alt_qspi_stig_cmd(ALT_QSPI_STIG_OPCODE_RESET_MEM, 0, 10000);
+    }
+
+    /////
+
+    if (status == ALT_E_SUCCESS)
+    {
+        ALT_QSPI_DEV_INST_CONFIG_t cfg =
+        {
+            .op_code        = ALT_QSPI_STIG_OPCODE_FASTREAD_QUAD_IO,
+            .inst_type      = ALT_QSPI_MODE_SINGLE, // RDID does not support QUAD.
+            .addr_xfer_type = ALT_QSPI_MODE_QUAD,
+            .data_xfer_type = ALT_QSPI_MODE_QUAD,
+            .dummy_cycles   = 10
+        };
+
+        status = alt_qspi_device_read_config_set(&cfg);
+    }
+
+/*
+    // CASE 157096: Investigate using QUAD for writes.
+    if (status == ALT_E_SUCCESS)
+    {
+        ALT_QSPI_DEV_INST_CONFIG_t cfg =
+        {
+            .op_code        = ALT_QSPI_STIG_OPCODE_PP,
+            .inst_type      = ALT_QSPI_MODE_SINGLE,
+            .addr_xfer_type = ALT_QSPI_MODE_QUAD,
+            .data_xfer_type = ALT_QSPI_MODE_QUAD,
+            .dummy_cycles   = 0
+        };
+
+        status = alt_qspi_device_write_config_set(&cfg);
+    }
+*/
+
+    return status;
+}
+
+static ALT_STATUS_CODE alt_qspi_N25Q_flag_wait_for_program(uint32_t timeout)
+{
+    // The flag status register is only available on the 512 Mib and 1 Gib
+    // (64 MiB and 128 MiB) Micron parts.
+    if (qspi_device_size < 0x4000000)
+    {
+        return ALT_E_SUCCESS;
+    }
+
+    ALT_STATUS_CODE status = ALT_E_SUCCESS;
+
+    uint32_t time_out = timeout;
+    uint32_t stat = 0;
+    bool infinite = (timeout == ALT_QSPI_TIMEOUT_INFINITE);
+
+    do
+    {
+        status = alt_qspi_device_status(&stat);
+        if (status != ALT_E_SUCCESS)
+        {
+            break;
+        }
+        if (!ALT_QSPI_STIG_SR_BUSY_GET(stat))
+        {
+            break;
+        }
+    }
+    while (time_out-- || infinite);
+
+    if (time_out == (uint32_t)-1 && !infinite)
+    {
+        status = ALT_E_TMO;
+    }
+
+    if (status == ALT_E_SUCCESS)
+    {
+        uint32_t flagsr = 0;
+
+        do
+        {
+            status = alt_qspi_N25Q_device_flag(&flagsr);
+            if (status != ALT_E_SUCCESS)
+            {
+                break;
+            }
+            if (ALT_QSPI_STIG_FLAGSR_PROGRAMREADY_GET(flagsr))
+            {
+                break;
+            }
+        }
+        while (timeout-- || infinite);
+
+        if (timeout == (uint32_t)-1 && !infinite)
+        {
+            status = ALT_E_TMO;
+        }
+
+        if (status == ALT_E_SUCCESS)
+        {
+            if (ALT_QSPI_STIG_FLAGSR_PROGRAMERROR_GET(flagsr))
+            {
+                status = ALT_E_ERROR;
+            }
+        }
+    }
+    return status;
+}
+
+static ALT_STATUS_CODE alt_qspi_N25Q_flag_wait_for_erase(uint32_t timeout)
+{
+    // The flag status register is only available on the 512 Mib and 1 Gib
+    // (64 MiB and 128 MiB) Micron parts.
+    if (qspi_device_size < 0x4000000)
+    {
+        return ALT_E_SUCCESS;
+    }
+
+    ALT_STATUS_CODE status = ALT_E_SUCCESS;
+
+    uint32_t time_out = timeout;
+    uint32_t stat = 0;
+    bool infinite = (timeout == ALT_QSPI_TIMEOUT_INFINITE);
+
+    do
+    {
+        status = alt_qspi_device_status(&stat);
+        if (status != ALT_E_SUCCESS)
+        {
+            break;
+        }
+        if (!ALT_QSPI_STIG_SR_BUSY_GET(stat))
+        {
+            break;
+        }
+    }
+    while (time_out-- || infinite);
+
+    if (time_out == (uint32_t)-1 && !infinite)
+    {
+        status = ALT_E_TMO;
+    }
+
+    if (status == ALT_E_SUCCESS)
+    {
+
+        uint32_t flagsr = 0;
+
+        do
+        {
+            status = alt_qspi_N25Q_device_flag(&flagsr);
+            if (status != ALT_E_SUCCESS)
+            {
+                break;
+            }
+            if (ALT_QSPI_STIG_FLAGSR_ERASEREADY_GET(flagsr))
+            {
+                break;
+            }
+        }
+        while (timeout-- || infinite);
+
+        if (timeout == (uint32_t)-1 && !infinite)
+        {
+            status = ALT_E_TMO;
+        }
+
+        if (status == ALT_E_SUCCESS)
+        {
+            if (ALT_QSPI_STIG_FLAGSR_ERASEERROR_GET(flagsr))
+            {
+                status = ALT_E_ERROR;
+            }
+        }
+    }
+ 
+    return status;
+}
+#endif
+
+//
+// A helper function which converts a ns interval into a delay interval for a given MHz.
+// The +999 is there to round up the result.
+//
+static inline int alt_qspi_ns_to_multiplier(int ns, int mhz)
+{
+    return ((ns * mhz) + 999) / 1000;
+}
+
+ALT_STATUS_CODE alt_qspi_init(void)
+{
+    ALT_STATUS_CODE status = ALT_E_SUCCESS;
+    alt_freq_t qspi_clk_freq = 0;
+
+    // Validate QSPI module input clocks.
+    //  - pclk    - l4_mp_clk
+    //  - hclk    - l4_mp_clk
+    //  - ref_clk - qspi_clk
+
+    // Check and validate the QSPI ref_clk which is connected to the HPS qspi_clk.
+    if (status == ALT_E_SUCCESS)
+    {
+        if (alt_clk_is_enabled(ALT_CLK_QSPI) != ALT_E_TRUE)
+        {
+            status = ALT_E_BAD_CLK;
+        }
+    }
+
+    if (status == ALT_E_SUCCESS)
+    {
+        status = alt_clk_freq_get(ALT_CLK_QSPI, &qspi_clk_freq);
+        if (status == ALT_E_SUCCESS)
+        {
+            if (qspi_clk_freq > ALT_QSPI_CLK_FREQ_MAX)
+            {
+                return ALT_E_BAD_CLK;
+            }
+        }
+    }
+
+    int qspi_clk_mhz = qspi_clk_freq / 1000000;
+
+    /////
+
+    // Take QSPI controller out of reset.
+    alt_clrbits_word(ALT_RSTMGR_PERMODRST_ADDR, ALT_RSTMGR_PERMODRST_QSPI_SET_MSK);
+
+    /////
+
+    // Configure the device timing
+
+    if (status == ALT_E_SUCCESS)
+    {
+        ALT_QSPI_TIMING_CONFIG_t timing_cfg =
+        {
+            .clk_phase  = (ALT_QSPI_CLK_PHASE_t)ALT_QSPI_CFG_SELCLKPHASE_RESET,
+            .clk_pol    = (ALT_QSPI_CLK_POLARITY_t)ALT_QSPI_CFG_SELCLKPOL_RESET,
+            .cs_da      = alt_qspi_ns_to_multiplier(ALT_QSPI_TSHSL_NS_DEF, qspi_clk_mhz),
+            .cs_dads    = alt_qspi_ns_to_multiplier(ALT_QSPI_TSD2D_NS_DEF, qspi_clk_mhz),
+            .cs_eot     = alt_qspi_ns_to_multiplier(ALT_QSPI_TCHSH_NS_DEF, qspi_clk_mhz),
+            .cs_sot     = alt_qspi_ns_to_multiplier(ALT_QSPI_TSLCH_NS_DEF, qspi_clk_mhz),
+            .rd_datacap = 1
+        };
+
+        dprintf("DEBUG[QSPI]: cs_da   = %" PRIu32 ".\n", timing_cfg.cs_da);
+        dprintf("DEBUG[QSPI]: cs_dads = %" PRIu32 ".\n", timing_cfg.cs_dads);
+        dprintf("DEBUG[QSPI]: cs_eot  = %" PRIu32 ".\n", timing_cfg.cs_eot);
+        dprintf("DEBUG[QSPI]: cs_sot  = %" PRIu32 ".\n", timing_cfg.cs_sot);
+
+        status = alt_qspi_timing_config_set(&timing_cfg);
+    }
+
+    /////
+
+    // Configure the remap address register, no remap
+
+    if (status == ALT_E_SUCCESS)
+    {
+        status = alt_qspi_ahb_remap_address_set(0);
+    }
+
+    // Configure the interrupt mask register, disabled all first
+
+    if (status == ALT_E_SUCCESS)
+    {
+        status = alt_qspi_int_disable(ALT_QSPI_INT_STATUS_ALL);
+    }
+
+    // Configure the baud rate divisor
+    // CASE 157095: Investigate using 108 MHz, and tweaking the rd_datacap param.
+
+    if (status == ALT_E_SUCCESS)
+    {
+        uint32_t device_sclk_mhz = 54;
+        uint32_t div_actual = (qspi_clk_mhz + (device_sclk_mhz - 1)) / device_sclk_mhz;
+        dprintf("DEBUG[QSPI]: div_actual = %" PRIu32 ".\n", div_actual);
+
+        ALT_QSPI_BAUD_DIV_t div_bits = (ALT_QSPI_BAUD_DIV_t)(((div_actual + 1) / 2) - 1);
+        status = alt_qspi_baud_rate_div_set(div_bits);
+    }
+
+    return status;
+}
+
+ALT_STATUS_CODE alt_qspi_uninit(void)
+{
+    // Put QSPI controller into reset.
+    alt_setbits_word(ALT_RSTMGR_PERMODRST_ADDR, ALT_RSTMGR_PERMODRST_QSPI_SET_MSK);
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_qspi_disable(void)
+{
+    alt_clrbits_word(ALT_QSPI_CFG_ADDR, ALT_QSPI_CFG_EN_SET_MSK);
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_qspi_enable(void)
+{
+    alt_setbits_word(ALT_QSPI_CFG_ADDR, ALT_QSPI_CFG_EN_SET_MSK);
+
+    ALT_STATUS_CODE status = ALT_E_SUCCESS;
+
+    /////
+
+    // Device specific configuration
+
+#if ALT_QSPI_PROVISION_MICRON_N25Q_SUPPORT
+    if (status == ALT_E_SUCCESS)
+    {
+        status = alt_qspi_N25Q_enable();
+    }
+#endif
+
+    uint32_t rdid = 0;
+
+    // Query device capabilities
+    // This requires QSPI to be enabled.
+
+    if (status == ALT_E_SUCCESS)
+    {
+        status = alt_qspi_device_rdid(&rdid);
+    }
+
+    if (status == ALT_E_SUCCESS)
+    {
+        // NOTE: The size code seems to be a form of BCD (binary coded decimal).
+        //   The first nibble is the 10's digit and the second nibble is the 1's
+        //   digit in the number of bytes.
+
+        // Capacity ID samples:
+        //  0x15 :   16 Mb =>   2 MiB => 1 << 21 ; BCD=15
+        //  0x16 :   32 Mb =>   4 MiB => 1 << 22 ; BCD=16
+        //  0x17 :   64 Mb =>   8 MiB => 1 << 23 ; BCD=17
+        //  0x18 :  128 Mb =>  16 MiB => 1 << 24 ; BCD=18
+        //  0x19 :  256 Mb =>  32 MiB => 1 << 25 ; BCD=19
+        //  0x1a
+        //  0x1b
+        //  0x1c
+        //  0x1d
+        //  0x1e
+        //  0x1f
+        //  0x20 :  512 Mb =>  64 MiB => 1 << 26 ; BCD=20
+        //  0x21 : 1024 Mb => 128 MiB => 1 << 27 ; BCD=21
+
+        int cap_code = ALT_QSPI_STIG_RDID_CAPACITYID_GET(rdid);
+
+        if ( ((cap_code >> 4) > 0x9) || ((cap_code & 0xf) > 0x9))
+        {
+            // If a non-valid BCD value is detected at the top or bottom nibble, chances
+            // are that the chip has a problem.
+
+            dprintf("DEBUG[QSPI]: Invalid CapacityID encountered: 0x%02x.\n", cap_code);
+            status = ALT_E_ERROR;
+        }
+        else
+        {
+            int cap_decoded = ((cap_code >> 4) * 10) + (cap_code & 0xf);
+
+            qspi_device_size = 1 << (cap_decoded + 6);
+
+            dprintf("DEBUG[QSPI]: Device size = 0x%" PRIx32 ".\n", qspi_device_size);
+        }
+    }
+
+    // Configure the device size and address bytes
+
+    if (status == ALT_E_SUCCESS)
+    {
+        ALT_QSPI_DEV_SIZE_CONFIG_t size_cfg =
+        {
+            .block_size         = ALT_QSPI_DEVSZ_BYTESPERSUBSECTOR_RESET,  // 0x10  => 2^16 = 64 KiB
+            .page_size          = ALT_QSPI_DEVSZ_BYTESPERDEVICEPAGE_RESET, // 0x100 => 256 B
+            .addr_size          = ALT_QSPI_DEVSZ_NUMADDRBYTES_RESET,       // 0x2   => 3 bytes or 0x00ffffff mask.
+            .lower_wrprot_block = 0,
+            .upper_wrprot_block = (qspi_device_size - 1) >> 16,
+            .wrprot_enable      = ALT_QSPI_WRPROT_EN_RESET
+        };
+
+        status = alt_qspi_device_size_config_set(&size_cfg);
+    }
+
+    /////
+
+    // Configure the DMA parameters
+
+    // This will allow DMA to work well without much intervention by users.
+
+    if (status == ALT_E_SUCCESS)
+    {
+        status = alt_qspi_dma_config_set(4, 32);
+    }
+
+    /////
+
+    return status;
+}
+
+/////
+
+uint32_t alt_qspi_int_status_get(void)
+{
+    // Read and return the value of the QSPI controller Interrupt Status
+    // Register (irqstat).
+    return alt_read_word(ALT_QSPI_IRQSTAT_ADDR);
+}
+
+ALT_STATUS_CODE alt_qspi_int_clear(const uint32_t mask)
+{
+    // Check that the [mask] contains valid interrupt status conditions values.
+    if ((ALT_QSPI_INT_STATUS_ALL & mask) == 0)
+    {
+        return ALT_E_BAD_ARG;
+    }
+
+    // Write 1's to clear the desired interrupt status condition(s).
+    alt_write_word(ALT_QSPI_IRQSTAT_ADDR, mask);
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_qspi_int_disable(const uint32_t mask)
+{
+    if (alt_qspi_is_idle() == false)
+    {
+        return ALT_E_ERROR;
+    }
+
+    // Check that the [mask] contains valid interrupt status conditions values.
+    if ((ALT_QSPI_INT_STATUS_ALL & mask) == 0)
+    {
+        return ALT_E_BAD_ARG;
+    }
+
+    // Write 0's to disable the desired interrupt status condition(s).
+    alt_clrbits_word(ALT_QSPI_IRQMSK_ADDR, mask);
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_qspi_int_enable(const uint32_t mask)
+{
+    if (alt_qspi_is_idle() == false)
+    {
+        return ALT_E_ERROR;
+    }
+
+    // Check that the [mask] contains valid interrupt status conditions values.
+    if ((ALT_QSPI_INT_STATUS_ALL & mask) == 0)
+    {
+        return ALT_E_BAD_ARG;
+    }
+
+    // Write 1's to enable the desired interrupt status condition(s).
+    alt_setbits_word(ALT_QSPI_IRQMSK_ADDR, mask);
+
+    return ALT_E_SUCCESS;
+}
+
+/////
+
+bool alt_qspi_is_idle(void)
+{
+    // If the idle field of the QSPI configuration register is 1 then the serial
+    // interface and QSPI pipeline is idle.
+    return ALT_QSPI_CFG_IDLE_GET(alt_read_word(ALT_QSPI_CFG_ADDR)) == 1;
+}
+
+/////
+
+static ALT_STATUS_CODE alt_qspi_indirect_write_start_bank(uint32_t dst, size_t length);
+
+static ALT_STATUS_CODE alt_qspi_indirect_page_bound_write_helper(uint32_t dst, const char * src, size_t length)
+{
+    ALT_STATUS_CODE status = ALT_E_SUCCESS;
+
+    if (status == ALT_E_SUCCESS)
+    {
+        status = alt_qspi_indirect_write_start_bank(dst, length);
+    }
+
+    if (status == ALT_E_SUCCESS)
+    {
+        uint32_t write_count = 0;
+        uint32_t write_capacity = ALT_QSPI_SRAM_FIFO_ENTRY_COUNT - alt_qspi_sram_partition_get();
+
+        while (write_count < length)
+        {
+            uint32_t space = write_capacity - alt_qspi_indirect_write_fill_level();
+            space = MIN(space, (length - write_count)/ sizeof(uint32_t));
+
+            const uint32_t * data = (const uint32_t *)(src + write_count);
+            for (uint32_t i = 0; i < space; ++i)
+            {
+                alt_write_word(ALT_QSPIDATA_ADDR, *data++);
+            }
+
+            write_count += space * sizeof(uint32_t);
+        }
+    }
+
+    if (status == ALT_E_SUCCESS)
+    {
+        status = alt_qspi_indirect_write_finish();
+    }
+
+    return status;
+}
+
+static ALT_STATUS_CODE alt_qspi_indirect_subsector_aligned_write_helper(const char * data, uint32_t subsec_addr)
+{
+    ALT_STATUS_CODE status = ALT_E_SUCCESS;
+
+    for (int i = 0; i < ALT_QSPI_SUBSECTOR_SIZE / ALT_QSPI_PAGE_SIZE; i++)
+    {
+        int offset = i * ALT_QSPI_PAGE_SIZE;
+
+        status = alt_qspi_indirect_page_bound_write_helper(subsec_addr + offset, data + offset, ALT_QSPI_PAGE_SIZE);
+        if (status != ALT_E_SUCCESS)
+        {
+            break;
+        }
+    }
+
+    return status;
+}
+
+static ALT_STATUS_CODE alt_qspi_indirect_read_start_bank(uint32_t src, size_t size);
+
+//
+// This helper function reads a segment of data, which is limited to 1 bank
+// (24 bits of addressing).
+//
+static ALT_STATUS_CODE alt_qspi_read_bank(char * dst, uint32_t src, size_t size)
+{
+    ALT_STATUS_CODE status = ALT_E_SUCCESS;
+
+    if (status == ALT_E_SUCCESS)
+    {
+        status = alt_qspi_indirect_read_start_bank(src, size);
+    }
+
+    if (status == ALT_E_SUCCESS)
+    {
+        uint32_t read_count = 0;
+
+        while (!alt_qspi_indirect_read_is_complete())
+        {
+            uint32_t level = alt_qspi_indirect_read_fill_level();
+//            level = MIN(level, (size - read_count) / sizeof(uint32_t));
+
+            uint32_t * data = (uint32_t *)(dst + read_count);
+            for (uint32_t i = 0; i < level; ++i)
+            {
+                *data++ = alt_read_word(ALT_QSPIDATA_ADDR);
+            }
+
+            read_count += level * sizeof(uint32_t);
+        }
+    }
+
+    if (status == ALT_E_SUCCESS)
+    {
+        status = alt_qspi_indirect_read_finish();
+    }
+
+    return status;
+}
+
+ALT_STATUS_CODE alt_qspi_read(void * dst, uint32_t src, size_t size)
+{
+    if (src >= qspi_device_size)
+    {
+        return ALT_E_ERROR;
+    }
+
+    if (src + size - 1 >= qspi_device_size)
+    {
+        return ALT_E_ERROR;
+    }
+
+    if (size == 0)
+    {
+        return ALT_E_SUCCESS;
+    }
+
+    if ((uintptr_t)dst & 0x3)
+    {
+        return ALT_E_ERROR;
+    }
+
+    if (src & 0x3)
+    {
+        return ALT_E_ERROR;
+    }
+
+    if (size & 0x3)
+    {
+        return ALT_E_ERROR;
+    }
+
+    /////
+
+    // Verify that there is not already a read in progress.
+    if (ALT_QSPI_INDRD_RD_STAT_GET(alt_read_word(ALT_QSPI_INDRD_ADDR)))
+    {
+        return ALT_E_ERROR;
+    }
+
+    /////
+
+    ALT_STATUS_CODE status = ALT_E_SUCCESS;
+
+    //
+    // bank_count : The number of bank(s) affected, including partial banks.
+    // bank_addr  : The aligned address of the first affected bank, including partial bank(s).
+    // bank_ofst  : The offset of the bank to read. Only used when reading the first bank.
+    //
+    uint32_t bank_count = ((src + size - 1) >> 24) - (src >> 24) + 1;
+    uint32_t bank_addr  = src & ALT_QSPI_BANK_ADDR_MSK;
+    uint32_t bank_ofst  = src & (ALT_QSPI_BANK_SIZE - 1);
+
+    char * data = (char *)dst;
+
+    uint32_t copy_length = MIN(size, ALT_QSPI_BANK_SIZE - bank_ofst);
+
+    dprintf("DEBUG[QSPI]: read(): bulk: mem_addr = %p; flash_addr = 0x%" PRIx32 ".\n", data, src);
+    dprintf("DEBUG[QSPI]: read(): bulk: bank_count = 0x%" PRIx32 ", bank_ofst = 0x%" PRIx32 ".\n", bank_count, bank_ofst);
+
+    for (uint32_t i = 0; i < bank_count; ++i)
+    {
+        dprintf("DEBUG[QSPI]: read(): bank 0x%" PRIx32 "; copy_length = 0x%" PRIx32 ".\n", bank_addr >> 24, copy_length);
+
+        status = alt_qspi_device_bank_select(bank_addr >> 24);
+        if (status != ALT_E_SUCCESS)
+        {
+            break;
+        }
+
+        status = alt_qspi_read_bank(dst, bank_ofst, copy_length);
+        if (status != ALT_E_SUCCESS)
+        {
+            break;
+        }
+
+        bank_addr += ALT_QSPI_BANK_SIZE;
+        data += copy_length;
+        size -= copy_length;
+
+        copy_length = MIN(size, ALT_QSPI_BANK_SIZE);
+    }
+
+    return status;
+}
+
+static ALT_STATUS_CODE alt_qspi_write_bank(uint32_t dst, const char * src, size_t size)
+{
+    ALT_STATUS_CODE status = ALT_E_SUCCESS;
+
+    /////
+
+    uint32_t page_ofst  = dst & (ALT_QSPI_PAGE_SIZE - 1);
+    uint32_t write_size = MIN(size, ALT_QSPI_PAGE_SIZE - page_ofst);
+
+    while (size)
+    {
+        dprintf("DEBUG[QSPI]: write(): flash dst = 0x%" PRIx32 ", mem src = %p, write size = 0x%" PRIx32 ", size left = 0x%x.\n", dst, src, write_size, size);
+
+        status = alt_qspi_indirect_page_bound_write_helper(dst, src, write_size);
+        if (status != ALT_E_SUCCESS)
+        {
+            break;
+        }
+
+        dst  += write_size;
+        src  += write_size;
+        size -= write_size;
+
+        write_size = MIN(size, ALT_QSPI_PAGE_SIZE);
+    }
+
+    return status;
+}
+
+ALT_STATUS_CODE alt_qspi_write(uint32_t dst, const void * src, size_t size)
+{
+    if (dst >= qspi_device_size)
+    {
+        return ALT_E_ERROR;
+    }
+
+    if (dst + size - 1 >= qspi_device_size)
+    {
+        return ALT_E_ERROR;
+    }
+
+    if (size == 0)
+    {
+        return ALT_E_SUCCESS;
+    }
+
+    if ((uintptr_t)src & 0x3)
+    {
+        return ALT_E_ERROR;
+    }
+
+    if (dst & 0x3)
+    {
+        return ALT_E_ERROR;
+    }
+
+    if (size & 0x3)
+    {
+        return ALT_E_ERROR;
+    }
+
+    /////
+
+    // Verify that there is not already a write in progress.
+    if (ALT_QSPI_INDWR_RDSTAT_GET(alt_read_word(ALT_QSPI_INDWR_ADDR)))
+    {
+        return ALT_E_ERROR;
+    }
+
+    /////
+
+    ALT_STATUS_CODE status = ALT_E_SUCCESS;
+
+    uint32_t bank_count = ((dst + size - 1) >> 24) - (dst >> 24) + 1;
+    uint32_t bank_addr  = dst & ALT_QSPI_BANK_ADDR_MSK;
+    uint32_t bank_ofst  = dst & (ALT_QSPI_BANK_SIZE - 1);
+
+    const char * data  = src;
+
+    uint32_t copy_length = MIN(size, ALT_QSPI_BANK_SIZE - bank_ofst);
+
+    dprintf("DEBUG[QSPI]: write(): bulk: flash_addr = 0x%" PRIx32 "; mem_addr = %p.\n", dst, data);
+    dprintf("DEBUG[QSPI]: write(): bulk: bank_count = 0x%" PRIx32 ", bank_ofst = 0x%" PRIx32 ".\n", bank_count, bank_ofst);
+
+    for (uint32_t i = 0; i < bank_count; ++i)
+    {
+        dprintf("DEBUG[QSPI]: write(): bank 0x%" PRIx32 "; copy_length = 0x%" PRIx32 ".\n", bank_addr >> 24, copy_length);
+
+        status = alt_qspi_device_bank_select(bank_addr >> 24);
+        if (status != ALT_E_SUCCESS)
+        {
+            break;
+        }
+
+        status = alt_qspi_write_bank(bank_ofst, data, copy_length);
+        if (status != ALT_E_SUCCESS)
+        {
+            break;
+        }
+
+        bank_addr += ALT_QSPI_BANK_SIZE;
+        data += copy_length;
+        size -= copy_length;
+
+        copy_length = MIN(size, ALT_QSPI_BANK_SIZE);
+    }
+
+    return status;
+}
+
+static ALT_STATUS_CODE alt_qspi_erase_subsector_bank(uint32_t addr);
+
+static ALT_STATUS_CODE alt_qspi_replace_bank(uint32_t dst, const char * src, size_t size)
+{
+    ALT_STATUS_CODE status = ALT_E_SUCCESS;
+
+    //
+    // subsec_count        : The total number of affected subsector(s),
+    //                       including partial subsector(s).
+    // subsec_addr         : The aligned address of the next affected subsector,
+    //                       including partial subsector(s).
+    // subsec_partial_head : The number of subsector unaligned data to be
+    //                       written out at the start of the flash write
+    //                       request. This data ends at the end of the subsector
+    //                       or earlier depending on the number of data to be
+    //                       written.
+    // subsec_partial_tail : The number of subsector unaligned data to be
+    //                       written out at the end of the flash write request.
+    //                       This data starts at the start of the subsector. If
+    //                       only a single subsector is written (partial or
+    //                       full), this value will be zero.
+    //
+
+    uint32_t subsec_count = ((dst + size - 1) >> 12) - (dst >> 12) + 1;
+    uint32_t subsec_addr  = dst & ALT_QSPI_SUBSECTOR_ADDR_MSK;
+
+    uint32_t subsec_partial_head = MIN(ALT_QSPI_SUBSECTOR_SIZE - (dst & (ALT_QSPI_SUBSECTOR_SIZE - 1)), size) & (ALT_QSPI_SUBSECTOR_SIZE - 1);
+    uint32_t subsec_partial_tail = (size - subsec_partial_head) & (ALT_QSPI_SUBSECTOR_SIZE - 1);
+
+    dprintf("DEBUG[QSPI]: replace(): report: dst = 0x%" PRIx32 "; size = 0x%x.\n",
+            dst, size);
+    dprintf("DEBUG[QSPI]: replace(): report: subsec_count = 0x%" PRIx32 "; subsec_addr = 0x%" PRIx32 ".\n",
+            subsec_count, subsec_addr);
+    dprintf("DEBUG[QSPI]: replace(): report: partial_head = 0x%" PRIx32 "; partial_tail = 0x%" PRIx32 ".\n",
+            subsec_partial_head, subsec_partial_tail);
+
+    // Write the first subsector, partial case.
+
+    if (subsec_partial_head)
+    {
+        // The write request is not aligned to a subsector so we must do the
+        // Read-Modify-Write cycle to preserve the existing data at the head of
+        // the subsector not affected by the write.
+
+        char subsec_buf[ALT_QSPI_SUBSECTOR_SIZE];
+
+        uint32_t subsec_ofst = dst & ~ALT_QSPI_SUBSECTOR_ADDR_MSK;
+
+        // - Read the subsector into buffer
+        // - Erase that subsector
+        // - Copy in the user data into buffer
+        // - Write out buffer to subsector
+
+        if (status == ALT_E_SUCCESS)
+        {
+            status = alt_qspi_read_bank(subsec_buf, subsec_addr, subsec_ofst);
+        }
+        if (status == ALT_E_SUCCESS)
+        {
+            status = alt_qspi_erase_subsector_bank(subsec_addr);
+        }
+        if (status == ALT_E_SUCCESS)
+        {
+            memcpy(subsec_buf + subsec_ofst, src, subsec_partial_head);
+            status = alt_qspi_indirect_subsector_aligned_write_helper(subsec_buf, subsec_addr);
+        }
+
+        // Do some bookkeeping on the user buffer information
+        src  += subsec_partial_head;
+        size -= subsec_partial_head;
+
+        // Do some bookkeeping on the subsector tracking
+        subsec_count--;
+        subsec_addr += ALT_QSPI_SUBSECTOR_SIZE;
+
+        dprintf("DEBUG[QSPI]: replace(): partial head: subsec_ofst = 0x%" PRIx32 "; size left = 0x%x; status = %" PRIi32 ".\n",
+                subsec_ofst, size, status);
+    }
+
+    // If there is a partial tail, then take 1 off the subsec_count. This way
+    // the following loop will write out all the complete subsectors. The tail
+    // will be written out afterwards.
+    
+    if (subsec_partial_tail)
+    {
+        subsec_count--;
+    }
+
+    // Write the aligned subsectors following any partial subsectors.
+
+    for (uint32_t i = 0; i < subsec_count; ++i)
+    {
+        // - Erase subsector
+        // - Write out buffer to subsector
+
+        if (status == ALT_E_SUCCESS)
+        {
+            status = alt_qspi_erase_subsector_bank(subsec_addr);
+        }
+        if (status == ALT_E_SUCCESS)
+        {
+            status = alt_qspi_indirect_subsector_aligned_write_helper(src, subsec_addr);
+        }
+
+        src  += ALT_QSPI_SUBSECTOR_SIZE;
+        size -= ALT_QSPI_SUBSECTOR_SIZE;
+
+        // Don't modify subsec_count as it's being used by the loop.
+        subsec_addr += ALT_QSPI_SUBSECTOR_SIZE;
+
+        dprintf("DEBUG[QSPI]: replace(): subsec aligned: size left = 0x%x, status = %" PRIi32 ".\n",
+                size, status);
+    }
+
+    // Write the last subsector, partial case.
+
+    if (subsec_partial_tail)
+    {
+        // The write request is not aligned to a subsector so we must do the
+        // Read-Modify-Write cycle to preserve the existing data at the end of
+        // the subsector not affected by the write.
+
+        char subsec_buf[ALT_QSPI_SUBSECTOR_SIZE];
+
+        // - Read the subsector into buffer
+        // - Erase that subsector
+        // - Copy in the user data into buffer
+        // - Write out buffer to subsector
+
+        if (status == ALT_E_SUCCESS)
+        {
+            status = alt_qspi_read_bank(subsec_buf  + subsec_partial_tail,
+                                        subsec_addr + subsec_partial_tail,
+                                        ALT_QSPI_SUBSECTOR_SIZE - subsec_partial_tail);
+        }
+        if (status == ALT_E_SUCCESS)
+        {
+            status = alt_qspi_erase_subsector_bank(subsec_addr);
+        }
+        if (status == ALT_E_SUCCESS)
+        {
+            memcpy(subsec_buf, src, subsec_partial_tail);
+            status = alt_qspi_indirect_subsector_aligned_write_helper(subsec_buf, subsec_addr);
+        }
+
+        src  += subsec_partial_tail;
+        size -= subsec_partial_tail;
+
+        dprintf("DEBUG[QSPI]: replace(): partial tail: size left = 0x%x, status = %" PRIi32 ".\n",
+                size, status);
+    }
+
+    return status;
+}
+
+ALT_STATUS_CODE alt_qspi_replace(uint32_t dst, const void * src, size_t size)
+{
+    if (dst >= qspi_device_size)
+    {
+        return ALT_E_ERROR;
+    }
+
+    if (dst + size - 1 >= qspi_device_size)
+    {
+        return ALT_E_ERROR;
+    }
+
+    if (size == 0)
+    {
+        return ALT_E_SUCCESS;
+    }
+
+    if ((uintptr_t)src & 0x3)
+    {
+        return ALT_E_ERROR;
+    }
+
+    if (dst & 0x3)
+    {
+        return ALT_E_ERROR;
+    }
+
+    if (size & 0x3)
+    {
+        return ALT_E_ERROR;
+    }
+
+    /////
+
+    // Verify that there is not already a read in progress.
+    if (ALT_QSPI_INDRD_RD_STAT_GET(alt_read_word(ALT_QSPI_INDRD_ADDR)))
+    {
+        return ALT_E_ERROR;
+    }
+
+    // Verify that there is not already a write in progress.
+    if (ALT_QSPI_INDWR_RDSTAT_GET(alt_read_word(ALT_QSPI_INDWR_ADDR)))
+    {
+        return ALT_E_ERROR;
+    }
+
+    /////
+
+    ALT_STATUS_CODE status = ALT_E_SUCCESS;
+
+    uint32_t bank_count = ((dst + size - 1) >> 24) - (dst >> 24) + 1;
+    uint32_t bank_addr  = dst & ALT_QSPI_BANK_ADDR_MSK;
+    uint32_t bank_ofst  = dst & (ALT_QSPI_BANK_SIZE - 1);
+
+    const char * data = (const char *)src;
+
+    uint32_t copy_length = MIN(size, ALT_QSPI_BANK_SIZE - bank_ofst);
+
+    dprintf("DEBUG[QSPI]: replace(): bulk: flash_addr = 0x%" PRIx32 "; mem_addr = %p.\n", dst, data);
+    dprintf("DEBUG[QSPI]: replace(): bulk: bank_count = 0x%" PRIx32 ", bank_ofst = 0x%" PRIx32 ".\n", bank_count, bank_ofst);
+
+    for (uint32_t i = 0; i < bank_count; ++i)
+    {
+        dprintf("DEBUG[QSPI]: replace(): bank 0x%" PRIx32 "; copy_length = 0x%" PRIx32 ".\n", bank_addr >> 24, copy_length);
+
+        status = alt_qspi_device_bank_select(bank_addr >> 24);
+        if (status != ALT_E_SUCCESS)
+        {
+            break;
+        }
+
+        status = alt_qspi_replace_bank(bank_ofst, data, copy_length);
+        if (status != ALT_E_SUCCESS)
+        {
+            break;
+        }
+
+        bank_addr += ALT_QSPI_BANK_SIZE;
+        data += copy_length;
+        size -= copy_length;
+
+        copy_length = MIN(size, ALT_QSPI_BANK_SIZE);
+    }
+
+    return status;
+}
+
+/////
+
+ALT_QSPI_BAUD_DIV_t alt_qspi_baud_rate_div_get(void)
+{
+    uint32_t baud_rate_div = ALT_QSPI_CFG_BAUDDIV_GET(alt_read_word(ALT_QSPI_CFG_ADDR));
+    return (ALT_QSPI_BAUD_DIV_t) baud_rate_div;
+}
+
+ALT_STATUS_CODE alt_qspi_baud_rate_div_set(const ALT_QSPI_BAUD_DIV_t baud_rate_div)
+{
+    if (0xf < (uint32_t)baud_rate_div)
+    {
+        // Invalid baud rate divisor value.
+        return ALT_E_BAD_ARG;
+    }
+
+    // Set the Master Mode Baud Rate Divisor Field of the QSPI Configuration Register.
+    alt_replbits_word(ALT_QSPI_CFG_ADDR,
+                      ALT_QSPI_CFG_BAUDDIV_SET_MSK,
+                      ALT_QSPI_CFG_BAUDDIV_SET(baud_rate_div));
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_qspi_chip_select_config_get(uint32_t* cs,
+                                                ALT_QSPI_CS_MODE_t* cs_mode)
+{
+    uint32_t cfg = alt_read_word(ALT_QSPI_CFG_ADDR);
+
+    *cs      = ALT_QSPI_CFG_PERCSLINES_GET(cfg);
+    *cs_mode = (ALT_QSPI_CS_MODE_t) ALT_QSPI_CFG_PERSELDEC_GET(cfg);
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_qspi_chip_select_config_set(const uint32_t cs,
+                                                const ALT_QSPI_CS_MODE_t cs_mode)
+{
+    // chip select cs:
+    // four bit value, bit 0 = cs0, bit 1 = cs1, bit 2 = cs2, bit 3 = cs3
+    // since cs is low true, the value of each bit should be zero if enable the cs.
+    // 
+    // also allows multiple cs line enabled together.
+ 
+    if (cs > ((1 << ALT_QSPI_CFG_PERCSLINES_WIDTH) - 1))
+    {
+        // [cs] not within possible 4 bit chip select line value range.
+        return ALT_E_ARG_RANGE;
+    }
+
+    if ((cs_mode != ALT_QSPI_CS_MODE_SINGLE_SELECT) && (cs_mode != ALT_QSPI_CS_MODE_DECODE))
+    {
+        return ALT_E_INV_OPTION;
+    }
+
+    // Update the Peripheral Chip Select Lines and Peripheral Select Decode
+    // Fields of the QSPI Configuration Register value with the chip select
+    // options.
+    uint32_t cfg = alt_read_word(ALT_QSPI_CFG_ADDR);
+    cfg &= ALT_QSPI_CFG_PERCSLINES_CLR_MSK & ALT_QSPI_CFG_PERSELDEC_CLR_MSK;
+    cfg |= ALT_QSPI_CFG_PERCSLINES_SET(cs) | ALT_QSPI_CFG_PERSELDEC_SET(cs_mode);
+    alt_write_word(ALT_QSPI_CFG_ADDR, cfg);
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_qspi_mode_bit_disable(void)
+{
+    // Clear the Mode Bit Enable Field of the Device Read Instruction Register
+    // to disable mode bits from being sent after the address bytes.
+    alt_clrbits_word(ALT_QSPI_DEVRD_ADDR, ALT_QSPI_DEVRD_ENMODBITS_SET_MSK);
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_qspi_mode_bit_enable(void)
+{
+    // Set the Mode Bit Enable Field of the Device Read Instruction Register
+    // to enable mode bits to be sent after the address bytes.
+    alt_setbits_word(ALT_QSPI_DEVRD_ADDR, ALT_QSPI_DEVRD_ENMODBITS_SET_MSK);
+
+    return ALT_E_SUCCESS;
+}
+
+uint32_t alt_qspi_mode_bit_config_get(void)
+{
+    // Return the 8 bit value from the Mode Field of the Mode Bit Configuration
+    // Register.
+    return ALT_QSPI_MODBIT_MOD_GET(alt_read_word(ALT_QSPI_MODBIT_ADDR));
+}
+
+ALT_STATUS_CODE alt_qspi_mode_bit_config_set(const uint32_t mode_bits)
+{
+    if (alt_qspi_is_idle() == false)
+    {
+        return ALT_E_ERROR;
+    }
+
+    if (mode_bits > ((1 << ALT_QSPI_MODBIT_MOD_WIDTH) - 1))
+    {
+        // 'mode_bits' not within possible 8 bit mode value range.
+        return ALT_E_ARG_RANGE;
+    }
+
+    // Set the 8 bit value in the Mode Field of the Mode Bit Configuration
+    // Register.
+    alt_replbits_word(ALT_QSPI_MODBIT_ADDR,
+                      ALT_QSPI_MODBIT_MOD_SET_MSK,
+                      ALT_QSPI_MODBIT_MOD_SET(mode_bits));
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_qspi_device_size_config_get(ALT_QSPI_DEV_SIZE_CONFIG_t * cfg)
+{
+    // Although not required, it is recommended that the write protect feature
+    // be enabled prior to enabling the QSPI controller. This will block any AHB
+    // writes from taking effect. This also means the write protection registers
+    // (Lower Write Protection, Upper Write Protection, and Write Protection)
+    // should be setup and the number of bytes per device block in the device
+    // size configuration register should be setup prior to enabling the QSPI
+    // controller.
+
+    // Read Device Size Register and get the Number of Bytes per Block, Number
+    // of Bytes per Device, and Number of Address Bytes Fields.
+
+    uint32_t devsz = alt_read_word(ALT_QSPI_DEVSZ_ADDR);
+
+    cfg->block_size = ALT_QSPI_DEVSZ_BYTESPERSUBSECTOR_GET(devsz);
+    cfg->page_size  = ALT_QSPI_DEVSZ_BYTESPERDEVICEPAGE_GET(devsz);
+    cfg->addr_size  = ALT_QSPI_DEVSZ_NUMADDRBYTES_GET(devsz);
+
+    // Read Lower Write Protection, Upper Write Protection, and Write Protection
+    // Registers.
+
+    cfg->lower_wrprot_block = ALT_QSPI_LOWWRPROT_SUBSECTOR_GET(alt_read_word(ALT_QSPI_LOWWRPROT_ADDR));
+    cfg->upper_wrprot_block = ALT_QSPI_UPPWRPROT_SUBSECTOR_GET(alt_read_word(ALT_QSPI_UPPWRPROT_ADDR));
+    cfg->wrprot_enable      = ALT_QSPI_WRPROT_EN_GET(alt_read_word(ALT_QSPI_WRPROT_ADDR));
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_qspi_device_size_config_set(const ALT_QSPI_DEV_SIZE_CONFIG_t * cfg)
+{
+    if (cfg->block_size > ((1 << ALT_QSPI_DEVSZ_BYTESPERSUBSECTOR_WIDTH) - 1))
+    {
+        return ALT_E_ARG_RANGE;
+    }
+
+    if (cfg->page_size > ((1 << ALT_QSPI_DEVSZ_BYTESPERDEVICEPAGE_WIDTH) - 1))
+    {
+        return ALT_E_ARG_RANGE;
+    }
+
+    if (cfg->addr_size > ((1 << ALT_QSPI_DEVSZ_NUMADDRBYTES_WIDTH) - 1))
+    {
+        return ALT_E_ARG_RANGE;
+    }
+
+    if (cfg->lower_wrprot_block > cfg->upper_wrprot_block)
+    {
+        // Null write protection regions are not allowed.
+        return ALT_E_ARG_RANGE;
+    }
+
+    /////
+
+    uint32_t value = ALT_QSPI_DEVSZ_BYTESPERSUBSECTOR_SET(cfg->block_size) |
+                     ALT_QSPI_DEVSZ_BYTESPERDEVICEPAGE_SET(cfg->page_size) |
+                     ALT_QSPI_DEVSZ_NUMADDRBYTES_SET(cfg->addr_size);
+
+    alt_write_word(ALT_QSPI_DEVSZ_ADDR, value);
+
+    if (cfg->wrprot_enable)
+    {
+        alt_write_word(ALT_QSPI_LOWWRPROT_ADDR, cfg->lower_wrprot_block);
+        alt_write_word(ALT_QSPI_UPPWRPROT_ADDR, cfg->upper_wrprot_block);
+    }
+
+    // Read Upper Write Protection Register - uppwrprot.
+    // Set the Write Protection Enable Bit Field of the Write Protection
+    // Register accordingly.
+    if (cfg->wrprot_enable)
+    {
+        alt_setbits_word(ALT_QSPI_WRPROT_ADDR, ALT_QSPI_WRPROT_EN_SET(1));
+    }
+    else
+    {
+        alt_clrbits_word(ALT_QSPI_WRPROT_ADDR, ALT_QSPI_WRPROT_EN_SET(1));
+    }
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_qspi_device_read_config_get(ALT_QSPI_DEV_INST_CONFIG_t * cfg)
+{
+    // Read the Device Read Instruction Register - devrd.
+    uint32_t devrd = alt_read_word(ALT_QSPI_DEVRD_ADDR);
+
+    cfg->op_code        = ALT_QSPI_DEVRD_RDOPCODE_GET(devrd);
+    cfg->inst_type      = (ALT_QSPI_MODE_t) ALT_QSPI_DEVRD_INSTWIDTH_GET(devrd);
+    cfg->addr_xfer_type = (ALT_QSPI_MODE_t) ALT_QSPI_DEVRD_ADDRWIDTH_GET(devrd);
+    cfg->data_xfer_type = (ALT_QSPI_MODE_t) ALT_QSPI_DEVRD_DATAWIDTH_GET(devrd);
+    cfg->dummy_cycles   = ALT_QSPI_DEVRD_DUMMYRDCLKS_GET(devrd);
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_qspi_device_read_config_set(const ALT_QSPI_DEV_INST_CONFIG_t * cfg)
+{
+    if (alt_qspi_is_idle() == false)
+    {
+        return ALT_E_ERROR;
+    }
+
+    // Validate input
+
+    if (cfg->op_code > ((1 << ALT_QSPI_DEVRD_RDOPCODE_WIDTH) - 1))
+    {
+        return ALT_E_BAD_ARG;
+    }
+
+    switch (cfg->inst_type)
+    {
+    case ALT_QSPI_MODE_SINGLE:
+    case ALT_QSPI_MODE_DUAL:
+    case ALT_QSPI_MODE_QUAD:
+        break;
+    default:
+        return ALT_E_BAD_ARG;
+    }
+
+    switch (cfg->addr_xfer_type)
+    {
+    case ALT_QSPI_MODE_SINGLE:
+    case ALT_QSPI_MODE_DUAL:
+    case ALT_QSPI_MODE_QUAD:
+        break;
+    default:
+        return ALT_E_BAD_ARG;
+    }
+
+    switch (cfg->data_xfer_type)
+    {
+    case ALT_QSPI_MODE_SINGLE:
+    case ALT_QSPI_MODE_DUAL:
+    case ALT_QSPI_MODE_QUAD:
+        break;
+    default:
+        return ALT_E_BAD_ARG;
+    }
+
+    if (cfg->dummy_cycles > ((1 << ALT_QSPI_DEVRD_DUMMYRDCLKS_WIDTH) - 1))
+    {
+        return ALT_E_BAD_ARG;
+    }
+
+    /////
+
+    // Read the Device Read Instruction Register - devrd.
+    uint32_t devrd = alt_read_word(ALT_QSPI_DEVRD_ADDR);
+
+    devrd &= ALT_QSPI_DEVRD_RDOPCODE_CLR_MSK &
+             ALT_QSPI_DEVRD_INSTWIDTH_CLR_MSK &
+             ALT_QSPI_DEVRD_ADDRWIDTH_CLR_MSK &
+             ALT_QSPI_DEVRD_DATAWIDTH_CLR_MSK &
+             ALT_QSPI_DEVRD_DUMMYRDCLKS_CLR_MSK;
+
+    devrd |= ALT_QSPI_DEVRD_RDOPCODE_SET(cfg->op_code) |
+             ALT_QSPI_DEVRD_INSTWIDTH_SET(cfg->inst_type) |
+             ALT_QSPI_DEVRD_ADDRWIDTH_SET(cfg->addr_xfer_type) |
+             ALT_QSPI_DEVRD_DATAWIDTH_SET(cfg->data_xfer_type) |
+             ALT_QSPI_DEVRD_DUMMYRDCLKS_SET(cfg->dummy_cycles);
+
+    alt_write_word(ALT_QSPI_DEVRD_ADDR, devrd);
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_qspi_device_write_config_get(ALT_QSPI_DEV_INST_CONFIG_t * cfg)
+{
+    // Device Write Instruction Register - devwr.
+    uint32_t devwr = alt_read_word(ALT_QSPI_DEVWR_ADDR);
+
+    cfg->op_code        = ALT_QSPI_DEVWR_WROPCODE_GET(devwr);
+    // The Instruction Type field in the Device READ Instruction Register only appears
+    // once and applies to both READ and WRITE opertions. it is not included in the
+    // Device WRITE Instruction Register.
+    cfg->inst_type      = (ALT_QSPI_MODE_t) ALT_QSPI_DEVRD_INSTWIDTH_GET(alt_read_word(ALT_QSPI_DEVRD_ADDR));
+    cfg->addr_xfer_type = (ALT_QSPI_MODE_t) ALT_QSPI_DEVWR_ADDRWIDTH_GET(devwr);
+    cfg->data_xfer_type = (ALT_QSPI_MODE_t) ALT_QSPI_DEVWR_DATAWIDTH_GET(devwr);
+    cfg->dummy_cycles   = ALT_QSPI_DEVWR_DUMMYWRCLKS_GET(devwr);
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_qspi_device_write_config_set(const ALT_QSPI_DEV_INST_CONFIG_t * cfg)
+{
+    if (alt_qspi_is_idle() == false)
+    {
+        return ALT_E_ERROR;
+    }
+
+    // Validate input
+
+    if (cfg->op_code > ((1 << ALT_QSPI_DEVWR_WROPCODE_WIDTH) - 1))
+    {
+        return ALT_E_BAD_ARG;
+    }
+
+    switch (cfg->inst_type)
+    {
+    case ALT_QSPI_MODE_SINGLE:
+    case ALT_QSPI_MODE_DUAL:
+    case ALT_QSPI_MODE_QUAD:
+        break;
+    default:
+        return ALT_E_BAD_ARG;
+    }
+
+    switch (cfg->addr_xfer_type)
+    {
+    case ALT_QSPI_MODE_SINGLE:
+    case ALT_QSPI_MODE_DUAL:
+    case ALT_QSPI_MODE_QUAD:
+        break;
+    default:
+        return ALT_E_BAD_ARG;
+    }
+
+    switch (cfg->data_xfer_type)
+    {
+    case ALT_QSPI_MODE_SINGLE:
+    case ALT_QSPI_MODE_DUAL:
+    case ALT_QSPI_MODE_QUAD:
+        break;
+    default:
+        return ALT_E_BAD_ARG;
+    }
+
+    if (cfg->dummy_cycles > ((1 << ALT_QSPI_DEVWR_DUMMYWRCLKS_WIDTH) - 1))
+    {
+        return ALT_E_BAD_ARG;
+    }
+
+    /////
+
+    // Read the Device Write Instruction Register - devwr.
+    uint32_t devwr = alt_read_word(ALT_QSPI_DEVWR_ADDR);
+
+    devwr &= ALT_QSPI_DEVWR_WROPCODE_CLR_MSK &
+             ALT_QSPI_DEVWR_ADDRWIDTH_CLR_MSK &
+             ALT_QSPI_DEVWR_DATAWIDTH_CLR_MSK &
+             ALT_QSPI_DEVWR_DUMMYWRCLKS_CLR_MSK;
+
+    devwr |= ALT_QSPI_DEVWR_WROPCODE_SET(cfg->op_code) |
+             ALT_QSPI_DEVWR_ADDRWIDTH_SET(cfg->addr_xfer_type) |
+             ALT_QSPI_DEVWR_DATAWIDTH_SET(cfg->data_xfer_type) |
+             ALT_QSPI_DEVWR_DUMMYWRCLKS_SET(cfg->dummy_cycles);
+
+    alt_write_word(ALT_QSPI_DEVWR_ADDR, devwr);
+
+    // The Instruction Type field in the Device READ Instruction Register only appears
+    // once and applies to both READ and WRITE operations - it is not included in the
+    // Device WRITE Instruction Register. Therefore, modify the Instruction Type
+    // Field in the Device Read Register.
+    alt_replbits_word(ALT_QSPI_DEVRD_ADDR,
+                      ALT_QSPI_DEVRD_INSTWIDTH_SET_MSK,
+                      ALT_QSPI_DEVRD_INSTWIDTH_SET((uint32_t) cfg->inst_type));
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_qspi_timing_config_get(ALT_QSPI_TIMING_CONFIG_t * cfg)
+{
+    // QSPI Configuration Register - cfg
+    uint32_t cfgreg = alt_read_word(ALT_QSPI_CFG_ADDR);
+    cfg->clk_phase  = (ALT_QSPI_CLK_PHASE_t) ALT_QSPI_CFG_SELCLKPHASE_GET(cfgreg);
+    cfg->clk_pol    = (ALT_QSPI_CLK_POLARITY_t) ALT_QSPI_CFG_SELCLKPOL_GET(cfgreg);
+
+    // QSPI Device Delay Register
+    uint32_t delayreg = alt_read_word(ALT_QSPI_DELAY_ADDR);
+    cfg->cs_sot  = ALT_QSPI_DELAY_INIT_GET(delayreg);
+    cfg->cs_eot  = ALT_QSPI_DELAY_AFTER_GET(delayreg);
+    cfg->cs_dads = ALT_QSPI_DELAY_BTWN_GET(delayreg);
+    cfg->cs_da   = ALT_QSPI_DELAY_NSS_GET(delayreg);
+
+    // Read Data Capture Register
+    cfg->rd_datacap = ALT_QSPI_RDDATACAP_DELAY_GET(alt_read_word(ALT_QSPI_RDDATACAP_ADDR));
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_qspi_timing_config_set(const ALT_QSPI_TIMING_CONFIG_t * cfg)
+{
+    if (alt_qspi_is_idle() == false)
+    {
+        return ALT_E_ERROR;
+    }
+
+    // Validate parameter(s)
+
+    switch (cfg->clk_phase)
+    {
+    case ALT_QSPI_CLK_PHASE_ACTIVE:
+    case ALT_QSPI_CLK_PHASE_INACTIVE:
+        break;
+    default:
+        return ALT_E_BAD_ARG;
+    }
+
+    switch (cfg->clk_pol)
+    {
+    case ALT_QSPI_CLK_POLARITY_LOW:
+    case ALT_QSPI_CLK_POLARITY_HIGH:
+        break;
+    default:
+        return ALT_E_BAD_ARG;
+    }
+
+    if (cfg->cs_da > ((1 << ALT_QSPI_DELAY_NSS_WIDTH) - 1))
+    {
+        return ALT_E_BAD_ARG;
+    }
+    if (cfg->cs_dads > ((1 << ALT_QSPI_DELAY_BTWN_WIDTH) - 1))
+    {
+        return ALT_E_BAD_ARG;
+    }
+    if (cfg->cs_eot > ((1 << ALT_QSPI_DELAY_AFTER_WIDTH) - 1))
+    {
+        return ALT_E_BAD_ARG;
+    }
+    if (cfg->cs_sot > ((1 << ALT_QSPI_DELAY_INIT_WIDTH) - 1))
+    {
+        return ALT_E_BAD_ARG;
+    }
+
+    if (cfg->rd_datacap > ((1 << ALT_QSPI_RDDATACAP_DELAY_WIDTH) - 1))
+    {
+        return ALT_E_BAD_ARG;
+    }
+
+    /////
+
+    // QSPI Configuration Register - cfg
+    uint32_t cfgreg = alt_read_word(ALT_QSPI_CFG_ADDR);
+    cfgreg &= ALT_QSPI_CFG_SELCLKPHASE_CLR_MSK &
+              ALT_QSPI_CFG_SELCLKPOL_CLR_MSK;
+    cfgreg |= ALT_QSPI_CFG_SELCLKPHASE_SET(cfg->clk_phase) |
+              ALT_QSPI_CFG_SELCLKPOL_SET(cfg->clk_pol);
+    alt_write_word(ALT_QSPI_CFG_ADDR, cfgreg);
+
+    // QSPI Device Delay Register
+    uint32_t delayreg = ALT_QSPI_DELAY_INIT_SET(cfg->cs_sot)  |
+                        ALT_QSPI_DELAY_AFTER_SET(cfg->cs_eot) |
+                        ALT_QSPI_DELAY_BTWN_SET(cfg->cs_dads) |
+                        ALT_QSPI_DELAY_NSS_SET(cfg->cs_da);
+    alt_write_word(ALT_QSPI_DELAY_ADDR, delayreg);
+
+    // Read Data Capture Register
+
+    alt_write_word(ALT_QSPI_RDDATACAP_ADDR,
+                   ALT_QSPI_RDDATACAP_BYP_SET(1) | 
+                   ALT_QSPI_RDDATACAP_DELAY_SET(cfg->rd_datacap));
+
+    return ALT_E_SUCCESS;
+}
+
+/////
+
+ALT_STATUS_CODE alt_qspi_direct_disable(void)
+{
+    // Clear (set to 0) the Enable Direct Access Controller Field of the QSPI
+    // Configuration Register to disable the Direct Access Controller.
+    alt_clrbits_word(ALT_QSPI_CFG_ADDR, ALT_QSPI_CFG_ENDIRACC_SET_MSK);
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_qspi_direct_enable(void)
+{
+    // Set (set to 1) the Enable Direct Access Controller Field of the QSPI
+    // Configuration Register to enable the Direct Access Controller.
+    alt_setbits_word(ALT_QSPI_CFG_ADDR, ALT_QSPI_CFG_ENDIRACC_SET_MSK);
+
+    return ALT_E_SUCCESS;
+}
+
+uint32_t alt_qspi_ahb_remap_address_get(void)
+{
+    // Read and return the value of the Remap Address Register.
+    return ALT_QSPI_REMAPADDR_VALUE_GET(alt_read_word(ALT_QSPI_REMAPADDR_ADDR));
+}
+
+ALT_STATUS_CODE alt_qspi_ahb_remap_address_set(const uint32_t ahb_remap_addr)
+{
+    if (alt_qspi_is_idle() == false)
+    {
+        return ALT_E_ERROR;
+    }
+
+    // Read and return the value of the Remap Address Register.
+    alt_setbits_word(ALT_QSPI_REMAPADDR_ADDR, ALT_QSPI_REMAPADDR_VALUE_SET(ahb_remap_addr));
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_qspi_ahb_address_remap_disable(void)
+{
+    // Clear (set to 0) the Enable AHB Address Remapping Field of the QSPI
+    // Configuration Register to disable AHB address remapping.
+    alt_clrbits_word(ALT_QSPI_CFG_ADDR, ALT_QSPI_CFG_ENAHBREMAP_SET_MSK);
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_qspi_ahb_address_remap_enable(void)
+{
+    // Set (set to 1) the Enable AHB Address Remapping Field of the QSPI
+    // Configuration Register to enable AHB address remapping.
+    alt_setbits_word(ALT_QSPI_CFG_ADDR, ALT_QSPI_CFG_ENAHBREMAP_SET_MSK);
+
+    return ALT_E_SUCCESS;
+}
+
+/////
+
+static ALT_STATUS_CODE alt_qspi_indirect_read_start_bank(uint32_t flash_addr,
+                                                         size_t num_bytes)
+{
+    alt_write_word(ALT_QSPI_INDRDSTADDR_ADDR, flash_addr);
+    alt_write_word(ALT_QSPI_INDRDCNT_ADDR, num_bytes);
+    alt_write_word(ALT_QSPI_INDRD_ADDR, ALT_QSPI_INDRD_START_SET_MSK |
+                                        ALT_QSPI_INDRD_IND_OPS_DONE_STAT_SET_MSK);
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_qspi_indirect_read_start(const uint32_t flash_addr,
+                                             const size_t num_bytes)
+{
+    // flash_addr and num_bytes restriction is to prevent possible unaligned
+    // exceptions.
+
+    if (flash_addr & 0x3)
+    {
+        return ALT_E_ERROR;
+    }
+
+    if (num_bytes & 0x3)
+    {
+        return ALT_E_ERROR;
+    }
+
+    if (num_bytes == 0)
+    {
+        // Do not report this as a success. If a indirect read was not
+        // previously completed, it may be cleared already, at which point
+        // alt_qspi_indirect_read_is_complete() will never report true.
+        return ALT_E_ERROR;
+    }
+
+    if (flash_addr > qspi_device_size)
+    {
+        return ALT_E_ERROR;
+    }
+
+    if (flash_addr + num_bytes > qspi_device_size)
+    {
+        return ALT_E_ERROR;
+    }
+
+    // Verify request does not cross bank boundary.
+    // This limitation is due to the 3-byte addressing limitation.
+    if ((flash_addr & ALT_QSPI_BANK_ADDR_MSK) != ((flash_addr + num_bytes - 1) & ALT_QSPI_BANK_ADDR_MSK))
+    {
+        return ALT_E_ERROR;
+    }
+
+    // Verify that there is not already a read in progress.
+    if (ALT_QSPI_INDRD_RD_STAT_GET(alt_read_word(ALT_QSPI_INDRD_ADDR)))
+    {
+        return ALT_E_ERROR;
+    }
+
+    /////
+
+    ALT_STATUS_CODE status;
+    status = alt_qspi_device_bank_select(flash_addr >> 24);
+    if (status != ALT_E_SUCCESS)
+    {
+        return status;
+    }
+
+    /////
+
+    return alt_qspi_indirect_read_start_bank(flash_addr,
+                                             num_bytes);
+
+}
+
+ALT_STATUS_CODE alt_qspi_indirect_read_finish(void)
+{
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_qspi_indirect_read_cancel(void)
+{
+    // An indirect operation may be cancelled at any time by setting Indirect
+    // Transfer Control Register bit [1].
+    alt_write_word(ALT_QSPI_INDRD_ADDR, ALT_QSPI_INDRD_CANCEL_SET_MSK);
+
+    return ALT_E_SUCCESS;
+}
+
+uint32_t alt_qspi_indirect_read_fill_level(void)
+{
+    // Return the SRAM Fill Level (Indirect Read Partition) Field of the SRAM
+    // Fill Register to get the SRAM Fill Level for the Indirect Read Partition
+    // in units of SRAM Words (4 bytes).
+    return ALT_QSPI_SRAMFILL_INDRDPART_GET(alt_read_word(ALT_QSPI_SRAMFILL_ADDR));
+}
+
+uint32_t alt_qspi_indirect_read_watermark_get(void)
+{
+    // Return the Watermark value in the Indirect Read Transfer Watermark Register.
+    return alt_read_word(ALT_QSPI_INDRDWATER_ADDR);
+}
+
+ALT_STATUS_CODE alt_qspi_indirect_read_watermark_set(const uint32_t watermark)
+{
+    // Verify that there is not already a read in progress.
+    if (ALT_QSPI_INDRD_RD_STAT_GET(alt_read_word(ALT_QSPI_INDRD_ADDR)))
+    {
+        return ALT_E_ERROR;
+    }
+
+    // Set the Watermark value in the Indirect Read Transfer Watermark Register.
+    alt_write_word(ALT_QSPI_INDRDWATER_ADDR, watermark);
+
+    return ALT_E_SUCCESS;
+}
+
+bool alt_qspi_indirect_read_is_complete(void)
+{
+    // The value of the Indirect Completion Status Field of the Indirect Read
+    // Transfer Control Register is set by hardware when an indirect read
+    // operation has completed.
+    return (alt_read_word(ALT_QSPI_INDRD_ADDR) & ALT_QSPI_INDRD_IND_OPS_DONE_STAT_SET_MSK) != 0;
+}
+
+static ALT_STATUS_CODE alt_qspi_indirect_write_start_bank(uint32_t flash_addr,
+                                                          size_t num_bytes)
+{
+    alt_write_word(ALT_QSPI_INDWRSTADDR_ADDR, flash_addr);
+    alt_write_word(ALT_QSPI_INDWRCNT_ADDR, num_bytes);
+    alt_write_word(ALT_QSPI_INDWR_ADDR, ALT_QSPI_INDWR_START_SET_MSK |
+                                        ALT_QSPI_INDWR_INDDONE_SET_MSK);
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_qspi_indirect_write_start(const uint32_t flash_addr,
+                                              const size_t num_bytes)
+{
+    // flash_addr and num_bytes restriction is to prevent possible unaligned
+    // exceptions.
+
+    if (flash_addr & 0x3)
+    {
+        return ALT_E_ERROR;
+    }
+
+    if (num_bytes & 0x3)
+    {
+        return ALT_E_ERROR;
+    }
+
+    if (num_bytes == 0)
+    {
+        // Do not report this as a success. If a indirect write was not
+        // previously completed, it may be cleared already, at which point
+        // alt_qspi_indirect_write_is_complete() will never report true.
+        return ALT_E_ERROR;
+    }
+
+    if (num_bytes > 256)
+    {
+        // The Micron part can only write up to 256 bytes at a time.
+        return ALT_E_ERROR;
+    }
+
+    if (flash_addr > qspi_device_size)
+    {
+        return ALT_E_ERROR;
+    }
+
+    if (flash_addr + num_bytes > qspi_device_size)
+    {
+        return ALT_E_ERROR;
+    }
+
+/*
+    // Verify request does not cross bank boundary.
+    // This limitation is due to the 3-byte addressing limitation.
+    if ((flash_addr & ALT_QSPI_BANK_ADDR_MSK) != ((flash_addr + num_bytes - 1) & ALT_QSPI_BANK_ADDR_MSK))
+    {
+        return ALT_E_ERROR;
+    }
+*/
+    // Verify request does not cross page boundary.
+    // This limitation is in place for the Micron part used.
+    if ((flash_addr & ALT_QSPI_PAGE_ADDR_MSK) != ((flash_addr + num_bytes - 1) & ALT_QSPI_PAGE_ADDR_MSK))
+    {
+        return ALT_E_ERROR;
+    }
+
+    // Verify that there is not already a write in progress.
+    if (ALT_QSPI_INDWR_RDSTAT_GET(alt_read_word(ALT_QSPI_INDWR_ADDR)))
+    {
+        return ALT_E_ERROR;
+    }
+
+    /////
+
+    ALT_STATUS_CODE status = ALT_E_SUCCESS;
+    status = alt_qspi_device_bank_select(flash_addr >> 24);
+    if (status != ALT_E_SUCCESS)
+    {
+        return status;
+    }
+
+    /////
+
+    return alt_qspi_indirect_write_start_bank(flash_addr,
+                                              num_bytes);
+}
+
+ALT_STATUS_CODE alt_qspi_indirect_write_finish(void)
+{
+#if ALT_QSPI_PROVISION_MICRON_N25Q_SUPPORT
+    return alt_qspi_N25Q_flag_wait_for_program(ALT_QSPI_TIMEOUT_INFINITE);
+#else
+    return ALT_E_SUCCESS;
+#endif
+}
+
+ALT_STATUS_CODE alt_qspi_indirect_write_cancel(void)
+{
+    ALT_STATUS_CODE status = ALT_E_SUCCESS;
+
+#if ALT_QSPI_PROVISION_MICRON_N25Q_SUPPORT
+    if (status == ALT_E_SUCCESS)
+    {
+        status = alt_qspi_N25Q_flag_wait_for_program(ALT_QSPI_TIMEOUT_INFINITE);
+    }
+#endif
+
+    if (status == ALT_E_SUCCESS)
+    {
+        // An indirect operation may be cancelled at any time by setting Indirect
+        // Transfer Control Register bit [1].
+        alt_write_word(ALT_QSPI_INDWR_ADDR, ALT_QSPI_INDWR_CANCEL_SET_MSK);
+    }
+
+    return status;
+}
+
+uint32_t alt_qspi_indirect_write_fill_level(void)
+{
+    // Return the SRAM Fill Level (Indirect Write Partition) Field of the SRAM
+    // Fill Register to get the SRAM Fill Level for the Indirect Write Partition
+    // in units of SRAM Words (4 bytes).
+    return ALT_QSPI_SRAMFILL_INDWRPART_GET(alt_read_word(ALT_QSPI_SRAMFILL_ADDR));
+}
+
+uint32_t alt_qspi_indirect_write_watermark_get(void)
+{
+    // Return the Watermark value in the Indirect Write Transfer Watermark Register.
+    return alt_read_word(ALT_QSPI_INDWRWATER_ADDR);
+}
+
+ALT_STATUS_CODE alt_qspi_indirect_write_watermark_set(const uint32_t watermark)
+{
+    // Verify that there is not already a write in progress.
+    if (ALT_QSPI_INDWR_RDSTAT_GET(alt_read_word(ALT_QSPI_INDWR_ADDR)))
+    {
+        return ALT_E_ERROR;
+    }
+
+    // Set the Watermark value in the Indirect Write Transfer Watermark Register.
+    alt_write_word(ALT_QSPI_INDWRWATER_ADDR, watermark);
+
+    return ALT_E_SUCCESS;
+}
+
+bool alt_qspi_indirect_write_is_complete(void)
+{
+    // The value of the Indirect Completion Status Field of the Indirect Write
+    // Transfer Control Register is set by hardware when an indirect write
+    // operation has completed.
+    return (alt_read_word(ALT_QSPI_INDWR_ADDR) & ALT_QSPI_INDWR_INDDONE_SET_MSK) != 0;
+}
+
+/////
+
+uint32_t alt_qspi_sram_partition_get(void)
+{
+    // The number of locations allocated to indirect read is equal to the value
+    // of the SRAM partition register. See the documentation for this function
+    // regarding the + 1 in the IP documentation. This way the get() and set()
+    // will be symmetrical.
+
+    return ALT_QSPI_SRAMPART_ADDR_GET(alt_read_word(ALT_QSPI_SRAMPART_ADDR));
+}
+
+ALT_STATUS_CODE alt_qspi_sram_partition_set(const uint32_t read_part_size)
+{
+    if (read_part_size > ((1 << ALT_QSPI_SRAMPART_ADDR_WIDTH) - 1))
+    {
+        return ALT_E_ARG_RANGE;
+    }
+
+    alt_replbits_word(ALT_QSPI_SRAMPART_ADDR,
+                      ALT_QSPI_SRAMPART_ADDR_SET_MSK,
+                      ALT_QSPI_SRAMPART_ADDR_SET(read_part_size));
+
+    return ALT_E_SUCCESS;
+}
+
+/////
+
+
+static ALT_STATUS_CODE alt_qspi_erase_subsector_bank(uint32_t addr)
+{
+    ALT_STATUS_CODE status = ALT_E_SUCCESS;
+
+    if (status == ALT_E_SUCCESS)
+    {
+        status = alt_qspi_device_wren();
+    }
+    
+    if (status == ALT_E_SUCCESS)
+    {
+        status = alt_qspi_stig_addr_cmd(ALT_QSPI_STIG_OPCODE_SUBSEC_ERASE, 0, addr, 10000);
+    }
+
+#if ALT_QSPI_PROVISION_MICRON_N25Q_SUPPORT
+    if (status == ALT_E_SUCCESS)
+    {
+        status = alt_qspi_N25Q_flag_wait_for_erase(ALT_QSPI_TIMEOUT_INFINITE);
+    }
+#endif
+
+    return status;
+}
+
+ALT_STATUS_CODE alt_qspi_erase_subsector(const uint32_t addr)
+{
+    ALT_STATUS_CODE status = ALT_E_SUCCESS;
+
+    if (status == ALT_E_SUCCESS)
+    {
+        status = alt_qspi_device_bank_select(addr >> 24);
+    }
+
+    if (status == ALT_E_SUCCESS)
+    {
+        status = alt_qspi_erase_subsector_bank(addr);
+    }
+
+    return status;
+}
+
+ALT_STATUS_CODE alt_qspi_erase_sector(const uint32_t addr)
+{
+    ALT_STATUS_CODE status = ALT_E_SUCCESS;
+
+    if (status == ALT_E_SUCCESS)
+    {
+        status = alt_qspi_device_bank_select(addr >> 24);
+    }
+
+    if (status == ALT_E_SUCCESS)
+    {
+        status = alt_qspi_device_wren();
+    }
+
+    if (status == ALT_E_SUCCESS)
+    {
+        status = alt_qspi_stig_addr_cmd(ALT_QSPI_STIG_OPCODE_SEC_ERASE, 0, addr, ALT_QSPI_TIMEOUT_INFINITE);
+    }
+
+#if ALT_QSPI_PROVISION_MICRON_N25Q_SUPPORT
+    if (status == ALT_E_SUCCESS)
+    {
+        status = alt_qspi_N25Q_flag_wait_for_erase(ALT_QSPI_TIMEOUT_INFINITE);
+    }
+#endif
+
+    return status;
+}
+
+ALT_STATUS_CODE alt_qspi_erase_chip(void)
+{
+    ALT_STATUS_CODE status = ALT_E_SUCCESS;
+
+    if (qspi_device_size >= (2 * ALT_QSPI_N25Q_DIE_SIZE))
+    {
+        // NOTE: This path is specifically for 512 Mib and 1 Gib Micron N25Q
+        //   chips only.
+
+        dprintf("DEBUG[QSPI]: erase[chip]: FYI, wait time is ~800s for 128 MiB.\n");
+
+        uint32_t die_count = qspi_device_size / ALT_QSPI_N25Q_DIE_SIZE;
+
+        for (int i = 0; i < die_count; ++i)
+        {
+            if (status != ALT_E_SUCCESS)
+            {
+                break;
+            }
+
+            dprintf("DEBUG[QSPI]: Erase chip: die = %d, total = %" PRIu32 ".\n", i, die_count);
+
+            if (status == ALT_E_SUCCESS)
+            {
+                status = alt_qspi_device_bank_select(i * (ALT_QSPI_N25Q_DIE_SIZE / ALT_QSPI_BANK_SIZE));
+            }
+
+            if (status == ALT_E_SUCCESS)
+            {
+                status = alt_qspi_device_wren(); 
+            }
+
+            if (status == ALT_E_SUCCESS)
+            {
+                status = alt_qspi_stig_addr_cmd(ALT_QSPI_STIG_OPCODE_DIE_ERASE, 0,
+                                                i * ALT_QSPI_N25Q_DIE_SIZE,
+                                                ALT_QSPI_TIMEOUT_INFINITE);
+            }
+
+#if ALT_QSPI_PROVISION_MICRON_N25Q_SUPPORT
+            if (status == ALT_E_SUCCESS)
+            {
+                status = alt_qspi_N25Q_flag_wait_for_erase(ALT_QSPI_TIMEOUT_INFINITE);
+            }
+#endif
+        }
+    }
+    else
+    {
+        // NOTE: Untested path.
+
+        dprintf("DEBUG[QSPI]: Bulk erase.\n");
+
+        if (status == ALT_E_SUCCESS)
+        {
+            status = alt_qspi_device_bank_select(0);
+        }
+
+        if (status == ALT_E_SUCCESS)
+        {
+            status = alt_qspi_device_wren();
+        }
+
+        if (status == ALT_E_SUCCESS)
+        {
+            // If BULK_ERASE is like other ERASE, it needs the address command.
+            status = alt_qspi_stig_addr_cmd(ALT_QSPI_STIG_OPCODE_BULK_ERASE, 0,
+                                            0,
+                                            ALT_QSPI_TIMEOUT_INFINITE);
+        }
+
+#if ALT_QSPI_PROVISION_MICRON_N25Q_SUPPORT
+        if (status == ALT_E_SUCCESS)
+        {
+            status = alt_qspi_N25Q_flag_wait_for_erase(ALT_QSPI_TIMEOUT_INFINITE);
+        }
+#endif
+    }
+
+    return status;
+}
+
+/////
+
+ALT_STATUS_CODE alt_qspi_dma_disable(void)
+{
+    // Clear (set to 0) the Enable DMA Peripheral Interface Field of the QSPI
+    // Configuration Register to disable the DMA peripheral interface.
+    alt_clrbits_word(ALT_QSPI_CFG_ADDR, ALT_QSPI_CFG_ENDMA_SET_MSK);
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_qspi_dma_enable(void)
+{
+    // Set (set to 1) the Enable DMA Peripheral Interface Field of the QSPI
+    // Configuration Register to enable the DMA peripheral interface.
+    alt_setbits_word(ALT_QSPI_CFG_ADDR, ALT_QSPI_CFG_ENDMA_SET_MSK);
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_qspi_dma_config_get(uint32_t * single_type_sz,
+                                        uint32_t * burst_type_sz)
+{
+    // Get the current value of the DMA Peripheral Register - dmaper
+    uint32_t dmaper = alt_read_word(ALT_QSPI_DMAPER_ADDR);
+
+    // For both values, a programmed value of 0 represents a single byte. The
+    // actual number of bytes used is 2 ** (value in this register field).
+    *single_type_sz = 1 << ALT_QSPI_DMAPER_NUMSGLREQBYTES_GET(dmaper);
+    *burst_type_sz  = 1 << ALT_QSPI_DMAPER_NUMBURSTREQBYTES_GET(dmaper);
+
+    return ALT_E_SUCCESS;
+}
+
+//
+// Returns true if [n] is a power of 2 value otherwise returns false.
+//
+static bool is_pow_2(uint32_t n)
+{
+    return ((n > 0) && ((n & (n - 1)) == 0));
+}
+
+//
+// Return the log base 2 value of a number that is known to be a power of 2.
+//
+static uint32_t log2u(uint32_t value)
+{
+    uint32_t exp = 0;
+    while ((exp < 32) && (value != (1 << exp)))
+    {
+        ++exp;
+    }
+    return exp;
+}
+
+ALT_STATUS_CODE alt_qspi_dma_config_set(const uint32_t single_type_sz,
+                                        const uint32_t burst_type_sz)
+{
+    if (alt_qspi_is_idle() == false)
+    {
+        return ALT_E_ERROR;
+    }
+
+    if (single_type_sz < 4)
+    {
+        return ALT_E_ERROR;
+    }
+
+    if (burst_type_sz < 4)
+    {
+        return ALT_E_ERROR;
+    }
+
+    if (burst_type_sz < single_type_sz)
+    {
+        return ALT_E_ERROR;
+    }
+
+    const uint32_t single_type_sz_max = 1 << ((1 << ALT_QSPI_DMAPER_NUMSGLREQBYTES_WIDTH) - 1);
+    const uint32_t burst_type_sz_max  = 1 << ((1 << ALT_QSPI_DMAPER_NUMBURSTREQBYTES_WIDTH) - 1);
+
+    // Both parameter values must be a power of 2 between 1 and 32728.
+    if (  (single_type_sz > single_type_sz_max) || !is_pow_2(single_type_sz)
+       || (burst_type_sz  > burst_type_sz_max)  || !is_pow_2(burst_type_sz)
+       )
+    {
+        return ALT_E_ARG_RANGE;
+    }
+
+    // Get the current value of the DMA Peripheral Register - dmaper
+    uint32_t dmaper = alt_read_word(ALT_QSPI_DMAPER_ADDR);
+    dmaper &= ALT_QSPI_DMAPER_NUMBURSTREQBYTES_CLR_MSK &
+              ALT_QSPI_DMAPER_NUMSGLREQBYTES_CLR_MSK;
+    dmaper |= ALT_QSPI_DMAPER_NUMBURSTREQBYTES_SET(log2u(burst_type_sz)) |
+              ALT_QSPI_DMAPER_NUMSGLREQBYTES_SET(log2u(single_type_sz));
+    alt_write_word(ALT_QSPI_DMAPER_ADDR, dmaper);
+
+    return ALT_E_SUCCESS;
+}
+
+/////
+
+//
+// Private STIG and device commands
+//
+
+static ALT_STATUS_CODE alt_qspi_stig_cmd_helper(uint32_t reg_value, uint32_t timeout)
+{
+    ALT_STATUS_CODE status = ALT_E_SUCCESS;
+    bool infinite = (timeout == ALT_QSPI_TIMEOUT_INFINITE);
+
+    alt_write_word(ALT_QSPI_FLSHCMD_ADDR, reg_value);
+    alt_write_word(ALT_QSPI_FLSHCMD_ADDR, reg_value | ALT_QSPI_FLSHCMD_EXECCMD_E_EXECUTE);
+
+    do
+    {
+        reg_value = alt_read_word(ALT_QSPI_FLSHCMD_ADDR);
+        if (!(reg_value & ALT_QSPI_FLSHCMD_CMDEXECSTAT_SET_MSK))
+        {
+            break;
+        }
+
+    } while (timeout-- || infinite);
+
+    if (timeout == (uint32_t)-1 && !infinite)
+    {
+        status = ALT_E_TMO;
+    }
+
+    return status;
+}
+
+ALT_STATUS_CODE alt_qspi_stig_cmd(uint32_t opcode, uint32_t dummy, uint32_t timeout)
+{
+    if (dummy > ((1 << ALT_QSPI_FLSHCMD_NUMDUMMYBYTES_WIDTH) - 1))
+    {
+        return ALT_E_ERROR;
+    }
+
+    uint32_t reg = ALT_QSPI_FLSHCMD_CMDOPCODE_SET(opcode) |
+                   ALT_QSPI_FLSHCMD_NUMDUMMYBYTES_SET(dummy);
+
+    return alt_qspi_stig_cmd_helper(reg, timeout);
+}
+
+ALT_STATUS_CODE alt_qspi_stig_rd_cmd(uint8_t opcode,
+                                     uint32_t dummy,
+                                     uint32_t num_bytes,
+                                     uint32_t * output,
+                                     uint32_t timeout)
+{
+    if (dummy > ((1 << ALT_QSPI_FLSHCMD_NUMDUMMYBYTES_WIDTH) - 1))
+    {
+        return ALT_E_ERROR;
+    }
+
+    // STIG read can only return up to 8 bytes.
+    if ((num_bytes > 8) || (num_bytes == 0))
+    {
+        return ALT_E_BAD_ARG;
+    }
+
+    uint32_t reg_value = 
+        ALT_QSPI_FLSHCMD_CMDOPCODE_SET(opcode)                              |
+        ALT_QSPI_FLSHCMD_ENRDDATA_SET(ALT_QSPI_FLSHCMD_ENRDDATA_E_EN)       |
+        ALT_QSPI_FLSHCMD_NUMRDDATABYTES_SET(num_bytes - 1)                  |
+        ALT_QSPI_FLSHCMD_ENCMDADDR_SET(ALT_QSPI_FLSHCMD_ENCMDADDR_E_DISD)   |
+        ALT_QSPI_FLSHCMD_ENMODBIT_SET(ALT_QSPI_FLSHCMD_ENMODBIT_E_DISD)     |
+        ALT_QSPI_FLSHCMD_NUMADDRBYTES_SET(0)                                |
+        ALT_QSPI_FLSHCMD_ENWRDATA_SET(ALT_QSPI_FLSHCMD_ENWRDATA_E_NOACTION) |
+        ALT_QSPI_FLSHCMD_NUMWRDATABYTES_SET(0)                              |
+        ALT_QSPI_FLSHCMD_NUMDUMMYBYTES_SET(dummy);
+
+    ALT_STATUS_CODE status = ALT_E_SUCCESS;
+
+    status = alt_qspi_stig_cmd_helper(reg_value, timeout);
+    if (status != ALT_E_SUCCESS)
+    {
+        return status;
+    }
+
+    output[0] = alt_read_word(ALT_QSPI_FLSHCMDRDDATALO_ADDR);
+
+    if (num_bytes > 4)
+    {
+        output[1] = alt_read_word(ALT_QSPI_FLSHCMDRDDATAUP_ADDR);
+    }
+
+    return ALT_E_SUCCESS;
+}
+
+ALT_STATUS_CODE alt_qspi_stig_wr_cmd(uint8_t opcode,
+                                     uint32_t dummy,
+                                     uint32_t num_bytes, 
+                                     const uint32_t * input,
+                                     uint32_t timeout)
+{
+    if (dummy > ((1 << ALT_QSPI_FLSHCMD_NUMDUMMYBYTES_WIDTH) - 1))
+    {
+        return ALT_E_ERROR;
+    }
+
+    // STIG can only write up to 8 bytes.
+    if ((num_bytes > 8) || (num_bytes == 0))
+    {
+        return ALT_E_BAD_ARG;
+    }
+
+    uint32_t reg_value =
+        ALT_QSPI_FLSHCMD_CMDOPCODE_SET(opcode)                                 |
+        ALT_QSPI_FLSHCMD_ENRDDATA_SET(ALT_QSPI_FLSHCMD_ENRDDATA_E_NOACTION)    |
+        ALT_QSPI_FLSHCMD_NUMRDDATABYTES_SET(0)                                 |
+        ALT_QSPI_FLSHCMD_ENCMDADDR_SET(ALT_QSPI_FLSHCMD_ENCMDADDR_E_DISD)      |
+        ALT_QSPI_FLSHCMD_ENMODBIT_SET(ALT_QSPI_FLSHCMD_ENMODBIT_E_DISD)        |
+        ALT_QSPI_FLSHCMD_NUMADDRBYTES_SET(0)                                   |
+        ALT_QSPI_FLSHCMD_ENWRDATA_SET(ALT_QSPI_FLSHCMD_ENWRDATA_E_WRDATABYTES) |
+        ALT_QSPI_FLSHCMD_NUMWRDATABYTES_SET(num_bytes - 1)                     |
+        ALT_QSPI_FLSHCMD_NUMDUMMYBYTES_SET(dummy);
+
+    alt_write_word(ALT_QSPI_FLSHCMDWRDATALO_ADDR, input[0]);
+
+    if (num_bytes > 4)
+    {
+        alt_write_word(ALT_QSPI_FLSHCMDWRDATAUP_ADDR, input[1]);
+    }
+
+    return alt_qspi_stig_cmd_helper(reg_value, timeout);
+}
+
+ALT_STATUS_CODE alt_qspi_stig_addr_cmd(uint8_t opcode,
+                                       uint32_t dummy,
+                                       uint32_t address,
+                                       uint32_t timeout)
+{
+    if (dummy > ((1 << ALT_QSPI_FLSHCMD_NUMDUMMYBYTES_WIDTH) - 1))
+    {
+        return ALT_E_ERROR;
+    }
+
+    uint32_t reg = ALT_QSPI_FLSHCMD_CMDOPCODE_SET(opcode) |
+                   ALT_QSPI_FLSHCMD_NUMDUMMYBYTES_SET(dummy);
+
+    reg |= ALT_QSPI_FLSHCMD_ENCMDADDR_SET(ALT_QSPI_FLSHCMD_ENCMDADDR_E_END);
+    reg |= ALT_QSPI_FLSHCMD_NUMADDRBYTES_SET(ALT_QSPI_FLSHCMD_NUMADDRBYTES_E_ADDRBYTE3);
+
+    alt_write_word(ALT_QSPI_FLSHCMDADDR_ADDR, address);
+
+    return alt_qspi_stig_cmd_helper(reg, timeout);
+}
+
+/////
+
+ALT_STATUS_CODE alt_qspi_device_wren(void) 
+{
+    // Write enable through STIG (not required, auto send by controller during write)
+    return alt_qspi_stig_cmd(ALT_QSPI_STIG_OPCODE_WREN, 0, 10000);
+}
+
+ALT_STATUS_CODE alt_qspi_device_wrdis(void) 
+{
+    // Write disable through STIG (not required, auto send by controller during write)
+    return alt_qspi_stig_cmd(ALT_QSPI_STIG_OPCODE_WRDIS, 0, 10000);
+}
+
+ALT_STATUS_CODE alt_qspi_device_rdid(uint32_t * rdid)
+{
+    // Read flash device ID through STIG
+    return alt_qspi_stig_rd_cmd(ALT_QSPI_STIG_OPCODE_RDID, 0, 4, rdid, 10000);
+}
+
+ALT_STATUS_CODE alt_qspi_discovery_parameter(uint32_t * param)
+{
+    // Read flash discovery parameters through STIG
+
+    return alt_qspi_stig_rd_cmd(ALT_QSPI_STIG_OPCODE_DISCVR_PARAM, 8, 8, param, 10000);
+}
+
+ALT_STATUS_CODE alt_qspi_device_bank_select(uint32_t bank) 
+{
+    ALT_STATUS_CODE status = ALT_E_SUCCESS;
+    dprintf("DEBUG[QSPI]: bank_select(): switching to bank 0x%" PRIu32 ".\n", bank);
+
+    if (status == ALT_E_SUCCESS)
+    {
+        status = alt_qspi_device_wren();
+    }
+
+    if (status == ALT_E_SUCCESS)
+    {
+        status = alt_qspi_stig_wr_cmd(ALT_QSPI_STIG_OPCODE_WR_EXT_REG, 0, 1, &bank, 10000);
+    }
+
+    if (status == ALT_E_SUCCESS)
+    {
+        status = alt_qspi_device_wrdis();
+    }
+
+    return status;
+}
+
+/////
+
+static bool alt_qspi_is_enabled(void)
+{
+    uint32_t cfg = alt_read_word(ALT_QSPI_CFG_ADDR);
+
+    if (cfg & ALT_QSPI_CFG_EN_SET_MSK)
+    {
+        return true;
+    }
+    else
+    {
+        return false;
+    }
+}
+
+ALT_STATUS_CODE alt_qspi_ecc_start(void * block, size_t size)
+{
+    if (size < (ALT_QSPI_PAGE_SIZE * 8))
+    {
+        return ALT_E_ERROR;
+    }
+
+    if (alt_qspi_is_enabled() == false)
+    {
+        return ALT_E_ERROR;
+    }
+
+    if (alt_qspi_is_idle() == false)
+    {
+        return ALT_E_ERROR;
+    }
+
+    ALT_STATUS_CODE status = ALT_E_SUCCESS;
+
+    // 1. Configure SRAM Partition Register to 126 words for read, 2 words for write.
+    // 2. Enable ECC on QSPI RAM
+    // 3. Trigger an indirect read transfer that will fill up 126 words in FIFO by
+    //    monitoring read FIFO fill level; Do not read out data through AHB.
+    // 4. Start AHB read and start indirect write operation to write back to the same
+    //    device location, this will fill up and initilaize the write partition RAM.
+    // 5. To clear spurious interrupts, reset the QSPI controller.
+
+    // Save the previous partition size
+
+    uint32_t sram_orig = alt_qspi_sram_partition_get();
+    dprintf("DEBUG[QSPI][ECC]: Save original SRAM as %" PRIu32 ".\n", sram_orig);
+
+    // Step 1
+
+    uint32_t sram_fill = (1 << ALT_QSPI_SRAMPART_ADDR_WIDTH) - 2;
+    alt_qspi_sram_partition_set(sram_fill);
+    dprintf("DEBUG[QSPI][ECC]: Set new SRAM as %" PRIu32 ".\n", sram_fill);
+
+    // Step 2
+
+    dprintf("DEBUG[QSPI][ECC]: Enable ECC in SysMgr.\n");
+    alt_write_word(ALT_SYSMGR_ECC_QSPI_ADDR, ALT_SYSMGR_ECC_QSPI_EN_SET_MSK);
+
+    // Step 3
+
+    // Issue a read ~ 2x larger than the read partition. We will read out 1 page,
+    // which will be used as the buffer to write back to QSPI. This way no data
+    // actually changes thus no erase will be needed.
+
+    if (status == ALT_E_SUCCESS)
+    {
+        dprintf("DEBUG[QSPI][ECC]: Start indirect read PAGE * 8.\n");
+        status = alt_qspi_indirect_read_start(0x0, ALT_QSPI_PAGE_SIZE * 8);
+    }
+
+    // Read out 1 page for the write data
+
+    if (status == ALT_E_SUCCESS)
+    {
+        dprintf("DEBUG[QSPI][ECC]: Reading out 1 page ...\n");
+
+        uint32_t read_size = 0;
+        char *   buffer    = block;
+        while (read_size < ALT_QSPI_PAGE_SIZE)
+        {
+            uint32_t level = alt_qspi_indirect_read_fill_level();
+            level = MIN(level, (ALT_QSPI_PAGE_SIZE - read_size) / sizeof(uint32_t));
+
+            uint32_t * data = (uint32_t *)(&buffer[read_size]);
+            for (uint32_t i = 0; i < level; ++i)
+            {
+                *data = alt_read_word(ALT_QSPIDATA_ADDR);
+                ++data;
+            }
+
+            read_size += level * sizeof(uint32_t);
+        }
+
+        if (read_size != ALT_QSPI_PAGE_SIZE)
+        {
+            status = ALT_E_ERROR;
+        }
+    }
+
+    // Wait for read FIFO to report it is up to the specified fill level.
+
+    if (status == ALT_E_SUCCESS)
+    {
+        dprintf("DEBUG[QSPI][ECC]: Waiting for read fill level ...\n");
+
+        uint32_t timeout = 10000;
+
+        while (alt_qspi_indirect_read_fill_level() < sram_fill)
+        {
+            if (--timeout == 0)
+            {
+                dprintf("DEBUG[QSPI][ECC]: Waiting for read fill timeout !!!\n");
+                status = ALT_E_TMO;
+                break;
+            }
+        }
+    }
+
+    // Step 4
+
+    // Issue a write of 1 page of the same data from 0x0.
+
+    if (status == ALT_E_SUCCESS)
+    {
+        dprintf("DEBUG[QSPI][ECC]: Start indirect write PAGE.\n");
+        status = alt_qspi_indirect_write_start(0x0, ALT_QSPI_PAGE_SIZE);
+    }
+
+    if (status == ALT_E_SUCCESS)
+    {
+        dprintf("DEBUG[QSPI][ECC]: Writing in 1 page ...\n");
+
+        uint32_t write_size = 0;
+        char *   buffer     = block;
+
+        while (write_size < ALT_QSPI_PAGE_SIZE)
+        {
+            uint32_t space = 2 - alt_qspi_indirect_write_fill_level();
+            if (space == 0)
+            {
+                dprintf("DEBUG[QSPI][ECC]: Write FIFO filled at write_size = %" PRIu32 ".\n", write_size);
+                // Space = 0; which means all 2 positions in the write FIFO is filled,
+                // meaning it has been initialized with respect to ECC.
+                break;
+            }
+
+            space = MIN(space, (ALT_QSPI_PAGE_SIZE - write_size) / sizeof(uint32_t));
+
+            uint32_t * data = (uint32_t *)(&buffer[write_size]);
+            for (uint32_t i = 0; i < space; ++i)
+            {
+                alt_write_word(ALT_QSPIDATA_ADDR, *data);
+                ++data;
+            }
+
+            write_size += space * sizeof(uint32_t);
+        }
+
+        if (write_size != ALT_QSPI_PAGE_SIZE)
+        {
+            dprintf("DEBUG[QSPI][ECC]: Cancel indirect write.\n");
+            status = alt_qspi_indirect_write_cancel();
+        }
+    }
+
+    if (status == ALT_E_SUCCESS)
+    {
+        dprintf("DEBUG[QSPI][ECC]: Finish indirect write.\n");
+        status = alt_qspi_indirect_write_finish();
+    }
+
+    // Cancel the indirect read as it has initialized the read FIFO partition.
+
+    if (status == ALT_E_SUCCESS)
+    {
+        dprintf("DEBUG[QSPI][ECC]: Cancel indirect read.\n");
+        status = alt_qspi_indirect_read_cancel();
+    }
+
+    if (status == ALT_E_SUCCESS)
+    {
+        dprintf("DEBUG[QSPI][ECC]: Finish indirect read.\n");
+        status = alt_qspi_indirect_read_finish();
+    }
+
+    // Step 5
+
+    if (status == ALT_E_SUCCESS)
+    {
+        dprintf("DEBUG[QSPI][ECC]: Clear any pending spurious QSPI ECC interrupts.\n");
+
+        alt_write_word(ALT_SYSMGR_ECC_QSPI_ADDR,
+                         ALT_SYSMGR_ECC_QSPI_EN_SET_MSK
+                       | ALT_SYSMGR_ECC_QSPI_SERR_SET_MSK
+                       | ALT_SYSMGR_ECC_QSPI_DERR_SET_MSK);
+    }
+
+    /////
+
+    // Restore original partition
+
+    if (status == ALT_E_SUCCESS)
+    {
+        dprintf("DEBUG[QSPI][ECC]: Restore original SRAM as %" PRIu32 ".\n", sram_orig);
+        status = alt_qspi_sram_partition_set(sram_orig);
+    }
+
+    return status;
+}
diff --git a/c/src/lib/libbsp/arm/altera-cyclone-v/preinstall.am b/c/src/lib/libbsp/arm/altera-cyclone-v/preinstall.am
index 4093831..768c01d 100644
--- a/c/src/lib/libbsp/arm/altera-cyclone-v/preinstall.am
+++ b/c/src/lib/libbsp/arm/altera-cyclone-v/preinstall.am
@@ -143,10 +143,18 @@ $(PROJECT_INCLUDE)/bsp/nocache-heap.h: include/nocache-heap.h $(PROJECT_INCLUDE)
 	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/nocache-heap.h
 PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/nocache-heap.h
 
+$(PROJECT_INCLUDE)/bsp/alt_16550_uart.h: hwlib/include/alt_16550_uart.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/alt_16550_uart.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/alt_16550_uart.h
+
 $(PROJECT_INCLUDE)/bsp/alt_address_space.h: hwlib/include/alt_address_space.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
 	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/alt_address_space.h
 PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/alt_address_space.h
 
+$(PROJECT_INCLUDE)/bsp/alt_cache.h: hwlib/include/alt_cache.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/alt_cache.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/alt_cache.h
+
 $(PROJECT_INCLUDE)/bsp/alt_clock_group.h: hwlib/include/alt_clock_group.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
 	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/alt_clock_group.h
 PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/alt_clock_group.h
@@ -155,6 +163,18 @@ $(PROJECT_INCLUDE)/bsp/alt_clock_manager.h: hwlib/include/alt_clock_manager.h $(
 	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/alt_clock_manager.h
 PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/alt_clock_manager.h
 
+$(PROJECT_INCLUDE)/bsp/alt_dma_common.h: hwlib/include/alt_dma_common.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/alt_dma_common.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/alt_dma_common.h
+
+$(PROJECT_INCLUDE)/bsp/alt_dma.h: hwlib/include/alt_dma.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/alt_dma.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/alt_dma.h
+
+$(PROJECT_INCLUDE)/bsp/alt_dma_program.h: hwlib/include/alt_dma_program.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/alt_dma_program.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/alt_dma_program.h
+
 $(PROJECT_INCLUDE)/bsp/alt_generalpurpose_io.h: hwlib/include/alt_generalpurpose_io.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
 	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/alt_generalpurpose_io.h
 PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/alt_generalpurpose_io.h
@@ -175,6 +195,10 @@ $(PROJECT_INCLUDE)/bsp/alt_mpu_registers.h: hwlib/include/alt_mpu_registers.h $(
 	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/alt_mpu_registers.h
 PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/alt_mpu_registers.h
 
+$(PROJECT_INCLUDE)/bsp/alt_qspi_private.h: hwlib/include/alt_qspi_private.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/alt_qspi_private.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/alt_qspi_private.h
+
 $(PROJECT_INCLUDE)/bsp/alt_reset_manager.h: hwlib/include/alt_reset_manager.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
 	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/alt_reset_manager.h
 PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/alt_reset_manager.h
@@ -191,6 +215,14 @@ $(PROJECT_INCLUDE)/bsp/socal/alt_clkmgr.h: hwlib/include/socal/alt_clkmgr.h $(PR
 	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/socal/alt_clkmgr.h
 PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/socal/alt_clkmgr.h
 
+$(PROJECT_INCLUDE)/bsp/socal/alt_dmanonsecure.h: hwlib/include/socal/alt_dmanonsecure.h $(PROJECT_INCLUDE)/bsp/socal/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/socal/alt_dmanonsecure.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/socal/alt_dmanonsecure.h
+
+$(PROJECT_INCLUDE)/bsp/socal/alt_dmasecure.h: hwlib/include/socal/alt_dmasecure.h $(PROJECT_INCLUDE)/bsp/socal/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/socal/alt_dmasecure.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/socal/alt_dmasecure.h
+
 $(PROJECT_INCLUDE)/bsp/socal/alt_gpio.h: hwlib/include/socal/alt_gpio.h $(PROJECT_INCLUDE)/bsp/socal/$(dirstamp)
 	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/socal/alt_gpio.h
 PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/socal/alt_gpio.h
@@ -203,6 +235,14 @@ $(PROJECT_INCLUDE)/bsp/socal/alt_l3.h: hwlib/include/socal/alt_l3.h $(PROJECT_IN
 	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/socal/alt_l3.h
 PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/socal/alt_l3.h
 
+$(PROJECT_INCLUDE)/bsp/socal/alt_qspidata.h: hwlib/include/socal/alt_qspidata.h $(PROJECT_INCLUDE)/bsp/socal/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/socal/alt_qspidata.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/socal/alt_qspidata.h
+
+$(PROJECT_INCLUDE)/bsp/socal/alt_qspi.h: hwlib/include/socal/alt_qspi.h $(PROJECT_INCLUDE)/bsp/socal/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/socal/alt_qspi.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/socal/alt_qspi.h
+
 $(PROJECT_INCLUDE)/bsp/socal/alt_rstmgr.h: hwlib/include/socal/alt_rstmgr.h $(PROJECT_INCLUDE)/bsp/socal/$(dirstamp)
 	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/socal/alt_rstmgr.h
 PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/socal/alt_rstmgr.h



More information about the vc mailing list