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