mbed library sources. Supersedes mbed-src.

Dependents:   Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more

Committer:
AnnaBridge
Date:
Wed Feb 20 22:31:08 2019 +0000
Revision:
189:f392fc9709a3
Parent:
188:bcfe06ba3d64
mbed library release version 165

Who changed what in which revision?

UserRevisionLine numberNew contents of line
<> 153:fa9ff456f731 1 /* mbed Microcontroller Library
<> 153:fa9ff456f731 2 *******************************************************************************
<> 153:fa9ff456f731 3 * Copyright (c) 2015, STMicroelectronics
<> 153:fa9ff456f731 4 * All rights reserved.
<> 153:fa9ff456f731 5 *
<> 153:fa9ff456f731 6 * Redistribution and use in source and binary forms, with or without
<> 153:fa9ff456f731 7 * modification, are permitted provided that the following conditions are met:
<> 153:fa9ff456f731 8 *
<> 153:fa9ff456f731 9 * 1. Redistributions of source code must retain the above copyright notice,
<> 153:fa9ff456f731 10 * this list of conditions and the following disclaimer.
<> 153:fa9ff456f731 11 * 2. Redistributions in binary form must reproduce the above copyright notice,
<> 153:fa9ff456f731 12 * this list of conditions and the following disclaimer in the documentation
<> 153:fa9ff456f731 13 * and/or other materials provided with the distribution.
<> 153:fa9ff456f731 14 * 3. Neither the name of STMicroelectronics nor the names of its contributors
<> 153:fa9ff456f731 15 * may be used to endorse or promote products derived from this software
<> 153:fa9ff456f731 16 * without specific prior written permission.
<> 153:fa9ff456f731 17 *
<> 153:fa9ff456f731 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
<> 153:fa9ff456f731 19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
<> 153:fa9ff456f731 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
<> 153:fa9ff456f731 21 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
<> 153:fa9ff456f731 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
<> 153:fa9ff456f731 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
<> 153:fa9ff456f731 24 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
<> 153:fa9ff456f731 25 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
<> 153:fa9ff456f731 26 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
<> 153:fa9ff456f731 27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<> 153:fa9ff456f731 28 *******************************************************************************
<> 153:fa9ff456f731 29 */
<> 153:fa9ff456f731 30
<> 153:fa9ff456f731 31
<> 153:fa9ff456f731 32 #include "mbed_assert.h"
<> 153:fa9ff456f731 33 #include "i2c_api.h"
<> 160:d5399cc887bb 34 #include "platform/mbed_wait_api.h"
<> 153:fa9ff456f731 35
<> 153:fa9ff456f731 36 #if DEVICE_I2C
<> 153:fa9ff456f731 37
<> 153:fa9ff456f731 38 #include "cmsis.h"
<> 153:fa9ff456f731 39 #include "pinmap.h"
<> 153:fa9ff456f731 40 #include "PeripheralPins.h"
<> 153:fa9ff456f731 41 #include "i2c_device.h" // family specific defines
<> 153:fa9ff456f731 42
<> 153:fa9ff456f731 43 #ifndef DEBUG_STDIO
<> 153:fa9ff456f731 44 # define DEBUG_STDIO 0
<> 153:fa9ff456f731 45 #endif
<> 153:fa9ff456f731 46
<> 153:fa9ff456f731 47 #if DEBUG_STDIO
<> 153:fa9ff456f731 48 # include <stdio.h>
<> 153:fa9ff456f731 49 # define DEBUG_PRINTF(...) do { printf(__VA_ARGS__); } while(0)
<> 153:fa9ff456f731 50 #else
<> 153:fa9ff456f731 51 # define DEBUG_PRINTF(...) {}
<> 153:fa9ff456f731 52 #endif
<> 153:fa9ff456f731 53
<> 153:fa9ff456f731 54 #if DEVICE_I2C_ASYNCH
AnnaBridge 187:0387e8f68319 55 #define I2C_S(obj) (struct i2c_s *) (&((obj)->i2c))
<> 153:fa9ff456f731 56 #else
AnnaBridge 187:0387e8f68319 57 #define I2C_S(obj) (struct i2c_s *) (obj)
<> 153:fa9ff456f731 58 #endif
<> 153:fa9ff456f731 59
<> 153:fa9ff456f731 60 /* Family specific description for I2C */
<> 153:fa9ff456f731 61 #define I2C_NUM (5)
AnnaBridge 187:0387e8f68319 62 static I2C_HandleTypeDef *i2c_handles[I2C_NUM];
<> 153:fa9ff456f731 63
<> 153:fa9ff456f731 64 /* Timeout values are based on core clock and I2C clock.
<> 153:fa9ff456f731 65 The BYTE_TIMEOUT is computed as twice the number of cycles it would
<> 153:fa9ff456f731 66 take to send 10 bits over I2C. Most Flags should take less than that.
<> 153:fa9ff456f731 67 This is for immediate FLAG or ACK check.
<> 153:fa9ff456f731 68 */
<> 153:fa9ff456f731 69 #define BYTE_TIMEOUT ((SystemCoreClock / obj_s->hz) * 2 * 10)
<> 153:fa9ff456f731 70 /* Timeout values based on I2C clock.
<> 153:fa9ff456f731 71 The BYTE_TIMEOUT_US is computed as 3x the time in us it would
<> 153:fa9ff456f731 72 take to send 10 bits over I2C. Most Flags should take less than that.
<> 153:fa9ff456f731 73 This is for complete transfers check.
<> 153:fa9ff456f731 74 */
<> 153:fa9ff456f731 75 #define BYTE_TIMEOUT_US ((SystemCoreClock / obj_s->hz) * 3 * 10)
<> 153:fa9ff456f731 76 /* Timeout values for flags and events waiting loops. These timeouts are
<> 153:fa9ff456f731 77 not based on accurate values, they just guarantee that the application will
AnnaBridge 187:0387e8f68319 78 not remain stuck if the I2C communication is corrupted.
<> 153:fa9ff456f731 79 */
<> 153:fa9ff456f731 80 #define FLAG_TIMEOUT ((int)0x1000)
<> 153:fa9ff456f731 81
<> 153:fa9ff456f731 82 /* GENERIC INIT and HELPERS FUNCTIONS */
<> 153:fa9ff456f731 83
<> 153:fa9ff456f731 84 #if defined(I2C1_BASE)
<> 153:fa9ff456f731 85 static void i2c1_irq(void)
<> 153:fa9ff456f731 86 {
AnnaBridge 187:0387e8f68319 87 I2C_HandleTypeDef *handle = i2c_handles[0];
<> 153:fa9ff456f731 88 HAL_I2C_EV_IRQHandler(handle);
<> 153:fa9ff456f731 89 HAL_I2C_ER_IRQHandler(handle);
<> 153:fa9ff456f731 90 }
<> 153:fa9ff456f731 91 #endif
<> 153:fa9ff456f731 92 #if defined(I2C2_BASE)
<> 153:fa9ff456f731 93 static void i2c2_irq(void)
<> 153:fa9ff456f731 94 {
AnnaBridge 187:0387e8f68319 95 I2C_HandleTypeDef *handle = i2c_handles[1];
<> 153:fa9ff456f731 96 HAL_I2C_EV_IRQHandler(handle);
<> 153:fa9ff456f731 97 HAL_I2C_ER_IRQHandler(handle);
<> 153:fa9ff456f731 98 }
<> 153:fa9ff456f731 99 #endif
<> 153:fa9ff456f731 100 #if defined(I2C3_BASE)
<> 153:fa9ff456f731 101 static void i2c3_irq(void)
<> 153:fa9ff456f731 102 {
AnnaBridge 187:0387e8f68319 103 I2C_HandleTypeDef *handle = i2c_handles[2];
<> 153:fa9ff456f731 104 HAL_I2C_EV_IRQHandler(handle);
<> 153:fa9ff456f731 105 HAL_I2C_ER_IRQHandler(handle);
<> 153:fa9ff456f731 106 }
<> 153:fa9ff456f731 107 #endif
<> 153:fa9ff456f731 108 #if defined(I2C4_BASE)
<> 153:fa9ff456f731 109 static void i2c4_irq(void)
<> 153:fa9ff456f731 110 {
AnnaBridge 187:0387e8f68319 111 I2C_HandleTypeDef *handle = i2c_handles[3];
<> 153:fa9ff456f731 112 HAL_I2C_EV_IRQHandler(handle);
<> 153:fa9ff456f731 113 HAL_I2C_ER_IRQHandler(handle);
<> 153:fa9ff456f731 114 }
<> 153:fa9ff456f731 115 #endif
<> 153:fa9ff456f731 116 #if defined(FMPI2C1_BASE)
<> 153:fa9ff456f731 117 static void i2c5_irq(void)
<> 153:fa9ff456f731 118 {
AnnaBridge 187:0387e8f68319 119 I2C_HandleTypeDef *handle = i2c_handles[4];
<> 153:fa9ff456f731 120 HAL_I2C_EV_IRQHandler(handle);
<> 153:fa9ff456f731 121 HAL_I2C_ER_IRQHandler(handle);
<> 153:fa9ff456f731 122 }
<> 153:fa9ff456f731 123 #endif
<> 153:fa9ff456f731 124
AnnaBridge 187:0387e8f68319 125 void i2c_ev_err_enable(i2c_t *obj, uint32_t handler)
AnnaBridge 187:0387e8f68319 126 {
<> 153:fa9ff456f731 127 struct i2c_s *obj_s = I2C_S(obj);
<> 153:fa9ff456f731 128 IRQn_Type irq_event_n = obj_s->event_i2cIRQ;
<> 153:fa9ff456f731 129 IRQn_Type irq_error_n = obj_s->error_i2cIRQ;
<> 153:fa9ff456f731 130 /* default prio in master case is set to 2 */
<> 153:fa9ff456f731 131 uint32_t prio = 2;
<> 153:fa9ff456f731 132
<> 153:fa9ff456f731 133 /* Set up ITs using IRQ and handler tables */
<> 153:fa9ff456f731 134 NVIC_SetVector(irq_event_n, handler);
<> 153:fa9ff456f731 135 NVIC_SetVector(irq_error_n, handler);
<> 153:fa9ff456f731 136
<> 153:fa9ff456f731 137 #if DEVICE_I2CSLAVE
<> 153:fa9ff456f731 138 /* Set higher priority to slave device than master.
<> 153:fa9ff456f731 139 * In case a device makes use of both master and slave, the
<> 153:fa9ff456f731 140 * slave needs higher responsiveness.
<> 153:fa9ff456f731 141 */
<> 153:fa9ff456f731 142 if (obj_s->slave) {
<> 153:fa9ff456f731 143 prio = 1;
<> 153:fa9ff456f731 144 }
<> 153:fa9ff456f731 145 #endif
<> 153:fa9ff456f731 146
<> 153:fa9ff456f731 147 NVIC_SetPriority(irq_event_n, prio);
<> 153:fa9ff456f731 148 NVIC_SetPriority(irq_error_n, prio);
<> 153:fa9ff456f731 149 NVIC_EnableIRQ(irq_event_n);
<> 153:fa9ff456f731 150 NVIC_EnableIRQ(irq_error_n);
<> 153:fa9ff456f731 151 }
<> 153:fa9ff456f731 152
AnnaBridge 187:0387e8f68319 153 void i2c_ev_err_disable(i2c_t *obj)
AnnaBridge 187:0387e8f68319 154 {
<> 153:fa9ff456f731 155 struct i2c_s *obj_s = I2C_S(obj);
<> 153:fa9ff456f731 156 IRQn_Type irq_event_n = obj_s->event_i2cIRQ;
<> 153:fa9ff456f731 157 IRQn_Type irq_error_n = obj_s->error_i2cIRQ;
<> 153:fa9ff456f731 158
<> 153:fa9ff456f731 159 HAL_NVIC_DisableIRQ(irq_event_n);
<> 153:fa9ff456f731 160 HAL_NVIC_DisableIRQ(irq_error_n);
<> 153:fa9ff456f731 161 }
<> 153:fa9ff456f731 162
<> 153:fa9ff456f731 163 uint32_t i2c_get_irq_handler(i2c_t *obj)
<> 153:fa9ff456f731 164 {
<> 153:fa9ff456f731 165 struct i2c_s *obj_s = I2C_S(obj);
<> 153:fa9ff456f731 166 I2C_HandleTypeDef *handle = &(obj_s->handle);
<> 153:fa9ff456f731 167 uint32_t handler = 0;
<> 153:fa9ff456f731 168
<> 153:fa9ff456f731 169 switch (obj_s->index) {
<> 153:fa9ff456f731 170 #if defined(I2C1_BASE)
<> 153:fa9ff456f731 171 case 0:
<> 153:fa9ff456f731 172 handler = (uint32_t)&i2c1_irq;
<> 153:fa9ff456f731 173 break;
<> 153:fa9ff456f731 174 #endif
<> 153:fa9ff456f731 175 #if defined(I2C2_BASE)
<> 153:fa9ff456f731 176 case 1:
<> 153:fa9ff456f731 177 handler = (uint32_t)&i2c2_irq;
<> 153:fa9ff456f731 178 break;
<> 153:fa9ff456f731 179 #endif
<> 153:fa9ff456f731 180 #if defined(I2C3_BASE)
<> 153:fa9ff456f731 181 case 2:
<> 153:fa9ff456f731 182 handler = (uint32_t)&i2c3_irq;
<> 153:fa9ff456f731 183 break;
<> 153:fa9ff456f731 184 #endif
<> 153:fa9ff456f731 185 #if defined(I2C4_BASE)
<> 153:fa9ff456f731 186 case 3:
<> 153:fa9ff456f731 187 handler = (uint32_t)&i2c4_irq;
<> 153:fa9ff456f731 188 break;
<> 153:fa9ff456f731 189 #endif
<> 153:fa9ff456f731 190 #if defined(FMPI2C1_BASE)
<> 153:fa9ff456f731 191 case 4:
<> 153:fa9ff456f731 192 handler = (uint32_t)&i2c5_irq;
<> 153:fa9ff456f731 193 break;
<> 153:fa9ff456f731 194 #endif
<> 153:fa9ff456f731 195 }
<> 153:fa9ff456f731 196
<> 153:fa9ff456f731 197 i2c_handles[obj_s->index] = handle;
<> 153:fa9ff456f731 198 return handler;
<> 153:fa9ff456f731 199 }
<> 153:fa9ff456f731 200
AnnaBridge 187:0387e8f68319 201 void i2c_hw_reset(i2c_t *obj)
AnnaBridge 187:0387e8f68319 202 {
<> 153:fa9ff456f731 203 int timeout;
<> 153:fa9ff456f731 204 struct i2c_s *obj_s = I2C_S(obj);
<> 153:fa9ff456f731 205 I2C_HandleTypeDef *handle = &(obj_s->handle);
<> 153:fa9ff456f731 206
<> 153:fa9ff456f731 207 handle->Instance = (I2C_TypeDef *)(obj_s->i2c);
<> 153:fa9ff456f731 208
<> 153:fa9ff456f731 209 // wait before reset
<> 153:fa9ff456f731 210 timeout = BYTE_TIMEOUT;
<> 153:fa9ff456f731 211 while ((__HAL_I2C_GET_FLAG(handle, I2C_FLAG_BUSY)) && (--timeout != 0));
<> 153:fa9ff456f731 212 #if defined I2C1_BASE
<> 153:fa9ff456f731 213 if (obj_s->i2c == I2C_1) {
<> 153:fa9ff456f731 214 __HAL_RCC_I2C1_FORCE_RESET();
<> 153:fa9ff456f731 215 __HAL_RCC_I2C1_RELEASE_RESET();
<> 153:fa9ff456f731 216 }
<> 153:fa9ff456f731 217 #endif
<> 153:fa9ff456f731 218 #if defined I2C2_BASE
<> 153:fa9ff456f731 219 if (obj_s->i2c == I2C_2) {
<> 153:fa9ff456f731 220 __HAL_RCC_I2C2_FORCE_RESET();
<> 153:fa9ff456f731 221 __HAL_RCC_I2C2_RELEASE_RESET();
<> 153:fa9ff456f731 222 }
<> 153:fa9ff456f731 223 #endif
<> 153:fa9ff456f731 224 #if defined I2C3_BASE
<> 153:fa9ff456f731 225 if (obj_s->i2c == I2C_3) {
<> 153:fa9ff456f731 226 __HAL_RCC_I2C3_FORCE_RESET();
<> 153:fa9ff456f731 227 __HAL_RCC_I2C3_RELEASE_RESET();
<> 153:fa9ff456f731 228 }
<> 153:fa9ff456f731 229 #endif
<> 153:fa9ff456f731 230 #if defined I2C4_BASE
<> 153:fa9ff456f731 231 if (obj_s->i2c == I2C_4) {
<> 153:fa9ff456f731 232 __HAL_RCC_I2C4_FORCE_RESET();
<> 153:fa9ff456f731 233 __HAL_RCC_I2C4_RELEASE_RESET();
<> 153:fa9ff456f731 234 }
<> 153:fa9ff456f731 235 #endif
<> 153:fa9ff456f731 236 #if defined FMPI2C1_BASE
<> 153:fa9ff456f731 237 if (obj_s->i2c == FMPI2C_1) {
<> 153:fa9ff456f731 238 __HAL_RCC_FMPI2C1_FORCE_RESET();
<> 153:fa9ff456f731 239 __HAL_RCC_FMPI2C1_RELEASE_RESET();
<> 153:fa9ff456f731 240 }
<> 153:fa9ff456f731 241 #endif
<> 153:fa9ff456f731 242 }
<> 153:fa9ff456f731 243
Kojto 158:b23ee177fd68 244 void i2c_sw_reset(i2c_t *obj)
Kojto 158:b23ee177fd68 245 {
Kojto 158:b23ee177fd68 246 struct i2c_s *obj_s = I2C_S(obj);
Kojto 158:b23ee177fd68 247 I2C_HandleTypeDef *handle = &(obj_s->handle);
Kojto 158:b23ee177fd68 248 /* SW reset procedure:
Kojto 158:b23ee177fd68 249 * PE must be kept low during at least 3 APB clock cycles
Kojto 158:b23ee177fd68 250 * in order to perform the software reset.
Kojto 158:b23ee177fd68 251 * This is ensured by writing the following software sequence:
Kojto 158:b23ee177fd68 252 * - Write PE=0
Kojto 158:b23ee177fd68 253 * - Check PE=0
Kojto 158:b23ee177fd68 254 * - Write PE=1.
Kojto 158:b23ee177fd68 255 */
Kojto 158:b23ee177fd68 256 handle->Instance->CR1 &= ~I2C_CR1_PE;
AnnaBridge 187:0387e8f68319 257 while (handle->Instance->CR1 & I2C_CR1_PE);
Kojto 158:b23ee177fd68 258 handle->Instance->CR1 |= I2C_CR1_PE;
Kojto 158:b23ee177fd68 259 }
Kojto 158:b23ee177fd68 260
AnnaBridge 187:0387e8f68319 261 void i2c_init(i2c_t *obj, PinName sda, PinName scl)
AnnaBridge 187:0387e8f68319 262 {
<> 153:fa9ff456f731 263
<> 153:fa9ff456f731 264 struct i2c_s *obj_s = I2C_S(obj);
<> 153:fa9ff456f731 265
<> 153:fa9ff456f731 266 // Determine the I2C to use
<> 153:fa9ff456f731 267 I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA);
<> 153:fa9ff456f731 268 I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL);
<> 153:fa9ff456f731 269 obj_s->sda = sda;
<> 153:fa9ff456f731 270 obj_s->scl = scl;
<> 153:fa9ff456f731 271
<> 153:fa9ff456f731 272 obj_s->i2c = (I2CName)pinmap_merge(i2c_sda, i2c_scl);
<> 153:fa9ff456f731 273 MBED_ASSERT(obj_s->i2c != (I2CName)NC);
<> 153:fa9ff456f731 274
<> 153:fa9ff456f731 275 #if defined I2C1_BASE
<> 153:fa9ff456f731 276 // Enable I2C1 clock and pinout if not done
<> 153:fa9ff456f731 277 if (obj_s->i2c == I2C_1) {
<> 153:fa9ff456f731 278 obj_s->index = 0;
<> 153:fa9ff456f731 279 __HAL_RCC_I2C1_CLK_ENABLE();
<> 153:fa9ff456f731 280 // Configure I2C pins
<> 153:fa9ff456f731 281 obj_s->event_i2cIRQ = I2C1_EV_IRQn;
<> 153:fa9ff456f731 282 obj_s->error_i2cIRQ = I2C1_ER_IRQn;
<> 153:fa9ff456f731 283 }
<> 153:fa9ff456f731 284 #endif
<> 153:fa9ff456f731 285 #if defined I2C2_BASE
<> 153:fa9ff456f731 286 // Enable I2C2 clock and pinout if not done
<> 153:fa9ff456f731 287 if (obj_s->i2c == I2C_2) {
<> 153:fa9ff456f731 288 obj_s->index = 1;
<> 153:fa9ff456f731 289 __HAL_RCC_I2C2_CLK_ENABLE();
<> 153:fa9ff456f731 290 obj_s->event_i2cIRQ = I2C2_EV_IRQn;
<> 153:fa9ff456f731 291 obj_s->error_i2cIRQ = I2C2_ER_IRQn;
<> 153:fa9ff456f731 292 }
<> 153:fa9ff456f731 293 #endif
<> 153:fa9ff456f731 294 #if defined I2C3_BASE
<> 153:fa9ff456f731 295 // Enable I2C3 clock and pinout if not done
<> 153:fa9ff456f731 296 if (obj_s->i2c == I2C_3) {
<> 153:fa9ff456f731 297 obj_s->index = 2;
<> 153:fa9ff456f731 298 __HAL_RCC_I2C3_CLK_ENABLE();
<> 153:fa9ff456f731 299 obj_s->event_i2cIRQ = I2C3_EV_IRQn;
<> 153:fa9ff456f731 300 obj_s->error_i2cIRQ = I2C3_ER_IRQn;
<> 153:fa9ff456f731 301 }
<> 153:fa9ff456f731 302 #endif
<> 153:fa9ff456f731 303 #if defined I2C4_BASE
<> 153:fa9ff456f731 304 // Enable I2C3 clock and pinout if not done
<> 153:fa9ff456f731 305 if (obj_s->i2c == I2C_4) {
<> 153:fa9ff456f731 306 obj_s->index = 3;
<> 153:fa9ff456f731 307 __HAL_RCC_I2C4_CLK_ENABLE();
<> 153:fa9ff456f731 308 obj_s->event_i2cIRQ = I2C4_EV_IRQn;
<> 153:fa9ff456f731 309 obj_s->error_i2cIRQ = I2C4_ER_IRQn;
<> 153:fa9ff456f731 310 }
<> 153:fa9ff456f731 311 #endif
<> 153:fa9ff456f731 312 #if defined FMPI2C1_BASE
<> 153:fa9ff456f731 313 // Enable I2C3 clock and pinout if not done
<> 153:fa9ff456f731 314 if (obj_s->i2c == FMPI2C_1) {
<> 153:fa9ff456f731 315 obj_s->index = 4;
<> 153:fa9ff456f731 316 __HAL_RCC_FMPI2C1_CLK_ENABLE();
<> 153:fa9ff456f731 317 obj_s->event_i2cIRQ = FMPI2C1_EV_IRQn;
<> 153:fa9ff456f731 318 obj_s->error_i2cIRQ = FMPI2C1_ER_IRQn;
<> 153:fa9ff456f731 319 }
<> 153:fa9ff456f731 320 #endif
<> 153:fa9ff456f731 321
Anna Bridge 180:96ed750bd169 322 // Configure I2C pins
Anna Bridge 180:96ed750bd169 323 pinmap_pinout(sda, PinMap_I2C_SDA);
Anna Bridge 180:96ed750bd169 324 pinmap_pinout(scl, PinMap_I2C_SCL);
Anna Bridge 180:96ed750bd169 325 pin_mode(sda, OpenDrainNoPull);
Anna Bridge 180:96ed750bd169 326 pin_mode(scl, OpenDrainNoPull);
Anna Bridge 180:96ed750bd169 327
<> 153:fa9ff456f731 328 // I2C configuration
<> 153:fa9ff456f731 329 // Default hz value used for timeout computation
AnnaBridge 187:0387e8f68319 330 if (!obj_s->hz) {
AnnaBridge 187:0387e8f68319 331 obj_s->hz = 100000; // 100 kHz per default
AnnaBridge 187:0387e8f68319 332 }
<> 153:fa9ff456f731 333
<> 153:fa9ff456f731 334 // Reset to clear pending flags if any
<> 153:fa9ff456f731 335 i2c_hw_reset(obj);
AnnaBridge 187:0387e8f68319 336 i2c_frequency(obj, obj_s->hz);
<> 153:fa9ff456f731 337
<> 153:fa9ff456f731 338 #if DEVICE_I2CSLAVE
<> 153:fa9ff456f731 339 // I2C master by default
<> 153:fa9ff456f731 340 obj_s->slave = 0;
<> 153:fa9ff456f731 341 obj_s->pending_slave_tx_master_rx = 0;
<> 153:fa9ff456f731 342 obj_s->pending_slave_rx_maxter_tx = 0;
<> 153:fa9ff456f731 343 #endif
<> 153:fa9ff456f731 344
<> 153:fa9ff456f731 345 // I2C Xfer operation init
<> 153:fa9ff456f731 346 obj_s->event = 0;
<> 153:fa9ff456f731 347 obj_s->XferOperation = I2C_FIRST_AND_LAST_FRAME;
<> 156:95d6b41a828b 348 #ifdef I2C_IP_VERSION_V2
<> 156:95d6b41a828b 349 obj_s->pending_start = 0;
<> 156:95d6b41a828b 350 #endif
<> 153:fa9ff456f731 351 }
<> 153:fa9ff456f731 352
<> 153:fa9ff456f731 353 void i2c_frequency(i2c_t *obj, int hz)
<> 153:fa9ff456f731 354 {
<> 153:fa9ff456f731 355 int timeout;
<> 153:fa9ff456f731 356 struct i2c_s *obj_s = I2C_S(obj);
<> 153:fa9ff456f731 357 I2C_HandleTypeDef *handle = &(obj_s->handle);
<> 153:fa9ff456f731 358
<> 153:fa9ff456f731 359 // wait before init
<> 153:fa9ff456f731 360 timeout = BYTE_TIMEOUT;
<> 153:fa9ff456f731 361 while ((__HAL_I2C_GET_FLAG(handle, I2C_FLAG_BUSY)) && (--timeout != 0));
<> 153:fa9ff456f731 362
<> 153:fa9ff456f731 363 #ifdef I2C_IP_VERSION_V1
<> 153:fa9ff456f731 364 handle->Init.ClockSpeed = hz;
<> 153:fa9ff456f731 365 handle->Init.DutyCycle = I2C_DUTYCYCLE_2;
<> 153:fa9ff456f731 366 #endif
<> 153:fa9ff456f731 367 #ifdef I2C_IP_VERSION_V2
<> 153:fa9ff456f731 368 /* Only predefined timing for below frequencies are supported */
<> 153:fa9ff456f731 369 MBED_ASSERT((hz == 100000) || (hz == 400000) || (hz == 1000000));
<> 153:fa9ff456f731 370 handle->Init.Timing = get_i2c_timing(hz);
<> 153:fa9ff456f731 371
<> 153:fa9ff456f731 372 // Enable the Fast Mode Plus capability
<> 153:fa9ff456f731 373 if (hz == 1000000) {
<> 153:fa9ff456f731 374 #if defined(I2C1_BASE) && defined(__HAL_SYSCFG_FASTMODEPLUS_ENABLE) && defined (I2C_FASTMODEPLUS_I2C1)
<> 153:fa9ff456f731 375 if (obj_s->i2c == I2C_1) {
<> 156:95d6b41a828b 376 HAL_I2CEx_EnableFastModePlus(I2C_FASTMODEPLUS_I2C1);
<> 153:fa9ff456f731 377 }
<> 153:fa9ff456f731 378 #endif
<> 153:fa9ff456f731 379 #if defined(I2C2_BASE) && defined(__HAL_SYSCFG_FASTMODEPLUS_ENABLE) && defined (I2C_FASTMODEPLUS_I2C2)
<> 153:fa9ff456f731 380 if (obj_s->i2c == I2C_2) {
<> 156:95d6b41a828b 381 HAL_I2CEx_EnableFastModePlus(I2C_FASTMODEPLUS_I2C2);
<> 153:fa9ff456f731 382 }
<> 153:fa9ff456f731 383 #endif
<> 153:fa9ff456f731 384 #if defined(I2C3_BASE) && defined(__HAL_SYSCFG_FASTMODEPLUS_ENABLE) && defined (I2C_FASTMODEPLUS_I2C3)
<> 153:fa9ff456f731 385 if (obj_s->i2c == I2C_3) {
<> 156:95d6b41a828b 386 HAL_I2CEx_EnableFastModePlus(I2C_FASTMODEPLUS_I2C3);
<> 153:fa9ff456f731 387 }
<> 153:fa9ff456f731 388 #endif
<> 153:fa9ff456f731 389 #if defined(I2C4_BASE) && defined(__HAL_SYSCFG_FASTMODEPLUS_ENABLE) && defined (I2C_FASTMODEPLUS_I2C4)
<> 153:fa9ff456f731 390 if (obj_s->i2c == I2C_4) {
<> 156:95d6b41a828b 391 HAL_I2CEx_EnableFastModePlus(I2C_FASTMODEPLUS_I2C4);
<> 153:fa9ff456f731 392 }
<> 153:fa9ff456f731 393 #endif
<> 153:fa9ff456f731 394 }
<> 153:fa9ff456f731 395 #endif //I2C_IP_VERSION_V2
<> 153:fa9ff456f731 396
<> 153:fa9ff456f731 397 /*##-1- Configure the I2C clock source. The clock is derived from the SYSCLK #*/
<> 153:fa9ff456f731 398 #if defined(I2C1_BASE) && defined (__HAL_RCC_I2C1_CONFIG)
<> 153:fa9ff456f731 399 if (obj_s->i2c == I2C_1) {
<> 153:fa9ff456f731 400 __HAL_RCC_I2C1_CONFIG(I2CAPI_I2C1_CLKSRC);
<> 153:fa9ff456f731 401 }
<> 153:fa9ff456f731 402 #endif
<> 153:fa9ff456f731 403 #if defined(I2C2_BASE) && defined(__HAL_RCC_I2C2_CONFIG)
<> 153:fa9ff456f731 404 if (obj_s->i2c == I2C_2) {
<> 153:fa9ff456f731 405 __HAL_RCC_I2C2_CONFIG(I2CAPI_I2C2_CLKSRC);
<> 153:fa9ff456f731 406 }
<> 153:fa9ff456f731 407 #endif
<> 153:fa9ff456f731 408 #if defined(I2C3_BASE) && defined(__HAL_RCC_I2C3_CONFIG)
<> 153:fa9ff456f731 409 if (obj_s->i2c == I2C_3) {
<> 153:fa9ff456f731 410 __HAL_RCC_I2C3_CONFIG(I2CAPI_I2C3_CLKSRC);
<> 153:fa9ff456f731 411 }
<> 153:fa9ff456f731 412 #endif
<> 153:fa9ff456f731 413 #if defined(I2C4_BASE) && defined(__HAL_RCC_I2C4_CONFIG)
<> 153:fa9ff456f731 414 if (obj_s->i2c == I2C_4) {
<> 153:fa9ff456f731 415 __HAL_RCC_I2C4_CONFIG(I2CAPI_I2C4_CLKSRC);
<> 153:fa9ff456f731 416 }
<> 153:fa9ff456f731 417 #endif
<> 153:fa9ff456f731 418
<> 153:fa9ff456f731 419 #ifdef I2C_ANALOGFILTER_ENABLE
<> 153:fa9ff456f731 420 /* Enable the Analog I2C Filter */
AnnaBridge 187:0387e8f68319 421 HAL_I2CEx_ConfigAnalogFilter(handle, I2C_ANALOGFILTER_ENABLE);
<> 153:fa9ff456f731 422 #endif
<> 153:fa9ff456f731 423
<> 153:fa9ff456f731 424 // I2C configuration
<> 153:fa9ff456f731 425 handle->Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
AnnaBridge 165:e614a9f1c9e2 426 handle->Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
AnnaBridge 165:e614a9f1c9e2 427 handle->Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
AnnaBridge 165:e614a9f1c9e2 428 handle->Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
<> 153:fa9ff456f731 429 handle->Init.OwnAddress1 = 0;
<> 153:fa9ff456f731 430 handle->Init.OwnAddress2 = 0;
<> 153:fa9ff456f731 431 HAL_I2C_Init(handle);
<> 153:fa9ff456f731 432
<> 153:fa9ff456f731 433 /* store frequency for timeout computation */
<> 153:fa9ff456f731 434 obj_s->hz = hz;
<> 153:fa9ff456f731 435 }
<> 153:fa9ff456f731 436
AnnaBridge 187:0387e8f68319 437 i2c_t *get_i2c_obj(I2C_HandleTypeDef *hi2c)
AnnaBridge 187:0387e8f68319 438 {
<> 153:fa9ff456f731 439 /* Aim of the function is to get i2c_s pointer using hi2c pointer */
<> 153:fa9ff456f731 440 /* Highly inspired from magical linux kernel's "container_of" */
<> 153:fa9ff456f731 441 /* (which was not directly used since not compatible with IAR toolchain) */
<> 153:fa9ff456f731 442 struct i2c_s *obj_s;
<> 153:fa9ff456f731 443 i2c_t *obj;
<> 153:fa9ff456f731 444
AnnaBridge 187:0387e8f68319 445 obj_s = (struct i2c_s *)((char *)hi2c - offsetof(struct i2c_s, handle));
AnnaBridge 187:0387e8f68319 446 obj = (i2c_t *)((char *)obj_s - offsetof(i2c_t, i2c));
<> 153:fa9ff456f731 447
<> 153:fa9ff456f731 448 return (obj);
<> 153:fa9ff456f731 449 }
<> 153:fa9ff456f731 450
AnnaBridge 187:0387e8f68319 451 void i2c_reset(i2c_t *obj)
AnnaBridge 187:0387e8f68319 452 {
<> 156:95d6b41a828b 453 struct i2c_s *obj_s = I2C_S(obj);
<> 156:95d6b41a828b 454 /* As recommended in i2c_api.h, mainly send stop */
<> 156:95d6b41a828b 455 i2c_stop(obj);
<> 156:95d6b41a828b 456 /* then re-init */
<> 156:95d6b41a828b 457 i2c_init(obj, obj_s->sda, obj_s->scl);
<> 156:95d6b41a828b 458 }
<> 156:95d6b41a828b 459
<> 153:fa9ff456f731 460 /*
<> 153:fa9ff456f731 461 * UNITARY APIS.
<> 153:fa9ff456f731 462 * For very basic operations, direct registers access is needed
<> 153:fa9ff456f731 463 * There are 2 different IPs version that need to be supported
<> 153:fa9ff456f731 464 */
<> 153:fa9ff456f731 465 #ifdef I2C_IP_VERSION_V1
AnnaBridge 187:0387e8f68319 466 int i2c_start(i2c_t *obj)
AnnaBridge 187:0387e8f68319 467 {
<> 153:fa9ff456f731 468
<> 153:fa9ff456f731 469 int timeout;
<> 153:fa9ff456f731 470 struct i2c_s *obj_s = I2C_S(obj);
<> 153:fa9ff456f731 471 I2C_HandleTypeDef *handle = &(obj_s->handle);
<> 153:fa9ff456f731 472
<> 153:fa9ff456f731 473 // Clear Acknowledge failure flag
<> 153:fa9ff456f731 474 __HAL_I2C_CLEAR_FLAG(handle, I2C_FLAG_AF);
<> 153:fa9ff456f731 475
<> 153:fa9ff456f731 476 // Wait the STOP condition has been previously correctly sent
<> 153:fa9ff456f731 477 // This timeout can be avoid in some specific cases by simply clearing the STOP bit
<> 153:fa9ff456f731 478 timeout = FLAG_TIMEOUT;
<> 153:fa9ff456f731 479 while ((handle->Instance->CR1 & I2C_CR1_STOP) == I2C_CR1_STOP) {
<> 153:fa9ff456f731 480 if ((timeout--) == 0) {
<> 153:fa9ff456f731 481 return 1;
<> 153:fa9ff456f731 482 }
<> 153:fa9ff456f731 483 }
<> 153:fa9ff456f731 484
<> 153:fa9ff456f731 485 // Generate the START condition
<> 153:fa9ff456f731 486 handle->Instance->CR1 |= I2C_CR1_START;
<> 153:fa9ff456f731 487
<> 153:fa9ff456f731 488 // Wait the START condition has been correctly sent
<> 153:fa9ff456f731 489 timeout = FLAG_TIMEOUT;
<> 153:fa9ff456f731 490 while (__HAL_I2C_GET_FLAG(handle, I2C_FLAG_SB) == RESET) {
<> 153:fa9ff456f731 491 if ((timeout--) == 0) {
<> 153:fa9ff456f731 492 return 1;
<> 153:fa9ff456f731 493 }
<> 153:fa9ff456f731 494 }
<> 153:fa9ff456f731 495
<> 153:fa9ff456f731 496 return 0;
<> 153:fa9ff456f731 497 }
<> 153:fa9ff456f731 498
AnnaBridge 187:0387e8f68319 499 int i2c_stop(i2c_t *obj)
AnnaBridge 187:0387e8f68319 500 {
<> 153:fa9ff456f731 501 struct i2c_s *obj_s = I2C_S(obj);
<> 153:fa9ff456f731 502 I2C_TypeDef *i2c = (I2C_TypeDef *)obj_s->i2c;
<> 153:fa9ff456f731 503
<> 153:fa9ff456f731 504 // Generate the STOP condition
<> 153:fa9ff456f731 505 i2c->CR1 |= I2C_CR1_STOP;
<> 153:fa9ff456f731 506
<> 154:37f96f9d4de2 507 /* In case of mixed usage of the APIs (unitary + SYNC)
Kojto 158:b23ee177fd68 508 * re-init HAL state
<> 154:37f96f9d4de2 509 */
AnnaBridge 187:0387e8f68319 510 if (obj_s->XferOperation != I2C_FIRST_AND_LAST_FRAME) {
AnnaBridge 187:0387e8f68319 511 i2c_init(obj, obj_s->sda, obj_s->scl);
AnnaBridge 187:0387e8f68319 512 }
<> 154:37f96f9d4de2 513
<> 153:fa9ff456f731 514 return 0;
<> 153:fa9ff456f731 515 }
<> 153:fa9ff456f731 516
AnnaBridge 187:0387e8f68319 517 int i2c_byte_read(i2c_t *obj, int last)
AnnaBridge 187:0387e8f68319 518 {
<> 153:fa9ff456f731 519
<> 153:fa9ff456f731 520 int timeout;
<> 153:fa9ff456f731 521 struct i2c_s *obj_s = I2C_S(obj);
<> 153:fa9ff456f731 522 I2C_HandleTypeDef *handle = &(obj_s->handle);
<> 153:fa9ff456f731 523
<> 153:fa9ff456f731 524 if (last) {
<> 153:fa9ff456f731 525 // Don't acknowledge the last byte
<> 153:fa9ff456f731 526 handle->Instance->CR1 &= ~I2C_CR1_ACK;
<> 153:fa9ff456f731 527 } else {
<> 153:fa9ff456f731 528 // Acknowledge the byte
<> 153:fa9ff456f731 529 handle->Instance->CR1 |= I2C_CR1_ACK;
<> 153:fa9ff456f731 530 }
<> 153:fa9ff456f731 531
<> 153:fa9ff456f731 532 // Wait until the byte is received
<> 153:fa9ff456f731 533 timeout = FLAG_TIMEOUT;
<> 153:fa9ff456f731 534 while (__HAL_I2C_GET_FLAG(handle, I2C_FLAG_RXNE) == RESET) {
<> 153:fa9ff456f731 535 if ((timeout--) == 0) {
<> 153:fa9ff456f731 536 return -1;
<> 153:fa9ff456f731 537 }
<> 153:fa9ff456f731 538 }
<> 153:fa9ff456f731 539
<> 153:fa9ff456f731 540 return (int)handle->Instance->DR;
<> 153:fa9ff456f731 541 }
<> 153:fa9ff456f731 542
AnnaBridge 187:0387e8f68319 543 int i2c_byte_write(i2c_t *obj, int data)
AnnaBridge 187:0387e8f68319 544 {
<> 153:fa9ff456f731 545
<> 153:fa9ff456f731 546 int timeout;
<> 153:fa9ff456f731 547 struct i2c_s *obj_s = I2C_S(obj);
<> 153:fa9ff456f731 548 I2C_HandleTypeDef *handle = &(obj_s->handle);
<> 153:fa9ff456f731 549
<> 153:fa9ff456f731 550 handle->Instance->DR = (uint8_t)data;
<> 153:fa9ff456f731 551
<> 153:fa9ff456f731 552 // Wait until the byte (might be the address) is transmitted
<> 153:fa9ff456f731 553 timeout = FLAG_TIMEOUT;
<> 153:fa9ff456f731 554 while ((__HAL_I2C_GET_FLAG(handle, I2C_FLAG_TXE) == RESET) &&
<> 153:fa9ff456f731 555 (__HAL_I2C_GET_FLAG(handle, I2C_FLAG_BTF) == RESET) &&
AnnaBridge 187:0387e8f68319 556 (__HAL_I2C_GET_FLAG(handle, I2C_FLAG_ADDR) == RESET)) {
<> 153:fa9ff456f731 557 if ((timeout--) == 0) {
<> 156:95d6b41a828b 558 return 2;
<> 153:fa9ff456f731 559 }
<> 153:fa9ff456f731 560 }
<> 153:fa9ff456f731 561
AnnaBridge 187:0387e8f68319 562 if (__HAL_I2C_GET_FLAG(handle, I2C_FLAG_ADDR) != RESET) {
AnnaBridge 187:0387e8f68319 563 __HAL_I2C_CLEAR_ADDRFLAG(handle);
AnnaBridge 187:0387e8f68319 564 }
<> 153:fa9ff456f731 565
<> 153:fa9ff456f731 566 return 1;
<> 153:fa9ff456f731 567 }
<> 153:fa9ff456f731 568 #endif //I2C_IP_VERSION_V1
<> 153:fa9ff456f731 569 #ifdef I2C_IP_VERSION_V2
<> 156:95d6b41a828b 570
AnnaBridge 187:0387e8f68319 571 int i2c_start(i2c_t *obj)
AnnaBridge 187:0387e8f68319 572 {
<> 153:fa9ff456f731 573 struct i2c_s *obj_s = I2C_S(obj);
<> 156:95d6b41a828b 574 /* This I2C IP doesn't */
<> 156:95d6b41a828b 575 obj_s->pending_start = 1;
<> 153:fa9ff456f731 576 return 0;
<> 153:fa9ff456f731 577 }
<> 153:fa9ff456f731 578
AnnaBridge 187:0387e8f68319 579 int i2c_stop(i2c_t *obj)
AnnaBridge 187:0387e8f68319 580 {
<> 153:fa9ff456f731 581 struct i2c_s *obj_s = I2C_S(obj);
<> 156:95d6b41a828b 582 I2C_HandleTypeDef *handle = &(obj_s->handle);
<> 156:95d6b41a828b 583 int timeout = FLAG_TIMEOUT;
<> 156:95d6b41a828b 584 #if DEVICE_I2CSLAVE
<> 156:95d6b41a828b 585 if (obj_s->slave) {
<> 156:95d6b41a828b 586 /* re-init slave when stop is requested */
<> 156:95d6b41a828b 587 i2c_init(obj, obj_s->sda, obj_s->scl);
<> 156:95d6b41a828b 588 return 0;
<> 156:95d6b41a828b 589 }
<> 156:95d6b41a828b 590 #endif
<> 156:95d6b41a828b 591 // Disable reload mode
<> 156:95d6b41a828b 592 handle->Instance->CR2 &= (uint32_t)~I2C_CR2_RELOAD;
AnnaBridge 189:f392fc9709a3 593
AnnaBridge 188:bcfe06ba3d64 594 // Ensure the transmission is started before sending a stop
AnnaBridge 188:bcfe06ba3d64 595 if ((handle->Instance->CR2 & (uint32_t)I2C_CR2_RD_WRN) == 0) {
AnnaBridge 189:f392fc9709a3 596 timeout = FLAG_TIMEOUT;
AnnaBridge 189:f392fc9709a3 597 while (!__HAL_I2C_GET_FLAG(handle, I2C_FLAG_TXIS)) {
AnnaBridge 189:f392fc9709a3 598 if ((timeout--) == 0) {
AnnaBridge 189:f392fc9709a3 599 return I2C_ERROR_BUS_BUSY;
AnnaBridge 189:f392fc9709a3 600 }
AnnaBridge 189:f392fc9709a3 601 }
AnnaBridge 188:bcfe06ba3d64 602 }
AnnaBridge 189:f392fc9709a3 603
<> 156:95d6b41a828b 604 // Generate the STOP condition
<> 156:95d6b41a828b 605 handle->Instance->CR2 |= I2C_CR2_STOP;
<> 153:fa9ff456f731 606
<> 156:95d6b41a828b 607 timeout = FLAG_TIMEOUT;
<> 156:95d6b41a828b 608 while (!__HAL_I2C_GET_FLAG(handle, I2C_FLAG_STOPF)) {
<> 156:95d6b41a828b 609 if ((timeout--) == 0) {
<> 156:95d6b41a828b 610 return I2C_ERROR_BUS_BUSY;
<> 156:95d6b41a828b 611 }
<> 156:95d6b41a828b 612 }
<> 156:95d6b41a828b 613
<> 156:95d6b41a828b 614 /* Clear STOP Flag */
<> 156:95d6b41a828b 615 __HAL_I2C_CLEAR_FLAG(handle, I2C_FLAG_STOPF);
<> 156:95d6b41a828b 616
<> 156:95d6b41a828b 617 /* Erase slave address, this wiil be used as a marker
<> 156:95d6b41a828b 618 * to know when we need to prepare next start */
<> 156:95d6b41a828b 619 handle->Instance->CR2 &= ~I2C_CR2_SADD;
<> 156:95d6b41a828b 620
Kojto 158:b23ee177fd68 621 /*
Kojto 158:b23ee177fd68 622 * V2 IP is meant for automatic STOP, not user STOP
Kojto 158:b23ee177fd68 623 * SW reset the IP state machine before next transaction
Kojto 158:b23ee177fd68 624 */
Kojto 158:b23ee177fd68 625 i2c_sw_reset(obj);
Kojto 158:b23ee177fd68 626
<> 156:95d6b41a828b 627 /* In case of mixed usage of the APIs (unitary + SYNC)
Kojto 158:b23ee177fd68 628 * re-init HAL state */
<> 156:95d6b41a828b 629 if (obj_s->XferOperation != I2C_FIRST_AND_LAST_FRAME) {
<> 156:95d6b41a828b 630 i2c_init(obj, obj_s->sda, obj_s->scl);
<> 156:95d6b41a828b 631 }
<> 153:fa9ff456f731 632
<> 153:fa9ff456f731 633 return 0;
<> 153:fa9ff456f731 634 }
<> 153:fa9ff456f731 635
AnnaBridge 187:0387e8f68319 636 int i2c_byte_read(i2c_t *obj, int last)
AnnaBridge 187:0387e8f68319 637 {
<> 153:fa9ff456f731 638 struct i2c_s *obj_s = I2C_S(obj);
<> 153:fa9ff456f731 639 I2C_HandleTypeDef *handle = &(obj_s->handle);
<> 156:95d6b41a828b 640 int timeout = FLAG_TIMEOUT;
<> 156:95d6b41a828b 641 uint32_t tmpreg = handle->Instance->CR2;
<> 156:95d6b41a828b 642 char data;
<> 156:95d6b41a828b 643 #if DEVICE_I2CSLAVE
<> 156:95d6b41a828b 644 if (obj_s->slave) {
<> 156:95d6b41a828b 645 return i2c_slave_read(obj, &data, 1);
<> 156:95d6b41a828b 646 }
<> 156:95d6b41a828b 647 #endif
<> 156:95d6b41a828b 648 /* Then send data when there's room in the TX fifo */
<> 156:95d6b41a828b 649 if ((tmpreg & I2C_CR2_RELOAD) != 0) {
<> 156:95d6b41a828b 650 while (!__HAL_I2C_GET_FLAG(handle, I2C_FLAG_TCR)) {
<> 156:95d6b41a828b 651 if ((timeout--) == 0) {
<> 156:95d6b41a828b 652 DEBUG_PRINTF("timeout in byte_read\r\n");
<> 156:95d6b41a828b 653 return -1;
<> 156:95d6b41a828b 654 }
<> 156:95d6b41a828b 655 }
<> 156:95d6b41a828b 656 }
<> 153:fa9ff456f731 657
<> 157:ff67d9f36b67 658 /* Enable reload mode as we don't know how many bytes will be sent */
<> 157:ff67d9f36b67 659 /* and set transfer size to 1 */
<> 157:ff67d9f36b67 660 tmpreg |= I2C_CR2_RELOAD | (I2C_CR2_NBYTES & (1 << 16));
<> 156:95d6b41a828b 661 /* Set the prepared configuration */
<> 156:95d6b41a828b 662 handle->Instance->CR2 = tmpreg;
<> 156:95d6b41a828b 663
<> 153:fa9ff456f731 664 timeout = FLAG_TIMEOUT;
<> 156:95d6b41a828b 665 while (!__HAL_I2C_GET_FLAG(handle, I2C_FLAG_RXNE)) {
<> 153:fa9ff456f731 666 if ((timeout--) == 0) {
<> 153:fa9ff456f731 667 return -1;
<> 153:fa9ff456f731 668 }
<> 153:fa9ff456f731 669 }
<> 153:fa9ff456f731 670
<> 156:95d6b41a828b 671 /* Then Get Byte */
<> 156:95d6b41a828b 672 data = handle->Instance->RXDR;
<> 156:95d6b41a828b 673
<> 156:95d6b41a828b 674 if (last) {
<> 156:95d6b41a828b 675 /* Disable Address Acknowledge */
<> 156:95d6b41a828b 676 handle->Instance->CR2 |= I2C_CR2_NACK;
<> 156:95d6b41a828b 677 }
<> 156:95d6b41a828b 678
<> 156:95d6b41a828b 679 return data;
<> 153:fa9ff456f731 680 }
<> 153:fa9ff456f731 681
AnnaBridge 187:0387e8f68319 682 int i2c_byte_write(i2c_t *obj, int data)
AnnaBridge 187:0387e8f68319 683 {
<> 153:fa9ff456f731 684 struct i2c_s *obj_s = I2C_S(obj);
<> 153:fa9ff456f731 685 I2C_HandleTypeDef *handle = &(obj_s->handle);
<> 156:95d6b41a828b 686 int timeout = FLAG_TIMEOUT;
<> 156:95d6b41a828b 687 uint32_t tmpreg = handle->Instance->CR2;
<> 156:95d6b41a828b 688 #if DEVICE_I2CSLAVE
<> 156:95d6b41a828b 689 if (obj_s->slave) {
<> 156:95d6b41a828b 690 return i2c_slave_write(obj, (char *) &data, 1);
<> 156:95d6b41a828b 691 }
<> 156:95d6b41a828b 692 #endif
<> 156:95d6b41a828b 693 if (obj_s->pending_start) {
<> 156:95d6b41a828b 694 obj_s->pending_start = 0;
<> 156:95d6b41a828b 695 //* First byte after the start is the address */
<> 156:95d6b41a828b 696 tmpreg |= (uint32_t)((uint32_t)data & I2C_CR2_SADD);
<> 156:95d6b41a828b 697 if (data & 0x01) {
AnnaBridge 187:0387e8f68319 698 tmpreg |= I2C_CR2_START | I2C_CR2_RD_WRN;
<> 156:95d6b41a828b 699 } else {
AnnaBridge 187:0387e8f68319 700 tmpreg |= I2C_CR2_START;
AnnaBridge 187:0387e8f68319 701 tmpreg &= ~I2C_CR2_RD_WRN;
<> 156:95d6b41a828b 702 }
<> 156:95d6b41a828b 703 /* Disable reload first to use it later */
<> 156:95d6b41a828b 704 tmpreg &= ~I2C_CR2_RELOAD;
<> 156:95d6b41a828b 705 /* Disable Autoend */
<> 156:95d6b41a828b 706 tmpreg &= ~I2C_CR2_AUTOEND;
<> 156:95d6b41a828b 707 /* Do not set any transfer size for now */
<> 156:95d6b41a828b 708 tmpreg |= (I2C_CR2_NBYTES & (1 << 16));
<> 156:95d6b41a828b 709 /* Set the prepared configuration */
<> 156:95d6b41a828b 710 handle->Instance->CR2 = tmpreg;
<> 156:95d6b41a828b 711 } else {
<> 156:95d6b41a828b 712 /* Set the prepared configuration */
<> 156:95d6b41a828b 713 tmpreg = handle->Instance->CR2;
<> 153:fa9ff456f731 714
<> 156:95d6b41a828b 715 /* Then send data when there's room in the TX fifo */
<> 156:95d6b41a828b 716 if ((tmpreg & I2C_CR2_RELOAD) != 0) {
<> 156:95d6b41a828b 717 while (!__HAL_I2C_GET_FLAG(handle, I2C_FLAG_TCR)) {
<> 156:95d6b41a828b 718 if ((timeout--) == 0) {
<> 156:95d6b41a828b 719 DEBUG_PRINTF("timeout in byte_write\r\n");
<> 156:95d6b41a828b 720 return 2;
<> 156:95d6b41a828b 721 }
<> 156:95d6b41a828b 722 }
<> 153:fa9ff456f731 723 }
<> 156:95d6b41a828b 724 /* Enable reload mode as we don't know how many bytes will eb sent */
<> 156:95d6b41a828b 725 tmpreg |= I2C_CR2_RELOAD;
AnnaBridge 187:0387e8f68319 726 /* Set transfer size to 1 */
<> 156:95d6b41a828b 727 tmpreg |= (I2C_CR2_NBYTES & (1 << 16));
AnnaBridge 187:0387e8f68319 728 /* Set the prepared configuration */
<> 156:95d6b41a828b 729 handle->Instance->CR2 = tmpreg;
<> 156:95d6b41a828b 730 /* Prepare next write */
<> 156:95d6b41a828b 731 timeout = FLAG_TIMEOUT;
<> 156:95d6b41a828b 732 while (!__HAL_I2C_GET_FLAG(handle, I2C_FLAG_TXE)) {
<> 156:95d6b41a828b 733 if ((timeout--) == 0) {
<> 156:95d6b41a828b 734 return 2;
<> 156:95d6b41a828b 735 }
<> 156:95d6b41a828b 736 }
<> 156:95d6b41a828b 737 /* Write byte */
<> 156:95d6b41a828b 738 handle->Instance->TXDR = data;
<> 153:fa9ff456f731 739 }
<> 153:fa9ff456f731 740
<> 153:fa9ff456f731 741 return 1;
<> 153:fa9ff456f731 742 }
<> 153:fa9ff456f731 743 #endif //I2C_IP_VERSION_V2
<> 153:fa9ff456f731 744
<> 153:fa9ff456f731 745 /*
<> 153:fa9ff456f731 746 * SYNC APIS
<> 153:fa9ff456f731 747 */
AnnaBridge 187:0387e8f68319 748 int i2c_read(i2c_t *obj, int address, char *data, int length, int stop)
AnnaBridge 187:0387e8f68319 749 {
<> 154:37f96f9d4de2 750 struct i2c_s *obj_s = I2C_S(obj);
<> 154:37f96f9d4de2 751 I2C_HandleTypeDef *handle = &(obj_s->handle);
<> 154:37f96f9d4de2 752 int count = I2C_ERROR_BUS_BUSY, ret = 0;
<> 154:37f96f9d4de2 753 uint32_t timeout = 0;
<> 154:37f96f9d4de2 754
AnnaBridge 177:d650f5d4c87a 755 // Trick to remove compiler warning "left and right operands are identical" in some cases
AnnaBridge 177:d650f5d4c87a 756 uint32_t op1 = I2C_FIRST_AND_LAST_FRAME;
AnnaBridge 177:d650f5d4c87a 757 uint32_t op2 = I2C_LAST_FRAME;
AnnaBridge 177:d650f5d4c87a 758 if ((obj_s->XferOperation == op1) || (obj_s->XferOperation == op2)) {
AnnaBridge 187:0387e8f68319 759 if (stop) {
<> 154:37f96f9d4de2 760 obj_s->XferOperation = I2C_FIRST_AND_LAST_FRAME;
AnnaBridge 187:0387e8f68319 761 } else {
<> 154:37f96f9d4de2 762 obj_s->XferOperation = I2C_FIRST_FRAME;
AnnaBridge 187:0387e8f68319 763 }
<> 154:37f96f9d4de2 764 } else if ((obj_s->XferOperation == I2C_FIRST_FRAME) ||
AnnaBridge 187:0387e8f68319 765 (obj_s->XferOperation == I2C_NEXT_FRAME)) {
AnnaBridge 187:0387e8f68319 766 if (stop) {
<> 154:37f96f9d4de2 767 obj_s->XferOperation = I2C_LAST_FRAME;
AnnaBridge 187:0387e8f68319 768 } else {
<> 154:37f96f9d4de2 769 obj_s->XferOperation = I2C_NEXT_FRAME;
AnnaBridge 187:0387e8f68319 770 }
<> 154:37f96f9d4de2 771 }
<> 154:37f96f9d4de2 772
<> 154:37f96f9d4de2 773 obj_s->event = 0;
<> 154:37f96f9d4de2 774
AnnaBridge 187:0387e8f68319 775 /* Activate default IRQ handlers for sync mode
AnnaBridge 187:0387e8f68319 776 * which would be overwritten in async mode
AnnaBridge 187:0387e8f68319 777 */
<> 154:37f96f9d4de2 778 i2c_ev_err_enable(obj, i2c_get_irq_handler(obj));
<> 154:37f96f9d4de2 779
<> 154:37f96f9d4de2 780 ret = HAL_I2C_Master_Sequential_Receive_IT(handle, address, (uint8_t *) data, length, obj_s->XferOperation);
<> 154:37f96f9d4de2 781
AnnaBridge 187:0387e8f68319 782 if (ret == HAL_OK) {
<> 154:37f96f9d4de2 783 timeout = BYTE_TIMEOUT_US * (length + 1);
<> 154:37f96f9d4de2 784 /* transfer started : wait completion or timeout */
AnnaBridge 187:0387e8f68319 785 while (!(obj_s->event & I2C_EVENT_ALL) && (--timeout != 0)) {
<> 154:37f96f9d4de2 786 wait_us(1);
<> 154:37f96f9d4de2 787 }
<> 154:37f96f9d4de2 788
<> 154:37f96f9d4de2 789 i2c_ev_err_disable(obj);
<> 154:37f96f9d4de2 790
AnnaBridge 187:0387e8f68319 791 if ((timeout == 0) || (obj_s->event != I2C_EVENT_TRANSFER_COMPLETE)) {
<> 154:37f96f9d4de2 792 DEBUG_PRINTF(" TIMEOUT or error in i2c_read\r\n");
<> 154:37f96f9d4de2 793 /* re-init IP to try and get back in a working state */
<> 154:37f96f9d4de2 794 i2c_init(obj, obj_s->sda, obj_s->scl);
<> 154:37f96f9d4de2 795 } else {
<> 154:37f96f9d4de2 796 count = length;
<> 154:37f96f9d4de2 797 }
<> 154:37f96f9d4de2 798 } else {
<> 154:37f96f9d4de2 799 DEBUG_PRINTF("ERROR in i2c_read:%d\r\n", ret);
<> 154:37f96f9d4de2 800 }
<> 154:37f96f9d4de2 801
<> 154:37f96f9d4de2 802 return count;
<> 154:37f96f9d4de2 803 }
<> 154:37f96f9d4de2 804
AnnaBridge 187:0387e8f68319 805 int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop)
AnnaBridge 187:0387e8f68319 806 {
<> 153:fa9ff456f731 807 struct i2c_s *obj_s = I2C_S(obj);
<> 153:fa9ff456f731 808 I2C_HandleTypeDef *handle = &(obj_s->handle);
<> 154:37f96f9d4de2 809 int count = I2C_ERROR_BUS_BUSY, ret = 0;
<> 153:fa9ff456f731 810 uint32_t timeout = 0;
<> 153:fa9ff456f731 811
AnnaBridge 177:d650f5d4c87a 812 // Trick to remove compiler warning "left and right operands are identical" in some cases
AnnaBridge 177:d650f5d4c87a 813 uint32_t op1 = I2C_FIRST_AND_LAST_FRAME;
AnnaBridge 177:d650f5d4c87a 814 uint32_t op2 = I2C_LAST_FRAME;
AnnaBridge 177:d650f5d4c87a 815 if ((obj_s->XferOperation == op1) || (obj_s->XferOperation == op2)) {
AnnaBridge 187:0387e8f68319 816 if (stop) {
<> 153:fa9ff456f731 817 obj_s->XferOperation = I2C_FIRST_AND_LAST_FRAME;
AnnaBridge 187:0387e8f68319 818 } else {
<> 153:fa9ff456f731 819 obj_s->XferOperation = I2C_FIRST_FRAME;
AnnaBridge 187:0387e8f68319 820 }
<> 153:fa9ff456f731 821 } else if ((obj_s->XferOperation == I2C_FIRST_FRAME) ||
AnnaBridge 187:0387e8f68319 822 (obj_s->XferOperation == I2C_NEXT_FRAME)) {
AnnaBridge 187:0387e8f68319 823 if (stop) {
<> 153:fa9ff456f731 824 obj_s->XferOperation = I2C_LAST_FRAME;
AnnaBridge 187:0387e8f68319 825 } else {
<> 153:fa9ff456f731 826 obj_s->XferOperation = I2C_NEXT_FRAME;
AnnaBridge 187:0387e8f68319 827 }
<> 153:fa9ff456f731 828 }
<> 153:fa9ff456f731 829
<> 153:fa9ff456f731 830 obj_s->event = 0;
<> 153:fa9ff456f731 831
<> 153:fa9ff456f731 832 i2c_ev_err_enable(obj, i2c_get_irq_handler(obj));
<> 153:fa9ff456f731 833
AnnaBridge 187:0387e8f68319 834 ret = HAL_I2C_Master_Sequential_Transmit_IT(handle, address, (uint8_t *) data, length, obj_s->XferOperation);
<> 153:fa9ff456f731 835
AnnaBridge 187:0387e8f68319 836 if (ret == HAL_OK) {
<> 154:37f96f9d4de2 837 timeout = BYTE_TIMEOUT_US * (length + 1);
<> 153:fa9ff456f731 838 /* transfer started : wait completion or timeout */
AnnaBridge 187:0387e8f68319 839 while (!(obj_s->event & I2C_EVENT_ALL) && (--timeout != 0)) {
<> 153:fa9ff456f731 840 wait_us(1);
<> 153:fa9ff456f731 841 }
<> 153:fa9ff456f731 842
<> 153:fa9ff456f731 843 i2c_ev_err_disable(obj);
<> 153:fa9ff456f731 844
AnnaBridge 187:0387e8f68319 845 if ((timeout == 0) || (obj_s->event != I2C_EVENT_TRANSFER_COMPLETE)) {
<> 153:fa9ff456f731 846 DEBUG_PRINTF(" TIMEOUT or error in i2c_write\r\n");
<> 153:fa9ff456f731 847 /* re-init IP to try and get back in a working state */
<> 153:fa9ff456f731 848 i2c_init(obj, obj_s->sda, obj_s->scl);
AnnaBridge 187:0387e8f68319 849 } else {
<> 153:fa9ff456f731 850 count = length;
AnnaBridge 187:0387e8f68319 851 }
<> 153:fa9ff456f731 852 } else {
<> 153:fa9ff456f731 853 DEBUG_PRINTF("ERROR in i2c_read\r\n");
<> 153:fa9ff456f731 854 }
<> 153:fa9ff456f731 855
<> 153:fa9ff456f731 856 return count;
<> 153:fa9ff456f731 857 }
<> 153:fa9ff456f731 858
AnnaBridge 187:0387e8f68319 859 void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c)
AnnaBridge 187:0387e8f68319 860 {
<> 153:fa9ff456f731 861 /* Get object ptr based on handler ptr */
<> 153:fa9ff456f731 862 i2c_t *obj = get_i2c_obj(hi2c);
<> 153:fa9ff456f731 863 struct i2c_s *obj_s = I2C_S(obj);
<> 153:fa9ff456f731 864
<> 153:fa9ff456f731 865 #if DEVICE_I2C_ASYNCH
<> 153:fa9ff456f731 866 /* Handle potential Tx/Rx use case */
<> 153:fa9ff456f731 867 if ((obj->tx_buff.length) && (obj->rx_buff.length)) {
<> 153:fa9ff456f731 868 if (obj_s->stop) {
<> 153:fa9ff456f731 869 obj_s->XferOperation = I2C_LAST_FRAME;
<> 153:fa9ff456f731 870 } else {
<> 153:fa9ff456f731 871 obj_s->XferOperation = I2C_NEXT_FRAME;
<> 153:fa9ff456f731 872 }
<> 153:fa9ff456f731 873
AnnaBridge 187:0387e8f68319 874 HAL_I2C_Master_Sequential_Receive_IT(hi2c, obj_s->address, (uint8_t *)obj->rx_buff.buffer, obj->rx_buff.length, obj_s->XferOperation);
AnnaBridge 187:0387e8f68319 875 } else
<> 153:fa9ff456f731 876 #endif
<> 153:fa9ff456f731 877 {
<> 153:fa9ff456f731 878 /* Set event flag */
<> 153:fa9ff456f731 879 obj_s->event = I2C_EVENT_TRANSFER_COMPLETE;
<> 153:fa9ff456f731 880 }
<> 153:fa9ff456f731 881 }
<> 153:fa9ff456f731 882
AnnaBridge 187:0387e8f68319 883 void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *hi2c)
AnnaBridge 187:0387e8f68319 884 {
<> 153:fa9ff456f731 885 /* Get object ptr based on handler ptr */
<> 153:fa9ff456f731 886 i2c_t *obj = get_i2c_obj(hi2c);
<> 153:fa9ff456f731 887 struct i2c_s *obj_s = I2C_S(obj);
<> 153:fa9ff456f731 888
<> 153:fa9ff456f731 889 /* Set event flag */
<> 153:fa9ff456f731 890 obj_s->event = I2C_EVENT_TRANSFER_COMPLETE;
<> 153:fa9ff456f731 891 }
<> 153:fa9ff456f731 892
AnnaBridge 187:0387e8f68319 893 void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c)
AnnaBridge 187:0387e8f68319 894 {
<> 153:fa9ff456f731 895 /* Get object ptr based on handler ptr */
<> 153:fa9ff456f731 896 i2c_t *obj = get_i2c_obj(hi2c);
<> 153:fa9ff456f731 897 struct i2c_s *obj_s = I2C_S(obj);
<> 153:fa9ff456f731 898 #if DEVICE_I2CSLAVE
<> 153:fa9ff456f731 899 I2C_HandleTypeDef *handle = &(obj_s->handle);
<> 153:fa9ff456f731 900 uint32_t address = 0;
<> 153:fa9ff456f731 901 /* Store address to handle it after reset */
AnnaBridge 187:0387e8f68319 902 if (obj_s->slave) {
<> 153:fa9ff456f731 903 address = handle->Init.OwnAddress1;
AnnaBridge 187:0387e8f68319 904 }
<> 153:fa9ff456f731 905 #endif
<> 153:fa9ff456f731 906
<> 153:fa9ff456f731 907 DEBUG_PRINTF("HAL_I2C_ErrorCallback:%d, index=%d\r\n", (int) hi2c->ErrorCode, obj_s->index);
<> 153:fa9ff456f731 908
<> 153:fa9ff456f731 909 /* re-init IP to try and get back in a working state */
<> 153:fa9ff456f731 910 i2c_init(obj, obj_s->sda, obj_s->scl);
<> 153:fa9ff456f731 911
<> 153:fa9ff456f731 912 #if DEVICE_I2CSLAVE
<> 153:fa9ff456f731 913 /* restore slave address */
<> 162:e13f6fdb2ac4 914 if (address != 0) {
<> 162:e13f6fdb2ac4 915 obj_s->slave = 1;
<> 162:e13f6fdb2ac4 916 i2c_slave_address(obj, 0, address, 0);
<> 162:e13f6fdb2ac4 917 }
<> 153:fa9ff456f731 918 #endif
<> 153:fa9ff456f731 919
<> 153:fa9ff456f731 920 /* Keep Set event flag */
<> 153:fa9ff456f731 921 obj_s->event = I2C_EVENT_ERROR;
<> 153:fa9ff456f731 922 }
<> 153:fa9ff456f731 923
<> 153:fa9ff456f731 924 #if DEVICE_I2CSLAVE
<> 153:fa9ff456f731 925 /* SLAVE API FUNCTIONS */
AnnaBridge 187:0387e8f68319 926 void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask)
AnnaBridge 187:0387e8f68319 927 {
<> 153:fa9ff456f731 928 struct i2c_s *obj_s = I2C_S(obj);
<> 153:fa9ff456f731 929 I2C_HandleTypeDef *handle = &(obj_s->handle);
<> 153:fa9ff456f731 930
<> 153:fa9ff456f731 931 // I2C configuration
<> 153:fa9ff456f731 932 handle->Init.OwnAddress1 = address;
<> 153:fa9ff456f731 933 HAL_I2C_Init(handle);
<> 153:fa9ff456f731 934
<> 153:fa9ff456f731 935 i2c_ev_err_enable(obj, i2c_get_irq_handler(obj));
<> 153:fa9ff456f731 936
<> 153:fa9ff456f731 937 HAL_I2C_EnableListen_IT(handle);
<> 153:fa9ff456f731 938 }
<> 153:fa9ff456f731 939
AnnaBridge 187:0387e8f68319 940 void i2c_slave_mode(i2c_t *obj, int enable_slave)
AnnaBridge 187:0387e8f68319 941 {
<> 153:fa9ff456f731 942
<> 153:fa9ff456f731 943 struct i2c_s *obj_s = I2C_S(obj);
<> 153:fa9ff456f731 944 I2C_HandleTypeDef *handle = &(obj_s->handle);
<> 153:fa9ff456f731 945
<> 153:fa9ff456f731 946 if (enable_slave) {
<> 153:fa9ff456f731 947 obj_s->slave = 1;
<> 153:fa9ff456f731 948 HAL_I2C_EnableListen_IT(handle);
<> 153:fa9ff456f731 949 } else {
<> 153:fa9ff456f731 950 obj_s->slave = 0;
<> 153:fa9ff456f731 951 HAL_I2C_DisableListen_IT(handle);
<> 153:fa9ff456f731 952 }
<> 153:fa9ff456f731 953 }
<> 153:fa9ff456f731 954
<> 153:fa9ff456f731 955 // See I2CSlave.h
<> 153:fa9ff456f731 956 #define NoData 0 // the slave has not been addressed
<> 153:fa9ff456f731 957 #define ReadAddressed 1 // the master has requested a read from this slave (slave = transmitter)
<> 153:fa9ff456f731 958 #define WriteGeneral 2 // the master is writing to all slave
<> 153:fa9ff456f731 959 #define WriteAddressed 3 // the master is writing to this slave (slave = receiver)
<> 153:fa9ff456f731 960
<> 153:fa9ff456f731 961
AnnaBridge 187:0387e8f68319 962 void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, uint16_t AddrMatchCode)
AnnaBridge 187:0387e8f68319 963 {
<> 153:fa9ff456f731 964 /* Get object ptr based on handler ptr */
<> 153:fa9ff456f731 965 i2c_t *obj = get_i2c_obj(hi2c);
<> 153:fa9ff456f731 966 struct i2c_s *obj_s = I2C_S(obj);
<> 153:fa9ff456f731 967
<> 153:fa9ff456f731 968 /* Transfer direction in HAL is from Master point of view */
AnnaBridge 187:0387e8f68319 969 if (TransferDirection == I2C_DIRECTION_RECEIVE) {
<> 153:fa9ff456f731 970 obj_s->pending_slave_tx_master_rx = 1;
<> 153:fa9ff456f731 971 }
<> 153:fa9ff456f731 972
AnnaBridge 187:0387e8f68319 973 if (TransferDirection == I2C_DIRECTION_TRANSMIT) {
<> 153:fa9ff456f731 974 obj_s->pending_slave_rx_maxter_tx = 1;
<> 153:fa9ff456f731 975 }
<> 153:fa9ff456f731 976 }
<> 153:fa9ff456f731 977
AnnaBridge 187:0387e8f68319 978 void HAL_I2C_SlaveTxCpltCallback(I2C_HandleTypeDef *I2cHandle)
AnnaBridge 187:0387e8f68319 979 {
<> 153:fa9ff456f731 980 /* Get object ptr based on handler ptr */
<> 153:fa9ff456f731 981 i2c_t *obj = get_i2c_obj(I2cHandle);
<> 153:fa9ff456f731 982 struct i2c_s *obj_s = I2C_S(obj);
<> 153:fa9ff456f731 983 obj_s->pending_slave_tx_master_rx = 0;
<> 153:fa9ff456f731 984 }
<> 153:fa9ff456f731 985
AnnaBridge 187:0387e8f68319 986 void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *I2cHandle)
AnnaBridge 187:0387e8f68319 987 {
<> 153:fa9ff456f731 988 /* Get object ptr based on handler ptr */
<> 153:fa9ff456f731 989 i2c_t *obj = get_i2c_obj(I2cHandle);
<> 153:fa9ff456f731 990 struct i2c_s *obj_s = I2C_S(obj);
<> 153:fa9ff456f731 991 obj_s->pending_slave_rx_maxter_tx = 0;
<> 153:fa9ff456f731 992 }
<> 153:fa9ff456f731 993
<> 153:fa9ff456f731 994 void HAL_I2C_ListenCpltCallback(I2C_HandleTypeDef *hi2c)
<> 153:fa9ff456f731 995 {
<> 153:fa9ff456f731 996 /* restart listening for master requests */
<> 153:fa9ff456f731 997 HAL_I2C_EnableListen_IT(hi2c);
<> 153:fa9ff456f731 998 }
<> 153:fa9ff456f731 999
AnnaBridge 187:0387e8f68319 1000 int i2c_slave_receive(i2c_t *obj)
AnnaBridge 187:0387e8f68319 1001 {
<> 153:fa9ff456f731 1002
<> 153:fa9ff456f731 1003 struct i2c_s *obj_s = I2C_S(obj);
<> 153:fa9ff456f731 1004 int retValue = NoData;
<> 153:fa9ff456f731 1005
AnnaBridge 187:0387e8f68319 1006 if (obj_s->pending_slave_rx_maxter_tx) {
AnnaBridge 187:0387e8f68319 1007 retValue = WriteAddressed;
AnnaBridge 187:0387e8f68319 1008 }
<> 153:fa9ff456f731 1009
AnnaBridge 187:0387e8f68319 1010 if (obj_s->pending_slave_tx_master_rx) {
AnnaBridge 187:0387e8f68319 1011 retValue = ReadAddressed;
AnnaBridge 187:0387e8f68319 1012 }
<> 153:fa9ff456f731 1013
<> 153:fa9ff456f731 1014 return (retValue);
<> 153:fa9ff456f731 1015 }
<> 153:fa9ff456f731 1016
AnnaBridge 187:0387e8f68319 1017 int i2c_slave_read(i2c_t *obj, char *data, int length)
AnnaBridge 187:0387e8f68319 1018 {
<> 153:fa9ff456f731 1019 struct i2c_s *obj_s = I2C_S(obj);
<> 153:fa9ff456f731 1020 I2C_HandleTypeDef *handle = &(obj_s->handle);
<> 153:fa9ff456f731 1021 int count = 0;
<> 153:fa9ff456f731 1022 int ret = 0;
<> 153:fa9ff456f731 1023 uint32_t timeout = 0;
<> 153:fa9ff456f731 1024
<> 153:fa9ff456f731 1025 /* Always use I2C_NEXT_FRAME as slave will just adapt to master requests */
<> 153:fa9ff456f731 1026 ret = HAL_I2C_Slave_Sequential_Receive_IT(handle, (uint8_t *) data, length, I2C_NEXT_FRAME);
<> 153:fa9ff456f731 1027
AnnaBridge 187:0387e8f68319 1028 if (ret == HAL_OK) {
<> 154:37f96f9d4de2 1029 timeout = BYTE_TIMEOUT_US * (length + 1);
AnnaBridge 187:0387e8f68319 1030 while (obj_s->pending_slave_rx_maxter_tx && (--timeout != 0)) {
<> 153:fa9ff456f731 1031 wait_us(1);
<> 153:fa9ff456f731 1032 }
<> 153:fa9ff456f731 1033
AnnaBridge 187:0387e8f68319 1034 if (timeout != 0) {
AnnaBridge 187:0387e8f68319 1035 count = length;
AnnaBridge 187:0387e8f68319 1036 } else {
AnnaBridge 187:0387e8f68319 1037 DEBUG_PRINTF("TIMEOUT or error in i2c_slave_read\r\n");
AnnaBridge 187:0387e8f68319 1038 }
<> 153:fa9ff456f731 1039 }
<> 153:fa9ff456f731 1040 return count;
<> 153:fa9ff456f731 1041 }
<> 153:fa9ff456f731 1042
AnnaBridge 187:0387e8f68319 1043 int i2c_slave_write(i2c_t *obj, const char *data, int length)
AnnaBridge 187:0387e8f68319 1044 {
<> 153:fa9ff456f731 1045 struct i2c_s *obj_s = I2C_S(obj);
<> 153:fa9ff456f731 1046 I2C_HandleTypeDef *handle = &(obj_s->handle);
<> 153:fa9ff456f731 1047 int count = 0;
<> 153:fa9ff456f731 1048 int ret = 0;
<> 153:fa9ff456f731 1049 uint32_t timeout = 0;
<> 153:fa9ff456f731 1050
<> 153:fa9ff456f731 1051 /* Always use I2C_NEXT_FRAME as slave will just adapt to master requests */
<> 153:fa9ff456f731 1052 ret = HAL_I2C_Slave_Sequential_Transmit_IT(handle, (uint8_t *) data, length, I2C_NEXT_FRAME);
<> 153:fa9ff456f731 1053
AnnaBridge 187:0387e8f68319 1054 if (ret == HAL_OK) {
<> 154:37f96f9d4de2 1055 timeout = BYTE_TIMEOUT_US * (length + 1);
AnnaBridge 187:0387e8f68319 1056 while (obj_s->pending_slave_tx_master_rx && (--timeout != 0)) {
<> 153:fa9ff456f731 1057 wait_us(1);
<> 153:fa9ff456f731 1058 }
<> 153:fa9ff456f731 1059
AnnaBridge 187:0387e8f68319 1060 if (timeout != 0) {
AnnaBridge 187:0387e8f68319 1061 count = length;
AnnaBridge 187:0387e8f68319 1062 } else {
AnnaBridge 187:0387e8f68319 1063 DEBUG_PRINTF("TIMEOUT or error in i2c_slave_write\r\n");
AnnaBridge 187:0387e8f68319 1064 }
<> 153:fa9ff456f731 1065 }
<> 153:fa9ff456f731 1066
<> 153:fa9ff456f731 1067 return count;
<> 153:fa9ff456f731 1068 }
<> 153:fa9ff456f731 1069 #endif // DEVICE_I2CSLAVE
<> 153:fa9ff456f731 1070
<> 153:fa9ff456f731 1071 #if DEVICE_I2C_ASYNCH
<> 153:fa9ff456f731 1072 /* ASYNCH MASTER API FUNCTIONS */
AnnaBridge 187:0387e8f68319 1073 void HAL_I2C_AbortCpltCallback(I2C_HandleTypeDef *hi2c)
AnnaBridge 187:0387e8f68319 1074 {
<> 153:fa9ff456f731 1075 /* Get object ptr based on handler ptr */
<> 153:fa9ff456f731 1076 i2c_t *obj = get_i2c_obj(hi2c);
<> 153:fa9ff456f731 1077 struct i2c_s *obj_s = I2C_S(obj);
<> 153:fa9ff456f731 1078 I2C_HandleTypeDef *handle = &(obj_s->handle);
<> 153:fa9ff456f731 1079
<> 153:fa9ff456f731 1080 /* Disable IT. Not always done before calling macro */
<> 153:fa9ff456f731 1081 __HAL_I2C_DISABLE_IT(handle, I2C_IT_ALL);
<> 153:fa9ff456f731 1082 i2c_ev_err_disable(obj);
<> 153:fa9ff456f731 1083
<> 153:fa9ff456f731 1084 /* Set event flag */
<> 153:fa9ff456f731 1085 obj_s->event = I2C_EVENT_ERROR;
<> 153:fa9ff456f731 1086 }
<> 153:fa9ff456f731 1087
AnnaBridge 187:0387e8f68319 1088 void i2c_transfer_asynch(i2c_t *obj, const void *tx, size_t tx_length, void *rx, size_t rx_length, uint32_t address, uint32_t stop, uint32_t handler, uint32_t event, DMAUsage hint)
AnnaBridge 187:0387e8f68319 1089 {
<> 153:fa9ff456f731 1090
<> 153:fa9ff456f731 1091 // TODO: DMA usage is currently ignored by this way
<> 153:fa9ff456f731 1092 (void) hint;
<> 153:fa9ff456f731 1093
<> 153:fa9ff456f731 1094 struct i2c_s *obj_s = I2C_S(obj);
<> 153:fa9ff456f731 1095 I2C_HandleTypeDef *handle = &(obj_s->handle);
<> 153:fa9ff456f731 1096
<> 153:fa9ff456f731 1097 /* Update object */
<> 153:fa9ff456f731 1098 obj->tx_buff.buffer = (void *)tx;
<> 153:fa9ff456f731 1099 obj->tx_buff.length = tx_length;
<> 153:fa9ff456f731 1100 obj->tx_buff.pos = 0;
<> 153:fa9ff456f731 1101 obj->tx_buff.width = 8;
<> 153:fa9ff456f731 1102
<> 153:fa9ff456f731 1103 obj->rx_buff.buffer = (void *)rx;
<> 153:fa9ff456f731 1104 obj->rx_buff.length = rx_length;
<> 153:fa9ff456f731 1105 obj->rx_buff.pos = SIZE_MAX;
<> 153:fa9ff456f731 1106 obj->rx_buff.width = 8;
<> 153:fa9ff456f731 1107
<> 153:fa9ff456f731 1108 obj_s->available_events = event;
<> 153:fa9ff456f731 1109 obj_s->event = 0;
<> 153:fa9ff456f731 1110 obj_s->address = address;
<> 153:fa9ff456f731 1111 obj_s->stop = stop;
<> 153:fa9ff456f731 1112
<> 153:fa9ff456f731 1113 i2c_ev_err_enable(obj, handler);
<> 153:fa9ff456f731 1114
<> 153:fa9ff456f731 1115 /* Set operation step depending if stop sending required or not */
<> 153:fa9ff456f731 1116 if ((tx_length && !rx_length) || (!tx_length && rx_length)) {
AnnaBridge 177:d650f5d4c87a 1117 // Trick to remove compiler warning "left and right operands are identical" in some cases
AnnaBridge 177:d650f5d4c87a 1118 uint32_t op1 = I2C_FIRST_AND_LAST_FRAME;
AnnaBridge 177:d650f5d4c87a 1119 uint32_t op2 = I2C_LAST_FRAME;
AnnaBridge 177:d650f5d4c87a 1120 if ((obj_s->XferOperation == op1) || (obj_s->XferOperation == op2)) {
AnnaBridge 187:0387e8f68319 1121 if (stop) {
<> 153:fa9ff456f731 1122 obj_s->XferOperation = I2C_FIRST_AND_LAST_FRAME;
AnnaBridge 187:0387e8f68319 1123 } else {
<> 153:fa9ff456f731 1124 obj_s->XferOperation = I2C_FIRST_FRAME;
AnnaBridge 187:0387e8f68319 1125 }
<> 153:fa9ff456f731 1126 } else if ((obj_s->XferOperation == I2C_FIRST_FRAME) ||
AnnaBridge 187:0387e8f68319 1127 (obj_s->XferOperation == I2C_NEXT_FRAME)) {
AnnaBridge 187:0387e8f68319 1128 if (stop) {
<> 153:fa9ff456f731 1129 obj_s->XferOperation = I2C_LAST_FRAME;
AnnaBridge 187:0387e8f68319 1130 } else {
<> 153:fa9ff456f731 1131 obj_s->XferOperation = I2C_NEXT_FRAME;
AnnaBridge 187:0387e8f68319 1132 }
<> 153:fa9ff456f731 1133 }
<> 153:fa9ff456f731 1134
<> 153:fa9ff456f731 1135 if (tx_length > 0) {
AnnaBridge 187:0387e8f68319 1136 HAL_I2C_Master_Sequential_Transmit_IT(handle, address, (uint8_t *)tx, tx_length, obj_s->XferOperation);
<> 153:fa9ff456f731 1137 }
<> 153:fa9ff456f731 1138 if (rx_length > 0) {
AnnaBridge 187:0387e8f68319 1139 HAL_I2C_Master_Sequential_Receive_IT(handle, address, (uint8_t *)rx, rx_length, obj_s->XferOperation);
<> 153:fa9ff456f731 1140 }
AnnaBridge 187:0387e8f68319 1141 } else if (tx_length && rx_length) {
<> 153:fa9ff456f731 1142 /* Two steps operation, don't modify XferOperation, keep it for next step */
AnnaBridge 177:d650f5d4c87a 1143 // Trick to remove compiler warning "left and right operands are identical" in some cases
AnnaBridge 177:d650f5d4c87a 1144 uint32_t op1 = I2C_FIRST_AND_LAST_FRAME;
AnnaBridge 177:d650f5d4c87a 1145 uint32_t op2 = I2C_LAST_FRAME;
AnnaBridge 177:d650f5d4c87a 1146 if ((obj_s->XferOperation == op1) || (obj_s->XferOperation == op2)) {
AnnaBridge 187:0387e8f68319 1147 HAL_I2C_Master_Sequential_Transmit_IT(handle, address, (uint8_t *)tx, tx_length, I2C_FIRST_FRAME);
<> 153:fa9ff456f731 1148 } else if ((obj_s->XferOperation == I2C_FIRST_FRAME) ||
AnnaBridge 187:0387e8f68319 1149 (obj_s->XferOperation == I2C_NEXT_FRAME)) {
AnnaBridge 187:0387e8f68319 1150 HAL_I2C_Master_Sequential_Transmit_IT(handle, address, (uint8_t *)tx, tx_length, I2C_NEXT_FRAME);
<> 153:fa9ff456f731 1151 }
<> 153:fa9ff456f731 1152 }
<> 153:fa9ff456f731 1153 }
<> 153:fa9ff456f731 1154
<> 153:fa9ff456f731 1155
AnnaBridge 187:0387e8f68319 1156 uint32_t i2c_irq_handler_asynch(i2c_t *obj)
AnnaBridge 187:0387e8f68319 1157 {
<> 153:fa9ff456f731 1158
<> 153:fa9ff456f731 1159 struct i2c_s *obj_s = I2C_S(obj);
<> 153:fa9ff456f731 1160 I2C_HandleTypeDef *handle = &(obj_s->handle);
<> 153:fa9ff456f731 1161
<> 153:fa9ff456f731 1162 HAL_I2C_EV_IRQHandler(handle);
<> 153:fa9ff456f731 1163 HAL_I2C_ER_IRQHandler(handle);
<> 153:fa9ff456f731 1164
AnnaBridge 187:0387e8f68319 1165 /* Return I2C event status */
<> 153:fa9ff456f731 1166 return (obj_s->event & obj_s->available_events);
<> 153:fa9ff456f731 1167 }
<> 153:fa9ff456f731 1168
AnnaBridge 187:0387e8f68319 1169 uint8_t i2c_active(i2c_t *obj)
AnnaBridge 187:0387e8f68319 1170 {
<> 153:fa9ff456f731 1171
<> 153:fa9ff456f731 1172 struct i2c_s *obj_s = I2C_S(obj);
<> 153:fa9ff456f731 1173 I2C_HandleTypeDef *handle = &(obj_s->handle);
<> 153:fa9ff456f731 1174
<> 153:fa9ff456f731 1175 if (handle->State == HAL_I2C_STATE_READY) {
<> 153:fa9ff456f731 1176 return 0;
AnnaBridge 187:0387e8f68319 1177 } else {
<> 153:fa9ff456f731 1178 return 1;
<> 153:fa9ff456f731 1179 }
<> 153:fa9ff456f731 1180 }
<> 153:fa9ff456f731 1181
AnnaBridge 187:0387e8f68319 1182 void i2c_abort_asynch(i2c_t *obj)
AnnaBridge 187:0387e8f68319 1183 {
<> 153:fa9ff456f731 1184
<> 153:fa9ff456f731 1185 struct i2c_s *obj_s = I2C_S(obj);
<> 153:fa9ff456f731 1186 I2C_HandleTypeDef *handle = &(obj_s->handle);
<> 153:fa9ff456f731 1187
<> 153:fa9ff456f731 1188 /* Abort HAL requires DevAddress, but is not used. Use Dummy */
<> 153:fa9ff456f731 1189 uint16_t Dummy_DevAddress = 0x00;
<> 153:fa9ff456f731 1190
<> 153:fa9ff456f731 1191 HAL_I2C_Master_Abort_IT(handle, Dummy_DevAddress);
<> 153:fa9ff456f731 1192 }
<> 153:fa9ff456f731 1193
<> 153:fa9ff456f731 1194 #endif // DEVICE_I2C_ASYNCH
<> 153:fa9ff456f731 1195
<> 153:fa9ff456f731 1196 #endif // DEVICE_I2C