テスト用です。

Dependencies:   mbed

Committer:
jksoft
Date:
Tue Oct 11 11:09:42 2016 +0000
Revision:
0:8468a4403fea
SB??ver;

Who changed what in which revision?

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