Ver código fonte

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

main
PaulStoffregen 7 anos atrás
pai
commit
39c840b8e9
2 arquivos alterados com 49 adições e 19 exclusões
  1. +46
    -15
      WireKinetis.cpp
  2. +3
    -4
      WireKinetis.h

+ 46
- 15
WireKinetis.cpp Ver arquivo

#undef I2C0_SLTH #undef I2C0_SLTH
#undef I2C0_SLTL #undef I2C0_SLTL


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


void TwoWire::begin(void) void TwoWire::begin(void)
{ {
port.S = I2C_S_IICIF; port.S = I2C_S_IICIF;
return; return;
} }
#if defined(KINETISL)
#if defined(WIRE_HAS_STOP_INTERRUPT)
c1 = port.FLT; c1 = port.FLT;
if ((c1 & I2C_FLT_STOPF) && (c1 & I2C_FLT_STOPIE)) { if ((c1 & I2C_FLT_STOPF) && (c1 & I2C_FLT_STOPIE)) {
port.FLT = c1 & ~I2C_FLT_STOPIE; port.FLT = c1 & ~I2C_FLT_STOPIE;
} else { } else {
// Continue Slave Receive // Continue Slave Receive
irqcount = 0; 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; 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
#endif // WIRE_HAS_STOP_INTERRUPT
//digitalWriteFast(4, HIGH); //digitalWriteFast(4, HIGH);
data = port.D; data = port.D;
//serial_phex(data); //serial_phex(data);
port.S = I2C_S_IICIF; port.S = I2C_S_IICIF;
} }



// Detects the stop condition that terminates a slave receive transfer. // 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 // 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); //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); //delayMicroseconds(100);
} else { } 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); //digitalWrite(3, LOW);
} }
#endif // !WIRE_HAS_STOP_INTERRUPT




// Chapter 44: Inter-Integrated Circuit (I2C) - Page 1012 // Chapter 44: Inter-Integrated Circuit (I2C) - Page 1012
IRQ_I2C2 IRQ_I2C2
}; };


TwoWire Wire2(KINETIS_I2C2, TwoWire::i2c2_hardware);

#endif // WIRE_IMPLEMENT_WIRE2 #endif // WIRE_IMPLEMENT_WIRE2




IRQ_I2C3 IRQ_I2C3
}; };


TwoWire Wire3(KINETIS_I2C3, TwoWire::i2c3_hardware);

#endif // WIRE_IMPLEMENT_WIRE3 #endif // WIRE_IMPLEMENT_WIRE3





+ 3
- 4
WireKinetis.h Ver arquivo



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


extern "C" void i2c0_isr(void);

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


void onReceiveService(uint8_t*, int); void onReceiveService(uint8_t*, int);
void (*user_onRequest)(void); void (*user_onRequest)(void);
void (*user_onReceive)(int); void (*user_onReceive)(int);
//void sda_rising_isr(void);
void sda_rising_isr(void);
friend void i2c0_isr(void); friend void i2c0_isr(void);
friend void i2c1_isr(void); friend void i2c1_isr(void);
friend void i2c2_isr(void); friend void i2c2_isr(void);
friend void i2c3_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 #ifdef WIRE_IMPLEMENT_WIRE

Carregando…
Cancelar
Salvar