Microchip® Advanced Software Framework

Quick Start Guide for SERCOM I2C Slave - Basic

In this use case, the I2C will used and set up as follows:

  • Slave mode
  • 100KHz operation speed
  • Not operational in standby
  • 10000 packet timeout value

Prerequisites

The device must be connected to an I2C master.

Setup

Code

The following must be added to the user application:

A sample buffer to write from, a sample buffer to read to and length of buffers:

#define DATA_LENGTH 10
uint8_t write_buffer[DATA_LENGTH] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09
};
uint8_t read_buffer[DATA_LENGTH];

Address to respond to:

#define SLAVE_ADDRESS 0x12

Globally accessible module structure:

Function for setting up the module:

{
/* Create and initialize config_i2c_slave structure */
struct i2c_slave_config config_i2c_slave;
i2c_slave_get_config_defaults(&config_i2c_slave);
/* Change address and address_mode */
config_i2c_slave.address = SLAVE_ADDRESS;
config_i2c_slave.address_mode = I2C_SLAVE_ADDRESS_MODE_MASK;
#if SAMR30
config_i2c_slave.pinmux_pad0 = CONF_SLAVE_SDA_PINMUX;
config_i2c_slave.pinmux_pad1 = CONF_SLAVE_SCK_PINMUX;
#endif
config_i2c_slave.buffer_timeout = 1000;
/* Initialize and enable device with config_i2c_slave */
i2c_slave_init(&i2c_slave_instance, CONF_I2C_SLAVE_MODULE, &config_i2c_slave);
}

Add to user application main():

Workflow

  1. Configure and enable module.
    1. Create and initialize configuration structure.
      struct i2c_slave_config config_i2c_slave;
      i2c_slave_get_config_defaults(&config_i2c_slave);
    2. Change address and address mode settings in the configuration.
      config_i2c_slave.address = SLAVE_ADDRESS;
      config_i2c_slave.address_mode = I2C_SLAVE_ADDRESS_MODE_MASK;
      #if SAMR30
      config_i2c_slave.pinmux_pad0 = CONF_SLAVE_SDA_PINMUX;
      config_i2c_slave.pinmux_pad1 = CONF_SLAVE_SCK_PINMUX;
      #endif
      config_i2c_slave.buffer_timeout = 1000;
    3. Initialize the module with the set configurations.
      i2c_slave_init(&i2c_slave_instance, CONF_I2C_SLAVE_MODULE, &config_i2c_slave);
    4. Enable the module.
  2. Create variable to hold transfer direction.
  3. Create packet variable to transfer.
    struct i2c_slave_packet packet = {
    .data = write_buffer,
    };

Implementation

Code

Add to user application main():

while (true) {
/* Wait for direction from master */
/* Transfer packet in direction requested by master */
packet.data = read_buffer;
} else if (dir == I2C_SLAVE_DIRECTION_WRITE) {
packet.data = write_buffer;
}
}

Workflow

  1. Wait for start condition from master and get transfer direction.
  2. Depending on transfer direction, set up buffer to read to or write from, and write or read from master.