mirror of
https://github.com/SMFSW/cI2C
synced 2024-09-22 07:21:42 +02:00
Compare commits
23 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
d31cca271e | ||
|
e94f51f762 | ||
|
dbe9dc0a61 | ||
|
e6d3d2a8ae | ||
|
b9babcdde0 | ||
|
b079e7997d | ||
|
3277748c49 | ||
|
de152ccc5f | ||
|
fa20634862 | ||
|
4ce72eeb34 | ||
|
669f2c787b | ||
|
7122bfd2de | ||
|
66ceef30b4 | ||
|
7a2af3d743 | ||
|
668e2ebcf5 | ||
|
93e2ffcccc | ||
|
dc8c19cb7a | ||
|
ee3b56f52e | ||
|
a3ed48b1f1 | ||
|
0e091c3f95 | ||
|
4fcef282b6 | ||
|
63be41402d | ||
|
acfcfec7aa |
4
.gitignore
vendored
Normal file → Executable file
4
.gitignore
vendored
Normal file → Executable file
@ -27,3 +27,7 @@
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
|
||||
#Doxygen
|
||||
doxygen_sqlite3.db
|
||||
html
|
29
.travis.yml
Executable file
29
.travis.yml
Executable file
@ -0,0 +1,29 @@
|
||||
language: c
|
||||
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- graphviz
|
||||
|
||||
# Blacklist
|
||||
branches:
|
||||
except:
|
||||
- gh-pages
|
||||
|
||||
env:
|
||||
global:
|
||||
- PRETTYNAME="cI2C: Arduino Hardware I2C for AVR (in plain c)"
|
||||
- GH_REPO_NAME: cI2C
|
||||
- GH_REPO_REF: github.com/SMFSW/cI2C.git
|
||||
- DOXYFILE: $TRAVIS_BUILD_DIR/Doxyfile.auto
|
||||
|
||||
before_install:
|
||||
- source <(curl -SLs https://raw.githubusercontent.com/SMFSW/travis-ci-arduino/master/install.sh)
|
||||
|
||||
script:
|
||||
- build_avr_platforms
|
||||
|
||||
# Generate and deploy documentation
|
||||
after_success:
|
||||
- source <(curl -SLs https://raw.githubusercontent.com/SMFSW/travis-ci-arduino/master/library_check.sh)
|
||||
- source <(curl -SLs https://raw.githubusercontent.com/SMFSW/travis-ci-arduino/master/doxy_gen_and_deploy.sh)
|
12
Doxyfile
12
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
|
||||
# control system is used.
|
||||
|
||||
PROJECT_NUMBER = 1.1
|
||||
PROJECT_NUMBER = 1.3
|
||||
|
||||
# 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
|
||||
@ -244,7 +244,7 @@ TCL_SUBST =
|
||||
# members will be omitted, etc.
|
||||
# The default value is: NO.
|
||||
|
||||
OPTIMIZE_OUTPUT_FOR_C = NO
|
||||
OPTIMIZE_OUTPUT_FOR_C = YES
|
||||
|
||||
# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or
|
||||
# Python sources only. Doxygen will then generate output that is more tailored
|
||||
@ -748,7 +748,7 @@ WARN_IF_DOC_ERROR = YES
|
||||
# parameter documentation, but not about the absence of documentation.
|
||||
# The default value is: NO.
|
||||
|
||||
WARN_NO_PARAMDOC = NO
|
||||
WARN_NO_PARAMDOC = YES
|
||||
|
||||
# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when
|
||||
# a warning is encountered.
|
||||
@ -770,7 +770,7 @@ WARN_FORMAT = "$file:$line: $text"
|
||||
# messages should be written. If left blank the output is written to standard
|
||||
# error (stderr).
|
||||
|
||||
WARN_LOGFILE =
|
||||
WARN_LOGFILE = workdir/doxy.log
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the input files
|
||||
@ -935,7 +935,7 @@ FILTER_SOURCE_PATTERNS =
|
||||
# (index.html). This can be useful if you have a project on for instance GitHub
|
||||
# and want to reuse the introduction page also for the doxygen output.
|
||||
|
||||
USE_MDFILE_AS_MAINPAGE =
|
||||
USE_MDFILE_AS_MAINPAGE = README.md
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to source browsing
|
||||
@ -1729,7 +1729,7 @@ LATEX_EXTRA_FILES =
|
||||
# The default value is: YES.
|
||||
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||
|
||||
PDF_HYPERLINKS = NO
|
||||
PDF_HYPERLINKS = YES
|
||||
|
||||
# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate
|
||||
# the PDF file directly from the LaTeX files. Set this option to YES, to get a
|
||||
|
2446
Doxyfile.auto
Executable file
2446
Doxyfile.auto
Executable file
File diff suppressed because it is too large
Load Diff
95
README.md
95
README.md
@ -1,10 +1,12 @@
|
||||
# cI2C
|
||||
# cI2C [![Build Status](https://travis-ci.com/SMFSW/cI2C.svg?branch=master)](https://travis-ci.com/SMFSW/cI2C)
|
||||
|
||||
Arduino Hardware I2C for AVR (plain c)
|
||||
|
||||
Hardware I2C library for AVR MCUs (lib intended for I2C protocols development in c, for easier ports to other MCUs)
|
||||
|
||||
## Library choice:
|
||||
* cI2C library implements I2C bus for AVR tagets (Uno, Nano, Mega...)
|
||||
## Library choice
|
||||
|
||||
* cI2C library implements I2C bus for AVR targets (Uno, Nano, Mega...)
|
||||
* you may prefer this one when:
|
||||
* working on AVR targets
|
||||
* interrupts are not needed
|
||||
@ -16,64 +18,69 @@ Hardware I2C library for AVR MCUs (lib intended for I2C protocols development in
|
||||
No refactoring is required when switching between **cI2C** & **WireWrapper** libs;
|
||||
Both libs share same Typedefs, Functions & Parameters.
|
||||
|
||||
## Notes:
|
||||
## Notes
|
||||
|
||||
* cI2C is written in plain c (intentionally)
|
||||
* cI2C does not use any interrupt (yet, but soon will have to)
|
||||
* cI2C is designed to act as bus Master (Slave mode will be considered in future releases)
|
||||
* cI2C is set to work on AVR targets only
|
||||
* for other targets, you may use **WireWrapper** instead (will be using Wire)
|
||||
|
||||
## Usage:
|
||||
## Usage
|
||||
|
||||
This library is intended to be able to work with multiple slaves connected on the same I2C bus.
|
||||
Thus, the I2C bus and Slaves are defined separately.
|
||||
|
||||
* On one hand, I2C bus has to be initialised with appropriate speed:
|
||||
* use I2C_init(speed): speed can be choosen from I2C_SPEED enum for convenience, or passing an integer as parameter
|
||||
* On the other hand, Slave(s) have to be defined and initialised too:
|
||||
* use I2C_SLAVE typedef to declare slaves structs
|
||||
* use I2C_slave_init(pSlave, addr, regsize)
|
||||
* **pSlave** is a pointer to the slave struct to initialise
|
||||
* **addr** is the slave I2C address (don't shift addr, lib takes care of that)
|
||||
* **regsize** is the width of internal slave registers (to be choosen from I2C_INT_SIZE)
|
||||
* On one hand, I2C bus has to be initialized with appropriate speed:
|
||||
* use `I2C_init(speed)`: speed can be chosen from `I2C_SPEED` enum for convenience, or passing an integer as parameter
|
||||
* On the other hand, Slave(s) have to be defined and initialized too:
|
||||
* use `I2C_SLAVE` typedef to declare slaves structs
|
||||
* use `I2C_slave_init(pSlave, addr, regsize)`
|
||||
* `pSlave`: pointer to the slave struct to initialize
|
||||
* `addr`: slave I2C address (don't shift addr, lib takes care of that)
|
||||
* `regsize`: width of internal slave registers (to be chosen from `I2C_INT_SIZE`)
|
||||
* in case you need to use custom R/W procedures for a particular slave:
|
||||
* use I2C_slave_set_rw_func(pSlave, pFunc, rw)
|
||||
* **pSlave** is a pointer to the slave declaration to initialise
|
||||
* **pFunc** is a pointer to the Read or Write bypass function
|
||||
* **rw** can be choosen from I2C_RW enum (wr=0, rd=1)
|
||||
* use `I2C_slave_set_rw_func(pSlave, pFunc, rw)`
|
||||
* `pSlave`: pointer to the slave declaration to initialize
|
||||
* `pFunc`: pointer to the Read or Write bypass function
|
||||
* `rw`: can be chosen from `I2C_RW` enum (wr=0, rd=1)
|
||||
|
||||
After all inits are done, the lib can basically be used this way:
|
||||
* I2C_read(pSlave, regaddr, pData, bytes)
|
||||
* **pSlave** is a pointer to the slave struct to read from
|
||||
* **regaddr** is the start address to read from
|
||||
* **pData** is a pointer to the place where datas read will be stored
|
||||
* **bytes** number of bytes to read from slave
|
||||
* returns true if read is ok, false otherwise
|
||||
* I2C_write(pSlave, regaddr, pData, bytes)
|
||||
* **pSlave** is a pointer to the slave struct to write to
|
||||
* **regaddr** is the start address to write to
|
||||
* **pData** is a pointer to the block of datas to write to slave
|
||||
* **bytes** number of bytes to write to slave
|
||||
* returns true if write is ok, false otherwise
|
||||
* `I2C_read(pSlave, regaddr, pData, bytes)`
|
||||
* `pSlave`: pointer to the slave struct to read from
|
||||
* `regaddr`: start address to read from
|
||||
* `pData`: pointer to the place where datas read will be stored
|
||||
* `bytes`: number of bytes to read from slave
|
||||
* returns `true` if read is ok, `false` otherwise
|
||||
* `I2C_write(pSlave, regaddr, pData, bytes)`
|
||||
* `pSlave`: pointer to the slave struct to write to
|
||||
* `regaddr`: start address to write to
|
||||
* `pData`: pointer to the block of datas to write to slave
|
||||
* `bytes`: number of bytes to write to slave
|
||||
* returns `true` if write is ok, `false` otherwise
|
||||
|
||||
## Examples included
|
||||
|
||||
## Examples included:
|
||||
following examples should work with any I2C EEPROM/FRAM with address 0x50
|
||||
(yet function to get Chip ID are device dependant (and will probably only work on FUJITSU devices))
|
||||
* ci2c_master_write.ino: Write some bytes to FRAM and compare them with what's read afterwards
|
||||
* ci2c_master_read.ino: Read some bytes in FRAM
|
||||
* ci2c_advanced.ino: Redirecting slave write & read functions (to custom functions following typedef)
|
||||
(yet function to get Chip ID are device dependent (and will probably only work on FUJITSU devices))
|
||||
* [ci2c_master_write.ino](examples/ci2c_master_write/ci2c_master_write.ino): Write some bytes to FRAM and compare them with what's read afterwards
|
||||
* [ci2c_master_read.ino](examples/ci2c_master_read/ci2c_master_read.ino): Read some bytes in FRAM
|
||||
* [ci2c_advanced.ino](examples/ci2c_advanced/ci2c_advanced.ino): Redirecting slave write & read functions (to custom functions following typedef)
|
||||
|
||||
Doxygen doc can be generated for the library using doxyfile
|
||||
## Documentation
|
||||
|
||||
## Links:
|
||||
Feel free to share your thoughts @ xgarmanboziax@gmail.com about:
|
||||
* issues encountered
|
||||
* optimisations
|
||||
* improvements & new functionalities
|
||||
Doxygen doc can be generated using "Doxyfile".
|
||||
|
||||
See [generated documentation](https://smfsw.github.io/cI2C/)
|
||||
|
||||
## Release Notes
|
||||
|
||||
See [release notes](ReleaseNotes.md)
|
||||
|
||||
## See also
|
||||
|
||||
**cI2C**
|
||||
- https://github.com/SMFSW/cI2C
|
||||
- https://bitbucket.org/SMFSW/ci2c
|
||||
* [cI2C github](https://github.com/SMFSW/cI2C) - C implementation of this library
|
||||
|
||||
**WireWrapper**
|
||||
- https://github.com/SMFSW/WireWrapper
|
||||
- https://bitbucket.org/SMFSW/wirewrapper
|
||||
* [WireWrapper github](https://github.com/SMFSW/WireWrapper) - Cpp implementation using Wire Wrapper
|
||||
|
@ -1,20 +1,28 @@
|
||||
Arduino Hardware I2C for AVR (plain c)
|
||||
2017-2017 SMFSW
|
||||
2017-2018 SMFSW
|
||||
|
||||
- cI2C is set to work on AVR targets only
|
||||
-> for other targets, you may use WireWrapper instead (will be using Wire)
|
||||
-> cI2C & WireWrapper libs declare same structures & functions as seen from the outside
|
||||
(switch between libs without changing anyhting but the include)
|
||||
(switch between libs without changing anything but the include)
|
||||
|
||||
|
||||
Feel free to share your thoughts @ xgarmanboziax@gmail.com about:
|
||||
- issues encountered
|
||||
- optimisations
|
||||
- optimizations
|
||||
- improvements & new functionalities
|
||||
|
||||
------------
|
||||
|
||||
** Actual:
|
||||
v1.3 13 May 2018:
|
||||
- Delay between retries is now 1ms
|
||||
- Adding support for unit tests and doxygen documentation generation with Travis CI
|
||||
- Updated README.md
|
||||
|
||||
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:
|
||||
- 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)
|
@ -7,7 +7,7 @@
|
||||
This example code is in the public domain.
|
||||
|
||||
created Jan 12 2017
|
||||
latest mod Nov 21 2017
|
||||
latest mod Nov 30 2017
|
||||
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; }
|
||||
|
||||
slave->reg_addr = 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
|
||||
{
|
||||
slave->reg_addr = 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; }
|
||||
@ -102,10 +102,10 @@ bool I2C_rd_advanced(I2C_SLAVE * slave, const uint16_t reg_addr, uint8_t * data,
|
||||
{
|
||||
if (bytes == 0) { return false; }
|
||||
|
||||
slave->reg_addr = reg_addr;
|
||||
|
||||
if (slave->cfg.reg_size)
|
||||
if ((slave->cfg.reg_size) && (reg_addr != slave->reg_addr)) // Don't send address if reading next
|
||||
{
|
||||
slave->reg_addr = 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
|
||||
|
@ -1,5 +1,5 @@
|
||||
name=cI2C
|
||||
version=1.1
|
||||
version=1.3
|
||||
author=SMFSW <xgarmanboziax@gmail.com>
|
||||
maintainer=SMFSW <xgarmanboziax@gmail.com>
|
||||
sentence=Arduino Hardware I2C for AVR (in plain c)
|
||||
|
25
src/ci2c.c
25
src/ci2c.c
@ -1,18 +1,13 @@
|
||||
/*!\file ci2c.c
|
||||
** \author SMFSW
|
||||
** \version 1.1
|
||||
** \copyright MIT SMFSW (2017)
|
||||
** \copyright MIT SMFSW (2017-2018)
|
||||
** \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 +64,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;
|
||||
}
|
||||
|
||||
@ -237,7 +232,7 @@ static I2C_STATUS I2C_comm(I2C_SLAVE * slave, const uint16_t reg_addr, uint8_t *
|
||||
ack = fc(slave, reg_addr, data, bytes);
|
||||
while ((!ack) && (retry != 0)) // If com not successful, retry some more times
|
||||
{
|
||||
delay(5);
|
||||
delay(1);
|
||||
ack = fc(slave, reg_addr, data, bytes);
|
||||
retry--;
|
||||
}
|
||||
@ -393,12 +388,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 +424,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
|
||||
|
@ -1,8 +1,8 @@
|
||||
/*!\file ci2c.h
|
||||
** \author SMFSW
|
||||
** \version 1.1
|
||||
** \copyright MIT SMFSW (2017)
|
||||
** \copyright MIT SMFSW (2017-2018)
|
||||
** \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 +212,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 +232,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); }
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user