mbed library sources

Fork of mbed-src by mbed official

Committer:
mbed_official
Date:
Fri Jul 17 09:15:10 2015 +0100
Revision:
592:a274ee790e56
Parent:
579:53297373a894
Synchronized with git revision e7144f83a8d75df80c4877936b6ffe552b0be9e6

Full URL: https://github.com/mbedmicro/mbed/commit/e7144f83a8d75df80c4877936b6ffe552b0be9e6/

More API implementation for SAMR21

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 579:53297373a894 1 #ifndef I2C_SLAVE_H_INCLUDED
mbed_official 579:53297373a894 2 #define I2C_SLAVE_H_INCLUDED
mbed_official 579:53297373a894 3
mbed_official 579:53297373a894 4 #include "i2c_common.h"
mbed_official 579:53297373a894 5 #include <sercom.h>
mbed_official 579:53297373a894 6 #include <pinmux.h>
mbed_official 579:53297373a894 7
mbed_official 579:53297373a894 8 #if I2C_SLAVE_CALLBACK_MODE == true
mbed_official 579:53297373a894 9 # include <sercom_interrupt.h>
mbed_official 579:53297373a894 10 #endif
mbed_official 579:53297373a894 11
mbed_official 579:53297373a894 12 #ifndef PINMUX_DEFAULT
mbed_official 579:53297373a894 13 # define PINMUX_DEFAULT 0
mbed_official 579:53297373a894 14 #endif
mbed_official 579:53297373a894 15
mbed_official 579:53297373a894 16 #ifdef __cplusplus
mbed_official 579:53297373a894 17 extern "C" {
mbed_official 579:53297373a894 18 #endif
mbed_official 579:53297373a894 19
mbed_official 579:53297373a894 20 /**
mbed_official 579:53297373a894 21 * \addtogroup asfdoc_sam0_sercom_i2c_group
mbed_official 579:53297373a894 22 *
mbed_official 579:53297373a894 23 * @{
mbed_official 579:53297373a894 24 *
mbed_official 579:53297373a894 25 */
mbed_official 579:53297373a894 26
mbed_official 579:53297373a894 27 /**
mbed_official 579:53297373a894 28 * \name I2C Slave Status Flags
mbed_official 579:53297373a894 29 *
mbed_official 579:53297373a894 30 * I<SUP>2</SUP>C slave status flags, returned by \ref i2c_slave_get_status() and cleared
mbed_official 579:53297373a894 31 * by \ref i2c_slave_clear_status().
mbed_official 579:53297373a894 32 * @{
mbed_official 579:53297373a894 33 */
mbed_official 579:53297373a894 34
mbed_official 579:53297373a894 35 /** Address Match.
mbed_official 579:53297373a894 36 * \note Should only be cleared internally by driver.
mbed_official 579:53297373a894 37 */
mbed_official 579:53297373a894 38 #define I2C_SLAVE_STATUS_ADDRESS_MATCH (1UL << 0)
mbed_official 579:53297373a894 39 /** Data Ready. */
mbed_official 579:53297373a894 40 #define I2C_SLAVE_STATUS_DATA_READY (1UL << 1)
mbed_official 579:53297373a894 41 /** Stop Received. */
mbed_official 579:53297373a894 42 #define I2C_SLAVE_STATUS_STOP_RECEIVED (1UL << 2)
mbed_official 579:53297373a894 43 /** Clock Hold.
mbed_official 579:53297373a894 44 * \note Cannot be cleared, only valid when I2C_SLAVE_STATUS_ADDRESS_MATCH is
mbed_official 579:53297373a894 45 * set.
mbed_official 579:53297373a894 46 */
mbed_official 579:53297373a894 47 #define I2C_SLAVE_STATUS_CLOCK_HOLD (1UL << 3)
mbed_official 579:53297373a894 48 /** SCL Low Timeout. */
mbed_official 579:53297373a894 49 #define I2C_SLAVE_STATUS_SCL_LOW_TIMEOUT (1UL << 4)
mbed_official 579:53297373a894 50 /** Repeated Start.
mbed_official 579:53297373a894 51 * \note Cannot be cleared, only valid when I2C_SLAVE_STATUS_ADDRESS_MATCH is
mbed_official 579:53297373a894 52 * set.
mbed_official 579:53297373a894 53 */
mbed_official 579:53297373a894 54 #define I2C_SLAVE_STATUS_REPEATED_START (1UL << 5)
mbed_official 579:53297373a894 55 /** Received not acknowledge.
mbed_official 579:53297373a894 56 * \note Cannot be cleared.
mbed_official 579:53297373a894 57 */
mbed_official 579:53297373a894 58 #define I2C_SLAVE_STATUS_RECEIVED_NACK (1UL << 6)
mbed_official 579:53297373a894 59 /** Transmit Collision. */
mbed_official 579:53297373a894 60 #define I2C_SLAVE_STATUS_COLLISION (1UL << 7)
mbed_official 579:53297373a894 61 /** Bus error. */
mbed_official 579:53297373a894 62 #define I2C_SLAVE_STATUS_BUS_ERROR (1UL << 8)
mbed_official 579:53297373a894 63
mbed_official 579:53297373a894 64 /** @} */
mbed_official 579:53297373a894 65
mbed_official 579:53297373a894 66 /**
mbed_official 579:53297373a894 67 * \brief I<SUP>2</SUP>C slave packet for read/write
mbed_official 579:53297373a894 68 *
mbed_official 579:53297373a894 69 * Structure to be used when transferring I<SUP>2</SUP>C slave packets.
mbed_official 579:53297373a894 70 */
mbed_official 579:53297373a894 71 struct i2c_slave_packet {
mbed_official 579:53297373a894 72 /** Length of data array. */
mbed_official 579:53297373a894 73 uint16_t data_length;
mbed_official 579:53297373a894 74 /** Data array containing all data to be transferred. */
mbed_official 579:53297373a894 75 uint8_t *data;
mbed_official 579:53297373a894 76 };
mbed_official 579:53297373a894 77
mbed_official 579:53297373a894 78 #if I2C_SLAVE_CALLBACK_MODE == true
mbed_official 579:53297373a894 79 /**
mbed_official 579:53297373a894 80 * \brief Callback types
mbed_official 579:53297373a894 81 *
mbed_official 579:53297373a894 82 * The available callback types for the I<SUP>2</SUP>C slave.
mbed_official 579:53297373a894 83 */
mbed_official 579:53297373a894 84 enum i2c_slave_callback {
mbed_official 579:53297373a894 85 /** Callback for packet write complete. */
mbed_official 579:53297373a894 86 I2C_SLAVE_CALLBACK_WRITE_COMPLETE,
mbed_official 579:53297373a894 87 /** Callback for packet read complete. */
mbed_official 579:53297373a894 88 I2C_SLAVE_CALLBACK_READ_COMPLETE,
mbed_official 579:53297373a894 89 /**
mbed_official 579:53297373a894 90 * Callback for read request from master - can be used to
mbed_official 579:53297373a894 91 * issue a write.
mbed_official 579:53297373a894 92 */
mbed_official 579:53297373a894 93 I2C_SLAVE_CALLBACK_READ_REQUEST,
mbed_official 579:53297373a894 94 /**
mbed_official 579:53297373a894 95 * Callback for write request from master - can be used to issue a read.
mbed_official 579:53297373a894 96 */
mbed_official 579:53297373a894 97 I2C_SLAVE_CALLBACK_WRITE_REQUEST,
mbed_official 579:53297373a894 98 /** Callback for error. */
mbed_official 579:53297373a894 99 I2C_SLAVE_CALLBACK_ERROR,
mbed_official 579:53297373a894 100 /**
mbed_official 579:53297373a894 101 * Callback for error in last transfer. Discovered on a new address
mbed_official 579:53297373a894 102 * interrupt.
mbed_official 579:53297373a894 103 */
mbed_official 579:53297373a894 104 I2C_SLAVE_CALLBACK_ERROR_LAST_TRANSFER,
mbed_official 579:53297373a894 105 # if !defined(__DOXYGEN__)
mbed_official 579:53297373a894 106 /** Total number of callbacks. */
mbed_official 579:53297373a894 107 _I2C_SLAVE_CALLBACK_N,
mbed_official 579:53297373a894 108 # endif
mbed_official 579:53297373a894 109 };
mbed_official 579:53297373a894 110
mbed_official 579:53297373a894 111 # if !defined(__DOXYGEN__)
mbed_official 579:53297373a894 112 /** Software module prototype. */
mbed_official 579:53297373a894 113 struct i2c_slave_module;
mbed_official 579:53297373a894 114
mbed_official 579:53297373a894 115 /** Callback type. */
mbed_official 579:53297373a894 116 typedef void (*i2c_slave_callback_t)(
mbed_official 579:53297373a894 117 struct i2c_slave_module *const module);
mbed_official 579:53297373a894 118 # endif
mbed_official 579:53297373a894 119 #endif
mbed_official 579:53297373a894 120
mbed_official 579:53297373a894 121 /**
mbed_official 579:53297373a894 122 * \brief Enum for the possible SDA hold times with respect to the negative
mbed_official 579:53297373a894 123 * edge of SCL
mbed_official 579:53297373a894 124 *
mbed_official 579:53297373a894 125 * Enum for the possible SDA hold times with respect to the negative edge
mbed_official 579:53297373a894 126 * of SCL.
mbed_official 579:53297373a894 127 */
mbed_official 579:53297373a894 128 enum i2c_slave_sda_hold_time {
mbed_official 579:53297373a894 129 /** SDA hold time disabled. */
mbed_official 579:53297373a894 130 I2C_SLAVE_SDA_HOLD_TIME_DISABLED =
mbed_official 579:53297373a894 131 ((SERCOM_I2CS_CTRLA_SDAHOLD_Msk & ((0) << SERCOM_I2CS_CTRLA_SDAHOLD_Pos))),
mbed_official 579:53297373a894 132 /** SDA hold time 50ns - 100ns. */
mbed_official 579:53297373a894 133 I2C_SLAVE_SDA_HOLD_TIME_50NS_100NS =
mbed_official 579:53297373a894 134 ((SERCOM_I2CS_CTRLA_SDAHOLD_Msk & ((1) << SERCOM_I2CS_CTRLA_SDAHOLD_Pos))),
mbed_official 579:53297373a894 135 /** SDA hold time 300ns - 600ns. */
mbed_official 579:53297373a894 136 I2C_SLAVE_SDA_HOLD_TIME_300NS_600NS =
mbed_official 579:53297373a894 137 ((SERCOM_I2CS_CTRLA_SDAHOLD_Msk & ((2) << SERCOM_I2CS_CTRLA_SDAHOLD_Pos))),
mbed_official 579:53297373a894 138 /** SDA hold time 400ns - 800ns. */
mbed_official 579:53297373a894 139 I2C_SLAVE_SDA_HOLD_TIME_400NS_800NS =
mbed_official 579:53297373a894 140 ((SERCOM_I2CS_CTRLA_SDAHOLD_Msk & ((3) << SERCOM_I2CS_CTRLA_SDAHOLD_Pos))),
mbed_official 579:53297373a894 141 };
mbed_official 579:53297373a894 142
mbed_official 579:53297373a894 143 /**
mbed_official 579:53297373a894 144 * \brief Enum for the possible address modes
mbed_official 579:53297373a894 145 *
mbed_official 579:53297373a894 146 * Enum for the possible address modes.
mbed_official 579:53297373a894 147 */
mbed_official 579:53297373a894 148 enum i2c_slave_address_mode {
mbed_official 579:53297373a894 149 /** Address match on address_mask used as a mask to address. */
mbed_official 579:53297373a894 150 I2C_SLAVE_ADDRESS_MODE_MASK = SERCOM_I2CS_CTRLB_AMODE(0),
mbed_official 579:53297373a894 151 /** Address math on both address and address_mask. */
mbed_official 579:53297373a894 152 I2C_SLAVE_ADDRESS_MODE_TWO_ADDRESSES = SERCOM_I2CS_CTRLB_AMODE(1),
mbed_official 579:53297373a894 153 /**
mbed_official 579:53297373a894 154 * Address match on range of addresses between and including address and
mbed_official 579:53297373a894 155 * address_mask.
mbed_official 579:53297373a894 156 */
mbed_official 579:53297373a894 157 I2C_SLAVE_ADDRESS_MODE_RANGE = SERCOM_I2CS_CTRLB_AMODE(2),
mbed_official 579:53297373a894 158 };
mbed_official 579:53297373a894 159
mbed_official 579:53297373a894 160 /**
mbed_official 579:53297373a894 161 * \brief Enum for the direction of a request
mbed_official 579:53297373a894 162 *
mbed_official 579:53297373a894 163 * Enum for the direction of a request.
mbed_official 579:53297373a894 164 */
mbed_official 579:53297373a894 165 enum i2c_slave_direction {
mbed_official 579:53297373a894 166 /** Read. */
mbed_official 579:53297373a894 167 I2C_SLAVE_DIRECTION_READ,
mbed_official 579:53297373a894 168 /** Write. */
mbed_official 579:53297373a894 169 I2C_SLAVE_DIRECTION_WRITE,
mbed_official 579:53297373a894 170 /** No direction. */
mbed_official 579:53297373a894 171 I2C_SLAVE_DIRECTION_NONE,
mbed_official 579:53297373a894 172 };
mbed_official 579:53297373a894 173
mbed_official 579:53297373a894 174 #ifdef FEATURE_I2C_FAST_MODE_PLUS_AND_HIGH_SPEED
mbed_official 579:53297373a894 175 /**
mbed_official 579:53297373a894 176 * \brief Enum for the transfer speed
mbed_official 579:53297373a894 177 *
mbed_official 579:53297373a894 178 * Enum for the transfer speed.
mbed_official 579:53297373a894 179 */
mbed_official 579:53297373a894 180 enum i2c_slave_transfer_speed {
mbed_official 579:53297373a894 181 /** Standard-mode (Sm) up to 100KHz and Fast-mode (Fm) up to 400KHz. */
mbed_official 579:53297373a894 182 I2C_SLAVE_SPEED_STANDARD_AND_FAST = SERCOM_I2CS_CTRLA_SPEED(0),
mbed_official 579:53297373a894 183 /** Fast-mode Plus (Fm+) up to 1MHz. */
mbed_official 579:53297373a894 184 I2C_SLAVE_SPEED_FAST_MODE_PLUS = SERCOM_I2CS_CTRLA_SPEED(1),
mbed_official 579:53297373a894 185 /** High-speed mode (Hs-mode) up to 3.4MHz. */
mbed_official 579:53297373a894 186 I2C_SLAVE_SPEED_HIGH_SPEED = SERCOM_I2CS_CTRLA_SPEED(2),
mbed_official 579:53297373a894 187 };
mbed_official 579:53297373a894 188 #endif
mbed_official 579:53297373a894 189
mbed_official 579:53297373a894 190 /**
mbed_official 579:53297373a894 191 * \brief SERCOM I<SUP>2</SUP>C Slave driver software device instance structure.
mbed_official 579:53297373a894 192 *
mbed_official 579:53297373a894 193 * SERCOM I<SUP>2</SUP>C Slave driver software instance structure, used to
mbed_official 579:53297373a894 194 * retain software state information of an associated hardware module instance.
mbed_official 579:53297373a894 195 *
mbed_official 579:53297373a894 196 * \note The fields of this structure should not be altered by the user
mbed_official 579:53297373a894 197 * application; they are reserved for module-internal use only.
mbed_official 579:53297373a894 198 */
mbed_official 579:53297373a894 199 struct i2c_slave_module {
mbed_official 579:53297373a894 200 #if !defined(__DOXYGEN__)
mbed_official 579:53297373a894 201 /** Hardware instance initialized for the struct. */
mbed_official 579:53297373a894 202 Sercom *hw;
mbed_official 579:53297373a894 203 /** Module lock. */
mbed_official 579:53297373a894 204 volatile bool locked;
mbed_official 579:53297373a894 205 /** Timeout value for polled functions. */
mbed_official 579:53297373a894 206 uint16_t buffer_timeout;
mbed_official 579:53297373a894 207 # ifdef FEATURE_I2C_10_BIT_ADDRESS
mbed_official 579:53297373a894 208 /** Using 10-bit addressing for the slave. */
mbed_official 579:53297373a894 209 bool ten_bit_address;
mbed_official 579:53297373a894 210 # endif
mbed_official 579:53297373a894 211 # if I2C_SLAVE_CALLBACK_MODE == true
mbed_official 579:53297373a894 212 /** Nack on address match. */
mbed_official 579:53297373a894 213 bool nack_on_address;
mbed_official 579:53297373a894 214 /** Pointers to callback functions. */
mbed_official 579:53297373a894 215 volatile i2c_slave_callback_t callbacks[_I2C_SLAVE_CALLBACK_N];
mbed_official 579:53297373a894 216 /** Mask for registered callbacks. */
mbed_official 579:53297373a894 217 volatile uint8_t registered_callback;
mbed_official 579:53297373a894 218 /** Mask for enabled callbacks. */
mbed_official 579:53297373a894 219 volatile uint8_t enabled_callback;
mbed_official 579:53297373a894 220 /** The total number of bytes to transfer. */
mbed_official 579:53297373a894 221 volatile uint16_t buffer_length;
mbed_official 579:53297373a894 222 /**
mbed_official 579:53297373a894 223 * Counter used for bytes left to send in write and to count number of
mbed_official 579:53297373a894 224 * obtained bytes in read.
mbed_official 579:53297373a894 225 */
mbed_official 579:53297373a894 226 uint16_t buffer_remaining;
mbed_official 579:53297373a894 227 /** Data buffer for packet write and read. */
mbed_official 579:53297373a894 228 volatile uint8_t *buffer;
mbed_official 579:53297373a894 229 /** Save direction of request from master. 1 = read, 0 = write. */
mbed_official 579:53297373a894 230 volatile enum i2c_transfer_direction transfer_direction;
mbed_official 579:53297373a894 231 /** Status for status read back in error callback. */
mbed_official 579:53297373a894 232 volatile enum status_code status;
mbed_official 579:53297373a894 233 # endif
mbed_official 579:53297373a894 234 #endif
mbed_official 579:53297373a894 235 };
mbed_official 579:53297373a894 236
mbed_official 579:53297373a894 237 /**
mbed_official 579:53297373a894 238 * \brief Configuration structure for the I<SUP>2</SUP>C Slave device
mbed_official 579:53297373a894 239 *
mbed_official 579:53297373a894 240 * This is the configuration structure for the I<SUP>2</SUP>C Slave device. It is used
mbed_official 579:53297373a894 241 * as an argument for \ref i2c_slave_init to provide the desired
mbed_official 579:53297373a894 242 * configurations for the module. The structure should be initialized using the
mbed_official 579:53297373a894 243 * \ref i2c_slave_get_config_defaults.
mbed_official 579:53297373a894 244 */
mbed_official 579:53297373a894 245 struct i2c_slave_config {
mbed_official 579:53297373a894 246 /** Set to enable the SCL low timeout. */
mbed_official 579:53297373a894 247 bool enable_scl_low_timeout;
mbed_official 579:53297373a894 248 /** SDA hold time with respect to the negative edge of SCL. */
mbed_official 579:53297373a894 249 enum i2c_slave_sda_hold_time sda_hold_time;
mbed_official 579:53297373a894 250 /** Timeout to wait for master in polled functions. */
mbed_official 579:53297373a894 251 uint16_t buffer_timeout;
mbed_official 579:53297373a894 252 /** Addressing mode. */
mbed_official 579:53297373a894 253 enum i2c_slave_address_mode address_mode;
mbed_official 579:53297373a894 254 /** Address or upper limit of address range. */
mbed_official 579:53297373a894 255 uint16_t address;
mbed_official 579:53297373a894 256 /** Address mask, second address or lower limit of address range. */
mbed_official 579:53297373a894 257 uint16_t address_mask;
mbed_official 579:53297373a894 258 #ifdef FEATURE_I2C_10_BIT_ADDRESS
mbed_official 579:53297373a894 259 /** Enable 10-bit addressing. */
mbed_official 579:53297373a894 260 bool ten_bit_address;
mbed_official 579:53297373a894 261 #endif
mbed_official 579:53297373a894 262 /**
mbed_official 579:53297373a894 263 * Enable general call address recognition (general call address
mbed_official 579:53297373a894 264 * is defined as 0000000 with direction bit 0).
mbed_official 579:53297373a894 265 */
mbed_official 579:53297373a894 266 bool enable_general_call_address;
mbed_official 579:53297373a894 267
mbed_official 579:53297373a894 268 #ifdef FEATURE_I2C_FAST_MODE_PLUS_AND_HIGH_SPEED
mbed_official 579:53297373a894 269 /** Transfer speed mode. */
mbed_official 579:53297373a894 270 enum i2c_slave_transfer_speed transfer_speed;
mbed_official 579:53297373a894 271 #endif
mbed_official 579:53297373a894 272
mbed_official 579:53297373a894 273 #if I2C_SLAVE_CALLBACK_MODE == true
mbed_official 579:53297373a894 274 /**
mbed_official 579:53297373a894 275 * Enable NACK on address match (this can be changed after initialization
mbed_official 579:53297373a894 276 * via the \ref i2c_slave_enable_nack_on_address and
mbed_official 579:53297373a894 277 * \ref i2c_slave_disable_nack_on_address functions).
mbed_official 579:53297373a894 278 */
mbed_official 579:53297373a894 279 bool enable_nack_on_address;
mbed_official 579:53297373a894 280 #endif
mbed_official 579:53297373a894 281 /** GCLK generator to use as clock source. */
mbed_official 579:53297373a894 282 enum gclk_generator generator_source;
mbed_official 579:53297373a894 283 /** Set to keep module active in sleep modes. */
mbed_official 579:53297373a894 284 bool run_in_standby;
mbed_official 579:53297373a894 285 /** PAD0 (SDA) pinmux. */
mbed_official 579:53297373a894 286 uint32_t pinmux_pad0;
mbed_official 579:53297373a894 287 /** PAD1 (SCL) pinmux. */
mbed_official 579:53297373a894 288 uint32_t pinmux_pad1;
mbed_official 579:53297373a894 289 /** Set to enable SCL low time-out. */
mbed_official 579:53297373a894 290 bool scl_low_timeout;
mbed_official 579:53297373a894 291 #ifdef FEATURE_I2C_SCL_STRETCH_MODE
mbed_official 579:53297373a894 292 /** Set to enable SCL stretch only after ACK bit (required for high speed). */
mbed_official 579:53297373a894 293 bool scl_stretch_only_after_ack_bit;
mbed_official 579:53297373a894 294 #endif
mbed_official 579:53297373a894 295 #ifdef FEATURE_I2C_SCL_EXTEND_TIMEOUT
mbed_official 579:53297373a894 296 /** Set to enable slave SCL low extend time-out. */
mbed_official 579:53297373a894 297 bool slave_scl_low_extend_timeout;
mbed_official 579:53297373a894 298 #endif
mbed_official 579:53297373a894 299 };
mbed_official 579:53297373a894 300
mbed_official 579:53297373a894 301
mbed_official 579:53297373a894 302 /**
mbed_official 579:53297373a894 303 * \name Lock/Unlock
mbed_official 579:53297373a894 304 * @{
mbed_official 579:53297373a894 305 */
mbed_official 579:53297373a894 306
mbed_official 579:53297373a894 307 /**
mbed_official 579:53297373a894 308 * \brief Attempt to get lock on driver instance
mbed_official 579:53297373a894 309 *
mbed_official 579:53297373a894 310 * This function checks the instance's lock, which indicates whether or not it
mbed_official 579:53297373a894 311 * is currently in use, and sets the lock if it was not already set.
mbed_official 579:53297373a894 312 *
mbed_official 579:53297373a894 313 * The purpose of this is to enable exclusive access to driver instances, so
mbed_official 579:53297373a894 314 * that, e.g., transactions by different services will not interfere with each
mbed_official 579:53297373a894 315 * other.
mbed_official 579:53297373a894 316 *
mbed_official 579:53297373a894 317 * \param[in,out] module Pointer to the driver instance to lock
mbed_official 579:53297373a894 318 *
mbed_official 579:53297373a894 319 * \retval STATUS_OK If the module was locked
mbed_official 579:53297373a894 320 * \retval STATUS_BUSY If the module was already locked
mbed_official 579:53297373a894 321 */
mbed_official 579:53297373a894 322 static inline enum status_code i2c_slave_lock(
mbed_official 579:53297373a894 323 struct i2c_slave_module *const module)
mbed_official 579:53297373a894 324 {
mbed_official 579:53297373a894 325 enum status_code status;
mbed_official 579:53297373a894 326
mbed_official 579:53297373a894 327 system_interrupt_enter_critical_section();
mbed_official 579:53297373a894 328
mbed_official 579:53297373a894 329 if (module->locked) {
mbed_official 579:53297373a894 330 status = STATUS_BUSY;
mbed_official 579:53297373a894 331 } else {
mbed_official 579:53297373a894 332 module->locked = true;
mbed_official 579:53297373a894 333 status = STATUS_OK;
mbed_official 579:53297373a894 334 }
mbed_official 579:53297373a894 335
mbed_official 579:53297373a894 336 system_interrupt_leave_critical_section();
mbed_official 579:53297373a894 337
mbed_official 579:53297373a894 338 return status;
mbed_official 579:53297373a894 339 }
mbed_official 579:53297373a894 340
mbed_official 579:53297373a894 341 /**
mbed_official 579:53297373a894 342 * \brief Unlock driver instance
mbed_official 579:53297373a894 343 *
mbed_official 579:53297373a894 344 * This function clears the instance lock, indicating that it is available for
mbed_official 579:53297373a894 345 * use.
mbed_official 579:53297373a894 346 *
mbed_official 579:53297373a894 347 * \param[in,out] module Pointer to the driver instance to lock
mbed_official 579:53297373a894 348 *
mbed_official 579:53297373a894 349 * \retval STATUS_OK If the module was locked
mbed_official 579:53297373a894 350 * \retval STATUS_BUSY If the module was already locked
mbed_official 579:53297373a894 351 */
mbed_official 579:53297373a894 352 static inline void i2c_slave_unlock(struct i2c_slave_module *const module)
mbed_official 579:53297373a894 353 {
mbed_official 579:53297373a894 354 module->locked = false;
mbed_official 579:53297373a894 355 }
mbed_official 579:53297373a894 356
mbed_official 579:53297373a894 357 /** @} */
mbed_official 579:53297373a894 358
mbed_official 579:53297373a894 359 /**
mbed_official 579:53297373a894 360 * \name Configuration and Initialization
mbed_official 579:53297373a894 361 * @{
mbed_official 579:53297373a894 362 */
mbed_official 579:53297373a894 363
mbed_official 579:53297373a894 364 /**
mbed_official 579:53297373a894 365 * \brief Returns the synchronization status of the module
mbed_official 579:53297373a894 366 *
mbed_official 579:53297373a894 367 * Returns the synchronization status of the module.
mbed_official 579:53297373a894 368 *
mbed_official 579:53297373a894 369 * \param[out] module Pointer to software module structure
mbed_official 579:53297373a894 370 *
mbed_official 579:53297373a894 371 * \return Status of the synchronization.
mbed_official 579:53297373a894 372 * \retval true Module is busy synchronizing
mbed_official 579:53297373a894 373 * \retval false Module is not synchronizing
mbed_official 579:53297373a894 374 */
mbed_official 579:53297373a894 375 static inline bool i2c_slave_is_syncing(
mbed_official 579:53297373a894 376 const struct i2c_slave_module *const module)
mbed_official 579:53297373a894 377 {
mbed_official 579:53297373a894 378 /* Sanity check */
mbed_official 579:53297373a894 379 Assert(module);
mbed_official 579:53297373a894 380 Assert(module->hw);
mbed_official 579:53297373a894 381
mbed_official 579:53297373a894 382 SercomI2cs *const i2c_hw = &(module->hw->I2CS);
mbed_official 579:53297373a894 383
mbed_official 579:53297373a894 384 /* Return sync status */
mbed_official 579:53297373a894 385 #if defined(FEATURE_SERCOM_SYNCBUSY_SCHEME_VERSION_1)
mbed_official 579:53297373a894 386 return (i2c_hw->STATUS.reg & SERCOM_I2CS_STATUS_SYNCBUSY);
mbed_official 579:53297373a894 387 #elif defined(FEATURE_SERCOM_SYNCBUSY_SCHEME_VERSION_2)
mbed_official 579:53297373a894 388 return (i2c_hw->SYNCBUSY.reg & SERCOM_I2CS_SYNCBUSY_MASK);
mbed_official 579:53297373a894 389 #else
mbed_official 579:53297373a894 390 # error Unknown SERCOM SYNCBUSY scheme!
mbed_official 579:53297373a894 391 #endif
mbed_official 579:53297373a894 392 }
mbed_official 579:53297373a894 393
mbed_official 579:53297373a894 394 #if !defined(__DOXYGEN__)
mbed_official 579:53297373a894 395 /**
mbed_official 579:53297373a894 396 * \internal Wait for hardware module to sync
mbed_official 579:53297373a894 397 *
mbed_official 579:53297373a894 398 * \param[in] module Pointer to software module structure
mbed_official 579:53297373a894 399 */
mbed_official 579:53297373a894 400 static void _i2c_slave_wait_for_sync(
mbed_official 579:53297373a894 401 const struct i2c_slave_module *const module)
mbed_official 579:53297373a894 402 {
mbed_official 579:53297373a894 403 /* Sanity check. */
mbed_official 579:53297373a894 404 Assert(module);
mbed_official 579:53297373a894 405
mbed_official 579:53297373a894 406 while (i2c_slave_is_syncing(module)) {
mbed_official 579:53297373a894 407 /* Wait for I2C module to sync */
mbed_official 579:53297373a894 408 }
mbed_official 579:53297373a894 409 }
mbed_official 579:53297373a894 410 #endif
mbed_official 579:53297373a894 411
mbed_official 579:53297373a894 412 /**
mbed_official 579:53297373a894 413 * \brief Gets the I<SUP>2</SUP>C slave default configurations
mbed_official 579:53297373a894 414 *
mbed_official 579:53297373a894 415 * This will initialize the configuration structure to known default values.
mbed_official 579:53297373a894 416 *
mbed_official 579:53297373a894 417 * The default configuration is as follows:
mbed_official 579:53297373a894 418 * - Disable SCL low timeout
mbed_official 579:53297373a894 419 * - 300ns - 600ns SDA hold time
mbed_official 579:53297373a894 420 * - Buffer timeout = 65535
mbed_official 579:53297373a894 421 * - Address with mask
mbed_official 579:53297373a894 422 * - Address = 0
mbed_official 579:53297373a894 423 * - Address mask = 0 (one single address)
mbed_official 579:53297373a894 424 * - General call address disabled
mbed_official 579:53297373a894 425 * - Address nack disabled if the interrupt driver is used
mbed_official 579:53297373a894 426 * - GCLK generator 0
mbed_official 579:53297373a894 427 * - Do not run in standby
mbed_official 579:53297373a894 428 * - PINMUX_DEFAULT for SERCOM pads
mbed_official 579:53297373a894 429 *
mbed_official 579:53297373a894 430 * Those default configuration only availale if the device supports it:
mbed_official 579:53297373a894 431 * - Not using 10-bit addressing
mbed_official 579:53297373a894 432 * - Standard-mode and Fast-mode transfer speed
mbed_official 579:53297373a894 433 * - SCL stretch disabled
mbed_official 579:53297373a894 434 * - slave SCL low extend time-out disabled
mbed_official 579:53297373a894 435 *
mbed_official 579:53297373a894 436 * \param[out] config Pointer to configuration structure to be initialized
mbed_official 579:53297373a894 437 */
mbed_official 579:53297373a894 438 static inline void i2c_slave_get_config_defaults(
mbed_official 579:53297373a894 439 struct i2c_slave_config *const config)
mbed_official 579:53297373a894 440 {
mbed_official 579:53297373a894 441 /*Sanity check argument. */
mbed_official 579:53297373a894 442 Assert(config);
mbed_official 579:53297373a894 443 config->enable_scl_low_timeout = false;
mbed_official 579:53297373a894 444 config->sda_hold_time = I2C_SLAVE_SDA_HOLD_TIME_300NS_600NS;
mbed_official 579:53297373a894 445 config->buffer_timeout = 65535;
mbed_official 579:53297373a894 446 config->address_mode = I2C_SLAVE_ADDRESS_MODE_MASK;
mbed_official 579:53297373a894 447 config->address = 0;
mbed_official 579:53297373a894 448 config->address_mask = 0;
mbed_official 579:53297373a894 449 #ifdef FEATURE_I2C_10_BIT_ADDRESS
mbed_official 579:53297373a894 450 config->ten_bit_address = false;
mbed_official 579:53297373a894 451 #endif
mbed_official 579:53297373a894 452 config->enable_general_call_address = false;
mbed_official 579:53297373a894 453 #ifdef FEATURE_I2C_FAST_MODE_PLUS_AND_HIGH_SPEED
mbed_official 579:53297373a894 454 config->transfer_speed = I2C_SLAVE_SPEED_STANDARD_AND_FAST;
mbed_official 579:53297373a894 455 #endif
mbed_official 579:53297373a894 456 #if I2C_SLAVE_CALLBACK_MODE == true
mbed_official 579:53297373a894 457 config->enable_nack_on_address = false;
mbed_official 579:53297373a894 458 #endif
mbed_official 579:53297373a894 459 config->generator_source = GCLK_GENERATOR_0;
mbed_official 579:53297373a894 460 config->run_in_standby = false;
mbed_official 579:53297373a894 461 config->pinmux_pad0 = PINMUX_DEFAULT;
mbed_official 579:53297373a894 462 config->pinmux_pad1 = PINMUX_DEFAULT;
mbed_official 579:53297373a894 463 config->scl_low_timeout = false;
mbed_official 579:53297373a894 464 #ifdef FEATURE_I2C_SCL_STRETCH_MODE
mbed_official 579:53297373a894 465 config->scl_stretch_only_after_ack_bit = false;
mbed_official 579:53297373a894 466 #endif
mbed_official 579:53297373a894 467 #ifdef FEATURE_I2C_SCL_EXTEND_TIMEOUT
mbed_official 579:53297373a894 468 config->slave_scl_low_extend_timeout = false;
mbed_official 579:53297373a894 469 #endif
mbed_official 579:53297373a894 470 }
mbed_official 579:53297373a894 471
mbed_official 579:53297373a894 472 enum status_code i2c_slave_init(struct i2c_slave_module *const module,
mbed_official 579:53297373a894 473 Sercom *const hw,
mbed_official 579:53297373a894 474 const struct i2c_slave_config *const config);
mbed_official 579:53297373a894 475
mbed_official 579:53297373a894 476 /**
mbed_official 579:53297373a894 477 * \brief Enables the I<SUP>2</SUP>C module
mbed_official 579:53297373a894 478 *
mbed_official 579:53297373a894 479 * This will enable the requested I<SUP>2</SUP>C module.
mbed_official 579:53297373a894 480 *
mbed_official 579:53297373a894 481 * \param[in] module Pointer to the software module struct
mbed_official 579:53297373a894 482 */
mbed_official 579:53297373a894 483 static inline void i2c_slave_enable(
mbed_official 579:53297373a894 484 const struct i2c_slave_module *const module)
mbed_official 579:53297373a894 485 {
mbed_official 579:53297373a894 486 /* Sanity check of arguments. */
mbed_official 579:53297373a894 487 Assert(module);
mbed_official 579:53297373a894 488 Assert(module->hw);
mbed_official 579:53297373a894 489
mbed_official 579:53297373a894 490 SercomI2cs *const i2c_hw = &(module->hw->I2CS);
mbed_official 579:53297373a894 491
mbed_official 579:53297373a894 492 #if I2C_SLAVE_CALLBACK_MODE == true
mbed_official 579:53297373a894 493 /* Enable global interrupt for module */
mbed_official 579:53297373a894 494 system_interrupt_enable(_sercom_get_interrupt_vector(module->hw));
mbed_official 579:53297373a894 495 #endif
mbed_official 579:53297373a894 496
mbed_official 579:53297373a894 497 /* Wait for module to sync */
mbed_official 579:53297373a894 498 _i2c_slave_wait_for_sync(module);
mbed_official 579:53297373a894 499
mbed_official 579:53297373a894 500 /* Enable module */
mbed_official 579:53297373a894 501 i2c_hw->CTRLA.reg |= SERCOM_I2CS_CTRLA_ENABLE;
mbed_official 579:53297373a894 502 }
mbed_official 579:53297373a894 503
mbed_official 579:53297373a894 504
mbed_official 579:53297373a894 505 /**
mbed_official 579:53297373a894 506 * \brief Disables the I<SUP>2</SUP>C module
mbed_official 579:53297373a894 507 *
mbed_official 579:53297373a894 508 * This will disable the I<SUP>2</SUP>C module specified in the provided software module
mbed_official 579:53297373a894 509 * structure.
mbed_official 579:53297373a894 510 *
mbed_official 579:53297373a894 511 * \param[in] module Pointer to the software module struct
mbed_official 579:53297373a894 512 */
mbed_official 579:53297373a894 513 static inline void i2c_slave_disable(
mbed_official 579:53297373a894 514 const struct i2c_slave_module *const module)
mbed_official 579:53297373a894 515 {
mbed_official 579:53297373a894 516 /* Sanity check of arguments. */
mbed_official 579:53297373a894 517 Assert(module);
mbed_official 579:53297373a894 518 Assert(module->hw);
mbed_official 579:53297373a894 519
mbed_official 579:53297373a894 520 SercomI2cs *const i2c_hw = &(module->hw->I2CS);
mbed_official 579:53297373a894 521
mbed_official 579:53297373a894 522 #if I2C_SLAVE_CALLBACK_MODE == true
mbed_official 579:53297373a894 523 /* Disable interrupts */
mbed_official 579:53297373a894 524 i2c_hw->INTENCLR.reg = SERCOM_I2CS_INTENSET_PREC |
mbed_official 579:53297373a894 525 SERCOM_I2CS_INTENSET_AMATCH | SERCOM_I2CS_INTENSET_DRDY;
mbed_official 579:53297373a894 526
mbed_official 579:53297373a894 527 /* Clear interrupt flags */
mbed_official 579:53297373a894 528 i2c_hw->INTFLAG.reg = SERCOM_I2CS_INTFLAG_PREC | SERCOM_I2CS_INTFLAG_AMATCH |
mbed_official 579:53297373a894 529 SERCOM_I2CS_INTFLAG_DRDY;
mbed_official 579:53297373a894 530
mbed_official 579:53297373a894 531 /* Disable global interrupt for module */
mbed_official 579:53297373a894 532 system_interrupt_disable(_sercom_get_interrupt_vector(module->hw));
mbed_official 579:53297373a894 533 #endif
mbed_official 579:53297373a894 534
mbed_official 579:53297373a894 535 /* Wait for module to sync */
mbed_official 579:53297373a894 536 _i2c_slave_wait_for_sync(module);
mbed_official 579:53297373a894 537
mbed_official 579:53297373a894 538 /* Disable module */
mbed_official 579:53297373a894 539 i2c_hw->CTRLA.reg &= ~SERCOM_I2CS_CTRLA_ENABLE;
mbed_official 579:53297373a894 540 }
mbed_official 579:53297373a894 541
mbed_official 579:53297373a894 542 void i2c_slave_reset(
mbed_official 579:53297373a894 543 struct i2c_slave_module *const module);
mbed_official 579:53297373a894 544
mbed_official 579:53297373a894 545 /** @} */
mbed_official 579:53297373a894 546
mbed_official 579:53297373a894 547 /**
mbed_official 579:53297373a894 548 * \name Read and Write
mbed_official 579:53297373a894 549 * @{
mbed_official 579:53297373a894 550 */
mbed_official 579:53297373a894 551
mbed_official 579:53297373a894 552 enum status_code i2c_slave_write_packet_wait(
mbed_official 579:53297373a894 553 struct i2c_slave_module *const module,
mbed_official 579:53297373a894 554 struct i2c_slave_packet *const packet);
mbed_official 579:53297373a894 555 enum status_code i2c_slave_read_packet_wait(
mbed_official 579:53297373a894 556 struct i2c_slave_module *const module,
mbed_official 579:53297373a894 557 struct i2c_slave_packet *const packet);
mbed_official 579:53297373a894 558 enum i2c_slave_direction i2c_slave_get_direction_wait(
mbed_official 579:53297373a894 559 struct i2c_slave_module *const module);
mbed_official 579:53297373a894 560
mbed_official 579:53297373a894 561 /** @} */
mbed_official 579:53297373a894 562
mbed_official 579:53297373a894 563 /**
mbed_official 579:53297373a894 564 * \name Status Management
mbed_official 579:53297373a894 565 * @{
mbed_official 579:53297373a894 566 */
mbed_official 579:53297373a894 567 uint32_t i2c_slave_get_status(
mbed_official 579:53297373a894 568 struct i2c_slave_module *const module);
mbed_official 579:53297373a894 569 void i2c_slave_clear_status(
mbed_official 579:53297373a894 570 struct i2c_slave_module *const module,
mbed_official 579:53297373a894 571 uint32_t status_flags);
mbed_official 579:53297373a894 572 /** @} */
mbed_official 579:53297373a894 573
mbed_official 579:53297373a894 574 #ifdef FEATURE_I2C_DMA_SUPPORT
mbed_official 579:53297373a894 575 /**
mbed_official 579:53297373a894 576 * \name SERCOM I2C Slave with DMA Interfaces
mbed_official 579:53297373a894 577 * @{
mbed_official 579:53297373a894 578 */
mbed_official 579:53297373a894 579
mbed_official 579:53297373a894 580 /**
mbed_official 579:53297373a894 581 * \brief Read SERCOM I<SUP>2</SUP>C interrupt status.
mbed_official 579:53297373a894 582 *
mbed_official 579:53297373a894 583 * Read I<SUP>2</SUP>C interrupt status for DMA transfer.
mbed_official 579:53297373a894 584 *
mbed_official 579:53297373a894 585 * \param[in,out] module Pointer to the driver instance to lock
mbed_official 579:53297373a894 586 *
mbed_official 579:53297373a894 587 */
mbed_official 579:53297373a894 588 static inline uint8_t i2c_slave_dma_read_interrupt_status(struct i2c_slave_module *const module)
mbed_official 579:53297373a894 589 {
mbed_official 579:53297373a894 590 return (uint8_t)module->hw->I2CS.INTFLAG.reg;
mbed_official 579:53297373a894 591 }
mbed_official 579:53297373a894 592
mbed_official 579:53297373a894 593 /**
mbed_official 579:53297373a894 594 * \brief Write SERCOM I<SUP>2</SUP>C interrupt status.
mbed_official 579:53297373a894 595 *
mbed_official 579:53297373a894 596 * Write I<SUP>2</SUP>C interrupt status for DMA transfer.
mbed_official 579:53297373a894 597 *
mbed_official 579:53297373a894 598 * \param[in,out] module Pointer to the driver instance to lock
mbed_official 579:53297373a894 599 * \param[in] flag Interrupt flag status
mbed_official 579:53297373a894 600 *
mbed_official 579:53297373a894 601 */
mbed_official 579:53297373a894 602 static inline void i2c_slave_dma_write_interrupt_status(struct i2c_slave_module *const module,
mbed_official 579:53297373a894 603 uint8_t flag)
mbed_official 579:53297373a894 604 {
mbed_official 579:53297373a894 605 module->hw->I2CS.INTFLAG.reg = flag;
mbed_official 579:53297373a894 606 }
mbed_official 579:53297373a894 607
mbed_official 579:53297373a894 608 /** @} */
mbed_official 579:53297373a894 609 #endif
mbed_official 579:53297373a894 610
mbed_official 579:53297373a894 611 /** @} */
mbed_official 579:53297373a894 612
mbed_official 579:53297373a894 613 #ifdef __cplusplus
mbed_official 579:53297373a894 614 }
mbed_official 579:53297373a894 615 #endif
mbed_official 579:53297373a894 616
mbed_official 579:53297373a894 617 #endif /* I2C_SLAVE_H_INCLUDED */