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