Microchip® Advanced Software Framework

Quick Start Guide for SERCOM I2C Slave - Callback

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
static uint8_t write_buffer[DATA_LENGTH] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
};
static uint8_t read_buffer [DATA_LENGTH];

Address to respond to:

#define SLAVE_ADDRESS 0x12

Globally accessible module structure:

struct i2c_slave_module i2c_slave_instance;

Globally accessible packet:

static struct i2c_slave_packet packet;

Function for setting up the module:

void configure_i2c_slave(void)
{
/* Initialize config structure and module instance */
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
/* Initialize and enable device with config */
i2c_slave_init(&i2c_slave_instance, CONF_I2C_SLAVE_MODULE, &config_i2c_slave);
i2c_slave_enable(&i2c_slave_instance);
}

Callback function for read request from a master:

void i2c_read_request_callback(
struct i2c_slave_module *const module)
{
/* Init i2c packet */
packet.data_length = DATA_LENGTH;
packet.data = write_buffer;
/* Write buffer to master */
i2c_slave_write_packet_job(module, &packet);
}

Callback function for write request from a master:

void i2c_write_request_callback(
struct i2c_slave_module *const module)
{
/* Init i2c packet */
packet.data_length = DATA_LENGTH;
packet.data = read_buffer;
/* Read buffer from master */
if (i2c_slave_read_packet_job(module, &packet) != STATUS_OK) {
}
}

Function for setting up the callback functionality of the driver:

void configure_i2c_slave_callbacks(void)
{
/* Register and enable callback functions */
i2c_slave_register_callback(&i2c_slave_instance, i2c_read_request_callback,
i2c_slave_enable_callback(&i2c_slave_instance,
i2c_slave_register_callback(&i2c_slave_instance, i2c_write_request_callback,
i2c_slave_enable_callback(&i2c_slave_instance,
}

Add to user application main():

/* Configure device and enable */
configure_i2c_slave();
configure_i2c_slave_callbacks();

Workflow

  1. Configure and enable module.
    configure_i2c_slave();
    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
    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.
      i2c_slave_enable(&i2c_slave_instance);
  2. Register and enable callback functions.
    configure_i2c_slave_callbacks();
    1. Register and enable callbacks for read and write requests from master.
      i2c_slave_register_callback(&i2c_slave_instance, i2c_read_request_callback,
      i2c_slave_enable_callback(&i2c_slave_instance,
      i2c_slave_register_callback(&i2c_slave_instance, i2c_write_request_callback,
      i2c_slave_enable_callback(&i2c_slave_instance,

Implementation

Code

Add to user application main():

while (true) {
/* Infinite loop while waiting for I2C master interaction */
}

Workflow

  1. Infinite while loop, while waiting for interaction from master.
    while (true) {
    /* Infinite loop while waiting for I2C master interaction */
    }

Callback

When an address packet is received, one of the callback functions will be called, depending on the DIR bit in the received packet.

Workflow

  • Read request callback:
    1. Length of buffer and buffer to be sent to master is initialized.
      packet.data_length = DATA_LENGTH;
      packet.data = write_buffer;
    2. Write packet to master.
      i2c_slave_write_packet_job(module, &packet);
  • Write request callback:
    1. Length of buffer and buffer to be read from master is initialized.
      packet.data_length = DATA_LENGTH;
      packet.data = read_buffer;
    2. Read packet from master.
      if (i2c_slave_read_packet_job(module, &packet) != STATUS_OK) {
      }