Microchip® Advanced Software Framework

 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
Asfdoc_sam0_sercom_i2c_group

Data Structures

struct  i2c_slave_config
 Configuration structure for the I2C slave device. More...
 
struct  i2c_slave_module
 SERCOM I2C slave driver software device instance structure. More...
 
struct  i2c_slave_packet
 I2C slave packet for read/write. More...
 

Enumerations

enum  i2c_slave_address_mode {
  I2C_SLAVE_ADDRESS_MODE_MASK = SERCOM_I2CS_CTRLB_AMODE(0),
  I2C_SLAVE_ADDRESS_MODE_TWO_ADDRESSES = SERCOM_I2CS_CTRLB_AMODE(1),
  I2C_SLAVE_ADDRESS_MODE_RANGE = SERCOM_I2CS_CTRLB_AMODE(2)
}
 Enum for the possible address modes. More...
 
enum  i2c_slave_direction {
  I2C_SLAVE_DIRECTION_READ,
  I2C_SLAVE_DIRECTION_WRITE,
  I2C_SLAVE_DIRECTION_NONE
}
 Enum for the direction of a request. More...
 
enum  i2c_slave_sda_hold_time {
  I2C_SLAVE_SDA_HOLD_TIME_DISABLED,
  I2C_SLAVE_SDA_HOLD_TIME_50NS_100NS,
  I2C_SLAVE_SDA_HOLD_TIME_300NS_600NS,
  I2C_SLAVE_SDA_HOLD_TIME_400NS_800NS
}
 Enum for the possible SDA hold times with respect to the negative edge of SCL. More...
 

I2C Slave Status Flags

I2C slave status flags, returned by i2c_slave_get_status() and cleared by i2c_slave_clear_status().

#define I2C_SLAVE_STATUS_ADDRESS_MATCH   (1UL << 0)
 Address Match. More...
 
#define I2C_SLAVE_STATUS_DATA_READY   (1UL << 1)
 Data Ready. More...
 
#define I2C_SLAVE_STATUS_STOP_RECEIVED   (1UL << 2)
 Stop Received. More...
 
#define I2C_SLAVE_STATUS_CLOCK_HOLD   (1UL << 3)
 Clock Hold. More...
 
#define I2C_SLAVE_STATUS_SCL_LOW_TIMEOUT   (1UL << 4)
 SCL Low Timeout. More...
 
#define I2C_SLAVE_STATUS_REPEATED_START   (1UL << 5)
 Repeated Start. More...
 
#define I2C_SLAVE_STATUS_RECEIVED_NACK   (1UL << 6)
 Received not acknowledge. More...
 
#define I2C_SLAVE_STATUS_COLLISION   (1UL << 7)
 Transmit Collision. More...
 
#define I2C_SLAVE_STATUS_BUS_ERROR   (1UL << 8)
 Bus error. More...
 

Lock/Unlock

static enum status_code i2c_slave_lock (struct i2c_slave_module *const module)
 Attempt to get lock on driver instance. More...
 
static void i2c_slave_unlock (struct i2c_slave_module *const module)
 Unlock driver instance. More...
 

Configuration and Initialization

static bool i2c_slave_is_syncing (const struct i2c_slave_module *const module)
 Returns the synchronization status of the module. More...
 
static void i2c_slave_get_config_defaults (struct i2c_slave_config *const config)
 Gets the I2C slave default configurations. More...
 
enum status_code i2c_slave_init (struct i2c_slave_module *const module, Sercom *const hw, const struct i2c_slave_config *const config)
 Initializes the requested I2C hardware module. More...
 
static void i2c_slave_enable (const struct i2c_slave_module *const module)
 Enables the I2C module. More...
 
static void i2c_slave_disable (const struct i2c_slave_module *const module)
 Disables the I2C module. More...
 
void i2c_slave_reset (struct i2c_slave_module *const module)
 Resets the hardware module. More...
 

Read and Write

enum status_code i2c_slave_write_packet_wait (struct i2c_slave_module *const module, struct i2c_slave_packet *const packet)
 Writes a packet to the master. More...
 
enum status_code i2c_slave_read_packet_wait (struct i2c_slave_module *const module, struct i2c_slave_packet *const packet)
 Reads a packet from the master. More...
 
enum i2c_slave_direction i2c_slave_get_direction_wait (struct i2c_slave_module *const module)
 Waits for a start condition on the bus. More...
 

Status Management

uint32_t i2c_slave_get_status (struct i2c_slave_module *const module)
 Retrieves the current module status. More...
 
void i2c_slave_clear_status (struct i2c_slave_module *const module, uint32_t status_flags)
 Clears a module status flag. More...
 

#define I2C_SLAVE_STATUS_ADDRESS_MATCH   (1UL << 0)

Address Match.

Note
Should only be cleared internally by driver.

Referenced by i2c_slave_clear_status(), and i2c_slave_get_status().

#define I2C_SLAVE_STATUS_BUS_ERROR   (1UL << 8)

Bus error.

Referenced by i2c_slave_clear_status(), and i2c_slave_get_status().

#define I2C_SLAVE_STATUS_CLOCK_HOLD   (1UL << 3)

Clock Hold.

Note
Cannot be cleared, only valid when I2C_SLAVE_STATUS_ADDRESS_MATCH is set.

Referenced by i2c_slave_get_status().

#define I2C_SLAVE_STATUS_COLLISION   (1UL << 7)

Transmit Collision.

Referenced by i2c_slave_clear_status(), and i2c_slave_get_status().

#define I2C_SLAVE_STATUS_DATA_READY   (1UL << 1)

Data Ready.

Referenced by i2c_slave_clear_status(), and i2c_slave_get_status().

#define I2C_SLAVE_STATUS_RECEIVED_NACK   (1UL << 6)

Received not acknowledge.

Note
Cannot be cleared.

Referenced by i2c_slave_get_status().

#define I2C_SLAVE_STATUS_REPEATED_START   (1UL << 5)

Repeated Start.

Note
Cannot be cleared, only valid when I2C_SLAVE_STATUS_ADDRESS_MATCH is set.

Referenced by i2c_slave_get_status().

#define I2C_SLAVE_STATUS_SCL_LOW_TIMEOUT   (1UL << 4)

SCL Low Timeout.

Referenced by i2c_slave_clear_status(), and i2c_slave_get_status().

#define I2C_SLAVE_STATUS_STOP_RECEIVED   (1UL << 2)

Stop Received.

Referenced by i2c_slave_clear_status(), and i2c_slave_get_status().

Enum for the possible address modes.

Enum for the possible address modes.

Enumerator
I2C_SLAVE_ADDRESS_MODE_MASK 

Address match on address_mask used as a mask to address.

I2C_SLAVE_ADDRESS_MODE_TWO_ADDRESSES 

Address math on both address and address_mask.

I2C_SLAVE_ADDRESS_MODE_RANGE 

Address match on range of addresses between and including address and address_mask.

Enum for the direction of a request.

Enum for the direction of a request.

Enumerator
I2C_SLAVE_DIRECTION_READ 

Read.

I2C_SLAVE_DIRECTION_WRITE 

Write.

I2C_SLAVE_DIRECTION_NONE 

No direction.

Enum for the possible SDA hold times with respect to the negative edge of SCL.

Enum for the possible SDA hold times with respect to the negative edge of SCL.

Enumerator
I2C_SLAVE_SDA_HOLD_TIME_DISABLED 

SDA hold time disabled.

I2C_SLAVE_SDA_HOLD_TIME_50NS_100NS 

SDA hold time 50ns - 100ns.

I2C_SLAVE_SDA_HOLD_TIME_300NS_600NS 

SDA hold time 300ns - 600ns.

I2C_SLAVE_SDA_HOLD_TIME_400NS_800NS 

SDA hold time 400ns - 800ns.

void i2c_slave_clear_status ( struct i2c_slave_module *const  module,
uint32_t  status_flags 
)

Clears a module status flag.

Clears the given status flag of the module.

Note
Not all status flags can be cleared.
Parameters
[in]modulePointer to the I2C software device struct
[in]status_flagsBit mask of status flags to clear

References Assert, I2C_SLAVE_STATUS_ADDRESS_MATCH, I2C_SLAVE_STATUS_BUS_ERROR, I2C_SLAVE_STATUS_COLLISION, I2C_SLAVE_STATUS_DATA_READY, I2C_SLAVE_STATUS_SCL_LOW_TIMEOUT, and I2C_SLAVE_STATUS_STOP_RECEIVED.

static void i2c_slave_disable ( const struct i2c_slave_module *const  module)
inlinestatic

Disables the I2C module.

This will disable the I2C module specified in the provided software module structure.

Parameters
[in]modulePointer to the software module struct

References Assert, and system_interrupt_disable().

Referenced by i2c_slave_reset().

static void i2c_slave_enable ( const struct i2c_slave_module *const  module)
inlinestatic

Enables the I2C module.

This will enable the requested I2C module.

Parameters
[in]modulePointer to the software module struct

References Assert, and system_interrupt_enable().

Referenced by configure_i2c().

static void i2c_slave_get_config_defaults ( struct i2c_slave_config *const  config)
inlinestatic

Gets the I2C slave default configurations.

This will initialize the configuration structure to known default values.

The default configuration is as follows:

  • Disable SCL low timeout
  • 300ns - 600ns SDA hold time
  • Buffer timeout = 65535
  • Address with mask
  • Address = 0
  • Address mask = 0 (one single address)
  • General call address disabled
  • Address nack disabled if the interrupt driver is used
  • GCLK generator 0
  • Do not run in standby
  • PINMUX_DEFAULT for SERCOM pads

Those default configuration only available if the device supports it:

  • Not using 10-bit addressing
  • Standard-mode and Fast-mode transfer speed
  • SCL stretch disabled
  • Slave SCL low extend time-out disabled
Parameters
[out]configPointer to configuration structure to be initialized

References i2c_slave_config::address, i2c_slave_config::address_mask, i2c_slave_config::address_mode, Assert, i2c_slave_config::buffer_timeout, i2c_slave_config::enable_general_call_address, i2c_slave_config::enable_scl_low_timeout, GCLK_GENERATOR_0, i2c_slave_config::generator_source, I2C_SLAVE_ADDRESS_MODE_MASK, I2C_SLAVE_SDA_HOLD_TIME_300NS_600NS, PINMUX_DEFAULT, i2c_slave_config::pinmux_pad0, i2c_slave_config::pinmux_pad1, i2c_slave_config::run_in_standby, i2c_slave_config::scl_low_timeout, and i2c_slave_config::sda_hold_time.

Referenced by configure_i2c().

enum i2c_slave_direction i2c_slave_get_direction_wait ( struct i2c_slave_module *const  module)

Waits for a start condition on the bus.

Note
This function is only available for 7-bit slave addressing.

Waits for the master to issue a start condition on the bus.

Note
This function does not check for errors in the last transfer, this will be discovered when reading or writing.
Parameters
[in]modulePointer to software module structure
Returns
Direction of the current transfer, when in slave mode.
Return values
I2C_SLAVE_DIRECTION_NONENo request from master within timeout period
I2C_SLAVE_DIRECTION_READWrite request from master
I2C_SLAVE_DIRECTION_WRITERead request from master

References _i2c_slave_wait_for_bus(), Assert, I2C_SLAVE_DIRECTION_NONE, I2C_SLAVE_DIRECTION_READ, I2C_SLAVE_DIRECTION_WRITE, and STATUS_OK.

uint32_t i2c_slave_get_status ( struct i2c_slave_module *const  module)

Retrieves the current module status.

Checks the status of the module and returns it as a bitmask of status flags.

Parameters
[in]modulePointer to the I2C slave software device struct
Returns
Bitmask of status flags.
Return values
I2C_SLAVE_STATUS_ADDRESS_MATCHA valid address has been received
I2C_SLAVE_STATUS_DATA_READYA I2C slave byte transmission is successfully completed
I2C_SLAVE_STATUS_STOP_RECEIVEDA stop condition is detected for a transaction being processed
I2C_SLAVE_STATUS_CLOCK_HOLDThe slave is holding the SCL line low
I2C_SLAVE_STATUS_SCL_LOW_TIMEOUTAn SCL low time-out has occurred
I2C_SLAVE_STATUS_REPEATED_STARTIndicates a repeated start, only valid if I2C_SLAVE_STATUS_ADDRESS_MATCH is set
I2C_SLAVE_STATUS_RECEIVED_NACKThe last data packet sent was not acknowledged
I2C_SLAVE_STATUS_COLLISIONThe I2C slave was not able to transmit a high data or NACK bit
I2C_SLAVE_STATUS_BUS_ERRORAn illegal bus condition has occurred on the bus

References Assert, I2C_SLAVE_STATUS_ADDRESS_MATCH, I2C_SLAVE_STATUS_BUS_ERROR, I2C_SLAVE_STATUS_CLOCK_HOLD, I2C_SLAVE_STATUS_COLLISION, I2C_SLAVE_STATUS_DATA_READY, I2C_SLAVE_STATUS_RECEIVED_NACK, I2C_SLAVE_STATUS_REPEATED_START, I2C_SLAVE_STATUS_SCL_LOW_TIMEOUT, and I2C_SLAVE_STATUS_STOP_RECEIVED.

enum status_code i2c_slave_init ( struct i2c_slave_module *const  module,
Sercom *const  hw,
const struct i2c_slave_config *const  config 
)

Initializes the requested I2C hardware module.

Initializes the SERCOM I2C slave device requested and sets the provided software module struct. Run this function before any further use of the driver.

Parameters
[out]modulePointer to software module struct
[in]hwPointer to the hardware instance
[in]configPointer to the configuration struct
Returns
Status of initialization.
Return values
STATUS_OKModule initiated correctly
STATUS_ERR_DENIEDIf module is enabled
STATUS_BUSYIf module is busy resetting
STATUS_ERR_ALREADY_INITIALIZEDIf setting other GCLK generator than previously set

References _i2c_slave_set_config(), _sercom_get_sercom_inst_index(), Assert, i2c_slave_config::generator_source, sercom_set_gclk_generator(), system_gclk_chan_config::source_generator, STATUS_BUSY, STATUS_ERR_DENIED, system_apb_clock_set_mask(), SYSTEM_CLOCK_APB_APBC, SYSTEM_CLOCK_APB_APBD, system_gclk_chan_enable(), system_gclk_chan_get_config_defaults(), and system_gclk_chan_set_config().

Referenced by configure_i2c().

static bool i2c_slave_is_syncing ( const struct i2c_slave_module *const  module)
inlinestatic

Returns the synchronization status of the module.

Returns the synchronization status of the module.

Parameters
[out]modulePointer to software module structure
Returns
Status of the synchronization.
Return values
trueModule is busy synchronizing
falseModule is not synchronizing

References Assert.

static enum status_code i2c_slave_lock ( struct i2c_slave_module *const  module)
inlinestatic

Attempt to get lock on driver instance.

This function checks the instance's lock, which indicates whether or not it is currently in use, and sets the lock if it was not already set.

The purpose of this is to enable exclusive access to driver instances, so that, e.g., transactions by different services will not interfere with each other.

Parameters
[in,out]modulePointer to the driver instance to lock
Return values
STATUS_OKIf the module was locked
STATUS_BUSYIf the module was already locked

References STATUS_BUSY, STATUS_OK, system_interrupt_enter_critical_section(), and system_interrupt_leave_critical_section().

enum status_code i2c_slave_read_packet_wait ( struct i2c_slave_module *const  module,
struct i2c_slave_packet *const  packet 
)

Reads a packet from the master.

Reads a packet from the master. This will wait for the master to issue a request.

Parameters
[in]modulePointer to software module structure
[out]packetPacket to read from master
Returns
Status of packet read.
Return values
STATUS_OKPacket was read successfully
STATUS_ABORTEDMaster sent stop condition or repeated start before specified length of bytes was received
STATUS_ERR_IOThere was an error in the previous transfer
STATUS_ERR_DENIEDStart condition not received, another interrupt flag is set
STATUS_ERR_INVALID_ARGInvalid argument(s) was provided
STATUS_ERR_BUSYThe I2C module is busy with a job
STATUS_ERR_BAD_FORMATMaster wants to read data
STATUS_ERR_ERR_OVERFLOWLast byte received overflows buffer

References _i2c_slave_wait_for_bus(), Assert, i2c_slave_packet::data, i2c_slave_packet::data_length, STATUS_ABORTED, STATUS_BUSY, STATUS_ERR_BAD_FORMAT, STATUS_ERR_DENIED, STATUS_ERR_INVALID_ARG, STATUS_ERR_IO, and STATUS_OK.

Referenced by fetch_data(), and get_length().

void i2c_slave_reset ( struct i2c_slave_module *const  module)

Resets the hardware module.

This will reset the module to hardware defaults.

Parameters
[in,out]modulePointer to software module structure

References Assert, i2c_slave_disable(), system_interrupt_clear_pending(), system_interrupt_enter_critical_section(), and system_interrupt_leave_critical_section().

static void i2c_slave_unlock ( struct i2c_slave_module *const  module)
inlinestatic

Unlock driver instance.

This function clears the instance lock, indicating that it is available for use.

Parameters
[in,out]modulePointer to the driver instance to lock
Return values
STATUS_OKIf the module was locked
STATUS_BUSYIf the module was already locked
enum status_code i2c_slave_write_packet_wait ( struct i2c_slave_module *const  module,
struct i2c_slave_packet *const  packet 
)

Writes a packet to the master.

Writes a packet to the master. This will wait for the master to issue a request.

Parameters
[in]modulePointer to software module structure
[in]packetPacket to write to master
Returns
Status of packet write.
Return values
STATUS_OKPacket was written successfully
STATUS_ERR_DENIEDStart condition not received, another interrupt flag is set
STATUS_ERR_IOThere was an error in the previous transfer
STATUS_ERR_BAD_FORMATMaster wants to write data
STATUS_ERR_INVALID_ARGInvalid argument(s) was provided
STATUS_ERR_BUSYThe I2C module is busy with a job
STATUS_ERR_ERR_OVERFLOWMaster NACKed before entire packet was transferred
STATUS_ERR_TIMEOUTNo response was given within the timeout period

References _i2c_slave_wait_for_bus(), Assert, i2c_slave_packet::data, i2c_slave_packet::data_length, STATUS_BUSY, STATUS_ERR_BAD_FORMAT, STATUS_ERR_DENIED, STATUS_ERR_INVALID_ARG, STATUS_ERR_IO, STATUS_ERR_OVERFLOW, STATUS_ERR_TIMEOUT, and STATUS_OK.

Referenced by send_ack().