mbed library sources

Dependents:   FRDM-KL46Z_LCD_Test FRDM-KL46Z_LCD_Test FRDM-KL46Z_Plantilla FRDM-KL46Z_Plantilla ... more

Committer:
ebrus
Date:
Thu Jul 28 15:56:34 2016 +0000
Revision:
0:6bc4ac881c8e
1;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ebrus 0:6bc4ac881c8e 1 /* mbed Microcontroller Library
ebrus 0:6bc4ac881c8e 2 *******************************************************************************
ebrus 0:6bc4ac881c8e 3 * Copyright (c) 2014, STMicroelectronics
ebrus 0:6bc4ac881c8e 4 * All rights reserved.
ebrus 0:6bc4ac881c8e 5 *
ebrus 0:6bc4ac881c8e 6 * Redistribution and use in source and binary forms, with or without
ebrus 0:6bc4ac881c8e 7 * modification, are permitted provided that the following conditions are met:
ebrus 0:6bc4ac881c8e 8 *
ebrus 0:6bc4ac881c8e 9 * 1. Redistributions of source code must retain the above copyright notice,
ebrus 0:6bc4ac881c8e 10 * this list of conditions and the following disclaimer.
ebrus 0:6bc4ac881c8e 11 * 2. Redistributions in binary form must reproduce the above copyright notice,
ebrus 0:6bc4ac881c8e 12 * this list of conditions and the following disclaimer in the documentation
ebrus 0:6bc4ac881c8e 13 * and/or other materials provided with the distribution.
ebrus 0:6bc4ac881c8e 14 * 3. Neither the name of STMicroelectronics nor the names of its contributors
ebrus 0:6bc4ac881c8e 15 * may be used to endorse or promote products derived from this software
ebrus 0:6bc4ac881c8e 16 * without specific prior written permission.
ebrus 0:6bc4ac881c8e 17 *
ebrus 0:6bc4ac881c8e 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
ebrus 0:6bc4ac881c8e 19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
ebrus 0:6bc4ac881c8e 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
ebrus 0:6bc4ac881c8e 21 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
ebrus 0:6bc4ac881c8e 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
ebrus 0:6bc4ac881c8e 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
ebrus 0:6bc4ac881c8e 24 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
ebrus 0:6bc4ac881c8e 25 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
ebrus 0:6bc4ac881c8e 26 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
ebrus 0:6bc4ac881c8e 27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
ebrus 0:6bc4ac881c8e 28 *******************************************************************************
ebrus 0:6bc4ac881c8e 29 */
ebrus 0:6bc4ac881c8e 30 #include "mbed_assert.h"
ebrus 0:6bc4ac881c8e 31 #include "i2c_api.h"
ebrus 0:6bc4ac881c8e 32
ebrus 0:6bc4ac881c8e 33 #if DEVICE_I2C
ebrus 0:6bc4ac881c8e 34
ebrus 0:6bc4ac881c8e 35 #include "cmsis.h"
ebrus 0:6bc4ac881c8e 36 #include "pinmap.h"
ebrus 0:6bc4ac881c8e 37
ebrus 0:6bc4ac881c8e 38 /* Timeout values for flags and events waiting loops. These timeouts are
ebrus 0:6bc4ac881c8e 39 not based on accurate values, they just guarantee that the application will
ebrus 0:6bc4ac881c8e 40 not remain stuck if the I2C communication is corrupted. */
ebrus 0:6bc4ac881c8e 41 #define FLAG_TIMEOUT ((int)0x1000)
ebrus 0:6bc4ac881c8e 42 #define LONG_TIMEOUT ((int)0x8000)
ebrus 0:6bc4ac881c8e 43
ebrus 0:6bc4ac881c8e 44 static const PinMap PinMap_I2C_SDA[] = {
ebrus 0:6bc4ac881c8e 45 {PB_7, I2C_1, STM_PIN_DATA(GPIO_Mode_AF_OD, 0)},
ebrus 0:6bc4ac881c8e 46 {PB_9, I2C_1, STM_PIN_DATA(GPIO_Mode_AF_OD, 2)}, // GPIO_Remap_I2C1
ebrus 0:6bc4ac881c8e 47 {PB_11, I2C_2, STM_PIN_DATA(GPIO_Mode_AF_OD, 0)},
ebrus 0:6bc4ac881c8e 48 {NC, NC, 0}
ebrus 0:6bc4ac881c8e 49 };
ebrus 0:6bc4ac881c8e 50
ebrus 0:6bc4ac881c8e 51 static const PinMap PinMap_I2C_SCL[] = {
ebrus 0:6bc4ac881c8e 52 {PB_6, I2C_1, STM_PIN_DATA(GPIO_Mode_AF_OD, 0)},
ebrus 0:6bc4ac881c8e 53 {PB_8, I2C_1, STM_PIN_DATA(GPIO_Mode_AF_OD, 2)}, // GPIO_Remap_I2C1
ebrus 0:6bc4ac881c8e 54 {PB_10, I2C_2, STM_PIN_DATA(GPIO_Mode_AF_OD, 0)},
ebrus 0:6bc4ac881c8e 55 {NC, NC, 0}
ebrus 0:6bc4ac881c8e 56 };
ebrus 0:6bc4ac881c8e 57
ebrus 0:6bc4ac881c8e 58 int i2c1_inited = 0;
ebrus 0:6bc4ac881c8e 59 int i2c2_inited = 0;
ebrus 0:6bc4ac881c8e 60
ebrus 0:6bc4ac881c8e 61 void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
ebrus 0:6bc4ac881c8e 62 int timeout;
ebrus 0:6bc4ac881c8e 63 I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
ebrus 0:6bc4ac881c8e 64
ebrus 0:6bc4ac881c8e 65 // Determine the I2C to use
ebrus 0:6bc4ac881c8e 66 I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA);
ebrus 0:6bc4ac881c8e 67 I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL);
ebrus 0:6bc4ac881c8e 68
ebrus 0:6bc4ac881c8e 69 obj->i2c = (I2CName)pinmap_merge(i2c_sda, i2c_scl);
ebrus 0:6bc4ac881c8e 70 MBED_ASSERT(obj->i2c != (I2CName)NC);
ebrus 0:6bc4ac881c8e 71
ebrus 0:6bc4ac881c8e 72 // Enable I2C clock and configure I2C pins if not done before
ebrus 0:6bc4ac881c8e 73 if ((obj->i2c == I2C_1)&& !i2c1_inited) {
ebrus 0:6bc4ac881c8e 74 i2c1_inited = 1;
ebrus 0:6bc4ac881c8e 75 RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
ebrus 0:6bc4ac881c8e 76 // Configure I2C pins
ebrus 0:6bc4ac881c8e 77 pinmap_pinout(scl, PinMap_I2C_SCL);
ebrus 0:6bc4ac881c8e 78 pin_mode(scl, OpenDrain);
ebrus 0:6bc4ac881c8e 79 pinmap_pinout(sda, PinMap_I2C_SDA);
ebrus 0:6bc4ac881c8e 80 pin_mode(sda, OpenDrain);
ebrus 0:6bc4ac881c8e 81 }
ebrus 0:6bc4ac881c8e 82 if ((obj->i2c == I2C_2)&& !i2c2_inited) {
ebrus 0:6bc4ac881c8e 83 i2c2_inited = 1;
ebrus 0:6bc4ac881c8e 84 RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);
ebrus 0:6bc4ac881c8e 85 // Configure I2C pins
ebrus 0:6bc4ac881c8e 86 pinmap_pinout(scl, PinMap_I2C_SCL);
ebrus 0:6bc4ac881c8e 87 pin_mode(scl, OpenDrain);
ebrus 0:6bc4ac881c8e 88 pinmap_pinout(sda, PinMap_I2C_SDA);
ebrus 0:6bc4ac881c8e 89 pin_mode(sda, OpenDrain);
ebrus 0:6bc4ac881c8e 90 }
ebrus 0:6bc4ac881c8e 91
ebrus 0:6bc4ac881c8e 92 // Reset to clear pending flags if any
ebrus 0:6bc4ac881c8e 93 i2c_reset(obj);
ebrus 0:6bc4ac881c8e 94
ebrus 0:6bc4ac881c8e 95 // I2C configuration
ebrus 0:6bc4ac881c8e 96 i2c_frequency(obj, 100000); // 100 kHz per default
ebrus 0:6bc4ac881c8e 97 }
ebrus 0:6bc4ac881c8e 98
ebrus 0:6bc4ac881c8e 99 void i2c_frequency(i2c_t *obj, int hz) {
ebrus 0:6bc4ac881c8e 100 int timeout;
ebrus 0:6bc4ac881c8e 101
ebrus 0:6bc4ac881c8e 102 I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
ebrus 0:6bc4ac881c8e 103 I2C_InitTypeDef I2C_InitStructure;
ebrus 0:6bc4ac881c8e 104
ebrus 0:6bc4ac881c8e 105 if ((hz != 0) && (hz <= 400000)) {
ebrus 0:6bc4ac881c8e 106
ebrus 0:6bc4ac881c8e 107 // wait before init
ebrus 0:6bc4ac881c8e 108 timeout = LONG_TIMEOUT;
ebrus 0:6bc4ac881c8e 109 while((I2C_GetFlagStatus(i2c, I2C_FLAG_BUSY)) && (timeout-- != 0));
ebrus 0:6bc4ac881c8e 110
ebrus 0:6bc4ac881c8e 111 I2C_DeInit(i2c);
ebrus 0:6bc4ac881c8e 112
ebrus 0:6bc4ac881c8e 113 // I2C configuration
ebrus 0:6bc4ac881c8e 114 I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
ebrus 0:6bc4ac881c8e 115 I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
ebrus 0:6bc4ac881c8e 116 I2C_InitStructure.I2C_OwnAddress1 = 0;
ebrus 0:6bc4ac881c8e 117 I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
ebrus 0:6bc4ac881c8e 118 I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
ebrus 0:6bc4ac881c8e 119 I2C_InitStructure.I2C_ClockSpeed = hz;
ebrus 0:6bc4ac881c8e 120 I2C_Init(i2c, &I2C_InitStructure);
ebrus 0:6bc4ac881c8e 121
ebrus 0:6bc4ac881c8e 122 I2C_Cmd(i2c, ENABLE);
ebrus 0:6bc4ac881c8e 123 }
ebrus 0:6bc4ac881c8e 124 }
ebrus 0:6bc4ac881c8e 125
ebrus 0:6bc4ac881c8e 126 inline int i2c_start(i2c_t *obj) {
ebrus 0:6bc4ac881c8e 127 I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
ebrus 0:6bc4ac881c8e 128 int timeout;
ebrus 0:6bc4ac881c8e 129
ebrus 0:6bc4ac881c8e 130 I2C_ClearFlag(i2c, I2C_FLAG_AF); // Clear Acknowledge failure flag
ebrus 0:6bc4ac881c8e 131
ebrus 0:6bc4ac881c8e 132 // Generate the START condition
ebrus 0:6bc4ac881c8e 133 I2C_GenerateSTART(i2c, ENABLE);
ebrus 0:6bc4ac881c8e 134
ebrus 0:6bc4ac881c8e 135 // Wait the START condition has been correctly sent
ebrus 0:6bc4ac881c8e 136 timeout = FLAG_TIMEOUT;
ebrus 0:6bc4ac881c8e 137 while (I2C_GetFlagStatus(i2c, I2C_FLAG_SB) == RESET) {
ebrus 0:6bc4ac881c8e 138 timeout--;
ebrus 0:6bc4ac881c8e 139 if (timeout == 0) {
ebrus 0:6bc4ac881c8e 140 return 1;
ebrus 0:6bc4ac881c8e 141 }
ebrus 0:6bc4ac881c8e 142 }
ebrus 0:6bc4ac881c8e 143
ebrus 0:6bc4ac881c8e 144 return 0;
ebrus 0:6bc4ac881c8e 145 }
ebrus 0:6bc4ac881c8e 146
ebrus 0:6bc4ac881c8e 147 inline int i2c_stop(i2c_t *obj) {
ebrus 0:6bc4ac881c8e 148 I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
ebrus 0:6bc4ac881c8e 149
ebrus 0:6bc4ac881c8e 150 I2C_GenerateSTOP(i2c, ENABLE);
ebrus 0:6bc4ac881c8e 151
ebrus 0:6bc4ac881c8e 152 return 0;
ebrus 0:6bc4ac881c8e 153 }
ebrus 0:6bc4ac881c8e 154
ebrus 0:6bc4ac881c8e 155 int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
ebrus 0:6bc4ac881c8e 156 I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
ebrus 0:6bc4ac881c8e 157 int timeout;
ebrus 0:6bc4ac881c8e 158 int count;
ebrus 0:6bc4ac881c8e 159 int value;
ebrus 0:6bc4ac881c8e 160
ebrus 0:6bc4ac881c8e 161 i2c_start(obj);
ebrus 0:6bc4ac881c8e 162
ebrus 0:6bc4ac881c8e 163 // Send slave address for read
ebrus 0:6bc4ac881c8e 164 I2C_Send7bitAddress(i2c, address, I2C_Direction_Receiver);
ebrus 0:6bc4ac881c8e 165
ebrus 0:6bc4ac881c8e 166 // Wait address is acknowledged
ebrus 0:6bc4ac881c8e 167 timeout = FLAG_TIMEOUT;
ebrus 0:6bc4ac881c8e 168 while (I2C_CheckEvent(i2c, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED) == ERROR) {
ebrus 0:6bc4ac881c8e 169 timeout--;
ebrus 0:6bc4ac881c8e 170 if (timeout == 0) {
ebrus 0:6bc4ac881c8e 171 return -1;
ebrus 0:6bc4ac881c8e 172 }
ebrus 0:6bc4ac881c8e 173 }
ebrus 0:6bc4ac881c8e 174
ebrus 0:6bc4ac881c8e 175 // Read all bytes except last one
ebrus 0:6bc4ac881c8e 176 for (count = 0; count < (length - 1); count++) {
ebrus 0:6bc4ac881c8e 177 value = i2c_byte_read(obj, 0);
ebrus 0:6bc4ac881c8e 178 data[count] = (char)value;
ebrus 0:6bc4ac881c8e 179 }
ebrus 0:6bc4ac881c8e 180
ebrus 0:6bc4ac881c8e 181 // If not repeated start, send stop.
ebrus 0:6bc4ac881c8e 182 // Warning: must be done BEFORE the data is read.
ebrus 0:6bc4ac881c8e 183 if (stop) {
ebrus 0:6bc4ac881c8e 184 i2c_stop(obj);
ebrus 0:6bc4ac881c8e 185 }
ebrus 0:6bc4ac881c8e 186
ebrus 0:6bc4ac881c8e 187 // Read the last byte
ebrus 0:6bc4ac881c8e 188 value = i2c_byte_read(obj, 1);
ebrus 0:6bc4ac881c8e 189 data[count] = (char)value;
ebrus 0:6bc4ac881c8e 190
ebrus 0:6bc4ac881c8e 191 return length;
ebrus 0:6bc4ac881c8e 192 }
ebrus 0:6bc4ac881c8e 193
ebrus 0:6bc4ac881c8e 194 int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) {
ebrus 0:6bc4ac881c8e 195 I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
ebrus 0:6bc4ac881c8e 196 int timeout;
ebrus 0:6bc4ac881c8e 197 int count;
ebrus 0:6bc4ac881c8e 198
ebrus 0:6bc4ac881c8e 199 i2c_start(obj);
ebrus 0:6bc4ac881c8e 200
ebrus 0:6bc4ac881c8e 201 // Send slave address for write
ebrus 0:6bc4ac881c8e 202 I2C_Send7bitAddress(i2c, address, I2C_Direction_Transmitter);
ebrus 0:6bc4ac881c8e 203
ebrus 0:6bc4ac881c8e 204 // Wait address is acknowledged
ebrus 0:6bc4ac881c8e 205 timeout = FLAG_TIMEOUT;
ebrus 0:6bc4ac881c8e 206 while (I2C_CheckEvent(i2c, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) == ERROR) {
ebrus 0:6bc4ac881c8e 207 timeout--;
ebrus 0:6bc4ac881c8e 208 if (timeout == 0) {
ebrus 0:6bc4ac881c8e 209 return -1;
ebrus 0:6bc4ac881c8e 210 }
ebrus 0:6bc4ac881c8e 211 }
ebrus 0:6bc4ac881c8e 212
ebrus 0:6bc4ac881c8e 213 for (count = 0; count < length; count++) {
ebrus 0:6bc4ac881c8e 214 if (i2c_byte_write(obj, data[count]) != 1) {
ebrus 0:6bc4ac881c8e 215 i2c_stop(obj);
ebrus 0:6bc4ac881c8e 216 return 0;
ebrus 0:6bc4ac881c8e 217 }
ebrus 0:6bc4ac881c8e 218 }
ebrus 0:6bc4ac881c8e 219
ebrus 0:6bc4ac881c8e 220 // If not repeated start, send stop.
ebrus 0:6bc4ac881c8e 221 if (stop) {
ebrus 0:6bc4ac881c8e 222 i2c_stop(obj);
ebrus 0:6bc4ac881c8e 223 }
ebrus 0:6bc4ac881c8e 224
ebrus 0:6bc4ac881c8e 225 return count;
ebrus 0:6bc4ac881c8e 226 }
ebrus 0:6bc4ac881c8e 227
ebrus 0:6bc4ac881c8e 228 int i2c_byte_read(i2c_t *obj, int last) {
ebrus 0:6bc4ac881c8e 229 I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
ebrus 0:6bc4ac881c8e 230 uint8_t data;
ebrus 0:6bc4ac881c8e 231 int timeout;
ebrus 0:6bc4ac881c8e 232
ebrus 0:6bc4ac881c8e 233 if (last) {
ebrus 0:6bc4ac881c8e 234 // Don't acknowledge the last byte
ebrus 0:6bc4ac881c8e 235 I2C_AcknowledgeConfig(i2c, DISABLE);
ebrus 0:6bc4ac881c8e 236 } else {
ebrus 0:6bc4ac881c8e 237 // Acknowledge the byte
ebrus 0:6bc4ac881c8e 238 I2C_AcknowledgeConfig(i2c, ENABLE);
ebrus 0:6bc4ac881c8e 239 }
ebrus 0:6bc4ac881c8e 240
ebrus 0:6bc4ac881c8e 241 // Wait until the byte is received
ebrus 0:6bc4ac881c8e 242 timeout = FLAG_TIMEOUT;
ebrus 0:6bc4ac881c8e 243 while (I2C_GetFlagStatus(i2c, I2C_FLAG_RXNE) == RESET) {
ebrus 0:6bc4ac881c8e 244 timeout--;
ebrus 0:6bc4ac881c8e 245 if (timeout == 0) {
ebrus 0:6bc4ac881c8e 246 return -1;
ebrus 0:6bc4ac881c8e 247 }
ebrus 0:6bc4ac881c8e 248 }
ebrus 0:6bc4ac881c8e 249
ebrus 0:6bc4ac881c8e 250 data = I2C_ReceiveData(i2c);
ebrus 0:6bc4ac881c8e 251
ebrus 0:6bc4ac881c8e 252 return (int)data;
ebrus 0:6bc4ac881c8e 253 }
ebrus 0:6bc4ac881c8e 254
ebrus 0:6bc4ac881c8e 255 int i2c_byte_write(i2c_t *obj, int data) {
ebrus 0:6bc4ac881c8e 256 I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
ebrus 0:6bc4ac881c8e 257 int timeout;
ebrus 0:6bc4ac881c8e 258
ebrus 0:6bc4ac881c8e 259 I2C_SendData(i2c, (uint8_t)data);
ebrus 0:6bc4ac881c8e 260
ebrus 0:6bc4ac881c8e 261 // Wait until the byte is transmitted
ebrus 0:6bc4ac881c8e 262 timeout = FLAG_TIMEOUT;
ebrus 0:6bc4ac881c8e 263 while ((I2C_GetFlagStatus(i2c, I2C_FLAG_TXE) == RESET) &&
ebrus 0:6bc4ac881c8e 264 (I2C_GetFlagStatus(i2c, I2C_FLAG_BTF) == RESET)) {
ebrus 0:6bc4ac881c8e 265 timeout--;
ebrus 0:6bc4ac881c8e 266 if (timeout == 0) {
ebrus 0:6bc4ac881c8e 267 return 0;
ebrus 0:6bc4ac881c8e 268 }
ebrus 0:6bc4ac881c8e 269 }
ebrus 0:6bc4ac881c8e 270
ebrus 0:6bc4ac881c8e 271 return 1;
ebrus 0:6bc4ac881c8e 272 }
ebrus 0:6bc4ac881c8e 273
ebrus 0:6bc4ac881c8e 274 void i2c_reset(i2c_t *obj) {
ebrus 0:6bc4ac881c8e 275 I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
ebrus 0:6bc4ac881c8e 276 int timeout;
ebrus 0:6bc4ac881c8e 277
ebrus 0:6bc4ac881c8e 278 // wait before reset
ebrus 0:6bc4ac881c8e 279 timeout = LONG_TIMEOUT;
ebrus 0:6bc4ac881c8e 280 while((I2C_GetFlagStatus(i2c, I2C_FLAG_BUSY)) && (timeout-- != 0));
ebrus 0:6bc4ac881c8e 281
ebrus 0:6bc4ac881c8e 282 if (obj->i2c == I2C_1) {
ebrus 0:6bc4ac881c8e 283 RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, ENABLE);
ebrus 0:6bc4ac881c8e 284 RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, DISABLE);
ebrus 0:6bc4ac881c8e 285 }
ebrus 0:6bc4ac881c8e 286 if (obj->i2c == I2C_2) {
ebrus 0:6bc4ac881c8e 287 RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C2, ENABLE);
ebrus 0:6bc4ac881c8e 288 RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C2, DISABLE);
ebrus 0:6bc4ac881c8e 289 }
ebrus 0:6bc4ac881c8e 290 }
ebrus 0:6bc4ac881c8e 291
ebrus 0:6bc4ac881c8e 292 #if DEVICE_I2CSLAVE
ebrus 0:6bc4ac881c8e 293
ebrus 0:6bc4ac881c8e 294 void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask) {
ebrus 0:6bc4ac881c8e 295 I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
ebrus 0:6bc4ac881c8e 296 uint16_t tmpreg;
ebrus 0:6bc4ac881c8e 297
ebrus 0:6bc4ac881c8e 298 // Get the old register value
ebrus 0:6bc4ac881c8e 299 tmpreg = i2c->OAR1;
ebrus 0:6bc4ac881c8e 300 // Reset address bits
ebrus 0:6bc4ac881c8e 301 tmpreg &= 0xFC00;
ebrus 0:6bc4ac881c8e 302 // Set new address
ebrus 0:6bc4ac881c8e 303 tmpreg |= (uint16_t)((uint16_t)address & (uint16_t)0x00FE); // 7-bits
ebrus 0:6bc4ac881c8e 304 // Store the new register value
ebrus 0:6bc4ac881c8e 305 i2c->OAR1 = tmpreg;
ebrus 0:6bc4ac881c8e 306 }
ebrus 0:6bc4ac881c8e 307
ebrus 0:6bc4ac881c8e 308 void i2c_slave_mode(i2c_t *obj, int enable_slave) {
ebrus 0:6bc4ac881c8e 309 // Nothing to do
ebrus 0:6bc4ac881c8e 310 }
ebrus 0:6bc4ac881c8e 311
ebrus 0:6bc4ac881c8e 312 // See I2CSlave.h
ebrus 0:6bc4ac881c8e 313 #define NoData 0 // the slave has not been addressed
ebrus 0:6bc4ac881c8e 314 #define ReadAddressed 1 // the master has requested a read from this slave (slave = transmitter)
ebrus 0:6bc4ac881c8e 315 #define WriteGeneral 2 // the master is writing to all slave
ebrus 0:6bc4ac881c8e 316 #define WriteAddressed 3 // the master is writing to this slave (slave = receiver)
ebrus 0:6bc4ac881c8e 317
ebrus 0:6bc4ac881c8e 318 int i2c_slave_receive(i2c_t *obj) {
ebrus 0:6bc4ac881c8e 319 int retValue = NoData;
ebrus 0:6bc4ac881c8e 320 uint32_t event;
ebrus 0:6bc4ac881c8e 321 I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
ebrus 0:6bc4ac881c8e 322
ebrus 0:6bc4ac881c8e 323 event = I2C_GetLastEvent(i2c);
ebrus 0:6bc4ac881c8e 324 if (event != 0) {
ebrus 0:6bc4ac881c8e 325 switch (event) {
ebrus 0:6bc4ac881c8e 326 case I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED:
ebrus 0:6bc4ac881c8e 327 retValue = WriteAddressed;
ebrus 0:6bc4ac881c8e 328 break;
ebrus 0:6bc4ac881c8e 329 case I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED:
ebrus 0:6bc4ac881c8e 330 retValue = ReadAddressed;
ebrus 0:6bc4ac881c8e 331 break;
ebrus 0:6bc4ac881c8e 332 case I2C_EVENT_SLAVE_GENERALCALLADDRESS_MATCHED:
ebrus 0:6bc4ac881c8e 333 retValue = WriteGeneral;
ebrus 0:6bc4ac881c8e 334 break;
ebrus 0:6bc4ac881c8e 335 default:
ebrus 0:6bc4ac881c8e 336 retValue = NoData;
ebrus 0:6bc4ac881c8e 337 break;
ebrus 0:6bc4ac881c8e 338 }
ebrus 0:6bc4ac881c8e 339
ebrus 0:6bc4ac881c8e 340 // clear ADDR
ebrus 0:6bc4ac881c8e 341 if ((retValue == WriteAddressed) || (retValue == ReadAddressed)) {
ebrus 0:6bc4ac881c8e 342 // read SR to clear ADDR flag
ebrus 0:6bc4ac881c8e 343 i2c->SR1;
ebrus 0:6bc4ac881c8e 344 i2c->SR2;
ebrus 0:6bc4ac881c8e 345 }
ebrus 0:6bc4ac881c8e 346 // clear stopf
ebrus 0:6bc4ac881c8e 347 if (I2C_GetFlagStatus(i2c, I2C_FLAG_STOPF) == SET) {
ebrus 0:6bc4ac881c8e 348 // read SR1 and write CR1 to clear STOP flag
ebrus 0:6bc4ac881c8e 349 i2c->SR1;
ebrus 0:6bc4ac881c8e 350 I2C_Cmd(i2c, ENABLE);
ebrus 0:6bc4ac881c8e 351 }
ebrus 0:6bc4ac881c8e 352 // clear AF
ebrus 0:6bc4ac881c8e 353 if (I2C_GetFlagStatus(i2c, I2C_FLAG_AF) == SET) {
ebrus 0:6bc4ac881c8e 354 I2C_ClearFlag(i2c, I2C_FLAG_AF);
ebrus 0:6bc4ac881c8e 355 }
ebrus 0:6bc4ac881c8e 356 }
ebrus 0:6bc4ac881c8e 357 return (retValue);
ebrus 0:6bc4ac881c8e 358 }
ebrus 0:6bc4ac881c8e 359
ebrus 0:6bc4ac881c8e 360 int i2c_slave_read(i2c_t *obj, char *data, int length) {
ebrus 0:6bc4ac881c8e 361 int count = 0;
ebrus 0:6bc4ac881c8e 362
ebrus 0:6bc4ac881c8e 363 // Read all bytes
ebrus 0:6bc4ac881c8e 364 for (count = 0; count < length; count++) {
ebrus 0:6bc4ac881c8e 365 data[count] = i2c_byte_read(obj, 0);
ebrus 0:6bc4ac881c8e 366 }
ebrus 0:6bc4ac881c8e 367
ebrus 0:6bc4ac881c8e 368 return count;
ebrus 0:6bc4ac881c8e 369 }
ebrus 0:6bc4ac881c8e 370
ebrus 0:6bc4ac881c8e 371 int i2c_slave_write(i2c_t *obj, const char *data, int length) {
ebrus 0:6bc4ac881c8e 372 int count = 0;
ebrus 0:6bc4ac881c8e 373
ebrus 0:6bc4ac881c8e 374 // Write all bytes
ebrus 0:6bc4ac881c8e 375 for (count = 0; count < length; count++) {
ebrus 0:6bc4ac881c8e 376 i2c_byte_write(obj, data[count]);
ebrus 0:6bc4ac881c8e 377 }
ebrus 0:6bc4ac881c8e 378
ebrus 0:6bc4ac881c8e 379 return count;
ebrus 0:6bc4ac881c8e 380 }
ebrus 0:6bc4ac881c8e 381
ebrus 0:6bc4ac881c8e 382
ebrus 0:6bc4ac881c8e 383 #endif // DEVICE_I2CSLAVE
ebrus 0:6bc4ac881c8e 384
ebrus 0:6bc4ac881c8e 385 #endif // DEVICE_I2C