mbed library sources

Dependents:   frdm_kl05z_gpio_test

Fork of mbed-src by mbed official

Committer:
shaoziyang
Date:
Sat Sep 13 14:25:46 2014 +0000
Revision:
323:9e901b0a5aa1
Parent:
314:b682143dd337
test with CLOCK_SETUP = 0

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 void i2c_interface_enable(i2c_t *obj)
mbed_official 300:55638feb26a4 34 {
mbed_official 85:e1a8e879a6a9 35 obj->i2c->ENABLE = (TWI_ENABLE_ENABLE_Enabled << TWI_ENABLE_ENABLE_Pos);
mbed_official 85:e1a8e879a6a9 36 }
mbed_official 85:e1a8e879a6a9 37
mbed_official 300:55638feb26a4 38 void twi_master_init(i2c_t *obj, PinName sda, PinName scl, int frequency)
mbed_official 300:55638feb26a4 39 {
mbed_official 300:55638feb26a4 40 NRF_GPIO->PIN_CNF[scl] = ((GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos) |
mbed_official 300:55638feb26a4 41 (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) |
mbed_official 300:55638feb26a4 42 (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos) |
mbed_official 300:55638feb26a4 43 (GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos) |
mbed_official 300:55638feb26a4 44 (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos));
mbed_official 85:e1a8e879a6a9 45
mbed_official 300:55638feb26a4 46 NRF_GPIO->PIN_CNF[sda] = ((GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos) |
mbed_official 300:55638feb26a4 47 (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) |
mbed_official 300:55638feb26a4 48 (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos) |
mbed_official 300:55638feb26a4 49 (GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos) |
mbed_official 300:55638feb26a4 50 (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos));
mbed_official 85:e1a8e879a6a9 51
mbed_official 300:55638feb26a4 52 obj->i2c->PSELSCL = scl;
mbed_official 300:55638feb26a4 53 obj->i2c->PSELSDA = sda;
mbed_official 85:e1a8e879a6a9 54 // set default frequency at 100k
mbed_official 85:e1a8e879a6a9 55 i2c_frequency(obj, frequency);
mbed_official 85:e1a8e879a6a9 56 i2c_interface_enable(obj);
mbed_official 85:e1a8e879a6a9 57 }
mbed_official 300:55638feb26a4 58
mbed_official 300:55638feb26a4 59 void i2c_init(i2c_t *obj, PinName sda, PinName scl)
mbed_official 300:55638feb26a4 60 {
mbed_official 85:e1a8e879a6a9 61 // determine the SPI to use
mbed_official 85:e1a8e879a6a9 62 I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA);
mbed_official 85:e1a8e879a6a9 63 I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL);
mbed_official 300:55638feb26a4 64 I2CName i2c = (I2CName)pinmap_merge(i2c_sda, i2c_scl);
mbed_official 300:55638feb26a4 65 obj->i2c = (NRF_TWI_Type *)i2c;
mbed_official 300:55638feb26a4 66
mbed_official 227:7bd0639b8911 67 MBED_ASSERT((int)obj->i2c != NC);
mbed_official 85:e1a8e879a6a9 68
mbed_official 300:55638feb26a4 69 obj->scl = scl;
mbed_official 300:55638feb26a4 70 obj->sda = sda;
mbed_official 85:e1a8e879a6a9 71 obj->i2c->EVENTS_ERROR = 0;
mbed_official 227:7bd0639b8911 72 obj->i2c->ENABLE = TWI_ENABLE_ENABLE_Disabled << TWI_ENABLE_ENABLE_Pos;
mbed_official 227:7bd0639b8911 73 obj->i2c->POWER = 0;
mbed_official 300:55638feb26a4 74
mbed_official 300:55638feb26a4 75 for (int i = 0; i<100; i++) {
mbed_official 85:e1a8e879a6a9 76 }
mbed_official 300:55638feb26a4 77
mbed_official 300:55638feb26a4 78 obj->i2c->POWER = 1;
mbed_official 300:55638feb26a4 79 twi_master_init(obj, sda, scl, 100000);
mbed_official 85:e1a8e879a6a9 80 }
mbed_official 300:55638feb26a4 81
mbed_official 300:55638feb26a4 82 void i2c_reset(i2c_t *obj)
mbed_official 300:55638feb26a4 83 {
mbed_official 85:e1a8e879a6a9 84 obj->i2c->EVENTS_ERROR = 0;
mbed_official 227:7bd0639b8911 85 obj->i2c->ENABLE = TWI_ENABLE_ENABLE_Disabled << TWI_ENABLE_ENABLE_Pos;
mbed_official 227:7bd0639b8911 86 obj->i2c->POWER = 0;
mbed_official 300:55638feb26a4 87 for (int i = 0; i<100; i++) {
mbed_official 85:e1a8e879a6a9 88 }
mbed_official 300:55638feb26a4 89
mbed_official 300:55638feb26a4 90 obj->i2c->POWER = 1;
mbed_official 300:55638feb26a4 91 twi_master_init(obj, obj->sda, obj->scl, obj->freq);
mbed_official 85:e1a8e879a6a9 92 }
mbed_official 85:e1a8e879a6a9 93
mbed_official 300:55638feb26a4 94 int i2c_start(i2c_t *obj)
mbed_official 300:55638feb26a4 95 {
mbed_official 85:e1a8e879a6a9 96 int status = 0;
mbed_official 85:e1a8e879a6a9 97 i2c_reset(obj);
mbed_official 314:b682143dd337 98 obj->address_set = 0;
mbed_official 85:e1a8e879a6a9 99 return status;
mbed_official 85:e1a8e879a6a9 100 }
mbed_official 85:e1a8e879a6a9 101
mbed_official 300:55638feb26a4 102 int i2c_stop(i2c_t *obj)
mbed_official 300:55638feb26a4 103 {
mbed_official 85:e1a8e879a6a9 104 int timeOut = 100000;
mbed_official 85:e1a8e879a6a9 105 obj->i2c->EVENTS_STOPPED = 0;
mbed_official 85:e1a8e879a6a9 106 // write the stop bit
mbed_official 85:e1a8e879a6a9 107 obj->i2c->TASKS_STOP = 1;
mbed_official 300:55638feb26a4 108 while (!obj->i2c->EVENTS_STOPPED) {
mbed_official 85:e1a8e879a6a9 109 timeOut--;
mbed_official 300:55638feb26a4 110 if (timeOut<0) {
mbed_official 85:e1a8e879a6a9 111 return 1;
mbed_official 300:55638feb26a4 112 }
mbed_official 227:7bd0639b8911 113 }
mbed_official 314:b682143dd337 114 obj->address_set = 0;
mbed_official 85:e1a8e879a6a9 115 i2c_reset(obj);
mbed_official 85:e1a8e879a6a9 116 return 0;
mbed_official 85:e1a8e879a6a9 117 }
mbed_official 85:e1a8e879a6a9 118
mbed_official 300:55638feb26a4 119 int i2c_do_write(i2c_t *obj, int value)
mbed_official 300:55638feb26a4 120 {
mbed_official 85:e1a8e879a6a9 121 int timeOut = 100000;
mbed_official 85:e1a8e879a6a9 122 obj->i2c->TXD = value;
mbed_official 300:55638feb26a4 123 while (!obj->i2c->EVENTS_TXDSENT) {
mbed_official 85:e1a8e879a6a9 124 timeOut--;
mbed_official 300:55638feb26a4 125 if (timeOut<0) {
mbed_official 85:e1a8e879a6a9 126 return 1;
mbed_official 300:55638feb26a4 127 }
mbed_official 85:e1a8e879a6a9 128 }
mbed_official 227:7bd0639b8911 129 obj->i2c->EVENTS_TXDSENT = 0;
mbed_official 85:e1a8e879a6a9 130 return 0;
mbed_official 85:e1a8e879a6a9 131 }
mbed_official 85:e1a8e879a6a9 132
mbed_official 300:55638feb26a4 133 int i2c_do_read(i2c_t *obj, char *data, int last)
mbed_official 300:55638feb26a4 134 {
mbed_official 85:e1a8e879a6a9 135 int timeOut = 100000;
mbed_official 177:d57c40a064c8 136
mbed_official 300:55638feb26a4 137 if (last) {
mbed_official 314:b682143dd337 138 // To trigger stop task when a byte is received,
mbed_official 314:b682143dd337 139 // must be set before resume task.
mbed_official 314:b682143dd337 140 obj->i2c->SHORTS = 2;
mbed_official 177:d57c40a064c8 141 }
mbed_official 314:b682143dd337 142
mbed_official 314:b682143dd337 143 obj->i2c->TASKS_RESUME = 1;
mbed_official 314:b682143dd337 144
mbed_official 300:55638feb26a4 145 while (!obj->i2c->EVENTS_RXDREADY) {
mbed_official 85:e1a8e879a6a9 146 timeOut--;
mbed_official 300:55638feb26a4 147 if (timeOut<0) {
mbed_official 85:e1a8e879a6a9 148 return 1;
mbed_official 300:55638feb26a4 149 }
mbed_official 85:e1a8e879a6a9 150 }
mbed_official 300:55638feb26a4 151 obj->i2c->EVENTS_RXDREADY = 0;
mbed_official 85:e1a8e879a6a9 152 *data = obj->i2c->RXD;
mbed_official 300:55638feb26a4 153
mbed_official 85:e1a8e879a6a9 154 return 0;
mbed_official 85:e1a8e879a6a9 155 }
mbed_official 85:e1a8e879a6a9 156
mbed_official 300:55638feb26a4 157 void i2c_frequency(i2c_t *obj, int hz)
mbed_official 300:55638feb26a4 158 {
mbed_official 300:55638feb26a4 159 if (hz<250000) {
mbed_official 85:e1a8e879a6a9 160 obj->freq = 100000;
mbed_official 85:e1a8e879a6a9 161 obj->i2c->FREQUENCY = (TWI_FREQUENCY_FREQUENCY_K100 << TWI_FREQUENCY_FREQUENCY_Pos);
mbed_official 300:55638feb26a4 162 } else if (hz<400000) {
mbed_official 85:e1a8e879a6a9 163 obj->freq = 250000;
mbed_official 85:e1a8e879a6a9 164 obj->i2c->FREQUENCY = (TWI_FREQUENCY_FREQUENCY_K250 << TWI_FREQUENCY_FREQUENCY_Pos);
mbed_official 300:55638feb26a4 165 } else {
mbed_official 85:e1a8e879a6a9 166 obj->freq = 400000;
mbed_official 85:e1a8e879a6a9 167 obj->i2c->FREQUENCY = (TWI_FREQUENCY_FREQUENCY_K400 << TWI_FREQUENCY_FREQUENCY_Pos);
mbed_official 85:e1a8e879a6a9 168 }
mbed_official 85:e1a8e879a6a9 169 }
mbed_official 85:e1a8e879a6a9 170
mbed_official 300:55638feb26a4 171 int checkError(i2c_t *obj)
mbed_official 300:55638feb26a4 172 {
mbed_official 300:55638feb26a4 173 if (obj->i2c->EVENTS_ERROR == 1) {
mbed_official 300:55638feb26a4 174 if (obj->i2c->ERRORSRC & TWI_ERRORSRC_ANACK_Msk) {
mbed_official 300:55638feb26a4 175 obj->i2c->EVENTS_ERROR = 0;
mbed_official 300:55638feb26a4 176 obj->i2c->TASKS_STOP = 1;
mbed_official 85:e1a8e879a6a9 177 return I2C_ERROR_BUS_BUSY;
mbed_official 85:e1a8e879a6a9 178 }
mbed_official 300:55638feb26a4 179
mbed_official 300:55638feb26a4 180 obj->i2c->EVENTS_ERROR = 0;
mbed_official 300:55638feb26a4 181 obj->i2c->TASKS_STOP = 1;
mbed_official 227:7bd0639b8911 182 return I2C_ERROR_NO_SLAVE;
mbed_official 227:7bd0639b8911 183 }
mbed_official 85:e1a8e879a6a9 184 return 0;
mbed_official 85:e1a8e879a6a9 185 }
mbed_official 85:e1a8e879a6a9 186
mbed_official 300:55638feb26a4 187 int i2c_read(i2c_t *obj, int address, char *data, int length, int stop)
mbed_official 300:55638feb26a4 188 {
mbed_official 300:55638feb26a4 189 int status, count, errorResult;
mbed_official 300:55638feb26a4 190 obj->i2c->ADDRESS = (address >> 1);
mbed_official 314:b682143dd337 191 obj->i2c->SHORTS = 1; // to trigger suspend task when a byte is received
mbed_official 85:e1a8e879a6a9 192 obj->i2c->EVENTS_RXDREADY = 0;
mbed_official 85:e1a8e879a6a9 193 obj->i2c->TASKS_STARTRX = 1;
mbed_official 300:55638feb26a4 194
mbed_official 85:e1a8e879a6a9 195 // Read in all except last byte
mbed_official 85:e1a8e879a6a9 196 for (count = 0; count < (length - 1); count++) {
mbed_official 300:55638feb26a4 197 status = i2c_do_read(obj, &data[count], 0);
mbed_official 227:7bd0639b8911 198 if (status) {
mbed_official 85:e1a8e879a6a9 199 errorResult = checkError(obj);
mbed_official 85:e1a8e879a6a9 200 i2c_reset(obj);
mbed_official 300:55638feb26a4 201 if (errorResult<0) {
mbed_official 85:e1a8e879a6a9 202 return errorResult;
mbed_official 85:e1a8e879a6a9 203 }
mbed_official 85:e1a8e879a6a9 204 return count;
mbed_official 85:e1a8e879a6a9 205 }
mbed_official 85:e1a8e879a6a9 206 }
mbed_official 85:e1a8e879a6a9 207
mbed_official 85:e1a8e879a6a9 208 // read in last byte
mbed_official 300:55638feb26a4 209 status = i2c_do_read(obj, &data[length - 1], 1);
mbed_official 85:e1a8e879a6a9 210 if (status) {
mbed_official 85:e1a8e879a6a9 211 i2c_reset(obj);
mbed_official 85:e1a8e879a6a9 212 return length - 1;
mbed_official 85:e1a8e879a6a9 213 }
mbed_official 85:e1a8e879a6a9 214 // If not repeated start, send stop.
mbed_official 85:e1a8e879a6a9 215 if (stop) {
mbed_official 300:55638feb26a4 216 while (!obj->i2c->EVENTS_STOPPED) {
mbed_official 85:e1a8e879a6a9 217 }
mbed_official 85:e1a8e879a6a9 218 obj->i2c->EVENTS_STOPPED = 0;
mbed_official 227:7bd0639b8911 219 }
mbed_official 85:e1a8e879a6a9 220 return length;
mbed_official 85:e1a8e879a6a9 221 }
mbed_official 85:e1a8e879a6a9 222
mbed_official 300:55638feb26a4 223 int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop)
mbed_official 300:55638feb26a4 224 {
mbed_official 85:e1a8e879a6a9 225 int status, errorResult;
mbed_official 300:55638feb26a4 226 obj->i2c->ADDRESS = (address >> 1);
mbed_official 85:e1a8e879a6a9 227 obj->i2c->SHORTS = 0;
mbed_official 227:7bd0639b8911 228 obj->i2c->TASKS_STARTTX = 1;
mbed_official 300:55638feb26a4 229
mbed_official 300:55638feb26a4 230 for (int i = 0; i<length; i++) {
mbed_official 85:e1a8e879a6a9 231 status = i2c_do_write(obj, data[i]);
mbed_official 300:55638feb26a4 232 if (status) {
mbed_official 85:e1a8e879a6a9 233 i2c_reset(obj);
mbed_official 85:e1a8e879a6a9 234 errorResult = checkError(obj);
mbed_official 300:55638feb26a4 235 if (errorResult<0) {
mbed_official 85:e1a8e879a6a9 236 return errorResult;
mbed_official 85:e1a8e879a6a9 237 }
mbed_official 85:e1a8e879a6a9 238 return i;
mbed_official 85:e1a8e879a6a9 239 }
mbed_official 85:e1a8e879a6a9 240 }
mbed_official 300:55638feb26a4 241
mbed_official 85:e1a8e879a6a9 242 // If not repeated start, send stop.
mbed_official 85:e1a8e879a6a9 243 if (stop) {
mbed_official 300:55638feb26a4 244 if (i2c_stop(obj)) {
mbed_official 85:e1a8e879a6a9 245 return I2C_ERROR_NO_SLAVE;
mbed_official 85:e1a8e879a6a9 246 }
mbed_official 85:e1a8e879a6a9 247 }
mbed_official 85:e1a8e879a6a9 248 return length;
mbed_official 85:e1a8e879a6a9 249 }
mbed_official 85:e1a8e879a6a9 250
mbed_official 300:55638feb26a4 251 int i2c_byte_read(i2c_t *obj, int last)
mbed_official 300:55638feb26a4 252 {
mbed_official 85:e1a8e879a6a9 253 char data;
mbed_official 85:e1a8e879a6a9 254 int status;
mbed_official 300:55638feb26a4 255
mbed_official 300:55638feb26a4 256 status = i2c_do_read(obj, &data, last);
mbed_official 85:e1a8e879a6a9 257 if (status) {
mbed_official 85:e1a8e879a6a9 258 i2c_reset(obj);
mbed_official 85:e1a8e879a6a9 259 }
mbed_official 85:e1a8e879a6a9 260 return data;
mbed_official 85:e1a8e879a6a9 261 }
mbed_official 85:e1a8e879a6a9 262
mbed_official 300:55638feb26a4 263 int i2c_byte_write(i2c_t *obj, int data)
mbed_official 300:55638feb26a4 264 {
mbed_official 85:e1a8e879a6a9 265 int status = 0;
mbed_official 314:b682143dd337 266 if (!obj->address_set) {
mbed_official 314:b682143dd337 267 obj->address_set = 1;
mbed_official 300:55638feb26a4 268 obj->i2c->ADDRESS = (data >> 1);
mbed_official 300:55638feb26a4 269
mbed_official 300:55638feb26a4 270 if (data & 1) {
mbed_official 85:e1a8e879a6a9 271 obj->i2c->EVENTS_RXDREADY = 0;
mbed_official 314:b682143dd337 272 obj->i2c->SHORTS = 1;
mbed_official 85:e1a8e879a6a9 273 obj->i2c->TASKS_STARTRX = 1;
mbed_official 300:55638feb26a4 274 } else {
mbed_official 314:b682143dd337 275 obj->i2c->SHORTS = 0;
mbed_official 300:55638feb26a4 276 obj->i2c->TASKS_STARTTX = 1;
mbed_official 85:e1a8e879a6a9 277 }
mbed_official 300:55638feb26a4 278 } else {
mbed_official 85:e1a8e879a6a9 279 status = i2c_do_write(obj, data);
mbed_official 300:55638feb26a4 280 if (status) {
mbed_official 85:e1a8e879a6a9 281 i2c_reset(obj);
mbed_official 85:e1a8e879a6a9 282 }
mbed_official 85:e1a8e879a6a9 283 }
mbed_official 300:55638feb26a4 284 return (1 - status);
mbed_official 85:e1a8e879a6a9 285 }