mbed library sources

Fork of mbed-src by mbed official

Revision:
613:bc40b8d2aec4
Parent:
612:fba1c7dc54c0
Child:
614:9d86c2ae5de0
--- a/targets/hal/TARGET_Atmel/TARGET_SAM21/drivers/sercom/i2c/i2c_slave.h	Tue Aug 18 15:00:09 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,617 +0,0 @@
-#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
-
-/**
- * \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 availale 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 */