Modification of Mbed-dev library for LQFP48 package microcontrollers: STM32F103C8 (STM32F103C8T6) and STM32F103CB (STM32F103CBT6) (Bluepill boards, Maple mini etc. )

Fork of mbed-STM32F103C8_org by Nothing Special

Library for STM32F103C8 (Bluepill boards etc.).
Use this instead of mbed library.
This library allows the size of the code in the FLASH up to 128kB. Therefore, code also runs on microcontrollers STM32F103CB (eg. Maple mini).
But in the case of STM32F103C8, check the size of the resulting code would not exceed 64kB.

To compile a program with this library, use NUCLEO-F103RB as the target name. !

Changes:

  • Corrected initialization of the HSE + crystal clock (mbed permanent bug), allowing the use of on-board xtal (8MHz).(1)
  • Additionally, it also set USB clock (48Mhz).(2)
  • Definitions of pins and peripherals adjusted to LQFP48 case.
  • Board led LED1 is now PC_13 (3)
  • USER_BUTTON is now PC_14 (4)

    Now the library is complete rebuilt based on mbed-dev v160 (and not yet fully tested).

notes
(1) - In case 8MHz xtal on board, CPU frequency is 72MHz. Without xtal is 64MHz.
(2) - Using the USB interface is only possible if STM32 is clocking by on-board 8MHz xtal or external clock signal 8MHz on the OSC_IN pin.
(3) - On Bluepill board led operation is reversed, i.e. 0 - led on, 1 - led off.
(4) - Bluepill board has no real user button

Information

After export to SW4STM (AC6):

  • add line #include "mbed_config.h" in files Serial.h and RawSerial.h
  • in project properties change Optimisation Level to Optimise for size (-Os)
Committer:
mega64
Date:
Thu Apr 27 23:56:38 2017 +0000
Revision:
148:8b0b02bf146f
Parent:
146:03e976389d16
Remove unnecessary folders

Who changed what in which revision?

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