Skyward boardcore
Loading...
Searching...
No Matches
Boardcore::I2CDriver Class Reference

Low level driver for I2C peripherals. More...

#include <I2CDriver.h>

Classes

struct  I2CSlaveConfig
 Configuration struct for a slave device. This will be used for configuring the bus in order to communicate with the addressed device. More...
 

Public Types

enum  Operation : uint8_t { WRITE = 0 , READ = 1 }
 
enum  Speed : uint8_t { STANDARD = 0 , FAST = 1 , MAX_SPEED = FAST }
 
enum  Addressing : uint8_t { BIT7 = 0 , BIT10 = 1 }
 
enum  Errors : uint16_t {
  NO_ERROR = 0 , BUS_LOCKED = 1 << 0 , BERR = 1 << 1 , ARLO = 1 << 2 ,
  AF = 1 << 3 , OVR = 1 << 4 , SB_NOT_SENT = 1 << 5 , ADDR_ERROR = 1 << 6
}
 Error enums with a value that makes it possible to keep the "or-red" value to store more errors. More...
 

Public Member Functions

 I2CDriver (I2C_TypeDef *i2c, miosix::GpioPin scl, miosix::GpioPin sda)
 Constructor for the I2C low-level driver.
 
 I2CDriver (const I2CDriver &)=delete
 
I2CDriveroperator= (const I2CDriver &)=delete
 
 I2CDriver (I2CDriver &&)=delete
 
I2CDriveroperator= (I2CDriver &&)=delete
 
 ~I2CDriver ()
 Disables the peripheral, the interrupts in the NVIC and the peripheral's clock.
 
bool read (const I2CSlaveConfig &slaveConfig, void *buffer, const size_t &nBytes)
 Read operation to read nBytes. In case of an error during the communication, this method returns false with no further attempts.
 
bool write (const I2CSlaveConfig &slaveConfig, const void *buffer, const size_t &nBytes, bool generateStop=true)
 Write operation to write nBytes. In case of an error during the communication, this method returns false with no further attempts.
 
void flushBus ()
 Performs the recovery from the locked state if necessary.
 
uint16_t getLastError ()
 Returns the last errors happened in the communication.
 
void IRQhandleInterrupt ()
 Handles the interrupt for events of the specific peripheral.
 
void IRQhandleErrInterrupt ()
 Handles the interrupt for the errors in the specific peripheral.
 

Detailed Description

Low level driver for I2C peripherals.

This is NOT a thread safe driver. The features supported are:

  • Only Master logic;
  • Standard, Fast and Fast plus (if supported) speed modes;
  • 7bit addressing;
  • Exposes basic read or write methods with the option for the write method to not generate a STOP condition;
  • There is a method 'flushBus' in order to check and possibly recover from a locked state on the bus;
  • Dynamic setting of clock parameters in order to change speed or addressing mode before interacting with a device;

Definition at line 56 of file I2CDriver.h.

Member Enumeration Documentation

◆ Addressing

Enumerator
BIT7 
BIT10 

Definition at line 77 of file I2CDriver.h.

◆ Errors

Error enums with a value that makes it possible to keep the "or-red" value to store more errors.

Enumerator
NO_ERROR 

The bus didn't have any error.

BUS_LOCKED 

Detected a locked state on the bus.

BERR 

External Start or stop condition detected.

ARLO 

Arbitration lost.

AF 

Acknowledge failure.

OVR 

Overrun/underrun error.

SB_NOT_SENT 

Start bit not sent.

ADDR_ERROR 

Address sent but peripheral in wrong state.

Definition at line 87 of file I2CDriver.h.

◆ Operation

Enumerator
WRITE 
READ 

Definition at line 59 of file I2CDriver.h.

◆ Speed

Enumerator
STANDARD 
FAST 
MAX_SPEED 

Definition at line 65 of file I2CDriver.h.

Constructor & Destructor Documentation

◆ I2CDriver() [1/3]

Boardcore::I2CDriver::I2CDriver ( I2C_TypeDef * i2c,
miosix::GpioPin scl,
miosix::GpioPin sda )

Constructor for the I2C low-level driver.

It initializes the peripheral clock, the pins, calls the init() method and enables the IRQs in the NVIC. Pins are internally initialized so that they are always set to ALTERNATE_OD mode with Alternate Function 4 (the usual AF of I2C pins). Thanks to this we avoid the possibility of short circuits between master and slaves when they both drive the same bus on two different logical values.

Parameters
i2cStructure that represents the I2C peripheral.
sclSerial clock GpioPin of the relative I2C peripheral.
sdaSerial data GpioPin of the relative I2C peripheral. Delete copy/move constructors/operators.

◆ I2CDriver() [2/3]

Boardcore::I2CDriver::I2CDriver ( const I2CDriver & )
delete

◆ I2CDriver() [3/3]

Boardcore::I2CDriver::I2CDriver ( I2CDriver && )
delete

◆ ~I2CDriver()

Boardcore::I2CDriver::~I2CDriver ( )

Disables the peripheral, the interrupts in the NVIC and the peripheral's clock.

Member Function Documentation

◆ flushBus()

void Boardcore::I2CDriver::flushBus ( )

Performs the recovery from the locked state if necessary.

It tries to recover from the locked state forcing (changing the mode of the clock pin) N_SCL_BITBANG clock cycles and re-initializing the peripheral. It usually takes less than 200us for 16 clocks forced in standard mode.

◆ getLastError()

uint16_t Boardcore::I2CDriver::getLastError ( )

Returns the last errors happened in the communication.

For checking if a specific error occurred in the last transaction you can do if(getLastError() & Errors::<error-to-check>). Do not use == to check for errors because there could be more errors at once. To check if no errors occurred use if(getLastError() == Errors::NO_ERROR) or simply if(!getLastError())

Returns
A bit sequence where the bits set correspond to the last errors occurred in the peripheral (see the I2CDriver::Errors enum to get the correspondence between bit position and error reported).

◆ IRQhandleErrInterrupt()

void Boardcore::I2CDriver::IRQhandleErrInterrupt ( )

Handles the interrupt for the errors in the specific peripheral.

It disables the interrupts of the peripheral, wakes the thread up, sets the "error" software flag and resets the error flags in the register.

Warning
This function should only be called by interrupts. No user code should call this method.

◆ IRQhandleInterrupt()

void Boardcore::I2CDriver::IRQhandleInterrupt ( )

Handles the interrupt for events of the specific peripheral.

Wakes up the thread only if the operation is completed or an error is detected, otherwise all the phases of the read or write are handled in this ISR thanks to the changing of the peripheral flags.

Warning
This function should only be called by interrupts. No user code should call this method.

◆ operator=() [1/2]

I2CDriver & Boardcore::I2CDriver::operator= ( const I2CDriver & )
delete

◆ operator=() [2/2]

I2CDriver & Boardcore::I2CDriver::operator= ( I2CDriver && )
delete

◆ read()

bool Boardcore::I2CDriver::read ( const I2CSlaveConfig & slaveConfig,
void * buffer,
const size_t & nBytes )

Read operation to read nBytes. In case of an error during the communication, this method returns false with no further attempts.

Warning
Check always if the operation succeeded or not!
Parameters
slaveConfigThe configuration struct of the slave device.
bufferData buffer where to store the data read from the bus.
nBytesNumber of bytes to read.
Returns
True if the read is successful, false otherwise.

◆ write()

bool Boardcore::I2CDriver::write ( const I2CSlaveConfig & slaveConfig,
const void * buffer,
const size_t & nBytes,
bool generateStop = true )

Write operation to write nBytes. In case of an error during the communication, this method returns false with no further attempts.

Warning
Check always if the operation succeeded or not!
Parameters
slaveConfigThe configuration struct of the slave device.
bufferData buffer where to read the data to send.
nBytesNumber of bytes to send.
generateStopFlag for the stop condition generation.
Returns
True if the write is successful, false otherwise.

The documentation for this class was generated from the following file: