You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by ma...@apache.org on 2016/02/27 02:26:39 UTC

[37/51] [abbrv] [partial] incubator-mynewt-larva git commit: Arduino zero BSP and Atmel MCU in a different repository.

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/a280628a/hw/mcu/atmel/samd21xx/src/sam0/drivers/sercom/i2c/i2c_sam0/i2c_master_interrupt.c
----------------------------------------------------------------------
diff --git a/hw/mcu/atmel/samd21xx/src/sam0/drivers/sercom/i2c/i2c_sam0/i2c_master_interrupt.c b/hw/mcu/atmel/samd21xx/src/sam0/drivers/sercom/i2c/i2c_sam0/i2c_master_interrupt.c
deleted file mode 100755
index 10dfcdf..0000000
--- a/hw/mcu/atmel/samd21xx/src/sam0/drivers/sercom/i2c/i2c_sam0/i2c_master_interrupt.c
+++ /dev/null
@@ -1,755 +0,0 @@
-/**
- * \file
- *
- * \brief SAM I2C Master Interrupt Driver
- *
- * Copyright (C) 2012-2015 Atmel Corporation. All rights reserved.
- *
- * \asf_license_start
- *
- * \page License
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * 3. The name of Atmel may not be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * 4. This software may only be redistributed and used in connection with an
- *    Atmel microcontroller product.
- *
- * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
- * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * \asf_license_stop
- *
- */
-/*
- * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
- */
-
-#include "i2c_master_interrupt.h"
-
-extern enum status_code _i2c_master_wait_for_bus(
-		struct i2c_master_module *const module);
-
-extern enum status_code _i2c_master_address_response(
-		struct i2c_master_module *const module);
-
-extern enum status_code _i2c_master_send_hs_master_code(
-		struct i2c_master_module *const module,
-		uint8_t hs_master_code);;
-
-/**
- * \internal
- * Read next data. Used by interrupt handler to get next data byte from slave.
- *
- * \param[in,out] module  Pointer to software module structure
- */
-static void _i2c_master_read(
-		struct i2c_master_module *const module)
-{
-	/* Sanity check arguments. */
-	Assert(module);
-	Assert(module->hw);
-
-	SercomI2cm *const i2c_module = &(module->hw->I2CM);
-	bool sclsm_flag = i2c_module->CTRLA.bit.SCLSM;
-
-	/* Find index to save next value in buffer */
-	uint16_t buffer_index = module->buffer_length;
-	buffer_index -= module->buffer_remaining;
-
-	module->buffer_remaining--;
-
-	if (sclsm_flag) {
-		if (module->send_nack && module->buffer_remaining == 1) {
-			/* Set action to NACK. */
-			i2c_module->CTRLB.reg |= SERCOM_I2CM_CTRLB_ACKACT;
-		}
-	} else {
-		if (module->send_nack && module->buffer_remaining == 0) {
-			/* Set action to NACK. */
-			i2c_module->CTRLB.reg |= SERCOM_I2CM_CTRLB_ACKACT;
-		}
-	}
-
-	if (module->buffer_remaining == 0) {
-		if (module->send_stop) {
-			/* Send stop condition */
-			_i2c_master_wait_for_sync(module);
-			i2c_module->CTRLB.reg |= SERCOM_I2CM_CTRLB_CMD(3);
-		}
-	}
-	
-	/* Read byte from slave and put in buffer */
-	_i2c_master_wait_for_sync(module);
-	module->buffer[buffer_index] = i2c_module->DATA.reg;
-}
-
-/**
- * \internal
- *
- * Write next data. Used by interrupt handler to send next data byte to slave.
- *
- * \param[in,out] module  Pointer to software module structure
- */
-static void _i2c_master_write(struct i2c_master_module *const module)
-{
-	/* Sanity check arguments. */
-	Assert(module);
-	Assert(module->hw);
-
-	SercomI2cm *const i2c_module = &(module->hw->I2CM);
-
-	/* Check for ack from slave */
-	if (i2c_module->STATUS.reg & SERCOM_I2CM_STATUS_RXNACK)
-	{
-		/* Set status */
-		module->status = STATUS_ERR_OVERFLOW;
-		/* Do not write more data */
-		return;
-	}
-
-	/* Find index to get next byte in buffer */
-	uint16_t buffer_index = module->buffer_length;
-	buffer_index -= module->buffer_remaining;
-
-	module->buffer_remaining--;
-
-	/* Write byte from buffer to slave */
-	_i2c_master_wait_for_sync(module);
-	i2c_module->DATA.reg = module->buffer[buffer_index];
-}
-
-/**
- * \internal
- * Acts on slave address response. Checks for errors concerning master->slave
- * handshake.
- *
- * \param[in,out] module  Pointer to software module structure
- */
-static void _i2c_master_async_address_response(
-		struct i2c_master_module *const module)
-{
-	/* Sanity check arguments. */
-	Assert(module);
-	Assert(module->hw);
-
-	SercomI2cm *const i2c_module = &(module->hw->I2CM);
-
-	/* Check for error. Ignore bus-error; workaround for bus state stuck in
-	 * BUSY.
-	 */
-	if (i2c_module->INTFLAG.reg & SERCOM_I2CM_INTFLAG_MB)
-	{
-		/* Clear write interrupt flag */
-		i2c_module->INTFLAG.reg = SERCOM_I2CM_INTENCLR_MB;
-
-		/* Check arbitration */
-		if (i2c_module->STATUS.reg & SERCOM_I2CM_STATUS_ARBLOST) {
-			/* Return busy */
-			module->status = STATUS_ERR_PACKET_COLLISION;
-		}
-	} else if (i2c_module->STATUS.reg & SERCOM_I2CM_STATUS_RXNACK) {
-		/* Return bad address value */
-		module->status           = STATUS_ERR_BAD_ADDRESS;
-		module->buffer_remaining = 0;
-
-		if (module->send_stop) {
-			/* Send stop condition */
-			_i2c_master_wait_for_sync(module);
-			i2c_module->CTRLB.reg |= SERCOM_I2CM_CTRLB_CMD(3);
-		}
-	}
-
-	module->buffer_length = module->buffer_remaining;
-
-	/* Check for status OK. */
-	if (module->status == STATUS_BUSY) {
-		/* Call function based on transfer direction. */
-		if (module->transfer_direction == I2C_TRANSFER_WRITE) {
-			_i2c_master_write(module);
-		} else {
-			_i2c_master_read(module);
-		}
-	}
-}
-
-/**
- * \brief Registers callback for the specified callback type
- *
- * Associates the given callback function with the
- * specified callback type.
- *
- * To enable the callback, the \ref i2c_master_enable_callback function
- * must be used.
- *
- * \param[in,out]  module         Pointer to the software module struct
- * \param[in]      callback       Pointer to the function desired for the
- *                                specified callback
- * \param[in]      callback_type  Callback type to register
- */
-void i2c_master_register_callback(
-		struct i2c_master_module *const module,
-		const i2c_master_callback_t callback,
-		enum i2c_master_callback callback_type)
-{
-	/* Sanity check */
-	Assert(module);
-	Assert(module->hw);
-	Assert(callback);
-
-	/* Register callback */
-	module->callbacks[callback_type] = callback;
-
-	/* Set corresponding bit to set callback as registered */
-	module->registered_callback |= (1 << callback_type);
-}
-
-/**
- * \brief Unregisters callback for the specified callback type
- *
- * When called, the currently registered callback for the given callback type
- * will be removed.
- *
- * \param[in,out] module         Pointer to the software module struct
- * \param[in]     callback_type  Specifies the callback type to unregister
- */
-void i2c_master_unregister_callback(
-		struct i2c_master_module *const module,
-		enum i2c_master_callback callback_type)
-{
-	/* Sanity check */
-	Assert(module);
-	Assert(module->hw);
-
-	/* Register callback */
-	module->callbacks[callback_type] = NULL;
-
-	/* Clear corresponding bit to set callback as unregistered */
-	module->registered_callback &= ~(1 << callback_type);
-}
-
-/**
- * \internal
- * Starts a read bytes operation.
- *
- * \param[in,out] module  Pointer to software module struct
- * \param[in,out] packet  Pointer to I<SUP>2</SUP>C packet to transfer
- *
- * \return Status of starting reading I<SUP>2</SUP>C packet.
- * \retval STATUS_OK    If reading was started successfully
- * \retval STATUS_BUSY  If module is currently busy with another transfer
- */
-enum status_code i2c_master_read_bytes(
-		struct i2c_master_module *const module,
-		struct i2c_master_packet *const packet)
-{
-	/* Sanity check */
-	Assert(module);
-	Assert(module->hw);
-
-	SercomI2cm *const i2c_module = &(module->hw->I2CM);
-
-	/* Save packet to software module */
-	module->buffer             = packet->data;
-	module->buffer_remaining   = packet->data_length;
-	module->transfer_direction = I2C_TRANSFER_READ;
-	module->status             = STATUS_BUSY;
-	module->send_stop = false;
-	module->send_nack = false;
-	
-	/* Enable interrupts */
-	i2c_module->INTENSET.reg =
-			SERCOM_I2CM_INTENSET_MB | SERCOM_I2CM_INTENSET_SB;
-
-	return STATUS_OK;
-}
-
-/**
- * \internal
- * Starts a read packet operation.
- *
- * \param[in,out] module  Pointer to software module struct
- * \param[in,out] packet  Pointer to I<SUP>2</SUP>C packet to transfer
- *
- * \return Status of starting reading I<SUP>2</SUP>C packet.
- * \retval STATUS_OK    If reading was started successfully
- * \retval STATUS_BUSY  If module is currently busy with another transfer
- */
-static enum status_code _i2c_master_read_packet(
-		struct i2c_master_module *const module,
-		struct i2c_master_packet *const packet)
-{
-	/* Sanity check */
-	Assert(module);
-	Assert(module->hw);
-
-	SercomI2cm *const i2c_module = &(module->hw->I2CM);
-	enum status_code tmp_status;
-
-	/* Save packet to software module */
-	module->buffer             = packet->data;
-	module->buffer_remaining   = packet->data_length;
-	module->transfer_direction = I2C_TRANSFER_READ;
-	module->status             = STATUS_BUSY;
-
-	/* Switch to high speed mode */
-	if (packet->high_speed) {
-		_i2c_master_send_hs_master_code(module, packet->hs_master_code);
-	}
-
-	/* Set action to ACK. */
-	i2c_module->CTRLB.reg &= ~SERCOM_I2CM_CTRLB_ACKACT;
-
-	if (packet->ten_bit_address) {
-		/*
-		 * Write ADDR.ADDR[10:1] with the 10-bit address. ADDR.TENBITEN must
-		 * be set and read/write bit (ADDR.ADDR[0]) equal to 0.
-		 */
-		i2c_module->ADDR.reg = (packet->address << 1) |
-			(packet->high_speed << SERCOM_I2CM_ADDR_HS_Pos) |
-			SERCOM_I2CM_ADDR_TENBITEN;
-
-		/* Wait for response on bus. */
-		tmp_status = _i2c_master_wait_for_bus(module);
-
-		/* Set action to ack. */
-		i2c_module->CTRLB.reg &= ~SERCOM_I2CM_CTRLB_ACKACT;
-
-		/* Check for address response error unless previous error is
-		 * detected. */
-		if (tmp_status == STATUS_OK) {
-			tmp_status = _i2c_master_address_response(module);
-		}
-
-		if (tmp_status == STATUS_OK) {
-			/* Enable interrupts */
-			i2c_module->INTENSET.reg =
-				SERCOM_I2CM_INTENSET_MB | SERCOM_I2CM_INTENSET_SB;
-
-			/*
-			 * Write ADDR[7:0] register to "11110 address[9:8] 1"
-			 * ADDR.TENBITEN must be cleared
-			 */
-			i2c_module->ADDR.reg = (((packet->address >> 8) | 0x78) << 1) |
-				(packet->high_speed << SERCOM_I2CM_ADDR_HS_Pos) |
-				I2C_TRANSFER_READ;
-		} else {
-			return tmp_status;
-		}
-	} else {
-		/* Enable interrupts */
-		i2c_module->INTENSET.reg =
-			SERCOM_I2CM_INTENSET_MB | SERCOM_I2CM_INTENSET_SB;
-
-		/* Set address and direction bit. Will send start command on bus */
-		i2c_module->ADDR.reg = (packet->address << 1) | I2C_TRANSFER_READ |
-			(packet->high_speed << SERCOM_I2CM_ADDR_HS_Pos);
-	}
-
-	return STATUS_OK;
-}
-
-/**
- * \brief Initiates a read packet operation
- *
- * Reads a data packet from the specified slave address on the I<SUP>2</SUP>C
- * bus. This is the non-blocking equivalent of \ref i2c_master_read_packet_wait.
- *
- * \param[in,out] module  Pointer to software module struct
- * \param[in,out] packet  Pointer to I<SUP>2</SUP>C packet to transfer
- *
- * \return Status of starting reading I<SUP>2</SUP>C packet.
- * \retval STATUS_OK    If reading was started successfully
- * \retval STATUS_BUSY  If module is currently busy with another transfer
- */
-enum status_code i2c_master_read_packet_job(
-		struct i2c_master_module *const module,
-		struct i2c_master_packet *const packet)
-{
-	/* Sanity check */
-	Assert(module);
-	Assert(module->hw);
-	Assert(packet);
-
-	/* Check if the I2C module is busy with a job */
-	if (module->buffer_remaining > 0) {
-		return STATUS_BUSY;
-	}
-
-	/* Make sure we send STOP */
-	module->send_stop = true;
-	module->send_nack = true;
-	/* Start reading */
-	return _i2c_master_read_packet(module, packet);
-}
-
-/**
- * \brief Initiates a read packet operation without sending a STOP condition when done
- *
- * Reads a data packet from the specified slave address on the I<SUP>2</SUP>C bus without
- * sending a stop condition, thus retaining ownership of the bus when done.
- * To end the transaction, a \ref i2c_master_read_packet_wait "read" or
- * \ref i2c_master_write_packet_wait "write" with stop condition must be
- * performed.
- *
- * This is the non-blocking equivalent of \ref i2c_master_read_packet_wait_no_stop.
- *
- * \param[in,out] module  Pointer to software module struct
- * \param[in,out] packet  Pointer to I<SUP>2</SUP>C packet to transfer
- *
- * \return Status of starting reading I<SUP>2</SUP>C packet.
- * \retval STATUS_OK   If reading was started successfully
- * \retval STATUS_BUSY If module is currently busy with another operation
- */
-enum status_code i2c_master_read_packet_job_no_stop(
-		struct i2c_master_module *const module,
-		struct i2c_master_packet *const packet)
-{
-	/* Sanity check */
-	Assert(module);
-	Assert(module->hw);
-	Assert(packet);
-
-	/* Check if the I2C module is busy with a job */
-	if (module->buffer_remaining > 0) {
-		return STATUS_BUSY;
-	}
-
-	/* Make sure we don't send STOP */
-	module->send_stop = false;
-	module->send_nack = true;
-	/* Start reading */
-	return _i2c_master_read_packet(module, packet);
-}
-
-/**
- * \brief Initiates a read packet operation without sending a NACK signal and a 
- * STOP condition when done
- *
- * Reads a data packet from the specified slave address on the I<SUP>2</SUP>C bus without
- * sending a nack and a stop condition, thus retaining ownership of the bus when done.
- * To end the transaction, a \ref i2c_master_read_packet_wait "read" or
- * \ref i2c_master_write_packet_wait "write" with stop condition must be
- * performed.
- *
- * This is the non-blocking equivalent of \ref i2c_master_read_packet_wait_no_stop.
- *
- * \param[in,out] module  Pointer to software module struct
- * \param[in,out] packet  Pointer to I<SUP>2</SUP>C packet to transfer
- *
- * \return Status of starting reading I<SUP>2</SUP>C packet.
- * \retval STATUS_OK   If reading was started successfully
- * \retval STATUS_BUSY If module is currently busy with another operation
- */
-enum status_code i2c_master_read_packet_job_no_nack(
-		struct i2c_master_module *const module,
-		struct i2c_master_packet *const packet)
-{
-	/* Sanity check */
-	Assert(module);
-	Assert(module->hw);
-	Assert(packet);
-
-	/* Check if the I2C module is busy with a job */
-	if (module->buffer_remaining > 0) {
-		return STATUS_BUSY;
-	}
-
-	/* Make sure we don't send STOP */
-	module->send_stop = false;
-	module->send_nack = false;
-	/* Start reading */
-	return _i2c_master_read_packet(module, packet);
-}
-
-/**
- * \internal
- * Starts a write bytes operation.
- *
- * \param[in,out] module  Pointer to software module struct
- * \param[in,out] packet  Pointer to I<SUP>2</SUP>C packet to transfer
- *
- * \return Status of starting write I<SUP>2</SUP>C bytes.
- * \retval STATUS_OK    If writing was started successfully
- * \retval STATUS_BUSY  If module is currently busy with another transfer
- */
-enum status_code i2c_master_write_bytes(
-		struct i2c_master_module *const module,
-		struct i2c_master_packet *const packet)
-{
-	/* Sanity check */
-	Assert(module);
-	Assert(module->hw);
-
-	SercomI2cm *const i2c_module = &(module->hw->I2CM);
-
-	/* Save packet to software module */
-	module->buffer             = packet->data;
-	module->buffer_remaining   = packet->data_length;
-	module->transfer_direction = I2C_TRANSFER_WRITE;
-	module->status             = STATUS_BUSY;
-	module->send_stop = false;
-	module->send_nack = false;
-	
-	/* Enable interrupts */
-	i2c_module->INTENSET.reg =
-			SERCOM_I2CM_INTENSET_MB | SERCOM_I2CM_INTENSET_SB;
-
-	return STATUS_OK;
-}
-
-/**
- * \internal Initiates a write packet operation
- *
- * \param[in,out] module  Pointer to software module struct
- * \param[in,out] packet  Pointer to I<SUP>2</SUP>C packet to transfer
- *
- * \return Status of starting writing I<SUP>2</SUP>C packet job.
- * \retval STATUS_OK   If writing was started successfully
- * \retval STATUS_BUSY If module is currently busy with another transfer
- */
-static enum status_code _i2c_master_write_packet(
-		struct i2c_master_module *const module,
-		struct i2c_master_packet *const packet)
-{
-	/* Sanity check */
-	Assert(module);
-	Assert(module->hw);
-
-	SercomI2cm *const i2c_module = &(module->hw->I2CM);
-
-	/* Switch to high speed mode */
-	if (packet->high_speed) {
-		_i2c_master_send_hs_master_code(module, packet->hs_master_code);
-	}
-
-	/* Set action to ACK. */
-	i2c_module->CTRLB.reg &= ~SERCOM_I2CM_CTRLB_ACKACT;
-
-	/* Save packet to software module */
-	module->buffer             = packet->data;
-	module->buffer_remaining   = packet->data_length;
-	module->transfer_direction = I2C_TRANSFER_WRITE;
-	module->status             = STATUS_BUSY;
-
-	/* Enable interrupts */
-	i2c_module->INTENSET.reg =
-			SERCOM_I2CM_INTENSET_MB | SERCOM_I2CM_INTENSET_SB;
-
-	/* Set address and direction bit, will send start command on bus */
-	if (packet->ten_bit_address) {
-		i2c_module->ADDR.reg = (packet->address << 1) | I2C_TRANSFER_WRITE |
-			(packet->high_speed << SERCOM_I2CM_ADDR_HS_Pos) |
-			SERCOM_I2CM_ADDR_TENBITEN;
-	} else {
-		i2c_module->ADDR.reg = (packet->address << 1) | I2C_TRANSFER_WRITE |
-			(packet->high_speed << SERCOM_I2CM_ADDR_HS_Pos);
-	}
-
-	return STATUS_OK;
-}
-
-/**
- * \brief Initiates a write packet operation
- *
- * Writes a data packet to the specified slave address on the I<SUP>2</SUP>C
- * bus. This is the non-blocking equivalent of \ref i2c_master_write_packet_wait.
- *
- * \param[in,out] module  Pointer to software module struct
- * \param[in,out] packet  Pointer to I<SUP>2</SUP>C packet to transfer
- *
- * \return Status of starting writing I<SUP>2</SUP>C packet job.
- * \retval STATUS_OK    If writing was started successfully
- * \retval STATUS_BUSY  If module is currently busy with another transfer
- */
-enum status_code i2c_master_write_packet_job(
-		struct i2c_master_module *const module,
-		struct i2c_master_packet *const packet)
-{
-	/* Sanity check */
-	Assert(module);
-	Assert(module->hw);
-	Assert(packet);
-
-	/* Check if the I2C module is busy with another job. */
-	if (module->buffer_remaining > 0) {
-		return STATUS_BUSY;
-	}
-
-	/* Make sure we send STOP at end*/
-	module->send_stop = true;
-	module->send_nack = true;
-	/* Start write operation */
-	return _i2c_master_write_packet(module, packet);
-}
-
-/**
- * \brief Initiates a write packet operation without sending a STOP condition when done
- *
- * Writes a data packet to the specified slave address on the I<SUP>2</SUP>C bus
- * without sending a stop condition, thus retaining ownership of the bus when
- * done. To end the transaction, a \ref i2c_master_read_packet_wait "read" or
- * \ref i2c_master_write_packet_wait "write" with stop condition or sending
- * a stop with the \ref i2c_master_send_stop function must be performed.
- *
- * This is the non-blocking equivalent of \ref i2c_master_write_packet_wait_no_stop.
- *
- * \param[in,out] module  Pointer to software module struct
- * \param[in,out] packet  Pointer to I<SUP>2</SUP>C packet to transfer
- *
- * \return Status of starting writing I<SUP>2</SUP>C packet job.
- * \retval STATUS_OK    If writing was started successfully
- * \retval STATUS_BUSY  If module is currently busy with another
- */
-enum status_code i2c_master_write_packet_job_no_stop(
-		struct i2c_master_module *const module,
-		struct i2c_master_packet *const packet)
-{
-	/* Sanity check */
-	Assert(module);
-	Assert(module->hw);
-	Assert(packet);
-
-	/* Check if the I2C module is busy with another job. */
-	if (module->buffer_remaining > 0) {
-		return STATUS_BUSY;
-	}
-
-	/* Do not send stop condition when done */
-	module->send_stop = false;
-	module->send_nack = true;
-	/* Start write operation */
-	return _i2c_master_write_packet(module, packet);
-}
-
-/**
- * \internal
- * Interrupt handler for I<SUP>2</SUP>C master.
- *
- * \param[in] instance  SERCOM instance that triggered the interrupt
- */
-void _i2c_master_interrupt_handler(
-		uint8_t instance)
-{
-	/* Get software module for callback handling */
-	struct i2c_master_module *module =
-			(struct i2c_master_module*)_sercom_instances[instance];
-
-	Assert(module);
-
-	SercomI2cm *const i2c_module = &(module->hw->I2CM);
-	bool sclsm_flag = i2c_module->CTRLA.bit.SCLSM;
-
-	/* Combine callback registered and enabled masks */
-	uint8_t callback_mask = module->enabled_callback;
-	callback_mask &= module->registered_callback;
-
-	/* Check if the module should respond to address ack */
-	if ((module->buffer_length <= 0) && (module->buffer_remaining > 0)) {
-		/* Call function for address response */
-		_i2c_master_async_address_response(module);
-
-	/* Check if buffer write is done */
-	} else if ((module->buffer_length > 0) && (module->buffer_remaining <= 0) &&
-			(module->status == STATUS_BUSY) &&
-			(module->transfer_direction == I2C_TRANSFER_WRITE)) {
-		/* Stop packet operation */
-		i2c_module->INTENCLR.reg =
-				SERCOM_I2CM_INTENCLR_MB | SERCOM_I2CM_INTENCLR_SB;
-
-		module->buffer_length = 0;
-		module->status        = STATUS_OK;
-
-		if (module->send_stop) {
-			/* Send stop condition */
-			_i2c_master_wait_for_sync(module);
-			i2c_module->CTRLB.reg |= SERCOM_I2CM_CTRLB_CMD(3);
-		} else {
-			/* Clear write interrupt flag */
-			i2c_module->INTFLAG.reg = SERCOM_I2CM_INTFLAG_MB;
-		}
-		
-		if (callback_mask & (1 << I2C_MASTER_CALLBACK_WRITE_COMPLETE)) {
-			module->callbacks[I2C_MASTER_CALLBACK_WRITE_COMPLETE](module);
-		}
-
-	/* Continue buffer write/read */
-	} else if ((module->buffer_length > 0) && (module->buffer_remaining > 0)){
-		/* Check that bus ownership is not lost */
-		if ((!(i2c_module->STATUS.reg & SERCOM_I2CM_STATUS_BUSSTATE(2))) &&
-				(!(sclsm_flag && (module->buffer_remaining == 1))))	{
-			module->status = STATUS_ERR_PACKET_COLLISION;
-		} else if (module->transfer_direction == I2C_TRANSFER_WRITE) {
-			_i2c_master_write(module);
-		} else {
-			_i2c_master_read(module);
-		}
-	}
-
-	/* Check if read buffer transfer is complete */
-	if ((module->buffer_length > 0) && (module->buffer_remaining <= 0) &&
-			(module->status == STATUS_BUSY) &&
-			(module->transfer_direction == I2C_TRANSFER_READ)) {
-		
-		/* Clear read interrupt flag */
-		if (i2c_module->INTFLAG.reg & SERCOM_I2CM_INTFLAG_SB) {
-			i2c_module->INTFLAG.reg = SERCOM_I2CM_INTFLAG_SB;
-		}
-		/* Stop packet operation */
-		i2c_module->INTENCLR.reg =
-				SERCOM_I2CM_INTENCLR_MB | SERCOM_I2CM_INTENCLR_SB;
-		module->buffer_length = 0;
-		module->status        = STATUS_OK;
-
-		/* Call appropriate callback if enabled and registered */
-		if ((callback_mask & (1 << I2C_MASTER_CALLBACK_READ_COMPLETE))
-				&& (module->transfer_direction == I2C_TRANSFER_READ)) {
-			module->callbacks[I2C_MASTER_CALLBACK_READ_COMPLETE](module);
-		} else if ((callback_mask & (1 << I2C_MASTER_CALLBACK_WRITE_COMPLETE))
-				&& (module->transfer_direction == I2C_TRANSFER_WRITE)) {
-			module->callbacks[I2C_MASTER_CALLBACK_WRITE_COMPLETE](module);
-		}
-	}
-
-	/* Check for error */
-	if ((module->status != STATUS_BUSY) && (module->status != STATUS_OK)) {
-		/* Stop packet operation */
-		i2c_module->INTENCLR.reg = SERCOM_I2CM_INTENCLR_MB |
-				SERCOM_I2CM_INTENCLR_SB;
-
-		module->buffer_length = 0;
-		module->buffer_remaining = 0;
-
-		/* Send nack and stop command unless arbitration is lost */
-		if ((module->status != STATUS_ERR_PACKET_COLLISION) &&
-				module->send_stop) {
-			_i2c_master_wait_for_sync(module);
-			i2c_module->CTRLB.reg |= SERCOM_I2CM_CTRLB_ACKACT |
-					SERCOM_I2CM_CTRLB_CMD(3);
-		}
-
-		/* Call error callback if enabled and registered */
-		if (callback_mask & (1 << I2C_MASTER_CALLBACK_ERROR)) {
-			module->callbacks[I2C_MASTER_CALLBACK_ERROR](module);
-		}
-	}
-}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/a280628a/hw/mcu/atmel/samd21xx/src/sam0/drivers/sercom/i2c/i2c_sam0/i2c_slave.c
----------------------------------------------------------------------
diff --git a/hw/mcu/atmel/samd21xx/src/sam0/drivers/sercom/i2c/i2c_sam0/i2c_slave.c b/hw/mcu/atmel/samd21xx/src/sam0/drivers/sercom/i2c/i2c_sam0/i2c_slave.c
deleted file mode 100755
index 4bb968d..0000000
--- a/hw/mcu/atmel/samd21xx/src/sam0/drivers/sercom/i2c/i2c_sam0/i2c_slave.c
+++ /dev/null
@@ -1,745 +0,0 @@
-/**
- * \file
- *
- * \brief SAM I2C Slave Driver
- *
- * Copyright (C) 2013-2015 Atmel Corporation. All rights reserved.
- *
- * \asf_license_start
- *
- * \page License
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * 3. The name of Atmel may not be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * 4. This software may only be redistributed and used in connection with an
- *    Atmel microcontroller product.
- *
- * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
- * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * \asf_license_stop
- *
- */
-/*
- * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
- */
-
-#include "i2c_slave.h"
-#if I2C_SLAVE_CALLBACK_MODE == true
-#  include "i2c_slave_interrupt.h"
-#endif
-
-/**
- * \internal Sets configuration to module
- *
- * \param[out] module  Pointer to software module structure
- * \param[in]  config  Configuration structure with configurations to set
- *
- * \return Status of setting configuration.
- * \retval STATUS_OK                       Module was configured correctly
- * \retval STATUS_ERR_ALREADY_INITIALIZED  If setting other GCLK generator than
- *                                         previously set
- */
-static enum status_code _i2c_slave_set_config(
-		struct i2c_slave_module *const module,
-		const struct i2c_slave_config *const config)
-{
-	uint32_t tmp_ctrla;
-
-	/* Sanity check arguments */
-	Assert(module);
-	Assert(module->hw);
-	Assert(config);
-
-	SercomI2cs *const i2c_hw = &(module->hw->I2CS);
-	Sercom *const sercom_hw = module->hw;
-
-	module->buffer_timeout = config->buffer_timeout;
-	module->ten_bit_address = config->ten_bit_address;
-
-	struct system_pinmux_config pin_conf;
-	system_pinmux_get_config_defaults(&pin_conf);
-
-	uint32_t pad0 = config->pinmux_pad0;
-	uint32_t pad1 = config->pinmux_pad1;
-
-	/* SERCOM PAD0 - SDA */
-	if (pad0 == PINMUX_DEFAULT) {
-		pad0 = _sercom_get_default_pad(sercom_hw, 0);
-	}
-	pin_conf.mux_position = pad0 & 0xFFFF;
-	pin_conf.direction    = SYSTEM_PINMUX_PIN_DIR_OUTPUT_WITH_READBACK;
-	system_pinmux_pin_set_config(pad0 >> 16, &pin_conf);
-
-	/* SERCOM PAD1 - SCL */
-	if (pad1 == PINMUX_DEFAULT) {
-		pad1 = _sercom_get_default_pad(sercom_hw, 1);
-	}
-	pin_conf.mux_position = pad1 & 0xFFFF;
-	pin_conf.direction    = SYSTEM_PINMUX_PIN_DIR_OUTPUT_WITH_READBACK;
-	system_pinmux_pin_set_config(pad1 >> 16, &pin_conf);
-
-	/* Prepare config to write to register CTRLA */
-	if (config->run_in_standby || system_is_debugger_present()) {
-		tmp_ctrla = SERCOM_I2CS_CTRLA_RUNSTDBY;
-	} else {
-		tmp_ctrla = 0;
-	}
-
-	/* Check and set SCL clock stretch mode. */
-	if (config->scl_stretch_only_after_ack_bit || (config->transfer_speed == I2C_SLAVE_SPEED_HIGH_SPEED)) {
-		tmp_ctrla |= SERCOM_I2CM_CTRLA_SCLSM;
-	}
-	
-	tmp_ctrla |= ((uint32_t)config->sda_hold_time |
-			config->transfer_speed |
-			(config->scl_low_timeout << SERCOM_I2CS_CTRLA_LOWTOUTEN_Pos) |
-			(config->slave_scl_low_extend_timeout << SERCOM_I2CS_CTRLA_SEXTTOEN_Pos));
-
-	i2c_hw->CTRLA.reg |= tmp_ctrla;
-
-	/* Set CTRLB configuration */
-	i2c_hw->CTRLB.reg = SERCOM_I2CS_CTRLB_SMEN | config->address_mode;
-
-	i2c_hw->ADDR.reg = config->address << SERCOM_I2CS_ADDR_ADDR_Pos |
-			config->address_mask << SERCOM_I2CS_ADDR_ADDRMASK_Pos |
-			config->ten_bit_address << SERCOM_I2CS_ADDR_TENBITEN_Pos |
-			config->enable_general_call_address << SERCOM_I2CS_ADDR_GENCEN_Pos;
-
-	return STATUS_OK;
-}
-
-/**
- * \brief Initializes the requested I<SUP>2</SUP>C hardware module
- *
- * Initializes the SERCOM I<SUP>2</SUP>C slave device requested and sets the provided
- * software module struct.  Run this function before any further use of
- * the driver.
- *
- * \param[out] module  Pointer to software module struct
- * \param[in]  hw      Pointer to the hardware instance
- * \param[in]  config  Pointer to the configuration struct
- *
- * \return Status of initialization.
- * \retval STATUS_OK                       Module initiated correctly
- * \retval STATUS_ERR_DENIED               If module is enabled
- * \retval STATUS_BUSY                     If module is busy resetting
- * \retval STATUS_ERR_ALREADY_INITIALIZED  If setting other GCLK generator than
- *                                         previously set
- */
-enum status_code i2c_slave_init(
-		struct i2c_slave_module *const module,
-		Sercom *const hw,
-		const struct i2c_slave_config *const config)
-{
-	/* Sanity check arguments */
-	Assert(module);
-	Assert(hw);
-	Assert(config);
-
-	/* Initialize software module */
-	module->hw = hw;
-
-	SercomI2cs *const i2c_hw = &(module->hw->I2CS);
-
-	/* Check if module is enabled */
-	if (i2c_hw->CTRLA.reg & SERCOM_I2CS_CTRLA_ENABLE) {
-		return STATUS_ERR_DENIED;
-	}
-
-	/* Check if reset is in progress */
-	if (i2c_hw->CTRLA.reg & SERCOM_I2CS_CTRLA_SWRST) {
-		return STATUS_BUSY;
-	}
-
-	uint32_t sercom_index = _sercom_get_sercom_inst_index(module->hw);
-	uint32_t pm_index, gclk_index; 
-#if (SAML21) || (SAML22) || (SAMC20) || (SAMC21)
-#if (SAML21)
-	if (sercom_index == 5) {
-		pm_index     = MCLK_APBDMASK_SERCOM5_Pos;
-		gclk_index   = SERCOM5_GCLK_ID_CORE;
-	} else {
-		pm_index     = sercom_index + MCLK_APBCMASK_SERCOM0_Pos;
-		gclk_index   = sercom_index + SERCOM0_GCLK_ID_CORE;
-	}
-#else
-	pm_index     = sercom_index + MCLK_APBCMASK_SERCOM0_Pos;
-	gclk_index   = sercom_index + SERCOM0_GCLK_ID_CORE;
-#endif
-#else
-	pm_index     = sercom_index + PM_APBCMASK_SERCOM0_Pos;
-	gclk_index   = sercom_index + SERCOM0_GCLK_ID_CORE;
-#endif
-	
-	/* Turn on module in PM */
-#if (SAML21)
-	if (sercom_index == 5) {
-		system_apb_clock_set_mask(SYSTEM_CLOCK_APB_APBD, 1 << pm_index);
-	} else {
-		system_apb_clock_set_mask(SYSTEM_CLOCK_APB_APBC, 1 << pm_index);	
-	}
-#else
-	system_apb_clock_set_mask(SYSTEM_CLOCK_APB_APBC, 1 << pm_index);
-#endif
-
-	/* Set up the GCLK for the module */
-	struct system_gclk_chan_config gclk_chan_conf;
-	system_gclk_chan_get_config_defaults(&gclk_chan_conf);
-	gclk_chan_conf.source_generator = config->generator_source;
-	system_gclk_chan_set_config(gclk_index, &gclk_chan_conf);
-	system_gclk_chan_enable(gclk_index);
-	sercom_set_gclk_generator(config->generator_source, false);
-
-#if I2C_SLAVE_CALLBACK_MODE == true
-	/* Get sercom instance index */
-	uint8_t instance_index = _sercom_get_sercom_inst_index(module->hw);
-
-	/* Save software module in interrupt handler */
-	_sercom_set_handler(instance_index, _i2c_slave_interrupt_handler);
-
-	/* Save software module */
-	_sercom_instances[instance_index] = module;
-
-	/* Initialize values in module */
-	module->registered_callback = 0;
-	module->enabled_callback = 0;
-	module->buffer_length = 0;
-	module->nack_on_address = config->enable_nack_on_address;
-#endif
-
-	/* Set SERCOM module to operate in I2C slave mode */
-	i2c_hw->CTRLA.reg = SERCOM_I2CS_CTRLA_MODE(0x4);
-
-	/* Set config and return status */
-	return _i2c_slave_set_config(module, config);
-}
-
-/**
- * \brief Resets the hardware module
- *
- * This will reset the module to hardware defaults.
- *
- * \param[in,out] module  Pointer to software module structure
- */
-void i2c_slave_reset(
-		struct i2c_slave_module *const module)
-{
-	/* Sanity check arguments */
-	Assert(module);
-	Assert(module->hw);
-
-	SercomI2cs *const i2c_hw = &(module->hw->I2CS);
-
-#if I2C_SLAVE_CALLBACK_MODE == true
-	/* Reset module instance */
-	module->registered_callback = 0;
-	module->enabled_callback = 0;
-	module->buffer_length = 0;
-	module->buffer_remaining = 0;
-	module->buffer = NULL;
-#endif
-
-	/* Disable module */
-	i2c_slave_disable(module);
-
-#if I2C_SLAVE_CALLBACK_MODE == true
-	/* Clear all pending interrupts */
-	system_interrupt_enter_critical_section();
-	system_interrupt_clear_pending(_sercom_get_interrupt_vector(module->hw));
-	system_interrupt_leave_critical_section();
-#endif
-
-	/* Wait for sync */
-	_i2c_slave_wait_for_sync(module);
-
-	/* Reset module */
-	i2c_hw->CTRLA.reg = SERCOM_I2CS_CTRLA_SWRST;
-}
-
-/**
- * \internal Waits for answer on bus
- *
- * \param[in]  module  Pointer to software module structure
- *
- * \return Status of bus.
- * \retval STATUS_OK           If given response from slave device
- * \retval STATUS_ERR_TIMEOUT  If no response was given within specified timeout
- *                             period
- */
-static enum status_code _i2c_slave_wait_for_bus(
-		struct i2c_slave_module *const module)
-{
-	/* Sanity check arguments */
-	Assert(module);
-	Assert(module->hw);
-
-	SercomI2cm *const i2c_module = &(module->hw->I2CM);
-
-	/* Wait for reply */
-	uint16_t timeout_counter = 0;
-	while ((!(i2c_module->INTFLAG.reg & SERCOM_I2CS_INTFLAG_DRDY)) &&
-			(!(i2c_module->INTFLAG.reg & SERCOM_I2CS_INTFLAG_PREC)) &&
-			(!(i2c_module->INTFLAG.reg & SERCOM_I2CS_INTFLAG_AMATCH))) {
-
-		/* Check timeout condition */
-		if (++timeout_counter >= module->buffer_timeout) {
-			return STATUS_ERR_TIMEOUT;
-		}
-	}
-	return STATUS_OK;
-}
-
-/**
- * \brief Writes a packet to the master
- *
- * Writes a packet to the master. This will wait for the master to issue
- * a request.
- *
- * \param[in]  module  Pointer to software module structure
- * \param[in]  packet  Packet to write to master
- *
- * \return Status of packet write.
- * \retval STATUS_OK                Packet was written successfully
- * \retval STATUS_ERR_DENIED        Start condition not received, another
- *                                  interrupt flag is set
- * \retval STATUS_ERR_IO            There was an error in the previous transfer
- * \retval STATUS_ERR_BAD_FORMAT    Master wants to write data
- * \retval STATUS_ERR_INVALID_ARG   Invalid argument(s) was provided
- * \retval STATUS_ERR_BUSY          The I<SUP>2</SUP>C module is busy with a job
- * \retval STATUS_ERR_ERR_OVERFLOW  Master NACKed before entire packet was
- *                                  transferred
- * \retval STATUS_ERR_TIMEOUT       No response was given within the timeout
- *                                  period
- */
-enum status_code i2c_slave_write_packet_wait(
-		struct i2c_slave_module *const module,
-		struct i2c_slave_packet *const packet)
-{
-	/* Sanity check arguments */
-	Assert(module);
-	Assert(module->hw);
-	Assert(packet);
-
-	SercomI2cs *const i2c_hw = &(module->hw->I2CS);
-
-	uint16_t length = packet->data_length;
-
-	if (length == 0) {
-		return STATUS_ERR_INVALID_ARG;
-	}
-
-#if I2C_SLAVE_CALLBACK_MODE == true
-	/* Check if the module is busy with a job or AMATCH is enabled */
-	if (module->buffer_remaining > 0 ||
-			(i2c_hw->INTENSET.reg & SERCOM_I2CS_INTFLAG_AMATCH)) {
-		return STATUS_BUSY;
-	}
-#endif
-
-	enum status_code status;
-	/* Wait for master to send address packet */
-	status = _i2c_slave_wait_for_bus(module);
-
-	if (status != STATUS_OK) {
-			/* Timeout, return */
-			return status;
-	}
-	if (!(i2c_hw->INTFLAG.reg & SERCOM_I2CS_INTFLAG_AMATCH)) {
-		/* Not address interrupt, something is wrong */
-		return STATUS_ERR_DENIED;
-	}
-
-	if (module->ten_bit_address) {
-		/* ACK the first address */
-		i2c_hw->CTRLB.reg &= ~SERCOM_I2CS_CTRLB_ACKACT;
-		i2c_hw->CTRLB.reg |= SERCOM_I2CS_CTRLB_CMD(0x3);
-
-		/* Wait for address interrupt */
-		status = _i2c_slave_wait_for_bus(module);
-
-		if (status != STATUS_OK) {
-			/* Timeout, return */
-			return STATUS_ERR_TIMEOUT;
-		}
-
-		if (!(i2c_hw->INTFLAG.reg & SERCOM_I2CS_INTFLAG_AMATCH)) {
-			/* Not address interrupt, something is wrong */
-			return STATUS_ERR_DENIED;
-		}
-	}
-
-	/* Check if there was an error in last transfer */
-	if (i2c_hw->STATUS.reg & (SERCOM_I2CS_STATUS_BUSERR |
-			SERCOM_I2CS_STATUS_COLL | SERCOM_I2CS_STATUS_LOWTOUT)) {
-		return STATUS_ERR_IO;
-	}
-
-	/* Check direction */
-	if (!(i2c_hw->STATUS.reg & SERCOM_I2CS_STATUS_DIR)) {
-		/* Write request from master, send NACK and return */
-		i2c_hw->CTRLB.reg |= SERCOM_I2CS_CTRLB_ACKACT;
-		i2c_hw->CTRLB.reg |= SERCOM_I2CS_CTRLB_CMD(0x3);
-		return STATUS_ERR_BAD_FORMAT;
-	}
-
-	/* Read request from master, ACK address */
-	i2c_hw->CTRLB.reg &= ~SERCOM_I2CS_CTRLB_ACKACT;
-	i2c_hw->CTRLB.reg |= SERCOM_I2CS_CTRLB_CMD(0x3);
-
-	uint16_t i = 0;
-
-	/* Wait for data interrupt */
-	status = _i2c_slave_wait_for_bus(module);
-	if (status != STATUS_OK) {
-			/* Timeout, return */
-			return status;
-	}
-
-	while (length--) {
-		/* Write data */
-		_i2c_slave_wait_for_sync(module);
-		i2c_hw->DATA.reg = packet->data[i++];
-
-		/* Wait for response from master */
-		status = _i2c_slave_wait_for_bus(module);
-
-		if (status != STATUS_OK) {
-			/* Timeout, return */
-			return status;
-		}
-
-		if (i2c_hw->STATUS.reg & SERCOM_I2CS_STATUS_RXNACK &&
-				length !=0) {
-			/* NACK from master, abort */
-			/* Release line */
-			i2c_hw->CTRLB.reg |= SERCOM_I2CS_CTRLB_CMD(0x02);
-
-			return STATUS_ERR_OVERFLOW;
-		}
-		/* ACK from master, continue writing */
-	}
-
-	/* Release line */
-	i2c_hw->CTRLB.reg |= SERCOM_I2CS_CTRLB_CMD(0x02);
-
-	return STATUS_OK;
-}
-
-/**
- * \brief Reads a packet from the master
- *
- * Reads a packet from the master. This will wait for the master to issue a
- * request.
- *
- * \param[in]  module  Pointer to software module structure
- * \param[out] packet  Packet to read from master
- *
- * \return Status of packet read.
- * \retval STATUS_OK                Packet was read successfully
- * \retval STATUS_ABORTED           Master sent stop condition or repeated
- *                                  start before specified length of bytes
- *                                  was received
- * \retval STATUS_ERR_IO            There was an error in the previous transfer
- * \retval STATUS_ERR_DENIED        Start condition not received, another
- *                                  interrupt flag is set
- * \retval STATUS_ERR_INVALID_ARG   Invalid argument(s) was provided
- * \retval STATUS_ERR_BUSY          The I<SUP>2</SUP>C module is busy with a job
- * \retval STATUS_ERR_BAD_FORMAT    Master wants to read data
- * \retval STATUS_ERR_ERR_OVERFLOW  Last byte received overflows buffer
- */
-enum status_code i2c_slave_read_packet_wait(
-		struct i2c_slave_module *const module,
-		struct i2c_slave_packet *const packet)
-{
-	/* Sanity check arguments */
-	Assert(module);
-	Assert(module->hw);
-	Assert(packet);
-
-	SercomI2cs *const i2c_hw = &(module->hw->I2CS);
-
-	uint16_t length = packet->data_length;
-
-	if (length == 0) {
-		return STATUS_ERR_INVALID_ARG;
-	}
-
-#if I2C_SLAVE_CALLBACK_MODE == true
-	/* Check if the module is busy with a job or AMATCH is enabled */
-	if (module->buffer_remaining > 0 ||
-			(i2c_hw->INTENSET.reg & SERCOM_I2CS_INTFLAG_AMATCH)) {
-		return STATUS_BUSY;
-	}
-#endif
-
-	enum status_code status;
-
-	/* Wait for master to send address packet */
-	status = _i2c_slave_wait_for_bus(module);
-	if (status != STATUS_OK) {
-		/* Timeout, return */
-		return status;
-	}
-
-	if (!(i2c_hw->INTFLAG.reg & SERCOM_I2CS_INTFLAG_AMATCH)) {
-		/* Not address interrupt, something is wrong */
-		return STATUS_ERR_DENIED;
-	}
-
-	/* Check if there was an error in the last transfer */
-	if (i2c_hw->STATUS.reg & (SERCOM_I2CS_STATUS_BUSERR |
-			SERCOM_I2CS_STATUS_COLL | SERCOM_I2CS_STATUS_LOWTOUT)) {
-		return STATUS_ERR_IO;
-	}
-	/* Check direction */
-	if ((i2c_hw->STATUS.reg & SERCOM_I2CS_STATUS_DIR)) {
-		/* Read request from master, send NACK and return */
-		i2c_hw->CTRLB.reg |= SERCOM_I2CS_CTRLB_ACKACT;
-		i2c_hw->CTRLB.reg |= SERCOM_I2CS_CTRLB_CMD(0x3);
-		return STATUS_ERR_BAD_FORMAT;
-	}
-
-	/* Write request from master, ACK address */
-	i2c_hw->CTRLB.reg &= ~SERCOM_I2CS_CTRLB_ACKACT;
-	i2c_hw->CTRLB.reg |= SERCOM_I2CS_CTRLB_CMD(0x3);
-
-	uint16_t i = 0;
-	while (length--) {
-
-		/* Wait for next byte or stop condition */
-		status = _i2c_slave_wait_for_bus(module);
-		if (status != STATUS_OK) {
-			/* Timeout, return */
-			return status;
-		}
-
-		if ((i2c_hw->INTFLAG.reg & SERCOM_I2CS_INTFLAG_PREC) ||
-				i2c_hw->INTFLAG.reg & SERCOM_I2CS_INTFLAG_AMATCH) {
-			/* Master sent stop condition, or repeated start, read done */
-			/* Clear stop flag */
-			i2c_hw->INTFLAG.reg = SERCOM_I2CS_INTFLAG_PREC;
-			return STATUS_ABORTED;
-		}
-
-		/* Read data */
-		_i2c_slave_wait_for_sync(module);
-		packet->data[i++] = i2c_hw->DATA.reg;
-
-	}
-
-	/* Packet read done, wait for packet to NACK, Stop or repeated start */
-	status = _i2c_slave_wait_for_bus(module);
-
-	if (i2c_hw->INTFLAG.reg & SERCOM_I2CS_INTFLAG_DRDY) {
-		/* Buffer is full, send NACK */
-		i2c_hw->CTRLB.reg |= SERCOM_I2CS_CTRLB_ACKACT;
-		i2c_hw->CTRLB.reg |= SERCOM_I2CS_CTRLB_CMD(0x2);
-	}
-	if (i2c_hw->INTFLAG.reg & SERCOM_I2CS_INTFLAG_PREC) {
-		/* Clear stop flag */
-		i2c_hw->INTFLAG.reg = SERCOM_I2CS_INTFLAG_PREC;
-	}
-	return STATUS_OK;
-}
-
-/**
- * \brief Waits for a start condition on the bus
- *
- * \note This function is only available for 7-bit slave addressing.
- *
- * Waits for the master to issue a start condition on the bus.
- * 
- * \note This function does not check for errors in the last transfer,
- * this will be discovered when reading or writing.
- *
- * \param[in]  module  Pointer to software module structure
- *
- * \return Direction of the current transfer, when in slave mode.
- * \retval I2C_SLAVE_DIRECTION_NONE   No request from master within timeout
- *                                    period
- * \retval I2C_SLAVE_DIRECTION_READ   Write request from master
- * \retval I2C_SLAVE_DIRECTION_WRITE  Read request from master
- */
-enum i2c_slave_direction i2c_slave_get_direction_wait(
-		struct i2c_slave_module *const module)
-{
-	/* Sanity check arguments */
-	Assert(module);
-	Assert(module->hw);
-
-	SercomI2cs *const i2c_hw = &(module->hw->I2CS);
-
-	enum status_code status;
-
-	/* Wait for address interrupt */
-	status = _i2c_slave_wait_for_bus(module);
-
-	if (status != STATUS_OK) {
-		/* Timeout, return */
-		return I2C_SLAVE_DIRECTION_NONE;
-	}
-
-	if (!(i2c_hw->INTFLAG.reg & SERCOM_I2CS_INTFLAG_AMATCH)) {
-		/* Not address interrupt, something is wrong */
-		return I2C_SLAVE_DIRECTION_NONE;
-	}
-
-	/* Check direction */
-	if ((i2c_hw->STATUS.reg & SERCOM_I2CS_STATUS_DIR)) {
-		/* Read request from master */
-		return I2C_SLAVE_DIRECTION_WRITE;
-	} else {
-		/* Write request from master */
-		return I2C_SLAVE_DIRECTION_READ;
-	}
-}
-
-/**
- * \brief Retrieves the current module status
- *
- * Checks the status of the module and returns it as a bitmask of status
- * flags.
- *
- * \param[in] module      Pointer to the I<SUP>2</SUP>C slave software device struct
- *
- * \return Bitmask of status flags.
- *
- * \retval I2C_SLAVE_STATUS_ADDRESS_MATCH   A valid address has been received
- * \retval I2C_SLAVE_STATUS_DATA_READY      A I<SUP>2</SUP>C slave byte transmission is
- *                                          successfully completed
- * \retval I2C_SLAVE_STATUS_STOP_RECEIVED   A stop condition is detected for a
- *                                          transaction being processed
- * \retval I2C_SLAVE_STATUS_CLOCK_HOLD      The slave is holding the SCL line
- *                                          low
- * \retval I2C_SLAVE_STATUS_SCL_LOW_TIMEOUT An SCL low time-out has occurred
- * \retval I2C_SLAVE_STATUS_REPEATED_START  Indicates a repeated start, only
- *                                          valid if \ref
- *                                          I2C_SLAVE_STATUS_ADDRESS_MATCH is
- *                                          set
- * \retval I2C_SLAVE_STATUS_RECEIVED_NACK   The last data packet sent was not
- *                                          acknowledged
- * \retval I2C_SLAVE_STATUS_COLLISION       The I<SUP>2</SUP>C slave was not able to
- *                                          transmit a high data or NACK bit
- * \retval I2C_SLAVE_STATUS_BUS_ERROR       An illegal bus condition has
- *                                          occurred on the bus
- */
-uint32_t i2c_slave_get_status(
-		struct i2c_slave_module *const module)
-{
-	/* Sanity check arguments */
-	Assert(module);
-	Assert(module->hw);
-
-	SercomI2cs *const i2c_hw = &(module->hw->I2CS);
-
-	uint8_t intflags = i2c_hw->INTFLAG.reg;
-	uint8_t status = i2c_hw->STATUS.reg;
-	uint32_t status_flags = 0;
-
-	/* Check Address Match flag */
-	if (intflags & SERCOM_I2CS_INTFLAG_AMATCH) {
-		status_flags |= I2C_SLAVE_STATUS_ADDRESS_MATCH;
-	}
-	/* Check Data Ready flag */
-	if (intflags & SERCOM_I2CS_INTFLAG_DRDY) {
-		status_flags |= I2C_SLAVE_STATUS_DATA_READY;
-	}
-	/* Check Stop flag */
-	if (intflags & SERCOM_I2CS_INTFLAG_PREC) {
-		status_flags |= I2C_SLAVE_STATUS_STOP_RECEIVED;
-	}
-	/* Check Clock Hold */
-	if (status & SERCOM_I2CS_STATUS_CLKHOLD) {
-		status_flags |= I2C_SLAVE_STATUS_CLOCK_HOLD;
-	}
-	/* Check SCL Low Timeout */
-	if (status & SERCOM_I2CS_STATUS_LOWTOUT) {
-		status_flags |= I2C_SLAVE_STATUS_SCL_LOW_TIMEOUT;
-	}
-	/* Check Repeated Start */
-	if (status & SERCOM_I2CS_STATUS_SR) {
-		status_flags |= I2C_SLAVE_STATUS_REPEATED_START;
-	}
-	/* Check Received Not Acknowledge */
-	if (status & SERCOM_I2CS_STATUS_RXNACK) {
-		status_flags |= I2C_SLAVE_STATUS_RECEIVED_NACK;
-	}
-	/* Check Transmit Collision */
-	if (status & SERCOM_I2CS_STATUS_COLL) {
-		status_flags |= I2C_SLAVE_STATUS_COLLISION;
-	}
-	/* Check Bus Error */
-	if (status & SERCOM_I2CS_STATUS_BUSERR) {
-		status_flags |= I2C_SLAVE_STATUS_BUS_ERROR;
-	}
-
-	return status_flags;
-}
-
-/**
- * \brief Clears a module status flag
- *
- * Clears the given status flag of the module.
- *
- * \note Not all status flags can be cleared.
- *
- * \param[in] module         Pointer to the I<SUP>2</SUP>C software device struct
- * \param[in] status_flags   Bit mask of status flags to clear
- *
- */
-void i2c_slave_clear_status(
-		struct i2c_slave_module *const module,
-		uint32_t status_flags)
-{
-	/* Sanity check arguments */
-	Assert(module);
-	Assert(module->hw);
-
-	SercomI2cs *const i2c_hw = &(module->hw->I2CS);
-
-	/* Clear Address Match flag */
-	if (status_flags & I2C_SLAVE_STATUS_ADDRESS_MATCH) {
-		i2c_hw->INTFLAG.reg = SERCOM_I2CS_INTFLAG_AMATCH;
-	}
-	/* Clear Data Ready flag */
-	if (status_flags & I2C_SLAVE_STATUS_DATA_READY) {
-		i2c_hw->INTFLAG.reg = SERCOM_I2CS_INTFLAG_DRDY;
-	}
-	/* Clear Stop flag */
-	if (status_flags & I2C_SLAVE_STATUS_STOP_RECEIVED) {
-		i2c_hw->INTFLAG.reg = SERCOM_I2CS_INTFLAG_PREC;
-	}
-	/* Clear SCL Low Timeout */
-	if (status_flags & I2C_SLAVE_STATUS_SCL_LOW_TIMEOUT) {
-		i2c_hw->STATUS.reg = SERCOM_I2CS_STATUS_LOWTOUT;
-	}
-	/* Clear Transmit Collision */
-	if (status_flags & I2C_SLAVE_STATUS_COLLISION) {
-		i2c_hw->STATUS.reg = SERCOM_I2CS_STATUS_COLL;
-	}
-	/* Clear Bus Error */
-	if (status_flags & I2C_SLAVE_STATUS_BUS_ERROR) {
-		i2c_hw->STATUS.reg = SERCOM_I2CS_STATUS_BUSERR;
-	}
-}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/a280628a/hw/mcu/atmel/samd21xx/src/sam0/drivers/sercom/i2c/i2c_sam0/i2c_slave_interrupt.c
----------------------------------------------------------------------
diff --git a/hw/mcu/atmel/samd21xx/src/sam0/drivers/sercom/i2c/i2c_sam0/i2c_slave_interrupt.c b/hw/mcu/atmel/samd21xx/src/sam0/drivers/sercom/i2c/i2c_sam0/i2c_slave_interrupt.c
deleted file mode 100755
index 0a6f234..0000000
--- a/hw/mcu/atmel/samd21xx/src/sam0/drivers/sercom/i2c/i2c_sam0/i2c_slave_interrupt.c
+++ /dev/null
@@ -1,434 +0,0 @@
-/**
- * \file
- *
- * \brief SAM I2C Slave Interrupt Driver
- *
- * Copyright (c) 2013-2015 Atmel Corporation. All rights reserved.
- *
- * \asf_license_start
- *
- * \page License
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * 3. The name of Atmel may not be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * 4. This software may only be redistributed and used in connection with an
- *    Atmel microcontroller product.
- *
- * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
- * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * \asf_license_stop
- *
- */
-/*
- * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
- */
-
-#include "i2c_slave_interrupt.h"
-
-/**
- * \brief Enables sending of NACK on address match
- *
- * Enables sending of NACK on address match, thus discarding
- * any incoming transaction.
- *
- * \param[in,out] module  Pointer to software module structure
- */
-void i2c_slave_enable_nack_on_address(
-		struct i2c_slave_module *const module)
-{
-	/* Sanity check arguments. */
-	Assert(module);
-
-	module->nack_on_address = true;
-}
-
-/**
- * \brief Disables sending NACK on address match
- *
- * Disables sending of NACK on address match, thus
- * acknowledging incoming transactions.
- *
- * \param[in,out] module  Pointer to software module structure
- */
-void i2c_slave_disable_nack_on_address(
-		struct i2c_slave_module *const module)
-{
-	/* Sanity check arguments. */
-	Assert(module);
-
-	module->nack_on_address = false;
-}
-
-/**
- * \internal
- * Reads next data. Used by interrupt handler to get next data byte from master.
- *
- * \param[in,out] module  Pointer to software module structure
- */
-static void _i2c_slave_read(
-		struct i2c_slave_module *const module)
-{
-	SercomI2cs *const i2c_hw = &(module->hw->I2CS);
-
-	/* Read byte from master and put in buffer. */
-	*(module->buffer++) = i2c_hw->DATA.reg;
-
-	/*Decrement remaining buffer length */
-	module->buffer_remaining--;
-}
-
-/**
- * \internal
- * Writes next data. Used by interrupt handler to send next data byte to master.
- *
- * \param[in,out] module  Pointer to software module structure
- */
-static void _i2c_slave_write(
-		struct i2c_slave_module *const module)
-{
-	SercomI2cs *const i2c_hw = &(module->hw->I2CS);
-
-	/* Write byte from buffer to master */
-	i2c_hw->DATA.reg = *(module->buffer++);
-
-	/*Decrement remaining buffer length */
-	module->buffer_remaining--;
-}
-
-/**
- * \brief Registers callback for the specified callback type
- *
- * Associates the given callback function with the
- * specified callback type. To enable the callback, the
- * \ref i2c_slave_enable_callback function must be used.
- *
- * \param[in,out] module         Pointer to the software module struct
- * \param[in]     callback       Pointer to the function desired for the
- *                               specified callback
- * \param[in]     callback_type  Callback type to register
- */
-void i2c_slave_register_callback(
-		struct i2c_slave_module *const module,
-		i2c_slave_callback_t callback,
-		enum i2c_slave_callback callback_type)
-{
-	/* Sanity check. */
-	Assert(module);
-	Assert(module->hw);
-	Assert(callback);
-
-	/* Register callback. */
-	module->callbacks[callback_type] = callback;
-
-	/* Set corresponding bit to set callback as initiated. */
-	module->registered_callback |= (1 << callback_type);
-}
-
-/**
- * \brief Unregisters callback for the specified callback type
- *
- * Removes the currently registered callback for the given callback
- * type.
- *
- * \param[in,out]  module         Pointer to the software module struct
- * \param[in]      callback_type  Callback type to unregister
- */
-void i2c_slave_unregister_callback(
-		struct i2c_slave_module *const module,
-		enum i2c_slave_callback callback_type)
-{
-	/* Sanity check. */
-	Assert(module);
-	Assert(module->hw);
-
-	/* Register callback. */
-	module->callbacks[callback_type] = NULL;
-
-	/* Set corresponding bit to set callback as initiated. */
-	module->registered_callback &= ~(1 << callback_type);
-}
-
-/**
- * \brief Initiates a reads packet operation
- *
- * Reads a data packet from the master. A write request must be initiated by
- * the master before the packet can be read.
- *
- * The \ref I2C_SLAVE_CALLBACK_WRITE_REQUEST callback can be used to call this
- * function.
- *
- * \param[in,out] module  Pointer to software module struct
- * \param[in,out] packet  Pointer to I<SUP>2</SUP>C packet to transfer
- *
- * \return Status of starting asynchronously reading I<SUP>2</SUP>C packet.
- * \retval STATUS_OK    If reading was started successfully
- * \retval STATUS_BUSY  If module is currently busy with another transfer
- */
-enum status_code i2c_slave_read_packet_job(
-		struct i2c_slave_module *const module,
-		struct i2c_slave_packet *const packet)
-{
-	/* Sanity check */
-	Assert(module);
-	Assert(module->hw);
-	Assert(packet);
-
-	/* Check if the I2C module is busy doing async operation. */
-	if (module->buffer_remaining > 0) {
-		return STATUS_BUSY;
-	}
-
-	/* Save packet to software module. */
-	module->buffer           = packet->data;
-	module->buffer_remaining = packet->data_length;
-	module->buffer_length    = packet->data_length;
-	module->status           = STATUS_BUSY;
-
-	/* Enable interrupts */
-	SercomI2cs *const i2c_hw = &(module->hw->I2CS);
-	i2c_hw->INTENSET.reg = SERCOM_I2CS_INTFLAG_AMATCH |
-			SERCOM_I2CS_INTFLAG_DRDY | SERCOM_I2CS_INTFLAG_PREC;
-
-	/* Read will begin when master initiates the transfer */
-	return STATUS_OK;
-}
-
-/**
- * \brief Initiates a write packet operation
- *
- * Writes a data packet to the master. A read request must be initiated by
- * the master before the packet can be written.
- *
- * The \ref I2C_SLAVE_CALLBACK_READ_REQUEST callback can be used to call this
- * function.
- *
- * \param[in,out] module  Pointer to software module struct
- * \param[in,out] packet  Pointer to I<SUP>2</SUP>C packet to transfer
- *
- * \return Status of starting writing I<SUP>2</SUP>C packet.
- * \retval STATUS_OK   If writing was started successfully
- * \retval STATUS_BUSY If module is currently busy with another transfer
- */
-enum status_code i2c_slave_write_packet_job(
-		struct i2c_slave_module *const module,
-		struct i2c_slave_packet *const packet)
-{
-	/* Sanity check */
-	Assert(module);
-	Assert(module->hw);
-	Assert(packet);
-
-	/* Check if the I2C module is busy doing async operation. */
-	if (module->buffer_remaining > 0) {
-		return STATUS_BUSY;
-	}
-
-	/* Save packet to software module. */
-	module->buffer           = packet->data;
-	module->buffer_remaining = packet->data_length;
-	module->buffer_length    = packet->data_length;
-	module->status           = STATUS_BUSY;
-
-	/* Enable interrupts */
-	SercomI2cs *const i2c_hw = &(module->hw->I2CS);
-	i2c_hw->INTENSET.reg = SERCOM_I2CS_INTFLAG_AMATCH |
-			SERCOM_I2CS_INTFLAG_DRDY | SERCOM_I2CS_INTFLAG_PREC;
-
-	return STATUS_OK;
-}
-
-/**
- * \internal Interrupt handler for I<SUP>2</SUP>C slave
- *
- * \param[in] instance Sercom instance that triggered the interrupt
- */
-void _i2c_slave_interrupt_handler(
-		uint8_t instance)
-{
-	/* Get software module for callback handling. */
-	struct i2c_slave_module *module =
-			(struct i2c_slave_module*)_sercom_instances[instance];
-
-	Assert(module);
-
-	SercomI2cs *const i2c_hw = &(module->hw->I2CS);
-
-	/* Combine callback registered and enabled masks. */
-	uint8_t callback_mask = module->enabled_callback;
-	callback_mask &= module->registered_callback;
-
-
-	if (i2c_hw->INTFLAG.reg & SERCOM_I2CS_INTFLAG_AMATCH) {
-	/* Address match */
-		/* Check if last transfer is done - repeated start */
-		if (module->buffer_length != module->buffer_remaining &&
-				module->transfer_direction == I2C_TRANSFER_WRITE) {
-
-			module->status = STATUS_OK;
-			module->buffer_length = 0;
-			module->buffer_remaining = 0;
-
-			if ((callback_mask & (1 << I2C_SLAVE_CALLBACK_READ_COMPLETE))) {
-				module->callbacks[I2C_SLAVE_CALLBACK_READ_COMPLETE](module);
-			}
-		} else if (module->buffer_length != module->buffer_remaining &&
-				module->transfer_direction == I2C_TRANSFER_READ) {
-			module->status = STATUS_OK;
-			module->buffer_length = 0;
-			module->buffer_remaining = 0;
-
-			if ((callback_mask & (1 << I2C_SLAVE_CALLBACK_WRITE_COMPLETE))) {
-				module->callbacks[I2C_SLAVE_CALLBACK_WRITE_COMPLETE](module);
-			}
-		}
-
-		if (i2c_hw->STATUS.reg & (SERCOM_I2CS_STATUS_BUSERR |
-				SERCOM_I2CS_STATUS_COLL | SERCOM_I2CS_STATUS_LOWTOUT)) {
-			/* An error occurred in last packet transfer */
-			module->status = STATUS_ERR_IO;
-
-			if ((callback_mask & (1 << I2C_SLAVE_CALLBACK_ERROR_LAST_TRANSFER))) {
-				module->callbacks[I2C_SLAVE_CALLBACK_ERROR_LAST_TRANSFER](module);
-			}
-		}
-		if (module->nack_on_address) {
-			/* NACK address, workaround 13574 */
-			_i2c_slave_set_ctrlb_ackact(module, false);
-		} else if (i2c_hw->STATUS.reg & SERCOM_I2CS_STATUS_DIR) {
-			/* Set transfer direction in module instance */
-			module->transfer_direction = I2C_TRANSFER_READ;
-
-			/* Read request from master */
-			if (callback_mask & (1 << I2C_SLAVE_CALLBACK_READ_REQUEST)) {
-				module->callbacks[I2C_SLAVE_CALLBACK_READ_REQUEST](module);
-			}
-
-			if (module->buffer_length == 0) {
-				/* Data buffer not set up, NACK address, workaround 13574*/
-				_i2c_slave_set_ctrlb_ackact(module, false);
-			} else {
-				/* ACK address, workaround 13574 */
-				_i2c_slave_set_ctrlb_ackact(module, true);
-			}
-		} else {
-			/* Set transfer direction in dev inst */
-			module->transfer_direction = I2C_TRANSFER_WRITE;
-
-			/* Write request from master */
-			if (callback_mask & (1 << I2C_SLAVE_CALLBACK_WRITE_REQUEST)) {
-				module->callbacks[I2C_SLAVE_CALLBACK_WRITE_REQUEST](module);
-			}
-
-			if (module->buffer_length == 0) {
-				/* Data buffer not set up, NACK address, workaround 13574 */
-				_i2c_slave_set_ctrlb_ackact(module, false);
-			} else {
-				/* ACK address, workaround 13574 */
-				_i2c_slave_set_ctrlb_ackact(module, true);
-			}
-		}
-
-		/* ACK or NACK address, Workaround 13574 */
-		_i2c_slave_set_ctrlb_cmd3(module);
-
-		/* ACK next incoming packet, workaround 13574 */
-		_i2c_slave_set_ctrlb_ackact(module, true);
-
-	} else if (i2c_hw->INTFLAG.reg & SERCOM_I2CS_INTFLAG_PREC) {
-		/* Stop condition on bus - current transfer done */
-
-		/* Clear Stop interrupt */
-		i2c_hw->INTFLAG.reg = SERCOM_I2CS_INTFLAG_PREC;
-
-		/* Disable interrupts */
-		i2c_hw->INTENCLR.reg = SERCOM_I2CS_INTFLAG_PREC | SERCOM_I2CS_INTFLAG_DRDY;
-
-		if (!((module->enabled_callback & (1 << I2C_SLAVE_CALLBACK_READ_REQUEST))
-				|| (module->enabled_callback == (1 << I2C_SLAVE_CALLBACK_WRITE_REQUEST)))) {
-			/* Disable address match if read/write request is not enabled */
-			i2c_hw->INTENCLR.reg = SERCOM_I2CS_INTFLAG_AMATCH;
-		}
-
-		if (!(module->status == STATUS_ERR_OVERFLOW || module->status == STATUS_ERR_IO)) {
-			module->status = STATUS_OK;
-			module->buffer_length = 0;
-			module->buffer_remaining = 0;
-
-			/* Call appropriate callback if enabled and registered */
-			if ((callback_mask & (1 << I2C_SLAVE_CALLBACK_READ_COMPLETE))
-					&& (module->transfer_direction == I2C_TRANSFER_WRITE)) {
-				/* Read from master complete */
-				module->callbacks[I2C_SLAVE_CALLBACK_READ_COMPLETE](module);
-			} else if ((callback_mask & (1 << I2C_SLAVE_CALLBACK_WRITE_COMPLETE))
-					&& (module->transfer_direction == I2C_TRANSFER_READ)) {
-				/* Write to master complete */
-				module->callbacks[I2C_SLAVE_CALLBACK_WRITE_COMPLETE](module);
-			}
-					}
-	} else if (i2c_hw->INTFLAG.reg & SERCOM_I2CS_INTFLAG_DRDY) {
-		/* Check if buffer is full, or NACK from master */
-		if (module->buffer_remaining <= 0 ||
-				(module->transfer_direction == I2C_TRANSFER_READ &&
-				(module->buffer_length > module->buffer_remaining) &&
-				(i2c_hw->STATUS.reg & SERCOM_I2CS_STATUS_RXNACK))) {
-
-			module->buffer_remaining = 0;
-			module->buffer_length = 0;
-
-			if (module->transfer_direction == I2C_TRANSFER_WRITE) {
-				/* Buffer is full, send NACK, workaround 13574 */
-				_i2c_slave_set_ctrlb_ackact(module, false);
-				i2c_hw->CTRLB.reg |= SERCOM_I2CS_CTRLB_CMD(0x2);
-
-				/* Set status, new character in DATA register will overflow
-				 * buffer */
-				module->status = STATUS_ERR_OVERFLOW;
-
-				if (callback_mask & (1 << I2C_SLAVE_CALLBACK_ERROR)) {
-					/* Read complete */
-					module->callbacks[I2C_SLAVE_CALLBACK_ERROR](module);
-				}
-			} else {
-				/* Release SCL and wait for new start condition */
-				_i2c_slave_set_ctrlb_ackact(module, false);
-				i2c_hw->CTRLB.reg |= SERCOM_I2CS_CTRLB_CMD(0x2);
-
-				/* Transfer successful */
-				module->status = STATUS_OK;
-
-				/* Disable interrupts */
-				i2c_hw->INTENCLR.reg = SERCOM_I2CS_INTFLAG_DRDY;
-			}
-
-		/* Continue buffer write/read */
-		} else if (module->buffer_length > 0 && module->buffer_remaining > 0) {
-			/* Call function based on transfer direction */
-			if (module->transfer_direction == I2C_TRANSFER_WRITE) {
-				_i2c_slave_read(module);
-			} else {
-				_i2c_slave_write(module);
-			}
-		}
-	}
-}

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