summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2011-07-04 20:52:54 +0200
committerHarald Welte <laforge@gnumonks.org>2011-07-04 20:52:54 +0200
commit044ad7c3987460ede48ff27afd6bdb0ca05a0432 (patch)
tree924818cdb0d39ca08aec540d18da7bd406eaae8c /drivers
import at91lib from at91lib_20100901_softpack_1_9_v_1_0_svn_v1501120100901_softpack_1_9_v_1_0_svn_v15011
it's sad to see that atmel doesn't publish their svn repo or has a centralized location or even puts proper version/release info into the library itself
Diffstat (limited to 'drivers')
-rw-r--r--drivers/async/async.c48
-rw-r--r--drivers/async/async.h65
-rw-r--r--drivers/dmad/dmad.c300
-rw-r--r--drivers/dmad/dmad.dir36
-rw-r--r--drivers/dmad/dmad.h158
-rw-r--r--drivers/drivers.dir44
-rw-r--r--drivers/lcd/color.h132
-rw-r--r--drivers/lcd/draw.c237
-rw-r--r--drivers/lcd/draw.h110
-rw-r--r--drivers/lcd/draw_hx8347.c387
-rw-r--r--drivers/lcd/font.c209
-rw-r--r--drivers/lcd/font.h112
-rw-r--r--drivers/lcd/font10x14.h237
-rw-r--r--drivers/lcd/lcd.dir39
-rw-r--r--drivers/lcd/lcdd.c138
-rw-r--r--drivers/lcd/lcdd.h61
-rw-r--r--drivers/lcd/lcdd_hx8347.c147
-rw-r--r--drivers/macb/macb.c569
-rw-r--r--drivers/macb/macb.dir42
-rw-r--r--drivers/macb/macb.h106
-rw-r--r--drivers/macb/mii.h178
-rw-r--r--drivers/tsd/tsd.dir42
-rw-r--r--drivers/tsd/tsd.h74
-rw-r--r--drivers/tsd/tsd_ads7843.c438
-rw-r--r--drivers/tsd/tsd_com.c390
-rw-r--r--drivers/tsd/tsd_com.h48
-rw-r--r--drivers/tsd/tsd_tsadc.c269
-rw-r--r--drivers/twi/twid.c344
-rw-r--r--drivers/twi/twid.h92
29 files changed, 5052 insertions, 0 deletions
diff --git a/drivers/async/async.c b/drivers/async/async.c
new file mode 100644
index 0000000..618af33
--- /dev/null
+++ b/drivers/async/async.c
@@ -0,0 +1,48 @@
+/* ----------------------------------------------------------------------------
+ * 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 "async.h"
+
+//------------------------------------------------------------------------------
+// Global functions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// Returns 1 if the given transfer has ended; otherwise returns 0.
+/// \param pAsync Pointer to an Async instance.
+//------------------------------------------------------------------------------
+unsigned char ASYNC_IsFinished(Async *pAsync)
+{
+ return (pAsync->status != ASYNC_STATUS_PENDING);
+}
+
diff --git a/drivers/async/async.h b/drivers/async/async.h
new file mode 100644
index 0000000..e359895
--- /dev/null
+++ b/drivers/async/async.h
@@ -0,0 +1,65 @@
+/* ----------------------------------------------------------------------------
+ * 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.
+ * ----------------------------------------------------------------------------
+ */
+
+#ifndef ASYNC_H
+#define ASYNC_H
+
+//------------------------------------------------------------------------------
+// Global definitions
+//------------------------------------------------------------------------------
+
+/// Transfer is still pending.
+#define ASYNC_STATUS_PENDING 0xFF
+
+//------------------------------------------------------------------------------
+// Global types
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// Asynchronous transfer descriptor.
+//------------------------------------------------------------------------------
+typedef struct _Async {
+
+ // Asynchronous transfer status.
+ volatile unsigned char status;
+ // Callback function to invoke when transfer completes or fails.
+ void *callback;
+ // Driver storage area; do not use.
+ unsigned int pStorage[4];
+
+} Async;
+
+//------------------------------------------------------------------------------
+// Global functions
+//------------------------------------------------------------------------------
+
+extern unsigned char ASYNC_IsFinished(Async *pAsync);
+
+#endif //#ifndef ASYNC_H
+
diff --git a/drivers/dmad/dmad.c b/drivers/dmad/dmad.c
new file mode 100644
index 0000000..75187d0
--- /dev/null
+++ b/drivers/dmad/dmad.c
@@ -0,0 +1,300 @@
+/* ----------------------------------------------------------------------------
+ * 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 "dmad.h"
+#include <dma/dma.h>
+#include <irq/irq.h>
+#include <utility/assert.h>
+#include <utility/trace.h>
+
+//------------------------------------------------------------------------------
+// Local types
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+/// DMA transfer descriptor. Tracks the status and parameters of a transfer
+/// on the DMA bus.
+//------------------------------------------------------------------------------
+typedef struct _DmaTransfer {
+ /// Buffer transfer status.
+ volatile unsigned char status;
+ /// Transfer buffer size in byte.
+ unsigned int bufSize;
+ /// Total transfer size to byte.
+ volatile unsigned int transferSize;
+ /// Optional callback function.
+ DmaCallback callback;
+} DmaTransfer;
+
+//------------------------------------------------------------------------------
+/// DMAD driver structure. Monitors the status of transfers on all
+/// DMA channels.
+//------------------------------------------------------------------------------
+typedef struct _Dmad {
+
+ /// List of transfers occuring on each channel.
+ DmaTransfer transfers[DMA_CHANNEL_NUM];
+} Dmad;
+
+//------------------------------------------------------------------------------
+// Local variables
+//------------------------------------------------------------------------------
+
+/// Global DMA transfer instance.
+static Dmad dmad;
+
+//------------------------------------------------------------------------------
+// Local functions
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+/// This handler function must be called by the DMAC interrupt service routine.
+/// Identifies which event was activated and calls the associated function.
+//------------------------------------------------------------------------------
+void DMAD_Handler()
+{
+ unsigned int status;
+ unsigned char channel;
+ DmaTransfer *pTransfer;
+ status = DMA_GetStatus();
+ // Check if the buffer transfer completed is set.
+ if(status & AT91C_BTC)
+ {
+ // Scan each channel status.
+ for(channel = 0; channel < DMA_CHANNEL_NUM; channel++) {
+ if(!(status & (DMA_BTC << channel))){
+ continue;
+ }
+
+ dmad.transfers[channel].transferSize -= dmad.transfers[channel].bufSize;
+ // if next buffer is to be the last buffer in the transfer, then clear the automatic mode bit.
+ if(dmad.transfers[channel].transferSize <= dmad.transfers[channel].bufSize) {
+ DMA_ClearAutoMode(channel);
+ }
+ // Transfer finished
+ if(dmad.transfers[channel].transferSize == 0) {
+ pTransfer = &(dmad.transfers[channel]);
+ pTransfer->callback();
+ DMA_DisableIt(DMA_BTC << channel);
+ DMA_DisableChannel(channel);
+ }
+ else
+ {
+ // Write the KEEPON field to clear the STALL states.
+ DMA_KeeponChannel(channel);
+ }
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+/// Initializes the DMA controller.
+/// \param channel Particular channel number
+/// \param defaultHandler Using the default dmad interrupt handler.
+//------------------------------------------------------------------------------
+void DMAD_Initialize(unsigned char channel, unsigned char defaultHandler)
+{
+ unsigned int status;
+ unsigned int flag;
+
+ // Enable peripheral clock
+#if !defined(at91sam9rl64)
+ AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_HDMA;
+#endif
+
+ // Read the channel handler status to ensure the channel is a free channel.
+ status = DMA_GetChannelStatus();
+ TRACE_INFO ("DMAD_Initialize channel %x \n\r", channel);
+ SANITY_CHECK(!(status & (1 << channel)));
+ // Clear any pending interrupts on the channel.
+ DMA_GetStatus();
+ // Disble the channel.
+ DMA_DisableChannel(channel);
+ // Disable the interrupt
+ flag = 0xffffff;
+ DMA_DisableIt(flag);
+ // Enable DMA.
+ DMA_Enable();
+ if(defaultHandler)
+ {
+ IRQ_ConfigureIT(AT91C_ID_HDMA, 0, DMAD_Handler);
+ IRQ_EnableIT(AT91C_ID_HDMA);
+ }
+ // Initialize transfer instance.
+ dmad.transfers[channel].transferSize = 0;
+}
+
+//------------------------------------------------------------------------------
+/// Configure the DMA transfer buffer by giving transfer mode, it could be single
+/// buffer or multi-buffer(LLI/auto-reload/contiguous buffers) with or without
+/// Picture-In-Picture mode.
+/// \param channel Particular channel number.
+/// \param sourceTransferMode Source buffer transfer mode.
+/// \param destTransferMode Destination buffer transfer mode.
+/// \param lli Pointer to a DmaLinkList structure instance.
+/// \param pip Pointer to a PictureInPicture structure.
+//------------------------------------------------------------------------------
+unsigned char DMAD_Configure_Buffer(unsigned char channel,
+ unsigned char sourceTransferMode,
+ unsigned char destTransferMode,
+ DmaLinkList *lli,
+ PictureInPicture *pip)
+{
+ DmaTransfer *pTransfer = &(dmad.transfers[channel]);
+ // Check that no transfer is pending on the channel
+ if (pTransfer-> transferSize > 0 ) {
+ TRACE_ERROR("DAM transfer is already pending\n\r");
+ return DMAD_ERROR_BUSY;
+ }
+ // Configure source transfer mode.
+ DMA_SetSourceBufferMode(channel, sourceTransferMode, 0);
+
+ // Configure destination transfer mode.
+ DMA_SetDestBufferMode(channel, destTransferMode, 0);
+
+ if(lli){
+ DMA_SetDescriptorAddr(channel, (unsigned int)(&lli[0]));
+ }
+ else {
+ DMA_SetDescriptorAddr(channel, 0);
+ }
+
+ if(pip){
+ #if defined(AT91C_SRC_PIP)
+ // If source picture-in-picture mode is enabled, program the DMAC_SPIP.
+ if(pip->pipSourceBoundarySize){
+ // If destination picture-in-picture mode is enabled, program the DMAC_DPIP.
+ DMA_SPIPconfiguration(channel, pip->pipSourceHoleSize, pip->pipSourceBoundarySize);
+ }
+ #endif
+
+ #if defined(AT91C_DST_PIP)
+ if(pip->pipDestBoundarySize){
+ DMA_DPIPconfiguration(channel, pip->pipDestHoleSize, pip->pipDestBoundarySize);
+ }
+ #endif
+ }
+ return 0;
+}
+
+//------------------------------------------------------------------------------
+/// Configure the DMA transfer control infomation.
+/// \param channel Particular channel number.
+/// \param bufSize Buffer transfer size in byte.
+/// \param sourceWidth Source transfer width.
+/// \param destWidth Destination transfer width.
+/// \param sourceAddress Destination transfer width.
+/// \param destAddress Destination transfer width.
+//------------------------------------------------------------------------------
+unsigned char DMAD_Configure_TransferController(unsigned char channel,
+ unsigned int bufSize,
+ unsigned char sourceWidth,
+ unsigned char destWidth,
+ unsigned int sourceAddress,
+ unsigned int destAddress)
+{
+ DmaTransfer *pTransfer = &(dmad.transfers[channel]);
+ // Check that no transfer is pending on the channel
+ if (pTransfer-> transferSize > 0 ) {
+ TRACE_ERROR("DAM transfer is already pending\n\r");
+ return DMAD_ERROR_BUSY;
+ }
+ pTransfer->bufSize = bufSize;
+
+ // Set up the transfer width and transfer size.
+ DMA_SetSourceBufferSize(channel, bufSize, sourceWidth, destWidth, 0);
+
+ if(sourceAddress) {
+ // Write the starting source address.
+ DMA_SetSourceAddr(channel, sourceAddress);
+ }
+ if(destAddress){
+ // Write the starting destination address.
+ DMA_SetDestinationAddr(channel, destAddress);
+ }
+ return 0;
+}
+
+//------------------------------------------------------------------------------
+/// Starts buffer transfer on the given channel
+/// \param channel Particular channel number.
+/// \param size Total transfer size in byte.
+/// \param callback Optional callback function.
+/// \param polling Polling channel status enable.
+//------------------------------------------------------------------------------
+unsigned char DMAD_BufferTransfer(unsigned char channel,
+ unsigned int size,
+ DmaCallback callback,
+ unsigned char polling)
+{
+ DmaTransfer *pTransfer = &(dmad.transfers[channel]);
+ // Check that no transfer is pending on the channel
+ if (pTransfer-> transferSize > 0 ) {
+ TRACE_ERROR("DAM transfer is already pending\n\r");
+ return DMAD_ERROR_BUSY;
+ }
+ pTransfer->status = DMAD_ERROR_BUSY;
+ pTransfer->transferSize = size;
+ pTransfer->callback = callback;
+
+ if(!polling){
+ DMA_EnableIt(DMA_BTC << channel);
+ }
+ // Enable the channel.
+ DMA_EnableChannel(channel);
+
+ if(polling){
+ while ((DMA_GetChannelStatus() & (DMA_ENA << channel)) == (DMA_ENA << channel));
+ if (pTransfer->callback) {
+ pTransfer->callback();
+ }
+ pTransfer->transferSize = 0;
+ DMA_DisableChannel(channel);
+ }
+ return 0;
+}
+
+//------------------------------------------------------------------------------
+/// Returns 1 if no transfer is currently pending on the given channel;
+/// otherwise, returns 0.
+/// \param channel Channel number.
+//------------------------------------------------------------------------------
+unsigned char DMAD_IsFinished(unsigned char channel)
+{
+ SANITY_CHECK(channel <= DMA_CHANNEL_NUM);
+ if (dmad.transfers[channel].transferSize > 0) {
+ return 0;
+ }
+ else {
+ DMA_DisableChannel(channel);
+ return 1;
+ }
+}
diff --git a/drivers/dmad/dmad.dir b/drivers/dmad/dmad.dir
new file mode 100644
index 0000000..a9ec454
--- /dev/null
+++ b/drivers/dmad/dmad.dir
@@ -0,0 +1,36 @@
+/* ----------------------------------------------------------------------------
+ * 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.
+ * ----------------------------------------------------------------------------
+ */
+
+//------------------------------------------------------------------------------
+/// \dir
+///
+/// !!!Contents
+///
+/// This directory contains the source code for the DMA driver in dmad.h.
+//------------------------------------------------------------------------------
diff --git a/drivers/dmad/dmad.h b/drivers/dmad/dmad.h
new file mode 100644
index 0000000..dfb0886
--- /dev/null
+++ b/drivers/dmad/dmad.h
@@ -0,0 +1,158 @@
+/* ----------------------------------------------------------------------------
+ * 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.
+ * ----------------------------------------------------------------------------
+ */
+
+//------------------------------------------------------------------------------
+/// \unit
+///
+/// !!!Purpose
+///
+/// The %Dma driver is a high level dma driver which performs DMA device Initializes,
+/// tansfer mode configuration and dma transfer.
+///
+/// !!!Usage
+///
+/// -# Initializes a %Dma controller and dma transfer instance.
+/// Initializes dma for specified channel using DMAD_Initialize().
+/// -# Configures the %Dma transfer buffer by giving transfer mode, transfer mode
+/// for source peripheral and destination peripheral could be single buffer or
+/// multi-buffer(LLI/auto-reload/contiguous buffers) with or without
+/// Picture-In-Picture mode.
+/// DMAD_Configure_Buffer()
+/// \code
+/// // Configure multi-buffer transfer with source address auto-reloaded and
+/// contiguous destination address.
+/// DMAD_Configure_Buffer(DMA_CHANNEL_1,
+/// DMA_TRANSFER_RELOAD,
+/// DMA_TRANSFER_CONTIGUOUS,
+/// 0,
+/// 0);
+/// \endcode
+/// -# Configures the %Dma characteristics (such as source/destination
+/// single transfer width, buffer transfer size and source/destionation
+/// start addreass for the device corresponding to the specified channle
+/// using DMAD_Configure_TransferController().
+/// -# Starts a %Dma transfer using DMAD_BufferTransfer().
+/// The transfer is performed using the %Dma channels.
+/// -# Initialize the total size to be transfered.
+/// -# Initialize the callback function if specified.
+/// -# Enable the interrupt for specified %dma channel.
+/// -# Enable the specified %dma channel.
+/// -# Example for transfering buffer through the %Dma.
+/// \code
+/// // Start channel 1 transfer. Source image auto-reload 4 times.
+/// and transfer to destination continguous.
+/// DMAD_BufferTransfer(DMA_CHANNEL_1, bufferSize * 4, TestCallback, 0);
+/// while (!DMAD_IsFinished(DMA_CHANNEL_1));
+/// \endcode
+/// -# The DMAD_Handler() must be called by the DMA Interrupt Service Routine
+/// with the corresponding %Dma instance. It is invokes to check for pending
+/// interrupts.
+/// - Example for initializing %Dma interrupt handler in upper application.
+/// \code
+/// AIC_ConfigureIT(AT91C_ID_HDMA, 0, DMAD_Handler);
+/// \endcode
+//------------------------------------------------------------------------------
+
+#ifndef DMAD_H
+#define DMAD_H
+
+//------------------------------------------------------------------------------
+// Global definitions
+//------------------------------------------------------------------------------
+/// DMA driver is currently busy.
+#define DMAD_ERROR_BUSY 1
+/// Using the default interrupt handler of the DMAD
+#define DMAD_USE_DEFAULT_IT 1
+#define DMAD_NO_DEFAULT_IT 0
+
+//------------------------------------------------------------------------------
+// Types
+//------------------------------------------------------------------------------
+
+/// DMA driver callback function.
+typedef void (*DmaCallback)();
+
+//------------------------------------------------------------------------------
+/// DMA multi buffer transfer Linker List Item structure.
+//------------------------------------------------------------------------------
+typedef struct _DmaLinkList {
+ /// Source address.
+ unsigned int sourceAddress;
+ /// Destination address.
+ unsigned int destAddress;
+ /// Control A value.
+ unsigned int controlA;
+ /// Control B value.
+ unsigned int controlB;
+ /// Descriptor Address.
+ unsigned int descriptor;
+} DmaLinkList;
+
+//------------------------------------------------------------------------------
+/// DMA picture-in-picture mode configuration structure.
+//------------------------------------------------------------------------------
+typedef struct _PictureInPicture {
+ /// Size in byte add to the source address in PIP.
+ unsigned short pipSourceHoleSize;
+ /// Number of transfer in byte to perform before the source address increase.
+ unsigned short pipSourceBoundarySize;
+ /// Size in byte add to the destination address in PIP.
+ unsigned short pipDestHoleSize;
+ /// Number of transfer in byte to perform before the destination address increase.
+ unsigned short pipDestBoundarySize;
+} PictureInPicture;
+
+
+//------------------------------------------------------------------------------
+// Global functions
+//------------------------------------------------------------------------------
+extern void DMAD_Initialize(unsigned char channel, unsigned char defaultHandler);
+
+extern unsigned char DMAD_Configure_Buffer(unsigned char channel,
+ unsigned char sourceTransferMode,
+ unsigned char destTransferMode,
+ DmaLinkList *lli,
+ PictureInPicture *pip);
+
+extern unsigned char DMAD_Configure_TransferController(unsigned char channel,
+ unsigned int bufSize,
+ unsigned char sourceWidth,
+ unsigned char destWidth,
+ unsigned int sourceAddress,
+ unsigned int destAddress);
+
+extern unsigned char DMAD_BufferTransfer(unsigned char channel,
+ unsigned int size,
+ DmaCallback callback,
+ unsigned char polling);
+
+extern unsigned char DMAD_IsFinished(unsigned char channel);
+
+#endif //#ifndef DMAD_H
+
diff --git a/drivers/drivers.dir b/drivers/drivers.dir
new file mode 100644
index 0000000..edf87bd
--- /dev/null
+++ b/drivers/drivers.dir
@@ -0,0 +1,44 @@
+/* ----------------------------------------------------------------------------
+ * 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.
+ * ----------------------------------------------------------------------------
+ */
+
+//------------------------------------------------------------------------------
+/// \dir
+/// !Purpose
+///
+/// This directory contains several sub-directories, each one corresponding to
+/// a category of code modules.
+///
+/// Each subdirectory inside this one provides code for fully-fledged drivers.
+///
+/// Drivers APIs provide high-level unified interface of functions to drive
+/// %interlnal Flash interface, tsd interface, %Twi interface and so on.
+/// However, they do not provide low-level functions to use of AT91 peripherals;
+/// such code can be found in the #perpherials# directory of at91lib.
+//------------------------------------------------------------------------------
+
diff --git a/drivers/lcd/color.h b/drivers/lcd/color.h
new file mode 100644
index 0000000..68128c2
--- /dev/null
+++ b/drivers/lcd/color.h
@@ -0,0 +1,132 @@
+/* ----------------------------------------------------------------------------
+ * 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.
+ * ----------------------------------------------------------------------------
+ */
+
+#ifndef COLOR_H
+#define COLOR_H
+
+//------------------------------------------------------------------------------
+/// RGB 24 Bpp
+/// RGB 888
+/// R7R6R5R4 R3R2R1R0 G7G6G5G4 G3G2G1G0 B7B6B5B4 B3B2B1B0
+//------------------------------------------------------------------------------
+#define COLOR_BLACK 0x000000
+#define COLOR_WHITE 0xFFFFFF
+
+#define COLOR_BLUE 0x0000FF
+#define COLOR_GREEN 0x00FF00
+#define COLOR_RED 0xFF0000
+
+#define COLOR_NAVY 0x000080
+#define COLOR_DARKBLUE 0x00008B
+#define COLOR_DARKGREEN 0x006400
+#define COLOR_DARKCYAN 0x008B8B
+#define COLOR_CYAN 0x00FFFF
+#define COLOR_TURQUOISE 0x40E0D0
+#define COLOR_INDIGO 0x4B0082
+#define COLOR_DARKRED 0x800000
+#define COLOR_OLIVE 0x808000
+#define COLOR_GRAY 0x808080
+#define COLOR_SKYBLUE 0x87CEEB
+#define COLOR_BLUEVIOLET 0x8A2BE2
+#define COLOR_LIGHTGREEN 0x90EE90
+#define COLOR_DARKVIOLET 0x9400D3
+#define COLOR_YELLOWGREEN 0x9ACD32
+#define COLOR_BROWN 0xA52A2A
+#define COLOR_DARKGRAY 0xA9A9A9
+#define COLOR_SIENNA 0xA0522D
+#define COLOR_LIGHTBLUE 0xADD8E6
+#define COLOR_GREENYELLOW 0xADFF2F
+#define COLOR_SILVER 0xC0C0C0
+#define COLOR_LIGHTGREY 0xD3D3D3
+#define COLOR_LIGHTCYAN 0xE0FFFF
+#define COLOR_VIOLET 0xEE82EE
+#define COLOR_AZUR 0xF0FFFF
+#define COLOR_BEIGE 0xF5F5DC
+#define COLOR_MAGENTA 0xFF00FF
+#define COLOR_TOMATO 0xFF6347
+#define COLOR_GOLD 0xFFD700
+#define COLOR_ORANGE 0xFFA500
+#define COLOR_SNOW 0xFFFAFA
+#define COLOR_YELLOW 0xFFFF00
+
+#endif // #define COLOR_H
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/drivers/lcd/draw.c b/drivers/lcd/draw.c
new file mode 100644
index 0000000..e7d5909
--- /dev/null
+++ b/drivers/lcd/draw.c
@@ -0,0 +1,237 @@
+/* ----------------------------------------------------------------------------
+ * 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 "draw.h"
+#include "font.h"
+#include <board.h>
+#include <utility/assert.h>
+
+#include <string.h>
+
+//------------------------------------------------------------------------------
+// Global functions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// Fills the given LCD buffer with a particular color.
+/// Only works in 24-bits packed mode for now.
+/// \param pBuffer LCD buffer to fill.
+/// \param color Fill color.
+//------------------------------------------------------------------------------
+void LCDD_Fill(void *pBuffer, unsigned int color)
+{
+ unsigned int i;
+ unsigned char tmpBuffer[12];
+
+ // Prepare temporary buffer
+ for (i=0; i < 4; i++) {
+
+ memcpy(&(tmpBuffer[i*3]), &color, 3);
+ }
+
+ // Copy in LCD buffer
+ i = 0;
+ while (i < (BOARD_LCD_FRAMESIZE * 4)) {
+
+ memcpy(&(((unsigned char *) pBuffer)[i]), tmpBuffer, 12);
+ i += 12;
+ }
+}
+
+//------------------------------------------------------------------------------
+/// Sets the specified pixel to the given color.
+/// !!! Only works in 24-bits packed mode for now. !!!
+/// \param pBuffer LCD buffer to draw on.
+/// \param x X-coordinate of pixel.
+/// \param y Y-coordinate of pixel.
+/// \param color Pixel color.
+//------------------------------------------------------------------------------
+void LCDD_DrawPixel(
+ void *pBuffer,
+ unsigned int x,
+ unsigned int y,
+ unsigned int color)
+{
+ unsigned char *pTmp = &(((unsigned char *) pBuffer)[y*3*BOARD_LCD_WIDTH + x*3]);
+
+ // Modify color when using RGB565
+#ifdef BOARD_LCD_RGB565
+ unsigned char r;
+ unsigned char g;
+ unsigned char b;
+
+ r = (color >> 16) & 0xFF;
+ g = (color >> 8) & 0xFF;
+ b = color & 0xFF;
+ r = ((r & 0x78) << 1) | ((r & 0x80) >> 5) | ((g & 0x80) >> 4);
+ g = ((g & 0x7C) << 1);
+ b = (b & 0xFC);
+ color = (b << 16) | (g << 8) | r;
+#elif defined (BOARD_LCD_BGR565)
+ unsigned char r;
+ unsigned char g;
+ unsigned char b;
+
+ r = (color >> 16) & 0xFF;
+ g = (color >> 8) & 0xFF;
+ b = color & 0xFF;
+ color = (b << 16) | (g << 8) | r;
+#endif
+
+ pTmp[0] = (color >> 16) & 0xFF;
+ pTmp[1] = (color >> 8) & 0xFF;
+ pTmp[2] = (color >> 0) & 0xFF;
+}
+
+//------------------------------------------------------------------------------
+/// Read pixel of given coordinate.
+/// !!! Only works in 24-bits packed mode for now. !!!
+/// \param pBuffer LCD buffer to draw on.
+/// \param x X-coordinate of pixel.
+/// \param y Y-coordinate of pixel.
+/// \return Pixel color.
+//------------------------------------------------------------------------------
+unsigned int LCDD_ReadPixel(
+ void *pBuffer,
+ unsigned int x,
+ unsigned int y)
+{
+ unsigned char *pTmp = &(((unsigned char *) pBuffer)[y*3*BOARD_LCD_WIDTH + x*3]);
+ unsigned int color;
+
+#ifdef BOARD_LCD_RGB565
+ color = 0; // TBD
+#elif defined (BOARD_LCD_BGR565)
+ color = ((pTmp[2] << 16) | (pTmp[1] << 8) | pTmp[0]);
+#else
+ color = ((pTmp[0] << 16) | (pTmp[1] << 8) | pTmp[2]);
+#endif
+
+ return color;
+}
+
+//------------------------------------------------------------------------------
+/// Draws a rectangle inside a LCD buffer, at the given coordinates.
+/// \param pBuffer LCD buffer to draw on.
+/// \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.
+//------------------------------------------------------------------------------
+void LCDD_DrawRectangle(
+ void *pBuffer,
+ unsigned int x,
+ unsigned int y,
+ unsigned int width,
+ unsigned int height,
+ unsigned int color)
+{
+ unsigned int rx, ry;
+
+ for (ry=0; ry < height; ry++) {
+
+ for (rx=0; rx < width; rx++) {
+
+ LCDD_DrawPixel(pBuffer, x+rx, y+ry, color);
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+/// Draws a string inside a LCD buffer, at the given coordinates. Line breaks
+/// will be honored.
+/// \param pBuffer Buffer to draw on.
+/// \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.
+//------------------------------------------------------------------------------
+void LCDD_DrawString(
+ void *pBuffer,
+ unsigned int x,
+ unsigned int y,
+ const char *pString,
+ unsigned int color)
+{
+ unsigned xorg = x;
+
+ while (*pString != 0) {
+ if (*pString == '\n') {
+
+ y += gFont.height + 2;
+ x = xorg;
+ }
+ else {
+
+ LCDD_DrawChar(pBuffer, x, y, *pString, color);
+ x += gFont.width + 2;
+ }
+ pString++;
+ }
+}
+
+//------------------------------------------------------------------------------
+/// 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.
+//------------------------------------------------------------------------------
+void LCDD_GetStringSize(
+ const char *pString,
+ unsigned int *pWidth,
+ unsigned int *pHeight)
+{
+ unsigned int width = 0;
+ unsigned int 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) *pWidth = width;
+ if (pHeight) *pHeight = height;
+}
diff --git a/drivers/lcd/draw.h b/drivers/lcd/draw.h
new file mode 100644
index 0000000..5690b66
--- /dev/null
+++ b/drivers/lcd/draw.h
@@ -0,0 +1,110 @@
+/* ----------------------------------------------------------------------------
+ * 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.
+ * ----------------------------------------------------------------------------
+ */
+
+//------------------------------------------------------------------------------
+/// \unit
+///
+/// !!!Purpose
+///
+/// Provides simple drawing function to use with the LCD.
+///
+/// !!!Usage
+///
+/// -# Use LCDD_Fill to fill the LCD buffer with a specific color.
+/// -# Draw a pixel on the screen at the specified coordinates using
+/// LCDD_DrawPixel.
+/// -# Draw a rectangle with LCDD_DrawRectangle.
+/// -# Draw a string on the LCD with LCDD_DrawString.
+//------------------------------------------------------------------------------
+
+#ifndef DRAW_H
+#define DRAW_H
+
+//------------------------------------------------------------------------------
+// Global functions
+//------------------------------------------------------------------------------
+
+extern void LCDD_Fill(void *pBuffer, unsigned int color);
+
+extern void LCDD_DrawPixel(
+ void *pBuffer,
+ unsigned int x,
+ unsigned int y,
+ unsigned int c);
+
+extern unsigned int LCDD_ReadPixel(
+ void *pBuffer,
+ unsigned int x,
+ unsigned int y);
+
+extern void LCDD_DrawRectangle(
+ void *pBuffer,
+ unsigned int x,
+ unsigned int y,
+ unsigned int width,
+ unsigned int height,
+ unsigned int color);
+
+extern void LCDD_DrawString(
+ void *pBuffer,
+ unsigned int x,
+ unsigned int y,
+ const char *pString,
+ unsigned int color);
+extern void LCDD_DrawStringEx(
+ void *pBuffer,
+ unsigned int x,
+ unsigned int y,
+ const char *pString,
+ unsigned int color,
+ unsigned int dir);
+
+extern void LCDD_DrawStringWithBGColor(
+ void *pBuffer,
+ unsigned int x,
+ unsigned int y,
+ const char *pString,
+ unsigned int fontColor,
+ unsigned int bgColor);
+
+extern void LCDD_DrawStringWithBGColorEx(
+ void *pBuffer,
+ unsigned int x,
+ unsigned int y,
+ const char *pString,
+ unsigned int fontColor,
+ unsigned int bgColor,
+ unsigned int dir);
+
+extern void LCDD_GetStringSize(
+ const char *pString,
+ unsigned int *pWidth,
+ unsigned int *pHeight);
+
+#endif //#ifndef DRAW_H
diff --git a/drivers/lcd/draw_hx8347.c b/drivers/lcd/draw_hx8347.c
new file mode 100644
index 0000000..f262d9a
--- /dev/null
+++ b/drivers/lcd/draw_hx8347.c
@@ -0,0 +1,387 @@
+/* ----------------------------------------------------------------------------
+ * 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 "draw.h"
+#include "font.h"
+#include <board.h>
+#include <utility/assert.h>
+#include <hx8347/hx8347.h>
+
+#include <string.h>
+/// lcd is busy,0 free,1 busy
+int gLCDIsBusy = 0;
+//------------------------------------------------------------------------------
+// Global functions
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+/// indicate the lcd is available for use
+//------------------------------------------------------------------------------
+int LCDD_IsBusy()
+{
+ return gLCDIsBusy;
+}
+//------------------------------------------------------------------------------
+/// Set lcd to busy
+//------------------------------------------------------------------------------
+void LCDD_SetBusy()
+{
+ gLCDIsBusy = 1;
+}
+//------------------------------------------------------------------------------
+/// clear lcd to free
+//------------------------------------------------------------------------------
+void LCDD_ClearBusy()
+{
+ gLCDIsBusy = 0;
+}
+//------------------------------------------------------------------------------
+/// Fills the given LCD buffer with a particular color.
+/// Only works in 24-bits packed mode for now.
+/// \param pBuffer LCD buffer to fill.
+/// \param color Fill color.
+//------------------------------------------------------------------------------
+void LCDD_Fill(void *pBuffer, unsigned int color)
+{
+ unsigned int i;
+ unsigned short color16 = RGB24ToRGB16(color);
+
+
+ LCD_SetCursor((void *)BOARD_LCD_BASE, 0, 0);
+ LCD_WriteRAM_Prepare((void *)BOARD_LCD_BASE);
+ for (i = 0; i < (BOARD_LCD_WIDTH * BOARD_LCD_HEIGHT); i++) {
+
+ LCD_WriteRAM((void *)BOARD_LCD_BASE, color16);
+ }
+}
+
+//------------------------------------------------------------------------------
+/// Sets the specified pixel to the given color.
+/// !!! Only works in 24-bits packed mode for now. !!!
+/// \param pBuffer LCD buffer to draw on.
+/// \param x X-coordinate of pixel.
+/// \param y Y-coordinate of pixel.
+/// \param color Pixel color.
+//------------------------------------------------------------------------------
+void LCDD_DrawPixel(
+ void *pBuffer,
+ unsigned int x,
+ unsigned int y,
+ unsigned int color)
+{
+ unsigned short color16 = RGB24ToRGB16(color);
+
+ LCD_SetCursor(pBuffer, x, y);
+ LCD_WriteRAM_Prepare(pBuffer);
+ LCD_WriteRAM(pBuffer, color16);
+}
+
+//------------------------------------------------------------------------------
+/// Read pixel of given coordinate.
+/// !!! The return pixel is RGB565 format !!!
+/// \param pBuffer LCD buffer to draw on.
+/// \param x X-coordinate of pixel.
+/// \param y Y-coordinate of pixel.
+/// \return Pixel color.
+//------------------------------------------------------------------------------
+unsigned int LCDD_ReadPixel(
+ void *pBuffer,
+ unsigned int x,
+ unsigned int y)
+{
+ unsigned short readData[4];
+ unsigned int color;
+
+ LCD_SetCursor(pBuffer, x, y);
+ LCD_ReadRAM_Prepare(pBuffer);
+ readData[0] = LCD_ReadRAM(pBuffer); // Dummy date
+ readData[1] = LCD_ReadRAM(pBuffer); // color R
+ readData[2] = LCD_ReadRAM(pBuffer); // color G
+ readData[3] = LCD_ReadRAM(pBuffer); // color B
+ color = (((readData[1] & 0xF8) << 8) |
+ ((readData[2] & 0xFC) << 3) |
+ ((readData[3] & 0xF8) >> 3));
+
+ return color;
+}
+
+//------------------------------------------------------------------------------
+/// Draws a rectangle inside a LCD buffer, at the given coordinates.
+/// \param pBuffer LCD buffer to draw on.
+/// \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.
+//------------------------------------------------------------------------------
+void LCDD_DrawRectangle(
+ void *pBuffer,
+ unsigned int x,
+ unsigned int y,
+ unsigned int width,
+ unsigned int height,
+ unsigned int color)
+{
+ unsigned int rx, ry;
+
+ for (ry=0; ry < height; ry++) {
+
+ for (rx=0; rx < width; rx++) {
+
+ LCDD_DrawPixel(pBuffer, x+rx, y+ry, color);
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+/// Draws a string inside a LCD buffer, at the given coordinates. Line breaks
+/// will be honored.
+/// \param pBuffer Buffer to draw on.
+/// \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.
+//------------------------------------------------------------------------------
+void LCDD_DrawString(
+ void *pBuffer,
+ unsigned int x,
+ unsigned int y,
+ const char *pString,
+ unsigned int color)
+{
+ unsigned xorg = x;
+
+ while (*pString != 0) {
+ if (*pString == '\n') {
+
+ y += gFont.height + 2;
+ x = xorg;
+ }
+ else {
+
+ LCDD_DrawChar(pBuffer, x, y, *pString, color);
+ x += gFont.width + 2;
+ }
+ pString++;
+ }
+}
+//------------------------------------------------------------------------------
+/// Draws a string inside a LCD buffer, at the given coordinates. Line breaks
+/// will be honored.
+/// \param pBuffer Buffer to draw on.
+/// \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.
+/// \param dir The dirciton of the string,0 for horizontal,1 for vertical
+//------------------------------------------------------------------------------
+void LCDD_DrawStringEx(
+ void *pBuffer,
+ unsigned int x,
+ unsigned int y,
+ const char *pString,
+ unsigned int color,
+ unsigned int dir)
+{
+ unsigned int xorg = x;
+ unsigned int yorg = y;
+
+ if(LCDD_IsBusy()) return;
+
+ gLCDIsBusy = 1;
+
+ if(dir)
+ {
+ while (*pString != 0) {
+ if (*pString == '\n') {
+
+ x -= gFont.height + 2;
+ y = yorg;
+
+ }
+ else {
+ LCDD_DrawCharVertical(pBuffer, x, y, *pString, color);
+ y += gFont.width + 2;
+ }
+ pString++;
+ }
+
+ }
+ else
+ {
+ while (*pString != 0) {
+ if (*pString == '\n') {
+
+ y += gFont.height + 2;
+ x = xorg;
+
+ }
+ else {
+ LCDD_DrawChar(pBuffer, x, y, *pString, color);
+ x += gFont.width + 2;
+ }
+ pString++;
+ }
+ }
+ gLCDIsBusy = 0;
+
+}
+//------------------------------------------------------------------------------
+/// Draws a string inside a LCD buffer, at the given coordinates. Line breaks
+/// will be honored.
+/// \param pBuffer Buffer to draw on.
+/// \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.
+//------------------------------------------------------------------------------
+void LCDD_DrawStringWithBGColor(
+ void *pBuffer,
+ unsigned int x,
+ unsigned int y,
+ const char *pString,
+ unsigned int fontColor,
+ unsigned int bgColor)
+{
+ unsigned xorg = x;
+
+ while (*pString != 0) {
+ if (*pString == '\n') {
+
+ y += gFont.height + 2;
+ x = xorg;
+ }
+ else {
+
+ LCDD_DrawCharWithBGColor(pBuffer, x, y, *pString, fontColor, bgColor);
+ x += gFont.width + 2;
+ }
+ pString++;
+ }
+}
+//------------------------------------------------------------------------------
+/// Draws a string inside a LCD buffer, at the given coordinates. Line breaks
+/// will be honored.
+/// \param pBuffer Buffer to draw on.
+/// \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.
+/// \param dir The dirciton of the string,0 for horizontal,1 for vertical
+//------------------------------------------------------------------------------
+void LCDD_DrawStringWithBGColorEx(
+ void *pBuffer,
+ unsigned int x,
+ unsigned int y,
+ const char *pString,
+ unsigned int fontColor,
+ unsigned int bgColor,
+ unsigned int dir)
+{
+ unsigned int xorg = x;
+ unsigned int yorg = y;
+
+ if(LCDD_IsBusy()) return;
+
+ gLCDIsBusy = 1;
+
+ if(dir)
+ {
+ while (*pString != 0) {
+ if (*pString == '\n') {
+
+ x -= gFont.height + 2;
+ y = yorg;
+
+ }
+ else {
+ LCDD_DrawCharVerticalWithBGColor(pBuffer, x, y, *pString, fontColor, bgColor);
+ y += gFont.width + 2;
+ }
+ pString++;
+ }
+ }
+ else
+ {
+ while (*pString != 0) {
+ if (*pString == '\n') {
+
+ y += gFont.height + 2;
+ x = xorg;
+
+ }
+ else {
+ LCDD_DrawCharWithBGColor(pBuffer, x, y, *pString, fontColor, bgColor);
+ x += gFont.width + 2;
+ }
+ pString++;
+ }
+
+ }
+
+ gLCDIsBusy = 0;
+
+}
+//------------------------------------------------------------------------------
+/// 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.
+//------------------------------------------------------------------------------
+void LCDD_GetStringSize(
+ const char *pString,
+ unsigned int *pWidth,
+ unsigned int *pHeight)
+{
+ unsigned int width = 0;
+ unsigned int 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) *pWidth = width;
+ if (pHeight) *pHeight = height;
+}
diff --git a/drivers/lcd/font.c b/drivers/lcd/font.c
new file mode 100644
index 0000000..843c669
--- /dev/null
+++ b/drivers/lcd/font.c
@@ -0,0 +1,209 @@
+/* ----------------------------------------------------------------------------
+ * 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 "font.h"
+#include "draw.h"
+#include "font10x14.h"
+#include <utility/assert.h>
+
+//------------------------------------------------------------------------------
+// Local variables
+//------------------------------------------------------------------------------
+
+/// Global variable describing the font being instancied.
+const Font gFont = {10, 14};
+
+//------------------------------------------------------------------------------
+// Global functions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// Draws an ASCII character on the given LCD buffer.
+/// \param pBuffer Buffer to write on.
+/// \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.
+//------------------------------------------------------------------------------
+void LCDD_DrawChar(
+ void *pBuffer,
+ unsigned int x,
+ unsigned int y,
+ char c,
+ unsigned int color)
+{
+ unsigned int row, col;
+
+ SANITY_CHECK((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(pBuffer, x+col, y+row, color);
+ }
+ }
+ for (row = 0; row < 6; row++) {
+
+ if ((pCharset10x14[((c - 0x20) * 20) + col * 2 + 1] >> (7 - row)) & 0x1) {
+
+ LCDD_DrawPixel(pBuffer, x+col, y+row+8, color);
+ }
+ }
+ }
+}
+//------------------------------------------------------------------------------
+/// Draws an ASCII character on the given LCD buffer with 90 degree clockwise rotate .
+/// \param pBuffer Buffer to write on.
+/// \param x X-coordinate of character upper-left corner, x decreasing by step.
+/// \param y Y-coordinate of character upper-left corner, y increasing by step.
+/// \param c Character to output.
+/// \param color Character color.
+//------------------------------------------------------------------------------
+void LCDD_DrawCharVertical(
+ void *pBuffer,
+ unsigned int x,
+ unsigned int y,
+ char c,
+ unsigned int color)
+{
+ unsigned int row, col;
+
+ SANITY_CHECK((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(pBuffer, x-row, y+col, color);
+ }
+ }
+ for (row = 0; row < 6; row++) {
+
+ if ((pCharset10x14[((c - 0x20) * 20) + col * 2 + 1] >> (7 - row)) & 0x1) {
+
+ LCDD_DrawPixel(pBuffer, x-row-8, y+col, color);
+ }
+ }
+ }
+}
+//------------------------------------------------------------------------------
+/// Draws an ASCII character on the given LCD buffer.
+/// \param pBuffer Buffer to write on.
+/// \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 foreground color.
+/// \param bgColor Background color of character
+//------------------------------------------------------------------------------
+void LCDD_DrawCharWithBGColor(
+ void *pBuffer,
+ unsigned int x,
+ unsigned int y,
+ char c,
+ unsigned int fontColor,
+ unsigned int bgColor)
+{
+ unsigned int row, col;
+
+ SANITY_CHECK((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(pBuffer, x+col, y+row, fontColor);
+ } else {
+ LCDD_DrawPixel(pBuffer, x+col, y+row, bgColor);
+ }
+ }
+ for (row = 0; row < 6; row++) {
+
+ if ((pCharset10x14[((c - 0x20) * 20) + col * 2 + 1] >> (7 - row)) & 0x1) {
+
+ LCDD_DrawPixel(pBuffer, x+col, y+row+8, fontColor);
+ } else {
+ LCDD_DrawPixel(pBuffer, x+col, y+row+8, bgColor);
+ }
+ }
+ }
+}
+//------------------------------------------------------------------------------
+/// Draws an ASCII character on the given LCD buffer ith 90 degree clockwise rotate.
+/// \param pBuffer Buffer to write on.
+/// \param x X-coordinate of character upper-left corner x decreasing by step.
+/// \param y Y-coordinate of character upper-left corner y increasing by step.
+/// \param c Character to output.
+/// \param fontColor Character foreground color.
+/// \param bgColor Background color of character
+//------------------------------------------------------------------------------
+void LCDD_DrawCharVerticalWithBGColor(
+ void *pBuffer,
+ unsigned int x,
+ unsigned int y,
+ char c,
+ unsigned int fontColor,
+ unsigned int bgColor)
+{
+ unsigned int row, col;
+
+ SANITY_CHECK((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(pBuffer, x-row, y+col, fontColor);
+ } else {
+ LCDD_DrawPixel(pBuffer, x-row, y+col, bgColor);
+ }
+ }
+ for (row = 0; row < 6; row++) {
+
+ if ((pCharset10x14[((c - 0x20) * 20) + col * 2 + 1] >> (7 - row)) & 0x1) {
+
+ LCDD_DrawPixel(pBuffer, x-row-8, y+col, fontColor);
+ } else {
+ LCDD_DrawPixel(pBuffer, x-row-8, y+col, bgColor);
+ }
+ }
+ }
+}
diff --git a/drivers/lcd/font.h b/drivers/lcd/font.h
new file mode 100644
index 0000000..2576de6
--- /dev/null
+++ b/drivers/lcd/font.h
@@ -0,0 +1,112 @@
+/* ----------------------------------------------------------------------------
+ * 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.
+ * ----------------------------------------------------------------------------
+ */
+
+//------------------------------------------------------------------------------
+/// \unit
+///
+/// !!!Purpose
+///
+/// The font.h files declares a font structure and a LCDD_DrawChar function
+/// that must be implemented by a font definition file to be used with the
+/// LCDD_DrawString method of draw.h.
+///
+/// The font10x14.c implements the necessary variable and function for a 10x14
+/// font.
+///
+/// !!!Usage
+///
+/// -# Declare a gFont global variable with the necessary Font information.
+/// -# Implement an LCDD_DrawChar function which displays the specified
+/// character on the LCD.
+/// -# Use the LCDD_DrawString method defined in draw.h to display a complete
+/// string.
+//------------------------------------------------------------------------------
+
+#ifndef FONT_H
+#define FONT_H
+
+//------------------------------------------------------------------------------
+// Global types
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// Describes the font (width, height, supported characters, etc.) used by
+/// the LCD driver draw API.
+//------------------------------------------------------------------------------
+typedef struct _Font {
+
+ /// Font width in pixels.
+ unsigned char width;
+ /// Font height in pixels.
+ unsigned char height;
+
+} Font;
+
+//------------------------------------------------------------------------------
+// Global variables
+//------------------------------------------------------------------------------
+
+/// Global variable describing the font being instancied.
+extern const Font gFont;
+
+//------------------------------------------------------------------------------
+// Global functions
+//------------------------------------------------------------------------------
+
+extern void LCDD_DrawChar(
+ void *pBuffer,
+ unsigned int x,
+ unsigned int y,
+ char c,
+ unsigned int color);
+
+extern void LCDD_DrawCharVertical(
+ void *pBuffer,
+ unsigned int x,
+ unsigned int y,
+ char c,
+ unsigned int color);
+
+extern void LCDD_DrawCharWithBGColor(
+ void *pBuffer,
+ unsigned int x,
+ unsigned int y,
+ char c,
+ unsigned int fontColor,
+ unsigned int bgColor);
+
+extern void LCDD_DrawCharVerticalWithBGColor(
+ void *pBuffer,
+ unsigned int x,
+ unsigned int y,
+ char c,
+ unsigned int fontColor,
+ unsigned int bgColor);
+
+#endif //#ifndef FONT_H
diff --git a/drivers/lcd/font10x14.h b/drivers/lcd/font10x14.h
new file mode 100644
index 0000000..b86612a
--- /dev/null
+++ b/drivers/lcd/font10x14.h
@@ -0,0 +1,237 @@
+/* ----------------------------------------------------------------------------
+ * 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.
+ * ----------------------------------------------------------------------------
+ */
+
+#ifndef LCD_FONT_10x14_H
+#define LCD_FONT_10x14_H
+
+//------------------------------------------------------------------------------
+// Headers
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+// Definitions
+//------------------------------------------------------------------------------
+
+const unsigned char 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
+};
+
+
+#endif // #ifdef _LCD_FONT_10x14_h
diff --git a/drivers/lcd/lcd.dir b/drivers/lcd/lcd.dir
new file mode 100644
index 0000000..260d5ea
--- /dev/null
+++ b/drivers/lcd/lcd.dir
@@ -0,0 +1,39 @@
+/* ----------------------------------------------------------------------------
+ * 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.
+ * ----------------------------------------------------------------------------
+ */
+
+//------------------------------------------------------------------------------
+/// \dir
+///
+/// !!!Contents
+///
+/// This directory contains the source code for the LCD driver in lcd.h. In
+/// addition, several drawing function are provided by draw.h. A font system is
+/// also defined in font.h. Now supports two types of lcd controller:
+/// peripheral LCDC and and HX8347 LCDC.
+//------------------------------------------------------------------------------
diff --git a/drivers/lcd/lcdd.c b/drivers/lcd/lcdd.c
new file mode 100644
index 0000000..efb14ed
--- /dev/null
+++ b/drivers/lcd/lcdd.c
@@ -0,0 +1,138 @@
+/* ----------------------------------------------------------------------------
+ * 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 "lcdd.h"
+#include <board.h>
+#include <lcd/lcd.h>
+#include <pio/pio.h>
+
+//------------------------------------------------------------------------------
+// Global functions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// Initializes the LCD controller using the board-specific parameters (stored
+/// in the corresponding board.h). The LCD and DMA are not enabled by this
+/// function; this is done during the first call to LCDD_DisplayBuffer.
+//------------------------------------------------------------------------------
+void LCDD_Initialize(void)
+{
+ const Pin pPins[] = {PINS_LCD};
+
+ // Enable pins
+ PIO_Configure(pPins, PIO_LISTSIZE(pPins));
+
+ // Enable peripheral clock
+ AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_LCDC;
+
+#if defined(at91sam9g10)||defined(at91sam9261)
+ AT91C_BASE_PMC->PMC_SCER = AT91C_PMC_HCK1;
+#endif
+
+ // Disable the LCD and the DMA
+ LCD_DisableDma();
+ LCD_Disable(0);
+
+ // Configure the LCD controller
+ LCD_SetPixelClock(BOARD_MCK, BOARD_LCD_PIXELCLOCK);
+ LCD_SetDisplayType(BOARD_LCD_DISPLAYTYPE);
+ LCD_SetScanMode(AT91C_LCDC_SCANMOD_SINGLESCAN);
+ LCD_SetBitsPerPixel(BOARD_LCD_BPP);
+ LCD_SetPolarities(BOARD_LCD_POLARITY_INVVD,
+ BOARD_LCD_POLARITY_INVFRAME,
+ BOARD_LCD_POLARITY_INVLINE,
+ BOARD_LCD_POLARITY_INVCLK,
+ BOARD_LCD_POLARITY_INVDVAL);
+ LCD_SetClockMode(BOARD_LCD_CLOCKMODE);
+ LCD_SetMemoryFormat((unsigned int) AT91C_LCDC_MEMOR_LITTLEIND);
+ LCD_SetSize(BOARD_LCD_WIDTH, BOARD_LCD_HEIGHT);
+
+ // Configure timings
+ LCD_SetVerticalTimings(BOARD_LCD_TIMING_VFP,
+ BOARD_LCD_TIMING_VBP,
+ BOARD_LCD_TIMING_VPW,
+ BOARD_LCD_TIMING_VHDLY);
+ LCD_SetHorizontalTimings(BOARD_LCD_TIMING_HBP,
+ BOARD_LCD_TIMING_HPW,
+ BOARD_LCD_TIMING_HFP);
+
+ // Configure contrast (TODO functions)
+ LCD_SetContrastPrescaler(AT91C_LCDC_PS_NOTDIVIDED);
+ LCD_SetContrastPolarity(AT91C_LCDC_POL_POSITIVEPULSE);
+ LCD_SetContrastValue(0x80);
+ LCD_EnableContrast();
+
+ // Configure DMA
+ LCD_SetFrameSize(BOARD_LCD_FRAMESIZE);
+ LCD_SetBurstLength(4);
+}
+
+//------------------------------------------------------------------------------
+/// Displays the contents of the provided buffer on the LCD. The buffer is
+/// provided as-is to the LCD DMA and is not copied.
+/// If the LCD and DMA are not yet enabled, this function enables them.
+/// \param pBuffer Buffer to display.
+/// \return The address of the previously displayed buffer.
+//------------------------------------------------------------------------------
+void * LCDD_DisplayBuffer(void *pBuffer)
+{
+ void *pOldBuffer;
+
+ pOldBuffer = LCD_SetFrameBufferAddress(pBuffer);
+
+ // Enable LCD & DMA if needed
+ if ((AT91C_BASE_LCDC->LCDC_DMACON & AT91C_LCDC_DMAEN) != AT91C_LCDC_DMAEN) {
+
+ LCD_EnableDma();
+ LCD_Enable(0x0C);
+ }
+
+ return pOldBuffer;
+}
+
+//------------------------------------------------------------------------------
+/// Shutdown the LCD
+//------------------------------------------------------------------------------
+void LCDD_Stop(void)
+{
+ // Enable peripheral clock
+ AT91C_BASE_PMC->PMC_PCDR = 1 << AT91C_ID_LCDC;
+
+#if defined(at91sam9g10)||defined(at91sam9261)
+ AT91C_BASE_PMC->PMC_SCDR = AT91C_PMC_HCK1;
+#endif
+
+ // Disable the LCD and the DMA
+ LCD_DisableDma();
+ LCD_Disable(0);
+}
diff --git a/drivers/lcd/lcdd.h b/drivers/lcd/lcdd.h
new file mode 100644
index 0000000..27da073
--- /dev/null
+++ b/drivers/lcd/lcdd.h
@@ -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.
+ * ----------------------------------------------------------------------------
+ */
+
+//------------------------------------------------------------------------------
+/// \unit
+///
+/// !!!Purpose
+///
+/// Simple driver for the LCD, which takes care of the initialization.
+///
+/// !!!Usage
+///
+/// -# Call LCDD_Initialize to configure the LCD controller.
+/// -# Set the buffer displayed by the LCD with LCDD_DisplayBuffer if using
+/// peripheral LCDC, or start displaying with LCDD_Start if using HX8347.
+//------------------------------------------------------------------------------
+
+#ifndef LCDD_H
+#define LCDD_H
+
+//------------------------------------------------------------------------------
+// Global functions
+//------------------------------------------------------------------------------
+
+extern void LCDD_Initialize(void); // For peripheral LCDC & HX8347
+
+extern void * LCDD_DisplayBuffer(void *pBuffer); // For peripheral LCDC only
+
+extern void LCDD_Start(void); // For HX8347 only
+
+extern void LCDD_Stop(void); // For peripheral LCDC & HX8347
+
+extern void LCDD_SetBacklight (unsigned int step); // For peripheral LCDC only
+
+#endif //#ifndef LCDD_H
diff --git a/drivers/lcd/lcdd_hx8347.c b/drivers/lcd/lcdd_hx8347.c
new file mode 100644
index 0000000..e5871ad
--- /dev/null
+++ b/drivers/lcd/lcdd_hx8347.c
@@ -0,0 +1,147 @@
+/* ----------------------------------------------------------------------------
+ * 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 "lcdd.h"
+
+#include <board.h>
+#include <pmc/pmc.h>
+#include <hx8347/hx8347.h>
+#include <pio/pio.h>
+
+//------------------------------------------------------------------------------
+// Global functions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// Initializes the LCD controller.
+/// SMC are configured @ 96MHz for LCD.
+/// \param pLcdBase LCD base address.
+//------------------------------------------------------------------------------
+void LCDD_Initialize(void)
+{
+ const Pin pPins[] = {BOARD_LCD_PINS};
+ AT91PS_HSMC4_CS pSMC = AT91C_BASE_HSMC4_CS2;
+ unsigned int rMode;
+
+ // Enable pins
+ PIO_Configure(pPins, PIO_LISTSIZE(pPins));
+
+ // Enable peripheral clock
+ PMC_EnablePeripheral(AT91C_ID_HSMC4);
+
+ // EBI SMC Configuration
+ pSMC->HSMC4_SETUP = 0
+ | ((1 << 0) & AT91C_HSMC4_NWE_SETUP)
+ | ((1 << 8) & AT91C_HSMC4_NCS_WR_SETUP)
+ | ((9 << 16) & AT91C_HSMC4_NRD_SETUP)
+ | ((9 << 24) & AT91C_HSMC4_NCS_RD_SETUP)
+ ;
+
+ pSMC->HSMC4_PULSE = 0
+ | (( 4 << 0) & AT91C_HSMC4_NWE_PULSE)
+ | (( 4 << 8) & AT91C_HSMC4_NCS_WR_PULSE)
+ | (( 36 << 16) & AT91C_HSMC4_NRD_PULSE)
+ | (( 36 << 24) & AT91C_HSMC4_NCS_RD_PULSE)
+ ;
+
+ pSMC->HSMC4_CYCLE = 0
+ | ((10 << 0) & AT91C_HSMC4_NWE_CYCLE)
+ | ((45 << 16) & AT91C_HSMC4_NRD_CYCLE)
+ ;
+
+ rMode = pSMC->HSMC4_MODE & ~(AT91C_HSMC4_DBW | AT91C_HSMC4_READ_MODE | AT91C_HSMC4_WRITE_MODE);
+ pSMC->HSMC4_MODE = rMode
+ | (AT91C_HSMC4_READ_MODE)
+ | (AT91C_HSMC4_WRITE_MODE)
+ | (AT91C_HSMC4_DBW_WIDTH_SIXTEEN_BITS)
+ ;
+
+ // Initialize LCD controller (HX8347)
+ LCD_Initialize((void *)BOARD_LCD_BASE);
+
+ // Set LCD backlight
+ LCDD_SetBacklight(25);
+}
+
+//------------------------------------------------------------------------------
+/// Turn on the LCD
+//------------------------------------------------------------------------------
+void LCDD_Start(void)
+{
+ LCD_On((void *)BOARD_LCD_BASE);
+}
+
+//------------------------------------------------------------------------------
+/// Turn off the LCD
+//------------------------------------------------------------------------------
+void LCDD_Stop(void)
+{
+ LCD_Off((void *)BOARD_LCD_BASE);
+}
+
+//------------------------------------------------------------------------------
+/// Set the backlight of the LCD.
+/// \param level Backlight brightness level [1..32], 32 is maximum level.
+//------------------------------------------------------------------------------
+void LCDD_SetBacklight (unsigned int level)
+{
+ unsigned int i;
+ const Pin pPins[] = {BOARD_BACKLIGHT_PIN};
+
+ // 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);
+
+// PIO_Clear(pPins);
+// PIO_Clear(pPins);
+// PIO_Clear(pPins);
+ }
+// PIO_Set(pPins);
+}
diff --git a/drivers/macb/macb.c b/drivers/macb/macb.c
new file mode 100644
index 0000000..0f387dd
--- /dev/null
+++ b/drivers/macb/macb.c
@@ -0,0 +1,569 @@
+/* ----------------------------------------------------------------------------
+ * 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.
+ * ----------------------------------------------------------------------------
+ */
+
+// drivers/macb/macb.c
+
+//-----------------------------------------------------------------------------
+// Headers
+//-----------------------------------------------------------------------------
+#include "macb.h"
+#include "mii.h"
+#include <pio/pio.h>
+#include <rstc/rstc.h>
+#include <emac/emac.h>
+#include <utility/trace.h>
+#include <utility/assert.h>
+
+//-----------------------------------------------------------------------------
+// Definitions
+//-----------------------------------------------------------------------------
+
+/// Default max retry count
+#define MACB_RETRY_MAX 1000000
+
+//-----------------------------------------------------------------------------
+/// Dump all the useful registers
+/// \param pMacb Pointer to the MACB instance
+//-----------------------------------------------------------------------------
+static void MACB_DumpRegisters(Macb *pMacb)
+{
+ unsigned char phyAddress;
+ unsigned int retryMax;
+ unsigned int value;
+
+ TRACE_INFO("MACB_DumpRegisters\n\r");
+ ASSERT(pMacb, "F: MACB_DumpRegisters\n\r");
+
+ EMAC_EnableMdio();
+ phyAddress = pMacb->phyAddress;
+ retryMax = pMacb->retryMax;
+
+ TRACE_INFO("MII MACB @%d) Registers:\n\r", phyAddress);
+
+ EMAC_ReadPhy(phyAddress, MII_BMCR, &value, retryMax);
+ TRACE_INFO(" _BMCR : 0x%X\n\r", value);
+ EMAC_ReadPhy(phyAddress, MII_BMSR, &value, retryMax);
+ TRACE_INFO(" _BMSR : 0x%X\n\r", value);
+ EMAC_ReadPhy(phyAddress, MII_ANAR, &value, retryMax);
+ TRACE_INFO(" _ANAR : 0x%X\n\r", value);
+ EMAC_ReadPhy(phyAddress, MII_ANLPAR, &value, retryMax);
+ TRACE_INFO(" _ANLPAR : 0x%X\n\r", value);
+ EMAC_ReadPhy(phyAddress, MII_ANER, &value, retryMax);
+ TRACE_INFO(" _ANER : 0x%X\n\r", value);
+ EMAC_ReadPhy(phyAddress, MII_DSCR, &value, retryMax);
+ TRACE_INFO(" _DSCR : 0x%X\n\r", value);
+ EMAC_ReadPhy(phyAddress, MII_DSCSR, &value, retryMax);
+ TRACE_INFO(" _DSCSR : 0x%X\n\r", value);
+ EMAC_ReadPhy(phyAddress, MII_10BTCSR, &value, retryMax);
+ TRACE_INFO(" _10BTCSR: 0x%X\n\r", value);
+ EMAC_ReadPhy(phyAddress, MII_PWDOR, &value, retryMax);
+ TRACE_INFO(" _PWDOR : 0x%X\n\r", value);
+ EMAC_ReadPhy(phyAddress, MII_CONFIGR, &value, retryMax);
+ TRACE_INFO(" _CONFIGR: 0x%X\n\r", value);
+ EMAC_ReadPhy(phyAddress, MII_MDINTR, &value, retryMax);
+ TRACE_INFO(" _MDINTR : 0x%X\n\r", value);
+ EMAC_ReadPhy(phyAddress, MII_RECR, &value, retryMax);
+ TRACE_INFO(" _RECR : 0x%X\n\r", value);
+ EMAC_ReadPhy(phyAddress, MII_DISCR, &value, retryMax);
+ TRACE_INFO(" _DISCR : 0x%X\n\r", value);
+ EMAC_ReadPhy(phyAddress, MII_RLSR, &value, retryMax);
+ TRACE_INFO(" _RLSR : 0x%X\n\r", value);
+
+ EMAC_DisableMdio();
+}
+
+//-----------------------------------------------------------------------------
+/// Find a valid PHY Address ( from 0 to 31 ).
+/// Check BMSR register ( not 0 nor 0xFFFF )
+/// Return 0xFF when no valid PHY Address found.
+/// \param pMacb Pointer to the MACB instance
+//-----------------------------------------------------------------------------
+static unsigned char MACB_FindValidPhy(Macb *pMacb)
+{
+ unsigned int retryMax;
+ unsigned int value=0;
+ unsigned char rc;
+ unsigned char phyAddress;
+ unsigned char cnt;
+
+ TRACE_DEBUG("MACB_FindValidPhy\n\r");
+ ASSERT(pMacb, "F: MACB_FindValidPhy\n\r");
+
+ EMAC_EnableMdio();
+ phyAddress = pMacb->phyAddress;
+ retryMax = pMacb->retryMax;
+
+ // Check current phyAddress
+ rc = phyAddress;
+ if( EMAC_ReadPhy(phyAddress, MII_PHYID1, &value, retryMax) == 0 ) {
+ TRACE_ERROR("MACB PROBLEM\n\r");
+ }
+ TRACE_DEBUG("_PHYID1 : 0x%X, addr: %d\n\r", value, phyAddress);
+
+ // Find another one
+ if (value != MII_OUI_MSB) {
+
+ rc = 0xFF;
+ for(cnt = 0; cnt < 32; cnt ++) {
+
+ phyAddress = (phyAddress + 1) & 0x1F;
+ if( EMAC_ReadPhy(phyAddress, MII_PHYID1, &value, retryMax) == 0 ) {
+ TRACE_ERROR("MACB PROBLEM\n\r");
+ }
+ TRACE_DEBUG("_PHYID1 : 0x%X, addr: %d\n\r", value, phyAddress);
+ if (value == MII_OUI_MSB) {
+
+ rc = phyAddress;
+ break;
+ }
+ }
+ }
+
+ EMAC_DisableMdio();
+ if (rc != 0xFF) {
+
+ TRACE_INFO("** Valid PHY Found: %d\n\r", rc);
+ EMAC_ReadPhy(phyAddress, MII_DSCSR, &value, retryMax);
+ TRACE_DEBUG("_DSCSR : 0x%X, addr: %d\n\r", value, phyAddress);
+
+ }
+ return rc;
+}
+
+
+//-----------------------------------------------------------------------------
+// Exported functions
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+/// Setup the maximum timeout count of the driver.
+/// \param pMacb Pointer to the MACB instance
+/// \param toMax Timeout maxmum count.
+//-----------------------------------------------------------------------------
+void MACB_SetupTimeout(Macb *pMacb, unsigned int toMax)
+{
+ ASSERT(pMacb, "-F- MACB_SetupTimeout\n\r");
+
+ pMacb->retryMax = toMax;
+}
+
+//-----------------------------------------------------------------------------
+/// Initialize the MACB instance
+/// \param pMacb Pointer to the MACB instance
+/// \param pEmac Pointer to the Emac instance for the MACB
+/// \param phyAddress The PHY address used to access the PHY
+/// ( pre-defined by pin status on PHY reset )
+//-----------------------------------------------------------------------------
+void MACB_Init(Macb *pMacb, unsigned char phyAddress)
+{
+ ASSERT(pMacb , "-F- MACB_Init\n\r");
+
+ pMacb->phyAddress = phyAddress;
+
+ // Initialize timeout by default
+ pMacb->retryMax = MACB_RETRY_MAX;
+}
+
+
+//-----------------------------------------------------------------------------
+/// Issue a SW reset to reset all registers of the PHY
+/// Return 1 if successfully, 0 if timeout.
+/// \param pMacb Pointer to the MACB instance
+//-----------------------------------------------------------------------------
+static unsigned char MACB_ResetPhy(Macb *pMacb)
+{
+ unsigned int retryMax;
+ unsigned int bmcr = MII_RESET;
+ unsigned char phyAddress;
+ unsigned int timeout = 10;
+ unsigned char ret = 1;
+
+ ASSERT(pMacb, "-F- MACB_ResetPhy");
+ TRACE_INFO(" MACB_ResetPhy\n\r");
+
+ phyAddress = pMacb->phyAddress;
+ retryMax = pMacb->retryMax;
+
+ EMAC_EnableMdio();
+ bmcr = MII_RESET;
+ EMAC_WritePhy(phyAddress, MII_BMCR, bmcr, retryMax);
+
+ do {
+ EMAC_ReadPhy(phyAddress, MII_BMCR, &bmcr, retryMax);
+ timeout--;
+ } while ((bmcr & MII_RESET) && timeout);
+
+ EMAC_DisableMdio();
+
+ if (!timeout) {
+ ret = 0;
+ }
+
+ return( ret );
+}
+
+//-----------------------------------------------------------------------------
+/// Do a HW initialize to the PHY ( via RSTC ) and setup clocks & PIOs
+/// This should be called only once to initialize the PHY pre-settings.
+/// The PHY address is reset status of CRS,RXD[3:0] (the emacPins' pullups).
+/// The COL pin is used to select MII mode on reset (pulled up for Reduced MII)
+/// The RXDV pin is used to select test mode on reset (pulled up for test mode)
+/// The above pins should be predefined for corresponding settings in resetPins
+/// The EMAC peripheral pins are configured after the reset done.
+/// Return 1 if RESET OK, 0 if timeout.
+/// \param pMacb Pointer to the MACB instance
+/// \param mck Main clock setting to initialize clock
+/// \param resetPins Pointer to list of PIOs to configure before HW RESET
+/// (for PHY power on reset configuration latch)
+/// \param nbResetPins Number of PIO items that should be configured
+/// \param emacPins Pointer to list of PIOs for the EMAC interface
+/// \param nbEmacPins Number of PIO items that should be configured
+//-----------------------------------------------------------------------------
+
+unsigned char MACB_InitPhy(Macb *pMacb,
+ unsigned int mck,
+ const Pin *pResetPins,
+ unsigned int nbResetPins,
+ const Pin *pEmacPins,
+ unsigned int nbEmacPins)
+{
+ unsigned char rc = 1;
+ unsigned char phy;
+ volatile unsigned int i;
+
+ ASSERT(pMacb, "-F- MACB_InitPhy\n\r");
+
+ // Perform RESET
+ TRACE_DEBUG("RESET PHY\n\r");
+
+ if (pResetPins) {
+
+ // Configure PINS
+ PIO_Configure(pResetPins, nbResetPins);
+
+#if !defined(BOARD_EMAC_RESET)
+ // Execute reset
+ RSTC_SetExtResetLength(MACB_RESET_LENGTH);
+ RSTC_ExtReset();
+ // Get NRST level
+ printf("NRST level %d\n\r", RSTC_GetNrstLevel());
+ // Wait for end hardware reset
+ while (!RSTC_GetNrstLevel());
+#else
+ int i=0;
+ const Pin nrstPin = BOARD_EMAC_RESET;
+ PIO_Configure(&nrstPin, 1);
+ for(i=0;i<100000;i++) {
+ PIO_Clear(&nrstPin);
+ }
+ PIO_Set(&nrstPin);
+#endif
+ }
+
+ // Configure EMAC runtime pins
+ if (rc) {
+
+ PIO_Configure(pEmacPins, nbEmacPins);
+ rc = EMAC_SetMdcClock( mck );
+ if (!rc) {
+
+ TRACE_ERROR("No Valid MDC clock\n\r");
+ return 0;
+ }
+
+ // Check PHY Address
+ phy = MACB_FindValidPhy(pMacb);
+ if (phy == 0xFF) {
+
+ TRACE_ERROR("PHY Access fail\n\r");
+ return 0;
+ }
+ if(phy != pMacb->phyAddress) {
+
+ pMacb->phyAddress = phy;
+
+ MACB_ResetPhy(pMacb);
+
+ }
+
+ }
+ else {
+
+ TRACE_ERROR("PHY Reset Timeout\n\r");
+ }
+
+ return rc;
+}
+
+//-----------------------------------------------------------------------------
+/// Issue a Auto Negotiation of the PHY
+/// Return 1 if successfully, 0 if timeout.
+/// \param pMacb Pointer to the MACB instance
+//-----------------------------------------------------------------------------
+unsigned char MACB_AutoNegotiate(Macb *pMacb)
+{
+ unsigned int retryMax;
+ unsigned int value;
+ unsigned int phyAnar;
+ unsigned int phyAnalpar;
+ unsigned int retryCount= 0;
+ unsigned char phyAddress;
+ unsigned char rc = 1;
+
+ ASSERT(pMacb, "-F- MACB_AutoNegotiate\n\r");
+ phyAddress = pMacb->phyAddress;
+ retryMax = pMacb->retryMax;
+
+ EMAC_EnableMdio();
+
+ if (!EMAC_ReadPhy(phyAddress, MII_PHYID1, &value, retryMax)) {
+ TRACE_ERROR("Pb EMAC_ReadPhy Id1\n\r");
+ rc = 0;
+ goto AutoNegotiateExit;
+ }
+ TRACE_DEBUG("ReadPhy Id1 0x%X, addresse: %d\n\r", value, phyAddress);
+ if (!EMAC_ReadPhy(phyAddress, MII_PHYID2, &phyAnar, retryMax)) {
+ TRACE_ERROR("Pb EMAC_ReadPhy Id2\n\r");
+ rc = 0;
+ goto AutoNegotiateExit;
+ }
+ TRACE_DEBUG("ReadPhy Id2 0x%X\n\r", phyAnar);
+
+ if( ( value == MII_OUI_MSB )
+ && ( ((phyAnar>>10)&MII_LSB_MASK) == MII_OUI_LSB ) ) {
+
+ TRACE_DEBUG("Vendor Number Model = 0x%X\n\r", ((phyAnar>>4)&0x3F));
+ TRACE_DEBUG("Model Revision Number = 0x%X\n\r", (phyAnar&0x7));
+ }
+ else {
+ TRACE_ERROR("Problem OUI value\n\r");
+ }
+
+ // Setup control register
+ rc = EMAC_ReadPhy(phyAddress, MII_BMCR, &value, retryMax);
+ if (rc == 0) {
+
+ goto AutoNegotiateExit;
+ }
+
+ value &= ~MII_AUTONEG; // Remove autonegotiation enable
+ value &= ~(MII_LOOPBACK|MII_POWER_DOWN);
+ value |= MII_ISOLATE; // Electrically isolate PHY
+ rc = EMAC_WritePhy(phyAddress, MII_BMCR, value, retryMax);
+ if (rc == 0) {
+
+ goto AutoNegotiateExit;
+ }
+
+ // Set the Auto_negotiation Advertisement Register
+ // MII advertising for Next page
+ // 100BaseTxFD and HD, 10BaseTFD and HD, IEEE 802.3
+ phyAnar = MII_TX_FDX | MII_TX_HDX |
+ MII_10_FDX | MII_10_HDX | MII_AN_IEEE_802_3;
+ rc = EMAC_WritePhy(phyAddress, MII_ANAR, phyAnar, retryMax);
+ if (rc == 0) {
+
+ goto AutoNegotiateExit;
+ }
+
+ // Read & modify control register
+ rc = EMAC_ReadPhy(phyAddress, MII_BMCR, &value, retryMax);
+ if (rc == 0) {
+
+ goto AutoNegotiateExit;
+ }
+
+ value |= MII_SPEED_SELECT | MII_AUTONEG | MII_DUPLEX_MODE;
+ rc = EMAC_WritePhy(phyAddress, MII_BMCR, value, retryMax);
+ if (rc == 0) {
+
+ goto AutoNegotiateExit;
+ }
+
+ // Restart Auto_negotiation
+ value |= MII_RESTART_AUTONEG;
+ value &= ~MII_ISOLATE;
+ rc = EMAC_WritePhy(phyAddress, MII_BMCR, value, retryMax);
+ if (rc == 0) {
+
+ goto AutoNegotiateExit;
+ }
+ TRACE_DEBUG(" _BMCR: 0x%X\n\r", value);
+
+ // Check AutoNegotiate complete
+ while (1) {
+
+ rc = EMAC_ReadPhy(phyAddress, MII_BMSR, &value, retryMax);
+ if (rc == 0) {
+
+ TRACE_ERROR("rc==0\n\r");
+ goto AutoNegotiateExit;
+ }
+ // Done successfully
+ if (value & MII_AUTONEG_COMP) {
+
+ TRACE_INFO("AutoNegotiate complete\n\r");
+ break;
+ }
+ // Timeout check
+ if (retryMax) {
+
+ if (++ retryCount >= retryMax) {
+
+ MACB_DumpRegisters(pMacb);
+ TRACE_ERROR("TimeOut\n\r");
+ rc = 0;
+ goto AutoNegotiateExit;
+ }
+ }
+ }
+
+ // Get the AutoNeg Link partner base page
+ rc = EMAC_ReadPhy(phyAddress, MII_ANLPAR, &phyAnalpar, retryMax);
+ if (rc == 0) {
+
+ goto AutoNegotiateExit;
+ }
+
+ // Setup the EMAC link speed
+ if ((phyAnar & phyAnalpar) & MII_TX_FDX) {
+
+ // set MII for 100BaseTX and Full Duplex
+ EMAC_SetLinkSpeed(1, 1);
+ }
+ else if ((phyAnar & phyAnalpar) & MII_10_FDX) {
+
+ // set MII for 10BaseT and Full Duplex
+ EMAC_SetLinkSpeed(0, 1);
+ }
+ else if ((phyAnar & phyAnalpar) & MII_TX_HDX) {
+
+ // set MII for 100BaseTX and half Duplex
+ EMAC_SetLinkSpeed(1, 0);
+ }
+ else if ((phyAnar & phyAnalpar) & MII_10_HDX) {
+
+ // set MII for 10BaseT and half Duplex
+ EMAC_SetLinkSpeed(0, 0);
+ }
+
+ // Setup EMAC mode
+#if (BOARD_EMAC_MODE_RMII != 1)
+ EMAC_EnableMII();
+#else
+ EMAC_EnableRMII();
+#endif
+
+AutoNegotiateExit:
+ EMAC_DisableMdio();
+ return rc;
+}
+
+//-----------------------------------------------------------------------------
+/// Get the Link & speed settings, and automatically setup the EMAC with the
+/// settings.
+/// Return 1 if link found, 0 if no ethernet link.
+/// \param pMacb Pointer to the MACB instance
+/// \param applySetting Apply the settings to EMAC interface
+//-----------------------------------------------------------------------------
+unsigned char MACB_GetLinkSpeed(Macb *pMacb, unsigned char applySetting)
+{
+ unsigned int retryMax;
+ unsigned int stat1;
+ unsigned int stat2;
+ unsigned char phyAddress;
+ unsigned char rc = 1;
+
+ TRACE_DEBUG("MACB_GetLinkSpeed\n\r");
+ ASSERT(pMacb, "-F- MACB_GetLinkSpeed\n\r");
+
+ EMAC_EnableMdio();
+ phyAddress = pMacb->phyAddress;
+ retryMax = pMacb->retryMax;
+
+ rc = EMAC_ReadPhy(phyAddress, MII_BMSR, &stat1, retryMax);
+ if (rc == 0) {
+
+ goto GetLinkSpeedExit;
+ }
+
+ if ((stat1 & MII_LINK_STATUS) == 0) {
+
+ TRACE_ERROR("Pb: LinkStat: 0x%x\n\r", stat1);
+
+ rc = 0;
+ goto GetLinkSpeedExit;
+ }
+
+ if (applySetting == 0) {
+
+ TRACE_ERROR("Pb: applySetting: 0x%x\n\r", applySetting);
+ goto GetLinkSpeedExit;
+ }
+
+ // Re-configure Link speed
+ rc = EMAC_ReadPhy(phyAddress, MII_DSCSR, &stat2, retryMax);
+ if (rc == 0) {
+
+ TRACE_ERROR("Pb: rc: 0x%x\n\r", rc);
+ goto GetLinkSpeedExit;
+ }
+
+ if ((stat1 & MII_100BASE_TX_FD) && (stat2 & MII_100FDX)) {
+
+ // set Emac for 100BaseTX and Full Duplex
+ EMAC_SetLinkSpeed(1, 1);
+ }
+
+ if ((stat1 & MII_10BASE_T_FD) && (stat2 & MII_10FDX)) {
+
+ // set MII for 10BaseT and Full Duplex
+ EMAC_SetLinkSpeed(0, 1);
+ }
+
+ if ((stat1 & MII_100BASE_T4_HD) && (stat2 & MII_100HDX)) {
+
+ // set MII for 100BaseTX and Half Duplex
+ EMAC_SetLinkSpeed(1, 0);
+ }
+
+ if ((stat1 & MII_10BASE_T_HD) && (stat2 & MII_10HDX)) {
+
+ // set MII for 10BaseT and Half Duplex
+ EMAC_SetLinkSpeed(0, 0);
+ }
+
+ // Start the EMAC transfers
+ TRACE_DEBUG("MACB_GetLinkSpeed passed\n\r");
+
+GetLinkSpeedExit:
+ EMAC_DisableMdio();
+ return rc;
+}
+
diff --git a/drivers/macb/macb.dir b/drivers/macb/macb.dir
new file mode 100644
index 0000000..708cf7f
--- /dev/null
+++ b/drivers/macb/macb.dir
@@ -0,0 +1,42 @@
+/* ----------------------------------------------------------------------------
+ * 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.
+ * ----------------------------------------------------------------------------
+ */
+
+//------------------------------------------------------------------------------
+/// \dir
+/// !Purpose
+///
+/// Definition of methods and structures for using PHY DM9161
+///
+/// !Usage
+///
+//-----------------------------------------------------------------------------
+///
+///
+//------------------------------------------------------------------------------
+
diff --git a/drivers/macb/macb.h b/drivers/macb/macb.h
new file mode 100644
index 0000000..13741a3
--- /dev/null
+++ b/drivers/macb/macb.h
@@ -0,0 +1,106 @@
+/* ----------------------------------------------------------------------------
+ * 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.
+ * ----------------------------------------------------------------------------
+ */
+
+//-----------------------------------------------------------------------------
+/// \unit
+///
+/// !Purpose
+///
+/// Implementation of MACB driver
+///
+/// !Contents
+///
+/// Please refer to the list of functions in the #Overview# tab of this unit
+/// for more detailed information.
+//-----------------------------------------------------------------------------
+
+
+// drivers/macb/macb.h
+
+#ifndef _MACB_H
+#define _MACB_H
+
+//-----------------------------------------------------------------------------
+// Headers
+//-----------------------------------------------------------------------------
+#include <pio/pio.h>
+
+//-----------------------------------------------------------------------------
+// Definitions
+//-----------------------------------------------------------------------------
+
+/// The reset length setting for external reset configuration
+#define MACB_RESET_LENGTH 0xD
+
+//-----------------------------------------------------------------------------
+// Types
+//-----------------------------------------------------------------------------
+
+/// The DM9161 instance
+typedef struct _Macb {
+
+ /// The retry & timeout settings
+ unsigned int retryMax;
+
+ /// PHY address ( pre-defined by pins on reset )
+ unsigned char phyAddress;
+
+} Macb, *pMacb;
+
+//------------------------------------------------------------------------------
+// Exported functions
+//------------------------------------------------------------------------------
+
+extern void MACB_SetupTimeout(Macb *pMacb, unsigned int toMax);
+
+extern void MACB_Init(Macb *pMacb, unsigned char phyAddress);
+
+extern unsigned char MACB_InitPhy(Macb *pMacb,
+ unsigned int mck,
+ const Pin *pResetPins,
+ unsigned int nbResetPins,
+ const Pin *pEmacPins,
+ unsigned int nbEmacPins);
+
+extern unsigned char MACB_AutoNegotiate(Macb *pMacb);
+
+extern unsigned char MACB_GetLinkSpeed(Macb *pMacb,
+ unsigned char applySettings);
+
+extern unsigned char MACB_Send(Macb *pMacb,
+ void *pBuffer,
+ unsigned int size);
+
+extern unsigned int MACB_Poll(Macb *pMacb,
+ unsigned char *pBuffer,
+ unsigned int size);
+
+
+#endif // #ifndef _MACB_H
+
diff --git a/drivers/macb/mii.h b/drivers/macb/mii.h
new file mode 100644
index 0000000..e1deda2
--- /dev/null
+++ b/drivers/macb/mii.h
@@ -0,0 +1,178 @@
+/* ----------------------------------------------------------------------------
+ * 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.
+ * ----------------------------------------------------------------------------
+ */
+
+#ifndef _MII_DEFINE_H
+#define _MII_DEFINE_H
+
+
+//-----------------------------------------------------------------------------
+/// Definitions
+//-----------------------------------------------------------------------------
+
+#define MII_BMCR 0 // Basic Mode Control Register
+#define MII_BMSR 1 // Basic Mode Status Register
+#define MII_PHYID1 2 // PHY Idendifier Register 1
+#define MII_PHYID2 3 // PHY Idendifier Register 2
+#define MII_ANAR 4 // Auto_Negotiation Advertisement Register
+#define MII_ANLPAR 5 // Auto_negotiation Link Partner Ability Register
+#define MII_ANER 6 // Auto-negotiation Expansion Register
+#define MII_DSCR 16 // Specified Configuration Register
+#define MII_DSCSR 17 // Specified Configuration and Status Register
+#define MII_10BTCSR 18 // 10BASE-T Configuration and Satus Register
+#define MII_PWDOR 19 // Power Down Control Register
+#define MII_CONFIGR 20 // Specified config Register
+#define MII_MDINTR 21 // Specified Interrupt Register
+#define MII_RECR 22 // Specified Receive Error Counter Register
+#define MII_DISCR 23 // Specified Disconnect Counter Register
+#define MII_RLSR 24 // Hardware Reset Latch State Register
+
+// Basic Mode Control Register (BMCR)
+// Bit definitions: MII_BMCR
+#define MII_RESET (1 << 15) // 1= Software Reset; 0=Normal Operation
+#define MII_LOOPBACK (1 << 14) // 1=loopback Enabled; 0=Normal Operation
+#define MII_SPEED_SELECT (1 << 13) // 1=100Mbps; 0=10Mbps
+#define MII_AUTONEG (1 << 12) // Auto-negotiation Enable
+#define MII_POWER_DOWN (1 << 11) // 1=Power down 0=Normal operation
+#define MII_ISOLATE (1 << 10) // 1 = Isolates 0 = Normal operation
+#define MII_RESTART_AUTONEG (1 << 9) // 1 = Restart auto-negotiation 0 = Normal operation
+#define MII_DUPLEX_MODE (1 << 8) // 1 = Full duplex operation 0 = Normal operation
+#define MII_COLLISION_TEST (1 << 7) // 1 = Collision test enabled 0 = Normal operation
+// Reserved 6 to 0 // Read as 0, ignore on write
+
+// Basic Mode Status Register (BMSR)
+// Bit definitions: MII_BMSR
+#define MII_100BASE_T4 (1 << 15) // 100BASE-T4 Capable
+#define MII_100BASE_TX_FD (1 << 14) // 100BASE-TX Full Duplex Capable
+#define MII_100BASE_T4_HD (1 << 13) // 100BASE-TX Half Duplex Capable
+#define MII_10BASE_T_FD (1 << 12) // 10BASE-T Full Duplex Capable
+#define MII_10BASE_T_HD (1 << 11) // 10BASE-T Half Duplex Capable
+// Reserved 10 to 7 // Read as 0, ignore on write
+#define MII_MF_PREAMB_SUPPR (1 << 6) // MII Frame Preamble Suppression
+#define MII_AUTONEG_COMP (1 << 5) // Auto-negotiation Complete
+#define MII_REMOTE_FAULT (1 << 4) // Remote Fault
+#define MII_AUTONEG_ABILITY (1 << 3) // Auto Configuration Ability
+#define MII_LINK_STATUS (1 << 2) // Link Status
+#define MII_JABBER_DETECT (1 << 1) // Jabber Detect
+#define MII_EXTEND_CAPAB (1 << 0) // Extended Capability
+
+// PHY ID Identifier Register
+// definitions: MII_PHYID1
+#define MII_LSB_MASK 0x3F
+
+#if defined(BOARD_EMAC_PHY_COMP_DM9161)
+#define MII_OUI_MSB 0x0181
+#define MII_OUI_LSB 0x2E
+//#define MII_PHYID1_OUI 0x606E // OUI: Organizationally Unique Identifier
+//#define MII_ID 0x0181b8a0
+#elif defined(BOARD_EMAC_PHY_COMP_LAN8700)
+#define MII_OUI_MSB 0x0007
+#define MII_OUI_LSB 0x30
+#else
+#error no PHY Ethernet component defined !
+#endif
+
+// Auto-negotiation Advertisement Register (ANAR)
+// Auto-negotiation Link Partner Ability Register (ANLPAR)
+// Bit definitions: MII_ANAR, MII_ANLPAR
+#define MII_NP (1 << 15) // Next page Indication
+#define MII_ACK (1 << 14) // Acknowledge
+#define MII_RF (1 << 13) // Remote Fault
+// Reserved 12 to 11 // Write as 0, ignore on read
+#define MII_FCS (1 << 10) // Flow Control Support
+#define MII_T4 (1 << 9) // 100BASE-T4 Support
+#define MII_TX_FDX (1 << 8) // 100BASE-TX Full Duplex Support
+#define MII_TX_HDX (1 << 7) // 100BASE-TX Support
+#define MII_10_FDX (1 << 6) // 10BASE-T Full Duplex Support
+#define MII_10_HDX (1 << 5) // 10BASE-T Support
+// Selector 4 to 0 // Protocol Selection Bits
+#define MII_AN_IEEE_802_3 0x0001
+
+// Auto-negotiation Expansion Register (ANER)
+// Bit definitions: MII_ANER
+// Reserved 15 to 5 // Read as 0, ignore on write
+#define MII_PDF (1 << 4) // Local Device Parallel Detection Fault
+#define MII_LP_NP_ABLE (1 << 3) // Link Partner Next Page Able
+#define MII_NP_ABLE (1 << 2) // Local Device Next Page Able
+#define MII_PAGE_RX (1 << 1) // New Page Received
+#define MII_LP_AN_ABLE (1 << 0) // Link Partner Auto-negotiation Able
+
+// Specified Configuration Register (DSCR)
+// Bit definitions: MII_DSCR
+#define MII_BP4B5B (1 << 15) // Bypass 4B5B Encoding and 5B4B Decoding
+#define MII_BP_SCR (1 << 14) // Bypass Scrambler/Descrambler Function
+#define MII_BP_ALIGN (1 << 13) // Bypass Symbol Alignment Function
+#define MII_BP_ADPOK (1 << 12) // BYPASS ADPOK
+#define MII_REPEATER (1 << 11) // Repeater/Node Mode
+#define MII_TX (1 << 10) // 100BASE-TX Mode Control
+#define MII_FEF (1 << 9) // Far end Fault enable
+#define MII_RMII_ENABLE (1 << 8) // Reduced MII Enable
+#define MII_F_LINK_100 (1 << 7) // Force Good Link in 100Mbps
+#define MII_SPLED_CTL (1 << 6) // Speed LED Disable
+#define MII_COLLED_CTL (1 << 5) // Collision LED Enable
+#define MII_RPDCTR_EN (1 << 4) // Reduced Power Down Control Enable
+#define MII_SM_RST (1 << 3) // Reset State Machine
+#define MII_MFP_SC (1 << 2) // MF Preamble Suppression Control
+#define MII_SLEEP (1 << 1) // Sleep Mode
+#define MII_RLOUT (1 << 0) // Remote Loopout Control
+
+// Specified Configuration and Status Register (DSCSR)
+// Bit definitions: MII_DSCSR
+#define MII_100FDX (1 << 15) // 100M Full Duplex Operation Mode
+#define MII_100HDX (1 << 14) // 100M Half Duplex Operation Mode
+#define MII_10FDX (1 << 13) // 10M Full Duplex Operation Mode
+#define MII_10HDX (1 << 12) // 10M Half Duplex Operation Mode
+
+// 10BASE-T Configuration/Status (10BTCSR)
+// Bit definitions: MII_10BTCSR
+// Reserved 18 to 15 // Read as 0, ignore on write
+#define MII_LP_EN (1 << 14) // Link Pulse Enable
+#define MII_HBE (1 << 13) // Heartbeat Enable
+#define MII_SQUELCH (1 << 12) // Squelch Enable
+#define MII_JABEN (1 << 11) // Jabber Enable
+#define MII_10BT_SER (1 << 10) // 10BASE-T GPSI Mode
+// Reserved 9 to 1 // Read as 0, ignore on write
+#define MII_POLR (1 << 0) // Polarity Reversed
+
+// Specified Interrupt Register
+// Bit definitions: MII_MDINTR
+#define MII_INTR_PEND (1 << 15) // Interrupt Pending
+// Reserved 14 to 12 // Reserved
+#define MII_FDX_MASK (1 << 11) // Full-duplex Interrupt Mask
+#define MII_SPD_MASK (1 << 10) // Speed Interrupt Mask
+#define MII_LINK_MASK (1 << 9) // Link Interrupt Mask
+#define MII_INTR_MASK (1 << 8) // Master Interrupt Mask
+// Reserved 7 to 5 // Reserved
+#define MII_FDX_CHANGE (1 << 4) // Duplex Status Change Interrupt
+#define MII_SPD_CHANGE (1 << 3) // Speed Status Change Interrupt
+#define MII_LINK_CHANGE (1 << 2) // Link Status Change Interrupt
+// Reserved 1 // Reserved
+#define MII_INTR_STATUS (1 << 0) // Interrupt Status
+
+#endif // #ifndef _MII_DEFINE_H
+
diff --git a/drivers/tsd/tsd.dir b/drivers/tsd/tsd.dir
new file mode 100644
index 0000000..c72fa6f
--- /dev/null
+++ b/drivers/tsd/tsd.dir
@@ -0,0 +1,42 @@
+/* ----------------------------------------------------------------------------
+ * 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.
+ * ----------------------------------------------------------------------------
+ */
+
+//------------------------------------------------------------------------------
+/// \dir
+///
+/// !!!Contents
+///
+/// This directory contains the source code of the touchscreen driver. tsd.h
+/// contains all the interface functions definitions. tsd_tsadc.c contains the
+/// implementation of the driver for the chip that have the peripheral ip TSADC.
+/// tsd_ads7843.c contains the driver implementation for board that have the
+/// external component ads7843 (the chip has not the peripheral ip TSDADC).
+/// tds_com.c contains all the common function for the two driver implementations
+/// (calibration functions).
+//------------------------------------------------------------------------------
diff --git a/drivers/tsd/tsd.h b/drivers/tsd/tsd.h
new file mode 100644
index 0000000..22a4930
--- /dev/null
+++ b/drivers/tsd/tsd.h
@@ -0,0 +1,74 @@
+/* ----------------------------------------------------------------------------
+ * 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.
+ * ----------------------------------------------------------------------------
+ */
+
+//------------------------------------------------------------------------------
+/// \unit
+///
+/// !!!Purpose
+///
+/// This unit provides a very powerful touchscreen driver which handles all the
+/// complexity. This includes touchscreen calibration, retrieving measurements,
+/// configuring the TSADC, etc.
+///
+/// !!!Usage
+///
+/// -# Call TSD_Initialize() whenever the touchscreen should start the
+/// calibration process (as it is done in the function).
+/// -# Declare a global TSD_PenPressed function anywhere in your code. This
+/// function will get called every time the pen is pressed on the screen.
+/// -# Declare a global TSD_PenMoved function, which will get called whenever
+/// the pen stays in contact with the screen but changes position.
+/// -# Declare a global TSD_PenReleased function, which will be invoked as the
+/// pen is lifted from the screen.
+//------------------------------------------------------------------------------
+
+#ifndef TSD_H
+#define TSD_H
+
+//------------------------------------------------------------------------------
+// Headers
+//------------------------------------------------------------------------------
+
+#include "tsd_com.h"
+
+//------------------------------------------------------------------------------
+// Global functions
+//------------------------------------------------------------------------------
+
+extern void TSD_Initialize(void *pLcdBuffer);
+
+extern unsigned char TSD_Calibrate(void *pLcdBuffer);
+
+extern void TSD_Reset(void);
+
+#ifdef at91sam3u
+extern void TSD_TimerHandler(void);
+#endif
+
+#endif //#ifndef TSD_H
diff --git a/drivers/tsd/tsd_ads7843.c b/drivers/tsd/tsd_ads7843.c
new file mode 100644
index 0000000..3800a5f
--- /dev/null
+++ b/drivers/tsd/tsd_ads7843.c
@@ -0,0 +1,438 @@
+/* ----------------------------------------------------------------------------
+ * 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>
+
+#ifdef BOARD_TSC_ADS7843
+
+#include "tsd.h"
+#include "tsd_com.h"
+#include <irq/irq.h>
+#include <pio/pio.h>
+#include <pio/pio_it.h>
+#if defined(cortexm3)
+#include <systick/systick.h>
+#else
+#include <pit/pit.h>
+#endif
+#include <ads7843/ads7843.h>
+#include <drivers/lcd/lcdd.h>
+#include <drivers/lcd/draw.h>
+#include <drivers/lcd/font.h>
+
+#include <string.h>
+
+//------------------------------------------------------------------------------
+// Local definitions
+//------------------------------------------------------------------------------
+
+/// PIT period value in µseconds.
+#define PIT_PERIOD 10000 // 10 ms
+
+/// Delay for pushbutton debouncing (in PIT_PERIOD time-base).
+#define DEBOUNCE_TIME 6 // PIT_PERIOD * 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
+
+//------------------------------------------------------------------------------
+// Local 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 Pin pinPenIRQ = PIN_TCS_IRQ;
+
+/// Global timestamp in milliseconds since start of application.
+static volatile unsigned int timestamp = 0;
+
+/// last time when the pen is pressed on the touchscreen
+static volatile unsigned int timePress = 0;
+
+/// last time when the pen is released
+static volatile unsigned int timeRelease = 0;
+
+/// pen state
+static volatile e_pen_state penState = STATE_PEN_RELEASED;
+
+/// Touch screen initiallized flag
+static unsigned int tsInitFlag = 0;
+
+//------------------------------------------------------------------------------
+// External functions
+//------------------------------------------------------------------------------
+
+extern void TSD_PenPressed(unsigned int x, unsigned int y);
+extern void TSD_PenMoved(unsigned int x, unsigned int y);
+extern void TSD_PenReleased(unsigned int x, unsigned int y);
+
+//------------------------------------------------------------------------------
+// Local functions
+//------------------------------------------------------------------------------
+extern void TSD_GetRawMeasurement(unsigned int *pData);
+
+#if defined(cortexm3)
+//------------------------------------------------------------------------------
+/// 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.
+/// For AT91SAM3, SysTick interrupt should call it per 10ms.
+//------------------------------------------------------------------------------
+void TSD_TimerHandler(void)
+{
+ unsigned int data[2];
+ static unsigned int 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) {
+
+ if( (timestamp - timePress) > 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) {
+
+ if( (timestamp - timeRelease) > 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]);
+ }
+ }
+ }
+ }
+}
+
+#else // For SAM7/SAM9
+
+//------------------------------------------------------------------------------
+/// Handler for PIT interrupt. 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.
+//------------------------------------------------------------------------------
+static void ISR_Pit(void)
+{
+ unsigned int status;
+ unsigned int data[2];
+ static unsigned int point[2];
+
+ // Read the PIT status register
+ status = PIT_GetStatus() & AT91C_PITC_PITS;
+ if (status != 0) {
+
+ // Read the PIVR to acknowledge interrupt and get number of ticks
+ timestamp += (PIT_GetPIVR() >> 20);
+ }
+
+ // 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
+ PIO_DisableIt(&pinPenIRQ);
+ ADS7843_GetPosition(&data[0], &data[1]);
+ PIO_EnableIt(&pinPenIRQ);
+
+ 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) {
+
+ if( (timestamp - timePress) > 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) {
+
+ if( (timestamp - timeRelease) > 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]);
+ }
+ }
+ }
+ }
+}
+#endif
+
+//------------------------------------------------------------------------------
+/// 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;
+ }
+ }
+}
+
+#if !defined(cortexm3)
+//------------------------------------------------------------------------------
+/// Configure the periodic interval timer to generate an interrupt every 10 ms
+//------------------------------------------------------------------------------
+static void ConfigurePit(void)
+{
+ // Initialize the PIT to the desired frequency
+ PIT_Init(PIT_PERIOD, BOARD_MCK / 1000000);
+
+ // Configure interrupt on PIT
+ IRQ_DisableIT(AT91C_ID_SYS);
+ IRQ_ConfigureIT(AT91C_ID_SYS, AT91C_AIC_PRIOR_LOWEST, ISR_Pit);
+ IRQ_EnableIT(AT91C_ID_SYS);
+ PIT_EnableIT();
+
+ // Enable the pit
+ PIT_Enable();
+}
+#endif
+
+//-----------------------------------------------------------------------------
+/// Configure PENIRQ for interrupt
+//-----------------------------------------------------------------------------
+void ConfigurePenIRQ(void)
+{
+ // Configure pios
+ PIO_Configure(&pinPenIRQ, PIO_LISTSIZE(pinPenIRQ));
+
+ // Initialize interrupts
+#if defined(cortexm3)
+ PIO_InitializeInterrupts(0);
+#else // For SAM7/SAM9
+ PIO_InitializeInterrupts(AT91C_AIC_PRIOR_HIGHEST);
+#endif
+ PIO_ConfigureIt(&pinPenIRQ, (void (*)(const Pin *)) ISR_PenIRQ);
+
+ // Enable the interrupt
+ PIO_EnableIt(&pinPenIRQ);
+}
+
+//------------------------------------------------------------------------------
+// Global functions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// Reads and store a touchscreen measurement in the provided array.
+/// \param pData Array where the measurements will be stored
+//------------------------------------------------------------------------------
+void TSD_GetRawMeasurement(unsigned int *pData)
+{
+#if defined(cortexm3)
+ // Get the current position of the pressed pen
+ PIO_DisableIt(&pinPenIRQ);
+ ADS7843_GetPosition(&pData[0], &pData[1]);
+ PIO_EnableIt(&pinPenIRQ);
+#else
+ // Get the current position of the pressed pen
+ PIO_DisableIt(&pinPenIRQ);
+ ADS7843_GetPosition(&pData[0], &pData[1]);
+ PIO_EnableIt(&pinPenIRQ);
+#endif
+}
+
+//------------------------------------------------------------------------------
+/// Wait pen pressed
+//------------------------------------------------------------------------------
+void TSD_WaitPenPressed(void)
+{
+ // Wait for touch & end of conversion
+ while (penState != STATE_PEN_RELEASED);
+ while (penState != STATE_PEN_PRESSED);
+}
+
+//------------------------------------------------------------------------------
+/// Wait pen released
+//------------------------------------------------------------------------------
+void TSD_WaitPenReleased(void)
+{
+ // Wait for contact loss
+ while (penState != STATE_PEN_PRESSED);
+ while (penState != STATE_PEN_RELEASED);
+}
+
+//------------------------------------------------------------------------------
+/// Do calibration
+/// \param pLcdBuffer LCD buffer to use for displaying the calibration info.
+/// \return 1 if calibration is Ok, 0 else
+//------------------------------------------------------------------------------
+unsigned char TSD_Calibrate(void *pLcdBuffer)
+{
+ unsigned char ret = 0;
+
+ // Calibration is done only once
+ if(TSDCom_IsCalibrationOk()) {
+ return 1;
+ }
+
+ // Do calibration
+ ret = TSDCom_Calibrate(pLcdBuffer);
+
+ return ret;
+}
+
+//------------------------------------------------------------------------------
+/// Initializes the touchscreen driver and starts the calibration process. When
+/// finished, the touchscreen is operational.
+///
+/// Important: the LCD driver must have been initialized prior to calling this
+/// function.
+/// \param pBuffer LCD buffer to use for displaying the calibration info.
+//------------------------------------------------------------------------------
+void TSD_Initialize(void *pLcdBuffer)
+{
+ ADS7843_Initialize();
+ ConfigurePenIRQ();
+#if !defined(cortexm3)
+ ConfigurePit();
+#endif
+ tsInitFlag = 1;
+
+ // Calibration
+ if(pLcdBuffer) {
+ while (!TSD_Calibrate(pLcdBuffer));
+ }
+}
+
+//------------------------------------------------------------------------------
+/// Stop the Touchscreen, disable interrupt and stop Pit
+//------------------------------------------------------------------------------
+void TSD_Reset(void)
+{
+ // Disable SPI 0
+ ADS7843_Reset();
+
+ // Disable the interrupt
+ PIO_DisableIt(&pinPenIRQ);
+
+#if !defined(cortexm3)
+ // Stop Pit interrupt
+ PIT_DisableIT();
+ IRQ_DisableIT(AT91C_ID_SYS);
+#endif
+}
+
+#endif //#ifdef BOARD_TSC_ADS7843
diff --git a/drivers/tsd/tsd_com.c b/drivers/tsd/tsd_com.c
new file mode 100644
index 0000000..a930cc9
--- /dev/null
+++ b/drivers/tsd/tsd_com.c
@@ -0,0 +1,390 @@
+/* ----------------------------------------------------------------------------
+ * 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 "tsd.h"
+#include <board.h>
+#include <irq/irq.h>
+#include <pio/pio.h>
+#include <drivers/lcd/lcdd.h>
+#include <drivers/lcd/draw.h>
+#include <drivers/lcd/font.h>
+#include <drivers/lcd/color.h>
+#include <string.h>
+#include <utility/assert.h>
+
+//------------------------------------------------------------------------------
+// Local 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 (positive or negative)
+#define DELAY_RESULT_DISPLAY 4000000
+
+//------------------------------------------------------------------------------
+// Local types
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// Point used during the touchscreen calibration process.
+//------------------------------------------------------------------------------
+typedef struct _CalibrationPoint {
+
+ /// Coordinate of point along the X-axis of the screen.
+ unsigned int x;
+ /// Coordinate of point along the Y-axis of the screen.
+ unsigned int y;
+ /// Calibration data of point.
+ unsigned int data[2];
+
+} CalibrationPoint;
+
+//------------------------------------------------------------------------------
+// Local variables
+//------------------------------------------------------------------------------
+
+/// indicates if the touch screen has been calibrated.
+/// If not, Callback functions are not called
+static volatile unsigned char bCalibrationOk = 0;
+/// Slope for interpoling touchscreen measurements along the X-axis.
+static signed int xSlope;
+/// Slope for interpoling touchscreen measurements along the Y-axis.
+static signed int 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}
+};
+
+//------------------------------------------------------------------------------
+// External functions
+//------------------------------------------------------------------------------
+
+extern void TSD_GetRawMeasurement(unsigned int *pData);
+extern void TSD_WaitPenPressed(void);
+extern void TSD_WaitPenReleased(void);
+
+//------------------------------------------------------------------------------
+// Local functions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// Display a calibration point on the given buffer.
+/// \param pLcdBuffer LCD buffer to draw on.
+/// \param pPoint Calibration point to display.
+//------------------------------------------------------------------------------
+static void DrawCalibrationPoint(
+ void *pLcdBuffer,
+ const CalibrationPoint *pPoint)
+{
+ LCDD_DrawRectangle(pLcdBuffer,
+ pPoint->x - POINTS_SIZE / 2,
+ pPoint->y - POINTS_SIZE / 2,
+ POINTS_SIZE,
+ POINTS_SIZE,
+ COLOR_RED);
+}
+
+//------------------------------------------------------------------------------
+/// Clears a calibration point from the given buffer.
+/// \param pLcdBuffer LCD buffer to draw on.
+/// \param pPoint Calibration point to clear.
+//------------------------------------------------------------------------------
+static void ClearCalibrationPoint(
+ void *pLcdBuffer,
+ const CalibrationPoint *pPoint)
+{
+ LCDD_DrawRectangle(pLcdBuffer,
+ pPoint->x - POINTS_SIZE / 2,
+ pPoint->y - POINTS_SIZE / 2,
+ POINTS_SIZE,
+ POINTS_SIZE,
+ COLOR_WHITE);
+}
+
+//------------------------------------------------------------------------------
+// Global functions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// Indicates if the calibration of the touch screen is Ok
+/// \return 1 calibration Ok, 0 if not
+//------------------------------------------------------------------------------
+unsigned char TSDCom_IsCalibrationOk(void)
+{
+ if (bCalibrationOk == 1) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+//------------------------------------------------------------------------------
+/// 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 unsigned int *pData, unsigned int *pPoint)
+{
+ pPoint[0] = calibrationPoints[0].x
+ - (((signed int) calibrationPoints[0].data[0] - (signed int) pData[0]) * 1024)
+ / xSlope;
+
+ pPoint[1] = calibrationPoints[0].y
+ - (((signed int) calibrationPoints[0].data[1] - (signed int) 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;
+ }
+}
+
+//------------------------------------------------------------------------------
+/// Performs the calibration process using the provided buffer to display
+/// information.
+/// \param pLcdBuffer LCD buffer to display.
+/// \return True if calibration was successful; otherwise false.
+//------------------------------------------------------------------------------
+unsigned char TSDCom_Calibrate(void *pLcdBuffer)
+{
+#ifdef AT91C_ID_LCDC
+ void *pOldLcdBuffer;
+#endif
+ volatile unsigned int i; // to keep the tempo with gcc code optimisation
+ signed int slope1, slope2;
+ CalibrationPoint measuredPoint;
+ unsigned char xOk, yOk;
+ signed int xDiff, yDiff;
+
+ // Calibration setup
+ LCDD_Fill(pLcdBuffer, COLOR_WHITE);
+ LCDD_DrawString(pLcdBuffer, 30, 50, "LCD calibration", COLOR_BLACK);
+ LCDD_DrawString(pLcdBuffer, 1, 100, " Touch the dots to\ncalibrate the screen", COLOR_DARKBLUE);
+#ifdef AT91C_ID_LCDC
+ pOldLcdBuffer = LCDD_DisplayBuffer(pLcdBuffer);
+#endif
+
+ // Calibration points
+ for (i=0; i < 4; i++) {
+
+ DrawCalibrationPoint(pLcdBuffer, &calibrationPoints[i]);
+
+ // Wait for touch & end of conversion
+ TSD_WaitPenPressed();
+ TSD_GetRawMeasurement(calibrationPoints[i].data);
+ ClearCalibrationPoint(pLcdBuffer, &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 = ((signed int) calibrationPoints[0].data[0]) - ((signed int) calibrationPoints[1].data[0]);
+ slope1 *= 1024;
+ slope1 /= ((signed int) calibrationPoints[0].x) - ((signed int) calibrationPoints[1].x);
+ slope2 = ((signed int) calibrationPoints[2].data[0]) - ((signed int) calibrationPoints[3].data[0]);
+ slope2 *= 1024;
+ slope2 /= ((signed int) calibrationPoints[2].x) - ((signed int) calibrationPoints[3].x);
+ xSlope = (slope1 + slope2) / 2;
+
+ slope1 = ((signed int) calibrationPoints[0].data[1]) - ((signed int) calibrationPoints[2].data[1]);
+ slope1 *= 1024;
+ slope1 /= ((signed int) calibrationPoints[0].y) - ((signed int) calibrationPoints[2].y);
+ slope2 = ((signed int) calibrationPoints[1].data[1]) - ((signed int) calibrationPoints[3].data[1]);
+ slope2 *= 1024;
+ slope2 /= ((signed int) calibrationPoints[1].y) - ((signed int) calibrationPoints[3].y);
+ ySlope = (slope1 + slope2) / 2;
+
+ // Test point
+ LCDD_Fill(pLcdBuffer, 0xFFFFFF);
+ LCDD_DrawString(pLcdBuffer, 30, 50, "LCD calibration", COLOR_BLACK);
+ LCDD_DrawString(pLcdBuffer, 1, 100, " Touch the point to\nvalidate calibration", COLOR_DARKBLUE);
+ DrawCalibrationPoint(pLcdBuffer, &testPoint);
+
+ // Wait for touch & end of conversion
+ TSD_WaitPenPressed();
+
+ TSD_GetRawMeasurement(measuredPoint.data);
+ TSDCom_InterpolateMeasurement(measuredPoint.data, (unsigned int *) &measuredPoint);
+ DrawCalibrationPoint(pLcdBuffer, &measuredPoint);
+
+ // Check resulting x and y
+ xDiff = (signed int) measuredPoint.x - (signed int) testPoint.x;
+ yDiff = (signed int) measuredPoint.y - (signed int) 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(pLcdBuffer, COLOR_WHITE);
+ LCDD_DrawString(pLcdBuffer, 30, 50, "LCD calibration", COLOR_BLACK);
+ LCDD_DrawString(pLcdBuffer, 80, 100, "Success !", COLOR_GREEN);
+
+ }
+ else {
+
+ bCalibrationOk = 0;
+ LCDD_Fill(pLcdBuffer, COLOR_WHITE);
+ LCDD_DrawString(pLcdBuffer, 30, 50, "LCD calibration", COLOR_BLACK);
+ LCDD_DrawString(pLcdBuffer, 40, 100, "Error too big", COLOR_RED);
+ }
+
+ // Slight delay
+ for (i = 0; i < DELAY_RESULT_DISPLAY; i++);
+
+#ifdef AT91C_ID_LCDC
+ // Restore old LCD buffer
+ LCDD_DisplayBuffer(pOldLcdBuffer);
+#endif
+
+ return (xOk && yOk);
+}
+
+//------------------------------------------------------------------------------
+/// Read calibrate data to buffer.
+/// \param pBuffer Data buffer.
+/// \param size Size of data buffer in bytes.
+//------------------------------------------------------------------------------
+void TSDCom_ReadCalibrateData(void *pBuffer, unsigned int size)
+{
+ unsigned char *pDest = (unsigned char *)pBuffer;
+
+ SANITY_CHECK((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);
+}
+
+//------------------------------------------------------------------------------
+/// Restore calibrate data with buffer data.
+/// \param pBuffer Data buffer.
+/// \param size Size of data buffer in bytes.
+//------------------------------------------------------------------------------
+void TSDCom_RestoreCalibrateData(void *pBuffer, unsigned int size)
+{
+ unsigned char *pSrc = (unsigned char *)pBuffer;
+
+ SANITY_CHECK((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/drivers/tsd/tsd_com.h b/drivers/tsd/tsd_com.h
new file mode 100644
index 0000000..91e99c6
--- /dev/null
+++ b/drivers/tsd/tsd_com.h
@@ -0,0 +1,48 @@
+/* ----------------------------------------------------------------------------
+ * 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.
+ * ----------------------------------------------------------------------------
+ */
+
+#ifndef TSD_COM_H
+#define TSD_COM_H
+
+//------------------------------------------------------------------------------
+// Global functions
+//------------------------------------------------------------------------------
+
+extern void TSDCom_InterpolateMeasurement(
+ const unsigned int *pData,
+ unsigned int *pPoint);
+
+unsigned char TSDCom_Calibrate(void *pLcdBuffer);
+
+unsigned char TSDCom_IsCalibrationOk(void);
+
+void TSDCom_ReadCalibrateData(void *pBuffer, unsigned int size);
+void TSDCom_RestoreCalibrateData(void *pBuffer, unsigned int size);
+
+#endif //#ifndef TSD_COM_H
diff --git a/drivers/tsd/tsd_tsadc.c b/drivers/tsd/tsd_tsadc.c
new file mode 100644
index 0000000..bb9106a
--- /dev/null
+++ b/drivers/tsd/tsd_tsadc.c
@@ -0,0 +1,269 @@
+/* ----------------------------------------------------------------------------
+ * 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>
+
+#ifdef AT91C_BASE_TSADC
+
+#include "tsd.h"
+#include "tsd_com.h"
+#include <irq/irq.h>
+#include <pio/pio.h>
+#include <tsadcc/tsadcc.h>
+#include <drivers/lcd/lcdd.h>
+#include <drivers/lcd/draw.h>
+#include <drivers/lcd/font.h>
+
+#include <string.h>
+
+//------------------------------------------------------------------------------
+// Local definitions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+// Local types
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+// Local variables
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+// External functions
+//------------------------------------------------------------------------------
+
+extern void TSD_PenPressed(unsigned int x, unsigned int y);
+extern void TSD_PenMoved(unsigned int x, unsigned int y);
+extern void TSD_PenReleased(unsigned int x, unsigned int y);
+
+//------------------------------------------------------------------------------
+// Local functions
+//------------------------------------------------------------------------------
+extern void TSD_GetRawMeasurement(unsigned int *pData);
+
+//------------------------------------------------------------------------------
+/// Interrupt handler for the TSADC. Handles pen press, pen move and pen release
+/// events by invoking three callback functions.
+//------------------------------------------------------------------------------
+static void InterruptHandler(void)
+{
+ unsigned int status;
+ unsigned int data[2];
+ static unsigned int newPoint[2];
+ static unsigned int point[2];
+ static unsigned char report = 0;
+
+ // Retrieve TADC status
+ // Bug fix: two step operation so IAR doesn't complain that the order of
+ // volatile access is unspecified.
+ status = AT91C_BASE_TSADC->TSADC_SR;
+ status &= AT91C_BASE_TSADC->TSADC_IMR;
+
+ // Pen release
+ if ((status & AT91C_TSADC_NOCNT) == AT91C_TSADC_NOCNT) {
+
+ // Invoke PenReleased callback
+ if(TSDCom_IsCalibrationOk()) {
+ TSD_PenReleased(point[0], point[1]);
+ }
+
+ // Stop periodic trigger mode
+ TSADCC_SetDebounceTime(BOARD_TOUCHSCREEN_DEBOUNCE);
+ AT91C_BASE_TSADC->TSADC_IDR = AT91C_TSADC_EOC3 | AT91C_TSADC_NOCNT;
+
+ TSADCC_SetTriggerMode(AT91C_TSADC_TRGMOD_PENDET_TRIGGER);
+ TSD_GetRawMeasurement(data); // Clear data registers
+ AT91C_BASE_TSADC->TSADC_SR;
+ AT91C_BASE_TSADC->TSADC_IER = AT91C_TSADC_PENCNT;
+ }
+ // Pen press
+ else if ((status & AT91C_TSADC_PENCNT) == AT91C_TSADC_PENCNT) {
+
+ // Invoke PenPressed callback with (x,y) coordinates
+ while ((AT91C_BASE_TSADC->TSADC_SR & AT91C_TSADC_EOC3) != AT91C_TSADC_EOC3);
+ TSD_GetRawMeasurement(data);
+ TSDCom_InterpolateMeasurement(data, point);
+
+ // Invoke PenPressed callback
+ if(TSDCom_IsCalibrationOk()) {
+ TSD_PenPressed(point[0], point[1]);
+ }
+
+ // Configure TSADC for periodic trigger
+ TSADCC_SetDebounceTime(10); // 1ns
+ AT91C_BASE_TSADC->TSADC_IER = AT91C_TSADC_EOC3 | AT91C_TSADC_NOCNT;
+ AT91C_BASE_TSADC->TSADC_IDR = AT91C_TSADC_PENCNT;
+ TSADCC_SetTriggerPeriod(10000000); // 10ms
+ TSADCC_SetTriggerMode(AT91C_TSADC_TRGMOD_PERIODIC_TRIGGER);
+ report = 0;
+ }
+ // Pen move
+ else if ((status & AT91C_TSADC_EOC3) == AT91C_TSADC_EOC3) {
+
+ // Invoke callback with LAST value measured
+ // Explanation: the very last value that will be measured (just as the
+ // pen is released) might be corrupted and there is no way to know. So
+ // we just discard it.
+
+ if (report) {
+
+ memcpy(point, newPoint, sizeof(newPoint));
+ // Invoke PenMoved callback
+ if(TSDCom_IsCalibrationOk()) {
+ TSD_PenMoved(point[0], point[1]);
+ }
+ report = 0;
+ }
+
+ TSD_GetRawMeasurement(data);
+ TSDCom_InterpolateMeasurement(data, newPoint);
+ if ((newPoint[0] != point[0]) || (newPoint[1] != point[1])) {
+
+ report = 1;
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+// Global functions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// Reads and store a touchscreen measurement in the provided array.
+/// The value stored are:
+/// - data[0] = CDR3 * 1024 / CDR2
+/// - data[1] = CDR1 * 1024 / CDR0
+/// \param pData Array where the measurements will be stored
+//------------------------------------------------------------------------------
+void TSD_GetRawMeasurement(unsigned int *pData)
+{
+ pData[0] = (AT91C_BASE_TSADC->TSADC_CDR3 * 1024);
+ pData[0] /= AT91C_BASE_TSADC->TSADC_CDR2;
+ pData[1] = (AT91C_BASE_TSADC->TSADC_CDR1 * 1024);
+ pData[1] /= AT91C_BASE_TSADC->TSADC_CDR0;
+}
+
+//------------------------------------------------------------------------------
+/// Wait pen pressed
+//------------------------------------------------------------------------------
+void TSD_WaitPenPressed(void)
+{
+ // Wait for touch & end of conversion
+ while ((AT91C_BASE_TSADC->TSADC_SR & AT91C_TSADC_PENCNT) != AT91C_TSADC_PENCNT);
+ while ((AT91C_BASE_TSADC->TSADC_SR & AT91C_TSADC_EOC3) != AT91C_TSADC_EOC3);
+}
+
+//------------------------------------------------------------------------------
+/// Wait pen released
+//------------------------------------------------------------------------------
+void TSD_WaitPenReleased(void)
+{
+ // Wait for contact loss
+ while ((AT91C_BASE_TSADC->TSADC_SR & AT91C_TSADC_NOCNT) != AT91C_TSADC_NOCNT);
+}
+
+//------------------------------------------------------------------------------
+/// Do calibration
+/// \param pLcdBuffer LCD buffer to use for displaying the calibration info.
+/// \return 1 if calibration is Ok, 0 else
+//------------------------------------------------------------------------------
+unsigned char TSD_Calibrate(void *pLcdBuffer)
+{
+ unsigned char ret = 0;
+
+ // Calibration is done only once
+ if(TSDCom_IsCalibrationOk()) {
+ return 1;
+ }
+
+ // Enable trigger
+ TSADCC_SetTriggerMode(AT91C_TSADC_TRGMOD_PENDET_TRIGGER);
+
+ // Do calibration
+ ret = TSDCom_Calibrate(pLcdBuffer);
+
+ // Disable trigger
+ TSADCC_SetTriggerMode(AT91C_TSADC_TRGMOD_NO_TRIGGER);
+
+ // Configure interrupt generation
+ // Do it only if the calibration is Ok.
+ if(ret) {
+ TSADCC_SetTriggerMode(AT91C_TSADC_TRGMOD_PENDET_TRIGGER);
+ IRQ_ConfigureIT(AT91C_ID_TSADC, 0, InterruptHandler);
+ IRQ_EnableIT(AT91C_ID_TSADC);
+ AT91C_BASE_TSADC->TSADC_IER = AT91C_TSADC_PENCNT;
+ }
+
+ return ret;
+}
+
+//------------------------------------------------------------------------------
+/// Initializes the touchscreen driver and starts the calibration process. When
+/// finished, the touchscreen is operational.
+/// The configuration is taken from the board.h of the device being compiled.
+///
+/// Important: the LCD driver must have been initialized prior to calling this
+/// function.
+/// \param pLcdBuffer LCD buffer to use for displaying the calibration info.
+//------------------------------------------------------------------------------
+void TSD_Initialize(void *pLcdBuffer)
+{
+ const Pin pins[] = {PINS_TSADCC};
+
+ // Configuration
+ AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_TSADC;
+ PIO_Configure(pins, PIO_LISTSIZE(pins));
+ TSADCC_SetOperatingMode(AT91C_TSADC_TSAMOD_TS_ONLY_MODE);
+ TSADCC_SetPenDetect(1);
+ TSADCC_SetAdcFrequency(BOARD_TOUCHSCREEN_ADCCLK, BOARD_MCK);
+ TSADCC_SetStartupTime(BOARD_TOUCHSCREEN_STARTUP);
+ TSADCC_SetTrackAndHoldTime(BOARD_TOUCHSCREEN_SHTIM);
+ TSADCC_SetDebounceTime(BOARD_TOUCHSCREEN_DEBOUNCE);
+
+ // Do calibration if the LCd buffer is not a null pointer
+ if(pLcdBuffer) {
+ // Calibration
+ while (!TSD_Calibrate(pLcdBuffer));
+ }
+}
+
+//------------------------------------------------------------------------------
+/// Reset/stop the touchscreen
+//------------------------------------------------------------------------------
+void TSD_Reset(void)
+{
+ IRQ_DisableIT(AT91C_ID_TSADC);
+ AT91C_BASE_PMC->PMC_PCDR = 1 << AT91C_ID_TSADC;
+}
+
+#endif //#ifdef AT91C_BASE_TSADC
diff --git a/drivers/twi/twid.c b/drivers/twi/twid.c
new file mode 100644
index 0000000..d08d96a
--- /dev/null
+++ b/drivers/twi/twid.c
@@ -0,0 +1,344 @@
+/* ----------------------------------------------------------------------------
+ * 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.
+ * ----------------------------------------------------------------------------
+ */
+
+
+#define TWITIMEOUTMAX 50000
+
+//------------------------------------------------------------------------------
+// Headers
+//------------------------------------------------------------------------------
+
+#include "twid.h"
+#include <twi/twi.h>
+#include <utility/assert.h>
+#include <utility/trace.h>
+
+//------------------------------------------------------------------------------
+// Local types
+//------------------------------------------------------------------------------
+
+/// TWI driver callback function.
+typedef void (*TwiCallback)(Async *);
+
+//------------------------------------------------------------------------------
+/// TWI asynchronous transfer descriptor.
+//------------------------------------------------------------------------------
+typedef struct _AsyncTwi {
+
+ /// Asynchronous transfer status.
+ volatile unsigned char status;
+ // Callback function to invoke when transfer completes or fails.
+ TwiCallback callback;
+ /// Pointer to the data buffer.
+ unsigned char *pData;
+ /// Total number of bytes to transfer.
+ unsigned int num;
+ /// Number of already transferred bytes.
+ unsigned int transferred;
+
+} AsyncTwi;
+
+//------------------------------------------------------------------------------
+// Global functions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// Initializes a TWI driver instance, using the given TWI peripheral. 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, AT91S_TWI *pTwi)
+{
+ TRACE_DEBUG("TWID_Initialize()\n\r");
+ SANITY_CHECK(pTwid);
+ SANITY_CHECK(pTwi);
+
+ // Initialize driver
+ pTwid->pTwi = pTwi;
+ pTwid->pTransfer = 0;
+}
+
+//------------------------------------------------------------------------------
+/// 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)
+{
+ unsigned char status;
+ AsyncTwi *pTransfer = (AsyncTwi *) pTwid->pTransfer;
+ AT91S_TWI *pTwi = pTwid->pTwi;
+
+ SANITY_CHECK(pTwid);
+
+ // Retrieve interrupt status
+ status = TWI_GetMaskedStatus(pTwi);
+
+ // Byte received
+ if (TWI_STATUS_RXRDY(status)) {
+
+ pTransfer->pData[pTransfer->transferred] = TWI_ReadByte(pTwi);
+ pTransfer->transferred++;
+
+ // Transfer finished ?
+ if (pTransfer->transferred == pTransfer->num) {
+
+ TWI_DisableIt(pTwi, AT91C_TWI_RXRDY);
+ TWI_EnableIt(pTwi, AT91C_TWI_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, AT91C_TWI_TXRDY);
+ TWI_EnableIt(pTwi, AT91C_TWI_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, AT91C_TWI_TXCOMP);
+ pTransfer->status = 0;
+ if (pTransfer->callback) {
+
+ pTransfer->callback((Async *) pTransfer);
+ }
+ pTwid->pTransfer = 0;
+ }
+}
+
+//-----------------------------------------------------------------------------
+/// Asynchronously reads data from a slave on the TWI bus. An optional
+/// callback function is triggered when the transfer is complete.
+/// Returns 0 if the transfer has been started; otherwise returns a TWI error
+/// code.
+/// \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.
+//-----------------------------------------------------------------------------
+unsigned char TWID_Read(
+ Twid *pTwid,
+ unsigned char address,
+ unsigned int iaddress,
+ unsigned char isize,
+ unsigned char *pData,
+ unsigned int num,
+ Async *pAsync)
+{
+ AT91S_TWI *pTwi = pTwid->pTwi;
+ AsyncTwi *pTransfer = (AsyncTwi *) pTwid->pTransfer;
+ unsigned int timeout;
+
+ //TRACE_DEBUG("TWID_Read()\n\r");
+ SANITY_CHECK(pTwid);
+ SANITY_CHECK((address & 0x80) == 0);
+ SANITY_CHECK((iaddress & 0xFF000000) == 0);
+ SANITY_CHECK(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, AT91C_TWI_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) && (++timeout<TWITIMEOUTMAX) );
+ if (timeout == TWITIMEOUTMAX) {
+ TRACE_ERROR("TWID Timeout BR\n\r");
+ return TWID_ERROR_TIMEOUT;
+ }
+ *pData++ = TWI_ReadByte(pTwi);
+ num--;
+ }
+
+ // Wait for transfer to be complete
+ timeout = 0;
+ while( !TWI_TransferComplete(pTwi) && (++timeout<TWITIMEOUTMAX) );
+ if (timeout == TWITIMEOUTMAX) {
+ TRACE_ERROR("TWID Timeout TC\n\r");
+ return TWID_ERROR_TIMEOUT;
+ }
+ }
+
+ return 0;
+}
+
+//------------------------------------------------------------------------------
+/// Asynchronously sends data to a slave on the TWI bus. An optional callback
+/// function is invoked whenever the transfer is complete.
+/// \param pTwid Pointer to a Twid instance.
+/// \param address Slave address.
+/// \param iaddress Optional slave internal address.
+/// \param isize Number of internal address bytes.
+/// \param pData Data buffer to send.
+/// \param num Number of bytes to send.
+/// \param pAsync Pointer to an Asynchronous transfer descriptor.
+//------------------------------------------------------------------------------
+unsigned char TWID_Write(
+ Twid *pTwid,
+ unsigned char address,
+ unsigned int iaddress,
+ unsigned char isize,
+ unsigned char *pData,
+ unsigned int num,
+ Async *pAsync)
+{
+ AT91S_TWI *pTwi = pTwid->pTwi;
+ AsyncTwi *pTransfer = (AsyncTwi *) pTwid->pTransfer;
+ unsigned int timeout;
+
+ //TRACE_DEBUG("TWID_Write()\n\r");
+ //TRACE_DEBUG("0x%X\n\r", pData[0]);
+ SANITY_CHECK(pTwi);
+ SANITY_CHECK((address & 0x80) == 0);
+ SANITY_CHECK((iaddress & 0xFF000000) == 0);
+ SANITY_CHECK(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, AT91C_TWI_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<TWITIMEOUTMAX) );
+ if (timeout == TWITIMEOUTMAX) {
+ TRACE_ERROR("TWID Timeout BS\n\r");
+ return TWID_ERROR_TIMEOUT;
+ }
+
+ TWI_WriteByte(pTwi, *pData++);
+ num--;
+ }
+
+ // Wait for actual end of transfer
+ timeout = 0;
+
+#ifdef TWI_V3XX
+ // Send a STOP condition
+ TWI_SendSTOPCondition(pTwi);
+#endif
+
+ while( !TWI_TransferComplete(pTwi) && (++timeout<TWITIMEOUTMAX) );
+ if (timeout == TWITIMEOUTMAX) {
+ TRACE_ERROR("TWID Timeout TC2\n\r");
+ return TWID_ERROR_TIMEOUT;
+ }
+
+ }
+
+ return 0;
+}
+
diff --git a/drivers/twi/twid.h b/drivers/twi/twid.h
new file mode 100644
index 0000000..c2a708e
--- /dev/null
+++ b/drivers/twi/twid.h
@@ -0,0 +1,92 @@
+/* ----------------------------------------------------------------------------
+ * 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.
+ * ----------------------------------------------------------------------------
+ */
+
+#ifndef TWID_H
+#define TWID_H
+
+//------------------------------------------------------------------------------
+// Headers
+//------------------------------------------------------------------------------
+
+#include <board.h>
+#include <drivers/async/async.h>
+
+//------------------------------------------------------------------------------
+// Global definitions
+//------------------------------------------------------------------------------
+
+/// TWI driver is currently busy.
+#define TWID_ERROR_BUSY 1
+/// TWI driver operation timeout.
+#define TWID_ERROR_TIMEOUT 2
+
+//------------------------------------------------------------------------------
+// Global types
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// TWI driver structure. Holds the internal state of the driver.
+//------------------------------------------------------------------------------
+typedef struct _Twid {
+
+ /// Pointer to the underlying TWI peripheral.
+ AT91S_TWI *pTwi;
+ /// Current asynchronous transfer being processed.
+ Async *pTransfer;
+
+} Twid;
+
+//------------------------------------------------------------------------------
+// Global functions
+//------------------------------------------------------------------------------
+
+extern void TWID_Initialize(Twid *pTwid, AT91S_TWI *pTwi);
+
+extern void TWID_Handler(Twid *pTwid);
+
+extern unsigned char TWID_Read(
+ Twid *pTwid,
+ unsigned char address,
+ unsigned int iaddress,
+ unsigned char isize,
+ unsigned char *pData,
+ unsigned int num,
+ Async *pAsync);
+
+extern unsigned char TWID_Write(
+ Twid *pTwid,
+ unsigned char address,
+ unsigned int iaddress,
+ unsigned char isize,
+ unsigned char *pData,
+ unsigned int num,
+ Async *pAsync);
+
+#endif //#ifndef TWID_H
+
personal git repositories of Harald Welte. Your mileage may vary