I2C: make API more generic

This commit is contained in:
King Kévin 2018-02-06 11:53:50 +01:00
parent 50bea30599
commit 2522939c66
2 changed files with 272 additions and 150 deletions

View File

@ -15,13 +15,13 @@
/** library to communicate using I2C as master (code)
* @file i2c_master.c
* @author King Kévin <kingkevin@cuvoodoo.info>
* @date 2017
* @date 2017-2018
* @note peripherals used: I2C @ref i2c_master_i2c, timer @ref i2c_master_timer
*/
/* standard libraries */
#include <stdint.h> // standard integer types
#include <stdio.h> // standard I/O facilities
//#include <stdio.h> // standard I/O facilities
#include <stdlib.h> // general utilities
/* STM32 (including CM3) libraries */
@ -30,13 +30,14 @@
#include <libopencm3/stm32/i2c.h> // I2C library
#include <libopencm3/stm32/timer.h> // timer utilities
/* own libraries */
#include "global.h" // global utilities
#include "i2c_master.h" // I2C header and definitions
/** @defgroup i2c_master_i2c I2C peripheral used to communicate
* @{
*/
#define I2C_MASTER_I2C 2 /**< I2C peripheral */
#define I2C_MASTER_I2C 1 /**< I2C peripheral */
/** @} */
/** @defgroup i2c_master_timer timer peripheral used for timeouts
@ -46,7 +47,6 @@
#define I2C_MASTER_TIMEOUT 4 /**< timeout factor (compared to expected time) */
/** @} */
void i2c_master_setup(bool fast)
{
// configure I2C peripheral
@ -94,89 +94,72 @@ void i2c_master_setup(bool fast)
timer_clear_flag(TIM(I2C_MASTER_TIMER), TIM_SR_UIF); // clear flag
}
bool i2c_master_read(uint8_t slave, const uint8_t* address, size_t address_size, uint8_t* data, size_t data_size)
bool i2c_master_start(void)
{
// sanity check
if (address==NULL || address_size==0 || data==NULL || data_size==0) { // input data is erroneous
return false;
}
if (I2C_SR2(I2C(I2C_MASTER_I2C)) & I2C_SR2_BUSY) { // I2C device is busy
return false;
}
if (I2C_SR2(I2C(I2C_MASTER_I2C)) & I2C_SR2_MSL) { // I2C device is already in master mode
return false;
}
bool to_return = false; // return if read succeeded
// send start condition
// send (re-)start condition
i2c_send_start(I2C(I2C_MASTER_I2C)); // send start condition to start transaction
timer_set_counter(TIM(I2C_MASTER_TIMER),0); // restart timer
timer_set_counter(TIM(I2C_MASTER_TIMER), 0); // restart timer
timer_clear_flag(TIM(I2C_MASTER_TIMER), TIM_SR_UIF); // clear flag
timer_enable_counter(TIM(I2C_MASTER_TIMER)); // enable timer for timeouts
while (!(I2C_SR1(I2C(I2C_MASTER_I2C)) & I2C_SR1_SB) && !timer_get_flag(TIM(I2C_MASTER_TIMER), TIM_SR_UIF)); // wait until start condition is transmitted
timer_disable_counter(TIM(I2C_MASTER_TIMER)); // disable timer for timeouts
if (timer_get_flag(TIM(I2C_MASTER_TIMER), TIM_SR_UIF)) { // timeout occurred
timer_clear_flag(TIM(I2C_MASTER_TIMER), TIM_SR_UIF); // clear flag
goto error;
return false;
}
if (!(I2C_SR2(I2C(I2C_MASTER_I2C)) & I2C_SR2_MSL)) { // verify if in master mode
goto error;
return false;
}
return true;
}
bool i2c_master_select_slave(uint8_t slave, bool write)
{
if (!(I2C_SR2(I2C(I2C_MASTER_I2C)) & I2C_SR2_BUSY)) { // I2C device is not busy (start condition has not been sent)
if (!i2c_master_start()) { // send start condition
return false; // could not send start condition
}
}
if (!(I2C_SR2(I2C(I2C_MASTER_I2C)) & I2C_SR2_MSL)) { // I2C device is already not master mode
return false;
}
// select slave
i2c_send_7bit_address(I2C(I2C_MASTER_I2C), slave, I2C_WRITE); // select slave
timer_set_counter(TIM(I2C_MASTER_TIMER),0); // restart timer
i2c_send_7bit_address(I2C(I2C_MASTER_I2C), slave, write ? I2C_WRITE : I2C_READ); // select slave, with read/write flag
timer_set_counter(TIM(I2C_MASTER_TIMER), 0); // restart timer
timer_clear_flag(TIM(I2C_MASTER_TIMER), TIM_SR_UIF); // clear flag
timer_enable_counter(TIM(I2C_MASTER_TIMER)); // enable timer for timeouts
while (!(I2C_SR1(I2C(I2C_MASTER_I2C)) & I2C_SR1_ADDR) && !timer_get_flag(TIM(I2C_MASTER_TIMER), TIM_SR_UIF)); // wait until address is transmitted
timer_disable_counter(TIM(I2C_MASTER_TIMER)); // disable timer for timeouts
if (timer_get_flag(TIM(I2C_MASTER_TIMER), TIM_SR_UIF)) { // timeout occurred
if (timer_get_flag(TIM(I2C_MASTER_TIMER), TIM_SR_UIF)) { // timeout occurred (no ACK received)
timer_clear_flag(TIM(I2C_MASTER_TIMER), TIM_SR_UIF); // clear flag
goto error;
return false;
}
if (!((I2C_SR2(I2C(I2C_MASTER_I2C)) & I2C_SR2_TRA))) { // verify we are in transmit mode (and read SR2 to clear ADDR)
goto error;
}
// send address
for (size_t i=0; i<address_size; i++) {
i2c_send_data(I2C(I2C_MASTER_I2C), address[i]); // send memory address we want to read
timer_set_counter(TIM(I2C_MASTER_TIMER),0); // restart timer
timer_clear_flag(TIM(I2C_MASTER_TIMER), TIM_SR_UIF); // clear flag
timer_enable_counter(TIM(I2C_MASTER_TIMER)); // enable timer for timeouts
while (!(I2C_SR1(I2C(I2C_MASTER_I2C)) & I2C_SR1_TxE) && !timer_get_flag(TIM(I2C_MASTER_TIMER), TIM_SR_UIF)); // wait until byte has been transmitted
timer_disable_counter(TIM(I2C_MASTER_TIMER)); // disable timer for timeouts
if (timer_get_flag(TIM(I2C_MASTER_TIMER), TIM_SR_UIF)) { // timeout occurred
timer_clear_flag(TIM(I2C_MASTER_TIMER), TIM_SR_UIF); // clear flag
goto error;
if (write) {
if (!((I2C_SR2(I2C(I2C_MASTER_I2C)) & I2C_SR2_TRA))) { // verify we are in transmit mode (and read SR2 to clear ADDR)
return false;
}
} else {
if ((I2C_SR2(I2C(I2C_MASTER_I2C)) & I2C_SR2_TRA)) { // verify we are in read mode (and read SR2 to clear ADDR)
return false;
}
}
// switch to read mode
i2c_send_start(I2C(I2C_MASTER_I2C)); // send restart condition to switch from write to read mode
timer_set_counter(TIM(I2C_MASTER_TIMER),0); // restart timer
timer_clear_flag(TIM(I2C_MASTER_TIMER), TIM_SR_UIF); // clear flag
timer_enable_counter(TIM(I2C_MASTER_TIMER)); // enable timer for timeouts
while (!(I2C_SR1(I2C(I2C_MASTER_I2C)) & I2C_SR1_SB) && !timer_get_flag(TIM(I2C_MASTER_TIMER), TIM_SR_UIF)); // wait until start condition is transmitted
timer_disable_counter(TIM(I2C_MASTER_TIMER)); // disable timer for timeouts
if (timer_get_flag(TIM(I2C_MASTER_TIMER), TIM_SR_UIF)) { // timeout occurred
timer_clear_flag(TIM(I2C_MASTER_TIMER), TIM_SR_UIF); // clear flag
goto error;
}
return true;
}
i2c_send_7bit_address(I2C(I2C_MASTER_I2C), slave, I2C_READ); // select slave
timer_set_counter(TIM(I2C_MASTER_TIMER),0); // restart timer
timer_clear_flag(TIM(I2C_MASTER_TIMER), TIM_SR_UIF); // clear flag
timer_enable_counter(TIM(I2C_MASTER_TIMER)); // enable timer for timeouts
while (!(I2C_SR1(I2C(I2C_MASTER_I2C)) & I2C_SR1_ADDR) && !timer_get_flag(TIM(I2C_MASTER_TIMER), TIM_SR_UIF)); // wait until address is transmitted
timer_disable_counter(TIM(I2C_MASTER_TIMER)); // disable timer for timeouts
if (timer_get_flag(TIM(I2C_MASTER_TIMER), TIM_SR_UIF)) { // timeout occurred
timer_clear_flag(TIM(I2C_MASTER_TIMER), TIM_SR_UIF); // clear flag
goto error;
}
if ((I2C_SR2(I2C(I2C_MASTER_I2C)) & I2C_SR2_TRA)) { // verify we are in read mode (and read SR2 to clear ADDR)
goto error;
bool i2c_master_read(uint8_t* data, size_t data_size)
{
// sanity check
if (data==NULL || data_size==0) { // no data to read
return true;
}
if (!(I2C_SR2(I2C(I2C_MASTER_I2C)) & I2C_SR2_BUSY)) { // I2C device is not busy (start condition has not been sent)
return false; // address has probably also not been sent
}
if (!(I2C_SR2(I2C(I2C_MASTER_I2C)) & I2C_SR2_MSL)) { // I2C device not master mode
return false;
}
// read data
@ -187,96 +170,34 @@ bool i2c_master_read(uint8_t slave, const uint8_t* address, size_t address_size,
} else {
i2c_enable_ack(I2C(I2C_MASTER_I2C)); // ACK received byte to continue slave transmission
}
timer_set_counter(TIM(I2C_MASTER_TIMER),0); // restart timer
timer_set_counter(TIM(I2C_MASTER_TIMER), 0); // restart timer
timer_clear_flag(TIM(I2C_MASTER_TIMER), TIM_SR_UIF); // clear flag
timer_enable_counter(TIM(I2C_MASTER_TIMER)); // enable timer for timeouts
while (!(I2C_SR1(I2C(I2C_MASTER_I2C)) & I2C_SR1_RxNE) && !timer_get_flag(TIM(I2C_MASTER_TIMER), TIM_SR_UIF)); // wait until byte has been received
timer_disable_counter(TIM(I2C_MASTER_TIMER)); // disable timer for timeouts
if (timer_get_flag(TIM(I2C_MASTER_TIMER), TIM_SR_UIF)) { // timeout occurred
timer_clear_flag(TIM(I2C_MASTER_TIMER), TIM_SR_UIF); // clear flag
goto error;
return false;
}
data[i] = i2c_get_data(I2C(I2C_MASTER_I2C)); // read received byte
}
to_return = true;
error:
if (I2C_SR2(I2C(I2C_MASTER_I2C)) & I2C_SR2_BUSY) { // release bus if busy
// i2c_send_stop(I2C(I2C_MASTER_I2C)); // send stop to release bus
}
i2c_send_stop(I2C(I2C_MASTER_I2C)); // send stop to release bus
timer_set_counter(TIM(I2C_MASTER_TIMER),0); // restart timer
timer_clear_flag(TIM(I2C_MASTER_TIMER), TIM_SR_UIF); // clear flag
timer_enable_counter(TIM(I2C_MASTER_TIMER)); // enable timer for timeouts
while ((I2C_SR2(I2C(I2C_MASTER_I2C)) & I2C_SR2_MSL) && !timer_get_flag(TIM(I2C_MASTER_TIMER), TIM_SR_UIF)); // wait until bus released (non master mode)
timer_disable_counter(TIM(I2C_MASTER_TIMER)); // disable timer for timeouts
if (timer_get_flag(TIM(I2C_MASTER_TIMER), TIM_SR_UIF)) { // timeout occurred
timer_clear_flag(TIM(I2C_MASTER_TIMER), TIM_SR_UIF); // clear flag
}
return to_return;
return true;
}
bool i2c_master_write(uint8_t slave, const uint8_t* address, size_t address_size, const uint8_t* data, size_t data_size)
bool i2c_master_write(const uint8_t* data, size_t data_size)
{
// sanity check
if (address==NULL || address_size==0 || data==NULL || data_size==0) { // input data is erroneous
return false;
if (data==NULL || data_size==0) { // no data to write
return true;
}
if (I2C_SR2(I2C(I2C_MASTER_I2C)) & I2C_SR2_BUSY) { // I2C device is busy
return false;
if (!(I2C_SR2(I2C(I2C_MASTER_I2C)) & I2C_SR2_BUSY)) { // I2C device is not busy (start condition has not been sent)
return false; // address has probably also not been sent
}
if (I2C_SR2(I2C(I2C_MASTER_I2C)) & I2C_SR2_MSL) { // I2C device is already in master mode
if (!(I2C_SR2(I2C(I2C_MASTER_I2C)) & I2C_SR2_MSL)) { // I2C device is not master mode
return false;
}
bool to_return = false; // return if read succeeded
// send start condition
i2c_send_start(I2C(I2C_MASTER_I2C)); // send start condition to start transaction
timer_set_counter(TIM(I2C_MASTER_TIMER),0); // restart timer
timer_clear_flag(TIM(I2C_MASTER_TIMER), TIM_SR_UIF); // clear flag
timer_enable_counter(TIM(I2C_MASTER_TIMER)); // enable timer for timeouts
while (!(I2C_SR1(I2C(I2C_MASTER_I2C)) & I2C_SR1_SB) && !timer_get_flag(TIM(I2C_MASTER_TIMER), TIM_SR_UIF)); // wait until start condition is transmitted
timer_disable_counter(TIM(I2C_MASTER_TIMER)); // disable timer for timeouts
if (timer_get_flag(TIM(I2C_MASTER_TIMER), TIM_SR_UIF)) { // timeout occurred
timer_clear_flag(TIM(I2C_MASTER_TIMER), TIM_SR_UIF); // clear flag
goto error;
}
if (!(I2C_SR2(I2C(I2C_MASTER_I2C)) & I2C_SR2_MSL)) { // verify if in master mode
goto error;
}
// select slave
i2c_send_7bit_address(I2C(I2C_MASTER_I2C), slave, I2C_WRITE); // select slave
timer_set_counter(TIM(I2C_MASTER_TIMER),0); // restart timer
timer_clear_flag(TIM(I2C_MASTER_TIMER), TIM_SR_UIF); // clear flag
timer_enable_counter(TIM(I2C_MASTER_TIMER)); // enable timer for timeouts
while (!(I2C_SR1(I2C(I2C_MASTER_I2C)) & I2C_SR1_ADDR) && !timer_get_flag(TIM(I2C_MASTER_TIMER), TIM_SR_UIF)); // wait until address is transmitted
timer_disable_counter(TIM(I2C_MASTER_TIMER)); // disable timer for timeouts
if (timer_get_flag(TIM(I2C_MASTER_TIMER), TIM_SR_UIF)) { // timeout occurred
timer_clear_flag(TIM(I2C_MASTER_TIMER), TIM_SR_UIF); // clear flag
goto error;
}
if (!((I2C_SR2(I2C(I2C_MASTER_I2C)) & I2C_SR2_TRA))) { // verify we are in transmit mode (and read SR2 to clear ADDR)
goto error;
}
// send address
for (size_t i=0; i<address_size; i++) {
i2c_send_data(I2C(I2C_MASTER_I2C), address[i]); // send memory address we want to read
timer_set_counter(TIM(I2C_MASTER_TIMER),0); // restart timer
timer_clear_flag(TIM(I2C_MASTER_TIMER), TIM_SR_UIF); // clear flag
timer_enable_counter(TIM(I2C_MASTER_TIMER)); // enable timer for timeouts
while (!(I2C_SR1(I2C(I2C_MASTER_I2C)) & I2C_SR1_TxE) && !timer_get_flag(TIM(I2C_MASTER_TIMER), TIM_SR_UIF)); // wait until byte has been transmitted
timer_disable_counter(TIM(I2C_MASTER_TIMER)); // disable timer for timeouts
if (timer_get_flag(TIM(I2C_MASTER_TIMER), TIM_SR_UIF)) { // timeout occurred
timer_clear_flag(TIM(I2C_MASTER_TIMER), TIM_SR_UIF); // clear flag
goto error;
}
}
// write data
for (size_t i=0; i<data_size; i++) { // write bytes
i2c_send_data(I2C(I2C_MASTER_I2C), data[i]); // send byte to be written in memory
@ -285,24 +206,186 @@ bool i2c_master_write(uint8_t slave, const uint8_t* address, size_t address_size
timer_enable_counter(TIM(I2C_MASTER_TIMER)); // enable timer for timeouts
while (!(I2C_SR1(I2C(I2C_MASTER_I2C)) & I2C_SR1_TxE) && !timer_get_flag(TIM(I2C_MASTER_TIMER), TIM_SR_UIF)); // wait until byte has been transmitted
timer_disable_counter(TIM(I2C_MASTER_TIMER)); // disable timer for timeouts
if (timer_get_flag(TIM(I2C_MASTER_TIMER), TIM_SR_UIF)) { // timeout occurred
if (timer_get_flag(TIM(I2C_MASTER_TIMER), TIM_SR_UIF)) { // timeout occurred (no ACK received)
timer_clear_flag(TIM(I2C_MASTER_TIMER), TIM_SR_UIF); // clear flag
goto error;
return false;
}
}
to_return = true;
error:
if (I2C_SR2(I2C(I2C_MASTER_I2C)) & I2C_SR2_BUSY) { // release bus if busy
i2c_send_stop(I2C(I2C_MASTER_I2C)); // send stop to release bus
return true;
}
void i2c_master_stop(void)
{
// sanity check
if (!(I2C_SR2(I2C(I2C_MASTER_I2C)) & I2C_SR2_BUSY)) { // release is not busy
return; // bus has probably already been released
}
timer_set_counter(TIM(I2C_MASTER_TIMER),0); // restart timer
// send stop condition
i2c_send_stop(I2C(I2C_MASTER_I2C)); // send stop to release bus
timer_set_counter(TIM(I2C_MASTER_TIMER), 0); // restart timer
timer_clear_flag(TIM(I2C_MASTER_TIMER), TIM_SR_UIF); // clear flag
timer_enable_counter(TIM(I2C_MASTER_TIMER)); // enable timer for timeouts
while ((I2C_SR2(I2C(I2C_MASTER_I2C)) & I2C_SR2_MSL) && !timer_get_flag(TIM(I2C_MASTER_TIMER), TIM_SR_UIF)); // wait until bus released (non master mode)
while ((I2C_SR2(I2C(I2C_MASTER_I2C)) & I2C_SR2_MSL) && !timer_get_flag(TIM(I2C_MASTER_TIMER), TIM_SR_UIF)); // wait until bus released (non master mode)
timer_disable_counter(TIM(I2C_MASTER_TIMER)); // disable timer for timeouts
if (timer_get_flag(TIM(I2C_MASTER_TIMER), TIM_SR_UIF)) { // timeout occurred
timer_clear_flag(TIM(I2C_MASTER_TIMER), TIM_SR_UIF); // clear flag
}
return to_return;
}
bool i2c_master_slave_read(uint8_t slave, uint8_t* data, size_t data_size)
{
// sanity check
if (I2C_SR2(I2C(I2C_MASTER_I2C)) & I2C_SR2_BUSY) { // I2C device is busy
return false;
}
if (I2C_SR2(I2C(I2C_MASTER_I2C)) & I2C_SR2_MSL) { // I2C device is already in master mode
return false;
}
bool success = false; // return if read succeeded
// send start condition
if (!i2c_master_start()) {
goto error;
}
// select slave to write
if (!i2c_master_select_slave(slave, true)) {
goto error;
}
// read data
if (NULL!=data && data_size>0) {
// read data
if (!i2c_master_read(data, data_size)) {
goto error;
}
}
success = true;
error:
i2c_master_stop(); // sent stop condition
return success;
}
bool i2c_master_slave_write(uint8_t slave, const uint8_t* data, size_t data_size)
{
// sanity check
if (I2C_SR2(I2C(I2C_MASTER_I2C)) & I2C_SR2_BUSY) { // I2C device is busy
return false;
}
if (I2C_SR2(I2C(I2C_MASTER_I2C)) & I2C_SR2_MSL) { // I2C device is already in master mode
return false;
}
bool success = false; // return if read succeeded
// send start condition
if (!i2c_master_start()) {
goto error;
}
// select slave to write
if (!i2c_master_select_slave(slave, true)) {
goto error;
}
// write data
if (NULL!=data && data_size>0) {
if (!i2c_master_write(data, data_size)) {
goto error;
}
}
success = true;
error:
i2c_master_stop(); // sent stop condition
return success;
}
bool i2c_master_address_read(uint8_t slave, const uint8_t* address, size_t address_size, uint8_t* data, size_t data_size)
{
// sanity check
if (I2C_SR2(I2C(I2C_MASTER_I2C)) & I2C_SR2_BUSY) { // I2C device is busy
return false;
}
if (I2C_SR2(I2C(I2C_MASTER_I2C)) & I2C_SR2_MSL) { // I2C device is already in master mode
return false;
}
bool success = false; // return if read succeeded
// write address
if (NULL!=address && address_size>0) {
// send start condition
if (!i2c_master_start()) {
goto error;
}
// select slave to write
if (!i2c_master_select_slave(slave, true)) {
goto error;
}
// send address
if (!i2c_master_write(address, address_size)) {
goto error;
}
}
// read data
if (NULL!=data && data_size>0) {
// send re-start condition
if (!i2c_master_start()) {
goto error;
}
// select slave to read
if (!i2c_master_select_slave(slave, false)) {
goto error;
}
// read data
if (!i2c_master_read(data, data_size)) {
goto error;
}
}
success = true;
error:
i2c_master_stop(); // sent stop condition
return success;
}
bool i2c_master_address_write(uint8_t slave, const uint8_t* address, size_t address_size, const uint8_t* data, size_t data_size)
{
// sanity check
if (I2C_SR2(I2C(I2C_MASTER_I2C)) & I2C_SR2_BUSY) { // I2C device is busy
return false;
}
if (I2C_SR2(I2C(I2C_MASTER_I2C)) & I2C_SR2_MSL) { // I2C device is already in master mode
return false;
}
bool success = false; // return if read succeeded
// send start condition
if (!i2c_master_start()) {
goto error;
}
// select slave to write
if (!i2c_master_select_slave(slave, true)) {
goto error;
}
// write address
if (NULL!=address && address_size>0) {
// send address
if (!i2c_master_write(address, address_size)) {
goto error;
}
}
// write data
if (NULL!=data && data_size>0) {
if (!i2c_master_write(data, data_size)) {
goto error;
}
}
success = true;
error:
i2c_master_stop(); // sent stop condition
return success;
}

View File

@ -15,8 +15,9 @@
/** library to communicate using I2C as master (API)
* @file i2c_master.h
* @author King Kévin <kingkevin@cuvoodoo.info>
* @date 2017
* @date 2017-2018
* @note peripherals used: I2C @ref i2c_master_i2c, timer @ref i2c_master_timer
* @warning only 7-byte I2C slave addresses are supported
*/
#pragma once
@ -24,7 +25,46 @@
* @param[in] fast use standard (100 kHz) or fast (400 kHz) mode
*/
void i2c_master_setup(bool fast);
/** read from I2C slave
/** send start condition
* @return if start condition was sent successfully (true) or error occurred (false)
*/
bool i2c_master_start(void);
/** select slave device
* @warning a start condition should be sent before this operation
* @param[in] slave 7-bit I2C address of slave device to select
* @param[in] write this transaction will be followed by a read (false) or write (true) operation
* @return if slave was selected successfully (true) or error occurred (false)
*/
bool i2c_master_select_slave(uint8_t slave, bool write);
/** read data
* @warning the slave device must be selected before this operation
* @param[out] data array to store bytes read
* @param[in] data_size number of bytes to read
*/
bool i2c_master_read(uint8_t* data, size_t data_size);
/** write data
* @warning the slave device must be selected before this operation
* @param[in] data array of byte to write to slave
* @param[in] data_size number of bytes to write
*/
bool i2c_master_write(const uint8_t* data, size_t data_size);
/** sent stop condition */
void i2c_master_stop(void);
/** read from date from an I2C slave
* @param[in] slave 7-bit I2C salve device address to read from
* @param[out] data array to store bytes read
* @param[in] data_size number of bytes to read
* @return if read succeeded
*/
bool i2c_master_slave_read(uint8_t slave, uint8_t* data, size_t data_size);
/** write data to an I2C slave
* @param[in] slave 7-bit I2C salve device address to write to
* @param[in] data array of byte to write to slave
* @param[in] data_size number of bytes to write
* @return if write succeeded
*/
bool i2c_master_slave_write(uint8_t slave, const uint8_t* data, size_t data_size);
/** read data at specific address from an I2C memory slave
* @param[in] slave 7-bit I2C salve device address to read from
* @param[in] address memory address of slave to read from
* @param[in] address_size address size in bytes
@ -32,8 +72,8 @@ void i2c_master_setup(bool fast);
* @param[in] data_size number of bytes to read
* @return if read succeeded
*/
bool i2c_master_read(uint8_t slave, const uint8_t* address, size_t address_size, uint8_t* data, size_t data_size);
/** write to I2C slave
bool i2c_master_address_read(uint8_t slave, const uint8_t* address, size_t address_size, uint8_t* data, size_t data_size);
/** write data at specific address on an I2C memory slave
* @param[in] slave 7-bit I2C salve device address to write to
* @param[in] address memory address of slave to write to
* @param[in] address_size address size in bytes
@ -41,5 +81,4 @@ bool i2c_master_read(uint8_t slave, const uint8_t* address, size_t address_size,
* @param[in] data_size number of bytes to write
* @return if write succeeded
*/
bool i2c_master_write(uint8_t slave, const uint8_t* address, size_t address_size, const uint8_t* data, size_t data_size);
bool i2c_master_address_write(uint8_t slave, const uint8_t* address, size_t address_size, const uint8_t* data, size_t data_size);