mbed library sources

Fork of mbed-src by mbed official

Committer:
mbed_official
Date:
Wed Aug 27 08:45:06 2014 +0100
Revision:
300:55638feb26a4
Parent:
270:e2babe29baf8
Child:
314:b682143dd337
Synchronized with git revision 90467175c04ad81c20cdf7b2ddb86c54f5f3dcbb

Full URL: https://github.com/mbedmicro/mbed/commit/90467175c04ad81c20cdf7b2ddb86c54f5f3dcbb/

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 85:e1a8e879a6a9 1 /* mbed Microcontroller Library
mbed_official 104:a6a92e2e5a92 2 * Copyright (c) 2013 Nordic Semiconductor
mbed_official 85:e1a8e879a6a9 3 *
mbed_official 85:e1a8e879a6a9 4 * Licensed under the Apache License, Version 2.0 (the "License");
mbed_official 85:e1a8e879a6a9 5 * you may not use this file except in compliance with the License.
mbed_official 85:e1a8e879a6a9 6 * You may obtain a copy of the License at
mbed_official 85:e1a8e879a6a9 7 *
mbed_official 85:e1a8e879a6a9 8 * http://www.apache.org/licenses/LICENSE-2.0
mbed_official 85:e1a8e879a6a9 9 *
mbed_official 85:e1a8e879a6a9 10 * Unless required by applicable law or agreed to in writing, software
mbed_official 85:e1a8e879a6a9 11 * distributed under the License is distributed on an "AS IS" BASIS,
mbed_official 85:e1a8e879a6a9 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
mbed_official 85:e1a8e879a6a9 13 * See the License for the specific language governing permissions and
mbed_official 85:e1a8e879a6a9 14 * limitations under the License.
mbed_official 85:e1a8e879a6a9 15 */
mbed_official 227:7bd0639b8911 16 #include "mbed_assert.h"
mbed_official 85:e1a8e879a6a9 17 #include "i2c_api.h"
mbed_official 85:e1a8e879a6a9 18 #include "cmsis.h"
mbed_official 85:e1a8e879a6a9 19 #include "pinmap.h"
mbed_official 85:e1a8e879a6a9 20
mbed_official 85:e1a8e879a6a9 21 static const PinMap PinMap_I2C_SDA[] = {
mbed_official 85:e1a8e879a6a9 22 {p22, I2C_0, 1},
mbed_official 85:e1a8e879a6a9 23 {p13, I2C_1, 2},
mbed_official 300:55638feb26a4 24 {NC, NC, 0}
mbed_official 85:e1a8e879a6a9 25 };
mbed_official 85:e1a8e879a6a9 26
mbed_official 85:e1a8e879a6a9 27 static const PinMap PinMap_I2C_SCL[] = {
mbed_official 85:e1a8e879a6a9 28 {p20, I2C_0, 1},
mbed_official 85:e1a8e879a6a9 29 {p15, I2C_1, 2},
mbed_official 300:55638feb26a4 30 {NC, NC, 0}
mbed_official 85:e1a8e879a6a9 31 };
mbed_official 85:e1a8e879a6a9 32
mbed_official 300:55638feb26a4 33 uint8_t addrSet = 0;
mbed_official 85:e1a8e879a6a9 34
mbed_official 300:55638feb26a4 35 void i2c_interface_enable(i2c_t *obj)
mbed_official 300:55638feb26a4 36 {
mbed_official 85:e1a8e879a6a9 37 obj->i2c->ENABLE = (TWI_ENABLE_ENABLE_Enabled << TWI_ENABLE_ENABLE_Pos);
mbed_official 85:e1a8e879a6a9 38 }
mbed_official 85:e1a8e879a6a9 39
mbed_official 300:55638feb26a4 40 void twi_master_init(i2c_t *obj, PinName sda, PinName scl, int frequency)
mbed_official 300:55638feb26a4 41 {
mbed_official 300:55638feb26a4 42 NRF_GPIO->PIN_CNF[scl] = ((GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos) |
mbed_official 300:55638feb26a4 43 (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) |
mbed_official 300:55638feb26a4 44 (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos) |
mbed_official 300:55638feb26a4 45 (GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos) |
mbed_official 300:55638feb26a4 46 (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos));
mbed_official 85:e1a8e879a6a9 47
mbed_official 300:55638feb26a4 48 NRF_GPIO->PIN_CNF[sda] = ((GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos) |
mbed_official 300:55638feb26a4 49 (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) |
mbed_official 300:55638feb26a4 50 (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos) |
mbed_official 300:55638feb26a4 51 (GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos) |
mbed_official 300:55638feb26a4 52 (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos));
mbed_official 85:e1a8e879a6a9 53
mbed_official 300:55638feb26a4 54 obj->i2c->PSELSCL = scl;
mbed_official 300:55638feb26a4 55 obj->i2c->PSELSDA = sda;
mbed_official 85:e1a8e879a6a9 56 // set default frequency at 100k
mbed_official 85:e1a8e879a6a9 57 i2c_frequency(obj, frequency);
mbed_official 85:e1a8e879a6a9 58 i2c_interface_enable(obj);
mbed_official 85:e1a8e879a6a9 59 }
mbed_official 300:55638feb26a4 60
mbed_official 300:55638feb26a4 61 void i2c_init(i2c_t *obj, PinName sda, PinName scl)
mbed_official 300:55638feb26a4 62 {
mbed_official 85:e1a8e879a6a9 63 // determine the SPI to use
mbed_official 85:e1a8e879a6a9 64 I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA);
mbed_official 85:e1a8e879a6a9 65 I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL);
mbed_official 300:55638feb26a4 66 I2CName i2c = (I2CName)pinmap_merge(i2c_sda, i2c_scl);
mbed_official 300:55638feb26a4 67 obj->i2c = (NRF_TWI_Type *)i2c;
mbed_official 300:55638feb26a4 68
mbed_official 227:7bd0639b8911 69 MBED_ASSERT((int)obj->i2c != NC);
mbed_official 85:e1a8e879a6a9 70
mbed_official 300:55638feb26a4 71 obj->scl = scl;
mbed_official 300:55638feb26a4 72 obj->sda = sda;
mbed_official 85:e1a8e879a6a9 73 obj->i2c->EVENTS_ERROR = 0;
mbed_official 227:7bd0639b8911 74 obj->i2c->ENABLE = TWI_ENABLE_ENABLE_Disabled << TWI_ENABLE_ENABLE_Pos;
mbed_official 227:7bd0639b8911 75 obj->i2c->POWER = 0;
mbed_official 300:55638feb26a4 76
mbed_official 300:55638feb26a4 77 for (int i = 0; i<100; i++) {
mbed_official 85:e1a8e879a6a9 78 }
mbed_official 300:55638feb26a4 79
mbed_official 300:55638feb26a4 80 obj->i2c->POWER = 1;
mbed_official 300:55638feb26a4 81 twi_master_init(obj, sda, scl, 100000);
mbed_official 85:e1a8e879a6a9 82 }
mbed_official 300:55638feb26a4 83
mbed_official 300:55638feb26a4 84 void i2c_reset(i2c_t *obj)
mbed_official 300:55638feb26a4 85 {
mbed_official 85:e1a8e879a6a9 86 obj->i2c->EVENTS_ERROR = 0;
mbed_official 227:7bd0639b8911 87 obj->i2c->ENABLE = TWI_ENABLE_ENABLE_Disabled << TWI_ENABLE_ENABLE_Pos;
mbed_official 227:7bd0639b8911 88 obj->i2c->POWER = 0;
mbed_official 300:55638feb26a4 89 for (int i = 0; i<100; i++) {
mbed_official 85:e1a8e879a6a9 90 }
mbed_official 300:55638feb26a4 91
mbed_official 300:55638feb26a4 92 obj->i2c->POWER = 1;
mbed_official 300:55638feb26a4 93 twi_master_init(obj, obj->sda, obj->scl, obj->freq);
mbed_official 85:e1a8e879a6a9 94 }
mbed_official 85:e1a8e879a6a9 95
mbed_official 300:55638feb26a4 96 int i2c_start(i2c_t *obj)
mbed_official 300:55638feb26a4 97 {
mbed_official 85:e1a8e879a6a9 98 int status = 0;
mbed_official 85:e1a8e879a6a9 99 i2c_reset(obj);
mbed_official 300:55638feb26a4 100 addrSet = 0;
mbed_official 85:e1a8e879a6a9 101 return status;
mbed_official 85:e1a8e879a6a9 102 }
mbed_official 85:e1a8e879a6a9 103
mbed_official 300:55638feb26a4 104 int i2c_stop(i2c_t *obj)
mbed_official 300:55638feb26a4 105 {
mbed_official 85:e1a8e879a6a9 106 int timeOut = 100000;
mbed_official 85:e1a8e879a6a9 107 obj->i2c->EVENTS_STOPPED = 0;
mbed_official 85:e1a8e879a6a9 108 // write the stop bit
mbed_official 85:e1a8e879a6a9 109 obj->i2c->TASKS_STOP = 1;
mbed_official 300:55638feb26a4 110 while (!obj->i2c->EVENTS_STOPPED) {
mbed_official 85:e1a8e879a6a9 111 timeOut--;
mbed_official 300:55638feb26a4 112 if (timeOut<0) {
mbed_official 85:e1a8e879a6a9 113 return 1;
mbed_official 300:55638feb26a4 114 }
mbed_official 227:7bd0639b8911 115 }
mbed_official 85:e1a8e879a6a9 116 addrSet = 0;
mbed_official 85:e1a8e879a6a9 117 i2c_reset(obj);
mbed_official 85:e1a8e879a6a9 118 return 0;
mbed_official 85:e1a8e879a6a9 119 }
mbed_official 85:e1a8e879a6a9 120
mbed_official 300:55638feb26a4 121 int i2c_do_write(i2c_t *obj, int value)
mbed_official 300:55638feb26a4 122 {
mbed_official 85:e1a8e879a6a9 123 int timeOut = 100000;
mbed_official 85:e1a8e879a6a9 124 obj->i2c->TXD = value;
mbed_official 300:55638feb26a4 125 while (!obj->i2c->EVENTS_TXDSENT) {
mbed_official 85:e1a8e879a6a9 126 timeOut--;
mbed_official 300:55638feb26a4 127 if (timeOut<0) {
mbed_official 85:e1a8e879a6a9 128 return 1;
mbed_official 300:55638feb26a4 129 }
mbed_official 85:e1a8e879a6a9 130 }
mbed_official 227:7bd0639b8911 131 obj->i2c->EVENTS_TXDSENT = 0;
mbed_official 85:e1a8e879a6a9 132 return 0;
mbed_official 85:e1a8e879a6a9 133 }
mbed_official 85:e1a8e879a6a9 134
mbed_official 300:55638feb26a4 135 int i2c_do_read(i2c_t *obj, char *data, int last)
mbed_official 300:55638feb26a4 136 {
mbed_official 85:e1a8e879a6a9 137 int timeOut = 100000;
mbed_official 177:d57c40a064c8 138
mbed_official 300:55638feb26a4 139 if (last) {
mbed_official 177:d57c40a064c8 140 obj->i2c->TASKS_STOP = 1;
mbed_official 177:d57c40a064c8 141 }
mbed_official 300:55638feb26a4 142 while (!obj->i2c->EVENTS_RXDREADY) {
mbed_official 85:e1a8e879a6a9 143 timeOut--;
mbed_official 300:55638feb26a4 144 if (timeOut<0) {
mbed_official 85:e1a8e879a6a9 145 return 1;
mbed_official 300:55638feb26a4 146 }
mbed_official 85:e1a8e879a6a9 147 }
mbed_official 300:55638feb26a4 148 obj->i2c->EVENTS_RXDREADY = 0;
mbed_official 300:55638feb26a4 149
mbed_official 85:e1a8e879a6a9 150 *data = obj->i2c->RXD;
mbed_official 300:55638feb26a4 151
mbed_official 300:55638feb26a4 152 for (int i = 0; i<320; i++) {
mbed_official 85:e1a8e879a6a9 153 }
mbed_official 300:55638feb26a4 154
mbed_official 85:e1a8e879a6a9 155 obj->i2c->TASKS_RESUME = 1;
mbed_official 300:55638feb26a4 156
mbed_official 85:e1a8e879a6a9 157 return 0;
mbed_official 85:e1a8e879a6a9 158 }
mbed_official 85:e1a8e879a6a9 159
mbed_official 300:55638feb26a4 160 void i2c_frequency(i2c_t *obj, int hz)
mbed_official 300:55638feb26a4 161 {
mbed_official 300:55638feb26a4 162 if (hz<250000) {
mbed_official 85:e1a8e879a6a9 163 obj->freq = 100000;
mbed_official 85:e1a8e879a6a9 164 obj->i2c->FREQUENCY = (TWI_FREQUENCY_FREQUENCY_K100 << TWI_FREQUENCY_FREQUENCY_Pos);
mbed_official 300:55638feb26a4 165 } else if (hz<400000) {
mbed_official 85:e1a8e879a6a9 166 obj->freq = 250000;
mbed_official 85:e1a8e879a6a9 167 obj->i2c->FREQUENCY = (TWI_FREQUENCY_FREQUENCY_K250 << TWI_FREQUENCY_FREQUENCY_Pos);
mbed_official 300:55638feb26a4 168 } else {
mbed_official 85:e1a8e879a6a9 169 obj->freq = 400000;
mbed_official 85:e1a8e879a6a9 170 obj->i2c->FREQUENCY = (TWI_FREQUENCY_FREQUENCY_K400 << TWI_FREQUENCY_FREQUENCY_Pos);
mbed_official 85:e1a8e879a6a9 171 }
mbed_official 85:e1a8e879a6a9 172 }
mbed_official 85:e1a8e879a6a9 173
mbed_official 300:55638feb26a4 174 int checkError(i2c_t *obj)
mbed_official 300:55638feb26a4 175 {
mbed_official 300:55638feb26a4 176 if (obj->i2c->EVENTS_ERROR == 1) {
mbed_official 300:55638feb26a4 177 if (obj->i2c->ERRORSRC & TWI_ERRORSRC_ANACK_Msk) {
mbed_official 300:55638feb26a4 178 obj->i2c->EVENTS_ERROR = 0;
mbed_official 300:55638feb26a4 179 obj->i2c->TASKS_STOP = 1;
mbed_official 85:e1a8e879a6a9 180 return I2C_ERROR_BUS_BUSY;
mbed_official 85:e1a8e879a6a9 181 }
mbed_official 300:55638feb26a4 182
mbed_official 300:55638feb26a4 183 obj->i2c->EVENTS_ERROR = 0;
mbed_official 300:55638feb26a4 184 obj->i2c->TASKS_STOP = 1;
mbed_official 227:7bd0639b8911 185 return I2C_ERROR_NO_SLAVE;
mbed_official 227:7bd0639b8911 186 }
mbed_official 85:e1a8e879a6a9 187 return 0;
mbed_official 85:e1a8e879a6a9 188 }
mbed_official 85:e1a8e879a6a9 189
mbed_official 300:55638feb26a4 190 int i2c_read(i2c_t *obj, int address, char *data, int length, int stop)
mbed_official 300:55638feb26a4 191 {
mbed_official 300:55638feb26a4 192 int status, count, errorResult;
mbed_official 300:55638feb26a4 193 obj->i2c->ADDRESS = (address >> 1);
mbed_official 85:e1a8e879a6a9 194 obj->i2c->SHORTS = 0;
mbed_official 85:e1a8e879a6a9 195 obj->i2c->EVENTS_RXDREADY = 0;
mbed_official 85:e1a8e879a6a9 196 obj->i2c->TASKS_STARTRX = 1;
mbed_official 300:55638feb26a4 197
mbed_official 85:e1a8e879a6a9 198 // Read in all except last byte
mbed_official 85:e1a8e879a6a9 199 for (count = 0; count < (length - 1); count++) {
mbed_official 300:55638feb26a4 200 status = i2c_do_read(obj, &data[count], 0);
mbed_official 227:7bd0639b8911 201 if (status) {
mbed_official 85:e1a8e879a6a9 202 errorResult = checkError(obj);
mbed_official 85:e1a8e879a6a9 203 i2c_reset(obj);
mbed_official 300:55638feb26a4 204 if (errorResult<0) {
mbed_official 85:e1a8e879a6a9 205 return errorResult;
mbed_official 85:e1a8e879a6a9 206 }
mbed_official 85:e1a8e879a6a9 207 return count;
mbed_official 85:e1a8e879a6a9 208 }
mbed_official 85:e1a8e879a6a9 209 }
mbed_official 85:e1a8e879a6a9 210
mbed_official 85:e1a8e879a6a9 211 // read in last byte
mbed_official 300:55638feb26a4 212 status = i2c_do_read(obj, &data[length - 1], 1);
mbed_official 85:e1a8e879a6a9 213 if (status) {
mbed_official 85:e1a8e879a6a9 214 i2c_reset(obj);
mbed_official 85:e1a8e879a6a9 215 return length - 1;
mbed_official 85:e1a8e879a6a9 216 }
mbed_official 85:e1a8e879a6a9 217 // If not repeated start, send stop.
mbed_official 85:e1a8e879a6a9 218 if (stop) {
mbed_official 300:55638feb26a4 219 while (!obj->i2c->EVENTS_STOPPED) {
mbed_official 85:e1a8e879a6a9 220 }
mbed_official 85:e1a8e879a6a9 221 obj->i2c->EVENTS_STOPPED = 0;
mbed_official 227:7bd0639b8911 222 }
mbed_official 85:e1a8e879a6a9 223 return length;
mbed_official 85:e1a8e879a6a9 224 }
mbed_official 85:e1a8e879a6a9 225
mbed_official 300:55638feb26a4 226 int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop)
mbed_official 300:55638feb26a4 227 {
mbed_official 85:e1a8e879a6a9 228 int status, errorResult;
mbed_official 300:55638feb26a4 229 obj->i2c->ADDRESS = (address >> 1);
mbed_official 85:e1a8e879a6a9 230 obj->i2c->SHORTS = 0;
mbed_official 227:7bd0639b8911 231 obj->i2c->TASKS_STARTTX = 1;
mbed_official 300:55638feb26a4 232
mbed_official 300:55638feb26a4 233 for (int i = 0; i<length; i++) {
mbed_official 85:e1a8e879a6a9 234 status = i2c_do_write(obj, data[i]);
mbed_official 300:55638feb26a4 235 if (status) {
mbed_official 85:e1a8e879a6a9 236 i2c_reset(obj);
mbed_official 85:e1a8e879a6a9 237 errorResult = checkError(obj);
mbed_official 300:55638feb26a4 238 if (errorResult<0) {
mbed_official 85:e1a8e879a6a9 239 return errorResult;
mbed_official 85:e1a8e879a6a9 240 }
mbed_official 85:e1a8e879a6a9 241 return i;
mbed_official 85:e1a8e879a6a9 242 }
mbed_official 85:e1a8e879a6a9 243 }
mbed_official 300:55638feb26a4 244
mbed_official 85:e1a8e879a6a9 245 // If not repeated start, send stop.
mbed_official 85:e1a8e879a6a9 246 if (stop) {
mbed_official 300:55638feb26a4 247 if (i2c_stop(obj)) {
mbed_official 85:e1a8e879a6a9 248 return I2C_ERROR_NO_SLAVE;
mbed_official 85:e1a8e879a6a9 249 }
mbed_official 85:e1a8e879a6a9 250 }
mbed_official 85:e1a8e879a6a9 251 return length;
mbed_official 85:e1a8e879a6a9 252 }
mbed_official 85:e1a8e879a6a9 253
mbed_official 300:55638feb26a4 254 int i2c_byte_read(i2c_t *obj, int last)
mbed_official 300:55638feb26a4 255 {
mbed_official 85:e1a8e879a6a9 256 char data;
mbed_official 85:e1a8e879a6a9 257 int status;
mbed_official 300:55638feb26a4 258
mbed_official 300:55638feb26a4 259 status = i2c_do_read(obj, &data, last);
mbed_official 85:e1a8e879a6a9 260 if (status) {
mbed_official 85:e1a8e879a6a9 261 i2c_reset(obj);
mbed_official 85:e1a8e879a6a9 262 }
mbed_official 85:e1a8e879a6a9 263 return data;
mbed_official 85:e1a8e879a6a9 264 }
mbed_official 85:e1a8e879a6a9 265
mbed_official 300:55638feb26a4 266 int i2c_byte_write(i2c_t *obj, int data)
mbed_official 300:55638feb26a4 267 {
mbed_official 85:e1a8e879a6a9 268 int status = 0;
mbed_official 300:55638feb26a4 269 if (!addrSet) {
mbed_official 300:55638feb26a4 270 addrSet = 1;
mbed_official 300:55638feb26a4 271 obj->i2c->ADDRESS = (data >> 1);
mbed_official 300:55638feb26a4 272
mbed_official 300:55638feb26a4 273 if (data & 1) {
mbed_official 85:e1a8e879a6a9 274 obj->i2c->EVENTS_RXDREADY = 0;
mbed_official 85:e1a8e879a6a9 275 obj->i2c->TASKS_STARTRX = 1;
mbed_official 300:55638feb26a4 276 } else {
mbed_official 300:55638feb26a4 277 obj->i2c->TASKS_STARTTX = 1;
mbed_official 85:e1a8e879a6a9 278 }
mbed_official 300:55638feb26a4 279 } else {
mbed_official 85:e1a8e879a6a9 280 status = i2c_do_write(obj, data);
mbed_official 300:55638feb26a4 281 if (status) {
mbed_official 85:e1a8e879a6a9 282 i2c_reset(obj);
mbed_official 85:e1a8e879a6a9 283 }
mbed_official 85:e1a8e879a6a9 284 }
mbed_official 300:55638feb26a4 285 return (1 - status);
mbed_official 85:e1a8e879a6a9 286 }