diff --git a/sam3s_example/Makefile b/sam3s_example/Makefile
index 3c646dea..3ea94e75 100644
--- a/sam3s_example/Makefile
+++ b/sam3s_example/Makefile
@@ -116,12 +116,12 @@ LDFLAGS = -mcpu=cortex-m3 -mthumb -Wl,--cref -Wl,--check-sections -Wl,--gc-secti
# Directories where source files can be found
-VPATH += src cmsis lib
+VPATH += src_board src_sam3s cmsis
# Objects built from C source files
C_CMSIS = core_cm3.o
C_LOWLEVEL = board_cstartup_gnu.o board_lowlevel.o syscalls.o exceptions.o
-C_LIBLEVEL = spi.o pio.o pmc.o
+C_LIBLEVEL = spi.o pio.o pmc.o usart.o
C_APPLEVEL = main.o
C_OBJECTS = $(C_CMSIS) $(C_LOWLEVEL) $(C_LIBLEVEL) $(C_APPLEVEL)
@@ -162,7 +162,7 @@ endef
$(foreach MEMORY, $(MEMORIES), $(eval $(call RULES,$(MEMORY))))
program:
- openocd -f /home/chrysh/ba_thesis/thesis/openocd/openocd.cfg -c "init" -c "halt" -c "flash write_bank 0 /home/chrysh/ba_thesis/thesis/src/sam3s_example/bin/project-flash.bin 0" -c "reset" -c "shutdown"
+ openocd -f /home/chrysh/ba_thesis/thesis/openocd/openocd.cfg -c "init" -c "halt" -c "flash write_bank 0 ./bin/project-flash.bin 0" -c "reset" -c "shutdown"
clean:
-rm -fR $(OBJ)/*.o $(BIN)/*.bin $(BIN)/*.elf $(BIN)/*.elf.txt $(BIN)/*.map $(BIN)/*.lst
diff --git a/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/ads7843.c b/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/ads7843.c
new file mode 100644
index 00000000..1ad9fde2
--- /dev/null
+++ b/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/ads7843.c
@@ -0,0 +1,197 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * 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:
+ *
+ * - 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 ADS7843 driver.
+ *
+ */
+
+/*----------------------------------------------------------------------------
+ * Headers
+ *----------------------------------------------------------------------------*/
+
+#include "board.h"
+
+/*----------------------------------------------------------------------------
+ * Definitions
+ *----------------------------------------------------------------------------*/
+
+#define ADS_CTRL_PD0 (1 << 0) /* PD0 */
+#define ADS_CTRL_PD1 (1 << 1) /* PD1 */
+#define ADS_CTRL_DFR (1 << 2) /* SER/DFR */
+#define ADS_CTRL_EIGHT_BITS_MOD (1 << 3) /* Mode */
+#define ADS_CTRL_START (1 << 7) /* Start Bit */
+#define ADS_CTRL_SWITCH_SHIFT 4 /* Address setting */
+
+/* Get X position command */
+#define CMD_Y_POSITION ((1 << ADS_CTRL_SWITCH_SHIFT) | ADS_CTRL_START | ADS_CTRL_PD0 | ADS_CTRL_PD1)
+/* Get Y position command */
+#define CMD_X_POSITION ((5 << ADS_CTRL_SWITCH_SHIFT) | ADS_CTRL_START | ADS_CTRL_PD0 | ADS_CTRL_PD1)
+
+/* Enable penIRQ */
+#define CMD_ENABLE_PENIRQ ((1 << ADS_CTRL_SWITCH_SHIFT) | ADS_CTRL_START)
+
+
+#define ADS7843_TIMEOUT 5000000
+
+#define DELAY_BEFORE_SPCK 200 /* 2us min (tCSS) <=> 200/100 000 000 = 2us */
+#define DELAY_BETWEEN_CONS_COM 0xf /* 5us min (tCSH) <=> (32 * 15) / (100 000 000) = 5us */
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ *----------------------------------------------------------------------------*/
+
+/** Pins used by SPI */
+static const Pin pinsSPI[] = {BOARD_TSC_SPI_PINS, BOARD_TSC_NPCS_PIN};
+
+/** Touch screen BUSY pin */
+static const Pin pinBusy[] = {PIN_TSC_BUSY};
+
+/*----------------------------------------------------------------------------
+ * Local functions
+ *----------------------------------------------------------------------------*/
+
+/**
+ * \brief Generic function to send a command to the touchscreen controller.
+ *
+ * \param bCmd command to send
+ *
+ * \return command result
+ */
+static uint32_t SendCommand( uint8_t bCmd )
+{
+ uint32_t uResult = 0;
+ uint32_t uTimeout = 0;
+
+ /* (volatile declaration needed for code optimisation by compiler) */
+ volatile uint8_t bufferRX[3];
+ volatile uint8_t bufferTX[3];
+
+ Pdc *pPdc = (Pdc *)SPI;
+ uint32_t dStatus;
+
+ bufferRX[0] = 0;
+ bufferRX[1] = 0;
+ bufferRX[2] = 0;
+
+ bufferTX[0] = bCmd;
+ bufferTX[1] = 0;
+ bufferTX[2] = 0;
+
+ /* Send Command and data through the SPI */
+ pPdc->PERIPH_PTCR = PERIPH_PTCR_RXTDIS;
+ pPdc->PERIPH_RPR = (uint32_t) bufferRX;
+ pPdc->PERIPH_RCR = 3;
+
+ pPdc->PERIPH_PTCR = PERIPH_PTCR_TXTDIS;
+ pPdc->PERIPH_TPR = (uint32_t) bufferTX;
+ pPdc->PERIPH_TCR = 3;
+
+ pPdc->PERIPH_PTCR = PERIPH_PTCR_RXTEN;
+ pPdc->PERIPH_PTCR = PERIPH_PTCR_TXTEN;
+
+ do
+ {
+ dStatus = REG_SPI_SR;
+ uTimeout++;
+ }
+ while ((( dStatus & SPI_SR_RXBUFF) != SPI_SR_RXBUFF) && (uTimeout < ADS7843_TIMEOUT));
+
+ pPdc->PERIPH_PTCR = PERIPH_PTCR_RXTDIS;
+ pPdc->PERIPH_PTCR = PERIPH_PTCR_TXTDIS;
+
+ uResult = (uint32_t)bufferRX[1] << 8;
+ uResult |= (uint32_t)bufferRX[2];
+ uResult = uResult >> 4;
+
+ return uResult;
+}
+
+/*----------------------------------------------------------------------------
+ * Exported functions
+ *----------------------------------------------------------------------------*/
+
+/**
+ * \brief Get position of the pen by ask the ADS controller (SPI).
+ *
+ * \param px_pos pointer to the horizontal position
+ * \param py_pos pointer to the vertical position
+ *
+ */
+extern void ADS7843_GetPosition( uint32_t *px_pos, uint32_t *py_pos )
+{
+ /* Get X position */
+ *px_pos = SendCommand(CMD_X_POSITION);
+ /* Get Y position */
+ *py_pos = SendCommand(CMD_Y_POSITION);
+ /* Switch to full power mode */
+ SendCommand(CMD_ENABLE_PENIRQ);
+}
+
+/**
+ * \brief Initialization of the SPI for communication with ADS7843 component.
+ */
+extern void ADS7843_Initialize( void )
+{
+ volatile uint32_t uDummy;
+
+ /* Configure pins */
+ PIO_Configure(pinsSPI, PIO_LISTSIZE(pinsSPI));
+
+ PIO_Configure(pinBusy, PIO_LISTSIZE(pinBusy));
+
+ SPI_Configure(BOARD_TSC_SPI_BASE,
+ BOARD_TSC_SPI_ID,
+ SPI_MR_MSTR | SPI_MR_MODFDIS | SPI_PCS(BOARD_TSC_NPCS) /* Value of the SPI configuration register. */
+ );
+
+ SPI_ConfigureNPCS(BOARD_TSC_SPI_BASE, BOARD_TSC_NPCS,
+ SPI_CSR_NCPHA | SPI_CSR_DLYBS(DELAY_BEFORE_SPCK) |
+ SPI_CSR_DLYBCT(DELAY_BETWEEN_CONS_COM) | SPI_CSR_SCBR(0xC8) );
+
+ SPI_Enable(BOARD_TSC_SPI_BASE);
+
+ for (uDummy=0; uDummy<100000; uDummy++);
+
+ uDummy = REG_SPI_SR;
+ uDummy = REG_SPI_RDR;
+
+ SendCommand(CMD_ENABLE_PENIRQ);
+}
+
+/**
+ * \brief Reset the ADS7843
+ */
+void ADS7843_Reset( void )
+{
+ /* Disable SPI */
+ SPI_Disable( BOARD_TSC_SPI_BASE ) ;
+}
diff --git a/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/at45_spi.c b/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/at45_spi.c
new file mode 100644
index 00000000..2d84c4c2
--- /dev/null
+++ b/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/at45_spi.c
@@ -0,0 +1,316 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * 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:
+ *
+ * - 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_at45_module SPI AT45 driver
+ * \ingroup at45d_module
+ * The Dataflash driver is based on top of the corresponding Spi driver.
+ * A Dataflash structure instance has to be initialized using the DF_Init
+ * function. Then basic dataflash operations can be launched using macros such
+ * as DF_continuous_read. These macros invoke the DF_Command() function which
+ * invokes the DPI low driver using the SPI_SendCommand() function.
+ * Beware to compute the dataflash internal address, the dataflash sector
+ * description must be known (DataflashDesc). Dataflash can be automatically
+ * detected using the DF_Scan() function.
+ *
+ * \section Usage
+ *
+ * - Initializes an AT45 instance and configures SPI chip select pin
+ * using AT45_Configure().
+ * - Detect DF and returns DF description corresponding to the device
+ * connected using AT45_FindDevice().This function shall be called by
+ * the application before AT45_SendCommand.
+ * - Sends a command to the DF through the SPI using AT45_SendCommand().
+ * The command is identified by its command code and the number of
+ * bytes to transfer.
+ * - Example code for sending command to write a page to DF.
+ * \code
+ * // Issue a page write through buffer 1 command
+ * error = AT45_SendCommand(pAt45, AT45_PAGE_WRITE_BUF1, 4,
+ * pBuffer, size, address, 0, 0);
+ * \endcode
+ * - Example code for sending command to read a page from DF.
+ * If data needs to be received, then a data buffer must be
+ * provided.
+ * \code
+ * // Issue a continuous read array command
+ * error = AT45_SendCommand(pAt45, AT45_CONTINUOUS_READ_LEG, 8,
+ * pBuffer, size, address, 0, 0);
+ * \endcode
+ * - This function does not block; its optional callback will
+ * be invoked when the transfer completes.
+ * - Check the AT45 driver is ready or not by polling AT45_IsBusy().
+ *
+ * Related files :\n
+ * \ref spi_at45.c\n
+ * \ref spi_at45.h.\n
+*/
+/*@{*/
+/*@}*/
+
+
+/**
+ * \file
+ *
+ * Implementation of SPI At45 driver.
+ *
+ */
+
+
+
+/*----------------------------------------------------------------------------
+ * Headers
+ *----------------------------------------------------------------------------*/
+
+#include "board.h"
+
+#include
+#include
+
+/*----------------------------------------------------------------------------
+ * Internal definitions
+ *----------------------------------------------------------------------------*/
+
+/** Number of dataflash which can be recognized.*/
+#define NUMDATAFLASH (sizeof(at45Devices) / sizeof(At45Desc))
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ *----------------------------------------------------------------------------*/
+
+/** indicate if the device is configured as binary page or not.*/
+static uint8_t configuredBinaryPage;
+
+/** At45 device descriptor structure. */
+static const At45Desc at45Devices[] = {
+ { 512, 1, 264, 9, 0x0C, "AT45DB011D"},
+ { 1024, 1, 264, 9, 0x14, "AT45DB021D"},
+ { 2048, 1, 264, 9, 0x1C, "AT45DB041D"},
+ { 4096, 1, 264, 9, 0x24, "AT45DB081D"},
+ { 4096, 1, 528, 10, 0x2C, "AT45DB161D"},
+ { 8192, 1, 528, 10, 0x34, "AT45DB321D"},
+ { 8192, 1, 1056, 11, 0x3C, "AT45DB642D"},
+ {16384, 1, 1056, 11, 0x10, "AT45DB1282"},
+ {16384, 1, 2112, 12, 0x18, "AT45DB2562"},
+ {32768, 1, 2112, 12, 0x20, "AT45DB5122"}
+};
+
+/*----------------------------------------------------------------------------
+ * Exported functions
+ *----------------------------------------------------------------------------*/
+
+/**
+ * \brief Initializes an AT45 instance and configures SPI chip select register.
+ *
+ * \param pAt45 Pointer to the At45 instance to initialize.
+ * \param pSpid Pointer to the underlying SPI driver.
+ * \param spiCs Chip select value to connect to the At45.
+ * \return 0.
+ */
+extern uint32_t AT45_Configure( At45* pAt45, Spid* pSpid, uint8_t ucSpiCs )
+{
+ SpidCmd* pCommand ;
+
+ /* Sanity checks */
+ assert( pSpid != NULL ) ;
+ assert( pAt45 != NULL ) ;
+
+ /* Initialize the At45 instance */
+ pAt45->pSpid = pSpid ;
+ pAt45->pDesc = 0 ;
+ memset( pAt45->pCmdBuffer, 0, 8 ) ;
+
+ /* Initialize the spidCmd structure */
+ pCommand = &(pAt45->command) ;
+ pCommand->pCmd = pAt45->pCmdBuffer ;
+ pCommand->callback = 0 ;
+ pCommand->pArgument = 0 ;
+ pCommand->spiCs = ucSpiCs ;
+
+ return 0 ;
+}
+
+/**
+ * \brief Check if the At45 driver is in busy.
+ *
+ * \param pAt45 Pointer to the At45 instance to initialize.
+ * \return 1 if the At45 driver is not executing any command,otherwise it returns 0.
+ */
+extern uint32_t AT45_IsBusy( At45* pAt45 )
+{
+ return SPID_IsBusy( pAt45->pSpid ) ;
+}
+
+/**
+ * \brief Sends a command to the dataflash through the SPI.
+ * The command is identified by its command code and the number of bytes to transfer
+ * (1 + number of address bytes + number of dummy bytes).If data needs to be received,
+ * then a data buffer must be provided.
+ * \note This function does not block; its optional callback will be invoked when
+ * the transfer completes.
+ * \param pAt45 Pointer to the At45 instance to initialize.
+ * \param cmd Command code.
+ * \param cmdSize Size of command code + address bytes + dummy bytes.
+ * \param pData Data buffer.
+ * \param dataSize Number of data bytes to send/receive.
+ * \param address Address at which the command is performed if meaningful.
+ * \param callback Optional callback to invoke at end of transfer.
+ * \param pArgument Optional parameter to the callback function.
+ * \return 0.
+ */
+extern uint32_t AT45_SendCommand( At45* pAt45, uint8_t ucCmd, uint8_t ucCmdSize, uint8_t *pucData, uint32_t dwDataSize,
+ uint32_t dwAddress, SpidCallback pCallback, void *pArgument )
+{
+ SpidCmd *pCommand ;
+ const At45Desc *pDesc;
+ uint32_t dfAddress = 0 ;
+
+ /* Sanity checks */
+ assert( pAt45 != NULL ) ;
+
+ pDesc = pAt45->pDesc ;
+
+ assert( pDesc || (ucCmd == AT45_STATUS_READ) ) ;
+
+ /* Check if the SPI driver is available*/
+ if ( AT45_IsBusy( pAt45 ) )
+ {
+ return AT45_ERROR_LOCK ;
+ }
+
+ /* Compute command pattern*/
+ pAt45->pCmdBuffer[0] = ucCmd ;
+
+ /* Add address bytes if necessary*/
+ if ( ucCmdSize > 1 )
+ {
+ assert( pDesc != NULL ) ;
+ if ( !configuredBinaryPage )
+ {
+ dfAddress = ((dwAddress / (pDesc->pageSize)) << pDesc->pageOffset)
+ + (dwAddress % (pDesc->pageSize));
+ }
+ else
+ {
+ dfAddress = dwAddress ;
+ }
+
+ /* Write address bytes */
+ if ( pDesc->pageNumber >= 16384 )
+ {
+ pAt45->pCmdBuffer[1] = ((dfAddress & 0x0F000000) >> 24);
+ pAt45->pCmdBuffer[2] = ((dfAddress & 0x00FF0000) >> 16);
+ pAt45->pCmdBuffer[3] = ((dfAddress & 0x0000FF00) >> 8);
+ pAt45->pCmdBuffer[4] = ((dfAddress & 0x000000FF) >> 0);
+
+ if ( (ucCmd != AT45_CONTINUOUS_READ) && (ucCmd != AT45_PAGE_READ) )
+ {
+ ucCmdSize++ ;
+ }
+ }
+ else
+ {
+ pAt45->pCmdBuffer[1] = ((dfAddress & 0x00FF0000) >> 16);
+ pAt45->pCmdBuffer[2] = ((dfAddress & 0x0000FF00) >> 8);
+ pAt45->pCmdBuffer[3] = ((dfAddress & 0x000000FF) >> 0);
+ }
+ }
+
+ /* Update the SPI Transfer descriptors */
+ pCommand = &(pAt45->command) ;
+ pCommand->cmdSize = ucCmdSize ;
+ pCommand->pData = pucData ;
+ pCommand->dataSize = dwDataSize ;
+ pCommand->callback = pCallback ;
+ pCommand->pArgument = pArgument ;
+
+ /* Send Command and data through the SPI */
+ if ( SPID_SendCommand( pAt45->pSpid, pCommand ) )
+ {
+ return AT45_ERROR_SPI ;
+ }
+
+ return 0 ;
+}
+
+/**
+ * \brief returns the At45Desc structure corresponding to the device connected.
+ * It automatically initializes pAt45->pDesc field structure.
+ *
+ * \note This function shall be called by the application before AT45_SendCommand.
+ *
+ * \param pAt45 Pointer to the At45 instance to initialize.
+ * \param status Device status register value.
+ *
+ * \return 0 if successful; Otherwise, returns AT45_ERROR_LOCK if the At45
+ * driver is in use or AT45_ERROR_SPI if there was an error with the SPI driver.
+ */
+extern const At45Desc * AT45_FindDevice( At45 *pAt45, uint8_t status )
+{
+ uint32_t i;
+ uint8_t id = AT45_STATUS_ID(status);
+
+ /* Check if status is all one; in which case, it is assumed that no device is connected*/
+ if ( status == 0xFF )
+ {
+ return 0 ;
+ }
+
+ /* Look in device array */
+ i = 0 ;
+ pAt45->pDesc = 0 ;
+ while ( (i < NUMDATAFLASH) && !(pAt45->pDesc) )
+ {
+ if ( at45Devices[i].id == id )
+ {
+ pAt45->pDesc = &(at45Devices[i]) ;
+ }
+ i++ ;
+ }
+
+ configuredBinaryPage = AT45_STATUS_BINARY(status);
+
+ return pAt45->pDesc ;
+}
+
+/**
+ * \brief returns the pagesize corresponding to the device connected.
+ * \param pAt45 Pointer to the At45 instance to initialize.
+ * \return page size.
+ */
+extern uint32_t AT45_PageSize( At45 *pAt45 )
+{
+ uint32_t dwPageSize = pAt45->pDesc->pageSize ;
+
+ if ( ((pAt45->pDesc->hasBinaryPage) == 0) || !configuredBinaryPage )
+ {
+ return dwPageSize ;
+ }
+
+ return ((dwPageSize >> 8) << 8) ;
+}
diff --git a/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/at45d.c b/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/at45d.c
new file mode 100644
index 00000000..71b7b76d
--- /dev/null
+++ b/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/at45d.c
@@ -0,0 +1,254 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * 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:
+ *
+ * - 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 external_component External Component
+ *
+ * \addtogroup at45d_module AT45 driver
+ * \ingroup external_component
+ * The AT45 Dataflash driver is based on the corresponding AT45 driver.
+ * A AT45 instance has to be initialized using the Dataflash levle function
+ * AT45_Configure(). AT45 Dataflash can be automatically detected using
+ * the AT45_FindDevice() function. Then AT45 dataflash operations such as
+ * read, write and erase DF can be launched using AT45_SendCommand function
+ * with corresponding AT45 command set.
+ *
+ * \section Usage
+ *
+ * - Reads data from the At45 at the specified address using AT45D_Read().
+ * - Writes data on the At45 at the specified address using AT45D_Write().
+ * - Erases a page of data at the given address using AT45D_Erase().
+ * - Poll until the At45 has completed of corresponding operations using
+ * AT45D_WaitReady().
+ * - Retrieves and returns the At45 current using AT45D_GetStatus().
+ *
+ * Related files :\n
+ * \ref at45d.c\n
+ * \ref at45d.h.\n
+ */
+ /*@{*/
+ /*@}*/
+
+
+/**
+ * \file
+ *
+ * Implementation of At45 driver.
+ *
+ */
+
+/*----------------------------------------------------------------------------
+ * Headers
+ *----------------------------------------------------------------------------*/
+
+#include "board.h"
+
+#include
+#include
+
+/*----------------------------------------------------------------------------
+ * Local functions
+ *----------------------------------------------------------------------------*/
+
+/**
+ * \brief Wait for transfer to finish calling the SPI driver ISR (interrupts are
+ * disabled).
+ *
+ * \param pAt45 Pointer to an AT45 driver instance.
+ */
+static void AT45D_Wait( At45* pAt45 )
+{
+ assert( pAt45 != NULL ) ;
+
+ /* Wait for transfer to finish */
+ while ( AT45_IsBusy( pAt45 ) )
+ {
+ SPID_Handler( pAt45->pSpid ) ;
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * Global functions
+ *----------------------------------------------------------------------------*/
+
+/**
+ * \brief Waits for the At45 to be ready to accept new commands.
+ *
+ * \param pAt45 Pointer to an AT45 driver instance.
+ */
+extern void AT45D_WaitReady( At45* pAt45 )
+{
+ uint8_t ready = 0;
+
+ assert( pAt45 != NULL ) ;
+
+ /* Poll device until it is ready. */
+ while (!ready)
+ {
+ ready = AT45_STATUS_READY(AT45D_GetStatus(pAt45));
+ }
+}
+
+/**
+ * \brief Retrieves and returns the At45 current status, or 0 if an error happened.
+ *
+ * \param pAt45 Pointer to an AT45 driver instance.
+ */
+extern uint32_t AT45D_GetStatus( At45* pAt45 )
+{
+ uint32_t dwError ;
+ uint8_t ucStatus ;
+
+ assert( pAt45 != NULL ) ;
+
+ /* Issue a status register read command */
+ dwError = AT45_SendCommand( pAt45, AT45_STATUS_READ, 1, &ucStatus, 1, 0, 0, 0 ) ;
+ assert( !dwError ) ;
+
+ /* Wait for command to terminate */
+ while ( AT45_IsBusy( pAt45 ) )
+ {
+ AT45D_Wait( pAt45 ) ;
+ }
+
+ return ucStatus ;
+}
+
+/**
+ * \brief Reads data from the At45 inside the provided buffer. Since a continuous
+ * read command is used, there is no restriction on the buffer size and read address.
+ *
+ * \param pAt45 Pointer to an AT45 driver instance.
+ * \param pBuffer Data buffer.
+ * \param size Number of bytes to read.
+ * \param address Address at which data shall be read.
+ */
+extern void AT45D_Read( At45* pAt45, uint8_t* pucBuffer, uint32_t dwSize, uint32_t dwAddress )
+{
+ uint32_t dwError ;
+
+ assert( pAt45 != NULL ) ;
+ assert( pucBuffer != NULL ) ;
+
+ /* Issue a continuous read array command. */
+ dwError = AT45_SendCommand( pAt45, AT45_CONTINUOUS_READ_LEG, 8, pucBuffer, dwSize, dwAddress, 0, 0 ) ;
+ assert( !dwError ) ;
+
+ /* Wait for the read command to execute. */
+ while ( AT45_IsBusy( pAt45 ) )
+ {
+ AT45D_Wait( pAt45 ) ;
+ }
+}
+
+/**
+ * \brief Writes data on the At45 at the specified address. Only one page of
+ * data is written that way; if the address is not at the beginning of the
+ * page, the data is written starting from this address and wraps around to
+ * the beginning of the page.
+ *
+ * \param pAt45 Pointer to an AT45 driver instance.
+ * \param pucBuffer Data buffer.
+ * \param dwSize Number of bytes to write.
+ * \param dwAddress Destination address on the At45.
+ */
+extern void AT45D_Write( At45* pAt45, uint8_t *pucBuffer, uint32_t dwSize, uint32_t dwAddress )
+{
+ uint8_t dwError ;
+
+ assert( pAt45 != NULL ) ;
+ assert( pucBuffer != NULL ) ;
+ assert( dwSize <= pAt45->pDesc->pageSize ) ;
+
+ /* Issue a page write through buffer 1 command. */
+ dwError = AT45_SendCommand( pAt45, AT45_PAGE_WRITE_BUF1, 4, pucBuffer, dwSize, dwAddress, 0, 0 ) ;
+ assert( !dwError ) ;
+
+ /* Wait until the command is sent. */
+ while ( AT45_IsBusy( pAt45 ) )
+ {
+ AT45D_Wait( pAt45 ) ;
+ }
+
+ /* Wait until the At45 becomes ready again.*/
+ AT45D_WaitReady( pAt45 ) ;
+}
+
+/**
+ * \brief Erases a page of data at the given address in the At45.
+ *
+ * \param pAt45 Pointer to an AT45 driver instance.
+ * \param dwAddress Address of page to erase.
+ */
+extern void AT45D_Erase( At45* pAt45, uint32_t dwAddress )
+{
+ uint32_t dwError ;
+
+ assert( pAt45 != NULL ) ;
+
+ /* Issue a page erase command. */
+ dwError = AT45_SendCommand( pAt45, AT45_PAGE_ERASE, 4, 0, 0, dwAddress, 0, 0 ) ;
+ assert( !dwError ) ;
+
+ /* Wait for end of transfer. */
+ while ( AT45_IsBusy(pAt45 ) )
+ {
+ AT45D_Wait( pAt45 ) ;
+ }
+
+ /* Poll until the At45 has completed the erase operation. */
+ AT45D_WaitReady( pAt45 ) ;
+}
+
+/**
+ * \brief Configure power-of-2 binary page size in the At45.
+ *
+ * \param pAt45 Pointer to an AT45 driver instance.
+ */
+extern void AT45D_BinaryPage( At45* pAt45 )
+{
+ uint8_t dwError ;
+ uint8_t opcode[3]= {AT45_BINARY_PAGE};
+ assert( pAt45 != NULL ) ;
+
+ /* Issue a binary page command. */
+
+ dwError = AT45_SendCommand( pAt45, AT45_BINARY_PAGE_FIRST_OPCODE, 1, opcode, 3, 0, 0, 0 ) ;
+
+ assert( !dwError ) ;
+
+ /* Wait for end of transfer.*/
+ while ( AT45_IsBusy( pAt45 ) )
+ {
+ AT45D_Wait( pAt45 ) ;
+ }
+
+ /* Wait until the At45 becomes ready again.*/
+ AT45D_WaitReady( pAt45 ) ;
+}
diff --git a/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/bmp.c b/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/bmp.c
new file mode 100644
index 00000000..7637e76c
--- /dev/null
+++ b/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/bmp.c
@@ -0,0 +1,319 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, 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.
+ * ----------------------------------------------------------------------------
+ */
+
+//------------------------------------------------------------------------------
+// Headers
+//------------------------------------------------------------------------------
+
+#include "board.h"
+
+#include
+
+//-----------------------------------------------------------------------------
+// Define
+//-----------------------------------------------------------------------------
+/// BMP offset for header
+#define IMAGE_OFFSET 0x100
+
+
+//------------------------------------------------------------------------------
+// Internal constants
+//------------------------------------------------------------------------------
+
+
+//------------------------------------------------------------------------------
+// Internal types
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// Describe the BMP palette
+//------------------------------------------------------------------------------
+typedef struct _BMPPaletteEntry
+{
+ /// Blue value
+ uint8_t b;
+ /// Green value
+ uint8_t g;
+ /// Red value
+ uint8_t r;
+ /// Filler character value
+ uint8_t filler;
+} BMPPaletteEntry ;
+
+//------------------------------------------------------------------------------
+// Exported functions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// Test if BMP is valid
+/// \param file Buffer holding the file to examinate.
+/// \return 1 if the header of a BMP file is valid; otherwise returns 0.
+//------------------------------------------------------------------------------
+uint8_t BMP_IsValid( void *file )
+{
+ return ((BMPHeader*) file)->type == BMP_TYPE ;
+}
+
+//------------------------------------------------------------------------------
+/// Returns the size of a BMP image given at least its header (the file does
+/// not have to be complete).
+/// \param file Pointer to the buffer which holds the BMP file.
+/// \return size of BMP image
+//------------------------------------------------------------------------------
+uint32_t BMP_GetFileSize( void *file )
+{
+ return ((BMPHeader *) file)->fileSize ;
+}
+
+//-----------------------------------------------------------------------------
+/// Write a BMP header
+/// \param pAddressHeader Begin address of the BMP
+/// \param bmpHSize BMP heigth size
+/// \param bmpVSize BMP width size
+/// \param nbByte_Pixels Number of byte per pixels
+//-----------------------------------------------------------------------------
+void WriteBMPheader( uint32_t* pAddressHeader, uint32_t bmpHSize, uint32_t bmpVSize, uint8_t nbByte_Pixels )
+{
+ uint32_t i;
+ uint32_t* fill;
+ BMPHeader *Header;
+
+ fill = pAddressHeader;
+ for ( i=0 ; i < IMAGE_OFFSET ; i+=4 )
+ {
+ *fill++ = 0;
+ }
+
+ Header = (BMPHeader*) pAddressHeader;
+
+ Header->type = BMP_TYPE;
+ Header->fileSize = (bmpHSize * bmpVSize * nbByte_Pixels) + IMAGE_OFFSET;
+ Header->reserved1 = 0;
+ Header->reserved2 = 0;
+ Header->offset = IMAGE_OFFSET;
+ Header->headerSize = BITMAPINFOHEADER;
+ Header->width = bmpHSize;
+ Header->height = bmpVSize;
+ Header->planes = 1;
+ Header->bits = nbByte_Pixels * 8;
+ Header->compression = 0;
+ Header->imageSize = bmpHSize * bmpVSize * nbByte_Pixels;
+ Header->xresolution = 0;
+ Header->yresolution = 0;
+ Header->ncolours = 0;
+ Header->importantcolours = 0;
+}
+
+
+//------------------------------------------------------------------------------
+/// debug function, dislay BMP header
+/// \param pAddressHeader Address of the BMP
+//------------------------------------------------------------------------------
+#if (TRACE_LEVEL >= TRACE_LEVEL_INFO)
+void BMP_displayHeader( uint32_t* pAddressHeader )
+{
+ BMPHeader *header;
+
+ header = (BMPHeader*) pAddressHeader;
+
+ TRACE_INFO("BMP\n\r");
+ TRACE_INFO("type 0x%X \n\r", header->type);
+ TRACE_INFO("fileSize %d \n\r", header->fileSize);
+ TRACE_INFO("reserved1 %d \n\r", header->reserved1);
+ TRACE_INFO("reserved2 %d \n\r", header->reserved2);
+ TRACE_INFO("offset %d \n\r", header->offset);
+ TRACE_INFO("headerSize %d \n\r", header->headerSize);
+ TRACE_INFO("width %d \n\r", header->width);
+ TRACE_INFO("height %d \n\r", header->height);
+ TRACE_INFO("planes %d \n\r", header->planes);
+ TRACE_INFO("bits %d \n\r", header->bits);
+ TRACE_INFO("compression %d \n\r", header->compression);
+ TRACE_INFO("imageSize %d \n\r", header->imageSize);
+ TRACE_INFO("xresolution %d \n\r", header->xresolution);
+ TRACE_INFO("yresolution %d \n\r", header->yresolution);
+ TRACE_INFO("ncolours %d \n\r", header->ncolours);
+ TRACE_INFO("importantcolours %d\n\r", header->importantcolours);
+}
+#endif
+
+//------------------------------------------------------------------------------
+/// Loads a BMP image located at the given address, decodes it and stores the
+/// resulting image inside the provided buffer. Image must have the specified
+/// width & height.
+/// If no buffer is provided, this function simply checks if it is able to
+/// decode the image.
+/// \param file Buffer which holds the BMP file.
+/// \param buffer Buffer in which to store the decoded image.
+/// \param width Buffer width in pixels.
+/// \param height Buffer height in pixels.
+/// \param bpp Number of bits per pixels that the buffer stores.
+/// \return 0 if the image has been loaded; otherwise returns an error code.
+//------------------------------------------------------------------------------
+uint8_t BMP_Decode( void *file, uint8_t *buffer, uint32_t width, uint32_t height, uint8_t bpp )
+{
+ BMPHeader *header;
+ uint32_t i, j;
+ uint8_t r, g, b;
+ uint8_t *image;
+
+ // Read header information
+ header = (BMPHeader*) file;
+
+ // Verify that the file is valid
+ if ( !BMP_IsValid( file ) )
+ {
+ TRACE_ERROR("BMP_Decode: File type is not 'BM' (0x%04X).\n\r",header->type);
+
+ return 1;
+ }
+
+ // Check that parameters match
+ if ( (header->compression != 0) || (header->width != width) || (header->height != height))
+ {
+ TRACE_ERROR("BMP_Decode: File format not supported\n\r");
+ TRACE_ERROR(" -> .compression = %u\n\r", (unsigned int)header->compression);
+ TRACE_ERROR(" -> .width = %u\n\r", (unsigned int)header->width);
+ TRACE_ERROR(" -> .height = %u\n\r", (unsigned int)header->height);
+ TRACE_ERROR(" -> .bits = %d\n\r", (int)header->bits);
+
+ return 2;
+ }
+
+ // Get image data
+ image = (uint8_t *) ((uint32_t) file + header->offset);
+
+ // Check that the bpp resolution is supported
+ // Only a 24-bit output & 24- or 8-bit input are supported
+ if ( bpp != 24 )
+ {
+ TRACE_ERROR("BMP_Decode: Output resolution not supported\n\r");
+
+ return 3;
+ }
+ else
+ {
+ if (header->bits == 24)
+ {
+ // Decoding is ok
+ if (!buffer) return 0;
+
+ // Get image data (swapping red & blue)
+ for ( i=0 ; i < height ; i++ )
+ {
+ for ( j=0 ; j < width; j++ )
+ {
+ r = image[((height - i - 1) * width + j) * 3 + 2];
+ g = image[((height - i - 1) * width + j) * 3 + 1];
+ b = image[((height - i - 1) * width + j) * 3];
+
+ #if defined(BOARD_LCD_RGB565)
+ // Interlacing
+ r = ((r << 1) & 0xF0) | ((g & 0x80) >> 4) | ((r & 0x80) >> 5);
+ g = (g << 1) & 0xF8;
+ b = b & 0xF8;
+
+ buffer[(i * width + j) * 3] = b;
+ buffer[(i * width + j) * 3 + 1] = g;
+ buffer[(i * width + j) * 3 + 2] = r;
+
+ #else
+ buffer[(i * width + j) * 3] = r;
+ buffer[(i * width + j) * 3 + 1] = g;
+ buffer[(i * width + j) * 3 + 2] = b;
+ #endif //#if defined(BOARD_LCD_RGB565)
+ }
+ }
+ }
+ else
+ {
+ if ( header->bits == 8 )
+ {
+ BMPPaletteEntry palette[256];
+
+ // Decoding is ok
+ if (!buffer) return 0;
+
+ // Retrieve palette
+ memcpy( palette, (uint8_t *) ((uint32_t) file + sizeof( BMPHeader )), header->offset - sizeof( BMPHeader ) ) ;
+
+ // Decode image (reversing row order)
+ for ( i=0 ; i < height ; i++ )
+ {
+ for (j=0; j < width; j++)
+ {
+ r = palette[image[(height - i - 1) * width + j]].r;
+ g = palette[image[(height - i - 1) * width + j]].g;
+ b = palette[image[(height - i - 1) * width + j]].b;
+
+ buffer[(i * width + j) * 3] = r;
+ buffer[(i * width + j) * 3 + 1] = g;
+ buffer[(i * width + j) * 3 + 2] = b;
+ }
+ }
+ }
+ else
+ {
+
+ TRACE_ERROR("BMP_Decode: Input resolution not supported\n\r");
+ TRACE_INFO("header->bits 0x%X \n\r", header->bits);
+ return 4 ;
+ }
+ }
+ }
+
+ return 0 ;
+}
+
+//------------------------------------------------------------------------------
+/// Convert RGB 565 to RGB 555 (RGB 555 is adapted to LCD)
+/// \param fileSource Buffer which holds the RGB file
+/// \param fileDestination Buffer in which to store the decoded image
+/// \param width Buffer width in pixels.
+/// \param height Buffer height in pixels.
+/// \param bpp Number of bits per pixels that the buffer stores.
+//------------------------------------------------------------------------------
+void RGB565toBGR555( uint8_t *fileSource, uint8_t *fileDestination, uint32_t width, uint32_t height, uint8_t bpp )
+{
+ uint32_t i;
+ uint32_t j;
+ uint32_t row;
+
+ for (i=0; i < height*(bpp/8); i++)
+ {
+ row = (i*width*(bpp/8));
+
+ for (j=0; j <= width*(bpp/8); j+=2)
+ {
+ fileDestination[row+j] = ((fileSource[row+j+1]>>3)&0x1F)
+ | (fileSource[row+j]&0xE0);
+ fileDestination[row+j+1] = (fileSource[row+j+1]&0x03)
+ | ((fileSource[row+j]&0x1F)<<2);
+ }
+ }
+}
diff --git a/sam3s_example/src/board_cstartup_gnu.c b/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/board_cstartup_gnu.c
similarity index 96%
rename from sam3s_example/src/board_cstartup_gnu.c
rename to sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/board_cstartup_gnu.c
index 423e7758..3647d5e7 100644
--- a/sam3s_example/src/board_cstartup_gnu.c
+++ b/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/board_cstartup_gnu.c
@@ -56,9 +56,12 @@ extern uint32_t _ezero;
/*----------------------------------------------------------------------------
* ProtoTypes
*----------------------------------------------------------------------------*/
+
+/** \cond DOXYGEN_SHOULD_SKIP_THIS */
extern int main( void ) ;
-extern void __libc_init_array( void ) ;
+/** \endcond */
void ResetException( void ) ;
+extern void __libc_init_array( void ) ;
/*------------------------------------------------------------------------------
* Exception Table
diff --git a/sam3s_example/src/board_lowlevel.c b/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/board_lowlevel.c
similarity index 92%
rename from sam3s_example/src/board_lowlevel.c
rename to sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/board_lowlevel.c
index ca9f9dc3..7c3a55d2 100644
--- a/sam3s_example/src/board_lowlevel.c
+++ b/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/board_lowlevel.c
@@ -38,13 +38,12 @@
*----------------------------------------------------------------------------*/
#include "board.h"
-#include "board_lowlevel.h"
/*----------------------------------------------------------------------------
* Local definitions
*----------------------------------------------------------------------------*/
-/* Clock settings at 48MHz */
+/* Clock settings at 48MHz for 12 MHz crystal */
#if (BOARD_MCK == 48000000)
#define BOARD_OSCOUNT (CKGR_MOR_MOSCXTST(0x8))
#define BOARD_PLLAR (CKGR_PLLAR_STUCKTO1 \
@@ -53,7 +52,7 @@
| CKGR_PLLAR_DIVA(0x1))
#define BOARD_MCKR (PMC_MCKR_PRES_CLK_2 | PMC_MCKR_CSS_PLLA_CLK)
-/* Clock settings at 64MHz */
+/* Clock settings at 64MHz for 12 MHz crystal */
#elif (BOARD_MCK == 64000000)
#define BOARD_OSCOUNT (CKGR_MOR_MOSCXTST(0x8))
#define BOARD_PLLAR (CKGR_PLLAR_STUCKTO1 \
@@ -78,7 +77,7 @@
* This includes EFC and master clock configuration.
* It also enable a low level on the pin NRST triggers a user reset.
*/
-WEAK void LowLevelInit( void )
+extern WEAK void LowLevelInit( void )
{
uint32_t timeout = 0;
@@ -86,22 +85,21 @@ WEAK void LowLevelInit( void )
EFC->EEFC_FMR = EEFC_FMR_FWS(3);
/* Select external slow clock */
-#if 0
- if ((SUPC->SUPC_SR & SUPC_SR_OSCSEL) != SUPC_SR_OSCSEL_CRYST)
+/* if ((SUPC->SUPC_SR & SUPC_SR_OSCSEL) != SUPC_SR_OSCSEL_CRYST)
{
SUPC->SUPC_CR = (uint32_t)(SUPC_CR_XTALSEL_CRYSTAL_SEL | SUPC_CR_KEY(0xA5));
timeout = 0;
while (!(SUPC->SUPC_SR & SUPC_SR_OSCSEL_CRYST) );
}
-#endif
+*/
/* Initialize main oscillator */
- if ( !(PMC->CKGR_MOR & CKGR_MOR_MOSCSEL) )
+/* if ( !(PMC->CKGR_MOR & CKGR_MOR_MOSCSEL) )
{
PMC->CKGR_MOR = CKGR_MOR_KEY(0x37) | BOARD_OSCOUNT | CKGR_MOR_MOSCRCEN | CKGR_MOR_MOSCXTEN;
timeout = 0;
while (!(PMC->PMC_SR & PMC_SR_MOSCXTS) && (timeout++ < CLOCK_TIMEOUT));
- }
+ }*/
/* Switch to 3-20MHz Xtal oscillator */
PMC->CKGR_MOR = CKGR_MOR_KEY(0x37) | BOARD_OSCOUNT | CKGR_MOR_MOSCRCEN | CKGR_MOR_MOSCXTEN | CKGR_MOR_MOSCSEL;
diff --git a/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/board_memories.c b/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/board_memories.c
new file mode 100644
index 00000000..ddeba30d
--- /dev/null
+++ b/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/board_memories.c
@@ -0,0 +1,153 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * 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:
+ *
+ * - 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
+ *----------------------------------------------------------------------------*/
+#include "board.h"
+
+/*----------------------------------------------------------------------------
+ * Exported functions
+ *----------------------------------------------------------------------------*/
+
+/**
+ * \brief Configures the EBI for NandFlash access.
+ */
+extern void BOARD_ConfigureNandFlash( Smc* pSmc )
+{
+ /* Enable peripheral clock */
+ PMC_EnablePeripheral( ID_SMC ) ;
+
+ /* NCS0 is assigned to a NAND Flash (NANDOE and NANWE used for NCS0) */
+ MATRIX->CCFG_SMCNFCS = CCFG_SMCNFCS_SMC_NFCS0;
+
+ pSmc->SMC_CS_NUMBER[0].SMC_SETUP = SMC_SETUP_NWE_SETUP(0)
+ | SMC_SETUP_NCS_WR_SETUP(1)
+ | SMC_SETUP_NRD_SETUP(0)
+ | SMC_SETUP_NCS_RD_SETUP(1);
+
+ pSmc->SMC_CS_NUMBER[0].SMC_PULSE = SMC_PULSE_NWE_PULSE(2)
+ | SMC_PULSE_NCS_WR_PULSE(3)
+ | SMC_PULSE_NRD_PULSE(4)
+ | SMC_PULSE_NCS_RD_PULSE(4);
+
+ pSmc->SMC_CS_NUMBER[0].SMC_CYCLE = SMC_CYCLE_NWE_CYCLE(4)
+ | SMC_CYCLE_NRD_CYCLE(7);
+
+ pSmc->SMC_CS_NUMBER[0].SMC_MODE = SMC_MODE_READ_MODE
+ | SMC_MODE_WRITE_MODE
+ | SMC_MODE_DBW_8_BIT;
+}
+
+/**
+ * \brief Configures the EBI for %NorFlash access.
+ */
+extern void BOARD_ConfigureNorFlash( Smc* pSmc )
+{
+ /* Enable peripheral clock */
+ PMC_EnablePeripheral( ID_SMC ) ;
+
+ /* Configure SMC, NCS3 is assigned to a norflash */
+ pSmc->SMC_CS_NUMBER[3].SMC_SETUP = SMC_SETUP_NWE_SETUP(2)
+ | SMC_SETUP_NCS_WR_SETUP(0)
+ | SMC_SETUP_NRD_SETUP(0)
+ | SMC_SETUP_NCS_RD_SETUP(0);
+
+ pSmc->SMC_CS_NUMBER[3].SMC_PULSE = SMC_PULSE_NWE_PULSE(6)
+ | SMC_PULSE_NCS_WR_PULSE(0xA)
+ | SMC_PULSE_NRD_PULSE(0xA)
+ | SMC_PULSE_NCS_RD_PULSE(0xA);
+
+ pSmc->SMC_CS_NUMBER[3].SMC_CYCLE = SMC_CYCLE_NWE_CYCLE(0xA)
+ | SMC_CYCLE_NRD_CYCLE(0xA);
+
+ pSmc->SMC_CS_NUMBER[3].SMC_MODE = SMC_MODE_READ_MODE
+ | SMC_MODE_WRITE_MODE
+ | SMC_MODE_DBW_8_BIT
+ | SMC_MODE_EXNW_MODE_DISABLED
+ | SMC_MODE_TDF_CYCLES(0x1);
+}
+
+/**
+ * \brief An accurate one-to-one comparison is necessary between PSRAM and SMC waveforms for
+ * a complete SMC configuration.
+ * \note The system is running at 48 MHz for the EBI Bus.
+ * Please refer to the "AC Characteristics" section of the customer product datasheet.
+ */
+extern void BOARD_ConfigurePSRAM( Smc* pSmc )
+{
+ uint32_t dwTmp ;
+
+ /* Enable peripheral clock */
+ PMC_EnablePeripheral( ID_SMC ) ;
+
+ /* Configure SMC, NCS1 is assigned to a external PSRAM */
+ /**
+ * PSRAM IS66WV51216BLL
+ * 55 ns Access time
+ * tdoe = 25 ns max
+ * SMC1 (timing SAM3S read mode SMC) = 21 ns of setup
+ * 21 + 55 = 76 ns => at least 5 cycles at 64 MHz
+ * Write pulse width minimum = 45 ns (PSRAM)
+ */
+ pSmc->SMC_CS_NUMBER[1].SMC_SETUP = SMC_SETUP_NWE_SETUP( 1 )
+ | SMC_SETUP_NCS_WR_SETUP( 0 )
+ | SMC_SETUP_NRD_SETUP( 2 )
+ | SMC_SETUP_NCS_RD_SETUP( 0 ) ;
+
+ pSmc->SMC_CS_NUMBER[1].SMC_PULSE = SMC_PULSE_NWE_PULSE( 3 )
+ | SMC_PULSE_NCS_WR_PULSE( 4 )
+ | SMC_PULSE_NRD_PULSE( 3 )
+ | SMC_PULSE_NCS_RD_PULSE( 5 ) ;
+
+ /* NWE_CYCLE: The total duration of the write cycle.
+ NWE_CYCLE = NWE_SETUP + NWE_PULSE + NWE_HOLD
+ = NCS_WR_SETUP + NCS_WR_PULSE + NCS_WR_HOLD
+ (tWC) Write Cycle Time min. 70ns
+ NRD_CYCLE: The total duration of the read cycle.
+ NRD_CYCLE = NRD_SETUP + NRD_PULSE + NRD_HOLD
+ = NCS_RD_SETUP + NCS_RD_PULSE + NCS_RD_HOLD
+ (tRC) Read Cycle Time min. 70ns. */
+ pSmc->SMC_CS_NUMBER[1].SMC_CYCLE = SMC_CYCLE_NWE_CYCLE( 4 )
+ | SMC_CYCLE_NRD_CYCLE( 5 ) ;
+
+ dwTmp = SMC->SMC_CS_NUMBER[0].SMC_MODE & (uint32_t)(~(SMC_MODE_DBW_Msk)) ;
+ pSmc->SMC_CS_NUMBER[1].SMC_MODE = dwTmp
+ | SMC_MODE_READ_MODE
+ | SMC_MODE_WRITE_MODE
+ | SMC_MODE_DBW_8_BIT ;
+}
+
diff --git a/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/clock.c b/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/clock.c
new file mode 100644
index 00000000..fb31374f
--- /dev/null
+++ b/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/clock.c
@@ -0,0 +1,184 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * 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:
+ *
+ * - 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"
+
+/*----------------------------------------------------------------------------
+ * Types
+ *----------------------------------------------------------------------------*/
+
+/*
+ * \brief Describes a possible clock configuration (processor clock & master clock),
+ * including the necessary register values.
+ */
+typedef struct _ClockConfiguration
+{
+
+ /** Processor clock frequency (in MHz). */
+ uint16_t pck;
+ /** Master clock frequency (in MHz). */
+ uint16_t mck;
+ /** CKGR_PLL reqister value. */
+ uint32_t pllr;
+ /** PMC_MCKR register value. */
+ uint32_t mckr;
+} ClockConfiguration ;
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ *----------------------------------------------------------------------------*/
+
+/* Clock configurations for the AT91SAM3S4-EK */
+#define CKGR_MUL_SHIFT 16
+#define CKGR_PLLCOUNT_SHIFT 8
+#define CKGR_DIV_SHIFT 0
+
+/* Clock configuration for the AT91SAM3S */
+static const ClockConfiguration clockConfigurations[] = {
+
+ /* PCK = 24 MHz, MCK = 24 MHz
+ * PCK = 12000000 * (7+1) / 2 / 2 = 24 MHz
+ */
+ {24, 24, (CKGR_PLLAR_STUCKTO1 | (7 << CKGR_MUL_SHIFT) \
+ | (0x3f << CKGR_PLLCOUNT_SHIFT) \
+ | (2 << CKGR_DIV_SHIFT)),
+ ( PMC_MCKR_PRES_CLK_2 | PMC_MCKR_CSS_PLLA_CLK)},
+ /* PCK = 48 MHz, MCK = 48 MHz
+ * PCK = 12000000 * (7+1) / 1 / 2 = 48 MHz
+ */
+ {48, 48, (CKGR_PLLAR_STUCKTO1 | (7 << CKGR_MUL_SHIFT) \
+ | (0x3f << CKGR_PLLCOUNT_SHIFT) \
+ | (1 << CKGR_DIV_SHIFT)),
+ ( PMC_MCKR_PRES_CLK_2 | PMC_MCKR_CSS_PLLA_CLK)},
+ /* PCK = 64 MHz, MCK = 64 MHz
+ * PCK = 12000000 * (15+1) / 3 / 1 = 64 MHz
+ */
+ {64, 64, (CKGR_PLLAR_STUCKTO1 | (15 << CKGR_MUL_SHIFT) \
+ | (0x3f << CKGR_PLLCOUNT_SHIFT) \
+ | (3 << CKGR_DIV_SHIFT)),
+ ( PMC_MCKR_PRES_CLK | PMC_MCKR_CSS_PLLA_CLK)}
+};
+
+/* Number of available clock configurations */
+#define NB_CLOCK_CONFIGURATION (sizeof(clockConfigurations)/sizeof(clockConfigurations[0]))
+
+/* Current clock configuration */
+uint32_t currentConfig = 0; /* 0 have to be the default configuration */
+
+/*----------------------------------------------------------------------------
+ * Exported functions
+ *----------------------------------------------------------------------------*/
+
+/**
+ * \brief Sets the specified clock configuration.
+ *
+ * \param configuration Index of the configuration to set.
+ */
+void CLOCK_SetConfig(uint8_t configuration)
+{
+ TRACE_DEBUG("Setting clock configuration #%d ... ", configuration);
+ currentConfig = configuration;
+
+ /* Switch to main oscillator in two operations */
+ PMC->PMC_MCKR = (PMC->PMC_MCKR & (uint32_t)~PMC_MCKR_CSS_Msk) | PMC_MCKR_CSS_MAIN_CLK;
+ while ((PMC->PMC_SR & PMC_SR_MCKRDY) == 0);
+
+ /* Configure PLL */
+ PMC->CKGR_PLLAR = clockConfigurations[configuration].pllr;
+ while ((PMC->PMC_SR & PMC_SR_LOCKA) == 0);
+
+ /* Configure master clock in two operations */
+ PMC->PMC_MCKR = (clockConfigurations[configuration].mckr & (uint32_t)~PMC_MCKR_CSS_Msk) | PMC_MCKR_CSS_MAIN_CLK;
+ while ((PMC->PMC_SR & PMC_SR_MCKRDY) == 0);
+ PMC->PMC_MCKR = clockConfigurations[configuration].mckr;
+ while ((PMC->PMC_SR & PMC_SR_MCKRDY) == 0);
+
+ /* DBGU reconfiguration */
+ UART_Configure(115200, clockConfigurations[configuration].mck*1000000);
+ TRACE_DEBUG("done.\n\r");
+}
+
+/**
+ * \brief Display the user menu on the DBGU.
+ */
+void CLOCK_DisplayMenu(void)
+{
+ uint32_t i;
+
+ printf("\n\rMenu Clock configuration:\n\r");
+ for (i = 0; i < NB_CLOCK_CONFIGURATION; i++) {
+
+ printf(" %u: Set PCK = %3u MHz, MCK = %3u MHz %s\n\r",
+ (unsigned int)i,
+ (unsigned int)clockConfigurations[i].pck,
+ (unsigned int)clockConfigurations[i].mck,
+ (currentConfig==i)?"(curr)":"");
+ }
+}
+
+/**
+ * \brief Get the current MCK
+ */
+uint16_t CLOCK_GetCurrMCK(void)
+{
+ return clockConfigurations[currentConfig].mck;
+}
+
+/**
+ * \brief Get the current PCK
+ */
+uint16_t CLOCK_GetCurrPCK(void)
+{
+ return clockConfigurations[currentConfig].pck;
+}
+
+/**
+ * \brief Change clock configuration.
+ */
+void CLOCK_UserChangeConfig(void)
+{
+ uint8_t key = 0;
+
+ while (1)
+ {
+ CLOCK_DisplayMenu();
+ key = UART_GetChar();
+
+ if ((key >= '0') && (key <= ('0' + NB_CLOCK_CONFIGURATION - 1)))
+ {
+ CLOCK_SetConfig(key - '0');
+ break;
+ }
+ }
+}
+
diff --git a/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/frame_buffer.c b/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/frame_buffer.c
new file mode 100644
index 00000000..bfc20ba4
--- /dev/null
+++ b/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/frame_buffer.c
@@ -0,0 +1,435 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2010, 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.
+ * ----------------------------------------------------------------------------
+ */
+
+/**
+ * \file
+ *
+ */
+
+/*----------------------------------------------------------------------------
+ * Headers
+ *----------------------------------------------------------------------------*/
+
+#include "board.h"
+#include
+#include
+
+/** Frame buffer color cache size used to optimize memcpy */
+#define FB_COLOR_CACHE_SIZE 8
+/*----------------------------------------------------------------------------
+ * Local variables
+ *----------------------------------------------------------------------------*/
+/** Pointer to frame buffer. It is 16 bit aligned to allow PDC operations
+ * LcdColor_t shall be defined in the physical lcd API (ili9225.c)
+*/
+static LcdColor_t *gpBuffer;
+/** Frame buffer width */
+static uint8_t gucWidth;
+/** Frame buffer height */
+static uint8_t gucHeight;
+/* Pixel color cache */
+static LcdColor_t gFbPixelCache[FB_COLOR_CACHE_SIZE];
+
+/*----------------------------------------------------------------------------
+ * Static functions
+ *----------------------------------------------------------------------------*/
+/**
+ * \brief Check Box coordinates. Return upper left and bottom right coordinates.
+ *
+ * \param pX1 X-coordinate of upper-left corner on LCD.
+ * \param pY1 Y-coordinate of upper-left corner on LCD.
+ * \param pX2 X-coordinate of lower-right corner on LCD.
+ * \param pY2 Y-coordinate of lower-right corner on LCD.
+ */
+static void CheckBoxCoordinates( uint32_t *pX1, uint32_t *pY1, uint32_t *pX2, uint32_t *pY2 )
+{
+ uint32_t dw;
+
+ if ( *pX1 >= gucWidth )
+ *pX1=gucWidth-1 ;
+
+ if ( *pX2 >= gucWidth )
+ *pX2=gucWidth-1 ;
+
+ if ( *pY1 >= gucHeight )
+ *pY1=gucHeight-1 ;
+
+ if ( *pY2 >= gucHeight )
+ *pY2=gucHeight-1 ;
+
+ if (*pX1 > *pX2) {
+ dw = *pX1;
+ *pX1 = *pX2;
+ *pX2 = dw;
+ }
+ if (*pY1 > *pY2) {
+ dw = *pY1;
+ *pY1 = *pY2;
+ *pY2 = dw;
+ }
+}
+
+/*
+ * \brief Draw a line on LCD, which is not horizontal or vertical.
+ *
+ * \param x X-coordinate of line start.
+ * \param y Y-coordinate of line start.
+ * \param length line length.
+ * \param direction line direction: 0 - horizontal, 1 - vertical.
+ * \param color Pixel color.
+ */
+static uint32_t DrawLineBresenham( uint32_t dwX1, uint32_t dwY1, uint32_t dwX2, uint32_t dwY2 )
+{
+ int dx, dy ;
+ int i ;
+ int xinc, yinc, cumul ;
+ int x, y ;
+
+ x = dwX1 ;
+ y = dwY1 ;
+ dx = dwX2 - dwX1 ;
+ dy = dwY2 - dwY1 ;
+
+ xinc = ( dx > 0 ) ? 1 : -1 ;
+ yinc = ( dy > 0 ) ? 1 : -1 ;
+ dx = ( dx > 0 ) ? dx : -dx ;
+ dy = ( dy > 0 ) ? dy : -dy ;
+
+ FB_DrawPixel(x, y);
+
+ if ( dx > dy )
+ {
+ cumul = dx / 2 ;
+ for ( i = 1 ; i <= dx ; i++ )
+ {
+ x += xinc ;
+ cumul += dy ;
+
+ if ( cumul >= dx )
+ {
+ cumul -= dx ;
+ y += yinc ;
+ }
+ FB_DrawPixel(x, y);
+ }
+ }
+ else
+ {
+ cumul = dy / 2 ;
+ for ( i = 1 ; i <= dy ; i++ )
+ {
+ y += yinc ;
+ cumul += dx ;
+
+ if ( cumul >= dy )
+ {
+ cumul -= dy ;
+ x += xinc ;
+ }
+
+ FB_DrawPixel(x, y);
+ }
+ }
+
+ return 0 ;
+}
+
+/*----------------------------------------------------------------------------
+ * External functions
+ *----------------------------------------------------------------------------*/
+
+/**
+ * \brief Configure the current frame buffer.
+ * Next frame buffer operations will take place in this frame buffer area.
+ * \param pBuffer 16 bit aligned sram buffer. PDC shall be able to access this
+ * memory area.
+ * \param ucWidth frame buffer width
+ * \param ucHeight frame buffer height
+ */
+extern void FB_SetFrameBuffer(LcdColor_t *pBuffer, uint8_t ucWidth, uint8_t ucHeight)
+{
+ /* Sanity check */
+ assert(pBuffer != NULL);
+
+ gpBuffer = pBuffer;
+ gucWidth = ucWidth;
+ gucHeight = ucHeight;
+}
+
+
+/**
+ * \brief Configure the current color that will be used in the next graphical operations.
+ *
+ * \param dwRgb24Bits 24 bit rgb color
+ */
+extern void FB_SetColor(uint32_t dwRgb24Bits)
+{
+ uint16_t i;
+// LcdColor_t wColor;
+
+// wColor = (dwRgb24Bits & 0xF80000) >> 8 |
+// (dwRgb24Bits & 0x00FC00) >> 5 |
+// (dwRgb24Bits & 0x0000F8) >> 3;
+
+ /* Fill the cache with selected color */
+ for (i = 0; i < FB_COLOR_CACHE_SIZE; ++i) {
+ gFbPixelCache[i] = dwRgb24Bits ;
+ }
+}
+/**
+ * \brief Draw a pixel on FB of given color.
+ *
+ * \param x X-coordinate of pixel.
+ * \param y Y-coordinate of pixel.
+ *
+ * \return 0 is operation is successful, 1 if pixel is out of the fb
+ */
+extern uint32_t FB_DrawPixel(
+ uint32_t dwX,
+ uint32_t dwY)
+{
+ if ((dwX >= gucWidth) || (dwY >= gucHeight)) {
+ return 1;
+ }
+ gpBuffer[dwX + dwY * gucWidth] = gFbPixelCache[0];
+
+ return 0;
+}
+
+/**
+ * \brief Write several pixels with the same color to FB.
+ *
+ * Pixel color is set by the LCD_SetColor() function.
+ * This function is optimized using an sram buffer to transfer block instead of
+ * individual pixels in order to limit the number of SPI interrupts.
+ * \param dwX1 X-coordinate of upper-left corner on LCD.
+ * \param dwY1 Y-coordinate of upper-left corner on LCD.
+ * \param dwX2 X-coordinate of lower-right corner on LCD.
+ * \param dwY2 Y-coordinate of lower-right corner on LCD.
+ *
+ * \return 0 if operation is successfull
+ */
+extern uint32_t FB_DrawFilledRectangle( uint32_t dwX1, uint32_t dwY1, uint32_t dwX2, uint32_t dwY2 )
+{
+ LcdColor_t *pFbBuffer, *pDestFbBuffer;
+ uint32_t dwY, blocks, bytes;
+
+ /* Swap coordinates if necessary */
+ CheckBoxCoordinates(&dwX1, &dwY1, &dwX2, &dwY2);
+
+ blocks = ((dwX2 - dwX1 + 1) / FB_COLOR_CACHE_SIZE);
+ bytes = ((dwX2 - dwX1 + 1) % FB_COLOR_CACHE_SIZE);
+
+ /* Each row is sent by block to benefit from memcpy optimizations */
+ pFbBuffer = &(gpBuffer[dwY1 * gucWidth + dwX1]);
+ for (dwY = dwY1; dwY <= dwY2; ++dwY) {
+ pDestFbBuffer = pFbBuffer;
+ while (blocks--) {
+ memcpy(pDestFbBuffer, gFbPixelCache, FB_COLOR_CACHE_SIZE * sizeof(LcdColor_t));
+ pDestFbBuffer += FB_COLOR_CACHE_SIZE;
+
+ }
+ memcpy(pDestFbBuffer, gFbPixelCache, bytes * sizeof(LcdColor_t));
+ pFbBuffer += gucWidth;
+ }
+
+ return 0;
+}
+
+/**
+ * \brief Write several pixels pre-formatted in a bufer to FB.
+ *
+ * \param dwX1 X-coordinate of upper-left corner on LCD.
+ * \param dwY1 Y-coordinate of upper-left corner on LCD.
+ * \param dwX2 X-coordinate of lower-right corner on LCD.
+ * \param dwY2 Y-coordinate of lower-right corner on LCD.
+ * \param pBuffer pixel buffer area (no constraint on alignment).
+ */
+extern uint32_t FB_DrawPicture( uint32_t dwX1, uint32_t dwY1, uint32_t dwX2, uint32_t dwY2, const void *pBuffer )
+{
+ LcdColor_t *pFbBuffer;
+ uint32_t dwY;
+
+ /* Swap coordinates if necessary */
+ CheckBoxCoordinates(&dwX1, &dwY1, &dwX2, &dwY2);
+
+ pFbBuffer = &(gpBuffer[dwY1 * gucWidth + dwX1]);
+ for (dwY = dwY1; dwY <= dwY2; ++dwY) {
+ memcpy(pFbBuffer, pBuffer, (dwX2 - dwX1 + 1) * sizeof(LcdColor_t));
+ pFbBuffer += gucWidth;
+ }
+
+ return 0 ;
+}
+
+/*
+ * \brief Draw a line on LCD, horizontal and vertical line are supported.
+ *
+ * \param dwX1 X-coordinate of line start.
+ * \param dwY1 Y-coordinate of line start.
+ * \param dwX2 X-coordinate of line end.
+ * \param dwY2 Y-coordinate of line end.
+ *
+ * \return 0 if operation is successful
+*/
+extern uint32_t FB_DrawLine ( uint32_t dwX1, uint32_t dwY1, uint32_t dwX2, uint32_t dwY2 )
+{
+ /* Optimize horizontal or vertical line drawing */
+ if (( dwY1 == dwY2 ) || (dwX1 == dwX2)) {
+ FB_DrawFilledRectangle( dwX1, dwY1, dwX2, dwY2 );
+ }
+ else {
+ DrawLineBresenham( dwX1, dwY1, dwX2, dwY2 ) ;
+ }
+
+ return 0 ;
+}
+
+/**
+ * \brief Draws a circle in FB, at the given coordinates.
+ *
+ * \param dwX X-coordinate of circle center.
+ * \param dwY Y-coordinate of circle center.
+ * \param dwR circle radius.
+ *
+ * \return 0 if operation is successful
+*/
+extern uint32_t FB_DrawCircle(
+ uint32_t dwX,
+ uint32_t dwY,
+ uint32_t dwR)
+{
+ int32_t d; /* Decision Variable */
+ uint32_t curX; /* Current X Value */
+ uint32_t curY; /* Current Y Value */
+
+ if (dwR == 0)
+ return 0;
+ d = 3 - (dwR << 1);
+ curX = 0;
+ curY = dwR;
+
+ while (curX <= curY)
+ {
+ FB_DrawPixel(dwX + curX, dwY + curY);
+ FB_DrawPixel(dwX + curX, dwY - curY);
+ FB_DrawPixel(dwX - curX, dwY + curY);
+ FB_DrawPixel(dwX - curX, dwY - curY);
+ FB_DrawPixel(dwX + curY, dwY + curX);
+ FB_DrawPixel(dwX + curY, dwY - curX);
+ FB_DrawPixel(dwX - curY, dwY + curX);
+ FB_DrawPixel(dwX - curY, dwY - curX);
+
+ if (d < 0) {
+ d += (curX << 2) + 6;
+ }
+ else {
+ d += ((curX - curY) << 2) + 10;
+ curY--;
+ }
+ curX++;
+ }
+ return 0;
+}
+
+/**
+ * \brief Draws a filled circle in FB, at the given coordinates.
+ *
+ * \param dwX X-coordinate of circle center.
+ * \param dwY Y-coordinate of circle center.
+ * \param dwR circle radius.
+ *
+ * \return 0 if operation is successful
+*/
+extern uint32_t FB_DrawFilledCircle( uint32_t dwX, uint32_t dwY, uint32_t dwRadius)
+{
+ signed int d ; // Decision Variable
+ uint32_t dwCurX ; // Current X Value
+ uint32_t dwCurY ; // Current Y Value
+ uint32_t dwXmin, dwYmin;
+
+ if (dwRadius == 0)
+ return 0;
+ d = 3 - (dwRadius << 1) ;
+ dwCurX = 0 ;
+ dwCurY = dwRadius ;
+
+ while ( dwCurX <= dwCurY )
+ {
+ dwXmin = (dwCurX > dwX) ? 0 : dwX-dwCurX;
+ dwYmin = (dwCurY > dwY) ? 0 : dwY-dwCurY;
+ FB_DrawFilledRectangle( dwXmin, dwYmin, dwX+dwCurX, dwYmin ) ;
+ FB_DrawFilledRectangle( dwXmin, dwY+dwCurY, dwX+dwCurX, dwY+dwCurY ) ;
+ dwXmin = (dwCurY > dwX) ? 0 : dwX-dwCurY;
+ dwYmin = (dwCurX > dwY) ? 0 : dwY-dwCurX;
+ FB_DrawFilledRectangle( dwXmin, dwYmin, dwX+dwCurY, dwYmin ) ;
+ FB_DrawFilledRectangle( dwXmin, dwY+dwCurX, dwX+dwCurY, dwY+dwCurX ) ;
+
+ if ( d < 0 )
+ {
+ d += (dwCurX << 2) + 6 ;
+ }
+ else
+ {
+ d += ((dwCurX - dwCurY) << 2) + 10;
+ dwCurY-- ;
+ }
+
+ dwCurX++ ;
+ }
+
+ return 0 ;
+}
+
+/**
+* Pixel color is set by the LCD_SetColor() function.
+* This function is optimized using an sram buffer to transfer block instead of
+* individual pixels in order to limit the number of SPI interrupts.
+* \param dwX1 X-coordinate of upper-left corner on LCD.
+* \param dwY1 Y-coordinate of upper-left corner on LCD.
+* \param dwX2 X-coordinate of lower-right corner on LCD.
+* \param dwY2 Y-coordinate of lower-right corner on LCD.
+*
+* \return 0 if operation is successfull
+*/
+extern uint32_t FB_DrawRectangle( uint32_t dwX1, uint32_t dwY1, uint32_t dwX2, uint32_t dwY2 )
+{
+ CheckBoxCoordinates(&dwX1, &dwY1, &dwX2, &dwY2);
+
+ FB_DrawFilledRectangle( dwX1, dwY1, dwX2, dwY1 ) ;
+ FB_DrawFilledRectangle( dwX1, dwY2, dwX2, dwY2 ) ;
+
+ FB_DrawFilledRectangle( dwX1, dwY1, dwX1, dwY2 ) ;
+ FB_DrawFilledRectangle( dwX2, dwY1, dwX2, dwY2 ) ;
+
+ return 0 ;
+}
+
+
+
diff --git a/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/hamming.c b/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/hamming.c
new file mode 100644
index 00000000..4a4fc0c4
--- /dev/null
+++ b/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/hamming.c
@@ -0,0 +1,339 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, 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.
+ * ----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * Headers
+ *----------------------------------------------------------------------------*/
+
+#include "board.h"
+
+/*----------------------------------------------------------------------------
+ * Internal function
+ *----------------------------------------------------------------------------*/
+
+/**
+ * Counts and return the number of bits set to '1' in the given byte.
+ * \param byte Byte to count.
+ */
+static uint8_t CountBitsInByte(uint8_t byte)
+{
+ uint8_t count = 0;
+
+ while (byte > 0)
+ {
+ if (byte & 1)
+ {
+ count++;
+ }
+ byte >>= 1;
+ }
+
+ return count;
+}
+
+/**
+ * Counts and return the number of bits set to '1' in the given hamming code.
+ * \param code Hamming code.
+ */
+static uint8_t CountBitsInCode256(uint8_t *code)
+{
+ return CountBitsInByte(code[0]) + CountBitsInByte(code[1]) + CountBitsInByte(code[2]);
+}
+
+/**
+ * Calculates the 22-bit hamming code for a 256-bytes block of data.
+ * \param data Data buffer to calculate code for.
+ * \param code Pointer to a buffer where the code should be stored.
+ */
+static void Compute256(const uint8_t *data, uint8_t *code)
+{
+ uint32_t i;
+ uint8_t columnSum = 0;
+ uint8_t evenLineCode = 0;
+ uint8_t oddLineCode = 0;
+ uint8_t evenColumnCode = 0;
+ uint8_t oddColumnCode = 0;
+
+ // Xor all bytes together to get the column sum;
+ // At the same time, calculate the even and odd line codes
+ for (i=0; i < 256; i++)
+ {
+ columnSum ^= data[i];
+
+ // If the xor sum of the byte is 0, then this byte has no incidence on
+ // the computed code; so check if the sum is 1.
+ if ((CountBitsInByte(data[i]) & 1) == 1)
+ {
+ // Parity groups are formed by forcing a particular index bit to 0
+ // (even) or 1 (odd).
+ // Example on one byte:
+ //
+ // bits (dec) 7 6 5 4 3 2 1 0
+ // (bin) 111 110 101 100 011 010 001 000
+ // '---'---'---'----------.
+ // |
+ // groups P4' ooooooooooooooo eeeeeeeeeeeeeee P4 |
+ // P2' ooooooo eeeeeee ooooooo eeeeeee P2 |
+ // P1' ooo eee ooo eee ooo eee ooo eee P1 |
+ // |
+ // We can see that: |
+ // - P4 -> bit 2 of index is 0 --------------------'
+ // - P4' -> bit 2 of index is 1.
+ // - P2 -> bit 1 of index if 0.
+ // - etc...
+ // We deduce that a bit position has an impact on all even Px if
+ // the log2(x)nth bit of its index is 0
+ // ex: log2(4) = 2, bit2 of the index must be 0 (-> 0 1 2 3)
+ // and on all odd Px' if the log2(x)nth bit of its index is 1
+ // ex: log2(2) = 1, bit1 of the index must be 1 (-> 0 1 4 5)
+ //
+ // As such, we calculate all the possible Px and Px' values at the
+ // same time in two variables, evenLineCode and oddLineCode, such as
+ // evenLineCode bits: P128 P64 P32 P16 P8 P4 P2 P1
+ // oddLineCode bits: P128' P64' P32' P16' P8' P4' P2' P1'
+ //
+ evenLineCode ^= (255 - i);
+ oddLineCode ^= i;
+ }
+ }
+
+ // At this point, we have the line parities, and the column sum. First, We
+ // must caculate the parity group values on the column sum.
+ for (i=0; i < 8; i++)
+ {
+ if (columnSum & 1)
+ {
+ evenColumnCode ^= (7 - i);
+ oddColumnCode ^= i;
+ }
+ columnSum >>= 1;
+ }
+
+ // Now, we must interleave the parity values, to obtain the following layout:
+ // Code[0] = Line1
+ // Code[1] = Line2
+ // Code[2] = Column
+ // Line = Px' Px P(x-1)- P(x-1) ...
+ // Column = P4' P4 P2' P2 P1' P1 PadBit PadBit
+ code[0] = 0;
+ code[1] = 0;
+ code[2] = 0;
+
+ for (i=0; i < 4; i++)
+ {
+ code[0] <<= 2;
+ code[1] <<= 2;
+ code[2] <<= 2;
+
+ // Line 1
+ if ((oddLineCode & 0x80) != 0)
+ {
+ code[0] |= 2;
+ }
+
+ if ((evenLineCode & 0x80) != 0)
+ {
+ code[0] |= 1;
+ }
+
+ // Line 2
+ if ((oddLineCode & 0x08) != 0)
+ {
+ code[1] |= 2;
+ }
+
+ if ((evenLineCode & 0x08) != 0)
+ {
+ code[1] |= 1;
+ }
+
+ // Column
+ if ((oddColumnCode & 0x04) != 0)
+ {
+ code[2] |= 2;
+ }
+
+ if ((evenColumnCode & 0x04) != 0)
+ {
+ code[2] |= 1;
+ }
+
+ oddLineCode <<= 1;
+ evenLineCode <<= 1;
+ oddColumnCode <<= 1;
+ evenColumnCode <<= 1;
+ }
+
+ // Invert codes (linux compatibility)
+ code[0] = (~(uint32_t)code[0]);
+ code[1] = (~(uint32_t)code[1]);
+ code[2] = (~(uint32_t)code[2]);
+
+ TRACE_DEBUG("Computed code = %02X %02X %02X\n\r",
+ code[0], code[1], code[2]);
+}
+
+/**
+ * Verifies and corrects a 256-bytes block of data using the given 22-bits
+ * hamming code.
+ *
+ * \param data Data buffer to check.
+ * \param originalCode Hamming code to use for verifying the data.
+ *
+ * \return 0 if there is no error, otherwise returns a HAMMING_ERROR code.
+ */
+static uint8_t Verify256( uint8_t* pucData, const uint8_t* pucOriginalCode )
+{
+ /* Calculate new code */
+ uint8_t computedCode[3] ;
+ uint8_t correctionCode[3] ;
+
+ Compute256( pucData, computedCode ) ;
+
+ /* Xor both codes together */
+ correctionCode[0] = computedCode[0] ^ pucOriginalCode[0] ;
+ correctionCode[1] = computedCode[1] ^ pucOriginalCode[1] ;
+ correctionCode[2] = computedCode[2] ^ pucOriginalCode[2] ;
+
+ TRACE_DEBUG( "Correction code = %02X %02X %02X\n\r", correctionCode[0], correctionCode[1], correctionCode[2] ) ;
+
+ // If all bytes are 0, there is no error
+ if ( (correctionCode[0] == 0) && (correctionCode[1] == 0) && (correctionCode[2] == 0) )
+ {
+ return 0 ;
+ }
+
+ /* If there is a single bit error, there are 11 bits set to 1 */
+ if ( CountBitsInCode256( correctionCode ) == 11 )
+ {
+ // Get byte and bit indexes
+ uint8_t byte ;
+ uint8_t bit ;
+
+ byte = correctionCode[0] & 0x80;
+ byte |= (correctionCode[0] << 1) & 0x40;
+ byte |= (correctionCode[0] << 2) & 0x20;
+ byte |= (correctionCode[0] << 3) & 0x10;
+
+ byte |= (correctionCode[1] >> 4) & 0x08;
+ byte |= (correctionCode[1] >> 3) & 0x04;
+ byte |= (correctionCode[1] >> 2) & 0x02;
+ byte |= (correctionCode[1] >> 1) & 0x01;
+
+ bit = (correctionCode[2] >> 5) & 0x04;
+ bit |= (correctionCode[2] >> 4) & 0x02;
+ bit |= (correctionCode[2] >> 3) & 0x01;
+
+ /* Correct bit */
+ TRACE_DEBUG("Correcting byte #%d at bit %d\n\r", byte, bit ) ;
+ pucData[byte] ^= (1 << bit) ;
+
+ return Hamming_ERROR_SINGLEBIT ;
+ }
+
+ /* Check if ECC has been corrupted */
+ if ( CountBitsInCode256( correctionCode ) == 1 )
+ {
+ return Hamming_ERROR_ECC ;
+ }
+ /* Otherwise, this is a multi-bit error */
+ else
+ {
+ return Hamming_ERROR_MULTIPLEBITS ;
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * Exported functions
+ *----------------------------------------------------------------------------*/
+
+/**
+ * Computes 3-bytes hamming codes for a data block whose size is multiple of
+ * 256 bytes. Each 256 bytes block gets its own code.
+ * \param data Data to compute code for.
+ * \param size Data size in bytes.
+ * \param code Codes buffer.
+ */
+void Hamming_Compute256x( const uint8_t *pucData, uint32_t dwSize, uint8_t* puCode )
+{
+ TRACE_DEBUG("Hamming_Compute256x()\n\r");
+
+ while ( dwSize > 0 )
+ {
+ Compute256( pucData, puCode ) ;
+
+ pucData += 256;
+ puCode += 3;
+ dwSize -= 256;
+ }
+}
+
+/**
+ * Verifies 3-bytes hamming codes for a data block whose size is multiple of
+ * 256 bytes. Each 256-bytes block is verified with its own code.
+ *
+ * \return 0 if the data is correct, Hamming_ERROR_SINGLEBIT if one or more
+ * block(s) have had a single bit corrected, or either Hamming_ERROR_ECC
+ * or Hamming_ERROR_MULTIPLEBITS.
+ *
+ * \param data Data buffer to verify.
+ * \param size Size of the data in bytes.
+ * \param code Original codes.
+ */
+uint8_t Hamming_Verify256x( uint8_t* pucData, uint32_t dwSize, const uint8_t* pucCode )
+{
+ uint8_t error ;
+ uint8_t result = 0 ;
+
+ TRACE_DEBUG( "Hamming_Verify256x()\n\r" ) ;
+
+ while ( dwSize > 0 )
+ {
+ error = Verify256( pucData, pucCode ) ;
+
+ if ( error == Hamming_ERROR_SINGLEBIT )
+ {
+ result = Hamming_ERROR_SINGLEBIT ;
+ }
+ else
+ {
+ if ( error )
+ {
+ return error ;
+ }
+ }
+
+ pucData += 256;
+ pucCode += 3;
+ dwSize -= 256;
+ }
+
+ return result ;
+}
+
diff --git a/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/ili9325.c b/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/ili9325.c
new file mode 100644
index 00000000..1b55e249
--- /dev/null
+++ b/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/ili9325.c
@@ -0,0 +1,907 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2010, 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.
+ * ----------------------------------------------------------------------------
+ */
+
+/**
+ * \file
+ *
+ * Implementation of ILI9325 driver.
+ *
+ */
+
+/*----------------------------------------------------------------------------
+ * Headers
+ *----------------------------------------------------------------------------*/
+#include "board.h"
+
+#include
+#include
+
+#ifdef BOARD_LCD_ILI9325
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ *----------------------------------------------------------------------------*/
+
+/* Pixel cache used to speed up communication */
+#define LCD_DATA_CACHE_SIZE BOARD_LCD_WIDTH
+static LcdColor_t gLcdPixelCache[LCD_DATA_CACHE_SIZE];
+
+/*----------------------------------------------------------------------------
+ * Export functions
+ *----------------------------------------------------------------------------*/
+
+
+/**
+ * \brief Write data to LCD Register.
+ *
+ * \param reg Register address.
+ * \param data Data to be written.
+ */
+static void LCD_WriteReg( uint8_t reg, uint16_t data )
+{
+ LCD_IR() = 0;
+ LCD_IR() = reg;
+ LCD_D() = (data >> 8) & 0xFF;
+ LCD_D() = data & 0xFF;
+}
+
+/**
+ * \brief Read data from LCD Register.
+ *
+ * \param reg Register address.
+ *
+ * \return Readed data.
+ */
+static uint16_t LCD_ReadReg( uint8_t reg )
+{
+ uint16_t value;
+
+ LCD_IR() = 0;
+ LCD_IR() = reg;
+
+ value = LCD_D();
+ value = (value << 8) | LCD_D();
+
+ return value;
+}
+
+
+/**
+ * \brief Prepare to write GRAM data.
+ */
+extern void LCD_WriteRAM_Prepare( void )
+{
+ LCD_IR() = 0 ;
+ LCD_IR() = ILI9325_R22H ; /* Write Data to GRAM (R22h) */
+}
+
+/**
+ * \brief Write data to LCD GRAM.
+ *
+ * \param color 24-bits RGB color.
+ */
+extern void LCD_WriteRAM( LcdColor_t dwColor )
+{
+ LCD_D() = ((dwColor >> 16) & 0xFF);
+ LCD_D() = ((dwColor >> 8) & 0xFF);
+ LCD_D() = (dwColor & 0xFF);
+}
+
+/**
+ * \brief Write mutiple data in buffer to LCD controller.
+ *
+ * \param pBuf data buffer.
+ * \param size size in pixels.
+ */
+static void LCD_WriteRAMBuffer(const LcdColor_t *pBuf, uint32_t size)
+{
+ uint32_t addr ;
+
+ for ( addr = 0 ; addr < size ; addr++ )
+ {
+ LCD_WriteRAM(pBuf[addr]);
+ }
+}
+
+/**
+ * \brief Prepare to read GRAM data.
+ */
+extern void LCD_ReadRAM_Prepare( void )
+{
+ LCD_IR() = 0 ;
+ LCD_IR() = ILI9325_R22H ; /* Write Data to GRAM (R22h) */
+}
+
+/**
+ * \brief Read data to LCD GRAM.
+ *
+ * \note Because pixel data LCD GRAM is 18-bits, so convertion to RGB 24-bits
+ * will cause low color bit lose.
+ *
+ * \return color 24-bits RGB color.
+ */
+extern uint32_t LCD_ReadRAM( void )
+{
+ uint8_t value[2];
+ uint32_t color;
+
+ value[0] = LCD_D(); /* dummy read */
+ value[1] = LCD_D(); /* dummy read */
+ value[0] = LCD_D(); /* data upper byte */
+ value[1] = LCD_D(); /* data lower byte */
+
+ /* Convert RGB565 to RGB888 */
+ /* For BGR format */
+ color = ((value[0] & 0xF8)) | /* R */
+ ((value[0] & 0x07) << 13) | ((value[1] & 0xE0) << 5) | /* G */
+ ((value[1] & 0x1F) << 19); /* B */
+ return color;
+}
+
+/*----------------------------------------------------------------------------
+ * Basic ILI9225 primitives
+ *----------------------------------------------------------------------------*/
+
+
+/**
+ * \brief Check Box coordinates. Return upper left and bottom right coordinates.
+ *
+ * \param pX1 X-coordinate of upper-left corner on LCD.
+ * \param pY1 Y-coordinate of upper-left corner on LCD.
+ * \param pX2 X-coordinate of lower-right corner on LCD.
+ * \param pY2 Y-coordinate of lower-right corner on LCD.
+ */
+static void CheckBoxCoordinates( uint32_t *pX1, uint32_t *pY1, uint32_t *pX2, uint32_t *pY2 )
+{
+ uint32_t dw;
+
+ if ( *pX1 >= BOARD_LCD_WIDTH )
+ {
+ *pX1 = BOARD_LCD_WIDTH-1 ;
+ }
+ if ( *pX2 >= BOARD_LCD_WIDTH )
+ {
+ *pX2 = BOARD_LCD_WIDTH-1 ;
+ }
+ if ( *pY1 >= BOARD_LCD_HEIGHT )
+ {
+ *pY1 = BOARD_LCD_HEIGHT-1 ;
+ }
+ if ( *pY2 >= BOARD_LCD_HEIGHT )
+ {
+ *pY2 = BOARD_LCD_HEIGHT-1 ;
+ }
+ if (*pX1 > *pX2)
+ {
+ dw = *pX1;
+ *pX1 = *pX2;
+ *pX2 = dw;
+ }
+ if (*pY1 > *pY2)
+ {
+ dw = *pY1;
+ *pY1 = *pY2;
+ *pY2 = dw;
+ }
+}
+
+/**
+ * \brief Initialize the LCD controller.
+ */
+extern uint32_t LCD_Initialize( void )
+{
+ uint16_t chipid ;
+
+ /* Check ILI9325 chipid */
+ chipid = LCD_ReadReg( ILI9325_R00H ) ; /* Driver Code Read (R00h) */
+ if ( chipid != ILI9325_DEVICE_CODE )
+ {
+ printf( "Read ILI9325 chip ID (0x%04x) error, skip initialization.\r\n", chipid ) ;
+ return 1 ;
+ }
+
+ /* Turn off LCD */
+ LCD_PowerDown() ;
+
+ /* Start initial sequence */
+ LCD_WriteReg(ILI9325_R10H, 0x0000); /* DSTB = LP = STB = 0 */
+ LCD_WriteReg(ILI9325_R00H, 0x0001); /* start internal OSC */
+ LCD_WriteReg(ILI9325_R01H, ILI9325_R01H_SS ) ; /* set SS and SM bit */
+ LCD_WriteReg(ILI9325_R02H, 0x0700); /* set 1 line inversion */
+ //LCD_WriteReg(ILI9325_R03H, 0xD030); /* set GRAM write direction and BGR=1. */
+ LCD_WriteReg(ILI9325_R04H, 0x0000); /* Resize register */
+ LCD_WriteReg(ILI9325_R08H, 0x0207); /* set the back porch and front porch */
+ LCD_WriteReg(ILI9325_R09H, 0x0000); /* set non-display area refresh cycle ISC[3:0] */
+ LCD_WriteReg(ILI9325_R0AH, 0x0000); /* FMARK function */
+ LCD_WriteReg(ILI9325_R0CH, 0x0000); /* RGB interface setting */
+ LCD_WriteReg(ILI9325_R0DH, 0x0000); /* Frame marker Position */
+ LCD_WriteReg(ILI9325_R0FH, 0x0000); /* RGB interface polarity */
+
+ /* Power on sequence */
+ LCD_WriteReg(ILI9325_R10H, 0x0000); /* SAP, BT[3:0], AP, DSTB, SLP, STB */
+ LCD_WriteReg(ILI9325_R11H, 0x0000); /* DC1[2:0], DC0[2:0], VC[2:0] */
+ LCD_WriteReg(ILI9325_R12H, 0x0000); /* VREG1OUT voltage */
+ LCD_WriteReg(ILI9325_R13H, 0x0000); /* VDV[4:0] for VCOM amplitude */
+ Wait( 200 ) ; /* Dis-charge capacitor power voltage */
+ LCD_WriteReg(ILI9325_R10H, 0x1290); /* SAP, BT[3:0], AP, DSTB, SLP, STB */
+ LCD_WriteReg(ILI9325_R11H, 0x0227); /* DC1[2:0], DC0[2:0], VC[2:0] */
+ Wait( 50 ) ;
+ LCD_WriteReg(ILI9325_R12H, 0x001B); /* Internal reference voltage= Vci; */
+ Wait( 50 ) ;
+ LCD_WriteReg(ILI9325_R13H, 0x1100); /* Set VDV[4:0] for VCOM amplitude */
+ LCD_WriteReg(ILI9325_R29H, 0x0019); /* Set VCM[5:0] for VCOMH */
+ LCD_WriteReg(ILI9325_R2BH, 0x000D); /* Set Frame Rate */
+ Wait( 50 ) ;
+
+ /* Adjust the Gamma Curve */
+ LCD_WriteReg(ILI9325_R30H, 0x0000);
+ LCD_WriteReg(ILI9325_R31H, 0x0204);
+ LCD_WriteReg(ILI9325_R32H, 0x0200);
+ LCD_WriteReg(ILI9325_R35H, 0x0007);
+ LCD_WriteReg(ILI9325_R36H, 0x1404);
+ LCD_WriteReg(ILI9325_R37H, 0x0705);
+ LCD_WriteReg(ILI9325_R38H, 0x0305);
+ LCD_WriteReg(ILI9325_R39H, 0x0707);
+ LCD_WriteReg(ILI9325_R3CH, 0x0701);
+ LCD_WriteReg(ILI9325_R3DH, 0x000e);
+
+ LCD_SetDisplayPortrait( 0 ) ;
+ /* Vertical Scrolling */
+ LCD_WriteReg( ILI9325_R61H, 0x0001 ) ;
+ LCD_WriteReg( ILI9325_R6AH, 0x0000 ) ;
+
+ /* Partial Display Control */
+ LCD_WriteReg(ILI9325_R80H, 0x0000);
+ LCD_WriteReg(ILI9325_R81H, 0x0000);
+ LCD_WriteReg(ILI9325_R82H, 0x0000);
+ LCD_WriteReg(ILI9325_R83H, 0x0000);
+ LCD_WriteReg(ILI9325_R84H, 0x0000);
+ LCD_WriteReg(ILI9325_R85H, 0x0000);
+
+ /* Panel Control */
+ LCD_WriteReg(ILI9325_R90H, 0x0010);
+ LCD_WriteReg(ILI9325_R92H, 0x0600);
+ LCD_WriteReg(ILI9325_R95H, 0x0110);
+
+ LCD_SetWindow( 0, 0, BOARD_LCD_WIDTH, BOARD_LCD_HEIGHT ) ;
+ LCD_SetCursor( 0, 0 ) ;
+
+ return 0 ;
+}
+
+/**
+ * \brief Turn on the LCD.
+ */
+extern void LCD_On( void )
+{
+ /* Display Control 1 (R07h) */
+ /* When BASEE = “1”, the base image is displayed. */
+ /* GON and DTE Set the output level of gate driver G1 ~ G320 : Normal Display */
+ /* D1=1 D0=1 BASEE=1: Base image display Operate */
+ LCD_WriteReg( ILI9325_R07H, ILI9325_R07H_BASEE
+ | ILI9325_R07H_GON | ILI9325_R07H_DTE
+ | ILI9325_R07H_D1 | ILI9325_R07H_D0 ) ;
+}
+
+
+/**
+ * \brief Turn off the LCD.
+ */
+extern void LCD_Off( void )
+{
+ /* Display Control 1 (R07h) */
+ /* When BASEE = “0”, no base image is displayed. */
+ /* When the display is turned off by setting D[1:0] = “00”, the ILI9325 internal display
+ operation is halted completely. */
+ /* PTDE1/0 = 0: turns off partial image. */
+ LCD_WriteReg( ILI9325_R07H, 0x00 ) ;
+}
+
+/**
+ * \brief Power down the LCD.
+ */
+extern void LCD_PowerDown( void )
+{
+ /* Display Control 1 (R07h) */
+ /* When BASEE = “0”, no base image is displayed. */
+ /* GON and DTE Set the output level of gate driver G1 ~ G320 : Normal Display */
+ /* D1=1 D0=1 BASEE=1: Base image display Operate */
+ LCD_WriteReg( ILI9325_R07H, ILI9325_R07H_GON | ILI9325_R07H_DTE
+ | ILI9325_R07H_D1 | ILI9325_R07H_D0 ) ;
+}
+
+/**
+ * \brief Convert 24 bit RGB color into 5-6-5 rgb color space.
+ *
+ * Initialize the LcdColor_t cache with the color pattern.
+ * \param x 24-bits RGB color.
+ * \return 0 for successfull operation.
+ */
+extern uint32_t LCD_SetColor( uint32_t dwRgb24Bits )
+{
+ uint32_t i ;
+
+ /* Fill the cache with selected color */
+ for ( i = 0 ; i < LCD_DATA_CACHE_SIZE ; ++i )
+ {
+ gLcdPixelCache[i] = dwRgb24Bits ;
+ }
+
+ return 0;
+}
+
+/**
+ * \brief Set cursor of LCD srceen.
+ *
+ * \param x X-coordinate of upper-left corner on LCD.
+ * \param y Y-coordinate of upper-left corner on LCD.
+ */
+extern void LCD_SetCursor( uint16_t x, uint16_t y )
+{
+ /* GRAM Horizontal/Vertical Address Set (R20h, R21h) */
+ LCD_WriteReg( ILI9325_R20H, x ) ; /* column */
+ LCD_WriteReg( ILI9325_R21H, y ) ; /* row */
+}
+
+extern void LCD_SetWindow( uint32_t dwX, uint32_t dwY, uint32_t dwWidth, uint32_t dwHeight )
+{
+ /* Horizontal and Vertical RAM Address Position (R50h, R51h, R52h, R53h) */
+
+ /* Set Horizontal Address Start Position */
+ LCD_WriteReg( ILI9325_R50H, (uint16_t)dwX ) ;
+
+ /* Set Horizontal Address End Position */
+ LCD_WriteReg( ILI9325_R51H, (uint16_t)dwX+dwWidth-1 ) ;
+
+ /* Set Vertical Address Start Position */
+ LCD_WriteReg( ILI9325_R52H, (uint16_t)dwY ) ;
+
+ /* Set Vertical Address End Position */
+ LCD_WriteReg( ILI9325_R53H, (uint16_t)dwY+dwHeight-1 ) ;
+}
+
+extern void LCD_SetDisplayLandscape( uint32_t dwRGB )
+{
+ uint16_t dwValue ;
+
+ /* When AM = “1”, the address is updated in vertical writing direction. */
+ /* DFM Set the mode of transferring data to the internal RAM when TRI = “1”. */
+ /* When TRI = “1”, data are transferred to the internal RAM in 8-bit x 3 transfers mode via the 8-bit interface. */
+ /* Use the high speed write mode (HWM=1) */
+ /* ORG = “1”: The original address “00000h” moves according to the I/D[1:0] setting. */
+ /* I/D[1:0] = 00 Horizontal : decrement Vertical : decrement, AM=0:Horizontal */
+ dwValue = ILI9325_R03H_AM | ILI9325_R03H_DFM | ILI9325_R03H_TRI | ILI9325_R03H_HWM | ILI9325_R03H_ORG ;
+
+ if ( dwRGB == 0 )
+ {
+ /* BGR=”1”: Swap the RGB data to BGR in writing into GRAM. */
+ dwValue |= ILI9325_R03H_BGR ;
+ }
+ LCD_WriteReg( ILI9325_R03H, dwValue ) ;
+
+ // LCD_WriteReg( ILI9325_R60H, (0x1d<<8)|0x00 ) ; /*Gate Scan Control */
+
+ LCD_SetWindow( 0, 0, BOARD_LCD_HEIGHT, BOARD_LCD_WIDTH ) ;
+}
+
+extern void LCD_SetDisplayPortrait( uint32_t dwRGB )
+{
+ uint16_t dwValue ;
+
+ /* Use the high speed write mode (HWM=1) */
+ /* When TRI = “1”, data are transferred to the internal RAM in 8-bit x 3 transfers mode via the 8-bit interface. */
+ /* DFM Set the mode of transferring data to the internal RAM when TRI = “1”. */
+ /* I/D[1:0] = 11 Horizontal : increment Vertical : increment, AM=0:Horizontal */
+ dwValue = ILI9325_R03H_HWM | ILI9325_R03H_TRI | ILI9325_R03H_DFM | ILI9325_R03H_ID1 | ILI9325_R03H_ID0 ;
+
+ if ( dwRGB == 0 )
+ {
+ /* BGR=”1”: Swap the RGB data to BGR in writing into GRAM. */
+ dwValue |= ILI9325_R03H_BGR ;
+ }
+ LCD_WriteReg( ILI9325_R03H, dwValue ) ;
+ /* Gate Scan Control (R60h, R61h, R6Ah) */
+ /* SCN[5:0] = 00 */
+ /* NL[5:0]: Sets the number of lines to drive the LCD at an interval of 8 lines. */
+ LCD_WriteReg( ILI9325_R60H, ILI9325_R60H_GS|(0x27<<8)|0x00 ) ;
+}
+
+
+extern void LCD_VerticalScroll( uint16_t wY )
+{
+ /* Gate Scan Control (R60h, R61h, R6Ah) */
+ /* Enables the grayscale inversion of the image by setting REV=1. */
+ /* VLE: Vertical scroll display enable bit */
+ LCD_WriteReg( ILI9325_R61H, 3 ) ;
+ LCD_WriteReg( ILI9325_R6AH, wY ) ;
+}
+
+
+extern void LCD_SetPartialImage1( uint32_t dwDisplayPos, uint32_t dwStart, uint32_t dwEnd )
+{
+ assert( dwStart <= dwEnd ) ;
+
+ /* Partial Image 1 Display Position (R80h) */
+ LCD_WriteReg( ILI9325_R80H, dwDisplayPos&0x1ff ) ;
+ /* Partial Image 1 RAM Start/End Address (R81h, R82h) */
+ LCD_WriteReg( ILI9325_R81H, dwStart&0x1ff ) ;
+ LCD_WriteReg( ILI9325_R82H, dwEnd&0x1ff ) ;
+}
+
+extern void LCD_SetPartialImage2( uint32_t dwDisplayPos, uint32_t dwStart, uint32_t dwEnd )
+{
+ assert( dwStart <= dwEnd ) ;
+
+ /* Partial Image 2 Display Position (R83h) */
+ LCD_WriteReg( ILI9325_R83H, dwDisplayPos&0x1ff ) ;
+ /* Partial Image 2 RAM Start/End Address (R84h, R85h) */
+ LCD_WriteReg( ILI9325_R84H, dwStart&0x1ff ) ;
+ LCD_WriteReg( ILI9325_R85H, dwEnd&0x1ff ) ;
+}
+
+/**
+ * \brief Draw a LcdColor_t on LCD of given color.
+ *
+ * \param x X-coordinate of pixel.
+ * \param y Y-coordinate of pixel.
+ */
+extern uint32_t LCD_DrawPixel( uint32_t x, uint32_t y )
+{
+ if( (x >= BOARD_LCD_WIDTH) || (y >= BOARD_LCD_HEIGHT) )
+ {
+ return 1;
+ }
+
+ /* Set cursor */
+ LCD_SetCursor( x, y );
+
+ /* Prepare to write in GRAM */
+ LCD_WriteRAM_Prepare();
+ LCD_WriteRAM( *gLcdPixelCache );
+
+ return 0;
+}
+
+
+
+extern void LCD_TestPattern( uint32_t dwRGB )
+{
+ uint32_t dwLine ;
+ uint32_t dw ;
+
+ LCD_SetWindow( 10, 10, 100, 20 ) ;
+ LCD_SetCursor( 10, 10 ) ;
+ LCD_WriteRAM_Prepare() ;
+
+ for ( dwLine=0 ; dwLine < 20 ; dwLine++ )
+ {
+ /* Draw White bar */
+ for ( dw=0 ; dw < 20 ; dw++ )
+ {
+ LCD_D() = 0xff ;
+ LCD_D() = 0xff ;
+ LCD_D() = 0xff ;
+ }
+ /* Draw Red bar */
+ for ( dw=0 ; dw < 20 ; dw++ )
+ {
+ if ( dwRGB == 0 )
+ {
+ LCD_D() = 0xff ;
+ LCD_D() = 0x00 ;
+ LCD_D() = 0x00 ;
+ }
+ else
+ {
+ LCD_D() = 0x00 ;
+ LCD_D() = 0x00 ;
+ LCD_D() = 0xff ;
+ }
+ }
+ /* Draw Green bar */
+ for ( dw=0 ; dw < 20 ; dw++ )
+ {
+ LCD_D() = 0x00 ;
+ LCD_D() = 0xff ;
+ LCD_D() = 0x00 ;
+ }
+ /* Draw Blue bar */
+ for ( dw=0 ; dw < 20 ; dw++ )
+ {
+ if ( dwRGB == 0 )
+ {
+ LCD_D() = 0x00 ;
+ LCD_D() = 0x00 ;
+ LCD_D() = 0xff ;
+ }
+ else
+ {
+ LCD_D() = 0xff ;
+ LCD_D() = 0x00 ;
+ LCD_D() = 0x00 ;
+ }
+ }
+ /* Draw Black bar */
+ for ( dw=0 ; dw < 20 ; dw++ )
+ {
+ LCD_D() = 0x00 ;
+ LCD_D() = 0x00 ;
+ LCD_D() = 0x00 ;
+ }
+ }
+
+ LCD_SetWindow( 0, 0, BOARD_LCD_WIDTH, BOARD_LCD_HEIGHT ) ;
+}
+
+
+/**
+ * \brief Write several pixels with the same color to LCD GRAM.
+ *
+ * LcdColor_t color is set by the LCD_SetColor() function.
+ * This function is optimized using an sram buffer to transfer block instead of
+ * individual pixels in order to limit the number of SPI interrupts.
+ * \param dwX1 X-coordinate of upper-left corner on LCD.
+ * \param dwY1 Y-coordinate of upper-left corner on LCD.
+ * \param dwX2 X-coordinate of lower-right corner on LCD.
+ * \param dwY2 Y-coordinate of lower-right corner on LCD.
+ */
+extern uint32_t LCD_DrawFilledRectangle( uint32_t dwX1, uint32_t dwY1, uint32_t dwX2, uint32_t dwY2 )
+{
+ uint32_t size, blocks;
+
+ /* Swap coordinates if necessary */
+ CheckBoxCoordinates(&dwX1, &dwY1, &dwX2, &dwY2);
+
+ /* Determine the refresh window area */
+ /* Horizontal and Vertical RAM Address Position (R50h, R51h, R52h, R53h) */
+ LCD_WriteReg(ILI9325_R50H, (uint16_t)dwX1);
+ LCD_WriteReg(ILI9325_R51H, (uint16_t)dwX2);
+ LCD_WriteReg(ILI9325_R52H, (uint16_t)dwY1);
+ LCD_WriteReg(ILI9325_R53H, (uint16_t)dwY2);
+
+ /* Set cursor */
+ LCD_SetCursor( dwX1, dwY1 );
+
+ /* Prepare to write in GRAM */
+ LCD_WriteRAM_Prepare();
+
+ size = (dwX2 - dwX1 + 1) * (dwY2 - dwY1 + 1);
+ /* Send pixels blocks => one SPI IT / block */
+ blocks = size / LCD_DATA_CACHE_SIZE;
+ while (blocks--)
+ {
+ LCD_WriteRAMBuffer(gLcdPixelCache, LCD_DATA_CACHE_SIZE);
+ }
+ /* Send remaining pixels */
+ LCD_WriteRAMBuffer(gLcdPixelCache, size % LCD_DATA_CACHE_SIZE);
+
+ /* Reset the refresh window area */
+ /* Horizontal and Vertical RAM Address Position (R50h, R51h, R52h, R53h) */
+ LCD_WriteReg(ILI9325_R50H, (uint16_t)0 ) ;
+ LCD_WriteReg(ILI9325_R51H, (uint16_t)BOARD_LCD_WIDTH - 1 ) ;
+ LCD_WriteReg(ILI9325_R52H, (uint16_t)0) ;
+ LCD_WriteReg(ILI9325_R53H, (uint16_t)BOARD_LCD_HEIGHT - 1 ) ;
+
+ return 0 ;
+}
+
+/**
+ * \brief Write several pixels pre-formatted in a bufer to LCD GRAM.
+ *
+ * \param dwX1 X-coordinate of upper-left corner on LCD.
+ * \param dwY1 Y-coordinate of upper-left corner on LCD.
+ * \param dwX2 X-coordinate of lower-right corner on LCD.
+ * \param dwY2 Y-coordinate of lower-right corner on LCD.
+ * \param pBuffer LcdColor_t buffer area.
+ */
+extern uint32_t LCD_DrawPicture( uint32_t dwX1, uint32_t dwY1, uint32_t dwX2, uint32_t dwY2, const LcdColor_t *pBuffer )
+{
+ uint32_t size, blocks;
+ LcdColor_t currentColor;
+
+ /* Swap coordinates if necessary */
+ CheckBoxCoordinates(&dwX1, &dwY1, &dwX2, &dwY2);
+
+ /* Determine the refresh window area */
+ /* Horizontal and Vertical RAM Address Position (R50h, R51h, R52h, R53h) */
+ LCD_WriteReg(ILI9325_R50H, (uint16_t)dwX1 ) ;
+ LCD_WriteReg(ILI9325_R51H, (uint16_t)dwX2 ) ;
+ LCD_WriteReg(ILI9325_R52H, (uint16_t)dwY1 ) ;
+ LCD_WriteReg(ILI9325_R53H, (uint16_t)dwY2 ) ;
+
+ /* Set cursor */
+ LCD_SetCursor( dwX1, dwY1 );
+
+ /* Prepare to write in GRAM */
+ LCD_WriteRAM_Prepare();
+
+ size = (dwX2 - dwX1 + 1) * (dwY2 - dwY1 + 1);
+
+ /* Check if the buffer is within the SRAM */
+ if ((IRAM_ADDR <= (uint32_t)pBuffer) && ((uint32_t)pBuffer < (IRAM_ADDR+IRAM_SIZE)))
+ {
+ LCD_WriteRAMBuffer(pBuffer, size);
+ }
+ /* If the buffer is not in SRAM, transfer it in SRAM first before transfer */
+ else
+ {
+ /* Use color buffer as a cache */
+ currentColor = gLcdPixelCache[0];
+ /* Send pixels blocks => one SPI IT / block */
+ blocks = size / LCD_DATA_CACHE_SIZE;
+ while (blocks--)
+ {
+ memcpy(gLcdPixelCache, pBuffer, LCD_DATA_CACHE_SIZE * sizeof(LcdColor_t));
+ LCD_WriteRAMBuffer(gLcdPixelCache, LCD_DATA_CACHE_SIZE);
+ pBuffer += LCD_DATA_CACHE_SIZE;
+ }
+ /* Send remaining pixels */
+ memcpy(gLcdPixelCache, pBuffer, (size % LCD_DATA_CACHE_SIZE) * sizeof(LcdColor_t));
+ LCD_WriteRAMBuffer(gLcdPixelCache, size % LCD_DATA_CACHE_SIZE);
+
+ /* Restore the color cache */
+ LCD_SetColor(currentColor);
+ }
+
+ /* Reset the refresh window area */
+ /* Horizontal and Vertical RAM Address Position (R50h, R51h, R52h, R53h) */
+ LCD_WriteReg(ILI9325_R50H, (uint16_t)0 ) ;
+ LCD_WriteReg(ILI9325_R51H, (uint16_t)BOARD_LCD_WIDTH - 1 ) ;
+ LCD_WriteReg(ILI9325_R52H, (uint16_t)0 ) ;
+ LCD_WriteReg(ILI9325_R53H, (uint16_t)BOARD_LCD_HEIGHT - 1 ) ;
+
+ return 0 ;
+}
+
+/*
+ * \brief Draw a line on LCD, which is not horizontal or vertical.
+ *
+ * \param x X-coordinate of line start.
+ * \param y Y-coordinate of line start.
+ * \param length line length.
+ * \param direction line direction: 0 - horizontal, 1 - vertical.
+ * \param color LcdColor_t color.
+ */
+static uint32_t DrawLineBresenham( uint32_t dwX1, uint32_t dwY1, uint32_t dwX2, uint32_t dwY2 )
+{
+ int dx, dy ;
+ int i ;
+ int xinc, yinc, cumul ;
+ int x, y ;
+
+ x = dwX1 ;
+ y = dwY1 ;
+ dx = dwX2 - dwX1 ;
+ dy = dwY2 - dwY1 ;
+
+ xinc = ( dx > 0 ) ? 1 : -1 ;
+ yinc = ( dy > 0 ) ? 1 : -1 ;
+ dx = ( dx > 0 ) ? dx : -dx ;
+ dy = ( dy > 0 ) ? dy : -dy ;
+
+ LCD_DrawPixel( x, y ) ;
+
+ if ( dx > dy )
+ {
+ cumul = dx / 2 ;
+ for ( i = 1 ; i <= dx ; i++ )
+ {
+ x += xinc ;
+ cumul += dy ;
+
+ if ( cumul >= dx )
+ {
+ cumul -= dx ;
+ y += yinc ;
+ }
+ LCD_DrawPixel( x, y ) ;
+ }
+ }
+ else
+ {
+ cumul = dy / 2 ;
+ for ( i = 1 ; i <= dy ; i++ )
+ {
+ y += yinc ;
+ cumul += dx ;
+
+ if ( cumul >= dy )
+ {
+ cumul -= dy ;
+ x += xinc ;
+ }
+
+ LCD_DrawPixel( x, y ) ;
+ }
+ }
+
+ return 0 ;
+}
+
+/*
+ * \brief Draw a line on LCD, horizontal and vertical line are supported.
+ *
+ * \param dwX1 X-coordinate of line start.
+ * \param dwY1 Y-coordinate of line start.
+ * \param dwX2 X-coordinate of line end.
+ * \param dwY2 Y-coordinate of line end.
+ */
+extern uint32_t LCD_DrawLine ( uint32_t dwX1, uint32_t dwY1, uint32_t dwX2, uint32_t dwY2 )
+{
+ /* Optimize horizontal or vertical line drawing */
+ if (( dwY1 == dwY2 ) || (dwX1 == dwX2))
+ {
+ LCD_DrawFilledRectangle( dwX1, dwY1, dwX2, dwY2 );
+ }
+ else
+ {
+ DrawLineBresenham( dwX1, dwY1, dwX2, dwY2 ) ;
+ }
+
+ return 0 ;
+}
+
+/**
+ * \brief Draws a circle on LCD, at the given coordinates.
+ *
+ * \param dwX X-coordinate of circle center.
+ * \param dwY Y-coordinate of circle center.
+ * \param dwR circle radius.
+*/
+extern uint32_t LCD_DrawCircle( uint32_t dwX, uint32_t dwY, uint32_t dwR )
+{
+ int32_t d; /* Decision Variable */
+ uint32_t curX; /* Current X Value */
+ uint32_t curY; /* Current Y Value */
+
+ if (dwR == 0)
+ {
+ return 0;
+ }
+ d = 3 - (dwR << 1);
+ curX = 0;
+ curY = dwR;
+
+ while (curX <= curY)
+ {
+ LCD_DrawPixel(dwX + curX, dwY + curY);
+ LCD_DrawPixel(dwX + curX, dwY - curY);
+ LCD_DrawPixel(dwX - curX, dwY + curY);
+ LCD_DrawPixel(dwX - curX, dwY - curY);
+ LCD_DrawPixel(dwX + curY, dwY + curX);
+ LCD_DrawPixel(dwX + curY, dwY - curX);
+ LCD_DrawPixel(dwX - curY, dwY + curX);
+ LCD_DrawPixel(dwX - curY, dwY - curX);
+
+ if (d < 0)
+ {
+ d += (curX << 2) + 6;
+ }
+ else
+ {
+ d += ((curX - curY) << 2) + 10;
+ curY--;
+ }
+ curX++;
+ }
+ return 0;
+}
+
+extern uint32_t LCD_DrawFilledCircle( uint32_t dwX, uint32_t dwY, uint32_t dwRadius)
+{
+ signed int d ; /* Decision Variable */
+ uint32_t dwCurX ; /* Current X Value */
+ uint32_t dwCurY ; /* Current Y Value */
+ uint32_t dwXmin, dwYmin;
+
+ if (dwRadius == 0)
+ {
+ return 0;
+ }
+ d = 3 - (dwRadius << 1) ;
+ dwCurX = 0 ;
+ dwCurY = dwRadius ;
+
+ while ( dwCurX <= dwCurY )
+ {
+ dwXmin = (dwCurX > dwX) ? 0 : dwX-dwCurX;
+ dwYmin = (dwCurY > dwY) ? 0 : dwY-dwCurY;
+ LCD_DrawFilledRectangle( dwXmin, dwYmin, dwX+dwCurX, dwYmin ) ;
+ LCD_DrawFilledRectangle( dwXmin, dwY+dwCurY, dwX+dwCurX, dwY+dwCurY ) ;
+ dwXmin = (dwCurY > dwX) ? 0 : dwX-dwCurY;
+ dwYmin = (dwCurX > dwY) ? 0 : dwY-dwCurX;
+ LCD_DrawFilledRectangle( dwXmin, dwYmin, dwX+dwCurY, dwYmin ) ;
+ LCD_DrawFilledRectangle( dwXmin, dwY+dwCurX, dwX+dwCurY, dwY+dwCurX ) ;
+
+ if ( d < 0 )
+ {
+ d += (dwCurX << 2) + 6 ;
+ }
+ else
+ {
+ d += ((dwCurX - dwCurY) << 2) + 10;
+ dwCurY-- ;
+ }
+
+ dwCurX++ ;
+ }
+
+ return 0 ;
+}
+
+extern uint32_t LCD_DrawRectangle( uint32_t dwX1, uint32_t dwY1, uint32_t dwX2, uint32_t dwY2 )
+{
+ CheckBoxCoordinates(&dwX1, &dwY1, &dwX2, &dwY2);
+
+ LCD_DrawFilledRectangle( dwX1, dwY1, dwX2, dwY1 ) ;
+ LCD_DrawFilledRectangle( dwX1, dwY2, dwX2, dwY2 ) ;
+
+ LCD_DrawFilledRectangle( dwX1, dwY1, dwX1, dwY2 ) ;
+ LCD_DrawFilledRectangle( dwX2, dwY1, dwX2, dwY2 ) ;
+
+ return 0 ;
+}
+
+
+/**
+ * \brief Set the backlight of the LCD (AAT3155).
+ *
+ * \param level Backlight brightness level [1..16], 1 means maximum brightness.
+ */
+extern void LCD_SetBacklight (uint32_t level)
+{
+ uint32_t i;
+ const Pin pPins[] = {BOARD_BACKLIGHT_PIN};
+
+ /* Ensure valid level */
+ level = (level < 1) ? 1 : level;
+ level = (level > 16) ? 16 : level;
+
+ /* Enable pins */
+ PIO_Configure(pPins, PIO_LISTSIZE(pPins));
+
+ /* Switch off backlight */
+ PIO_Clear(pPins);
+ i = 600 * (BOARD_MCK / 1000000); /* wait for at least 500us */
+ while(i--);
+
+ /* Set new backlight level */
+ for (i = 0; i < level; i++)
+ {
+ PIO_Clear(pPins);
+ PIO_Clear(pPins);
+ PIO_Clear(pPins);
+
+ PIO_Set(pPins);
+ PIO_Set(pPins);
+ PIO_Set(pPins);
+ }
+}
+
+#endif
diff --git a/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/iso7816_4.c b/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/iso7816_4.c
new file mode 100644
index 00000000..42560a0c
--- /dev/null
+++ b/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/iso7816_4.c
@@ -0,0 +1,611 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * 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:
+ *
+ * - 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
+ *
+ * ISO 7816 driver
+ *
+ * \section Usage
+ *
+ * Explanation on the usage of the code made available through the header file.
+ */
+
+/*------------------------------------------------------------------------------
+ * Headers
+ *------------------------------------------------------------------------------*/
+
+#include "board.h"
+
+/*------------------------------------------------------------------------------
+ * Definitions
+ *------------------------------------------------------------------------------*/
+/** Case for APDU commands*/
+#define CASE1 1
+#define CASE2 2
+#define CASE3 3
+
+/** Flip flop for send and receive char */
+#define USART_SEND 0
+#define USART_RCV 1
+
+#if !defined(BOARD_ISO7816_BASE_USART)
+ #define BOARD_ISO7816_BASE_USART USART1
+ #define BOARD_ISO7816_ID_USART ID_USART1
+#endif
+
+/*-----------------------------------------------------------------------------
+ * Internal variables
+ *-----------------------------------------------------------------------------*/
+/** Variable for state of send and receive froom USART */
+static uint8_t StateUsartGlobal = USART_RCV;
+/** Pin reset master card */
+static Pin st_pinIso7816RstMC;
+
+/*----------------------------------------------------------------------------
+ * Internal functions
+ *----------------------------------------------------------------------------*/
+
+/**
+ * Get a character from ISO7816
+ * \param pCharToReceive Pointer for store the received char
+ * \return 0: if timeout else status of US_CSR
+ */
+static uint32_t ISO7816_GetChar( uint8_t *pCharToReceive )
+{
+ uint32_t status;
+ uint32_t timeout=0;
+
+ if( StateUsartGlobal == USART_SEND ) {
+ while((BOARD_ISO7816_BASE_USART->US_CSR & US_CSR_TXEMPTY) == 0) {}
+ BOARD_ISO7816_BASE_USART->US_CR = US_CR_RSTSTA | US_CR_RSTIT | US_CR_RSTNACK;
+ StateUsartGlobal = USART_RCV;
+ }
+
+ /* Wait USART ready for reception */
+ while( ((BOARD_ISO7816_BASE_USART->US_CSR & US_CSR_RXRDY) == 0) ) {
+ if(timeout++ > 12000 * (BOARD_MCK/1000000)) {
+ TRACE_DEBUG("TimeOut\n\r");
+ return( 0 );
+ }
+ }
+
+ TRACE_DEBUG("T: %u\n\r", timeout);
+
+
+ /* At least one complete character has been received and US_RHR has not yet been read. */
+
+ /* Get a char */
+ *pCharToReceive = ((BOARD_ISO7816_BASE_USART->US_RHR) & 0xFF);
+
+ status = (BOARD_ISO7816_BASE_USART->US_CSR&(US_CSR_OVRE|US_CSR_FRAME|
+ US_CSR_PARE|US_CSR_TIMEOUT|US_CSR_NACK|
+ (1<<10)));
+
+ if (status != 0 ) {
+ /* TRACE_DEBUG("R:0x%X\n\r", status); */
+ TRACE_DEBUG("R:0x%X\n\r", BOARD_ISO7816_BASE_USART->US_CSR);
+ TRACE_DEBUG("Nb:0x%X\n\r", BOARD_ISO7816_BASE_USART->US_NER );
+ BOARD_ISO7816_BASE_USART->US_CR = US_CR_RSTSTA;
+ }
+
+ /* Return status */
+ return( status );
+}
+
+
+/**
+ * Send a char to ISO7816
+ * \param CharToSend char to be send
+ * \return status of US_CSR
+ */
+static uint32_t ISO7816_SendChar( uint8_t CharToSend )
+{
+ uint32_t status;
+
+ if( StateUsartGlobal == USART_RCV ) {
+ BOARD_ISO7816_BASE_USART->US_CR = US_CR_RSTSTA | US_CR_RSTIT | US_CR_RSTNACK;
+ StateUsartGlobal = USART_SEND;
+ }
+
+ /* Wait USART ready for transmit */
+ while((BOARD_ISO7816_BASE_USART->US_CSR & US_CSR_TXRDY) == 0) {}
+ /* There is no character in the US_THR */
+
+ /* Transmit a char */
+ BOARD_ISO7816_BASE_USART->US_THR = CharToSend;
+
+ status = (BOARD_ISO7816_BASE_USART->US_CSR&(US_CSR_OVRE|US_CSR_FRAME|
+ US_CSR_PARE|US_CSR_TIMEOUT|US_CSR_NACK|
+ (1<<10)));
+
+ if (status != 0 ) {
+ TRACE_DEBUG("E:0x%X\n\r", BOARD_ISO7816_BASE_USART->US_CSR);
+ TRACE_DEBUG("Nb:0x%X\n\r", BOARD_ISO7816_BASE_USART->US_NER );
+ BOARD_ISO7816_BASE_USART->US_CR = US_CR_RSTSTA;
+ }
+
+ /* Return status */
+ return( status );
+}
+
+
+/**
+ * Iso 7816 ICC power on
+ */
+static void ISO7816_IccPowerOn( void )
+{
+ /* Set RESET Master Card */
+ PIO_Set(&st_pinIso7816RstMC);
+}
+
+/*----------------------------------------------------------------------------
+ * Exported functions
+ *----------------------------------------------------------------------------*/
+
+/**
+ * Iso 7816 ICC power off
+ */
+void ISO7816_IccPowerOff( void )
+{
+ /* Clear RESET Master Card */
+ PIO_Clear(&st_pinIso7816RstMC);
+}
+
+/**
+ * Transfert Block TPDU T=0
+ * \param pAPDU APDU buffer
+ * \param pMessage Message buffer
+ * \param wLength Block length
+ * \return Message index
+ */
+uint16_t ISO7816_XfrBlockTPDU_T0(const uint8_t *pAPDU,
+ uint8_t *pMessage,
+ uint16_t wLength )
+{
+ uint16_t NeNc;
+ uint16_t indexApdu = 4;
+ uint16_t indexMessage = 0;
+ uint8_t SW1 = 0;
+ uint8_t procByte;
+ uint8_t cmdCase;
+
+ TRACE_DEBUG("pAPDU[0]=0x%X\n\r",pAPDU[0]);
+ TRACE_DEBUG("pAPDU[1]=0x%X\n\r",pAPDU[1]);
+ TRACE_DEBUG("pAPDU[2]=0x%X\n\r",pAPDU[2]);
+ TRACE_DEBUG("pAPDU[3]=0x%X\n\r",pAPDU[3]);
+ TRACE_DEBUG("pAPDU[4]=0x%X\n\r",pAPDU[4]);
+ TRACE_DEBUG("pAPDU[5]=0x%X\n\r",pAPDU[5]);
+ TRACE_DEBUG("wlength=%d\n\r",wLength);
+
+ ISO7816_SendChar( pAPDU[0] ); /* CLA */
+ ISO7816_SendChar( pAPDU[1] ); /* INS */
+ ISO7816_SendChar( pAPDU[2] ); /* P1 */
+ ISO7816_SendChar( pAPDU[3] ); /* P2 */
+ ISO7816_SendChar( pAPDU[4] ); /* P3 */
+
+ /* Handle the four structures of command APDU */
+ indexApdu = 4;
+
+ if( wLength == 4 ) {
+ cmdCase = CASE1;
+ NeNc = 0;
+ }
+ else if( wLength == 5) {
+ cmdCase = CASE2;
+ NeNc = pAPDU[4]; /* C5 */
+ if (NeNc == 0) {
+ NeNc = 256;
+ }
+ }
+ else if( wLength == 6) {
+ NeNc = pAPDU[4]; /* C5 */
+ cmdCase = CASE3;
+ }
+ else if( wLength == 7) {
+ NeNc = pAPDU[4]; /* C5 */
+ if( NeNc == 0 ) {
+ cmdCase = CASE2;
+ NeNc = (pAPDU[5]<<8)+pAPDU[6];
+ }
+ else {
+ cmdCase = CASE3;
+ }
+ }
+ else {
+ NeNc = pAPDU[4]; /* C5 */
+ if( NeNc == 0 ) {
+ cmdCase = CASE3;
+ NeNc = (pAPDU[5]<<8)+pAPDU[6];
+ }
+ else {
+ cmdCase = CASE3;
+ }
+ }
+
+ TRACE_DEBUG("CASE=0x%X NeNc=0x%X\n\r", cmdCase, NeNc);
+
+ /* Handle Procedure Bytes */
+ do {
+ ISO7816_GetChar(&procByte);
+ /* Handle NULL */
+ if ( procByte == ISO_NULL_VAL ) {
+ TRACE_DEBUG("INS\n\r");
+ continue;
+ }
+ /* Handle SW1 */
+ else if ( ((procByte & 0xF0) ==0x60) || ((procByte & 0xF0) ==0x90) ) {
+ TRACE_DEBUG("SW1\n\r");
+ SW1 = 1;
+ }
+ /* Handle INS */
+ else if ( pAPDU[1] == procByte) {
+ TRACE_DEBUG("HdlINS\n\r");
+ if (cmdCase == CASE2) {
+ /* receive data from card */
+ do {
+ ISO7816_GetChar(&pMessage[indexMessage++]);
+ } while( 0 != --NeNc );
+ }
+ else {
+ /* Send data */
+ do {
+ ISO7816_SendChar(pAPDU[indexApdu++]);
+ } while( 0 != --NeNc );
+ }
+ }
+ /* Handle INS ^ 0xff */
+ else if ( pAPDU[1] == (procByte ^ 0xff)) {
+ TRACE_DEBUG("HdlINS+\n\r");
+ if (cmdCase == CASE2) {
+ /* receive data from card */
+ ISO7816_GetChar(&pMessage[indexMessage++]);
+ }
+ else {
+ ISO7816_SendChar(pAPDU[indexApdu++]);
+ }
+ NeNc--;
+ }
+ else {
+ /* ?? */
+ TRACE_DEBUG("procByte=0x%X\n\r", procByte);
+ break;
+ }
+ } while (NeNc != 0);
+
+ /* Status Bytes */
+ if (SW1 == 0) {
+ ISO7816_GetChar(&pMessage[indexMessage++]); /* SW1 */
+ }
+ else {
+ pMessage[indexMessage++] = procByte;
+ }
+ ISO7816_GetChar(&pMessage[indexMessage++]); /* SW2 */
+
+ return( indexMessage );
+
+}
+
+/**
+ * Escape ISO7816
+ */
+void ISO7816_Escape( void )
+{
+ TRACE_DEBUG("For user, if needed\n\r");
+}
+
+/**
+ * Restart clock ISO7816
+ */
+void ISO7816_RestartClock( void )
+{
+ TRACE_DEBUG("ISO7816_RestartClock\n\r");
+ BOARD_ISO7816_BASE_USART->US_BRGR = 13;
+}
+
+/**
+ * Stop clock ISO7816
+ */
+void ISO7816_StopClock( void )
+{
+ TRACE_DEBUG("ISO7816_StopClock\n\r");
+ BOARD_ISO7816_BASE_USART->US_BRGR = 0;
+}
+
+/**
+ * T0 APDU
+ */
+void ISO7816_toAPDU( void )
+{
+ TRACE_DEBUG("ISO7816_toAPDU\n\r");
+ TRACE_DEBUG("Not supported at this time\n\r");
+}
+
+/**
+ * Answer To Reset (ATR)
+ * \param pAtr ATR buffer
+ * \param pLength Pointer for store the ATR length
+ */
+void ISO7816_Datablock_ATR( uint8_t* pAtr, uint8_t* pLength )
+{
+ uint32_t i;
+ uint32_t j;
+ uint32_t y;
+
+ *pLength = 0;
+
+ /* Read ATR TS */
+ ISO7816_GetChar(&pAtr[0]);
+ /* Read ATR T0 */
+ ISO7816_GetChar(&pAtr[1]);
+ y = pAtr[1] & 0xF0;
+ i = 2;
+
+ /* Read ATR Ti */
+ while (y) {
+
+ if (y & 0x10) { /* TA[i] */
+ ISO7816_GetChar(&pAtr[i++]);
+ }
+ if (y & 0x20) { /* TB[i] */
+ ISO7816_GetChar(&pAtr[i++]);
+ }
+ if (y & 0x40) { /* TC[i] */
+ ISO7816_GetChar(&pAtr[i++]);
+ }
+ if (y & 0x80) { /* TD[i] */
+ ISO7816_GetChar(&pAtr[i]);
+ y = pAtr[i++] & 0xF0;
+ }
+ else {
+ y = 0;
+ }
+ }
+
+ /* Historical Bytes */
+ y = pAtr[1] & 0x0F;
+ for( j=0; j < y; j++ ) {
+ ISO7816_GetChar(&pAtr[i++]);
+ }
+
+ *pLength = i;
+
+}
+
+/**
+ * Set data rate and clock frequency
+ * \param dwClockFrequency ICC clock frequency in KHz.
+ * \param dwDataRate ICC data rate in bpd
+ */
+void ISO7816_SetDataRateandClockFrequency( uint32_t dwClockFrequency, uint32_t dwDataRate )
+{
+ uint8_t ClockFrequency;
+
+ /* Define the baud rate divisor register */
+ /* CD = MCK / SCK */
+ /* SCK = FIDI x BAUD = 372 x 9600 */
+ /* BOARD_MCK */
+ /* CD = MCK/(FIDI x BAUD) = 48000000 / (372x9600) = 13 */
+ BOARD_ISO7816_BASE_USART->US_BRGR = BOARD_MCK / (dwClockFrequency*1000);
+
+ ClockFrequency = BOARD_MCK / BOARD_ISO7816_BASE_USART->US_BRGR;
+
+ BOARD_ISO7816_BASE_USART->US_FIDI = (ClockFrequency)/dwDataRate;
+
+}
+
+/**
+ * Pin status for ISO7816 RESET
+ * \return 1 if the Pin RstMC is high; otherwise 0.
+ */
+uint8_t ISO7816_StatusReset( void )
+{
+ return PIO_Get(&st_pinIso7816RstMC);
+}
+
+/**
+ * cold reset
+ */
+void ISO7816_cold_reset( void )
+{
+ volatile uint32_t i;
+
+ /* tb: wait 400 cycles*/
+ for( i=0; i<(120*(BOARD_MCK/1000000)); i++ ) {
+ }
+
+ BOARD_ISO7816_BASE_USART->US_RHR;
+ BOARD_ISO7816_BASE_USART->US_CR = US_CR_RSTSTA | US_CR_RSTIT | US_CR_RSTNACK;
+
+ ISO7816_IccPowerOn();
+}
+
+/**
+ * Warm reset
+ */
+void ISO7816_warm_reset( void )
+{
+ volatile uint32_t i;
+
+ ISO7816_IccPowerOff();
+
+ /* tb: wait 400 cycles */
+ for( i=0; i<(120*(BOARD_MCK/1000000)); i++ ) {
+ }
+
+ BOARD_ISO7816_BASE_USART->US_RHR;
+ BOARD_ISO7816_BASE_USART->US_CR = US_CR_RSTSTA | US_CR_RSTIT | US_CR_RSTNACK;
+
+ ISO7816_IccPowerOn();
+}
+
+/**
+ * Decode ATR trace
+ * \param pAtr pointer on ATR buffer
+ */
+void ISO7816_Decode_ATR( uint8_t* pAtr )
+{
+ uint32_t i;
+ uint32_t j;
+ uint32_t y;
+ uint8_t offset;
+
+ printf("\n\r");
+ printf("ATR: Answer To Reset:\n\r");
+ printf("TS = 0x%X Initial character ",pAtr[0]);
+ if( pAtr[0] == 0x3B ) {
+
+ printf("Direct Convention\n\r");
+ }
+ else {
+ if( pAtr[0] == 0x3F ) {
+
+ printf("Inverse Convention\n\r");
+ }
+ else {
+ printf("BAD Convention\n\r");
+ }
+ }
+
+ printf("T0 = 0x%X Format caracter\n\r",pAtr[1]);
+ printf(" Number of historical bytes: K = %d\n\r", pAtr[1]&0x0F);
+ printf(" Presence further interface byte:\n\r");
+ if( pAtr[1]&0x80 ) {
+ printf("TA ");
+ }
+ if( pAtr[1]&0x40 ) {
+ printf("TB ");
+ }
+ if( pAtr[1]&0x20 ) {
+ printf("TC ");
+ }
+ if( pAtr[1]&0x10 ) {
+ printf("TD ");
+ }
+ if( pAtr[1] != 0 ) {
+ printf(" present\n\r");
+ }
+
+ i = 2;
+ y = pAtr[1] & 0xF0;
+
+ /* Read ATR Ti */
+ offset = 1;
+ while (y) {
+
+ if (y & 0x10) { /* TA[i] */
+ printf("TA[%d] = 0x%X ", offset, pAtr[i]);
+ if( offset == 1 ) {
+ printf("FI = %d ", (pAtr[i]>>8));
+ printf("DI = %d", (pAtr[i]&0x0F));
+ }
+ printf("\n\r");
+ i++;
+ }
+ if (y & 0x20) { /* TB[i] */
+ printf("TB[%d] = 0x%X\n\r", offset, pAtr[i]);
+ i++;
+ }
+ if (y & 0x40) { /* TC[i] */
+ printf("TC[%d] = 0x%X ", offset, pAtr[i]);
+ if( offset == 1 ) {
+ printf("Extra Guard Time: N = %d", pAtr[i]);
+ }
+ printf("\n\r");
+ i++;
+ }
+ if (y & 0x80) { /* TD[i] */
+ printf("TD[%d] = 0x%X\n\r", offset, pAtr[i]);
+ y = pAtr[i++] & 0xF0;
+ }
+ else {
+ y = 0;
+ }
+ offset++;
+ }
+
+ /* Historical Bytes */
+ printf("Historical bytes:\n\r");
+ y = pAtr[1] & 0x0F;
+ for( j=0; j < y; j++ ) {
+
+ printf(" 0x%X", pAtr[i]);
+ if( (pAtr[i] > 0x21) && (pAtr[i] < 0x7D) ) { /* ASCII */
+ printf("(%c) ", pAtr[i]);
+ }
+ i++;
+ }
+ printf("\n\r\n\r");
+
+}
+
+/** Initializes a ISO driver
+ * \param pPinIso7816RstMC Pin ISO 7816 Rst MC
+ */
+void ISO7816_Init( const Pin pPinIso7816RstMC )
+{
+ TRACE_DEBUG("ISO_Init\n\r");
+
+ /* Pin ISO7816 initialize */
+ st_pinIso7816RstMC = pPinIso7816RstMC;
+
+ USART_Configure( BOARD_ISO7816_BASE_USART,
+ US_MR_USART_MODE_IS07816_T_0
+ | US_MR_USCLKS_MCK
+ | US_MR_NBSTOP_1_BIT
+ | US_MR_PAR_EVEN
+ | US_MR_CHRL_8_BIT
+ | US_MR_CLKO
+ | (3<<24), /* MAX_ITERATION */
+ 1,
+ 0);
+
+ /* Configure USART */
+ PMC_EnablePeripheral(BOARD_ISO7816_ID_USART);
+ /* Disable interrupts */
+ BOARD_ISO7816_BASE_USART->US_IDR = (uint32_t) -1;
+
+ BOARD_ISO7816_BASE_USART->US_FIDI = 372; /* by default */
+ /* Define the baud rate divisor register */
+ /* CD = MCK / SCK */
+ /* SCK = FIDI x BAUD = 372 x 9600 */
+ /* BOARD_MCK */
+ /* CD = MCK/(FIDI x BAUD) = 48000000 / (372x9600) = 13 */
+ BOARD_ISO7816_BASE_USART->US_BRGR = BOARD_MCK / (372*9600);
+
+ /* Write the Timeguard Register */
+ BOARD_ISO7816_BASE_USART->US_TTGR = 5;
+
+ USART_SetTransmitterEnabled(BOARD_ISO7816_BASE_USART, 1);
+ USART_SetReceiverEnabled(BOARD_ISO7816_BASE_USART, 1);
+
+}
+
diff --git a/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/lcd_draw.c b/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/lcd_draw.c
new file mode 100644
index 00000000..2756365b
--- /dev/null
+++ b/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/lcd_draw.c
@@ -0,0 +1,405 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * 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:
+ *
+ * - 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 draw function on LCD, Include draw text, image
+ * and basic shapes (line, rectangle, circle).
+ *
+ */
+
+/*----------------------------------------------------------------------------
+ * Headers
+ *----------------------------------------------------------------------------*/
+
+#include "board.h"
+
+#include
+#include
+#include
+
+/*----------------------------------------------------------------------------
+ * Exported functions
+ *----------------------------------------------------------------------------*/
+
+/**
+ * \brief Fills the given LCD buffer with a particular color.
+ *
+ * \param color Fill color.
+ */
+void LCDD_Fill( uint32_t dwColor )
+{
+ uint32_t dw ;
+
+ LCD_SetCursor( 0, 0 ) ;
+ LCD_WriteRAM_Prepare() ;
+
+ for ( dw = BOARD_LCD_WIDTH * BOARD_LCD_HEIGHT; dw > 0; dw-- )
+ {
+ LCD_WriteRAM( dwColor ) ;
+ }
+}
+
+/**
+ * \brief Draw a pixel on LCD of given color.
+ *
+ * \param x X-coordinate of pixel.
+ * \param y Y-coordinate of pixel.
+ * \param color Pixel color.
+ */
+extern void LCDD_DrawPixel( uint32_t x, uint32_t y, uint32_t color )
+{
+ LCD_SetCursor( x, y ) ;
+ LCD_WriteRAM_Prepare() ;
+ LCD_WriteRAM( color ) ;
+}
+
+/**
+ * \brief Read a pixel from LCD.
+ *
+ * \param x X-coordinate of pixel.
+ * \param y Y-coordinate of pixel.
+ *
+ * \return color Readed pixel color.
+ */
+extern uint32_t LCDD_ReadPixel( uint32_t x, uint32_t y )
+{
+ uint32_t color;
+
+ LCD_SetCursor(x, y);
+ LCD_ReadRAM_Prepare();
+ color = LCD_ReadRAM();
+
+ return color;
+}
+
+/*
+ * \brief Draw a line on LCD, horizontal and vertical line are supported.
+ *
+ * \param x X-coordinate of line start.
+ * \param y Y-coordinate of line start.
+ * \param length line length.
+ * \param direction line direction: 0 - horizontal, 1 - vertical.
+ * \param color Pixel color.
+ */
+extern void LCDD_DrawLine( uint32_t x, uint32_t y, uint32_t length, uint32_t direction, uint32_t color )
+{
+ uint32_t i = 0 ;
+
+ LCD_SetCursor( x, y ) ;
+
+ if ( direction == DIRECTION_HLINE )
+ {
+ LCD_WriteRAM_Prepare() ;
+ for ( i = 0; i < length; i++ )
+ {
+ LCD_WriteRAM( color ) ;
+ }
+ }
+ else
+ {
+ for ( i = 0; i < length; i++ )
+ {
+ LCD_WriteRAM_Prepare() ;
+ LCD_WriteRAM( color ) ;
+ y++ ;
+ LCD_SetCursor( x, y ) ;
+ }
+ }
+}
+
+/*
+ * \brief Draws a rectangle on LCD, at the given coordinates.
+ *
+ * \param x X-coordinate of upper-left rectangle corner.
+ * \param y Y-coordinate of upper-left rectangle corner.
+ * \param width Rectangle width in pixels.
+ * \param height Rectangle height in pixels.
+ * \param color Rectangle color.
+ */
+extern void LCDD_DrawRectangle( uint32_t x, uint32_t y, uint32_t width, uint32_t height, uint32_t color )
+{
+ LCDD_DrawLine(x, y, width, DIRECTION_HLINE, color);
+ LCDD_DrawLine(x, (y + height), width, DIRECTION_HLINE, color);
+
+ LCDD_DrawLine(x, y, height, DIRECTION_VLINE, color);
+ LCDD_DrawLine((x + width), y, height, DIRECTION_VLINE, color);
+}
+
+/*
+ * \brief Draws a rectangle with fill inside on LCD, at the given coordinates.
+ *
+ * \param x X-coordinate of upper-left rectangle corner.
+ * \param y Y-coordinate of upper-left rectangle corner.
+ * \param width Rectangle width in pixels.
+ * \param height Rectangle height in pixels.
+ * \param color Rectangle color.
+ */
+extern void LCDD_DrawRectangleWithFill( uint32_t dwX, uint32_t dwY, uint32_t dwWidth, uint32_t dwHeight, uint32_t dwColor )
+{
+ uint32_t i ;
+
+ LCD_SetWindow( dwX, dwY, dwWidth, dwHeight ) ;
+ LCD_SetCursor( dwX, dwY ) ;
+ LCD_WriteRAM_Prepare() ;
+
+ for ( i = dwWidth * dwHeight; i > 0; i-- )
+ {
+ LCD_WriteRAM( dwColor ) ;
+ }
+ LCD_SetWindow( 0, 0, BOARD_LCD_WIDTH, BOARD_LCD_HEIGHT ) ;
+ LCD_SetCursor( 0, 0 ) ;
+}
+
+/**
+ * \brief Draws a circle on LCD, at the given coordinates.
+ *
+ * \param x X-coordinate of circle center.
+ * \param y Y-coordinate of circle center.
+ * \param r circle radius.
+ * \param color circle color.
+ */
+extern void LCDD_DrawCircle( uint32_t x, uint32_t y, uint32_t r, uint32_t color )
+{
+ signed int d; /* Decision Variable */
+ uint32_t curX; /* Current X Value */
+ uint32_t curY; /* Current Y Value */
+
+ d = 3 - (r << 1);
+ curX = 0;
+ curY = r;
+
+ while (curX <= curY)
+ {
+ LCDD_DrawPixel(x + curX, y + curY, color);
+ LCDD_DrawPixel(x + curX, y - curY, color);
+ LCDD_DrawPixel(x - curX, y + curY, color);
+ LCDD_DrawPixel(x - curX, y - curY, color);
+ LCDD_DrawPixel(x + curY, y + curX, color);
+ LCDD_DrawPixel(x + curY, y - curX, color);
+ LCDD_DrawPixel(x - curY, y + curX, color);
+ LCDD_DrawPixel(x - curY, y - curX, color);
+
+ if (d < 0) {
+ d += (curX << 2) + 6;
+ }
+ else {
+ d += ((curX - curY) << 2) + 10;
+ curY--;
+ }
+ curX++;
+ }
+}
+
+/**
+ * \brief Draws a string inside a LCD buffer, at the given coordinates. Line breaks
+ * will be honored.
+ *
+ * \param x X-coordinate of string top-left corner.
+ * \param y Y-coordinate of string top-left corner.
+ * \param pString String to display.
+ * \param color String color.
+ */
+extern void LCDD_DrawString( uint32_t x, uint32_t y, const uint8_t *pString, uint32_t color )
+{
+ uint32_t xorg = x ;
+
+ while ( *pString != 0 )
+ {
+ if ( *pString == '\n' )
+ {
+ y += gFont.height + 2 ;
+ x = xorg ;
+ }
+ else
+ {
+ LCDD_DrawChar( x, y, *pString, color ) ;
+ x += gFont.width + 2 ;
+ }
+
+ pString++ ;
+ }
+}
+
+/**
+ * \brief Draws a string inside a LCD buffer, at the given coordinates
+ * with given background color. Line breaks will be honored.
+ *
+ * \param x X-coordinate of string top-left corner.
+ * \param y Y-coordinate of string top-left corner.
+ * \param pString String to display.
+ * \param fontColor String color.
+ * \param bgColor Background color.
+ */
+extern void LCDD_DrawStringWithBGColor( uint32_t x, uint32_t y, const char *pString, uint32_t fontColor, uint32_t bgColor )
+{
+ unsigned xorg = x;
+
+ while ( *pString != 0 )
+ {
+ if ( *pString == '\n' )
+ {
+ y += gFont.height + 2 ;
+ x = xorg ;
+ }
+ else
+ {
+ LCDD_DrawCharWithBGColor( x, y, *pString, fontColor, bgColor ) ;
+ x += gFont.width + 2;
+ }
+
+ pString++;
+ }
+}
+
+/**
+ * \brief Returns the width & height in pixels that a string will occupy on the screen
+ * if drawn using LCDD_DrawString.
+ *
+ * \param pString String.
+ * \param pWidth Pointer for storing the string width (optional).
+ * \param pHeight Pointer for storing the string height (optional).
+ *
+ * \return String width in pixels.
+ */
+extern void LCDD_GetStringSize( const uint8_t *pString, uint32_t *pWidth, uint32_t *pHeight )
+{
+ uint32_t width = 0;
+ uint32_t height = gFont.height;
+
+ while ( *pString != 0 )
+ {
+ if ( *pString == '\n' )
+ {
+ height += gFont.height + 2 ;
+ }
+ else
+ {
+ width += gFont.width + 2 ;
+ }
+
+ pString++ ;
+ }
+
+ if ( width > 0 )
+ {
+ width -= 2;
+ }
+
+ if ( pWidth != NULL )
+ {
+ *pWidth = width;
+ }
+
+ if ( pHeight != NULL )
+ {
+ *pHeight = height ;
+ }
+}
+
+/*
+ * \brief Draw a raw image at given position on LCD.
+ *
+ * \param x X-coordinate of image start.
+ * \param y Y-coordinate of image start.
+ * \param pImage Image buffer.
+ * \param width Image width.
+ * \param height Image height.
+ */
+void LCDD_DrawImage( uint32_t dwX, uint32_t dwY, const uint8_t *pImage, uint32_t dwWidth, uint32_t dwHeight )
+{
+ uint32_t dwCursor ;
+
+ LCD_SetWindow( dwX, dwY, dwWidth, dwHeight ) ;
+ LCD_SetCursor( dwX, dwY ) ;
+ LCD_WriteRAM_Prepare() ;
+
+ for ( dwCursor=dwWidth*dwHeight; dwCursor != 0; dwCursor-- )
+ {
+ LCD_D() = *pImage++ ;
+ LCD_D() = *pImage++ ;
+ LCD_D() = *pImage++ ;
+ }
+
+ LCD_SetWindow( 0, 0, BOARD_LCD_WIDTH, BOARD_LCD_HEIGHT ) ;
+}
+
+/*
+ * \brief Draw a raw image at given position on LCD.
+ *
+ * \param dwX X-coordinate of image start.
+ * \param dwY Y-coordinate of image start.
+ * \param pGIMPImage Image data.
+ */
+void LCDD_DrawGIMPImage( uint32_t dwX, uint32_t dwY, const SGIMPImage* pGIMPImage )
+{
+ uint32_t dw ;
+ register uint32_t dwLength ;
+ uint8_t* pucData ;
+
+ // Draw raw RGB bitmap
+ LCD_SetWindow( dwX, dwY, pGIMPImage->dwWidth, pGIMPImage->dwHeight ) ;
+ LCD_SetCursor( dwX, dwY ) ;
+
+ LCD_WriteRAM_Prepare() ;
+
+ dwLength = pGIMPImage->dwWidth*pGIMPImage->dwHeight ;
+ pucData = pGIMPImage->pucPixel_data ;
+ for ( dw=0; dw < dwLength; dw++ )
+ {
+ LCD_D() = (*pucData++) ;
+ LCD_D() = (*pucData++) ;
+ LCD_D() = (*pucData++) ;
+ }
+
+ LCD_SetWindow( 0, 0, BOARD_LCD_WIDTH, BOARD_LCD_HEIGHT ) ;
+}
+
+/*
+ * \brief Clear a window with an color.
+ *
+ * \param dwX X-coordinate of the window.
+ * \param dwY Y-coordinate of the window.
+ * \param dwWidth window width.
+ * \param dwHeight window height.
+ * \param dwColor background color
+ */
+extern void LCDD_ClearWindow( uint32_t dwX, uint32_t dwY, uint32_t dwWidth, uint32_t dwHeight, uint32_t dwColor )
+{
+ uint32_t dw ;
+
+ LCD_SetCursor( dwX, dwY) ;
+ LCD_WriteRAM_Prepare() ;
+
+ for ( dw = dwWidth * dwHeight; dw > 0; dw-- )
+ {
+ LCD_WriteRAM( dwColor ) ;
+ }
+}
diff --git a/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/lcd_font.c b/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/lcd_font.c
new file mode 100644
index 00000000..a3a2be0b
--- /dev/null
+++ b/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/lcd_font.c
@@ -0,0 +1,133 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * 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:
+ *
+ * - 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 draw font on LCD.
+ *
+ */
+
+/*----------------------------------------------------------------------------
+ * Headers
+ *----------------------------------------------------------------------------*/
+
+#include "board.h"
+
+#include
+#include
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ *----------------------------------------------------------------------------*/
+
+/** Global variable describing the font being instancied. */
+const Font gFont = {10, 14};
+
+/*----------------------------------------------------------------------------
+ * Exported functions
+ *----------------------------------------------------------------------------*/
+
+/**
+ * \brief Draws an ASCII character on LCD.
+ *
+ * \param x X-coordinate of character upper-left corner.
+ * \param y Y-coordinate of character upper-left corner.
+ * \param c Character to output.
+ * \param color Character color.
+ */
+extern void LCDD_DrawChar( uint32_t x, uint32_t y, uint8_t c, uint32_t color )
+{
+ uint32_t row, col ;
+
+ assert( (c >= 0x20) && (c <= 0x7F) ) ;
+
+ for ( col = 0 ; col < 10 ; col++ )
+ {
+ for ( row = 0 ; row < 8 ; row++ )
+ {
+ if ( (pCharset10x14[((c - 0x20) * 20) + col * 2] >> (7 - row)) & 0x1 )
+ {
+ LCDD_DrawPixel( x+col, y+row, color ) ;
+ }
+ }
+
+ for (row = 0; row < 6; row++ )
+ {
+ if ((pCharset10x14[((c - 0x20) * 20) + col * 2 + 1] >> (7 - row)) & 0x1)
+ {
+ LCDD_DrawPixel( x+col, y+row+8, color ) ;
+ }
+ }
+ }
+}
+
+/**
+ * \brief Draws an ASCII character on LCD with given background color.
+ *
+ * \param x X-coordinate of character upper-left corner.
+ * \param y Y-coordinate of character upper-left corner.
+ * \param c Character to output.
+ * \param fontColor Character color.
+ * \param bgColor Background color.
+ */
+extern void LCDD_DrawCharWithBGColor( uint32_t x, uint32_t y, uint8_t c, uint32_t fontColor, uint32_t bgColor )
+{
+ uint32_t row, col ;
+
+ assert( (c >= 0x20) && (c <= 0x7F) ) ;
+
+ for (col = 0; col < 10; col++)
+ {
+ for (row = 0 ; row < 8 ; row++)
+ {
+ if ( (pCharset10x14[((c - 0x20) * 20) + col * 2] >> (7 - row)) & 0x1 )
+ {
+ LCDD_DrawPixel( x+col, y+row, fontColor ) ;
+ }
+ else
+ {
+ LCDD_DrawPixel( x+col, y+row, bgColor ) ;
+ }
+ }
+
+ for ( row = 0 ; row < 6 ; row++ )
+ {
+ if ( (pCharset10x14[((c - 0x20) * 20) + col * 2 + 1] >> (7 - row)) & 0x1 )
+ {
+ LCDD_DrawPixel( x+col, y+row+8, fontColor ) ;
+ }
+ else
+ {
+ LCDD_DrawPixel( x+col, y+row+8, bgColor ) ;
+ }
+ }
+ }
+}
+
diff --git a/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/lcd_font10x14.c b/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/lcd_font10x14.c
new file mode 100644
index 00000000..a627355d
--- /dev/null
+++ b/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/lcd_font10x14.c
@@ -0,0 +1,233 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * 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:
+ *
+ * - 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.
+ *
+ */
+
+#include "board.h"
+
+/** Char set of font 10x14 */
+const uint8_t pCharset10x14[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xCC,
+ 0xFF, 0xCC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x0C, 0xC0, 0x0C, 0xC0, 0xFF, 0xFC, 0xFF, 0xFC, 0x0C, 0xC0,
+ 0x0C, 0xC0, 0xFF, 0xFC, 0xFF, 0xFC, 0x0C, 0xC0, 0x0C, 0xC0,
+ 0x0C, 0x60, 0x1E, 0x70, 0x3F, 0x30, 0x33, 0x30, 0xFF, 0xFC,
+ 0xFF, 0xFC, 0x33, 0x30, 0x33, 0xF0, 0x39, 0xE0, 0x18, 0xC0,
+ 0x60, 0x00, 0xF0, 0x0C, 0xF0, 0x3C, 0x60, 0xF0, 0x03, 0xC0,
+ 0x0F, 0x00, 0x3C, 0x18, 0xF0, 0x3C, 0xC0, 0x3C, 0x00, 0x18,
+ 0x3C, 0xF0, 0x7F, 0xF8, 0xC3, 0x1C, 0xC7, 0x8C, 0xCF, 0xCC,
+ 0xDC, 0xEC, 0x78, 0x78, 0x30, 0x30, 0x00, 0xFC, 0x00, 0xCC,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0xEC, 0x00,
+ 0xF8, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0F, 0xC0, 0x3F, 0xF0, 0x78, 0x78,
+ 0x60, 0x18, 0xC0, 0x0C, 0xC0, 0x0C, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xC0, 0x0C, 0xC0, 0x0C, 0x60, 0x18,
+ 0x78, 0x78, 0x3F, 0xF0, 0x0F, 0xC0, 0x00, 0x00, 0x00, 0x00,
+ 0x0C, 0x60, 0x0E, 0xE0, 0x07, 0xC0, 0x03, 0x80, 0x3F, 0xF8,
+ 0x3F, 0xF8, 0x03, 0x80, 0x07, 0xC0, 0x0E, 0xE0, 0x0C, 0x60,
+ 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x3F, 0xF0,
+ 0x3F, 0xF0, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
+ 0x00, 0x44, 0x00, 0xEC, 0x00, 0xF8, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
+ 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
+ 0x00, 0x18, 0x00, 0x3C, 0x00, 0x3C, 0x00, 0x18, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x0C, 0x00, 0x3C, 0x00, 0xF0, 0x03, 0xC0,
+ 0x0F, 0x00, 0x3C, 0x00, 0xF0, 0x00, 0xC0, 0x00, 0x00, 0x00,
+ 0x3F, 0xF0, 0x7F, 0xF8, 0xE0, 0xFC, 0xC1, 0xCC, 0xC3, 0x8C,
+ 0xC7, 0x0C, 0xCE, 0x0C, 0xFC, 0x1C, 0x7F, 0xF8, 0x3F, 0xF0,
+ 0x00, 0x00, 0x00, 0x00, 0x30, 0x0C, 0x70, 0x0C, 0xFF, 0xFC,
+ 0xFF, 0xFC, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+ 0x30, 0x0C, 0x70, 0x1C, 0xE0, 0x3C, 0xC0, 0x7C, 0xC0, 0xEC,
+ 0xC1, 0xCC, 0xC3, 0x8C, 0xE7, 0x0C, 0x7E, 0x0C, 0x3C, 0x0C,
+ 0x30, 0x30, 0x70, 0x38, 0xE0, 0x1C, 0xC0, 0x0C, 0xC0, 0x0C,
+ 0xC3, 0x0C, 0xC3, 0x0C, 0xE3, 0x1C, 0x7F, 0xF8, 0x3C, 0xF0,
+ 0x03, 0xC0, 0x07, 0xC0, 0x0E, 0xC0, 0x1C, 0xC0, 0x38, 0xC0,
+ 0x70, 0xC0, 0xFF, 0xFC, 0xFF, 0xFC, 0x00, 0xC0, 0x00, 0xC0,
+ 0xFC, 0x30, 0xFC, 0x38, 0xCC, 0x1C, 0xCC, 0x0C, 0xCC, 0x0C,
+ 0xCC, 0x0C, 0xCC, 0x0C, 0xCE, 0x1C, 0xC7, 0xF8, 0xC3, 0xF0,
+ 0x3F, 0xF0, 0x7F, 0xF8, 0xE3, 0x1C, 0xC3, 0x0C, 0xC3, 0x0C,
+ 0xC3, 0x0C, 0xC3, 0x0C, 0xE3, 0x9C, 0x71, 0xF8, 0x30, 0xF0,
+ 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC3, 0xFC,
+ 0xC7, 0xFC, 0xCE, 0x00, 0xDC, 0x00, 0xF8, 0x00, 0xF0, 0x00,
+ 0x3C, 0xF0, 0x7F, 0xF8, 0xE7, 0x9C, 0xC3, 0x0C, 0xC3, 0x0C,
+ 0xC3, 0x0C, 0xC3, 0x0C, 0xE7, 0x9C, 0x7F, 0xF8, 0x3C, 0xF0,
+ 0x3C, 0x00, 0x7E, 0x00, 0xE7, 0x0C, 0xC3, 0x0C, 0xC3, 0x1C,
+ 0xC3, 0x38, 0xC3, 0x70, 0xE7, 0xE0, 0x7F, 0xC0, 0x3F, 0x80,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x60, 0x3C, 0xF0,
+ 0x3C, 0xF0, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x44, 0x3C, 0xEC,
+ 0x3C, 0xF8, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x03, 0x00, 0x07, 0x80, 0x0F, 0xC0, 0x1C, 0xE0,
+ 0x38, 0x70, 0x70, 0x38, 0xE0, 0x1C, 0xC0, 0x0C, 0x00, 0x00,
+ 0x0C, 0xC0, 0x0C, 0xC0, 0x0C, 0xC0, 0x0C, 0xC0, 0x0C, 0xC0,
+ 0x0C, 0xC0, 0x0C, 0xC0, 0x0C, 0xC0, 0x0C, 0xC0, 0x0C, 0xC0,
+ 0x00, 0x00, 0xC0, 0x0C, 0xE0, 0x1C, 0x70, 0x38, 0x38, 0x70,
+ 0x1C, 0xE0, 0x0F, 0xC0, 0x07, 0x80, 0x03, 0x00, 0x00, 0x00,
+ 0x30, 0x00, 0x70, 0x00, 0xE0, 0x00, 0xC0, 0x00, 0xC1, 0xEC,
+ 0xC3, 0xEC, 0xC3, 0x00, 0xE6, 0x00, 0x7E, 0x00, 0x3C, 0x00,
+ 0x30, 0xF0, 0x71, 0xF8, 0xE3, 0x9C, 0xC3, 0x0C, 0xC3, 0xFC,
+ 0xC3, 0xFC, 0xC0, 0x0C, 0xE0, 0x1C, 0x7F, 0xF8, 0x3F, 0xF0,
+ 0x3F, 0xFC, 0x7F, 0xFC, 0xE0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,
+ 0xC0, 0xC0, 0xC0, 0xC0, 0xE0, 0xC0, 0x7F, 0xFC, 0x3F, 0xFC,
+ 0xFF, 0xFC, 0xFF, 0xFC, 0xC3, 0x0C, 0xC3, 0x0C, 0xC3, 0x0C,
+ 0xC3, 0x0C, 0xC3, 0x0C, 0xE7, 0x9C, 0x7F, 0xF8, 0x3C, 0xF0,
+ 0x3F, 0xF0, 0x7F, 0xF8, 0xE0, 0x1C, 0xC0, 0x0C, 0xC0, 0x0C,
+ 0xC0, 0x0C, 0xC0, 0x0C, 0xE0, 0x1C, 0x70, 0x38, 0x30, 0x30,
+ 0xFF, 0xFC, 0xFF, 0xFC, 0xC0, 0x0C, 0xC0, 0x0C, 0xC0, 0x0C,
+ 0xC0, 0x0C, 0xC0, 0x0C, 0xE0, 0x1C, 0x7F, 0xF8, 0x3F, 0xF0,
+ 0xFF, 0xFC, 0xFF, 0xFC, 0xC3, 0x0C, 0xC3, 0x0C, 0xC3, 0x0C,
+ 0xC3, 0x0C, 0xC3, 0x0C, 0xC3, 0x0C, 0xC0, 0x0C, 0xC0, 0x0C,
+ 0xFF, 0xFC, 0xFF, 0xFC, 0xC3, 0x00, 0xC3, 0x00, 0xC3, 0x00,
+ 0xC3, 0x00, 0xC3, 0x00, 0xC3, 0x00, 0xC0, 0x00, 0xC0, 0x00,
+ 0x3F, 0xF0, 0x7F, 0xF8, 0xE0, 0x1C, 0xC0, 0x0C, 0xC0, 0x0C,
+ 0xC3, 0x0C, 0xC3, 0x0C, 0xE3, 0x1C, 0x73, 0xF8, 0x33, 0xF0,
+ 0xFF, 0xFC, 0xFF, 0xFC, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
+ 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0xFF, 0xFC, 0xFF, 0xFC,
+ 0x00, 0x00, 0x00, 0x00, 0xC0, 0x0C, 0xC0, 0x0C, 0xFF, 0xFC,
+ 0xFF, 0xFC, 0xC0, 0x0C, 0xC0, 0x0C, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x30, 0x00, 0x38, 0xC0, 0x1C, 0xC0, 0x0C, 0xC0, 0x0C,
+ 0xC0, 0x1C, 0xFF, 0xF8, 0xFF, 0xF0, 0xC0, 0x00, 0xC0, 0x00,
+ 0xFF, 0xFC, 0xFF, 0xFC, 0x07, 0x80, 0x07, 0x80, 0x0F, 0xC0,
+ 0x1C, 0xE0, 0x38, 0x70, 0x70, 0x38, 0xE0, 0x1C, 0xC0, 0x0C,
+ 0xFF, 0xFC, 0xFF, 0xFC, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C,
+ 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C,
+ 0xFF, 0xFC, 0xFF, 0xFC, 0x70, 0x00, 0x38, 0x00, 0x1F, 0x00,
+ 0x1F, 0x00, 0x38, 0x00, 0x70, 0x00, 0xFF, 0xFC, 0xFF, 0xFC,
+ 0xFF, 0xFC, 0xFF, 0xFC, 0x1C, 0x00, 0x0E, 0x00, 0x07, 0x00,
+ 0x03, 0x80, 0x01, 0xC0, 0x00, 0xE0, 0xFF, 0xFC, 0xFF, 0xFC,
+ 0x3F, 0xF0, 0x7F, 0xF8, 0xE0, 0x1C, 0xC0, 0x0C, 0xC0, 0x0C,
+ 0xC0, 0x0C, 0xC0, 0x0C, 0xE0, 0x1C, 0x7F, 0xF8, 0x3F, 0xF0,
+ 0xFF, 0xFC, 0xFF, 0xFC, 0xC3, 0x00, 0xC3, 0x00, 0xC3, 0x00,
+ 0xC3, 0x00, 0xC3, 0x00, 0xE7, 0x00, 0x7E, 0x00, 0x3C, 0x00,
+ 0x3F, 0xF0, 0x7F, 0xF8, 0xE0, 0x1C, 0xC0, 0x0C, 0xC0, 0xCC,
+ 0xC0, 0xEC, 0xC0, 0x7C, 0xE0, 0x38, 0x7F, 0xFC, 0x3F, 0xEC,
+ 0xFF, 0xFC, 0xFF, 0xFC, 0xC3, 0x00, 0xC3, 0x80, 0xC3, 0x80,
+ 0xC3, 0xC0, 0xC3, 0xC0, 0xE7, 0x70, 0x7E, 0x3C, 0x3C, 0x1C,
+ 0x3C, 0x18, 0x7E, 0x1C, 0xE7, 0x0C, 0xC3, 0x0C, 0xC3, 0x0C,
+ 0xC3, 0x0C, 0xC3, 0x0C, 0xC3, 0x9C, 0xE1, 0xF8, 0x60, 0xF0,
+ 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xFF, 0xFC,
+ 0xFF, 0xFC, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00,
+ 0xFF, 0xF0, 0xFF, 0xF8, 0x00, 0x1C, 0x00, 0x0C, 0x00, 0x0C,
+ 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x1C, 0xFF, 0xF8, 0xFF, 0xF0,
+ 0xFF, 0xC0, 0xFF, 0xE0, 0x00, 0x70, 0x00, 0x38, 0x00, 0x1C,
+ 0x00, 0x1C, 0x00, 0x38, 0x00, 0x70, 0xFF, 0xE0, 0xFF, 0xC0,
+ 0xFF, 0xF0, 0xFF, 0xF8, 0x00, 0x1C, 0x00, 0x3C, 0x00, 0xF8,
+ 0x00, 0xF8, 0x00, 0x3C, 0x00, 0x1C, 0xFF, 0xF8, 0xFF, 0xF0,
+ 0xF0, 0x3C, 0xF8, 0x7C, 0x1C, 0xE0, 0x0F, 0xC0, 0x07, 0x80,
+ 0x07, 0x80, 0x0F, 0xC0, 0x1C, 0xE0, 0xF8, 0x7C, 0xF0, 0x3C,
+ 0xFC, 0x00, 0xFE, 0x00, 0x07, 0x00, 0x03, 0x80, 0x01, 0xFC,
+ 0x01, 0xFC, 0x03, 0x80, 0x07, 0x00, 0xFE, 0x00, 0xFC, 0x00,
+ 0xC0, 0x3C, 0xC0, 0x7C, 0xC0, 0xEC, 0xC1, 0xCC, 0xC3, 0x8C,
+ 0xC7, 0x0C, 0xCE, 0x0C, 0xDC, 0x0C, 0xF8, 0x0C, 0xF0, 0x0C,
+ 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFC, 0xFF, 0xFC, 0xC0, 0x0C,
+ 0xC0, 0x0C, 0xC0, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x30, 0x00, 0x30, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x03, 0x00,
+ 0x03, 0x00, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0x30, 0x00, 0x30,
+ 0x00, 0x00, 0x00, 0x00, 0xC0, 0x0C, 0xC0, 0x0C, 0xC0, 0x0C,
+ 0xFF, 0xFC, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x0C, 0x00, 0x1C, 0x00, 0x38, 0x00, 0x70, 0x00, 0xE0, 0x00,
+ 0xE0, 0x00, 0x70, 0x00, 0x38, 0x00, 0x1C, 0x00, 0x0C, 0x00,
+ 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C,
+ 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C,
+ 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0xE0, 0x00, 0x70, 0x00,
+ 0x38, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x30, 0x06, 0x78, 0x0E, 0xFC, 0x0C, 0xCC, 0x0C, 0xCC,
+ 0x0C, 0xCC, 0x0C, 0xCC, 0x0E, 0xCC, 0x07, 0xFC, 0x03, 0xF8,
+ 0xFF, 0xFC, 0xFF, 0xFC, 0x03, 0x0C, 0x03, 0x0C, 0x03, 0x0C,
+ 0x03, 0x0C, 0x03, 0x0C, 0x03, 0x9C, 0x01, 0xF8, 0x00, 0xF0,
+ 0x03, 0xF0, 0x07, 0xF8, 0x0E, 0x1C, 0x0C, 0x0C, 0x0C, 0x0C,
+ 0x0C, 0x0C, 0x0C, 0x0C, 0x0E, 0x1C, 0x07, 0x38, 0x03, 0x30,
+ 0x00, 0xF0, 0x01, 0xF8, 0x03, 0x9C, 0x03, 0x0C, 0x03, 0x0C,
+ 0x03, 0x0C, 0x03, 0x0C, 0x03, 0x0C, 0xFF, 0xFC, 0xFF, 0xFC,
+ 0x03, 0xF0, 0x07, 0xF8, 0x0E, 0xDC, 0x0C, 0xCC, 0x0C, 0xCC,
+ 0x0C, 0xCC, 0x0C, 0xCC, 0x0E, 0xDC, 0x07, 0xD8, 0x03, 0x90,
+ 0x00, 0x00, 0x03, 0x00, 0x3F, 0xFC, 0x7F, 0xFC, 0xE3, 0x00,
+ 0xE3, 0x00, 0x70, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x18, 0x07, 0x9C, 0x0F, 0xCC, 0x0C, 0xCC, 0x0C, 0xCC,
+ 0x0C, 0xCC, 0x0C, 0xCC, 0x0C, 0xDC, 0x0F, 0xF8, 0x07, 0xF0,
+ 0xFF, 0xFC, 0xFF, 0xFC, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
+ 0x03, 0x00, 0x03, 0x80, 0x01, 0xFC, 0x00, 0xFC, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0xFC,
+ 0x1B, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x30, 0x00, 0x38, 0x00, 0x1C, 0x00, 0x0C,
+ 0x00, 0x0C, 0x00, 0x1C, 0xCF, 0xF8, 0xCF, 0xF0, 0x00, 0x00,
+ 0x00, 0x00, 0xFF, 0xFC, 0xFF, 0xFC, 0x00, 0xE0, 0x01, 0xE0,
+ 0x03, 0xF0, 0x07, 0x38, 0x0E, 0x1C, 0x0C, 0x0C, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xC0, 0x0C, 0xC0, 0x0C, 0xFF, 0xFC,
+ 0xFF, 0xFC, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+ 0x0F, 0xFC, 0x0F, 0xFC, 0x0E, 0x00, 0x07, 0x00, 0x03, 0xC0,
+ 0x03, 0xC0, 0x07, 0x00, 0x0E, 0x00, 0x0F, 0xFC, 0x0F, 0xFC,
+ 0x0F, 0xFC, 0x0F, 0xFC, 0x03, 0x00, 0x07, 0x00, 0x0E, 0x00,
+ 0x0C, 0x00, 0x0C, 0x00, 0x0E, 0x00, 0x07, 0xFC, 0x03, 0xFC,
+ 0x03, 0xF0, 0x07, 0xF8, 0x0E, 0x1C, 0x0C, 0x0C, 0x0C, 0x0C,
+ 0x0C, 0x0C, 0x0C, 0x0C, 0x0E, 0x1C, 0x07, 0xF8, 0x03, 0xF0,
+ 0x0F, 0xFC, 0x0F, 0xFC, 0x0C, 0xC0, 0x0C, 0xC0, 0x0C, 0xC0,
+ 0x0C, 0xC0, 0x0C, 0xC0, 0x0F, 0xC0, 0x07, 0x80, 0x03, 0x00,
+ 0x03, 0x00, 0x07, 0x80, 0x0F, 0xC0, 0x0C, 0xC0, 0x0C, 0xC0,
+ 0x0C, 0xC0, 0x0C, 0xC0, 0x0C, 0xC0, 0x0F, 0xFC, 0x0F, 0xFC,
+ 0x0F, 0xFC, 0x0F, 0xFC, 0x03, 0x80, 0x07, 0x00, 0x0E, 0x00,
+ 0x0C, 0x00, 0x0C, 0x00, 0x0E, 0x00, 0x07, 0x00, 0x03, 0x00,
+ 0x03, 0x18, 0x07, 0x9C, 0x0F, 0xCC, 0x0C, 0xCC, 0x0C, 0xCC,
+ 0x0C, 0xCC, 0x0C, 0xCC, 0x0C, 0xFC, 0x0E, 0x78, 0x06, 0x30,
+ 0x00, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0xFF, 0xF0, 0xFF, 0xF8,
+ 0x0C, 0x1C, 0x0C, 0x1C, 0x0C, 0x38, 0x0C, 0x30, 0x00, 0x00,
+ 0x0F, 0xF0, 0x0F, 0xF8, 0x00, 0x1C, 0x00, 0x0C, 0x00, 0x0C,
+ 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x1C, 0x0F, 0xF8, 0x0F, 0xF0,
+ 0x0F, 0xC0, 0x0F, 0xE0, 0x00, 0x70, 0x00, 0x38, 0x00, 0x1C,
+ 0x00, 0x1C, 0x00, 0x38, 0x00, 0x70, 0x0F, 0xE0, 0x0F, 0xC0,
+ 0x0F, 0xF0, 0x0F, 0xF8, 0x00, 0x1C, 0x00, 0x1C, 0x00, 0xF8,
+ 0x00, 0xF8, 0x00, 0x1C, 0x00, 0x1C, 0x0F, 0xF8, 0x0F, 0xF0,
+ 0x0C, 0x0C, 0x0E, 0x1C, 0x07, 0x38, 0x03, 0xF0, 0x01, 0xE0,
+ 0x01, 0xE0, 0x03, 0xF0, 0x07, 0x38, 0x0E, 0x1C, 0x0C, 0x0C,
+ 0x0C, 0x00, 0x0E, 0x00, 0x07, 0x0C, 0x03, 0x9C, 0x01, 0xF8,
+ 0x01, 0xF0, 0x03, 0x80, 0x07, 0x00, 0x0E, 0x00, 0x0C, 0x00,
+ 0x0C, 0x0C, 0x0C, 0x1C, 0x0C, 0x3C, 0x0C, 0x7C, 0x0C, 0xEC,
+ 0x0D, 0xCC, 0x0F, 0x8C, 0x0F, 0x0C, 0x0E, 0x0C, 0x0C, 0x0C,
+ 0x00, 0x00, 0x03, 0x00, 0x07, 0x80, 0x3F, 0xF0, 0x7C, 0xF8,
+ 0xE0, 0x1C, 0xC0, 0x0C, 0xC0, 0x0C, 0xC0, 0x0C, 0x00, 0x00,
+ 0x03, 0x0C, 0x03, 0x0C, 0x3F, 0xFC, 0x7F, 0xFC, 0xE3, 0x0C,
+ 0xC3, 0x0C, 0xC0, 0x0C, 0xE0, 0x0C, 0x70, 0x0C, 0x30, 0x0C,
+ 0x00, 0x00, 0xC0, 0x0C, 0xC0, 0x0C, 0xC0, 0x0C, 0xE0, 0x1C,
+ 0x7C, 0xF8, 0x3F, 0xF0, 0x07, 0x80, 0x03, 0x00, 0x00, 0x00,
+ 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00,
+ 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00,
+ 0xFF, 0xFC, 0xFF, 0xFC, 0xFF, 0xFC, 0xFF, 0xFC, 0xFF, 0xFC,
+ 0xFF, 0xFC, 0xFF, 0xFC, 0xFF, 0xFC, 0xFF, 0xFC, 0xFF, 0xFC
+} ;
diff --git a/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/lcdd.c b/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/lcdd.c
new file mode 100644
index 00000000..49172f24
--- /dev/null
+++ b/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/lcdd.c
@@ -0,0 +1,140 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * 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:
+ *
+ * - 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 LCD driver, Include LCD initialization,
+ * LCD on/off and LCD backlight control.
+ *
+ */
+
+/*----------------------------------------------------------------------------
+ * Headers
+ *----------------------------------------------------------------------------*/
+#include "board.h"
+
+#include
+
+/*----------------------------------------------------------------------------
+ * Exported functions
+ *----------------------------------------------------------------------------*/
+
+/**
+ * \brief Initializes the LCD controller.
+ * Configure SMC to access LCD controller at 64MHz MCK.
+ */
+extern void LCDD_Initialize( void )
+{
+ const Pin pPins[] = {BOARD_LCD_PINS};
+ Smc *pSmc = SMC;
+
+ /* Enable pins */
+ PIO_Configure(pPins, PIO_LISTSIZE(pPins));
+
+ /* Enable peripheral clock */
+ PMC_EnablePeripheral( ID_SMC ) ;
+
+ /* EBI SMC Configuration */
+ pSmc->SMC_CS_NUMBER[1].SMC_SETUP = SMC_SETUP_NWE_SETUP(2)
+ | SMC_SETUP_NCS_WR_SETUP(2)
+ | SMC_SETUP_NRD_SETUP(2)
+ | SMC_SETUP_NCS_RD_SETUP(2);
+
+ pSmc->SMC_CS_NUMBER[1].SMC_PULSE = SMC_PULSE_NWE_PULSE(4)
+ | SMC_PULSE_NCS_WR_PULSE(4)
+ | SMC_PULSE_NRD_PULSE(10)
+ | SMC_PULSE_NCS_RD_PULSE(10);
+
+ pSmc->SMC_CS_NUMBER[1].SMC_CYCLE = SMC_CYCLE_NWE_CYCLE(10)
+ | SMC_CYCLE_NRD_CYCLE(22);
+
+ pSmc->SMC_CS_NUMBER[1].SMC_MODE = SMC_MODE_READ_MODE
+ | SMC_MODE_WRITE_MODE
+ | SMC_MODE_DBW_8_BIT;
+
+ /* Initialize LCD controller */
+ LCD_Initialize() ;
+
+ /* Initialize LCD controller */
+ LCD_SetDisplayPortrait( 0 ) ;
+
+ /* Set LCD backlight */
+ LCDD_SetBacklight( 2 ) ;
+}
+
+/**
+ * \brief Turn on the LCD.
+ */
+void LCDD_On(void)
+{
+ LCD_On();
+}
+
+/**
+ * \brief Turn off the LCD.
+ */
+void LCDD_Off(void)
+{
+ LCD_Off();
+}
+
+/**
+ * \brief Set the backlight of the LCD.
+ *
+ * \param level Backlight brightness level [1..16], 1 means maximum brightness.
+ */
+void LCDD_SetBacklight (uint32_t level)
+{
+ uint32_t i;
+ const Pin pPins[] = {BOARD_BACKLIGHT_PIN};
+
+ /* Ensure valid level */
+ level = (level < 1) ? 1 : level;
+ level = (level > 16) ? 16 : level;
+
+ /* Enable pins */
+ PIO_Configure(pPins, PIO_LISTSIZE(pPins));
+
+ /* Switch off backlight */
+ PIO_Clear(pPins);
+ i = 600 * (BOARD_MCK / 1000000); /* wait for at least 500us */
+ while(i--);
+
+ /* Set new backlight level */
+ for (i = 0; i < level; i++) {
+ PIO_Clear(pPins);
+ PIO_Clear(pPins);
+ PIO_Clear(pPins);
+
+ PIO_Set(pPins);
+ PIO_Set(pPins);
+ PIO_Set(pPins);
+ }
+}
diff --git a/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/led.c b/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/led.c
new file mode 100644
index 00000000..1a88e45b
--- /dev/null
+++ b/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/led.c
@@ -0,0 +1,168 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, 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.
+ * ----------------------------------------------------------------------------
+ */
+
+/**
+ * \file
+ */
+
+/*------------------------------------------------------------------------------
+ * Headers
+ *------------------------------------------------------------------------------*/
+
+#include "board.h"
+
+/*------------------------------------------------------------------------------
+ * Local Variables
+ *------------------------------------------------------------------------------*/
+
+#ifdef PINS_LEDS
+static const Pin pinsLeds[] = { PINS_LEDS } ;
+static const uint32_t numLeds = PIO_LISTSIZE( pinsLeds ) ;
+#endif
+
+/*------------------------------------------------------------------------------
+ * Global Functions
+ *------------------------------------------------------------------------------*/
+
+/**
+ * Configures the pin associated with the given LED number. If the LED does
+ * not exist on the board, the function does nothing.
+ * \param led Number of the LED to configure.
+ * \return 1 if the LED exists and has been configured; otherwise 0.
+ */
+extern uint32_t LED_Configure( uint32_t dwLed )
+{
+#ifdef PINS_LEDS
+ // Check that LED exists
+ if ( dwLed >= numLeds)
+ {
+
+ return 0;
+ }
+
+ // Configure LED
+ return ( PIO_Configure( &pinsLeds[dwLed], 1 ) ) ;
+#else
+ return 0 ;
+#endif
+}
+
+/**
+ * Turns the given LED on if it exists; otherwise does nothing.
+ * \param led Number of the LED to turn on.
+ * \return 1 if the LED has been turned on; 0 otherwise.
+ */
+extern uint32_t LED_Set( uint32_t dwLed )
+{
+#ifdef PINS_LEDS
+ /* Check if LED exists */
+ if ( dwLed >= numLeds )
+ {
+ return 0 ;
+ }
+
+ /* Turn LED on */
+ if ( pinsLeds[dwLed].type == PIO_OUTPUT_0 )
+ {
+
+ PIO_Set( &pinsLeds[dwLed] ) ;
+ }
+ else
+ {
+ PIO_Clear( &pinsLeds[dwLed] ) ;
+ }
+
+ return 1 ;
+#else
+ return 0 ;
+#endif
+}
+
+/**
+ * Turns a LED off.
+ *
+ * \param led Number of the LED to turn off.
+ * \return 1 if the LED has been turned off; 0 otherwise.
+ */
+extern uint32_t LED_Clear( uint32_t dwLed )
+{
+#ifdef PINS_LEDS
+ /* Check if LED exists */
+ if ( dwLed >= numLeds )
+ {
+ return 0 ;
+ }
+
+ /* Turn LED off */
+ if ( pinsLeds[dwLed].type == PIO_OUTPUT_0 )
+ {
+ PIO_Clear( &pinsLeds[dwLed] ) ;
+ }
+ else
+ {
+ PIO_Set( &pinsLeds[dwLed] ) ;
+ }
+
+ return 1 ;
+#else
+ return 0 ;
+#endif
+}
+
+/**
+ * Toggles the current state of a LED.
+ *
+ * \param led Number of the LED to toggle.
+ * \return 1 if the LED has been toggled; otherwise 0.
+ */
+extern uint32_t LED_Toggle( uint32_t dwLed )
+{
+#ifdef PINS_LEDS
+ /* Check if LED exists */
+ if ( dwLed >= numLeds )
+ {
+ return 0 ;
+ }
+
+ /* Toggle LED */
+ if ( PIO_GetOutputDataStatus( &pinsLeds[dwLed] ) )
+ {
+ PIO_Clear( &pinsLeds[dwLed] ) ;
+ }
+ else
+ {
+ PIO_Set( &pinsLeds[dwLed] ) ;
+ }
+
+ return 1 ;
+#else
+ return 0 ;
+#endif
+}
+
diff --git a/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/math.c b/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/math.c
new file mode 100644
index 00000000..2121f02d
--- /dev/null
+++ b/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/math.c
@@ -0,0 +1,95 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, 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.
+ * ----------------------------------------------------------------------------
+ */
+
+/*------------------------------------------------------------------------------
+ * Headers
+ *------------------------------------------------------------------------------*/
+
+#include "board.h"
+
+/*------------------------------------------------------------------------------
+ * Exported functions
+ *------------------------------------------------------------------------------*/
+
+/**
+ * Returns the minimum value between two integers.
+ *
+ * \param a First integer to compare.
+ * \param b Second integer to compare.
+ */
+extern uint32_t min( uint32_t dwA, uint32_t dwB )
+{
+ if ( dwA < dwB )
+ {
+ return dwA ;
+ }
+ else
+ {
+ return dwB ;
+ }
+}
+
+/*------------------------------------------------------------------------------
+ * Returns the absolute value of an integer.
+ *
+ * \param value Integer value.
+ *
+ * \note Do not call this function "abs", problem with gcc !
+ */
+extern uint32_t absv( int32_t lValue )
+{
+ if ( lValue < 0 )
+ {
+ return -lValue ;
+ }
+ else
+ {
+ return lValue ;
+ }
+}
+
+/*------------------------------------------------------------------------------
+ * Computes and returns x power of y.
+ *
+ * \param x Value.
+ * \param y Power.
+ */
+extern uint32_t power( uint32_t dwX, uint32_t dwY )
+{
+ uint32_t dwResult = 1 ;
+
+ while ( dwY > 0 )
+ {
+ dwResult *= dwX ;
+ dwY-- ;
+ }
+
+ return dwResult ;
+}
+
diff --git a/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/rand.c b/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/rand.c
new file mode 100644
index 00000000..371ea187
--- /dev/null
+++ b/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/rand.c
@@ -0,0 +1,61 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, 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.
+ * ----------------------------------------------------------------------------
+ */
+
+#include "board.h"
+
+/*------------------------------------------------------------------------------
+ * Global Variables
+ *------------------------------------------------------------------------------*/
+
+static uint32_t _dwRandNext=1 ;
+
+/*------------------------------------------------------------------------------
+ * Exported Functions
+ *------------------------------------------------------------------------------*/
+
+/**
+ * Initialize the seed for rand generator.
+ *
+ * \param seed rand initiation seed
+ */
+extern void srand( uint32_t dwSeed )
+{
+ _dwRandNext = dwSeed ;
+}
+
+/**
+ * Return a random number, maxinum assumed to be 65536
+ */
+extern int rand( void )
+{
+ _dwRandNext = _dwRandNext * 1103515245 + 12345 ;
+
+ return (uint32_t)(_dwRandNext/131072) % 65536 ;
+}
+
diff --git a/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/retarget.c b/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/retarget.c
new file mode 100644
index 00000000..cf441e5c
--- /dev/null
+++ b/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/retarget.c
@@ -0,0 +1,86 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2010, 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.
+ * ----------------------------------------------------------------------------
+ */
+
+/*
+ * This file Configures the target-dependent low level functions for character I/O.
+ */
+
+#include "board.h"
+#include
+
+/* Disable semihosting */
+#pragma import(__use_no_semihosting_swi)
+
+struct __FILE { int handle;} ;
+FILE __stdout;
+FILE __stderr;
+
+/*------------------------------------------------------------------------------
+ * Outputs a character.
+ *------------------------------------------------------------------------------*/
+int fputc(int ch, FILE *f)
+{
+ if ((f == stdout) || (f == stderr))
+ {
+ UART_PutChar( ch ) ;
+ return ch ;
+ }
+ else
+ {
+ return EOF ;
+ }
+}
+
+/*------------------------------------------------------------------------------
+ * Returns the error status accumulated during file I/O.
+ *------------------------------------------------------------------------------*/
+int ferror( FILE *f )
+{
+ return EOF ;
+}
+
+
+void _ttywrch( int ch )
+{
+ UART_PutChar( (uint8_t)ch ) ;
+}
+
+void _sys_exit(int return_code)
+{
+ while ( 1 ) ; /* endless loop */
+}
+
+/*------------------------------------------------------------------------------
+ * Low level functions I/O for assert().
+ *------------------------------------------------------------------------------*/
+void __assert_puts(const char *str)
+{
+ printf("%s", str);
+}
+
diff --git a/sam3s_example/src/syscalls.c b/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/syscalls.c
similarity index 93%
rename from sam3s_example/src/syscalls.c
rename to sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/syscalls.c
index 9b3bfec5..a71173c8 100644
--- a/sam3s_example/src/syscalls.c
+++ b/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/syscalls.c
@@ -111,18 +111,18 @@ extern int _read(int file, char *ptr, int len)
extern int _write( int file, char *ptr, int len )
{
- //int iIndex ;
+/*
+ int iIndex ;
// for ( ; *ptr != 0 ; ptr++ )
-/* for ( iIndex=0 ; iIndex < len ; iIndex++, ptr++ )
+ for ( iIndex=0 ; iIndex < len ; iIndex++, ptr++ )
{
UART_PutChar( *ptr ) ;
}
-
return iIndex ;
- */
- return 0;
+*/
+ return -1;
}
extern void _exit( int status )
diff --git a/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/timetick.c b/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/timetick.c
new file mode 100644
index 00000000..f0f3c27c
--- /dev/null
+++ b/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/timetick.c
@@ -0,0 +1,117 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * 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:
+ *
+ * - 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
+ * Implement simple system tick usage.
+ */
+
+/*----------------------------------------------------------------------------
+ * Headers
+ *----------------------------------------------------------------------------*/
+
+#include "board.h"
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ *----------------------------------------------------------------------------*/
+
+/** Tick Counter united by ms */
+static volatile uint32_t _dwTickCount=0 ;
+
+/*----------------------------------------------------------------------------
+ * Exported Functions
+ *----------------------------------------------------------------------------*/
+
+/**
+ * \brief Handler for Sytem Tick interrupt.
+ */
+extern void TimeTick_Increment( void )
+{
+ _dwTickCount++ ;
+}
+
+/**
+ * \brief Configures the SAM3 SysTick & reset tickCount.
+ * Systick interrupt handler will generates 1ms interrupt and increase a
+ * tickCount.
+ * \param new_mck Current master clock.
+ */
+extern uint32_t TimeTick_Configure( uint32_t new_mck )
+{
+ _dwTickCount = 0 ;
+ return SysTick_Config( new_mck/1000 ) ;
+}
+
+/**
+ * \brief Get current Tick Count, in ms.
+ */
+extern uint32_t GetTickCount( void )
+{
+ return _dwTickCount ;
+}
+
+/**
+ * \brief Sync Wait for several ms
+ */
+extern void Wait( volatile uint32_t dwMs )
+{
+ uint32_t dwStart ;
+ uint32_t dwCurrent ;
+
+ dwStart = _dwTickCount ;
+ do
+ {
+ dwCurrent = _dwTickCount ;
+ } while ( dwCurrent - dwStart < dwMs ) ;
+}
+
+/**
+ * \brief Sync Sleep for several ms
+ */
+extern void Sleep( volatile uint32_t dwMs )
+{
+ uint32_t dwStart ;
+ uint32_t dwCurrent ;
+
+ dwStart = _dwTickCount ;
+
+ do
+ {
+ dwCurrent = _dwTickCount ;
+
+ if ( dwCurrent - dwStart > dwMs )
+ {
+ break ;
+ }
+
+ __WFI() ;
+ } while( 1 ) ;
+}
+
diff --git a/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/trace.c b/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/trace.c
new file mode 100644
index 00000000..362539df
--- /dev/null
+++ b/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/trace.c
@@ -0,0 +1,59 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, 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.
+ * ----------------------------------------------------------------------------
+ */
+
+
+/*------------------------------------------------------------------------------
+ * Headers
+ *------------------------------------------------------------------------------*/
+
+#include "board.h"
+
+/*------------------------------------------------------------------------------
+ * Internal variables
+ *------------------------------------------------------------------------------*/
+
+/** Trace level can be set at applet initialization */
+#if !defined(NOTRACE) && (DYN_TRACES == 1)
+ uint32_t dwTraceLevel = TRACE_LEVEL ;
+#endif
+
+/**
+ * Initializes the U(S)ART Console
+ *
+ * \param dwBaudRate U(S)ART baudrate.
+ * \param dwMCk Master clock frequency.
+ */
+extern void TRACE_CONFIGURE( uint32_t dwBaudRate, uint32_t dwMCk )
+{
+ const Pin pinsUART0[] = { PINS_UART } ;
+
+ PIO_Configure( pinsUART0, PIO_LISTSIZE( pinsUART0 ) ) ;
+
+ UART_Configure( dwBaudRate, dwMCk ) ;
+}
diff --git a/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/tsd_ads7843.c b/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/tsd_ads7843.c
new file mode 100644
index 00000000..54838ff0
--- /dev/null
+++ b/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/tsd_ads7843.c
@@ -0,0 +1,317 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * 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:
+ *
+ * - 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 ADS7843 driver.
+ */
+
+/*----------------------------------------------------------------------------
+ * Headers
+ *----------------------------------------------------------------------------*/
+
+#include "board.h"
+
+#ifdef BOARD_TSC_ADS7843
+
+#include
+#include
+
+/*----------------------------------------------------------------------------
+ * Definitions
+ *----------------------------------------------------------------------------*/
+
+/** Delay for pushbutton debouncing (the time-base is 10 ms). */
+#define DEBOUNCE_TIME 6 /* 10 * 6 = 60 ms */
+
+/** Color of calibration points. */
+#define POINTS_COLOR 0x0000FF
+
+/** Size in pixels of calibration points. */
+#define POINTS_SIZE 4
+
+/** Maximum difference in pixels between the test point and the measured point. */
+#define POINTS_MAX_ERROR 5
+
+/*----------------------------------------------------------------------------
+ * Types
+ *----------------------------------------------------------------------------*/
+
+/** pen state */
+typedef enum {
+ STATE_PEN_RELEASED = 0,
+ STATE_PEN_PRESSED = 1,
+ STATE_PEN_DEBOUNCE = 2
+} e_pen_state;
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ *----------------------------------------------------------------------------*/
+
+/** Pins used by Interrupt Signal for Touch Screen Controller */
+static const Pin pinPenIRQ = PIN_TSC_IRQ;
+
+/** Global timestamp in milliseconds since start of application. */
+static volatile uint32_t timestamp = 0;
+
+/** last time when the pen is pressed on the touchscreen */
+static volatile uint32_t timePress = 0;
+
+/** last time when the pen is released */
+static volatile uint32_t timeRelease = 0;
+
+/** pen state */
+static volatile e_pen_state penState = STATE_PEN_RELEASED;
+
+/** Touch screen initiallized flag */
+static uint32_t tsInitFlag = 0;
+
+/*----------------------------------------------------------------------------
+ * Local functions
+ *----------------------------------------------------------------------------*/
+
+/**
+ * \brief Timer handler for touch screen. Increments the timestamp counter.
+ * Determine the state "Pen Pressed" or "Pen Released". To change state,
+ * the penIRQ has to keep the same value during DEBOUNCE_TIME.
+ *
+ * \note External timer interrupt should call it per 10ms.
+ */
+void TSD_TimerHandler( void )
+{
+ uint32_t data[2];
+ uint32_t timeKeep;
+ static uint32_t point[2];
+
+ if (!tsInitFlag) return;
+
+ timestamp++;
+ /* Get the current position of the pen if penIRQ has low value (pen pressed) */
+ if ( PIO_Get(&pinPenIRQ) == 0 )
+ {
+ /* Get the current position of the pressed pen */
+ if ( TSDCom_IsCalibrationOk() )
+ {
+ TSD_GetRawMeasurement(data);
+ TSDCom_InterpolateMeasurement(data, point);
+ }
+
+ /* call the callback function */
+ if ( penState == STATE_PEN_PRESSED )
+ {
+ if(TSDCom_IsCalibrationOk())
+ {
+ TSD_PenMoved(point[0], point[1]);
+ }
+ }
+ }
+
+ /* Determine the pen state */
+ if ( PIO_Get( &pinPenIRQ ) == 0 )
+ {
+ /* reinit the last time when release */
+ timeRelease = timestamp;
+
+ if ( penState == STATE_PEN_DEBOUNCE )
+ {
+ timeKeep = timestamp;
+ timeKeep -= timePress;
+ if(timeKeep > DEBOUNCE_TIME)
+ {
+ /* pen is pressed during an enough time : the state change */
+ penState = STATE_PEN_PRESSED;
+ /* call the callback function */
+ if ( TSDCom_IsCalibrationOk() )
+ {
+ TSD_PenPressed(point[0], point[1]);
+ }
+ }
+ }
+ }
+ else
+ {
+ /* reinit the last time when release */
+ timePress = timestamp;
+
+ if ( penState == STATE_PEN_DEBOUNCE )
+ {
+ timeKeep = timestamp;
+ timeKeep -= timeRelease;
+ if ( timeKeep > DEBOUNCE_TIME )
+ {
+ /* pen is released during an enough time : the state change */
+ penState = STATE_PEN_RELEASED;
+ /* call the callback function */
+ if ( TSDCom_IsCalibrationOk() )
+ {
+ TSD_PenReleased(point[0], point[1]);
+ }
+ }
+ }
+ }
+}
+
+/**
+ * \breif Interrupt handler for Touchscreen.
+ */
+static void ISR_PenIRQ( void )
+{
+ /* Check if the pen has been pressed */
+ if ( !PIO_Get( &pinPenIRQ ) )
+ {
+ if ( penState == STATE_PEN_RELEASED )
+ {
+ timePress = timestamp;
+ penState = STATE_PEN_DEBOUNCE;
+ }
+ }
+ else
+ {
+ if ( penState == STATE_PEN_PRESSED )
+ {
+ timeRelease = timestamp;
+ penState = STATE_PEN_DEBOUNCE;
+ }
+ }
+}
+
+/**
+ * \brief Configure PENIRQ for interrupt.
+ *
+ * \note Be sure the PIO interrupt management has been initialized by
+ * PIO_InitializeInterrupts() before call this function.
+ */
+static void ConfigurePenIRQ( void )
+{
+ /* Configure pios */
+ PIO_Configure(&pinPenIRQ, PIO_LISTSIZE(pinPenIRQ));
+
+ /* Initialize interrupts */
+ PIO_ConfigureIt(&pinPenIRQ, (void (*)(const Pin *)) ISR_PenIRQ);
+
+ /* Enable the interrupt */
+ PIO_EnableIt(&pinPenIRQ);
+}
+
+/*----------------------------------------------------------------------------
+ * Exported functions
+ *----------------------------------------------------------------------------*/
+
+/**
+ * \brief Reads and store a touchscreen measurement in the provided array.
+ *
+ * \param pData Array where the measurements will be stored
+ */
+extern void TSD_GetRawMeasurement( uint32_t* pdwData )
+{
+ /* Get the current position of the pressed pen */
+ PIO_DisableIt( &pinPenIRQ ) ;
+ ADS7843_GetPosition( &pdwData[0], &pdwData[1] ) ;
+ PIO_EnableIt( &pinPenIRQ ) ;
+}
+
+/**
+ * \brief Wait pen pressed.
+ */
+extern void TSD_WaitPenPressed( void )
+{
+ /* Wait for touch & end of conversion */
+ while ( penState != STATE_PEN_RELEASED ) ;
+
+ /* while (penState != STATE_PEN_PRESSED); */
+ while ( penState != STATE_PEN_PRESSED )
+ {
+ }
+}
+
+/**
+ * \brief Wait pen released.
+ */
+extern void TSD_WaitPenReleased( void )
+{
+ /* Wait for contact loss */
+ while (penState != STATE_PEN_PRESSED);
+ while (penState != STATE_PEN_RELEASED);
+}
+
+/**
+ * \brief Do calibration.
+ *
+ * \return 1 if calibration is Ok, 0 else.
+ */
+extern uint8_t TSD_Calibrate( void )
+{
+ uint8_t ret = 0 ;
+
+ /* Calibration is done only once */
+ if ( TSDCom_IsCalibrationOk() )
+ {
+ return 1;
+ }
+
+ /* Do calibration */
+ ret = TSDCom_Calibrate();
+
+ return ret;
+}
+
+/**
+ * \brief Initializes the touchscreen driver and starts the calibration process. When
+ * finished, the touchscreen is operational.
+ *
+ * \note Important: the LCD driver must have been initialized prior to calling this
+ * function.
+ */
+extern void TSD_Initialize( int8_t calEn )
+{
+ ADS7843_Initialize();
+ ConfigurePenIRQ();
+
+ tsInitFlag = 1;
+
+ /* Calibration */
+ if(calEn) {
+ while (!TSD_Calibrate());
+ }
+}
+
+/**
+ * \brief Stop the Touchscreen, disable interrupt.
+ */
+extern void TSD_Reset( void )
+{
+ /* Disable SPI 0 */
+ ADS7843_Reset() ;
+
+ /* Disable the interrupt */
+ PIO_DisableIt( &pinPenIRQ ) ;
+}
+
+#endif /* #ifdef BOARD_TSC_ADS7843 */
diff --git a/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/tsd_com.c b/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/tsd_com.c
new file mode 100644
index 00000000..5c41cf64
--- /dev/null
+++ b/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/tsd_com.c
@@ -0,0 +1,369 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * 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:
+ *
+ * - 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 touchscreen driver device irrelevance code.
+ */
+
+/*----------------------------------------------------------------------------
+ * Headers
+ *----------------------------------------------------------------------------*/
+
+#include "board.h"
+
+#include
+#include
+#include
+
+/*----------------------------------------------------------------------------
+ * Definitions
+ *----------------------------------------------------------------------------*/
+
+/** Size in pixels of calibration points. */
+#define POINTS_SIZE 4
+/** Maximum difference in pixels between the test point and the measured point. */
+#define POINTS_MAX_ERROR 8
+
+/** Delay at the end of calibartion for result display */
+#define DELAY_RESULT_DISPLAY 4000000
+
+/*----------------------------------------------------------------------------
+ * Types
+ *----------------------------------------------------------------------------*/
+
+/** \brief Point used during the touchscreen calibration process. */
+typedef struct _CalibrationPoint {
+
+ /** Coordinate of point along the X-axis of the screen. */
+ uint32_t x;
+ /** Coordinate of point along the Y-axis of the screen. */
+ uint32_t y;
+ /** Calibration data of point. */
+ uint32_t data[2];
+
+} CalibrationPoint;
+
+/*----------------------------------------------------------------------------
+ * Variables
+ *----------------------------------------------------------------------------*/
+
+/** indicates if the touch screen has been calibrated. */
+/** If not, Callback functions are not called. */
+static volatile uint8_t bCalibrationOk = 0;
+/** Slope for interpoling touchscreen measurements along the X-axis. */
+static int32_t xSlope;
+/** Slope for interpoling touchscreen measurements along the Y-axis. */
+static int32_t ySlope;
+
+/** Calibration points. */
+static CalibrationPoint calibrationPoints[] = {
+
+ /* Top-left corner calibration point */
+ {
+ BOARD_LCD_WIDTH / 10,
+ BOARD_LCD_HEIGHT / 10,
+ {0, 0}
+ },
+ /* Top-right corner calibration point */
+ {
+ BOARD_LCD_WIDTH - BOARD_LCD_WIDTH / 10,
+ BOARD_LCD_HEIGHT / 10,
+ {0, 0}
+ },
+ /* Bottom-right corner calibration point */
+ {
+ BOARD_LCD_WIDTH - BOARD_LCD_WIDTH / 10,
+ BOARD_LCD_HEIGHT - BOARD_LCD_HEIGHT / 10,
+ {0, 0}
+ },
+ /* Bottom-left corner calibration point */
+ {
+ BOARD_LCD_WIDTH / 10,
+ BOARD_LCD_HEIGHT - BOARD_LCD_HEIGHT / 10,
+ {0, 0}
+ }
+};
+
+/** Test point */
+static const CalibrationPoint testPoint = {
+ BOARD_LCD_WIDTH / 2,
+ BOARD_LCD_HEIGHT / 2,
+ {0, 0}
+};
+
+/*----------------------------------------------------------------------------
+ * Local functions
+ *----------------------------------------------------------------------------*/
+
+/**
+ * \brief Display a calibration point on the given buffer.
+ *
+ * \param pPoint Calibration point to display.
+ */
+static void DrawCalibrationPoint(const CalibrationPoint *pPoint)
+{
+ LCDD_DrawRectangleWithFill(pPoint->x - POINTS_SIZE / 2,
+ pPoint->y - POINTS_SIZE / 2,
+ POINTS_SIZE,
+ POINTS_SIZE,
+ COLOR_RED);
+}
+
+/**
+ * \brief Clears a calibration point from the given buffer.
+ *
+ * \param pPoint Calibration point to clear.
+ */
+static void ClearCalibrationPoint(const CalibrationPoint *pPoint)
+{
+ LCDD_DrawRectangleWithFill(pPoint->x - POINTS_SIZE / 2,
+ pPoint->y - POINTS_SIZE / 2,
+ POINTS_SIZE,
+ POINTS_SIZE,
+ COLOR_WHITE);
+}
+
+/*----------------------------------------------------------------------------
+ * Exported functions
+ *----------------------------------------------------------------------------*/
+
+/**
+ * \brief Indicates if the calibration of the touch screen is Ok.
+ *
+ * \return 1 calibration Ok, 0 if not.
+ */
+uint8_t TSDCom_IsCalibrationOk(void)
+{
+ if (bCalibrationOk == 1) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+/**
+ * \brief Interpolates the provided raw measurements using the previously calculated
+ * slope. The resulting x and y coordinates are stored in an array.
+ *
+ * \param pData Raw measurement data, as returned by TSD_GetRawMeasurement().
+ * \param pPoint Array in which x and y will be stored.
+ */
+void TSDCom_InterpolateMeasurement(const uint32_t *pData, uint32_t *pPoint)
+{
+ pPoint[0] = calibrationPoints[0].x
+ - (((int32_t) calibrationPoints[0].data[0] - (int32_t) pData[0]) * 1024)
+ / xSlope;
+
+ pPoint[1] = calibrationPoints[0].y
+ - (((int32_t) calibrationPoints[0].data[1] - (int32_t) pData[1]) * 1024)
+ / ySlope;
+
+ if(pPoint[0] & 0x80000000) /* Is pPoint[0] negative ? */
+ {
+ pPoint[0] = 0;
+ }
+
+ if(pPoint[0] > BOARD_LCD_WIDTH) /* Is pPoint[0] bigger than the LCD width ? */
+ {
+ pPoint[0] = BOARD_LCD_WIDTH;
+ }
+
+ if(pPoint[1] & 0x80000000) /* Is pPoint[1] negative ? */
+ {
+ pPoint[1] = 0;
+ }
+
+ if(pPoint[1] > BOARD_LCD_HEIGHT) /* Is pPoint[1] bigger than the LCD width ? */
+ {
+ pPoint[1] = BOARD_LCD_HEIGHT;
+ }
+}
+
+/**
+ * \brief Performs the calibration process using the provided buffer to display
+ * information.
+ *
+ * \return True if calibration was successful; otherwise false.
+ */
+uint8_t TSDCom_Calibrate(void)
+{
+ volatile uint32_t i; /* to keep the tempo with gcc code optimisation */
+ int32_t slope1, slope2;
+ CalibrationPoint measuredPoint;
+ uint8_t xOk, yOk;
+ int32_t xDiff, yDiff;
+
+ /* Calibration setup */
+ LCDD_Fill(COLOR_WHITE);
+ LCDD_DrawString(30, 50, (uint8_t *)"LCD calibration", COLOR_BLACK);
+ LCDD_DrawString(1, 140, (uint8_t *)"Touch the dots to\ncalibrate the screen", COLOR_DARKBLUE);
+
+ /* Calibration points */
+ for (i=0; i < 4; i++) {
+
+ DrawCalibrationPoint(&calibrationPoints[i]);
+
+ /* Wait for touch & end of conversion */
+ TSD_WaitPenPressed();
+ TSD_GetRawMeasurement(calibrationPoints[i].data);
+ ClearCalibrationPoint(&calibrationPoints[i]);
+
+ /* Wait for contact loss */
+ TSD_WaitPenReleased();
+ }
+
+ /**
+ * Calculate slopes using the calibration data
+ * Theory behind those calculations:
+ * - We suppose the touchscreen measurements are linear, so the following equations are true (simple
+ * linear regression) for any two 'a' and 'b' points of the screen:
+ * dx = (a.data[0] - b.data[0]) / (a.x - b.x)
+ * dy = (a.data[1] - b.data[1]) / (a.y - b.y)
+ *
+ * - We calculate dx and dy (called xslope and yslope here) using the calibration points.
+ *
+ * - We can then use dx and dy to infer the position of a point 'p' given the measurements performed
+ * by the touchscreen ('c' is any of the calibration points):
+ * dx = (p.data[0] - c.data[0]) / (p.x - c.x)
+ * dy = (p.data[1] - c.data[1]) / (p.y - c.y)
+ * Thus:
+ * p.x = c.x - (p.data[0] - c.data[0]) / dx
+ * p.y = c.y - (p.data[1] - c.data[1]) / dy
+ *
+ * - Since there are four calibration points, dx and dy can be calculated twice, so we average
+ * the two values.
+ */
+ slope1 = ((int32_t) calibrationPoints[0].data[0]) - ((int32_t) calibrationPoints[1].data[0]);
+ slope1 *= 1024;
+ slope1 /= ((int32_t) calibrationPoints[0].x) - ((int32_t) calibrationPoints[1].x);
+ slope2 = ((int32_t) calibrationPoints[2].data[0]) - ((int32_t) calibrationPoints[3].data[0]);
+ slope2 *= 1024;
+ slope2 /= ((int32_t) calibrationPoints[2].x) - ((int32_t) calibrationPoints[3].x);
+ xSlope = (slope1 + slope2) / 2;
+
+ slope1 = ((int32_t) calibrationPoints[0].data[1]) - ((int32_t) calibrationPoints[2].data[1]);
+ slope1 *= 1024;
+ slope1 /= ((int32_t) calibrationPoints[0].y) - ((int32_t) calibrationPoints[2].y);
+ slope2 = ((int32_t) calibrationPoints[1].data[1]) - ((int32_t) calibrationPoints[3].data[1]);
+ slope2 *= 1024;
+ slope2 /= ((int32_t) calibrationPoints[1].y) - ((int32_t) calibrationPoints[3].y);
+ ySlope = (slope1 + slope2) / 2;
+
+ /* Test point */
+ LCDD_Fill(0xFFFFFF);
+ LCDD_DrawString(30, 50, (uint8_t *)"LCD calibration", COLOR_BLACK);
+ LCDD_DrawString(1, 100, (uint8_t *)" Touch the point to\nvalidate calibration", COLOR_DARKBLUE);
+ DrawCalibrationPoint(&testPoint);
+
+ /* Wait for touch & end of conversion */
+ TSD_WaitPenPressed();
+
+ TSD_GetRawMeasurement(measuredPoint.data);
+ TSDCom_InterpolateMeasurement(measuredPoint.data, (uint32_t *) &measuredPoint);
+ DrawCalibrationPoint(&measuredPoint);
+
+ /* Check resulting x and y */
+ xDiff = (int32_t) measuredPoint.x - (int32_t) testPoint.x;
+ yDiff = (int32_t) measuredPoint.y - (int32_t) testPoint.y;
+ xOk = (xDiff >= -POINTS_MAX_ERROR) && (xDiff <= POINTS_MAX_ERROR);
+ yOk = (yDiff >= -POINTS_MAX_ERROR) && (yDiff <= POINTS_MAX_ERROR);
+
+ /* Wait for contact loss */
+ TSD_WaitPenReleased();
+
+ /* Check calibration result */
+ if (xOk && yOk) {
+
+ bCalibrationOk = 1;
+ LCDD_Fill(COLOR_WHITE);
+ LCDD_DrawString(30, 50, (uint8_t *)"LCD calibration", COLOR_BLACK);
+ LCDD_DrawString(80, 140, (uint8_t *)"Success !", COLOR_GREEN);
+
+ }
+ else {
+
+ bCalibrationOk = 0;
+ LCDD_Fill(COLOR_WHITE);
+ LCDD_DrawString(30, 50, (uint8_t *)"LCD calibration", COLOR_BLACK);
+ LCDD_DrawString(40, 140, (uint8_t *)"Error too big", COLOR_RED);
+ }
+
+ /* Slight delay */
+ for (i = 0; i < DELAY_RESULT_DISPLAY; i++);
+
+ return (xOk && yOk);
+}
+
+/**
+ * \brief Read calibrate data to buffer.
+ *
+ * \param pBuffer Data buffer.
+ * \param size Size of data buffer in bytes.
+ */
+void TSDCom_ReadCalibrateData(void *pBuffer, uint32_t size)
+{
+ uint8_t *pDest = (uint8_t *)pBuffer;
+
+ assert( (sizeof(bCalibrationOk) + sizeof(xSlope) +
+ sizeof(ySlope) + sizeof(calibrationPoints[0].data)) < size ) ;
+
+ memcpy(pDest, (void const *)&bCalibrationOk, sizeof(bCalibrationOk));
+ pDest += sizeof(bCalibrationOk);
+ memcpy(pDest, &xSlope, sizeof(xSlope));
+ pDest += sizeof(xSlope);
+ memcpy(pDest, &ySlope, sizeof(ySlope));
+ pDest += sizeof(ySlope);
+ memcpy(pDest, &calibrationPoints[0].data, sizeof(calibrationPoints[0].data));
+ pDest += sizeof(calibrationPoints[0].data);
+}
+
+/**
+ * \brief Restore calibrate data with buffer data.
+ *
+ * \param pBuffer Data buffer.
+ * \param size Size of data buffer in bytes.
+ */
+void TSDCom_RestoreCalibrateData(void *pBuffer, uint32_t size)
+{
+ uint8_t *pSrc = (uint8_t *)pBuffer;
+
+ assert( (sizeof(bCalibrationOk) + sizeof(xSlope) +
+ sizeof(ySlope) + sizeof(calibrationPoints[0].data)) < size ) ;
+
+ memcpy((void *)&bCalibrationOk, pSrc, sizeof(bCalibrationOk));
+ pSrc += sizeof(bCalibrationOk);
+ memcpy(&xSlope, pSrc, sizeof(xSlope));
+ pSrc += sizeof(xSlope);
+ memcpy(&ySlope, pSrc, sizeof(ySlope));
+ pSrc += sizeof(ySlope);
+ memcpy(&calibrationPoints[0].data, pSrc, sizeof(calibrationPoints[0].data));
+ pSrc += sizeof(calibrationPoints[0].data);
+}
diff --git a/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/uart_console.c b/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/uart_console.c
new file mode 100644
index 00000000..1c4cbd92
--- /dev/null
+++ b/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/uart_console.c
@@ -0,0 +1,389 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * 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:
+ *
+ * - 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
+ *----------------------------------------------------------------------------*/
+
+#include "board.h"
+
+#include
+#include
+
+/*----------------------------------------------------------------------------
+ * Definitions
+ *----------------------------------------------------------------------------*/
+
+/** Console baudrate always using 115200. */
+#define CONSOLE_BAUDRATE 115200
+/** Usart Hw interface used by the console (UART0). */
+#define CONSOLE_USART UART0
+/** Usart Hw ID used by the console (UART0). */
+#define CONSOLE_ID ID_UART0
+/** Pins description corresponding to Rxd,Txd, (UART pins) */
+#define CONSOLE_PINS {PINS_UART}
+
+/*----------------------------------------------------------------------------
+ * Variables
+ *----------------------------------------------------------------------------*/
+
+/** Is Console Initialized. */
+static uint8_t _ucIsConsoleInitialized=0 ;
+
+/**
+ * \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 UART_Configure( uint32_t baudrate, uint32_t masterClock)
+{
+ const Pin pPins[] = CONSOLE_PINS;
+ Uart *pUart = CONSOLE_USART;
+
+ /* Configure PIO */
+ PIO_Configure(pPins, PIO_LISTSIZE(pPins));
+
+ /* Configure PMC */
+ PMC->PMC_PCER0 = 1 << CONSOLE_ID;
+
+ /* Reset and disable receiver & transmitter */
+ pUart->UART_CR = UART_CR_RSTRX | UART_CR_RSTTX
+ | UART_CR_RXDIS | UART_CR_TXDIS;
+
+ /* Configure mode */
+ pUart->UART_MR = UART_MR_PAR_NO;
+
+ /* Configure baudrate */
+ /* Asynchronous, no oversampling */
+ pUart->UART_BRGR = (masterClock / baudrate) / 16;
+
+ /* Disable PDC channel */
+ pUart->UART_PTCR = UART_PTCR_RXTDIS | UART_PTCR_TXTDIS;
+
+ /* Enable receiver and transmitter */
+ pUart->UART_CR = UART_CR_RXEN | UART_CR_TXEN;
+
+ _ucIsConsoleInitialized=1 ;
+}
+
+/**
+ * \brief Outputs a character on the UART line.
+ *
+ * \note This function is synchronous (i.e. uses polling).
+ * \param c Character to send.
+ */
+extern void UART_PutChar( uint8_t c )
+{
+ Uart *pUart=CONSOLE_USART ;
+
+ if ( !_ucIsConsoleInitialized )
+ {
+ UART_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 ;
+
+}
+
+/**
+ * \brief Input a character from the UART line.
+ *
+ * \note This function is synchronous
+ * \return character received.
+ */
+extern uint32_t UART_GetChar( void )
+{
+ Uart *pUart=CONSOLE_USART ;
+
+ if ( !_ucIsConsoleInitialized )
+ {
+ UART_Configure(CONSOLE_BAUDRATE, BOARD_MCK);
+ }
+
+ while ( (pUart->UART_SR & UART_SR_RXRDY) == 0 ) ;
+
+ return pUart->UART_RHR ;
+}
+
+/**
+ * \brief Check if there is Input from UART line.
+ *
+ * \return true if there is Input.
+ */
+extern uint32_t UART_IsRxReady( void )
+{
+ Uart *pUart=CONSOLE_USART ;
+
+ if ( !_ucIsConsoleInitialized )
+ {
+ UART_Configure( CONSOLE_BAUDRATE, BOARD_MCK ) ;
+ }
+
+ return (pUart->UART_SR & UART_SR_RXRDY) > 0 ;
+}
+
+/**
+ * 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 UART_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 UART_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++ )
+ {
+ UART_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++ )
+ {
+ UART_PutChar( pucBuffer[j] ) ;
+ }
+
+ printf( "\n\r" ) ;
+ }
+}
+
+/**
+ * Reads an integer
+ *
+ * \param pdwValue Pointer to the uint32_t variable to contain the input value.
+ */
+extern uint32_t UART_GetInteger( uint32_t* pdwValue )
+{
+ uint8_t ucKey ;
+ uint8_t ucNbNb=0 ;
+ uint32_t dwValue=0 ;
+
+ while ( 1 )
+ {
+ ucKey=UART_GetChar() ;
+ UART_PutChar( ucKey ) ;
+
+ if ( ucKey >= '0' && ucKey <= '9' )
+ {
+ dwValue = (dwValue * 10) + (ucKey - '0');
+ ucNbNb++ ;
+ }
+ else
+ {
+ if ( ucKey == 0x0D || ucKey == ' ' )
+ {
+ if ( ucNbNb == 0 )
+ {
+ printf( "\n\rWrite a number and press ENTER or SPACE!\n\r" ) ;
+ return 0 ;
+ }
+ else
+ {
+ printf( "\n\r" ) ;
+ *pdwValue=dwValue ;
+
+ return 1 ;
+ }
+ }
+ else
+ {
+ printf( "\n\r'%c' not a number!\n\r", ucKey ) ;
+
+ return 0 ;
+ }
+ }
+ }
+}
+
+/**
+ * Reads an integer and check the value
+ *
+ * \param pdwValue Pointer to the uint32_t variable to contain the input value.
+ * \param dwMin Minimum value
+ * \param dwMax Maximum value
+ */
+extern uint32_t UART_GetIntegerMinMax( uint32_t* pdwValue, uint32_t dwMin, uint32_t dwMax )
+{
+ uint32_t dwValue=0 ;
+
+ if ( UART_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 UART_GetHexa32( uint32_t* pdwValue )
+{
+ uint8_t ucKey ;
+ uint32_t dw = 0 ;
+ uint32_t dwValue = 0 ;
+
+ for ( dw=0 ; dw < 8 ; dw++ )
+ {
+ ucKey = UART_GetChar() ;
+ UART_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 hexa 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 )
+{
+ UART_PutChar( c ) ;
+
+ return c ;
+}
+#endif // defined __ICCARM__
+
diff --git a/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/wav.c b/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/wav.c
new file mode 100644
index 00000000..be3947bd
--- /dev/null
+++ b/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/wav.c
@@ -0,0 +1,90 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * 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:
+ *
+ * - 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"
+
+#include
+
+/*----------------------------------------------------------------------------
+ * Definiation
+ *----------------------------------------------------------------------------*/
+
+/* WAV letters "RIFF" */
+#define WAV_CHUNKID 0x46464952
+/* WAV letters "WAVE"*/
+#define WAV_FORMAT 0x45564157
+/* WAV letters "fmt "*/
+#define WAV_SUBCHUNKID 0x20746D66
+
+/*----------------------------------------------------------------------------
+ * Exported functions
+ *----------------------------------------------------------------------------*/
+
+/**
+ * \brief Check if the header of a Wav file is valid ot not.
+ *
+ * \param file Buffer holding the file to examinate.
+ * \return 1 if the header of a Wav file is valid; otherwise returns 0.
+ */
+unsigned char WAV_IsValid(const WavHeader *header)
+{
+ return ((header->chunkID == WAV_CHUNKID)
+ && (header->format == WAV_FORMAT)
+ && (header->subchunk1Size == 0x10));
+}
+
+/**
+ * \brief Display the information of the WAV file (sample rate, stereo/mono
+ * and frame size).
+ *
+ * \param header Wav head information.
+ */
+
+void WAV_DisplayInfo(const WavHeader *header)
+{
+ printf( "Wave file header information\n\r");
+ printf( "--------------------------------\n\r");
+ printf( " - Chunk ID = 0x%08X\n\r", header->chunkID);
+ printf( " - Chunk Size = %u\n\r", header->chunkSize);
+ printf( " - Format = 0x%08X\n\r", header->format);
+ printf( " - SubChunk ID = 0x%08X\n\r", header->subchunk1ID);
+ printf( " - Subchunk1 Size = %u\n\r", header->subchunk1Size);
+ printf( " - Audio Format = 0x%04X\n\r", header->audioFormat);
+ printf( " - Num. Channels = %d\n\r", header->numChannels);
+ printf( " - Sample Rate = %u\n\r", header->sampleRate);
+ printf( " - Byte Rate = %u\n\r", header->byteRate);
+ printf( " - Block Align = %d\n\r", header->blockAlign);
+ printf( " - Bits Per Sample = %d\n\r", header->bitsPerSample);
+ printf( " - Subchunk2 ID = 0x%08X\n\r", header->subchunk2ID);
+ printf( " - Subchunk2 Size = %u\n\r", header->subchunk2Size);
+}
diff --git a/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/wm8731.c b/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/wm8731.c
new file mode 100644
index 00000000..784d1c9e
--- /dev/null
+++ b/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/wm8731.c
@@ -0,0 +1,139 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * 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:
+ *
+ * - 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 WM8731 driver.
+ *
+ */
+
+/*----------------------------------------------------------------------------
+ * Headers
+ *----------------------------------------------------------------------------*/
+
+#include "board.h"
+
+/*----------------------------------------------------------------------------
+ * Exported functions
+ *----------------------------------------------------------------------------*/
+
+/**
+ * \brief Read data from WM8731 Register.
+ *
+ * \param pTwid Pointer to twi driver structure
+ * \param device Twi slave address.
+ * \param regAddr Register address to read.
+ * \return value in the given register.
+ */
+uint16_t WM8731_Read(Twid *pTwid,
+ uint32_t device,
+ uint32_t regAddr)
+{
+ uint16_t bitsDataRegister;
+ uint8_t Tdata[2]={0,0};
+
+ TWID_Read(pTwid, device, regAddr, 0, Tdata, 2, 0);
+ bitsDataRegister = (Tdata[0] << 8) | Tdata[1];
+ return bitsDataRegister;
+}
+
+/**
+ * \brief Write data to WM8731 Register.
+ *
+ * \param pTwid Pointer to twi driver structure
+ * \param device Twi slave address.
+ * \param regAddr Register address to read.
+ * \param data Data to write
+ */
+void WM8731_Write(Twid *pTwid,
+ uint32_t device,
+ uint32_t regAddr,
+ uint16_t data)
+{
+ uint8_t tmpData[2];
+ uint16_t tmp;
+ tmp = ((regAddr & 0x7f) << 9) | (data & 0x1ff);
+
+ tmpData[0] = (tmp & 0xff00) >> 8;
+ tmpData[1] = tmp & 0xff;
+ TWID_Write(pTwid, device, regAddr, 0, tmpData, 2, 0);
+}
+
+/**
+ * \brief Init WM8731 to DAC mode.
+ *
+ * \param pTwid Pointer to twi driver structure
+ * \param device Twi slave address.
+ * \return 0.
+ */
+uint8_t WM8731_DAC_Init(Twid *pTwid,
+ uint32_t device)
+{
+ /* reset */
+ WM8731_Write(pTwid, device, WM8731_REG_RESET, 0);
+
+ /* analogue audio path control */
+ WM8731_Write(pTwid, device, WM8731_REG_ANALOGUE_PATH_CTRL, 0x12);
+
+ /* digital audio path control*/
+ WM8731_Write(pTwid, device, WM8731_REG_DIGITAL_PATH_CTRL, 0x00);
+
+ /* power down control */
+ WM8731_Write(pTwid, device, WM8731_REG_PWDOWN_CTRL, 0x7);
+
+ /* Active control*/
+ WM8731_Write(pTwid, device, WM8731_REG_ACTIVE_CTRL, 0x01);
+
+ return 0;
+}
+
+/**
+ * \brief Set WM8731 volume
+ *
+ * \param pTwid Pointer to twi driver structure
+ * \param device Twi slave address.
+ * \param value Register value, valid value is between 0x30 to 0x7f
+ * \return 0.
+ */
+uint8_t WM8731_VolumeSet(Twid *pTwid,
+ uint32_t device,
+ uint16_t value)
+{
+ uint16_t regValue;
+
+ value &= WM8731_LHPVOL_BITS;
+ regValue = WM8731_LRHPBOTH_BIT | WM8731_LZCEN_BIT | value;
+ WM8731_Write(pTwid, device, WM8731_REG_LEFT_HPOUT, regValue);
+ regValue = WM8731_RZCEN_BIT | WM8731_RLHPBOTH_BIT | value;
+ WM8731_Write(pTwid, device, WM8731_REG_RIGHT_HPOUT, value);
+ return 0;
+}
+
diff --git a/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/USBD_HAL.c b/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/USBD_HAL.c
new file mode 100644
index 00000000..1bf3ac07
--- /dev/null
+++ b/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/USBD_HAL.c
@@ -0,0 +1,1666 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, 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.
+ * ----------------------------------------------------------------------------
+ */
+
+/**
+
+ \file
+
+ \section Purpose
+
+ Implementation of USB device functions on a UDP controller.
+
+ See \ref usbd_api_method USBD API Methods.
+*/
+
+/** \addtogroup usbd_hal
+ *@{*/
+
+/*---------------------------------------------------------------------------
+ * Headers
+ *---------------------------------------------------------------------------*/
+
+#include "chip.h"
+#include "USBD_HAL.h"
+
+#include
+#include
+#include
+
+/*---------------------------------------------------------------------------
+ * Definitions
+ *---------------------------------------------------------------------------*/
+
+/** Indicates chip has an UDP Full Speed. */
+#define CHIP_USB_UDP
+
+/** Indicates chip has an internal pull-up. */
+#define CHIP_USB_PULLUP_INTERNAL
+
+/** Number of USB endpoints */
+#define CHIP_USB_NUMENDPOINTS 8
+
+/** Endpoints max paxcket size */
+#define CHIP_USB_ENDPOINTS_MAXPACKETSIZE(i) \
+ ((i == 0) ? 64 : \
+ ((i == 1) ? 64 : \
+ ((i == 2) ? 64 : \
+ ((i == 3) ? 64 : \
+ ((i == 4) ? 512 : \
+ ((i == 5) ? 512 : \
+ ((i == 6) ? 64 : \
+ ((i == 7) ? 64 : 0 ))))))))
+
+/** Endpoints Number of Bank */
+#define CHIP_USB_ENDPOINTS_BANKS(i) \
+ ((i == 0) ? 1 : \
+ ((i == 1) ? 2 : \
+ ((i == 2) ? 2 : \
+ ((i == 3) ? 1 : \
+ ((i == 4) ? 2 : \
+ ((i == 5) ? 2 : \
+ ((i == 6) ? 2 : \
+ ((i == 7) ? 2 : 0 ))))))))
+
+/**
+ * \section UDP_registers_sec "UDP Register field values"
+ *
+ * This section lists the initialize values of UDP registers.
+ *
+ * \subsection Values
+ * - UDP_RXDATA
+ */
+/** Bit mask for both banks of the UDP_CSR register. */
+#define UDP_CSR_RXDATA_BK (UDP_CSR_RX_DATA_BK0 | UDP_CSR_RX_DATA_BK1)
+
+/**
+ * \section endpoint_states_sec "UDP Endpoint states"
+ *
+ * This page lists the endpoint states.
+ *
+ * \subsection States
+ * - UDP_ENDPOINT_DISABLED
+ * - UDP_ENDPOINT_HALTED
+ * - UDP_ENDPOINT_IDLE
+ * - UDP_ENDPOINT_SENDING
+ * - UDP_ENDPOINT_RECEIVING
+ * - UDP_ENDPOINT_SENDINGM
+ * - UDP_ENDPOINT_RECEIVINGM
+ */
+
+/** Endpoint states: Endpoint is disabled */
+#define UDP_ENDPOINT_DISABLED 0
+/** Endpoint states: Endpoint is halted (i.e. STALLs every request) */
+#define UDP_ENDPOINT_HALTED 1
+/** Endpoint states: Endpoint is idle (i.e. ready for transmission) */
+#define UDP_ENDPOINT_IDLE 2
+/** Endpoint states: Endpoint is sending data */
+#define UDP_ENDPOINT_SENDING 3
+/** Endpoint states: Endpoint is receiving data */
+#define UDP_ENDPOINT_RECEIVING 4
+/** Endpoint states: Endpoint is sending MBL */
+#define UDP_ENDPOINT_SENDINGM 5
+/** Endpoint states: Endpoint is receiving MBL */
+#define UDP_ENDPOINT_RECEIVINGM 6
+
+/**
+ * \section udp_csr_register_access_sec "UDP CSR register access"
+ *
+ * This page lists the macros to access UDP CSR register.
+ *
+ * \comment
+ * In a preemptive environment, set or clear the flag and wait for a time of
+ * 1 UDPCK clock cycle and 1 peripheral clock cycle. However, RX_DATA_BK0,
+ * TXPKTRDY, RX_DATA_BK1 require wait times of 3 UDPCK clock cycles and
+ * 5 peripheral clock cycles before accessing DPR.
+ * See datasheet
+ *
+ * !Macros
+ * - CLEAR_CSR
+ * - SET_CSR
+ */
+
+#if defined ( __CC_ARM )
+ #define nop() {volatile int h; for(h=0;h<10;h++){}}
+#elif defined ( __ICCARM__ )
+ #include
+ #define nop() (__no_operation())
+#elif defined ( __GNUC__ )
+ #define nop() __asm__ __volatile__ ( "nop" )
+#endif
+
+
+/** Bitmap for all status bits in CSR. */
+#define REG_NO_EFFECT_1_ALL UDP_CSR_RX_DATA_BK0 | UDP_CSR_RX_DATA_BK1 \
+ |UDP_CSR_STALLSENTISOERROR | UDP_CSR_RXSETUP \
+ |UDP_CSR_TXCOMP
+
+/**
+ * Sets the specified bit(s) in the UDP_CSR register.
+ *
+ * \param endpoint The endpoint number of the CSR to process.
+ * \param flags The bitmap to set to 1.
+ */
+#define SET_CSR(endpoint, flags) \
+ { \
+ volatile uint32_t reg; \
+ int32_t nop_count ; \
+ reg = UDP->UDP_CSR[endpoint] ; \
+ reg |= REG_NO_EFFECT_1_ALL; \
+ reg |= (flags); \
+ UDP->UDP_CSR[endpoint] = reg; \
+ for( nop_count=0; nop_count<15; nop_count++ ) {\
+ nop();\
+ }\
+ }
+
+/**
+ * Clears the specified bit(s) in the UDP_CSR register.
+ *
+ * \param endpoint The endpoint number of the CSR to process.
+ * \param flags The bitmap to clear to 0.
+ */
+#define CLEAR_CSR(endpoint, flags) \
+{ \
+ volatile uint32_t reg; \
+ int32_t nop_count ; \
+ reg = UDP->UDP_CSR[endpoint]; \
+ reg |= REG_NO_EFFECT_1_ALL; \
+ reg &= ~((uint32_t)(flags)); \
+ UDP->UDP_CSR[endpoint] = reg; \
+ for( nop_count=0; nop_count<15; nop_count++ ) {\
+ nop();\
+ }\
+}
+
+
+/** Get Number of buffer in Multi-Buffer-List
+ * \param i input index
+ * \param o output index
+ * \param size list size
+ */
+#define MBL_NbBuffer(i, o, size) (((i)>(o))?((i)-(o)):((i)+(size)-(o)))
+
+/** Buffer list is full */
+#define MBL_FULL 1
+/** Buffer list is null */
+#define MBL_NULL 2
+
+/*---------------------------------------------------------------------------
+ * Types
+ *---------------------------------------------------------------------------*/
+
+/** Describes header for UDP endpoint transfer. */
+typedef struct {
+ /** Optional callback to invoke when the transfer completes. */
+ void* fCallback;
+ /** Optional argument to the callback function. */
+ void* pArgument;
+ /** Transfer type */
+ uint8_t transType;
+} TransferHeader;
+
+/** Describes a transfer on a UDP endpoint. */
+typedef struct {
+
+ /** Optional callback to invoke when the transfer completes. */
+ TransferCallback fCallback;
+ /** Optional argument to the callback function. */
+ void *pArgument;
+ /** Transfer type */
+ uint16_t transType;
+ /** Number of bytes which have been written into the UDP internal FIFO
+ * buffers. */
+ int16_t buffered;
+ /** Pointer to a data buffer used for emission/reception. */
+ uint8_t *pData;
+ /** Number of bytes which have been sent/received. */
+ int32_t transferred;
+ /** Number of bytes which have not been buffered/transferred yet. */
+ int32_t remaining;
+} Transfer;
+
+/** Describes Multi Buffer List transfer on a UDP endpoint. */
+typedef struct {
+ /** Optional callback to invoke when the transfer completes. */
+ MblTransferCallback fCallback;
+ /** Optional argument to the callback function. */
+ void *pArgument;
+ /** Transfer type */
+ volatile uint8_t transType;
+ /** List state (OK, FULL, NULL) (run time) */
+ uint8_t listState;
+ /** Multi-Buffer List size */
+ uint16_t listSize;
+ /** Pointer to multi-buffer list */
+ USBDTransferBuffer *pMbl;
+ /** Offset number of buffers to start transfer */
+ uint16_t offsetSize;
+ /** Current processing buffer index (run time) */
+ uint16_t outCurr;
+ /** Loast loaded buffer index (run time) */
+ uint16_t outLast;
+ /** Current buffer for input (run time) */
+ uint16_t inCurr;
+} MblTransfer;
+
+/**
+ * Describes the state of an endpoint of the UDP controller.
+ */
+typedef struct {
+
+ /* CSR */
+ //uint32_t CSR;
+ /** Current endpoint state. */
+ volatile uint8_t state;
+ /** Current reception bank (0 or 1). */
+ volatile uint8_t bank;
+ /** Maximum packet size for the endpoint. */
+ volatile uint16_t size;
+ /** Describes an ongoing transfer (if current state is either
+ * UDP_ENDPOINT_SENDING or UDP_ENDPOINT_RECEIVING) */
+ union {
+ TransferHeader transHdr;
+ Transfer singleTransfer;
+ MblTransfer mblTransfer;
+ } transfer;
+} Endpoint;
+
+/*---------------------------------------------------------------------------
+ * Internal variables
+ *---------------------------------------------------------------------------*/
+
+/** Holds the internal state for each endpoint of the UDP. */
+static Endpoint endpoints[CHIP_USB_NUMENDPOINTS];
+
+/*---------------------------------------------------------------------------
+ * Internal Functions
+ *---------------------------------------------------------------------------*/
+
+/**
+ * Enables the clock of the UDP peripheral.
+ * \return 1 if peripheral status changed.
+ */
+static uint8_t UDP_EnablePeripheralClock(void)
+{
+ if (!PMC_IsPeriphEnabled(ID_UDP)) {
+ PMC_EnablePeripheral(ID_UDP);
+ return 1;
+ }
+ return 0;
+}
+
+/**
+ * Disables the UDP peripheral clock.
+ */
+static inline void UDP_DisablePeripheralClock(void)
+{
+ PMC_DisablePeripheral(ID_UDP);
+}
+
+/**
+ * Enables the 48MHz USB clock.
+ */
+static inline void UDP_EnableUsbClock(void)
+{
+ REG_PMC_SCER = PMC_SCER_UDP;
+}
+
+/**
+ * Disables the 48MHz USB clock.
+ */
+static inline void UDP_DisableUsbClock(void)
+{
+ REG_PMC_SCDR = PMC_SCER_UDP;
+}
+
+/**
+ * Enables the UDP transceiver.
+ */
+static inline void UDP_EnableTransceiver(void)
+{
+ UDP->UDP_TXVC &= ~(uint32_t)UDP_TXVC_TXVDIS;
+}
+
+/**
+ * Disables the UDP transceiver.
+ */
+static inline void UDP_DisableTransceiver(void)
+{
+ UDP->UDP_TXVC |= UDP_TXVC_TXVDIS;
+}
+
+/**
+ * Handles a completed transfer on the given endpoint, invoking the
+ * configured callback if any.
+ * \param bEndpoint Number of the endpoint for which the transfer has completed.
+ * \param bStatus Status code returned by the transfer operation
+ */
+static void UDP_EndOfTransfer(uint8_t bEndpoint, uint8_t bStatus)
+{
+ Endpoint *pEndpoint = &(endpoints[bEndpoint]);
+
+ // Check that endpoint was sending or receiving data
+ if( (pEndpoint->state == UDP_ENDPOINT_RECEIVING)
+ || (pEndpoint->state == UDP_ENDPOINT_SENDING)) {
+
+ Transfer *pTransfer = (Transfer *)&(pEndpoint->transfer);
+ uint32_t transferred = pTransfer->transferred;
+ uint32_t remaining = pTransfer->remaining + pTransfer->buffered;
+
+ TRACE_DEBUG_WP("EoT ");
+
+ /* Endpoint returns in Idle state */
+ pEndpoint->state = UDP_ENDPOINT_IDLE;
+ /* Reset descriptor values */
+ pTransfer->pData = 0;
+ pTransfer->transferred = -1;
+ pTransfer->buffered = -1;
+ pTransfer->remaining = -1;
+
+ // Invoke callback is present
+ if (pTransfer->fCallback != 0) {
+
+ ((TransferCallback) pTransfer->fCallback)
+ (pTransfer->pArgument,
+ bStatus,
+ transferred,
+ remaining);
+ }
+ else {
+ TRACE_DEBUG_WP("NoCB ");
+ }
+ }
+ else if ( (pEndpoint->state == UDP_ENDPOINT_RECEIVINGM)
+ || (pEndpoint->state == UDP_ENDPOINT_SENDINGM) ) {
+
+ MblTransfer *pTransfer = (MblTransfer*)&(pEndpoint->transfer);
+
+ TRACE_DEBUG_WP("EoMT ");
+
+ /* Endpoint returns in Idle state */
+ pEndpoint->state = UDP_ENDPOINT_IDLE;
+ /* Reset transfer descriptor */
+ if (pTransfer->transType) {
+ MblTransfer *pMblt = (MblTransfer*)&(pEndpoint->transfer);
+ pMblt->listState = 0;
+ pMblt->outCurr = pMblt->inCurr = pMblt->outLast = 0;
+ }
+ /* Invoke callback */
+ if (pTransfer->fCallback != 0) {
+
+ ((MblTransferCallback) pTransfer->fCallback)
+ (pTransfer->pArgument,
+ bStatus);
+ }
+ else {
+ TRACE_DEBUG_WP("NoCB ");
+ }
+ }
+}
+
+/**
+ * Clears the correct reception flag (bank 0 or bank 1) of an endpoint
+ * \param bEndpoint Index of endpoint
+ */
+static void UDP_ClearRxFlag(uint8_t bEndpoint)
+{
+ Endpoint *pEndpoint = &(endpoints[bEndpoint]);
+
+ // Clear flag and change banks
+ if (pEndpoint->bank == 0) {
+
+ CLEAR_CSR(bEndpoint, UDP_CSR_RX_DATA_BK0);
+ // Swap bank if in dual-fifo mode
+ if (CHIP_USB_ENDPOINTS_BANKS(bEndpoint) > 1) {
+
+ pEndpoint->bank = 1;
+ }
+ }
+ else {
+
+ CLEAR_CSR(bEndpoint, UDP_CSR_RX_DATA_BK1);
+ pEndpoint->bank = 0;
+ }
+}
+
+/**
+ * Update multi-buffer-transfer descriptors.
+ * \param pTransfer Pointer to instance MblTransfer.
+ * \param size Size of bytes that processed.
+ * \param forceEnd Force the buffer END.
+ * \return 1 if current buffer ended.
+ */
+static uint8_t UDP_MblUpdate(MblTransfer *pTransfer,
+ USBDTransferBuffer * pBi,
+ uint16_t size,
+ uint8_t forceEnd)
+{
+ /* Update transfer descriptor */
+ pBi->remaining -= size;
+ /* Check if list NULL */
+ if (pTransfer->listState == MBL_NULL) {
+ return 1;
+ }
+ /* Check if current buffer ended */
+ if (pBi->remaining == 0 || forceEnd || size == 0) {
+
+ /* Process to next buffer */
+ if ((++ pTransfer->outCurr) == pTransfer->listSize)
+ pTransfer->outCurr = 0;
+ /* Check buffer NULL case */
+ if (pTransfer->outCurr == pTransfer->inCurr)
+ pTransfer->listState = MBL_NULL;
+ else {
+ pTransfer->listState = 0;
+ /* Continue transfer, prepare for next operation */
+ pBi = &pTransfer->pMbl[pTransfer->outCurr];
+ pBi->buffered = 0;
+ pBi->transferred = 0;
+ pBi->remaining = pBi->size;
+ }
+ return 1;
+ }
+ return 0;
+}
+
+/**
+ * Transfers a data payload from the current tranfer buffer to the endpoint
+ * FIFO
+ * \param bEndpoint Number of the endpoint which is sending data.
+ */
+static uint8_t UDP_MblWriteFifo(uint8_t bEndpoint)
+{
+ Endpoint *pEndpoint = &(endpoints[bEndpoint]);
+ MblTransfer *pTransfer = (MblTransfer*)&(pEndpoint->transfer);
+ USBDTransferBuffer *pBi = &(pTransfer->pMbl[pTransfer->outCurr]);
+ int32_t size;
+
+ volatile uint8_t * pBytes;
+ volatile uint8_t bufferEnd = 1;
+
+ /* Get the number of bytes to send */
+ size = pEndpoint->size;
+ if (size > pBi->remaining) size = pBi->remaining;
+
+ TRACE_DEBUG_WP("w%d.%d ", pTransfer->outCurr, size);
+
+ /* Record last accessed buffer */
+ pTransfer->outLast = pTransfer->outCurr;
+
+ pBytes = &(pBi->pBuffer[pBi->transferred + pBi->buffered]);
+ pBi->buffered += size;
+ bufferEnd = UDP_MblUpdate(pTransfer, pBi, size, 0);
+
+ /* Write packet in the FIFO buffer */
+ if (size) {
+ int32_t c8 = size >> 3;
+ int32_t c1 = size & 0x7;
+ for (; c8; c8 --) {
+ UDP->UDP_FDR[bEndpoint] = *(pBytes ++);
+ UDP->UDP_FDR[bEndpoint] = *(pBytes ++);
+ UDP->UDP_FDR[bEndpoint] = *(pBytes ++);
+ UDP->UDP_FDR[bEndpoint] = *(pBytes ++);
+
+ UDP->UDP_FDR[bEndpoint] = *(pBytes ++);
+ UDP->UDP_FDR[bEndpoint] = *(pBytes ++);
+ UDP->UDP_FDR[bEndpoint] = *(pBytes ++);
+ UDP->UDP_FDR[bEndpoint] = *(pBytes ++);
+ }
+ for (; c1; c1 --) {
+ UDP->UDP_FDR[bEndpoint] = *(pBytes ++);
+ }
+ }
+ return bufferEnd;
+}
+
+/**
+ * Transfers a data payload from the current tranfer buffer to the endpoint
+ * FIFO
+ * \param bEndpoint Number of the endpoint which is sending data.
+ */
+static void UDP_WritePayload(uint8_t bEndpoint)
+{
+ Endpoint *pEndpoint = &(endpoints[bEndpoint]);
+ Transfer *pTransfer = (Transfer*)&(pEndpoint->transfer);
+ int32_t size;
+
+ // Get the number of bytes to send
+ size = pEndpoint->size;
+ if (size > pTransfer->remaining) {
+
+ size = pTransfer->remaining;
+ }
+
+ // Update transfer descriptor information
+ pTransfer->buffered += size;
+ pTransfer->remaining -= size;
+
+ // Write packet in the FIFO buffer
+ while (size > 0) {
+
+ UDP->UDP_FDR[bEndpoint] = *(pTransfer->pData);
+ pTransfer->pData++;
+ size--;
+ }
+}
+
+
+/**
+ * Transfers a data payload from an endpoint FIFO to the current transfer buffer
+ * \param bEndpoint Endpoint number.
+ * \param wPacketSize Size of received data packet
+ */
+static void UDP_ReadPayload(uint8_t bEndpoint, int32_t wPacketSize)
+{
+ Endpoint *pEndpoint = &(endpoints[bEndpoint]);
+ Transfer *pTransfer = (Transfer*)&(pEndpoint->transfer);
+
+ // Check that the requested size is not bigger than the remaining transfer
+ if (wPacketSize > pTransfer->remaining) {
+
+ pTransfer->buffered += wPacketSize - pTransfer->remaining;
+ wPacketSize = pTransfer->remaining;
+ }
+
+ // Update transfer descriptor information
+ pTransfer->remaining -= wPacketSize;
+ pTransfer->transferred += wPacketSize;
+
+ // Retrieve packet
+ while (wPacketSize > 0) {
+
+ *(pTransfer->pData) = (uint8_t) UDP->UDP_FDR[bEndpoint];
+ pTransfer->pData++;
+ wPacketSize--;
+ }
+}
+
+/**
+ * Received SETUP packet from endpoint 0 FIFO
+ * \param pRequest Generic USB SETUP request sent over Control endpoints
+ */
+static void UDP_ReadRequest(USBGenericRequest *pRequest)
+{
+ uint8_t *pData = (uint8_t *)pRequest;
+ uint32_t i;
+
+ // Copy packet
+ for (i = 0; i < 8; i++) {
+
+ *pData = (uint8_t) UDP->UDP_FDR[0];
+ pData++;
+ }
+}
+
+/**
+ * Checks if an ongoing transfer on an endpoint has been completed.
+ * \param bEndpoint Endpoint number.
+ * \return 1 if the current transfer on the given endpoint is complete;
+ * otherwise 0.
+ */
+static uint8_t UDP_IsTransferFinished(uint8_t bEndpoint)
+{
+ Endpoint *pEndpoint = &(endpoints[bEndpoint]);
+ Transfer *pTransfer = (Transfer*)&(pEndpoint->transfer);
+
+ // Check if it is a Control endpoint
+ // -> Control endpoint must always finish their transfer with a zero-length
+ // packet
+ if ((UDP->UDP_CSR[bEndpoint] & UDP_CSR_EPTYPE_Msk) == UDP_CSR_EPTYPE_CTRL) {
+
+ return (pTransfer->buffered < pEndpoint->size);
+ }
+ // Other endpoints only need to transfer all the data
+ else {
+
+ return (pTransfer->buffered <= pEndpoint->size)
+ && (pTransfer->remaining == 0);
+ }
+}
+
+/**
+ * Endpoint interrupt handler.
+ * Handle IN/OUT transfers, received SETUP packets and STALLing
+ * \param bEndpoint Index of endpoint
+ */
+static void UDP_EndpointHandler(uint8_t bEndpoint)
+{
+ Endpoint *pEndpoint = &(endpoints[bEndpoint]);
+ Transfer *pTransfer = (Transfer*)&(pEndpoint->transfer);
+ MblTransfer *pMblt = (MblTransfer*)&(pEndpoint->transfer);
+ uint32_t status = UDP->UDP_CSR[bEndpoint];
+ uint16_t wPacketSize;
+ USBGenericRequest request;
+
+ TRACE_DEBUG_WP("E%d ", bEndpoint);
+ TRACE_DEBUG_WP("st:0x%X ", status);
+
+ // Handle interrupts
+ // IN packet sent
+ if ((status & UDP_CSR_TXCOMP) != 0) {
+
+ TRACE_DEBUG_WP("Wr ");
+
+ // Check that endpoint was in MBL Sending state
+ if (pEndpoint->state == UDP_ENDPOINT_SENDINGM) {
+
+ USBDTransferBuffer * pMbli = &(pMblt->pMbl[pMblt->outLast]);
+ uint8_t bufferEnd = 0;
+
+ TRACE_DEBUG_WP("TxM%d.%d ", pMblt->listState, pMbli->buffered);
+
+ // End of transfer ?
+ if (pMblt->listState == MBL_NULL && pMbli->buffered == 0) {
+
+ pMbli->transferred += pMbli->buffered;
+ pMbli->buffered = 0;
+
+ // Disable interrupt
+ UDP->UDP_IDR = 1 << bEndpoint;
+ UDP_EndOfTransfer(bEndpoint, USBD_STATUS_SUCCESS);
+ CLEAR_CSR(bEndpoint, UDP_CSR_TXCOMP);
+ }
+ else {
+
+ // Transfer remaining data
+ TRACE_DEBUG_WP("%d ", pEndpoint->size);
+
+ if (pMbli->buffered > pEndpoint->size) {
+ pMbli->transferred += pEndpoint->size;
+ pMbli->buffered -= pEndpoint->size;
+ }
+ else {
+ pMbli->transferred += pMbli->buffered;
+ pMbli->buffered = 0;
+ }
+
+ // Send next packet
+ if (CHIP_USB_ENDPOINTS_BANKS(bEndpoint) == 1) {
+
+ // No double buffering
+ bufferEnd = UDP_MblWriteFifo(bEndpoint);
+ SET_CSR(bEndpoint, UDP_CSR_TXPKTRDY);
+ CLEAR_CSR(bEndpoint, UDP_CSR_TXCOMP);
+ }
+ else {
+ // Double buffering
+ SET_CSR(bEndpoint, UDP_CSR_TXPKTRDY);
+ CLEAR_CSR(bEndpoint, UDP_CSR_TXCOMP);
+ bufferEnd = UDP_MblWriteFifo(bEndpoint);
+ }
+
+ if (bufferEnd && pMblt->fCallback) {
+ ((MblTransferCallback) pTransfer->fCallback)
+ (pTransfer->pArgument,
+ USBD_STATUS_PARTIAL_DONE);
+ }
+ }
+ }
+ // Check that endpoint was in Sending state
+ else if (pEndpoint->state == UDP_ENDPOINT_SENDING) {
+
+ // End of transfer ?
+ if (UDP_IsTransferFinished(bEndpoint)) {
+
+ pTransfer->transferred += pTransfer->buffered;
+ pTransfer->buffered = 0;
+
+ // Disable interrupt if this is not a control endpoint
+ if ((status & UDP_CSR_EPTYPE_Msk) != UDP_CSR_EPTYPE_CTRL) {
+
+ UDP->UDP_IDR = 1 << bEndpoint;
+ }
+
+ UDP_EndOfTransfer(bEndpoint, USBD_STATUS_SUCCESS);
+ CLEAR_CSR(bEndpoint, UDP_CSR_TXCOMP);
+ }
+ else {
+
+ // Transfer remaining data
+ TRACE_DEBUG_WP(" %d ", pEndpoint->size);
+
+ pTransfer->transferred += pEndpoint->size;
+ pTransfer->buffered -= pEndpoint->size;
+
+ // Send next packet
+ if (CHIP_USB_ENDPOINTS_BANKS(bEndpoint) == 1) {
+
+ // No double buffering
+ UDP_WritePayload(bEndpoint);
+ SET_CSR(bEndpoint, UDP_CSR_TXPKTRDY);
+ CLEAR_CSR(bEndpoint, UDP_CSR_TXCOMP);
+ }
+ else {
+ // Double buffering
+ SET_CSR(bEndpoint, UDP_CSR_TXPKTRDY);
+ CLEAR_CSR(bEndpoint, UDP_CSR_TXCOMP);
+ UDP_WritePayload(bEndpoint);
+ }
+ }
+ }
+ else {
+ // Acknowledge interrupt
+ TRACE_ERROR("Error Wr%d, %x\n\r", bEndpoint, pEndpoint->state);
+ CLEAR_CSR(bEndpoint, UDP_CSR_TXCOMP);
+ }
+ }
+
+ // OUT packet received
+ if ((status & UDP_CSR_RXDATA_BK) != 0) {
+
+ TRACE_DEBUG_WP("Rd ");
+
+ // Check that the endpoint is in Receiving state
+ if (pEndpoint->state != UDP_ENDPOINT_RECEIVING) {
+
+ // Check if an ACK has been received on a Control endpoint
+ if (((status & UDP_CSR_EPTYPE_Msk) == UDP_CSR_EPTYPE_CTRL)
+ && ((status & UDP_CSR_RXBYTECNT_Msk) == 0)) {
+
+ // Acknowledge the data and finish the current transfer
+ UDP_ClearRxFlag(bEndpoint);
+ UDP_EndOfTransfer(bEndpoint, USBD_STATUS_SUCCESS);
+ }
+ // Check if the data has been STALLed
+ else if ((status & UDP_CSR_FORCESTALL) != 0) {
+
+ // Discard STALLed data
+ TRACE_DEBUG_WP("Discard ");
+ UDP_ClearRxFlag(bEndpoint);
+ }
+ // NAK the data
+ else {
+
+ TRACE_DEBUG_WP("Nak ");
+ UDP->UDP_IDR = 1 << bEndpoint;
+ }
+ }
+ // Endpoint is in Read state
+ else {
+
+ // Retrieve data and store it into the current transfer buffer
+ wPacketSize = (uint16_t) (status >> 16);
+ TRACE_DEBUG_WP("%d ", wPacketSize);
+ UDP_ReadPayload(bEndpoint, wPacketSize);
+ UDP_ClearRxFlag(bEndpoint);
+
+ // Check if the transfer is finished
+ if ((pTransfer->remaining == 0) || (wPacketSize < pEndpoint->size)) {
+
+ // Disable interrupt if this is not a control endpoint
+ if ((status & UDP_CSR_EPTYPE_Msk) != UDP_CSR_EPTYPE_CTRL) {
+
+ UDP->UDP_IDR = 1 << bEndpoint;
+ }
+ UDP_EndOfTransfer(bEndpoint, USBD_STATUS_SUCCESS);
+ }
+ }
+ }
+
+ // STALL sent
+ if ((status & UDP_CSR_STALLSENTISOERROR) != 0) {
+
+ CLEAR_CSR(bEndpoint, UDP_CSR_STALLSENTISOERROR);
+
+ if ( (status & UDP_CSR_EPTYPE_Msk) == UDP_CSR_EPTYPE_ISO_IN
+ || (status & UDP_CSR_EPTYPE_Msk) == UDP_CSR_EPTYPE_ISO_OUT ) {
+
+ TRACE_WARNING("Isoe [%d] ", bEndpoint);
+ UDP_EndOfTransfer(bEndpoint, USBD_STATUS_ABORTED);
+ }
+ else {
+
+ TRACE_WARNING("Sta 0x%X [%d] ", (int)status, bEndpoint);
+
+ if (pEndpoint->state != UDP_ENDPOINT_HALTED) {
+
+ TRACE_WARNING( "_ " );
+ // If the endpoint is not halted, clear the STALL condition
+ CLEAR_CSR(bEndpoint, UDP_CSR_FORCESTALL);
+ }
+ }
+ }
+
+ // SETUP packet received
+ if ((status & UDP_CSR_RXSETUP) != 0) {
+
+ TRACE_DEBUG_WP("Stp ");
+
+ // If a transfer was pending, complete it
+ // Handles the case where during the status phase of a control write
+ // transfer, the host receives the device ZLP and ack it, but the ack
+ // is not received by the device
+ if ((pEndpoint->state == UDP_ENDPOINT_RECEIVING)
+ || (pEndpoint->state == UDP_ENDPOINT_SENDING)) {
+
+ UDP_EndOfTransfer(bEndpoint, USBD_STATUS_SUCCESS);
+ }
+ // Copy the setup packet
+ UDP_ReadRequest(&request);
+
+ // Set the DIR bit before clearing RXSETUP in Control IN sequence
+ if (USBGenericRequest_GetDirection(&request) == USBGenericRequest_IN) {
+
+ SET_CSR(bEndpoint, UDP_CSR_DIR);
+ }
+ // Acknowledge setup packet
+ CLEAR_CSR(bEndpoint, UDP_CSR_RXSETUP);
+
+ // Forward the request to the upper layer
+ USBD_RequestHandler(0, &request);
+ }
+
+}
+
+/**
+ * Sends data through a USB endpoint. Sets up the transfer descriptor,
+ * writes one or two data payloads (depending on the number of FIFO bank
+ * for the endpoint) and then starts the actual transfer. The operation is
+ * complete when all the data has been sent.
+ *
+ * *If the size of the buffer is greater than the size of the endpoint
+ * (or twice the size if the endpoint has two FIFO banks), then the buffer
+ * must be kept allocated until the transfer is finished*. This means that
+ * it is not possible to declare it on the stack (i.e. as a local variable
+ * of a function which returns after starting a transfer).
+ *
+ * \param pEndpoint Pointer to Endpoint struct.
+ * \param pData Pointer to a buffer with the data to send.
+ * \param dLength Size of the data buffer.
+ * \return USBD_STATUS_SUCCESS if the transfer has been started;
+ * otherwise, the corresponding error status code.
+ */
+static inline uint8_t UDP_Write(uint8_t bEndpoint,
+ const void *pData,
+ uint32_t dLength)
+{
+ Endpoint *pEndpoint = &(endpoints[bEndpoint]);
+ Transfer *pTransfer = (Transfer*)&(pEndpoint->transfer);
+
+ /* Check that the endpoint is in Idle state */
+ if (pEndpoint->state != UDP_ENDPOINT_IDLE) {
+
+ return USBD_STATUS_LOCKED;
+ }
+ TRACE_DEBUG_WP("Write%d(%d) ", bEndpoint, dLength);
+
+ /* Setup the transfer descriptor */
+ pTransfer->pData = (void *) pData;
+ pTransfer->remaining = dLength;
+ pTransfer->buffered = 0;
+ pTransfer->transferred = 0;
+
+ /* Send the first packet */
+ pEndpoint->state = UDP_ENDPOINT_SENDING;
+ while((UDP->UDP_CSR[bEndpoint]&UDP_CSR_TXPKTRDY)==UDP_CSR_TXPKTRDY);
+ UDP_WritePayload(bEndpoint);
+ SET_CSR(bEndpoint, UDP_CSR_TXPKTRDY);
+
+ /* If double buffering is enabled and there is data remaining,
+ prepare another packet */
+ if ((CHIP_USB_ENDPOINTS_BANKS(bEndpoint) > 1) && (pTransfer->remaining > 0)) {
+
+ UDP_WritePayload(bEndpoint);
+ }
+
+ /* Enable interrupt on endpoint */
+ UDP->UDP_IER = 1 << bEndpoint;
+
+ return USBD_STATUS_SUCCESS;
+}
+
+/**
+ * Sends data through a USB endpoint. Sets up the transfer descriptor list,
+ * writes one or two data payloads (depending on the number of FIFO bank
+ * for the endpoint) and then starts the actual transfer. The operation is
+ * complete when all the transfer buffer in the list has been sent.
+ *
+ * *If the size of the buffer is greater than the size of the endpoint
+ * (or twice the size if the endpoint has two FIFO banks), then the buffer
+ * must be kept allocated until the transfer is finished*. This means that
+ * it is not possible to declare it on the stack (i.e. as a local variable
+ * of a function which returns after starting a transfer).
+ *
+ * \param pEndpoint Pointer to Endpoint struct.
+ * \param pData Pointer to a buffer with the data to send.
+ * \param dLength Size of the data buffer.
+ * \return USBD_STATUS_SUCCESS if the transfer has been started;
+ * otherwise, the corresponding error status code.
+ */
+static inline uint8_t UDP_AddWr(uint8_t bEndpoint,
+ const void *pData,
+ uint32_t dLength)
+{
+ Endpoint *pEndpoint = &(endpoints[bEndpoint]);
+ MblTransfer *pMbl = (MblTransfer*)&(pEndpoint->transfer);
+ USBDTransferBuffer *pTx;
+
+ /* Check parameter */
+ if (dLength >= 0x10000)
+ return USBD_STATUS_INVALID_PARAMETER;
+
+ /* Data in progressing */
+ if (pEndpoint->state > UDP_ENDPOINT_IDLE) {
+ /* If list full */
+ if (pMbl->listState == MBL_FULL) {
+ return USBD_STATUS_LOCKED;
+ }
+ }
+
+ TRACE_DEBUG_WP("AddW%d(%d) ", bEndpoint, dLength);
+
+ /* Add buffer to buffer list and update index */
+ pTx = &(pMbl->pMbl[pMbl->inCurr]);
+ pTx->pBuffer = (uint8_t*)pData;
+ pTx->size = pTx->remaining = dLength;
+ pTx->transferred = pTx->buffered = 0;
+ /* Update input index */
+ if (pMbl->inCurr >= (pMbl->listSize-1)) pMbl->inCurr = 0;
+ else pMbl->inCurr ++;
+ if (pMbl->inCurr == pMbl->outCurr) pMbl->listState = MBL_FULL;
+ else pMbl->listState = 0;
+ /* Start sending when offset achieved */
+ if (MBL_NbBuffer(pMbl->inCurr, pMbl->outCurr, pMbl->listSize)
+ >= pMbl->offsetSize
+ && pEndpoint->state == UDP_ENDPOINT_IDLE) {
+ TRACE_DEBUG_WP("StartT ");
+ /* Change state */
+ pEndpoint->state = UDP_ENDPOINT_SENDINGM;
+ while((UDP->UDP_CSR[bEndpoint]&UDP_CSR_TXPKTRDY)==UDP_CSR_TXPKTRDY);
+ /* Send first packet */
+ UDP_MblWriteFifo(bEndpoint);
+ SET_CSR(bEndpoint, UDP_CSR_TXPKTRDY);
+ /* If double buffering is enabled and there is remaining, continue */
+ if ((CHIP_USB_ENDPOINTS_BANKS(bEndpoint) > 1)
+ && pMbl->pMbl[pMbl->outCurr].remaining) {
+ UDP_MblWriteFifo(bEndpoint);
+ }
+ /* Enable interrupt on endpoint */
+ UDP->UDP_IER = 1 << bEndpoint;
+ }
+
+ return USBD_STATUS_SUCCESS;
+}
+
+/**
+ * Reads incoming data on an USB endpoint This methods sets the transfer
+ * descriptor and activate the endpoint interrupt. The actual transfer is
+ * then carried out by the endpoint interrupt handler. The Read operation
+ * finishes either when the buffer is full, or a short packet (inferior to
+ * endpoint maximum size) is received.
+ *
+ * *The buffer must be kept allocated until the transfer is finished*.
+ * \param bEndpoint Endpoint number.
+ * \param pData Pointer to a data buffer.
+ * \param dLength Size of the data buffer in bytes.
+ * \return USBD_STATUS_SUCCESS if the read operation has been started;
+ * otherwise, the corresponding error code.
+ */
+static inline uint8_t UDP_Read(uint8_t bEndpoint,
+ void *pData,
+ uint32_t dLength)
+{
+ Endpoint *pEndpoint = &(endpoints[bEndpoint]);
+ Transfer *pTransfer = (Transfer*)&(pEndpoint->transfer);
+
+ /* Return if the endpoint is not in IDLE state */
+ if (pEndpoint->state != UDP_ENDPOINT_IDLE) {
+
+ return USBD_STATUS_LOCKED;
+ }
+
+ /* Endpoint enters Receiving state */
+ pEndpoint->state = UDP_ENDPOINT_RECEIVING;
+ TRACE_DEBUG_WP("Read%d(%d) ", bEndpoint, dLength);
+
+ /* Set the transfer descriptor */
+ pTransfer->pData = pData;
+ pTransfer->remaining = dLength;
+ pTransfer->buffered = 0;
+ pTransfer->transferred = 0;
+
+ /* Enable interrupt on endpoint */
+ UDP->UDP_IER = 1 << bEndpoint;
+
+ return USBD_STATUS_SUCCESS;
+}
+
+
+/*---------------------------------------------------------------------------
+ * Exported functions
+ *---------------------------------------------------------------------------*/
+
+/**
+ * USBD (UDP) interrupt handler
+ * Manages device resume, suspend, end of bus reset.
+ * Forwards endpoint events to the appropriate handler.
+ */
+void USBD_IrqHandler(void)
+{
+ uint32_t status;
+ int32_t eptnum = 0;
+
+ /* Enable peripheral ? */
+ //UDP_EnablePeripheralClock();
+
+ /* Get interrupt status
+ Some interrupts may get masked depending on the device state */
+ status = UDP->UDP_ISR;
+ status &= UDP->UDP_IMR;
+
+ if (USBD_GetState() < USBD_STATE_POWERED) {
+
+ status &= UDP_ICR_WAKEUP | UDP_ICR_RXRSM;
+ UDP->UDP_ICR = ~status;
+ }
+
+ /* Return immediately if there is no interrupt to service */
+ if (status == 0) {
+
+ TRACE_DEBUG_WP(".\n\r");
+ return;
+ }
+
+ /* Toggle USB LED if the device is active */
+ if (USBD_GetState() >= USBD_STATE_POWERED) {
+
+ //LED_Set(USBD_LEDUSB);
+ }
+
+ /* Service interrupts */
+
+ /** / Start Of Frame (SOF) */
+ //if (ISSET(dStatus, UDP_ISR_SOFINT)) {
+ //
+ // TRACE_DEBUG("SOF");
+ //
+ // // Invoke the SOF callback
+ // USB_StartOfFrameCallback(pUsb);
+ //
+ // // Acknowledge interrupt
+ // UDP->UDP_ICR = UDP_ICR_SOFINT;
+ // dStatus &= ~UDP_ISR_SOFINT;
+ //}
+ /* Resume (Wakeup) */
+ if ((status & (UDP_ISR_WAKEUP | UDP_ISR_RXRSM)) != 0) {
+
+ TRACE_INFO_WP("Res ");
+ /* Clear and disable resume interrupts */
+ UDP->UDP_ICR = UDP_ICR_WAKEUP | UDP_ICR_RXRSM | UDP_ICR_RXSUSP;
+ UDP->UDP_IDR = UDP_IDR_WAKEUP | UDP_IDR_RXRSM;
+ /* Do resome operations */
+ USBD_ResumeHandler();
+ }
+
+ /* Suspend
+ This interrupt is always treated last (hence the '==') */
+ if (status == UDP_ISR_RXSUSP) {
+
+ TRACE_INFO_WP("Susp ");
+ /* Enable wakeup */
+ UDP->UDP_IER = UDP_IER_WAKEUP | UDP_IER_RXRSM;
+ /* Acknowledge interrupt */
+ UDP->UDP_ICR = UDP_ICR_RXSUSP;
+ /* Do suspend operations */
+ USBD_SuspendHandler();
+ }
+ /* End of bus reset */
+ else if ((status & UDP_ISR_ENDBUSRES) != 0) {
+
+ TRACE_INFO_WP("EoBRes ");
+ /* Flush and enable the Suspend interrupt */
+ UDP->UDP_ICR = UDP_ICR_WAKEUP | UDP_ICR_RXRSM | UDP_ICR_RXSUSP;
+ UDP->UDP_IER = UDP_IER_RXSUSP;
+
+ /* Do RESET operations */
+ USBD_ResetHandler();
+
+ /* Acknowledge end of bus reset interrupt */
+ UDP->UDP_ICR = UDP_ICR_ENDBUSRES;
+ }
+ /* Endpoint interrupts */
+ else {
+
+ status &= ((1 << CHIP_USB_NUMENDPOINTS) - 1);
+ while (status != 0) {
+
+ /* Check if endpoint has a pending interrupt */
+ if ((status & (1 << eptnum)) != 0) {
+
+ UDP_EndpointHandler(eptnum);
+ status &= ~(1 << eptnum);
+
+ if (status != 0) {
+
+ TRACE_INFO_WP("\n\r - ");
+ }
+ }
+ eptnum++;
+ }
+ }
+
+ /* Toggle LED back to its previous state */
+ TRACE_DEBUG_WP("!");
+ TRACE_INFO_WP("\n\r");
+ if (USBD_GetState() >= USBD_STATE_POWERED) {
+
+ //LED_Clear(USBD_LEDUSB);
+ }
+}
+
+/**
+ * \brief Reset endpoints and disable them.
+ * -# Terminate transfer if there is any, with given status;
+ * -# Reset the endpoint & disable it.
+ * \param bmEPs Bitmap for endpoints to reset.
+ * \param bStatus Status passed to terminate transfer on endpoint.
+ * \param bKeepCfg 1 to keep old endpoint configuration.
+ * \note Use USBD_HAL_ConfigureEP() to configure and enable endpoint
+ if not keeping old configuration.
+ * \sa USBD_HAL_ConfigureEP().
+ */
+void USBD_HAL_ResetEPs(uint32_t bmEPs, uint8_t bStatus, uint8_t bKeepCfg)
+{
+ Endpoint *pEndpoint;
+ uint32_t tmp = bmEPs & ((1<UDP_IDR = epBit;
+ /* Kill pending TXPKTREADY */
+ CLEAR_CSR(ep, UDP_CSR_TXPKTRDY);
+
+ /* Reset transfer information */
+ pEndpoint = &(endpoints[ep]);
+ /* Reset endpoint state */
+ pEndpoint->bank = 0;
+ /* Endpoint configure */
+ epCfg = UDP->UDP_CSR[ep];
+ /* Reset endpoint */
+ UDP->UDP_RST_EP |= epBit;
+ UDP->UDP_RST_EP &= ~epBit;
+ /* Restore configure */
+ if (bKeepCfg) {
+ //SET_CSR(ep, pEndpoint->CSR);
+ SET_CSR(ep, epCfg);
+ }
+ else {
+ //pEndpoint->CSR = 0;
+ pEndpoint->state = UDP_ENDPOINT_DISABLED;
+ }
+
+ /* Terminate transfer on this EP */
+ UDP_EndOfTransfer(ep, bStatus);
+ }
+ epBit <<= 1;
+ }
+ /* Reset EPs */
+ // UDP->UDP_RST_EP |= bmEPs;
+ // UDP->UDP_RST_EP &= ~bmEPs;
+}
+
+/**
+ * Cancel pending READ/WRITE
+ * \param bmEPs Bitmap for endpoints to reset.
+ * \note EP callback is invoked with USBD_STATUS_CANCELED.
+ */
+void USBD_HAL_CancelIo(uint32_t bmEPs)
+{
+ uint32_t tmp = bmEPs & ((1<UDP_IDR = epBit;
+ /* Kill pending TXPKTREADY */
+ CLEAR_CSR(ep, UDP_CSR_TXPKTRDY);
+
+ /* Terminate transfer on this EP */
+ UDP_EndOfTransfer(ep, USBD_STATUS_CANCELED);
+ }
+ epBit <<= 1;
+ }
+}
+
+/**
+ * Configures an endpoint according to its endpoint Descriptor.
+ * \param pDescriptor Pointer to an endpoint descriptor.
+ */
+uint8_t USBD_HAL_ConfigureEP(const USBEndpointDescriptor *pDescriptor)
+{
+ Endpoint *pEndpoint;
+ uint8_t bEndpoint;
+ uint8_t bType;
+ uint8_t bEndpointDir;
+
+ /* NULL descriptor -> Control endpoint 0 in default */
+ if (pDescriptor == 0) {
+ bEndpoint = 0;
+ pEndpoint = &(endpoints[bEndpoint]);
+ bType= USBEndpointDescriptor_CONTROL;
+ bEndpointDir = 0;
+ pEndpoint->size = CHIP_USB_ENDPOINTS_MAXPACKETSIZE(0);
+ }
+ /* Device descriptor -> Specific Control EP */
+ else if (pDescriptor->bDescriptorType == USBGenericDescriptor_DEVICE) {
+ bEndpoint = 0;
+ pEndpoint = &(endpoints[bEndpoint]);
+ bType = USBEndpointDescriptor_CONTROL;
+ bEndpointDir = 0;
+ pEndpoint->size = ((USBDeviceDescriptor *)pDescriptor)->bMaxPacketSize0;
+ }
+ /* Not endpoint descriptor, ERROR! */
+ else if (pDescriptor->bDescriptorType != USBGenericDescriptor_ENDPOINT) {
+ return 0xFF;
+ }
+ else {
+ bEndpoint = USBEndpointDescriptor_GetNumber(pDescriptor);
+ pEndpoint = &(endpoints[bEndpoint]);
+ bType = USBEndpointDescriptor_GetType(pDescriptor);
+ bEndpointDir = USBEndpointDescriptor_GetDirection(pDescriptor);
+ pEndpoint->size = USBEndpointDescriptor_GetMaxPacketSize(pDescriptor);
+ }
+
+ /* Abort the current transfer is the endpoint was configured and in
+ Write or Read state */
+ if ((pEndpoint->state == UDP_ENDPOINT_RECEIVING)
+ || (pEndpoint->state == UDP_ENDPOINT_SENDING)
+ || (pEndpoint->state == UDP_ENDPOINT_RECEIVINGM)
+ || (pEndpoint->state == UDP_ENDPOINT_SENDINGM)) {
+ UDP_EndOfTransfer(bEndpoint, USBD_STATUS_RESET);
+ }
+ pEndpoint->state = UDP_ENDPOINT_IDLE;
+
+ /* Reset Endpoint Fifos */
+ UDP->UDP_RST_EP |= (1 << bEndpoint);
+ UDP->UDP_RST_EP &= ~(1 << bEndpoint);
+
+ /* Configure endpoint */
+ SET_CSR(bEndpoint, (uint32_t)UDP_CSR_EPEDS
+ | (bType << 8) | (bEndpointDir << 10));
+ if (bType != USBEndpointDescriptor_CONTROL) {
+
+ }
+ else {
+
+ UDP->UDP_IER = (1 << bEndpoint);
+ }
+
+ TRACE_INFO_WP("CfgEp%d ", bEndpoint);
+ return bEndpoint;
+}
+
+/**
+ * Set callback for a USB endpoint for transfer (read/write).
+ *
+ * \param bEP Endpoint number.
+ * \param fCallback Optional callback function to invoke when the transfer is
+ * complete.
+ * \param pCbData Optional pointer to data to the callback function.
+ * \return USBD_STATUS_SUCCESS or USBD_STATUS_LOCKED if endpoint is busy.
+ */
+uint8_t USBD_HAL_SetTransferCallback(uint8_t bEP,
+ TransferCallback fCallback,
+ void *pCbData)
+{
+ Endpoint *pEndpoint = &(endpoints[bEP]);
+ TransferHeader *pTransfer = (TransferHeader*)&(pEndpoint->transfer);
+ /* Check that the endpoint is not transferring */
+ if (pEndpoint->state > UDP_ENDPOINT_IDLE) {
+ return USBD_STATUS_LOCKED;
+ }
+ TRACE_DEBUG_WP("sXfrCb ");
+ /* Setup the transfer callback and extension data */
+ pTransfer->fCallback = (void*)fCallback;
+ pTransfer->pArgument = pCbData;
+ return USBD_STATUS_SUCCESS;
+}
+
+/**
+ * Configure an endpoint to use multi-buffer-list transfer mode.
+ * The buffers can be added by _Read/_Write function.
+ * \param pMbList Pointer to a multi-buffer list used, NULL to disable MBL.
+ * \param mblSize Multi-buffer list size (number of buffers can be queued)
+ * \param startOffset When number of buffer achieve this offset transfer start
+ */
+uint8_t USBD_HAL_SetupMblTransfer( uint8_t bEndpoint,
+ USBDTransferBuffer* pMbList,
+ uint16_t mblSize,
+ uint16_t startOffset)
+{
+ Endpoint *pEndpoint = &(endpoints[bEndpoint]);
+ MblTransfer *pXfr = (MblTransfer*)&(pEndpoint->transfer);
+ uint16_t i;
+ /* Check that the endpoint is not transferring */
+ if (pEndpoint->state > UDP_ENDPOINT_IDLE) {
+ return USBD_STATUS_LOCKED;
+ }
+ TRACE_DEBUG_WP("sMblXfr ");
+ /* Enable Multi-Buffer Transfer List */
+ if (pMbList) {
+ /* Reset list items */
+ for (i = 0; i < mblSize; i --) {
+ pMbList[i].pBuffer = NULL;
+ pMbList[i].size = 0;
+ pMbList[i].transferred = 0;
+ pMbList[i].buffered = 0;
+ pMbList[i].remaining = 0;
+ }
+ /* Setup transfer */
+ pXfr->transType = 1;
+ pXfr->listState = 0; /* OK */
+ pXfr->listSize = mblSize;
+ pXfr->pMbl = pMbList;
+ pXfr->outCurr = pXfr->outLast = 0;
+ pXfr->inCurr = 0;
+ pXfr->offsetSize = startOffset;
+ }
+ /* Disable Multi-Buffer Transfer */
+ else {
+ pXfr->transType = 0;
+ pXfr->pMbl = NULL;
+ pXfr->listSize = 0;
+ pXfr->offsetSize = 1;
+ }
+ return USBD_STATUS_SUCCESS;
+}
+
+/**
+ * Sends data through a USB endpoint. Sets up the transfer descriptor,
+ * writes one or two data payloads (depending on the number of FIFO bank
+ * for the endpoint) and then starts the actual transfer. The operation is
+ * complete when all the data has been sent.
+ *
+ * *If the size of the buffer is greater than the size of the endpoint
+ * (or twice the size if the endpoint has two FIFO banks), then the buffer
+ * must be kept allocated until the transfer is finished*. This means that
+ * it is not possible to declare it on the stack (i.e. as a local variable
+ * of a function which returns after starting a transfer).
+ *
+ * \param bEndpoint Endpoint number.
+ * \param pData Pointer to a buffer with the data to send.
+ * \param dLength Size of the data buffer.
+ * \return USBD_STATUS_SUCCESS if the transfer has been started;
+ * otherwise, the corresponding error status code.
+ */
+uint8_t USBD_HAL_Write( uint8_t bEndpoint,
+ const void *pData,
+ uint32_t dLength)
+{
+ if (endpoints[bEndpoint].transfer.transHdr.transType)
+ return UDP_AddWr(bEndpoint, pData, dLength);
+ else
+ return UDP_Write(bEndpoint, pData, dLength);
+}
+
+/**
+ * Reads incoming data on an USB endpoint This methods sets the transfer
+ * descriptor and activate the endpoint interrupt. The actual transfer is
+ * then carried out by the endpoint interrupt handler. The Read operation
+ * finishes either when the buffer is full, or a short packet (inferior to
+ * endpoint maximum size) is received.
+ *
+ * *The buffer must be kept allocated until the transfer is finished*.
+ * \param bEndpoint Endpoint number.
+ * \param pData Pointer to a data buffer.
+ * \param dLength Size of the data buffer in bytes.
+ * \return USBD_STATUS_SUCCESS if the read operation has been started;
+ * otherwise, the corresponding error code.
+ */
+uint8_t USBD_HAL_Read(uint8_t bEndpoint,
+ void *pData,
+ uint32_t dLength)
+{
+ if (endpoints[bEndpoint].transfer.transHdr.transType)
+ return USBD_STATUS_SW_NOT_SUPPORTED;
+ else
+ return UDP_Read(bEndpoint, pData, dLength);
+}
+
+/**
+ * \brief Enable Pull-up, connect.
+ *
+ * -# Enable HW access if needed
+ * -# Enable Pull-Up
+ * -# Disable HW access if needed
+ */
+void USBD_HAL_Connect(void)
+{
+ uint8_t dis = UDP_EnablePeripheralClock();
+ UDP->UDP_TXVC |= UDP_TXVC_PUON;
+ if (dis) UDP_DisablePeripheralClock();
+}
+
+/**
+ * \brief Disable Pull-up, disconnect.
+ *
+ * -# Enable HW access if needed
+ * -# Disable PULL-Up
+ * -# Disable HW access if needed
+ */
+void USBD_HAL_Disconnect(void)
+{
+ uint8_t dis = UDP_EnablePeripheralClock();
+ UDP->UDP_TXVC &= ~(uint32_t)UDP_TXVC_PUON;
+ if (dis) UDP_DisablePeripheralClock();
+}
+
+/**
+ * Starts a remote wake-up procedure.
+ */
+void USBD_HAL_RemoteWakeUp(void)
+{
+ UDP_EnablePeripheralClock();
+ UDP_EnableUsbClock();
+ UDP_EnableTransceiver();
+
+ TRACE_INFO_WP("RWUp ");
+
+ // Activates a remote wakeup (edge on ESR), then clear ESR
+ UDP->UDP_GLB_STAT |= UDP_GLB_STAT_ESR;
+ UDP->UDP_GLB_STAT &= ~(uint32_t)UDP_GLB_STAT_ESR;
+}
+
+/**
+ * Sets the device address to the given value.
+ * \param address New device address.
+ */
+void USBD_HAL_SetAddress(uint8_t address)
+{
+ /* Set address */
+ UDP->UDP_FADDR = UDP_FADDR_FEN | (address & UDP_FADDR_FADD_Msk);
+ /* If the address is 0, the device returns to the Default state */
+ if (address == 0) UDP->UDP_GLB_STAT = 0;
+ /* If the address is non-zero, the device enters the Address state */
+ else UDP->UDP_GLB_STAT = UDP_GLB_STAT_FADDEN;
+}
+
+/**
+ * Sets the current device configuration.
+ * \param cfgnum - Configuration number to set.
+ */
+void USBD_HAL_SetConfiguration(uint8_t cfgnum)
+{
+ /* If the configuration number if non-zero, the device enters the
+ Configured state */
+ if (cfgnum != 0) UDP->UDP_GLB_STAT |= UDP_GLB_STAT_CONFG;
+ /* If the configuration number is zero, the device goes back to the Address
+ state */
+ else {
+ UDP->UDP_GLB_STAT = UDP_FADDR_FEN;
+ }
+}
+
+/**
+ * Initializes the USB HW Access driver.
+ */
+void USBD_HAL_Init(void)
+{
+ /* Must before USB & TXVC access! */
+ UDP_EnablePeripheralClock();
+
+ /* Reset & disable endpoints */
+ USBD_HAL_ResetEPs(0xFFFFFFFF, USBD_STATUS_RESET, 0);
+
+ /* Configure the pull-up on D+ and disconnect it */
+ UDP->UDP_TXVC &= ~(uint32_t)UDP_TXVC_PUON;
+
+ UDP_EnableUsbClock();
+
+ UDP->UDP_IDR = 0xFE;
+ UDP->UDP_IER = UDP_IER_WAKEUP;
+}
+
+/**
+ * Causes the given endpoint to acknowledge the next packet it receives
+ * with a STALL handshake except setup request.
+ * \param bEP Endpoint number.
+ * \return USBD_STATUS_SUCCESS or USBD_STATUS_LOCKED.
+ */
+uint8_t USBD_HAL_Stall(uint8_t bEP)
+{
+ Endpoint *pEndpoint = &(endpoints[bEP]);
+
+ /* Check that endpoint is in Idle state */
+ if (pEndpoint->state != UDP_ENDPOINT_IDLE) {
+ TRACE_WARNING("UDP_Stall: EP%d locked\n\r", bEP);
+ return USBD_STATUS_LOCKED;
+ }
+ /* STALL endpoint */
+ SET_CSR(bEP, UDP_CSR_FORCESTALL);
+ TRACE_DEBUG_WP("Stall%d ", bEP);
+ return USBD_STATUS_SUCCESS;
+}
+
+/**
+ * Sets/Clear/Get the HALT state on the endpoint.
+ * In HALT state, the endpoint should keep stalling any packet.
+ * \param bEndpoint Endpoint number.
+ * \param ctl Control code CLR/HALT/READ.
+ * 0: Clear HALT state;
+ * 1: Set HALT state;
+ * .: Return HALT status.
+ * \return USBD_STATUS_INVALID_PARAMETER if endpoint not exist,
+ * otherwise endpoint halt status.
+ */
+uint8_t USBD_HAL_Halt(uint8_t bEndpoint, uint8_t ctl)
+{
+ Endpoint *pEndpoint = &(endpoints[bEndpoint]);
+ uint8_t status = 0;
+
+ /* SET Halt */
+ if (ctl == 1) {
+ /* Check that endpoint is enabled and not already in Halt state */
+ if ((pEndpoint->state != UDP_ENDPOINT_DISABLED)
+ && (pEndpoint->state != UDP_ENDPOINT_HALTED)) {
+
+ TRACE_DEBUG_WP("Halt%d ", bEndpoint);
+
+ /* Abort the current transfer if necessary */
+ UDP_EndOfTransfer(bEndpoint, USBD_STATUS_ABORTED);
+
+ /* Put endpoint into Halt state */
+ SET_CSR(bEndpoint, UDP_CSR_FORCESTALL);
+ pEndpoint->state = UDP_ENDPOINT_HALTED;
+
+ /* Enable the endpoint interrupt */
+ UDP->UDP_IER = 1 << bEndpoint;
+ }
+ }
+ /* CLEAR Halt */
+ else if (ctl == 0) {
+ /* Check if the endpoint is halted */
+ //if (pEndpoint->state != UDP_ENDPOINT_DISABLED) {
+ if (pEndpoint->state == UDP_ENDPOINT_HALTED) {
+
+ TRACE_DEBUG_WP("Unhalt%d ", bEndpoint);
+
+ /* Return endpoint to Idle state */
+ pEndpoint->state = UDP_ENDPOINT_IDLE;
+
+ /* Clear FORCESTALL flag */
+ CLEAR_CSR(bEndpoint, UDP_CSR_FORCESTALL);
+
+ /* Reset Endpoint Fifos, beware this is a 2 steps operation */
+ UDP->UDP_RST_EP |= 1 << bEndpoint;
+ UDP->UDP_RST_EP &= ~(1 << bEndpoint);
+ }
+ }
+
+ /* Return Halt status */
+ if (pEndpoint->state == UDP_ENDPOINT_HALTED) {
+ status = 1;
+ }
+ return( status );
+}
+
+/**
+ * Indicates if the device is running in high or full-speed. Always returns 0
+ * since UDP does not support high-speed mode.
+ */
+uint8_t USBD_HAL_IsHighSpeed(void)
+{
+ return 0;
+}
+
+/**
+ * Suspend USB Device HW Interface
+ *
+ * -# Disable transceiver
+ * -# Disable USB Clock
+ * -# Disable USB Peripheral
+ */
+void USBD_HAL_Suspend(void)
+{
+ /* The device enters the Suspended state */
+ UDP_DisableTransceiver();
+ UDP_DisableUsbClock();
+ UDP_DisablePeripheralClock();
+}
+
+/**
+ * Activate USB Device HW Interface
+ * -# Enable USB Peripheral
+ * -# Enable USB Clock
+ * -# Enable transceiver
+ */
+void USBD_HAL_Activate(void)
+{
+ UDP_EnablePeripheralClock();
+ UDP_EnableUsbClock();
+ UDP_EnableTransceiver();
+}
+
+/**@}*/
+
diff --git a/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/acc.c b/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/acc.c
new file mode 100644
index 00000000..76f4e47d
--- /dev/null
+++ b/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/acc.c
@@ -0,0 +1,162 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * 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:
+ *
+ * - 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
+ * 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:
+ *
+ * - Enable ACC peripheral clock by setting the corresponding bit in PMC_PCER1
+ * (PMC Peripheral Clock Enable Register 1)
+ *
+ * - Reset the controller by asserting ACC_CR_SWRST in ACC_CR(ACC Control Register)
+
+ * - Configure the mode as following steps:
+ * -# 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.
+ *
+ * - Wait until the automatic mask period expires by polling MASK bit in
+ * ACC_ISR.
+ *
+ *
+ * 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"
+
+/*----------------------------------------------------------------------------
+ * 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 comprator 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_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 selplus input applied on ACC SELPLUS
+ * \param selminus input applied on ACC SELMINUS
+ */
+extern void ACC_SetComparisionPair( 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 status value of ACC_ISR
+ */
+extern uint32_t ACC_GetComparisionResult( 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*/
+ }
+ }
+}
+
diff --git a/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/adc.c b/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/adc.c
new file mode 100644
index 00000000..95c9d5b2
--- /dev/null
+++ b/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/adc.c
@@ -0,0 +1,417 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * 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:
+ *
+ * - 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 adc_module Working with ADC
+ * The ADC driver provides the interface to configure and use the ADC peripheral.
+ * \n
+ *
+ * It converts the analog input to digital format. The converted result could be
+ * 12bit or 10bit. The ADC supports up to 16 analog lines.
+ *
+ * To Enable a ADC conversion,the user has to follow these few steps:
+ *
+ * - Select an appropriate reference voltage on ADVREF
+ * - Configure the ADC according to its requirements and special needs,which
+ * could be broken down into several parts:
+ * -# Select the resolution by setting or clearing ADC_MR_LOWRES bit in
+ * ADC_MR (Mode Register)
+ * -# Set ADC clock by setting ADC_MR_PRESCAL bits in ADC_MR, the clock is
+ * calculated with ADCClock = MCK / ( (PRESCAL+1) * 2 )
+ * -# Set Startup Time,Tracking Clock cycles and Transfer Clock respectively
+ * in ADC_MR.
+
+ * - Start conversion by setting ADC_CR_START in ADC_CR.
+ *
+ *
+ * For more accurate information, please look at the ADC section of the
+ * Datasheet.
+ *
+ * Related files :\n
+ * \ref adc.c\n
+ * \ref adc.h\n
+ */
+/*@{*/
+/*@}*/
+/**
+ * \file
+ *
+ * Implementation of Analog-to-Digital Converter (ADC).
+ *
+ */
+/*----------------------------------------------------------------------------
+ * Headers
+ *----------------------------------------------------------------------------*/
+
+#include "chip.h"
+
+/*----------------------------------------------------------------------------
+ * Exported functions
+ *----------------------------------------------------------------------------*/
+
+/**
+ * \brief Initialize the ADC controller
+ *
+ * \param pAdc Pointer to an Adc instance.
+ * \param idAdc ADC Index
+ * \param trgEn trigger mode, software or Hardware
+ * \param trgSel hardware trigger selection
+ * \param sleepMode sleep mode selection
+ * \param resolution resolution selection 10 bits or 12 bits
+ * \param mckClock value of MCK in Hz
+ * \param adcClock value of the ADC clock in Hz
+ * \param startup value of the start up time (in ADCClock) (see datasheet)
+ * \param tracking Tracking Time (in ADCClock cycle)
+ */
+extern void ADC_Initialize( Adc* pAdc, uint32_t idAdc )
+{
+ /* Enable peripheral clock*/
+ PMC->PMC_PCER0 = 1 << idAdc;
+
+ /* Reset the controller */
+ pAdc->ADC_CR = ADC_CR_SWRST;
+
+ /* Reset Mode Register set to default */
+ /* TrackTime set to 0 */
+ /* Transfer set to 1 */
+ /* settling set to 3 */
+ pAdc->ADC_MR = ADC_MR_TRANSFER(1) | ADC_MR_TRACKTIM(0) | ADC_MR_SETTLING(3);
+}
+
+/**
+ * \brief Initialize the ADC Timing
+ */
+extern void ADC_CfgTiming( Adc* pAdc, uint32_t tracking, uint32_t settling, uint32_t transfer )
+{
+ pAdc->ADC_MR = ADC_MR_TRANSFER( transfer )
+ | ADC_MR_SETTLING( settling )
+ | ADC_MR_TRACKTIM( tracking ) ;
+}
+
+/**
+ * \brief Initialize the ADC Timing
+ */
+extern void ADC_cfgFrequency( Adc* pAdc, uint32_t startup, uint32_t prescal )
+{
+ pAdc->ADC_MR |= ADC_MR_PRESCAL( prescal )
+ | ( (startup<ADC_MR |= ((trgEn<<0) & ADC_MR_TRGEN)
+ | ((trgSel<ADC_MR |= (resolution<<4) & ADC_MR_LOWRES;
+}
+
+/**
+ * \brief Initialize the ADC PowerSave
+ */
+extern void ADC_CfgPowerSave( Adc* pAdc, uint32_t sleep, uint32_t fwup )
+{
+ pAdc->ADC_MR |= ( ((sleep<<5) & ADC_MR_SLEEP)
+ | ((fwup<<6) & ADC_MR_FWUP) );
+}
+
+/**
+ * \brief Initialize the ADC Channel Mode
+ */
+extern void ADC_CfgChannelMode( Adc* pAdc, uint32_t useq, uint32_t anach )
+{
+ pAdc->ADC_MR |= ( ((anach<<23) & ADC_MR_ANACH)
+ | ((useq <<31) & (uint32_t)ADC_MR_USEQ) );
+}
+
+
+/**
+ * \brief calcul_startup
+ */
+static uint32_t calcul_startup( uint32_t startup )
+{
+ uint32_t startup_value=0;
+
+ if( startup == 0 )
+ startup_value = 0;
+ else if( startup == 1 )
+ startup_value = 8;
+ else if( startup == 2 )
+ startup_value = 16;
+ else if( startup == 3 )
+ startup_value = 24;
+ else if( startup == 4 )
+ startup_value = 64;
+ else if( startup == 5 )
+ startup_value = 80;
+ else if( startup == 6 )
+ startup_value = 96;
+ else if( startup == 7 )
+ startup_value = 112;
+ else if( startup == 8 )
+ startup_value = 512;
+ else if( startup == 9 )
+ startup_value = 576;
+ else if( startup == 10 )
+ startup_value = 640;
+ else if( startup == 11 )
+ startup_value = 704;
+ else if( startup == 12 )
+ startup_value = 768;
+ else if( startup == 13 )
+ startup_value = 832;
+ else if( startup == 14 )
+ startup_value = 896;
+ else if( startup == 15 )
+ startup_value = 960;
+
+ return startup_value;
+}
+
+/**
+ * \brief ADC check
+ */
+extern void ADC_check( Adc* pAdc, uint32_t mck_freq )
+{
+ uint32_t adc_freq;
+ uint32_t prescal;
+ uint32_t startup;
+
+ /* ADCClock = MCK / ( (PRESCAL+1) * 2 ) */
+ prescal = (( pAdc->ADC_MR & ADC_MR_PRESCAL_Msk) >> ADC_MR_PRESCAL_Pos);
+ adc_freq = mck_freq / ((prescal+1)*2);
+ printf("ADC clock frequency = %d Hz\r\n", (int)adc_freq );
+
+ if( adc_freq < ADC_FREQ_MIN )
+ {
+ printf("adc frequency too low (out of specification: %d Hz)\r\n", (int)ADC_FREQ_MIN);
+ }
+ if( adc_freq > ADC_FREQ_MAX )
+ {
+ printf("adc frequency too high (out of specification: %d Hz)\r\n", (int)ADC_FREQ_MAX);
+ }
+
+ startup = (( pAdc->ADC_MR & ADC_MR_STARTUP_Msk) >> ADC_MR_STARTUP_Pos);
+ if( !(pAdc->ADC_MR & ADC_MR_SLEEP_SLEEP) )
+ {
+ /* 40µs */
+ if( ADC_STARTUP_NORM * adc_freq / 1000000 > calcul_startup(startup) )
+ {
+ printf("Startup time too small: %d, programmed: %d\r\n", (int)(ADC_STARTUP_NORM * adc_freq / 1000000), (int)calcul_startup(startup));
+ }
+ }
+ else
+ {
+ if(pAdc->ADC_MR & ADC_MR_FREERUN_ON)
+ {
+ printf("FreeRun forbidden in sleep mode\n\r");
+ }
+ if( !(pAdc->ADC_MR & ADC_MR_FWUP_ON) )
+ {
+ /* Sleep 40µs */
+ if( ADC_STARTUP_NORM * adc_freq / 1000000 > calcul_startup(startup) )
+ {
+ printf("Startup time too small: %d, programmed: %d\r\n", (int)(ADC_STARTUP_NORM * adc_freq / 1000000), (int)(calcul_startup(startup)));
+ }
+ }
+ else
+ {
+ if( pAdc->ADC_MR & ADC_MR_FWUP_ON )
+ {
+ /* Fast Wake Up Sleep Mode: 12µs */
+ if( ADC_STARTUP_FAST * adc_freq / 1000000 > calcul_startup(startup) )
+ {
+ printf("Startup time too small: %d, programmed: %d\r\n", (int)(ADC_STARTUP_NORM * adc_freq / 1000000), (int)(calcul_startup(startup)));
+ }
+ }
+ }
+ }
+
+
+
+
+}
+
+
+
+/**
+ * Return the Channel Converted Data
+ *
+ * \param pAdc Pointer to an Adc instance.
+ * \param channel channel to get converted value
+ */
+extern uint32_t ADC_GetConvertedData( Adc* pAdc, uint32_t dwChannel )
+{
+ uint32_t dwData = 0;
+
+ assert( dwChannel < 16 ) ;
+
+ if ( 15 >= dwChannel )
+ {
+ dwData=*(pAdc->ADC_CDR+dwChannel) ;
+ }
+
+ return dwData ;
+}
+/**
+ * Set compare channel
+ *
+ * \param pAdc Pointer to an Adc instance.
+ * \param channel channel number to be set,16 for all channels
+ */
+extern void ADC_SetCompareChannel( Adc* pAdc, uint32_t dwChannel )
+{
+ assert( dwChannel <= 16 ) ;
+
+ if ( dwChannel < 16 )
+ {
+ pAdc->ADC_EMR &= (uint32_t)~(ADC_EMR_CMPALL);
+ pAdc->ADC_EMR &= (uint32_t)~(ADC_EMR_CMPSEL_Msk);
+ pAdc->ADC_EMR |= (dwChannel << ADC_EMR_CMPSEL_Pos);
+ }
+ else
+ {
+ pAdc->ADC_EMR |= ADC_EMR_CMPALL;
+ }
+}
+/**
+ * Set compare mode
+ *
+ * \param pAdc Pointer to an Adc instance.
+ * \param mode compare mode
+ */
+extern void ADC_SetCompareMode( Adc* pAdc, uint32_t dwMode )
+{
+ pAdc->ADC_EMR &= (uint32_t)~(ADC_EMR_CMPMODE_Msk);
+ pAdc->ADC_EMR |= (dwMode & ADC_EMR_CMPMODE_Msk) ;
+}
+/**
+ * Set comparsion window,one thereshold each time
+ *
+ * \param pAdc Pointer to an Adc instance.
+ * \param hi_lo Comparison Window
+ */
+extern void ADC_SetComparisonWindow( Adc* pAdc, uint32_t dwHi_Lo )
+{
+ pAdc->ADC_CWR = dwHi_Lo ;
+}
+
+/**----------------------------------------------------------------------------
+ * Test if ADC Interrupt is Masked
+ *
+ * \param pAdc Pointer to an Adc instance.
+ * \param flag flag to be tested
+ *
+ * \return 1 if interrupt is masked, otherwise 0
+ */
+uint32_t ADC_IsInterruptMasked( Adc* pAdc, uint32_t dwFlag )
+{
+ return (ADC_GetInterruptMaskStatus( pAdc ) & dwFlag) ;
+}
+
+/**----------------------------------------------------------------------------
+ * Test if ADC Status is Set
+ *
+ * \param pAdc Pointer to an Adc instance.
+ * \param flag flag to be tested
+ *
+ * \return 1 if the staus is set; 0 otherwise
+ */
+extern uint32_t ADC_IsStatusSet( Adc* pAdc, uint32_t dwFlag )
+{
+ return (ADC_GetStatus( pAdc ) & dwFlag) ;
+}
+
+/**----------------------------------------------------------------------------
+ * Test if ADC channel interrupt Status is Set
+ *
+ * \param adc_sr Value of SR register
+ * \param channel Channel to be tested
+ *
+ * \return 1 if interrupt status is set, otherwise 0
+ */
+extern uint32_t ADC_IsChannelInterruptStatusSet( uint32_t dwAdc_sr, uint32_t dwChannel )
+{
+ uint32_t dwStatus ;
+
+ if ( (dwAdc_sr & ((uint32_t)1 << dwChannel)) == ((uint32_t)1 << dwChannel) )
+ {
+ dwStatus = 1 ;
+ }
+ else
+ {
+ dwStatus = 0 ;
+ }
+
+ return dwStatus ;
+}
+
+/**
+ * \brief Read converted data through PDC channel
+ *
+ * \param pADC the pointer of adc peripheral
+ * \param pBuffer the destination buffer
+ * \param dwSize the size of the buffer
+ */
+extern uint32_t ADC_ReadBuffer( Adc* pADC, int16_t *pwBuffer, uint32_t dwSize )
+{
+ /* Check if the first PDC bank is free*/
+ if ( (pADC->ADC_RCR == 0) && (pADC->ADC_RNCR == 0) )
+ {
+ pADC->ADC_RPR = (uint32_t)pwBuffer ;
+ pADC->ADC_RCR = dwSize ;
+ pADC->ADC_PTCR = ADC_PTCR_RXTEN;
+
+ return 1;
+ }
+ /* Check if the second PDC bank is free*/
+ else
+ {
+ if ( pADC->ADC_RNCR == 0 )
+ {
+ pADC->ADC_RNPR = (uint32_t)pwBuffer ;
+ pADC->ADC_RNCR = dwSize ;
+
+ return 1 ;
+ }
+ else
+ {
+ return 0 ;
+ }
+ }
+}
+
diff --git a/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/async.c b/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/async.c
new file mode 100644
index 00000000..b202be22
--- /dev/null
+++ b/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/async.c
@@ -0,0 +1,53 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * 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:
+ *
+ * - 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
+ *
+ * Provide a routine for asynchronos transfer.
+ *
+ */
+
+/*----------------------------------------------------------------------------
+ * Headers
+ *----------------------------------------------------------------------------*/
+#include "chip.h"
+
+/*----------------------------------------------------------------------------
+ * 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) ;
+}
+
diff --git a/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/crccu.c b/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/crccu.c
new file mode 100644
index 00000000..d356cf17
--- /dev/null
+++ b/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/crccu.c
@@ -0,0 +1,112 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * 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:
+ *
+ * - 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 crccu_module Working with CRCCU
+ * The CRCCU driver provides the interface to configure and use the CRCCU
+ * peripheral.
+ *
+ * It performs a CRC computation on a Memory Area. CRC computation is performed
+ * from the LSB to MSB bit. Three different polynomials are available:
+ * CCIT802.3, CASTAGNOLI and CCIT16.
+ *
+ * To computes CRC of a buffer, the user has to follow these few steps:
+ *
+ * - Reset initial CRC by setting RESET bit in CRCCU_CRC_CR,
+ * - Configure CRC descriptor and working mode,
+ * - Start to compute CRC by setting DMAEN in CRCCU_DMA_EN,
+ * - Get CRC value in CRCCU_CRC_SR.
+ *
+ *
+ * For more accurate information, please look at the CRCCU section of the
+ * Datasheet.
+ *
+ * Related files :\n
+ * \ref crccu.c\n
+ * \ref crccu.h.\n
+*/
+/*@{*/
+/*@}*/
+
+/**
+ * \file
+ *
+ * Implementation of Cyclic Redundancy Check Calculation Unit (CRCCU).
+ *
+ */
+
+/*----------------------------------------------------------------------------
+ * Headers
+ *----------------------------------------------------------------------------*/
+#include "chip.h"
+
+/*----------------------------------------------------------------------------
+ * Definitions
+ *----------------------------------------------------------------------------*/
+#define CRCCU_TIMEOUT 0xFFFFFFFF
+
+/*----------------------------------------------------------------------------
+ * Exported functions
+ *----------------------------------------------------------------------------*/
+/**
+ * \brief Reset initial CRC to 0xFFFFFFFF.
+ */
+extern void CRCCU_ResetCrcValue( Crccu* pCrccu )
+{
+ pCrccu->CRCCU_CR = CRCCU_CR_RESET;
+}
+
+/**
+ * \brief Configure the CRCCU.
+ *
+ * \param dscrAddr CRC decscriptor address.
+ * \param mode CRC work mode
+ */
+extern void CRCCU_Configure( Crccu* pCrccu, uint32_t dwDscrAddr, uint32_t dwMode )
+{
+ pCrccu->CRCCU_DSCR = dwDscrAddr ;
+ pCrccu->CRCCU_MR = dwMode ;
+}
+
+/**
+ * \brief Start to compute the CRC of a buffer.
+ *
+ * \return The CRC of the buffer.
+ */
+extern uint32_t CRCCU_ComputeCrc( Crccu* pCrccu )
+{
+ uint32_t dwTimeout = 0 ;
+
+ pCrccu->CRCCU_DMA_EN = CRCCU_DMA_EN_DMAEN ;
+
+ while ( ((pCrccu->CRCCU_DMA_SR & CRCCU_DMA_SR_DMASR) == CRCCU_DMA_SR_DMASR) &&
+ (dwTimeout++ < CRCCU_TIMEOUT) ) ;
+
+ return (pCrccu->CRCCU_SR) ;
+}
+
diff --git a/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/dacc.c b/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/dacc.c
new file mode 100644
index 00000000..ae460dfc
--- /dev/null
+++ b/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/dacc.c
@@ -0,0 +1,183 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * 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:
+ *
+ * - 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
+ * 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:
+ *
+ * - Select an appropriate reference voltage on ADVREF
+ * - 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 Startup Time and Refresh Period through setting STARTUP and 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 .
+
+ *
+ *
+ * For more accurate information, please look at the DACC section of the
+ * Datasheet.
+ *
+ * Related files :\n
+ * \ref DACC.c\n
+ * \ref DACC.h\n
+*/
+/*@{*/
+/*@}*/
+/**
+ * \file
+ *
+ * Implementation of Digital-to-Analog Converter Controller (DACC).
+ *
+ */
+/*----------------------------------------------------------------------------
+ * Headers
+ *----------------------------------------------------------------------------*/
+
+#include "chip.h"
+
+#include
+#include
+
+/*----------------------------------------------------------------------------
+ * Exported functions
+ *----------------------------------------------------------------------------*/
+
+/**
+ * \brief Initialize the DACC controller
+ * \param pDACC Pointer to an DACC instance.
+ * \param idDACC identifier of DAC peripheral
+ * \param trgEn trigger mode, free running mode or external Hardware trigger
+ * \param word transfer size,word or half word
+ * \param trgSel hardware trigger selection
+ * \param sleepMode sleep mode selection
+ * \param mck value of MCK in Hz
+ * \param refresh refresh period
+ * \param user_sel user channel selection ,0 or 1
+ * \param tag_mode tag for channel number
+ * \param startup value of the start up time (in DACCClock) (see datasheet)
+*/
+extern void DACC_Initialize( Dacc* pDACC,
+ uint8_t idDACC,
+ uint8_t trgEn,
+ uint8_t trgSel,
+ uint8_t word,
+ uint8_t sleepMode,
+ uint32_t mck,
+ uint8_t refresh, /* refresh period */
+ uint8_t user_sel, /* user channel selection */
+ uint32_t tag_mode, /* using tag for channel number */
+ uint32_t startup
+ )
+{
+ assert( 1024*refresh*1000/(mck>>1) < 20 ) ;
+
+ /* Enable peripheral clock*/
+ PMC->PMC_PCER0 = 1 << idDACC;
+
+ /* Reset the controller */
+ DACC_SoftReset(pDACC);
+
+ /* Write to the MR register */
+ DACC_CfgModeReg( pDACC,
+ ( (trgEn<<0) & DACC_MR_TRGEN)
+ | DACC_MR_TRGSEL(trgSel)
+ | ( (word<<4) & DACC_MR_WORD)
+ | ( (sleepMode<<5) & DACC_MR_SLEEP)
+ | DACC_MR_REFRESH(refresh)
+ | ( (user_sel<DACC_MR ;
+
+ if ( dwMR & DACC_MR_WORD )
+ {
+ pDACC->DACC_CDR = dwData ;
+ }
+ else
+ {
+ pDACC->DACC_CDR = (dwData&0xFFFF) ;
+ }
+}
+
+
+/**
+ * \brief Write converted data through PDC channel
+ * \param pDACC the pointer of DACC peripheral
+ * \param pBuffer the destination buffer
+ * \param size the size of the buffer
+*/
+extern uint32_t DACC_WriteBuffer( Dacc* pDACC, uint16_t *pwBuffer, uint32_t dwSize )
+{
+
+ /* Check if the first PDC bank is free*/
+ if ( (pDACC->DACC_TCR == 0) && (pDACC->DACC_TNCR == 0) )
+ {
+ pDACC->DACC_TPR = (uint32_t)pwBuffer ;
+ pDACC->DACC_TCR = dwSize ;
+ pDACC->DACC_PTCR = DACC_PTCR_TXTEN ;
+
+ return 1 ;
+ }
+ /* Check if the second PDC bank is free*/
+ else
+ {
+ if (pDACC->DACC_TNCR == 0)
+ {
+ pDACC->DACC_TNPR = (uint32_t)pwBuffer ;
+ pDACC->DACC_TNCR = dwSize ;
+
+ return 1 ;
+ }
+ else
+ {
+ return 0 ;
+ }
+ }
+
+}
+
+
diff --git a/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/efc.c b/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/efc.c
new file mode 100644
index 00000000..97104d5e
--- /dev/null
+++ b/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/efc.c
@@ -0,0 +1,289 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * 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:
+ *
+ * - 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
+ * 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:
+ *
+ * - Write a correct key, command and argument in EEFC_FCR.
+ * - 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.
+ * - Once the command is achieved, it can be detected even by polling EEFC_FSR or interrupt.
+ *
+ *
+ * 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 tranlate 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
+
+/*----------------------------------------------------------------------------
+ * Exported functions
+ *----------------------------------------------------------------------------*/
+
+/**
+ * \brief Enables the flash ready interrupt source on the EEFC peripheral.
+ *
+ * \param efc Pointer to a Efc instance
+ */
+extern void EFC_EnableFrdyIt( Efc* efc )
+{
+ efc->EEFC_FMR |= EEFC_FMR_FRDY ;
+}
+
+/**
+ * \brief Disables the flash ready interrupt source on the EEFC peripheral.
+ *
+ * \param efc Pointer to a Efc instance
+ */
+
+extern void EFC_DisableFrdyIt( Efc* efc )
+{
+ efc->EEFC_FMR &= ~((uint32_t)EEFC_FMR_FRDY) ;
+}
+
+
+/**
+ * \brief Set read/write wait state on the EEFC perpherial.
+ *
+ * \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 dwValue ;
+
+ dwValue = efc->EEFC_FMR ;
+ dwValue &= ~((uint32_t)EEFC_FMR_FWS_Msk) ;
+ dwValue |= EEFC_FMR_FWS(ucCycles);
+ efc->EEFC_FMR = dwValue ;
+}
+
+/**
+ * \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 )
+{
+ Efc *pEfc ;
+ uint16_t wPage ;
+ uint16_t wOffset ;
+
+ assert( dwAddress >= IFLASH_ADDR ) ;
+ assert( dwAddress <= (IFLASH_ADDR + IFLASH_SIZE) ) ;
+
+ pEfc = EFC ;
+ wPage = (dwAddress - IFLASH_ADDR) / IFLASH_PAGE_SIZE;
+ wOffset = (dwAddress - IFLASH_ADDR) % IFLASH_PAGE_SIZE;
+
+ TRACE_DEBUG( "Translated 0x%08X to page=%d and offset=%d\n\r", dwAddress, wPage, wOffset ) ;
+ /* Store values */
+ if ( pEfc )
+ {
+ *ppEfc = pEfc ;
+ }
+
+ if ( pwPage )
+ {
+ *pwPage = wPage ;
+ }
+
+ if ( pwOffset )
+ {
+ *pwOffset = wOffset ;
+ }
+}
+
+/**
+ * \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 ;
+
+ assert( efc ) ;
+ assert( wPage <= IFLASH_NB_OF_PAGES ) ;
+ assert( wOffset < IFLASH_PAGE_SIZE ) ;
+
+ /* Compute address */
+ dwAddress = IFLASH_ADDR + wPage * IFLASH_PAGE_SIZE + wOffset ;
+
+ /* Store result */
+ if ( pdwAddress != NULL )
+ {
+ *pdwAddress = dwAddress ;
+ }
+}
+
+/**
+ * \brief Starts the executing the given command on the EEFC and returns as soon as the command is started.
+ *
+ * \note It does NOT set the FMCN field automatically.
+ * \param efc Pointer to a Efc instance
+ * \param command Command to execute.
+ * \param argument Command argument (should be 0 if not used).
+ */
+extern void EFC_StartCommand( Efc* efc, uint32_t dwCommand, uint32_t dwArgument )
+{
+ /* Check command & argument */
+ switch ( dwCommand )
+ {
+ case EFC_FCMD_WP:
+ case EFC_FCMD_WPL:
+ case EFC_FCMD_EWP:
+ case EFC_FCMD_EWPL:
+ case EFC_FCMD_SLB:
+ case EFC_FCMD_CLB:
+ assert( dwArgument < IFLASH_NB_OF_PAGES ) ;
+ break ;
+
+ case EFC_FCMD_SFB:
+ case EFC_FCMD_CFB:
+ assert( dwArgument < 2 ) ;
+ break;
+
+ case EFC_FCMD_GETD:
+ case EFC_FCMD_EA:
+ case EFC_FCMD_GLB:
+ case EFC_FCMD_GFB:
+ case EFC_FCMD_STUI:
+ assert( dwArgument == 0 ) ;
+ break;
+
+ default: assert( 0 ) ;
+ }
+
+ /* Start command Embedded flash */
+ assert( (efc->EEFC_FSR & EEFC_FMR_FRDY) == EEFC_FMR_FRDY ) ;
+ efc->EEFC_FCR = EEFC_FCR_FKEY(0x5A) | EEFC_FCR_FARG(dwArgument) | EEFC_FCR_FCMD(dwCommand) ;
+}
+
+/**
+ * \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 ) ;
+ IAP_PerformCommand( 0, EEFC_FCR_FKEY(0x5A) | EEFC_FCR_FARG(dwArgument) | EEFC_FCR_FCMD(dwCommand) ) ;
+
+ return (efc->EEFC_FSR & (EEFC_FSR_FLOCKE | EEFC_FSR_FCMDE)) ;
+ }
+ else
+ {
+ uint32_t dwStatus ;
+
+ efc->EEFC_FCR = EEFC_FCR_FKEY(0x5A) | 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) ) ;
+ }
+}
+
+
diff --git a/sam3s_example/src/exceptions.c b/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/exceptions.c
similarity index 100%
rename from sam3s_example/src/exceptions.c
rename to sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/exceptions.c
diff --git a/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/flashd.c b/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/flashd.c
new file mode 100644
index 00000000..7dc7276c
--- /dev/null
+++ b/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/flashd.c
@@ -0,0 +1,512 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * 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:
+ *
+ * - 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 programing operation, the user has to follow these few steps :
+ *
+ * - Configue flash wait states to initializes the flash.
+ * - Checks whether a region to be programmed is locked.
+ * - Unlocks the user region to be programmed if the region have locked before.
+ * - Erases the user page before program (optional).
+ * - Writes the user page from the page buffer.
+ * - Locks the region of programmed area if any.
+ *
+ *
+ * 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
+#include
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ *----------------------------------------------------------------------------*/
+
+//static NO_INIT uint8_t _aucPageBuffer[IFLASH_PAGE_SIZE] ;
+static NO_INIT uint32_t _adwPageBuffer[IFLASH_PAGE_SIZE/4] ;
+static uint8_t* _aucPageBuffer = (uint8_t*)_adwPageBuffer;
+static NO_INIT uint32_t _dwUseIAP ;
+
+/*----------------------------------------------------------------------------
+ * Local macros
+ *----------------------------------------------------------------------------*/
+
+#define min( a, b ) (((a) < (b)) ? (a) : (b))
+
+/*----------------------------------------------------------------------------
+ * 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", *pdwActualStart, *pdwActualEnd ) ;
+}
+
+
+/*----------------------------------------------------------------------------
+ * Exported functions
+ *----------------------------------------------------------------------------*/
+
+/**
+ * \brief Initializes the flash driver.
+ *
+ * \param mck Master clock frequency in Hz.
+ */
+
+extern void FLASHD_Initialize( uint32_t dwMCk, uint32_t dwUseIAP )
+{
+ EFC_DisableFrdyIt( EFC ) ;
+
+ if ( (dwMCk/1000000) >= 64 )
+ {
+ EFC_SetWaitState( EFC, 2 ) ;
+ }
+ else
+ {
+ if ( (dwMCk/1000000) >= 50 )
+ {
+ EFC_SetWaitState( EFC, 1 ) ;
+ }
+ else
+ {
+ EFC_SetWaitState( EFC, 0 ) ;
+ }
+ }
+
+ _dwUseIAP=dwUseIAP ;
+}
+
+/**
+ * \brief Erases the entire flash.
+ *
+ * \param address 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 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 sizeTmp ;
+ uint32_t *pAlignedDestination ;
+ uint32_t *pAlignedSource ;
+
+ 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( _aucPageBuffer, (void *) pageAddress, offset);
+
+ /* Buffer data */
+ memcpy( _aucPageBuffer + offset, pvBuffer, writeSize);
+
+ /* Post-buffer data */
+ memcpy( _aucPageBuffer + 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 ;
+ pAlignedSource = (uint32_t*)_adwPageBuffer ;
+ sizeTmp = IFLASH_PAGE_SIZE ;
+
+ while ( sizeTmp >= 4 )
+ {
+ *pAlignedDestination++ = *pAlignedSource++;
+ sizeTmp -= 4;
+ }
+
+ /* Send writing command */
+ dwError = EFC_PerformCommand( pEfc, EFC_FCMD_EWP, page, _dwUseIAP ) ;
+ if ( dwError )
+ {
+ return dwError ;
+ }
+
+ /* Progression */
+ dwAddress += IFLASH_PAGE_SIZE ;
+ 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 )
+{
+ Efc *pEfc ;
+ uint16_t startPage, endPage ;
+ uint8_t startRegion, endRegion ;
+ uint32_t numPagesInRegion ;
+ uint32_t status ;
+ uint32_t dwError ;
+ 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
+ dwError = EFC_PerformCommand( pEfc, EFC_FCMD_GLB, 0, _dwUseIAP ) ;
+ assert( !dwError ) ;
+ status = EFC_GetResult( pEfc ) ;
+
+ // Check status of each involved region
+ while ( startRegion < endRegion )
+ {
+ if ( (status & (1 << startRegion)) != 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 dwError ;
+ uint32_t dwStatus ;
+
+ assert( ucGPNVM < 2 ) ;
+
+ /* Get GPNVMs status */
+ dwError = EFC_PerformCommand( EFC, EFC_FCMD_GFB, 0, _dwUseIAP ) ;
+ assert( !dwError ) ;
+ 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 < 2 ) ;
+
+ 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 < 2 ) ;
+
+ if ( FLASHD_IsGPNVMSet( ucGPNVM ) )
+ {
+ return EFC_PerformCommand( EFC, EFC_FCMD_CFB, ucGPNVM, _dwUseIAP ) ;
+ }
+ else
+ {
+ return 0 ;
+ }
+}
+/**
+ * \brief Read the unique ID.
+ *
+ * \param uniqueID pointer on a 4bytes char containing the unique ID value.
+ * \returns 0 if successful; otherwise returns an error code.
+ */
+extern uint32_t FLASHD_ReadUniqueID( uint32_t* pdwUniqueID )
+{
+ uint32_t dwError ;
+
+ assert( pdwUniqueID != NULL ) ;
+
+ pdwUniqueID[0] = 0 ;
+ pdwUniqueID[1] = 0 ;
+ pdwUniqueID[2] = 0 ;
+ pdwUniqueID[3] = 0 ;
+
+ EFC_StartCommand( EFC, EFC_FCMD_STUI, 0 ) ;
+
+ 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) ;
+
+ dwError = EFC_PerformCommand( EFC, EFC_FCMD_SPUI, 0, _dwUseIAP ) ;
+ if ( dwError )
+ {
+ return dwError ;
+ }
+
+ return 0 ;
+}
diff --git a/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/hsmci.c b/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/hsmci.c
new file mode 100644
index 00000000..bcc811b9
--- /dev/null
+++ b/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/hsmci.c
@@ -0,0 +1,262 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * 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:
+ *
+ * - 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,
+ * not using PDC nor DMA to transfer data.
+ *
+ */
+
+/*---------------------------------------------------------------------------
+ * Headers
+ *---------------------------------------------------------------------------*/
+#include "chip.h"
+
+#include
+
+
+/*---------------------------------------------------------------------------
+ * Local macros
+ *---------------------------------------------------------------------------*/
+
+/** Reset MCI */
+#define MCI_RESET(pMciHw) (pMciHw->HSMCI_CR = HSMCI_CR_SWRST)
+
+/*---------------------------------------------------------------------------
+ * Exported functions
+ *---------------------------------------------------------------------------*/
+
+/**
+ * Enable MCI
+ * \param pMciHw Pointer to a MCI peripheral.
+ */
+void MCI_Enable(Hsmci *pMciHw)
+{
+ pMciHw->HSMCI_CR = HSMCI_CR_MCIEN;
+}
+
+/**
+ * Disable MCI
+ * \param pMciHw Pointer to a MCI peripheral.
+ */
+void MCI_Disable(Hsmci *pMciHw)
+{
+ pMciHw->HSMCI_CR = HSMCI_CR_MCIDIS;
+}
+
+/**
+ * Initializes a MCI driver instance and the underlying peripheral.
+ * \param pMci Pointer to a MCI driver instance.
+ * \param pMciHw Pointer to a MCI peripheral.
+ * \param mciId MCI peripheral identifier.
+ */
+void MCI_Init( Mcid *pMci, Hsmci *pMciHw, uint8_t mciId, uint32_t dwMCk )
+{
+ unsigned short clkDiv;
+
+ /* Initialize the MCI driver structure */
+ pMci->pMciHw = pMciHw;
+ pMci->mciId = mciId;
+ pMci->semaphore = 1;
+ pMci->pCommand = NULL;
+
+ /* Enable the MCI peripheral */
+ PMC_EnablePeripheral( mciId ) ;
+
+ /* Reset the MCI */
+ pMciHw->HSMCI_CR = HSMCI_CR_SWRST;
+
+ /* Disable the MCI */
+ pMciHw->HSMCI_CR = HSMCI_CR_MCIDIS | HSMCI_CR_PWSDIS;
+
+ /* Disable all the interrupts */
+ pMciHw->HSMCI_IDR = 0xFFFFFFFF;
+
+ /* Set the Data Timeout Register */
+ pMciHw->HSMCI_DTOR = HSMCI_DTOR_DTOCYC_Msk | HSMCI_DTOR_DTOMUL_Msk ;
+ /* CSTOR ? */
+ pMciHw->HSMCI_CSTOR = HSMCI_CSTOR_CSTOCYC_Msk | HSMCI_CSTOR_CSTOMUL_Msk ;
+
+ /* Set the Mode Register: 400KHz for MCK = 48MHz (CLKDIV = 58) */
+ clkDiv = (dwMCk / (MCI_INITIAL_SPEED * 2)) - 1;
+ pMciHw->HSMCI_MR = (clkDiv | (HSMCI_MR_PWSDIV( 0x07 )) ) ;
+
+ /* Set the SDCard Register 1-bit, slot A */
+ pMciHw->HSMCI_SDCR = HSMCI_SDCR_SDCSEL_SLOTA | HSMCI_SDCR_SDCBUS_1 ;
+
+ /* Enable the MCI and the Power Saving */
+ pMciHw->HSMCI_CR = HSMCI_CR_MCIEN;
+
+ /* Configure MCI */
+ pMciHw->HSMCI_CFG = HSMCI_CFG_FIFOMODE
+ | ((1 << 4) & HSMCI_CFG_FERRCTRL);
+
+ /* Disable the MCI peripheral clock. */
+ PMC_DisablePeripheral(mciId);
+}
+
+/**
+ * Configure the MCI CLKDIV in the MCI_MR register. The max. for MCI clock is
+ * MCK/2 and corresponds to CLKDIV = 0
+ * \param pMci Pointer to the low level MCI driver.
+ * \param mciSpeed MCI clock speed in Hz, 0 will not change current speed.
+ * \param mck MCK to generate MCI Clock, in Hz
+ * \return The actual speed used, 0 for fail.
+ */
+uint32_t MCI_SetSpeed( Mcid* pMci, uint32_t mciSpeed, uint32_t mck )
+{
+ Hsmci *pMciHw = pMci->pMciHw;
+ uint32_t mciMr;
+ uint32_t clkdiv;
+ uint8_t mciDis;
+
+ assert(pMci);
+ assert(pMciHw);
+
+ PMC_EnablePeripheral(pMci->mciId);
+ mciDis = PMC_IsPeriphEnabled(pMci->mciId);
+
+ mciMr = pMciHw->HSMCI_MR & (~(uint32_t)HSMCI_MR_CLKDIV_Msk);
+ /* Multimedia Card Interface clock (MCCK or MCI_CK) is Master Clock (MCK)
+ * divided by (2*(CLKDIV+1))
+ * mciSpeed = MCK / (2*(CLKDIV+1)) */
+ if (mciSpeed > 0)
+ {
+ clkdiv = (mck / 2 / mciSpeed);
+ /* Speed should not bigger than expired one */
+ if (mciSpeed < mck/2/clkdiv)
+ {
+ clkdiv ++;
+ }
+
+ if ( clkdiv > 0 )
+ {
+ clkdiv -= 1;
+ }
+ assert( (clkdiv & 0xFFFFFF00) == 0 ) ; /* "mciSpeed too small" */
+ }
+ else
+ {
+ clkdiv = 0 ;
+ }
+
+ /* Actual MCI speed */
+ mciSpeed = mck / 2 / (clkdiv + 1);
+ /* Modify MR */
+ pMciHw->HSMCI_MR = mciMr | clkdiv;
+ if ( mciDis )
+ {
+ PMC_DisablePeripheral( pMci->mciId ) ;
+ }
+
+ return (mciSpeed);
+}
+
+/**
+ * Configure the MCI_CFG to enable the HS mode
+ * \param pMci Pointer to the low level MCI driver.
+ * \param hsEnable 1 to enable, 0 to disable HS mode.
+ */
+uint8_t MCI_EnableHsMode(Mcid* pMci, uint8_t hsEnable)
+{
+ Hsmci *pMciHw = pMci->pMciHw;
+ uint32_t cfgr;
+ uint8_t mciDis;
+ uint8_t rc = 0;
+
+ assert(pMci);
+ assert(pMci->pMciHw);
+
+ PMC_EnablePeripheral(pMci->mciId);
+ mciDis = PMC_IsPeriphEnabled(pMci->mciId);
+
+ cfgr = pMciHw->HSMCI_CFG;
+ if (hsEnable == 1)
+ {
+ cfgr |= HSMCI_CFG_HSMODE;
+ }
+ else
+ {
+ if (hsEnable == 0)
+ {
+ cfgr &= ~(uint32_t)HSMCI_CFG_HSMODE;
+ }
+ else
+ {
+ rc = ((cfgr & HSMCI_CFG_HSMODE) != 0);
+ }
+ }
+
+ pMciHw->HSMCI_CFG = cfgr;
+ if (mciDis)
+ {
+ PMC_DisablePeripheral(pMci->mciId);
+ }
+
+ return rc;
+}
+
+/**
+ * Configure the MCI SDCBUS in the MCI_SDCR register. Only two modes available
+ *
+ * \param pMci Pointer to the low level MCI driver.
+ * \param busWidth MCI bus width mode. 00: 1-bit, 10: 4-bit, 11: 8-bit.
+ */
+uint32_t MCI_SetBusWidth(Mcid*pMci, uint32_t busWidth)
+{
+ Hsmci *pMciHw = pMci->pMciHw;
+ uint32_t mciSdcr;
+ uint8_t mciDis;
+
+ assert(pMci);
+ assert(pMci->pMciHw);
+
+ if( (busWidth != HSMCI_SDCR_SDCBUS_1) && (busWidth != HSMCI_SDCR_SDCBUS_4) && (busWidth != HSMCI_SDCR_SDCBUS_8) )
+ {
+ return (uint32_t)-1;
+ }
+
+ busWidth &= HSMCI_SDCR_SDCBUS_Msk ;
+
+ PMC_EnablePeripheral(pMci->mciId);
+ mciDis = PMC_IsPeriphEnabled(pMci->mciId);
+
+ mciSdcr = (pMciHw->HSMCI_SDCR & ~(uint32_t)(HSMCI_SDCR_SDCBUS_Msk));
+ pMciHw->HSMCI_SDCR = mciSdcr | busWidth;
+
+ if (mciDis)
+ {
+ PMC_DisablePeripheral(pMci->mciId);
+ }
+
+ return 0;
+}
+
diff --git a/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/hsmci_pdc.c b/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/hsmci_pdc.c
new file mode 100644
index 00000000..9f794cce
--- /dev/null
+++ b/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/hsmci_pdc.c
@@ -0,0 +1,305 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * 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:
+ *
+ * - 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,
+ * using PDC to transfer data.
+ *
+ */
+/*---------------------------------------------------------------------------
+ * Headers
+ *---------------------------------------------------------------------------*/
+
+#include "chip.h"
+
+#include
+
+/*---------------------------------------------------------------------------
+ * Local macros
+ *---------------------------------------------------------------------------*/
+
+/** Reset MCI */
+#define MCI_RESET(pMciHw) (pMciHw->HSMCI_CR = HSMCI_CR_SWRST)
+
+
+/*---------------------------------------------------------------------------
+ * Exported functions
+ *---------------------------------------------------------------------------*/
+
+/**
+ * Enable MCI
+ * \param pMciHw Pointer to a MCI peripheral.
+ */
+void MCI_Enable(Hsmci *pMciHw)
+{
+ pMciHw->HSMCI_CR = HSMCI_CR_MCIEN;
+}
+
+/**
+ * Disable MCI
+ * \param pMciHw Pointer to a MCI peripheral.
+ */
+void MCI_Disable(Hsmci *pMciHw)
+{
+ pMciHw->HSMCI_CR = HSMCI_CR_MCIDIS;
+}
+
+/**
+ * Initializes a MCI driver instance and the underlying peripheral.
+ * \param pMci Pointer to a MCI driver instance.
+ * \param pMciHw Pointer to a MCI peripheral.
+ * \param mciId MCI peripheral identifier.
+ */
+void MCI_Init( Mcid *pMci, Hsmci *pMciHw, uint8_t mciId, uint32_t dwMCk )
+{
+ unsigned short clkDiv;
+
+ /* Initialize the MCI driver structure */
+ pMci->pMciHw = pMciHw;
+ pMci->mciId = mciId;
+ pMci->semaphore = 1;
+ pMci->pCommand = NULL;
+
+ /* Enable the MCI peripheral */
+ PMC_EnablePeripheral( mciId ) ;
+
+ /* Reset the MCI */
+ pMciHw->HSMCI_CR = HSMCI_CR_SWRST;
+
+ /* Disable the MCI */
+ pMciHw->HSMCI_CR = HSMCI_CR_MCIDIS | HSMCI_CR_PWSDIS;
+
+ /* Disable all the interrupts */
+ pMciHw->HSMCI_IDR = 0xFFFFFFFF;
+
+ /* Set the Data Timeout Register */
+ pMciHw->HSMCI_DTOR = HSMCI_DTOR_DTOCYC_Msk | HSMCI_DTOR_DTOMUL_Msk ;
+ /* CSTOR ? */
+ pMciHw->HSMCI_CSTOR = HSMCI_CSTOR_CSTOCYC_Msk | HSMCI_CSTOR_CSTOMUL_Msk ;
+
+ /* Set the Mode Register: 400KHz for MCK = 48MHz (CLKDIV = 58) */
+ clkDiv = (dwMCk / (MCI_INITIAL_SPEED * 2)) - 1;
+ pMciHw->HSMCI_MR = (clkDiv | (HSMCI_MR_PWSDIV( 0x07 )) ) ;
+
+ /* Set the SDCard Register 1-bit, slot A */
+ pMciHw->HSMCI_SDCR = HSMCI_SDCR_SDCSEL_SLOTA | HSMCI_SDCR_SDCBUS_1 ;
+
+ /* Enable the MCI and the Power Saving */
+ pMciHw->HSMCI_CR = HSMCI_CR_MCIEN;
+
+ /* Configure MCI */
+ pMciHw->HSMCI_CFG = HSMCI_CFG_FIFOMODE
+ | ((1 << 4) & HSMCI_CFG_FERRCTRL);
+
+ /* Disable the MCI peripheral clock. */
+ PMC_DisablePeripheral(mciId);
+}
+
+/**
+ * Reset MCI HW interface and disable it.
+ * \param keepSettings Keep old register settings, including
+ * _MR, _SDCR, _DTOR, _CSTOR, _DMA and _CFG.
+ */
+void MCI_Reset(Mcid *pMci, uint8_t keepSettings)
+{
+ Hsmci *pMciHw = pMci->pMciHw;
+ uint8_t mciDis;
+
+ assert(pMci);
+ assert(pMci->pMciHw);
+
+ PMC_EnablePeripheral(pMci->mciId);
+ mciDis = PMC_IsPeriphEnabled(pMci->mciId);
+ if (keepSettings)
+ {
+ uint32_t mr, sdcr, dtor, cstor;
+ uint32_t cfg;
+ mr = pMciHw->HSMCI_MR;
+ sdcr = pMciHw->HSMCI_SDCR;
+ dtor = pMciHw->HSMCI_DTOR;
+ cstor = pMciHw->HSMCI_CSTOR;
+ cfg = pMciHw->HSMCI_CFG;
+ MCI_RESET(pMciHw);
+ MCI_Disable(pMciHw);
+ pMciHw->HSMCI_MR = mr;
+ pMciHw->HSMCI_SDCR = sdcr;
+ pMciHw->HSMCI_DTOR = dtor;
+ pMciHw->HSMCI_CSTOR = cstor;
+ pMciHw->HSMCI_CFG = cfg;
+ }
+ else
+ {
+ MCI_RESET(pMciHw);
+ MCI_Disable(pMciHw);
+ }
+ if ( mciDis )
+ {
+ PMC_DisablePeripheral( pMci->mciId ) ;
+ }
+}
+
+/**
+ * Configure the MCI CLKDIV in the MCI_MR register. The max. for MCI clock is
+ * MCK/2 and corresponds to CLKDIV = 0
+ * \param pMci Pointer to the low level MCI driver.
+ * \param mciSpeed MCI clock speed in Hz, 0 will not change current speed.
+ * \param mck MCK to generate MCI Clock, in Hz
+ * \return The actual speed used, 0 for fail.
+ */
+uint32_t MCI_SetSpeed( Mcid* pMci, uint32_t mciSpeed, uint32_t mck )
+{
+ Hsmci *pMciHw = pMci->pMciHw;
+ uint32_t mciMr;
+ uint32_t clkdiv;
+ uint8_t mciDis;
+
+ assert(pMci);
+ assert(pMciHw);
+
+ PMC_EnablePeripheral(pMci->mciId);
+ mciDis = PMC_IsPeriphEnabled(pMci->mciId);
+
+ mciMr = pMciHw->HSMCI_MR & (~(uint32_t)HSMCI_MR_CLKDIV_Msk);
+ /* Multimedia Card Interface clock (MCCK or MCI_CK) is Master Clock (MCK)
+ * divided by (2*(CLKDIV+1))
+ * mciSpeed = MCK / (2*(CLKDIV+1)) */
+ if (mciSpeed > 0)
+ {
+ clkdiv = (mck / 2 / mciSpeed);
+ /* Speed should not bigger than expired one */
+ if (mciSpeed < mck/2/clkdiv)
+ {
+ clkdiv ++;
+ }
+
+ if ( clkdiv > 0 )
+ {
+ clkdiv -= 1;
+ }
+ assert( (clkdiv & 0xFFFFFF00) == 0 ) ; /* "mciSpeed too small" */
+ }
+ else
+ {
+ clkdiv = 0 ;
+ }
+
+ /* Actual MCI speed */
+ mciSpeed = mck / 2 / (clkdiv + 1);
+ /* Modify MR */
+ pMciHw->HSMCI_MR = mciMr | clkdiv;
+ if ( mciDis )
+ {
+ PMC_DisablePeripheral( pMci->mciId ) ;
+ }
+
+ return (mciSpeed);
+}
+
+/**
+ * Configure the MCI_CFG to enable the HS mode
+ * \param pMci Pointer to the low level MCI driver.
+ * \param hsEnable 1 to enable, 0 to disable HS mode.
+ */
+uint8_t MCI_EnableHsMode(Mcid* pMci, uint8_t hsEnable)
+{
+ Hsmci *pMciHw = pMci->pMciHw;
+ uint32_t cfgr;
+ uint8_t mciDis;
+ uint8_t rc = 0;
+
+ assert(pMci);
+ assert(pMci->pMciHw);
+
+ PMC_EnablePeripheral(pMci->mciId);
+ mciDis = PMC_IsPeriphEnabled(pMci->mciId);
+
+ cfgr = pMciHw->HSMCI_CFG;
+ if (hsEnable == 1)
+ {
+ cfgr |= HSMCI_CFG_HSMODE;
+ }
+ else
+ {
+ if (hsEnable == 0)
+ {
+ cfgr &= ~(uint32_t)HSMCI_CFG_HSMODE;
+ }
+ else
+ {
+ rc = ((cfgr & HSMCI_CFG_HSMODE) != 0);
+ }
+ }
+
+ pMciHw->HSMCI_CFG = cfgr;
+ if (mciDis)
+ {
+ PMC_DisablePeripheral(pMci->mciId);
+ }
+
+ return rc;
+}
+
+/**
+ * Configure the MCI SDCBUS in the MCI_SDCR register. Only two modes available
+ *
+ * \param pMci Pointer to the low level MCI driver.
+ * \param busWidth MCI bus width mode. 00: 1-bit, 10: 4-bit, 11: 8-bit.
+ */
+uint32_t MCI_SetBusWidth(Mcid*pMci, uint32_t busWidth)
+{
+ Hsmci *pMciHw = pMci->pMciHw;
+ uint32_t mciSdcr;
+ uint8_t mciDis;
+
+ assert(pMci);
+ assert(pMci->pMciHw);
+
+ if( (busWidth != HSMCI_SDCR_SDCBUS_1) && (busWidth != HSMCI_SDCR_SDCBUS_4) && (busWidth != HSMCI_SDCR_SDCBUS_8) )
+ {
+ return (uint32_t)-1;
+ }
+
+ busWidth &= HSMCI_SDCR_SDCBUS_Msk ;
+
+ PMC_EnablePeripheral(pMci->mciId);
+ mciDis = PMC_IsPeriphEnabled(pMci->mciId);
+
+ mciSdcr = (pMciHw->HSMCI_SDCR & ~(uint32_t)(HSMCI_SDCR_SDCBUS_Msk));
+ pMciHw->HSMCI_SDCR = mciSdcr | busWidth;
+
+ if (mciDis)
+ {
+ PMC_DisablePeripheral(pMci->mciId);
+ }
+
+ return 0;
+}
+
diff --git a/sam3s_example/src/pio.c b/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/pio.c
similarity index 96%
rename from sam3s_example/src/pio.c
rename to sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/pio.c
index 3bc258e7..49a6741c 100644
--- a/sam3s_example/src/pio.c
+++ b/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/pio.c
@@ -36,7 +36,6 @@
#include "pio.h"
#include "pmc.h"
-
/*----------------------------------------------------------------------------
* Local functions
*----------------------------------------------------------------------------*/
diff --git a/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/pio_capture.c b/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/pio_capture.c
new file mode 100644
index 00000000..407a5c05
--- /dev/null
+++ b/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/pio_capture.c
@@ -0,0 +1,283 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2010, 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.
+ * ----------------------------------------------------------------------------
+ */
+
+/** \addtogroup pio_capture_module Working with PIO Parallel Capture Mode
+ * 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:
+ *
+ * - Enable PIOA peripheral clock
+ * - Configure the PDC
+ * - Configure the PIO Capture interrupt
+ * - Enable the PDC
+ * - Enable the PIO Capture
+ * - Wait for interrupt
+ * - Disable the interrupt
+ * - Read the DATA
+ *
+ *
+ * For more accurate information, please look at the PIO Parallel Capture Mode section of the
+ * Datasheet.
+ *
+ * Related files :\n
+ * \ref pio_capture.c\n
+ * \ref pio_capture.h\n
+ */
+/*@{*/
+/*@}*/
+/**
+ * \file
+ *
+ * Implementation of PIO Parallel Capture.
+ *
+ */
+
+/*----------------------------------------------------------------------------
+ * Headers
+ *----------------------------------------------------------------------------*/
+
+#include "chip.h"
+
+#include
+
+/*----------------------------------------------------------------------------
+ * 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;
+
+ /* Read the status register*/
+ pio_captureSr = PIOA->PIO_PCISR ;
+ pio_captureSr &= 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 Interupt 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 Interupt 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
+ * Be careful to configure the PDC before enable interrupt on pio capture.
+ * Otherway, the pdc will go in interrupt handler continuously.
+ * \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->dPDCsize <= PIO_RPR_RXPTR_Msk) ) ;
+ assert( (pInit->alwaysSampling < 2) );
+ assert( (pInit->halfSampling < 2) );
+ assert( (pInit->modeFirstSample < 2) );
+
+ /* PDC: Transfer Control Register */
+ /* Disables the PDC transmitter channel requests */
+ PIOA->PIO_PTCR = PIO_PTCR_RXTDIS;
+ /* PDC: Receive Pointer Register */
+ PIOA->PIO_RPR = (uint32_t)pInit->pData;
+ /* PDC: Receive Counter Register */
+ /* Starts peripheral data transfer if corresponding channel is active */
+ PIOA->PIO_RCR = PIO_RCR_RXCTR(pInit->dPDCsize);
+
+ /* PDC: Transfer Control Register */
+ /* Enables PDC receiver channel requests if RXTDIS is not set */
+ PIOA->PIO_PTCR = PIO_PTCR_RXTEN ;
+
+
+ /* Copy the API structure for interrupt handler */
+ _PioCaptureCopy = pInit;
+ /* PIO Parallel Capture Mode */
+ PIOA->PIO_PCMR = PIO_PCMR_DSIZE(pInit->dsize)
+ | ((pInit->alwaysSampling<<9) & PIO_PCMR_ALWYS)
+ | ((pInit->halfSampling<<10) & PIO_PCMR_HALFS)
+ | ((pInit->modeFirstSample<<11) & PIO_PCMR_FRSTS);
+
+ 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;
+ }
+// else
+// {
+// TRACE_INFO("No interruption, no callback\n\r");
+// }
+
+}
+
diff --git a/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/pio_it.c b/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/pio_it.c
new file mode 100644
index 00000000..c5351e81
--- /dev/null
+++ b/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/pio_it.c
@@ -0,0 +1,315 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, 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.
+ * ----------------------------------------------------------------------------
+ */
+
+/*
+ * \file
+ */
+
+/*----------------------------------------------------------------------------
+ * Headers
+ *----------------------------------------------------------------------------*/
+
+#include "chip.h"
+
+#include
+
+/*----------------------------------------------------------------------------
+ * 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* ) ;
+} 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 Stub, to handling all PIO Capture interrupts, if not defined.
+ */
+/*----------------------------------------------------------------------------*/
+//extern WEAK void PIO_CaptureHandler( void )
+//{
+//}
+
+/**
+ * \brief Handles all interrupts on the given PIO controller.
+ * \param id PIO controller ID.
+ * \param pPio PIO controller base address.
+ */
+extern void PioInterruptHandler( uint32_t id, Pio *pPio )
+{
+ uint32_t status;
+ uint32_t i;
+
+ /* Read PIO controller status */
+ status = pPio->PIO_ISR;
+ status &= pPio->PIO_IMR;
+
+ /* Check pending events */
+ if ( status != 0 )
+ {
+ TRACE_DEBUG( "PIO interrupt on PIO controller #%d\n\r", id ) ;
+
+ /* Find triggering source */
+ i = 0;
+ while ( status != 0 )
+ {
+ /* There cannot be an unconfigured source enabled. */
+ assert(i < _dwNumSources);
+
+ /* Source is configured on the same controller */
+ if (_aIntSources[i].pPin->id == id)
+ {
+ /* Source has PIOs whose statuses have changed */
+ if ( (status & _aIntSources[i].pPin->mask) != 0 )
+ {
+ TRACE_DEBUG( "Interrupt source #%d triggered\n\r", i ) ;
+
+ _aIntSources[i].handler(_aIntSources[i].pPin);
+ status &= ~(_aIntSources[i].pPin->mask);
+ }
+ }
+ i++;
+ }
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * Global Functions
+ *----------------------------------------------------------------------------*/
+
+/**
+ * \brief Parallel IO Controller A interrupt handler
+ * \Redefined PIOA interrupt handler for NVIC interrupt table.
+ */
+extern void PIOA_IrqHandler( void )
+{
+ if ( PIOA->PIO_PCISR != 0 )
+ {
+ PIO_CaptureHandler() ;
+ }
+
+ PioInterruptHandler( ID_PIOA, PIOA ) ;
+}
+
+/**
+ * \brief Parallel IO Controller B interrupt handler
+ * \Redefined PIOB interrupt handler for NVIC interrupt table.
+ */
+extern void PIOB_IrqHandler( void )
+{
+ PioInterruptHandler( ID_PIOB, PIOB ) ;
+}
+
+/**
+ * \brief Parallel IO Controller C interrupt handler
+ * \Redefined PIOC interrupt handler for NVIC interrupt table.
+ */
+extern void PIOC_IrqHandler( void )
+{
+ PioInterruptHandler( ID_PIOC, PIOC ) ;
+}
+
+/**
+ * \brief Initializes the PIO interrupt management logic
+ *
+ * The desired priority of PIO interrupts must be provided.
+ * Calling this function multiple times result in the reset of currently
+ * configured interrupts.
+ *
+ * \param priority PIO controller interrupts priority.
+ */
+extern void PIO_InitializeInterrupts( uint32_t dwPriority )
+{
+ TRACE_DEBUG( "PIO_Initialize()\n\r" ) ;
+
+ /* Reset sources */
+ _dwNumSources = 0 ;
+
+ /* Configure PIO interrupt sources */
+ TRACE_DEBUG( "PIO_Initialize: Configuring PIOA\n\r" ) ;
+ PMC_EnablePeripheral( ID_PIOA ) ;
+ PIOA->PIO_ISR ;
+ PIOA->PIO_IDR = 0xFFFFFFFF ;
+ NVIC_DisableIRQ( PIOA_IRQn ) ;
+ NVIC_ClearPendingIRQ( PIOA_IRQn ) ;
+ NVIC_SetPriority( PIOA_IRQn, dwPriority ) ;
+ NVIC_EnableIRQ( PIOA_IRQn ) ;
+
+ TRACE_DEBUG( "PIO_Initialize: Configuring PIOB\n\r" ) ;
+ PMC_EnablePeripheral( ID_PIOB ) ;
+ PIOB->PIO_ISR ;
+ PIOB->PIO_IDR = 0xFFFFFFFF ;
+ NVIC_DisableIRQ( PIOB_IRQn ) ;
+ NVIC_ClearPendingIRQ( PIOB_IRQn ) ;
+ NVIC_SetPriority( PIOB_IRQn, dwPriority ) ;
+ NVIC_EnableIRQ( PIOB_IRQn ) ;
+
+ TRACE_DEBUG( "PIO_Initialize: Configuring PIOC\n\r" ) ;
+ PMC_EnablePeripheral( ID_PIOC ) ;
+ PIOC->PIO_ISR ;
+ PIOC->PIO_IDR = 0xFFFFFFFF ;
+ NVIC_DisableIRQ( PIOC_IRQn ) ;
+ NVIC_ClearPendingIRQ( PIOC_IRQn ) ;
+ NVIC_SetPriority( PIOC_IRQn, dwPriority ) ;
+ NVIC_EnableIRQ( PIOC_IRQn ) ;
+}
+
+/**
+ * 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.
+ */
+extern void PIO_ConfigureIt( const Pin *pPin, void (*handler)( const Pin* ) )
+{
+ Pio* pio ;
+ InterruptSource* pSource ;
+
+ TRACE_DEBUG( "PIO_ConfigureIt()\n\r" ) ;
+
+ assert( pPin ) ;
+ pio = pPin->pio ;
+ assert( _dwNumSources < MAX_INTERRUPT_SOURCES ) ;
+
+ /* Define new source */
+ TRACE_DEBUG( "PIO_ConfigureIt: Defining new source #%d.\n\r", _dwNumSources ) ;
+
+ pSource = &(_aIntSources[_dwNumSources]) ;
+ pSource->pPin = pPin ;
+ pSource->handler = handler ;
+ _dwNumSources++ ;
+
+ /* PIO3 with additional interrupt support
+ * Configure additional interrupt mode registers */
+ if ( pPin->attribute & PIO_IT_AIME )
+ {
+ // enable additional interrupt mode
+ pio->PIO_AIMER = pPin->mask ;
+
+ // if bit field of selected pin is 1, set as Rising Edge/High level detection event
+ if ( pPin->attribute & PIO_IT_RE_OR_HL )
+ {
+ pio->PIO_REHLSR = pPin->mask ;
+ }
+ else
+ {
+ pio->PIO_FELLSR = pPin->mask;
+ }
+
+ /* if bit field of selected pin is 1, set as edge detection source */
+ if (pPin->attribute & PIO_IT_EDGE)
+ pio->PIO_ESR = pPin->mask;
+ else
+ pio->PIO_LSR = pPin->mask;
+ }
+ else
+ {
+ /* disable additional interrupt mode */
+ pio->PIO_AIMDR = pPin->mask;
+ }
+}
+
+/**
+ * Enables the given interrupt source if it has been configured. The status
+ * register of the corresponding PIO controller is cleared prior to enabling
+ * the interrupt.
+ * \param pPin Interrupt source to enable.
+ */
+extern void PIO_EnableIt( const Pin *pPin )
+{
+ TRACE_DEBUG( "PIO_EnableIt()\n\r" ) ;
+
+ assert( pPin != NULL ) ;
+
+#ifndef NOASSERT
+ uint32_t i = 0;
+ uint32_t dwFound = 0;
+
+ while ( (i < _dwNumSources) && !dwFound )
+ {
+ if ( _aIntSources[i].pPin == pPin )
+ {
+ dwFound = 1 ;
+ }
+ i++ ;
+ }
+ assert( dwFound != 0 ) ;
+#endif
+
+ pPin->pio->PIO_ISR;
+ pPin->pio->PIO_IER = pPin->mask ;
+}
+
+/**
+ * Disables a given interrupt source, with no added side effects.
+ *
+ * \param pPin Interrupt source to disable.
+ */
+extern void PIO_DisableIt( const Pin *pPin )
+{
+ assert( pPin != NULL ) ;
+
+ TRACE_DEBUG( "PIO_DisableIt()\n\r" ) ;
+
+ pPin->pio->PIO_IDR = pPin->mask;
+}
+
diff --git a/sam3s_example/src/pmc.c b/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/pmc.c
similarity index 86%
rename from sam3s_example/src/pmc.c
rename to sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/pmc.c
index 4efc8ba1..b71d7480 100644
--- a/sam3s_example/src/pmc.c
+++ b/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/pmc.c
@@ -32,6 +32,7 @@
*----------------------------------------------------------------------------*/
#include "chip.h"
+#include "trace.h"
#include
@@ -62,6 +63,7 @@ extern void PMC_EnablePeripheral( uint32_t dwId )
{
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", dwId ) ;
}
else
{
@@ -73,6 +75,7 @@ extern void PMC_EnablePeripheral( uint32_t dwId )
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", dwId + 32 ) ;
}
else
{
@@ -97,6 +100,7 @@ extern void PMC_DisablePeripheral( uint32_t dwId )
{
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", dwId ) ;
}
else
{
@@ -108,6 +112,7 @@ extern void PMC_DisablePeripheral( uint32_t dwId )
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", dwId + 32 ) ;
}
else
{
@@ -127,6 +132,7 @@ extern void PMC_EnableAllPeripherals( void )
PMC->PMC_PCER1 = MASK_STATUS1 ;
while ( (PMC->PMC_PCSR1 & MASK_STATUS1) != MASK_STATUS1 ) ;
+ TRACE_DEBUG( "Enable all periph clocks\n\r" ) ;
}
/**
@@ -140,6 +146,7 @@ extern void PMC_DisableAllPeripherals( void )
PMC->PMC_PCDR1 = MASK_STATUS1 ;
while ( (PMC->PMC_PCSR1 & MASK_STATUS1) != 0 ) ;
+ TRACE_DEBUG( "Disable all periph clocks\n\r" ) ;
}
/**
diff --git a/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/pwmc.c b/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/pwmc.c
new file mode 100644
index 00000000..6e367951
--- /dev/null
+++ b/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/pwmc.c
@@ -0,0 +1,608 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * 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:
+ *
+ * - 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
+ * 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 automaticly.
+ *
+ * Before enabling the channels, they must have been configured first.
+ * The main settings include:
+ *
+ * - Configuration of the clock generator.
+ * - Selection of the clock for each channel.
+ * - Configuration of output waveform characteristics, such as period, duty-cycle etc.
+ * - Configuration for synchronous channels if needed.
+ * - 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).
+ *
+ *
+ * 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
+#include
+
+/*----------------------------------------------------------------------------
+ * 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(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 ) ;
+ PWM->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;
+ }
+ /* Otherwise use update register */
+ else {
+
+ 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;
+ }
+ /* Otherwise use update register */
+ else {
+
+ 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);
+ }
+ /* Otherwise use update register */
+ else {
+ pPwm->PWM_CH_NUM[channel].PWM_DTUPD = timeH | (timeL << 16);
+ }
+}
+
+/**
+ * \brief Configures Syncronous channel with the given parameters.
+ * Beware: At this time, the channels should be disabled.
+ *
+ * \param channels Bitwise OR of Syncronous channels.
+ * \param updateMode Syncronous 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;
+ }
+ /* Otherwise use update register */
+ else {
+
+ 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 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 Sends the contents of buffer through a PWMC peripheral, using the PDC to
+ * take care of the transfer.
+ *
+ * Note: Duty cycle of syncronous channels can update by PDC
+ * when the field UPDM (Update Mode) in the PWM_SCM register is set to 2.
+ *
+ * \param pwmc Pointer to an Pwm instance.
+ * \param buffer Data buffer to send.
+ * \param length Length of the data buffer.
+ */
+uint8_t PWMC_WriteBuffer(Pwm *pwmc,
+ void *buffer,
+ uint32_t length)
+{
+ /* Check if first bank is free */
+ if (pwmc->PWM_TCR == 0) {
+
+ pwmc->PWM_TPR = (uint32_t) buffer;
+ pwmc->PWM_TCR = length;
+ pwmc->PWM_PTCR = PERIPH_PTCR_TXTEN;
+ return 1;
+ }
+ /* Check if second bank is free */
+ else if (pwmc->PWM_TNCR == 0) {
+
+ pwmc->PWM_TNPR = (uint32_t) buffer;
+ pwmc->PWM_TNCR = length;
+ return 1;
+ }
+
+ /* No free banks */
+ return 0;
+}
+
+/**
+ * \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 Enalbe override output.
+ *
+ * \param value Bitwise OR of output selection.
+ * \param sync 0: enable the output asyncronously, 1: enable it syncronously
+ */
+void PWMC_EnableOverrideOutput( Pwm* pPwm, uint32_t value, uint32_t sync)
+{
+ if (sync) {
+
+ pPwm->PWM_OSSUPD = value;
+ } else {
+
+ pPwm->PWM_OSS = value;
+ }
+}
+
+/**
+ * \brief Disalbe override output.
+ *
+ * \param value Bitwise OR of output selection.
+ * \param sync 0: enable the output asyncronously, 1: enable it syncronously
+ */
+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_FPV = 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_CMPxM = mode;
+ pPwm->PWM_CMP[x].PWM_CMPxV = value;
+ }
+ /* Otherwise use update register */
+ else {
+ pPwm->PWM_CMP[x].PWM_CMPxMUPD = mode;
+ pPwm->PWM_CMP[x].PWM_CMPxVUPD = 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_ELxMR[0] = mode;
+ } else if (x == 1) {
+ pPwm->PWM_ELxMR[1] = mode;
+ }
+}
diff --git a/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/rtc.c b/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/rtc.c
new file mode 100644
index 00000000..60ab3ef2
--- /dev/null
+++ b/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/rtc.c
@@ -0,0 +1,464 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * 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:
+ *
+ * - 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
+ * 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 :
+ *
+ * - Set UPDTIM and/or UPDCAL bit(s) in RTC_CR,
+ * - Polling or IRQ on the ACKUPD bit of RTC_CR,
+ * - Clear ACKUPD bit in RTC_SCCR,
+ * - Update Time and/or Calendar values in RTC_TIMR/RTC_CALR (BCD format),
+ * - Clear UPDTIM and/or UPDCAL bit in RTC_CR.
+ *
+ * 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 occurence 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
+#include
+
+/*----------------------------------------------------------------------------
+ * 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 sucess, 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) ;
+}
+
diff --git a/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/rtt.c b/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/rtt.c
new file mode 100644
index 00000000..516a196c
--- /dev/null
+++ b/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/rtt.c
@@ -0,0 +1,132 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * 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:
+ *
+ * - 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
+ * 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 balue. 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:
+ *
+ * - Programming PTPRES in RTT_MR to feeding the timer with a 1Hz signal.
+ * - Writing the bit RTTRST in RTT_MR to restart the timer with new settings.
+ *
+ *
+ * An alarm can be set to happen on second by setting alarm value in RTT_AR.
+ * Alarm occurence 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
+
+/*----------------------------------------------------------------------------
+ * 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;
+}
diff --git a/sam3s_example/src/spi.c b/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/spi.c
similarity index 100%
rename from sam3s_example/src/spi.c
rename to sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/spi.c
diff --git a/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/spi_pdc.c b/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/spi_pdc.c
new file mode 100644
index 00000000..eea16ba8
--- /dev/null
+++ b/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/spi_pdc.c
@@ -0,0 +1,251 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * 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:
+ *
+ * - 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_pdc_module SPI PDC driver
+ * \ingroup spi_at45_module
+ * The Spi driver is a low level spi driver which performs SPI device Initializes,
+ * spi transfer and receive. It can be used by upper SPI driver such as AT45
+ * driver and AT26 driver.
+ *
+ * \section Usage
+ *
+ * - Initializes a SPI instance and the corresponding SPI hardware,
+ * Configure SPI in Master Mode using SPID_Configure().
+ * - Configures the SPI characteristics (such as Clock Polarity, Phase,
+ * transfers delay and Baud Rate) for the device corresponding to the
+ * chip select using SPID_ConfigureCS().
+ * - Starts a SPI master transfer using SPID_SendCommand().
+ * The transfer is performed using the PDC channels.
+ * - It enable the SPI clock.
+ * - Set the corresponding peripheral chip select.
+ * - Initialize the two SPI PDC buffers.
+ * - Initialize SPI_TPR and SPI_TCR with SPI command data and size
+ * to send command data first.
+ * - Initialize SPI_RPR and SPI_RCR with SPI command data and size
+ * as dummy value.
+ * - Initialize SPI_TNPR and SPI_TNCR with rest of the data to be
+ * transfered.(if the data specified in cmd structure)
+ * - Initialize SPI_RNPR and SPI_RNCR with rest of the data to be
+ * received.(if the data specified in cmd structure)
+ * - Initialize the callback function if specified.
+ * - Enable transmitter and receiver.
+ * - Example for sending a command to the dataflash through the SPI.
+ * \code
+ * /// Build command to be sent.
+ * ...
+ * // Send Command and data through the SPI
+ * if (SPID_SendCommand(pAt45->pSpid, pCommand)) {
+ * return AT45_ERROR_SPI;
+ * }
+ * \endcode
+ * - The SPI_Handler() must be called by the SPI Interrupt Service Routine
+ * with the corresponding Spi instance. It is invokes to check for pending
+ * interrupts.
+ * - Example for initializing SPI interrupt handler in upper application.
+ * \code
+ * AIC_ConfigureIT(AT91C_ID_SPI, 0, SPI_Handler);
+ * \endcode
+ *
+ * Related files :\n
+ * \ref spi_pdc.c\n
+ * \ref spi_pdc.h.\n
+*/
+/*@{*/
+/*@}*/
+
+
+/**
+ * \file
+ *
+ * Implementation of SPI PDC driver.
+ *
+ */
+
+/*----------------------------------------------------------------------------
+ * Headers
+ *----------------------------------------------------------------------------*/
+#include "chip.h"
+
+/*----------------------------------------------------------------------------
+ * Exported functions
+ *----------------------------------------------------------------------------*/
+
+/**
+ * \brief Initializes the Spid structure and the corresponding SPI hardware.
+ *
+ * \param pSpid Pointer to a Spid instance.
+ * \param pSpiHw Associated SPI peripheral.
+ * \param spiId SPI peripheral identifier.
+ * \return 0.
+ */
+extern uint32_t SPID_Configure( Spid* pSpid, Spi* pSpiHw, uint8_t spiId )
+{
+ /* Initialize the SPI structure*/
+ pSpid->pSpiHw = pSpiHw ;
+ pSpid->spiId = spiId ;
+ pSpid->semaphore = 1 ;
+ pSpid->pCurrentCommand = 0 ;
+
+ /* Enable the SPI clock*/
+ PMC_EnablePeripheral( pSpid->spiId ) ;
+
+ /* Configure SPI in Master Mode with No CS selected !!! */
+ SPI_Configure( pSpiHw, pSpid->spiId, SPI_MR_MSTR | SPI_MR_MODFDIS | SPI_MR_PCS_Msk ) ;
+
+ /* Enable the SPI */
+ SPI_Enable( pSpiHw ) ;
+
+ /* Disable the SPI clock */
+ PMC_DisablePeripheral( pSpid->spiId ) ;
+
+ return 0 ;
+}
+
+/**
+ * \brief Configures the parameters for the device corresponding to the cs.
+ *
+ * \param pSpid Pointer to a Spid instance.
+ * \param cs number corresponding to the SPI chip select.
+ * \param csr SPI_CSR value to setup.
+ */
+extern void SPID_ConfigureCS( Spid* pSpid, uint32_t dwCS, uint32_t dwCSR )
+{
+ SPI_ConfigureNPCS( pSpid->pSpiHw, dwCS, dwCSR ) ;
+}
+
+/**
+ * \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.
+ * \return 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.
+ */
+extern uint32_t SPID_SendCommand( Spid* pSpid, SpidCmd* pCommand )
+{
+ Spi* pSpiHw = pSpid->pSpiHw ;
+ uint32_t dwSpiMr ;
+
+ /* Try to get the dataflash semaphore */
+ if ( pSpid->semaphore == 0 )
+ {
+ return SPID_ERROR_LOCK ;
+ }
+ pSpid->semaphore-- ;
+
+ /* Enable the SPI clock */
+ PMC_EnablePeripheral( pSpid->spiId ) ;
+
+ /* Disable transmitter and receiver*/
+ SPI_PdcDisableRx( pSpiHw ) ;
+ SPI_PdcDisableTx( pSpiHw ) ;
+
+ /* Write to the MR register*/
+ dwSpiMr = pSpiHw->SPI_MR ;
+ dwSpiMr |= SPI_MR_PCS_Msk ;
+ dwSpiMr &= ~((1 << pCommand->spiCs) << 16 ) ;
+ pSpiHw->SPI_MR=dwSpiMr ;
+
+ /* Initialize the two SPI PDC buffer*/
+ SPI_PdcSetRx( pSpiHw, pCommand->pCmd, pCommand->cmdSize, pCommand->pData, pCommand->dataSize ) ;
+ SPI_PdcSetTx( pSpiHw, pCommand->pCmd, pCommand->cmdSize, pCommand->pData, pCommand->dataSize ) ;
+
+ /* Initialize the callback*/
+ pSpid->pCurrentCommand = pCommand ;
+
+ /* Enable transmitter and receiver*/
+ SPI_PdcEnableRx( pSpiHw ) ;
+ SPI_PdcEnableTx( pSpiHw ) ;
+
+ /* Enable buffer complete interrupt*/
+ SPI_EnableIt( pSpiHw, SPI_IER_RXBUFF ) ;
+
+ return 0 ;
+}
+
+/**
+ * \brief The SPI_Handler must be called by the SPI Interrupt Service Routine with the
+ * corresponding Spi instance.
+ *
+ * \note The SPI_Handler will unlock the Spi semaphore and invoke the upper application
+ * callback.
+ * \param pSpid Pointer to a Spid instance.
+ */
+extern void SPID_Handler( Spid* pSpid )
+{
+ SpidCmd *pSpidCmd = pSpid->pCurrentCommand ;
+ Spi *pSpiHw = pSpid->pSpiHw ;
+ volatile uint32_t spiSr ;
+
+ /* Read the status register*/
+ spiSr = pSpiHw->SPI_SR ;
+ if ( spiSr & SPI_SR_RXBUFF )
+ {
+ /* Disable transmitter and receiver */
+ SPI_PdcDisableRx( pSpiHw ) ;
+ SPI_PdcDisableTx( pSpiHw ) ;
+
+ /* Disable the SPI clock*/
+ PMC_DisablePeripheral( pSpid->spiId ) ;
+
+ /* Disable buffer complete interrupt */
+ SPI_DisableIt( pSpiHw, SPI_IDR_RXBUFF ) ;
+
+ /* Release the dataflash semaphore*/
+ pSpid->semaphore++ ;
+
+ /* Invoke the callback associated with the current command*/
+ if ( pSpidCmd && pSpidCmd->callback )
+ {
+ pSpidCmd->callback( 0, pSpidCmd->pArgument ) ;
+ }
+
+ /* Nothing must be done after. A new DF operation may have been started
+ in the callback function.*/
+ }
+}
+
+/**
+ * \brief Returns 1 if the SPI driver is currently busy executing a command; otherwise
+ * returns 0.
+ * \param pSpid Pointer to a Spid instance.
+ */
+extern uint32_t SPID_IsBusy( const Spid* pSpid )
+{
+ if ( pSpid->semaphore == 0 )
+ {
+ return 1 ;
+ }
+ else
+ {
+ return 0 ;
+ }
+}
diff --git a/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/ssc.c b/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/ssc.c
new file mode 100644
index 00000000..44c7256a
--- /dev/null
+++ b/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/ssc.c
@@ -0,0 +1,247 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * 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:
+ *
+ * - 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
+ * 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() and SSC_WriteBuffer()
+ * -# Receive data from the receiver using SSC_Read() and SSC_ReadBuffer()
+ * -# Disable the transmitter and/or the receiver using SSC_DisableTransmitter()
+ * and SSC_DisableReceiver()
+ *
+ * For more accurate information, please look at the RTC 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 bitRate bit rate.
+ * \param masterClock master clock.
+ */
+void SSC_Configure(uint32_t bitRate, uint32_t masterClock)
+{
+ /* Enable SSC peripheral clock */
+ PMC->PMC_PCER0 = 1 << ID_SSC;
+
+ /* Reset, disable receiver & transmitter */
+ SSC->SSC_CR = SSC_CR_RXDIS | SSC_CR_TXDIS | SSC_CR_SWRST;
+
+ SSC->SSC_PTCR = SSC_PTCR_RXTDIS | SSC_PTCR_TXTDIS;
+ /* Configure clock frequency */
+ if (bitRate != 0) {
+
+ SSC->SSC_CMR = masterClock / (2 * bitRate);
+ }
+ else {
+
+ SSC->SSC_CMR = 0;
+ }
+}
+
+/**
+ * \brief Configures the transmitter of a SSC peripheral.
+ * \param tcmr Transmit Clock Mode Register value.
+ * \param tfmr Transmit Frame Mode Register value.
+ */
+void SSC_ConfigureTransmitter(uint32_t tcmr, uint32_t tfmr)
+{
+ SSC->SSC_TCMR = tcmr;
+ SSC->SSC_TFMR = tfmr;
+}
+
+/**
+ * \brief Configures the receiver of a SSC peripheral.
+ * \param rcmr Receive Clock Mode Register value.
+ * \param rfmr Receive Frame Mode Register value.
+ */
+void SSC_ConfigureReceiver(uint32_t rcmr, uint32_t rfmr)
+{
+ SSC->SSC_RCMR = rcmr;
+ SSC->SSC_RFMR = rfmr;
+}
+
+/**
+ * \brief Enables the transmitter of a SSC peripheral.
+ */
+void SSC_EnableTransmitter(void)
+{
+ SSC->SSC_CR = SSC_CR_TXEN;
+}
+
+/**
+ * \brief Disables the transmitter of a SSC peripheral.
+ */
+void SSC_DisableTransmitter(void)
+{
+ SSC->SSC_CR = SSC_CR_TXDIS;
+}
+
+/**
+ * \brief Enables the receiver of a SSC peripheral.
+ */
+void SSC_EnableReceiver(void)
+{
+ SSC->SSC_CR = SSC_CR_RXEN;
+}
+
+/**
+ * \brief Disables the receiver of a SSC peripheral.
+ */
+void SSC_DisableReceiver(void)
+{
+ SSC->SSC_CR = SSC_CR_RXDIS;
+}
+
+/**
+ * \brief Enables one or more interrupt sources of a SSC peripheral.
+ * \param sources Bitwise OR of selected interrupt sources.
+ */
+void SSC_EnableInterrupts(uint32_t sources)
+{
+ SSC->SSC_IER = sources;
+}
+
+/**
+ * \brief Disables one or more interrupt sources of a SSC peripheral.
+ * \param sources Bitwise OR of selected interrupt sources.
+ */
+void SSC_DisableInterrupts(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 frame Data frame to send.
+ */
+void SSC_Write(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.
+ */
+uint32_t SSC_Read(void)
+{
+ while ((SSC->SSC_SR & SSC_SR_RXRDY) == 0);
+ return SSC->SSC_RHR;
+}
+
+/**
+ * \brief Sends the contents of a data buffer a SSC peripheral, using the PDC.
+ * \param buffer Data buffer to send.
+ * \param length Size of the data buffer.
+ * \return 1 if the buffer has been queued for transmission; otherwise returns 0.
+ */
+uint8_t SSC_WriteBuffer(void *buffer, uint32_t length)
+{
+ /* Check if first bank is free*/
+ if (SSC->SSC_TCR == 0) {
+
+ SSC->SSC_TPR = (uint32_t) buffer;
+ SSC->SSC_TCR = length;
+ SSC->SSC_PTCR = SSC_PTCR_TXTEN;
+ return 1;
+ }
+ /* Check if second bank is free*/
+ else if (SSC->SSC_TNCR == 0) {
+
+ SSC->SSC_TNPR = (uint32_t) buffer;
+ SSC->SSC_TNCR = length;
+ return 1;
+ }
+ return 0;
+}
+
+/**
+ * \brief Reads data coming from a SSC peripheral receiver and stores it into the
+ * giving buffer with PDC.
+ * \param buffer ata buffer used for reception.
+ * \param length Size of the data buffer.
+ * \return 1 if the buffer has been queued for reception; otherwise returns 0.
+ */
+uint8_t SSC_ReadBuffer(void *buffer, uint32_t length)
+{
+ /* Check if the first bank is free*/
+ if (SSC->SSC_RCR == 0) {
+
+ SSC->SSC_RPR = (uint32_t) buffer;
+ SSC->SSC_RCR = length;
+ SSC->SSC_PTCR = SSC_PTCR_RXTEN;
+ return 1;
+ }
+ /* Check if second bank is free*/
+ else if (SSC->SSC_RNCR == 0) {
+ SSC->SSC_RNPR = (uint32_t) buffer;
+ SSC->SSC_RNCR = length;
+ return 1;
+ }
+ return 0;
+}
diff --git a/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/supc.c b/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/supc.c
new file mode 100644
index 00000000..340bbd60
--- /dev/null
+++ b/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/supc.c
@@ -0,0 +1,196 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, 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.
+ * ----------------------------------------------------------------------------
+ */
+
+//------------------------------------------------------------------------------
+// Headers
+//------------------------------------------------------------------------------
+
+#include "chip.h"
+
+#include
+
+//------------------------------------------------------------------------------
+// Local definitions
+//------------------------------------------------------------------------------
+
+/// Key value for the SUPC_MR register.
+#define SUPC_KEY ((uint32_t) (0xA5 << 24))
+
+//------------------------------------------------------------------------------
+// Global functions
+//------------------------------------------------------------------------------
+
+#if !defined(__ICCARM__)
+__attribute__ ((section (".ramfunc"))) // GCC
+#endif
+//------------------------------------------------------------------------------
+/// Enables the flash power supply with the given wake-up setting.
+/// \param time Wake-up time.
+//------------------------------------------------------------------------------
+void SUPC_EnableFlash( Supc* pSupc, uint32_t dwTime )
+{
+ pSupc->SUPC_FWUTR = dwTime ;
+ pSupc->SUPC_MR = SUPC_KEY | pSupc->SUPC_MR | AT91C_SUPC_FLASHON ;
+
+ while ((pSupc->SUPC_SR & AT91C_SUPC_FLASHS) != AT91C_SUPC_FLASHS) ;
+}
+
+#if !defined(__ICCARM__)
+__attribute__ ((section (".ramfunc"))) // GCC
+#endif
+//------------------------------------------------------------------------------
+/// Disables the flash power supply.
+//------------------------------------------------------------------------------
+void SUPC_DisableFlash( Supc* pSupc )
+{
+ pSupc->SUPC_MR = SUPC_KEY | (pSupc->SUPC_MR & ~AT91C_SUPC_FLASHON) ;
+
+ while ((pSupc->SUPC_SR & AT91C_SUPC_FLASHS) == AT91C_SUPC_FLASHS) ;
+}
+
+//------------------------------------------------------------------------------
+/// Sets the voltage regulator output voltage.
+/// \param voltage Voltage to set.
+//------------------------------------------------------------------------------
+void SUPC_SetVoltageOutput( Supc* pSupc, uint32_t dwVoltage )
+{
+ assert( (voltage & ~AT91C_SUPC_VRVDD) == 0 ) ;
+
+ pSupc->SUPC_MR = SUPC_KEY | (pSupc->SUPC_MR & ~AT91C_SUPC_VRVDD) | dwVoltage ;
+}
+
+//------------------------------------------------------------------------------
+/// Puts the voltage regulator in deep mode.
+//------------------------------------------------------------------------------
+void SUPC_EnableDeepMode( Supc* pSupc )
+{
+ pSupc->SUPC_MR = SUPC_KEY | pSupc->SUPC_MR | AT91C_SUPC_VRDEEP ;
+}
+
+//------------------------------------------------------------------------------
+/// Puts the voltage regulator in normal mode.
+//------------------------------------------------------------------------------
+void SUPC_DisableDeepMode( Supc* pSupc )
+{
+ pSupc->SUPC_MR = SUPC_KEY | (pSupc->SUPC_MR & ~AT91C_SUPC_VRDEEP) ;
+}
+
+//-----------------------------------------------------------------------------
+/// Enables the backup SRAM power supply, so its data is saved while the device
+/// is in backup mode.
+//-----------------------------------------------------------------------------
+void SUPC_EnableSram( Supc* pSupc )
+{
+ pSupc->SUPC_MR = SUPC_KEY | pSupc->SUPC_MR | AT91C_SUPC_SRAMON ;
+}
+
+//-----------------------------------------------------------------------------
+/// Disables the backup SRAM power supply.
+//-----------------------------------------------------------------------------
+void SUPC_DisableSram( Supc* pSupc )
+{
+ pSupc->SUPC_MR = SUPC_KEY | (pSupc->SUPC_MR & ~AT91C_SUPC_SRAMON) ;
+}
+
+//-----------------------------------------------------------------------------
+/// Enables the RTC power supply.
+//-----------------------------------------------------------------------------
+void SUPC_EnableRtc( Supc* pSupc )
+{
+ pSupc->SUPC_MR = SUPC_KEY | pSupc->SUPC_MR | AT91C_SUPC_RTCON ;
+
+ while ((pSupc->SUPC_SR & AT91C_SUPC_RTS) != AT91C_SUPC_RTS) ;
+}
+
+//-----------------------------------------------------------------------------
+/// Disables the RTC power supply.
+//-----------------------------------------------------------------------------
+void SUPC_DisableRtc( Supc* pSupc )
+{
+ pSupc->SUPC_MR = SUPC_KEY | (pSupc->SUPC_MR & ~AT91C_SUPC_RTCON) ;
+
+ while ((pSupc->SUPC_SR & AT91C_SUPC_RTS) == AT91C_SUPC_RTS);
+}
+
+//-----------------------------------------------------------------------------
+/// Sets the BOD sampling mode (or disables it).
+/// \param mode BOD sampling mode.
+//-----------------------------------------------------------------------------
+void SUPC_SetBodSampling( Supc* pSupc, uint32_t dwMode )
+{
+ assert( (dwMode & ~AT91C_SUPC_BODSMPL) == 0 ) ;
+
+ pSupc->SUPC_BOMR &= ~AT91C_SUPC_BODSMPL;
+ pSupc->SUPC_BOMR |= dwMode ;
+}
+
+//------------------------------------------------------------------------------
+/// Disables the voltage regulator, which makes the device enter backup mode.
+//------------------------------------------------------------------------------
+void SUPC_DisableVoltageRegulator( Supc* pSupc )
+{
+ pSupc->SUPC_CR = SUPC_KEY | AT91C_SUPC_VROFF ;
+
+ while ( 1 ) ;
+}
+
+//------------------------------------------------------------------------------
+/// Shuts the device down so it enters Off mode.
+//------------------------------------------------------------------------------
+void SUPC_Shutdown( Supc* pSupc )
+{
+ pSupc->SUPC_CR = SUPC_KEY | AT91C_SUPC_SHDW ;
+
+ while (1);
+}
+
+//------------------------------------------------------------------------------
+/// Sets the wake-up sources when in backup mode.
+/// \param sources Wake-up sources to enable.
+//------------------------------------------------------------------------------
+void SUPC_SetWakeUpSources( Supc* pSupc, uint32_t dwSources )
+{
+ assert( (dwSources & ~0x0000000B) == 0 ) ;
+
+ pSupc->SUPC_WUMR &= ~0x0000000B;
+ pSupc->SUPC_WUMR |= dwSources ;
+}
+
+//------------------------------------------------------------------------------
+/// Sets the wake-up inputs when in backup mode.
+/// \param inputs Wake up inputs to enable.
+//------------------------------------------------------------------------------
+void SUPC_SetWakeUpInputs( Supc* pSupc, uint32_t dwInputs )
+{
+ assert( (dwInputs & ~0xFFFF) == 0 ) ;
+
+ pSupc->SUPC_WUIR &= ~0xFFFF ;
+ pSupc->SUPC_WUIR |= dwInputs ;
+}
+
diff --git a/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/tc.c b/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/tc.c
new file mode 100644
index 00000000..9cad5467
--- /dev/null
+++ b/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/tc.c
@@ -0,0 +1,175 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * 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:
+ *
+ * - 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 Timer Counter (TC).
+ *
+ */
+
+/*------------------------------------------------------------------------------
+ * Headers
+ *------------------------------------------------------------------------------*/
+
+#include "chip.h"
+
+#include
+
+/*------------------------------------------------------------------------------
+ * 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 )
+{
+ const uint32_t adwDivisors[5] = { 2, 8, 32, 128, dwBoardMCK / 32768 } ;
+
+ uint32_t dwIndex = 0 ;
+
+ /* 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 ;
+}
+
diff --git a/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/twi.c b/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/twi.c
new file mode 100644
index 00000000..c2fec947
--- /dev/null
+++ b/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/twi.c
@@ -0,0 +1,380 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * 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:
+ *
+ * - 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
+ * The TWI driver provides the interface to configure and use the TWI
+ * peripheral.
+ *
+ * \section Usage
+ *
+ * - Configures a TWI peripheral to operate in master mode, at the given
+ * frequency (in Hz) using TWI_Configure().
+ * - Sends a STOP condition on the TWI using TWI_Stop().
+ * - 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()).
+ * - 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.
+ * - 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.
+ * - 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().
+ * - Check if the current transmission is complete (the STOP has been sent)
+ * using TWI_TransferComplete().
+ * - Enables & disable the selected interrupts sources on a TWI peripheral
+ * using TWI_EnableIt() and TWI_DisableIt().
+ * - 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().
+ *
+ * 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
+
+/*----------------------------------------------------------------------------
+ * 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 Twi instance.
+ * \param twck Desired TWI clock frequency.
+ * \param mck Master clock frequency.
+ */
+void TWI_ConfigureMaster( Twi* 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 ) ;
+
+ /* SVEN: TWI Slave Mode Enabled */
+ pTwi->TWI_CR = TWI_CR_SVEN ;
+ /* Reset the TWI */
+ pTwi->TWI_CR = TWI_CR_SWRST ;
+ pTwi->TWI_RHR ;
+
+ /* TWI Slave Mode Disabled, TWI Master Mode Disabled. */
+ pTwi->TWI_CR = TWI_CR_SVDIS ;
+ pTwi->TWI_CR = TWI_CR_MSDIS ;
+
+ /* Set master mode */
+ pTwi->TWI_CR = TWI_CR_MSEN ;
+
+ /* Configure clock */
+ while ( !dwOk )
+ {
+ dwClDiv = ((dwMCk / (2 * dwTwCk)) - 4) / (1<TWI_CWGR = 0 ;
+ pTwi->TWI_CWGR = (dwCkDiv << 16) | (dwClDiv << 8) | dwClDiv ;
+}
+
+/**
+ * \brief Configures a TWI peripheral to operate in slave mode.
+ * \param pTwi Pointer to an Twi instance.
+ * \param slaveAddress Slave address.
+ */
+void TWI_ConfigureSlave(Twi *pTwi, uint8_t slaveAddress)
+{
+ uint32_t i;
+
+ /* TWI software reset */
+ pTwi->TWI_CR = TWI_CR_SWRST;
+ pTwi->TWI_RHR;
+
+ /* Wait at least 10 ms */
+ for (i=0; i < 1000000; i++);
+
+ /* TWI Slave Mode Disabled, TWI Master Mode Disabled*/
+ pTwi->TWI_CR = TWI_CR_SVDIS | TWI_CR_MSDIS;
+
+ /* Configure slave address. */
+ pTwi->TWI_SMR = 0;
+ pTwi->TWI_SMR = TWI_SMR_SADR(slaveAddress);
+
+ /* SVEN: TWI Slave Mode Enabled */
+ pTwi->TWI_CR = TWI_CR_SVEN;
+
+ /* Wait at least 10 ms */
+ for (i=0; i < 1000000; i++);
+ assert( (pTwi->TWI_CR & TWI_CR_SVDIS)!= TWI_CR_SVDIS ) ;
+}
+
+/**
+ * \brief Sends a STOP condition on the TWI.
+ * \param pTwi Pointer to an Twi instance.
+ */
+void TWI_Stop( Twi *pTwi )
+{
+ assert( pTwi != NULL ) ;
+
+ pTwi->TWI_CR = TWI_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 Twi instance.
+ * \param address Slave address on the bus.
+ * \param iaddress Optional internal address bytes.
+ * \param isize Number of internal address bytes.
+ */
+void TWI_StartRead(
+ Twi *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->TWI_MMR = 0;
+ pTwi->TWI_MMR = (isize << 8) | TWI_MMR_MREAD | (address << 16);
+
+ /* Set internal address bytes */
+ pTwi->TWI_IADR = 0;
+ pTwi->TWI_IADR = iaddress;
+
+ /* Send START condition */
+ pTwi->TWI_CR = TWI_CR_START;
+}
+
+/**
+ * \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 Twi instance.
+ * \return byte read.
+ */
+uint8_t TWI_ReadByte(Twi *pTwi)
+{
+ assert( pTwi != NULL ) ;
+
+ return pTwi->TWI_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 Twi instance.
+ * \param byte Byte to send.
+ */
+void TWI_WriteByte(Twi *pTwi, uint8_t byte)
+{
+ assert( pTwi != NULL ) ;
+
+ pTwi->TWI_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 Twi 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(
+ Twi *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->TWI_MMR = 0;
+ pTwi->TWI_MMR = (isize << 8) | (address << 16);
+
+ /* Set internal address bytes. */
+ pTwi->TWI_IADR = 0;
+ pTwi->TWI_IADR = iaddress;
+
+ /* Write first byte to send.*/
+ TWI_WriteByte(pTwi, byte);
+}
+
+/**
+ * \brief Check if a byte have been receiced from TWI.
+ * \param pTwi Pointer to an Twi 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(Twi *pTwi)
+{
+ return ((pTwi->TWI_SR & TWI_SR_RXRDY) == TWI_SR_RXRDY);
+}
+
+/**
+ * \brief Check if a byte have been sent to TWI.
+ * \param pTwi Pointer to an Twi 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(Twi *pTwi)
+{
+ return ((pTwi->TWI_SR & TWI_SR_TXRDY) == TWI_SR_TXRDY);
+}
+
+/**
+ * \brief Check if current transmission is complet.
+ * \param pTwi Pointer to an Twi instance.
+ * \return 1 if the current transmission is complete (the STOP has been sent);
+ * otherwise returns 0.
+ */
+uint8_t TWI_TransferComplete(Twi *pTwi)
+{
+ return ((pTwi->TWI_SR & TWI_SR_TXCOMP) == TWI_SR_TXCOMP);
+}
+
+/**
+ * \brief Enables the selected interrupts sources on a TWI peripheral.
+ * \param pTwi Pointer to an Twi instance.
+ * \param sources Bitwise OR of selected interrupt sources.
+ */
+void TWI_EnableIt(Twi *pTwi, uint32_t sources)
+{
+ assert( pTwi != NULL ) ;
+ assert( (sources & 0xFFFFF088) == 0 ) ;
+
+ pTwi->TWI_IER = sources;
+}
+
+/**
+ * \brief Disables the selected interrupts sources on a TWI peripheral.
+ * \param pTwi Pointer to an Twi instance.
+ * \param sources Bitwise OR of selected interrupt sources.
+ */
+void TWI_DisableIt(Twi *pTwi, uint32_t sources)
+{
+ assert( pTwi != NULL ) ;
+ assert( (sources & 0xFFFFF088) == 0 ) ;
+
+ pTwi->TWI_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 Twi instance.
+ * \return TWI status register.
+ */
+uint32_t TWI_GetStatus(Twi *pTwi)
+{
+ assert( pTwi != NULL ) ;
+
+ return pTwi->TWI_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 Twi instance.
+ */
+uint32_t TWI_GetMaskedStatus(Twi *pTwi)
+{
+ uint32_t status;
+
+ assert( pTwi != NULL ) ;
+
+ status = pTwi->TWI_SR;
+ status &= pTwi->TWI_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 Twi instance.
+ */
+void TWI_SendSTOPCondition(Twi *pTwi)
+{
+ assert( pTwi != NULL ) ;
+
+ pTwi->TWI_CR |= TWI_CR_STOP;
+}
+
diff --git a/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/twid.c b/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/twid.c
new file mode 100644
index 00000000..a7dcdfdd
--- /dev/null
+++ b/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/twid.c
@@ -0,0 +1,342 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * 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:
+ *
+ * - 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
+
+/*----------------------------------------------------------------------------
+ * Definition
+ *----------------------------------------------------------------------------*/
+#define TWITIMEOUTMAX 50000
+
+/*----------------------------------------------------------------------------
+ * 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;
+
+/*----------------------------------------------------------------------------
+ * Global functions
+ *----------------------------------------------------------------------------*/
+/**
+ * \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, Twi *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
+ * occuring 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 ;
+ Twi *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, TWI_IDR_RXRDY);
+ TWI_EnableIt(pTwi, TWI_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, TWI_IDR_TXRDY);
+ TWI_EnableIt(pTwi, TWI_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, TWI_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)
+{
+ Twi *pTwi;
+ AsyncTwi *pTransfer;
+ uint32_t timeout;
+
+ 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;
+ }
+
+ /* Set STOP signal if only one byte is sent*/
+ if (num == 1) {
+
+ TWI_Stop(pTwi);
+ }
+
+ /* 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, TWI_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*/
+ timeout = 0;
+ while( !TWI_ByteReceived(pTwi) && (++timeoutpTwi;
+ AsyncTwi *pTransfer = (AsyncTwi *) pTwid->pTransfer;
+ uint32_t timeout;
+
+ 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, TWI_IER_TXRDY);
+ }
+ /* Synchronous transfer*/
+ else {
+
+ // Start write
+ TWI_StartWrite(pTwi, address, iaddress, isize, *pData++);
+ num--;
+
+ /* Send all bytes */
+ while (num > 0) {
+
+ /* Wait before sending the next byte */
+ timeout = 0;
+ while( !TWI_ByteSent(pTwi) && (++timeout
+ * Configure USART with expected mode and baudrate(see \ref USART_Configure), which could be done by:
+ * -# Resetting and disabling transmitter and receiver by setting US_CR(Control Register).
+ * -# Conifguring the USART in a specific mode by setting USART_MODE bits in US_MR(Mode Register)
+ * -# Setting baudrate which is different from mode to mode.
+
+ * Enable transmitter or receiver respectively by set US_CR_TXEN or US_CR_RXEN in US_CR.
+ * Read from or write to the peripheral with \ref USART_ReadBuffer or \ref USART_WriteBuffer.
+ These operations could be done by polling or interruption.
+ * For polling, check the status bit US_CSR_ENDRX/US_CSR_RXBUFF (READ) or US_CSR_ENDTX/
+ US_CSR_TXBUFE (WRITE).
+ * For interruption,"enable" the status bit through US_IER and
+ realize the hanler with USARTx_IrqHandler according to IRQ vector
+ table which is defined in board_cstartup_.c
+ To enable the interruption of USART,it should be configured with priority and enabled first through
+ NVIC .
+ *
+ *
+ * For more accurate information, please look at the USART section of the
+ * Datasheet.
+ *
+ * Related files :\n
+ * \ref usart.c\n
+ * \ref usart.h\n
+*/
+
+
+
+/**
+ * \file
+ *
+ * Implementation of USART (Universal Synchronous Asynchronous Receiver Transmitter)
+ * controller.
+ *
+ */
+/*------------------------------------------------------------------------------
+ * Headers
+ *------------------------------------------------------------------------------*/
+#include "chip.h"
+#include "trace.h"
+
+#include
+#include
+
+/*----------------------------------------------------------------------------
+ * Local definitions
+ *----------------------------------------------------------------------------*/
+
+
+/*------------------------------------------------------------------------------
+ * Exported functions
+ *------------------------------------------------------------------------------*/
+
+/**
+ * \brief Configures an USART peripheral with the specified parameters.
+ *
+ *
+ * \param usart 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 *usart,
+ uint32_t mode,
+ uint32_t baudrate,
+ uint32_t masterClock)
+{
+ /* Reset and disable receiver & transmitter*/
+ usart->US_CR = US_CR_RSTRX | US_CR_RSTTX
+ | US_CR_RXDIS | US_CR_TXDIS;
+
+ /* Configure mode*/
+ usart->US_MR = mode;
+
+ /* Configure baudrate*/
+ /* Asynchronous, no oversampling*/
+ if ( ((mode & US_MR_SYNC) == 0) && ((mode & US_MR_OVER) == 0) )
+ {
+ usart->US_BRGR = (masterClock / baudrate) / 16;
+ }
+
+ if( ((mode & US_MR_USART_MODE_SPI_MASTER) == US_MR_USART_MODE_SPI_MASTER)
+ || ((mode & US_MR_SYNC) == US_MR_SYNC))
+ {
+ if( (mode & US_MR_USCLKS_Msk) == US_MR_USCLKS_MCK)
+ {
+ usart->US_BRGR = masterClock / baudrate;
+ }
+ else
+ {
+ if ( (mode & US_MR_USCLKS_DIV) == US_MR_USCLKS_DIV)
+ {
+ usart->US_BRGR = masterClock / baudrate / 8;
+ }
+ }
+ }
+ /* TODO other modes*/
+}
+/**
+ * \brief Enables or disables the transmitter of an USART peripheral.
+ *
+ *
+ * \param usart Pointer to an USART peripheral
+ * \param enabled If true, the transmitter is enabled; otherwise it is
+ * disabled.
+ */
+void USART_SetTransmitterEnabled(Usart *usart, uint8_t enabled)
+{
+ if (enabled) {
+
+ usart->US_CR = US_CR_TXEN;
+ }
+ else {
+
+ usart->US_CR = US_CR_TXDIS;
+ }
+}
+
+/**
+ * \brief Enables or disables the receiver of an USART peripheral
+ *
+ *
+ * \param usart Pointer to an USART peripheral
+ * \param enabled If true, the receiver is enabled; otherwise it is disabled.
+ */
+void USART_SetReceiverEnabled(Usart *usart,
+ uint8_t enabled)
+{
+ if (enabled) {
+
+ usart->US_CR = US_CR_RXEN;
+ }
+ else {
+
+ usart->US_CR = US_CR_RXDIS;
+ }
+}
+
+/**
+ * \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 usart 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 *usart,
+ uint16_t data,
+ volatile uint32_t timeOut)
+{
+ if (timeOut == 0) {
+
+ while ((usart->US_CSR & US_CSR_TXEMPTY) == 0);
+ }
+ else {
+
+ while ((usart->US_CSR & US_CSR_TXEMPTY) == 0) {
+
+ if (timeOut == 0) {
+
+ TRACE_ERROR("USART_Write: Timed out.\n\r");
+ return;
+ }
+ timeOut--;
+ }
+ }
+
+ usart->US_THR = data;
+}
+
+/**
+ * \brief Sends the contents of a data buffer through the specified USART peripheral.
+ * This function returns immediately (1 if the buffer has been queued, 0
+ * otherwise); poll the ENDTX and TXBUFE bits of the USART status register
+ * to check for the transfer completion.
+ *
+ * \param usart Pointer to an USART peripheral.
+ * \param buffer Pointer to the data buffer to send.
+ * \param size Size of the data buffer (in bytes).
+ */
+uint8_t USART_WriteBuffer(
+ Usart *usart,
+ void *buffer,
+ uint32_t size)
+{
+ /* Check if the first PDC bank is free*/
+ if ((usart->US_TCR == 0) && (usart->US_TNCR == 0)) {
+
+ usart->US_TPR = (uint32_t) buffer;
+ usart->US_TCR = size;
+ usart->US_PTCR = US_PTCR_TXTEN;
+
+ return 1;
+ }
+ /* Check if the second PDC bank is free*/
+ else if (usart->US_TNCR == 0) {
+
+ usart->US_TNPR = (uint32_t) buffer;
+ usart->US_TNCR = size;
+
+ return 1;
+ }
+ else {
+
+ return 0;
+ }
+}
+
+
+/**
+ * \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 usart Pointer to an USART peripheral.
+ * \param timeOut Time out value (0 -> no timeout).
+ */
+uint16_t USART_Read(
+ Usart *usart,
+ volatile uint32_t timeOut)
+{
+ if (timeOut == 0) {
+
+ while ((usart->US_CSR & US_CSR_RXRDY) == 0);
+ }
+ else {
+
+ while ((usart->US_CSR & US_CSR_RXRDY) == 0) {
+
+ if (timeOut == 0) {
+
+ TRACE_ERROR( "USART_Read: Timed out.\n\r" ) ;
+ return 0;
+ }
+ timeOut--;
+ }
+ }
+
+ return usart->US_RHR;
+}
+
+/**
+ * \brief Reads data from an USART peripheral, filling the provided buffer until it
+ * becomes full. This function returns immediately with 1 if the buffer has
+ * been queued for transmission; otherwise 0.
+ *
+ * \param usart Pointer to an USART peripheral.
+ * \param buffer Pointer to the buffer where the received data will be stored.
+ * \param size Size of the data buffer (in bytes).
+ */
+uint8_t USART_ReadBuffer(Usart *usart,
+ void *buffer,
+ uint32_t size)
+{
+ /* Check if the first PDC bank is free*/
+ if ((usart->US_RCR == 0) && (usart->US_RNCR == 0)) {
+
+ usart->US_RPR = (uint32_t) buffer;
+ usart->US_RCR = size;
+ usart->US_PTCR = US_PTCR_RXTEN;
+
+ return 1;
+ }
+ /* Check if the second PDC bank is free*/
+ else if (usart->US_RNCR == 0) {
+
+ usart->US_RNPR = (uint32_t) buffer;
+ usart->US_RNCR = size;
+
+ return 1;
+ }
+ else {
+
+ return 0;
+ }
+}
+
+/**
+ * \brief Returns 1 if some data has been received and can be read from an USART;
+ * otherwise returns 0.
+ *
+ * \param usart Pointer to an Usart instance.
+ */
+uint8_t USART_IsDataAvailable(Usart *usart)
+{
+ if ((usart->US_CSR & US_CSR_RXRDY) != 0) {
+
+ return 1;
+ }
+ else {
+
+ return 0;
+ }
+}
+
+/**
+ * \brief Sets the filter value for the IRDA demodulator.
+ *
+ * \param pUsart Pointer to an Usart instance.
+ * \param filter Filter value.
+ */
+void USART_SetIrdaFilter(Usart *pUsart, uint8_t filter)
+{
+ assert( pUsart != NULL ) ;
+
+ pUsart->US_IF = filter;
+}
+
+/**
+ * \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 usart Pointer to an USART peripheral.
+ * \param c Character to send
+ */
+void USART_PutChar(
+ Usart *usart,
+ uint8_t c)
+{
+ /* Wait for the transmitter to be ready*/
+ while ((usart->US_CSR & US_CSR_TXEMPTY) == 0);
+
+ /* Send character*/
+ usart->US_THR = c;
+
+ /* Wait for the transfer to complete*/
+ while ((usart->US_CSR & US_CSR_TXEMPTY) == 0);
+}
+
+/**
+ * \brief Return 1 if a character can be read in USART
+ */
+uint32_t USART_IsRxReady(Usart *usart)
+{
+ return (usart->US_CSR & US_CSR_RXRDY);
+}
+/**
+ * \brief Get present status
+ */
+uint32_t USART_GetStatus(Usart *usart)
+{
+ return usart->US_CSR;
+}
+/**
+ * \brief Enable interrupt
+ */
+void USART_EnableIt(Usart *usart,uint32_t mode)
+{
+ usart->US_IER = mode;
+}
+/**
+ * \brief Disable interrupt
+ */
+void USART_DisableIt(Usart *usart,uint32_t mode)
+{
+ usart->US_IDR = mode;
+}
+/**
+ * \brief Reads and returns a character from the USART.
+ *
+ * \note This function is synchronous (i.e. uses polling).
+ * \param usart Pointer to an USART peripheral.
+ * \return Character received.
+ */
+uint8_t USART_GetChar(Usart *usart)
+{
+ while ((usart->US_CSR & US_CSR_RXRDY) == 0);
+ return usart->US_RHR;
+}
diff --git a/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/wdt.c b/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/wdt.c
new file mode 100644
index 00000000..f8a493b5
--- /dev/null
+++ b/sam3s_example/atmel_softpack_libraries/libchip_sam3s/source/wdt.c
@@ -0,0 +1,132 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * 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:
+ *
+ * - 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
+ * 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:
+ *
+ * - Enable watchdog with given mode using \ref WDT_Enable().
+ *
- Restart the watchdog using \ref WDT_Restart() within the watchdog period.
+ *
+ *
+ * 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
+
+/*----------------------------------------------------------------------------
+ * 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) ;
+}
diff --git a/sam3s_example/cmsis b/sam3s_example/cmsis
new file mode 120000
index 00000000..895b6776
--- /dev/null
+++ b/sam3s_example/cmsis
@@ -0,0 +1 @@
+./atmel_softpack_libraries/libchip_sam3s/cmsis
\ No newline at end of file
diff --git a/sam3s_example/cmsis/core_cm3.c b/sam3s_example/cmsis/core_cm3.c
deleted file mode 100644
index 46ca332b..00000000
--- a/sam3s_example/cmsis/core_cm3.c
+++ /dev/null
@@ -1,817 +0,0 @@
-/**************************************************************************//**
- * @file core_cm3.c
- * @brief CMSIS Cortex-M3 Core Peripheral Access Layer Source File
- * @version V1.30
- * @date 30. October 2009
- *
- * @note
- * Copyright (C) 2009 ARM Limited. All rights reserved.
- *
- * @par
- * ARM Limited (ARM) is supplying this software for use with Cortex-M
- * processor based microcontrollers. This file can be freely distributed
- * within development tools that are supporting such ARM based processors.
- *
- * @par
- * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
- * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
- * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
- * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
- *
- ******************************************************************************/
-
-/*
- * Remo Giermann:
- * 2012/01/09 - fixed __STREX[BHW] functions
- *
- *
- */
-
-#include
-
-/* define compiler specific symbols */
-#if defined ( __CC_ARM )
- #define __ASM __asm /*!< asm keyword for ARM Compiler */
- #define __INLINE __inline /*!< inline keyword for ARM Compiler */
-
-#elif defined ( __ICCARM__ )
- #define __ASM __asm /*!< asm keyword for IAR Compiler */
- #define __INLINE inline /*!< inline keyword for IAR Compiler. Only avaiable in High optimization mode! */
-
-#elif defined ( __GNUC__ )
- #define __ASM __asm /*!< asm keyword for GNU Compiler */
- #define __INLINE inline /*!< inline keyword for GNU Compiler */
-
-#elif defined ( __TASKING__ )
- #define __ASM __asm /*!< asm keyword for TASKING Compiler */
- #define __INLINE inline /*!< inline keyword for TASKING Compiler */
-
-#endif
-
-uint32_t __get_PSP(void) ;
-void __set_PSP(uint32_t topOfProcStack) ;
-uint32_t __get_MSP(void) ;
-void __set_MSP(uint32_t mainStackPointer) ;
-uint32_t __REV16(uint16_t value) ;
-int32_t __REVSH(int16_t value) ;
-uint32_t __RBIT(uint32_t value) ;
-uint8_t __LDREXB(uint8_t *addr) ;
-uint16_t __LDREXH(uint16_t *addr) ;
-uint32_t __LDREXW(uint32_t *addr) ;
-uint32_t __STREXB(uint8_t value, uint8_t *addr) ;
-uint32_t __STREXH(uint16_t value, uint16_t *addr) ;
-uint32_t __STREXW(uint32_t value, uint32_t *addr) ;
-
-uint32_t __get_BASEPRI(void) ;
-void __set_BASEPRI(uint32_t basePri) ;
-uint32_t __get_PRIMASK(void) ;
-void __set_PRIMASK(uint32_t priMask) ;
-uint32_t __get_FAULTMASK(void) ;
-void __set_FAULTMASK(uint32_t faultMask) ;
-uint32_t __get_CONTROL(void) ;
-void __set_CONTROL(uint32_t control) ;
-uint32_t __REV(uint32_t value) ;
-
-/* ################### Compiler specific Intrinsics ########################### */
-
-#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
-/* ARM armcc specific functions */
-
-/**
- * @brief Return the Process Stack Pointer
- *
- * @return ProcessStackPointer
- *
- * Return the actual process stack pointer
- */
-__ASM uint32_t __get_PSP(void)
-{
- mrs r0, psp
- bx lr
-}
-
-/**
- * @brief Set the Process Stack Pointer
- *
- * @param topOfProcStack Process Stack Pointer
- *
- * Assign the value ProcessStackPointer to the MSP
- * (process stack pointer) Cortex processor register
- */
-__ASM void __set_PSP(uint32_t topOfProcStack)
-{
- msr psp, r0
- bx lr
-}
-
-/**
- * @brief Return the Main Stack Pointer
- *
- * @return Main Stack Pointer
- *
- * Return the current value of the MSP (main stack pointer)
- * Cortex processor register
- */
-__ASM uint32_t __get_MSP(void)
-{
- mrs r0, msp
- bx lr
-}
-
-/**
- * @brief Set the Main Stack Pointer
- *
- * @param topOfMainStack Main Stack Pointer
- *
- * Assign the value mainStackPointer to the MSP
- * (main stack pointer) Cortex processor register
- */
-__ASM void __set_MSP(uint32_t mainStackPointer)
-{
- msr msp, r0
- bx lr
-}
-
-/**
- * @brief Reverse byte order in unsigned short value
- *
- * @param value value to reverse
- * @return reversed value
- *
- * Reverse byte order in unsigned short value
- */
-__ASM uint32_t __REV16(uint16_t value)
-{
- rev16 r0, r0
- bx lr
-}
-
-/**
- * @brief Reverse byte order in signed short value with sign extension to integer
- *
- * @param value value to reverse
- * @return reversed value
- *
- * Reverse byte order in signed short value with sign extension to integer
- */
-__ASM int32_t __REVSH(int16_t value)
-{
- revsh r0, r0
- bx lr
-}
-
-
-#if (__ARMCC_VERSION < 400000)
-
-/**
- * @brief Remove the exclusive lock created by ldrex
- *
- * Removes the exclusive lock which is created by ldrex.
- */
-__ASM void __CLREX(void)
-{
- clrex
-}
-
-/**
- * @brief Return the Base Priority value
- *
- * @return BasePriority
- *
- * Return the content of the base priority register
- */
-__ASM uint32_t __get_BASEPRI(void)
-{
- mrs r0, basepri
- bx lr
-}
-
-/**
- * @brief Set the Base Priority value
- *
- * @param basePri BasePriority
- *
- * Set the base priority register
- */
-__ASM void __set_BASEPRI(uint32_t basePri)
-{
- msr basepri, r0
- bx lr
-}
-
-/**
- * @brief Return the Priority Mask value
- *
- * @return PriMask
- *
- * Return state of the priority mask bit from the priority mask register
- */
-__ASM uint32_t __get_PRIMASK(void)
-{
- mrs r0, primask
- bx lr
-}
-
-/**
- * @brief Set the Priority Mask value
- *
- * @param priMask PriMask
- *
- * Set the priority mask bit in the priority mask register
- */
-__ASM void __set_PRIMASK(uint32_t priMask)
-{
- msr primask, r0
- bx lr
-}
-
-/**
- * @brief Return the Fault Mask value
- *
- * @return FaultMask
- *
- * Return the content of the fault mask register
- */
-__ASM uint32_t __get_FAULTMASK(void)
-{
- mrs r0, faultmask
- bx lr
-}
-
-/**
- * @brief Set the Fault Mask value
- *
- * @param faultMask faultMask value
- *
- * Set the fault mask register
- */
-__ASM void __set_FAULTMASK(uint32_t faultMask)
-{
- msr faultmask, r0
- bx lr
-}
-
-/**
- * @brief Return the Control Register value
- *
- * @return Control value
- *
- * Return the content of the control register
- */
-__ASM uint32_t __get_CONTROL(void)
-{
- mrs r0, control
- bx lr
-}
-
-/**
- * @brief Set the Control Register value
- *
- * @param control Control value
- *
- * Set the control register
- */
-__ASM void __set_CONTROL(uint32_t control)
-{
- msr control, r0
- bx lr
-}
-
-#endif /* __ARMCC_VERSION */
-
-
-
-#elif (defined (__ICCARM__)) /*------------------ ICC Compiler -------------------*/
-/* IAR iccarm specific functions */
-#pragma diag_suppress=Pe940
-
-/**
- * @brief Return the Process Stack Pointer
- *
- * @return ProcessStackPointer
- *
- * Return the actual process stack pointer
- */
-uint32_t __get_PSP(void)
-{
- __ASM("mrs r0, psp");
- __ASM("bx lr");
-}
-
-/**
- * @brief Set the Process Stack Pointer
- *
- * @param topOfProcStack Process Stack Pointer
- *
- * Assign the value ProcessStackPointer to the MSP
- * (process stack pointer) Cortex processor register
- */
-void __set_PSP(uint32_t topOfProcStack)
-{
- __ASM("msr psp, r0");
- __ASM("bx lr");
-}
-
-/**
- * @brief Return the Main Stack Pointer
- *
- * @return Main Stack Pointer
- *
- * Return the current value of the MSP (main stack pointer)
- * Cortex processor register
- */
-uint32_t __get_MSP(void)
-{
- __ASM("mrs r0, msp");
- __ASM("bx lr");
-}
-
-/**
- * @brief Set the Main Stack Pointer
- *
- * @param topOfMainStack Main Stack Pointer
- *
- * Assign the value mainStackPointer to the MSP
- * (main stack pointer) Cortex processor register
- */
-void __set_MSP(uint32_t topOfMainStack)
-{
- __ASM("msr msp, r0");
- __ASM("bx lr");
-}
-
-/**
- * @brief Reverse byte order in unsigned short value
- *
- * @param value value to reverse
- * @return reversed value
- *
- * Reverse byte order in unsigned short value
- */
-uint32_t __REV16(uint16_t value)
-{
- __ASM("rev16 r0, r0");
- __ASM("bx lr");
-}
-
-/**
- * @brief Reverse bit order of value
- *
- * @param value value to reverse
- * @return reversed value
- *
- * Reverse bit order of value
- */
-uint32_t __RBIT(uint32_t value)
-{
- __ASM("rbit r0, r0");
- __ASM("bx lr");
-}
-
-/**
- * @brief LDR Exclusive (8 bit)
- *
- * @param *addr address pointer
- * @return value of (*address)
- *
- * Exclusive LDR command for 8 bit values)
- */
-uint8_t __LDREXB(uint8_t *addr)
-{
- __ASM("ldrexb r0, [r0]");
- __ASM("bx lr");
-}
-
-/**
- * @brief LDR Exclusive (16 bit)
- *
- * @param *addr address pointer
- * @return value of (*address)
- *
- * Exclusive LDR command for 16 bit values
- */
-uint16_t __LDREXH(uint16_t *addr)
-{
- __ASM("ldrexh r0, [r0]");
- __ASM("bx lr");
-}
-
-/**
- * @brief LDR Exclusive (32 bit)
- *
- * @param *addr address pointer
- * @return value of (*address)
- *
- * Exclusive LDR command for 32 bit values
- */
-uint32_t __LDREXW(uint32_t *addr)
-{
- __ASM("ldrex r0, [r0]");
- __ASM("bx lr");
-}
-
-/**
- * @brief STR Exclusive (8 bit)
- *
- * @param value value to store
- * @param *addr address pointer
- * @return successful / failed
- *
- * Exclusive STR command for 8 bit values
- */
-uint32_t __STREXB(uint8_t value, uint8_t *addr)
-{
- __ASM("strexb r2, r0, [r1]");
- __ASM("mov r2, r0");
- __ASM("bx lr");
-}
-
-/**
- * @brief STR Exclusive (16 bit)
- *
- * @param value value to store
- * @param *addr address pointer
- * @return successful / failed
- *
- * Exclusive STR command for 16 bit values
- */
-uint32_t __STREXH(uint16_t value, uint16_t *addr)
-{
- __ASM("strexh r2, r0, [r1]");
- __ASM("mov r2, r0");
- __ASM("bx lr");
-}
-
-/**
- * @brief STR Exclusive (32 bit)
- *
- * @param value value to store
- * @param *addr address pointer
- * @return successful / failed
- *
- * Exclusive STR command for 32 bit values
- */
-uint32_t __STREXW(uint32_t value, uint32_t *addr)
-{
- __ASM("strex r2, r0, [r1]");
- __ASM("mov r2, r0");
- __ASM("bx lr");
-}
-
-#pragma diag_default=Pe940
-
-
-#elif (defined (__GNUC__)) /*------------------ GNU Compiler ---------------------*/
-/* GNU gcc specific functions */
-
-/**
- * @brief Return the Process Stack Pointer
- *
- * @return ProcessStackPointer
- *
- * Return the actual process stack pointer
- */
-/*extern uint32_t __get_PSP(void) __attribute__( ( naked ) ); */
-uint32_t __get_PSP(void)
-{
- uint32_t result=0;
-
- __ASM volatile ("MRS %0, psp\n\t"
- "MOV r0, %0 \n\t"
- "BX lr \n\t" : "=r" (result) );
- return(result);
-}
-
-/**
- * @brief Set the Process Stack Pointer
- *
- * @param topOfProcStack Process Stack Pointer
- *
- * Assign the value ProcessStackPointer to the MSP
- * (process stack pointer) Cortex processor register
- */
-/*void __set_PSP(uint32_t topOfProcStack) __attribute__( ( naked ) ); */
-void __set_PSP(uint32_t topOfProcStack)
-{
- __ASM volatile ("MSR psp, %0\n\t"
- "BX lr \n\t" : : "r" (topOfProcStack) );
-}
-
-/**
- * @brief Return the Main Stack Pointer
- *
- * @return Main Stack Pointer
- *
- * Return the current value of the MSP (main stack pointer)
- * Cortex processor register
- */
-/*uint32_t __get_MSP(void) __attribute__( ( naked ) ); */
-uint32_t __get_MSP(void)
-{
- uint32_t result=0;
-
- __ASM volatile ("MRS %0, msp\n\t"
- "MOV r0, %0 \n\t"
- "BX lr \n\t" : "=r" (result) );
- return(result);
-}
-
-/**
- * @brief Set the Main Stack Pointer
- *
- * @param topOfMainStack Main Stack Pointer
- *
- * Assign the value mainStackPointer to the MSP
- * (main stack pointer) Cortex processor register
- */
-/*void __set_MSP(uint32_t topOfMainStack) __attribute__( ( naked ) ); */
-void __set_MSP(uint32_t topOfMainStack)
-{
- __ASM volatile ("MSR msp, %0\n\t"
- "BX lr \n\t" : : "r" (topOfMainStack) );
-}
-
-/**
- * @brief Return the Base Priority value
- *
- * @return BasePriority
- *
- * Return the content of the base priority register
- */
-uint32_t __get_BASEPRI(void)
-{
- uint32_t result=0;
-
- __ASM volatile ("MRS %0, basepri_max" : "=r" (result) );
- return(result);
-}
-
-/**
- * @brief Set the Base Priority value
- *
- * @param basePri BasePriority
- *
- * Set the base priority register
- */
-void __set_BASEPRI(uint32_t value)
-{
- __ASM volatile ("MSR basepri, %0" : : "r" (value) );
-}
-
-/**
- * @brief Return the Priority Mask value
- *
- * @return PriMask
- *
- * Return state of the priority mask bit from the priority mask register
- */
-uint32_t __get_PRIMASK(void)
-{
- uint32_t result=0;
-
- __ASM volatile ("MRS %0, primask" : "=r" (result) );
- return(result);
-}
-
-/**
- * @brief Set the Priority Mask value
- *
- * @param priMask PriMask
- *
- * Set the priority mask bit in the priority mask register
- */
-void __set_PRIMASK(uint32_t priMask)
-{
- __ASM volatile ("MSR primask, %0" : : "r" (priMask) );
-}
-
-/**
- * @brief Return the Fault Mask value
- *
- * @return FaultMask
- *
- * Return the content of the fault mask register
- */
-uint32_t __get_FAULTMASK(void)
-{
- uint32_t result=0;
-
- __ASM volatile ("MRS %0, faultmask" : "=r" (result) );
- return(result);
-}
-
-/**
- * @brief Set the Fault Mask value
- *
- * @param faultMask faultMask value
- *
- * Set the fault mask register
- */
-void __set_FAULTMASK(uint32_t faultMask)
-{
- __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) );
-}
-
-/**
- * @brief Return the Control Register value
-*
-* @return Control value
- *
- * Return the content of the control register
- */
-uint32_t __get_CONTROL(void)
-{
- uint32_t result=0;
-
- __ASM volatile ("MRS %0, control" : "=r" (result) );
- return(result);
-}
-
-/**
- * @brief Set the Control Register value
- *
- * @param control Control value
- *
- * Set the control register
- */
-void __set_CONTROL(uint32_t control)
-{
- __ASM volatile ("MSR control, %0" : : "r" (control) );
-}
-
-
-/**
- * @brief Reverse byte order in integer value
- *
- * @param value value to reverse
- * @return reversed value
- *
- * Reverse byte order in integer value
- */
-uint32_t __REV(uint32_t value)
-{
- uint32_t result=0;
-
- __ASM volatile ("rev %0, %1" : "=r" (result) : "r" (value) );
- return(result);
-}
-
-/**
- * @brief Reverse byte order in unsigned short value
- *
- * @param value value to reverse
- * @return reversed value
- *
- * Reverse byte order in unsigned short value
- */
-uint32_t __REV16(uint16_t value)
-{
- uint32_t result=0;
-
- __ASM volatile ("rev16 %0, %1" : "=r" (result) : "r" (value) );
- return(result);
-}
-
-/**
- * @brief Reverse byte order in signed short value with sign extension to integer
- *
- * @param value value to reverse
- * @return reversed value
- *
- * Reverse byte order in signed short value with sign extension to integer
- */
-int32_t __REVSH(int16_t value)
-{
- uint32_t result=0;
-
- __ASM volatile ("revsh %0, %1" : "=r" (result) : "r" (value) );
- return(result);
-}
-
-/**
- * @brief Reverse bit order of value
- *
- * @param value value to reverse
- * @return reversed value
- *
- * Reverse bit order of value
- */
-uint32_t __RBIT(uint32_t value)
-{
- uint32_t result=0;
-
- __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) );
- return(result);
-}
-
-/**
- * @brief LDR Exclusive (8 bit)
- *
- * @param *addr address pointer
- * @return value of (*address)
- *
- * Exclusive LDR command for 8 bit value
- */
-uint8_t __LDREXB(uint8_t *addr)
-{
- uint8_t result=0;
-
- __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) );
- return(result);
-}
-
-/**
- * @brief LDR Exclusive (16 bit)
- *
- * @param *addr address pointer
- * @return value of (*address)
- *
- * Exclusive LDR command for 16 bit values
- */
-uint16_t __LDREXH(uint16_t *addr)
-{
- uint16_t result=0;
-
- __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) );
- return(result);
-}
-
-/**
- * @brief LDR Exclusive (32 bit)
- *
- * @param *addr address pointer
- * @return value of (*address)
- *
- * Exclusive LDR command for 32 bit values
- */
-uint32_t __LDREXW(uint32_t *addr)
-{
- uint32_t result=0;
-
- __ASM volatile ("ldrex %0, [%1]" : "=r" (result) : "r" (addr) );
- return(result);
-}
-
-/**
- * @brief STR Exclusive (8 bit)
- *
- * @param value value to store
- * @param *addr address pointer
- * @return successful / failed
- *
- * Exclusive STR command for 8 bit values
- */
-uint32_t __STREXB(uint8_t value, uint8_t *addr)
-{
- uint32_t result=0;
-
- __ASM volatile ("strexb %0, %2, [%1]" : "=&r" (result) : "r" (addr), "r" (value) );
- return(result);
-}
-
-/**
- * @brief STR Exclusive (16 bit)
- *
- * @param value value to store
- * @param *addr address pointer
- * @return successful / failed
- *
- * Exclusive STR command for 16 bit values
- */
-uint32_t __STREXH(uint16_t value, uint16_t *addr)
-{
- uint32_t result=0;
-
- __ASM volatile ("strexh %0, %2, [%1]" : "=&r" (result) : "r" (addr), "r" (value) );
- return(result);
-}
-
-/**
- * @brief STR Exclusive (32 bit)
- *
- * @param value value to store
- * @param *addr address pointer
- * @return successful / failed
- *
- * Exclusive STR command for 32 bit values
- */
-uint32_t __STREXW(uint32_t value, uint32_t *addr)
-{
- uint32_t result=0;
-
- __ASM volatile ("strex %0, %2, [%1]" : "=&r" (result) : "r" (addr), "r" (value) );
- return(result);
-}
-
-
-#elif (defined (__TASKING__)) /*------------------ TASKING Compiler ---------------------*/
-/* TASKING carm specific functions */
-
-/*
- * The CMSIS functions have been implemented as intrinsics in the compiler.
- * Please use "carm -?i" to get an up to date list of all instrinsics,
- * Including the CMSIS ones.
- */
-
-#endif
diff --git a/sam3s_example/cmsis/core_cm3.h b/sam3s_example/cmsis/core_cm3.h
deleted file mode 100644
index 1c07effa..00000000
--- a/sam3s_example/cmsis/core_cm3.h
+++ /dev/null
@@ -1,1818 +0,0 @@
-/**************************************************************************//**
- * @file core_cm3.h
- * @brief CMSIS Cortex-M3 Core Peripheral Access Layer Header File
- * @version V1.30
- * @date 30. October 2009
- *
- * @note
- * Copyright (C) 2009 ARM Limited. All rights reserved.
- *
- * @par
- * ARM Limited (ARM) is supplying this software for use with Cortex-M
- * processor based microcontrollers. This file can be freely distributed
- * within development tools that are supporting such ARM based processors.
- *
- * @par
- * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
- * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
- * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
- * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
- *
- ******************************************************************************/
-
-#ifndef __CM3_CORE_H__
-#define __CM3_CORE_H__
-
-/** @addtogroup CMSIS_CM3_core_LintCinfiguration CMSIS CM3 Core Lint Configuration
- *
- * List of Lint messages which will be suppressed and not shown:
- * - Error 10: \n
- * register uint32_t __regBasePri __asm("basepri"); \n
- * Error 10: Expecting ';'
- * .
- * - Error 530: \n
- * return(__regBasePri); \n
- * Warning 530: Symbol '__regBasePri' (line 264) not initialized
- * .
- * - Error 550: \n
- * __regBasePri = (basePri & 0x1ff); \n
- * Warning 550: Symbol '__regBasePri' (line 271) not accessed
- * .
- * - Error 754: \n
- * uint32_t RESERVED0[24]; \n
- * Info 754: local structure member '' (line 109, file ./cm3_core.h) not referenced
- * .
- * - Error 750: \n
- * #define __CM3_CORE_H__ \n
- * Info 750: local macro '__CM3_CORE_H__' (line 43, file./cm3_core.h) not referenced
- * .
- * - Error 528: \n
- * static __INLINE void NVIC_DisableIRQ(uint32_t IRQn) \n
- * Warning 528: Symbol 'NVIC_DisableIRQ(unsigned int)' (line 419, file ./cm3_core.h) not referenced
- * .
- * - Error 751: \n
- * } InterruptType_Type; \n
- * Info 751: local typedef 'InterruptType_Type' (line 170, file ./cm3_core.h) not referenced
- * .
- * Note: To re-enable a Message, insert a space before 'lint' *
- *
- */
-
-/*lint -save */
-/*lint -e10 */
-/*lint -e530 */
-/*lint -e550 */
-/*lint -e754 */
-/*lint -e750 */
-/*lint -e528 */
-/*lint -e751 */
-
-
-/** @addtogroup CMSIS_CM3_core_definitions CM3 Core Definitions
- This file defines all structures and symbols for CMSIS core:
- - CMSIS version number
- - Cortex-M core registers and bitfields
- - Cortex-M core peripheral base address
- @{
- */
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-#define __CM3_CMSIS_VERSION_MAIN (0x01) /*!< [31:16] CMSIS HAL main version */
-#define __CM3_CMSIS_VERSION_SUB (0x30) /*!< [15:0] CMSIS HAL sub version */
-#define __CM3_CMSIS_VERSION ((__CM3_CMSIS_VERSION_MAIN << 16) | __CM3_CMSIS_VERSION_SUB) /*!< CMSIS HAL version number */
-
-#define __CORTEX_M (0x03) /*!< Cortex core */
-
-#include /* Include standard types */
-
-#if defined (__ICCARM__)
- #include /* IAR Intrinsics */
-#endif
-
-
-#ifndef __NVIC_PRIO_BITS
- #define __NVIC_PRIO_BITS 4 /*!< standard definition for NVIC Priority Bits */
-#endif
-
-
-
-
-/**
- * IO definitions
- *
- * define access restrictions to peripheral registers
- */
-
-#ifdef __cplusplus
- #define __I volatile /*!< defines 'read only' permissions */
-#else
- #define __I volatile const /*!< defines 'read only' permissions */
-#endif
-#define __O volatile /*!< defines 'write only' permissions */
-#define __IO volatile /*!< defines 'read / write' permissions */
-
-
-
-/*******************************************************************************
- * Register Abstraction
- ******************************************************************************/
-/** @addtogroup CMSIS_CM3_core_register CMSIS CM3 Core Register
- @{
-*/
-
-
-/** @addtogroup CMSIS_CM3_NVIC CMSIS CM3 NVIC
- memory mapped structure for Nested Vectored Interrupt Controller (NVIC)
- @{
- */
-typedef struct
-{
- __IO uint32_t ISER[8]; /*!< Offset: 0x000 Interrupt Set Enable Register */
- uint32_t RESERVED0[24];
- __IO uint32_t ICER[8]; /*!< Offset: 0x080 Interrupt Clear Enable Register */
- uint32_t RSERVED1[24];
- __IO uint32_t ISPR[8]; /*!< Offset: 0x100 Interrupt Set Pending Register */
- uint32_t RESERVED2[24];
- __IO uint32_t ICPR[8]; /*!< Offset: 0x180 Interrupt Clear Pending Register */
- uint32_t RESERVED3[24];
- __IO uint32_t IABR[8]; /*!< Offset: 0x200 Interrupt Active bit Register */
- uint32_t RESERVED4[56];
- __IO uint8_t IP[240]; /*!< Offset: 0x300 Interrupt Priority Register (8Bit wide) */
- uint32_t RESERVED5[644];
- __O uint32_t STIR; /*!< Offset: 0xE00 Software Trigger Interrupt Register */
-} NVIC_Type;
-/*@}*/ /* end of group CMSIS_CM3_NVIC */
-
-
-/** @addtogroup CMSIS_CM3_SCB CMSIS CM3 SCB
- memory mapped structure for System Control Block (SCB)
- @{
- */
-typedef struct
-{
- __I uint32_t CPUID; /*!< Offset: 0x00 CPU ID Base Register */
- __IO uint32_t ICSR; /*!< Offset: 0x04 Interrupt Control State Register */
- __IO uint32_t VTOR; /*!< Offset: 0x08 Vector Table Offset Register */
- __IO uint32_t AIRCR; /*!< Offset: 0x0C Application Interrupt / Reset Control Register */
- __IO uint32_t SCR; /*!< Offset: 0x10 System Control Register */
- __IO uint32_t CCR; /*!< Offset: 0x14 Configuration Control Register */
- __IO uint8_t SHP[12]; /*!< Offset: 0x18 System Handlers Priority Registers (4-7, 8-11, 12-15) */
- __IO uint32_t SHCSR; /*!< Offset: 0x24 System Handler Control and State Register */
- __IO uint32_t CFSR; /*!< Offset: 0x28 Configurable Fault Status Register */
- __IO uint32_t HFSR; /*!< Offset: 0x2C Hard Fault Status Register */
- __IO uint32_t DFSR; /*!< Offset: 0x30 Debug Fault Status Register */
- __IO uint32_t MMFAR; /*!< Offset: 0x34 Mem Manage Address Register */
- __IO uint32_t BFAR; /*!< Offset: 0x38 Bus Fault Address Register */
- __IO uint32_t AFSR; /*!< Offset: 0x3C Auxiliary Fault Status Register */
- __I uint32_t PFR[2]; /*!< Offset: 0x40 Processor Feature Register */
- __I uint32_t DFR; /*!< Offset: 0x48 Debug Feature Register */
- __I uint32_t ADR; /*!< Offset: 0x4C Auxiliary Feature Register */
- __I uint32_t MMFR[4]; /*!< Offset: 0x50 Memory Model Feature Register */
- __I uint32_t ISAR[5]; /*!< Offset: 0x60 ISA Feature Register */
-} SCB_Type;
-
-/* SCB CPUID Register Definitions */
-#define SCB_CPUID_IMPLEMENTER_Pos 24 /*!< SCB CPUID: IMPLEMENTER Position */
-#define SCB_CPUID_IMPLEMENTER_Msk (0xFFul << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */
-
-#define SCB_CPUID_VARIANT_Pos 20 /*!< SCB CPUID: VARIANT Position */
-#define SCB_CPUID_VARIANT_Msk (0xFul << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */
-
-#define SCB_CPUID_PARTNO_Pos 4 /*!< SCB CPUID: PARTNO Position */
-#define SCB_CPUID_PARTNO_Msk (0xFFFul << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */
-
-#define SCB_CPUID_REVISION_Pos 0 /*!< SCB CPUID: REVISION Position */
-#define SCB_CPUID_REVISION_Msk (0xFul << SCB_CPUID_REVISION_Pos) /*!< SCB CPUID: REVISION Mask */
-
-/* SCB Interrupt Control State Register Definitions */
-#define SCB_ICSR_NMIPENDSET_Pos 31 /*!< SCB ICSR: NMIPENDSET Position */
-#define SCB_ICSR_NMIPENDSET_Msk (1ul << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */
-
-#define SCB_ICSR_PENDSVSET_Pos 28 /*!< SCB ICSR: PENDSVSET Position */
-#define SCB_ICSR_PENDSVSET_Msk (1ul << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */
-
-#define SCB_ICSR_PENDSVCLR_Pos 27 /*!< SCB ICSR: PENDSVCLR Position */
-#define SCB_ICSR_PENDSVCLR_Msk (1ul << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */
-
-#define SCB_ICSR_PENDSTSET_Pos 26 /*!< SCB ICSR: PENDSTSET Position */
-#define SCB_ICSR_PENDSTSET_Msk (1ul << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */
-
-#define SCB_ICSR_PENDSTCLR_Pos 25 /*!< SCB ICSR: PENDSTCLR Position */
-#define SCB_ICSR_PENDSTCLR_Msk (1ul << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */
-
-#define SCB_ICSR_ISRPREEMPT_Pos 23 /*!< SCB ICSR: ISRPREEMPT Position */
-#define SCB_ICSR_ISRPREEMPT_Msk (1ul << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */
-
-#define SCB_ICSR_ISRPENDING_Pos 22 /*!< SCB ICSR: ISRPENDING Position */
-#define SCB_ICSR_ISRPENDING_Msk (1ul << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */
-
-#define SCB_ICSR_VECTPENDING_Pos 12 /*!< SCB ICSR: VECTPENDING Position */
-#define SCB_ICSR_VECTPENDING_Msk (0x1FFul << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */
-
-#define SCB_ICSR_RETTOBASE_Pos 11 /*!< SCB ICSR: RETTOBASE Position */
-#define SCB_ICSR_RETTOBASE_Msk (1ul << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */
-
-#define SCB_ICSR_VECTACTIVE_Pos 0 /*!< SCB ICSR: VECTACTIVE Position */
-#define SCB_ICSR_VECTACTIVE_Msk (0x1FFul << SCB_ICSR_VECTACTIVE_Pos) /*!< SCB ICSR: VECTACTIVE Mask */
-
-/* SCB Interrupt Control State Register Definitions */
-#define SCB_VTOR_TBLBASE_Pos 29 /*!< SCB VTOR: TBLBASE Position */
-#define SCB_VTOR_TBLBASE_Msk (0x1ul << SCB_VTOR_TBLBASE_Pos) /*!< SCB VTOR: TBLBASE Mask */
-
-#define SCB_VTOR_TBLOFF_Pos 7 /*!< SCB VTOR: TBLOFF Position */
-#define SCB_VTOR_TBLOFF_Msk (0x3FFFFFul << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */
-
-/* SCB Application Interrupt and Reset Control Register Definitions */
-#define SCB_AIRCR_VECTKEY_Pos 16 /*!< SCB AIRCR: VECTKEY Position */
-#define SCB_AIRCR_VECTKEY_Msk (0xFFFFul << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */
-
-#define SCB_AIRCR_VECTKEYSTAT_Pos 16 /*!< SCB AIRCR: VECTKEYSTAT Position */
-#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFul << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */
-
-#define SCB_AIRCR_ENDIANESS_Pos 15 /*!< SCB AIRCR: ENDIANESS Position */
-#define SCB_AIRCR_ENDIANESS_Msk (1ul << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */
-
-#define SCB_AIRCR_PRIGROUP_Pos 8 /*!< SCB AIRCR: PRIGROUP Position */
-#define SCB_AIRCR_PRIGROUP_Msk (7ul << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */
-
-#define SCB_AIRCR_SYSRESETREQ_Pos 2 /*!< SCB AIRCR: SYSRESETREQ Position */
-#define SCB_AIRCR_SYSRESETREQ_Msk (1ul << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */
-
-#define SCB_AIRCR_VECTCLRACTIVE_Pos 1 /*!< SCB AIRCR: VECTCLRACTIVE Position */
-#define SCB_AIRCR_VECTCLRACTIVE_Msk (1ul << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */
-
-#define SCB_AIRCR_VECTRESET_Pos 0 /*!< SCB AIRCR: VECTRESET Position */
-#define SCB_AIRCR_VECTRESET_Msk (1ul << SCB_AIRCR_VECTRESET_Pos) /*!< SCB AIRCR: VECTRESET Mask */
-
-/* SCB System Control Register Definitions */
-#define SCB_SCR_SEVONPEND_Pos 4 /*!< SCB SCR: SEVONPEND Position */
-#define SCB_SCR_SEVONPEND_Msk (1ul << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */
-
-#define SCB_SCR_SLEEPDEEP_Pos 2 /*!< SCB SCR: SLEEPDEEP Position */
-#define SCB_SCR_SLEEPDEEP_Msk (1ul << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */
-
-#define SCB_SCR_SLEEPONEXIT_Pos 1 /*!< SCB SCR: SLEEPONEXIT Position */
-#define SCB_SCR_SLEEPONEXIT_Msk (1ul << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */
-
-/* SCB Configuration Control Register Definitions */
-#define SCB_CCR_STKALIGN_Pos 9 /*!< SCB CCR: STKALIGN Position */
-#define SCB_CCR_STKALIGN_Msk (1ul << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */
-
-#define SCB_CCR_BFHFNMIGN_Pos 8 /*!< SCB CCR: BFHFNMIGN Position */
-#define SCB_CCR_BFHFNMIGN_Msk (1ul << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */
-
-#define SCB_CCR_DIV_0_TRP_Pos 4 /*!< SCB CCR: DIV_0_TRP Position */
-#define SCB_CCR_DIV_0_TRP_Msk (1ul << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */
-
-#define SCB_CCR_UNALIGN_TRP_Pos 3 /*!< SCB CCR: UNALIGN_TRP Position */
-#define SCB_CCR_UNALIGN_TRP_Msk (1ul << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */
-
-#define SCB_CCR_USERSETMPEND_Pos 1 /*!< SCB CCR: USERSETMPEND Position */
-#define SCB_CCR_USERSETMPEND_Msk (1ul << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */
-
-#define SCB_CCR_NONBASETHRDENA_Pos 0 /*!< SCB CCR: NONBASETHRDENA Position */
-#define SCB_CCR_NONBASETHRDENA_Msk (1ul << SCB_CCR_NONBASETHRDENA_Pos) /*!< SCB CCR: NONBASETHRDENA Mask */
-
-/* SCB System Handler Control and State Register Definitions */
-#define SCB_SHCSR_USGFAULTENA_Pos 18 /*!< SCB SHCSR: USGFAULTENA Position */
-#define SCB_SHCSR_USGFAULTENA_Msk (1ul << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */
-
-#define SCB_SHCSR_BUSFAULTENA_Pos 17 /*!< SCB SHCSR: BUSFAULTENA Position */
-#define SCB_SHCSR_BUSFAULTENA_Msk (1ul << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */
-
-#define SCB_SHCSR_MEMFAULTENA_Pos 16 /*!< SCB SHCSR: MEMFAULTENA Position */
-#define SCB_SHCSR_MEMFAULTENA_Msk (1ul << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */
-
-#define SCB_SHCSR_SVCALLPENDED_Pos 15 /*!< SCB SHCSR: SVCALLPENDED Position */
-#define SCB_SHCSR_SVCALLPENDED_Msk (1ul << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */
-
-#define SCB_SHCSR_BUSFAULTPENDED_Pos 14 /*!< SCB SHCSR: BUSFAULTPENDED Position */
-#define SCB_SHCSR_BUSFAULTPENDED_Msk (1ul << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */
-
-#define SCB_SHCSR_MEMFAULTPENDED_Pos 13 /*!< SCB SHCSR: MEMFAULTPENDED Position */
-#define SCB_SHCSR_MEMFAULTPENDED_Msk (1ul << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */
-
-#define SCB_SHCSR_USGFAULTPENDED_Pos 12 /*!< SCB SHCSR: USGFAULTPENDED Position */
-#define SCB_SHCSR_USGFAULTPENDED_Msk (1ul << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */
-
-#define SCB_SHCSR_SYSTICKACT_Pos 11 /*!< SCB SHCSR: SYSTICKACT Position */
-#define SCB_SHCSR_SYSTICKACT_Msk (1ul << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */
-
-#define SCB_SHCSR_PENDSVACT_Pos 10 /*!< SCB SHCSR: PENDSVACT Position */
-#define SCB_SHCSR_PENDSVACT_Msk (1ul << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */
-
-#define SCB_SHCSR_MONITORACT_Pos 8 /*!< SCB SHCSR: MONITORACT Position */
-#define SCB_SHCSR_MONITORACT_Msk (1ul << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */
-
-#define SCB_SHCSR_SVCALLACT_Pos 7 /*!< SCB SHCSR: SVCALLACT Position */
-#define SCB_SHCSR_SVCALLACT_Msk (1ul << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */
-
-#define SCB_SHCSR_USGFAULTACT_Pos 3 /*!< SCB SHCSR: USGFAULTACT Position */
-#define SCB_SHCSR_USGFAULTACT_Msk (1ul << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */
-
-#define SCB_SHCSR_BUSFAULTACT_Pos 1 /*!< SCB SHCSR: BUSFAULTACT Position */
-#define SCB_SHCSR_BUSFAULTACT_Msk (1ul << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */
-
-#define SCB_SHCSR_MEMFAULTACT_Pos 0 /*!< SCB SHCSR: MEMFAULTACT Position */
-#define SCB_SHCSR_MEMFAULTACT_Msk (1ul << SCB_SHCSR_MEMFAULTACT_Pos) /*!< SCB SHCSR: MEMFAULTACT Mask */
-
-/* SCB Configurable Fault Status Registers Definitions */
-#define SCB_CFSR_USGFAULTSR_Pos 16 /*!< SCB CFSR: Usage Fault Status Register Position */
-#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFul << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */
-
-#define SCB_CFSR_BUSFAULTSR_Pos 8 /*!< SCB CFSR: Bus Fault Status Register Position */
-#define SCB_CFSR_BUSFAULTSR_Msk (0xFFul << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */
-
-#define SCB_CFSR_MEMFAULTSR_Pos 0 /*!< SCB CFSR: Memory Manage Fault Status Register Position */
-#define SCB_CFSR_MEMFAULTSR_Msk (0xFFul << SCB_CFSR_MEMFAULTSR_Pos) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */
-
-/* SCB Hard Fault Status Registers Definitions */
-#define SCB_HFSR_DEBUGEVT_Pos 31 /*!< SCB HFSR: DEBUGEVT Position */
-#define SCB_HFSR_DEBUGEVT_Msk (1ul << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */
-
-#define SCB_HFSR_FORCED_Pos 30 /*!< SCB HFSR: FORCED Position */
-#define SCB_HFSR_FORCED_Msk (1ul << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */
-
-#define SCB_HFSR_VECTTBL_Pos 1 /*!< SCB HFSR: VECTTBL Position */
-#define SCB_HFSR_VECTTBL_Msk (1ul << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */
-
-/* SCB Debug Fault Status Register Definitions */
-#define SCB_DFSR_EXTERNAL_Pos 4 /*!< SCB DFSR: EXTERNAL Position */
-#define SCB_DFSR_EXTERNAL_Msk (1ul << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */
-
-#define SCB_DFSR_VCATCH_Pos 3 /*!< SCB DFSR: VCATCH Position */
-#define SCB_DFSR_VCATCH_Msk (1ul << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */
-
-#define SCB_DFSR_DWTTRAP_Pos 2 /*!< SCB DFSR: DWTTRAP Position */
-#define SCB_DFSR_DWTTRAP_Msk (1ul << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */
-
-#define SCB_DFSR_BKPT_Pos 1 /*!< SCB DFSR: BKPT Position */
-#define SCB_DFSR_BKPT_Msk (1ul << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */
-
-#define SCB_DFSR_HALTED_Pos 0 /*!< SCB DFSR: HALTED Position */
-#define SCB_DFSR_HALTED_Msk (1ul << SCB_DFSR_HALTED_Pos) /*!< SCB DFSR: HALTED Mask */
-/*@}*/ /* end of group CMSIS_CM3_SCB */
-
-
-/** @addtogroup CMSIS_CM3_SysTick CMSIS CM3 SysTick
- memory mapped structure for SysTick
- @{
- */
-typedef struct
-{
- __IO uint32_t CTRL; /*!< Offset: 0x00 SysTick Control and Status Register */
- __IO uint32_t LOAD; /*!< Offset: 0x04 SysTick Reload Value Register */
- __IO uint32_t VAL; /*!< Offset: 0x08 SysTick Current Value Register */
- __I uint32_t CALIB; /*!< Offset: 0x0C SysTick Calibration Register */
-} SysTick_Type;
-
-/* SysTick Control / Status Register Definitions */
-#define SysTick_CTRL_COUNTFLAG_Pos 16 /*!< SysTick CTRL: COUNTFLAG Position */
-#define SysTick_CTRL_COUNTFLAG_Msk (1ul << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */
-
-#define SysTick_CTRL_CLKSOURCE_Pos 2 /*!< SysTick CTRL: CLKSOURCE Position */
-#define SysTick_CTRL_CLKSOURCE_Msk (1ul << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */
-
-#define SysTick_CTRL_TICKINT_Pos 1 /*!< SysTick CTRL: TICKINT Position */
-#define SysTick_CTRL_TICKINT_Msk (1ul << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */
-
-#define SysTick_CTRL_ENABLE_Pos 0 /*!< SysTick CTRL: ENABLE Position */
-#define SysTick_CTRL_ENABLE_Msk (1ul << SysTick_CTRL_ENABLE_Pos) /*!< SysTick CTRL: ENABLE Mask */
-
-/* SysTick Reload Register Definitions */
-#define SysTick_LOAD_RELOAD_Pos 0 /*!< SysTick LOAD: RELOAD Position */
-#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFul << SysTick_LOAD_RELOAD_Pos) /*!< SysTick LOAD: RELOAD Mask */
-
-/* SysTick Current Register Definitions */
-#define SysTick_VAL_CURRENT_Pos 0 /*!< SysTick VAL: CURRENT Position */
-#define SysTick_VAL_CURRENT_Msk (0xFFFFFFul << SysTick_VAL_CURRENT_Pos) /*!< SysTick VAL: CURRENT Mask */
-
-/* SysTick Calibration Register Definitions */
-#define SysTick_CALIB_NOREF_Pos 31 /*!< SysTick CALIB: NOREF Position */
-#define SysTick_CALIB_NOREF_Msk (1ul << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */
-
-#define SysTick_CALIB_SKEW_Pos 30 /*!< SysTick CALIB: SKEW Position */
-#define SysTick_CALIB_SKEW_Msk (1ul << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */
-
-#define SysTick_CALIB_TENMS_Pos 0 /*!< SysTick CALIB: TENMS Position */
-#define SysTick_CALIB_TENMS_Msk (0xFFFFFFul << SysTick_VAL_CURRENT_Pos) /*!< SysTick CALIB: TENMS Mask */
-/*@}*/ /* end of group CMSIS_CM3_SysTick */
-
-
-/** @addtogroup CMSIS_CM3_ITM CMSIS CM3 ITM
- memory mapped structure for Instrumentation Trace Macrocell (ITM)
- @{
- */
-typedef struct
-{
- __O union
- {
- __O uint8_t u8; /*!< Offset: ITM Stimulus Port 8-bit */
- __O uint16_t u16; /*!< Offset: ITM Stimulus Port 16-bit */
- __O uint32_t u32; /*!< Offset: ITM Stimulus Port 32-bit */
- } PORT [32]; /*!< Offset: 0x00 ITM Stimulus Port Registers */
- uint32_t RESERVED0[864];
- __IO uint32_t TER; /*!< Offset: ITM Trace Enable Register */
- uint32_t RESERVED1[15];
- __IO uint32_t TPR; /*!< Offset: ITM Trace Privilege Register */
- uint32_t RESERVED2[15];
- __IO uint32_t TCR; /*!< Offset: ITM Trace Control Register */
- uint32_t RESERVED3[29];
- __IO uint32_t IWR; /*!< Offset: ITM Integration Write Register */
- __IO uint32_t IRR; /*!< Offset: ITM Integration Read Register */
- __IO uint32_t IMCR; /*!< Offset: ITM Integration Mode Control Register */
- uint32_t RESERVED4[43];
- __IO uint32_t LAR; /*!< Offset: ITM Lock Access Register */
- __IO uint32_t LSR; /*!< Offset: ITM Lock Status Register */
- uint32_t RESERVED5[6];
- __I uint32_t PID4; /*!< Offset: ITM Peripheral Identification Register #4 */
- __I uint32_t PID5; /*!< Offset: ITM Peripheral Identification Register #5 */
- __I uint32_t PID6; /*!< Offset: ITM Peripheral Identification Register #6 */
- __I uint32_t PID7; /*!< Offset: ITM Peripheral Identification Register #7 */
- __I uint32_t PID0; /*!< Offset: ITM Peripheral Identification Register #0 */
- __I uint32_t PID1; /*!< Offset: ITM Peripheral Identification Register #1 */
- __I uint32_t PID2; /*!< Offset: ITM Peripheral Identification Register #2 */
- __I uint32_t PID3; /*!< Offset: ITM Peripheral Identification Register #3 */
- __I uint32_t CID0; /*!< Offset: ITM Component Identification Register #0 */
- __I uint32_t CID1; /*!< Offset: ITM Component Identification Register #1 */
- __I uint32_t CID2; /*!< Offset: ITM Component Identification Register #2 */
- __I uint32_t CID3; /*!< Offset: ITM Component Identification Register #3 */
-} ITM_Type;
-
-/* ITM Trace Privilege Register Definitions */
-#define ITM_TPR_PRIVMASK_Pos 0 /*!< ITM TPR: PRIVMASK Position */
-#define ITM_TPR_PRIVMASK_Msk (0xFul << ITM_TPR_PRIVMASK_Pos) /*!< ITM TPR: PRIVMASK Mask */
-
-/* ITM Trace Control Register Definitions */
-#define ITM_TCR_BUSY_Pos 23 /*!< ITM TCR: BUSY Position */
-#define ITM_TCR_BUSY_Msk (1ul << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */
-
-#define ITM_TCR_ATBID_Pos 16 /*!< ITM TCR: ATBID Position */
-#define ITM_TCR_ATBID_Msk (0x7Ful << ITM_TCR_ATBID_Pos) /*!< ITM TCR: ATBID Mask */
-
-#define ITM_TCR_TSPrescale_Pos 8 /*!< ITM TCR: TSPrescale Position */
-#define ITM_TCR_TSPrescale_Msk (3ul << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */
-
-#define ITM_TCR_SWOENA_Pos 4 /*!< ITM TCR: SWOENA Position */
-#define ITM_TCR_SWOENA_Msk (1ul << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */
-
-#define ITM_TCR_DWTENA_Pos 3 /*!< ITM TCR: DWTENA Position */
-#define ITM_TCR_DWTENA_Msk (1ul << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */
-
-#define ITM_TCR_SYNCENA_Pos 2 /*!< ITM TCR: SYNCENA Position */
-#define ITM_TCR_SYNCENA_Msk (1ul << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */
-
-#define ITM_TCR_TSENA_Pos 1 /*!< ITM TCR: TSENA Position */
-#define ITM_TCR_TSENA_Msk (1ul << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */
-
-#define ITM_TCR_ITMENA_Pos 0 /*!< ITM TCR: ITM Enable bit Position */
-#define ITM_TCR_ITMENA_Msk (1ul << ITM_TCR_ITMENA_Pos) /*!< ITM TCR: ITM Enable bit Mask */
-
-/* ITM Integration Write Register Definitions */
-#define ITM_IWR_ATVALIDM_Pos 0 /*!< ITM IWR: ATVALIDM Position */
-#define ITM_IWR_ATVALIDM_Msk (1ul << ITM_IWR_ATVALIDM_Pos) /*!< ITM IWR: ATVALIDM Mask */
-
-/* ITM Integration Read Register Definitions */
-#define ITM_IRR_ATREADYM_Pos 0 /*!< ITM IRR: ATREADYM Position */
-#define ITM_IRR_ATREADYM_Msk (1ul << ITM_IRR_ATREADYM_Pos) /*!< ITM IRR: ATREADYM Mask */
-
-/* ITM Integration Mode Control Register Definitions */
-#define ITM_IMCR_INTEGRATION_Pos 0 /*!< ITM IMCR: INTEGRATION Position */
-#define ITM_IMCR_INTEGRATION_Msk (1ul << ITM_IMCR_INTEGRATION_Pos) /*!< ITM IMCR: INTEGRATION Mask */
-
-/* ITM Lock Status Register Definitions */
-#define ITM_LSR_ByteAcc_Pos 2 /*!< ITM LSR: ByteAcc Position */
-#define ITM_LSR_ByteAcc_Msk (1ul << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */
-
-#define ITM_LSR_Access_Pos 1 /*!< ITM LSR: Access Position */
-#define ITM_LSR_Access_Msk (1ul << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */
-
-#define ITM_LSR_Present_Pos 0 /*!< ITM LSR: Present Position */
-#define ITM_LSR_Present_Msk (1ul << ITM_LSR_Present_Pos) /*!< ITM LSR: Present Mask */
-/*@}*/ /* end of group CMSIS_CM3_ITM */
-
-
-/** @addtogroup CMSIS_CM3_InterruptType CMSIS CM3 Interrupt Type
- memory mapped structure for Interrupt Type
- @{
- */
-typedef struct
-{
- uint32_t RESERVED0;
- __I uint32_t ICTR; /*!< Offset: 0x04 Interrupt Control Type Register */
-#if ((defined __CM3_REV) && (__CM3_REV >= 0x200))
- __IO uint32_t ACTLR; /*!< Offset: 0x08 Auxiliary Control Register */
-#else
- uint32_t RESERVED1;
-#endif
-} InterruptType_Type;
-
-/* Interrupt Controller Type Register Definitions */
-#define InterruptType_ICTR_INTLINESNUM_Pos 0 /*!< InterruptType ICTR: INTLINESNUM Position */
-#define InterruptType_ICTR_INTLINESNUM_Msk (0x1Ful << InterruptType_ICTR_INTLINESNUM_Pos) /*!< InterruptType ICTR: INTLINESNUM Mask */
-
-/* Auxiliary Control Register Definitions */
-#define InterruptType_ACTLR_DISFOLD_Pos 2 /*!< InterruptType ACTLR: DISFOLD Position */
-#define InterruptType_ACTLR_DISFOLD_Msk (1ul << InterruptType_ACTLR_DISFOLD_Pos) /*!< InterruptType ACTLR: DISFOLD Mask */
-
-#define InterruptType_ACTLR_DISDEFWBUF_Pos 1 /*!< InterruptType ACTLR: DISDEFWBUF Position */
-#define InterruptType_ACTLR_DISDEFWBUF_Msk (1ul << InterruptType_ACTLR_DISDEFWBUF_Pos) /*!< InterruptType ACTLR: DISDEFWBUF Mask */
-
-#define InterruptType_ACTLR_DISMCYCINT_Pos 0 /*!< InterruptType ACTLR: DISMCYCINT Position */
-#define InterruptType_ACTLR_DISMCYCINT_Msk (1ul << InterruptType_ACTLR_DISMCYCINT_Pos) /*!< InterruptType ACTLR: DISMCYCINT Mask */
-/*@}*/ /* end of group CMSIS_CM3_InterruptType */
-
-
-#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1)
-/** @addtogroup CMSIS_CM3_MPU CMSIS CM3 MPU
- memory mapped structure for Memory Protection Unit (MPU)
- @{
- */
-typedef struct
-{
- __I uint32_t TYPE; /*!< Offset: 0x00 MPU Type Register */
- __IO uint32_t CTRL; /*!< Offset: 0x04 MPU Control Register */
- __IO uint32_t RNR; /*!< Offset: 0x08 MPU Region RNRber Register */
- __IO uint32_t RBAR; /*!< Offset: 0x0C MPU Region Base Address Register */
- __IO uint32_t RASR; /*!< Offset: 0x10 MPU Region Attribute and Size Register */
- __IO uint32_t RBAR_A1; /*!< Offset: 0x14 MPU Alias 1 Region Base Address Register */
- __IO uint32_t RASR_A1; /*!< Offset: 0x18 MPU Alias 1 Region Attribute and Size Register */
- __IO uint32_t RBAR_A2; /*!< Offset: 0x1C MPU Alias 2 Region Base Address Register */
- __IO uint32_t RASR_A2; /*!< Offset: 0x20 MPU Alias 2 Region Attribute and Size Register */
- __IO uint32_t RBAR_A3; /*!< Offset: 0x24 MPU Alias 3 Region Base Address Register */
- __IO uint32_t RASR_A3; /*!< Offset: 0x28 MPU Alias 3 Region Attribute and Size Register */
-} MPU_Type;
-
-/* MPU Type Register */
-#define MPU_TYPE_IREGION_Pos 16 /*!< MPU TYPE: IREGION Position */
-#define MPU_TYPE_IREGION_Msk (0xFFul << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */
-
-#define MPU_TYPE_DREGION_Pos 8 /*!< MPU TYPE: DREGION Position */
-#define MPU_TYPE_DREGION_Msk (0xFFul << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */
-
-#define MPU_TYPE_SEPARATE_Pos 0 /*!< MPU TYPE: SEPARATE Position */
-#define MPU_TYPE_SEPARATE_Msk (1ul << MPU_TYPE_SEPARATE_Pos) /*!< MPU TYPE: SEPARATE Mask */
-
-/* MPU Control Register */
-#define MPU_CTRL_PRIVDEFENA_Pos 2 /*!< MPU CTRL: PRIVDEFENA Position */
-#define MPU_CTRL_PRIVDEFENA_Msk (1ul << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */
-
-#define MPU_CTRL_HFNMIENA_Pos 1 /*!< MPU CTRL: HFNMIENA Position */
-#define MPU_CTRL_HFNMIENA_Msk (1ul << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */
-
-#define MPU_CTRL_ENABLE_Pos 0 /*!< MPU CTRL: ENABLE Position */
-#define MPU_CTRL_ENABLE_Msk (1ul << MPU_CTRL_ENABLE_Pos) /*!< MPU CTRL: ENABLE Mask */
-
-/* MPU Region Number Register */
-#define MPU_RNR_REGION_Pos 0 /*!< MPU RNR: REGION Position */
-#define MPU_RNR_REGION_Msk (0xFFul << MPU_RNR_REGION_Pos) /*!< MPU RNR: REGION Mask */
-
-/* MPU Region Base Address Register */
-#define MPU_RBAR_ADDR_Pos 5 /*!< MPU RBAR: ADDR Position */
-#define MPU_RBAR_ADDR_Msk (0x7FFFFFFul << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */
-
-#define MPU_RBAR_VALID_Pos 4 /*!< MPU RBAR: VALID Position */
-#define MPU_RBAR_VALID_Msk (1ul << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */
-
-#define MPU_RBAR_REGION_Pos 0 /*!< MPU RBAR: REGION Position */
-#define MPU_RBAR_REGION_Msk (0xFul << MPU_RBAR_REGION_Pos) /*!< MPU RBAR: REGION Mask */
-
-/* MPU Region Attribute and Size Register */
-#define MPU_RASR_XN_Pos 28 /*!< MPU RASR: XN Position */
-#define MPU_RASR_XN_Msk (1ul << MPU_RASR_XN_Pos) /*!< MPU RASR: XN Mask */
-
-#define MPU_RASR_AP_Pos 24 /*!< MPU RASR: AP Position */
-#define MPU_RASR_AP_Msk (7ul << MPU_RASR_AP_Pos) /*!< MPU RASR: AP Mask */
-
-#define MPU_RASR_TEX_Pos 19 /*!< MPU RASR: TEX Position */
-#define MPU_RASR_TEX_Msk (7ul << MPU_RASR_TEX_Pos) /*!< MPU RASR: TEX Mask */
-
-#define MPU_RASR_S_Pos 18 /*!< MPU RASR: Shareable bit Position */
-#define MPU_RASR_S_Msk (1ul << MPU_RASR_S_Pos) /*!< MPU RASR: Shareable bit Mask */
-
-#define MPU_RASR_C_Pos 17 /*!< MPU RASR: Cacheable bit Position */
-#define MPU_RASR_C_Msk (1ul << MPU_RASR_C_Pos) /*!< MPU RASR: Cacheable bit Mask */
-
-#define MPU_RASR_B_Pos 16 /*!< MPU RASR: Bufferable bit Position */
-#define MPU_RASR_B_Msk (1ul << MPU_RASR_B_Pos) /*!< MPU RASR: Bufferable bit Mask */
-
-#define MPU_RASR_SRD_Pos 8 /*!< MPU RASR: Sub-Region Disable Position */
-#define MPU_RASR_SRD_Msk (0xFFul << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */
-
-#define MPU_RASR_SIZE_Pos 1 /*!< MPU RASR: Region Size Field Position */
-#define MPU_RASR_SIZE_Msk (0x1Ful << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */
-
-#define MPU_RASR_ENA_Pos 0 /*!< MPU RASR: Region enable bit Position */
-#define MPU_RASR_ENA_Msk (0x1Ful << MPU_RASR_ENA_Pos) /*!< MPU RASR: Region enable bit Disable Mask */
-
-/*@}*/ /* end of group CMSIS_CM3_MPU */
-#endif
-
-
-/** @addtogroup CMSIS_CM3_CoreDebug CMSIS CM3 Core Debug
- memory mapped structure for Core Debug Register
- @{
- */
-typedef struct
-{
- __IO uint32_t DHCSR; /*!< Offset: 0x00 Debug Halting Control and Status Register */
- __O uint32_t DCRSR; /*!< Offset: 0x04 Debug Core Register Selector Register */
- __IO uint32_t DCRDR; /*!< Offset: 0x08 Debug Core Register Data Register */
- __IO uint32_t DEMCR; /*!< Offset: 0x0C Debug Exception and Monitor Control Register */
-} CoreDebug_Type;
-
-/* Debug Halting Control and Status Register */
-#define CoreDebug_DHCSR_DBGKEY_Pos 16 /*!< CoreDebug DHCSR: DBGKEY Position */
-#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFul << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */
-
-#define CoreDebug_DHCSR_S_RESET_ST_Pos 25 /*!< CoreDebug DHCSR: S_RESET_ST Position */
-#define CoreDebug_DHCSR_S_RESET_ST_Msk (1ul << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */
-
-#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24 /*!< CoreDebug DHCSR: S_RETIRE_ST Position */
-#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1ul << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */
-
-#define CoreDebug_DHCSR_S_LOCKUP_Pos 19 /*!< CoreDebug DHCSR: S_LOCKUP Position */
-#define CoreDebug_DHCSR_S_LOCKUP_Msk (1ul << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */
-
-#define CoreDebug_DHCSR_S_SLEEP_Pos 18 /*!< CoreDebug DHCSR: S_SLEEP Position */
-#define CoreDebug_DHCSR_S_SLEEP_Msk (1ul << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */
-
-#define CoreDebug_DHCSR_S_HALT_Pos 17 /*!< CoreDebug DHCSR: S_HALT Position */
-#define CoreDebug_DHCSR_S_HALT_Msk (1ul << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */
-
-#define CoreDebug_DHCSR_S_REGRDY_Pos 16 /*!< CoreDebug DHCSR: S_REGRDY Position */
-#define CoreDebug_DHCSR_S_REGRDY_Msk (1ul << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */
-
-#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5 /*!< CoreDebug DHCSR: C_SNAPSTALL Position */
-#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1ul << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */
-
-#define CoreDebug_DHCSR_C_MASKINTS_Pos 3 /*!< CoreDebug DHCSR: C_MASKINTS Position */
-#define CoreDebug_DHCSR_C_MASKINTS_Msk (1ul << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */
-
-#define CoreDebug_DHCSR_C_STEP_Pos 2 /*!< CoreDebug DHCSR: C_STEP Position */
-#define CoreDebug_DHCSR_C_STEP_Msk (1ul << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */
-
-#define CoreDebug_DHCSR_C_HALT_Pos 1 /*!< CoreDebug DHCSR: C_HALT Position */
-#define CoreDebug_DHCSR_C_HALT_Msk (1ul << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */
-
-#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0 /*!< CoreDebug DHCSR: C_DEBUGEN Position */
-#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1ul << CoreDebug_DHCSR_C_DEBUGEN_Pos) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */
-
-/* Debug Core Register Selector Register */
-#define CoreDebug_DCRSR_REGWnR_Pos 16 /*!< CoreDebug DCRSR: REGWnR Position */
-#define CoreDebug_DCRSR_REGWnR_Msk (1ul << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */
-
-#define CoreDebug_DCRSR_REGSEL_Pos 0 /*!< CoreDebug DCRSR: REGSEL Position */
-#define CoreDebug_DCRSR_REGSEL_Msk (0x1Ful << CoreDebug_DCRSR_REGSEL_Pos) /*!< CoreDebug DCRSR: REGSEL Mask */
-
-/* Debug Exception and Monitor Control Register */
-#define CoreDebug_DEMCR_TRCENA_Pos 24 /*!< CoreDebug DEMCR: TRCENA Position */
-#define CoreDebug_DEMCR_TRCENA_Msk (1ul << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */
-
-#define CoreDebug_DEMCR_MON_REQ_Pos 19 /*!< CoreDebug DEMCR: MON_REQ Position */
-#define CoreDebug_DEMCR_MON_REQ_Msk (1ul << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */
-
-#define CoreDebug_DEMCR_MON_STEP_Pos 18 /*!< CoreDebug DEMCR: MON_STEP Position */
-#define CoreDebug_DEMCR_MON_STEP_Msk (1ul << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */
-
-#define CoreDebug_DEMCR_MON_PEND_Pos 17 /*!< CoreDebug DEMCR: MON_PEND Position */
-#define CoreDebug_DEMCR_MON_PEND_Msk (1ul << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */
-
-#define CoreDebug_DEMCR_MON_EN_Pos 16 /*!< CoreDebug DEMCR: MON_EN Position */
-#define CoreDebug_DEMCR_MON_EN_Msk (1ul << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */
-
-#define CoreDebug_DEMCR_VC_HARDERR_Pos 10 /*!< CoreDebug DEMCR: VC_HARDERR Position */
-#define CoreDebug_DEMCR_VC_HARDERR_Msk (1ul << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */
-
-#define CoreDebug_DEMCR_VC_INTERR_Pos 9 /*!< CoreDebug DEMCR: VC_INTERR Position */
-#define CoreDebug_DEMCR_VC_INTERR_Msk (1ul << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */
-
-#define CoreDebug_DEMCR_VC_BUSERR_Pos 8 /*!< CoreDebug DEMCR: VC_BUSERR Position */
-#define CoreDebug_DEMCR_VC_BUSERR_Msk (1ul << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */
-
-#define CoreDebug_DEMCR_VC_STATERR_Pos 7 /*!< CoreDebug DEMCR: VC_STATERR Position */
-#define CoreDebug_DEMCR_VC_STATERR_Msk (1ul << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */
-
-#define CoreDebug_DEMCR_VC_CHKERR_Pos 6 /*!< CoreDebug DEMCR: VC_CHKERR Position */
-#define CoreDebug_DEMCR_VC_CHKERR_Msk (1ul << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */
-
-#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5 /*!< CoreDebug DEMCR: VC_NOCPERR Position */
-#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1ul << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */
-
-#define CoreDebug_DEMCR_VC_MMERR_Pos 4 /*!< CoreDebug DEMCR: VC_MMERR Position */
-#define CoreDebug_DEMCR_VC_MMERR_Msk (1ul << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */
-
-#define CoreDebug_DEMCR_VC_CORERESET_Pos 0 /*!< CoreDebug DEMCR: VC_CORERESET Position */
-#define CoreDebug_DEMCR_VC_CORERESET_Msk (1ul << CoreDebug_DEMCR_VC_CORERESET_Pos) /*!< CoreDebug DEMCR: VC_CORERESET Mask */
-/*@}*/ /* end of group CMSIS_CM3_CoreDebug */
-
-
-/* Memory mapping of Cortex-M3 Hardware */
-#define SCS_BASE (0xE000E000) /*!< System Control Space Base Address */
-#define ITM_BASE (0xE0000000) /*!< ITM Base Address */
-#define CoreDebug_BASE (0xE000EDF0) /*!< Core Debug Base Address */
-#define SysTick_BASE (SCS_BASE + 0x0010) /*!< SysTick Base Address */
-#define NVIC_BASE (SCS_BASE + 0x0100) /*!< NVIC Base Address */
-#define SCB_BASE (SCS_BASE + 0x0D00) /*!< System Control Block Base Address */
-
-#define InterruptType ((InterruptType_Type *) SCS_BASE) /*!< Interrupt Type Register */
-#define SCB ((SCB_Type *) SCB_BASE) /*!< SCB configuration struct */
-#define SysTick ((SysTick_Type *) SysTick_BASE) /*!< SysTick configuration struct */
-#define NVIC ((NVIC_Type *) NVIC_BASE) /*!< NVIC configuration struct */
-#define ITM ((ITM_Type *) ITM_BASE) /*!< ITM configuration struct */
-#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */
-
-#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1)
- #define MPU_BASE (SCS_BASE + 0x0D90) /*!< Memory Protection Unit */
- #define MPU ((MPU_Type*) MPU_BASE) /*!< Memory Protection Unit */
-#endif
-
-/*@}*/ /* end of group CMSIS_CM3_core_register */
-
-
-/*******************************************************************************
- * Hardware Abstraction Layer
- ******************************************************************************/
-
-#if defined ( __CC_ARM )
- #define __ASM __asm /*!< asm keyword for ARM Compiler */
- #define __INLINE __inline /*!< inline keyword for ARM Compiler */
-
-#elif defined ( __ICCARM__ )
- #define __ASM __asm /*!< asm keyword for IAR Compiler */
- #define __INLINE inline /*!< inline keyword for IAR Compiler. Only avaiable in High optimization mode! */
-
-#elif defined ( __GNUC__ )
- #define __ASM __asm /*!< asm keyword for GNU Compiler */
- #define __INLINE inline /*!< inline keyword for GNU Compiler */
-
-#elif defined ( __TASKING__ )
- #define __ASM __asm /*!< asm keyword for TASKING Compiler */
- #define __INLINE inline /*!< inline keyword for TASKING Compiler */
-
-#endif
-
-
-/* ################### Compiler specific Intrinsics ########################### */
-
-#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
-/* ARM armcc specific functions */
-
-#define __enable_fault_irq __enable_fiq
-#define __disable_fault_irq __disable_fiq
-
-#define __NOP __nop
-#define __WFI __wfi
-#define __WFE __wfe
-#define __SEV __sev
-#define __ISB() __isb(0)
-#define __DSB() __dsb(0)
-#define __DMB() __dmb(0)
-#define __REV __rev
-#define __RBIT __rbit
-#define __LDREXB(ptr) ((unsigned char ) __ldrex(ptr))
-#define __LDREXH(ptr) ((unsigned short) __ldrex(ptr))
-#define __LDREXW(ptr) ((unsigned int ) __ldrex(ptr))
-#define __STREXB(value, ptr) __strex(value, ptr)
-#define __STREXH(value, ptr) __strex(value, ptr)
-#define __STREXW(value, ptr) __strex(value, ptr)
-
-
-/* intrinsic unsigned long long __ldrexd(volatile void *ptr) */
-/* intrinsic int __strexd(unsigned long long val, volatile void *ptr) */
-/* intrinsic void __enable_irq(); */
-/* intrinsic void __disable_irq(); */
-
-
-/**
- * @brief Return the Process Stack Pointer
- *
- * @return ProcessStackPointer
- *
- * Return the actual process stack pointer
- */
-extern uint32_t __get_PSP(void);
-
-/**
- * @brief Set the Process Stack Pointer
- *
- * @param topOfProcStack Process Stack Pointer
- *
- * Assign the value ProcessStackPointer to the MSP
- * (process stack pointer) Cortex processor register
- */
-extern void __set_PSP(uint32_t topOfProcStack);
-
-/**
- * @brief Return the Main Stack Pointer
- *
- * @return Main Stack Pointer
- *
- * Return the current value of the MSP (main stack pointer)
- * Cortex processor register
- */
-extern uint32_t __get_MSP(void);
-
-/**
- * @brief Set the Main Stack Pointer
- *
- * @param topOfMainStack Main Stack Pointer
- *
- * Assign the value mainStackPointer to the MSP
- * (main stack pointer) Cortex processor register
- */
-extern void __set_MSP(uint32_t topOfMainStack);
-
-/**
- * @brief Reverse byte order in unsigned short value
- *
- * @param value value to reverse
- * @return reversed value
- *
- * Reverse byte order in unsigned short value
- */
-extern uint32_t __REV16(uint16_t value);
-
-/**
- * @brief Reverse byte order in signed short value with sign extension to integer
- *
- * @param value value to reverse
- * @return reversed value
- *
- * Reverse byte order in signed short value with sign extension to integer
- */
-extern int32_t __REVSH(int16_t value);
-
-
-#if (__ARMCC_VERSION < 400000)
-
-/**
- * @brief Remove the exclusive lock created by ldrex
- *
- * Removes the exclusive lock which is created by ldrex.
- */
-extern void __CLREX(void);
-
-/**
- * @brief Return the Base Priority value
- *
- * @return BasePriority
- *
- * Return the content of the base priority register
- */
-extern uint32_t __get_BASEPRI(void);
-
-/**
- * @brief Set the Base Priority value
- *
- * @param basePri BasePriority
- *
- * Set the base priority register
- */
-extern void __set_BASEPRI(uint32_t basePri);
-
-/**
- * @brief Return the Priority Mask value
- *
- * @return PriMask
- *
- * Return state of the priority mask bit from the priority mask register
- */
-extern uint32_t __get_PRIMASK(void);
-
-/**
- * @brief Set the Priority Mask value
- *
- * @param priMask PriMask
- *
- * Set the priority mask bit in the priority mask register
- */
-extern void __set_PRIMASK(uint32_t priMask);
-
-/**
- * @brief Return the Fault Mask value
- *
- * @return FaultMask
- *
- * Return the content of the fault mask register
- */
-extern uint32_t __get_FAULTMASK(void);
-
-/**
- * @brief Set the Fault Mask value
- *
- * @param faultMask faultMask value
- *
- * Set the fault mask register
- */
-extern void __set_FAULTMASK(uint32_t faultMask);
-
-/**
- * @brief Return the Control Register value
- *
- * @return Control value
- *
- * Return the content of the control register
- */
-extern uint32_t __get_CONTROL(void);
-
-/**
- * @brief Set the Control Register value
- *
- * @param control Control value
- *
- * Set the control register
- */
-extern void __set_CONTROL(uint32_t control);
-
-#else /* (__ARMCC_VERSION >= 400000) */
-
-/**
- * @brief Remove the exclusive lock created by ldrex
- *
- * Removes the exclusive lock which is created by ldrex.
- */
-#define __CLREX __clrex
-
-/**
- * @brief Return the Base Priority value
- *
- * @return BasePriority
- *
- * Return the content of the base priority register
- */
-static __INLINE uint32_t __get_BASEPRI(void)
-{
- register uint32_t __regBasePri __ASM("basepri");
- return(__regBasePri);
-}
-
-/**
- * @brief Set the Base Priority value
- *
- * @param basePri BasePriority
- *
- * Set the base priority register
- */
-static __INLINE void __set_BASEPRI(uint32_t basePri)
-{
- register uint32_t __regBasePri __ASM("basepri");
- __regBasePri = (basePri & 0xff);
-}
-
-/**
- * @brief Return the Priority Mask value
- *
- * @return PriMask
- *
- * Return state of the priority mask bit from the priority mask register
- */
-static __INLINE uint32_t __get_PRIMASK(void)
-{
- register uint32_t __regPriMask __ASM("primask");
- return(__regPriMask);
-}
-
-/**
- * @brief Set the Priority Mask value
- *
- * @param priMask PriMask
- *
- * Set the priority mask bit in the priority mask register
- */
-static __INLINE void __set_PRIMASK(uint32_t priMask)
-{
- register uint32_t __regPriMask __ASM("primask");
- __regPriMask = (priMask);
-}
-
-/**
- * @brief Return the Fault Mask value
- *
- * @return FaultMask
- *
- * Return the content of the fault mask register
- */
-static __INLINE uint32_t __get_FAULTMASK(void)
-{
- register uint32_t __regFaultMask __ASM("faultmask");
- return(__regFaultMask);
-}
-
-/**
- * @brief Set the Fault Mask value
- *
- * @param faultMask faultMask value
- *
- * Set the fault mask register
- */
-static __INLINE void __set_FAULTMASK(uint32_t faultMask)
-{
- register uint32_t __regFaultMask __ASM("faultmask");
- __regFaultMask = (faultMask & 1);
-}
-
-/**
- * @brief Return the Control Register value
- *
- * @return Control value
- *
- * Return the content of the control register
- */
-static __INLINE uint32_t __get_CONTROL(void)
-{
- register uint32_t __regControl __ASM("control");
- return(__regControl);
-}
-
-/**
- * @brief Set the Control Register value
- *
- * @param control Control value
- *
- * Set the control register
- */
-static __INLINE void __set_CONTROL(uint32_t control)
-{
- register uint32_t __regControl __ASM("control");
- __regControl = control;
-}
-
-#endif /* __ARMCC_VERSION */
-
-
-
-#elif (defined (__ICCARM__)) /*------------------ ICC Compiler -------------------*/
-/* IAR iccarm specific functions */
-
-#define __enable_irq __enable_interrupt /*!< global Interrupt enable */
-#define __disable_irq __disable_interrupt /*!< global Interrupt disable */
-
-static __INLINE void __enable_fault_irq( void ) { __ASM ("cpsie f"); }
-static __INLINE void __disable_fault_irq( void ) { __ASM ("cpsid f"); }
-
-#define __NOP __no_operation /*!< no operation intrinsic in IAR Compiler */
-static __INLINE void __WFI( void ) { __ASM ("wfi"); }
-static __INLINE void __WFE( void ) { __ASM ("wfe"); }
-static __INLINE void __SEV( void ) { __ASM ("sev"); }
-static __INLINE void __CLREX( void ) { __ASM ("clrex"); }
-
-/* intrinsic void __ISB(void) */
-/* intrinsic void __DSB(void) */
-/* intrinsic void __DMB(void) */
-/* intrinsic void __set_PRIMASK(); */
-/* intrinsic void __get_PRIMASK(); */
-/* intrinsic void __set_FAULTMASK(); */
-/* intrinsic void __get_FAULTMASK(); */
-/* intrinsic uint32_t __REV(uint32_t value); */
-/* intrinsic uint32_t __REVSH(uint32_t value); */
-/* intrinsic unsigned long __STREX(unsigned long, unsigned long); */
-/* intrinsic unsigned long __LDREX(unsigned long *); */
-
-
-/**
- * @brief Return the Process Stack Pointer
- *
- * @return ProcessStackPointer
- *
- * Return the actual process stack pointer
- */
-extern uint32_t __get_PSP(void);
-
-/**
- * @brief Set the Process Stack Pointer
- *
- * @param topOfProcStack Process Stack Pointer
- *
- * Assign the value ProcessStackPointer to the MSP
- * (process stack pointer) Cortex processor register
- */
-extern void __set_PSP(uint32_t topOfProcStack);
-
-/**
- * @brief Return the Main Stack Pointer
- *
- * @return Main Stack Pointer
- *
- * Return the current value of the MSP (main stack pointer)
- * Cortex processor register
- */
-extern uint32_t __get_MSP(void);
-
-/**
- * @brief Set the Main Stack Pointer
- *
- * @param topOfMainStack Main Stack Pointer
- *
- * Assign the value mainStackPointer to the MSP
- * (main stack pointer) Cortex processor register
- */
-extern void __set_MSP(uint32_t topOfMainStack);
-
-/**
- * @brief Reverse byte order in unsigned short value
- *
- * @param value value to reverse
- * @return reversed value
- *
- * Reverse byte order in unsigned short value
- */
-extern uint32_t __REV16(uint16_t value);
-
-/**
- * @brief Reverse bit order of value
- *
- * @param value value to reverse
- * @return reversed value
- *
- * Reverse bit order of value
- */
-extern uint32_t __RBIT(uint32_t value);
-
-/**
- * @brief LDR Exclusive (8 bit)
- *
- * @param *addr address pointer
- * @return value of (*address)
- *
- * Exclusive LDR command for 8 bit values)
- */
-extern uint8_t __LDREXB(uint8_t *addr);
-
-/**
- * @brief LDR Exclusive (16 bit)
- *
- * @param *addr address pointer
- * @return value of (*address)
- *
- * Exclusive LDR command for 16 bit values
- */
-extern uint16_t __LDREXH(uint16_t *addr);
-
-/**
- * @brief LDR Exclusive (32 bit)
- *
- * @param *addr address pointer
- * @return value of (*address)
- *
- * Exclusive LDR command for 32 bit values
- */
-extern uint32_t __LDREXW(uint32_t *addr);
-
-/**
- * @brief STR Exclusive (8 bit)
- *
- * @param value value to store
- * @param *addr address pointer
- * @return successful / failed
- *
- * Exclusive STR command for 8 bit values
- */
-extern uint32_t __STREXB(uint8_t value, uint8_t *addr);
-
-/**
- * @brief STR Exclusive (16 bit)
- *
- * @param value value to store
- * @param *addr address pointer
- * @return successful / failed
- *
- * Exclusive STR command for 16 bit values
- */
-extern uint32_t __STREXH(uint16_t value, uint16_t *addr);
-
-/**
- * @brief STR Exclusive (32 bit)
- *
- * @param value value to store
- * @param *addr address pointer
- * @return successful / failed
- *
- * Exclusive STR command for 32 bit values
- */
-extern uint32_t __STREXW(uint32_t value, uint32_t *addr);
-
-
-
-#elif (defined (__GNUC__)) /*------------------ GNU Compiler ---------------------*/
-/* GNU gcc specific functions */
-
-static __INLINE void __enable_irq(void) { __ASM volatile ("cpsie i"); }
-static __INLINE void __disable_irq(void) { __ASM volatile ("cpsid i"); }
-
-static __INLINE void __enable_fault_irq(void) { __ASM volatile ("cpsie f"); }
-static __INLINE void __disable_fault_irq(void) { __ASM volatile ("cpsid f"); }
-
-static __INLINE void __NOP(void) { __ASM volatile ("nop"); }
-static __INLINE void __WFI(void) { __ASM volatile ("wfi"); }
-static __INLINE void __WFE(void) { __ASM volatile ("wfe"); }
-static __INLINE void __SEV(void) { __ASM volatile ("sev"); }
-static __INLINE void __ISB(void) { __ASM volatile ("isb"); }
-static __INLINE void __DSB(void) { __ASM volatile ("dsb"); }
-static __INLINE void __DMB(void) { __ASM volatile ("dmb"); }
-static __INLINE void __CLREX(void) { __ASM volatile ("clrex"); }
-
-
-/**
- * @brief Return the Process Stack Pointer
- *
- * @return ProcessStackPointer
- *
- * Return the actual process stack pointer
- */
-extern uint32_t __get_PSP(void);
-
-/**
- * @brief Set the Process Stack Pointer
- *
- * @param topOfProcStack Process Stack Pointer
- *
- * Assign the value ProcessStackPointer to the MSP
- * (process stack pointer) Cortex processor register
- */
-extern void __set_PSP(uint32_t topOfProcStack);
-
-/**
- * @brief Return the Main Stack Pointer
- *
- * @return Main Stack Pointer
- *
- * Return the current value of the MSP (main stack pointer)
- * Cortex processor register
- */
-extern uint32_t __get_MSP(void);
-
-/**
- * @brief Set the Main Stack Pointer
- *
- * @param topOfMainStack Main Stack Pointer
- *
- * Assign the value mainStackPointer to the MSP
- * (main stack pointer) Cortex processor register
- */
-extern void __set_MSP(uint32_t topOfMainStack);
-
-/**
- * @brief Return the Base Priority value
- *
- * @return BasePriority
- *
- * Return the content of the base priority register
- */
-extern uint32_t __get_BASEPRI(void);
-
-/**
- * @brief Set the Base Priority value
- *
- * @param basePri BasePriority
- *
- * Set the base priority register
- */
-extern void __set_BASEPRI(uint32_t basePri);
-
-/**
- * @brief Return the Priority Mask value
- *
- * @return PriMask
- *
- * Return state of the priority mask bit from the priority mask register
- */
-extern uint32_t __get_PRIMASK(void);
-
-/**
- * @brief Set the Priority Mask value
- *
- * @param priMask PriMask
- *
- * Set the priority mask bit in the priority mask register
- */
-extern void __set_PRIMASK(uint32_t priMask);
-
-/**
- * @brief Return the Fault Mask value
- *
- * @return FaultMask
- *
- * Return the content of the fault mask register
- */
-extern uint32_t __get_FAULTMASK(void);
-
-/**
- * @brief Set the Fault Mask value
- *
- * @param faultMask faultMask value
- *
- * Set the fault mask register
- */
-extern void __set_FAULTMASK(uint32_t faultMask);
-
-/**
- * @brief Return the Control Register value
-*
-* @return Control value
- *
- * Return the content of the control register
- */
-extern uint32_t __get_CONTROL(void);
-
-/**
- * @brief Set the Control Register value
- *
- * @param control Control value
- *
- * Set the control register
- */
-extern void __set_CONTROL(uint32_t control);
-
-/**
- * @brief Reverse byte order in integer value
- *
- * @param value value to reverse
- * @return reversed value
- *
- * Reverse byte order in integer value
- */
-extern uint32_t __REV(uint32_t value);
-
-/**
- * @brief Reverse byte order in unsigned short value
- *
- * @param value value to reverse
- * @return reversed value
- *
- * Reverse byte order in unsigned short value
- */
-extern uint32_t __REV16(uint16_t value);
-
-/**
- * @brief Reverse byte order in signed short value with sign extension to integer
- *
- * @param value value to reverse
- * @return reversed value
- *
- * Reverse byte order in signed short value with sign extension to integer
- */
-extern int32_t __REVSH(int16_t value);
-
-/**
- * @brief Reverse bit order of value
- *
- * @param value value to reverse
- * @return reversed value
- *
- * Reverse bit order of value
- */
-extern uint32_t __RBIT(uint32_t value);
-
-/**
- * @brief LDR Exclusive (8 bit)
- *
- * @param *addr address pointer
- * @return value of (*address)
- *
- * Exclusive LDR command for 8 bit value
- */
-extern uint8_t __LDREXB(uint8_t *addr);
-
-/**
- * @brief LDR Exclusive (16 bit)
- *
- * @param *addr address pointer
- * @return value of (*address)
- *
- * Exclusive LDR command for 16 bit values
- */
-extern uint16_t __LDREXH(uint16_t *addr);
-
-/**
- * @brief LDR Exclusive (32 bit)
- *
- * @param *addr address pointer
- * @return value of (*address)
- *
- * Exclusive LDR command for 32 bit values
- */
-extern uint32_t __LDREXW(uint32_t *addr);
-
-/**
- * @brief STR Exclusive (8 bit)
- *
- * @param value value to store
- * @param *addr address pointer
- * @return successful / failed
- *
- * Exclusive STR command for 8 bit values
- */
-extern uint32_t __STREXB(uint8_t value, uint8_t *addr);
-
-/**
- * @brief STR Exclusive (16 bit)
- *
- * @param value value to store
- * @param *addr address pointer
- * @return successful / failed
- *
- * Exclusive STR command for 16 bit values
- */
-extern uint32_t __STREXH(uint16_t value, uint16_t *addr);
-
-/**
- * @brief STR Exclusive (32 bit)
- *
- * @param value value to store
- * @param *addr address pointer
- * @return successful / failed
- *
- * Exclusive STR command for 32 bit values
- */
-extern uint32_t __STREXW(uint32_t value, uint32_t *addr);
-
-
-#elif (defined (__TASKING__)) /*------------------ TASKING Compiler ---------------------*/
-/* TASKING carm specific functions */
-
-/*
- * The CMSIS functions have been implemented as intrinsics in the compiler.
- * Please use "carm -?i" to get an up to date list of all instrinsics,
- * Including the CMSIS ones.
- */
-
-#endif
-
-
-/** @addtogroup CMSIS_CM3_Core_FunctionInterface CMSIS CM3 Core Function Interface
- Core Function Interface containing:
- - Core NVIC Functions
- - Core SysTick Functions
- - Core Reset Functions
-*/
-/*@{*/
-
-/* ########################## NVIC functions #################################### */
-
-/**
- * @brief Set the Priority Grouping in NVIC Interrupt Controller
- *
- * @param PriorityGroup is priority grouping field
- *
- * Set the priority grouping field using the required unlock sequence.
- * The parameter priority_grouping is assigned to the field
- * SCB->AIRCR [10:8] PRIGROUP field. Only values from 0..7 are used.
- * In case of a conflict between priority grouping and available
- * priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set.
- */
-static __INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
-{
- uint32_t reg_value;
- uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */
-
- reg_value = SCB->AIRCR; /* read old register configuration */
- reg_value &= ~(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk); /* clear bits to change */
- reg_value = (reg_value |
- (0x5FA << SCB_AIRCR_VECTKEY_Pos) |
- (PriorityGroupTmp << 8)); /* Insert write key and priorty group */
- SCB->AIRCR = reg_value;
-}
-
-/**
- * @brief Get the Priority Grouping from NVIC Interrupt Controller
- *
- * @return priority grouping field
- *
- * Get the priority grouping from NVIC Interrupt Controller.
- * priority grouping is SCB->AIRCR [10:8] PRIGROUP field.
- */
-static __INLINE uint32_t NVIC_GetPriorityGrouping(void)
-{
- return ((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos); /* read priority grouping field */
-}
-
-/**
- * @brief Enable Interrupt in NVIC Interrupt Controller
- *
- * @param IRQn The positive number of the external interrupt to enable
- *
- * Enable a device specific interupt in the NVIC interrupt controller.
- * The interrupt number cannot be a negative value.
- */
-static __INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
-{
- NVIC->ISER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* enable interrupt */
-}
-
-/**
- * @brief Disable the interrupt line for external interrupt specified
- *
- * @param IRQn The positive number of the external interrupt to disable
- *
- * Disable a device specific interupt in the NVIC interrupt controller.
- * The interrupt number cannot be a negative value.
- */
-static __INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
-{
- NVIC->ICER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* disable interrupt */
-}
-
-/**
- * @brief Read the interrupt pending bit for a device specific interrupt source
- *
- * @param IRQn The number of the device specifc interrupt
- * @return 1 = interrupt pending, 0 = interrupt not pending
- *
- * Read the pending register in NVIC and return 1 if its status is pending,
- * otherwise it returns 0
- */
-static __INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
-{
- return((uint32_t) ((NVIC->ISPR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if pending else 0 */
-}
-
-/**
- * @brief Set the pending bit for an external interrupt
- *
- * @param IRQn The number of the interrupt for set pending
- *
- * Set the pending bit for the specified interrupt.
- * The interrupt number cannot be a negative value.
- */
-static __INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
-{
- NVIC->ISPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* set interrupt pending */
-}
-
-/**
- * @brief Clear the pending bit for an external interrupt
- *
- * @param IRQn The number of the interrupt for clear pending
- *
- * Clear the pending bit for the specified interrupt.
- * The interrupt number cannot be a negative value.
- */
-static __INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
-{
- NVIC->ICPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */
-}
-
-/**
- * @brief Read the active bit for an external interrupt
- *
- * @param IRQn The number of the interrupt for read active bit
- * @return 1 = interrupt active, 0 = interrupt not active
- *
- * Read the active register in NVIC and returns 1 if its status is active,
- * otherwise it returns 0.
- */
-static __INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn)
-{
- return((uint32_t)((NVIC->IABR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if active else 0 */
-}
-
-/**
- * @brief Set the priority for an interrupt
- *
- * @param IRQn The number of the interrupt for set priority
- * @param priority The priority to set
- *
- * Set the priority for the specified interrupt. The interrupt
- * number can be positive to specify an external (device specific)
- * interrupt, or negative to specify an internal (core) interrupt.
- *
- * Note: The priority cannot be set for every core interrupt.
- */
-static __INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
-{
- if(IRQn < 0) {
- SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for Cortex-M3 System Interrupts */
- else {
- NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for device specific Interrupts */
-}
-
-/**
- * @brief Read the priority for an interrupt
- *
- * @param IRQn The number of the interrupt for get priority
- * @return The priority for the interrupt
- *
- * Read the priority for the specified interrupt. The interrupt
- * number can be positive to specify an external (device specific)
- * interrupt, or negative to specify an internal (core) interrupt.
- *
- * The returned priority value is automatically aligned to the implemented
- * priority bits of the microcontroller.
- *
- * Note: The priority cannot be set for every core interrupt.
- */
-static __INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
-{
-
- if(IRQn < 0) {
- return((uint32_t)(SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] >> (8 - __NVIC_PRIO_BITS))); } /* get priority for Cortex-M3 system interrupts */
- else {
- return((uint32_t)(NVIC->IP[(uint32_t)(IRQn)] >> (8 - __NVIC_PRIO_BITS))); } /* get priority for device specific interrupts */
-}
-
-
-/**
- * @brief Encode the priority for an interrupt
- *
- * @param PriorityGroup The used priority group
- * @param PreemptPriority The preemptive priority value (starting from 0)
- * @param SubPriority The sub priority value (starting from 0)
- * @return The encoded priority for the interrupt
- *
- * Encode the priority for an interrupt with the given priority group,
- * preemptive priority value and sub priority value.
- * In case of a conflict between priority grouping and available
- * priority bits (__NVIC_PRIO_BITS) the samllest possible priority group is set.
- *
- * The returned priority value can be used for NVIC_SetPriority(...) function
- */
-static __INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority)
-{
- uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */
- uint32_t PreemptPriorityBits;
- uint32_t SubPriorityBits;
-
- PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp;
- SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS;
-
- return (
- ((PreemptPriority & ((1 << (PreemptPriorityBits)) - 1)) << SubPriorityBits) |
- ((SubPriority & ((1 << (SubPriorityBits )) - 1)))
- );
-}
-
-
-/**
- * @brief Decode the priority of an interrupt
- *
- * @param Priority The priority for the interrupt
- * @param PriorityGroup The used priority group
- * @param pPreemptPriority The preemptive priority value (starting from 0)
- * @param pSubPriority The sub priority value (starting from 0)
- *
- * Decode an interrupt priority value with the given priority group to
- * preemptive priority value and sub priority value.
- * In case of a conflict between priority grouping and available
- * priority bits (__NVIC_PRIO_BITS) the samllest possible priority group is set.
- *
- * The priority value can be retrieved with NVIC_GetPriority(...) function
- */
-static __INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* pPreemptPriority, uint32_t* pSubPriority)
-{
- uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */
- uint32_t PreemptPriorityBits;
- uint32_t SubPriorityBits;
-
- PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp;
- SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS;
-
- *pPreemptPriority = (Priority >> SubPriorityBits) & ((1 << (PreemptPriorityBits)) - 1);
- *pSubPriority = (Priority ) & ((1 << (SubPriorityBits )) - 1);
-}
-
-
-
-/* ################################## SysTick function ############################################ */
-
-#if (!defined (__Vendor_SysTickConfig)) || (__Vendor_SysTickConfig == 0)
-
-/**
- * @brief Initialize and start the SysTick counter and its interrupt.
- *
- * @param ticks number of ticks between two interrupts
- * @return 1 = failed, 0 = successful
- *
- * Initialise the system tick timer and its interrupt and start the
- * system tick timer / counter in free running mode to generate
- * periodical interrupts.
- */
-static __INLINE uint32_t SysTick_Config(uint32_t ticks)
-{
- if (ticks > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */
-
- SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1; /* set reload register */
- NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Cortex-M0 System Interrupts */
- SysTick->VAL = 0; /* Load the SysTick Counter Value */
- SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
- SysTick_CTRL_TICKINT_Msk |
- SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
- return (0); /* Function successful */
-}
-
-#endif
-
-
-
-
-/* ################################## Reset function ############################################ */
-
-/**
- * @brief Initiate a system reset request.
- *
- * Initiate a system reset request to reset the MCU
- */
-static __INLINE void NVIC_SystemReset(void)
-{
- SCB->AIRCR = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) |
- (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) |
- SCB_AIRCR_SYSRESETREQ_Msk); /* Keep priority group unchanged */
- __DSB(); /* Ensure completion of memory access */
- while(1); /* wait until reset */
-}
-
-/*@}*/ /* end of group CMSIS_CM3_Core_FunctionInterface */
-
-
-
-/* ##################################### Debug In/Output function ########################################### */
-
-/** @addtogroup CMSIS_CM3_CoreDebugInterface CMSIS CM3 Core Debug Interface
- Core Debug Interface containing:
- - Core Debug Receive / Transmit Functions
- - Core Debug Defines
- - Core Debug Variables
-*/
-/*@{*/
-
-extern volatile int ITM_RxBuffer; /*!< variable to receive characters */
-#define ITM_RXBUFFER_EMPTY 0x5AA55AA5 /*!< value identifying ITM_RxBuffer is ready for next character */
-
-
-/**
- * @brief Outputs a character via the ITM channel 0
- *
- * @param ch character to output
- * @return character to output
- *
- * The function outputs a character via the ITM channel 0.
- * The function returns when no debugger is connected that has booked the output.
- * It is blocking when a debugger is connected, but the previous character send is not transmitted.
- */
-static __INLINE uint32_t ITM_SendChar (uint32_t ch)
-{
- if ((CoreDebug->DEMCR & CoreDebug_DEMCR_TRCENA_Msk) && /* Trace enabled */
- (ITM->TCR & ITM_TCR_ITMENA_Msk) && /* ITM enabled */
- (ITM->TER & (1ul << 0) ) ) /* ITM Port #0 enabled */
- {
- while (ITM->PORT[0].u32 == 0);
- ITM->PORT[0].u8 = (uint8_t) ch;
- }
- return (ch);
-}
-
-
-/**
- * @brief Inputs a character via variable ITM_RxBuffer
- *
- * @return received character, -1 = no character received
- *
- * The function inputs a character via variable ITM_RxBuffer.
- * The function returns when no debugger is connected that has booked the output.
- * It is blocking when a debugger is connected, but the previous character send is not transmitted.
- */
-static __INLINE int ITM_ReceiveChar (void) {
- int ch = -1; /* no character available */
-
- if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) {
- ch = ITM_RxBuffer;
- ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */
- }
-
- return (ch);
-}
-
-
-/**
- * @brief Check if a character via variable ITM_RxBuffer is available
- *
- * @return 1 = character available, 0 = no character available
- *
- * The function checks variable ITM_RxBuffer whether a character is available or not.
- * The function returns '1' if a character is available and '0' if no character is available.
- */
-static __INLINE int ITM_CheckChar (void) {
-
- if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) {
- return (0); /* no character available */
- } else {
- return (1); /* character available */
- }
-}
-
-/*@}*/ /* end of group CMSIS_CM3_core_DebugInterface */
-
-
-#ifdef __cplusplus
-}
-#endif
-
-/*@}*/ /* end of group CMSIS_CM3_core_definitions */
-
-#endif /* __CM3_CORE_H__ */
-
-/*lint -restore */
diff --git a/sam3s_example/blink.c b/sam3s_example/mains/blink.c
similarity index 100%
rename from sam3s_example/blink.c
rename to sam3s_example/mains/blink.c
diff --git a/sam3s_example/blink2.c b/sam3s_example/mains/blink2.c
similarity index 100%
rename from sam3s_example/blink2.c
rename to sam3s_example/mains/blink2.c
diff --git a/sam3s_example/src_board b/sam3s_example/src_board
new file mode 120000
index 00000000..5ce1bf49
--- /dev/null
+++ b/sam3s_example/src_board
@@ -0,0 +1 @@
+./atmel_softpack_libraries/libboard_sam3s-ek/source
\ No newline at end of file
diff --git a/sam3s_example/src_sam3s b/sam3s_example/src_sam3s
new file mode 120000
index 00000000..6355c88d
--- /dev/null
+++ b/sam3s_example/src_sam3s
@@ -0,0 +1 @@
+./atmel_softpack_libraries/libchip_sam3s/source
\ No newline at end of file