I2C CMSIS STM32F303RE
Hello again.
I'm having this problem with I2C with the STM32F303RE.
I have this array of data I want to send via I2C to a sensor.
std::uint8_t conf_bytes[2] = {0xF4, 0x03};
periph::I2C::write_data(I2C1, BME_ADDR, 2U, conf_bytes); BME_ADDR is the address of the sensor I want to write to.
and this is my function write_data:
void write_data(I2C_TypeDef * i2c, std::uint8_t slave_addr, std::uint8_t data_size, std::uint8_t * data){
volatile std::uint8_t nbytes = data_size;
volatile std::uint8_t i = 0;
i2c->CR1 &= ~I2C_CR1_PE;
i2c->CR1 |= I2C_CR1_PE;
while((i2c->ISR & IS_BUSSY)){}
i2c->CR2 &= ~I2C_CR2_RD_WRN;
i2c->CR2 |= (slave_addr << 1U);
i2c->CR2 |= (nbytes << NBYTES);
i2c->CR2 |= I2C_CR2_START;
while(nbytes--){
while(!(i2c->ISR & I2C_ISR_TXIS)){}
i2c->TXDR = data[i];
i++;
}
i2c->CR2 |= I2C_CR2_STOP;
}Trying this I get the following result with the logic analyzer:
That strange glitch happens all the time, and I don't know what else I can do.
I made another function to read a register of the sensor:
uint8_t * read_data(I2C_TypeDef * i2c, std::uint8_t slave_addr, std::uint8_t size, std::uint8_t * data); it is defined as follows:
uint8_t * read_reg(I2C_TypeDef * i2c, std::uint8_t slave_addr, std::uint8_t data_tx_size, std::uint8_t * data_tx, std::uint8_t data_rx_size){
i2c->CR1 &= ~I2C_CR1_PE;
i2c->CR1 |= I2C_CR1_PE;
std::uint8_t tx_s = data_tx_size;
std::uint8_t rx_s = data_rx_size;
std::uint8_t received = 0;
std::uint8_t * data_return = new std::uint8_t[rx_s];
while((i2c->ISR & IS_BUSSY)){}
i2c->CR2 &= ~I2C_CR2_RD_WRN;
i2c->CR2 |= (slave_addr << 1U);
volatile std::uint8_t i = 0;
i2c->CR2 |= (tx_s << NBYTES);
i2c->CR2 |= I2C_CR2_START;
while(tx_s--){
while(!(i2c->ISR & I2C_ISR_TXIS)){}
i2c->TXDR = data_tx[i];
i++;
}
i2c->CR2 &= ~(tx_s << NBYTES);
i2c->CR2 |= (rx_s << NBYTES);
i2c->CR2 |= I2C_CR2_RD_WRN;
i2c->CR2 |= I2C_CR2_START;
while(rx_s--){
while(!(i2c->ISR & I2C_ISR_RXNE)){}
data_return[received] = i2c->RXDR;
}
i2c->CR2 |= I2C_CR2_STOP;
return data_return;
}and for example, I want to read the register 0XD0 that contains the sensor ID:
utils::delay::ms(200);
std::uint8_t data_i2c[1] = {0xD0};
periph::I2C::read_reg(I2C1, BME_ADDR, 1U, data_i2c, 1U);
utils::delay::ms(200); And the result is the following:
It works perfectly, but, even if I make a write and then a read, all the data gets distorted all over again, so, I don't know what could it be, or maybe is my logic analyzer (is one of those cheap Chinese of saelae, but for now, it has been working perfectly)
Thanks for any answer
