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

Compare commits

...

28 commits
v1.1 ... master

Author SHA1 Message Date
SMFSW
6ab8c5bb62 Custom badges
GIST added in README.md
Create build-badges.yml
2025-05-06 23:55:34 +02:00
SMFSW
07a99be69e CodeFactor badge 2025-05-03 00:53:01 +02:00
SMFSW
8c01ec61e6 Create bitbucket-push.yml
Setting up mirroring to bitbucket repository
2025-05-01 23:33:00 +02:00
SMFSW
bd32fc10a7 - .github gh-pages workflow added (generate doxygen doc & push)
- Removal of unneeded .travis.yml & references (not used anymore)
2025-04-30 23:25:34 +02:00
SMFSW
3176bde372
Create jekyll-gh-pages.yml
Setting up jekyll env to generate documentation with doxygen and push to gh-pages
2025-04-30 23:25:06 +02:00
SMFSW
d31cca271e Updated to travis-ci.com status 2018-12-12 20:54:31 +01:00
SMFSW
e94f51f762 Removed deprecated sudo from .travis.yml 2018-12-11 19:53:01 +01:00
SMFSW
dbe9dc0a61 typo in ReleaseNotes.md 2018-06-17 18:23:58 +02:00
SMFSW
e6d3d2a8ae v1.3: Delay between retries set to 1ms 2018-05-27 15:57:06 +02:00
SMFSW
b9babcdde0 Added dedicated Doxyfile for Travis CI and updated .travis.yml to use graphviz 2018-05-04 17:43:37 +02:00
SMFSW
b079e7997d Doxyfile updated for Travis CI 2018-05-04 12:30:50 +02:00
SMFSW
3277748c49 Updated Doxyfile & .travis.yml 2018-05-04 02:23:19 +02:00
SMFSW
de152ccc5f Updated .travis.yml 2018-05-04 01:46:31 +02:00
SMFSW
fa20634862 Updated .travis.yml 2018-05-04 01:29:09 +02:00
SMFSW
4ce72eeb34 Upadated Doxyfile and .travis.yml for documentation generation 2018-05-04 00:34:44 +02:00
SMFSW
669f2c787b Updated README.md 2018-05-04 00:16:21 +02:00
SMFSW
7122bfd2de Updated README.md 2018-05-03 21:24:01 +02:00
SMFSW
66ceef30b4 Updated README.md 2018-05-03 21:15:08 +02:00
SMFSW
7a2af3d743 README.md updated 2018-05-03 20:57:08 +02:00
SMFSW
668e2ebcf5 Release Notes.md renamed to ReleaseNotes.md 2018-05-03 20:06:58 +02:00
SMFSW
93e2ffcccc Release Notes.md renamed to ReleaseNotes.md 2018-05-03 20:05:10 +02:00
SMFSW
dc8c19cb7a v1.3: Updated README.md 2018-05-03 19:33:34 +02:00
SMFSW
ee3b56f52e v1.3: updated README.md for Travis 2018-05-03 19:22:12 +02:00
SMFSW
a3ed48b1f1 v1.3: Release Notes is now markdown 2018-05-03 19:14:57 +02:00
SMFSW
0e091c3f95 updated .travis.yml 2018-05-03 19:02:27 +02:00
SMFSW
4fcef282b6 v1.3: Added Travis CI support and removed doxygen version anchors in sources 2018-05-03 18:42:08 +02:00
SMFSW
63be41402d Doxyfile 2018-03-15 01:38:58 +01:00
SMFSW
acfcfec7aa v1.2: No internal address transmission when reading/writing to next internal address (auto-increment feature of most I2C devices) 2017-11-30 22:40:42 +01:00
16 changed files with 2634 additions and 80 deletions

22
.github/workflows/bitbucket-push.yml vendored Normal file
View file

@ -0,0 +1,22 @@
name: Mirror Github repository to BitBucket
on: [push]
jobs:
update_bitbucket_mirror:
name: update_bitbucket_mirror
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0 # <-- clone with complete history
- name: Push
uses: heussd/mirror-to-bitbucket-github-action@v2
with:
username: SMFSW
repository: ci2c
password: ${{ secrets.BITBUCKET_PASSWORD }}

21
.github/workflows/build-badges.yml vendored Normal file
View file

@ -0,0 +1,21 @@
name: Build custom repository badges
on: [push]
jobs:
create_badges:
name: create_gist_badges
runs-on: ubuntu-latest
steps:
- name: Create repository activity badge
uses: schneegans/dynamic-badges-action@v1.7.0
with:
auth: ${{ secrets.GIST_SECRET }}
gistID: a9a2b2a02fda1b33461d53ddfe69d649
filename: cI2C_status_badge.json
label: "Status"
message: ${{ vars.REPO_STATUS }}
color: ${{ vars.REPO_STATUS_COLOR }}

53
.github/workflows/jekyll-gh-pages.yml vendored Normal file
View file

@ -0,0 +1,53 @@
# Sample workflow for building and deploying a Doxygen site to GitHub Pages
name: Deploy Doxygen docs to gh-pages branch
on:
# Runs on pushes targeting the default branch
push:
branches: ["master"]
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
contents: read
pages: write
id-token: write
# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
concurrency:
group: "pages"
cancel-in-progress: false
jobs:
# Build job
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Pages
uses: actions/configure-pages@v5
- name: Run Doxygen
uses: mattnotmitt/doxygen-action@edge
with:
# working-directory: '/doxygen'
doxyfile-path: 'Doxyfile.auto'
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: html
# Deployment job
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
needs: build
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4

4
.gitignore vendored
View file

@ -27,3 +27,7 @@
*.exe
*.out
*.app
#Doxygen
doxygen_sqlite3.db
html

12
Doxyfile Executable file → Normal file
View file

@ -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 Normal file

File diff suppressed because it is too large Load diff

0
LICENSE Executable file → Normal file
View file

95
README.md Executable file → Normal file
View file

@ -1,10 +1,22 @@
# cI2C
[![author](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/SMFSW/a9a2b2a02fda1b33461d53ddfe69d649/raw/auth_SMFSW.json)](https://github.com/SMFSW)
![badge](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/SMFSW/a9a2b2a02fda1b33461d53ddfe69d649/raw/cI2C_status_badge.json)
[![license](https://img.shields.io/badge/License-MIT-darkred.svg)](LICENSE)
[![CodeFactor](https://www.codefactor.io/repository/github/smfsw/ci2c/badge)](https://www.codefactor.io/repository/github/smfsw/ci2c)
![platform](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/SMFSW/a9a2b2a02fda1b33461d53ddfe69d649/raw/platform_INO.json)
[![doxy](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/SMFSW/a9a2b2a02fda1b33461d53ddfe69d649/raw/tool_DOXY.json)](https://smfsw.github.io/cI2C)
[![re_note](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/SMFSW/a9a2b2a02fda1b33461d53ddfe69d649/raw/tool_RN.json)](ReleaseNotes.md)
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 +28,59 @@ 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
## Links:
Feel free to share your thoughts @ xgarmanboziax@gmail.com about:
* issues encountered
* optimisations
* improvements & new functionalities
## 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

14
Release Notes.txt → ReleaseNotes.md Executable file → Normal file
View file

@ -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)

14
examples/ci2c_advanced/ci2c_advanced.ino Executable file → Normal file
View file

@ -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

0
examples/ci2c_master_read/ci2c_master_read.ino Executable file → Normal file
View file

0
examples/ci2c_master_write/ci2c_master_write.ino Executable file → Normal file
View file

0
keywords.txt Executable file → Normal file
View file

2
library.properties Executable file → Normal file
View file

@ -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 Executable file → Normal file
View file

@ -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

6
src/ci2c.h Executable file → Normal file
View file

@ -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); }