Index: bsps/arm/atsam/contrib/libraries/libboard/board.h
===================================================================
--- bsps/arm/atsam/contrib/libraries/libboard/board.h	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libboard/board.h	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,45 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+#ifndef _BOARD_H_
+#define _BOARD_H_
+
+#ifdef __rtems__
+#include <bspopts.h>
+#endif /* __rtems__ */
+#if defined(BOARD_SAMV71_XULT)
+	#include "board_v71_xult.h"
+#elif defined(BOARD_SAME70_XPLD)
+	#include "board_e70_xpld.h"
+#else
+	#error "board definition not correct!"
+#endif
+
+#endif /* #ifndef _BOARD_H_ */
+
Index: bsps/arm/atsam/contrib/libraries/libboard/board_v71_xult.h
===================================================================
--- bsps/arm/atsam/contrib/libraries/libboard/board_v71_xult.h	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libboard/board_v71_xult.h	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,778 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+/**
+ * \page samv7_Xplained_ultra_board_desc SAM V71 Xplained Ultra - Board
+ * Description
+ *
+ * \section Purpose
+ *
+ * This file is dedicated to describe the SAM V71 Xplained Ultra board.
+ *
+ * \section Contents
+ *
+ *  - For SAM V71 Xplained Ultra board information, see
+ *    \subpage samv7_Xplained_ultra_board_info.
+ *  - For operating frequency information, see \subpage samv7_Xplained_ultra_opfreq.
+ *  - For using portable PIO definitions, see \subpage samv7_Xplained_ultra_piodef.
+ *  - For using GMAC PIO definitions, see \subpage samv7_Xplained_ultra_gmac.
+ *  - For using ISI definitions, see \subpage samv7_Xplained_ultra_isi.
+ *  - For on-board memories, see \subpage samv7_Xplained_ultra_mem.
+ *  - Several USB definitions are included here,
+ *    see \subpage samv7_Xplained_ultra_usb.
+ *  - For External components, see \subpage samv7_Xplained_ultra_extcomp.
+ *  - For Individual chip definition, see \subpage samv7_Xplained_ultra_chipdef.
+ *
+ * To get more software details and the full list of parameters related to the
+ * SAM V71 Xplained Ultra board configuration, please have a look at the source
+ * file:
+ * \ref board.h, \ref board_v71_xult.h\n
+ *
+ * \section Usage
+ *
+ *  - The code for booting the board is provided by startup_samv71.c and
+ *    board_lowlevel.c.
+ *  - For using board PIOs, board characteristics (clock, etc.) and external
+ *    components, see board.h, board_v71_xult.h.
+ *  - For manipulating memories, see board_memories.h.
+ *
+ * This file can be used as a template and modified to fit a custom board, with
+ * specific PIOs usage or memory connections.
+ */
+
+/**
+ *  \file board.h
+ *
+ *  Definition of SAM V71 Xplained Ultra board characteristics, PIOs and
+ *  external components interface.
+ */
+
+#ifndef _BOARD_V71_XULT_H_
+#define _BOARD_V71_XULT_H_
+
+/*----------------------------------------------------------------------------
+ *        Headers
+ *----------------------------------------------------------------------------*/
+
+#include "chip.h"
+
+#include "include/board_lowlevel.h"
+#include "include/board_memories.h"
+#include "include/led.h"
+#include "include/gmii.h"
+#include "include/gmacb_phy.h"
+#include "include/dbg_console.h"
+#include "include/bmp.h"
+#include "include/lcdd.h"
+#include "include/ili9488.h"
+#include "include/ili9488_reg.h"
+#include "include/ili9488_spi.h"
+#include "include/ili9488_ebi.h"
+#include "include/ili9488_dma.h"
+#include "include/ili9488_spi_dma.h"
+#include "include/ili9488_ebi_dma.h"
+#include "include/frame_buffer.h"
+#include "include/lcd_color.h"
+#include "include/lcd_draw.h"
+#include "include/lcd_font10x14.h"
+#include "include/lcd_font.h"
+#include "include/lcd_gimp_image.h"
+#include "include/rtc_calib.h"
+#include "include/wm8904.h"
+#include "include/cs2100.h"
+#include "include/s25fl1.h"
+#include "include/image_sensor_inf.h"
+#include "include/iso7816_4.h"
+
+#ifndef __rtems__
+#if defined (__GNUC__)
+	#include "include/syscalls.h"
+#endif
+#endif /* __rtems__ */
+/*----------------------------------------------------------------------------
+ *        Definitions
+ *----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------*/
+/**
+ * \page samv7_Xplained_ultra_board_info "SAM V71 Xplained Ultra - Board informations"
+ * This page lists several definition related to the board description.
+ *
+ * \section Definitions
+ * - \ref BOARD_NAME
+ */
+
+/** Name of the board */
+#define BOARD_NAME "SAM V71 Xplained Ultra"
+#define NO_PUSHBUTTON
+#ifndef __rtems__
+/*----------------------------------------------------------------------------*/
+/**
+ *  \page samv7_Xplained_ultra_opfreq "SAM V71 Xplained Ultra - Operating frequencies"
+ *  This page lists several definition related to the board operating frequency
+ *  (when using the initialization done by board_lowlevel.c).
+ *
+ *  \section Definitions
+ *  - \ref BOARD_MAINOSC
+ *  - \ref BOARD_MCK
+ */
+
+/** Frequency of the board main oscillator */
+#define BOARD_MAINOSC    12000000
+
+/** Master clock frequency (when using board_lowlevel.c) */
+
+#ifdef MCK_123MHZ
+	#define BOARD_MCK    123000000
+#else
+	#define BOARD_MCK    150000000
+#endif
+
+#if (BOARD_MCK==123000000)
+
+	#define PLL_MUL    0x16
+	#define PLL_DIV    0x01
+
+#else   // 300MHz(PCK) and 150MHz(MCK) by default
+
+	#define PLL_MUL    0x19
+	#define PLL_DIV    0x01
+
+#endif
+#else /* __rtems__ */
+#include <bsp/atsam-clock-config.h>
+#endif /* __rtems__ */
+
+/*----------------------------------------------------------------------------*/
+/**
+ * \page samv7_Xplained_ultra_piodef "SAM V71 Xplained Ultra - PIO definitions"
+ * This pages lists all the PIOs definitions contained in board.h. The constants
+ * are named using the following convention: PIN_* for a constant which defines
+ * a single Pin instance (but may include several PIOs sharing the same
+ * controller), and PINS_* for a list of Pin instances.
+ *
+ * UART0
+ * - \ref PINS_UART0
+ *
+ * UART4
+ * - \ref PINS_UART4
+ *
+ * LEDs
+ * - \ref PIN_LED_0
+ * - \ref PIN_LED_1
+ * - \ref PINS_LEDS
+ *
+ * Push buttons
+ * - \ref PIN_PUSHBUTTON_0
+ * - \ref PIN_PUSHBUTTON_1
+ * - \ref PINS_PUSHBUTTONS
+ * - \ref PUSHBUTTON_BP0
+ * - \ref PUSHBUTTON_BP1
+ *
+ * PWMC
+ * - \ref PIN_PWMC_PWMH0
+ * - \ref PIN_PWMC_PWMH1
+ * - \ref PIN_PWM_LED0
+ * - \ref PIN_PWM_LED1
+ * - \ref CHANNEL_PWM_LED0
+ * - \ref CHANNEL_PWM_LED1
+ *
+ * SPI
+ * - \ref PIN_SPI_MISO
+ * - \ref PIN_SPI_MOSI
+ * - \ref PIN_SPI_SPCK
+ * - \ref PINS_SPI
+ *
+ * PCK0
+ * - \ref PIN_PCK0
+ * - \ref PIN_PCK1
+ * - \ref PIN_PCK2
+ *
+ * PIO PARALLEL CAPTURE
+ * - \ref PIN_PIODCEN1
+ * - \ref PIN_PIODCEN2
+ *
+ * TWI
+ * - \ref TWI_V3XX
+ * - \ref PIN_TWI_TWD0
+ * - \ref PIN_TWI_TWCK0
+ * - \ref PINS_TWI0
+ * - \ref PIN_TWI_TWD1
+ * - \ref PIN_TWI_TWCK1
+ * - \ref PINS_TWI1
+ *
+ * USART0
+ * - \ref PIN_USART0_RXD
+ * - \ref PIN_USART0_TXD
+ * - \ref PIN_USART0_CTS
+ * - \ref PIN_USART0_RTS
+ * - \ref PIN_USART0_SCK
+ *
+ * USART1
+ * - \ref PIN_USART1_RXD
+ * - \ref PIN_USART1_TXD
+ * - \ref PIN_USART1_CTS
+ * - \ref PIN_USART1_RTS
+ * - \ref PIN_USART1_SCK
+ *
+ * USART2
+ * - \ref PIN_USART2_RXD
+ * - \ref PIN_USART2_TXD
+ * - \ref PIN_USART2_CTS
+ * - \ref PIN_USART2_RTS
+ * - \ref PIN_USART2_SCK
+ *
+ * SSC
+ * - \ref PIN_SSC_TD
+ * - \ref PIN_SSC_TK
+ * - \ref PIN_SSC_TF
+ * - \ref PIN_SSC_RD
+ * - \ref PIN_SSC_RK
+ * - \ref PIN_SSC_RF
+ * - \ref PIN_SSC_TD
+ * - \ref PINS_SSC_CODEC
+ *
+ * MCAN
+ * - \ref PIN_MCAN0_TXD
+ * - \ref PIN_MCAN0_RXD
+ * - \ref PIN_MCAN1_TXD
+ * - \ref PIN_MCAN1_RXD
+ */
+
+/** SSC pin Transmitter Data (TD) */
+#define PIN_SSC_TD  {PIO_PD26B_TD, PIOD, ID_PIOD, PIO_PERIPH_B, PIO_DEFAULT}
+/** SSC pin Transmitter Clock (TK) */
+#define PIN_SSC_TK  {PIO_PB1D_TK, PIOB, ID_PIOB, PIO_PERIPH_D, PIO_DEFAULT}
+/** SSC pin Transmitter FrameSync (TF) */
+#define PIN_SSC_TF  {PIO_PB0D_TF, PIOB, ID_PIOB, PIO_PERIPH_D, PIO_DEFAULT}
+/** SSC pin RD */
+#define PIN_SSC_RD  {PIO_PA10C_RD, PIOA, ID_PIOA, PIO_PERIPH_C, PIO_DEFAULT}
+/** SSC pin RK */
+#define PIN_SSC_RK  {PIO_PA22A_RK, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
+/** SSC pin RF */
+#define PIN_SSC_RF  {PIO_PD24B_RF, PIOD, ID_PIOD, PIO_PERIPH_B, PIO_DEFAULT}
+
+/** SSC pins definition for codec. */
+#define PINS_SSC_CODEC \
+	{PIN_SSC_TD,  PIN_SSC_TK, PIN_SSC_TF, PIN_SSC_RD,  PIN_SSC_RK, PIN_SSC_RF}
+
+/** UART pins (UTXD0 and URXD0) definitions, PA9,10. */
+#define PINS_UART0  \
+	{PIO_PA9A_URXD0 | PIO_PA10A_UTXD0, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
+/** UART pins (UTXD4 and URXD4) definitions, PD19,18. */
+#define PINS_UART4 \
+	{PIO_PD18C_URXD4 | PIO_PD19C_UTXD4, PIOD, ID_PIOD, PIO_PERIPH_C, PIO_DEFAULT}
+
+/* LED pins definitions */
+#define LED_YELLOW0  0
+#define LED_YELLOW1  1
+
+/** LED #0 pin definition (YELLOW). */
+#define PIN_LED_0  {PIO_PC9, PIOC, ID_PIOC, PIO_OUTPUT_1, PIO_DEFAULT}
+/** LED #1 pin definition (YELLOW). */
+#define PIN_LED_1  {PIO_PA23, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
+
+/** List of all LEDs definitions. */
+#define PINS_LEDS  {PIN_LED_0, PIN_LED_1}
+
+/** Number of LEDs */
+#define LED_NUM  2
+
+/**
+ * Push button #0 definition.
+ * Attributes = pull-up + debounce + interrupt on rising edge.
+ */
+#define PIN_PUSHBUTTON_0 \
+	{PIO_PA9, PIOA, ID_PIOA, PIO_INPUT, PIO_PULLUP | PIO_DEBOUNCE | PIO_IT_FALL_EDGE}
+/**
+ * Push button #1 definition.
+ * Attributes = pull-up + debounce + interrupt on rising edge.
+ */
+#define PIN_PUSHBUTTON_1 \
+	{PIO_PB12, PIOB, ID_PIOB, PIO_INPUT, PIO_PULLUP | PIO_DEBOUNCE | PIO_IT_FALL_EDGE}
+
+/** List of all push button definitions. */
+#define PINS_PUSHBUTTONS {PIN_PUSHBUTTON_0, PIN_PUSHBUTTON_1}
+
+/** Push button #0 index. */
+#define PUSHBUTTON_BP0  0
+/** Push button #1 index. */
+#define PUSHBUTTON_BP1  1
+
+/** Number of Buttons */
+#define BUTTON_NUM  2
+
+/** Index of wakeup source */
+#define WKUP_IDX    6
+
+/** PWMC PWM0 pin definition: Output High. */
+#define PIN_PWMC_PWMH0  {PIO_PD20A_PWMH0, PIOD, ID_PIOD, PIO_PERIPH_A, PIO_DEFAULT}
+/** PWMC PWM1 pin definition: Output High. */
+#define PIN_PWMC_PWMH1  {PIO_PD21A_PWMH1, PIOD, ID_PIOD, PIO_PERIPH_A, PIO_DEFAULT}
+/** PWM pins definition for LED0 */
+#define PIN_PWM_LED0  PIN_PWMC_PWMH0
+/** PWM pins definition for LED1 */
+#define PIN_PWM_LED1  PIN_PWMC_PWMH1
+/** PWM channel for LED0 */
+#define CHANNEL_PWM_LED0 0
+/** PWM channel for LED1 */
+#define CHANNEL_PWM_LED1 1
+
+/** SPI MISO pin definition. */
+#define PIN_SPI_MISO {PIO_PD20B_SPI0_MISO, PIOD, ID_PIOD, PIO_PERIPH_B, PIO_DEFAULT}
+/** SPI MOSI pin definition. */
+#define PIN_SPI_MOSI {PIO_PD21B_SPI0_MOSI, PIOD, ID_PIOD, PIO_PERIPH_B, PIO_DEFAULT}
+/** SPI SPCK pin definition. */
+#define PIN_SPI_SPCK {PIO_PD22B_SPI0_SPCK, PIOD, ID_PIOD, PIO_PERIPH_B, PIO_DEFAULT}
+/** SPI chip select pin definition. */
+#define PIN_SPI_NPCS0 {PIO_PB2D_SPI0_NPCS0, PIOB, ID_PIOB, PIO_PERIPH_D, PIO_DEFAULT}
+#define PIN_SPI_NPCS1 {PIO_PD25B_SPI0_NPCS1, PIOD, ID_PIOD, PIO_PERIPH_B, PIO_DEFAULT}
+#define PIN_SPI_NPCS3 {PIO_PD27B_SPI0_NPCS3, PIOD, ID_PIOD, PIO_PERIPH_B, PIO_DEFAULT}
+
+/** List of SPI pin definitions (MISO, MOSI & SPCK). */
+#define PINS_SPI  PIN_SPI_MISO, PIN_SPI_MOSI, PIN_SPI_SPCK
+
+/** PCK0 */
+#define PIN_PCK0  {PIO_PB13B_PCK0, PIOB, ID_PIOB, PIO_PERIPH_B, PIO_DEFAULT}
+/** PCK1 */
+#define PIN_PCK1  {PIO_PA17B_PCK1, PIOB, ID_PIOB, PIO_PERIPH_B, PIO_DEFAULT}
+/** PCK2 */
+#define PIN_PCK2   {PIO_PA18B_PCK2, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
+
+
+/** PIO PARALLEL CAPTURE */
+/** Parallel Capture Mode Data Enable1 */
+#define PIN_PIODCEN1 PIO_PA15
+/** Parallel Capture Mode Data Enable2 */
+#define PIN_PIODCEN2 PIO_PA16
+
+/** TWI version 3.xx */
+#define TWI_V3XX
+/** TWI0 data pin */
+#define PIN_TWI_TWD0 {PIO_PA3A_TWD0, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
+/** TWI0 clock pin */
+#define PIN_TWI_TWCK0 {PIO_PA4A_TWCK0, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
+/** TWI0 pins */
+#define PINS_TWI0  {PIN_TWI_TWD0, PIN_TWI_TWCK0}
+
+/** TWI1 data pin */
+#define PIN_TWI_TWD1 {PIO_PB4A_TWD1, PIOB, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT}
+/** TWI1 clock pin */
+#define PIN_TWI_TWCK1 {PIO_PB5A_TWCK1, PIOB, ID_PIOB, PIO_PERIPH_A,PIO_DEFAULT}
+/** TWI1 pins */
+#define PINS_TWI1  {PIN_TWI_TWD1, PIN_TWI_TWCK1}
+
+/** USART0 pin RX */
+#define PIN_USART0_RXD {PIO_PB0C_RXD0, PIOB, ID_PIOB, PIO_PERIPH_C, PIO_DEFAULT}
+/** USART0 pin TX */
+#define PIN_USART0_TXD {PIO_PB1C_TXD0, PIOB, ID_PIOB, PIO_PERIPH_C, PIO_DEFAULT}
+/** USART0 pin CTS */
+#define PIN_USART0_CTS {PIO_PB2C_CTS0, PIOB, ID_PIOB, PIO_PERIPH_C, PIO_DEFAULT}
+/** USART0 pin RTS */
+#define PIN_USART0_RTS {PIO_PB3C_RTS0, PIOB, ID_PIOB, PIO_PERIPH_C, PIO_DEFAULT}
+/** USART0 pin SCK */
+#define PIN_USART0_SCK {PIO_PB13C_SCK0, PIOB, ID_PIOB, PIO_PERIPH_C,PIO_DEFAULT}
+
+/** USART1 pin RX */
+#define PIN_USART1_RXD {PIO_PA21A_RXD1, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
+/** USART1 pin TX */
+#define PIN_USART1_TXD {PIO_PB4D_TXD1, PIOB, ID_PIOB, PIO_PERIPH_D, PIO_DEFAULT}
+/** USART1 pin CTS */
+#define PIN_USART1_CTS {PIO_PA25A_CTS1, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
+/** USART1 pin RTS */
+#define PIN_USART1_RTS {PIO_PA24A_RTS1, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
+/** USART1 pin ENABLE */
+#define PIN_USART1_EN {PIO_PA23A_SCK1, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
+/** USART1 pin SCK */
+#define PIN_USART1_SCK {PIO_PA23A_SCK1, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
+
+/** USART2 pin RX */
+#define PIN_USART2_RXD {PIO_PD15B_RXD2, PIOD, ID_PIOD, PIO_PERIPH_B, PIO_DEFAULT}
+/** USART2 pin TX */
+#define PIN_USART2_TXD {PIO_PD16B_TXD2, PIOD, ID_PIOD, PIO_PERIPH_B, PIO_DEFAULT}
+/** USART2 pin CTS */
+#define PIN_USART2_CTS {PIO_PD19B_CTS2, PIOD, ID_PIOD, PIO_PERIPH_B, PIO_DEFAULT}
+/** USART2 pin RTS */
+#define PIN_USART2_RTS {PIO_PD18B_RTS2, PIOD, ID_PIOD, PIO_PERIPH_B, PIO_DEFAULT}
+/** USART2 pin SCK */
+#define PIN_USART2_SCK {PIO_PD17B_SCK2, PIOD, ID_PIOD, PIO_PERIPH_B, PIO_DEFAULT}
+
+/*Pins for USART0 as 7816 mode*/
+/** PIN used for reset the smartcard */
+#define PIN_ISO7816_RSTMC  {PIO_PB2C_CTS0, PIOB, ID_PIOB, PIO_OUTPUT_0, PIO_DEFAULT}
+/** Pins used for connect the smartcard */
+#define PINS_ISO7816        PIN_USART0_TXD, PIN_USART0_SCK,PIN_ISO7816_RSTMC
+
+/** MCAN0 pin Transmit Data (TXD) */
+#define PIN_MCAN0_TXD {PIO_PB2A_CANTX0, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
+/** MCAN0 pin Receive Data (RXD) */
+#define PIN_MCAN0_RXD {PIO_PB3A_CANRX0, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
+
+/** MCAN1 pin Transmit Data (TXD) */
+#define PIN_MCAN1_TXD {PIO_PC14C_CANTX1, PIOC, ID_PIOC, PIO_PERIPH_C, PIO_DEFAULT}
+/** MCAN1 pin Receive Data (RXD) */
+#define PIN_MCAN1_RXD {PIO_PC12C_CANRX1, PIOC, ID_PIOC, PIO_PERIPH_C, PIO_DEFAULT}
+
+/*----------------------------------------------------------------------------*/
+/**
+ * \page samv7_Xplained_ultra_gmac "SAM V71 Xplained Ultra - GMAC"
+ * \section GMAC
+ * - \ref BOARD_GMAC_PHY_ADDR
+ * - \ref BOARD_GMAC_PHY_COMP_KSZ8061RNB
+ * - \ref BOARD_GMAC_MODE_RMII
+ * - \ref BOARD_GMAC_PINS
+ * - \ref BOARD_GMAC_RESET_PIN
+ *
+ */
+/** PHY address */
+#define BOARD_GMAC_PHY_ADDR             1
+/** PHY Component */
+#define BOARD_GMAC_PHY_COMP_KSZ8061RNB  1
+/** Board GMAC power control - ALWAYS ON */
+#define BOARD_GMAC_POWER_ALWAYS_ON
+/** Board GMAC work mode - RMII/MII (1 / 0) */
+#define BOARD_GMAC_MODE_RMII            1
+
+/** The PIN list of PIO for GMAC */
+#define BOARD_GMAC_PINS \
+	{ (PIO_PD0A_GTXCK | PIO_PD1A_GTXEN | PIO_PD2A_GTX0 | PIO_PD3A_GTX1 \
+		| PIO_PD4A_GRXDV | PIO_PD5A_GRX0 | PIO_PD6A_GRX1 | PIO_PD7A_GRXER \
+		| PIO_PD8A_GMDC | PIO_PD9A_GMDIO),PIOD, ID_PIOD, PIO_PERIPH_A, PIO_DEFAULT}, \
+	{PIO_PC30, PIOC, ID_PIOC, PIO_INPUT,    PIO_PULLUP},\
+	{PIO_PA29, PIOA, ID_PIOA, PIO_INPUT,    PIO_DEFAULT}
+
+/** The PIN list of PIO for GMAC */
+#define BOARD_GMAC_RESET_PIN {PIO_PC10, PIOC, ID_PIOC, PIO_OUTPUT_1, PIO_PULLUP}
+
+/** The runtime pin configure list for GMAC */
+#define BOARD_GMAC_RUN_PINS  BOARD_GMAC_PINS
+
+
+/*----------------------------------------------------------------------------*/
+/**
+ * \page samv7_Xplained_ultra_isi "SAM V71 Xplained Ultra - ISI"
+ * This page lists all the IO definitions connected to ISI module.
+ * ISI
+ * - \ref PIN_ISI_D0
+ * - \ref PIN_ISI_D1
+ * - \ref PIN_ISI_D2
+ * - \ref PIN_ISI_D3
+ * - \ref PIN_ISI_D4
+ * - \ref PIN_ISI_D5
+ * - \ref PIN_ISI_D6
+ * - \ref PIN_ISI_D7
+ * - \ref PIN_ISI_D8
+ * - \ref PIN_ISI_D9
+ * - \ref BOARD_ISI_VSYNC
+ * - \ref BOARD_ISI_HSYNC
+ * - \ref BOARD_ISI_PCK
+ * - \ref BOARD_ISI_PINS
+ *
+ */
+#define PIN_ISI_D0  {PIO_PD22D_ISI_D0,  PIOD, ID_PIOD, PIO_PERIPH_D, PIO_PULLUP}
+#define PIN_ISI_D1  {PIO_PD21D_ISI_D1,  PIOD, ID_PIOD, PIO_PERIPH_D, PIO_PULLUP}
+#define PIN_ISI_D2  {PIO_PB3D_ISI_D2,   PIOB, ID_PIOB, PIO_PERIPH_D, PIO_PULLUP}
+#define PIN_ISI_D3  {PIO_PA9B_ISI_D3,   PIOA, ID_PIOA, PIO_PERIPH_B, PIO_PULLUP}
+#define PIN_ISI_D4  {PIO_PA5B_ISI_D4,   PIOA, ID_PIOA, PIO_PERIPH_B, PIO_PULLUP}
+#define PIN_ISI_D5  {PIO_PD11D_ISI_D5,  PIOD, ID_PIOD, PIO_PERIPH_D, PIO_PULLUP}
+#define PIN_ISI_D6  {PIO_PD12D_ISI_D6,  PIOD, ID_PIOD, PIO_PERIPH_D, PIO_PULLUP}
+#define PIN_ISI_D7  {PIO_PA27D_ISI_D7,  PIOA, ID_PIOA, PIO_PERIPH_D, PIO_PULLUP}
+#define PIN_ISI_D8  {PIO_PD27D_ISI_D8,  PIOD, ID_PIOD, PIO_PERIPH_D, PIO_PULLUP}
+#define PIN_ISI_D9  {PIO_PD28D_ISI_D9,  PIOD, ID_PIOD, PIO_PERIPH_D, PIO_PULLUP}
+
+#define BOARD_ISI_VSYNC {PIO_PD25D_ISI_VSYNC, PIOD, ID_PIOD, PIO_PERIPH_D, PIO_DEFAULT}
+#define BOARD_ISI_HSYNC {PIO_PD24D_ISI_HSYNC, PIOD, ID_PIOD, PIO_PERIPH_D, PIO_DEFAULT}
+#define BOARD_ISI_PCK   {PIO_PA24D_ISI_PCK, PIOA, ID_PIOA, PIO_PERIPH_D, PIO_DEFAULT}
+
+#define BOARD_ISI_PCK0  { PIO_PA6B_PCK0,  PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT }
+#define BOARD_ISI_RST   { 1 << 13, PIOB, ID_PIOB, PIO_OUTPUT_1, PIO_DEFAULT }
+#define BOARD_ISI_PWD   { 1 << 19,  PIOC, ID_PIOC, PIO_OUTPUT_1, PIO_DEFAULT }
+
+#define BOARD_ISI_PINS \
+	PIN_ISI_D0, PIN_ISI_D1, PIN_ISI_D2,PIN_ISI_D3,PIN_ISI_D4, PIN_ISI_D5,\
+	PIN_ISI_D6,PIN_ISI_D7,PIN_ISI_D8, PIN_ISI_D9,BOARD_ISI_VSYNC ,\
+	BOARD_ISI_HSYNC ,BOARD_ISI_PCK, BOARD_ISI_RST, BOARD_ISI_PWD,BOARD_ISI_PCK0
+
+/*----------------------------------------------------------------------------*/
+/**
+ * \page samv7_Xplained_ultra_usb "SAM V71 Xplained Ultra - USB device"
+ *
+ * \section Definitions
+ * - \ref BOARD_USB_BMATTRIBUTES
+ *
+ * \section vBus
+ * - \ref PIN_USB_VBUS
+ *
+ */
+
+/**
+ * USB attributes configuration descriptor (bus or self powered,
+ * remote wakeup)
+ */
+#define BOARD_USB_BMATTRIBUTES USBConfigurationDescriptor_SELFPOWERED_NORWAKEUP
+
+/** USB VBus monitoring pin definition. */
+#define PIN_USB_VBUS {PIO_PC16, PIOC, ID_PIOC, PIO_INPUT, PIO_DEFAULT}
+
+
+/*----------------------------------------------------------------------------*/
+/**
+ * \page samv7_Xplained_ultra_extcomp "SAM V71 Xplained Ultra - External components"
+ * This page lists the definitions related to external on-board components
+ * located in the board.h file for the SAM V71 Xplained Ultra board.
+ *
+ * LCD
+ */
+/** Indicates board has an ILI9325 external component to manage LCD. */
+#define BOARD_LCD_ILI9488
+//#define BOARD_LCD_SPI_EXT1
+#define BOARD_LCD_SPI_EXT2
+
+/** SPI pin definition for LCD */
+#if defined (BOARD_LCD_SPI_EXT1)
+/** SPI MISO pin definition. */
+#define LCD_SPI_MISO {PIO_PD20B_SPI0_MISO, PIOD, ID_PIOD, PIO_PERIPH_B, PIO_DEFAULT}
+/** SPI MOSI pin definition. */
+#define LCD_SPI_MOSI {PIO_PD21B_SPI0_MOSI, PIOD, ID_PIOD, PIO_PERIPH_B, PIO_DEFAULT}
+/** SPI SPCK pin definition. */
+#define LCD_SPI_SPCK {PIO_PD22B_SPI0_SPCK, PIOD, ID_PIOD, PIO_PERIPH_B, PIO_DEFAULT}
+/** SPI chip select pin definition. */
+#define LCD_SPI_NPCS {PIO_PD27B_SPI0_NPCS3, PIOD, ID_PIOD, PIO_PERIPH_B,PIO_DEFAULT}
+
+/** SPI chip select pin definition. */
+#define LCD_SPI_NPCS    {PIO_PD25B_SPI0_NPCS1, PIOD, ID_PIOD, PIO_PERIPH_B,PIO_DEFAULT}
+
+/** LCD pins definition. */
+#define BOARD_SPI_LCD_PINS  {LCD_SPI_MISO, LCD_SPI_MOSI, LCD_SPI_SPCK, LCD_SPI_NPCS}
+
+/** Back-light pin definition. */
+
+#define BOARD_SPI_LCD_BACKLIGHT_PIN  \
+	{PIO_PA0A_PWMC0_PWMH0, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
+
+/** PWMC PWM0 pin definition: Output Low. */
+#define LCD_SPI_PIN_RESET   {PIO_PD28, PIOD, ID_PIOD, PIO_OUTPUT_1, PIO_DEFAULT}
+
+/** PWM channel for LED0 */
+#define CHANNEL_PWM_LCD 0
+
+#endif
+/*ENDIF BOARD_LCD_SPI_EXT1 */
+
+#if defined (BOARD_LCD_SPI_EXT2)
+/** SPI MISO pin definition. */
+#define LCD_SPI_MISO {PIO_PD20B_SPI0_MISO, PIOD, ID_PIOD, PIO_PERIPH_B, PIO_DEFAULT}
+/** SPI MOSI pin definition. */
+#define LCD_SPI_MOSI {PIO_PD21B_SPI0_MOSI, PIOD, ID_PIOD, PIO_PERIPH_B, PIO_DEFAULT}
+/** SPI SPCK pin definition. */
+#define LCD_SPI_SPCK {PIO_PD22B_SPI0_SPCK, PIOD, ID_PIOD, PIO_PERIPH_B, PIO_DEFAULT}
+/** SPI chip select pin definition. */
+#define LCD_SPI_NPCS {PIO_PD27B_SPI0_NPCS3, PIOD, ID_PIOD, PIO_PERIPH_B,PIO_DEFAULT}
+
+/** LCD pins definition. */
+#define BOARD_SPI_LCD_PINS  {LCD_SPI_MISO, LCD_SPI_MOSI, LCD_SPI_SPCK, LCD_SPI_NPCS}
+
+/** Back-light pin definition. */
+
+#define BOARD_SPI_LCD_PIN_BACKLIGHT  \
+	{PIO_PC19B_PWMC0_PWMH2, PIOC, ID_PIOC, PIO_OUTPUT_1, PIO_DEFAULT}
+
+/** PWMC PWM0 pin definition: Output Low. */
+#define LCD_SPI_PIN_RESET   {PIO_PA24, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
+
+/** LCD command/data select pin */
+#define BOARD_SPI_LCD_PIN_CDS   {PIO_PA6, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
+
+/** PWM channel for LED0 */
+#define CHANNEL_PWM_LCD 2
+
+#endif
+/*ENDIF BOARD_LCD_SPI_EXT2 */
+
+/** SMC pin definition for LCD */
+/** LCD data pin */
+#define PIN_EBI_LCD_DATAL           {0xFF, PIOC, ID_PIOC, PIO_PERIPH_A, PIO_PULLUP}
+#define PIN_EBI_LCD_DATAH_0         {0x3F, PIOE, ID_PIOE, PIO_PERIPH_A, PIO_PULLUP}
+#define PIN_EBI_LCD_DATAH_1         {PIO_PA15A_D14|PIO_PA16A_D15, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_PULLUP}
+/** LCD WE pin */
+#define PIN_EBI_LCD_NWE             {PIO_PC8A_NWE,  PIOC, ID_PIOC, PIO_PERIPH_A, PIO_PULLUP}
+/** LCD RD pin */
+#define PIN_EBI_LCD_NRD             {PIO_PC11A_NRD, PIOC, ID_PIOC, PIO_PERIPH_A, PIO_PULLUP}
+/* LCD CS pin (NCS3) */
+#define PIN_EBI_LCD_CS              {PIO_PD19A_NCS3, PIOD, ID_PIOD, PIO_PERIPH_A, PIO_PULLUP}
+/** LCD command/data select pin */
+#define BOARD_EBI_LCD_PIN_CDS       {PIO_PC30, PIOC, ID_PIOC, PIO_OUTPUT_1, PIO_DEFAULT}
+/** Back-light pin definition. */
+#define BOARD_EBI_LCD_PIN_BACKLIGHT {PIO_PC9B_TIOB7, PIOC, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT}
+/** LCD reset pin */
+#define LCD_EBI_PIN_RESET           {PIO_PC13, PIOC, ID_PIOC, PIO_OUTPUT_1, PIO_DEFAULT}
+
+/** LCD pins definition. */
+#define BOARD_EBI_LCD_PINS          \
+	{PIN_EBI_LCD_DATAL, PIN_EBI_LCD_DATAH_0, PIN_EBI_LCD_DATAH_1, \
+		PIN_EBI_LCD_NWE,PIN_EBI_LCD_NRD,PIN_EBI_LCD_CS}
+
+
+/** Display width in pixels. */
+#define BOARD_LCD_WIDTH             320
+/** Display height in pixels. */
+#define BOARD_LCD_HEIGHT            480
+
+
+/*----------------------------------------------------------------------------*/
+/**
+ * \page samv7_Xplained_ultra_mem "SAM V71 Xplained Ultra - Memories"
+ * This page lists definitions related to internal & external on-board memories.
+ * \section SDRAM
+ * - \ref PIN_SDRAM_D0_7
+ * - \ref PIN_SDRAM_D8_13
+ * - \ref PIN_SDRAM_D14_15
+ * - \ref PIN_SDRAM_A0_9
+ * - \ref PIN_SDRAM_SDA10
+ * - \ref PIN_SDRAM_CAS
+ * - \ref PIN_SDRAM_RAS
+ * - \ref PIN_SDRAM_SDCKE
+ * - \ref PIN_SDRAM_SDCK
+ * - \ref PIN_SDRAM_SDSC
+ * - \ref PIN_SDRAM_NBS0
+ * - \ref PIN_SDRAM_NBS1
+ * - \ref PIN_SDRAM_SDWE
+ * - \ref PIN_SDRAM_BA0
+ *
+ * \section SDMMC
+ * - \ref BOARD_MCI_PIN_CD
+ * - \ref BOARD_MCI_PIN_CK
+ * - \ref BOARD_MCI_PINS_SLOTA
+ * - \ref BOARD_SD_PINS
+ *
+ * \section QSPI
+ * - \ref PINS_QSPI_IO
+ * - \ref PINS_QSPI_IO3
+ * - \ref PINS_QSPI
+ */
+
+/** List of all SDRAM pin definitions. */
+#define BOARD_SDRAM_SIZE  (2*1024*1024)
+#define PIN_SDRAM_D0_7    {0x000000FF, PIOC, ID_PIOC, PIO_PERIPH_A, PIO_DEFAULT}
+#define PIN_SDRAM_D8_13   {0x0000003F, PIOE, ID_PIOE, PIO_PERIPH_A, PIO_DEFAULT}
+#define PIN_SDRAM_D14_15  {0x00018000, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
+#define PIN_SDRAM_A0_9    {0x3FF00000, PIOC, ID_PIOC, PIO_PERIPH_A, PIO_DEFAULT}
+#define PIN_SDRAM_SDA10   {0x00002000, PIOD, ID_PIOD, PIO_PERIPH_C, PIO_DEFAULT}
+
+#define PIN_SDRAM_CAS     {0x00020000, PIOD, ID_PIOD, PIO_PERIPH_C, PIO_DEFAULT}
+#define PIN_SDRAM_RAS     {0x00010000, PIOD, ID_PIOD, PIO_PERIPH_C, PIO_DEFAULT}
+#define PIN_SDRAM_SDCKE   {0x00004000, PIOD, ID_PIOD, PIO_PERIPH_C, PIO_DEFAULT}
+#define PIN_SDRAM_SDCK    {0x00800000, PIOD, ID_PIOD, PIO_PERIPH_C, PIO_DEFAULT}
+#define PIN_SDRAM_SDSC    {0x00008000, PIOC, ID_PIOC, PIO_PERIPH_A, PIO_DEFAULT}
+#define PIN_SDRAM_NBS0    {0x00040000, PIOC, ID_PIOC, PIO_PERIPH_A, PIO_DEFAULT}
+#define PIN_SDRAM_NBS1    {0x00008000, PIOD, ID_PIOD, PIO_PERIPH_C, PIO_DEFAULT}
+#define PIN_SDRAM_SDWE    {0x20000000, PIOD, ID_PIOD, PIO_PERIPH_C, PIO_DEFAULT}
+#define PIN_SDRAM_BA0     {0x00100000, PIOA, ID_PIOA, PIO_PERIPH_C, PIO_DEFAULT}
+
+#define BOARD_SDRAM_PINS PIN_SDRAM_D0_7, PIN_SDRAM_D8_13 , PIN_SDRAM_D14_15,\
+	PIN_SDRAM_A0_9, PIN_SDRAM_SDA10, PIN_SDRAM_BA0, \
+	PIN_SDRAM_CAS, PIN_SDRAM_RAS, PIN_SDRAM_SDCKE,PIN_SDRAM_SDCK,\
+	PIN_SDRAM_SDSC,PIN_SDRAM_NBS0 ,PIN_SDRAM_NBS1,PIN_SDRAM_SDWE
+
+
+/** List of all MCI pin definitions. */
+
+/** MCI0 Card detect pin definition. (PE5) */
+#define BOARD_MCI_PIN_CD  {PIO_PD18, PIOD, ID_PIOD, PIO_INPUT, PIO_PULLUP}
+/** MCI0 Clock . */
+#define BOARD_MCI_PIN_CK  {PIO_PA25D_MCCK, PIOA, ID_PIOA, PIO_PERIPH_D, PIO_DEFAULT}
+
+/** MCI0 Solt A IO pins definition. (PC4-PC13) */
+#define BOARD_MCI_PINS_SLOTA \
+	{(PIO_PA30C_MCDA0 | PIO_PA31C_MCDA1 | PIO_PA26C_MCDA2 | PIO_PA27C_MCDA3 | PIO_PA28C_MCCDA),\
+		PIOA, ID_PIOA, PIO_PERIPH_C, PIO_DEFAULT}
+
+/** MCI pins that shall be configured to access the SD card. */
+#define BOARD_SD_PINS     {BOARD_MCI_PINS_SLOTA, BOARD_MCI_PIN_CK}
+/** MCI Card Detect pin. */
+#define BOARD_SD_PIN_CD   BOARD_MCI_PIN_CD
+/** Total number of MCI interface */
+#define BOARD_NUM_MCI     1
+
+/** List of all SQPI pin definitions. */
+#define PINS_QSPI_IO   \
+	{(PIO_PA11A_QCS | PIO_PA13A_QIO0 | PIO_PA12A_QIO1 | PIO_PA17A_QIO2 | PIO_PA14A_QSCK),\
+		PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
+#define PINS_QSPI_IO3   {PIO_PD31A_QIO3, PIOD, ID_PIOD, PIO_PERIPH_A, PIO_DEFAULT}
+#define PINS_QSPI      {PINS_QSPI_IO, PINS_QSPI_IO3}
+
+/*----------------------------------------------------------------------------*/
+/**
+ * \page samv7_Xplained_ultra_chipdef "SAM V71 Xplained Ultra - Individual chip definition"
+ * This page lists the definitions related to different chip's definition
+ *
+ * \section USART
+ * - \ref BOARD_PIN_USART_RXD
+ * - \ref BOARD_PIN_USART_TXD
+ * - \ref BOARD_PIN_USART_CTS
+ * - \ref BOARD_PIN_USART_RTS
+ * - \ref BOARD_PIN_USART_EN
+ * - \ref BOARD_USART_BASE
+ * - \ref BOARD_ID_USART
+ */
+
+/** Rtc */
+#define BOARD_RTC_ID   ID_RTC
+
+/** TWI ID for QTouch application to use */
+#define BOARD_ID_TWI_AT42    ID_TWI0
+/** TWI Base for QTouch application to use */
+#define BOARD_BASE_TWI_AT42  TWI0
+/** TWI pins for QTouch application to use */
+#define BOARD_PINS_TWI_AT42  PINS_TWI0
+
+/** USART RX pin for application */
+#define BOARD_PIN_USART_RXD  PIN_USART1_RXD
+/** USART TX pin for application */
+#define BOARD_PIN_USART_TXD  PIN_USART1_TXD
+/** USART CTS pin for application */
+#define BOARD_PIN_USART_CTS  PIN_USART1_CTS
+/** USART RTS pin for application */
+#define BOARD_PIN_USART_RTS  PIN_USART1_RTS
+/** USART ENABLE pin for application */
+#define BOARD_PIN_USART_EN  PIN_USART1_EN
+/** USART Base for application */
+#define BOARD_USART_BASE  USART1
+/** USART ID for application */
+#define BOARD_ID_USART   ID_USART1
+
+
+
+/*----------------------------------------------------------------------------*/
+/*
+* USB pins
+*/
+#define PINS_VBUS_EN   {PIO_PC16, PIOC, ID_PIOC, PIO_OUTPUT_1, PIO_DEFAULT}
+#endif /* #ifndef _BOARD_V71_XULT_H_ */
+
Index: bsps/arm/atsam/contrib/libraries/libboard/include/bmp.h
===================================================================
--- bsps/arm/atsam/contrib/libraries/libboard/include/bmp.h	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libboard/include/bmp.h	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,119 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+/**
+ *  \file
+ *  \section Purpose
+ *
+ *  Utility for BMP
+ *
+ */
+
+#ifndef BMP_H
+#define BMP_H
+
+/**  BMP magic number ('BM'). */
+#define BMP_TYPE       0x4D42
+
+/**  headerSize must be set to 40 */
+#define BITMAPINFOHEADER   40
+
+/*------------------------------------------------------------------------------
+ *         Exported types
+ *------------------------------------------------------------------------------*/
+
+#pragma pack(1)
+
+/** BMP (Windows) Header Format */
+typedef struct _BMPHeader {
+	/*  signature, must be 4D42 hex */
+	uint16_t type;
+	/*  size of BMP file in bytes (unreliable) */
+	uint32_t fileSize;
+	/*  reserved, must be zero */
+	uint16_t reserved1;
+	/*  reserved, must be zero */
+	uint16_t reserved2;
+	/*  offset to start of image data in bytes */
+	uint32_t offset;
+	/*  size of BITMAPINFOHEADER structure, must be 40 */
+	uint32_t headerSize;
+	/*  image width in pixels */
+	uint32_t width;
+	/*  image height in pixels */
+	uint32_t height;
+	/*  number of planes in the image, must be 1 */
+	uint16_t planes;
+	/*  number of bits per pixel (1, 4, 8, 16, 24, 32) */
+	uint16_t bits;
+	/*  compression type (0=none, 1=RLE-8, 2=RLE-4) */
+	uint32_t compression;
+	/*  size of image data in bytes (including padding) */
+	uint32_t imageSize;
+	/*  horizontal resolution in pixels per meter (unreliable) */
+	uint32_t xresolution;
+	/*  vertical resolution in pixels per meter (unreliable) */
+	uint32_t yresolution;
+	/*  number of colors in image, or zero */
+	uint32_t ncolours;
+	/*  number of important colors, or zero */
+	uint32_t importantcolours;
+} BMPHeader;
+
+#pragma pack()
+
+/*------------------------------------------------------------------------------
+ *         Exported functions
+ *------------------------------------------------------------------------------*/
+extern uint8_t BMP_IsValid(void *file);
+extern uint32_t BMP_GetFileSize(void *file);
+
+extern uint8_t BMP_Decode(
+	void *file,
+	uint8_t *buffer,
+	uint32_t width,
+	uint32_t height,
+	uint8_t bpp);
+
+extern void WriteBMPheader(
+	uint32_t *pAddressHeader,
+	uint32_t  bmpHSize,
+	uint32_t  bmpVSize,
+	uint8_t nbByte_Pixels);
+
+extern void BMP_displayHeader(uint32_t *pAddressHeader);
+extern void RGB565toBGR555(
+	uint8_t *fileSource,
+	uint8_t *fileDestination,
+	uint32_t width,
+	uint32_t height,
+	uint8_t bpp);
+
+#endif //#ifndef BMP_H
+
Index: bsps/arm/atsam/contrib/libraries/libboard/include/board_lowlevel.h
===================================================================
--- bsps/arm/atsam/contrib/libraries/libboard/include/board_lowlevel.h	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libboard/include/board_lowlevel.h	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,47 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+/**
+ * \file
+ *
+ * Interface for the low-level initialization function.
+ *
+ */
+
+#ifndef BOARD_LOWLEVEL_H
+#define BOARD_LOWLEVEL_H
+
+/*----------------------------------------------------------------------------
+ *        Exported functions
+ *----------------------------------------------------------------------------*/
+extern void LowLevelInit(void);
+extern void _SetupMemoryRegion(void);
+
+#endif /* BOARD_LOWLEVEL_H */
+
Index: bsps/arm/atsam/contrib/libraries/libboard/include/board_memories.h
===================================================================
--- bsps/arm/atsam/contrib/libraries/libboard/include/board_memories.h	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libboard/include/board_memories.h	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,52 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+/**
+ * \file
+ *
+ * Interface for memories configuration on board.
+ *
+ */
+
+#ifndef BOARD_MEMORIES_H
+#define BOARD_MEMORIES_H
+
+/*----------------------------------------------------------------------------
+ *        Exported functions
+ *----------------------------------------------------------------------------*/
+
+#ifndef __rtems__
+extern void BOARD_ConfigureSdram(void);
+#else /* __rtems__ */
+extern void BOARD_ConfigureSdram(void) ATSAM_START_SRAM_SECTION;
+#endif /* __rtems__ */
+extern uint32_t BOARD_SdramValidation(uint32_t baseAddr, uint32_t size);
+
+#endif /* #ifndef BOARD_MEMORIES_H */
+
Index: bsps/arm/atsam/contrib/libraries/libboard/include/cs2100.h
===================================================================
--- bsps/arm/atsam/contrib/libraries/libboard/include/cs2100.h	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libboard/include/cs2100.h	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,93 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+/**
+  * \file
+  *
+  * Implementation WM8904 driver.
+  *
+  */
+
+#ifndef CS2100_H
+#define CS2100_H
+
+#include "board.h"
+
+/*----------------------------------------------------------------------------
+ *         Definitions
+ *----------------------------------------------------------------------------*/
+
+#define CS2100_SLAVE_ADDRESS                    0x4E
+
+/** ID and Rev register*/
+#define CS2100_REG_ID                           0x01
+
+/** VMID control 0 register*/
+#define CS2100_REG_CTRL                         0x02
+
+/** MIC Bias control 0 register*/
+#define CS2100_REG_DEV_CFG1                     0x03
+
+/** Bias control 1 register*/
+#define CS2100_REG_CFG                          0x05
+
+/** Power management control 0 register*/
+#define CS2100_REG_32_BIT_RATIO_1               0x06
+/** Power management control 0 register*/
+#define CS2100_REG_32_BIT_RATIO_2               0x07
+/** Power management control 0 register*/
+#define CS2100_REG_32_BIT_RATIO_3               0x08
+/** Power management control 0 register*/
+#define CS2100_REG_32_BIT_RATIO_4               0x09
+/** Power management control 2 register*/
+#define CS2100_REG_FUNC_CFG1                    0x16
+/** Power management control 3 register*/
+#define CS2100_REG_FUNC_CFG2                    0x17
+/** Power management control 3 register*/
+#define CS2100_REG_FUNC_CFG3                    0x1E
+
+/*----------------------------------------------------------------------------
+ *         Exported functions
+ *----------------------------------------------------------------------------*/
+
+extern uint16_t CS2100_Read(
+	Twid *pTwid,
+	uint32_t device,
+	uint32_t regAddr);
+
+extern void CS2100_Write(
+	Twid *pTwid,
+	uint32_t device,
+	uint32_t regAddr,
+	uint16_t data);
+
+extern uint8_t CS2100_Init(Twid *pTwid, uint32_t device, uint32_t PCK);
+#endif // CS2100_H
+
+
Index: bsps/arm/atsam/contrib/libraries/libboard/include/dbg_console.h
===================================================================
--- bsps/arm/atsam/contrib/libraries/libboard/include/dbg_console.h	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libboard/include/dbg_console.h	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,55 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+/**
+  *  \file
+  *
+  *  Include function prototype for the UART console.
+  */
+
+#ifndef _DBG_CONSOLE_
+#define _DBG_CONSOLE_
+
+#include <stdint.h>
+
+extern void DBG_Configure(uint32_t dwBaudrate, uint32_t dwMasterClock);
+extern void DBG_PutChar(uint8_t uc);
+extern uint32_t DBG_GetChar(void);
+extern uint32_t DBG_IsRxReady(void);
+
+
+extern void DBG_DumpFrame(uint8_t *pucFrame, uint32_t dwSize);
+extern void DBG_DumpMemory(uint8_t *pucBuffer, uint32_t dwSize,
+							uint32_t dwAddress);
+extern uint32_t DBG_GetInteger(int32_t *pdwValue);
+extern uint32_t DBG_GetIntegerMinMax(int32_t *pdwValue, int32_t dwMin,
+									  int32_t dwMax);
+extern uint32_t DBG_GetHexa32(uint32_t *pdwValue);
+
+#endif /* _DBG_CONSOLE_ */
Index: bsps/arm/atsam/contrib/libraries/libboard/include/frame_buffer.h
===================================================================
--- bsps/arm/atsam/contrib/libraries/libboard/include/frame_buffer.h	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libboard/include/frame_buffer.h	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,83 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+/**
+ * \file
+ *
+ * Interface of frame buffer driver.
+ *
+ */
+
+#ifndef _FRAME_BUFFER_
+#define _FRAME_BUFFER_
+
+/*----------------------------------------------------------------------------
+ *        Exported functions
+ *----------------------------------------------------------------------------*/
+
+extern void FB_SetFrameBuffer(
+	LcdColor_t *pBuffer,
+	uint8_t ucWidth,
+	uint8_t ucHeight);
+
+extern void FB_SetColor(uint32_t color);
+
+extern uint32_t FB_DrawLine (
+	uint32_t dwX1,
+	uint32_t dwY1,
+	uint32_t dwX2,
+	uint32_t dwY2);
+
+extern uint32_t FB_DrawPixel(uint32_t x, uint32_t y);
+extern uint32_t FB_DrawCircle(uint32_t x, uint32_t y, uint32_t r);
+extern uint32_t FB_DrawFilledCircle(
+	uint32_t dwX,
+	uint32_t dwY,
+	uint32_t dwRadius);
+
+extern uint32_t FB_DrawRectangle(
+	uint32_t dwX1,
+	uint32_t dwY1,
+	uint32_t dwX2,
+	uint32_t dwY2);
+
+extern uint32_t FB_DrawFilledRectangle(
+	uint32_t dwX1,
+	uint32_t dwY1,
+	uint32_t dwX2,
+	uint32_t dwY2);
+
+extern uint32_t FB_DrawPicture(
+	uint32_t dwX1,
+	uint32_t dwY1,
+	uint32_t dwX2,
+	uint32_t dwY2,
+	const void *pBuffer);
+
+#endif /* #ifndef _FRAME_BUFFER_ */
Index: bsps/arm/atsam/contrib/libraries/libboard/include/gmacb_phy.h
===================================================================
--- bsps/arm/atsam/contrib/libraries/libboard/include/gmacb_phy.h	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libboard/include/gmacb_phy.h	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,114 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+/** \file */
+
+/** \addtogroup gmacb_module Ethernet GMACB Driver
+ *@{
+ *  Implement GEMAC PHY driver, that initialize the PHY to prepare for
+ *  Ethernet transfer.
+ *
+ *  \section Usage
+ *  -# EMAC related pins and Driver should be initialized at first.
+ *  -# Initialize GMACB Driver instance by invoking GMACB_Init().
+ *  -# Initialize PHY connected via GMACB_InitPhy(), PHY address is
+ *     automatically adjusted by attempt to read.
+ *  -# Perform PHY auto negotiate through GMACB_AutoNegotiate(), so
+ *     connection established.
+ *
+ *
+ *  Related files:\n
+ *  \ref gmacb.h\n
+ *  \ref gmacb.c\n
+ *  \ref gmii.h.\n
+ *
+ */
+/**@}*/
+
+#ifndef _GMACB_PHY_H
+#define _GMACB_PHY_H
+
+
+/*---------------------------------------------------------------------------
+ *         Headers
+ *---------------------------------------------------------------------------*/
+
+#include "board.h"
+
+/*---------------------------------------------------------------------------
+ *         Definitions
+ *---------------------------------------------------------------------------*/
+
+/** The reset length setting for external reset configuration */
+#define GMACB_RESET_LENGTH         0xD
+
+/*---------------------------------------------------------------------------
+ *         Types
+ *---------------------------------------------------------------------------*/
+
+
+/** The DM9161 instance */
+typedef struct _GMacb {
+	/**< Driver */
+	sGmacd *pGmacd;
+	/** The retry & timeout settings */
+	uint32_t retryMax;
+	/** PHY address (pre-defined by pins on reset) */
+	uint8_t phyAddress;
+} GMacb;
+
+/*---------------------------------------------------------------------------
+ *         Exported functions
+ *---------------------------------------------------------------------------*/
+extern void GMACB_SetupTimeout(GMacb *pMacb, uint32_t toMax);
+
+extern void GMACB_Init(GMacb *pMacb, sGmacd *pGmacd, uint8_t phyAddress);
+
+extern uint8_t GMACB_InitPhy(
+	GMacb *pMacb,
+	uint32_t mck,
+	const Pin *pResetPins,
+	uint32_t nbResetPins,
+	const Pin *pEmacPins,
+	uint32_t nbEmacPins);
+
+extern uint8_t GMACB_AutoNegotiate(GMacb *pMacb);
+
+extern uint8_t GMACB_GetLinkSpeed(GMacb *pMacb, uint8_t applySettings);
+
+extern uint8_t GMACB_Send(GMacb *pMacb, void *pBuffer, uint32_t size);
+
+extern uint32_t GMACB_Poll(GMacb *pMacb, uint8_t *pBuffer, uint32_t size);
+
+extern void GMACB_DumpRegisters(GMacb *pMacb);
+
+extern uint8_t GMACB_ResetPhy(GMacb *pMacb);
+
+#endif // #ifndef _GMACB_H
+
Index: bsps/arm/atsam/contrib/libraries/libboard/include/gmii.h
===================================================================
--- bsps/arm/atsam/contrib/libraries/libboard/include/gmii.h	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libboard/include/gmii.h	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,116 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+#ifndef _GMII_DEFINE_H
+#define _GMII_DEFINE_H
+
+
+/*---------------------------------------------------------------------------
+ *         Definitions
+ *---------------------------------------------------------------------------*/
+
+//IEEE defined Registers
+#define GMII_BMCR        0x0   // Basic Mode Control Register
+#define GMII_BMSR        0x1   // Basic Mode Status Register
+#define GMII_PHYID1R     0x2   // PHY Identifier Register 1
+#define GMII_PHYID2R     0x3   // PHY Identifier Register 2
+#define GMII_ANAR        0x4   // Auto_Negotiation Advertisement Register
+#define GMII_ANLPAR      0x5   // Auto_negotiation Link Partner Ability Register
+#define GMII_ANER        0x6   // Auto-negotiation Expansion Register
+#define GMII_ANNPR       0x7   // Auto-negotiation Next Page Register
+#define GMII_ANLPNPAR    0x8   // Auto_negotiation Link Partner Next Page Ability Register
+#define GMII_AFEC0R      0x11  // AFE Control 0 Register
+#define GMII_AFEC3R      0x14  // AFE Control 3 Register
+#define GMII_RXERCR      0x15  // RXER Counter Register
+#define GMII_OMSSR       0x17  // Operation Mode Strap Status Register
+#define GMII_ECR         0x18  // Expanded Control Register
+#define GMII_ICSR        0x1B  // Interrupt Control/Status Register
+#define GMII_FC          0x1C  // Function Control
+#define GMII_LCSR        0x1D  // LinkMD® Control/Status Register
+#define GMII_PC1R        0x1E  // PHY Control 1 Register
+#define GMII_PC2R        0x1F  // PHY Control 2 Register
+
+// PHY ID Identifier Register
+#define GMII_LSB_MASK           0x0U
+// definitions: MII_PHYID1
+#define GMII_OUI_MSB            0x0022
+// definitions: MII_PHYID2
+#define GMII_OUI_LSB            0x1572          // KSZ8061 PHY Id2
+
+// Basic Mode Control Register (BMCR)
+// Bit definitions: MII_BMCR
+#define GMII_RESET             (1 << 15) // 1= Software Reset; 0=Normal Operation
+#define GMII_LOOPBACK          (1 << 14) // 1=loopback Enabled; 0=Normal Operation
+#define GMII_SPEED_SELECT_LSB  (1 << 13) // 1,0=1000Mbps 0,1=100Mbps; 0,0=10Mbps
+#define GMII_AUTONEG           (1 << 12) // Auto-negotiation Enable
+#define GMII_POWER_DOWN        (1 << 11) // 1=Power down 0=Normal operation
+#define GMII_ISOLATE           (1 << 10) // 1 = Isolates 0 = Normal operation
+#define GMII_RESTART_AUTONEG   (1 << 9)  // 1 = Restart auto-negotiation 0 = Normal operation
+#define GMII_DUPLEX_MODE       (1 << 8)  // 1 = Full duplex operation 0 = Normal operation
+//      Reserved                7        // Read as 0, ignore on write
+#define GMII_SPEED_SELECT_MSB  (1 << 6)  // 
+//      Reserved                5 to 0   // Read as 0, ignore on write
+
+
+// Basic Mode Status Register (BMSR)
+// Bit definitions: MII_BMSR
+#define GMII_100BASE_T4        (1 << 15) // 100BASE-T4 Capable
+#define GMII_100BASE_TX_FD     (1 << 14) // 100BASE-TX Full Duplex Capable
+#define GMII_100BASE_T4_HD     (1 << 13) // 100BASE-TX Half Duplex Capable
+#define GMII_10BASE_T_FD       (1 << 12) // 10BASE-T Full Duplex Capable
+#define GMII_10BASE_T_HD       (1 << 11) // 10BASE-T Half Duplex Capable
+//      Reserved                10 to 9  // Read as 0, ignore on write
+#define GMII_EXTEND_STATUS     (1 << 8)  // 1 = Extend Status Information In Reg 15
+//      Reserved                7
+#define GMII_MF_PREAMB_SUPPR   (1 << 6)  // MII Frame Preamble Suppression
+#define GMII_AUTONEG_COMP      (1 << 5)  // Auto-negotiation Complete
+#define GMII_REMOTE_FAULT      (1 << 4)  // Remote Fault
+#define GMII_AUTONEG_ABILITY   (1 << 3)  // Auto Configuration Ability
+#define GMII_LINK_STATUS       (1 << 2)  // Link Status
+#define GMII_JABBER_DETECT     (1 << 1)  // Jabber Detect
+#define GMII_EXTEND_CAPAB      (1 << 0)  // Extended Capability
+
+// Auto-negotiation Advertisement Register (ANAR)
+// Auto-negotiation Link Partner Ability Register (ANLPAR)
+// Bit definitions: MII_ANAR, MII_ANLPAR
+#define GMII_NP               (1 << 15) // Next page Indication
+//      Reserved               7
+#define GMII_RF               (1 << 13) // Remote Fault
+//      Reserved               12       // Write as 0, ignore on read
+#define GMII_PAUSE_MASK       (3 << 11) // 0,0 = No Pause 1,0 = Asymmetric Pause(link partner)
+										// 0,1 = Symmetric Pause 1,1 = Symmetric&Asymmetric Pause(local device)
+#define GMII_T4               (1 << 9)  // 100BASE-T4 Support
+#define GMII_TX_FDX           (1 << 8)  // 100BASE-TX Full Duplex Support
+#define GMII_TX_HDX           (1 << 7)  // 100BASE-TX Support
+#define GMII_10_FDX           (1 << 6)  // 10BASE-T Full Duplex Support
+#define GMII_10_HDX           (1 << 5)  // 10BASE-T Support
+//      Selector                 4 to 0   // Protocol Selection Bits
+#define GMII_AN_IEEE_802_3      0x00001
+
+#endif // #ifndef _MII_DEFINE_H
Index: bsps/arm/atsam/contrib/libraries/libboard/include/ili9488.h
===================================================================
--- bsps/arm/atsam/contrib/libraries/libboard/include/ili9488.h	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libboard/include/ili9488.h	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,106 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+/**
+ * \file
+ *
+ * Interface of ILI9488 driver.
+ *
+ */
+
+#ifndef _ILI9488_H_
+#define _ILI9488_H_
+
+/*----------------------------------------------------------------------------
+ *        Headers
+ *----------------------------------------------------------------------------*/
+
+#include "board.h"
+
+#include <stdint.h>
+
+
+/*----------------------------------------------------------------------------
+ *        Definitions
+ *----------------------------------------------------------------------------*/
+
+#define ILI9488_SPIMODE        0
+#define ILI9488_EBIMODE        1
+
+/* ILI9325 ID code */
+#define ILI9488_DEVICE_CODE    0x9488
+
+#define ILI9488_LCD_WIDTH       320
+#define ILI9488_LCD_HEIGHT      480
+#define ILI9488_SELF_TEST_OK    0xC0
+
+/* EBI chip select for LCD */
+#define SMC_EBI_LCD_CS          3
+
+/*----------------------------------------------------------------------------
+ *        Types
+ *----------------------------------------------------------------------------*/
+typedef enum {
+	AccessInst = 0,
+	AccessRead,
+	AccessWrite
+} AccessIli_t;
+
+typedef union _union_type {
+	uint32_t value;
+	struct {
+		uint8_t byte_8;
+		uint8_t byte_l6;
+		uint8_t byte_24;
+		uint8_t byte_32;
+	} byte;
+	struct {
+		uint16_t half_word_l;
+		uint16_t half_word_h;
+	} half_word;
+} union_type;
+typedef volatile uint8_t REG8;
+
+typedef uint32_t LcdColor_t;
+
+/*----------------------------------------------------------------------------
+ *        Marcos
+ *----------------------------------------------------------------------------*/
+/* Pixel cache used to speed up communication */
+#define LCD_DATA_CACHE_SIZE         BOARD_LCD_WIDTH
+
+/*----------------------------------------------------------------------------
+ *        Function Marcos
+ *----------------------------------------------------------------------------*/
+#define get_0b_to_8b(x)             (((union_type*)&(x))->byte.byte_8)
+#define get_8b_to_16b(x)            (((union_type*)&(x))->byte.byte_l6)
+#define get_16b_to_24b(x)           (((union_type*)&(x))->byte.byte_24)
+#define get_24b_to_32b(x)           (((union_type*)&(x))->byte.byte_32)
+
+#endif /* #ifndef ILI9488 */
Index: bsps/arm/atsam/contrib/libraries/libboard/include/ili9488_dma.h
===================================================================
--- bsps/arm/atsam/contrib/libraries/libboard/include/ili9488_dma.h	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libboard/include/ili9488_dma.h	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,92 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+/**
+ * \file
+ *
+ * Interface of ILI9488 driver.
+ *
+ */
+
+#ifndef _ILI9488_DMA_H_
+#define _ILI9488_DMA_H_
+
+/*----------------------------------------------------------------------------
+ *        Headers
+ *----------------------------------------------------------------------------*/
+
+#include "board.h"
+#include <stdint.h>
+
+/*------------------------------------------------------------------------------
+ *        Definitions
+ *----------------------------------------------------------------------------*/
+/** An unspecified error has occurred.*/
+#define ILI9488_ERROR_DMA_ALLOCATE_CHANNEL          1
+#define ILI9488_ERROR_DMA_CONFIGURE                 2
+#define ILI9488_ERROR_DMA_TRANSFER                  3
+#define ILI9488_ERROR_DMA_SIZE                      4
+
+#define ILI9488_SPI                                 SPI0
+#define ILI9488_SPI_ID                              ID_SPI0
+
+/* EBI BASE ADDRESS for SMC LCD */
+#define ILI9488_BASE_ADDRESS        0x63000000
+
+/*------------------------------------------------------------------------------
+ *        Types
+ *----------------------------------------------------------------------------*/
+
+typedef struct _ILI9488_dma {
+	/** Pointer to DMA driver */
+	sXdmad              *xdmaD;
+	/** ili9488 Tx channel */
+	uint32_t            ili9488DmaTxChannel;
+	/** ili9488 Rx channel */
+	uint32_t            ili9488DmaRxChannel;
+	/** ili9488 Tx/Rx configure descriptor */
+	sXdmadCfg           xdmadRxCfg, xdmadTxCfg;
+	/** ili9488 dma interrupt */
+	uint32_t            xdmaInt;
+	/** Pointer to SPI Hardware registers */
+	Spi                *pSpiHw;
+	/** SPI Id as defined in the product datasheet */
+	uint8_t             spiId;
+} sIli9488Dma;
+
+typedef struct _ILI9488_ctl {
+	/** ili9488 Command/Data mode */
+	volatile uint32_t       cmdOrDataFlag;
+	/** ili9488 Rx done */
+	volatile uint32_t       rxDoneFlag;
+	/** ili9488 Tx done */
+	volatile uint32_t       txDoneFlag;
+} sIli9488DmaCtl;
+
+#endif /* #ifndef ILI9488_DMA */
Index: bsps/arm/atsam/contrib/libraries/libboard/include/ili9488_ebi.h
===================================================================
--- bsps/arm/atsam/contrib/libraries/libboard/include/ili9488_ebi.h	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libboard/include/ili9488_ebi.h	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,63 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+/**
+ * \file
+ *
+ * Interface of ILI9488 driver.
+ *
+ */
+
+#ifndef _ILI9488_EBI_H_
+#define _ILI9488_EBI_H_
+
+/*----------------------------------------------------------------------------
+ *        Headers
+ *----------------------------------------------------------------------------*/
+
+#include "board.h"
+
+#include <stdint.h>
+
+/*----------------------------------------------------------------------------
+ *        Exported functions
+ *----------------------------------------------------------------------------*/
+extern uint32_t ILI9488_EbiReadChipId (void);
+extern uint32_t ILI9488_EbiInitialize(sXdmad *dmad);
+extern void ILI9488_EbiSetPixelFormat(uint16_t format);
+extern void ILI9488_EbiSetCursor(uint16_t x, uint16_t y);
+extern void ILI9488_EbiSetWindow(uint16_t dwX, uint16_t dwY,
+		uint16_t dwWidth, uint16_t dwHeight);
+extern void ILI9488_EbiSetFullWindow(void);
+extern void ILI9488_EbiOn(void);
+extern void ILI9488_EbiOff(void);
+extern void ILI9488_EbiSetDisplayLandscape(uint8_t dwRGB,
+		uint8_t LandscaprMode);
+
+#endif /* #ifndef ILI9488_EBI */
Index: bsps/arm/atsam/contrib/libraries/libboard/include/ili9488_ebi_dma.h
===================================================================
--- bsps/arm/atsam/contrib/libraries/libboard/include/ili9488_ebi_dma.h	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libboard/include/ili9488_ebi_dma.h	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,55 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+/**
+ * \file
+ *
+ * Interface of ILI9488 driver.
+ *
+ */
+
+#ifndef _ILI9488_EBI_DMA_H_
+#define _ILI9488_EBI_DMA_H_
+
+/*----------------------------------------------------------------------------
+ *        Headers
+ *----------------------------------------------------------------------------*/
+
+#include "board.h"
+#include <stdint.h>
+
+/*----------------------------------------------------------------------------
+ *        Exported functions
+ *----------------------------------------------------------------------------*/
+extern uint8_t ILI9488_EbiInitializeWithDma(sXdmad *dmad);
+extern uint8_t ILI9488_EbiDmaTxTransfer(uint16_t *pTxBuffer, uint32_t wTxSize);
+extern uint8_t ILI9488_EbiDmaRxTransfer(uint32_t *pRxBuffer, uint32_t wRxSize);
+extern uint8_t ILI9488_EbiSendCommand(uint16_t Instr, uint16_t *pTxData,
+		uint32_t *pRxData, AccessIli_t ReadWrite, uint32_t size);
+#endif /* #ifndef ILI9488_EBI_DMA */
Index: bsps/arm/atsam/contrib/libraries/libboard/include/ili9488_reg.h
===================================================================
--- bsps/arm/atsam/contrib/libraries/libboard/include/ili9488_reg.h	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libboard/include/ili9488_reg.h	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,131 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+#ifndef ILI9488_REG_H_INCLUDED
+#define ILI9488_REG_H_INCLUDED
+
+/* Level 1 Commands (from the display Datasheet) */
+#define ILI9488_CMD_NOP                             0x00
+#define ILI9488_CMD_SOFTWARE_RESET                  0x01
+#define ILI9488_CMD_READ_DISP_ID                    0x04
+#define ILI9488_CMD_READ_ERROR_DSI                  0x05
+#define ILI9488_CMD_READ_DISP_STATUS                0x09
+#define ILI9488_CMD_READ_DISP_POWER_MODE            0x0A
+#define ILI9488_CMD_READ_DISP_MADCTRL               0x0B
+#define ILI9488_CMD_READ_DISP_PIXEL_FORMAT          0x0C
+#define ILI9488_CMD_READ_DISP_IMAGE_MODE            0x0D
+#define ILI9488_CMD_READ_DISP_SIGNAL_MODE           0x0E
+#define ILI9488_CMD_READ_DISP_SELF_DIAGNOSTIC       0x0F
+#define ILI9488_CMD_ENTER_SLEEP_MODE                0x10
+#define ILI9488_CMD_SLEEP_OUT                       0x11
+#define ILI9488_CMD_PARTIAL_MODE_ON                 0x12
+#define ILI9488_CMD_NORMAL_DISP_MODE_ON             0x13
+#define ILI9488_CMD_DISP_INVERSION_OFF              0x20
+#define ILI9488_CMD_DISP_INVERSION_ON               0x21
+#define ILI9488_CMD_PIXEL_OFF                       0x22
+#define ILI9488_CMD_PIXEL_ON                        0x23
+#define ILI9488_CMD_DISPLAY_OFF                     0x28
+#define ILI9488_CMD_DISPLAY_ON                      0x29
+#define ILI9488_CMD_COLUMN_ADDRESS_SET              0x2A
+#define ILI9488_CMD_PAGE_ADDRESS_SET                0x2B
+#define ILI9488_CMD_MEMORY_WRITE                    0x2C
+#define ILI9488_CMD_MEMORY_READ                     0x2E
+#define ILI9488_CMD_PARTIAL_AREA                    0x30
+#define ILI9488_CMD_VERT_SCROLL_DEFINITION          0x33
+#define ILI9488_CMD_TEARING_EFFECT_LINE_OFF         0x34
+#define ILI9488_CMD_TEARING_EFFECT_LINE_ON          0x35
+#define ILI9488_CMD_MEMORY_ACCESS_CONTROL           0x36
+#define ILI9488_CMD_VERT_SCROLL_START_ADDRESS       0x37
+#define ILI9488_CMD_IDLE_MODE_OFF                   0x38
+#define ILI9488_CMD_IDLE_MODE_ON                    0x39
+#define ILI9488_CMD_COLMOD_PIXEL_FORMAT_SET         0x3A
+#define ILI9488_CMD_WRITE_MEMORY_CONTINUE           0x3C
+#define ILI9488_CMD_READ_MEMORY_CONTINUE            0x3E
+#define ILI9488_CMD_SET_TEAR_SCANLINE               0x44
+#define ILI9488_CMD_GET_SCANLINE                    0x45
+#define ILI9488_CMD_WRITE_DISPLAY_BRIGHTNESS        0x51
+#define ILI9488_CMD_READ_DISPLAY_BRIGHTNESS         0x52
+#define ILI9488_CMD_WRITE_CTRL_DISPLAY              0x53
+#define ILI9488_CMD_READ_CTRL_DISPLAY               0x54
+#define ILI9488_CMD_WRITE_CONTENT_ADAPT_BRIGHTNESS  0x55
+#define ILI9488_CMD_READ_CONTENT_ADAPT_BRIGHTNESS   0x56
+#define ILI9488_CMD_WRITE_MIN_CAB_LEVEL             0x5E
+#define ILI9488_CMD_READ_MIN_CAB_LEVEL              0x5F
+#define ILI9488_CMD_READ_ABC_SELF_DIAG_RES          0x68
+#define ILI9488_CMD_READ_ID1                        0xDA
+#define ILI9488_CMD_READ_ID2                        0xDB
+#define ILI9488_CMD_READ_ID3                        0xDC
+
+/* Level 2 Commands (from the display Datasheet) */
+#define ILI9488_CMD_INTERFACE_MODE_CONTROL          0xB0
+#define ILI9488_CMD_FRAME_RATE_CONTROL_NORMAL       0xB1
+#define ILI9488_CMD_FRAME_RATE_CONTROL_IDLE_8COLOR  0xB2
+#define ILI9488_CMD_FRAME_RATE_CONTROL_PARTIAL      0xB3
+#define ILI9488_CMD_DISPLAY_INVERSION_CONTROL       0xB4
+#define ILI9488_CMD_BLANKING_PORCH_CONTROL          0xB5
+#define ILI9488_CMD_DISPLAY_FUNCTION_CONTROL        0xB6
+#define ILI9488_CMD_ENTRY_MODE_SET                  0xB7
+#define ILI9488_CMD_BACKLIGHT_CONTROL_1             0xB9
+#define ILI9488_CMD_BACKLIGHT_CONTROL_2             0xBA
+#define ILI9488_CMD_HS_LANES_CONTROL                0xBE
+#define ILI9488_CMD_POWER_CONTROL_1                 0xC0
+#define ILI9488_CMD_POWER_CONTROL_2                 0xC1
+#define ILI9488_CMD_POWER_CONTROL_NORMAL_3          0xC2
+#define ILI9488_CMD_POWER_CONTROL_IDEL_4            0xC3
+#define ILI9488_CMD_POWER_CONTROL_PARTIAL_5         0xC4
+#define ILI9488_CMD_VCOM_CONTROL_1                  0xC5
+#define ILI9488_CMD_CABC_CONTROL_1                  0xC6
+#define ILI9488_CMD_CABC_CONTROL_2                  0xC8
+#define ILI9488_CMD_CABC_CONTROL_3                  0xC9
+#define ILI9488_CMD_CABC_CONTROL_4                  0xCA
+#define ILI9488_CMD_CABC_CONTROL_5                  0xCB
+#define ILI9488_CMD_CABC_CONTROL_6                  0xCC
+#define ILI9488_CMD_CABC_CONTROL_7                  0xCD
+#define ILI9488_CMD_CABC_CONTROL_8                  0xCE
+#define ILI9488_CMD_CABC_CONTROL_9                  0xCF
+#define ILI9488_CMD_NVMEM_WRITE                     0xD0
+#define ILI9488_CMD_NVMEM_PROTECTION_KEY            0xD1
+#define ILI9488_CMD_NVMEM_STATUS_READ               0xD2
+#define ILI9488_CMD_READ_ID4                        0xD3
+#define ILI9488_CMD_ADJUST_CONTROL_1                0xD7
+#define ILI9488_CMD_READ_ID_VERSION                 0xD8
+#define ILI9488_CMD_POSITIVE_GAMMA_CORRECTION       0xE0
+#define ILI9488_CMD_NEGATIVE_GAMMA_CORRECTION       0xE1
+#define ILI9488_CMD_DIGITAL_GAMMA_CONTROL_1         0xE2
+#define ILI9488_CMD_DIGITAL_GAMMA_CONTROL_2         0xE3
+#define ILI9488_CMD_SET_IMAGE_FUNCTION              0xE9
+#define ILI9488_CMD_ADJUST_CONTROL_2                0xF2
+#define ILI9488_CMD_ADJUST_CONTROL_3                0xF7
+#define ILI9488_CMD_ADJUST_CONTROL_4                0xF8
+#define ILI9488_CMD_ADJUST_CONTROL_5                0xF9
+#define ILI9488_CMD_SPI_READ_SETTINGS               0xFB
+#define ILI9488_CMD_ADJUST_CONTROL_6                0xFC
+#define ILI9488_CMD_ADJUST_CONTROL_7                0xFF
+
+#endif /* ILI9488_REGS_H_INCLUDED */
Index: bsps/arm/atsam/contrib/libraries/libboard/include/ili9488_spi.h
===================================================================
--- bsps/arm/atsam/contrib/libraries/libboard/include/ili9488_spi.h	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libboard/include/ili9488_spi.h	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,69 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+/**
+ * \file
+ *
+ * Interface of ILI9488 driver.
+ *
+ */
+
+#ifndef _ILI9488_SPI_H_
+#define _ILI9488_SPI_H_
+
+/*------------------------------------------------------------------------------
+ *        Headers
+ *----------------------------------------------------------------------------*/
+
+#include "board.h"
+
+/*------------------------------------------------------------------------------
+ *        Exported functions
+ *----------------------------------------------------------------------------*/
+extern uint32_t ILI9488_SpiReadChipId (void);
+extern uint32_t ILI9488_SpiInitialize(sXdmad *dmad);
+extern void ILI9488_SpiSetPixelFormat(uint8_t format);
+extern void ILI9488_SpiNop(void);
+extern void ILI9488_SpiWriteMemory(const uint8_t *pBuf, uint32_t size);
+extern void ILI9488_SpiReadMemory(const uint8_t *pBuf, uint32_t size);
+extern void ILI9488_SpiSetCursor(uint16_t x, uint16_t y);
+extern void ILI9488_SpiSetWindow(
+	uint16_t dwX,
+	uint16_t dwY,
+	uint16_t dwWidth,
+	uint16_t dwHeight);
+
+extern void ILI9488_SpiSetFullWindow(void);
+extern void ILI9488_SpiOn(void);
+extern void ILI9488_SpiOff(void);
+extern void ILI9488_SpiSetDisplayLandscape(
+	uint8_t dwRGB, uint8_t LandscaprMode);
+extern void ILI9488_SetPixelColor(uint32_t x, uint32_t y, uint32_t color);
+
+#endif /* #ifndef ILI9488_SPI */
Index: bsps/arm/atsam/contrib/libraries/libboard/include/ili9488_spi_dma.h
===================================================================
--- bsps/arm/atsam/contrib/libraries/libboard/include/ili9488_spi_dma.h	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libboard/include/ili9488_spi_dma.h	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,56 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+/**
+ * \file
+ *
+ * Interface of ILI9488 DMA driver.
+ *
+ */
+
+#ifndef _ILI9488_SPI_DMA_H_
+#define _ILI9488_SPI_DMA_H_
+
+/*----------------------------------------------------------------------------
+ *        Headers
+ *----------------------------------------------------------------------------*/
+
+#include "board.h"
+#include <stdint.h>
+
+/*----------------------------------------------------------------------------
+ *        Exported functions
+ *----------------------------------------------------------------------------*/
+extern uint8_t ILI9488_SpiInitializeWithDma(sXdmad *dmad);
+extern uint8_t ILI9488_SpiDmaTxTransfer(uint8_t *pTxBuffer, uint32_t wTxSize);
+extern uint8_t ILI9488_SpiDmaRxTransfer(uint32_t *pRxBuffer, uint32_t wRxSize);
+extern uint8_t ILI9488_SpiSendCommand(uint8_t Instr, uint8_t *pTxData,
+		uint32_t *pRxData, AccessIli_t ReadWrite, uint32_t size);
+
+#endif /* #ifndef ILI9488_SPI_DMA */
Index: bsps/arm/atsam/contrib/libraries/libboard/include/image_sensor_inf.h
===================================================================
--- bsps/arm/atsam/contrib/libraries/libboard/include/image_sensor_inf.h	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libboard/include/image_sensor_inf.h	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,136 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+/*----------------------------------------------------------------------------
+ *        Headers
+ *----------------------------------------------------------------------------*/
+#include "board.h"
+
+
+/*---------------------------------------------------------------------------
+ *         Definition
+ *---------------------------------------------------------------------------*/
+#define SENDOR_SUPPORTED_OUTPUTS 7
+
+/** terminating list entry for register in configuration file */
+#define SENSOR_REG_TERM         0xFF
+/** terminating list entry for value in configuration file */
+#define SENSOR_VAL_TERM         0xFF
+
+/*----------------------------------------------------------------------------
+ *        Types
+ *----------------------------------------------------------------------------*/
+
+/** Sensor type */
+typedef enum _sensorType {
+	SENSOR_COMS = 0,
+	SENSOR_CCD
+} sensorType_t;
+
+/** Sensor status or return code */
+typedef enum _sensorStatus {
+	SENSOR_OK = 0,        /**< Operation is successful */
+	SENSOR_TWI_ERROR,
+	SENSOR_ID_ERROR,
+	SENSOR_RESOLUTION_NOT_SUPPORTED
+} sendorStatus_t;
+
+/** Sensor TWI mode */
+typedef enum _sensorTwiMode {
+	SENSOR_TWI_REG_BYTE_DATA_BYTE = 0,
+	SENSOR_TWI_REG_2BYTE_DATA_BYTE,
+	SENSOR_TWI_REG_BYTE_DATA_2BYTE
+} sensorTwiMode_t;
+
+/** Sensor resolution */
+typedef enum _sensorResolution {
+	QVGA = 0,
+	VGA,
+	SVGA,
+	XGA,
+	WXGA,
+	UVGA
+} sensorOutputResolution_t;
+
+/** Sensor output format */
+typedef enum _sensorOutputFormat {
+	RAW_BAYER_12_BIT = 0,
+	RAW_BAYER_10_BIT,
+	YUV_422_8_BIT,
+	YUV_422_10_BIT,
+	MONO_12_BIT
+} sensorOutputFormat_t;
+
+/** define a structure for sensor register initialization values */
+typedef struct _sensor_reg {
+	uint16_t reg; /* Register to be written */
+	uint16_t val; /* value to be written */
+} sensorReg_t;
+
+typedef struct _sensor_output {
+	uint8_t type;                              /** Index 0: normal, 1: AF setting*/
+	sensorOutputResolution_t output_resolution; /** sensor output resolution */
+	sensorOutputFormat_t output_format;         /** sensor output format */
+	uint8_t supported;                          /** supported for current output_resolution*/
+	uint32_t output_width;                      /** output width */
+	uint32_t output_height;                     /** output height */
+	const sensorReg_t *output_setting;          /** sensor registers setting */
+} sensorOutput_t;
+
+/** define a structure for sensor profile */
+typedef struct _sensor_profile {
+	sensorType_t cmos_ccd;        /** Sensor type for CMOS sensor or CCD */
+	sensorTwiMode_t twi_inf_mode; /** TWI interface mode  */
+	uint32_t twi_slave_addr;      /** TWI slave address */
+	uint16_t pid_high_reg;        /** Register address for product ID high byte */
+	uint16_t pid_low_reg;         /** Register address for product ID low byte*/
+	uint16_t pid_high;            /** product ID high byte */
+	uint16_t pid_low;             /** product ID low byte */
+	uint16_t version_mask;        /** version mask */
+	const sensorOutput_t
+		*outputConf[SENDOR_SUPPORTED_OUTPUTS]; /** sensor settings */
+} sensorProfile_t;
+
+/*----------------------------------------------------------------------------
+ *        Exported functions
+ *----------------------------------------------------------------------------*/
+extern sendorStatus_t sensor_twi_write_regs(Twid *pTwid,
+		const sensorReg_t *pReglist);
+
+extern sendorStatus_t sensor_twi_read_regs(Twid *pTwid,
+		const sensorReg_t *pReglist);
+
+extern sendorStatus_t sensor_setup(Twid *pTwid,
+		const sensorProfile_t *sensor_profile,
+		sensorOutputResolution_t resolution);
+
+extern sendorStatus_t sensor_get_output(sensorOutputFormat_t *format,
+		uint32_t *width,
+		uint32_t *height,
+		sensorOutputResolution_t resolution);
Index: bsps/arm/atsam/contrib/libraries/libboard/include/lcd_color.h
===================================================================
--- bsps/arm/atsam/contrib/libraries/libboard/include/lcd_color.h	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libboard/include/lcd_color.h	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,109 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+#ifndef COLOR_H
+#define COLOR_H
+
+/**
+ * \file
+ *
+ * RGB 24-bits color table definition.
+ *
+ */
+
+/*
+ * RGB 24 Bpp
+ * RGB 888
+ * R7R6R5R4 R3R2R1R0 G7G6G5G4 G3G2G1G0 B7B6B5B4 B3B2B1B0
+ */
+
+#define COLOR_BLACK          0x000000
+#define COLOR_WHITE          0xFFFFFF
+
+#define COLOR_BLUE           0x0000FF
+#define COLOR_GREEN          0x00FF00
+#define COLOR_RED            0xFF0000
+
+#define COLOR_NAVY           0x000080
+#define COLOR_DARKBLUE       0x00008B
+#define COLOR_DARKGREEN      0x006400
+#define COLOR_DARKCYAN       0x008B8B
+#define COLOR_CYAN           0x00FFFF
+#define COLOR_TURQUOISE      0x40E0D0
+#define COLOR_INDIGO         0x4B0082
+#define COLOR_DARKRED        0x800000
+#define COLOR_OLIVE          0x808000
+#define COLOR_GRAY           0x808080
+#define COLOR_SKYBLUE        0x87CEEB
+#define COLOR_BLUEVIOLET     0x8A2BE2
+#define COLOR_LIGHTGREEN     0x90EE90
+#define COLOR_DARKVIOLET     0x9400D3
+#define COLOR_YELLOWGREEN    0x9ACD32
+#define COLOR_BROWN          0xA52A2A
+#define COLOR_DARKGRAY       0xA9A9A9
+#define COLOR_SIENNA         0xA0522D
+#define COLOR_LIGHTBLUE      0xADD8E6
+#define COLOR_GREENYELLOW    0xADFF2F
+#define COLOR_SILVER         0xC0C0C0
+#define COLOR_LIGHTGREY      0xD3D3D3
+#define COLOR_LIGHTCYAN      0xE0FFFF
+#define COLOR_VIOLET         0xEE82EE
+#define COLOR_AZUR           0xF0FFFF
+#define COLOR_BEIGE          0xF5F5DC
+#define COLOR_MAGENTA        0xFF00FF
+#define COLOR_TOMATO         0xFF6347
+#define COLOR_GOLD           0xFFD700
+#define COLOR_ORANGE         0xFFA500
+#define COLOR_SNOW           0xFFFAFA
+#define COLOR_YELLOW         0xFFFF00
+
+#define BLACK 0x0000
+#define BLUE  0x001F
+#define RED   0xF800
+#define GREEN 0x07E0
+#define WHITE 0xFFFF
+
+/* level is in [0; 31]*/
+#define BLUE_LEV(level)   ((level)&BLUE)
+#define GREEN_LEV(level)  ((((level)*2)<<5)&GREEN)
+#define RED_LEV(level)    (((level)<<(5+6))&RED)
+#define GRAY_LEV(level)   (BLUE_LEV(level) | GREEN_LEV(level) | RED_LEV(level))
+
+#define RGB_24_TO_RGB565(RGB) \
+		(((RGB >>19)<<11) | (((RGB & 0x00FC00) >>5)) | (RGB & 0x00001F))
+#define RGB_24_TO_18BIT(RGB) \
+		(((RGB >>16)&0xFC) | (((RGB & 0x00FF00) >>10) << 10) | (RGB & 0x0000FC)<<16)
+#define RGB_16_TO_18BIT(RGB) \
+		(((((RGB >>11)*63)/31)<<18) | (RGB & 0x00FC00) | (((RGB & 0x00001F)*63)/31))
+#define BGR_TO_RGB_18BIT(RGB) \
+		(RGB & 0xFF0000) | ((RGB & 0x00FF00) >> 8) | ((RGB & 0x0000FC) >> 16))
+#define BGR_16_TO_18BITRGB(RGB)   BGR_TO_RGB_18BIT(RGB_16_TO_18BIT(RGB))
+
+
+#endif /* #define COLOR_H */
Index: bsps/arm/atsam/contrib/libraries/libboard/include/lcd_draw.h
===================================================================
--- bsps/arm/atsam/contrib/libraries/libboard/include/lcd_draw.h	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libboard/include/lcd_draw.h	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,186 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+/**
+ * \file
+ *
+ * Interface for draw function on LCD.
+ *
+ */
+
+#ifndef DRAW_H
+#define DRAW_H
+
+/*----------------------------------------------------------------------------
+ *        Headers
+ *----------------------------------------------------------------------------*/
+#include "board.h"
+#include <stdint.h>
+#include "lcd_gimp_image.h"
+
+/*----------------------------------------------------------------------------
+ *        Definitions
+ *----------------------------------------------------------------------------*/
+
+/** Horizontal direction line definition */
+#define DIRECTION_HLINE   0
+/** Vertical direction line definition */
+#define DIRECTION_VLINE   1
+
+typedef struct _rect {
+	uint32_t x;
+	uint32_t y;
+	uint32_t width;
+	uint32_t height;
+} rect;
+
+COMPILER_PACK_SET(1)
+typedef struct _rgb {
+	uint8_t b;
+	uint8_t g;
+	uint8_t r;
+} sBGR;
+COMPILER_PACK_RESET()
+
+/*----------------------------------------------------------------------------
+ *        Exported functions
+ *----------------------------------------------------------------------------*/
+extern void LCDD_SetUpdateWindowSize(rect rc);
+
+extern void LCDD_UpdateWindow(void);
+
+extern void LCDD_UpdatePartialWindow(uint8_t *pbuf, uint32_t size);
+
+extern void LCDD_DrawRectangleWithFill(
+		uint16_t *pbuf,
+		uint32_t dwX,
+		uint32_t dwY,
+		uint32_t dwWidth,
+		uint32_t dwHeight,
+		uint32_t dwColor);
+
+extern uint32_t LCDD_DrawCircle(
+		uint16_t *pbuf,
+		uint32_t x,
+		uint32_t y,
+		uint32_t r,
+		uint32_t color);
+
+extern uint32_t LCD_DrawFilledCircle(
+		uint16_t *pbuf,
+		uint32_t dwX,
+		uint32_t dwY,
+		uint32_t dwRadius,
+		uint32_t color);
+
+extern void LCDD_DrawString(
+		uint16_t *pbuf,
+		uint32_t x,
+		uint32_t y,
+		const uint8_t *pString,
+		uint32_t color);
+
+extern void LCDD_GetStringSize(
+		const uint8_t *pString,
+		uint32_t *pWidth,
+		uint32_t *pHeight);
+
+extern void LCDD_BitBlt(
+		uint16_t *pbuf,
+		uint32_t dst_x,
+		uint32_t dst_y,
+		uint32_t dst_w,
+		uint32_t dst_h,
+		const LcdColor_t *src,
+		uint32_t src_x,
+		uint32_t src_y,
+		uint32_t src_w,
+		uint32_t src_h);
+
+extern void LCDD_BitBltAlphaBlend(uint16_t *pbuf,
+								  uint32_t dst_x,
+								  uint32_t dst_y,
+								  uint32_t dst_w,
+								  uint32_t dst_h,
+								  const LcdColor_t *src,
+								  uint32_t src_x,
+								  uint32_t src_y,
+								  uint32_t src_w,
+								  uint32_t src_h,
+								  uint32_t alpha);
+extern void LCDD_DrawImage(
+	uint16_t *pbuf,
+	uint32_t dwX,
+	uint32_t dwY,
+	const LcdColor_t *pImage,
+	uint32_t dwWidth,
+	uint32_t dwHeight);
+
+extern void LCDD_DrawPixel(
+	uint16_t *pbuf,
+	uint32_t x,
+	uint32_t y,
+	uint32_t color);
+
+extern void LCDD_DrawLine(
+	uint16_t *pbuf,
+	uint32_t dwX1,
+	uint32_t dwY1,
+	uint32_t dwX2,
+	uint32_t dwY2,
+	uint32_t color);
+
+extern uint32_t LCDD_DrawLineBresenham(
+	uint16_t *pbuf,
+	uint32_t dwX1,
+	uint32_t dwY1,
+	uint32_t dwX2,
+	uint32_t dwY2,
+	uint32_t color);
+
+extern void LCDD_DrawRectangle(
+	uint16_t *pbuf,
+	uint32_t x,
+	uint32_t y,
+	uint32_t width,
+	uint32_t height,
+	uint32_t color);
+
+extern void LCDD_SetCavasBuffer(
+	void *pBuffer,
+	uint32_t wBufferSize);
+
+extern void LCDD_DrawStraightLine(
+	uint16_t *pbuf,
+	uint32_t dwX1,
+	uint32_t dwY1,
+	uint32_t dwX2,
+	uint32_t dwY2 ,
+	uint32_t color);
+#endif /* #ifndef DRAW_H */
Index: bsps/arm/atsam/contrib/libraries/libboard/include/lcd_font.h
===================================================================
--- bsps/arm/atsam/contrib/libraries/libboard/include/lcd_font.h	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libboard/include/lcd_font.h	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,108 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+/**
+ * \file
+ *
+ * Interface for draw font on LCD.
+ *
+ */
+
+/**
+ *
+ * \section Purpose
+ *
+ * The font.h files declares a font structure and a LCDD_DrawChar function
+ * that must be implemented by a font definition file to be used with the
+ * LCDD_DrawString method of draw.h.
+ *
+ * The font10x14.c implements the necessary variable and function for a 10x14
+ * font.
+ *
+ * \section Usage
+ *
+ * -# Declare a gFont global variable with the necessary Font information.
+ * -# Implement an LCDD_DrawChar function which displays the specified
+ *    character on the LCD.
+ * -# Use the LCDD_DrawString method defined in draw.h to display a complete
+ *    string.
+ */
+
+#ifndef _LCD_FONT_
+#define _LCD_FONT_
+
+/*----------------------------------------------------------------------------
+ *        Headers
+ *----------------------------------------------------------------------------*/
+
+#include <stdint.h>
+
+/*----------------------------------------------------------------------------
+ *        Types
+ *----------------------------------------------------------------------------*/
+
+
+/** \brief Describes the font (width, height, supported characters, etc.) used by
+ * the LCD driver draw API.
+ */
+typedef struct _Font {
+	/* Font width in pixels. */
+	uint8_t width;
+	/* Font height in pixels. */
+	uint8_t height;
+} Font;
+
+/*----------------------------------------------------------------------------
+ *        Variables
+ *----------------------------------------------------------------------------*/
+
+/** Global variable describing the font being instanced. */
+extern const Font gFont;
+
+/*----------------------------------------------------------------------------
+ *        Exported functions
+ *----------------------------------------------------------------------------*/
+
+extern void LCDD_DrawChar(
+	uint16_t *pCanvasBuffer,
+	uint32_t x,
+	uint32_t y,
+	uint8_t c,
+	uint32_t color);
+
+extern void LCD_DrawString(
+	uint16_t *pCanvasBuffer,
+	uint32_t dwX,
+	uint32_t dwY,
+	const uint8_t *pString,
+	uint32_t color);
+
+
+#endif /* #ifndef LCD_FONT_ */
+
Index: bsps/arm/atsam/contrib/libraries/libboard/include/lcd_font10x14.h
===================================================================
--- bsps/arm/atsam/contrib/libraries/libboard/include/lcd_font10x14.h	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libboard/include/lcd_font10x14.h	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,45 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+/**
+ * \file
+ *
+ * Font 10x14 table definition.
+ *
+ */
+
+#ifndef _LCD_FONT_10x14_
+#define _LCD_FONT_10x14_
+
+#include <stdint.h>
+
+/** Char set of font 10x14 */
+extern const uint8_t pCharset10x14[];
+
+#endif /* #ifdef _LCD_FONT_10x14_ */
Index: bsps/arm/atsam/contrib/libraries/libboard/include/lcd_gimp_image.h
===================================================================
--- bsps/arm/atsam/contrib/libraries/libboard/include/lcd_gimp_image.h	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libboard/include/lcd_gimp_image.h	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,42 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+#ifndef _GIMP_IMAGE_
+#define _GIMP_IMAGE_
+
+#include <stdint.h>
+
+typedef struct _SGIMPImage {
+	uint32_t dwWidth;
+	uint32_t dwHeight;
+	uint32_t dwBytes_per_pixel; /* 3:RGB, 4:RGBA */
+	uint8_t *pucPixel_data;
+} SGIMPImage;
+
+#endif // _GIMP_IMAGE_
Index: bsps/arm/atsam/contrib/libraries/libboard/include/lcdd.h
===================================================================
--- bsps/arm/atsam/contrib/libraries/libboard/include/lcdd.h	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libboard/include/lcdd.h	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,52 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+/**
+ * \file
+ *
+ * Interface for LCD driver.
+ *
+ */
+
+#ifndef LCDD_H
+#define LCDD_H
+
+/*----------------------------------------------------------------------------
+ *        Exported functions
+ *----------------------------------------------------------------------------*/
+
+extern void LCDD_Initialize(uint8_t lcdMode, sXdmad *dmad, uint8_t cRotate);
+
+extern void LCDD_On(void);
+
+extern void LCDD_Off(void);
+
+extern void LCDD_SetBacklight (uint32_t step);
+
+#endif /* #ifndef LCDD_H */
Index: bsps/arm/atsam/contrib/libraries/libboard/include/led.h
===================================================================
--- bsps/arm/atsam/contrib/libraries/libboard/include/led.h	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libboard/include/led.h	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,72 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+/**
+ * \file
+ *
+ *  \section Purpose
+ *
+ *  Small set of functions for simple and portable LED usage.
+ *
+ *  \section Usage
+ *
+ *  -# Configure one or more LEDs using LED_Configure and
+ *     LED_ConfigureAll.
+ *  -# Set, clear and toggle LEDs using LED_Set, LED_Clear and
+ *     LED_Toggle.
+ *
+ *  LEDs are numbered starting from 0; the number of LEDs depend on the
+ *  board being used. All the functions defined here will compile properly
+ *  regardless of whether the LED is defined or not; they will simply
+ *  return 0 when a LED which does not exist is given as an argument.
+ *  Also, these functions take into account how each LED is connected on to
+ *  board; thus, \ref LED_Set might change the level on the corresponding pin
+ *  to 0 or 1, but it will always light the LED on; same thing for the other
+ *  methods.
+ */
+
+#ifndef _LED_
+#define _LED_
+
+#include <stdint.h>
+
+/*----------------------------------------------------------------------------
+ *        Exported functions
+ *----------------------------------------------------------------------------*/
+
+extern uint32_t LED_Configure(uint32_t dwLed);
+
+extern uint32_t LED_Set(uint32_t dwLed);
+
+extern uint32_t LED_Clear(uint32_t dwLed);
+
+extern uint32_t LED_Toggle(uint32_t dwLed);
+
+#endif /* #ifndef LED_H */
+
Index: bsps/arm/atsam/contrib/libraries/libboard/include/math.h
===================================================================
--- bsps/arm/atsam/contrib/libraries/libboard/include/math.h	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libboard/include/math.h	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,42 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+#ifndef _MATH_
+#define _MATH_
+
+/*------------------------------------------------------------------------------
+ *         Exported functions
+ *------------------------------------------------------------------------------*/
+
+extern uint32_t min(uint32_t dwA, uint32_t dwB);
+extern uint32_t absv(int32_t lValue);
+extern uint32_t power(uint32_t dwX, uint32_t dwY);
+
+#endif /* #ifndef _MATH_ */
+
Index: bsps/arm/atsam/contrib/libraries/libboard/include/mcan_config.h
===================================================================
--- bsps/arm/atsam/contrib/libraries/libboard/include/mcan_config.h	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libboard/include/mcan_config.h	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,126 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+/**
+ *  \file
+ *
+ *  \section Purpose
+ *
+ *  Interface for configuring and using Timer Counter (TC) peripherals.
+ *
+ *  \section Usage
+ *  -# Optionally, use TC_FindMckDivisor() to let the program find the best
+ *     TCCLKS field value automatically.
+ *  -# Configure a Timer Counter in the desired mode using TC_Configure().
+ *  -# Start or stop the timer clock using TC_Start() and TC_Stop().
+ */
+
+#ifndef _MCAN_CONFIG_
+#define _MCAN_CONFIG_
+
+/*------------------------------------------------------------------------------
+ *         Headers
+ *------------------------------------------------------------------------------*/
+
+
+/*------------------------------------------------------------------------------
+ *         Global functions
+ *------------------------------------------------------------------------------*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Programmable Clock Source for Baud Rate is Common To Both MCAN Controllers */
+#define MCAN_PROG_CLK_PRESCALER       1   /* /1 to /256 */
+// select one of the following for the programmable clock source
+//#define MCAN_PROG_CLK_SELECT          PMC_PCK_CSS_SLOW_CLK
+//#define MCAN_PROG_CLK_SELECT          PMC_PCK_CSS_MAIN_CLK
+//#define MCAN_PROG_CLK_SELECT          PMC_PCK_CSS_PLLA_CLK
+//#define MCAN_PROG_CLK_SELECT          PMC_PCK_CSS_UPLL_CLK
+#define MCAN_PROG_CLK_SELECT          PMC_PCK_CSS_MCK
+#define MCAN_PROG_CLK_FREQ_HZ \
+	((float) 150000000 / (float) MCAN_PROG_CLK_PRESCALER)
+
+#define MCAN0_BIT_RATE_BPS            500000
+#define MCAN0_PROP_SEG                2
+#define MCAN0_PHASE_SEG1              11
+#define MCAN0_PHASE_SEG2              11
+#define MCAN0_SYNC_JUMP               4
+
+#define MCAN0_FAST_BIT_RATE_BPS       2000000
+#define MCAN0_FAST_PROP_SEG           2
+#define MCAN0_FAST_PHASE_SEG1         4
+#define MCAN0_FAST_PHASE_SEG2         4
+#define MCAN0_FAST_SYNC_JUMP          2
+
+#define MCAN0_NMBR_STD_FLTS           8  /* 128 max filters */
+#define MCAN0_NMBR_EXT_FLTS           8  /* 64 max filters */
+#define MCAN0_NMBR_RX_FIFO0_ELMTS     0  /* # of elements, 64 elements max */
+#define MCAN0_NMBR_RX_FIFO1_ELMTS     0  /* # of elements, 64 elements max */
+#define MCAN0_NMBR_RX_DED_BUF_ELMTS   16 /* # of elements, 64 elements max */
+#define MCAN0_NMBR_TX_EVT_FIFO_ELMTS  0  /* # of elements, 32 elements max */
+#define MCAN0_NMBR_TX_DED_BUF_ELMTS   4  /* # of elements, 32 elements max */
+#define MCAN0_NMBR_TX_FIFO_Q_ELMTS    0  /* # of elements, 32 elements max */
+#define MCAN0_RX_FIFO0_ELMT_SZ        8  /* 8, 12, 16, 20, 24, 32, 48, 64 bytes */
+#define MCAN0_RX_FIFO1_ELMT_SZ        8  /* 8, 12, 16, 20, 24, 32, 48, 64 bytes */
+#define MCAN0_RX_BUF_ELMT_SZ          8  /* 8, 12, 16, 20, 24, 32, 48, 64 bytes */
+#define MCAN0_TX_BUF_ELMT_SZ          8  /* 8, 12, 16, 20, 24, 32, 48, 64 bytes */
+
+#define MCAN1_BIT_RATE_BPS            500000
+#define MCAN1_PROP_SEG                2
+#define MCAN1_PHASE_SEG1              11
+#define MCAN1_PHASE_SEG2              11
+#define MCAN1_SYNC_JUMP               4
+
+#define MCAN1_FAST_BIT_RATE_BPS       2000000
+#define MCAN1_FAST_PROP_SEG           2
+#define MCAN1_FAST_PHASE_SEG1         4
+#define MCAN1_FAST_PHASE_SEG2         4
+#define MCAN1_FAST_SYNC_JUMP          2
+
+#define MCAN1_NMBR_STD_FLTS           8   /* 128 max filters */
+#define MCAN1_NMBR_EXT_FLTS           8   /* 64 max filters */
+#define MCAN1_NMBR_RX_FIFO0_ELMTS     12  /* # of elements, 64 elements max */
+#define MCAN1_NMBR_RX_FIFO1_ELMTS     0   /* # of elements, 64 elements max */
+#define MCAN1_NMBR_RX_DED_BUF_ELMTS   4   /* # of elements, 64 elements max */
+#define MCAN1_NMBR_TX_EVT_FIFO_ELMTS  0   /* # of elements, 32 elements max */
+#define MCAN1_NMBR_TX_DED_BUF_ELMTS   4   /* # of elements, 32 elements max */
+#define MCAN1_NMBR_TX_FIFO_Q_ELMTS    4   /* # of elements, 32 elements max */
+#define MCAN1_RX_FIFO0_ELMT_SZ        8   /* 8, 12, 16, 20, 24, 32, 48, 64 bytes */
+#define MCAN1_RX_FIFO1_ELMT_SZ        8   /* 8, 12, 16, 20, 24, 32, 48, 64 bytes */
+#define MCAN1_RX_BUF_ELMT_SZ          64  /* 8, 12, 16, 20, 24, 32, 48, 64 bytes */
+#define MCAN1_TX_BUF_ELMT_SZ          32  /* 8, 12, 16, 20, 24, 32, 48, 64 bytes */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* #ifndef _MCAN_CONFIG_ */
+
Index: bsps/arm/atsam/contrib/libraries/libboard/include/rtc_calib.h
===================================================================
--- bsps/arm/atsam/contrib/libraries/libboard/include/rtc_calib.h	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libboard/include/rtc_calib.h	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,49 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+/**
+ * \file
+ *
+ * Interface for Real Time Clock calibration (RTC) .
+ *
+ */
+
+/** RTC crystal **/
+
+
+typedef struct {
+	int8_t Tempr;
+	int16_t PPM;
+	uint8_t NEGPPM;
+	uint8_t HIGHPPM;
+	uint16_t CORRECTION;
+} RTC_PPMLookup;
+
+
+extern void RTC_ClockCalibration(Rtc *pRtc, int32_t CurrentTempr);
Index: bsps/arm/atsam/contrib/libraries/libboard/include/s25fl1.h
===================================================================
--- bsps/arm/atsam/contrib/libraries/libboard/include/s25fl1.h	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libboard/include/s25fl1.h	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,255 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+/**
+ * \file
+ *
+ * Interface for the S25fl1 Serial Flash driver.
+ *
+ */
+
+#ifndef S25FL1_H
+#define S25FL1_H
+#define USE_QSPI_DMA
+/*----------------------------------------------------------------------------
+ *        Macros
+ *----------------------------------------------------------------------------*/
+
+#define Size(pAt25)            ((pAt25)->pDesc->size)
+#define PageSize(pAt25)        ((pAt25)->pDesc->pageSize)
+#define BlockSize(pAt25)       ((pAt25)->pDesc->blockSize)
+#define Name(pAt25)            ((pAt25)->pDesc->name)
+#define ManId(pAt25)           (((pAt25)->pDesc->jedecId) & 0xFF)
+#define PageNumber(pAt25)      (Size(pAt25) / PageSize(pAt25))
+#define BlockNumber(pAt25)     (Size(pAt25) / BlockSize(pAt25))
+#define PagePerBlock(pAt25)    (BlockSize(pAt25) / PageSize(pAt25))
+#define BlockEraseCmd(pAt25)   ((pAt25)->pDesc->blockEraseCmd)
+
+/*----------------------------------------------------------------------------
+ *        Local definitions
+ *----------------------------------------------------------------------------*/
+
+/** Device is protected, operation cannot be carried out. */
+#define ERROR_PROTECTED        1
+/** Device is busy executing a command. */
+#define ERROR_BUSY             2
+/** There was a problem while trying to program page data. */
+#define ERROR_PROGRAM          3
+/** There was an SPI communication error. */
+#define ERROR_SPI              4
+
+/** Device ready/busy status bit. */
+#define STATUS_RDYBSY          (1 << 0)
+/** Device is ready. */
+#define STATUS_RDYBSY_READY    (0 << 0)
+/** Device is busy with internal operations. */
+#define STATUS_RDYBSY_BUSY     (1 << 0)
+/** Write enable latch status bit. */
+#define STATUS_WEL             (1 << 1)
+/** Device is not write enabled. */
+#define STATUS_WEL_DISABLED    (0 << 1)
+/** Device is write enabled. */
+#define STATUS_WEL_ENABLED     (1 << 1)
+/** Software protection status bit-field. */
+#define STATUS_SWP             (3 << 2)
+/** All sectors are software protected. */
+#define STATUS_SWP_PROTALL     (3 << 2)
+/** Some sectors are software protected. */
+#define STATUS_SWP_PROTSOME    (1 << 2)
+/** No sector is software protected. */
+#define STATUS_SWP_PROTNONE    (0 << 2)
+/** Write protect pin status bit. */
+#define STATUS_WPP             (1 << 4)
+/** Write protect signal is not asserted. */
+#define STATUS_WPP_NOTASSERTED (0 << 4)
+/** Write protect signal is asserted. */
+#define STATUS_WPP_ASSERTED    (1 << 4)
+/** Erase/program error bit. */
+#define STATUS_EPE             (1 << 5)
+/** Erase or program operation was successful. */
+#define STATUS_EPE_SUCCESS     (0 << 5)
+/** Erase or program error detected. */
+#define STATUS_EPE_ERROR       (1 << 5)
+/** Sector protection registers locked bit. */
+#define STATUS_SPRL            (1 << 7)
+/** Sector protection registers are unlocked. */
+#define STATUS_SPRL_UNLOCKED   (0 << 7)
+/** Sector protection registers are locked. */
+#define STATUS_SPRL_LOCKED     (1 << 7)
+
+/** Quad enable bit */
+#define STATUS_QUAD_ENABLE     (1 << 1)
+/** Quad enable bit */
+#define STATUS_WRAP_ENABLE     (0 << 4)
+
+/** Latency control bits */
+#define STATUS_LATENCY_CTRL    (0xF << 0)
+
+#define STATUS_WRAP_BYTE       (1 << 5)
+
+#define BLOCK_PROTECT_Msk      (7 << 2)
+
+#define TOP_BTM_PROTECT_Msk    (1 << 5)
+
+#define SEC_PROTECT_Msk        (1 << 6)
+
+#define CHIP_PROTECT_Msk       (0x1F << 2)
+
+/** Read array command code. */
+#define READ_ARRAY             0x0B
+/** Read array (low frequency) command code. */
+#define READ_ARRAY_LF          0x03
+/** Fast Read array  command code. */
+#define READ_ARRAY_DUAL        0x3B
+/** Fast Read array  command code. */
+#define READ_ARRAY_QUAD        0x6B
+/** Fast Read array  command code. */
+#define READ_ARRAY_DUAL_IO     0xBB
+/** Fast Read array  command code. */
+#define READ_ARRAY_QUAD_IO     0xEB
+/** Block erase command code (4K block). */
+#define BLOCK_ERASE_4K         0x20
+/** Block erase command code (32K block). */
+#define BLOCK_ERASE_32K        0x52
+/** Block erase command code (64K block). */
+#define BLOCK_ERASE_64K        0xD8
+/** Chip erase command code 1. */
+#define CHIP_ERASE_1           0x60
+/** Chip erase command code 2. */
+#define CHIP_ERASE_2           0xC7
+/** Byte/page program command code. */
+#define BYTE_PAGE_PROGRAM      0x02
+/** Sequential program mode command code 1. */
+#define SEQUENTIAL_PROGRAM_1   0xAD
+/** Sequential program mode command code 2. */
+#define SEQUENTIAL_PROGRAM_2   0xAF
+/** Write enable command code. */
+#define WRITE_ENABLE           0x06
+/** Write disable command code. */
+#define WRITE_DISABLE          0x04
+/** Protect sector command code. */
+#define PROTECT_SECTOR         0x36
+/** Unprotected sector command code. */
+#define UNPROTECT_SECTOR       0x39
+/** Read sector protection registers command code. */
+#define READ_SECTOR_PROT       0x3C
+/** Read status register command code. */
+#define READ_STATUS_1          0x05
+/** Read status register command code. */
+#define READ_STATUS_2          0x35
+/** Read status register command code. */
+#define READ_STATUS_3          0x33
+/** Write status register command code. */
+#define WRITE_STATUS           0x01
+/** Read manufacturer and device ID command code. */
+#define READ_JEDEC_ID          0x9F
+/** Deep power-down command code. */
+#define DEEP_PDOWN             0xB9
+/** Resume from deep power-down command code. */
+#define RES_DEEP_PDOWN         0xAB
+/** Resume from deep power-down command code. */
+#define SOFT_RESET_ENABLE      0x66
+/** Resume from deep power-down command code. */
+#define SOFT_RESET             0x99
+/** Resume from deep power-down command code. */
+#define WRAP_ENABLE            0x77
+/** Continuous Read Mode Reset command code. */
+#define CONT_MODE_RESET        0xFF
+
+/** SPI Flash Manufacturer JEDEC ID */
+#define ATMEL_SPI_FLASH             0x1F
+#define ST_SPI_FLASH                0x20
+#define WINBOND_SPI_FLASH           0xEF
+#define MACRONIX_SPI_FLASH          0xC2
+#define SST_SPI_FLASH               0xBF
+
+/*----------------------------------------------------------------------------
+ *        Exported functions
+ *----------------------------------------------------------------------------*/
+
+uint32_t S25FL1D_ReadJedecId(void);
+
+void S25FL1D_InitFlashInterface(uint8_t Mode);
+
+void S25FL1D_SoftReset(void);
+
+void S25FL1D_ContReadModeReset(void);
+unsigned char S25FL1D_Unprotect(void);
+
+unsigned char S25FL1D_Protect(uint32_t StartAddr, uint32_t Size);
+
+void S25FL1D_QuadMode(uint8_t Enable);
+
+void S25FL1D_EnableWrap(uint8_t ByetAlign);
+
+void S25FL1D_SetReadLatencyControl(uint8_t Latency);
+
+unsigned char S25FL1D_EraseChip(void);
+
+unsigned char S25FL1D_EraseSector(unsigned int address);
+
+unsigned char S25FL1D_Erase64KBlock(unsigned int address);
+
+unsigned char S25FL1D_Write(
+	uint32_t *pData,
+	uint32_t size,
+	uint32_t address,
+	uint8_t Secure);
+
+extern unsigned char S25FL1D_Read(
+	uint32_t *pData,
+	uint32_t size,
+	uint32_t address);
+
+extern unsigned char S25FL1D_ReadDual(
+	uint32_t *pData,
+	uint32_t size,
+	uint32_t address);
+
+extern unsigned char S25FL1D_ReadQuad(
+	uint32_t *pData,
+	uint32_t size,
+	uint32_t address);
+
+extern unsigned char S25FL1D_ReadDualIO(
+	uint32_t *pData,
+	uint32_t size,
+	uint32_t address,
+	uint8_t ContMode,
+	uint8_t Secure);
+
+extern unsigned char S25FL1D_ReadQuadIO(
+	uint32_t *pData,
+	uint32_t size,
+	uint32_t address,
+	uint8_t ContMode,
+	uint8_t Secure);
+
+#endif // #ifndef S25FL1_H
+
Index: bsps/arm/atsam/contrib/libraries/libboard/include/wm8904.h
===================================================================
--- bsps/arm/atsam/contrib/libraries/libboard/include/wm8904.h	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libboard/include/wm8904.h	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,160 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+/**
+  * \file
+  *
+  * Implementation WM8904 driver.
+  *
+  */
+
+#ifndef WM8904_H
+#define WM8904_H
+
+#include "board.h"
+
+/*----------------------------------------------------------------------------
+ *         Definitions
+ *----------------------------------------------------------------------------*/
+#define WM8904_CSB_STATE            (0x0 << 0)
+
+/** Slave address */
+#define WM8904_SLAVE_ADDRESS        0x1a | WM8904_CSB_STATE
+#define CS2100_SLAVE_ADDRESS        0x4E
+
+
+/** Reset register*/
+#define WM8904_REG_RESET                           0x00
+
+/** Bias control 0 register*/
+#define WM8904_REG_BIAS_CTRL0                      0x04
+
+/** VMID control 0 register*/
+#define WM8904_REG_VMID_CTRL0                      0x05
+
+/** MIC Bias control 0 register*/
+#define WM8904_REG_MICBIAS_CTRL0                   0x06
+
+/** Bias control 1 register*/
+#define WM8904_REG_BIAS_CTRL1                      0x07
+
+/** Power management control 0 register*/
+#define WM8904_REG_POWER_MANG0                     0x0C
+/** Power management control 2 register*/
+#define WM8904_REG_POWER_MANG2                     0x0E
+/** Power management control 3 register*/
+#define WM8904_REG_POWER_MANG3                     0x0F
+/** Power management control 6 register*/
+#define WM8904_REG_POWER_MANG6                     0x12
+
+/** Clock rate0 register*/
+#define WM8904_REG_CLOCK_RATE0                     0x14
+/** Clock rate1 register*/
+#define WM8904_REG_CLOCK_RATE1                     0x15
+
+/** Clock rate2 register*/
+#define WM8904_REG_CLOCK_RATE2                     0x16
+
+/** Audio interface0 register*/
+#define WM8904_REG_AUD_INF0                        0x18
+
+/** Audio interface1 register*/
+#define WM8904_REG_AUD_INF1                        0x19
+/** Audio interface2 register*/
+#define WM8904_REG_AUD_INF2                        0x1A
+/** Audio interface3 register*/
+#define WM8904_REG_AUD_INF3                        0x1B
+
+/** ADC digital 0 register*/
+#define WM8904_REG_ADC_DIG0                        0x20
+/** ADC digital 1 register*/
+#define WM8904_REG_ADC_DIG1                        0x21
+
+/** Analogue left input 0 register*/
+#define WM8904_REG_ANALOGUE_LIN0                   0x2C
+/** Analogue right input 0 register*/
+#define WM8904_REG_ANALOGUE_RIN0                   0x2D
+
+/** Analogue left input 1 register*/
+#define WM8904_REG_ANALOGUE_LIN1                   0x2E
+/** Analogue right input 1 register*/
+#define WM8904_REG_ANALOGUE_RIN1                   0x2F
+
+/** Analogue left output 1 register*/
+#define WM8904_REG_ANALOGUE_LOUT1                  0x39
+/** Analogue right output 1 register*/
+#define WM8904_REG_ANALOGUE_ROUT1                  0x3A
+
+/** Analogue left output 2 register*/
+#define WM8904_REG_ANALOGUE_LOUT2                  0x3B
+/** Analogue right output 2 register*/
+#define WM8904_REG_ANALOGUE_ROUT2                  0x3C
+
+/** Analogue output 12 ZC register*/
+#define WM8904_REG_ANALOGUE_OUT12ZC                0x3D
+
+/** DC servo 0 register*/
+#define WM8904_REG_DC_SERVO0                       0x43
+
+/** Analogue HP 0 register*/
+#define WM8904_REG_ANALOGUE_HP0                    0x5A
+
+/** Charge pump 0 register*/
+#define WM8904_REG_CHARGE_PUMP0                    0x62
+
+/** Class W 0 register*/
+#define WM8904_REG_CLASS0                          0x68
+
+/** FLL control 1 register*/
+#define WM8904_REG_FLL_CRTL1                       0x74
+/** FLL control 2 register*/
+#define WM8904_REG_FLL_CRTL2                       0x75
+/** FLL control 3 register*/
+#define WM8904_REG_FLL_CRTL3                       0x76
+/** FLL control 4 register*/
+#define WM8904_REG_FLL_CRTL4                       0x77
+/** FLL control 5 register*/
+#define WM8904_REG_FLL_CRTL5                       0x78
+
+/** DUMMY register*/
+#define WM8904_REG_END                             0xFF
+
+/*----------------------------------------------------------------------------
+ *         Exported functions
+ *----------------------------------------------------------------------------*/
+
+extern uint16_t WM8904_Read(Twid *pTwid, uint32_t device, uint32_t regAddr);
+extern void WM8904_Write(Twid *pTwid, uint32_t device, uint32_t regAddr,
+						 uint16_t data);
+extern uint8_t WM8904_Init(Twid *pTwid, uint32_t device, uint32_t PCK);
+extern uint8_t WM8904_VolumeSet(Twid *pTwid,  uint32_t device, uint16_t value);
+extern void WM8904_IN2R_IN1L(Twid *pTwid, uint32_t device);
+#endif // WM8904_H
+
+
Index: bsps/arm/atsam/contrib/libraries/libboard/resources_v71/system_samv71.c
===================================================================
--- bsps/arm/atsam/contrib/libraries/libboard/resources_v71/system_samv71.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libboard/resources_v71/system_samv71.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,318 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+#ifndef __rtems__
+#include "samv71.h"
+#else /* __rtems__ */
+#include <chip.h>
+#endif /* __rtems__ */
+
+/* @cond 0 */
+/**INDENT-OFF**/
+#ifdef __cplusplus
+extern "C" {
+#endif
+/**INDENT-ON**/
+	/* @endcond */
+
+	/* %ATMEL_SYSTEM% */
+	/* Clock Settings (600MHz PLL VDDIO 3.3V and VDDCORE 1.2V) */
+	/* Clock Settings (300MHz HCLK, 150MHz MCK)=> PRESC = 2, MDIV = 2 */
+#define SYS_BOARD_OSCOUNT   (CKGR_MOR_MOSCXTST(0x8U))
+#ifndef __rtems__
+#if BOARD_MCK == 123000000
+	/* For example usb_video, PLLA/HCLK/MCK clock is set to 492/246/123MHz to achieve
+	   the maximum performance, for other examples the clock is set to 300/300/150MHz */
+	#define SYS_BOARD_PLLAR     (CKGR_PLLAR_ONE | CKGR_PLLAR_MULA(0x28U) | \
+								 CKGR_PLLAR_PLLACOUNT(0x3fU) | CKGR_PLLAR_DIVA(0x1U))
+
+#define SYS_BOARD_MCKR_MDIV (PMC_MCKR_MDIV_PCK_DIV2)
+	#define SYS_BOARD_MCKR      (PMC_MCKR_PRES_CLK_2 | PMC_MCKR_CSS_PLLA_CLK \
+								 | SYS_BOARD_MCKR_MDIV)
+#elif BOARD_MCK == 150000000
+	#define SYS_BOARD_PLLAR     (CKGR_PLLAR_ONE | CKGR_PLLAR_MULA(0x18U) | \
+								 CKGR_PLLAR_PLLACOUNT(0x3fU) | CKGR_PLLAR_DIVA(0x1U))
+
+#define SYS_BOARD_MCKR_MDIV (PMC_MCKR_MDIV_PCK_DIV2)
+	#define SYS_BOARD_MCKR      (PMC_MCKR_PRES_CLK_1 | PMC_MCKR_CSS_PLLA_CLK \
+								 | SYS_BOARD_MCKR_MDIV)
+#else
+	#error "unexpected Main Clock (MCK) frequency"
+#endif
+
+	uint32_t SystemCoreClock = CHIP_FREQ_MAINCK_RC_4MHZ;
+#else /* __rtems__ */
+#define SYS_BOARD_MCKR_MDIV ((atsam_clock_config.mckr_init) & PMC_MCKR_MDIV_Msk)
+#define SYS_BOARD_MCKR (atsam_clock_config.mckr_init)
+#define SYS_BOARD_PLLAR (atsam_clock_config.pllar_init)
+#endif /* __rtems__ */
+#define USBCLK_DIV          10
+
+	/**
+	 * \brief Setup the microcontroller system.
+	 * Initialize the System and update the SystemFrequency variable.
+	 */
+#ifndef __rtems__
+	void SystemInit(void)
+#else /* __rtems__ */
+	void ATSAM_START_SRAM_SECTION SystemInit(void)
+#endif /* __rtems__ */
+{
+	uint32_t read_MOR;
+	/* Set FWS according to SYS_BOARD_MCKR configuration */
+	EFC->EEFC_FMR = EEFC_FMR_FWS(5);
+
+	/* Before switching MAIN OSC on external crystal : enable it and don't
+	 * disable at the same time RC OSC in case of if MAIN OSC is still using RC
+	 * OSC
+	 */
+
+#if ATSAM_SLOWCLOCK_USE_XTAL == 1
+	read_MOR = PMC->CKGR_MOR;
+	/* enable external crystal - enable RC OSC */
+	read_MOR |= (CKGR_MOR_KEY_PASSWD | CKGR_MOR_XT32KFME);
+	PMC->CKGR_MOR = read_MOR;
+
+	/* Select XTAL 32k instead of internal slow RC 32k for slow clock */
+	if ((SUPC->SUPC_SR & SUPC_SR_OSCSEL) != SUPC_SR_OSCSEL_CRYST) {
+		SUPC->SUPC_CR = SUPC_CR_KEY_PASSWD | SUPC_CR_XTALSEL_CRYSTAL_SEL;
+
+		while (!(SUPC->SUPC_SR & SUPC_SR_OSCSEL));
+	}
+#endif
+
+	/* Initialize main oscillator */
+	if (!(PMC->CKGR_MOR & CKGR_MOR_MOSCSEL)) {
+		PMC->CKGR_MOR = CKGR_MOR_KEY_PASSWD | SYS_BOARD_OSCOUNT | CKGR_MOR_MOSCRCEN |
+						CKGR_MOR_MOSCXTEN;
+
+		while (!(PMC->PMC_SR & PMC_SR_MOSCXTS)) {
+		}
+	}
+
+	/* Switch to 3-20MHz Xtal oscillator */
+	PMC->CKGR_MOR = CKGR_MOR_KEY_PASSWD | SYS_BOARD_OSCOUNT | CKGR_MOR_MOSCRCEN |
+					CKGR_MOR_MOSCXTEN | CKGR_MOR_MOSCSEL;
+
+	while (!(PMC->PMC_SR & PMC_SR_MOSCSELS)) {
+	}
+
+	PMC->PMC_MCKR = (PMC->PMC_MCKR & ~(uint32_t)PMC_MCKR_CSS_Msk) |
+					PMC_MCKR_CSS_MAIN_CLK;
+
+	while (!(PMC->PMC_SR & PMC_SR_MCKRDY)) {
+	}
+
+	/* Initialize PLLA */
+	PMC->CKGR_PLLAR = SYS_BOARD_PLLAR;
+
+	while (!(PMC->PMC_SR & PMC_SR_LOCKA)) {
+	}
+
+	/* Switch to main clock: DO NOT modify MDIV and CSS feild at the same access */
+	PMC->PMC_MCKR = (PMC->PMC_MCKR & ~(uint32_t)PMC_MCKR_MDIV_Msk) |
+					SYS_BOARD_MCKR_MDIV;
+	PMC->PMC_MCKR = (SYS_BOARD_MCKR & ~PMC_MCKR_CSS_Msk) | PMC_MCKR_CSS_MAIN_CLK;
+
+	while (!(PMC->PMC_SR & PMC_SR_MCKRDY)) {
+	}
+
+	/* Switch to PLLA */
+	PMC->PMC_MCKR = SYS_BOARD_MCKR;
+
+	while (!(PMC->PMC_SR & PMC_SR_MCKRDY)) {
+	}
+
+#ifndef __rtems__
+	SystemCoreClock = CHIP_FREQ_CPU_MAX;
+#endif /* __rtems__ */
+}
+
+#ifndef __rtems__
+void SystemCoreClockUpdate(void)
+{
+	/* Determine clock frequency according to clock register values */
+	switch (PMC->PMC_MCKR & (uint32_t) PMC_MCKR_CSS_Msk) {
+	case PMC_MCKR_CSS_SLOW_CLK: /* Slow clock */
+		if (SUPC->SUPC_SR & SUPC_SR_OSCSEL)
+			SystemCoreClock = CHIP_FREQ_XTAL_32K;
+		else
+			SystemCoreClock = CHIP_FREQ_SLCK_RC;
+
+		break;
+
+	case PMC_MCKR_CSS_MAIN_CLK: /* Main clock */
+		if (PMC->CKGR_MOR & CKGR_MOR_MOSCSEL)
+			SystemCoreClock = CHIP_FREQ_XTAL_12M;
+		else {
+			SystemCoreClock = CHIP_FREQ_MAINCK_RC_4MHZ;
+
+			switch (PMC->CKGR_MOR & CKGR_MOR_MOSCRCF_Msk) {
+			case CKGR_MOR_MOSCRCF_4_MHz:
+				break;
+
+			case CKGR_MOR_MOSCRCF_8_MHz:
+				SystemCoreClock *= 2U;
+				break;
+
+			case CKGR_MOR_MOSCRCF_12_MHz:
+				SystemCoreClock *= 3U;
+				break;
+
+			default:
+				break;
+			}
+		}
+
+		break;
+
+	case PMC_MCKR_CSS_PLLA_CLK: /* PLLA clock */
+		if (PMC->CKGR_MOR & CKGR_MOR_MOSCSEL)
+			SystemCoreClock = CHIP_FREQ_XTAL_12M;
+		else {
+			SystemCoreClock = CHIP_FREQ_MAINCK_RC_4MHZ;
+
+			switch (PMC->CKGR_MOR & CKGR_MOR_MOSCRCF_Msk) {
+			case CKGR_MOR_MOSCRCF_4_MHz:
+				break;
+
+			case CKGR_MOR_MOSCRCF_8_MHz:
+				SystemCoreClock *= 2U;
+				break;
+
+			case CKGR_MOR_MOSCRCF_12_MHz:
+				SystemCoreClock *= 3U;
+				break;
+
+			default:
+				break;
+			}
+		}
+
+		if ((uint32_t) (PMC->PMC_MCKR & (uint32_t) PMC_MCKR_CSS_Msk) ==
+			 PMC_MCKR_CSS_PLLA_CLK) {
+			SystemCoreClock *= ((((PMC->CKGR_PLLAR) & CKGR_PLLAR_MULA_Msk) >>
+								 CKGR_PLLAR_MULA_Pos) + 1U);
+			SystemCoreClock /= ((((PMC->CKGR_PLLAR) & CKGR_PLLAR_DIVA_Msk) >>
+								 CKGR_PLLAR_DIVA_Pos));
+		}
+
+		break;
+
+	default:
+		break;
+	}
+
+	if ((PMC->PMC_MCKR & PMC_MCKR_PRES_Msk) == PMC_MCKR_PRES_CLK_3)
+		SystemCoreClock /= 3U;
+	else
+		SystemCoreClock >>= ((PMC->PMC_MCKR & PMC_MCKR_PRES_Msk) >> PMC_MCKR_PRES_Pos);
+}
+#endif /* __rtems__ */
+/**
+ * Initialize flash.
+ */
+void system_init_flash(uint32_t ul_clk)
+{
+	/* Set FWS for embedded Flash access according to operating frequency */
+	if (ul_clk < CHIP_FREQ_FWS_0)
+		EFC->EEFC_FMR = EEFC_FMR_FWS(0) | EEFC_FMR_CLOE;
+	else {
+		if (ul_clk < CHIP_FREQ_FWS_1)
+			EFC->EEFC_FMR = EEFC_FMR_FWS(1) | EEFC_FMR_CLOE;
+		else {
+			if (ul_clk < CHIP_FREQ_FWS_2)
+				EFC->EEFC_FMR = EEFC_FMR_FWS(2) | EEFC_FMR_CLOE;
+			else {
+				if (ul_clk < CHIP_FREQ_FWS_3)
+					EFC->EEFC_FMR = EEFC_FMR_FWS(3) | EEFC_FMR_CLOE;
+				else {
+					if (ul_clk < CHIP_FREQ_FWS_4)
+						EFC->EEFC_FMR = EEFC_FMR_FWS(4) | EEFC_FMR_CLOE;
+					else
+						EFC->EEFC_FMR = EEFC_FMR_FWS(5) | EEFC_FMR_CLOE;
+				}
+			}
+		}
+	}
+}
+
+/**
+ * \brief Enable  USB clock.
+ *
+ * \param pll_id Source of the USB clock.
+ * \param div Actual clock divisor. Must be superior to 0.
+ */
+void sysclk_enable_usb(void)
+{
+	/* Disable FS USB clock*/
+	PMC->PMC_SCDR = PMC_SCDR_USBCLK;
+
+	/* Enable PLL 480 MHz */
+	PMC->CKGR_UCKR = CKGR_UCKR_UPLLEN | CKGR_UCKR_UPLLCOUNT(0xF);
+
+	/* Wait that PLL is considered locked by the PMC */
+	while (!(PMC->PMC_SR & PMC_SR_LOCKU));
+
+	/* USB clock register: USB Clock Input is UTMI PLL */
+	PMC->PMC_USB = (PMC_USB_USBS | PMC_USB_USBDIV(USBCLK_DIV - 1));
+
+	PMC->PMC_SCER = PMC_SCER_USBCLK;
+}
+
+
+/**
+ * \brief Disables USB clock.
+ *
+ *
+ * \param pll_id Source of the USB clock.
+ * \param div Actual clock divisor. Must be superior to 0.
+ */
+void sysclk_disable_usb(void)
+{
+	/* Disable FS USB clock*/
+	PMC->PMC_SCDR = PMC_SCDR_USBCLK;
+
+	/* Enable PLL 480 MHz */
+	PMC->CKGR_UCKR = CKGR_UCKR_UPLLEN | CKGR_UCKR_UPLLCOUNT(0xF);
+
+	/* Wait that PLL is considered locked by the PMC */
+	while (!(PMC->PMC_SR & PMC_SR_LOCKU));
+
+	/* USB clock register: USB Clock Input is UTMI PLL */
+	PMC->PMC_USB = (PMC_USB_USBS | PMC_USB_USBDIV(USBCLK_DIV - 1));
+}
+
+/* @cond 0 */
+/**INDENT-OFF**/
+#ifdef __cplusplus
+}
+#endif
+/**INDENT-ON**/
+/* @endcond */
Index: bsps/arm/atsam/contrib/libraries/libboard/source/board_lowlevel.c
===================================================================
--- bsps/arm/atsam/contrib/libraries/libboard/source/board_lowlevel.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libboard/source/board_lowlevel.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,434 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+/**
+ * \file
+ *
+ * Provides the low-level initialization function that called on chip startup.
+ */
+
+/*----------------------------------------------------------------------------
+ *        Headers
+ *----------------------------------------------------------------------------*/
+
+#ifndef __rtems__
+#include "board.h"
+#else /* __rtems__ */
+#define MPU_HAS_NOCACHE_REGION
+#include <chip.h>
+#include <include/board_lowlevel.h>
+#endif /* __rtems__ */
+
+
+#if defined(ENABLE_TCM) && defined(__GNUC__)
+	extern char _itcm_lma, _sitcm, _eitcm;
+#endif
+
+
+/*----------------------------------------------------------------------------
+ *        Exported functions
+ *----------------------------------------------------------------------------*/
+/* Default memory map
+   NO. Address range          Memory region    Memory type     Shareable?    Cache policy
+   1   0x00000000- 0x1FFFFFFF Code             Normal
+       0x00000000- 0x003FFFFF ITCM
+       0x00400000- 0x005FFFFF Internal flash   Normal          Not shareable   WB
+   2   0x20000000- 0x3FFFFFFF SRAM             Normal
+       0x20000000- 0x203FFFFF DTCM
+       0x20400000- 0x2043FFFF First Partition  Normal          Not shareable   WB
+ if MPU_HAS_NOCACHE_REGION is defined
+       0x20440000- 0x2045EFFF Second Partition Normal          Not shareable   WB
+       0x2045F000- 0x2045FFFF Nocache SRAM     Normal          Shareable
+ if MPU_HAS_NOCACHE_REGION is NOT defined
+       0x20440000- 0x2045FFFF Second Partition Normal          Not shareable   WB
+   3   0x40000000- 0x5FFFFFFF Peripheral       Device          Shareable
+   4   0x60000000- 0x7FFFFFFF RAM
+       0x60000000- 0x6FFFFFFF External EBI  Strongly-ordered   Shareable
+       0x70000000- 0x7FFFFFFF SDRAM            Normal          Shareable       WBWA
+   5   0x80000000- 0x9FFFFFFF QSPI          Strongly-ordered   Shareable
+   6   0xA0100000- 0xA01FFFFF USBHS RAM        Device          Shareable
+   7   0xE0000000- 0xFFFFFFFF System           -                  -
+   */
+
+/**
+ * \brief Set up a memory region.
+ */
+void _SetupMemoryRegion(void)
+{
+
+	uint32_t dwRegionBaseAddr;
+	uint32_t dwRegionAttr;
+
+	memory_barrier();
+
+	/***************************************************
+	    ITCM memory region --- Normal
+	    START_Addr:-  0x00000000UL
+	    END_Addr:-    0x003FFFFFUL
+	****************************************************/
+
+	dwRegionBaseAddr =
+		ITCM_START_ADDRESS |
+		MPU_REGION_VALID |
+		MPU_DEFAULT_ITCM_REGION;        // 1
+
+#ifdef __rtems__
+	if (ITCM_END_ADDRESS + 1 != ITCM_START_ADDRESS) {
+#endif /* __rtems__ */
+	dwRegionAttr =
+		MPU_AP_PRIVILEGED_READ_WRITE |
+		MPU_CalMPURegionSize(ITCM_END_ADDRESS - ITCM_START_ADDRESS) |
+		MPU_REGION_ENABLE;
+#ifdef __rtems__
+	} else {
+		dwRegionAttr = MPU_REGION_DISABLE;
+	}
+#endif /* __rtems__ */
+
+	MPU_SetRegion(dwRegionBaseAddr, dwRegionAttr);
+
+
+	/****************************************************
+	    Internal flash memory region --- Normal read-only
+	    (update to Strongly ordered in write accesses)
+	    START_Addr:-  0x00400000UL
+	    END_Addr:-    0x005FFFFFUL
+	******************************************************/
+
+	dwRegionBaseAddr =
+		IFLASH_START_ADDRESS |
+		MPU_REGION_VALID |
+		MPU_DEFAULT_IFLASH_REGION;      //2
+
+	dwRegionAttr =
+		MPU_AP_READONLY |
+		INNER_NORMAL_WB_NWA_TYPE(NON_SHAREABLE) |
+		MPU_CalMPURegionSize(IFLASH_END_ADDRESS - IFLASH_START_ADDRESS) |
+		MPU_REGION_ENABLE;
+
+	MPU_SetRegion(dwRegionBaseAddr, dwRegionAttr);
+
+	/****************************************************
+	    DTCM memory region --- Normal
+	    START_Addr:-  0x20000000L
+	    END_Addr:-    0x203FFFFFUL
+	******************************************************/
+
+	/* DTCM memory region */
+	dwRegionBaseAddr =
+		DTCM_START_ADDRESS |
+		MPU_REGION_VALID |
+		MPU_DEFAULT_DTCM_REGION;         //3
+
+#ifdef __rtems__
+	if (DTCM_END_ADDRESS + 1 != DTCM_START_ADDRESS) {
+#endif /* __rtems__ */
+	dwRegionAttr =
+		MPU_AP_PRIVILEGED_READ_WRITE |
+		INNER_NORMAL_NOCACHE_TYPE(NON_SHAREABLE) |
+		MPU_CalMPURegionSize(DTCM_END_ADDRESS - DTCM_START_ADDRESS) |
+		MPU_REGION_ENABLE;
+#ifdef __rtems__
+	} else {
+		dwRegionAttr = MPU_REGION_DISABLE;
+	}
+#endif /* __rtems__ */
+
+	MPU_SetRegion(dwRegionBaseAddr, dwRegionAttr);
+
+
+	/****************************************************
+	    SRAM Cacheable memory region --- Normal
+	    START_Addr:-  0x20400000UL
+	    END_Addr:-    0x2043FFFFUL
+	******************************************************/
+	/* SRAM memory  region */
+	dwRegionBaseAddr =
+		SRAM_FIRST_START_ADDRESS |
+		MPU_REGION_VALID |
+		MPU_DEFAULT_SRAM_REGION_1;         //4
+
+	dwRegionAttr =
+		MPU_AP_FULL_ACCESS    |
+		INNER_NORMAL_WB_NWA_TYPE(NON_SHAREABLE) |
+		MPU_CalMPURegionSize(SRAM_FIRST_END_ADDRESS - SRAM_FIRST_START_ADDRESS)
+		| MPU_REGION_ENABLE;
+
+	MPU_SetRegion(dwRegionBaseAddr, dwRegionAttr);
+
+
+	/****************************************************
+	    Internal SRAM second partition memory region --- Normal
+	    START_Addr:-  0x20440000UL
+	    END_Addr:-    0x2045FFFFUL
+	******************************************************/
+#ifndef __rtems__
+	/* SRAM memory region */
+	dwRegionBaseAddr =
+		SRAM_SECOND_START_ADDRESS |
+		MPU_REGION_VALID |
+		MPU_DEFAULT_SRAM_REGION_2;         //5
+
+	dwRegionAttr =
+		MPU_AP_FULL_ACCESS    |
+		INNER_NORMAL_WB_NWA_TYPE(NON_SHAREABLE) |
+		MPU_CalMPURegionSize(SRAM_SECOND_END_ADDRESS - SRAM_SECOND_START_ADDRESS) |
+		MPU_REGION_ENABLE;
+
+	MPU_SetRegion(dwRegionBaseAddr, dwRegionAttr);
+#else /* __rtems__ */
+	/* NOTE: The first SRAM region is increased so it covers the whole SRAM. If
+	 * the SRAM is something odd (like 384k on the SAME70Q21), the next higher
+	 * power of two will be used (in the example: 512k). That removes the need of
+	 * the second SRAM region. There is currently no memory after the SRAM so that
+	 * shouldn't be a problem. */
+#endif /* __rtems__ */
+
+#ifdef MPU_HAS_NOCACHE_REGION
+	dwRegionBaseAddr =
+		SRAM_NOCACHE_START_ADDRESS |
+		MPU_REGION_VALID |
+		MPU_NOCACHE_SRAM_REGION;          //11
+
+	dwRegionAttr =
+		MPU_AP_FULL_ACCESS    |
+		INNER_OUTER_NORMAL_NOCACHE_TYPE(SHAREABLE) |
+		MPU_CalMPURegionSize(NOCACHE_SRAM_REGION_SIZE) |
+		MPU_REGION_ENABLE;
+
+	MPU_SetRegion(dwRegionBaseAddr, dwRegionAttr);
+#endif
+
+	/****************************************************
+	    Peripheral memory region --- DEVICE Shareable
+	    START_Addr:-  0x40000000UL
+	    END_Addr:-    0x5FFFFFFFUL
+	******************************************************/
+	dwRegionBaseAddr =
+		PERIPHERALS_START_ADDRESS |
+		MPU_REGION_VALID |
+		MPU_PERIPHERALS_REGION;          //6
+
+	dwRegionAttr = MPU_AP_FULL_ACCESS |
+				   MPU_REGION_EXECUTE_NEVER |
+				   SHAREABLE_DEVICE_TYPE |
+				   MPU_CalMPURegionSize(PERIPHERALS_END_ADDRESS - PERIPHERALS_START_ADDRESS)
+				   | MPU_REGION_ENABLE;
+
+	MPU_SetRegion(dwRegionBaseAddr, dwRegionAttr);
+
+#ifdef __rtems__
+	dwRegionBaseAddr =
+		SYSTEM_START_ADDRESS |
+		MPU_REGION_VALID |
+		MPU_SYSTEM_REGION;
+
+	dwRegionAttr = MPU_AP_FULL_ACCESS |
+				   MPU_REGION_EXECUTE_NEVER |
+				   SHAREABLE_DEVICE_TYPE |
+				   MPU_CalMPURegionSize(SYSTEM_END_ADDRESS - SYSTEM_START_ADDRESS)
+				   | MPU_REGION_ENABLE;
+
+	MPU_SetRegion(dwRegionBaseAddr, dwRegionAttr);
+#endif /* __rtems__ */
+
+	/****************************************************
+	    External EBI memory  memory region --- Strongly Ordered
+	    START_Addr:-  0x60000000UL
+	    END_Addr:-    0x6FFFFFFFUL
+	******************************************************/
+	dwRegionBaseAddr =
+		EXT_EBI_START_ADDRESS |
+		MPU_REGION_VALID |
+		MPU_EXT_EBI_REGION;
+
+	dwRegionAttr =
+		MPU_AP_FULL_ACCESS |
+		/* External memory Must be defined with 'Device' or 'Strongly Ordered'
+		attribute for write accesses (AXI) */
+		STRONGLY_ORDERED_SHAREABLE_TYPE |
+		MPU_CalMPURegionSize(EXT_EBI_END_ADDRESS - EXT_EBI_START_ADDRESS) |
+		MPU_REGION_ENABLE;
+
+	MPU_SetRegion(dwRegionBaseAddr, dwRegionAttr);
+
+	/****************************************************
+	    SDRAM Cacheable memory region --- Normal
+	    START_Addr:-  0x70000000UL
+	    END_Addr:-    0x7FFFFFFFUL
+	******************************************************/
+	dwRegionBaseAddr =
+		SDRAM_START_ADDRESS |
+		MPU_REGION_VALID |
+		MPU_DEFAULT_SDRAM_REGION;        //7
+
+	dwRegionAttr =
+		MPU_AP_FULL_ACCESS    |
+		INNER_NORMAL_WB_RWA_TYPE(SHAREABLE) |
+		MPU_CalMPURegionSize(SDRAM_END_ADDRESS - SDRAM_START_ADDRESS) |
+		MPU_REGION_ENABLE;
+
+	MPU_SetRegion(dwRegionBaseAddr, dwRegionAttr);
+
+	/****************************************************
+	    QSPI memory region --- Normal
+	    START_Addr:-  0x80000000UL
+	    END_Addr:-    0x9FFFFFFFUL
+	******************************************************/
+	dwRegionBaseAddr =
+		QSPI_START_ADDRESS |
+		MPU_REGION_VALID |
+		MPU_QSPIMEM_REGION;              //8
+
+#ifdef __rtems__
+	if (QSPI_END_ADDRESS + 1 != QSPI_START_ADDRESS) {
+#endif /* __rtems__ */
+	dwRegionAttr =
+		MPU_AP_FULL_ACCESS |
+		INNER_NORMAL_WB_NWA_TYPE(SHAREABLE) |
+		MPU_CalMPURegionSize(QSPI_END_ADDRESS - QSPI_START_ADDRESS) |
+		MPU_REGION_ENABLE;
+#ifdef __rtems__
+	} else {
+		dwRegionAttr = MPU_REGION_DISABLE;
+	}
+#endif /* __rtems__ */
+
+	MPU_SetRegion(dwRegionBaseAddr, dwRegionAttr);
+
+
+	/****************************************************
+	    USB RAM Memory region --- Device
+	    START_Addr:-  0xA0100000UL
+	    END_Addr:-    0xA01FFFFFUL
+	******************************************************/
+	dwRegionBaseAddr =
+		USBHSRAM_START_ADDRESS |
+		MPU_REGION_VALID |
+		MPU_USBHSRAM_REGION;              //9
+
+	dwRegionAttr =
+		MPU_AP_FULL_ACCESS |
+		MPU_REGION_EXECUTE_NEVER |
+		SHAREABLE_DEVICE_TYPE |
+		MPU_CalMPURegionSize(USBHSRAM_END_ADDRESS - USBHSRAM_START_ADDRESS) |
+		MPU_REGION_ENABLE;
+
+	MPU_SetRegion(dwRegionBaseAddr, dwRegionAttr);
+
+
+	/* Enable the memory management fault , Bus Fault, Usage Fault exception */
+	SCB->SHCSR |= (SCB_SHCSR_MEMFAULTENA_Msk | SCB_SHCSR_BUSFAULTENA_Msk
+				   | SCB_SHCSR_USGFAULTENA_Msk);
+
+	/* Enable the MPU region */
+#ifndef __rtems__
+	MPU_Enable(MPU_ENABLE | MPU_PRIVDEFENA);
+#else /* __rtems__ */
+	MPU_Enable(MPU_ENABLE);
+#endif /* __rtems__ */
+
+	memory_sync();
+}
+
+#ifdef ENABLE_TCM
+
+#if defined (__ICCARM__) /* IAR Ewarm */
+	#pragma section = "CSTACK"
+	#pragma section = "CSTACK_DTCM"
+	#define SRAM_STACK_BASE     (__section_begin("CSTACK"))
+	#define DTCM_STACK_BASE     (__section_begin("CSTACK_DTCM"))
+	#define SRAM_STACK_LIMIT    (__section_end("CSTACK"))
+	#define DTCM_STACK_LIMIT    (__section_end("CSTACK_DTCM"))
+#elif defined (__CC_ARM)  /* MDK */
+	extern uint32_t Image$$ARM_LIB_STACK$$Base;
+	extern uint32_t Image$$ARM_LIB_STACK$$ZI$$Limit;
+	extern uint32_t Image$$DTCM_STACK$$Base;
+	extern uint32_t Image$$DTCM_STACK$$ZI$$Limit;
+	#define SRAM_STACK_BASE     (&Image$$ARM_LIB_STACK$$Base)
+	#define DTCM_STACK_BASE     (&Image$$DTCM_STACK$$Base)
+	#define SRAM_STACK_LIMIT    (&Image$$ARM_LIB_STACK$$ZI$$Limit)
+	#define DTCM_STACK_LIMIT    (&Image$$DTCM_STACK$$ZI$$Limit)
+#elif defined (__GNUC__)  /* GCC */
+	extern char _sdtcm_stack, _edtcm_stack, _sstack, _estack;
+	#define SRAM_STACK_BASE     ((void *)(&_sstack))
+	#define DTCM_STACK_BASE     ((void *)(&_sdtcm_stack))
+	#define SRAM_STACK_LIMIT    ((void *)(&_estack))
+	#define DTCM_STACK_LIMIT    ((void *)(&_edtcm_stack))
+#endif
+
+/** \brief  Change stack's location to DTCM
+
+    The function changes the stack's location from SRAM to DTCM
+ */
+void TCM_StackInit(void);
+void TCM_StackInit(void)
+{
+	uint32_t offset = (uint32_t)SRAM_STACK_LIMIT - (uint32_t)DTCM_STACK_LIMIT;
+	volatile char *dst = (volatile char *)DTCM_STACK_LIMIT;
+	volatile char *src = (volatile char *)SRAM_STACK_LIMIT;
+
+	/* copy stack data from SRAM to DTCM */
+	while (src > (volatile char *)SRAM_STACK_BASE)
+		*--dst = *--src;
+
+	__set_MSP(__get_MSP() - offset);
+}
+
+#endif
+
+
+/**
+ * \brief Performs the low-level initialization of the chip.
+ */
+extern WEAK void LowLevelInit(void)
+{
+
+	SystemInit();
+#ifndef MPU_EXAMPLE_FEATURE
+	_SetupMemoryRegion();
+#endif
+
+#if defined(FFT_DEMO) && (defined(__GNUC__) || defined(__CC_ARM))
+	/* Enabling the FPU */
+	SCB->CPACR |= 0x00F00000;
+	__DSB();
+	__ISB();
+#endif
+
+#if defined(ENABLE_TCM) && defined(__GNUC__)
+	volatile char *dst = &_sitcm;
+	volatile char *src = &_itcm_lma;
+
+	/* copy code_TCM from flash to ITCM */
+	while (dst < &_eitcm)
+		*dst++ = *src++;
+
+#endif
+}
Index: bsps/arm/atsam/contrib/libraries/libboard/source/board_memories.c
===================================================================
--- bsps/arm/atsam/contrib/libraries/libboard/source/board_memories.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libboard/source/board_memories.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,293 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+/**
+ * \file
+ *
+ * Implementation of memories configuration on board.
+ *
+ */
+
+/*----------------------------------------------------------------------------
+ *        Headers
+ *----------------------------------------------------------------------------*/
+#ifndef __rtems__
+#include "board.h"
+#else /* __rtems__ */
+#include <chip.h>
+#include <include/board_memories.h>
+#endif /* __rtems__ */
+
+/*----------------------------------------------------------------------------
+ *        Exported functions
+ *----------------------------------------------------------------------------*/
+
+#define SDRAM_BA0 (1 << 20)
+#define SDRAM_BA1 (1 << 21)
+
+
+#ifndef __rtems__
+uint32_t BOARD_SdramValidation(uint32_t baseAddr, uint32_t size)
+{
+	uint32_t i;
+	uint32_t ret = 1;
+	uint32_t *ptr32 = (uint32_t *) baseAddr;
+	uint16_t *ptr16 = (uint16_t *) baseAddr;
+	uint8_t *ptr8 = (uint8_t *) baseAddr;
+	/* Test for 55AA55AA/AA55AA55 pattern */
+	printf(" Test for 55AA55AA/AA55AA55 pattern ... \n\r");
+
+	for (i = 0; i < size; i ++) {
+		if (i & 1)
+			ptr32[i] = 0x55AA55AA;
+		else
+			ptr32[i] = 0xAA55AA55;
+
+		memory_barrier()
+	}
+
+	for (i = 0; i <  size; i++) {
+		if (i & 1) {
+			if (ptr32[i] != 0x55AA55AA) {
+				printf("-E- Expected:%x, read %x @ %x \n\r" ,
+					   0xAA55AA55, (unsigned)ptr32[i], (unsigned)(baseAddr + i));
+				ret = 0;
+
+			}
+		} else {
+			if (ptr32[i] != 0xAA55AA55) {
+				printf("-E- Expected:%x, read %x @ %x \n\r" ,
+					   0xAA55AA55 , (unsigned)ptr32[i], (unsigned)(baseAddr + i));
+				ret = 0;
+			}
+		}
+	}
+
+	if (!ret) return ret;
+
+	printf(" Test for BYTE accessing... \n\r");
+
+	/* Test for BYTE accessing */
+	for (i = 0; i < size; i ++)
+		ptr8[i] = (uint8_t)(i & 0xFF);
+
+	for (i = 0; i <  size; i++) {
+		if (ptr8[i] != (uint8_t)(i & 0xFF))  {
+			printf("-E- Expected:%x, read %x @ %x \n\r" ,
+				   (unsigned)(i & 0xFF), ptr8[i], (unsigned)(baseAddr + i));
+			ret = 0;
+		}
+	}
+
+	if (!ret) return ret;
+
+	printf(" Test for WORD accessing... \n\r");
+
+	/* Test for WORD accessing */
+	for (i = 0; i < size / 2; i ++)
+		ptr16[i] = (uint16_t)(i & 0xFFFF);
+
+	for (i = 0; i <  size / 2; i++) {
+		if (ptr16[i] != (uint16_t)(i & 0xFFFF))  {
+			printf("-E- Expected:%x, read %x @ %x \n\r" ,
+				   (unsigned)(i & 0xFFFF), ptr16[i], (unsigned)(baseAddr + i));
+			ret = 0;
+		}
+	}
+
+	if (!ret) return ret;
+
+	printf(" Test for DWORD accessing... \n\r");
+
+	/* Test for DWORD accessing */
+	for (i = 0; i < size / 4; i ++) {
+		ptr32[i] = (uint32_t)(i & 0xFFFFFFFF);
+		memory_barrier()
+	}
+
+	for (i = 0; i <  size / 4; i++) {
+		if (ptr32[i] != (uint32_t)(i & 0xFFFFFFFF))  {
+			printf("-E- Expected:%x, read %x @ %x \n\r" ,
+				   (unsigned)(i & 0xFFFFFFFF), (unsigned)ptr32[i], (unsigned)(baseAddr + i));
+			ret = 0;
+		}
+	}
+
+	return ret;
+}
+#endif /* __rtems__ */
+
+
+/**
+ * \brief Configures the EBI for SDRAM (IS42S16100E-7B) access.
+ */
+
+
+void BOARD_ConfigureSdram(void)
+{
+#ifndef __rtems__
+	const Pin pinsSdram[] = {BOARD_SDRAM_PINS};
+#endif /* __rtems__ */
+	volatile uint32_t i;
+	volatile uint8_t *pSdram = (uint8_t *) SDRAM_CS_ADDR;
+
+	/* Configure PIO */
+#ifndef __rtems__
+	PIO_Configure(pinsSdram, PIO_LISTSIZE(pinsSdram));
+#endif /* __rtems__ */
+	PMC_EnablePeripheral(ID_SDRAMC);
+	MATRIX->CCFG_SMCNFCS = CCFG_SMCNFCS_SDRAMEN;
+
+	/* 1. SDRAM features must be set in the configuration register:
+	asynchronous timings (TRC, TRAS, etc.), number of columns, rows,
+	CAS latency, and the data bus width. */
+#ifndef __rtems__
+	SDRAMC->SDRAMC_CR =
+		SDRAMC_CR_NC_COL8      // 8 column bits
+		| SDRAMC_CR_NR_ROW11     // 12 row bits (4K)
+		| SDRAMC_CR_CAS_LATENCY3 // CAS Latency 3
+		| SDRAMC_CR_NB_BANK2     // 2 banks
+		| SDRAMC_CR_DBW          // 16 bit
+		| SDRAMC_CR_TWR(5)
+		| SDRAMC_CR_TRC_TRFC(13) // 63ns   min
+		| SDRAMC_CR_TRP(5)       // Command period (PRE to ACT) 21 ns min
+		| SDRAMC_CR_TRCD(
+			5)      // Active Command to read/Write Command delay time 21ns min
+		| SDRAMC_CR_TRAS(9)      // Command period (ACT to PRE)  42ns min
+		| SDRAMC_CR_TXSR(15U);   // Exit self-refresh to active time  70ns Min
+#else /* __rtems__ */
+	SDRAMC->SDRAMC_CR = BOARD_Sdram_Config.sdramc_cr;
+#endif /* __rtems__ */
+
+	/* 2. For mobile SDRAM, temperature-compensated self refresh (TCSR), drive
+	strength (DS) and partial array self refresh (PASR) must be set in the
+	Low Power Register. */
+
+	/* 3. The SDRAM memory type must be set in the Memory Device Register.*/
+#ifndef __rtems__
+	SDRAMC->SDRAMC_MDR = SDRAMC_MDR_MD_SDRAM;
+#else /* __rtems__ */
+	SDRAMC->SDRAMC_MDR = BOARD_Sdram_Config.sdramc_mdr;
+#endif /* __rtems__ */
+
+	/* 4. A minimum pause of 200 ŠÌs is provided to precede any signal toggle.*/
+	for (i = 0; i < 100000; i++);
+
+	/* 5. (1)A NOP command is issued to the SDRAM devices. The application must
+	set Mode to 1 in the Mode Register and perform a write access to
+	any SDRAM address.*/
+	SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_NOP;
+#ifdef __rtems__
+	(void) SDRAMC->SDRAMC_MR;
+	__DMB();
+#endif /* __rtems__ */
+	*pSdram = 0;
+
+	for (i = 0; i < 100000; i++);
+
+	/* 6. An All Banks Precharge command is issued to the SDRAM devices.
+	The application must set Mode to 2 in the Mode Register and perform a write
+	access to any SDRAM address. */
+	SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_ALLBANKS_PRECHARGE;
+#ifdef __rtems__
+	(void) SDRAMC->SDRAMC_MR;
+	__DMB();
+#endif /* __rtems__ */
+	*pSdram = 0;
+
+	for (i = 0; i < 100000; i++);
+
+	/* 7. Eight auto-refresh (CBR) cycles are provided. The application must
+	set the Mode to 4 in the Mode Register and perform a write access to any
+	SDRAM location eight times.*/
+	for (i = 0; i < 8; i++) {
+		SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_AUTO_REFRESH;
+#ifdef __rtems__
+		(void) SDRAMC->SDRAMC_MR;
+	__DMB();
+#endif /* __rtems__ */
+		*pSdram = 0;
+	}
+
+	for (i = 0; i < 100000; i++);
+
+	/*8. A Mode Register set (MRS) cycle is issued to program the parameters of
+	the SDRAM devices, in particular CAS latency and burst length. The
+	application must set Mode to 3 in the Mode Register and perform a write
+	access to the SDRAM. The write address must be chosen so that BA[1:0]
+	are set to 0. For example, with a 16-bit 128 MB SDRAM (12 rows, 9 columns,
+	4 banks) bank address, the SDRAM write access should be done at the address
+	0x70000000.*/
+	SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_LOAD_MODEREG;
+#ifdef __rtems__
+	(void) SDRAMC->SDRAMC_MR;
+	__DMB();
+#endif /* __rtems__ */
+	*pSdram = 0;
+
+	for (i = 0; i < 100000; i++);
+
+	/*9. For mobile SDRAM initialization, an Extended Mode Register set (EMRS)
+	cycle is issued to program the SDRAM parameters (TCSR, PASR, DS). The
+	application must set Mode to 5 in the Mode Register and perform a write
+	access to the SDRAM. The write address must be chosen so that BA[1] or BA[0]
+	are set to 1.
+	For example, with a 16-bit 128 MB SDRAM, (12 rows, 9 columns, 4 banks) bank
+	address the SDRAM write access should be done at the address 0x70800000 or
+	0x70400000. */
+	//SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_EXT_LOAD_MODEREG;
+	// *((uint8_t *)(pSdram + SDRAM_BA0)) = 0;
+
+	/* 10. The application must go into Normal Mode, setting Mode to 0 in the
+	Mode Register and performing a write access at any location in the SDRAM. */
+	SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_NORMAL;
+#ifdef __rtems__
+	(void) SDRAMC->SDRAMC_MR;
+	__DMB();
+#endif /* __rtems__ */
+	*pSdram = 0;
+
+	for (i = 0; i < 100000; i++);
+
+	/* 11. Write the refresh rate into the count field in the SDRAMC Refresh
+	Timer register. (Refresh rate = delay between refresh cycles).
+	The SDRAM device requires a refresh every 15.625 ŠÌs or 7.81 ŠÌs.
+	With a 100 MHz frequency, the Refresh Timer Counter Register must be set
+	with the value 1562(15.625 ŠÌs x 100 MHz) or 781(7.81 ŠÌs x 100 MHz). */
+	// For IS42S16100E, 2048 refresh cycle every 32ms, every 15.625 ŠÌs
+	/* ((32 x 10(^-3))/2048) x150 x (10^6) */
+#ifndef __rtems__
+	SDRAMC->SDRAMC_TR = 1562;
+	SDRAMC->SDRAMC_CFR1 |= SDRAMC_CFR1_UNAL;
+#else /* __rtems__ */
+	SDRAMC->SDRAMC_TR = BOARD_Sdram_Config.sdramc_tr;
+	SDRAMC->SDRAMC_CFR1 = BOARD_Sdram_Config.sdramc_cfr1;
+#endif /* __rtems__ */
+	/* After initialization, the SDRAM devices are fully functional. */
+}
Index: bsps/arm/atsam/contrib/libraries/libboard/source/dbg_console.c
===================================================================
--- bsps/arm/atsam/contrib/libraries/libboard/source/dbg_console.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libboard/source/dbg_console.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,564 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+/**
+ * \file
+ *
+ * Implements UART console.
+ *
+ */
+
+/*----------------------------------------------------------------------------
+ *        Headers
+ *----------------------------------------------------------------------------*/
+
+#ifndef __rtems__
+#include "board.h"
+#else /* __rtems__ */
+#include <chip.h>
+#include <include/dbg_console.h>
+#endif /* __rtems__ */
+
+#include <stdio.h>
+#include <stdint.h>
+
+/*----------------------------------------------------------------------------
+ *        Definitions
+ *----------------------------------------------------------------------------*/
+
+/** Console baud rate always using 115200. */
+
+
+#ifndef __rtems__
+#define CONSOLE_BAUDRATE    115200
+
+/** EDBG used USART1 as the console, but LON support on USART1 only */
+#ifndef USART_LON
+	#define CONSOLE_EDBG
+#endif
+
+#if defined CONSOLE_EDBG
+	#define CONSOLE_ON_USART
+#else
+	#define CONSOLE_ON_UART
+#endif
+
+#if defined CONSOLE_ON_UART
+	#if defined SSC_AUDIO || defined USART_LON
+		/** Usart Hw interface used by the console (UART4). */
+		#define CONSOLE_UART       UART4
+
+		/** Pins description corresponding to Rxd,Txd, (UART pins) */
+		#define CONSOLE_PINS        {PINS_UART4}
+
+		#define CONSOLE_ID          ID_UART4
+	#else
+		/** Usart Hw interface used by the console (UART0). */
+		#define CONSOLE_UART       UART0
+
+		/** Pins description corresponding to Rxd,Txd, (UART pins) */
+		#define CONSOLE_PINS        {PINS_UART0}
+
+		#define CONSOLE_ID          ID_UART0
+
+	#endif
+#endif
+
+#if defined CONSOLE_ON_USART
+
+/** USART1 pin RX */
+#define PIN_USART1_RXD_DBG \
+	{PIO_PA21A_RXD1, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
+/** USART1 pin TX */
+#define PIN_USART1_TXD_DBG \
+	{PIO_PB4D_TXD1, PIOB, ID_PIOB, PIO_PERIPH_D, PIO_DEFAULT}
+#define PINS_USART1        PIN_USART1_TXD_DBG, PIN_USART1_RXD_DBG
+
+/** Usart Hw interface used by the console (Usart0). */
+#define CONSOLE_Usart      USART1
+
+/** Pins description corresponding to Rxd,Txd, (Usart pins) */
+#define CONSOLE_PINS      {PINS_USART1}
+
+#define CONSOLE_ID        ID_USART1
+#endif
+#else /* __rtems__ */
+#define CONSOLE_BAUDRATE ATSAM_CONSOLE_BAUD
+#if ATSAM_CONSOLE_DEVICE_TYPE == 1
+  #define CONSOLE_ON_UART
+  #if ATSAM_CONSOLE_DEVICE_INDEX == 4
+    #define CONSOLE_UART UART4
+    #define CONSOLE_ID ID_UART4
+  #elif ATSAM_CONSOLE_DEVICE_INDEX == 3
+    #define CONSOLE_UART UART3
+    #define CONSOLE_ID ID_UART3
+  #elif ATSAM_CONSOLE_DEVICE_INDEX == 2
+    #define CONSOLE_UART UART2
+    #define CONSOLE_ID ID_UART2
+  #elif ATSAM_CONSOLE_DEVICE_INDEX == 1
+    #define CONSOLE_UART UART1
+    #define CONSOLE_ID ID_UART1
+  #else
+    #define CONSOLE_UART UART0
+    #define CONSOLE_ID ID_UART0
+  #endif
+#else
+  #define CONSOLE_ON_USART
+  #if ATSAM_CONSOLE_DEVICE_INDEX == 4
+    #define CONSOLE_Usart USART4
+    #define CONSOLE_ID ID_USART4
+  #elif ATSAM_CONSOLE_DEVICE_INDEX == 3
+    #define CONSOLE_Usart USART3
+    #define CONSOLE_ID ID_USART3
+  #elif ATSAM_CONSOLE_DEVICE_INDEX == 2
+    #define CONSOLE_Usart USART2
+    #define CONSOLE_ID ID_USART2
+  #elif ATSAM_CONSOLE_DEVICE_INDEX == 1
+    #define CONSOLE_Usart USART1
+    #define CONSOLE_ID ID_USART1
+  #else
+    #define CONSOLE_Usart USART0
+    #define CONSOLE_ID ID_USART0
+  #endif
+#endif
+#endif /* __rtems__ */
+
+
+/*----------------------------------------------------------------------------
+ *        Variables
+ *----------------------------------------------------------------------------*/
+
+#ifndef __rtems__
+/** Is Console Initialized. */
+static uint8_t _ucIsConsoleInitialized = 0;
+#else /* __rtems__ */
+#define _ucIsConsoleInitialized 1
+#endif /* __rtems__ */
+
+/**
+ * \brief Configures an USART peripheral with the specified parameters.
+ *
+ * \param baudrate  Baudrate at which the USART should operate (in Hz).
+ * \param masterClock  Frequency of the system master clock (in Hz).
+ */
+extern void DBG_Configure(uint32_t baudrate, uint32_t masterClock)
+{
+
+#ifndef __rtems__
+	const Pin pPins[] = CONSOLE_PINS;
+#endif /* __rtems__ */
+#if defined CONSOLE_ON_UART
+	Uart *pUart = CONSOLE_UART;
+	/* Configure PIO */
+#ifndef __rtems__
+	PIO_Configure(pPins, PIO_LISTSIZE(pPins));
+#endif /* __rtems__ */
+
+	// Reset & disable receiver and transmitter, disable interrupts
+	pUart->UART_CR = UART_CR_RSTRX | UART_CR_RSTTX | UART_CR_RSTSTA;
+	pUart->UART_IDR = 0xFFFFFFFF;
+	PMC_EnablePeripheral(CONSOLE_ID);
+	pUart->UART_BRGR = (masterClock / baudrate) / 16;
+	// Configure mode register
+	pUart->UART_MR
+		= (UART_MR_CHMODE_NORMAL | UART_MR_PAR_NO
+		   | UART_MR_BRSRCCK_PERIPH_CLK);
+	// Enable receiver and transmitter
+	pUart->UART_CR = UART_CR_RXEN | UART_CR_TXEN;
+#endif
+
+#if defined CONSOLE_ON_USART
+	Usart *pUsart = CONSOLE_Usart;
+	// Disable the MATRIX registers write protection
+#ifndef __rtems__
+	MATRIX->MATRIX_WPMR  = MATRIX_WPMR_WPKEY_PASSWD;
+	MATRIX->CCFG_SYSIO |= CCFG_SYSIO_SYSIO4;
+
+	PIO_Configure(pPins, PIO_LISTSIZE(pPins));
+#endif /* __rtems__ */
+
+	// Reset & disable receiver and transmitter, disable interrupts
+	pUsart->US_CR = US_CR_RSTRX | US_CR_RSTTX | US_CR_RSTSTA;
+	pUsart->US_IDR = 0xFFFFFFFF;
+	PMC_EnablePeripheral(CONSOLE_ID);
+	pUsart->US_BRGR = (masterClock / baudrate) / 16;
+
+	// Configure mode register
+	pUsart->US_MR
+		= (US_MR_USART_MODE_NORMAL | US_MR_PAR_NO | US_MR_USCLKS_MCK
+		   | US_MR_CHRL_8_BIT);
+
+	// Enable receiver and transmitter
+	pUsart->US_CR = US_CR_RXEN | US_CR_TXEN;
+#endif
+#ifndef __rtems__
+	_ucIsConsoleInitialized = 1;
+
+	/* Disable buffering for printf(). */
+#if (defined (__GNUC__) && !defined (__SAMBA__))
+	setvbuf(stdout, (char *)NULL, _IONBF, 0);
+#endif
+#endif /* __rtems__ */
+}
+
+/**
+ * \brief Outputs a character on the UART line.
+ *
+ * \note This function is synchronous (i.e. uses polling).
+ * \param c  Character to send.
+ */
+extern void DBG_PutChar(uint8_t c)
+{
+#if defined CONSOLE_ON_UART
+	Uart *pUart = CONSOLE_UART;
+
+	if (!_ucIsConsoleInitialized)
+		DBG_Configure(CONSOLE_BAUDRATE, BOARD_MCK);
+
+	// Wait for the transmitter to be ready
+	while ((pUart->UART_SR & UART_SR_TXEMPTY) == 0);
+
+	// Send character
+	pUart->UART_THR = c;
+
+	// Wait for the transfer to complete
+	while ((pUart->UART_SR & UART_SR_TXEMPTY) == 0);
+
+#endif
+
+#if defined CONSOLE_ON_USART
+	Usart *pUsart = CONSOLE_Usart;
+
+	if (!_ucIsConsoleInitialized)
+		DBG_Configure(CONSOLE_BAUDRATE, BOARD_MCK);
+
+	// Wait for the transmitter to be ready
+	while ((pUsart->US_CSR & US_CSR_TXEMPTY) == 0);
+
+	// Send character
+	pUsart->US_THR = c;
+
+	// Wait for the transfer to complete
+	while ((pUsart->US_CSR & US_CSR_TXEMPTY) == 0);
+
+#endif
+}
+
+/**
+ * \brief Input a character from the UART line.
+ *
+ * \note This function is synchronous
+ * \return character received.
+ */
+extern uint32_t DBG_GetChar(void)
+{
+#if defined CONSOLE_ON_UART
+	Uart *pUart = CONSOLE_UART;
+
+	if (!_ucIsConsoleInitialized)
+		DBG_Configure(CONSOLE_BAUDRATE, BOARD_MCK);
+
+	while ((pUart->UART_SR & UART_SR_RXRDY) == 0);
+
+	return pUart->UART_RHR;
+#endif
+
+#if defined CONSOLE_ON_USART
+	Usart *pUsart = CONSOLE_Usart;
+
+	if (!_ucIsConsoleInitialized)
+		DBG_Configure(CONSOLE_BAUDRATE, BOARD_MCK);
+
+	while ((pUsart->US_CSR & US_CSR_RXRDY) == 0);
+
+	return pUsart->US_RHR;
+#endif
+}
+
+/**
+ * \brief Check if there is Input from UART line.
+ *
+ * \return true if there is Input.
+ */
+extern uint32_t DBG_IsRxReady(void)
+{
+#if defined CONSOLE_ON_UART
+	Uart *pUart = CONSOLE_UART;
+
+	if (!_ucIsConsoleInitialized)
+		DBG_Configure(CONSOLE_BAUDRATE, BOARD_MCK);
+
+	return (pUart->UART_SR & UART_SR_RXRDY);
+#endif
+
+#if defined CONSOLE_ON_USART
+	Usart *pUsart = CONSOLE_Usart;
+
+	if (!_ucIsConsoleInitialized)
+		DBG_Configure(CONSOLE_BAUDRATE, BOARD_MCK);
+
+	return (pUsart->US_CSR & US_CSR_RXRDY);
+#endif
+}
+
+#ifndef __rtems__
+/**
+ *  Displays the content of the given frame on the UART0.
+ *
+ *  \param pucFrame Pointer to the frame to dump.
+ *  \param dwSize   Buffer size in bytes.
+ */
+extern void DBG_DumpFrame(uint8_t *pucFrame, uint32_t dwSize)
+{
+	uint32_t dw;
+
+	for (dw = 0; dw < dwSize; dw++)
+		printf("%02X ", pucFrame[dw]);
+
+	printf("\n\r");
+}
+
+/**
+ *  Displays the content of the given buffer on the UART0.
+ *
+ *  \param pucBuffer  Pointer to the buffer to dump.
+ *  \param dwSize     Buffer size in bytes.
+ *  \param dwAddress  Start address to display
+ */
+extern void DBG_DumpMemory(uint8_t *pucBuffer, uint32_t dwSize,
+							uint32_t dwAddress)
+{
+	uint32_t i;
+	uint32_t j;
+	uint32_t dwLastLineStart;
+	uint8_t *pucTmp;
+
+	for (i = 0; i < (dwSize / 16); i++) {
+		printf("0x%08X: ", (unsigned int)(dwAddress + (i * 16)));
+		pucTmp = (uint8_t *)&pucBuffer[i * 16];
+
+		for (j = 0; j < 4; j++) {
+			printf("%02X%02X%02X%02X ",
+					pucTmp[0], pucTmp[1], pucTmp[2], pucTmp[3]);
+			pucTmp += 4;
+		}
+
+		pucTmp = (uint8_t *)&pucBuffer[i * 16];
+
+		for (j = 0; j < 16; j++)
+			DBG_PutChar(*pucTmp++);
+
+		printf("\n\r");
+	}
+
+	if ((dwSize % 16) != 0) {
+		dwLastLineStart = dwSize - (dwSize % 16);
+
+		printf("0x%08X: ", (unsigned int)(dwAddress + dwLastLineStart));
+
+		for (j = dwLastLineStart; j < dwLastLineStart + 16; j++) {
+			if ((j != dwLastLineStart) && (j % 4 == 0))
+				printf(" ");
+
+			if (j < dwSize)
+				printf("%02X", pucBuffer[j]);
+			else
+				printf("  ");
+		}
+
+		printf(" ");
+
+		for (j = dwLastLineStart; j < dwSize; j++)
+			DBG_PutChar(pucBuffer[j]);
+
+		printf("\n\r");
+	}
+}
+
+/**
+ * Reads an integer
+ *
+ * \param pdwValue  Pointer to a integer variable to contain the input value.
+ *
+ * \return success(1) or failure(0)
+ */
+extern uint32_t DBG_GetInteger(int32_t *pdwValue)
+{
+	uint8_t ucKey;
+	uint8_t ucNum = 0;
+	int32_t dwValue = 0;
+	int32_t sign = 1;
+
+	while (1) {
+		ucKey = DBG_GetChar();
+		DBG_PutChar(ucKey);
+
+		if (((ucKey == '-') || (ucKey == '+')) && (ucNum == 0)) {
+			if (ucKey == '-')
+				sign = -1;
+			else
+				sign = 1;
+
+			ucNum++;
+		} else {
+			if (ucKey >= '0' && ucKey <= '9') {
+				dwValue = (dwValue * 10) + (ucKey - '0');
+				ucNum++;
+			} else {
+				if (ucKey == 0x0D || ucKey == ' ') {
+					if (ucNum == 0) {
+						printf("\n\rWrite a number and press ENTER or SPACE!\n\r");
+						return 0;
+					} else {
+						printf("\n\r");
+						*pdwValue = dwValue * sign;
+
+						return 1;
+					}
+				} else {
+					printf("\n\r'%c' not a number or sign(+/-)!\n\r", ucKey);
+					return 0;
+				}
+			}
+		}
+	}
+}
+
+/**
+ * Reads an integer and check the value
+ *
+ * \param pdwValue  Pointer to a integer variable to contain the input value.
+ * \param dwMin     Minimum value
+ * \param dwMax     Maximum value
+ *
+ * \return success(1) or failure(0)
+ */
+extern uint32_t DBG_GetIntegerMinMax(int32_t *pdwValue, int32_t dwMin,
+									 int32_t dwMax)
+{
+	int32_t dwValue = 0;
+
+	if (DBG_GetInteger(&dwValue) == 0)
+		return 0;
+
+	if (dwValue < dwMin || dwValue > dwMax) {
+		printf("\n\rThe number have to be between %d and %d\n\r",
+				(int)dwMin, (int)dwMax);
+
+		return 0;
+	}
+
+	printf("\n\r");
+
+	*pdwValue = dwValue;
+
+	return 1;
+}
+
+/**
+ *  Reads an hexadecimal number
+ *
+ *  \param pdwValue  Pointer to the uint32_t variable to contain the input value.
+ */
+extern uint32_t DBG_GetHexa32(uint32_t *pdwValue)
+{
+	uint8_t ucKey;
+	uint32_t dw = 0;
+	uint32_t dwValue = 0;
+
+	for (dw = 0; dw < 8; dw++) {
+		ucKey = DBG_GetChar();
+		DBG_PutChar(ucKey);
+
+		if (ucKey >= '0' &&  ucKey <= '9')
+			dwValue = (dwValue * 16) + (ucKey - '0');
+		else {
+			if (ucKey >= 'A' &&  ucKey <= 'F')
+				dwValue = (dwValue * 16) + (ucKey - 'A' + 10);
+			else {
+				if (ucKey >= 'a' &&  ucKey <= 'f')
+					dwValue = (dwValue * 16) + (ucKey - 'a' + 10);
+				else {
+					printf("\n\rIt is not a hexadecimal character!\n\r");
+
+					return 0;
+				}
+			}
+		}
+	}
+
+	printf("\n\r");
+	*pdwValue = dwValue;
+
+	return 1;
+}
+
+#if defined __ICCARM__ /* IAR Ewarm 5.41+ */
+/**
+ * \brief Outputs a character on the UART.
+ *
+ * \param c  Character to output.
+ *
+ * \return The character that was output.
+ */
+extern WEAK signed int putchar(signed int c)
+{
+	DBG_PutChar(c);
+
+	return c;
+}
+
+#endif  // defined __ICCARM__
+extern WEAK int puts(const char *ptr)
+{
+
+	for (; *ptr != 0; ptr++)
+		DBG_PutChar(*ptr);
+
+	return 0;
+
+}
+
+extern WEAK char *gets(char *ptr)
+{
+	uint8_t ch = 0;
+
+	while (ch != '\r') {
+		ch = DBG_GetChar();
+		DBG_PutChar(ch);
+		*(ptr++) = ch;
+	}
+
+	*ptr = '\0';
+	return 0;
+
+}
+
+
+#endif /* __rtems__ */
Index: bsps/arm/atsam/contrib/libraries/libchip/source/acc.c
===================================================================
--- bsps/arm/atsam/contrib/libraries/libchip/source/acc.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libchip/source/acc.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,159 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+/** \addtogroup acc_module Working with ACC
+ *  \ingroup peripherals_module
+ * The ACC driver provides the interface to configure and use the ACC
+ * peripheral.\n
+ *
+ * It applies comparison on two inputs and gives a compare output.
+ *
+ * To Enable a ACC Comparison,the user has to follow these few steps:
+ * <ul>
+ * <li> Enable ACC peripheral clock by setting the corresponding bit in
+ *     PMC_PCER1 (PMC Peripheral Clock Enable Register 1)
+ * </li>
+ * <li> Reset the controller by asserting ACC_CR_SWRST in ACC_CR(ACC Control
+ * Register) </li>
+ * <li> Configure the mode as following steps:  </li>
+ * -#   Select inputs for SELMINUS and SELPLUS in ACC_MR (ACC Mode Register).
+ * -#   Enable Analog Comparator by setting ACEN in ACC_MR.
+ * -#   Configure Edge Type to detect different compare output.
+ * </li>
+ * <li> Wait until the automatic mask period expires by polling MASK bit in
+ *      ACC_ISR.
+ * </ul>
+ *
+ * For more accurate information, please look at the ACC section of the
+ * Datasheet.
+ *
+ * Related files :\n
+ * \ref acc.c\n
+ * \ref acc.h\n
+ */
+/*@{*/
+/*@}*/
+/**
+ * \file
+ *
+ * Implementation of Analog Comparator Controller (ACC).
+ *
+ */
+/*----------------------------------------------------------------------------
+ *        Headers
+ *----------------------------------------------------------------------------*/
+
+#include "chip.h"
+#include "acc.h"
+
+/*----------------------------------------------------------------------------
+ *        Exported functions
+ *----------------------------------------------------------------------------*/
+
+/**
+ * \brief Initialize the ACC controller
+ *
+ * \param pAcc Pointer to an Acc instance.
+ * \param idAcc ACC identifier
+ * \param ucSelplus input connected to inp, 0~7
+ * \param ucSelminus input connected to inm,0~7
+ * \param wAc_en Analog comparator enabled/disabled
+ * \param wEdge CF flag triggering mode
+ * \param wInvert INVert comparator output,use pattern defined in the device
+ * header file
+ */
+extern void ACC_Configure(Acc *pAcc, uint8_t idAcc, uint8_t ucSelplus,
+						   uint8_t ucSelminus, uint16_t wAc_en, uint16_t wEdge, uint16_t wInvert)
+{
+	/* Enable peripheral clock*/
+	PMC->PMC_PCER1 = 1 << (idAcc - 32);
+
+	/*  Reset the controller */
+	pAcc->ACC_CR |= ACC_CR_SWRST;
+
+	/*  Write to the MR register */
+	ACC_CfgModeReg(pAcc,
+					((ucSelplus << ACC_MR_SELPLUS_Pos) & ACC_MR_SELPLUS_Msk) |
+					((ucSelminus << ACC_MR_SELMINUS_Pos) & ACC_MR_SELMINUS_Msk) |
+					((wAc_en << 8) & ACC_MR_ACEN) |
+					((wEdge << ACC_MR_EDGETYP_Pos) & ACC_MR_EDGETYP_Msk) |
+					((wInvert << 12) & ACC_MR_INV));
+	/* set hysteresis and current option*/
+	pAcc->ACC_ACR = (ACC_ACR_ISEL_HISP
+					 | ((0x01 << ACC_ACR_HYST_Pos) & ACC_ACR_HYST_Msk));
+
+	/* Automatic Output Masking Period*/
+	while (pAcc->ACC_ISR & (uint32_t)ACC_ISR_MASK);
+}
+
+/**
+ * Return the Channel Converted Data
+ * \param pAcc Pointer to an Acc instance.
+ * \param ucSelplus input applied on ACC SELPLUS
+ * \param ucSelminus input applied on ACC SELMINUS
+ */
+extern void ACC_SetComparisonPair(Acc *pAcc, uint8_t ucSelplus,
+		uint8_t ucSelminus)
+{
+	uint32_t dwTemp;
+
+	assert(ucSelplus < 8 && ucSelminus < 8);
+
+	dwTemp = pAcc->ACC_MR;
+	pAcc->ACC_MR =
+		dwTemp & (uint32_t) ((~ACC_MR_SELMINUS_Msk) & (~ACC_MR_SELPLUS_Msk));
+
+	pAcc->ACC_MR |= (((ucSelplus << ACC_MR_SELPLUS_Pos) & ACC_MR_SELPLUS_Msk) |
+					((ucSelminus << ACC_MR_SELMINUS_Pos) & ACC_MR_SELMINUS_Msk));
+}
+
+/**
+ * Return Comparison Result
+ * \param pAcc Pointer to an Acc instance.
+ * \param dwStatus value of ACC_ISR
+ */
+extern uint32_t ACC_GetComparisonResult(Acc *pAcc, uint32_t dwStatus)
+{
+	uint32_t dwTemp = pAcc->ACC_MR;
+
+	if ((dwTemp & ACC_MR_INV) == ACC_MR_INV)  {
+		if (dwStatus & ACC_ISR_SCO) {
+			return 0; /* inn>inp*/
+		} else {
+			return 1;/* inp>inn*/
+		}
+	} else {
+		if (dwStatus & ACC_ISR_SCO) {
+			return 1; /* inp>inn*/
+		} else {
+			return 0;/* inn>inp*/
+		}
+	}
+}
+
Index: bsps/arm/atsam/contrib/libraries/libchip/source/aes.c
===================================================================
--- bsps/arm/atsam/contrib/libraries/libchip/source/aes.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libchip/source/aes.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,286 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+/** \addtogroup aes_module Working with AES
+ * \ingroup peripherals_module
+ * The AES driver provides the interface to configure and use the AES peripheral.
+ * \n
+ *
+ * The Advanced Encryption Standard (AES) specifies a FIPS-approved
+ * cryptographic algorithm that can be used to protect electronic data. The AES
+ * algorithm is a symmetric block cipher that can encrypt (encipher) and decrypt
+ * (decipher) information.
+ * Encryption converts data to an unintelligible form called ciphertext.
+ * Decrypting the ciphertext converts the data back into its original form,
+ * called plaintext. The CIPHER bit in the AES Mode Register (AES_MR) allows
+ * selection between the encryption and the decryption processes. The AES is
+ * capable of using cryptographic keys of 128/192/256 bits to encrypt and
+ * decrypt data in blocks of 128 bits.
+ * This 128-bit/192-bit/256-bit key is defined in the Key Registers (AES_KEYWRx)
+ * and set by AES_WriteKey(). The input to the encryption processes of the CBC,
+ * CFB, and OFB modes includes, in addition to the plaintext, a 128-bit data
+ * block called the initialization vector (IV),
+ * which must be set with AES_SetVector().
+ * The initialization vector is used in an initial step in the encryption of a
+ * message and in the corresponding decryption of the message.
+ * The Initialization Vector Registers are also used by the CTR mode to set the
+ * counter value.
+ *
+ * To Enable a AES encryption and decryption,the user has to follow these few
+ * steps:
+ * <ul>
+ * <li> A software triggered hardware reset of the AES interface is performed
+ * by AES_SoftReset().</li>
+ * <li> Configure AES algorithm mode, key mode, start mode and operation mode by
+ * AES_Configure(). </li>
+ * <li> Input AES data for encryption and decryption with function
+ * AES_SetInput() </li>
+ * <li> Set AES key with function AES_WriteKey(). </li>
+ * <li> To start the encryption or the decryption process with AES_Start()</li>
+ * <li> To get the encryption or decryption result by AES_GetOutput() </li>
+ * </ul>
+ *
+ *
+ * For more accurate information, please look at the AES section of the
+ * Datasheet.
+ *
+ * Related files :\n
+ * \ref aes.c\n
+ * \ref aes.h\n
+ */
+/*@{*/
+/*@}*/
+
+
+/**
+ * \file
+ *
+ * Implementation of Advanced Encryption Standard (AES)
+ *
+ */
+
+/*----------------------------------------------------------------------------
+ *        Headers
+ *----------------------------------------------------------------------------*/
+
+#include "chip.h"
+#include "aes.h"
+
+/*----------------------------------------------------------------------------
+ *        Exported functions
+ *----------------------------------------------------------------------------*/
+
+/**
+ * \brief Starts Manual encryption/decryption process.
+ */
+void AES_Start(void)
+{
+	AES->AES_CR = AES_CR_START;
+}
+
+/**
+ * \brief Resets the AES. A software triggered hardware reset of the AES
+ *  interface is performed.
+ */
+void AES_SoftReset(void)
+{
+	AES->AES_CR = AES_CR_SWRST;
+}
+
+/**
+ * \brief Configures an AES peripheral with the specified parameters.
+ *  \param mode  Desired value for the AES mode register (see the datasheet).
+ */
+void AES_Configure(uint32_t mode)
+{
+	AES->AES_MR = mode;
+}
+
+/**
+ * \brief Enables the selected interrupts sources on a AES peripheral.
+ * \param sources  Bitwise OR of selected interrupt sources.
+ */
+void AES_EnableIt(uint32_t sources)
+{
+	AES->AES_IER = sources;
+}
+
+/**
+ * \brief Disables the selected interrupts sources on a AES peripheral.
+ * \param sources  Bitwise OR of selected interrupt sources.
+ */
+void AES_DisableIt(uint32_t sources)
+{
+	AES->AES_IDR = sources;
+}
+
+/**
+ * \brief Get the current status register of the given AES peripheral.
+ * \return  AES status register.
+ */
+uint32_t AES_GetStatus(void)
+{
+	return AES->AES_ISR;
+}
+
+/**
+ * \brief Set the 128-bit/192-bit/256-bit cryptographic key used for
+ * encryption/decryption.
+ * \param pKey Pointer to a 16/24/32 bytes cipher key.
+ * \param keyLength length of key
+ */
+void AES_WriteKey(const uint32_t *pKey, uint32_t keyLength)
+{
+	AES->AES_KEYWR[0] = pKey[0];
+	AES->AES_KEYWR[1] = pKey[1];
+	AES->AES_KEYWR[2] = pKey[2];
+	AES->AES_KEYWR[3] = pKey[3];
+
+	if (keyLength >= 24) {
+		AES->AES_KEYWR[4] = pKey[4];
+		AES->AES_KEYWR[5] = pKey[5];
+	}
+
+	if (keyLength == 32) {
+		AES->AES_KEYWR[6] = pKey[6];
+		AES->AES_KEYWR[7] = pKey[7];
+	}
+}
+
+/**
+ * \brief Set the for 32-bit input Data allow to set the 128-bit data block
+ * used for encryption/decryption.
+ * \param data Pointer to the 16-bytes data to cipher/decipher.
+ */
+void AES_SetInput(uint32_t *data)
+{
+	uint8_t i;
+
+	for (i = 0; i < 4; i++)
+		AES->AES_IDATAR[i] = data[i];
+}
+
+/**
+ * \brief Get the four 32-bit data contain the 128-bit data block which
+ * has been encrypted/decrypted.
+ * \param data pointer to the word that has been encrypted/decrypted..
+ */
+void AES_GetOutput(uint32_t *data)
+{
+	uint8_t i;
+
+	for (i = 0; i < 4; i++)
+		data[i] = AES->AES_ODATAR[i];
+}
+
+/**
+ * \brief Set four 64-bit initialization vector data block, which is used by
+ * some modes of operation as an additional initial input.
+ * \param pVector point to the word of the initialization vector.
+ */
+void AES_SetVector(const uint32_t *pVector)
+{
+	AES->AES_IVR[0] = pVector[0];
+	AES->AES_IVR[1] = pVector[1];
+	AES->AES_IVR[2] = pVector[2];
+	AES->AES_IVR[3] = pVector[3];
+}
+
+/**
+ * \brief Set Length in bytes of the AAD data that is to be processed.
+ * \param len Length.
+ */
+void AES_SetAadLen(uint32_t len)
+{
+	AES->AES_AADLENR = len;
+}
+
+/**
+ * \brief Set Length in bytes of the Length in bytes of the
+ * plaintext/ciphertext (C) data that is to be processed..
+ * \param len Length.
+ */
+void AES_SetDataLen(uint32_t len)
+{
+	AES->AES_CLENR = len;
+}
+
+/**
+ * \brief Set The four 32-bit Hash Word registers expose the intermediate GHASH
+ * value. May be read to save the current GHASH value so processing can later be
+ * resumed, presumably on a later message fragment. modes of operation as an
+ * additional initial input.
+ * \param hash point to the word of the hash.
+ */
+void AES_SetGcmHash(uint32_t *hash)
+{
+	uint8_t i;
+
+	for (i = 0; i < 4; i++)
+		AES->AES_GHASHR[i] = hash[i];
+}
+
+
+/**
+ * \brief Get The four 32-bit Tag which contain the final 128-bit GCM
+ * Authentication tag ¡°T¡± when GCM processing is complete.
+ * \param tag point to the word of the tag.
+ */
+void AES_GetGcmTag(uint32_t *tag)
+{
+	uint8_t i;
+
+	for (i = 0; i < 4; i++)
+		tag[i] = AES->AES_TAGR[i];
+}
+
+/**
+ * \brief Reports the current value of the 32-bit GCM counter
+ * \param counter Point to value of GCM counter.
+ */
+void AES_GetGcmCounter(uint32_t *counter)
+{
+	*counter = AES->AES_CTRR;
+}
+
+
+/**
+ * \brief Get the four 32-bit data contain the 128-bit H value computed from
+ * the KEYW value
+ * \param data point to the word that has been encrypted/decrypted.
+ */
+void AES_GetGcmH(uint32_t *h)
+{
+	uint8_t i;
+
+	for (i = 0; i < 4; i++)
+		h[i] = AES->AES_GCMHR[i];
+}
+
+
Index: bsps/arm/atsam/contrib/libraries/libchip/source/afe_dma.c
===================================================================
--- bsps/arm/atsam/contrib/libraries/libchip/source/afe_dma.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libchip/source/afe_dma.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,256 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+/** \addtogroup afe_dma_module Working with AFE (DMA support)
+ *  \ingroup peripherals_module
+ * The afec driver provides the interface to configure and use the afecC
+ * peripheral with DMA support.\n
+ *
+ * For more accurate information, please look at the AFEC section of the
+ * Datasheet.
+ *
+ * Related files :\n
+ * \ref afe_dma.c\n
+ * \ref afe_dma.h\n
+ */
+/*@{*/
+/*@}*/
+/**
+ * \file
+ *
+ *
+ */
+/*----------------------------------------------------------------------------
+ *        Headers
+ *----------------------------------------------------------------------------*/
+
+#include "chip.h"
+#include "afe_dma.h"
+#include "xdmad.h"
+
+#include <stdint.h>
+#include <assert.h>
+
+/*  DMA driver instance */
+static uint32_t afeDmaRxChannel;
+
+/*----------------------------------------------------------------------------
+ *        Local functions
+ *----------------------------------------------------------------------------*/
+
+/**
+ * \brief AFE xDMA Rx callback
+ * Invoked on AFE DMA reception done.
+ * \param channel DMA channel.
+ * \param pArg Pointer to callback argument - Pointer to AfeDma instance.
+ */
+static void Afe_Rx_Cb(uint32_t channel, AfeDma *pArg)
+{
+	AfeCmd *pAfedCmd = pArg->pCurrentCommand;
+
+	if (channel != afeDmaRxChannel)
+		return;
+
+	/* Configure and enable interrupt on RC compare */
+	NVIC_ClearPendingIRQ(XDMAC_IRQn);
+	NVIC_DisableIRQ(XDMAC_IRQn);
+
+	/* Release the DMA channels */
+	XDMAD_FreeChannel(pArg->pXdmad, afeDmaRxChannel);
+	SCB_InvalidateDCache_by_Addr(pAfedCmd->pRxBuff, pAfedCmd->RxSize);
+	/* Release the dataflash semaphore */
+	pArg->semaphore++;
+
+	/* Invoke the callback associated with the current command */
+	if (pAfedCmd && pAfedCmd->callback)
+		pAfedCmd->callback(0, pAfedCmd->pArgument);
+}
+
+/**
+ * \brief Configure the DMA Channels: 0 RX.
+ * Channels are disabled after configure.
+ * \param pXdmad Pointer to a AfeDma instance
+ * \returns 0 if the dma channel configuration successfully; otherwise returns
+ * AFE_ERROR_XXX.
+ */
+static uint8_t _AfeConfigureDmaChannels(AfeDma *pAfed)
+{
+
+	/* Driver initialize */
+	XDMAD_FreeChannel(pAfed->pXdmad, afeDmaRxChannel);
+
+	/* Allocate a DMA channel for AFE0/1 RX. */
+	afeDmaRxChannel =
+		XDMAD_AllocateChannel(pAfed->pXdmad, pAfed->afeId, XDMAD_TRANSFER_MEMORY);
+
+	if (afeDmaRxChannel == XDMAD_ALLOC_FAILED)
+		return AFE_ERROR;
+
+	/* Setup callbacks for AFE0/1 RX */
+	XDMAD_SetCallback(pAfed->pXdmad, afeDmaRxChannel,
+					  (XdmadTransferCallback)Afe_Rx_Cb, pAfed);
+
+	if (XDMAD_PrepareChannel(pAfed->pXdmad, afeDmaRxChannel))
+		return AFE_ERROR;
+
+	return AFE_OK;
+}
+
+/**
+ * \brief Configure the DMA source and destination with Linker List mode.
+ * \param pXdmad Pointer to a AfeDma instance
+ * \param pCommand Pointer to AfeCmd instance
+ * \param AfeCmd Pointer to command
+ */
+
+static uint8_t _Afe_configureLinkList(Afec *pAfeHw, void *pXdmad,
+									  AfeCmd *pCommand)
+{
+	uint32_t xdmaCndc, xdmaInt;
+	sXdmadCfg xdmadRxCfg;
+	uint32_t afeId;
+
+	if ((unsigned int)pAfeHw == (unsigned int)AFEC0) afeId = ID_AFEC0;
+
+	if ((unsigned int)pAfeHw == (unsigned int)AFEC1) afeId = ID_AFEC1;
+
+	/* Setup RX Link List */
+	xdmadRxCfg.mbr_ubc = XDMA_UBC_NVIEW_NDV0 |
+						 XDMA_UBC_NDE_FETCH_DIS |
+						 XDMA_UBC_NDEN_UPDATED |
+						 pCommand->RxSize;
+
+	xdmadRxCfg.mbr_da = (uint32_t)pCommand->pRxBuff;
+	xdmadRxCfg.mbr_sa = (uint32_t) & (pAfeHw->AFEC_LCDR);
+	xdmadRxCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN |
+						 XDMAC_CC_MBSIZE_SINGLE |
+						 XDMAC_CC_DSYNC_PER2MEM |
+						 XDMAC_CC_CSIZE_CHK_1 |
+						 XDMAC_CC_DWIDTH_WORD |
+						 XDMAC_CC_SIF_AHB_IF1 |
+						 XDMAC_CC_DIF_AHB_IF1 |
+						 XDMAC_CC_SAM_FIXED_AM |
+						 XDMAC_CC_DAM_INCREMENTED_AM |
+						 XDMAC_CC_PERID(
+							 XDMAIF_Get_ChannelNumber(afeId, XDMAD_TRANSFER_RX));
+
+	xdmadRxCfg.mbr_bc = 0;
+	xdmadRxCfg.mbr_sus = 0;
+	xdmadRxCfg.mbr_dus = 0;
+
+	xdmaInt =  (XDMAC_CIE_BIE   |
+				XDMAC_CIE_DIE   |
+				XDMAC_CIE_FIE   |
+				XDMAC_CIE_RBIE  |
+				XDMAC_CIE_WBIE  |
+				XDMAC_CIE_ROIE);
+	xdmaCndc = 0;
+
+	if (XDMAD_ConfigureTransfer(pXdmad, afeDmaRxChannel,
+								 &xdmadRxCfg, xdmaCndc, 0, xdmaInt))
+		return AFE_ERROR;
+
+	return AFE_OK;
+}
+
+/*----------------------------------------------------------------------------
+ *        Exported functions
+ *----------------------------------------------------------------------------*/
+
+
+/**
+ * \brief Initializes the AfeDma structure and the corresponding AFE & DMA .
+ * hardware select value.
+ * The driver will uses DMA channel 0 for RX .
+ * The DMA channels are freed automatically when no DMA command processing.
+ *
+ * \param pAfed  Pointer to a AfeDma instance.
+ * \param pAfeHw Associated Afe peripheral.
+ * \param AfeId  Afe peripheral identifier.
+ * \param pDmad  Pointer to a Dmad instance.
+ */
+uint32_t Afe_ConfigureDma(AfeDma *pAfed ,
+						Afec *pAfeHw ,
+						uint8_t AfeId,
+						sXdmad *pXdmad)
+{
+	/* Initialize the Afe structure */
+	pAfed->pAfeHw = pAfeHw;
+	pAfed->afeId  = AfeId;
+	pAfed->semaphore = 1;
+	pAfed->pCurrentCommand = 0;
+	assert(pXdmad == &XDMAD_Instance);
+	pAfed->pXdmad = pXdmad;
+	return 0;
+}
+
+/**
+ * \brief Starts a AFE transfer. This is a non blocking function. It will
+ *  return as soon as the transfer is started.
+ *
+ * \param pAfed  Pointer to a AfeDma instance.
+ * \param pCommand Pointer to the Afe command to execute.
+ * \returns 0 if the transfer has been started successfully; otherwise returns
+ * AFE_ERROR_LOCK is the driver is in use, or AFE_ERROR if the command is not
+ * valid.
+ */
+uint32_t Afe_SendData(AfeDma *pAfed, AfeCmd *pCommand)
+{
+	Afec *pAfeHw = pAfed->pAfeHw;
+
+	/* Try to get the dataflash semaphore */
+	if (pAfed->semaphore == 0)
+
+		return AFE_ERROR_LOCK;
+
+	pAfed->semaphore--;
+
+	// Initialize the callback
+	pAfed->pCurrentCommand = pCommand;
+
+	/* Initialize DMA controller using channel 0 for RX. */
+	if (_AfeConfigureDmaChannels(pAfed))
+		return AFE_ERROR_LOCK;
+
+	/* Configure and enable interrupt on RC compare */
+	NVIC_ClearPendingIRQ(XDMAC_IRQn);
+	NVIC_SetPriority(XDMAC_IRQn , 1);
+	NVIC_EnableIRQ(XDMAC_IRQn);
+
+	if (_Afe_configureLinkList(pAfeHw, pAfed->pXdmad, pCommand))
+		return AFE_ERROR_LOCK;
+
+	AFEC_StartConversion(pAfeHw);
+
+	/* Start DMA 0(RX) */
+	if (XDMAD_StartTransfer(pAfed->pXdmad, afeDmaRxChannel))
+		return AFE_ERROR_LOCK;
+
+	return AFE_OK;;
+}
Index: bsps/arm/atsam/contrib/libraries/libchip/source/afec.c
===================================================================
--- bsps/arm/atsam/contrib/libraries/libchip/source/afec.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libchip/source/afec.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,458 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+/** \addtogroup AFEC_module Working with AFE
+ * \ingroup peripherals_module
+ * The AFE driver provides the interface to configure and use the AFE peripheral.
+ * \n
+ *
+ * It converts the analog input to digital format. The converted result could be
+ * 12bit or 10bit. The AFE supports up to 16 analog lines.
+ *
+ * To Enable a AFE conversion,the user has to follow these few steps:
+ * <ul>
+ * <li> Select an appropriate reference voltage on ADVREF   </li>
+ * <li> Configure the AFE according to its requirements and special needs,which
+ * could be  broken down into several parts:
+ * -#   Select the resolution by setting or clearing AFEC_MR_LOWRES bit in
+ *      AFEC_MR (Mode Register)
+ * -#   Set AFE clock by setting AFEC_MR_PRESCAL bits in AFEC_MR, the clock is
+ *      calculated with AFEClock = MCK / ((PRESCAL+1) * 2)
+ * -#   Set Startup Time,Tracking Clock cycles and Transfer Clock respectively
+ *      in AFEC_MR.
+ </li>
+ * <li> Start conversion by setting AFEC_CR_START in AFEC_CR. </li>
+ * </ul>
+ *
+ * For more accurate information, please look at the AFE section of the
+ * Datasheet.
+ *
+ * Related files :\n
+ * \ref afec.c\n
+ * \ref afec.h\n
+ * \ref afe_dma.c\n
+ * \ref afe_dma.h\n
+ */
+/*@{*/
+/*@}*/
+/**
+ * \file
+ *
+ * Implementation of Analog-to-Digital Converter (AFE).
+ *
+ */
+/*----------------------------------------------------------------------------
+ *        Headers
+ *----------------------------------------------------------------------------*/
+
+#include "chip.h"
+
+
+/*----------------------------------------------------------------------------
+ *        Local variables
+ *----------------------------------------------------------------------------*/
+
+/** Current working clock */
+static uint32_t dwAFEClock = 0;
+
+/*----------------------------------------------------------------------------
+ *        Exported functions
+ *----------------------------------------------------------------------------*/
+
+/**
+ * \brief Initialize the AFE controller
+ *
+ * \param pAFE Pointer to an AFE instance.
+ * \param dwID AFE Index
+ */
+extern void AFEC_Initialize(Afec *pAFE, uint32_t dwID)
+{
+	/* Enable peripheral clock*/
+	PMC_EnablePeripheral(dwID);
+
+	/*  Reset the controller */
+	pAFE->AFEC_CR = AFEC_CR_SWRST;
+
+	/* Reset Mode Register */
+	pAFE->AFEC_MR = 0;
+}
+
+/**
+ * \brief Set AFE clock.
+ *
+ * \param pAFE Pointer to an AFE instance.
+ * \param dwPres prescale value
+ * \param dwMck Board MCK (Hz)
+ *
+ * \return AFE clock
+ */
+
+extern uint32_t AFEC_SetClock(Afec *pAFE, uint32_t dwClk, uint32_t dwMck)
+{
+	uint32_t dwPres, dwMr;
+	/* Formula for PRESCAL is:
+	   PRESCAL = peripheral clock/ fAFE Clock - 1 */
+
+	dwPres = (dwMck) / (dwClk) - 1;
+	dwMr = AFEC_MR_PRESCAL(dwPres);
+
+	if (dwMr == 0) return 0;
+
+	dwMr |= (pAFE->AFEC_MR & ~AFEC_MR_PRESCAL_Msk);
+	pAFE->AFEC_MR = dwMr;
+	dwAFEClock = dwMck / (dwPres + 1);
+	return dwAFEClock;
+}
+
+/**
+ * \brief Set AFE timing.
+ *
+ * \param pAFE Pointer to an AFE instance.
+ * \param dwStartup startup value
+ * \param dwTracking tracking value
+ * \param dwSettling settling value
+ */
+extern void AFEC_SetTiming(Afec *pAFE, uint32_t dwStartup, uint32_t dwTracking,
+							uint32_t dwSettling)
+{
+	uint32_t dwMr;
+
+	dwMr = pAFE->AFEC_MR;
+	dwMr &= (~AFEC_MR_STARTUP_Msk) & (~AFEC_MR_TRACKTIM_Msk) &
+			(~AFEC_MR_SETTLING_Msk);
+
+	/* Formula:
+	 *     Startup  Time = startup value / AFEClock
+	 *     Transfer Time = (TRANSFER * 2 + 3) / AFEClock
+	 *     Tracking Time = (TRACKTIM + 1) / AFEClock
+	 *     Settling Time = settling value / AFEClock
+	 */
+	dwMr |= dwStartup | dwTracking | dwSettling;
+	pAFE->AFEC_MR |= dwMr;
+}
+
+/**
+ * \brief Set AFE trigger.
+ *
+ * \param pAFE Pointer to an AFE instance.
+ * \param dwTrgSel Trigger selection
+ */
+extern void AFEC_SetTrigger(Afec *pAFE, uint32_t dwTrgSel)
+{
+	uint32_t dwMr;
+
+	dwMr = pAFE->AFEC_MR;
+	dwMr &= ~AFEC_MR_TRGSEL_Msk;
+	dwMr |= dwTrgSel;
+	pAFE->AFEC_MR |= dwMr;
+}
+
+
+/**
+ * \brief Enable/Disable sleep mode.
+ *
+ * \param pAFE Pointer to an AFE instance.
+ * \param bEnDis Enable/Disable sleep mode.
+ */
+extern void AFEC_SetSleepMode(Afec *pAFE, uint8_t bEnDis)
+{
+	if (bEnDis)
+		pAFE->AFEC_MR |=  AFEC_MR_SLEEP;
+	else
+		pAFE->AFEC_MR &= ~AFEC_MR_SLEEP;
+}
+
+/**
+ * \brief Enable/Disable fast wake up.
+ *
+ * \param pAFE Pointer to an AFE instance.
+ * \param bEnDis Enable/Disable fast wake up in sleep mode.
+ */
+extern void AFEC_SetFastWakeup(Afec *pAFE, uint8_t bEnDis)
+{
+	if (bEnDis)
+		pAFE->AFEC_MR |=  AFEC_MR_FWUP;
+	else
+		pAFE->AFEC_MR &= ~AFEC_MR_FWUP;
+}
+
+/**
+ * \brief Enable/Disable sequence mode.
+ *
+ * \param pAFE  Pointer to an AFE instance.
+ * \param bEnDis Enable/Disable sequence mode.
+ */
+extern void AFEC_SetSequenceMode(Afec *pAFE, uint8_t bEnDis)
+{
+	if (bEnDis) {
+		/* User Sequence Mode: The sequence respects what is defined in
+		   AFEC_SEQR1 and AFEC_SEQR2 */
+		pAFE->AFEC_MR |=  AFEC_MR_USEQ;
+	} else {
+		/* Normal Mode: The controller converts channels in a simple
+		numeric order. */
+		pAFE->AFEC_MR &= ~AFEC_MR_USEQ;
+	}
+}
+
+/**
+ * \brief Set channel sequence.
+ *
+ * \param pAFE   Pointer to an AFE instance.
+ * \param dwSEQ1 Sequence 1 ~ 8  channel number.
+ * \param dwSEQ2 Sequence 9 ~ 16 channel number.
+ */
+extern void AFEC_SetSequence(Afec *pAFE, uint32_t dwSEQ1, uint32_t dwSEQ2)
+{
+	pAFE->AFEC_SEQ1R = dwSEQ1;
+	pAFE->AFEC_SEQ2R = dwSEQ2;
+}
+
+/**
+ * \brief Set channel sequence by given channel list.
+ *
+ * \param pAFE    Pointer to an AFE instance.
+ * \param ucChList Channel list.
+ * \param ucNumCh  Number of channels in list.
+ */
+extern void AFEC_SetSequenceByList(Afec *pAFE, uint8_t ucChList[],
+									uint8_t ucNumCh)
+{
+	uint8_t i;
+	uint8_t ucShift;
+
+	pAFE->AFEC_SEQ1R = 0;
+
+	for (i = 0, ucShift = 0; i < 8; i ++, ucShift += 4) {
+		if (i >= ucNumCh) return;
+
+		pAFE->AFEC_SEQ1R |= ucChList[i] << ucShift;
+
+	}
+
+	pAFE->AFEC_SEQ2R = 0;
+
+	for (ucShift = 0; i < 16; i ++, ucShift += 4) {
+		if (i >= ucNumCh) return;
+
+		pAFE->AFEC_SEQ2R |= ucChList[i] << ucShift;
+	}
+}
+
+/**
+ * \brief Set analog change.
+ * IF enabled, it allows different analog settings for each channel,
+ * otherwise, DIFF0, GAIN0 and OFF0 are used for all channels.
+ *
+ * \param pAFE   Pointer to an AFE instance.
+ * \param bEnDis Enable/Disable.
+ */
+extern void AFEC_SetAnalogChange(Afec *pAFE, uint8_t bEnDis)
+{
+	if (bEnDis)
+		pAFE->AFEC_MR |=  AFEC_MR_ONE;
+	else
+		pAFE->AFEC_MR &= ~AFEC_MR_ONE;
+}
+
+/**
+ * \brief Set "TAG" mode, show channel number in last data or not.
+ *
+ * \param pAFE   Pointer to an AFE instance.
+ * \param bEnDis Enable/Disable TAG value.
+ */
+extern void AFEC_SetTagEnable(Afec *pAFE, uint8_t bEnDis)
+{
+	if (bEnDis)
+		pAFE->AFEC_EMR |=  AFEC_EMR_TAG;
+	else
+		pAFE->AFEC_EMR &= ~AFEC_EMR_TAG;
+}
+
+/**
+ * \brief Set compare channel.
+ *
+ * \param pAFE Pointer to an AFE instance.
+ * \param dwChannel channel number to be set,16 for all channels
+ */
+extern void AFEC_SetCompareChannel(Afec *pAFE, uint32_t dwChannel)
+{
+	assert(dwChannel <= 16);
+
+	if (dwChannel < 16) {
+		pAFE->AFEC_EMR &= ~(AFEC_EMR_CMPALL);
+		pAFE->AFEC_EMR &= ~(AFEC_EMR_CMPSEL_Msk);
+		pAFE->AFEC_EMR |= (dwChannel << AFEC_EMR_CMPSEL_Pos);
+	} else
+		pAFE->AFEC_EMR |= AFEC_EMR_CMPALL;
+}
+
+/**
+ * \brief Set compare mode.
+ *
+ * \param pAFE Pointer to an AFE instance.
+ * \param dwMode compare mode
+ */
+extern void AFEC_SetCompareMode(Afec *pAFE, uint32_t dwMode)
+{
+	pAFE->AFEC_EMR &= ~(AFEC_EMR_CMPMODE_Msk);
+	pAFE->AFEC_EMR |= (dwMode & AFEC_EMR_CMPMODE_Msk);
+}
+
+/**
+ * \brief Set comparison window.
+ *
+ * \param pAFE Pointer to an AFE instance.
+ * \param dwHi_Lo Comparison Window
+ */
+extern void AFEC_SetComparisonWindow(Afec *pAFE, uint32_t dwHi_Lo)
+{
+	pAFE->AFEC_CWR = dwHi_Lo;
+}
+
+/**
+ * \brief Return the Channel Converted Data
+ *
+ * \param pAFE Pointer to an AFE instance.
+ * \param dwChannel channel to get converted value
+ */
+extern uint32_t AFEC_GetConvertedData(Afec *pAFE, uint32_t dwChannel)
+{
+	uint32_t dwData = 0;
+	assert(dwChannel < 12);
+	pAFE->AFEC_CSELR = dwChannel;
+	dwData = pAFE->AFEC_CDR;
+
+	return dwData;
+}
+
+
+/**
+ * Sets the AFE startup time.
+ * \param pAFE  Pointer to an AFE instance.
+ * \param dwUs  Startup time in uS.
+ */
+void AFEC_SetStartupTime(Afec *pAFE, uint32_t dwUs)
+{
+	uint32_t dwStart;
+	uint32_t dwMr;
+
+	if (dwAFEClock == 0) return;
+
+	/* Formula for STARTUP is:
+	   STARTUP = (time x AFECLK) / (1000000) - 1
+	   Division multiplied by 10 for higher precision */
+
+	dwStart = (dwUs * dwAFEClock) / (100000);
+
+	if (dwStart % 10) dwStart /= 10;
+	else {
+		dwStart /= 10;
+
+		if (dwStart) dwStart --;
+	}
+
+	if      (dwStart >  896) dwMr = AFEC_MR_STARTUP_SUT960;
+	else if (dwStart >  832) dwMr = AFEC_MR_STARTUP_SUT896;
+	else if (dwStart >  768) dwMr = AFEC_MR_STARTUP_SUT832;
+	else if (dwStart >  704) dwMr = AFEC_MR_STARTUP_SUT768;
+	else if (dwStart >  640) dwMr = AFEC_MR_STARTUP_SUT704;
+	else if (dwStart >  576) dwMr = AFEC_MR_STARTUP_SUT640;
+	else if (dwStart >  512) dwMr = AFEC_MR_STARTUP_SUT576;
+	else if (dwStart >  112) dwMr = AFEC_MR_STARTUP_SUT512;
+	else if (dwStart >   96) dwMr = AFEC_MR_STARTUP_SUT112;
+	else if (dwStart >   80) dwMr = AFEC_MR_STARTUP_SUT96;
+	else if (dwStart >   64) dwMr = AFEC_MR_STARTUP_SUT80;
+	else if (dwStart >   24) dwMr = AFEC_MR_STARTUP_SUT64;
+	else if (dwStart >   16) dwMr = AFEC_MR_STARTUP_SUT24;
+	else if (dwStart >    8) dwMr = AFEC_MR_STARTUP_SUT16;
+	else if (dwStart >    0) dwMr = AFEC_MR_STARTUP_SUT8;
+	else                     dwMr = AFEC_MR_STARTUP_SUT0;
+
+	dwMr |= pAFE->AFEC_MR & ~AFEC_MR_STARTUP_Msk;
+	pAFE->AFEC_MR = dwMr;
+}
+
+
+/**
+ * Set AFE tracking time
+ * \param pAFE  Pointer to an AFE instance.
+ * \param dwNs  Tracking time in nS.
+ */
+void AFEC_SetTrackingTime(Afec *pAFE, uint32_t dwNs)
+{
+	uint32_t dwShtim;
+	uint32_t dwMr;
+
+	if (dwAFEClock == 0) return;
+
+	/* Formula for SHTIM is:
+	   SHTIM = (time x AFECLK) / (1000000000) - 1
+	   Since 1 billion is close to the maximum value for an integer, we first
+	   divide AFECLK by 1000 to avoid an overflow */
+	dwShtim = (dwNs * (dwAFEClock / 1000)) / 100000;
+
+	if (dwShtim % 10) dwShtim /= 10;
+	else {
+		dwShtim /= 10;
+
+		if (dwShtim) dwShtim --;
+	}
+
+	dwMr  = AFEC_MR_TRACKTIM(dwShtim);
+	dwMr |= pAFE->AFEC_MR & ~AFEC_MR_TRACKTIM_Msk;
+	pAFE->AFEC_MR = dwMr;
+}
+
+/**
+ * \brief Set analog offset to be used for channel CSEL.
+ *
+ * \param afec  Base address of the AFEC.
+ * \param dwChannel AFEC channel number.
+ * \param aoffset  Analog offset value.
+ */
+void AFEC_SetAnalogOffset(Afec *pAFE, uint32_t dwChannel, uint32_t aoffset)
+{
+	assert(dwChannel < 12);
+	pAFE->AFEC_CSELR = dwChannel;
+	pAFE->AFEC_COCR = (aoffset & AFEC_COCR_AOFF_Msk);;
+}
+
+/**
+ * \brief Set analog offset to be used for channel CSEL.
+ *
+ * \param afec  Base address of the AFEC.
+ * \param control  Analog control value.
+ */
+void AFEC_SetAnalogControl(Afec *pAFE, uint32_t control)
+{
+	pAFE->AFEC_ACR = control;
+}
+
+
Index: bsps/arm/atsam/contrib/libraries/libchip/source/dac_dma.c
===================================================================
--- bsps/arm/atsam/contrib/libraries/libchip/source/dac_dma.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libchip/source/dac_dma.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,238 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+/** \addtogroup dacc_module Working with DACC
+ *  \ingroup peripherals_module
+ * The DACC driver provides the interface to configure and use the DACC
+ * peripheral.\n
+ *
+ * The DACC(Digital-to-Analog Converter Controller) converts digital code to
+ * analog output.
+ * The data to be converted are sent in a common register for all channels.
+ * It offers up to 2 analog outputs.The output voltage ranges from (1/6)ADVREF
+ * to (5/6)ADVREF.
+ *
+ * To Enable a DACC conversion,the user has to follow these few steps:
+ * <ul>
+ * <li> Select an appropriate reference voltage on ADVREF   </li>
+ * <li> Configure the DACC according to its requirements and special needs,
+ * which could be broken down into several parts:
+ * -#   Enable DACC in free running mode by clearing TRGEN in DACC_MR;
+ * -#   Configure Refresh Period through setting REFRESH fields
+ *      in DACC_MR; The refresh mechanism is used to protect the output analog
+ * value from
+ *      decreasing.
+ * -#   Enable channels and write digital code to DACC_CDR,in free running mode,
+ * the conversion is started right after at least one channel is enabled and
+ * data is written .
+ </li>
+ * </ul>
+ *
+ * For more accurate information, please look at the DACC section of the
+ * Datasheet.
+ *
+ * Related files :\n
+ * \ref dac_dma.c\n
+ * \ref dac_dma.h\n
+ */
+/*@{*/
+/*@}*/
+/**
+ * \file
+ *
+ * Implementation of Digital-to-Analog Converter Controller (DACC).
+ *
+ */
+
+/*----------------------------------------------------------------------------
+ *        Headers
+ *----------------------------------------------------------------------------*/
+
+#include "chip.h"
+
+#include <stdint.h>
+#include <assert.h>
+
+/*  DMA driver instance */
+static uint32_t dacDmaTxChannel;
+static LinkedListDescriporView1 dmaWriteLinkList[256];
+/*----------------------------------------------------------------------------
+ *        Local functions
+ *----------------------------------------------------------------------------*/
+
+/**
+ * \brief Configure the DMA Channels: 0 RX.
+ * Channels are disabled after configure.
+ * \returns 0 if the dma channel configuration successfully; otherwise returns
+ * DAC_ERROR_XXX.
+ */
+static uint8_t _DacConfigureDmaChannels(DacDma *pDacd)
+{
+
+	/* Driver initialize */
+	XDMAD_FreeChannel(pDacd->pXdmad, dacDmaTxChannel);
+
+	/* Allocate a DMA channel for DAC0/1 TX. */
+	dacDmaTxChannel =
+		XDMAD_AllocateChannel(pDacd->pXdmad, XDMAD_TRANSFER_MEMORY, ID_DACC);
+
+	if (dacDmaTxChannel == XDMAD_ALLOC_FAILED)
+		return DAC_ERROR;
+
+	if (XDMAD_PrepareChannel(pDacd->pXdmad, dacDmaTxChannel))
+		return DAC_ERROR;
+
+	return DAC_OK;
+}
+
+
+/**
+ * \brief Configure the DMA source and destination with Linker List mode.
+ *
+ * \param pBuffer Pointer to dac buffer
+ * \param size length of buffer
+ */
+
+static uint8_t _Dac_configureLinkList(Dacc *pDacHw, void *pXdmad,
+									  DacCmd *pCommand)
+{
+	uint32_t xdmaCndc;
+	sXdmadCfg xdmadCfg;
+	uint32_t *pBuffer;
+	/* Setup TX Link List */
+	uint8_t i;
+	pBuffer = (uint32_t *)pCommand->pTxBuff;
+
+	for (i = 0; i < pCommand->TxSize; i++) {
+		dmaWriteLinkList[i].mbr_ubc = XDMA_UBC_NVIEW_NDV1
+									  | XDMA_UBC_NDE_FETCH_EN
+									  | XDMA_UBC_NSEN_UPDATED
+									  | XDMAC_CUBC_UBLEN(4);
+		dmaWriteLinkList[i].mbr_sa = (uint32_t)pBuffer;
+		dmaWriteLinkList[i].mbr_da =
+			(uint32_t) & (pDacHw->DACC_CDR[pCommand->dacChannel]);
+
+		if (i == (pCommand->TxSize - 1)) {
+			if (pCommand->loopback)
+				dmaWriteLinkList[i].mbr_nda = (uint32_t)&dmaWriteLinkList[0];
+			else
+				dmaWriteLinkList[i].mbr_nda = 0;
+		} else
+			dmaWriteLinkList[i].mbr_nda = (uint32_t)&dmaWriteLinkList[i + 1];
+
+		pBuffer++;
+	}
+
+	xdmadCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN
+					   | XDMAC_CC_MBSIZE_SINGLE
+					   | XDMAC_CC_DSYNC_MEM2PER
+					   | XDMAC_CC_CSIZE_CHK_1
+					   | XDMAC_CC_DWIDTH_WORD
+					   | XDMAC_CC_SIF_AHB_IF1
+					   | XDMAC_CC_DIF_AHB_IF1
+					   | XDMAC_CC_SAM_INCREMENTED_AM
+					   | XDMAC_CC_DAM_FIXED_AM
+					   | XDMAC_CC_PERID(
+							XDMAIF_Get_ChannelNumber(ID_DACC, XDMAD_TRANSFER_TX));
+	xdmaCndc = XDMAC_CNDC_NDVIEW_NDV1
+			   | XDMAC_CNDC_NDE_DSCR_FETCH_EN
+			   | XDMAC_CNDC_NDSUP_SRC_PARAMS_UPDATED
+			   | XDMAC_CNDC_NDDUP_DST_PARAMS_UPDATED;
+	XDMAD_ConfigureTransfer(pXdmad, dacDmaTxChannel, &xdmadCfg, xdmaCndc,
+							 (uint32_t)&dmaWriteLinkList[0], XDMAC_CIE_LIE);
+	return DAC_OK;
+}
+
+/*----------------------------------------------------------------------------
+ *        Exported functions
+ *----------------------------------------------------------------------------*/
+/**
+ * \brief Initializes the DacDma structure and the corresponding DAC & DMA .
+ * hardware select value.
+ * The driver will uses DMA channel 0 for RX .
+ * The DMA channels are freed automatically when no DMA command processing.
+ *
+ * \param pDacd  Pointer to a DacDma instance.
+ * \param pDacHw Associated Dac peripheral.
+ * \param DacId  Dac peripheral identifier.
+ * \param pDmad  Pointer to a Dmad instance.
+ */
+uint32_t Dac_ConfigureDma(DacDma *pDacd ,
+						   Dacc *pDacHw ,
+						   uint8_t DacId,
+						   sXdmad *pXdmad)
+{
+	/* Initialize the Dac structure */
+	pDacd->pDacHw = pDacHw;
+	pDacd->dacId  = DacId;
+	pDacd->semaphore = 1;
+	pDacd->pCurrentCommand = 0;
+	assert(pXdmad == &XDMAD_Instance);
+	pDacd->pXdmad = pXdmad;
+	return 0;
+}
+
+/**
+ * \brief Starts a DAC transfer. This is a non blocking function. It will
+ *  return as soon as the transfer is started.
+ *
+ * \param pDacd  Pointer to a DacDma instance.
+ * \param pCommand Pointer to the Dac command to execute.
+ * \returns 0 if the transfer has been started successfully; otherwise returns
+ * DAC_ERROR_LOCK is the driver is in use, or DAC_ERROR if the command is not
+ * valid.
+ */
+uint32_t Dac_SendData(DacDma *pDacd, DacCmd *pCommand)
+{
+	Dacc *pDacHw = pDacd->pDacHw;
+
+	/* Try to get the dataflash semaphore */
+	if (pDacd->semaphore == 0)
+		return DAC_ERROR_LOCK;
+
+	pDacd->semaphore--;
+
+	// Initialize the callback
+	pDacd->pCurrentCommand = pCommand;
+
+	/* Initialize DMA controller using channel 0 for RX. */
+	if (_DacConfigureDmaChannels(pDacd))
+		return DAC_ERROR_LOCK;
+
+	if (_Dac_configureLinkList(pDacHw, pDacd->pXdmad, pCommand))
+		return DAC_ERROR_LOCK;
+
+	SCB_CleanDCache();
+
+	/* Start DMA TX */
+	if (XDMAD_StartTransfer(pDacd->pXdmad, dacDmaTxChannel))
+		return DAC_ERROR_LOCK;
+
+	return DAC_OK;;
+}
Index: bsps/arm/atsam/contrib/libraries/libchip/source/efc.c
===================================================================
--- bsps/arm/atsam/contrib/libraries/libchip/source/efc.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libchip/source/efc.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,280 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+/** \addtogroup efc_module Working with EEFC
+ *  \ingroup peripherals_module
+ *
+ * The EEFC driver provides the interface to configure and use the EEFC
+ * peripheral.
+ *
+ * The user needs to set the number of wait states depending on the frequency
+ * used.\n
+ * Configure number of cycles for flash read/write operations in the FWS field
+ * of EEFC_FMR.
+ *
+ * It offers a function to send flash command to EEFC and waits for the
+ * flash to be ready.
+ *
+ * To send flash command, the user could do in either of following way:
+ * <ul>
+ * <li>Write a correct key, command and argument in EEFC_FCR. </li>
+ * <li>Or, Use IAP (In Application Programming) function which is executed from
+ * ROM directly, this allows flash programming to be done by code running in
+ * flash.</li>
+ * <li>Once the command is achieved, it can be detected even by polling
+ * EEFC_FSR or interrupt.
+ * </ul>
+ *
+ * The command argument could be a page number,GPNVM number or nothing, it
+ * depends on the command itself. Some useful functions in this driver could
+ * help user translate physical flash address into a page number and vice verse.
+ *
+ * For more accurate information, please look at the EEFC section of the
+ * Datasheet.
+ *
+ * Related files :\n
+ * \ref efc.c\n
+ * \ref efc.h.\n
+ */
+/*@{*/
+/*@}*/
+
+
+/**
+ * \file
+ *
+ * Implementation of Enhanced Embedded Flash Controller (EEFC).
+ *
+ */
+
+
+/*----------------------------------------------------------------------------
+ *        Headers
+ *----------------------------------------------------------------------------*/
+#include "chip.h"
+
+#include <assert.h>
+
+
+/*----------------------------------------------------------------------------
+ *        Macro
+ *----------------------------------------------------------------------------*/
+#define EEFC_FCR_FCMD(value) ((EEFC_FCR_FCMD_Msk & ((value) << EEFC_FCR_FCMD_Pos)))
+
+/*----------------------------------------------------------------------------
+ *        Exported functions
+ *----------------------------------------------------------------------------*/
+
+extern void EFC_WriteFMR(Efc *efc, uint32_t dwFmr);
+
+#ifdef __ICCARM__
+	extern __ramfunc void EFC_WriteFMR(Efc *efc, uint32_t dwFmr)
+#else
+	__attribute__ ((section (".ramfunc")))
+	extern void EFC_WriteFMR(Efc *efc, uint32_t dwFmr)
+#endif
+{
+	efc->EEFC_FMR = dwFmr;
+}
+
+/**
+ * \brief Enables the flash ready interrupt source on the EEFC peripheral.
+ *
+ * \param efc  Pointer to a Efc instance
+ */
+extern void EFC_EnableFrdyIt(Efc *efc)
+{
+	uint32_t dwFmr;
+
+	dwFmr = efc->EEFC_FMR |= EEFC_FMR_FRDY;
+	EFC_WriteFMR(efc, dwFmr);
+}
+
+/**
+ * \brief Disables the flash ready interrupt source on the EEFC peripheral.
+ *
+ * \param efc  Pointer to a Efc instance
+ */
+extern void EFC_DisableFrdyIt(Efc *efc)
+{
+	uint32_t dwFmr;
+
+	dwFmr = efc->EEFC_FMR & (~EEFC_FMR_FRDY);
+	EFC_WriteFMR(efc, dwFmr);
+}
+
+
+/**
+ * \brief Set read/write wait state on the EEFC peripheral.
+ *
+ * \param efc  Pointer to a Efc instance
+ * \param cycles  the number of wait states in cycle.
+ */
+extern void EFC_SetWaitState(Efc *efc, uint8_t ucCycles)
+{
+	uint32_t dwFmr;
+
+	dwFmr = efc->EEFC_FMR;
+	dwFmr &= ~((uint32_t)EEFC_FMR_FWS_Msk);
+	dwFmr |= EEFC_FMR_FWS(ucCycles);
+	EFC_WriteFMR(efc, dwFmr);
+}
+
+/**
+ * \brief Returns the current status of the EEFC.
+ *
+ * \note Keep in mind that this function clears the value of some status bits
+ * (LOCKE, PROGE).
+ *
+ * \param efc  Pointer to a Efc instance
+ */
+extern uint32_t EFC_GetStatus(Efc *efc)
+{
+	return efc->EEFC_FSR;
+}
+
+/**
+ * \brief Returns the result of the last executed command.
+ *
+ * \param efc  Pointer to a Efc instance
+ */
+extern uint32_t EFC_GetResult(Efc *efc)
+{
+	return efc->EEFC_FRR;
+}
+
+/**
+ * \brief Translates the given address page and offset values.
+ * \note The resulting values are stored in the provided variables if they are
+ * not null.
+ *
+ * \param efc  Pointer to a Efc instance
+ * \param address  Address to translate.
+ * \param pPage  First page accessed.
+ * \param pOffset  Byte offset in first page.
+ */
+extern void EFC_TranslateAddress(Efc **ppEfc, uint32_t dwAddress,
+								  uint16_t *pwPage,
+								  uint16_t *pwOffset)
+{
+	assert(dwAddress >= IFLASH_ADDR);
+	assert(dwAddress <= (IFLASH_ADDR + IFLASH_SIZE));
+
+	/* Store values */
+	if (ppEfc)
+		*ppEfc = EFC;
+
+	if (pwPage)
+		*pwPage = (dwAddress - IFLASH_ADDR) / IFLASH_PAGE_SIZE;
+
+	if (pwOffset) {
+		*pwOffset = (dwAddress - IFLASH_ADDR) % IFLASH_PAGE_SIZE;;
+	}
+}
+
+
+/**
+ * \brief Computes the address of a flash access given the page and offset.
+ *
+ * \param efc  Pointer to a Efc instance
+ * \param page  Page number.
+ * \param offset  Byte offset inside page.
+ * \param pAddress  Computed address (optional).
+ */
+extern void EFC_ComputeAddress(Efc *efc, uint16_t wPage, uint16_t wOffset,
+								uint32_t *pdwAddress)
+{
+	uint32_t dwAddress;
+
+	/* Stop warning */
+	efc = efc;
+
+	assert(efc);
+	assert(wPage <= IFLASH_NB_OF_PAGES);
+	assert(wOffset < IFLASH_PAGE_SIZE);
+	dwAddress = IFLASH_ADDR + wPage * IFLASH_PAGE_SIZE + wOffset;
+
+	/* Store result */
+	if (pdwAddress != NULL)
+		*pdwAddress = dwAddress;
+}
+
+/**
+ * \brief Performs the given command and wait until its completion (or an error).
+ *
+ * \param efc  Pointer to a Efc instance
+ * \param command  Command to perform.
+ * \param argument  Optional command argument.
+ *
+ * \return 0 if successful, otherwise returns an error code.
+ */
+
+extern uint32_t EFC_PerformCommand(Efc *efc, uint32_t dwCommand,
+									uint32_t dwArgument, uint32_t dwUseIAP)
+{
+	if (dwUseIAP != 0) {
+		/* Pointer on IAP function in ROM */
+		static uint32_t (*IAP_PerformCommand)(uint32_t, uint32_t);
+
+		IAP_PerformCommand = (uint32_t (*)(uint32_t, uint32_t))
+							 * ((uint32_t *)CHIP_FLASH_IAP_ADDRESS);
+
+		if (efc == EFC) {
+			IAP_PerformCommand(0, EEFC_FCR_FKEY_PASSWD | EEFC_FCR_FARG(dwArgument)
+								| EEFC_FCR_FCMD(dwCommand));
+		}
+
+		return (efc->EEFC_FSR & (EEFC_FSR_FLOCKE | EEFC_FSR_FCMDE | EEFC_FSR_FLERR));
+	} else {
+		uint32_t dwStatus;
+
+		efc->EEFC_FCR = EEFC_FCR_FKEY_PASSWD | EEFC_FCR_FARG(dwArgument)
+						| EEFC_FCR_FCMD(dwCommand);
+
+		do {
+			dwStatus = efc->EEFC_FSR;
+		} while ((dwStatus & EEFC_FSR_FRDY) != EEFC_FSR_FRDY);
+
+		return (dwStatus & (EEFC_FSR_FLOCKE | EEFC_FSR_FCMDE | EEFC_FSR_FLERR));
+	}
+}
+
+/**
+ * \brief Set flash access mode.
+ *
+ * \param dwMode - 0:128-bit, (1<<24):64-bit
+ */
+extern void EFC_SetFlashAccessMode(Efc *efc, uint32_t dwMode)
+{
+	uint32_t dwFmr;
+
+	dwFmr = dwMode;
+	EFC_WriteFMR(efc, dwFmr);
+}
+
Index: bsps/arm/atsam/contrib/libraries/libchip/source/exceptions.c
===================================================================
--- bsps/arm/atsam/contrib/libraries/libchip/source/exceptions.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libchip/source/exceptions.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,214 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+/**
+ * \file
+ * This file contains the default exception handlers.
+ *
+ * \note
+ * The exception handler has weak aliases.
+ * As they are weak aliases, any function with the same name will override
+ * this definition.
+ */
+
+/*----------------------------------------------------------------------------
+ *        Headers
+ *----------------------------------------------------------------------------*/
+
+#include "chip.h"
+
+/*----------------------------------------------------------------------------
+ *        Exported functions
+ *----------------------------------------------------------------------------*/
+
+/**
+ * \brief Default NMI interrupt handler.
+ */
+void NMI_Handler(void)
+{
+	printf("\r\n-E- Enter NMI_Handler!");
+
+	while (1);
+}
+
+/**
+ * \brief This function back trace the stack to give exact address where fault
+ happened
+**/
+__STATIC_INLINE uint32_t StackUnwind(void)
+{
+	uint32_t Fault_Add;
+
+#if defined (__CC_ARM)
+	uint32_t temp;
+	__ASM("mrs temp, msp ");
+	__ASM{ ldr Fault_Add, [temp, #28]}
+#else
+	__ASM("mrs r0, msp ");
+	__ASM("ldr %0, [r0,#28]" : "=r" (Fault_Add));
+#endif
+	return Fault_Add;
+}
+
+/**
+ * \brief If Other Faults are enabled then HardFault error will look for those
+ *  errors to give more detail about fault
+**/
+static void HardFault_reason(void)
+{
+	uint32_t CFSRValue;
+	TRACE_DEBUG("In Hard Fault Handler\n\r");
+	TRACE_DEBUG("SCB->HFSR = 0x%08x\n\r", SCB->HFSR);
+
+	if ((SCB->HFSR & SCB_HFSR_DEBUGEVT_Msk)) {
+		TRACE_DEBUG("Debug Event Hard Fault\n\r");
+		TRACE_DEBUG("SCB->DFSR = 0x%08x\n", SCB->DFSR);
+	}
+
+	if ((SCB->HFSR & SCB_HFSR_VECTTBL_Msk)) {
+		TRACE_DEBUG("Fault was due to vector table read on \
+			exception processing\n\r");
+	}
+
+	// Forced HardFault
+	if ((SCB->HFSR & SCB_HFSR_FORCED_Msk)) {
+		TRACE_DEBUG("Forced Hard Fault\n\r");
+		TRACE_DEBUG("SCB->CFSR = 0x%08x\n\r", SCB->CFSR);
+
+		// Usage Fault
+		if ((SCB->CFSR & SCB_CFSR_USGFAULTSR_Msk)) {
+			CFSRValue = SCB->CFSR;
+			TRACE_DEBUG("Usage fault: ");
+			CFSRValue >>= SCB_CFSR_USGFAULTSR_Pos;
+
+			if ((CFSRValue & (1 << 9)))
+				TRACE_DEBUG("Divide by zero\n\r");
+
+			if ((CFSRValue & (1 << 8)))
+				TRACE_DEBUG("Unaligned access error\n\r");
+
+			if ((CFSRValue & (1 << 3)))
+				TRACE_DEBUG("Coprocessor access error\n\r");
+
+			if ((CFSRValue & (1 << 2)))
+				TRACE_DEBUG("Integrity check error on EXC_RETURN\n\r");
+		}
+
+		// Bus Fault
+		if ((SCB->CFSR & SCB_CFSR_BUSFAULTSR_Msk)) {
+			CFSRValue = SCB->CFSR;
+			TRACE_DEBUG("Bus fault: ");
+			CFSRValue >>= SCB_CFSR_BUSFAULTSR_Pos;
+
+			if ((CFSRValue & (1 << 7)) && (CFSRValue & (1 << 1))) {
+				TRACE_DEBUG("Precise data access error. Bus Fault Address \
+					Register is: %x \n\r", SCB->BFAR);
+			}
+
+			if ((CFSRValue & (1 << 4)))
+				TRACE_DEBUG("Bus fault has occurred on exception entry\n\r");
+
+			if ((CFSRValue & (1 << 3)))
+				TRACE_DEBUG("bus fault has occurred on exception return\n\r");
+
+			if ((CFSRValue & (1 << 2)))
+				TRACE_DEBUG("Imprecise data access error\n\r");
+
+			if ((CFSRValue & (1 << 0))) {
+				TRACE_DEBUG("This bit indicates a bus fault on an instruction \
+					pre-fetch. \n\r");
+			}
+		}
+	}
+
+	// MemoryFault
+	if ((SCB->CFSR & SCB_CFSR_MEMFAULTSR_Msk)) {
+		CFSRValue = SCB->CFSR;
+		TRACE_DEBUG("Memory fault: ");
+		CFSRValue >>= SCB_CFSR_MEMFAULTSR_Pos;
+
+		if ((CFSRValue & (1 << 9)) != 0)
+			TRACE_DEBUG("Divide by zero\n\r");
+	}
+
+	__ISB();
+	__DMB();
+	__ASM volatile("BKPT #01");
+}
+/**
+ * \brief Default HardFault interrupt handler.
+ */
+
+void HardFault_Handler(void)
+{
+	printf("\n\rHardFault at address 0X%x\n\r", (int)StackUnwind());
+	__ISB();
+	__DMB();
+	HardFault_reason();
+}
+
+#ifndef MPU_EXAMPLE_FEATURE
+/**
+ * \brief Default MemManage interrupt handler.
+ */
+void MemManage_Handler(void)
+{
+	printf("\n\rMemoryMemFault (MPU fault) at address 0X%x\n\r",
+		   (int)StackUnwind());
+	__ISB();
+	__DMB();
+	__ASM volatile("BKPT #01");
+}
+#endif
+
+/**
+ * \brief Default BusFault interrupt handler.
+ */
+void BusFault_Handler(void)
+{
+	__ASM("nop");
+	__ASM("nop");
+	printf("\n\rBus Fault at address 0X%x\n\r", (int)StackUnwind());
+
+	__ISB();
+	__DMB();
+	__ASM volatile("BKPT #01");
+}
+
+/**
+ * \brief Default UsageFault interrupt handler.
+ */
+void UsageFault_Handler(void)
+{
+	printf("\r\nUsage fault at address 0X%x", (int)StackUnwind());
+
+	__ISB();
+	__DMB();
+	__ASM volatile("BKPT #01");
+}
Index: bsps/arm/atsam/contrib/libraries/libchip/source/flashd.c
===================================================================
--- bsps/arm/atsam/contrib/libraries/libchip/source/flashd.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libchip/source/flashd.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,595 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+/** \addtogroup flashd_module Flash Memory Interface
+ * The flash driver manages the programming, erasing, locking and unlocking
+ * sequences with dedicated commands.
+ *
+ * To implement flash programming operation, the user has to follow these few
+ * steps :
+ * <ul>
+ * <li>Configure flash wait states to initializes the flash. </li>
+ * <li>Checks whether a region to be programmed is locked. </li>
+ * <li>Unlocks the user region to be programmed if the region have locked
+ * before.</li>
+ * <li>Erases the user page before program (optional).</li>
+ * <li>Writes the user page from the page buffer.</li>
+ * <li>Locks the region of programmed area if any.</li>
+ * </ul>
+ *
+ * Writing 8-bit and 16-bit data is not allowed and may lead to unpredictable
+ * data corruption.
+ * A check of this validity and padding for 32-bit alignment should be done in
+ * write algorithm.
+ * Lock/unlock range associated with the user address range is automatically
+ * translated.
+ *
+ * This security bit can be enabled through the command "Set General Purpose
+ * NVM Bit 0".
+ *
+ * A 128-bit factory programmed unique ID could be read to serve several
+ * purposes.
+ *
+ * The driver accesses the flash memory by calling the lowlevel module provided
+ * in \ref efc_module.
+ * For more accurate information, please look at the EEFC section of the
+ * Datasheet.
+ *
+ * Related files :\n
+ * \ref flashd.c\n
+ * \ref flashd.h.\n
+ * \ref efc.c\n
+ * \ref efc.h.\n
+ */
+/*@{*/
+/*@}*/
+
+
+/**
+ * \file
+ *
+ * The flash driver provides the unified interface for flash program operations.
+ *
+ */
+
+/*----------------------------------------------------------------------------
+ *        Headers
+ *----------------------------------------------------------------------------*/
+#include "chip.h"
+
+#include <string.h>
+#include <assert.h>
+
+/*----------------------------------------------------------------------------
+ *        Definitions
+ *----------------------------------------------------------------------------*/
+
+#define GPNVM_NUM_MAX    9
+
+/*----------------------------------------------------------------------------
+ *        Local variables
+ *----------------------------------------------------------------------------*/
+
+static uint32_t _pdwPageBuffer[IFLASH_PAGE_SIZE / sizeof(uint32_t)];
+static uint32_t _dwUseIAP = 1; /* Use IAP interface by default. */
+
+
+/*----------------------------------------------------------------------------
+ *        Local functions
+ *----------------------------------------------------------------------------*/
+
+
+/**
+ * \brief Computes the lock range associated with the given address range.
+ *
+ * \param dwStart  Start address of lock range.
+ * \param dwEnd  End address of lock range.
+ * \param pdwActualStart  Actual start address of lock range.
+ * \param pdwActualEnd  Actual end address of lock range.
+ */
+static void ComputeLockRange(uint32_t dwStart, uint32_t dwEnd,
+							  uint32_t *pdwActualStart, uint32_t *pdwActualEnd)
+{
+	Efc *pStartEfc;
+	Efc *pEndEfc;
+	uint16_t wStartPage;
+	uint16_t wEndPage;
+	uint16_t wNumPagesInRegion;
+	uint16_t wActualStartPage;
+	uint16_t wActualEndPage;
+
+	/* Convert start and end address in page numbers */
+	EFC_TranslateAddress(&pStartEfc, dwStart, &wStartPage, 0);
+	EFC_TranslateAddress(&pEndEfc, dwEnd, &wEndPage, 0);
+
+	/* Find out the first page of the first region to lock */
+	wNumPagesInRegion = IFLASH_LOCK_REGION_SIZE / IFLASH_PAGE_SIZE;
+	wActualStartPage = wStartPage - (wStartPage % wNumPagesInRegion);
+	wActualEndPage = wEndPage;
+
+	if ((wEndPage % wNumPagesInRegion) != 0)
+		wActualEndPage += wNumPagesInRegion - (wEndPage % wNumPagesInRegion);
+
+	/* Store actual page numbers */
+	EFC_ComputeAddress(pStartEfc, wActualStartPage, 0, pdwActualStart);
+	EFC_ComputeAddress(pEndEfc, wActualEndPage, 0, pdwActualEnd);
+	TRACE_DEBUG("Actual lock range is 0x%06X - 0x%06X\n\r",
+				 (unsigned int)*pdwActualStart, (unsigned int)*pdwActualEnd);
+}
+
+
+/*----------------------------------------------------------------------------
+ *        Exported functions
+ *----------------------------------------------------------------------------*/
+
+/**
+ * \brief Initializes the flash driver.
+ *
+ * \param dwMCk     Master clock frequency in Hz.
+ * \param dwUseIAP  0: use EEFC controller interface, 1: use IAP interface.
+ *                  dwUseIAP should be set to 1 when running out of flash.
+ */
+
+extern void FLASHD_Initialize(uint32_t dwMCk, uint32_t dwUseIAP)
+{
+	dwMCk = dwMCk; /* avoid warnings */
+
+	EFC_DisableFrdyIt(EFC);
+	_dwUseIAP = dwUseIAP;
+}
+
+/**
+ * \brief Erases the entire flash.
+ *
+ * \param dwAddress  Flash start address.
+ * \return 0 if successful; otherwise returns an error code.
+ */
+extern uint32_t FLASHD_Erase(uint32_t dwAddress)
+{
+	Efc *pEfc;
+	uint16_t wPage;
+	uint16_t wOffset;
+	uint32_t dwError;
+
+	assert((dwAddress >= IFLASH_ADDR)
+			|| (dwAddress <= (IFLASH_ADDR + IFLASH_SIZE)));
+
+	/* Translate write address */
+	EFC_TranslateAddress(&pEfc, dwAddress, &wPage, &wOffset);
+	dwError = EFC_PerformCommand(pEfc, EFC_FCMD_EA, 0, _dwUseIAP);
+
+	return dwError;
+}
+
+/**
+ * \brief Erases flash by sector.
+ *
+ * \param dwAddress  Start address of be erased sector.
+ *
+ * \return 0 if successful; otherwise returns an error code.
+ */
+extern uint32_t FLASHD_EraseSector(uint32_t dwAddress)
+{
+	Efc *pEfc;
+	uint16_t wPage;
+	uint16_t wOffset;
+	uint32_t dwError;
+
+	assert((dwAddress >= IFLASH_ADDR)
+			|| (dwAddress <= (IFLASH_ADDR + IFLASH_SIZE)));
+
+	/* Translate write address */
+	EFC_TranslateAddress(&pEfc, dwAddress, &wPage, &wOffset);
+	dwError = EFC_PerformCommand(pEfc, EFC_FCMD_ES, wPage, _dwUseIAP);
+
+	return dwError;
+}
+
+/**
+ * \brief Erases flash by pages.
+ *
+ * \param dwAddress  Start address of be erased pages.
+ * \param dwPageNum  Number of pages to be erased with EPA command (4, 8, 16, 32)
+ *
+ * \return 0 if successful; otherwise returns an error code.
+ */
+extern uint32_t FLASHD_ErasePages(uint32_t dwAddress, uint32_t dwPageNum)
+{
+	Efc *pEfc;
+	uint16_t wPage;
+	uint16_t wOffset;
+	uint32_t dwError;
+	static uint32_t dwFarg;
+
+	assert((dwAddress >= IFLASH_ADDR)
+			|| (dwAddress <= (IFLASH_ADDR + IFLASH_SIZE)));
+
+	/* Translate write address */
+	EFC_TranslateAddress(&pEfc, dwAddress, &wPage, &wOffset);
+
+	/* Get FARG field for EPA command:
+	 * The first page to be erased is specified in the FARG[15:2] field of
+	 * the MC_FCR register. The first page number must be modulo 4, 8,16 or 32
+	 * according to the number of pages to erase at the same time.
+	 *
+	 * The 2 lowest bits of the FARG field define the number of pages to
+	 * be erased (FARG[1:0]).
+	 */
+	if (dwPageNum == 32) {
+		wPage &= ~(32u - 1u);
+		dwFarg = (wPage) | 3; /* 32 pages */
+	} else if (dwPageNum == 16) {
+		wPage &= ~(16u - 1u);
+		dwFarg = (wPage) | 2; /* 16 pages */
+	} else if (dwPageNum == 8) {
+		wPage &= ~(8u - 1u);
+		dwFarg = (wPage) | 1; /* 8 pages */
+	} else {
+		wPage &= ~(4u - 1u);
+		dwFarg = (wPage) | 0; /* 4 pages */
+	}
+
+	dwError = EFC_PerformCommand(pEfc, EFC_FCMD_EPA, dwFarg, _dwUseIAP);
+
+	return dwError;
+}
+
+
+/**
+ * \brief Writes a data buffer in the internal flash
+ *
+ * \note This function works in polling mode, and thus only returns when the
+ * data has been effectively written.
+ * \param address  Write address.
+ * \param pBuffer  Data buffer.
+ * \param size  Size of data buffer in bytes.
+ * \return 0 if successful, otherwise returns an error code.
+ */
+extern uint32_t FLASHD_Write(uint32_t dwAddress,
+							  const void *pvBuffer, uint32_t dwSize)
+{
+	Efc *pEfc;
+	uint16_t page;
+	uint16_t offset;
+	uint32_t writeSize;
+	uint32_t pageAddress;
+	uint16_t padding;
+	uint32_t dwError;
+	uint32_t dwIdx;
+	uint32_t *pAlignedDestination;
+	uint8_t  *pucPageBuffer = (uint8_t *)_pdwPageBuffer;
+
+	assert(pvBuffer);
+	assert(dwAddress >= IFLASH_ADDR);
+	assert((dwAddress + dwSize) <= (IFLASH_ADDR + IFLASH_SIZE));
+
+	/* Translate write address */
+	EFC_TranslateAddress(&pEfc, dwAddress, &page, &offset);
+
+	/* Write all pages */
+	while (dwSize > 0) {
+		/* Copy data in temporary buffer to avoid alignment problems */
+		writeSize = min((uint32_t)IFLASH_PAGE_SIZE - offset, dwSize);
+		EFC_ComputeAddress(pEfc, page, 0, &pageAddress);
+		padding = IFLASH_PAGE_SIZE - offset - writeSize;
+
+		/* Pre-buffer data */
+		memcpy(pucPageBuffer, (void *) pageAddress, offset);
+
+		/* Buffer data */
+		memcpy(pucPageBuffer + offset, pvBuffer, writeSize);
+
+		/* Post-buffer data */
+		memcpy(pucPageBuffer + offset + writeSize,
+				(void *) (pageAddress + offset + writeSize), padding);
+
+		/* Write page
+		 * Writing 8-bit and 16-bit data is not allowed and may
+		    lead to unpredictable data corruption
+		 */
+		pAlignedDestination = (uint32_t *)pageAddress;
+
+		for (dwIdx = 0; dwIdx < (IFLASH_PAGE_SIZE / sizeof(uint32_t)); ++ dwIdx) {
+			*pAlignedDestination++ = _pdwPageBuffer[dwIdx];
+			memory_barrier()
+		}
+
+		/* Cache coherence operation before flash write*/
+		SCB_CleanDCache_by_Addr((uint32_t *)pageAddress, IFLASH_PAGE_SIZE);
+
+		/* Note: It is not possible to use Erase and write Command (EWP) on all Flash
+		(this command is available on the First 2 Small Sector, 16K Bytes).
+		For the next block, Erase them first then use Write page command. */
+
+		/* Send writing command */
+		dwError = EFC_PerformCommand(pEfc, EFC_FCMD_WP, page, _dwUseIAP);
+
+		if (dwError)
+			return dwError;
+
+		/* Progression */
+		pvBuffer = (void *)((uint32_t) pvBuffer + writeSize);
+		dwSize -= writeSize;
+		page++;
+		offset = 0;
+	}
+
+	return 0;
+}
+
+/**
+ * \brief Locks all the regions in the given address range. The actual lock
+ * range is reported through two output parameters.
+ *
+ * \param start  Start address of lock range.
+ * \param end    End address of lock range.
+ * \param pActualStart  Start address of the actual lock range (optional).
+ * \param pActualEnd  End address of the actual lock range (optional).
+ * \return 0 if successful, otherwise returns an error code.
+ */
+extern uint32_t FLASHD_Lock(uint32_t start, uint32_t end,
+							 uint32_t *pActualStart, uint32_t *pActualEnd)
+{
+	Efc *pEfc;
+	uint32_t actualStart, actualEnd;
+	uint16_t startPage, endPage;
+	uint32_t dwError;
+	uint16_t numPagesInRegion = IFLASH_LOCK_REGION_SIZE / IFLASH_PAGE_SIZE;
+
+	/* Compute actual lock range and store it */
+	ComputeLockRange(start, end, &actualStart, &actualEnd);
+
+	if (pActualStart != NULL)
+		*pActualStart = actualStart;
+
+	if (pActualEnd != NULL)
+		*pActualEnd = actualEnd;
+
+	/* Compute page numbers */
+	EFC_TranslateAddress(&pEfc, actualStart, &startPage, 0);
+	EFC_TranslateAddress(0, actualEnd, &endPage, 0);
+
+	/* Lock all pages */
+	while (startPage < endPage) {
+		dwError = EFC_PerformCommand(pEfc, EFC_FCMD_SLB, startPage, _dwUseIAP);
+
+		if (dwError)
+			return dwError;
+
+		startPage += numPagesInRegion;
+	}
+
+	return 0;
+}
+
+/**
+ * \brief Unlocks all the regions in the given address range. The actual unlock
+ * range is reported through two output parameters.
+ * \param start  Start address of unlock range.
+ * \param end  End address of unlock range.
+ * \param pActualStart  Start address of the actual unlock range (optional).
+ * \param pActualEnd  End address of the actual unlock range (optional).
+ * \return 0 if successful, otherwise returns an error code.
+ */
+extern uint32_t FLASHD_Unlock(uint32_t start, uint32_t end,
+							   uint32_t *pActualStart, uint32_t *pActualEnd)
+{
+	Efc *pEfc;
+	uint32_t actualStart, actualEnd;
+	uint16_t startPage, endPage;
+	uint32_t dwError;
+	uint16_t numPagesInRegion = IFLASH_LOCK_REGION_SIZE / IFLASH_PAGE_SIZE;
+
+	/* Compute actual unlock range and store it */
+	ComputeLockRange(start, end, &actualStart, &actualEnd);
+
+	if (pActualStart != NULL)
+		*pActualStart = actualStart;
+
+	if (pActualEnd != NULL)
+		*pActualEnd = actualEnd;
+
+	/* Compute page numbers */
+	EFC_TranslateAddress(&pEfc, actualStart, &startPage, 0);
+	EFC_TranslateAddress(0, actualEnd, &endPage, 0);
+
+	/* Unlock all pages */
+	while (startPage < endPage) {
+		dwError = EFC_PerformCommand(pEfc, EFC_FCMD_CLB, startPage, _dwUseIAP);
+
+		if (dwError)
+			return dwError;
+
+		startPage += numPagesInRegion;
+	}
+
+	return 0;
+}
+
+/**
+ * \brief Returns the number of locked regions inside the given address range.
+ *
+ * \param start  Start address of range
+ * \param end    End address of range.
+ */
+extern uint32_t FLASHD_IsLocked(uint32_t start, uint32_t end)
+{
+	uint32_t i, j;
+	Efc *pEfc;
+	uint16_t startPage, endPage;
+	uint8_t startRegion, endRegion;
+	uint32_t numPagesInRegion;
+	uint32_t status[IFLASH_NB_OF_LOCK_BITS / 32u];
+	uint32_t numLockedRegions = 0;
+
+	assert(end >= start);
+	assert((start >= IFLASH_ADDR) && (end <= IFLASH_ADDR + IFLASH_SIZE));
+
+	/* Compute page numbers */
+	EFC_TranslateAddress(&pEfc, start, &startPage, 0);
+	EFC_TranslateAddress(0, end, &endPage, 0);
+
+	/* Compute region numbers */
+	numPagesInRegion = IFLASH_LOCK_REGION_SIZE / IFLASH_PAGE_SIZE;
+	startRegion = startPage / numPagesInRegion;
+	endRegion = endPage / numPagesInRegion;
+
+	if ((endPage % numPagesInRegion) != 0)
+		endRegion++;
+
+	/* Retrieve lock status */
+	EFC_PerformCommand(pEfc, EFC_FCMD_GLB, 0, _dwUseIAP);
+
+	for (i = 0; i < (IFLASH_NB_OF_LOCK_BITS / 32u); i++)
+		status[i] = EFC_GetResult(pEfc);
+
+	/* Check status of each involved region */
+	while (startRegion < endRegion) {
+		i = startRegion / 32u;
+		j = startRegion % 32u;
+
+		if ((status[i] & (1 << j)) != 0)
+			numLockedRegions++;
+
+		startRegion++;
+	}
+
+	return numLockedRegions;
+}
+
+/**
+ * \brief Check if the given GPNVM bit is set or not.
+ *
+ * \param gpnvm  GPNVM bit index.
+ * \returns 1 if the given GPNVM bit is currently set; otherwise returns 0.
+ */
+extern uint32_t FLASHD_IsGPNVMSet(uint8_t ucGPNVM)
+{
+	uint32_t dwStatus;
+
+	assert(ucGPNVM < GPNVM_NUM_MAX);
+
+	/* Get GPNVMs status */
+	EFC_PerformCommand(EFC, EFC_FCMD_GFB, 0, _dwUseIAP);
+	dwStatus = EFC_GetResult(EFC);
+
+	/* Check if GPNVM is set */
+	if ((dwStatus & (1 << ucGPNVM)) != 0)
+		return 1;
+	else
+		return 0;
+}
+
+/**
+ * \brief Sets the selected GPNVM bit.
+ *
+ * \param gpnvm  GPNVM bit index.
+ * \returns 0 if successful; otherwise returns an error code.
+ */
+extern uint32_t FLASHD_SetGPNVM(uint8_t ucGPNVM)
+{
+	assert(ucGPNVM < GPNVM_NUM_MAX);
+
+	if (!FLASHD_IsGPNVMSet(ucGPNVM))
+		return EFC_PerformCommand(EFC, EFC_FCMD_SFB, ucGPNVM, _dwUseIAP);
+	else
+		return 0;
+}
+
+/**
+ * \brief Clears the selected GPNVM bit.
+ *
+ * \param gpnvm  GPNVM bit index.
+ * \returns 0 if successful; otherwise returns an error code.
+ */
+extern uint32_t FLASHD_ClearGPNVM(uint8_t ucGPNVM)
+{
+	assert(ucGPNVM < GPNVM_NUM_MAX);
+
+	if (FLASHD_IsGPNVMSet(ucGPNVM))
+		return EFC_PerformCommand(EFC, EFC_FCMD_CFB, ucGPNVM, _dwUseIAP);
+	else
+		return 0;
+}
+
+/**
+ * \brief Read the unique ID.
+ *
+ * \param pdwUniqueID pointer on a 4bytes char containing the unique ID value.
+ * \returns 0 if successful; otherwise returns an error code.
+ */
+#ifdef __ICCARM__
+	extern __ramfunc uint32_t FLASHD_ReadUniqueID(uint32_t *pdwUniqueID)
+#else
+	__attribute__ ((section (".ramfunc")))
+	uint32_t FLASHD_ReadUniqueID(uint32_t *pdwUniqueID)
+#endif
+{
+	uint32_t status;
+
+	if (pdwUniqueID == NULL)
+		return 1;
+
+	pdwUniqueID[0] = 0;
+	pdwUniqueID[1] = 0;
+	pdwUniqueID[2] = 0;
+	pdwUniqueID[3] = 0;
+
+	/* Send the Start Read unique Identifier command (STUI) by writing the Flash
+	   Command Register with the STUI command.*/
+	EFC->EEFC_FCR = EEFC_FCR_FKEY_PASSWD | EFC_FCMD_STUI;
+
+	/* When the Unique Identifier is ready to be read, the FRDY bit in the Flash
+	   Programming Status Register (EEFC_FSR) falls. */
+	do {
+		status = EFC->EEFC_FSR;
+	} while ((status & EEFC_FSR_FRDY) == EEFC_FSR_FRDY);
+
+	/* The Unique Identifier is located in the first 128 bits of the Flash
+	   memory mapping. So, at the address 0x400000-0x40000F. */
+	pdwUniqueID[0] = *(uint32_t *)IFLASH_ADDR;
+	pdwUniqueID[1] = *(uint32_t *)(IFLASH_ADDR + 4);
+	pdwUniqueID[2] = *(uint32_t *)(IFLASH_ADDR + 8);
+	pdwUniqueID[3] = *(uint32_t *)(IFLASH_ADDR + 12);
+
+	/* To stop the Unique Identifier mode, the user needs to send the Stop Read
+	   unique Identifier command (SPUI) by writing the Flash Command Register
+	   with the SPUI command. */
+	EFC->EEFC_FCR = EEFC_FCR_FKEY_PASSWD | EFC_FCMD_SPUI;
+
+	/* When the Stop read Unique Unique Identifier command (SPUI) has been
+	performed, the FRDY bit in the Flash Programming Status Register (EEFC_FSR)
+	rises. */
+	do {
+		status = EFC->EEFC_FSR;
+	} while ((status & EEFC_FSR_FRDY) != EEFC_FSR_FRDY);
+
+	return 0;
+}
+
Index: bsps/arm/atsam/contrib/libraries/libchip/source/gmac.c
===================================================================
--- bsps/arm/atsam/contrib/libraries/libchip/source/gmac.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libchip/source/gmac.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,685 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+/** \file */
+
+/*----------------------------------------------------------------------------
+ *        Headers
+ *----------------------------------------------------------------------------*/
+
+#include "chip.h"
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+
+
+/*----------------------------------------------------------------------------
+ *        Internal functions
+ *----------------------------------------------------------------------------*/
+/*----------------------------------------------------------------------------
+ *        Exported functions
+ *----------------------------------------------------------------------------*/
+
+/**
+ * Return 1 if PHY is idle
+ */
+uint8_t GMAC_IsIdle(Gmac *pGmac)
+{
+	return ((pGmac->GMAC_NSR & GMAC_NSR_IDLE) > 0);
+}
+
+
+/**
+ * Execute PHY maintenance command
+ */
+void GMAC_PHYMaintain(Gmac      *pGmac,
+					  uint8_t   bPhyAddr,
+					  uint8_t   bRegAddr,
+					  uint8_t   bRW,
+					  uint16_t  wData)
+{
+	/* Wait until bus idle */
+	while ((pGmac->GMAC_NSR & GMAC_NSR_IDLE) == 0);
+
+	/* Write maintain register */
+	pGmac->GMAC_MAN = (~GMAC_MAN_WZO & GMAC_MAN_CLTTO)
+					  | (GMAC_MAN_OP(bRW ? 0x2 : 0x1))
+					  | GMAC_MAN_WTN(0x02)
+					  | GMAC_MAN_PHYA(bPhyAddr)
+					  | GMAC_MAN_REGA(bRegAddr)
+					  | GMAC_MAN_DATA(wData);
+}
+
+/**
+ * Return PHY maintenance data returned
+ */
+uint16_t GMAC_PHYData(Gmac *pGmac)
+{
+	/* Wait until bus idle */
+	while ((pGmac->GMAC_NSR & GMAC_NSR_IDLE) == 0);
+
+	/* Return data */
+	return (uint16_t)(pGmac->GMAC_MAN & GMAC_MAN_DATA_Msk);
+}
+
+/**
+ *  \brief Set MDC clock according to current board clock. Per 802.3, MDC should
+ *  be less then 2.5MHz.
+ *  \param pGmac Pointer to an Gmac instance.
+ *  \param mck Mdc clock
+ *  \return 1 if successfully, 0 if MDC clock not found.
+ */
+uint8_t GMAC_SetMdcClock(Gmac *pGmac, uint32_t mck)
+{
+	uint32_t clock_dividor;
+	pGmac->GMAC_NCR &=  ~(GMAC_NCR_RXEN | GMAC_NCR_TXEN);
+
+	if (mck <= 20000000) {
+		clock_dividor = GMAC_NCFGR_CLK_MCK_8;          // MDC clock = MCK/8
+	} else if (mck <= 40000000) {
+		clock_dividor = GMAC_NCFGR_CLK_MCK_16;         // MDC clock = MCK/16
+	} else if (mck <= 80000000) {
+		clock_dividor = GMAC_NCFGR_CLK_MCK_32;         // MDC clock = MCK/32
+	} else if (mck <= 160000000) {
+		clock_dividor = GMAC_NCFGR_CLK_MCK_64;         // MDC clock = MCK/64
+	} else if (mck <= 240000000) {
+		clock_dividor = GMAC_NCFGR_CLK_MCK_96;         // MDC clock = MCK/96
+	} else {
+		TRACE_ERROR("E: No valid MDC clock.\n\r");
+		return 0;
+	}
+
+	pGmac->GMAC_NCFGR = (pGmac->GMAC_NCFGR & (~GMAC_NCFGR_CLK_Msk)) | clock_dividor;
+	pGmac->GMAC_NCR |=  (GMAC_NCR_RXEN | GMAC_NCR_TXEN);
+	return 1;
+}
+
+/**
+ *  \brief Enable MDI with PHY
+ *  \param pGmac Pointer to an Gmac instance.
+ */
+void GMAC_EnableMdio(Gmac *pGmac)
+{
+	pGmac->GMAC_NCR &=  ~(GMAC_NCR_RXEN | GMAC_NCR_TXEN);
+	pGmac->GMAC_NCR |= GMAC_NCR_MPE;
+	pGmac->GMAC_NCR |=  (GMAC_NCR_RXEN | GMAC_NCR_TXEN);
+}
+
+/**
+ *  \brief Enable MDI with PHY
+ *  \param pGmac Pointer to an Gmac instance.
+ */
+void GMAC_DisableMdio(Gmac *pGmac)
+{
+	pGmac->GMAC_NCR &=  ~(GMAC_NCR_RXEN | GMAC_NCR_TXEN);
+	pGmac->GMAC_NCR &= ~GMAC_NCR_MPE;
+	pGmac->GMAC_NCR |=  (GMAC_NCR_RXEN | GMAC_NCR_TXEN);
+}
+
+/**
+ *  \brief Enable MII mode for GMAC, called once after auto negotiate
+ *  \param pGmac Pointer to an Gmac instance.
+ */
+void GMAC_EnableMII(Gmac *pGmac)
+{
+	pGmac->GMAC_NCR &=  ~(GMAC_NCR_RXEN | GMAC_NCR_TXEN);
+	pGmac->GMAC_UR &= ~GMAC_UR_RMII;
+	pGmac->GMAC_NCR |=  (GMAC_NCR_RXEN | GMAC_NCR_TXEN);
+}
+
+/**
+ *  \brief Enable GMII mode for GMAC, called once after auto negotiate
+ *  \param pGmac Pointer to an Gmac instance.
+ */
+void GMAC_EnableGMII(Gmac *pGmac)
+{
+	pGmac->GMAC_NCR &=  ~(GMAC_NCR_RXEN | GMAC_NCR_TXEN);
+	/* RGMII disable */
+	pGmac->GMAC_UR &= ~GMAC_UR_RMII;
+	pGmac->GMAC_NCR |=  (GMAC_NCR_RXEN | GMAC_NCR_TXEN);
+}
+
+#define GMAC_NCFGR_GBE (0x1u << 10)
+/**
+ *  \brief Enable RGMII mode for GMAC, called once after auto negotiate
+ *  \param pGmac Pointer to an Gmac instance.
+ *  \param duplex: 1 full duplex 0 half duplex
+ *  \param speed:   0 10M 1 100M
+ */
+void GMAC_EnableRGMII(Gmac *pGmac, uint32_t duplex, uint32_t speed)
+{
+	pGmac->GMAC_NCR &=  ~(GMAC_NCR_RXEN | GMAC_NCR_TXEN);
+
+	if (duplex == GMAC_DUPLEX_HALF)
+		pGmac->GMAC_NCFGR &= ~GMAC_NCFGR_FD;
+	else
+		pGmac->GMAC_NCFGR |= GMAC_NCFGR_FD;
+
+
+	if (speed == GMAC_SPEED_10M)
+		pGmac->GMAC_NCFGR &= ~GMAC_NCFGR_SPD;
+	else if (speed == GMAC_SPEED_100M)
+		pGmac->GMAC_NCFGR |= GMAC_NCFGR_SPD;
+	else
+		pGmac->GMAC_NCFGR |= GMAC_NCFGR_SPD;
+
+	/* RGMII enable */
+	pGmac->GMAC_UR = 0;
+	pGmac->GMAC_NCFGR &= ~GMAC_NCFGR_GBE;
+	pGmac->GMAC_NCR |=  (GMAC_NCR_RXEN | GMAC_NCR_TXEN);
+	return;
+}
+
+/**
+ *  \brief Setup the GMAC for the link : speed 100M/10M and Full/Half duplex
+ *  \param pGmac Pointer to an Gmac instance.
+ *  \param speed        Link speed, 0 for 10M, 1 for 100M
+ *  \param fullduplex   1 for Full Duplex mode
+ */
+void GMAC_SetLinkSpeed(Gmac *pGmac, uint8_t speed, uint8_t fullduplex)
+{
+	uint32_t ncfgr;
+	ncfgr = pGmac->GMAC_NCFGR;
+	ncfgr &= ~(GMAC_NCFGR_SPD | GMAC_NCFGR_FD);
+
+	if (speed)
+		ncfgr |= GMAC_NCFGR_SPD;
+
+	if (fullduplex)
+		ncfgr |= GMAC_NCFGR_FD;
+
+	pGmac->GMAC_NCFGR = ncfgr;
+	pGmac->GMAC_NCR |=  (GMAC_NCR_RXEN | GMAC_NCR_TXEN);
+}
+
+/**
+ *  \brief set local loop back
+ *  \param pGmac Pointer to an Gmac instance.
+ */
+uint32_t GMAC_SetLocalLoopBack(Gmac *pGmac)
+{
+	pGmac->GMAC_NCR |= GMAC_NCR_LBL;
+	return 0;
+}
+
+/**
+ * Return interrupt mask.
+ */
+uint32_t GMAC_GetItMask(Gmac *pGmac, gmacQueList_t queueIdx)
+{
+	if (!queueIdx)
+		return pGmac->GMAC_IMR;
+	else
+		return pGmac->GMAC_IMRPQ[queueIdx - 1];
+}
+
+
+/**
+ * Return transmit status
+ */
+uint32_t GMAC_GetTxStatus(Gmac *pGmac)
+{
+	return pGmac->GMAC_TSR;
+}
+
+/**
+ * Clear transmit status
+ */
+void GMAC_ClearTxStatus(Gmac *pGmac, uint32_t dwStatus)
+{
+	pGmac->GMAC_TSR = dwStatus;
+}
+
+/**
+ * Return receive status
+ */
+uint32_t GMAC_GetRxStatus(Gmac *pGmac)
+{
+	return pGmac->GMAC_RSR;
+}
+
+/**
+ * Clear receive status
+ */
+void GMAC_ClearRxStatus(Gmac *pGmac, uint32_t dwStatus)
+{
+	pGmac->GMAC_RSR = dwStatus;
+}
+
+
+/**
+ * Enable/Disable GMAC receive.
+ */
+void GMAC_ReceiveEnable(Gmac *pGmac, uint8_t bEnaDis)
+{
+	if (bEnaDis) pGmac->GMAC_NCR |=  GMAC_NCR_RXEN;
+	else         pGmac->GMAC_NCR &= ~GMAC_NCR_RXEN;
+}
+
+/**
+ * Enable/Disable GMAC transmit.
+ */
+void GMAC_TransmitEnable(Gmac *pGmac, uint8_t bEnaDis)
+{
+	if (bEnaDis) pGmac->GMAC_NCR |=  GMAC_NCR_TXEN;
+	else         pGmac->GMAC_NCR &= ~GMAC_NCR_TXEN;
+}
+
+
+/**
+ * Set Rx Queue
+ */
+void GMAC_SetRxQueue(Gmac *pGmac, uint32_t dwAddr, gmacQueList_t queueIdx)
+{
+	if (!queueIdx)
+		pGmac->GMAC_RBQB = GMAC_RBQB_ADDR_Msk & dwAddr;
+	else
+		pGmac->GMAC_RBQBAPQ[queueIdx - 1] = GMAC_RBQB_ADDR_Msk & dwAddr;
+}
+
+/**
+ * Get Rx Queue Address
+ */
+uint32_t GMAC_GetRxQueue(Gmac *pGmac, gmacQueList_t queueIdx)
+{
+	if (!queueIdx)
+		return pGmac->GMAC_RBQB;
+	else
+		return pGmac->GMAC_RBQBAPQ[queueIdx - 1];
+}
+
+/**
+ * Set Tx Queue
+ */
+void GMAC_SetTxQueue(Gmac *pGmac, uint32_t dwAddr, gmacQueList_t queueIdx)
+{
+	if (!queueIdx)
+		pGmac->GMAC_TBQB = GMAC_TBQB_ADDR_Msk & dwAddr;
+	else
+		pGmac->GMAC_TBQBAPQ[queueIdx - 1] = GMAC_TBQB_ADDR_Msk & dwAddr;
+}
+
+/**
+ * Get Tx Queue
+ */
+uint32_t GMAC_GetTxQueue(Gmac *pGmac, gmacQueList_t queueIdx)
+{
+	if (!queueIdx)
+		return pGmac->GMAC_TBQB;
+	else
+		return pGmac->GMAC_TBQBAPQ[queueIdx - 1];
+}
+
+
+/**
+ * Write control value
+ */
+void GMAC_NetworkControl(Gmac *pGmac, uint32_t bmNCR)
+{
+	pGmac->GMAC_NCR = bmNCR;
+}
+
+
+/**
+ * Get control value
+ */
+uint32_t GMAC_GetNetworkControl(Gmac *pGmac)
+{
+	return pGmac->GMAC_NCR;
+}
+
+/**
+ * Enable interrupt(s).
+ */
+void GMAC_EnableIt(Gmac *pGmac, uint32_t dwSources, gmacQueList_t queueIdx)
+{
+	if (!queueIdx)
+		pGmac->GMAC_IER = dwSources;
+	else
+		pGmac->GMAC_IERPQ[queueIdx - 1] = dwSources;
+}
+
+/**
+ * Disable interrupt(s).
+ */
+void GMAC_DisableAllQueueIt(Gmac *pGmac, uint32_t dwSources)
+{
+	pGmac->GMAC_IDR = dwSources;
+	pGmac->GMAC_IDRPQ[0] = dwSources;
+	pGmac->GMAC_IDRPQ[1] = dwSources;
+}
+
+/**
+ * Disable interrupt(s).
+ */
+void GMAC_EnableAllQueueIt(Gmac *pGmac, uint32_t dwSources)
+{
+	pGmac->GMAC_IER = dwSources;
+	pGmac->GMAC_IERPQ[0] = dwSources;
+	pGmac->GMAC_IERPQ[1] = dwSources;
+}
+
+/**
+ * Disable interrupt(s).
+ */
+void GMAC_DisableIt(Gmac *pGmac, uint32_t dwSources, gmacQueList_t queueIdx)
+{
+	if (!queueIdx)
+		pGmac->GMAC_IDR = dwSources;
+	else
+		pGmac->GMAC_IDRPQ[queueIdx - 1] = dwSources;
+}
+
+/**
+ * Return interrupt status.
+ */
+uint32_t GMAC_GetItStatus(Gmac *pGmac, gmacQueList_t queueIdx)
+{
+	if (!queueIdx)
+		return pGmac->GMAC_ISR;
+	else
+		return pGmac->GMAC_ISRPQ[queueIdx - 1];
+}
+
+
+/**
+ * Set MAC Address
+ */
+void GMAC_SetAddress(Gmac *pGmac, uint8_t bIndex, uint8_t *pMacAddr)
+{
+	pGmac->GMAC_SA[bIndex].GMAC_SAB = (pMacAddr[3] << 24)
+									  | (pMacAddr[2] << 16)
+									  | (pMacAddr[1] <<  8)
+									  | (pMacAddr[0])
+									 ;
+	pGmac->GMAC_SA[bIndex].GMAC_SAT = (pMacAddr[5] <<  8)
+									  | (pMacAddr[4])
+									 ;
+}
+
+/**
+ * Set MAC Address via 2 DW
+ */
+void GMAC_SetAddress32(Gmac *pGmac, uint8_t bIndex, uint32_t dwMacT,
+					   uint32_t dwMacB)
+{
+	pGmac->GMAC_SA[bIndex].GMAC_SAB = dwMacB;
+	pGmac->GMAC_SA[bIndex].GMAC_SAT = dwMacT;
+}
+
+/**
+ * Set MAC Address via int64
+ */
+void GMAC_SetAddress64(Gmac *pGmac, uint8_t bIndex, uint64_t ddwMac)
+{
+	pGmac->GMAC_SA[bIndex].GMAC_SAB = (uint32_t)ddwMac;
+	pGmac->GMAC_SA[bIndex].GMAC_SAT = (uint32_t)(ddwMac > 32);
+}
+
+
+/**
+ * Clear all statistics registers
+ */
+void GMAC_ClearStatistics(Gmac *pGmac)
+{
+	pGmac->GMAC_NCR |=  GMAC_NCR_CLRSTAT;
+}
+
+/**
+ * Increase all statistics registers
+ */
+void GMAC_IncreaseStatistics(Gmac *pGmac)
+{
+	pGmac->GMAC_NCR |=  GMAC_NCR_INCSTAT;
+}
+
+/**
+ * Enable/Disable statistics registers writing.
+ */
+void GMAC_StatisticsWriteEnable(Gmac *pGmac, uint8_t bEnaDis)
+{
+	if (bEnaDis) pGmac->GMAC_NCR |=  GMAC_NCR_WESTAT;
+	else         pGmac->GMAC_NCR &= ~GMAC_NCR_WESTAT;
+}
+
+
+/**
+ * Setup network configuration register
+ */
+void GMAC_Configure(Gmac *pGmac, uint32_t dwCfg)
+{
+	pGmac->GMAC_NCFGR = dwCfg;
+}
+
+
+/**
+ * Setup DMA configuration register
+ */
+void GMAC_SetDMAConfig(Gmac *pGmac, uint32_t dwDmaCfg, gmacQueList_t queueIdx)
+{
+	if (!queueIdx)
+		pGmac->GMAC_DCFGR = dwDmaCfg;
+	else
+		pGmac->GMAC_RBSRPQ[queueIdx - 1] = dwDmaCfg;
+}
+
+/**
+ * Return DMA configuration register
+ */
+uint32_t GMAC_GetDMAConfig(Gmac *pGmac, gmacQueList_t queueIdx)
+{
+	if (!queueIdx)
+		return pGmac->GMAC_DCFGR;
+	else
+		return pGmac->GMAC_RBSRPQ[queueIdx - 1];;
+}
+
+/**
+ * Return network configuration.
+ */
+uint32_t GMAC_GetConfigure(Gmac *pGmac)
+{
+	return pGmac->GMAC_NCFGR;
+}
+
+
+/**
+ * Start transmission
+ */
+void GMAC_TransmissionStart(Gmac *pGmac)
+{
+	pGmac->GMAC_NCR |= GMAC_NCR_TSTART;
+}
+
+/**
+ * Halt transmission
+ */
+void GMAC_TransmissionHalt(Gmac *pGmac)
+{
+	pGmac->GMAC_NCR |= GMAC_NCR_THALT;
+}
+
+
+/* Screener Register configurations */
+void GMAC_ClearScreener1Reg (Gmac *pGmac, gmacQueList_t queueIdx)
+{
+	pGmac->GMAC_ST1RPQ[queueIdx] = 0u;
+}
+
+void GMAC_WriteScreener1Reg(Gmac *pGmac, gmacQueList_t queueIdx,
+							uint32_t regVal)
+{
+	pGmac->GMAC_ST1RPQ[queueIdx] = regVal;
+}
+
+void GMAC_ClearScreener2Reg (Gmac *pGmac, gmacQueList_t queueIdx)
+{
+	pGmac->GMAC_ST2RPQ[queueIdx] = 0u;
+}
+
+void GMAC_WriteScreener2Reg (Gmac *pGmac, gmacQueList_t queueIdx,
+							 uint32_t regVal)
+{
+	pGmac->GMAC_ST2RPQ[queueIdx] = regVal;
+}
+
+void GMAC_WriteEthTypeReg (Gmac *pGmac, gmacQueList_t queueIdx,
+						   uint16_t etherType)
+{
+	pGmac->GMAC_ST2ER[queueIdx] = (uint32_t)etherType;
+}
+
+void GMAC_WriteCompareReg(Gmac *pGmac, gmacQueList_t queueIdx, uint32_t c0Reg,
+						  uint16_t c1Reg)
+{
+	pGmac->GMAC_ST2COMP[queueIdx].GMAC_ST2COM0 = c0Reg;
+	pGmac->GMAC_ST2COMP[queueIdx].GMAC_ST2COM1 = (uint32_t)c1Reg;
+	memory_barrier();
+}
+
+/* CBS queue control APIs */
+void GMAC_EnableCbsQueA(Gmac *pGmac)
+{
+	pGmac->GMAC_CBSCR |= GMAC_CBSCR_QAE;
+}
+
+void GMAC_DisableCbsQueA(Gmac *pGmac)
+{
+	pGmac->GMAC_CBSCR &= ~GMAC_CBSCR_QAE;
+}
+
+void GMAC_EnableCbsQueB(Gmac *pGmac)
+{
+	pGmac->GMAC_CBSCR |= GMAC_CBSCR_QBE;
+}
+
+void GMAC_DisableCbsQueB(Gmac *pGmac)
+{
+	pGmac->GMAC_CBSCR &= ~GMAC_CBSCR_QBE;
+}
+
+
+void GMAC_ConfigIdleSlopeA(Gmac *pGmac, uint32_t idleSlopeA)
+{
+	/* 10/100 speeds use a 4-bit interface */
+	pGmac->GMAC_CBSISQA = idleSlopeA > 2u;
+}
+
+void GMAC_ConfigIdleSlopeB(Gmac *pGmac, uint32_t idleSlopeB)
+{
+	/* 10/100 speeds use a 4-bit interface */
+	pGmac->GMAC_CBSISQB = idleSlopeB > 2u;
+}
+
+void GMAC_SetTsuTmrIncReg(Gmac *pGmac, uint32_t nanoSec)
+{
+	pGmac->GMAC_TI = nanoSec;
+}
+
+uint16_t GMAC_GetPtpEvtMsgRxdMsbSec(Gmac *pGmac)
+{
+	return (uint16_t)(pGmac->GMAC_EFRSH & GMAC_EFRSH_RUD_Msk);
+}
+
+uint32_t GMAC_GetPtpEvtMsgRxdLsbSec(Gmac *pGmac)
+{
+	return (pGmac->GMAC_EFRSL & GMAC_EFRSL_RUD_Msk);
+}
+
+uint32_t GMAC_GetPtpEvtMsgRxdNanoSec(Gmac *pGmac)
+{
+	return (pGmac->GMAC_EFRN & GMAC_EFRN_RUD_Msk);
+}
+
+void GMAC_SetTsuCompare(Gmac *pGmac, uint32_t seconds47, uint32_t seconds31,
+						uint32_t nanosec)
+{
+	pGmac->GMAC_SCH = seconds47;
+	pGmac->GMAC_SCL = seconds31;
+	pGmac->GMAC_NSC = nanosec;
+	memory_barrier();
+}
+
+
+void GMAC_SetTsuCompareNanoSec(Gmac *pGmac, uint32_t nanosec)
+{
+	pGmac->GMAC_NSC = nanosec;
+}
+
+void GMAC_SetTsuCompareSec31(Gmac *pGmac, uint32_t seconds31)
+{
+	pGmac->GMAC_SCL = seconds31;
+}
+
+void GMAC_SetTsuCompareSec47(Gmac *pGmac, uint16_t seconds47)
+{
+	pGmac->GMAC_SCH = seconds47;
+}
+
+
+uint32_t GMAC_GetRxEvtFrameSec(Gmac *pGmac)
+{
+	return pGmac->GMAC_EFRSL;
+}
+
+uint32_t GMAC_GetRxEvtFrameNsec(Gmac *pGmac)
+{
+	return pGmac->GMAC_EFRN;
+}
+
+uint32_t GMAC_GetRxPeerEvtFrameSec(Gmac *pGmac)
+{
+	return pGmac->GMAC_PEFRSL;
+}
+
+uint32_t GMAC_GetRxPeerEvtFrameNsec(Gmac *pGmac)
+{
+	return pGmac->GMAC_PEFRN;
+}
+
+uint32_t GMAC_GetTxEvtFrameSec(Gmac *pGmac)
+{
+	return pGmac->GMAC_EFTSL;
+}
+
+uint32_t GMAC_GetTxEvtFrameNsec(Gmac *pGmac)
+{
+	return pGmac->GMAC_EFTN;
+}
+
+uint32_t GMAC_GetTxPeerEvtFrameSec(Gmac *pGmac)
+{
+	return pGmac->GMAC_PEFTSL;
+}
+
+uint32_t GMAC_GetTxPeerEvtFrameNsec(Gmac *pGmac)
+{
+	return pGmac->GMAC_PEFTN;
+}
Index: bsps/arm/atsam/contrib/libraries/libchip/source/gmacd.c
===================================================================
--- bsps/arm/atsam/contrib/libraries/libchip/source/gmacd.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libchip/source/gmacd.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,1054 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+ /** \file */
+
+/*---------------------------------------------------------------------------
+ *         Headers
+ *---------------------------------------------------------------------------*/
+
+#include "chip.h"
+#include <string.h>
+
+/** \addtogroup gmacd_defines
+    @{*/
+
+
+/** ISO/IEC 14882:2003(E) - 5.6 Multiplicative operators:
+ * The binary / operator yields the quotient, and the binary % operator yields
+ * the remainder from the division of the first expression by the second.
+ * If the second operand of / or % is zero the behaviour is undefined; otherwise
+ *  (a/b)*b + a%b is equal to a.
+ * If both operands are non-negative then the remainder is non-negative;
+ * if not, the sign of the remainder is implementation-defined 74).
+ */
+__STATIC_INLINE int fixed_mod(int a, int b)
+{
+	int rem = a % b;
+
+	while (rem < 0)
+		rem += b;
+
+	return rem;
+}
+
+/** Return count in buffer */
+#define GCIRC_CNT(head,tail,size)  fixed_mod((head) - (tail), (size))
+
+/** Return space available, 0..size-1. always leave one free char as a
+    completely full buffer has head == tail, which is the same as empty */
+#define GCIRC_SPACE(head,tail,size) GCIRC_CNT((tail),((head)+1),(size))
+
+/** Return count up to the end of the buffer. Carefully avoid accessing head
+    and tail more than once, so they can change underneath us without returning
+    inconsistent results */
+#define GCIRC_CNT_TO_END(head,tail,size) \
+	({int end = (size) - (tail); \
+		int n = fixed_mod((head) + end, (size));    \
+		n < end ? n : end;})
+
+/** Return space available up to the end of the buffer */
+#define GCIRC_SPACE_TO_END(head,tail,size) \
+	({int end = (size) - 1 - (head); \
+		int n = fixed_mod(end + (tail), (size));    \
+		n <= end ? n : end+1;})
+
+/** Increment head or tail */
+#define GCIRC_INC(headortail,size) \
+	headortail++;             \
+	if (headortail >= size) {  \
+		headortail = 0;       \
+	}
+
+/** Circular buffer is empty ? */
+#define GCIRC_EMPTY(head, tail)     (head == tail)
+
+/** Clear circular buffer */
+#define GCIRC_CLEAR(head, tail)  (head = tail = 0)
+
+/* This variable holds the write index into gPtpMsgTxQue */
+uint8_t ptpTxQueWriteIdx = 0u;
+uint8_t ptpTxQueReadIdx = 0u;
+
+/* This queue holds the transmit event messages */
+ptpMsgType gPtpMsgTxQue[EFRS_BUFFER_LEN];
+uint16_t gPtpMsgTxSeqId[EFRS_BUFFER_LEN];
+
+
+
+const uint32_t isrMasks[] = { GMAC_IMR_SFT, GMAC_IMR_DRQFT,
+							  GMAC_IMR_PDRQFT , GMAC_IMR_PDRSFT
+							};
+
+/*---------------------------------------------------------------------------
+ *         Local functions
+ *---------------------------------------------------------------------------*/
+
+/**
+ *  \brief Disable TX & reset registers and descriptor list
+ *  \param pDrv Pointer to GMAC Driver instance.
+ */
+static void GMACD_ResetTx(sGmacd *pDrv, gmacQueList_t queIdx)
+{
+	Gmac *pHw = pDrv->pHw;
+	uint8_t *pTxBuffer = pDrv->queueList[queIdx].pTxBuffer;
+	sGmacTxDescriptor *pTd = pDrv->queueList[queIdx].pTxD;
+	uint32_t Index;
+	uint32_t Address;
+
+	/* Disable TX */
+	GMAC_TransmitEnable(pHw, 0);
+
+	/* Setup the TX descriptors. */
+	GCIRC_CLEAR(pDrv->queueList[queIdx].wTxHead, pDrv->queueList[queIdx].wTxTail);
+
+	for (Index = 0; Index < pDrv->queueList[queIdx].wTxListSize; Index++) {
+		Address = (uint32_t)(&(pTxBuffer[Index *
+										 pDrv->queueList[queIdx].wTxBufferSize]));
+		pTd[Index].addr = Address;
+		pTd[Index].status.val = (uint32_t)GMAC_TX_USED_BIT;
+	}
+
+	pTd[pDrv->queueList[queIdx].wTxListSize - 1].status.val =
+		GMAC_TX_USED_BIT | GMAC_TX_WRAP_BIT;
+
+	/* Transmit Buffer Queue Pointer Register */
+
+	GMAC_SetTxQueue(pHw, (uint32_t)pTd, queIdx);
+}
+
+/**
+ *  \brief Disable RX & reset registers and descriptor list
+ *  \param pDrv Pointer to GMAC Driver instance.
+ */
+static void GMACD_ResetRx(sGmacd *pDrv, gmacQueList_t queIdx)
+{
+	Gmac    *pHw = pDrv->pHw;
+	uint8_t *pRxBuffer = pDrv->queueList[queIdx].pRxBuffer;
+	sGmacRxDescriptor *pRd = pDrv->queueList[queIdx].pRxD;
+
+	uint32_t Index;
+	uint32_t Address;
+
+	/* Disable RX */
+	GMAC_ReceiveEnable(pHw, 0);
+
+	/* Setup the RX descriptors. */
+	pDrv->queueList[queIdx].wRxI = 0;
+
+	for (Index = 0; Index < pDrv->queueList[queIdx].wRxListSize; Index++) {
+		Address = (uint32_t)(&(pRxBuffer[Index *
+										 pDrv->queueList[queIdx].wRxBufferSize]));
+		/* Remove GMAC_RXD_bmOWNERSHIP and GMAC_RXD_bmWRAP */
+		pRd[Index].addr.val = Address & GMAC_ADDRESS_MASK;
+		pRd[Index].status.val = 0;
+	}
+
+	pRd[pDrv->queueList[queIdx].wRxListSize - 1].addr.val |= GMAC_RX_WRAP_BIT;
+
+	/* Receive Buffer Queue Pointer Register */
+	GMAC_SetRxQueue(pHw, (uint32_t)pRd, queIdx);
+}
+
+
+/**
+ *  \brief Process successfully sent packets
+ *  \param pGmacd Pointer to GMAC Driver instance.
+ */
+static void GMACD_TxCompleteHandler(sGmacd *pGmacd, gmacQueList_t qId)
+{
+	Gmac                   *pHw = pGmacd->pHw;
+	sGmacTxDescriptor      *pTxTd;
+	fGmacdTransferCallback fTxCb;
+	uint32_t               tsr;
+
+	/* Clear status */
+	tsr = GMAC_GetTxStatus(pHw);
+	GMAC_ClearTxStatus(pHw, tsr);
+
+	while (!GCIRC_EMPTY(
+			   pGmacd->queueList[qId].wTxHead, pGmacd->queueList[qId].wTxTail)) {
+		pTxTd = &pGmacd->queueList[qId].pTxD[pGmacd->queueList[qId].wTxTail];
+
+		/* Exit if frame has not been sent yet:
+		 * On TX completion, the GMAC set the USED bit only into the
+		 * very first buffer descriptor of the sent frame.
+		 * Otherwise it updates this descriptor with status error bits.
+		 * This is the descriptor write back.
+		 */
+		if ((pTxTd->status.val & GMAC_TX_USED_BIT) == 0)
+			break;
+
+		/* Process all buffers of the current transmitted frame */
+		while ((pTxTd->status.val & GMAC_TX_LAST_BUFFER_BIT) == 0) {
+			GCIRC_INC(pGmacd->queueList[qId].wTxTail,
+					  pGmacd->queueList[qId].wTxListSize);
+			pTxTd = &pGmacd->queueList[qId].pTxD[pGmacd->queueList[qId].wTxTail];
+			memory_sync();
+		}
+
+		/* Notify upper layer that a frame has been sent */
+		fTxCb = pGmacd->queueList[qId].fTxCbList[pGmacd->queueList[qId].wTxTail];
+
+		if (fTxCb)
+			fTxCb(tsr);
+
+		/* Go to next frame */
+		GCIRC_INC(pGmacd->queueList[qId].wTxTail, pGmacd->queueList[qId].wTxListSize);
+	}
+
+	/* If a wakeup has been scheduled, notify upper layer that it can
+	   send other packets, send will be successful. */
+	if (pGmacd->queueList[qId].fWakupCb &&
+		GCIRC_SPACE(pGmacd->queueList[qId].wTxHead,
+					pGmacd->queueList[qId].wTxTail,
+					pGmacd->queueList[qId].wTxListSize) >=
+		pGmacd->queueList[qId].bWakeupThreshold)
+		pGmacd->queueList[qId].fWakupCb();
+}
+
+
+/**
+ *  \brief Reset TX queue when errors are detected
+ *  \param pGmacd Pointer to GMAC Driver instance.
+ */
+static void GMACD_TxErrorHandler(sGmacd *pGmacd, gmacQueList_t qId)
+{
+	Gmac                   *pHw = pGmacd->pHw;
+	sGmacTxDescriptor      *pTxTd;
+	fGmacdTransferCallback fTxCb;
+	uint32_t               tsr;
+
+	/* Clear TXEN bit into the Network Configuration Register:
+	 * this is a workaround to recover from TX lockups that
+	 * occur on sama5d3 gmac (r1p24f2) when using  scatter-gather.
+	 * This issue has never been seen on sama5d4 gmac (r1p31).
+	 */
+	GMAC_TransmitEnable(pHw, 0);
+
+	/* The following step should be optional since this function is called
+	 * directly by the IRQ handler. Indeed, according to Cadence
+	 * documentation, the transmission is halted on errors such as
+	 * too many retries or transmit under run.
+	 * However it would become mandatory if the call of this function
+	 * were scheduled as a task by the IRQ handler (this is how Linux
+	 * driver works). Then this function might compete with GMACD_Send().
+	 *
+	 * Setting bit 10, tx_halt, of the Network Control Register is not enough:
+	 * We should wait for bit 3, tx_go, of the Transmit Status Register to
+	 * be cleared at transmit completion if a frame is being transmitted.
+	 */
+	GMAC_TransmissionHalt(pHw);
+
+	while (GMAC_GetTxStatus(pHw) & GMAC_TSR_TXGO);
+
+	/* Treat frames in TX queue including the ones that caused the error. */
+	while (!GCIRC_EMPTY(pGmacd->queueList[qId].wTxHead,
+						pGmacd->queueList[qId].wTxTail)) {
+		int tx_completed = 0;
+		pTxTd = &pGmacd->queueList[qId].pTxD[pGmacd->queueList[qId].wTxTail];
+
+		/* Check USED bit on the very first buffer descriptor to validate
+		 * TX completion.
+		 */
+		if (pTxTd->status.val & GMAC_TX_USED_BIT)
+			tx_completed = 1;
+
+		/* Go to the last buffer descriptor of the frame */
+		while ((pTxTd->status.val & GMAC_TX_LAST_BUFFER_BIT) == 0) {
+			GCIRC_INC(pGmacd->queueList[qId].wTxTail,
+					  pGmacd->queueList[qId].wTxListSize);
+			pTxTd = &pGmacd->queueList[qId].pTxD[pGmacd->queueList[qId].wTxTail];
+		}
+
+		/* Notify upper layer that a frame status */
+		fTxCb = pGmacd->queueList[qId].fTxCbList[pGmacd->queueList[qId].wTxTail];
+
+		if (fTxCb)
+			fTxCb(tx_completed ? GMAC_TSR_TXCOMP : 0);
+
+		// TODO: which error to notify?
+
+		/* Go to next frame */
+		GCIRC_INC(pGmacd->queueList[qId].wTxTail, pGmacd->queueList[qId].wTxListSize);
+	}
+
+	/* Reset TX queue */
+	GMACD_ResetTx(pGmacd, qId);
+
+	/* Clear status */
+	tsr = GMAC_GetTxStatus(pHw);
+	GMAC_ClearTxStatus(pHw, tsr);
+
+	/* Now we are ready to start transmission again */
+	GMAC_TransmitEnable(pHw, 1);
+
+	if (pGmacd->queueList[qId].fWakupCb)
+		pGmacd->queueList[qId].fWakupCb();
+}
+
+
+/*---------------------------------------------------------------------------
+ *         Exported functions
+ *---------------------------------------------------------------------------*/
+
+
+#ifndef PTP_1588_TX_DISABLE
+
+void GMACD_TxPtpEvtMsgCBRegister (sGmacd *pGmacd,
+								  fGmacdTxPtpEvtCallBack pTxPtpEvtCb, gmacQueList_t queIdx)
+{
+	pGmacd->queueList[queIdx].fTxPtpEvtCb = pTxPtpEvtCb;
+}
+
+#endif   /* #ifdef PTP_1588_TX_DISABLE */
+
+/**
+ *  \brief GMAC Interrupt handler
+ *  \param pGmacd Pointer to GMAC Driver instance.
+ */
+void GMACD_Handler(sGmacd *pGmacd, gmacQueList_t queIdx)
+{
+	Gmac *pHw = pGmacd->pHw;
+	uint32_t isr;
+	uint32_t rsr;
+
+	/* Interrupt Status Register is cleared on read */
+	while ((isr = GMAC_GetItStatus(pHw, queIdx)) != 0) {
+		/*  Sync Frame Received - PTP */
+		if (0u != (isr & GMAC_ISR_SFR)) {
+			rsr = GMAC_ISR_SFR;
+			memory_barrier();
+
+			/* Invoke callbacks */
+			if (pGmacd->queueList[queIdx].fRxCb)
+				pGmacd->queueList[queIdx].fRxCb(rsr);
+			else {
+			}
+		} else {
+		}
+
+		/* Peer Delay Request Frame Received - PTP */
+		if (0u != (isr & GMAC_ISR_PDRQFR)) {
+			rsr = GMAC_ISR_PDRQFR;
+			memory_barrier();
+
+			/* Invoke callbacks */
+			if (pGmacd->queueList[queIdx].fRxCb)
+				pGmacd->queueList[queIdx].fRxCb(rsr);
+			else {
+			}
+		} else {
+		}
+
+		/* Peer Delay Response Frame Received - PTP */
+		if (0u != (isr & GMAC_ISR_PDRSFR)) {
+
+			rsr = GMAC_ISR_PDRSFR;
+			memory_barrier();
+
+			/* Invoke callbacks */
+			if (pGmacd->queueList[queIdx].fRxCb)
+				pGmacd->queueList[queIdx].fRxCb(rsr);
+			else {
+			}
+		} else {
+		}
+
+		if (0u != (isr & GMAC_ISR_TSU)) {
+			/* Invoke call back with flag set to TSU comparison interrupt */
+			rsr = GMAC_ISR_TSU;
+			memory_barrier();
+
+			/* Invoke callbacks */
+			if (pGmacd->queueList[queIdx].fRxCb)
+				pGmacd->queueList[queIdx].fRxCb(rsr);
+			else {
+			}
+		} else {
+		}
+
+		/* RX packet */
+		if (isr & GMAC_INT_RX_STATUS_BITS) {
+			/* Clear status */
+			rsr = GMAC_GetRxStatus(pHw);
+			GMAC_ClearRxStatus(pHw, rsr);
+
+			/* Invoke callback */
+			if (pGmacd->queueList[queIdx].fRxCb)
+				pGmacd->queueList[queIdx].fRxCb(rsr);
+		}
+
+		/* TX error */
+		if (isr & GMAC_INT_TX_STATUS_ERR_BITS) {
+			GMACD_TxErrorHandler(pGmacd, queIdx);
+			break;
+		}
+
+#ifndef PTP_1588_TX_DISABLE
+
+		/* Transmit of SYNC / PDELAY_REQ / PDELAY_RSP */
+		if (0u != (isr & isrMasks[gPtpMsgTxQue[ptpTxQueReadIdx]])) {
+			/* Invoke callback */
+			/*  Check if it is possible for multiple messages to be triggered
+			within a single isr. If so, a loop may be needed to validate the top
+			of the queue with the actual interrupt that has been triggered */
+			/* while (0u != (isr & (GMAC_IMR_SFT | GMAC_IMR_PDRQFT | GMAC_IMR_PDRSFT))) { */
+			if (pGmacd->queueList[queIdx].fTxPtpEvtCb) {
+				switch (gPtpMsgTxQue[ptpTxQueReadIdx]) {
+				case SYNC_MSG_TYPE:
+					pGmacd->queueList[queIdx].fTxPtpEvtCb
+					(gPtpMsgTxQue[ptpTxQueReadIdx],
+					 GMAC_GetTxEvtFrameSec(pHw),
+					 GMAC_GetTxEvtFrameNsec(pHw),
+					 gPtpMsgTxSeqId[ptpTxQueReadIdx]);
+					isr &= GMAC_IMR_SFT;
+					break;
+
+				case PDELAY_REQ_TYPE:
+					pGmacd->queueList[queIdx].fTxPtpEvtCb
+					(gPtpMsgTxQue[ptpTxQueReadIdx],
+					 GMAC_GetTxPeerEvtFrameSec(pHw),
+					 GMAC_GetTxPeerEvtFrameNsec(pHw),
+					 gPtpMsgTxSeqId[ptpTxQueReadIdx]);
+					isr &= GMAC_IMR_PDRQFT;
+					break;
+
+				case PDELAY_RESP_TYPE:
+					pGmacd->queueList[queIdx].fTxPtpEvtCb
+					(gPtpMsgTxQue[ptpTxQueReadIdx],
+					 GMAC_GetTxPeerEvtFrameSec(pHw),
+					 GMAC_GetTxPeerEvtFrameNsec(pHw),
+					 gPtpMsgTxSeqId[ptpTxQueReadIdx]);
+					isr &= GMAC_IMR_PDRSFT;
+					break;
+
+				default:
+					/* Only for Peer messages & sync messages */
+					break;
+				};
+			} else {
+			}
+
+			ptpTxQueReadIdx++;
+			ptpTxQueReadIdx &= (EFRS_BUFFER_LEN - 1);
+
+		} else {
+			/* if (0u != (isr & isrMasks[gPtpMsgTxQue[ptpTxQueReadIdx]])) */
+		}
+
+#endif /* #ifndef PTP_1588_TX_DISABLE */
+
+		/* TX packet */
+		if (isr & GMAC_IER_TCOMP)
+			GMACD_TxCompleteHandler(pGmacd, queIdx);
+
+		if (isr & GMAC_IER_HRESP)
+			TRACE_ERROR("HRESP\n\r");
+	}
+}
+
+
+/**
+ * \brief Initialize the GMAC with the Gmac controller address
+ *  \param pGmacd Pointer to GMAC Driver instance.
+ *  \param pHw    Pointer to HW address for registers.
+ *  \param bID     HW ID for power management
+ *  \param enableCAF    Enable/Disable CopyAllFrame.
+ *  \param enableNBC    Enable/Disable NoBroadCast.
+ */
+void GMACD_Init(sGmacd *pGmacd,
+				Gmac *pHw,
+				uint8_t bID,
+				uint8_t enableCAF,
+				uint8_t enableNBC)
+{
+	uint32_t dwNcfgr;
+
+	/* Check parameters */
+	//    assert(GRX_BUFFERS * GMAC_RX_UNITSIZE > GMAC_FRAME_LENTGH_MAX);
+
+	TRACE_DEBUG("GMAC_Init\n\r");
+
+	/* Initialize struct */
+	pGmacd->pHw = pHw;
+	pGmacd->bId = bID;
+
+	/* Power ON */
+	PMC_EnablePeripheral(bID);
+
+	/* Disable TX & RX and more */
+	GMAC_NetworkControl(pHw, 0);
+	GMAC_DisableAllQueueIt(pHw, ~0u);
+
+	GMAC_ClearStatistics(pHw);
+	/* Clear all status bits in the receive status register. */
+	GMAC_ClearRxStatus(pHw, GMAC_RSR_RXOVR | GMAC_RSR_REC
+					   | GMAC_RSR_BNA | GMAC_RSR_HNO);
+
+	/* Clear all status bits in the transmit status register */
+	GMAC_ClearTxStatus(pHw, GMAC_TSR_UBR | GMAC_TSR_COL | GMAC_TSR_RLE
+					   | GMAC_TSR_TXGO | GMAC_TSR_TFC | GMAC_TSR_TXCOMP
+					   | GMAC_TSR_HRESP);
+
+	/* Clear All interrupts */
+	GMAC_GetItStatus(pHw, GMAC_QUE_0);
+	GMAC_GetItStatus(pHw, GMAC_QUE_1);
+	GMAC_GetItStatus(pHw, GMAC_QUE_2);
+
+	/* Enable the copy of data into the buffers
+	   ignore broadcasts, and don't copy FCS. */
+	dwNcfgr = GMAC_NCFGR_FD | GMAC_NCFGR_DBW(0) | GMAC_NCFGR_CLK_MCK_64 |
+			  GMAC_NCFGR_MAXFS | GMAC_NCFGR_PEN | GMAC_NCFGR_RFCS;
+
+	if (enableCAF)
+		dwNcfgr |= GMAC_NCFGR_CAF;
+
+	if (enableNBC)
+		dwNcfgr |= GMAC_NCFGR_NBC;
+
+	GMAC_Configure(pHw, dwNcfgr);
+}
+
+
+/**
+ * Initialize necessary allocated buffer lists for GMAC Driver to transfer data.
+ * Must be invoked after GMACD_Init() but before RX/TX start.
+ * Replace the deprecated GMACD_InitTransfer().
+ * \param pGmacd Pointer to GMAC Driver instance.
+ * \param pInit  Pointer to sGmacInit.
+ * \param pInit  Pointer to gmacQueList_t for different queue.
+ * \return GMACD_OK or GMACD_PARAM.
+ * \note If input address is not 8-byte aligned the address is automatically
+ *       adjusted and the list size is reduced by one.
+ */
+uint8_t GMACD_InitTransfer(sGmacd *pGmacd, const sGmacInit *pInit,
+						   gmacQueList_t queIdx)
+{
+	Gmac *pHw = pGmacd->pHw;
+	uint8_t *pRxBuffer = pInit->pRxBuffer;
+	sGmacRxDescriptor *pRxD = pInit->pRxD;
+	uint16_t wRxBufferSize = pInit->wRxBufferSize;
+	uint16_t wRxSize = pInit->wRxSize;
+	uint8_t *pTxBuffer = pInit->pTxBuffer;
+	sGmacTxDescriptor *pTxD = pInit->pTxD;
+	uint16_t wTxBufferSize = pInit->wTxBufferSize;
+	uint16_t wTxSize = pInit->wTxSize;
+	fGmacdTransferCallback *pTxCb = pInit->pTxCb;
+	uint32_t dwDmaCfg;
+
+	if (wRxSize <= 1 || wTxSize <= 1 || pTxCb == NULL) return GMACD_PARAM;
+
+	if (!wRxBufferSize || wRxBufferSize > 16 * 1024 || wRxBufferSize & 0x3f)
+		return GMACD_PARAM;
+
+	if (!wTxBufferSize)
+		return GMACD_PARAM;
+
+	if (pInit->bIsGem) {
+		if (!queIdx) {
+			dwDmaCfg = (GMAC_DCFGR_DRBS(wRxBufferSize >> 6))
+					   | GMAC_DCFGR_RXBMS(3) | GMAC_DCFGR_TXPBMS;
+
+			switch (pInit->bDmaBurstLength) {
+			case 16:
+				dwDmaCfg |= GMAC_DCFGR_FBLDO_INCR16;
+				break;
+
+			case 8:
+				dwDmaCfg |= GMAC_DCFGR_FBLDO_INCR8;
+				break;
+
+			case 4:
+				dwDmaCfg |= GMAC_DCFGR_FBLDO_INCR4;
+				break;
+
+			case 1:
+				dwDmaCfg |= GMAC_DCFGR_FBLDO_SINGLE;
+				break;
+
+			default:
+				return GMACD_PARAM;
+			}
+		} else
+			dwDmaCfg = (GMAC_RBSRPQ_RBS(wRxBufferSize >> 6));
+
+		GMAC_SetDMAConfig(pHw, dwDmaCfg, queIdx);
+	}
+
+	pGmacd->queueList[queIdx].wRxBufferSize = wRxBufferSize;
+	pGmacd->queueList[queIdx].wTxBufferSize = wTxBufferSize;
+
+	/* Assign RX buffers */
+	if (((uint32_t)pRxBuffer & 0x7)
+		|| ((uint32_t)pRxD & 0x7)) {
+		wRxSize --;
+		TRACE_DEBUG("RX list address adjusted\n\r");
+	}
+
+	pGmacd->queueList[queIdx].pRxBuffer = (uint8_t *)((uint32_t)pRxBuffer &
+										  0xFFFFFFF8);
+	pGmacd->queueList[queIdx].pRxD = (sGmacRxDescriptor *)((
+										 uint32_t)pRxD & 0xFFFFFFF8);
+	pGmacd->queueList[queIdx].wRxListSize = wRxSize;
+
+	/* Assign TX buffers */
+	if (((uint32_t)pTxBuffer & 0x7)
+		   || ((uint32_t)pTxD & 0x7)) {
+		wTxSize --;
+		TRACE_DEBUG("TX list address adjusted\n\r");
+	}
+
+	pGmacd->queueList[queIdx].pTxBuffer = (uint8_t *)((uint32_t)pTxBuffer &
+										  0xFFFFFFF8);
+	pGmacd->queueList[queIdx].pTxD = (sGmacTxDescriptor *)((
+										 uint32_t)pTxD & 0xFFFFFFF8);
+	pGmacd->queueList[queIdx].wTxListSize = wTxSize;
+	pGmacd->queueList[queIdx].fTxCbList = pTxCb;
+
+	/* Reset TX & RX */
+	GMACD_ResetRx(pGmacd, queIdx);
+	GMACD_ResetTx(pGmacd, queIdx);
+
+	/* Setup the interrupts for RX/TX completion (and errors) */
+	switch (queIdx) {
+	case GMAC_QUE_0:
+		/* YBP: Que 0 should be configured last so as to enable transmit and
+		Receive in the NCR register */
+
+		/* Enable Rx and Tx, plus the status register. */
+		GMAC_TransmitEnable(pHw, 1);
+		GMAC_ReceiveEnable(pHw, 1);
+		GMAC_StatisticsWriteEnable(pHw, 1);
+
+		GMAC_EnableIt(pHw,
+					  GMAC_INT_RX_BITS |
+					  GMAC_INT_TX_BITS |
+					  GMAC_INT_TX_ERR_BITS, GMAC_QUE_0);
+		break;
+
+	case GMAC_QUE_1:
+		GMAC_EnableIt(pHw,
+					  GMAC_INT_RX_BITS |
+					  GMAC_INT_TX_BITS |
+					  GMAC_INT_TX_ERR_BITS, GMAC_QUE_1);
+		break;
+
+	case GMAC_QUE_2:
+		GMAC_EnableIt(pHw,
+					  GMAC_INT_RX_BITS |
+					  GMAC_INT_TX_BITS |
+					  GMAC_INT_TX_ERR_BITS, GMAC_QUE_2);
+		break;
+	};
+
+	return GMACD_OK;
+}
+
+
+/**
+ * Reset TX & RX queue & statistics
+ * \param pGmacd Pointer to GMAC Driver instance.
+ */
+void GMACD_Reset(sGmacd *pGmacd)
+{
+	Gmac *pHw = pGmacd->pHw;
+
+	GMACD_ResetRx(pGmacd, GMAC_QUE_0);
+	GMACD_ResetRx(pGmacd, GMAC_QUE_1);
+	GMACD_ResetRx(pGmacd, GMAC_QUE_2);
+
+	GMACD_ResetTx(pGmacd, GMAC_QUE_0);
+	GMACD_ResetTx(pGmacd, GMAC_QUE_1);
+	GMACD_ResetTx(pGmacd, GMAC_QUE_2);
+
+	//memset((void*)&GmacStatistics, 0x00, sizeof(GmacStats));
+	GMAC_NetworkControl(pHw, GMAC_NCR_TXEN | GMAC_NCR_RXEN
+						| GMAC_NCR_WESTAT | GMAC_NCR_CLRSTAT);
+}
+
+/**
+ * \brief Send a frame split into buffers. If the frame size is larger than
+ * transfer buffer size error returned. If frame transfer status is monitored,
+ * specify callback for each frame.
+ *  \param pGmacd Pointer to GMAC Driver instance.
+ *  \param sgl Pointer to a scatter-gather list describing the buffers of the
+ * ethernet frame.
+ *  \param fTxCb Pointer to callback function.
+ */
+uint8_t GMACD_SendSG(sGmacd *pGmacd,
+					 const sGmacSGList *sgl,
+					 fGmacdTransferCallback fTxCb,
+					 gmacQueList_t queIdx)
+{
+	Gmac *pHw = pGmacd->pHw;
+	sGmacTxDescriptor *pTd = pGmacd->queueList[queIdx].pTxD;
+	sGmacTxDescriptor *pTxTd;
+	uint16_t wTxPos, wTxHead;
+	int i;
+
+	TRACE_DEBUG("%s\n\r", __FUNCTION__);
+
+	/* Check parameter */
+	if (!sgl->len) {
+		TRACE_ERROR("%s:: ethernet frame is empty.\r\n", __FUNCTION__);
+		return GMACD_PARAM;
+	}
+
+	if (sgl->len >= pGmacd->queueList[queIdx].wTxListSize) {
+		TRACE_ERROR("%s: ethernet frame has too many buffers.\r\n", __FUNCTION__);
+		return GMACD_PARAM;
+	}
+
+	/* Check available space */
+	if (GCIRC_SPACE(pGmacd->queueList[queIdx].wTxHead,
+					pGmacd->queueList[queIdx].wTxTail,
+					pGmacd->queueList[queIdx].wTxListSize) < (int)sgl->len)
+		return GMACD_TX_BUSY;
+
+	/* Tag end of TX queue */
+	wTxHead = fixed_mod(pGmacd->queueList[queIdx].wTxHead + sgl->len,
+						pGmacd->queueList[queIdx].wTxListSize);
+	wTxPos = wTxHead;
+	pGmacd->queueList[queIdx].fTxCbList[wTxPos] = NULL;
+	pTxTd = &pTd[wTxPos];
+	pTxTd->status.val = GMAC_TX_USED_BIT;
+
+	/* Update buffer descriptors in reverse order to avoid a race
+	 * condition with hardware.
+	 */
+	for (i = (int)(sgl->len - 1); i >= 0; --i) {
+		const sGmacSG *sg = &sgl->sg[i];
+		uint32_t status;
+
+		if (sg->size > pGmacd->queueList[queIdx].wTxBufferSize) {
+			TRACE_ERROR("%s: buffer size is too big.\r\n", __FUNCTION__);
+			return GMACD_PARAM;
+		}
+
+		if (wTxPos == 0)
+			wTxPos = pGmacd->queueList[queIdx].wTxListSize - 1;
+		else
+			wTxPos--;
+
+		/* Reset TX callback */
+		pGmacd->queueList[queIdx].fTxCbList[wTxPos] = NULL;
+
+		pTxTd = &pTd[wTxPos];
+#ifdef GMAC_ZERO_COPY
+		/** Update buffer descriptor address word:
+		 *  MUST be done before status word to avoid a race condition.
+		 */
+		pTxTd->addr = (uint32_t)sg->pBuffer;
+
+#else
+
+		/* Copy data into transmission buffer */
+		if (sg->pBuffer && sg->size) {
+			memcpy((void *)pTxTd->addr, sg->pBuffer, sg->size);
+			SCB_CleanDCache_by_Addr((void *)pTxTd->addr, sg->size);
+		}
+
+#endif
+
+		/* Compute buffer descriptor status word */
+		status = sg->size & GMAC_LENGTH_FRAME;
+
+		if (i == (int)(sgl->len - 1)) {
+			status |= GMAC_TX_LAST_BUFFER_BIT;
+			pGmacd->queueList[queIdx].fTxCbList[wTxPos] = fTxCb;
+		}
+
+		if (wTxPos == pGmacd->queueList[queIdx].wTxListSize - 1)
+			status |= GMAC_TX_WRAP_BIT;
+
+		/* Update buffer descriptor status word: clear USED bit */
+		pTxTd->status.val = status;
+
+		memory_sync();
+	}
+
+	/* Update TX ring buffer pointers */
+	pGmacd->queueList[queIdx].wTxHead = wTxHead;
+	/* Now start to transmit if it is not already done */
+
+	GMAC_TransmissionStart(pHw);
+	return GMACD_OK;
+}
+
+/**
+ * \brief Send a packet with GMAC. If the packet size is larger than transfer
+ * buffer size error returned. If packet transfer status is monitored, specify
+ * callback for each packet.
+ *  \param pGmacd Pointer to GMAC Driver instance.
+ *  \param pBuffer   The buffer to be send
+ *  \param size     The size of buffer to be send
+ *  \param fTxCb Threshold Wakeup callback
+ *  \return         OK, Busy or invalid packet
+ */
+uint8_t GMACD_Send(sGmacd *pGmacd,
+				   void *pBuffer,
+				   uint32_t size,
+				   fGmacdTransferCallback fTxCb,
+				   gmacQueList_t queIdx)
+{
+	sGmacSGList sgl;
+	sGmacSG sg;
+
+	uint8_t *msgPtr;
+	ptpMsgType ptpMsg;
+	/* Init single entry scatter-gather list */
+	sg.size = size;
+	sg.pBuffer = pBuffer;
+	sgl.len = 1;
+	sgl.sg = &sg;
+
+
+
+#ifndef PTP_1588_TX_DISABLE
+
+	msgPtr = (uint8_t *)pBuffer;
+
+	if (0x88u == msgPtr[12] && 0xf7u == msgPtr[13]) {
+		/* Extract Tx PTP message  type */
+		ptpMsg = (ptpMsgType)(msgPtr[14] & 0x0F);
+
+		if (ptpMsg == SYNC_MSG_TYPE || ptpMsg == PDELAY_REQ_TYPE
+			|| ptpMsg == PDELAY_RESP_TYPE) {
+			/* Only add message to Tx queue of msg types that have
+			    tx event ISRs enabled. */
+			gPtpMsgTxQue[ptpTxQueWriteIdx] = ptpMsg;
+
+			/* Copy the Sequence Id */
+			gPtpMsgTxSeqId[ptpTxQueWriteIdx] =
+				(uint16_t)(((uint16_t)msgPtr[44] << 8) | msgPtr[45]);
+			ptpTxQueWriteIdx++;
+			ptpTxQueWriteIdx &= (EFRS_BUFFER_LEN - 1u);
+		} else {
+			/* if (ptpMsg == SYNC_MSG_TYPE || ptpMsg == PDELAY_REQ_TYPE\
+			|| ptpMsg == PDELAY_RESP_TYPE) { */
+		}
+	} else { /* if (0x88 == msgPtr[12] && 0xf7 == msgPtr[13]) { */
+	}
+
+#endif /* #ifndef PTP_1588_TX_DISABLE */
+	return GMACD_SendSG(pGmacd, &sgl, fTxCb, queIdx);
+}
+
+/**
+ * Return current load of TX.
+ * \param pGmacd   Pointer to GMAC Driver instance.
+ */
+uint32_t GMACD_TxLoad(sGmacd *pGmacd, gmacQueList_t queIdx)
+{
+	uint16_t head = pGmacd->queueList[queIdx].wTxHead;
+	uint16_t tail = pGmacd->queueList[queIdx].wTxTail;
+	return GCIRC_CNT(head, tail, pGmacd->queueList[queIdx].wTxListSize);
+}
+
+/**
+ * \brief Receive a packet with GMAC.
+ * If not enough buffer for the packet, the remaining data is lost but right
+ * frame length is returned.
+ *  \param pGmacd Pointer to GMAC Driver instance.
+ *  \param pFrame           Buffer to store the frame
+ *  \param frameSize        Size of the frame
+ *  \param pRcvSize         Received size
+ *  \return                 OK, no data, or frame too small
+ */
+uint8_t GMACD_Poll(sGmacd *pGmacd,
+				   uint8_t *pFrame,
+				   uint32_t frameSize,
+				   uint32_t *pRcvSize,
+				   gmacQueList_t queIdx)
+{
+
+	uint16_t bufferLength;
+	uint32_t   tmpFrameSize = 0;
+	uint8_t  *pTmpFrame = 0;
+	uint32_t   tmpIdx = pGmacd->queueList[queIdx].wRxI;
+	volatile sGmacRxDescriptor *pRxTd =
+		&pGmacd->queueList[queIdx].pRxD[pGmacd->queueList[queIdx].wRxI];
+
+	uint8_t isFrame = 0;
+
+	if (pFrame == NULL) return GMACD_PARAM;
+
+	/* Set the default return value */
+	*pRcvSize = 0;
+
+	/* Process received RxTd */
+	while ((pRxTd->addr.val & GMAC_RX_OWNERSHIP_BIT) == GMAC_RX_OWNERSHIP_BIT) {
+		/* A start of frame has been received, discard previous fragments */
+		if ((pRxTd->status.val & GMAC_RX_SOF_BIT) == GMAC_RX_SOF_BIT) {
+			/* Skip previous fragment */
+			while (tmpIdx != pGmacd->queueList[queIdx].wRxI) {
+				pRxTd =
+					&pGmacd->queueList[queIdx].pRxD[pGmacd->queueList[queIdx].wRxI];
+				pRxTd->addr.val &= ~(GMAC_RX_OWNERSHIP_BIT);
+				GCIRC_INC(pGmacd->queueList[queIdx].wRxI,
+						  pGmacd->queueList[queIdx].wRxListSize);
+			}
+
+			pTmpFrame = pFrame;
+			tmpFrameSize = 0;
+			/* Start to gather buffers in a frame */
+			isFrame = 1;
+		}
+
+		/* Increment the pointer */
+		GCIRC_INC(tmpIdx, pGmacd->queueList[queIdx].wRxListSize);
+
+		/* Copy data in the frame buffer */
+		if (isFrame) {
+			if (tmpIdx == pGmacd->queueList[queIdx].wRxI) {
+				TRACE_INFO("no EOF (Invalid of buffers too small)\n\r");
+
+				do {
+					pRxTd =
+						&pGmacd->queueList[queIdx].pRxD[pGmacd->queueList[queIdx].wRxI];
+					pRxTd->addr.val &= ~(GMAC_RX_OWNERSHIP_BIT);
+					GCIRC_INC(pGmacd->queueList[queIdx].wRxI,
+							  pGmacd->queueList[queIdx].wRxListSize);
+				} while (tmpIdx != pGmacd->queueList[queIdx].wRxI);
+
+				return GMACD_RX_NULL;
+			}
+
+			/* Copy the buffer into the application frame */
+			bufferLength = pGmacd->queueList[queIdx].wRxBufferSize;
+
+			if ((tmpFrameSize + bufferLength) > frameSize)
+				bufferLength = frameSize - tmpFrameSize;
+
+			SCB_InvalidateDCache_by_Addr((void *)(pRxTd->addr.val & GMAC_ADDRESS_MASK) ,
+										 bufferLength);
+			memcpy(pTmpFrame, (void *)(pRxTd->addr.val & GMAC_ADDRESS_MASK),
+				   bufferLength);
+			pTmpFrame += bufferLength;
+			tmpFrameSize += bufferLength;
+
+			/* An end of frame has been received, return the data */
+			if ((pRxTd->status.val & GMAC_RX_EOF_BIT) == GMAC_RX_EOF_BIT) {
+				/* Frame size from the GMAC */
+				*pRcvSize = (pRxTd->status.val & GMAC_LENGTH_FRAME);
+
+				/* Application frame buffer is too small all data have not been
+				    copied */
+				if (tmpFrameSize < *pRcvSize)
+					return GMACD_SIZE_TOO_SMALL;
+
+				TRACE_DEBUG("packet %d-%d (%d)\n\r",
+							pGmacd->queueList[queIdx].wRxI, tmpIdx, *pRcvSize);
+
+				/* All data have been copied in the application frame buffer
+				    => release TD */
+				while (pGmacd->queueList[queIdx].wRxI != tmpIdx) {
+					pRxTd =
+						&pGmacd->queueList[queIdx].pRxD[pGmacd->queueList[queIdx].wRxI];
+					pRxTd->addr.val &= ~(GMAC_RX_OWNERSHIP_BIT);
+					GCIRC_INC(pGmacd->queueList[queIdx].wRxI,
+							  pGmacd->queueList[queIdx].wRxListSize);
+				}
+
+				return GMACD_OK;
+			}
+		} else {
+			/* SOF has not been detected, skip the fragment */
+			pRxTd->addr.val &= ~(GMAC_RX_OWNERSHIP_BIT);
+			pGmacd->queueList[queIdx].wRxI = tmpIdx;
+		}
+
+		/* Process the next buffer */
+		pRxTd = &pGmacd->queueList[queIdx].pRxD[tmpIdx];
+	}
+
+	return GMACD_RX_NULL;
+}
+
+/**
+ * \brief Registers pRxCb callback. Callback will be invoked after the next
+ * received frame. When GMAC_Poll() returns GMAC_RX_NO_DATA the application task
+ * call GMAC_Set_RxCb() to register pRxCb() callback and enters suspend state.
+ * The callback is in charge to resume the task once a new frame has been
+ * received. The next time GMAC_Poll() is called, it will be successful.
+ *  \param pGmacd Pointer to GMAC Driver instance.
+ *  \param fRxCb   Pointer to callback function
+ *  \return        OK, no data, or frame too small
+ */
+
+void GMACD_SetRxCallback(sGmacd *pGmacd, fGmacdTransferCallback fRxCb,
+						 gmacQueList_t queIdx)
+{
+	Gmac *pHw = pGmacd->pHw;
+
+	if (fRxCb == NULL) {
+		GMAC_DisableIt(pHw, GMAC_IDR_RCOMP, queIdx);
+		pGmacd->queueList[queIdx].fRxCb = NULL;
+	} else {
+		pGmacd->queueList[queIdx].fRxCb = fRxCb;
+		GMAC_EnableIt(pHw, GMAC_IER_RCOMP, queIdx);
+	}
+}
+
+/**
+ * Register/Clear TX wakeup callback.
+ *
+ * When GMACD_Send() returns GMACD_TX_BUSY (all TD busy) the application
+ * task calls GMACD_SetTxWakeupCallback() to register fWakeup() callback and
+ * enters suspend state. The callback is in charge to resume the task once
+ * several TD have been released. The next time GMACD_Send() will be called,
+ * it shall be successful.
+ *
+ * This function is usually invoked with NULL callback from the TX wakeup
+ * callback itself, to unregister. Once the callback has resumed the
+ * application task, there is no need to invoke the callback again.
+ *
+ * \param pGmacd   Pointer to GMAC Driver instance.
+ * \param fWakeup     Wakeup callback.
+ * \param bThreshold  Number of free TD before wakeup callback invoked.
+ * \return GMACD_OK, GMACD_PARAM on parameter error.
+ */
+uint8_t GMACD_SetTxWakeupCallback(sGmacd *pGmacd,
+								  fGmacdWakeupCallback fWakeup,
+								  uint8_t bThreshold,
+								  gmacQueList_t queIdx)
+{
+	if (fWakeup == NULL)
+		pGmacd->queueList[queIdx].fWakupCb = NULL;
+	else {
+		if (bThreshold <= pGmacd->queueList[queIdx].wTxListSize) {
+			pGmacd->queueList[queIdx].fWakupCb = fWakeup;
+			pGmacd->queueList[queIdx].bWakeupThreshold = bThreshold;
+		} else
+			return GMACD_PARAM;
+	}
+
+	return GMACD_OK;
+}
Index: bsps/arm/atsam/contrib/libraries/libchip/source/hsmci.c
===================================================================
--- bsps/arm/atsam/contrib/libraries/libchip/source/hsmci.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libchip/source/hsmci.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,569 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+/** \file
+ *
+ * Implementation of High Speed MultiMedia Card Interface (HSMCI) controller.
+ */
+
+/*---------------------------------------------------------------------------
+ *         Headers
+ *---------------------------------------------------------------------------*/
+
+#include "chip.h"
+#include <assert.h>
+
+/*---------------------------------------------------------------------------
+ *         Exported functions
+ *---------------------------------------------------------------------------*/
+
+/** \addtogroup hsmci_functions
+ *@{
+ */
+
+/**
+ * \brief Enable Multi-Media Interface
+ *
+ * \param pRMci Pointer to a Hsmci instance
+ */
+extern void HSMCI_Enable(Hsmci *pRMci)
+{
+	pRMci->HSMCI_CR = HSMCI_CR_MCIEN;
+}
+
+/**
+ * \brief Disable Multi-Media Interface
+ *
+ * \param pRMci Pointer to a Hsmci instance
+ */
+extern void HSMCI_Disable(Hsmci *pRMci)
+{
+	pRMci->HSMCI_CR = HSMCI_CR_MCIDIS;
+
+}
+
+/**
+ * \brief Reset (& Disable) Multi-Media Interface
+ *
+ * \param mci Pointer to a Hsmci instance
+ * \param bBackup Backup registers values to keep previous settings, including
+ *                _MR, _SDCR, _DTOR, _CSTOR, _DMA and _CFG.
+ */
+extern void HSMCI_Reset(Hsmci *pRMci, uint8_t bBackup)
+{
+	if (bBackup) {
+		uint32_t mr    = pRMci->HSMCI_MR;
+		uint32_t dtor  = pRMci->HSMCI_DTOR;
+		uint32_t sdcr  = pRMci->HSMCI_SDCR;
+		uint32_t cstor = pRMci->HSMCI_CSTOR;
+		uint32_t dma   = pRMci->HSMCI_DMA;
+		uint32_t cfg   = pRMci->HSMCI_CFG;
+
+		pRMci->HSMCI_CR = HSMCI_CR_SWRST;
+
+		pRMci->HSMCI_MR    = mr;
+		pRMci->HSMCI_DTOR  = dtor;
+		pRMci->HSMCI_SDCR  = sdcr;
+		pRMci->HSMCI_CSTOR = cstor;
+		pRMci->HSMCI_DMA   = dma;
+		pRMci->HSMCI_CFG   = cfg;
+	} else
+		pRMci->HSMCI_CR = HSMCI_CR_SWRST;
+}
+
+/**
+ * \brief Select slot
+ * \param pRMci Pointer to a Hsmci instance
+ * \param bSlot Slot ID (0~3 for A~D).
+ */
+extern void HSMCI_Select(Hsmci *pRMci, uint8_t bSlot, uint8_t bBusWidth)
+{
+	uint32_t dwSdcr;
+	dwSdcr = (HSMCI_SDCR_SDCSEL_Msk & bSlot);
+
+	switch (bBusWidth) {
+	case 1:
+		pRMci->HSMCI_SDCR = dwSdcr | HSMCI_SDCR_SDCBUS_1;
+		break;
+
+	case 4:
+		pRMci->HSMCI_SDCR = dwSdcr | HSMCI_SDCR_SDCBUS_4;
+		break;
+
+	case 8:
+		pRMci->HSMCI_SDCR = dwSdcr | HSMCI_SDCR_SDCBUS_8;
+		break;
+	}
+}
+
+/**
+ * \brief Set slot
+ * \param pRMci Pointer to a Hsmci instance
+ * \param bSlot Slot ID (0~3 for A~D).
+ */
+extern void HSMCI_SetSlot(Hsmci *pRMci, uint8_t bSlot)
+{
+	uint32_t dwSdcr = pRMci->HSMCI_SDCR & ~HSMCI_SDCR_SDCSEL_Msk;
+	pRMci->HSMCI_SDCR = dwSdcr | (HSMCI_SDCR_SDCSEL_Msk & bSlot);
+}
+
+/**
+ * \brief Set bus width of MCI
+ * \param pRMci Pointer to a Hsmci instance
+ * \param bBusWidth 1,4 or 8 (bits).
+ */
+extern void HSMCI_SetBusWidth(Hsmci *pRMci, uint8_t bBusWidth)
+{
+	uint32_t dwSdcr = pRMci->HSMCI_SDCR & ~HSMCI_SDCR_SDCBUS_Msk;
+
+	switch (bBusWidth) {
+	case 1:
+		pRMci->HSMCI_SDCR = dwSdcr | HSMCI_SDCR_SDCBUS_1;
+		break;
+
+	case 4:
+		pRMci->HSMCI_SDCR = dwSdcr | HSMCI_SDCR_SDCBUS_4;
+		break;
+
+	case 8:
+		pRMci->HSMCI_SDCR = dwSdcr | HSMCI_SDCR_SDCBUS_8;
+		break;
+	}
+}
+
+/**
+ * \brief Return bus width setting.
+ *
+ * \param pRMci  Pointer to an MCI instance.
+ * \return 1, 4 or 8.
+ */
+extern uint8_t HSMCI_GetBusWidth(Hsmci *pRMci)
+{
+	switch (pRMci->HSMCI_SDCR & HSMCI_SDCR_SDCBUS_Msk) {
+	case HSMCI_SDCR_SDCBUS_1: return 1;
+
+	case HSMCI_SDCR_SDCBUS_4: return 4;
+
+	case HSMCI_SDCR_SDCBUS_8: return 8;
+	}
+
+	return 0;
+}
+
+/**
+ * \brief Configures a MCI peripheral as specified.
+ *
+ * \param pRMci  Pointer to an MCI instance.
+ * \param dwMode Value of the MCI Mode register.
+ */
+extern void HSMCI_ConfigureMode(Hsmci *pRMci, uint32_t dwMode)
+{
+	pRMci->HSMCI_MR = dwMode;
+
+}
+
+/**
+ * \brief Return mode register
+ * \param pRMci  Pointer to an MCI instance.
+ */
+extern uint32_t HSMCI_GetMode(Hsmci *pRMci)
+{
+	return pRMci->HSMCI_MR;
+}
+
+/**
+ * \brief Enable/Disable R/W proof
+ *
+ * \param pRMci    Pointer to an MCI instance.
+ * \param bRdProof Read proof enable/disable.
+ * \param bWrProof Write proof enable/disable.
+ */
+extern void HSMCI_ProofEnable(Hsmci *pRMci, uint8_t bRdProof, uint8_t bWrProof)
+{
+	uint32_t mr = pRMci->HSMCI_MR;
+	pRMci->HSMCI_MR = (mr & (~(HSMCI_MR_WRPROOF | HSMCI_MR_RDPROOF)))
+					  | (bRdProof ? HSMCI_MR_RDPROOF : 0)
+					  | (bWrProof ? HSMCI_MR_WRPROOF : 0)
+					 ;
+}
+
+/**
+ * \brief Padding value setting.
+ *
+ * \param pRMci    Pointer to an MCI instance.
+ * \param bPadvEn  Padding value 0xFF/0x00.
+ */
+extern void HSMCI_PadvCtl(Hsmci *pRMci, uint8_t bPadv)
+{
+	if (bPadv)
+		pRMci->HSMCI_MR |= HSMCI_MR_PADV;
+	else
+		pRMci->HSMCI_MR &= ~HSMCI_MR_PADV;
+}
+
+/**
+ * \brief Force byte transfer enable/disable.
+ *
+ * \param pRMci    Pointer to an MCI instance.
+ * \param bFByteEn FBYTE enable/disable.
+ */
+extern void HSMCI_FByteEnable(Hsmci *pRMci, uint8_t bFByteEn)
+{
+	if (bFByteEn)
+		pRMci->HSMCI_MR |= HSMCI_MR_FBYTE;
+	else
+		pRMci->HSMCI_MR &= ~HSMCI_MR_FBYTE;
+}
+
+/**
+ * \brief Check if Force Byte mode enabled.
+ *
+ * \param pRMci    Pointer to an MCI instance.
+ * \return 1 if _FBYTE is enabled.
+ */
+extern uint8_t HSMCI_IsFByteEnabled(Hsmci *pRMci)
+{
+	return ((pRMci->HSMCI_MR & HSMCI_MR_FBYTE) > 0);
+}
+
+/**
+ * \brief Set Clock Divider & Power save divider for MCI.
+ *
+ * \param pRMci    Pointer to an MCI instance.
+ * \param bClkDiv  Clock Divider value (0 ~ 255).
+ * \param bPwsDiv  Power Saving Divider (1 ~ 7).
+ */
+extern void HSMCI_DivCtrl(Hsmci *pRMci, uint32_t bClkDiv, uint8_t bPwsDiv)
+{
+	uint32_t mr = pRMci->HSMCI_MR;
+	uint32_t clkdiv , clkodd;
+	clkdiv = bClkDiv - 2;
+	clkodd = (bClkDiv & 1) ? HSMCI_MR_CLKODD : 0;
+	clkdiv = clkdiv >> 1;
+
+	pRMci->HSMCI_MR = (mr & ~(HSMCI_MR_CLKDIV_Msk | HSMCI_MR_PWSDIV_Msk))
+					  | HSMCI_MR_CLKDIV(clkdiv)
+					  | HSMCI_MR_PWSDIV(bPwsDiv)
+					  | clkodd
+					 ;
+}
+
+/**
+ * \brief Enables one or more interrupt sources of MCI peripheral.
+ *
+ * \param pRMci   Pointer to an Hsmci instance.
+ * \param sources Bitwise OR of selected interrupt sources.
+ */
+extern void HSMCI_EnableIt(Hsmci *pRMci, uint32_t dwSources)
+{
+	pRMci->HSMCI_IER = dwSources;
+}
+
+/**
+ * \brief Disable one or more interrupt sources of MCI peripheral.
+ *
+ * \param pRMci   Pointer to an Hsmci instance.
+ * \param sources Bitwise OR of selected interrupt sources.
+ */
+extern void HSMCI_DisableIt(Hsmci *pRMci, uint32_t dwSources)
+{
+	pRMci->HSMCI_IDR = dwSources;
+}
+
+/**
+ * \brief Return the interrupt mask register.
+ *
+ * \param pRMci   Pointer to an Hsmci instance.
+ * \return MCI interrupt mask register.
+ */
+extern uint32_t HSMCI_GetItMask(Hsmci *pRMci)
+{
+	return (pRMci->HSMCI_IMR);
+}
+
+/**
+ * \brief Set block len & count for transfer
+ *
+ * \param pRMci     Pointer to an Hsmci instance.
+ * \param wBlkLen   Block size.
+ * \param wCnt      Block(byte) count.
+ */
+extern void HSMCI_ConfigureTransfer(Hsmci *pRMci,
+									uint16_t wBlkLen,
+									uint16_t wCnt)
+{
+	pRMci->HSMCI_BLKR = (wBlkLen << 16) | wCnt;
+}
+
+/**
+ * \brief Set block length
+ *
+ *  Count is reset to 0.
+ *
+ * \param pRMci     Pointer to an Hsmci instance.
+ * \param wBlkSize  Block size.
+ */
+extern void HSMCI_SetBlockLen(Hsmci *pRMci, uint16_t wBlkSize)
+{
+	pRMci->HSMCI_BLKR = wBlkSize << 16;
+}
+
+/**
+ * \brief Set block (byte) count
+ *
+ * \param pRMci     Pointer to an Hsmci instance.
+ * \param wBlkCnt   Block(byte) count.
+ */
+extern void HSMCI_SetBlockCount(Hsmci *pRMci, uint16_t wBlkCnt)
+{
+	pRMci->HSMCI_BLKR |= wBlkCnt;
+}
+
+/**
+ * \brief Configure the Completion Signal Timeout
+ *
+ * \param pRMci Pointer to an Hsmci instance.
+ * \param dwConfigure Completion Signal Timeout configure.
+ */
+extern void HSMCI_ConfigureCompletionTO(Hsmci *pRMci, uint32_t dwConfigure)
+{
+	pRMci->HSMCI_CSTOR = dwConfigure;
+}
+
+/**
+ * \brief Configure the Data Timeout
+ *
+ * \param pRMci Pointer to an Hsmci instance.
+ * \param dwConfigure Data Timeout configure.
+ */
+extern void HSMCI_ConfigureDataTO(Hsmci *pRMci, uint32_t dwConfigure)
+{
+	pRMci->HSMCI_DTOR = dwConfigure;
+}
+
+/**
+ * \brief Send command
+ *
+ * \param pRMci Pointer to an Hsmci instance.
+ * \param dwCmd Command register value.
+ * \param dwArg Argument register value.
+ */
+extern void HSMCI_SendCmd(Hsmci *pRMci, uint32_t dwCmd, uint32_t dwArg)
+{
+	pRMci->HSMCI_ARGR = dwArg;
+	pRMci->HSMCI_CMDR = dwCmd;
+}
+
+
+/**
+ * \brief Return the response register.
+ *
+ * \param pRMci   Pointer to an Hsmci instance.
+ * \return MCI response register.
+ */
+extern uint32_t HSMCI_GetResponse(Hsmci *pRMci)
+{
+	return pRMci->HSMCI_RSPR[0];
+}
+
+/**
+ * \brief Return the receive data register.
+ *
+ * \param pRMci   Pointer to an Hsmci instance.
+ * \return MCI receive data register.
+ */
+extern uint32_t HSMCI_Read(Hsmci *pRMci)
+{
+	return pRMci->HSMCI_RDR;
+}
+
+/**
+ * \brief Read from FIFO
+ *
+ * \param pRMci   Pointer to an Hsmci instance.
+ * \param pdwData Pointer to data buffer.
+ * \param dwSize  Size of data buffer (in DWord).
+ */
+extern void HSMCI_ReadFifo(Hsmci *pRMci, uint8_t *pdwData, uint32_t dwSize)
+{
+	volatile uint32_t *pFIFO = (volatile uint32_t *)(pRMci->HSMCI_FIFO);
+	register uint32_t c4, c1;
+
+	if (dwSize == 0)
+		return;
+
+	c4 = dwSize >> 2;
+	c1 = dwSize & 0x3;
+
+	for (; c4; c4 --) {
+		*pdwData ++ = *pFIFO ++;
+		*pdwData ++ = *pFIFO ++;
+		*pdwData ++ = *pFIFO ++;
+		*pdwData ++ = *pFIFO ++;
+	}
+
+	for (; c1; c1 --)
+		*pdwData ++ = *pFIFO ++;
+}
+
+/**
+ * \brief Sends data through MCI peripheral.
+ *
+ * \param pRMci   Pointer to an Hsmci instance.
+ * \param
+ */
+extern void HSMCI_Write(Hsmci *pRMci, uint32_t dwData)
+{
+	pRMci->HSMCI_TDR = dwData;
+}
+
+/**
+ * \brief Write to FIFO
+ *
+ * \param pRMci   Pointer to an Hsmci instance.
+ * \param pdwData Pointer to data buffer.
+ * \param dwSize  Size of data buffer (In DWord).
+ */
+extern void HSMCI_WriteFifo(Hsmci *pRMci, uint8_t *pdwData, uint32_t dwSize)
+{
+	volatile uint32_t *pFIFO = (volatile uint32_t *)(pRMci->HSMCI_FIFO);
+	register uint32_t c4, c1;
+
+	if (dwSize == 0)
+		return;
+
+	c4 = dwSize >> 2;
+	c1 = dwSize & 0x3;
+
+	for (; c4; c4 --) {
+		*pFIFO ++ = *pdwData ++;
+		*pFIFO ++ = *pdwData ++;
+		*pFIFO ++ = *pdwData ++;
+		*pFIFO ++ = *pdwData ++;
+	}
+
+	for (; c1; c1 --)
+		*pFIFO ++ = *pdwData ++;
+}
+
+/**
+ * \brief Return the status register.
+ *
+ * \param pRMci   Pointer to an Hsmci instance.
+ * \return MCI status register.
+ */
+extern uint32_t HSMCI_GetStatus(Hsmci *pRMci)
+{
+	return pRMci->HSMCI_SR;
+}
+
+/**
+ * \brief Configure the HSMCI DMA
+ *
+ * \param pRMci Pointer to an Hsmci instance.
+ * \param dwConfigure Configure value.
+ */
+extern void HSMCI_ConfigureDma(Hsmci *pRMci, uint32_t dwConfigure)
+{
+	pRMci->HSMCI_DMA = dwConfigure;
+}
+
+/**
+ * \brief Enable the HSMCI DMA
+ *
+ * \param pRMci Pointer to an Hsmci instance.
+ * \param bEnable 1 to enable, 0 to disable.
+ */
+extern void HSMCI_EnableDma(Hsmci *pRMci, uint8_t bEnable)
+{
+	if (bEnable) {
+		pRMci->HSMCI_DMA |= HSMCI_DMA_DMAEN;//| HSMCI_DMA_CHKSIZE_32;
+	} else
+		pRMci->HSMCI_DMA &= ~HSMCI_DMA_DMAEN;
+}
+
+/**
+ * \brief Configure the HSMCI
+ *
+ * \param pRMci   Pointer to an Hsmci instance.
+ * \param dwConfigure Configure value.
+ */
+extern void HSMCI_Configure(Hsmci *pRMci, uint32_t dwConfigure)
+{
+	pRMci->HSMCI_CFG = dwConfigure;
+}
+
+/**
+ * \brief Enable/Disable High-Speed mode for MCI
+ *
+ * \param pRMci Pointer to an Hsmci instance.
+ * \param bHsEnable Enable/Disable high-speed.
+ */
+extern void HSMCI_HsEnable(Hsmci *pRMci, uint8_t bHsEnable)
+{
+	if (bHsEnable)
+		pRMci->HSMCI_CFG |= HSMCI_CFG_HSMODE;
+	else
+		pRMci->HSMCI_CFG &= ~HSMCI_CFG_HSMODE;
+}
+
+/**
+ * \brief Check if High-speed mode is enabled on MCI
+ * \param pRMci Pointer to an Hsmci instance.
+ * \return 1
+ */
+extern uint8_t HSMCI_IsHsEnabled(Hsmci *pRMci)
+{
+	return ((pRMci->HSMCI_CFG & HSMCI_CFG_HSMODE) > 0);
+}
+
+/**
+ * \brief Configure the Write Protection Mode
+ *
+ * \param pRMci   Pointer to an Hsmci instance.
+ * \param dwConfigure WP mode configure value.
+ */
+extern void HSMCI_ConfigureWP(Hsmci *pRMci, uint32_t dwConfigure)
+{
+	pRMci->HSMCI_WPMR = dwConfigure;
+}
+
+/**
+ * \brief Return the write protect status register.
+ *
+ * \param pRMci   Pointer to an Hsmci instance.
+ * \return MCI write protect status register.
+ */
+extern uint32_t HSMCI_GetWPStatus(Hsmci *pRMci)
+{
+	return pRMci->HSMCI_WPSR;
+}
+
+/**@}*/
+
Index: bsps/arm/atsam/contrib/libraries/libchip/source/icm.c
===================================================================
--- bsps/arm/atsam/contrib/libraries/libchip/source/icm.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libchip/source/icm.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,234 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+/** \addtogroup icm_module Working with ICM
+ *  \ingroup peripherals_module
+ * The TWI driver provides the interface to True Random Number Generator (ICM)
+ * passes the American NIST Special Publication 800-22 and Die-hard
+ * Random Tests Suites.
+ * The ICM may be used as an entropy source for seeding an NIST approved DRNG
+ * (Deterministic RNG) as required by FIPS PUB 140-2 and 140-3. use the TWI
+ * peripheral.
+ *
+ * \section Usage
+ * <ul>
+ * <li> Configures a TWI peripheral to operate in master mode, at the given
+ * frequency (in Hz) using TWI_Configure(). </li>
+ * <li> Sends a STOP condition on the TWI using TWI_Stop().</li>
+ * <li> Starts a read operation on the TWI bus with the specified slave using
+ * TWI_StartRead(). Data must then be read using TWI_ReadByte() whenever
+ * a byte is available (poll using TWI_ByteReceived()).</li>
+ * <li> Starts a write operation on the TWI to access the selected slave using
+ * TWI_StartWrite(). A byte of data must be provided to start the write;
+ * other bytes are written next.</li>
+ * <li> Sends a byte of data to one of the TWI slaves on the bus using
+ * TWI_WriteByte().
+ * This function must be called once before TWI_StartWrite() with the first byte
+ * of data to send, then it ICMll be called repeatedly after that to send the
+ * remaining bytes.</li>
+ * <li> Check if a byte has been received and can be read on the given TWI
+ * peripheral using TWI_ByteReceived().<
+ * Check if a byte has been sent using TWI_ByteSent().</li>
+ * <li> Check if the current transmission is complete (the STOP has been sent)
+ * using TWI_TransferComplete().</li>
+ * <li> Enables & disable the selected interrupts sources on a TWI peripheral
+ * using TWI_EnableIt() and TWI_DisableIt().</li>
+ * <li> Get current status register of the given TWI peripheral using
+ * TWI_GetStatus(). Get current status register of the given TWI peripheral, but
+ * masking interrupt sources which are not currently enabled using
+ * TWI_GetMaskedStatus().</li>
+ * </ul>
+ * For more accurate information, please look at the TWI section of the
+ * Datasheet.
+ *
+ * Related files :\n
+ * \ref twi.c\n
+ * \ref twi.h.\n
+ */
+/*@{*/
+/*@}*/
+
+/**
+ * \file
+ *
+ * Implementation of True Random Number Generator (ICM)
+ *
+ */
+
+/*----------------------------------------------------------------------------
+ *        Headers
+ *----------------------------------------------------------------------------*/
+
+#include "chip.h"
+
+/*----------------------------------------------------------------------------
+ *        Exported functions
+ *----------------------------------------------------------------------------*/
+
+/**
+ * \brief Enable ICM, the ICM controller is activated
+ */
+void ICM_Enable(void)
+{
+	ICM->ICM_CTRL = ICM_CTRL_ENABLE;
+}
+
+/**
+ * \brief Disable ICM, if a region is active, this region is terminated
+ */
+void ICM_Disable(void)
+{
+	ICM->ICM_CTRL = ICM_CTRL_DISABLE;
+}
+
+/**
+ * \brief Resets the ICM controller.
+ */
+void ICM_SoftReset(void)
+{
+	ICM->ICM_CTRL = ICM_CTRL_SWRST;
+}
+
+/**
+ * \brief Recompute Internal hash.
+ * \param region, When REHASH[region] is set to one, the region digest is
+ * re-computed.
+ * \note This bit is only available when Region monitoring is disabled.
+ */
+void ICM_ReComputeHash(uint8_t region)
+{
+	ICM->ICM_CTRL = ICM_CTRL_REHASH(region);
+}
+
+/**
+ * \brief Enable region monitoring for given region
+ * \param region, When bit RMEN[region] is set to one, the monitoring of Region
+ * is activated.
+ */
+void ICM_EnableMonitor(uint8_t region)
+{
+	ICM->ICM_CTRL = ICM_CTRL_RMEN(region);
+}
+
+/**
+ * \brief Disable region monitoring for given region
+ * \param region, When bit RMDIS[region] is set to one, the monitoring of
+ * Region is disabled.
+ */
+void ICM_DisableMonitor(uint8_t region)
+{
+	ICM->ICM_CTRL = ICM_CTRL_RMDIS(region);
+}
+
+/**
+ * \brief Configures an ICM peripheral with the specified parameters.
+ *  \param mode  Desired value for the ICM mode register (see the datasheet).
+ */
+void ICM_Configure(uint32_t mode)
+{
+	ICM->ICM_CFG = mode;
+}
+
+/**
+ * \brief Enables the selected interrupts sources on a ICM peripheral.
+ * \param sources  Bitwise OR of selected interrupt sources.
+ */
+void ICM_EnableIt(uint32_t sources)
+{
+	ICM->ICM_IER = sources;
+}
+
+/**
+ * \brief Disables the selected interrupts sources on a ICM peripheral.
+ * \param sources  Bitwise OR of selected interrupt sources.
+ */
+void ICM_DisableIt(uint32_t sources)
+{
+	ICM->ICM_IDR = sources;
+}
+
+/**
+ * \brief Get the current interrupt status register of the given ICM peripheral.
+ * \return  ICM status register.
+ */
+uint32_t ICM_GetIntStatus(void)
+{
+	return ICM->ICM_ISR;
+}
+
+/**
+ * \brief Get the current status register of the given ICM peripheral.
+ * \return  ICM status register.
+ */
+uint32_t ICM_GetStatus(void)
+{
+	return ICM->ICM_SR;
+}
+
+
+/**
+ * \brief Get the undefined access status register of the given ICM peripheral.
+ * \return  ICM status register.
+ */
+uint32_t ICM_GetUStatus(void)
+{
+	return ICM->ICM_UASR;
+}
+
+/**
+ * \brief Set descriptor area start address register.
+ * \param addr start address
+ * \note The start address is a multiple of the total size of the data structure
+ * (64 bytes).
+ */
+void ICM_SetDescStartAddress(uint32_t addr)
+{
+	ICM->ICM_DSCR = addr;
+}
+
+/**
+ * \brief Set hash area start address register.
+ * \param addr start address
+ * \note This field points at the Hash memory location. The address must be a
+ * multiple of 128 bytes.
+ */
+void ICM_SetHashStartAddress(uint32_t addr)
+{
+	ICM->ICM_HASH = addr;
+}
+
+/**
+ * \brief Set ICM user initial Hash value register.
+ * \param val Initial Hash Value
+ */
+void ICM_SetInitHashValue(uint32_t val)
+{
+	ICM->ICM_UIHVAL[0] = ICM_UIHVAL_VAL(val);
+}
+
Index: bsps/arm/atsam/contrib/libraries/libchip/source/isi.c
===================================================================
--- bsps/arm/atsam/contrib/libraries/libchip/source/isi.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libchip/source/isi.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,385 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+/*----------------------------------------------------------------------------
+ *        Headers
+ *----------------------------------------------------------------------------*/
+
+#include "chip.h"
+
+/*----------------------------------------------------------------------------
+ *        Local functions
+ *----------------------------------------------------------------------------*/
+
+/**
+ * \brief Workaround for ISI CFG2 register read.
+ * \note The ISI_CFG2[31:27] can be written correctly, because the input writing
+ * data are assigned directly to the internal control bits as specified,
+ * the mismatch only happens in reading operation.
+ * [31:28] are shift right 1 bit, so [31:27] can be read from [30:27].
+ */
+__STATIC_INLINE uint32_t _ISI_GetCFG2_Workaround(void)
+{
+	uint32_t wrongfield;
+	wrongfield = ISI->ISI_CFG2 >> (ISI_CFG2_YCC_SWAP_Pos - 1);
+	return (ISI->ISI_CFG2 & 0x07FFFFFF) | (wrongfield << ISI_CFG2_YCC_SWAP_Pos);
+}
+
+/*----------------------------------------------------------------------------
+ *        Export functions
+ *----------------------------------------------------------------------------*/
+
+/**
+ * \brief Enable ISI
+ */
+void ISI_Enable(void)
+{
+	ISI->ISI_CR |= ISI_CR_ISI_EN;
+
+	while ((ISI->ISI_SR & ISI_CR_ISI_EN) != ISI_CR_ISI_EN);
+}
+
+/**
+ * \brief Enable ISI Dma channel
+ * \param  channel to be enabled
+ */
+void ISI_DmaChannelEnable(uint32_t channel)
+{
+	ISI->ISI_DMA_CHER |= channel;
+}
+
+/**
+ * \brief Disable ISI Dma channel
+ * \param  channel to be disabled
+ */
+void ISI_DmaChannelDisable(uint32_t channel)
+{
+	ISI->ISI_DMA_CHDR |= channel;
+}
+
+/**
+ * \brief Disable ISI
+ */
+void ISI_Disable(void)
+{
+	/* Write one to this field to disable the module */
+	ISI->ISI_CR |= ISI_CR_ISI_DIS;
+
+	/* Software must poll DIS_DONE field in the ISI_STATUS register to verify that the command
+	has successfully completed.*/
+	while ((ISI->ISI_SR & ISI_SR_DIS_DONE) != ISI_SR_DIS_DONE);
+}
+
+
+/**
+ * \brief Enable ISI interrupt
+ * \param  flag of interrupt to enable
+ */
+void ISI_EnableInterrupt(uint32_t flag)
+{
+	ISI->ISI_IER = flag;
+}
+
+/**
+ * \brief Disable ISI interrupt
+ * \param  flag of interrupt to disable
+ */
+void ISI_DisableInterrupt(uint32_t flag)
+{
+	ISI->ISI_IDR = flag;
+}
+
+/**
+ * \brief Return ISI status register
+ * \return Status of ISI register
+ */
+uint32_t ISI_StatusRegister(void)
+{
+	return (ISI->ISI_SR);
+}
+
+/**
+ * \brief Enable Codec path for capture next frame
+ */
+void ISI_CodecPathFull(void)
+{
+	// The codec path is enabled and the next frame is captured.
+	// Both codec and preview data-paths are working simultaneously
+	ISI->ISI_CR |= ISI_CR_ISI_CDC;
+	ISI->ISI_CFG1 |= ISI_CFG1_FULL;
+}
+
+/**
+ * \brief Set frame rate
+ * \param frame frame rate capture
+ */
+void ISI_SetFrameRate(uint32_t frame)
+{
+	if (frame > 7) {
+		TRACE_ERROR("rate too big\n\r");
+		frame = 7;
+	}
+
+	ISI->ISI_CFG1 |= ISI_CFG1_FRATE(frame);
+}
+
+/**
+ * \brief Get the number of byte per pixels
+ * \param bmpRgb BMP type can be YUV or RGB
+ */
+uint8_t ISI_BytesForOnePixel(uint8_t bmpRgb)
+{
+	uint8_t nbByte_Pixel;
+
+	if (bmpRgb == RGB) {
+		if ((_ISI_GetCFG2_Workaround() & ISI_CFG2_RGB_MODE) == ISI_CFG2_RGB_MODE) {
+			// RGB: 5:6:5 16bits/pixels
+			nbByte_Pixel = 2;
+		} else {
+			// RGB: 8:8:8 24bits/pixels
+			nbByte_Pixel = 3;
+		}
+	} else {
+		// YUV: 2 pixels for 4 bytes
+		nbByte_Pixel = 2;
+	}
+
+	return nbByte_Pixel;
+}
+
+/**
+ * \brief Reset ISI
+ */
+void ISI_Reset(void)
+{
+	uint32_t timeout = 0;
+
+	// Resets the image sensor interface.
+	// Finish capturing the current frame and then shut down the module.
+	ISI->ISI_CR = ISI_CR_ISI_SRST | ISI_CR_ISI_DIS;
+
+	// wait Software reset has completed successfully.
+	while ((!(ISI->ISI_SR & ISI_SR_SRST))
+			&& (timeout < 0x5000))
+		timeout++;
+
+	if (timeout == 0x5000)
+		TRACE_ERROR("ISI-Reset timeout\n\r");
+}
+
+
+/**
+ * \brief Set the windows blank
+ * \param hBlank  pixel clock periods to wait before the beginning of a line.
+ * \param vBlank  lines are skipped at the beginning of the frame.
+ */
+void ISI_SetBlank(uint8_t hBlank, uint8_t vBlank)
+{
+	ISI->ISI_CFG1 |= ISI_CFG1_SLD(hBlank) + ISI_CFG1_SFD(vBlank);
+}
+
+
+/**
+ * \brief Set vertical and horizontal Size of the Image Sensor
+ * \param hSize  Horizontal size of the Image sensor [0..2047].
+ * \param vSize  Vertical size of the Image sensor [0..2047].
+ */
+void ISI_SetSensorSize(uint32_t hSize, uint32_t vSize)
+{
+	uint32_t val;
+	val = _ISI_GetCFG2_Workaround();
+	val &= (~ISI_CFG2_IM_VSIZE_Msk);
+	val &= (~ISI_CFG2_IM_HSIZE_Msk);
+	// IM_VSIZE: Vertical size of the Image sensor [0..2047]
+	// Vertical size = IM_VSIZE + 1
+	// IM_HSIZE: Horizontal size of the Image sensor [0..2047]
+	// Horizontal size = IM_HSIZE + 1
+	ISI->ISI_CFG2 &= (~ISI_CFG2_IM_VSIZE_Msk);
+	ISI->ISI_CFG2 &= (~ISI_CFG2_IM_HSIZE_Msk);
+	ISI->ISI_CFG2 = val | ISI_CFG2_IM_VSIZE(vSize - 1) | ISI_CFG2_IM_HSIZE(
+						hSize - 1);
+}
+
+/**
+ * \brief Defines RGB pattern when RGB_MODE is set to 1.
+ * \param wRgbPixelMapping  RGB pattern
+ */
+void ISI_RgbPixelMapping(uint32_t wRgbPixelMapping)
+{
+	ISI->ISI_CFG2 = _ISI_GetCFG2_Workaround() & (~ISI_CFG2_RGB_CFG_Msk);
+
+	if (wRgbPixelMapping != ISI_CFG2_RGB_CFG_DEFAULT)
+		ISI->ISI_CFG2 = _ISI_GetCFG2_Workaround() | wRgbPixelMapping
+						| ISI_CFG2_RGB_MODE;
+	else
+		ISI->ISI_CFG2 = _ISI_GetCFG2_Workaround();
+}
+
+/**
+ * \brief Enables RGB swap
+ * \param swapMode  0: D7-R7, 1: D0-R7
+ */
+void ISI_RgbSwapMode(uint32_t swapMode)
+{
+	ISI->ISI_CFG2 = _ISI_GetCFG2_Workaround() & (~ISI_CFG2_RGB_SWAP);
+
+	if (swapMode) ISI->ISI_CFG2 = _ISI_GetCFG2_Workaround() | ISI_CFG2_RGB_SWAP;
+}
+
+/**
+ * \brief Defines YCrCb swap format.
+ * \param wYuvSwapMode YUV Swap format
+ */
+void ISI_YCrCbFormat(uint32_t wYuvSwapMode)
+{
+	ISI->ISI_CFG2 = _ISI_GetCFG2_Workaround() & (~ISI_CFG2_YCC_SWAP_Msk);
+	ISI->ISI_CFG2 = _ISI_GetCFG2_Workaround() | wYuvSwapMode;
+}
+
+/**
+ * \brief Input image is assumed to be grayscale-coded.
+ * \param wPixelFormat  0: 2 pixels per word, 1:1 pixel per word.
+ */
+void ISI_setGrayScaleMode(uint32_t wPixelFormat)
+{
+	ISI->ISI_CFG2 = _ISI_GetCFG2_Workaround() | ISI_CFG2_GRAYSCALE;
+
+	if (wPixelFormat) ISI->ISI_CFG2 = _ISI_GetCFG2_Workaround() | ISI_CFG2_GS_MODE;
+
+}
+
+/**
+ * \brief Set data stream format.
+ * \param wStreamMode  0: YUV input, 1: RGB 8:8:8/5:6:5 input
+ */
+void ISI_setInputStream(uint32_t wStreamMode)
+{
+	ISI->ISI_CFG2 = _ISI_GetCFG2_Workaround() & (~ISI_CFG2_COL_SPACE);
+
+	if (wStreamMode) ISI->ISI_CFG2 = _ISI_GetCFG2_Workaround() | ISI_CFG2_COL_SPACE;
+}
+
+/**
+ * \brief Set preview size.
+ * \param hSize  Horizontal Preview size  (640 max only in RGB mode).
+ * \param vSize  Vertical Preview size  (480 max only in RGB mode).
+ */
+void ISI_setPreviewSize(uint32_t hSize, uint32_t vSize)
+{
+	if (hSize > 640) hSize = 640;
+
+	if (vSize > 480) vSize = 480;
+
+	ISI->ISI_PSIZE = ISI_PSIZE_PREV_VSIZE(vSize - 1) | ISI_PSIZE_PREV_HSIZE(
+						 hSize - 1);
+}
+
+/**
+ * \brief calculate scaler factor automatically.
+ * \note The sensor size and preview size for LCD was configured before this setting.
+ */
+void ISI_calcScalerFactor(void)
+{
+	uint32_t hLcdSize, hSensorSize;
+	uint32_t hRatio;
+	hLcdSize = ((ISI->ISI_PSIZE & ISI_PSIZE_PREV_HSIZE_Msk) >>
+				ISI_PSIZE_PREV_HSIZE_Pos) + 1;
+	hSensorSize = ((_ISI_GetCFG2_Workaround() & ISI_CFG2_IM_HSIZE_Msk)
+				   >> ISI_CFG2_IM_HSIZE_Pos) + 1;
+	hRatio = 1600 * hSensorSize / hLcdSize;
+	ISI->ISI_PDECF = (hRatio / 100);
+}
+
+/**
+ * \brief Configure DMA for preview path.
+ * \param baseFrameBufDesc  Preview Descriptor Address.
+ * \param dmaCtrl  DMA Preview Control.
+ * \param frameBufferStartAddr  DMA Preview Base Address.
+ */
+void ISI_setDmaInPreviewPath(uint32_t baseFrameBufDesc,
+							 uint32_t dmaCtrl, uint32_t frameBufferStartAddr)
+{
+	ISI->ISI_DMA_P_DSCR = baseFrameBufDesc;
+	ISI->ISI_DMA_P_CTRL = dmaCtrl;
+	ISI->ISI_DMA_P_ADDR = frameBufferStartAddr;
+}
+
+/**
+ * \brief Configure DMA for Codec path.
+ * \param baseFrameBufDesc  Preview Descriptor Address.
+ * \param dmaCtrl  DMA Preview Control.
+ * \param frameBufferStartAddr  DMA Preview Base Address.
+ */
+void ISI_setDmaInCodecPath(uint32_t baseFrameBufDesc,
+						   uint32_t dmaCtrl, uint32_t frameBufferStartAddr)
+{
+	ISI->ISI_DMA_C_DSCR = baseFrameBufDesc;
+	ISI->ISI_DMA_C_CTRL = dmaCtrl;
+	ISI->ISI_DMA_C_ADDR = frameBufferStartAddr;
+}
+
+/**
+ * \brief ISI set matrix for YUV to RGB color space for preview path.
+ * \param yuv2rgb structure of YUV to RBG parameters.
+ */
+void ISI_SetMatrix4Yuv2Rgb (ISI_Y2R *yuv2rgb)
+{
+	ISI->ISI_Y2R_SET0 = ISI_Y2R_SET0_C0(yuv2rgb->C0)
+						| ISI_Y2R_SET0_C1(yuv2rgb->C1)
+						| ISI_Y2R_SET0_C2(yuv2rgb->C2)
+						| ISI_Y2R_SET0_C3(yuv2rgb->C3);
+
+	ISI->ISI_Y2R_SET1 = ISI_Y2R_SET1_C4(yuv2rgb->C4)
+						| ((yuv2rgb->Yoff == 1) ? ISI_Y2R_SET1_Yoff : 0)
+						| ((yuv2rgb->Croff == 1) ? ISI_Y2R_SET1_Croff : 0)
+						| ((yuv2rgb->Cboff == 1) ? ISI_Y2R_SET1_Cboff : 0);
+}
+
+/**
+ * \brief ISI set matrix for RGB to YUV color space for codec path.
+ * \param rgb2yuv structure of RGB to YUV parameters.
+ */
+void ISI_SetMatrix4Rgb2Yuv (ISI_R2Y *rgb2yuv)
+{
+	ISI->ISI_R2Y_SET0 = ISI_R2Y_SET0_C0(rgb2yuv->C0)
+						| ISI_R2Y_SET0_C1(rgb2yuv->C1)
+						| ISI_R2Y_SET0_C2(rgb2yuv->C2)
+						| ((rgb2yuv->Roff == 1) ? ISI_R2Y_SET0_Roff : 0);
+
+	ISI->ISI_R2Y_SET1 = ISI_R2Y_SET1_C3(rgb2yuv->C3)
+						| ISI_R2Y_SET1_C4(rgb2yuv->C4)
+						| ISI_R2Y_SET1_C5(rgb2yuv->C5)
+						| ((rgb2yuv->Goff == 1) ? ISI_R2Y_SET1_Goff : 0);
+
+	ISI->ISI_R2Y_SET2 = ISI_R2Y_SET2_C6(rgb2yuv->C6)
+						| ISI_R2Y_SET2_C7(rgb2yuv->C7)
+						| ISI_R2Y_SET2_C8(rgb2yuv->C8)
+						| ((rgb2yuv->Boff == 1) ? ISI_R2Y_SET2_Boff : 0);
+}
+
Index: bsps/arm/atsam/contrib/libraries/libchip/source/mcan.c
===================================================================
--- bsps/arm/atsam/contrib/libraries/libchip/source/mcan.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libchip/source/mcan.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,1175 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+/** \file
+ *  Implements functions for Controller Area Network (CAN)
+ *  peripheral operations.
+ */
+/** \addtogroup can_module
+ *@{*/
+
+
+/*----------------------------------------------------------------------------
+ *        Headers
+ *----------------------------------------------------------------------------*/
+#ifndef __rtems__
+#include "board.h"
+#endif /* __rtems__ */
+#include "chip.h"
+#include "mcan_config.h"
+#include <assert.h>
+/*---------------------------------------------------------------------------
+ *      Definitions
+ *---------------------------------------------------------------------------*/
+#define MAILBOX_ADDRESS(address) (0xFFFC & (address))
+
+#define CAN_CLK_FREQ_HZ               MCAN_PROG_CLK_FREQ_HZ
+
+#define MCAN0_TSEG1                   (MCAN0_PROP_SEG + MCAN0_PHASE_SEG1)
+#define MCAN0_TSEG2                   (MCAN0_PHASE_SEG2)
+#define MCAN0_BRP                     ((uint32_t) (((float) CAN_CLK_FREQ_HZ / \
+									   ((float)(MCAN0_TSEG1 + MCAN0_TSEG2 + 3) *\
+										(float) MCAN0_BIT_RATE_BPS)) - 1))
+#define MCAN0_SJW                     (MCAN0_SYNC_JUMP - 1)
+#define MCAN0_FTSEG1                  (MCAN0_FAST_PROP_SEG + MCAN0_FAST_PHASE_SEG1)
+#define MCAN0_FTSEG2                  (MCAN0_FAST_PHASE_SEG2)
+#define MCAN0_FBRP                    ((uint32_t) (((float) CAN_CLK_FREQ_HZ / \
+									   ((float)(MCAN0_FTSEG1 + MCAN0_FTSEG2 + 3) * \
+										(float) MCAN0_FAST_BIT_RATE_BPS)) - 1))
+#define MCAN0_FSJW                    (MCAN0_FAST_SYNC_JUMP - 1)
+
+#define MCAN0_STD_FLTS_WRDS           (MCAN0_NMBR_STD_FLTS)
+/* 128 max filters */
+#define MCAN0_EXT_FLTS_WRDS           (MCAN0_NMBR_EXT_FLTS * 2)
+/* 64 max filters */
+#define MCAN0_RX_FIFO0_WRDS           (MCAN0_NMBR_RX_FIFO0_ELMTS * \
+									   ((MCAN0_RX_FIFO0_ELMT_SZ/4) + 2))
+/* 64 elements max */
+#define MCAN0_RX_FIFO1_WRDS           (MCAN0_NMBR_RX_FIFO1_ELMTS *\
+									   ((MCAN0_RX_FIFO1_ELMT_SZ/4) + 2))
+/* 64 elements max */
+#define MCAN0_RX_DED_BUFS_WRDS            (MCAN0_NMBR_RX_DED_BUF_ELMTS * \
+		((MCAN0_RX_BUF_ELMT_SZ/4) + 2))
+/* 64 elements max */
+#define MCAN0_TX_EVT_FIFO_WRDS        (MCAN0_NMBR_TX_EVT_FIFO_ELMTS * 2)
+/* 32 elements max */
+#define MCAN0_TX_DED_BUF_WRDS         (MCAN0_NMBR_TX_DED_BUF_ELMTS * \
+									   ((MCAN0_TX_BUF_ELMT_SZ/4) + 2))
+/* 32 elements max */
+#define MCAN0_TX_FIFO_Q_WRDS          (MCAN0_NMBR_TX_FIFO_Q_ELMTS *\
+									   ((MCAN0_TX_BUF_ELMT_SZ/4) + 2))
+/* 32 elements max */
+
+#define MCAN1_TSEG1                   (MCAN1_PROP_SEG + MCAN1_PHASE_SEG1)
+#define MCAN1_TSEG2                   (MCAN1_PHASE_SEG2)
+#define MCAN1_BRP                     ((uint32_t) (((float) CAN_CLK_FREQ_HZ / \
+									   ((float)(MCAN1_TSEG1 + MCAN1_TSEG2 + 3) *\
+										(float) MCAN1_BIT_RATE_BPS)) - 1))
+#define MCAN1_SJW                     (MCAN1_SYNC_JUMP - 1)
+#define MCAN1_FTSEG1                  (MCAN1_FAST_PROP_SEG + MCAN1_FAST_PHASE_SEG1)
+#define MCAN1_FTSEG2                  (MCAN1_FAST_PHASE_SEG2)
+#define MCAN1_FBRP                    ((uint32_t) (((float) CAN_CLK_FREQ_HZ /\
+									   ((float)(MCAN1_FTSEG1 + MCAN1_FTSEG2 + 3) *\
+										(float) MCAN1_FAST_BIT_RATE_BPS)) - 1))
+#define MCAN1_FSJW                    (MCAN1_FAST_SYNC_JUMP - 1)
+
+#define MCAN1_STD_FLTS_WRDS           (MCAN1_NMBR_STD_FLTS)
+/* 128 max filters */
+#define MCAN1_EXT_FLTS_WRDS           (MCAN1_NMBR_EXT_FLTS * 2)
+/* 64 max filters */
+#define MCAN1_RX_FIFO0_WRDS           (MCAN1_NMBR_RX_FIFO0_ELMTS * \
+									   ((MCAN1_RX_FIFO0_ELMT_SZ/4) + 2))
+/* 64 elements max */
+#define MCAN1_RX_FIFO1_WRDS           (MCAN1_NMBR_RX_FIFO1_ELMTS *\
+									   ((MCAN1_RX_FIFO1_ELMT_SZ/4) + 2))
+/* 64 elements max */
+#define MCAN1_RX_DED_BUFS_WRDS            (MCAN1_NMBR_RX_DED_BUF_ELMTS * \
+		((MCAN1_RX_BUF_ELMT_SZ/4) + 2))
+/* 64 elements max */
+#define MCAN1_TX_EVT_FIFO_WRDS        (MCAN1_NMBR_TX_EVT_FIFO_ELMTS * 2)
+/* 32 elements max */
+#define MCAN1_TX_DED_BUF_WRDS         (MCAN1_NMBR_TX_DED_BUF_ELMTS * \
+									   ((MCAN1_TX_BUF_ELMT_SZ/4) + 2))
+/* 32 elements max */
+#define MCAN1_TX_FIFO_Q_WRDS          (MCAN1_NMBR_TX_FIFO_Q_ELMTS * \
+									   ((MCAN1_TX_BUF_ELMT_SZ/4) + 2))
+/* 32 elements max */
+
+/* validate CAN0 entries */
+#if (MCAN0_TSEG1 > 63)
+	#error "Invalid CAN0 TSEG1"
+#endif
+#if (MCAN0_TSEG2 > 15)
+	#error "Invalid CAN0 TSEG2"
+#endif
+#if (MCAN0_SJW > 15)
+	#error "Invalid CAN0 SJW"
+#endif
+#if (MCAN0_FTSEG1 > 15)
+	#error "Invalid CAN0 FTSEG1"
+#endif
+#if (MCAN0_FTSEG2 > 7)
+	#error "Invalid CAN0 FTSEG2"
+#endif
+#if (MCAN0_FSJW > 3)
+	#error "Invalid CAN0 FSJW"
+#endif
+
+#if (MCAN0_NMBR_STD_FLTS > 128)
+	#error "Invalid CAN0 # of Standard Filters"
+#endif
+#if (MCAN0_NMBR_EXT_FLTS > 64)
+	#error "Invalid CAN0 # of Extended Filters"
+#endif
+#if (MCAN0_NMBR_RX_FIFO0_ELMTS > 64)
+	#error "Invalid CAN0 # RX FIFO 0 ELEMENTS"
+#endif
+#if (MCAN0_NMBR_RX_FIFO1_ELMTS > 64)
+	#error "Invalid CAN0 # RX FIFO 0 ELEMENTS"
+#endif
+#if (MCAN0_NMBR_RX_DED_BUF_ELMTS > 64)
+	#error "Invalid CAN0 # RX BUFFER ELEMENTS"
+#endif
+#if (MCAN0_NMBR_TX_EVT_FIFO_ELMTS > 32)
+	#error "Invalid CAN0 # TX EVENT FIFO ELEMENTS"
+#endif
+#if ((MCAN0_NMBR_TX_DED_BUF_ELMTS + MCAN0_NMBR_TX_FIFO_Q_ELMTS)  > 32)
+	#error "Invalid CAN0 # TX BUFFER ELEMENTS"
+#endif
+
+#if   (8 == MCAN0_RX_FIFO0_ELMT_SZ)
+	#define MCAN0_RX_FIFO0_DATA_SIZE  (0u)
+#elif (12 == MCAN0_RX_FIFO0_ELMT_SZ)
+	#define MCAN0_RX_FIFO0_DATA_SIZE  (1u)
+#elif (16 == MCAN0_RX_FIFO0_ELMT_SZ)
+	#define MCAN0_RX_FIFO0_DATA_SIZE  (2u)
+#elif (20 == MCAN0_RX_FIFO0_ELMT_SZ)
+	#define MCAN0_RX_FIFO0_DATA_SIZE  (3u)
+#elif (24 == MCAN0_RX_FIFO0_ELMT_SZ)
+	#define MCAN0_RX_FIFO0_DATA_SIZE  (4u)
+#elif (32 == MCAN0_RX_FIFO0_ELMT_SZ)
+	#define MCAN0_RX_FIFO0_DATA_SIZE  (5u)
+#elif (48 == MCAN0_RX_FIFO0_ELMT_SZ)
+	#define MCAN0_RX_FIFO0_DATA_SIZE  (6u)
+#elif (64 == MCAN0_RX_FIFO0_ELMT_SZ)
+	#define MCAN0_RX_FIFO0_DATA_SIZE  (7u)
+#else
+	#error "Invalid CAN0 RX FIFO0 ELEMENT SIZE"
+#endif
+
+#if   (8 == MCAN0_RX_FIFO1_ELMT_SZ)
+	#define MCAN0_RX_FIFO1_DATA_SIZE  (0u)
+#elif (12 == MCAN0_RX_FIFO1_ELMT_SZ)
+	#define MCAN0_RX_FIFO1_DATA_SIZE  (1u)
+#elif (16 == MCAN0_RX_FIFO1_ELMT_SZ)
+	#define MCAN0_RX_FIFO1_DATA_SIZE  (2u)
+#elif (20 == MCAN0_RX_FIFO1_ELMT_SZ)
+	#define MCAN0_RX_FIFO1_DATA_SIZE  (3u)
+#elif (24 == MCAN0_RX_FIFO1_ELMT_SZ)
+	#define MCAN0_RX_FIFO1_DATA_SIZE  (4u)
+#elif (32 == MCAN0_RX_FIFO1_ELMT_SZ)
+	#define MCAN0_RX_FIFO1_DATA_SIZE  (5u)
+#elif (48 == MCAN0_RX_FIFO1_ELMT_SZ)
+	#define MCAN0_RX_FIFO1_DATA_SIZE  (6u)
+#elif (64 == MCAN0_RX_FIFO1_ELMT_SZ)
+	#define MCAN0_RX_FIFO1_DATA_SIZE  (7u)
+#else
+	#error "Invalid CAN0 RX FIFO1 ELEMENT SIZE"
+#endif
+
+#if   (8 == MCAN0_RX_BUF_ELMT_SZ)
+	#define MCAN0_RX_BUF_DATA_SIZE  (0u)
+#elif (12 == MCAN0_RX_BUF_ELMT_SZ)
+	#define MCAN0_RX_BUF_DATA_SIZE  (1u)
+#elif (16 == MCAN0_RX_BUF_ELMT_SZ)
+	#define MCAN0_RX_BUF_DATA_SIZE  (2u)
+#elif (20 == MCAN0_RX_BUF_ELMT_SZ)
+	#define MCAN0_RX_BUF_DATA_SIZE  (3u)
+#elif (24 == MCAN0_RX_BUF_ELMT_SZ)
+	#define MCAN0_RX_BUF_DATA_SIZE  (4u)
+#elif (32 == MCAN0_RX_BUF_ELMT_SZ)
+	#define MCAN0_RX_BUF_DATA_SIZE  (5u)
+#elif (48 == MCAN0_RX_BUF_ELMT_SZ)
+	#define MCAN0_RX_BUF_DATA_SIZE  (6u)
+#elif (64 == MCAN0_RX_BUF_ELMT_SZ)
+	#define MCAN0_RX_BUF_DATA_SIZE  (7u)
+#else
+	#error "Invalid CAN0 RX BUFFER ELEMENT SIZE"
+#endif
+
+#if   (8 == MCAN0_TX_BUF_ELMT_SZ)
+	#define MCAN0_TX_BUF_DATA_SIZE  (0u)
+#elif (12 == MCAN0_TX_BUF_ELMT_SZ)
+	#define MCAN0_TX_BUF_DATA_SIZE  (1u)
+#elif (16 == MCAN0_TX_BUF_ELMT_SZ)
+	#define MCAN0_TX_BUF_DATA_SIZE  (2u)
+#elif (20 == MCAN0_TX_BUF_ELMT_SZ)
+	#define MCAN0_TX_BUF_DATA_SIZE  (3u)
+#elif (24 == MCAN0_TX_BUF_ELMT_SZ)
+	#define MCAN0_TX_BUF_DATA_SIZE  (4u)
+#elif (32 == MCAN0_TX_BUF_ELMT_SZ)
+	#define MCAN0_TX_BUF_DATA_SIZE  (5u)
+#elif (48 == MCAN0_TX_BUF_ELMT_SZ)
+	#define MCAN0_TX_BUF_DATA_SIZE  (6u)
+#elif (64 == MCAN0_TX_BUF_ELMT_SZ)
+	#define MCAN0_TX_BUF_DATA_SIZE  (7u)
+#else
+	#error "Invalid CAN0 TX BUFFER ELEMENT SIZE"
+#endif
+
+/* validate CAN1 entries */
+#if (MCAN1_TSEG1 > 63)
+	#error "Invalid CAN1 TSEG1"
+#endif
+#if (MCAN1_TSEG2 > 15)
+	#error "Invalid CAN1 TSEG2"
+#endif
+#if (MCAN1_SJW > 15)
+	#error "Invalid CAN1 SJW"
+#endif
+#if (MCAN1_FTSEG1 > 15)
+	#error "Invalid CAN1 FTSEG1"
+#endif
+#if (MCAN1_FTSEG2 > 7)
+	#error "Invalid CAN1 FTSEG2"
+#endif
+#if (MCAN1_FSJW > 3)
+	#error "Invalid CAN1 FSJW"
+#endif
+
+#if (MCAN1_NMBR_STD_FLTS > 128)
+	#error "Invalid CAN1 # of Standard Filters"
+#endif
+#if (MCAN1_NMBR_EXT_FLTS > 64)
+	#error "Invalid CAN1 # of Extended Filters"
+#endif
+#if (MCAN1_NMBR_RX_FIFO0_ELMTS > 64)
+	#error "Invalid CAN1 # RX FIFO 0 ELEMENTS"
+#endif
+#if (MCAN1_NMBR_RX_FIFO1_ELMTS > 64)
+	#error "Invalid CAN1 # RX FIFO 0 ELEMENTS"
+#endif
+#if (MCAN1_NMBR_RX_DED_BUF_ELMTS > 64)
+	#error "Invalid CAN1 # RX BUFFER ELEMENTS"
+#endif
+#if (MCAN1_NMBR_TX_EVT_FIFO_ELMTS > 32)
+	#error "Invalid CAN1 # TX EVENT FIFO ELEMENTS"
+#endif
+#if ((MCAN1_NMBR_TX_DED_BUF_ELMTS + MCAN1_NMBR_TX_FIFO_Q_ELMTS)  > 32)
+	#error "Invalid CAN1 # TX BUFFER ELEMENTS"
+#endif
+
+#if   (8 == MCAN1_RX_FIFO0_ELMT_SZ)
+	#define MCAN1_RX_FIFO0_DATA_SIZE  (0u)
+#elif (12 == MCAN1_RX_FIFO0_ELMT_SZ)
+	#define MCAN1_RX_FIFO0_DATA_SIZE  (1u)
+#elif (16 == MCAN1_RX_FIFO0_ELMT_SZ)
+	#define MCAN1_RX_FIFO0_DATA_SIZE  (2u)
+#elif (20 == MCAN1_RX_FIFO0_ELMT_SZ)
+	#define MCAN1_RX_FIFO0_DATA_SIZE  (3u)
+#elif (24 == MCAN1_RX_FIFO0_ELMT_SZ)
+	#define MCAN1_RX_FIFO0_DATA_SIZE  (4u)
+#elif (32 == MCAN1_RX_FIFO0_ELMT_SZ)
+	#define MCAN1_RX_FIFO0_DATA_SIZE  (5u)
+#elif (48 == MCAN1_RX_FIFO0_ELMT_SZ)
+	#define MCAN1_RX_FIFO0_DATA_SIZE  (6u)
+#elif (64 == MCAN1_RX_FIFO0_ELMT_SZ)
+	#define MCAN1_RX_FIFO0_DATA_SIZE  (7u)
+#else
+	#error "Invalid CAN1 RX FIFO0 ELEMENT SIZE"
+#endif
+
+#if   (8 == MCAN1_RX_FIFO1_ELMT_SZ)
+	#define MCAN1_RX_FIFO1_DATA_SIZE  (0u)
+#elif (12 == MCAN1_RX_FIFO1_ELMT_SZ)
+	#define MCAN1_RX_FIFO1_DATA_SIZE  (1u)
+#elif (16 == MCAN1_RX_FIFO1_ELMT_SZ)
+	#define MCAN1_RX_FIFO1_DATA_SIZE  (2u)
+#elif (20 == MCAN1_RX_FIFO1_ELMT_SZ)
+	#define MCAN1_RX_FIFO1_DATA_SIZE  (3u)
+#elif (24 == MCAN1_RX_FIFO1_ELMT_SZ)
+	#define MCAN1_RX_FIFO1_DATA_SIZE  (4u)
+#elif (32 == MCAN1_RX_FIFO1_ELMT_SZ)
+	#define MCAN1_RX_FIFO1_DATA_SIZE  (5u)
+#elif (48 == MCAN1_RX_FIFO1_ELMT_SZ)
+	#define MCAN1_RX_FIFO1_DATA_SIZE  (6u)
+#elif (64 == MCAN1_RX_FIFO1_ELMT_SZ)
+	#define MCAN1_RX_FIFO1_DATA_SIZE  (7u)
+#else
+	#error "Invalid CAN1 RX FIFO1 ELEMENT SIZE"
+#endif
+
+#if   (8 == MCAN1_RX_BUF_ELMT_SZ)
+	#define MCAN1_RX_BUF_DATA_SIZE  (0u)
+#elif (12 == MCAN1_RX_BUF_ELMT_SZ)
+	#define MCAN1_RX_BUF_DATA_SIZE  (1u)
+#elif (16 == MCAN1_RX_BUF_ELMT_SZ)
+	#define MCAN1_RX_BUF_DATA_SIZE  (2u)
+#elif (20 == MCAN1_RX_BUF_ELMT_SZ)
+	#define MCAN1_RX_BUF_DATA_SIZE  (3u)
+#elif (24 == MCAN1_RX_BUF_ELMT_SZ)
+	#define MCAN1_RX_BUF_DATA_SIZE  (4u)
+#elif (32 == MCAN1_RX_BUF_ELMT_SZ)
+	#define MCAN1_RX_BUF_DATA_SIZE  (5u)
+#elif (48 == MCAN1_RX_BUF_ELMT_SZ)
+	#define MCAN1_RX_BUF_DATA_SIZE  (6u)
+#elif (64 == MCAN1_RX_BUF_ELMT_SZ)
+	#define MCAN1_RX_BUF_DATA_SIZE  (7u)
+#else
+	#error "Invalid CAN1 RX BUFFER ELEMENT SIZE"
+#endif
+
+#if   (8 == MCAN1_TX_BUF_ELMT_SZ)
+	#define MCAN1_TX_BUF_DATA_SIZE  (0u)
+#elif (12 == MCAN1_TX_BUF_ELMT_SZ)
+	#define MCAN1_TX_BUF_DATA_SIZE  (1u)
+#elif (16 == MCAN1_TX_BUF_ELMT_SZ)
+	#define MCAN1_TX_BUF_DATA_SIZE  (2u)
+#elif (20 == MCAN1_TX_BUF_ELMT_SZ)
+	#define MCAN1_TX_BUF_DATA_SIZE  (3u)
+#elif (24 == MCAN1_TX_BUF_ELMT_SZ)
+	#define MCAN1_TX_BUF_DATA_SIZE  (4u)
+#elif (32 == MCAN1_TX_BUF_ELMT_SZ)
+	#define MCAN1_TX_BUF_DATA_SIZE  (5u)
+#elif (48 == MCAN1_TX_BUF_ELMT_SZ)
+	#define MCAN1_TX_BUF_DATA_SIZE  (6u)
+#elif (64 == MCAN1_TX_BUF_ELMT_SZ)
+	#define MCAN1_TX_BUF_DATA_SIZE  (7u)
+#else
+	#error "Invalid CAN1 TX BUFFER ELEMENT SIZE"
+#endif
+
+#define CAN_11_BIT_ID_MASK                 (0x7FF)
+#define CAN_29_BIT_ID_MASK                 (0x1FFFFFFF)
+#define ELMT_SIZE_MASK                (0x1F)
+/* max element size is 18 words, fits in 5 bits */
+
+#define BUFFER_XTD_MASK               (0x40000000)
+#define BUFFER_EXT_ID_MASK            (0x1FFFFFFF)
+#define BUFFER_STD_ID_MASK            (0x1FFC0000)
+#define BUFFER_DLC_MASK               (0x000F0000)
+#define BUFFER_RXTS_MASK              (0x0000FFFF)
+
+#define STD_FILT_SFT_MASK             (3U << 30)
+#define STD_FILT_SFT_RANGE            (0U << 30)
+#define STD_FILT_SFT_DUAL             (1U << 30)
+#define STD_FILT_SFT_CLASSIC          (2U << 30)
+#define STD_FILT_SFEC_MASK            (7U << 27)
+#define STD_FILT_SFEC_DISABLE         (0U << 27)
+#define STD_FILT_SFEC_FIFO0           (1U << 27)
+#define STD_FILT_SFEC_FIFO1           (2U << 27)
+#define STD_FILT_SFEC_REJECT          (3U << 27)
+#define STD_FILT_SFEC_PRIORITY        (4U << 27)
+#define STD_FILT_SFEC_PRIORITY_FIFO0  (5U << 27)
+#define STD_FILT_SFEC_PRIORITY_FIFO1  (6U << 27)
+#define STD_FILT_SFEC_BUFFER          (7U << 27)
+#define STD_FILT_SFID1_MASK           (0x03FFU << 16)
+#define STD_FILT_SFID2_MASK           (0x3FFU << 0)
+#define STD_FILT_SFID2_RX_BUFFER      (0U << 9)
+#define STD_FILT_SFID2_DEBUG_A        (1U << 9)
+#define STD_FILT_SFID2_DEBUG_B        (2U << 9)
+#define STD_FILT_SFID2_DEBUG_C        (3U << 9)
+#define STD_FILT_SFID2_BUFFER(nmbr)   (nmbr & 0x3F)
+
+#define EXT_FILT_EFEC_MASK            (7U << 29)
+#define EXT_FILT_EFEC_DISABLE         (0U << 29)
+#define EXT_FILT_EFEC_FIFO0           (1U << 29)
+#define EXT_FILT_EFEC_FIFO1           (2U << 29)
+#define EXT_FILT_EFEC_REJECT          (3U << 29)
+#define EXT_FILT_EFEC_PRIORITY        (4U << 29)
+#define EXT_FILT_EFEC_PRIORITY_FIFO0  (5U << 29)
+#define EXT_FILT_EFEC_PRIORITY_FIFO1  (6U << 29)
+#define EXT_FILT_EFEC_BUFFER          (7U << 29)
+#define EXT_FILT_EFID1_MASK           (0x1FFFFFFF)
+#define EXT_FILT_EFT_MASK             (3U << 30)
+#define EXT_FILT_EFT_RANGE            (0U << 30)
+#define EXT_FILT_EFT_DUAL             (1U << 30)
+#define EXT_FILT_EFT_CLASSIC          (2U << 30)
+#define EXT_FILT_EFT_RANGE_NO_XIDAM   (3U << 30)
+#define EXT_FILT_EFID2_MASK           (0x1FFFFFFF)
+#define EXT_FILT_EFID2_RX_BUFFER      (0U << 9)
+#define EXT_FILT_EFID2_DEBUG_A        (1U << 9)
+#define EXT_FILT_EFID2_DEBUG_B        (2U << 9)
+#define EXT_FILT_EFID2_DEBUG_C        (3U << 9)
+#define EXT_FILT_EFID2_BUFFER(nmbr)   (nmbr & 0x3F)
+
+
+/*---------------------------------------------------------------------------
+ *      Internal variables
+ *---------------------------------------------------------------------------*/
+
+#ifndef __rtems__
+static const Pin pinsMcan0[] =  {PIN_MCAN0_TXD, PIN_MCAN0_RXD };
+static const Pin pinsMcan1[] =  {PIN_MCAN1_TXD, PIN_MCAN1_RXD };
+#endif /* __rtems__ */
+
+static uint32_t can0MsgRam[MCAN0_STD_FLTS_WRDS +
+						   MCAN0_EXT_FLTS_WRDS +
+						   MCAN0_RX_FIFO0_WRDS +
+						   MCAN0_RX_FIFO1_WRDS +
+						   MCAN0_RX_DED_BUFS_WRDS +
+						   MCAN0_TX_EVT_FIFO_WRDS +
+						   MCAN0_TX_DED_BUF_WRDS +
+						   MCAN0_TX_FIFO_Q_WRDS];
+
+static uint32_t can1MsgRam[MCAN1_STD_FLTS_WRDS +
+						   MCAN1_EXT_FLTS_WRDS +
+						   MCAN1_RX_FIFO0_WRDS +
+						   MCAN1_RX_FIFO1_WRDS +
+						   MCAN1_RX_DED_BUFS_WRDS +
+						   MCAN1_TX_EVT_FIFO_WRDS +
+						   MCAN1_TX_DED_BUF_WRDS +
+						   MCAN1_TX_FIFO_Q_WRDS];
+
+static const uint8_t dlcToMsgLength[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 12, 16, 20, 24, 32, 48, 64 };
+
+const MCan_ConfigType mcan0Config = {
+	MCAN0,
+	MCAN_BTP_BRP(MCAN0_BRP) | MCAN_BTP_TSEG1(MCAN0_TSEG1) |
+	MCAN_BTP_TSEG2(MCAN0_TSEG2) | MCAN_BTP_SJW(MCAN0_SJW),
+	MCAN_FBTP_FBRP(MCAN0_FBRP) | MCAN_FBTP_FTSEG1(MCAN0_FTSEG1) |
+	MCAN_FBTP_FTSEG2(MCAN0_FTSEG2) | MCAN_FBTP_FSJW(MCAN0_FSJW),
+	MCAN0_NMBR_STD_FLTS,
+	MCAN0_NMBR_EXT_FLTS,
+	MCAN0_NMBR_RX_FIFO0_ELMTS,
+	MCAN0_NMBR_RX_FIFO1_ELMTS,
+	MCAN0_NMBR_RX_DED_BUF_ELMTS,
+	MCAN0_NMBR_TX_EVT_FIFO_ELMTS,
+	MCAN0_NMBR_TX_DED_BUF_ELMTS,
+	MCAN0_NMBR_TX_FIFO_Q_ELMTS,
+	(MCAN0_RX_FIFO0_DATA_SIZE << 29) | ((MCAN0_RX_FIFO0_ELMT_SZ / 4) + 2),
+	/* element size in WORDS */
+	(MCAN0_RX_FIFO1_DATA_SIZE << 29) | ((MCAN0_RX_FIFO1_ELMT_SZ / 4) + 2),
+	/* element size in WORDS */
+	(MCAN0_RX_BUF_DATA_SIZE << 29) | ((MCAN0_RX_BUF_ELMT_SZ / 4) + 2),
+	/* element size in WORDS */
+	(MCAN0_TX_BUF_DATA_SIZE << 29) | ((MCAN0_TX_BUF_ELMT_SZ / 4) + 2),
+	/* element size in WORDS */
+	{
+		&can0MsgRam[0],
+		&can0MsgRam[MCAN0_STD_FLTS_WRDS],
+		&can0MsgRam[MCAN0_STD_FLTS_WRDS + MCAN0_EXT_FLTS_WRDS],
+		&can0MsgRam[MCAN0_STD_FLTS_WRDS + MCAN0_EXT_FLTS_WRDS + MCAN0_RX_FIFO0_WRDS],
+		&can0MsgRam[MCAN0_STD_FLTS_WRDS + MCAN0_EXT_FLTS_WRDS + MCAN0_RX_FIFO0_WRDS +
+		MCAN0_RX_FIFO1_WRDS],
+		&can0MsgRam[MCAN0_STD_FLTS_WRDS + MCAN0_EXT_FLTS_WRDS + MCAN0_RX_FIFO0_WRDS +
+		MCAN0_RX_FIFO1_WRDS + MCAN0_RX_DED_BUFS_WRDS],
+		&can0MsgRam[MCAN0_STD_FLTS_WRDS + MCAN0_EXT_FLTS_WRDS + MCAN0_RX_FIFO0_WRDS +
+		MCAN0_RX_FIFO1_WRDS + MCAN0_RX_DED_BUFS_WRDS + MCAN0_TX_EVT_FIFO_WRDS],
+		&can0MsgRam[MCAN0_STD_FLTS_WRDS + MCAN0_EXT_FLTS_WRDS + MCAN0_RX_FIFO0_WRDS +
+		MCAN0_RX_FIFO1_WRDS + MCAN0_RX_DED_BUFS_WRDS + MCAN0_TX_EVT_FIFO_WRDS +
+		MCAN0_TX_DED_BUF_WRDS]
+	},
+};
+
+const MCan_ConfigType mcan1Config = {
+	MCAN1,
+	MCAN_BTP_BRP(MCAN1_BRP) | MCAN_BTP_TSEG1(MCAN1_TSEG1) |
+	MCAN_BTP_TSEG2(MCAN1_TSEG2) | MCAN_BTP_SJW(MCAN1_SJW),
+	MCAN_FBTP_FBRP(MCAN1_FBRP) | MCAN_FBTP_FTSEG1(MCAN1_FTSEG1) |
+	MCAN_FBTP_FTSEG2(MCAN1_FTSEG2) | MCAN_FBTP_FSJW(MCAN1_FSJW),
+	MCAN1_NMBR_STD_FLTS,
+	MCAN1_NMBR_EXT_FLTS,
+	MCAN1_NMBR_RX_FIFO0_ELMTS,
+	MCAN1_NMBR_RX_FIFO1_ELMTS,
+	MCAN0_NMBR_RX_DED_BUF_ELMTS,
+	MCAN1_NMBR_TX_EVT_FIFO_ELMTS,
+	MCAN1_NMBR_TX_DED_BUF_ELMTS,
+	MCAN1_NMBR_TX_FIFO_Q_ELMTS,
+	(MCAN1_RX_FIFO0_DATA_SIZE << 29) | ((MCAN1_RX_FIFO0_ELMT_SZ / 4) + 2),
+	/* element size in WORDS */
+	(MCAN1_RX_FIFO1_DATA_SIZE << 29) | ((MCAN1_RX_FIFO1_ELMT_SZ / 4) + 2),
+	/* element size in WORDS */
+	(MCAN1_RX_BUF_DATA_SIZE << 29) | ((MCAN1_RX_BUF_ELMT_SZ / 4) + 2),
+	/* element size in WORDS */
+	(MCAN1_TX_BUF_DATA_SIZE << 29) | ((MCAN1_TX_BUF_ELMT_SZ / 4) + 2),
+	/* element size in WORDS */
+	{
+		&can1MsgRam[0],
+		&can1MsgRam[MCAN1_STD_FLTS_WRDS],
+		&can1MsgRam[MCAN1_STD_FLTS_WRDS + MCAN1_EXT_FLTS_WRDS],
+		&can1MsgRam[MCAN1_STD_FLTS_WRDS + MCAN1_EXT_FLTS_WRDS + MCAN1_RX_FIFO0_WRDS],
+		&can1MsgRam[MCAN1_STD_FLTS_WRDS + MCAN1_EXT_FLTS_WRDS + MCAN1_RX_FIFO0_WRDS
+		+ MCAN1_RX_FIFO1_WRDS],
+		&can1MsgRam[MCAN1_STD_FLTS_WRDS + MCAN1_EXT_FLTS_WRDS + MCAN1_RX_FIFO0_WRDS
+		+ MCAN1_RX_FIFO1_WRDS + MCAN1_RX_DED_BUFS_WRDS],
+		&can1MsgRam[MCAN1_STD_FLTS_WRDS + MCAN1_EXT_FLTS_WRDS + MCAN1_RX_FIFO0_WRDS
+		+ MCAN1_RX_FIFO1_WRDS + MCAN1_RX_DED_BUFS_WRDS + MCAN1_TX_EVT_FIFO_WRDS],
+		&can1MsgRam[MCAN1_STD_FLTS_WRDS + MCAN1_EXT_FLTS_WRDS + MCAN1_RX_FIFO0_WRDS
+		+ MCAN1_RX_FIFO1_WRDS + MCAN1_RX_DED_BUFS_WRDS + MCAN1_TX_EVT_FIFO_WRDS
+		+ MCAN1_TX_DED_BUF_WRDS]
+	},
+};
+
+
+/*---------------------------------------------------------------------------
+ *      Exported Functions
+ *---------------------------------------------------------------------------*/
+/**
+* \brief Initializes the MCAN hardware for giving peripheral.
+* Default: Mixed mode TX Buffer + FIFO.
+*
+* \param mcanConfig  Pointer to a MCAN instance.
+*/
+void MCAN_Init(const MCan_ConfigType *mcanConfig)
+{
+	Mcan       *mcan = mcanConfig->pMCan;
+	uint32_t    regVal32;
+	uint32_t   *pMsgRam;
+	uint32_t    cntr;
+	IRQn_Type   mCanLine0Irq;
+
+	/* Both MCAN controllers use programmable clock 5 to derive bit rate */
+	// select MCK divided by 1 as programmable clock 5 output
+	PMC->PMC_PCK[5] = PMC_PCK_PRES(MCAN_PROG_CLK_PRESCALER - 1) |
+					  MCAN_PROG_CLK_SELECT;
+	PMC->PMC_SCER = PMC_SCER_PCK5;
+
+	if (MCAN0 ==  mcan) {
+#ifndef __rtems__
+		PIO_Configure(pinsMcan0, PIO_LISTSIZE(pinsMcan0));
+#endif /* __rtems__ */
+		// Enable MCAN peripheral clock
+		PMC_EnablePeripheral(ID_MCAN0);
+		// Configure Message RAM Base Address
+		regVal32 = MATRIX->CCFG_CAN0 & 0x000001FF;
+		MATRIX->CCFG_CAN0 = regVal32 |
+							((uint32_t) mcanConfig->msgRam.pStdFilts & 0xFFFF0000);
+		mCanLine0Irq = MCAN0_IRQn;
+	} else if (MCAN1 ==  mcan) {
+#ifndef __rtems__
+		PIO_Configure(pinsMcan1, PIO_LISTSIZE(pinsMcan1));
+#endif /* __rtems__ */
+		// Enable MCAN peripheral clock
+		PMC_EnablePeripheral(ID_MCAN1);
+		// Configure Message RAM Base Address
+		regVal32 = MATRIX->CCFG_SYSIO & 0x0000FFFF;
+		MATRIX->CCFG_SYSIO = regVal32 | ((uint32_t) mcanConfig->msgRam.pStdFilts &
+										  0xFFFF0000);
+		mCanLine0Irq = MCAN1_IRQn;
+	} else
+		return;
+
+	/* Indicates Initialization state */
+	mcan->MCAN_CCCR = MCAN_CCCR_INIT_ENABLED;
+
+	do { regVal32 = mcan->MCAN_CCCR; }
+	while (0u == (regVal32 & MCAN_CCCR_INIT_ENABLED));
+
+	/* Enable writing to configuration registers */
+	mcan->MCAN_CCCR = MCAN_CCCR_INIT_ENABLED | MCAN_CCCR_CCE_CONFIGURABLE;
+
+	/* Global Filter Configuration: Reject remote frames, reject non-matching frames */
+	mcan->MCAN_GFC = MCAN_GFC_RRFE_REJECT | MCAN_GFC_RRFS_REJECT
+					 | MCAN_GFC_ANFE(2) | MCAN_GFC_ANFS(2);
+
+	// Extended ID Filter AND mask
+	mcan->MCAN_XIDAM = 0x1FFFFFFF;
+
+	/* Interrupt configuration - leave initialization with all interrupts off */
+	// Disable all interrupts
+	mcan->MCAN_IE =  0;
+	mcan->MCAN_TXBTIE = 0x00000000;
+	// All interrupts directed to Line 0
+	mcan->MCAN_ILS =  0x00000000;
+	// Disable both interrupt LINE 0 & LINE 1
+	mcan->MCAN_ILE = 0x00;
+	// Clear all interrupt flags
+	mcan->MCAN_IR = 0xFFCFFFFF;
+	/* Enable NVIC - but no interrupts will happen since all sources are
+	    disabled in MCAN_IE */
+	NVIC_ClearPendingIRQ(mCanLine0Irq);
+	NVIC_EnableIRQ(mCanLine0Irq);
+	NVIC_ClearPendingIRQ((IRQn_Type) (mCanLine0Irq + 1));
+	NVIC_EnableIRQ((IRQn_Type) (mCanLine0Irq + 1));
+
+	/* Configure CAN bit timing */
+	mcan->MCAN_BTP = mcanConfig->bitTiming;
+	mcan->MCAN_FBTP = mcanConfig->fastBitTiming;
+
+	/* Configure message RAM starting addresses & sizes */
+	mcan->MCAN_SIDFC = MAILBOX_ADDRESS((uint32_t) mcanConfig->msgRam.pStdFilts)
+					   | MCAN_SIDFC_LSS(mcanConfig->nmbrStdFilts);
+	mcan->MCAN_XIDFC = MAILBOX_ADDRESS((uint32_t) mcanConfig->msgRam.pExtFilts)
+					   | MCAN_XIDFC_LSE(mcanConfig->nmbrExtFilts);
+	mcan->MCAN_RXF0C = MAILBOX_ADDRESS((uint32_t) mcanConfig->msgRam.pRxFifo0)
+					   | MCAN_RXF0C_F0S(mcanConfig->nmbrFifo0Elmts);
+	// watermark interrupt off, blocking mode
+	mcan->MCAN_RXF1C = MAILBOX_ADDRESS((uint32_t) mcanConfig->msgRam.pRxFifo1)
+					   | MCAN_RXF1C_F1S(mcanConfig->nmbrFifo1Elmts);
+	// watermark interrupt off, blocking mode
+	mcan->MCAN_RXBC = MAILBOX_ADDRESS((uint32_t) mcanConfig->msgRam.pRxDedBuf);
+	mcan->MCAN_TXEFC = MAILBOX_ADDRESS((uint32_t) mcanConfig->msgRam.pTxEvtFifo)
+					   | MCAN_TXEFC_EFS(mcanConfig->nmbrTxEvtFifoElmts);
+	// watermark interrupt off
+	mcan->MCAN_TXBC = MAILBOX_ADDRESS((uint32_t) mcanConfig->msgRam.pTxDedBuf)
+					  | MCAN_TXBC_NDTB(mcanConfig->nmbrTxDedBufElmts)
+					  | MCAN_TXBC_TFQS(mcanConfig->nmbrTxFifoQElmts);
+	mcan->MCAN_RXESC = ((mcanConfig->rxBufElmtSize >> (29 - MCAN_RXESC_RBDS_Pos)) &
+						MCAN_RXESC_RBDS_Msk) |
+					   ((mcanConfig->rxFifo1ElmtSize >> (29 - MCAN_RXESC_F1DS_Pos)) &
+						MCAN_RXESC_F1DS_Msk) |
+					   ((mcanConfig->rxFifo0ElmtSize >> (29 - MCAN_RXESC_F0DS_Pos)) &
+						MCAN_RXESC_F0DS_Msk);
+	mcan->MCAN_TXESC = ((mcanConfig->txBufElmtSize >> (29 - MCAN_TXESC_TBDS_Pos)) &
+						MCAN_TXESC_TBDS_Msk);
+
+	/* Configure Message Filters */
+	// ...Disable all standard filters
+	pMsgRam = mcanConfig->msgRam.pStdFilts;
+	cntr = mcanConfig->nmbrStdFilts;
+
+	while (cntr > 0) {
+		*pMsgRam++ = STD_FILT_SFEC_DISABLE;
+		cntr--;
+	}
+
+	// ...Disable all extended filters
+	pMsgRam = mcanConfig->msgRam.pExtFilts;
+	cntr = mcanConfig->nmbrExtFilts;
+
+	while (cntr > 0) {
+		*pMsgRam = EXT_FILT_EFEC_DISABLE;
+		pMsgRam = pMsgRam + 2;
+		cntr--;
+	}
+
+	mcan->MCAN_NDAT1 = 0xFFFFFFFF;  // clear new (rx) data flags
+	mcan->MCAN_NDAT2 = 0xFFFFFFFF;  // clear new (rx) data flags
+
+	regVal32 =  mcan->MCAN_CCCR & ~(MCAN_CCCR_CME_Msk | MCAN_CCCR_CMR_Msk);
+	mcan->MCAN_CCCR = regVal32 | MCAN_CCCR_CME_ISO11898_1;
+	mcan->MCAN_CCCR = regVal32 | (MCAN_CCCR_CMR_ISO11898_1 |
+								  MCAN_CCCR_CME_ISO11898_1);
+
+	__DSB();
+	__ISB();
+}
+
+/**
+ * \brief Enables a FUTURE switch to FD mode (tx & rx payloads up to 64 bytes)
+ * but transmits WITHOUT bit rate switching
+ * INIT must be set - so this should be called between MCAN_Init() and
+ * MCAN_Enable()
+ * \param mcanConfig  Pointer to a MCAN instance.
+ */
+void MCAN_InitFdEnable(const MCan_ConfigType *mcanConfig)
+{
+	Mcan      *mcan = mcanConfig->pMCan;
+	uint32_t   regVal32;
+
+	regVal32 =  mcan->MCAN_CCCR & ~MCAN_CCCR_CME_Msk;
+	mcan->MCAN_CCCR = regVal32 | MCAN_CCCR_CME(1);
+}
+
+/**
+ * \brief Enables a FUTURE switch to FD mode (tx & rx payloads up to 64 bytes) and transmits
+ * WITH bit rate switching
+ * INIT must be set - so this should be called between MCAN_Init() and MCAN_Enable()
+ * \param mcanConfig  Pointer to a MCAN instance.
+ */
+void MCAN_InitFdBitRateSwitchEnable(const MCan_ConfigType *mcanConfig)
+{
+	Mcan      *mcan = mcanConfig->pMCan;
+	uint32_t   regVal32;
+
+	regVal32 =  mcan->MCAN_CCCR & ~MCAN_CCCR_CME_Msk;
+	mcan->MCAN_CCCR = regVal32 | MCAN_CCCR_CME(2);
+}
+
+/**
+ * \brief Initializes the MCAN in loop back mode.
+ * INIT must be set - so this should be called between MCAN_Init() and
+ * MCAN_Enable()
+ * \param mcanConfig  Pointer to a MCAN instance.
+ */
+void MCAN_InitLoopback(const MCan_ConfigType *mcanConfig)
+{
+	Mcan *mcan = mcanConfig->pMCan;
+
+	mcan->MCAN_CCCR |= MCAN_CCCR_TEST_ENABLED;
+	//mcan->MCAN_CCCR |= MCAN_CCCR_MON_ENABLED;  // for internal loop back
+	mcan->MCAN_TEST |= MCAN_TEST_LBCK_ENABLED;
+}
+
+/**
+ * \brief Initializes MCAN queue for TX
+ * INIT must be set - so this should be called between MCAN_Init() and
+ * MCAN_Enable()
+ * \param mcanConfig  Pointer to a MCAN instance.
+ */
+void MCAN_InitTxQueue(const MCan_ConfigType *mcanConfig)
+{
+	Mcan *mcan = mcanConfig->pMCan;
+	mcan->MCAN_TXBC |= MCAN_TXBC_TFQM;
+}
+
+/**
+ * \brief Enable MCAN peripheral.
+ * INIT must be set - so this should be called between MCAN_Init()
+ * \param mcanConfig  Pointer to a MCAN instance.
+ */
+void MCAN_Enable(const MCan_ConfigType *mcanConfig)
+{
+	Mcan *mcan = mcanConfig->pMCan;
+	mcan->MCAN_CCCR &= ~MCAN_CCCR_INIT_ENABLED;
+}
+
+/**
+ * \brief Requests switch to Iso11898-1 (standard / classic) mode (tx & rx
+ * payloads up to 8 bytes).
+ * \param mcanConfig  Pointer to a MCAN instance.
+ */
+void MCAN_RequestIso11898_1(const MCan_ConfigType *mcanConfig)
+{
+	Mcan      *mcan = mcanConfig->pMCan;
+	uint32_t   regVal32;
+
+	regVal32 =  mcan->MCAN_CCCR & ~MCAN_CCCR_CMR_Msk;
+	mcan->MCAN_CCCR = regVal32 | MCAN_CCCR_CMR_ISO11898_1;
+
+	while ((mcan->MCAN_CCCR & (MCAN_CCCR_FDBS | MCAN_CCCR_FDO)) != 0)
+	{ /* wait */ }
+}
+
+/**
+ * \brief Requests switch to FD mode (tx & rx payloads up to 64 bytes) but
+ * transmits WITHOUT bit
+ * rate switching. requested mode should have been enabled at initialization
+ * \param mcanConfig  Pointer to a MCAN instance.
+ */
+void MCAN_RequestFd(const MCan_ConfigType *mcanConfig)
+{
+	Mcan      *mcan = mcanConfig->pMCan;
+	uint32_t   regVal32;
+
+	if ((mcan->MCAN_CCCR & MCAN_CCCR_CME_Msk) == MCAN_CCCR_CME(1)) {
+		regVal32 =  mcan->MCAN_CCCR & ~MCAN_CCCR_CMR_Msk;
+		mcan->MCAN_CCCR = regVal32 | MCAN_CCCR_CMR_FD;
+
+		while ((mcan->MCAN_CCCR & MCAN_CCCR_FDO) == 0) { /* wait */ }
+	}
+}
+
+/**
+ * \brief Request switch to FD mode (tx & rx payloads up to 64 bytes) and
+ * transmits WITH bit rate switching.
+ * requested mode should have been enabled at initialization
+ * \param mcanConfig  Pointer to a MCAN instance.
+ */
+void MCAN_RequestFdBitRateSwitch(const MCan_ConfigType *mcanConfig)
+{
+	Mcan      *mcan = mcanConfig->pMCan;
+	uint32_t   regVal32;
+
+	if ((mcan->MCAN_CCCR & MCAN_CCCR_CME_Msk) == MCAN_CCCR_CME(2)) {
+		regVal32 =  mcan->MCAN_CCCR & ~MCAN_CCCR_CMR_Msk;
+		mcan->MCAN_CCCR = regVal32 | MCAN_CCCR_CMR_FD_BITRATE_SWITCH;
+
+		while ((mcan->MCAN_CCCR & (MCAN_CCCR_FDBS | MCAN_CCCR_FDO)) !=
+				(MCAN_CCCR_FDBS | MCAN_CCCR_FDO)) { /* wait */ }
+	}
+}
+
+/**
+ * \brief Switch on loop back mode.
+ * TEST must be set in MCAN_CCCR - e.g. by a prior call to MCAN_InitLoopback()
+ * \param mcanConfig  Pointer to a MCAN instance.
+ */
+void MCAN_LoopbackOn(const MCan_ConfigType *mcanConfig)
+{
+	Mcan *mcan = mcanConfig->pMCan;
+	mcan->MCAN_TEST |= MCAN_TEST_LBCK_ENABLED;
+}
+
+/**
+ * \brief Switch off loop back mode.
+ * \param mcanConfig  Pointer to a MCAN instance.
+ */
+void MCAN_LoopbackOff(const MCan_ConfigType *mcanConfig)
+{
+	Mcan *mcan = mcanConfig->pMCan;
+	mcan->MCAN_TEST &= ~MCAN_TEST_LBCK_ENABLED;
+}
+
+/**
+ * \brief Enable message line and message stored to Dedicated Receive Buffer
+ * Interrupt Line.
+ * \param mcanConfig  Pointer to a MCAN instance.
+ * \param line  Message line.
+ */
+void MCAN_IEnableMessageStoredToRxDedBuffer(const MCan_ConfigType *mcanConfig,
+		MCan_IntrLineType line)
+{
+	Mcan *mcan = mcanConfig->pMCan;
+
+	if (line == CAN_INTR_LINE_0) {
+		mcan->MCAN_ILS &= ~MCAN_ILS_DRXL;
+		mcan->MCAN_ILE |= MCAN_ILE_EINT0;
+	} else  {
+		// Interrupt Line 1
+		mcan->MCAN_ILS |= MCAN_ILS_DRXL;
+		mcan->MCAN_ILE |= MCAN_ILE_EINT1;
+	}
+
+	mcan->MCAN_IR = MCAN_IR_DRX;  // clear previous flag
+	mcan->MCAN_IE |= MCAN_IE_DRXE;  // enable it
+}
+
+/**
+ * \brief Configures a Dedicated TX Buffer.
+ * \param mcanConfig  Pointer to a MCAN instance.
+ * \param buffer  Pointer to buffer.
+ * \param id  Message ID.
+ * \param idType  Type of ID
+ * \param dlc  Type of dlc.
+ */
+uint8_t   *MCAN_ConfigTxDedBuffer(const MCan_ConfigType *mcanConfig,
+								   uint8_t buffer, uint32_t id, MCan_IdType idType, MCan_DlcType dlc)
+{
+	Mcan *mcan = mcanConfig->pMCan;
+	uint32_t *pThisTxBuf = 0;
+
+	if (buffer < mcanConfig->nmbrTxDedBufElmts) {
+		pThisTxBuf = mcanConfig->msgRam.pTxDedBuf + (buffer *
+					 (mcanConfig->txBufElmtSize & ELMT_SIZE_MASK));
+
+		if (idType == CAN_STD_ID)
+			*pThisTxBuf++ = ((id << 18) & (CAN_11_BIT_ID_MASK << 18));
+		else
+			*pThisTxBuf++ = BUFFER_XTD_MASK | (id & CAN_29_BIT_ID_MASK);
+
+		*pThisTxBuf++ = (uint32_t) dlc << 16;
+		/* enable transmit from buffer to set TC interrupt bit in IR, but
+		interrupt will not happen unless TC interrupt is enabled*/
+		mcan->MCAN_TXBTIE = (1 << buffer);
+	}
+
+	return (uint8_t *) pThisTxBuf;  // now it points to the data field
+}
+
+/**
+ * \brief Send Tx buffer.
+ * \param mcanConfig  Pointer to a MCAN instance.
+ * \param buffer  Pointer to buffer.
+ */
+void MCAN_SendTxDedBuffer(const MCan_ConfigType *mcanConfig, uint8_t buffer)
+{
+	Mcan *mcan = mcanConfig->pMCan;
+
+	if (buffer < mcanConfig->nmbrTxDedBufElmts)
+		mcan->MCAN_TXBAR = (1 << buffer);
+}
+
+/**
+ * \brief Adds Message to TX Fifo / Queue
+ * \param mcanConfig  Pointer to a MCAN instance.
+ * \param id  Message ID.
+ * \param idType  Type of ID
+ * \param dlc  Type of dlc.
+ * \param data  Pointer to data.
+ */
+uint32_t MCAN_AddToTxFifoQ(const MCan_ConfigType *mcanConfig,
+							uint32_t id, MCan_IdType idType, MCan_DlcType dlc, uint8_t *data)
+{
+	Mcan *mcan = mcanConfig->pMCan;
+	uint32_t   putIdx = 255;
+	uint32_t *pThisTxBuf = 0;
+	uint8_t   *pTxData;
+	uint8_t    msgLength;
+	uint8_t    cnt;
+
+	// Configured for FifoQ and FifoQ not full?
+	if ((mcanConfig->nmbrTxFifoQElmts > 0) &&
+		((mcan->MCAN_TXFQS & MCAN_TXFQS_TFQF) == 0)) {
+		putIdx = (mcan->MCAN_TXFQS & MCAN_TXFQS_TFQPI_Msk) >> MCAN_TXFQS_TFQPI_Pos;
+		pThisTxBuf = mcanConfig->msgRam.pTxDedBuf + (putIdx *
+					 (mcanConfig->txBufElmtSize & ELMT_SIZE_MASK));
+
+		if (idType == CAN_STD_ID)
+			*pThisTxBuf++ = ((id << 18) & (CAN_11_BIT_ID_MASK << 18));
+		else
+			*pThisTxBuf++ = BUFFER_XTD_MASK | (id & CAN_29_BIT_ID_MASK);
+
+		*pThisTxBuf++ = (uint32_t) dlc << 16;
+		pTxData = (uint8_t *) pThisTxBuf;
+		msgLength = dlcToMsgLength[dlc];
+
+		for (cnt = 0; cnt < msgLength; cnt++)
+			*pTxData++ = *data++;
+
+		/* enable transmit from buffer to set TC interrupt bit in IR, but
+		interrupt will not happen unless TC interrupt is enabled */
+		mcan->MCAN_TXBTIE = (1 << putIdx);
+		// request to send
+		mcan->MCAN_TXBAR = (1 << putIdx);
+	}
+
+	return putIdx;  // now it points to the data field
+}
+
+/**
+ * \brief Check if data transmitted from buffer/fifo/queue
+ * \param mcanConfig  Pointer to a MCAN instance.
+ * \param buffer  Pointer to data buffer.
+ */
+uint8_t MCAN_IsBufferTxd(const MCan_ConfigType *mcanConfig, uint8_t buffer)
+{
+	Mcan *mcan = mcanConfig->pMCan;
+
+	return (mcan->MCAN_TXBTO & (1 << buffer));
+}
+
+/**
+ * \brief Configure RX Buffer Filter
+ * ID must match exactly for a RX Buffer Filter
+ * \param mcanConfig  Pointer to a MCAN instance.
+ * \param buffer  Pointer to data buffer.
+ * \param filter  data of filter.
+ * \param idType  Type of ID
+ */
+void MCAN_ConfigRxBufferFilter(const MCan_ConfigType *mcanConfig,
+								uint32_t buffer, uint32_t filter, uint32_t id, MCan_IdType idType)
+{
+	uint32_t *pThisRxFilt = 0;
+
+	if (buffer < mcanConfig->nmbrRxDedBufElmts) {
+		if (idType == CAN_STD_ID) {
+			if ((filter < mcanConfig->nmbrStdFilts)
+				&& (id <= CAN_11_BIT_ID_MASK)) {
+				pThisRxFilt = mcanConfig->msgRam.pStdFilts + filter;
+				// 1 word per filter
+				*pThisRxFilt = STD_FILT_SFEC_BUFFER | (id << 16) |
+							   STD_FILT_SFID2_RX_BUFFER | buffer;
+			}
+		} else {
+			// extended ID
+			if ((filter < mcanConfig->nmbrExtFilts) &&
+				(id <= CAN_29_BIT_ID_MASK)) {
+				pThisRxFilt = mcanConfig->msgRam.pExtFilts + (2 * filter);
+				// 2 words per filter
+				*pThisRxFilt++ = (uint32_t) EXT_FILT_EFEC_BUFFER | id;
+				*pThisRxFilt = EXT_FILT_EFID2_RX_BUFFER | buffer;
+			}
+		}
+	}
+}
+
+/**
+ * \brief Configure Classic Filter
+ * Classic Filters direct accepted messages to a FIFO & include both a ID and
+ * a ID mask
+ * \param mcanConfig  Pointer to a MCAN instance.
+ * \param buffer  Pointer to data buffer.
+ * \param fifo   fifo Number.
+ * \param filter  data of filter.
+ * \param idType  Type of ID
+ * \param mask  Mask to be match
+ */
+void MCAN_ConfigRxClassicFilter(const MCan_ConfigType *mcanConfig,
+								 MCan_FifoType fifo, uint8_t filter, uint32_t id,
+								 MCan_IdType idType, uint32_t mask)
+{
+	uint32_t *pThisRxFilt = 0;
+	uint32_t   filterTemp;
+
+	if (idType == CAN_STD_ID) {
+		if ((filter < mcanConfig->nmbrStdFilts) && (id <= CAN_11_BIT_ID_MASK)
+			&& (mask <= CAN_11_BIT_ID_MASK)) {
+			pThisRxFilt = mcanConfig->msgRam.pStdFilts + filter;
+			// 1 word per filter
+			filterTemp = (uint32_t) STD_FILT_SFT_CLASSIC | (id << 16) | mask;
+
+			if (fifo == CAN_FIFO_0)
+				*pThisRxFilt = STD_FILT_SFEC_FIFO0 | filterTemp;
+			else if (fifo == CAN_FIFO_1)
+				*pThisRxFilt = STD_FILT_SFEC_FIFO1 | filterTemp;
+		}
+	} else {
+		// extended ID
+		if ((filter < mcanConfig->nmbrExtFilts)
+			&& (id <= CAN_29_BIT_ID_MASK)
+			&& (mask <= CAN_29_BIT_ID_MASK)) {
+			pThisRxFilt = mcanConfig->msgRam.pExtFilts + (2 * filter);
+
+			// 2 words per filter
+			if (fifo == CAN_FIFO_0)
+				*pThisRxFilt++ = EXT_FILT_EFEC_FIFO0 | id;
+			else if (fifo == CAN_FIFO_1)
+				*pThisRxFilt++ = EXT_FILT_EFEC_FIFO1 | id;
+
+			*pThisRxFilt = (uint32_t) EXT_FILT_EFT_CLASSIC | mask;
+		}
+	}
+}
+
+/**
+ * \brief check if data received into buffer
+ * \param mcanConfig  Pointer to a MCAN instance.
+ * \param buffer  Pointer to data buffer.
+ */
+uint8_t MCAN_IsNewDataInRxDedBuffer(const MCan_ConfigType *mcanConfig,
+									 uint8_t buffer)
+{
+	Mcan *mcan = mcanConfig->pMCan;
+
+	if (buffer < 32)
+		return (mcan->MCAN_NDAT1 & (1 << buffer));
+	else if (buffer < 64)
+		return (mcan->MCAN_NDAT1 & (1 << (buffer - 32)));
+	else
+		return 0;
+}
+
+/**
+ * \brief Get Rx buffer
+ * \param mcanConfig  Pointer to a MCAN instance.
+ * \param buffer  Pointer to data buffer.
+ * \param pRxMailbox  Pointer to rx Mailbox.
+ */
+void MCAN_GetRxDedBuffer(const MCan_ConfigType *mcanConfig,
+						  uint8_t buffer, Mailbox64Type *pRxMailbox)
+{
+	Mcan      *mcan = mcanConfig->pMCan;
+	uint32_t *pThisRxBuf = 0;
+	uint32_t   tempRy;  // temp copy of RX buffer word
+	uint32_t   dlc;
+	uint8_t   *pRxData;
+	uint8_t    idx;
+
+	if (buffer < mcanConfig->nmbrRxDedBufElmts) {
+		pThisRxBuf = mcanConfig->msgRam.pRxDedBuf
+					 + (buffer * (mcanConfig->rxBufElmtSize & ELMT_SIZE_MASK));
+		tempRy = *pThisRxBuf++;  // word R0 contains ID
+
+		if (tempRy & BUFFER_XTD_MASK) {
+			// extended ID?
+			pRxMailbox->info.id = tempRy & BUFFER_EXT_ID_MASK;
+		} else {
+			// standard ID
+			pRxMailbox->info.id = (tempRy & BUFFER_STD_ID_MASK) >> 18;
+		}
+
+		tempRy = *pThisRxBuf++;  // word R1 contains DLC & time stamp
+		dlc = (tempRy & BUFFER_DLC_MASK) >> 16;
+		pRxMailbox->info.length = dlcToMsgLength[dlc];
+		pRxMailbox->info.timestamp = tempRy & BUFFER_RXTS_MASK;
+		// copy the data from the buffer to the mailbox
+		pRxData = (uint8_t *) pThisRxBuf;
+
+		SCB_CleanDCache_by_Addr((uint32_t *)pRxData, pRxMailbox->info.length);
+		SCB_CleanDCache_by_Addr((uint32_t *) & (pRxMailbox->data[0]),
+								pRxMailbox->info.length);
+
+		for (idx = 0; idx < pRxMailbox->info.length; idx++)
+			pRxMailbox->data[idx] = *pRxData++;
+
+		/* clear the new data flag for the buffer */
+
+		if (buffer < 32)
+			mcan->MCAN_NDAT1 = (1 << buffer);
+		else
+			mcan->MCAN_NDAT1 = (1 << (buffer - 32));
+
+	}
+}
+
+/**
+ * \brief Get from the receive FIFO and place in a application mailbox
+ * \param mcanConfig  Pointer to a MCAN instance.
+ * \param fifo  Fifo Number
+ * \param pRxMailbox  Pointer to rx Mailbox.
+ * \return: # of fifo entries at the start of the function
+ *         0 -> FIFO was empty at start
+ *         1 -> FIFO had 1 entry at start, but is empty at finish
+ *         2 -> FIFO had 2 entries at start, has 1 entry at finish
+ */
+uint32_t MCAN_GetRxFifoBuffer(const MCan_ConfigType *mcanConfig,
+							   MCan_FifoType fifo, Mailbox64Type *pRxMailbox)
+{
+	Mcan      *mcan = mcanConfig->pMCan;
+	uint32_t *pThisRxBuf = 0;
+	uint32_t   tempRy;  // temp copy of RX buffer word
+	uint32_t   dlc;
+	uint8_t   *pRxData;
+	uint8_t    idx;
+	uint32_t *fifo_ack_reg;
+	uint32_t   get_index;
+	uint32_t   fill_level;
+	uint32_t   element_size;
+
+	// default: fifo empty
+	fill_level = 0;
+
+	if (fifo == CAN_FIFO_0) {
+		get_index = (mcan->MCAN_RXF0S & MCAN_RXF0S_F0GI_Msk) >> MCAN_RXF0S_F0GI_Pos;
+		fill_level = (mcan->MCAN_RXF0S & MCAN_RXF0S_F0FL_Msk) >> MCAN_RXF0S_F0FL_Pos;
+		pThisRxBuf = mcanConfig->msgRam.pRxFifo0;
+		element_size = mcanConfig->rxFifo0ElmtSize & ELMT_SIZE_MASK;
+		fifo_ack_reg = (uint32_t *) &mcan->MCAN_RXF0A;
+	} else if (fifo == CAN_FIFO_1) {
+		get_index = (mcan->MCAN_RXF1S & MCAN_RXF1S_F1GI_Msk) >> MCAN_RXF1S_F1GI_Pos;
+		fill_level = (mcan->MCAN_RXF1S & MCAN_RXF1S_F1FL_Msk) >> MCAN_RXF1S_F1FL_Pos;
+		pThisRxBuf = mcanConfig->msgRam.pRxFifo1;
+		element_size = mcanConfig->rxFifo1ElmtSize & ELMT_SIZE_MASK;
+		fifo_ack_reg = (uint32_t *) &mcan->MCAN_RXF1A;
+	}
+
+	if (fill_level > 0) {
+		pThisRxBuf = pThisRxBuf + (get_index * element_size);
+		tempRy = *pThisRxBuf++;  // word R0 contains ID
+
+		if (tempRy & BUFFER_XTD_MASK) {
+			// extended ID?
+			pRxMailbox->info.id = tempRy & BUFFER_EXT_ID_MASK;
+		} else {
+			// standard ID
+			pRxMailbox->info.id = (tempRy & BUFFER_STD_ID_MASK) >> 18;
+		}
+
+		tempRy = *pThisRxBuf++;  // word R1 contains DLC & timestamps
+		dlc = (tempRy & BUFFER_DLC_MASK) >> 16;
+		pRxMailbox->info.length = dlcToMsgLength[dlc];
+		pRxMailbox->info.timestamp = tempRy & BUFFER_RXTS_MASK;
+		/* copy the data from the buffer to the mailbox */
+		pRxData = (uint8_t *) pThisRxBuf;
+
+		for (idx = 0; idx < pRxMailbox->info.length; idx++)
+			pRxMailbox->data[idx] = *pRxData++;
+
+		// acknowledge reading the fifo entry
+		*fifo_ack_reg = get_index;
+		/* return entries remaining in FIFO */
+	}
+
+	return (fill_level);
+}
+
+/**@}*/
+
Index: bsps/arm/atsam/contrib/libraries/libchip/source/mediaLB.c
===================================================================
--- bsps/arm/atsam/contrib/libraries/libchip/source/mediaLB.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libchip/source/mediaLB.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,58 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+/** \addtogroup mediaLB Working with MediaLB
+ * \ingroup peripherals_module
+ * The mediaLB driver provides the interface to configure and use the peripheral.
+ *
+ */
+/*@{*/
+/*@}*/
+
+/**
+ * \file
+ *
+ * Implementation of mediaLB controller.
+ *
+ */
+
+/*----------------------------------------------------------------------------
+ *        Headers
+ *----------------------------------------------------------------------------*/
+
+#include "chip.h"
+
+#include <stdint.h>
+
+/*----------------------------------------------------------------------------
+ *        Exported functions
+ *----------------------------------------------------------------------------*/
+
+
+
Index: bsps/arm/atsam/contrib/libraries/libchip/source/mpu.c
===================================================================
--- bsps/arm/atsam/contrib/libraries/libchip/source/mpu.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libchip/source/mpu.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,168 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+/** \file */
+
+/**
+ * \addtogroup mmu MMU Initialization
+ *
+ * \section Usage
+ *
+ * Translation Look-aside Buffers (TLBs) are an implementation technique that
+ * caches translations or translation table entries. TLBs avoid the requirement
+ * for every memory access to perform a translation table lookup.
+ * The ARM architecture does not specify the exact form of the TLB structures
+ * for any design. In a similar way to the requirements for caches, the
+ * architecture only defines certain principles for TLBs:
+ *
+ * The MMU supports memory accesses based on memory sections or pages:
+ * Super-sections Consist of 16MB blocks of memory. Support for Super sections
+ * is optional.
+ * -# Sections Consist of 1MB blocks of memory.
+ * -# Large pages Consist of 64KB blocks of memory.
+ * -# Small pages Consist of 4KB blocks of memory.
+ *
+ * Access to a memory region is controlled by the access permission bits and
+ * the domain field in the TLB entry.
+ * Memory region attributes
+ * Each TLB entry has an associated set of memory region attributes. These
+ * control accesses to the caches,
+ * how the write buffer is used, and if the memory region is Shareable and
+ * therefore must be kept coherent.
+ *
+ * Related files:\n
+ * \ref mmu.c\n
+ * \ref mmu.h \n
+ */
+
+/*-------------------------------------------------------------------------- */
+/*         Headers                                                           */
+/*-------------------------------------------------------------------------- */
+#include <chip.h>
+
+/*----------------------------------------------------------------------------
+ *        Exported functions
+
+ *----------------------------------------------------------------------------*/
+/**
+ * \brief Enables the MPU module.
+ *
+ * \param dwMPUEnable  Enable/Disable the memory region.
+ */
+void MPU_Enable(uint32_t dwMPUEnable)
+{
+	MPU->CTRL = dwMPUEnable;
+}
+
+/**
+ * \brief Set active memory region.
+ *
+ * \param dwRegionNum  The memory region to be active.
+ */
+void MPU_SetRegionNum(uint32_t dwRegionNum)
+{
+	MPU->RNR = dwRegionNum;
+}
+
+/**
+ * \brief Disable the current active region.
+ */
+extern void MPU_DisableRegion(void)
+{
+	MPU->RASR &= 0xfffffffe;
+}
+
+/**
+ * \brief Setup a memory region.
+ *
+ * \param dwRegionBaseAddr  Memory region base address.
+ * \param dwRegionAttr  Memory region attributes.
+ */
+void MPU_SetRegion(uint32_t dwRegionBaseAddr, uint32_t dwRegionAttr)
+{
+	MPU->RBAR = dwRegionBaseAddr;
+	MPU->RASR = dwRegionAttr;
+}
+
+
+/**
+ * \brief Calculate region size for the RASR.
+ */
+uint32_t MPU_CalMPURegionSize(uint32_t dwActualSizeInBytes)
+{
+	uint32_t dwRegionSize = 32;
+	uint32_t dwReturnValue = 4;
+
+	while (dwReturnValue < 31) {
+		if (dwActualSizeInBytes <= dwRegionSize)
+			break;
+		else
+			dwReturnValue++;
+
+		dwRegionSize <<= 1;
+	}
+
+	return (dwReturnValue << 1);
+}
+
+
+/**
+ *  \brief Update MPU regions.
+ *
+ *  \return Unused (ANSI-C compatibility).
+ */
+void MPU_UpdateRegions(uint32_t dwRegionNum, uint32_t dwRegionBaseAddr,
+						uint32_t dwRegionAttr)
+{
+
+	/* Disable interrupt */
+	__disable_irq();
+
+	/* Clean up data and instruction buffer */
+	__DSB();
+	__ISB();
+
+	/* Set active region */
+	MPU_SetRegionNum(dwRegionNum);
+
+	/* Disable region */
+	MPU_DisableRegion();
+
+	/* Update region attribute */
+	MPU_SetRegion(dwRegionBaseAddr, dwRegionAttr);
+
+	/* Clean up data and instruction buffer to make the new region taking
+	   effect at once */
+	__DSB();
+	__ISB();
+
+	/* Enable the interrupt */
+	__enable_irq();
+}
+
Index: bsps/arm/atsam/contrib/libraries/libchip/source/pio.c
===================================================================
--- bsps/arm/atsam/contrib/libraries/libchip/source/pio.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libchip/source/pio.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,499 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+/** \file */
+
+/*----------------------------------------------------------------------------
+ *        Headers
+ *----------------------------------------------------------------------------*/
+#include "chip.h"
+
+/*----------------------------------------------------------------------------
+ *        Local functions
+ *----------------------------------------------------------------------------*/
+
+/**
+ * \brief Configures one or more pin(s) of a PIO controller as being controlled by
+ * peripheral A. Optionally, the corresponding internal pull-up(s) can be enabled.
+ *
+ * \param pio  Pointer to a PIO controller.
+ * \param mask  Bitmask of one or more pin(s) to configure.
+ * \param enablePullUp  Indicates if the pin(s) internal pull-up shall be
+ *                      configured.
+ */
+static void PIO_SetPeripheralA(
+	Pio *pio,
+	unsigned int mask,
+	unsigned char enablePullUp)
+{
+	unsigned int abcdsr;
+	/* Disable interrupts on the pin(s) */
+	pio->PIO_IDR = mask;
+
+	/* Enable the pull-up(s) if necessary */
+	if (enablePullUp)
+		pio->PIO_PUER = mask;
+	else
+		pio->PIO_PUDR = mask;
+
+	abcdsr = pio->PIO_ABCDSR[0];
+	pio->PIO_ABCDSR[0] &= (~mask & abcdsr);
+	abcdsr = pio->PIO_ABCDSR[1];
+	pio->PIO_ABCDSR[1] &= (~mask & abcdsr);
+	pio->PIO_PDR = mask;
+}
+
+/**
+ * \brief Configures one or more pin(s) of a PIO controller as being controlled
+ * by peripheral B. Optionally, the corresponding internal pull-up(s) can be
+ * enabled.
+ *
+ * \param pio  Pointer to a PIO controller.
+ * \param mask  Bitmask of one or more pin(s) to configure.
+ * \param enablePullUp  Indicates if the pin(s) internal pull-up shall be
+ *                      configured.
+ */
+static void PIO_SetPeripheralB(
+	Pio *pio,
+	unsigned int mask,
+	unsigned char enablePullUp)
+{
+	unsigned int abcdsr;
+	/* Disable interrupts on the pin(s) */
+	pio->PIO_IDR = mask;
+
+	/* Enable the pull-up(s) if necessary */
+	if (enablePullUp)
+		pio->PIO_PUER = mask;
+	else
+		pio->PIO_PUDR = mask;
+
+	abcdsr = pio->PIO_ABCDSR[0];
+	pio->PIO_ABCDSR[0] = (mask | abcdsr);
+	abcdsr = pio->PIO_ABCDSR[1];
+	pio->PIO_ABCDSR[1] &= (~mask & abcdsr);
+
+	pio->PIO_PDR = mask;
+}
+
+/**
+ * \brief Configures one or more pin(s) of a PIO controller as being controlled
+ * by peripheral C. Optionally, the corresponding internal pull-up(s) can be
+ * enabled.
+ *
+ * \param pio  Pointer to a PIO controller.
+ * \param mask  Bitmask of one or more pin(s) to configure.
+ * \param enablePullUp  Indicates if the pin(s) internal pull-up shall be
+ *                      configured.
+ */
+static void PIO_SetPeripheralC(
+	Pio *pio,
+	unsigned int mask,
+	unsigned char enablePullUp)
+{
+	unsigned int abcdsr;
+	/* Disable interrupts on the pin(s) */
+	pio->PIO_IDR = mask;
+
+	/* Enable the pull-up(s) if necessary */
+	if (enablePullUp)
+		pio->PIO_PUER = mask;
+	else
+		pio->PIO_PUDR = mask;
+
+	abcdsr = pio->PIO_ABCDSR[0];
+	pio->PIO_ABCDSR[0] &= (~mask & abcdsr);
+	abcdsr = pio->PIO_ABCDSR[1];
+	pio->PIO_ABCDSR[1] = (mask | abcdsr);
+
+	pio->PIO_PDR = mask;
+}
+
+/**
+ * \brief Configures one or more pin(s) of a PIO controller as being controlled
+ * by peripheral D. Optionally, the corresponding internal pull-up(s) can be
+ * enabled.
+ *
+ * \param pio  Pointer to a PIO controller.
+ * \param mask  Bitmask of one or more pin(s) to configure.
+ * \param enablePullUp  Indicates if the pin(s) internal pull-up shall be
+ *                      configured.
+ */
+static void PIO_SetPeripheralD(
+	Pio *pio,
+	unsigned int mask,
+	unsigned char enablePullUp)
+{
+	unsigned int abcdsr;
+	/* Disable interrupts on the pin(s) */
+	pio->PIO_IDR = mask;
+
+	/* Enable the pull-up(s) if necessary */
+	if (enablePullUp)
+		pio->PIO_PUER = mask;
+	else
+		pio->PIO_PUDR = mask;
+
+	abcdsr = pio->PIO_ABCDSR[0];
+	pio->PIO_ABCDSR[0] = (mask | abcdsr);
+	abcdsr = pio->PIO_ABCDSR[1];
+	pio->PIO_ABCDSR[1] = (mask | abcdsr);
+
+	pio->PIO_PDR = mask;
+}
+
+/**
+ * \brief Configures one or more pin(s) or a PIO controller as inputs. Optionally,
+ * the corresponding internal pull-up(s) and glitch filter(s) can be enabled.
+ *
+ * \param pio  Pointer to a PIO controller.
+ * \param mask  Bitmask indicating which pin(s) to configure as input(s).
+ * \param enablePullUp  Indicates if the internal pull-up(s) must be enabled.
+ * \param enableFilter  Indicates if the glitch filter(s) must be enabled.
+ */
+static void PIO_SetInput(
+	Pio *pio,
+	unsigned int mask,
+	unsigned char attribute)
+{
+	/* Disable interrupts */
+	pio->PIO_IDR = mask;
+
+	/* Enable pull-up(s) if necessary */
+	if (attribute & PIO_PULLUP)
+		pio->PIO_PUER = mask;
+	else
+		pio->PIO_PUDR = mask;
+
+	/* Enable Input Filter if necessary */
+	if (attribute & (PIO_DEGLITCH | PIO_DEBOUNCE))
+		pio->PIO_IFER = mask;
+	else
+		pio->PIO_IFDR = mask;
+
+	/* Enable de-glitch or de-bounce if necessary */
+	if (attribute & PIO_DEGLITCH)
+		pio->PIO_IFSCDR = mask;
+	else {
+		if (attribute & PIO_DEBOUNCE)
+			pio->PIO_IFSCER = mask;
+	}
+
+	/* Configure additional interrupt mode registers */
+	if (attribute & PIO_IT_AIME) {
+		// enable additional interrupt mode
+		pio->PIO_AIMER  = mask;
+
+		// if bit field of selected pin is 1, set as Rising Edge/High level detection event
+		if (attribute & PIO_IT_RE_OR_HL)
+			pio->PIO_REHLSR = mask;
+		else
+			pio->PIO_FELLSR = mask;
+
+		/* if bit field of selected pin is 1, set as edge detection source */
+		if (attribute & PIO_IT_EDGE)
+			pio->PIO_ESR = mask;
+		else
+			pio->PIO_LSR = mask;
+	} else {
+		/* disable additional interrupt mode */
+		pio->PIO_AIMDR = mask;
+	}
+
+	/* Configure pin as input */
+	pio->PIO_ODR = mask;
+	pio->PIO_PER = mask;
+}
+
+/**
+ * \brief Configures one or more pin(s) of a PIO controller as outputs, with the
+ * given default value. Optionally, the multi-drive feature can be enabled
+ * on the pin(s).
+ *
+ * \param pio  Pointer to a PIO controller.
+ * \param mask  Bitmask indicating which pin(s) to configure.
+ * \param defaultValue  Default level on the pin(s).
+ * \param enableMultiDrive  Indicates if the pin(s) shall be configured as
+ *                          open-drain.
+ * \param enablePullUp  Indicates if the pin shall have its pull-up activated.
+ */
+static void PIO_SetOutput(
+	Pio *pio,
+	unsigned int mask,
+	unsigned char defaultValue,
+	unsigned char enableMultiDrive,
+	unsigned char enablePullUp)
+{
+	/* Disable interrupts */
+	pio->PIO_IDR = mask;
+
+	/* Enable pull-up(s) if necessary */
+	if (enablePullUp)
+		pio->PIO_PUER = mask;
+	else
+		pio->PIO_PUDR = mask;
+
+	/* Enable multi-drive if necessary */
+	if (enableMultiDrive)
+		pio->PIO_MDER = mask;
+	else
+		pio->PIO_MDDR = mask;
+
+	/* Set default value */
+	if (defaultValue)
+		pio->PIO_SODR = mask;
+	else
+		pio->PIO_CODR = mask;
+
+	/* Configure pin(s) as output(s) */
+	pio->PIO_OER = mask;
+	pio->PIO_PER = mask;
+}
+
+/*----------------------------------------------------------------------------
+ *         Global functions
+ *----------------------------------------------------------------------------*/
+
+/**
+ * \brief Configures a list of Pin instances, each of which can either hold a
+ * single pin or a group of pins, depending on the mask value; all pins are
+ * configured by this function. The size of the array must also be provided and
+ *  is easily computed using PIO_LISTSIZE whenever its length is not known in
+ * advance.
+ *
+ * \param list  Pointer to a list of Pin instances.
+ * \param size  Size of the Pin list (calculated using PIO_LISTSIZE).
+ *
+ * \return 1 if the pins have been configured properly; otherwise 0.
+ */
+uint8_t PIO_Configure(const Pin *list, uint32_t size)
+{
+	/* Configure pins */
+	while (size > 0) {
+		switch (list->type) {
+		case PIO_PERIPH_A:
+			PIO_SetPeripheralA(list->pio,
+							   list->mask,
+							   (list->attribute & PIO_PULLUP) ? 1 : 0);
+			break;
+
+		case PIO_PERIPH_B:
+			PIO_SetPeripheralB(list->pio,
+							   list->mask,
+							   (list->attribute & PIO_PULLUP) ? 1 : 0);
+			break;
+
+		case PIO_PERIPH_C:
+			PIO_SetPeripheralC(list->pio,
+							   list->mask,
+							   (list->attribute & PIO_PULLUP) ? 1 : 0);
+			break;
+
+		case PIO_PERIPH_D:
+			PIO_SetPeripheralD(list->pio,
+							   list->mask,
+							   (list->attribute & PIO_PULLUP) ? 1 : 0);
+			break;
+
+		case PIO_INPUT:
+#ifndef __FPGA
+			PMC_EnablePeripheral(list->id);
+#endif
+			PIO_SetInput(list->pio,
+						 list->mask,
+						 list->attribute);
+			break;
+
+		case PIO_OUTPUT_0:
+		case PIO_OUTPUT_1:
+			PIO_SetOutput(list->pio,
+						  list->mask,
+						  (list->type == PIO_OUTPUT_1),
+						  (list->attribute & PIO_OPENDRAIN) ? 1 : 0,
+						  (list->attribute & PIO_PULLUP) ? 1 : 0);
+			break;
+
+		default: return 0;
+		}
+
+		list++;
+		size--;
+	}
+
+	return 1;
+}
+
+/**
+ * \brief Sets a high output level on all the PIOs defined in the given Pin
+ * instance.
+ * This has no immediate effects on PIOs that are not output, but the PIO
+ * controller will memorize the value they are changed to outputs.
+ *
+ * \param pin  Pointer to a Pin instance describing one or more pins.
+ */
+void PIO_Set(const Pin *pin)
+{
+	pin->pio->PIO_SODR = pin->mask;
+}
+
+/**
+ * \brief Sets a low output level on all the PIOs defined in the given Pin
+ * instance.
+ * This has no immediate effects on PIOs that are not output, but the PIO
+ * controller will memorize the value they are changed to outputs.
+ *
+ * \param pin  Pointer to a Pin instance describing one or more pins.
+ */
+void PIO_Clear(const Pin *pin)
+{
+	pin->pio->PIO_CODR = pin->mask;
+}
+
+/**
+ * \brief Returns 1 if one or more PIO of the given Pin instance currently have
+ * a high level; otherwise returns 0. This method returns the actual value that
+ * is being read on the pin. To return the supposed output value of a pin, use
+ * PIO_GetOutputDataStatus() instead.
+ *
+ * \param pin  Pointer to a Pin instance describing one or more pins.
+ *
+ * \return 1 if the Pin instance contains at least one PIO that currently has
+ * a high level; otherwise 0.
+ */
+unsigned char PIO_Get(const Pin *pin)
+{
+	unsigned int reg;
+
+	if ((pin->type == PIO_OUTPUT_0) || (pin->type == PIO_OUTPUT_1))
+		reg = pin->pio->PIO_ODSR;
+	else
+		reg = pin->pio->PIO_PDSR;
+
+	if ((reg & pin->mask) == 0)
+		return 0;
+	else
+		return 1;
+}
+
+/**
+ * \brief Returns 1 if one or more PIO of the given Pin are configured to output
+ * a high level (even if they are not output).
+ * To get the actual value of the pin, use PIO_Get() instead.
+ *
+ * \param pin  Pointer to a Pin instance describing one or more pins.
+ *
+ * \return 1 if the Pin instance contains at least one PIO that is configured
+ * to output a high level; otherwise 0.
+ */
+unsigned char PIO_GetOutputDataStatus(const Pin *pin)
+{
+	if ((pin->pio->PIO_ODSR & pin->mask) == 0)
+		return 0;
+	else
+		return 1;
+}
+
+/**
+ * \brief Configures Glitch or Denouncing filter for input.
+ *
+ * \param pin  Pointer to a Pin instance describing one or more pins.
+ * \param cuttoff  Cut off frequency for denounce filter.
+ */
+void PIO_SetDebounceFilter(const Pin *pin, uint32_t cuttoff)
+{
+	Pio *pio = pin->pio;
+
+	pio->PIO_IFSCER = pin->mask; /* set Denouncing, 0 bit field no effect */
+	pio->PIO_SCDR = ((32678 / (2 * (cuttoff))) - 1) & 0x3FFF;
+	/* the lowest 14 bits work */
+}
+
+/**
+ * \brief Enable write protect.
+ *
+ * \param pin  Pointer to a Pin instance describing one or more pins.
+ */
+void PIO_EnableWriteProtect(const Pin *pin)
+{
+	Pio *pio = pin->pio;
+
+	pio->PIO_WPMR = (PIO_WPMR_WPKEY_VALID | PIO_WPMR_WPEN_EN);
+}
+
+/**
+ * \brief Disable write protect.
+ *
+ * \param pin  Pointer to a Pin instance describing one or more pins.
+ */
+
+void PIO_DisableWriteProtect(const Pin *pin)
+{
+	Pio *pio = pin->pio;
+
+	pio->PIO_WPMR = (PIO_WPMR_WPKEY_VALID | PIO_WPMR_WPEN_DIS);
+}
+
+/**
+ * \brief Get write protect violation information.
+ *
+ * \param pin  Pointer to a Pin instance describing one or more pins.
+ */
+uint32_t PIO_GetWriteProtectViolationInfo(const Pin *pin)
+{
+	Pio *pio = pin->pio;
+	return (pio->PIO_WPSR);
+}
+
+/**
+ *  \brief Set pin type
+ * the pin is controlled by the corresponding peripheral (A, B, C, D,E)
+ * \param pin      Pointer to a Pin instance describing one or more pins.
+ * \param pinType  PIO_PERIPH_A, PIO_PERIPH_B, ...
+ */
+void PIO_SetPinType(Pin *pin, uint8_t pinType)
+{
+	pin->type = pinType;
+}
+
+/**
+ * \brief Set the drive strength of the pin.
+ *
+ * \param pin  Pointer to a Pin instance describing one or more pins.
+ * \param strength  0 for low drive strength or 1 for high drive strength.
+ */
+void PIO_SetDriveStrength(const Pin *pin, uint8_t strength)
+{
+	Pio *pio = pin->pio;
+
+	if (strength) {
+		pio->PIO_DRIVER |= pin->mask;
+	} else {
+		pio->PIO_DRIVER &= ~(pin->mask);
+	}
+}
Index: bsps/arm/atsam/contrib/libraries/libchip/source/pio_capture.c
===================================================================
--- bsps/arm/atsam/contrib/libraries/libchip/source/pio_capture.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libchip/source/pio_capture.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,255 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+/** \addtogroup pio_capture_module Working with PIO Parallel Capture Mode
+ *  \ingroup peripherals_module
+ * The PIO Parallel Capture Mode driver provides the interface to configure
+ * and use the PIO Parallel Capture Mode peripheral.\n
+ *
+ * The PIO Controller integrates an interface able to read data from a CMOS digital
+ * image sensor, a high-speed parallel ADC, a DSP synchronous port in synchronous
+ * mode, etc.... For better understanding and to ease reading, the following
+ * description uses an example with a CMOS digital image sensor
+ *
+ * To use the PIO Parallel Capture, the user has to follow these few steps:
+ * <ul>
+ *   <li> Enable PIOA peripheral clock </li>
+ *   <li> Configure the PDC </li>
+ *   <li> Configure the PIO Capture interrupt </li>
+ *   <li> Enable the PDC </li>
+ *   <li> Enable the PIO Capture </li>
+ *   <li> Wait for interrupt </li>
+ *   <li> Disable the interrupt </li>
+ *   <li> Read the DATA </li>
+ * </ul>
+ *
+ * For more accurate information, please look at the PIO Parallel Capture Mode
+ * section of the Datasheet.
+ *
+ * <b>API Usage:</b>
+ *
+ *  -# Configurate the interrupt for PIOA, can be done by
+ * PIO_InitializeInterrupts()
+ *  -# Initialize the PIO Parallel Capture API by filing the SpioCaptureInit
+ *     structure
+ * options:
+ *       - alwaysSampling: for sample data with or without take in account
+ *         ENABLE pins.
+ *       - halfSampling: for sample all data or only one time out of two
+ *  -# Call PIO_CaptureInit() for init and enable the PDC, init the PIO capture.
+ *  -# Call PIO_CaptureEnable() for enable the PIO Parallel Capture.
+ *  -# When an interrupt is received, the PIO_CaptureHandler() is call and the
+ *     respective callback is launch.
+ *  -# When the transfer is complete, the user need to disable interrupt with
+ *     PIO_CaptureDisableIt(). Otherwise, the PDC will send an interrupt.
+ *  -# The data receive by the PIO Parallel Capture is inside the buffer passed
+ *     in the PIO_CaptureInit().
+ *
+ * Related files :\n
+ * \ref pio_capture.c\n
+ * \ref pio_capture.h\n
+ */
+/*@{*/
+/*@}*/
+/**
+ * \file
+ *
+ * Implementation of PIO Parallel Capture.
+ *
+ */
+
+/*----------------------------------------------------------------------------
+ *        Headers
+ *----------------------------------------------------------------------------*/
+
+#include "chip.h"
+
+#include <assert.h>
+
+#define PIO_PCISR_RXBUFF (0x1u<<3)
+#define PIO_PCISR_ENDRX  (0x1u<<2)
+/*----------------------------------------------------------------------------
+ *        Local Functions
+ *----------------------------------------------------------------------------*/
+/** Copy the API structure for interrupt handler */
+static SpioCaptureInit *_PioCaptureCopy;
+
+/*----------------------------------------------------------------------------
+ *        Global Functions
+ *----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------*/
+/**
+ * \brief The PIO_CaptureHandler must be called by the PIO Capture Interrupt
+ * Service Routine with the corresponding PIO Capture instance.
+ */
+/*----------------------------------------------------------------------------*/
+extern void PIO_CaptureHandler(void)
+{
+	volatile uint32_t pio_captureSr;
+	uint32_t k;
+
+	/* Read the status register*/
+	pio_captureSr = PIOA->PIO_PCISR;
+	k = pio_captureSr;
+	pio_captureSr = k & PIOA->PIO_PCIMR;
+
+	if (pio_captureSr & PIO_PCISR_DRDY) {
+		/* Parallel Capture Mode Data Ready */
+		if (_PioCaptureCopy->CbkDataReady != NULL)
+			_PioCaptureCopy->CbkDataReady(_PioCaptureCopy);
+		else
+			TRACE_DEBUG("IT PIO Capture Data Ready received (no callback)\n\r");
+	}
+
+	if (pio_captureSr & PIO_PCISR_OVRE) {
+		/* Parallel Capture Mode Overrun Error */
+		if (_PioCaptureCopy->CbkOverrun != NULL)
+			_PioCaptureCopy->CbkOverrun(_PioCaptureCopy);
+		else
+			TRACE_DEBUG("IT PIO Capture Overrun Error received (no callback)\n\r");
+	}
+
+	if (pio_captureSr & PIO_PCISR_RXBUFF) {
+		/* Reception Buffer Full */
+		if (_PioCaptureCopy->CbkBuffFull != NULL)
+			_PioCaptureCopy->CbkBuffFull(_PioCaptureCopy);
+		else {
+			TRACE_DEBUG("IT PIO Capture Reception Buffer Full received \
+					(no callback)\n\r");
+		}
+	}
+
+	if (pio_captureSr & PIO_PCISR_ENDRX) {
+		/* End of Reception Transfer */
+		if (_PioCaptureCopy->CbkEndReception != NULL)
+			_PioCaptureCopy->CbkEndReception(_PioCaptureCopy);
+		else {
+			TRACE_DEBUG("IT PIO Capture End of Reception Transfer \
+					received (no callback)\n\r");
+		}
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/**
+ * \brief Disable Interrupt of the PIO Capture
+ * \param itToDisable : Interrupt to disable
+ */
+/*----------------------------------------------------------------------------*/
+void PIO_CaptureDisableIt(uint32_t itToDisable)
+{
+	/* Parallel capture mode is enabled */
+	PIOA->PIO_PCIDR = itToDisable;
+}
+
+/*----------------------------------------------------------------------------*/
+/**
+ * \brief Enable Interrupt of the PIO Capture
+ * \param itToEnable : Interrupt to enable
+ */
+/*----------------------------------------------------------------------------*/
+void PIO_CaptureEnableIt(uint32_t itToEnable)
+{
+	/* Parallel capture mode is enabled */
+	PIOA->PIO_PCIER = itToEnable;
+}
+
+/*----------------------------------------------------------------------------*/
+/**
+ * \brief Enable the PIO Capture
+ */
+/*----------------------------------------------------------------------------*/
+void PIO_CaptureEnable(void)
+{
+	/* PDC: Receive Pointer Register */
+	//    PIOA->PIO_RPR = (uint32_t)_PioCaptureCopy->pData;
+	//    /* PDC: Receive Counter Register */
+	//    /* Starts peripheral data transfer if corresponding channel is active */
+	//    PIOA->PIO_RCR = PIO_RCR_RXCTR(_PioCaptureCopy->dPDCsize);
+
+	/* Parallel capture mode is enabled */
+	PIOA->PIO_PCMR |= PIO_PCMR_PCEN;
+}
+
+/*----------------------------------------------------------------------------*/
+/**
+ * \brief Disable the PIO Capture
+ */
+/*----------------------------------------------------------------------------*/
+void PIO_CaptureDisable(void)
+{
+	/* Parallel capture mode is disabled */
+	PIOA->PIO_PCMR &= (uint32_t)(~PIO_PCMR_PCEN);
+}
+
+/*----------------------------------------------------------------------------*/
+/**
+ * \brief Initialize the PIO Capture
+ * \param dsize :
+ *  0 = The reception data in the PIO_PCRHR register is a BYTE (8-bit).
+ *  1 = The reception data in the PIO_PCRHR register is a HALF-WORD (16-bit).
+ * 2/3 = The reception data in the PIO_PCRHR register is a WORD (32-bit).
+ * \param alwaysSampling: ALWYS: Parallel Capture Mode Always Sampling
+ * 0 = The parallel capture mode samples the data when both data enables are active.
+ * 1 = The parallel capture mode samples the data whatever the data enables are.
+ * \param halfSampling: HALFS: Parallel Capture Mode Half Sampling
+ * 0 = The parallel capture mode samples all the data.
+ * 1 = The parallel capture mode samples the data only one time out of two.
+ * \param modeFirstSample: FRSTS: Parallel Capture Mode First Sample
+ * This bit is useful only if the HALFS bit is set to 1. If data are numbered
+ * in the order that they are received with an index from 0 to n:
+ * 0 = Only data with an even index are sampled.
+ * 1 = Only data with an odd index are sampled.
+ */
+/*----------------------------------------------------------------------------*/
+void PIO_CaptureInit(SpioCaptureInit *pInit)
+{
+	PMC_EnablePeripheral(ID_PIOA);
+
+	assert((pInit->dsize < 0x4));
+	assert((pInit->alwaysSampling < 2));
+	assert((pInit->halfSampling < 2));
+	assert((pInit->modeFirstSample < 2));
+	/* Copy the API structure for interrupt handler */
+	_PioCaptureCopy = pInit;
+
+	if (pInit->CbkDataReady != NULL)
+		PIOA->PIO_PCIER = PIO_PCISR_DRDY;
+
+	if (pInit->CbkOverrun != NULL)
+		PIOA->PIO_PCIER = PIO_PCISR_OVRE;
+
+	if (pInit->CbkEndReception != NULL)
+		PIOA->PIO_PCIER = PIO_PCISR_ENDRX;
+
+	if (pInit->CbkBuffFull != NULL)
+		PIOA->PIO_PCIER = PIO_PCISR_RXBUFF;
+}
+
Index: bsps/arm/atsam/contrib/libraries/libchip/source/pio_it.c
===================================================================
--- bsps/arm/atsam/contrib/libraries/libchip/source/pio_it.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libchip/source/pio_it.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,283 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+/*
+ * \file
+ */
+
+/*----------------------------------------------------------------------------
+ *        Headers
+ *----------------------------------------------------------------------------*/
+
+#include "chip.h"
+
+#include <rtems/irq-extension.h>
+#include <rtems/sysinit.h>
+#include <bsp/fatal.h>
+
+/*----------------------------------------------------------------------------
+ *        Local definitions
+ *----------------------------------------------------------------------------*/
+
+/* Maximum number of interrupt sources that can be defined. This
+ * constant can be increased, but the current value is the smallest possible
+ * that will be compatible with all existing projects. */
+#define MAX_INTERRUPT_SOURCES       7
+
+/*----------------------------------------------------------------------------
+ *        Local types
+ *----------------------------------------------------------------------------*/
+
+/**
+ * Describes a PIO interrupt source, including the PIO instance triggering the
+ * interrupt and the associated interrupt handler.
+ */
+typedef struct _InterruptSource {
+	/* Pointer to the source pin instance. */
+	const Pin *pPin;
+
+	/* Interrupt handler. */
+	void (*handler)(const Pin *, void *arg);
+
+	void *arg;
+} InterruptSource;
+
+/*----------------------------------------------------------------------------
+ *        Local variables
+ *----------------------------------------------------------------------------*/
+
+/* List of interrupt sources. */
+static InterruptSource _aIntSources[MAX_INTERRUPT_SOURCES];
+
+/* Number of currently defined interrupt sources. */
+static uint32_t _dwNumSources = 0;
+
+/*----------------------------------------------------------------------------
+ *        Local Functions
+ *----------------------------------------------------------------------------*/
+
+/**
+ * \brief Handles all interrupts on the given PIO controller.
+ * \param id  PIO controller ID.
+ * \param pPio  PIO controller base address.
+ */
+static void PIO_Interrupt(Pio *pPio, uint32_t id)
+{
+	uint32_t status;
+	size_t i;
+
+	status = pPio->PIO_ISR;
+	status &= pPio->PIO_IMR;
+
+	for (i = 0; status != 0 && i < MAX_INTERRUPT_SOURCES; ++i) {
+		const InterruptSource *is = &_aIntSources[i];
+		const Pin *pin = is->pPin;;
+
+		if (pin->id == id) {
+			uint32_t mask = pin->mask;
+
+			if ((status & mask) != 0) {
+				status &= ~mask;
+				(*is->handler)(pin, is->arg);
+			}
+		}
+	}
+}
+
+/*----------------------------------------------------------------------------
+ *        Global Functions
+ *----------------------------------------------------------------------------*/
+
+/**
+ * \brief Parallel IO Controller A interrupt handler
+ * \Redefined PIOA interrupt handler for NVIC interrupt table.
+ */
+static void PIOA_Interrupt(void *arg)
+{
+	PIO_Interrupt(arg, ID_PIOA);
+}
+
+/**
+ * \brief Parallel IO Controller B interrupt handler
+ * \Redefined PIOB interrupt handler for NVIC interrupt table.
+ */
+static void PIOB_Interrupt(void *arg)
+{
+	PIO_Interrupt(arg, ID_PIOB);
+}
+
+/**
+ * \brief Parallel IO Controller C interrupt handler
+ * \Redefined PIOC interrupt handler for NVIC interrupt table.
+ */
+static void PIOC_Interrupt(void *arg)
+{
+	PIO_Interrupt(arg, ID_PIOC);
+}
+
+
+/**
+ * \brief Parallel IO Controller D interrupt handler
+ * \Redefined PIOD interrupt handler for NVIC interrupt table.
+ */
+static void PIOD_Interrupt(void *arg)
+{
+	PIO_Interrupt(arg, ID_PIOD);
+}
+
+/**
+ * \brief Parallel IO Controller E interrupt handler
+ * \Redefined PIOE interrupt handler for NVIC interrupt table.
+ */
+static void PIOE_Interrupt(void *arg)
+{
+	PIO_Interrupt(arg, ID_PIOE);
+}
+
+static void PIO_SysInitializeInterrupts(void)
+{
+	rtems_status_code sc;
+
+	TRACE_DEBUG("PIO_Initialize()\n\r");
+
+	/* Configure PIO interrupt sources */
+	TRACE_DEBUG("PIO_Initialize: Configuring PIOA\n\r");
+	PMC_EnablePeripheral(ID_PIOA);
+	PIOA->PIO_ISR;
+	PIOA->PIO_IDR = 0xFFFFFFFF;
+	sc = rtems_interrupt_handler_install(
+		PIOA_IRQn,
+		"PIO A",
+		RTEMS_INTERRUPT_UNIQUE,
+		PIOA_Interrupt,
+		PIOA
+	);
+	if (sc != RTEMS_SUCCESSFUL) {
+		bsp_fatal(ATSAM_FATAL_PIO_IRQ_A);
+	}
+
+	TRACE_DEBUG("PIO_Initialize: Configuring PIOB\n\r");
+	PMC_EnablePeripheral(ID_PIOB);
+	PIOB->PIO_ISR;
+	PIOB->PIO_IDR = 0xFFFFFFFF;
+	sc = rtems_interrupt_handler_install(
+		PIOB_IRQn,
+		"PIO B",
+		RTEMS_INTERRUPT_UNIQUE,
+		PIOB_Interrupt,
+		PIOB
+	);
+	if (sc != RTEMS_SUCCESSFUL) {
+		bsp_fatal(ATSAM_FATAL_PIO_IRQ_B);
+	}
+
+	TRACE_DEBUG("PIO_Initialize: Configuring PIOC\n\r");
+	PMC_EnablePeripheral(ID_PIOC);
+	PIOC->PIO_ISR;
+	PIOC->PIO_IDR = 0xFFFFFFFF;
+	sc = rtems_interrupt_handler_install(
+		PIOC_IRQn,
+		"PIO C",
+		RTEMS_INTERRUPT_UNIQUE,
+		PIOC_Interrupt,
+		PIOC
+	);
+	if (sc != RTEMS_SUCCESSFUL) {
+		bsp_fatal(ATSAM_FATAL_PIO_IRQ_C);
+	}
+
+	TRACE_DEBUG("PIO_Initialize: Configuring PIOD\n\r");
+	PMC_EnablePeripheral(ID_PIOD);
+	PIOD->PIO_ISR;
+	PIOD->PIO_IDR = 0xFFFFFFFF;
+	sc = rtems_interrupt_handler_install(
+		PIOD_IRQn,
+		"PIO D",
+		RTEMS_INTERRUPT_UNIQUE,
+		PIOD_Interrupt,
+		PIOD
+	);
+	if (sc != RTEMS_SUCCESSFUL) {
+		bsp_fatal(ATSAM_FATAL_PIO_IRQ_D);
+	}
+
+	TRACE_DEBUG("PIO_Initialize: Configuring PIOE\n\r");
+	PMC_EnablePeripheral(ID_PIOE);
+	PIOE->PIO_ISR;
+	PIOE->PIO_IDR = 0xFFFFFFFF;
+	sc = rtems_interrupt_handler_install(
+		PIOE_IRQn,
+		"PIO E",
+		RTEMS_INTERRUPT_UNIQUE,
+		PIOE_Interrupt,
+		PIOE
+	);
+	if (sc != RTEMS_SUCCESSFUL) {
+		bsp_fatal(ATSAM_FATAL_PIO_IRQ_E);
+	}
+}
+
+RTEMS_SYSINIT_ITEM(PIO_SysInitializeInterrupts, RTEMS_SYSINIT_BSP_START,
+    RTEMS_SYSINIT_ORDER_LAST);
+
+/**
+ * Configures a PIO or a group of PIO to generate an interrupt on status
+ * change. The provided interrupt handler will be called with the triggering
+ * pin as its parameter (enabling different pin instances to share the same
+ * handler).
+ * \param pPin  Pointer to a Pin instance.
+ * \param handler  Interrupt handler function pointer.
+ * \param arg Pointer to interrupt handler argument
+ */
+void PIO_ConfigureIt(const Pin *pPin, void (*handler)(const Pin *, void *arg),
+    void *arg)
+{
+	InterruptSource *pSource;
+	rtems_interrupt_level level;
+
+	TRACE_DEBUG("PIO_ConfigureIt()\n\r");
+
+	rtems_interrupt_disable(level);
+
+	if (_dwNumSources == MAX_INTERRUPT_SOURCES) {
+		bsp_fatal(ATSAM_FATAL_PIO_CONFIGURE_IT);
+	}
+
+	pSource = &(_aIntSources[_dwNumSources]);
+	pSource->pPin = pPin;
+	pSource->handler = handler;
+	pSource->arg = arg;
+
+	_dwNumSources++;
+
+	rtems_interrupt_enable(level);
+
+	/* Define new source */
+	TRACE_DEBUG("PIO_ConfigureIt: Defining new source #%d.\n\r", _dwNumSources);
+}
Index: bsps/arm/atsam/contrib/libraries/libchip/source/pmc.c
===================================================================
--- bsps/arm/atsam/contrib/libraries/libchip/source/pmc.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libchip/source/pmc.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,597 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+/** \addtogroup pmc_module Working with PMC
+ * The PMC driver provides the Interface to configure the Power Management
+ * Controller (PMC).
+ *
+ *  \section Usage
+ * <ul>
+ *  <li> Enables/Disable the clock of a peripheral by using
+ * PMC_EnablePeripheral() and PMC_DisablePeripheral().</li>
+ *  <li> Enables/Disable the clock of all peripherals by using
+ * PMC_EnableAllPeripherals() and PMC_DisableAllPeripherals().</li>
+ *  <li> Get status of a peripheral using PMC_IsPeriphEnabled().</li>
+ *  <li> Manage the clocks using PMC_EnableExtOsc(), PMC_DisableExtOsc(),
+ * PMC_SelectExtOsc(), PMC_SelectExtBypassOsc(), PMC_EnableIntRC4_8_12MHz(),
+ * PMC_DisableIntRC4_8_12MHz(), PMC_SetPllaClock(), PMC_SetMckSelection(),
+ * PMC_DisableAllClocks(), PMC_ConfigureMckWithPlla(),
+ * PMC_EnableXT32KFME() and PMC_ConfigurePCK2().</li>
+ *
+ * </ul>
+ * For more accurate information, please look at the PMC section of the Datasheet.
+ *
+ * Related files :\n
+ * \ref pmc.c\n
+ * \ref pmc.h.\n
+*/
+
+/**
+*  \file
+*
+*  \section Purpose
+*
+*  Interface for configuring and using Power Management Controller (PMC)
+* peripherals.
+*
+*/
+
+/**
+ * \file
+ *
+ * Implementation of Power Management Controller (PMC).
+ *
+ */
+
+/*----------------------------------------------------------------------------
+ *        Headers
+ *----------------------------------------------------------------------------*/
+
+#include "chip.h"
+
+#include <assert.h>
+
+/*----------------------------------------------------------------------------
+ *        Local definitions
+ *----------------------------------------------------------------------------*/
+
+#define MASK_STATUS0 0xFFFFFFFC
+#define MASK_STATUS1 0xFFFFFFFF
+
+/*----------------------------------------------------------------------------
+ *        Local functions
+ *----------------------------------------------------------------------------*/
+/**
+ * \brief Switch MCK to PLLA clock.
+ */
+static void _PMC_SwitchMck2PllaClock(void)
+
+{
+	/* Select PLLA as input clock for MCK */
+	PMC->PMC_MCKR = (PMC->PMC_MCKR & ~PMC_MCKR_CSS_Msk) | PMC_MCKR_CSS_PLLA_CLK;
+
+	/* Wait until the master clock is established */
+	while (!(PMC->PMC_SR & PMC_SR_MCKRDY));
+}
+
+/**
+ * \brief Switch MCK to main clock.
+ */
+static void _PMC_SwitchMck2MainClock(void)
+{
+	/* Select Main Oscillator as input clock for MCK */
+	PMC->PMC_MCKR = (PMC->PMC_MCKR & ~PMC_MCKR_CSS_Msk) | PMC_MCKR_CSS_MAIN_CLK;
+
+	/* Wait until the master clock is established */
+	while (!(PMC->PMC_SR & PMC_SR_MCKRDY));
+
+	PMC->PMC_MCKR = PMC_MCKR_CSS_MAIN_CLK;
+
+	while (!(PMC->PMC_SR & PMC_SR_MCKRDY));
+}
+
+/**
+ * \brief Switch MCK to slow clock.
+ */
+static void _PMC_SwitchMck2SlowClock(void)
+{
+	/* Select Slow Clock as input clock for MCK */
+	PMC->PMC_MCKR = (PMC->PMC_MCKR & ~PMC_MCKR_CSS_Msk) | PMC_MCKR_CSS_SLOW_CLK;
+
+	/* Wait until the master clock is established */
+	while (!(PMC->PMC_SR & PMC_SR_MCKRDY));
+}
+
+/**
+ * \brief Set prescaler for MCK.
+ *
+ * \param prescaler Master Clock prescaler
+ */
+static void _PMC_SetMckPrescaler(uint32_t prescaler)
+{
+	/* Change MCK Prescaler divider in PMC_MCKR register */
+	PMC->PMC_MCKR = (PMC->PMC_MCKR & ~PMC_MCKR_PRES_Msk) | prescaler;
+
+	/* Wait until the master clock is established */
+	while (!(PMC->PMC_SR & PMC_SR_MCKRDY));
+}
+/*----------------------------------------------------------------------------
+ *        Exported functions
+ *----------------------------------------------------------------------------*/
+
+/**
+ * \brief Enables the clock of a peripheral. The peripheral ID is used
+ * to identify which peripheral is targeted.
+ *
+ * \note The ID must NOT be shifted (i.e. 1 << ID_xxx).
+ *
+ * \param id  Peripheral ID (ID_xxx).
+ */
+void PMC_EnablePeripheral(uint32_t dwId)
+{
+	assert(dwId < 63);
+
+	if (dwId < 32) {
+		if ((PMC->PMC_PCSR0 & ((uint32_t)1 << dwId)) == ((uint32_t)1 << dwId)) {
+			TRACE_DEBUG("PMC_EnablePeripheral: clock of peripheral" \
+						 " %u is already enabled\n\r", (unsigned int)dwId);
+		} else
+			PMC->PMC_PCER0 = 1 << dwId;
+	} else {
+		dwId -= 32;
+
+		if ((PMC->PMC_PCSR1 & ((uint32_t)1 << dwId)) == ((uint32_t)1 << dwId)) {
+			TRACE_DEBUG("PMC_EnablePeripheral: clock of peripheral" \
+						 " %u is already enabled\n\r", (unsigned int)(dwId + 32));
+		} else
+			PMC->PMC_PCER1 = 1 << dwId;
+	}
+}
+
+/**
+ * \brief Disables the clock of a peripheral. The peripheral ID is used
+ * to identify which peripheral is targeted.
+ *
+ * \note The ID must NOT be shifted (i.e. 1 << ID_xxx).
+ *
+ * \param id  Peripheral ID (ID_xxx).
+ */
+void PMC_DisablePeripheral(uint32_t dwId)
+{
+	assert(dwId < 63);
+
+	if (dwId < 32) {
+		if ((PMC->PMC_PCSR0 & ((uint32_t)1 << dwId)) != ((uint32_t)1 << dwId)) {
+			TRACE_DEBUG("PMC_DisablePeripheral: clock of peripheral" \
+						" %u is not enabled\n\r", (unsigned int)dwId);
+		} else
+			PMC->PMC_PCDR0 = 1 << dwId;
+	} else {
+		dwId -= 32;
+
+		if ((PMC->PMC_PCSR1 & ((uint32_t)1 << dwId)) != ((uint32_t)1 << dwId)) {
+			TRACE_DEBUG("PMC_DisablePeripheral: clock of peripheral"
+						 " %u is not enabled\n\r", (unsigned int)(dwId + 32));
+		} else
+			PMC->PMC_PCDR1 = 1 << dwId;
+	}
+}
+
+/**
+ * \brief Enable all the periph clock via PMC.
+ */
+void PMC_EnableAllPeripherals(void)
+{
+	PMC->PMC_PCER0 = MASK_STATUS0;
+
+	while ((PMC->PMC_PCSR0 & MASK_STATUS0) != MASK_STATUS0);
+
+	PMC->PMC_PCER1 = MASK_STATUS1;
+
+	while ((PMC->PMC_PCSR1 & MASK_STATUS1) != MASK_STATUS1);
+
+	TRACE_DEBUG("Enable all periph clocks\n\r");
+}
+
+/**
+ * \brief Disable all the periph clock via PMC.
+ */
+void PMC_DisableAllPeripherals(void)
+{
+	PMC->PMC_PCDR0 = MASK_STATUS0;
+
+	while ((PMC->PMC_PCSR0 & MASK_STATUS0) != 0);
+
+	PMC->PMC_PCDR1 = MASK_STATUS1;
+
+	while ((PMC->PMC_PCSR1 & MASK_STATUS1) != 0);
+
+	TRACE_DEBUG("Disable all periph clocks\n\r");
+}
+
+/**
+ * \brief Get Periph Status for the given peripheral ID.
+ *
+ * \param id  Peripheral ID (ID_xxx).
+ */
+uint32_t PMC_IsPeriphEnabled(uint32_t dwId)
+{
+	assert(dwId < ID_PERIPH_COUNT);
+
+	if (dwId < 32)
+		return (PMC->PMC_PCSR0 & (1 << dwId));
+	else
+		return (PMC->PMC_PCSR1 & (1 << (dwId - 32)));
+}
+
+
+/**
+ * \brief Enable external oscillator as main clock input.
+ */
+void PMC_EnableExtOsc(void)
+{
+	uint32_t   read_MOR;
+
+	/* Before switching MAIN OSC on external crystal : enable it and don't disable
+	 * at the same time RC OSC in case of if MAIN OSC is still using RC OSC
+	 */
+
+	read_MOR = PMC->CKGR_MOR;
+	read_MOR &= ~CKGR_MOR_MOSCRCF_Msk;
+	/* reset MOSCRCF field in MOR register before select RC 12MHz */
+	read_MOR  |= (CKGR_MOR_KEY_PASSWD
+				  | CKGR_MOR_MOSCRCF_12_MHz
+				  | CKGR_MOR_MOSCXTEN
+				  | CKGR_MOR_MOSCRCEN
+				  | CKGR_MOR_MOSCXTST(DEFAUTL_MAIN_OSC_COUNT));
+	/* enable external crystal - enable RC OSC */
+
+	PMC->CKGR_MOR = read_MOR;
+
+	while (!(PMC->PMC_SR & PMC_SR_MOSCRCS));
+
+	/* wait end of RC oscillator stabilization */
+	while (!(PMC->PMC_SR & PMC_SR_MCKRDY));
+
+	read_MOR |= CKGR_MOR_MOSCSEL;
+	/* select external crystal */
+
+	PMC->CKGR_MOR = read_MOR;
+
+	while (!(PMC->PMC_SR & PMC_SR_MOSCSELS));
+
+	/* Wait end of Main Oscillator Selection */
+	while (!(PMC->PMC_SR & PMC_SR_MCKRDY));
+}
+
+/**
+ * \brief Disable external 12MHz oscillator.
+ */
+void PMC_DisableExtOsc(void)
+{
+	uint32_t   read_MOR;
+
+	read_MOR = PMC->CKGR_MOR;
+	read_MOR &= ~CKGR_MOR_MOSCXTEN; /* disable main xtal osc */
+	PMC->CKGR_MOR = CKGR_MOR_KEY_PASSWD | read_MOR;
+
+	while (!(PMC->PMC_SR & PMC_SR_MCKRDY));
+}
+
+/**
+ * \brief Select external OSC.
+ */
+void PMC_SelectExtOsc(void)
+{
+	/* switch from internal RC 12 MHz to external OSC 12 MHz */
+	/* wait Main XTAL Oscillator stabilisation*/
+	if ((PMC->CKGR_MOR & CKGR_MOR_MOSCSEL) == CKGR_MOR_MOSCSEL) {
+		PMC_DisableIntRC4_8_12MHz();
+		return;
+	}
+
+	/* enable external OSC 12 MHz */
+	PMC->CKGR_MOR |= CKGR_MOR_MOSCXTEN | CKGR_MOR_KEY_PASSWD;
+
+	/* wait Main CLK Ready */
+	while (!(PMC->CKGR_MCFR & CKGR_MCFR_MAINFRDY));
+
+	/* switch MAIN clock to external OSC 12 MHz*/
+	PMC->CKGR_MOR |= CKGR_MOR_MOSCSEL | CKGR_MOR_KEY_PASSWD;
+
+	/* wait MAIN clock status change for external OSC 12 MHz selection*/
+	while (!(PMC->PMC_SR & PMC_SR_MOSCSELS));
+
+	/* in case where MCK is running on MAIN CLK */
+	while (!(PMC->PMC_SR & PMC_SR_MCKRDY));
+
+	PMC_DisableIntRC4_8_12MHz();
+}
+
+
+/**
+ * \brief Select external OSC.
+ */
+void PMC_SelectExtBypassOsc(void)
+{
+	volatile uint32_t timeout;
+
+	if ((PMC->CKGR_MOR & CKGR_MOR_MOSCXTBY) != CKGR_MOR_MOSCXTBY) {
+		PMC->CKGR_MOR = CKGR_MOR_KEY_PASSWD |
+						CKGR_MOR_MOSCRCEN |
+						CKGR_MOR_MOSCXTST(0xFF) |
+						CKGR_MOR_MOSCXTBY;
+		PMC->CKGR_MOR |= CKGR_MOR_KEY_PASSWD | CKGR_MOR_MOSCSEL;
+
+		/* wait MAIN clock status change for external OSC 12 MHz selection*/
+		while (!(PMC->PMC_SR & PMC_SR_MOSCSELS));
+
+		// Check if an external clock is provided
+		for (timeout = 0; timeout < 0xffff; timeout++);
+
+		while (!(PMC->CKGR_MCFR & CKGR_MCFR_MAINFRDY));
+	}
+}
+
+/**
+ * \brief Enable internal 4/8/12MHz fast RC as main clock input.
+ *
+ * \param freqSelect fast RC frequency (FAST_RC_4MHZ, FAST_RC_8MHZ,
+ * FAST_RC_12MHZ).
+ */
+void PMC_EnableIntRC4_8_12MHz(uint32_t freqSelect)
+{
+	/* Enable Fast RC oscillator but DO NOT switch to RC now */
+	PMC->CKGR_MOR |= (CKGR_MOR_KEY_PASSWD | CKGR_MOR_MOSCRCEN);
+
+	/* Wait the Fast RC to stabilize */
+	while (!(PMC->PMC_SR & PMC_SR_MOSCRCS));
+
+	/* Change Fast RC oscillator frequency */
+	PMC->CKGR_MOR = (PMC->CKGR_MOR & ~CKGR_MOR_MOSCRCF_Msk) |
+					CKGR_MOR_KEY_PASSWD | freqSelect;
+
+	/* Wait the Fast RC to stabilize */
+	while (!(PMC->PMC_SR & PMC_SR_MOSCRCS));
+
+	/* Switch to Fast RC */
+	PMC->CKGR_MOR = (PMC->CKGR_MOR & ~CKGR_MOR_MOSCSEL) |
+					CKGR_MOR_KEY_PASSWD;
+
+	/* wait MAIN clock status change for Fast RC oscillator */
+	while (!(PMC->PMC_SR & PMC_SR_MOSCSELS));
+
+	/* in case where MCK is running on MAIN CLK */
+	while (!(PMC->PMC_SR & PMC_SR_MCKRDY));
+
+}
+
+/**
+ * \brief Disable internal 4/8/12MHz fast RC.
+ */
+void PMC_DisableIntRC4_8_12MHz(void)
+{
+	uint32_t   read_MOR;
+
+	read_MOR = PMC->CKGR_MOR;
+
+	read_MOR &= ~CKGR_MOR_MOSCRCF_Msk;   /* reset MOSCRCF field in MOR register */
+	read_MOR &= ~CKGR_MOR_MOSCRCEN;      /* disable fast RC */
+	PMC->CKGR_MOR = CKGR_MOR_KEY_PASSWD | read_MOR;
+
+	while (!(PMC->PMC_SR & PMC_SR_MCKRDY));
+}
+
+/**
+ * \brief Configure PLLA clock by giving MUL and DIV.
+ *        Disable PLLA when 'mul' set to 0.
+ *
+ * \param mul  PLL multiplier factor.
+ * \param div  PLL divider factor.
+ */
+void PMC_SetPllaClock(uint32_t mul, uint32_t div)
+{
+	if (mul != 0) {
+		/* Init PLL speed */
+		PMC->CKGR_PLLAR = CKGR_PLLAR_ONE
+						  | CKGR_PLLAR_PLLACOUNT(DEFAUTL_PLLA_COUNT)
+						  | CKGR_PLLAR_MULA(mul - 1)
+						  | CKGR_PLLAR_DIVA(div);
+
+		/* Wait for PLL stabilization */
+		while (!(PMC->PMC_SR & PMC_SR_LOCKA));
+	} else {
+		PMC->CKGR_PLLAR = CKGR_PLLAR_ONE; /* disable PLL A */
+	}
+}
+
+/**
+ * \brief Selection of Master Clock.
+ *
+ * \param clockSource  Master Clock source.
+ * \param prescaler    Master Clock prescaler.
+ *
+ * \note
+ * The PMC_MCKR register must not be programmed in a single write
+ * operation (see. Product Data Sheet).
+ */
+void PMC_SetMckSelection(uint32_t clockSource, uint32_t prescaler)
+{
+	switch (clockSource) {
+	case PMC_MCKR_CSS_SLOW_CLK :
+		_PMC_SwitchMck2SlowClock();
+		_PMC_SetMckPrescaler(prescaler);
+		break;
+
+	case PMC_MCKR_CSS_MAIN_CLK :
+		_PMC_SwitchMck2MainClock();
+		_PMC_SetMckPrescaler(prescaler);
+		break;
+
+	case PMC_MCKR_CSS_PLLA_CLK :
+		_PMC_SetMckPrescaler(prescaler);
+		_PMC_SwitchMck2PllaClock();
+		break;
+	}
+}
+
+/**
+ * \brief Disable all clocks.
+ */
+void PMC_DisableAllClocks(void)
+{
+	uint32_t   read_reg;
+
+	PMC->PMC_SCDR = PMC_SCDR_PCK0 | PMC_SCDR_PCK1 | PMC_SCDR_PCK2 | PMC_SCDR_PCK3 |
+					PMC_SCDR_PCK4 | PMC_SCDR_PCK5 | PMC_SCDR_PCK6;  /* disable PCK */
+
+	_PMC_SwitchMck2MainClock();
+
+	PMC->CKGR_PLLAR = PMC->CKGR_PLLAR & ~CKGR_PLLAR_MULA_Msk;   /* disable PLL A */
+
+	_PMC_SwitchMck2SlowClock();
+
+	read_reg  =  PMC->CKGR_MOR;
+	read_reg  =  (read_reg & ~CKGR_MOR_MOSCRCEN) | CKGR_MOR_KEY_PASSWD;
+	/* disable RC OSC */
+
+	PMC->CKGR_MOR = read_reg;
+
+	PMC_DisableAllPeripherals(); /* disable all peripheral clocks */
+}
+
+/**
+ * \brief Configure PLLA as clock input for MCK.
+ *
+ * \param mul        PLL multiplier factor (not shifted, don't minus 1).
+ * \param div        PLL divider factor (not shifted).
+ * \param prescaler  Master Clock prescaler (shifted as in register).
+ */
+void PMC_ConfigureMckWithPlla(uint32_t mul, uint32_t div, uint32_t prescaler)
+{
+	/* First, select Main OSC as input clock for MCK */
+	_PMC_SwitchMck2MainClock();
+
+	/* Then, Set PLLA clock */
+	PMC_SetPllaClock(mul, div);
+
+	/* Wait until the master clock is established for the case we already
+	    turn on the PLL */
+	while (!(PMC->PMC_SR & PMC_SR_MCKRDY));
+
+	/* Finally, select PllA as input clock for MCK */
+	PMC_SetMckSelection(PMC_MCKR_CSS_PLLA_CLK, prescaler);
+}
+
+
+/**
+ * \brief Configure PLLA as clock input for MCK.
+ *
+ * \param mul        PLL multiplier factor (not shifted, don't minus 1).
+ * \param div        PLL divider factor (not shifted).
+ * \param prescaler  Master Clock prescaler (shifted as in register).
+ */
+void PMC_EnableXT32KFME(void)
+{
+
+	uint32_t   read_MOR;
+
+	/* Before switching MAIN OSC on external crystal : enable it and don't
+	disable at the same time RC OSC in case of if MAIN OSC is still using
+	RC OSC */
+
+	read_MOR = PMC->CKGR_MOR;
+
+	read_MOR |= (CKGR_MOR_KEY_PASSWD | CKGR_MOR_XT32KFME);
+	/* enable external crystal - enable RC OSC */
+
+	PMC->CKGR_MOR = read_MOR;
+
+}
+
+/**
+ * \brief Configure PLLA as clock input for MCK.
+ *
+ * \param mul        PLL multiplier factor (not shifted, don't minus 1).
+ * \param div        PLL divider factor (not shifted).
+ * \param prescaler  Master Clock prescaler (shifted as in register).
+ */
+void PMC_ConfigurePCK0(uint32_t MasterClk, uint32_t prescaler)
+{
+	PMC->PMC_SCDR = PMC_SCDR_PCK0;  /* disable PCK */
+
+	while ((PMC->PMC_SCSR)& PMC_SCSR_PCK0);
+
+	PMC->PMC_PCK[0] = MasterClk | prescaler;
+	PMC->PMC_SCER = PMC_SCER_PCK0;
+
+	while (!((PMC->PMC_SR) & PMC_SR_PCKRDY0));
+
+}
+
+
+/**
+ * \brief Configure PLLA as clock input for MCK.
+ *
+ * \param mul        PLL multiplier factor (not shifted, don't minus 1).
+ * \param div        PLL divider factor (not shifted).
+ * \param prescaler  Master Clock prescaler (shifted as in register).
+ */
+void PMC_ConfigurePCK1(uint32_t MasterClk, uint32_t prescaler)
+{
+	PMC->PMC_SCDR = PMC_SCDR_PCK1;  /* disable PCK */
+
+	while ((PMC->PMC_SCSR)& PMC_SCSR_PCK1);
+
+	PMC->PMC_PCK[1] = MasterClk | prescaler;
+	PMC->PMC_SCER = PMC_SCER_PCK1;
+
+	while (!((PMC->PMC_SR) & PMC_SR_PCKRDY1));
+
+}
+
+/**
+ * \brief Configure PLLA as clock input for MCK.
+ *
+ * \param mul        PLL multiplier factor (not shifted, don't minus 1).
+ * \param div        PLL divider factor (not shifted).
+ * \param prescaler  Master Clock prescaler (shifted as in register).
+ */
+void PMC_ConfigurePCK2(uint32_t MasterClk, uint32_t prescaler)
+{
+	PMC->PMC_SCDR = PMC_SCDR_PCK2;  /* disable PCK */
+
+	while ((PMC->PMC_SCSR)& PMC_SCSR_PCK2);
+
+	PMC->PMC_PCK[2] = MasterClk | prescaler;
+	PMC->PMC_SCER = PMC_SCER_PCK2;
+
+	while (!((PMC->PMC_SR) & PMC_SR_PCKRDY2));
+
+}
Index: bsps/arm/atsam/contrib/libraries/libchip/source/pwmc.c
===================================================================
--- bsps/arm/atsam/contrib/libraries/libchip/source/pwmc.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libchip/source/pwmc.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,579 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+/** \addtogroup pwm_module Working with PWM
+ *  \ingroup peripherals_module
+ * The PWM driver provides the interface to configure and use the PWM
+ * peripheral.
+ *
+ * The PWM macrocell controls square output waveforms of 4 channels.
+ * Characteristics of output waveforms such as period, duty-cycle,
+ * dead-time can be configured.\n
+ * Some of PWM channels can be linked together as synchronous channel and
+ * duty-cycle of synchronous channels can be updated by PDC automatically.
+ *
+ * Before enabling the channels, they must have been configured first.
+ * The main settings include:
+ * <ul>
+ * <li>Configuration of the clock generator.</li>
+ * <li>Selection of the clock for each channel.</li>
+ * <li>Configuration of output waveform characteristics, such as period,
+ * duty-cycle etc.</li>
+ * <li>Configuration for synchronous channels if needed.</li>
+ *    - Selection of the synchronous channels.
+ *    - Selection of the moment when the WRDY flag and the corresponding PDC
+ *      transfer request are set (PTRM and PTRCS in the PWM_SCM register).
+ *    - Configuration of the update mode (UPDM in the PWM_SCM register).
+ *    - Configuration of the update period (UPR in the PWM_SCUP register).
+ * </ul>
+ *
+ * After the channels is enabled, the user must use respective update registers
+ * to change the wave characteristics to prevent unexpected output waveform.
+ * i.e. PWM_CDTYUPDx register should be used if user want to change duty-cycle
+ * when the channel is enabled.
+ *
+ * For more accurate information, please look at the PWM section of the
+ * Datasheet.
+ *
+ * Related files :\n
+ * \ref pwmc.c\n
+ * \ref pwmc.h.\n
+ */
+/*@{*/
+/*@}*/
+
+/**
+ * \file
+ *
+ * Implementation of the Pulse Width Modulation Controller (PWM) peripheral.
+ *
+ */
+
+/*----------------------------------------------------------------------------
+ *        Headers
+ *----------------------------------------------------------------------------*/
+
+#include "chip.h"
+
+#include <stdint.h>
+#include <assert.h>
+
+/*----------------------------------------------------------------------------
+ *         Local functions
+ *----------------------------------------------------------------------------*/
+
+/**
+ * \brief Finds a prescaler/divisor couple to generate the desired frequency
+ * from MCK.
+ *
+ * Returns the value to enter in PWM_CLK or 0 if the configuration cannot be
+ * met.
+ *
+ * \param frequency  Desired frequency in Hz.
+ * \param mck  Master clock frequency in Hz.
+ */
+static uint16_t FindClockConfiguration(
+	uint32_t frequency,
+	uint32_t mck)
+{
+	uint32_t divisors[11] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024};
+	uint8_t divisor = 0;
+	uint32_t prescaler;
+
+	assert(frequency <= mck);
+
+	/* Find prescaler and divisor values */
+	prescaler = (mck / divisors[divisor]) / frequency;
+
+	while ((prescaler > 255) && (divisor < 11)) {
+		divisor++;
+		prescaler = (mck / divisors[divisor]) / frequency;
+	}
+
+	/* Return result */
+	if (divisor < 11) {
+		TRACE_DEBUG("Found divisor=%u and prescaler=%u for freq=%uHz\n\r",
+					 divisors[divisor], prescaler, frequency);
+
+		return prescaler | (divisor << 8);
+	} else
+		return 0;
+}
+
+/*----------------------------------------------------------------------------
+ *        Exported functions
+ *----------------------------------------------------------------------------*/
+
+/**
+ * \brief Configures PWM a channel with the given parameters, basic configure
+ * function.
+ *
+ * The PWM controller must have been clocked in the PMC prior to calling this
+ * function.
+ * Beware: this function disables the channel. It waits until disable is effective.
+ *
+ * \param channel  Channel number.
+ * \param prescaler  Channel prescaler.
+ * \param alignment  Channel alignment.
+ * \param polarity  Channel polarity.
+ */
+void PWMC_ConfigureChannel(
+	Pwm *pPwm,
+	uint8_t channel,
+	uint32_t prescaler,
+	uint32_t alignment,
+	uint32_t polarity)
+{
+	pPwm->PWM_CH_NUM[0].PWM_CMR = 1;
+
+	//    assert(prescaler < PWM_CMR0_CPRE_MCKB);
+	assert((alignment & (uint32_t)~PWM_CMR_CALG) == 0);
+	assert((polarity & (uint32_t)~PWM_CMR_CPOL) == 0);
+
+	/* Disable channel (effective at the end of the current period) */
+	if ((pPwm->PWM_SR & (1 << channel)) != 0) {
+		pPwm->PWM_DIS = 1 << channel;
+
+		while ((pPwm->PWM_SR & (1 << channel)) != 0);
+	}
+
+	/* Configure channel */
+	pPwm->PWM_CH_NUM[channel].PWM_CMR = prescaler | alignment | polarity;
+}
+
+/**
+ * \brief Configures PWM a channel with the given parameters, extend configure
+ * function.
+ * The PWM controller must have been clocked in the PMC prior to calling this
+ * function.
+ * Beware: this function disables the channel. It waits until disable is effective.
+ *
+ * \param channel            Channel number.
+ * \param prescaler          Channel prescaler.
+ * \param alignment          Channel alignment.
+ * \param polarity           Channel polarity.
+ * \param countEventSelect   Channel counter event selection.
+ * \param DTEnable           Channel dead time generator enable.
+ * \param DTHInverte         Channel Dead-Time PWMHx output Inverted.
+ * \param DTLInverte         Channel Dead-Time PWMHx output Inverted.
+ */
+void PWMC_ConfigureChannelExt(
+	Pwm *pPwm,
+	uint8_t channel,
+	uint32_t prescaler,
+	uint32_t alignment,
+	uint32_t polarity,
+	uint32_t countEventSelect,
+	uint32_t DTEnable,
+	uint32_t DTHInverte,
+	uint32_t DTLInverte)
+{
+	//    assert(prescaler < PWM_CMR0_CPRE_MCKB);
+	assert((alignment & (uint32_t)~PWM_CMR_CALG) == 0);
+	assert((polarity & (uint32_t)~PWM_CMR_CPOL) == 0);
+	assert((countEventSelect & (uint32_t)~PWM_CMR_CES) == 0);
+	assert((DTEnable & (uint32_t)~PWM_CMR_DTE) == 0);
+	assert((DTHInverte & (uint32_t)~PWM_CMR_DTHI) == 0);
+	assert((DTLInverte & (uint32_t)~PWM_CMR_DTLI) == 0);
+
+	/* Disable channel (effective at the end of the current period) */
+	if ((pPwm->PWM_SR & (1 << channel)) != 0) {
+		pPwm->PWM_DIS = 1 << channel;
+
+		while ((pPwm->PWM_SR & (1 << channel)) != 0);
+	}
+
+	/* Configure channel */
+	pPwm->PWM_CH_NUM[channel].PWM_CMR = prescaler | alignment | polarity |
+										countEventSelect | DTEnable | DTHInverte | DTLInverte;
+}
+
+/**
+ * \brief Configures PWM clocks A & B to run at the given frequencies.
+ *
+ * This function finds the best MCK divisor and prescaler values automatically.
+ *
+ * \param clka  Desired clock A frequency (0 if not used).
+ * \param clkb  Desired clock B frequency (0 if not used).
+ * \param mck  Master clock frequency.
+ */
+void PWMC_ConfigureClocks(Pwm *pPwm, uint32_t clka, uint32_t clkb, uint32_t mck)
+{
+	uint32_t mode = 0;
+	uint32_t result;
+
+	/* Clock A */
+	if (clka != 0) {
+		result = FindClockConfiguration(clka, mck);
+		assert(result != 0);
+		mode |= result;
+	}
+
+	/* Clock B */
+	if (clkb != 0) {
+		result = FindClockConfiguration(clkb, mck);
+		assert(result != 0);
+		mode |= (result << 16);
+	}
+
+	/* Configure clocks */
+	TRACE_DEBUG("Setting PWM_CLK = 0x%08X\n\r", mode);
+	pPwm->PWM_CLK = mode;
+}
+
+/**
+ * \brief Sets the period value used by a PWM channel.
+ *
+ * This function writes directly to the CPRD register if the channel is disabled;
+ * otherwise, it uses the update register CPRDUPD.
+ *
+ * \param channel Channel number.
+ * \param period  Period value.
+ */
+void PWMC_SetPeriod(Pwm *pPwm, uint8_t channel, uint16_t period)
+{
+	/* If channel is disabled, write to CPRD */
+	if ((pPwm->PWM_SR & (1 << channel)) == 0)
+
+		pPwm->PWM_CH_NUM[channel].PWM_CPRD = period;
+	else {
+		/* Otherwise use update register */
+		pPwm->PWM_CH_NUM[channel].PWM_CPRDUPD = period;
+	}
+}
+
+/**
+ * \brief Sets the duty cycle used by a PWM channel.
+ * This function writes directly to the CDTY register if the channel is disabled;
+ * otherwise it uses the update register CDTYUPD.
+ * Note that the duty cycle must always be inferior or equal to the channel
+ * period.
+ *
+ * \param channel  Channel number.
+ * \param duty     Duty cycle value.
+ */
+void PWMC_SetDutyCycle(Pwm *pPwm, uint8_t channel, uint16_t duty)
+{
+	assert(duty <= pPwm->PWM_CH_NUM[channel].PWM_CPRD);
+
+	/* If channel is disabled, write to CDTY */
+	if ((pPwm->PWM_SR & (1 << channel)) == 0)
+		pPwm->PWM_CH_NUM[channel].PWM_CDTY = duty;
+	else {
+		/* Otherwise use update register */
+		pPwm->PWM_CH_NUM[channel].PWM_CDTYUPD = duty;
+	}
+}
+
+/**
+ * \brief Sets the dead time used by a PWM channel.
+ * This function writes directly to the DT register if the channel is disabled;
+ * otherwise it uses the update register DTUPD.
+ * Note that the dead time must always be inferior or equal to the channel
+ * period.
+ *
+ * \param channel  Channel number.
+ * \param timeH    Dead time value for PWMHx output.
+ * \param timeL    Dead time value for PWMLx output.
+ */
+void PWMC_SetDeadTime(Pwm *pPwm, uint8_t channel, uint16_t timeH,
+					   uint16_t timeL)
+{
+	assert(timeH <= pPwm->PWM_CH_NUM[channel].PWM_CPRD);
+	assert(timeL <= pPwm->PWM_CH_NUM[channel].PWM_CPRD);
+
+	/* If channel is disabled, write to DT */
+	if ((pPwm->PWM_SR & (1 << channel)) == 0)
+		pPwm->PWM_CH_NUM[channel].PWM_DT = timeH | (timeL << 16);
+	else {
+		/* Otherwise use update register */
+		pPwm->PWM_CH_NUM[channel].PWM_DTUPD = timeH | (timeL << 16);
+	}
+}
+
+/**
+ * \brief Configures Synchronous channel with the given parameters.
+ * Beware: At this time, the channels should be disabled.
+ *
+ * \param channels                 Bitwise OR of Synchronous channels.
+ * \param updateMode               Synchronous channel update mode.
+ * \param requestMode              PDC transfer request mode.
+ * \param requestComparisonSelect  PDC transfer request comparison selection.
+ */
+void PWMC_ConfigureSyncChannel(Pwm *pPwm,
+								uint32_t channels,
+								uint32_t updateMode,
+								uint32_t requestMode,
+								uint32_t requestComparisonSelect)
+{
+	pPwm->PWM_SCM = channels | updateMode | requestMode | requestComparisonSelect;
+}
+
+/**
+ * \brief Sets the update period of the synchronous channels.
+ * This function writes directly to the SCUP register if the channel #0 is disabled;
+ * otherwise it uses the update register SCUPUPD.
+ *
+ * \param period   update period.
+ */
+void PWMC_SetSyncChannelUpdatePeriod(Pwm *pPwm, uint8_t period)
+{
+	/* If channel is disabled, write to SCUP */
+	if ((pPwm->PWM_SR & (1 << 0)) == 0)
+		pPwm->PWM_SCUP = period;
+	else {
+		/* Otherwise use update register */
+		pPwm->PWM_SCUPUPD = period;
+	}
+}
+
+/**
+ * \brief Sets synchronous channels update unlock.
+ *
+ * Note: If the UPDM field is set to 0, writing the UPDULOCK bit to 1
+ * triggers the update of the period value, the duty-cycle and
+ * the dead-time values of synchronous channels at the beginning
+ * of the next PWM period. If the field UPDM is set to 1 or 2,
+ * writing the UPDULOCK bit to 1 triggers only the update of
+ * the period value and of the dead-time values of synchronous channels.
+ * This bit is automatically reset when the update is done.
+ */
+void PWMC_SetSyncChannelUpdateUnlock(Pwm *pPwm)
+{
+	pPwm->PWM_SCUC = PWM_SCUC_UPDULOCK;
+}
+
+/**
+ * \brief Enables the given PWM channel.
+ *
+ * This does NOT enable the corresponding pin;this must be done in the user code.
+ *
+ * \param channel  Channel number.
+ */
+void PWMC_EnableChannel(Pwm *pPwm, uint8_t channel)
+{
+	pPwm->PWM_ENA = 1 << channel;
+}
+
+/**
+ * \brief Disables the given PWM channel.
+ *
+ * Beware, channel will be effectively disabled at the end of the current period.
+ * Application can check channel is disabled using the following wait loop:
+ * while ((PWM->PWM_SR & (1 << channel)) != 0);
+ *
+ * \param channel  Channel number.
+ */
+void PWMC_DisableChannel(Pwm *pPwm, uint8_t channel)
+{
+	pPwm->PWM_DIS = 1 << channel;
+}
+
+/**
+ * \brief Enables the period interrupt for the given PWM channel.
+ *
+ * \param channel  Channel number.
+ */
+void PWMC_EnableChannelIt(Pwm *pPwm, uint8_t channel)
+{
+	pPwm->PWM_IER1 = 1 << channel;
+}
+
+/**
+ * \brief Return PWM Interrupt Status2 Register
+ *
+ */
+uint32_t PWMC_GetStatus2(Pwm *pPwm)
+{
+	return pPwm->PWM_ISR2;
+}
+
+/**
+ * \brief Disables the period interrupt for the given PWM channel.
+ *
+ * \param channel  Channel number.
+ */
+void PWMC_DisableChannelIt(Pwm *pPwm, uint8_t channel)
+{
+	pPwm->PWM_IDR1 = 1 << channel;
+}
+
+/**
+ * \brief Enables the selected interrupts sources on a PWMC peripheral.
+ *
+ * \param sources1  Bitwise OR of selected interrupt sources of PWM_IER1.
+ * \param sources2  Bitwise OR of selected interrupt sources of PWM_IER2.
+ */
+void PWMC_EnableIt(Pwm *pPwm, uint32_t sources1, uint32_t sources2)
+{
+	pPwm->PWM_IER1 = sources1;
+	pPwm->PWM_IER2 = sources2;
+}
+
+/**
+ * \brief Disables the selected interrupts sources on a PWMC peripheral.
+ *
+ * \param sources1  Bitwise OR of selected interrupt sources of PWM_IDR1.
+ * \param sources2  Bitwise OR of selected interrupt sources of PWM_IDR2.
+ */
+void PWMC_DisableIt(Pwm *pPwm, uint32_t sources1, uint32_t sources2)
+{
+	pPwm->PWM_IDR1 = sources1;
+	pPwm->PWM_IDR2 = sources2;
+}
+
+/**
+ * \brief Set PWM output override value.
+ *
+ * \param value  Bitwise OR of output override value.
+ */
+void PWMC_SetOverrideValue(Pwm *pPwm, uint32_t value)
+{
+	pPwm->PWM_OOV = value;
+}
+
+/**
+ * \brief Enable override output.
+ *
+ * \param value  Bitwise OR of output selection.
+ * \param sync   0: enable the output asynchronously, 1: enable it synchronously
+ */
+void PWMC_EnableOverrideOutput(Pwm *pPwm, uint32_t value, uint32_t sync)
+{
+	if (sync)
+		pPwm->PWM_OSSUPD = value;
+	else
+		pPwm->PWM_OSS = value;
+}
+
+/**
+ * \brief Output Selection for override PWM output.
+ *
+ * \param value  Bitwise OR of output override value.
+ */
+void PWMC_OutputOverrideSelection(Pwm *pPwm, uint32_t value)
+{
+	pPwm->PWM_OS = value;
+}
+
+
+/**
+ * \brief Disable override output.
+ *
+ * \param value  Bitwise OR of output selection.
+ * \param sync   0: enable the output asynchronously, 1: enable it synchronously
+ */
+void PWMC_DisableOverrideOutput(Pwm *pPwm, uint32_t value, uint32_t sync)
+{
+	if (sync)
+
+		pPwm->PWM_OSCUPD = value;
+	else
+
+		pPwm->PWM_OSC = value;
+}
+
+/**
+ * \brief Set PWM fault mode.
+ *
+ * \param mode  Bitwise OR of fault mode.
+ */
+void PWMC_SetFaultMode(Pwm *pPwm, uint32_t mode)
+{
+	pPwm->PWM_FMR = mode;
+}
+
+/**
+ * \brief PWM fault clear.
+ *
+ * \param fault  Bitwise OR of fault to clear.
+ */
+void PWMC_FaultClear(Pwm *pPwm, uint32_t fault)
+{
+	pPwm->PWM_FCR = fault;
+}
+
+/**
+ * \brief Set PWM fault protection value.
+ *
+ * \param value  Bitwise OR of fault protection value.
+ */
+void PWMC_SetFaultProtectionValue(Pwm *pPwm, uint32_t value)
+{
+	pPwm->PWM_FPV1 = value;
+}
+
+/**
+ * \brief Enable PWM fault protection.
+ *
+ * \param value  Bitwise OR of FPEx[y].
+ */
+void PWMC_EnableFaultProtection(Pwm *pPwm, uint32_t value)
+{
+	pPwm->PWM_FPE = value;
+}
+
+/**
+ * \brief Configure comparison unit.
+ *
+ * \param x     comparison x index
+ * \param value comparison x value.
+ * \param mode  comparison x mode
+ */
+void PWMC_ConfigureComparisonUnit(Pwm *pPwm, uint32_t x, uint32_t value,
+								   uint32_t mode)
+{
+	assert(x < 8);
+
+	/* If channel is disabled, write to CMPxM & CMPxV */
+	if ((pPwm->PWM_SR & (1 << 0)) == 0) {
+		pPwm->PWM_CMP[x].PWM_CMPM = mode;
+		pPwm->PWM_CMP[x].PWM_CMPV = value;
+	} else {
+		/* Otherwise use update register */
+		pPwm->PWM_CMP[x].PWM_CMPMUPD = mode;
+		pPwm->PWM_CMP[x].PWM_CMPVUPD = value;
+	}
+}
+
+/**
+ * \brief Configure event line mode.
+ *
+ * \param x    Line x
+ * \param mode Bitwise OR of line mode selection
+ */
+void PWMC_ConfigureEventLineMode(Pwm *pPwm, uint32_t x, uint32_t mode)
+{
+	assert(x < 2);
+
+	if (x == 0)
+		pPwm->PWM_ELMR[0] = mode;
+	else if (x == 1)
+		pPwm->PWM_ELMR[1] = mode;
+}
Index: bsps/arm/atsam/contrib/libraries/libchip/source/qspi.c
===================================================================
--- bsps/arm/atsam/contrib/libraries/libchip/source/qspi.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libchip/source/qspi.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,757 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+/** \addtogroup qspi_module Working with QSPI
+ * \ingroup peripherals_module
+ * The QSPI driver provides the interface to configure and use the QSPI
+ * peripheral.
+ *
+ * The Serial Peripheral Interface (QSPI) circuit is a synchronous serial
+ * data link that provides communication with external devices in Master
+ * or Slave Mode.
+ *
+ * To use the QSPI, the user has to follow these few steps:
+ * -# Enable the QSPI pins required by the application (see pio.h).
+ * -# Configure the QSPI using the \ref QSPI_Configure(). This enables the
+ *    peripheral clock. The mode register is loaded with the given value.
+ * -# Configure all the necessary chip selects with \ref QSPI_ConfigureNPCS().
+ * -# Enable the QSPI by calling \ref QSPI_Enable().
+ * -# Send/receive data using \ref QSPI_Write() and \ref QSPI_Read(). Note that
+*  \ref QSPI_Read()
+ *    must be called after \ref QSPI_Write() to retrieve the last value read.
+ * -# Send/receive data using the PDC with the \ref QSPI_WriteBuffer() and
+ *    \ref QSPI_ReadBuffer() functions.
+ * -# Disable the QSPI by calling \ref QSPI_Disable().
+ *
+ * For more accurate information, please look at the QSPI section of the
+ * Datasheet.
+ *
+ * Related files :\n
+ * \ref qspi.c\n
+ * \ref qspi.h.\n
+ */
+/*@{*/
+/*@}*/
+
+/**
+ * \file
+ *
+ * Implementation of Serial Peripheral Interface (QSPI) controller.
+ *
+ */
+
+/*----------------------------------------------------------------------------
+ *        Headers
+ *----------------------------------------------------------------------------*/
+
+#include "chip.h"
+#include "stdlib.h"
+#include "string.h"
+
+#include <stdint.h>
+#include <bsp/iocopy.h>
+
+
+#define SCRAMBLE_KEY    0x0BADDEAD
+/*----------------------------------------------------------------------------
+ *        Internal functions
+ *----------------------------------------------------------------------------*/
+
+
+
+/**
+ * \brief Configure QSPI/SPI mode
+ *
+ * \param pQspi  Pointer to a Qspi instance.
+ */
+__STATIC_INLINE void QSPI_ConfigureMode(Qspi *pQspi, uint8_t dMode)
+{
+	assert(pQspi);
+	pQspi->QSPI_MR =  dMode;
+}
+
+/**
+ * \brief Configure mode register of QSPI
+ *
+ * \param pQspi  Pointer to a Qspi instance.
+ */
+__STATIC_INLINE void QSPI_Configure(Qspi *pQspi, uint32_t dwConfiguration)
+{
+	assert(pQspi);
+	pQspi->QSPI_MR |=  dwConfiguration;
+}
+
+
+/**
+ * \brief Configures a instruction address for QSPI in QSPI mode
+ *
+ * \param pQspi   Pointer to a Qspi instance.
+ * \param dwAddr  Instruction Address
+ */
+__STATIC_INLINE void QSPI_SetInstAddr(Qspi *pQspi, uint32_t dwAddr)
+{
+	assert(pQspi);
+	pQspi->QSPI_IAR = dwAddr;
+}
+
+
+/**
+ * \brief Configures instruction register with a given command for QSPI
+ *
+ * \param pQspi   Pointer to a Qspi instance.
+ * \param dwInst  Instruction Code
+ * \param dwOpt   Instruction Code option
+ */
+__STATIC_INLINE void QSPI_SetInst(Qspi *pQspi, uint8_t dwInst, uint8_t dwOpt)
+{
+	assert(pQspi);
+	pQspi->QSPI_ICR = (dwInst | QSPI_ICR_OPT(dwOpt));
+}
+
+/**
+ * \brief Configures instruction frame register of QSPI
+ *
+ * \param pQspi         Pointer to a Qspi instance.
+ * \param pInstFrame    Instruction Frame configuration
+ */
+__STATIC_INLINE void QSPI_SetInstFrame(Qspi *pQspi,
+										QspiInstFrame_t *pInstFrame)
+{
+	assert(pQspi);
+	pQspi->QSPI_IFR = pInstFrame->InstFrame.val;
+}
+
+/**
+ * \brief Reads the Instruction frame of QSPI
+ *
+ * \param pQspi   Pointer to an Qspi instance.
+ */
+__STATIC_INLINE uint32_t QSPI_GetInstFrame(Qspi *pQspi)
+{
+	assert(pQspi);
+	return pQspi->QSPI_IFR;
+}
+
+/**
+ * \brief Read QSPI RDR register for SPI mode
+ *
+ * \param pQspi   Pointer to an Qspi instance.
+ */
+__STATIC_INLINE uint16_t QSPI_ReadSPI(Qspi *pQspi)
+{
+	assert(pQspi);
+
+	while (!QSPI_GetStatus(pQspi, IsReceived));
+
+	return  pQspi->QSPI_RDR;
+}
+
+
+/**
+ * \brief Write to QSPI Tx register in SPI mode
+ *
+ * \param pQspi   Pointer to an Qspi instance.
+ * \param wData   Data to transmit
+ */
+__STATIC_INLINE void QSPI_WriteSPI(Qspi *pQspi, uint16_t wData)
+{
+	assert(pQspi);
+
+	/* Send data */
+	while (!QSPI_GetStatus(pQspi, IsTxEmpty));
+
+	pQspi->QSPI_TDR = wData;
+
+	while (!QSPI_GetStatus(pQspi, IsTxSent));
+}
+
+/**
+ * \brief Configures QSPI scrambling with a given Key
+ *
+ * \param pQspi         Pointer to an Qspi instance.
+ * \param wKey          Key for scramble/unscramble
+ * \param EnableFlag    Enable/disable scramble
+ * \param Random        Add random value with given key
+ */
+__STATIC_INLINE void QSPI_ScrambleData(Qspi *pQspi, uint32_t wKey,
+										uint8_t EnableFlag, uint8_t Random)
+{
+	assert(pQspi);
+	assert(EnableFlag < 2);
+	assert(Random < 2);
+
+	if (EnableFlag)
+		pQspi->QSPI_SKR = wKey;
+
+	pQspi->QSPI_SMR = (EnableFlag | (Random << 1));
+}
+
+/*----------------------------------------------------------------------------
+ *        Exported functions
+ *----------------------------------------------------------------------------*/
+
+/**
+ * \brief Enables a QSPI peripheral.
+ *
+ * \param pQspi  Pointer to a Qspi instance.
+ */
+void QSPI_Enable(Qspi *pQspi)
+{
+	assert(pQspi);
+	pQspi->QSPI_CR = QSPI_CR_QSPIEN;
+
+	while (!(pQspi->QSPI_SR & QSPI_SR_QSPIENS));
+}
+
+/**
+ * \brief Disables a QSPI peripheral.
+ *
+ * \param pQspi  Pointer to a Qspi instance.
+ */
+void QSPI_Disable(Qspi *pQspi)
+{
+	assert(pQspi);
+	pQspi->QSPI_CR = QSPI_CR_QSPIDIS;
+
+	while (pQspi->QSPI_SR & QSPI_SR_QSPIENS);
+}
+
+/**
+ * \brief Resets a QSPI peripheral.
+ *
+ * \param pQspi  Pointer to a Qspi instance.
+ */
+void QSPI_SwReset(Qspi *pQspi)
+{
+	assert(pQspi);
+	pQspi->QSPI_CR = QSPI_CR_SWRST;
+}
+
+/**
+ * \brief Enables one or more interrupt sources of a QSPI peripheral.
+ *
+ * \param pQspi  Pointer to a Qspi instance.
+ * \param sources Bitwise OR of selected interrupt sources.
+ */
+QspidStatus_t QSPI_EnableIt(Qspi *pQspi, uint32_t dwSources)
+{
+	assert(pQspi);
+	pQspi->QSPI_IER = dwSources;
+	return QSPI_SUCCESS;
+}
+
+/**
+ * \brief Disables one or more interrupt sources of a QSPI peripheral.
+ *
+ * \param pQspi  Pointer to a Qspi instance.
+ * \param sources Bitwise OR of selected interrupt sources.
+ */
+QspidStatus_t QSPI_DisableIt(Qspi *pQspi, uint32_t dwSources)
+{
+	assert(pQspi);
+	pQspi->QSPI_IDR = dwSources;
+	return QSPI_SUCCESS;
+}
+
+/**
+ * \brief Return the interrupt mask register.
+ *
+ * \return Qspi interrupt mask register.
+ */
+uint32_t QSPI_GetItMask(Qspi *pQspi)
+{
+	assert(pQspi);
+	return (pQspi->QSPI_IMR);
+}
+
+/**
+ * \brief Returns enabled interrupt status
+ *
+ * \return Qspi interrupt mask register.
+ */
+uint32_t QSPI_GetEnabledItStatus(Qspi *pQspi)
+{
+	assert(pQspi);
+	return (pQspi->QSPI_IMR & QSPI_GetStatus(pQspi, (QspiStatus_t)0xFFFFFFFF));
+}
+
+/**
+ * \brief Get the current status register of the given QSPI peripheral.
+ * \note This resets the internal value of the status register, so further
+ * read may yield different values.
+ * \param pQspi   Pointer to a Qspi instance.
+ * \param rStatus Compare status with given status bit
+ * \return  QSPI status register.
+ */
+uint32_t QSPI_GetStatus(Qspi *pQspi, const QspiStatus_t rStatus)
+{
+	assert(pQspi);
+	return (pQspi->QSPI_SR & rStatus);
+}
+
+/**
+ * \brief Configures peripheral clock of a QSPI/SPI peripheral.
+ *
+ * \param pQspi   Pointer to an Qspi instance.
+ * \param dwConfiguration  Desired clock configuration.
+ */
+void QSPI_ConfigureClock(Qspi *pQspi, QspiClockMode_t ClockMode,
+						  uint32_t dwClockCfg)
+{
+	assert(pQspi);
+	pQspi->QSPI_SCR = ClockMode;
+	pQspi->QSPI_SCR |= dwClockCfg;
+}
+
+/**
+ * \brief Configures QSPI/SPI
+ *
+ * \param pQspi             Pointer to an Qspi instance.
+ * \param Mode              Mode for QSPI or SPI
+ * \param dwConfiguration   Config of SPI or QSPI mode
+ */
+QspidStatus_t QSPI_ConfigureInterface(Qspid_t *pQspid, QspiMode_t Mode,
+									   uint32_t dwConfiguration)
+{
+	pQspid->pQspiHw = QSPI;
+	pQspid->qspiId = ID_QSPI;
+
+	QSPI_Disable(pQspid->pQspiHw);
+	QSPI_SwReset(pQspid->pQspiHw);
+
+	QSPI_ConfigureMode(pQspid->pQspiHw, Mode);
+	QSPI_Configure(pQspid->pQspiHw, dwConfiguration);
+
+	return QSPI_SUCCESS;
+}
+
+
+/**
+ * \brief Ends ongoing transfer by releasing CS of QSPI peripheral.
+ *
+ * \param pQspi  Pointer to an Qspi instance.
+ */
+QspidStatus_t QSPI_EndTransfer(Qspi *pQspi)
+{
+	assert(pQspi);
+
+	while (!QSPI_GetStatus(pQspi, IsTxEmpty));
+
+	pQspi->QSPI_CR = QSPI_CR_LASTXFER;
+
+	return QSPI_SUCCESS;
+}
+
+
+/*----------------------------------------------------------------------------
+ *        SPI functions
+ *----------------------------------------------------------------------------*/
+/**
+ * \brief Reads the data received by a SPI peripheral. This
+ * method must be called after a successful SPI_Write call.
+ *
+ * \param pQspid    Pointer to a Qspi instance.
+ * \param pData     Buffer to put read value
+ * \return Qspi status
+ */
+QspidStatus_t QSPI_SingleReadSPI(Qspid_t *pQspid, uint16_t *const pData)
+{
+	QspidStatus_t Status = QSPI_UNKNOWN_ERROR;
+	Qspi *pQspi = pQspid->pQspiHw;
+	uint32_t NumOfAttempt = 0;
+	uint16_t Dummy = 0xFF;
+
+	for (;;) {
+		if (QSPI_GetStatus(pQspi, IsReceived)) {
+			*pData = QSPI_ReadSPI(pQspi);
+			QSPI_WriteSPI(pQspi, Dummy);
+			*pData = QSPI_ReadSPI(pQspi);
+			NumOfAttempt = 0;
+			Status = QSPI_SUCCESS;
+		} else {
+			if (NumOfAttempt > 0xFFFF) {
+				Status = QSPI_READ_ERROR;
+				TRACE_ERROR(" SPI Read Error \n\r");
+				break;
+			} else {
+				Status = QSPI_READ_ERROR;
+				NumOfAttempt++;
+			}
+		}
+	}
+
+	return Status;
+}
+
+/**
+ * \brief Reads multiple data received by a SPI peripheral. This
+ * method must be called after a successful SPI_Write call.
+ *
+ * \param pQspid        Pointer to a Qspi instance.
+ * \param pData         Pointer to read buffer
+ * \param NumOfBytes    Num of bytes to read
+ *
+ * \return Qspi status
+ */
+QspidStatus_t QSPI_MultiReadSPI(Qspid_t *pQspid, uint16_t *const pData,
+								 uint32_t NumOfBytes)
+{
+	QspidStatus_t Status = QSPI_UNKNOWN_ERROR;
+	Qspi *pQspi = pQspid->pQspiHw;
+	uint32_t NumOfBytesRead = 0;
+	uint32_t NumOfAttempt = 0;
+	uint8_t *pwData = (uint8_t *)pData;
+	uint16_t Dummy = 0xFF;
+
+	/* Dummy read  and write to discard  first bytes recvd and start
+	    receiving new data*/
+	Dummy = QSPI_ReadSPI(pQspi);
+	QSPI_WriteSPI(pQspi, Dummy);
+
+	for (; NumOfBytesRead < NumOfBytes;) {
+		if (QSPI_GetStatus(pQspi, IsTxSent)) {
+			*pwData = QSPI_ReadSPI(pQspi);
+
+			if (pQspi->QSPI_MR & QSPI_MR_NBBITS_Msk)
+				pwData += sizeof(uint16_t);
+			else
+				pwData += sizeof(uint8_t);
+
+			NumOfBytesRead++;
+			NumOfAttempt = 0;
+			Status = QSPI_SUCCESS;
+			QSPI_WriteSPI(pQspi, Dummy);
+		} else {
+			if (NumOfAttempt > 0xFFFF) {
+				Status = QSPI_READ_ERROR;
+				TRACE_ERROR(" SPI MultiRead Error \n\r");
+				break;
+			} else {
+				Status = QSPI_READ_ERROR;
+				NumOfAttempt++;
+			}
+		}
+	}
+
+	return Status;
+}
+
+/**
+ * \brief Sends a single data through a SPI peripheral.
+ *
+ * \param pQspid    Pointer to a Qspi instance.
+ * \param pData     Pointer to Tx data
+ *
+ * \return Qspi status
+ */
+QspidStatus_t QSPI_SingleWriteSPI(Qspid_t *pQspid, uint16_t const *pData)
+{
+	QspidStatus_t Status = QSPI_UNKNOWN_ERROR;
+	Qspi *pQspi = pQspid->pQspiHw;
+	uint32_t NumOfAttempt = 0;
+
+	for (;;) {
+		if (QSPI_GetStatus(pQspi, IsTxSent)) {
+			QSPI_WriteSPI(pQspi, *pData);
+			NumOfAttempt = 0;
+			Status = QSPI_SUCCESS;
+			break;
+		} else {
+			Status = QSPI_BUSY_SENDING;
+			NumOfAttempt++;
+
+			if (NumOfAttempt > 0xFFFF) {
+				Status = QSPI_WRITE_ERROR;
+				TRACE_ERROR(" SPI Write Error \n\r");
+				break;
+			}
+		}
+	}
+
+	return Status;
+
+}
+
+/**
+ * \brief Sends multiple data through a SPI peripheral.
+ *
+ * \param pQspid        Pointer to a Qspi instance.
+ * \param pData         Pointer to a Tx buffer
+ * \param NumOfBytes    Num of data to send.
+ */
+QspidStatus_t QSPI_MultiWriteSPI(Qspid_t *pQspid, uint16_t const *pData,
+								  uint32_t NumOfBytes)
+{
+	QspidStatus_t Status = QSPI_UNKNOWN_ERROR;
+	Qspi *pQspi = pQspid->pQspiHw;
+	uint32_t NumOfBytesWrite = 0;
+	uint32_t NumOfAttempt = 0;
+	uint8_t *pwData = (uint8_t *)pData;
+	uint8_t Addr_Inc = 0;
+
+	if (pQspi->QSPI_MR & QSPI_MR_NBBITS_Msk)
+		Addr_Inc = sizeof(uint16_t);
+	else
+		Addr_Inc = sizeof(uint8_t);
+
+	for (; NumOfBytesWrite < NumOfBytes;) {
+		if (QSPI_GetStatus(pQspi, IsTxEmpty)) {
+			QSPI_WriteSPI(pQspi, (uint16_t)*pwData);
+			pwData += Addr_Inc;
+			NumOfBytesWrite++;
+			NumOfAttempt = 0;
+			Status = QSPI_SUCCESS;
+		} else {
+			Status = QSPI_BUSY_SENDING;
+			NumOfAttempt++;
+
+			if (NumOfAttempt > 0xFFFF) {
+				Status = QSPI_WRITE_ERROR;
+				TRACE_ERROR(" SPI Multi Write Error \n\r");
+				break;
+			}
+		}
+	}
+
+	return Status;
+
+}
+
+/*----------------------------------------------------------------------------
+ *        QSPI functions
+ *----------------------------------------------------------------------------*/
+
+/**
+ * \brief Send an instruction over QSPI (oly a flash command no data)
+ *
+ * \param pQspi     Pointer to an Qspi instance.
+ * \param KeepCfg   To keep Instruction fram value or restes to zero
+ *
+ * \return Returns 1 if At least one instruction end has been detected since
+ * the last read of QSPI_SR.; otherwise
+ * returns 0.
+ */
+QspidStatus_t QSPI_SendCommand(Qspid_t *pQspid, uint8_t const KeepCfg)
+{
+	QspiInstFrame_t  *const pFrame = pQspid->pQspiFrame;
+	QspiMemCmd_t  pCommand = pQspid->qspiCommand;
+	QspidStatus_t Status = QSPI_UNKNOWN_ERROR;
+	uint32_t timeout = 15000;
+
+	if (pFrame->InstFrame.bm.bAddrEn)
+		QSPI_SetInstAddr(pQspid->pQspiHw, pFrame->Addr);
+
+	QSPI_SetInst(pQspid->pQspiHw, (pCommand.Instruction & 0xFF),
+				 ((pCommand.Option >> QSPI_ICR_OPT_Pos) & 0xFF));
+	QSPI_SetInstFrame(pQspid->pQspiHw, pFrame);
+
+	memory_sync();
+
+	/*
+	 * FIXME: Timeout has been introduced due to a problem that was detected
+	 * when QSPI_SR_INSTRE was not detected and the function is stuck in an
+	 * endless loop. This is still an open issue.
+	 * peripheral clock: 50Mhz -> 20 ns period time.
+	 * timeout: set to 15000 loop cycles => 300000 ns.
+	 * with loop instructions, the delay increases to 1ms altogether.
+	 */
+	while (!(pQspid->pQspiHw->QSPI_SR & QSPI_SR_INSTRE) && timeout > 0) {
+		--timeout;
+	}
+
+	if (timeout == 0) {
+		Status = QSPI_WRITE_ERROR;
+	}
+
+	// poll CR reg to know status if instruction has end
+	if (!KeepCfg)
+		pFrame->InstFrame.val = 0;
+
+	return Status;
+}
+
+
+
+/**
+ * \brief Send instruction over QSPI with data
+ *
+ * \param pQspi     Pointer to an Qspi instance.
+ * \param KeepCfg   To keep Instruction fram value or restes to zero
+ *
+ * \return Returns 1 if At least one instruction end has been detected
+ *  since the last read of QSPI_SR.; otherwise returns 0.
+ */
+QspidStatus_t QSPI_SendCommandWithData(Qspid_t *pQspid, uint8_t const KeepCfg)
+{
+	QspiInstFrame_t *const  pFrame = pQspid->pQspiFrame;
+	QspiMemCmd_t  pCommand = pQspid->qspiCommand;
+	QspiBuffer_t    pBuffer     =  pQspid->qspiBuffer;
+	uint32_t *pQspiBuffer = (uint32_t *)QSPIMEM_ADDR;
+	QspidStatus_t Status = QSPI_UNKNOWN_ERROR;
+
+	//assert(pBuffer.pDataRx);
+	assert(pBuffer.pDataTx);
+
+	QSPI_SetInst(pQspid->pQspiHw, (pCommand.Instruction & 0xFF),
+				 (pCommand.Option & 0xFF));
+	QSPI_SetInstFrame(pQspid->pQspiHw, pFrame);
+
+	QSPI_GetInstFrame(pQspid->pQspiHw);
+
+	// to synchronize system bus accesses
+	if (!KeepCfg)
+		pFrame->InstFrame.val = 0;
+
+	memcpy(pQspiBuffer  , pBuffer.pDataTx ,  pBuffer.TxDataSize);
+	memory_sync();
+	QSPI_EndTransfer(pQspid->pQspiHw);
+
+	// End transmission after all data has been sent
+	while (!(pQspid->pQspiHw->QSPI_SR & QSPI_SR_INSTRE));
+
+	// poll CR reg to know status if instruction has end
+
+	return Status;
+}
+
+/**
+ * \brief Send instruction over QSPI to read data
+ *
+ * \param pQspi     Pointer to an Qspi instance.
+ * \param KeepCfg   To keep Instruction from value or resets to zero
+ *
+ * \return Returns 1 if At least one instruction end has been detected
+ * since the last read of QSPI_SR.; otherwise returns 0.
+ */
+QspidStatus_t QSPI_ReadCommand(Qspid_t *pQspid, uint8_t const KeepCfg)
+{
+	QspiInstFrame_t *const  pFrame = pQspid->pQspiFrame;
+	QspiMemCmd_t  pCommand = pQspid->qspiCommand;
+	QspiBuffer_t    pBuffer     =  pQspid->qspiBuffer;
+	uint32_t *pQspiBuffer = (uint32_t *)QSPIMEM_ADDR;
+	QspidStatus_t Status = QSPI_UNKNOWN_ERROR;
+
+	assert(pBuffer.pDataRx);
+
+	QSPI_SetInst(pQspid->pQspiHw, (pCommand.Instruction & 0xFF),
+				 (pCommand.Option & 0xFF));
+	QSPI_SetInstFrame(pQspid->pQspiHw, pFrame);
+
+	QSPI_GetInstFrame(pQspid->pQspiHw);
+
+	// to synchronize system bus accesses
+	if (!KeepCfg)
+		pFrame->InstFrame.val = 0;
+
+	memcpy(pBuffer.pDataRx , pQspiBuffer,  pBuffer.RxDataSize);
+	memory_sync();
+	QSPI_EndTransfer(pQspid->pQspiHw);
+
+	// End transmission after all data has been sent
+	while (!(pQspid->pQspiHw->QSPI_SR & QSPI_SR_INSTRE));
+
+	// poll CR reg to know status if instruction has end
+
+	return Status;
+}
+
+/**
+ * \brief Sends an instruction over QSPI and configures other related address
+*  like Addr , Frame and synchronise bus access before data read or write
+ *
+ * \param pQspi         Pointer to an Qspi instance.
+ * \param KeepCfg       To keep Instruction from value or resets to zero
+ * \param ScrambleFlag  Enable or disable scramble on QSPI
+ *
+ * \return Returns 1 if At least one instruction end has been detected since
+ * the last read of QSPI_SR.; otherwise returns 0.
+ */
+QspidStatus_t QSPI_EnableMemAccess(Qspid_t *pQspid, uint8_t const KeepCfg,
+									uint8_t ScrambleFlag)
+{
+	QspiInstFrame_t *const pFrame = pQspid->pQspiFrame;
+	QspiMemCmd_t  pCommand = pQspid->qspiCommand;
+
+	QspidStatus_t Status = QSPI_UNKNOWN_ERROR;
+
+	QSPI_SetInst(pQspid->pQspiHw, (pCommand.Instruction & 0xFF),
+				 (pCommand.Option & 0xFF));
+
+	if (ScrambleFlag)
+		QSPI_ScrambleData(pQspid->pQspiHw, SCRAMBLE_KEY, ScrambleFlag, 1);
+
+	QSPI_SetInstFrame(pQspid->pQspiHw, pFrame);
+
+	QSPI_GetInstFrame(pQspid->pQspiHw);
+
+	// to synchronize system bus accesses
+	if (!KeepCfg)
+		pFrame->InstFrame.val = 0;
+
+	Status = QSPI_SUCCESS;
+	return Status;
+}
+
+/**
+ * \brief Writes or reads the QSPI memory (0x80000000) to transmit or
+ * receive data from Flash memory
+ * \param pQspi         Pointer to an Qspi instance.
+ * \param ReadWrite     Flag to indicate read/write QSPI memory access
+ *
+ * \return Returns 1 if At least one instruction end has been detected since
+ * the last read of QSPI_SR.; otherwise returns 0.
+ */
+QspidStatus_t QSPI_ReadWriteMem(Qspid_t *pQspid, Access_t const ReadWrite)
+{
+	QspidStatus_t Status = QSPI_UNKNOWN_ERROR;
+	QspiInstFrame_t *const pFrame = pQspid->pQspiFrame;
+	void *pQspiMem = (void *)(QSPIMEM_ADDR | pFrame->Addr);
+	QspiBuffer_t    pBuffer     =  pQspid->qspiBuffer;
+
+	assert(((ReadWrite > CmdAccess)
+			  && (ReadWrite <= WriteAccess)) ? true : false);
+
+	if (ReadWrite == WriteAccess) {
+		atsam_copy_to_io(pQspiMem, pBuffer.pDataTx ,
+		    pBuffer.TxDataSize);
+	} else {
+		atsam_copy_from_io(pBuffer.pDataRx, pQspiMem,
+		    pBuffer.RxDataSize);
+	}
+	memory_sync();
+	QSPI_EndTransfer(pQspid->pQspiHw);
+
+	// End transmission after all data has been sent
+	while (!(pQspid->pQspiHw->QSPI_SR & QSPI_SR_INSTRE));
+
+	// poll CR reg to know status if instruction has end
+
+	Status = QSPI_SUCCESS;
+	return Status;
+}
Index: bsps/arm/atsam/contrib/libraries/libchip/source/qspi_dma.c
===================================================================
--- bsps/arm/atsam/contrib/libraries/libchip/source/qspi_dma.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libchip/source/qspi_dma.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,619 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+/**
+ * \addtogroup qspi_dma_module QSPI xDMA driver
+ * \ingroup peripherals_module
+ *
+ *
+ */
+
+/**
+ * \file
+ *
+ * Implementation for the SPI Flash with xDMA driver.
+ *
+ */
+
+
+/*----------------------------------------------------------------------------
+ *        Headers
+ *----------------------------------------------------------------------------*/
+
+#include "chip.h"
+#ifdef __rtems__
+#include "../../../utils/utility.h"
+#endif /* __rtems__ */
+
+/*----------------------------------------------------------------------------
+ *        Definitions
+ *----------------------------------------------------------------------------*/
+
+/** xDMA support */
+
+/** xDMA Link List size for SPI transmission*/
+#define DMA_QSPI_LLI     2
+
+/*-----------------------------------------------------------------------------
+ *        QSPI DMA Local functions
+ *----------------------------------------------------------------------------*/
+
+/**
+ * \brief SPI xDMA Rx callback
+ * Invoked on SPi DMA reception done.
+ * \param channel DMA channel.
+ * \param pArg Pointer to callback argument - Pointer to Spid instance.
+ */
+static void QSPID_Spi_Cb(uint32_t channel, QspiDma_t *pArg)
+{
+	Qspi *pQspiHw = pArg->Qspid.pQspiHw;
+
+	if (channel != pArg->RxChNum)
+		return;
+
+	/* Release the semaphore */
+	ReleaseMutex(pArg->progress);
+	QSPI_EndTransfer(pQspiHw);
+	SCB_InvalidateDCache_by_Addr((uint32_t *)pArg->Qspid.qspiBuffer.pDataRx,
+								 pArg->Qspid.qspiBuffer.RxDataSize);
+	memory_sync();
+}
+
+
+/**
+ * \brief QSPI xDMA Tx callback
+ * Invoked on QSPi DMA Write done.
+ * \param channel DMA channel.
+ * \param pArg Pointer to callback argument - Pointer to Spid instance.
+ */
+static void QSPID_qspiTx_Cb(uint32_t channel, QspiDma_t *pArg)
+{
+	Qspi *pQspiHw = pArg->Qspid.pQspiHw;
+
+	if (channel != pArg->TxChNum)
+		return;
+
+	/* Release the semaphore */
+	ReleaseMutex(pArg->progress);
+	QSPI_EndTransfer(pQspiHw);
+
+	while (!QSPI_GetStatus(pArg->Qspid.pQspiHw, IsEofInst));
+
+	memory_sync();
+}
+
+
+/**
+ * \brief QSPI xDMA Rx callback
+ * Invoked on SPi DMA reception done.
+ * \param channel DMA channel.
+ * \param pArg Pointer to callback argument - Pointer to Spid instance.
+ */
+static void QSPID_qspiRx_Cb(uint32_t channel, QspiDma_t *pArg)
+{
+	Qspi *pQspiHw = pArg->Qspid.pQspiHw;
+
+	if (channel != pArg->RxChNum)
+		return;
+
+	/* Release the semaphore */
+	ReleaseMutex(pArg->progress);
+	QSPI_EndTransfer(pQspiHw);
+
+	while (!QSPI_GetStatus(pArg->Qspid.pQspiHw, IsEofInst));
+
+	SCB_InvalidateDCache_by_Addr((uint32_t *)pArg->Qspid.qspiBuffer.pDataRx,
+								 pArg->Qspid.qspiBuffer.RxDataSize);
+	memory_sync();
+}
+
+/**
+ * \brief Configures the DMA for QSPI
+ *
+ * \param pQspidma  Pointer to QSPI DMA structure
+ * \param Addr      Address to Read or write of QSPI flash memory
+ * \param pBuffer   Pointer input/output buffer
+ * \param ReadWrite Read or write memory flag
+ * \returns 0 if the dma multibuffer configuration successfully; otherwise returns
+ * QSPID_ERROR_XXX.
+ */
+static uint8_t QSPID_configureQpsiDma(QspiDma_t *pQspidma, uint32_t Addr,
+									  QspiBuffer_t *pBuffer, Access_t const ReadWrite)
+{
+	sXdmadCfg xdmadCfg, xdmadRxCfg, xdmadTxCfg;
+	uint8_t chanNum;
+	uint8_t qspi_id =  pQspidma->Qspid.qspiId;
+	Qspi *pQspiHw = pQspidma->Qspid.pQspiHw;
+	uint32_t xdmaCndc, xdmaInt, BurstSize, ChannelWidth;
+
+
+	/* Setup DMA  for QSPI */
+
+	if (pQspidma->Qspid.qspiMode == QSPI_MR_SMM_SPI) {
+		// SPI mode
+		/* SPI TX DMA config */
+		xdmadTxCfg.mbr_sa   =   (uint32_t)pBuffer->pDataTx;
+		xdmadTxCfg.mbr_da   =   (uint32_t)&pQspiHw->QSPI_TDR;
+		xdmadTxCfg.mbr_ubc  =   (pBuffer->TxDataSize);
+
+		xdmadTxCfg.mbr_cfg =  XDMAC_CC_TYPE_PER_TRAN |
+							  XDMAC_CC_MBSIZE_SINGLE |
+							  XDMAC_CC_DSYNC_MEM2PER |
+							  XDMAC_CC_CSIZE_CHK_1 |
+							  XDMAC_CC_DWIDTH_BYTE |
+							  XDMAC_CC_SIF_AHB_IF0 |
+							  XDMAC_CC_DIF_AHB_IF1 |
+							  XDMAC_CC_SAM_INCREMENTED_AM |
+							  XDMAC_CC_DAM_FIXED_AM |
+							  XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber
+											 (qspi_id, XDMAD_TRANSFER_TX));
+
+		xdmadTxCfg.mbr_bc = 0;
+		xdmadTxCfg.mbr_sus = 0;
+		xdmadTxCfg.mbr_dus = 0;
+
+		/* SPI RX DMA config */
+
+		xdmadRxCfg.mbr_da  =  (uint32_t)pBuffer->pDataRx;
+		xdmadRxCfg.mbr_sa  =  (uint32_t)&pQspiHw->QSPI_RDR;
+		xdmadRxCfg.mbr_ubc =   (pBuffer->RxDataSize);
+		xdmadRxCfg.mbr_cfg =    XDMAC_CC_TYPE_PER_TRAN |
+								XDMAC_CC_MBSIZE_SINGLE |
+								XDMAC_CC_DSYNC_PER2MEM |
+								XDMAC_CC_CSIZE_CHK_1 |
+								XDMAC_CC_DWIDTH_BYTE |
+								XDMAC_CC_SIF_AHB_IF1 |
+								XDMAC_CC_DIF_AHB_IF0 |
+								XDMAC_CC_SAM_FIXED_AM |
+								XDMAC_CC_DAM_INCREMENTED_AM |
+								XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber
+											   (qspi_id, XDMAD_TRANSFER_RX));
+
+		xdmadRxCfg.mbr_bc = 0;
+		xdmadRxCfg.mbr_sus = 0;
+		xdmadRxCfg.mbr_dus = 0;
+		xdmaCndc = 0;
+		/* Put all interrupts on for non LLI list setup of DMA */
+		xdmaInt =  (XDMAC_CIE_BIE   |
+					XDMAC_CIE_RBIE  |
+					XDMAC_CIE_WBIE  |
+					XDMAC_CIE_ROIE);
+
+		memory_barrier();
+
+		if (XDMAD_ConfigureTransfer
+			(pQspidma->pXdmad, pQspidma->RxChNum, &xdmadRxCfg, xdmaCndc, 0, xdmaInt))
+			return QSPID_ERROR;
+
+		if (XDMAD_ConfigureTransfer
+			(pQspidma->pXdmad, pQspidma->TxChNum, &xdmadTxCfg, xdmaCndc, 0, xdmaInt))
+			return QSPID_ERROR;
+
+		return 0;
+
+	} else {
+		if (ReadWrite == WriteAccess) {
+			xdmadCfg.mbr_sa = (uint32_t)pBuffer->pDataTx;
+			xdmadCfg.mbr_da = (uint32_t)(QSPIMEM_ADDR | Addr);
+			xdmadCfg.mbr_ubc =  (pBuffer->TxDataSize);
+			chanNum =  pQspidma->TxChNum;
+			ChannelWidth = XDMAC_CC_DWIDTH_BYTE;
+			BurstSize = XDMAC_CC_MBSIZE_SIXTEEN;
+		} else if (ReadWrite == ReadAccess) {
+			xdmadCfg.mbr_da = (uint32_t)pBuffer->pDataRx;
+			xdmadCfg.mbr_sa = (uint32_t)(QSPIMEM_ADDR | Addr);
+			xdmadCfg.mbr_ubc =  ((pBuffer->RxDataSize >> 2));
+			chanNum =  pQspidma->RxChNum;
+			ChannelWidth = XDMAC_CC_DWIDTH_WORD;
+			BurstSize = XDMAC_CC_MBSIZE_SIXTEEN;
+		} else {
+			TRACE_ERROR(" QSPI error \n\r");
+			return 1;
+		}
+
+		xdmadCfg.mbr_cfg = XDMAC_CC_TYPE_MEM_TRAN |
+						   XDMAC_CC_MEMSET_NORMAL_MODE |
+						   BurstSize |
+						   ChannelWidth |
+						   XDMAC_CC_SIF_AHB_IF1 |
+						   XDMAC_CC_DIF_AHB_IF1 |
+						   XDMAC_CC_SAM_INCREMENTED_AM |
+						   XDMAC_CC_DAM_INCREMENTED_AM;
+
+		xdmadCfg.mbr_bc = 0;
+		xdmadCfg.mbr_sus = 0;
+		xdmadCfg.mbr_dus = 0;
+
+		xdmaCndc = 0;
+
+
+		/* Put all interrupts on for non LLI list setup of DMA */
+		xdmaInt =  (XDMAC_CIE_BIE   |
+					XDMAC_CIE_RBIE  |
+					XDMAC_CIE_WBIE  |
+					XDMAC_CIE_ROIE);
+
+		memory_barrier();
+
+		if (XDMAD_ConfigureTransfer(pQspidma->pXdmad, chanNum, &xdmadCfg, xdmaCndc, 0,
+									 xdmaInt))
+			return QSPID_ERROR;
+
+		return 0;
+	}
+}
+
+/*----------------------------------------------------------------------------
+ *        Exported functions
+ *----------------------------------------------------------------------------*/
+/**
+ * \brief Initializes the pQspidma structure and the corresponding QSPI & DMA .
+ * hardware select value.
+ *
+ * \param pQspidma  Pointer to a QspiDma_t instance.
+ * \param Mode      Associated SPI peripheral.
+ * \param dwConf    QSPI peripheral configuration.
+ * \param pXdmad    Pointer to a Xdmad instance.
+ */
+uint32_t QSPID_Configure(QspiDma_t *pQspidma, QspiMode_t Mode,
+						  uint32_t dwConf, sXdmad *pXdmad)
+{
+	/* Initialize the QSPI structure */
+
+	QSPI_ConfigureInterface(&pQspidma->Qspid, Mode, dwConf);
+
+	pQspidma->Qspid.qspiCommand.Instruction = 0;
+	pQspidma->Qspid.qspiCommand.Option = 0;
+
+	pQspidma->RxChNum = QSPID_CH_NOT_ENABLED;
+	pQspidma->TxChNum = QSPID_CH_NOT_ENABLED;
+
+	assert(pXdmad == &XDMAD_Instance);
+	pQspidma->pXdmad = pXdmad;
+
+	return QSPI_SUCCESS;
+}
+
+
+
+/**
+ * \brief Enables a QSPI Rx channel. This function will allocate a dma Rx
+ *  channel for QSPI
+ *
+ * \param pQspidma  Pointer to a Spid instance.
+
+ * \returns 0 if the transfer has been started successfully; otherwise returns
+ * QSPID_ERROR_LOCK is the driver is in use, or QSPID_ERROR if the command is not
+ * valid.
+ */
+uint32_t QSPID_EnableQspiRxChannel(QspiDma_t *pQspidma)
+{
+	static uint16_t DmaChannel;
+
+	/* Try to get the semaphore */
+	if (pQspidma->RxChNum != QSPID_CH_NOT_ENABLED)
+		return QSPID_ERROR_LOCK;
+
+	/* Allocate a DMA channel */
+	DmaChannel = XDMAD_AllocateChannel(
+					 pQspidma->pXdmad, XDMAD_TRANSFER_MEMORY, XDMAD_TRANSFER_MEMORY);
+
+	if (DmaChannel == XDMAD_ALLOC_FAILED)
+		return QSPID_ERROR;
+
+	pQspidma->RxChNum = DmaChannel;
+	/* Setup callbacks*/
+	XDMAD_SetCallback(pQspidma->pXdmad, pQspidma->RxChNum,
+					  (XdmadTransferCallback)QSPID_qspiRx_Cb, pQspidma);
+
+	if (XDMAD_PrepareChannel(pQspidma->pXdmad, pQspidma->RxChNum))
+		return QSPID_ERROR;
+
+	return 0;
+}
+
+
+/**
+ * \brief Enables a QSPI Tx channel. This function will allocate a dma Tx
+ * channel for QSPI
+ *
+ * \param pQspidma  Pointer to a Spid instance.
+
+ * \returns 0 if the transfer has been started successfully; otherwise returns
+ * QSPID_ERROR_LOCK is the driver is in use, or QSPID_ERROR if the command is
+ * not valid.
+ */
+uint32_t QSPID_EnableQspiTxChannel(QspiDma_t *pQspidma)
+{
+	static uint16_t DmaChannel;
+
+	/* Try to get the  semaphore */
+	if (pQspidma->TxChNum != QSPID_CH_NOT_ENABLED)
+		return QSPID_ERROR_LOCK;
+
+	/* Allocate a DMA channel */
+	DmaChannel = XDMAD_AllocateChannel(pQspidma->pXdmad,
+										XDMAD_TRANSFER_MEMORY, XDMAD_TRANSFER_MEMORY);
+
+	if (DmaChannel == XDMAD_ALLOC_FAILED)
+		return QSPID_ERROR;
+
+	pQspidma->TxChNum = DmaChannel;
+	/* Setup callbacks  */
+	XDMAD_SetCallback(pQspidma->pXdmad, pQspidma->TxChNum,
+					  (XdmadTransferCallback)QSPID_qspiTx_Cb, pQspidma);
+
+	if (XDMAD_PrepareChannel(pQspidma->pXdmad, pQspidma->TxChNum))
+		return QSPID_ERROR;
+
+	return 0;
+}
+
+
+/**
+ * \brief Enables a QSPI SPI Rx channel. This function will allocate a dma
+ *  Rx channel for QSPI SPI mode
+ *
+ * \param pQspidma  Pointer to a Spid instance.
+
+ * \returns 0 if the transfer has been started successfully; otherwise returns
+ * QSPID_ERROR_LOCK is the driver is in use, or QSPID_ERROR if the command is
+ * not valid.
+ */
+uint32_t QSPID_EnableSpiChannel(QspiDma_t *pQspidma)
+{
+	static uint16_t DmaChannel;
+
+	/* Try to get the semaphore */
+	if (pQspidma->RxChNum != QSPID_CH_NOT_ENABLED)
+		return QSPID_ERROR_LOCK;
+
+	/* Try to get the  semaphore */
+	if (pQspidma->TxChNum != QSPID_CH_NOT_ENABLED)
+		return QSPID_ERROR_LOCK;
+
+	/* Allocate a DMA channel */
+	DmaChannel = XDMAD_AllocateChannel
+				 (pQspidma->pXdmad, pQspidma->Qspid.qspiId, XDMAD_TRANSFER_MEMORY);
+
+	if (DmaChannel == XDMAD_ALLOC_FAILED)
+		return QSPID_ERROR;
+
+	pQspidma->RxChNum = DmaChannel;
+
+	/* Allocate a DMA channel */
+	DmaChannel = XDMAD_AllocateChannel(pQspidma->pXdmad,
+										XDMAD_TRANSFER_MEMORY, pQspidma->Qspid.qspiId);
+
+	if (DmaChannel == XDMAD_ALLOC_FAILED)
+		return QSPID_ERROR;
+
+	pQspidma->TxChNum = DmaChannel;
+
+	/* Setup callbacks*/
+	XDMAD_SetCallback(pQspidma->pXdmad, pQspidma->RxChNum,
+					  (XdmadTransferCallback)QSPID_Spi_Cb, pQspidma);
+
+	if (XDMAD_PrepareChannel(pQspidma->pXdmad, pQspidma->RxChNum))
+		return QSPID_ERROR;
+
+	/* Setup callbacks for SPI0/1 TX (ignored) */
+	XDMAD_SetCallback(pQspidma->pXdmad, pQspidma->TxChNum, NULL, NULL);
+
+	if (XDMAD_PrepareChannel(pQspidma->pXdmad, pQspidma->TxChNum))
+		return QSPID_ERROR;
+
+	return 0;
+}
+
+
+/**
+ * \brief Disables a QSPI Rx channel. This function will de-allocate previous
+ *  allocated dma Rx channel for QSPI
+ *
+ * \param pQspidma  Pointer to a Spid instance.
+
+ * \returns 0 if the transfer has been started successfully; otherwise returns
+ * QSPID_ERROR_LOCK is the driver is in use, or QSPID_ERROR if the command is
+ * not valid.
+ */
+uint32_t QSPID_DisableQspiRxChannel(QspiDma_t *pQspidma)
+{
+
+	XDMAC_SoftwareFlushReq(pQspidma->pXdmad->pXdmacs, pQspidma->RxChNum);
+	XDMAD_StopTransfer(pQspidma->pXdmad, pQspidma->RxChNum);
+
+	XDMAD_SetCallback(pQspidma->pXdmad, pQspidma->RxChNum, NULL, NULL);
+
+
+	/* Free allocated DMA channel for QSPI RX. */
+	XDMAD_FreeChannel(pQspidma->pXdmad, pQspidma->RxChNum);
+
+	pQspidma->RxChNum = QSPID_CH_NOT_ENABLED;
+
+	return 0;
+}
+
+
+
+/**
+ * \brief Disables a QSPI Tx channel. This function will de-allocate previous
+ * allocated dma Tx channel for QSPI
+ *
+ * \param pQspidma  Pointer to a Spid instance.
+
+ * \returns 0 if the transfer has been started successfully; otherwise returns
+ * QSPID_ERROR_LOCK is the driver is in use, or QSPID_ERROR if the command is
+ * not valid.
+ */
+uint32_t QSPID_DisableQspiTxChannel(QspiDma_t *pQspidma)
+{
+
+	XDMAC_SoftwareFlushReq(pQspidma->pXdmad->pXdmacs, pQspidma->TxChNum);
+	XDMAD_StopTransfer(pQspidma->pXdmad, pQspidma->TxChNum);
+
+	XDMAD_SetCallback(pQspidma->pXdmad, pQspidma->TxChNum, NULL, NULL);
+
+	/* Free allocated DMA channel for QSPI TX. */
+	XDMAD_FreeChannel(pQspidma->pXdmad, pQspidma->TxChNum);
+
+	pQspidma->TxChNum = QSPID_CH_NOT_ENABLED;
+
+	return 0;
+}
+
+
+/**
+ * \brief Disables a QSPI SPI Rx and Tx channels. This function will
+ *  de-allocate privious allocated dma Rx, Txchannel for QSPI in SPI mode
+ *
+ * \param pQspidma  Pointer to a Spid instance.
+
+ * \returns 0 if the transfer has been started successfully; otherwise returns
+ * QSPID_ERROR_LOCK is the driver is in use, or QSPID_ERROR if the command is
+ * not valid.
+ */
+uint32_t QSPID_DisableSpiChannel(QspiDma_t *pQspidma)
+{
+
+	XDMAC_SoftwareFlushReq(pQspidma->pXdmad->pXdmacs, pQspidma->RxChNum);
+	//XDMAC_SoftwareFlushReq(pQspidma->pXdmad->pXdmacs, pQspidma->TxChNum);
+	XDMAD_StopTransfer(pQspidma->pXdmad, pQspidma->RxChNum);
+	XDMAD_StopTransfer(pQspidma->pXdmad, pQspidma->TxChNum);
+
+	XDMAD_SetCallback(pQspidma->pXdmad, pQspidma->RxChNum, NULL, NULL);
+
+	/* Free allocated DMA channel for QSPI RX. */
+	XDMAD_FreeChannel(pQspidma->pXdmad, pQspidma->RxChNum);
+
+	XDMAD_FreeChannel(pQspidma->pXdmad, pQspidma->TxChNum);
+
+	pQspidma->RxChNum = QSPID_CH_NOT_ENABLED;
+	pQspidma->TxChNum = QSPID_CH_NOT_ENABLED;
+
+	return 0;
+}
+
+
+/**
+ * \brief Starts a QSPI read or write operation.
+ *
+ * \param pQspidma  Pointer to a Qspid instance.
+ * \param ReadWrite Defines the memory access type
+ * \returns 0 if the transfer has been started successfully; otherwise returns
+ * QSPID_ERROR_LOCK is the driver is in use, or QSPID_ERROR if the command is
+ * not valid.
+ */
+uint32_t QSPID_ReadWriteQSPI(QspiDma_t *pQspidma, Access_t const ReadWrite)
+{
+	QspiBuffer_t *pBuffer = &pQspidma->Qspid.qspiBuffer;
+	uint8_t chanNum;
+	uint32_t semTimer = 0x7FF;
+
+	//assert(pBuffer->pDataTx);
+
+	if (pQspidma->progress)
+		return QSPID_ERROR_LOCK;
+
+	LockMutex(pQspidma->progress, semTimer);
+
+	if (QSPID_configureQpsiDma
+		(pQspidma, pQspidma->Qspid.pQspiFrame->Addr, pBuffer, ReadWrite))
+		return QSPID_ERROR_LOCK;
+
+	if (ReadWrite == WriteAccess) {
+		chanNum =  pQspidma->TxChNum;
+		SCB_CleanDCache_by_Addr((uint32_t *)pBuffer->pDataTx, pBuffer->TxDataSize);
+	} else {
+		if (ReadWrite != ReadAccess)
+			TRACE_ERROR("%s QSPI Access Error\n\r", __FUNCTION__);
+		chanNum =  pQspidma->RxChNum;
+	}
+
+	/* Start DMA 0(RX) && 1(TX) */
+	if (XDMAD_StartTransfer(pQspidma->pXdmad, chanNum))
+		return QSPID_ERROR_LOCK;
+
+	return 0;
+}
+
+/**
+ * \brief Starts a SPI master transfer. This is a non blocking function. It will
+ *  return as soon as the transfer is started.
+ *
+ * \param pSpid  Pointer to a Spid instance.
+ * \param pCommand Pointer to the SPI command to execute.
+ * \returns 0 if the transfer has been started successfully; otherwise returns
+ * SPID_ERROR_LOCK is the driver is in use, or SPID_ERROR if the command is not
+ * valid.
+ */
+uint32_t QSPID_ReadWriteSPI(QspiDma_t *pQspidma, Access_t const ReadWrite)
+{
+	QspiBuffer_t *pBuffer = &pQspidma->Qspid.qspiBuffer;
+	uint32_t semTimer = 0x7FF;
+
+	assert(pBuffer->pDataRx);
+	assert(pBuffer->pDataTx);
+
+	/* Try to get the dataflash semaphore */
+	if (pQspidma->progress)
+
+		return QSPID_ERROR_LOCK;
+
+	LockMutex(pQspidma->progress, semTimer);
+
+	if (QSPID_configureQpsiDma
+		(pQspidma, pQspidma->Qspid.pQspiFrame->Addr, pBuffer, ReadWrite))
+		return QSPID_ERROR_LOCK;
+
+	SCB_CleanDCache_by_Addr((uint32_t *)pBuffer->pDataTx, pBuffer->TxDataSize);
+
+	/* Start DMA 0(RX) && 1(TX) */
+	if (XDMAD_StartTransfer(pQspidma->pXdmad, pQspidma->RxChNum))
+		return QSPID_ERROR_LOCK;
+
+	if (XDMAD_StartTransfer(pQspidma->pXdmad, pQspidma->TxChNum))
+		return QSPID_ERROR_LOCK;
+
+	return 0;
+}
+
+/**
+ * \brief Check if the QSPI driver is busy.
+ *
+ * \param pSpid  Pointer to a Spid instance.
+ * \returns 1 if the SPI driver is currently busy executing a command; otherwise
+ */
+uint32_t QSPID_IsBusy(volatile uint8_t *QspiSemaphore)
+{
+	if (Is_LockFree(QspiSemaphore))
+		return 1;
+	else
+		return 0;
+}
Index: bsps/arm/atsam/contrib/libraries/libchip/source/rstc.c
===================================================================
--- bsps/arm/atsam/contrib/libraries/libchip/source/rstc.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libchip/source/rstc.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,167 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+/** \file */
+/*---------------------------------------------------------------------------
+ *         Headers
+ *---------------------------------------------------------------------------*/
+
+#include <chip.h>
+
+
+/*---------------------------------------------------------------------------
+ *         Exported functions
+ *---------------------------------------------------------------------------*/
+
+/**
+ * Configure the mode of the RSTC peripheral.
+ * The configuration is computed by the lib (RSTC_RMR_*).
+ * \param mr Desired mode configuration.
+ */
+void RSTC_ConfigureMode(uint32_t mr)
+{
+	Rstc *pHw = RSTC;
+	mr &= ~RSTC_MR_KEY_Msk;
+	pHw->RSTC_MR = mr | RSTC_MR_KEY_PASSWD;
+}
+
+/**
+ * Enable/Disable the detection of a low level on the pin NRST as User Reset
+ * \param enable 1 to enable & 0 to disable.
+ */
+void RSTC_SetUserResetEnable(uint8_t enable)
+{
+	Rstc *pHw = RSTC;
+	uint32_t mr = pHw->RSTC_MR & (~RSTC_MR_KEY_Msk);
+
+	if (enable)
+		mr |=  RSTC_MR_URSTEN;
+	else
+		mr &= ~RSTC_MR_URSTEN;
+
+	pHw->RSTC_MR = mr | RSTC_MR_KEY_PASSWD;
+}
+
+/**
+ * Enable/Disable the interrupt of a User Reset (USRTS bit in RSTC_RST).
+ * \param enable 1 to enable & 0 to disable.
+ */
+void RSTC_SetUserResetInterruptEnable(uint8_t enable)
+{
+	Rstc *pHw = RSTC;
+	uint32_t mr = pHw->RSTC_MR & (~RSTC_MR_KEY_Msk);
+
+	if (enable)
+		mr |=  RSTC_MR_URSTIEN;
+	else
+		mr &= ~RSTC_MR_URSTIEN;
+
+	pHw->RSTC_MR = mr | RSTC_MR_KEY_PASSWD;
+}
+
+/**
+ * Setup the external reset length. The length is asserted during a time of
+ * pow(2, powl+1) Slow Clock(32KHz). The duration is between 60us and 2s.
+ * \param powl   Power length defined.
+ */
+void RSTC_SetExtResetLength(uint8_t powl)
+{
+	Rstc *pHw = RSTC;
+	uint32_t mr = pHw->RSTC_MR;
+	mr &= ~(RSTC_MR_KEY_Msk | RSTC_MR_ERSTL_Msk);
+	mr |=  RSTC_MR_ERSTL(powl);
+	pHw->RSTC_MR = mr | RSTC_MR_KEY_PASSWD;
+}
+
+
+/**
+ * Resets the processor.
+ */
+void RSTC_ProcessorReset(void)
+{
+	Rstc *pHw = RSTC;
+	pHw->RSTC_CR = RSTC_CR_PROCRST | RSTC_CR_KEY_PASSWD;
+}
+
+
+/**
+ * Asserts the NRST pin for external resets.
+ */
+void RSTC_ExtReset(void)
+{
+	Rstc *pHw = RSTC;
+	pHw->RSTC_CR = RSTC_CR_EXTRST | RSTC_CR_KEY_PASSWD;
+}
+
+/**
+ * Return NRST pin level (1 or 0).
+ */
+uint8_t RSTC_GetNrstLevel(void)
+{
+	Rstc *pHw = RSTC;
+	return ((pHw->RSTC_SR & RSTC_SR_NRSTL) > 0);
+}
+
+/**
+ * Returns 1 if at least one high-to-low transition of NRST (User Reset) has
+ * been detected since the last read of RSTC_RSR.
+ */
+uint8_t RSTC_IsUserResetDetected(void)
+{
+	Rstc *pHw = RSTC;
+
+	if (pHw->RSTC_SR & RSTC_SR_URSTS)
+		return 1;
+
+	return 0;
+}
+
+/**
+ * Return 1 if a software reset command is being performed by the reset
+ * controller. The reset controller is busy.
+ */
+uint8_t RSTC_IsBusy(void)
+{
+	Rstc *pHw = RSTC;
+
+	if (pHw->RSTC_SR & RSTC_SR_SRCMP)
+		return 1;
+
+	return 0;
+}
+
+/**
+ * Get the status
+ */
+uint32_t RSTC_GetStatus(void)
+{
+	Rstc *pHw = RSTC;
+	return (pHw->RSTC_SR);
+}
+
Index: bsps/arm/atsam/contrib/libraries/libchip/source/rtc.c
===================================================================
--- bsps/arm/atsam/contrib/libraries/libchip/source/rtc.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libchip/source/rtc.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,452 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+/** \addtogroup rtc_module Working with RTC
+ *  \ingroup peripherals_module
+ * The RTC driver provides the interface to configure and use the RTC
+ * peripheral.
+ *
+ * It manages date, time, and alarms.\n
+ * This timer is clocked by the 32kHz system clock, and is not impacted by
+ * power management settings (PMC). To be accurate, it is better to use an
+ * external 32kHz crystal instead of the internal 32kHz RC.\n
+ *
+ * It uses BCD format, and time can be set in AM/PM or 24h mode through a
+ * configuration bit in the mode register.\n
+ *
+ * To update date or time, the user has to follow these few steps :
+ * <ul>
+ * <li>Set UPDTIM and/or UPDCAL bit(s) in RTC_CR,</li>
+ * <li>Polling or IRQ on the ACKUPD bit of RTC_CR,</li>
+ * <li>Clear ACKUPD bit in RTC_SCCR,</li>
+ * <li>Update Time and/or Calendar values in RTC_TIMR/RTC_CALR (BCD format),</li>
+ * <li>Clear UPDTIM and/or UPDCAL bit in RTC_CR.</li>
+ * </ul>
+ * An alarm can be set to happen on month, date, hours, minutes or seconds,
+ * by setting the proper "Enable" bit of each of these fields in the Time and
+ * Calendar registers.
+ * This allows a large number of configurations to be available for the user.
+ * Alarm occurrence can be detected even by polling or interrupt.
+ *
+ * A check of the validity of the date and time format and values written by
+ * the user is automatically done.
+ * Errors are reported through the Valid Entry Register.
+ *
+ * For more accurate information, please look at the RTC section of the
+ * Datasheet.
+ *
+ * Related files :\n
+ * \ref rtc.c\n
+ * \ref rtc.h.\n
+ */
+/*@{*/
+/*@}*/
+
+
+/**
+ * \file
+ *
+ * Implementation of Real Time Clock (RTC) controller.
+ *
+ */
+
+/*----------------------------------------------------------------------------
+ *        Headers
+ *----------------------------------------------------------------------------*/
+
+#include "chip.h"
+
+#include <stdint.h>
+#include <assert.h>
+
+/*----------------------------------------------------------------------------
+ *        Exported functions
+ *----------------------------------------------------------------------------*/
+
+/**
+ * \brief Sets the RTC in either 12 or 24 hour mode.
+ *
+ * \param mode  Hour mode.
+ */
+extern void RTC_SetHourMode(Rtc *pRtc, uint32_t dwMode)
+{
+	assert((dwMode & 0xFFFFFFFE) == 0);
+
+	pRtc->RTC_MR = dwMode;
+}
+
+/**
+ * \brief Gets the RTC mode.
+ *
+ * \return Hour mode.
+ */
+extern uint32_t RTC_GetHourMode(Rtc *pRtc)
+{
+	uint32_t dwMode;
+
+	TRACE_DEBUG("RTC_SetHourMode()\n\r");
+
+	dwMode = pRtc->RTC_MR;
+	dwMode &= 0xFFFFFFFE;
+
+	return dwMode;
+}
+
+/**
+ * \brief Enables the selected interrupt sources of the RTC.
+ *
+ * \param sources  Interrupt sources to enable.
+ */
+extern void RTC_EnableIt(Rtc *pRtc, uint32_t dwSources)
+{
+	assert((dwSources & (uint32_t)(~0x1F)) == 0);
+
+	TRACE_DEBUG("RTC_EnableIt()\n\r");
+
+	pRtc->RTC_IER = dwSources;
+}
+
+/**
+ * \brief Disables the selected interrupt sources of the RTC.
+ *
+ * \param sources  Interrupt sources to disable.
+ */
+extern void RTC_DisableIt(Rtc *pRtc, uint32_t dwSources)
+{
+	assert((dwSources & (uint32_t)(~0x1F)) == 0);
+
+	TRACE_DEBUG("RTC_DisableIt()\n\r");
+
+	pRtc->RTC_IDR = dwSources;
+}
+
+/**
+ * \brief Sets the current time in the RTC.
+ *
+ * \note In successive update operations, the user must wait at least one second
+ * after resetting the UPDTIM/UPDCAL bit in the RTC_CR before setting these
+ * bits again. Please look at the RTC section of the datasheet for detail.
+ *
+ * \param ucHour    Current hour in 12 or 24 hour mode.
+ * \param ucMinute  Current minute.
+ * \param ucSecond  Current second.
+ *
+ * \return 0 success, 1 fail to set
+ */
+extern int RTC_SetTime(Rtc *pRtc, uint8_t ucHour, uint8_t ucMinute,
+						uint8_t ucSecond)
+{
+	uint32_t dwTime = 0;
+	uint8_t ucHour_bcd;
+	uint8_t ucMin_bcd;
+	uint8_t ucSec_bcd;
+
+	TRACE_DEBUG("RTC_SetTime(%02d:%02d:%02d)\n\r", ucHour, ucMinute, ucSecond);
+
+	/* if 12-hour mode, set AMPM bit */
+	if ((pRtc->RTC_MR & RTC_MR_HRMOD) == RTC_MR_HRMOD) {
+		if (ucHour > 12) {
+			ucHour -= 12;
+			dwTime |= RTC_TIMR_AMPM;
+		}
+	}
+
+	ucHour_bcd = (ucHour % 10)   | ((ucHour / 10) << 4);
+	ucMin_bcd  = (ucMinute % 10) | ((ucMinute / 10) << 4);
+	ucSec_bcd  = (ucSecond % 10) | ((ucSecond / 10) << 4);
+
+	/* value overflow */
+	if ((ucHour_bcd & (uint8_t)(~RTC_HOUR_BIT_LEN_MASK)) |
+		 (ucMin_bcd & (uint8_t)(~RTC_MIN_BIT_LEN_MASK)) |
+		 (ucSec_bcd & (uint8_t)(~RTC_SEC_BIT_LEN_MASK)))
+		return 1;
+
+	dwTime = ucSec_bcd | (ucMin_bcd << 8) | (ucHour_bcd << 16);
+
+	pRtc->RTC_CR |= RTC_CR_UPDTIM;
+
+	while ((pRtc->RTC_SR & RTC_SR_ACKUPD) != RTC_SR_ACKUPD);
+
+	pRtc->RTC_SCCR = RTC_SCCR_ACKCLR;
+	pRtc->RTC_TIMR = dwTime;
+	pRtc->RTC_CR &= (uint32_t)(~RTC_CR_UPDTIM);
+	pRtc->RTC_SCCR |= RTC_SCCR_SECCLR;
+
+	return (int)(pRtc->RTC_VER & RTC_VER_NVTIM);
+}
+
+/**
+ * \brief Retrieves the current time as stored in the RTC in several variables.
+ *
+ * \param pucHour    If not null, current hour is stored in this variable.
+ * \param pucMinute  If not null, current minute is stored in this variable.
+ * \param pucSecond  If not null, current second is stored in this variable.
+ */
+extern void RTC_GetTime(Rtc *pRtc, uint8_t *pucHour,
+						 uint8_t *pucMinute, uint8_t *pucSecond)
+{
+	uint32_t dwTime;
+
+	TRACE_DEBUG("RTC_GetTime()\n\r");
+
+	/* Get current RTC time */
+	dwTime = pRtc->RTC_TIMR;
+
+	while (dwTime != pRtc->RTC_TIMR)
+		dwTime = pRtc->RTC_TIMR;
+
+	/* Hour */
+	if (pucHour) {
+		*pucHour = ((dwTime & 0x00300000) >> 20) * 10
+				   + ((dwTime & 0x000F0000) >> 16);
+
+		if ((dwTime & RTC_TIMR_AMPM) == RTC_TIMR_AMPM)
+			*pucHour += 12;
+	}
+
+	/* Minute */
+	if (pucMinute) {
+		*pucMinute = ((dwTime & 0x00007000) >> 12) * 10
+					 + ((dwTime & 0x00000F00) >> 8);
+	}
+
+	/* Second */
+	if (pucSecond) {
+		*pucSecond = ((dwTime & 0x00000070) >> 4) * 10
+					 + (dwTime & 0x0000000F);
+	}
+}
+
+/**
+ * \brief Sets a time alarm on the RTC.
+ * The match is performed only on the provided variables;
+ * Setting all pointers to 0 disables the time alarm.
+ *
+ * \note In AM/PM mode, the hour value must have bit #7 set for PM, cleared for
+ * AM (as expected in the time registers).
+ *
+ * \param pucHour    If not null, the time alarm will hour-match this value.
+ * \param pucMinute  If not null, the time alarm will minute-match this value.
+ * \param pucSecond  If not null, the time alarm will second-match this value.
+ *
+ * \return 0 success, 1 fail to set
+ */
+extern int RTC_SetTimeAlarm(Rtc *pRtc, uint8_t *pucHour,
+							 uint8_t *pucMinute, uint8_t *pucSecond)
+{
+	uint32_t dwAlarm = 0;
+
+	TRACE_DEBUG("RTC_SetTimeAlarm()\n\r");
+
+	/* Hour */
+	if (pucHour)
+		dwAlarm |= RTC_TIMALR_HOUREN | ((*pucHour / 10) << 20) | ((
+					   *pucHour % 10) << 16);
+
+	/* Minute */
+	if (pucMinute) {
+		dwAlarm |= RTC_TIMALR_MINEN | ((*pucMinute / 10) << 12)
+				   | ((*pucMinute % 10) << 8);
+	}
+
+	/* Second */
+	if (pucSecond)
+		dwAlarm |= RTC_TIMALR_SECEN | ((*pucSecond / 10) << 4) | (*pucSecond % 10);
+
+	pRtc->RTC_TIMALR = dwAlarm;
+
+	return (int)(pRtc->RTC_VER & RTC_VER_NVTIMALR);
+}
+
+/**
+ * \brief Retrieves the current year, month and day from the RTC.
+ * Month, day and week values are numbered starting at 1.
+ *
+ * \param pYwear  Current year (optional).
+ * \param pucMonth  Current month (optional).
+ * \param pucDay  Current day (optional).
+ * \param pucWeek  Current day in current week (optional).
+ */
+extern void RTC_GetDate(Rtc *pRtc, uint16_t *pwYear, uint8_t *pucMonth,
+						 uint8_t *pucDay, uint8_t *pucWeek)
+{
+	uint32_t dwDate;
+
+	/* Get current date (multiple reads are necessary to insure a stable value) */
+	do {
+		dwDate = pRtc->RTC_CALR;
+	} while (dwDate != pRtc->RTC_CALR);
+
+	/* Retrieve year */
+	if (pwYear) {
+		*pwYear = (((dwDate  >> 4) & 0x7) * 1000)
+				  + ((dwDate & 0xF) * 100)
+				  + (((dwDate >> 12) & 0xF) * 10)
+				  + ((dwDate >> 8) & 0xF);
+	}
+
+	/* Retrieve month */
+	if (pucMonth)
+		*pucMonth = (((dwDate >> 20) & 1) * 10) + ((dwDate >> 16) & 0xF);
+
+	/* Retrieve day */
+	if (pucDay)
+		*pucDay = (((dwDate >> 28) & 0x3) * 10) + ((dwDate >> 24) & 0xF);
+
+	/* Retrieve week */
+	if (pucWeek)
+		*pucWeek = ((dwDate >> 21) & 0x7);
+}
+
+/**
+ * \brief Sets the current year, month and day in the RTC.
+ * Month, day and week values must be numbered starting from 1.
+ *
+ * \note In successive update operations, the user must wait at least one second
+ * after resetting the UPDTIM/UPDCAL bit in the RTC_CR before setting these
+ * bits again. Please look at the RTC section of the datasheet for detail.
+ *
+ * \param wYear  Current year.
+ * \param ucMonth Current month.
+ * \param ucDay   Current day.
+ * \param ucWeek  Day number in current week.
+ *
+ * \return 0 success, 1 fail to set
+ */
+extern int RTC_SetDate(Rtc *pRtc, uint16_t wYear, uint8_t ucMonth,
+						uint8_t ucDay, uint8_t ucWeek)
+{
+	uint32_t wDate;
+	uint8_t ucCent_bcd;
+	uint8_t ucYear_bcd;
+	uint8_t ucMonth_bcd;
+	uint8_t ucDay_bcd;
+	uint8_t ucWeek_bcd;
+
+	ucCent_bcd  = ((wYear / 100) % 10) | ((wYear / 1000) << 4);
+	ucYear_bcd  = (wYear % 10) | (((wYear / 10) % 10) << 4);
+	ucMonth_bcd = ((ucMonth % 10) | (ucMonth / 10) << 4);
+	ucDay_bcd   = ((ucDay % 10) | (ucDay / 10) << 4);
+	ucWeek_bcd  = ((ucWeek % 10) | (ucWeek / 10) << 4);
+
+	/* value over flow */
+	if ((ucCent_bcd & (uint8_t)(~RTC_CENT_BIT_LEN_MASK)) |
+		 (ucYear_bcd & (uint8_t)(~RTC_YEAR_BIT_LEN_MASK)) |
+		 (ucMonth_bcd & (uint8_t)(~RTC_MONTH_BIT_LEN_MASK)) |
+		 (ucWeek_bcd & (uint8_t)(~RTC_WEEK_BIT_LEN_MASK)) |
+		 (ucDay_bcd & (uint8_t)(~RTC_DATE_BIT_LEN_MASK))
+	)
+		return 1;
+
+
+	/* Convert values to date register value */
+	wDate = ucCent_bcd |
+			(ucYear_bcd << 8) |
+			(ucMonth_bcd << 16) |
+			(ucWeek_bcd << 21) |
+			(ucDay_bcd << 24);
+
+	/* Update calendar register  */
+	pRtc->RTC_CR |= RTC_CR_UPDCAL;
+
+	while ((pRtc->RTC_SR & RTC_SR_ACKUPD) != RTC_SR_ACKUPD);
+
+	pRtc->RTC_SCCR = RTC_SCCR_ACKCLR;
+	pRtc->RTC_CALR = wDate;
+	pRtc->RTC_CR &= (uint32_t)(~RTC_CR_UPDCAL);
+	pRtc->RTC_SCCR |= RTC_SCCR_SECCLR; /* clear SECENV in SCCR */
+
+	return (int)(pRtc->RTC_VER & RTC_VER_NVCAL);
+}
+
+/**
+ * \brief Sets a date alarm in the RTC.
+ * The alarm will match only the provided values;
+ * Passing a null-pointer disables the corresponding field match.
+ *
+ * \param pucMonth If not null, the RTC alarm will month-match this value.
+ * \param pucDay   If not null, the RTC alarm will day-match this value.
+ *
+ * \return 0 success, 1 fail to set
+ */
+extern int RTC_SetDateAlarm(Rtc *pRtc, uint8_t *pucMonth, uint8_t *pucDay)
+{
+	uint32_t dwAlarm;
+
+	dwAlarm = ((pucMonth) || (pucDay)) ? (0) : (0x01010000);
+
+	TRACE_DEBUG("RTC_SetDateAlarm()\n\r");
+
+	/* Compute alarm field value */
+	if (pucMonth) {
+		dwAlarm |= RTC_CALALR_MTHEN | ((*pucMonth / 10) << 20)
+				   | ((*pucMonth % 10) << 16);
+	}
+
+	if (pucDay) {
+		dwAlarm |= RTC_CALALR_DATEEN | ((*pucDay / 10) << 28)
+				   | ((*pucDay % 10) << 24);
+	}
+
+	/* Set alarm */
+	pRtc->RTC_CALALR = dwAlarm;
+
+	return (int)(pRtc->RTC_VER & RTC_VER_NVCALALR);
+}
+
+/**
+ * \brief Clear flag bits of status clear command register in the RTC.
+ *
+ * \param mask Bits mask of cleared events
+ */
+extern void RTC_ClearSCCR(Rtc *pRtc, uint32_t dwMask)
+{
+	/* Clear all flag bits in status clear command register */
+	dwMask &= RTC_SCCR_ACKCLR | RTC_SCCR_ALRCLR | RTC_SCCR_SECCLR
+			  | RTC_SCCR_TIMCLR | RTC_SCCR_CALCLR;
+
+	pRtc->RTC_SCCR = dwMask;
+}
+
+/**
+ * \brief Get flag bits of status register in the RTC.
+ *
+ * \param mask Bits mask of Status Register
+ *
+ * \return Status register & mask
+ */
+extern uint32_t RTC_GetSR(Rtc *pRtc, uint32_t dwMask)
+{
+	uint32_t dwEvent;
+
+	dwEvent = pRtc->RTC_SR;
+
+	return (dwEvent & dwMask);
+}
+
Index: bsps/arm/atsam/contrib/libraries/libchip/source/rtt.c
===================================================================
--- bsps/arm/atsam/contrib/libraries/libchip/source/rtt.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libchip/source/rtt.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,134 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+/** \addtogroup rtt_module Working with RTT
+ *  \ingroup peripherals_module
+ * The RTT driver provides the interface to configure and use the RTT
+ * peripheral.
+ *
+ * The Real-time Timer is used to count elapsed seconds.\n
+ * This timer is clocked by the 32kHz system clock divided by a programmable
+ * 16-bit value. To be accurate, it is better to use an
+ * external 32kHz crystal instead of the internal 32kHz RC.\n
+ *
+ * To count elapsed seconds, the user could follow these few steps:
+ * <ul>
+ * <li>Programming PTPRES in RTT_MR to feeding the timer with a 1Hz signal.</li>
+ * <li>Writing the bit RTTRST in RTT_MR to restart the timer with new settings.
+ * </li>
+ * </ul>
+ *
+ * An alarm can be set to happen on second by setting alarm value in RTT_AR.
+ * Alarm occurrence can be detected by polling or interrupt.
+ *
+ * For more accurate information, please look at the RTT section of the
+ * Datasheet.
+ *
+ * Related files :\n
+ * \ref rtt.c\n
+ * \ref rtt.h.\n
+ */
+/*@{*/
+/*@}*/
+
+/**
+ * \file
+ *
+ * Implementation of Real Time Timer (RTT) controller.
+ *
+ */
+
+/*----------------------------------------------------------------------------
+ *        Headers
+ *----------------------------------------------------------------------------*/
+#include "chip.h"
+
+#include <assert.h>
+
+/*----------------------------------------------------------------------------
+ *        Exported functions
+ *----------------------------------------------------------------------------*/
+
+/**
+ * \brief Changes the prescaler value of the given RTT and restarts it.
+ *
+ * \note This function disables RTT interrupt sources.
+ *
+ * \param rtt  Pointer to a Rtt instance.
+ * \param prescaler  Prescaler value for the RTT.
+ */
+void RTT_SetPrescaler(Rtt *rtt, uint16_t prescaler)
+{
+	rtt->RTT_MR = (prescaler |  RTT_MR_RTTRST);
+}
+
+/**
+ * \brief Returns the current value of the RTT timer value.
+ *
+ * \param rtt  Pointer to a Rtt instance.
+ */
+uint32_t RTT_GetTime(Rtt *rtt)
+{
+	return rtt->RTT_VR;
+}
+
+/**
+ * \brief Enables the specified RTT interrupt sources.
+ *
+ * \param rtt  Pointer to a Rtt instance.
+ * \param sources  Bitmask of interrupts to enable.
+ */
+void RTT_EnableIT(Rtt *rtt, uint32_t sources)
+{
+	assert((sources & 0x0004FFFF) == 0);
+	rtt->RTT_MR |= sources;
+}
+
+/**
+ * \brief Returns the status register value of the given RTT.
+ *
+ * \param rtt  Pointer to an Rtt instance.
+ */
+uint32_t RTT_GetStatus(Rtt *rtt)
+{
+	return rtt->RTT_SR;
+}
+
+/**
+ * \brief Configures the RTT to generate an alarm at the given time.
+ *
+ * \param pRtt  Pointer to an Rtt instance.
+ * \param time  Alarm time.
+ */
+void RTT_SetAlarm(Rtt *pRtt, uint32_t time)
+{
+	assert(time > 0);
+
+	pRtt->RTT_AR = time - 1;
+}
Index: bsps/arm/atsam/contrib/libraries/libchip/source/sdramc.c
===================================================================
--- bsps/arm/atsam/contrib/libraries/libchip/source/sdramc.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libchip/source/sdramc.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,212 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+/** \addtogroup sdram_module
+ * The SDRAMC driver provides the Interface to configure the SDRAM Controller
+ * (SDRAMC).
+ *  \section Usage
+ * <ul>
+ *  <li> Configure SDRAM using SDRAMC_Configure().</li>
+
+ * </ul>
+ * For more accurate information, please look at the SDRAMC section of the
+ * Datasheet.
+ * Related files :\n
+ * \ref sdramc.c\n
+ * \ref sdramc.h.\n
+*/
+
+/**
+*  \file
+*
+*  \section Purpose
+*
+*  Interface for configuring and using SDRAM Controller (SDRAMC).
+*
+*/
+
+/**
+ * \file
+ *
+ * Implementation of memories configuration on board.
+ *
+ */
+/*----------------------------------------------------------------------------
+ *        Headers
+ *----------------------------------------------------------------------------*/
+#include "chip.h"
+#include "sdramc.h"
+
+/*----------------------------------------------------------------------------
+ *        Local functions
+ *----------------------------------------------------------------------------*/
+/**
+ * \brief Calculate the sdram controller config register value.
+ * \param pMemory  Pointer to the sdram structure.
+ * \return Configure register value.
+ */
+static uint32_t SDRAMC_compute_CR_value(SSdramc_Memory *pMemory)
+{
+	uint32_t dw = 0;
+
+	dw |= pMemory->cfg.dwColumnBits;
+	dw |= pMemory->cfg.dwRowBits;
+	dw |= pMemory->cfg.dwBanks;  //NB, number of banks
+	dw |= pMemory->cfg.dwCAS;  //CAS, CAS latency
+	dw |= pMemory->cfg.dwDataBusWidth;  //DBW, data bus width
+	dw |= SDRAMC_CR_TWR(pMemory->cfg.dwWriteRecoveryDelay);
+	//TWR, Write Recovery Delay
+	dw |= SDRAMC_CR_TRC_TRFC(pMemory->cfg.dwRowCycleDelay_RowRefreshCycle);
+	//TRC_TRFC,Row Cycle Delay and Row Refresh Cycle
+	dw |= SDRAMC_CR_TRP(pMemory->cfg.dwRowPrechargeDelay);
+	//TRP, Row Precharge Delay
+	dw |= SDRAMC_CR_TRCD(pMemory->cfg.dwRowColumnDelay);
+	//TRCD, Row to Column Delay
+	dw |= SDRAMC_CR_TRAS(pMemory->cfg.dwActivePrechargeDelay);
+	//TRAS, Active to Precharge Delay
+	dw |= SDRAMC_CR_TXSR(pMemory->cfg.dwExitSelfRefreshActiveDelay);
+	//TXSR, Exit Self Refresh to Active Delay
+	return dw;
+}
+
+/*----------------------------------------------------------------------------
+ *        Exported functions
+ *----------------------------------------------------------------------------*/
+/**
+ * \brief Configure and initialize the SDRAM controller.
+ * \param pMemory  Pointer to the sdram structure.
+ * \param dwClockFrequency  SDRAM clock frequency.
+ */
+extern void SDRAMC_Configure(SSdramc_Memory *pMemory,
+							  uint32_t dwClockFrequency)
+{
+	volatile uint32_t dw;
+
+	/* SDRAM hardware init */
+	/* Enable peripheral clock */
+	PMC_EnablePeripheral(ID_SMC);
+
+	/* SDRAM device configure */
+	/* Step 1. */
+	/* Program the features of SDRAM device into the Configuration Register.*/
+	SDRAMC->SDRAMC_CR = SDRAMC_compute_CR_value(pMemory);
+
+	/* Step 2. */
+	/* For low-power SDRAM, temperature-compensated self refresh (TCSR),
+	   drive strength (DS) and partial array self refresh (PASR) must be set
+	   in the Low-power Register.*/
+	SDRAMC->SDRAMC_LPR = 0;
+
+	/* Step 3. */
+	/* Program the memory device type into the Memory Device Register */
+	SDRAMC->SDRAMC_MDR = SDRAMC_MDR_MD_SDRAM;
+
+	/* Step 4 */
+	/* A minimum pause of 200 ŠÌs is provided to precede any signal toggle.
+	   (6 core cycles per iteration) */
+	for (dw = 0; dw < ((dwClockFrequency / 1000000) * 200 / 6); dw++);
+
+	/* Step 5. */
+	/* A NOP command is issued to the SDR-SDRAM. Program NOP command into
+	 Mode Register, the application must set Mode to 1 in the Mode Register.
+	Perform a write access to any SDR-SDRAM address to acknowledge this command.
+	Now the clock which drives SDR-SDRAM device is enabled.*/
+	SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_NOP;
+	*(uint16_t *)(EBI_SDRAMC_ADDR) = 0;
+
+	/* Step 6. */
+	/* An all banks precharge command is issued to the SDR-SDRAM. Program all
+	   banks precharge command into Mode Register, the application must set Mode to
+	   2 in the Mode Register . Perform a write access to any SDRSDRAM address to
+	   acknowledge this command. */
+	SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_ALLBANKS_PRECHARGE;
+	*(uint16_t *)(EBI_SDRAMC_ADDR) = 0x0;
+
+	/* add some delays after precharge */
+	for (dw = 0; dw < ((dwClockFrequency / 1000000) * 200 / 6); dw++);
+
+	/* Step 7. */
+	/* Eight auto-refresh (CBR) cycles are provided. Program the auto refresh
+	   command (CBR) into Mode Register, the application must set Mode to 4 in
+	   the Mode Register. Once in the idle state, eight AUTO REFRESH cycles must
+	   be performed. */
+	SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_AUTO_REFRESH;
+	*(uint16_t *)(EBI_SDRAMC_ADDR + 0) = 0x1;
+
+	SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_AUTO_REFRESH;
+	*(uint16_t *)(EBI_SDRAMC_ADDR + 0) = 0x2;
+
+	SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_AUTO_REFRESH;
+	*(uint16_t *)(EBI_SDRAMC_ADDR + 0) = 0x3;
+
+	SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_AUTO_REFRESH;
+	*(uint16_t *)(EBI_SDRAMC_ADDR + 0) = 0x4;
+
+	SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_AUTO_REFRESH;
+	*(uint16_t *)(EBI_SDRAMC_ADDR + 0) = 0x5;
+
+	SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_AUTO_REFRESH;
+	*(uint16_t *)(EBI_SDRAMC_ADDR + 0) = 0x6;
+
+	SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_AUTO_REFRESH;
+	*(uint16_t *)(EBI_SDRAMC_ADDR + 0) = 0x7;
+
+	SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_AUTO_REFRESH;
+	*(uint16_t *)(EBI_SDRAMC_ADDR + 0) = 0x8;
+
+	/* Step 8. */
+	/* A Mode Register set (MRS) cycle is issued to program the parameters of
+	   the SDRAM devices, in particular CAS latency and burst length. */
+	SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_LOAD_MODEREG;
+	*(uint16_t *)(EBI_SDRAMC_ADDR + 0x22) = 0xcafe;
+
+	/* Step 9. */
+	/* For low-power SDR-SDRAM initialization, an Extended Mode Register set
+	   (EMRS) cycle is issued to program the SDR-SDRAM parameters (TCSR, PASR, DS).
+	   The write address must be chosen so that BA[1] is set to 1 and BA[0] is set
+	   to 0 */
+	SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_EXT_LOAD_MODEREG;
+	*((uint16_t *)(EBI_SDRAMC_ADDR + (1 << pMemory->cfg.dwBK1))) = 0;
+
+	/* Step 10. */
+	/* The application must go into Normal Mode, setting Mode to 0 in the Mode
+	   Register and perform a write access at any location in the SDRAM to
+	   acknowledge this command. */
+	SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_NORMAL;
+	*(uint16_t *)(EBI_SDRAMC_ADDR) = 0x0;
+
+	/* Step 11. */
+	/* Write the refresh rate into the count field in the SDRAMC Refresh
+	   Timer register. Set Refresh timer 15.625 us*/
+	dw = dwClockFrequency / 1000u;
+	dw *= 15625u;
+	dw /= 1000000u;
+	SDRAMC->SDRAMC_TR = SDRAMC_TR_COUNT(dw);
+}
+
Index: bsps/arm/atsam/contrib/libraries/libchip/source/spi.c
===================================================================
--- bsps/arm/atsam/contrib/libraries/libchip/source/spi.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libchip/source/spi.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,282 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+/** \addtogroup spi_module Working with SPI
+ * The SPI driver provides the interface to configure and use the SPI
+ * peripheral.
+ *
+ * The Serial Peripheral Interface (SPI) circuit is a synchronous serial
+ * data link that provides communication with external devices in Master
+ * or Slave Mode.
+ *
+ * To use the SPI, the user has to follow these few steps:
+ * -# Enable the SPI pins required by the application (see pio.h).
+ * -# Configure the SPI using the \ref SPI_Configure(). This enables the
+ *    peripheral clock. The mode register is loaded with the given value.
+ * -# Configure all the necessary chip selects with \ref SPI_ConfigureNPCS().
+ * -# Enable the SPI by calling \ref SPI_Enable().
+ * -# Send/receive data using \ref SPI_Write() and \ref SPI_Read(). Note that
+ * \ref SPI_Read()
+ *    must be called after \ref SPI_Write() to retrieve the last value read.
+ * -# Disable the SPI by calling \ref SPI_Disable().
+ *
+ * For more accurate information, please look at the SPI section of the
+ * Datasheet.
+ *
+ * Related files :\n
+ * \ref spi.c\n
+ * \ref spi.h.\n
+ */
+/*@{*/
+/*@}*/
+
+/**
+ * \file
+ *
+ * Implementation of Serial Peripheral Interface (SPI) controller.
+ *
+ */
+
+/*----------------------------------------------------------------------------
+ *        Headers
+ *----------------------------------------------------------------------------*/
+
+#include "chip.h"
+
+#include <stdint.h>
+
+/*----------------------------------------------------------------------------
+ *        Exported functions
+ *----------------------------------------------------------------------------*/
+
+/**
+ * \brief Enables a SPI peripheral.
+ *
+ * \param spi  Pointer to an SPI instance.
+ */
+extern void SPI_Enable(Spi *spi)
+{
+	spi->SPI_CR = SPI_CR_SPIEN;
+}
+
+/**
+ * \brief Disables a SPI peripheral.
+ *
+ * \param spi  Pointer to an SPI instance.
+ */
+extern void SPI_Disable(Spi *spi)
+{
+	spi->SPI_CR = SPI_CR_SPIDIS;
+}
+
+/**
+ * \brief Enables one or more interrupt sources of a SPI peripheral.
+ *
+ * \param spi  Pointer to an SPI instance.
+ * \param sources Bitwise OR of selected interrupt sources.
+ */
+extern void SPI_EnableIt(Spi *spi, uint32_t dwSources)
+{
+	spi->SPI_IER = dwSources;
+}
+
+/**
+ * \brief Disables one or more interrupt sources of a SPI peripheral.
+ *
+ * \param spi  Pointer to an SPI instance.
+ * \param sources Bitwise OR of selected interrupt sources.
+ */
+extern void SPI_DisableIt(Spi *spi, uint32_t dwSources)
+{
+	spi->SPI_IDR = dwSources;
+}
+
+/**
+ * \brief Configures a SPI peripheral as specified. The configuration can be
+ * computed using several macros (see \ref spi_configuration_macros).
+ *
+ * \param spi  Pointer to an SPI instance.
+ * \param id   Peripheral ID of the SPI.
+ * \param configuration  Value of the SPI configuration register.
+ */
+extern void SPI_Configure(Spi *spi, uint32_t dwId, uint32_t dwConfiguration)
+{
+	PMC_EnablePeripheral(dwId);
+
+	spi->SPI_CR = SPI_CR_SPIDIS;
+
+	/* Execute a software reset of the SPI twice */
+	spi->SPI_CR = SPI_CR_SWRST;
+	spi->SPI_CR = SPI_CR_SWRST;
+	spi->SPI_MR = dwConfiguration;
+}
+
+/**
+ * \brief Configures SPI chip select.
+ *
+ * \param spi  Pointer to an SPI instance.
+ * \param cS  Chip select of NPSCx.
+ */
+extern void SPI_ChipSelect(Spi *spi, uint8_t cS)
+{
+	spi->SPI_MR |= SPI_MR_PCS_Msk;
+	spi->SPI_MR &= ~(SPI_MR_PCS (cS));
+}
+
+/**
+ * \brief Configures SPI Mode Register.
+ *
+ * \param spi  Pointer to an SPI instance.
+ * \param configuration  Value of the SPI mode register.
+ */
+extern void SPI_SetMode(Spi *spi,
+						 uint32_t dwConfiguration)
+{
+	spi->SPI_MR = dwConfiguration;
+}
+
+/**
+ * \brief Configures SPI to release last used CS line.
+ *
+ * \param spi  Pointer to an SPI instance.
+ */
+extern void SPI_ReleaseCS(Spi *spi)
+{
+	spi->SPI_CR = SPI_CR_LASTXFER;
+}
+
+
+/**
+ * \brief Configures a chip select of a SPI peripheral. The chip select
+ * configuration is computed using several macros
+ * (see \ref spi_configuration_macros).
+ *
+ * \param spi   Pointer to an SPI instance.
+ * \param npcs  Chip select to configure (0, 1, 2 or 3).
+ * \param configuration  Desired chip select configuration.
+ */
+void SPI_ConfigureNPCS(Spi *spi, uint32_t dwNpcs, uint32_t dwConfiguration)
+{
+	spi->SPI_CSR[dwNpcs] = dwConfiguration;
+}
+
+/**
+ * \brief Configures a chip select active mode of a SPI peripheral.
+ *
+ * \param spi   Pointer to an SPI instance.
+ * \param dwNpcs  Chip select to configure (0, 1, 2 or 3).
+ * \param bReleaseOnLast CS controlled by last transfer.
+ *                       SPI_ReleaseCS() is used to release CS.
+ */
+void SPI_ConfigureCSMode(Spi *spi, uint32_t dwNpcs, uint32_t bReleaseOnLast)
+{
+	if (bReleaseOnLast)
+		spi->SPI_CSR[dwNpcs] |=  SPI_CSR_CSAAT;
+	else
+		spi->SPI_CSR[dwNpcs] &= ~SPI_CSR_CSAAT;
+}
+
+/**
+ * \brief Get the current status register of the given SPI peripheral.
+ * \note This resets the internal value of the status register, so further
+ * read may yield different values.
+ * \param spi   Pointer to a Spi instance.
+ * \return  SPI status register.
+ */
+extern uint32_t SPI_GetStatus(Spi *spi)
+{
+	return spi->SPI_SR;
+}
+
+/**
+ * \brief Reads and returns the last word of data received by a SPI peripheral.
+ * This method must be called after a successful SPI_Write call.
+ *
+ * \param spi  Pointer to an Spi instance.
+ *
+ * \return read data.
+ */
+extern uint32_t SPI_Read(Spi *spi)
+{
+	while ((spi->SPI_SR & SPI_SR_RDRF) == 0);
+
+	return spi->SPI_RDR & 0xFFFF;
+}
+
+/**
+ * \brief Sends data through a SPI peripheral. If the SPI is configured to use a
+ * fixed  peripheral select, the npcs value is meaningless. Otherwise,
+ * it identifies the component which shall be addressed.
+ *
+ * \param spi   Pointer to an SPI instance.
+ * \param npcs  Chip select of the component to address (0, 1, 2 or 3).
+ * \param data  Word of data to send.
+ */
+extern void SPI_Write(Spi *spi, uint32_t dwNpcs, uint16_t wData)
+{
+	/* Send data */
+	while ((spi->SPI_SR & SPI_SR_TXEMPTY) == 0);
+
+	spi->SPI_TDR = wData | SPI_PCS(dwNpcs);
+
+	while ((spi->SPI_SR & SPI_SR_TDRE) == 0);
+}
+
+/**
+ * \brief Sends last data through a SPI peripheral.
+ * If the SPI is configured to use a fixed peripheral select, the npcs value is
+ * meaningless. Otherwise, it identifies the component which shall be addressed.
+ *
+ * \param spi   Pointer to an SPI instance.
+ * \param npcs  Chip select of the component to address (0, 1, 2 or 3).
+ * \param data  Word of data to send.
+ */
+extern void SPI_WriteLast(Spi *spi, uint32_t dwNpcs, uint16_t wData)
+{
+	/* Send data */
+	while ((spi->SPI_SR & SPI_SR_TXEMPTY) == 0);
+
+	spi->SPI_TDR = wData | SPI_PCS(dwNpcs) | SPI_TDR_LASTXFER;
+
+	while ((spi->SPI_SR & SPI_SR_TDRE) == 0);
+}
+
+/**
+ * \brief Check if SPI transfer finish.
+ *
+ * \param spi  Pointer to an SPI instance.
+ *
+ * \return Returns 1 if there is no pending write operation on the SPI;
+ * otherwise returns 0.
+ */
+extern uint32_t SPI_IsFinished(Spi *spi)
+{
+	return ((spi->SPI_SR & SPI_SR_TXEMPTY) != 0);
+}
+
Index: bsps/arm/atsam/contrib/libraries/libchip/source/spi_dma.c
===================================================================
--- bsps/arm/atsam/contrib/libraries/libchip/source/spi_dma.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libchip/source/spi_dma.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,392 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+/**
+ * \addtogroup spi_dma_module SPI xDMA driver
+ * \ingroup lib_spiflash
+ * \section Usage
+ *
+ * <ul>
+ * <li> SPID_Configure() initializes and configures the SPI peripheral and xDMA
+ * for data transfer.</li>
+ * <li> Configures the parameters for the device corresponding to the cs value
+ * by SPID_ConfigureCS(). </li>
+ * <li> Starts a SPI master transfer. This is a non blocking function
+ * SPID_SendCommand(). It will
+ * return as soon as the transfer is started..</li>
+ * </ul>
+ *
+ */
+
+/**
+ * \file
+ *
+ * Implementation for the SPI Flash with xDMA driver.
+ *
+ */
+
+
+/*----------------------------------------------------------------------------
+ *        Headers
+ *----------------------------------------------------------------------------*/
+
+#include "chip.h"
+
+/*----------------------------------------------------------------------------
+ *        Definitions
+ *----------------------------------------------------------------------------*/
+
+/** xDMA support */
+#define USE_SPI_DMA
+
+/** xDMA Link List size for SPI transmission*/
+#define DMA_SPI_LLI     2
+
+/*----------------------------------------------------------------------------
+ *        Macros
+ *----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+ *        Local Variables
+ *----------------------------------------------------------------------------*/
+
+
+/*  DMA driver instance */
+static uint32_t spiDmaTxChannel;
+static uint32_t spiDmaRxChannel;
+
+/*----------------------------------------------------------------------------
+ *        Local functions
+ *----------------------------------------------------------------------------*/
+
+/**
+ * \brief SPI xDMA Rx callback
+ * Invoked on SPi DMA reception done.
+ * \param channel DMA channel.
+ * \param pArg Pointer to callback argument - Pointer to Spid instance.
+ */
+static void SPID_Rx_Cb(uint32_t channel, Spid *pArg)
+{
+	SpidCmd *pSpidCmd = pArg->pCurrentCommand;
+	Spi *pSpiHw = pArg->pSpiHw;
+
+	if (channel != spiDmaRxChannel)
+		return;
+
+	/* Disable the SPI TX & RX */
+	SPI_Disable (pSpiHw);
+	TRACE_INFO("SPI Rx DMA Callback has been called %d bytes received\n\r",
+			   pArg->pCurrentCommand->RxSize);
+	/* Configure and enable interrupt on RC compare */
+	NVIC_ClearPendingIRQ(XDMAC_IRQn);
+	NVIC_DisableIRQ(XDMAC_IRQn);
+
+	/* Disable the SPI Peripheral */
+	PMC_DisablePeripheral (pArg->spiId);
+
+	/* Release CS */
+	SPI_ReleaseCS(pSpiHw);
+
+	/* Release the DMA channels */
+	XDMAD_FreeChannel(pArg->pXdmad, spiDmaRxChannel);
+	XDMAD_FreeChannel(pArg->pXdmad, spiDmaTxChannel);
+	SCB_InvalidateDCache_by_Addr((uint32_t *)pArg->pCurrentCommand->pRxBuff,
+								 pArg->pCurrentCommand->RxSize);
+	/* Release the dataflash semaphore */
+	pArg->semaphore++;
+
+	printf(" %s\n\r", pArg->pCurrentCommand->pRxBuff);
+
+	/* Invoke the callback associated with the current command */
+	if (pSpidCmd && pSpidCmd->callback) {
+		//printf("p %d", pArg->semaphore);
+		pSpidCmd->callback(0, pSpidCmd->pArgument);
+	}
+}
+
+/**
+ * \brief Configure the DMA Channels: 0 RX, 1 TX.
+ * Channels are disabled after configure.
+ * \returns 0 if the dma channel configuration successfully; otherwise returns
+ * SPID_ERROR_XXX.
+ */
+static uint8_t _spid_configureDmaChannels(Spid *pSpid)
+{
+	/* Driver initialize */
+	XDMAD_FreeChannel(pSpid->pXdmad, spiDmaTxChannel);
+	XDMAD_FreeChannel(pSpid->pXdmad, spiDmaRxChannel);
+
+	/* Allocate a DMA channel for SPI0/1 TX. */
+	spiDmaTxChannel = XDMAD_AllocateChannel(pSpid->pXdmad,
+					  XDMAD_TRANSFER_MEMORY, pSpid->spiId);
+
+	if (spiDmaTxChannel == XDMAD_ALLOC_FAILED)
+		return SPID_ERROR;
+
+	/* Allocate a DMA channel for SPI0/1 RX. */
+	spiDmaRxChannel =
+		XDMAD_AllocateChannel(pSpid->pXdmad, pSpid->spiId, XDMAD_TRANSFER_MEMORY);
+
+	if (spiDmaRxChannel == XDMAD_ALLOC_FAILED)
+		return SPID_ERROR;
+
+	/* Setup callbacks for SPI0/1 RX */
+	XDMAD_SetCallback(pSpid->pXdmad, spiDmaRxChannel,
+					  (XdmadTransferCallback)SPID_Rx_Cb, pSpid);
+
+	if (XDMAD_PrepareChannel(pSpid->pXdmad, spiDmaRxChannel))
+		return SPID_ERROR;
+
+	/* Setup callbacks for SPI0/1 TX (ignored) */
+	XDMAD_SetCallback(pSpid->pXdmad, spiDmaTxChannel, NULL, NULL);
+
+	if (XDMAD_PrepareChannel(pSpid->pXdmad, spiDmaTxChannel))
+		return SPID_ERROR;
+
+	return 0;
+}
+
+/**
+ * \brief Configure the DMA source and destination with Linker List mode.
+ *
+ * \param pCommand Pointer to command
+ * \returns 0 if the dma multibuffer configuration successfully; otherwise
+ * returns SPID_ERROR_XXX.
+ */
+static uint8_t _spid_configureLinkList(Spi *pSpiHw, void *pXdmad,
+									   SpidCmd *pCommand)
+{
+	sXdmadCfg xdmadRxCfg, xdmadTxCfg;
+	uint32_t xdmaCndc, xdmaInt;
+	uint32_t spiId;
+
+	if ((unsigned int)pSpiHw == (unsigned int)SPI0) spiId = ID_SPI0;
+
+	if ((unsigned int)pSpiHw == (unsigned int)SPI1) spiId = ID_SPI1;
+
+	/* Setup TX  */
+
+	xdmadTxCfg.mbr_sa = (uint32_t)pCommand->pTxBuff;
+
+	xdmadTxCfg.mbr_da = (uint32_t)&pSpiHw->SPI_TDR;
+
+	xdmadTxCfg.mbr_ubc =  XDMA_UBC_NVIEW_NDV0 |
+						  XDMA_UBC_NDE_FETCH_DIS |
+						  XDMA_UBC_NSEN_UPDATED | pCommand->TxSize;
+
+	xdmadTxCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN |
+						 XDMAC_CC_MBSIZE_SINGLE |
+						 XDMAC_CC_DSYNC_MEM2PER |
+						 XDMAC_CC_CSIZE_CHK_1 |
+						 XDMAC_CC_DWIDTH_BYTE |
+						 XDMAC_CC_SIF_AHB_IF1 |
+						 XDMAC_CC_DIF_AHB_IF1 |
+						 XDMAC_CC_SAM_INCREMENTED_AM |
+						 XDMAC_CC_DAM_FIXED_AM |
+						 XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber(spiId, XDMAD_TRANSFER_TX));
+
+
+	xdmadTxCfg.mbr_bc = 0;
+	xdmadTxCfg.mbr_sus = 0;
+	xdmadTxCfg.mbr_dus = 0;
+
+	/* Setup RX Link List */
+
+	xdmadRxCfg.mbr_ubc = XDMA_UBC_NVIEW_NDV0 |
+						 XDMA_UBC_NDE_FETCH_DIS |
+						 XDMA_UBC_NDEN_UPDATED | pCommand->RxSize;
+
+	xdmadRxCfg.mbr_da = (uint32_t)pCommand->pRxBuff;
+
+	xdmadRxCfg.mbr_sa = (uint32_t)&pSpiHw->SPI_RDR;
+	xdmadRxCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN |
+						 XDMAC_CC_MBSIZE_SINGLE |
+						 XDMAC_CC_DSYNC_PER2MEM |
+						 XDMAC_CC_CSIZE_CHK_1 |
+						 XDMAC_CC_DWIDTH_BYTE |
+						 XDMAC_CC_SIF_AHB_IF1 |
+						 XDMAC_CC_DIF_AHB_IF1 |
+						 XDMAC_CC_SAM_FIXED_AM |
+						 XDMAC_CC_DAM_INCREMENTED_AM |
+						 XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber(spiId, XDMAD_TRANSFER_RX));
+
+
+	xdmadRxCfg.mbr_bc = 0;
+	xdmadRxCfg.mbr_sus = 0;
+	xdmadRxCfg.mbr_dus = 0;
+
+	xdmaCndc = 0;
+
+	/* Put all interrupts on for non LLI list setup of DMA */
+	xdmaInt =  (XDMAC_CIE_BIE   |
+				XDMAC_CIE_DIE   |
+				XDMAC_CIE_FIE   |
+				XDMAC_CIE_RBIE  |
+				XDMAC_CIE_WBIE  |
+				XDMAC_CIE_ROIE);
+
+	if (XDMAD_ConfigureTransfer(pXdmad, spiDmaRxChannel, &xdmadRxCfg, xdmaCndc, 0,
+								 xdmaInt))
+		return SPID_ERROR;
+
+	if (XDMAD_ConfigureTransfer(pXdmad, spiDmaTxChannel, &xdmadTxCfg, xdmaCndc, 0,
+								 xdmaInt))
+		return SPID_ERROR;
+
+	return 0;
+}
+
+
+/*----------------------------------------------------------------------------
+ *        Exported functions
+ *----------------------------------------------------------------------------*/
+/**
+ * \brief Initializes the Spid structure and the corresponding SPI & DMA hardware.
+ * select value.
+ * The driver will uses DMA channel 0 for RX and DMA channel 1 for TX.
+ * The DMA channels are freed automatically when no SPI command processing.
+ *
+ * \param pSpid  Pointer to a Spid instance.
+ * \param pSpiHw Associated SPI peripheral.
+ * \param spiId  SPI peripheral identifier.
+ * \param pDmad  Pointer to a Dmad instance.
+ */
+uint32_t SPID_Configure(Spid *pSpid ,
+						 Spi *pSpiHw ,
+						 uint8_t spiId,
+						 uint32_t spiMode,
+						 sXdmad *pXdmad)
+{
+	/* Initialize the SPI structure */
+	pSpid->pSpiHw = pSpiHw;
+	pSpid->spiId  = spiId;
+	pSpid->semaphore = 1;
+	pSpid->pCurrentCommand = 0;
+	assert(pXdmad == &XDMAD_Instance);
+	pSpid->pXdmad = pXdmad;
+
+	/* Enable the SPI Peripheral ,Execute a software reset of the SPI,
+	    Configure SPI in Master Mode*/
+	SPI_Configure (pSpiHw, pSpid->spiId, spiMode);
+
+	return 0;
+}
+
+/**
+ * \brief Configures the parameters for the device corresponding to the cs value.
+ *
+ * \param pSpid  Pointer to a Spid instance.
+ * \param cs number corresponding to the SPI chip select.
+ * \param csr SPI_CSR value to setup.
+ */
+void SPID_ConfigureCS(Spid *pSpid,
+					   uint32_t dwCS,
+					   uint32_t dwCsr)
+{
+	Spi *pSpiHw = pSpid->pSpiHw;
+
+	/* Enable the SPI Peripheral */
+	PMC_EnablePeripheral (pSpid->spiId);
+	/* Configure SPI Chip Select Register */
+	SPI_ConfigureNPCS(pSpiHw, dwCS, dwCsr);
+
+	/* Disable the SPI Peripheral */
+	PMC_DisablePeripheral (pSpid->spiId);
+
+}
+
+/**
+ * \brief Starts a SPI master transfer. This is a non blocking function. It will
+ *  return as soon as the transfer is started.
+ *
+ * \param pSpid  Pointer to a Spid instance.
+ * \param pCommand Pointer to the SPI command to execute.
+ * \returns 0 if the transfer has been started successfully; otherwise returns
+ * SPID_ERROR_LOCK is the driver is in use, or SPID_ERROR if the command is not
+ * valid.
+ */
+uint32_t SPID_SendCommand(Spid *pSpid, SpidCmd *pCommand)
+{
+	Spi *pSpiHw = pSpid->pSpiHw;
+
+	/* Try to get the dataflash semaphore */
+	if (pSpid->semaphore == 0)
+		return SPID_ERROR_LOCK;
+
+	pSpid->semaphore--;
+
+	/* Enable the SPI Peripheral */
+	PMC_EnablePeripheral (pSpid->spiId);
+
+	/* SPI chip select */
+	SPI_ChipSelect (pSpiHw, 1 << pCommand->spiCs);
+
+	// Initialize the callback
+	pSpid->pCurrentCommand = pCommand;
+
+	/* Initialize DMA controller using channel 0 for RX, 1 for TX. */
+	if (_spid_configureDmaChannels(pSpid))
+		return SPID_ERROR_LOCK;
+
+	/* Configure and enable interrupt on RC compare */
+	NVIC_ClearPendingIRQ(XDMAC_IRQn);
+	NVIC_SetPriority(XDMAC_IRQn , 1);
+	NVIC_EnableIRQ(XDMAC_IRQn);
+
+
+	if (_spid_configureLinkList(pSpiHw, pSpid->pXdmad, pCommand))
+		return SPID_ERROR_LOCK;
+
+	/* Enables the SPI to transfer and receive data. */
+	SPI_Enable (pSpiHw);
+	SCB_CleanDCache_by_Addr((uint32_t *)pCommand->pTxBuff, pCommand->TxSize);
+
+	/* Start DMA 0(RX) && 1(TX) */
+	if (XDMAD_StartTransfer(pSpid->pXdmad, spiDmaRxChannel))
+		return SPID_ERROR_LOCK;
+
+	if (XDMAD_StartTransfer(pSpid->pXdmad, spiDmaTxChannel))
+		return SPID_ERROR_LOCK;
+
+	return 0;
+}
+
+/**
+ * \brief Check if the SPI driver is busy.
+ *
+ * \param pSpid  Pointer to a Spid instance.
+ * \returns 1 if the SPI driver is currently busy executing a command; otherwise
+ */
+uint32_t SPID_IsBusy(const Spid *pSpid)
+{
+	if (pSpid->semaphore == 0)
+		return 1;
+	else
+		return 0;
+}
Index: bsps/arm/atsam/contrib/libraries/libchip/source/ssc.c
===================================================================
--- bsps/arm/atsam/contrib/libraries/libchip/source/ssc.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libchip/source/ssc.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,219 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+/** \addtogroup ssc_module Working with SSC
+ *  \ingroup peripherals_module
+ * The SSC driver provides the interface to configure and use the SSC
+ * peripheral.
+ *
+ * !Usage
+ *
+ * -# Enable the SSC interface pins.
+ * -# Configure the SSC to operate at a specific frequency by calling
+ *    SSC_Configure(). This function enables the peripheral clock of the SSC,
+ *    but not its PIOs.
+ * -# Configure the transmitter and/or the receiver using the
+ *    SSC_ConfigureTransmitter() and SSC_ConfigureEmitter() functions.
+ * -# Enable the PIOs or the transmitter and/or the received.
+ * -# Enable the transmitter and/or the receiver using SSC_EnableTransmitter()
+ *    and SSC_EnableReceiver()
+ * -# Send data through the transmitter using SSC_Write()
+ * -# Receive data from the receiver using SSC_Read()
+ * -# Disable the transmitter and/or the receiver using SSC_DisableTransmitter()
+ *    and SSC_DisableReceiver()
+ *
+ * For more accurate information, please look at the SSC section of the
+ * Datasheet.
+ *
+ * Related files :\n
+ * \ref ssc.c\n
+ * \ref ssc.h.\n
+ */
+/*@{*/
+/*@}*/
+
+
+/**
+ * \file
+ *
+ * Implementation of Synchronous Serial (SSC) controller.
+ *
+ */
+
+/*----------------------------------------------------------------------------
+ *        Headers
+ *----------------------------------------------------------------------------*/
+
+#include "chip.h"
+
+/*----------------------------------------------------------------------------
+ *       Exported functions
+ *----------------------------------------------------------------------------*/
+
+/**
+ * \brief Configures a SSC peripheral.If the divided clock is not used, the
+ *  master clock frequency can be set to 0.
+ * \note The emitter and transmitter are disabled by this function.
+ * \param ssc  Pointer to an SSC instance.
+ * \param bitRate  bit rate.
+ * \param masterClock  master clock.
+ */
+void SSC_Configure(Ssc *ssc, uint32_t bitRate, uint32_t masterClock)
+{
+	uint32_t id;
+	//    uint32_t maxClock;
+	id = ID_SSC;
+	//    maxClock = PMC_SetPeriMaxClock(id, masterClock);
+
+	/* Reset, disable receiver & transmitter */
+	ssc->SSC_CR = SSC_CR_RXDIS | SSC_CR_TXDIS | SSC_CR_SWRST;
+
+	/* Configure clock frequency */
+	if (bitRate != 0)
+		ssc->SSC_CMR = masterClock / (2 * bitRate);
+	else
+		ssc->SSC_CMR = 0;
+
+	/* Enable SSC peripheral clock */
+	PMC_EnablePeripheral(id);
+}
+
+/**
+ * \brief Configures the transmitter of a SSC peripheral.
+ * \param ssc  Pointer to an SSC instance.
+ * \param tcmr Transmit Clock Mode Register value.
+ * \param tfmr Transmit Frame Mode Register value.
+ */
+void SSC_ConfigureTransmitter(Ssc *ssc, uint32_t tcmr, uint32_t tfmr)
+{
+	ssc->SSC_TCMR = tcmr;
+	ssc->SSC_TFMR = tfmr;
+}
+
+/**
+ * \brief Configures the receiver of a SSC peripheral.
+ * \param ssc  Pointer to an SSC instance.
+ * \param rcmr Receive Clock Mode Register value.
+ * \param rfmr Receive Frame Mode Register value.
+ */
+void SSC_ConfigureReceiver(Ssc *ssc, uint32_t rcmr, uint32_t rfmr)
+{
+	ssc->SSC_RCMR = rcmr;
+	ssc->SSC_RFMR = rfmr;
+}
+
+/**
+ * \brief Enables the transmitter of a SSC peripheral.
+ * \param ssc  Pointer to an SSC instance.
+ */
+void SSC_EnableTransmitter(Ssc *ssc)
+{
+	ssc->SSC_CR = SSC_CR_TXEN;
+}
+
+/**
+ * \brief Disables the transmitter of a SSC peripheral.
+ * \param ssc  Pointer to an SSC instance.
+ */
+void SSC_DisableTransmitter(Ssc *ssc)
+{
+	ssc->SSC_CR = SSC_CR_TXDIS;
+}
+
+/**
+ * \brief Enables the receiver of a SSC peripheral.
+ * \param ssc  Pointer to an SSC instance.
+ */
+void SSC_EnableReceiver(Ssc *ssc)
+{
+	ssc->SSC_CR = SSC_CR_RXEN;
+}
+
+/**
+ * \brief Disables the receiver of a SSC peripheral.
+ * \param ssc  Pointer to an SSC instance.
+ */
+void SSC_DisableReceiver(Ssc *ssc)
+{
+	ssc->SSC_CR = SSC_CR_RXDIS;
+}
+
+/**
+ * \brief Enables one or more interrupt sources of a SSC peripheral.
+ * \param ssc  Pointer to an SSC instance.
+ * \param sources Bitwise OR of selected interrupt sources.
+ */
+void SSC_EnableInterrupts(Ssc *ssc, uint32_t sources)
+{
+	ssc->SSC_IER = sources;
+}
+
+/**
+ * \brief Disables one or more interrupt sources of a SSC peripheral.
+ * \param ssc  Pointer to an SSC instance.
+ * \param sources Bitwise OR of selected interrupt sources.
+ */
+void SSC_DisableInterrupts(Ssc *ssc, uint32_t sources)
+{
+	ssc->SSC_IDR = sources;
+}
+
+/**
+ * \brief Sends one data frame through a SSC peripheral. If another frame is currently
+ * being sent, this function waits for the previous transfer to complete.
+ * \param ssc  Pointer to an SSC instance.
+ * \param frame Data frame to send.
+ */
+void SSC_Write(Ssc *ssc, uint32_t frame)
+{
+	while ((ssc->SSC_SR & SSC_SR_TXRDY) == 0);
+
+	ssc->SSC_THR = frame;
+}
+
+/**
+ * \brief Waits until one frame is received on a SSC peripheral, and returns it.
+ * \param ssc  Pointer to an SSC instance.
+ */
+uint32_t SSC_Read(Ssc *ssc)
+{
+	while ((ssc->SSC_SR & SSC_SR_RXRDY) == 0);
+
+	return ssc->SSC_RHR;
+}
+
+/**
+ * \brief Return 1 if one frame is received, 0 otherwise.
+ * \param ssc  Pointer to an SSC instance.
+ */
+uint8_t SSC_IsRxReady(Ssc *ssc)
+{
+	return ((ssc->SSC_SR & SSC_SR_RXRDY) > 0);
+}
+
Index: bsps/arm/atsam/contrib/libraries/libchip/source/supc.c
===================================================================
--- bsps/arm/atsam/contrib/libraries/libchip/source/supc.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libchip/source/supc.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,193 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+/*----------------------------------------------------------------------------
+ *        Headers
+ *----------------------------------------------------------------------------*/
+
+#include "chip.h"
+
+#include <assert.h>
+
+/*----------------------------------------------------------------------------
+ *        Local functions
+ *----------------------------------------------------------------------------*/
+
+/**
+ * \brief Select external 32K Crystal.
+ *
+ */
+
+void SUPC_SelectExtCrystal32K(void)
+{
+	PMC_EnableXT32KFME();
+
+	/* Select XTAL 32k instead of internal slow RC 32k for slow clock */
+	if ((SUPC->SUPC_SR & SUPC_SR_OSCSEL) != SUPC_SR_OSCSEL_CRYST) {
+		SUPC->SUPC_CR = SUPC_CR_KEY_PASSWD | SUPC_CR_XTALSEL_CRYSTAL_SEL;
+
+		while (!(SUPC->SUPC_SR & SUPC_SR_OSCSEL));
+	}
+}
+
+/**
+ * \brief VROFF asserts the vddcore_nreset and stops the voltage regulator
+ *
+ */
+void SUPC_DisableVoltageReg(void)
+{
+	SUPC->SUPC_CR |= SUPC_CR_KEY_PASSWD | SUPC_CR_VROFF;
+}
+
+/**
+ * \brief Configures supply monitor
+ *
+ */
+void SUPC_ConfigSupplyMonitor(uint32_t Config)
+{
+	SUPC->SUPC_SMMR = Config;
+}
+
+
+/**
+ * \brief Disables supply monitor
+ *
+ */
+void SUPC_DisableSupplyMonitor(void)
+{
+	SUPC->SUPC_SMMR = SUPC_SMMR_SMSMPL_SMD;
+}
+
+
+/**
+ * \brief Enables/Disables Brownout detector
+ *
+ */
+void SUPC_BrownoutDetectEnable(uint8_t enable)
+{
+	if (enable)
+		SUPC->SUPC_MR = (SUPC_MR_BODDIS_ENABLE | SUPC_MR_KEY_PASSWD);
+	else
+		SUPC->SUPC_MR = (SUPC_MR_BODDIS_DISABLE | SUPC_MR_KEY_PASSWD);
+}
+
+/**
+ * \brief Enables Brownout Detector Reset
+ *
+ */
+void SUPC_BrownoutResetEnable(void)
+{
+	SUPC->SUPC_MR = (SUPC_MR_BODRSTEN_ENABLE | SUPC_MR_KEY_PASSWD);
+}
+
+
+/**
+ * \brief Enables/Disables Sram in backup mode
+ *
+ */
+void SUPC_SramBackupMode(uint8_t enable)
+{
+	if (enable)
+		SUPC->SUPC_MR = ((1 << 17) | SUPC_MR_KEY_PASSWD);
+	else
+		SUPC->SUPC_MR = ((0 << 17) | SUPC_MR_KEY_PASSWD);
+}
+
+/**
+ * \brief Bypass external 32.768KHz oscillator
+ *
+ */
+void SUPC_BypassXtal32KOsc(void)
+{
+	SUPC->SUPC_MR = (SUPC_MR_OSCBYPASS_BYPASS | SUPC_MR_KEY_PASSWD);
+}
+
+
+/**
+ * \brief Enables/Disables Wakeup mode
+ *
+ */
+void SUPC_EnablesWakeupMode(uint32_t Regs, uint8_t enable)
+{
+	if (enable)
+		SUPC->SUPC_WUMR |= Regs;
+	else
+		SUPC->SUPC_WUMR &= ~(uint32_t)Regs;
+}
+
+/**
+ * \brief Configure Wakeup denounce period
+ *
+ */
+void SUPC_SetWakeupDebounce(uint8_t period)
+{
+	SUPC->SUPC_WUMR |= ((period << SUPC_WUMR_WKUPDBC_Pos) & SUPC_WUMR_WKUPDBC_Msk);
+}
+
+/**
+ * \brief Configure Low-power denounce period
+ *
+ */
+void SUPC_SetLowPowerDebounce(uint8_t period)
+{
+	SUPC->SUPC_WUMR |= ((period << SUPC_WUMR_LPDBC_Pos) & SUPC_WUMR_LPDBC_Msk);
+}
+
+
+/**
+ * \brief Enables/Disables Wakeup Inputs
+ *
+ */
+void SUPC_EnablesWakeupInput(uint32_t Input, uint8_t enable)
+{
+	if (enable)
+		SUPC->SUPC_WUIR |= Input;
+	else
+		SUPC->SUPC_WUIR &= ~(uint32_t)Input;
+}
+
+/**
+ * \brief Checks if Crystal oscillator is selected as a slow clock
+ */
+
+uint8_t SUPC_IsSlowClkExtCrystal32K(void)
+{
+	return ((SUPC->SUPC_SR & SUPC_SR_OSCSEL) >> 7);
+}
+
+/**
+ * \brief Checks if Crystal oscillator is selected as a slow clock
+ */
+
+uint8_t SUPC_Read_Status(uint32_t status)
+{
+	return (SUPC->SUPC_SR & status);
+}
+
+
Index: bsps/arm/atsam/contrib/libraries/libchip/source/tc.c
===================================================================
--- bsps/arm/atsam/contrib/libraries/libchip/source/tc.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libchip/source/tc.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,213 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+/** \addtogroup tc_module
+ * The TC driver provides the Interface to configure the Timer Counter (TC).
+ *
+ *  \section Usage
+ * <ul>
+ *  <li> Optionally, use TC_FindMckDivisor() to let the program find the best
+ *     TCCLKS field value automatically.</li>
+ *  <li> Configure a Timer Counter in the desired mode using TC_Configure().</li>
+ *  <li> Start or stop the timer clock using TC_Start() and TC_Stop().</li>
+ *
+ * </ul>
+ * For more accurate information, please look at the TC section of the Datasheet.
+ *
+ * Related files :\n
+ * \ref tc.c\n
+ * \ref tc.h.\n
+*/
+
+/**
+*  \file
+*
+*  \section Purpose
+*
+*  Interface for configuring and using Timer Counter (TC) peripherals.
+*
+*  \section Usage
+*  -# Optionally, use TC_FindMckDivisor() to let the program find the best
+*     TCCLKS field value automatically.
+*  -# Configure a Timer Counter in the desired mode using TC_Configure().
+*  -# Start or stop the timer clock using TC_Start() and TC_Stop().
+*/
+
+/**
+ * \file
+ *
+ * Implementation of Timer Counter (TC).
+ *
+ */
+
+/*------------------------------------------------------------------------------
+ *         Headers
+ *-----------------------------------------------------------------------------*/
+
+#ifndef __rtems__
+#include "board.h"
+#else /* __rtems__ */
+#include <chip.h>
+#endif /* __rtems__ */
+
+#include <assert.h>
+
+/*------------------------------------------------------------------------------
+ *         Global functions
+ *----------------------------------------------------------------------------*/
+
+/**
+ * \brief Configures a Timer Counter Channel
+ *
+ * Configures a Timer Counter to operate in the given mode. Timer is stopped
+ * after configuration and must be restarted with TC_Start(). All the
+ * interrupts of the timer are also disabled.
+ *
+ * \param pTc  Pointer to a Tc instance.
+ * \param channel Channel number.
+ * \param mode  Operating mode (TC_CMR value).
+ */
+extern void TC_Configure(Tc *pTc, uint32_t dwChannel, uint32_t dwMode)
+{
+	TcChannel *pTcCh;
+
+	assert(dwChannel < (sizeof(pTc->TC_CHANNEL) / sizeof(
+							 pTc->TC_CHANNEL[0])));
+	pTcCh = pTc->TC_CHANNEL + dwChannel;
+
+	/*  Disable TC clock */
+	pTcCh->TC_CCR = TC_CCR_CLKDIS;
+
+	/*  Disable interrupts */
+	pTcCh->TC_IDR = 0xFFFFFFFF;
+
+	/*  Clear status register */
+	pTcCh->TC_SR;
+
+	/*  Set mode */
+	pTcCh->TC_CMR = dwMode;
+}
+
+/**
+ * \brief Reset and Start the TC Channel
+ *
+ * Enables the timer clock and performs a software reset to start the counting.
+ *
+ * \param pTc  Pointer to a Tc instance.
+ * \param dwChannel Channel number.
+ */
+extern void TC_Start(Tc *pTc, uint32_t dwChannel)
+{
+	TcChannel *pTcCh;
+
+	assert(dwChannel < (sizeof(pTc->TC_CHANNEL) / sizeof(
+							 pTc->TC_CHANNEL[0])));
+
+	pTcCh = pTc->TC_CHANNEL + dwChannel;
+	pTcCh->TC_CCR = TC_CCR_CLKEN | TC_CCR_SWTRG;
+}
+
+/**
+ * \brief Stop TC Channel
+ *
+ * Disables the timer clock, stopping the counting.
+ *
+ * \param pTc     Pointer to a Tc instance.
+ * \param dwChannel Channel number.
+ */
+extern void TC_Stop(Tc *pTc, uint32_t dwChannel)
+{
+	TcChannel *pTcCh;
+
+	assert(dwChannel < (sizeof(pTc->TC_CHANNEL) / sizeof(
+							 pTc->TC_CHANNEL[0])));
+
+	pTcCh = pTc->TC_CHANNEL + dwChannel;
+	pTcCh->TC_CCR = TC_CCR_CLKDIS;
+}
+
+/**
+ * \brief Find best MCK divisor
+ *
+ * Finds the best MCK divisor given the timer frequency and MCK. The result
+ * is guaranteed to satisfy the following equation:
+ * \code
+ *   (MCK / (DIV * 65536)) <= freq <= (MCK / DIV)
+ * \endcode
+ * with DIV being the highest possible value.
+ *
+ * \param dwFreq  Desired timer frequency.
+ * \param dwMCk  Master clock frequency.
+ * \param dwDiv  Divisor value.
+ * \param dwTcClks  TCCLKS field value for divisor.
+ * \param dwBoardMCK  Board clock frequency.
+ *
+ * \return 1 if a proper divisor has been found, otherwise 0.
+ */
+extern uint32_t TC_FindMckDivisor(uint32_t dwFreq, uint32_t dwMCk,
+								   uint32_t *dwDiv, uint32_t *dwTcClks, uint32_t dwBoardMCK)
+{
+	/*
+	TCCLKS:
+	    0 - PCK6: default source - Slow Clock; update according to actual case
+	    4 - SLCK: (slow clock) is either "Embedded 32kHz RC Oscillator" or
+	              "32768Hz Crystal Oscillator"
+	*/
+	const uint32_t adwDivisors[5] = { BOARD_MCK / 32768, 8, 32, 128, BOARD_MCK / 32768 };
+
+	uint32_t dwIndex = 0;
+	dwBoardMCK = dwBoardMCK;
+
+	/*  Satisfy lower bound */
+	while (dwFreq < ((dwMCk / adwDivisors[dwIndex]) / 65536)) {
+		dwIndex++;
+
+		/*  If no divisor can be found, return 0 */
+		if (dwIndex == (sizeof(adwDivisors) / sizeof(adwDivisors[0])))
+			return 0;
+	}
+
+	/*  Try to maximize DIV while satisfying upper bound */
+	while (dwIndex < 4) {
+		if (dwFreq > (dwMCk / adwDivisors[dwIndex + 1]))
+			break;
+
+		dwIndex++;
+	}
+
+	/*  Store results */
+	if (dwDiv)
+		*dwDiv = adwDivisors[dwIndex];
+
+	if (dwTcClks)
+		*dwTcClks = dwIndex;
+
+	return 1;
+}
+
Index: bsps/arm/atsam/contrib/libraries/libchip/source/trng.c
===================================================================
--- bsps/arm/atsam/contrib/libraries/libchip/source/trng.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libchip/source/trng.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,122 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+/** \addtogroup rtng_module Working with RTNG
+ * \ingroup peripherals_module
+ * The TRNG driver provides the interface to configure and use the TRNG
+ * peripheral.\n
+ *
+ * The True Random Number Generator (TRNG) passes the American NIST Special
+ * Publication 800-22 and Diehard Random Tests Suites. As soon as the TRNG is
+ * enabled (TRNG_Enable()),  the generator provides one 32-bit value every 84
+ * clock cycles.  Interrupt trng_int can be enabled through TRNG_EnableIt()
+ * (respectively disabled in TRNG_IDR).
+ * This interrupt is set when a new random value is available and is cleared
+ * when the status  register is read (TRNG_SR register). The flag DATRDY of
+ * the status register (TRNG_ISR) is set when the random data is ready to be
+ * read out on the 32-bit output data through TRNG_GetRandData().
+ *
+ * For more accurate information, please look at the SHA section of the
+ * Datasheet.
+ *
+ * Related files :\n
+ * \ref trng.c\n
+ * \ref trng.h\n
+ */
+/*@{*/
+/*@}*/
+
+/**
+ * \file
+ *
+ * Implementation of True Random Number Generator (TRNG)
+ *
+ */
+
+/*----------------------------------------------------------------------------
+ *        Headers
+ *----------------------------------------------------------------------------*/
+
+#include "chip.h"
+
+/*----------------------------------------------------------------------------
+ *        Exported functions
+ *----------------------------------------------------------------------------*/
+
+/**
+ * \brief Enables the TRNG to provide Random Values.
+ * \param key  This key is to be written when the ENABLE bit is set.
+ */
+void TRNG_Enable(void)
+{
+	TRNG->TRNG_CR = TRNG_CR_ENABLE | TRNG_CR_KEY_PASSWD;
+}
+
+/**
+ * \brief Disables the TRNG to provide Random Values.
+ * \param key  This key is to be written when the DISABLE bit is set.
+ */
+void TRNG_Disable(void)
+{
+	TRNG->TRNG_CR = TRNG_CR_KEY_PASSWD;
+}
+
+/**
+ * \brief Data Ready Interrupt enable.
+ */
+void TRNG_EnableIt(void)
+{
+	TRNG->TRNG_IER = TRNG_IER_DATRDY;
+}
+
+/**
+ * \brief Data Ready Interrupt Disable.
+ */
+void TRNG_DisableIt(void)
+{
+	TRNG->TRNG_IDR = TRNG_IDR_DATRDY;
+}
+
+/**
+ * \brief Get the current status register of the given TRNG peripheral.
+ * \return  TRNG status register.
+ */
+uint32_t TRNG_GetStatus(void)
+{
+	return TRNG->TRNG_ISR;
+}
+
+/**
+ * \brief Get the  32-bit Output Data from TRNG peripheral.
+ * \return  TRNG output data.
+ */
+uint32_t TRNG_GetRandData(void)
+{
+	return TRNG->TRNG_ODATA;
+}
Index: bsps/arm/atsam/contrib/libraries/libchip/source/twi.c
===================================================================
--- bsps/arm/atsam/contrib/libraries/libchip/source/twi.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libchip/source/twi.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,382 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+/** \addtogroup twi_module Working with TWI
+ *  \ingroup peripherals_module
+ * The TWI driver provides the interface to configure and use the TWI
+ * peripheral.
+ *
+ * \section Usage
+ * <ul>
+ * <li> Configures a TWI peripheral to operate in master mode, at the given
+ * frequency (in Hz) using TWI_Configure(). </li>
+ * <li> Sends a STOP condition on the TWI using TWI_Stop().</li>
+ * <li> Starts a read operation on the TWI bus with the specified slave using
+ * TWI_StartRead(). Data must then be read using TWI_ReadByte() whenever
+ * a byte is available (poll using TWI_ByteReceived()).</li>
+ * <li> Starts a write operation on the TWI to access the selected slave using
+ * TWI_StartWrite(). A byte of data must be provided to start the write;
+ * other bytes are written next.</li>
+ * <li> Sends a byte of data to one of the TWI slaves on the bus using
+ * TWI_WriteByte().
+ * This function must be called once before TWI_StartWrite() with the first
+ * byte of data
+ * to send, then it shall be called repeatedly after that to send the
+ * remaining bytes.</li>
+ * <li> Check if a byte has been received and can be read on the given TWI
+ * peripheral using TWI_ByteReceived().<
+ * Check if a byte has been sent using TWI_ByteSent().</li>
+ * <li> Check if the current transmission is complete (the STOP has been sent)
+ * using TWI_TransferComplete().</li>
+ * <li> Enables & disable the selected interrupts sources on a TWI peripheral
+ * using TWI_EnableIt() and TWI_DisableIt().</li>
+ * <li> Get current status register of the given TWI peripheral using
+ * TWI_GetStatus(). Get current status register of the given TWI peripheral, but
+ * masking interrupt sources which are not currently enabled using
+ * TWI_GetMaskedStatus().</li>
+ * </ul>
+ * For more accurate information, please look at the TWI section of the
+ * Datasheet.
+ *
+ * Related files :\n
+ * \ref twi.c\n
+ * \ref twi.h.\n
+ */
+/*@{*/
+/*@}*/
+
+/**
+ * \file
+ *
+ * Implementation of Two Wire Interface (TWI).
+ *
+ */
+
+/*----------------------------------------------------------------------------
+ *        Headers
+ *----------------------------------------------------------------------------*/
+
+#include "chip.h"
+
+#include <assert.h>
+
+#define TWIHS_IT    (TWIHS_IER_TXCOMP | TWIHS_IER_TXCOMP | TWIHS_IER_RXRDY \
+					  | TWIHS_IER_TXRDY | TWIHS_IER_SVACC | TWIHS_IER_GACC | \
+					  TWIHS_IER_OVRE | TWIHS_IER_UNRE | TWIHS_IER_NACK | \
+					  TWIHS_IER_ARBLST | TWIHS_IER_SCL_WS | TWIHS_IER_EOSACC | \
+					  TWIHS_IER_MCACK | TWIHS_IER_TOUT | TWIHS_IER_PECERR |\
+					  TWIHS_IER_SMBDAM | TWIHS_IER_SMBHHM)
+
+
+/** variable for control thether or not to set both START and STOP
+  * In single data byte master read, the START and STOP must both be set */
+uint32_t twi_send_stop = 0;
+
+/*----------------------------------------------------------------------------
+ *        Exported functions
+ *----------------------------------------------------------------------------*/
+
+/**
+ * \brief Configures a TWI peripheral to operate in master mode, at the given
+ * frequency (in Hz). The duty cycle of the TWI clock is set to 50%.
+ * \param pTwi  Pointer to an Twihs instance.
+ * \param twck  Desired TWI clock frequency.
+ * \param mck  Master clock frequency.
+ */
+void TWI_ConfigureMaster(Twihs *pTwi, uint32_t dwTwCk, uint32_t dwMCk)
+{
+	uint32_t dwCkDiv = 0;
+	uint32_t dwClDiv;
+	uint32_t dwOk = 0;
+
+	TRACE_DEBUG("TWI_ConfigureMaster()\n\r");
+	assert(pTwi);
+
+	/* Reset the TWI */
+	pTwi->TWIHS_CR = TWIHS_CR_SWRST;
+
+	/* Configure clock */
+	while (!dwOk) {
+		dwClDiv = ((dwMCk / (2 * dwTwCk)) - 4) / (1 << dwCkDiv);
+
+		if (dwClDiv <= 255)
+			dwOk = 1;
+		else
+			dwCkDiv++;
+	}
+
+	assert(dwCkDiv < 8);
+	TRACE_DEBUG("Using CKDIV = %u and CLDIV/CHDIV = %u\n\r", dwCkDiv, dwClDiv);
+
+	pTwi->TWIHS_CWGR = (dwCkDiv << 16) | (dwClDiv << 8) | dwClDiv;
+
+	/* TWI Slave Mode Disabled. */
+	pTwi->TWIHS_CR = TWIHS_CR_SVDIS;
+
+	/* Set master mode */
+	pTwi->TWIHS_CR = TWIHS_CR_MSEN;
+}
+
+/**
+ * \brief Configures a TWI peripheral to operate in slave mode.
+ * \param pTwi  Pointer to an Twihs instance.
+ * \param slaveAddress Slave address.
+ */
+void TWI_ConfigureSlave(Twihs *pTwi, uint8_t slaveAddress)
+{
+	/* TWI software reset */
+	pTwi->TWIHS_CR = TWIHS_CR_SWRST;
+
+	/* Configure slave address. */
+	pTwi->TWIHS_SMR = TWIHS_SMR_SADR(slaveAddress);
+
+	/* TWI Master Mode Disabled*/
+	pTwi->TWIHS_CR = TWIHS_CR_MSDIS;
+
+	/* SVEN: TWI Slave Mode Enabled */
+	pTwi->TWIHS_CR = TWIHS_CR_SVEN;
+
+	assert((pTwi->TWIHS_CR & TWIHS_CR_SVDIS) != TWIHS_CR_SVDIS);
+}
+
+/**
+ * \brief Sends a STOP condition on the TWI.
+ * \param pTwi  Pointer to an Twihs instance.
+ */
+void TWI_Stop(Twihs *pTwi)
+{
+	assert(pTwi != NULL);
+
+	pTwi->TWIHS_CR = TWIHS_CR_STOP;
+}
+
+/**
+ * \brief Starts a read operation on the TWI bus with the specified slave, it
+ * returns immediately. Data must then be read using TWI_ReadByte() whenever a
+ * byte is available (poll using TWI_ByteReceived()).
+ * \param pTwi  Pointer to an Twihs instance.
+ * \param address  Slave address on the bus.
+ * \param iaddress  Optional internal address bytes.
+ * \param isize  Number of internal address bytes.
+ */
+void TWI_StartRead(
+	Twihs *pTwi,
+	uint8_t address,
+	uint32_t iaddress,
+	uint8_t isize)
+{
+	assert(pTwi != NULL);
+	assert((address & 0x80) == 0);
+	assert((iaddress & 0xFF000000) == 0);
+	assert(isize < 4);
+
+	/* Set slave address and number of internal address bytes. */
+	pTwi->TWIHS_MMR = 0;
+	pTwi->TWIHS_MMR = (isize << 8) | TWIHS_MMR_MREAD | (address << 16);
+
+	/* Set internal address bytes */
+	pTwi->TWIHS_IADR = 0;
+	pTwi->TWIHS_IADR = iaddress;
+
+	/* Send START condition */
+	if (0 == twi_send_stop)
+		pTwi->TWIHS_CR = TWIHS_CR_START;
+	else {
+		twi_send_stop = 0;
+		pTwi->TWIHS_CR = TWIHS_CR_START | TWIHS_CR_STOP;
+	}
+}
+
+/**
+ * \brief Reads a byte from the TWI bus. The read operation must have been started
+ * using TWI_StartRead() and a byte must be available (check with TWI_ByteReceived()).
+ * \param pTwi  Pointer to an Twihs instance.
+ * \return byte read.
+ */
+uint8_t TWI_ReadByte(Twihs *pTwi)
+{
+	assert(pTwi != NULL);
+
+	return pTwi->TWIHS_RHR;
+}
+
+/**
+ * \brief Sends a byte of data to one of the TWI slaves on the bus.
+ * \note This function must be called once before TWI_StartWrite() with
+ * the first byte of data  to send, then it shall be called repeatedly
+ * after that to send the remaining bytes.
+ * \param pTwi  Pointer to an Twihs instance.
+ * \param byte  Byte to send.
+ */
+void TWI_WriteByte(Twihs *pTwi, uint8_t byte)
+{
+	assert(pTwi != NULL);
+
+	pTwi->TWIHS_THR = byte;
+}
+
+/**
+ * \brief Starts a write operation on the TWI to access the selected slave, then
+ *  returns immediately. A byte of data must be provided to start the write;
+ * other bytes are written next.
+ * after that to send the remaining bytes.
+ * \param pTwi  Pointer to an Twihs instance.
+ * \param address  Address of slave to acccess on the bus.
+ * \param iaddress  Optional slave internal address.
+ * \param isize  Number of internal address bytes.
+ * \param byte  First byte to send.
+ */
+void TWI_StartWrite(
+	Twihs *pTwi,
+	uint8_t address,
+	uint32_t iaddress,
+	uint8_t isize,
+	uint8_t byte)
+{
+	assert(pTwi != NULL);
+	assert((address & 0x80) == 0);
+	assert((iaddress & 0xFF000000) == 0);
+	assert(isize < 4);
+
+	/* Set slave address and number of internal address bytes. */
+	pTwi->TWIHS_MMR = 0;
+	pTwi->TWIHS_MMR = (isize << 8) | (address << 16);
+
+	/* Set internal address bytes. */
+	pTwi->TWIHS_IADR = 0;
+	pTwi->TWIHS_IADR = iaddress;
+
+	/* Write first byte to send.*/
+	TWI_WriteByte(pTwi, byte);
+}
+
+/**
+ * \brief Check if a byte have been received from TWI.
+ * \param pTwi  Pointer to an Twihs instance.
+ * \return 1 if a byte has been received and can be read on the given TWI
+ * peripheral; otherwise, returns 0. This function resets the status register.
+ */
+uint8_t TWI_ByteReceived(Twihs *pTwi)
+{
+	return ((pTwi->TWIHS_SR & TWIHS_SR_RXRDY) == TWIHS_SR_RXRDY);
+}
+
+/**
+ * \brief Check if a byte have been sent to TWI.
+ * \param pTwi  Pointer to an Twihs instance.
+ * \return 1 if a byte has been sent  so another one can be stored for
+ * transmission; otherwise returns 0. This function clears the status register.
+ */
+uint8_t TWI_ByteSent(Twihs *pTwi)
+{
+	return ((pTwi->TWIHS_SR & TWIHS_SR_TXRDY) == TWIHS_SR_TXRDY);
+}
+
+/**
+ * \brief Check if current transmission is completed.
+ * \param pTwi  Pointer to an Twihs instance.
+ * \return  1 if the current transmission is complete (the STOP has been sent);
+ * otherwise returns 0.
+ */
+uint8_t TWI_TransferComplete(Twihs *pTwi)
+{
+	return ((pTwi->TWIHS_SR & TWIHS_SR_TXCOMP) == TWIHS_SR_TXCOMP);
+}
+
+/**
+ * \brief Enables the selected interrupts sources on a TWI peripheral.
+ * \param pTwi  Pointer to an Twihs instance.
+ * \param sources  Bitwise OR of selected interrupt sources.
+ */
+void TWI_EnableIt(Twihs *pTwi, uint32_t sources)
+{
+	assert(pTwi != NULL);
+	assert((sources & TWIHS_IT));
+
+	pTwi->TWIHS_IER = sources;
+}
+
+/**
+ * \brief Disables the selected interrupts sources on a TWI peripheral.
+ * \param pTwi  Pointer to an Twihs instance.
+ * \param sources  Bitwise OR of selected interrupt sources.
+ */
+void TWI_DisableIt(Twihs *pTwi, uint32_t sources)
+{
+	assert(pTwi != NULL);
+	assert(sources & TWIHS_IT);
+
+	pTwi->TWIHS_IDR = sources;
+}
+
+/**
+ * \brief Get the current status register of the given TWI peripheral.
+ * \note This resets the internal value of the status register, so further
+ * read may yield different values.
+ * \param pTwi  Pointer to an Twihs instance.
+ * \return  TWI status register.
+ */
+uint32_t TWI_GetStatus(Twihs *pTwi)
+{
+	assert(pTwi != NULL);
+
+	return pTwi->TWIHS_SR;
+}
+
+/**
+ * \brief Returns the current status register of the given TWI peripheral, but
+ * masking interrupt sources which are not currently enabled.
+ * \note This resets the internal value of the status register, so further
+ * read may yield different values.
+ * \param pTwi  Pointer to an Twihs instance.
+ */
+uint32_t TWI_GetMaskedStatus(Twihs *pTwi)
+{
+	uint32_t status;
+
+	assert(pTwi != NULL);
+
+	status = pTwi->TWIHS_SR;
+	status &= pTwi->TWIHS_IMR;
+
+	return status;
+}
+
+/**
+ * \brief  Sends a STOP condition. STOP Condition is sent just after completing
+ *  the current byte transmission in master read mode.
+ * \param pTwi  Pointer to an Twihs instance.
+ */
+void TWI_SendSTOPCondition(Twihs *pTwi)
+{
+	assert(pTwi != NULL);
+
+	pTwi->TWIHS_CR |= TWIHS_CR_STOP;
+}
+
Index: bsps/arm/atsam/contrib/libraries/libchip/source/twid.c
===================================================================
--- bsps/arm/atsam/contrib/libraries/libchip/source/twid.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libchip/source/twid.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,752 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+/*----------------------------------------------------------------------------
+ *        Headers
+ *----------------------------------------------------------------------------*/
+#include "chip.h"
+
+#include <assert.h>
+
+/*----------------------------------------------------------------------------
+ *        Definition
+ *----------------------------------------------------------------------------*/
+#define TWITIMEOUTMAX 400
+static uint32_t dmaWriteChannel, dmaReadChannel;
+
+extern uint32_t twi_send_stop;
+
+/*----------------------------------------------------------------------------
+ *        Types
+ *----------------------------------------------------------------------------*/
+
+/** TWI driver callback function.*/
+typedef void (*TwiCallback)(Async *);
+
+/** \brief TWI asynchronous transfer descriptor.*/
+typedef struct _AsyncTwi {
+
+	/** Asynchronous transfer status. */
+	volatile uint8_t status;
+	/** Callback function to invoke when transfer completes or fails.*/
+	TwiCallback callback;
+	/** Pointer to the data buffer.*/
+	uint8_t *pData;
+	/** Total number of bytes to transfer.*/
+	uint32_t num;
+	/** Number of already transferred bytes.*/
+	uint32_t transferred;
+
+} AsyncTwi;
+
+/**
+ * \brief Initializes a TWI DMA Read channel.
+ */
+static void TWID_DmaInitializeRead(TwihsDma *pTwiXdma)
+{
+	/* Allocate a XDMA channel, Read accesses into TWI_THR */
+	dmaReadChannel = XDMAD_AllocateChannel(pTwiXdma->pTwiDma, pTwiXdma->Twi_id,
+											XDMAD_TRANSFER_MEMORY);
+
+	if (dmaReadChannel == XDMAD_ALLOC_FAILED)
+		printf("-E- Can't allocate XDMA channel\n\r");
+
+	XDMAD_PrepareChannel(pTwiXdma->pTwiDma, dmaReadChannel);
+}
+
+/**
+ * \brief Initializes a TWI DMA write channel.
+ */
+static void TWID_DmaInitializeWrite(TwihsDma *pTwiXdma)
+{
+	/* Allocate a XDMA channel, Write accesses into TWI_THR */
+	dmaWriteChannel = XDMAD_AllocateChannel(pTwiXdma->pTwiDma,
+					  XDMAD_TRANSFER_MEMORY,
+					  pTwiXdma->Twi_id);
+
+	if (dmaWriteChannel == XDMAD_ALLOC_FAILED)
+		printf("-E- Can't allocate XDMA channel\n\r");
+
+	XDMAD_PrepareChannel(pTwiXdma->pTwiDma, dmaWriteChannel);
+}
+
+/**
+ * \brief Configure xDMA write linker list for TWI transfer.
+ */
+static uint8_t TWID_XdmaConfigureWrite(TwihsDma *pTwiXdma, uint8_t *buf,
+									   uint32_t len)
+{
+	uint32_t xdmaCndc, Thr, xdmaInt;
+	sXdmadCfg xdmadTxCfg;
+
+	Thr = (uint32_t) & (TWIHS0->TWIHS_THR);
+
+	if (pTwiXdma->Twi_id == ID_TWIHS1)
+		Thr = (uint32_t) & (TWIHS1->TWIHS_THR);
+
+	if (pTwiXdma->Twi_id == ID_TWIHS2)
+		Thr = (uint32_t) & (TWIHS2->TWIHS_THR);
+
+	xdmadTxCfg.mbr_ubc =      XDMA_UBC_NVIEW_NDV0 |
+							  XDMA_UBC_NDE_FETCH_DIS |
+							  XDMA_UBC_NSEN_UPDATED |  len;
+
+	xdmadTxCfg.mbr_sa = (uint32_t)buf;
+	xdmadTxCfg.mbr_da = Thr;
+	xdmadTxCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN |
+						 XDMAC_CC_MBSIZE_SINGLE |
+						 XDMAC_CC_DSYNC_MEM2PER |
+						 XDMAC_CC_CSIZE_CHK_1 |
+						 XDMAC_CC_DWIDTH_BYTE |
+						 XDMAC_CC_SIF_AHB_IF1 |
+						 XDMAC_CC_DIF_AHB_IF1 |
+						 XDMAC_CC_SAM_INCREMENTED_AM |
+						 XDMAC_CC_DAM_FIXED_AM |
+						 XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber(
+											pTwiXdma->Twi_id, XDMAD_TRANSFER_TX));
+
+	xdmadTxCfg.mbr_bc = 0;
+	xdmadTxCfg.mbr_sus = 0;
+	xdmadTxCfg.mbr_dus = 0;
+	xdmaCndc = 0;
+
+	xdmaInt =  (XDMAC_CIE_BIE |
+				XDMAC_CIE_RBIE  |
+				XDMAC_CIE_WBIE);
+
+	if (XDMAD_ConfigureTransfer(pTwiXdma->pTwiDma, dmaWriteChannel,
+								 &xdmadTxCfg, xdmaCndc, 0, xdmaInt))
+		return USARTD_ERROR;
+
+	return 0;
+}
+
+
+/**
+ * \brief Configure xDMA read linker list for TWI transfer.
+ */
+static uint8_t TWID_XdmaConfigureRead(TwihsDma *pTwiXdma, uint8_t *buf,
+									  uint32_t len)
+{
+	uint32_t xdmaCndc, Rhr, xdmaInt;
+	sXdmadCfg xdmadRxCfg;
+
+	Rhr = (uint32_t) & (TWIHS0->TWIHS_RHR);
+
+	if (pTwiXdma->Twi_id == ID_TWIHS1)
+		Rhr = (uint32_t) & (TWIHS1->TWIHS_RHR);
+
+	if (pTwiXdma->Twi_id == ID_TWIHS2)
+		Rhr = (uint32_t) & (TWIHS2->TWIHS_RHR);
+
+	xdmadRxCfg.mbr_ubc = XDMA_UBC_NVIEW_NDV0 |
+						 XDMA_UBC_NDE_FETCH_DIS |
+						 XDMA_UBC_NDEN_UPDATED |
+						 len;
+
+	xdmadRxCfg.mbr_da = (uint32_t)buf;
+	xdmadRxCfg.mbr_sa = Rhr;
+
+	xdmadRxCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN |
+						 XDMAC_CC_MBSIZE_SINGLE |
+						 XDMAC_CC_DSYNC_PER2MEM |
+						 XDMAC_CC_CSIZE_CHK_1 |
+						 XDMAC_CC_DWIDTH_BYTE |
+						 XDMAC_CC_SIF_AHB_IF1 |
+						 XDMAC_CC_DIF_AHB_IF1 |
+						 XDMAC_CC_SAM_FIXED_AM |
+						 XDMAC_CC_DAM_INCREMENTED_AM |
+						 XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber(
+											pTwiXdma->Twi_id , XDMAD_TRANSFER_RX));
+
+	xdmadRxCfg.mbr_bc = 0;
+	xdmadRxCfg.mbr_sus = 0;
+	xdmadRxCfg.mbr_dus = 0;
+	xdmaCndc = 0;
+	xdmaInt =  (XDMAC_CIE_BIE |
+				XDMAC_CIE_RBIE  |
+				XDMAC_CIE_WBIE);
+
+	if (XDMAD_ConfigureTransfer(pTwiXdma->pTwiDma, dmaReadChannel,
+								 &xdmadRxCfg, xdmaCndc, 0, xdmaInt))
+		return 1;
+
+	return 0;
+}
+
+/*----------------------------------------------------------------------------
+ *        Global functions
+ *----------------------------------------------------------------------------*/
+
+/**
+ * \brief Returns 1 if the given transfer has ended; otherwise returns 0.
+ * \param pAsync  Pointer to an Async instance.
+ */
+uint32_t ASYNC_IsFinished(Async *pAsync)
+{
+	return (pAsync->status != ASYNC_STATUS_PENDING);
+}
+
+/**
+ * \brief Initializes a TWI driver instance, using the given TWI peripheral.
+ * \note The peripheral must have been initialized properly before calling this
+ * function.
+ * \param pTwid  Pointer to the Twid instance to initialize.
+ * \param pTwi  Pointer to the TWI peripheral to use.
+ */
+void TWID_Initialize(Twid *pTwid, Twihs *pTwi)
+{
+	TRACE_DEBUG("TWID_Initialize()\n\r");
+	assert(pTwid != NULL);
+	assert(pTwi != NULL);
+
+	/* Initialize driver. */
+	pTwid->pTwi = pTwi;
+	pTwid->pTransfer = 0;
+}
+
+/**
+ * \brief Interrupt handler for a TWI peripheral. Manages asynchronous transfer
+ * occurring on the bus. This function MUST be called by the interrupt service
+ * routine of the TWI peripheral if asynchronous read/write are needed.
+ * \param pTwid  Pointer to a Twid instance.
+ */
+void TWID_Handler(Twid *pTwid)
+{
+	uint8_t status;
+	AsyncTwi *pTransfer;
+	Twihs *pTwi;
+
+	assert(pTwid != NULL);
+
+	pTransfer = (AsyncTwi *)pTwid->pTransfer;
+	assert(pTransfer != NULL);
+	pTwi = pTwid->pTwi;
+	assert(pTwi != NULL);
+
+	/* Retrieve interrupt status */
+	status = TWI_GetMaskedStatus(pTwi);
+
+	/* Byte received */
+	if (TWI_STATUS_RXRDY(status)) {
+
+		pTransfer->pData[pTransfer->transferred] = TWI_ReadByte(pTwi);
+		pTransfer->transferred++;
+
+		/* check for transfer finish */
+		if (pTransfer->transferred == pTransfer->num) {
+
+			TWI_DisableIt(pTwi, TWIHS_IDR_RXRDY);
+			TWI_EnableIt(pTwi, TWIHS_IER_TXCOMP);
+		}
+		/* Last byte? */
+		else if (pTransfer->transferred == (pTransfer->num - 1))
+
+			TWI_Stop(pTwi);
+	}
+	/* Byte sent*/
+	else if (TWI_STATUS_TXRDY(status)) {
+
+		/* Transfer finished ? */
+		if (pTransfer->transferred == pTransfer->num) {
+
+			TWI_DisableIt(pTwi, TWIHS_IDR_TXRDY);
+			TWI_EnableIt(pTwi, TWIHS_IER_TXCOMP);
+			TWI_SendSTOPCondition(pTwi);
+		}
+		/* Bytes remaining */
+		else {
+
+			TWI_WriteByte(pTwi, pTransfer->pData[pTransfer->transferred]);
+			pTransfer->transferred++;
+		}
+	}
+	/* Transfer complete*/
+	else if (TWI_STATUS_TXCOMP(status)) {
+
+		TWI_DisableIt(pTwi, TWIHS_IDR_TXCOMP);
+		pTransfer->status = 0;
+
+		if (pTransfer->callback)
+			pTransfer->callback((Async *) pTransfer);
+
+		pTwid->pTransfer = 0;
+	}
+}
+
+/**
+ * \brief Asynchronously reads data from a slave on the TWI bus. An optional
+ * callback function is triggered when the transfer is complete.
+ * \param pTwid  Pointer to a Twid instance.
+ * \param address  TWI slave address.
+ * \param iaddress  Optional slave internal address.
+ * \param isize  Internal address size in bytes.
+ * \param pData  Data buffer for storing received bytes.
+ * \param num  Number of bytes to read.
+ * \param pAsync  Asynchronous transfer descriptor.
+ * \return 0 if the transfer has been started; otherwise returns a TWI error code.
+ */
+uint8_t TWID_Read(
+	Twid *pTwid,
+	uint8_t address,
+	uint32_t iaddress,
+	uint8_t isize,
+	uint8_t *pData,
+	uint32_t num,
+	Async *pAsync)
+{
+	Twihs *pTwi;
+	AsyncTwi *pTransfer;
+	uint32_t startTime;
+	assert(pTwid != NULL);
+	pTwi = pTwid->pTwi;
+	pTransfer = (AsyncTwi *) pTwid->pTransfer;
+
+	assert((address & 0x80) == 0);
+	assert((iaddress & 0xFF000000) == 0);
+	assert(isize < 4);
+
+	/* Check that no transfer is already pending*/
+	if (pTransfer) {
+
+		TRACE_ERROR("TWID_Read: A transfer is already pending\n\r");
+		return TWID_ERROR_BUSY;
+	}
+
+	/* In single data byte master read, the START and STOP must both be set */
+	twi_send_stop = (num == 1) ? 1 : 0;
+
+	/* Asynchronous transfer*/
+	if (pAsync) {
+
+		/* Update the transfer descriptor */
+		pTwid->pTransfer = pAsync;
+		pTransfer = (AsyncTwi *) pAsync;
+		pTransfer->status = ASYNC_STATUS_PENDING;
+		pTransfer->pData = pData;
+		pTransfer->num = num;
+		pTransfer->transferred = 0;
+
+		/* Enable read interrupt and start the transfer */
+		TWI_EnableIt(pTwi, TWIHS_IER_RXRDY);
+		TWI_StartRead(pTwi, address, iaddress, isize);
+	}
+	/* Synchronous transfer*/
+	else {
+
+		/* Start read*/
+		TWI_StartRead(pTwi, address, iaddress, isize);
+
+		/* Read all bytes, setting STOP before the last byte*/
+		while (num > 0) {
+
+			/* Last byte ?*/
+			if (num == 1)
+				TWI_Stop(pTwi);
+
+			/* Wait for byte then read and store it*/
+			startTime = GetTicks();
+
+			while (!TWI_ByteReceived(pTwi)) {
+				if ((GetDelayInTicks(startTime, GetTicks())) > TWITIMEOUTMAX) {
+					TRACE_ERROR("TWID Timeout BR\n\r");
+					break;
+				}
+			}
+
+			*pData++ = TWI_ReadByte(pTwi);
+			num--;
+		}
+
+		/* Wait for transfer to be complete */
+		startTime = GetTicks();
+
+		while (!TWI_TransferComplete(pTwi)) {
+			if ((GetDelayInTicks(startTime, GetTicks())) > TWITIMEOUTMAX) {
+				TRACE_ERROR("TWID Timeout TC\n\r");
+				break;
+			}
+		}
+	}
+
+	return 0;
+}
+
+/**
+ * \brief Asynchronously sends data to a slave on the TWI bus. An optional
+ * callback function is invoked whenever the transfer is complete.
+ * \param pTwid  Pointer to a Twid instance.
+ * \param address  TWI slave address.
+ * \param iaddress  Optional slave internal address.
+ * \param isize  Number of internal address bytes.
+ * \param pData  Data buffer for storing received bytes.
+ * \param num  Data buffer to send.
+ * \param pAsync  Asynchronous transfer descriptor.
+ * \return 0 if the transfer has been started; otherwise returns a TWI error code.
+ */
+uint8_t TWID_Write(
+	Twid *pTwid,
+	uint8_t address,
+	uint32_t iaddress,
+	uint8_t isize,
+	uint8_t *pData,
+	uint32_t num,
+	Async *pAsync)
+{
+	Twihs *pTwi = pTwid->pTwi;
+	uint32_t startTime;
+	AsyncTwi *pTransfer = (AsyncTwi *) pTwid->pTransfer;
+
+	assert(pTwi != NULL);
+	assert((address & 0x80) == 0);
+	assert((iaddress & 0xFF000000) == 0);
+	assert(isize < 4);
+
+	/* Check that no transfer is already pending */
+	if (pTransfer) {
+		TRACE_ERROR("TWI_Write: A transfer is already pending\n\r");
+		return TWID_ERROR_BUSY;
+	}
+
+	/* Asynchronous transfer */
+	if (pAsync) {
+		/* Update the transfer descriptor */
+		pTwid->pTransfer = pAsync;
+		pTransfer = (AsyncTwi *) pAsync;
+		pTransfer->status = ASYNC_STATUS_PENDING;
+		pTransfer->pData = pData;
+		pTransfer->num = num;
+		pTransfer->transferred = 1;
+
+		/* Enable write interrupt and start the transfer */
+		TWI_StartWrite(pTwi, address, iaddress, isize, *pData);
+		TWI_EnableIt(pTwi, TWIHS_IER_TXRDY);
+
+	} else {
+		/* Synchronous transfer*/
+		// Start write
+		TWI_StartWrite(pTwi, address, iaddress, isize, *pData++);
+		num--;
+
+		/* Send all bytes */
+		while (num > 0) {
+			/* Wait before sending the next byte */
+			startTime = GetTicks();
+
+			while (!TWI_ByteSent(pTwi)) {
+				if ((GetDelayInTicks(startTime, GetTicks())) > TWITIMEOUTMAX) {
+					TRACE_ERROR("TWID Timeout BS\n\r");
+					break;
+				}
+			}
+
+			TWI_WriteByte(pTwi, *pData++);
+			num--;
+		}
+
+		/* Wait for actual end of transfer */
+		startTime = GetTicks();
+		/* Send a STOP condition */
+		TWI_SendSTOPCondition(pTwi);
+
+		while (!TWI_TransferComplete(pTwi)) {
+			if ((GetDelayInTicks(startTime, GetTicks())) > TWITIMEOUTMAX) {
+				TRACE_ERROR("TWID Timeout TC2\n\r");
+				break;
+			}
+		}
+	}
+
+	return 0;
+}
+
+/**
+ * \brief Initializes a TWI driver instance, using the given TWI peripheral.
+ * \note The peripheral must have been initialized properly before calling this
+ * function.
+ * \param pTwid  Pointer to the Twid instance to initialize.
+ * \param pTwi  Pointer to the TWI peripheral to use.
+ */
+void TWID_DmaInitialize(TwihsDma *pTwidma, Twihs *pTwi, uint8_t bPolling)
+{
+	TRACE_DEBUG("TWID_Initialize()\n\r");
+	assert(pTwidma != NULL);
+
+	if ((unsigned int)pTwi == (unsigned int)TWIHS0) pTwidma->Twi_id = ID_TWIHS0;
+
+	if ((unsigned int)pTwi == (unsigned int)TWIHS1) pTwidma->Twi_id = ID_TWIHS1;
+
+	if ((unsigned int)pTwi == (unsigned int)TWIHS2) pTwidma->Twi_id = ID_TWIHS2;
+
+	/* Initialize driver. */
+	pTwidma->pTwid->pTwi = pTwi;
+	pTwidma->pTwid->pTransfer = 0;
+
+	assert(!bPolling);
+}
+
+/**
+ * \brief Asynchronously reads data from a slave on the TWI bus. An optional
+ * callback function is triggered when the transfer is complete.
+ * \param pTwid  Pointer to a Twid instance.
+ * \param address  TWI slave address.
+ * \param iaddress  Optional slave internal address.
+ * \param isize  Internal address size in bytes.
+ * \param pData  Data buffer for storing received bytes.
+ * \param num  Number of bytes to read.
+ * \param pAsync  Asynchronous transfer descriptor.
+ * \param TWI_ID  TWI ID for TWI0, TWIHS1, TWIHS2.
+ * \return 0 if the transfer has been started; otherwise returns a TWI error code.
+ */
+uint8_t TWID_DmaRead(
+	TwihsDma *pTwiXdma,
+	uint8_t address,
+	uint32_t iaddress,
+	uint8_t isize,
+	uint8_t *pData,
+	uint32_t num,
+	Async *pAsync)
+{
+	Twihs *pTwi;
+	AsyncTwi *pTransfer;
+	uint32_t status, startTime;
+
+	assert(pTwiXdma->pTwid != NULL);
+	pTwi = pTwiXdma->pTwid->pTwi;
+	pTransfer = (AsyncTwi *) pTwiXdma->pTwid->pTransfer;
+
+	assert((address & 0x80) == 0);
+	assert((iaddress & 0xFF000000) == 0);
+	assert(isize < 4);
+
+	/* Check that no transfer is already pending*/
+	if (pTransfer) {
+
+		TRACE_ERROR("TWID_Read: A transfer is already pending\n\r");
+		return TWID_ERROR_BUSY;
+	}
+
+	/* Asynchronous transfer*/
+	if (pAsync) {
+		/* Update the transfer descriptor */
+		pTwiXdma->pTwid->pTransfer = pAsync;
+		pTransfer = (AsyncTwi *) pAsync;
+		pTransfer->status = ASYNC_STATUS_PENDING;
+		pTransfer->pData = pData;
+		pTransfer->num = num;
+		pTransfer->transferred = 0;
+
+		/* Enable read interrupt and start the transfer */
+		TWI_EnableIt(pTwi, TWIHS_IER_RXRDY);
+		TWI_StartRead(pTwi, address, iaddress, isize);
+	} else {
+		/* Synchronous transfer*/
+		TWID_DmaInitializeRead(pTwiXdma);
+		TWID_XdmaConfigureRead(pTwiXdma, pData, (num - 2));
+
+		/* Start read*/
+		XDMAD_StartTransfer(pTwiXdma->pTwiDma, dmaReadChannel);
+		TWI_StartRead(pTwi, address, iaddress, isize);
+
+		startTime = GetTicks();
+		status = XDMAD_IsTransferDone(pTwiXdma->pTwiDma, dmaReadChannel);
+
+		while (status != XDMAD_OK) {
+			status = XDMAD_IsTransferDone(pTwiXdma->pTwiDma, dmaReadChannel);
+
+			if ((GetDelayInTicks(startTime, GetTicks())) > TWITIMEOUTMAX) {
+				TRACE_ERROR("TWID DMA not done\n\r");
+				break;
+			}
+		}
+
+		if (XDMAD_OK == status)
+			SCB_InvalidateDCache_by_Addr((uint32_t *)pData, (num - 2));
+
+		status = TWI_GetStatus(pTwi);
+		startTime = GetTicks();
+
+		while (!(status & TWIHS_SR_RXRDY)) {
+			status = TWI_GetStatus(pTwi);
+
+			if ((GetDelayInTicks(startTime, GetTicks())) > TWITIMEOUTMAX) {
+				TRACE_ERROR("TWID DMA not done\n\r");
+				break;
+			}
+		}
+
+		TWI_Stop(pTwi);
+
+		pData[num - 2] = TWI_ReadByte(pTwi);
+		status = TWI_GetStatus(pTwi);
+		startTime = GetTicks();
+
+		while (!(status & TWIHS_SR_RXRDY)) {
+			status = TWI_GetStatus(pTwi);
+
+			if ((GetDelayInTicks(startTime, GetTicks())) > TWITIMEOUTMAX) {
+				TRACE_ERROR("TWID Timeout Read\n\r");
+				break;
+			}
+		}
+
+		pData[num - 1] = TWI_ReadByte(pTwi);
+		status = TWI_GetStatus(pTwi);
+		startTime = GetTicks();
+
+		while (!(status & TWIHS_SR_TXCOMP)) {
+			status = TWI_GetStatus(pTwi);
+
+			if ((GetDelayInTicks(startTime, GetTicks())) > TWITIMEOUTMAX) {
+				TRACE_ERROR("TWID Timeout Read\n\r");
+				break;
+			}
+		}
+
+		XDMAD_StopTransfer(pTwiXdma->pTwiDma, dmaReadChannel);
+		XDMAD_FreeChannel(pTwiXdma->pTwiDma, dmaWriteChannel);
+	}
+
+	return 0;
+}
+
+/**
+ * \brief Asynchronously sends data to a slave on the TWI bus. An optional
+ * callback function is invoked whenever the transfer is complete.
+ * \param pTwid  Pointer to a Twid instance.
+ * \param address  TWI slave address.
+ * \param iaddress  Optional slave internal address.
+ * \param isize  Number of internal address bytes.
+ * \param pData  Data buffer for storing received bytes.
+ * \param num  Data buffer to send.
+ * \param pAsync  Asynchronous transfer descriptor.
+ * \param TWI_ID  TWIHS ID for TWIHS0, TWIHS1, TWIHS2.
+ * \return 0 if the transfer has been started; otherwise returns a TWI error code.
+ */
+uint8_t TWID_DmaWrite(
+	TwihsDma *pTwiXdma,
+	uint8_t address,
+	uint32_t iaddress,
+	uint8_t isize,
+	uint8_t *pData,
+	uint32_t num,
+	Async *pAsync)
+{
+	Twihs *pTwi = pTwiXdma->pTwid->pTwi;
+	AsyncTwi *pTransfer = (AsyncTwi *) pTwiXdma->pTwid->pTransfer;
+	uint32_t status, startTime;
+	//uint8_t singleTransfer = 0;
+	assert(pTwi != NULL);
+	assert((address & 0x80) == 0);
+	assert((iaddress & 0xFF000000) == 0);
+	assert(isize < 4);
+
+	//    if (num == 1) singleTransfer = 1;
+	/* Check that no transfer is already pending */
+	if (pTransfer) {
+
+		TRACE_ERROR("TWI_Write: A transfer is already pending\n\r");
+		return TWID_ERROR_BUSY;
+	}
+
+	/* Asynchronous transfer */
+	if (pAsync) {
+
+		/* Update the transfer descriptor */
+		pTwiXdma->pTwid->pTransfer = pAsync;
+		pTransfer = (AsyncTwi *) pAsync;
+		pTransfer->status = ASYNC_STATUS_PENDING;
+		pTransfer->pData = pData;
+		pTransfer->num = num;
+		pTransfer->transferred = 1;
+
+		/* Enable write interrupt and start the transfer */
+		TWI_StartWrite(pTwi, address, iaddress, isize, *pData);
+		TWI_EnableIt(pTwi, TWIHS_IER_TXRDY);
+	} else {
+		/* Synchronous transfer*/
+		TWID_DmaInitializeWrite(pTwiXdma);
+		TWID_XdmaConfigureWrite(pTwiXdma, pData, (num - 1));
+		/* Set slave address and number of internal address bytes. */
+		pTwi->TWIHS_MMR = 0;
+		pTwi->TWIHS_MMR = (isize << 8) | (address << 16);
+
+		/* Set internal address bytes. */
+		pTwi->TWIHS_IADR = 0;
+		pTwi->TWIHS_IADR = iaddress;
+
+		// cache maintenance before starting DMA Xfr
+		SCB_CleanDCache_by_Addr((uint32_t *)pData, (num - 1));
+		startTime = GetTicks();
+
+		XDMAD_StartTransfer(pTwiXdma->pTwiDma, dmaWriteChannel);
+
+		while ((XDMAD_IsTransferDone(pTwiXdma->pTwiDma, dmaWriteChannel))) {
+			if ((GetDelayInTicks(startTime, GetTicks())) > TWITIMEOUTMAX) {
+				TRACE_ERROR("TWID DMA not done, Channel State is %d\n\r",
+							pTwiXdma->pTwiDma->XdmaChannels[dmaWriteChannel].state);
+				break;
+			}
+		}
+
+		status = TWI_GetStatus(pTwi);
+		startTime = GetTicks();
+
+		while (!(status & TWIHS_SR_TXRDY)) {
+			status = TWI_GetStatus(pTwi);
+
+			if ((GetDelayInTicks(startTime, GetTicks())) > TWITIMEOUTMAX) {
+				TRACE_ERROR("TWID Timeout TXRDY\n\r");
+				break;
+			}
+		}
+
+		/* Send a STOP condition */
+		TWI_Stop(pTwi);
+
+		TWI_WriteByte(pTwi, pData[num - 1]);
+		status = TWI_GetStatus(pTwi);
+		startTime = GetTicks();
+
+		while (!(status & TWIHS_SR_TXCOMP)) {
+			status = TWI_GetStatus(pTwi);
+
+			if ((GetDelayInTicks(startTime, GetTicks())) > TWITIMEOUTMAX) {
+				TRACE_ERROR("TWID Timeout Write\n\r");
+				break;
+			}
+		}
+
+		XDMAD_StopTransfer(pTwiXdma->pTwiDma, dmaWriteChannel);
+		XDMAD_FreeChannel(pTwiXdma->pTwiDma, dmaWriteChannel);
+
+	}
+
+	return 0;
+}
Index: bsps/arm/atsam/contrib/libraries/libchip/source/uart.c
===================================================================
--- bsps/arm/atsam/contrib/libraries/libchip/source/uart.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libchip/source/uart.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,232 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+/**
+ * \file
+ *
+ * Implementation of UART (Universal Asynchronous Receiver Transmitter)
+ * controller.
+ *
+ */
+/*------------------------------------------------------------------------------
+ *         Headers
+ *----------------------------------------------------------------------------*/
+#include "chip.h"
+
+#include <assert.h>
+#include <string.h>
+
+/*------------------------------------------------------------------------------
+ *         Exported functions
+ *----------------------------------------------------------------------------*/
+
+/**
+ * \brief Configures an UART peripheral with the specified parameters.
+ *
+ *
+ *  \param uart  Pointer to the UART peripheral to configure.
+ *  \param mode  Desired value for the UART mode register (see the datasheet).
+ *  \param baudrate  Baudrate at which the UART should operate (in Hz).
+ *  \param masterClock  Frequency of the system master clock (in Hz).
+ */
+void UART_Configure(Uart *uart,
+					uint32_t mode,
+					uint32_t baudrate,
+					uint32_t masterClock)
+{
+	/* Reset and disable receiver & transmitter*/
+	uart->UART_CR = UART_CR_RSTRX | UART_CR_RSTTX
+					| UART_CR_RXDIS | UART_CR_TXDIS | UART_CR_RSTSTA;
+
+	uart->UART_IDR = 0xFFFFFFFF;
+
+	/* Configure mode*/
+	uart->UART_MR = mode;
+
+	/* Configure baudrate*/
+	uart->UART_BRGR = (masterClock / baudrate) / 16;
+
+	uart->UART_CR = UART_CR_TXEN | UART_CR_RXEN;
+
+}
+/**
+ * \brief Enables or disables the transmitter of an UART peripheral.
+ *
+ *
+ * \param uart  Pointer to an UART peripheral
+ * \param enabled  If true, the transmitter is enabled; otherwise it is
+ *  disabled.
+ */
+void UART_SetTransmitterEnabled(Uart *uart, uint8_t enabled)
+{
+	if (enabled)
+		uart->UART_CR = UART_CR_TXEN;
+	else
+		uart->UART_CR = UART_CR_TXDIS;
+}
+
+/**
+ * \brief Enables or disables the receiver of an UART peripheral
+ *
+ *
+ * \param uart  Pointer to an UART peripheral
+ * \param enabled  If true, the receiver is enabled; otherwise it is disabled.
+ */
+void UART_SetReceiverEnabled(Uart *uart, uint8_t enabled)
+{
+	if (enabled)
+		uart->UART_CR = UART_CR_RXEN;
+	else
+		uart->UART_CR = UART_CR_RXDIS;
+}
+
+/**
+ * \brief   Return 1 if a character can be read in UART
+ * \param uart  Pointer to an UART peripheral.
+ */
+uint32_t UART_IsRxReady(Uart *uart)
+{
+	return (uart->UART_SR & UART_SR_RXRDY);
+}
+
+/**
+ * \brief  Reads and returns a character from the UART.
+ *
+ * \note This function is synchronous (i.e. uses polling).
+ * \param uart  Pointer to an UART peripheral.
+ * \return Character received.
+ */
+uint8_t UART_GetChar(Uart *uart)
+{
+	while (!UART_IsRxReady(uart));
+
+	return uart->UART_RHR;
+}
+
+/**
+ * \brief   Return 1 if a character can be send to UART
+ * \param uart  Pointer to an UART peripheral.
+ */
+uint32_t UART_IsTxReady(Uart *uart)
+{
+	return (uart->UART_SR & UART_SR_TXRDY);
+}
+
+/**
+ * \brief   Return 1 if a character can be send to UART
+ * \param uart  Pointer to an UART peripheral.
+ */
+static uint32_t UART_IsTxSent(Uart *uart)
+{
+	return (uart->UART_SR & UART_SR_TXEMPTY);
+}
+
+/**
+ * \brief  Sends one packet of data through the specified UART peripheral. This
+ * function operates synchronously, so it only returns when the data has been
+ * actually sent.
+ *
+ * \param uart  Pointer to an UART peripheral.
+ * \param c  Character to send
+ */
+void UART_PutChar(Uart *uart, uint8_t c)
+{
+	/* Wait for the transmitter to be ready*/
+	while (!UART_IsRxReady(uart) && !UART_IsTxSent(uart));
+
+	/* Send character*/
+	uart->UART_THR = c;
+
+	/* Wait for the transfer to complete*/
+	while (!UART_IsTxSent(uart));
+}
+
+/**
+ * \brief   Get present status
+ * \param uart  Pointer to an UART peripheral.
+ */
+uint32_t UART_GetStatus(Uart *uart)
+{
+	return uart->UART_SR;
+}
+
+/**
+ * \brief   Enable interrupt
+ * \param uart  Pointer to an UART peripheral.
+ * \param mode  Interrupt mode.
+ */
+void UART_EnableIt(Uart *uart, uint32_t mode)
+{
+	uart->UART_IER = mode;
+}
+
+/**
+ * \brief   Disable interrupt
+ * \param uart  Pointer to an UART peripheral.
+ * \param mode  Interrupt mode.
+ */
+void UART_DisableIt(Uart *uart, uint32_t mode)
+{
+	uart->UART_IDR = mode;
+}
+
+/**
+ * \brief   Return interrupt mask
+ * \param uart  Pointer to an UART peripheral.
+ */
+uint32_t UART_GetItMask(Uart *uart)
+{
+	return uart->UART_IMR;
+}
+
+void UART_SendBuffer(Uart *uart, uint8_t *pBuffer, uint32_t BuffLen)
+{
+	uint8_t *pData = pBuffer;
+	uint32_t Len = 0;
+
+	for (Len = 0; Len < BuffLen; Len++) {
+		UART_PutChar(uart, *pData);
+		pData++;
+	}
+}
+
+void UART_ReceiveBuffer(Uart *uart, uint8_t *pBuffer, uint32_t BuffLen)
+{
+	uint32_t Len = 0;
+
+	for (Len = 0; Len < BuffLen; Len++) {
+		*pBuffer = UART_GetChar(uart);
+		pBuffer++;
+	}
+}
+
+void UART_CompareConfig(Uart *uart, uint8_t Val1, uint8_t Val2)
+{
+	uart->UART_CMPR = (UART_CMPR_VAL1(Val1) | UART_CMPR_VAL2(Val2));
+}
Index: bsps/arm/atsam/contrib/libraries/libchip/source/uart_dma.c
===================================================================
--- bsps/arm/atsam/contrib/libraries/libchip/source/uart_dma.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libchip/source/uart_dma.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,616 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+/**
+ * \addtogroup uart_dma_module UART xDMA driver
+ * \ingroup lib_uart
+ * \section Usage
+ *
+ * <ul>
+ * <li> UARTD_Configure() initializes and configures the UART peripheral and
+ * xDMA for data transfer.</li>
+ * <li> Configures the parameters for the device corresponding to the cs value
+ * by UARTD_ConfigureCS(). </li>
+ * <li> Starts a UART master transfer. This is a non blocking function
+ * UARTD_SendData(). It will
+ * return as soon as the transfer is started..</li>
+ * </ul>
+ *
+ */
+
+/**
+ * \file
+ *
+ * Implementation for the UART with xDMA driver.
+ *
+ */
+
+
+/*----------------------------------------------------------------------------
+ *        Headers
+ *----------------------------------------------------------------------------*/
+
+#include "chip.h"
+#include "string.h"
+#include "stdlib.h"
+
+
+/*----------------------------------------------------------------------------
+ *        Local functions
+ *----------------------------------------------------------------------------*/
+
+/**
+* \brief UART xDMA Rx callback
+* Invoked on UART DMA reception done.
+* \param channel DMA channel.
+* \param pArg Pointer to callback argument - Pointer to UARTDma instance.
+*/
+static void UARTD_Rx_Cb(uint32_t channel, UartDma *pArg)
+{
+
+	UartChannel *pUartdCh = pArg->pRxChannel;
+
+	if (channel != pUartdCh->ChNum)
+		return;
+
+	/* Release the DMA channels */
+	XDMAD_FreeChannel(pArg->pXdmad, pUartdCh->ChNum);
+	pUartdCh->sempaphore = 1;
+	SCB_InvalidateDCache_by_Addr((uint32_t *)pUartdCh->pBuff, pUartdCh->BuffSize);
+}
+
+/**
+ * \brief USART xDMA Rx callback
+ * Invoked on USART DMA reception done.
+ * \param channel DMA channel.
+ * \param pArg Pointer to callback argument - Pointer to USARTDma instance.
+ */
+static void UARTD_Tx_Cb(uint32_t channel, UartDma *pArg)
+{
+	UartChannel *pUartdCh = pArg->pTxChannel;
+
+	if (channel != pUartdCh->ChNum)
+		return;
+
+	/* Release the DMA channels */
+	XDMAD_FreeChannel(pArg->pXdmad, pUartdCh->ChNum);
+	pUartdCh->sempaphore = 1;
+}
+
+/**
+ * \brief Configure the UART Rx DMA mode.
+ *
+ * \param pUartHw   Pointer to UART instance
+ * \param pXdmad    Pointer to XDMA instance
+ * \param pUsartRx  Pointer to Usart Rx channel
+ * \returns 0 if the dma multibuffer configuration successfully; otherwise
+ * returns USARTD_ERROR_XXX.
+ */
+static uint8_t _configureUartRxDma(UartDma *pUartd ,  UartChannel *pUartRx)
+{
+	sXdmadCfg xdmadRxCfg;
+	uint32_t xdmaCndc, xdmaInt;
+	uint32_t i, LLI_Size;
+	Uart *pUartHwRx = pUartd->pUartHw;
+	sXdmad *pXdmadRx = pUartd->pXdmad;
+	uint8_t *pBuff = 0;
+
+	/* Setup RX Single block */
+	if (pUartRx->dmaProgrammingMode < XDMAD_LLI) {
+		xdmadRxCfg.mbr_ubc = pUartRx->BuffSize;
+		xdmadRxCfg.mbr_da = (uint32_t)pUartRx->pBuff;
+
+		xdmadRxCfg.mbr_sa = (uint32_t)&pUartHwRx->UART_RHR;
+		xdmadRxCfg.mbr_cfg =  XDMAC_CC_TYPE_PER_TRAN |
+							  XDMAC_CC_MBSIZE_SIXTEEN |
+							  XDMAC_CC_DSYNC_PER2MEM |
+							  XDMAC_CC_CSIZE_CHK_1 |
+							  XDMAC_CC_DWIDTH_BYTE |
+							  XDMAC_CC_SIF_AHB_IF1 |
+							  XDMAC_CC_DIF_AHB_IF1 |
+							  XDMAC_CC_SAM_FIXED_AM |
+							  XDMAC_CC_DAM_INCREMENTED_AM |
+							  XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber
+											 (pUartd->uartId, XDMAD_TRANSFER_RX));
+
+		xdmadRxCfg.mbr_bc = 0;
+
+		if (pUartRx->dmaProgrammingMode == XDMAD_MULTI)
+			xdmadRxCfg.mbr_bc = pUartRx->dmaBlockSize;
+
+		xdmadRxCfg.mbr_sus = 0;
+		xdmadRxCfg.mbr_dus = 0;
+		xdmaCndc = 0;
+
+		/* Put all interrupts on for non LLI list setup of DMA */
+		xdmaInt =  (XDMAC_CIE_BIE   |
+					XDMAC_CIE_DIE   |
+					XDMAC_CIE_FIE   |
+					XDMAC_CIE_RBIE  |
+					XDMAC_CIE_WBIE  |
+					XDMAC_CIE_ROIE);
+
+	} else if (pUartRx->dmaProgrammingMode == XDMAD_LLI) {
+		/* Setup RX Link List */
+		LLI_Size = pUartRx->dmaBlockSize;
+		pBuff = pUartRx->pBuff;
+
+		if (pUartRx->pLLIview != NULL)   {
+			free(pUartRx->pLLIview);
+			pUartRx->pLLIview = NULL;
+		}
+
+		pUartRx->pLLIview = malloc(sizeof(LinkedListDescriporView1) * LLI_Size);
+
+		if (pUartRx->pLLIview == NULL) {
+			TRACE_ERROR(" Can not allocate memory to Rx LLI");
+			return USARTD_ERROR;
+		}
+
+		xdmadRxCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN |
+							 XDMAC_CC_MBSIZE_SIXTEEN |
+							 XDMAC_CC_DSYNC_PER2MEM |
+							 XDMAC_CC_MEMSET_NORMAL_MODE |
+							 XDMAC_CC_CSIZE_CHK_1 |
+							 XDMAC_CC_DWIDTH_BYTE |
+							 XDMAC_CC_SIF_AHB_IF1 |
+							 XDMAC_CC_DIF_AHB_IF1 |
+							 XDMAC_CC_SAM_FIXED_AM |
+							 XDMAC_CC_DAM_INCREMENTED_AM |
+							 XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber(
+												pUartd->uartId, XDMAD_TRANSFER_RX));
+		xdmadRxCfg.mbr_bc = 0;
+
+		for (i = 0; i < LLI_Size; i++) {
+			pUartRx->pLLIview[i].mbr_ubc = XDMA_UBC_NVIEW_NDV1 |
+										   XDMA_UBC_NSEN_UNCHANGED |
+										   XDMA_UBC_NDEN_UPDATED |
+										   ((i == LLI_Size - 1) ? ((pUartRx->dmaRingBuffer) ?
+												   XDMA_UBC_NDE_FETCH_EN : 0) :
+											XDMA_UBC_NDE_FETCH_EN) | pUartRx->BuffSize;
+			pUartRx->pLLIview[i].mbr_sa = (uint32_t)&pUartHwRx->UART_RHR;
+			pUartRx->pLLIview[i].mbr_da = (uint32_t)pBuff;
+			pUartRx->pLLIview[i].mbr_nda = (i == (LLI_Size - 1)) ?
+										   ((pUartRx->dmaRingBuffer) ? (uint32_t)pUartRx->pLLIview : 0) :
+										   (uint32_t)&pUartRx->pLLIview[ i + 1 ];
+			pBuff += pUartRx->BuffSize;
+		}
+
+		SCB_CleanDCache_by_Addr((uint32_t *)(pUartRx->pLLIview),
+								sizeof(LinkedListDescriporView1)*LLI_Size);
+
+		xdmaCndc = XDMAC_CNDC_NDVIEW_NDV1 |
+				   XDMAC_CNDC_NDE_DSCR_FETCH_EN |
+				   XDMAC_CNDC_NDSUP_SRC_PARAMS_UPDATED |
+				   XDMAC_CNDC_NDDUP_DST_PARAMS_UPDATED;
+
+		xdmaInt = ((pUartRx->dmaRingBuffer) ? XDMAC_CIE_BIE : XDMAC_CIE_LIE);
+
+	} else
+		return 1;
+
+	if (XDMAD_ConfigureTransfer(pXdmadRx, pUartRx->ChNum, &xdmadRxCfg,
+								 xdmaCndc, (uint32_t)pUartRx->pLLIview, xdmaInt))
+		return USARTD_ERROR;
+
+	return 0;
+}
+
+/**
+ * \brief Configure the UART Tx DMA mode.
+ *
+ * \param pUartHw   Pointer to UART instance
+ * \param pXdmad    Pointer to XDMA instance
+ * \param pUsartTx  Pointer to Usart Tx channel
+ * \returns 0 if the dma multibuffer configuration successfully; otherwise
+ * returns USARTD_ERROR_XXX.
+ */
+static uint8_t _configureUartTxDma(UartDma *pUartd, UartChannel *pUartTx)
+{
+	sXdmadCfg xdmadTxCfg;
+	uint32_t xdmaCndc, xdmaInt, LLI_Size, i;
+	uint8_t *pBuff = 0;
+	Uart *pUartHwTx = pUartd->pUartHw;
+	sXdmad *pXdmadTx = pUartd->pXdmad;
+
+
+	/* Setup TX  */
+	if (pUartTx->dmaProgrammingMode < XDMAD_LLI) {
+		xdmadTxCfg.mbr_ubc = pUartTx->BuffSize;
+
+		xdmadTxCfg.mbr_sa = (uint32_t)pUartTx->pBuff;
+		xdmadTxCfg.mbr_da = (uint32_t)&pUartHwTx->UART_THR;
+		xdmadTxCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN |
+							 XDMAC_CC_MBSIZE_SIXTEEN |
+							 XDMAC_CC_DSYNC_MEM2PER |
+							 XDMAC_CC_CSIZE_CHK_1 |
+							 XDMAC_CC_DWIDTH_BYTE |
+							 XDMAC_CC_SIF_AHB_IF1 |
+							 XDMAC_CC_DIF_AHB_IF1 |
+							 XDMAC_CC_SAM_INCREMENTED_AM |
+							 XDMAC_CC_DAM_FIXED_AM |
+							 XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber(
+												pUartd->uartId, XDMAD_TRANSFER_TX));
+
+		xdmadTxCfg.mbr_bc = 0;
+
+		if (pUartTx->dmaProgrammingMode == XDMAD_MULTI)
+			xdmadTxCfg.mbr_bc = pUartTx->dmaBlockSize;
+
+		xdmadTxCfg.mbr_sus = 0;
+		xdmadTxCfg.mbr_dus = 0;
+		xdmadTxCfg.mbr_ds = 0;
+		xdmaCndc = 0;
+		/* Enable End of Block; Read Bus error;  Write Bus Error;
+		Overflow Error interrupt */
+		xdmaInt =  (XDMAC_CIE_BIE    |
+					XDMAC_CIE_RBIE  |
+					XDMAC_CIE_WBIE  |
+					XDMAC_CIE_ROIE);
+
+	} else if (pUartTx->dmaProgrammingMode == XDMAD_LLI) {
+		LLI_Size = pUartTx->dmaBlockSize;
+		pBuff = pUartTx->pBuff;
+
+		if (pUartTx->pLLIview != NULL) {
+			free(pUartTx->pLLIview);
+			pUartTx->pLLIview = NULL;
+		}
+
+		pUartTx->pLLIview = malloc(sizeof(LinkedListDescriporView1) * LLI_Size);
+
+		if (pUartTx->pLLIview == NULL) {
+			TRACE_ERROR(" Can not allocate memory to Tx LLI");
+			return USARTD_ERROR;
+		}
+
+		xdmadTxCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN |
+							 XDMAC_CC_MBSIZE_SIXTEEN |
+							 XDMAC_CC_DSYNC_MEM2PER |
+							 XDMAC_CC_MEMSET_NORMAL_MODE |
+							 XDMAC_CC_CSIZE_CHK_1 |
+							 XDMAC_CC_DWIDTH_BYTE |
+							 XDMAC_CC_SIF_AHB_IF1 |
+							 XDMAC_CC_DIF_AHB_IF1 |
+							 XDMAC_CC_SAM_INCREMENTED_AM |
+							 XDMAC_CC_DAM_FIXED_AM |
+							 XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber(
+												pUartd->uartId, XDMAD_TRANSFER_TX));
+		xdmadTxCfg.mbr_bc = 0;
+
+		for (i = 0; i < LLI_Size; i++) {
+			pUartTx->pLLIview[i].mbr_ubc = XDMA_UBC_NVIEW_NDV1 |
+										   XDMA_UBC_NSEN_UPDATED |
+										   XDMA_UBC_NDEN_UNCHANGED |
+										   ((i == LLI_Size - 1) ? ((pUartTx->dmaRingBuffer) ?
+												   XDMA_UBC_NDE_FETCH_EN : 0) :
+											XDMA_UBC_NDE_FETCH_EN) | pUartTx->BuffSize;
+			pUartTx->pLLIview[i].mbr_da = (uint32_t)&pUartHwTx->UART_THR;
+			pUartTx->pLLIview[i].mbr_sa = (uint32_t)pBuff;
+			pUartTx->pLLIview[i].mbr_nda = (i == (LLI_Size - 1)) ?
+										   ((pUartTx->dmaRingBuffer) ? (uint32_t)pUartTx->pLLIview : 0) :
+										   (uint32_t)&pUartTx->pLLIview[ i + 1 ];
+			pBuff += pUartTx->BuffSize;
+		}
+
+		SCB_CleanDCache_by_Addr((uint32_t *)(pUartTx->pLLIview),
+								sizeof(LinkedListDescriporView1)*LLI_Size);
+
+		xdmaCndc = XDMAC_CNDC_NDVIEW_NDV1 |
+				   XDMAC_CNDC_NDE_DSCR_FETCH_EN |
+				   XDMAC_CNDC_NDSUP_SRC_PARAMS_UPDATED |
+				   XDMAC_CNDC_NDDUP_DST_PARAMS_UPDATED;
+		xdmaInt = ((pUartTx->dmaRingBuffer) ? XDMAC_CIE_BIE : XDMAC_CIE_LIE);
+
+	} else {
+		TRACE_ERROR("DmaProgState is incorrect \n\r");
+		return 1;
+	}
+
+	if (XDMAD_ConfigureTransfer(pXdmadTx, pUartTx->ChNum, &xdmadTxCfg, xdmaCndc,
+								 (uint32_t)pUartTx->pLLIview, xdmaInt))
+		return USARTD_ERROR;
+
+	return 0;
+}
+
+/*----------------------------------------------------------------------------
+ *        Exported functions
+ *----------------------------------------------------------------------------*/
+/**
+ * \brief Initializes the UartDma structure and the corresponding UART & DMA .
+ * hardware select value.
+ * The driver will uses DMA channel 0 for RX and DMA channel 1 for TX.
+ * The DMA channels are freed automatically when no UART command processing.
+ *
+ * \param pUartd    Pointer to a UartDma instance.
+ * \param pUartHw   Associated UART peripheral.
+ * \param uartId    UART peripheral identifier.
+ * \param uartMode  UART peripheral identifier.*
+ * \param baud      UART baud rate
+ * \param clk       UART ref clock
+ * \param pXdmad    Pointer to a Dmad instance.
+ */
+uint32_t UARTD_Configure(UartDma *pUartd ,
+						  uint8_t uartId,
+						  uint32_t uartMode,
+						  uint32_t baud,
+						  uint32_t clk)
+{
+	/* Enable the peripheral clock in the PMC*/
+	PMC_EnablePeripheral(uartId);
+
+	/* Initialize the UART structure */
+	pUartd->uartId  = uartId;
+
+	if (uartId == ID_UART0)
+		pUartd->pUartHw = UART0;
+
+	if (uartId == ID_UART1)
+		pUartd->pUartHw = UART1;
+
+	if (uartId == ID_UART2)
+		pUartd->pUartHw = UART2;
+
+	if (uartId == ID_UART3)
+		pUartd->pUartHw = UART3;
+
+	if (uartId == ID_UART4)
+		pUartd->pUartHw = UART4;
+
+	pUartd->pXdmad->pXdmacs = XDMAC;
+
+	/* Enable the UART Peripheral ,Execute a software reset of the UART,
+	    Configure UART in Master Mode*/
+	UART_Configure (pUartd->pUartHw, uartMode, baud, clk);
+
+	/* Check if DMA IRQ is enable; if not clear pending IRQs in init it */
+	if (!(NVIC_GetActive(XDMAC_IRQn)))
+		NVIC_ClearPendingIRQ(XDMAC_IRQn);
+
+	return 0;
+}
+
+/**
+ * \brief This function initialize the appropriate DMA channel for Rx channel of
+ * UART
+ * \param pUartd     Pointer to a UartDma instance.
+ * \param pRxCh      Pointer to TxChannel configuration
+ * \returns          0 if the transfer has been started successfully;
+ * otherwise returns UARTD_ERROR_LOCK is the driver is in use, or UARTD_ERROR
+ * if the command is not valid.
+ */
+uint32_t UARTD_EnableRxChannels(UartDma *pUartd, UartChannel *pRxCh)
+{
+	Uart *pUartHw = pUartd->pUartHw;
+	uint32_t Channel;
+
+	assert(pRxCh);
+	/* Init USART Rx Channel. */
+	pUartd->pRxChannel = pRxCh;
+
+	/* Enables the USART to receive data. */
+	UART_SetReceiverEnabled (pUartHw , ENABLE);
+
+
+	/* Allocate a DMA channel for UART RX. */
+	Channel =  XDMAD_AllocateChannel(pUartd->pXdmad, pUartd->uartId,
+									  XDMAD_TRANSFER_MEMORY);
+
+	if (Channel == XDMAD_ALLOC_FAILED)
+		return UARTD_ERROR;
+
+	pRxCh->ChNum = Channel;
+
+	/* Setup callbacks for UART RX */
+	if (pRxCh->callback) {
+		XDMAD_SetCallback(pUartd->pXdmad, pRxCh->ChNum,
+						  (XdmadTransferCallback)pRxCh->callback, pRxCh->pArgument);
+	} else {
+		XDMAD_SetCallback(pUartd->pXdmad, pRxCh->ChNum,
+						  (XdmadTransferCallback)UARTD_Rx_Cb, pUartd);
+	}
+
+	if (XDMAD_PrepareChannel(pUartd->pXdmad, pRxCh->ChNum))
+		return UARTD_ERROR;
+
+	if (_configureUartRxDma(pUartd, pRxCh))
+		return UARTD_ERROR_LOCK;
+
+	/* Check if DMA IRQ is enable; if not Enable it */
+	if (!(NVIC_GetActive(XDMAC_IRQn))) {
+		/* Enable interrupt  */
+		NVIC_EnableIRQ(XDMAC_IRQn);
+	}
+
+	return 0;
+}
+
+/**
+ * \brief This function initialize the appropriate DMA channel for Tx channel of
+ * UART
+ * \param pUartd     Pointer to a UartDma instance.
+ * \param pTxCh      Pointer to RxChannel configuration
+ * \returns          0 if the transfer has been started successfully;
+ * otherwise returns UARTD_ERROR_LOCK is the driver is in use, or UARTD_ERROR
+ * if the command is not valid.
+ */
+uint32_t UARTD_EnableTxChannels(UartDma *pUartd, UartChannel *pTxCh)
+{
+	Uart *pUartHw = pUartd->pUartHw;
+	uint32_t Channel;
+
+	/* Init USART Tx Channel. */
+	pUartd->pTxChannel = pTxCh;
+
+	/* Enables the USART to transfer data. */
+	UART_SetTransmitterEnabled (pUartHw , ENABLE);
+
+	/* Allocate a DMA channel for UART TX. */
+	Channel =  XDMAD_AllocateChannel(pUartd->pXdmad,
+									  XDMAD_TRANSFER_MEMORY, pUartd->uartId);
+
+	if (pTxCh->ChNum == XDMAD_ALLOC_FAILED)
+		return USARTD_ERROR;
+
+	pTxCh->ChNum = Channel;
+
+	/* Setup callbacks for UART TX */
+	if (pUartd->pTxChannel->callback) {
+		XDMAD_SetCallback(pUartd->pXdmad, pTxCh->ChNum,
+						  (XdmadTransferCallback)pTxCh->callback, pTxCh->pArgument);
+	} else
+		XDMAD_SetCallback(pUartd->pXdmad, pTxCh->ChNum,
+						  (XdmadTransferCallback)UARTD_Tx_Cb, pUartd);
+
+	if (XDMAD_PrepareChannel(pUartd->pXdmad, pTxCh->ChNum))
+		return USARTD_ERROR;
+
+	if (_configureUartTxDma(pUartd, pTxCh))
+		return USARTD_ERROR_LOCK;
+
+	/* Check if DMA IRQ is enable; if not Enable it */
+	if (!(NVIC_GetActive(XDMAC_IRQn))) {
+		/* Enable interrupt  */
+		NVIC_EnableIRQ(XDMAC_IRQn);
+	}
+
+	return 0;
+}
+
+/**
+ * \brief This function disables the appropriate DMA channel for Rx channel of
+ * USART
+ * \param pUsartd       Pointer to a UsartDma instance.
+ * \param pRxCh         Pointer to TxChannel configuration
+ * \returns             0 if the transfer has been started successfully;
+ * otherwise returns USARTD_ERROR_LOCK is the driver is in use, or USARTD_ERROR
+ * if the command is not valid.
+ */
+
+uint32_t UARTD_DisableRxChannels(UartDma *pUartd, UartChannel *pRxCh)
+{
+	assert(pRxCh);
+
+	/* Enables the USART to transfer data. */
+	UART_SetReceiverEnabled (pUartd->pUartHw , DISABLE);
+
+	XDMAD_StopTransfer(pUartd->pXdmad, pRxCh->ChNum);
+
+	XDMAD_SetCallback(pUartd->pXdmad, pRxCh->ChNum, NULL, NULL);
+
+	/* Free allocated DMA channel for USART TX. */
+	if (XDMAD_FreeChannel(pUartd->pXdmad, pRxCh->ChNum) != XDMAD_OK)
+		return USARTD_ERROR;
+
+	if (pRxCh->dmaProgrammingMode == XDMAD_LLI) {
+		free(pRxCh->pLLIview);
+		pRxCh->pLLIview = NULL;
+	}
+
+	pRxCh->sempaphore = 1;
+	return 0;
+}
+
+
+/**
+ * \brief This function disables the appropriate DMA channel for Tx channel of
+ * USART
+ * \param pUsartd       Pointer to a USARTDma instance.
+ * \param pTxCh         Pointer to TxChannel configuration
+ * \returns             0 if the transfer has been started successfully;
+ *  otherwise returns USARTD_ERROR_LOCK is the driver is in use, or USARTD_ERROR
+ * if the command is not valid.
+ */
+
+uint32_t UARTD_DisableTxChannels(UartDma *pUartd, UartChannel *pTxCh)
+{
+	assert(pTxCh);
+
+	/* Enables the USART to transfer data. */
+	UART_SetTransmitterEnabled (pUartd->pUartHw , DISABLE);
+
+	XDMAD_StopTransfer(pUartd->pXdmad, pTxCh->ChNum);
+
+	XDMAD_SetCallback(pUartd->pXdmad, pTxCh->ChNum, NULL, NULL);
+
+	/* Free allocated DMA channel for USART TX. */
+	if (XDMAD_FreeChannel(pUartd->pXdmad, pTxCh->ChNum) != XDMAD_OK)
+		return USARTD_ERROR;
+
+	if (pTxCh->dmaProgrammingMode == XDMAD_LLI) {
+		free(pTxCh->pLLIview);
+		pTxCh->pLLIview = NULL;
+	}
+
+	pTxCh->sempaphore = 1;
+	return 0;
+}
+
+/**
+ * \brief Starts a UART master transfer. This is a non blocking function. It
+ * will return as soon as the transfer is started.
+ *
+ * \param pUartd  Pointer to a UartDma instance.
+ * \returns 0 if the transfer has been started successfully; otherwise returns
+ * UARTD_ERROR_LOCK is the driver is in use, or UARTD_ERROR if the command is
+ * not valid.
+ */
+uint32_t UARTD_SendData(UartDma *pUartd)
+{
+	/* Start DMA 0(RX) && 1(TX) */
+	SCB_CleanDCache_by_Addr((uint32_t *)pUartd->pTxChannel->pBuff,
+							pUartd->pTxChannel->BuffSize);
+	pUartd->pTxChannel->sempaphore = 0;
+
+	if (XDMAD_StartTransfer(pUartd->pXdmad, pUartd->pTxChannel->ChNum))
+		return USARTD_ERROR_LOCK;
+
+	return 0;
+}
+
+/**
+ * \brief Starts a UART master transfer. This is a non blocking function. It
+ *  will return as soon as the transfer is started.
+ *
+ * \param pUartd  Pointer to a UartDma instance.
+ * \returns 0 if the transfer has been started successfully; otherwise returns
+ * UARTD_ERROR_LOCK is the driver is in use, or UARTD_ERROR if the command is
+ * not valid.
+ */
+uint32_t UARTD_RcvData(UartDma *pUartd)
+{
+	pUartd->pRxChannel->sempaphore = 0;
+
+	/* Start DMA 0(RX) && 1(TX) */
+	if (XDMAD_StartTransfer(pUartd->pXdmad, pUartd->pRxChannel->ChNum))
+		return USARTD_ERROR_LOCK;
+
+	return 0;
+}
Index: bsps/arm/atsam/contrib/libraries/libchip/source/usart.c
===================================================================
--- bsps/arm/atsam/contrib/libraries/libchip/source/usart.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libchip/source/usart.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,466 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+/**
+ * \file
+ *
+ * Implementation of USART (Universal Synchronous Asynchronous Receiver
+ * Transmitter) controller.
+ *
+ */
+/*------------------------------------------------------------------------------
+ *         Headers
+ *-----------------------------------------------------------------------------*/
+#include "chip.h"
+
+#include <assert.h>
+#include <string.h>
+
+/*----------------------------------------------------------------------------
+ *        Local definitions
+ *----------------------------------------------------------------------------*/
+
+
+/*------------------------------------------------------------------------------
+ *         Exported functions
+ *-----------------------------------------------------------------------------*/
+
+/**
+ * \brief Configures an USART baudrate.
+ *
+ *
+ *  \param pUsart  Pointer to the USART peripheral to configure.
+ *  \param baudrate  Baudrate at which the USART should operate (in Hz).
+ *  \param masterClock  Frequency of the system master clock (in Hz).
+ */
+void USART_SetBaudrate(Usart *pUsart,
+					   uint8_t OverSamp,
+					   uint32_t baudrate,
+					   uint32_t masterClock)
+{
+	unsigned int CD, FP, BaudError, ActualBaudRate;
+	/* Configure baudrate*/
+	BaudError = 10;
+	OverSamp = 0;
+#ifdef __rtems__
+	CD = 0;
+	FP = 0;
+#endif /* __rtems__ */
+
+	/*Asynchronous*/
+	if ((pUsart->US_MR & US_MR_SYNC) == 0) {
+		/* 7816 mode */
+		if (((pUsart->US_MR & US_MR_USART_MODE_IS07816_T_0)
+			  == US_MR_USART_MODE_IS07816_T_0)
+			 || ((pUsart->US_MR & US_MR_USART_MODE_IS07816_T_1)
+				 == US_MR_USART_MODE_IS07816_T_1)) {
+			/* Define the baud rate divisor register */
+			/* CD  = MCK / SCK */
+			/* SCK = FIDI x BAUD = 372 x 9600 */
+			/* BOARD_MCK */
+			/* CD = MCK/(FIDI x BAUD) = 150000000 / (372x9600) = 42 */
+			CD = masterClock / (pUsart->US_FIDI * baudrate);
+			FP = 0;
+		} else {
+			while (BaudError > 5) {
+				CD = (masterClock / (baudrate * 8 * (2 - OverSamp)));
+				FP = ((masterClock / (baudrate * (2 - OverSamp))) - CD * 8);
+				ActualBaudRate = (masterClock / (CD * 8 + FP)) / (2 - OverSamp);
+				BaudError = (100 - ((baudrate * 100 / ActualBaudRate)));
+
+				if (BaudError > 5) {
+					OverSamp++;
+
+					if (OverSamp >= 2) {
+						TRACE_ERROR("Canont set this baudrate \n\r");
+						break;
+					}
+				}
+			}
+		}
+	}
+
+	/*Synchronous SPI  */
+	if ((pUsart->US_MR & US_MR_USART_MODE_SPI_MASTER)
+		== US_MR_USART_MODE_SPI_MASTER
+		|| ((pUsart->US_MR & US_MR_SYNC) == US_MR_SYNC)) {
+		if ((pUsart->US_MR & US_MR_USCLKS_Msk) == US_MR_USCLKS_MCK) {
+			CD = masterClock / baudrate;
+			FP = ((masterClock / baudrate) - CD);
+		}
+	}
+
+	pUsart->US_BRGR = (US_BRGR_CD(CD) | US_BRGR_FP(FP));
+
+	/* Configure OverSamp*/
+	pUsart->US_MR |= (OverSamp << 19);
+}
+
+/**
+ * \brief Configures an USART peripheral with the specified parameters.
+ *
+ *
+ *  \param pUsart  Pointer to the USART peripheral to configure.
+ *  \param mode  Desired value for the USART mode register (see the datasheet).
+ *  \param baudrate  Baudrate at which the USART should operate (in Hz).
+ *  \param masterClock  Frequency of the system master clock (in Hz).
+ */
+void USART_Configure(Usart *pUsart,
+					 uint32_t mode,
+					 uint32_t baudrate,
+					 uint32_t masterClock)
+{
+
+	/* Reset and disable receiver & transmitter*/
+	pUsart->US_CR = US_CR_RSTRX | US_CR_RSTTX
+					| US_CR_RXDIS | US_CR_TXDIS | US_CR_RSTSTA;
+	pUsart->US_IDR = 0xFFFFFFFF;
+
+	pUsart->US_MR = mode;
+	/* Configure baudrate*/
+	USART_SetBaudrate(pUsart, 0, baudrate, masterClock);
+
+	/* Enable receiver and transmitter */
+	pUsart->US_CR = US_CR_RXEN | US_CR_TXEN;
+
+	/* Disable buffering for printf(). */
+#if (defined (__GNUC__) && !defined (__SAMBA__))
+	setvbuf(stdout, (char *)NULL, _IONBF, 0);
+#endif
+
+}
+/**
+ * \brief Enables or disables the transmitter of an USART peripheral.
+ *
+ *
+ * \param pUsart  Pointer to an USART peripheral
+ * \param enabled  If true, the transmitter is enabled; otherwise it is
+ * disabled.
+ */
+void USART_SetTransmitterEnabled(Usart *pUsart, uint8_t enabled)
+{
+	if (enabled)
+		pUsart->US_CR = US_CR_TXEN;
+	else
+		pUsart->US_CR = US_CR_TXDIS;
+}
+
+/**
+ * \brief Disables the Receiver of an USART peripheral.
+ *
+ * \param pUsart  Pointer to an USART peripheral
+ */
+void USART_DisableRx(Usart *pUsart)
+{
+
+	pUsart->US_CR = US_CR_RXDIS;
+}
+
+/**
+ * \brief Disables the transmitter of an USART peripheral.
+ *
+ * \param pUsart  Pointer to an USART peripheral
+ */
+void USART_DisableTx(Usart *pUsart)
+{
+	pUsart->US_CR =  US_CR_TXDIS;
+}
+
+/**
+ * \brief Enables the Receiver of an USART peripheral.
+ *
+ * \param pUsart  Pointer to an USART peripheral
+ */
+void USART_EnableRx(Usart *pUsart)
+{
+
+	pUsart->US_CR = US_CR_RXEN;
+}
+
+/**
+ * \brief Enables the transmitter of an USART peripheral
+ *
+ * \param pUsart  Pointer to an USART peripheral
+ */
+void USART_EnableTx(Usart *pUsart)
+{
+	pUsart->US_CR =  US_CR_TXEN;
+}
+/**
+ * \brief Resets or disables the Receiver of an USART peripheral.
+ *
+ *
+ * \param pUsart  Pointer to an USART peripheral
+ */
+void USART_ResetRx(Usart *pUsart)
+{
+
+	pUsart->US_CR = US_CR_RSTRX | US_CR_RXDIS;
+}
+
+/**
+ * \brief resets and disables the transmitter of an USART peripheral.
+ *
+ *
+ * \param pUsart  Pointer to an USART peripheral
+ */
+void USART_ResetTx(Usart *pUsart)
+{
+	pUsart->US_CR =  US_CR_RSTTX | US_CR_TXDIS;
+}
+/**
+ * \brief Enables or disables the receiver of an USART peripheral
+ *
+ *
+ * \param pUsart  Pointer to an USART peripheral
+ * \param enabled  If true, the receiver is enabled; otherwise it is disabled.
+ */
+void USART_SetReceiverEnabled(Usart *pUsart, uint8_t enabled)
+{
+	if (enabled)
+		pUsart->US_CR = US_CR_RXEN;
+	else
+		pUsart->US_CR = US_CR_RXDIS;
+}
+
+/**
+ * \brief Enables or disables the Request To Send (RTS) of an USART peripheral
+ *
+ *
+ * \param pUsart  Pointer to an USART peripheral
+ * \param enabled  If true, the RTS is enabled (0); otherwise it is disabled.
+ */
+void USART_SetRTSEnabled(Usart *pUsart, uint8_t enabled)
+{
+	if (enabled)
+		pUsart->US_CR = US_CR_RTSEN;
+	else
+		pUsart->US_CR = US_CR_RTSDIS;
+}
+
+/**
+ * \brief Sends one packet of data through the specified USART peripheral. This
+ * function operates synchronously, so it only returns when the data has been
+ * actually sent.
+ *
+ *
+ * \param pUsart  Pointer to an USART peripheral.
+ * \param data  Data to send including 9nth bit and sync field if necessary (in
+ *        the same format as the US_THR register in the datasheet).
+ * \param timeOut  Time out value (0 = no timeout).
+ */
+void USART_Write(Usart *pUsart, uint16_t data, volatile uint32_t timeOut)
+{
+	if (timeOut == 0) {
+		while ((pUsart->US_CSR & US_CSR_TXEMPTY) == 0);
+	} else {
+		while ((pUsart->US_CSR & US_CSR_TXEMPTY) == 0) {
+			if (timeOut == 0) {
+				TRACE_ERROR("USART_Write: Timed out.\n\r");
+				return;
+			}
+
+			timeOut--;
+		}
+	}
+
+	pUsart->US_THR = data;
+}
+
+/**
+ * \brief  Reads and return a packet of data on the specified USART peripheral.
+ * This function operates asynchronously, so it waits until some data has been
+ * received.
+ *
+ * \param pUsart  Pointer to an USART peripheral.
+ * \param timeOut  Time out value (0 -> no timeout).
+ */
+uint16_t USART_Read(Usart *pUsart, volatile uint32_t timeOut)
+{
+	if (timeOut == 0) {
+		while ((pUsart->US_CSR & US_CSR_RXRDY) == 0);
+	} else {
+		while ((pUsart->US_CSR & US_CSR_RXRDY) == 0) {
+			if (timeOut == 0) {
+				TRACE_ERROR("USART_Read: Timed out.\n\r");
+				return 0;
+			}
+
+			timeOut--;
+		}
+	}
+
+	return pUsart->US_RHR;
+}
+
+/**
+ * \brief  Returns 1 if some data has been received and can be read from an
+ * USART; otherwise returns 0.
+ *
+ * \param pUsart  Pointer to an USART instance.
+ */
+uint8_t USART_IsDataAvailable(Usart *pUsart)
+{
+	if ((pUsart->US_CSR & US_CSR_RXRDY) != 0)
+		return 1;
+	else
+		return 0;
+}
+
+/**
+ * \brief  Sends one packet of data through the specified USART peripheral. This
+ * function operates synchronously, so it only returns when the data has been
+ * actually sent.
+ *
+ * \param pUsart  Pointer to an USART peripheral.
+ * \param c  Character to send
+ */
+void USART_PutChar(Usart *pUsart, uint8_t c)
+{
+	/* Wait for the transmitter to be ready*/
+	while ((pUsart->US_CSR & US_CSR_TXEMPTY) == 0);
+
+	/* Send character*/
+	pUsart->US_THR = c;
+
+	/* Wait for the transfer to complete*/
+	while ((pUsart->US_CSR & US_CSR_TXEMPTY) == 0);
+}
+
+/**
+ * \brief   Return 1 if a character can be read in USART
+ * \param pUsart  Pointer to an USART peripheral.
+ */
+uint32_t USART_IsRxReady(Usart *pUsart)
+{
+	return (pUsart->US_CSR & US_CSR_RXRDY);
+}
+
+/**
+ * \brief   Get present status
+ * \param pUsart  Pointer to an USART peripheral.
+ */
+uint32_t USART_GetStatus(Usart *pUsart)
+{
+	return pUsart->US_CSR;
+}
+
+/**
+ * \brief   Enable interrupt
+ * \param pUsart  Pointer to an USART peripheral.
+ * \param mode  Interrupt mode.
+ */
+void USART_EnableIt(Usart *pUsart, uint32_t mode)
+{
+	pUsart->US_IER = mode;
+}
+
+/**
+ * \brief   Disable interrupt
+ * \param pUsart  Pointer to an USART peripheral.
+ * \param mode  Interrupt mode.
+ */
+void USART_DisableIt(Usart *pUsart, uint32_t mode)
+{
+	pUsart->US_IDR = mode;
+}
+
+/**
+ * \brief   Return interrupt mask
+ * \param pUsart  Pointer to an USART peripheral.
+ */
+uint32_t USART_GetItMask(Usart *pUsart)
+{
+	return pUsart->US_IMR;
+}
+
+/**
+ * \brief  Reads and returns a character from the USART.
+ *
+ * \note This function is synchronous (i.e. uses polling).
+ * \param pUsart  Pointer to an USART peripheral.
+ * \return Character received.
+ */
+uint8_t USART_GetChar(Usart *pUsart)
+{
+	while ((pUsart->US_CSR & US_CSR_RXRDY) == 0);
+
+	return pUsart->US_RHR;
+}
+
+/**
+ * \brief  Enable Rx Timeout for USART.
+ *
+ * \param pUsart  Pointer to an USART peripheral.
+ * \param Timeout  Timeout value
+ * \return None
+ */
+void USART_EnableRecvTimeOut(Usart *pUsart, uint32_t Timeout)
+{
+	if (Timeout <= MAX_RX_TIMEOUT)
+		pUsart->US_RTOR = Timeout;
+	else if (Timeout == 0) {
+		TRACE_DEBUG("Timeout is disabled\n\r");
+	} else {
+		TRACE_INFO_WP("\n\r");
+		TRACE_FATAL("Timeout value is out of range\n\r");
+	}
+}
+
+/**
+ * \brief  Enable Tx Timeout for USART.
+ *
+ * \param pUsart  Pointer to an USART peripheral.
+ * \param TimeGaurd  TimeGaurd value
+ * \return None
+ */
+void USART_EnableTxTimeGaurd(Usart *pUsart, uint32_t TimeGaurd)
+{
+	if (((pUsart->US_MR & US_MR_USART_MODE_LON) && TimeGaurd <= 16777215) ||
+		 ((pUsart->US_MR & US_MR_USART_MODE_LON) && TimeGaurd <= 255))
+		pUsart->US_TTGR = TimeGaurd;
+	else
+		TRACE_ERROR(" TimeGaurd Value is too big for mode");
+}
+/**
+ * \brief  Acknowledge Rx timeout and sets to Idle or periodic repetitive state.
+ *
+ * \param pUsart  Pointer to an USART peripheral.
+ * \param Periodic  If timeout is periodic or should wait for new char
+ * \return None
+ */
+void USART_AcknowledgeRxTimeOut(Usart *pUsart, uint8_t Periodic)
+{
+	if (Periodic) {
+		pUsart->US_CR = US_CR_RETTO;     // Restart timeout timer
+	} else {
+		// Puts USARt in Idle mode and waits for a char after timeout
+		pUsart->US_CR = US_CR_STTTO;
+	}
+}
Index: bsps/arm/atsam/contrib/libraries/libchip/source/usart_dma.c
===================================================================
--- bsps/arm/atsam/contrib/libraries/libchip/source/usart_dma.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libchip/source/usart_dma.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,600 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+/**
+* \addtogroup usart_dma_module USART xDMA driver
+* \section Usage
+*
+* <ul>
+* <li> USARTD_Configure() initializes and configures the USART peripheral
+* and xDMA for data transfer.</li>
+* <li> Configures the parameters for the device corresponding to the cs
+* value by USARTD_ConfigureCS(). </li>
+* </ul>
+*
+*/
+
+/**
+ * \file
+ *
+ * Implementation for the USART with xDMA driver.
+ *
+ */
+
+/*----------------------------------------------------------------------------
+ *        Headers
+ *----------------------------------------------------------------------------*/
+
+#include "chip.h"
+#include "string.h"
+#include "stdlib.h"
+
+/*----------------------------------------------------------------------------
+ *        Local functions
+ *----------------------------------------------------------------------------*/
+
+/**
+ * \brief USART xDMA Rx callback
+ * Invoked on USART DMA reception done.
+ * \param channel DMA channel.
+ * \param pArg Pointer to callback argument - Pointer to USARTDma instance.
+ */
+static void USARTD_Rx_Cb(uint32_t channel, UsartDma *pArg)
+{
+
+	UsartChannel *pUsartdCh = pArg->pRxChannel;
+
+	if (channel != pUsartdCh->ChNum)
+		return;
+
+	/* Release the DMA channels */
+	XDMAD_FreeChannel(pArg->pXdmad, pUsartdCh->ChNum);
+	pUsartdCh->dmaProgress = 1;
+	SCB_InvalidateDCache_by_Addr((uint32_t *)pUsartdCh->pBuff, pUsartdCh->BuffSize);
+
+}
+
+/**
+ * \brief USART xDMA Rx callback
+ * Invoked on USART DMA reception done.
+ * \param channel DMA channel.
+ * \param pArg Pointer to callback argument - Pointer to USARTDma instance.
+ */
+static void USARTD_Tx_Cb(uint32_t channel, UsartDma *pArg)
+{
+	UsartChannel *pUsartdCh = pArg->pTxChannel;
+
+	if (channel != pUsartdCh->ChNum)
+		return;
+
+	/* Release the DMA channels */
+	XDMAD_FreeChannel(pArg->pXdmad, pUsartdCh->ChNum);
+
+	pUsartdCh->dmaProgress = 1;
+}
+
+/**
+ * \brief Configure the USART Rx DMA Destination with Linker List mode.
+ *
+ * \param UsartChannel Pointer to USART dma channel
+ * \returns 0 if the dma multibuffer configuration successfully; otherwise
+ * returnsUSARTD_ERROR_XXX.
+ */
+static uint8_t _configureRxDma(UsartDma *pUsart, UsartChannel *pUsartRx)
+{
+	sXdmadCfg xdmadRxCfg;
+	uint32_t xdmaCndc, xdmaInt;
+	uint32_t i, LLI_Size;
+	Usart *pUsartHwRx = pUsart->pUsartHw;
+	sXdmad *pXdmadRx = pUsart->pXdmad;
+	uint8_t *pBuff = 0;
+
+
+	/* Setup RX Single block */
+	if (pUsartRx->dmaProgrammingMode < XDMAD_LLI) {
+		xdmadRxCfg.mbr_ubc = pUsartRx->BuffSize;
+		xdmadRxCfg.mbr_da = (uint32_t)pUsartRx->pBuff;
+
+		xdmadRxCfg.mbr_sa = (uint32_t)&pUsartHwRx->US_RHR;
+		xdmadRxCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN |
+							 XDMAC_CC_MBSIZE_SIXTEEN |
+							 XDMAC_CC_DSYNC_PER2MEM |
+							 XDMAC_CC_CSIZE_CHK_1 |
+							 XDMAC_CC_DWIDTH_BYTE |
+							 XDMAC_CC_SIF_AHB_IF1 |
+							 XDMAC_CC_DIF_AHB_IF1 |
+							 XDMAC_CC_SAM_FIXED_AM |
+							 XDMAC_CC_DAM_INCREMENTED_AM |
+							 XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber
+											(pUsart->usartId, XDMAD_TRANSFER_RX));
+
+		xdmadRxCfg.mbr_bc = 0;
+
+		if (pUsartRx->dmaProgrammingMode == XDMAD_MULTI)
+			xdmadRxCfg.mbr_bc = pUsartRx->dmaBlockSize;
+
+		xdmadRxCfg.mbr_sus = 0;
+		xdmadRxCfg.mbr_dus = 0;
+		xdmaCndc = 0;
+		xdmaInt =  (XDMAC_CIE_BIE   |
+					XDMAC_CIE_DIE   |
+					XDMAC_CIE_FIE   |
+					XDMAC_CIE_RBIE  |
+					XDMAC_CIE_WBIE  |
+					XDMAC_CIE_ROIE);
+	} else if (pUsartRx->dmaProgrammingMode == XDMAD_LLI) {
+
+		/* Setup RX Link List */
+		LLI_Size = pUsartRx->dmaBlockSize;
+		pBuff = pUsartRx->pBuff;
+
+		if (pUsartRx->pLLIview != NULL) {
+			free(pUsartRx->pLLIview);
+			pUsartRx->pLLIview = NULL;
+		}
+
+		pUsartRx->pLLIview = malloc(sizeof(LinkedListDescriporView1) * LLI_Size);
+
+		if (pUsartRx->pLLIview == NULL) {
+			TRACE_ERROR(" Can not allocate memory to Rx LLI");
+			return USARTD_ERROR;
+		}
+
+		xdmadRxCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN |
+							 XDMAC_CC_MBSIZE_SIXTEEN |
+							 XDMAC_CC_DSYNC_PER2MEM |
+							 XDMAC_CC_MEMSET_NORMAL_MODE |
+							 XDMAC_CC_CSIZE_CHK_1 |
+							 XDMAC_CC_DWIDTH_BYTE |
+							 XDMAC_CC_SIF_AHB_IF1 |
+							 XDMAC_CC_DIF_AHB_IF1 |
+							 XDMAC_CC_SAM_FIXED_AM |
+							 XDMAC_CC_DAM_INCREMENTED_AM |
+							 XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber
+											(pUsart->usartId, XDMAD_TRANSFER_RX));
+		xdmadRxCfg.mbr_bc = 0;
+
+		for (i = 0; i < LLI_Size; i++) {
+			pUsartRx->pLLIview[i].mbr_ubc = XDMA_UBC_NVIEW_NDV1 |
+											XDMA_UBC_NSEN_UNCHANGED |
+											XDMA_UBC_NDEN_UPDATED |
+											((i == LLI_Size - 1) ? (
+												 (pUsartRx->dmaRingBuffer) ?
+												 XDMA_UBC_NDE_FETCH_EN : 0) :
+											 XDMA_UBC_NDE_FETCH_EN) |
+											pUsartRx->BuffSize;
+			pUsartRx->pLLIview[i].mbr_sa = (uint32_t)&pUsartHwRx->US_RHR;
+			pUsartRx->pLLIview[i].mbr_da = (uint32_t)pBuff;
+			pUsartRx->pLLIview[i].mbr_nda = (i == (LLI_Size - 1)) ?
+											((pUsartRx->dmaRingBuffer) ? (uint32_t)pUsartRx->pLLIview : 0)
+											: (uint32_t)&pUsartRx->pLLIview[ i + 1 ];
+			pBuff += pUsartRx->BuffSize;
+		}
+
+		SCB_CleanDCache_by_Addr((uint32_t *)(pUsartRx->pLLIview),
+								sizeof(LinkedListDescriporView1)*LLI_Size);
+		xdmaCndc = XDMAC_CNDC_NDVIEW_NDV1 |
+				   XDMAC_CNDC_NDE_DSCR_FETCH_EN |
+				   XDMAC_CNDC_NDSUP_SRC_PARAMS_UPDATED |
+				   XDMAC_CNDC_NDDUP_DST_PARAMS_UPDATED;
+		xdmaInt = ((pUsartRx->dmaRingBuffer) ? XDMAC_CIE_BIE : XDMAC_CIE_LIE);
+	} else
+		return 1;
+
+	if (XDMAD_ConfigureTransfer(
+			pXdmadRx, pUsartRx->ChNum, &xdmadRxCfg, xdmaCndc,
+			(uint32_t)pUsartRx->pLLIview, xdmaInt))
+		return USARTD_ERROR;
+
+	return 0;
+}
+
+/**
+ * \brief Configure the USART tx DMA source with Linker List mode.
+ *
+ * \param UsartChannel Pointer to USART dma channel
+  * \returns 0 if the dma multibuffer configuration successfully; otherwise returns
+ * USARTD_ERROR_XXX.
+ */
+static uint8_t _configureTxDma(UsartDma *pUsart, UsartChannel *pUsartTx)
+{
+	sXdmadCfg xdmadTxCfg;
+	uint32_t xdmaCndc, xdmaInt, LLI_Size, i;
+	uint8_t *pBuff = 0;
+	Usart *pUsartHwTx = pUsart->pUsartHw;
+	sXdmad *pXdmadTx = pUsart->pXdmad;
+
+	/* Setup TX Link List */
+
+	if (pUsartTx->dmaProgrammingMode < XDMAD_LLI) {
+		/* Number of Data */
+		xdmadTxCfg.mbr_ubc =   pUsartTx->BuffSize;
+		/* Source and Destination address of DMA */
+		xdmadTxCfg.mbr_sa = (uint32_t)pUsartTx->pBuff;
+		xdmadTxCfg.mbr_da = (uint32_t)&pUsartHwTx->US_THR;
+		/* DMA Channel configuration */
+		xdmadTxCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN |
+							 XDMAC_CC_MBSIZE_SIXTEEN |
+							 XDMAC_CC_DSYNC_MEM2PER |
+							 XDMAC_CC_CSIZE_CHK_1 |
+							 XDMAC_CC_DWIDTH_BYTE |
+							 XDMAC_CC_SIF_AHB_IF1 |
+							 XDMAC_CC_DIF_AHB_IF1 |
+							 XDMAC_CC_SAM_INCREMENTED_AM |
+							 XDMAC_CC_DAM_FIXED_AM |
+							 XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber
+											(pUsart->usartId, XDMAD_TRANSFER_TX));
+
+		xdmadTxCfg.mbr_bc = 0;
+
+		if (pUsartTx->dmaProgrammingMode == XDMAD_MULTI)
+			xdmadTxCfg.mbr_bc = pUsartTx->dmaBlockSize;
+
+		xdmadTxCfg.mbr_sus = 0;
+		xdmadTxCfg.mbr_dus = 0;
+		xdmadTxCfg.mbr_ds = 0;
+		xdmaCndc = 0;
+		/* Enable End of Block; Read Bus error;  Write Bus Error;
+		Overflow Error interrupt */
+		xdmaInt =  (XDMAC_CIE_BIE    |
+					XDMAC_CIE_RBIE  |
+					XDMAC_CIE_WBIE  |
+					XDMAC_CIE_ROIE);
+	} else if (pUsartTx->dmaProgrammingMode == XDMAD_LLI) {
+		LLI_Size = pUsartTx->dmaBlockSize;
+		pBuff = pUsartTx->pBuff;
+
+		/* If channel's LLI is already configured and application
+		want to reconfigured it, free before re-allocating memory */
+		if (pUsartTx->pLLIview != NULL) {
+			free(pUsartTx->pLLIview);
+			pUsartTx->pLLIview = NULL;
+		}
+
+		pUsartTx->pLLIview = malloc(sizeof(LinkedListDescriporView1) * LLI_Size);
+
+		if (pUsartTx->pLLIview == NULL) {
+			TRACE_ERROR(" Can not allocate memory to Tx LLI");
+			return USARTD_ERROR;
+		}
+
+		xdmadTxCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN |
+							 XDMAC_CC_MBSIZE_SIXTEEN |
+							 XDMAC_CC_DSYNC_MEM2PER |
+							 XDMAC_CC_MEMSET_NORMAL_MODE |
+							 XDMAC_CC_CSIZE_CHK_1 |
+							 XDMAC_CC_DWIDTH_BYTE |
+							 XDMAC_CC_SIF_AHB_IF1 |
+							 XDMAC_CC_DIF_AHB_IF1 |
+							 XDMAC_CC_SAM_INCREMENTED_AM |
+							 XDMAC_CC_DAM_FIXED_AM |
+							 XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber
+											(pUsart->usartId, XDMAD_TRANSFER_TX));
+		xdmadTxCfg.mbr_bc = 0;
+
+		for (i = 0; i < LLI_Size; i++) {
+			pUsartTx->pLLIview[i].mbr_ubc = XDMA_UBC_NVIEW_NDV1 |
+											XDMA_UBC_NSEN_UPDATED |
+											XDMA_UBC_NDEN_UNCHANGED |
+											((i == LLI_Size - 1) ? ((pUsartTx->dmaRingBuffer)
+													? XDMA_UBC_NDE_FETCH_EN : 0) :
+											 XDMA_UBC_NDE_FETCH_EN) | pUsartTx->BuffSize;
+			pUsartTx->pLLIview[i].mbr_sa = (uint32_t)pBuff;
+			pUsartTx->pLLIview[i].mbr_da = (uint32_t)&pUsartHwTx->US_THR;
+			pUsartTx->pLLIview[i].mbr_nda = (i == (LLI_Size - 1)) ?
+											((pUsartTx->dmaRingBuffer) ? (uint32_t)pUsartTx->pLLIview : 0)
+											: (uint32_t)&pUsartTx->pLLIview[ i + 1 ];
+			pBuff += pUsartTx->BuffSize;
+		}
+
+		SCB_CleanDCache_by_Addr((uint32_t *)(pUsartTx->pLLIview),
+								sizeof(LinkedListDescriporView1)*LLI_Size);
+		xdmaCndc = XDMAC_CNDC_NDVIEW_NDV1 |
+				   XDMAC_CNDC_NDE_DSCR_FETCH_EN |
+				   XDMAC_CNDC_NDSUP_SRC_PARAMS_UPDATED |
+				   XDMAC_CNDC_NDDUP_DST_PARAMS_UPDATED;
+		xdmaInt = ((pUsartTx->dmaRingBuffer) ? XDMAC_CIE_BIE : XDMAC_CIE_LIE);
+	} else {
+		TRACE_ERROR("DmaProgState is incorrect \n\r");
+		return 1;
+	}
+
+	if (XDMAD_ConfigureTransfer(pXdmadTx, pUsartTx->ChNum,
+								 &xdmadTxCfg, xdmaCndc, (uint32_t)pUsartTx->pLLIview, xdmaInt))
+		return USARTD_ERROR;
+
+	return 0;
+}
+
+/*----------------------------------------------------------------------------
+ *        Exported functions
+ *----------------------------------------------------------------------------*/
+/**
+ * \brief Initializes the USARTDma structure and the corresponding USART & DMA .
+ * hardware select value.
+ * The driver will uses DMA channel 0 for RX and DMA channel 1 for TX.
+ * The DMA channels are freed automatically when no USART command processing.
+ *
+ * \param pUSARTD  Pointer to a UsartDma instance.
+ * \param pUsartHw Associated USART peripheral.
+ * \param usartId  USART peripheral identifier.
+ * \param UsartClk USART clock.
+ * \param pXdmad  Pointer to a Dmad instance.
+ */
+uint32_t USARTD_Configure(UsartDma *pUsartd ,
+						   uint8_t usartId,
+						   uint32_t UsartMode,
+						   uint32_t BaudRate,
+						   uint32_t UsartClk)
+{
+	/* Enable the peripheral clock in the PMC*/
+	PMC_EnablePeripheral(usartId);
+
+	/* Initialize the USART structure */
+	pUsartd->usartId  = usartId;
+
+	if (usartId == ID_USART0)
+		pUsartd->pUsartHw = USART0;
+
+	if (usartId == ID_USART1)
+		pUsartd->pUsartHw = USART1;
+
+	if (usartId == ID_USART2)
+		pUsartd->pUsartHw = USART2;
+
+
+	/* Enable the USART Peripheral ,Execute a software reset of the USART,
+	    Configure USART in Master Mode*/
+	USART_Configure (pUsartd->pUsartHw, UsartMode, BaudRate, UsartClk);
+
+	/* Check if DMA IRQ is enable; if not clear pending IRQs in init it */
+	if (!(NVIC_GetActive(XDMAC_IRQn)))
+		NVIC_ClearPendingIRQ(XDMAC_IRQn);
+
+	return 0;
+}
+
+/**
+ * \brief This function initialize the appropriate DMA channel for Rx channel
+ * of USART
+ * \param pUsartd       Pointer to a UsartDma instance.
+ * \param pRxCh         Pointer to TxChannel configuration
+ * \returns             0 if the transfer has been started successfully;
+ * otherwise returns USARTD_ERROR_LOCK is the driver is in use, or
+ * USARTD_ERROR if the command is not valid.
+ */
+uint32_t USARTD_EnableRxChannels(UsartDma *pUsartd, UsartChannel *pRxCh)
+{
+	uint32_t Channel;
+
+	assert(pRxCh);
+	/* Init USART Rx Channel. */
+	pUsartd->pRxChannel = pRxCh;
+
+	/* Enables the USART to receive data. */
+	USART_SetReceiverEnabled (pUsartd->pUsartHw , ENABLE);
+
+
+	/* Allocate a DMA channel for USART0/1 RX. */
+	Channel =  XDMAD_AllocateChannel(pUsartd->pXdmad, pUsartd->usartId,
+									  XDMAD_TRANSFER_MEMORY);
+
+	if (Channel == XDMAD_ALLOC_FAILED)
+		return USARTD_ERROR;
+
+	pRxCh->ChNum = Channel;
+
+	/* Setup callbacks for USART RX */
+	if (pUsartd->pRxChannel->callback) {
+		XDMAD_SetCallback(pUsartd->pXdmad, pRxCh->ChNum,
+						  (XdmadTransferCallback)pRxCh->callback, pRxCh->pArgument);
+	} else {
+		XDMAD_SetCallback(pUsartd->pXdmad, pRxCh->ChNum,
+						  (XdmadTransferCallback)USARTD_Rx_Cb, pUsartd);
+	}
+
+
+	if (XDMAD_PrepareChannel(pUsartd->pXdmad, pRxCh->ChNum))
+		return USARTD_ERROR;
+
+	if (_configureRxDma(pUsartd , pUsartd->pRxChannel))
+		return USARTD_ERROR_LOCK;
+
+	/* Check if DMA IRQ is enable; if not Enable it */
+	if (!(NVIC_GetActive(XDMAC_IRQn))) {
+		/* Enable interrupt  */
+		NVIC_EnableIRQ(XDMAC_IRQn);
+	}
+
+	return 0;
+}
+
+/**
+ * \brief This function initialize the appropriate DMA channel for Tx channel
+ * of USART
+ * \param pUsartd       Pointer to a USARTDma instance.
+ * \param pTxCh         Pointer to TxChannel configuration
+ * \returns             0 if the transfer has been started successfully;
+ * otherwise returns USARTD_ERROR_LOCK is the driver is in use, or
+ * USARTD_ERROR if the command is not valid.
+ */
+uint32_t USARTD_EnableTxChannels(UsartDma *pUsartd, UsartChannel *pTxCh)
+{
+
+	uint32_t Channel;
+
+	assert(pTxCh);
+
+	/* Init USART Tx Channel. */
+	pUsartd->pTxChannel = pTxCh;
+
+	/* Enables the USART to transfer data. */
+	USART_SetTransmitterEnabled (pUsartd->pUsartHw , ENABLE);
+
+	/* Allocate a DMA channel for USART0/1 TX. */
+	Channel =  XDMAD_AllocateChannel(pUsartd->pXdmad, XDMAD_TRANSFER_MEMORY,
+									  pUsartd->usartId);
+
+	if (Channel == XDMAD_ALLOC_FAILED)
+		return USARTD_ERROR;
+
+	pTxCh->ChNum = Channel;
+
+	/* Setup callbacks for USART0/1 TX */
+	if (pUsartd->pTxChannel->callback) {
+		XDMAD_SetCallback(pUsartd->pXdmad, pTxCh->ChNum,
+						  (XdmadTransferCallback)pTxCh->callback, pTxCh->pArgument);
+	} else
+		XDMAD_SetCallback(pUsartd->pXdmad, pTxCh->ChNum,
+						  (XdmadTransferCallback)USARTD_Tx_Cb, pUsartd);
+
+	if (XDMAD_PrepareChannel(pUsartd->pXdmad, pTxCh->ChNum))
+		return USARTD_ERROR;
+
+	if (_configureTxDma(pUsartd , pUsartd->pTxChannel))
+		return USARTD_ERROR_LOCK;
+
+	/* Check if DMA IRQ is enable; if not Enable it */
+	if (!(NVIC_GetActive(XDMAC_IRQn))) {
+		/* Enable interrupt  */
+		NVIC_EnableIRQ(XDMAC_IRQn);
+	}
+
+	return 0;
+}
+
+/**
+ * \brief This function disables the appropriate DMA channel for Rx channel of
+ * USART
+ * \param pUsartd       Pointer to a UsartDma instance.
+ * \param pRxCh         Pointer to TxChannel configuration
+ * \returns             0 if the transfer has been started successfully;
+ * otherwise returns USARTD_ERROR_LOCK is the driver is in use, or
+ * USARTD_ERROR if the command is not valid.
+ */
+uint32_t USARTD_DisableRxChannels(UsartDma *pUsartd, UsartChannel *pRxCh)
+{
+	assert(pRxCh);
+
+	/* Enables the USART to transfer data. */
+	USART_SetReceiverEnabled (pUsartd->pUsartHw , DISABLE);
+
+	XDMAD_StopTransfer(pUsartd->pXdmad, pRxCh->ChNum);
+
+	XDMAD_SetCallback(pUsartd->pXdmad, pRxCh->ChNum, NULL, NULL);
+
+	/* Free allocated DMA channel for USART TX. */
+	if (XDMAD_FreeChannel(pUsartd->pXdmad, pRxCh->ChNum) != XDMAD_OK)
+		return USARTD_ERROR;
+
+	if (pRxCh->dmaProgrammingMode == XDMAD_LLI) {
+		free(pRxCh->pLLIview);
+		pRxCh->pLLIview = NULL;
+	}
+
+	pRxCh->dmaProgress = 1;
+	return 0;
+}
+
+/**
+ * \brief This function disables the appropriate DMA channel for Tx channel of
+ * USART
+ * \param pUsartd       Pointer to a USARTDma instance.
+ * \param pTxCh         Pointer to TxChannel configuration
+ * \returns             0 if the transfer has been started successfully;
+ * otherwise returns USARTD_ERROR_LOCK is the driver is in use, or
+ * USARTD_ERROR if the command is not valid.
+ */
+
+uint32_t USARTD_DisableTxChannels(UsartDma *pUsartd, UsartChannel *pTxCh)
+{
+	assert(pTxCh);
+
+	/* Enables the USART to transfer data. */
+	USART_SetTransmitterEnabled (pUsartd->pUsartHw , DISABLE);
+
+	XDMAD_StopTransfer(pUsartd->pXdmad, pTxCh->ChNum);
+
+	XDMAD_SetCallback(pUsartd->pXdmad, pTxCh->ChNum, NULL, NULL);
+
+	/* Free allocated DMA channel for USART TX. */
+	if (XDMAD_FreeChannel(pUsartd->pXdmad, pTxCh->ChNum) != XDMAD_OK)
+		return USARTD_ERROR;
+
+	if (pTxCh->dmaProgrammingMode == XDMAD_LLI) {
+		free(pTxCh->pLLIview);
+		pTxCh->pLLIview = NULL;
+	}
+
+	pTxCh->dmaProgress = 1;
+	return 0;
+}
+
+/**
+ * \brief Starts a USART master transfer. This is a non blocking function. It
+ * will return as soon as the transfer is started.
+ *
+ * \param pUSARTD  Pointer to a USARTDma instance.
+ * \returns 0 if the transfer has been started successfully; otherwise returns
+ * USARTD_ERROR_LOCK is the driver is in use, or USARTD_ERROR if the command is
+ * not valid.
+ */
+uint32_t USARTD_SendData(UsartDma *pUsartd)
+{
+	/* Start DMA 0(RX) && 1(TX) */
+	pUsartd->pTxChannel->dmaProgress = 0;
+	SCB_CleanDCache_by_Addr((uint32_t *)pUsartd->pTxChannel->pBuff,
+							pUsartd->pTxChannel->BuffSize);
+
+	if (XDMAD_StartTransfer(pUsartd->pXdmad, pUsartd->pTxChannel->ChNum))
+		return USARTD_ERROR_LOCK;
+
+	return 0;
+}
+
+/**
+ * \brief Starts a USART master transfer. This is a non blocking function. It will
+ *  return as soon as the transfer is started.
+ *
+ * \param pUSARTD  Pointer to a USARTDma instance.
+ * \returns 0 if the transfer has been started successfully; otherwise returns
+ * USARTD_ERROR_LOCK is the driver is in use, or USARTD_ERROR if the command is not
+ * valid.
+ */
+uint32_t USARTD_RcvData(UsartDma *pUsartd)
+{
+	/* Start DMA 0(RX) && 1(TX) */
+	pUsartd->pRxChannel->dmaProgress = 0;
+
+	if (XDMAD_StartTransfer(pUsartd->pXdmad, pUsartd->pRxChannel->ChNum))
+		return USARTD_ERROR_LOCK;
+
+	return 0;
+}
+
Index: bsps/arm/atsam/contrib/libraries/libchip/source/wdt.c
===================================================================
--- bsps/arm/atsam/contrib/libraries/libchip/source/wdt.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libchip/source/wdt.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,133 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+/**
+ * \file
+ *
+ * Implementation of Watchdog Timer (WDT) controller.
+ *
+ */
+
+/** \addtogroup wdt_module Working with WDT
+ *  \ingroup peripherals_module
+ * The WDT driver provides the interface to configure and use the WDT
+ * peripheral.
+ *
+ * The WDT can be used to prevent system lock-up if the software becomes
+ * trapped in a deadlock. It can generate a general reset or a processor
+ * reset only. It is clocked by slow clock divided by 128.
+ *
+ * The WDT is running at reset with 16 seconds watchdog period (slow clock at
+ * 32.768 kHz)
+ * and external reset generation enabled. The user must either disable it or
+ * reprogram it to meet the application requires.
+ *
+ * To use the WDT, the user could follow these few steps:
+ * <ul>
+ * <li>Enable watchdog with given mode using \ref WDT_Enable().
+ * <li>Restart the watchdog using \ref WDT_Restart() within the watchdog period.
+ * </ul>
+ *
+ * For more accurate information, please look at the WDT section of the
+ * Datasheet.
+ *
+ * \note
+ * The Watchdog Mode Register (WDT_MR) can be written only once.\n
+ *
+ * Related files :\n
+ * \ref wdt.c\n
+ * \ref wdt.h.\n
+ */
+/*@{*/
+/*@}*/
+
+/*---------------------------------------------------------------------------
+ *        Headers
+ *---------------------------------------------------------------------------*/
+
+#include "chip.h"
+
+#include <stdint.h>
+
+/*----------------------------------------------------------------------------
+ *        Exported functions
+ *----------------------------------------------------------------------------*/
+
+/**
+ * \brief Enable watchdog with given mode.
+ *
+ * \note The Watchdog Mode Register (WDT_MR) can be written only once.
+ * Only a processor reset resets it.
+ *
+ * \param dwMode   WDT mode to be set
+ */
+extern void WDT_Enable(Wdt *pWDT, uint32_t dwMode)
+{
+	pWDT->WDT_MR = dwMode;
+}
+
+/**
+ * \brief Disable watchdog.
+ *
+ * \note The Watchdog Mode Register (WDT_MR) can be written only once.
+ * Only a processor reset resets it.
+ */
+extern void WDT_Disable(Wdt *pWDT)
+{
+	pWDT->WDT_MR = WDT_MR_WDDIS;
+}
+
+/**
+ * \brief Watchdog restart.
+ */
+extern void WDT_Restart(Wdt *pWDT)
+{
+	pWDT->WDT_CR = 0xA5000001;
+}
+
+/**
+ * \brief Watchdog get status.
+ */
+extern uint32_t WDT_GetStatus(Wdt *pWDT)
+{
+	return (pWDT->WDT_SR & 0x3);
+}
+
+/**
+ * \brief Watchdog get period.
+ *
+ * \param dwMs   desired watchdog period in millisecond.
+ */
+extern uint32_t WDT_GetPeriod(uint32_t dwMs)
+{
+	if ((dwMs < 4) || (dwMs > 16000))
+		return 0;
+
+	return ((dwMs << 8) / 1000);
+}
Index: bsps/arm/atsam/contrib/libraries/libchip/source/xdma_hardware_interface.c
===================================================================
--- bsps/arm/atsam/contrib/libraries/libchip/source/xdma_hardware_interface.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libchip/source/xdma_hardware_interface.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,158 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+/** \addtogroup dmad_module
+ *
+ * \section DmaHw Dma Hardware Interface Usage
+ * <ul>
+ * <li> The DMA controller can handle the transfer between peripherals and memory
+ * and so receives the triggers from the peripherals. The hardware interface
+ * number are getting from DMAIF_Get_ChannelNumber().</li>
+
+ * <li> DMAIF_IsValidatedPeripherOnDma() helps to check if the given DMAC has
+ * associated peripheral identifier coded by the given  peripheral.</li>
+ *
+ * </ul>
+ */
+/*@{*/
+/*@}*/
+
+/** \file */
+/*----------------------------------------------------------------------------
+ *        Headers
+ *----------------------------------------------------------------------------*/
+#include "chip.h"
+
+/*----------------------------------------------------------------------------
+ *        Local variables
+ *----------------------------------------------------------------------------*/
+/** Array of DMA Channel definition for SAMv7 chip*/
+static const XdmaHardwareInterface xdmaHwIf[] = {
+	/* xdmac, peripheral,  T/R, HW interface number*/
+	{0,   ID_HSMCI,     0,      0},
+	{0,   ID_HSMCI,     1,      0},
+	{0,   ID_SPI0,      0,      1},
+	{0,   ID_SPI0,      1,      2},
+	{0,   ID_SPI1,      0,      3},
+	{0,   ID_SPI1,      1,      4},
+	{0,   ID_QSPI,      0,      5},
+	{0,   ID_QSPI,      1,      6},
+	{0,   ID_USART0,    0,      7},
+	{0,   ID_USART0,    1,      8},
+	{0,   ID_USART1,    0,      9},
+	{0,   ID_USART1,    1,      10},
+	{0,   ID_USART2,    0,      11},
+	{0,   ID_USART2,    1,      12},
+	{0,   ID_PWM0,      0,      13},
+	{0,   ID_TWIHS0,    0,      14},
+	{0,   ID_TWIHS0,    1,      15},
+	{0,   ID_TWIHS1,    0,      16},
+	{0,   ID_TWIHS1,    1,      17},
+	{0,   ID_TWIHS2,    0,      18},
+	{0,   ID_TWIHS2,    1,      19},
+	{0,   ID_UART0,     0,      20},
+	{0,   ID_UART0,     1,      21},
+	{0,   ID_UART1,     0,      22},
+	{0,   ID_UART1,     1,      23},
+	{0,   ID_UART2,     0,      24},
+	{0,   ID_UART2,     1,      25},
+	{0,   ID_UART3,     0,      26},
+	{0,   ID_UART3,     1,      27},
+	{0,   ID_UART4,     0,      28},
+	{0,   ID_UART4,     1,      29},
+	{0,   ID_DACC,      0,      30},
+	{0,   ID_DACC,      0,      31},
+	{0,   ID_SSC,       0,      32},
+	{0,   ID_SSC,       1,      33},
+	{0,   ID_PIOA,      1,      34},
+	{0,   ID_AFEC0,     1,      35},
+	{0,   ID_AFEC1,     1,      36},
+	{0,   ID_AES,       0,      37},
+	{0,   ID_AES,       1,      38},
+	{0,   ID_PWM1,      0,      39},
+	{0,   ID_TC0,       1,      40},
+	{0,   ID_TC1,       1,      41},
+	{0,   ID_TC2,       1,      42},
+	{0,   ID_TC3,       1,      43},
+};
+
+
+/*----------------------------------------------------------------------------
+ *        Exported functions
+ *----------------------------------------------------------------------------*/
+
+/**
+ * \brief Get peripheral identifier coded for hardware handshaking interface
+ *
+ * \param bDmac      DMA Controller number.
+ * \param bPeriphID  Peripheral ID.
+ * \param bTransfer  Transfer type 0: Tx, 1 :Rx.
+ * \return 0-15 peripheral identifier coded.
+ *         0xff : no associated peripheral identifier coded.
+ */
+uint8_t XDMAIF_Get_ChannelNumber (uint8_t bPeriphID,
+								  uint8_t bTransfer)
+{
+	uint8_t i;
+	uint8_t NumOfPeripheral = ((XDMAC_GetType(XDMAC) & 0x00FF0000) >> 16);
+
+	for (i = 0; i <= NumOfPeripheral; i++) {
+		if ((xdmaHwIf[i].bPeriphID == bPeriphID) &&
+			 (xdmaHwIf[i].bTransfer == bTransfer))
+			return xdmaHwIf[i].bIfID;
+	}
+
+	return 0xff;
+}
+
+/**
+ * \brief Check if the given DMAC has associated peripheral identifier coded by
+ * the given  peripheral.
+ *
+ * \param bDmac      DMA Controller number.
+ * \param bPeriphID  Peripheral ID (0xff : memory only).
+ * \return 1:  Is a validated peripheral. 0: no associated peripheral identifier
+ * coded.
+ */
+uint8_t XDMAIF_IsValidatedPeripherOnDma(uint8_t bPeriphID)
+{
+	uint8_t i;
+	uint8_t NumOfPeripheral = ((XDMAC_GetType(XDMAC) & 0x00FF0000) >> 16);
+
+	/* It is always validated when transfer to memory */
+	if (bPeriphID == 0xFF)
+		return 1;
+
+	for (i = 0; i <= NumOfPeripheral; i++) {
+		if ((xdmaHwIf[i].bPeriphID == bPeriphID))
+			return 1;
+	}
+
+	return 0;
+}
Index: bsps/arm/atsam/contrib/libraries/libchip/source/xdmad.c
===================================================================
--- bsps/arm/atsam/contrib/libraries/libchip/source/xdmad.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/libraries/libchip/source/xdmad.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,495 @@
+/* ---------------------------------------------------------------------------- */
+/*                  Atmel Microcontroller Software Support                      */
+/*                       SAM Software Package License                           */
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2015, Atmel Corporation                                        */
+/*                                                                              */
+/* All rights reserved.                                                         */
+/*                                                                              */
+/* Redistribution and use in source and binary forms, with or without           */
+/* modification, are permitted provided that the following condition is met:    */
+/*                                                                              */
+/* - Redistributions of source code must retain the above copyright notice,     */
+/* this list of conditions and the disclaimer below.                            */
+/*                                                                              */
+/* Atmel's name may not be used to endorse or promote products derived from     */
+/* this software without specific prior written permission.                     */
+/*                                                                              */
+/* DISCLAIMER:  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   */
+/* 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.                           */
+/* ---------------------------------------------------------------------------- */
+
+/** \addtogroup xdmad_module
+ *
+ * \section Xdma xDma Configuration Usage
+ *
+ * To configure a XDMA channel, the user has to follow these few steps :
+ * <ul>
+ * <li> Initialize a XDMA driver instance by XDMAD_Initialize().</li>
+ * <li> choose an available (disabled) channel using XDMAD_AllocateChannel().</li>
+ * <li> After the XDMAC selected channel has been programmed,
+ * XDMAD_PrepareChannel() is to enable clock and dma peripheral of the DMA, and
+ * set Configuration register to set up the transfer type (memory or non-memory
+ * peripheral for source and destination) and flow control device.</li>
+ * <li> Invoke XDMAD_StartTransfer() to start DMA transfer  or
+ * XDMAD_StopTransfer() to force stop DMA transfer.</li>
+ * <li> Once the buffer of data is transferred, XDMAD_IsTransferDone()
+ * checks if DMA transfer is finished.</li>
+ * <li> XDMAD_Handler() handles XDMA interrupt, and invoking XDMAD_SetCallback()
+ * if provided.</li>
+ * </ul>
+ *
+ * Related files:\n
+ * \ref xdmad.h\n
+ * \ref xdmad.c.\n
+ */
+
+/** \file */
+
+/** \addtogroup dmad_functions
+  @{*/
+
+/*----------------------------------------------------------------------------
+ *        Includes
+ *----------------------------------------------------------------------------*/
+
+#include "chip.h"
+#ifdef __rtems__
+#include "../../../utils/utility.h"
+#include <rtems/irq-extension.h>
+#include <rtems/sysinit.h>
+#include <bsp/fatal.h>
+#endif /* __rtems__ */
+#include <assert.h>
+
+/*----------------------------------------------------------------------------
+ *        Local functions
+ *----------------------------------------------------------------------------*/
+static void XDMAD_Handler(void *arg);
+/**
+ * \brief Try to allocate a DMA channel for on given controller.
+ * \param pDmad  Pointer to DMA driver instance.
+ * \param bSrcID Source peripheral ID, 0xFF for memory.
+ * \param bDstID Destination peripheral ID, 0xFF for memory.
+ * \return Channel number if allocation successful, return
+ * DMAD_ALLOC_FAILED if allocation failed.
+ */
+static uint32_t XDMAD_AllocateXdmacChannel(sXdmad *pXdmad,
+		uint8_t bSrcID,
+		uint8_t bDstID)
+{
+	uint32_t i;
+
+	/* Can't support peripheral to peripheral */
+	if (((bSrcID != XDMAD_TRANSFER_MEMORY)
+		 && (bDstID != XDMAD_TRANSFER_MEMORY)))
+		return XDMAD_ALLOC_FAILED;
+
+	/* dma transfer from peripheral to memory */
+	if (bDstID == XDMAD_TRANSFER_MEMORY) {
+		if ((!XDMAIF_IsValidatedPeripherOnDma(bSrcID))) {
+			TRACE_ERROR("%s:: Allocation failed", __FUNCTION__);
+			return XDMAD_ALLOC_FAILED;
+		}
+	}
+
+	/* dma transfer from memory to peripheral */
+	if (bSrcID == XDMAD_TRANSFER_MEMORY) {
+		if ((!XDMAIF_IsValidatedPeripherOnDma(bDstID))) {
+			TRACE_ERROR("%s:: Allocation failed", __FUNCTION__);
+			return XDMAD_ALLOC_FAILED;
+		}
+	}
+
+	for (i = 0; i < pXdmad->numChannels; i ++) {
+		if (pXdmad->XdmaChannels[i].state == XDMAD_STATE_FREE) {
+			/* Allocate the channel */
+			pXdmad->XdmaChannels[i].state = XDMAD_STATE_ALLOCATED;
+			/* Get general informations */
+			pXdmad->XdmaChannels[i].bSrcPeriphID = bSrcID;
+			pXdmad->XdmaChannels[i].bDstPeriphID = bDstID;
+			pXdmad->XdmaChannels[i].bSrcTxIfID =
+				XDMAIF_Get_ChannelNumber(bSrcID, 0);
+			pXdmad->XdmaChannels[i].bSrcRxIfID =
+				XDMAIF_Get_ChannelNumber(bSrcID, 1);
+			pXdmad->XdmaChannels[i].bDstTxIfID =
+				XDMAIF_Get_ChannelNumber(bDstID, 0);
+			pXdmad->XdmaChannels[i].bDstRxIfID =
+				XDMAIF_Get_ChannelNumber(bDstID, 1);
+			return  ((i) & 0xFF);
+		}
+	}
+
+	TRACE_ERROR("%s:: Allocation failed, all channels are occupied", __FUNCTION__);
+	return XDMAD_ALLOC_FAILED;
+}
+
+void XDMAD_DoNothingCallback(uint32_t Channel, void *pArg)
+{
+	/* Do nothing */
+}
+
+/*----------------------------------------------------------------------------
+ *        Exported functions
+ *----------------------------------------------------------------------------*/
+
+sXdmad XDMAD_Instance;
+
+static void XDMAD_SysInitialize(void)
+{
+	sXdmad *pXdmad;
+	uint32_t j;
+	rtems_status_code sc;
+
+	pXdmad = &XDMAD_Instance;
+
+	pXdmad->pXdmacs = XDMAC;
+	pXdmad->numControllers = XDMAC_CONTROLLER_NUM;
+	pXdmad->numChannels    = (XDMAC_GTYPE_NB_CH(XDMAC_GetType(XDMAC)) + 1);
+
+	for (j = 0; j < pXdmad->numChannels; j ++) {
+		pXdmad->XdmaChannels[j].fCallback = XDMAD_DoNothingCallback;
+	}
+
+	sc = rtems_interrupt_handler_install(
+		ID_XDMAC,
+		"XDMA",
+		RTEMS_INTERRUPT_UNIQUE,
+		XDMAD_Handler,
+		pXdmad
+	);
+	if (sc != RTEMS_SUCCESSFUL) {
+		bsp_fatal(ATSAM_FATAL_XDMA_IRQ_INSTALL);
+	}
+}
+
+RTEMS_SYSINIT_ITEM(XDMAD_SysInitialize, RTEMS_SYSINIT_BSP_START,
+    RTEMS_SYSINIT_ORDER_LAST);
+
+
+/**
+ * \brief Allocate a XDMA channel for upper layer.
+ * \param pXdmad  Pointer to xDMA driver instance.
+ * \param bSrcID Source peripheral ID, 0xFF for memory.
+ * \param bDstID Destination peripheral ID, 0xFF for memory.
+ * \return Channel number if allocation successful, return
+ * XDMAD_ALLOC_FAILED if allocation failed.
+ */
+uint32_t XDMAD_AllocateChannel(sXdmad *pXdmad,
+								uint8_t bSrcID,
+								uint8_t bDstID)
+{
+	uint32_t dwChannel = XDMAD_ALLOC_FAILED;
+	uint32_t volatile timer = 0x7FF;
+
+	LockMutex(pXdmad->xdmaMutex, timer);
+	dwChannel = XDMAD_AllocateXdmacChannel(pXdmad,  bSrcID, bDstID);
+	ReleaseMutex(pXdmad->xdmaMutex);
+
+	return dwChannel;
+}
+
+/**
+ * \brief Free the specified xDMA channel.
+ * \param pXdmad     Pointer to xDMA driver instance.
+ * \param dwChannel ControllerNumber << 8 | ChannelNumber.
+ */
+eXdmadRC XDMAD_FreeChannel(sXdmad *pXdmad,
+							uint32_t dwChannel)
+{
+	uint8_t iChannel    = (dwChannel) & 0xFF;
+	assert(pXdmad != NULL);
+
+	if (iChannel >= pXdmad->numChannels) return XDMAD_ERROR;
+
+	switch (pXdmad->XdmaChannels[iChannel].state) {
+	case XDMAD_STATE_ALLOCATED:
+	case XDMAD_STATE_START:
+	case XDMAD_STATE_IN_XFR:
+		return XDMAD_BUSY;
+
+	case XDMAD_STATE_DONE:
+	case XDMAD_STATE_HALTED:
+		pXdmad->XdmaChannels[iChannel].state = XDMAD_STATE_FREE;
+		break;
+	}
+
+	return XDMAD_OK;
+}
+
+/**
+ * \brief Set the callback function for xDMA channel transfer.
+ * \param pXdmad     Pointer to xDMA driver instance.
+ * \param dwChannel ControllerNumber << 8 | ChannelNumber.
+ * \param fCallback Pointer to callback function.
+ * \param pArg Pointer to optional argument for callback.
+ */
+eXdmadRC XDMAD_SetCallback(sXdmad *pXdmad,
+							uint32_t dwChannel,
+							XdmadTransferCallback fCallback,
+							void *pArg)
+{
+
+	uint8_t iChannel    = (dwChannel) & 0xFF;
+	assert(pXdmad != NULL);
+
+	if (iChannel >= pXdmad->numChannels) return XDMAD_ERROR;
+
+	if (pXdmad->XdmaChannels[iChannel].state == XDMAD_STATE_FREE)
+		return XDMAD_ERROR;
+	else if (pXdmad->XdmaChannels[iChannel].state == XDMAD_STATE_START)
+		return XDMAD_BUSY;
+
+	pXdmad->XdmaChannels[iChannel].fCallback = fCallback;
+	pXdmad->XdmaChannels[iChannel].pArg = pArg;
+
+	return XDMAD_OK;
+}
+
+
+/**
+ * \brief Enable clock of the xDMA peripheral, Enable the dma peripheral,
+ * configure configuration register for xDMA transfer.
+ * \param pXdmad     Pointer to xDMA driver instance.
+ * \param dwChannel ControllerNumber << 8 | ChannelNumber.
+ * \param dwCfg     Configuration value.
+ */
+eXdmadRC XDMAD_PrepareChannel(sXdmad *pXdmad, uint32_t dwChannel)
+{
+
+	uint8_t iChannel    = (dwChannel) & 0xFF;
+	Xdmac *pXdmac = pXdmad->pXdmacs;
+
+	assert(pXdmad != NULL);
+
+	if (iChannel >= pXdmad->numChannels) return XDMAD_ERROR;
+
+	if (pXdmad->XdmaChannels[iChannel].state == XDMAD_STATE_FREE)
+		return XDMAD_ERROR;
+	else if ((pXdmad->XdmaChannels[iChannel].state == XDMAD_STATE_START)
+			  || (pXdmad->XdmaChannels[iChannel].state == XDMAD_STATE_IN_XFR))
+		return XDMAD_BUSY;
+
+
+	/* Enable clock of the DMA peripheral */
+	if (!PMC_IsPeriphEnabled(ID_XDMAC))
+		PMC_EnablePeripheral(ID_XDMAC);
+
+	/* Clear dummy status */
+	XDMAC_GetChannelIsr(pXdmac, iChannel);
+	/* Disables XDMAC interrupt for the given channel. */
+	XDMAC_DisableGIt (pXdmac, iChannel);
+	XDMAC_DisableChannelIt (pXdmac, iChannel, 0xFF);
+	/* Disable the given dma channel. */
+	XDMAC_DisableChannel(pXdmac, iChannel);
+	XDMAC_SetSourceAddr(pXdmac, iChannel, 0);
+	XDMAC_SetDestinationAddr(pXdmac, iChannel, 0);
+	XDMAC_SetBlockControl(pXdmac, iChannel, 0);
+	XDMAC_SetChannelConfig(pXdmac, iChannel, 0x20);
+	XDMAC_SetDescriptorAddr(pXdmac, iChannel, 0, 0);
+	XDMAC_SetDescriptorControl(pXdmac, iChannel, 0);
+	return XDMAD_OK;
+}
+
+/**
+ * \brief xDMA interrupt handler
+ * \param arg Pointer to DMA driver instance.
+ */
+static void XDMAD_Handler(void *arg)
+{
+	sXdmad *pDmad;
+	Xdmac *pXdmac;
+	sXdmadChannel *pCh;
+	uint32_t xdmaChannelIntStatus, xdmaGlobaIntStatus, xdmaGlobalChStatus;
+	uint8_t bExec;
+	uint8_t _iChannel;
+
+	pDmad = arg;
+	pXdmac = pDmad->pXdmacs;
+	xdmaGlobaIntStatus = XDMAC_GetGIsr(pXdmac) & 0xFFFFFF;
+	xdmaGlobalChStatus = XDMAC_GetGlobalChStatus(pXdmac);
+
+	while (xdmaGlobaIntStatus != 0) {
+		_iChannel = 31 - __builtin_clz(xdmaGlobaIntStatus);
+		xdmaGlobaIntStatus &= ~(UINT32_C(1) << _iChannel);
+
+		pCh = &pDmad->XdmaChannels[_iChannel];
+		bExec = 0;
+
+		if ((xdmaGlobalChStatus & (XDMAC_GS_ST0 << _iChannel)) == 0) {
+			xdmaChannelIntStatus = XDMAC_GetMaskChannelIsr(pXdmac, _iChannel);
+
+			if (xdmaChannelIntStatus & XDMAC_CIS_BIS) {
+				if ((XDMAC_GetChannelItMask(pXdmac, _iChannel) & XDMAC_CIM_LIM) == 0) {
+					pCh->state = XDMAD_STATE_DONE;
+					bExec = 1;
+				}
+
+				TRACE_DEBUG("XDMAC_CIS_BIS\n\r");
+			}
+
+			if (xdmaChannelIntStatus & XDMAC_CIS_FIS)
+				TRACE_DEBUG("XDMAC_CIS_FIS\n\r");
+
+			if (xdmaChannelIntStatus & XDMAC_CIS_RBEIS)
+				TRACE_DEBUG("XDMAC_CIS_RBEIS\n\r");
+
+			if (xdmaChannelIntStatus & XDMAC_CIS_WBEIS)
+				TRACE_DEBUG("XDMAC_CIS_WBEIS\n\r");
+
+			if (xdmaChannelIntStatus & XDMAC_CIS_ROIS)
+				TRACE_DEBUG("XDMAC_CIS_ROIS\n\r");
+
+			if (xdmaChannelIntStatus & XDMAC_CIS_LIS) {
+				TRACE_DEBUG("XDMAC_CIS_LIS\n\r");
+				pCh->state = XDMAD_STATE_DONE;
+				bExec = 1;
+			}
+
+			if (xdmaChannelIntStatus & XDMAC_CIS_DIS) {
+				pCh->state = XDMAD_STATE_DONE;
+				bExec = 1;
+			}
+
+		} else {
+			/* Block end interrupt for LLI dma mode */
+			if (XDMAC_GetChannelIsr(pXdmac, _iChannel) & XDMAC_CIS_BIS) {
+				bExec = 1;
+			}
+		}
+
+		/* Execute callback */
+		if (bExec)
+			pCh->fCallback(_iChannel, pCh->pArg);
+	}
+}
+
+
+/**
+ * \brief Configure DMA for a single transfer.
+ * \param pXdmad     Pointer to xDMA driver instance.
+ * \param dwChannel ControllerNumber << 8 | ChannelNumber.
+ */
+eXdmadRC XDMAD_ConfigureTransfer(sXdmad *pXdmad,
+								  uint32_t dwChannel,
+								  sXdmadCfg *pXdmaParam,
+								  uint32_t dwXdmaDescCfg,
+								  uint32_t dwXdmaDescAddr,
+								  uint32_t dwXdmaIntEn)
+{
+	uint8_t iChannel    = (dwChannel) & 0xFF;
+
+	assert(pXdmad != NULL);
+
+	if (iChannel >= pXdmad->numChannels)
+		return XDMAD_ERROR;
+
+	Xdmac *pXdmac = pXdmad->pXdmacs;
+	XDMAC_GetChannelIsr(pXdmac, iChannel);
+
+	if (pXdmad->XdmaChannels[iChannel].state == XDMAD_STATE_FREE)
+		return XDMAD_ERROR;
+
+	if (pXdmad->XdmaChannels[iChannel].state == XDMAD_STATE_START)
+		return XDMAD_BUSY;
+
+	/* Linked List is enabled */
+	if ((dwXdmaDescCfg & XDMAC_CNDC_NDE) == XDMAC_CNDC_NDE_DSCR_FETCH_EN) {
+		if ((dwXdmaDescCfg & XDMAC_CNDC_NDVIEW_Msk) == XDMAC_CNDC_NDVIEW_NDV0) {
+			XDMAC_SetChannelConfig(pXdmac, iChannel, pXdmaParam->mbr_cfg);
+			XDMAC_SetSourceAddr(pXdmac, iChannel, pXdmaParam->mbr_sa);
+			XDMAC_SetDestinationAddr(pXdmac, iChannel, pXdmaParam->mbr_da);
+		}
+
+		if ((dwXdmaDescCfg & XDMAC_CNDC_NDVIEW_Msk) == XDMAC_CNDC_NDVIEW_NDV1)
+			XDMAC_SetChannelConfig(pXdmac, iChannel, pXdmaParam->mbr_cfg);
+
+		XDMAC_SetDescriptorAddr(pXdmac, iChannel, dwXdmaDescAddr, 0);
+		XDMAC_SetDescriptorControl(pXdmac, iChannel, dwXdmaDescCfg);
+		XDMAC_DisableChannelIt (pXdmac, iChannel, 0xFF);
+		XDMAC_EnableChannelIt (pXdmac, iChannel, dwXdmaIntEn);
+	} else {
+		/* LLI is disabled. */
+		XDMAC_SetSourceAddr(pXdmac, iChannel, pXdmaParam->mbr_sa);
+		XDMAC_SetDestinationAddr(pXdmac, iChannel, pXdmaParam->mbr_da);
+		XDMAC_SetMicroblockControl(pXdmac, iChannel, pXdmaParam->mbr_ubc);
+		XDMAC_SetBlockControl(pXdmac, iChannel, pXdmaParam->mbr_bc);
+		XDMAC_SetDataStride_MemPattern(pXdmac, iChannel, pXdmaParam->mbr_ds);
+		XDMAC_SetSourceMicroBlockStride(pXdmac, iChannel, pXdmaParam->mbr_sus);
+		XDMAC_SetDestinationMicroBlockStride(pXdmac, iChannel, pXdmaParam->mbr_dus);
+		XDMAC_SetChannelConfig(pXdmac, iChannel, pXdmaParam->mbr_cfg);
+		XDMAC_SetDescriptorAddr(pXdmac, iChannel, 0, 0);
+		XDMAC_SetDescriptorControl(pXdmac, iChannel, 0);
+		XDMAC_EnableChannelIt (pXdmac, iChannel, dwXdmaIntEn);
+	}
+
+	return XDMAD_OK;
+}
+
+/**
+ * \brief Start xDMA transfer.
+ * \param pXdmad     Pointer to XDMA driver instance.
+ * \param dwChannel ControllerNumber << 8 | ChannelNumber.
+ */
+eXdmadRC XDMAD_StartTransfer(sXdmad *pXdmad, uint32_t dwChannel)
+{
+	uint8_t iChannel    = (dwChannel) & 0xFF;
+
+	assert(pXdmad != NULL);
+
+	if (iChannel >= pXdmad->numChannels) return XDMAD_ERROR;
+
+	Xdmac *pXdmac = pXdmad->pXdmacs;
+
+	if (pXdmad->XdmaChannels[iChannel].state == XDMAD_STATE_FREE) {
+		TRACE_ERROR("%s:: XDMAD_STATE_FREE \n\r", __FUNCTION__);
+		return XDMAD_ERROR;
+	} else if (pXdmad->XdmaChannels[iChannel].state == XDMAD_STATE_START) {
+		TRACE_ERROR("%s:: XDMAD_STATE_START \n\r", __FUNCTION__)
+		return XDMAD_BUSY;
+	}
+
+	/* Change state to transferring */
+	pXdmad->XdmaChannels[iChannel].state = XDMAD_STATE_START;
+	XDMAC_EnableChannel(pXdmac, iChannel);
+	XDMAC_EnableGIt(pXdmac, iChannel);
+
+	return XDMAD_OK;
+}
+
+
+/**
+ * \brief Stop DMA transfer.
+ * \param pDmad     Pointer to DMA driver instance.
+ * \param dwChannel ControllerNumber << 8 | ChannelNumber.
+ */
+eXdmadRC XDMAD_StopTransfer(sXdmad *pXdmad, uint32_t dwChannel)
+{
+	uint8_t _iChannel    = (dwChannel) & 0xFF;
+	assert(pXdmad != NULL);
+
+	if (_iChannel >= pXdmad->numChannels) return XDMAD_ERROR;
+
+	Xdmac *pXdmac = pXdmad->pXdmacs;
+
+	pXdmad->XdmaChannels[_iChannel].state = XDMAD_STATE_HALTED;
+	/* Disable channel */
+	XDMAC_DisableChannel(pXdmac, _iChannel);
+	/* Disable interrupts */
+	XDMAC_DisableChannelIt(pXdmac, _iChannel, 0xFF);
+	/* Clear pending status */
+	XDMAC_GetChannelIsr(pXdmac, _iChannel);
+	XDMAC_GetGlobalChStatus(pXdmac);
+	return XDMAD_OK;
+}
+
+/**@}*/
+
Index: bsps/arm/atsam/contrib/utils/utility.h
===================================================================
--- bsps/arm/atsam/contrib/utils/utility.h	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/contrib/utils/utility.h	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,111 @@
+/* ----------------------------------------------------------------------------
+ *         SAM Software Package License
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2014, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: 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
+ * 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.
+ * ----------------------------------------------------------------------------
+ */
+
+#ifndef UTILITY_H
+#define UTILITY_H
+
+#include "chip.h"
+ 
+
+
+#define RESET_CYCLE_COUNTER()  do { \
+        CoreDebug->DEMCR = CoreDebug_DEMCR_TRCENA_Msk; \
+        __DSB(); DWT->LAR = 0xC5ACCE55; __DSB(); \
+        DWT->CTRL &= ~DWT_CTRL_CYCCNTENA_Msk; \
+        DWT->CYCCNT = 0; \
+        DWT->CTRL = DWT_CTRL_CYCCNTENA_Msk; \
+    }while(0)
+
+#define GET_CYCLE_COUNTER(x)                x=DWT->CYCCNT;   
+
+#define LockMutex(mut, timeout)             get_lock(&mut, 1, &timeout)
+    
+#define ReleaseMutex(mut)                   free_lock(&mut)
+
+#define GetResource(mut, max, timeout)      get_lock(&mut, max, &timeout)
+    
+#define FreeResource(mut)                   free_lock(&mut)
+
+
+__STATIC_INLINE uint8_t Is_LockFree(volatile uint8_t *Lock_Variable)
+{
+    /* return Variable value*/
+    return __LDREXB(Lock_Variable); 
+    
+}
+
+__STATIC_INLINE uint8_t get_lock(volatile uint8_t *Lock_Variable, const uint8_t maxValue, volatile uint32_t *pTimeout)
+{
+    while (*pTimeout)
+	{
+        if(__LDREXB(Lock_Variable) < maxValue)
+        {
+          /* Set the Variable */
+          while( __STREXB(((*Lock_Variable) + 1), Lock_Variable) )
+          {            
+            if(!(*pTimeout)--)
+            {
+              return 1;       // quit if timeout
+            }
+          }
+          /* Memory access barrier */
+          __DMB();
+          TRACE_DEBUG("Mutex locked ");
+          return 0;
+        }
+        
+        ((*pTimeout)--);
+	}
+    return 1;
+}
+
+
+
+__STATIC_INLINE uint8_t free_lock(volatile uint8_t *Lock_Variable)
+{
+    /* Memory access barrier Ensure memory operations completed before releasing lock  */
+    __DSB();
+    if(__LDREXB(Lock_Variable))
+    {
+      __STREXB( ((*Lock_Variable) - 1), Lock_Variable);
+      TRACE_DEBUG("Mutex freed ");
+      __DSB();
+      __DMB(); // Ensure memory operations completed before
+      return 0;
+    }
+    else
+    {
+      return 1;
+    }
+    
+    
+}
+
+
+#endif /* UTILITY_H */
Index: bsps/arm/atsam/start/iocopy.c
===================================================================
--- bsps/arm/atsam/start/iocopy.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
+++ bsps/arm/atsam/start/iocopy.c	(revision 54aabb70eb9ad64d3bcb9f95968de6a4473ebe3b)
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2018 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Dornierstr. 4
+ *  82178 Puchheim
+ *  Germany
+ *  <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <bsp/iocopy.h>
+
+static void atsam_do_copy(
+  uint8_t *dst,
+  const uint8_t *src,
+  size_t n,
+  bool aligned
+)
+{
+  if (aligned) {
+    while (n > 3) {
+      *(uint32_t *)dst = *(uint32_t *)src;
+      dst += 4;
+      src += 4;
+      n -= 4;
+    }
+  }
+
+  while (n > 0) {
+    *dst = *src;
+    ++dst;
+    ++src;
+    --n;
+  }
+}
+
+void atsam_copy_to_io(void *dst, const void *src, size_t n)
+{
+  atsam_do_copy(dst, src, n, ((uintptr_t)dst) % 4 == 0);
+}
+
+void atsam_copy_from_io(void *dst, const void *src, size_t n)
+{
+  atsam_do_copy(dst, src, n, ((uintptr_t)src) % 4 == 0);
+}
