mbed library sources: Modified to operate FRDM-KL25Z at 48MHz from internal 32kHz oscillator (nothing else changed).
Fork of mbed-src by
The only file that changed is: mbed-src-FLL48/targets/cmsis/TARGET_Freescale/TARGET_KL25Z/system_MKL25Z4.h
targets/hal/TARGET_STM/TARGET_STM32F4XX/i2c_api.c@20:4263a77256ae, 2013-09-10 (annotated)
- Committer:
- bogdanm
- Date:
- Tue Sep 10 15:14:19 2013 +0300
- Revision:
- 20:4263a77256ae
Sync with git revision 171dda705c947bf910926a0b73d6a4797802554d
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
bogdanm | 20:4263a77256ae | 1 | /* mbed Microcontroller Library |
bogdanm | 20:4263a77256ae | 2 | * Copyright (c) 2006-2013 ARM Limited |
bogdanm | 20:4263a77256ae | 3 | * |
bogdanm | 20:4263a77256ae | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
bogdanm | 20:4263a77256ae | 5 | * you may not use this file except in compliance with the License. |
bogdanm | 20:4263a77256ae | 6 | * You may obtain a copy of the License at |
bogdanm | 20:4263a77256ae | 7 | * |
bogdanm | 20:4263a77256ae | 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
bogdanm | 20:4263a77256ae | 9 | * |
bogdanm | 20:4263a77256ae | 10 | * Unless required by applicable law or agreed to in writing, software |
bogdanm | 20:4263a77256ae | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
bogdanm | 20:4263a77256ae | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
bogdanm | 20:4263a77256ae | 13 | * See the License for the specific language governing permissions and |
bogdanm | 20:4263a77256ae | 14 | * limitations under the License. |
bogdanm | 20:4263a77256ae | 15 | */ |
bogdanm | 20:4263a77256ae | 16 | #include "i2c_api.h" |
bogdanm | 20:4263a77256ae | 17 | |
bogdanm | 20:4263a77256ae | 18 | #if DEVICE_I2C |
bogdanm | 20:4263a77256ae | 19 | |
bogdanm | 20:4263a77256ae | 20 | #include "cmsis.h" |
bogdanm | 20:4263a77256ae | 21 | #include "pinmap.h" |
bogdanm | 20:4263a77256ae | 22 | #include "error.h" |
bogdanm | 20:4263a77256ae | 23 | |
bogdanm | 20:4263a77256ae | 24 | static const PinMap PinMap_I2C_SDA[] = { |
bogdanm | 20:4263a77256ae | 25 | {PB_7, I2C_1, STM_PIN_DATA(2, 4)}, |
bogdanm | 20:4263a77256ae | 26 | {PB_9, I2C_1, STM_PIN_DATA(2, 4)}, |
bogdanm | 20:4263a77256ae | 27 | {PB_11, I2C_2, STM_PIN_DATA(2, 4)}, |
bogdanm | 20:4263a77256ae | 28 | {PC_9, I2C_3, STM_PIN_DATA(2, 4)}, |
bogdanm | 20:4263a77256ae | 29 | {PF_0, I2C_2, STM_PIN_DATA(2, 4)}, |
bogdanm | 20:4263a77256ae | 30 | {PH_5, I2C_2, STM_PIN_DATA(2, 4)}, |
bogdanm | 20:4263a77256ae | 31 | {PH_8, I2C_3, STM_PIN_DATA(2, 4)}, |
bogdanm | 20:4263a77256ae | 32 | {NC, NC, 0} |
bogdanm | 20:4263a77256ae | 33 | }; |
bogdanm | 20:4263a77256ae | 34 | |
bogdanm | 20:4263a77256ae | 35 | static const PinMap PinMap_I2C_SCL[] = { |
bogdanm | 20:4263a77256ae | 36 | {PA_8, I2C_3, STM_PIN_DATA(2, 4)}, |
bogdanm | 20:4263a77256ae | 37 | {PB_6, I2C_1, STM_PIN_DATA(2, 4)}, |
bogdanm | 20:4263a77256ae | 38 | {PB_8, I2C_1, STM_PIN_DATA(2, 4)}, |
bogdanm | 20:4263a77256ae | 39 | {PB_10, I2C_2, STM_PIN_DATA(2, 4)}, |
bogdanm | 20:4263a77256ae | 40 | {PF_1, I2C_2, STM_PIN_DATA(2, 4)}, |
bogdanm | 20:4263a77256ae | 41 | {PH_4, I2C_2, STM_PIN_DATA(2, 4)}, |
bogdanm | 20:4263a77256ae | 42 | {PH_7, I2C_3, STM_PIN_DATA(2, 4)}, |
bogdanm | 20:4263a77256ae | 43 | {NC, NC, 0} |
bogdanm | 20:4263a77256ae | 44 | }; |
bogdanm | 20:4263a77256ae | 45 | |
bogdanm | 20:4263a77256ae | 46 | static const uint32_t I2C_addr_offset[2][4] = { |
bogdanm | 20:4263a77256ae | 47 | {0x0C, 0x20, 0x24, 0x28}, |
bogdanm | 20:4263a77256ae | 48 | {0x30, 0x34, 0x38, 0x3C} |
bogdanm | 20:4263a77256ae | 49 | }; |
bogdanm | 20:4263a77256ae | 50 | |
bogdanm | 20:4263a77256ae | 51 | |
bogdanm | 20:4263a77256ae | 52 | static inline void i2c_interface_enable(i2c_t *obj) { |
bogdanm | 20:4263a77256ae | 53 | obj->i2c->CR1 |= I2C_CR1_PE; |
bogdanm | 20:4263a77256ae | 54 | } |
bogdanm | 20:4263a77256ae | 55 | |
bogdanm | 20:4263a77256ae | 56 | static inline void i2c_interface_disable(i2c_t *obj) { |
bogdanm | 20:4263a77256ae | 57 | obj->i2c->CR1 &= ~I2C_CR1_PE; |
bogdanm | 20:4263a77256ae | 58 | } |
bogdanm | 20:4263a77256ae | 59 | |
bogdanm | 20:4263a77256ae | 60 | |
bogdanm | 20:4263a77256ae | 61 | static inline void i2c_power_enable(i2c_t *obj) { |
bogdanm | 20:4263a77256ae | 62 | switch ((int)obj->i2c) { |
bogdanm | 20:4263a77256ae | 63 | case I2C_1: |
bogdanm | 20:4263a77256ae | 64 | RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN; |
bogdanm | 20:4263a77256ae | 65 | RCC->APB1ENR |= RCC_APB1ENR_I2C1EN; |
bogdanm | 20:4263a77256ae | 66 | break; |
bogdanm | 20:4263a77256ae | 67 | case I2C_2: |
bogdanm | 20:4263a77256ae | 68 | RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN | RCC_AHB1ENR_GPIOFEN | |
bogdanm | 20:4263a77256ae | 69 | RCC_AHB1ENR_GPIOHEN; |
bogdanm | 20:4263a77256ae | 70 | RCC->APB1ENR |= RCC_APB1ENR_I2C2EN; |
bogdanm | 20:4263a77256ae | 71 | break; |
bogdanm | 20:4263a77256ae | 72 | case I2C_3: |
bogdanm | 20:4263a77256ae | 73 | RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOCEN | |
bogdanm | 20:4263a77256ae | 74 | RCC_AHB1ENR_GPIOHEN; |
bogdanm | 20:4263a77256ae | 75 | RCC->APB1ENR |= RCC_APB1ENR_I2C3EN; |
bogdanm | 20:4263a77256ae | 76 | break; |
bogdanm | 20:4263a77256ae | 77 | } |
bogdanm | 20:4263a77256ae | 78 | } |
bogdanm | 20:4263a77256ae | 79 | |
bogdanm | 20:4263a77256ae | 80 | static inline void i2c_wait_status(i2c_t *obj, uint32_t sr1_mask, |
bogdanm | 20:4263a77256ae | 81 | uint32_t sr2_mask) { |
bogdanm | 20:4263a77256ae | 82 | while (!(((obj->i2c->SR1 & sr1_mask) >= sr1_mask) && |
bogdanm | 20:4263a77256ae | 83 | ((obj->i2c->SR2 & sr2_mask) == sr2_mask))); |
bogdanm | 20:4263a77256ae | 84 | } |
bogdanm | 20:4263a77256ae | 85 | |
bogdanm | 20:4263a77256ae | 86 | // Wait until the slave address has been acknowledged |
bogdanm | 20:4263a77256ae | 87 | static inline void i2c_wait_addr_tx(i2c_t *obj) { |
bogdanm | 20:4263a77256ae | 88 | uint32_t sr1_mask = I2C_SR1_ADDR | I2C_SR1_TXE; |
bogdanm | 20:4263a77256ae | 89 | uint32_t sr2_mask = I2C_SR2_MSL | I2C_SR2_BUSY | I2C_SR2_TRA; |
bogdanm | 20:4263a77256ae | 90 | i2c_wait_status(obj, sr1_mask, sr2_mask); |
bogdanm | 20:4263a77256ae | 91 | } |
bogdanm | 20:4263a77256ae | 92 | |
bogdanm | 20:4263a77256ae | 93 | // Wait until the slave address has been acknowledged |
bogdanm | 20:4263a77256ae | 94 | static inline void i2c_wait_addr_rx(i2c_t *obj) { |
bogdanm | 20:4263a77256ae | 95 | uint32_t sr1_mask = I2C_SR1_ADDR; |
bogdanm | 20:4263a77256ae | 96 | uint32_t sr2_mask = I2C_SR2_MSL | I2C_SR2_BUSY; |
bogdanm | 20:4263a77256ae | 97 | i2c_wait_status(obj, sr1_mask, sr2_mask); |
bogdanm | 20:4263a77256ae | 98 | } |
bogdanm | 20:4263a77256ae | 99 | |
bogdanm | 20:4263a77256ae | 100 | |
bogdanm | 20:4263a77256ae | 101 | // Wait until a byte has been sent |
bogdanm | 20:4263a77256ae | 102 | static inline void i2c_wait_send(i2c_t *obj) { |
bogdanm | 20:4263a77256ae | 103 | uint32_t sr1_mask = I2C_SR1_BTF | I2C_SR1_TXE; |
bogdanm | 20:4263a77256ae | 104 | uint32_t sr2_mask = I2C_SR2_MSL | I2C_SR2_BUSY | I2C_SR2_TRA; |
bogdanm | 20:4263a77256ae | 105 | i2c_wait_status(obj, sr1_mask, sr2_mask); |
bogdanm | 20:4263a77256ae | 106 | } |
bogdanm | 20:4263a77256ae | 107 | |
bogdanm | 20:4263a77256ae | 108 | // Wait until a byte has been received |
bogdanm | 20:4263a77256ae | 109 | static inline void i2c_wait_receive(i2c_t *obj) { |
bogdanm | 20:4263a77256ae | 110 | uint32_t sr1_mask = I2C_SR1_RXNE; |
bogdanm | 20:4263a77256ae | 111 | uint32_t sr2_mask = I2C_SR2_MSL | I2C_SR2_BUSY; |
bogdanm | 20:4263a77256ae | 112 | i2c_wait_status(obj, sr1_mask, sr2_mask); |
bogdanm | 20:4263a77256ae | 113 | } |
bogdanm | 20:4263a77256ae | 114 | |
bogdanm | 20:4263a77256ae | 115 | // Wait until the start condition has been accepted |
bogdanm | 20:4263a77256ae | 116 | static inline void i2c_wait_start(i2c_t *obj) { |
bogdanm | 20:4263a77256ae | 117 | uint32_t sr1_mask = I2C_SR1_SB; |
bogdanm | 20:4263a77256ae | 118 | uint32_t sr2_mask = I2C_SR2_MSL | I2C_SR2_BUSY; |
bogdanm | 20:4263a77256ae | 119 | i2c_wait_status(obj, sr1_mask, sr2_mask); |
bogdanm | 20:4263a77256ae | 120 | } |
bogdanm | 20:4263a77256ae | 121 | |
bogdanm | 20:4263a77256ae | 122 | void i2c_init(i2c_t *obj, PinName sda, PinName scl) { |
bogdanm | 20:4263a77256ae | 123 | // determine the SPI to use |
bogdanm | 20:4263a77256ae | 124 | I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA); |
bogdanm | 20:4263a77256ae | 125 | I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL); |
bogdanm | 20:4263a77256ae | 126 | obj->i2c = (I2C_TypeDef *)pinmap_merge(i2c_sda, i2c_scl); |
bogdanm | 20:4263a77256ae | 127 | |
bogdanm | 20:4263a77256ae | 128 | if ((int)obj->i2c == NC) { |
bogdanm | 20:4263a77256ae | 129 | error("I2C pin mapping failed"); |
bogdanm | 20:4263a77256ae | 130 | } |
bogdanm | 20:4263a77256ae | 131 | |
bogdanm | 20:4263a77256ae | 132 | // enable power |
bogdanm | 20:4263a77256ae | 133 | i2c_power_enable(obj); |
bogdanm | 20:4263a77256ae | 134 | |
bogdanm | 20:4263a77256ae | 135 | pinmap_pinout(sda, PinMap_I2C_SDA); |
bogdanm | 20:4263a77256ae | 136 | pinmap_pinout(scl, PinMap_I2C_SCL); |
bogdanm | 20:4263a77256ae | 137 | |
bogdanm | 20:4263a77256ae | 138 | pin_mode(sda, OpenDrain); |
bogdanm | 20:4263a77256ae | 139 | pin_mode(scl, OpenDrain); |
bogdanm | 20:4263a77256ae | 140 | |
bogdanm | 20:4263a77256ae | 141 | // Force reset if the bus is stuck in the BUSY state |
bogdanm | 20:4263a77256ae | 142 | if (obj->i2c->SR2 & I2C_SR2_BUSY) { |
bogdanm | 20:4263a77256ae | 143 | obj->i2c->CR1 |= I2C_CR1_SWRST; |
bogdanm | 20:4263a77256ae | 144 | obj->i2c->CR1 &= ~I2C_CR1_SWRST; |
bogdanm | 20:4263a77256ae | 145 | } |
bogdanm | 20:4263a77256ae | 146 | |
bogdanm | 20:4263a77256ae | 147 | // Set the peripheral clock frequency |
bogdanm | 20:4263a77256ae | 148 | obj->i2c->CR2 |= 42; |
bogdanm | 20:4263a77256ae | 149 | |
bogdanm | 20:4263a77256ae | 150 | // set default frequency at 100k |
bogdanm | 20:4263a77256ae | 151 | i2c_frequency(obj, 100000); |
bogdanm | 20:4263a77256ae | 152 | i2c_interface_enable(obj); |
bogdanm | 20:4263a77256ae | 153 | } |
bogdanm | 20:4263a77256ae | 154 | |
bogdanm | 20:4263a77256ae | 155 | inline int i2c_start(i2c_t *obj) { |
bogdanm | 20:4263a77256ae | 156 | // Wait until we are not busy any more |
bogdanm | 20:4263a77256ae | 157 | while (obj->i2c->SR2 & I2C_SR2_BUSY); |
bogdanm | 20:4263a77256ae | 158 | |
bogdanm | 20:4263a77256ae | 159 | // Generate the start condition |
bogdanm | 20:4263a77256ae | 160 | obj->i2c->CR1 |= I2C_CR1_START; |
bogdanm | 20:4263a77256ae | 161 | i2c_wait_start(obj); |
bogdanm | 20:4263a77256ae | 162 | |
bogdanm | 20:4263a77256ae | 163 | return 0; |
bogdanm | 20:4263a77256ae | 164 | } |
bogdanm | 20:4263a77256ae | 165 | |
bogdanm | 20:4263a77256ae | 166 | inline int i2c_stop(i2c_t *obj) { |
bogdanm | 20:4263a77256ae | 167 | // Generate the stop condition |
bogdanm | 20:4263a77256ae | 168 | obj->i2c->CR1 |= I2C_CR1_STOP; |
bogdanm | 20:4263a77256ae | 169 | return 0; |
bogdanm | 20:4263a77256ae | 170 | } |
bogdanm | 20:4263a77256ae | 171 | |
bogdanm | 20:4263a77256ae | 172 | |
bogdanm | 20:4263a77256ae | 173 | static inline int i2c_do_write(i2c_t *obj, int value, uint8_t addr) { |
bogdanm | 20:4263a77256ae | 174 | obj->i2c->DR = value; |
bogdanm | 20:4263a77256ae | 175 | return 0; |
bogdanm | 20:4263a77256ae | 176 | } |
bogdanm | 20:4263a77256ae | 177 | |
bogdanm | 20:4263a77256ae | 178 | static inline int i2c_do_read(i2c_t *obj, int last) { |
bogdanm | 20:4263a77256ae | 179 | if(last) { |
bogdanm | 20:4263a77256ae | 180 | // Don't acknowledge the byte |
bogdanm | 20:4263a77256ae | 181 | obj->i2c->CR1 &= ~(I2C_CR1_ACK); |
bogdanm | 20:4263a77256ae | 182 | } else { |
bogdanm | 20:4263a77256ae | 183 | // Acknowledge the byte |
bogdanm | 20:4263a77256ae | 184 | obj->i2c->CR1 |= I2C_CR1_ACK; |
bogdanm | 20:4263a77256ae | 185 | } |
bogdanm | 20:4263a77256ae | 186 | |
bogdanm | 20:4263a77256ae | 187 | // Wait until we receive the byte |
bogdanm | 20:4263a77256ae | 188 | i2c_wait_receive(obj); |
bogdanm | 20:4263a77256ae | 189 | |
bogdanm | 20:4263a77256ae | 190 | int data = obj->i2c->DR; |
bogdanm | 20:4263a77256ae | 191 | return data; |
bogdanm | 20:4263a77256ae | 192 | } |
bogdanm | 20:4263a77256ae | 193 | |
bogdanm | 20:4263a77256ae | 194 | void i2c_frequency(i2c_t *obj, int hz) { |
bogdanm | 20:4263a77256ae | 195 | i2c_interface_disable(obj); |
bogdanm | 20:4263a77256ae | 196 | obj->i2c->CCR &= ~(I2C_CCR_CCR | I2C_CCR_FS); |
bogdanm | 20:4263a77256ae | 197 | if (hz > 100000) { |
bogdanm | 20:4263a77256ae | 198 | // Fast Mode |
bogdanm | 20:4263a77256ae | 199 | obj->i2c->CCR |= I2C_CCR_FS; |
bogdanm | 20:4263a77256ae | 200 | int result = 42000000 / (hz * 3); |
bogdanm | 20:4263a77256ae | 201 | obj->i2c->CCR |= result & I2C_CCR_CCR; |
bogdanm | 20:4263a77256ae | 202 | obj->i2c->TRISE = ((42 * 300) / 1000) + 1; |
bogdanm | 20:4263a77256ae | 203 | } |
bogdanm | 20:4263a77256ae | 204 | else { |
bogdanm | 20:4263a77256ae | 205 | // Standard mode |
bogdanm | 20:4263a77256ae | 206 | obj->i2c->CCR &= ~I2C_CCR_FS; |
bogdanm | 20:4263a77256ae | 207 | int result = 42000000 / (hz << 1); |
bogdanm | 20:4263a77256ae | 208 | result = result < 0x4 ? 0x4 : result; |
bogdanm | 20:4263a77256ae | 209 | obj->i2c->CCR |= result & I2C_CCR_CCR; |
bogdanm | 20:4263a77256ae | 210 | obj->i2c->TRISE = 42 + 1; |
bogdanm | 20:4263a77256ae | 211 | } |
bogdanm | 20:4263a77256ae | 212 | i2c_interface_enable(obj); |
bogdanm | 20:4263a77256ae | 213 | } |
bogdanm | 20:4263a77256ae | 214 | |
bogdanm | 20:4263a77256ae | 215 | // The I2C does a read or a write as a whole operation |
bogdanm | 20:4263a77256ae | 216 | // There are two types of error conditions it can encounter |
bogdanm | 20:4263a77256ae | 217 | // 1) it can not obtain the bus |
bogdanm | 20:4263a77256ae | 218 | // 2) it gets error responses at part of the transmission |
bogdanm | 20:4263a77256ae | 219 | // |
bogdanm | 20:4263a77256ae | 220 | // We tackle them as follows: |
bogdanm | 20:4263a77256ae | 221 | // 1) we retry until we get the bus. we could have a "timeout" if we can not get it |
bogdanm | 20:4263a77256ae | 222 | // which basically turns it in to a 2) |
bogdanm | 20:4263a77256ae | 223 | // 2) on error, we use the standard error mechanisms to report/debug |
bogdanm | 20:4263a77256ae | 224 | // |
bogdanm | 20:4263a77256ae | 225 | // Therefore an I2C transaction should always complete. If it doesn't it is usually |
bogdanm | 20:4263a77256ae | 226 | // because something is setup wrong (e.g. wiring), and we don't need to programatically |
bogdanm | 20:4263a77256ae | 227 | // check for that |
bogdanm | 20:4263a77256ae | 228 | |
bogdanm | 20:4263a77256ae | 229 | int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) { |
bogdanm | 20:4263a77256ae | 230 | int count; |
bogdanm | 20:4263a77256ae | 231 | |
bogdanm | 20:4263a77256ae | 232 | i2c_start(obj); |
bogdanm | 20:4263a77256ae | 233 | |
bogdanm | 20:4263a77256ae | 234 | // Send the slave address |
bogdanm | 20:4263a77256ae | 235 | i2c_do_write(obj, (address | 0x01), 1); |
bogdanm | 20:4263a77256ae | 236 | |
bogdanm | 20:4263a77256ae | 237 | // Wait until we have transmitted and the ADDR byte is set |
bogdanm | 20:4263a77256ae | 238 | i2c_wait_addr_rx(obj); |
bogdanm | 20:4263a77256ae | 239 | |
bogdanm | 20:4263a77256ae | 240 | // Read in all except last byte |
bogdanm | 20:4263a77256ae | 241 | for (count = 0; count < (length - 1); count++) { |
bogdanm | 20:4263a77256ae | 242 | int value = i2c_do_read(obj, 0); |
bogdanm | 20:4263a77256ae | 243 | data[count] = (char) value; |
bogdanm | 20:4263a77256ae | 244 | } |
bogdanm | 20:4263a77256ae | 245 | |
bogdanm | 20:4263a77256ae | 246 | // read in last byte |
bogdanm | 20:4263a77256ae | 247 | int value = i2c_do_read(obj, 1); |
bogdanm | 20:4263a77256ae | 248 | data[count] = (char) value; |
bogdanm | 20:4263a77256ae | 249 | |
bogdanm | 20:4263a77256ae | 250 | // If not repeated start, send stop. |
bogdanm | 20:4263a77256ae | 251 | if (stop) { |
bogdanm | 20:4263a77256ae | 252 | i2c_stop(obj); |
bogdanm | 20:4263a77256ae | 253 | } |
bogdanm | 20:4263a77256ae | 254 | |
bogdanm | 20:4263a77256ae | 255 | return length; |
bogdanm | 20:4263a77256ae | 256 | } |
bogdanm | 20:4263a77256ae | 257 | |
bogdanm | 20:4263a77256ae | 258 | int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) { |
bogdanm | 20:4263a77256ae | 259 | int i; |
bogdanm | 20:4263a77256ae | 260 | |
bogdanm | 20:4263a77256ae | 261 | i2c_start(obj); |
bogdanm | 20:4263a77256ae | 262 | |
bogdanm | 20:4263a77256ae | 263 | // Send the slave address |
bogdanm | 20:4263a77256ae | 264 | i2c_do_write(obj, (address & 0xFE), 1); |
bogdanm | 20:4263a77256ae | 265 | i2c_wait_addr_tx(obj); |
bogdanm | 20:4263a77256ae | 266 | |
bogdanm | 20:4263a77256ae | 267 | for (i=0; i<length; i++) { |
bogdanm | 20:4263a77256ae | 268 | i2c_do_write(obj, data[i], 0); |
bogdanm | 20:4263a77256ae | 269 | i2c_wait_send(obj); |
bogdanm | 20:4263a77256ae | 270 | } |
bogdanm | 20:4263a77256ae | 271 | |
bogdanm | 20:4263a77256ae | 272 | // If not repeated start, send stop. |
bogdanm | 20:4263a77256ae | 273 | if (stop) { |
bogdanm | 20:4263a77256ae | 274 | i2c_stop(obj); |
bogdanm | 20:4263a77256ae | 275 | } |
bogdanm | 20:4263a77256ae | 276 | |
bogdanm | 20:4263a77256ae | 277 | return length; |
bogdanm | 20:4263a77256ae | 278 | } |
bogdanm | 20:4263a77256ae | 279 | |
bogdanm | 20:4263a77256ae | 280 | void i2c_reset(i2c_t *obj) { |
bogdanm | 20:4263a77256ae | 281 | i2c_stop(obj); |
bogdanm | 20:4263a77256ae | 282 | } |
bogdanm | 20:4263a77256ae | 283 | |
bogdanm | 20:4263a77256ae | 284 | int i2c_byte_read(i2c_t *obj, int last) { |
bogdanm | 20:4263a77256ae | 285 | return (i2c_do_read(obj, last) & 0xFF); |
bogdanm | 20:4263a77256ae | 286 | } |
bogdanm | 20:4263a77256ae | 287 | |
bogdanm | 20:4263a77256ae | 288 | int i2c_byte_write(i2c_t *obj, int data) { |
bogdanm | 20:4263a77256ae | 289 | i2c_do_write(obj, (data & 0xFF), 0); |
bogdanm | 20:4263a77256ae | 290 | i2c_wait_send(obj); |
bogdanm | 20:4263a77256ae | 291 | |
bogdanm | 20:4263a77256ae | 292 | // TODO: Should return whether write has been acknowledged |
bogdanm | 20:4263a77256ae | 293 | return 1; |
bogdanm | 20:4263a77256ae | 294 | } |
bogdanm | 20:4263a77256ae | 295 | |
bogdanm | 20:4263a77256ae | 296 | #endif |