void i2c_setup(void) { rcc_periph_clock_enable(RCC_I2C1); rcc_periph_clock_enable(RCC_GPIOB); //clock from 48 MHz RCC_CFGR3 |= RCC_CFGR3_I2C1SW; //i2c_reset(I2C_BUS); RCC_APB1RSTR |= RCC_APB1RSTR_I2C1RST; RCC_APB1RSTR &= ~RCC_APB1RSTR_I2C1RST; gpio_mode_setup(I2C_PIN_PORT, GPIO_MODE_AF, GPIO_PUPD_NONE, I2C_PINS); gpio_set_af(I2C_PIN_PORT, I2C_PIN_AF, I2C_PINS); //i2c_peripheral_disable(I2C_BUS); I2C_CR1(I2C_BUS) &= ~I2C_CR1_PE; //configure ANFOFF DNF[3:0] in CR1 //i2c_enable_analog_filter(I2C_BUS); I2C_CR1(I2C_BUS) &= ~I2C_CR1_ANFOFF; //i2c_set_digital_filter(I2C_BUS, I2C_CR1_DNF_DISABLED); //default is good //Configure PRESC[3:0] SDADEL[3:0] SCLDEL[3:0] SCLH[7:0] SCLL[7:0] // in TIMINGR //i2c_100khz_i2cclk8mhz(I2C_BUS); //let's assume this is good :) //I don't think the timing matters when we're slave I2C_TIMINGR(I2C_BUS) = 0; //configure No-Stretch CR1 (only relevant in slave mode) //i2c_enable_stretching(I2C_BUS); //addressing mode //i2c_set_7bit_addr_mode(I2C_BUS); //default is good //slave address I2C_OAR1(I2C_BUS) = I2C_OAR1_OA1EN + (I2C_SLAVE_ADDRESS << 1); //enable all interrupts I2C_CR1(I2C_BUS) |= 0xfe; //i2c_peripheral_enable(I2C_BUS); I2C_CR1(I2C_BUS) |= I2C_CR1_PE; nvic_enable_irq(NVIC_I2C1_IRQ); }
void i2c_set_scl_low_period(uint32_t i2c, uint8_t period) { I2C_TIMINGR(i2c) = (I2C_TIMINGR(i2c) & ~I2C_TIMINGR_SCLL_MASK) | (period << I2C_TIMINGR_SCLL_SHIFT); }
void i2c_set_data_hold_time(uint32_t i2c, uint8_t h_time) { I2C_TIMINGR(i2c) = (I2C_TIMINGR(i2c) & ~I2C_TIMINGR_SDADEL_MASK) | (h_time << I2C_TIMINGR_SDADEL_SHIFT); }
void i2c_set_data_setup_time(uint32_t i2c, uint8_t s_time) { I2C_TIMINGR(i2c) = (I2C_TIMINGR(i2c) & ~I2C_TIMINGR_SCLDEL_MASK) | (s_time << I2C_TIMINGR_SCLDEL_SHIFT); }
/* t_presc= (presc+1)*t_i2cclk */ void i2c_set_prescaler(uint32_t i2c, uint8_t presc) { I2C_TIMINGR(i2c) = (I2C_TIMINGR(i2c) & ~I2C_TIMINGR_PRESC_MASK) | (presc << I2C_TIMINGR_PRESC_SHIFT); }