mbed library sources

Dependents:   frdm_kl05z_gpio_test

Fork of mbed-src by mbed official

Committer:
mbed_official
Date:
Fri Feb 21 12:15:10 2014 +0000
Revision:
104:a6a92e2e5a92
Parent:
85:e1a8e879a6a9
Child:
177:d57c40a064c8
Synchronized with git revision 195a50befc6da080be0051d0d9bc0838f6cb873e

Full URL: https://github.com/mbedmicro/mbed/commit/195a50befc6da080be0051d0d9bc0838f6cb873e/

nrf-mbed merge

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