FastArduino  v1.7
C++ library to build fast but small Arduino/AVR projects
i2c Namespace Reference

Define API to define and manage I2C devices. More...

Namespaces

 debug
 Defines API to ease I2C devices debugging.
 
 status
 Defines API to ease I2C manager status tracing and debugging.
 

Classes

class  AbstractI2CAsyncManager
 Abstract asynchronous I2C Manager. More...
 
class  AbstractI2CSyncATmegaManager
 Abstract synchronous I2C Manager for ATmega architecture. More...
 
class  AbstractI2CSyncATtinyManager
 Abstract synchronous I2C Manager for ATtiny architecture. More...
 
class  AbstractI2CSyncManager
 Abstract synchronous I2C Manager for all MCU architectures. More...
 
class  I2CAsyncDebugManager
 Asynchronous I2C Manager for ATmega architecture with debug facility. More...
 
class  I2CAsyncLCDebugManager
 Asynchronous I2C Manager for ATmega architecture with debug facility and support for dynamic proxies. More...
 
class  I2CAsyncLCManager
 Asynchronous I2C Manager for ATmega architecture with support for dynamic proxies. More...
 
class  I2CAsyncLCStatusDebugManager
 Asynchronous I2C Manager for ATmega architecture with debug and status notification facilities and support for dynamic proxies. More...
 
class  I2CAsyncLCStatusManager
 Asynchronous I2C Manager for ATmega architecture with status notification facility and support for dynamic proxies. More...
 
class  I2CAsyncManager
 Asynchronous I2C Manager for ATmega architecture. More...
 
class  I2CAsyncStatusDebugManager
 Asynchronous I2C Manager for ATmega architecture with debug and status notification facilities. More...
 
class  I2CAsyncStatusManager
 Asynchronous I2C Manager for ATmega architecture with status notification facility. More...
 
class  I2CCommand
 Atomic I2C command as used internally by an asynchronous I2C Manager. More...
 
class  I2CDevice
 Base class for all I2C devices. More...
 
class  I2CLightCommand
 Light atomic I2C command as prepared by an I2C device. More...
 
class  I2CSyncDebugManager
 Synchronous I2C Manager for ATmega architecture with debug facility. More...
 
class  I2CSyncLCDebugManager
 Synchronous I2C Manager for ATmega architecture with debug facility and support for dynamic proxies. More...
 
class  I2CSyncLCManager
 Synchronous I2C Manager for ATmega architecture with support for dynamic proxies. More...
 
class  I2CSyncLCStatusDebugManager
 Synchronous I2C Manager for ATmega architecture with status notification and debug facilities and support for dynamic proxies. More...
 
class  I2CSyncLCStatusManager
 Synchronous I2C Manager for ATmega architecture with status notification facility and support for dynamic proxies. More...
 
class  I2CSyncManager
 Synchronous I2C Manager for ATmega architecture. More...
 
class  I2CSyncStatusDebugManager
 Synchronous I2C Manager for ATmega architecture with status notification and debug facility. More...
 
class  I2CSyncStatusManager
 Synchronous I2C Manager for ATmega architecture wit status notification facility. More...
 

Typedefs

using I2C_DEBUG_HOOK = void(*)(DebugStatus status, uint8_t data)
 The default debugging hook type. More...
 
using I2C_STATUS_HOOK = void(*)(Status expected, Status actual)
 The default status observer hook type. More...
 

Enumerations

enum  Status : uint8_t {
  Status::OK = 0x00,
  Status::START_TRANSMITTED = 0x08,
  Status::REPEAT_START_TRANSMITTED = 0x10,
  Status::SLA_W_TRANSMITTED_ACK = 0x18,
  Status::SLA_W_TRANSMITTED_NACK = 0x20,
  Status::DATA_TRANSMITTED_ACK = 0x28,
  Status::DATA_TRANSMITTED_NACK = 0x30,
  Status::ARBITRATION_LOST = 0x38,
  Status::SLA_R_TRANSMITTED_ACK = 0x40,
  Status::SLA_R_TRANSMITTED_NACK = 0x48,
  Status::DATA_RECEIVED_ACK = 0x50,
  Status::DATA_RECEIVED_NACK = 0x58
}
 Transmission status codes. More...
 
enum  I2CMode : uint8_t {
  I2CMode::STANDARD,
  I2CMode::FAST
}
 I2C available transmission modes. More...
 
enum  I2CErrorPolicy : uint8_t {
  I2CErrorPolicy::DO_NOTHING,
  I2CErrorPolicy::CLEAR_ALL_COMMANDS,
  I2CErrorPolicy::CLEAR_TRANSACTION_COMMANDS
}
 I2C Manager policy to use in case of an error during I2C transaction. More...
 
enum  I2CCallback : uint8_t {
  I2CCallback::NONE = 0,
  I2CCallback::END_COMMAND,
  I2CCallback::END_TRANSACTION,
  I2CCallback::ERROR
}
 Type passed to I2C ISR registered callbacks (asynchronous I2C Manager only) when an asynchronous I2C transaction is executed. More...
 
enum  DebugStatus : uint8_t {
  DebugStatus::START = 0,
  DebugStatus::REPEAT_START,
  DebugStatus::SLAW,
  DebugStatus::SLAR,
  DebugStatus::SEND,
  DebugStatus::RECV,
  DebugStatus::RECV_LAST,
  DebugStatus::STOP,
  DebugStatus::SEND_OK,
  DebugStatus::SEND_ERROR,
  DebugStatus::RECV_OK,
  DebugStatus::RECV_ERROR
}
 List of debug states that are reported by the I2C Manager in debug mode. More...
 

Variables

static constexpr Mode I2C_STANDARD = Mode<I2CMode::STANDARD>{}
 Constant determining that best supported I2C mode for an I2CDevice is STANDARD (100kHz).
 
static constexpr Mode I2C_FAST = Mode<I2CMode::FAST>{}
 Constant determining that best supported I2C mode for an I2CDevice is FAST (400kHz).
 

Detailed Description

Define API to define and manage I2C devices.

This namespace defines everything related to I2C.

I2C is available to all MCU supported by FastArduino, even in ATtiny MCU, for which I2C is implemented with Universal Serial Interface (USI).

Note
Current implementation supports both synchronous and asynchronous operation. However, asynchronous operation is only supported on ATmega MCU.

The following snippet shows how to use an I2C device, the DS1307 Real Time Clock:

int main()
{
manager.begin();
devices::rtc::DS1307 rtc{manager};
rtc.get_datetime(now);
...
manager.end();
}

In FastArduino, I2C communication is centralized by an I2C Manager; there are several flavors of I2C Manager defined in FastArduino, with distinct characteristics such as:

  • synchronous (all MCU) or asynchronous (ATmega only)
  • I2C mode supported (fast 400kHz or standard 100kHz)
  • policy to follow in case of failure during an I2C transaction
  • ...

I2C devices to connect with must be managed by a dedicated subclass of i2c::I2CDevice, which provides a specific API for the interfaced device, and handles all communication with an I2C Manager.

For any I2C device subclass, the provided API comes in 2 flavours at a time (whatever I2C Manager is used):

  • asynchronous: the API enqueues a chain of I2C commands for the underlying I2C transaction and lets the I2C Manager handle these commands asynchronously if possible (the I2C Manager must support asynchronous operations); when really handled asynchronously, the API returns immediately, before the actual I2C transaction is performed. Actual results will be returned through a future::Future instance, passed as input argument of the API.
  • synchronous: the API blocks until the complete underlying I2C transaction is complete. This API is implemented based on the asynchronous API above, but simply awaits for the Future result of the I2C transaction.

FastArduino defines many specific I2C Manager classes among the following:

All these classes are template classes with various arguments (the actual list of arguments depends on each specific class):

  • MODE: i2c::I2CMode (bus frequency) supported (fast 400kHz or standard 100kHz)
  • POLICY: i2c::I2CErrorPolicy (behavior in case of an error during a transaction) for asynchronous I2C Managers only
  • DEBUG_HOOK: the type of callback hook for debug, can be a simple function pointer (type i2c::I2C_DEBUG_HOOK) or a more complex functor class
  • STATUS_HOOK: the type of callback hook for I2C status, can be a simple function pointer (type i2c::I2C_STATUS_HOOK) or a more complex functor class

All these different flavors of I2C Manager share the same API (except for their constructor that may need different arguments).

Lifecycle support enables programs to move futures around without losing track of the right location, thanks to the use of lifecycle::LightProxy. Although not often needed, it can prove useful in some situations.

All I2C Manager asynchronous flavors operate based on a queue of I2C commands. It is up to the end program to create the properly sized buffer for that command queue, before instantiating the relevant asynchronous I2C Manager; the buffer must be passed to the asynchronous I2C Manager constructor. Asynchronous I2C Manager classes will work fine only if the proper ISR function is registered, through one of the 3 provided registration macros. Some of these registration macros also allow registration of a callback hook that will be called for every single I2C step (as defined in ATmega datasheet).

The following snippet shows the minimal code to operate the I2C RTC device DS1307 in synchronous mode:

// Define type alias for I2C Manager; here we use the simplest possible synchronous manager
using RTC = DS1307<MANAGER>;
...
// Instantiate and start I2C Manager
MANAGER manager;
manager.begin();
// Instantiate the DS1307 RTC device
RTC rtc{manager};
// Call specific DS1307 API to get current date
tm now;
rtc.get_datetime(now);

The next snippet demonstrates how to do the same but in an asynchronous way:

// Define type alias for I2C Manager; here we use the simplest possible asynchronous manager
using RTC = DS1307<MANAGER>;
// Define a buffer for the I2C Manager commands queue
static constexpr uint8_t I2C_BUFFER_SIZE = 32;
static MANAGER::I2CCOMMAND i2c_buffer[I2C_BUFFER_SIZE];
// Register I2C ISR to allow asynchronous operation with the I2C Manager
...
// Instantiate and start I2C Manager
MANAGER manager{i2c_buffer};
manager.begin();
// Instantiate the DS1307 RTC device
RTC rtc{manager};
// Prepare Future to receive current date
RTC::GetDatetimeFuture future;
// Call specific DS1307 API to get current date
int error = rtc.get_datetime(future);
// Check error here (should be 0)...
// When needed, get the Future result (await if needed)
tm now;
bool ok = get_date_future.get(now);
See also
REGISTER_I2C_ISR()
REGISTER_I2C_ISR_FUNCTION()
REGISTER_I2C_ISR_METHOD()

Typedef Documentation

◆ I2C_DEBUG_HOOK

using i2c::I2C_DEBUG_HOOK = typedef void (*)(DebugStatus status, uint8_t data)

The default debugging hook type.

Warning
Do not use this (function pointer) for your hooks! This will increase code size and ISR delay. Rather use functors as defined in i2c_debug.h.
See also
I2CSyncDebugManager
I2CAsyncDebugManager
i2c::debug::I2CDebugRecorder
i2c::debug::I2CDebugLiveLogger

Definition at line 83 of file i2c_handler_common.h.

◆ I2C_STATUS_HOOK

using i2c::I2C_STATUS_HOOK = typedef void (*)(Status expected, Status actual)

The default status observer hook type.

Warning
Do not use this (function pointer) for your hooks! This will increase code size and ISR delay. Rather use functors as defined in i2c_status.h.
See also
I2CSyncStatusManager
I2CAsyncStatusManager
i2c::debug::I2CDebugRecorder
i2c::debug::I2CDebugLiveLogger

Definition at line 96 of file i2c_handler_common.h.

Enumeration Type Documentation

◆ Status

enum i2c::Status : uint8_t
strong

Transmission status codes.

Transmission status is returned by all i2c::I2CDevice read and write methods. This status is also transmitted to an optional hook function for debug purposes.

All codes are defined and directly mapped from ATmega328 datasheet (section 22. "2-wire Serial interface", tables 22-2 and 22-3).

You will probably never need to use these codes in your program.

See also
I2CSyncStatusManager
I2CAsyncStatusManager
i2c::status
Enumerator
OK 

Code indicating the last called method executed as expected without any issue.

START_TRANSMITTED 

[Transmitter/Receiver modes] A START condition has been transmitted.

REPEAT_START_TRANSMITTED 

[Transmitter/Receiver modes] A repeated START condition has been transmitted.

SLA_W_TRANSMITTED_ACK 

[Transmitter mode] SLA+W has been transmitted; ACK has been received.

SLA_W_TRANSMITTED_NACK 

[Transmitter mode] SLA+W has been transmitted; NOT ACK has been received.

DATA_TRANSMITTED_ACK 

[Transmitter mode] Data byte has been transmitted; ACK has been received.

DATA_TRANSMITTED_NACK 

[Transmitter mode] Data byte has been transmitted; NOT ACK has been received.

ARBITRATION_LOST 

[Transmitter mode] Abitration lost in SLA+W or data bytes.

[Receiver mode] Abitration lost in SLA+R or NOT ACK bit.

SLA_R_TRANSMITTED_ACK 

[Receiver mode] SLA+R has been transmitted; ACK has been received.

SLA_R_TRANSMITTED_NACK 

[Receiver mode] SLA+R has been transmitted; NOT ACK has been received.

DATA_RECEIVED_ACK 

[Receiver mode] Data byte has been transmitted; ACK has been returned.

DATA_RECEIVED_NACK 

[Receiver mode] Data byte has been transmitted; NOT ACK has been returned.

Definition at line 65 of file i2c.h.

◆ I2CMode

enum i2c::I2CMode : uint8_t
strong

I2C available transmission modes.

This defines the maximum bus transmission frequency.

See also
I2CSyncManager
I2CAsyncManager
Enumerator
STANDARD 

I2C Standard mode, less than 100KHz.

FAST 

I2C Fast mode, less than 400KHz.

Definition at line 107 of file i2c.h.

◆ I2CErrorPolicy

enum i2c::I2CErrorPolicy : uint8_t
strong

I2C Manager policy to use in case of an error during I2C transaction.

Warning
available only on ATmega MCU.
See also
I2CAsyncManager
Enumerator
DO_NOTHING 

Do nothing at all in case of an error; useful only with a synchronous I2C Manager.

CLEAR_ALL_COMMANDS 

In case of an error during I2C transaction, then all I2CCommand currently in queue will be removed.

Warning
this means that an error with device A can trigger a removal of pending commands for device B.
CLEAR_TRANSACTION_COMMANDS 

In case of an error during I2C transaction, then all pending I2CCommand of the current transaction will be removed.

Definition at line 119 of file i2c_handler_atmega.h.

◆ I2CCallback

enum i2c::I2CCallback : uint8_t
strong

Type passed to I2C ISR registered callbacks (asynchronous I2C Manager only) when an asynchronous I2C transaction is executed.

Enumerator
NONE 

An I2C command is being processed (intermediate step).

END_COMMAND 

An I2C command has just been finished executed.

END_TRANSACTION 

The last I2C command in a transaction has just been finished executing.

ERROR 

An error has occurred during I2C transaction execution.

Definition at line 146 of file i2c_handler_atmega.h.

◆ DebugStatus

enum i2c::DebugStatus : uint8_t
strong

List of debug states that are reported by the I2C Manager in debug mode.

See also
I2CSyncDebugManager
I2CAsyncDebugManager
Enumerator
START 

A start condition has just been sent.

REPEAT_START 

A repeat start condition has just been sent.

SLAW 

A slave address has just been sent for writing.

SLAR 

A slave address has just been sent for reading.

SEND 

A byte has just be sent to the slave.

RECV 

A byte is being received from the slave.

RECV_LAST 

The last byte is being received from the slave.

STOP 

A stop condition has just been sent.

SEND_OK 

The latest sent byte has been acknowledged by the slave.

SEND_ERROR 

The latest sent byte has not been acknowledged by the slave.

RECV_OK 

I2C Manager has acknowledged the latest received byte from the slave.

RECV_ERROR 

I2C Manager has not acknowledged the latest received byte from the slave.

Definition at line 43 of file i2c_handler_common.h.

future
Contains the API around Future implementation.
Definition: future.cpp:18
devices::rtc::tm
The datetime structure used by the RTC API.
Definition: ds1307.h:78
devices::rtc::DS1307
I2C device driver for the DS1307 RTC chip.
Definition: ds1307.h:115
i2c::I2CSyncManager
Synchronous I2C Manager for ATmega architecture.
Definition: i2c_handler_atmega.h:1181
i2c::AbstractI2CSyncManager< ATmegaI2CSyncHandler< MODE_, HAS_STATUS_, I2C_STATUS_HOOK >, MODE_, HAS_LC_, I2C_STATUS_HOOK, HAS_DEBUG_, I2C_DEBUG_HOOK >::end
void end()
Disable MCU I2C transmission.
Definition: i2c_handler_common.h:444
i2c::I2CAsyncManager
Asynchronous I2C Manager for ATmega architecture.
Definition: i2c_handler_atmega.h:818
REGISTER_I2C_ISR
#define REGISTER_I2C_ISR(MANAGER)
Register the necessary ISR (Interrupt Service Routine) for an asynchronous I2C Manager to work proper...
Definition: i2c_handler_atmega.h:57
i2c::AbstractI2CSyncManager< ATmegaI2CSyncHandler< MODE_, HAS_STATUS_, I2C_STATUS_HOOK >, MODE_, HAS_LC_, I2C_STATUS_HOOK, HAS_DEBUG_, I2C_DEBUG_HOOK >::begin
void begin()
Prepare and enable the MCU for I2C transmission.
Definition: i2c_handler_common.h:433