1 /******************************************************************************
2 *                                                                             *
3 * License Agreement                                                           *
4 *                                                                             *
5 * Copyright (c) 2016 Altera Corporation, San Jose, California, USA.           *
6 * All rights reserved.                                                        *
7 *                                                                             *
8 * Permission is hereby granted, free of charge, to any person obtaining a     *
9 * copy of this software and associated documentation files (the "Software"),  *
10 * to deal in the Software without restriction, including without limitation   *
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,    *
12 * and/or sell copies of the Software, and to permit persons to whom the       *
13 * Software is furnished to do so, subject to the following conditions:        *
14 *                                                                             *
15 * The above copyright notice and this permission notice shall be included in  *
16 * all copies or substantial portions of the Software.                         *
17 *                                                                             *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR  *
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,    *
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER      *
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING     *
23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER         *
24 * DEALINGS IN THE SOFTWARE.                                                   *
25 *                                                                             *
26 *                                                                             *
27 ******************************************************************************/
28 #include <stddef.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <stdint.h>
32 #include "io.h"
33 #include "priv/alt_busy_sleep.h"
34 #include "sys/alt_errno.h"
35 #include "sys/alt_irq.h"
36 #include "sys/alt_stdio.h"
37 #include "sys/alt_alarm.h"
38 #include "altera_avalon_i2c.h"
39 
40 
41 
42 /* for all functions in this file, see the altera_avalon_i2c.h file for more complete function descriptions. */
43 
44 /* optional irq callback */
optional_irq_callback(void * context)45 static void optional_irq_callback(void * context)
46 {
47    int timeout=100000;
48    alt_u32 bytes_read;
49 
50    ALT_AVALON_I2C_DEV_t *i2c_dev = context;
51    IRQ_DATA_t *irq = i2c_dev->callback_context;
52 
53    if (irq->irq_busy==2)  /*receive request*/
54    {
55        alt_avalon_i2c_rx_read_available(i2c_dev, irq->buffer, irq->size, &bytes_read);
56        irq->size-=bytes_read;
57        irq->buffer+=bytes_read;
58        if (irq->size > 0)
59        {
60          /* clear ISR register content */
61          alt_avalon_i2c_int_clear(i2c_dev,ALT_AVALON_I2C_ISR_ALL_CLEARABLE_INTS_MSK);
62          /* re-enable the RX_READY interrupt */
63          alt_avalon_i2c_int_enable(i2c_dev,ALT_AVALON_I2C_ISER_RX_READY_EN_MSK);
64          return;
65        }
66     }
67 
68     /*transaction should be done so no or minimal looping should occur*/
69     /*for a write, this code will only be reached after the cmd fifo is*/
70     /*empty (sent).  For a read this code will only be reached after all*/
71     /*bytes have been received.*/
72     while (alt_avalon_i2c_is_busy(i2c_dev))
73     {
74       if (--timeout == 0)
75       {
76          break;
77       }
78     }
79 
80     /*disable the ip.  The ip is disabled and enabled for each transaction.*/
81     alt_avalon_i2c_disable(i2c_dev);
82 
83     irq->irq_busy=0;
84 }
85 
alt_avalon_i2c_register_optional_irq_handler(ALT_AVALON_I2C_DEV_t * i2c_dev,IRQ_DATA_t * irq_data)86 void alt_avalon_i2c_register_optional_irq_handler(ALT_AVALON_I2C_DEV_t *i2c_dev,IRQ_DATA_t * irq_data)
87 {
88    irq_data->irq_busy=0;
89    alt_avalon_i2c_register_callback(i2c_dev,optional_irq_callback,0,irq_data);
90 }
91 
92 /* The list of registered i2c components */
93 ALT_LLIST_HEAD(alt_avalon_i2c_list);
94 
95 /* Interrupt handler for the AVALON_I2C module. */
96 /* Interrupts are not re-enabled in this handler */
alt_avalon_i2c_irq(void * context)97 static void alt_avalon_i2c_irq(void *context)
98 {
99     ALT_AVALON_I2C_DEV_t *dev = (ALT_AVALON_I2C_DEV_t *) context;
100     alt_irq_context cpu_sr;
101 
102     /*disable i2c interrupts*/
103     alt_avalon_i2c_int_disable(dev,ALT_AVALON_I2C_ISR_ALLINTS_MSK);
104 
105     /* clear irq status */
106     alt_avalon_i2c_int_clear(dev,ALT_AVALON_I2C_ISR_ALL_CLEARABLE_INTS_MSK);
107 
108     /*
109     * Other interrupts are explicitly disabled if callbacks
110     * are registered because there is no guarantee that they are
111     * pre-emption-safe. This allows the driver to support
112     * interrupt pre-emption.
113     */
114     if(dev->callback)
115     {
116         cpu_sr = alt_irq_disable_all();
117         dev->callback(dev);
118         alt_irq_enable_all(cpu_sr);
119     }
120 
121     return;
122 }
123 
124 /* Associate a user-specific routine with the i2c interrupt handler. */
alt_avalon_i2c_register_callback(ALT_AVALON_I2C_DEV_t * dev,alt_avalon_i2c_callback callback,alt_u32 control,void * context)125 void alt_avalon_i2c_register_callback(
126     ALT_AVALON_I2C_DEV_t *dev,
127     alt_avalon_i2c_callback callback,
128     alt_u32 control,
129     void *context)
130 {
131     dev->callback         = callback;
132     dev->callback_context = context;
133     dev->control          = control;
134 
135     return ;
136 }
137 
138  /* Initializes the I2C Module. This routine is called
139  * from the ALT_AVALON_I2C_INIT macro and is called automatically
140  * by alt_sys_init.c */
alt_avalon_i2c_init(ALT_AVALON_I2C_DEV_t * dev)141 void alt_avalon_i2c_init (ALT_AVALON_I2C_DEV_t *dev)
142 {
143     extern alt_llist alt_avalon_i2c_list;
144     ALT_AVALON_I2C_MASTER_CONFIG_t cfg;
145     int error;
146 
147     /* disable ip */
148     alt_avalon_i2c_disable(dev);
149 
150     /* Disable interrupts */
151     alt_avalon_i2c_int_disable(dev,ALT_AVALON_I2C_ISR_ALLINTS_MSK);
152 
153     /* clear ISR register content */
154     alt_avalon_i2c_int_clear(dev,ALT_AVALON_I2C_ISR_ALL_CLEARABLE_INTS_MSK);
155 
156     /* set the cmd fifo threshold */
157     alt_avalon_i2c_tfr_cmd_fifo_threshold_set(dev,ALT_AVALON_I2C_TFR_CMD_FIFO_NOT_FULL);
158 
159     /* set the tx fifo threshold */
160     alt_avalon_i2c_rx_fifo_threshold_set(dev,ALT_AVALON_I2C_RX_DATA_FIFO_FULL);
161 
162     /* set the default bus speed */
163     cfg.speed_mode = ALT_AVALON_I2C_SPEED_STANDARD;
164 
165     /*set the address mode */
166     cfg.addr_mode = ALT_AVALON_I2C_ADDR_MODE_7_BIT;
167 
168     /* set the bus speed */
169     alt_avalon_i2c_master_config_speed_set(dev,&cfg,ALT_AVALON_I2C_SS_MAX_HZ);
170 
171     /* write the cfg information */
172     alt_avalon_i2c_master_config_set(dev,&cfg);
173 
174     /* Register this instance of the i2c controller with HAL */
175     alt_dev_llist_insert((alt_dev_llist*) dev, &alt_avalon_i2c_list);
176 
177     /*
178      * Creating semaphores used to protect access to the registers
179      * when running in a multi-threaded environment.
180      */
181     error = ALT_SEM_CREATE (&dev->regs_lock, 1);
182 
183     if (!error)
184     {
185         /* Install IRQ handler */
186         alt_ic_isr_register(dev->irq_controller_ID, dev->irq_ID, alt_avalon_i2c_irq, dev, 0x0);
187     }
188     else
189     {
190         alt_printf("failed to create semaphores\n");
191     }
192 
193     return;
194 
195 }
196 
197 /*  Retrieve a pointer to the i2c instance */
alt_avalon_i2c_open(const char * name)198 ALT_AVALON_I2C_DEV_t* alt_avalon_i2c_open(const char* name)
199 {
200     ALT_AVALON_I2C_DEV_t* dev = NULL;
201 
202     dev = (ALT_AVALON_I2C_DEV_t*) alt_find_dev (name, &alt_avalon_i2c_list);
203 
204     return dev;
205 }
206 
207 /* enable the avalon i2c ip */
alt_avalon_i2c_enable(ALT_AVALON_I2C_DEV_t * i2c_dev)208 ALT_AVALON_I2C_STATUS_CODE alt_avalon_i2c_enable(ALT_AVALON_I2C_DEV_t *i2c_dev)
209 {
210    IRQ_DATA_t *irq_data = i2c_dev->callback_context;
211    alt_u32 enable_status;
212 
213    /*if the ip is already enabled, return a busy status*/
214    enable_status = (IORD_ALT_AVALON_I2C_CTRL(i2c_dev->i2c_base) & ALT_AVALON_I2C_CTRL_EN_MSK) >> ALT_AVALON_I2C_CTRL_EN_OFST;
215    if (enable_status)
216    {
217      return ALT_AVALON_I2C_BUSY;
218    }
219 
220    /*if the optional irq callback is registered ensure irq_busy is 0*/
221    if (i2c_dev->callback == optional_irq_callback)
222    {
223      irq_data->irq_busy=0;
224    }
225 
226    /* enable ip */
227    IORMW_ALT_AVALON_I2C_CTRL(i2c_dev->i2c_base,ALT_AVALON_I2C_CTRL_EN_MSK,ALT_AVALON_I2C_CTRL_EN_MSK);
228 
229    return ALT_AVALON_I2C_SUCCESS;
230 }
231 
232 /* disable the avalon i2c ip */
alt_avalon_i2c_disable(ALT_AVALON_I2C_DEV_t * i2c_dev)233 void alt_avalon_i2c_disable(ALT_AVALON_I2C_DEV_t *i2c_dev)
234 {
235    /* disable ip */
236    IORMW_ALT_AVALON_I2C_CTRL(i2c_dev->i2c_base,0,ALT_AVALON_I2C_CTRL_EN_MSK);
237 
238 }
239 
240 /* populate the the master config structure from the register values */
alt_avalon_i2c_master_config_get(ALT_AVALON_I2C_DEV_t * i2c_dev,ALT_AVALON_I2C_MASTER_CONFIG_t * cfg)241 void alt_avalon_i2c_master_config_get(ALT_AVALON_I2C_DEV_t *i2c_dev,
242                                           ALT_AVALON_I2C_MASTER_CONFIG_t* cfg)
243 {
244 
245     cfg->addr_mode = i2c_dev->address_mode;
246     cfg->speed_mode = (IORD_ALT_AVALON_I2C_CTRL(i2c_dev->i2c_base) & ALT_AVALON_I2C_CTRL_BUS_SPEED_MSK) >> ALT_AVALON_I2C_CTRL_BUS_SPEED_OFST;
247 
248     cfg->scl_hcnt = (IORD_ALT_AVALON_I2C_SCL_HIGH(i2c_dev->i2c_base) & ALT_AVALON_I2C_SCL_HIGH_COUNT_PERIOD_MSK) >> ALT_AVALON_I2C_SCL_HIGH_COUNT_PERIOD_OFST;
249     cfg->scl_lcnt = (IORD_ALT_AVALON_I2C_SCL_LOW(i2c_dev->i2c_base) & ALT_AVALON_I2C_SCL_LOW_COUNT_PERIOD_MSK) >> ALT_AVALON_I2C_SCL_LOW_COUNT_PERIOD_OFST;
250     cfg->sda_cnt = (IORD_ALT_AVALON_I2C_SDA_HOLD(i2c_dev->i2c_base) & ALT_AVALON_I2C_SDA_HOLD_COUNT_PERIOD_MSK) >> ALT_AVALON_I2C_SDA_HOLD_COUNT_PERIOD_OFST;
251 }
252 
253 /* set the registers from the master config structure */
alt_avalon_i2c_master_config_set(ALT_AVALON_I2C_DEV_t * i2c_dev,const ALT_AVALON_I2C_MASTER_CONFIG_t * cfg)254 void alt_avalon_i2c_master_config_set(ALT_AVALON_I2C_DEV_t *i2c_dev,
255                                           const ALT_AVALON_I2C_MASTER_CONFIG_t* cfg)
256 {
257     i2c_dev->address_mode   =   cfg->addr_mode;
258     IORMW_ALT_AVALON_I2C_CTRL(i2c_dev->i2c_base,(cfg->speed_mode) << ALT_AVALON_I2C_CTRL_BUS_SPEED_OFST,ALT_AVALON_I2C_CTRL_BUS_SPEED_MSK);
259 
260     IOWR_ALT_AVALON_I2C_SCL_HIGH(i2c_dev->i2c_base,cfg->scl_hcnt);
261     IOWR_ALT_AVALON_I2C_SCL_LOW(i2c_dev->i2c_base,cfg->scl_lcnt);
262     IOWR_ALT_AVALON_I2C_SDA_HOLD(i2c_dev->i2c_base,cfg->sda_cnt);
263 }
264 
265 /* This function returns the speed based on parameters of the
266  * I2C master configuration.
267 */
alt_avalon_i2c_master_config_speed_get(ALT_AVALON_I2C_DEV_t * i2c_dev,const ALT_AVALON_I2C_MASTER_CONFIG_t * cfg,alt_u32 * speed_in_hz)268 ALT_AVALON_I2C_STATUS_CODE alt_avalon_i2c_master_config_speed_get(ALT_AVALON_I2C_DEV_t *i2c_dev,
269                                                 const ALT_AVALON_I2C_MASTER_CONFIG_t* cfg,
270                                                 alt_u32 * speed_in_hz)
271 {
272 
273    if ((cfg->scl_lcnt == 0) || (cfg->scl_hcnt == 0))
274    {
275        return ALT_AVALON_I2C_BAD_ARG;
276    }
277 
278    *speed_in_hz = (i2c_dev->ip_freq_in_hz) / (cfg->scl_lcnt + cfg->scl_hcnt);
279 
280    return ALT_AVALON_I2C_SUCCESS;
281 }
282 
283 /*This is a utility function that computes parameters for the I2C master
284  * configuration that best matches the speed requested. */
alt_avalon_i2c_master_config_speed_set(ALT_AVALON_I2C_DEV_t * i2c_dev,ALT_AVALON_I2C_MASTER_CONFIG_t * cfg,alt_u32 speed_in_hz)285  ALT_AVALON_I2C_STATUS_CODE alt_avalon_i2c_master_config_speed_set(ALT_AVALON_I2C_DEV_t *i2c_dev,
286                                                 ALT_AVALON_I2C_MASTER_CONFIG_t * cfg,
287                                                 alt_u32 speed_in_hz)
288 {
289     alt_u32 scl_lcnt,scl_hcnt;
290 
291     /* If speed is not standard or fast return range error */
292     if ((speed_in_hz > ALT_AVALON_I2C_FS_MAX_HZ) || (speed_in_hz < ALT_AVALON_I2C_SS_MIN_HZ) || (speed_in_hz == 0))
293     {
294         return ALT_AVALON_I2C_RANGE;
295     }
296 
297      /* <lcount> = <internal clock> / 2 * <speed, Hz> */
298     scl_lcnt = (i2c_dev->ip_freq_in_hz) / (speed_in_hz << 1);
299 
300     /* adjust h/l by predetermined amount */
301     scl_hcnt = scl_lcnt + ALT_AVALON_I2C_DIFF_LCNT_HCNT;
302     scl_lcnt = scl_lcnt - ALT_AVALON_I2C_DIFF_LCNT_HCNT;
303 
304     if (speed_in_hz > ALT_AVALON_I2C_FS_MIN_HZ)
305     {
306        cfg->speed_mode = ALT_AVALON_I2C_SPEED_FAST;
307     }
308     else
309     {
310        cfg->speed_mode = ALT_AVALON_I2C_SPEED_STANDARD;
311     }
312 
313     cfg->scl_lcnt = scl_lcnt;
314     cfg->scl_hcnt = scl_hcnt;
315     cfg->sda_cnt  = scl_lcnt - (scl_lcnt / 2);
316 
317     return ALT_AVALON_I2C_SUCCESS;
318 
319 }
320 
321 /*Returns ALT_AVALON_I2C_TRUE if the I2C controller is busy. The I2C controller is busy if
322  * not in the IDLE state */
alt_avalon_i2c_is_busy(ALT_AVALON_I2C_DEV_t * i2c_dev)323 ALT_AVALON_I2C_STATUS_CODE alt_avalon_i2c_is_busy(ALT_AVALON_I2C_DEV_t *i2c_dev)
324 {
325 
326     if (IORD_ALT_AVALON_I2C_STATUS(i2c_dev->i2c_base) & ALT_AVALON_I2C_STATUS_CORE_STATUS_MSK)
327     {
328        return ALT_AVALON_I2C_TRUE;
329     }
330 
331     return ALT_AVALON_I2C_FALSE;
332 }
333 
334 /*Read all available bytes from the receive FIFO up to max_bytes_to_read.  If max_bytes_to_read = 0 then read all available */
alt_avalon_i2c_rx_read_available(ALT_AVALON_I2C_DEV_t * i2c_dev,alt_u8 * buffer,alt_u32 max_bytes_to_read,alt_u32 * bytes_read)335 void alt_avalon_i2c_rx_read_available(ALT_AVALON_I2C_DEV_t *i2c_dev, alt_u8 *buffer, alt_u32 max_bytes_to_read, alt_u32 *bytes_read)
336 {
337     *bytes_read = 0;
338 
339     while (IORD_ALT_AVALON_I2C_RX_DATA_FIFO_LVL(i2c_dev->i2c_base))
340     {
341        buffer[*bytes_read] = (alt_u8)IORD_ALT_AVALON_I2C_RX_DATA(i2c_dev->i2c_base);
342        *bytes_read+=1;
343        if ((*bytes_read == max_bytes_to_read) && (max_bytes_to_read != 0)) break;
344     }
345 }
346 
347 /*when a byte is available, reads a single data byte from the receive FIFO. */
alt_avalon_i2c_rx_read(ALT_AVALON_I2C_DEV_t * i2c_dev,alt_u8 * val)348 ALT_AVALON_I2C_STATUS_CODE alt_avalon_i2c_rx_read(ALT_AVALON_I2C_DEV_t *i2c_dev, alt_u8 *val)
349 {
350     alt_u32 status = ALT_AVALON_I2C_SUCCESS;
351     alt_u32 timeout = 100000;
352 
353 
354     while (IORD_ALT_AVALON_I2C_RX_DATA_FIFO_LVL(i2c_dev->i2c_base) == 0)
355     {
356       if (timeout<10) alt_busy_sleep(10000);
357       if (--timeout == 0)
358       {
359         status = ALT_AVALON_I2C_TIMEOUT;
360         break;
361       }
362     }
363 
364     *val = (alt_u8)IORD_ALT_AVALON_I2C_RX_DATA(i2c_dev->i2c_base);
365 
366     return status;
367 }
368 
369 /* When space is available, writes the Transfer Command FIFO. */
alt_avalon_i2c_cmd_write(ALT_AVALON_I2C_DEV_t * i2c_dev,alt_u8 val,alt_u8 issue_restart,alt_u8 issue_stop)370 ALT_AVALON_I2C_STATUS_CODE alt_avalon_i2c_cmd_write(ALT_AVALON_I2C_DEV_t *i2c_dev,
371                                                       alt_u8 val,
372                                                       alt_u8 issue_restart,
373                                                       alt_u8 issue_stop)
374 {
375     alt_u32 timeout = 10000;
376     ALT_AVALON_I2C_STATUS_CODE status = ALT_AVALON_I2C_SUCCESS;
377 
378 
379     while ((IORD_ALT_AVALON_I2C_ISR(i2c_dev->i2c_base) & ALT_AVALON_I2C_ISR_TX_READY_MSK)==0)
380     {
381       if (timeout<10) alt_busy_sleep(10000);
382       if (--timeout == 0)
383       {
384         return ALT_AVALON_I2C_TIMEOUT;
385       }
386     }
387 
388     IOWR_ALT_AVALON_I2C_TFR_CMD(i2c_dev->i2c_base,val |
389                                      (issue_restart << ALT_AVALON_I2C_TFR_CMD_STA_OFST) |
390                                      (issue_stop << ALT_AVALON_I2C_TFR_CMD_STO_OFST));
391 
392 
393     /*check for nack error*/
394     alt_avalon_i2c_check_nack(i2c_dev,&status);
395 
396     /*check for arb lost*/
397     alt_avalon_i2c_check_arblost(i2c_dev,&status);
398 
399     return status;
400 }
401 
402 /*send 7 or 10 bit i2c address to cmd fifo*/
alt_avalon_i2c_send_address(ALT_AVALON_I2C_DEV_t * i2c_dev,const alt_u32 rw_bit,const alt_u8 issue_restart)403 ALT_AVALON_I2C_STATUS_CODE alt_avalon_i2c_send_address(ALT_AVALON_I2C_DEV_t *i2c_dev,
404                                                        const alt_u32 rw_bit,
405                                                        const alt_u8 issue_restart)
406 {
407     alt_u32 status;
408 
409     if (i2c_dev->address_mode == ALT_AVALON_I2C_ADDR_MODE_10_BIT)
410     {
411        status = alt_avalon_i2c_cmd_write(i2c_dev,(((i2c_dev->master_target_address | TARGET_ADDR_MASK_10BIT) >> 7) & 0xfe) | rw_bit,issue_restart,ALT_AVALON_I2C_NO_STOP);
412        status = alt_avalon_i2c_cmd_write(i2c_dev,i2c_dev->master_target_address & 0xff,ALT_AVALON_I2C_NO_RESTART,ALT_AVALON_I2C_NO_STOP);
413     }
414     else
415     {
416        status = alt_avalon_i2c_cmd_write(i2c_dev,(i2c_dev->master_target_address << 1) | rw_bit,issue_restart,ALT_AVALON_I2C_NO_STOP);
417     }
418 
419     return status;
420 }
421 
422 /* This function returns the current target address. */
alt_avalon_i2c_master_target_get(ALT_AVALON_I2C_DEV_t * i2c_dev,alt_u32 * target_addr)423 void alt_avalon_i2c_master_target_get(ALT_AVALON_I2C_DEV_t * i2c_dev, alt_u32 * target_addr)
424 {
425     *target_addr=i2c_dev->master_target_address;
426 }
427 
428 /* This function updates the target address for any upcoming I2C bus IO. */
alt_avalon_i2c_master_target_set(ALT_AVALON_I2C_DEV_t * i2c_dev,alt_u32 target_addr)429 void alt_avalon_i2c_master_target_set(ALT_AVALON_I2C_DEV_t * i2c_dev, alt_u32 target_addr)
430 {
431     i2c_dev->master_target_address=target_addr;
432 }
433 
434 /*if nack detected, status is set to ALT_AVALON_I2C_NACK_ERR*/
alt_avalon_i2c_check_nack(ALT_AVALON_I2C_DEV_t * i2c_dev,ALT_AVALON_I2C_STATUS_CODE * status)435 void alt_avalon_i2c_check_nack(ALT_AVALON_I2C_DEV_t *i2c_dev,ALT_AVALON_I2C_STATUS_CODE * status)
436 {
437     if (IORD_ALT_AVALON_I2C_ISR(i2c_dev->i2c_base) & ALT_AVALON_I2C_ISR_NACK_DET_MSK)
438     {
439       *status=ALT_AVALON_I2C_NACK_ERR;
440     }
441 }
442 
443 /*if arb lost is detected, status is set to ALT_AVALON_I2C_ARB_LOST_ERR*/
alt_avalon_i2c_check_arblost(ALT_AVALON_I2C_DEV_t * i2c_dev,ALT_AVALON_I2C_STATUS_CODE * status)444 void alt_avalon_i2c_check_arblost(ALT_AVALON_I2C_DEV_t *i2c_dev,ALT_AVALON_I2C_STATUS_CODE * status)
445 {
446     if (IORD_ALT_AVALON_I2C_ISR(i2c_dev->i2c_base) & ALT_AVALON_I2C_ISR_ARBLOST_DET_MSK)
447     {
448       *status=ALT_AVALON_I2C_ARB_LOST_ERR;
449     }
450 }
451 
alt_avalon_i2c_interrupt_transaction_status(ALT_AVALON_I2C_DEV_t * i2c_dev)452 ALT_AVALON_I2C_STATUS_CODE alt_avalon_i2c_interrupt_transaction_status(ALT_AVALON_I2C_DEV_t *i2c_dev)
453 {
454     ALT_AVALON_I2C_STATUS_CODE status = ALT_AVALON_I2C_SUCCESS;
455     IRQ_DATA_t *irq_data = i2c_dev->callback_context;
456     alt_u32 timeout=10000 * irq_data->size + 10000;
457     alt_u32 saveints,temp_bytes_read;
458 
459     /* save current enabled interrupts */
460     alt_avalon_i2c_enabled_ints_get(i2c_dev,&saveints);
461 
462     /* disable the enabled interrupts */
463     alt_avalon_i2c_int_disable(i2c_dev,saveints);
464 
465     alt_avalon_i2c_check_nack(i2c_dev,&status);
466 
467     if (status!=ALT_AVALON_I2C_SUCCESS)
468     {
469       if (irq_data->irq_busy)
470       {
471         while (alt_avalon_i2c_is_busy(i2c_dev))
472         {
473               if (timeout<10) alt_busy_sleep(10000);
474               if (--timeout == 0)
475               {
476                  status = ALT_AVALON_I2C_TIMEOUT;
477                  break;
478               }
479         }
480 
481         /*clear any rx entries */
482         alt_avalon_i2c_rx_read_available(i2c_dev, irq_data->buffer,0,&temp_bytes_read);
483 
484         /*disable the ip.  The ip is disabled and enabled for each transaction. */
485         alt_avalon_i2c_disable(i2c_dev);
486 
487         /*abort the transaction */
488         irq_data->irq_busy=0;
489       }
490 
491       /*return nack error so transaction can be retried*/
492       return status;
493     }
494 
495     if (irq_data->irq_busy)
496     {
497         /*re-enable the interrupts*/
498         alt_avalon_i2c_int_enable(i2c_dev,saveints);
499 
500         /*return transaction still busy*/
501         return ALT_AVALON_I2C_BUSY;
502     }
503 
504     /*return transaction completed status, ok to do another transaction*/
505     return ALT_AVALON_I2C_SUCCESS;
506 }
507 
508 /*transmit function with retry and optionally interrupts*/
alt_avalon_i2c_master_tx(ALT_AVALON_I2C_DEV_t * i2c_dev,const alt_u8 * buffer,const alt_u32 size,const alt_u8 use_interrupts)509 ALT_AVALON_I2C_STATUS_CODE alt_avalon_i2c_master_tx(ALT_AVALON_I2C_DEV_t *i2c_dev,
510                                        const alt_u8 * buffer,
511                                        const alt_u32 size,
512                                        const alt_u8 use_interrupts)
513 {
514     ALT_AVALON_I2C_STATUS_CODE status;
515     alt_u32 retry=10000;
516 
517     while (retry--)
518     {
519       if (retry<10) alt_busy_sleep(10000);
520       if (use_interrupts)
521       {
522          status = alt_avalon_i2c_master_transmit_using_interrupts(i2c_dev, buffer, size, ALT_AVALON_I2C_NO_RESTART, ALT_AVALON_I2C_STOP);
523       }
524       else
525       {
526          status = alt_avalon_i2c_master_transmit(i2c_dev, buffer, size, ALT_AVALON_I2C_NO_RESTART, ALT_AVALON_I2C_STOP);
527       }
528       if ((status==ALT_AVALON_I2C_ARB_LOST_ERR) || (status==ALT_AVALON_I2C_NACK_ERR) || (status==ALT_AVALON_I2C_BUSY)) continue;
529       break;
530     }
531 
532     return status;
533 }
534 
535 /*receive function with retry and optionally interrupts*/
alt_avalon_i2c_master_rx(ALT_AVALON_I2C_DEV_t * i2c_dev,alt_u8 * buffer,const alt_u32 size,const alt_u8 use_interrupts)536 ALT_AVALON_I2C_STATUS_CODE alt_avalon_i2c_master_rx(ALT_AVALON_I2C_DEV_t *i2c_dev,
537                                        alt_u8 * buffer,
538                                        const alt_u32 size,
539                                        const alt_u8 use_interrupts)
540 {
541     ALT_AVALON_I2C_STATUS_CODE status;
542     alt_u32 retry=10000;
543 
544     if (use_interrupts)
545     {
546       while (retry--)
547       {
548         if (retry<10) alt_busy_sleep(10000);
549         status = alt_avalon_i2c_master_receive_using_interrupts(i2c_dev, buffer, size, ALT_AVALON_I2C_NO_RESTART, ALT_AVALON_I2C_STOP);
550         if ((status==ALT_AVALON_I2C_ARB_LOST_ERR) || (status==ALT_AVALON_I2C_NACK_ERR) || (status==ALT_AVALON_I2C_BUSY)) continue;
551         break;
552       }
553     }
554     else
555     {
556       while (retry--)
557       {
558         if (retry<10) alt_busy_sleep(10000);
559         status = alt_avalon_i2c_master_receive(i2c_dev, buffer, size, ALT_AVALON_I2C_NO_RESTART, ALT_AVALON_I2C_STOP);
560         if ((status==ALT_AVALON_I2C_ARB_LOST_ERR) || (status==ALT_AVALON_I2C_NACK_ERR) || (status==ALT_AVALON_I2C_BUSY)) continue;
561         break;
562       }
563     }
564 
565     return status;
566 }
567 
568 
569 /*transmit, restart, recieve function using retry and optionally interrupts */
alt_avalon_i2c_master_tx_rx(ALT_AVALON_I2C_DEV_t * i2c_dev,const alt_u8 * txbuffer,const alt_u32 txsize,alt_u8 * rxbuffer,const alt_u32 rxsize,const alt_u8 use_interrupts)570 ALT_AVALON_I2C_STATUS_CODE alt_avalon_i2c_master_tx_rx(ALT_AVALON_I2C_DEV_t *i2c_dev,
571                                        const alt_u8 * txbuffer,
572                                        const alt_u32 txsize,
573                                        alt_u8 * rxbuffer,
574                                        const alt_u32 rxsize,
575                                        const alt_u8 use_interrupts)
576 {
577     ALT_AVALON_I2C_STATUS_CODE status;
578     alt_u32 retry=10000;
579 
580     if (use_interrupts)
581     {
582       while (retry--)
583       {
584         if (retry<10) alt_busy_sleep(10000);
585         status = alt_avalon_i2c_master_transmit_using_interrupts(i2c_dev, txbuffer, txsize, ALT_AVALON_I2C_NO_RESTART, ALT_AVALON_I2C_NO_STOP);
586         if ((status==ALT_AVALON_I2C_ARB_LOST_ERR) || (status==ALT_AVALON_I2C_NACK_ERR) || (status==ALT_AVALON_I2C_BUSY)) continue;
587 
588         status = alt_avalon_i2c_master_receive_using_interrupts(i2c_dev, rxbuffer, rxsize, ALT_AVALON_I2C_RESTART, ALT_AVALON_I2C_STOP);
589         if ((status==ALT_AVALON_I2C_ARB_LOST_ERR) || (status==ALT_AVALON_I2C_NACK_ERR) || (status==ALT_AVALON_I2C_BUSY)) continue;
590 
591         break;
592       }
593     }
594     else
595     {
596       while (retry--)
597       {
598         if (retry<10) alt_busy_sleep(10000);
599         status = alt_avalon_i2c_master_transmit(i2c_dev, txbuffer, txsize, ALT_AVALON_I2C_NO_RESTART, ALT_AVALON_I2C_NO_STOP);
600         if ((status==ALT_AVALON_I2C_ARB_LOST_ERR) || (status==ALT_AVALON_I2C_NACK_ERR) || (status==ALT_AVALON_I2C_BUSY)) continue;
601 
602         status = alt_avalon_i2c_master_receive(i2c_dev, rxbuffer, rxsize, ALT_AVALON_I2C_RESTART, ALT_AVALON_I2C_STOP);
603         if ((status==ALT_AVALON_I2C_ARB_LOST_ERR) || (status==ALT_AVALON_I2C_NACK_ERR) || (status==ALT_AVALON_I2C_BUSY)) continue;
604 
605         break;
606       }
607     }
608 
609     return status;
610 }
611 
612 /*This function issues a write command and transmits data to the I2C bus. */
alt_avalon_i2c_master_transmit(ALT_AVALON_I2C_DEV_t * i2c_dev,const alt_u8 * buffer,alt_u32 size,const alt_u8 issue_restart,const alt_u8 issue_stop)613 ALT_AVALON_I2C_STATUS_CODE alt_avalon_i2c_master_transmit(ALT_AVALON_I2C_DEV_t *i2c_dev,
614                                         const alt_u8 * buffer,
615                                         alt_u32 size,
616                                         const alt_u8 issue_restart,
617                                         const alt_u8 issue_stop)
618 {
619     ALT_AVALON_I2C_STATUS_CODE status = ALT_AVALON_I2C_SUCCESS;
620     alt_u32 timeout=size * 10000;
621 
622     if (size==0)
623     {
624       return ALT_AVALON_I2C_SUCCESS;
625     }
626 
627     /*if a new transaction, enable ip and clear int status*/
628     if (!issue_restart)
629     {
630       /*enable the ip.  The ip is disabled and enabled for each transaction.*/
631       status = alt_avalon_i2c_enable(i2c_dev);
632       if (status != ALT_AVALON_I2C_SUCCESS)
633       {
634         return status;
635       }
636 
637       /*Clear the ISR reg*/
638       alt_avalon_i2c_int_clear(i2c_dev,ALT_AVALON_I2C_ISR_ALL_CLEARABLE_INTS_MSK);
639     }
640 
641     /*Start Write, transmit address. */
642     status = alt_avalon_i2c_send_address(i2c_dev,ALT_AVALON_I2C_WRITE,issue_restart);
643 
644     if (status == ALT_AVALON_I2C_SUCCESS)
645     {
646         while ((size > 1) && (status == ALT_AVALON_I2C_SUCCESS))
647         {
648             status = alt_avalon_i2c_cmd_write(i2c_dev, *buffer, ALT_AVALON_I2C_NO_RESTART, ALT_AVALON_I2C_NO_STOP);
649 
650             ++buffer;
651             --size;
652         }
653 
654         /* Last byte */
655         if (status == ALT_AVALON_I2C_SUCCESS)
656         {
657             status = alt_avalon_i2c_cmd_write(i2c_dev, *buffer, ALT_AVALON_I2C_NO_RESTART, issue_stop);
658 
659             ++buffer;
660             --size;
661         }
662     }
663 
664     /*if end of transaction, wait until the ip is idle then disable the ip*/
665     if ((issue_stop) || (status != ALT_AVALON_I2C_SUCCESS))
666     {
667 
668         while (alt_avalon_i2c_is_busy(i2c_dev))
669         {
670             if (timeout<10) alt_busy_sleep(10000);
671             if (--timeout == 0)
672             {
673                status = ALT_AVALON_I2C_TIMEOUT;
674                break;
675             }
676         }
677 
678         /*check for a nack error*/
679         alt_avalon_i2c_check_nack(i2c_dev,&status);
680 
681         /*disable the ip.  The ip is disabled and enabled for each transaction.*/
682         alt_avalon_i2c_disable(i2c_dev);
683     }
684 
685 
686     return status;
687 }
688 
689 /*This function issues a write command and transmits data to the I2C bus  */
alt_avalon_i2c_master_transmit_using_interrupts(ALT_AVALON_I2C_DEV_t * i2c_dev,const alt_u8 * buffer,alt_u32 size,const alt_u8 issue_restart,const alt_u8 issue_stop)690 ALT_AVALON_I2C_STATUS_CODE alt_avalon_i2c_master_transmit_using_interrupts(ALT_AVALON_I2C_DEV_t *i2c_dev,
691                                         const alt_u8 * buffer,
692                                         alt_u32 size,
693                                         const alt_u8 issue_restart,
694                                         const alt_u8 issue_stop)
695 {
696     ALT_AVALON_I2C_STATUS_CODE status = ALT_AVALON_I2C_SUCCESS;
697     alt_u32 timeout=size*10000;
698     IRQ_DATA_t *irq_data = i2c_dev->callback_context;
699 
700     if (size==0)
701     {
702       return ALT_AVALON_I2C_SUCCESS;
703     }
704 
705     /*IS the optional interrupt handler registered??*/
706     if (i2c_dev->callback != optional_irq_callback)
707     {
708        return ALT_AVALON_I2C_BAD_ARG;
709     }
710 
711     /*if a new transaction, enable ip and clear int status*/
712     if (!issue_restart)
713     {
714       /*enable the ip.  The ip is disabled and enabled for each transaction.*/
715       status = alt_avalon_i2c_enable(i2c_dev);
716       if (status != ALT_AVALON_I2C_SUCCESS)
717       {
718         return status;
719       }
720 
721       /*Clear the ISR reg*/
722       alt_avalon_i2c_int_clear(i2c_dev,ALT_AVALON_I2C_ISR_ALL_CLEARABLE_INTS_MSK);
723     }
724 
725     /*Start Write, transmit address. */
726     status = alt_avalon_i2c_send_address(i2c_dev,ALT_AVALON_I2C_WRITE,issue_restart);
727 
728     if (status == ALT_AVALON_I2C_SUCCESS)
729     {
730         while ((size > 1) && (status == ALT_AVALON_I2C_SUCCESS))
731         {
732             status = alt_avalon_i2c_cmd_write(i2c_dev, *buffer, ALT_AVALON_I2C_NO_RESTART, ALT_AVALON_I2C_NO_STOP);
733 
734             ++buffer;
735             --size;
736         }
737 
738         /* Last byte */
739         if (status == ALT_AVALON_I2C_SUCCESS)
740         {
741             status = alt_avalon_i2c_cmd_write(i2c_dev, *buffer, ALT_AVALON_I2C_NO_RESTART, issue_stop);
742 
743             ++buffer;
744             --size;
745         }
746     }
747 
748     /*if error, wait until the ip is idle then disable the ip*/
749     if (status != ALT_AVALON_I2C_SUCCESS)
750     {
751 
752         while (alt_avalon_i2c_is_busy(i2c_dev))
753         {
754             if (timeout<10) alt_busy_sleep(10000);
755             if (--timeout == 0)
756             {
757                status = ALT_AVALON_I2C_TIMEOUT;
758                break;
759             }
760         }
761 
762         /*disable the ip.  The ip is disabled and enabled for each transaction.*/
763         alt_avalon_i2c_disable(i2c_dev);
764     }
765     else
766     {
767        if (issue_stop)
768        {
769          /* clear ISR register content */
770          alt_avalon_i2c_int_clear(i2c_dev,ALT_AVALON_I2C_ISR_ALL_CLEARABLE_INTS_MSK);
771          /* set the cmd fifo threshold */
772          alt_avalon_i2c_tfr_cmd_fifo_threshold_set(i2c_dev,ALT_AVALON_I2C_TFR_CMD_FIFO_EMPTY);
773          /* set the interrupt transaction busy bit */
774          irq_data->irq_busy=1;
775          /* enable the TX_READY interrupt */
776          alt_avalon_i2c_int_enable(i2c_dev,ALT_AVALON_I2C_ISER_TX_READY_EN_MSK);
777        }
778     }
779 
780     return status;
781 }
782 
783 /*This function receives one or more data bytes transmitted from a slave in
784  * response to read requests issued from this master. */
alt_avalon_i2c_master_receive(ALT_AVALON_I2C_DEV_t * i2c_dev,alt_u8 * buffer,const alt_u32 size,const alt_u8 issue_restart,const alt_u8 issue_stop)785 ALT_AVALON_I2C_STATUS_CODE alt_avalon_i2c_master_receive(ALT_AVALON_I2C_DEV_t *i2c_dev,
786                                        alt_u8 * buffer,
787                                        const alt_u32 size,
788                                        const alt_u8 issue_restart,
789                                        const alt_u8 issue_stop)
790 {
791     ALT_AVALON_I2C_STATUS_CODE status = ALT_AVALON_I2C_SUCCESS;
792     alt_u32 timeout;
793     alt_u32 bytes_read=0;
794     alt_u32 bytes_written=0;
795     alt_u32 temp_bytes_read;
796 
797     if (size==0)
798     {
799       return ALT_AVALON_I2C_SUCCESS;
800     }
801 
802     /*if a new transaction, enable ip and clear int status*/
803     if (!issue_restart)
804     {
805        /*enable the ip.  The ip is disabled and enabled for each transaction.*/
806       status = alt_avalon_i2c_enable(i2c_dev);
807       if (status != ALT_AVALON_I2C_SUCCESS)
808       {
809         return status;
810       }
811 
812       /*Clear the ISR reg*/
813       alt_avalon_i2c_int_clear(i2c_dev,ALT_AVALON_I2C_ISR_ALL_CLEARABLE_INTS_MSK);
814     }
815 
816     /*Start Write, transmit address. */
817     status = alt_avalon_i2c_send_address(i2c_dev,ALT_AVALON_I2C_READ,issue_restart);
818 
819     if (status == ALT_AVALON_I2C_SUCCESS)
820     {
821         while ((bytes_written < (size-1)) && (status == ALT_AVALON_I2C_SUCCESS))
822         {
823             status = alt_avalon_i2c_cmd_write(i2c_dev, 0, ALT_AVALON_I2C_NO_RESTART, ALT_AVALON_I2C_NO_STOP);
824             bytes_written++;
825             if (status == ALT_AVALON_I2C_SUCCESS)
826             {
827                alt_avalon_i2c_rx_read_available(i2c_dev, buffer,0,&temp_bytes_read);
828                buffer+=temp_bytes_read;
829                bytes_read+=temp_bytes_read;
830             }
831         }
832 
833         /* Last byte */
834         if (status == ALT_AVALON_I2C_SUCCESS)
835         {
836             status = alt_avalon_i2c_cmd_write(i2c_dev, 0, ALT_AVALON_I2C_NO_RESTART, issue_stop);
837         }
838     }
839 
840     while ((bytes_read < size) && (status==ALT_AVALON_I2C_SUCCESS))
841     {
842         status=alt_avalon_i2c_rx_read(i2c_dev, buffer);
843         buffer++;
844         bytes_read++;
845     }
846 
847     /*if end of transaction, wait until the ip is idle then disable the ip*/
848     if ((issue_stop) || (status != ALT_AVALON_I2C_SUCCESS))
849     {
850         timeout=10000 * size;
851         while (alt_avalon_i2c_is_busy(i2c_dev))
852         {
853             if (timeout<10) alt_busy_sleep(10000);
854             if (--timeout == 0)
855             {
856                status = ALT_AVALON_I2C_TIMEOUT;
857                break;
858             }
859         }
860 
861         /*check for nack error*/
862         alt_avalon_i2c_check_nack(i2c_dev,&status);
863 
864         /*disable the ip.  The ip is disabled and enabled for each transaction.*/
865         alt_avalon_i2c_disable(i2c_dev);
866     }
867 
868     return status;
869 }
870 
871 /*This function receives one or more data bytes transmitted from a slave in
872  * response to read requests issued from this master.  Uses the optional interrupt routine. */
alt_avalon_i2c_master_receive_using_interrupts(ALT_AVALON_I2C_DEV_t * i2c_dev,alt_u8 * buffer,const alt_u32 size,const alt_u8 issue_restart,const alt_u8 issue_stop)873 ALT_AVALON_I2C_STATUS_CODE alt_avalon_i2c_master_receive_using_interrupts(ALT_AVALON_I2C_DEV_t *i2c_dev,
874                                        alt_u8 * buffer,
875                                        const alt_u32 size,
876                                        const alt_u8 issue_restart,
877                                        const alt_u8 issue_stop)
878 {
879     ALT_AVALON_I2C_STATUS_CODE status = ALT_AVALON_I2C_SUCCESS;
880     IRQ_DATA_t *irq_data = i2c_dev->callback_context;
881     alt_u32 timeout;
882     alt_u32 bytes_written=0;
883 
884     if (size==0)
885     {
886       return ALT_AVALON_I2C_SUCCESS;
887     }
888 
889     /*Is the optional interrupt handler registered??*/
890     if (i2c_dev->callback != optional_irq_callback)
891     {
892        return ALT_AVALON_I2C_BAD_ARG;
893     }
894 
895     /*if a new transaction, enable ip and clear int status*/
896     if (!issue_restart)
897     {
898       /*enable the ip.  The ip is disabled and enabled for each transaction.*/
899       status = alt_avalon_i2c_enable(i2c_dev);
900       if (status != ALT_AVALON_I2C_SUCCESS)
901       {
902         return status;
903       }
904 
905       /*Clear the ISR reg*/
906       alt_avalon_i2c_int_clear(i2c_dev,ALT_AVALON_I2C_ISR_ALL_CLEARABLE_INTS_MSK);
907 
908     }
909 
910     /*Start Write, transmit address. */
911     status = alt_avalon_i2c_send_address(i2c_dev,ALT_AVALON_I2C_READ,issue_restart);
912 
913     if (status == ALT_AVALON_I2C_SUCCESS)
914     {
915         while ((bytes_written < (size-1)) && (status == ALT_AVALON_I2C_SUCCESS))
916         {
917             status = alt_avalon_i2c_cmd_write(i2c_dev, 0, ALT_AVALON_I2C_NO_RESTART, ALT_AVALON_I2C_NO_STOP);
918             bytes_written++;
919         }
920 
921         /* Last byte */
922         if (status == ALT_AVALON_I2C_SUCCESS)
923         {
924             status = alt_avalon_i2c_cmd_write(i2c_dev, 0, ALT_AVALON_I2C_NO_RESTART, issue_stop);
925         }
926     }
927 
928     /*if error, wait until the ip is idle then disable the ip*/
929     if (status != ALT_AVALON_I2C_SUCCESS)
930     {
931         timeout=10000 * size;
932         while (alt_avalon_i2c_is_busy(i2c_dev))
933         {
934             if (timeout<10) alt_busy_sleep(10000);
935             if (--timeout == 0)
936             {
937                status = ALT_AVALON_I2C_TIMEOUT;
938                break;
939             }
940         }
941 
942         /*disable the ip.  The ip is disabled and enabled for each transaction.*/
943         alt_avalon_i2c_disable(i2c_dev);
944     }
945     else
946     {
947        if (issue_stop)
948        {
949          /* clear ISR register content */
950          alt_avalon_i2c_int_clear(i2c_dev,ALT_AVALON_I2C_ISR_ALL_CLEARABLE_INTS_MSK);
951          /* set the cmd fifo threshold */
952          alt_avalon_i2c_rx_fifo_threshold_set(i2c_dev,ALT_AVALON_I2C_RX_DATA_FIFO_1_ENTRY);
953          /* set the interrupt transaction busy bit  2 = receive */
954          irq_data->irq_busy=2;
955 
956          irq_data->buffer = buffer;
957          irq_data->size = size;
958 
959          /* enable the RX_READY interrupt */
960          alt_avalon_i2c_int_enable(i2c_dev,ALT_AVALON_I2C_ISER_RX_READY_EN_MSK);
961        }
962     }
963 
964     return status;
965 }
966 
967 /* Returns the current I2C controller interrupt status conditions. */
alt_avalon_i2c_int_status_get(ALT_AVALON_I2C_DEV_t * i2c_dev,alt_u32 * status)968 void alt_avalon_i2c_int_status_get(ALT_AVALON_I2C_DEV_t *i2c_dev,
969                                        alt_u32 *status)
970 {
971     *status = IORD_ALT_AVALON_I2C_ISR(i2c_dev->i2c_base) & IORD_ALT_AVALON_I2C_ISER(i2c_dev->i2c_base);
972 }
973 
974 /*Returns the I2C controller raw interrupt status conditions irrespective of
975  * the interrupt status condition enablement state. */
alt_avalon_i2c_int_raw_status_get(ALT_AVALON_I2C_DEV_t * i2c_dev,alt_u32 * status)976 void alt_avalon_i2c_int_raw_status_get(ALT_AVALON_I2C_DEV_t *i2c_dev,
977                                            alt_u32 *status)
978 {
979     *status = IORD_ALT_AVALON_I2C_ISR(i2c_dev->i2c_base);
980 }
981 
982 /*Clears the specified I2C controller interrupt status conditions identified
983  * in the mask. */
alt_avalon_i2c_int_clear(ALT_AVALON_I2C_DEV_t * i2c_dev,const alt_u32 mask)984 void alt_avalon_i2c_int_clear(ALT_AVALON_I2C_DEV_t *i2c_dev, const alt_u32 mask)
985 {
986     IOWR_ALT_AVALON_I2C_ISR(i2c_dev->i2c_base,mask);
987 }
988 
989 /*Disable the specified I2C controller interrupt status conditions identified in
990  * the mask. */
alt_avalon_i2c_int_disable(ALT_AVALON_I2C_DEV_t * i2c_dev,const alt_u32 mask)991 void alt_avalon_i2c_int_disable(ALT_AVALON_I2C_DEV_t *i2c_dev, const alt_u32 mask)
992 {
993    alt_u32 enabled_ints;
994 
995    alt_avalon_i2c_enabled_ints_get(i2c_dev,&enabled_ints);
996    enabled_ints &=  (~mask);
997    IOWR_ALT_AVALON_I2C_ISER(i2c_dev->i2c_base,ALT_AVALON_I2C_ISR_ALLINTS_MSK & enabled_ints);
998 }
999 
1000 /*Enable the specified I2C controller interrupt status conditions identified in
1001  * the mask. */
alt_avalon_i2c_int_enable(ALT_AVALON_I2C_DEV_t * i2c_dev,const alt_u32 mask)1002 void alt_avalon_i2c_int_enable(ALT_AVALON_I2C_DEV_t *i2c_dev, const alt_u32 mask)
1003 {
1004     alt_u32 enabled_ints;
1005 
1006     alt_avalon_i2c_enabled_ints_get(i2c_dev,&enabled_ints);
1007     enabled_ints |= mask;
1008     IOWR_ALT_AVALON_I2C_ISER(i2c_dev->i2c_base,ALT_AVALON_I2C_ISR_ALLINTS_MSK & enabled_ints);
1009 }
1010 
1011 /*gets the enabled i2c interrupts. */
alt_avalon_i2c_enabled_ints_get(ALT_AVALON_I2C_DEV_t * i2c_dev,alt_u32 * enabled_ints)1012 void alt_avalon_i2c_enabled_ints_get(ALT_AVALON_I2C_DEV_t *i2c_dev, alt_u32 * enabled_ints)
1013 {
1014     *enabled_ints=IORD_ALT_AVALON_I2C_ISER(i2c_dev->i2c_base) & ALT_AVALON_I2C_ISR_ALLINTS_MSK;
1015 }
1016 
1017 /*Gets the current receive FIFO threshold level value. */
alt_avalon_i2c_rx_fifo_threshold_get(ALT_AVALON_I2C_DEV_t * i2c_dev,ALT_AVALON_I2C_RX_DATA_FIFO_THRESHOLD_t * threshold)1018 void alt_avalon_i2c_rx_fifo_threshold_get(ALT_AVALON_I2C_DEV_t *i2c_dev,
1019                                               ALT_AVALON_I2C_RX_DATA_FIFO_THRESHOLD_t *threshold)
1020 {
1021     *threshold = (IORD_ALT_AVALON_I2C_CTRL(i2c_dev->i2c_base) & ALT_AVALON_I2C_CTRL_RX_DATA_FIFO_THD_MSK) >>  ALT_AVALON_I2C_CTRL_RX_DATA_FIFO_THD_OFST;
1022 }
1023 
1024 /*sets the current receive FIFO threshold level value. */
alt_avalon_i2c_rx_fifo_threshold_set(ALT_AVALON_I2C_DEV_t * i2c_dev,const ALT_AVALON_I2C_RX_DATA_FIFO_THRESHOLD_t threshold)1025 void alt_avalon_i2c_rx_fifo_threshold_set(ALT_AVALON_I2C_DEV_t *i2c_dev,
1026                                               const ALT_AVALON_I2C_RX_DATA_FIFO_THRESHOLD_t threshold)
1027 {
1028     IORMW_ALT_AVALON_I2C_CTRL(i2c_dev->i2c_base,threshold << ALT_AVALON_I2C_CTRL_RX_DATA_FIFO_THD_OFST,ALT_AVALON_I2C_CTRL_RX_DATA_FIFO_THD_MSK);
1029 }
1030 
1031 /*Gets the current Transfer Command FIFO threshold level value.*/
alt_avalon_i2c_tfr_cmd_fifo_threshold_get(ALT_AVALON_I2C_DEV_t * i2c_dev,ALT_AVALON_I2C_TFR_CMD_FIFO_THRESHOLD_t * threshold)1032 void alt_avalon_i2c_tfr_cmd_fifo_threshold_get(ALT_AVALON_I2C_DEV_t *i2c_dev,
1033                                               ALT_AVALON_I2C_TFR_CMD_FIFO_THRESHOLD_t *threshold)
1034 {
1035     *threshold = (IORD_ALT_AVALON_I2C_CTRL(i2c_dev->i2c_base) & ALT_AVALON_I2C_CTRL_TFR_CMD_FIFO_THD_MSK) >> ALT_AVALON_I2C_CTRL_TFR_CMD_FIFO_THD_OFST;
1036 }
1037 
1038 /*Sets the current Transfer Command FIFO threshold level value.*/
alt_avalon_i2c_tfr_cmd_fifo_threshold_set(ALT_AVALON_I2C_DEV_t * i2c_dev,const ALT_AVALON_I2C_TFR_CMD_FIFO_THRESHOLD_t threshold)1039 void alt_avalon_i2c_tfr_cmd_fifo_threshold_set(ALT_AVALON_I2C_DEV_t *i2c_dev,
1040                                               const ALT_AVALON_I2C_TFR_CMD_FIFO_THRESHOLD_t threshold)
1041 {
1042   IORMW_ALT_AVALON_I2C_CTRL(i2c_dev->i2c_base,threshold << ALT_AVALON_I2C_CTRL_TFR_CMD_FIFO_THD_OFST,ALT_AVALON_I2C_CTRL_TFR_CMD_FIFO_THD_MSK);
1043 }
1044