Browse Source

Use hardware description for pin numbers

main
PaulStoffregen 7 years ago
parent
commit
5df8a3133d
2 changed files with 131 additions and 128 deletions
  1. +118
    -125
      WireKinetis.cpp
  2. +13
    -3
      WireKinetis.h

+ 118
- 125
WireKinetis.cpp View File

@@ -44,25 +44,19 @@

void sda_rising_isr(void);

TwoWire::TwoWire(KINETIS_I2C_t &myport, const I2C_Hardware_t &myhardware)
: port(myport), hardware(myhardware)
void TwoWire::begin(void)
{
//serial_begin(BAUD2DIV(115200));
//serial_print("\nWire Begin\n");

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)
{
//serial_begin(BAUD2DIV(115200));
//serial_print("\nWire Begin\n");

slave_mode = 0;
hardware.clock_gate_register |= hardware.clock_gate_mask;
port.C1 = 0;
@@ -73,32 +67,14 @@ void TwoWire::begin(void)
// would enable pullup resistors. However, there seems
// to be a bug in chip while I2C is enabled, where setting
// those causes the port to be driven strongly high.
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
}
uint32_t mux;
volatile uint32_t *reg;
reg = portConfigRegister(hardware.sda_pin[sda_pin_index]);
mux = PORT_PCR_MUX(hardware.sda_mux[sda_pin_index]);
*reg = mux|PORT_PCR_ODE|PORT_PCR_SRE|PORT_PCR_DSE;
reg = portConfigRegister(hardware.scl_pin[scl_pin_index]);
mux = PORT_PCR_MUX(hardware.scl_mux[scl_pin_index]);
*reg = mux|PORT_PCR_ODE|PORT_PCR_SRE|PORT_PCR_DSE;
setClock(100000);
port.C2 = I2C_C2_HDRS;
port.C1 = I2C_C1_IICEN;
@@ -269,72 +245,44 @@ void TwoWire::setClock(uint32_t frequency)

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
}
if (pin == hardware.sda_pin[sda_pin_index]) return;
uint32_t newindex=0;
while (1) {
uint32_t sda_pin = hardware.sda_pin[newindex];
if (sda_pin == 255) return;
if (sda_pin == pin) break;
if (++newindex >= sizeof(hardware.sda_pin)) return;
}
sda_pin_num = pin;
if ((hardware.clock_gate_register & hardware.clock_gate_mask)) {
volatile uint32_t *reg;
reg = portConfigRegister(hardware.sda_pin[sda_pin_index]);
*reg = 0;
reg = portConfigRegister(hardware.sda_pin[newindex]);
uint32_t mux = PORT_PCR_MUX(hardware.sda_mux[newindex]);
*reg = mux|PORT_PCR_ODE|PORT_PCR_SRE|PORT_PCR_DSE;
}
sda_pin_index = newindex;
}

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
}
if (pin == hardware.scl_pin[scl_pin_index]) return;
uint32_t newindex=0;
while (1) {
uint32_t scl_pin = hardware.scl_pin[newindex];
if (scl_pin == 255) return;
if (scl_pin == pin) break;
if (++newindex >= sizeof(hardware.scl_pin)) return;
}
scl_pin_num = pin;
if ((hardware.clock_gate_register & hardware.clock_gate_mask)) {
volatile uint32_t *reg;
reg = portConfigRegister(hardware.scl_pin[scl_pin_index]);
*reg = 0;
reg = portConfigRegister(hardware.scl_pin[newindex]);
uint32_t mux = PORT_PCR_MUX(hardware.scl_mux[newindex]);
*reg = mux|PORT_PCR_ODE|PORT_PCR_SRE|PORT_PCR_DSE;
}
scl_pin_index = newindex;
}

void TwoWire::begin(uint8_t address)
@@ -350,33 +298,13 @@ void TwoWire::end()
{
if (!(hardware.clock_gate_register & hardware.clock_gate_mask)) return;
NVIC_DISABLE_IRQ(IRQ_I2C0);
// TODO: should this try to create a stop condition??
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
}
volatile uint32_t *reg;
reg = portConfigRegister(hardware.scl_pin[scl_pin_index]);
*reg = 0;
reg = portConfigRegister(hardware.sda_pin[sda_pin_index]);
*reg = 0;
hardware.clock_gate_register &= ~hardware.clock_gate_mask;
}

@@ -686,14 +614,79 @@ uint8_t TwoWire::requestFrom(uint8_t address, uint8_t length, uint8_t sendStop)
}


const TwoWire::I2C_Hardware_t TwoWire::i2c0_hardware = {
SIM_SCGC4, SIM_SCGC4_I2C0,
#if defined(__MKL26Z64__) || defined(__MK20DX128__) || defined(__MK20DX256__)
18, 17, 255, 255, 255,
2, 2, 0, 0, 0,
19, 16, 255, 255, 255,
2, 2, 0, 0, 0,
#elif defined(__MK64FX512__) || defined(__MK66FX1M0__)
18, 17, 34, 8, 48,
2, 2, 5, 7, 2,
19, 16, 33, 7, 47,
2, 2, 5, 7, 2,
#endif
};

const TwoWire::I2C_Hardware_t TwoWire::i2c1_hardware = {
SIM_SCGC4, SIM_SCGC4_I2C1,
#if defined(__MKL26Z64__)
23, 255, 255, 255, 255,
2, 0, 0, 0, 0,
22, 255, 255, 255, 255,
2, 0, 0, 0, 0,
#elif defined(__MK20DX256__)
30, 255, 255, 255, 255,
2, 0, 0, 0, 0,
29, 255, 255, 255, 255,
2, 0, 0, 0, 0,
#elif defined(__MK64FX512__) || defined(__MK66FX1M0__)
38, 255, 255, 255, 255,
2, 0, 0, 0, 0,
37, 255, 255, 255, 255,
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
};

const TwoWire::I2C_Hardware_t TwoWire::i2c2_hardware = {
SIM_SCGC1, SIM_SCGC1_I2C2,
#if defined(__MK64FX512__) || defined(__MK66FX1M0__)
4, 255, 255, 255, 255,
5, 0, 0, 0, 0,
3, 26, 255, 255, 255,
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
};

const TwoWire::I2C_Hardware_t TwoWire::i2c0_hardware = {
SIM_SCGC4, SIM_SCGC4_I2C0
const TwoWire::I2C_Hardware_t TwoWire::i2c3_hardware = {
SIM_SCGC1, SIM_SCGC1_I2C3,
#if defined(__MK66FX1M0__)
56, 255, 255, 255, 255,
2, 0, 0, 0, 0,
57, 255, 255, 255, 255,
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
};


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




+ 13
- 3
WireKinetis.h View File

@@ -46,10 +46,19 @@ public:
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];
} 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:
TwoWire(KINETIS_I2C_t &myport, const I2C_Hardware_t &myhardware);
TwoWire(KINETIS_I2C_t &myport, const I2C_Hardware_t &myhardware)
: port(myport), hardware(myhardware), sda_pin_index(0), scl_pin_index(0) {
}
void begin();
void begin(uint8_t address);
void begin(int address) {
@@ -142,6 +151,7 @@ private:
while (!(port.S & I2C_S_IICIF)) ; // wait (TODO: timeout)
port.S = I2C_S_IICIF;
}
void isr(void);
KINETIS_I2C_t &port;
const I2C_Hardware_t &hardware;
uint8_t rxBuffer[BUFFER_LENGTH];
@@ -154,13 +164,13 @@ private:
uint8_t transmitting;
uint8_t slave_mode;
uint8_t irqcount;
uint8_t sda_pin_index;
uint8_t scl_pin_index;
void onRequestService(void);
void onReceiveService(uint8_t*, int);
void (*user_onRequest)(void);
void (*user_onReceive)(int);
void sda_rising_isr(void);
uint8_t sda_pin_num;
uint8_t scl_pin_num;
friend void i2c0_isr(void);
friend void sda_rising_isr(void);
};

Loading…
Cancel
Save