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; }
mp_obj_t pyb_I2C(mp_obj_t i2c_id, mp_obj_t i2c_addr) { pyb_i2c_t i2c_port; switch(mp_obj_get_int(i2c_id)) { case 0: i2c_port = PYB_I2C_1; break; case 1: i2c_port = PYB_I2C_2; break; default: return mp_const_none; } if (_i2c_init(i2c_port) == false) { return mp_const_none; } pyb_i2c_obj_t *o = m_new_obj(pyb_i2c_obj_t); o->base.type = &i2c_obj_type; o->i2c_port = i2c_port; o->i2c_addr = mp_obj_get_int(i2c_addr); o->i2c_state = I2C_STATE_IDLE; return o; }
int i2c_init_master(i2c_t dev, i2c_speed_t speed) { int ccr; if ((unsigned int)dev >= I2C_NUMOF) { return -1; } /* 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; } I2C_TypeDef *i2c = i2c_config[dev].dev; /* enable I2C clock */ i2c_poweron(dev); /* set IRQn priority */ NVIC_SetPriority(i2c_config[dev].er_irqn, I2C_IRQ_PRIO); /* enable IRQn */ NVIC_EnableIRQ(i2c_config[dev].er_irqn); /* configure pins */ gpio_init(i2c_config[dev].scl, GPIO_DIR_OUT, GPIO_PULLUP); gpio_init_af(i2c_config[dev].scl, i2c_config[dev].af); gpio_init(i2c_config[dev].sda, GPIO_DIR_OUT, GPIO_PULLUP); gpio_init_af(i2c_config[dev].sda, i2c_config[dev].af); /* configure device */ _i2c_init(i2c, ccr); return 0; }
void i2c_init(i2c_t dev) { assert(dev < I2C_NUMOF); DEBUG("[i2c] init: initializing device\n"); mutex_init(&locks[dev]); I2C_TypeDef *i2c = i2c_config[dev].dev; periph_clk_en(i2c_config[dev].bus, i2c_config[dev].rcc_mask); NVIC_SetPriority(i2c_config[dev].irqn, I2C_IRQ_PRIO); NVIC_EnableIRQ(i2c_config[dev].irqn); #if defined(CPU_FAM_STM32F0) || defined(CPU_FAM_STM32F3) /* Set I2CSW bits to enable I2C clock source */ RCC->CFGR3 |= i2c_config[dev].rcc_sw_mask; #endif DEBUG("[i2c] init: configuring pins\n"); /* configure pins */ gpio_init(i2c_config[dev].scl_pin, GPIO_OD_PU); gpio_init_af(i2c_config[dev].scl_pin, i2c_config[dev].scl_af); gpio_init(i2c_config[dev].sda_pin, GPIO_OD_PU); gpio_init_af(i2c_config[dev].sda_pin, i2c_config[dev].sda_af); DEBUG("[i2c] init: configuring device\n"); /* set the timing register value from predefined values */ i2c_timing_param_t tp = timing_params[i2c_config[dev].speed]; uint32_t timing = (( (uint32_t)tp.presc << I2C_TIMINGR_PRESC_Pos) | ( (uint32_t)tp.scldel << I2C_TIMINGR_SCLDEL_Pos) | ( (uint32_t)tp.sdadel << I2C_TIMINGR_SDADEL_Pos) | ( (uint16_t)tp.sclh << I2C_TIMINGR_SCLH_Pos) | tp.scll); _i2c_init(i2c, timing); }
void i2c_init(i2c_t dev) { assert(dev < I2C_NUMOF); mutex_init(&locks[dev]); I2C_TypeDef *i2c = i2c_config[dev].dev; assert(i2c != NULL); uint32_t ccr; /* read speed configuration */ switch (i2c_config[dev].speed) { case I2C_SPEED_LOW: /* 10Kbit/s */ ccr = i2c_config[dev].clk / 20000; break; case I2C_SPEED_NORMAL: /* 100Kbit/s */ ccr = i2c_config[dev].clk / 200000; break; case I2C_SPEED_FAST: ccr = i2c_config[dev].clk / 800000; break; default: return; } periph_clk_en(i2c_config[dev].bus, i2c_config[dev].rcc_mask); NVIC_SetPriority(i2c_config[dev].irqn, I2C_IRQ_PRIO); NVIC_EnableIRQ(i2c_config[dev].irqn); /* configure pins */ gpio_init(i2c_config[dev].scl_pin, GPIO_OD_PU); gpio_init(i2c_config[dev].sda_pin, GPIO_OD_PU); #ifdef CPU_FAM_STM32F1 /* This is needed in case the remapped pins are used */ if (i2c_config[dev].scl_pin == GPIO_PIN(PORT_B, 8) || i2c_config[dev].sda_pin == GPIO_PIN(PORT_B, 9)) { /* The remapping periph clock must first be enabled */ RCC->APB2ENR |= RCC_APB2ENR_AFIOEN; /* Then the remap can occur */ AFIO->MAPR |= AFIO_MAPR_I2C1_REMAP; } gpio_init_af(i2c_config[dev].scl_pin, GPIO_AF_OUT_OD); gpio_init_af(i2c_config[dev].sda_pin, GPIO_AF_OUT_OD); #else gpio_init_af(i2c_config[dev].scl_pin, i2c_config[dev].scl_af); gpio_init_af(i2c_config[dev].sda_pin, i2c_config[dev].sda_af); #endif /* configure device */ _i2c_init(i2c, i2c_config[dev].clk, ccr); #if defined(CPU_FAM_STM32F4) /* make sure the analog filters don't hang -> see errata sheet 2.14.7 */ if (i2c->SR2 & I2C_SR2_BUSY) { /* disable peripheral */ i2c->CR1 &= ~I2C_CR1_PE; /* toggle both pins to reset analog filter */ gpio_init(i2c_config[dev].scl_pin, GPIO_OD); gpio_init(i2c_config[dev].sda_pin, GPIO_OD); gpio_set(i2c_config[dev].sda_pin); gpio_set(i2c_config[dev].scl_pin); gpio_clear(i2c_config[dev].sda_pin); gpio_clear(i2c_config[dev].scl_pin); gpio_set(i2c_config[dev].sda_pin); gpio_set(i2c_config[dev].scl_pin); /* reset pins for alternate function */ gpio_init(i2c_config[dev].scl_pin, GPIO_OD_PU); gpio_init(i2c_config[dev].sda_pin, GPIO_OD_PU); gpio_init_af(i2c_config[dev].scl_pin, i2c_config[dev].scl_af); gpio_init_af(i2c_config[dev].sda_pin, i2c_config[dev].sda_af); /* make peripheral soft reset */ i2c->CR1 |= I2C_CR1_SWRST; i2c->CR1 &= ~I2C_CR1_SWRST; /* enable device */ _i2c_init(i2c, i2c_config[dev].clk, ccr); } #endif }