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.h Source File

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