Forked mbed-dev as I use an 20 pins stm32F042 and not the 32 pins version

Dependents:   Numitron_clock

Fork of mbed-dev by mbed official

Committer:
riktw
Date:
Sun Jan 22 22:20:36 2017 +0000
Revision:
153:0a78729d3229
Parent:
149:156823d33999
Back to 8Mhz clock. Revision 1.0

Who changed what in which revision?

UserRevisionLine numberNew contents of line
<> 144:ef7eb2e8f9f7 1 /* mbed Microcontroller Library
<> 144:ef7eb2e8f9f7 2 * Copyright (c) 2006-2013 ARM Limited
<> 144:ef7eb2e8f9f7 3 *
<> 144:ef7eb2e8f9f7 4 * Licensed under the Apache License, Version 2.0 (the "License");
<> 144:ef7eb2e8f9f7 5 * you may not use this file except in compliance with the License.
<> 144:ef7eb2e8f9f7 6 * You may obtain a copy of the License at
<> 144:ef7eb2e8f9f7 7 *
<> 144:ef7eb2e8f9f7 8 * http://www.apache.org/licenses/LICENSE-2.0
<> 144:ef7eb2e8f9f7 9 *
<> 144:ef7eb2e8f9f7 10 * Unless required by applicable law or agreed to in writing, software
<> 144:ef7eb2e8f9f7 11 * distributed under the License is distributed on an "AS IS" BASIS,
<> 144:ef7eb2e8f9f7 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
<> 144:ef7eb2e8f9f7 13 * See the License for the specific language governing permissions and
<> 144:ef7eb2e8f9f7 14 * limitations under the License.
<> 144:ef7eb2e8f9f7 15 */
<> 144:ef7eb2e8f9f7 16 #include <stdlib.h>
<> 144:ef7eb2e8f9f7 17 #include <string.h>
<> 144:ef7eb2e8f9f7 18
<> 144:ef7eb2e8f9f7 19 #include "i2c_api.h"
<> 144:ef7eb2e8f9f7 20 #include "cmsis.h"
<> 144:ef7eb2e8f9f7 21 #include "pinmap.h"
<> 144:ef7eb2e8f9f7 22
<> 144:ef7eb2e8f9f7 23 #define LPC824_I2C0_FMPLUS 1
<> 144:ef7eb2e8f9f7 24
<> 144:ef7eb2e8f9f7 25 #if DEVICE_I2C
<> 144:ef7eb2e8f9f7 26
<> 144:ef7eb2e8f9f7 27 static const SWM_Map SWM_I2C_SDA[] = {
<> 144:ef7eb2e8f9f7 28 //PINASSIGN Register ID, Pinselect bitfield position
<> 144:ef7eb2e8f9f7 29 { 9, 8},
<> 144:ef7eb2e8f9f7 30 { 9, 24},
<> 144:ef7eb2e8f9f7 31 {10, 8},
<> 144:ef7eb2e8f9f7 32 };
<> 144:ef7eb2e8f9f7 33
<> 144:ef7eb2e8f9f7 34 static const SWM_Map SWM_I2C_SCL[] = {
<> 144:ef7eb2e8f9f7 35 //PINASSIGN Register ID, Pinselect bitfield position
<> 144:ef7eb2e8f9f7 36 { 9, 16},
<> 144:ef7eb2e8f9f7 37 {10, 0},
<> 144:ef7eb2e8f9f7 38 {10, 16},
<> 144:ef7eb2e8f9f7 39 };
<> 144:ef7eb2e8f9f7 40
<> 144:ef7eb2e8f9f7 41
<> 144:ef7eb2e8f9f7 42 static int i2c_used = 0;
<> 144:ef7eb2e8f9f7 43 static uint8_t repeated_start = 0;
<> 144:ef7eb2e8f9f7 44
<> 144:ef7eb2e8f9f7 45 #define I2C_DAT(x) (x->i2c->MSTDAT)
<> 144:ef7eb2e8f9f7 46 #define I2C_STAT(x) ((x->i2c->STAT >> 1) & (0x07))
<> 144:ef7eb2e8f9f7 47
<> 144:ef7eb2e8f9f7 48 static inline void i2c_power_enable(int ch)
<> 144:ef7eb2e8f9f7 49 {
<> 144:ef7eb2e8f9f7 50 switch(ch) {
<> 144:ef7eb2e8f9f7 51 case 0:
<> 144:ef7eb2e8f9f7 52 // I2C0, Same as for LPC812
<> 144:ef7eb2e8f9f7 53 LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 5);
<> 144:ef7eb2e8f9f7 54 LPC_SYSCON->PRESETCTRL &= ~(1 << 6);
<> 144:ef7eb2e8f9f7 55 LPC_SYSCON->PRESETCTRL |= (1 << 6);
<> 144:ef7eb2e8f9f7 56 break;
<> 144:ef7eb2e8f9f7 57 case 1:
<> 144:ef7eb2e8f9f7 58 case 2:
<> 144:ef7eb2e8f9f7 59 case 3:
<> 144:ef7eb2e8f9f7 60 // I2C1,I2C2 or I2C3. Not available for LPC812
<> 144:ef7eb2e8f9f7 61 LPC_SYSCON->SYSAHBCLKCTRL |= (1 << (20 + ch));
<> 144:ef7eb2e8f9f7 62 LPC_SYSCON->PRESETCTRL &= ~(1 << (13 + ch));
<> 144:ef7eb2e8f9f7 63 LPC_SYSCON->PRESETCTRL |= (1 << (13 + ch));
<> 144:ef7eb2e8f9f7 64 break;
<> 144:ef7eb2e8f9f7 65 default:
<> 144:ef7eb2e8f9f7 66 break;
<> 144:ef7eb2e8f9f7 67 }
<> 144:ef7eb2e8f9f7 68 }
<> 144:ef7eb2e8f9f7 69
<> 144:ef7eb2e8f9f7 70
<> 144:ef7eb2e8f9f7 71 static inline void i2c_interface_enable(i2c_t *obj) {
<> 144:ef7eb2e8f9f7 72 obj->i2c->CFG |= (1 << 0); // Enable Master mode
<> 144:ef7eb2e8f9f7 73 // obj->i2c->CFG &= ~(1 << 1); // Disable Slave mode
<> 144:ef7eb2e8f9f7 74 }
<> 144:ef7eb2e8f9f7 75
<> 144:ef7eb2e8f9f7 76
<> 144:ef7eb2e8f9f7 77 static int get_available_i2c(void) {
<> 144:ef7eb2e8f9f7 78 int i;
<> 144:ef7eb2e8f9f7 79 for (i=0; i<3; i++) {
<> 144:ef7eb2e8f9f7 80 if ((i2c_used & (1 << i)) == 0)
<> 144:ef7eb2e8f9f7 81 return i+1;
<> 144:ef7eb2e8f9f7 82 }
<> 144:ef7eb2e8f9f7 83 return -1;
<> 144:ef7eb2e8f9f7 84 }
<> 144:ef7eb2e8f9f7 85
<> 144:ef7eb2e8f9f7 86 void i2c_init(i2c_t *obj, PinName sda, PinName scl)
<> 144:ef7eb2e8f9f7 87 {
<> 144:ef7eb2e8f9f7 88 const SWM_Map *swm;
<> 144:ef7eb2e8f9f7 89 uint32_t regVal;
<> 144:ef7eb2e8f9f7 90 int i2c_ch = 0;
<> 144:ef7eb2e8f9f7 91
<> 144:ef7eb2e8f9f7 92 //LPC824
<> 144:ef7eb2e8f9f7 93 //I2C0 can support FM+ but only on P0_11 and P0_10
<> 144:ef7eb2e8f9f7 94 if (sda == I2C_SDA && scl == I2C_SCL) {
<> 144:ef7eb2e8f9f7 95 //Select I2C mode for P0_11 and P0_10
<> 144:ef7eb2e8f9f7 96 LPC_SWM->PINENABLE0 &= ~(0x3 << 11);
<> 144:ef7eb2e8f9f7 97
<> 144:ef7eb2e8f9f7 98 #if(LPC824_I2C0_FMPLUS == 1)
<> 144:ef7eb2e8f9f7 99 // Enable FM+ mode on P0_11, P0_10
<> 144:ef7eb2e8f9f7 100 LPC_IOCON->PIO0_10 &= ~(0x3 << 8);
<> 144:ef7eb2e8f9f7 101 LPC_IOCON->PIO0_10 |= (0x2 << 8); //FM+ mode
<> 144:ef7eb2e8f9f7 102 LPC_IOCON->PIO0_11 &= ~(0x3 << 8);
<> 144:ef7eb2e8f9f7 103 LPC_IOCON->PIO0_11 |= (0x2 << 8); //FM+ mode
<> 144:ef7eb2e8f9f7 104 #endif
<> 144:ef7eb2e8f9f7 105 }
<> 144:ef7eb2e8f9f7 106 else {
<> 144:ef7eb2e8f9f7 107 //Select any other pin for I2C1, I2C2 or I2C3
<> 144:ef7eb2e8f9f7 108 i2c_ch = get_available_i2c();
<> 144:ef7eb2e8f9f7 109 if (i2c_ch == -1)
<> 144:ef7eb2e8f9f7 110 return;
<> 144:ef7eb2e8f9f7 111 i2c_used |= (1 << (i2c_ch - 1));
<> 144:ef7eb2e8f9f7 112
<> 144:ef7eb2e8f9f7 113 swm = &SWM_I2C_SDA[i2c_ch - 1];
<> 144:ef7eb2e8f9f7 114 regVal = LPC_SWM->PINASSIGN[swm->n] & ~(0xFF << swm->offset);
<> 144:ef7eb2e8f9f7 115 LPC_SWM->PINASSIGN[swm->n] = regVal | ((sda >> PIN_SHIFT) << swm->offset);
<> 144:ef7eb2e8f9f7 116
<> 144:ef7eb2e8f9f7 117 swm = &SWM_I2C_SCL[i2c_ch - 1];
<> 144:ef7eb2e8f9f7 118 regVal = LPC_SWM->PINASSIGN[swm->n] & ~(0xFF << swm->offset);
<> 144:ef7eb2e8f9f7 119 LPC_SWM->PINASSIGN[swm->n] = regVal | ((scl >> PIN_SHIFT) << swm->offset);
<> 144:ef7eb2e8f9f7 120 }
<> 144:ef7eb2e8f9f7 121
<> 144:ef7eb2e8f9f7 122 switch(i2c_ch) {
<> 144:ef7eb2e8f9f7 123 case 0:
<> 144:ef7eb2e8f9f7 124 obj->i2c = (LPC_I2C0_Type *)LPC_I2C0;
<> 144:ef7eb2e8f9f7 125 break;
<> 144:ef7eb2e8f9f7 126 case 1:
<> 144:ef7eb2e8f9f7 127 obj->i2c = (LPC_I2C0_Type *)LPC_I2C1;
<> 144:ef7eb2e8f9f7 128 break;
<> 144:ef7eb2e8f9f7 129 case 2:
<> 144:ef7eb2e8f9f7 130 obj->i2c = (LPC_I2C0_Type *)LPC_I2C2;
<> 144:ef7eb2e8f9f7 131 break;
<> 144:ef7eb2e8f9f7 132 case 3:
<> 144:ef7eb2e8f9f7 133 obj->i2c = (LPC_I2C0_Type *)LPC_I2C3;
<> 144:ef7eb2e8f9f7 134 break;
<> 144:ef7eb2e8f9f7 135 default:
<> 144:ef7eb2e8f9f7 136 break;
<> 144:ef7eb2e8f9f7 137 }
<> 144:ef7eb2e8f9f7 138
<> 144:ef7eb2e8f9f7 139 // enable power
<> 144:ef7eb2e8f9f7 140 i2c_power_enable(i2c_ch);
<> 144:ef7eb2e8f9f7 141 // set default frequency at 100k
<> 144:ef7eb2e8f9f7 142 i2c_frequency(obj, 100000);
<> 144:ef7eb2e8f9f7 143 i2c_interface_enable(obj);
<> 144:ef7eb2e8f9f7 144 }
<> 144:ef7eb2e8f9f7 145
<> 144:ef7eb2e8f9f7 146
<> 144:ef7eb2e8f9f7 147 static inline int i2c_status(i2c_t *obj) {
<> 144:ef7eb2e8f9f7 148 return I2C_STAT(obj);
<> 144:ef7eb2e8f9f7 149 }
<> 144:ef7eb2e8f9f7 150
<> 144:ef7eb2e8f9f7 151 // Wait until the Master Serial Interrupt (SI) is set
<> 144:ef7eb2e8f9f7 152 // Timeout when it takes too long.
<> 144:ef7eb2e8f9f7 153 static int i2c_wait_SI(i2c_t *obj) {
<> 144:ef7eb2e8f9f7 154 int timeout = 0;
<> 144:ef7eb2e8f9f7 155 while (!(obj->i2c->STAT & (1 << 0))) {
<> 144:ef7eb2e8f9f7 156 timeout++;
<> 144:ef7eb2e8f9f7 157 if (timeout > 100000) return -1;
<> 144:ef7eb2e8f9f7 158 }
<> 144:ef7eb2e8f9f7 159 return 0;
<> 144:ef7eb2e8f9f7 160 }
<> 144:ef7eb2e8f9f7 161
<> 144:ef7eb2e8f9f7 162
<> 144:ef7eb2e8f9f7 163 //Attention. Spec says: First store Address in DAT before setting STA !
<> 144:ef7eb2e8f9f7 164 //Undefined state when using single byte I2C operations and too much delay
<> 144:ef7eb2e8f9f7 165 //between i2c_start and do_i2c_write(Address).
<> 144:ef7eb2e8f9f7 166 //Also note that lpc812/824 will immediately continue reading a byte when Address b0 == 1
<> 144:ef7eb2e8f9f7 167 inline int i2c_start(i2c_t *obj) {
<> 144:ef7eb2e8f9f7 168 int status = 0;
<> 144:ef7eb2e8f9f7 169 if (repeated_start) {
<> 144:ef7eb2e8f9f7 170 obj->i2c->MSTCTL = (1 << 1) | (1 << 0); // STA bit and Continue bit to complete previous RD or WR
<> 144:ef7eb2e8f9f7 171 repeated_start = 0;
<> 144:ef7eb2e8f9f7 172 } else {
<> 144:ef7eb2e8f9f7 173 obj->i2c->MSTCTL = (1 << 1); // STA bit
<> 144:ef7eb2e8f9f7 174 }
<> 144:ef7eb2e8f9f7 175 return status;
<> 144:ef7eb2e8f9f7 176 }
<> 144:ef7eb2e8f9f7 177
<> 144:ef7eb2e8f9f7 178 //Generate Stop condition and wait until bus is Idle
<> 144:ef7eb2e8f9f7 179 //Will also send NAK for previous RD
<> 144:ef7eb2e8f9f7 180 inline int i2c_stop(i2c_t *obj) {
<> 144:ef7eb2e8f9f7 181 int timeout = 0;
<> 144:ef7eb2e8f9f7 182
<> 144:ef7eb2e8f9f7 183 // STP bit and Continue bit. Sends NAK to complete previous RD
<> 144:ef7eb2e8f9f7 184 obj->i2c->MSTCTL = (1 << 2) | (1 << 0);
<> 144:ef7eb2e8f9f7 185
<> 144:ef7eb2e8f9f7 186 //Spin until Ready (b0 == 1)and Status is Idle (b3..b1 == 000)
<> 144:ef7eb2e8f9f7 187 while ((obj->i2c->STAT & ((7 << 1) | (1 << 0))) != ((0 << 1) | (1 << 0))) {
<> 144:ef7eb2e8f9f7 188 timeout ++;
<> 144:ef7eb2e8f9f7 189 if (timeout > 100000) return 1;
<> 144:ef7eb2e8f9f7 190 }
<> 144:ef7eb2e8f9f7 191
<> 144:ef7eb2e8f9f7 192 // repeated_start = 0; // bus free
<> 144:ef7eb2e8f9f7 193 return 0;
<> 144:ef7eb2e8f9f7 194 }
<> 144:ef7eb2e8f9f7 195
<> 144:ef7eb2e8f9f7 196 //Spec says: first check Idle and status is Ok
<> 144:ef7eb2e8f9f7 197 static inline int i2c_do_write(i2c_t *obj, int value, uint8_t addr) {
<> 144:ef7eb2e8f9f7 198 // write the data
<> 144:ef7eb2e8f9f7 199 I2C_DAT(obj) = value;
<> 144:ef7eb2e8f9f7 200
<> 144:ef7eb2e8f9f7 201 if (!addr)
<> 144:ef7eb2e8f9f7 202 obj->i2c->MSTCTL = (1 << 0); //Set continue for data. Should not be set for addr since that uses STA
<> 144:ef7eb2e8f9f7 203
<> 144:ef7eb2e8f9f7 204 // wait and return status
<> 144:ef7eb2e8f9f7 205 i2c_wait_SI(obj);
<> 144:ef7eb2e8f9f7 206 return i2c_status(obj);
<> 144:ef7eb2e8f9f7 207 }
<> 144:ef7eb2e8f9f7 208
<> 144:ef7eb2e8f9f7 209
<> 144:ef7eb2e8f9f7 210 //Attention, correct Order: wait for data ready, read data, read status, continue, return
<> 144:ef7eb2e8f9f7 211 //Dont read DAT or STAT when not ready, so dont read after setting continue.
<> 144:ef7eb2e8f9f7 212 //Results may be invalid when next read is underway.
<> 144:ef7eb2e8f9f7 213 static inline int i2c_do_read(i2c_t *obj, int last) {
<> 144:ef7eb2e8f9f7 214 // wait for it to arrive
<> 144:ef7eb2e8f9f7 215 i2c_wait_SI(obj);
<> 144:ef7eb2e8f9f7 216 if (!last)
<> 144:ef7eb2e8f9f7 217 obj->i2c->MSTCTL = (1 << 0); //ACK and Continue
<> 144:ef7eb2e8f9f7 218
<> 144:ef7eb2e8f9f7 219 // return the data
<> 144:ef7eb2e8f9f7 220 return (I2C_DAT(obj) & 0xFF);
<> 144:ef7eb2e8f9f7 221 }
<> 144:ef7eb2e8f9f7 222
<> 144:ef7eb2e8f9f7 223
<> 144:ef7eb2e8f9f7 224 void i2c_frequency(i2c_t *obj, int hz) {
<> 144:ef7eb2e8f9f7 225 // No peripheral clock divider on the M0
<> 144:ef7eb2e8f9f7 226 uint32_t PCLK = SystemCoreClock;
<> 144:ef7eb2e8f9f7 227
<> 144:ef7eb2e8f9f7 228 uint32_t clkdiv = PCLK / (hz * 4) - 1;
<> 144:ef7eb2e8f9f7 229
<> 144:ef7eb2e8f9f7 230 obj->i2c->CLKDIV = clkdiv;
<> 144:ef7eb2e8f9f7 231 obj->i2c->MSTTIME = 0;
<> 144:ef7eb2e8f9f7 232 }
<> 144:ef7eb2e8f9f7 233
<> 144:ef7eb2e8f9f7 234 // The I2C does a read or a write as a whole operation
<> 144:ef7eb2e8f9f7 235 // There are two types of error conditions it can encounter
<> 144:ef7eb2e8f9f7 236 // 1) it can not obtain the bus
<> 144:ef7eb2e8f9f7 237 // 2) it gets error responses at part of the transmission
<> 144:ef7eb2e8f9f7 238 //
<> 144:ef7eb2e8f9f7 239 // We tackle them as follows:
<> 144:ef7eb2e8f9f7 240 // 1) we retry until we get the bus. we could have a "timeout" if we can not get it
<> 144:ef7eb2e8f9f7 241 // which basically turns it in to a 2)
<> 144:ef7eb2e8f9f7 242 // 2) on error, we use the standard error mechanisms to report/debug
<> 144:ef7eb2e8f9f7 243 //
<> 144:ef7eb2e8f9f7 244 // Therefore an I2C transaction should always complete. If it doesn't it is usually
<> 144:ef7eb2e8f9f7 245 // because something is setup wrong (e.g. wiring), and we don't need to programatically
<> 144:ef7eb2e8f9f7 246 // check for that
<> 144:ef7eb2e8f9f7 247 int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
<> 144:ef7eb2e8f9f7 248 int count, status;
<> 144:ef7eb2e8f9f7 249
<> 144:ef7eb2e8f9f7 250 //Store the address+RD and then generate STA
<> 144:ef7eb2e8f9f7 251 I2C_DAT(obj) = address | 0x01;
<> 144:ef7eb2e8f9f7 252 i2c_start(obj);
<> 144:ef7eb2e8f9f7 253
<> 144:ef7eb2e8f9f7 254 // Wait for completion of STA and Sending of SlaveAddress+RD and first Read byte
<> 144:ef7eb2e8f9f7 255 i2c_wait_SI(obj);
<> 144:ef7eb2e8f9f7 256 status = i2c_status(obj);
<> 144:ef7eb2e8f9f7 257 if (status == 0x03) { // NAK on SlaveAddress
<> 144:ef7eb2e8f9f7 258 i2c_stop(obj);
<> 144:ef7eb2e8f9f7 259 return I2C_ERROR_NO_SLAVE;
<> 144:ef7eb2e8f9f7 260 }
<> 144:ef7eb2e8f9f7 261
<> 144:ef7eb2e8f9f7 262 // Read in all except last byte
<> 144:ef7eb2e8f9f7 263 for (count = 0; count < (length-1); count++) {
<> 144:ef7eb2e8f9f7 264
<> 144:ef7eb2e8f9f7 265 // Wait for it to arrive, note that first byte read after address+RD is already waiting
<> 144:ef7eb2e8f9f7 266 i2c_wait_SI(obj);
<> 144:ef7eb2e8f9f7 267 status = i2c_status(obj);
<> 144:ef7eb2e8f9f7 268 if (status != 0x01) { // RX RDY
<> 144:ef7eb2e8f9f7 269 i2c_stop(obj);
<> 144:ef7eb2e8f9f7 270 return count;
<> 144:ef7eb2e8f9f7 271 }
<> 144:ef7eb2e8f9f7 272 data[count] = I2C_DAT(obj) & 0xFF; // Store read byte
<> 144:ef7eb2e8f9f7 273
<> 144:ef7eb2e8f9f7 274 obj->i2c->MSTCTL = (1 << 0); // Send ACK and Continue to read
<> 144:ef7eb2e8f9f7 275 }
<> 144:ef7eb2e8f9f7 276
<> 144:ef7eb2e8f9f7 277 // Read final byte
<> 144:ef7eb2e8f9f7 278 // Wait for it to arrive
<> 144:ef7eb2e8f9f7 279 i2c_wait_SI(obj);
<> 144:ef7eb2e8f9f7 280
<> 144:ef7eb2e8f9f7 281 status = i2c_status(obj);
<> 144:ef7eb2e8f9f7 282 if (status != 0x01) { // RX RDY
<> 144:ef7eb2e8f9f7 283 i2c_stop(obj);
<> 144:ef7eb2e8f9f7 284 return count;
<> 144:ef7eb2e8f9f7 285 }
<> 144:ef7eb2e8f9f7 286 data[count] = I2C_DAT(obj) & 0xFF; // Store final read byte
<> 144:ef7eb2e8f9f7 287
<> 144:ef7eb2e8f9f7 288 // If not repeated start, send stop.
<> 144:ef7eb2e8f9f7 289 if (stop) {
<> 144:ef7eb2e8f9f7 290 i2c_stop(obj); // Also sends NAK for last read byte
<> 144:ef7eb2e8f9f7 291 } else {
<> 144:ef7eb2e8f9f7 292 repeated_start = 1;
<> 144:ef7eb2e8f9f7 293 }
<> 144:ef7eb2e8f9f7 294
<> 144:ef7eb2e8f9f7 295 return length;
<> 144:ef7eb2e8f9f7 296 }
<> 144:ef7eb2e8f9f7 297
<> 144:ef7eb2e8f9f7 298
<> 144:ef7eb2e8f9f7 299 int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) {
<> 144:ef7eb2e8f9f7 300 int i, status;
<> 144:ef7eb2e8f9f7 301
<> 144:ef7eb2e8f9f7 302 //Store the address+/WR and then generate STA
<> 144:ef7eb2e8f9f7 303 I2C_DAT(obj) = address & 0xFE;
<> 144:ef7eb2e8f9f7 304 i2c_start(obj);
<> 144:ef7eb2e8f9f7 305
<> 144:ef7eb2e8f9f7 306 // Wait for completion of STA and Sending of SlaveAddress+/WR
<> 144:ef7eb2e8f9f7 307 i2c_wait_SI(obj);
<> 144:ef7eb2e8f9f7 308 status = i2c_status(obj);
<> 144:ef7eb2e8f9f7 309 if (status == 0x03) { // NAK SlaveAddress
<> 144:ef7eb2e8f9f7 310 i2c_stop(obj);
<> 144:ef7eb2e8f9f7 311 return I2C_ERROR_NO_SLAVE;
<> 144:ef7eb2e8f9f7 312 }
<> 144:ef7eb2e8f9f7 313
<> 144:ef7eb2e8f9f7 314 //Write all bytes
<> 144:ef7eb2e8f9f7 315 for (i=0; i<length; i++) {
<> 144:ef7eb2e8f9f7 316 status = i2c_do_write(obj, data[i], 0);
<> 144:ef7eb2e8f9f7 317 if (status != 0x02) { // TX RDY. Handles a Slave NAK on datawrite
<> 144:ef7eb2e8f9f7 318 i2c_stop(obj);
<> 144:ef7eb2e8f9f7 319 return i;
<> 144:ef7eb2e8f9f7 320 }
<> 144:ef7eb2e8f9f7 321 }
<> 144:ef7eb2e8f9f7 322
<> 144:ef7eb2e8f9f7 323 // If not repeated start, send stop.
<> 144:ef7eb2e8f9f7 324 if (stop) {
<> 144:ef7eb2e8f9f7 325 i2c_stop(obj);
<> 144:ef7eb2e8f9f7 326 } else {
<> 144:ef7eb2e8f9f7 327 repeated_start = 1;
<> 144:ef7eb2e8f9f7 328 }
<> 144:ef7eb2e8f9f7 329
<> 144:ef7eb2e8f9f7 330 return length;
<> 144:ef7eb2e8f9f7 331 }
<> 144:ef7eb2e8f9f7 332
<> 144:ef7eb2e8f9f7 333 void i2c_reset(i2c_t *obj) {
<> 144:ef7eb2e8f9f7 334 i2c_stop(obj);
<> 144:ef7eb2e8f9f7 335 }
<> 144:ef7eb2e8f9f7 336
<> 144:ef7eb2e8f9f7 337 int i2c_byte_read(i2c_t *obj, int last) {
<> 144:ef7eb2e8f9f7 338 return (i2c_do_read(obj, last) & 0xFF);
<> 144:ef7eb2e8f9f7 339 // return (i2c_do_read(obj, last, 0) & 0xFF);
<> 144:ef7eb2e8f9f7 340 }
<> 144:ef7eb2e8f9f7 341
<> 144:ef7eb2e8f9f7 342 int i2c_byte_write(i2c_t *obj, int data) {
<> 144:ef7eb2e8f9f7 343 int ack;
<> 144:ef7eb2e8f9f7 344 int status = i2c_do_write(obj, (data & 0xFF), 0);
<> 144:ef7eb2e8f9f7 345
<> 144:ef7eb2e8f9f7 346 switch(status) {
<> 144:ef7eb2e8f9f7 347 case 2: // TX RDY. Handles a Slave NAK on datawrite
<> 144:ef7eb2e8f9f7 348 ack = 1;
<> 144:ef7eb2e8f9f7 349 break;
<> 144:ef7eb2e8f9f7 350 default:
<> 144:ef7eb2e8f9f7 351 ack = 0;
<> 144:ef7eb2e8f9f7 352 break;
<> 144:ef7eb2e8f9f7 353 }
<> 144:ef7eb2e8f9f7 354
<> 144:ef7eb2e8f9f7 355 return ack;
<> 144:ef7eb2e8f9f7 356 }
<> 144:ef7eb2e8f9f7 357
<> 144:ef7eb2e8f9f7 358
<> 144:ef7eb2e8f9f7 359 #if DEVICE_I2CSLAVE
<> 144:ef7eb2e8f9f7 360
<> 144:ef7eb2e8f9f7 361 #define I2C_SLVDAT(x) (x->i2c->SLVDAT)
<> 144:ef7eb2e8f9f7 362 #define I2C_SLVSTAT(x) ((x->i2c->STAT >> 9) & (0x03))
<> 144:ef7eb2e8f9f7 363 #define I2C_SLVSI(x) ((x->i2c->STAT >> 8) & (0x01))
<> 144:ef7eb2e8f9f7 364 //#define I2C_SLVCNT(x) (x->i2c->SLVCTL = (1 << 0))
<> 144:ef7eb2e8f9f7 365 //#define I2C_SLVNAK(x) (x->i2c->SLVCTL = (1 << 1))
<> 144:ef7eb2e8f9f7 366
<> 144:ef7eb2e8f9f7 367 #if(0)
<> 144:ef7eb2e8f9f7 368 // Wait until the Slave Serial Interrupt (SI) is set
<> 144:ef7eb2e8f9f7 369 // Timeout when it takes too long.
<> 144:ef7eb2e8f9f7 370 static int i2c_wait_slave_SI(i2c_t *obj) {
<> 144:ef7eb2e8f9f7 371 int timeout = 0;
<> 144:ef7eb2e8f9f7 372 while (!(obj->i2c->STAT & (1 << 8))) {
<> 144:ef7eb2e8f9f7 373 timeout++;
<> 144:ef7eb2e8f9f7 374 if (timeout > 100000) return -1;
<> 144:ef7eb2e8f9f7 375 }
<> 144:ef7eb2e8f9f7 376 return 0;
<> 144:ef7eb2e8f9f7 377 }
<> 144:ef7eb2e8f9f7 378 #endif
<> 144:ef7eb2e8f9f7 379
<> 144:ef7eb2e8f9f7 380 void i2c_slave_mode(i2c_t *obj, int enable_slave) {
<> 144:ef7eb2e8f9f7 381
<> 144:ef7eb2e8f9f7 382 if (enable_slave) {
<> 144:ef7eb2e8f9f7 383 // obj->i2c->CFG &= ~(1 << 0); //Disable Master mode
<> 144:ef7eb2e8f9f7 384 obj->i2c->CFG |= (1 << 1); //Enable Slave mode
<> 144:ef7eb2e8f9f7 385 }
<> 144:ef7eb2e8f9f7 386 else {
<> 144:ef7eb2e8f9f7 387 // obj->i2c->CFG |= (1 << 0); //Enable Master mode
<> 144:ef7eb2e8f9f7 388 obj->i2c->CFG &= ~(1 << 1); //Disable Slave mode
<> 144:ef7eb2e8f9f7 389 }
<> 144:ef7eb2e8f9f7 390 }
<> 144:ef7eb2e8f9f7 391
<> 144:ef7eb2e8f9f7 392 // Wait for next I2C event and find out what is going on
<> 144:ef7eb2e8f9f7 393 //
<> 144:ef7eb2e8f9f7 394 int i2c_slave_receive(i2c_t *obj) {
<> 144:ef7eb2e8f9f7 395 int addr;
<> 144:ef7eb2e8f9f7 396
<> 144:ef7eb2e8f9f7 397 // Check if there is any data pending
<> 144:ef7eb2e8f9f7 398 if (! I2C_SLVSI(obj)) {
<> 144:ef7eb2e8f9f7 399 return 0; //NoData
<> 144:ef7eb2e8f9f7 400 };
<> 144:ef7eb2e8f9f7 401
<> 144:ef7eb2e8f9f7 402 // Check State
<> 144:ef7eb2e8f9f7 403 switch(I2C_SLVSTAT(obj)) {
<> 144:ef7eb2e8f9f7 404 case 0x0: // Slave address plus R/W received
<> 144:ef7eb2e8f9f7 405 // At least one of the four slave addresses has been matched by hardware.
<> 144:ef7eb2e8f9f7 406 // You can figure out which address by checking Slave address match Index in STAT register.
<> 144:ef7eb2e8f9f7 407
<> 144:ef7eb2e8f9f7 408 // Get the received address
<> 144:ef7eb2e8f9f7 409 addr = I2C_SLVDAT(obj) & 0xFF;
<> 144:ef7eb2e8f9f7 410 // Send ACK on address and Continue
<> 144:ef7eb2e8f9f7 411 obj->i2c->SLVCTL = (1 << 0);
<> 144:ef7eb2e8f9f7 412
<> 144:ef7eb2e8f9f7 413 if (addr == 0x00) {
<> 144:ef7eb2e8f9f7 414 return 2; //WriteGeneral
<> 144:ef7eb2e8f9f7 415 }
<> 144:ef7eb2e8f9f7 416 //check the RW bit
<> 144:ef7eb2e8f9f7 417 if ((addr & 0x01) == 0x01) {
<> 144:ef7eb2e8f9f7 418 return 1; //ReadAddressed
<> 144:ef7eb2e8f9f7 419 }
<> 144:ef7eb2e8f9f7 420 else {
<> 144:ef7eb2e8f9f7 421 return 3; //WriteAddressed
<> 144:ef7eb2e8f9f7 422 }
<> 144:ef7eb2e8f9f7 423 //break;
<> 144:ef7eb2e8f9f7 424
<> 144:ef7eb2e8f9f7 425 case 0x1: // Slave receive. Received data is available (Slave Receiver mode).
<> 144:ef7eb2e8f9f7 426 // Oops, should never get here...
<> 144:ef7eb2e8f9f7 427 obj->i2c->SLVCTL = (1 << 1); // Send NACK on received data, try to recover...
<> 144:ef7eb2e8f9f7 428 return 0; //NoData
<> 144:ef7eb2e8f9f7 429
<> 144:ef7eb2e8f9f7 430 case 0x2: // Slave transmit. Data can be transmitted (Slave Transmitter mode).
<> 144:ef7eb2e8f9f7 431 // Oops, should never get here...
<> 144:ef7eb2e8f9f7 432 I2C_SLVDAT(obj) = 0xFF; // Send dummy data for transmission
<> 144:ef7eb2e8f9f7 433 obj->i2c->SLVCTL = (1 << 0); // Continue and try to recover...
<> 144:ef7eb2e8f9f7 434 return 0; //NoData
<> 144:ef7eb2e8f9f7 435
<> 144:ef7eb2e8f9f7 436 case 0x3: // Reserved.
<> 144:ef7eb2e8f9f7 437 default: // Oops, should never get here...
<> 144:ef7eb2e8f9f7 438 obj->i2c->SLVCTL = (1 << 0); // Continue and try to recover...
<> 144:ef7eb2e8f9f7 439 return 0; //NoData
<> 144:ef7eb2e8f9f7 440 //break;
<> 144:ef7eb2e8f9f7 441 } //switch status
<> 144:ef7eb2e8f9f7 442 }
<> 144:ef7eb2e8f9f7 443
<> 144:ef7eb2e8f9f7 444 // The dedicated I2C Slave byte read and byte write functions need to be called
<> 144:ef7eb2e8f9f7 445 // from 'common' mbed I2CSlave API for devices that have separate Master and
<> 144:ef7eb2e8f9f7 446 // Slave engines such as the lpc812 and lpc1549.
<> 144:ef7eb2e8f9f7 447
<> 144:ef7eb2e8f9f7 448 //Called when Slave is addressed for Write, Slave will receive Data in polling mode
<> 144:ef7eb2e8f9f7 449 //Parameter last=1 means received byte will be NACKed.
<> 144:ef7eb2e8f9f7 450 int i2c_slave_byte_read(i2c_t *obj, int last) {
<> 144:ef7eb2e8f9f7 451 int data;
<> 144:ef7eb2e8f9f7 452
<> 144:ef7eb2e8f9f7 453 // Wait for data
<> 144:ef7eb2e8f9f7 454 while (!I2C_SLVSI(obj)); // Wait forever
<> 144:ef7eb2e8f9f7 455 //if (i2c_wait_slave_SI(obj) != 0) {return -2;} // Wait with timeout
<> 144:ef7eb2e8f9f7 456
<> 144:ef7eb2e8f9f7 457 // Dont bother to check State, were not returning it anyhow..
<> 144:ef7eb2e8f9f7 458 //if (I2C_SLVSTAT(obj)) == 0x01) {
<> 144:ef7eb2e8f9f7 459 // Slave receive. Received data is available (Slave Receiver mode).
<> 144:ef7eb2e8f9f7 460 //};
<> 144:ef7eb2e8f9f7 461
<> 144:ef7eb2e8f9f7 462 data = I2C_SLVDAT(obj) & 0xFF; // Get and store the received data
<> 144:ef7eb2e8f9f7 463 if (last) {
<> 144:ef7eb2e8f9f7 464 obj->i2c->SLVCTL = (1 << 1); // Send NACK on received data and Continue
<> 144:ef7eb2e8f9f7 465 }
<> 144:ef7eb2e8f9f7 466 else {
<> 144:ef7eb2e8f9f7 467 obj->i2c->SLVCTL = (1 << 0); // Send ACK on data and Continue to read
<> 144:ef7eb2e8f9f7 468 }
<> 144:ef7eb2e8f9f7 469
<> 144:ef7eb2e8f9f7 470 return data;
<> 144:ef7eb2e8f9f7 471 }
<> 144:ef7eb2e8f9f7 472
<> 144:ef7eb2e8f9f7 473
<> 144:ef7eb2e8f9f7 474 //Called when Slave is addressed for Read, Slave will send Data in polling mode
<> 144:ef7eb2e8f9f7 475 //
<> 144:ef7eb2e8f9f7 476 int i2c_slave_byte_write(i2c_t *obj, int data) {
<> 144:ef7eb2e8f9f7 477
<> 144:ef7eb2e8f9f7 478 // Wait until Ready
<> 144:ef7eb2e8f9f7 479 while (!I2C_SLVSI(obj)); // Wait forever
<> 144:ef7eb2e8f9f7 480 // if (i2c_wait_slave_SI(obj) != 0) {return -2;} // Wait with timeout
<> 144:ef7eb2e8f9f7 481
<> 144:ef7eb2e8f9f7 482 // Check State
<> 144:ef7eb2e8f9f7 483 switch(I2C_SLVSTAT(obj)) {
<> 144:ef7eb2e8f9f7 484 case 0x0: // Slave address plus R/W received
<> 144:ef7eb2e8f9f7 485 // At least one of the four slave addresses has been matched by hardware.
<> 144:ef7eb2e8f9f7 486 // You can figure out which address by checking Slave address match Index in STAT register.
<> 144:ef7eb2e8f9f7 487 // I2C Restart occurred
<> 144:ef7eb2e8f9f7 488 return -1;
<> 144:ef7eb2e8f9f7 489 //break;
<> 144:ef7eb2e8f9f7 490 case 0x1: // Slave receive. Received data is available (Slave Receiver mode).
<> 144:ef7eb2e8f9f7 491 // Should not get here...
<> 144:ef7eb2e8f9f7 492 return -2;
<> 144:ef7eb2e8f9f7 493 //break;
<> 144:ef7eb2e8f9f7 494 case 0x2: // Slave transmit. Data can be transmitted (Slave Transmitter mode).
<> 144:ef7eb2e8f9f7 495 I2C_SLVDAT(obj) = data & 0xFF; // Store the data for transmission
<> 144:ef7eb2e8f9f7 496 obj->i2c->SLVCTL = (1 << 0); // Continue to send
<> 144:ef7eb2e8f9f7 497
<> 144:ef7eb2e8f9f7 498 return 1;
<> 144:ef7eb2e8f9f7 499 //break;
<> 144:ef7eb2e8f9f7 500 case 0x3: // Reserved.
<> 144:ef7eb2e8f9f7 501 default:
<> 144:ef7eb2e8f9f7 502 // Should not get here...
<> 144:ef7eb2e8f9f7 503 return -3;
<> 144:ef7eb2e8f9f7 504 //break;
<> 144:ef7eb2e8f9f7 505 } // switch status
<> 144:ef7eb2e8f9f7 506 }
<> 144:ef7eb2e8f9f7 507
<> 144:ef7eb2e8f9f7 508
<> 144:ef7eb2e8f9f7 509 //Called when Slave is addressed for Write, Slave will receive Data in polling mode
<> 144:ef7eb2e8f9f7 510 //Parameter length (>=1) is the maximum allowable number of bytes. All bytes will be ACKed.
<> 144:ef7eb2e8f9f7 511 int i2c_slave_read(i2c_t *obj, char *data, int length) {
<> 144:ef7eb2e8f9f7 512 int count=0;
<> 144:ef7eb2e8f9f7 513
<> 144:ef7eb2e8f9f7 514 // Read and ACK all expected bytes
<> 144:ef7eb2e8f9f7 515 while (count < length) {
<> 144:ef7eb2e8f9f7 516 // Wait for data
<> 144:ef7eb2e8f9f7 517 while (!I2C_SLVSI(obj)); // Wait forever
<> 144:ef7eb2e8f9f7 518 // if (i2c_wait_slave_SI(obj) != 0) {return -2;} // Wait with timeout
<> 144:ef7eb2e8f9f7 519
<> 144:ef7eb2e8f9f7 520 // Check State
<> 144:ef7eb2e8f9f7 521 switch(I2C_SLVSTAT(obj)) {
<> 144:ef7eb2e8f9f7 522 case 0x0: // Slave address plus R/W received
<> 144:ef7eb2e8f9f7 523 // At least one of the four slave addresses has been matched by hardware.
<> 144:ef7eb2e8f9f7 524 // You can figure out which address by checking Slave address match Index in STAT register.
<> 144:ef7eb2e8f9f7 525 // I2C Restart occurred
<> 144:ef7eb2e8f9f7 526 return -1;
<> 144:ef7eb2e8f9f7 527 //break;
<> 144:ef7eb2e8f9f7 528
<> 144:ef7eb2e8f9f7 529 case 0x1: // Slave receive. Received data is available (Slave Receiver mode).
<> 144:ef7eb2e8f9f7 530 data[count] = I2C_SLVDAT(obj) & 0xFF; // Get and store the received data
<> 144:ef7eb2e8f9f7 531 obj->i2c->SLVCTL = (1 << 0); // Send ACK on data and Continue to read
<> 144:ef7eb2e8f9f7 532 break;
<> 144:ef7eb2e8f9f7 533
<> 144:ef7eb2e8f9f7 534 case 0x2: // Slave transmit. Data can be transmitted (Slave Transmitter mode).
<> 144:ef7eb2e8f9f7 535 case 0x3: // Reserved.
<> 144:ef7eb2e8f9f7 536 default: // Should never get here...
<> 144:ef7eb2e8f9f7 537 return -2;
<> 144:ef7eb2e8f9f7 538 //break;
<> 144:ef7eb2e8f9f7 539 } // switch status
<> 144:ef7eb2e8f9f7 540
<> 144:ef7eb2e8f9f7 541 count++;
<> 144:ef7eb2e8f9f7 542 } // for all bytes
<> 144:ef7eb2e8f9f7 543
<> 144:ef7eb2e8f9f7 544 return count; // Received the expected number of bytes
<> 144:ef7eb2e8f9f7 545 }
<> 144:ef7eb2e8f9f7 546
<> 144:ef7eb2e8f9f7 547
<> 144:ef7eb2e8f9f7 548 //Called when Slave is addressed for Read, Slave will send Data in polling mode
<> 144:ef7eb2e8f9f7 549 //Parameter length (>=1) is the maximum number of bytes. Exit when Slave byte is NACKed.
<> 144:ef7eb2e8f9f7 550 int i2c_slave_write(i2c_t *obj, const char *data, int length) {
<> 144:ef7eb2e8f9f7 551 int count;
<> 144:ef7eb2e8f9f7 552
<> 144:ef7eb2e8f9f7 553 // Send and all bytes or Exit on NAK
<> 144:ef7eb2e8f9f7 554 for (count=0; count < length; count++) {
<> 144:ef7eb2e8f9f7 555 // Wait until Ready for data
<> 144:ef7eb2e8f9f7 556 while (!I2C_SLVSI(obj)); // Wait forever
<> 144:ef7eb2e8f9f7 557 // if (i2c_wait_slave_SI(obj) != 0) {return -2;} // Wait with timeout
<> 144:ef7eb2e8f9f7 558
<> 144:ef7eb2e8f9f7 559 // Check State
<> 144:ef7eb2e8f9f7 560 switch(I2C_SLVSTAT(obj)) {
<> 144:ef7eb2e8f9f7 561 case 0x0: // Slave address plus R/W received
<> 144:ef7eb2e8f9f7 562 // At least one of the four slave addresses has been matched by hardware.
<> 144:ef7eb2e8f9f7 563 // You can figure out which address by checking Slave address match Index in STAT register.
<> 144:ef7eb2e8f9f7 564 // I2C Restart occurred
<> 144:ef7eb2e8f9f7 565 return -1;
<> 144:ef7eb2e8f9f7 566 //break;
<> 144:ef7eb2e8f9f7 567 case 0x1: // Slave receive. Received data is available (Slave Receiver mode).
<> 144:ef7eb2e8f9f7 568 // Should not get here...
<> 144:ef7eb2e8f9f7 569 return -2;
<> 144:ef7eb2e8f9f7 570 //break;
<> 144:ef7eb2e8f9f7 571 case 0x2: // Slave transmit. Data can be transmitted (Slave Transmitter mode).
<> 144:ef7eb2e8f9f7 572 I2C_SLVDAT(obj) = data[count] & 0xFF; // Store the data for transmission
<> 144:ef7eb2e8f9f7 573 obj->i2c->SLVCTL = (1 << 0); // Continue to send
<> 144:ef7eb2e8f9f7 574 break;
<> 144:ef7eb2e8f9f7 575 case 0x3: // Reserved.
<> 144:ef7eb2e8f9f7 576 default:
<> 144:ef7eb2e8f9f7 577 // Should not get here...
<> 144:ef7eb2e8f9f7 578 return -3;
<> 144:ef7eb2e8f9f7 579 //break;
<> 144:ef7eb2e8f9f7 580 } // switch status
<> 144:ef7eb2e8f9f7 581 } // for all bytes
<> 144:ef7eb2e8f9f7 582
<> 144:ef7eb2e8f9f7 583 return length; // Transmitted the max number of bytes
<> 144:ef7eb2e8f9f7 584 }
<> 144:ef7eb2e8f9f7 585
<> 144:ef7eb2e8f9f7 586
<> 144:ef7eb2e8f9f7 587 // Set the four slave addresses.
<> 144:ef7eb2e8f9f7 588 void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask) {
<> 144:ef7eb2e8f9f7 589 obj->i2c->SLVADR0 = (address & 0xFE); // Store address in address 0 register
<> 144:ef7eb2e8f9f7 590 obj->i2c->SLVADR1 = (0x00 & 0xFE); // Store general call write address in address 1 register
<> 144:ef7eb2e8f9f7 591 obj->i2c->SLVADR2 = (0x01); // Disable address 2 register
<> 144:ef7eb2e8f9f7 592 obj->i2c->SLVADR3 = (0x01); // Disable address 3 register
<> 144:ef7eb2e8f9f7 593 obj->i2c->SLVQUAL0 = (mask & 0xFE); // Qualifier mask for address 0 register. Any maskbit that is 1 will always be a match
<> 144:ef7eb2e8f9f7 594 }
<> 144:ef7eb2e8f9f7 595
<> 144:ef7eb2e8f9f7 596 #endif
<> 144:ef7eb2e8f9f7 597
<> 144:ef7eb2e8f9f7 598 #endif