]> git.sur5r.net Git - freertos/blobdiff - FreeRTOS/Demo/CORTEX_A9_Cyclone_V_SoC_DK/Altera_Code/HardwareLibrary/alt_i2c.c
Added project for Altera Cyclone V SoC, currently running from internal RAM.
[freertos] / FreeRTOS / Demo / CORTEX_A9_Cyclone_V_SoC_DK / Altera_Code / HardwareLibrary / alt_i2c.c
diff --git a/FreeRTOS/Demo/CORTEX_A9_Cyclone_V_SoC_DK/Altera_Code/HardwareLibrary/alt_i2c.c b/FreeRTOS/Demo/CORTEX_A9_Cyclone_V_SoC_DK/Altera_Code/HardwareLibrary/alt_i2c.c
new file mode 100644 (file)
index 0000000..028eaf2
--- /dev/null
@@ -0,0 +1,2004 @@
+/******************************************************************************\r
+ *\r
+ * Copyright 2013 Altera Corporation. All Rights Reserved.\r
+ * \r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions are met:\r
+ * \r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ * this list of conditions and the following disclaimer.\r
+ * \r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ * this list of conditions and the following disclaimer in the documentation\r
+ * and/or other materials provided with the distribution.\r
+ * \r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ * derived from this software without specific prior written permission.\r
+ * \r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY EXPRESS OR\r
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED. IN NO\r
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\r
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;\r
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\r
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR\r
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF\r
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ * \r
+ ******************************************************************************/\r
+\r
+#include "alt_i2c.h"\r
+#include "alt_reset_manager.h"\r
+#include <stdio.h>\r
+\r
+/////\r
+\r
+// NOTE: To enable debugging output, delete the next line and uncomment the\r
+//   line after.\r
+#define dprintf(...)\r
+// #define dprintf(fmt, ...) printf(fmt, ##__VA_ARGS__)\r
+\r
+/////\r
+\r
+#define MIN(a, b) ((a) > (b) ? (b) : (a))\r
+\r
+/////\r
+\r
+// Timeout for reset manager\r
+#define ALT_I2C_RESET_TMO_INIT      8192\r
+// Timeout for disable device\r
+#define ALT_I2C_MAX_T_POLL_COUNT    8192\r
+// Timeout for waiting interrupt\r
+#define ALT_I2C_TMO_WAITER          2500000\r
+\r
+// Min frequency during standard speed\r
+#define ALT_I2C_SS_MIN_SPEED        8000\r
+// Max frequency during standard speed\r
+#define ALT_I2C_SS_MAX_SPEED        100000\r
+// Min frequency during fast speed\r
+#define ALT_I2C_FS_MIN_SPEED        100000\r
+// Max frequency during fast speed\r
+#define ALT_I2C_FS_MAX_SPEED        400000\r
+// Default spike suppression limit during standard speed\r
+#define ALT_I2C_SS_DEFAULT_SPKLEN   11\r
+// Default spike suppression limit during fast speed\r
+#define ALT_I2C_FS_DEFAULT_SPKLEN   4\r
+\r
+// Diff between SCL LCNT and SCL HCNT\r
+#define ALT_I2C_DIFF_LCNT_HCNT      70\r
+\r
+// Reserved address from 0x00 to 0x07\r
+#define ALT_I2C_SLV_RESERVE_ADDR_S_1     0x00\r
+#define ALT_I2C_SLV_RESERVE_ADDR_F_1     0x07\r
+// Reserved address from 0x78 to 0x7F\r
+#define ALT_I2C_SLV_RESERVE_ADDR_S_2     0x78\r
+#define ALT_I2C_SLV_RESERVE_ADDR_F_2     0x7F\r
+\r
+static ALT_STATUS_CODE alt_i2c_is_enabled_helper(ALT_I2C_DEV_t * i2c_dev);\r
+\r
+//\r
+// Check whether i2c space is correct.\r
+//\r
+static ALT_STATUS_CODE alt_i2c_checking(ALT_I2C_DEV_t * i2c_dev)\r
+{\r
+    if (   (i2c_dev->location != (void *)ALT_I2C_I2C0)\r
+        && (i2c_dev->location != (void *)ALT_I2C_I2C1)\r
+        && (i2c_dev->location != (void *)ALT_I2C_I2C2)\r
+        && (i2c_dev->location != (void *)ALT_I2C_I2C3))\r
+    {\r
+        // Incorrect device\r
+        return ALT_E_FALSE;\r
+    }\r
+\r
+    // Reset i2c module\r
+    return ALT_E_TRUE;\r
+}\r
+\r
+static ALT_STATUS_CODE alt_i2c_rstmgr_set(ALT_I2C_DEV_t * i2c_dev)\r
+{\r
+    uint32_t rst_mask = ALT_RSTMGR_PERMODRST_I2C0_SET_MSK;\r
+\r
+    // Assert the appropriate I2C module reset signal via the Reset Manager Peripheral Reset register.\r
+    switch ((ALT_I2C_CTLR_t)i2c_dev->location)\r
+    {\r
+    case ALT_I2C_I2C0:\r
+        rst_mask = ALT_RSTMGR_PERMODRST_I2C0_SET_MSK;\r
+        break;\r
+    case ALT_I2C_I2C1:\r
+        rst_mask = ALT_RSTMGR_PERMODRST_I2C1_SET_MSK;\r
+        break;\r
+    case ALT_I2C_I2C2:\r
+        rst_mask = ALT_RSTMGR_PERMODRST_I2C2_SET_MSK;\r
+        break;\r
+    case ALT_I2C_I2C3:\r
+        rst_mask = ALT_RSTMGR_PERMODRST_I2C3_SET_MSK;\r
+        break;\r
+    default:\r
+        return ALT_E_BAD_ARG;\r
+    }\r
+\r
+    alt_setbits_word(ALT_RSTMGR_PERMODRST_ADDR, rst_mask);\r
+\r
+    return ALT_E_SUCCESS;\r
+}\r
+\r
+//\r
+// Reset i2c module by reset manager\r
+//\r
+static ALT_STATUS_CODE alt_i2c_rstmgr_strobe(ALT_I2C_DEV_t * i2c_dev)\r
+{\r
+    uint32_t rst_mask = ALT_RSTMGR_PERMODRST_I2C0_SET_MSK;\r
+\r
+    // Assert the appropriate I2C module reset signal via the Reset Manager Peripheral Reset register.\r
+    switch ((ALT_I2C_CTLR_t)i2c_dev->location)\r
+    {\r
+    case ALT_I2C_I2C0:\r
+        rst_mask = ALT_RSTMGR_PERMODRST_I2C0_SET_MSK;\r
+        break;\r
+    case ALT_I2C_I2C1:\r
+        rst_mask = ALT_RSTMGR_PERMODRST_I2C1_SET_MSK;\r
+        break;\r
+    case ALT_I2C_I2C2:\r
+        rst_mask = ALT_RSTMGR_PERMODRST_I2C2_SET_MSK;\r
+        break;\r
+    case ALT_I2C_I2C3:\r
+        rst_mask = ALT_RSTMGR_PERMODRST_I2C3_SET_MSK;\r
+        break;\r
+    default:\r
+        return ALT_E_BAD_ARG;\r
+    }\r
+\r
+    alt_setbits_word(ALT_RSTMGR_PERMODRST_ADDR, rst_mask);\r
+\r
+    volatile uint32_t timeout = ALT_I2C_RESET_TMO_INIT;\r
+\r
+    // Wait while i2c modure is reseting\r
+    while (--timeout)\r
+        ;\r
+\r
+    // Deassert the appropriate I2C module reset signal via the Reset Manager Peripheral Reset register.\r
+    alt_clrbits_word(ALT_RSTMGR_PERMODRST_ADDR, rst_mask);\r
+\r
+    return ALT_E_SUCCESS;\r
+}\r
+\r
+//\r
+// Initialize the specified I2C controller instance for use and return a device\r
+// handle referencing it.\r
+//\r
+ALT_STATUS_CODE alt_i2c_init(const ALT_I2C_CTLR_t i2c,\r
+                             ALT_I2C_DEV_t * i2c_dev)\r
+{\r
+    // Save i2c start address to the instance\r
+    i2c_dev->location = (void *)i2c;\r
+    \r
+    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)\r
+    {\r
+        return ALT_E_BAD_ARG;\r
+    }\r
+\r
+    if (alt_clk_is_enabled(ALT_CLK_L4_SP) != ALT_E_TRUE)\r
+    {\r
+        return ALT_E_BAD_CLK;\r
+    }\r
+\r
+    /////\r
+\r
+    ALT_STATUS_CODE status = ALT_E_SUCCESS;\r
+\r
+    if (status == ALT_E_SUCCESS)\r
+    {\r
+        status = alt_clk_freq_get(ALT_CLK_L4_SP, &i2c_dev->clock_freq);\r
+    }\r
+\r
+    // Reset i2c module\r
+    if (status == ALT_E_SUCCESS)\r
+    {\r
+        status = alt_i2c_reset(i2c_dev);\r
+    }\r
+\r
+    return status;\r
+}\r
+\r
+//\r
+// Reset i2c module\r
+//\r
+ALT_STATUS_CODE alt_i2c_reset(ALT_I2C_DEV_t * i2c_dev)\r
+{\r
+    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)\r
+    {\r
+        return ALT_E_BAD_ARG;\r
+    }\r
+\r
+    ALT_STATUS_CODE status = ALT_E_SUCCESS;\r
+\r
+    bool already_enabled = (alt_i2c_is_enabled_helper(i2c_dev) == ALT_E_TRUE);\r
+\r
+    if (already_enabled)\r
+    {\r
+        // Temporarily disable controller\r
+        status = alt_i2c_disable(i2c_dev);\r
+        if (status != ALT_E_SUCCESS)\r
+        {\r
+            return status;\r
+        }\r
+    }\r
+    \r
+    // Reset i2c module by reset manager\r
+    alt_i2c_rstmgr_strobe(i2c_dev);\r
+\r
+    // Set optimal parameters for all i2c devices on the bus\r
+    ALT_I2C_MASTER_CONFIG_t cfg;\r
+    cfg.addr_mode      = ALT_I2C_ADDR_MODE_7_BIT;\r
+    cfg.speed_mode     = ALT_I2C_SPEED_STANDARD;\r
+    cfg.fs_spklen      = ALT_I2C_SS_DEFAULT_SPKLEN;\r
+    cfg.restart_enable = ALT_E_TRUE;\r
+    cfg.ss_scl_lcnt    = cfg.fs_scl_lcnt = 0x2FB;\r
+    cfg.ss_scl_hcnt    = cfg.fs_scl_hcnt = 0x341;\r
+\r
+    alt_i2c_master_config_set(i2c_dev, &cfg);\r
+\r
+    // Active master mode \r
+    alt_i2c_op_mode_set(i2c_dev, ALT_I2C_MODE_MASTER);\r
+\r
+    // Reset the last target address cache.\r
+    i2c_dev->last_target = 0xffffffff;\r
+\r
+    // Clear interrupts mask and clear interrupt status.\r
+    // Interrupts are unmasked by default.\r
+    alt_i2c_int_disable(i2c_dev, ALT_I2C_STATUS_INT_ALL);\r
+    alt_i2c_int_clear(i2c_dev, ALT_I2C_STATUS_INT_ALL);\r
+\r
+    if (already_enabled)\r
+    {\r
+        // Re-enable controller\r
+        status = alt_i2c_enable(i2c_dev);\r
+    }\r
+\r
+    return status;\r
+}\r
+\r
+//\r
+// Uninitialize the I2C controller referenced by the i2c_dev handle.\r
+//\r
+ALT_STATUS_CODE alt_i2c_uninit(ALT_I2C_DEV_t * i2c_dev)\r
+{\r
+    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)\r
+    {\r
+        return ALT_E_BAD_ARG;\r
+    }\r
+\r
+    ALT_STATUS_CODE status = ALT_E_SUCCESS;\r
+\r
+    // Disable i2c controller\r
+    if (status == ALT_E_SUCCESS)\r
+    {\r
+        status = alt_i2c_disable(i2c_dev);\r
+    }\r
+\r
+    // Reset i2c module by reset manager\r
+    if (status == ALT_E_SUCCESS)\r
+    {\r
+        status = alt_i2c_rstmgr_set(i2c_dev);\r
+    }\r
+\r
+    return status;\r
+}\r
+\r
+//\r
+// Enables the I2C controller.\r
+//\r
+ALT_STATUS_CODE alt_i2c_enable(ALT_I2C_DEV_t * i2c_dev)\r
+{\r
+    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)\r
+    {\r
+        return ALT_E_BAD_ARG;\r
+    }\r
+\r
+    // Enable DMA by default.\r
+    alt_write_word(ALT_I2C_DMA_CR_ADDR(i2c_dev->location), \r
+                   ALT_I2C_DMA_CR_TDMAE_SET_MSK | ALT_I2C_DMA_CR_RDMAE_SET_MSK);\r
+\r
+    alt_setbits_word(ALT_I2C_EN_ADDR(i2c_dev->location), ALT_I2C_EN_EN_SET_MSK);\r
+\r
+    return ALT_E_SUCCESS;\r
+}\r
+\r
+//\r
+// Disables the I2C controller\r
+//\r
+ALT_STATUS_CODE alt_i2c_disable(ALT_I2C_DEV_t * i2c_dev)\r
+{\r
+    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)\r
+    {\r
+        return ALT_E_BAD_ARG;\r
+    }\r
+\r
+    // If i2c controller is enabled, return with sucess\r
+    if (alt_i2c_is_enabled_helper(i2c_dev) == ALT_E_FALSE)\r
+    {\r
+        return ALT_E_SUCCESS;\r
+    }\r
+\r
+    // Else clear enable bit of i2c_enable register\r
+    alt_clrbits_word(ALT_I2C_EN_ADDR(i2c_dev->location), ALT_I2C_EN_EN_SET_MSK);\r
+    \r
+    uint32_t timeout = ALT_I2C_MAX_T_POLL_COUNT;\r
+\r
+    // Wait to complete all transfer operations or timeout\r
+    while (alt_i2c_is_enabled_helper(i2c_dev) == ALT_E_TRUE)\r
+    {\r
+        // If controller still are active, return timeout error\r
+        if (--timeout == 0)\r
+        {\r
+            return ALT_E_TMO;\r
+        }\r
+    }\r
+\r
+    // Clear interrupt status\r
+    alt_i2c_int_clear(i2c_dev, ALT_I2C_STATUS_INT_ALL);\r
+\r
+    return ALT_E_SUCCESS;\r
+}\r
+\r
+//\r
+// Check whether i2c controller is enable\r
+//\r
+static ALT_STATUS_CODE alt_i2c_is_enabled_helper(ALT_I2C_DEV_t * i2c_dev)\r
+{\r
+    if (ALT_I2C_EN_STAT_IC_EN_GET(alt_read_word(ALT_I2C_EN_STAT_ADDR(i2c_dev->location))))\r
+    {\r
+        return ALT_E_TRUE;\r
+    }\r
+    else\r
+    {\r
+        return ALT_E_FALSE;\r
+    }\r
+}\r
+\r
+ALT_STATUS_CODE alt_i2c_is_enabled(ALT_I2C_DEV_t * i2c_dev)\r
+{\r
+    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)\r
+    {\r
+        return ALT_E_BAD_ARG;\r
+    }\r
+\r
+    return alt_i2c_is_enabled_helper(i2c_dev);\r
+}\r
+\r
+//\r
+// Get config parameters from appropriate registers for master mode.\r
+//\r
+ALT_STATUS_CODE alt_i2c_master_config_get(ALT_I2C_DEV_t *i2c_dev,\r
+                                          ALT_I2C_MASTER_CONFIG_t* cfg)\r
+{\r
+    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)\r
+    {\r
+        return ALT_E_BAD_ARG;\r
+    }\r
+\r
+    uint32_t cfg_register  = alt_read_word(ALT_I2C_CON_ADDR(i2c_dev->location));\r
+    uint32_t tar_register  = alt_read_word(ALT_I2C_TAR_ADDR(i2c_dev->location));\r
+    uint32_t spkl_register = alt_read_word(ALT_I2C_FS_SPKLEN_ADDR(i2c_dev->location));\r
+\r
+    cfg->speed_mode     = (ALT_I2C_SPEED_t)ALT_I2C_CON_SPEED_GET(cfg_register);\r
+    cfg->fs_spklen      = ALT_I2C_FS_SPKLEN_SPKLEN_GET(spkl_register);\r
+    cfg->restart_enable = ALT_I2C_CON_IC_RESTART_EN_GET(cfg_register);\r
+    cfg->addr_mode      = (ALT_I2C_ADDR_MODE_t)ALT_I2C_TAR_IC_10BITADDR_MST_GET(tar_register);\r
+\r
+    cfg->ss_scl_lcnt = alt_read_word(ALT_I2C_SS_SCL_LCNT_ADDR(i2c_dev->location));\r
+    cfg->ss_scl_hcnt = alt_read_word(ALT_I2C_SS_SCL_HCNT_ADDR(i2c_dev->location));\r
+    cfg->fs_scl_lcnt = alt_read_word(ALT_I2C_FS_SCL_LCNT_ADDR(i2c_dev->location));\r
+    cfg->fs_scl_hcnt = alt_read_word(ALT_I2C_FS_SCL_HCNT_ADDR(i2c_dev->location));\r
+\r
+    return ALT_E_SUCCESS;\r
+}\r
+\r
+//\r
+// Set config parameters to appropriate registers for master mode.\r
+//\r
+ALT_STATUS_CODE alt_i2c_master_config_set(ALT_I2C_DEV_t *i2c_dev,\r
+                                          const ALT_I2C_MASTER_CONFIG_t* cfg)\r
+{\r
+    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)\r
+    {\r
+        return ALT_E_BAD_ARG;\r
+    }\r
+\r
+    if (   (cfg->speed_mode != ALT_I2C_SPEED_STANDARD)\r
+        && (cfg->speed_mode != ALT_I2C_SPEED_FAST))\r
+    {\r
+        return ALT_E_BAD_ARG;\r
+    }\r
+\r
+    if (   (cfg->addr_mode != ALT_I2C_ADDR_MODE_7_BIT)\r
+        && (cfg->addr_mode != ALT_I2C_ADDR_MODE_10_BIT))\r
+    {\r
+        return ALT_E_ARG_RANGE;\r
+    }\r
+\r
+    ALT_STATUS_CODE status = ALT_E_SUCCESS;\r
+\r
+    bool already_enabled = (alt_i2c_is_enabled_helper(i2c_dev) == ALT_E_TRUE);\r
+\r
+    if (already_enabled)\r
+    {\r
+        // Temporarily disable controller\r
+        status = alt_i2c_disable(i2c_dev);\r
+        if (status != ALT_E_SUCCESS)\r
+        {\r
+            return status;\r
+        }\r
+    }\r
+\r
+    // Set config parameters to appropriate registers\r
+\r
+    alt_replbits_word(ALT_I2C_CON_ADDR(i2c_dev->location),\r
+                      ALT_I2C_CON_SPEED_SET_MSK | ALT_I2C_CON_IC_RESTART_EN_SET_MSK,\r
+                      ALT_I2C_CON_SPEED_SET(cfg->speed_mode) | ALT_I2C_CON_IC_RESTART_EN_SET(cfg->restart_enable));\r
+    \r
+    alt_replbits_word(ALT_I2C_TAR_ADDR(i2c_dev->location),\r
+                      ALT_I2C_TAR_IC_10BITADDR_MST_SET_MSK, \r
+                      ALT_I2C_TAR_IC_10BITADDR_MST_SET(cfg->addr_mode));\r
+\r
+    alt_replbits_word(ALT_I2C_FS_SPKLEN_ADDR(i2c_dev->location),\r
+                      ALT_I2C_FS_SPKLEN_SPKLEN_SET_MSK,\r
+                      ALT_I2C_FS_SPKLEN_SPKLEN_SET(cfg->fs_spklen));\r
+    \r
+    alt_replbits_word(ALT_I2C_SS_SCL_LCNT_ADDR(i2c_dev->location),\r
+                      ALT_I2C_SS_SCL_LCNT_IC_SS_SCL_LCNT_SET_MSK,\r
+                      ALT_I2C_SS_SCL_LCNT_IC_SS_SCL_LCNT_SET(cfg->ss_scl_lcnt));\r
+    alt_replbits_word(ALT_I2C_SS_SCL_HCNT_ADDR(i2c_dev->location),\r
+                      ALT_I2C_SS_SCL_HCNT_IC_SS_SCL_HCNT_SET_MSK,\r
+                      ALT_I2C_SS_SCL_HCNT_IC_SS_SCL_HCNT_SET(cfg->ss_scl_hcnt));\r
+    alt_replbits_word(ALT_I2C_FS_SCL_LCNT_ADDR(i2c_dev->location),\r
+                      ALT_I2C_FS_SCL_LCNT_IC_FS_SCL_LCNT_SET_MSK,\r
+                      ALT_I2C_FS_SCL_LCNT_IC_FS_SCL_LCNT_SET(cfg->fs_scl_lcnt));\r
+    alt_replbits_word(ALT_I2C_FS_SCL_HCNT_ADDR(i2c_dev->location),\r
+                      ALT_I2C_FS_SCL_HCNT_IC_FS_SCL_HCNT_SET_MSK,\r
+                      ALT_I2C_FS_SCL_HCNT_IC_FS_SCL_HCNT_SET(cfg->fs_scl_hcnt));\r
+\r
+    if (already_enabled)\r
+    {\r
+        // Re-enable controller\r
+        status = alt_i2c_enable(i2c_dev);\r
+    }\r
+\r
+    return status;\r
+}\r
+\r
+//\r
+// Return bus speed by configuration of i2c controller for master mode.\r
+//\r
+ALT_STATUS_CODE alt_i2c_master_config_speed_get(ALT_I2C_DEV_t *i2c_dev,\r
+                                                const ALT_I2C_MASTER_CONFIG_t * cfg,\r
+                                                uint32_t * speed_in_hz)\r
+{\r
+    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)\r
+    {\r
+        return ALT_E_BAD_ARG;\r
+    }\r
+\r
+    uint32_t scl_lcnt = (cfg->speed_mode == ALT_I2C_SPEED_STANDARD) ? cfg->ss_scl_lcnt : cfg->fs_scl_lcnt;\r
+\r
+    if (scl_lcnt == 0)\r
+    {\r
+        return ALT_E_BAD_ARG;\r
+    }\r
+    \r
+    *speed_in_hz = i2c_dev->clock_freq / (scl_lcnt << 1);\r
+\r
+    return ALT_E_SUCCESS;\r
+}\r
+\r
+//\r
+// Fill struct with configuration of i2c controller for master mode by bus speed\r
+//\r
+ALT_STATUS_CODE alt_i2c_master_config_speed_set(ALT_I2C_DEV_t *i2c_dev,\r
+                                                ALT_I2C_MASTER_CONFIG_t * cfg,\r
+                                                uint32_t speed_in_hz)    \r
+{\r
+    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)\r
+    {\r
+        return ALT_E_BAD_ARG;\r
+    }\r
+\r
+    // If speed is not standard or fast return range error\r
+    if ((speed_in_hz > ALT_I2C_FS_MAX_SPEED) || (speed_in_hz < ALT_I2C_SS_MIN_SPEED))\r
+    {\r
+        return ALT_E_ARG_RANGE;\r
+    }\r
+    \r
+    if (speed_in_hz > ALT_I2C_FS_MIN_SPEED)\r
+    {\r
+        cfg->speed_mode = ALT_I2C_SPEED_FAST;\r
+        cfg->fs_spklen  = ALT_I2C_FS_DEFAULT_SPKLEN;\r
+    }\r
+    else\r
+    {\r
+        cfg->speed_mode = ALT_I2C_SPEED_STANDARD;\r
+        cfg->fs_spklen  = ALT_I2C_SS_DEFAULT_SPKLEN;\r
+    }\r
+\r
+    // <lcount> = <internal clock> / 2 * <speed, Hz>\r
+    uint32_t scl_lcnt = i2c_dev->clock_freq / (speed_in_hz << 1);\r
+\r
+    cfg->ss_scl_lcnt = cfg->fs_scl_lcnt = scl_lcnt;\r
+    // hcount = <lcount> + 70\r
+    cfg->ss_scl_hcnt = cfg->fs_scl_hcnt = scl_lcnt - ALT_I2C_DIFF_LCNT_HCNT;\r
+\r
+    // lcount = <internal clock> / 2 * <speed, Hz>\r
+\r
+    return ALT_E_SUCCESS;\r
+}\r
+\r
+//\r
+// Get config parameters from appropriate registers for slave mode.\r
+//\r
+ALT_STATUS_CODE alt_i2c_slave_config_get(ALT_I2C_DEV_t *i2c_dev,\r
+                                         ALT_I2C_SLAVE_CONFIG_t* cfg)\r
+{\r
+    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)\r
+    {\r
+        return ALT_E_BAD_ARG;\r
+    }\r
+\r
+    uint32_t cfg_register  = alt_read_word(ALT_I2C_CON_ADDR(i2c_dev->location));\r
+    uint32_t sar_register  = alt_read_word(ALT_I2C_SAR_ADDR(i2c_dev->location));\r
+    uint32_t nack_register = alt_read_word(ALT_I2C_SLV_DATA_NACK_ONLY_ADDR(i2c_dev->location));\r
+\r
+    cfg->addr_mode   = (ALT_I2C_ADDR_MODE_t)ALT_I2C_CON_IC_10BITADDR_SLV_GET(cfg_register);\r
+    cfg->addr        = ALT_I2C_SAR_IC_SAR_GET(sar_register);\r
+    cfg->nack_enable = ALT_I2C_SLV_DATA_NACK_ONLY_NACK_GET(nack_register);\r
+\r
+    return ALT_E_SUCCESS;\r
+}\r
+\r
+//\r
+// Set config parameters to appropriate registers for slave mode.\r
+//\r
+ALT_STATUS_CODE alt_i2c_slave_config_set(ALT_I2C_DEV_t *i2c_dev,\r
+                                         const ALT_I2C_SLAVE_CONFIG_t* cfg)\r
+{\r
+    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)\r
+    {\r
+        return ALT_E_BAD_ARG;\r
+    }\r
+\r
+    if (   (cfg->addr_mode != ALT_I2C_ADDR_MODE_7_BIT)\r
+        && (cfg->addr_mode != ALT_I2C_ADDR_MODE_10_BIT))\r
+    {\r
+        return ALT_E_BAD_ARG;\r
+    }\r
+\r
+    if (   (cfg->addr > ALT_I2C_SAR_IC_SAR_SET_MSK)\r
+        || (cfg->addr < ALT_I2C_SLV_RESERVE_ADDR_F_1)\r
+        || ((cfg->addr > ALT_I2C_SLV_RESERVE_ADDR_S_2) && (cfg->addr < ALT_I2C_SLV_RESERVE_ADDR_F_2))\r
+       )\r
+    {\r
+        return ALT_E_ARG_RANGE;\r
+    }\r
+\r
+    ALT_STATUS_CODE status = ALT_E_SUCCESS;\r
+\r
+    bool already_enabled = (alt_i2c_is_enabled_helper(i2c_dev) == ALT_E_TRUE);\r
+\r
+    if (already_enabled)\r
+    {\r
+        // Temporarily disable controller\r
+        status = alt_i2c_disable(i2c_dev);\r
+        if (status != ALT_E_SUCCESS)\r
+        {\r
+            return status;\r
+        }\r
+    }\r
+\r
+    alt_replbits_word(ALT_I2C_CON_ADDR(i2c_dev->location),\r
+                      ALT_I2C_CON_IC_10BITADDR_SLV_SET_MSK,\r
+                      ALT_I2C_CON_IC_10BITADDR_SLV_SET(cfg->addr_mode));\r
+\r
+    alt_replbits_word(ALT_I2C_SAR_ADDR(i2c_dev->location),\r
+                      ALT_I2C_SAR_IC_SAR_SET_MSK,\r
+                      ALT_I2C_SAR_IC_SAR_SET(cfg->addr));\r
+    alt_replbits_word(ALT_I2C_SLV_DATA_NACK_ONLY_ADDR(i2c_dev->location),\r
+                      ALT_I2C_SLV_DATA_NACK_ONLY_NACK_SET_MSK,\r
+                      ALT_I2C_SLV_DATA_NACK_ONLY_NACK_SET(cfg->nack_enable));\r
+\r
+    if (already_enabled)\r
+    {\r
+        // Re-enable controller\r
+        status = alt_i2c_enable(i2c_dev);\r
+    }\r
+\r
+    return status;\r
+}\r
+\r
+//\r
+// Get hold time (use during slave mode)\r
+//\r
+ALT_STATUS_CODE alt_i2c_sda_hold_time_get(ALT_I2C_DEV_t *i2c_dev, \r
+                                          uint16_t *hold_time)\r
+{\r
+    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)\r
+    {\r
+        return ALT_E_BAD_ARG;\r
+    }\r
+\r
+    uint32_t sda_register = alt_read_word(ALT_I2C_SDA_HOLD_ADDR(i2c_dev->location));\r
+    *hold_time = ALT_I2C_SDA_HOLD_IC_SDA_HOLD_GET(sda_register);\r
+\r
+    return ALT_E_SUCCESS;\r
+}\r
+    \r
+//\r
+// Set hold time (use during slave mode)\r
+//\r
+ALT_STATUS_CODE alt_i2c_sda_hold_time_set(ALT_I2C_DEV_t *i2c_dev, \r
+                                          const uint16_t hold_time)\r
+{\r
+    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)\r
+    {\r
+        return ALT_E_BAD_ARG;\r
+    }\r
+\r
+    ALT_STATUS_CODE status = ALT_E_SUCCESS;\r
+\r
+    bool already_enabled = (alt_i2c_is_enabled_helper(i2c_dev) == ALT_E_TRUE);\r
+\r
+    if (already_enabled)\r
+    {\r
+        // Temporarily disable controller\r
+        status = alt_i2c_disable(i2c_dev);\r
+        if (status != ALT_E_SUCCESS)\r
+        {\r
+            return status;\r
+        }\r
+    }\r
+\r
+    alt_replbits_word(ALT_I2C_SDA_HOLD_ADDR(i2c_dev->location),\r
+                      ALT_I2C_SDA_HOLD_IC_SDA_HOLD_SET_MSK,\r
+                      ALT_I2C_SDA_HOLD_IC_SDA_HOLD_SET(hold_time));\r
+\r
+    if (already_enabled)\r
+    {\r
+        // Re-enable controller\r
+        status = alt_i2c_enable(i2c_dev);\r
+    }\r
+\r
+    return status;\r
+}\r
+    \r
+//\r
+// Gets the current operational mode of the I2C controller.\r
+//\r
+ALT_STATUS_CODE alt_i2c_op_mode_get(ALT_I2C_DEV_t *i2c_dev,\r
+                                    ALT_I2C_MODE_t* mode)\r
+{\r
+    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)\r
+    {\r
+        return ALT_E_BAD_ARG;\r
+    }\r
+    \r
+    uint32_t cfg_register = alt_read_word(ALT_I2C_CON_ADDR(i2c_dev->location));\r
+    uint32_t mst_mod_stat = ALT_I2C_CON_MST_MOD_GET(cfg_register);\r
+    uint32_t slv_mod_stat = ALT_I2C_CON_IC_SLV_DIS_GET(cfg_register);\r
+\r
+    // Return error if master and slave modes enable or disable at the same time\r
+    if (   (mst_mod_stat == ALT_I2C_CON_MST_MOD_E_EN  && slv_mod_stat == ALT_I2C_CON_IC_SLV_DIS_E_EN) \r
+        || (mst_mod_stat == ALT_I2C_CON_MST_MOD_E_DIS && slv_mod_stat == ALT_I2C_CON_IC_SLV_DIS_E_DIS))\r
+    {\r
+        return ALT_E_ERROR;\r
+    }\r
+\r
+    *mode = (ALT_I2C_MODE_t)mst_mod_stat;\r
+\r
+    return ALT_E_SUCCESS;\r
+}\r
+    \r
+//\r
+// Sets the operational mode of the I2C controller.\r
+//\r
+ALT_STATUS_CODE alt_i2c_op_mode_set(ALT_I2C_DEV_t *i2c_dev,\r
+                                    const ALT_I2C_MODE_t mode)    \r
+{\r
+    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)\r
+    {\r
+        return ALT_E_BAD_ARG;\r
+    }\r
+\r
+    if (   (mode != ALT_I2C_MODE_MASTER)\r
+        && (mode != ALT_I2C_MODE_SLAVE))\r
+    {\r
+        return ALT_E_ARG_RANGE;\r
+    }\r
+    \r
+    ALT_STATUS_CODE status = ALT_E_SUCCESS;\r
+\r
+    bool already_enabled = (alt_i2c_is_enabled_helper(i2c_dev) == ALT_E_TRUE);\r
+\r
+    if (already_enabled)\r
+    {\r
+        // Temporarily disable controller\r
+        status = alt_i2c_disable(i2c_dev);\r
+        if (status != ALT_E_SUCCESS)\r
+        {\r
+            return status;\r
+        }\r
+    }\r
+\r
+    if (mode == ALT_I2C_MODE_MASTER)\r
+    {\r
+        // Enable master, disable slave\r
+        alt_replbits_word(ALT_I2C_CON_ADDR(i2c_dev->location),\r
+                          ALT_I2C_CON_IC_SLV_DIS_SET_MSK | ALT_I2C_CON_MST_MOD_SET_MSK,\r
+                          ALT_I2C_CON_IC_SLV_DIS_SET(ALT_I2C_CON_IC_SLV_DIS_E_DIS) | ALT_I2C_CON_MST_MOD_SET(ALT_I2C_CON_MST_MOD_E_EN));\r
+    }\r
+    else if (mode == ALT_I2C_MODE_SLAVE)\r
+    {\r
+        // Enable slave, disable master\r
+        alt_replbits_word(ALT_I2C_CON_ADDR(i2c_dev->location),\r
+                          ALT_I2C_CON_IC_SLV_DIS_SET_MSK | ALT_I2C_CON_MST_MOD_SET_MSK,\r
+                          ALT_I2C_CON_IC_SLV_DIS_SET(ALT_I2C_CON_IC_SLV_DIS_E_EN) | ALT_I2C_CON_MST_MOD_SET(ALT_I2C_CON_MST_MOD_E_DIS));\r
+    }\r
+        \r
+    if (already_enabled)\r
+    {\r
+        // Re-enable controller\r
+        status = alt_i2c_enable(i2c_dev);\r
+    }\r
+    \r
+    return status;\r
+}\r
+    \r
+//\r
+// Returns ALT_E_TRUE if the I2C controller is busy\r
+//\r
+ALT_STATUS_CODE alt_i2c_is_busy(ALT_I2C_DEV_t *i2c_dev)\r
+{\r
+    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)\r
+    {\r
+        return ALT_E_BAD_ARG;\r
+    }\r
+    \r
+    if ( ALT_I2C_STAT_ACTIVITY_GET(alt_read_word(ALT_I2C_STAT_ADDR(i2c_dev->location))))\r
+    {\r
+        return ALT_E_TRUE;\r
+    }\r
+    else\r
+    {\r
+        return ALT_E_FALSE;\r
+    }\r
+}\r
+\r
+//\r
+// This function reads a single data byte from the receive FIFO.\r
+//\r
+ALT_STATUS_CODE alt_i2c_read(ALT_I2C_DEV_t *i2c_dev, uint8_t *value)\r
+{\r
+    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)\r
+    {\r
+        return ALT_E_BAD_ARG;\r
+    }\r
+\r
+    if (alt_i2c_is_enabled_helper(i2c_dev) == ALT_E_FALSE)\r
+    {\r
+        return ALT_E_ERROR;\r
+    }\r
+\r
+    *value = (uint8_t)(ALT_I2C_DATA_CMD_DAT_GET(alt_read_word(ALT_I2C_DATA_CMD_ADDR(i2c_dev->location))));\r
+\r
+    return ALT_E_SUCCESS;\r
+}\r
+\r
+//\r
+// This function writes a single data byte to the transmit FIFO.\r
+//\r
+ALT_STATUS_CODE alt_i2c_write(ALT_I2C_DEV_t *i2c_dev, const uint8_t value)\r
+{\r
+    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)\r
+    {\r
+        return ALT_E_BAD_ARG;\r
+    }\r
+\r
+    if (alt_i2c_is_enabled_helper(i2c_dev) == ALT_E_FALSE)\r
+    {\r
+        return ALT_E_ERROR;\r
+    }\r
+\r
+    alt_write_word(ALT_I2C_DATA_CMD_ADDR(i2c_dev->location),\r
+                   ALT_I2C_DATA_CMD_DAT_SET(value));\r
+\r
+    return ALT_E_SUCCESS;\r
+}\r
+\r
+//\r
+// This function acts in the role of a slave-receiver by receiving a single data\r
+// byte from the I2C bus in response to a write command from the master.\r
+//\r
+ALT_STATUS_CODE alt_i2c_slave_receive(ALT_I2C_DEV_t * i2c_dev,\r
+                                      uint8_t * data)\r
+{\r
+    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)\r
+    {\r
+        return ALT_E_BAD_ARG;\r
+    }\r
+\r
+    if (alt_i2c_is_enabled_helper(i2c_dev) == ALT_E_FALSE)\r
+    {\r
+        return ALT_E_ERROR;\r
+    }\r
+\r
+    // alt_i2c_read().\r
+    *data = (uint8_t)(ALT_I2C_DATA_CMD_DAT_GET(alt_read_word(ALT_I2C_DATA_CMD_ADDR(i2c_dev->location))));\r
+\r
+    return ALT_E_SUCCESS;\r
+}\r
+\r
+//\r
+// This function acts in the role of a slave-transmitter by transmitting a single\r
+// data byte to the I2C bus in response to a read request from the master.\r
+//\r
+ALT_STATUS_CODE alt_i2c_slave_transmit(ALT_I2C_DEV_t *i2c_dev,\r
+                                       const uint8_t data)\r
+{\r
+    // Send bulk of data with one value\r
+    return alt_i2c_slave_bulk_transmit(i2c_dev, &data, 1);\r
+}\r
+\r
+//\r
+// This function acts in the role of a slave-transmitter by transmitting data in\r
+// bulk to the I2C bus in response to a series of read requests from a master.\r
+//\r
+ALT_STATUS_CODE alt_i2c_slave_bulk_transmit(ALT_I2C_DEV_t *i2c_dev,\r
+                                            const void * data,\r
+                                            const size_t size)\r
+{\r
+    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)\r
+    {\r
+        return ALT_E_BAD_ARG;\r
+    }\r
+\r
+    if (alt_i2c_is_enabled_helper(i2c_dev) == ALT_E_FALSE)\r
+    {\r
+        return ALT_E_ERROR;\r
+    }\r
+\r
+    const char * buffer = data;\r
+    for (size_t i = 0; i < size; ++i)\r
+    {\r
+        alt_write_word(ALT_I2C_DATA_CMD_ADDR(i2c_dev->location),\r
+                         ALT_I2C_DATA_CMD_DAT_SET(*buffer)\r
+                       | ALT_I2C_DATA_CMD_STOP_SET(false)\r
+                       | ALT_I2C_DATA_CMD_RESTART_SET(false));\r
+\r
+        ++buffer;\r
+    }\r
+\r
+    return ALT_E_SUCCESS;\r
+}\r
+\r
+ALT_STATUS_CODE alt_i2c_master_target_get(ALT_I2C_DEV_t * i2c_dev, uint32_t * target_addr)\r
+{\r
+    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)\r
+    {\r
+        return ALT_E_BAD_ARG;\r
+    }\r
+\r
+    *target_addr = i2c_dev->last_target;\r
+\r
+    return ALT_E_SUCCESS;\r
+}\r
+\r
+ALT_STATUS_CODE alt_i2c_master_target_set(ALT_I2C_DEV_t * i2c_dev, uint32_t target_addr)\r
+{\r
+    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)\r
+    {\r
+        return ALT_E_BAD_ARG;\r
+    }\r
+\r
+    ALT_STATUS_CODE status = ALT_E_SUCCESS;\r
+\r
+    // Wait until the TX FIFO flushes. This is needed because TAR can only be\r
+    // updated under specific conditions.\r
+\r
+    if (target_addr != i2c_dev->last_target)\r
+    {\r
+        uint32_t timeout = 10000;\r
+\r
+        while (alt_i2c_tx_fifo_is_empty(i2c_dev) == ALT_E_FALSE)\r
+        {\r
+            if (--timeout == 0)\r
+            {\r
+                status = ALT_E_TMO;\r
+                break;\r
+            }\r
+        }\r
+\r
+        // Update target address\r
+        if (status == ALT_E_SUCCESS)\r
+        {\r
+            alt_replbits_word(ALT_I2C_TAR_ADDR(i2c_dev->location),\r
+                              ALT_I2C_TAR_IC_TAR_SET_MSK,\r
+                              ALT_I2C_TAR_IC_TAR_SET(target_addr));\r
+\r
+            i2c_dev->last_target = target_addr;\r
+        }\r
+    }\r
+\r
+    return status;\r
+}\r
+\r
+//\r
+// Write bulk of data or read requests to tx fifo\r
+//\r
+static ALT_STATUS_CODE alt_i2c_master_transmit_helper(ALT_I2C_DEV_t * i2c_dev,\r
+                                                      const uint8_t * buffer,\r
+                                                      size_t size,\r
+                                                      bool issue_restart,\r
+                                                      bool issue_stop)\r
+{\r
+    ALT_STATUS_CODE status = ALT_E_SUCCESS;\r
+\r
+    // If the rested size is 1, the restart and stop may need to be sent in the\r
+    // same frame.\r
+    if (size == 1)\r
+    {\r
+        if (status == ALT_E_SUCCESS)\r
+        {\r
+            status = alt_i2c_issue_write(i2c_dev,\r
+                                         *buffer,\r
+                                         issue_restart,\r
+                                         issue_stop);\r
+\r
+            ++buffer;\r
+            --size;\r
+        }\r
+    }\r
+    else\r
+    {\r
+        // First byte\r
+\r
+        if (status == ALT_E_SUCCESS)\r
+        {\r
+            status = alt_i2c_issue_write(i2c_dev,\r
+                                         *buffer,\r
+                                         issue_restart,\r
+                                         false);\r
+\r
+            ++buffer;\r
+            --size;\r
+        }\r
+\r
+        /////\r
+            \r
+        // Middle byte(s)\r
+\r
+        if (status == ALT_E_SUCCESS)\r
+        {\r
+            uint32_t timeout = size * 10000;\r
+\r
+            while (size > 1)\r
+            {\r
+                uint32_t level = 0;\r
+                status = alt_i2c_tx_fifo_level_get(i2c_dev, &level);\r
+                if (status != ALT_E_SUCCESS)\r
+                {\r
+                    break;\r
+                }\r
+\r
+                uint32_t space = ALT_I2C_TX_FIFO_NUM_ENTRIES - level;\r
+                if (space == 0)\r
+                {\r
+                    if (--timeout == 0)\r
+                    {\r
+                        status = ALT_E_TMO;\r
+                        break;\r
+                    }\r
+\r
+                    continue;\r
+                }\r
+                \r
+                // Subtract 1 because the last byte may need to issue_stop\r
+                space = MIN(space, size - 1);\r
+\r
+                for (uint32_t i = 0; i < space; ++i)\r
+                {\r
+                    alt_write_word(ALT_I2C_DATA_CMD_ADDR(i2c_dev->location),\r
+                                     ALT_I2C_DATA_CMD_DAT_SET(*buffer)\r
+                                   | ALT_I2C_DATA_CMD_STOP_SET(false)\r
+                                   | ALT_I2C_DATA_CMD_RESTART_SET(false));\r
+\r
+                    ++buffer;\r
+                }\r
+\r
+                size -= space;\r
+            }\r
+        }\r
+\r
+        /////\r
+\r
+        // Last byte\r
+\r
+        if (status == ALT_E_SUCCESS)\r
+        {\r
+            status = alt_i2c_issue_write(i2c_dev,\r
+                                         *buffer,\r
+                                         false,\r
+                                         issue_stop);\r
+\r
+            ++buffer;\r
+            --size;\r
+        }\r
+    }\r
+\r
+    return status;\r
+}\r
+\r
+//\r
+// This function acts in the role of a master-transmitter by issuing a write\r
+// command and transmitting data to the I2C bus.\r
+//\r
+ALT_STATUS_CODE alt_i2c_master_transmit(ALT_I2C_DEV_t *i2c_dev,\r
+                                        const void * data,\r
+                                        const size_t size,\r
+                                        const bool issue_restart,\r
+                                        const bool issue_stop)\r
+{\r
+    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)\r
+    {\r
+        return ALT_E_BAD_ARG;\r
+    }\r
+\r
+    if (alt_i2c_is_enabled_helper(i2c_dev) == ALT_E_FALSE)\r
+    {\r
+        return ALT_E_ERROR;\r
+    }\r
+\r
+    if (size == 0)\r
+    {\r
+        return ALT_E_SUCCESS;\r
+    }\r
+    \r
+    ALT_STATUS_CODE status = ALT_E_SUCCESS;\r
+\r
+    if (status == ALT_E_SUCCESS)\r
+    {\r
+        status = alt_i2c_master_transmit_helper(i2c_dev,\r
+                                                data,\r
+                                                size,\r
+                                                issue_restart,\r
+                                                issue_stop);\r
+    }\r
+\r
+    // Need reset for set i2c bus in idle state\r
+    if (status == ALT_E_TMO)\r
+    {\r
+        alt_i2c_reset(i2c_dev);\r
+    }\r
+\r
+    return status;\r
+}\r
+\r
+ALT_STATUS_CODE alt_i2c_master_receive_helper(ALT_I2C_DEV_t *i2c_dev,\r
+                                              uint8_t * buffer,\r
+                                              size_t size,\r
+                                              bool issue_restart,\r
+                                              bool issue_stop)\r
+{\r
+    ALT_STATUS_CODE status = ALT_E_SUCCESS;\r
+\r
+    uint32_t issue_left = size;\r
+    uint32_t data_left  = size;\r
+\r
+    uint32_t timeout = size * 10000;\r
+\r
+    // Wait for space in the TX FIFO to send the first read request.\r
+    // This is needed because the issue restart need to be set.\r
+\r
+    if (issue_restart == true)\r
+    {\r
+        if (status == ALT_E_SUCCESS)\r
+        {\r
+            while (alt_i2c_tx_fifo_is_full(i2c_dev) == ALT_E_TRUE)\r
+            {\r
+                if (--timeout == 0)\r
+                {\r
+                    status = ALT_E_TMO;\r
+                    break;\r
+                }\r
+            }\r
+        }\r
+\r
+        // Now send the first request.\r
+\r
+        if (status == ALT_E_SUCCESS)\r
+        {\r
+            alt_write_word(ALT_I2C_DATA_CMD_ADDR(i2c_dev->location),\r
+                             ALT_I2C_DATA_CMD_CMD_SET(ALT_I2C_DATA_CMD_CMD_E_RD)\r
+                           | ALT_I2C_DATA_CMD_STOP_SET(false)\r
+                           | ALT_I2C_DATA_CMD_RESTART_SET(issue_restart));\r
+\r
+            --issue_left;\r
+        }\r
+    }\r
+\r
+    // For the rest of the data ...\r
+\r
+    while (data_left > 0)\r
+    {\r
+        if (status != ALT_E_SUCCESS)\r
+        {\r
+            break;\r
+        }\r
+\r
+        // Top up the TX FIFO with read issues\r
+        // Special consideration must be made for the last read issue, as it may be necessary to "issue_stop".\r
+\r
+        if (issue_left > 0)\r
+        {\r
+            uint32_t level = 0;\r
+            status = alt_i2c_tx_fifo_level_get(i2c_dev, &level);\r
+            if (status != ALT_E_SUCCESS)\r
+            {\r
+                break;\r
+            }\r
+\r
+            uint32_t space = ALT_I2C_TX_FIFO_NUM_ENTRIES - level;\r
+\r
+            if (issue_left == 1)\r
+            {\r
+                if (space > 0)\r
+                {\r
+                    space = 1;\r
+\r
+                    alt_write_word(ALT_I2C_DATA_CMD_ADDR(i2c_dev->location),\r
+                                   ALT_I2C_DATA_CMD_CMD_SET(ALT_I2C_DATA_CMD_CMD_E_RD)\r
+                                   | ALT_I2C_DATA_CMD_STOP_SET(issue_stop)\r
+                                   | ALT_I2C_DATA_CMD_RESTART_SET(false));\r
+                }\r
+            }\r
+            else\r
+            {\r
+                // Send up to issue_left - 1, as the last issue has special considerations.\r
+                space = MIN(issue_left - 1, space);\r
+\r
+                for (uint32_t i = 0; i < space; ++i)\r
+                {\r
+                    alt_write_word(ALT_I2C_DATA_CMD_ADDR(i2c_dev->location),\r
+                                   ALT_I2C_DATA_CMD_CMD_SET(ALT_I2C_DATA_CMD_CMD_E_RD)\r
+                                   | ALT_I2C_DATA_CMD_STOP_SET(false)\r
+                                   | ALT_I2C_DATA_CMD_RESTART_SET(false));\r
+                }\r
+            }\r
+\r
+            issue_left -= space;\r
+        }\r
+\r
+        // Read out the resulting received data as they come in.\r
+\r
+        if (data_left > 0)\r
+        {\r
+            uint32_t level = 0;\r
+            status = alt_i2c_rx_fifo_level_get(i2c_dev, &level);\r
+            if (status != ALT_E_SUCCESS)\r
+            {\r
+                break;\r
+            }\r
+\r
+            if (level == 0)\r
+            {\r
+                if (--timeout == 0)\r
+                {\r
+                    status = ALT_E_TMO;\r
+                    break;\r
+                }\r
+            }\r
+\r
+            level = MIN(data_left, level);\r
+\r
+            for (uint32_t i = 0; i < level; ++i)\r
+            {\r
+                // alt_i2c_read(i2c_dev, &value);\r
+                *buffer = (uint8_t)(ALT_I2C_DATA_CMD_DAT_GET(alt_read_word(ALT_I2C_DATA_CMD_ADDR(i2c_dev->location))));\r
+                ++buffer;\r
+            }\r
+\r
+            data_left -= level;\r
+        }\r
+    }\r
+\r
+\r
+    return status;\r
+}\r
+\r
+//\r
+// This function acts in the role of a master-receiver by receiving one or more\r
+// data bytes transmitted from a slave in response to read requests issued from\r
+// this master.\r
+//\r
+ALT_STATUS_CODE alt_i2c_master_receive(ALT_I2C_DEV_t *i2c_dev, \r
+                                       void * data,\r
+                                       const size_t size,\r
+                                       const bool issue_restart,\r
+                                       const bool issue_stop)\r
+{\r
+    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)\r
+    {\r
+        return ALT_E_BAD_ARG;\r
+    }\r
+\r
+    if (alt_i2c_is_enabled_helper(i2c_dev) == ALT_E_FALSE)\r
+    {\r
+        return ALT_E_ERROR;\r
+    }\r
+\r
+    if (size == 0)\r
+    {\r
+        return ALT_E_SUCCESS;\r
+    }\r
+\r
+    ALT_STATUS_CODE status = ALT_E_SUCCESS;\r
+\r
+    // This I2C controller requires that a read issue be performed for each byte requested.\r
+    // Read issue takes space in the TX FIFO, which may asynchronously handling a previous request.\r
+\r
+    if (size == 1)\r
+    {\r
+        uint32_t timeout = 10000;\r
+\r
+        // Wait for space in the TX FIFO to send the read request.\r
+\r
+        if (status == ALT_E_SUCCESS)\r
+        {\r
+            while (alt_i2c_tx_fifo_is_full(i2c_dev) == ALT_E_TRUE)\r
+            {\r
+                if (--timeout == 0)\r
+                {\r
+                    status = ALT_E_TMO;\r
+                    break;\r
+                }\r
+            }\r
+        }\r
+\r
+        // Issue the read request in the TX FIFO.\r
+\r
+        if (status == ALT_E_SUCCESS)\r
+        {\r
+            alt_write_word(ALT_I2C_DATA_CMD_ADDR(i2c_dev->location),\r
+                             ALT_I2C_DATA_CMD_CMD_SET(ALT_I2C_DATA_CMD_CMD_E_RD)\r
+                           | ALT_I2C_DATA_CMD_STOP_SET(issue_stop)\r
+                           | ALT_I2C_DATA_CMD_RESTART_SET(issue_restart));\r
+\r
+        }\r
+\r
+        // Wait for data to become available in the RX FIFO.\r
+\r
+        if (status == ALT_E_SUCCESS)\r
+        {\r
+            while (alt_i2c_rx_fifo_is_empty(i2c_dev) == ALT_E_TRUE)\r
+            {\r
+                if (--timeout == 0)\r
+                {\r
+                    status = ALT_E_TMO;\r
+                    break;\r
+                }\r
+            }\r
+        }\r
+\r
+        // Read the RX FIFO.\r
+\r
+        if (status == ALT_E_SUCCESS)\r
+        {\r
+            uint8_t * buffer = data;\r
+            *buffer = (uint8_t)(ALT_I2C_DATA_CMD_DAT_GET(alt_read_word(ALT_I2C_DATA_CMD_ADDR(i2c_dev->location))));\r
+        }\r
+    }\r
+    else if (size <= 64)\r
+    {\r
+        if (status == ALT_E_SUCCESS)\r
+        {\r
+            status = alt_i2c_master_receive_helper(i2c_dev,\r
+                                                   data,\r
+                                                   size,\r
+                                                   issue_restart,\r
+                                                   issue_stop);\r
+        }\r
+    }\r
+    else\r
+    {\r
+        uint8_t * buffer = data;\r
+        size_t size_left = size;\r
+\r
+        // Send the first ALT_I2C_RX_FIFO_NUM_ENTRIES items\r
+\r
+        if (status == ALT_E_SUCCESS)\r
+        {\r
+            status = alt_i2c_master_receive_helper(i2c_dev,\r
+                                                   buffer,\r
+                                                   ALT_I2C_RX_FIFO_NUM_ENTRIES,\r
+                                                   issue_restart,\r
+                                                   false);\r
+        }\r
+\r
+        buffer    += ALT_I2C_RX_FIFO_NUM_ENTRIES;\r
+        size_left -= ALT_I2C_RX_FIFO_NUM_ENTRIES;\r
+\r
+        while (size_left > 0)\r
+        {\r
+            if (size_left > ALT_I2C_RX_FIFO_NUM_ENTRIES)\r
+            {\r
+                if (status == ALT_E_SUCCESS)\r
+                {\r
+                    status = alt_i2c_master_receive_helper(i2c_dev,\r
+                                                           buffer,\r
+                                                           ALT_I2C_RX_FIFO_NUM_ENTRIES,\r
+                                                           false,\r
+                                                           false);\r
+                }\r
+\r
+                buffer    += ALT_I2C_RX_FIFO_NUM_ENTRIES;\r
+                size_left -= ALT_I2C_RX_FIFO_NUM_ENTRIES;\r
+            }\r
+            else\r
+            {\r
+                if (status == ALT_E_SUCCESS)\r
+                {\r
+                    status = alt_i2c_master_receive_helper(i2c_dev,\r
+                                                           buffer,\r
+                                                           size_left,\r
+                                                           false,\r
+                                                           issue_stop);\r
+                }\r
+\r
+                size_left = 0;\r
+            }\r
+\r
+            if (status != ALT_E_SUCCESS)\r
+            {\r
+                break;\r
+            }\r
+        }\r
+    }\r
+\r
+    // Need reset for set i2c bus in idle state\r
+    if (status == ALT_E_TMO)\r
+    {\r
+        alt_i2c_reset(i2c_dev);\r
+    }\r
+\r
+    return status;\r
+}\r
+\r
+//\r
+// This function causes the I2C controller master to send data to the bus.\r
+//\r
+ALT_STATUS_CODE alt_i2c_issue_write(ALT_I2C_DEV_t *i2c_dev,\r
+                                    const uint8_t value,\r
+                                    const bool issue_restart,\r
+                                    const bool issue_stop)\r
+{\r
+    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)\r
+    {\r
+        return ALT_E_BAD_ARG;\r
+    }\r
+\r
+    if (alt_i2c_is_enabled_helper(i2c_dev) == ALT_E_FALSE)\r
+    {\r
+        return ALT_E_ERROR;\r
+    }\r
+\r
+    // Wait until there is a FIFO spot\r
+    uint32_t timeout = 10000;\r
+\r
+    while (alt_i2c_tx_fifo_is_full(i2c_dev) == ALT_E_TRUE)\r
+    {\r
+        if (--timeout == 0)\r
+        {\r
+            return ALT_E_TMO;\r
+        }\r
+    }\r
+\r
+    alt_write_word(ALT_I2C_DATA_CMD_ADDR(i2c_dev->location),\r
+                     ALT_I2C_DATA_CMD_DAT_SET(value)\r
+                   | ALT_I2C_DATA_CMD_STOP_SET(issue_stop)\r
+                   | ALT_I2C_DATA_CMD_RESTART_SET(issue_restart));\r
+\r
+    return ALT_E_SUCCESS;\r
+}\r
+\r
+//\r
+// This function causes the I2C controller master to issue a READ request on the bus.\r
+//\r
+ALT_STATUS_CODE alt_i2c_issue_read(ALT_I2C_DEV_t *i2c_dev,\r
+                                   const bool issue_restart,\r
+                                   const bool issue_stop)\r
+{\r
+    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)\r
+    {\r
+        return ALT_E_BAD_ARG;\r
+    }\r
+\r
+    if (alt_i2c_is_enabled_helper(i2c_dev) == ALT_E_FALSE)\r
+    {\r
+        return ALT_E_ERROR;\r
+    }\r
+\r
+    // Wait until there is a FIFO spot\r
+    uint32_t timeout = 10000;\r
+\r
+    while (alt_i2c_tx_fifo_is_full(i2c_dev) == ALT_E_TRUE)\r
+    {\r
+        if (--timeout == 0)\r
+        {\r
+            return ALT_E_TMO;\r
+        }\r
+    }\r
+\r
+    alt_write_word(ALT_I2C_DATA_CMD_ADDR(i2c_dev->location),\r
+                     ALT_I2C_DATA_CMD_CMD_SET(ALT_I2C_DATA_CMD_CMD_E_RD)\r
+                   | ALT_I2C_DATA_CMD_STOP_SET(issue_stop)\r
+                   | ALT_I2C_DATA_CMD_RESTART_SET(issue_restart));\r
+\r
+    return ALT_E_SUCCESS;\r
+}\r
+\r
+//\r
+// This function acts in the role of a master-transmitter by issuing a general\r
+// call command to all devices connected to the I2C bus.\r
+//\r
+ALT_STATUS_CODE alt_i2c_master_general_call(ALT_I2C_DEV_t *i2c_dev,\r
+                                            const void * data,\r
+                                            const size_t size,\r
+                                            const bool issue_restart,\r
+                                            const bool issue_stop)\r
+{\r
+    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)\r
+    {\r
+        return ALT_E_BAD_ARG;\r
+    }\r
+\r
+    if (alt_i2c_is_enabled_helper(i2c_dev) == ALT_E_FALSE)\r
+    {\r
+        return ALT_E_ERROR;\r
+    }\r
+\r
+    ALT_STATUS_CODE status = ALT_E_SUCCESS;\r
+\r
+    if (status == ALT_E_SUCCESS)\r
+    {\r
+        status = alt_i2c_master_target_set(i2c_dev, 0);\r
+    }\r
+\r
+    // General call is a transmit in master mode (target address are not used during it)\r
+    if (status == ALT_E_SUCCESS)\r
+    {\r
+        status = alt_i2c_master_transmit(i2c_dev, data, size, issue_restart, issue_stop);\r
+    }\r
+\r
+    return status;\r
+}\r
+\r
+/////\r
+\r
+ALT_STATUS_CODE alt_i2c_general_call_ack_disable(ALT_I2C_DEV_t *i2c_dev)\r
+{\r
+    ALT_STATUS_CODE status = ALT_E_SUCCESS;\r
+\r
+    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)\r
+    {\r
+        return ALT_E_BAD_ARG;\r
+    }\r
+\r
+    bool already_enabled = (alt_i2c_is_enabled_helper(i2c_dev) == ALT_E_TRUE);\r
+\r
+    if (already_enabled)\r
+    {\r
+        // Temporarily disable controller\r
+        status = alt_i2c_disable(i2c_dev);\r
+        if (status != ALT_E_SUCCESS)\r
+        {\r
+            return status;\r
+        }\r
+    }\r
+\r
+    alt_replbits_word(ALT_I2C_TAR_ADDR(i2c_dev->location),\r
+                      ALT_I2C_TAR_SPECIAL_SET_MSK | ALT_I2C_TAR_GC_OR_START_SET_MSK,\r
+                      ALT_I2C_TAR_SPECIAL_SET(ALT_I2C_TAR_SPECIAL_E_STARTBYTE) | ALT_I2C_TAR_GC_OR_START_SET(ALT_I2C_TAR_GC_OR_START_E_STARTBYTE));\r
+\r
+    if (already_enabled)\r
+    {\r
+        // Re-enable controller\r
+        status = alt_i2c_enable(i2c_dev);\r
+    }\r
+\r
+    return status;\r
+}\r
+\r
+//\r
+// Enables the I2C controller to respond with an ACK when it receives a General\r
+// Call address.\r
+//\r
+ALT_STATUS_CODE alt_i2c_general_call_ack_enable(ALT_I2C_DEV_t *i2c_dev)\r
+{\r
+    ALT_STATUS_CODE status = ALT_E_SUCCESS;\r
+\r
+    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)\r
+    {\r
+        return ALT_E_BAD_ARG;\r
+    }\r
+\r
+    bool already_enabled = (alt_i2c_is_enabled_helper(i2c_dev) == ALT_E_TRUE);\r
+\r
+    if (already_enabled)\r
+    {\r
+        // Temporarily disable controller\r
+        status = alt_i2c_disable(i2c_dev);\r
+        if (status != ALT_E_SUCCESS)\r
+        {\r
+            return status;\r
+        }\r
+    }\r
+\r
+    alt_replbits_word(ALT_I2C_TAR_ADDR(i2c_dev->location),\r
+                      ALT_I2C_TAR_SPECIAL_SET_MSK | ALT_I2C_TAR_GC_OR_START_SET_MSK,\r
+                      ALT_I2C_TAR_SPECIAL_SET(ALT_I2C_TAR_SPECIAL_E_GENCALL) | ALT_I2C_TAR_GC_OR_START_SET(ALT_I2C_TAR_GC_OR_START_E_GENCALL));\r
+\r
+    if (already_enabled)\r
+    {\r
+        // Re-enable controller\r
+        status = alt_i2c_enable(i2c_dev);\r
+    }\r
+\r
+    return status;\r
+}\r
+\r
+//\r
+// Returns ALT_E_TRUE if the I2C controller is enabled to respond to General Call\r
+// addresses.\r
+//\r
+ALT_STATUS_CODE alt_i2c_general_call_ack_is_enabled(ALT_I2C_DEV_t *i2c_dev)\r
+{\r
+    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)\r
+    {\r
+        return ALT_E_BAD_ARG;\r
+    }\r
+\r
+    uint32_t tar_register = alt_read_word(ALT_I2C_TAR_ADDR(i2c_dev->location));\r
+    \r
+    if (   (ALT_I2C_TAR_SPECIAL_GET(tar_register)     == ALT_I2C_TAR_SPECIAL_E_GENCALL)\r
+        && (ALT_I2C_TAR_GC_OR_START_GET(tar_register) == ALT_I2C_TAR_GC_OR_START_E_GENCALL)\r
+       )\r
+    {\r
+        return ALT_E_TRUE;\r
+    }\r
+    else\r
+    {\r
+        return ALT_E_FALSE;\r
+    }\r
+}\r
+\r
+//\r
+// Returns the current I2C controller interrupt status conditions.\r
+//\r
+ALT_STATUS_CODE alt_i2c_int_status_get(ALT_I2C_DEV_t *i2c_dev,\r
+                                       uint32_t *status)\r
+{\r
+    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)\r
+    {\r
+        return ALT_E_BAD_ARG;\r
+    }\r
+\r
+    *status = alt_read_word(ALT_I2C_INTR_STAT_ADDR(i2c_dev->location));\r
+\r
+    return ALT_E_SUCCESS;\r
+}\r
+\r
+//\r
+// Returns the I2C controller raw interrupt status conditions irrespective of\r
+// the interrupt status condition enablement state.\r
+//\r
+ALT_STATUS_CODE alt_i2c_int_raw_status_get(ALT_I2C_DEV_t *i2c_dev,\r
+                                           uint32_t *status)\r
+{\r
+    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)\r
+    {\r
+        return ALT_E_BAD_ARG;\r
+    }\r
+\r
+    *status = alt_read_word(ALT_I2C_RAW_INTR_STAT_ADDR(i2c_dev->location));\r
+\r
+    return ALT_E_SUCCESS;\r
+}\r
+\r
+//\r
+// Clears the specified I2C controller interrupt status conditions identified\r
+// in the mask.\r
+//\r
+ALT_STATUS_CODE alt_i2c_int_clear(ALT_I2C_DEV_t *i2c_dev, const uint32_t mask)\r
+{\r
+    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)\r
+    {\r
+        return ALT_E_BAD_ARG;\r
+    }\r
+\r
+    if (mask == ALT_I2C_STATUS_INT_ALL)\r
+    {\r
+        alt_read_word(ALT_I2C_CLR_INTR_ADDR(i2c_dev->location));\r
+        return ALT_E_SUCCESS;\r
+    }\r
+    \r
+    // For different status clear different register\r
+\r
+    if (mask & ALT_I2C_STATUS_RX_UNDER)\r
+    {\r
+        alt_read_word(ALT_I2C_CLR_RX_UNDER_ADDR(i2c_dev->location));\r
+    }\r
+    if (mask & ALT_I2C_STATUS_RX_OVER)\r
+    {\r
+        alt_read_word(ALT_I2C_CLR_RX_OVER_ADDR(i2c_dev->location));\r
+    }\r
+    if (mask & ALT_I2C_STATUS_TX_OVER)\r
+    {\r
+        alt_read_word(ALT_I2C_CLR_TX_OVER_ADDR(i2c_dev->location));\r
+    }\r
+    if (mask & ALT_I2C_STATUS_RD_REQ)\r
+    {\r
+        alt_read_word(ALT_I2C_CLR_RD_REQ_ADDR(i2c_dev->location));\r
+    }\r
+    if (mask & ALT_I2C_STATUS_TX_ABORT)\r
+    {\r
+        alt_read_word(ALT_I2C_CLR_TX_ABRT_ADDR(i2c_dev->location));\r
+    }\r
+    if (mask & ALT_I2C_STATUS_RX_DONE)\r
+    {\r
+        alt_read_word(ALT_I2C_CLR_RX_DONE_ADDR(i2c_dev->location));\r
+    }\r
+    if (mask & ALT_I2C_STATUS_ACTIVITY)\r
+    {\r
+        alt_read_word(ALT_I2C_CLR_ACTIVITY_ADDR(i2c_dev->location));\r
+    }\r
+    if (mask & ALT_I2C_STATUS_STOP_DET)\r
+    {\r
+        alt_read_word(ALT_I2C_CLR_STOP_DET_ADDR(i2c_dev->location));\r
+    }\r
+    if (mask & ALT_I2C_STATUS_START_DET)\r
+    {\r
+        alt_read_word(ALT_I2C_CLR_START_DET_ADDR(i2c_dev->location));\r
+    }\r
+    if (mask & ALT_I2C_STATUS_INT_CALL)\r
+    {\r
+        alt_read_word(ALT_I2C_CLR_GEN_CALL_ADDR(i2c_dev->location));\r
+    }\r
+\r
+    return ALT_E_SUCCESS;\r
+}\r
+\r
+//\r
+// Disable the specified I2C controller interrupt status conditions identified in\r
+// the mask.\r
+//\r
+ALT_STATUS_CODE alt_i2c_int_disable(ALT_I2C_DEV_t *i2c_dev, const uint32_t mask)\r
+{\r
+    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)\r
+    {\r
+        return ALT_E_BAD_ARG;\r
+    }\r
+\r
+    alt_clrbits_word(ALT_I2C_INTR_MSK_ADDR(i2c_dev->location), mask);    \r
+\r
+    return ALT_E_SUCCESS;\r
+}\r
+\r
+//\r
+// Enable the specified I2C controller interrupt status conditions identified in\r
+// the mask.\r
+//\r
+ALT_STATUS_CODE alt_i2c_int_enable(ALT_I2C_DEV_t *i2c_dev, const uint32_t mask)\r
+{\r
+    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)\r
+    {\r
+        return ALT_E_BAD_ARG;\r
+    }\r
+\r
+    alt_setbits_word(ALT_I2C_INTR_MSK_ADDR(i2c_dev->location), mask);\r
+\r
+    return ALT_E_SUCCESS;\r
+}\r
+\r
+/////\r
+\r
+//\r
+// Gets the cause of I2C transmission abort.\r
+//\r
+ALT_STATUS_CODE alt_i2c_tx_abort_cause_get(ALT_I2C_DEV_t *i2c_dev,\r
+                                           ALT_I2C_TX_ABORT_CAUSE_t *cause)\r
+{\r
+    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)\r
+    {\r
+        return ALT_E_BAD_ARG;\r
+    }\r
+\r
+    *cause = (ALT_I2C_TX_ABORT_CAUSE_t)alt_read_word(ALT_I2C_TX_ABRT_SRC_ADDR(i2c_dev->location));\r
+\r
+    return ALT_E_SUCCESS;\r
+}\r
+\r
+/////\r
+\r
+//\r
+// Returns ALT_E_TRUE when the receive FIFO is empty.\r
+//\r
+ALT_STATUS_CODE alt_i2c_rx_fifo_is_empty(ALT_I2C_DEV_t *i2c_dev)\r
+{\r
+    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)\r
+    {\r
+        return ALT_E_BAD_ARG;\r
+    }\r
+\r
+    if (ALT_I2C_STAT_RFNE_GET(alt_read_word(ALT_I2C_STAT_ADDR(i2c_dev->location))) == ALT_I2C_STAT_RFNE_E_EMPTY)\r
+    {\r
+        return ALT_E_TRUE;\r
+    }\r
+    else\r
+    {\r
+        return ALT_E_FALSE;\r
+    }\r
+}\r
+\r
+//\r
+// Returns ALT_E_TRUE when the receive FIFO is completely full.\r
+//\r
+ALT_STATUS_CODE alt_i2c_rx_fifo_is_full(ALT_I2C_DEV_t *i2c_dev)\r
+{\r
+    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)\r
+    {\r
+        return ALT_E_BAD_ARG;\r
+    }\r
+\r
+    if (ALT_I2C_STAT_RFF_GET(alt_read_word(ALT_I2C_STAT_ADDR(i2c_dev->location))) == ALT_I2C_STAT_RFF_E_FULL)\r
+    {\r
+        return ALT_E_TRUE;\r
+    }\r
+    else\r
+    {\r
+        return ALT_E_FALSE;\r
+    }\r
+}\r
+\r
+//\r
+// Returns the number of valid entries in the receive FIFO.\r
+//\r
+ALT_STATUS_CODE alt_i2c_rx_fifo_level_get(ALT_I2C_DEV_t *i2c_dev,\r
+                                          uint32_t *num_entries)\r
+{\r
+    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)\r
+    {\r
+        return ALT_E_BAD_ARG;\r
+    }\r
+\r
+    *num_entries = ALT_I2C_RXFLR_RXFLR_GET(alt_read_word(ALT_I2C_RXFLR_ADDR(i2c_dev->location)));\r
+\r
+    return ALT_E_SUCCESS;\r
+}\r
+\r
+//\r
+// Gets the current receive FIFO threshold level value.\r
+//\r
+ALT_STATUS_CODE alt_i2c_rx_fifo_threshold_get(ALT_I2C_DEV_t *i2c_dev,\r
+                                              uint8_t *threshold)\r
+{\r
+    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)\r
+    {\r
+        return ALT_E_BAD_ARG;\r
+    }\r
+\r
+    *threshold = ALT_I2C_RX_TL_RX_TL_GET(alt_read_word(ALT_I2C_RX_TL_ADDR(i2c_dev->location)));\r
+\r
+    return ALT_E_SUCCESS;\r
+}\r
+\r
+//\r
+// Sets the current receive FIFO threshold level value.\r
+//\r
+ALT_STATUS_CODE alt_i2c_rx_fifo_threshold_set(ALT_I2C_DEV_t *i2c_dev,\r
+                                              const uint8_t threshold)\r
+{\r
+    ALT_STATUS_CODE status = ALT_E_SUCCESS;\r
+\r
+    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)\r
+    {\r
+        return ALT_E_BAD_ARG;\r
+    }\r
+\r
+    bool already_enabled = (alt_i2c_is_enabled_helper(i2c_dev) == ALT_E_TRUE);\r
+\r
+    if (already_enabled)\r
+    {\r
+        // Temporarily disable controller\r
+        status = alt_i2c_disable(i2c_dev);\r
+        if (status != ALT_E_SUCCESS)\r
+        {\r
+            return status;\r
+        }\r
+    }\r
+\r
+    alt_replbits_word(ALT_I2C_RX_TL_ADDR(i2c_dev->location),\r
+                      ALT_I2C_RX_TL_RX_TL_SET_MSK,\r
+                      ALT_I2C_RX_TL_RX_TL_SET(threshold));\r
+\r
+    if (already_enabled)\r
+    {\r
+        // Re-enable controller\r
+        status = alt_i2c_enable(i2c_dev);\r
+    }\r
+\r
+    return status;\r
+}\r
+\r
+//\r
+// Returns ALT_E_TRUE when the transmit FIFO is empty.\r
+//\r
+ALT_STATUS_CODE alt_i2c_tx_fifo_is_empty(ALT_I2C_DEV_t *i2c_dev)\r
+{\r
+    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)\r
+    {\r
+        return ALT_E_BAD_ARG;\r
+    }\r
+\r
+    if (ALT_I2C_STAT_TFE_GET(alt_read_word(ALT_I2C_STAT_ADDR(i2c_dev->location))) == ALT_I2C_STAT_TFE_E_EMPTY)\r
+    {\r
+        return ALT_E_TRUE;\r
+    }\r
+    else\r
+    {\r
+        return ALT_E_FALSE;\r
+    }\r
+}\r
+\r
+//\r
+// Returns ALT_E_TRUE when the transmit FIFO is completely full.\r
+//\r
+ALT_STATUS_CODE alt_i2c_tx_fifo_is_full(ALT_I2C_DEV_t *i2c_dev)\r
+{\r
+    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)\r
+    {\r
+        return ALT_E_BAD_ARG;\r
+    }\r
+\r
+    if (ALT_I2C_STAT_TFNF_GET(alt_read_word(ALT_I2C_STAT_ADDR(i2c_dev->location))) == ALT_I2C_STAT_TFNF_E_FULL)\r
+    {\r
+        return ALT_E_TRUE;\r
+    }\r
+    else\r
+    {\r
+        return ALT_E_FALSE;\r
+    }\r
+}\r
+\r
+//\r
+// Returns the number of valid entries in the transmit FIFO.\r
+//\r
+ALT_STATUS_CODE alt_i2c_tx_fifo_level_get(ALT_I2C_DEV_t *i2c_dev,\r
+                                          uint32_t *num_entries)\r
+{\r
+    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)\r
+    {\r
+        return ALT_E_BAD_ARG;\r
+    }\r
+\r
+    *num_entries = ALT_I2C_TXFLR_TXFLR_GET(alt_read_word(ALT_I2C_TXFLR_ADDR(i2c_dev->location)));\r
+\r
+    return ALT_E_SUCCESS;\r
+}\r
+\r
+//\r
+// Sets the current transmit FIFO threshold level value.\r
+//\r
+ALT_STATUS_CODE alt_i2c_tx_fifo_threshold_get(ALT_I2C_DEV_t *i2c_dev,\r
+                                              uint8_t *threshold)\r
+{\r
+    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)\r
+    {\r
+        return ALT_E_BAD_ARG;\r
+    }\r
+\r
+    *threshold = ALT_I2C_TX_TL_TX_TL_GET(alt_read_word(ALT_I2C_TX_TL_ADDR(i2c_dev->location)));\r
+\r
+    return ALT_E_SUCCESS;\r
+}\r
+\r
+//\r
+// Sets the current transmit FIFO threshold level value.\r
+//\r
+ALT_STATUS_CODE alt_i2c_tx_fifo_threshold_set(ALT_I2C_DEV_t *i2c_dev,\r
+                                              const uint8_t threshold)\r
+{\r
+    ALT_STATUS_CODE status = ALT_E_SUCCESS;\r
+\r
+    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)\r
+    {\r
+        return ALT_E_BAD_ARG;\r
+    }\r
+\r
+    bool already_enabled = (alt_i2c_is_enabled_helper(i2c_dev) == ALT_E_TRUE);\r
+\r
+    if (already_enabled)\r
+    {\r
+        // Temporarily disable controller\r
+        status = alt_i2c_disable(i2c_dev);\r
+        if (status != ALT_E_SUCCESS)\r
+        {\r
+            return status;\r
+        }\r
+    }\r
+\r
+    alt_replbits_word(ALT_I2C_TX_TL_ADDR(i2c_dev->location),\r
+                      ALT_I2C_TX_TL_TX_TL_SET_MSK,\r
+                      ALT_I2C_TX_TL_TX_TL_SET(threshold));\r
+\r
+    if (already_enabled)\r
+    {\r
+        // Re-enable controller\r
+        status = alt_i2c_enable(i2c_dev);\r
+    }\r
+\r
+    return status;\r
+}\r
+\r
+/////\r
+\r
+ALT_STATUS_CODE alt_i2c_rx_dma_threshold_get(ALT_I2C_DEV_t * i2c_dev, uint8_t * threshold)\r
+{\r
+    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)\r
+    {\r
+        return ALT_E_BAD_ARG;\r
+    }\r
+\r
+    *threshold = ALT_I2C_DMA_RDLR_DMARDL_GET(alt_read_word(ALT_I2C_DMA_RDLR_ADDR(i2c_dev->location)));\r
+    return ALT_E_SUCCESS;\r
+}\r
+\r
+ALT_STATUS_CODE alt_i2c_rx_dma_threshold_set(ALT_I2C_DEV_t * i2c_dev, uint8_t threshold)\r
+{\r
+    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)\r
+    {\r
+        return ALT_E_BAD_ARG;\r
+    }\r
+\r
+    if (threshold > ALT_I2C_DMA_RDLR_DMARDL_SET_MSK)\r
+    {\r
+        return ALT_E_ARG_RANGE;\r
+    }\r
+\r
+    alt_write_word(ALT_I2C_DMA_RDLR_ADDR(i2c_dev->location), threshold);\r
+    return ALT_E_SUCCESS;\r
+\r
+}\r
+\r
+ALT_STATUS_CODE alt_i2c_tx_dma_threshold_get(ALT_I2C_DEV_t * i2c_dev, uint8_t * threshold)\r
+{\r
+    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)\r
+    {\r
+        return ALT_E_BAD_ARG;\r
+    }\r
+\r
+    *threshold = ALT_I2C_DMA_TDLR_DMATDL_GET(alt_read_word(ALT_I2C_DMA_TDLR_ADDR(i2c_dev->location)));\r
+    return ALT_E_SUCCESS;\r
+}\r
+\r
+ALT_STATUS_CODE alt_i2c_tx_dma_threshold_set(ALT_I2C_DEV_t * i2c_dev, uint8_t threshold)\r
+{\r
+    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)\r
+    {\r
+        return ALT_E_BAD_ARG;\r
+    }\r
+\r
+    if (threshold > ALT_I2C_DMA_TDLR_DMATDL_SET_MSK)\r
+    {\r
+        return ALT_E_ARG_RANGE;\r
+    }\r
+\r
+    alt_write_word(ALT_I2C_DMA_TDLR_ADDR(i2c_dev->location), threshold);\r
+    return ALT_E_SUCCESS;\r
+}\r