http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/a280628a/hw/mcu/atmel/samd21xx/src/sam0/drivers/sercom/spi_master_vec/spi_master_vec.c
----------------------------------------------------------------------
diff --git 
a/hw/mcu/atmel/samd21xx/src/sam0/drivers/sercom/spi_master_vec/spi_master_vec.c 
b/hw/mcu/atmel/samd21xx/src/sam0/drivers/sercom/spi_master_vec/spi_master_vec.c
deleted file mode 100755
index 39a7327..0000000
--- 
a/hw/mcu/atmel/samd21xx/src/sam0/drivers/sercom/spi_master_vec/spi_master_vec.c
+++ /dev/null
@@ -1,586 +0,0 @@
-/**
- * \file
- *
- * \brief SERCOM SPI master with vectored I/O driver implementation
- *
- * 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 "spi_master_vec.h"
-#include <sercom_interrupt.h>
-#include <system.h>
-#include <system_interrupt.h>
-
-/**
- * \ingroup asfdoc_sam0_sercom_spi_master_vec_group
- *
- * @{
- */
-
-/**
- * \name Internal functions
- * @{
- */
-
-/** \cond INTERNAL */
-
-static void _spi_master_vec_int_handler(uint8_t sercom_index);
-
-/**
- * \brief Wait for SERCOM SPI to synchronize
- *
- * \param[in] sercom_spi SERCOM SPI to check for synchronization.
- *
- * \note The implementation of this function depends on the SERCOM revision.
- */
-static inline void _spi_master_vec_wait_for_sync(SercomSpi *const sercom_spi)
-{
-#if defined(FEATURE_SERCOM_SYNCBUSY_SCHEME_VERSION_1)
-       while (sercom_spi->STATUS.reg & SERCOM_SPI_STATUS_SYNCBUSY) {
-               /* Intentionally left empty */
-       }
-#elif defined(FEATURE_SERCOM_SYNCBUSY_SCHEME_VERSION_2)
-       while (sercom_spi->SYNCBUSY.reg) {
-               /* Intentionally left empty */
-       }
-#else
-#  error Unknown SERCOM SYNCBUSY scheme!
-#endif
-}
-
-/**
- * \brief Pin MUX configuration helper
- *
- * \param[in] pinmux Pin MUX setting to apply. Special values:
- * \arg \c PINMUX_UNUSED to do nothing.
- * \arg \c PINMUX_DEFAULT to use default pin MUX for the SERCOM pad.
- * \param[in] sercom,padnum SERCOM pad specification, for \ref PINMUX_DEFAULT.
- */
-static inline void _spi_master_vec_pinmux_helper(uint32_t pinmux,
-               Sercom *const sercom, uint8_t padnum)
-{
-       struct system_pinmux_config pin_conf;
-
-       if (pinmux == PINMUX_DEFAULT) {
-               pinmux = _sercom_get_default_pad(sercom, padnum);
-       }
-
-       if (pinmux == PINMUX_UNUSED) {
-               return;
-       }
-
-       system_pinmux_get_config_defaults(&pin_conf);
-       pin_conf.mux_position = pinmux & 0xFFFF;
-       system_pinmux_pin_set_config(pinmux >> 16, &pin_conf);
-};
-
-/** \endcond */
-
-/** @} */
-
-/**
- * \brief Initialize hardware and driver instance
- *
- * This function configures the clock system for the specified SERCOM module,
- * sets up the related pins and their MUX, initializes the SERCOM in SPI master
- * mode, and prepares the driver instance for operation.
- *
- * \pre \ref system_init() must have been called prior to this function.
- *
- * The SERCOM SPI module is left disabled after initialization, and must be
- * enabled with \ref spi_master_vec_enable() before a transfer can be done.
- *
- * \param[out] module Driver instance to initialize.
- * \param[in,out] sercom SERCOM module to initialize and associate driver
- * instance with.
- * \param[in] config Driver configuration to use.
- *
- * \return Status of initialization.
- * \retval STATUS_OK if initialization succeeded.
- * \retval STATUS_ERR_INVALID_ARG if driver has been misconfigured.
- */
-enum status_code spi_master_vec_init(struct spi_master_vec_module *const 
module,
-               Sercom *const sercom, const struct spi_master_vec_config *const 
config)
-{
-       Assert(module);
-       Assert(sercom);
-       Assert(config);
-
-       enum status_code status;
-       SercomSpi *const spi_hw = &(sercom->SPI);
-       struct system_gclk_chan_config gclk_chan_conf;
-       uint16_t tmp_baud;
-       uint32_t sercom_index = _sercom_get_sercom_inst_index((Sercom *)spi_hw);
-#if (SAML21) || (SAML22) || (SAMC20) || (SAMC21)
-       uint32_t pm_index = sercom_index + MCLK_APBCMASK_SERCOM0_Pos;
-#else
-       uint32_t pm_index = sercom_index + PM_APBCMASK_SERCOM0_Pos;
-#endif
-       uint32_t gclk_index = sercom_index + SERCOM0_GCLK_ID_CORE;
-       uint32_t gclk_hz;
-
-       module->sercom = sercom;
-
-       /* Enable clock for the module interface */
-       system_apb_clock_set_mask(SYSTEM_CLOCK_APB_APBC, 1 << pm_index);
-
-       /* Set up the GCLK for the module */
-       system_gclk_chan_get_config_defaults(&gclk_chan_conf);
-       gclk_chan_conf.source_generator = config->gclk_generator;
-       system_gclk_chan_set_config(gclk_index, &gclk_chan_conf);
-       system_gclk_chan_enable(gclk_index);
-       sercom_set_gclk_generator(config->gclk_generator, false);
-
-       _spi_master_vec_wait_for_sync(spi_hw);
-
-       /* Set up the SERCOM SPI module as master */
-       spi_hw->CTRLA.reg = SERCOM_SPI_CTRLA_MODE(0x3);
-       spi_hw->CTRLA.reg |= (uint32_t)config->mux_setting
-                       | config->transfer_mode
-                       | config->data_order
-                       | ((config->run_in_standby || 
system_is_debugger_present()) ?
-                                       SERCOM_SPI_CTRLA_RUNSTDBY : 0);
-
-       /* Get baud value from configured baudrate and internal clock rate */
-       gclk_hz = system_gclk_chan_get_hz(gclk_index);
-       status = _sercom_get_sync_baud_val(config->baudrate, gclk_hz, 
&tmp_baud);
-
-       if (status != STATUS_OK) {
-               /* Baud rate calculation error! */
-               return STATUS_ERR_INVALID_ARG;
-       }
-
-       spi_hw->BAUD.reg = (uint8_t)tmp_baud;
-
-       /* Configure the pin multiplexers */
-       _spi_master_vec_pinmux_helper(config->pinmux_pad0, sercom, 0);
-       _spi_master_vec_pinmux_helper(config->pinmux_pad3, sercom, 3);
-
-       /* SERCOM PAD1 and PAD2 are used for slave SS.
-        * This is a SPI master driver, so control of slave SS must be left to
-        * the PORT module, i.e., peripheral MUX should not be set for that pin.
-        * DOPO controls which PAD is used for slave SS:
-        * If DOPO is odd, SERCOM_PAD1 is SS: SERCOM_PAD2 can be MUXed.
-        * If DOPO is even, SERCOM_PAD2 is SS: SERCOM_PAD1 can be MUXed.
-        */
-       if (config->mux_setting & (1 << SERCOM_SPI_CTRLA_DOPO_Pos)) {
-               _spi_master_vec_pinmux_helper(config->pinmux_pad2, sercom, 2);
-       } else {
-               _spi_master_vec_pinmux_helper(config->pinmux_pad1, sercom, 1);
-       }
-
-       /* Initialize our instance and register interrupt handler + data */
-       module->rx_bufdesc_ptr = NULL;
-       module->tx_bufdesc_ptr = NULL;
-       module->direction = SPI_MASTER_VEC_DIRECTION_IDLE;
-       module->status = STATUS_OK;
-#ifdef CONF_SPI_MASTER_VEC_OS_SUPPORT
-       CONF_SPI_MASTER_VEC_CREATE_SEMAPHORE(module->busy_semaphore);
-#endif
-
-       _sercom_set_handler(sercom_index, _spi_master_vec_int_handler);
-       _sercom_instances[sercom_index] = module;
-
-       return STATUS_OK;
-}
-
-/**
- * \brief Enable the SERCOM SPI module
- *
- * This function must be called after \ref spi_master_vec_init() before a
- * transfer can be started.
- *
- * \param[in,out] module Driver instance to operate on.
- */
-void spi_master_vec_enable(const struct spi_master_vec_module *const module)
-{
-       Assert(module);
-       Assert(module->sercom);
-
-       SercomSpi *const spi_hw = &(module->sercom->SPI);
-
-       spi_hw->INTENCLR.reg = SERCOM_SPI_INTFLAG_DRE | SERCOM_SPI_INTFLAG_RXC
-                       | SERCOM_SPI_INTFLAG_TXC;
-
-       _spi_master_vec_wait_for_sync(spi_hw);
-
-       spi_hw->CTRLA.reg |= SERCOM_SPI_CTRLA_ENABLE;
-
-       system_interrupt_enable(_sercom_get_interrupt_vector(module->sercom));
-}
-
-/**
- * \brief Disable the SERCOM SPI module
- *
- * \param[in,out] module Driver instance to operate on.
- */
-void spi_master_vec_disable(struct spi_master_vec_module *const module)
-{
-       Assert(module);
-       Assert(module->sercom);
-
-       SercomSpi *const spi_hw = &(module->sercom->SPI);
-
-       system_interrupt_disable(_sercom_get_interrupt_vector(module->sercom));
-
-       _spi_master_vec_wait_for_sync(spi_hw);
-
-       spi_hw->CTRLB.reg = 0;
-       spi_hw->CTRLA.reg &= ~SERCOM_SPI_CTRLA_ENABLE;
-       module->rx_bufdesc_ptr = NULL;
-       module->tx_bufdesc_ptr = NULL;
-       module->direction = SPI_MASTER_VEC_DIRECTION_IDLE;
-       module->status = STATUS_OK;
-}
-
-/**
- * \brief Reset the SERCOM SPI module
- *
- * This function will disable and reset the SPI module to its power on default
- * values.
- *
- * \param[in,out] module Pointer to a driver instance.
- */
-void spi_master_vec_reset(struct spi_master_vec_module *const module)
-{
-       /* Sanity check arguments */
-       Assert(module);
-       Assert(module->sercom);
-
-       SercomSpi *const spi_hw = &(module->sercom->SPI);
-
-       /* Disable the module */
-       spi_master_vec_disable(module);
-
-       _spi_master_vec_wait_for_sync(spi_hw);
-
-       /* Software reset the module */
-       spi_hw->CTRLA.reg |= SERCOM_SPI_CTRLA_SWRST;
-
-#ifdef CONF_SPI_MASTER_VEC_OS_SUPPORT
-       CONF_SPI_MASTER_VEC_DELETE_SEMAPHORE(module->busy_semaphore);
-#endif
-}
-
-/**
- * \brief Start vectored I/O transfer
- *
- * This function initiates a uni- or bidirectional SPI transfer from/to any
- * number of data buffers. The transfer is interrupt-driven and will run in the
- * background, after this function has returned.
- *
- * The buffers to transmit from or receive into must be described in arrays of
- * buffer descriptors. These arrays \e must end with descriptors that specify
- * zero buffer length. The first descriptor in an array can \e not specify zero
- * length. The number of bytes to transmit and to receive do not have to be
- * equal.
- *
- * If the address for a receive buffer is set to \c NULL, the received bytes
- * corresponding to that buffer descriptor will be discarded. This is useful if
- * slave is already set up to transfer a number of bytes, but the master has no
- * available buffer to receive them into. As an example, to receive the two
- * first bytes and discard the 128 following, the buffer descriptors could be:
-\code
-       struct spi_master_vec_bufdesc rx_buffers[3] = {
-               // Read two status bytes
-               {.data = status_buffer, .length = 2},
-               // Discard 128 data bytes
-               {.data = NULL, .length = 128},
-               // End of reception
-               {.length = 0},
-       };
-\endcode
- *
- * To initiate a unidirectional transfer, pass \c NULL as the address of either
- * buffer descriptor array, like this:
-\code
-       // Transmit some buffers
-       spi_master_vec_transceive_buffer_job(&module, tx_buffers, NULL);
-
-       // Receive some buffers
-       spi_master_vec_transceive_buffer_job(&module, NULL, rx_buffers);
-\endcode
- *
- * \pre \ref spi_master_vec_init() and \ref spi_master_vec_enable() must have
- * been called before this function.
- *
- * \param[in,out] module Driver instance to operate on.
- * \param[in] tx_bufdescs address of buffer descriptor array for bytes to
- * transmit.
- * \arg \c NULL if the transfer is a simplex read.
- * \param[in,out] rx_bufdescs address of buffer descriptor array for storing
- * received bytes.
- * \arg \c NULL if the transfer is a simplex write.
- *
- * \return Status of transfer start.
- * \retval STATUS_OK if transfer was started.
- * \retval STATUS_BUSY if a transfer is already on-going.
- */
-enum status_code spi_master_vec_transceive_buffer_job(
-               struct spi_master_vec_module *const module,
-               struct spi_master_vec_bufdesc tx_bufdescs[],
-               struct spi_master_vec_bufdesc rx_bufdescs[])
-{
-       Assert(module);
-       Assert(module->sercom);
-       Assert(tx_bufdescs || rx_bufdescs);
-
-       SercomSpi *const spi_hw = &(module->sercom->SPI);
-       uint32_t tmp_ctrlb;
-       uint8_t tmp_intenset;
-
-       system_interrupt_enter_critical_section();
-       if (module->status == STATUS_BUSY) {
-               system_interrupt_leave_critical_section();
-               return STATUS_BUSY;
-       } else {
-               module->status = STATUS_BUSY;
-               system_interrupt_leave_critical_section();
-       }
-
-#ifdef CONF_SPI_MASTER_VEC_OS_SUPPORT
-       CONF_SPI_MASTER_VEC_TAKE_SEMAPHORE(module->busy_semaphore);
-#endif
-
-       module->tx_bufdesc_ptr = tx_bufdescs;
-       module->rx_bufdesc_ptr = rx_bufdescs;
-
-       if (tx_bufdescs && rx_bufdescs) {
-               Assert(tx_bufdescs[0].length);
-               Assert(rx_bufdescs[0].length);
-
-               module->direction = SPI_MASTER_VEC_DIRECTION_BOTH;
-               module->tx_length = tx_bufdescs[0].length;
-               module->tx_head_ptr = tx_bufdescs[0].data;
-               module->rx_length = rx_bufdescs[0].length;
-               module->rx_head_ptr = rx_bufdescs[0].data;
-               module->tx_lead_on_rx = 0;
-               tmp_ctrlb = SERCOM_SPI_CTRLB_RXEN;
-               tmp_intenset = SERCOM_SPI_INTFLAG_DRE | SERCOM_SPI_INTFLAG_RXC;
-       } else {
-               if (tx_bufdescs) {
-                       Assert(tx_bufdescs[0].length);
-
-                       module->direction = SPI_MASTER_VEC_DIRECTION_WRITE;
-                       module->tx_length = tx_bufdescs[0].length;
-                       module->tx_head_ptr = tx_bufdescs[0].data;
-                       tmp_ctrlb = 0;
-                       tmp_intenset = SERCOM_SPI_INTFLAG_DRE;
-               } else {
-                       Assert(rx_bufdescs[0].length);
-
-                       module->direction = SPI_MASTER_VEC_DIRECTION_READ;
-                       module->rx_length = rx_bufdescs[0].length;
-                       module->rx_head_ptr = rx_bufdescs[0].data;
-                       module->tx_lead_on_rx = 0;
-                       tmp_ctrlb = SERCOM_SPI_CTRLB_RXEN;
-                       tmp_intenset = SERCOM_SPI_INTFLAG_DRE | 
SERCOM_SPI_INTFLAG_RXC;
-               }
-       }
-
-       /* Ensure the SERCOM is sync'ed before writing these registers */
-       _spi_master_vec_wait_for_sync(spi_hw);
-
-       spi_hw->CTRLB.reg = tmp_ctrlb;
-       spi_hw->INTENSET.reg = tmp_intenset;
-
-       return STATUS_OK;
-}
-
-/**
- * \brief Interrupt handler
- *
- * \param[in] sercom_index SERCOM instance number passed from the master SERCOM
- * driver.
- */
-static void _spi_master_vec_int_handler(uint8_t sercom_index)
-{
-       struct spi_master_vec_module *const module =
-                       _sercom_instances[sercom_index];
-       enum _spi_master_vec_direction dir = module->direction;
-       SercomSpi *const spi_hw = &(module->sercom->SPI);
-       uint8_t int_status;
-
-       int_status = spi_hw->INTFLAG.reg ;
-    int_status &= spi_hw->INTENSET.reg;
-
-       if (int_status & SERCOM_SPI_INTFLAG_DRE) {
-               uint_fast8_t tx_lead_on_rx = module->tx_lead_on_rx;
-
-               /* If TX is ahead of RX by 2+ bytes, allow RX to catch up.
-                * Note: will only happen _once_ per READ or BOTH.
-                */
-               if ((tx_lead_on_rx >= 2) && (dir != 
SPI_MASTER_VEC_DIRECTION_WRITE)) {
-                       Assert((dir == SPI_MASTER_VEC_DIRECTION_READ)
-                                       || (dir == 
SPI_MASTER_VEC_DIRECTION_BOTH));
-                       Assert(int_status & SERCOM_SPI_INTFLAG_RXC);
-               /* Otherwise, we can send more bytes */
-               } else {
-                       module->tx_lead_on_rx = ++tx_lead_on_rx;
-
-                       /* If doing a READ, just send 0 to trigger the transfer 
*/
-                       if (dir == SPI_MASTER_VEC_DIRECTION_READ) {
-                               uint32_t tx_lead_limit;
-
-                               spi_hw->DATA.reg = 0;
-
-check_for_read_end:
-                               /* With current TX'ed bytes, will we get the 
last RX byte?
-                                * If so, we can disable the DRE interrupt to 
stop transmitting.
-                                *
-                                * Since a buffer can have minimum 1 byte 
length, this check is
-                                * simplified by first checking if the RX end 
is so close that
-                                * the max. 2 byte lead of TX may actually fill 
the buffers.
-                                */
-                               tx_lead_limit = (module->rx_bufdesc_ptr + 
1)->length;
-
-                               if (!tx_lead_limit || !(module->rx_bufdesc_ptr 
+ 2)->length) {
-                                       tx_lead_limit += module->rx_length;
-
-                                       if (tx_lead_on_rx >= tx_lead_limit) {
-                                               spi_hw->INTENCLR.reg = 
SERCOM_SPI_INTFLAG_DRE;
-                                       }
-                               }
-                       /* For WRITE and BOTH, output current byte */
-                       } else {
-                               spi_master_vec_buflen_t tx_length;
-                               uint8_t *tx_head_ptr;
-
-                               tx_head_ptr = module->tx_head_ptr;
-                               spi_hw->DATA.reg = *(tx_head_ptr++);
-
-                               /* Check if this was the last byte to send */
-                               tx_length = module->tx_length - 1;
-
-                               if (tx_length) {
-                                       module->tx_head_ptr = tx_head_ptr;
-                                       module->tx_length = tx_length;
-                               } else {
-                               /* Any more buffers left to send, perhaps? */
-                                       tx_length = 
(++module->tx_bufdesc_ptr)->length;
-
-                                       if (tx_length) {
-                                               module->tx_head_ptr = 
module->tx_bufdesc_ptr->data;
-                                               module->tx_length = tx_length;
-                                       } else {
-                                               if (dir == 
SPI_MASTER_VEC_DIRECTION_WRITE) {
-                                               /* Disable DRE and enable TXC 
to end WRITE */
-                                                       spi_hw->INTENCLR.reg = 
SERCOM_SPI_INTFLAG_DRE;
-                                                       spi_hw->INTENSET.reg = 
SERCOM_SPI_INTFLAG_TXC;
-                                               } else {
-                                               /* For BOTH, check if we still 
have bytes to read */
-                                                       dir = 
SPI_MASTER_VEC_DIRECTION_READ;
-                                                       module->direction = dir;
-                                                       goto check_for_read_end;
-                                               }
-                                       }
-                               }
-                       }
-               }
-       }
-
-       /* For READ and BOTH, store the received byte */
-       if (int_status & SERCOM_SPI_INTFLAG_RXC) {
-               spi_master_vec_buflen_t rx_length;
-               uint8_t *rx_head_ptr;
-
-               rx_head_ptr = module->rx_head_ptr;
-               if (rx_head_ptr != NULL) {
-                       *(rx_head_ptr++) = spi_hw->DATA.reg;
-               } else {
-                       uint8_t dummy;
-                       dummy = spi_hw->DATA.reg;
-                       UNUSED(dummy);
-               }
-               module->tx_lead_on_rx--;
-
-               /* Check if this was the last byte to receive */
-               rx_length = module->rx_length - 1;
-
-               if (rx_length) {
-                       module->rx_head_ptr = rx_head_ptr;
-                       module->rx_length = rx_length;
-               } else {
-                       /* Any more buffers left to receive into? */
-                       rx_length = (++module->rx_bufdesc_ptr)->length;
-
-                       if (rx_length) {
-                               module->rx_head_ptr = 
module->rx_bufdesc_ptr->data;
-                               module->rx_length = rx_length;
-                       } else {
-                               /* Disable the SPI receiver (instant effect) 
and RX interrupt */
-                               spi_hw->CTRLB.reg = 0;
-                               spi_hw->INTENCLR.reg = SERCOM_SPI_INTFLAG_RXC;
-
-                               if (dir == SPI_MASTER_VEC_DIRECTION_READ) {
-                                       /* If doing READ, end the transaction 
here */
-                                       dir = SPI_MASTER_VEC_DIRECTION_IDLE;
-                                       module->direction = dir;
-                                       module->status = STATUS_OK;
-#ifdef CONF_SPI_MASTER_VEC_OS_SUPPORT
-                                       
CONF_SPI_MASTER_VEC_GIVE_SEMAPHORE_FROM_ISR(module->busy_semaphore);
-#endif
-                               } else {
-                                       /* If doing BOTH, change direction to 
WRITE */
-                                       dir = SPI_MASTER_VEC_DIRECTION_WRITE;
-                                       module->direction = dir;
-                               }
-                       }
-               }
-       }
-
-       /* For WRITE */
-       if (int_status & SERCOM_SPI_INTFLAG_TXC) {
-               /* End transaction here, since last byte has been sent */
-               spi_hw->INTENCLR.reg = SERCOM_SPI_INTFLAG_TXC;
-
-               dir = SPI_MASTER_VEC_DIRECTION_IDLE;
-               module->direction = dir;
-               module->status = STATUS_OK;
-#ifdef CONF_SPI_MASTER_VEC_OS_SUPPORT
-               
CONF_SPI_MASTER_VEC_GIVE_SEMAPHORE_FROM_ISR(module->busy_semaphore);
-#endif
-       }
-}
-
-/**
- * @}
- */
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/a280628a/hw/mcu/atmel/samd21xx/src/sam0/drivers/sercom/spi_master_vec/spi_master_vec.h
----------------------------------------------------------------------
diff --git 
a/hw/mcu/atmel/samd21xx/src/sam0/drivers/sercom/spi_master_vec/spi_master_vec.h 
b/hw/mcu/atmel/samd21xx/src/sam0/drivers/sercom/spi_master_vec/spi_master_vec.h
deleted file mode 100755
index a10ae22..0000000
--- 
a/hw/mcu/atmel/samd21xx/src/sam0/drivers/sercom/spi_master_vec/spi_master_vec.h
+++ /dev/null
@@ -1,692 +0,0 @@
-/**
- * \file
- *
- * \brief SERCOM SPI master with vectored I/O driver include
- *
- * 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 SPI_MASTER_VEC_H
-#define SPI_MASTER_VEC_H
-
-#include <compiler.h>
-#include <gclk.h>
-#include <port.h>
-#include <spi.h>
-#include <status_codes.h>
-#include <conf_spi_master_vec.h>
-
-/**
- * \defgroup asfdoc_sam0_sercom_spi_master_vec_group SAM Serial Peripheral 
Interface Master Driver w/ Vectored I/O (SERCOM SPI)
- *
- * This driver for Atmel&reg; | SMART SAM devices provides an interface for 
the configuration
- * and operation of the SERCOM module in SPI master mode and uses vectored I/O
- * for data transfers.
- *
- * The following peripherals are used by this driver:
- * - SERCOM (Serial Communication Interface)
- *
- * The following devices can use this driver:
- *  - Atmel | SMART SAM D20/D21
- *  - Atmel | SMART SAM R21
- *  - Atmel | SMART SAM D09/D10/D11
- *  - Atmel | SMART SAM L21/L22
- *  - Atmel | SMART SAM DA1
- *  - Atmel | SMART SAM C20/C21
- *
- * The reader is assumed to be familiar with the regular SERCOM SPI driver, and
- * how it is configured and operated. Configuration of this driver is done a
- * similar way and actually re-uses several enumerations (configuration values)
- * from the regular SERCOM SPI driver.
- *
- * The outline of this documentation is as follows:
- * - \ref asfdoc_sam0_sercom_spi_master_vec_prerequisites
- * - \ref asfdoc_sam0_sercom_spi_master_vec_module_overview
- * - \ref asfdoc_sam0_sercom_spi_master_vec_special_considerations
- * - \ref asfdoc_sam0_sercom_spi_master_vec_extra_info
- * - \ref asfdoc_sam0_sercom_spi_master_vec_examples
- * - \ref asfdoc_sam0_sercom_spi_master_vec_api_overview
- *
- *
- * \section asfdoc_sam0_sercom_spi_master_vec_prerequisites Prerequisites
- *
- * This driver uses the \ref asfdoc_sam0_system_clock_group "SYSTEM clock 
driver"
- * to select the SERCOM's clock source and to configure the SERCOM for the
- * desired baud rate. Ensure that the selected clock source is configured and
- * that the clock system is initialized. This is typically done indirectly with
- * \ref system_init(), or directly with \ref system_clock_init().
- *
- * According to the datasheet, the minimum and maximum limits for the baud rate
- * is given by: \f$ \frac{1}{2^{17}} \times f_{clk} \le f_{baud}
- * \le \frac{1}{2} \times f_{clk} \f$.
- *
- *
- * \section asfdoc_sam0_sercom_spi_master_vec_module_overview Module Overview
- *
- * This SERCOM SPI master driver supports uni- and bidirectional transfers of
- * 8-bit data with vectored I/O, also know as scatter/gather.
- * It does not implement control of SS or slave addressing since the intended
- * usage is in stacks which usually have their own protocols and handshaking
- * schemes.
- *
- *
- * \subsection asfdoc_sam0_sercom_spi_master_vectored_io Vectored I/O
- *
- * Vectored I/O enables the transfer of data from/to any number of buffers with
- * arbitrary memory locations without having to do several transfers, i.e., one
- * buffer at a time. This feature is useful in stacks because it allows each
- * layer of the stack to have a dedicated data buffer, thus avoiding the need
- * for a centralized data buffer that the different layers must use in
- * cooperation.
- *
- * The vectored I/O relies on arrays of buffer descriptors which must be passed
- * to the driver to start a transfer. These buffer descriptors specify where in
- * memory each buffer is, and how large they are.
- * \ref asfdoc_sam0_vectored_io_example "The figure below" illustrates this
- * for an example with three buffers of varying sizes that are transmitted.
- *
- * \anchor asfdoc_sam0_vectored_io_example
- * \dot
-digraph bufptr_to_spiord {
-       rankdir=LR;
-       subgraph cluster_bufptr {
-               style=invis;
-               bufptr_label [shape=none, label="Buffer descriptors"];
-               bufptrs [shape=record, label="<bf1> [0]|<bf2> [1]|<bf3> 
[2]|<bf4> [3]"];
-       }
-       subgraph cluster_buf {
-               style=invis;
-               buf_label [shape=none, label="Memory layout"];
-               bufs [shape=record, 
label="...|<b1>&quot;yy&quot;|...|<b3>&quot;z&quot;|<b2>&quot;xxx&quot;|..."];
-       }
-       subgraph cluster_spiord {
-               style=invis;
-               spiord_label [shape=none, label="SPI transmission"];
-               spiord [shape=record, 
label="<s1>&quot;yy&quot;|<s2>&quot;xxx&quot;|<s3>&quot;z&quot;"];
-       }
-       bufptrs:bf1 -> bufs:b1 -> spiord:s1;
-       bufptrs:bf2 -> bufs:b2 -> spiord:s2;
-       bufptrs:bf3 -> bufs:b3 -> spiord:s3;
-       bufptrs:bf4 -> "none";
-}
- * \enddot
- *
- * Note that the last descriptor \e must indicate no next buffer in order for
- * the driver to detect that the end of the buffer list has been reached. This
- * means that for \c N buffers, \c N+1 buffer descriptors are needed.
- *
- * Bidirectional transfers are supported without any restrictions on the buffer
- * descriptors, so the number of bytes and buffers to receive and transmit do
- * \e not have to be the same.
- *
- * \sa spi_master_vec_transceive_buffer_job() for details on starting 
transfers.
- *
- *
- * \subsection asfdoc_sam0_sercom_spi_master_os_support OS support
- *
- * Since this driver is interrupt-driven, it is possible for the MCU to run
- * other code while a transfer is on-going.
- *
- * In a single-threaded application, this can be achieved by starting a 
transfer
- * and then avoid any waiting for completion until absolutely required, e.g.,
- * when a new transfer is needed.
- *
- * But in a multi-threaded application, for example based on FreeRTOS, one can
- * utilize \e semaphores to let the OS know when a function is waiting and thus
- * blocking the thread, and that other threads can be run instead. Put another
- * way, the waiting can be made efficient.
- *
- * This driver has an internal semaphore which is used to signal to the OS
- * whenever a function is waiting for a transfer to complete. And since the
- * semaphore datatypes and functions are OS-specific, the support has been made
- * configurable by the use of macros. Note that support for FreeRTOS is already
- * implemented, but must be enabled.
- *
- * \sa CONF_SPI_MASTER_VEC_OS_SUPPORT for more on the configurable OS support.
- *
- *
- * \section asfdoc_sam0_sercom_spi_master_vec_special_considerations Special 
Considerations
- *
- * \subsection asfdoc_sam0_sercom_spi_master_vec_special_isr Interrupt safety
- *
- * This driver should not be used within interrupt contexts. The reason for 
this
- * is that the driver itself is interrupt driven. Further, the configurable OS
- * support is implemented with the assumption that transfers are only started
- * in threads, not in interrupt service routines, because it gives the simplest
- * API.
- *
- *
- * \subsection asfdoc_sam0_sercom_spi_master_vec_special_mux Signal MUX
- *
- * The SERCOM module has two layers of signal multiplexing in SPI mode:
- * -# SERCOM pad MUX: This routes the SPI signals to internal lines.
- * -# PORT pin MUX: This routes the internal line to a device pin.
- *
- * Both of these layers are configured in the \ref spi_master_vec_config
- * "configuration structure", using the members named \c mux_setting and
- * \c pinmux_padN. These must be set in combination.
- *
- * The driver supplies values for the
- * \ref spi_master_vec_config::mux_setting "SERCOM pad MUX" from the standard
- * ASF SERCOM SPI driver. For the PORT pin MUX configuration, refer to the
- * peripheral include file for the device (\c pio_samd20XNN.h ) and use the
- * macros that are prefixed with \c PINMUX_, such as
- * \c PINMUX_PA04D_SERCOM0_PAD0. It is also possible to use the default pin MUX
- * setting for a SERCOM pad by using the \ref PINMUX_DEFAULT macro. The 
defaults
- * are defined in the file \ref sercom_pinout.h.
- *
- * Note that for \ref spi_master_vec_init() to function properly with the macro
- * \ref PINMUX_DEFAULT, the order of the values in \c pinmux_padN \e must be
- * correct, i.e., \c pinmux_pad0 must contain the pin MUX setting for
- * multiplexing SERCOM pad 0, and so on.
- *
- *
- * \section asfdoc_sam0_sercom_spi_master_vec_extra_info Extra Information
- *
- * For extra information, see
- * \subpage asfdoc_sam0_sercom_spi_master_vec_extra. This includes:
- * - \ref asfdoc_sam0_sercom_spi_master_vec_extra_acronyms
- * - \ref asfdoc_sam0_sercom_spi_master_vec_extra_dependencies
- * - \ref asfdoc_sam0_sercom_spi_master_vec_extra_errata
- * - \ref asfdoc_sam0_sercom_spi_master_vec_extra_history
- *
- *
- * \section asfdoc_sam0_sercom_spi_master_vec_examples Examples
- *
- * For a list of examples related to this driver, see
- * \ref asfdoc_sam0_sercom_spi_master_vec_exqsg.
- *
- *
- * \section asfdoc_sam0_sercom_spi_master_vec_api_overview API Overview
- *
- * @{
- */
-
-/**
- * Driver configuration structure
- *
- * \sa asfdoc_sam0_sercom_spi_master_vec_special_considerations for more
- * information regarding SERCOM pad and pin MUX.
- */
-struct spi_master_vec_config {
-       /** Baud rate in Hertz. */
-       uint32_t baudrate;
-       /** GCLK generator to use for the SERCOM. */
-       enum gclk_generator gclk_generator;
-       /** Enabled in sleep modes. */
-       bool run_in_standby;
-       /** SERCOM pad MUX setting. */
-       enum spi_signal_mux_setting mux_setting;
-       /** Transfer mode. */
-       enum spi_transfer_mode transfer_mode;
-       /** Data order. */
-       enum spi_data_order data_order;
-       /** Pin MUX setting for SERCOM pad 0. */
-       uint32_t pinmux_pad0;
-       /** Pin MUX setting for SERCOM pad 1. */
-       uint32_t pinmux_pad1;
-       /** Pin MUX setting for SERCOM pad 2. */
-       uint32_t pinmux_pad2;
-       /** Pin MUX setting for SERCOM pad 4. */
-       uint32_t pinmux_pad3;
-};
-
-/** Buffer length container. */
-typedef uint16_t spi_master_vec_buflen_t;
-
-/** Buffer descriptor structure. */
-struct spi_master_vec_bufdesc {
-       /** Pointer to buffer start. */
-       void *data;
-       /** Length of buffer. */
-       spi_master_vec_buflen_t length;
-};
-
-/** Transfer direction */
-enum _spi_master_vec_direction {
-       SPI_MASTER_VEC_DIRECTION_READ,
-       SPI_MASTER_VEC_DIRECTION_WRITE,
-       SPI_MASTER_VEC_DIRECTION_BOTH,
-       SPI_MASTER_VEC_DIRECTION_IDLE,
-};
-
-/** Driver instance. */
-struct spi_master_vec_module {
-#if !defined(__DOXYGEN__)
-       Sercom *volatile sercom;
-       volatile bool locked;
-       volatile enum _spi_master_vec_direction direction;
-       volatile enum status_code status;
-       volatile spi_master_vec_buflen_t rx_length;
-       volatile spi_master_vec_buflen_t tx_length;
-       uint8_t *volatile rx_head_ptr;
-       uint8_t *volatile tx_head_ptr;
-       volatile uint_fast8_t tx_lead_on_rx;
-       struct spi_master_vec_bufdesc *volatile rx_bufdesc_ptr;
-       struct spi_master_vec_bufdesc *volatile tx_bufdesc_ptr;
-#  ifdef CONF_SPI_MASTER_VEC_OS_SUPPORT
-       CONF_SPI_MASTER_VEC_SEMAPHORE_TYPE busy_semaphore;
-#  endif
-#endif
-};
-
-/**
- * \name Configuration and Initialization
- * @{
- */
-
-/**
- * \brief Initialize configuration with default values.
- *
- * \param[out] config Configuration struct to initialize.
- */
-static inline void spi_master_vec_get_config_defaults(
-               struct spi_master_vec_config *const config)
-{
-       config->baudrate = 100000;
-       config->gclk_generator = GCLK_GENERATOR_0;
-       config->run_in_standby = false;
-       config->mux_setting = SPI_SIGNAL_MUX_SETTING_D;
-       config->transfer_mode = SPI_TRANSFER_MODE_0;
-       config->data_order = SPI_DATA_ORDER_MSB;
-       config->pinmux_pad0 = PINMUX_DEFAULT;
-       config->pinmux_pad1 = PINMUX_DEFAULT;
-       config->pinmux_pad2 = PINMUX_DEFAULT;
-       config->pinmux_pad3 = PINMUX_DEFAULT;
-}
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-enum status_code spi_master_vec_init(struct spi_master_vec_module *const 
module,
-               Sercom *const sercom, const struct spi_master_vec_config *const 
config);
-
-/** @} */
-
-/**
- * \name Enable/Disable and Reset
- * @{
- */
-
-void spi_master_vec_enable(const struct spi_master_vec_module *const module);
-void spi_master_vec_disable(struct spi_master_vec_module *const module);
-void spi_master_vec_reset(struct spi_master_vec_module *const module);
-
-/** @} */
-
-/**
- * \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 spi_master_vec_lock(
-               struct spi_master_vec_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.
- */
-static inline void spi_master_vec_unlock(
-               struct spi_master_vec_module *const module)
-{
-       module->locked = false;
-}
-
-/** @} */
-
-/**
- * \name Read/Write and Status
- * @{
- */
-
-enum status_code spi_master_vec_transceive_buffer_job(
-               struct spi_master_vec_module *const module,
-               struct spi_master_vec_bufdesc tx_bufdescs[],
-               struct spi_master_vec_bufdesc rx_bufdescs[]);
-
-/**
- * \brief Get current status of transfer.
- *
- * \param[in] module Driver instance to operate on.
- *
- * \return Current status of driver instance.
- * \retval STATUS_OK if idle and previous transfer succeeded.
- * \retval STATUS_BUSY if a transfer is ongoing.
- * \retval <other> if previous transfer failed.
- */
-static inline enum status_code spi_master_vec_get_job_status(
-               const struct spi_master_vec_module *const module)
-{
-       return module->status;
-}
-
-/**
- * \brief Get status of transfer upon job end.
- *
- * \param[in]  module Driver instance to operate on.
- *
- * \return Current status of driver instance.
- * \retval STATUS_OK if idle and previous transfer succeeded.
- * \retval <other> if previous transfer failed.
- */
-static inline enum status_code spi_master_vec_get_job_status_wait(
-               const struct spi_master_vec_module *const module)
-{
-       enum status_code status;
-
-#ifdef CONF_SPI_MASTER_VEC_OS_SUPPORT
-       CONF_SPI_MASTER_VEC_TAKE_SEMAPHORE(module->busy_semaphore);
-       status = spi_master_vec_get_job_status(module);
-       CONF_SPI_MASTER_VEC_GIVE_SEMAPHORE(module->busy_semaphore);
-#else
-       do {
-               status = spi_master_vec_get_job_status(module);
-       } while (status == STATUS_BUSY);
-#endif
-
-       return status;
-}
-
-
-/**
- * \brief Start vectored I/O transfer, wait for it to end.
- *
- * \param[in,out] module Driver instance to operate on.
- * \param[in] tx_bufdescs address of buffer descriptor array for bytes to
- * transmit.
- * \arg \c NULL if the transfer is a simplex read.
- * \param[in,out] rx_bufdescs address of buffer descriptor array for storing
- * received bytes.
- * \arg \c NULL if the transfer is a simplex write.
- *
- * \return Status of transfer start.
- * \retval STATUS_OK if transfer succeeded.
- * \retval STATUS_BUSY if a transfer was already on-going.
- * \retval <other> if transfer failed.
- */
-static inline enum status_code spi_master_vec_transceive_buffer_wait(
-               struct spi_master_vec_module *const module,
-               struct spi_master_vec_bufdesc tx_bufdescs[],
-               struct spi_master_vec_bufdesc rx_bufdescs[])
-{
-       enum status_code status;
-
-       status = spi_master_vec_transceive_buffer_job(module, tx_bufdescs,
-                       rx_bufdescs);
-
-       if (status == STATUS_BUSY) {
-               return status;
-       }
-
-       return spi_master_vec_get_job_status_wait(module);
-}
-
-/** @} */
-
-#ifdef __cplusplus
-}
-#endif
-
-/**
- * \name OS Support Configuration
- * @{
- */
-
-/**
- * \def CONF_SPI_MASTER_VEC_OS_SUPPORT
- * \brief Enable support for OS
- *
- * Defining this symbol will enable support for an OS, e.g., FreeRTOS, by using
- * the macros in this group:
- * - \ref CONF_SPI_MASTER_VEC_SEMAPHORE_TYPE
- * - \ref CONF_SPI_MASTER_VEC_CREATE_SEMAPHORE
- * - \ref CONF_SPI_MASTER_VEC_DELETE_SEMAPHORE
- * - \ref CONF_SPI_MASTER_VEC_TAKE_SEMAPHORE
- * - \ref CONF_SPI_MASTER_VEC_GIVE_SEMAPHORE
- * - \ref CONF_SPI_MASTER_VEC_GIVE_SEMAPHORE_FROM_ISR
- *
- * The user must ensure that these macros map to the implementation for the OS
- * that is used. Further, required includes must be added alongside these 
macros
- * in \ref conf_spi_master_vec.h.
- *
- * The purpose of this configuration is to enable usage of the OS' semaphore
- * system to wait for transfers to end rather than continuously polling the
- * transfer status, which is an inefficient approach.
- */
-
-/**
- * \def CONF_SPI_MASTER_VEC_SEMAPHORE_TYPE
- * \brief Semaphore datatype
- */
-
-/**
- * \def CONF_SPI_MASTER_VEC_CREATE_SEMAPHORE
- * \brief Create/initialize semaphore
- *
- * \param semaphore Semaphore member in driver instance.
- */
-
-/**
- * \def CONF_SPI_MASTER_VEC_DELETE_SEMAPHORE
- * \brief Delete semaphore
- *
- * \param semaphore Semaphore member in driver instance.
- */
-
-/**
- * \def CONF_SPI_MASTER_VEC_TAKE_SEMAPHORE
- * \brief Wait for and take semaphore
- *
- * \param semaphore Semaphore member in driver instance.
- */
-
-/**
- * \def CONF_SPI_MASTER_VEC_GIVE_SEMAPHORE
- * \brief Give semaphore back
- *
- * \param semaphore Semaphore member in driver instance.
- */
-
-/**
- * \def CONF_SPI_MASTER_VEC_GIVE_SEMAPHORE_FROM_ISR
- * \brief Give semaphore back from an ISR
- *
- * \param semaphore Semaphore member in driver instance.
- */
-
-/** @} */
-
-/**
- * @}
- */
-
-/**
- * \page asfdoc_sam0_sercom_spi_master_vec_extra Extra Information for SERCOM 
SPI Master Driver w/ Vectored I/O
- *
- *
- * \section asfdoc_sam0_sercom_spi_master_vec_extra_acronyms Acronyms
- *
- * The table below presents the acronyms used in this module.
- *
- * <table>
- *     <tr>
- *         <th>Acronym</td>
- *         <th>Description</td>
- *     </tr>
- *     <tr>
- *         <td>GCLK</td>
- *         <td>Generic Clock</td>
- *     </tr>
- *     <tr>
- *         <td>MISO</td>
- *         <td>Master Input, Slave Output</td>
- *     </tr>
- *     <tr>
- *         <td>MOSI</td>
- *         <td>Master Output, Slave Input</td>
- *     </tr>
- *     <tr>
- *         <td>SCK</td>
- *         <td>Serial Clock</td>
- *     </tr>
- *     <tr>
- *         <td>SPI</td>
- *         <td>Serial Peripheral Interface</td>
- *     </tr>
- *     <tr>
- *         <td>SS</td>
- *         <td>Slave Select</td>
- *     </tr>
- * </table>
- *
- *
- * \section asfdoc_sam0_sercom_spi_master_vec_extra_dependencies Dependencies
- *
- * This driver has the following dependencies:
- * - \ref asfdoc_sam0_system_group "System driver"
- * - \ref group_sam0_utils "Compiler driver"
- * - \ref asfdoc_sam0_port_group "Port driver"
- * - \ref Common SERCOM driver base
- *
- *
- * \section asfdoc_sam0_sercom_spi_master_vec_extra_errata Errata
- *
- * There are no errata related to this driver.
- *
- *
- * \section asfdoc_sam0_sercom_spi_master_vec_extra_history Module History
- *
- * An overview of the module history is presented in the table below, with
- * details on the enhancements and fixes made to the module since its first
- * release. The current version of this corresponds to the newest version in 
the
- * table.
- *
- * <table>
- *     <tr>
- *         <th>Changelog</th>
- *     </tr>
- *     <tr>
- *         <td>Initial Release</td>
- *     </tr>
- * </table>
- */
-
-/**
- * \page asfdoc_sam0_sercom_spi_master_vec_exqsg Examples for SERCOM SPI 
Master Driver w/ Vectored I/O
- *
- * This is a list of the available Quick Start guides (QSGs) and example
- * applications for \ref asfdoc_sam0_sercom_spi_master_vec_group. QSGs are
- * simple examples with step-by-step instructions to configure and use this
- * driver in a selection of use cases. Note that QSGs can be compiled as a
- * standalone application or be added to the user application.
- *
- * - \subpage asfdoc_sam0_sercom_spi_master_vec_basic
- */
-
- /**
-  * \page asfdoc_sam0_sercom_spi_master_vec_document_revision_history Document 
Revision History
-  *
-  * <table>
-  *      <tr>
-  *         <th>Doc. Rev.</td>
-  *         <th>Date</td>
-  *         <th>Comments</td>
-  *      </tr>
-  *      <tr>
-  *           <td>D</td>
-  *           <td>12/2014</td>
-  *           <td>Add SAM L21/C21 support.</td>
-  *     </tr>
-  *      <tr>
-  *           <td>C</td>
-  *           <td>04/2014</td>
-  *           <td>Add SAM D10/D11 support.</td>
-  *     </tr>
-  *     <tr>
-  *           <td>B</td>
-  *           <td>03/2014</td>
-  *           <td>Add SAMR21 support.</td>
-  *     </tr>
-  *     <tr>
-  *         <td>A</td>
-  *         <td>01/2014</td>
-  *         <td>Initial release</td>
-  *     </tr>
-  * </table>
-  */
-
-#endif /* SPI_MASTER_VEC_H */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/a280628a/hw/mcu/atmel/samd21xx/src/sam0/drivers/sercom/usart/usart.c
----------------------------------------------------------------------
diff --git a/hw/mcu/atmel/samd21xx/src/sam0/drivers/sercom/usart/usart.c 
b/hw/mcu/atmel/samd21xx/src/sam0/drivers/sercom/usart/usart.c
deleted file mode 100755
index 5772ae0..0000000
--- a/hw/mcu/atmel/samd21xx/src/sam0/drivers/sercom/usart/usart.c
+++ /dev/null
@@ -1,811 +0,0 @@
-/**
- * \file
- *
- * \brief SAM SERCOM USART 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 "usart.h"
-#include <pinmux.h>
-#if USART_CALLBACK_MODE == true
-#  include "usart_interrupt.h"
-#endif
-
-/**
- * \internal
- * Set Configuration of the USART module
- */
-static enum status_code _usart_set_config(
-               struct usart_module *const module,
-               const struct usart_config *const config)
-{
-       /* Sanity check arguments */
-       Assert(module);
-       Assert(module->hw);
-
-       /* Get a pointer to the hardware module instance */
-       SercomUsart *const usart_hw = &(module->hw->USART);
-
-       /* Index for generic clock */
-       uint32_t sercom_index = _sercom_get_sercom_inst_index(module->hw);
-       uint32_t gclk_index   = sercom_index + SERCOM0_GCLK_ID_CORE;
-
-       /* Cache new register values to minimize the number of register writes 
*/
-       uint32_t ctrla = 0;
-       uint32_t ctrlb = 0;
-#ifdef FEATURE_USART_ISO7816
-       uint32_t ctrlc = 0;
-#endif
-       uint16_t baud  = 0;
-       uint32_t transfer_mode;
-
-       enum sercom_asynchronous_operation_mode mode = 
SERCOM_ASYNC_OPERATION_MODE_ARITHMETIC;
-       enum sercom_asynchronous_sample_num sample_num = 
SERCOM_ASYNC_SAMPLE_NUM_16;
-
-#ifdef FEATURE_USART_OVER_SAMPLE
-       switch (config->sample_rate) {
-               case USART_SAMPLE_RATE_16X_ARITHMETIC:
-                       mode = SERCOM_ASYNC_OPERATION_MODE_ARITHMETIC;
-                       sample_num = SERCOM_ASYNC_SAMPLE_NUM_16;
-                       break;
-               case USART_SAMPLE_RATE_8X_ARITHMETIC:
-                       mode = SERCOM_ASYNC_OPERATION_MODE_ARITHMETIC;
-                       sample_num = SERCOM_ASYNC_SAMPLE_NUM_8;
-                       break;
-               case USART_SAMPLE_RATE_3X_ARITHMETIC:
-                       mode = SERCOM_ASYNC_OPERATION_MODE_ARITHMETIC;
-                       sample_num = SERCOM_ASYNC_SAMPLE_NUM_3;
-                       break;
-               case USART_SAMPLE_RATE_16X_FRACTIONAL:
-                       mode = SERCOM_ASYNC_OPERATION_MODE_FRACTIONAL;
-                       sample_num = SERCOM_ASYNC_SAMPLE_NUM_16;
-                       break;
-               case USART_SAMPLE_RATE_8X_FRACTIONAL:
-                       mode = SERCOM_ASYNC_OPERATION_MODE_FRACTIONAL;
-                       sample_num = SERCOM_ASYNC_SAMPLE_NUM_8;
-                       break;
-       }
-#endif
-
-       /* Set data order, internal muxing, and clock polarity */
-       ctrla = (uint32_t)config->data_order |
-               (uint32_t)config->mux_setting |
-       #ifdef FEATURE_USART_OVER_SAMPLE
-               config->sample_adjustment |
-               config->sample_rate |
-       #endif
-       #ifdef FEATURE_USART_IMMEDIATE_BUFFER_OVERFLOW_NOTIFICATION
-               (config->immediate_buffer_overflow_notification << 
SERCOM_USART_CTRLA_IBON_Pos) |
-       #endif
-               (config->clock_polarity_inverted << 
SERCOM_USART_CTRLA_CPOL_Pos);
-
-       enum status_code status_code = STATUS_OK;
-
-       transfer_mode = (uint32_t)config->transfer_mode;
-#ifdef FEATURE_USART_ISO7816
-       if(config->iso7816_config.enabled) {
-               transfer_mode = config->iso7816_config.protocol_t;
-       }
-#endif
-       /* Get baud value from mode and clock */
-#ifdef FEATURE_USART_ISO7816
-       if(config->iso7816_config.enabled) {
-               baud = config->baudrate;
-       } else {
-#endif
-       switch (transfer_mode)
-       {
-               case USART_TRANSFER_SYNCHRONOUSLY:
-                       if (!config->use_external_clock) {
-                               status_code = 
_sercom_get_sync_baud_val(config->baudrate,
-                                               
system_gclk_chan_get_hz(gclk_index), &baud);
-                       }
-
-                       break;
-
-               case USART_TRANSFER_ASYNCHRONOUSLY:
-                       if (config->use_external_clock) {
-                               status_code =
-                                               
_sercom_get_async_baud_val(config->baudrate,
-                                                       config->ext_clock_freq, 
&baud, mode, sample_num);
-                       } else {
-                               status_code =
-                                               
_sercom_get_async_baud_val(config->baudrate,
-                                                       
system_gclk_chan_get_hz(gclk_index), &baud, mode, sample_num);
-                       }
-
-                       break;
-       }
-
-       /* Check if calculating the baudrate failed */
-       if (status_code != STATUS_OK) {
-               /* Abort */
-               return status_code;
-       }
-#ifdef FEATURE_USART_ISO7816
-       }
-#endif
-
-#ifdef FEATURE_USART_IRDA
-       if(config->encoding_format_enable) {
-               usart_hw->RXPL.reg = config->receive_pulse_length;
-       }
-#endif
-
-       /* Wait until synchronization is complete */
-       _usart_wait_for_sync(module);
-
-       /*Set baud val */
-       usart_hw->BAUD.reg = baud;
-
-       /* Set sample mode */
-       ctrla |= transfer_mode;
-
-       if (config->use_external_clock == false) {
-               ctrla |= SERCOM_USART_CTRLA_MODE(0x1);
-       }
-       else {
-               ctrla |= SERCOM_USART_CTRLA_MODE(0x0);
-       }
-
-       /* Set stopbits and enable transceivers */
-       ctrlb =  
-               #ifdef FEATURE_USART_IRDA
-                       (config->encoding_format_enable << 
SERCOM_USART_CTRLB_ENC_Pos) |
-               #endif
-               #ifdef FEATURE_USART_START_FRAME_DECTION
-                       (config->start_frame_detection_enable << 
SERCOM_USART_CTRLB_SFDE_Pos) |
-               #endif
-               #ifdef FEATURE_USART_COLLISION_DECTION
-                       (config->collision_detection_enable << 
SERCOM_USART_CTRLB_COLDEN_Pos) |
-               #endif
-                       (config->receiver_enable << 
SERCOM_USART_CTRLB_RXEN_Pos) |
-                       (config->transmitter_enable << 
SERCOM_USART_CTRLB_TXEN_Pos);
-
-#ifdef FEATURE_USART_ISO7816
-       if(config->iso7816_config.enabled) {
-               ctrla |= SERCOM_USART_CTRLA_FORM(0x07);
-               if (config->iso7816_config.enable_inverse) {
-                       ctrla |= SERCOM_USART_CTRLA_TXINV | 
SERCOM_USART_CTRLA_RXINV;
-               }
-               ctrlb |=  USART_CHARACTER_SIZE_8BIT;
-               
-               switch(config->iso7816_config.protocol_t) {
-                       case ISO7816_PROTOCOL_T_0:
-                               ctrlb |= (uint32_t)config->stopbits;    
-                               ctrlc |= 
SERCOM_USART_CTRLC_GTIME(config->iso7816_config.guard_time) | \
-                                               
(config->iso7816_config.inhibit_nack) | \
-                                               
(config->iso7816_config.successive_recv_nack) | \
-                                               
SERCOM_USART_CTRLC_MAXITER(config->iso7816_config.max_iterations);
-                               break;  
-                       case ISO7816_PROTOCOL_T_1:
-                               ctrlb |= USART_STOPBITS_1;
-                               break;          
-               }
-       } else {
-#endif
-       ctrlb |= (uint32_t)config->character_size;
-       /* Check parity mode bits */
-       if (config->parity != USART_PARITY_NONE) {
-               ctrla |= SERCOM_USART_CTRLA_FORM(1);
-               ctrlb |= config->parity;
-       } else {
-#ifdef FEATURE_USART_LIN_SLAVE
-               if(config->lin_slave_enable) {
-                       ctrla |= SERCOM_USART_CTRLA_FORM(0x4);
-               } else {
-                       ctrla |= SERCOM_USART_CTRLA_FORM(0);
-               }
-#else
-               ctrla |= SERCOM_USART_CTRLA_FORM(0);
-#endif
-       }
-#ifdef FEATURE_USART_ISO7816
-       }
-#endif
-
-#ifdef FEATURE_USART_LIN_MASTER
-       usart_hw->CTRLC.reg = ((usart_hw->CTRLC.reg) & 
SERCOM_USART_CTRLC_GTIME_Msk)
-                                               | config->lin_header_delay
-                                               | config->lin_break_length;
-
-       if (config->lin_node != LIN_INVALID_MODE) {
-               ctrla &= ~(SERCOM_USART_CTRLA_FORM(0xf));
-               ctrla |= config->lin_node;
-       }
-#endif
-
-       /* Set whether module should run in standby. */
-       if (config->run_in_standby || system_is_debugger_present()) {
-               ctrla |= SERCOM_USART_CTRLA_RUNSTDBY;
-       }
-
-       /* Wait until synchronization is complete */
-       _usart_wait_for_sync(module);
-
-       /* Write configuration to CTRLB */
-       usart_hw->CTRLB.reg = ctrlb;
-
-       /* Wait until synchronization is complete */
-       _usart_wait_for_sync(module);
-
-       /* Write configuration to CTRLA */
-       usart_hw->CTRLA.reg = ctrla;
-
-#ifdef FEATURE_USART_RS485
-       if ((usart_hw->CTRLA.reg & SERCOM_USART_CTRLA_FORM_Msk) != \
-               SERCOM_USART_CTRLA_FORM(0x07)) {
-               usart_hw->CTRLC.reg &= ~(SERCOM_USART_CTRLC_GTIME(0x7));
-               usart_hw->CTRLC.reg |= 
SERCOM_USART_CTRLC_GTIME(config->rs485_guard_time);
-       }
-#endif
-
-#ifdef FEATURE_USART_ISO7816
-       if(config->iso7816_config.enabled) {
-               _usart_wait_for_sync(module);
-               usart_hw->CTRLC.reg = ctrlc;
-       }
-#endif
-
-       return STATUS_OK;
-}
-
-/**
- * \brief Initializes the device
- *
- * Initializes the USART device based on the setting specified in the
- * configuration struct.
- *
- * \param[out] module  Pointer to USART device
- * \param[in]  hw      Pointer to USART hardware instance
- * \param[in]  config  Pointer to configuration struct
- *
- * \return Status of the initialization.
- *
- * \retval STATUS_OK                       The initialization was successful
- * \retval STATUS_BUSY                     The USART module is busy
- *                                         resetting
- * \retval STATUS_ERR_DENIED               The USART has not been disabled in
- *                                         advance of initialization
- * \retval STATUS_ERR_INVALID_ARG          The configuration struct contains
- *                                         invalid configuration
- * \retval STATUS_ERR_ALREADY_INITIALIZED  The SERCOM instance has already been
- *                                         initialized with different clock
- *                                         configuration
- * \retval STATUS_ERR_BAUD_UNAVAILABLE     The BAUD rate given by the
- *                                         configuration
- *                                         struct cannot be reached with
- *                                         the current clock configuration
- */
-enum status_code usart_init(
-               struct usart_module *const module,
-               Sercom *const hw,
-               const struct usart_config *const config)
-{
-       /* Sanity check arguments */
-       Assert(module);
-       Assert(hw);
-       Assert(config);
-
-       enum status_code status_code = STATUS_OK;
-
-       /* Assign module pointer to software instance struct */
-       module->hw = hw;
-
-       /* Get a pointer to the hardware module instance */
-       SercomUsart *const usart_hw = &(module->hw->USART);
-
-       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
-
-       if (usart_hw->CTRLA.reg & SERCOM_USART_CTRLA_SWRST) {
-               /* The module is busy resetting itself */
-               return STATUS_BUSY;
-       }
-
-       if (usart_hw->CTRLA.reg & SERCOM_USART_CTRLA_ENABLE) {
-               /* Check the module is enabled */
-               return STATUS_ERR_DENIED;
-       }
-
-       /* 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);
-
-       /* Set character size */
-       module->character_size = config->character_size;
-
-       /* Set transmitter and receiver status */
-       module->receiver_enabled = config->receiver_enable;
-       module->transmitter_enabled = config->transmitter_enable;
-
-#ifdef FEATURE_USART_LIN_SLAVE
-       module->lin_slave_enabled = config->lin_slave_enable;
-#endif
-#ifdef FEATURE_USART_START_FRAME_DECTION
-       module->start_frame_detection_enabled = 
config->start_frame_detection_enable;
-#endif
-#ifdef FEATURE_USART_ISO7816
-       module->iso7816_mode_enabled = config->iso7816_config.enabled;
-#endif
-       /* Set configuration according to the config struct */
-       status_code = _usart_set_config(module, config);
-       if(status_code != STATUS_OK) {
-               return status_code;
-       }
-
-       struct system_pinmux_config pin_conf;
-       system_pinmux_get_config_defaults(&pin_conf);
-       pin_conf.direction = SYSTEM_PINMUX_PIN_DIR_INPUT;
-       pin_conf.input_pull = SYSTEM_PINMUX_PIN_PULL_NONE;
-
-       uint32_t pad_pinmuxes[] = {
-                       config->pinmux_pad0, config->pinmux_pad1,
-                       config->pinmux_pad2, config->pinmux_pad3
-               };
-
-       /* Configure the SERCOM pins according to the user configuration */
-       for (uint8_t pad = 0; pad < 4; pad++) {
-               uint32_t current_pinmux = pad_pinmuxes[pad];
-
-               if (current_pinmux == PINMUX_DEFAULT) {
-                       current_pinmux = _sercom_get_default_pad(hw, pad);
-               }
-
-               if (current_pinmux != PINMUX_UNUSED) {
-                       pin_conf.mux_position = current_pinmux & 0xFFFF;
-                       system_pinmux_pin_set_config(current_pinmux >> 16, 
&pin_conf);
-               }
-       }
-
-#if USART_CALLBACK_MODE == true
-       /* Initialize parameters */
-       for (uint32_t i = 0; i < USART_CALLBACK_N; i++) {
-               module->callback[i]            = NULL;
-       }
-
-       module->tx_buffer_ptr              = NULL;
-       module->rx_buffer_ptr              = NULL;
-       module->remaining_tx_buffer_length = 0x0000;
-       module->remaining_rx_buffer_length = 0x0000;
-       module->callback_reg_mask          = 0x00;
-       module->callback_enable_mask       = 0x00;
-       module->rx_status                  = STATUS_OK;
-       module->tx_status                  = STATUS_OK;
-
-       /* Set interrupt handler and register USART software module struct in
-        * look-up table */
-       uint8_t instance_index = _sercom_get_sercom_inst_index(module->hw);
-       _sercom_set_handler(instance_index, _usart_interrupt_handler);
-       _sercom_instances[instance_index] = module;
-#endif
-
-       return status_code;
-}
-
-/**
- * \brief Transmit a character via the USART
- *
- * This blocking function will transmit a single character via the
- * USART.
- *
- * \param[in]  module   Pointer to the software instance struct
- * \param[in]  tx_data  Data to transfer
- *
- * \return Status of the operation.
- * \retval STATUS_OK         If the operation was completed
- * \retval STATUS_BUSY       If the operation was not completed, due to the 
USART
- *                           module being busy
- * \retval STATUS_ERR_DENIED If the transmitter is not enabled
- */
-enum status_code usart_write_wait(
-               struct usart_module *const module,
-               const uint16_t tx_data)
-{
-       /* Sanity check arguments */
-       Assert(module);
-       Assert(module->hw);
-
-       /* Get a pointer to the hardware module instance */
-       SercomUsart *const usart_hw = &(module->hw->USART);
-
-       /* Check that the transmitter is enabled */
-       if (!(module->transmitter_enabled)) {
-               return STATUS_ERR_DENIED;
-       }
-
-#if USART_CALLBACK_MODE == true
-       /* Check if the USART is busy doing asynchronous operation. */
-       if (module->remaining_tx_buffer_length > 0) {
-               return STATUS_BUSY;
-       }
-
-#else
-       /* Check if USART is ready for new data */
-       if (!(usart_hw->INTFLAG.reg & SERCOM_USART_INTFLAG_DRE)) {
-               /* Return error code */
-               return STATUS_BUSY;
-       }
-#endif
-
-       /* Wait until synchronization is complete */
-       _usart_wait_for_sync(module);
-
-       /* Write data to USART module */
-       usart_hw->DATA.reg = tx_data;
-
-       while (!(usart_hw->INTFLAG.reg & SERCOM_USART_INTFLAG_TXC)) {
-               /* Wait until data is sent */
-       }
-
-       return STATUS_OK;
-}
-
-/**
- * \brief Receive a character via the USART
- *
- * This blocking function will receive a character via the USART.
- *
- * \param[in]   module   Pointer to the software instance struct
- * \param[out]  rx_data  Pointer to received data
- *
- * \return Status of the operation.
- * \retval STATUS_OK                If the operation was completed
- * \retval STATUS_BUSY              If the operation was not completed,
- *                                  due to the USART module being busy
- * \retval STATUS_ERR_BAD_FORMAT    If the operation was not completed,
- *                                  due to configuration mismatch between USART
- *                                  and the sender
- * \retval STATUS_ERR_BAD_OVERFLOW  If the operation was not completed,
- *                                  due to the baudrate being too low or the
- *                                  system frequency being too high
- * \retval STATUS_ERR_BAD_DATA      If the operation was not completed, due to
- *                                  data being corrupted
- * \retval STATUS_ERR_DENIED        If the receiver is not enabled
- */
-enum status_code usart_read_wait(
-               struct usart_module *const module,
-               uint16_t *const rx_data)
-{
-       /* Sanity check arguments */
-       Assert(module);
-       Assert(module->hw);
-
-       /* Error variable */
-       uint8_t error_code;
-
-       /* Get a pointer to the hardware module instance */
-       SercomUsart *const usart_hw = &(module->hw->USART);
-
-       /* Check that the receiver is enabled */
-       if (!(module->receiver_enabled)) {
-               return STATUS_ERR_DENIED;
-       }
-
-#if USART_CALLBACK_MODE == true
-       /* Check if the USART is busy doing asynchronous operation. */
-       if (module->remaining_rx_buffer_length > 0) {
-               return STATUS_BUSY;
-       }
-#endif
-
-       /* Check if USART has new data */
-       if (!(usart_hw->INTFLAG.reg & SERCOM_USART_INTFLAG_RXC)) {
-               /* Return error code */
-               return STATUS_BUSY;
-       }
-
-       /* Wait until synchronization is complete */
-       _usart_wait_for_sync(module);
-
-       /* Read out the status code and mask away all but the 3 LSBs*/
-       error_code = (uint8_t)(usart_hw->STATUS.reg & SERCOM_USART_STATUS_MASK);
-
-       /* Check if an error has occurred during the receiving */
-       if (error_code) {
-               /* Check which error occurred */
-               if (error_code & SERCOM_USART_STATUS_FERR) {
-                       /* Clear flag by writing a 1 to it and
-                        * return with an error code */
-                       usart_hw->STATUS.reg = SERCOM_USART_STATUS_FERR;
-
-                       return STATUS_ERR_BAD_FORMAT;
-               } else if (error_code & SERCOM_USART_STATUS_BUFOVF) {
-                       /* Clear flag by writing a 1 to it and
-                        * return with an error code */
-                       usart_hw->STATUS.reg = SERCOM_USART_STATUS_BUFOVF;
-
-                       return STATUS_ERR_OVERFLOW;
-               } else if (error_code & SERCOM_USART_STATUS_PERR) {
-                       /* Clear flag by writing a 1 to it and
-                        * return with an error code */
-                       usart_hw->STATUS.reg = SERCOM_USART_STATUS_PERR;
-
-                       return STATUS_ERR_BAD_DATA;
-               }
-#ifdef FEATURE_USART_LIN_SLAVE
-               else if (error_code & SERCOM_USART_STATUS_ISF) {
-                       /* Clear flag by writing 1 to it  and
-                        *  return with an error code */
-                       usart_hw->STATUS.reg |= SERCOM_USART_STATUS_ISF;
-
-                       return STATUS_ERR_PROTOCOL;
-               }
-#endif
-#ifdef FEATURE_USART_COLLISION_DECTION
-               else if (error_code & SERCOM_USART_STATUS_COLL) {
-                       /* Clear flag by writing 1 to it
-                        *  return with an error code */
-                       usart_hw->STATUS.reg |= SERCOM_USART_STATUS_COLL;
-
-                       return STATUS_ERR_PACKET_COLLISION;
-               }
-#endif
-       }
-
-       /* Read data from USART module */
-       *rx_data = usart_hw->DATA.reg;
-
-       return STATUS_OK;
-}
-
-/**
- * \brief Transmit a buffer of characters via the USART
- *
- * This blocking function will transmit a block of \c length characters
- * via the USART.
- *
- * \note Using this function in combination with the interrupt (\c _job) 
functions is
- *       not recommended as it has no functionality to check if there is an
- *       ongoing interrupt driven operation running or not.
- *
- * \param[in]  module   Pointer to USART software instance struct
- * \param[in]  tx_data  Pointer to data to transmit
- * \param[in]  length   Number of characters to transmit
- *
- * \note If using 9-bit data, the array that *tx_data point to should be 
defined 
- *       as uint16_t array and should be casted to uint8_t* pointer. Because 
it 
- *       is an address pointer, the highest byte is not discarded. For example:
- *   \code
-          #define TX_LEN 3
-          uint16_t tx_buf[TX_LEN] = {0x0111, 0x0022, 0x0133};
-          usart_write_buffer_wait(&module, (uint8_t*)tx_buf, TX_LEN);
-    \endcode
- *
- * \return Status of the operation.
- * \retval STATUS_OK              If operation was completed
- * \retval STATUS_ERR_INVALID_ARG If operation was not completed, due to 
invalid
- *                                arguments
- * \retval STATUS_ERR_TIMEOUT     If operation was not completed, due to USART
- *                                module timing out
- * \retval STATUS_ERR_DENIED      If the transmitter is not enabled
- */
-enum status_code usart_write_buffer_wait(
-               struct usart_module *const module,
-               const uint8_t *tx_data,
-               uint16_t length)
-{
-       /* Sanity check arguments */
-       Assert(module);
-       Assert(module->hw);
-
-       /* Check if the buffer length is valid */
-       if (length == 0) {
-               return STATUS_ERR_INVALID_ARG;
-       }
-
-       /* Check that the transmitter is enabled */
-       if (!(module->transmitter_enabled)) {
-               return STATUS_ERR_DENIED;
-       }
-
-       /* Get a pointer to the hardware module instance */
-       SercomUsart *const usart_hw = &(module->hw->USART);
-
-       /* Wait until synchronization is complete */
-       _usart_wait_for_sync(module);
-
-       uint16_t tx_pos = 0;
-
-       /* Blocks while buffer is being transferred */
-       while (length--) {
-               /* Wait for the USART to be ready for new data and abort
-               * operation if it doesn't get ready within the timeout*/
-               for (uint32_t i = 0; i <= USART_TIMEOUT; i++) {
-                       if (usart_hw->INTFLAG.reg & SERCOM_USART_INTFLAG_DRE) {
-                               break;
-                       } else if (i == USART_TIMEOUT) {
-                               return STATUS_ERR_TIMEOUT;
-                       }
-               }
-
-               /* Data to send is at least 8 bits long */
-               uint16_t data_to_send = tx_data[tx_pos++];
-
-               /* Check if the character size exceeds 8 bit */
-               if (module->character_size == USART_CHARACTER_SIZE_9BIT) {
-                       data_to_send |= (tx_data[tx_pos++] << 8);
-               }
-
-               /* Send the data through the USART module */
-               usart_write_wait(module, data_to_send);
-       }
-
-       /* Wait until Transmit is complete or timeout */
-       for (uint32_t i = 0; i <= USART_TIMEOUT; i++) {
-               if (usart_hw->INTFLAG.reg & SERCOM_USART_INTFLAG_TXC) {
-                       break;
-               } else if (i == USART_TIMEOUT) {
-                       return STATUS_ERR_TIMEOUT;
-               }
-       }
-
-       return STATUS_OK;
-}
-
-/**
- * \brief Receive a buffer of \c length characters via the USART
- *
- * This blocking function will receive a block of \c length characters
- * via the USART.
- *
- * \note Using this function in combination with the interrupt (\c *_job)
- *       functions is not recommended as it has no functionality to check if
- *       there is an ongoing interrupt driven operation running or not.
- *
- * \param[in]  module   Pointer to USART software instance struct
- * \param[out] rx_data  Pointer to receive buffer
- * \param[in]  length   Number of characters to receive
- *
- * \note If using 9-bit data, the array that *rx_data point to should be 
defined 
- *       as uint16_t array and should be casted to uint8_t* pointer. Because 
it 
- *       is an address pointer, the highest byte is not discarded. For example:
- *   \code
-          #define RX_LEN 3
-          uint16_t rx_buf[RX_LEN] = {0x0,};
-          usart_read_buffer_wait(&module, (uint8_t*)rx_buf, RX_LEN);
-    \endcode
- *
- * \return Status of the operation.
- * \retval STATUS_OK                If operation was completed
- * \retval STATUS_ERR_INVALID_ARG   If operation was not completed, due to an
- *                                  invalid argument being supplied
- * \retval STATUS_ERR_TIMEOUT       If operation was not completed, due
- *                                  to USART module timing out
- * \retval STATUS_ERR_BAD_FORMAT    If the operation was not completed,
- *                                  due to a configuration mismatch
- *                                  between USART and the sender
- * \retval STATUS_ERR_BAD_OVERFLOW  If the operation was not completed,
- *                                  due to the baudrate being too low or the
- *                                  system frequency being too high
- * \retval STATUS_ERR_BAD_DATA      If the operation was not completed, due
- *                                  to data being corrupted
- * \retval STATUS_ERR_DENIED        If the receiver is not enabled
- */
-enum status_code usart_read_buffer_wait(
-               struct usart_module *const module,
-               uint8_t *rx_data,
-               uint16_t length)
-{
-       /* Sanity check arguments */
-       Assert(module);
-       Assert(module->hw);
-
-       /* Check if the buffer length is valid */
-       if (length == 0) {
-               return STATUS_ERR_INVALID_ARG;
-       }
-
-       /* Check that the receiver is enabled */
-       if (!(module->receiver_enabled)) {
-               return STATUS_ERR_DENIED;
-       }
-
-       /* Get a pointer to the hardware module instance */
-       SercomUsart *const usart_hw = &(module->hw->USART);
-
-       uint16_t rx_pos = 0;
-
-       /* Blocks while buffer is being received */
-       while (length--) {
-               /* Wait for the USART to have new data and abort operation if it
-                * doesn't get ready within the timeout*/
-               for (uint32_t i = 0; i <= USART_TIMEOUT; i++) {
-                       if (usart_hw->INTFLAG.reg & SERCOM_USART_INTFLAG_RXC) {
-                               break;
-                       } else if (i == USART_TIMEOUT) {
-                               return STATUS_ERR_TIMEOUT;
-                       }
-               }
-
-               enum status_code retval;
-               uint16_t received_data = 0;
-
-               retval = usart_read_wait(module, &received_data);
-
-               if (retval != STATUS_OK) {
-                       /* Overflow, abort */
-                       return retval;
-               }
-
-               /* Read value will be at least 8-bits long */
-               rx_data[rx_pos++] = received_data;
-
-               /* If 9-bit data, write next received byte to the buffer */
-               if (module->character_size == USART_CHARACTER_SIZE_9BIT) {
-                       rx_data[rx_pos++] = (received_data >> 8);
-               }
-       }
-
-       return STATUS_OK;
-}

Reply via email to