mbed library sources

Dependents:   Encrypted my_mbed lklk CyaSSL_DTLS_Cellular ... more

Superseded

This library was superseded by mbed-dev - https://os.mbed.com/users/mbed_official/code/mbed-dev/.

Development branch of the mbed library sources. This library is kept in synch with the latest changes from the mbed SDK and it is not guaranteed to work.

If you are looking for a stable and tested release, please import one of the official mbed library releases:

Import librarymbed

The official Mbed 2 C/C++ SDK provides the software platform and libraries to build your applications.

Revision:
613:bc40b8d2aec4
Parent:
612:fba1c7dc54c0
Child:
614:9d86c2ae5de0
--- a/targets/hal/TARGET_Atmel/TARGET_SAM21/drivers/sercom/i2c/i2c_samd21_r21_d10_d11_l21/i2c_slave.c	Tue Aug 18 15:00:09 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,674 +0,0 @@
-#include "i2c_slave.h"
-#if I2C_SLAVE_CALLBACK_MODE == true
-#  include "i2c_slave_interrupt.h"
-#endif
-
-/**
- * \internal Sets configuration to module
- *
- * \param[out] module  Pointer to software module structure
- * \param[in]  config  Configuration structure with configurations to set
- *
- * \return Status of setting configuration.
- * \retval STATUS_OK                       Module was configured correctly
- * \retval STATUS_ERR_ALREADY_INITIALIZED  If setting other GCLK generator than
- *                                         previously set
- */
-static enum status_code _i2c_slave_set_config(
-    struct i2c_slave_module *const module,
-    const struct i2c_slave_config *const config)
-{
-    uint32_t tmp_ctrla;
-
-    /* Sanity check arguments. */
-    Assert(module);
-    Assert(module->hw);
-    Assert(config);
-
-    SercomI2cs *const i2c_hw = &(module->hw->I2CS);
-    Sercom *const sercom_hw = module->hw;
-
-    module->buffer_timeout = config->buffer_timeout;
-    module->ten_bit_address = config->ten_bit_address;
-
-    struct system_pinmux_config pin_conf;
-    system_pinmux_get_config_defaults(&pin_conf);
-
-    uint32_t pad0 = config->pinmux_pad0;
-    uint32_t pad1 = config->pinmux_pad1;
-
-    /* SERCOM PAD0 - SDA */
-    if (pad0 == PINMUX_DEFAULT) {
-        pad0 = _sercom_get_default_pad(sercom_hw, 0);
-    }
-    pin_conf.mux_position = pad0 & 0xFFFF;
-    pin_conf.direction    = SYSTEM_PINMUX_PIN_DIR_OUTPUT_WITH_READBACK;
-    system_pinmux_pin_set_config(pad0 >> 16, &pin_conf);
-
-    /* SERCOM PAD1 - SCL */
-    if (pad1 == PINMUX_DEFAULT) {
-        pad1 = _sercom_get_default_pad(sercom_hw, 1);
-    }
-    pin_conf.mux_position = pad1 & 0xFFFF;
-    pin_conf.direction    = SYSTEM_PINMUX_PIN_DIR_OUTPUT_WITH_READBACK;
-    system_pinmux_pin_set_config(pad1 >> 16, &pin_conf);
-
-    /* Prepare config to write to register CTRLA */
-    if (config->run_in_standby || system_is_debugger_present()) {
-        tmp_ctrla = SERCOM_I2CS_CTRLA_RUNSTDBY;
-    } else {
-        tmp_ctrla = 0;
-    }
-
-    tmp_ctrla |= ((uint32_t)config->sda_hold_time |
-                  config->transfer_speed |
-                  (config->scl_low_timeout << SERCOM_I2CS_CTRLA_LOWTOUTEN_Pos) |
-                  (config->scl_stretch_only_after_ack_bit << SERCOM_I2CS_CTRLA_SCLSM_Pos) |
-                  (config->slave_scl_low_extend_timeout << SERCOM_I2CS_CTRLA_SEXTTOEN_Pos));
-
-    i2c_hw->CTRLA.reg |= tmp_ctrla;
-
-    /* Set CTRLB configuration */
-    i2c_hw->CTRLB.reg = SERCOM_I2CS_CTRLB_SMEN | config->address_mode;
-
-    i2c_hw->ADDR.reg = config->address << SERCOM_I2CS_ADDR_ADDR_Pos |
-                       config->address_mask << SERCOM_I2CS_ADDR_ADDRMASK_Pos |
-                       config->ten_bit_address << SERCOM_I2CS_ADDR_TENBITEN_Pos |
-                       config->enable_general_call_address << SERCOM_I2CS_ADDR_GENCEN_Pos;
-
-    return STATUS_OK;
-}
-
-/**
- * \brief Initializes the requested I<SUP>2</SUP>C hardware module
- *
- * Initializes the SERCOM I<SUP>2</SUP>C Slave device requested and sets the provided
- * software module struct.  Run this function before any further use of
- * the driver.
- *
- * \param[out] module  Pointer to software module struct
- * \param[in]  hw      Pointer to the hardware instance
- * \param[in]  config  Pointer to the configuration struct
- *
- * \return Status of initialization.
- * \retval STATUS_OK                       Module initiated correctly
- * \retval STATUS_ERR_DENIED               If module is enabled
- * \retval STATUS_BUSY                     If module is busy resetting
- * \retval STATUS_ERR_ALREADY_INITIALIZED  If setting other GCLK generator than
- *                                         previously set
- */
-enum status_code i2c_slave_init(
-    struct i2c_slave_module *const module,
-    Sercom *const hw,
-    const struct i2c_slave_config *const config)
-{
-    /* Sanity check arguments. */
-    Assert(module);
-    Assert(hw);
-    Assert(config);
-
-    /* Initialize software module */
-    module->hw = hw;
-
-    SercomI2cs *const i2c_hw = &(module->hw->I2CS);
-
-    /* Check if module is enabled. */
-    if (i2c_hw->CTRLA.reg & SERCOM_I2CS_CTRLA_ENABLE) {
-        return STATUS_ERR_DENIED;
-    }
-
-    /* Check if reset is in progress. */
-    if (i2c_hw->CTRLA.reg & SERCOM_I2CS_CTRLA_SWRST) {
-        return STATUS_BUSY;
-    }
-
-    uint32_t sercom_index = _sercom_get_sercom_inst_index(module->hw);
-#if (SAML21)
-    uint32_t pm_index     = sercom_index + MCLK_APBCMASK_SERCOM0_Pos;
-#else
-    uint32_t pm_index     = sercom_index + PM_APBCMASK_SERCOM0_Pos;
-#endif
-    uint32_t gclk_index   = sercom_index + SERCOM0_GCLK_ID_CORE;
-
-    /* Turn on module in PM */
-    system_apb_clock_set_mask(SYSTEM_CLOCK_APB_APBC, 1 << pm_index);
-
-    /* Set up the GCLK for the module */
-    struct system_gclk_chan_config gclk_chan_conf;
-    system_gclk_chan_get_config_defaults(&gclk_chan_conf);
-    gclk_chan_conf.source_generator = config->generator_source;
-    system_gclk_chan_set_config(gclk_index, &gclk_chan_conf);
-    system_gclk_chan_enable(gclk_index);
-    sercom_set_gclk_generator(config->generator_source, false);
-
-#if I2C_SLAVE_CALLBACK_MODE == true
-    /* Get sercom instance index. */
-    uint8_t instance_index = _sercom_get_sercom_inst_index(module->hw);
-
-    /* Save software module in interrupt handler. */
-    _sercom_set_handler(instance_index, _i2c_slave_interrupt_handler);
-
-    /* Save software module. */
-    _sercom_instances[instance_index] = module;
-
-    /* Initialize values in module. */
-    module->registered_callback = 0;
-    module->enabled_callback = 0;
-    module->buffer_length = 0;
-    module->nack_on_address = config->enable_nack_on_address;
-#endif
-
-    /* Set SERCOM module to operate in I2C slave mode. */
-    i2c_hw->CTRLA.reg = SERCOM_I2CS_CTRLA_MODE(0x4);
-
-    /* Set config and return status. */
-    return _i2c_slave_set_config(module, config);
-}
-
-/**
- * \brief Resets the hardware module
- *
- * This will reset the module to hardware defaults.
- *
- * \param[in,out] module  Pointer to software module structure
- */
-void i2c_slave_reset(
-    struct i2c_slave_module *const module)
-{
-    /* Sanity check arguments. */
-    Assert(module);
-    Assert(module->hw);
-
-    SercomI2cs *const i2c_hw = &(module->hw->I2CS);
-
-#if I2C_SLAVE_CALLBACK_MODE == true
-    /* Reset module instance. */
-    module->registered_callback = 0;
-    module->enabled_callback = 0;
-    module->buffer_length = 0;
-    module->buffer_remaining = 0;
-    module->buffer = NULL;
-#endif
-
-    /* Disable module */
-    i2c_slave_disable(module);
-
-#if I2C_SLAVE_CALLBACK_MODE == true
-    /* Clear all pending interrupts. */
-    system_interrupt_enter_critical_section();
-    system_interrupt_clear_pending(_sercom_get_interrupt_vector(module->hw));
-    system_interrupt_leave_critical_section();
-#endif
-
-    /* Wait for sync. */
-    _i2c_slave_wait_for_sync(module);
-
-    /* Reset module. */
-    i2c_hw->CTRLA.reg = SERCOM_I2CS_CTRLA_SWRST;
-}
-
-/**
- * \internal Waits for answer on bus
- *
- * \param[in]  module  Pointer to software module structure
- *
- * \return Status of bus.
- * \retval STATUS_OK           If given response from slave device
- * \retval STATUS_ERR_TIMEOUT  If no response was given within specified timeout
- *                             period
- */
-static enum status_code _i2c_slave_wait_for_bus(
-    struct i2c_slave_module *const module)
-{
-    /* Sanity check arguments. */
-    Assert(module);
-    Assert(module->hw);
-
-    SercomI2cm *const i2c_module = &(module->hw->I2CM);
-
-    /* Wait for reply. */
-    uint16_t timeout_counter = 0;
-    while ((!(i2c_module->INTFLAG.reg & SERCOM_I2CS_INTFLAG_DRDY)) &&
-            (!(i2c_module->INTFLAG.reg & SERCOM_I2CS_INTFLAG_PREC)) &&
-            (!(i2c_module->INTFLAG.reg & SERCOM_I2CS_INTFLAG_AMATCH))) {
-
-        /* Check timeout condition. */
-        if (++timeout_counter >= module->buffer_timeout) {
-            return STATUS_ERR_TIMEOUT;
-        }
-    }
-    return STATUS_OK;
-}
-
-/**
- * \brief Writes a packet to the master
- *
- * Writes a packet to the master. This will wait for the master to issue
- * a request.
- *
- * \param[in]  module  Pointer to software module structure
- * \param[in]  packet  Packet to write to master
- *
- * \return Status of packet write.
- * \retval STATUS_OK                Packet was written successfully
- * \retval STATUS_ERR_DENIED        Start condition not received, another
- *                                  interrupt flag is set
- * \retval STATUS_ERR_IO            There was an error in the previous transfer
- * \retval STATUS_ERR_BAD_FORMAT    Master wants to write data
- * \retval STATUS_ERR_INVALID_ARG   Invalid argument(s) was provided
- * \retval STATUS_ERR_BUSY          The I<SUP>2</SUP>C module is busy with a job
- * \retval STATUS_ERR_ERR_OVERFLOW  Master NACKed before entire packet was
- *                                  transferred
- * \retval STATUS_ERR_TIMEOUT       No response was given within the timeout
- *                                  period
- */
-enum status_code i2c_slave_write_packet_wait(
-    struct i2c_slave_module *const module,
-    struct i2c_slave_packet *const packet)
-{
-    /* Sanity check arguments. */
-    Assert(module);
-    Assert(module->hw);
-    Assert(packet);
-
-    SercomI2cs *const i2c_hw = &(module->hw->I2CS);
-
-    uint16_t length = packet->data_length;
-
-    if (length == 0) {
-        return STATUS_ERR_INVALID_ARG;
-    }
-
-#if I2C_SLAVE_CALLBACK_MODE == true
-    /* Check if the module is busy with a job or AMATCH is enabled */
-    if (module->buffer_remaining > 0 ||
-            (i2c_hw->INTENSET.reg & SERCOM_I2CS_INTFLAG_AMATCH)) {
-        return STATUS_BUSY;
-    }
-#endif
-
-    enum status_code status;
-    /* Wait for master to send address packet */
-    status = _i2c_slave_wait_for_bus(module);
-
-    if (status != STATUS_OK) {
-        /* Timeout, return */
-        return status;
-    }
-    if (!(i2c_hw->INTFLAG.reg & SERCOM_I2CS_INTFLAG_AMATCH)) {
-        /* Not address interrupt, something is wrong */
-        return STATUS_ERR_DENIED;
-    }
-
-    if (module->ten_bit_address) {
-        /* ACK the first address */
-        i2c_hw->CTRLB.reg &= ~SERCOM_I2CS_CTRLB_ACKACT;
-        i2c_hw->CTRLB.reg |= SERCOM_I2CS_CTRLB_CMD(0x3);
-
-        /* Wait for address interrupt */
-        status = _i2c_slave_wait_for_bus(module);
-
-        if (status != STATUS_OK) {
-            /* Timeout, return */
-            return STATUS_ERR_TIMEOUT;
-        }
-
-        if (!(i2c_hw->INTFLAG.reg & SERCOM_I2CS_INTFLAG_AMATCH)) {
-            /* Not address interrupt, something is wrong */
-            return STATUS_ERR_DENIED;
-        }
-    }
-
-    /* Check if there was an error in last transfer */
-    if (i2c_hw->STATUS.reg & (SERCOM_I2CS_STATUS_BUSERR |
-                              SERCOM_I2CS_STATUS_COLL | SERCOM_I2CS_STATUS_LOWTOUT)) {
-        return STATUS_ERR_IO;
-    }
-
-    /* Check direction */
-    if (!(i2c_hw->STATUS.reg & SERCOM_I2CS_STATUS_DIR)) {
-        /* Write request from master, send NACK and return */
-        i2c_hw->CTRLB.reg |= SERCOM_I2CS_CTRLB_ACKACT;
-        i2c_hw->CTRLB.reg |= SERCOM_I2CS_CTRLB_CMD(0x3);
-        return STATUS_ERR_BAD_FORMAT;
-    }
-
-    /* Read request from master, ACK address */
-    i2c_hw->CTRLB.reg &= ~SERCOM_I2CS_CTRLB_ACKACT;
-    i2c_hw->CTRLB.reg |= SERCOM_I2CS_CTRLB_CMD(0x3);
-
-    uint16_t i = 0;
-
-    /* Wait for data interrupt */
-    status = _i2c_slave_wait_for_bus(module);
-    if (status != STATUS_OK) {
-        /* Timeout, return */
-        return status;
-    }
-
-    while (length--) {
-        /* Write data */
-        _i2c_slave_wait_for_sync(module);
-        i2c_hw->DATA.reg = packet->data[i++];
-
-        /* Wait for response from master */
-        status = _i2c_slave_wait_for_bus(module);
-
-        if (status != STATUS_OK) {
-            /* Timeout, return */
-            return status;
-        }
-
-        if (i2c_hw->STATUS.reg & SERCOM_I2CS_STATUS_RXNACK &&
-                length !=0) {
-            /* NACK from master, abort */
-            /* Release line */
-            i2c_hw->CTRLB.reg |= SERCOM_I2CS_CTRLB_CMD(0x02);
-
-            return STATUS_ERR_OVERFLOW;
-        }
-        /* ACK from master, continue writing */
-    }
-
-    /* Release line */
-    i2c_hw->CTRLB.reg |= SERCOM_I2CS_CTRLB_CMD(0x02);
-
-    return STATUS_OK;
-}
-
-/**
- * \brief Reads a packet from the master
- *
- * Reads a packet from the master. This will wait for the master to issue a
- * request.
- *
- * \param[in]  module  Pointer to software module structure
- * \param[out] packet  Packet to read from master
- *
- * \return Status of packet read.
- * \retval STATUS_OK                Packet was read successfully
- * \retval STATUS_ABORTED           Master sent stop condition or repeated
- *                                  start before specified length of bytes
- *                                  was received
- * \retval STATUS_ERR_IO            There was an error in the previous transfer
- * \retval STATUS_ERR_DENIED        Start condition not received, another
- *                                  interrupt flag is set
- * \retval STATUS_ERR_INVALID_ARG   Invalid argument(s) was provided
- * \retval STATUS_ERR_BUSY          The I<SUP>2</SUP>C module is busy with a job
- * \retval STATUS_ERR_BAD_FORMAT    Master wants to read data
- * \retval STATUS_ERR_ERR_OVERFLOW  Last byte received overflows buffer
- */
-enum status_code i2c_slave_read_packet_wait(
-    struct i2c_slave_module *const module,
-    struct i2c_slave_packet *const packet)
-{
-    /* Sanity check arguments. */
-    Assert(module);
-    Assert(module->hw);
-    Assert(packet);
-
-    SercomI2cs *const i2c_hw = &(module->hw->I2CS);
-
-    uint16_t length = packet->data_length;
-
-    if (length == 0) {
-        return STATUS_ERR_INVALID_ARG;
-    }
-
-#if I2C_SLAVE_CALLBACK_MODE == true
-    /* Check if the module is busy with a job or AMATCH is enabled */
-    if (module->buffer_remaining > 0 ||
-            (i2c_hw->INTENSET.reg & SERCOM_I2CS_INTFLAG_AMATCH)) {
-        return STATUS_BUSY;
-    }
-#endif
-
-    enum status_code status;
-
-    /* Wait for master to send address packet */
-    status = _i2c_slave_wait_for_bus(module);
-    if (status != STATUS_OK) {
-        /* Timeout, return */
-        return status;
-    }
-
-    if (!(i2c_hw->INTFLAG.reg & SERCOM_I2CS_INTFLAG_AMATCH)) {
-        /* Not address interrupt, something is wrong */
-        return STATUS_ERR_DENIED;
-    }
-
-    /* Check if there was an error in the last transfer */
-    if (i2c_hw->STATUS.reg & (SERCOM_I2CS_STATUS_BUSERR |
-                              SERCOM_I2CS_STATUS_COLL | SERCOM_I2CS_STATUS_LOWTOUT)) {
-        return STATUS_ERR_IO;
-    }
-    /* Check direction */
-    if ((i2c_hw->STATUS.reg & SERCOM_I2CS_STATUS_DIR)) {
-        /* Read request from master, send NACK and return */
-        i2c_hw->CTRLB.reg |= SERCOM_I2CS_CTRLB_ACKACT;
-        i2c_hw->CTRLB.reg |= SERCOM_I2CS_CTRLB_CMD(0x3);
-        return STATUS_ERR_BAD_FORMAT;
-    }
-
-    /* Write request from master, ACK address */
-    i2c_hw->CTRLB.reg &= ~SERCOM_I2CS_CTRLB_ACKACT;
-    i2c_hw->CTRLB.reg |= SERCOM_I2CS_CTRLB_CMD(0x3);
-
-    uint16_t i = 0;
-    while (length--) {
-
-        /* Wait for next byte or stop condition */
-        status = _i2c_slave_wait_for_bus(module);
-        if (status != STATUS_OK) {
-            /* Timeout, return */
-            return status;
-        }
-
-        if ((i2c_hw->INTFLAG.reg & SERCOM_I2CS_INTFLAG_PREC) ||
-                i2c_hw->INTFLAG.reg & SERCOM_I2CS_INTFLAG_AMATCH) {
-            /* Master sent stop condition, or repeated start, read done */
-            /* Clear stop flag */
-            i2c_hw->INTFLAG.reg = SERCOM_I2CS_INTFLAG_PREC;
-            return STATUS_ABORTED;
-        }
-
-        /* Read data */
-        _i2c_slave_wait_for_sync(module);
-        packet->data[i++] = i2c_hw->DATA.reg;
-
-    }
-
-    /* Packet read done, wait for packet to NACK, Stop or repeated start */
-    status = _i2c_slave_wait_for_bus(module);
-
-    if (i2c_hw->INTFLAG.reg & SERCOM_I2CS_INTFLAG_DRDY) {
-        /* Buffer is full, send NACK */
-        i2c_hw->CTRLB.reg |= SERCOM_I2CS_CTRLB_ACKACT;
-        i2c_hw->CTRLB.reg |= SERCOM_I2CS_CTRLB_CMD(0x2);
-    }
-    if (i2c_hw->INTFLAG.reg & SERCOM_I2CS_INTFLAG_PREC) {
-        /* Clear stop flag */
-        i2c_hw->INTFLAG.reg = SERCOM_I2CS_INTFLAG_PREC;
-    }
-    return STATUS_OK;
-}
-
-/**
- * \brief 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 that this function does not check for errors in the last transfer,
- * this will be discovered when reading or writing.
- *
- * \param[in]  module  Pointer to software module structure
- *
- * \return Direction of the current transfer, when in slave mode.
- * \retval I2C_SLAVE_DIRECTION_NONE   No request from master within timeout
- *                                    period
- * \retval I2C_SLAVE_DIRECTION_READ   Write request from master
- * \retval I2C_SLAVE_DIRECTION_WRITE  Read request from master
- */
-enum i2c_slave_direction i2c_slave_get_direction_wait(
-    struct i2c_slave_module *const module)
-{
-    /* Sanity check arguments. */
-    Assert(module);
-    Assert(module->hw);
-
-    SercomI2cs *const i2c_hw = &(module->hw->I2CS);
-
-    enum status_code status;
-
-    /* Wait for address interrupt */
-    status = _i2c_slave_wait_for_bus(module);
-
-    if (status != STATUS_OK) {
-        /* Timeout, return */
-        return I2C_SLAVE_DIRECTION_NONE;
-    }
-
-    if (!(i2c_hw->INTFLAG.reg & SERCOM_I2CS_INTFLAG_AMATCH)) {
-        /* Not address interrupt, something is wrong */
-        return I2C_SLAVE_DIRECTION_NONE;
-    }
-
-    /* Check direction */
-    if ((i2c_hw->STATUS.reg & SERCOM_I2CS_STATUS_DIR)) {
-        /* Read request from master */
-        return I2C_SLAVE_DIRECTION_WRITE;
-    } else {
-        /* Write request from master */
-        return I2C_SLAVE_DIRECTION_READ;
-    }
-}
-
-/**
- * \brief Retrieves the current module status
- *
- * Checks the status of the module and returns it as a bitmask of status
- * flags.
- *
- * \param[in] module      Pointer to the I<SUP>2</SUP>C slave software device struct
- *
- * \return Bitmask of status flags.
- *
- * \retval I2C_SLAVE_STATUS_ADDRESS_MATCH   A valid address has been received
- * \retval I2C_SLAVE_STATUS_DATA_READY      A I<SUP>2</SUP>C slave byte transmission is
- *                                          successfully completed
- * \retval I2C_SLAVE_STATUS_STOP_RECEIVED   A stop condition is detected for a
- *                                          transaction being processed
- * \retval I2C_SLAVE_STATUS_CLOCK_HOLD      The slave is holding the SCL line
- *                                          low
- * \retval I2C_SLAVE_STATUS_SCL_LOW_TIMEOUT An SCL low time-out has occurred
- * \retval I2C_SLAVE_STATUS_REPEATED_START  Indicates a repeated start, only
- *                                          valid if \ref
- *                                          I2C_SLAVE_STATUS_ADDRESS_MATCH is
- *                                          set
- * \retval I2C_SLAVE_STATUS_RECEIVED_NACK   The last data packet sent was not
- *                                          acknowledged
- * \retval I2C_SLAVE_STATUS_COLLISION       The I<SUP>2</SUP>C slave was not able to
- *                                          transmit a high data or NACK bit
- * \retval I2C_SLAVE_STATUS_BUS_ERROR       An illegal bus condition has
- *                                          occurred on the bus
- */
-uint32_t i2c_slave_get_status(
-    struct i2c_slave_module *const module)
-{
-    /* Sanity check arguments */
-    Assert(module);
-    Assert(module->hw);
-
-    SercomI2cs *const i2c_hw = &(module->hw->I2CS);
-
-    uint8_t intflags = i2c_hw->INTFLAG.reg;
-    uint8_t status = i2c_hw->STATUS.reg;
-    uint32_t status_flags = 0;
-
-    /* Check Address Match flag */
-    if (intflags & SERCOM_I2CS_INTFLAG_AMATCH) {
-        status_flags |= I2C_SLAVE_STATUS_ADDRESS_MATCH;
-    }
-    /* Check Data Ready flag */
-    if (intflags & SERCOM_I2CS_INTFLAG_DRDY) {
-        status_flags |= I2C_SLAVE_STATUS_DATA_READY;
-    }
-    /* Check Stop flag */
-    if (intflags & SERCOM_I2CS_INTFLAG_PREC) {
-        status_flags |= I2C_SLAVE_STATUS_STOP_RECEIVED;
-    }
-    /* Check Clock Hold */
-    if (status & SERCOM_I2CS_STATUS_CLKHOLD) {
-        status_flags |= I2C_SLAVE_STATUS_CLOCK_HOLD;
-    }
-    /* Check SCL Low Timeout */
-    if (status & SERCOM_I2CS_STATUS_LOWTOUT) {
-        status_flags |= I2C_SLAVE_STATUS_SCL_LOW_TIMEOUT;
-    }
-    /* Check Repeated Start */
-    if (status & SERCOM_I2CS_STATUS_SR) {
-        status_flags |= I2C_SLAVE_STATUS_REPEATED_START;
-    }
-    /* Check Received Not Acknowledge */
-    if (status & SERCOM_I2CS_STATUS_RXNACK) {
-        status_flags |= I2C_SLAVE_STATUS_RECEIVED_NACK;
-    }
-    /* Check Transmit Collision */
-    if (status & SERCOM_I2CS_STATUS_COLL) {
-        status_flags |= I2C_SLAVE_STATUS_COLLISION;
-    }
-    /* Check Bus Error */
-    if (status & SERCOM_I2CS_STATUS_BUSERR) {
-        status_flags |= I2C_SLAVE_STATUS_BUS_ERROR;
-    }
-
-    return status_flags;
-}
-
-/**
- * \brief Clears a module status flag
- *
- * Clears the given status flag of the module.
- *
- * \note Not all status flags can be cleared.
- *
- * \param[in] module         Pointer to the I<SUP>2</SUP>C software device struct
- * \param[in] status_flags   Bit mask of status flags to clear
- *
- */
-void i2c_slave_clear_status(
-    struct i2c_slave_module *const module,
-    uint32_t status_flags)
-{
-    /* Sanity check arguments */
-    Assert(module);
-    Assert(module->hw);
-
-    SercomI2cs *const i2c_hw = &(module->hw->I2CS);
-
-    /* Clear Address Match flag */
-    if (status_flags & I2C_SLAVE_STATUS_ADDRESS_MATCH) {
-        i2c_hw->INTFLAG.reg = SERCOM_I2CS_INTFLAG_AMATCH;
-    }
-    /* Clear Data Ready flag */
-    if (status_flags & I2C_SLAVE_STATUS_DATA_READY) {
-        i2c_hw->INTFLAG.reg = SERCOM_I2CS_INTFLAG_DRDY;
-    }
-    /* Clear Stop flag */
-    if (status_flags & I2C_SLAVE_STATUS_STOP_RECEIVED) {
-        i2c_hw->INTFLAG.reg = SERCOM_I2CS_INTFLAG_PREC;
-    }
-    /* Clear SCL Low Timeout */
-    if (status_flags & I2C_SLAVE_STATUS_SCL_LOW_TIMEOUT) {
-        i2c_hw->STATUS.reg = SERCOM_I2CS_STATUS_LOWTOUT;
-    }
-    /* Clear Transmit Collision */
-    if (status_flags & I2C_SLAVE_STATUS_COLLISION) {
-        i2c_hw->STATUS.reg = SERCOM_I2CS_STATUS_COLL;
-    }
-    /* Clear Bus Error */
-    if (status_flags & I2C_SLAVE_STATUS_BUS_ERROR) {
-        i2c_hw->STATUS.reg = SERCOM_I2CS_STATUS_BUSERR;
-    }
-}