I2C-Library for various sensors

twi_master.cpp

Committer:
JOEV
Date:
2019-07-31
Revision:
0:782435d2cc06

File content as of revision 0:782435d2cc06:

/**
 * @brief Implementation of TWI_Master class.
 * 
 * @file twi_master.cpp
 * @author Joel von Rotz
 * @date 18.07.2018
 */
#include "mbed.h"
#include "twi_master.h"

/**
 * @brief Construct a new TWI_Master object. The given parameters should be all the necessary things to start
 * interacting with the other libraries.
 * 
 * @param sda SDA-Pin
 * @param scl SCL-Pin
 * @param frequency     I2C-frequency (default: 400kHz)
 */
TWI_Master::TWI_Master(PinName sda, PinName scl, uint32_t frequency) : 
        m_i2c_sensor(sda, scl)
{
    m_i2c_sensor.frequency(frequency);
}

/**
 * @brief Writes data into specified address (changes every bit)
 * 
 * @param slave_address     register-address which will be written to 
 * @param data              8-bit value that overwrites the register-value
 */
void        TWI_Master::i2c_write(uint8_t i2c_address, uint8_t slave_address, const uint8_t data)
{
    char writeArray[2] = {slave_address, data};
    m_i2c_sensor.write(i2c_address, writeArray, 2, false);
}

/**
 * @brief Writes bits by masking the necessary bits. The data variables will be normally masked with the mask 
 * <code><strong>(data & mask)</strong></code>, the register will be masked by the inverted mask <code><strong>(register_value & ~mask)</strong></code>.
 * What will be written to the register will be <code><strong> new_register_data = (data | register_value) </strong></code>.
 * 
 * @param slave_address     register-address that will be edited
 * @param data              8-bit value that edit the editable bits (which are determined by the mask) 
 * @param mask              Bits that want to be changed, all the other bits will be saved. 
 */
void        TWI_Master::i2c_writeBits(uint8_t i2c_address, uint8_t slave_address, const uint8_t data, uint8_t mask)
{
    char current_value;
    char writeArray[2] = {slave_address, data};

    //Get current value of desired register and mask it with mask-value
    current_value = i2c_read(i2c_address, slave_address);
    current_value &= ~mask;

    //Combine Data with the new data (additionaly masking the data) and send it to the Sensor
    writeArray[1] = current_value | (data & mask);

    m_i2c_sensor.write(i2c_address, writeArray, 2, false);
}

/**
 * @brief Reads multiple registers
 * 
 * @param slave_address     the start register-address
 * @param data              array, which the functions saves the data to
 * @param length            the length of the read-sequence
 */
void        TWI_Master::i2c_readSeries(uint8_t i2c_address, uint8_t slave_address, uint8_t *data, uint8_t length)
{
    char *data_array;
    data_array = reinterpret_cast<char*>(data);

    const char temp_address = slave_address;

    m_i2c_sensor.write(i2c_address, &temp_address, 1, true);
    m_i2c_sensor.read(i2c_address, data_array,length, false);
}

/**
 * @brief Reads one register from the specified register-address.
 * 
 * @param slave_address     the desired register-address for reading
 * @return uint8_t          returns read data
 */
uint8_t     TWI_Master::i2c_read(uint8_t i2c_address, uint8_t slave_address)
{
    char data;
    const char temp_address = slave_address;
    m_i2c_sensor.write(i2c_address, &temp_address, 1, true);
    m_i2c_sensor.read(i2c_address, &data, 1, false);
    return data;
}

/**
 * @brief Reads one register from the specified address and masks it with
 * the given mask.
 * 
 * @param slave_address     the desired register-address for reading
 * @param mask              the mask for the desired bits
 * @return uint8_t          returns the masked data
 */
uint8_t     TWI_Master::i2c_readBits(uint8_t i2c_address, uint8_t slave_address, uint8_t mask)
{
    char data;
    const char temp_address = slave_address;
    m_i2c_sensor.write(i2c_address, &temp_address, 1, true);
    m_i2c_sensor.read(i2c_address, &data, 1, false);
    return data & mask;
}