#include "i2c.h" #include "stm32.h" void I2C::enable() { RCC.enable(RCC.I2C2); asm volatile("nop"); I2C2.CR1 = 0x8000; I2C2.CR1 = 0; I2C2.CR2 = 36; I2C2.TRISE = 37; I2C2.CCR = 180; I2C2.CR1 = 1; } void I2C::write_reg(uint8_t addr, uint8_t reg, uint8_t data) { I2C2.CR1 |= 0x100; while(!(I2C2.SR1 & 0x01)); I2C2.DR = (addr << 1) | 0; while (!(I2C2.SR1 & 0x02)); I2C2.SR2; I2C2.DR = reg; while (!(I2C2.SR1 & 0x80)); I2C2.DR = data; while (!(I2C2.SR1 & 0x04)); I2C2.CR1 |= 0x200; } void I2C::read_reg(uint8_t addr, uint8_t reg, uint8_t len, uint8_t* buf) { I2C2.CR1 |= 0x100; while(!(I2C2.SR1 & 0x01)); I2C2.DR = (addr << 1) | 0; while (!(I2C2.SR1 & 0x02)); I2C2.SR2; I2C2.DR = reg; while (!(I2C2.SR1 & 0x80)); I2C2.CR1 |= 0x100; while(!(I2C2.SR1 & 0x01)); I2C2.DR = (addr << 1) | 1; while (!(I2C2.SR1 & 0x02)); I2C2.SR2; I2C2.CR1 |= 0x400; // Set ACK. while(len) { if(len == 3) { while (!(I2C2.SR1 & 0x04)); // Wait for BTF I2C2.CR1 &= ~0x400; // Clear ACK. *buf++ = I2C2.DR; len--; I2C2.CR1 |= 0x200; // Set STOP. *buf++ = I2C2.DR; len--; } else { while (!(I2C2.SR1 & 0x40)); // Wait for RXNE *buf++ = I2C2.DR; len--; } } }