Maintool / mbed-src-v4

Fork of mbed-src by mbed official

Committer:
mbed_official
Date:
Thu Feb 20 23:00:08 2014 +0000
Revision:
103:9b881da47c92
Child:
117:e0a7df0a9a56
Synchronized with git revision 1f2da5f6047218c8c45334c11bdaaaeab3c18841

Full URL: https://github.com/mbedmicro/mbed/commit/1f2da5f6047218c8c45334c11bdaaaeab3c18841/

NXP master merge

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 103:9b881da47c92 1 /* mbed Microcontroller Library
mbed_official 103:9b881da47c92 2 * Copyright (c) 2006-2013 ARM Limited
mbed_official 103:9b881da47c92 3 *
mbed_official 103:9b881da47c92 4 * Licensed under the Apache License, Version 2.0 (the "License");
mbed_official 103:9b881da47c92 5 * you may not use this file except in compliance with the License.
mbed_official 103:9b881da47c92 6 * You may obtain a copy of the License at
mbed_official 103:9b881da47c92 7 *
mbed_official 103:9b881da47c92 8 * http://www.apache.org/licenses/LICENSE-2.0
mbed_official 103:9b881da47c92 9 *
mbed_official 103:9b881da47c92 10 * Unless required by applicable law or agreed to in writing, software
mbed_official 103:9b881da47c92 11 * distributed under the License is distributed on an "AS IS" BASIS,
mbed_official 103:9b881da47c92 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
mbed_official 103:9b881da47c92 13 * See the License for the specific language governing permissions and
mbed_official 103:9b881da47c92 14 * limitations under the License.
mbed_official 103:9b881da47c92 15 */
mbed_official 103:9b881da47c92 16
mbed_official 103:9b881da47c92 17 #include "i2c_api.h"
mbed_official 103:9b881da47c92 18 #include "cmsis.h"
mbed_official 103:9b881da47c92 19 #include "pinmap.h"
mbed_official 103:9b881da47c92 20 #include "error.h"
mbed_official 103:9b881da47c92 21
mbed_official 103:9b881da47c92 22 static uint8_t repeated_start = 0;
mbed_official 103:9b881da47c92 23
mbed_official 103:9b881da47c92 24 #define I2C_STAT(x) ((LPC_I2C0->STAT >> 1) & (0x07))
mbed_official 103:9b881da47c92 25
mbed_official 103:9b881da47c92 26 static inline int i2c_status(i2c_t *obj) {
mbed_official 103:9b881da47c92 27 return I2C_STAT(obj);
mbed_official 103:9b881da47c92 28 }
mbed_official 103:9b881da47c92 29
mbed_official 103:9b881da47c92 30 // Wait until the Serial Interrupt (SI) is set
mbed_official 103:9b881da47c92 31 static int i2c_wait_SI(i2c_t *obj) {
mbed_official 103:9b881da47c92 32 int timeout = 0;
mbed_official 103:9b881da47c92 33 while (!(LPC_I2C0->STAT & (1 << 0))) {
mbed_official 103:9b881da47c92 34 timeout++;
mbed_official 103:9b881da47c92 35 if (timeout > 100000) return -1;
mbed_official 103:9b881da47c92 36 }
mbed_official 103:9b881da47c92 37 return 0;
mbed_official 103:9b881da47c92 38 }
mbed_official 103:9b881da47c92 39
mbed_official 103:9b881da47c92 40 static inline void i2c_interface_enable(i2c_t *obj) {
mbed_official 103:9b881da47c92 41 LPC_I2C0->CFG |= (1 << 0);
mbed_official 103:9b881da47c92 42 }
mbed_official 103:9b881da47c92 43
mbed_official 103:9b881da47c92 44 static inline void i2c_power_enable(i2c_t *obj) {
mbed_official 103:9b881da47c92 45 // Enables clock for I2C0
mbed_official 103:9b881da47c92 46 LPC_SYSCON->SYSAHBCLKCTRL1 |= (1<<13);
mbed_official 103:9b881da47c92 47 // LPC_SYSCON->PRESETCTRL1 &= ~(0x1<<13);
mbed_official 103:9b881da47c92 48 LPC_SYSCON->PRESETCTRL1 |= (0x1<<13);
mbed_official 103:9b881da47c92 49 LPC_SYSCON->PRESETCTRL1 &= ~(0x1 << 13);
mbed_official 103:9b881da47c92 50
mbed_official 103:9b881da47c92 51 }
mbed_official 103:9b881da47c92 52
mbed_official 103:9b881da47c92 53 void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
mbed_official 103:9b881da47c92 54
mbed_official 103:9b881da47c92 55 // ƒsƒ“’è‹`‚ÌŠm”F‚Ç‚¤‚µ‚悤c
mbed_official 103:9b881da47c92 56
mbed_official 103:9b881da47c92 57
mbed_official 103:9b881da47c92 58 // enable power
mbed_official 103:9b881da47c92 59 i2c_power_enable(obj);
mbed_official 103:9b881da47c92 60 // pin enable
mbed_official 103:9b881da47c92 61 LPC_SWM->PINENABLE1 &= ~(0x3 << 3);
mbed_official 103:9b881da47c92 62 // set default frequency at 100k
mbed_official 103:9b881da47c92 63 i2c_frequency(obj, 100000);
mbed_official 103:9b881da47c92 64 i2c_interface_enable(obj);
mbed_official 103:9b881da47c92 65 }
mbed_official 103:9b881da47c92 66
mbed_official 103:9b881da47c92 67 inline int i2c_start(i2c_t *obj) {
mbed_official 103:9b881da47c92 68 int status = 0;
mbed_official 103:9b881da47c92 69 if (repeated_start) {
mbed_official 103:9b881da47c92 70 LPC_I2C0->MSTCTL = (1 << 1) | (1 << 0);
mbed_official 103:9b881da47c92 71 repeated_start = 0;
mbed_official 103:9b881da47c92 72 } else {
mbed_official 103:9b881da47c92 73 LPC_I2C0->MSTCTL = (1 << 1);
mbed_official 103:9b881da47c92 74 }
mbed_official 103:9b881da47c92 75 return status;
mbed_official 103:9b881da47c92 76 }
mbed_official 103:9b881da47c92 77
mbed_official 103:9b881da47c92 78 inline int i2c_stop(i2c_t *obj) {
mbed_official 103:9b881da47c92 79 int timeout = 0;
mbed_official 103:9b881da47c92 80
mbed_official 103:9b881da47c92 81 LPC_I2C0->MSTCTL = (1 << 2) | (1 << 0);
mbed_official 103:9b881da47c92 82 while ((LPC_I2C0->STAT & ((1 << 0) | (7 << 1))) != ((1 << 0) | (0 << 1))) {
mbed_official 103:9b881da47c92 83 timeout ++;
mbed_official 103:9b881da47c92 84 if (timeout > 100000) return 1;
mbed_official 103:9b881da47c92 85 }
mbed_official 103:9b881da47c92 86
mbed_official 103:9b881da47c92 87 return 0;
mbed_official 103:9b881da47c92 88 }
mbed_official 103:9b881da47c92 89
mbed_official 103:9b881da47c92 90
mbed_official 103:9b881da47c92 91 static inline int i2c_do_write(i2c_t *obj, int value, uint8_t addr) {
mbed_official 103:9b881da47c92 92 // write the data
mbed_official 103:9b881da47c92 93 LPC_I2C0->MSTDAT = value;
mbed_official 103:9b881da47c92 94
mbed_official 103:9b881da47c92 95 if (!addr)
mbed_official 103:9b881da47c92 96 LPC_I2C0->MSTCTL = (1 << 0);
mbed_official 103:9b881da47c92 97
mbed_official 103:9b881da47c92 98 // wait and return status
mbed_official 103:9b881da47c92 99 i2c_wait_SI(obj);
mbed_official 103:9b881da47c92 100 return i2c_status(obj);
mbed_official 103:9b881da47c92 101 }
mbed_official 103:9b881da47c92 102
mbed_official 103:9b881da47c92 103 static inline int i2c_do_read(i2c_t *obj, int last) {
mbed_official 103:9b881da47c92 104 // wait for it to arrive
mbed_official 103:9b881da47c92 105 i2c_wait_SI(obj);
mbed_official 103:9b881da47c92 106 if (!last)
mbed_official 103:9b881da47c92 107 LPC_I2C0->MSTCTL = (1 << 0);
mbed_official 103:9b881da47c92 108
mbed_official 103:9b881da47c92 109 // return the data
mbed_official 103:9b881da47c92 110 //return (I2C_DAT(obj) & 0xFF);
mbed_official 103:9b881da47c92 111 return (LPC_I2C0->MSTDAT & 0xFF);
mbed_official 103:9b881da47c92 112 }
mbed_official 103:9b881da47c92 113
mbed_official 103:9b881da47c92 114 void i2c_frequency(i2c_t *obj, int hz) {
mbed_official 103:9b881da47c92 115 // No peripheral clock divider on the M0
mbed_official 103:9b881da47c92 116 uint32_t PCLK = SystemCoreClock;
mbed_official 103:9b881da47c92 117
mbed_official 103:9b881da47c92 118 uint32_t clkdiv = PCLK / (hz * 4) - 1;
mbed_official 103:9b881da47c92 119
mbed_official 103:9b881da47c92 120 LPC_I2C0->DIV = clkdiv;
mbed_official 103:9b881da47c92 121 LPC_I2C0->MSTTIME = 0;
mbed_official 103:9b881da47c92 122 }
mbed_official 103:9b881da47c92 123
mbed_official 103:9b881da47c92 124 int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
mbed_official 103:9b881da47c92 125 int count, status;
mbed_official 103:9b881da47c92 126 int timeout = 0;
mbed_official 103:9b881da47c92 127
mbed_official 103:9b881da47c92 128 i2c_start(obj);
mbed_official 103:9b881da47c92 129
mbed_official 103:9b881da47c92 130 //status = i2c_do_write(obj, (address | 0x01), 1);
mbed_official 103:9b881da47c92 131 LPC_I2C0->MSTDAT = (address | 0x01);
mbed_official 103:9b881da47c92 132 LPC_I2C0->MSTCTL |= 0x20;
mbed_official 103:9b881da47c92 133 while (!(LPC_I2C0->STAT & (1 << 0))) {
mbed_official 103:9b881da47c92 134 timeout++;
mbed_official 103:9b881da47c92 135 if (timeout > 100000) return -1;
mbed_official 103:9b881da47c92 136 }
mbed_official 103:9b881da47c92 137 status = ((LPC_I2C0->STAT >> 1) & (0x07));
mbed_official 103:9b881da47c92 138
mbed_official 103:9b881da47c92 139 if (status != 0x01) {
mbed_official 103:9b881da47c92 140 i2c_stop(obj);
mbed_official 103:9b881da47c92 141 return I2C_ERROR_NO_SLAVE;
mbed_official 103:9b881da47c92 142 }
mbed_official 103:9b881da47c92 143
mbed_official 103:9b881da47c92 144 // Read in all except last byte
mbed_official 103:9b881da47c92 145 for (count = 0; count < (length - 1); count++) {
mbed_official 103:9b881da47c92 146 //int value = i2c_do_read(obj, 0);
mbed_official 103:9b881da47c92 147 while (!(LPC_I2C0->STAT & (1 << 0))) {
mbed_official 103:9b881da47c92 148 timeout++;
mbed_official 103:9b881da47c92 149 if (timeout > 100000) return -1;
mbed_official 103:9b881da47c92 150 }
mbed_official 103:9b881da47c92 151 if (!0)
mbed_official 103:9b881da47c92 152 LPC_I2C0->MSTCTL = (1 << 0);
mbed_official 103:9b881da47c92 153 data[count] = (LPC_I2C0->MSTDAT & 0xFF);
mbed_official 103:9b881da47c92 154 //
mbed_official 103:9b881da47c92 155 status = ((LPC_I2C0->STAT >> 1) & (0x07));
mbed_official 103:9b881da47c92 156 if (status != 0x00) {
mbed_official 103:9b881da47c92 157 i2c_stop(obj);
mbed_official 103:9b881da47c92 158 return count;
mbed_official 103:9b881da47c92 159 }
mbed_official 103:9b881da47c92 160 //data[count] = (char) value;
mbed_official 103:9b881da47c92 161 }
mbed_official 103:9b881da47c92 162
mbed_official 103:9b881da47c92 163 // read in last byte
mbed_official 103:9b881da47c92 164 //int value = i2c_do_read(obj, 1);
mbed_official 103:9b881da47c92 165 while (!(LPC_I2C0->STAT & (1 << 0))) {
mbed_official 103:9b881da47c92 166 timeout++;
mbed_official 103:9b881da47c92 167 if (timeout > 100000) return -1;
mbed_official 103:9b881da47c92 168 }
mbed_official 103:9b881da47c92 169 data[count] = (LPC_I2C0->MSTDAT & 0xFF);
mbed_official 103:9b881da47c92 170 //
mbed_official 103:9b881da47c92 171 status = i2c_status(obj);
mbed_official 103:9b881da47c92 172 if (status != 0x01) {
mbed_official 103:9b881da47c92 173 i2c_stop(obj);
mbed_official 103:9b881da47c92 174 return length - 1;
mbed_official 103:9b881da47c92 175 }
mbed_official 103:9b881da47c92 176
mbed_official 103:9b881da47c92 177 //data[count] = (char) value;
mbed_official 103:9b881da47c92 178
mbed_official 103:9b881da47c92 179 // If not repeated start, send stop.
mbed_official 103:9b881da47c92 180 if (stop) {
mbed_official 103:9b881da47c92 181 i2c_stop(obj);
mbed_official 103:9b881da47c92 182 } else {
mbed_official 103:9b881da47c92 183 repeated_start = 1;
mbed_official 103:9b881da47c92 184 }
mbed_official 103:9b881da47c92 185
mbed_official 103:9b881da47c92 186 return length;
mbed_official 103:9b881da47c92 187 }
mbed_official 103:9b881da47c92 188
mbed_official 103:9b881da47c92 189 int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) {
mbed_official 103:9b881da47c92 190 int i, status;
mbed_official 103:9b881da47c92 191 int timeout = 0;
mbed_official 103:9b881da47c92 192
mbed_official 103:9b881da47c92 193 i2c_start(obj);
mbed_official 103:9b881da47c92 194
mbed_official 103:9b881da47c92 195 //status = i2c_do_write(obj, (address & 0xFE), 1);
mbed_official 103:9b881da47c92 196 LPC_I2C0->MSTDAT = (address & 0xFE);
mbed_official 103:9b881da47c92 197 LPC_I2C0->MSTCTL |= 0x20;
mbed_official 103:9b881da47c92 198 // wait and return status
mbed_official 103:9b881da47c92 199 while (!(LPC_I2C0->STAT & (1 << 0))) {
mbed_official 103:9b881da47c92 200 timeout++;
mbed_official 103:9b881da47c92 201 if (timeout > 100000) return -1;
mbed_official 103:9b881da47c92 202 }
mbed_official 103:9b881da47c92 203 status = ((LPC_I2C0->STAT >> 1) & (0x07));
mbed_official 103:9b881da47c92 204
mbed_official 103:9b881da47c92 205 if (status != 0x02) {
mbed_official 103:9b881da47c92 206 i2c_stop(obj);
mbed_official 103:9b881da47c92 207 return I2C_ERROR_NO_SLAVE;
mbed_official 103:9b881da47c92 208 }
mbed_official 103:9b881da47c92 209
mbed_official 103:9b881da47c92 210 for (i=0; i<length; i++) {
mbed_official 103:9b881da47c92 211 //status = i2c_do_write(obj, data[i], 0);
mbed_official 103:9b881da47c92 212 LPC_I2C0->MSTDAT = data[i];
mbed_official 103:9b881da47c92 213 LPC_I2C0->MSTCTL = (1 << 0);
mbed_official 103:9b881da47c92 214 // wait and return status
mbed_official 103:9b881da47c92 215 while (!(LPC_I2C0->STAT & (1 << 0))) {
mbed_official 103:9b881da47c92 216 timeout++;
mbed_official 103:9b881da47c92 217 if (timeout > 100000) return -1;
mbed_official 103:9b881da47c92 218 }
mbed_official 103:9b881da47c92 219 status = ((LPC_I2C0->STAT >> 1) & (0x07));
mbed_official 103:9b881da47c92 220 if (status != 0x02) {
mbed_official 103:9b881da47c92 221 i2c_stop(obj);
mbed_official 103:9b881da47c92 222 return i;
mbed_official 103:9b881da47c92 223 }
mbed_official 103:9b881da47c92 224 }
mbed_official 103:9b881da47c92 225
mbed_official 103:9b881da47c92 226 // If not repeated start, send stop.
mbed_official 103:9b881da47c92 227 if (stop) {
mbed_official 103:9b881da47c92 228 i2c_stop(obj);
mbed_official 103:9b881da47c92 229 } else {
mbed_official 103:9b881da47c92 230 repeated_start = 1;
mbed_official 103:9b881da47c92 231 }
mbed_official 103:9b881da47c92 232
mbed_official 103:9b881da47c92 233 return length;
mbed_official 103:9b881da47c92 234 }
mbed_official 103:9b881da47c92 235
mbed_official 103:9b881da47c92 236 void i2c_reset(i2c_t *obj) {
mbed_official 103:9b881da47c92 237 i2c_stop(obj);
mbed_official 103:9b881da47c92 238 }
mbed_official 103:9b881da47c92 239
mbed_official 103:9b881da47c92 240 int i2c_byte_read(i2c_t *obj, int last) {
mbed_official 103:9b881da47c92 241 return (i2c_do_read(obj, last) & 0xFF);
mbed_official 103:9b881da47c92 242 }
mbed_official 103:9b881da47c92 243
mbed_official 103:9b881da47c92 244 int i2c_byte_write(i2c_t *obj, int data) {
mbed_official 103:9b881da47c92 245 int ack;
mbed_official 103:9b881da47c92 246 int status = i2c_do_write(obj, (data & 0xFF), 0);
mbed_official 103:9b881da47c92 247
mbed_official 103:9b881da47c92 248 switch(status) {
mbed_official 103:9b881da47c92 249 case 2:
mbed_official 103:9b881da47c92 250 ack = 1;
mbed_official 103:9b881da47c92 251 break;
mbed_official 103:9b881da47c92 252 default:
mbed_official 103:9b881da47c92 253 ack = 0;
mbed_official 103:9b881da47c92 254 break;
mbed_official 103:9b881da47c92 255 }
mbed_official 103:9b881da47c92 256
mbed_official 103:9b881da47c92 257 return ack;
mbed_official 103:9b881da47c92 258 }