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:
227:7bd0639b8911
test with CLOCK_SETUP = 0

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 46:bebbbd80dd87 1 /* mbed Microcontroller Library
mbed_official 46:bebbbd80dd87 2 * Copyright (c) 2006-2013 ARM Limited
mbed_official 46:bebbbd80dd87 3 *
mbed_official 46:bebbbd80dd87 4 * Licensed under the Apache License, Version 2.0 (the "License");
mbed_official 46:bebbbd80dd87 5 * you may not use this file except in compliance with the License.
mbed_official 46:bebbbd80dd87 6 * You may obtain a copy of the License at
mbed_official 46:bebbbd80dd87 7 *
mbed_official 46:bebbbd80dd87 8 * http://www.apache.org/licenses/LICENSE-2.0
mbed_official 46:bebbbd80dd87 9 *
mbed_official 46:bebbbd80dd87 10 * Unless required by applicable law or agreed to in writing, software
mbed_official 46:bebbbd80dd87 11 * distributed under the License is distributed on an "AS IS" BASIS,
mbed_official 46:bebbbd80dd87 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
mbed_official 46:bebbbd80dd87 13 * See the License for the specific language governing permissions and
mbed_official 46:bebbbd80dd87 14 * limitations under the License.
mbed_official 46:bebbbd80dd87 15 */
mbed_official 46:bebbbd80dd87 16 #include "i2c_api.h"
mbed_official 46:bebbbd80dd87 17 #include "cmsis.h"
mbed_official 46:bebbbd80dd87 18 #include "pinmap.h"
mbed_official 46:bebbbd80dd87 19
mbed_official 46:bebbbd80dd87 20 static const SWM_Map SWM_I2C_SDA[] = {
mbed_official 46:bebbbd80dd87 21 {7, 24},
mbed_official 46:bebbbd80dd87 22 };
mbed_official 46:bebbbd80dd87 23
mbed_official 46:bebbbd80dd87 24 static const SWM_Map SWM_I2C_SCL[] = {
mbed_official 46:bebbbd80dd87 25 {8, 0},
mbed_official 46:bebbbd80dd87 26 };
mbed_official 46:bebbbd80dd87 27
mbed_official 46:bebbbd80dd87 28 static uint8_t repeated_start = 0;
mbed_official 46:bebbbd80dd87 29
mbed_official 46:bebbbd80dd87 30 #define I2C_DAT(x) (x->i2c->MSTDAT)
mbed_official 46:bebbbd80dd87 31 #define I2C_STAT(x) ((x->i2c->STAT >> 1) & (0x07))
mbed_official 46:bebbbd80dd87 32
mbed_official 46:bebbbd80dd87 33 static inline int i2c_status(i2c_t *obj) {
mbed_official 46:bebbbd80dd87 34 return I2C_STAT(obj);
mbed_official 46:bebbbd80dd87 35 }
mbed_official 46:bebbbd80dd87 36
mbed_official 46:bebbbd80dd87 37 // Wait until the Serial Interrupt (SI) is set
mbed_official 46:bebbbd80dd87 38 static int i2c_wait_SI(i2c_t *obj) {
mbed_official 46:bebbbd80dd87 39 int timeout = 0;
mbed_official 46:bebbbd80dd87 40 while (!(obj->i2c->STAT & (1 << 0))) {
mbed_official 46:bebbbd80dd87 41 timeout++;
mbed_official 46:bebbbd80dd87 42 if (timeout > 100000) return -1;
mbed_official 46:bebbbd80dd87 43 }
mbed_official 46:bebbbd80dd87 44 return 0;
mbed_official 46:bebbbd80dd87 45 }
mbed_official 46:bebbbd80dd87 46
mbed_official 46:bebbbd80dd87 47 static inline void i2c_interface_enable(i2c_t *obj) {
mbed_official 46:bebbbd80dd87 48 obj->i2c->CFG |= (1 << 0);
mbed_official 46:bebbbd80dd87 49 }
mbed_official 46:bebbbd80dd87 50
mbed_official 46:bebbbd80dd87 51 static inline void i2c_power_enable(i2c_t *obj) {
mbed_official 227:7bd0639b8911 52 LPC_SYSCON->SYSAHBCLKCTRL |= (1<<5);
mbed_official 46:bebbbd80dd87 53 LPC_SYSCON->PRESETCTRL &= ~(0x1<<6);
mbed_official 46:bebbbd80dd87 54 LPC_SYSCON->PRESETCTRL |= (0x1<<6);
mbed_official 46:bebbbd80dd87 55 }
mbed_official 46:bebbbd80dd87 56
mbed_official 46:bebbbd80dd87 57 void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
mbed_official 46:bebbbd80dd87 58 obj->i2c = (LPC_I2C_TypeDef *)LPC_I2C;
mbed_official 46:bebbbd80dd87 59
mbed_official 46:bebbbd80dd87 60 const SWM_Map *swm;
mbed_official 46:bebbbd80dd87 61 uint32_t regVal;
mbed_official 46:bebbbd80dd87 62
mbed_official 46:bebbbd80dd87 63 swm = &SWM_I2C_SDA[0];
mbed_official 46:bebbbd80dd87 64 regVal = LPC_SWM->PINASSIGN[swm->n] & ~(0xFF << swm->offset);
mbed_official 46:bebbbd80dd87 65 LPC_SWM->PINASSIGN[swm->n] = regVal | (sda << swm->offset);
mbed_official 46:bebbbd80dd87 66
mbed_official 46:bebbbd80dd87 67 swm = &SWM_I2C_SCL[0];
mbed_official 46:bebbbd80dd87 68 regVal = LPC_SWM->PINASSIGN[swm->n] & ~(0xFF << swm->offset);
mbed_official 46:bebbbd80dd87 69 LPC_SWM->PINASSIGN[swm->n] = regVal | (scl << swm->offset);
mbed_official 46:bebbbd80dd87 70
mbed_official 46:bebbbd80dd87 71 // enable power
mbed_official 46:bebbbd80dd87 72 i2c_power_enable(obj);
mbed_official 46:bebbbd80dd87 73 // set default frequency at 100k
mbed_official 46:bebbbd80dd87 74 i2c_frequency(obj, 100000);
mbed_official 46:bebbbd80dd87 75 i2c_interface_enable(obj);
mbed_official 46:bebbbd80dd87 76 }
mbed_official 46:bebbbd80dd87 77
mbed_official 46:bebbbd80dd87 78 inline int i2c_start(i2c_t *obj) {
mbed_official 46:bebbbd80dd87 79 int status = 0;
mbed_official 46:bebbbd80dd87 80 if (repeated_start) {
mbed_official 46:bebbbd80dd87 81 obj->i2c->MSTCTL = (1 << 1) | (1 << 0);
mbed_official 46:bebbbd80dd87 82 repeated_start = 0;
mbed_official 46:bebbbd80dd87 83 } else {
mbed_official 46:bebbbd80dd87 84 obj->i2c->MSTCTL = (1 << 1);
mbed_official 46:bebbbd80dd87 85 }
mbed_official 46:bebbbd80dd87 86 return status;
mbed_official 46:bebbbd80dd87 87 }
mbed_official 46:bebbbd80dd87 88
mbed_official 46:bebbbd80dd87 89 inline int i2c_stop(i2c_t *obj) {
mbed_official 46:bebbbd80dd87 90 int timeout = 0;
mbed_official 46:bebbbd80dd87 91
mbed_official 46:bebbbd80dd87 92 obj->i2c->MSTCTL = (1 << 2) | (1 << 0);
mbed_official 46:bebbbd80dd87 93 while ((obj->i2c->STAT & ((1 << 0) | (7 << 1))) != ((1 << 0) | (0 << 1))) {
mbed_official 46:bebbbd80dd87 94 timeout ++;
mbed_official 46:bebbbd80dd87 95 if (timeout > 100000) return 1;
mbed_official 46:bebbbd80dd87 96 }
mbed_official 46:bebbbd80dd87 97
mbed_official 46:bebbbd80dd87 98 return 0;
mbed_official 46:bebbbd80dd87 99 }
mbed_official 46:bebbbd80dd87 100
mbed_official 46:bebbbd80dd87 101
mbed_official 46:bebbbd80dd87 102 static inline int i2c_do_write(i2c_t *obj, int value, uint8_t addr) {
mbed_official 46:bebbbd80dd87 103 // write the data
mbed_official 46:bebbbd80dd87 104 I2C_DAT(obj) = value;
mbed_official 46:bebbbd80dd87 105
mbed_official 46:bebbbd80dd87 106 if (!addr)
mbed_official 46:bebbbd80dd87 107 obj->i2c->MSTCTL = (1 << 0);
mbed_official 46:bebbbd80dd87 108
mbed_official 46:bebbbd80dd87 109 // wait and return status
mbed_official 46:bebbbd80dd87 110 i2c_wait_SI(obj);
mbed_official 46:bebbbd80dd87 111 return i2c_status(obj);
mbed_official 46:bebbbd80dd87 112 }
mbed_official 46:bebbbd80dd87 113
mbed_official 46:bebbbd80dd87 114 static inline int i2c_do_read(i2c_t *obj, int last) {
mbed_official 46:bebbbd80dd87 115 // wait for it to arrive
mbed_official 46:bebbbd80dd87 116 i2c_wait_SI(obj);
mbed_official 46:bebbbd80dd87 117 if (!last)
mbed_official 46:bebbbd80dd87 118 obj->i2c->MSTCTL = (1 << 0);
mbed_official 46:bebbbd80dd87 119
mbed_official 46:bebbbd80dd87 120 // return the data
mbed_official 46:bebbbd80dd87 121 return (I2C_DAT(obj) & 0xFF);
mbed_official 46:bebbbd80dd87 122 }
mbed_official 46:bebbbd80dd87 123
mbed_official 46:bebbbd80dd87 124 void i2c_frequency(i2c_t *obj, int hz) {
mbed_official 46:bebbbd80dd87 125 // No peripheral clock divider on the M0
mbed_official 46:bebbbd80dd87 126 uint32_t PCLK = SystemCoreClock;
mbed_official 46:bebbbd80dd87 127
mbed_official 46:bebbbd80dd87 128 uint32_t clkdiv = PCLK / (hz * 4) - 1;
mbed_official 46:bebbbd80dd87 129
mbed_official 46:bebbbd80dd87 130 obj->i2c->DIV = clkdiv;
mbed_official 46:bebbbd80dd87 131 obj->i2c->MSTTIME = 0;
mbed_official 46:bebbbd80dd87 132 }
mbed_official 46:bebbbd80dd87 133
mbed_official 46:bebbbd80dd87 134 // The I2C does a read or a write as a whole operation
mbed_official 46:bebbbd80dd87 135 // There are two types of error conditions it can encounter
mbed_official 46:bebbbd80dd87 136 // 1) it can not obtain the bus
mbed_official 46:bebbbd80dd87 137 // 2) it gets error responses at part of the transmission
mbed_official 46:bebbbd80dd87 138 //
mbed_official 46:bebbbd80dd87 139 // We tackle them as follows:
mbed_official 46:bebbbd80dd87 140 // 1) we retry until we get the bus. we could have a "timeout" if we can not get it
mbed_official 46:bebbbd80dd87 141 // which basically turns it in to a 2)
mbed_official 46:bebbbd80dd87 142 // 2) on error, we use the standard error mechanisms to report/debug
mbed_official 46:bebbbd80dd87 143 //
mbed_official 46:bebbbd80dd87 144 // Therefore an I2C transaction should always complete. If it doesn't it is usually
mbed_official 46:bebbbd80dd87 145 // because something is setup wrong (e.g. wiring), and we don't need to programatically
mbed_official 46:bebbbd80dd87 146 // check for that
mbed_official 46:bebbbd80dd87 147
mbed_official 46:bebbbd80dd87 148 int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
mbed_official 46:bebbbd80dd87 149 int count, status;
mbed_official 46:bebbbd80dd87 150
mbed_official 46:bebbbd80dd87 151 i2c_start(obj);
mbed_official 46:bebbbd80dd87 152
mbed_official 46:bebbbd80dd87 153 status = i2c_do_write(obj, (address | 0x01), 1);
mbed_official 46:bebbbd80dd87 154 if (status != 0x01) {
mbed_official 46:bebbbd80dd87 155 i2c_stop(obj);
mbed_official 46:bebbbd80dd87 156 return I2C_ERROR_NO_SLAVE;
mbed_official 46:bebbbd80dd87 157 }
mbed_official 46:bebbbd80dd87 158
mbed_official 46:bebbbd80dd87 159 // Read in all except last byte
mbed_official 46:bebbbd80dd87 160 for (count = 0; count < (length - 1); count++) {
mbed_official 46:bebbbd80dd87 161 int value = i2c_do_read(obj, 0);
mbed_official 46:bebbbd80dd87 162 status = i2c_status(obj);
mbed_official 46:bebbbd80dd87 163 if (status != 0x00) {
mbed_official 46:bebbbd80dd87 164 i2c_stop(obj);
mbed_official 46:bebbbd80dd87 165 return count;
mbed_official 46:bebbbd80dd87 166 }
mbed_official 46:bebbbd80dd87 167 data[count] = (char) value;
mbed_official 46:bebbbd80dd87 168 }
mbed_official 46:bebbbd80dd87 169
mbed_official 46:bebbbd80dd87 170 // read in last byte
mbed_official 46:bebbbd80dd87 171 int value = i2c_do_read(obj, 1);
mbed_official 46:bebbbd80dd87 172 status = i2c_status(obj);
mbed_official 46:bebbbd80dd87 173 if (status != 0x01) {
mbed_official 46:bebbbd80dd87 174 i2c_stop(obj);
mbed_official 46:bebbbd80dd87 175 return length - 1;
mbed_official 46:bebbbd80dd87 176 }
mbed_official 46:bebbbd80dd87 177
mbed_official 46:bebbbd80dd87 178 data[count] = (char) value;
mbed_official 46:bebbbd80dd87 179
mbed_official 46:bebbbd80dd87 180 // If not repeated start, send stop.
mbed_official 46:bebbbd80dd87 181 if (stop) {
mbed_official 46:bebbbd80dd87 182 i2c_stop(obj);
mbed_official 46:bebbbd80dd87 183 } else {
mbed_official 46:bebbbd80dd87 184 repeated_start = 1;
mbed_official 46:bebbbd80dd87 185 }
mbed_official 46:bebbbd80dd87 186
mbed_official 46:bebbbd80dd87 187 return length;
mbed_official 46:bebbbd80dd87 188 }
mbed_official 46:bebbbd80dd87 189
mbed_official 46:bebbbd80dd87 190 int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) {
mbed_official 46:bebbbd80dd87 191 int i, status;
mbed_official 46:bebbbd80dd87 192
mbed_official 46:bebbbd80dd87 193 i2c_start(obj);
mbed_official 46:bebbbd80dd87 194
mbed_official 46:bebbbd80dd87 195 status = i2c_do_write(obj, (address & 0xFE), 1);
mbed_official 46:bebbbd80dd87 196 if (status != 0x02) {
mbed_official 46:bebbbd80dd87 197 i2c_stop(obj);
mbed_official 46:bebbbd80dd87 198 return I2C_ERROR_NO_SLAVE;
mbed_official 46:bebbbd80dd87 199 }
mbed_official 46:bebbbd80dd87 200
mbed_official 46:bebbbd80dd87 201 for (i=0; i<length; i++) {
mbed_official 46:bebbbd80dd87 202 status = i2c_do_write(obj, data[i], 0);
mbed_official 46:bebbbd80dd87 203 if (status != 0x02) {
mbed_official 46:bebbbd80dd87 204 i2c_stop(obj);
mbed_official 46:bebbbd80dd87 205 return i;
mbed_official 46:bebbbd80dd87 206 }
mbed_official 46:bebbbd80dd87 207 }
mbed_official 46:bebbbd80dd87 208
mbed_official 46:bebbbd80dd87 209 // If not repeated start, send stop.
mbed_official 46:bebbbd80dd87 210 if (stop) {
mbed_official 46:bebbbd80dd87 211 i2c_stop(obj);
mbed_official 46:bebbbd80dd87 212 } else {
mbed_official 46:bebbbd80dd87 213 repeated_start = 1;
mbed_official 46:bebbbd80dd87 214 }
mbed_official 46:bebbbd80dd87 215
mbed_official 46:bebbbd80dd87 216 return length;
mbed_official 46:bebbbd80dd87 217 }
mbed_official 46:bebbbd80dd87 218
mbed_official 46:bebbbd80dd87 219 void i2c_reset(i2c_t *obj) {
mbed_official 46:bebbbd80dd87 220 i2c_stop(obj);
mbed_official 46:bebbbd80dd87 221 }
mbed_official 46:bebbbd80dd87 222
mbed_official 46:bebbbd80dd87 223 int i2c_byte_read(i2c_t *obj, int last) {
mbed_official 46:bebbbd80dd87 224 return (i2c_do_read(obj, last) & 0xFF);
mbed_official 46:bebbbd80dd87 225 }
mbed_official 46:bebbbd80dd87 226
mbed_official 46:bebbbd80dd87 227 int i2c_byte_write(i2c_t *obj, int data) {
mbed_official 46:bebbbd80dd87 228 int ack;
mbed_official 46:bebbbd80dd87 229 int status = i2c_do_write(obj, (data & 0xFF), 0);
mbed_official 46:bebbbd80dd87 230
mbed_official 46:bebbbd80dd87 231 switch(status) {
mbed_official 46:bebbbd80dd87 232 case 2:
mbed_official 46:bebbbd80dd87 233 ack = 1;
mbed_official 46:bebbbd80dd87 234 break;
mbed_official 46:bebbbd80dd87 235 default:
mbed_official 46:bebbbd80dd87 236 ack = 0;
mbed_official 46:bebbbd80dd87 237 break;
mbed_official 46:bebbbd80dd87 238 }
mbed_official 46:bebbbd80dd87 239
mbed_official 46:bebbbd80dd87 240 return ack;
mbed_official 46:bebbbd80dd87 241 }