The official Mbed 2 C/C++ SDK provides the software platform and libraries to build your applications.
Dependents: hello SerialTestv11 SerialTestv12 Sierpinski ... more
mbed 2
This is the mbed 2 library. If you'd like to learn about Mbed OS please see the mbed-os docs.
Diff: TARGET_SAMD21G18A/TOOLCHAIN_ARM_STD/i2c_slave.h
- Revision:
- 171:3a7713b1edbc
- Parent:
- 111:4336505e4b1c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TARGET_SAMD21G18A/TOOLCHAIN_ARM_STD/i2c_slave.h Thu Nov 08 11:45:42 2018 +0000 @@ -0,0 +1,749 @@ +/** + * \file + * + * \brief SAM SERCOM I2C Slave Driver + * + * Copyright (c) 2013-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a> + */ + +#ifndef I2C_SLAVE_H_INCLUDED +#define I2C_SLAVE_H_INCLUDED + +#include "i2c_common.h" +#include <sercom.h> +#include <pinmux.h> + +#if I2C_SLAVE_CALLBACK_MODE == true +# include <sercom_interrupt.h> +#endif + +#ifndef PINMUX_DEFAULT +# define PINMUX_DEFAULT 0 +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup asfdoc_sam0_sercom_i2c_group + * + * @{ + * + */ + +/** + * \name I2C Slave Status Flags + * + * I<SUP>2</SUP>C slave status flags, returned by \ref i2c_slave_get_status() and cleared + * by \ref i2c_slave_clear_status(). + * @{ + */ + +/** Address Match. + * \note Should only be cleared internally by driver. + */ +#define I2C_SLAVE_STATUS_ADDRESS_MATCH (1UL << 0) +/** Data Ready. */ +#define I2C_SLAVE_STATUS_DATA_READY (1UL << 1) +/** Stop Received. */ +#define I2C_SLAVE_STATUS_STOP_RECEIVED (1UL << 2) +/** Clock Hold. + * \note Cannot be cleared, only valid when I2C_SLAVE_STATUS_ADDRESS_MATCH is + * set. + */ +#define I2C_SLAVE_STATUS_CLOCK_HOLD (1UL << 3) +/** SCL Low Timeout. */ +#define I2C_SLAVE_STATUS_SCL_LOW_TIMEOUT (1UL << 4) +/** Repeated Start. + * \note Cannot be cleared, only valid when I2C_SLAVE_STATUS_ADDRESS_MATCH is + * set. + */ +#define I2C_SLAVE_STATUS_REPEATED_START (1UL << 5) +/** Received not acknowledge. + * \note Cannot be cleared. + */ +#define I2C_SLAVE_STATUS_RECEIVED_NACK (1UL << 6) +/** Transmit Collision. */ +#define I2C_SLAVE_STATUS_COLLISION (1UL << 7) +/** Bus error. */ +#define I2C_SLAVE_STATUS_BUS_ERROR (1UL << 8) + +/** @} */ + +/** + * \brief I<SUP>2</SUP>C slave packet for read/write + * + * Structure to be used when transferring I<SUP>2</SUP>C slave packets. + */ +struct i2c_slave_packet { + /** Length of data array. */ + uint16_t data_length; + /** Data array containing all data to be transferred. */ + uint8_t *data; +}; + +#if I2C_SLAVE_CALLBACK_MODE == true +/** +* \brief Callback types +* +* The available callback types for the I<SUP>2</SUP>C slave. +*/ +enum i2c_slave_callback { + /** Callback for packet write complete. */ + I2C_SLAVE_CALLBACK_WRITE_COMPLETE, + /** Callback for packet read complete. */ + I2C_SLAVE_CALLBACK_READ_COMPLETE, + /** + * Callback for read request from master - can be used to + * issue a write. + */ + I2C_SLAVE_CALLBACK_READ_REQUEST, + /** + * Callback for write request from master - can be used to issue a read. + */ + I2C_SLAVE_CALLBACK_WRITE_REQUEST, + /** Callback for error. */ + I2C_SLAVE_CALLBACK_ERROR, + /** + * Callback for error in last transfer. Discovered on a new address + * interrupt. + */ + I2C_SLAVE_CALLBACK_ERROR_LAST_TRANSFER, +# if !defined(__DOXYGEN__) + /** Total number of callbacks. */ + _I2C_SLAVE_CALLBACK_N, +# endif +}; + +# if !defined(__DOXYGEN__) +/** Software module prototype. */ +struct i2c_slave_module; + +/** Callback type. */ +typedef void (*i2c_slave_callback_t)( + struct i2c_slave_module *const module); +# endif +#endif + +/** + * \brief Enum for the possible SDA hold times with respect to the negative + * edge of SCL + * + * Enum for the possible SDA hold times with respect to the negative edge + * of SCL. + */ +enum i2c_slave_sda_hold_time { + /** SDA hold time disabled. */ + I2C_SLAVE_SDA_HOLD_TIME_DISABLED = + ((SERCOM_I2CS_CTRLA_SDAHOLD_Msk & ((0) << SERCOM_I2CS_CTRLA_SDAHOLD_Pos))), + /** SDA hold time 50ns - 100ns. */ + I2C_SLAVE_SDA_HOLD_TIME_50NS_100NS = + ((SERCOM_I2CS_CTRLA_SDAHOLD_Msk & ((1) << SERCOM_I2CS_CTRLA_SDAHOLD_Pos))), + /** SDA hold time 300ns - 600ns. */ + I2C_SLAVE_SDA_HOLD_TIME_300NS_600NS = + ((SERCOM_I2CS_CTRLA_SDAHOLD_Msk & ((2) << SERCOM_I2CS_CTRLA_SDAHOLD_Pos))), + /** SDA hold time 400ns - 800ns. */ + I2C_SLAVE_SDA_HOLD_TIME_400NS_800NS = + ((SERCOM_I2CS_CTRLA_SDAHOLD_Msk & ((3) << SERCOM_I2CS_CTRLA_SDAHOLD_Pos))), +}; + +/** + * \brief Enum for the possible address modes + * + * Enum for the possible address modes. + */ +enum i2c_slave_address_mode { + /** Address match on address_mask used as a mask to address. */ + I2C_SLAVE_ADDRESS_MODE_MASK = SERCOM_I2CS_CTRLB_AMODE(0), + /** Address math on both address and address_mask. */ + I2C_SLAVE_ADDRESS_MODE_TWO_ADDRESSES = SERCOM_I2CS_CTRLB_AMODE(1), + /** + * Address match on range of addresses between and including address and + * address_mask. + */ + I2C_SLAVE_ADDRESS_MODE_RANGE = SERCOM_I2CS_CTRLB_AMODE(2), +}; + +/** + * \brief Enum for the direction of a request + * + * Enum for the direction of a request. + */ +enum i2c_slave_direction { + /** Read. */ + I2C_SLAVE_DIRECTION_READ, + /** Write. */ + I2C_SLAVE_DIRECTION_WRITE, + /** No direction. */ + I2C_SLAVE_DIRECTION_NONE, +}; + +#ifdef FEATURE_I2C_FAST_MODE_PLUS_AND_HIGH_SPEED +/** + * \brief Enum for the transfer speed + * + * Enum for the transfer speed. + */ +enum i2c_slave_transfer_speed { + /** Standard-mode (Sm) up to 100KHz and Fast-mode (Fm) up to 400KHz. */ + I2C_SLAVE_SPEED_STANDARD_AND_FAST = SERCOM_I2CS_CTRLA_SPEED(0), + /** Fast-mode Plus (Fm+) up to 1MHz. */ + I2C_SLAVE_SPEED_FAST_MODE_PLUS = SERCOM_I2CS_CTRLA_SPEED(1), + /** High-speed mode (Hs-mode) up to 3.4MHz. */ + I2C_SLAVE_SPEED_HIGH_SPEED = SERCOM_I2CS_CTRLA_SPEED(2), +}; +#endif + +/** + * \brief SERCOM I<SUP>2</SUP>C Slave driver software device instance structure. + * + * SERCOM I<SUP>2</SUP>C Slave driver software instance structure, used to + * retain software state information of an associated hardware module instance. + * + * \note The fields of this structure should not be altered by the user + * application; they are reserved for module-internal use only. + */ +struct i2c_slave_module { +#if !defined(__DOXYGEN__) + /** Hardware instance initialized for the struct. */ + Sercom *hw; + /** Module lock. */ + volatile bool locked; + /** Timeout value for polled functions. */ + uint16_t buffer_timeout; +# ifdef FEATURE_I2C_10_BIT_ADDRESS + /** Using 10-bit addressing for the slave. */ + bool ten_bit_address; +# endif +# if I2C_SLAVE_CALLBACK_MODE == true + /** Nack on address match. */ + bool nack_on_address; + /** Pointers to callback functions. */ + volatile i2c_slave_callback_t callbacks[_I2C_SLAVE_CALLBACK_N]; + /** Mask for registered callbacks. */ + volatile uint8_t registered_callback; + /** Mask for enabled callbacks. */ + volatile uint8_t enabled_callback; + /** The total number of bytes to transfer. */ + volatile uint16_t buffer_length; + /** + * Counter used for bytes left to send in write and to count number of + * obtained bytes in read. + */ + uint16_t buffer_remaining; + /** Data buffer for packet write and read. */ + volatile uint8_t *buffer; + /** Save direction of request from master. 1 = read, 0 = write. */ + volatile enum i2c_transfer_direction transfer_direction; + /** Status for status read back in error callback. */ + volatile enum status_code status; +# endif +#endif +}; + +/** + * \brief Configuration structure for the I<SUP>2</SUP>C Slave device + * + * This is the configuration structure for the I<SUP>2</SUP>C Slave device. It is used + * as an argument for \ref i2c_slave_init to provide the desired + * configurations for the module. The structure should be initialized using the + * \ref i2c_slave_get_config_defaults. + */ +struct i2c_slave_config { + /** Set to enable the SCL low timeout. */ + bool enable_scl_low_timeout; + /** SDA hold time with respect to the negative edge of SCL. */ + enum i2c_slave_sda_hold_time sda_hold_time; + /** Timeout to wait for master in polled functions. */ + uint16_t buffer_timeout; + /** Addressing mode. */ + enum i2c_slave_address_mode address_mode; + /** Address or upper limit of address range. */ + uint16_t address; + /** Address mask, second address or lower limit of address range. */ + uint16_t address_mask; +#ifdef FEATURE_I2C_10_BIT_ADDRESS + /** Enable 10-bit addressing. */ + bool ten_bit_address; +#endif + /** + * Enable general call address recognition (general call address + * is defined as 0000000 with direction bit 0). + */ + bool enable_general_call_address; + +#ifdef FEATURE_I2C_FAST_MODE_PLUS_AND_HIGH_SPEED + /** Transfer speed mode. */ + enum i2c_slave_transfer_speed transfer_speed; +#endif + +#if I2C_SLAVE_CALLBACK_MODE == true + /** + * Enable NACK on address match (this can be changed after initialization + * via the \ref i2c_slave_enable_nack_on_address and + * \ref i2c_slave_disable_nack_on_address functions). + */ + bool enable_nack_on_address; +#endif + /** GCLK generator to use as clock source. */ + enum gclk_generator generator_source; + /** Set to keep module active in sleep modes. */ + bool run_in_standby; + /** PAD0 (SDA) pinmux. */ + uint32_t pinmux_pad0; + /** PAD1 (SCL) pinmux. */ + uint32_t pinmux_pad1; + /** Set to enable SCL low time-out. */ + bool scl_low_timeout; +#ifdef FEATURE_I2C_SCL_STRETCH_MODE + /** Set to enable SCL stretch only after ACK bit (required for high speed). */ + bool scl_stretch_only_after_ack_bit; +#endif +#ifdef FEATURE_I2C_SCL_EXTEND_TIMEOUT + /** Set to enable slave SCL low extend time-out. */ + bool slave_scl_low_extend_timeout; +#endif +}; + + +/** + * \name Lock/Unlock + * @{ + */ + +/** + * \brief Attempt to get lock on driver instance + * + * This function checks the instance's lock, which indicates whether or not it + * is currently in use, and sets the lock if it was not already set. + * + * The purpose of this is to enable exclusive access to driver instances, so + * that, e.g., transactions by different services will not interfere with each + * other. + * + * \param[in,out] module Pointer to the driver instance to lock + * + * \retval STATUS_OK If the module was locked + * \retval STATUS_BUSY If the module was already locked + */ +static inline enum status_code i2c_slave_lock( + struct i2c_slave_module *const module) +{ + enum status_code status; + + system_interrupt_enter_critical_section(); + + if (module->locked) { + status = STATUS_BUSY; + } else { + module->locked = true; + status = STATUS_OK; + } + + system_interrupt_leave_critical_section(); + + return status; +} + +/** + * \brief Unlock driver instance + * + * This function clears the instance lock, indicating that it is available for + * use. + * + * \param[in,out] module Pointer to the driver instance to lock + * + * \retval STATUS_OK If the module was locked + * \retval STATUS_BUSY If the module was already locked + */ +static inline void i2c_slave_unlock(struct i2c_slave_module *const module) +{ + module->locked = false; +} + +/** @} */ + +/** + * \name Configuration and Initialization + * @{ + */ + +/** + * \brief Returns the synchronization status of the module + * + * Returns the synchronization status of the module. + * + * \param[out] module Pointer to software module structure + * + * \return Status of the synchronization. + * \retval true Module is busy synchronizing + * \retval false Module is not synchronizing + */ +static inline bool i2c_slave_is_syncing( + const struct i2c_slave_module *const module) +{ + /* Sanity check */ + Assert(module); + Assert(module->hw); + + SercomI2cs *const i2c_hw = &(module->hw->I2CS); + + /* Return sync status */ +#if defined(FEATURE_SERCOM_SYNCBUSY_SCHEME_VERSION_1) + return (i2c_hw->STATUS.reg & SERCOM_I2CS_STATUS_SYNCBUSY); +#elif defined(FEATURE_SERCOM_SYNCBUSY_SCHEME_VERSION_2) + return (i2c_hw->SYNCBUSY.reg & SERCOM_I2CS_SYNCBUSY_MASK); +#else +# error Unknown SERCOM SYNCBUSY scheme! +#endif +} + +#if !defined(__DOXYGEN__) +/** + * \internal Wait for hardware module to sync + * + * \param[in] module Pointer to software module structure + */ +static void _i2c_slave_wait_for_sync( + const struct i2c_slave_module *const module) +{ + /* Sanity check. */ + Assert(module); + + while (i2c_slave_is_syncing(module)) { + /* Wait for I2C module to sync */ + } +} +#endif + +///@cond INTERNAL +/** + * \internal Workaround for errata 13574 + * Instead set ACK/NACK of CTRLB + * + * This errata exist in part revisions of SAMD20/D21 + * D10/D11/L21/DAx/C20/C21, but workaround can be works in all + * revision of those device. As this function operation + * should be use less cpu time as possible, so caller + * function can ignore to check revision number, and use + * this workaround in all revision of those device. + * + * \param[in,out] module Pointer to software module structure + * \param[in] send_ack true send ACK, false send NACK + */ +static inline void _i2c_slave_set_ctrlb_ackact( + struct i2c_slave_module *const module, + bool send_ack) +{ + Assert(module); + Assert(module->hw); + + SercomI2cs *const i2c_hw = &(module->hw->I2CS); + +#if (SAMD20 || SAMD21 || SAMD10 || SAMD11 || SAML21 || SAMDA1 || SAMC20 || SAMC21) + /* Workaround, Following two write are atomic */ + system_interrupt_enter_critical_section(); + i2c_hw->STATUS.reg = 0; + + if (send_ack == true) { + i2c_hw->CTRLB.reg = 0; + } else { + i2c_hw->CTRLB.reg = SERCOM_I2CS_CTRLB_ACKACT; + } + system_interrupt_leave_critical_section(); +#else + /* Normal operation */ + if (send_ack == true) { + i2c_hw->CTRLB.reg &= ~SERCOM_I2CS_CTRLB_ACKACT; + } else { + i2c_hw->CTRLB.reg |= SERCOM_I2CS_CTRLB_ACKACT; + } +#endif + return; +} + +/** + * \internal Workaround for SAM0 errata 13574, + * instead Set CMD3 of CTRLB + * + * This errata exist in part revisions of SAMD20/D21 + * D10/D11/L21/DAx/C20/C21, but workaround can be works in all + * revision of those device. As this function operation + * should be use less cpu time as possible, so caller + * function can ignore to check revision number, and use + * this workaround in all revision of those device. + * + * \param[in,out] module Pointer to software module structure + */ +static inline void _i2c_slave_set_ctrlb_cmd3( + struct i2c_slave_module *const module) +{ + Assert(module); + Assert(module->hw); + + SercomI2cs *const i2c_hw = &(module->hw->I2CS); + +#if (SAMD20 || SAMD21 || SAMD10 || SAMD11 || SAML21 || SAMDA1 || SAMC20 || SAMC21) + /* Workaround */ + /* + * Below code instead i2c_hw->CTRLB.reg = SERCOM_I2CS_CTRLB_CMD(0x3); + * CMD=0x3 clears all interrupts, so to keep the result similar + * PREC is cleared if it was set + */ + if (i2c_hw->INTFLAG.bit.PREC) { + i2c_hw->INTFLAG.reg = SERCOM_I2CS_INTFLAG_PREC; + } + i2c_hw->INTFLAG.reg = SERCOM_I2CS_INTFLAG_AMATCH; +#else + /* Normal operation */ + i2c_hw->CTRLB.reg = SERCOM_I2CS_CTRLB_CMD(0x3); +#endif + return; +} +///@endcond + +/** + * \brief Gets the I<SUP>2</SUP>C slave default configurations + * + * This will initialize the configuration structure to known default values. + * + * The default configuration is as follows: + * - Disable SCL low timeout + * - 300ns - 600ns SDA hold time + * - Buffer timeout = 65535 + * - Address with mask + * - Address = 0 + * - Address mask = 0 (one single address) + * - General call address disabled + * - Address nack disabled if the interrupt driver is used + * - GCLK generator 0 + * - Do not run in standby + * - PINMUX_DEFAULT for SERCOM pads + * + * Those default configuration only available if the device supports it: + * - Not using 10-bit addressing + * - Standard-mode and Fast-mode transfer speed + * - SCL stretch disabled + * - slave SCL low extend time-out disabled + * + * \param[out] config Pointer to configuration structure to be initialized + */ +static inline void i2c_slave_get_config_defaults( + struct i2c_slave_config *const config) +{ + /*Sanity check argument. */ + Assert(config); + config->enable_scl_low_timeout = false; + config->sda_hold_time = I2C_SLAVE_SDA_HOLD_TIME_300NS_600NS; + config->buffer_timeout = 65535; + config->address_mode = I2C_SLAVE_ADDRESS_MODE_MASK; + config->address = 0; + config->address_mask = 0; +#ifdef FEATURE_I2C_10_BIT_ADDRESS + config->ten_bit_address = false; +#endif + config->enable_general_call_address = false; +#ifdef FEATURE_I2C_FAST_MODE_PLUS_AND_HIGH_SPEED + config->transfer_speed = I2C_SLAVE_SPEED_STANDARD_AND_FAST; +#endif +#if I2C_SLAVE_CALLBACK_MODE == true + config->enable_nack_on_address = false; +#endif + config->generator_source = GCLK_GENERATOR_0; + config->run_in_standby = false; + config->pinmux_pad0 = PINMUX_DEFAULT; + config->pinmux_pad1 = PINMUX_DEFAULT; + config->scl_low_timeout = false; +#ifdef FEATURE_I2C_SCL_STRETCH_MODE + config->scl_stretch_only_after_ack_bit = false; +#endif +#ifdef FEATURE_I2C_SCL_EXTEND_TIMEOUT + config->slave_scl_low_extend_timeout = false; +#endif +} + +enum status_code i2c_slave_init(struct i2c_slave_module *const module, + Sercom *const hw, + const struct i2c_slave_config *const config); + +/** + * \brief Enables the I<SUP>2</SUP>C module + * + * This will enable the requested I<SUP>2</SUP>C module. + * + * \param[in] module Pointer to the software module struct + */ +static inline void i2c_slave_enable( + const struct i2c_slave_module *const module) +{ + /* Sanity check of arguments. */ + Assert(module); + Assert(module->hw); + + SercomI2cs *const i2c_hw = &(module->hw->I2CS); + +#if I2C_SLAVE_CALLBACK_MODE == true + /* Enable global interrupt for module */ + system_interrupt_enable(_sercom_get_interrupt_vector(module->hw)); +#endif + + /* Wait for module to sync */ + _i2c_slave_wait_for_sync(module); + + /* Enable module */ + i2c_hw->CTRLA.reg |= SERCOM_I2CS_CTRLA_ENABLE; +} + + +/** + * \brief Disables the I<SUP>2</SUP>C module + * + * This will disable the I<SUP>2</SUP>C module specified in the provided software module + * structure. + * + * \param[in] module Pointer to the software module struct + */ +static inline void i2c_slave_disable( + const struct i2c_slave_module *const module) +{ + /* Sanity check of arguments. */ + Assert(module); + Assert(module->hw); + + SercomI2cs *const i2c_hw = &(module->hw->I2CS); + +#if I2C_SLAVE_CALLBACK_MODE == true + /* Disable interrupts */ + i2c_hw->INTENCLR.reg = SERCOM_I2CS_INTENSET_PREC | + SERCOM_I2CS_INTENSET_AMATCH | SERCOM_I2CS_INTENSET_DRDY; + + /* Clear interrupt flags */ + i2c_hw->INTFLAG.reg = SERCOM_I2CS_INTFLAG_PREC | SERCOM_I2CS_INTFLAG_AMATCH | + SERCOM_I2CS_INTFLAG_DRDY; + + /* Disable global interrupt for module */ + system_interrupt_disable(_sercom_get_interrupt_vector(module->hw)); +#endif + + /* Wait for module to sync */ + _i2c_slave_wait_for_sync(module); + + /* Disable module */ + i2c_hw->CTRLA.reg &= ~SERCOM_I2CS_CTRLA_ENABLE; +} + +void i2c_slave_reset( + struct i2c_slave_module *const module); + +/** @} */ + +/** + * \name Read and Write + * @{ + */ + +enum status_code i2c_slave_write_packet_wait( + struct i2c_slave_module *const module, + struct i2c_slave_packet *const packet); +enum status_code i2c_slave_read_packet_wait( + struct i2c_slave_module *const module, + struct i2c_slave_packet *const packet); +enum i2c_slave_direction i2c_slave_get_direction_wait( + struct i2c_slave_module *const module); + +/** @} */ + +/** + * \name Status Management + * @{ + */ +uint32_t i2c_slave_get_status( + struct i2c_slave_module *const module); +void i2c_slave_clear_status( + struct i2c_slave_module *const module, + uint32_t status_flags); +/** @} */ + +#ifdef FEATURE_I2C_DMA_SUPPORT +/** + * \name SERCOM I2C Slave with DMA Interfaces + * @{ + */ + +/** + * \brief Read SERCOM I<SUP>2</SUP>C interrupt status. + * + * Read I<SUP>2</SUP>C interrupt status for DMA transfer. + * + * \param[in,out] module Pointer to the driver instance to lock + * + */ +static inline uint8_t i2c_slave_dma_read_interrupt_status(struct i2c_slave_module *const module) +{ + return (uint8_t)module->hw->I2CS.INTFLAG.reg; +} + +/** + * \brief Write SERCOM I<SUP>2</SUP>C interrupt status. + * + * Write I<SUP>2</SUP>C interrupt status for DMA transfer. + * + * \param[in,out] module Pointer to the driver instance to lock + * \param[in] flag Interrupt flag status + * + */ +static inline void i2c_slave_dma_write_interrupt_status(struct i2c_slave_module *const module, + uint8_t flag) +{ + module->hw->I2CS.INTFLAG.reg = flag; +} + +/** @} */ +#endif + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* I2C_SLAVE_H_INCLUDED */