aboutsummaryrefslogtreecommitdiff
path: root/firmwares/wifishield/wifiHD/src/SOFTWARE_FRAMEWORK/DRIVERS/SPI
diff options
context:
space:
mode:
authorDavid A. Mellis <d.mellis@arduino.cc>2012-09-13 10:42:25 -0400
committerDavid A. Mellis <d.mellis@arduino.cc>2012-09-13 10:42:25 -0400
commitbd45bf50c7c68ec35c3aad8c5e7bf4d3db9cafc1 (patch)
treec02065cc7b15ce5f0a8eaa9f0030a268b37c89bb /firmwares/wifishield/wifiHD/src/SOFTWARE_FRAMEWORK/DRIVERS/SPI
parent6225a8596005bfb0be68fa641f5b47d01a95c12d (diff)
parent0d9a111face4f3629bcae8e52af843792af3b453 (diff)
Merge branch 'master' of ../wifishield
Diffstat (limited to 'firmwares/wifishield/wifiHD/src/SOFTWARE_FRAMEWORK/DRIVERS/SPI')
-rw-r--r--firmwares/wifishield/wifiHD/src/SOFTWARE_FRAMEWORK/DRIVERS/SPI/spi.c443
-rw-r--r--firmwares/wifishield/wifiHD/src/SOFTWARE_FRAMEWORK/DRIVERS/SPI/spi.h342
2 files changed, 785 insertions, 0 deletions
diff --git a/firmwares/wifishield/wifiHD/src/SOFTWARE_FRAMEWORK/DRIVERS/SPI/spi.c b/firmwares/wifishield/wifiHD/src/SOFTWARE_FRAMEWORK/DRIVERS/SPI/spi.c
new file mode 100644
index 0000000..d2b7ccd
--- /dev/null
+++ b/firmwares/wifishield/wifiHD/src/SOFTWARE_FRAMEWORK/DRIVERS/SPI/spi.c
@@ -0,0 +1,443 @@
+/* This source file is part of the ATMEL AVR-UC3-SoftwareFramework-1.7.0 Release */
+
+/*This file is prepared for Doxygen automatic documentation generation.*/
+/*! \file *********************************************************************
+ *
+ * \brief SPI driver for AVR32 UC3.
+ *
+ * This file defines a useful set of functions for the SPI interface on AVR32
+ * devices.
+ *
+ * - Compiler: IAR EWAVR32 and GNU GCC for AVR32
+ * - Supported devices: All AVR32 devices with an SPI module can be used.
+ * - AppNote:
+ *
+ * \author Atmel Corporation: http://www.atmel.com \n
+ * Support and FAQ: http://support.atmel.no/
+ *
+ ******************************************************************************/
+
+/* Copyright (c) 2009 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:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. The name of Atmel may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * 4. This software may only be redistributed and used in connection with an Atmel
+ * AVR product.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
+ *
+ */
+
+#include "spi.h"
+
+#ifdef FREERTOS_USED
+
+#include "FreeRTOS.h"
+#include "semphr.h"
+
+#endif
+
+
+/*! \name SPI Writable Bit-Field Registers
+ */
+//! @{
+
+typedef union
+{
+ unsigned long cr;
+ avr32_spi_cr_t CR;
+} u_avr32_spi_cr_t;
+
+typedef union
+{
+ unsigned long mr;
+ avr32_spi_mr_t MR;
+} u_avr32_spi_mr_t;
+
+typedef union
+{
+ unsigned long tdr;
+ avr32_spi_tdr_t TDR;
+} u_avr32_spi_tdr_t;
+
+typedef union
+{
+ unsigned long ier;
+ avr32_spi_ier_t IER;
+} u_avr32_spi_ier_t;
+
+typedef union
+{
+ unsigned long idr;
+ avr32_spi_idr_t IDR;
+} u_avr32_spi_idr_t;
+
+typedef union
+{
+ unsigned long csr;
+ avr32_spi_csr0_t CSR;
+} u_avr32_spi_csr_t;
+
+//! @}
+
+
+#ifdef FREERTOS_USED
+
+//! The SPI mutex.
+static xSemaphoreHandle xSPIMutex;
+
+#endif
+
+
+/*! \brief Calculates the baudrate divider.
+ *
+ * \param options Pointer to a structure containing initialization options for
+ * an SPI channel.
+ * \param pba_hz SPI module input clock frequency (PBA clock, Hz).
+ *
+ * \return Divider or error code.
+ * \retval >=0 Success.
+ * \retval <0 Error.
+ */
+static int getBaudDiv(const spi_options_t *options, unsigned int pba_hz)
+{
+ int baudDiv = (pba_hz + options->baudrate / 2) / options->baudrate;
+
+ if (baudDiv <= 0 || baudDiv > 255) {
+ return -1;
+ }
+
+ return baudDiv;
+}
+
+
+void spi_reset(volatile avr32_spi_t *spi)
+{
+ spi->cr = AVR32_SPI_CR_SWRST_MASK;
+}
+
+
+spi_status_t spi_initSlave(volatile avr32_spi_t *spi,
+ unsigned char bits,
+ unsigned char spi_mode)
+{
+ if (spi_mode > 3 ||
+ bits < 8 || bits > 16) {
+ return SPI_ERROR_ARGUMENT;
+ }
+
+ // Reset.
+ spi->cr = AVR32_SPI_CR_SWRST_MASK;
+
+ // Will use CSR0 offsets; these are the same for CSR0 to CSR3.
+ spi->csr0 = ((spi_mode >> 1) << AVR32_SPI_CSR0_CPOL_OFFSET) |
+ (((spi_mode & 0x1) ^ 0x1) << AVR32_SPI_CSR0_NCPHA_OFFSET) |
+ ((bits - 8) << AVR32_SPI_CSR0_BITS_OFFSET);
+
+ return SPI_OK;
+}
+
+
+spi_status_t spi_initTest(volatile avr32_spi_t *spi)
+{
+ // Reset.
+ spi->cr = AVR32_SPI_CR_SWRST_MASK;
+ spi->mr |= AVR32_SPI_MR_MSTR_MASK | // Master Mode.
+ AVR32_SPI_MR_LLB_MASK; // Local Loopback.
+
+ return SPI_OK;
+}
+
+
+spi_status_t spi_initMaster(volatile avr32_spi_t *spi, const spi_options_t *options)
+{
+ u_avr32_spi_mr_t u_avr32_spi_mr;
+
+ if (options->modfdis > 1) {
+ return SPI_ERROR_ARGUMENT;
+ }
+
+ // Reset.
+ spi->cr = AVR32_SPI_CR_SWRST_MASK;
+
+ // Master Mode.
+ u_avr32_spi_mr.mr = spi->mr;
+ u_avr32_spi_mr.MR.mstr = 1;
+ u_avr32_spi_mr.MR.modfdis = options->modfdis;
+ u_avr32_spi_mr.MR.llb = 0;
+ u_avr32_spi_mr.MR.pcs = (1 << AVR32_SPI_MR_PCS_SIZE) - 1;
+ spi->mr = u_avr32_spi_mr.mr;
+
+ return SPI_OK;
+}
+
+
+spi_status_t spi_selectionMode(volatile avr32_spi_t *spi,
+ unsigned char variable_ps,
+ unsigned char pcs_decode,
+ unsigned char delay)
+{
+ u_avr32_spi_mr_t u_avr32_spi_mr;
+
+ if (variable_ps > 1 ||
+ pcs_decode > 1) {
+ return SPI_ERROR_ARGUMENT;
+ }
+
+ u_avr32_spi_mr.mr = spi->mr;
+ u_avr32_spi_mr.MR.ps = variable_ps;
+ u_avr32_spi_mr.MR.pcsdec = pcs_decode;
+ u_avr32_spi_mr.MR.dlybcs = delay;
+ spi->mr = u_avr32_spi_mr.mr;
+
+ return SPI_OK;
+}
+
+
+spi_status_t spi_selectChip(volatile avr32_spi_t *spi, unsigned char chip)
+{
+#ifdef FREERTOS_USED
+ while (pdFALSE == xSemaphoreTake(xSPIMutex, 20));
+#endif
+
+ // Assert all lines; no peripheral is selected.
+ spi->mr |= AVR32_SPI_MR_PCS_MASK;
+
+ if (spi->mr & AVR32_SPI_MR_PCSDEC_MASK) {
+ // The signal is decoded; allow up to 15 chips.
+ if (chip > 14) {
+ return SPI_ERROR_ARGUMENT;
+ }
+
+ spi->mr &= ~AVR32_SPI_MR_PCS_MASK | (chip << AVR32_SPI_MR_PCS_OFFSET);
+ } else {
+ if (chip > 3) {
+ return SPI_ERROR_ARGUMENT;
+ }
+
+ spi->mr &= ~(1 << (AVR32_SPI_MR_PCS_OFFSET + chip));
+ }
+
+ return SPI_OK;
+}
+
+
+spi_status_t spi_unselectChip(volatile avr32_spi_t *spi, unsigned char chip)
+{
+ unsigned int timeout = SPI_TIMEOUT;
+
+ while (!(spi->sr & AVR32_SPI_SR_TXEMPTY_MASK)) {
+ if (!timeout--) {
+ return SPI_ERROR_TIMEOUT;
+ }
+ }
+
+ // Assert all lines; no peripheral is selected.
+ spi->mr |= AVR32_SPI_MR_PCS_MASK;
+
+ // Last transfer, so deassert the current NPCS if CSAAT is set.
+ spi->cr = AVR32_SPI_CR_LASTXFER_MASK;
+
+#ifdef FREERTOS_USED
+ xSemaphoreGive(xSPIMutex);
+#endif
+
+ return SPI_OK;
+}
+
+
+spi_status_t spi_setupChipReg(volatile avr32_spi_t *spi,
+ const spi_options_t *options,
+ unsigned int pba_hz)
+{
+ u_avr32_spi_csr_t u_avr32_spi_csr;
+
+ if (options->spi_mode > 3 ||
+ options->stay_act > 1 ||
+ options->bits < 8 || options->bits > 16) {
+ return SPI_ERROR_ARGUMENT;
+ }
+
+ int baudDiv = getBaudDiv(options, pba_hz);
+
+ if (baudDiv < 0) {
+ return SPI_ERROR_ARGUMENT;
+ }
+
+ // Will use CSR0 offsets; these are the same for CSR0 to CSR3.
+ u_avr32_spi_csr.csr = 0;
+ u_avr32_spi_csr.CSR.cpol = options->spi_mode >> 1;
+ u_avr32_spi_csr.CSR.ncpha = (options->spi_mode & 0x1) ^ 0x1;
+ u_avr32_spi_csr.CSR.csaat = options->stay_act;
+ u_avr32_spi_csr.CSR.bits = options->bits - 8;
+ u_avr32_spi_csr.CSR.scbr = baudDiv;
+ u_avr32_spi_csr.CSR.dlybs = options->spck_delay;
+ u_avr32_spi_csr.CSR.dlybct = options->trans_delay;
+
+ switch(options->reg) {
+ case 0:
+ spi->csr0 = u_avr32_spi_csr.csr;
+ break;
+ case 1:
+ spi->csr1 = u_avr32_spi_csr.csr;
+ break;
+ case 2:
+ spi->csr2 = u_avr32_spi_csr.csr;
+ break;
+ case 3:
+ spi->csr3 = u_avr32_spi_csr.csr;
+ break;
+ default:
+ return SPI_ERROR_ARGUMENT;
+ }
+
+#ifdef FREERTOS_USED
+ if (!xSPIMutex)
+ {
+ // Create the SPI mutex.
+ vSemaphoreCreateBinary(xSPIMutex);
+ if (!xSPIMutex)
+ {
+ while(1);
+ }
+ }
+#endif
+
+ return SPI_OK;
+}
+
+
+void spi_enable(volatile avr32_spi_t *spi)
+{
+ spi->cr = AVR32_SPI_CR_SPIEN_MASK;
+}
+
+
+void spi_disable(volatile avr32_spi_t *spi)
+{
+ spi->cr = AVR32_SPI_CR_SPIDIS_MASK;
+}
+
+
+int spi_is_enabled(volatile avr32_spi_t *spi)
+{
+ return (spi->sr & AVR32_SPI_SR_SPIENS_MASK) != 0;
+}
+
+
+inline unsigned char spi_writeRegisterEmptyCheck(volatile avr32_spi_t *spi)
+{
+ return ((spi->sr & AVR32_SPI_SR_TDRE_MASK) != 0);
+}
+
+
+inline spi_status_t spi_write(volatile avr32_spi_t *spi, unsigned short data)
+{
+ unsigned int timeout = SPI_TIMEOUT;
+
+ while (!(spi->sr & AVR32_SPI_SR_TDRE_MASK)) {
+ if (!timeout--) {
+ return SPI_ERROR_TIMEOUT;
+ }
+ }
+
+ spi->tdr = data << AVR32_SPI_TDR_TD_OFFSET;
+
+ return SPI_OK;
+}
+
+
+spi_status_t spi_variableSlaveWrite(volatile avr32_spi_t *spi, unsigned short data,
+ unsigned char pcs, unsigned char lastxfer)
+{
+ unsigned int timeout = SPI_TIMEOUT;
+
+ if (pcs > 14 || lastxfer > 1) {
+ return SPI_ERROR_ARGUMENT;
+ }
+
+ while (!(spi->sr & AVR32_SPI_SR_TDRE_MASK)) {
+ if (!timeout--) {
+ return SPI_ERROR_TIMEOUT;
+ }
+ }
+
+ spi->tdr = (data << AVR32_SPI_TDR_TD_OFFSET) |
+ (pcs << AVR32_SPI_TDR_PCS_OFFSET) |
+ (lastxfer << AVR32_SPI_TDR_LASTXFER_OFFSET);
+
+ return SPI_OK;
+}
+
+
+inline unsigned char spi_writeEndCheck(volatile avr32_spi_t *spi)
+{
+ return ((spi->sr & AVR32_SPI_SR_TXEMPTY_MASK) != 0);
+}
+
+
+unsigned char spi_readRegisterFullCheck(volatile avr32_spi_t *spi)
+{
+ return ((spi->sr & AVR32_SPI_SR_RDRF_MASK) != 0);
+}
+
+
+inline spi_status_t spi_read(volatile avr32_spi_t *spi, unsigned short *data)
+{
+ unsigned int timeout = SPI_TIMEOUT;
+
+ while ((spi->sr & (AVR32_SPI_SR_RDRF_MASK | AVR32_SPI_SR_TXEMPTY_MASK)) !=
+ (AVR32_SPI_SR_RDRF_MASK | AVR32_SPI_SR_TXEMPTY_MASK)) {
+ if (!timeout--) {
+ return SPI_ERROR_TIMEOUT;
+ }
+ }
+
+ *data = spi->rdr >> AVR32_SPI_RDR_RD_OFFSET;
+
+ return SPI_OK;
+}
+
+
+unsigned char spi_getStatus(volatile avr32_spi_t *spi)
+{
+ spi_status_t ret = SPI_OK;
+ unsigned long sr = spi->sr;
+
+ if (sr & AVR32_SPI_SR_OVRES_MASK) {
+ ret = SPI_ERROR_OVERRUN;
+ }
+
+ if (sr & AVR32_SPI_SR_MODF_MASK) {
+ ret += SPI_ERROR_MODE_FAULT;
+ }
+
+ if (ret == (SPI_ERROR_OVERRUN + SPI_ERROR_MODE_FAULT)) {
+ return SPI_ERROR_OVERRUN_AND_MODE_FAULT;
+ }
+ else if (ret > 0) {
+ return ret;
+ } else {
+ return SPI_OK;
+ }
+}
diff --git a/firmwares/wifishield/wifiHD/src/SOFTWARE_FRAMEWORK/DRIVERS/SPI/spi.h b/firmwares/wifishield/wifiHD/src/SOFTWARE_FRAMEWORK/DRIVERS/SPI/spi.h
new file mode 100644
index 0000000..6dcc928
--- /dev/null
+++ b/firmwares/wifishield/wifiHD/src/SOFTWARE_FRAMEWORK/DRIVERS/SPI/spi.h
@@ -0,0 +1,342 @@
+/* This header file is part of the ATMEL AVR-UC3-SoftwareFramework-1.7.0 Release */
+
+/*This file is prepared for Doxygen automatic documentation generation.*/
+/*! \file *********************************************************************
+ *
+ * \brief SPI driver for AVR32 UC3.
+ *
+ * This file defines a useful set of functions for the SPI interface on AVR32
+ * devices.
+ *
+ * - Compiler: IAR EWAVR32 and GNU GCC for AVR32
+ * - Supported devices: All AVR32 devices with an SPI module can be used.
+ * - AppNote:
+ *
+ * \author Atmel Corporation: http://www.atmel.com \n
+ * Support and FAQ: http://support.atmel.no/
+ *
+ ******************************************************************************/
+
+/* Copyright (c) 2009 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:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. The name of Atmel may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * 4. This software may only be redistributed and used in connection with an Atmel
+ * AVR product.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
+ *
+ */
+
+#ifndef _SPI_H_
+#define _SPI_H_
+
+#include <avr32/io.h>
+
+
+//! Time-out value (number of attempts).
+#define SPI_TIMEOUT 10000
+
+
+//! Status codes used by the SPI driver.
+typedef enum
+{
+ SPI_ERROR = -1,
+ SPI_OK = 0,
+ SPI_ERROR_TIMEOUT = 1,
+ SPI_ERROR_ARGUMENT,
+ SPI_ERROR_OVERRUN,
+ SPI_ERROR_MODE_FAULT,
+ SPI_ERROR_OVERRUN_AND_MODE_FAULT
+} spi_status_t;
+
+//! Option structure for SPI channels.
+typedef struct
+{
+ //! The SPI channel to set up.
+ unsigned char reg;
+
+ //! Preferred baudrate for the SPI.
+ unsigned int baudrate;
+
+ //! Number of bits in each character (8 to 16).
+ unsigned char bits;
+
+ //! Delay before first clock pulse after selecting slave (in PBA clock periods).
+ unsigned char spck_delay;
+
+ //! Delay between each transfer/character (in PBA clock periods).
+ unsigned char trans_delay;
+
+ //! Sets this chip to stay active after last transfer to it.
+ unsigned char stay_act;
+
+ //! Which SPI mode to use when transmitting.
+ unsigned char spi_mode;
+
+ //! Disables the mode fault detection.
+ //! With this bit cleared, the SPI master mode will disable itself if another
+ //! master tries to address it.
+ unsigned char modfdis;
+} spi_options_t;
+
+
+/*! \brief Resets the SPI controller.
+ *
+ * \param spi Base address of the SPI instance.
+ */
+extern void spi_reset(volatile avr32_spi_t *spi);
+
+/*! \brief Initializes the SPI in slave mode.
+ *
+ * \param spi Base address of the SPI instance.
+ * \param bits Number of bits in each transmitted character (8 to 16).
+ * \param spi_mode Clock polarity and phase.
+ *
+ * \return Status.
+ * \retval SPI_OK Success.
+ * \retval SPI_ERROR_ARGUMENT Invalid argument(s) passed.
+ */
+extern spi_status_t spi_initSlave(volatile avr32_spi_t *spi,
+ unsigned char bits,
+ unsigned char spi_mode);
+
+/*! \brief Sets up the SPI in a test mode where the transmitter is connected to
+ * the receiver (local loopback).
+ *
+ * \param spi Base address of the SPI instance.
+ *
+ * \return Status.
+ * \retval SPI_OK Success.
+ */
+extern spi_status_t spi_initTest(volatile avr32_spi_t *spi);
+
+/*! \brief Initializes the SPI in master mode.
+ *
+ * \param spi Base address of the SPI instance.
+ * \param options Pointer to a structure containing initialization options.
+ *
+ * \return Status.
+ * \retval SPI_OK Success.
+ * \retval SPI_ERROR_ARGUMENT Invalid argument(s) passed.
+ */
+extern spi_status_t spi_initMaster(volatile avr32_spi_t *spi, const spi_options_t *options);
+
+/*! \brief Sets up how and when the slave chips are selected (master mode only).
+ *
+ * \param spi Base address of the SPI instance.
+ * \param variable_ps Target slave is selected in transfer register for every
+ * character to transmit.
+ * \param pcs_decode The four chip select lines are decoded externally. Values
+ * 0 to 14 can be given to \ref spi_selectChip.
+ * \param delay Delay in PBA periods between chip selects.
+ *
+ * \return Status.
+ * \retval SPI_OK Success.
+ * \retval SPI_ERROR_ARGUMENT Invalid argument(s) passed.
+ */
+extern spi_status_t spi_selectionMode(volatile avr32_spi_t *spi,
+ unsigned char variable_ps,
+ unsigned char pcs_decode,
+ unsigned char delay);
+
+/*! \brief Selects slave chip.
+ *
+ * \param spi Base address of the SPI instance.
+ * \param chip Slave chip number (normal: 0 to 3, extarnally decoded signal: 0
+ * to 14).
+ *
+ * \return Status.
+ * \retval SPI_OK Success.
+ * \retval SPI_ERROR_ARGUMENT Invalid argument(s) passed.
+ */
+extern spi_status_t spi_selectChip(volatile avr32_spi_t *spi, unsigned char chip);
+
+/*! \brief Unselects slave chip.
+ *
+ * \param spi Base address of the SPI instance.
+ * \param chip Slave chip number (normal: 0 to 3, extarnally decoded signal: 0
+ * to 14).
+ *
+ * \return Status.
+ * \retval SPI_OK Success.
+ * \retval SPI_ERROR_TIMEOUT Time-out.
+ *
+ * \note Will block program execution until time-out occurs if last transmission
+ * is not complete. Invoke \ref spi_writeEndCheck beforehand if needed.
+ */
+extern spi_status_t spi_unselectChip(volatile avr32_spi_t *spi, unsigned char chip);
+
+/*! \brief Sets options for a specific slave chip.
+ *
+ * The baudrate field has to be written before transfer in master mode. Four
+ * similar registers exist, one for each slave. When using encoded slave
+ * addressing, reg=0 sets options for slaves 0 to 3, reg=1 for slaves 4 to 7 and
+ * so on.
+ *
+ * \param spi Base address of the SPI instance.
+ * \param options Pointer to a structure containing initialization options for
+ * an SPI channel.
+ * \param pba_hz SPI module input clock frequency (PBA clock, Hz).
+ *
+ * \return Status.
+ * \retval SPI_OK Success.
+ * \retval SPI_ERROR_ARGUMENT Invalid argument(s) passed.
+ */
+extern spi_status_t spi_setupChipReg(volatile avr32_spi_t *spi,
+ const spi_options_t *options,
+ unsigned int pba_hz);
+
+/*! \brief Enables the SPI.
+ *
+ * \param spi Base address of the SPI instance.
+ */
+extern void spi_enable(volatile avr32_spi_t *spi);
+
+/*! \brief Disables the SPI.
+ *
+ * Ensures that nothing is transferred while setting up buffers.
+ *
+ * \param spi Base address of the SPI instance.
+ *
+ * \warning This may cause data loss if used on a slave SPI.
+ */
+extern void spi_disable(volatile avr32_spi_t *spi);
+
+/*! \brief Tests if the SPI is enabled.
+ *
+ * \param spi Base address of the SPI instance.
+ *
+ * \return \c 1 if the SPI is enabled, otherwise \c 0.
+ */
+extern int spi_is_enabled(volatile avr32_spi_t *spi);
+
+/*! \brief Checks if there is no data in the transmit register.
+ *
+ * \param spi Base address of the SPI instance.
+ *
+ * \return Status.
+ * \retval 1 No data in TDR.
+ * \retval 0 Some data in TDR.
+ */
+extern unsigned char spi_writeRegisterEmptyCheck(volatile avr32_spi_t *spi);
+
+/*! \brief Writes one data word in master fixed peripheral select mode or in
+ * slave mode.
+ *
+ * \param spi Base address of the SPI instance.
+ * \param data The data word to write.
+ *
+ * \return Status.
+ * \retval SPI_OK Success.
+ * \retval SPI_ERROR_TIMEOUT Time-out.
+ *
+ * \note Will block program execution until time-out occurs if transmitter is
+ * busy and transmit buffer is full. Invoke
+ * \ref spi_writeRegisterEmptyCheck beforehand if needed.
+ *
+ * \note Once the data has been written to the transmit buffer, the end of
+ * transmission is not waited for. Invoke \ref spi_writeEndCheck if
+ * needed.
+ */
+extern spi_status_t spi_write(volatile avr32_spi_t *spi, unsigned short data);
+
+/*! \brief Selects a slave in master variable peripheral select mode and writes
+ * one data word to it.
+ *
+ * \param spi Base address of the SPI instance.
+ * \param data The data word to write.
+ * \param pcs Slave selector (bit 0 -> nCS line 0, bit 1 -> nCS line 1,
+ * etc.).
+ * \param lastxfer Boolean indicating whether this is the last data word
+ * transfer.
+ *
+ * \return Status.
+ * \retval SPI_OK Success.
+ * \retval SPI_ERROR_TIMEOUT Time-out.
+ * \retval SPI_ERROR_ARGUMENT Invalid argument(s) passed.
+ *
+ * \note Will block program execution until time-out occurs if transmitter is
+ * busy and transmit buffer is full. Invoke
+ * \ref spi_writeRegisterEmptyCheck beforehand if needed.
+ *
+ * \note Once the data has been written to the transmit buffer, the end of
+ * transmission is not waited for. Invoke \ref spi_writeEndCheck if
+ * needed.
+ */
+extern spi_status_t spi_variableSlaveWrite(volatile avr32_spi_t *spi,
+ unsigned short data,
+ unsigned char pcs,
+ unsigned char lastxfer);
+
+/*! \brief Checks if all transmissions are complete.
+ *
+ * \param spi Base address of the SPI instance.
+ *
+ * \return Status.
+ * \retval 1 All transmissions complete.
+ * \retval 0 Transmissions not complete.
+ */
+extern unsigned char spi_writeEndCheck(volatile avr32_spi_t *spi);
+
+/*! \brief Checks if there is data in the receive register.
+ *
+ * \param spi Base address of the SPI instance.
+ *
+ * \return Status.
+ * \retval 1 Some data in RDR.
+ * \retval 0 No data in RDR.
+ */
+extern unsigned char spi_readRegisterFullCheck(volatile avr32_spi_t *spi);
+
+/*! \brief Reads one data word in master mode or in slave mode.
+ *
+ * \param spi Base address of the SPI instance.
+ * \param data Pointer to the location where to store the received data word.
+ *
+ * \return Status.
+ * \retval SPI_OK Success.
+ * \retval SPI_ERROR_TIMEOUT Time-out.
+ *
+ * \note Will block program execution until time-out occurs if no data is
+ * received or last transmission is not complete. Invoke
+ * \ref spi_writeEndCheck or \ref spi_readRegisterFullCheck beforehand if
+ * needed.
+ */
+extern spi_status_t spi_read(volatile avr32_spi_t *spi, unsigned short *data);
+
+/*! \brief Gets status information from the SPI.
+ *
+ * \param spi Base address of the SPI instance.
+ *
+ * \return Status.
+ * \retval SPI_OK Success.
+ * \retval SPI_ERROR_OVERRUN Overrun error.
+ * \retval SPI_ERROR_MODE_FAULT Mode fault (SPI addressed as slave
+ * while in master mode).
+ * \retval SPI_ERROR_OVERRUN_AND_MODE_FAULT Overrun error and mode fault.
+ */
+extern unsigned char spi_getStatus(volatile avr32_spi_t *spi);
+
+
+#endif // _SPI_H_