mbed library sources. Supersedes mbed-src. Fixed broken STM32F1xx RTC on rtc_api.c

Dependents:   Nucleo_F103RB_RTC_battery_bkup_pwr_off_okay

Fork of mbed-dev by mbed official

Committer:
maxxir
Date:
Tue Nov 07 16:46:29 2017 +0000
Revision:
177:619788de047e
Parent:
149:156823d33999
To fix broken RTC on Nucleo_F103RB / STM32F103 BluePill etc..;  Used direct RTC register manipulation for STM32F1xx;  rtc_read() && rtc_write()  (native rtc_init() - works good);  also added stub for non-working on STM32F1xx rtc_read_subseconds().

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