|
-
-
- #include "Wire.h"
-
- #if defined(__arm__) && defined(TEENSYDUINO)
-
- #include "kinetis.h"
- #include <string.h> // for memcpy
- #include "core_pins.h"
- #include "Wire.h"
-
-
- #undef I2C0_A1
- #undef I2C0_F
- #undef I2C0_C1
- #undef I2C0_S
- #undef I2C0_D
- #undef I2C0_C2
- #undef I2C0_FLT
- #undef I2C0_RA
- #undef I2C0_SMB
- #undef I2C0_A2
- #undef I2C0_SLTH
- #undef I2C0_SLTL
-
- void sda_rising_isr(void);
-
- TwoWire::TwoWire(KINETIS_I2C_t &myport, const I2C_Hardware_t &myhardware)
- : port(myport), hardware(myhardware)
- {
- rxBufferIndex = 0;
- rxBufferLength = 0;
- txBufferIndex = 0;
- txBufferLength = 0;
- transmitting = 0;
- sda_pin_num = 18;
- scl_pin_num = 19;
- user_onRequest = NULL;
- user_onReceive = NULL;
- }
-
- void TwoWire::begin(void)
- {
-
-
-
- slave_mode = 0;
- hardware.clock_gate_register |= hardware.clock_gate_mask;
- port.C1 = 0;
-
-
-
-
-
-
-
- if (sda_pin_num == 18) {
- CORE_PIN18_CONFIG = PORT_PCR_MUX(2)|PORT_PCR_ODE|PORT_PCR_SRE|PORT_PCR_DSE;
- } else if (sda_pin_num == 17) {
- CORE_PIN17_CONFIG = PORT_PCR_MUX(2)|PORT_PCR_ODE|PORT_PCR_SRE|PORT_PCR_DSE;
- #if defined(__MK64FX512__) || defined(__MK66FX1M0__)
- } else if (sda_pin_num == 34) {
- CORE_PIN34_CONFIG = PORT_PCR_MUX(5)|PORT_PCR_ODE|PORT_PCR_SRE|PORT_PCR_DSE;
- } else if (sda_pin_num == 8) {
- CORE_PIN8_CONFIG = PORT_PCR_MUX(7)|PORT_PCR_ODE|PORT_PCR_SRE|PORT_PCR_DSE;
- } else if (sda_pin_num == 48) {
- CORE_PIN48_CONFIG = PORT_PCR_MUX(2)|PORT_PCR_ODE|PORT_PCR_SRE|PORT_PCR_DSE;
- #endif
- }
- if (scl_pin_num == 19) {
- CORE_PIN19_CONFIG = PORT_PCR_MUX(2)|PORT_PCR_ODE|PORT_PCR_SRE|PORT_PCR_DSE;
- } else if (scl_pin_num == 16) {
- CORE_PIN16_CONFIG = PORT_PCR_MUX(2)|PORT_PCR_ODE|PORT_PCR_SRE|PORT_PCR_DSE;
- #if defined(__MK64FX512__) || defined(__MK66FX1M0__)
- } else if (scl_pin_num == 33) {
- CORE_PIN33_CONFIG = PORT_PCR_MUX(5)|PORT_PCR_ODE|PORT_PCR_SRE|PORT_PCR_DSE;
- } else if (scl_pin_num == 7) {
- CORE_PIN7_CONFIG = PORT_PCR_MUX(7)|PORT_PCR_ODE|PORT_PCR_SRE|PORT_PCR_DSE;
- } else if (scl_pin_num == 47) {
- CORE_PIN47_CONFIG = PORT_PCR_MUX(2)|PORT_PCR_ODE|PORT_PCR_SRE|PORT_PCR_DSE;
- #endif
- }
- setClock(100000);
- port.C2 = I2C_C2_HDRS;
- port.C1 = I2C_C1_IICEN;
-
-
- }
-
- void TwoWire::setClock(uint32_t frequency)
- {
- if (!(hardware.clock_gate_register & hardware.clock_gate_mask)) return;
-
- #if F_BUS == 120000000
- if (frequency < 400000) {
- port.F = I2C_F_DIV1152;
- } else if (frequency < 1000000) {
- port.F = I2C_F_DIV288;
- } else {
- port.F = I2C_F_DIV128;
- }
- port.FLT = 4;
- #elif F_BUS == 108000000
- if (frequency < 400000) {
- port.F = I2C_F_DIV1024;
- } else if (frequency < 1000000) {
- port.F = I2C_F_DIV256;
- } else {
- port.F = I2C_F_DIV112;
- }
- port.FLT = 4;
- #elif F_BUS == 96000000
- if (frequency < 400000) {
- port.F = I2C_F_DIV960;
- } else if (frequency < 1000000) {
- port.F = I2C_F_DIV240;
- } else {
- port.F = I2C_F_DIV96;
- }
- port.FLT = 4;
- #elif F_BUS == 90000000
- if (frequency < 400000) {
- port.F = I2C_F_DIV896;
- } else if (frequency < 1000000) {
- port.F = I2C_F_DIV224;
- } else {
- port.F = I2C_F_DIV88;
- }
- port.FLT = 4;
- #elif F_BUS == 80000000
- if (frequency < 400000) {
- port.F = I2C_F_DIV768;
- } else if (frequency < 1000000) {
- port.F = I2C_F_DIV192;
- } else {
- port.F = I2C_F_DIV80;
- }
- port.FLT = 4;
- #elif F_BUS == 72000000
- if (frequency < 400000) {
- port.F = I2C_F_DIV640;
- } else if (frequency < 1000000) {
- port.F = I2C_F_DIV192;
- } else {
- port.F = I2C_F_DIV72;
- }
- port.FLT = 4;
- #elif F_BUS == 64000000
- if (frequency < 400000) {
- port.F = I2C_F_DIV640;
- } else if (frequency < 1000000) {
- port.F = I2C_F_DIV160;
- } else {
- port.F = I2C_F_DIV64;
- }
- port.FLT = 4;
- #elif F_BUS == 60000000
- if (frequency < 400000) {
- port.F = 0x2C;
- } else if (frequency < 1000000) {
- port.F = 0x1C;
- } else {
- port.F = 0x12;
- }
- port.FLT = 4;
- #elif F_BUS == 56000000
- if (frequency < 400000) {
- port.F = 0x2B;
- } else if (frequency < 1000000) {
- port.F = 0x1C;
- } else {
- port.F = 0x0E;
- }
- port.FLT = 4;
- #elif F_BUS == 54000000
- if (frequency < 400000) {
- port.F = I2C_F_DIV512;
- } else if (frequency < 1000000) {
- port.F = I2C_F_DIV128;
- } else {
- port.F = I2C_F_DIV56;
- }
- port.FLT = 4;
- #elif F_BUS == 48000000
- if (frequency < 400000) {
- port.F = 0x27;
- } else if (frequency < 1000000) {
- port.F = 0x1A;
- } else {
- port.F = 0x0D;
- }
- port.FLT = 4;
- #elif F_BUS == 40000000
- if (frequency < 400000) {
- port.F = 0x29;
- } else if (frequency < 1000000) {
- port.F = 0x19;
- } else {
- port.F = 0x0B;
- }
- port.FLT = 3;
- #elif F_BUS == 36000000
- if (frequency < 400000) {
- port.F = 0x28;
- } else if (frequency < 1000000) {
- port.F = 0x19;
- } else {
- port.F = 0x0A;
- }
- port.FLT = 3;
- #elif F_BUS == 24000000
- if (frequency < 400000) {
- port.F = 0x1F;
- } else if (frequency < 1000000) {
- port.F = 0x12;
- } else {
- port.F = 0x02;
- }
- port.FLT = 2;
- #elif F_BUS == 16000000
- if (frequency < 400000) {
- port.F = 0x20;
- } else if (frequency < 1000000) {
- port.F = 0x07;
- } else {
- port.F = 0x00;
- }
- port.FLT = 1;
- #elif F_BUS == 8000000
- if (frequency < 400000) {
- port.F = 0x14;
- } else {
- port.F = 0x00;
- }
- port.FLT = 1;
- #elif F_BUS == 4000000
- if (frequency < 400000) {
- port.F = 0x07;
- } else {
- port.F = 0x00;
- }
- port.FLT = 1;
- #elif F_BUS == 2000000
- port.F = 0x00;
- port.FLT = 1;
- #else
- #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"
- #endif
- }
-
- void TwoWire::setSDA(uint8_t pin)
- {
- if (pin == sda_pin_num) return;
- if ((hardware.clock_gate_register & hardware.clock_gate_mask)) {
- if (sda_pin_num == 18) {
- CORE_PIN18_CONFIG = 0;
- } else if (sda_pin_num == 17) {
- CORE_PIN17_CONFIG = 0;
- #if defined(__MK64FX512__) || defined(__MK66FX1M0__)
- } else if (sda_pin_num == 34) {
- CORE_PIN34_CONFIG = 0;
- } else if (sda_pin_num == 8) {
- CORE_PIN8_CONFIG = 0;
- } else if (sda_pin_num == 48) {
- CORE_PIN48_CONFIG = 0;
- #endif
- }
-
- if (pin == 18) {
- CORE_PIN18_CONFIG = PORT_PCR_MUX(2)|PORT_PCR_ODE|PORT_PCR_SRE|PORT_PCR_DSE;
- } else if (pin == 17) {
- CORE_PIN17_CONFIG = PORT_PCR_MUX(2)|PORT_PCR_ODE|PORT_PCR_SRE|PORT_PCR_DSE;
- #if defined(__MK64FX512__) || defined(__MK66FX1M0__)
- } else if (pin == 34) {
- CORE_PIN34_CONFIG = PORT_PCR_MUX(5)|PORT_PCR_ODE|PORT_PCR_SRE|PORT_PCR_DSE;
- } else if (pin == 8) {
- CORE_PIN8_CONFIG = PORT_PCR_MUX(7)|PORT_PCR_ODE|PORT_PCR_SRE|PORT_PCR_DSE;
- } else if (pin == 48) {
- CORE_PIN48_CONFIG = PORT_PCR_MUX(2)|PORT_PCR_ODE|PORT_PCR_SRE|PORT_PCR_DSE;
- #endif
- }
- }
- sda_pin_num = pin;
- }
-
- void TwoWire::setSCL(uint8_t pin)
- {
- if (pin == scl_pin_num) return;
- if ((hardware.clock_gate_register & hardware.clock_gate_mask)) {
- if (scl_pin_num == 19) {
- CORE_PIN19_CONFIG = 0;
- } else if (scl_pin_num == 16) {
- CORE_PIN16_CONFIG = 0;
- #if defined(__MK64FX512__) || defined(__MK66FX1M0__)
- } else if (scl_pin_num == 33) {
- CORE_PIN33_CONFIG = 0;
- } else if (scl_pin_num == 7) {
- CORE_PIN7_CONFIG = 0;
- } else if (scl_pin_num == 47) {
- CORE_PIN47_CONFIG = 0;
- #endif
- }
-
- if (pin == 19) {
- CORE_PIN19_CONFIG = PORT_PCR_MUX(2)|PORT_PCR_ODE|PORT_PCR_SRE|PORT_PCR_DSE;
- } else if (pin == 16) {
- CORE_PIN16_CONFIG = PORT_PCR_MUX(2)|PORT_PCR_ODE|PORT_PCR_SRE|PORT_PCR_DSE;
- #if defined(__MK64FX512__) || defined(__MK66FX1M0__)
- } else if (pin == 33) {
- CORE_PIN33_CONFIG = PORT_PCR_MUX(5)|PORT_PCR_ODE|PORT_PCR_SRE|PORT_PCR_DSE;
- } else if (pin == 7) {
- CORE_PIN7_CONFIG = PORT_PCR_MUX(7)|PORT_PCR_ODE|PORT_PCR_SRE|PORT_PCR_DSE;
- } else if (pin == 47) {
- CORE_PIN47_CONFIG = PORT_PCR_MUX(2)|PORT_PCR_ODE|PORT_PCR_SRE|PORT_PCR_DSE;
- #endif
- }
- }
- scl_pin_num = pin;
- }
-
- void TwoWire::begin(uint8_t address)
- {
- begin();
- port.A1 = address << 1;
- slave_mode = 1;
- port.C1 = I2C_C1_IICEN | I2C_C1_IICIE;
- NVIC_ENABLE_IRQ(IRQ_I2C0);
- }
-
- void TwoWire::end()
- {
- if (!(hardware.clock_gate_register & hardware.clock_gate_mask)) return;
- NVIC_DISABLE_IRQ(IRQ_I2C0);
- port.C1 = 0;
- if (sda_pin_num == 18) {
- CORE_PIN18_CONFIG = 0;
- } else if (sda_pin_num == 17) {
- CORE_PIN17_CONFIG = 0;
- #if defined(__MK64FX512__) || defined(__MK66FX1M0__)
- } else if (sda_pin_num == 34) {
- CORE_PIN34_CONFIG = 0;
- } else if (sda_pin_num == 8) {
- CORE_PIN8_CONFIG = 0;
- } else if (sda_pin_num == 48) {
- CORE_PIN48_CONFIG = 0;
- #endif
- }
- if (scl_pin_num == 19) {
- CORE_PIN19_CONFIG = 0;
- } else if (scl_pin_num == 16) {
- CORE_PIN16_CONFIG = 0;
- #if defined(__MK64FX512__) || defined(__MK66FX1M0__)
- } else if (scl_pin_num == 33) {
- CORE_PIN33_CONFIG = 0;
- } else if (scl_pin_num == 7) {
- CORE_PIN7_CONFIG = 0;
- } else if (scl_pin_num == 47) {
- CORE_PIN47_CONFIG = 0;
- #endif
- }
- hardware.clock_gate_register &= ~hardware.clock_gate_mask;
- }
-
- void i2c0_isr(void)
- {
- uint8_t status, c1, data;
- static uint8_t receiving=0;
-
- status = Wire.port.S;
-
- if (status & I2C_S_ARBL) {
-
- Wire.port.S = I2C_S_ARBL;
-
- if (receiving && Wire.rxBufferLength > 0) {
-
-
-
- }
- if (!(status & I2C_S_IAAS)) return;
- }
- if (status & I2C_S_IAAS) {
-
-
- if (status & I2C_S_SRW) {
-
-
- receiving = 0;
- Wire.txBufferLength = 0;
- if (Wire.user_onRequest != NULL) {
- Wire.user_onRequest();
- }
- if (Wire.txBufferLength == 0) {
-
-
-
- Wire.txBufferLength = 1;
- Wire.txBuffer[0] = 0;
- }
- Wire.port.C1 = I2C_C1_IICEN | I2C_C1_IICIE | I2C_C1_TX;
- Wire.port.D = Wire.txBuffer[0];
- Wire.txBufferIndex = 1;
- } else {
-
-
- receiving = 1;
- Wire.rxBufferLength = 0;
- Wire.port.C1 = I2C_C1_IICEN | I2C_C1_IICIE;
- data = Wire.port.D;
- }
- Wire.port.S = I2C_S_IICIF;
- return;
- }
- #if defined(KINETISL)
- c1 = Wire.port.FLT;
- if ((c1 & I2C_FLT_STOPF) && (c1 & I2C_FLT_STOPIE)) {
- Wire.port.FLT = c1 & ~I2C_FLT_STOPIE;
- if (Wire.user_onReceive != NULL) {
- Wire.rxBufferIndex = 0;
- Wire.user_onReceive(Wire.rxBufferLength);
- }
- }
- #endif
- c1 = Wire.port.C1;
- if (c1 & I2C_C1_TX) {
-
-
- if ((status & I2C_S_RXAK) == 0) {
-
-
- if (Wire.txBufferIndex < Wire.txBufferLength) {
- Wire.port.D = Wire.txBuffer[Wire.txBufferIndex++];
- } else {
- Wire.port.D = 0;
- }
- Wire.port.C1 = I2C_C1_IICEN | I2C_C1_IICIE | I2C_C1_TX;
- } else {
-
-
- Wire.port.C1 = I2C_C1_IICEN | I2C_C1_IICIE;
- data = Wire.port.D;
- }
- } else {
-
- Wire.irqcount = 0;
- #if defined(KINETISK)
- attachInterrupt(18, sda_rising_isr, RISING);
- #elif defined(KINETISL)
- Wire.port.FLT |= I2C_FLT_STOPIE;
- #endif
-
- data = Wire.port.D;
-
- if (Wire.rxBufferLength < BUFFER_LENGTH && receiving) {
- Wire.rxBuffer[Wire.rxBufferLength++] = data;
- }
-
- }
- Wire.port.S = I2C_S_IICIF;
- }
-
-
-
-
- void sda_rising_isr(void)
- {
-
- if (!(Wire.port.S & I2C_S_BUSY)) {
- detachInterrupt(18);
- if (Wire.user_onReceive != NULL) {
- Wire.rxBufferIndex = 0;
- Wire.user_onReceive(Wire.rxBufferLength);
- }
-
- } else {
- if (++Wire.irqcount >= 2 || !Wire.slave_mode) {
- detachInterrupt(18);
- }
- }
-
- }
-
-
-
-
-
-
-
-
-
-
-
- size_t TwoWire::write(uint8_t data)
- {
- if (transmitting || slave_mode) {
- if (txBufferLength >= BUFFER_LENGTH+1) {
- setWriteError();
- return 0;
- }
- txBuffer[txBufferLength++] = data;
- return 1;
- }
- return 0;
- }
-
- size_t TwoWire::write(const uint8_t *data, size_t quantity)
- {
- if (transmitting || slave_mode) {
- size_t avail = BUFFER_LENGTH+1 - txBufferLength;
- if (quantity > avail) {
- quantity = avail;
- setWriteError();
- }
- memcpy(txBuffer + txBufferLength, data, quantity);
- txBufferLength += quantity;
- return quantity;
- }
- return 0;
- }
-
-
- uint8_t TwoWire::endTransmission(uint8_t sendStop)
- {
- uint8_t i, status, ret=0;
-
-
- port.S = I2C_S_IICIF | I2C_S_ARBL;
-
- if (port.C1 & I2C_C1_MST) {
-
-
- port.C1 = I2C_C1_IICEN | I2C_C1_MST | I2C_C1_RSTA | I2C_C1_TX;
- } else {
-
-
- uint32_t wait_begin = millis();
- while (i2c_status() & I2C_S_BUSY) {
-
- if (millis() - wait_begin > 15) {
-
- port.C1 = 0;
- port.C1 = I2C_C1_IICEN;
-
- return 4;
- }
- }
-
- slave_mode = 0;
- port.C1 = I2C_C1_IICEN | I2C_C1_MST | I2C_C1_TX;
- }
-
- while (1) {
- status = i2c_status();
- if ((status & I2C_S_BUSY)) break;
- }
-
- for (i=0; i < txBufferLength; i++) {
- port.D = txBuffer[i];
-
- while (1) {
- status = i2c_status();
- if ((status & I2C_S_IICIF)) break;
- if (!(status & I2C_S_BUSY)) break;
- }
- port.S = I2C_S_IICIF;
-
- status = i2c_status();
- if ((status & I2C_S_ARBL)) {
-
-
-
- port.C1 = I2C_C1_IICEN;
- ret = 4;
- break;
- }
- if (!(status & I2C_S_BUSY)) {
-
- port.C1 = I2C_C1_IICEN;
- ret = 4;
- break;
- }
- if (status & I2C_S_RXAK) {
-
- if (i == 0) {
- ret = 2;
- } else {
- ret = 3;
- }
- sendStop = 1;
- break;
- }
- }
- if (sendStop) {
-
- port.C1 = I2C_C1_IICEN;
-
- }
- transmitting = 0;
-
-
- return ret;
- }
-
-
- uint8_t TwoWire::requestFrom(uint8_t address, uint8_t length, uint8_t sendStop)
- {
- uint8_t tmp __attribute__((unused));
- uint8_t status, count=0;
-
- rxBufferIndex = 0;
- rxBufferLength = 0;
-
-
- port.S = I2C_S_IICIF | I2C_S_ARBL;
-
- if (port.C1 & I2C_C1_MST) {
-
- port.C1 = I2C_C1_IICEN | I2C_C1_MST | I2C_C1_RSTA | I2C_C1_TX;
- } else {
-
- while (i2c_status() & I2C_S_BUSY) ;
-
- slave_mode = 0;
- port.C1 = I2C_C1_IICEN | I2C_C1_MST | I2C_C1_TX;
- }
-
- port.D = (address << 1) | 1;
- i2c_wait();
- status = i2c_status();
- if ((status & I2C_S_RXAK) || (status & I2C_S_ARBL)) {
-
-
- port.C1 = I2C_C1_IICEN;
- return 0;
- }
- if (length == 0) {
-
-
- port.C1 = I2C_C1_IICEN | (sendStop ? 0 : I2C_C1_MST);
- return 0;
- } else if (length == 1) {
- port.C1 = I2C_C1_IICEN | I2C_C1_MST | I2C_C1_TXAK;
- } else {
- port.C1 = I2C_C1_IICEN | I2C_C1_MST;
- }
- tmp = port.D;
- while (length > 1) {
- i2c_wait();
- length--;
- if (length == 1) port.C1 = I2C_C1_IICEN | I2C_C1_MST | I2C_C1_TXAK;
- if (count < BUFFER_LENGTH) {
- rxBuffer[count++] = port.D;
- } else {
- tmp = port.D;
- }
- }
- i2c_wait();
- port.C1 = I2C_C1_IICEN | I2C_C1_MST | I2C_C1_TX;
- if (count < BUFFER_LENGTH) {
- rxBuffer[count++] = port.D;
- } else {
- tmp = port.D;
- }
- if (sendStop) port.C1 = I2C_C1_IICEN;
- rxBufferLength = count;
- return count;
- }
-
-
-
-
- const TwoWire::I2C_Hardware_t TwoWire::i2c0_hardware = {
- SIM_SCGC4, SIM_SCGC4_I2C0
- };
-
-
- TwoWire Wire(KINETIS_I2C0, TwoWire::i2c0_hardware);
-
-
-
- #endif
|