mbed library sources. Supersedes mbed-src. Fixed broken STM32F1xx RTC on rtc_api.c

Dependents:   Nucleo_F103RB_RTC_battery_bkup_pwr_off_okay

Fork of mbed-dev by mbed official

Committer:
maxxir
Date:
Tue Nov 07 16:46:29 2017 +0000
Revision:
177:619788de047e
Parent:
172:7d866c31b3c5
To fix broken RTC on Nucleo_F103RB / STM32F103 BluePill etc..;  Used direct RTC register manipulation for STM32F1xx;  rtc_read() && rtc_write()  (native rtc_init() - works good);  also added stub for non-working on STM32F1xx rtc_read_subseconds().

Who changed what in which revision?

UserRevisionLine numberNew contents of line
AnnaBridge 172:7d866c31b3c5 1 /* mbed Microcontroller Library
AnnaBridge 172:7d866c31b3c5 2 * (C)Copyright TOSHIBA ELECTRONIC DEVICES & STORAGE CORPORATION 2017 All rights reserved
AnnaBridge 172:7d866c31b3c5 3 *
AnnaBridge 172:7d866c31b3c5 4 * Licensed under the Apache License, Version 2.0 (the "License");
AnnaBridge 172:7d866c31b3c5 5 * you may not use this file except in compliance with the License.
AnnaBridge 172:7d866c31b3c5 6 * You may obtain a copy of the License at
AnnaBridge 172:7d866c31b3c5 7 *
AnnaBridge 172:7d866c31b3c5 8 * http://www.apache.org/licenses/LICENSE-2.0
AnnaBridge 172:7d866c31b3c5 9 *
AnnaBridge 172:7d866c31b3c5 10 * Unless required by applicable law or agreed to in writing, software
AnnaBridge 172:7d866c31b3c5 11 * distributed under the License is distributed on an "AS IS" BASIS,
AnnaBridge 172:7d866c31b3c5 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
AnnaBridge 172:7d866c31b3c5 13 * See the License for the specific language governing permissions and
AnnaBridge 172:7d866c31b3c5 14 * limitations under the License.
AnnaBridge 172:7d866c31b3c5 15 */
AnnaBridge 172:7d866c31b3c5 16 #include "i2c_api.h"
AnnaBridge 172:7d866c31b3c5 17 #include "mbed_error.h"
AnnaBridge 172:7d866c31b3c5 18 #include "PeripheralNames.h"
AnnaBridge 172:7d866c31b3c5 19 #include "pinmap.h"
AnnaBridge 172:7d866c31b3c5 20
AnnaBridge 172:7d866c31b3c5 21 #define I2C_NACK (0)
AnnaBridge 172:7d866c31b3c5 22 #define I2C_ACK (1)
AnnaBridge 172:7d866c31b3c5 23 #define I2C_NO_DATA (0)
AnnaBridge 172:7d866c31b3c5 24 #define I2C_READ_ADDRESSED (1)
AnnaBridge 172:7d866c31b3c5 25 #define I2C_WRITE_GENERAL (2)
AnnaBridge 172:7d866c31b3c5 26 #define I2C_WRITE_ADDRESSED (3)
AnnaBridge 172:7d866c31b3c5 27 #define SELF_ADDR (0xE0)
AnnaBridge 172:7d866c31b3c5 28 #define I2C_TIMEOUT (100000)
AnnaBridge 172:7d866c31b3c5 29
AnnaBridge 172:7d866c31b3c5 30 static const PinMap PinMap_I2C_SDA[] = {
AnnaBridge 172:7d866c31b3c5 31 {PC1, I2C_0, PIN_DATA(1, 2)},
AnnaBridge 172:7d866c31b3c5 32 {PG1, I2C_1, PIN_DATA(1, 2)},
AnnaBridge 172:7d866c31b3c5 33 {NC, NC, 0}
AnnaBridge 172:7d866c31b3c5 34 };
AnnaBridge 172:7d866c31b3c5 35
AnnaBridge 172:7d866c31b3c5 36 static const PinMap PinMap_I2C_SCL[] = {
AnnaBridge 172:7d866c31b3c5 37 {PC0, I2C_0, PIN_DATA(1, 2)},
AnnaBridge 172:7d866c31b3c5 38 {PG0, I2C_1, PIN_DATA(1, 2)},
AnnaBridge 172:7d866c31b3c5 39 {NC, NC, 0}
AnnaBridge 172:7d866c31b3c5 40 };
AnnaBridge 172:7d866c31b3c5 41
AnnaBridge 172:7d866c31b3c5 42 void I2C_ClearINTOutput(TSB_I2C_TypeDef * I2Cx);
AnnaBridge 172:7d866c31b3c5 43 // Clock setting structure definition
AnnaBridge 172:7d866c31b3c5 44 typedef struct {
AnnaBridge 172:7d866c31b3c5 45 uint32_t sck;
AnnaBridge 172:7d866c31b3c5 46 uint32_t prsck;
AnnaBridge 172:7d866c31b3c5 47 } I2C_clock_setting_t;
AnnaBridge 172:7d866c31b3c5 48
AnnaBridge 172:7d866c31b3c5 49 static const uint32_t I2C_SCK_DIVIDER_TBL[8] = {20, 24, 32, 48, 80, 144, 272, 528}; // SCK Divider value table
AnnaBridge 172:7d866c31b3c5 50 static uint32_t start_flag = 0;
AnnaBridge 172:7d866c31b3c5 51 I2C_clock_setting_t clk;
AnnaBridge 172:7d866c31b3c5 52 I2C_State status;
AnnaBridge 172:7d866c31b3c5 53
AnnaBridge 172:7d866c31b3c5 54 static int32_t wait_status(i2c_t *obj)
AnnaBridge 172:7d866c31b3c5 55 {
AnnaBridge 172:7d866c31b3c5 56 volatile int32_t timeout = I2C_TIMEOUT;
AnnaBridge 172:7d866c31b3c5 57
AnnaBridge 172:7d866c31b3c5 58 while (I2C_GetINTI2CStatus(obj->i2c) == DISABLE) {
AnnaBridge 172:7d866c31b3c5 59 if ((timeout--) == 0) {
AnnaBridge 172:7d866c31b3c5 60 return (-1);
AnnaBridge 172:7d866c31b3c5 61 }
AnnaBridge 172:7d866c31b3c5 62 }
AnnaBridge 172:7d866c31b3c5 63 return (0);
AnnaBridge 172:7d866c31b3c5 64 }
AnnaBridge 172:7d866c31b3c5 65
AnnaBridge 172:7d866c31b3c5 66 // Initialize the I2C peripheral. It sets the default parameters for I2C
AnnaBridge 172:7d866c31b3c5 67 void i2c_init(i2c_t *obj, PinName sda, PinName scl)
AnnaBridge 172:7d866c31b3c5 68 {
AnnaBridge 172:7d866c31b3c5 69 MBED_ASSERT(obj != NULL);
AnnaBridge 172:7d866c31b3c5 70 I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA);
AnnaBridge 172:7d866c31b3c5 71 I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL);
AnnaBridge 172:7d866c31b3c5 72 I2CName i2c_name = (I2CName)pinmap_merge(i2c_sda, i2c_scl);
AnnaBridge 172:7d866c31b3c5 73 MBED_ASSERT((int)i2c_name != NC);
AnnaBridge 172:7d866c31b3c5 74
AnnaBridge 172:7d866c31b3c5 75 switch (i2c_name) {
AnnaBridge 172:7d866c31b3c5 76 case I2C_0:
AnnaBridge 172:7d866c31b3c5 77 CG_SetFcPeriphA(CG_FC_PERIPH_I2C0, ENABLE);
AnnaBridge 172:7d866c31b3c5 78 obj->i2c = TSB_I2C0;
AnnaBridge 172:7d866c31b3c5 79 obj->IRQn = INTI2C0_IRQn;
AnnaBridge 172:7d866c31b3c5 80 break;
AnnaBridge 172:7d866c31b3c5 81 case I2C_1:
AnnaBridge 172:7d866c31b3c5 82 CG_SetFcPeriphB(CG_FC_PERIPH_I2C1, ENABLE);
AnnaBridge 172:7d866c31b3c5 83 obj->i2c = TSB_I2C1;
AnnaBridge 172:7d866c31b3c5 84 obj->IRQn = INTI2C1_IRQn;
AnnaBridge 172:7d866c31b3c5 85 break;
AnnaBridge 172:7d866c31b3c5 86 default:
AnnaBridge 172:7d866c31b3c5 87 error("I2C is not available");
AnnaBridge 172:7d866c31b3c5 88 break;
AnnaBridge 172:7d866c31b3c5 89 }
AnnaBridge 172:7d866c31b3c5 90
AnnaBridge 172:7d866c31b3c5 91 pinmap_pinout(sda, PinMap_I2C_SDA);
AnnaBridge 172:7d866c31b3c5 92 pin_mode(sda, OpenDrain);
AnnaBridge 172:7d866c31b3c5 93 pin_mode(sda, PullUp);
AnnaBridge 172:7d866c31b3c5 94
AnnaBridge 172:7d866c31b3c5 95 pinmap_pinout(scl, PinMap_I2C_SCL);
AnnaBridge 172:7d866c31b3c5 96 pin_mode(scl, OpenDrain);
AnnaBridge 172:7d866c31b3c5 97 pin_mode(scl, PullUp);
AnnaBridge 172:7d866c31b3c5 98
AnnaBridge 172:7d866c31b3c5 99 NVIC_DisableIRQ(obj->IRQn);
AnnaBridge 172:7d866c31b3c5 100
AnnaBridge 172:7d866c31b3c5 101 i2c_reset(obj);
AnnaBridge 172:7d866c31b3c5 102 i2c_frequency(obj, 100000);
AnnaBridge 172:7d866c31b3c5 103 }
AnnaBridge 172:7d866c31b3c5 104
AnnaBridge 172:7d866c31b3c5 105 // Configure the I2C frequency
AnnaBridge 172:7d866c31b3c5 106 void i2c_frequency(i2c_t *obj, int hz)
AnnaBridge 172:7d866c31b3c5 107 {
AnnaBridge 172:7d866c31b3c5 108 uint64_t sck, tmp_sck;
AnnaBridge 172:7d866c31b3c5 109 uint64_t prsck, tmp_prsck;
AnnaBridge 172:7d866c31b3c5 110 uint64_t fscl, tmp_fscl;
AnnaBridge 172:7d866c31b3c5 111 uint64_t fx;
AnnaBridge 172:7d866c31b3c5 112
AnnaBridge 172:7d866c31b3c5 113 SystemCoreClockUpdate();
AnnaBridge 172:7d866c31b3c5 114
AnnaBridge 172:7d866c31b3c5 115 if (hz <= 1000000) {
AnnaBridge 172:7d866c31b3c5 116 sck = tmp_sck = 0;
AnnaBridge 172:7d866c31b3c5 117 prsck = tmp_prsck = 1;
AnnaBridge 172:7d866c31b3c5 118 fscl = tmp_fscl = 0;
AnnaBridge 172:7d866c31b3c5 119 for (prsck = 1; prsck <= 32; prsck++) {
AnnaBridge 172:7d866c31b3c5 120 fx = ((uint64_t)SystemCoreClock / prsck);
AnnaBridge 172:7d866c31b3c5 121 if ((fx < 40000000U) && (fx > 6666666U)) {
AnnaBridge 172:7d866c31b3c5 122 for (sck = 0; sck <= 7; sck++) {
AnnaBridge 172:7d866c31b3c5 123 fscl = (fx / (uint64_t)I2C_SCK_DIVIDER_TBL[sck]);
AnnaBridge 172:7d866c31b3c5 124 if ((fscl <= (uint64_t)hz) && (fscl > tmp_fscl)) {
AnnaBridge 172:7d866c31b3c5 125 tmp_fscl = fscl;
AnnaBridge 172:7d866c31b3c5 126 tmp_sck = sck;
AnnaBridge 172:7d866c31b3c5 127 tmp_prsck = (prsck < 32)? prsck: 0;
AnnaBridge 172:7d866c31b3c5 128 }
AnnaBridge 172:7d866c31b3c5 129 }
AnnaBridge 172:7d866c31b3c5 130 }
AnnaBridge 172:7d866c31b3c5 131 }
AnnaBridge 172:7d866c31b3c5 132 clk.sck = (uint32_t)tmp_sck;
AnnaBridge 172:7d866c31b3c5 133 clk.prsck = (tmp_prsck < 32) ? (uint32_t)(tmp_prsck) : 0;
AnnaBridge 172:7d866c31b3c5 134 }
AnnaBridge 172:7d866c31b3c5 135 obj->myi2c.I2CSelfAddr = SELF_ADDR;
AnnaBridge 172:7d866c31b3c5 136 obj->myi2c.I2CDataLen = I2C_DATA_LEN_8;
AnnaBridge 172:7d866c31b3c5 137 obj->myi2c.I2CACKState = ENABLE;
AnnaBridge 172:7d866c31b3c5 138 obj->myi2c.I2CClkDiv = clk.sck;
AnnaBridge 172:7d866c31b3c5 139 obj->myi2c.PrescalerClkDiv = clk.prsck;
AnnaBridge 172:7d866c31b3c5 140
AnnaBridge 172:7d866c31b3c5 141 I2C_Init(obj->i2c, &obj->myi2c);
AnnaBridge 172:7d866c31b3c5 142 NVIC_DisableIRQ(obj->IRQn);
AnnaBridge 172:7d866c31b3c5 143 }
AnnaBridge 172:7d866c31b3c5 144
AnnaBridge 172:7d866c31b3c5 145 int i2c_start(i2c_t *obj)
AnnaBridge 172:7d866c31b3c5 146 {
AnnaBridge 172:7d866c31b3c5 147 start_flag = 1;
AnnaBridge 172:7d866c31b3c5 148 return 0;
AnnaBridge 172:7d866c31b3c5 149 }
AnnaBridge 172:7d866c31b3c5 150
AnnaBridge 172:7d866c31b3c5 151 int i2c_stop(i2c_t *obj)
AnnaBridge 172:7d866c31b3c5 152 {
AnnaBridge 172:7d866c31b3c5 153 I2C_GenerateStop(obj->i2c);
AnnaBridge 172:7d866c31b3c5 154 return 0;
AnnaBridge 172:7d866c31b3c5 155 }
AnnaBridge 172:7d866c31b3c5 156
AnnaBridge 172:7d866c31b3c5 157 void i2c_reset(i2c_t *obj)
AnnaBridge 172:7d866c31b3c5 158 {
AnnaBridge 172:7d866c31b3c5 159 I2C_SWReset(obj->i2c);
AnnaBridge 172:7d866c31b3c5 160 }
AnnaBridge 172:7d866c31b3c5 161
AnnaBridge 172:7d866c31b3c5 162 int i2c_read(i2c_t *obj, int address, char *data, int length, int stop)
AnnaBridge 172:7d866c31b3c5 163 {
AnnaBridge 172:7d866c31b3c5 164 int32_t result = 0;
AnnaBridge 172:7d866c31b3c5 165 int32_t count = 0;
AnnaBridge 172:7d866c31b3c5 166
AnnaBridge 172:7d866c31b3c5 167 if (length > 0) {
AnnaBridge 172:7d866c31b3c5 168 start_flag = 1; // Start Condition
AnnaBridge 172:7d866c31b3c5 169 if (i2c_byte_write(obj, (int32_t)((uint32_t)address | 1U)) == I2C_ACK) {
AnnaBridge 172:7d866c31b3c5 170 while (count < length) {
AnnaBridge 172:7d866c31b3c5 171 int32_t pdata = i2c_byte_read(obj, ((count < (length - 1)) ? 0 : 1));
AnnaBridge 172:7d866c31b3c5 172 if (pdata < 0) {
AnnaBridge 172:7d866c31b3c5 173 break;
AnnaBridge 172:7d866c31b3c5 174 }
AnnaBridge 172:7d866c31b3c5 175 data[count++] = (uint8_t)pdata;
AnnaBridge 172:7d866c31b3c5 176 }
AnnaBridge 172:7d866c31b3c5 177 result = count;
AnnaBridge 172:7d866c31b3c5 178 } else {
AnnaBridge 172:7d866c31b3c5 179 stop = 1;
AnnaBridge 172:7d866c31b3c5 180 result = I2C_ERROR_NO_SLAVE;
AnnaBridge 172:7d866c31b3c5 181 }
AnnaBridge 172:7d866c31b3c5 182
AnnaBridge 172:7d866c31b3c5 183 if (stop) { // Stop Condition
AnnaBridge 172:7d866c31b3c5 184 i2c_stop(obj);
AnnaBridge 172:7d866c31b3c5 185 }
AnnaBridge 172:7d866c31b3c5 186 }
AnnaBridge 172:7d866c31b3c5 187 return (result);
AnnaBridge 172:7d866c31b3c5 188 }
AnnaBridge 172:7d866c31b3c5 189
AnnaBridge 172:7d866c31b3c5 190 int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) // Blocking sending data
AnnaBridge 172:7d866c31b3c5 191 {
AnnaBridge 172:7d866c31b3c5 192 int32_t result = 0;
AnnaBridge 172:7d866c31b3c5 193 int32_t count = 0;
AnnaBridge 172:7d866c31b3c5 194
AnnaBridge 172:7d866c31b3c5 195 start_flag = 1; // Start Condition
AnnaBridge 172:7d866c31b3c5 196 if (i2c_byte_write(obj, address) == I2C_ACK) {
AnnaBridge 172:7d866c31b3c5 197 while (count < length) {
AnnaBridge 172:7d866c31b3c5 198 if (i2c_byte_write(obj, (int32_t)data[count++]) < I2C_ACK) {
AnnaBridge 172:7d866c31b3c5 199 break;
AnnaBridge 172:7d866c31b3c5 200 }
AnnaBridge 172:7d866c31b3c5 201 }
AnnaBridge 172:7d866c31b3c5 202 result = count;
AnnaBridge 172:7d866c31b3c5 203 } else {
AnnaBridge 172:7d866c31b3c5 204 stop = 1;
AnnaBridge 172:7d866c31b3c5 205 result = I2C_ERROR_NO_SLAVE;
AnnaBridge 172:7d866c31b3c5 206 }
AnnaBridge 172:7d866c31b3c5 207
AnnaBridge 172:7d866c31b3c5 208 if (stop) { // Stop Condition
AnnaBridge 172:7d866c31b3c5 209 i2c_stop(obj);
AnnaBridge 172:7d866c31b3c5 210 }
AnnaBridge 172:7d866c31b3c5 211 return (result);
AnnaBridge 172:7d866c31b3c5 212 }
AnnaBridge 172:7d866c31b3c5 213
AnnaBridge 172:7d866c31b3c5 214 int i2c_byte_read(i2c_t *obj, int last)
AnnaBridge 172:7d866c31b3c5 215 {
AnnaBridge 172:7d866c31b3c5 216 int32_t result;
AnnaBridge 172:7d866c31b3c5 217
AnnaBridge 172:7d866c31b3c5 218 I2C_ClearINTOutput(obj->i2c);
AnnaBridge 172:7d866c31b3c5 219
AnnaBridge 172:7d866c31b3c5 220 if (last) {
AnnaBridge 172:7d866c31b3c5 221 I2C_SelectACKoutput(obj->i2c, ENABLE);
AnnaBridge 172:7d866c31b3c5 222 } else {
AnnaBridge 172:7d866c31b3c5 223 I2C_SelectACKoutput(obj->i2c, DISABLE);
AnnaBridge 172:7d866c31b3c5 224 }
AnnaBridge 172:7d866c31b3c5 225 I2C_SetSendData(obj->i2c, 0x00);
AnnaBridge 172:7d866c31b3c5 226
AnnaBridge 172:7d866c31b3c5 227 if (wait_status(obj) < 0) {
AnnaBridge 172:7d866c31b3c5 228 result = -1;
AnnaBridge 172:7d866c31b3c5 229 } else {
AnnaBridge 172:7d866c31b3c5 230 result = (int32_t)I2C_GetReceiveData(obj->i2c);
AnnaBridge 172:7d866c31b3c5 231 }
AnnaBridge 172:7d866c31b3c5 232 return (result);
AnnaBridge 172:7d866c31b3c5 233 }
AnnaBridge 172:7d866c31b3c5 234
AnnaBridge 172:7d866c31b3c5 235 void I2C_Start_Condition(i2c_t *p_obj, uint32_t data)
AnnaBridge 172:7d866c31b3c5 236 {
AnnaBridge 172:7d866c31b3c5 237 status = I2C_GetState(p_obj->i2c);
AnnaBridge 172:7d866c31b3c5 238 if (status.Bit.BusState) {
AnnaBridge 172:7d866c31b3c5 239 I2C_SetRepeatStart(p_obj->i2c, ENABLE);
AnnaBridge 172:7d866c31b3c5 240 }
AnnaBridge 172:7d866c31b3c5 241 I2C_SetSendData(p_obj->i2c, (uint32_t)data);
AnnaBridge 172:7d866c31b3c5 242 I2C_GenerateStart(p_obj->i2c);
AnnaBridge 172:7d866c31b3c5 243 }
AnnaBridge 172:7d866c31b3c5 244
AnnaBridge 172:7d866c31b3c5 245 int i2c_byte_write(i2c_t *obj, int data)
AnnaBridge 172:7d866c31b3c5 246 {
AnnaBridge 172:7d866c31b3c5 247 int32_t result;
AnnaBridge 172:7d866c31b3c5 248
AnnaBridge 172:7d866c31b3c5 249 I2C_ClearINTOutput(obj->i2c);
AnnaBridge 172:7d866c31b3c5 250
AnnaBridge 172:7d866c31b3c5 251 if (start_flag == 1) {
AnnaBridge 172:7d866c31b3c5 252 I2C_Start_Condition(obj, (uint32_t)data);
AnnaBridge 172:7d866c31b3c5 253 start_flag = 0;
AnnaBridge 172:7d866c31b3c5 254 } else {
AnnaBridge 172:7d866c31b3c5 255 I2C_SetSendData(obj->i2c, (uint32_t)data);
AnnaBridge 172:7d866c31b3c5 256 }
AnnaBridge 172:7d866c31b3c5 257
AnnaBridge 172:7d866c31b3c5 258 if (wait_status(obj) < 0) {
AnnaBridge 172:7d866c31b3c5 259 return (-1);
AnnaBridge 172:7d866c31b3c5 260 }
AnnaBridge 172:7d866c31b3c5 261
AnnaBridge 172:7d866c31b3c5 262 status = I2C_GetState(obj->i2c);
AnnaBridge 172:7d866c31b3c5 263 if (!status.Bit.LastRxBit) {
AnnaBridge 172:7d866c31b3c5 264 result = 1;
AnnaBridge 172:7d866c31b3c5 265 } else {
AnnaBridge 172:7d866c31b3c5 266 result = 0;
AnnaBridge 172:7d866c31b3c5 267 }
AnnaBridge 172:7d866c31b3c5 268 return (result);
AnnaBridge 172:7d866c31b3c5 269 }
AnnaBridge 172:7d866c31b3c5 270
AnnaBridge 172:7d866c31b3c5 271 void i2c_slave_mode(i2c_t *obj, int enable_slave)
AnnaBridge 172:7d866c31b3c5 272 {
AnnaBridge 172:7d866c31b3c5 273 i2c_reset(obj);
AnnaBridge 172:7d866c31b3c5 274
AnnaBridge 172:7d866c31b3c5 275 obj->myi2c.I2CDataLen = I2C_DATA_LEN_8;
AnnaBridge 172:7d866c31b3c5 276 obj->myi2c.I2CACKState = ENABLE;
AnnaBridge 172:7d866c31b3c5 277 obj->myi2c.I2CClkDiv = clk.sck;
AnnaBridge 172:7d866c31b3c5 278 obj->myi2c.PrescalerClkDiv = clk.prsck;
AnnaBridge 172:7d866c31b3c5 279
AnnaBridge 172:7d866c31b3c5 280 if (enable_slave) {
AnnaBridge 172:7d866c31b3c5 281 obj->myi2c.I2CSelfAddr = obj->address;
AnnaBridge 172:7d866c31b3c5 282 I2C_SetINTI2CReq(obj->i2c, ENABLE);
AnnaBridge 172:7d866c31b3c5 283 } else {
AnnaBridge 172:7d866c31b3c5 284 obj->myi2c.I2CSelfAddr = SELF_ADDR;
AnnaBridge 172:7d866c31b3c5 285 NVIC_DisableIRQ(obj->IRQn);
AnnaBridge 172:7d866c31b3c5 286 I2C_ClearINTOutput(obj->i2c);
AnnaBridge 172:7d866c31b3c5 287 }
AnnaBridge 172:7d866c31b3c5 288 I2C_Init(obj->i2c, &obj->myi2c);
AnnaBridge 172:7d866c31b3c5 289 }
AnnaBridge 172:7d866c31b3c5 290
AnnaBridge 172:7d866c31b3c5 291 int i2c_slave_receive(i2c_t *obj)
AnnaBridge 172:7d866c31b3c5 292 {
AnnaBridge 172:7d866c31b3c5 293 int32_t result = I2C_NO_DATA;
AnnaBridge 172:7d866c31b3c5 294
AnnaBridge 172:7d866c31b3c5 295 if ((I2C_GetINTI2CStatus(obj->i2c)) && (I2C_GetSlaveAddrMatchState(obj->i2c))) {
AnnaBridge 172:7d866c31b3c5 296 status = I2C_GetState(obj->i2c);
AnnaBridge 172:7d866c31b3c5 297 if (!status.Bit.TRx) {
AnnaBridge 172:7d866c31b3c5 298 result = I2C_WRITE_ADDRESSED;
AnnaBridge 172:7d866c31b3c5 299 } else {
AnnaBridge 172:7d866c31b3c5 300 result = I2C_READ_ADDRESSED;
AnnaBridge 172:7d866c31b3c5 301 }
AnnaBridge 172:7d866c31b3c5 302 }
AnnaBridge 172:7d866c31b3c5 303 return (result);
AnnaBridge 172:7d866c31b3c5 304 }
AnnaBridge 172:7d866c31b3c5 305
AnnaBridge 172:7d866c31b3c5 306 int i2c_slave_read(i2c_t *obj, char *data, int length)
AnnaBridge 172:7d866c31b3c5 307 {
AnnaBridge 172:7d866c31b3c5 308 int32_t count = 0;
AnnaBridge 172:7d866c31b3c5 309
AnnaBridge 172:7d866c31b3c5 310 while (count < length) {
AnnaBridge 172:7d866c31b3c5 311 int32_t pdata = i2c_byte_read(obj, ((count < (length - 1))? 0: 1));
AnnaBridge 172:7d866c31b3c5 312 status = I2C_GetState(obj->i2c);
AnnaBridge 172:7d866c31b3c5 313 if (status.Bit.TRx) {
AnnaBridge 172:7d866c31b3c5 314 return (count);
AnnaBridge 172:7d866c31b3c5 315 } else {
AnnaBridge 172:7d866c31b3c5 316 if (pdata < 0) {
AnnaBridge 172:7d866c31b3c5 317 break;
AnnaBridge 172:7d866c31b3c5 318 }
AnnaBridge 172:7d866c31b3c5 319 data[count++] = (uint8_t)pdata;
AnnaBridge 172:7d866c31b3c5 320 }
AnnaBridge 172:7d866c31b3c5 321 }
AnnaBridge 172:7d866c31b3c5 322 i2c_slave_mode(obj, 1);
AnnaBridge 172:7d866c31b3c5 323 return (count);
AnnaBridge 172:7d866c31b3c5 324 }
AnnaBridge 172:7d866c31b3c5 325
AnnaBridge 172:7d866c31b3c5 326 int i2c_slave_write(i2c_t *obj, const char *data, int length)
AnnaBridge 172:7d866c31b3c5 327 {
AnnaBridge 172:7d866c31b3c5 328 int32_t count = 0;
AnnaBridge 172:7d866c31b3c5 329
AnnaBridge 172:7d866c31b3c5 330 while (count < length) {
AnnaBridge 172:7d866c31b3c5 331 if (i2c_byte_write(obj, (int32_t)data[count++]) < I2C_ACK) {
AnnaBridge 172:7d866c31b3c5 332 break;
AnnaBridge 172:7d866c31b3c5 333 }
AnnaBridge 172:7d866c31b3c5 334 }
AnnaBridge 172:7d866c31b3c5 335 i2c_slave_mode(obj, 1);
AnnaBridge 172:7d866c31b3c5 336 return (count);
AnnaBridge 172:7d866c31b3c5 337 }
AnnaBridge 172:7d866c31b3c5 338
AnnaBridge 172:7d866c31b3c5 339 void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask)
AnnaBridge 172:7d866c31b3c5 340 {
AnnaBridge 172:7d866c31b3c5 341 obj->address = address & 0xFE;
AnnaBridge 172:7d866c31b3c5 342 i2c_slave_mode(obj, 1);
AnnaBridge 172:7d866c31b3c5 343 }