Browse Source

Define Wire objects for each board

main
PaulStoffregen 8 years ago
parent
commit
cef2e757c6
2 changed files with 97 additions and 61 deletions
  1. +63
    -56
      WireKinetis.cpp
  2. +34
    -5
      WireKinetis.h

+ 63
- 56
WireKinetis.cpp View File

} }


void i2c0_isr(void) void i2c0_isr(void)
{
Wire.isr();
}

void TwoWire::isr(void)
{ {
uint8_t status, c1, data; uint8_t status, c1, data;
static uint8_t receiving=0; static uint8_t receiving=0;


status = Wire.port.S;
status = port.S;
//serial_print("."); //serial_print(".");
if (status & I2C_S_ARBL) { if (status & I2C_S_ARBL) {
// Arbitration Lost // Arbitration Lost
Wire.port.S = I2C_S_ARBL;
port.S = I2C_S_ARBL;
//serial_print("a"); //serial_print("a");
if (receiving && Wire.rxBufferLength > 0) {
if (receiving && rxBufferLength > 0) {
// TODO: does this detect the STOP condition in slave receive mode? // TODO: does this detect the STOP condition in slave receive mode?




//serial_print("T"); //serial_print("T");
// Begin Slave Transmit // Begin Slave Transmit
receiving = 0; receiving = 0;
Wire.txBufferLength = 0;
if (Wire.user_onRequest != NULL) {
Wire.user_onRequest();
txBufferLength = 0;
if (user_onRequest != NULL) {
user_onRequest();
} }
if (Wire.txBufferLength == 0) {
if (txBufferLength == 0) {
// is this correct, transmitting a single zero // is this correct, transmitting a single zero
// when we should send nothing? Arduino's AVR // when we should send nothing? Arduino's AVR
// implementation does this, but is it ok? // implementation does this, but is it ok?
Wire.txBufferLength = 1;
Wire.txBuffer[0] = 0;
txBufferLength = 1;
txBuffer[0] = 0;
} }
Wire.port.C1 = I2C_C1_IICEN | I2C_C1_IICIE | I2C_C1_TX;
Wire.port.D = Wire.txBuffer[0];
Wire.txBufferIndex = 1;
port.C1 = I2C_C1_IICEN | I2C_C1_IICIE | I2C_C1_TX;
port.D = txBuffer[0];
txBufferIndex = 1;
} else { } else {
// Begin Slave Receive // Begin Slave Receive
//serial_print("R"); //serial_print("R");
receiving = 1; receiving = 1;
Wire.rxBufferLength = 0;
Wire.port.C1 = I2C_C1_IICEN | I2C_C1_IICIE;
data = Wire.port.D;
rxBufferLength = 0;
port.C1 = I2C_C1_IICEN | I2C_C1_IICIE;
data = port.D;
} }
Wire.port.S = I2C_S_IICIF;
port.S = I2C_S_IICIF;
return; return;
} }
#if defined(KINETISL) #if defined(KINETISL)
c1 = Wire.port.FLT;
c1 = port.FLT;
if ((c1 & I2C_FLT_STOPF) && (c1 & I2C_FLT_STOPIE)) { 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);
port.FLT = c1 & ~I2C_FLT_STOPIE;
if (user_onReceive != NULL) {
rxBufferIndex = 0;
user_onReceive(rxBufferLength);
} }
} }
#endif #endif
c1 = Wire.port.C1;
c1 = port.C1;
if (c1 & I2C_C1_TX) { if (c1 & I2C_C1_TX) {
// Continue Slave Transmit // Continue Slave Transmit
//serial_print("t"); //serial_print("t");
if ((status & I2C_S_RXAK) == 0) { if ((status & I2C_S_RXAK) == 0) {
//serial_print("."); //serial_print(".");
// Master ACK'd previous byte // Master ACK'd previous byte
if (Wire.txBufferIndex < Wire.txBufferLength) {
Wire.port.D = Wire.txBuffer[Wire.txBufferIndex++];
if (txBufferIndex < txBufferLength) {
port.D = txBuffer[txBufferIndex++];
} else { } else {
Wire.port.D = 0;
port.D = 0;
} }
Wire.port.C1 = I2C_C1_IICEN | I2C_C1_IICIE | I2C_C1_TX;
port.C1 = I2C_C1_IICEN | I2C_C1_IICIE | I2C_C1_TX;
} else { } else {
//serial_print("*"); //serial_print("*");
// Master did not ACK previous byte // Master did not ACK previous byte
Wire.port.C1 = I2C_C1_IICEN | I2C_C1_IICIE;
data = Wire.port.D;
port.C1 = I2C_C1_IICEN | I2C_C1_IICIE;
data = port.D;
} }
} else { } else {
// Continue Slave Receive // Continue Slave Receive
Wire.irqcount = 0;
irqcount = 0;
#if defined(KINETISK) #if defined(KINETISK)
attachInterrupt(18, sda_rising_isr, RISING);
attachInterrupt(hardware.sda_pin[sda_pin_index], sda_rising_isr, RISING);
#elif defined(KINETISL) #elif defined(KINETISL)
Wire.port.FLT |= I2C_FLT_STOPIE;
port.FLT |= I2C_FLT_STOPIE;
#endif #endif
//digitalWriteFast(4, HIGH); //digitalWriteFast(4, HIGH);
data = Wire.port.D;
data = port.D;
//serial_phex(data); //serial_phex(data);
if (Wire.rxBufferLength < BUFFER_LENGTH && receiving) {
Wire.rxBuffer[Wire.rxBufferLength++] = data;
if (rxBufferLength < BUFFER_LENGTH && receiving) {
rxBuffer[rxBufferLength++] = data;
} }
//digitalWriteFast(4, LOW); //digitalWriteFast(4, LOW);
} }
Wire.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.
{ {
//digitalWrite(3, HIGH); //digitalWrite(3, HIGH);
if (!(Wire.port.S & I2C_S_BUSY)) { if (!(Wire.port.S & I2C_S_BUSY)) {
detachInterrupt(18);
detachInterrupt(Wire.hardware.sda_pin[Wire.sda_pin_index]);
if (Wire.user_onReceive != NULL) { if (Wire.user_onReceive != NULL) {
Wire.rxBufferIndex = 0; Wire.rxBufferIndex = 0;
Wire.user_onReceive(Wire.rxBufferLength); Wire.user_onReceive(Wire.rxBufferLength);
//delayMicroseconds(100); //delayMicroseconds(100);
} else { } else {
if (++Wire.irqcount >= 2 || !Wire.slave_mode) { if (++Wire.irqcount >= 2 || !Wire.slave_mode) {
detachInterrupt(18);
detachInterrupt(Wire.hardware.sda_pin[Wire.sda_pin_index]);
} }
} }
//digitalWrite(3, LOW); //digitalWrite(3, LOW);
return count; return count;
} }


#ifdef WIRE_IMPLEMENT_WIRE


const TwoWire::I2C_Hardware_t TwoWire::i2c0_hardware = { const TwoWire::I2C_Hardware_t TwoWire::i2c0_hardware = {
SIM_SCGC4, SIM_SCGC4_I2C0, SIM_SCGC4, SIM_SCGC4_I2C0,
#endif #endif
}; };


TwoWire Wire(KINETIS_I2C0, TwoWire::i2c0_hardware);

#endif // WIRE_IMPLEMENT_WIRE


#ifdef WIRE_IMPLEMENT_WIRE1

const TwoWire::I2C_Hardware_t TwoWire::i2c1_hardware = { const TwoWire::I2C_Hardware_t TwoWire::i2c1_hardware = {
SIM_SCGC4, SIM_SCGC4_I2C1, SIM_SCGC4, SIM_SCGC4_I2C1,
#if defined(__MKL26Z64__) #if defined(__MKL26Z64__)
2, 0, 0, 0, 0, 2, 0, 0, 0, 0,
37, 255, 255, 255, 255, 37, 255, 255, 255, 255,
2, 0, 0, 0, 0, 2, 0, 0, 0, 0,
#else
255, 255, 255, 255, 255,
0, 0, 0, 0, 0,
255, 255, 255, 255, 255,
0, 0, 0, 0, 0,
#endif #endif
}; };


TwoWire Wire1(KINETIS_I2C1, TwoWire::i2c1_hardware);

#endif // WIRE_IMPLEMENT_WIRE1


#ifdef WIRE_IMPLEMENT_WIRE2

const TwoWire::I2C_Hardware_t TwoWire::i2c2_hardware = { const TwoWire::I2C_Hardware_t TwoWire::i2c2_hardware = {
SIM_SCGC1, SIM_SCGC1_I2C2, SIM_SCGC1, SIM_SCGC1_I2C2,
#if defined(__MK64FX512__) || defined(__MK66FX1M0__) #if defined(__MK64FX512__) || defined(__MK66FX1M0__)
5, 0, 0, 0, 0, 5, 0, 0, 0, 0,
3, 26, 255, 255, 255, 3, 26, 255, 255, 255,
5, 5, 0, 0, 0, 5, 5, 0, 0, 0,
#else
255, 255, 255, 255, 255,
0, 0, 0, 0, 0,
255, 255, 255, 255, 255,
0, 0, 0, 0, 0,
#endif #endif
}; };


#endif // WIRE_IMPLEMENT_WIRE2


#ifdef WIRE_IMPLEMENT_WIRE3

const TwoWire::I2C_Hardware_t TwoWire::i2c3_hardware = { const TwoWire::I2C_Hardware_t TwoWire::i2c3_hardware = {
SIM_SCGC1, SIM_SCGC1_I2C3, SIM_SCGC1, SIM_SCGC1_I2C3,
#if defined(__MK66FX1M0__) #if defined(__MK66FX1M0__)
2, 0, 0, 0, 0, 2, 0, 0, 0, 0,
57, 255, 255, 255, 255, 57, 255, 255, 255, 255,
2, 0, 0, 0, 0, 2, 0, 0, 0, 0,
#else
255, 255, 255, 255, 255,
0, 0, 0, 0, 0,
255, 255, 255, 255, 255,
0, 0, 0, 0, 0,
#endif #endif
}; };



TwoWire Wire(KINETIS_I2C0, TwoWire::i2c0_hardware);
TwoWire Wire1(KINETIS_I2C1, TwoWire::i2c1_hardware);

#endif // WIRE_IMPLEMENT_WIRE3




#endif // __arm__ && TEENSYDUINO #endif // __arm__ && TEENSYDUINO

+ 34
- 5
WireKinetis.h View File

#define BUFFER_LENGTH 32 #define BUFFER_LENGTH 32
#define WIRE_HAS_END 1 #define WIRE_HAS_END 1



// Teensy LC
#if defined(__MKL26Z64__) #if defined(__MKL26Z64__)
#define WIRE_HAS_STOP_INTERRUPT 1
#elif defined(__MK64FX512__) || defined(__MK66FX1M0__)
#define WIRE_HAS_START_INTERRUPT 1
#define WIRE_HAS_STOP_INTERRUPT 1
#define WIRE_IMPLEMENT_WIRE
#define WIRE_IMPLEMENT_WIRE1
#define WIRE_HAS_STOP_INTERRUPT

// Teensy 3.0
#elif defined(__MK20DX128__)
#define WIRE_IMPLEMENT_WIRE

// Teensy 3.1 & 3.2
#elif defined(__MK20DX256__)
#define WIRE_IMPLEMENT_WIRE
#define WIRE_IMPLEMENT_WIRE1

// Teensy 3.5
#elif defined(__MK64FX512__)
#define WIRE_IMPLEMENT_WIRE
#define WIRE_IMPLEMENT_WIRE1
#define WIRE_IMPLEMENT_WIRE2
#define WIRE_HAS_START_INTERRUPT
#define WIRE_HAS_STOP_INTERRUPT

// Teensy 3.6
#elif defined(__MK66FX1M0__)
#define WIRE_IMPLEMENT_WIRE
#define WIRE_IMPLEMENT_WIRE1
#define WIRE_IMPLEMENT_WIRE2
#define WIRE_IMPLEMENT_WIRE3
#define WIRE_HAS_START_INTERRUPT
#define WIRE_HAS_STOP_INTERRUPT

#endif #endif



class TwoWire : public Stream class TwoWire : public Stream
{ {
public: public:
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 sda_rising_isr(void); friend void sda_rising_isr(void);
}; };

Loading…
Cancel
Save