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 */

Reply via email to