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