void i2c_poweron(i2c_t dev) { switch (dev) { #if I2C_0_EN case I2C_0: I2C_0_CLKEN(); break; #endif } }
int i2c_init_master(i2c_t dev, i2c_speed_t speed) { I2C_TypeDef *i2c; gpio_t pin_scl, pin_sda; int ccr; /* read speed configuration */ switch (speed) { case I2C_SPEED_NORMAL: ccr = I2C_APBCLK / 200000; break; case I2C_SPEED_FAST: ccr = I2C_APBCLK / 800000; break; default: return -2; } /* read static device configuration */ switch (dev) { #if I2C_0_EN case I2C_0: i2c = I2C_0_DEV; pin_scl = I2C_0_SCL_PIN; pin_sda = I2C_0_SDA_PIN; I2C_0_CLKEN(); NVIC_SetPriority(I2C_0_ERR_IRQ, I2C_IRQ_PRIO); NVIC_EnableIRQ(I2C_0_ERR_IRQ); break; #endif default: return -1; } /* configure pins */ _pin_config(pin_scl, pin_sda); /* configure device */ _i2c_init(i2c, ccr); /* make sure the analog filters don't hang -> see errata sheet 2.14.7 */ if (i2c->SR2 & I2C_SR2_BUSY) { DEBUG("LINE BUSY AFTER RESET -> toggle pins now\n"); /* disable peripheral */ i2c->CR1 &= ~I2C_CR1_PE; /* re-run pin config to toggle and re-configure pins */ _pin_config(pin_scl, pin_sda); /* make peripheral soft reset */ i2c->CR1 |= I2C_CR1_SWRST; i2c->CR1 &= ~I2C_CR1_SWRST; /* enable device */ _i2c_init(i2c, ccr); } return 0; }
int i2c_init_master(i2c_t dev, i2c_speed_t speed) { I2C_Type *i2c; PORT_Type *i2c_port; int pin_scl = 0; int pin_sda = 0; uint32_t baudrate_flags = 0; /** @todo Kinetis I2C: Add automatic baud rate flags selection function */ /* * See the Chapter "I2C divider and hold values": * Kinetis K60 Reference Manual, section 51.4.1.10, Table 51-41. * Kinetis MKW2x Reference Manual, section 52.4.1.10, Table 52-41. * * baud rate = I2C_module_clock / (mul × ICR) */ switch (speed) { case I2C_SPEED_LOW: baudrate_flags |= I2C_F_MULT(KINETIS_I2C_F_MULT_LOW) | I2C_F_ICR(KINETIS_I2C_F_ICR_LOW); break; case I2C_SPEED_NORMAL: baudrate_flags |= I2C_F_MULT(KINETIS_I2C_F_MULT_NORMAL) | I2C_F_ICR(KINETIS_I2C_F_ICR_NORMAL); break; case I2C_SPEED_FAST: baudrate_flags |= I2C_F_MULT(KINETIS_I2C_F_MULT_FAST) | I2C_F_ICR(KINETIS_I2C_F_ICR_FAST); break; case I2C_SPEED_FAST_PLUS: baudrate_flags |= I2C_F_MULT(KINETIS_I2C_F_MULT_FAST_PLUS) | I2C_F_ICR(KINETIS_I2C_F_ICR_FAST_PLUS); break; default: /* * High speed mode is not supported on Kinetis devices, * see: https://community.freescale.com/thread/316371 * * Hardware allows setting the baud rate high enough but the * capacitance of the bus and lacking a proper high speed mode SCL * driver will make the signals go out of spec. */ return -2; } /* read static device configuration */ switch (dev) { #if I2C_0_EN case I2C_0: i2c = I2C_0_DEV; i2c_port = I2C_0_PORT; pin_scl = I2C_0_SCL_PIN; pin_sda = I2C_0_SDA_PIN; I2C_0_CLKEN(); I2C_0_PORT_CLKEN(); break; #endif default: return -1; } /* configure pins, alternate output */ i2c_port->PCR[pin_scl] = I2C_0_PORT_CFG; i2c_port->PCR[pin_sda] = I2C_0_PORT_CFG; i2c->F = baudrate_flags; /* enable i2c-module and interrupt */ i2c->C1 = I2C_C1_IICEN_MASK | I2C_C1_IICIE_MASK | I2C_C1_TXAK_MASK; i2c->C2 = 0; return 0; }
int i2c_init_master(i2c_t dev, i2c_speed_t speed) { I2C_TypeDef *i2c; GPIO_TypeDef *port_scl; GPIO_TypeDef *port_sda; int pin_scl, pin_sda; int ccr; /* read speed configuration */ switch (speed) { case I2C_SPEED_NORMAL: ccr = I2C_APBCLK / 200000; break; case I2C_SPEED_FAST: ccr = I2C_APBCLK / 800000; break; default: return -2; } /* read static device configuration */ switch (dev) { #if I2C_0_EN case I2C_0: i2c = I2C_0_DEV; port_scl = I2C_0_SCL_PORT; pin_scl = I2C_0_SCL_PIN; port_sda = I2C_0_SDA_PORT; pin_sda = I2C_0_SDA_PIN; I2C_0_CLKEN(); I2C_0_SCL_CLKEN(); I2C_0_SDA_CLKEN(); break; #endif default: return -1; } /* configure pins, alternate output, open-drain, output mode with 50MHz */ if (pin_scl < 8) { port_scl->CRL |= (0xf << (pin_scl * 4)); } else { port_scl->CRH |= (0xf << ((pin_scl - 8) * 4)); } if (pin_sda < 8) { port_sda->CRL |= (0xf << (pin_sda * 4)); } else { port_sda->CRH |= (0xf << ((pin_sda - 8) * 4)); } /* disable device and set ACK bit */ i2c->CR1 = I2C_CR1_ACK; /* configure I2C clock */ i2c->CR2 = (I2C_APBCLK / 1000000); i2c->CCR = ccr; i2c->TRISE = (I2C_APBCLK / 1000000) + 1; /* configure device */ i2c->OAR1 = 0; /* makes sure we are in 7-bit address mode */ /* enable device */ i2c->CR1 |= I2C_CR1_PE; return 0; }