Intel® Quark™ Microcontroller Software Interface 1.4.0 Intel® Quark™ Microcontroller BSP

- Main Page
- Modules
- Data Structures
- Files

- File List

qm_ss_i2c.c
1 /*
2 * {% copyright %}
3 */
4
5 #include <string.h>
6 #include "qm_ss_i2c.h"
7 #include "clk.h"
8
9 #define TX_TL (2)
10 #define RX_TL (5)
11
12 /* number of retries before giving up on disabling the controller */
13 #define I2C_POLL_COUNT (1000000)
14 #define I2C_POLL_MICROSECOND (1)
15
16 static uint32_t i2c_base[QM_SS_I2C_NUM] = {QM_SS_I2C_0_BASE, QM_SS_I2C_1_BASE};
17 static volatile const qm_ss_i2c_transfer_t *i2c_transfer[QM_SS_I2C_NUM];
18 static volatile uint32_t i2c_write_pos[QM_SS_I2C_NUM],
19 i2c_read_pos[QM_SS_I2C_NUM], i2c_read_cmd_send[QM_SS_I2C_NUM];
20
21 static void controller_enable(const qm_ss_i2c_t i2c);
22 static int controller_disable(const qm_ss_i2c_t i2c);
23
24 static uint32_t
25 i2c_fill_tx_fifo(const qm_i2c_t i2c,
26 const volatile qm_ss_i2c_transfer_t *const transfer,
27 uint32_t controller)
28 {
29 uint32_t data_cmd = 0, count_tx = (QM_SS_I2C_FIFO_SIZE - TX_TL);
30 uint32_t write_buffer_remaining = transfer->tx_len - i2c_write_pos[i2c];
31 uint32_t read_buffer_remaining = transfer->rx_len - i2c_read_pos[i2c];
32
33 while ((count_tx) && write_buffer_remaining) {
34 count_tx--;
35 write_buffer_remaining--;
36
37 /* write command -IC_DATA_CMD[8] = 0 */
38 /* fill IC_DATA_CMD[7:0] with the data */
39 data_cmd = QM_SS_I2C_DATA_CMD_PUSH |
40 i2c_transfer[i2c]->tx[i2c_write_pos[i2c]];
41
42 /* if transfer is a combined transfer, only
43 * send stop at
44 * end of the transfer sequence */
45 if (i2c_transfer[i2c]->stop && (read_buffer_remaining == 0) &&
46 (write_buffer_remaining == 0)) {
47
48 data_cmd |= QM_SS_I2C_DATA_CMD_STOP;
49 }
50
51 /* write data */
52 QM_SS_I2C_WRITE_DATA_CMD(controller, data_cmd);
53 i2c_write_pos[i2c]++;
54
55 /* TX_EMPTY INTR is autocleared when the buffer
56 * levels goes above the threshold
57 */
58 }
59
60 return write_buffer_remaining;
61 }
62
63 static void handle_i2c_error_interrupt(const qm_ss_i2c_t i2c)
64 {
65 uint32_t controller = i2c_base[i2c];
66 qm_ss_i2c_status_t status = 0;
67 int rc = -EIO;
68
69 /* Check for TX_OVER error */
70 if (QM_SS_I2C_READ_INTR_STAT(controller) &
71 QM_SS_I2C_INTR_STAT_TX_OVER) {
72
73 status = QM_SS_I2C_TX_OVER;
74
75 /* Clear interrupt */
76 QM_SS_I2C_CLEAR_TX_OVER_INTR(controller);
77 }
78
79 /* Check for RX_UNDER error */
80 if (QM_SS_I2C_READ_INTR_STAT(controller) &
81 QM_SS_I2C_INTR_STAT_RX_UNDER) {
82
83 status = QM_SS_I2C_RX_UNDER;
84
85 /* Clear interrupt */
86 QM_SS_I2C_CLEAR_RX_UNDER_INTR(controller);
87 }
88
89 /* Check for RX_OVER error */
90 if (QM_SS_I2C_READ_INTR_STAT(controller) &
91 QM_SS_I2C_INTR_STAT_RX_OVER) {
92
93 status = QM_SS_I2C_RX_OVER;
94
95 /* Clear interrupt */
96 QM_SS_I2C_CLEAR_RX_OVER_INTR(controller);
97 }
98
99 /* Check for TX_ABRT error */
100 if ((QM_SS_I2C_READ_INTR_STAT(controller) &
101 QM_SS_I2C_INTR_STAT_TX_ABRT)) {
102
103 QM_ASSERT(!(QM_SS_I2C_READ_TX_ABRT_SOURCE(controller) &
104 QM_SS_I2C_TX_ABRT_SBYTE_NORSTRT));
105
106 status = QM_SS_I2C_TX_ABORT;
107
108 status |= (QM_SS_I2C_READ_TX_ABRT_SOURCE(controller) &
109 QM_SS_I2C_TX_ABRT_SOURCE_ALL_MASK);
110
111 /* Clear interrupt */
112 QM_SS_I2C_CLEAR_TX_ABRT_INTR(controller);
113
114 rc = (status & QM_SS_I2C_TX_ABRT_USER_ABRT) ? -ECANCELED : -EIO;
115 }
116
117 /* Mask interrupts */
118 QM_SS_I2C_MASK_ALL_INTERRUPTS(controller);
119
120 controller_disable(i2c);
121 if (i2c_transfer[i2c]->callback) {
122 i2c_transfer[i2c]->callback(i2c_transfer[i2c]->callback_data,
123 rc, status, 0);
124 }
125 }
126
127 static void handle_i2c_rx_avail_interrupt(const qm_ss_i2c_t i2c)
128 {
129 const volatile qm_ss_i2c_transfer_t *const transfer = i2c_transfer[i2c];
130 uint32_t controller = i2c_base[i2c];
131 uint32_t read_buffer_remaining = transfer->rx_len - i2c_read_pos[i2c];
132
133 /* RX read from buffer */
134 if ((QM_SS_I2C_READ_INTR_STAT(controller) &
135 QM_SS_I2C_INTR_STAT_RX_FULL)) {
136
137 while (read_buffer_remaining &&
138 (QM_SS_I2C_READ_RXFLR(controller))) {
139 QM_SS_I2C_READ_RX_FIFO(controller);
140 /* IC_DATA_CMD[7:0] contains received data */
141 i2c_transfer[i2c]->rx[i2c_read_pos[i2c]] =
142 QM_SS_I2C_READ_DATA_CMD(controller);
143 read_buffer_remaining--;
144 i2c_read_pos[i2c]++;
145
146 if (read_buffer_remaining == 0) {
147 /* mask rx full interrupt if transfer
148 * complete
149 */
150 QM_SS_I2C_MASK_INTERRUPT(
151 controller,
152 QM_SS_I2C_INTR_MASK_RX_FULL |
153 QM_SS_I2C_INTR_MASK_TX_EMPTY);
154
155 if (i2c_transfer[i2c]->stop) {
156 controller_disable(i2c);
157 }
158
159 if (i2c_transfer[i2c]->callback) {
160 i2c_transfer[i2c]->callback(
161 i2c_transfer[i2c]->callback_data, 0,
162 QM_SS_I2C_IDLE, i2c_read_pos[i2c]);
163 }
164 }
165 }
166 if (read_buffer_remaining > 0 &&
167 read_buffer_remaining < (RX_TL + 1)) {
168 /* Adjust the RX threshold so the next 'RX_FULL'
169 * interrupt is generated when all the remaining
170 * data are received.
171 */
172 QM_SS_I2C_CLEAR_RX_TL(controller);
173 QM_SS_I2C_WRITE_RX_TL(controller,
174 (read_buffer_remaining - 1));
175 }
176
177 /* RX_FULL INTR is autocleared when the buffer
178 * levels goes below the threshold
179 */
180 }
181 }
182
183 static void handle_i2c_tx_req_interrupt(const qm_ss_i2c_t i2c)
184 {
185 const volatile qm_ss_i2c_transfer_t *const transfer = i2c_transfer[i2c];
186 uint32_t controller = i2c_base[i2c];
187 uint32_t count_tx;
188 uint32_t read_buffer_remaining = transfer->rx_len - i2c_read_pos[i2c];
189 uint32_t write_buffer_remaining = transfer->tx_len - i2c_write_pos[i2c];
190 uint32_t missing_bytes;
191
192 if ((QM_SS_I2C_READ_INTR_STAT(controller) &
193 QM_SS_I2C_INTR_STAT_TX_EMPTY)) {
194
195 if ((QM_SS_I2C_READ_STATUS(controller) &
196 QM_SS_I2C_STATUS_TFE) &&
197 (i2c_transfer[i2c]->tx != NULL) &&
198 (write_buffer_remaining == 0) &&
199 (read_buffer_remaining == 0)) {
200
201 QM_SS_I2C_MASK_INTERRUPT(controller,
202 QM_SS_I2C_INTR_MASK_TX_EMPTY);
203
204 /* if this is not a combined
205 * transaction, disable the controller now
206 */
207 if (i2c_transfer[i2c]->stop) {
208 controller_disable(i2c);
209 }
210
211 /* callback */
212 if (i2c_transfer[i2c]->callback) {
213 i2c_transfer[i2c]->callback(
214 i2c_transfer[i2c]->callback_data, 0,
215 QM_SS_I2C_IDLE, i2c_write_pos[i2c]);
216 }
217 }
218
219 write_buffer_remaining =
220 i2c_fill_tx_fifo(i2c, i2c_transfer[i2c], controller);
221
222 /* If missing_bytes is not null, then that means we are already
223 * waiting for some bytes after sending read request on the
224 * previous interruption. We have to take into account this
225 * value in order to not send too much request so we won't fall
226 * into rx overflow */
227 missing_bytes = read_buffer_remaining - i2c_read_cmd_send[i2c];
228
229 /* Sanity check: The number of read data but not processed
230 * cannot be more than the number of expected bytes */
231 QM_ASSERT(QM_SS_I2C_READ_RXFLR(controller) <= missing_bytes);
232
233 /* count_tx is the remaining size in the fifo */
234 count_tx =
235 QM_SS_I2C_FIFO_SIZE - QM_SS_I2C_READ_TXFLR(controller);
236
237 if (count_tx > missing_bytes) {
238 count_tx -= missing_bytes;
239 } else {
240 count_tx = 0;
241 }
242
243 while (i2c_read_cmd_send[i2c] &&
244 (write_buffer_remaining == 0) && count_tx) {
245 count_tx--;
246 i2c_read_cmd_send[i2c]--;
247
248 /* if transfer is a combined transfer, only
249 * send stop at
250 * end of
251 * the transfer sequence */
252 if (i2c_transfer[i2c]->stop &&
253 (i2c_read_cmd_send[i2c] == 0)) {
254
255 QM_SS_I2C_WRITE_DATA_CMD(
256 controller, (QM_SS_I2C_DATA_CMD_CMD |
257 QM_SS_I2C_DATA_CMD_PUSH |
258 QM_SS_I2C_DATA_CMD_STOP));
259
260 } else {
261
262 QM_SS_I2C_WRITE_DATA_CMD(
263 controller, (QM_SS_I2C_DATA_CMD_CMD |
264 QM_SS_I2C_DATA_CMD_PUSH));
265 }
266 }
267
268 /* generate a tx_empty interrupt when tx fifo is fully
269 * empty */
270 if ((write_buffer_remaining == 0) &&
271 (read_buffer_remaining == 0)) {
272 QM_SS_I2C_CLEAR_TX_TL(controller);
273 }
274 }
275 }
276
277 static void handle_i2c_stop_det_interrupt(const qm_ss_i2c_t i2c)
278 {
279 uint32_t controller = i2c_base[i2c];
280
281 if ((QM_SS_I2C_READ_INTR_STAT(controller) & QM_SS_I2C_INTR_STAT_STOP)) {
282
283 /* Clear interrupt */
284 QM_SS_I2C_CLEAR_STOP_DET_INTR(controller);
285
286 if (i2c_transfer[i2c]->callback) {
287 i2c_transfer[i2c]->callback(
288 i2c_transfer[i2c]->callback_data, 0, QM_SS_I2C_IDLE,
289 0);
290 }
291 }
292 }
293
294 QM_ISR_DECLARE(qm_ss_i2c_0_error_isr)
295 {
296 handle_i2c_error_interrupt(QM_SS_I2C_0);
297 }
298
299 QM_ISR_DECLARE(qm_ss_i2c_0_rx_avail_isr)
300 {
301 handle_i2c_rx_avail_interrupt(QM_SS_I2C_0);
302 }
303
304 QM_ISR_DECLARE(qm_ss_i2c_0_tx_req_isr)
305 {
306 handle_i2c_tx_req_interrupt(QM_SS_I2C_0);
307 }
308
309 QM_ISR_DECLARE(qm_ss_i2c_0_stop_det_isr)
310 {
311 handle_i2c_stop_det_interrupt(QM_SS_I2C_0);
312 }
313
314 QM_ISR_DECLARE(qm_ss_i2c_1_error_isr)
315 {
316 handle_i2c_error_interrupt(QM_SS_I2C_1);
317 }
318
319 QM_ISR_DECLARE(qm_ss_i2c_1_rx_avail_isr)
320 {
321 handle_i2c_rx_avail_interrupt(QM_SS_I2C_1);
322 }
323
324 QM_ISR_DECLARE(qm_ss_i2c_1_tx_req_isr)
325 {
326 handle_i2c_tx_req_interrupt(QM_SS_I2C_1);
327 }
328
329 QM_ISR_DECLARE(qm_ss_i2c_1_stop_det_isr)
330 {
331 handle_i2c_stop_det_interrupt(QM_SS_I2C_1);
332 }
333
334 static uint32_t get_lo_cnt(uint32_t lo_time_ns)
335 {
336 return (((clk_sys_get_ticks_per_us() * lo_time_ns) / 1000) - 1);
337 }
338
339 static uint32_t get_hi_cnt(qm_ss_i2c_t i2c, uint32_t hi_time_ns)
340 {
341 uint32_t controller = i2c_base[i2c];
342
343 return (((clk_sys_get_ticks_per_us() * hi_time_ns) / 1000) - 7 -
344 (QM_SS_I2C_READ_SPKLEN(controller)));
345 }
346
347 int qm_ss_i2c_set_config(const qm_ss_i2c_t i2c,
348 const qm_ss_i2c_config_t *const cfg)
349 {
350 QM_CHECK(i2c < QM_SS_I2C_NUM, -EINVAL);
351 QM_CHECK(cfg != NULL, -EINVAL);
352
353 uint32_t controller = i2c_base[i2c], lcnt = 0, hcnt = 0, min_lcnt = 0,
354 lcnt_diff = 0;
355
356 QM_SS_I2C_WRITE_CLKEN(controller);
357
358 /* mask all interrupts */
359 QM_SS_I2C_MASK_ALL_INTERRUPTS(controller);
360
361 /* disable controller */
362 if (controller_disable(i2c)) {
363 return -EBUSY;
364 }
365
366 /* Set mode */
367 QM_SS_I2C_WRITE_RESTART_EN(controller);
368 QM_SS_I2C_WRITE_ADDRESS_MODE(controller, cfg->address_mode);
369
370 /*
371 * Timing generation algorithm:
372 * 1. compute hi/lo count so as to achieve the desired bus
373 * speed at 50% duty cycle
374 * 2. adjust the hi/lo count to ensure that minimum hi/lo
375 * timings are guaranteed as per spec.
376 */
377
378 QM_SS_I2C_CLEAR_SPKLEN(controller);
379 QM_SS_I2C_CLEAR_SPEED(controller);
380
381 switch (cfg->speed) {
382 case QM_SS_I2C_SPEED_STD:
383
384 QM_SS_I2C_WRITE_SPEED(controller, QM_SS_I2C_CON_SPEED_SS);
385 QM_SS_I2C_WRITE_SPKLEN(controller, QM_SS_I2C_SPK_LEN_SS);
386
387 min_lcnt = get_lo_cnt(QM_I2C_MIN_SS_NS);
388 lcnt = get_lo_cnt(QM_I2C_SS_50_DC_NS);
389 hcnt = get_hi_cnt(i2c, QM_I2C_SS_50_DC_NS);
390 break;
391
392 case QM_SS_I2C_SPEED_FAST:
393
394 QM_SS_I2C_WRITE_SPEED(controller, QM_SS_I2C_CON_SPEED_FS);
395 QM_SS_I2C_WRITE_SPKLEN(controller, QM_SS_I2C_SPK_LEN_FS);
396
397 min_lcnt = get_lo_cnt(QM_I2C_MIN_FS_NS);
398 lcnt = get_lo_cnt(QM_I2C_FS_50_DC_NS);
399 hcnt = get_hi_cnt(i2c, QM_I2C_FS_50_DC_NS);
400 break;
401
402 #if HAS_SS_I2C_FAST_PLUS_SPEED
403 case QM_SS_I2C_SPEED_FAST_PLUS:
404
405 QM_SS_I2C_WRITE_SPEED(controller, QM_SS_I2C_CON_SPEED_FSP);
406 QM_SS_I2C_WRITE_SPKLEN(controller, QM_SS_I2C_SPK_LEN_FSP);
407
408 min_lcnt = get_lo_cnt(QM_I2C_MIN_FSP_NS);
409 lcnt = get_lo_cnt(QM_I2C_FSP_50_DC_NS);
410 hcnt = get_hi_cnt(i2c, QM_I2C_FSP_50_DC_NS);
411
412 break;
413 #endif /* HAS_SS_I2C_FAST_PLUS_SPEED */
414 }
415
416 if (hcnt > QM_SS_I2C_IC_HCNT_MAX || hcnt < QM_SS_I2C_IC_HCNT_MIN) {
417 return -EINVAL;
418 }
419
420 if (lcnt > QM_SS_I2C_IC_LCNT_MAX || lcnt < QM_SS_I2C_IC_LCNT_MIN) {
421 return -EINVAL;
422 }
423
424 /* Increment minimum low count to account for rounding down */
425 min_lcnt++;
426 if (lcnt < min_lcnt) {
427 lcnt_diff = (min_lcnt - lcnt);
428 lcnt += (lcnt_diff);
429 hcnt -= (lcnt_diff);
430 }
431
432 if (QM_SS_I2C_SPEED_STD == cfg->speed) {
433 QM_SS_I2C_CLEAR_SS_SCL_HCNT(controller);
434 QM_SS_I2C_CLEAR_SS_SCL_LCNT(controller);
435
436 QM_SS_I2C_WRITE_SS_SCL_HCNT(controller, hcnt);
437 QM_SS_I2C_WRITE_SS_SCL_LCNT(controller, lcnt);
438
439 } else { /* Fast and fast plus modes */
440 QM_SS_I2C_CLEAR_FS_SCL_HCNT(controller);
441 QM_SS_I2C_CLEAR_FS_SCL_LCNT(controller);
442
443 QM_SS_I2C_WRITE_FS_SCL_HCNT(controller, hcnt);
444 QM_SS_I2C_WRITE_FS_SCL_LCNT(controller, lcnt);
445 }
446
447 return 0;
448 }
449
450 int qm_ss_i2c_set_speed(const qm_ss_i2c_t i2c, const qm_ss_i2c_speed_t speed,
451 const uint16_t lo_cnt, const uint16_t hi_cnt)
452 {
453 QM_CHECK(i2c < QM_SS_I2C_NUM, -EINVAL);
454 QM_CHECK(hi_cnt < QM_SS_I2C_IC_HCNT_MAX &&
455 hi_cnt > QM_SS_I2C_IC_HCNT_MIN,
456 -EINVAL);
457 QM_CHECK(lo_cnt < QM_SS_I2C_IC_LCNT_MAX &&
458 lo_cnt > QM_SS_I2C_IC_LCNT_MIN,
459 -EINVAL);
460
461 uint32_t controller = i2c_base[i2c];
462
463 QM_SS_I2C_CLEAR_SPKLEN(controller);
464 QM_SS_I2C_CLEAR_SPEED(controller);
465
466 switch (speed) {
467 case QM_SS_I2C_SPEED_STD:
468 QM_SS_I2C_WRITE_SPKLEN(controller, QM_SS_I2C_SPK_LEN_SS);
469 QM_SS_I2C_WRITE_SPEED(controller, QM_SS_I2C_CON_SPEED_SS);
470
471 QM_SS_I2C_CLEAR_SS_SCL_HCNT(controller);
472 QM_SS_I2C_CLEAR_SS_SCL_LCNT(controller);
473
474 QM_SS_I2C_WRITE_SS_SCL_HCNT(controller, hi_cnt);
475 QM_SS_I2C_WRITE_SS_SCL_LCNT(controller, lo_cnt);
476 break;
477
478 case QM_SS_I2C_SPEED_FAST:
479 QM_SS_I2C_WRITE_SPKLEN(controller, QM_SS_I2C_SPK_LEN_FS);
480 QM_SS_I2C_WRITE_SPEED(controller, QM_SS_I2C_CON_SPEED_FS);
481
482 QM_SS_I2C_CLEAR_FS_SCL_HCNT(controller);
483 QM_SS_I2C_CLEAR_FS_SCL_LCNT(controller);
484
485 QM_SS_I2C_WRITE_FS_SCL_HCNT(controller, hi_cnt);
486 QM_SS_I2C_WRITE_FS_SCL_LCNT(controller, lo_cnt);
487 break;
488 #if HAS_SS_I2C_FAST_PLUS_SPEED
489 case QM_SS_I2C_SPEED_FAST_PLUS:
490 QM_SS_I2C_WRITE_SPKLEN(controller, QM_SS_I2C_SPK_LEN_FSP);
491 QM_SS_I2C_WRITE_SPEED(controller, QM_SS_I2C_CON_SPEED_FSP);
492
493 QM_SS_I2C_CLEAR_FS_SCL_HCNT(controller);
494 QM_SS_I2C_CLEAR_FS_SCL_LCNT(controller);
495
496 QM_SS_I2C_WRITE_FS_SCL_HCNT(controller, hi_cnt);
497 QM_SS_I2C_WRITE_FS_SCL_LCNT(controller, lo_cnt);
498 break;
499 #endif /* HAS_SS_I2C_FAST_PLUS_SPEED */
500 }
501
502 return 0;
503 }
504
505 int qm_ss_i2c_get_status(const qm_ss_i2c_t i2c,
506 qm_ss_i2c_status_t *const status)
507 {
508 QM_CHECK(status != NULL, -EINVAL);
509
510 uint32_t controller = i2c_base[i2c];
511
512 *status = QM_SS_I2C_IDLE;
513
514 /* check if slave or master are active */
515 if (QM_SS_I2C_READ_STATUS(controller) & QM_SS_I2C_STATUS_BUSY_MASK) {
516 *status |= QM_SS_I2C_BUSY;
517 }
518
519 /* check for abort status */
520 *status |= (QM_SS_I2C_READ_TX_ABRT_SOURCE(controller) &
521 QM_SS_I2C_TX_ABRT_SOURCE_ALL_MASK);
522
523 return 0;
524 }
525
526 int qm_ss_i2c_master_write(const qm_ss_i2c_t i2c, const uint16_t slave_addr,
527 const uint8_t *const data, uint32_t len,
528 const bool stop, qm_ss_i2c_status_t *const status)
529 {
530 QM_CHECK(i2c < QM_SS_I2C_NUM, -EINVAL);
531 QM_CHECK(data != NULL, -EINVAL);
532 QM_CHECK(len > 0, -EINVAL);
533
534 uint8_t *d = (uint8_t *)data;
535 uint32_t controller = i2c_base[i2c], data_cmd = 0;
536 int ret = 0;
537
538 /* write slave address to TAR */
539 QM_SS_I2C_CLEAR_TAR(controller);
540 QM_SS_I2C_WRITE_TAR(controller, slave_addr);
541
542 /* enable controller */
543 controller_enable(i2c);
544
545 while (len--) {
546
547 /* wait if FIFO is full */
548 while (!(QM_SS_I2C_READ_STATUS(controller) &
549 QM_SS_I2C_STATUS_TFNF))
550 ;
551
552 /* write command -IC_DATA_CMD[8] = 0 */
553 /* fill IC_DATA_CMD[7:0] with the data */
554 data_cmd = *d;
555 data_cmd |= QM_SS_I2C_DATA_CMD_PUSH;
556
557 /* send stop after last byte */
558 if (len == 0 && stop) {
559 data_cmd |= QM_SS_I2C_DATA_CMD_STOP;
560 }
561
562 QM_SS_I2C_WRITE_DATA_CMD(controller, data_cmd);
563 d++;
564 }
565
566 /* this is a blocking call, wait until FIFO is empty or tx abrt
567 * error */
568 while (!(QM_SS_I2C_READ_STATUS(controller) & QM_SS_I2C_STATUS_TFE))
569 ;
570
571 if ((QM_SS_I2C_READ_INTR_STAT(controller) &
572 QM_SS_I2C_INTR_STAT_TX_ABRT)) {
573 ret = -EIO;
574 }
575
576 /* disable controller */
577 if (true == stop) {
578 if (controller_disable(i2c)) {
579 ret = -EBUSY;
580 }
581 }
582
583 if (status != NULL) {
584 qm_ss_i2c_get_status(i2c, status);
585 }
586
587 /* Clear abort status
588 * The controller flushes/resets/empties
589 * the TX FIFO whenever this bit is set. The TX
590 * FIFO remains in this flushed state until the
591 * register IC_CLR_TX_ABRT is read.
592 */
593 QM_SS_I2C_CLEAR_TX_ABRT_INTR(controller);
594
595 return ret;
596 }
597
598 int qm_ss_i2c_master_read(const qm_ss_i2c_t i2c, const uint16_t slave_addr,
599 uint8_t *const data, uint32_t len, const bool stop,
600 qm_ss_i2c_status_t *const status)
601 {
602 QM_CHECK(i2c < QM_SS_I2C_NUM, -EINVAL);
603 QM_CHECK(data != NULL, -EINVAL);
604 QM_CHECK(len > 0, -EINVAL);
605
606 uint32_t controller = i2c_base[i2c],
607 data_cmd = QM_SS_I2C_DATA_CMD_CMD | QM_SS_I2C_DATA_CMD_PUSH;
608 uint8_t *d = (uint8_t *)data;
609 int ret = 0;
610
611 /* write slave address to TAR */
612 QM_SS_I2C_CLEAR_TAR(controller);
613 QM_SS_I2C_WRITE_TAR(controller, slave_addr);
614
615 /* enable controller */
616 controller_enable(i2c);
617
618 while (len--) {
619 if (len == 0 && stop) {
620 data_cmd |= QM_SS_I2C_DATA_CMD_STOP;
621 }
622
623 QM_SS_I2C_WRITE_DATA_CMD(controller, data_cmd);
624
625 /* wait if rx fifo is empty, break if tx empty and
626 * error*/
627 while (!(QM_SS_I2C_READ_STATUS(controller) &
628 QM_SS_I2C_STATUS_RFNE)) {
629 if (QM_SS_I2C_READ_INTR_STAT(controller) &
630 QM_SS_I2C_INTR_STAT_TX_ABRT) {
631 break;
632 }
633 }
634
635 if ((QM_SS_I2C_READ_INTR_STAT(controller) &
636 QM_SS_I2C_INTR_STAT_TX_ABRT)) {
637 ret = -EIO;
638 break;
639 }
640
641 QM_SS_I2C_READ_RX_FIFO(controller);
642
643 /* wait until rx fifo is empty, indicating pop is complete*/
644 while (
645 (QM_SS_I2C_READ_STATUS(controller) & QM_SS_I2C_STATUS_RFNE))
646 ;
647
648 /* IC_DATA_CMD[7:0] contains received data */
649 *d = QM_SS_I2C_READ_DATA_CMD(controller);
650 d++;
651 }
652
653 /* disable controller */
654 if (true == stop) {
655 if (controller_disable(i2c)) {
656 ret = -EBUSY;
657 }
658 }
659
660 if (status != NULL) {
661 qm_ss_i2c_get_status(i2c, status);
662 }
663
664 /* Clear abort status
665 * The controller flushes/resets/empties
666 * the TX FIFO whenever this bit is set. The TX
667 * FIFO remains in this flushed state until the
668 * register IC_CLR_TX_ABRT is read.
669 */
670 QM_SS_I2C_CLEAR_TX_ABRT_INTR(controller);
671
672 return ret;
673 }
674
675 int qm_ss_i2c_master_irq_transfer(const qm_ss_i2c_t i2c,
676 const qm_ss_i2c_transfer_t *const xfer,
677 const uint16_t slave_addr)
678 {
679 QM_CHECK(i2c < QM_SS_I2C_NUM, -EINVAL);
680 QM_CHECK(NULL != xfer, -EINVAL);
681
682 uint32_t controller = i2c_base[i2c];
683
684 /* write slave address to TAR */
685 QM_SS_I2C_CLEAR_TAR(controller);
686 QM_SS_I2C_WRITE_TAR(controller, slave_addr);
687
688 i2c_write_pos[i2c] = 0;
689 i2c_read_pos[i2c] = 0;
690 i2c_read_cmd_send[i2c] = xfer->rx_len;
691 i2c_transfer[i2c] = xfer;
692
693 /* set threshold */
694 if (xfer->rx_len > 0 && xfer->rx_len < (RX_TL + 1)) {
695 /* If 'rx_len' is less than the default threshold, we have to
696 * change the threshold value so the 'RX FULL' interrupt is
697 * generated once all data from the transfer is received.
698 */
699 QM_SS_I2C_CLEAR_RX_TL(controller);
700 QM_SS_I2C_CLEAR_TX_TL(controller);
701
702 QM_SS_I2C_WRITE_RX_TL(controller, (xfer->rx_len - 1));
703 QM_SS_I2C_WRITE_TX_TL(controller, TX_TL);
704 } else {
705 QM_SS_I2C_CLEAR_RX_TL(controller);
706 QM_SS_I2C_CLEAR_TX_TL(controller);
707
708 QM_SS_I2C_WRITE_RX_TL(controller, RX_TL);
709 QM_SS_I2C_WRITE_TX_TL(controller, TX_TL);
710 }
711
712 /* enable controller */
713 controller_enable(i2c);
714
715 /* Start filling tx fifo. */
716 i2c_fill_tx_fifo(i2c, xfer, controller);
717
718 /* unmask interrupts */
719 QM_SS_I2C_UNMASK_INTERRUPTS(controller);
720
721 return 0;
722 }
723
724 static void controller_enable(const qm_ss_i2c_t i2c)
725 {
726 uint32_t controller = i2c_base[i2c];
727 if (!(QM_SS_I2C_READ_ENABLE_STATUS(controller) &
728 QM_SS_I2C_ENABLE_STATUS_IC_EN)) {
729 /* enable controller */
730 QM_SS_I2C_ENABLE(controller);
731 /* wait until controller is enabled */
732 while (!(QM_SS_I2C_READ_ENABLE_STATUS(controller) &
733 QM_SS_I2C_ENABLE_STATUS_IC_EN))
734 ;
735 }
736
737 /* Clear all interruption flags */
738 QM_SS_I2C_CLEAR_ALL_INTR(controller);
739 }
740
741 static int controller_disable(const qm_ss_i2c_t i2c)
742 {
743 uint32_t controller = i2c_base[i2c];
744 int poll_count = I2C_POLL_COUNT;
745
746 /* disable controller */
747 QM_SS_I2C_DISABLE(controller);
748
749 /* wait until controller is disabled */
750 while ((QM_SS_I2C_READ_ENABLE_STATUS(controller) &
751 QM_SS_I2C_ENABLE_STATUS_IC_EN) &&
752 poll_count--) {
753 clk_sys_udelay(I2C_POLL_MICROSECOND);
754 }
755
756 /* returns 0 if ok, meaning controller is disabled */
757 return (QM_SS_I2C_READ_ENABLE_STATUS(controller) &
758 QM_SS_I2C_ENABLE_STATUS_IC_EN);
759 }
760
761 int qm_ss_i2c_irq_transfer_terminate(const qm_ss_i2c_t i2c)
762 {
763 QM_CHECK(i2c < QM_SS_I2C_NUM, -EINVAL);
764
765 uint32_t controller = i2c_base[i2c];
766
767 /* Abort:
768 * In response to an ABORT, the controller issues a STOP and
769 * flushes
770 * the Tx FIFO after completing the current transfer, then sets
771 * the
772 * TX_ABORT interrupt after the abort operation. The ABORT bit
773 * is
774 * cleared automatically by hardware after the abort operation.
775 */
776 QM_SS_I2C_ABORT(controller);
777
778 return 0;
779 }
780
781 #if (ENABLE_RESTORE_CONTEXT)
782 int qm_ss_i2c_save_context(const qm_ss_i2c_t i2c,
783 qm_ss_i2c_context_t *const ctx)
784 {
785 uint32_t controller = i2c_base[i2c];
786
787 QM_CHECK(i2c < QM_SS_I2C_NUM, -EINVAL);
788 QM_CHECK(ctx != NULL, -EINVAL);
789
790 ctx->i2c_fs_scl_cnt =
791 __builtin_arc_lr(controller + QM_SS_I2C_FS_SCL_CNT);
792 ctx->i2c_ss_scl_cnt =
793 __builtin_arc_lr(controller + QM_SS_I2C_SS_SCL_CNT);
794 ctx->i2c_con = __builtin_arc_lr(controller + QM_SS_I2C_CON);
795
796 return 0;
797 }
798
799 int qm_ss_i2c_restore_context(const qm_ss_i2c_t i2c,
800 const qm_ss_i2c_context_t *const ctx)
801 {
802 uint32_t controller = i2c_base[i2c];
803
804 QM_CHECK(i2c < QM_SS_I2C_NUM, -EINVAL);
805 QM_CHECK(ctx != NULL, -EINVAL);
806
807 __builtin_arc_sr(ctx->i2c_fs_scl_cnt,
808 controller + QM_SS_I2C_FS_SCL_CNT);
809 __builtin_arc_sr(ctx->i2c_ss_scl_cnt,
810 controller + QM_SS_I2C_SS_SCL_CNT);
811 __builtin_arc_sr(ctx->i2c_con, controller + QM_SS_I2C_CON);
812
813 return 0;
814 }
815 #else
816 int qm_ss_i2c_save_context(const qm_ss_i2c_t i2c,
817 qm_ss_i2c_context_t *const ctx)
818 {
819 (void)i2c;
820 (void)ctx;
821
822 return 0;
823 }
824
825 int qm_ss_i2c_restore_context(const qm_ss_i2c_t i2c,
826 const qm_ss_i2c_context_t *const ctx)
827 {
828 (void)i2c;
829 (void)ctx;
830
831 return 0;
832 }
833 #endif /* ENABLE_RESTORE_CONTEXT */
QM_SS_I2C_SPEED_FAST
Fast mode (400 Kbps).
Definition: qm_ss_i2c.h:47
qm_ss_i2c_speed_t
qm_ss_i2c_speed_t
QM SS I2C speed type.
Definition: qm_ss_i2c.h:45
qm_ss_i2c_transfer_t
QM SS I2C transfer type.
Definition: qm_ss_i2c.h:99
qm_ss_i2c_master_write
int qm_ss_i2c_master_write(const qm_ss_i2c_t i2c, const uint16_t slave_addr, const uint8_t *const data, uint32_t len, const bool stop, qm_ss_i2c_status_t *const status)
Master write on I2C.
Definition: qm_ss_i2c.c:526
qm_ss_i2c_master_irq_transfer
int qm_ss_i2c_master_irq_transfer(const qm_ss_i2c_t i2c, const qm_ss_i2c_transfer_t *const xfer, const uint16_t slave_addr)
Interrupt based master transfer on I2C.
Definition: qm_ss_i2c.c:675
qm_ss_i2c_transfer_t::rx
uint8_t * rx
Read data.
Definition: qm_ss_i2c.h:102
qm_ss_i2c_save_context
int qm_ss_i2c_save_context(const qm_ss_i2c_t i2c, qm_ss_i2c_context_t *const ctx)
Save SS I2C context.
Definition: qm_ss_i2c.c:782
QM_SS_I2C_IDLE
Controller idle.
Definition: qm_ss_i2c.h:57
QM_SS_I2C_TX_ABORT
Tx abort.
Definition: qm_ss_i2c.h:78
QM_ISR_DECLARE
QM_ISR_DECLARE(qm_ss_i2c_0_error_isr)
ISR for I2C 0 error interrupt.
Definition: qm_ss_i2c.c:294
qm_ss_i2c_t
qm_ss_i2c_t
Sensor Subsystem I2C.
Definition: qm_sensor_regs.h:532
qm_ss_i2c_transfer_t::tx
uint8_t * tx
Write data.
Definition: qm_ss_i2c.h:100
qm_ss_i2c_transfer_t::rx_len
uint32_t rx_len
Read buffer length.
Definition: qm_ss_i2c.h:103
qm_ss_i2c_transfer_t::callback
void(* callback)(void *data, int rc, qm_ss_i2c_status_t status, uint32_t len)
User callback.
Definition: qm_ss_i2c.h:115
QM_SS_I2C_TX_ABRT_USER_ABRT
User abort.
Definition: qm_ss_i2c.h:76
qm_ss_i2c_get_status
int qm_ss_i2c_get_status(const qm_ss_i2c_t i2c, qm_ss_i2c_status_t *const status)
Retrieve SS I2C status.
Definition: qm_ss_i2c.c:505
QM_SS_I2C_SPEED_STD
Standard mode (100 Kbps).
Definition: qm_ss_i2c.h:46
QM_SS_I2C_TX_OVER
Tx overflow.
Definition: qm_ss_i2c.h:79
QM_SS_I2C_BUSY
Controller busy.
Definition: qm_ss_i2c.h:77
clk_sys_udelay
void clk_sys_udelay(uint32_t microseconds)
Idle loop the processor for at least the value given in microseconds.
Definition: clk.c:352
clk_sys_get_ticks_per_us
uint32_t clk_sys_get_ticks_per_us(void)
Get number of system ticks per micro second.
Definition: clk.c:347
qm_ss_i2c_status_t
qm_ss_i2c_status_t
QM SS I2C status type.
Definition: qm_ss_i2c.h:56
qm_ss_i2c_master_read
int qm_ss_i2c_master_read(const qm_ss_i2c_t i2c, const uint16_t slave_addr, uint8_t *const data, uint32_t len, const bool stop, qm_ss_i2c_status_t *const status)
Master read of I2C.
Definition: qm_ss_i2c.c:598
QM_SS_I2C_RX_OVER
Rx overflow.
Definition: qm_ss_i2c.h:80
qm_i2c_t
qm_i2c_t
Number of I2C controllers.
Definition: qm_soc_regs.h:861
qm_ss_i2c_set_speed
int qm_ss_i2c_set_speed(const qm_ss_i2c_t i2c, const qm_ss_i2c_speed_t speed, const uint16_t lo_cnt, const uint16_t hi_cnt)
Set I2C speed.
Definition: qm_ss_i2c.c:450
qm_ss_i2c_config_t::speed
qm_ss_i2c_speed_t speed
Standard, fast or fast plus mode.
Definition: qm_ss_i2c.h:88
qm_ss_i2c_config_t
QM SS I2C configuration type.
Definition: qm_ss_i2c.h:87
qm_ss_i2c_restore_context
int qm_ss_i2c_restore_context(const qm_ss_i2c_t i2c, const qm_ss_i2c_context_t *const ctx)
Restore SS I2C context.
Definition: qm_ss_i2c.c:799
qm_ss_i2c_set_config
int qm_ss_i2c_set_config(const qm_ss_i2c_t i2c, const qm_ss_i2c_config_t *const cfg)
Set SS I2C configuration.
Definition: qm_ss_i2c.c:347
qm_ss_i2c_context_t
SS I2C context type.
Definition: qm_sensor_regs.h:235
qm_ss_i2c_transfer_t::tx_len
uint32_t tx_len
Write data length.
Definition: qm_ss_i2c.h:101
QM_SS_I2C_RX_UNDER
Rx underflow.
Definition: qm_ss_i2c.h:81
QM_SS_I2C_SPEED_FAST_PLUS
Fast plus mode (1 Mbps).
Definition: qm_ss_i2c.h:49
qm_ss_i2c_irq_transfer_terminate
int qm_ss_i2c_irq_transfer_terminate(const qm_ss_i2c_t i2c)
Terminate I2C IRQ/DMA transfer.
Definition: qm_ss_i2c.c:761
qm_ss_i2c_config_t::address_mode
qm_ss_i2c_addr_t address_mode
7 or 10 bit addressing.
Definition: qm_ss_i2c.h:89