Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:22:43

0001 /**
0002  * @file
0003  *
0004  * @ingroup RTEMSBSPsARMCycVContrib
0005  */
0006 
0007 /******************************************************************************
0008  *
0009  * Copyright 2013 Altera Corporation. All Rights Reserved.
0010  * 
0011  * Redistribution and use in source and binary forms, with or without
0012  * modification, are permitted provided that the following conditions are met:
0013  * 
0014  * 1. Redistributions of source code must retain the above copyright notice,
0015  * this list of conditions and the following disclaimer.
0016  * 
0017  * 2. Redistributions in binary form must reproduce the above copyright notice,
0018  * this list of conditions and the following disclaimer in the documentation
0019  * and/or other materials provided with the distribution.
0020  * 
0021  * 3. The name of the author may not be used to endorse or promote products
0022  * derived from this software without specific prior written permission.
0023  * 
0024  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY EXPRESS OR
0025  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
0026  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED. IN NO
0027  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
0028  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
0029  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
0030  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
0031  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
0032  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
0033  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0034  * 
0035  ******************************************************************************/
0036 
0037 #include <bsp/alt_i2c.h>
0038 #include <bsp/alt_reset_manager.h>
0039 #include <stdio.h>
0040 
0041 /////
0042 
0043 // NOTE: To enable debugging output, delete the next line and uncomment the
0044 //   line after.
0045 #define dprintf(...)
0046 // #define dprintf(fmt, ...) printf(fmt, ##__VA_ARGS__)
0047 
0048 /////
0049 
0050 #define MIN(a, b) ((a) > (b) ? (b) : (a))
0051 
0052 /////
0053 
0054 // Timeout for reset manager
0055 #define ALT_I2C_RESET_TMO_INIT      8192
0056 // Timeout for disable device
0057 #define ALT_I2C_MAX_T_POLL_COUNT    8192
0058 // Timeout for waiting interrupt
0059 #define ALT_I2C_TMO_WAITER          2500000
0060 
0061 // Min frequency during standard speed
0062 #define ALT_I2C_SS_MIN_SPEED        8000
0063 // Max frequency during standard speed
0064 #define ALT_I2C_SS_MAX_SPEED        100000
0065 // Min frequency during fast speed
0066 #define ALT_I2C_FS_MIN_SPEED        100000
0067 // Max frequency during fast speed
0068 #define ALT_I2C_FS_MAX_SPEED        400000
0069 // Default spike suppression limit during standard speed
0070 #define ALT_I2C_SS_DEFAULT_SPKLEN   11
0071 // Default spike suppression limit during fast speed
0072 #define ALT_I2C_FS_DEFAULT_SPKLEN   4
0073 
0074 // Diff between SCL LCNT and SCL HCNT
0075 #define ALT_I2C_DIFF_LCNT_HCNT      70
0076 
0077 // Reserved address from 0x00 to 0x07
0078 #define ALT_I2C_SLV_RESERVE_ADDR_S_1     0x00
0079 #define ALT_I2C_SLV_RESERVE_ADDR_F_1     0x07
0080 // Reserved address from 0x78 to 0x7F
0081 #define ALT_I2C_SLV_RESERVE_ADDR_S_2     0x78
0082 #define ALT_I2C_SLV_RESERVE_ADDR_F_2     0x7F
0083 
0084 static ALT_STATUS_CODE alt_i2c_is_enabled_helper(ALT_I2C_DEV_t * i2c_dev);
0085 
0086 //
0087 // Check whether i2c space is correct.
0088 //
0089 static ALT_STATUS_CODE alt_i2c_checking(ALT_I2C_DEV_t * i2c_dev)
0090 {
0091     if (   (i2c_dev->location != (void *)ALT_I2C_I2C0)
0092         && (i2c_dev->location != (void *)ALT_I2C_I2C1)
0093         && (i2c_dev->location != (void *)ALT_I2C_I2C2)
0094         && (i2c_dev->location != (void *)ALT_I2C_I2C3))
0095     {
0096         // Incorrect device
0097         return ALT_E_FALSE;
0098     }
0099 
0100     // Reset i2c module
0101     return ALT_E_TRUE;
0102 }
0103 
0104 static ALT_STATUS_CODE alt_i2c_rstmgr_set(ALT_I2C_DEV_t * i2c_dev)
0105 {
0106     uint32_t rst_mask = ALT_RSTMGR_PERMODRST_I2C0_SET_MSK;
0107 
0108     // Assert the appropriate I2C module reset signal via the Reset Manager Peripheral Reset register.
0109     switch ((ALT_I2C_CTLR_t)i2c_dev->location)
0110     {
0111     case ALT_I2C_I2C0:
0112         rst_mask = ALT_RSTMGR_PERMODRST_I2C0_SET_MSK;
0113         break;
0114     case ALT_I2C_I2C1:
0115         rst_mask = ALT_RSTMGR_PERMODRST_I2C1_SET_MSK;
0116         break;
0117     case ALT_I2C_I2C2:
0118         rst_mask = ALT_RSTMGR_PERMODRST_I2C2_SET_MSK;
0119         break;
0120     case ALT_I2C_I2C3:
0121         rst_mask = ALT_RSTMGR_PERMODRST_I2C3_SET_MSK;
0122         break;
0123     default:
0124         return ALT_E_BAD_ARG;
0125     }
0126 
0127     alt_setbits_word(ALT_RSTMGR_PERMODRST_ADDR, rst_mask);
0128 
0129     return ALT_E_SUCCESS;
0130 }
0131 
0132 //
0133 // Reset i2c module by reset manager
0134 //
0135 static ALT_STATUS_CODE alt_i2c_rstmgr_strobe(ALT_I2C_DEV_t * i2c_dev)
0136 {
0137     uint32_t rst_mask = ALT_RSTMGR_PERMODRST_I2C0_SET_MSK;
0138 
0139     // Assert the appropriate I2C module reset signal via the Reset Manager Peripheral Reset register.
0140     switch ((ALT_I2C_CTLR_t)i2c_dev->location)
0141     {
0142     case ALT_I2C_I2C0:
0143         rst_mask = ALT_RSTMGR_PERMODRST_I2C0_SET_MSK;
0144         break;
0145     case ALT_I2C_I2C1:
0146         rst_mask = ALT_RSTMGR_PERMODRST_I2C1_SET_MSK;
0147         break;
0148     case ALT_I2C_I2C2:
0149         rst_mask = ALT_RSTMGR_PERMODRST_I2C2_SET_MSK;
0150         break;
0151     case ALT_I2C_I2C3:
0152         rst_mask = ALT_RSTMGR_PERMODRST_I2C3_SET_MSK;
0153         break;
0154     default:
0155         return ALT_E_BAD_ARG;
0156     }
0157 
0158     alt_setbits_word(ALT_RSTMGR_PERMODRST_ADDR, rst_mask);
0159 
0160     volatile uint32_t timeout = ALT_I2C_RESET_TMO_INIT;
0161 
0162     // Wait while i2c modure is reseting
0163     while (--timeout)
0164         ;
0165 
0166     // Deassert the appropriate I2C module reset signal via the Reset Manager Peripheral Reset register.
0167     alt_clrbits_word(ALT_RSTMGR_PERMODRST_ADDR, rst_mask);
0168 
0169     return ALT_E_SUCCESS;
0170 }
0171 
0172 //
0173 // Initialize the specified I2C controller instance for use and return a device
0174 // handle referencing it.
0175 //
0176 ALT_STATUS_CODE alt_i2c_init(const ALT_I2C_CTLR_t i2c,
0177                              ALT_I2C_DEV_t * i2c_dev)
0178 {
0179     // Save i2c start address to the instance
0180     i2c_dev->location = (void *)i2c;
0181     
0182     if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
0183     {
0184         return ALT_E_BAD_ARG;
0185     }
0186 
0187     if (alt_clk_is_enabled(ALT_CLK_L4_SP) != ALT_E_TRUE)
0188     {
0189         return ALT_E_BAD_CLK;
0190     }
0191 
0192     /////
0193 
0194     ALT_STATUS_CODE status = ALT_E_SUCCESS;
0195 
0196     if (status == ALT_E_SUCCESS)
0197     {
0198         status = alt_clk_freq_get(ALT_CLK_L4_SP, &i2c_dev->clock_freq);
0199     }
0200 
0201     // Reset i2c module
0202     if (status == ALT_E_SUCCESS)
0203     {
0204         status = alt_i2c_reset(i2c_dev);
0205     }
0206 
0207     return status;
0208 }
0209 
0210 //
0211 // Reset i2c module
0212 //
0213 ALT_STATUS_CODE alt_i2c_reset(ALT_I2C_DEV_t * i2c_dev)
0214 {
0215     if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
0216     {
0217         return ALT_E_BAD_ARG;
0218     }
0219 
0220     ALT_STATUS_CODE status = ALT_E_SUCCESS;
0221 
0222     bool already_enabled = (alt_i2c_is_enabled_helper(i2c_dev) == ALT_E_TRUE);
0223 
0224     if (already_enabled)
0225     {
0226         // Temporarily disable controller
0227         status = alt_i2c_disable(i2c_dev);
0228         if (status != ALT_E_SUCCESS)
0229         {
0230             return status;
0231         }
0232     }
0233     
0234     // Reset i2c module by reset manager
0235     alt_i2c_rstmgr_strobe(i2c_dev);
0236 
0237     // Set optimal parameters for all i2c devices on the bus
0238     ALT_I2C_MASTER_CONFIG_t cfg;
0239     cfg.addr_mode      = ALT_I2C_ADDR_MODE_7_BIT;
0240     cfg.speed_mode     = ALT_I2C_SPEED_STANDARD;
0241     cfg.fs_spklen      = ALT_I2C_SS_DEFAULT_SPKLEN;
0242     cfg.restart_enable = ALT_E_TRUE;
0243     cfg.ss_scl_lcnt    = cfg.fs_scl_lcnt = 0x2FB;
0244     cfg.ss_scl_hcnt    = cfg.fs_scl_hcnt = 0x341;
0245 
0246     alt_i2c_master_config_set(i2c_dev, &cfg);
0247 
0248     // Active master mode 
0249     alt_i2c_op_mode_set(i2c_dev, ALT_I2C_MODE_MASTER);
0250 
0251     // Reset the last target address cache.
0252     i2c_dev->last_target = 0xffffffff;
0253 
0254     // Clear interrupts mask and clear interrupt status.
0255     // Interrupts are unmasked by default.
0256     alt_i2c_int_disable(i2c_dev, ALT_I2C_STATUS_INT_ALL);
0257     alt_i2c_int_clear(i2c_dev, ALT_I2C_STATUS_INT_ALL);
0258 
0259     if (already_enabled)
0260     {
0261         // Re-enable controller
0262         status = alt_i2c_enable(i2c_dev);
0263     }
0264 
0265     return status;
0266 }
0267 
0268 //
0269 // Uninitialize the I2C controller referenced by the i2c_dev handle.
0270 //
0271 ALT_STATUS_CODE alt_i2c_uninit(ALT_I2C_DEV_t * i2c_dev)
0272 {
0273     if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
0274     {
0275         return ALT_E_BAD_ARG;
0276     }
0277 
0278     ALT_STATUS_CODE status = ALT_E_SUCCESS;
0279 
0280     // Disable i2c controller
0281     if (status == ALT_E_SUCCESS)
0282     {
0283         status = alt_i2c_disable(i2c_dev);
0284     }
0285 
0286     // Reset i2c module by reset manager
0287     if (status == ALT_E_SUCCESS)
0288     {
0289         status = alt_i2c_rstmgr_set(i2c_dev);
0290     }
0291 
0292     return status;
0293 }
0294 
0295 //
0296 // Enables the I2C controller.
0297 //
0298 ALT_STATUS_CODE alt_i2c_enable(ALT_I2C_DEV_t * i2c_dev)
0299 {
0300     if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
0301     {
0302         return ALT_E_BAD_ARG;
0303     }
0304 
0305     // Enable DMA by default.
0306     alt_write_word(ALT_I2C_DMA_CR_ADDR(i2c_dev->location), 
0307                    ALT_I2C_DMA_CR_TDMAE_SET_MSK | ALT_I2C_DMA_CR_RDMAE_SET_MSK);
0308 
0309     alt_setbits_word(ALT_I2C_EN_ADDR(i2c_dev->location), ALT_I2C_EN_EN_SET_MSK);
0310 
0311     return ALT_E_SUCCESS;
0312 }
0313 
0314 //
0315 // Disables the I2C controller
0316 //
0317 ALT_STATUS_CODE alt_i2c_disable(ALT_I2C_DEV_t * i2c_dev)
0318 {
0319     if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
0320     {
0321         return ALT_E_BAD_ARG;
0322     }
0323 
0324     // If i2c controller is enabled, return with sucess
0325     if (alt_i2c_is_enabled_helper(i2c_dev) == ALT_E_FALSE)
0326     {
0327         return ALT_E_SUCCESS;
0328     }
0329 
0330     // Else clear enable bit of i2c_enable register
0331     alt_clrbits_word(ALT_I2C_EN_ADDR(i2c_dev->location), ALT_I2C_EN_EN_SET_MSK);
0332     
0333     uint32_t timeout = ALT_I2C_MAX_T_POLL_COUNT;
0334 
0335     // Wait to complete all transfer operations or timeout
0336     while (alt_i2c_is_enabled_helper(i2c_dev) == ALT_E_TRUE)
0337     {
0338         // If controller still are active, return timeout error
0339         if (--timeout == 0)
0340         {
0341             return ALT_E_TMO;
0342         }
0343     }
0344 
0345     // Clear interrupt status
0346     alt_i2c_int_clear(i2c_dev, ALT_I2C_STATUS_INT_ALL);
0347 
0348     return ALT_E_SUCCESS;
0349 }
0350 
0351 //
0352 // Check whether i2c controller is enable
0353 //
0354 static ALT_STATUS_CODE alt_i2c_is_enabled_helper(ALT_I2C_DEV_t * i2c_dev)
0355 {
0356     if (ALT_I2C_EN_STAT_IC_EN_GET(alt_read_word(ALT_I2C_EN_STAT_ADDR(i2c_dev->location))))
0357     {
0358         return ALT_E_TRUE;
0359     }
0360     else
0361     {
0362         return ALT_E_FALSE;
0363     }
0364 }
0365 
0366 ALT_STATUS_CODE alt_i2c_is_enabled(ALT_I2C_DEV_t * i2c_dev)
0367 {
0368     if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
0369     {
0370         return ALT_E_BAD_ARG;
0371     }
0372 
0373     return alt_i2c_is_enabled_helper(i2c_dev);
0374 }
0375 
0376 //
0377 // Get config parameters from appropriate registers for master mode.
0378 //
0379 ALT_STATUS_CODE alt_i2c_master_config_get(ALT_I2C_DEV_t *i2c_dev,
0380                                           ALT_I2C_MASTER_CONFIG_t* cfg)
0381 {
0382     if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
0383     {
0384         return ALT_E_BAD_ARG;
0385     }
0386 
0387     uint32_t cfg_register  = alt_read_word(ALT_I2C_CON_ADDR(i2c_dev->location));
0388     uint32_t tar_register  = alt_read_word(ALT_I2C_TAR_ADDR(i2c_dev->location));
0389     uint32_t spkl_register = alt_read_word(ALT_I2C_FS_SPKLEN_ADDR(i2c_dev->location));
0390 
0391     cfg->speed_mode     = (ALT_I2C_SPEED_t)ALT_I2C_CON_SPEED_GET(cfg_register);
0392     cfg->fs_spklen      = ALT_I2C_FS_SPKLEN_SPKLEN_GET(spkl_register);
0393     cfg->restart_enable = ALT_I2C_CON_IC_RESTART_EN_GET(cfg_register);
0394     cfg->addr_mode      = (ALT_I2C_ADDR_MODE_t)ALT_I2C_TAR_IC_10BITADDR_MST_GET(tar_register);
0395 
0396     cfg->ss_scl_lcnt = alt_read_word(ALT_I2C_SS_SCL_LCNT_ADDR(i2c_dev->location));
0397     cfg->ss_scl_hcnt = alt_read_word(ALT_I2C_SS_SCL_HCNT_ADDR(i2c_dev->location));
0398     cfg->fs_scl_lcnt = alt_read_word(ALT_I2C_FS_SCL_LCNT_ADDR(i2c_dev->location));
0399     cfg->fs_scl_hcnt = alt_read_word(ALT_I2C_FS_SCL_HCNT_ADDR(i2c_dev->location));
0400 
0401     return ALT_E_SUCCESS;
0402 }
0403 
0404 //
0405 // Set config parameters to appropriate registers for master mode.
0406 //
0407 ALT_STATUS_CODE alt_i2c_master_config_set(ALT_I2C_DEV_t *i2c_dev,
0408                                           const ALT_I2C_MASTER_CONFIG_t* cfg)
0409 {
0410     if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
0411     {
0412         return ALT_E_BAD_ARG;
0413     }
0414 
0415     if (   (cfg->speed_mode != ALT_I2C_SPEED_STANDARD)
0416         && (cfg->speed_mode != ALT_I2C_SPEED_FAST))
0417     {
0418         return ALT_E_BAD_ARG;
0419     }
0420 
0421     if (   (cfg->addr_mode != ALT_I2C_ADDR_MODE_7_BIT)
0422         && (cfg->addr_mode != ALT_I2C_ADDR_MODE_10_BIT))
0423     {
0424         return ALT_E_ARG_RANGE;
0425     }
0426 
0427     ALT_STATUS_CODE status = ALT_E_SUCCESS;
0428 
0429     bool already_enabled = (alt_i2c_is_enabled_helper(i2c_dev) == ALT_E_TRUE);
0430 
0431     if (already_enabled)
0432     {
0433         // Temporarily disable controller
0434         status = alt_i2c_disable(i2c_dev);
0435         if (status != ALT_E_SUCCESS)
0436         {
0437             return status;
0438         }
0439     }
0440 
0441     // Set config parameters to appropriate registers
0442 
0443     alt_replbits_word(ALT_I2C_CON_ADDR(i2c_dev->location),
0444                       ALT_I2C_CON_SPEED_SET_MSK | ALT_I2C_CON_IC_RESTART_EN_SET_MSK,
0445                       ALT_I2C_CON_SPEED_SET(cfg->speed_mode) | ALT_I2C_CON_IC_RESTART_EN_SET(cfg->restart_enable));
0446     
0447     alt_replbits_word(ALT_I2C_TAR_ADDR(i2c_dev->location),
0448                       ALT_I2C_TAR_IC_10BITADDR_MST_SET_MSK, 
0449                       ALT_I2C_TAR_IC_10BITADDR_MST_SET(cfg->addr_mode));
0450 
0451     alt_replbits_word(ALT_I2C_FS_SPKLEN_ADDR(i2c_dev->location),
0452                       ALT_I2C_FS_SPKLEN_SPKLEN_SET_MSK,
0453                       ALT_I2C_FS_SPKLEN_SPKLEN_SET(cfg->fs_spklen));
0454     
0455     alt_replbits_word(ALT_I2C_SS_SCL_LCNT_ADDR(i2c_dev->location),
0456                       ALT_I2C_SS_SCL_LCNT_IC_SS_SCL_LCNT_SET_MSK,
0457                       ALT_I2C_SS_SCL_LCNT_IC_SS_SCL_LCNT_SET(cfg->ss_scl_lcnt));
0458     alt_replbits_word(ALT_I2C_SS_SCL_HCNT_ADDR(i2c_dev->location),
0459                       ALT_I2C_SS_SCL_HCNT_IC_SS_SCL_HCNT_SET_MSK,
0460                       ALT_I2C_SS_SCL_HCNT_IC_SS_SCL_HCNT_SET(cfg->ss_scl_hcnt));
0461     alt_replbits_word(ALT_I2C_FS_SCL_LCNT_ADDR(i2c_dev->location),
0462                       ALT_I2C_FS_SCL_LCNT_IC_FS_SCL_LCNT_SET_MSK,
0463                       ALT_I2C_FS_SCL_LCNT_IC_FS_SCL_LCNT_SET(cfg->fs_scl_lcnt));
0464     alt_replbits_word(ALT_I2C_FS_SCL_HCNT_ADDR(i2c_dev->location),
0465                       ALT_I2C_FS_SCL_HCNT_IC_FS_SCL_HCNT_SET_MSK,
0466                       ALT_I2C_FS_SCL_HCNT_IC_FS_SCL_HCNT_SET(cfg->fs_scl_hcnt));
0467 
0468     if (already_enabled)
0469     {
0470         // Re-enable controller
0471         status = alt_i2c_enable(i2c_dev);
0472     }
0473 
0474     return status;
0475 }
0476 
0477 //
0478 // Return bus speed by configuration of i2c controller for master mode.
0479 //
0480 ALT_STATUS_CODE alt_i2c_master_config_speed_get(ALT_I2C_DEV_t *i2c_dev,
0481                                                 const ALT_I2C_MASTER_CONFIG_t * cfg,
0482                                                 uint32_t * speed_in_hz)
0483 {
0484     if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
0485     {
0486         return ALT_E_BAD_ARG;
0487     }
0488 
0489     uint32_t scl_lcnt = (cfg->speed_mode == ALT_I2C_SPEED_STANDARD) ? cfg->ss_scl_lcnt : cfg->fs_scl_lcnt;
0490 
0491     if (scl_lcnt == 0)
0492     {
0493         return ALT_E_BAD_ARG;
0494     }
0495     
0496     *speed_in_hz = i2c_dev->clock_freq / (scl_lcnt << 1);
0497 
0498     return ALT_E_SUCCESS;
0499 }
0500 
0501 //
0502 // Fill struct with configuration of i2c controller for master mode by bus speed
0503 //
0504 ALT_STATUS_CODE alt_i2c_master_config_speed_set(ALT_I2C_DEV_t *i2c_dev,
0505                                                 ALT_I2C_MASTER_CONFIG_t * cfg,
0506                                                 uint32_t speed_in_hz)    
0507 {
0508     if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
0509     {
0510         return ALT_E_BAD_ARG;
0511     }
0512 
0513     // If speed is not standard or fast return range error
0514     if ((speed_in_hz > ALT_I2C_FS_MAX_SPEED) || (speed_in_hz < ALT_I2C_SS_MIN_SPEED))
0515     {
0516         return ALT_E_ARG_RANGE;
0517     }
0518     
0519     if (speed_in_hz > ALT_I2C_FS_MIN_SPEED)
0520     {
0521         cfg->speed_mode = ALT_I2C_SPEED_FAST;
0522         cfg->fs_spklen  = ALT_I2C_FS_DEFAULT_SPKLEN;
0523     }
0524     else
0525     {
0526         cfg->speed_mode = ALT_I2C_SPEED_STANDARD;
0527         cfg->fs_spklen  = ALT_I2C_SS_DEFAULT_SPKLEN;
0528     }
0529 
0530     // <lcount> = <internal clock> / 2 * <speed, Hz>
0531     uint32_t scl_lcnt = i2c_dev->clock_freq / (speed_in_hz << 1);
0532 
0533     cfg->ss_scl_lcnt = cfg->fs_scl_lcnt = scl_lcnt;
0534     // hcount = <lcount> + 70
0535     cfg->ss_scl_hcnt = cfg->fs_scl_hcnt = scl_lcnt - ALT_I2C_DIFF_LCNT_HCNT;
0536 
0537     // lcount = <internal clock> / 2 * <speed, Hz>
0538 
0539     return ALT_E_SUCCESS;
0540 }
0541 
0542 //
0543 // Get config parameters from appropriate registers for slave mode.
0544 //
0545 ALT_STATUS_CODE alt_i2c_slave_config_get(ALT_I2C_DEV_t *i2c_dev,
0546                                          ALT_I2C_SLAVE_CONFIG_t* cfg)
0547 {
0548     if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
0549     {
0550         return ALT_E_BAD_ARG;
0551     }
0552 
0553     uint32_t cfg_register  = alt_read_word(ALT_I2C_CON_ADDR(i2c_dev->location));
0554     uint32_t sar_register  = alt_read_word(ALT_I2C_SAR_ADDR(i2c_dev->location));
0555     uint32_t nack_register = alt_read_word(ALT_I2C_SLV_DATA_NACK_ONLY_ADDR(i2c_dev->location));
0556 
0557     cfg->addr_mode   = (ALT_I2C_ADDR_MODE_t)ALT_I2C_CON_IC_10BITADDR_SLV_GET(cfg_register);
0558     cfg->addr        = ALT_I2C_SAR_IC_SAR_GET(sar_register);
0559     cfg->nack_enable = ALT_I2C_SLV_DATA_NACK_ONLY_NACK_GET(nack_register);
0560 
0561     return ALT_E_SUCCESS;
0562 }
0563 
0564 //
0565 // Set config parameters to appropriate registers for slave mode.
0566 //
0567 ALT_STATUS_CODE alt_i2c_slave_config_set(ALT_I2C_DEV_t *i2c_dev,
0568                                          const ALT_I2C_SLAVE_CONFIG_t* cfg)
0569 {
0570     if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
0571     {
0572         return ALT_E_BAD_ARG;
0573     }
0574 
0575     if (   (cfg->addr_mode != ALT_I2C_ADDR_MODE_7_BIT)
0576         && (cfg->addr_mode != ALT_I2C_ADDR_MODE_10_BIT))
0577     {
0578         return ALT_E_BAD_ARG;
0579     }
0580 
0581     if (   (cfg->addr > ALT_I2C_SAR_IC_SAR_SET_MSK)
0582         || (cfg->addr < ALT_I2C_SLV_RESERVE_ADDR_F_1)
0583         || ((cfg->addr > ALT_I2C_SLV_RESERVE_ADDR_S_2) && (cfg->addr < ALT_I2C_SLV_RESERVE_ADDR_F_2))
0584        )
0585     {
0586         return ALT_E_ARG_RANGE;
0587     }
0588 
0589     ALT_STATUS_CODE status = ALT_E_SUCCESS;
0590 
0591     bool already_enabled = (alt_i2c_is_enabled_helper(i2c_dev) == ALT_E_TRUE);
0592 
0593     if (already_enabled)
0594     {
0595         // Temporarily disable controller
0596         status = alt_i2c_disable(i2c_dev);
0597         if (status != ALT_E_SUCCESS)
0598         {
0599             return status;
0600         }
0601     }
0602 
0603     alt_replbits_word(ALT_I2C_CON_ADDR(i2c_dev->location),
0604                       ALT_I2C_CON_IC_10BITADDR_SLV_SET_MSK,
0605                       ALT_I2C_CON_IC_10BITADDR_SLV_SET(cfg->addr_mode));
0606 
0607     alt_replbits_word(ALT_I2C_SAR_ADDR(i2c_dev->location),
0608                       ALT_I2C_SAR_IC_SAR_SET_MSK,
0609                       ALT_I2C_SAR_IC_SAR_SET(cfg->addr));
0610     alt_replbits_word(ALT_I2C_SLV_DATA_NACK_ONLY_ADDR(i2c_dev->location),
0611                       ALT_I2C_SLV_DATA_NACK_ONLY_NACK_SET_MSK,
0612                       ALT_I2C_SLV_DATA_NACK_ONLY_NACK_SET(cfg->nack_enable));
0613 
0614     if (already_enabled)
0615     {
0616         // Re-enable controller
0617         status = alt_i2c_enable(i2c_dev);
0618     }
0619 
0620     return status;
0621 }
0622 
0623 //
0624 // Get hold time (use during slave mode)
0625 //
0626 ALT_STATUS_CODE alt_i2c_sda_hold_time_get(ALT_I2C_DEV_t *i2c_dev, 
0627                                           uint16_t *hold_time)
0628 {
0629     if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
0630     {
0631         return ALT_E_BAD_ARG;
0632     }
0633 
0634     uint32_t sda_register = alt_read_word(ALT_I2C_SDA_HOLD_ADDR(i2c_dev->location));
0635     *hold_time = ALT_I2C_SDA_HOLD_IC_SDA_HOLD_GET(sda_register);
0636 
0637     return ALT_E_SUCCESS;
0638 }
0639     
0640 //
0641 // Set hold time (use during slave mode)
0642 //
0643 ALT_STATUS_CODE alt_i2c_sda_hold_time_set(ALT_I2C_DEV_t *i2c_dev, 
0644                                           const uint16_t hold_time)
0645 {
0646     if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
0647     {
0648         return ALT_E_BAD_ARG;
0649     }
0650 
0651     ALT_STATUS_CODE status = ALT_E_SUCCESS;
0652 
0653     bool already_enabled = (alt_i2c_is_enabled_helper(i2c_dev) == ALT_E_TRUE);
0654 
0655     if (already_enabled)
0656     {
0657         // Temporarily disable controller
0658         status = alt_i2c_disable(i2c_dev);
0659         if (status != ALT_E_SUCCESS)
0660         {
0661             return status;
0662         }
0663     }
0664 
0665     alt_replbits_word(ALT_I2C_SDA_HOLD_ADDR(i2c_dev->location),
0666                       ALT_I2C_SDA_HOLD_IC_SDA_HOLD_SET_MSK,
0667                       ALT_I2C_SDA_HOLD_IC_SDA_HOLD_SET(hold_time));
0668 
0669     if (already_enabled)
0670     {
0671         // Re-enable controller
0672         status = alt_i2c_enable(i2c_dev);
0673     }
0674 
0675     return status;
0676 }
0677     
0678 //
0679 // Gets the current operational mode of the I2C controller.
0680 //
0681 ALT_STATUS_CODE alt_i2c_op_mode_get(ALT_I2C_DEV_t *i2c_dev,
0682                                     ALT_I2C_MODE_t* mode)
0683 {
0684     if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
0685     {
0686         return ALT_E_BAD_ARG;
0687     }
0688     
0689     uint32_t cfg_register = alt_read_word(ALT_I2C_CON_ADDR(i2c_dev->location));
0690     uint32_t mst_mod_stat = ALT_I2C_CON_MST_MOD_GET(cfg_register);
0691     uint32_t slv_mod_stat = ALT_I2C_CON_IC_SLV_DIS_GET(cfg_register);
0692 
0693     // Return error if master and slave modes enable or disable at the same time
0694     if (   (mst_mod_stat == ALT_I2C_CON_MST_MOD_E_EN  && slv_mod_stat == ALT_I2C_CON_IC_SLV_DIS_E_EN) 
0695         || (mst_mod_stat == ALT_I2C_CON_MST_MOD_E_DIS && slv_mod_stat == ALT_I2C_CON_IC_SLV_DIS_E_DIS))
0696     {
0697         return ALT_E_ERROR;
0698     }
0699 
0700     *mode = (ALT_I2C_MODE_t)mst_mod_stat;
0701 
0702     return ALT_E_SUCCESS;
0703 }
0704     
0705 //
0706 // Sets the operational mode of the I2C controller.
0707 //
0708 ALT_STATUS_CODE alt_i2c_op_mode_set(ALT_I2C_DEV_t *i2c_dev,
0709                                     const ALT_I2C_MODE_t mode)    
0710 {
0711     if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
0712     {
0713         return ALT_E_BAD_ARG;
0714     }
0715 
0716     if (   (mode != ALT_I2C_MODE_MASTER)
0717         && (mode != ALT_I2C_MODE_SLAVE))
0718     {
0719         return ALT_E_ARG_RANGE;
0720     }
0721     
0722     ALT_STATUS_CODE status = ALT_E_SUCCESS;
0723 
0724     bool already_enabled = (alt_i2c_is_enabled_helper(i2c_dev) == ALT_E_TRUE);
0725 
0726     if (already_enabled)
0727     {
0728         // Temporarily disable controller
0729         status = alt_i2c_disable(i2c_dev);
0730         if (status != ALT_E_SUCCESS)
0731         {
0732             return status;
0733         }
0734     }
0735 
0736     if (mode == ALT_I2C_MODE_MASTER)
0737     {
0738         // Enable master, disable slave
0739         alt_replbits_word(ALT_I2C_CON_ADDR(i2c_dev->location),
0740                           ALT_I2C_CON_IC_SLV_DIS_SET_MSK | ALT_I2C_CON_MST_MOD_SET_MSK,
0741                           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));
0742     }
0743     else if (mode == ALT_I2C_MODE_SLAVE)
0744     {
0745         // Enable slave, disable master
0746         alt_replbits_word(ALT_I2C_CON_ADDR(i2c_dev->location),
0747                           ALT_I2C_CON_IC_SLV_DIS_SET_MSK | ALT_I2C_CON_MST_MOD_SET_MSK,
0748                           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));
0749     }
0750         
0751     if (already_enabled)
0752     {
0753         // Re-enable controller
0754         status = alt_i2c_enable(i2c_dev);
0755     }
0756     
0757     return status;
0758 }
0759     
0760 //
0761 // Returns ALT_E_TRUE if the I2C controller is busy
0762 //
0763 ALT_STATUS_CODE alt_i2c_is_busy(ALT_I2C_DEV_t *i2c_dev)
0764 {
0765     if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
0766     {
0767         return ALT_E_BAD_ARG;
0768     }
0769     
0770     if ( ALT_I2C_STAT_ACTIVITY_GET(alt_read_word(ALT_I2C_STAT_ADDR(i2c_dev->location))))
0771     {
0772         return ALT_E_TRUE;
0773     }
0774     else
0775     {
0776         return ALT_E_FALSE;
0777     }
0778 }
0779 
0780 //
0781 // This function reads a single data byte from the receive FIFO.
0782 //
0783 ALT_STATUS_CODE alt_i2c_read(ALT_I2C_DEV_t *i2c_dev, uint8_t *value)
0784 {
0785     if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
0786     {
0787         return ALT_E_BAD_ARG;
0788     }
0789 
0790     if (alt_i2c_is_enabled_helper(i2c_dev) == ALT_E_FALSE)
0791     {
0792         return ALT_E_ERROR;
0793     }
0794 
0795     *value = (uint8_t)(ALT_I2C_DATA_CMD_DAT_GET(alt_read_word(ALT_I2C_DATA_CMD_ADDR(i2c_dev->location))));
0796 
0797     return ALT_E_SUCCESS;
0798 }
0799 
0800 //
0801 // This function writes a single data byte to the transmit FIFO.
0802 //
0803 ALT_STATUS_CODE alt_i2c_write(ALT_I2C_DEV_t *i2c_dev, const uint8_t value)
0804 {
0805     if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
0806     {
0807         return ALT_E_BAD_ARG;
0808     }
0809 
0810     if (alt_i2c_is_enabled_helper(i2c_dev) == ALT_E_FALSE)
0811     {
0812         return ALT_E_ERROR;
0813     }
0814 
0815     alt_write_word(ALT_I2C_DATA_CMD_ADDR(i2c_dev->location),
0816                    ALT_I2C_DATA_CMD_DAT_SET(value));
0817 
0818     return ALT_E_SUCCESS;
0819 }
0820 
0821 //
0822 // This function acts in the role of a slave-receiver by receiving a single data
0823 // byte from the I2C bus in response to a write command from the master.
0824 //
0825 ALT_STATUS_CODE alt_i2c_slave_receive(ALT_I2C_DEV_t * i2c_dev,
0826                                       uint8_t * data)
0827 {
0828     if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
0829     {
0830         return ALT_E_BAD_ARG;
0831     }
0832 
0833     if (alt_i2c_is_enabled_helper(i2c_dev) == ALT_E_FALSE)
0834     {
0835         return ALT_E_ERROR;
0836     }
0837 
0838     // alt_i2c_read().
0839     *data = (uint8_t)(ALT_I2C_DATA_CMD_DAT_GET(alt_read_word(ALT_I2C_DATA_CMD_ADDR(i2c_dev->location))));
0840 
0841     return ALT_E_SUCCESS;
0842 }
0843 
0844 //
0845 // This function acts in the role of a slave-transmitter by transmitting a single
0846 // data byte to the I2C bus in response to a read request from the master.
0847 //
0848 ALT_STATUS_CODE alt_i2c_slave_transmit(ALT_I2C_DEV_t *i2c_dev,
0849                                        const uint8_t data)
0850 {
0851     // Send bulk of data with one value
0852     return alt_i2c_slave_bulk_transmit(i2c_dev, &data, 1);
0853 }
0854 
0855 //
0856 // This function acts in the role of a slave-transmitter by transmitting data in
0857 // bulk to the I2C bus in response to a series of read requests from a master.
0858 //
0859 ALT_STATUS_CODE alt_i2c_slave_bulk_transmit(ALT_I2C_DEV_t *i2c_dev,
0860                                             const void * data,
0861                                             const size_t size)
0862 {
0863     if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
0864     {
0865         return ALT_E_BAD_ARG;
0866     }
0867 
0868     if (alt_i2c_is_enabled_helper(i2c_dev) == ALT_E_FALSE)
0869     {
0870         return ALT_E_ERROR;
0871     }
0872 
0873     const char * buffer = data;
0874     for (size_t i = 0; i < size; ++i)
0875     {
0876         alt_write_word(ALT_I2C_DATA_CMD_ADDR(i2c_dev->location),
0877                          ALT_I2C_DATA_CMD_DAT_SET(*buffer)
0878                        | ALT_I2C_DATA_CMD_STOP_SET(false)
0879                        | ALT_I2C_DATA_CMD_RESTART_SET(false));
0880 
0881         ++buffer;
0882     }
0883 
0884     return ALT_E_SUCCESS;
0885 }
0886 
0887 ALT_STATUS_CODE alt_i2c_master_target_get(ALT_I2C_DEV_t * i2c_dev, uint32_t * target_addr)
0888 {
0889     if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
0890     {
0891         return ALT_E_BAD_ARG;
0892     }
0893 
0894     *target_addr = i2c_dev->last_target;
0895 
0896     return ALT_E_SUCCESS;
0897 }
0898 
0899 ALT_STATUS_CODE alt_i2c_master_target_set(ALT_I2C_DEV_t * i2c_dev, uint32_t target_addr)
0900 {
0901     if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
0902     {
0903         return ALT_E_BAD_ARG;
0904     }
0905 
0906     ALT_STATUS_CODE status = ALT_E_SUCCESS;
0907 
0908     // Wait until the TX FIFO flushes. This is needed because TAR can only be
0909     // updated under specific conditions.
0910 
0911     if (target_addr != i2c_dev->last_target)
0912     {
0913         uint32_t timeout = 10000;
0914 
0915         while (alt_i2c_tx_fifo_is_empty(i2c_dev) == ALT_E_FALSE)
0916         {
0917             if (--timeout == 0)
0918             {
0919                 status = ALT_E_TMO;
0920                 break;
0921             }
0922         }
0923 
0924         // Update target address
0925         if (status == ALT_E_SUCCESS)
0926         {
0927             alt_replbits_word(ALT_I2C_TAR_ADDR(i2c_dev->location),
0928                               ALT_I2C_TAR_IC_TAR_SET_MSK,
0929                               ALT_I2C_TAR_IC_TAR_SET(target_addr));
0930 
0931             i2c_dev->last_target = target_addr;
0932         }
0933     }
0934 
0935     return status;
0936 }
0937 
0938 //
0939 // Write bulk of data or read requests to tx fifo
0940 //
0941 static ALT_STATUS_CODE alt_i2c_master_transmit_helper(ALT_I2C_DEV_t * i2c_dev,
0942                                                       const uint8_t * buffer,
0943                                                       size_t size,
0944                                                       bool issue_restart,
0945                                                       bool issue_stop)
0946 {
0947     ALT_STATUS_CODE status = ALT_E_SUCCESS;
0948 
0949     // If the rested size is 1, the restart and stop may need to be sent in the
0950     // same frame.
0951     if (size == 1)
0952     {
0953         if (status == ALT_E_SUCCESS)
0954         {
0955             status = alt_i2c_issue_write(i2c_dev,
0956                                          *buffer,
0957                                          issue_restart,
0958                                          issue_stop);
0959 
0960             ++buffer;
0961             --size;
0962         }
0963     }
0964     else
0965     {
0966         // First byte
0967 
0968         if (status == ALT_E_SUCCESS)
0969         {
0970             status = alt_i2c_issue_write(i2c_dev,
0971                                          *buffer,
0972                                          issue_restart,
0973                                          false);
0974 
0975             ++buffer;
0976             --size;
0977         }
0978 
0979         /////
0980             
0981         // Middle byte(s)
0982 
0983         if (status == ALT_E_SUCCESS)
0984         {
0985             uint32_t timeout = size * 10000;
0986 
0987             while (size > 1)
0988             {
0989                 uint32_t level = 0;
0990                 status = alt_i2c_tx_fifo_level_get(i2c_dev, &level);
0991                 if (status != ALT_E_SUCCESS)
0992                 {
0993                     break;
0994                 }
0995 
0996                 uint32_t space = ALT_I2C_TX_FIFO_NUM_ENTRIES - level;
0997                 if (space == 0)
0998                 {
0999                     if (--timeout == 0)
1000                     {
1001                         status = ALT_E_TMO;
1002                         break;
1003                     }
1004 
1005                     continue;
1006                 }
1007                 
1008                 // Subtract 1 because the last byte may need to issue_stop
1009                 space = MIN(space, size - 1);
1010 
1011                 for (uint32_t i = 0; i < space; ++i)
1012                 {
1013                     alt_write_word(ALT_I2C_DATA_CMD_ADDR(i2c_dev->location),
1014                                      ALT_I2C_DATA_CMD_DAT_SET(*buffer)
1015                                    | ALT_I2C_DATA_CMD_STOP_SET(false)
1016                                    | ALT_I2C_DATA_CMD_RESTART_SET(false));
1017 
1018                     ++buffer;
1019                 }
1020 
1021                 size -= space;
1022             }
1023         }
1024 
1025         /////
1026 
1027         // Last byte
1028 
1029         if (status == ALT_E_SUCCESS)
1030         {
1031             status = alt_i2c_issue_write(i2c_dev,
1032                                          *buffer,
1033                                          false,
1034                                          issue_stop);
1035 
1036             ++buffer;
1037             --size;
1038         }
1039     }
1040 
1041     return status;
1042 }
1043 
1044 //
1045 // This function acts in the role of a master-transmitter by issuing a write
1046 // command and transmitting data to the I2C bus.
1047 //
1048 ALT_STATUS_CODE alt_i2c_master_transmit(ALT_I2C_DEV_t *i2c_dev,
1049                                         const void * data,
1050                                         const size_t size,
1051                                         const bool issue_restart,
1052                                         const bool issue_stop)
1053 {
1054     if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
1055     {
1056         return ALT_E_BAD_ARG;
1057     }
1058 
1059     if (alt_i2c_is_enabled_helper(i2c_dev) == ALT_E_FALSE)
1060     {
1061         return ALT_E_ERROR;
1062     }
1063 
1064     if (size == 0)
1065     {
1066         return ALT_E_SUCCESS;
1067     }
1068     
1069     ALT_STATUS_CODE status = ALT_E_SUCCESS;
1070 
1071     if (status == ALT_E_SUCCESS)
1072     {
1073         status = alt_i2c_master_transmit_helper(i2c_dev,
1074                                                 data,
1075                                                 size,
1076                                                 issue_restart,
1077                                                 issue_stop);
1078     }
1079 
1080     // Need reset for set i2c bus in idle state
1081     if (status == ALT_E_TMO)
1082     {
1083         alt_i2c_reset(i2c_dev);
1084     }
1085 
1086     return status;
1087 }
1088 
1089 ALT_STATUS_CODE alt_i2c_master_receive_helper(ALT_I2C_DEV_t *i2c_dev,
1090                                               uint8_t * buffer,
1091                                               size_t size,
1092                                               bool issue_restart,
1093                                               bool issue_stop)
1094 {
1095     ALT_STATUS_CODE status = ALT_E_SUCCESS;
1096 
1097     uint32_t issue_left = size;
1098     uint32_t data_left  = size;
1099 
1100     uint32_t timeout = size * 10000;
1101 
1102     // Wait for space in the TX FIFO to send the first read request.
1103     // This is needed because the issue restart need to be set.
1104 
1105     if (issue_restart == true)
1106     {
1107         if (status == ALT_E_SUCCESS)
1108         {
1109             while (alt_i2c_tx_fifo_is_full(i2c_dev) == ALT_E_TRUE)
1110             {
1111                 if (--timeout == 0)
1112                 {
1113                     status = ALT_E_TMO;
1114                     break;
1115                 }
1116             }
1117         }
1118 
1119         // Now send the first request.
1120 
1121         if (status == ALT_E_SUCCESS)
1122         {
1123             alt_write_word(ALT_I2C_DATA_CMD_ADDR(i2c_dev->location),
1124                              ALT_I2C_DATA_CMD_CMD_SET(ALT_I2C_DATA_CMD_CMD_E_RD)
1125                            | ALT_I2C_DATA_CMD_STOP_SET(false)
1126                            | ALT_I2C_DATA_CMD_RESTART_SET(issue_restart));
1127 
1128             --issue_left;
1129         }
1130     }
1131 
1132     // For the rest of the data ...
1133 
1134     while (data_left > 0)
1135     {
1136         if (status != ALT_E_SUCCESS)
1137         {
1138             break;
1139         }
1140 
1141         // Top up the TX FIFO with read issues
1142         // Special consideration must be made for the last read issue, as it may be necessary to "issue_stop".
1143 
1144         if (issue_left > 0)
1145         {
1146             uint32_t level = 0;
1147             status = alt_i2c_tx_fifo_level_get(i2c_dev, &level);
1148             if (status != ALT_E_SUCCESS)
1149             {
1150                 break;
1151             }
1152 
1153             uint32_t space = ALT_I2C_TX_FIFO_NUM_ENTRIES - level;
1154 
1155             if (issue_left == 1)
1156             {
1157                 if (space > 0)
1158                 {
1159                     space = 1;
1160 
1161                     alt_write_word(ALT_I2C_DATA_CMD_ADDR(i2c_dev->location),
1162                                    ALT_I2C_DATA_CMD_CMD_SET(ALT_I2C_DATA_CMD_CMD_E_RD)
1163                                    | ALT_I2C_DATA_CMD_STOP_SET(issue_stop)
1164                                    | ALT_I2C_DATA_CMD_RESTART_SET(false));
1165                 }
1166             }
1167             else
1168             {
1169                 // Send up to issue_left - 1, as the last issue has special considerations.
1170                 space = MIN(issue_left - 1, space);
1171 
1172                 for (uint32_t i = 0; i < space; ++i)
1173                 {
1174                     alt_write_word(ALT_I2C_DATA_CMD_ADDR(i2c_dev->location),
1175                                    ALT_I2C_DATA_CMD_CMD_SET(ALT_I2C_DATA_CMD_CMD_E_RD)
1176                                    | ALT_I2C_DATA_CMD_STOP_SET(false)
1177                                    | ALT_I2C_DATA_CMD_RESTART_SET(false));
1178                 }
1179             }
1180 
1181             issue_left -= space;
1182         }
1183 
1184         // Read out the resulting received data as they come in.
1185 
1186         if (data_left > 0)
1187         {
1188             uint32_t level = 0;
1189             status = alt_i2c_rx_fifo_level_get(i2c_dev, &level);
1190             if (status != ALT_E_SUCCESS)
1191             {
1192                 break;
1193             }
1194 
1195             if (level == 0)
1196             {
1197                 if (--timeout == 0)
1198                 {
1199                     status = ALT_E_TMO;
1200                     break;
1201                 }
1202             }
1203 
1204             level = MIN(data_left, level);
1205 
1206             for (uint32_t i = 0; i < level; ++i)
1207             {
1208                 // alt_i2c_read(i2c_dev, &value);
1209                 *buffer = (uint8_t)(ALT_I2C_DATA_CMD_DAT_GET(alt_read_word(ALT_I2C_DATA_CMD_ADDR(i2c_dev->location))));
1210                 ++buffer;
1211             }
1212 
1213             data_left -= level;
1214         }
1215     }
1216 
1217 
1218     return status;
1219 }
1220 
1221 //
1222 // This function acts in the role of a master-receiver by receiving one or more
1223 // data bytes transmitted from a slave in response to read requests issued from
1224 // this master.
1225 //
1226 ALT_STATUS_CODE alt_i2c_master_receive(ALT_I2C_DEV_t *i2c_dev, 
1227                                        void * data,
1228                                        const size_t size,
1229                                        const bool issue_restart,
1230                                        const bool issue_stop)
1231 {
1232     if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
1233     {
1234         return ALT_E_BAD_ARG;
1235     }
1236 
1237     if (alt_i2c_is_enabled_helper(i2c_dev) == ALT_E_FALSE)
1238     {
1239         return ALT_E_ERROR;
1240     }
1241 
1242     if (size == 0)
1243     {
1244         return ALT_E_SUCCESS;
1245     }
1246 
1247     ALT_STATUS_CODE status = ALT_E_SUCCESS;
1248 
1249     // This I2C controller requires that a read issue be performed for each byte requested.
1250     // Read issue takes space in the TX FIFO, which may asynchronously handling a previous request.
1251 
1252     if (size == 1)
1253     {
1254         uint32_t timeout = 10000;
1255 
1256         // Wait for space in the TX FIFO to send the read request.
1257 
1258         if (status == ALT_E_SUCCESS)
1259         {
1260             while (alt_i2c_tx_fifo_is_full(i2c_dev) == ALT_E_TRUE)
1261             {
1262                 if (--timeout == 0)
1263                 {
1264                     status = ALT_E_TMO;
1265                     break;
1266                 }
1267             }
1268         }
1269 
1270         // Issue the read request in the TX FIFO.
1271 
1272         if (status == ALT_E_SUCCESS)
1273         {
1274             alt_write_word(ALT_I2C_DATA_CMD_ADDR(i2c_dev->location),
1275                              ALT_I2C_DATA_CMD_CMD_SET(ALT_I2C_DATA_CMD_CMD_E_RD)
1276                            | ALT_I2C_DATA_CMD_STOP_SET(issue_stop)
1277                            | ALT_I2C_DATA_CMD_RESTART_SET(issue_restart));
1278 
1279         }
1280 
1281         // Wait for data to become available in the RX FIFO.
1282 
1283         if (status == ALT_E_SUCCESS)
1284         {
1285             while (alt_i2c_rx_fifo_is_empty(i2c_dev) == ALT_E_TRUE)
1286             {
1287                 if (--timeout == 0)
1288                 {
1289                     status = ALT_E_TMO;
1290                     break;
1291                 }
1292             }
1293         }
1294 
1295         // Read the RX FIFO.
1296 
1297         if (status == ALT_E_SUCCESS)
1298         {
1299             uint8_t * buffer = data;
1300             *buffer = (uint8_t)(ALT_I2C_DATA_CMD_DAT_GET(alt_read_word(ALT_I2C_DATA_CMD_ADDR(i2c_dev->location))));
1301         }
1302     }
1303     else if (size <= 64)
1304     {
1305         if (status == ALT_E_SUCCESS)
1306         {
1307             status = alt_i2c_master_receive_helper(i2c_dev,
1308                                                    data,
1309                                                    size,
1310                                                    issue_restart,
1311                                                    issue_stop);
1312         }
1313     }
1314     else
1315     {
1316         uint8_t * buffer = data;
1317         size_t size_left = size;
1318 
1319         // Send the first ALT_I2C_RX_FIFO_NUM_ENTRIES items
1320 
1321         if (status == ALT_E_SUCCESS)
1322         {
1323             status = alt_i2c_master_receive_helper(i2c_dev,
1324                                                    buffer,
1325                                                    ALT_I2C_RX_FIFO_NUM_ENTRIES,
1326                                                    issue_restart,
1327                                                    false);
1328         }
1329 
1330         buffer    += ALT_I2C_RX_FIFO_NUM_ENTRIES;
1331         size_left -= ALT_I2C_RX_FIFO_NUM_ENTRIES;
1332 
1333         while (size_left > 0)
1334         {
1335             if (size_left > ALT_I2C_RX_FIFO_NUM_ENTRIES)
1336             {
1337                 if (status == ALT_E_SUCCESS)
1338                 {
1339                     status = alt_i2c_master_receive_helper(i2c_dev,
1340                                                            buffer,
1341                                                            ALT_I2C_RX_FIFO_NUM_ENTRIES,
1342                                                            false,
1343                                                            false);
1344                 }
1345 
1346                 buffer    += ALT_I2C_RX_FIFO_NUM_ENTRIES;
1347                 size_left -= ALT_I2C_RX_FIFO_NUM_ENTRIES;
1348             }
1349             else
1350             {
1351                 if (status == ALT_E_SUCCESS)
1352                 {
1353                     status = alt_i2c_master_receive_helper(i2c_dev,
1354                                                            buffer,
1355                                                            size_left,
1356                                                            false,
1357                                                            issue_stop);
1358                 }
1359 
1360                 size_left = 0;
1361             }
1362 
1363             if (status != ALT_E_SUCCESS)
1364             {
1365                 break;
1366             }
1367         }
1368     }
1369 
1370     // Need reset for set i2c bus in idle state
1371     if (status == ALT_E_TMO)
1372     {
1373         alt_i2c_reset(i2c_dev);
1374     }
1375 
1376     return status;
1377 }
1378 
1379 //
1380 // This function causes the I2C controller master to send data to the bus.
1381 //
1382 ALT_STATUS_CODE alt_i2c_issue_write(ALT_I2C_DEV_t *i2c_dev,
1383                                     const uint8_t value,
1384                                     const bool issue_restart,
1385                                     const bool issue_stop)
1386 {
1387     if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
1388     {
1389         return ALT_E_BAD_ARG;
1390     }
1391 
1392     if (alt_i2c_is_enabled_helper(i2c_dev) == ALT_E_FALSE)
1393     {
1394         return ALT_E_ERROR;
1395     }
1396 
1397     // Wait until there is a FIFO spot
1398     uint32_t timeout = 10000;
1399 
1400     while (alt_i2c_tx_fifo_is_full(i2c_dev) == ALT_E_TRUE)
1401     {
1402         if (--timeout == 0)
1403         {
1404             return ALT_E_TMO;
1405         }
1406     }
1407 
1408     alt_write_word(ALT_I2C_DATA_CMD_ADDR(i2c_dev->location),
1409                      ALT_I2C_DATA_CMD_DAT_SET(value)
1410                    | ALT_I2C_DATA_CMD_STOP_SET(issue_stop)
1411                    | ALT_I2C_DATA_CMD_RESTART_SET(issue_restart));
1412 
1413     return ALT_E_SUCCESS;
1414 }
1415 
1416 //
1417 // This function causes the I2C controller master to issue a READ request on the bus.
1418 //
1419 ALT_STATUS_CODE alt_i2c_issue_read(ALT_I2C_DEV_t *i2c_dev,
1420                                    const bool issue_restart,
1421                                    const bool issue_stop)
1422 {
1423     if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
1424     {
1425         return ALT_E_BAD_ARG;
1426     }
1427 
1428     if (alt_i2c_is_enabled_helper(i2c_dev) == ALT_E_FALSE)
1429     {
1430         return ALT_E_ERROR;
1431     }
1432 
1433     // Wait until there is a FIFO spot
1434     uint32_t timeout = 10000;
1435 
1436     while (alt_i2c_tx_fifo_is_full(i2c_dev) == ALT_E_TRUE)
1437     {
1438         if (--timeout == 0)
1439         {
1440             return ALT_E_TMO;
1441         }
1442     }
1443 
1444     alt_write_word(ALT_I2C_DATA_CMD_ADDR(i2c_dev->location),
1445                      ALT_I2C_DATA_CMD_CMD_SET(ALT_I2C_DATA_CMD_CMD_E_RD)
1446                    | ALT_I2C_DATA_CMD_STOP_SET(issue_stop)
1447                    | ALT_I2C_DATA_CMD_RESTART_SET(issue_restart));
1448 
1449     return ALT_E_SUCCESS;
1450 }
1451 
1452 //
1453 // This function acts in the role of a master-transmitter by issuing a general
1454 // call command to all devices connected to the I2C bus.
1455 //
1456 ALT_STATUS_CODE alt_i2c_master_general_call(ALT_I2C_DEV_t *i2c_dev,
1457                                             const void * data,
1458                                             const size_t size,
1459                                             const bool issue_restart,
1460                                             const bool issue_stop)
1461 {
1462     if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
1463     {
1464         return ALT_E_BAD_ARG;
1465     }
1466 
1467     if (alt_i2c_is_enabled_helper(i2c_dev) == ALT_E_FALSE)
1468     {
1469         return ALT_E_ERROR;
1470     }
1471 
1472     ALT_STATUS_CODE status = ALT_E_SUCCESS;
1473 
1474     if (status == ALT_E_SUCCESS)
1475     {
1476         status = alt_i2c_master_target_set(i2c_dev, 0);
1477     }
1478 
1479     // General call is a transmit in master mode (target address are not used during it)
1480     if (status == ALT_E_SUCCESS)
1481     {
1482         status = alt_i2c_master_transmit(i2c_dev, data, size, issue_restart, issue_stop);
1483     }
1484 
1485     return status;
1486 }
1487 
1488 /////
1489 
1490 ALT_STATUS_CODE alt_i2c_general_call_ack_disable(ALT_I2C_DEV_t *i2c_dev)
1491 {
1492     ALT_STATUS_CODE status = ALT_E_SUCCESS;
1493 
1494     if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
1495     {
1496         return ALT_E_BAD_ARG;
1497     }
1498 
1499     bool already_enabled = (alt_i2c_is_enabled_helper(i2c_dev) == ALT_E_TRUE);
1500 
1501     if (already_enabled)
1502     {
1503         // Temporarily disable controller
1504         status = alt_i2c_disable(i2c_dev);
1505         if (status != ALT_E_SUCCESS)
1506         {
1507             return status;
1508         }
1509     }
1510 
1511     alt_replbits_word(ALT_I2C_TAR_ADDR(i2c_dev->location),
1512                       ALT_I2C_TAR_SPECIAL_SET_MSK | ALT_I2C_TAR_GC_OR_START_SET_MSK,
1513                       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));
1514 
1515     if (already_enabled)
1516     {
1517         // Re-enable controller
1518         status = alt_i2c_enable(i2c_dev);
1519     }
1520 
1521     return status;
1522 }
1523 
1524 //
1525 // Enables the I2C controller to respond with an ACK when it receives a General
1526 // Call address.
1527 //
1528 ALT_STATUS_CODE alt_i2c_general_call_ack_enable(ALT_I2C_DEV_t *i2c_dev)
1529 {
1530     ALT_STATUS_CODE status = ALT_E_SUCCESS;
1531 
1532     if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
1533     {
1534         return ALT_E_BAD_ARG;
1535     }
1536 
1537     bool already_enabled = (alt_i2c_is_enabled_helper(i2c_dev) == ALT_E_TRUE);
1538 
1539     if (already_enabled)
1540     {
1541         // Temporarily disable controller
1542         status = alt_i2c_disable(i2c_dev);
1543         if (status != ALT_E_SUCCESS)
1544         {
1545             return status;
1546         }
1547     }
1548 
1549     alt_replbits_word(ALT_I2C_TAR_ADDR(i2c_dev->location),
1550                       ALT_I2C_TAR_SPECIAL_SET_MSK | ALT_I2C_TAR_GC_OR_START_SET_MSK,
1551                       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));
1552 
1553     if (already_enabled)
1554     {
1555         // Re-enable controller
1556         status = alt_i2c_enable(i2c_dev);
1557     }
1558 
1559     return status;
1560 }
1561 
1562 //
1563 // Returns ALT_E_TRUE if the I2C controller is enabled to respond to General Call
1564 // addresses.
1565 //
1566 ALT_STATUS_CODE alt_i2c_general_call_ack_is_enabled(ALT_I2C_DEV_t *i2c_dev)
1567 {
1568     if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
1569     {
1570         return ALT_E_BAD_ARG;
1571     }
1572 
1573     uint32_t tar_register = alt_read_word(ALT_I2C_TAR_ADDR(i2c_dev->location));
1574     
1575     if (   (ALT_I2C_TAR_SPECIAL_GET(tar_register)     == ALT_I2C_TAR_SPECIAL_E_GENCALL)
1576         && (ALT_I2C_TAR_GC_OR_START_GET(tar_register) == ALT_I2C_TAR_GC_OR_START_E_GENCALL)
1577        )
1578     {
1579         return ALT_E_TRUE;
1580     }
1581     else
1582     {
1583         return ALT_E_FALSE;
1584     }
1585 }
1586 
1587 //
1588 // Returns the current I2C controller interrupt status conditions.
1589 //
1590 ALT_STATUS_CODE alt_i2c_int_status_get(ALT_I2C_DEV_t *i2c_dev,
1591                                        uint32_t *status)
1592 {
1593     if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
1594     {
1595         return ALT_E_BAD_ARG;
1596     }
1597 
1598     *status = alt_read_word(ALT_I2C_INTR_STAT_ADDR(i2c_dev->location));
1599 
1600     return ALT_E_SUCCESS;
1601 }
1602 
1603 //
1604 // Returns the I2C controller raw interrupt status conditions irrespective of
1605 // the interrupt status condition enablement state.
1606 //
1607 ALT_STATUS_CODE alt_i2c_int_raw_status_get(ALT_I2C_DEV_t *i2c_dev,
1608                                            uint32_t *status)
1609 {
1610     if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
1611     {
1612         return ALT_E_BAD_ARG;
1613     }
1614 
1615     *status = alt_read_word(ALT_I2C_RAW_INTR_STAT_ADDR(i2c_dev->location));
1616 
1617     return ALT_E_SUCCESS;
1618 }
1619 
1620 //
1621 // Clears the specified I2C controller interrupt status conditions identified
1622 // in the mask.
1623 //
1624 ALT_STATUS_CODE alt_i2c_int_clear(ALT_I2C_DEV_t *i2c_dev, const uint32_t mask)
1625 {
1626     if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
1627     {
1628         return ALT_E_BAD_ARG;
1629     }
1630 
1631     if (mask == ALT_I2C_STATUS_INT_ALL)
1632     {
1633         alt_read_word(ALT_I2C_CLR_INTR_ADDR(i2c_dev->location));
1634         return ALT_E_SUCCESS;
1635     }
1636     
1637     // For different status clear different register
1638 
1639     if (mask & ALT_I2C_STATUS_RX_UNDER)
1640     {
1641         alt_read_word(ALT_I2C_CLR_RX_UNDER_ADDR(i2c_dev->location));
1642     }
1643     if (mask & ALT_I2C_STATUS_RX_OVER)
1644     {
1645         alt_read_word(ALT_I2C_CLR_RX_OVER_ADDR(i2c_dev->location));
1646     }
1647     if (mask & ALT_I2C_STATUS_TX_OVER)
1648     {
1649         alt_read_word(ALT_I2C_CLR_TX_OVER_ADDR(i2c_dev->location));
1650     }
1651     if (mask & ALT_I2C_STATUS_RD_REQ)
1652     {
1653         alt_read_word(ALT_I2C_CLR_RD_REQ_ADDR(i2c_dev->location));
1654     }
1655     if (mask & ALT_I2C_STATUS_TX_ABORT)
1656     {
1657         alt_read_word(ALT_I2C_CLR_TX_ABRT_ADDR(i2c_dev->location));
1658     }
1659     if (mask & ALT_I2C_STATUS_RX_DONE)
1660     {
1661         alt_read_word(ALT_I2C_CLR_RX_DONE_ADDR(i2c_dev->location));
1662     }
1663     if (mask & ALT_I2C_STATUS_ACTIVITY)
1664     {
1665         alt_read_word(ALT_I2C_CLR_ACTIVITY_ADDR(i2c_dev->location));
1666     }
1667     if (mask & ALT_I2C_STATUS_STOP_DET)
1668     {
1669         alt_read_word(ALT_I2C_CLR_STOP_DET_ADDR(i2c_dev->location));
1670     }
1671     if (mask & ALT_I2C_STATUS_START_DET)
1672     {
1673         alt_read_word(ALT_I2C_CLR_START_DET_ADDR(i2c_dev->location));
1674     }
1675     if (mask & ALT_I2C_STATUS_INT_CALL)
1676     {
1677         alt_read_word(ALT_I2C_CLR_GEN_CALL_ADDR(i2c_dev->location));
1678     }
1679 
1680     return ALT_E_SUCCESS;
1681 }
1682 
1683 //
1684 // Disable the specified I2C controller interrupt status conditions identified in
1685 // the mask.
1686 //
1687 ALT_STATUS_CODE alt_i2c_int_disable(ALT_I2C_DEV_t *i2c_dev, const uint32_t mask)
1688 {
1689     if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
1690     {
1691         return ALT_E_BAD_ARG;
1692     }
1693 
1694     alt_clrbits_word(ALT_I2C_INTR_MSK_ADDR(i2c_dev->location), mask);    
1695 
1696     return ALT_E_SUCCESS;
1697 }
1698 
1699 //
1700 // Enable the specified I2C controller interrupt status conditions identified in
1701 // the mask.
1702 //
1703 ALT_STATUS_CODE alt_i2c_int_enable(ALT_I2C_DEV_t *i2c_dev, const uint32_t mask)
1704 {
1705     if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
1706     {
1707         return ALT_E_BAD_ARG;
1708     }
1709 
1710     alt_setbits_word(ALT_I2C_INTR_MSK_ADDR(i2c_dev->location), mask);
1711 
1712     return ALT_E_SUCCESS;
1713 }
1714 
1715 /////
1716 
1717 //
1718 // Gets the cause of I2C transmission abort.
1719 //
1720 ALT_STATUS_CODE alt_i2c_tx_abort_cause_get(ALT_I2C_DEV_t *i2c_dev,
1721                                            ALT_I2C_TX_ABORT_CAUSE_t *cause)
1722 {
1723     if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
1724     {
1725         return ALT_E_BAD_ARG;
1726     }
1727 
1728     *cause = (ALT_I2C_TX_ABORT_CAUSE_t)alt_read_word(ALT_I2C_TX_ABRT_SRC_ADDR(i2c_dev->location));
1729 
1730     return ALT_E_SUCCESS;
1731 }
1732 
1733 /////
1734 
1735 //
1736 // Returns ALT_E_TRUE when the receive FIFO is empty.
1737 //
1738 ALT_STATUS_CODE alt_i2c_rx_fifo_is_empty(ALT_I2C_DEV_t *i2c_dev)
1739 {
1740     if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
1741     {
1742         return ALT_E_BAD_ARG;
1743     }
1744 
1745     if (ALT_I2C_STAT_RFNE_GET(alt_read_word(ALT_I2C_STAT_ADDR(i2c_dev->location))) == ALT_I2C_STAT_RFNE_E_EMPTY)
1746     {
1747         return ALT_E_TRUE;
1748     }
1749     else
1750     {
1751         return ALT_E_FALSE;
1752     }
1753 }
1754 
1755 //
1756 // Returns ALT_E_TRUE when the receive FIFO is completely full.
1757 //
1758 ALT_STATUS_CODE alt_i2c_rx_fifo_is_full(ALT_I2C_DEV_t *i2c_dev)
1759 {
1760     if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
1761     {
1762         return ALT_E_BAD_ARG;
1763     }
1764 
1765     if (ALT_I2C_STAT_RFF_GET(alt_read_word(ALT_I2C_STAT_ADDR(i2c_dev->location))) == ALT_I2C_STAT_RFF_E_FULL)
1766     {
1767         return ALT_E_TRUE;
1768     }
1769     else
1770     {
1771         return ALT_E_FALSE;
1772     }
1773 }
1774 
1775 //
1776 // Returns the number of valid entries in the receive FIFO.
1777 //
1778 ALT_STATUS_CODE alt_i2c_rx_fifo_level_get(ALT_I2C_DEV_t *i2c_dev,
1779                                           uint32_t *num_entries)
1780 {
1781     if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
1782     {
1783         return ALT_E_BAD_ARG;
1784     }
1785 
1786     *num_entries = ALT_I2C_RXFLR_RXFLR_GET(alt_read_word(ALT_I2C_RXFLR_ADDR(i2c_dev->location)));
1787 
1788     return ALT_E_SUCCESS;
1789 }
1790 
1791 //
1792 // Gets the current receive FIFO threshold level value.
1793 //
1794 ALT_STATUS_CODE alt_i2c_rx_fifo_threshold_get(ALT_I2C_DEV_t *i2c_dev,
1795                                               uint8_t *threshold)
1796 {
1797     if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
1798     {
1799         return ALT_E_BAD_ARG;
1800     }
1801 
1802     *threshold = ALT_I2C_RX_TL_RX_TL_GET(alt_read_word(ALT_I2C_RX_TL_ADDR(i2c_dev->location)));
1803 
1804     return ALT_E_SUCCESS;
1805 }
1806 
1807 //
1808 // Sets the current receive FIFO threshold level value.
1809 //
1810 ALT_STATUS_CODE alt_i2c_rx_fifo_threshold_set(ALT_I2C_DEV_t *i2c_dev,
1811                                               const uint8_t threshold)
1812 {
1813     ALT_STATUS_CODE status = ALT_E_SUCCESS;
1814 
1815     if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
1816     {
1817         return ALT_E_BAD_ARG;
1818     }
1819 
1820     bool already_enabled = (alt_i2c_is_enabled_helper(i2c_dev) == ALT_E_TRUE);
1821 
1822     if (already_enabled)
1823     {
1824         // Temporarily disable controller
1825         status = alt_i2c_disable(i2c_dev);
1826         if (status != ALT_E_SUCCESS)
1827         {
1828             return status;
1829         }
1830     }
1831 
1832     alt_replbits_word(ALT_I2C_RX_TL_ADDR(i2c_dev->location),
1833                       ALT_I2C_RX_TL_RX_TL_SET_MSK,
1834                       ALT_I2C_RX_TL_RX_TL_SET(threshold));
1835 
1836     if (already_enabled)
1837     {
1838         // Re-enable controller
1839         status = alt_i2c_enable(i2c_dev);
1840     }
1841 
1842     return status;
1843 }
1844 
1845 //
1846 // Returns ALT_E_TRUE when the transmit FIFO is empty.
1847 //
1848 ALT_STATUS_CODE alt_i2c_tx_fifo_is_empty(ALT_I2C_DEV_t *i2c_dev)
1849 {
1850     if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
1851     {
1852         return ALT_E_BAD_ARG;
1853     }
1854 
1855     if (ALT_I2C_STAT_TFE_GET(alt_read_word(ALT_I2C_STAT_ADDR(i2c_dev->location))) == ALT_I2C_STAT_TFE_E_EMPTY)
1856     {
1857         return ALT_E_TRUE;
1858     }
1859     else
1860     {
1861         return ALT_E_FALSE;
1862     }
1863 }
1864 
1865 //
1866 // Returns ALT_E_TRUE when the transmit FIFO is completely full.
1867 //
1868 ALT_STATUS_CODE alt_i2c_tx_fifo_is_full(ALT_I2C_DEV_t *i2c_dev)
1869 {
1870     if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
1871     {
1872         return ALT_E_BAD_ARG;
1873     }
1874 
1875     if (ALT_I2C_STAT_TFNF_GET(alt_read_word(ALT_I2C_STAT_ADDR(i2c_dev->location))) == ALT_I2C_STAT_TFNF_E_FULL)
1876     {
1877         return ALT_E_TRUE;
1878     }
1879     else
1880     {
1881         return ALT_E_FALSE;
1882     }
1883 }
1884 
1885 //
1886 // Returns the number of valid entries in the transmit FIFO.
1887 //
1888 ALT_STATUS_CODE alt_i2c_tx_fifo_level_get(ALT_I2C_DEV_t *i2c_dev,
1889                                           uint32_t *num_entries)
1890 {
1891     if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
1892     {
1893         return ALT_E_BAD_ARG;
1894     }
1895 
1896     *num_entries = ALT_I2C_TXFLR_TXFLR_GET(alt_read_word(ALT_I2C_TXFLR_ADDR(i2c_dev->location)));
1897 
1898     return ALT_E_SUCCESS;
1899 }
1900 
1901 //
1902 // Sets the current transmit FIFO threshold level value.
1903 //
1904 ALT_STATUS_CODE alt_i2c_tx_fifo_threshold_get(ALT_I2C_DEV_t *i2c_dev,
1905                                               uint8_t *threshold)
1906 {
1907     if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
1908     {
1909         return ALT_E_BAD_ARG;
1910     }
1911 
1912     *threshold = ALT_I2C_TX_TL_TX_TL_GET(alt_read_word(ALT_I2C_TX_TL_ADDR(i2c_dev->location)));
1913 
1914     return ALT_E_SUCCESS;
1915 }
1916 
1917 //
1918 // Sets the current transmit FIFO threshold level value.
1919 //
1920 ALT_STATUS_CODE alt_i2c_tx_fifo_threshold_set(ALT_I2C_DEV_t *i2c_dev,
1921                                               const uint8_t threshold)
1922 {
1923     ALT_STATUS_CODE status = ALT_E_SUCCESS;
1924 
1925     if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
1926     {
1927         return ALT_E_BAD_ARG;
1928     }
1929 
1930     bool already_enabled = (alt_i2c_is_enabled_helper(i2c_dev) == ALT_E_TRUE);
1931 
1932     if (already_enabled)
1933     {
1934         // Temporarily disable controller
1935         status = alt_i2c_disable(i2c_dev);
1936         if (status != ALT_E_SUCCESS)
1937         {
1938             return status;
1939         }
1940     }
1941 
1942     alt_replbits_word(ALT_I2C_TX_TL_ADDR(i2c_dev->location),
1943                       ALT_I2C_TX_TL_TX_TL_SET_MSK,
1944                       ALT_I2C_TX_TL_TX_TL_SET(threshold));
1945 
1946     if (already_enabled)
1947     {
1948         // Re-enable controller
1949         status = alt_i2c_enable(i2c_dev);
1950     }
1951 
1952     return status;
1953 }
1954 
1955 /////
1956 
1957 ALT_STATUS_CODE alt_i2c_rx_dma_threshold_get(ALT_I2C_DEV_t * i2c_dev, uint8_t * threshold)
1958 {
1959     if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
1960     {
1961         return ALT_E_BAD_ARG;
1962     }
1963 
1964     *threshold = ALT_I2C_DMA_RDLR_DMARDL_GET(alt_read_word(ALT_I2C_DMA_RDLR_ADDR(i2c_dev->location)));
1965     return ALT_E_SUCCESS;
1966 }
1967 
1968 ALT_STATUS_CODE alt_i2c_rx_dma_threshold_set(ALT_I2C_DEV_t * i2c_dev, uint8_t threshold)
1969 {
1970     if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
1971     {
1972         return ALT_E_BAD_ARG;
1973     }
1974 
1975     if (threshold > ALT_I2C_DMA_RDLR_DMARDL_SET_MSK)
1976     {
1977         return ALT_E_ARG_RANGE;
1978     }
1979 
1980     alt_write_word(ALT_I2C_DMA_RDLR_ADDR(i2c_dev->location), threshold);
1981     return ALT_E_SUCCESS;
1982 
1983 }
1984 
1985 ALT_STATUS_CODE alt_i2c_tx_dma_threshold_get(ALT_I2C_DEV_t * i2c_dev, uint8_t * threshold)
1986 {
1987     if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
1988     {
1989         return ALT_E_BAD_ARG;
1990     }
1991 
1992     *threshold = ALT_I2C_DMA_TDLR_DMATDL_GET(alt_read_word(ALT_I2C_DMA_TDLR_ADDR(i2c_dev->location)));
1993     return ALT_E_SUCCESS;
1994 }
1995 
1996 ALT_STATUS_CODE alt_i2c_tx_dma_threshold_set(ALT_I2C_DEV_t * i2c_dev, uint8_t threshold)
1997 {
1998     if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
1999     {
2000         return ALT_E_BAD_ARG;
2001     }
2002 
2003     if (threshold > ALT_I2C_DMA_TDLR_DMATDL_SET_MSK)
2004     {
2005         return ALT_E_ARG_RANGE;
2006     }
2007 
2008     alt_write_word(ALT_I2C_DMA_TDLR_ADDR(i2c_dev->location), threshold);
2009     return ALT_E_SUCCESS;
2010 }