Microchip® Advanced Software Framework

Quick Start Guide for SERCOM I2C Master - Callback

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

  • Master mode
  • 100KHz operation speed
  • Not operational in standby
  • 65535 unknown bus state timeout value

Prerequisites

The device must be connected to an I2C slave.

Setup

Code

The following must be added to the user application:

A sample buffer to write from, a reversed buffer to write from and length of buffers.

#define DATA_LENGTH 8
static uint8_t wr_buffer[DATA_LENGTH] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07
};
static uint8_t wr_buffer_reversed[DATA_LENGTH] = {
0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00
};
static uint8_t rd_buffer[DATA_LENGTH];

Address of slave:

#define SLAVE_ADDRESS 0x12

Globally accessible module structure:

struct i2c_master_module i2c_master_instance;

Globally accessible packet:

struct i2c_master_packet wr_packet;
struct i2c_master_packet rd_packet;

Function for setting up module:

void configure_i2c(void)
{
/* Initialize config structure and software module */
struct i2c_master_config config_i2c_master;
i2c_master_get_config_defaults(&config_i2c_master);
/* Change buffer timeout to something longer */
config_i2c_master.buffer_timeout = 65535;
#if SAMR30
config_i2c_master.pinmux_pad0 = CONF_MASTER_SDA_PINMUX;
config_i2c_master.pinmux_pad1 = CONF_MASTER_SCK_PINMUX;
#endif
/* Initialize and enable device with config */
while(i2c_master_init(&i2c_master_instance, CONF_I2C_MASTER_MODULE, &config_i2c_master) \
!= STATUS_OK);
i2c_master_enable(&i2c_master_instance);
}

Callback function for write complete:

void i2c_write_complete_callback(
struct i2c_master_module *const module)
{
/* Initiate new packet read */
i2c_master_read_packet_job(&i2c_master_instance,&rd_packet);
}

Function for setting up the callback functionality of the driver:

void configure_i2c_callbacks(void)
{
/* Register callback function. */
i2c_master_register_callback(&i2c_master_instance, i2c_write_complete_callback,
i2c_master_enable_callback(&i2c_master_instance,
}

Add to user application main():

/* Configure device and enable. */
configure_i2c();
/* Configure callbacks and enable. */
configure_i2c_callbacks();

Workflow

  1. Configure and enable module.
    configure_i2c();
    1. Create and initialize configuration structure.
      struct i2c_master_config config_i2c_master;
      i2c_master_get_config_defaults(&config_i2c_master);
    2. Change settings in the configuration.
      config_i2c_master.buffer_timeout = 65535;
      #if SAMR30
      config_i2c_master.pinmux_pad0 = CONF_MASTER_SDA_PINMUX;
      config_i2c_master.pinmux_pad1 = CONF_MASTER_SCK_PINMUX;
      #endif
    3. Initialize the module with the set configurations.
      while(i2c_master_init(&i2c_master_instance, CONF_I2C_MASTER_MODULE, &config_i2c_master) \
      != STATUS_OK);
    4. Enable the module.
      i2c_master_enable(&i2c_master_instance);
  2. Configure callback functionality.
    configure_i2c_callbacks();
    1. Register write complete callback.
      i2c_master_register_callback(&i2c_master_instance, i2c_write_complete_callback,
    2. Enable write complete callback.
  3. Create a packet to send to slave.
    wr_packet.address = SLAVE_ADDRESS;
    wr_packet.data_length = DATA_LENGTH;
    wr_packet.data = wr_buffer;

Implementation

Code

Add to user application main():

while (true) {
/* Infinite loop */
if (!port_pin_get_input_level(BUTTON_0_PIN)) {
while (!port_pin_get_input_level(BUTTON_0_PIN)) {
/* Waiting for button steady */
}
/* Send every other packet with reversed data */
if (wr_packet.data[0] == 0x00) {
wr_packet.data = &wr_buffer_reversed[0];
} else {
wr_packet.data = &wr_buffer[0];
}
i2c_master_write_packet_job(&i2c_master_instance, &wr_packet);
}
}

Workflow

  1. Write packet to slave.
    wr_packet.address = SLAVE_ADDRESS;
    wr_packet.data_length = DATA_LENGTH;
    wr_packet.data = wr_buffer;
  2. Infinite while loop, while waiting for interaction with slave.
    while (true) {
    /* Infinite loop */
    if (!port_pin_get_input_level(BUTTON_0_PIN)) {
    while (!port_pin_get_input_level(BUTTON_0_PIN)) {
    /* Waiting for button steady */
    }
    /* Send every other packet with reversed data */
    if (wr_packet.data[0] == 0x00) {
    wr_packet.data = &wr_buffer_reversed[0];
    } else {
    wr_packet.data = &wr_buffer[0];
    }
    i2c_master_write_packet_job(&i2c_master_instance, &wr_packet);
    }
    }

Callback

Each time a packet is sent, the callback function will be called.

Workflow

  • Write complete callback:
    1. Send every other packet in reversed order.
      if (wr_packet.data[0] == 0x00) {
      wr_packet.data = &wr_buffer_reversed[0];
      } else {
      wr_packet.data = &wr_buffer[0];
      }
    2. Write new packet to slave.
      wr_packet.address = SLAVE_ADDRESS;
      wr_packet.data_length = DATA_LENGTH;
      wr_packet.data = wr_buffer;