Переглянути джерело

Use pin change hack (only if needed) for Wire & Wire1

main
PaulStoffregen 7 роки тому
джерело
коміт
39c840b8e9
2 змінених файлів з 49 додано та 19 видалено
  1. +46
    -15
      WireKinetis.cpp
  2. +3
    -4
      WireKinetis.h

+ 46
- 15
WireKinetis.cpp Переглянути файл

@@ -47,8 +47,8 @@
#undef I2C0_SLTH
#undef I2C0_SLTL

void sda_rising_isr(void);
void sda_rising_isr0(void);
void sda_rising_isr1(void);

void TwoWire::begin(void)
{
@@ -392,7 +392,7 @@ void TwoWire::isr(void)
port.S = I2C_S_IICIF;
return;
}
#if defined(KINETISL)
#if defined(WIRE_HAS_STOP_INTERRUPT)
c1 = port.FLT;
if ((c1 & I2C_FLT_STOPF) && (c1 & I2C_FLT_STOPIE)) {
port.FLT = c1 & ~I2C_FLT_STOPIE;
@@ -424,11 +424,21 @@ void TwoWire::isr(void)
} else {
// Continue Slave Receive
irqcount = 0;
#if defined(KINETISK)
attachInterrupt(hardware.sda_pin[sda_pin_index], sda_rising_isr, RISING);
#elif defined(KINETISL)
#ifdef WIRE_HAS_STOP_INTERRUPT
port.FLT |= I2C_FLT_STOPIE;
#else
#if defined(WIRE_IMPLEMENT_WIRE) && !defined(WIRE_IMPLEMENT_WIRE1)
attachInterrupt(hardware.sda_pin[sda_pin_index], sda_rising_isr0, RISING);
#elif !defined(WIRE_IMPLEMENT_WIRE) && defined(WIRE_IMPLEMENT_WIRE1)
attachInterrupt(hardware.sda_pin[sda_pin_index], sda_rising_isr1, RISING);
#elif defined(WIRE_IMPLEMENT_WIRE) && defined(WIRE_IMPLEMENT_WIRE1)
if (this == &Wire) {
attachInterrupt(hardware.sda_pin[sda_pin_index], sda_rising_isr0, RISING);
} else if (this == &Wire1) {
attachInterrupt(hardware.sda_pin[sda_pin_index], sda_rising_isr1, RISING);
}
#endif
#endif // WIRE_HAS_STOP_INTERRUPT
//digitalWriteFast(4, HIGH);
data = port.D;
//serial_phex(data);
@@ -440,26 +450,43 @@ void TwoWire::isr(void)
port.S = I2C_S_IICIF;
}


// Detects the stop condition that terminates a slave receive transfer.
// Sadly, the I2C in Kinetis K series lacks the stop detect interrupt
// Sadly, the I2C in older Kinetis K series lacks the stop detect interrupt
// This pin change interrupt hack is needed to detect the stop condition
void sda_rising_isr(void)
#if !defined(WIRE_HAS_STOP_INTERRUPT)

#if defined(WIRE_IMPLEMENT_WIRE)
void sda_rising_isr0(void)
{
Wire.sda_rising_isr();
}
#endif
#if defined(WIRE_IMPLEMENT_WIRE1)
void sda_rising_isr1(void)
{
Wire1.sda_rising_isr();
}
#endif

void TwoWire::sda_rising_isr(void)
{
//digitalWrite(3, HIGH);
if (!(Wire.port.S & I2C_S_BUSY)) {
detachInterrupt(Wire.hardware.sda_pin[Wire.sda_pin_index]);
if (Wire.user_onReceive != NULL) {
Wire.rxBufferIndex = 0;
Wire.user_onReceive(Wire.rxBufferLength);
if (!(port.S & I2C_S_BUSY)) {
detachInterrupt(hardware.sda_pin[sda_pin_index]);
if (user_onReceive != NULL) {
rxBufferIndex = 0;
user_onReceive(rxBufferLength);
}
//delayMicroseconds(100);
} else {
if (++Wire.irqcount >= 2 || !Wire.slave_mode) {
detachInterrupt(Wire.hardware.sda_pin[Wire.sda_pin_index]);
if (++irqcount >= 2 || !slave_mode) {
detachInterrupt(hardware.sda_pin[sda_pin_index]);
}
}
//digitalWrite(3, LOW);
}
#endif // !WIRE_HAS_STOP_INTERRUPT


// Chapter 44: Inter-Integrated Circuit (I2C) - Page 1012
@@ -711,6 +738,8 @@ const TwoWire::I2C_Hardware_t TwoWire::i2c2_hardware = {
IRQ_I2C2
};

TwoWire Wire2(KINETIS_I2C2, TwoWire::i2c2_hardware);

#endif // WIRE_IMPLEMENT_WIRE2


@@ -727,6 +756,8 @@ const TwoWire::I2C_Hardware_t TwoWire::i2c3_hardware = {
IRQ_I2C3
};

TwoWire Wire3(KINETIS_I2C3, TwoWire::i2c3_hardware);

#endif // WIRE_IMPLEMENT_WIRE3



+ 3
- 4
WireKinetis.h Переглянути файл

@@ -29,8 +29,6 @@

#if defined(__arm__) && defined(TEENSYDUINO)

extern "C" void i2c0_isr(void);

#include <inttypes.h>
#include "Arduino.h"

@@ -205,12 +203,13 @@ private:
void onReceiveService(uint8_t*, int);
void (*user_onRequest)(void);
void (*user_onReceive)(int);
//void sda_rising_isr(void);
void sda_rising_isr(void);
friend void i2c0_isr(void);
friend void i2c1_isr(void);
friend void i2c2_isr(void);
friend void i2c3_isr(void);
friend void sda_rising_isr(void);
friend void sda_rising_isr0(void);
friend void sda_rising_isr1(void);
};

#ifdef WIRE_IMPLEMENT_WIRE

Завантаження…
Відмінити
Зберегти