source: rtems/c/src/lib/libbsp/arm/altera-cyclone-v/hwlib/src/hwmgr/alt_i2c.c @ 3f9cd87d

4.115
Last change on this file since 3f9cd87d was 3f9cd87d, checked in by Christian Mauderer <Christian.Mauderer@…>, on 07/14/14 at 14:33:52

bsp/altera-cyclone-v: Add a simple I2C driver.

  • Property mode set to 100644
File size: 54.9 KB
Line 
1/******************************************************************************
2 *
3 * Copyright 2013 Altera Corporation. All Rights Reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
14 *
15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
20 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED. IN NO
21 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 *
29 ******************************************************************************/
30
31#include "alt_i2c.h"
32#include "alt_reset_manager.h"
33#include <stdio.h>
34
35/////
36
37// NOTE: To enable debugging output, delete the next line and uncomment the
38//   line after.
39#define dprintf(...)
40// #define dprintf(fmt, ...) printf(fmt, ##__VA_ARGS__)
41
42/////
43
44#define MIN(a, b) ((a) > (b) ? (b) : (a))
45
46/////
47
48// Timeout for reset manager
49#define ALT_I2C_RESET_TMO_INIT      8192
50// Timeout for disable device
51#define ALT_I2C_MAX_T_POLL_COUNT    8192
52// Timeout for waiting interrupt
53#define ALT_I2C_TMO_WAITER          2500000
54
55// Min frequency during standard speed
56#define ALT_I2C_SS_MIN_SPEED        8000
57// Max frequency during standard speed
58#define ALT_I2C_SS_MAX_SPEED        100000
59// Min frequency during fast speed
60#define ALT_I2C_FS_MIN_SPEED        100000
61// Max frequency during fast speed
62#define ALT_I2C_FS_MAX_SPEED        400000
63// Default spike suppression limit during standard speed
64#define ALT_I2C_SS_DEFAULT_SPKLEN   11
65// Default spike suppression limit during fast speed
66#define ALT_I2C_FS_DEFAULT_SPKLEN   4
67
68// Diff between SCL LCNT and SCL HCNT
69#define ALT_I2C_DIFF_LCNT_HCNT      70
70
71// Reserved address from 0x00 to 0x07
72#define ALT_I2C_SLV_RESERVE_ADDR_S_1     0x00
73#define ALT_I2C_SLV_RESERVE_ADDR_F_1     0x07
74// Reserved address from 0x78 to 0x7F
75#define ALT_I2C_SLV_RESERVE_ADDR_S_2     0x78
76#define ALT_I2C_SLV_RESERVE_ADDR_F_2     0x7F
77
78static ALT_STATUS_CODE alt_i2c_is_enabled_helper(ALT_I2C_DEV_t * i2c_dev);
79
80//
81// Check whether i2c space is correct.
82//
83static ALT_STATUS_CODE alt_i2c_checking(ALT_I2C_DEV_t * i2c_dev)
84{
85    if (   (i2c_dev->location != (void *)ALT_I2C_I2C0)
86        && (i2c_dev->location != (void *)ALT_I2C_I2C1)
87        && (i2c_dev->location != (void *)ALT_I2C_I2C2)
88        && (i2c_dev->location != (void *)ALT_I2C_I2C3))
89    {
90        // Incorrect device
91        return ALT_E_FALSE;
92    }
93
94    // Reset i2c module
95    return ALT_E_TRUE;
96}
97
98static ALT_STATUS_CODE alt_i2c_rstmgr_set(ALT_I2C_DEV_t * i2c_dev)
99{
100    uint32_t rst_mask = ALT_RSTMGR_PERMODRST_I2C0_SET_MSK;
101
102    // Assert the appropriate I2C module reset signal via the Reset Manager Peripheral Reset register.
103    switch ((ALT_I2C_CTLR_t)i2c_dev->location)
104    {
105    case ALT_I2C_I2C0:
106        rst_mask = ALT_RSTMGR_PERMODRST_I2C0_SET_MSK;
107        break;
108    case ALT_I2C_I2C1:
109        rst_mask = ALT_RSTMGR_PERMODRST_I2C1_SET_MSK;
110        break;
111    case ALT_I2C_I2C2:
112        rst_mask = ALT_RSTMGR_PERMODRST_I2C2_SET_MSK;
113        break;
114    case ALT_I2C_I2C3:
115        rst_mask = ALT_RSTMGR_PERMODRST_I2C3_SET_MSK;
116        break;
117    default:
118        return ALT_E_BAD_ARG;
119    }
120
121    alt_setbits_word(ALT_RSTMGR_PERMODRST_ADDR, rst_mask);
122
123    return ALT_E_SUCCESS;
124}
125
126//
127// Reset i2c module by reset manager
128//
129static ALT_STATUS_CODE alt_i2c_rstmgr_strobe(ALT_I2C_DEV_t * i2c_dev)
130{
131    uint32_t rst_mask = ALT_RSTMGR_PERMODRST_I2C0_SET_MSK;
132
133    // Assert the appropriate I2C module reset signal via the Reset Manager Peripheral Reset register.
134    switch ((ALT_I2C_CTLR_t)i2c_dev->location)
135    {
136    case ALT_I2C_I2C0:
137        rst_mask = ALT_RSTMGR_PERMODRST_I2C0_SET_MSK;
138        break;
139    case ALT_I2C_I2C1:
140        rst_mask = ALT_RSTMGR_PERMODRST_I2C1_SET_MSK;
141        break;
142    case ALT_I2C_I2C2:
143        rst_mask = ALT_RSTMGR_PERMODRST_I2C2_SET_MSK;
144        break;
145    case ALT_I2C_I2C3:
146        rst_mask = ALT_RSTMGR_PERMODRST_I2C3_SET_MSK;
147        break;
148    default:
149        return ALT_E_BAD_ARG;
150    }
151
152    alt_setbits_word(ALT_RSTMGR_PERMODRST_ADDR, rst_mask);
153
154    volatile uint32_t timeout = ALT_I2C_RESET_TMO_INIT;
155
156    // Wait while i2c modure is reseting
157    while (--timeout)
158        ;
159
160    // Deassert the appropriate I2C module reset signal via the Reset Manager Peripheral Reset register.
161    alt_clrbits_word(ALT_RSTMGR_PERMODRST_ADDR, rst_mask);
162
163    return ALT_E_SUCCESS;
164}
165
166//
167// Initialize the specified I2C controller instance for use and return a device
168// handle referencing it.
169//
170ALT_STATUS_CODE alt_i2c_init(const ALT_I2C_CTLR_t i2c,
171                             ALT_I2C_DEV_t * i2c_dev)
172{
173    // Save i2c start address to the instance
174    i2c_dev->location = (void *)i2c;
175   
176    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
177    {
178        return ALT_E_BAD_ARG;
179    }
180
181    if (alt_clk_is_enabled(ALT_CLK_L4_SP) != ALT_E_TRUE)
182    {
183        return ALT_E_BAD_CLK;
184    }
185
186    /////
187
188    ALT_STATUS_CODE status = ALT_E_SUCCESS;
189
190    if (status == ALT_E_SUCCESS)
191    {
192        status = alt_clk_freq_get(ALT_CLK_L4_SP, &i2c_dev->clock_freq);
193    }
194
195    // Reset i2c module
196    if (status == ALT_E_SUCCESS)
197    {
198        status = alt_i2c_reset(i2c_dev);
199    }
200
201    return status;
202}
203
204//
205// Reset i2c module
206//
207ALT_STATUS_CODE alt_i2c_reset(ALT_I2C_DEV_t * i2c_dev)
208{
209    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
210    {
211        return ALT_E_BAD_ARG;
212    }
213
214    ALT_STATUS_CODE status = ALT_E_SUCCESS;
215
216    bool already_enabled = (alt_i2c_is_enabled_helper(i2c_dev) == ALT_E_TRUE);
217
218    if (already_enabled)
219    {
220        // Temporarily disable controller
221        status = alt_i2c_disable(i2c_dev);
222        if (status != ALT_E_SUCCESS)
223        {
224            return status;
225        }
226    }
227   
228    // Reset i2c module by reset manager
229    alt_i2c_rstmgr_strobe(i2c_dev);
230
231    // Set optimal parameters for all i2c devices on the bus
232    ALT_I2C_MASTER_CONFIG_t cfg;
233    cfg.addr_mode      = ALT_I2C_ADDR_MODE_7_BIT;
234    cfg.speed_mode     = ALT_I2C_SPEED_STANDARD;
235    cfg.fs_spklen      = ALT_I2C_SS_DEFAULT_SPKLEN;
236    cfg.restart_enable = ALT_E_TRUE;
237    cfg.ss_scl_lcnt    = cfg.fs_scl_lcnt = 0x2FB;
238    cfg.ss_scl_hcnt    = cfg.fs_scl_hcnt = 0x341;
239
240    alt_i2c_master_config_set(i2c_dev, &cfg);
241
242    // Active master mode
243    alt_i2c_op_mode_set(i2c_dev, ALT_I2C_MODE_MASTER);
244
245    // Reset the last target address cache.
246    i2c_dev->last_target = 0xffffffff;
247
248    // Clear interrupts mask and clear interrupt status.
249    // Interrupts are unmasked by default.
250    alt_i2c_int_disable(i2c_dev, ALT_I2C_STATUS_INT_ALL);
251    alt_i2c_int_clear(i2c_dev, ALT_I2C_STATUS_INT_ALL);
252
253    if (already_enabled)
254    {
255        // Re-enable controller
256        status = alt_i2c_enable(i2c_dev);
257    }
258
259    return status;
260}
261
262//
263// Uninitialize the I2C controller referenced by the i2c_dev handle.
264//
265ALT_STATUS_CODE alt_i2c_uninit(ALT_I2C_DEV_t * i2c_dev)
266{
267    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
268    {
269        return ALT_E_BAD_ARG;
270    }
271
272    ALT_STATUS_CODE status = ALT_E_SUCCESS;
273
274    // Disable i2c controller
275    if (status == ALT_E_SUCCESS)
276    {
277        status = alt_i2c_disable(i2c_dev);
278    }
279
280    // Reset i2c module by reset manager
281    if (status == ALT_E_SUCCESS)
282    {
283        status = alt_i2c_rstmgr_set(i2c_dev);
284    }
285
286    return status;
287}
288
289//
290// Enables the I2C controller.
291//
292ALT_STATUS_CODE alt_i2c_enable(ALT_I2C_DEV_t * i2c_dev)
293{
294    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
295    {
296        return ALT_E_BAD_ARG;
297    }
298
299    // Enable DMA by default.
300    alt_write_word(ALT_I2C_DMA_CR_ADDR(i2c_dev->location),
301                   ALT_I2C_DMA_CR_TDMAE_SET_MSK | ALT_I2C_DMA_CR_RDMAE_SET_MSK);
302
303    alt_setbits_word(ALT_I2C_EN_ADDR(i2c_dev->location), ALT_I2C_EN_EN_SET_MSK);
304
305    return ALT_E_SUCCESS;
306}
307
308//
309// Disables the I2C controller
310//
311ALT_STATUS_CODE alt_i2c_disable(ALT_I2C_DEV_t * i2c_dev)
312{
313    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
314    {
315        return ALT_E_BAD_ARG;
316    }
317
318    // If i2c controller is enabled, return with sucess
319    if (alt_i2c_is_enabled_helper(i2c_dev) == ALT_E_FALSE)
320    {
321        return ALT_E_SUCCESS;
322    }
323
324    // Else clear enable bit of i2c_enable register
325    alt_clrbits_word(ALT_I2C_EN_ADDR(i2c_dev->location), ALT_I2C_EN_EN_SET_MSK);
326   
327    uint32_t timeout = ALT_I2C_MAX_T_POLL_COUNT;
328
329    // Wait to complete all transfer operations or timeout
330    while (alt_i2c_is_enabled_helper(i2c_dev) == ALT_E_TRUE)
331    {
332        // If controller still are active, return timeout error
333        if (--timeout == 0)
334        {
335            return ALT_E_TMO;
336        }
337    }
338
339    // Clear interrupt status
340    alt_i2c_int_clear(i2c_dev, ALT_I2C_STATUS_INT_ALL);
341
342    return ALT_E_SUCCESS;
343}
344
345//
346// Check whether i2c controller is enable
347//
348static ALT_STATUS_CODE alt_i2c_is_enabled_helper(ALT_I2C_DEV_t * i2c_dev)
349{
350    if (ALT_I2C_EN_STAT_IC_EN_GET(alt_read_word(ALT_I2C_EN_STAT_ADDR(i2c_dev->location))))
351    {
352        return ALT_E_TRUE;
353    }
354    else
355    {
356        return ALT_E_FALSE;
357    }
358}
359
360ALT_STATUS_CODE alt_i2c_is_enabled(ALT_I2C_DEV_t * i2c_dev)
361{
362    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
363    {
364        return ALT_E_BAD_ARG;
365    }
366
367    return alt_i2c_is_enabled_helper(i2c_dev);
368}
369
370//
371// Get config parameters from appropriate registers for master mode.
372//
373ALT_STATUS_CODE alt_i2c_master_config_get(ALT_I2C_DEV_t *i2c_dev,
374                                          ALT_I2C_MASTER_CONFIG_t* cfg)
375{
376    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
377    {
378        return ALT_E_BAD_ARG;
379    }
380
381    uint32_t cfg_register  = alt_read_word(ALT_I2C_CON_ADDR(i2c_dev->location));
382    uint32_t tar_register  = alt_read_word(ALT_I2C_TAR_ADDR(i2c_dev->location));
383    uint32_t spkl_register = alt_read_word(ALT_I2C_FS_SPKLEN_ADDR(i2c_dev->location));
384
385    cfg->speed_mode     = (ALT_I2C_SPEED_t)ALT_I2C_CON_SPEED_GET(cfg_register);
386    cfg->fs_spklen      = ALT_I2C_FS_SPKLEN_SPKLEN_GET(spkl_register);
387    cfg->restart_enable = ALT_I2C_CON_IC_RESTART_EN_GET(cfg_register);
388    cfg->addr_mode      = (ALT_I2C_ADDR_MODE_t)ALT_I2C_TAR_IC_10BITADDR_MST_GET(tar_register);
389
390    cfg->ss_scl_lcnt = alt_read_word(ALT_I2C_SS_SCL_LCNT_ADDR(i2c_dev->location));
391    cfg->ss_scl_hcnt = alt_read_word(ALT_I2C_SS_SCL_HCNT_ADDR(i2c_dev->location));
392    cfg->fs_scl_lcnt = alt_read_word(ALT_I2C_FS_SCL_LCNT_ADDR(i2c_dev->location));
393    cfg->fs_scl_hcnt = alt_read_word(ALT_I2C_FS_SCL_HCNT_ADDR(i2c_dev->location));
394
395    return ALT_E_SUCCESS;
396}
397
398//
399// Set config parameters to appropriate registers for master mode.
400//
401ALT_STATUS_CODE alt_i2c_master_config_set(ALT_I2C_DEV_t *i2c_dev,
402                                          const ALT_I2C_MASTER_CONFIG_t* cfg)
403{
404    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
405    {
406        return ALT_E_BAD_ARG;
407    }
408
409    if (   (cfg->speed_mode != ALT_I2C_SPEED_STANDARD)
410        && (cfg->speed_mode != ALT_I2C_SPEED_FAST))
411    {
412        return ALT_E_BAD_ARG;
413    }
414
415    if (   (cfg->addr_mode != ALT_I2C_ADDR_MODE_7_BIT)
416        && (cfg->addr_mode != ALT_I2C_ADDR_MODE_10_BIT))
417    {
418        return ALT_E_ARG_RANGE;
419    }
420
421    ALT_STATUS_CODE status = ALT_E_SUCCESS;
422
423    bool already_enabled = (alt_i2c_is_enabled_helper(i2c_dev) == ALT_E_TRUE);
424
425    if (already_enabled)
426    {
427        // Temporarily disable controller
428        status = alt_i2c_disable(i2c_dev);
429        if (status != ALT_E_SUCCESS)
430        {
431            return status;
432        }
433    }
434
435    // Set config parameters to appropriate registers
436
437    alt_replbits_word(ALT_I2C_CON_ADDR(i2c_dev->location),
438                      ALT_I2C_CON_SPEED_SET_MSK | ALT_I2C_CON_IC_RESTART_EN_SET_MSK,
439                      ALT_I2C_CON_SPEED_SET(cfg->speed_mode) | ALT_I2C_CON_IC_RESTART_EN_SET(cfg->restart_enable));
440   
441    alt_replbits_word(ALT_I2C_TAR_ADDR(i2c_dev->location),
442                      ALT_I2C_TAR_IC_10BITADDR_MST_SET_MSK,
443                      ALT_I2C_TAR_IC_10BITADDR_MST_SET(cfg->addr_mode));
444
445    alt_replbits_word(ALT_I2C_FS_SPKLEN_ADDR(i2c_dev->location),
446                      ALT_I2C_FS_SPKLEN_SPKLEN_SET_MSK,
447                      ALT_I2C_FS_SPKLEN_SPKLEN_SET(cfg->fs_spklen));
448   
449    alt_replbits_word(ALT_I2C_SS_SCL_LCNT_ADDR(i2c_dev->location),
450                      ALT_I2C_SS_SCL_LCNT_IC_SS_SCL_LCNT_SET_MSK,
451                      ALT_I2C_SS_SCL_LCNT_IC_SS_SCL_LCNT_SET(cfg->ss_scl_lcnt));
452    alt_replbits_word(ALT_I2C_SS_SCL_HCNT_ADDR(i2c_dev->location),
453                      ALT_I2C_SS_SCL_HCNT_IC_SS_SCL_HCNT_SET_MSK,
454                      ALT_I2C_SS_SCL_HCNT_IC_SS_SCL_HCNT_SET(cfg->ss_scl_hcnt));
455    alt_replbits_word(ALT_I2C_FS_SCL_LCNT_ADDR(i2c_dev->location),
456                      ALT_I2C_FS_SCL_LCNT_IC_FS_SCL_LCNT_SET_MSK,
457                      ALT_I2C_FS_SCL_LCNT_IC_FS_SCL_LCNT_SET(cfg->fs_scl_lcnt));
458    alt_replbits_word(ALT_I2C_FS_SCL_HCNT_ADDR(i2c_dev->location),
459                      ALT_I2C_FS_SCL_HCNT_IC_FS_SCL_HCNT_SET_MSK,
460                      ALT_I2C_FS_SCL_HCNT_IC_FS_SCL_HCNT_SET(cfg->fs_scl_hcnt));
461
462    if (already_enabled)
463    {
464        // Re-enable controller
465        status = alt_i2c_enable(i2c_dev);
466    }
467
468    return status;
469}
470
471//
472// Return bus speed by configuration of i2c controller for master mode.
473//
474ALT_STATUS_CODE alt_i2c_master_config_speed_get(ALT_I2C_DEV_t *i2c_dev,
475                                                const ALT_I2C_MASTER_CONFIG_t * cfg,
476                                                uint32_t * speed_in_hz)
477{
478    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
479    {
480        return ALT_E_BAD_ARG;
481    }
482
483    uint32_t scl_lcnt = (cfg->speed_mode == ALT_I2C_SPEED_STANDARD) ? cfg->ss_scl_lcnt : cfg->fs_scl_lcnt;
484
485    if (scl_lcnt == 0)
486    {
487        return ALT_E_BAD_ARG;
488    }
489   
490    *speed_in_hz = i2c_dev->clock_freq / (scl_lcnt << 1);
491
492    return ALT_E_SUCCESS;
493}
494
495//
496// Fill struct with configuration of i2c controller for master mode by bus speed
497//
498ALT_STATUS_CODE alt_i2c_master_config_speed_set(ALT_I2C_DEV_t *i2c_dev,
499                                                ALT_I2C_MASTER_CONFIG_t * cfg,
500                                                uint32_t speed_in_hz)   
501{
502    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
503    {
504        return ALT_E_BAD_ARG;
505    }
506
507    // If speed is not standard or fast return range error
508    if ((speed_in_hz > ALT_I2C_FS_MAX_SPEED) || (speed_in_hz < ALT_I2C_SS_MIN_SPEED))
509    {
510        return ALT_E_ARG_RANGE;
511    }
512   
513    if (speed_in_hz > ALT_I2C_FS_MIN_SPEED)
514    {
515        cfg->speed_mode = ALT_I2C_SPEED_FAST;
516        cfg->fs_spklen  = ALT_I2C_FS_DEFAULT_SPKLEN;
517    }
518    else
519    {
520        cfg->speed_mode = ALT_I2C_SPEED_STANDARD;
521        cfg->fs_spklen  = ALT_I2C_SS_DEFAULT_SPKLEN;
522    }
523
524    // <lcount> = <internal clock> / 2 * <speed, Hz>
525    uint32_t scl_lcnt = i2c_dev->clock_freq / (speed_in_hz << 1);
526
527    cfg->ss_scl_lcnt = cfg->fs_scl_lcnt = scl_lcnt;
528    // hcount = <lcount> + 70
529    cfg->ss_scl_hcnt = cfg->fs_scl_hcnt = scl_lcnt - ALT_I2C_DIFF_LCNT_HCNT;
530
531    // lcount = <internal clock> / 2 * <speed, Hz>
532
533    return ALT_E_SUCCESS;
534}
535
536//
537// Get config parameters from appropriate registers for slave mode.
538//
539ALT_STATUS_CODE alt_i2c_slave_config_get(ALT_I2C_DEV_t *i2c_dev,
540                                         ALT_I2C_SLAVE_CONFIG_t* cfg)
541{
542    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
543    {
544        return ALT_E_BAD_ARG;
545    }
546
547    uint32_t cfg_register  = alt_read_word(ALT_I2C_CON_ADDR(i2c_dev->location));
548    uint32_t sar_register  = alt_read_word(ALT_I2C_SAR_ADDR(i2c_dev->location));
549    uint32_t nack_register = alt_read_word(ALT_I2C_SLV_DATA_NACK_ONLY_ADDR(i2c_dev->location));
550
551    cfg->addr_mode   = (ALT_I2C_ADDR_MODE_t)ALT_I2C_CON_IC_10BITADDR_SLV_GET(cfg_register);
552    cfg->addr        = ALT_I2C_SAR_IC_SAR_GET(sar_register);
553    cfg->nack_enable = ALT_I2C_SLV_DATA_NACK_ONLY_NACK_GET(nack_register);
554
555    return ALT_E_SUCCESS;
556}
557
558//
559// Set config parameters to appropriate registers for slave mode.
560//
561ALT_STATUS_CODE alt_i2c_slave_config_set(ALT_I2C_DEV_t *i2c_dev,
562                                         const ALT_I2C_SLAVE_CONFIG_t* cfg)
563{
564    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
565    {
566        return ALT_E_BAD_ARG;
567    }
568
569    if (   (cfg->addr_mode != ALT_I2C_ADDR_MODE_7_BIT)
570        && (cfg->addr_mode != ALT_I2C_ADDR_MODE_10_BIT))
571    {
572        return ALT_E_BAD_ARG;
573    }
574
575    if (   (cfg->addr > ALT_I2C_SAR_IC_SAR_SET_MSK)
576        || (cfg->addr < ALT_I2C_SLV_RESERVE_ADDR_F_1)
577        || ((cfg->addr > ALT_I2C_SLV_RESERVE_ADDR_S_2) && (cfg->addr < ALT_I2C_SLV_RESERVE_ADDR_F_2))
578       )
579    {
580        return ALT_E_ARG_RANGE;
581    }
582
583    ALT_STATUS_CODE status = ALT_E_SUCCESS;
584
585    bool already_enabled = (alt_i2c_is_enabled_helper(i2c_dev) == ALT_E_TRUE);
586
587    if (already_enabled)
588    {
589        // Temporarily disable controller
590        status = alt_i2c_disable(i2c_dev);
591        if (status != ALT_E_SUCCESS)
592        {
593            return status;
594        }
595    }
596
597    alt_replbits_word(ALT_I2C_CON_ADDR(i2c_dev->location),
598                      ALT_I2C_CON_IC_10BITADDR_SLV_SET_MSK,
599                      ALT_I2C_CON_IC_10BITADDR_SLV_SET(cfg->addr_mode));
600
601    alt_replbits_word(ALT_I2C_SAR_ADDR(i2c_dev->location),
602                      ALT_I2C_SAR_IC_SAR_SET_MSK,
603                      ALT_I2C_SAR_IC_SAR_SET(cfg->addr));
604    alt_replbits_word(ALT_I2C_SLV_DATA_NACK_ONLY_ADDR(i2c_dev->location),
605                      ALT_I2C_SLV_DATA_NACK_ONLY_NACK_SET_MSK,
606                      ALT_I2C_SLV_DATA_NACK_ONLY_NACK_SET(cfg->nack_enable));
607
608    if (already_enabled)
609    {
610        // Re-enable controller
611        status = alt_i2c_enable(i2c_dev);
612    }
613
614    return status;
615}
616
617//
618// Get hold time (use during slave mode)
619//
620ALT_STATUS_CODE alt_i2c_sda_hold_time_get(ALT_I2C_DEV_t *i2c_dev,
621                                          uint16_t *hold_time)
622{
623    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
624    {
625        return ALT_E_BAD_ARG;
626    }
627
628    uint32_t sda_register = alt_read_word(ALT_I2C_SDA_HOLD_ADDR(i2c_dev->location));
629    *hold_time = ALT_I2C_SDA_HOLD_IC_SDA_HOLD_GET(sda_register);
630
631    return ALT_E_SUCCESS;
632}
633   
634//
635// Set hold time (use during slave mode)
636//
637ALT_STATUS_CODE alt_i2c_sda_hold_time_set(ALT_I2C_DEV_t *i2c_dev,
638                                          const uint16_t hold_time)
639{
640    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
641    {
642        return ALT_E_BAD_ARG;
643    }
644
645    ALT_STATUS_CODE status = ALT_E_SUCCESS;
646
647    bool already_enabled = (alt_i2c_is_enabled_helper(i2c_dev) == ALT_E_TRUE);
648
649    if (already_enabled)
650    {
651        // Temporarily disable controller
652        status = alt_i2c_disable(i2c_dev);
653        if (status != ALT_E_SUCCESS)
654        {
655            return status;
656        }
657    }
658
659    alt_replbits_word(ALT_I2C_SDA_HOLD_ADDR(i2c_dev->location),
660                      ALT_I2C_SDA_HOLD_IC_SDA_HOLD_SET_MSK,
661                      ALT_I2C_SDA_HOLD_IC_SDA_HOLD_SET(hold_time));
662
663    if (already_enabled)
664    {
665        // Re-enable controller
666        status = alt_i2c_enable(i2c_dev);
667    }
668
669    return status;
670}
671   
672//
673// Gets the current operational mode of the I2C controller.
674//
675ALT_STATUS_CODE alt_i2c_op_mode_get(ALT_I2C_DEV_t *i2c_dev,
676                                    ALT_I2C_MODE_t* mode)
677{
678    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
679    {
680        return ALT_E_BAD_ARG;
681    }
682   
683    uint32_t cfg_register = alt_read_word(ALT_I2C_CON_ADDR(i2c_dev->location));
684    uint32_t mst_mod_stat = ALT_I2C_CON_MST_MOD_GET(cfg_register);
685    uint32_t slv_mod_stat = ALT_I2C_CON_IC_SLV_DIS_GET(cfg_register);
686
687    // Return error if master and slave modes enable or disable at the same time
688    if (   (mst_mod_stat == ALT_I2C_CON_MST_MOD_E_EN  && slv_mod_stat == ALT_I2C_CON_IC_SLV_DIS_E_EN)
689        || (mst_mod_stat == ALT_I2C_CON_MST_MOD_E_DIS && slv_mod_stat == ALT_I2C_CON_IC_SLV_DIS_E_DIS))
690    {
691        return ALT_E_ERROR;
692    }
693
694    *mode = (ALT_I2C_MODE_t)mst_mod_stat;
695
696    return ALT_E_SUCCESS;
697}
698   
699//
700// Sets the operational mode of the I2C controller.
701//
702ALT_STATUS_CODE alt_i2c_op_mode_set(ALT_I2C_DEV_t *i2c_dev,
703                                    const ALT_I2C_MODE_t mode)   
704{
705    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
706    {
707        return ALT_E_BAD_ARG;
708    }
709
710    if (   (mode != ALT_I2C_MODE_MASTER)
711        && (mode != ALT_I2C_MODE_SLAVE))
712    {
713        return ALT_E_ARG_RANGE;
714    }
715   
716    ALT_STATUS_CODE status = ALT_E_SUCCESS;
717
718    bool already_enabled = (alt_i2c_is_enabled_helper(i2c_dev) == ALT_E_TRUE);
719
720    if (already_enabled)
721    {
722        // Temporarily disable controller
723        status = alt_i2c_disable(i2c_dev);
724        if (status != ALT_E_SUCCESS)
725        {
726            return status;
727        }
728    }
729
730    if (mode == ALT_I2C_MODE_MASTER)
731    {
732        // Enable master, disable slave
733        alt_replbits_word(ALT_I2C_CON_ADDR(i2c_dev->location),
734                          ALT_I2C_CON_IC_SLV_DIS_SET_MSK | ALT_I2C_CON_MST_MOD_SET_MSK,
735                          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));
736    }
737    else if (mode == ALT_I2C_MODE_SLAVE)
738    {
739        // Enable slave, disable master
740        alt_replbits_word(ALT_I2C_CON_ADDR(i2c_dev->location),
741                          ALT_I2C_CON_IC_SLV_DIS_SET_MSK | ALT_I2C_CON_MST_MOD_SET_MSK,
742                          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));
743    }
744       
745    if (already_enabled)
746    {
747        // Re-enable controller
748        status = alt_i2c_enable(i2c_dev);
749    }
750   
751    return status;
752}
753   
754//
755// Returns ALT_E_TRUE if the I2C controller is busy
756//
757ALT_STATUS_CODE alt_i2c_is_busy(ALT_I2C_DEV_t *i2c_dev)
758{
759    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
760    {
761        return ALT_E_BAD_ARG;
762    }
763   
764    if ( ALT_I2C_STAT_ACTIVITY_GET(alt_read_word(ALT_I2C_STAT_ADDR(i2c_dev->location))))
765    {
766        return ALT_E_TRUE;
767    }
768    else
769    {
770        return ALT_E_FALSE;
771    }
772}
773
774//
775// This function reads a single data byte from the receive FIFO.
776//
777ALT_STATUS_CODE alt_i2c_read(ALT_I2C_DEV_t *i2c_dev, uint8_t *value)
778{
779    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
780    {
781        return ALT_E_BAD_ARG;
782    }
783
784    if (alt_i2c_is_enabled_helper(i2c_dev) == ALT_E_FALSE)
785    {
786        return ALT_E_ERROR;
787    }
788
789    *value = (uint8_t)(ALT_I2C_DATA_CMD_DAT_GET(alt_read_word(ALT_I2C_DATA_CMD_ADDR(i2c_dev->location))));
790
791    return ALT_E_SUCCESS;
792}
793
794//
795// This function writes a single data byte to the transmit FIFO.
796//
797ALT_STATUS_CODE alt_i2c_write(ALT_I2C_DEV_t *i2c_dev, const uint8_t value)
798{
799    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
800    {
801        return ALT_E_BAD_ARG;
802    }
803
804    if (alt_i2c_is_enabled_helper(i2c_dev) == ALT_E_FALSE)
805    {
806        return ALT_E_ERROR;
807    }
808
809    alt_write_word(ALT_I2C_DATA_CMD_ADDR(i2c_dev->location),
810                   ALT_I2C_DATA_CMD_DAT_SET(value));
811
812    return ALT_E_SUCCESS;
813}
814
815//
816// This function acts in the role of a slave-receiver by receiving a single data
817// byte from the I2C bus in response to a write command from the master.
818//
819ALT_STATUS_CODE alt_i2c_slave_receive(ALT_I2C_DEV_t * i2c_dev,
820                                      uint8_t * data)
821{
822    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
823    {
824        return ALT_E_BAD_ARG;
825    }
826
827    if (alt_i2c_is_enabled_helper(i2c_dev) == ALT_E_FALSE)
828    {
829        return ALT_E_ERROR;
830    }
831
832    // alt_i2c_read().
833    *data = (uint8_t)(ALT_I2C_DATA_CMD_DAT_GET(alt_read_word(ALT_I2C_DATA_CMD_ADDR(i2c_dev->location))));
834
835    return ALT_E_SUCCESS;
836}
837
838//
839// This function acts in the role of a slave-transmitter by transmitting a single
840// data byte to the I2C bus in response to a read request from the master.
841//
842ALT_STATUS_CODE alt_i2c_slave_transmit(ALT_I2C_DEV_t *i2c_dev,
843                                       const uint8_t data)
844{
845    // Send bulk of data with one value
846    return alt_i2c_slave_bulk_transmit(i2c_dev, &data, 1);
847}
848
849//
850// This function acts in the role of a slave-transmitter by transmitting data in
851// bulk to the I2C bus in response to a series of read requests from a master.
852//
853ALT_STATUS_CODE alt_i2c_slave_bulk_transmit(ALT_I2C_DEV_t *i2c_dev,
854                                            const void * data,
855                                            const size_t size)
856{
857    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
858    {
859        return ALT_E_BAD_ARG;
860    }
861
862    if (alt_i2c_is_enabled_helper(i2c_dev) == ALT_E_FALSE)
863    {
864        return ALT_E_ERROR;
865    }
866
867    const char * buffer = data;
868    for (size_t i = 0; i < size; ++i)
869    {
870        alt_write_word(ALT_I2C_DATA_CMD_ADDR(i2c_dev->location),
871                         ALT_I2C_DATA_CMD_DAT_SET(*buffer)
872                       | ALT_I2C_DATA_CMD_STOP_SET(false)
873                       | ALT_I2C_DATA_CMD_RESTART_SET(false));
874
875        ++buffer;
876    }
877
878    return ALT_E_SUCCESS;
879}
880
881ALT_STATUS_CODE alt_i2c_master_target_get(ALT_I2C_DEV_t * i2c_dev, uint32_t * target_addr)
882{
883    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
884    {
885        return ALT_E_BAD_ARG;
886    }
887
888    *target_addr = i2c_dev->last_target;
889
890    return ALT_E_SUCCESS;
891}
892
893ALT_STATUS_CODE alt_i2c_master_target_set(ALT_I2C_DEV_t * i2c_dev, uint32_t target_addr)
894{
895    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
896    {
897        return ALT_E_BAD_ARG;
898    }
899
900    ALT_STATUS_CODE status = ALT_E_SUCCESS;
901
902    // Wait until the TX FIFO flushes. This is needed because TAR can only be
903    // updated under specific conditions.
904
905    if (target_addr != i2c_dev->last_target)
906    {
907        uint32_t timeout = 10000;
908
909        while (alt_i2c_tx_fifo_is_empty(i2c_dev) == ALT_E_FALSE)
910        {
911            if (--timeout == 0)
912            {
913                status = ALT_E_TMO;
914                break;
915            }
916        }
917
918        // Update target address
919        if (status == ALT_E_SUCCESS)
920        {
921            alt_replbits_word(ALT_I2C_TAR_ADDR(i2c_dev->location),
922                              ALT_I2C_TAR_IC_TAR_SET_MSK,
923                              ALT_I2C_TAR_IC_TAR_SET(target_addr));
924
925            i2c_dev->last_target = target_addr;
926        }
927    }
928
929    return status;
930}
931
932//
933// Write bulk of data or read requests to tx fifo
934//
935static ALT_STATUS_CODE alt_i2c_master_transmit_helper(ALT_I2C_DEV_t * i2c_dev,
936                                                      const uint8_t * buffer,
937                                                      size_t size,
938                                                      bool issue_restart,
939                                                      bool issue_stop)
940{
941    ALT_STATUS_CODE status = ALT_E_SUCCESS;
942
943    // If the rested size is 1, the restart and stop may need to be sent in the
944    // same frame.
945    if (size == 1)
946    {
947        if (status == ALT_E_SUCCESS)
948        {
949            status = alt_i2c_issue_write(i2c_dev,
950                                         *buffer,
951                                         issue_restart,
952                                         issue_stop);
953
954            ++buffer;
955            --size;
956        }
957    }
958    else
959    {
960        // First byte
961
962        if (status == ALT_E_SUCCESS)
963        {
964            status = alt_i2c_issue_write(i2c_dev,
965                                         *buffer,
966                                         issue_restart,
967                                         false);
968
969            ++buffer;
970            --size;
971        }
972
973        /////
974           
975        // Middle byte(s)
976
977        if (status == ALT_E_SUCCESS)
978        {
979            uint32_t timeout = size * 10000;
980
981            while (size > 1)
982            {
983                uint32_t level = 0;
984                status = alt_i2c_tx_fifo_level_get(i2c_dev, &level);
985                if (status != ALT_E_SUCCESS)
986                {
987                    break;
988                }
989
990                uint32_t space = ALT_I2C_TX_FIFO_NUM_ENTRIES - level;
991                if (space == 0)
992                {
993                    if (--timeout == 0)
994                    {
995                        status = ALT_E_TMO;
996                        break;
997                    }
998
999                    continue;
1000                }
1001               
1002                // Subtract 1 because the last byte may need to issue_stop
1003                space = MIN(space, size - 1);
1004
1005                for (uint32_t i = 0; i < space; ++i)
1006                {
1007                    alt_write_word(ALT_I2C_DATA_CMD_ADDR(i2c_dev->location),
1008                                     ALT_I2C_DATA_CMD_DAT_SET(*buffer)
1009                                   | ALT_I2C_DATA_CMD_STOP_SET(false)
1010                                   | ALT_I2C_DATA_CMD_RESTART_SET(false));
1011
1012                    ++buffer;
1013                }
1014
1015                size -= space;
1016            }
1017        }
1018
1019        /////
1020
1021        // Last byte
1022
1023        if (status == ALT_E_SUCCESS)
1024        {
1025            status = alt_i2c_issue_write(i2c_dev,
1026                                         *buffer,
1027                                         false,
1028                                         issue_stop);
1029
1030            ++buffer;
1031            --size;
1032        }
1033    }
1034
1035    return status;
1036}
1037
1038//
1039// This function acts in the role of a master-transmitter by issuing a write
1040// command and transmitting data to the I2C bus.
1041//
1042ALT_STATUS_CODE alt_i2c_master_transmit(ALT_I2C_DEV_t *i2c_dev,
1043                                        const void * data,
1044                                        const size_t size,
1045                                        const bool issue_restart,
1046                                        const bool issue_stop)
1047{
1048    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
1049    {
1050        return ALT_E_BAD_ARG;
1051    }
1052
1053    if (alt_i2c_is_enabled_helper(i2c_dev) == ALT_E_FALSE)
1054    {
1055        return ALT_E_ERROR;
1056    }
1057
1058    if (size == 0)
1059    {
1060        return ALT_E_SUCCESS;
1061    }
1062   
1063    ALT_STATUS_CODE status = ALT_E_SUCCESS;
1064
1065    if (status == ALT_E_SUCCESS)
1066    {
1067        status = alt_i2c_master_transmit_helper(i2c_dev,
1068                                                data,
1069                                                size,
1070                                                issue_restart,
1071                                                issue_stop);
1072    }
1073
1074    // Need reset for set i2c bus in idle state
1075    if (status == ALT_E_TMO)
1076    {
1077        alt_i2c_reset(i2c_dev);
1078    }
1079
1080    return status;
1081}
1082
1083ALT_STATUS_CODE alt_i2c_master_receive_helper(ALT_I2C_DEV_t *i2c_dev,
1084                                              uint8_t * buffer,
1085                                              size_t size,
1086                                              bool issue_restart,
1087                                              bool issue_stop)
1088{
1089    ALT_STATUS_CODE status = ALT_E_SUCCESS;
1090
1091    uint32_t issue_left = size;
1092    uint32_t data_left  = size;
1093
1094    uint32_t timeout = size * 10000;
1095
1096    // Wait for space in the TX FIFO to send the first read request.
1097    // This is needed because the issue restart need to be set.
1098
1099    if (issue_restart == true)
1100    {
1101        if (status == ALT_E_SUCCESS)
1102        {
1103            while (alt_i2c_tx_fifo_is_full(i2c_dev) == ALT_E_TRUE)
1104            {
1105                if (--timeout == 0)
1106                {
1107                    status = ALT_E_TMO;
1108                    break;
1109                }
1110            }
1111        }
1112
1113        // Now send the first request.
1114
1115        if (status == ALT_E_SUCCESS)
1116        {
1117            alt_write_word(ALT_I2C_DATA_CMD_ADDR(i2c_dev->location),
1118                             ALT_I2C_DATA_CMD_CMD_SET(ALT_I2C_DATA_CMD_CMD_E_RD)
1119                           | ALT_I2C_DATA_CMD_STOP_SET(false)
1120                           | ALT_I2C_DATA_CMD_RESTART_SET(issue_restart));
1121
1122            --issue_left;
1123        }
1124    }
1125
1126    // For the rest of the data ...
1127
1128    while (data_left > 0)
1129    {
1130        if (status != ALT_E_SUCCESS)
1131        {
1132            break;
1133        }
1134
1135        // Top up the TX FIFO with read issues
1136        // Special consideration must be made for the last read issue, as it may be necessary to "issue_stop".
1137
1138        if (issue_left > 0)
1139        {
1140            uint32_t level = 0;
1141            status = alt_i2c_tx_fifo_level_get(i2c_dev, &level);
1142            if (status != ALT_E_SUCCESS)
1143            {
1144                break;
1145            }
1146
1147            uint32_t space = ALT_I2C_TX_FIFO_NUM_ENTRIES - level;
1148
1149            if (issue_left == 1)
1150            {
1151                if (space > 0)
1152                {
1153                    space = 1;
1154
1155                    alt_write_word(ALT_I2C_DATA_CMD_ADDR(i2c_dev->location),
1156                                   ALT_I2C_DATA_CMD_CMD_SET(ALT_I2C_DATA_CMD_CMD_E_RD)
1157                                   | ALT_I2C_DATA_CMD_STOP_SET(issue_stop)
1158                                   | ALT_I2C_DATA_CMD_RESTART_SET(false));
1159                }
1160            }
1161            else
1162            {
1163                // Send up to issue_left - 1, as the last issue has special considerations.
1164                space = MIN(issue_left - 1, space);
1165
1166                for (uint32_t i = 0; i < space; ++i)
1167                {
1168                    alt_write_word(ALT_I2C_DATA_CMD_ADDR(i2c_dev->location),
1169                                   ALT_I2C_DATA_CMD_CMD_SET(ALT_I2C_DATA_CMD_CMD_E_RD)
1170                                   | ALT_I2C_DATA_CMD_STOP_SET(false)
1171                                   | ALT_I2C_DATA_CMD_RESTART_SET(false));
1172                }
1173            }
1174
1175            issue_left -= space;
1176        }
1177
1178        // Read out the resulting received data as they come in.
1179
1180        if (data_left > 0)
1181        {
1182            uint32_t level = 0;
1183            status = alt_i2c_rx_fifo_level_get(i2c_dev, &level);
1184            if (status != ALT_E_SUCCESS)
1185            {
1186                break;
1187            }
1188
1189            if (level == 0)
1190            {
1191                if (--timeout == 0)
1192                {
1193                    status = ALT_E_TMO;
1194                    break;
1195                }
1196            }
1197
1198            level = MIN(data_left, level);
1199
1200            for (uint32_t i = 0; i < level; ++i)
1201            {
1202                // alt_i2c_read(i2c_dev, &value);
1203                *buffer = (uint8_t)(ALT_I2C_DATA_CMD_DAT_GET(alt_read_word(ALT_I2C_DATA_CMD_ADDR(i2c_dev->location))));
1204                ++buffer;
1205            }
1206
1207            data_left -= level;
1208        }
1209    }
1210
1211
1212    return status;
1213}
1214
1215//
1216// This function acts in the role of a master-receiver by receiving one or more
1217// data bytes transmitted from a slave in response to read requests issued from
1218// this master.
1219//
1220ALT_STATUS_CODE alt_i2c_master_receive(ALT_I2C_DEV_t *i2c_dev,
1221                                       void * data,
1222                                       const size_t size,
1223                                       const bool issue_restart,
1224                                       const bool issue_stop)
1225{
1226    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
1227    {
1228        return ALT_E_BAD_ARG;
1229    }
1230
1231    if (alt_i2c_is_enabled_helper(i2c_dev) == ALT_E_FALSE)
1232    {
1233        return ALT_E_ERROR;
1234    }
1235
1236    if (size == 0)
1237    {
1238        return ALT_E_SUCCESS;
1239    }
1240
1241    ALT_STATUS_CODE status = ALT_E_SUCCESS;
1242
1243    // This I2C controller requires that a read issue be performed for each byte requested.
1244    // Read issue takes space in the TX FIFO, which may asynchronously handling a previous request.
1245
1246    if (size == 1)
1247    {
1248        uint32_t timeout = 10000;
1249
1250        // Wait for space in the TX FIFO to send the read request.
1251
1252        if (status == ALT_E_SUCCESS)
1253        {
1254            while (alt_i2c_tx_fifo_is_full(i2c_dev) == ALT_E_TRUE)
1255            {
1256                if (--timeout == 0)
1257                {
1258                    status = ALT_E_TMO;
1259                    break;
1260                }
1261            }
1262        }
1263
1264        // Issue the read request in the TX FIFO.
1265
1266        if (status == ALT_E_SUCCESS)
1267        {
1268            alt_write_word(ALT_I2C_DATA_CMD_ADDR(i2c_dev->location),
1269                             ALT_I2C_DATA_CMD_CMD_SET(ALT_I2C_DATA_CMD_CMD_E_RD)
1270                           | ALT_I2C_DATA_CMD_STOP_SET(issue_stop)
1271                           | ALT_I2C_DATA_CMD_RESTART_SET(issue_restart));
1272
1273        }
1274
1275        // Wait for data to become available in the RX FIFO.
1276
1277        if (status == ALT_E_SUCCESS)
1278        {
1279            while (alt_i2c_rx_fifo_is_empty(i2c_dev) == ALT_E_TRUE)
1280            {
1281                if (--timeout == 0)
1282                {
1283                    status = ALT_E_TMO;
1284                    break;
1285                }
1286            }
1287        }
1288
1289        // Read the RX FIFO.
1290
1291        if (status == ALT_E_SUCCESS)
1292        {
1293            uint8_t * buffer = data;
1294            *buffer = (uint8_t)(ALT_I2C_DATA_CMD_DAT_GET(alt_read_word(ALT_I2C_DATA_CMD_ADDR(i2c_dev->location))));
1295        }
1296    }
1297    else if (size <= 64)
1298    {
1299        if (status == ALT_E_SUCCESS)
1300        {
1301            status = alt_i2c_master_receive_helper(i2c_dev,
1302                                                   data,
1303                                                   size,
1304                                                   issue_restart,
1305                                                   issue_stop);
1306        }
1307    }
1308    else
1309    {
1310        uint8_t * buffer = data;
1311        size_t size_left = size;
1312
1313        // Send the first ALT_I2C_RX_FIFO_NUM_ENTRIES items
1314
1315        if (status == ALT_E_SUCCESS)
1316        {
1317            status = alt_i2c_master_receive_helper(i2c_dev,
1318                                                   buffer,
1319                                                   ALT_I2C_RX_FIFO_NUM_ENTRIES,
1320                                                   issue_restart,
1321                                                   false);
1322        }
1323
1324        buffer    += ALT_I2C_RX_FIFO_NUM_ENTRIES;
1325        size_left -= ALT_I2C_RX_FIFO_NUM_ENTRIES;
1326
1327        while (size_left > 0)
1328        {
1329            if (size_left > ALT_I2C_RX_FIFO_NUM_ENTRIES)
1330            {
1331                if (status == ALT_E_SUCCESS)
1332                {
1333                    status = alt_i2c_master_receive_helper(i2c_dev,
1334                                                           buffer,
1335                                                           ALT_I2C_RX_FIFO_NUM_ENTRIES,
1336                                                           false,
1337                                                           false);
1338                }
1339
1340                buffer    += ALT_I2C_RX_FIFO_NUM_ENTRIES;
1341                size_left -= ALT_I2C_RX_FIFO_NUM_ENTRIES;
1342            }
1343            else
1344            {
1345                if (status == ALT_E_SUCCESS)
1346                {
1347                    status = alt_i2c_master_receive_helper(i2c_dev,
1348                                                           buffer,
1349                                                           size_left,
1350                                                           false,
1351                                                           issue_stop);
1352                }
1353
1354                size_left = 0;
1355            }
1356
1357            if (status != ALT_E_SUCCESS)
1358            {
1359                break;
1360            }
1361        }
1362    }
1363
1364    // Need reset for set i2c bus in idle state
1365    if (status == ALT_E_TMO)
1366    {
1367        alt_i2c_reset(i2c_dev);
1368    }
1369
1370    return status;
1371}
1372
1373//
1374// This function causes the I2C controller master to send data to the bus.
1375//
1376ALT_STATUS_CODE alt_i2c_issue_write(ALT_I2C_DEV_t *i2c_dev,
1377                                    const uint8_t value,
1378                                    const bool issue_restart,
1379                                    const bool issue_stop)
1380{
1381    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
1382    {
1383        return ALT_E_BAD_ARG;
1384    }
1385
1386    if (alt_i2c_is_enabled_helper(i2c_dev) == ALT_E_FALSE)
1387    {
1388        return ALT_E_ERROR;
1389    }
1390
1391    // Wait until there is a FIFO spot
1392    uint32_t timeout = 10000;
1393
1394    while (alt_i2c_tx_fifo_is_full(i2c_dev) == ALT_E_TRUE)
1395    {
1396        if (--timeout == 0)
1397        {
1398            return ALT_E_TMO;
1399        }
1400    }
1401
1402    alt_write_word(ALT_I2C_DATA_CMD_ADDR(i2c_dev->location),
1403                     ALT_I2C_DATA_CMD_DAT_SET(value)
1404                   | ALT_I2C_DATA_CMD_STOP_SET(issue_stop)
1405                   | ALT_I2C_DATA_CMD_RESTART_SET(issue_restart));
1406
1407    return ALT_E_SUCCESS;
1408}
1409
1410//
1411// This function causes the I2C controller master to issue a READ request on the bus.
1412//
1413ALT_STATUS_CODE alt_i2c_issue_read(ALT_I2C_DEV_t *i2c_dev,
1414                                   const bool issue_restart,
1415                                   const bool issue_stop)
1416{
1417    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
1418    {
1419        return ALT_E_BAD_ARG;
1420    }
1421
1422    if (alt_i2c_is_enabled_helper(i2c_dev) == ALT_E_FALSE)
1423    {
1424        return ALT_E_ERROR;
1425    }
1426
1427    // Wait until there is a FIFO spot
1428    uint32_t timeout = 10000;
1429
1430    while (alt_i2c_tx_fifo_is_full(i2c_dev) == ALT_E_TRUE)
1431    {
1432        if (--timeout == 0)
1433        {
1434            return ALT_E_TMO;
1435        }
1436    }
1437
1438    alt_write_word(ALT_I2C_DATA_CMD_ADDR(i2c_dev->location),
1439                     ALT_I2C_DATA_CMD_CMD_SET(ALT_I2C_DATA_CMD_CMD_E_RD)
1440                   | ALT_I2C_DATA_CMD_STOP_SET(issue_stop)
1441                   | ALT_I2C_DATA_CMD_RESTART_SET(issue_restart));
1442
1443    return ALT_E_SUCCESS;
1444}
1445
1446//
1447// This function acts in the role of a master-transmitter by issuing a general
1448// call command to all devices connected to the I2C bus.
1449//
1450ALT_STATUS_CODE alt_i2c_master_general_call(ALT_I2C_DEV_t *i2c_dev,
1451                                            const void * data,
1452                                            const size_t size,
1453                                            const bool issue_restart,
1454                                            const bool issue_stop)
1455{
1456    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
1457    {
1458        return ALT_E_BAD_ARG;
1459    }
1460
1461    if (alt_i2c_is_enabled_helper(i2c_dev) == ALT_E_FALSE)
1462    {
1463        return ALT_E_ERROR;
1464    }
1465
1466    ALT_STATUS_CODE status = ALT_E_SUCCESS;
1467
1468    if (status == ALT_E_SUCCESS)
1469    {
1470        status = alt_i2c_master_target_set(i2c_dev, 0);
1471    }
1472
1473    // General call is a transmit in master mode (target address are not used during it)
1474    if (status == ALT_E_SUCCESS)
1475    {
1476        status = alt_i2c_master_transmit(i2c_dev, data, size, issue_restart, issue_stop);
1477    }
1478
1479    return status;
1480}
1481
1482/////
1483
1484ALT_STATUS_CODE alt_i2c_general_call_ack_disable(ALT_I2C_DEV_t *i2c_dev)
1485{
1486    ALT_STATUS_CODE status = ALT_E_SUCCESS;
1487
1488    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
1489    {
1490        return ALT_E_BAD_ARG;
1491    }
1492
1493    bool already_enabled = (alt_i2c_is_enabled_helper(i2c_dev) == ALT_E_TRUE);
1494
1495    if (already_enabled)
1496    {
1497        // Temporarily disable controller
1498        status = alt_i2c_disable(i2c_dev);
1499        if (status != ALT_E_SUCCESS)
1500        {
1501            return status;
1502        }
1503    }
1504
1505    alt_replbits_word(ALT_I2C_TAR_ADDR(i2c_dev->location),
1506                      ALT_I2C_TAR_SPECIAL_SET_MSK | ALT_I2C_TAR_GC_OR_START_SET_MSK,
1507                      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));
1508
1509    if (already_enabled)
1510    {
1511        // Re-enable controller
1512        status = alt_i2c_enable(i2c_dev);
1513    }
1514
1515    return status;
1516}
1517
1518//
1519// Enables the I2C controller to respond with an ACK when it receives a General
1520// Call address.
1521//
1522ALT_STATUS_CODE alt_i2c_general_call_ack_enable(ALT_I2C_DEV_t *i2c_dev)
1523{
1524    ALT_STATUS_CODE status = ALT_E_SUCCESS;
1525
1526    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
1527    {
1528        return ALT_E_BAD_ARG;
1529    }
1530
1531    bool already_enabled = (alt_i2c_is_enabled_helper(i2c_dev) == ALT_E_TRUE);
1532
1533    if (already_enabled)
1534    {
1535        // Temporarily disable controller
1536        status = alt_i2c_disable(i2c_dev);
1537        if (status != ALT_E_SUCCESS)
1538        {
1539            return status;
1540        }
1541    }
1542
1543    alt_replbits_word(ALT_I2C_TAR_ADDR(i2c_dev->location),
1544                      ALT_I2C_TAR_SPECIAL_SET_MSK | ALT_I2C_TAR_GC_OR_START_SET_MSK,
1545                      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));
1546
1547    if (already_enabled)
1548    {
1549        // Re-enable controller
1550        status = alt_i2c_enable(i2c_dev);
1551    }
1552
1553    return status;
1554}
1555
1556//
1557// Returns ALT_E_TRUE if the I2C controller is enabled to respond to General Call
1558// addresses.
1559//
1560ALT_STATUS_CODE alt_i2c_general_call_ack_is_enabled(ALT_I2C_DEV_t *i2c_dev)
1561{
1562    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
1563    {
1564        return ALT_E_BAD_ARG;
1565    }
1566
1567    uint32_t tar_register = alt_read_word(ALT_I2C_TAR_ADDR(i2c_dev->location));
1568   
1569    if (   (ALT_I2C_TAR_SPECIAL_GET(tar_register)     == ALT_I2C_TAR_SPECIAL_E_GENCALL)
1570        && (ALT_I2C_TAR_GC_OR_START_GET(tar_register) == ALT_I2C_TAR_GC_OR_START_E_GENCALL)
1571       )
1572    {
1573        return ALT_E_TRUE;
1574    }
1575    else
1576    {
1577        return ALT_E_FALSE;
1578    }
1579}
1580
1581//
1582// Returns the current I2C controller interrupt status conditions.
1583//
1584ALT_STATUS_CODE alt_i2c_int_status_get(ALT_I2C_DEV_t *i2c_dev,
1585                                       uint32_t *status)
1586{
1587    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
1588    {
1589        return ALT_E_BAD_ARG;
1590    }
1591
1592    *status = alt_read_word(ALT_I2C_INTR_STAT_ADDR(i2c_dev->location));
1593
1594    return ALT_E_SUCCESS;
1595}
1596
1597//
1598// Returns the I2C controller raw interrupt status conditions irrespective of
1599// the interrupt status condition enablement state.
1600//
1601ALT_STATUS_CODE alt_i2c_int_raw_status_get(ALT_I2C_DEV_t *i2c_dev,
1602                                           uint32_t *status)
1603{
1604    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
1605    {
1606        return ALT_E_BAD_ARG;
1607    }
1608
1609    *status = alt_read_word(ALT_I2C_RAW_INTR_STAT_ADDR(i2c_dev->location));
1610
1611    return ALT_E_SUCCESS;
1612}
1613
1614//
1615// Clears the specified I2C controller interrupt status conditions identified
1616// in the mask.
1617//
1618ALT_STATUS_CODE alt_i2c_int_clear(ALT_I2C_DEV_t *i2c_dev, const uint32_t mask)
1619{
1620    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
1621    {
1622        return ALT_E_BAD_ARG;
1623    }
1624
1625    if (mask == ALT_I2C_STATUS_INT_ALL)
1626    {
1627        alt_read_word(ALT_I2C_CLR_INTR_ADDR(i2c_dev->location));
1628        return ALT_E_SUCCESS;
1629    }
1630   
1631    // For different status clear different register
1632
1633    if (mask & ALT_I2C_STATUS_RX_UNDER)
1634    {
1635        alt_read_word(ALT_I2C_CLR_RX_UNDER_ADDR(i2c_dev->location));
1636    }
1637    if (mask & ALT_I2C_STATUS_RX_OVER)
1638    {
1639        alt_read_word(ALT_I2C_CLR_RX_OVER_ADDR(i2c_dev->location));
1640    }
1641    if (mask & ALT_I2C_STATUS_TX_OVER)
1642    {
1643        alt_read_word(ALT_I2C_CLR_TX_OVER_ADDR(i2c_dev->location));
1644    }
1645    if (mask & ALT_I2C_STATUS_RD_REQ)
1646    {
1647        alt_read_word(ALT_I2C_CLR_RD_REQ_ADDR(i2c_dev->location));
1648    }
1649    if (mask & ALT_I2C_STATUS_TX_ABORT)
1650    {
1651        alt_read_word(ALT_I2C_CLR_TX_ABRT_ADDR(i2c_dev->location));
1652    }
1653    if (mask & ALT_I2C_STATUS_RX_DONE)
1654    {
1655        alt_read_word(ALT_I2C_CLR_RX_DONE_ADDR(i2c_dev->location));
1656    }
1657    if (mask & ALT_I2C_STATUS_ACTIVITY)
1658    {
1659        alt_read_word(ALT_I2C_CLR_ACTIVITY_ADDR(i2c_dev->location));
1660    }
1661    if (mask & ALT_I2C_STATUS_STOP_DET)
1662    {
1663        alt_read_word(ALT_I2C_CLR_STOP_DET_ADDR(i2c_dev->location));
1664    }
1665    if (mask & ALT_I2C_STATUS_START_DET)
1666    {
1667        alt_read_word(ALT_I2C_CLR_START_DET_ADDR(i2c_dev->location));
1668    }
1669    if (mask & ALT_I2C_STATUS_INT_CALL)
1670    {
1671        alt_read_word(ALT_I2C_CLR_GEN_CALL_ADDR(i2c_dev->location));
1672    }
1673
1674    return ALT_E_SUCCESS;
1675}
1676
1677//
1678// Disable the specified I2C controller interrupt status conditions identified in
1679// the mask.
1680//
1681ALT_STATUS_CODE alt_i2c_int_disable(ALT_I2C_DEV_t *i2c_dev, const uint32_t mask)
1682{
1683    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
1684    {
1685        return ALT_E_BAD_ARG;
1686    }
1687
1688    alt_clrbits_word(ALT_I2C_INTR_MSK_ADDR(i2c_dev->location), mask);   
1689
1690    return ALT_E_SUCCESS;
1691}
1692
1693//
1694// Enable the specified I2C controller interrupt status conditions identified in
1695// the mask.
1696//
1697ALT_STATUS_CODE alt_i2c_int_enable(ALT_I2C_DEV_t *i2c_dev, const uint32_t mask)
1698{
1699    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
1700    {
1701        return ALT_E_BAD_ARG;
1702    }
1703
1704    alt_setbits_word(ALT_I2C_INTR_MSK_ADDR(i2c_dev->location), mask);
1705
1706    return ALT_E_SUCCESS;
1707}
1708
1709/////
1710
1711//
1712// Gets the cause of I2C transmission abort.
1713//
1714ALT_STATUS_CODE alt_i2c_tx_abort_cause_get(ALT_I2C_DEV_t *i2c_dev,
1715                                           ALT_I2C_TX_ABORT_CAUSE_t *cause)
1716{
1717    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
1718    {
1719        return ALT_E_BAD_ARG;
1720    }
1721
1722    *cause = (ALT_I2C_TX_ABORT_CAUSE_t)alt_read_word(ALT_I2C_TX_ABRT_SRC_ADDR(i2c_dev->location));
1723
1724    return ALT_E_SUCCESS;
1725}
1726
1727/////
1728
1729//
1730// Returns ALT_E_TRUE when the receive FIFO is empty.
1731//
1732ALT_STATUS_CODE alt_i2c_rx_fifo_is_empty(ALT_I2C_DEV_t *i2c_dev)
1733{
1734    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
1735    {
1736        return ALT_E_BAD_ARG;
1737    }
1738
1739    if (ALT_I2C_STAT_RFNE_GET(alt_read_word(ALT_I2C_STAT_ADDR(i2c_dev->location))) == ALT_I2C_STAT_RFNE_E_EMPTY)
1740    {
1741        return ALT_E_TRUE;
1742    }
1743    else
1744    {
1745        return ALT_E_FALSE;
1746    }
1747}
1748
1749//
1750// Returns ALT_E_TRUE when the receive FIFO is completely full.
1751//
1752ALT_STATUS_CODE alt_i2c_rx_fifo_is_full(ALT_I2C_DEV_t *i2c_dev)
1753{
1754    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
1755    {
1756        return ALT_E_BAD_ARG;
1757    }
1758
1759    if (ALT_I2C_STAT_RFF_GET(alt_read_word(ALT_I2C_STAT_ADDR(i2c_dev->location))) == ALT_I2C_STAT_RFF_E_FULL)
1760    {
1761        return ALT_E_TRUE;
1762    }
1763    else
1764    {
1765        return ALT_E_FALSE;
1766    }
1767}
1768
1769//
1770// Returns the number of valid entries in the receive FIFO.
1771//
1772ALT_STATUS_CODE alt_i2c_rx_fifo_level_get(ALT_I2C_DEV_t *i2c_dev,
1773                                          uint32_t *num_entries)
1774{
1775    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
1776    {
1777        return ALT_E_BAD_ARG;
1778    }
1779
1780    *num_entries = ALT_I2C_RXFLR_RXFLR_GET(alt_read_word(ALT_I2C_RXFLR_ADDR(i2c_dev->location)));
1781
1782    return ALT_E_SUCCESS;
1783}
1784
1785//
1786// Gets the current receive FIFO threshold level value.
1787//
1788ALT_STATUS_CODE alt_i2c_rx_fifo_threshold_get(ALT_I2C_DEV_t *i2c_dev,
1789                                              uint8_t *threshold)
1790{
1791    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
1792    {
1793        return ALT_E_BAD_ARG;
1794    }
1795
1796    *threshold = ALT_I2C_RX_TL_RX_TL_GET(alt_read_word(ALT_I2C_RX_TL_ADDR(i2c_dev->location)));
1797
1798    return ALT_E_SUCCESS;
1799}
1800
1801//
1802// Sets the current receive FIFO threshold level value.
1803//
1804ALT_STATUS_CODE alt_i2c_rx_fifo_threshold_set(ALT_I2C_DEV_t *i2c_dev,
1805                                              const uint8_t threshold)
1806{
1807    ALT_STATUS_CODE status = ALT_E_SUCCESS;
1808
1809    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
1810    {
1811        return ALT_E_BAD_ARG;
1812    }
1813
1814    bool already_enabled = (alt_i2c_is_enabled_helper(i2c_dev) == ALT_E_TRUE);
1815
1816    if (already_enabled)
1817    {
1818        // Temporarily disable controller
1819        status = alt_i2c_disable(i2c_dev);
1820        if (status != ALT_E_SUCCESS)
1821        {
1822            return status;
1823        }
1824    }
1825
1826    alt_replbits_word(ALT_I2C_RX_TL_ADDR(i2c_dev->location),
1827                      ALT_I2C_RX_TL_RX_TL_SET_MSK,
1828                      ALT_I2C_RX_TL_RX_TL_SET(threshold));
1829
1830    if (already_enabled)
1831    {
1832        // Re-enable controller
1833        status = alt_i2c_enable(i2c_dev);
1834    }
1835
1836    return status;
1837}
1838
1839//
1840// Returns ALT_E_TRUE when the transmit FIFO is empty.
1841//
1842ALT_STATUS_CODE alt_i2c_tx_fifo_is_empty(ALT_I2C_DEV_t *i2c_dev)
1843{
1844    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
1845    {
1846        return ALT_E_BAD_ARG;
1847    }
1848
1849    if (ALT_I2C_STAT_TFE_GET(alt_read_word(ALT_I2C_STAT_ADDR(i2c_dev->location))) == ALT_I2C_STAT_TFE_E_EMPTY)
1850    {
1851        return ALT_E_TRUE;
1852    }
1853    else
1854    {
1855        return ALT_E_FALSE;
1856    }
1857}
1858
1859//
1860// Returns ALT_E_TRUE when the transmit FIFO is completely full.
1861//
1862ALT_STATUS_CODE alt_i2c_tx_fifo_is_full(ALT_I2C_DEV_t *i2c_dev)
1863{
1864    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
1865    {
1866        return ALT_E_BAD_ARG;
1867    }
1868
1869    if (ALT_I2C_STAT_TFNF_GET(alt_read_word(ALT_I2C_STAT_ADDR(i2c_dev->location))) == ALT_I2C_STAT_TFNF_E_FULL)
1870    {
1871        return ALT_E_TRUE;
1872    }
1873    else
1874    {
1875        return ALT_E_FALSE;
1876    }
1877}
1878
1879//
1880// Returns the number of valid entries in the transmit FIFO.
1881//
1882ALT_STATUS_CODE alt_i2c_tx_fifo_level_get(ALT_I2C_DEV_t *i2c_dev,
1883                                          uint32_t *num_entries)
1884{
1885    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
1886    {
1887        return ALT_E_BAD_ARG;
1888    }
1889
1890    *num_entries = ALT_I2C_TXFLR_TXFLR_GET(alt_read_word(ALT_I2C_TXFLR_ADDR(i2c_dev->location)));
1891
1892    return ALT_E_SUCCESS;
1893}
1894
1895//
1896// Sets the current transmit FIFO threshold level value.
1897//
1898ALT_STATUS_CODE alt_i2c_tx_fifo_threshold_get(ALT_I2C_DEV_t *i2c_dev,
1899                                              uint8_t *threshold)
1900{
1901    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
1902    {
1903        return ALT_E_BAD_ARG;
1904    }
1905
1906    *threshold = ALT_I2C_TX_TL_TX_TL_GET(alt_read_word(ALT_I2C_TX_TL_ADDR(i2c_dev->location)));
1907
1908    return ALT_E_SUCCESS;
1909}
1910
1911//
1912// Sets the current transmit FIFO threshold level value.
1913//
1914ALT_STATUS_CODE alt_i2c_tx_fifo_threshold_set(ALT_I2C_DEV_t *i2c_dev,
1915                                              const uint8_t threshold)
1916{
1917    ALT_STATUS_CODE status = ALT_E_SUCCESS;
1918
1919    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
1920    {
1921        return ALT_E_BAD_ARG;
1922    }
1923
1924    bool already_enabled = (alt_i2c_is_enabled_helper(i2c_dev) == ALT_E_TRUE);
1925
1926    if (already_enabled)
1927    {
1928        // Temporarily disable controller
1929        status = alt_i2c_disable(i2c_dev);
1930        if (status != ALT_E_SUCCESS)
1931        {
1932            return status;
1933        }
1934    }
1935
1936    alt_replbits_word(ALT_I2C_TX_TL_ADDR(i2c_dev->location),
1937                      ALT_I2C_TX_TL_TX_TL_SET_MSK,
1938                      ALT_I2C_TX_TL_TX_TL_SET(threshold));
1939
1940    if (already_enabled)
1941    {
1942        // Re-enable controller
1943        status = alt_i2c_enable(i2c_dev);
1944    }
1945
1946    return status;
1947}
1948
1949/////
1950
1951ALT_STATUS_CODE alt_i2c_rx_dma_threshold_get(ALT_I2C_DEV_t * i2c_dev, uint8_t * threshold)
1952{
1953    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
1954    {
1955        return ALT_E_BAD_ARG;
1956    }
1957
1958    *threshold = ALT_I2C_DMA_RDLR_DMARDL_GET(alt_read_word(ALT_I2C_DMA_RDLR_ADDR(i2c_dev->location)));
1959    return ALT_E_SUCCESS;
1960}
1961
1962ALT_STATUS_CODE alt_i2c_rx_dma_threshold_set(ALT_I2C_DEV_t * i2c_dev, uint8_t threshold)
1963{
1964    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
1965    {
1966        return ALT_E_BAD_ARG;
1967    }
1968
1969    if (threshold > ALT_I2C_DMA_RDLR_DMARDL_SET_MSK)
1970    {
1971        return ALT_E_ARG_RANGE;
1972    }
1973
1974    alt_write_word(ALT_I2C_DMA_RDLR_ADDR(i2c_dev->location), threshold);
1975    return ALT_E_SUCCESS;
1976
1977}
1978
1979ALT_STATUS_CODE alt_i2c_tx_dma_threshold_get(ALT_I2C_DEV_t * i2c_dev, uint8_t * threshold)
1980{
1981    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
1982    {
1983        return ALT_E_BAD_ARG;
1984    }
1985
1986    *threshold = ALT_I2C_DMA_TDLR_DMATDL_GET(alt_read_word(ALT_I2C_DMA_TDLR_ADDR(i2c_dev->location)));
1987    return ALT_E_SUCCESS;
1988}
1989
1990ALT_STATUS_CODE alt_i2c_tx_dma_threshold_set(ALT_I2C_DEV_t * i2c_dev, uint8_t threshold)
1991{
1992    if (alt_i2c_checking(i2c_dev) == ALT_E_FALSE)
1993    {
1994        return ALT_E_BAD_ARG;
1995    }
1996
1997    if (threshold > ALT_I2C_DMA_TDLR_DMATDL_SET_MSK)
1998    {
1999        return ALT_E_ARG_RANGE;
2000    }
2001
2002    alt_write_word(ALT_I2C_DMA_TDLR_ADDR(i2c_dev->location), threshold);
2003    return ALT_E_SUCCESS;
2004}
Note: See TracBrowser for help on using the repository browser.