User Tools

Site Tools


STM32 I2C bus code

I wrote the code “from scratch”.

i2creg.c
 
/*  Author, Copyright: Oleg Borodin, 2018 */
 
#include <libopencm3/stm32/i2c.h>
#include <stdlib.h>
#include <i2creg.h>
 
uint16_t i2c_read_seq(uint32_t i2c, uint16_t addr, uint8_t reg, uint8_t *data, uint16_t len) {
 
    i2c_enable_ack(i2c);
    i2c_send_start(i2c);
 
    /* I2C_EVENT_MASTER_MODE_SELECT EV5: BUSY, MSL and SB */
    while (!((I2C_SR1(i2c) & I2C_SR1_SB) & 
             (I2C_SR2(i2c) & (I2C_SR2_MSL | I2C_SR2_BUSY))));
 
    i2c_send_7bit_address(i2c, addr, I2C_WRITE);
    /* I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED EV6: BUSY, MSL, ADDR, TXE and TRA */
    while (!(  (I2C_SR1(i2c) & (I2C_SR1_TxE | I2C_SR1_ADDR)) & 
               (I2C_SR2(i2c) & (I2C_SR2_MSL | I2C_SR2_BUSY | I2C_SR2_TRA)) ));
    (void)I2C_SR2(i2c);
 
    i2c_send_data(i2c, reg);
    /* I2C_EVENT_MASTER_BYTE_TRANSMITTED EV8_2: TRA, BUSY, MSL, TXE and BTF */
    while (!((I2C_SR1(i2c) & (I2C_SR1_TxE | I2C_SR1_BTF)) & 
             (I2C_SR2(i2c) & (I2C_SR2_MSL | I2C_SR2_BUSY | I2C_SR2_TRA))));
 
    i2c_send_start(i2c);
    /* I2C_EVENT_MASTER_MODE_SELECT EV5: BUSY, MSL and SB */
    while (!((I2C_SR1(i2c) & I2C_SR1_SB) & 
             (I2C_SR2(i2c) & (I2C_SR2_MSL | I2C_SR2_BUSY))));
 
    i2c_send_7bit_address(i2c, addr, I2C_READ);
    /* I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED EV6: BUSY, MSL and ADDR */
    while (!(  (I2C_SR1(i2c) & (I2C_SR1_ADDR)) &
               (I2C_SR2(i2c) & (I2C_SR2_MSL | I2C_SR2_BUSY)) ));
 
    uint16_t i;
    for (i = 0; i < len; i++) {
        if (i == len - 1) {
            i2c_disable_ack(i2c);
            //i2c_nack_current(i2c);
            i2c_send_stop(i2c);
        }
        /* I2C_EVENT_MASTER_BYTE_RECEIVED EV7: BUSY, MSL and RXNE */
        while (!(I2C_SR1(i2c) & I2C_SR1_RxNE));
        data[i] = i2c_get_data(i2c);
    }
 
    while ((I2C_SR2(i2c) & (I2C_SR2_MSL | I2C_SR2_BUSY)));
    return ++i;
}
 
uint16_t i2c_write_seq(uint32_t i2c, uint16_t addr, uint8_t reg, uint8_t *data, uint16_t len) {
 
    i2c_enable_ack(i2c);
    i2c_send_start(i2c);
 
    /* I2C_EVENT_MASTER_MODE_SELECT EV5: BUSY, MSL and SB */
    while (!((I2C_SR1(i2c) & I2C_SR1_SB) & 
             (I2C_SR2(i2c) & (I2C_SR2_MSL | I2C_SR2_BUSY))));
 
    i2c_send_7bit_address(i2c, addr, I2C_WRITE);
    /* I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED EV6: BUSY, MSL, ADDR, TXE and TRA */
    while (!(  (I2C_SR1(i2c) & (I2C_SR1_TxE | I2C_SR1_ADDR)) & 
               (I2C_SR2(i2c) & (I2C_SR2_MSL | I2C_SR2_BUSY | I2C_SR2_TRA)) ));
    //(void)I2C_SR2(i2c);
 
    i2c_send_data(i2c, reg);
    /* I2C_EVENT_MASTER_BYTE_TRANSMITTED EV8_2: TRA, BUSY, MSL, TXE and BTF */
    while (!((I2C_SR1(i2c) & (I2C_SR1_TxE | I2C_SR1_BTF)) & 
             (I2C_SR2(i2c) & (I2C_SR2_MSL | I2C_SR2_BUSY | I2C_SR2_TRA))));
 
    uint16_t i;
    for (i = 0; i < len; i++) {
        i2c_send_data(i2c, data[i]);
        /* I2C_EVENT_MASTER_BYTE_TRANSMITTED EV8_2: TRA, BUSY, MSL, TXE and BTF */
        while (!((I2C_SR1(i2c) & (I2C_SR1_TxE | I2C_SR1_BTF)) & 
                (I2C_SR2(i2c) & (I2C_SR2_MSL | I2C_SR2_BUSY | I2C_SR2_TRA))));
    }
 
    i2c_send_stop(i2c);
 
    while ((I2C_SR2(i2c) & (I2C_SR2_MSL | I2C_SR2_BUSY)));
    return ++i;
}
 
void i2c_write_reg(uint32_t i2c, uint16_t addr, uint8_t reg, uint8_t data) {
    i2c_write_seq(i2c, addr, reg, &data, 1);
}
 
uint8_t i2c_read_reg(uint32_t i2c, uint16_t addr, uint8_t reg) {
    uint8_t data;
    i2c_read_seq(i2c, addr, reg, &data, 1);
    return data;
}
 
 
 
/* EOF */

First PagePrevious PageBack to overviewNext PageLast Page