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.h
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 #ifndef TwoWireKinetis_h 00028 #define TwoWireKinetis_h 00029 00030 #if defined(__arm__) && defined(TEENSYDUINO) 00031 00032 #include <inttypes.h> 00033 #include "Arduino.h" 00034 00035 #define BUFFER_LENGTH 32 00036 #define WIRE_HAS_END 1 00037 00038 00039 // Teensy LC 00040 #if defined(__MKL26Z64__) 00041 #define WIRE_IMPLEMENT_WIRE 00042 //Wire1 consumes precious memory on Teensy LC 00043 //#define WIRE_IMPLEMENT_WIRE1 00044 #define WIRE_HAS_STOP_INTERRUPT 00045 00046 // Teensy 3.0 00047 #elif defined(__MK20DX128__) 00048 #define WIRE_IMPLEMENT_WIRE 00049 00050 // Teensy 3.1 & 3.2 00051 #elif defined(__MK20DX256__) 00052 #define WIRE_IMPLEMENT_WIRE 00053 #define WIRE_IMPLEMENT_WIRE1 00054 00055 // Teensy 3.5 00056 #elif defined(__MK64FX512__) 00057 #define WIRE_IMPLEMENT_WIRE 00058 #define WIRE_IMPLEMENT_WIRE1 00059 #define WIRE_IMPLEMENT_WIRE2 00060 #define WIRE_HAS_START_INTERRUPT 00061 #define WIRE_HAS_STOP_INTERRUPT 00062 00063 // Teensy 3.6 00064 #elif defined(__MK66FX1M0__) 00065 #define WIRE_IMPLEMENT_WIRE 00066 #define WIRE_IMPLEMENT_WIRE1 00067 #define WIRE_IMPLEMENT_WIRE2 00068 //Wire3 is seldom used on Teensy 3.6 00069 //#define WIRE_IMPLEMENT_WIRE3 00070 #define WIRE_HAS_START_INTERRUPT 00071 #define WIRE_HAS_STOP_INTERRUPT 00072 00073 #endif 00074 00075 00076 class TwoWire : public Stream 00077 { 00078 public: 00079 // Hardware description struct 00080 typedef struct { 00081 volatile uint32_t &clock_gate_register; 00082 uint32_t clock_gate_mask; 00083 uint8_t sda_pin[5]; 00084 uint8_t sda_mux[5]; 00085 uint8_t scl_pin[5]; 00086 uint8_t scl_mux[5]; 00087 IRQ_NUMBER_t irq; 00088 } I2C_Hardware_t; 00089 static const I2C_Hardware_t i2c0_hardware; 00090 static const I2C_Hardware_t i2c1_hardware; 00091 static const I2C_Hardware_t i2c2_hardware; 00092 static const I2C_Hardware_t i2c3_hardware; 00093 public: 00094 constexpr TwoWire(uintptr_t port_addr, const I2C_Hardware_t &myhardware) 00095 : port_addr(port_addr), hardware(myhardware) { 00096 } 00097 void begin(); 00098 void begin(uint8_t address); 00099 void begin(int address) { 00100 begin((uint8_t)address); 00101 } 00102 void end(); 00103 void setClock(uint32_t frequency); 00104 void setSDA(uint8_t pin); 00105 void setSCL(uint8_t pin); 00106 void beginTransmission(uint8_t address) { 00107 txBuffer[0] = (address << 1); 00108 transmitting = 1; 00109 txBufferLength = 1; 00110 } 00111 void beginTransmission(int address) { 00112 beginTransmission((uint8_t)address); 00113 } 00114 uint8_t endTransmission(uint8_t sendStop); 00115 uint8_t endTransmission(void) { 00116 return endTransmission(1); 00117 } 00118 uint8_t requestFrom(uint8_t address, uint8_t quantity, uint8_t sendStop); 00119 uint8_t requestFrom(uint8_t address, uint8_t quantity) { 00120 return requestFrom(address, quantity, (uint8_t)1); 00121 } 00122 uint8_t requestFrom(int address, int quantity, int sendStop) { 00123 return requestFrom((uint8_t)address, (uint8_t)quantity, 00124 (uint8_t)(sendStop ? 1 : 0)); 00125 } 00126 uint8_t requestFrom(int address, int quantity) { 00127 return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)1); 00128 } 00129 virtual size_t write(uint8_t data); 00130 virtual size_t write(const uint8_t *data, size_t quantity); 00131 virtual int available(void) { 00132 return rxBufferLength - rxBufferIndex; 00133 } 00134 virtual int read(void) { 00135 if (rxBufferIndex >= rxBufferLength) return -1; 00136 return rxBuffer[rxBufferIndex++]; 00137 } 00138 virtual int peek(void) { 00139 if (rxBufferIndex >= rxBufferLength) return -1; 00140 return rxBuffer[rxBufferIndex]; 00141 } 00142 virtual void flush(void) { 00143 } 00144 void onReceive(void (*function)(int numBytes)) { 00145 user_onReceive = function; 00146 } 00147 void onRequest(void (*function)(void)) { 00148 user_onRequest = function; 00149 } 00150 // send() for compatibility with very old sketches and libraries 00151 void send(uint8_t b) { 00152 write(b); 00153 } 00154 void send(uint8_t *s, uint8_t n) { 00155 write(s, n); 00156 } 00157 void send(int n) { 00158 write((uint8_t)n); 00159 } 00160 void send(char *s) { 00161 write(s); 00162 } 00163 uint8_t receive(void) { 00164 int c = read(); 00165 if (c < 0) return 0; 00166 return c; 00167 } 00168 size_t write(unsigned long n) { 00169 return write((uint8_t)n); 00170 } 00171 size_t write(long n) { 00172 return write((uint8_t)n); 00173 } 00174 size_t write(unsigned int n) { 00175 return write((uint8_t)n); 00176 } 00177 size_t write(int n) { 00178 return write((uint8_t)n); 00179 } 00180 using Print::write; 00181 private: 00182 KINETIS_I2C_t& port() { return (*(KINETIS_I2C_t *) port_addr); } 00183 uint8_t i2c_status(void) { 00184 return port().S; 00185 } 00186 void isr(void); 00187 bool wait_idle(void); 00188 uintptr_t port_addr; 00189 const I2C_Hardware_t &hardware; 00190 uint8_t rxBuffer[BUFFER_LENGTH] = {}; 00191 uint8_t rxBufferIndex = 0; 00192 uint8_t rxBufferLength = 0; 00193 uint8_t txAddress = 0; 00194 uint8_t txBuffer[BUFFER_LENGTH+1] = {}; 00195 uint8_t txBufferIndex = 0; 00196 uint8_t txBufferLength = 0; 00197 uint8_t transmitting = 0; 00198 uint8_t slave_mode = 0; 00199 uint8_t irqcount = 0; 00200 uint8_t sda_pin_index = 0; 00201 uint8_t scl_pin_index = 0; 00202 void onRequestService(void); 00203 void onReceiveService(uint8_t*, int); 00204 void (*user_onRequest)(void) = nullptr; 00205 void (*user_onReceive)(int) = nullptr; 00206 void sda_rising_isr(void); 00207 friend void i2c0_isr(void); 00208 friend void i2c1_isr(void); 00209 friend void i2c2_isr(void); 00210 friend void i2c3_isr(void); 00211 friend void sda_rising_isr0(void); 00212 friend void sda_rising_isr1(void); 00213 }; 00214 00215 #ifdef WIRE_IMPLEMENT_WIRE 00216 extern TwoWire Wire; 00217 #endif 00218 #ifdef WIRE_IMPLEMENT_WIRE1 00219 extern TwoWire Wire1; 00220 #endif 00221 #ifdef WIRE_IMPLEMENT_WIRE2 00222 extern TwoWire Wire2; 00223 #endif 00224 #ifdef WIRE_IMPLEMENT_WIRE3 00225 extern TwoWire Wire3; 00226 #endif 00227 00228 00229 class TWBRemulation 00230 { 00231 public: 00232 inline TWBRemulation & operator = (int val) __attribute__((always_inline)) { 00233 if (val == 12 || val == ((F_CPU / 400000) - 16) / 2) { // 22, 52, 112 00234 I2C0_C1 = 0; 00235 #if F_BUS == 120000000 00236 I2C0_F = I2C_F_DIV288; // 416 kHz 00237 #elif F_BUS == 108000000 00238 I2C0_F = I2C_F_DIV256; // 422 kHz 00239 #elif F_BUS == 96000000 00240 I2C0_F = I2C_F_DIV240; // 400 kHz 00241 #elif F_BUS == 90000000 00242 I2C0_F = I2C_F_DIV224; // 402 kHz 00243 #elif F_BUS == 80000000 00244 I2C0_F = I2C_F_DIV192; // 416 kHz 00245 #elif F_BUS == 72000000 00246 I2C0_F = I2C_F_DIV192; // 375 kHz 00247 #elif F_BUS == 64000000 00248 I2C0_F = I2C_F_DIV160; // 400 kHz 00249 #elif F_BUS == 60000000 00250 I2C0_F = I2C_F_DIV144; // 416 kHz 00251 #elif F_BUS == 56000000 00252 I2C0_F = I2C_F_DIV144; // 389 kHz 00253 #elif F_BUS == 54000000 00254 I2C0_F = I2C_F_DIV128; // 422 kHz 00255 #elif F_BUS == 48000000 00256 I2C0_F = I2C_F_DIV112; // 400 kHz 00257 #elif F_BUS == 40000000 00258 I2C0_F = I2C_F_DIV96; // 416 kHz 00259 #elif F_BUS == 36000000 00260 I2C0_F = I2C_F_DIV96; // 375 kHz 00261 #elif F_BUS == 24000000 00262 I2C0_F = I2C_F_DIV64; // 375 kHz 00263 #elif F_BUS == 16000000 00264 I2C0_F = I2C_F_DIV40; // 400 kHz 00265 #elif F_BUS == 8000000 00266 I2C0_F = I2C_F_DIV20; // 400 kHz 00267 #elif F_BUS == 4000000 00268 I2C0_F = I2C_F_DIV20; // 200 kHz 00269 #elif F_BUS == 2000000 00270 I2C0_F = I2C_F_DIV20; // 100 kHz 00271 #endif 00272 I2C0_C1 = I2C_C1_IICEN; 00273 } else if (val == 72 || val == ((F_CPU / 100000) - 16) / 2) { // 112, 232, 472 00274 I2C0_C1 = 0; 00275 #if F_BUS == 120000000 00276 I2C0_F = I2C_F_DIV1152; // 104 kHz 00277 #elif F_BUS == 108000000 00278 I2C0_F = I2C_F_DIV1024; // 105 kHz 00279 #elif F_BUS == 96000000 00280 I2C0_F = I2C_F_DIV960; // 100 kHz 00281 #elif F_BUS == 90000000 00282 I2C0_F = I2C_F_DIV896; // 100 kHz 00283 #elif F_BUS == 80000000 00284 I2C0_F = I2C_F_DIV768; // 104 kHz 00285 #elif F_BUS == 72000000 00286 I2C0_F = I2C_F_DIV640; // 112 kHz 00287 #elif F_BUS == 64000000 00288 I2C0_F = I2C_F_DIV640; // 100 kHz 00289 #elif F_BUS == 60000000 00290 I2C0_F = I2C_F_DIV576; // 104 kHz 00291 #elif F_BUS == 56000000 00292 I2C0_F = I2C_F_DIV512; // 109 kHz 00293 #elif F_BUS == 54000000 00294 I2C0_F = I2C_F_DIV512; // 105 kHz 00295 #elif F_BUS == 48000000 00296 I2C0_F = I2C_F_DIV480; // 100 kHz 00297 #elif F_BUS == 40000000 00298 I2C0_F = I2C_F_DIV384; // 104 kHz 00299 #elif F_BUS == 36000000 00300 I2C0_F = I2C_F_DIV320; // 113 kHz 00301 #elif F_BUS == 24000000 00302 I2C0_F = I2C_F_DIV240; // 100 kHz 00303 #elif F_BUS == 16000000 00304 I2C0_F = I2C_F_DIV160; // 100 kHz 00305 #elif F_BUS == 8000000 00306 I2C0_F = I2C_F_DIV80; // 100 kHz 00307 #elif F_BUS == 4000000 00308 I2C0_F = I2C_F_DIV40; // 100 kHz 00309 #elif F_BUS == 2000000 00310 I2C0_F = I2C_F_DIV20; // 100 kHz 00311 #endif 00312 I2C0_C1 = I2C_C1_IICEN; 00313 } 00314 return *this; 00315 } 00316 inline operator int () const __attribute__((always_inline)) { 00317 #if F_BUS == 120000000 00318 if (I2C0_F == I2C_F_DIV288) return 12; 00319 #elif F_BUS == 108000000 00320 if (I2C0_F == I2C_F_DIV256) return 12; 00321 #elif F_BUS == 96000000 00322 if (I2C0_F == I2C_F_DIV240) return 12; 00323 #elif F_BUS == 90000000 00324 if (I2C0_F == I2C_F_DIV224) return 12; 00325 #elif F_BUS == 80000000 00326 if (I2C0_F == I2C_F_DIV192) return 12; 00327 #elif F_BUS == 72000000 00328 if (I2C0_F == I2C_F_DIV192) return 12; 00329 #elif F_BUS == 64000000 00330 if (I2C0_F == I2C_F_DIV160) return 12; 00331 #elif F_BUS == 60000000 00332 if (I2C0_F == I2C_F_DIV144) return 12; 00333 #elif F_BUS == 56000000 00334 if (I2C0_F == I2C_F_DIV144) return 12; 00335 #elif F_BUS == 54000000 00336 if (I2C0_F == I2C_F_DIV128) return 12; 00337 #elif F_BUS == 48000000 00338 if (I2C0_F == I2C_F_DIV112) return 12; 00339 #elif F_BUS == 40000000 00340 if (I2C0_F == I2C_F_DIV96) return 12; 00341 #elif F_BUS == 36000000 00342 if (I2C0_F == I2C_F_DIV96) return 12; 00343 #elif F_BUS == 24000000 00344 if (I2C0_F == I2C_F_DIV64) return 12; 00345 #elif F_BUS == 16000000 00346 if (I2C0_F == I2C_F_DIV40) return 12; 00347 #elif F_BUS == 8000000 00348 if (I2C0_F == I2C_F_DIV20) return 12; 00349 #elif F_BUS == 4000000 00350 if (I2C0_F == I2C_F_DIV20) return 12; 00351 #endif 00352 return 72; 00353 } 00354 }; 00355 extern TWBRemulation TWBR; 00356 00357 #endif 00358 #endif
Generated on Sat Jul 16 2022 20:55:16 by
1.7.2