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 #include "i2c_slave.h"
mbed_official 579:53297373a894 2 #if I2C_SLAVE_CALLBACK_MODE == true
mbed_official 579:53297373a894 3 # include "i2c_slave_interrupt.h"
mbed_official 579:53297373a894 4 #endif
mbed_official 579:53297373a894 5
mbed_official 579:53297373a894 6 /**
mbed_official 579:53297373a894 7 * \internal Sets configuration to module
mbed_official 579:53297373a894 8 *
mbed_official 579:53297373a894 9 * \param[out] module Pointer to software module structure
mbed_official 579:53297373a894 10 * \param[in] config Configuration structure with configurations to set
mbed_official 579:53297373a894 11 *
mbed_official 579:53297373a894 12 * \return Status of setting configuration.
mbed_official 579:53297373a894 13 * \retval STATUS_OK Module was configured correctly
mbed_official 579:53297373a894 14 * \retval STATUS_ERR_ALREADY_INITIALIZED If setting other GCLK generator than
mbed_official 579:53297373a894 15 * previously set
mbed_official 579:53297373a894 16 */
mbed_official 579:53297373a894 17 static enum status_code _i2c_slave_set_config(
mbed_official 579:53297373a894 18 struct i2c_slave_module *const module,
mbed_official 579:53297373a894 19 const struct i2c_slave_config *const config)
mbed_official 579:53297373a894 20 {
mbed_official 579:53297373a894 21 uint32_t tmp_ctrla;
mbed_official 579:53297373a894 22
mbed_official 579:53297373a894 23 /* Sanity check arguments. */
mbed_official 579:53297373a894 24 Assert(module);
mbed_official 579:53297373a894 25 Assert(module->hw);
mbed_official 579:53297373a894 26 Assert(config);
mbed_official 579:53297373a894 27
mbed_official 579:53297373a894 28 SercomI2cs *const i2c_hw = &(module->hw->I2CS);
mbed_official 579:53297373a894 29 Sercom *const sercom_hw = module->hw;
mbed_official 579:53297373a894 30
mbed_official 579:53297373a894 31 module->buffer_timeout = config->buffer_timeout;
mbed_official 579:53297373a894 32 module->ten_bit_address = config->ten_bit_address;
mbed_official 579:53297373a894 33
mbed_official 579:53297373a894 34 struct system_pinmux_config pin_conf;
mbed_official 579:53297373a894 35 system_pinmux_get_config_defaults(&pin_conf);
mbed_official 579:53297373a894 36
mbed_official 579:53297373a894 37 uint32_t pad0 = config->pinmux_pad0;
mbed_official 579:53297373a894 38 uint32_t pad1 = config->pinmux_pad1;
mbed_official 579:53297373a894 39
mbed_official 579:53297373a894 40 /* SERCOM PAD0 - SDA */
mbed_official 579:53297373a894 41 if (pad0 == PINMUX_DEFAULT) {
mbed_official 579:53297373a894 42 pad0 = _sercom_get_default_pad(sercom_hw, 0);
mbed_official 579:53297373a894 43 }
mbed_official 579:53297373a894 44 pin_conf.mux_position = pad0 & 0xFFFF;
mbed_official 579:53297373a894 45 pin_conf.direction = SYSTEM_PINMUX_PIN_DIR_OUTPUT_WITH_READBACK;
mbed_official 579:53297373a894 46 system_pinmux_pin_set_config(pad0 >> 16, &pin_conf);
mbed_official 579:53297373a894 47
mbed_official 579:53297373a894 48 /* SERCOM PAD1 - SCL */
mbed_official 579:53297373a894 49 if (pad1 == PINMUX_DEFAULT) {
mbed_official 579:53297373a894 50 pad1 = _sercom_get_default_pad(sercom_hw, 1);
mbed_official 579:53297373a894 51 }
mbed_official 579:53297373a894 52 pin_conf.mux_position = pad1 & 0xFFFF;
mbed_official 579:53297373a894 53 pin_conf.direction = SYSTEM_PINMUX_PIN_DIR_OUTPUT_WITH_READBACK;
mbed_official 579:53297373a894 54 system_pinmux_pin_set_config(pad1 >> 16, &pin_conf);
mbed_official 579:53297373a894 55
mbed_official 579:53297373a894 56 /* Prepare config to write to register CTRLA */
mbed_official 579:53297373a894 57 if (config->run_in_standby || system_is_debugger_present()) {
mbed_official 579:53297373a894 58 tmp_ctrla = SERCOM_I2CS_CTRLA_RUNSTDBY;
mbed_official 579:53297373a894 59 } else {
mbed_official 579:53297373a894 60 tmp_ctrla = 0;
mbed_official 579:53297373a894 61 }
mbed_official 579:53297373a894 62
mbed_official 579:53297373a894 63 tmp_ctrla |= ((uint32_t)config->sda_hold_time |
mbed_official 579:53297373a894 64 config->transfer_speed |
mbed_official 579:53297373a894 65 (config->scl_low_timeout << SERCOM_I2CS_CTRLA_LOWTOUTEN_Pos) |
mbed_official 579:53297373a894 66 (config->scl_stretch_only_after_ack_bit << SERCOM_I2CS_CTRLA_SCLSM_Pos) |
mbed_official 579:53297373a894 67 (config->slave_scl_low_extend_timeout << SERCOM_I2CS_CTRLA_SEXTTOEN_Pos));
mbed_official 579:53297373a894 68
mbed_official 579:53297373a894 69 i2c_hw->CTRLA.reg |= tmp_ctrla;
mbed_official 579:53297373a894 70
mbed_official 579:53297373a894 71 /* Set CTRLB configuration */
mbed_official 579:53297373a894 72 i2c_hw->CTRLB.reg = SERCOM_I2CS_CTRLB_SMEN | config->address_mode;
mbed_official 579:53297373a894 73
mbed_official 579:53297373a894 74 i2c_hw->ADDR.reg = config->address << SERCOM_I2CS_ADDR_ADDR_Pos |
mbed_official 579:53297373a894 75 config->address_mask << SERCOM_I2CS_ADDR_ADDRMASK_Pos |
mbed_official 579:53297373a894 76 config->ten_bit_address << SERCOM_I2CS_ADDR_TENBITEN_Pos |
mbed_official 579:53297373a894 77 config->enable_general_call_address << SERCOM_I2CS_ADDR_GENCEN_Pos;
mbed_official 579:53297373a894 78
mbed_official 579:53297373a894 79 return STATUS_OK;
mbed_official 579:53297373a894 80 }
mbed_official 579:53297373a894 81
mbed_official 579:53297373a894 82 /**
mbed_official 579:53297373a894 83 * \brief Initializes the requested I<SUP>2</SUP>C hardware module
mbed_official 579:53297373a894 84 *
mbed_official 579:53297373a894 85 * Initializes the SERCOM I<SUP>2</SUP>C Slave device requested and sets the provided
mbed_official 579:53297373a894 86 * software module struct. Run this function before any further use of
mbed_official 579:53297373a894 87 * the driver.
mbed_official 579:53297373a894 88 *
mbed_official 579:53297373a894 89 * \param[out] module Pointer to software module struct
mbed_official 579:53297373a894 90 * \param[in] hw Pointer to the hardware instance
mbed_official 579:53297373a894 91 * \param[in] config Pointer to the configuration struct
mbed_official 579:53297373a894 92 *
mbed_official 579:53297373a894 93 * \return Status of initialization.
mbed_official 579:53297373a894 94 * \retval STATUS_OK Module initiated correctly
mbed_official 579:53297373a894 95 * \retval STATUS_ERR_DENIED If module is enabled
mbed_official 579:53297373a894 96 * \retval STATUS_BUSY If module is busy resetting
mbed_official 579:53297373a894 97 * \retval STATUS_ERR_ALREADY_INITIALIZED If setting other GCLK generator than
mbed_official 579:53297373a894 98 * previously set
mbed_official 579:53297373a894 99 */
mbed_official 579:53297373a894 100 enum status_code i2c_slave_init(
mbed_official 579:53297373a894 101 struct i2c_slave_module *const module,
mbed_official 579:53297373a894 102 Sercom *const hw,
mbed_official 579:53297373a894 103 const struct i2c_slave_config *const config)
mbed_official 579:53297373a894 104 {
mbed_official 579:53297373a894 105 /* Sanity check arguments. */
mbed_official 579:53297373a894 106 Assert(module);
mbed_official 579:53297373a894 107 Assert(hw);
mbed_official 579:53297373a894 108 Assert(config);
mbed_official 579:53297373a894 109
mbed_official 579:53297373a894 110 /* Initialize software module */
mbed_official 579:53297373a894 111 module->hw = hw;
mbed_official 579:53297373a894 112
mbed_official 579:53297373a894 113 SercomI2cs *const i2c_hw = &(module->hw->I2CS);
mbed_official 579:53297373a894 114
mbed_official 579:53297373a894 115 /* Check if module is enabled. */
mbed_official 579:53297373a894 116 if (i2c_hw->CTRLA.reg & SERCOM_I2CS_CTRLA_ENABLE) {
mbed_official 579:53297373a894 117 return STATUS_ERR_DENIED;
mbed_official 579:53297373a894 118 }
mbed_official 579:53297373a894 119
mbed_official 579:53297373a894 120 /* Check if reset is in progress. */
mbed_official 579:53297373a894 121 if (i2c_hw->CTRLA.reg & SERCOM_I2CS_CTRLA_SWRST) {
mbed_official 579:53297373a894 122 return STATUS_BUSY;
mbed_official 579:53297373a894 123 }
mbed_official 579:53297373a894 124
mbed_official 579:53297373a894 125 uint32_t sercom_index = _sercom_get_sercom_inst_index(module->hw);
mbed_official 579:53297373a894 126 #if (SAML21)
mbed_official 579:53297373a894 127 uint32_t pm_index = sercom_index + MCLK_APBCMASK_SERCOM0_Pos;
mbed_official 579:53297373a894 128 #else
mbed_official 579:53297373a894 129 uint32_t pm_index = sercom_index + PM_APBCMASK_SERCOM0_Pos;
mbed_official 579:53297373a894 130 #endif
mbed_official 579:53297373a894 131 uint32_t gclk_index = sercom_index + SERCOM0_GCLK_ID_CORE;
mbed_official 579:53297373a894 132
mbed_official 579:53297373a894 133 /* Turn on module in PM */
mbed_official 579:53297373a894 134 system_apb_clock_set_mask(SYSTEM_CLOCK_APB_APBC, 1 << pm_index);
mbed_official 579:53297373a894 135
mbed_official 579:53297373a894 136 /* Set up the GCLK for the module */
mbed_official 579:53297373a894 137 struct system_gclk_chan_config gclk_chan_conf;
mbed_official 579:53297373a894 138 system_gclk_chan_get_config_defaults(&gclk_chan_conf);
mbed_official 579:53297373a894 139 gclk_chan_conf.source_generator = config->generator_source;
mbed_official 579:53297373a894 140 system_gclk_chan_set_config(gclk_index, &gclk_chan_conf);
mbed_official 579:53297373a894 141 system_gclk_chan_enable(gclk_index);
mbed_official 579:53297373a894 142 sercom_set_gclk_generator(config->generator_source, false);
mbed_official 579:53297373a894 143
mbed_official 579:53297373a894 144 #if I2C_SLAVE_CALLBACK_MODE == true
mbed_official 579:53297373a894 145 /* Get sercom instance index. */
mbed_official 579:53297373a894 146 uint8_t instance_index = _sercom_get_sercom_inst_index(module->hw);
mbed_official 579:53297373a894 147
mbed_official 579:53297373a894 148 /* Save software module in interrupt handler. */
mbed_official 579:53297373a894 149 _sercom_set_handler(instance_index, _i2c_slave_interrupt_handler);
mbed_official 579:53297373a894 150
mbed_official 579:53297373a894 151 /* Save software module. */
mbed_official 579:53297373a894 152 _sercom_instances[instance_index] = module;
mbed_official 579:53297373a894 153
mbed_official 579:53297373a894 154 /* Initialize values in module. */
mbed_official 579:53297373a894 155 module->registered_callback = 0;
mbed_official 579:53297373a894 156 module->enabled_callback = 0;
mbed_official 579:53297373a894 157 module->buffer_length = 0;
mbed_official 579:53297373a894 158 module->nack_on_address = config->enable_nack_on_address;
mbed_official 579:53297373a894 159 #endif
mbed_official 579:53297373a894 160
mbed_official 579:53297373a894 161 /* Set SERCOM module to operate in I2C slave mode. */
mbed_official 579:53297373a894 162 i2c_hw->CTRLA.reg = SERCOM_I2CS_CTRLA_MODE(0x4);
mbed_official 579:53297373a894 163
mbed_official 579:53297373a894 164 /* Set config and return status. */
mbed_official 579:53297373a894 165 return _i2c_slave_set_config(module, config);
mbed_official 579:53297373a894 166 }
mbed_official 579:53297373a894 167
mbed_official 579:53297373a894 168 /**
mbed_official 579:53297373a894 169 * \brief Resets the hardware module
mbed_official 579:53297373a894 170 *
mbed_official 579:53297373a894 171 * This will reset the module to hardware defaults.
mbed_official 579:53297373a894 172 *
mbed_official 579:53297373a894 173 * \param[in,out] module Pointer to software module structure
mbed_official 579:53297373a894 174 */
mbed_official 579:53297373a894 175 void i2c_slave_reset(
mbed_official 579:53297373a894 176 struct i2c_slave_module *const module)
mbed_official 579:53297373a894 177 {
mbed_official 579:53297373a894 178 /* Sanity check arguments. */
mbed_official 579:53297373a894 179 Assert(module);
mbed_official 579:53297373a894 180 Assert(module->hw);
mbed_official 579:53297373a894 181
mbed_official 579:53297373a894 182 SercomI2cs *const i2c_hw = &(module->hw->I2CS);
mbed_official 579:53297373a894 183
mbed_official 579:53297373a894 184 #if I2C_SLAVE_CALLBACK_MODE == true
mbed_official 579:53297373a894 185 /* Reset module instance. */
mbed_official 579:53297373a894 186 module->registered_callback = 0;
mbed_official 579:53297373a894 187 module->enabled_callback = 0;
mbed_official 579:53297373a894 188 module->buffer_length = 0;
mbed_official 579:53297373a894 189 module->buffer_remaining = 0;
mbed_official 579:53297373a894 190 module->buffer = NULL;
mbed_official 579:53297373a894 191 #endif
mbed_official 579:53297373a894 192
mbed_official 579:53297373a894 193 /* Disable module */
mbed_official 579:53297373a894 194 i2c_slave_disable(module);
mbed_official 579:53297373a894 195
mbed_official 579:53297373a894 196 #if I2C_SLAVE_CALLBACK_MODE == true
mbed_official 579:53297373a894 197 /* Clear all pending interrupts. */
mbed_official 579:53297373a894 198 system_interrupt_enter_critical_section();
mbed_official 579:53297373a894 199 system_interrupt_clear_pending(_sercom_get_interrupt_vector(module->hw));
mbed_official 579:53297373a894 200 system_interrupt_leave_critical_section();
mbed_official 579:53297373a894 201 #endif
mbed_official 579:53297373a894 202
mbed_official 579:53297373a894 203 /* Wait for sync. */
mbed_official 579:53297373a894 204 _i2c_slave_wait_for_sync(module);
mbed_official 579:53297373a894 205
mbed_official 579:53297373a894 206 /* Reset module. */
mbed_official 579:53297373a894 207 i2c_hw->CTRLA.reg = SERCOM_I2CS_CTRLA_SWRST;
mbed_official 579:53297373a894 208 }
mbed_official 579:53297373a894 209
mbed_official 579:53297373a894 210 /**
mbed_official 579:53297373a894 211 * \internal Waits for answer on bus
mbed_official 579:53297373a894 212 *
mbed_official 579:53297373a894 213 * \param[in] module Pointer to software module structure
mbed_official 579:53297373a894 214 *
mbed_official 579:53297373a894 215 * \return Status of bus.
mbed_official 579:53297373a894 216 * \retval STATUS_OK If given response from slave device
mbed_official 579:53297373a894 217 * \retval STATUS_ERR_TIMEOUT If no response was given within specified timeout
mbed_official 579:53297373a894 218 * period
mbed_official 579:53297373a894 219 */
mbed_official 579:53297373a894 220 static enum status_code _i2c_slave_wait_for_bus(
mbed_official 579:53297373a894 221 struct i2c_slave_module *const module)
mbed_official 579:53297373a894 222 {
mbed_official 579:53297373a894 223 /* Sanity check arguments. */
mbed_official 579:53297373a894 224 Assert(module);
mbed_official 579:53297373a894 225 Assert(module->hw);
mbed_official 579:53297373a894 226
mbed_official 579:53297373a894 227 SercomI2cm *const i2c_module = &(module->hw->I2CM);
mbed_official 579:53297373a894 228
mbed_official 579:53297373a894 229 /* Wait for reply. */
mbed_official 579:53297373a894 230 uint16_t timeout_counter = 0;
mbed_official 579:53297373a894 231 while ((!(i2c_module->INTFLAG.reg & SERCOM_I2CS_INTFLAG_DRDY)) &&
mbed_official 579:53297373a894 232 (!(i2c_module->INTFLAG.reg & SERCOM_I2CS_INTFLAG_PREC)) &&
mbed_official 579:53297373a894 233 (!(i2c_module->INTFLAG.reg & SERCOM_I2CS_INTFLAG_AMATCH))) {
mbed_official 579:53297373a894 234
mbed_official 579:53297373a894 235 /* Check timeout condition. */
mbed_official 579:53297373a894 236 if (++timeout_counter >= module->buffer_timeout) {
mbed_official 579:53297373a894 237 return STATUS_ERR_TIMEOUT;
mbed_official 579:53297373a894 238 }
mbed_official 579:53297373a894 239 }
mbed_official 579:53297373a894 240 return STATUS_OK;
mbed_official 579:53297373a894 241 }
mbed_official 579:53297373a894 242
mbed_official 579:53297373a894 243 /**
mbed_official 579:53297373a894 244 * \brief Writes a packet to the master
mbed_official 579:53297373a894 245 *
mbed_official 579:53297373a894 246 * Writes a packet to the master. This will wait for the master to issue
mbed_official 579:53297373a894 247 * a request.
mbed_official 579:53297373a894 248 *
mbed_official 579:53297373a894 249 * \param[in] module Pointer to software module structure
mbed_official 579:53297373a894 250 * \param[in] packet Packet to write to master
mbed_official 579:53297373a894 251 *
mbed_official 579:53297373a894 252 * \return Status of packet write.
mbed_official 579:53297373a894 253 * \retval STATUS_OK Packet was written successfully
mbed_official 579:53297373a894 254 * \retval STATUS_ERR_DENIED Start condition not received, another
mbed_official 579:53297373a894 255 * interrupt flag is set
mbed_official 579:53297373a894 256 * \retval STATUS_ERR_IO There was an error in the previous transfer
mbed_official 579:53297373a894 257 * \retval STATUS_ERR_BAD_FORMAT Master wants to write data
mbed_official 579:53297373a894 258 * \retval STATUS_ERR_INVALID_ARG Invalid argument(s) was provided
mbed_official 579:53297373a894 259 * \retval STATUS_ERR_BUSY The I<SUP>2</SUP>C module is busy with a job
mbed_official 579:53297373a894 260 * \retval STATUS_ERR_ERR_OVERFLOW Master NACKed before entire packet was
mbed_official 579:53297373a894 261 * transferred
mbed_official 579:53297373a894 262 * \retval STATUS_ERR_TIMEOUT No response was given within the timeout
mbed_official 579:53297373a894 263 * period
mbed_official 579:53297373a894 264 */
mbed_official 579:53297373a894 265 enum status_code i2c_slave_write_packet_wait(
mbed_official 579:53297373a894 266 struct i2c_slave_module *const module,
mbed_official 579:53297373a894 267 struct i2c_slave_packet *const packet)
mbed_official 579:53297373a894 268 {
mbed_official 579:53297373a894 269 /* Sanity check arguments. */
mbed_official 579:53297373a894 270 Assert(module);
mbed_official 579:53297373a894 271 Assert(module->hw);
mbed_official 579:53297373a894 272 Assert(packet);
mbed_official 579:53297373a894 273
mbed_official 579:53297373a894 274 SercomI2cs *const i2c_hw = &(module->hw->I2CS);
mbed_official 579:53297373a894 275
mbed_official 579:53297373a894 276 uint16_t length = packet->data_length;
mbed_official 579:53297373a894 277
mbed_official 579:53297373a894 278 if (length == 0) {
mbed_official 579:53297373a894 279 return STATUS_ERR_INVALID_ARG;
mbed_official 579:53297373a894 280 }
mbed_official 579:53297373a894 281
mbed_official 579:53297373a894 282 #if I2C_SLAVE_CALLBACK_MODE == true
mbed_official 579:53297373a894 283 /* Check if the module is busy with a job or AMATCH is enabled */
mbed_official 579:53297373a894 284 if (module->buffer_remaining > 0 ||
mbed_official 579:53297373a894 285 (i2c_hw->INTENSET.reg & SERCOM_I2CS_INTFLAG_AMATCH)) {
mbed_official 579:53297373a894 286 return STATUS_BUSY;
mbed_official 579:53297373a894 287 }
mbed_official 579:53297373a894 288 #endif
mbed_official 579:53297373a894 289
mbed_official 579:53297373a894 290 enum status_code status;
mbed_official 579:53297373a894 291 /* Wait for master to send address packet */
mbed_official 579:53297373a894 292 status = _i2c_slave_wait_for_bus(module);
mbed_official 579:53297373a894 293
mbed_official 579:53297373a894 294 if (status != STATUS_OK) {
mbed_official 579:53297373a894 295 /* Timeout, return */
mbed_official 579:53297373a894 296 return status;
mbed_official 579:53297373a894 297 }
mbed_official 579:53297373a894 298 if (!(i2c_hw->INTFLAG.reg & SERCOM_I2CS_INTFLAG_AMATCH)) {
mbed_official 579:53297373a894 299 /* Not address interrupt, something is wrong */
mbed_official 579:53297373a894 300 return STATUS_ERR_DENIED;
mbed_official 579:53297373a894 301 }
mbed_official 579:53297373a894 302
mbed_official 579:53297373a894 303 if (module->ten_bit_address) {
mbed_official 579:53297373a894 304 /* ACK the first address */
mbed_official 579:53297373a894 305 i2c_hw->CTRLB.reg &= ~SERCOM_I2CS_CTRLB_ACKACT;
mbed_official 579:53297373a894 306 i2c_hw->CTRLB.reg |= SERCOM_I2CS_CTRLB_CMD(0x3);
mbed_official 579:53297373a894 307
mbed_official 579:53297373a894 308 /* Wait for address interrupt */
mbed_official 579:53297373a894 309 status = _i2c_slave_wait_for_bus(module);
mbed_official 579:53297373a894 310
mbed_official 579:53297373a894 311 if (status != STATUS_OK) {
mbed_official 579:53297373a894 312 /* Timeout, return */
mbed_official 579:53297373a894 313 return STATUS_ERR_TIMEOUT;
mbed_official 579:53297373a894 314 }
mbed_official 579:53297373a894 315
mbed_official 579:53297373a894 316 if (!(i2c_hw->INTFLAG.reg & SERCOM_I2CS_INTFLAG_AMATCH)) {
mbed_official 579:53297373a894 317 /* Not address interrupt, something is wrong */
mbed_official 579:53297373a894 318 return STATUS_ERR_DENIED;
mbed_official 579:53297373a894 319 }
mbed_official 579:53297373a894 320 }
mbed_official 579:53297373a894 321
mbed_official 579:53297373a894 322 /* Check if there was an error in last transfer */
mbed_official 579:53297373a894 323 if (i2c_hw->STATUS.reg & (SERCOM_I2CS_STATUS_BUSERR |
mbed_official 579:53297373a894 324 SERCOM_I2CS_STATUS_COLL | SERCOM_I2CS_STATUS_LOWTOUT)) {
mbed_official 579:53297373a894 325 return STATUS_ERR_IO;
mbed_official 579:53297373a894 326 }
mbed_official 579:53297373a894 327
mbed_official 579:53297373a894 328 /* Check direction */
mbed_official 579:53297373a894 329 if (!(i2c_hw->STATUS.reg & SERCOM_I2CS_STATUS_DIR)) {
mbed_official 579:53297373a894 330 /* Write request from master, send NACK and return */
mbed_official 579:53297373a894 331 i2c_hw->CTRLB.reg |= SERCOM_I2CS_CTRLB_ACKACT;
mbed_official 579:53297373a894 332 i2c_hw->CTRLB.reg |= SERCOM_I2CS_CTRLB_CMD(0x3);
mbed_official 579:53297373a894 333 return STATUS_ERR_BAD_FORMAT;
mbed_official 579:53297373a894 334 }
mbed_official 579:53297373a894 335
mbed_official 579:53297373a894 336 /* Read request from master, ACK address */
mbed_official 579:53297373a894 337 i2c_hw->CTRLB.reg &= ~SERCOM_I2CS_CTRLB_ACKACT;
mbed_official 579:53297373a894 338 i2c_hw->CTRLB.reg |= SERCOM_I2CS_CTRLB_CMD(0x3);
mbed_official 579:53297373a894 339
mbed_official 579:53297373a894 340 uint16_t i = 0;
mbed_official 579:53297373a894 341
mbed_official 579:53297373a894 342 /* Wait for data interrupt */
mbed_official 579:53297373a894 343 status = _i2c_slave_wait_for_bus(module);
mbed_official 579:53297373a894 344 if (status != STATUS_OK) {
mbed_official 579:53297373a894 345 /* Timeout, return */
mbed_official 579:53297373a894 346 return status;
mbed_official 579:53297373a894 347 }
mbed_official 579:53297373a894 348
mbed_official 579:53297373a894 349 while (length--) {
mbed_official 579:53297373a894 350 /* Write data */
mbed_official 579:53297373a894 351 _i2c_slave_wait_for_sync(module);
mbed_official 579:53297373a894 352 i2c_hw->DATA.reg = packet->data[i++];
mbed_official 579:53297373a894 353
mbed_official 579:53297373a894 354 /* Wait for response from master */
mbed_official 579:53297373a894 355 status = _i2c_slave_wait_for_bus(module);
mbed_official 579:53297373a894 356
mbed_official 579:53297373a894 357 if (status != STATUS_OK) {
mbed_official 579:53297373a894 358 /* Timeout, return */
mbed_official 579:53297373a894 359 return status;
mbed_official 579:53297373a894 360 }
mbed_official 579:53297373a894 361
mbed_official 579:53297373a894 362 if (i2c_hw->STATUS.reg & SERCOM_I2CS_STATUS_RXNACK &&
mbed_official 579:53297373a894 363 length !=0) {
mbed_official 579:53297373a894 364 /* NACK from master, abort */
mbed_official 579:53297373a894 365 /* Release line */
mbed_official 579:53297373a894 366 i2c_hw->CTRLB.reg |= SERCOM_I2CS_CTRLB_CMD(0x02);
mbed_official 579:53297373a894 367
mbed_official 579:53297373a894 368 return STATUS_ERR_OVERFLOW;
mbed_official 579:53297373a894 369 }
mbed_official 579:53297373a894 370 /* ACK from master, continue writing */
mbed_official 579:53297373a894 371 }
mbed_official 579:53297373a894 372
mbed_official 579:53297373a894 373 /* Release line */
mbed_official 579:53297373a894 374 i2c_hw->CTRLB.reg |= SERCOM_I2CS_CTRLB_CMD(0x02);
mbed_official 579:53297373a894 375
mbed_official 579:53297373a894 376 return STATUS_OK;
mbed_official 579:53297373a894 377 }
mbed_official 579:53297373a894 378
mbed_official 579:53297373a894 379 /**
mbed_official 579:53297373a894 380 * \brief Reads a packet from the master
mbed_official 579:53297373a894 381 *
mbed_official 579:53297373a894 382 * Reads a packet from the master. This will wait for the master to issue a
mbed_official 579:53297373a894 383 * request.
mbed_official 579:53297373a894 384 *
mbed_official 579:53297373a894 385 * \param[in] module Pointer to software module structure
mbed_official 579:53297373a894 386 * \param[out] packet Packet to read from master
mbed_official 579:53297373a894 387 *
mbed_official 579:53297373a894 388 * \return Status of packet read.
mbed_official 579:53297373a894 389 * \retval STATUS_OK Packet was read successfully
mbed_official 579:53297373a894 390 * \retval STATUS_ABORTED Master sent stop condition or repeated
mbed_official 579:53297373a894 391 * start before specified length of bytes
mbed_official 579:53297373a894 392 * was received
mbed_official 579:53297373a894 393 * \retval STATUS_ERR_IO There was an error in the previous transfer
mbed_official 579:53297373a894 394 * \retval STATUS_ERR_DENIED Start condition not received, another
mbed_official 579:53297373a894 395 * interrupt flag is set
mbed_official 579:53297373a894 396 * \retval STATUS_ERR_INVALID_ARG Invalid argument(s) was provided
mbed_official 579:53297373a894 397 * \retval STATUS_ERR_BUSY The I<SUP>2</SUP>C module is busy with a job
mbed_official 579:53297373a894 398 * \retval STATUS_ERR_BAD_FORMAT Master wants to read data
mbed_official 579:53297373a894 399 * \retval STATUS_ERR_ERR_OVERFLOW Last byte received overflows buffer
mbed_official 579:53297373a894 400 */
mbed_official 579:53297373a894 401 enum status_code i2c_slave_read_packet_wait(
mbed_official 579:53297373a894 402 struct i2c_slave_module *const module,
mbed_official 579:53297373a894 403 struct i2c_slave_packet *const packet)
mbed_official 579:53297373a894 404 {
mbed_official 579:53297373a894 405 /* Sanity check arguments. */
mbed_official 579:53297373a894 406 Assert(module);
mbed_official 579:53297373a894 407 Assert(module->hw);
mbed_official 579:53297373a894 408 Assert(packet);
mbed_official 579:53297373a894 409
mbed_official 579:53297373a894 410 SercomI2cs *const i2c_hw = &(module->hw->I2CS);
mbed_official 579:53297373a894 411
mbed_official 579:53297373a894 412 uint16_t length = packet->data_length;
mbed_official 579:53297373a894 413
mbed_official 579:53297373a894 414 if (length == 0) {
mbed_official 579:53297373a894 415 return STATUS_ERR_INVALID_ARG;
mbed_official 579:53297373a894 416 }
mbed_official 579:53297373a894 417
mbed_official 579:53297373a894 418 #if I2C_SLAVE_CALLBACK_MODE == true
mbed_official 579:53297373a894 419 /* Check if the module is busy with a job or AMATCH is enabled */
mbed_official 579:53297373a894 420 if (module->buffer_remaining > 0 ||
mbed_official 579:53297373a894 421 (i2c_hw->INTENSET.reg & SERCOM_I2CS_INTFLAG_AMATCH)) {
mbed_official 579:53297373a894 422 return STATUS_BUSY;
mbed_official 579:53297373a894 423 }
mbed_official 579:53297373a894 424 #endif
mbed_official 579:53297373a894 425
mbed_official 579:53297373a894 426 enum status_code status;
mbed_official 579:53297373a894 427
mbed_official 579:53297373a894 428 /* Wait for master to send address packet */
mbed_official 579:53297373a894 429 status = _i2c_slave_wait_for_bus(module);
mbed_official 579:53297373a894 430 if (status != STATUS_OK) {
mbed_official 579:53297373a894 431 /* Timeout, return */
mbed_official 579:53297373a894 432 return status;
mbed_official 579:53297373a894 433 }
mbed_official 579:53297373a894 434
mbed_official 579:53297373a894 435 if (!(i2c_hw->INTFLAG.reg & SERCOM_I2CS_INTFLAG_AMATCH)) {
mbed_official 579:53297373a894 436 /* Not address interrupt, something is wrong */
mbed_official 579:53297373a894 437 return STATUS_ERR_DENIED;
mbed_official 579:53297373a894 438 }
mbed_official 579:53297373a894 439
mbed_official 579:53297373a894 440 /* Check if there was an error in the last transfer */
mbed_official 579:53297373a894 441 if (i2c_hw->STATUS.reg & (SERCOM_I2CS_STATUS_BUSERR |
mbed_official 579:53297373a894 442 SERCOM_I2CS_STATUS_COLL | SERCOM_I2CS_STATUS_LOWTOUT)) {
mbed_official 579:53297373a894 443 return STATUS_ERR_IO;
mbed_official 579:53297373a894 444 }
mbed_official 579:53297373a894 445 /* Check direction */
mbed_official 579:53297373a894 446 if ((i2c_hw->STATUS.reg & SERCOM_I2CS_STATUS_DIR)) {
mbed_official 579:53297373a894 447 /* Read request from master, send NACK and return */
mbed_official 579:53297373a894 448 i2c_hw->CTRLB.reg |= SERCOM_I2CS_CTRLB_ACKACT;
mbed_official 579:53297373a894 449 i2c_hw->CTRLB.reg |= SERCOM_I2CS_CTRLB_CMD(0x3);
mbed_official 579:53297373a894 450 return STATUS_ERR_BAD_FORMAT;
mbed_official 579:53297373a894 451 }
mbed_official 579:53297373a894 452
mbed_official 579:53297373a894 453 /* Write request from master, ACK address */
mbed_official 579:53297373a894 454 i2c_hw->CTRLB.reg &= ~SERCOM_I2CS_CTRLB_ACKACT;
mbed_official 579:53297373a894 455 i2c_hw->CTRLB.reg |= SERCOM_I2CS_CTRLB_CMD(0x3);
mbed_official 579:53297373a894 456
mbed_official 579:53297373a894 457 uint16_t i = 0;
mbed_official 579:53297373a894 458 while (length--) {
mbed_official 579:53297373a894 459
mbed_official 579:53297373a894 460 /* Wait for next byte or stop condition */
mbed_official 579:53297373a894 461 status = _i2c_slave_wait_for_bus(module);
mbed_official 579:53297373a894 462 if (status != STATUS_OK) {
mbed_official 579:53297373a894 463 /* Timeout, return */
mbed_official 579:53297373a894 464 return status;
mbed_official 579:53297373a894 465 }
mbed_official 579:53297373a894 466
mbed_official 579:53297373a894 467 if ((i2c_hw->INTFLAG.reg & SERCOM_I2CS_INTFLAG_PREC) ||
mbed_official 579:53297373a894 468 i2c_hw->INTFLAG.reg & SERCOM_I2CS_INTFLAG_AMATCH) {
mbed_official 579:53297373a894 469 /* Master sent stop condition, or repeated start, read done */
mbed_official 579:53297373a894 470 /* Clear stop flag */
mbed_official 579:53297373a894 471 i2c_hw->INTFLAG.reg = SERCOM_I2CS_INTFLAG_PREC;
mbed_official 579:53297373a894 472 return STATUS_ABORTED;
mbed_official 579:53297373a894 473 }
mbed_official 579:53297373a894 474
mbed_official 579:53297373a894 475 /* Read data */
mbed_official 579:53297373a894 476 _i2c_slave_wait_for_sync(module);
mbed_official 579:53297373a894 477 packet->data[i++] = i2c_hw->DATA.reg;
mbed_official 579:53297373a894 478
mbed_official 579:53297373a894 479 }
mbed_official 579:53297373a894 480
mbed_official 579:53297373a894 481 /* Packet read done, wait for packet to NACK, Stop or repeated start */
mbed_official 579:53297373a894 482 status = _i2c_slave_wait_for_bus(module);
mbed_official 579:53297373a894 483
mbed_official 579:53297373a894 484 if (i2c_hw->INTFLAG.reg & SERCOM_I2CS_INTFLAG_DRDY) {
mbed_official 579:53297373a894 485 /* Buffer is full, send NACK */
mbed_official 579:53297373a894 486 i2c_hw->CTRLB.reg |= SERCOM_I2CS_CTRLB_ACKACT;
mbed_official 579:53297373a894 487 i2c_hw->CTRLB.reg |= SERCOM_I2CS_CTRLB_CMD(0x2);
mbed_official 579:53297373a894 488 }
mbed_official 579:53297373a894 489 if (i2c_hw->INTFLAG.reg & SERCOM_I2CS_INTFLAG_PREC) {
mbed_official 579:53297373a894 490 /* Clear stop flag */
mbed_official 579:53297373a894 491 i2c_hw->INTFLAG.reg = SERCOM_I2CS_INTFLAG_PREC;
mbed_official 579:53297373a894 492 }
mbed_official 579:53297373a894 493 return STATUS_OK;
mbed_official 579:53297373a894 494 }
mbed_official 579:53297373a894 495
mbed_official 579:53297373a894 496 /**
mbed_official 579:53297373a894 497 * \brief Waits for a start condition on the bus
mbed_official 579:53297373a894 498 *
mbed_official 579:53297373a894 499 * \note This function is only available for 7-bit slave addressing.
mbed_official 579:53297373a894 500 *
mbed_official 579:53297373a894 501 * Waits for the master to issue a start condition on the bus.
mbed_official 579:53297373a894 502 * Note that this function does not check for errors in the last transfer,
mbed_official 579:53297373a894 503 * this will be discovered when reading or writing.
mbed_official 579:53297373a894 504 *
mbed_official 579:53297373a894 505 * \param[in] module Pointer to software module structure
mbed_official 579:53297373a894 506 *
mbed_official 579:53297373a894 507 * \return Direction of the current transfer, when in slave mode.
mbed_official 579:53297373a894 508 * \retval I2C_SLAVE_DIRECTION_NONE No request from master within timeout
mbed_official 579:53297373a894 509 * period
mbed_official 579:53297373a894 510 * \retval I2C_SLAVE_DIRECTION_READ Write request from master
mbed_official 579:53297373a894 511 * \retval I2C_SLAVE_DIRECTION_WRITE Read request from master
mbed_official 579:53297373a894 512 */
mbed_official 579:53297373a894 513 enum i2c_slave_direction i2c_slave_get_direction_wait(
mbed_official 579:53297373a894 514 struct i2c_slave_module *const module)
mbed_official 579:53297373a894 515 {
mbed_official 579:53297373a894 516 /* Sanity check 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 enum status_code status;
mbed_official 579:53297373a894 523
mbed_official 579:53297373a894 524 /* Wait for address interrupt */
mbed_official 579:53297373a894 525 status = _i2c_slave_wait_for_bus(module);
mbed_official 579:53297373a894 526
mbed_official 579:53297373a894 527 if (status != STATUS_OK) {
mbed_official 579:53297373a894 528 /* Timeout, return */
mbed_official 579:53297373a894 529 return I2C_SLAVE_DIRECTION_NONE;
mbed_official 579:53297373a894 530 }
mbed_official 579:53297373a894 531
mbed_official 579:53297373a894 532 if (!(i2c_hw->INTFLAG.reg & SERCOM_I2CS_INTFLAG_AMATCH)) {
mbed_official 579:53297373a894 533 /* Not address interrupt, something is wrong */
mbed_official 579:53297373a894 534 return I2C_SLAVE_DIRECTION_NONE;
mbed_official 579:53297373a894 535 }
mbed_official 579:53297373a894 536
mbed_official 579:53297373a894 537 /* Check direction */
mbed_official 579:53297373a894 538 if ((i2c_hw->STATUS.reg & SERCOM_I2CS_STATUS_DIR)) {
mbed_official 579:53297373a894 539 /* Read request from master */
mbed_official 579:53297373a894 540 return I2C_SLAVE_DIRECTION_WRITE;
mbed_official 579:53297373a894 541 } else {
mbed_official 579:53297373a894 542 /* Write request from master */
mbed_official 579:53297373a894 543 return I2C_SLAVE_DIRECTION_READ;
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 * \brief Retrieves the current module status
mbed_official 579:53297373a894 549 *
mbed_official 579:53297373a894 550 * Checks the status of the module and returns it as a bitmask of status
mbed_official 579:53297373a894 551 * flags.
mbed_official 579:53297373a894 552 *
mbed_official 579:53297373a894 553 * \param[in] module Pointer to the I<SUP>2</SUP>C slave software device struct
mbed_official 579:53297373a894 554 *
mbed_official 579:53297373a894 555 * \return Bitmask of status flags.
mbed_official 579:53297373a894 556 *
mbed_official 579:53297373a894 557 * \retval I2C_SLAVE_STATUS_ADDRESS_MATCH A valid address has been received
mbed_official 579:53297373a894 558 * \retval I2C_SLAVE_STATUS_DATA_READY A I<SUP>2</SUP>C slave byte transmission is
mbed_official 579:53297373a894 559 * successfully completed
mbed_official 579:53297373a894 560 * \retval I2C_SLAVE_STATUS_STOP_RECEIVED A stop condition is detected for a
mbed_official 579:53297373a894 561 * transaction being processed
mbed_official 579:53297373a894 562 * \retval I2C_SLAVE_STATUS_CLOCK_HOLD The slave is holding the SCL line
mbed_official 579:53297373a894 563 * low
mbed_official 579:53297373a894 564 * \retval I2C_SLAVE_STATUS_SCL_LOW_TIMEOUT An SCL low time-out has occurred
mbed_official 579:53297373a894 565 * \retval I2C_SLAVE_STATUS_REPEATED_START Indicates a repeated start, only
mbed_official 579:53297373a894 566 * valid if \ref
mbed_official 579:53297373a894 567 * I2C_SLAVE_STATUS_ADDRESS_MATCH is
mbed_official 579:53297373a894 568 * set
mbed_official 579:53297373a894 569 * \retval I2C_SLAVE_STATUS_RECEIVED_NACK The last data packet sent was not
mbed_official 579:53297373a894 570 * acknowledged
mbed_official 579:53297373a894 571 * \retval I2C_SLAVE_STATUS_COLLISION The I<SUP>2</SUP>C slave was not able to
mbed_official 579:53297373a894 572 * transmit a high data or NACK bit
mbed_official 579:53297373a894 573 * \retval I2C_SLAVE_STATUS_BUS_ERROR An illegal bus condition has
mbed_official 579:53297373a894 574 * occurred on the bus
mbed_official 579:53297373a894 575 */
mbed_official 579:53297373a894 576 uint32_t i2c_slave_get_status(
mbed_official 579:53297373a894 577 struct i2c_slave_module *const module)
mbed_official 579:53297373a894 578 {
mbed_official 579:53297373a894 579 /* Sanity check arguments */
mbed_official 579:53297373a894 580 Assert(module);
mbed_official 579:53297373a894 581 Assert(module->hw);
mbed_official 579:53297373a894 582
mbed_official 579:53297373a894 583 SercomI2cs *const i2c_hw = &(module->hw->I2CS);
mbed_official 579:53297373a894 584
mbed_official 579:53297373a894 585 uint8_t intflags = i2c_hw->INTFLAG.reg;
mbed_official 579:53297373a894 586 uint8_t status = i2c_hw->STATUS.reg;
mbed_official 579:53297373a894 587 uint32_t status_flags = 0;
mbed_official 579:53297373a894 588
mbed_official 579:53297373a894 589 /* Check Address Match flag */
mbed_official 579:53297373a894 590 if (intflags & SERCOM_I2CS_INTFLAG_AMATCH) {
mbed_official 579:53297373a894 591 status_flags |= I2C_SLAVE_STATUS_ADDRESS_MATCH;
mbed_official 579:53297373a894 592 }
mbed_official 579:53297373a894 593 /* Check Data Ready flag */
mbed_official 579:53297373a894 594 if (intflags & SERCOM_I2CS_INTFLAG_DRDY) {
mbed_official 579:53297373a894 595 status_flags |= I2C_SLAVE_STATUS_DATA_READY;
mbed_official 579:53297373a894 596 }
mbed_official 579:53297373a894 597 /* Check Stop flag */
mbed_official 579:53297373a894 598 if (intflags & SERCOM_I2CS_INTFLAG_PREC) {
mbed_official 579:53297373a894 599 status_flags |= I2C_SLAVE_STATUS_STOP_RECEIVED;
mbed_official 579:53297373a894 600 }
mbed_official 579:53297373a894 601 /* Check Clock Hold */
mbed_official 579:53297373a894 602 if (status & SERCOM_I2CS_STATUS_CLKHOLD) {
mbed_official 579:53297373a894 603 status_flags |= I2C_SLAVE_STATUS_CLOCK_HOLD;
mbed_official 579:53297373a894 604 }
mbed_official 579:53297373a894 605 /* Check SCL Low Timeout */
mbed_official 579:53297373a894 606 if (status & SERCOM_I2CS_STATUS_LOWTOUT) {
mbed_official 579:53297373a894 607 status_flags |= I2C_SLAVE_STATUS_SCL_LOW_TIMEOUT;
mbed_official 579:53297373a894 608 }
mbed_official 579:53297373a894 609 /* Check Repeated Start */
mbed_official 579:53297373a894 610 if (status & SERCOM_I2CS_STATUS_SR) {
mbed_official 579:53297373a894 611 status_flags |= I2C_SLAVE_STATUS_REPEATED_START;
mbed_official 579:53297373a894 612 }
mbed_official 579:53297373a894 613 /* Check Received Not Acknowledge */
mbed_official 579:53297373a894 614 if (status & SERCOM_I2CS_STATUS_RXNACK) {
mbed_official 579:53297373a894 615 status_flags |= I2C_SLAVE_STATUS_RECEIVED_NACK;
mbed_official 579:53297373a894 616 }
mbed_official 579:53297373a894 617 /* Check Transmit Collision */
mbed_official 579:53297373a894 618 if (status & SERCOM_I2CS_STATUS_COLL) {
mbed_official 579:53297373a894 619 status_flags |= I2C_SLAVE_STATUS_COLLISION;
mbed_official 579:53297373a894 620 }
mbed_official 579:53297373a894 621 /* Check Bus Error */
mbed_official 579:53297373a894 622 if (status & SERCOM_I2CS_STATUS_BUSERR) {
mbed_official 579:53297373a894 623 status_flags |= I2C_SLAVE_STATUS_BUS_ERROR;
mbed_official 579:53297373a894 624 }
mbed_official 579:53297373a894 625
mbed_official 579:53297373a894 626 return status_flags;
mbed_official 579:53297373a894 627 }
mbed_official 579:53297373a894 628
mbed_official 579:53297373a894 629 /**
mbed_official 579:53297373a894 630 * \brief Clears a module status flag
mbed_official 579:53297373a894 631 *
mbed_official 579:53297373a894 632 * Clears the given status flag of the module.
mbed_official 579:53297373a894 633 *
mbed_official 579:53297373a894 634 * \note Not all status flags can be cleared.
mbed_official 579:53297373a894 635 *
mbed_official 579:53297373a894 636 * \param[in] module Pointer to the I<SUP>2</SUP>C software device struct
mbed_official 579:53297373a894 637 * \param[in] status_flags Bit mask of status flags to clear
mbed_official 579:53297373a894 638 *
mbed_official 579:53297373a894 639 */
mbed_official 579:53297373a894 640 void i2c_slave_clear_status(
mbed_official 579:53297373a894 641 struct i2c_slave_module *const module,
mbed_official 579:53297373a894 642 uint32_t status_flags)
mbed_official 579:53297373a894 643 {
mbed_official 579:53297373a894 644 /* Sanity check arguments */
mbed_official 579:53297373a894 645 Assert(module);
mbed_official 579:53297373a894 646 Assert(module->hw);
mbed_official 579:53297373a894 647
mbed_official 579:53297373a894 648 SercomI2cs *const i2c_hw = &(module->hw->I2CS);
mbed_official 579:53297373a894 649
mbed_official 579:53297373a894 650 /* Clear Address Match flag */
mbed_official 579:53297373a894 651 if (status_flags & I2C_SLAVE_STATUS_ADDRESS_MATCH) {
mbed_official 579:53297373a894 652 i2c_hw->INTFLAG.reg = SERCOM_I2CS_INTFLAG_AMATCH;
mbed_official 579:53297373a894 653 }
mbed_official 579:53297373a894 654 /* Clear Data Ready flag */
mbed_official 579:53297373a894 655 if (status_flags & I2C_SLAVE_STATUS_DATA_READY) {
mbed_official 579:53297373a894 656 i2c_hw->INTFLAG.reg = SERCOM_I2CS_INTFLAG_DRDY;
mbed_official 579:53297373a894 657 }
mbed_official 579:53297373a894 658 /* Clear Stop flag */
mbed_official 579:53297373a894 659 if (status_flags & I2C_SLAVE_STATUS_STOP_RECEIVED) {
mbed_official 579:53297373a894 660 i2c_hw->INTFLAG.reg = SERCOM_I2CS_INTFLAG_PREC;
mbed_official 579:53297373a894 661 }
mbed_official 579:53297373a894 662 /* Clear SCL Low Timeout */
mbed_official 579:53297373a894 663 if (status_flags & I2C_SLAVE_STATUS_SCL_LOW_TIMEOUT) {
mbed_official 579:53297373a894 664 i2c_hw->STATUS.reg = SERCOM_I2CS_STATUS_LOWTOUT;
mbed_official 579:53297373a894 665 }
mbed_official 579:53297373a894 666 /* Clear Transmit Collision */
mbed_official 579:53297373a894 667 if (status_flags & I2C_SLAVE_STATUS_COLLISION) {
mbed_official 579:53297373a894 668 i2c_hw->STATUS.reg = SERCOM_I2CS_STATUS_COLL;
mbed_official 579:53297373a894 669 }
mbed_official 579:53297373a894 670 /* Clear Bus Error */
mbed_official 579:53297373a894 671 if (status_flags & I2C_SLAVE_STATUS_BUS_ERROR) {
mbed_official 579:53297373a894 672 i2c_hw->STATUS.reg = SERCOM_I2CS_STATUS_BUSERR;
mbed_official 579:53297373a894 673 }
mbed_official 579:53297373a894 674 }