1
0
Fork 0
mirror of https://github.com/SMFSW/cI2C synced 2025-07-04 20:46:56 +02:00

v1.2: No internal address transmission when reading/writing to next internal address (auto-increment feature of most I2C devices)

This commit is contained in:
SMFSW 2017-11-30 22:40:42 +01:00
parent a44abc72ec
commit acfcfec7aa
6 changed files with 23 additions and 25 deletions

View file

@ -1,18 +1,14 @@
/*!\file ci2c.c
** \author SMFSW
** \version 1.1
** \version 1.2
** \copyright MIT SMFSW (2017)
** \brief arduino master i2c in plain c code
** \warning Don't access (r/w) last 16b internal address byte alone right after init, this would lead to hazardous result (in such case, make a dummy read of addr 0 before)
**/
// TODO: add interrupt vector / callback for it operations (if not too messy)
// TODO: consider interrupts at least for RX when slave (and TX when master)
// TODO: change contigous r/w operations so it doesn't send internal address again
// TODO: split functions & headers
#include "ci2c.h"
#define START 0x08
@ -69,7 +65,7 @@ void I2C_slave_init(I2C_SLAVE * slave, const uint8_t sl_addr, const I2C_INT_SIZE
(void) I2C_slave_set_reg_size(slave, reg_sz);
I2C_slave_set_rw_func(slave, (ci2c_fct_ptr) I2C_wr, I2C_WRITE);
I2C_slave_set_rw_func(slave, (ci2c_fct_ptr) I2C_rd, I2C_READ);
slave->reg_addr = 0;
slave->reg_addr = (uint16_t) -1; // To be sure to send address on first access (warning: unless last 16b byte address is accessed alone)
slave->status = I2C_OK;
}
@ -393,12 +389,12 @@ static bool I2C_wr(I2C_SLAVE * slave, const uint16_t reg_addr, uint8_t * data, c
{
if (bytes == 0) { return false; }
(void) I2C_slave_set_reg_addr(slave, reg_addr);
if (I2C_start() == false) { return false; }
if (I2C_sndAddr(slave, I2C_WRITE) == false) { return false; }
if (slave->cfg.reg_size)
if ((slave->cfg.reg_size) && (reg_addr != slave->reg_addr)) // Don't send address if writing next
{
(void) I2C_slave_set_reg_addr(slave, reg_addr);
if (slave->cfg.reg_size >= I2C_16B_REG) // if size >2, 16bit address is used
{
if (I2C_wr8((uint8_t) (reg_addr >> 8)) == false) { return false; }
@ -429,10 +425,10 @@ static bool I2C_rd(I2C_SLAVE * slave, const uint16_t reg_addr, uint8_t * data, c
{
if (bytes == 0) { return false; }
(void) I2C_slave_set_reg_addr(slave, reg_addr);
if (slave->cfg.reg_size) // If start register has to be sent first
if ((slave->cfg.reg_size) && (reg_addr != slave->reg_addr)) // Don't send address if reading next
{
(void) I2C_slave_set_reg_addr(slave, reg_addr);
if (I2C_start() == false) { return false; }
if (I2C_sndAddr(slave, I2C_WRITE) == false) { return false; }
if (slave->cfg.reg_size >= I2C_16B_REG) // if size >2, 16bit address is used

View file

@ -1,8 +1,9 @@
/*!\file ci2c.h
** \author SMFSW
** \version 1.1
** \version 1.2
** \copyright MIT SMFSW (2017)
** \brief arduino i2c in plain c declarations
** \warning Don't access (r/w) last 16b internal address byte alone right after init, this would lead to hazardous result (in such case, make a dummy read of addr 0 before)
**/
/****************************************************************/
#ifndef __CI2C_H__
@ -212,7 +213,6 @@ I2C_STATUS I2C_write(I2C_SLAVE * slave, const uint16_t reg_addr, uint8_t * data,
** \return I2C_STATUS status of write attempt
**/
inline I2C_STATUS __attribute__((__always_inline__)) I2C_write_next(I2C_SLAVE * slave, uint8_t * data, const uint16_t bytes) {
// TODO: implement read next so that it doesn't have to send start register address again
return I2C_write(slave, slave->reg_addr, data, bytes); }
/*!\brief This function reads data from the address specified and stores this
@ -233,7 +233,6 @@ I2C_STATUS I2C_read(I2C_SLAVE * slave, const uint16_t reg_addr, uint8_t * data,
** \return I2C_STATUS status of read attempt
**/
inline I2C_STATUS __attribute__((__always_inline__)) I2C_read_next(I2C_SLAVE * slave, uint8_t * data, const uint16_t bytes) {
// TODO: implement read next so that it doesn't have to send start register address again
return I2C_read(slave, slave->reg_addr, data, bytes); }