Mbed for VNG board
Fork of mbed-src by
targets/hal/TARGET_Freescale/TARGET_KPSDK_MCUS/i2c_api.c@397:e6a80499f8a6, 2014-11-12 (annotated)
- Committer:
- mbed_official
- Date:
- Wed Nov 12 09:00:07 2014 +0000
- Revision:
- 397:e6a80499f8a6
- Parent:
- 324:406fd2029f23
Synchronized with git revision 6fd59778d63339412e56341e5ae1a8823a90f4f3
Full URL: https://github.com/mbedmicro/mbed/commit/6fd59778d63339412e56341e5ae1a8823a90f4f3/
Targets: KSDK - Fix ACK/NACK received inverted (issue #661)
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
mbed_official | 324:406fd2029f23 | 1 | /* mbed Microcontroller Library |
mbed_official | 324:406fd2029f23 | 2 | * Copyright (c) 2006-2013 ARM Limited |
mbed_official | 324:406fd2029f23 | 3 | * |
mbed_official | 324:406fd2029f23 | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
mbed_official | 324:406fd2029f23 | 5 | * you may not use this file except in compliance with the License. |
mbed_official | 324:406fd2029f23 | 6 | * You may obtain a copy of the License at |
mbed_official | 324:406fd2029f23 | 7 | * |
mbed_official | 324:406fd2029f23 | 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
mbed_official | 324:406fd2029f23 | 9 | * |
mbed_official | 324:406fd2029f23 | 10 | * Unless required by applicable law or agreed to in writing, software |
mbed_official | 324:406fd2029f23 | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
mbed_official | 324:406fd2029f23 | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
mbed_official | 324:406fd2029f23 | 13 | * See the License for the specific language governing permissions and |
mbed_official | 324:406fd2029f23 | 14 | * limitations under the License. |
mbed_official | 324:406fd2029f23 | 15 | */ |
mbed_official | 324:406fd2029f23 | 16 | #include "mbed_assert.h" |
mbed_official | 324:406fd2029f23 | 17 | #include "i2c_api.h" |
mbed_official | 324:406fd2029f23 | 18 | |
mbed_official | 324:406fd2029f23 | 19 | #if DEVICE_I2C |
mbed_official | 324:406fd2029f23 | 20 | |
mbed_official | 324:406fd2029f23 | 21 | #include "cmsis.h" |
mbed_official | 324:406fd2029f23 | 22 | #include "pinmap.h" |
mbed_official | 324:406fd2029f23 | 23 | #include "fsl_clock_manager.h" |
mbed_official | 324:406fd2029f23 | 24 | #include "fsl_i2c_hal.h" |
mbed_official | 324:406fd2029f23 | 25 | #include "fsl_port_hal.h" |
mbed_official | 324:406fd2029f23 | 26 | #include "fsl_sim_hal.h" |
mbed_official | 324:406fd2029f23 | 27 | #include "PeripheralPins.h" |
mbed_official | 324:406fd2029f23 | 28 | |
mbed_official | 324:406fd2029f23 | 29 | void i2c_init(i2c_t *obj, PinName sda, PinName scl) { |
mbed_official | 324:406fd2029f23 | 30 | uint32_t i2c_sda = pinmap_peripheral(sda, PinMap_I2C_SDA); |
mbed_official | 324:406fd2029f23 | 31 | uint32_t i2c_scl = pinmap_peripheral(scl, PinMap_I2C_SCL); |
mbed_official | 324:406fd2029f23 | 32 | obj->instance = pinmap_merge(i2c_sda, i2c_scl); |
mbed_official | 324:406fd2029f23 | 33 | MBED_ASSERT((int)obj->instance != NC); |
mbed_official | 324:406fd2029f23 | 34 | |
mbed_official | 324:406fd2029f23 | 35 | CLOCK_SYS_EnableI2cClock(obj->instance); |
mbed_official | 324:406fd2029f23 | 36 | uint32_t i2c_addrs[] = I2C_BASE_ADDRS; |
mbed_official | 324:406fd2029f23 | 37 | I2C_HAL_Init(i2c_addrs[obj->instance]); |
mbed_official | 324:406fd2029f23 | 38 | I2C_HAL_Enable(i2c_addrs[obj->instance]); |
mbed_official | 324:406fd2029f23 | 39 | I2C_HAL_SetIntCmd(i2c_addrs[obj->instance], true); |
mbed_official | 324:406fd2029f23 | 40 | i2c_frequency(obj, 100000); |
mbed_official | 324:406fd2029f23 | 41 | |
mbed_official | 324:406fd2029f23 | 42 | pinmap_pinout(sda, PinMap_I2C_SDA); |
mbed_official | 324:406fd2029f23 | 43 | pinmap_pinout(scl, PinMap_I2C_SCL); |
mbed_official | 324:406fd2029f23 | 44 | |
mbed_official | 324:406fd2029f23 | 45 | uint32_t port_addrs[] = PORT_BASE_ADDRS; |
mbed_official | 324:406fd2029f23 | 46 | PORT_HAL_SetOpenDrainCmd(port_addrs[sda >> GPIO_PORT_SHIFT], sda & 0xFF, true); |
mbed_official | 324:406fd2029f23 | 47 | PORT_HAL_SetOpenDrainCmd(port_addrs[scl >> GPIO_PORT_SHIFT], scl & 0xFF, true); |
mbed_official | 324:406fd2029f23 | 48 | } |
mbed_official | 324:406fd2029f23 | 49 | |
mbed_official | 324:406fd2029f23 | 50 | int i2c_start(i2c_t *obj) { |
mbed_official | 324:406fd2029f23 | 51 | uint32_t i2c_addrs[] = I2C_BASE_ADDRS; |
mbed_official | 324:406fd2029f23 | 52 | I2C_HAL_SendStart(i2c_addrs[obj->instance]); |
mbed_official | 324:406fd2029f23 | 53 | return 0; |
mbed_official | 324:406fd2029f23 | 54 | } |
mbed_official | 324:406fd2029f23 | 55 | |
mbed_official | 324:406fd2029f23 | 56 | int i2c_stop(i2c_t *obj) { |
mbed_official | 324:406fd2029f23 | 57 | volatile uint32_t n = 0; |
mbed_official | 324:406fd2029f23 | 58 | uint32_t i2c_addrs[] = I2C_BASE_ADDRS; |
mbed_official | 324:406fd2029f23 | 59 | if (I2C_HAL_IsMaster(i2c_addrs[obj->instance])) |
mbed_official | 324:406fd2029f23 | 60 | I2C_HAL_SendStop(i2c_addrs[obj->instance]); |
mbed_official | 324:406fd2029f23 | 61 | |
mbed_official | 324:406fd2029f23 | 62 | // It seems that there are timing problems |
mbed_official | 324:406fd2029f23 | 63 | // when there is no waiting time after a STOP. |
mbed_official | 324:406fd2029f23 | 64 | // This wait is also included on the samples |
mbed_official | 324:406fd2029f23 | 65 | // code provided with the freedom board |
mbed_official | 324:406fd2029f23 | 66 | for (n = 0; n < 200; n++) __NOP(); |
mbed_official | 324:406fd2029f23 | 67 | return 0; |
mbed_official | 324:406fd2029f23 | 68 | } |
mbed_official | 324:406fd2029f23 | 69 | |
mbed_official | 324:406fd2029f23 | 70 | static int timeout_status_poll(i2c_t *obj, i2c_status_flag_t flag) { |
mbed_official | 324:406fd2029f23 | 71 | uint32_t i, timeout = 100000; |
mbed_official | 324:406fd2029f23 | 72 | uint32_t i2c_addrs[] = I2C_BASE_ADDRS; |
mbed_official | 324:406fd2029f23 | 73 | |
mbed_official | 324:406fd2029f23 | 74 | for (i = 0; i < timeout; i++) { |
mbed_official | 324:406fd2029f23 | 75 | if (I2C_HAL_GetStatusFlag(i2c_addrs[obj->instance], flag)) |
mbed_official | 324:406fd2029f23 | 76 | return 0; |
mbed_official | 324:406fd2029f23 | 77 | } |
mbed_official | 324:406fd2029f23 | 78 | return 1; |
mbed_official | 324:406fd2029f23 | 79 | } |
mbed_official | 324:406fd2029f23 | 80 | |
mbed_official | 324:406fd2029f23 | 81 | // this function waits the end of a tx transfer and return the status of the transaction: |
mbed_official | 324:406fd2029f23 | 82 | // 0: OK ack received |
mbed_official | 324:406fd2029f23 | 83 | // 1: OK ack not received |
mbed_official | 324:406fd2029f23 | 84 | // 2: failure |
mbed_official | 324:406fd2029f23 | 85 | static int i2c_wait_end_tx_transfer(i2c_t *obj) { |
mbed_official | 324:406fd2029f23 | 86 | // wait for the interrupt flag |
mbed_official | 324:406fd2029f23 | 87 | uint32_t i2c_addrs[] = I2C_BASE_ADDRS; |
mbed_official | 324:406fd2029f23 | 88 | |
mbed_official | 324:406fd2029f23 | 89 | if (timeout_status_poll(obj, kI2CInterruptPending)) { |
mbed_official | 324:406fd2029f23 | 90 | return 2; |
mbed_official | 324:406fd2029f23 | 91 | } |
mbed_official | 324:406fd2029f23 | 92 | I2C_HAL_ClearInt(i2c_addrs[obj->instance]); |
mbed_official | 324:406fd2029f23 | 93 | |
mbed_official | 324:406fd2029f23 | 94 | // wait transfer complete |
mbed_official | 324:406fd2029f23 | 95 | if (timeout_status_poll(obj, kI2CTransferComplete)) { |
mbed_official | 324:406fd2029f23 | 96 | return 2; |
mbed_official | 324:406fd2029f23 | 97 | } |
mbed_official | 324:406fd2029f23 | 98 | |
mbed_official | 324:406fd2029f23 | 99 | // check if we received the ACK or not |
mbed_official | 397:e6a80499f8a6 | 100 | return I2C_HAL_GetStatusFlag(i2c_addrs[obj->instance], kI2CReceivedNak) ? 1 : 0; |
mbed_official | 324:406fd2029f23 | 101 | } |
mbed_official | 324:406fd2029f23 | 102 | |
mbed_official | 324:406fd2029f23 | 103 | // this function waits the end of a rx transfer and return the status of the transaction: |
mbed_official | 324:406fd2029f23 | 104 | // 0: OK |
mbed_official | 324:406fd2029f23 | 105 | // 1: failure |
mbed_official | 324:406fd2029f23 | 106 | static int i2c_wait_end_rx_transfer(i2c_t *obj) { |
mbed_official | 324:406fd2029f23 | 107 | // wait for the end of the rx transfer |
mbed_official | 324:406fd2029f23 | 108 | if (timeout_status_poll(obj, kI2CInterruptPending)) { |
mbed_official | 324:406fd2029f23 | 109 | return 1; |
mbed_official | 324:406fd2029f23 | 110 | } |
mbed_official | 324:406fd2029f23 | 111 | uint32_t i2c_addrs[] = I2C_BASE_ADDRS; |
mbed_official | 324:406fd2029f23 | 112 | I2C_HAL_ClearInt(i2c_addrs[obj->instance]); |
mbed_official | 324:406fd2029f23 | 113 | |
mbed_official | 324:406fd2029f23 | 114 | return 0; |
mbed_official | 324:406fd2029f23 | 115 | } |
mbed_official | 324:406fd2029f23 | 116 | |
mbed_official | 324:406fd2029f23 | 117 | static int i2c_do_write(i2c_t *obj, int value) { |
mbed_official | 324:406fd2029f23 | 118 | uint32_t i2c_addrs[] = I2C_BASE_ADDRS; |
mbed_official | 324:406fd2029f23 | 119 | I2C_HAL_WriteByte(i2c_addrs[obj->instance], value); |
mbed_official | 324:406fd2029f23 | 120 | |
mbed_official | 324:406fd2029f23 | 121 | // init and wait the end of the transfer |
mbed_official | 324:406fd2029f23 | 122 | return i2c_wait_end_tx_transfer(obj); |
mbed_official | 324:406fd2029f23 | 123 | } |
mbed_official | 324:406fd2029f23 | 124 | |
mbed_official | 324:406fd2029f23 | 125 | static int i2c_do_read(i2c_t *obj, char * data, int last) { |
mbed_official | 324:406fd2029f23 | 126 | uint32_t i2c_addrs[] = I2C_BASE_ADDRS; |
mbed_official | 324:406fd2029f23 | 127 | if (last) { |
mbed_official | 324:406fd2029f23 | 128 | I2C_HAL_SendNak(i2c_addrs[obj->instance]); |
mbed_official | 324:406fd2029f23 | 129 | } else { |
mbed_official | 324:406fd2029f23 | 130 | I2C_HAL_SendAck(i2c_addrs[obj->instance]); |
mbed_official | 324:406fd2029f23 | 131 | } |
mbed_official | 324:406fd2029f23 | 132 | |
mbed_official | 324:406fd2029f23 | 133 | *data = (I2C_HAL_ReadByte(i2c_addrs[obj->instance]) & 0xFF); |
mbed_official | 324:406fd2029f23 | 134 | |
mbed_official | 324:406fd2029f23 | 135 | // start rx transfer and wait the end of the transfer |
mbed_official | 324:406fd2029f23 | 136 | return i2c_wait_end_rx_transfer(obj); |
mbed_official | 324:406fd2029f23 | 137 | } |
mbed_official | 324:406fd2029f23 | 138 | |
mbed_official | 324:406fd2029f23 | 139 | void i2c_frequency(i2c_t *obj, int hz) { |
mbed_official | 324:406fd2029f23 | 140 | uint32_t busClock; |
mbed_official | 324:406fd2029f23 | 141 | uint32_t i2c_addrs[] = I2C_BASE_ADDRS; |
mbed_official | 324:406fd2029f23 | 142 | clock_manager_error_code_t error = CLOCK_SYS_GetFreq(kBusClock, &busClock); |
mbed_official | 324:406fd2029f23 | 143 | if (error == kClockManagerSuccess) { |
mbed_official | 324:406fd2029f23 | 144 | I2C_HAL_SetBaudRate(i2c_addrs[obj->instance], busClock, hz / 1000, NULL); |
mbed_official | 324:406fd2029f23 | 145 | } |
mbed_official | 324:406fd2029f23 | 146 | } |
mbed_official | 324:406fd2029f23 | 147 | |
mbed_official | 324:406fd2029f23 | 148 | int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) { |
mbed_official | 324:406fd2029f23 | 149 | int count; |
mbed_official | 324:406fd2029f23 | 150 | char dummy_read, *ptr; |
mbed_official | 324:406fd2029f23 | 151 | |
mbed_official | 324:406fd2029f23 | 152 | if (i2c_start(obj)) { |
mbed_official | 324:406fd2029f23 | 153 | i2c_stop(obj); |
mbed_official | 324:406fd2029f23 | 154 | return I2C_ERROR_BUS_BUSY; |
mbed_official | 324:406fd2029f23 | 155 | } |
mbed_official | 324:406fd2029f23 | 156 | |
mbed_official | 324:406fd2029f23 | 157 | if (i2c_do_write(obj, (address | 0x01))) { |
mbed_official | 324:406fd2029f23 | 158 | i2c_stop(obj); |
mbed_official | 324:406fd2029f23 | 159 | return I2C_ERROR_NO_SLAVE; |
mbed_official | 324:406fd2029f23 | 160 | } |
mbed_official | 324:406fd2029f23 | 161 | |
mbed_official | 324:406fd2029f23 | 162 | // set rx mode |
mbed_official | 324:406fd2029f23 | 163 | uint32_t i2c_addrs[] = I2C_BASE_ADDRS; |
mbed_official | 324:406fd2029f23 | 164 | I2C_HAL_SetDirMode(i2c_addrs[obj->instance], kI2CReceive); |
mbed_official | 324:406fd2029f23 | 165 | |
mbed_official | 324:406fd2029f23 | 166 | // Read in bytes |
mbed_official | 324:406fd2029f23 | 167 | for (count = 0; count < (length); count++) { |
mbed_official | 324:406fd2029f23 | 168 | ptr = (count == 0) ? &dummy_read : &data[count - 1]; |
mbed_official | 324:406fd2029f23 | 169 | uint8_t stop_ = (count == (length - 1)) ? 1 : 0; |
mbed_official | 324:406fd2029f23 | 170 | if (i2c_do_read(obj, ptr, stop_)) { |
mbed_official | 324:406fd2029f23 | 171 | i2c_stop(obj); |
mbed_official | 324:406fd2029f23 | 172 | return count; |
mbed_official | 324:406fd2029f23 | 173 | } |
mbed_official | 324:406fd2029f23 | 174 | } |
mbed_official | 324:406fd2029f23 | 175 | |
mbed_official | 324:406fd2029f23 | 176 | // If not repeated start, send stop. |
mbed_official | 324:406fd2029f23 | 177 | if (stop) |
mbed_official | 324:406fd2029f23 | 178 | i2c_stop(obj); |
mbed_official | 324:406fd2029f23 | 179 | |
mbed_official | 324:406fd2029f23 | 180 | // last read |
mbed_official | 324:406fd2029f23 | 181 | data[count-1] = I2C_HAL_ReadByte(i2c_addrs[obj->instance]); |
mbed_official | 324:406fd2029f23 | 182 | |
mbed_official | 324:406fd2029f23 | 183 | return length; |
mbed_official | 324:406fd2029f23 | 184 | } |
mbed_official | 324:406fd2029f23 | 185 | |
mbed_official | 324:406fd2029f23 | 186 | int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) { |
mbed_official | 324:406fd2029f23 | 187 | int i; |
mbed_official | 324:406fd2029f23 | 188 | |
mbed_official | 324:406fd2029f23 | 189 | if (i2c_start(obj)) { |
mbed_official | 324:406fd2029f23 | 190 | i2c_stop(obj); |
mbed_official | 324:406fd2029f23 | 191 | return I2C_ERROR_BUS_BUSY; |
mbed_official | 324:406fd2029f23 | 192 | } |
mbed_official | 324:406fd2029f23 | 193 | |
mbed_official | 324:406fd2029f23 | 194 | if (i2c_do_write(obj, (address & 0xFE))) { |
mbed_official | 324:406fd2029f23 | 195 | i2c_stop(obj); |
mbed_official | 324:406fd2029f23 | 196 | return I2C_ERROR_NO_SLAVE; |
mbed_official | 324:406fd2029f23 | 197 | } |
mbed_official | 324:406fd2029f23 | 198 | |
mbed_official | 324:406fd2029f23 | 199 | for (i = 0; i < length; i++) { |
mbed_official | 324:406fd2029f23 | 200 | if(i2c_do_write(obj, data[i])) { |
mbed_official | 324:406fd2029f23 | 201 | i2c_stop(obj); |
mbed_official | 324:406fd2029f23 | 202 | return i; |
mbed_official | 324:406fd2029f23 | 203 | } |
mbed_official | 324:406fd2029f23 | 204 | } |
mbed_official | 324:406fd2029f23 | 205 | |
mbed_official | 324:406fd2029f23 | 206 | if (stop) |
mbed_official | 324:406fd2029f23 | 207 | i2c_stop(obj); |
mbed_official | 324:406fd2029f23 | 208 | |
mbed_official | 324:406fd2029f23 | 209 | return length; |
mbed_official | 324:406fd2029f23 | 210 | } |
mbed_official | 324:406fd2029f23 | 211 | |
mbed_official | 324:406fd2029f23 | 212 | void i2c_reset(i2c_t *obj) { |
mbed_official | 324:406fd2029f23 | 213 | i2c_stop(obj); |
mbed_official | 324:406fd2029f23 | 214 | } |
mbed_official | 324:406fd2029f23 | 215 | |
mbed_official | 324:406fd2029f23 | 216 | int i2c_byte_read(i2c_t *obj, int last) { |
mbed_official | 324:406fd2029f23 | 217 | char data; |
mbed_official | 324:406fd2029f23 | 218 | uint32_t i2c_addrs[] = I2C_BASE_ADDRS; |
mbed_official | 324:406fd2029f23 | 219 | // set rx mode |
mbed_official | 324:406fd2029f23 | 220 | I2C_HAL_SetDirMode(i2c_addrs[obj->instance], kI2CReceive); |
mbed_official | 324:406fd2029f23 | 221 | |
mbed_official | 324:406fd2029f23 | 222 | // Setup read |
mbed_official | 324:406fd2029f23 | 223 | i2c_do_read(obj, &data, last); |
mbed_official | 324:406fd2029f23 | 224 | |
mbed_official | 324:406fd2029f23 | 225 | // set tx mode |
mbed_official | 324:406fd2029f23 | 226 | I2C_HAL_SetDirMode(i2c_addrs[obj->instance], kI2CSend); |
mbed_official | 324:406fd2029f23 | 227 | return I2C_HAL_ReadByte(i2c_addrs[obj->instance]); |
mbed_official | 324:406fd2029f23 | 228 | } |
mbed_official | 324:406fd2029f23 | 229 | |
mbed_official | 324:406fd2029f23 | 230 | int i2c_byte_write(i2c_t *obj, int data) { |
mbed_official | 324:406fd2029f23 | 231 | uint32_t i2c_addrs[] = I2C_BASE_ADDRS; |
mbed_official | 324:406fd2029f23 | 232 | // set tx mode |
mbed_official | 324:406fd2029f23 | 233 | I2C_HAL_SetDirMode(i2c_addrs[obj->instance], kI2CSend); |
mbed_official | 324:406fd2029f23 | 234 | |
mbed_official | 324:406fd2029f23 | 235 | return !i2c_do_write(obj, (data & 0xFF)); |
mbed_official | 324:406fd2029f23 | 236 | } |
mbed_official | 324:406fd2029f23 | 237 | |
mbed_official | 324:406fd2029f23 | 238 | |
mbed_official | 324:406fd2029f23 | 239 | #if DEVICE_I2CSLAVE |
mbed_official | 324:406fd2029f23 | 240 | void i2c_slave_mode(i2c_t *obj, int enable_slave) { |
mbed_official | 324:406fd2029f23 | 241 | uint32_t i2c_addrs[] = I2C_BASE_ADDRS; |
mbed_official | 324:406fd2029f23 | 242 | if (enable_slave) { |
mbed_official | 324:406fd2029f23 | 243 | // set slave mode |
mbed_official | 324:406fd2029f23 | 244 | BW_I2C_C1_MST(i2c_addrs[obj->instance], 0); |
mbed_official | 324:406fd2029f23 | 245 | I2C_HAL_SetIntCmd(i2c_addrs[obj->instance], true); |
mbed_official | 324:406fd2029f23 | 246 | } else { |
mbed_official | 324:406fd2029f23 | 247 | // set master mode |
mbed_official | 324:406fd2029f23 | 248 | BW_I2C_C1_MST(i2c_addrs[obj->instance], 1); |
mbed_official | 324:406fd2029f23 | 249 | } |
mbed_official | 324:406fd2029f23 | 250 | } |
mbed_official | 324:406fd2029f23 | 251 | |
mbed_official | 324:406fd2029f23 | 252 | int i2c_slave_receive(i2c_t *obj) { |
mbed_official | 324:406fd2029f23 | 253 | uint32_t i2c_addrs[] = I2C_BASE_ADDRS; |
mbed_official | 324:406fd2029f23 | 254 | switch(HW_I2C_S_RD(i2c_addrs[obj->instance])) { |
mbed_official | 324:406fd2029f23 | 255 | // read addressed |
mbed_official | 324:406fd2029f23 | 256 | case 0xE6: |
mbed_official | 324:406fd2029f23 | 257 | return 1; |
mbed_official | 324:406fd2029f23 | 258 | // write addressed |
mbed_official | 324:406fd2029f23 | 259 | case 0xE2: |
mbed_official | 324:406fd2029f23 | 260 | return 3; |
mbed_official | 324:406fd2029f23 | 261 | default: |
mbed_official | 324:406fd2029f23 | 262 | return 0; |
mbed_official | 324:406fd2029f23 | 263 | } |
mbed_official | 324:406fd2029f23 | 264 | } |
mbed_official | 324:406fd2029f23 | 265 | |
mbed_official | 324:406fd2029f23 | 266 | int i2c_slave_read(i2c_t *obj, char *data, int length) { |
mbed_official | 324:406fd2029f23 | 267 | uint8_t dummy_read; |
mbed_official | 324:406fd2029f23 | 268 | uint8_t *ptr; |
mbed_official | 324:406fd2029f23 | 269 | int count; |
mbed_official | 324:406fd2029f23 | 270 | uint32_t i2c_addrs[] = I2C_BASE_ADDRS; |
mbed_official | 324:406fd2029f23 | 271 | // set rx mode |
mbed_official | 324:406fd2029f23 | 272 | I2C_HAL_SetDirMode(i2c_addrs[obj->instance], kI2CSend); |
mbed_official | 324:406fd2029f23 | 273 | |
mbed_official | 324:406fd2029f23 | 274 | // first dummy read |
mbed_official | 324:406fd2029f23 | 275 | dummy_read = I2C_HAL_ReadByte(i2c_addrs[obj->instance]); |
mbed_official | 324:406fd2029f23 | 276 | if (i2c_wait_end_rx_transfer(obj)) |
mbed_official | 324:406fd2029f23 | 277 | return 0; |
mbed_official | 324:406fd2029f23 | 278 | |
mbed_official | 324:406fd2029f23 | 279 | // read address |
mbed_official | 324:406fd2029f23 | 280 | dummy_read = I2C_HAL_ReadByte(i2c_addrs[obj->instance]); |
mbed_official | 324:406fd2029f23 | 281 | if (i2c_wait_end_rx_transfer(obj)) |
mbed_official | 324:406fd2029f23 | 282 | return 0; |
mbed_official | 324:406fd2029f23 | 283 | |
mbed_official | 324:406fd2029f23 | 284 | // read (length - 1) bytes |
mbed_official | 324:406fd2029f23 | 285 | for (count = 0; count < (length - 1); count++) { |
mbed_official | 324:406fd2029f23 | 286 | data[count] = I2C_HAL_ReadByte(i2c_addrs[obj->instance]); |
mbed_official | 324:406fd2029f23 | 287 | if (i2c_wait_end_rx_transfer(obj)) |
mbed_official | 324:406fd2029f23 | 288 | return count; |
mbed_official | 324:406fd2029f23 | 289 | } |
mbed_official | 324:406fd2029f23 | 290 | |
mbed_official | 324:406fd2029f23 | 291 | // read last byte |
mbed_official | 324:406fd2029f23 | 292 | ptr = (length == 0) ? &dummy_read : (uint8_t *)&data[count]; |
mbed_official | 324:406fd2029f23 | 293 | *ptr = I2C_HAL_ReadByte(i2c_addrs[obj->instance]); |
mbed_official | 324:406fd2029f23 | 294 | |
mbed_official | 324:406fd2029f23 | 295 | return (length) ? (count + 1) : 0; |
mbed_official | 324:406fd2029f23 | 296 | } |
mbed_official | 324:406fd2029f23 | 297 | |
mbed_official | 324:406fd2029f23 | 298 | int i2c_slave_write(i2c_t *obj, const char *data, int length) { |
mbed_official | 324:406fd2029f23 | 299 | int i, count = 0; |
mbed_official | 324:406fd2029f23 | 300 | uint32_t i2c_addrs[] = I2C_BASE_ADDRS; |
mbed_official | 324:406fd2029f23 | 301 | |
mbed_official | 324:406fd2029f23 | 302 | // set tx mode |
mbed_official | 324:406fd2029f23 | 303 | I2C_HAL_SetDirMode(i2c_addrs[obj->instance], kI2CSend); |
mbed_official | 324:406fd2029f23 | 304 | |
mbed_official | 324:406fd2029f23 | 305 | for (i = 0; i < length; i++) { |
mbed_official | 324:406fd2029f23 | 306 | if (i2c_do_write(obj, data[count++]) == 2) |
mbed_official | 324:406fd2029f23 | 307 | return i; |
mbed_official | 324:406fd2029f23 | 308 | } |
mbed_official | 324:406fd2029f23 | 309 | |
mbed_official | 324:406fd2029f23 | 310 | // set rx mode |
mbed_official | 324:406fd2029f23 | 311 | I2C_HAL_SetDirMode(i2c_addrs[obj->instance], kI2CReceive); |
mbed_official | 324:406fd2029f23 | 312 | |
mbed_official | 324:406fd2029f23 | 313 | // dummy rx transfer needed |
mbed_official | 324:406fd2029f23 | 314 | // otherwise the master cannot generate a stop bit |
mbed_official | 324:406fd2029f23 | 315 | I2C_HAL_ReadByte(i2c_addrs[obj->instance]); |
mbed_official | 324:406fd2029f23 | 316 | if (i2c_wait_end_rx_transfer(obj) == 2) |
mbed_official | 324:406fd2029f23 | 317 | return count; |
mbed_official | 324:406fd2029f23 | 318 | |
mbed_official | 324:406fd2029f23 | 319 | return count; |
mbed_official | 324:406fd2029f23 | 320 | } |
mbed_official | 324:406fd2029f23 | 321 | |
mbed_official | 324:406fd2029f23 | 322 | void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask) { |
mbed_official | 324:406fd2029f23 | 323 | uint32_t i2c_addrs[] = I2C_BASE_ADDRS; |
mbed_official | 324:406fd2029f23 | 324 | I2C_HAL_SetUpperAddress7bit(i2c_addrs[obj->instance], address & 0xfe); |
mbed_official | 324:406fd2029f23 | 325 | } |
mbed_official | 324:406fd2029f23 | 326 | #endif |
mbed_official | 324:406fd2029f23 | 327 | |
mbed_official | 324:406fd2029f23 | 328 | #endif |