Mbed for ESIMEos / Mbed 2 deprecated FRDM-KL46Z_LCD_I2C_demo

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers WireKinetis.cpp Source File

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