[11U68]fix P0_11 to use GPIO

Fork of mbed-src by mbed official

Committer:
mbed_official
Date:
Wed Jun 10 10:00:08 2015 +0100
Revision:
563:536c9fb088a0
Parent:
548:1abac31e188e
Synchronized with git revision 4778e33fa11602202ae3a57ced5d026e8053cedf

Full URL: https://github.com/mbedmicro/mbed/commit/4778e33fa11602202ae3a57ced5d026e8053cedf/

Fix asynch methods constness

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 525:c320967f86b9 1 /* mbed Microcontroller Library
mbed_official 525:c320967f86b9 2 * Copyright (c) 2006-2013 ARM Limited
mbed_official 525:c320967f86b9 3 *
mbed_official 525:c320967f86b9 4 * Licensed under the Apache License, Version 2.0 (the "License");
mbed_official 525:c320967f86b9 5 * you may not use this file except in compliance with the License.
mbed_official 525:c320967f86b9 6 * You may obtain a copy of the License at
mbed_official 525:c320967f86b9 7 *
mbed_official 525:c320967f86b9 8 * http://www.apache.org/licenses/LICENSE-2.0
mbed_official 525:c320967f86b9 9 *
mbed_official 525:c320967f86b9 10 * Unless required by applicable law or agreed to in writing, software
mbed_official 525:c320967f86b9 11 * distributed under the License is distributed on an "AS IS" BASIS,
mbed_official 525:c320967f86b9 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
mbed_official 525:c320967f86b9 13 * See the License for the specific language governing permissions and
mbed_official 525:c320967f86b9 14 * limitations under the License.
mbed_official 525:c320967f86b9 15 */
mbed_official 525:c320967f86b9 16
mbed_official 525:c320967f86b9 17 #include "device.h"
mbed_official 525:c320967f86b9 18 #include "clocking.h"
mbed_official 525:c320967f86b9 19 #include <stdio.h>
mbed_official 525:c320967f86b9 20
mbed_official 525:c320967f86b9 21 #if DEVICE_I2C
mbed_official 525:c320967f86b9 22
mbed_official 525:c320967f86b9 23 #include "mbed_assert.h"
mbed_official 525:c320967f86b9 24 #include "i2c_api.h"
mbed_official 525:c320967f86b9 25 #include "PeripheralPins.h"
mbed_official 525:c320967f86b9 26 #include "pinmap_function.h"
mbed_official 526:7c4bdfe6a168 27 #include "sleepmodes.h"
mbed_official 525:c320967f86b9 28
mbed_official 525:c320967f86b9 29 #include "em_i2c.h"
mbed_official 525:c320967f86b9 30 #include "em_cmu.h"
mbed_official 525:c320967f86b9 31
mbed_official 525:c320967f86b9 32 /** Error flags indicating I2C transfer has failed somehow. */
mbed_official 525:c320967f86b9 33 /* Notice that I2C_IF_TXOF (transmit overflow) is not really possible with */
mbed_official 525:c320967f86b9 34 /* this SW supporting master mode. Likewise for I2C_IF_RXUF (receive underflow) */
mbed_official 525:c320967f86b9 35 /* RXUF is only likely to occur with this SW if using a debugger peeking into */
mbed_official 525:c320967f86b9 36 /* RXDATA register. Thus, we ignore those types of fault. */
mbed_official 525:c320967f86b9 37 #define I2C_IF_ERRORS (I2C_IF_BUSERR | I2C_IF_ARBLOST)
mbed_official 525:c320967f86b9 38 #define I2C_TIMEOUT 100000
mbed_official 525:c320967f86b9 39
mbed_official 525:c320967f86b9 40 /* Prototypes */
mbed_official 525:c320967f86b9 41 int block_and_wait_for_ack(I2C_TypeDef *i2c);
mbed_official 525:c320967f86b9 42 void i2c_enable(i2c_t *obj, uint8_t enable);
mbed_official 525:c320967f86b9 43 void i2c_enable_pins(i2c_t *obj, uint8_t enable);
mbed_official 525:c320967f86b9 44 void i2c_enable_interrupt(i2c_t *obj, uint32_t address, uint8_t enable);
mbed_official 525:c320967f86b9 45
mbed_official 525:c320967f86b9 46 static uint8_t i2c_get_index(i2c_t *obj)
mbed_official 525:c320967f86b9 47 {
mbed_official 525:c320967f86b9 48 uint8_t index = 0;
mbed_official 525:c320967f86b9 49 switch ((int)obj->i2c.i2c) {
mbed_official 525:c320967f86b9 50 #ifdef I2C0
mbed_official 525:c320967f86b9 51 case I2C_0:
mbed_official 525:c320967f86b9 52 index = 0;
mbed_official 525:c320967f86b9 53 break;
mbed_official 525:c320967f86b9 54 #endif
mbed_official 525:c320967f86b9 55 #ifdef I2C1
mbed_official 525:c320967f86b9 56 case I2C_1:
mbed_official 525:c320967f86b9 57 index = 1;
mbed_official 525:c320967f86b9 58 break;
mbed_official 525:c320967f86b9 59 #endif
mbed_official 525:c320967f86b9 60 default:
mbed_official 525:c320967f86b9 61 printf("I2C module not available.. Out of bound access.");
mbed_official 525:c320967f86b9 62 break;
mbed_official 525:c320967f86b9 63 }
mbed_official 525:c320967f86b9 64 return index;
mbed_official 525:c320967f86b9 65 }
mbed_official 525:c320967f86b9 66
mbed_official 525:c320967f86b9 67 static CMU_Clock_TypeDef i2c_get_clock(i2c_t *obj)
mbed_official 525:c320967f86b9 68 {
mbed_official 525:c320967f86b9 69 CMU_Clock_TypeDef clock;
mbed_official 525:c320967f86b9 70 switch ((int)obj->i2c.i2c) {
mbed_official 525:c320967f86b9 71 #ifdef I2C0
mbed_official 525:c320967f86b9 72 case I2C_0:
mbed_official 525:c320967f86b9 73 clock = cmuClock_I2C0;
mbed_official 525:c320967f86b9 74 break;
mbed_official 525:c320967f86b9 75 #endif
mbed_official 525:c320967f86b9 76 #ifdef I2C1
mbed_official 525:c320967f86b9 77 case I2C_1:
mbed_official 548:1abac31e188e 78 clock = cmuClock_I2C1;
mbed_official 525:c320967f86b9 79 break;
mbed_official 525:c320967f86b9 80 #endif
mbed_official 525:c320967f86b9 81 default:
mbed_official 525:c320967f86b9 82 printf("I2C module not available.. Out of bound access. (clock)");
mbed_official 525:c320967f86b9 83 clock = cmuClock_HFPER;
mbed_official 525:c320967f86b9 84 break;
mbed_official 525:c320967f86b9 85 }
mbed_official 525:c320967f86b9 86 return clock;
mbed_official 525:c320967f86b9 87 }
mbed_official 525:c320967f86b9 88
mbed_official 525:c320967f86b9 89 void i2c_preinit(i2c_t *obj, PinName sda, PinName scl)
mbed_official 525:c320967f86b9 90 {
mbed_official 525:c320967f86b9 91 I2CName i2c_sda = (I2CName) pinmap_peripheral(sda, PinMap_I2C_SDA);
mbed_official 525:c320967f86b9 92 I2CName i2c_scl = (I2CName) pinmap_peripheral(scl, PinMap_I2C_SCL);
mbed_official 525:c320967f86b9 93 obj->i2c.i2c = (I2C_TypeDef*) pinmap_merge(i2c_sda, i2c_scl);
mbed_official 525:c320967f86b9 94 MBED_ASSERT(((int) obj->i2c.i2c) != NC);
mbed_official 525:c320967f86b9 95
mbed_official 525:c320967f86b9 96 int loc_sda = pin_location(sda, PinMap_I2C_SDA);
mbed_official 525:c320967f86b9 97 int loc_scl = pin_location(scl, PinMap_I2C_SCL);
mbed_official 525:c320967f86b9 98 obj->i2c.loc = pinmap_merge(loc_sda, loc_scl);
mbed_official 525:c320967f86b9 99 MBED_ASSERT(obj->i2c.loc != NC);
mbed_official 525:c320967f86b9 100 obj->i2c.sda = sda;
mbed_official 525:c320967f86b9 101 obj->i2c.scl = scl;
mbed_official 525:c320967f86b9 102 }
mbed_official 525:c320967f86b9 103
mbed_official 525:c320967f86b9 104 void i2c_init(i2c_t *obj, PinName sda, PinName scl)
mbed_official 525:c320967f86b9 105 {
mbed_official 525:c320967f86b9 106 /* Assign mbed pins */
mbed_official 548:1abac31e188e 107 i2c_preinit(obj, sda, scl);
mbed_official 525:c320967f86b9 108
mbed_official 548:1abac31e188e 109 /* Enable clock for the peripheral */
mbed_official 548:1abac31e188e 110 CMU_ClockEnable(i2c_get_clock(obj), true);
mbed_official 525:c320967f86b9 111
mbed_official 525:c320967f86b9 112 /* Initializing the I2C */
mbed_official 525:c320967f86b9 113 /* Using default settings */
mbed_official 525:c320967f86b9 114 I2C_Init_TypeDef i2cInit = I2C_INIT_DEFAULT;
mbed_official 525:c320967f86b9 115 I2C_Init(obj->i2c.i2c, &i2cInit);
mbed_official 525:c320967f86b9 116
mbed_official 525:c320967f86b9 117 /* Enable pins at correct location */
mbed_official 525:c320967f86b9 118 obj->i2c.i2c->ROUTE = I2C_ROUTE_SDAPEN | I2C_ROUTE_SCLPEN | (obj->i2c.loc << _I2C_ROUTE_LOCATION_SHIFT);
mbed_official 525:c320967f86b9 119 i2c_enable_pins(obj, true);
mbed_official 525:c320967f86b9 120
mbed_official 525:c320967f86b9 121 /* Enable General Call Address Mode. That is; we respond to the general address (0x0) */
mbed_official 525:c320967f86b9 122 obj->i2c.i2c->CTRL |= _I2C_CTRL_GCAMEN_MASK;
mbed_official 525:c320967f86b9 123
mbed_official 525:c320967f86b9 124 /* We are assuming that there is only one master. So disable automatic arbitration */
mbed_official 525:c320967f86b9 125 obj->i2c.i2c->CTRL |= _I2C_CTRL_ARBDIS_MASK;
mbed_official 525:c320967f86b9 126
mbed_official 525:c320967f86b9 127 /* Enable i2c */
mbed_official 525:c320967f86b9 128 i2c_enable(obj, true);
mbed_official 525:c320967f86b9 129 }
mbed_official 525:c320967f86b9 130
mbed_official 525:c320967f86b9 131 void i2c_enable(i2c_t *obj, uint8_t enable)
mbed_official 525:c320967f86b9 132 {
mbed_official 525:c320967f86b9 133 I2C_Enable(obj->i2c.i2c, enable);
mbed_official 525:c320967f86b9 134 if (!enable) {
mbed_official 525:c320967f86b9 135 /* After a reset BUSY is usually set. We assume that we are the only master and call abort,
mbed_official 525:c320967f86b9 136 * which sends nothing on the bus, it just allows us to assume that the bus is idle */
mbed_official 525:c320967f86b9 137 if (obj->i2c.i2c->STATE & I2C_STATE_BUSY) {
mbed_official 525:c320967f86b9 138 obj->i2c.i2c->CMD = I2C_CMD_ABORT;
mbed_official 525:c320967f86b9 139 }
mbed_official 548:1abac31e188e 140
mbed_official 525:c320967f86b9 141 }
mbed_official 525:c320967f86b9 142 }
mbed_official 525:c320967f86b9 143
mbed_official 525:c320967f86b9 144 void i2c_enable_pins(i2c_t *obj, uint8_t enable)
mbed_official 525:c320967f86b9 145 {
mbed_official 525:c320967f86b9 146 if (enable) {
mbed_official 525:c320967f86b9 147 pin_mode(obj->i2c.scl, WiredAndPullUp);
mbed_official 525:c320967f86b9 148 pin_mode(obj->i2c.sda, WiredAndPullUp);
mbed_official 525:c320967f86b9 149 } else {
mbed_official 525:c320967f86b9 150 // TODO_LP return PinMode to the previous state
mbed_official 525:c320967f86b9 151 pin_mode(obj->i2c.sda, Disabled);
mbed_official 525:c320967f86b9 152 pin_mode(obj->i2c.scl, Disabled);
mbed_official 525:c320967f86b9 153 }
mbed_official 525:c320967f86b9 154 }
mbed_official 525:c320967f86b9 155
mbed_official 525:c320967f86b9 156 void i2c_enable_interrupt(i2c_t *obj, uint32_t address, uint8_t enable)
mbed_official 525:c320967f86b9 157 {
mbed_official 525:c320967f86b9 158 IRQn_Type irq_number;
mbed_official 525:c320967f86b9 159
mbed_official 525:c320967f86b9 160 switch (i2c_get_index(obj)) {
mbed_official 525:c320967f86b9 161 #ifdef I2C0
mbed_official 525:c320967f86b9 162 case 0:
mbed_official 525:c320967f86b9 163 irq_number = I2C0_IRQn;
mbed_official 525:c320967f86b9 164 break;
mbed_official 525:c320967f86b9 165 #endif
mbed_official 525:c320967f86b9 166 #ifdef I2C1
mbed_official 525:c320967f86b9 167 case 1:
mbed_official 525:c320967f86b9 168 irq_number = I2C1_IRQn;
mbed_official 525:c320967f86b9 169 break;
mbed_official 525:c320967f86b9 170 #endif
mbed_official 525:c320967f86b9 171 }
mbed_official 525:c320967f86b9 172
mbed_official 525:c320967f86b9 173 NVIC_SetVector(irq_number, address);
mbed_official 525:c320967f86b9 174 /* Lower IRQ priority to avoid messing with asynch RX on UART */
mbed_official 525:c320967f86b9 175 NVIC_SetPriority(irq_number, 1);
mbed_official 525:c320967f86b9 176 if (enable) {
mbed_official 525:c320967f86b9 177 NVIC_EnableIRQ(irq_number);
mbed_official 525:c320967f86b9 178 } else {
mbed_official 525:c320967f86b9 179 NVIC_DisableIRQ(irq_number);
mbed_official 525:c320967f86b9 180 }
mbed_official 525:c320967f86b9 181 }
mbed_official 525:c320967f86b9 182
mbed_official 525:c320967f86b9 183 /* Set the frequency of the I2C interface */
mbed_official 525:c320967f86b9 184 void i2c_frequency(i2c_t *obj, int hz)
mbed_official 525:c320967f86b9 185 {
mbed_official 525:c320967f86b9 186 /* Set frequency. As the second argument is 0,
mbed_official 525:c320967f86b9 187 * HFPER clock frequency is used as reference freq */
mbed_official 525:c320967f86b9 188 I2C_BusFreqSet(obj->i2c.i2c, REFERENCE_FREQUENCY, hz, i2cClockHLRStandard);
mbed_official 525:c320967f86b9 189 }
mbed_official 525:c320967f86b9 190
mbed_official 525:c320967f86b9 191 /* Creates a start condition on the I2C bus */
mbed_official 525:c320967f86b9 192 int i2c_start(i2c_t *obj)
mbed_official 525:c320967f86b9 193 {
mbed_official 525:c320967f86b9 194 I2C_TypeDef *i2c = obj->i2c.i2c;
mbed_official 525:c320967f86b9 195
mbed_official 525:c320967f86b9 196 /* Ensure buffers are empty */
mbed_official 525:c320967f86b9 197 i2c->CMD = I2C_CMD_CLEARPC | I2C_CMD_CLEARTX;
mbed_official 525:c320967f86b9 198 if (i2c->IF & I2C_IF_RXDATAV) {
mbed_official 525:c320967f86b9 199 (void) i2c->RXDATA;
mbed_official 525:c320967f86b9 200 }
mbed_official 525:c320967f86b9 201
mbed_official 525:c320967f86b9 202 /* Clear all pending interrupts prior to starting transfer. */
mbed_official 525:c320967f86b9 203 i2c->IFC = _I2C_IFC_MASK;
mbed_official 525:c320967f86b9 204
mbed_official 525:c320967f86b9 205 /* Send start */
mbed_official 525:c320967f86b9 206 obj->i2c.i2c->CMD = I2C_CMD_START;
mbed_official 525:c320967f86b9 207 return 0;
mbed_official 525:c320967f86b9 208 }
mbed_official 525:c320967f86b9 209
mbed_official 525:c320967f86b9 210 /* Creates a stop condition on the I2C bus */
mbed_official 525:c320967f86b9 211 int i2c_stop(i2c_t *obj)
mbed_official 525:c320967f86b9 212 {
mbed_official 525:c320967f86b9 213 obj->i2c.i2c->CMD = I2C_CMD_STOP;
mbed_official 525:c320967f86b9 214
mbed_official 525:c320967f86b9 215 /* Wait for the stop to be sent */
mbed_official 525:c320967f86b9 216 int timeout = I2C_TIMEOUT;
mbed_official 525:c320967f86b9 217 while (!(obj->i2c.i2c->IF & I2C_IF_MSTOP) && !timeout--);
mbed_official 525:c320967f86b9 218
mbed_official 525:c320967f86b9 219 return 0;
mbed_official 525:c320967f86b9 220 }
mbed_official 525:c320967f86b9 221
mbed_official 525:c320967f86b9 222 /* Returns number of bytes read */
mbed_official 525:c320967f86b9 223 int i2c_read(i2c_t *obj, int address, char *data, int length, int stop)
mbed_official 525:c320967f86b9 224 {
mbed_official 548:1abac31e188e 225 int retval;
mbed_official 525:c320967f86b9 226
mbed_official 525:c320967f86b9 227 i2c_start(obj);
mbed_official 525:c320967f86b9 228
mbed_official 525:c320967f86b9 229 retval = i2c_byte_write(obj, (address | 1));
mbed_official 525:c320967f86b9 230 if ((!retval) || (length == 0)) { //Write address with W flag (last bit 1)
mbed_official 548:1abac31e188e 231 obj->i2c.i2c->CMD = I2C_CMD_STOP | I2C_CMD_ABORT;
mbed_official 548:1abac31e188e 232 while(obj->i2c.i2c->STATE & I2C_STATE_BUSY); // Wait until the bus is done
mbed_official 525:c320967f86b9 233 return (retval == 0 ? I2C_ERROR_NO_SLAVE : 0); //NACK or error when writing adress. Return 0 as 0 bytes were read
mbed_official 525:c320967f86b9 234 }
mbed_official 525:c320967f86b9 235 int i = 0;
mbed_official 525:c320967f86b9 236 while (i < length) {
mbed_official 525:c320967f86b9 237 uint8_t last = (i == length - 1);
mbed_official 525:c320967f86b9 238 data[i++] = i2c_byte_read(obj, last);
mbed_official 525:c320967f86b9 239 }
mbed_official 525:c320967f86b9 240
mbed_official 525:c320967f86b9 241 if (stop) {
mbed_official 525:c320967f86b9 242 i2c_stop(obj);
mbed_official 525:c320967f86b9 243 }
mbed_official 525:c320967f86b9 244
mbed_official 525:c320967f86b9 245 return length;
mbed_official 525:c320967f86b9 246 }
mbed_official 525:c320967f86b9 247
mbed_official 525:c320967f86b9 248 int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop)
mbed_official 525:c320967f86b9 249 {
mbed_official 525:c320967f86b9 250 i2c_start(obj);
mbed_official 525:c320967f86b9 251
mbed_official 525:c320967f86b9 252 if (!i2c_byte_write(obj, (address & 0xFE))) {
mbed_official 525:c320967f86b9 253 i2c_stop(obj);
mbed_official 525:c320967f86b9 254 return I2C_ERROR_NO_SLAVE; //NACK or error when writing adress. Return 0 as 0 bytes were written
mbed_official 525:c320967f86b9 255 }
mbed_official 525:c320967f86b9 256 int i;
mbed_official 525:c320967f86b9 257 for (i = 0; i < length; i++) {
mbed_official 525:c320967f86b9 258 if (!i2c_byte_write(obj, data[i])) {
mbed_official 525:c320967f86b9 259 i2c_stop(obj);
mbed_official 525:c320967f86b9 260 return i;
mbed_official 525:c320967f86b9 261 }
mbed_official 525:c320967f86b9 262 }
mbed_official 525:c320967f86b9 263
mbed_official 525:c320967f86b9 264 if (stop) {
mbed_official 525:c320967f86b9 265 i2c_stop(obj);
mbed_official 525:c320967f86b9 266 }
mbed_official 525:c320967f86b9 267
mbed_official 525:c320967f86b9 268 return length;
mbed_official 525:c320967f86b9 269 }
mbed_official 525:c320967f86b9 270
mbed_official 525:c320967f86b9 271 void i2c_reset(i2c_t *obj)
mbed_official 525:c320967f86b9 272 {
mbed_official 525:c320967f86b9 273 /* EMLib function */
mbed_official 525:c320967f86b9 274 I2C_Reset(obj->i2c.i2c);
mbed_official 525:c320967f86b9 275 }
mbed_official 525:c320967f86b9 276
mbed_official 525:c320967f86b9 277 int i2c_byte_read(i2c_t *obj, int last)
mbed_official 525:c320967f86b9 278 {
mbed_official 525:c320967f86b9 279 int timeout = I2C_TIMEOUT;
mbed_official 525:c320967f86b9 280 /* Wait for data */
mbed_official 525:c320967f86b9 281 while (!(obj->i2c.i2c->STATUS & I2C_STATUS_RXDATAV) && timeout--);
mbed_official 525:c320967f86b9 282
mbed_official 525:c320967f86b9 283 if (timeout <= 0) {
mbed_official 525:c320967f86b9 284 return 0; //TODO Is this the correct way to handle this?
mbed_official 525:c320967f86b9 285 }
mbed_official 525:c320967f86b9 286 char data = obj->i2c.i2c->RXDATA;
mbed_official 525:c320967f86b9 287
mbed_official 525:c320967f86b9 288 if (last) {
mbed_official 525:c320967f86b9 289 obj->i2c.i2c->CMD = I2C_CMD_NACK;
mbed_official 525:c320967f86b9 290 } else {
mbed_official 525:c320967f86b9 291 obj->i2c.i2c->CMD = I2C_CMD_ACK;
mbed_official 525:c320967f86b9 292 }
mbed_official 525:c320967f86b9 293 return data;
mbed_official 525:c320967f86b9 294 }
mbed_official 525:c320967f86b9 295
mbed_official 525:c320967f86b9 296 int i2c_byte_write(i2c_t *obj, int data)
mbed_official 525:c320967f86b9 297 {
mbed_official 525:c320967f86b9 298 obj->i2c.i2c->TXDATA = data;
mbed_official 525:c320967f86b9 299 return block_and_wait_for_ack(obj->i2c.i2c);
mbed_official 525:c320967f86b9 300 }
mbed_official 525:c320967f86b9 301
mbed_official 525:c320967f86b9 302 /*
mbed_official 525:c320967f86b9 303 * Returns 1 for ACK. 0 for NACK, timeout or error.
mbed_official 525:c320967f86b9 304 */
mbed_official 525:c320967f86b9 305 int block_and_wait_for_ack(I2C_TypeDef *i2c)
mbed_official 525:c320967f86b9 306 {
mbed_official 525:c320967f86b9 307 uint32_t pending;
mbed_official 525:c320967f86b9 308 uint32_t timeout = I2C_TIMEOUT;
mbed_official 525:c320967f86b9 309 while (timeout > 0) {
mbed_official 525:c320967f86b9 310 timeout -= 1;
mbed_official 525:c320967f86b9 311 pending = i2c->IF;
mbed_official 525:c320967f86b9 312 /* If some sort of fault, abort transfer. */
mbed_official 525:c320967f86b9 313 if (pending & I2C_IF_ERRORS) {
mbed_official 525:c320967f86b9 314 if (pending & I2C_IF_ARBLOST) {
mbed_official 525:c320967f86b9 315 /* If arbitration fault, it indicates either a slave device */
mbed_official 525:c320967f86b9 316 /* not responding as expected, or other master which is not */
mbed_official 525:c320967f86b9 317 /* supported by this SW. */
mbed_official 525:c320967f86b9 318 return 0;
mbed_official 525:c320967f86b9 319 } else if (pending & I2C_IF_BUSERR) {
mbed_official 525:c320967f86b9 320 /* A bus error indicates a misplaced start or stop, which should */
mbed_official 525:c320967f86b9 321 /* not occur in master mode controlled by this SW. */
mbed_official 525:c320967f86b9 322 return 0;
mbed_official 525:c320967f86b9 323 }
mbed_official 525:c320967f86b9 324 }
mbed_official 525:c320967f86b9 325
mbed_official 525:c320967f86b9 326 if (pending & I2C_IF_NACK) {
mbed_official 525:c320967f86b9 327 i2c->IFC = I2C_IFC_NACK;
mbed_official 525:c320967f86b9 328 return 0; //Received NACK
mbed_official 525:c320967f86b9 329 } else if (pending & I2C_IF_ACK) {
mbed_official 525:c320967f86b9 330 i2c->IFC = I2C_IFC_ACK;
mbed_official 525:c320967f86b9 331 return 1; //Got ACK
mbed_official 525:c320967f86b9 332 }
mbed_official 525:c320967f86b9 333 }
mbed_official 525:c320967f86b9 334 return 0; //Timeout
mbed_official 525:c320967f86b9 335 }
mbed_official 525:c320967f86b9 336
mbed_official 525:c320967f86b9 337 #if DEVICE_I2CSLAVE
mbed_official 525:c320967f86b9 338
mbed_official 525:c320967f86b9 339 #define NoData 0
mbed_official 525:c320967f86b9 340 #define ReadAddressed 1
mbed_official 525:c320967f86b9 341 #define WriteGeneral 2
mbed_official 525:c320967f86b9 342 #define WriteAddressed 3
mbed_official 525:c320967f86b9 343
mbed_official 525:c320967f86b9 344
mbed_official 525:c320967f86b9 345 void i2c_slave_mode(i2c_t *obj, int enable_slave)
mbed_official 525:c320967f86b9 346 {
mbed_official 548:1abac31e188e 347 if(enable_slave) {
mbed_official 525:c320967f86b9 348 obj->i2c.i2c->CTRL |= _I2C_CTRL_SLAVE_MASK;
mbed_official 525:c320967f86b9 349 obj->i2c.i2c->CTRL |= _I2C_CTRL_AUTOACK_MASK; //Slave implementation assumes auto acking
mbed_official 548:1abac31e188e 350 } else {
mbed_official 525:c320967f86b9 351 obj->i2c.i2c->CTRL &= ~_I2C_CTRL_SLAVE_MASK;
mbed_official 525:c320967f86b9 352 obj->i2c.i2c->CTRL &= ~_I2C_CTRL_AUTOACK_MASK; //Master implementation ACKs manually
mbed_official 525:c320967f86b9 353 }
mbed_official 525:c320967f86b9 354 }
mbed_official 525:c320967f86b9 355
mbed_official 525:c320967f86b9 356 int i2c_slave_receive(i2c_t *obj)
mbed_official 525:c320967f86b9 357 {
mbed_official 525:c320967f86b9 358
mbed_official 548:1abac31e188e 359 if(obj->i2c.i2c->IF & I2C_IF_ADDR) {
mbed_official 525:c320967f86b9 360 obj->i2c.i2c->IFC = I2C_IF_ADDR; //Clear interrupt
mbed_official 525:c320967f86b9 361 /*0x00 is the address for general write.
mbed_official 525:c320967f86b9 362 The address the master wrote is in RXDATA now
mbed_official 525:c320967f86b9 363 and reading it also frees the buffer for the next
mbed_official 525:c320967f86b9 364 write which can then be acked. */
mbed_official 548:1abac31e188e 365 if(obj->i2c.i2c->RXDATA == 0x00) {
mbed_official 525:c320967f86b9 366 return WriteGeneral; //Read the address;
mbed_official 525:c320967f86b9 367 }
mbed_official 525:c320967f86b9 368
mbed_official 548:1abac31e188e 369 if(obj->i2c.i2c->STATE & I2C_STATE_TRANSMITTER) {
mbed_official 525:c320967f86b9 370 return ReadAddressed;
mbed_official 548:1abac31e188e 371 } else {
mbed_official 525:c320967f86b9 372 return WriteAddressed;
mbed_official 525:c320967f86b9 373 }
mbed_official 525:c320967f86b9 374 }
mbed_official 525:c320967f86b9 375
mbed_official 525:c320967f86b9 376 return NoData;
mbed_official 525:c320967f86b9 377
mbed_official 525:c320967f86b9 378 }
mbed_official 525:c320967f86b9 379
mbed_official 525:c320967f86b9 380 int i2c_slave_read(i2c_t *obj, char *data, int length)
mbed_official 525:c320967f86b9 381 {
mbed_official 525:c320967f86b9 382 int count;
mbed_official 525:c320967f86b9 383 for (count = 0; count < length; count++) {
mbed_official 525:c320967f86b9 384 data[count] = i2c_byte_read(obj, 0);
mbed_official 525:c320967f86b9 385 }
mbed_official 548:1abac31e188e 386
mbed_official 525:c320967f86b9 387
mbed_official 525:c320967f86b9 388 return count;
mbed_official 525:c320967f86b9 389
mbed_official 525:c320967f86b9 390 }
mbed_official 525:c320967f86b9 391
mbed_official 525:c320967f86b9 392 int i2c_slave_write(i2c_t *obj, const char *data, int length)
mbed_official 525:c320967f86b9 393 {
mbed_official 525:c320967f86b9 394 int count;
mbed_official 525:c320967f86b9 395 for (count = 0; count < length; count++) {
mbed_official 525:c320967f86b9 396 i2c_byte_write(obj, data[count]);
mbed_official 525:c320967f86b9 397 }
mbed_official 525:c320967f86b9 398
mbed_official 525:c320967f86b9 399 return count;
mbed_official 525:c320967f86b9 400 }
mbed_official 525:c320967f86b9 401
mbed_official 525:c320967f86b9 402 void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask)
mbed_official 525:c320967f86b9 403 {
mbed_official 525:c320967f86b9 404 obj->i2c.i2c->SADDR = address;
mbed_official 525:c320967f86b9 405 obj->i2c.i2c->SADDRMASK = 0xFE;//mask;
mbed_official 525:c320967f86b9 406 }
mbed_official 525:c320967f86b9 407
mbed_official 525:c320967f86b9 408 #endif //DEVICE_I2CSLAVE
mbed_official 525:c320967f86b9 409
mbed_official 525:c320967f86b9 410 #ifdef DEVICE_I2C_ASYNCH
mbed_official 525:c320967f86b9 411
mbed_official 525:c320967f86b9 412 #include "em_dma.h"
mbed_official 525:c320967f86b9 413 #include "dma_api_HAL.h"
mbed_official 525:c320967f86b9 414 #include "dma_api.h"
mbed_official 525:c320967f86b9 415 #include "sleep_api.h"
mbed_official 525:c320967f86b9 416 #include "buffer.h"
mbed_official 525:c320967f86b9 417
mbed_official 525:c320967f86b9 418 /** Start i2c asynchronous transfer.
mbed_official 525:c320967f86b9 419 * @param obj The I2C object
mbed_official 525:c320967f86b9 420 * @param tx The buffer to send
mbed_official 525:c320967f86b9 421 * @param tx_length The number of words to transmit
mbed_official 525:c320967f86b9 422 * @param rx The buffer to receive
mbed_official 525:c320967f86b9 423 * @param rx_length The number of words to receive
mbed_official 525:c320967f86b9 424 * @param address The address to be set - 7bit or 9 bit
mbed_official 525:c320967f86b9 425 * @param stop If true, stop will be generated after the transfer is done
mbed_official 525:c320967f86b9 426 * @param handler The I2C IRQ handler to be set
mbed_official 525:c320967f86b9 427 * @param hint DMA hint usage
mbed_official 525:c320967f86b9 428 */
mbed_official 563:536c9fb088a0 429 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)
mbed_official 548:1abac31e188e 430 {
mbed_official 548:1abac31e188e 431 I2C_TransferReturn_TypeDef retval;
mbed_official 548:1abac31e188e 432 if(i2c_active(obj)) return;
mbed_official 525:c320967f86b9 433 if((tx_length == 0) && (rx_length == 0)) return;
mbed_official 548:1abac31e188e 434 // For now, we are assuming a solely interrupt-driven implementation.
mbed_official 525:c320967f86b9 435
mbed_official 548:1abac31e188e 436 // Store transfer config
mbed_official 548:1abac31e188e 437 obj->i2c.xfer.addr = address;
mbed_official 525:c320967f86b9 438
mbed_official 548:1abac31e188e 439 // Some combination of tx_length and rx_length will tell us what to do
mbed_official 548:1abac31e188e 440 if((tx_length > 0) && (rx_length == 0)) {
mbed_official 548:1abac31e188e 441 obj->i2c.xfer.flags = I2C_FLAG_WRITE;
mbed_official 548:1abac31e188e 442 //Store buffer info
mbed_official 563:536c9fb088a0 443 obj->i2c.xfer.buf[0].data = (void *)tx;
mbed_official 548:1abac31e188e 444 obj->i2c.xfer.buf[0].len = (uint16_t) tx_length;
mbed_official 548:1abac31e188e 445 } else if ((tx_length == 0) && (rx_length > 0)) {
mbed_official 548:1abac31e188e 446 obj->i2c.xfer.flags = I2C_FLAG_READ;
mbed_official 548:1abac31e188e 447 //Store buffer info
mbed_official 548:1abac31e188e 448 obj->i2c.xfer.buf[0].data = rx;
mbed_official 548:1abac31e188e 449 obj->i2c.xfer.buf[0].len = (uint16_t) rx_length;
mbed_official 548:1abac31e188e 450 } else if ((tx_length > 0) && (rx_length > 0)) {
mbed_official 548:1abac31e188e 451 obj->i2c.xfer.flags = I2C_FLAG_WRITE_READ;
mbed_official 548:1abac31e188e 452 //Store buffer info
mbed_official 563:536c9fb088a0 453 obj->i2c.xfer.buf[0].data = (void *)tx;
mbed_official 548:1abac31e188e 454 obj->i2c.xfer.buf[0].len = (uint16_t) tx_length;
mbed_official 548:1abac31e188e 455 obj->i2c.xfer.buf[1].data = rx;
mbed_official 548:1abac31e188e 456 obj->i2c.xfer.buf[1].len = (uint16_t) rx_length;
mbed_official 548:1abac31e188e 457 }
mbed_official 525:c320967f86b9 458
mbed_official 548:1abac31e188e 459 if(address > 255) obj->i2c.xfer.flags |= I2C_FLAG_10BIT_ADDR;
mbed_official 525:c320967f86b9 460
mbed_official 548:1abac31e188e 461 // Store event flags
mbed_official 548:1abac31e188e 462 obj->i2c.events = event;
mbed_official 525:c320967f86b9 463
mbed_official 548:1abac31e188e 464 // Enable interrupt
mbed_official 548:1abac31e188e 465 i2c_enable_interrupt(obj, handler, true);
mbed_official 525:c320967f86b9 466
mbed_official 548:1abac31e188e 467 // Kick off the transfer
mbed_official 548:1abac31e188e 468 retval = I2C_TransferInit(obj->i2c.i2c, &(obj->i2c.xfer));
mbed_official 525:c320967f86b9 469
mbed_official 548:1abac31e188e 470 if(retval == i2cTransferInProgress) {
mbed_official 548:1abac31e188e 471 blockSleepMode(EM1);
mbed_official 548:1abac31e188e 472 } else {
mbed_official 548:1abac31e188e 473 // something happened, and the transfer did not go through
mbed_official 548:1abac31e188e 474 // So, we need to clean up
mbed_official 525:c320967f86b9 475
mbed_official 548:1abac31e188e 476 // Disable interrupt
mbed_official 548:1abac31e188e 477 i2c_enable_interrupt(obj, 0, false);
mbed_official 525:c320967f86b9 478
mbed_official 548:1abac31e188e 479 // Block until free
mbed_official 548:1abac31e188e 480 while(i2c_active(obj));
mbed_official 548:1abac31e188e 481 }
mbed_official 525:c320967f86b9 482 }
mbed_official 525:c320967f86b9 483
mbed_official 525:c320967f86b9 484 /** The asynchronous IRQ handler
mbed_official 525:c320967f86b9 485 * @param obj The I2C object which holds the transfer information
mbed_official 525:c320967f86b9 486 * @return Returns event flags if a transfer termination condition was met or 0 otherwise.
mbed_official 525:c320967f86b9 487 */
mbed_official 548:1abac31e188e 488 uint32_t i2c_irq_handler_asynch(i2c_t *obj)
mbed_official 548:1abac31e188e 489 {
mbed_official 525:c320967f86b9 490
mbed_official 548:1abac31e188e 491 // For now, we are assuming a solely interrupt-driven implementation.
mbed_official 525:c320967f86b9 492
mbed_official 548:1abac31e188e 493 I2C_TransferReturn_TypeDef status = I2C_Transfer(obj->i2c.i2c);
mbed_official 548:1abac31e188e 494 switch(status) {
mbed_official 548:1abac31e188e 495 case i2cTransferInProgress:
mbed_official 548:1abac31e188e 496 // Still busy transferring, so let it.
mbed_official 548:1abac31e188e 497 return 0;
mbed_official 548:1abac31e188e 498 case i2cTransferDone:
mbed_official 548:1abac31e188e 499 // Transfer has completed
mbed_official 525:c320967f86b9 500
mbed_official 548:1abac31e188e 501 // Disable interrupt
mbed_official 548:1abac31e188e 502 i2c_enable_interrupt(obj, 0, false);
mbed_official 525:c320967f86b9 503
mbed_official 548:1abac31e188e 504 unblockSleepMode(EM1);
mbed_official 525:c320967f86b9 505
mbed_official 548:1abac31e188e 506 return I2C_EVENT_TRANSFER_COMPLETE & obj->i2c.events;
mbed_official 548:1abac31e188e 507 case i2cTransferNack:
mbed_official 548:1abac31e188e 508 // A NACK has been received while an ACK was expected. This is usually because the slave did not respond to the address.
mbed_official 548:1abac31e188e 509 // Disable interrupt
mbed_official 548:1abac31e188e 510 i2c_enable_interrupt(obj, 0, false);
mbed_official 525:c320967f86b9 511
mbed_official 548:1abac31e188e 512 unblockSleepMode(EM1);
mbed_official 525:c320967f86b9 513
mbed_official 548:1abac31e188e 514 return I2C_EVENT_ERROR_NO_SLAVE & obj->i2c.events;
mbed_official 548:1abac31e188e 515 default:
mbed_official 548:1abac31e188e 516 // An error situation has arisen.
mbed_official 548:1abac31e188e 517 // Disable interrupt
mbed_official 548:1abac31e188e 518 i2c_enable_interrupt(obj, 0, false);
mbed_official 525:c320967f86b9 519
mbed_official 548:1abac31e188e 520 unblockSleepMode(EM1);
mbed_official 525:c320967f86b9 521
mbed_official 548:1abac31e188e 522 // return error
mbed_official 548:1abac31e188e 523 return I2C_EVENT_ERROR & obj->i2c.events;
mbed_official 548:1abac31e188e 524 }
mbed_official 525:c320967f86b9 525 }
mbed_official 525:c320967f86b9 526
mbed_official 525:c320967f86b9 527 /** Attempts to determine if I2C peripheral is already in use.
mbed_official 525:c320967f86b9 528 * @param obj The I2C object
mbed_official 525:c320967f86b9 529 * @return non-zero if the I2C module is active or zero if it is not
mbed_official 525:c320967f86b9 530 */
mbed_official 548:1abac31e188e 531 uint8_t i2c_active(i2c_t *obj)
mbed_official 548:1abac31e188e 532 {
mbed_official 548:1abac31e188e 533 return (obj->i2c.i2c->STATE & I2C_STATE_BUSY);
mbed_official 525:c320967f86b9 534 }
mbed_official 525:c320967f86b9 535
mbed_official 525:c320967f86b9 536 /** Abort ongoing asynchronous transaction.
mbed_official 525:c320967f86b9 537 * @param obj The I2C object
mbed_official 525:c320967f86b9 538 */
mbed_official 548:1abac31e188e 539 void i2c_abort_asynch(i2c_t *obj)
mbed_official 548:1abac31e188e 540 {
mbed_official 548:1abac31e188e 541 // Do not deactivate I2C twice
mbed_official 548:1abac31e188e 542 if (!i2c_active(obj)) return;
mbed_official 525:c320967f86b9 543
mbed_official 548:1abac31e188e 544 // Disable interrupt
mbed_official 548:1abac31e188e 545 i2c_enable_interrupt(obj, 0, false);
mbed_official 525:c320967f86b9 546
mbed_official 548:1abac31e188e 547 // Abort
mbed_official 548:1abac31e188e 548 obj->i2c.i2c->CMD = I2C_CMD_STOP | I2C_CMD_ABORT;
mbed_official 525:c320967f86b9 549
mbed_official 548:1abac31e188e 550 // Block until free
mbed_official 548:1abac31e188e 551 while(i2c_active(obj));
mbed_official 525:c320967f86b9 552
mbed_official 548:1abac31e188e 553 unblockSleepMode(EM1);
mbed_official 525:c320967f86b9 554 }
mbed_official 525:c320967f86b9 555
mbed_official 525:c320967f86b9 556 #endif //DEVICE_I2C ASYNCH
mbed_official 525:c320967f86b9 557 #endif //DEVICE_I2C