瀏覽代碼

IMXRT - work in progress...

main
PaulStoffregen 6 年之前
父節點
當前提交
b757eb66ff
共有 5 個文件被更改,包括 620 次插入3 次删除
  1. +4
    -1
      Wire.h
  2. +295
    -0
      WireIMXRT.cpp
  3. +319
    -0
      WireIMXRT.h
  4. +1
    -1
      WireKinetis.cpp
  5. +1
    -1
      WireKinetis.h

+ 4
- 1
Wire.h 查看文件

@@ -22,7 +22,10 @@
#ifndef TwoWire_h
#define TwoWire_h

#if defined(__arm__) && defined(TEENSYDUINO)
#if defined(__IMXRT1052__) || defined(__IMXRT1062__)
#include "WireIMXRT.h"

#elif defined(__arm__) && defined(TEENSYDUINO)
#include "WireKinetis.h"

#elif defined(__AVR__)

+ 295
- 0
WireIMXRT.cpp 查看文件

@@ -0,0 +1,295 @@

#include "Wire.h"


#if defined(__IMXRT1052__) || defined(__IMXRT1062__)

#include "debug/printf.h"

void i2c_setclock(uint32_t frequency);

void TwoWire::begin(void)
{
// use 24 MHz clock
CCM_CSCDR2 = (CCM_CSCDR2 & ~CCM_CSCDR2_LPI2C_CLK_PODF(63)) | CCM_CSCDR2_LPI2C_CLK_SEL;
CCM_CCGR2 |= CCM_CCGR2_LPI2C1(CCM_CCGR_ON);
LPI2C1_MCR = LPI2C_MCR_RST;
i2c_setclock(100000);
IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_00 = 3 | 0x10; // 18/A4 AD_B1_01 GPIO1.17 I2C1_SDA
IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_01 = 3 | 0x10; // 19/A5 AD_B1_00 GPIO1.16 I2C1_SCL
IOMUXC_LPI2C1_SCL_SELECT_INPUT = 1;
IOMUXC_LPI2C1_SDA_SELECT_INPUT = 1;
IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_00 |= IOMUXC_PAD_PKE | IOMUXC_PAD_PUE | IOMUXC_PAD_PUS(3);
IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_01 |= IOMUXC_PAD_PKE | IOMUXC_PAD_PUE | IOMUXC_PAD_PUS(3);
}

void TwoWire::setClock(uint32_t frequency)
{
}

void TwoWire::setSDA(uint8_t pin)
{
}

void TwoWire::setSCL(uint8_t pin)
{
}

void TwoWire::begin(uint8_t address)
{
}

void TwoWire::end()
{
}

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)
{
uint32_t i=0, len, status;

len = txBufferLength;
if (!len) return 4; // no data to transmit

// wait while bus is busy
while (1) {
status = LPI2C1_MSR; // pg 2899 & 2892
if (!(LPI2C1_MSR & LPI2C_MSR_BBF)) break; // bus is available
if (LPI2C1_MSR & LPI2C_MSR_MBF) break; // we already have bus control
// TODO: timeout...
}
printf("idle\n");

// TODO: is this correct if the prior use didn't send stop?
LPI2C1_MSR = LPI2C_MSR_PLTF | LPI2C_MSR_ALF | LPI2C_MSR_NDF | LPI2C_MSR_SDF; // clear flags

printf("MSR=%lX, MFSR=%lX\n", status, LPI2C1_MFSR);

while (1) {
// transmit stuff, if we haven't already
if (i <= len) {
uint32_t fifo_used = LPI2C1_MFSR & 0x07; // pg 2914
if (fifo_used < 4) printf("t=%ld\n", fifo_used);
while (fifo_used < 4) {
if (i == 0) {
LPI2C1_MTDR = LPI2C_MTDR_CMD_START | (txBuffer[0] << 1);
i = 1;
} else if (i < len) {
LPI2C1_MTDR = LPI2C_MTDR_CMD_TRANSMIT | txBuffer[i++];
} else {
if (sendStop) LPI2C1_MTDR = LPI2C_MTDR_CMD_STOP;
i++;
break;
}
fifo_used = fifo_used + 1;
}
}
// monitor status
status = LPI2C1_MSR; // pg 2899 & 2892
if (status & LPI2C_MSR_ALF) {
printf("arbitration lost\n");
return 4; // we lost bus arbitration to another master
}
if (status & LPI2C_MSR_NDF) {
printf("got NACK, fifo=%ld, i=%ld\n", LPI2C1_MFSR & 0x07, i);
// TODO: check that hardware really sends stop automatically
// TODO: do we need to clear the FIFO here?
return 2; // NACK for address
//return 3; // NACK for data TODO: how to discern addr from data?
}
//if (status & LPI2C_MSR_PLTF) {
//printf("bus stuck - what to do?\n");
//return 4;
//}
if (sendStop) {
if (status & LPI2C_MSR_SDF) return 0;
} else {
uint32_t fifo_used = LPI2C1_MFSR & 0x07; // pg 2914
if (fifo_used == 0) {
//digitalWriteFast(15, HIGH);
//delayMicroseconds(2);
//digitalWriteFast(15, LOW);
// TODO: this return before the data transmits!
// Should verify every byte ACKs, arbitration not lost
return 0;
}
}
}
}

uint8_t TwoWire::requestFrom(uint8_t address, uint8_t length, uint8_t sendStop)
{
uint32_t cmd=0, status, fifo;
// TODO: sendStop is currently ignored

// wait while bus is busy
while (1) {
status = LPI2C1_MSR; // pg 2899 & 2892
if (!(LPI2C1_MSR & LPI2C_MSR_BBF)) break; // bus is available
if (LPI2C1_MSR & LPI2C_MSR_MBF) break; // we already have bus control
// TODO: timeout...
}
printf("idle\n");

// TODO: is this correct if the prior use didn't send stop?
LPI2C1_MSR = LPI2C_MSR_PLTF | LPI2C_MSR_ALF | LPI2C_MSR_NDF | LPI2C_MSR_SDF; // clear flags

//printf("MSR=%lX, MFSR=%lX\n", status, LPI2C1_MFSR);
address = (address & 0x7F) << 1;
if (length < 1) length = 1;
if (length > 255) length = 255;
rxBufferIndex = 0;
rxBufferLength = 0;

while (1) {
// transmit stuff, if we haven't already
if (cmd < 3) {
fifo = LPI2C1_MFSR & 0x07; // pg 2914
if (fifo < 4) printf("t=%ld\n", fifo);
while (fifo < 4 && cmd < 3) {
if (cmd == 0) {
LPI2C1_MTDR = LPI2C_MTDR_CMD_START | 1 | address;
} else if (cmd == 1) {
// causes bus stuck... need way to recover
//LPI2C1_MTDR = LPI2C_MTDR_CMD_START | (length - 1);
LPI2C1_MTDR = LPI2C_MTDR_CMD_RECEIVE | (length - 1);
} else {
if (sendStop) LPI2C1_MTDR = LPI2C_MTDR_CMD_STOP;
}
cmd++;
fifo = fifo + 1;
}
}
// receive stuff
if (rxBufferLength < sizeof(rxBuffer)) {
fifo = (LPI2C1_MFSR >> 16) & 0x07;
//if (fifo > 0) printf("r=%ld\n", fifo);
while (fifo > 0 && rxBufferLength < sizeof(rxBuffer)) {
rxBuffer[rxBufferLength++] = LPI2C1_MRDR;
fifo = fifo - 1;
}
}
// monitor status
status = LPI2C1_MSR; // pg 2899 & 2892
if (status & LPI2C_MSR_ALF) {
printf("arbitration lost\n");
break;
}
if (status & LPI2C_MSR_NDF) {
printf("got NACK\n");
// TODO: how to make sure stop is sent?
break;
}
if (rxBufferLength >= length && cmd >= 3) break;
}
//digitalWriteFast(15, HIGH);
//delayMicroseconds(2);
//digitalWriteFast(15, LOW);
return rxBufferLength;
}







constexpr TwoWire::I2C_Hardware_t TwoWire::i2c1_hardware = {
CCM_CCGR2, CCM_CCGR2_LPI2C1(CCM_CCGR_ON),
18, 17, 255, 255, 255,
2, 2, 0, 0, 0,
19, 16, 255, 255, 255,
2, 2, 0, 0, 0,
IRQ_LPI2C1
};

TwoWire Wire(0, TwoWire::i2c1_hardware);




void i2c_setclock(uint32_t frequency)
{
// timing params, pg 2363
//SETHOLD: 2-63
//CLKLO: 3-63 clock low time
//CLKHI: 1-63 clock high time
//DATAVD:
#if 0
// 100 kHz using 24 MHz clock
DIV = 2;
FILT = 5; // filt 2.5
CLOCK_PERIOD = (24 MHz / 100 kHz) / DIV = 120;
RISETIME = 1; // depends on resistors
LATENCY = (2 + FILT + RISETIME) / DIV = 4
PRESCALE = log2(DIV) = 1; // div by 2
CLKLO = CLOCK_PERIOD/2 - 1 = 59
CLKHI = CLOCK_PERIOD/2 - LATENCY - 1 = 55
DATAVD = CLKLO/3 - LATENCY = 15 // guesswork on /3
SETHOLD = ??? = 36

// 400 kHz using 24 MHz clock
DIV = 1;
FILT = 2;
CLOCK_PERIOD = (24 MHz / 400 kHz) / DIV = 60
RISETIME = 1; // depends on resistors
LATENCY = (2 + FILT + RISETIME) / DIV = 3
PRESCALE = log2(DIV) = 0
CLKLO = CLOCK_PERIOD/2 - 1 = 29
CLKHI = CLOCK_PERIOD/2 - LATENCY - 1 = 26
DATAVD = CLKLO/3 - LATENCY = 7 // guesswork
SETHOLD = ??? = 21

// 1 MHz
DIV = 1;
FILT = 1;
CLOCK_PERIOD = (24 MHz / 1 MHz) / DIV = 24
RISETIME = 1; // depends on resistors
LATENCY = (2 + FILT + RISETIME) / DIV = 2
PRESCALE = log2(DIV) = 0
CLKLO = CLOCK_PERIOD/2 - 1 = 29
CLKHI = CLOCK_PERIOD/2 - LATENCY - 1 = 27
DATAVD = CLKLO/3 - LATENCY = 7 // guesswork
SETHOLD = ??? = 22

#endif
LPI2C1_MCR = 0;
LPI2C1_MCCR0 = LPI2C_MCCR0_CLKHI(55) | LPI2C_MCCR0_CLKLO(59) |
LPI2C_MCCR0_DATAVD(25) | LPI2C_MCCR0_SETHOLD(40);
LPI2C1_MCCR1 = LPI2C1_MCCR0;
LPI2C1_MCFGR0 = 0;
LPI2C1_MCFGR1 = /*LPI2C_MCFGR1_TIMECFG |*/ LPI2C_MCFGR1_PRESCALE(1);
LPI2C1_MCFGR2 = LPI2C_MCFGR2_FILTSDA(5) | LPI2C_MCFGR2_FILTSCL(5) | LPI2C_MCFGR2_BUSIDLE(3900);
LPI2C1_MCFGR3 = LPI2C_MCFGR3_PINLOW(3900);
LPI2C1_MFCR = LPI2C_MFCR_RXWATER(1) | LPI2C_MFCR_TXWATER(1);
LPI2C1_MCR = LPI2C_MCR_MEN;
}

#endif

+ 319
- 0
WireIMXRT.h 查看文件

@@ -0,0 +1,319 @@
/* Wire Library for Teensy LC & 3.X
* Copyright (c) 2014-2017, Paul Stoffregen, paul@pjrc.com
*
* Development of this I2C library was funded by PJRC.COM, LLC by sales of
* Teensy and related products. Please support PJRC's efforts to develop
* open source software by purchasing Teensy or other PJRC products.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice, development funding notice, and this permission
* notice shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

#ifndef TwoWireIMXRT_h
#define TwoWireIMXRT_h

#if defined(__IMXRT1052__) || defined(__IMXRT1062__)

#include <Arduino.h>
#include <stdint.h>

#define BUFFER_LENGTH 32
#define WIRE_HAS_END 1

class TwoWire : public Stream
{
public:
// Hardware description struct
typedef struct {
volatile uint32_t &clock_gate_register;
uint32_t clock_gate_mask;
uint8_t sda_pin[5];
uint8_t sda_mux[5];
uint8_t scl_pin[5];
uint8_t scl_mux[5];
IRQ_NUMBER_t irq;
} I2C_Hardware_t;
static const I2C_Hardware_t i2c0_hardware;
static const I2C_Hardware_t i2c1_hardware;
static const I2C_Hardware_t i2c2_hardware;
static const I2C_Hardware_t i2c3_hardware;
public:
constexpr TwoWire(uintptr_t port_addr, const I2C_Hardware_t &myhardware)
: port_addr(port_addr), hardware(myhardware) {
}
void begin();
void begin(uint8_t address);
void begin(int address) {
begin((uint8_t)address);
}
void end();
void setClock(uint32_t frequency);
void setSDA(uint8_t pin);
void setSCL(uint8_t pin);
void beginTransmission(uint8_t address) {
txBuffer[0] = (address << 1);
transmitting = 1;
txBufferLength = 1;
}
void beginTransmission(int address) {
beginTransmission((uint8_t)address);
}
uint8_t endTransmission(uint8_t sendStop);
uint8_t endTransmission(void) {
return endTransmission(1);
}
uint8_t requestFrom(uint8_t address, uint8_t quantity, uint8_t sendStop);
uint8_t requestFrom(uint8_t address, uint8_t quantity) {
return requestFrom(address, quantity, (uint8_t)1);
}
uint8_t requestFrom(int address, int quantity, int sendStop) {
return requestFrom((uint8_t)address, (uint8_t)quantity,
(uint8_t)(sendStop ? 1 : 0));
}
uint8_t requestFrom(int address, int quantity) {
return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)1);
}
virtual size_t write(uint8_t data);
virtual size_t write(const uint8_t *data, size_t quantity);
virtual int available(void) {
return rxBufferLength - rxBufferIndex;
}
virtual int read(void) {
if (rxBufferIndex >= rxBufferLength) return -1;
return rxBuffer[rxBufferIndex++];
}
virtual int peek(void) {
if (rxBufferIndex >= rxBufferLength) return -1;
return rxBuffer[rxBufferIndex];
}
virtual void flush(void) {
}
void onReceive(void (*function)(int numBytes)) {
user_onReceive = function;
}
void onRequest(void (*function)(void)) {
user_onRequest = function;
}
// send() for compatibility with very old sketches and libraries
void send(uint8_t b) {
write(b);
}
void send(uint8_t *s, uint8_t n) {
write(s, n);
}
void send(int n) {
write((uint8_t)n);
}
void send(char *s) {
write(s);
}
uint8_t receive(void) {
int c = read();
if (c < 0) return 0;
return c;
}
size_t write(unsigned long n) {
return write((uint8_t)n);
}
size_t write(long n) {
return write((uint8_t)n);
}
size_t write(unsigned int n) {
return write((uint8_t)n);
}
size_t write(int n) {
return write((uint8_t)n);
}
using Print::write;
private:
//IMXRT_LPI2C_t & port() { return (*(IMXRT_LPI2C_t *) port_addr); }
uint8_t i2c_status(void) {
//return port().S;
return 0;
}
void isr(void);
bool wait_idle(void);
uintptr_t port_addr;
const I2C_Hardware_t &hardware;
uint8_t rxBuffer[BUFFER_LENGTH] = {};
uint8_t rxBufferIndex = 0;
uint8_t rxBufferLength = 0;
uint8_t txAddress = 0;
uint8_t txBuffer[BUFFER_LENGTH+1] = {};
uint8_t txBufferIndex = 0;
uint8_t txBufferLength = 0;
uint8_t transmitting = 0;
uint8_t slave_mode = 0;
uint8_t irqcount = 0;
uint8_t sda_pin_index = 0;
uint8_t scl_pin_index = 0;
void onRequestService(void);
void onReceiveService(uint8_t*, int);
void (*user_onRequest)(void) = nullptr;
void (*user_onReceive)(int) = nullptr;
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_isr0(void);
friend void sda_rising_isr1(void);
};

extern TwoWire Wire;
extern TwoWire Wire1;
extern TwoWire Wire2;
extern TwoWire Wire3;


class TWBRemulation
{
public:
inline TWBRemulation & operator = (int val) __attribute__((always_inline)) {
/*if (val == 12 || val == ((F_CPU / 400000) - 16) / 2) { // 22, 52, 112
I2C0_C1 = 0;
#if F_BUS == 128000000
I2C0_F = I2C_F_DIV320; // 400 kHz
#elif F_BUS == 120000000
I2C0_F = I2C_F_DIV288; // 416 kHz
#elif F_BUS == 108000000
I2C0_F = I2C_F_DIV256; // 422 kHz
#elif F_BUS == 96000000
I2C0_F = I2C_F_DIV240; // 400 kHz
#elif F_BUS == 90000000
I2C0_F = I2C_F_DIV224; // 402 kHz
#elif F_BUS == 80000000
I2C0_F = I2C_F_DIV192; // 416 kHz
#elif F_BUS == 72000000
I2C0_F = I2C_F_DIV192; // 375 kHz
#elif F_BUS == 64000000
I2C0_F = I2C_F_DIV160; // 400 kHz
#elif F_BUS == 60000000
I2C0_F = I2C_F_DIV144; // 416 kHz
#elif F_BUS == 56000000
I2C0_F = I2C_F_DIV144; // 389 kHz
#elif F_BUS == 54000000
I2C0_F = I2C_F_DIV128; // 422 kHz
#elif F_BUS == 48000000
I2C0_F = I2C_F_DIV112; // 400 kHz
#elif F_BUS == 40000000
I2C0_F = I2C_F_DIV96; // 416 kHz
#elif F_BUS == 36000000
I2C0_F = I2C_F_DIV96; // 375 kHz
#elif F_BUS == 24000000
I2C0_F = I2C_F_DIV64; // 375 kHz
#elif F_BUS == 16000000
I2C0_F = I2C_F_DIV40; // 400 kHz
#elif F_BUS == 8000000
I2C0_F = I2C_F_DIV20; // 400 kHz
#elif F_BUS == 4000000
I2C0_F = I2C_F_DIV20; // 200 kHz
#elif F_BUS == 2000000
I2C0_F = I2C_F_DIV20; // 100 kHz
#endif
I2C0_C1 = I2C_C1_IICEN;
} else if (val == 72 || val == ((F_CPU / 100000) - 16) / 2) { // 112, 232, 472
I2C0_C1 = 0;
#if F_BUS == 128000000
I2C0_F = I2C_F_DIV1280; // 100 kHz
#elif F_BUS == 120000000
I2C0_F = I2C_F_DIV1152; // 104 kHz
#elif F_BUS == 108000000
I2C0_F = I2C_F_DIV1024; // 105 kHz
#elif F_BUS == 96000000
I2C0_F = I2C_F_DIV960; // 100 kHz
#elif F_BUS == 90000000
I2C0_F = I2C_F_DIV896; // 100 kHz
#elif F_BUS == 80000000
I2C0_F = I2C_F_DIV768; // 104 kHz
#elif F_BUS == 72000000
I2C0_F = I2C_F_DIV640; // 112 kHz
#elif F_BUS == 64000000
I2C0_F = I2C_F_DIV640; // 100 kHz
#elif F_BUS == 60000000
I2C0_F = I2C_F_DIV576; // 104 kHz
#elif F_BUS == 56000000
I2C0_F = I2C_F_DIV512; // 109 kHz
#elif F_BUS == 54000000
I2C0_F = I2C_F_DIV512; // 105 kHz
#elif F_BUS == 48000000
I2C0_F = I2C_F_DIV480; // 100 kHz
#elif F_BUS == 40000000
I2C0_F = I2C_F_DIV384; // 104 kHz
#elif F_BUS == 36000000
I2C0_F = I2C_F_DIV320; // 113 kHz
#elif F_BUS == 24000000
I2C0_F = I2C_F_DIV240; // 100 kHz
#elif F_BUS == 16000000
I2C0_F = I2C_F_DIV160; // 100 kHz
#elif F_BUS == 8000000
I2C0_F = I2C_F_DIV80; // 100 kHz
#elif F_BUS == 4000000
I2C0_F = I2C_F_DIV40; // 100 kHz
#elif F_BUS == 2000000
I2C0_F = I2C_F_DIV20; // 100 kHz
#endif
I2C0_C1 = I2C_C1_IICEN;
} */
return *this;
}
inline operator int () const __attribute__((always_inline)) {
/* #if F_BUS == 128000000
if (I2C0_F == I2C_F_DIV320) return 12;
#elif F_BUS == 120000000
if (I2C0_F == I2C_F_DIV288) return 12;
#elif F_BUS == 108000000
if (I2C0_F == I2C_F_DIV256) return 12;
#elif F_BUS == 96000000
if (I2C0_F == I2C_F_DIV240) return 12;
#elif F_BUS == 90000000
if (I2C0_F == I2C_F_DIV224) return 12;
#elif F_BUS == 80000000
if (I2C0_F == I2C_F_DIV192) return 12;
#elif F_BUS == 72000000
if (I2C0_F == I2C_F_DIV192) return 12;
#elif F_BUS == 64000000
if (I2C0_F == I2C_F_DIV160) return 12;
#elif F_BUS == 60000000
if (I2C0_F == I2C_F_DIV144) return 12;
#elif F_BUS == 56000000
if (I2C0_F == I2C_F_DIV144) return 12;
#elif F_BUS == 54000000
if (I2C0_F == I2C_F_DIV128) return 12;
#elif F_BUS == 48000000
if (I2C0_F == I2C_F_DIV112) return 12;
#elif F_BUS == 40000000
if (I2C0_F == I2C_F_DIV96) return 12;
#elif F_BUS == 36000000
if (I2C0_F == I2C_F_DIV96) return 12;
#elif F_BUS == 24000000
if (I2C0_F == I2C_F_DIV64) return 12;
#elif F_BUS == 16000000
if (I2C0_F == I2C_F_DIV40) return 12;
#elif F_BUS == 8000000
if (I2C0_F == I2C_F_DIV20) return 12;
#elif F_BUS == 4000000
if (I2C0_F == I2C_F_DIV20) return 12;
#endif */
return 72;
}
};
extern TWBRemulation TWBR;

#endif
#endif

+ 1
- 1
WireKinetis.cpp 查看文件

@@ -27,7 +27,7 @@
#include <Arduino.h>
#include "Wire.h"

#if defined(__arm__) && defined(TEENSYDUINO)
#if defined(__arm__) && defined(TEENSYDUINO) && (defined(KINETISK) || defined(KINETISL))

#include "kinetis.h"
#include <string.h> // for memcpy

+ 1
- 1
WireKinetis.h 查看文件

@@ -27,7 +27,7 @@
#ifndef TwoWireKinetis_h
#define TwoWireKinetis_h

#if defined(__arm__) && defined(TEENSYDUINO)
#if defined(__arm__) && defined(TEENSYDUINO) && (defined(KINETISK) || defined(KINETISL))

#include <Arduino.h>
#include <stdint.h>

Loading…
取消
儲存