Microchip® Advanced Software Framework

Quick Start Guide for SERCOM I2C Master - Basic

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

  • Master mode
  • 100KHz operation speed
  • Not operational in standby
  • 10000 packet timeout value
  • 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 send, a sample buffer to read:
    #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];
  • Slave address to access:
    #define SLAVE_ADDRESS 0x12
  • Number of times to try to send packet if it fails:
    #define TIMEOUT 1000
  • Globally accessible module structure:
    struct i2c_master_module i2c_master_instance;
  • Function for setting up the module:
    void configure_i2c_master(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 = 10000;
    #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. */
    i2c_master_init(&i2c_master_instance, CONF_I2C_MASTER_MODULE, &config_i2c_master);
    i2c_master_enable(&i2c_master_instance);
    }
  • Add to user application main():
    /* Configure device and enable. */
    configure_i2c_master();
    /* Timeout counter. */
    uint16_t timeout = 0;
    /* Init i2c packet. */
    struct i2c_master_packet packet = {
    .address = SLAVE_ADDRESS,
    .data_length = DATA_LENGTH,
    .data = write_buffer,
    .ten_bit_address = false,
    .high_speed = false,
    .hs_master_code = 0x0,
    };

Workflow

  1. Configure and enable module.
    void configure_i2c_master(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 = 10000;
    #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. */
    i2c_master_init(&i2c_master_instance, CONF_I2C_MASTER_MODULE, &config_i2c_master);
    i2c_master_enable(&i2c_master_instance);
    }
    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 = 10000;
      #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.
      i2c_master_init(&i2c_master_instance, CONF_I2C_MASTER_MODULE, &config_i2c_master);
    4. Enable the module.
      i2c_master_enable(&i2c_master_instance);
  2. Create a variable to see when we should stop trying to send packet.
    uint16_t timeout = 0;
  3. Create a packet to send.
    struct i2c_master_packet packet = {
    .address = SLAVE_ADDRESS,
    .data_length = DATA_LENGTH,
    .data = write_buffer,
    .ten_bit_address = false,
    .high_speed = false,
    .hs_master_code = 0x0,
    };

Implementation

Code

Add to user application main():

/* Write buffer to slave until success. */
while (i2c_master_write_packet_wait(&i2c_master_instance, &packet) !=
/* Increment timeout counter and check if timed out. */
if (timeout++ == TIMEOUT) {
break;
}
}
/* Read from slave until success. */
packet.data = read_buffer;
while (i2c_master_read_packet_wait(&i2c_master_instance, &packet) !=
/* Increment timeout counter and check if timed out. */
if (timeout++ == TIMEOUT) {
break;
}
}

Workflow

  1. Write packet to slave.
    while (i2c_master_write_packet_wait(&i2c_master_instance, &packet) !=
    /* Increment timeout counter and check if timed out. */
    if (timeout++ == TIMEOUT) {
    break;
    }
    }
    The module will try to send the packet TIMEOUT number of times or until it is successfully sent.
  2. Read packet from slave.
    packet.data = read_buffer;
    while (i2c_master_read_packet_wait(&i2c_master_instance, &packet) !=
    /* Increment timeout counter and check if timed out. */
    if (timeout++ == TIMEOUT) {
    break;
    }
    }
    The module will try to read the packet TIMEOUT number of times or until it is successfully read.