Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed
WireKinetis.cpp
00001 /* Wire Library for Teensy LC & 3.X 00002 * Copyright (c) 2014-2017, Paul Stoffregen, paul@pjrc.com 00003 * 00004 * Development of this I2C library was funded by PJRC.COM, LLC by sales of 00005 * Teensy and related products. Please support PJRC's efforts to develop 00006 * open source software by purchasing Teensy or other PJRC products. 00007 * 00008 * Permission is hereby granted, free of charge, to any person obtaining a copy 00009 * of this software and associated documentation files (the "Software"), to deal 00010 * in the Software without restriction, including without limitation the rights 00011 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00012 * copies of the Software, and to permit persons to whom the Software is 00013 * furnished to do so, subject to the following conditions: 00014 * 00015 * The above copyright notice, development funding notice, and this permission 00016 * notice shall be included in all copies or substantial portions of the Software. 00017 * 00018 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00019 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00020 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00021 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00022 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00023 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 00024 * THE SOFTWARE. 00025 */ 00026 00027 #include "Wire.h" 00028 00029 #if defined(__arm__) && defined(TEENSYDUINO) 00030 00031 #include "kinetis.h" 00032 #include <string.h> // for memcpy 00033 #include "core_pins.h" 00034 #include "Wire.h" 00035 00036 // undefine these, so we can't accidentally access the hardware directly. 00037 #undef I2C0_A1 00038 #undef I2C0_F 00039 #undef I2C0_C1 00040 #undef I2C0_S 00041 #undef I2C0_D 00042 #undef I2C0_C2 00043 #undef I2C0_FLT 00044 #undef I2C0_RA 00045 #undef I2C0_SMB 00046 #undef I2C0_A2 00047 #undef I2C0_SLTH 00048 #undef I2C0_SLTL 00049 00050 void sda_rising_isr0(void); 00051 void sda_rising_isr1(void); 00052 00053 void TwoWire::begin(void) 00054 { 00055 //serial_begin(BAUD2DIV(115200)); 00056 //serial_print("\nWire Begin\n"); 00057 00058 rxBufferIndex = 0; 00059 rxBufferLength = 0; 00060 txBufferIndex = 0; 00061 txBufferLength = 0; 00062 transmitting = 0; 00063 user_onRequest = NULL; 00064 user_onReceive = NULL; 00065 slave_mode = 0; 00066 hardware.clock_gate_register |= hardware.clock_gate_mask; 00067 port().C1 = 0; 00068 // On Teensy 3.0 external pullup resistors *MUST* be used 00069 // the PORT_PCR_PE bit is ignored when in I2C mode 00070 // I2C will not work at all without pullup resistors 00071 // It might seem like setting PORT_PCR_PE & PORT_PCR_PS 00072 // would enable pullup resistors. However, there seems 00073 // to be a bug in chip while I2C is enabled, where setting 00074 // those causes the port to be driven strongly high. 00075 uint32_t mux; 00076 volatile uint32_t *reg; 00077 reg = portConfigRegister(hardware.sda_pin[sda_pin_index]); 00078 mux = PORT_PCR_MUX(hardware.sda_mux[sda_pin_index]); 00079 *reg = mux|PORT_PCR_ODE|PORT_PCR_SRE|PORT_PCR_DSE; 00080 reg = portConfigRegister(hardware.scl_pin[scl_pin_index]); 00081 mux = PORT_PCR_MUX(hardware.scl_mux[scl_pin_index]); 00082 *reg = mux|PORT_PCR_ODE|PORT_PCR_SRE|PORT_PCR_DSE; 00083 setClock(100000); 00084 port().C2 = I2C_C2_HDRS; 00085 port().C1 = I2C_C1_IICEN; 00086 //pinMode(3, OUTPUT); 00087 //pinMode(4, OUTPUT); 00088 } 00089 00090 void TwoWire::setClock(uint32_t frequency) 00091 { 00092 if (!(hardware.clock_gate_register & hardware.clock_gate_mask)) return; 00093 00094 #if F_BUS == 120000000 00095 if (frequency < 400000) { 00096 port().F = I2C_F_DIV1152; // 104 kHz 00097 } else if (frequency < 1000000) { 00098 port().F = I2C_F_DIV288; // 416 kHz 00099 } else { 00100 port().F = I2C_F_DIV128; // 0.94 MHz 00101 } 00102 port().FLT = 4; 00103 #elif F_BUS == 108000000 00104 if (frequency < 400000) { 00105 port().F = I2C_F_DIV1024; // 105 kHz 00106 } else if (frequency < 1000000) { 00107 port().F = I2C_F_DIV256; // 422 kHz 00108 } else { 00109 port().F = I2C_F_DIV112; // 0.96 MHz 00110 } 00111 port().FLT = 4; 00112 #elif F_BUS == 96000000 00113 if (frequency < 400000) { 00114 port().F = I2C_F_DIV960; // 100 kHz 00115 } else if (frequency < 1000000) { 00116 port().F = I2C_F_DIV240; // 400 kHz 00117 } else { 00118 port().F = I2C_F_DIV96; // 1.0 MHz 00119 } 00120 port().FLT = 4; 00121 #elif F_BUS == 90000000 00122 if (frequency < 400000) { 00123 port().F = I2C_F_DIV896; // 100 kHz 00124 } else if (frequency < 1000000) { 00125 port().F = I2C_F_DIV224; // 402 kHz 00126 } else { 00127 port().F = I2C_F_DIV88; // 1.02 MHz 00128 } 00129 port().FLT = 4; 00130 #elif F_BUS == 80000000 00131 if (frequency < 400000) { 00132 port().F = I2C_F_DIV768; // 104 kHz 00133 } else if (frequency < 1000000) { 00134 port().F = I2C_F_DIV192; // 416 kHz 00135 } else { 00136 port().F = I2C_F_DIV80; // 1.0 MHz 00137 } 00138 port().FLT = 4; 00139 #elif F_BUS == 72000000 00140 if (frequency < 400000) { 00141 port().F = I2C_F_DIV640; // 112 kHz 00142 } else if (frequency < 1000000) { 00143 port().F = I2C_F_DIV192; // 375 kHz 00144 } else { 00145 port().F = I2C_F_DIV72; // 1.0 MHz 00146 } 00147 port().FLT = 4; 00148 #elif F_BUS == 64000000 00149 if (frequency < 400000) { 00150 port().F = I2C_F_DIV640; // 100 kHz 00151 } else if (frequency < 1000000) { 00152 port().F = I2C_F_DIV160; // 400 kHz 00153 } else { 00154 port().F = I2C_F_DIV64; // 1.0 MHz 00155 } 00156 port().FLT = 4; 00157 #elif F_BUS == 60000000 00158 if (frequency < 400000) { 00159 port().F = 0x2C; // 104 kHz 00160 } else if (frequency < 1000000) { 00161 port().F = 0x1C; // 416 kHz 00162 } else { 00163 port().F = 0x12; // 938 kHz 00164 } 00165 port().FLT = 4; 00166 #elif F_BUS == 56000000 00167 if (frequency < 400000) { 00168 port().F = 0x2B; // 109 kHz 00169 } else if (frequency < 1000000) { 00170 port().F = 0x1C; // 389 kHz 00171 } else { 00172 port().F = 0x0E; // 1 MHz 00173 } 00174 port().FLT = 4; 00175 #elif F_BUS == 54000000 00176 if (frequency < 400000) { 00177 port().F = I2C_F_DIV512; // 105 kHz 00178 } else if (frequency < 1000000) { 00179 port().F = I2C_F_DIV128; // 422 kHz 00180 } else { 00181 port().F = I2C_F_DIV56; // 0.96 MHz 00182 } 00183 port().FLT = 4; 00184 #elif F_BUS == 48000000 00185 if (frequency < 400000) { 00186 port().F = 0x27; // 100 kHz 00187 } else if (frequency < 1000000) { 00188 port().F = 0x1A; // 400 kHz 00189 } else { 00190 port().F = 0x0D; // 1 MHz 00191 } 00192 port().FLT = 4; 00193 #elif F_BUS == 40000000 00194 if (frequency < 400000) { 00195 port().F = 0x29; // 104 kHz 00196 } else if (frequency < 1000000) { 00197 port().F = 0x19; // 416 kHz 00198 } else { 00199 port().F = 0x0B; // 1 MHz 00200 } 00201 port().FLT = 3; 00202 #elif F_BUS == 36000000 00203 if (frequency < 400000) { 00204 port().F = 0x28; // 113 kHz 00205 } else if (frequency < 1000000) { 00206 port().F = 0x19; // 375 kHz 00207 } else { 00208 port().F = 0x0A; // 1 MHz 00209 } 00210 port().FLT = 3; 00211 #elif F_BUS == 24000000 00212 if (frequency < 400000) { 00213 port().F = 0x1F; // 100 kHz 00214 } else if (frequency < 1000000) { 00215 port().F = 0x12; // 375 kHz 00216 } else { 00217 port().F = 0x02; // 1 MHz 00218 } 00219 port().FLT = 2; 00220 #elif F_BUS == 16000000 00221 if (frequency < 400000) { 00222 port().F = 0x20; // 100 kHz 00223 } else if (frequency < 1000000) { 00224 port().F = 0x07; // 400 kHz 00225 } else { 00226 port().F = 0x00; // 800 kHz 00227 } 00228 port().FLT = 1; 00229 #elif F_BUS == 8000000 00230 if (frequency < 400000) { 00231 port().F = 0x14; // 100 kHz 00232 } else { 00233 port().F = 0x00; // 400 kHz 00234 } 00235 port().FLT = 1; 00236 #elif F_BUS == 4000000 00237 if (frequency < 400000) { 00238 port().F = 0x07; // 100 kHz 00239 } else { 00240 port().F = 0x00; // 200 kHz 00241 } 00242 port().FLT = 1; 00243 #elif F_BUS == 2000000 00244 port().F = 0x00; // 100 kHz 00245 port().FLT = 1; 00246 #else 00247 #error "F_BUS must be 120, 108, 96, 90, 80, 72, 64, 60, 56, 54, 48, 40, 36, 24, 16, 8, 4 or 2 MHz" 00248 #endif 00249 } 00250 00251 void TwoWire::setSDA(uint8_t pin) 00252 { 00253 if (pin == hardware.sda_pin[sda_pin_index]) return; 00254 uint32_t newindex=0; 00255 while (1) { 00256 uint32_t sda_pin = hardware.sda_pin[newindex]; 00257 if (sda_pin == 255) return; 00258 if (sda_pin == pin) break; 00259 if (++newindex >= sizeof(hardware.sda_pin)) return; 00260 } 00261 if ((hardware.clock_gate_register & hardware.clock_gate_mask)) { 00262 volatile uint32_t *reg; 00263 reg = portConfigRegister(hardware.sda_pin[sda_pin_index]); 00264 *reg = 0; 00265 reg = portConfigRegister(hardware.sda_pin[newindex]); 00266 uint32_t mux = PORT_PCR_MUX(hardware.sda_mux[newindex]); 00267 *reg = mux|PORT_PCR_ODE|PORT_PCR_SRE|PORT_PCR_DSE; 00268 } 00269 sda_pin_index = newindex; 00270 } 00271 00272 void TwoWire::setSCL(uint8_t pin) 00273 { 00274 if (pin == hardware.scl_pin[scl_pin_index]) return; 00275 uint32_t newindex=0; 00276 while (1) { 00277 uint32_t scl_pin = hardware.scl_pin[newindex]; 00278 if (scl_pin == 255) return; 00279 if (scl_pin == pin) break; 00280 if (++newindex >= sizeof(hardware.scl_pin)) return; 00281 } 00282 if ((hardware.clock_gate_register & hardware.clock_gate_mask)) { 00283 volatile uint32_t *reg; 00284 reg = portConfigRegister(hardware.scl_pin[scl_pin_index]); 00285 *reg = 0; 00286 reg = portConfigRegister(hardware.scl_pin[newindex]); 00287 uint32_t mux = PORT_PCR_MUX(hardware.scl_mux[newindex]); 00288 *reg = mux|PORT_PCR_ODE|PORT_PCR_SRE|PORT_PCR_DSE; 00289 } 00290 scl_pin_index = newindex; 00291 } 00292 00293 void TwoWire::begin(uint8_t address) 00294 { 00295 begin(); 00296 port().A1 = address << 1; 00297 slave_mode = 1; 00298 port().C1 = I2C_C1_IICEN | I2C_C1_IICIE; 00299 NVIC_ENABLE_IRQ(hardware.irq); 00300 } 00301 00302 void TwoWire::end() 00303 { 00304 if (!(hardware.clock_gate_register & hardware.clock_gate_mask)) return; 00305 NVIC_DISABLE_IRQ(hardware.irq); 00306 // TODO: should this try to create a stop condition?? 00307 port().C1 = 0; 00308 volatile uint32_t *reg; 00309 reg = portConfigRegister(hardware.scl_pin[scl_pin_index]); 00310 *reg = 0; 00311 reg = portConfigRegister(hardware.sda_pin[sda_pin_index]); 00312 *reg = 0; 00313 hardware.clock_gate_register &= ~hardware.clock_gate_mask; 00314 } 00315 00316 00317 void TwoWire::isr(void) 00318 { 00319 uint8_t status, c1, data; 00320 static uint8_t receiving=0; 00321 00322 status = port().S; 00323 //serial_print("."); 00324 if (status & I2C_S_ARBL) { 00325 // Arbitration Lost 00326 port().S = I2C_S_ARBL; 00327 //serial_print("a"); 00328 if (receiving && rxBufferLength > 0) { 00329 // TODO: does this detect the STOP condition in slave receive mode? 00330 00331 00332 } 00333 if (!(status & I2C_S_IAAS)) return; 00334 } 00335 if (status & I2C_S_IAAS) { 00336 //serial_print("\n"); 00337 // Addressed As A Slave 00338 if (status & I2C_S_SRW) { 00339 //serial_print("T"); 00340 // Begin Slave Transmit 00341 receiving = 0; 00342 txBufferLength = 0; 00343 if (user_onRequest != NULL) { 00344 user_onRequest(); 00345 } 00346 if (txBufferLength == 0) { 00347 // is this correct, transmitting a single zero 00348 // when we should send nothing? Arduino's AVR 00349 // implementation does this, but is it ok? 00350 txBufferLength = 1; 00351 txBuffer[0] = 0; 00352 } 00353 port().C1 = I2C_C1_IICEN | I2C_C1_IICIE | I2C_C1_TX; 00354 port().D = txBuffer[0]; 00355 txBufferIndex = 1; 00356 } else { 00357 // Begin Slave Receive 00358 //serial_print("R"); 00359 receiving = 1; 00360 rxBufferLength = 0; 00361 port().C1 = I2C_C1_IICEN | I2C_C1_IICIE; 00362 data = port().D; 00363 } 00364 port().S = I2C_S_IICIF; 00365 return; 00366 } 00367 #if defined(WIRE_HAS_STOP_INTERRUPT) 00368 c1 = port().FLT; 00369 if ((c1 & I2C_FLT_STOPF) && (c1 & I2C_FLT_STOPIE)) { 00370 port().FLT = c1 & ~I2C_FLT_STOPIE; 00371 if (user_onReceive != NULL) { 00372 rxBufferIndex = 0; 00373 user_onReceive(rxBufferLength); 00374 } 00375 } 00376 #endif 00377 c1 = port().C1; 00378 if (c1 & I2C_C1_TX) { 00379 // Continue Slave Transmit 00380 //serial_print("t"); 00381 if ((status & I2C_S_RXAK) == 0) { 00382 //serial_print("."); 00383 // Master ACK'd previous byte 00384 if (txBufferIndex < txBufferLength) { 00385 port().D = txBuffer[txBufferIndex++]; 00386 } else { 00387 port().D = 0; 00388 } 00389 port().C1 = I2C_C1_IICEN | I2C_C1_IICIE | I2C_C1_TX; 00390 } else { 00391 //serial_print("*"); 00392 // Master did not ACK previous byte 00393 port().C1 = I2C_C1_IICEN | I2C_C1_IICIE; 00394 data = port().D; 00395 } 00396 } else { 00397 // Continue Slave Receive 00398 irqcount = 0; 00399 #ifdef WIRE_HAS_STOP_INTERRUPT 00400 port().FLT |= I2C_FLT_STOPIE; 00401 #else 00402 #if defined(WIRE_IMPLEMENT_WIRE) && !defined(WIRE_IMPLEMENT_WIRE1) 00403 attachInterrupt(hardware.sda_pin[sda_pin_index], sda_rising_isr0, RISING); 00404 #elif !defined(WIRE_IMPLEMENT_WIRE) && defined(WIRE_IMPLEMENT_WIRE1) 00405 attachInterrupt(hardware.sda_pin[sda_pin_index], sda_rising_isr1, RISING); 00406 #elif defined(WIRE_IMPLEMENT_WIRE) && defined(WIRE_IMPLEMENT_WIRE1) 00407 if (this == &Wire) { 00408 attachInterrupt(hardware.sda_pin[sda_pin_index], sda_rising_isr0, RISING); 00409 } else if (this == &Wire1) { 00410 attachInterrupt(hardware.sda_pin[sda_pin_index], sda_rising_isr1, RISING); 00411 } 00412 #endif 00413 #endif // WIRE_HAS_STOP_INTERRUPT 00414 //digitalWriteFast(4, HIGH); 00415 data = port().D; 00416 //serial_phex(data); 00417 if (rxBufferLength < BUFFER_LENGTH && receiving) { 00418 rxBuffer[rxBufferLength++] = data; 00419 } 00420 //digitalWriteFast(4, LOW); 00421 } 00422 port().S = I2C_S_IICIF; 00423 } 00424 00425 00426 // Detects the stop condition that terminates a slave receive transfer. 00427 // Sadly, the I2C in older Kinetis K series lacks the stop detect interrupt 00428 // This pin change interrupt hack is needed to detect the stop condition 00429 #if !defined(WIRE_HAS_STOP_INTERRUPT) 00430 00431 #if defined(WIRE_IMPLEMENT_WIRE) 00432 void sda_rising_isr0(void) 00433 { 00434 Wire.sda_rising_isr(); 00435 } 00436 #endif 00437 #if defined(WIRE_IMPLEMENT_WIRE1) 00438 void sda_rising_isr1(void) 00439 { 00440 Wire1.sda_rising_isr(); 00441 } 00442 #endif 00443 00444 void TwoWire::sda_rising_isr(void) 00445 { 00446 //digitalWrite(3, HIGH); 00447 if (!(port().S & I2C_S_BUSY)) { 00448 detachInterrupt(hardware.sda_pin[sda_pin_index]); 00449 if (user_onReceive != NULL) { 00450 rxBufferIndex = 0; 00451 user_onReceive(rxBufferLength); 00452 } 00453 //delayMicroseconds(100); 00454 } else { 00455 if (++irqcount >= 2 || !slave_mode) { 00456 detachInterrupt(hardware.sda_pin[sda_pin_index]); 00457 } 00458 } 00459 //digitalWrite(3, LOW); 00460 } 00461 #endif // !WIRE_HAS_STOP_INTERRUPT 00462 00463 00464 // Chapter 44: Inter-Integrated Circuit (I2C) - Page 1012 00465 // I2C0_A1 // I2C Address Register 1 00466 // I2C0_F // I2C Frequency Divider register 00467 // I2C0_C1 // I2C Control Register 1 00468 // I2C0_S // I2C Status register 00469 // I2C0_D // I2C Data I/O register 00470 // I2C0_C2 // I2C Control Register 2 00471 // I2C0_FLT // I2C Programmable Input Glitch Filter register 00472 00473 size_t TwoWire::write(uint8_t data) 00474 { 00475 if (transmitting || slave_mode) { 00476 if (txBufferLength >= BUFFER_LENGTH+1) { 00477 setWriteError(); 00478 return 0; 00479 } 00480 txBuffer[txBufferLength++] = data; 00481 return 1; 00482 } 00483 return 0; 00484 } 00485 00486 size_t TwoWire::write(const uint8_t *data, size_t quantity) 00487 { 00488 if (transmitting || slave_mode) { 00489 size_t avail = BUFFER_LENGTH+1 - txBufferLength; 00490 if (quantity > avail) { 00491 quantity = avail; 00492 setWriteError(); 00493 } 00494 memcpy(txBuffer + txBufferLength, data, quantity); 00495 txBufferLength += quantity; 00496 return quantity; 00497 } 00498 return 0; 00499 } 00500 00501 bool TwoWire::wait_idle(void) 00502 { 00503 bool reset=false; 00504 uint32_t wait_begin = millis(); 00505 00506 //Serial.print("busy:"); 00507 while (i2c_status() & I2C_S_BUSY) { 00508 //Serial.write('.') ; 00509 uint32_t waited = millis() - wait_begin; 00510 #if 1 00511 if (waited > 15 && !reset) { 00512 reset = true; 00513 //Serial.println("attempt forced reset"); 00514 uint8_t sda_pin = hardware.sda_pin[sda_pin_index]; 00515 pinMode(sda_pin, INPUT_DISABLE); 00516 uint8_t scl_pin = hardware.scl_pin[sda_pin_index]; 00517 pinMode(scl_pin, OUTPUT); 00518 for (int i=0; i < 9; i++) { 00519 digitalWrite(scl_pin, LOW); 00520 delayMicroseconds(5); 00521 digitalWrite(scl_pin, HIGH); 00522 delayMicroseconds(5); 00523 } 00524 uint32_t mux; 00525 volatile uint32_t *reg; 00526 reg = portConfigRegister(hardware.sda_pin[sda_pin_index]); 00527 mux = PORT_PCR_MUX(hardware.sda_mux[sda_pin_index]); 00528 *reg = mux|PORT_PCR_ODE|PORT_PCR_SRE|PORT_PCR_DSE; 00529 reg = portConfigRegister(hardware.scl_pin[scl_pin_index]); 00530 mux = PORT_PCR_MUX(hardware.scl_mux[scl_pin_index]); 00531 *reg = mux|PORT_PCR_ODE|PORT_PCR_SRE|PORT_PCR_DSE; 00532 delayMicroseconds(10); 00533 continue; 00534 } 00535 #endif 00536 if (waited > 16) { 00537 // bus stuck busy too long 00538 port().C1 = 0; 00539 port().C1 = I2C_C1_IICEN; 00540 //Serial.println("abort"); 00541 //return 4; // timeout waiting for bus 00542 return false; 00543 } 00544 } 00545 return true; 00546 } 00547 00548 uint8_t TwoWire::endTransmission(uint8_t sendStop) 00549 { 00550 uint8_t i, status, ret=0; 00551 uint32_t wait_begin; 00552 00553 // clear the status flags 00554 port().S = I2C_S_IICIF | I2C_S_ARBL; 00555 // now take control of the bus... 00556 if (port().C1 & I2C_C1_MST) { 00557 // we are already the bus master, so send a repeated start 00558 //Serial.print("rstart:"); 00559 port().C1 = I2C_C1_IICEN | I2C_C1_MST | I2C_C1_RSTA | I2C_C1_TX; 00560 } else { 00561 // we are not currently the bus master, so wait for bus ready 00562 if (!wait_idle()) { 00563 //Serial.printf("endTransmission err1\n"); 00564 return 4; // timeout waiting for bus 00565 } 00566 // become the bus master in transmit mode (send start) 00567 slave_mode = 0; 00568 port().C1 = I2C_C1_IICEN | I2C_C1_MST | I2C_C1_TX; 00569 } 00570 // wait until start condition establishes control of the bus 00571 wait_begin = millis(); 00572 while (1) { 00573 status = i2c_status(); 00574 if ((status & I2C_S_BUSY)) break; 00575 //Serial.write('*') ; 00576 if (millis() - wait_begin > 4) { 00577 port().C1 = 0; 00578 port().C1 = I2C_C1_IICEN; 00579 //Serial.println("abort2"); 00580 //Serial.printf("endTransmission err2\n"); 00581 return 4; // error generating start condition 00582 } 00583 } 00584 // transmit the address and data 00585 for (i=0; i < txBufferLength; i++) { 00586 port().D = txBuffer[i]; 00587 //Serial.write('^'); 00588 wait_begin = millis(); 00589 while (1) { 00590 status = i2c_status(); 00591 if ((status & I2C_S_IICIF)) break; 00592 if (!(status & I2C_S_BUSY)) break; 00593 if (millis() - wait_begin > 5) { 00594 port().C1 = 0; 00595 port().C1 = I2C_C1_IICEN; 00596 //Serial.println("abort3"); 00597 //Serial.printf("endTransmission err3\n"); 00598 return 4; // clock stretch too long 00599 } 00600 } 00601 port().S = I2C_S_IICIF; 00602 //Serial.write('$'); 00603 status = i2c_status(); 00604 if ((status & I2C_S_ARBL)) { 00605 // we lost bus arbitration to another master 00606 // TODO: what is the proper thing to do here?? 00607 //Serial.printf(" c1=%02X ", port().C1); 00608 port().C1 = I2C_C1_IICEN; 00609 //Serial.printf("endTransmission err4\n"); 00610 ret = 4; // 4:other error 00611 break; 00612 } 00613 if (!(status & I2C_S_BUSY)) { 00614 // suddenly lost control of the bus! 00615 port().C1 = I2C_C1_IICEN; 00616 //Serial.printf("endTransmission err5\n"); 00617 ret = 4; // 4:other error 00618 break; 00619 } 00620 if (status & I2C_S_RXAK) { 00621 // the slave device did not acknowledge 00622 if (i == 0) { 00623 //Serial.printf("endTransmission err6\n"); 00624 ret = 2; // 2:received NACK on transmit of address 00625 } else { 00626 //Serial.printf("endTransmission err7\n"); 00627 ret = 3; // 3:received NACK on transmit of data 00628 } 00629 sendStop = 1; 00630 break; 00631 } 00632 } 00633 if (sendStop) { 00634 // send the stop condition 00635 port().C1 = I2C_C1_IICEN; 00636 // TODO: do we wait for this somehow? 00637 } 00638 transmitting = 0; 00639 //Serial.print(" ret="); 00640 //Serial.println(ret); 00641 return ret; 00642 } 00643 00644 00645 uint8_t TwoWire::requestFrom(uint8_t address, uint8_t length, uint8_t sendStop) 00646 { 00647 uint8_t tmp __attribute__((unused)); 00648 uint8_t status, count=0; 00649 uint32_t wait_begin; 00650 00651 rxBufferIndex = 0; 00652 rxBufferLength = 0; 00653 //serial_print("requestFrom\n"); 00654 // clear the status flags 00655 port().S = I2C_S_IICIF | I2C_S_ARBL; 00656 // now take control of the bus... 00657 if (port().C1 & I2C_C1_MST) { 00658 // we are already the bus master, so send a repeated start 00659 port().C1 = I2C_C1_IICEN | I2C_C1_MST | I2C_C1_RSTA | I2C_C1_TX; 00660 } else { 00661 // we are not currently the bus master, so wait for bus ready 00662 if (!wait_idle()) { 00663 //Serial.printf("requestFrom err1\n"); 00664 return 0; // timeout waiting for bus 00665 } 00666 // become the bus master in transmit mode (send start) 00667 slave_mode = 0; 00668 port().C1 = I2C_C1_IICEN | I2C_C1_MST | I2C_C1_TX; 00669 } 00670 00671 // wait until start condition establishes control of the bus 00672 wait_begin = millis(); 00673 while (1) { 00674 status = i2c_status(); 00675 if ((status & I2C_S_BUSY)) break; 00676 if (millis() - wait_begin > 4) { 00677 port().C1 = 0; 00678 port().C1 = I2C_C1_IICEN; 00679 //Serial.printf("requestFrom err2\n"); 00680 return 0; // error generating start condition 00681 } 00682 } 00683 // send the address 00684 port().D = (address << 1) | 1; 00685 wait_begin = millis(); 00686 while (!(port().S & I2C_S_IICIF)) { 00687 if (millis() - wait_begin > 5) { 00688 port().C1 = 0; 00689 port().C1 = I2C_C1_IICEN; 00690 //Serial.printf("requestFrom err3\n"); 00691 return 0; // clock stretch too long (during address) 00692 } 00693 } 00694 port().S = I2C_S_IICIF; 00695 status = i2c_status(); 00696 if ((status & I2C_S_RXAK) || (status & I2C_S_ARBL)) { 00697 // the slave device did not acknowledge 00698 // or we lost bus arbitration to another master 00699 port().C1 = I2C_C1_IICEN; 00700 //Serial.printf("requestFrom err4\n"); 00701 return 0; 00702 } 00703 if (length == 0) { 00704 // TODO: does anybody really do zero length reads? 00705 // if so, does this code really work? 00706 port().C1 = I2C_C1_IICEN | (sendStop ? 0 : I2C_C1_MST); 00707 //Serial.printf("requestFrom err5\n"); 00708 return 0; 00709 } else if (length == 1) { 00710 port().C1 = I2C_C1_IICEN | I2C_C1_MST | I2C_C1_TXAK; 00711 } else { 00712 port().C1 = I2C_C1_IICEN | I2C_C1_MST; 00713 } 00714 tmp = port().D; // initiate the first receive 00715 //delayMicroseconds(250); 00716 while (length > 1) { 00717 wait_begin = millis(); 00718 while (!(port().S & I2C_S_IICIF)) { 00719 if (millis() - wait_begin > 5) { 00720 port().C1 = 0; 00721 port().C1 = I2C_C1_IICEN; 00722 rxBufferLength = count; 00723 //Serial.printf("requestFrom err6\n"); 00724 return count; // clock stretch too long (during data) 00725 } 00726 } 00727 port().S = I2C_S_IICIF; 00728 status = port().S; 00729 if ((status & I2C_S_ARBL)) { 00730 // we lost bus arbitration to another master 00731 // or suddenly lost control of the bus! 00732 // TODO: what is the proper thing to do here?? 00733 //Serial.printf("requestFrom err7a\n"); 00734 return count; 00735 } 00736 if (!(status & I2C_S_BUSY)) { 00737 // we lost bus arbitration to another master 00738 // or suddenly lost control of the bus! 00739 // TODO: what is the proper thing to do here?? 00740 //Serial.printf("requestFrom err7b\n"); 00741 return count; 00742 } 00743 length--; 00744 if (length == 1) port().C1 = I2C_C1_IICEN | I2C_C1_MST | I2C_C1_TXAK; 00745 if (count < BUFFER_LENGTH) { 00746 rxBuffer[count++] = port().D; 00747 } else { 00748 tmp = port().D; 00749 } 00750 } 00751 wait_begin = millis(); 00752 while (!(port().S & I2C_S_IICIF)) { 00753 if (millis() - wait_begin > 5) { 00754 port().C1 = 0; 00755 port().C1 = I2C_C1_IICEN; 00756 rxBufferLength = count; 00757 //Serial.printf("requestFrom err8\n"); 00758 return count; // clock stretch too long (during data) 00759 } 00760 } 00761 port().S = I2C_S_IICIF; 00762 status = port().S; 00763 if ((status & I2C_S_ARBL)) { 00764 // we lost bus arbitration to another master 00765 // or suddenly lost control of the bus! 00766 // TODO: what is the proper thing to do here?? 00767 //digitalWriteFast(13, HIGH); 00768 port().S = I2C_S_ARBL; 00769 delayMicroseconds(5); 00770 port().C1 &= ~I2C_C1_TXAK; 00771 //Serial.printf("requestFrom err9a\n"); 00772 return count; 00773 } 00774 if (!(status & I2C_S_BUSY)) { 00775 // we lost bus arbitration to another master 00776 // or suddenly lost control of the bus! 00777 // TODO: what is the proper thing to do here?? 00778 //Serial.printf("requestFrom err9b\n"); 00779 return count; 00780 } 00781 port().C1 = I2C_C1_IICEN | I2C_C1_MST | I2C_C1_TX; 00782 if (count < BUFFER_LENGTH) { 00783 rxBuffer[count++] = port().D; 00784 } else { 00785 tmp = port().D; 00786 } 00787 #if F_CPU > 120000000 00788 __asm__("nop"); 00789 __asm__("nop"); 00790 __asm__("nop"); 00791 #endif 00792 if (sendStop) port().C1 = I2C_C1_IICEN; 00793 rxBufferLength = count; 00794 return count; 00795 } 00796 00797 // for compatibility with examples that directly call this AVR-specific function 00798 // https://learn.adafruit.com/adafruit-tca9548a-1-to-8-i2c-multiplexer-breakout/wiring-and-test 00799 // https://forum.pjrc.com/threads/44922-Undefined-reference-to-twi_writeTo 00800 extern "C" 00801 uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait, uint8_t sendStop) 00802 { 00803 if (!wait) return 4; 00804 Wire.beginTransmission(address); 00805 while (length) { 00806 Wire.write(*data++); 00807 length--; 00808 } 00809 return Wire.endTransmission(sendStop); 00810 } 00811 00812 constexpr TwoWire::I2C_Hardware_t TwoWire::i2c0_hardware = { 00813 SIM_SCGC4, SIM_SCGC4_I2C0, 00814 #if defined(__MKL26Z64__) || defined(__MK20DX128__) || defined(__MK20DX256__) 00815 18, 17, 255, 255, 255, 00816 2, 2, 0, 0, 0, 00817 19, 16, 255, 255, 255, 00818 2, 2, 0, 0, 0, 00819 #elif defined(__MK64FX512__) || defined(__MK66FX1M0__) 00820 18, 17, 34, 8, 48, 00821 2, 2, 5, 7, 2, 00822 19, 16, 33, 7, 47, 00823 2, 2, 5, 7, 2, 00824 #endif 00825 IRQ_I2C0 00826 }; 00827 00828 #if defined(__MKL26Z64__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__) 00829 constexpr TwoWire::I2C_Hardware_t TwoWire::i2c1_hardware = { 00830 SIM_SCGC4, SIM_SCGC4_I2C1, 00831 #if defined(__MKL26Z64__) 00832 23, 255, 255, 255, 255, 00833 2, 0, 0, 0, 0, 00834 22, 255, 255, 255, 255, 00835 2, 0, 0, 0, 0, 00836 #elif defined(__MK20DX256__) 00837 30, 255, 255, 255, 255, 00838 2, 0, 0, 0, 0, 00839 29, 255, 255, 255, 255, 00840 2, 0, 0, 0, 0, 00841 #elif defined(__MK64FX512__) || defined(__MK66FX1M0__) 00842 38, 58, 255, 255, 255, 00843 2, 6, 0, 0, 0, 00844 37, 59, 255, 255, 255, 00845 2, 6, 0, 0, 0, 00846 #endif 00847 IRQ_I2C1 00848 }; 00849 #endif 00850 00851 #if defined(__MK64FX512__) || defined(__MK66FX1M0__) 00852 constexpr TwoWire::I2C_Hardware_t TwoWire::i2c2_hardware = { 00853 SIM_SCGC1, SIM_SCGC1_I2C2, 00854 #if defined(__MK64FX512__) || defined(__MK66FX1M0__) 00855 4, 255, 255, 255, 255, 00856 5, 0, 0, 0, 0, 00857 3, 26, 255, 255, 255, 00858 5, 5, 0, 0, 0, 00859 #endif 00860 IRQ_I2C2 00861 }; 00862 #endif 00863 00864 #if defined(__MK66FX1M0__) 00865 constexpr TwoWire::I2C_Hardware_t TwoWire::i2c3_hardware = { 00866 SIM_SCGC1, SIM_SCGC1_I2C3, 00867 #if defined(__MK66FX1M0__) 00868 56, 255, 255, 255, 255, 00869 2, 0, 0, 0, 0, 00870 57, 255, 255, 255, 255, 00871 2, 0, 0, 0, 0, 00872 #endif 00873 IRQ_I2C3 00874 }; 00875 #endif 00876 00877 // Helper to transform a non-constant expression of the form 00878 // &(*(KINETIS_I2C_t *)0x40066000) 00879 // into a compile time constant. 00880 #define MAKE_CONST(x) (__builtin_constant_p(x) ? (x) : (x)) 00881 00882 #ifdef WIRE_IMPLEMENT_WIRE 00883 constexpr uintptr_t i2c0_addr = uintptr_t(MAKE_CONST(&KINETIS_I2C0)); 00884 TwoWire Wire(i2c0_addr, TwoWire::i2c0_hardware); 00885 void i2c0_isr(void) { Wire.isr(); } 00886 #endif 00887 #ifdef WIRE_IMPLEMENT_WIRE1 00888 constexpr uintptr_t i2c1_addr = uintptr_t(MAKE_CONST(&KINETIS_I2C1)); 00889 TwoWire Wire1(i2c1_addr, TwoWire::i2c1_hardware); 00890 void i2c1_isr(void) { Wire1.isr(); } 00891 #endif 00892 #ifdef WIRE_IMPLEMENT_WIRE2 00893 constexpr uintptr_t i2c2_addr = uintptr_t(MAKE_CONST(&KINETIS_I2C2)); 00894 TwoWire Wire2(i2c2_addr, TwoWire::i2c2_hardware); 00895 void i2c2_isr(void) { Wire2.isr(); } 00896 #endif 00897 #ifdef WIRE_IMPLEMENT_WIRE3 00898 constexpr uintptr_t i2c3_addr = uintptr_t(MAKE_CONST(&KINETIS_I2C3)); 00899 TwoWire Wire3(i2c3_addr, TwoWire::i2c3_hardware); 00900 void i2c3_isr(void) { Wire3.isr(); } 00901 #endif 00902 00903 00904 #endif // __arm__ && TEENSYDUINO
Generated on Sat Jul 16 2022 20:55:16 by
1.7.2