blob: 2be7afe2df5bb5c296fa6f30f1c811dce15a9d7b [file] [log] [blame]
Yann Gautierbb836ee2018-07-16 17:55:07 +02001/*
Yann Gautier113f31e2019-01-17 09:34:18 +01002 * Copyright (c) 2016-2019, STMicroelectronics - All Rights Reserved
Yann Gautierbb836ee2018-07-16 17:55:07 +02003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
Yann Gautierbb836ee2018-07-16 17:55:07 +02007#include <errno.h>
Yann Gautierbb836ee2018-07-16 17:55:07 +02008#include <stdbool.h>
9#include <stdlib.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000010
11#include <arch_helpers.h>
12#include <drivers/delay_timer.h>
13#include <drivers/st/stm32_i2c.h>
14#include <lib/mmio.h>
Yann Gautierbb836ee2018-07-16 17:55:07 +020015
16/* STM32 I2C registers offsets */
17#define I2C_CR1 0x00U
18#define I2C_CR2 0x04U
19#define I2C_OAR1 0x08U
20#define I2C_OAR2 0x0CU
21#define I2C_TIMINGR 0x10U
22#define I2C_TIMEOUTR 0x14U
23#define I2C_ISR 0x18U
24#define I2C_ICR 0x1CU
25#define I2C_PECR 0x20U
26#define I2C_RXDR 0x24U
27#define I2C_TXDR 0x28U
28
29#define MAX_DELAY 0xFFFFFFFFU
30
31/* I2C TIMING clear register Mask */
32#define TIMING_CLEAR_MASK 0xF0FFFFFFU
33/* Timeout 25 ms */
34#define I2C_TIMEOUT_BUSY 25U
35
36#define MAX_NBYTE_SIZE 255U
37
38static int i2c_request_memory_write(struct i2c_handle_s *hi2c,
39 uint16_t dev_addr, uint16_t mem_addr,
40 uint16_t mem_add_size, uint32_t timeout,
41 uint32_t tick_start);
42static int i2c_request_memory_read(struct i2c_handle_s *hi2c, uint16_t dev_addr,
43 uint16_t mem_addr, uint16_t mem_add_size,
44 uint32_t timeout, uint32_t tick_start);
45
46/* Private functions to handle flags during polling transfer */
47static int i2c_wait_flag(struct i2c_handle_s *hi2c, uint32_t flag,
48 uint8_t awaited_value, uint32_t timeout,
49 uint32_t tick_start);
50static int i2c_wait_txis(struct i2c_handle_s *hi2c, uint32_t timeout,
51 uint32_t tick_start);
52static int i2c_wait_stop(struct i2c_handle_s *hi2c, uint32_t timeout,
53 uint32_t tick_start);
54static int i2c_ack_failed(struct i2c_handle_s *hi2c, uint32_t timeout,
55 uint32_t tick_start);
56
57/* Private function to flush TXDR register */
58static void i2c_flush_txdr(struct i2c_handle_s *hi2c);
59
60/* Private function to start, restart or stop a transfer */
61static void i2c_transfer_config(struct i2c_handle_s *hi2c, uint16_t dev_addr,
62 uint16_t size, uint32_t i2c_mode,
63 uint32_t request);
64
65/*
66 * @brief Initialize the I2C device.
67 * @param hi2c: Pointer to a struct i2c_handle_s structure that contains
68 * the configuration information for the specified I2C.
69 * @retval 0 if OK, negative value else
70 */
71int stm32_i2c_init(struct i2c_handle_s *hi2c)
72{
73 if (hi2c == NULL) {
74 return -ENOENT;
75 }
76
77 if (hi2c->i2c_state == I2C_STATE_RESET) {
78 hi2c->lock = 0;
79 }
80
81 hi2c->i2c_state = I2C_STATE_BUSY;
82
83 /* Disable the selected I2C peripheral */
84 mmio_clrbits_32(hi2c->i2c_base_addr + I2C_CR1, I2C_CR1_PE);
85
86 /* Configure I2Cx: Frequency range */
87 mmio_write_32(hi2c->i2c_base_addr + I2C_TIMINGR,
88 hi2c->i2c_init.timing & TIMING_CLEAR_MASK);
89
90 /* Disable Own Address1 before set the Own Address1 configuration */
91 mmio_clrbits_32(hi2c->i2c_base_addr + I2C_OAR1, I2C_OAR1_OA1EN);
92
93 /* Configure I2Cx: Own Address1 and ack own address1 mode */
94 if (hi2c->i2c_init.addressing_mode == I2C_ADDRESSINGMODE_7BIT) {
95 mmio_write_32(hi2c->i2c_base_addr + I2C_OAR1,
96 I2C_OAR1_OA1EN | hi2c->i2c_init.own_address1);
97 } else { /* I2C_ADDRESSINGMODE_10BIT */
98 mmio_write_32(hi2c->i2c_base_addr + I2C_OAR1,
99 I2C_OAR1_OA1EN | I2C_OAR1_OA1MODE |
100 hi2c->i2c_init.own_address1);
101 }
102
103 /* Configure I2Cx: Addressing Master mode */
104 if (hi2c->i2c_init.addressing_mode == I2C_ADDRESSINGMODE_10BIT) {
105 mmio_write_32(hi2c->i2c_base_addr + I2C_CR2, I2C_CR2_ADD10);
106 }
107
108 /*
109 * Enable the AUTOEND by default, and enable NACK
110 * (should be disable only during Slave process)
111 */
112 mmio_setbits_32(hi2c->i2c_base_addr + I2C_CR2,
113 I2C_CR2_AUTOEND | I2C_CR2_NACK);
114
115 /* Disable Own Address2 before set the Own Address2 configuration */
116 mmio_clrbits_32(hi2c->i2c_base_addr + I2C_OAR2, I2C_DUALADDRESS_ENABLE);
117
118 /* Configure I2Cx: Dual mode and Own Address2 */
119 mmio_write_32(hi2c->i2c_base_addr + I2C_OAR2,
120 hi2c->i2c_init.dual_address_mode |
121 hi2c->i2c_init.own_address2 |
122 (hi2c->i2c_init.own_address2_masks << 8));
123
124 /* Configure I2Cx: Generalcall and NoStretch mode */
125 mmio_write_32(hi2c->i2c_base_addr + I2C_CR1,
126 hi2c->i2c_init.general_call_mode |
127 hi2c->i2c_init.no_stretch_mode);
128
129 /* Enable the selected I2C peripheral */
130 mmio_setbits_32(hi2c->i2c_base_addr + I2C_CR1, I2C_CR1_PE);
131
132 hi2c->i2c_err = I2C_ERROR_NONE;
133 hi2c->i2c_state = I2C_STATE_READY;
134 hi2c->i2c_mode = I2C_MODE_NONE;
135
136 return 0;
137}
138
139/*
140 * @brief Write an amount of data in blocking mode to a specific memory address
141 * @param hi2c: Pointer to a struct i2c_handle_s structure that contains
142 * the configuration information for the specified I2C.
143 * @param dev_addr: Target device address
144 * @param mem_addr: Internal memory address
145 * @param mem_add_size: size of internal memory address
146 * @param p_data: Pointer to data buffer
147 * @param size: Amount of data to be sent
148 * @param timeout: timeout duration
149 * @retval 0 if OK, negative value else
150 */
151int stm32_i2c_mem_write(struct i2c_handle_s *hi2c, uint16_t dev_addr,
152 uint16_t mem_addr, uint16_t mem_add_size,
153 uint8_t *p_data, uint16_t size, uint32_t timeout)
154{
155 uint32_t tickstart;
156
157 if ((hi2c->i2c_state != I2C_STATE_READY) || (hi2c->lock != 0U)) {
158 return -EBUSY;
159 }
160
161 if ((p_data == NULL) || (size == 0U)) {
162 return -EINVAL;
163 }
164
165 hi2c->lock = 1;
166
167 tickstart = (uint32_t)read_cntpct_el0();
168
169 if (i2c_wait_flag(hi2c, I2C_FLAG_BUSY, 1, I2C_TIMEOUT_BUSY,
170 tickstart) != 0) {
171 return -EIO;
172 }
173
174 hi2c->i2c_state = I2C_STATE_BUSY_TX;
175 hi2c->i2c_mode = I2C_MODE_MEM;
176 hi2c->i2c_err = I2C_ERROR_NONE;
177
178 hi2c->p_buff = p_data;
179 hi2c->xfer_count = size;
180
181 /* Send Slave Address and Memory Address */
182 if (i2c_request_memory_write(hi2c, dev_addr, mem_addr, mem_add_size,
183 timeout, tickstart) != 0) {
184 hi2c->lock = 0;
185 return -EIO;
186 }
187
188 /*
189 * Set NBYTES to write and reload
190 * if hi2c->xfer_count > MAX_NBYTE_SIZE
191 */
192 if (hi2c->xfer_count > MAX_NBYTE_SIZE) {
193 hi2c->xfer_size = MAX_NBYTE_SIZE;
194 i2c_transfer_config(hi2c, dev_addr, hi2c->xfer_size,
195 I2C_RELOAD_MODE, I2C_NO_STARTSTOP);
196 } else {
197 hi2c->xfer_size = hi2c->xfer_count;
198 i2c_transfer_config(hi2c, dev_addr, hi2c->xfer_size,
199 I2C_AUTOEND_MODE, I2C_NO_STARTSTOP);
200 }
201
202 do {
203 if (i2c_wait_txis(hi2c, timeout, tickstart) != 0) {
204 return -EIO;
205 }
206
207 mmio_write_8(hi2c->i2c_base_addr + I2C_TXDR, *hi2c->p_buff);
208 hi2c->p_buff++;
209 hi2c->xfer_count--;
210 hi2c->xfer_size--;
211
212 if ((hi2c->xfer_count != 0U) && (hi2c->xfer_size == 0U)) {
213 /* Wait until TCR flag is set */
214 if (i2c_wait_flag(hi2c, I2C_FLAG_TCR, 0, timeout,
215 tickstart) != 0) {
216 return -EIO;
217 }
218
219 if (hi2c->xfer_count > MAX_NBYTE_SIZE) {
220 hi2c->xfer_size = MAX_NBYTE_SIZE;
221 i2c_transfer_config(hi2c, dev_addr,
222 hi2c->xfer_size,
223 I2C_RELOAD_MODE,
224 I2C_NO_STARTSTOP);
225 } else {
226 hi2c->xfer_size = hi2c->xfer_count;
227 i2c_transfer_config(hi2c, dev_addr,
228 hi2c->xfer_size,
229 I2C_AUTOEND_MODE,
230 I2C_NO_STARTSTOP);
231 }
232 }
233
234 } while (hi2c->xfer_count > 0U);
235
236 /*
237 * No need to Check TC flag, with AUTOEND mode the stop
238 * is automatically generated.
239 * Wait until STOPF flag is reset.
240 */
241 if (i2c_wait_stop(hi2c, timeout, tickstart) != 0) {
242 return -EIO;
243 }
244
245 mmio_write_32(hi2c->i2c_base_addr + I2C_ICR, I2C_FLAG_STOPF);
246
247 mmio_clrbits_32(hi2c->i2c_base_addr + I2C_CR2, I2C_RESET_CR2);
248
249 hi2c->i2c_state = I2C_STATE_READY;
250 hi2c->i2c_mode = I2C_MODE_NONE;
251
252 hi2c->lock = 0;
253
254 return 0;
255}
256
257/*
258 * @brief Read an amount of data in blocking mode from a specific memory
259 * address
260 * @param hi2c: Pointer to a struct i2c_handle_s structure that contains
261 * the configuration information for the specified I2C.
262 * @param dev_addr: Target device address
263 * @param mem_addr: Internal memory address
264 * @param mem_add_size: size of internal memory address
265 * @param p_data: Pointer to data buffer
266 * @param size: Amount of data to be sent
267 * @param timeout: timeout duration
268 * @retval 0 if OK, negative value else
269 */
270int stm32_i2c_mem_read(struct i2c_handle_s *hi2c, uint16_t dev_addr,
271 uint16_t mem_addr, uint16_t mem_add_size,
272 uint8_t *p_data, uint16_t size, uint32_t timeout)
273{
274 uint32_t tickstart;
275
276 if ((hi2c->i2c_state != I2C_STATE_READY) || (hi2c->lock != 0U)) {
277 return -EBUSY;
278 }
279
280 if ((p_data == NULL) || (size == 0U)) {
281 return -EINVAL;
282 }
283
284 hi2c->lock = 1;
285
286 tickstart = (uint32_t)read_cntpct_el0();
287
288 if (i2c_wait_flag(hi2c, I2C_FLAG_BUSY, 1, I2C_TIMEOUT_BUSY,
289 tickstart) != 0) {
290 return -EIO;
291 }
292
293 hi2c->i2c_state = I2C_STATE_BUSY_RX;
294 hi2c->i2c_mode = I2C_MODE_MEM;
295 hi2c->i2c_err = I2C_ERROR_NONE;
296
297 hi2c->p_buff = p_data;
298 hi2c->xfer_count = size;
299
300 /* Send Slave Address and Memory Address */
301 if (i2c_request_memory_read(hi2c, dev_addr, mem_addr, mem_add_size,
302 timeout, tickstart) != 0) {
303 hi2c->lock = 0;
304 return -EIO;
305 }
306
307 /*
308 * Send Slave Address.
309 * Set NBYTES to write and reload if hi2c->xfer_count > MAX_NBYTE_SIZE
310 * and generate RESTART.
311 */
312 if (hi2c->xfer_count > MAX_NBYTE_SIZE) {
313 hi2c->xfer_size = MAX_NBYTE_SIZE;
314 i2c_transfer_config(hi2c, dev_addr, hi2c->xfer_size,
315 I2C_RELOAD_MODE, I2C_GENERATE_START_READ);
316 } else {
317 hi2c->xfer_size = hi2c->xfer_count;
318 i2c_transfer_config(hi2c, dev_addr, hi2c->xfer_size,
319 I2C_AUTOEND_MODE, I2C_GENERATE_START_READ);
320 }
321
322 do {
323 if (i2c_wait_flag(hi2c, I2C_FLAG_RXNE, 0, timeout,
324 tickstart) != 0) {
325 return -EIO;
326 }
327
328 *hi2c->p_buff = mmio_read_8(hi2c->i2c_base_addr + I2C_RXDR);
329 hi2c->p_buff++;
330 hi2c->xfer_size--;
331 hi2c->xfer_count--;
332
333 if ((hi2c->xfer_count != 0U) && (hi2c->xfer_size == 0U)) {
334 if (i2c_wait_flag(hi2c, I2C_FLAG_TCR, 0, timeout,
335 tickstart) != 0) {
336 return -EIO;
337 }
338
339 if (hi2c->xfer_count > MAX_NBYTE_SIZE) {
340 hi2c->xfer_size = MAX_NBYTE_SIZE;
341 i2c_transfer_config(hi2c, dev_addr,
342 hi2c->xfer_size,
343 I2C_RELOAD_MODE,
344 I2C_NO_STARTSTOP);
345 } else {
346 hi2c->xfer_size = hi2c->xfer_count;
347 i2c_transfer_config(hi2c, dev_addr,
348 hi2c->xfer_size,
349 I2C_AUTOEND_MODE,
350 I2C_NO_STARTSTOP);
351 }
352 }
353 } while (hi2c->xfer_count > 0U);
354
355 /*
356 * No need to Check TC flag, with AUTOEND mode the stop
357 * is automatically generated
358 * Wait until STOPF flag is reset
359 */
360 if (i2c_wait_stop(hi2c, timeout, tickstart) != 0) {
361 return -EIO;
362 }
363
364 mmio_write_32(hi2c->i2c_base_addr + I2C_ICR, I2C_FLAG_STOPF);
365
366 mmio_clrbits_32(hi2c->i2c_base_addr + I2C_CR2, I2C_RESET_CR2);
367
368 hi2c->i2c_state = I2C_STATE_READY;
369 hi2c->i2c_mode = I2C_MODE_NONE;
370
371 hi2c->lock = 0;
372
373 return 0;
374}
375
376/*
377 * @brief Checks if target device is ready for communication.
378 * @note This function is used with Memory devices
379 * @param hi2c: Pointer to a struct i2c_handle_s structure that contains
380 * the configuration information for the specified I2C.
381 * @param dev_addr: Target device address
382 * @param trials: Number of trials
383 * @param timeout: timeout duration
384 * @retval 0 if OK, negative value else
385 */
386int stm32_i2c_is_device_ready(struct i2c_handle_s *hi2c,
387 uint16_t dev_addr, uint32_t trials,
388 uint32_t timeout)
389{
390 uint32_t i2c_trials = 0U;
391
392 if ((hi2c->i2c_state != I2C_STATE_READY) || (hi2c->lock != 0U)) {
393 return -EBUSY;
394 }
395
396 if ((mmio_read_32(hi2c->i2c_base_addr + I2C_ISR) & I2C_FLAG_BUSY) !=
397 0U) {
398 return -EBUSY;
399 }
400
401 hi2c->lock = 1;
402
403 hi2c->i2c_state = I2C_STATE_BUSY;
404 hi2c->i2c_err = I2C_ERROR_NONE;
405
406 do {
407 uint32_t tickstart;
408
409 /* Generate Start */
410 if (hi2c->i2c_init.addressing_mode == I2C_ADDRESSINGMODE_7BIT) {
411 mmio_write_32(hi2c->i2c_base_addr + I2C_CR2,
412 (((uint32_t)dev_addr & I2C_CR2_SADD) |
413 I2C_CR2_START | I2C_CR2_AUTOEND) &
414 ~I2C_CR2_RD_WRN);
415 } else {
416 mmio_write_32(hi2c->i2c_base_addr + I2C_CR2,
417 (((uint32_t)dev_addr & I2C_CR2_SADD) |
418 I2C_CR2_START | I2C_CR2_ADD10) &
419 ~I2C_CR2_RD_WRN);
420 }
421
422 /*
423 * No need to Check TC flag, with AUTOEND mode the stop
424 * is automatically generated
425 * Wait until STOPF flag is set or a NACK flag is set
426 */
427 tickstart = (uint32_t)read_cntpct_el0();
428 while (((mmio_read_32(hi2c->i2c_base_addr + I2C_ISR) &
429 (I2C_FLAG_STOPF | I2C_FLAG_AF)) == 0U) &&
430 (hi2c->i2c_state != I2C_STATE_TIMEOUT)) {
431 if (timeout != MAX_DELAY) {
432 if ((((uint32_t)read_cntpct_el0() - tickstart) >
433 timeout) || (timeout == 0U)) {
434 hi2c->i2c_state = I2C_STATE_READY;
435
436 hi2c->i2c_err |=
437 I2C_ERROR_TIMEOUT;
438
439 hi2c->lock = 0;
440
441 return -EIO;
442 }
443 }
444 }
445
446 /* Check if the NACKF flag has not been set */
447 if ((mmio_read_32(hi2c->i2c_base_addr + I2C_ISR) &
448 I2C_FLAG_AF) == 0U) {
449 if (i2c_wait_flag(hi2c, I2C_FLAG_STOPF, 0, timeout,
450 tickstart) != 0) {
451 return -EIO;
452 }
453
454 mmio_write_32(hi2c->i2c_base_addr + I2C_ICR,
455 I2C_FLAG_STOPF);
456
457 hi2c->i2c_state = I2C_STATE_READY;
458
459 hi2c->lock = 0;
460
461 return 0;
462 }
463
464 if (i2c_wait_flag(hi2c, I2C_FLAG_STOPF, 0, timeout,
465 tickstart) != 0) {
466 return -EIO;
467 }
468
469 mmio_write_32(hi2c->i2c_base_addr + I2C_ICR, I2C_FLAG_AF);
470
471 mmio_write_32(hi2c->i2c_base_addr + I2C_ICR, I2C_FLAG_STOPF);
472
473 if (i2c_trials == trials) {
474 mmio_setbits_32(hi2c->i2c_base_addr + I2C_CR2,
475 I2C_CR2_STOP);
476
477 if (i2c_wait_flag(hi2c, I2C_FLAG_STOPF, 0, timeout,
478 tickstart) != 0) {
479 return -EIO;
480 }
481
482 mmio_write_32(hi2c->i2c_base_addr + I2C_ICR,
483 I2C_FLAG_STOPF);
484 }
485
486 i2c_trials++;
487 } while (i2c_trials < trials);
488
489 hi2c->i2c_state = I2C_STATE_READY;
490
491 hi2c->i2c_err |= I2C_ERROR_TIMEOUT;
492
493 hi2c->lock = 0;
494
495 return -EIO;
496}
497
498/*
499 * @brief Master sends target device address followed by internal memory
500 * address for write request.
501 * @param hi2c: Pointer to a struct i2c_handle_s structure that contains
502 * the configuration information for the specified I2C.
503 * @param dev_addr: Target device address
504 * @param mem_addr: Internal memory address
505 * @param mem_add_size: size of internal memory address
506 * @param timeout: timeout duration
507 * @param tick_start Tick start value
508 * @retval 0 if OK, negative value else
509 */
510static int i2c_request_memory_write(struct i2c_handle_s *hi2c,
511 uint16_t dev_addr, uint16_t mem_addr,
512 uint16_t mem_add_size, uint32_t timeout,
513 uint32_t tick_start)
514{
515 i2c_transfer_config(hi2c, dev_addr, mem_add_size, I2C_RELOAD_MODE,
516 I2C_GENERATE_START_WRITE);
517
518 if (i2c_wait_txis(hi2c, timeout, tick_start) != 0) {
519 return -EIO;
520 }
521
522 if (mem_add_size == I2C_MEMADD_SIZE_8BIT) {
523 /* Send Memory Address */
524 mmio_write_8(hi2c->i2c_base_addr + I2C_TXDR,
525 (uint8_t)(mem_addr & 0x00FFU));
526 } else {
527 /* Send MSB of Memory Address */
528 mmio_write_8(hi2c->i2c_base_addr + I2C_TXDR,
529 (uint8_t)((mem_addr & 0xFF00U) >> 8));
530
531 /* Wait until TXIS flag is set */
532 if (i2c_wait_txis(hi2c, timeout, tick_start) != 0) {
533 return -EIO;
534 }
535
536 /* Send LSB of Memory Address */
537 mmio_write_8(hi2c->i2c_base_addr + I2C_TXDR,
538 (uint8_t)(mem_addr & 0x00FFU));
539 }
540
541 if (i2c_wait_flag(hi2c, I2C_FLAG_TCR, 0, timeout, tick_start) !=
542 0) {
543 return -EIO;
544 }
545
546 return 0;
547}
548
549/*
550 * @brief Master sends target device address followed by internal memory
551 * address for read request.
552 * @param hi2c: Pointer to a struct i2c_handle_s structure that contains
553 * the configuration information for the specified I2C.
554 * @param dev_addr: Target device address
555 * @param mem_addr: Internal memory address
556 * @param mem_add_size: size of internal memory address
557 * @param timeout: timeout duration
558 * @param tick_start Tick start value
559 * @retval 0 if OK, negative value else
560 */
561static int i2c_request_memory_read(struct i2c_handle_s *hi2c, uint16_t dev_addr,
562 uint16_t mem_addr, uint16_t mem_add_size,
563 uint32_t timeout, uint32_t tick_start)
564{
565 i2c_transfer_config(hi2c, dev_addr, mem_add_size, I2C_SOFTEND_MODE,
566 I2C_GENERATE_START_WRITE);
567
568 if (i2c_wait_txis(hi2c, timeout, tick_start) != 0) {
569 return -EIO;
570 }
571
572 if (mem_add_size == I2C_MEMADD_SIZE_8BIT) {
573 /* Send Memory Address */
574 mmio_write_8(hi2c->i2c_base_addr + I2C_TXDR,
575 (uint8_t)(mem_addr & 0x00FFU));
576 } else {
577 /* Send MSB of Memory Address */
578 mmio_write_8(hi2c->i2c_base_addr + I2C_TXDR,
579 (uint8_t)((mem_addr & 0xFF00U) >> 8));
580
581 /* Wait until TXIS flag is set */
582 if (i2c_wait_txis(hi2c, timeout, tick_start) != 0) {
583 return -EIO;
584 }
585
586 /* Send LSB of Memory Address */
587 mmio_write_8(hi2c->i2c_base_addr + I2C_TXDR,
588 (uint8_t)(mem_addr & 0x00FFU));
589 }
590
591 if (i2c_wait_flag(hi2c, I2C_FLAG_TC, 0, timeout, tick_start) != 0) {
592 return -EIO;
593 }
594
595 return 0;
596}
597
598/*
599 * @brief I2C Tx data register flush process.
600 * @param hi2c: I2C handle.
601 * @retval None
602 */
603static void i2c_flush_txdr(struct i2c_handle_s *hi2c)
604{
605 /*
606 * If a pending TXIS flag is set,
607 * write a dummy data in TXDR to clear it.
608 */
609 if ((mmio_read_32(hi2c->i2c_base_addr + I2C_ISR) & I2C_FLAG_TXIS) !=
610 0U) {
611 mmio_write_32(hi2c->i2c_base_addr + I2C_TXDR, 0);
612 }
613
614 /* Flush TX register if not empty */
615 if ((mmio_read_32(hi2c->i2c_base_addr + I2C_ISR) & I2C_FLAG_TXE) ==
616 0U) {
617 mmio_setbits_32(hi2c->i2c_base_addr + I2C_ISR,
618 I2C_FLAG_TXE);
619 }
620}
621
622/*
623 * @brief This function handles I2C Communication timeout.
624 * @param hi2c: Pointer to a struct i2c_handle_s structure that contains
625 * the configuration information for the specified I2C.
626 * @param flag: Specifies the I2C flag to check.
627 * @param awaited_value: The awaited bit value for the flag (0 or 1).
628 * @param timeout: timeout duration
629 * @param tick_start: Tick start value
630 * @retval 0 if OK, negative value else
631 */
632static int i2c_wait_flag(struct i2c_handle_s *hi2c, uint32_t flag,
633 uint8_t awaited_value, uint32_t timeout,
634 uint32_t tick_start)
635{
636 uint8_t flag_check;
637
638 do {
639 flag_check = ((mmio_read_32(hi2c->i2c_base_addr + I2C_ISR) &
640 flag) == flag) ? 1U : 0U;
641
642 if (timeout != MAX_DELAY) {
643 if ((((uint32_t)read_cntpct_el0() - tick_start) >
644 timeout) || (timeout == 0U)) {
645 hi2c->i2c_err |= I2C_ERROR_TIMEOUT;
646 hi2c->i2c_state = I2C_STATE_READY;
647 hi2c->i2c_mode = I2C_MODE_NONE;
648
649 hi2c->lock = 0;
650 return -EIO;
651 }
652 }
653 } while (flag_check == awaited_value);
654
655 return 0;
656}
657
658/*
659 * @brief This function handles I2C Communication timeout for specific usage
660 * of TXIS flag.
661 * @param hi2c: Pointer to a struct i2c_handle_s structure that contains
662 * the configuration information for the specified I2C.
663 * @param timeout: timeout duration
664 * @param tick_start: Tick start value
665 * @retval 0 if OK, negative value else
666 */
667static int i2c_wait_txis(struct i2c_handle_s *hi2c, uint32_t timeout,
668 uint32_t tick_start)
669{
670 while ((mmio_read_32(hi2c->i2c_base_addr + I2C_ISR) &
671 I2C_FLAG_TXIS) == 0U) {
672 if (i2c_ack_failed(hi2c, timeout, tick_start) != 0) {
673 return -EIO;
674 }
675
676 if (timeout != MAX_DELAY) {
677 if ((((uint32_t)read_cntpct_el0() - tick_start) >
678 timeout) || (timeout == 0U)) {
679 hi2c->i2c_err |= I2C_ERROR_TIMEOUT;
680 hi2c->i2c_state = I2C_STATE_READY;
681 hi2c->i2c_mode = I2C_MODE_NONE;
682
683 hi2c->lock = 0;
684
685 return -EIO;
686 }
687 }
688 }
689
690 return 0;
691}
692
693/*
694 * @brief This function handles I2C Communication timeout for specific
695 * usage of STOP flag.
696 * @param hi2c: Pointer to a struct i2c_handle_s structure that contains
697 * the configuration information for the specified I2C.
698 * @param timeout: timeout duration
699 * @param tick_start: Tick start value
700 * @retval 0 if OK, negative value else
701 */
702static int i2c_wait_stop(struct i2c_handle_s *hi2c, uint32_t timeout,
703 uint32_t tick_start)
704{
705 while ((mmio_read_32(hi2c->i2c_base_addr + I2C_ISR) &
706 I2C_FLAG_STOPF) == 0U) {
707 if (i2c_ack_failed(hi2c, timeout, tick_start) != 0) {
708 return -EIO;
709 }
710
711 if ((((uint32_t)read_cntpct_el0() - tick_start) > timeout) ||
712 (timeout == 0U)) {
713 hi2c->i2c_err |= I2C_ERROR_TIMEOUT;
714 hi2c->i2c_state = I2C_STATE_READY;
715 hi2c->i2c_mode = I2C_MODE_NONE;
716
717 hi2c->lock = 0;
718
719 return -EIO;
720 }
721 }
722
723 return 0;
724}
725
726/*
727 * @brief This function handles Acknowledge failed detection during
728 * an I2C Communication.
729 * @param hi2c: Pointer to a struct i2c_handle_s structure that contains
730 * the configuration information for the specified I2C.
731 * @param timeout: timeout duration
732 * @param tick_start: Tick start value
733 * @retval 0 if OK, negative value else
734 */
735static int i2c_ack_failed(struct i2c_handle_s *hi2c, uint32_t timeout,
736 uint32_t tick_start)
737{
738 if ((mmio_read_32(hi2c->i2c_base_addr + I2C_ISR) & I2C_FLAG_AF) == 0U) {
739 return 0;
740 }
741
742 /*
743 * Wait until STOP Flag is reset.
744 * AutoEnd should be initiate after AF.
745 */
746 while ((mmio_read_32(hi2c->i2c_base_addr + I2C_ISR) &
747 I2C_FLAG_STOPF) == 0U) {
748 if (timeout != MAX_DELAY) {
749 if ((((uint32_t)read_cntpct_el0() - tick_start) >
750 timeout) || (timeout == 0U)) {
751 hi2c->i2c_err |= I2C_ERROR_TIMEOUT;
752 hi2c->i2c_state = I2C_STATE_READY;
753 hi2c->i2c_mode = I2C_MODE_NONE;
754
755 hi2c->lock = 0;
756
757 return -EIO;
758 }
759 }
760 }
761
762 mmio_write_32(hi2c->i2c_base_addr + I2C_ICR, I2C_FLAG_AF);
763
764 mmio_write_32(hi2c->i2c_base_addr + I2C_ICR, I2C_FLAG_STOPF);
765
766 i2c_flush_txdr(hi2c);
767
768 mmio_clrbits_32(hi2c->i2c_base_addr + I2C_CR2, I2C_RESET_CR2);
769
770 hi2c->i2c_err |= I2C_ERROR_AF;
771 hi2c->i2c_state = I2C_STATE_READY;
772 hi2c->i2c_mode = I2C_MODE_NONE;
773
774 hi2c->lock = 0;
775
776 return -EIO;
777}
778
779/*
780 * @brief Handles I2Cx communication when starting transfer or during transfer
781 * (TC or TCR flag are set).
782 * @param hi2c: I2C handle.
783 * @param dev_addr: Specifies the slave address to be programmed.
784 * @param size: Specifies the number of bytes to be programmed.
785 * This parameter must be a value between 0 and 255.
786 * @param i2c_mode: New state of the I2C START condition generation.
787 * This parameter can be one of the following values:
788 * @arg @ref I2C_RELOAD_MODE: Enable Reload mode .
789 * @arg @ref I2C_AUTOEND_MODE: Enable Automatic end mode.
790 * @arg @ref I2C_SOFTEND_MODE: Enable Software end mode.
791 * @param request: New state of the I2C START condition generation.
792 * This parameter can be one of the following values:
793 * @arg @ref I2C_NO_STARTSTOP: Don't Generate stop and start condition.
794 * @arg @ref I2C_GENERATE_STOP: Generate stop condition
795 * (size should be set to 0).
796 * @arg @ref I2C_GENERATE_START_READ: Generate Restart for read request.
797 * @arg @ref I2C_GENERATE_START_WRITE: Generate Restart for write request.
798 * @retval None
799 */
800static void i2c_transfer_config(struct i2c_handle_s *hi2c, uint16_t dev_addr,
801 uint16_t size, uint32_t i2c_mode,
802 uint32_t request)
803{
804 uint32_t clr_value, set_value;
805
806 clr_value = (I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD |
807 I2C_CR2_AUTOEND | I2C_CR2_START | I2C_CR2_STOP) |
808 (I2C_CR2_RD_WRN & (request >> (31U - I2C_CR2_RD_WRN_OFFSET)));
809
810 set_value = ((uint32_t)dev_addr & I2C_CR2_SADD) |
811 (((uint32_t)size << I2C_CR2_NBYTES_OFFSET) & I2C_CR2_NBYTES) |
812 i2c_mode | request;
813
814 mmio_clrsetbits_32(hi2c->i2c_base_addr + I2C_CR2, clr_value, set_value);
815}
816
817/*
818 * @brief Configure I2C Analog noise filter.
819 * @param hi2c: Pointer to a struct i2c_handle_s structure that contains
820 * the configuration information for the specified I2Cx peripheral
821 * @param analog_filter: New state of the Analog filter.
822 * @retval 0 if OK, negative value else
823 */
824int stm32_i2c_config_analog_filter(struct i2c_handle_s *hi2c,
825 uint32_t analog_filter)
826{
827 if ((hi2c->i2c_state != I2C_STATE_READY) || (hi2c->lock != 0U)) {
828 return -EBUSY;
829 }
830
831 hi2c->lock = 1;
832
833 hi2c->i2c_state = I2C_STATE_BUSY;
834
835 /* Disable the selected I2C peripheral */
836 mmio_clrbits_32(hi2c->i2c_base_addr + I2C_CR1, I2C_CR1_PE);
837
838 /* Reset I2Cx ANOFF bit */
839 mmio_clrbits_32(hi2c->i2c_base_addr + I2C_CR1, I2C_CR1_ANFOFF);
840
841 /* Set analog filter bit*/
842 mmio_setbits_32(hi2c->i2c_base_addr + I2C_CR1, analog_filter);
843
844 /* Enable the selected I2C peripheral */
845 mmio_setbits_32(hi2c->i2c_base_addr + I2C_CR1, I2C_CR1_PE);
846
847 hi2c->i2c_state = I2C_STATE_READY;
848
849 hi2c->lock = 0;
850
851 return 0;
852}