mirror of
https://github.com/SMFSW/cI2C
synced 2024-11-24 02:44:21 +01: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:
parent
a44abc72ec
commit
acfcfec7aa
2
Doxyfile
2
Doxyfile
@ -38,7 +38,7 @@ PROJECT_NAME = "Arduino Hardware I2C for AVR MCUs (plain c)"
|
|||||||
# could be handy for archiving the generated documentation or if some version
|
# could be handy for archiving the generated documentation or if some version
|
||||||
# control system is used.
|
# control system is used.
|
||||||
|
|
||||||
PROJECT_NUMBER = 1.1
|
PROJECT_NUMBER = 1.2
|
||||||
|
|
||||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||||
# for a project that appears at the top of each page and should give viewer a
|
# for a project that appears at the top of each page and should give viewer a
|
||||||
|
@ -15,6 +15,9 @@ Feel free to share your thoughts @ xgarmanboziax@gmail.com about:
|
|||||||
------------
|
------------
|
||||||
|
|
||||||
** Actual:
|
** Actual:
|
||||||
|
v1.2 30 Nov 2017:
|
||||||
|
- No internal address transmission when reading/writing to next internal address (make sure not to r/w last 16 address right just after init, otherwise make a dummy of address 0 just before)
|
||||||
|
|
||||||
v1.1 29 Nov 2017:
|
v1.1 29 Nov 2017:
|
||||||
- Frequency calculation fix (thanks to TonyWilk)
|
- Frequency calculation fix (thanks to TonyWilk)
|
||||||
- Set Frequency higher than Fast Mode (400KHz) will set bus to Fast Mode (frequency is up to 400KHz on AVR)
|
- Set Frequency higher than Fast Mode (400KHz) will set bus to Fast Mode (frequency is up to 400KHz on AVR)
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
This example code is in the public domain.
|
This example code is in the public domain.
|
||||||
|
|
||||||
created Jan 12 2017
|
created Jan 12 2017
|
||||||
latest mod Nov 21 2017
|
latest mod Nov 30 2017
|
||||||
by SMFSW
|
by SMFSW
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -66,12 +66,12 @@ bool I2C_wr_advanced(I2C_SLAVE * slave, const uint16_t reg_addr, uint8_t * data,
|
|||||||
{
|
{
|
||||||
if (bytes == 0) { return false; }
|
if (bytes == 0) { return false; }
|
||||||
|
|
||||||
slave->reg_addr = reg_addr;
|
|
||||||
|
|
||||||
if (I2C_start() == false) { return false; }
|
if (I2C_start() == false) { return false; }
|
||||||
if (I2C_sndAddr(slave, I2C_WRITE) == 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
|
||||||
{
|
{
|
||||||
|
slave->reg_addr = reg_addr;
|
||||||
|
|
||||||
if (slave->cfg.reg_size >= I2C_16B_REG) // if size >2, 16bit address is used
|
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; }
|
if (I2C_wr8((uint8_t) (reg_addr >> 8)) == false) { return false; }
|
||||||
@ -102,10 +102,10 @@ bool I2C_rd_advanced(I2C_SLAVE * slave, const uint16_t reg_addr, uint8_t * data,
|
|||||||
{
|
{
|
||||||
if (bytes == 0) { return false; }
|
if (bytes == 0) { return false; }
|
||||||
|
|
||||||
|
if ((slave->cfg.reg_size) && (reg_addr != slave->reg_addr)) // Don't send address if reading next
|
||||||
|
{
|
||||||
slave->reg_addr = reg_addr;
|
slave->reg_addr = reg_addr;
|
||||||
|
|
||||||
if (slave->cfg.reg_size)
|
|
||||||
{
|
|
||||||
if (I2C_start() == false) { return false; }
|
if (I2C_start() == false) { return false; }
|
||||||
if (I2C_sndAddr(slave, I2C_WRITE) == 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
|
if (slave->cfg.reg_size >= I2C_16B_REG) // if size >2, 16bit address is used
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
name=cI2C
|
name=cI2C
|
||||||
version=1.1
|
version=1.2
|
||||||
author=SMFSW <xgarmanboziax@gmail.com>
|
author=SMFSW <xgarmanboziax@gmail.com>
|
||||||
maintainer=SMFSW <xgarmanboziax@gmail.com>
|
maintainer=SMFSW <xgarmanboziax@gmail.com>
|
||||||
sentence=Arduino Hardware I2C for AVR (in plain c)
|
sentence=Arduino Hardware I2C for AVR (in plain c)
|
||||||
|
20
src/ci2c.c
20
src/ci2c.c
@ -1,18 +1,14 @@
|
|||||||
/*!\file ci2c.c
|
/*!\file ci2c.c
|
||||||
** \author SMFSW
|
** \author SMFSW
|
||||||
** \version 1.1
|
** \version 1.2
|
||||||
** \copyright MIT SMFSW (2017)
|
** \copyright MIT SMFSW (2017)
|
||||||
** \brief arduino master i2c in plain c code
|
** \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: 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: 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"
|
#include "ci2c.h"
|
||||||
|
|
||||||
#define START 0x08
|
#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);
|
(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_wr, I2C_WRITE);
|
||||||
I2C_slave_set_rw_func(slave, (ci2c_fct_ptr) I2C_rd, I2C_READ);
|
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;
|
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; }
|
if (bytes == 0) { return false; }
|
||||||
|
|
||||||
(void) I2C_slave_set_reg_addr(slave, reg_addr);
|
|
||||||
|
|
||||||
if (I2C_start() == false) { return false; }
|
if (I2C_start() == false) { return false; }
|
||||||
if (I2C_sndAddr(slave, I2C_WRITE) == 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 (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; }
|
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; }
|
if (bytes == 0) { return false; }
|
||||||
|
|
||||||
|
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);
|
(void) I2C_slave_set_reg_addr(slave, reg_addr);
|
||||||
|
|
||||||
if (slave->cfg.reg_size) // If start register has to be sent first
|
|
||||||
{
|
|
||||||
if (I2C_start() == false) { return false; }
|
if (I2C_start() == false) { return false; }
|
||||||
if (I2C_sndAddr(slave, I2C_WRITE) == 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
|
if (slave->cfg.reg_size >= I2C_16B_REG) // if size >2, 16bit address is used
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
/*!\file ci2c.h
|
/*!\file ci2c.h
|
||||||
** \author SMFSW
|
** \author SMFSW
|
||||||
** \version 1.1
|
** \version 1.2
|
||||||
** \copyright MIT SMFSW (2017)
|
** \copyright MIT SMFSW (2017)
|
||||||
** \brief arduino i2c in plain c declarations
|
** \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__
|
#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
|
** \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) {
|
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); }
|
return I2C_write(slave, slave->reg_addr, data, bytes); }
|
||||||
|
|
||||||
/*!\brief This function reads data from the address specified and stores this
|
/*!\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
|
** \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) {
|
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); }
|
return I2C_read(slave, slave->reg_addr, data, bytes); }
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user