summaryrefslogtreecommitdiff
path: root/utility
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 /utility
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 'utility')
-rw-r--r--utility/assert.h114
-rw-r--r--utility/bmp.c325
-rw-r--r--utility/bmp.h130
-rw-r--r--utility/clock.c289
-rw-r--r--utility/clock.h47
-rw-r--r--utility/demo-fw/commands/cmd_dhry.c479
-rw-r--r--utility/demo-fw/commands/cmd_slidepage.c67
-rw-r--r--utility/demo-fw/commands/cmd_slideshow.c284
-rw-r--r--utility/demo-fw/common/dfm_accelerometer.c647
-rw-r--r--utility/demo-fw/common/dfm_button.c248
-rw-r--r--utility/demo-fw/common/dfm_cmd.c880
-rw-r--r--utility/demo-fw/common/dfm_console.c216
-rw-r--r--utility/demo-fw/common/dfm_dispboxmgr.c481
-rw-r--r--utility/demo-fw/common/dfm_entry.c142
-rw-r--r--utility/demo-fw/common/dfm_fatfs.c384
-rw-r--r--utility/demo-fw/common/dfm_init.c118
-rw-r--r--utility/demo-fw/common/dfm_it.c638
-rw-r--r--utility/demo-fw/common/dfm_lcd_tsd.c1040
-rw-r--r--utility/demo-fw/include/DemobinHeader.h107
-rw-r--r--utility/demo-fw/include/dfm_accelerometer.h93
-rw-r--r--utility/demo-fw/include/dfm_button.h49
-rw-r--r--utility/demo-fw/include/dfm_cmd.h136
-rw-r--r--utility/demo-fw/include/dfm_config.h38
-rw-r--r--utility/demo-fw/include/dfm_console.h55
-rw-r--r--utility/demo-fw/include/dfm_dispboxmgr.h125
-rw-r--r--utility/demo-fw/include/dfm_entry.h67
-rw-r--r--utility/demo-fw/include/dfm_fatfs.h96
-rw-r--r--utility/demo-fw/include/dfm_init.h70
-rw-r--r--utility/demo-fw/include/dfm_it.h47
-rw-r--r--utility/demo-fw/include/dfm_lcd_tsd.h77
-rw-r--r--utility/demo-fw/include/dfm_varloc.h49
-rw-r--r--utility/demo-fw/include/fatfs_config.h220
-rw-r--r--utility/demo-fw/pc-tools/CreateDemoBin/Makefile69
-rw-r--r--utility/demo-fw/pc-tools/CreateDemoBin/Module1.bas350
-rw-r--r--utility/demo-fw/pc-tools/CreateDemoBin/PPT/CreateDemoBinH.bat2
-rw-r--r--utility/demo-fw/pc-tools/CreateDemoBin/PPT/CreateDemoBinIFlash.bat2
-rw-r--r--utility/demo-fw/pc-tools/CreateDemoBin/PPT/CreatelDemoBinV.bat2
-rw-r--r--utility/demo-fw/pc-tools/CreateDemoBin/PPT/DEMOBINFLASH1.binbin0 -> 78822 bytes
-rw-r--r--utility/demo-fw/pc-tools/CreateDemoBin/PPT/DEMOBINFLASH1.pptbin0 -> 125952 bytes
-rw-r--r--utility/demo-fw/pc-tools/CreateDemoBin/PPT/Module1.bas350
-rw-r--r--utility/demo-fw/pc-tools/CreateDemoBin/PPT/SAM3U_MarCom.pptbin0 -> 2458112 bytes
-rw-r--r--utility/demo-fw/pc-tools/CreateDemoBin/PPT/Sam3DEMO.binbin0 -> 5101618 bytes
-rw-r--r--utility/demo-fw/pc-tools/CreateDemoBin/PPT/Sam3DEMO.pptbin0 -> 1574400 bytes
-rw-r--r--utility/demo-fw/pc-tools/CreateDemoBin/PPT/SamDEMOV.binbin0 -> 5101618 bytes
-rw-r--r--utility/demo-fw/pc-tools/CreateDemoBin/PPT/SamDEMOV.pptbin0 -> 2018304 bytes
-rw-r--r--utility/demo-fw/pc-tools/CreateDemoBin/bin/CreateDemoBin.exebin0 -> 942615 bytes
-rw-r--r--utility/demo-fw/pc-tools/CreateDemoBin/bin/CreateMovieBin.exebin0 -> 940567 bytes
-rw-r--r--utility/demo-fw/pc-tools/CreateDemoBin/include/CreateDemoBin.h96
-rw-r--r--utility/demo-fw/pc-tools/CreateDemoBin/include/DemoBinHeader.h82
-rw-r--r--utility/demo-fw/pc-tools/CreateDemoBin/include/ScriptParse.h103
-rw-r--r--utility/demo-fw/pc-tools/CreateDemoBin/include/profile.h22
-rw-r--r--utility/demo-fw/pc-tools/CreateDemoBin/include/regex.h556
-rw-r--r--utility/demo-fw/pc-tools/CreateDemoBin/lib/EasyBMP/BSD_(revised)_license.txt10
-rw-r--r--utility/demo-fw/pc-tools/CreateDemoBin/lib/EasyBMP/EasyBMP.cpp1917
-rw-r--r--utility/demo-fw/pc-tools/CreateDemoBin/lib/EasyBMP/EasyBMP.h86
-rw-r--r--utility/demo-fw/pc-tools/CreateDemoBin/lib/EasyBMP/EasyBMP_BMP.h86
-rw-r--r--utility/demo-fw/pc-tools/CreateDemoBin/lib/EasyBMP/EasyBMP_ChangeLog.txt821
-rw-r--r--utility/demo-fw/pc-tools/CreateDemoBin/lib/EasyBMP/EasyBMP_DataStructures.h104
-rw-r--r--utility/demo-fw/pc-tools/CreateDemoBin/lib/EasyBMP/EasyBMP_VariousBMPutilities.h53
-rw-r--r--utility/demo-fw/pc-tools/CreateDemoBin/lib/EasyBMP/sample/EasyBMPbackground.bmpbin0 -> 308278 bytes
-rw-r--r--utility/demo-fw/pc-tools/CreateDemoBin/lib/EasyBMP/sample/EasyBMPsample.cpp82
-rw-r--r--utility/demo-fw/pc-tools/CreateDemoBin/lib/EasyBMP/sample/EasyBMPtext.bmpbin0 -> 113266 bytes
-rw-r--r--utility/demo-fw/pc-tools/CreateDemoBin/lib/EasyBMP/sample/makefile53
-rw-r--r--utility/demo-fw/pc-tools/CreateDemoBin/lib/libregex.abin0 -> 182428 bytes
-rw-r--r--utility/demo-fw/pc-tools/CreateDemoBin/readme.txt109
-rw-r--r--utility/demo-fw/pc-tools/CreateDemoBin/src/CreateDemoBin.cpp1102
-rw-r--r--utility/demo-fw/pc-tools/CreateDemoBin/src/ScriptParse.cpp851
-rw-r--r--utility/demo-fw/pc-tools/CreateDemoBin/src/main.cpp268
-rw-r--r--utility/encryption/aes_hardware.c391
-rw-r--r--utility/encryption/aes_hardware.h101
-rw-r--r--utility/encryption/aes_reference.c801
-rw-r--r--utility/encryption/aes_reference.h132
-rw-r--r--utility/encryption/encryption.h98
-rw-r--r--utility/encryption/libtomcrypt.c445
-rw-r--r--utility/encryption/libtomcrypt.h149
-rw-r--r--utility/encryption/tdes_hardware.c433
-rw-r--r--utility/encryption/tdes_hardware.h115
-rw-r--r--utility/hamming.c335
-rw-r--r--utility/hamming.h72
-rw-r--r--utility/iap.c98
-rw-r--r--utility/iap.h51
-rw-r--r--utility/led.c162
-rw-r--r--utility/led.h70
-rw-r--r--utility/math.c91
-rw-r--r--utility/math.h41
-rw-r--r--utility/rand.c58
-rw-r--r--utility/rand.h49
-rw-r--r--utility/retarget.c88
-rw-r--r--utility/stdio.c512
-rw-r--r--utility/string.c239
-rw-r--r--utility/trace.c299
-rw-r--r--utility/trace.h352
-rw-r--r--utility/utility.dir50
-rw-r--r--utility/video.c130
-rw-r--r--utility/video.h89
-rw-r--r--utility/wav.c84
-rw-r--r--utility/wav.h84
97 files changed, 20553 insertions, 0 deletions
diff --git a/utility/assert.h b/utility/assert.h
new file mode 100644
index 0000000..5cccb61
--- /dev/null
+++ b/utility/assert.h
@@ -0,0 +1,114 @@
+/* ----------------------------------------------------------------------------
+ * 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
+///
+/// Definition of the ASSERT() and SANITY_CHECK() macros, which are used for
+/// runtime condition & parameter verifying.
+///
+/// !Usage
+///
+/// -# Use ASSERT() in your code to check the value of function parameters,
+/// return values, etc. *Warning:* the ASSERT() condition must not have
+/// any side-effect; otherwise, the program may not work properly
+/// anymore when assertions are disabled.
+/// -# Use SANITY_CHECK() to perform checks with a default error message
+/// (outputs the file and line number where the error occured). This
+/// reduces memory overhead caused by assertion error strings.
+/// -# Initialize the dbgu to see failed assertions at run-time.
+/// -# Assertions can be entirely disabled by defining the NOASSERT symbol
+/// at compilation time.
+//------------------------------------------------------------------------------
+
+#ifndef ASSERT_H
+#define ASSERT_H
+
+//------------------------------------------------------------------------------
+// Headers
+//------------------------------------------------------------------------------
+
+#include <stdio.h>
+#include "trace.h"
+
+//------------------------------------------------------------------------------
+// Definitions
+//------------------------------------------------------------------------------
+#if defined(NOASSERT)
+ #define ASSERT(...)
+ #define SANITY_CHECK(...)
+#else
+
+ #if (TRACE_LEVEL == 0)
+ /// Checks that the given condition is true,
+ /// otherwise stops the program execution.
+ /// \param condition Condition to verify.
+ #define ASSERT(condition, ...) { \
+ if (!(condition)) { \
+ while (1); \
+ } \
+ }
+
+ /// Performs the same duty as the ASSERT() macro
+ /// \param condition Condition to verify.
+ #define SANITY_CHECK(condition) ASSERT(condition, ...)
+
+ #else
+ /// Checks that the given condition is true, otherwise displays an error
+ /// message and stops the program execution.
+ /// \param condition Condition to verify.
+ #define ASSERT(condition, ...) { \
+ if (!(condition)) { \
+ printf("-F- ASSERT: "); \
+ printf(__VA_ARGS__); \
+ while (1); \
+ } \
+ }
+ #define SANITY_ERROR "Sanity check failed at %s:%d\n\r"
+
+ /// Performs the same duty as the ASSERT() macro, except a default error
+ /// message is output if the condition is false.
+ /// \param condition Condition to verify.
+ #define SANITY_CHECK(condition) ASSERT(condition, SANITY_ERROR, __FILE__, __LINE__)
+ #endif
+#endif
+
+
+
+
+
+
+
+
+
+
+#endif //#ifndef ASSERT_H
+
diff --git a/utility/bmp.c b/utility/bmp.c
new file mode 100644
index 0000000..ee4fb34
--- /dev/null
+++ b/utility/bmp.c
@@ -0,0 +1,325 @@
+/* ----------------------------------------------------------------------------
+ * 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 "bmp.h"
+#include <board.h>
+#include <utility/trace.h>
+
+#include <string.h>
+
+//-----------------------------------------------------------------------------
+// Define
+//-----------------------------------------------------------------------------
+/// BMP offset for header
+#define IMAGE_OFFSET 0x100
+
+
+//------------------------------------------------------------------------------
+// Internal constants
+//------------------------------------------------------------------------------
+
+
+//------------------------------------------------------------------------------
+// Internal types
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// Describe the BMP palette
+//------------------------------------------------------------------------------
+struct BMPPaletteEntry {
+
+ /// Blue value
+ unsigned char b;
+ /// Green value
+ unsigned char g;
+ /// Red value
+ unsigned char r;
+ /// Filler character value
+ unsigned char filler;
+};
+
+//------------------------------------------------------------------------------
+// Exported functions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// Test if BMP is valid
+/// \param file Buffer holding the file to examinate.
+/// \return 1 if the header of a BMP file is valid; otherwise returns 0.
+//------------------------------------------------------------------------------
+unsigned char BMP_IsValid(void *file)
+{
+ return ((struct BMPHeader *) file)->type == BMP_TYPE;
+}
+
+//------------------------------------------------------------------------------
+/// Returns the size of a BMP image given at least its header (the file does
+/// not have to be complete).
+/// \param file Pointer to the buffer which holds the BMP file.
+/// \return size of BMP image
+//------------------------------------------------------------------------------
+unsigned int BMP_GetFileSize(void *file)
+{
+ return ((struct BMPHeader *) file)->fileSize;
+}
+
+//-----------------------------------------------------------------------------
+/// Write a BMP header
+/// \param pAddressHeader Begin address of the BMP
+/// \param bmpHSize BMP heigth size
+/// \param bmpVSize BMP width size
+/// \param bmpRgb Type of BMP (YUV or RGB)
+/// \param nbByte_Pixels Number of byte per pixels
+//-----------------------------------------------------------------------------
+void WriteBMPheader(unsigned int* pAddressHeader,
+ unsigned int bmpHSize,
+ unsigned int bmpVSize,
+ unsigned char bmpRgb,
+ unsigned char nbByte_Pixels)
+{
+ unsigned int i;
+ unsigned int* fill;
+ struct BMPHeader *Header;
+
+ fill = pAddressHeader;
+ for (i=0; i<IMAGE_OFFSET; i+=4) {
+ *fill++ = 0;
+ }
+
+ Header = (struct BMPHeader*) pAddressHeader;
+
+ Header->type = BMP_TYPE;
+ Header->fileSize = (bmpHSize * bmpVSize * nbByte_Pixels) + IMAGE_OFFSET;
+ Header->reserved1 = 0;
+ Header->reserved2 = 0;
+ Header->offset = IMAGE_OFFSET;
+ Header->headerSize = BITMAPINFOHEADER;
+ Header->width = bmpHSize;
+ Header->height = bmpVSize;
+ Header->planes = 1;
+ Header->bits = nbByte_Pixels * 8;
+ Header->compression = 0;
+ Header->imageSize = bmpHSize * bmpVSize * nbByte_Pixels;
+ Header->xresolution = 0;
+ Header->yresolution = 0;
+ Header->ncolours = 0;
+ Header->importantcolours = 0;
+}
+
+
+//------------------------------------------------------------------------------
+/// debug function, dislay BMP header
+/// \param pAddressHeader Address of the BMP
+//------------------------------------------------------------------------------
+void BMP_displayHeader(unsigned int* pAddressHeader)
+{
+ struct BMPHeader *header;
+
+ header = (struct BMPHeader*) pAddressHeader;
+
+ TRACE_INFO("BMP\n\r");
+ TRACE_INFO("type 0x%X \n\r", header->type);
+ TRACE_INFO("fileSize %d \n\r", header->fileSize);
+ TRACE_INFO("reserved1 %d \n\r", header->reserved1);
+ TRACE_INFO("reserved2 %d \n\r", header->reserved2);
+ TRACE_INFO("offset %d \n\r", header->offset);
+ TRACE_INFO("headerSize %d \n\r", header->headerSize);
+ TRACE_INFO("width %d \n\r", header->width);
+ TRACE_INFO("height %d \n\r", header->height);
+ TRACE_INFO("planes %d \n\r", header->planes);
+ TRACE_INFO("bits %d \n\r", header->bits);
+ TRACE_INFO("compression %d \n\r", header->compression);
+ TRACE_INFO("imageSize %d \n\r", header->imageSize);
+ TRACE_INFO("xresolution %d \n\r", header->xresolution);
+ TRACE_INFO("yresolution %d \n\r", header->yresolution);
+ TRACE_INFO("ncolours %d \n\r", header->ncolours);
+ TRACE_INFO("importantcolours %d\n\r", header->importantcolours);
+}
+
+
+//------------------------------------------------------------------------------
+/// Loads a BMP image located at the given address, decodes it and stores the
+/// resulting image inside the provided buffer. Image must have the specified
+/// width & height.
+/// If no buffer is provided, this function simply checks if it is able to
+/// decode the image.
+/// \param file Buffer which holds the BMP file.
+/// \param buffer Buffer in which to store the decoded image.
+/// \param width Buffer width in pixels.
+/// \param height Buffer height in pixels.
+/// \param bpp Number of bits per pixels that the buffer stores.
+/// \return 0 if the image has been loaded; otherwise returns an error code.
+//------------------------------------------------------------------------------
+unsigned char BMP_Decode(
+ void *file,
+ unsigned char *buffer,
+ unsigned int width,
+ unsigned int height,
+ unsigned char bpp)
+{
+ struct BMPHeader *header;
+ unsigned int i, j;
+ unsigned char r, g, b;
+ unsigned char *image;
+
+ // Read header information
+ header = (struct BMPHeader *) file;
+
+ // Verify that the file is valid
+ if (!BMP_IsValid(file)) {
+
+ TRACE_ERROR("BMP_Decode: File type is not 'BM' (0x%04X).\n\r",header->type);
+ return 1;
+ }
+
+ // Check that parameters match
+ if ((header->compression != 0)
+ || (header->width != width)
+ || (header->height != height)) {
+
+ TRACE_ERROR("BMP_Decode: File format not supported\n\r");
+ TRACE_ERROR(" -> .compression = %u\n\r", header->compression);
+ TRACE_ERROR(" -> .width = %u\n\r", header->width);
+ TRACE_ERROR(" -> .height = %u\n\r", header->height);
+ TRACE_ERROR(" -> .bits = %d\n\r", header->bits);
+ return 2;
+ }
+
+ // Get image data
+ image = (unsigned char *) ((unsigned int) file + header->offset);
+
+ // Check that the bpp resolution is supported
+ // Only a 24-bit output & 24- or 8-bit input are supported
+ if (bpp != 24) {
+
+ TRACE_ERROR("BMP_Decode: Output resolution not supported\n\r");
+ return 3;
+ }
+ else if (header->bits == 24) {
+
+ // Decoding is ok
+ if (!buffer) return 0;
+
+ // Get image data (swapping red & blue)
+ for (i=0; i < height; i++) {
+ for (j=0; j < width; j++) {
+
+ r = image[((height - i - 1) * width + j) * 3 + 2];
+ g = image[((height - i - 1) * width + j) * 3 + 1];
+ b = image[((height - i - 1) * width + j) * 3];
+
+#if defined(BOARD_LCD_RGB565)
+ // Interlacing
+ r = ((r << 1) & 0xF0) | ((g & 0x80) >> 4) | ((r & 0x80) >> 5);
+ g = (g << 1) & 0xF8;
+ b = b & 0xF8;
+
+ buffer[(i * width + j) * 3] = b;
+ buffer[(i * width + j) * 3 + 1] = g;
+ buffer[(i * width + j) * 3 + 2] = r;
+#elif defined(BOARD_LCD_BGR565)
+ buffer[(i * width + j) * 3] = b;
+ buffer[(i * width + j) * 3 + 1] = g;
+ buffer[(i * width + j) * 3 + 2] = r;
+#else
+ buffer[(i * width + j) * 3] = r;
+ buffer[(i * width + j) * 3 + 1] = g;
+ buffer[(i * width + j) * 3 + 2] = b;
+#endif //#if defined(BOARD_LCD_RGB565)
+ }
+ }
+ }
+ else if (header->bits == 8) {
+
+ // Decoding is ok
+ if (!buffer) return 0;
+
+ // Retrieve palette
+ struct BMPPaletteEntry palette[256];
+ memcpy(palette,
+ (unsigned char *) ((unsigned int) file + sizeof(struct BMPHeader)),
+ header->offset - sizeof(struct BMPHeader));
+
+ // Decode image (reversing row order)
+ for (i=0; i < height; i++) {
+ for (j=0; j < width; j++) {
+
+ r = palette[image[(height - i - 1) * width + j]].r;
+ g = palette[image[(height - i - 1) * width + j]].g;
+ b = palette[image[(height - i - 1) * width + j]].b;
+
+ buffer[(i * width + j) * 3] = r;
+ buffer[(i * width + j) * 3 + 1] = g;
+ buffer[(i * width + j) * 3 + 2] = b;
+ }
+ }
+ }
+ else {
+
+ TRACE_ERROR("BMP_Decode: Input resolution not supported\n\r");
+ TRACE_INFO("header->bits 0x%X \n\r", header->bits);
+ return 4;
+ }
+
+ return 0;
+}
+
+//------------------------------------------------------------------------------
+/// Convert RGB 565 to RGB 555 (RGB 555 is adapted to LCD)
+/// \param fileSource Buffer which holds the RGB file
+/// \param fileDestination Buffer in which to store the decoded image
+/// \param width Buffer width in pixels.
+/// \param height Buffer height in pixels.
+/// \param bpp Number of bits per pixels that the buffer stores.
+//------------------------------------------------------------------------------
+void RGB565toBGR555(
+ unsigned char *fileSource,
+ unsigned char *fileDestination,
+ unsigned int width,
+ unsigned int height,
+ unsigned char bpp)
+{
+ unsigned int i;
+ unsigned int j;
+ unsigned int row;
+
+ for (i=0; i < height*(bpp/8); i++) {
+ row = (i*width*(bpp/8));
+ for (j=0; j <= width*(bpp/8); j+=2) {
+ fileDestination[row+j] = ((fileSource[row+j+1]>>3)&0x1F)
+ | (fileSource[row+j]&0xE0);
+ fileDestination[row+j+1] = (fileSource[row+j+1]&0x03)
+ | ((fileSource[row+j]&0x1F)<<2);
+ }
+ }
+}
diff --git a/utility/bmp.h b/utility/bmp.h
new file mode 100644
index 0000000..6adfac3
--- /dev/null
+++ b/utility/bmp.h
@@ -0,0 +1,130 @@
+/* ----------------------------------------------------------------------------
+ * 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
+///
+/// Utility for BMP
+///
+//------------------------------------------------------------------------------
+
+#ifndef BMP_H
+#define BMP_H
+
+/// BMP magic number ('BM').
+#define BMP_TYPE 0x4D42
+
+/// headerSize must be set to 40
+#define BITMAPINFOHEADER 40
+
+//------------------------------------------------------------------------------
+// Exported types
+//------------------------------------------------------------------------------
+
+#ifdef __ICCARM__ // IAR
+#pragma pack(1) // IAR
+#define __attribute__(...) // IAR
+#endif // IAR
+
+// BMP (Windows) Header Format
+struct BMPHeader {
+ /// signature, must be 4D42 hex
+ unsigned short type;
+ /// size of BMP file in bytes (unreliable)
+ unsigned int fileSize;
+ /// reserved, must be zero
+ unsigned short reserved1;
+ /// reserved, must be zero
+ unsigned short reserved2;
+ /// offset to start of image data in bytes
+ unsigned int offset;
+ /// size of BITMAPINFOHEADER structure, must be 40
+ unsigned int headerSize;
+ /// image width in pixels
+ unsigned int width;
+ /// image height in pixels
+ unsigned int height;
+ /// number of planes in the image, must be 1
+ unsigned short planes;
+ /// number of bits per pixel (1, 4, 8, 16, 24, 32)
+ unsigned short bits;
+ /// compression type (0=none, 1=RLE-8, 2=RLE-4)
+ unsigned int compression;
+ /// size of image data in bytes (including padding)
+ unsigned int imageSize;
+ /// horizontal resolution in pixels per meter (unreliable)
+ unsigned int xresolution;
+ /// vertical resolution in pixels per meter (unreliable)
+ unsigned int yresolution;
+ /// number of colors in image, or zero
+ unsigned int ncolours;
+ /// number of important colors, or zero
+ unsigned int importantcolours;
+
+} __attribute__ ((packed)); // GCC
+
+#ifdef __ICCARM__ // IAR
+#pragma pack() // IAR
+#endif // IAR
+
+//------------------------------------------------------------------------------
+// Exported functions
+//------------------------------------------------------------------------------
+
+extern unsigned char BMP_IsValid(void *file);
+
+extern unsigned int BMP_GetFileSize(void *file);
+
+extern unsigned char BMP_Decode(
+ void *file,
+ unsigned char *buffer,
+ unsigned int width,
+ unsigned int height,
+ unsigned char bpp);
+
+extern void WriteBMPheader(unsigned int* pAddressHeader,
+ unsigned int bmpHSize,
+ unsigned int bmpVSize,
+ unsigned char bmpRgb,
+ unsigned char nbByte_Pixels);
+
+extern void BMP_displayHeader(unsigned int* pAddressHeader);
+
+extern void RGB565toBGR555(
+ unsigned char *fileSource,
+ unsigned char *fileDestination,
+ unsigned int width,
+ unsigned int height,
+ unsigned char bpp);
+
+
+#endif //#ifndef BMP_H
+
diff --git a/utility/clock.c b/utility/clock.c
new file mode 100644
index 0000000..830cb61
--- /dev/null
+++ b/utility/clock.c
@@ -0,0 +1,289 @@
+/* ----------------------------------------------------------------------------
+ * 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 "clock.h"
+#include <board.h>
+#include <utility/trace.h>
+
+//------------------------------------------------------------------------------
+// Internal types
+//------------------------------------------------------------------------------
+int currentConfig = 0; // 0 have to be the default configuration
+
+//------------------------------------------------------------------------------
+/// Describes a possible clock configuration (processor clock & master clock),
+/// including the necessary register values.
+//------------------------------------------------------------------------------
+struct ClockConfiguration {
+
+ /// Processor clock frequency (in MHz).
+ unsigned short pck;
+ /// Master clock frequency (in MHz).
+ unsigned short mck;
+ /// CKGR_PLL reqister value.
+ unsigned int pllr;
+ /// PMC_MCKR register value.
+ unsigned int mckr;
+};
+
+//------------------------------------------------------------------------------
+// Internal variables
+//------------------------------------------------------------------------------
+
+// Clock configurations for the AT91SAM9263-EK
+#if defined(at91sam9263)
+
+#define AT91C_CKGR_PLLR AT91C_CKGR_PLLAR
+#define AT91C_PMC_LOCK AT91C_PMC_LOCKA
+
+static const struct ClockConfiguration clockConfigurations[] = {
+ // PCK = 200 MHz, MCK = 100 MHz
+ {200, 100, 0x206DBF09, 0x00000102},
+ // PCK = 240 MHz, MCK = 120 MHz
+ {240, 120, 0x202BC003, 0x00000102},
+ // PCK = 120 MHz, MCK = 120 MHz
+ {120, 120, 0x20156003, 0x00000002},
+ // PCK = 96 MHz, MCK = 48 MHz
+ {96, 48, 0x2057400F, 0x00000102},
+ // PCK = 48 MHz, MCK = 48 MHz
+ {48, 48, 0x2057400F, 0x00000006}
+};
+
+// Clock configurations for the AT91SAM9G20-EK
+#elif defined(at91sam9g20)
+
+#define AT91C_CKGR_PLLR AT91C_CKGR_PLLAR
+#define AT91C_PMC_LOCK AT91C_PMC_LOCKA
+
+static const struct ClockConfiguration clockConfigurations[] = {
+
+ // PCK = 400 MHz, MCK = 133 MHz
+ {400, 133, 0x202A0101, 0x00001302},
+ // PCK = 200 MHz, MCK = 100 MHz
+ {200, 100, 0x202A3F01, 0x0000010A},
+ // PCK = 96 MHz, MCK = 48 MHz
+ {96, 48, 0x207C3F03, 0x0000010E},
+ // PCK = 48 MHz, MCK = 48 MHz
+ {48, 48, 0x207C3F03, 0x00000012}
+};
+
+// Clock configurations for the AT91SAM9XE-EK, AT91SAM9261-EK
+#elif defined(at91sam9xe128) || \
+ defined(at91sam9xe256) || \
+ defined(at91sam9xe512) || \
+ defined(at91sam9261)
+
+#define AT91C_CKGR_PLLR AT91C_CKGR_PLLAR
+#define AT91C_PMC_LOCK AT91C_PMC_LOCKA
+
+static const struct ClockConfiguration clockConfigurations[] = {
+
+ // PCK = 200 MHz, MCK = 100 MHz
+ {200, 100, 0x208CBF0D, 0x00000102},
+ // PCK = 100 MHz, MCK = 100 MHz
+ {100, 100, 0x20273F07, 0x00000002},
+ // PCK = 96 MHz, MCK = 48 MHz
+ {96, 48, 0x20483F0E, 0x00000102},
+ // PCK = 48 MHz, MCK = 48 MHz
+ {48, 48, 0x20483F0E, 0x00000006}
+};
+
+// Clock configurations for the AT91SAM9RL64-EK, AT91CAP9-DK, AT91CAP9-STK
+#elif defined(at91sam9rl64) || \
+ defined(at91cap9)
+
+#define AT91C_CKGR_PLLR AT91C_CKGR_PLLAR
+#define AT91C_PMC_LOCK AT91C_PMC_LOCKA
+
+static const struct ClockConfiguration clockConfigurations[] = {
+
+ // PCK = 200 MHz, MCK = 100 MHz
+ {200, 100, 0x2031BF03, 0x00000102},
+ // PCK = 100 MHz, MCK = 100 MHz
+ {100, 100, 0x20183F03, 0x00000002},
+ // PCK = 96 MHz, MCK = 48 MHz
+ {96, 48, 0x20073F01, 0x00000102},
+ // PCK = 48 MHz, MCK = 48 MHz
+ {48, 48, 0x20073F01, 0x00000006}
+};
+
+// Clock configuration for the AT91SAM7X-EK, AT91SAM7S-EK, AT91SAM7SE-EK
+#elif defined(at91sam7x128) || defined(at91sam7x256) || defined(at91sam7x512) \
+ || defined(at91sam7xc128) || defined(at91sam7xc256) || defined(at91sam7xc512) \
+ || defined(at91sam7s16) || defined(at91sam7s161) || defined(at91sam7s32) \
+ || defined(at91sam7s321) || defined(at91sam7s64) || defined(at91sam7s128) \
+ || defined(at91sam7s256) || defined(at91sam7s512) || defined(at91sam7se32) \
+ || defined(at91sam7se256) || defined(at91sam7se512)
+
+static const struct ClockConfiguration clockConfigurations[] = {
+
+ // PCK = 55 MHz, MCK = 55 MHz
+ {55, 55, 0x006A3F12, 0x00000007},
+ // PCK = 48 MHz, MCK = 48 MHz
+ {48, 48, 0x00483F0E, 0x00000007},
+};
+
+// Clock configuration for the AT91SAM7A3
+#elif defined(at91sam7a3)
+
+static const struct ClockConfiguration clockConfigurations[] = {
+
+ // PCK = 60 MHz, MCK = 60 MHz
+ {60, 60, 0x000C3F02, 0x00000007},
+ // PCK = 48 MHz, MCK = 48 MHz
+ {48, 48, 0x00483F0E, 0x00000007}
+};
+
+// Clock configurations for the AT91SAM9XE-EK, AT91SAM9261-EK
+ #elif defined(at91sam9g10)
+
+#define AT91C_CKGR_PLLR AT91C_CKGR_PLLAR
+#define AT91C_PMC_LOCK AT91C_PMC_LOCKA
+
+static const struct ClockConfiguration clockConfigurations[] = {
+ // PCK = 266 MHz, MCK = 133 MHz
+ {266, 133, 0x2064BF07, 0x00000102},
+ // PCK = 100 MHz, MCK = 100 MHz
+ {100, 100, 0x20273F07, 0x00000002},
+ // PCK = 96 MHz, MCK = 48 MHz
+ {96, 48, 0x20483F0E, 0x00000102},
+ // PCK = 48 MHz, MCK = 48 MHz
+ {48, 48, 0x20483F0E, 0x00000006}
+ };
+
+// Clock configuration for the AT91SAM3U
+#elif defined(at91sam3u)
+
+static const struct ClockConfiguration clockConfigurations[] = {
+
+ // PCK = 48 MHz, MCK = 48 MHz (default)
+ {48, 48, 0x20073f01, 0x00000012},
+ // PCK = 96 MHz, MCK = 96 MHz
+ {96, 96, 0x20073f01, 0x00000002},
+ // PCK = 24 MHz, MCK = 24 MHz
+ {24, 24, 0x20073f02, 0x00000012}
+};
+
+// No clock configuration
+#else
+ #error No clock configuration for this board.
+#endif
+
+/// Number of available clock configurations
+#define NB_CLOCK_CONFIGURATION (sizeof(clockConfigurations)/sizeof(clockConfigurations[0]))
+
+//------------------------------------------------------------------------------
+// Global Functions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// Sets the specified clock configuration.
+/// \param configuration Index of the configuration to set.
+//------------------------------------------------------------------------------
+void CLOCK_SetConfig(unsigned char configuration)
+{
+ TRACE_DEBUG("Setting clock configuration #%d ... ", configuration);
+ currentConfig = configuration;
+
+ // Switch to main oscillator in two operations
+ AT91C_BASE_PMC->PMC_MCKR = (AT91C_BASE_PMC->PMC_MCKR & ~AT91C_PMC_CSS) | AT91C_PMC_CSS_MAIN_CLK;
+ while ((AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY) == 0);
+
+ // Configure PLL
+ *AT91C_CKGR_PLLAR = clockConfigurations[configuration].pllr;
+ while ((AT91C_BASE_PMC->PMC_SR & AT91C_PMC_LOCKA) == 0);
+
+ // Configure master clock in two operations
+ AT91C_BASE_PMC->PMC_MCKR = (clockConfigurations[configuration].mckr & ~AT91C_PMC_CSS) | AT91C_PMC_CSS_MAIN_CLK;
+ while ((AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY) == 0);
+ AT91C_BASE_PMC->PMC_MCKR = clockConfigurations[configuration].mckr;
+ while ((AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY) == 0);
+
+ // DBGU reconfiguration
+ DBGU_Configure(DBGU_STANDARD, 115200, clockConfigurations[configuration].mck*1000000);
+ TRACE_DEBUG("done.\n\r");
+}
+
+//------------------------------------------------------------------------------
+/// Display the user menu on the DBGU.
+//------------------------------------------------------------------------------
+void CLOCK_DisplayMenu(void)
+{
+ unsigned int i;
+
+ printf("\n\rMenu Clock configuration:\n\r");
+ for (i = 0; i < NB_CLOCK_CONFIGURATION; i++) {
+
+ printf(" %d: Set PCK = %3d MHz, MCK = %3d MHz %s\n\r",
+ i,
+ clockConfigurations[i].pck,
+ clockConfigurations[i].mck,
+ (currentConfig==i)?"(curr)":"");
+ }
+}
+
+//------------------------------------------------------------------------------
+/// Get the current MCK
+//------------------------------------------------------------------------------
+unsigned short CLOCK_GetCurrMCK(void)
+{
+ return clockConfigurations[currentConfig].mck;
+}
+
+//------------------------------------------------------------------------------
+/// Get the current PCK
+//------------------------------------------------------------------------------
+unsigned short CLOCK_GetCurrPCK(void)
+{
+ return clockConfigurations[currentConfig].pck;
+}
+
+//------------------------------------------------------------------------------
+/// Change clock configuration.
+//------------------------------------------------------------------------------
+void CLOCK_UserChangeConfig(void)
+{
+ unsigned char key = 0;
+
+ while (1)
+ {
+ CLOCK_DisplayMenu();
+ key = DBGU_GetChar();
+
+ if ((key >= '0') && (key <= ('0' + NB_CLOCK_CONFIGURATION - 1)))
+ {
+ CLOCK_SetConfig(key - '0');
+ break;
+ }
+ }
+} \ No newline at end of file
diff --git a/utility/clock.h b/utility/clock.h
new file mode 100644
index 0000000..976f8e9
--- /dev/null
+++ b/utility/clock.h
@@ -0,0 +1,47 @@
+/* ----------------------------------------------------------------------------
+ * 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 CLOCK_H
+#define CLOCK_H
+
+//------------------------------------------------------------------------------
+// Global Functions
+//------------------------------------------------------------------------------
+
+extern void CLOCK_SetConfig(unsigned char configuration);
+
+extern void CLOCK_DisplayMenu(void);
+
+extern void CLOCK_UserChangeConfig(void);
+
+extern unsigned short CLOCK_GetCurrMCK(void);
+
+extern unsigned short CLOCK_GetCurrPCK(void);
+
+#endif //#ifndef FREQCONF_H
diff --git a/utility/demo-fw/commands/cmd_dhry.c b/utility/demo-fw/commands/cmd_dhry.c
new file mode 100644
index 0000000..958652b
--- /dev/null
+++ b/utility/demo-fw/commands/cmd_dhry.c
@@ -0,0 +1,479 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ----------------------------------------------------------------------------
+ */
+
+//------------------------------------------------------------------------------
+// Headers
+//------------------------------------------------------------------------------
+
+#include <board.h>
+#include <rtt/rtt.h>
+#include <pio/pio.h>
+#include <dbgu/dbgu.h>
+#include <utility/trace.h>
+#include <cp15/cp15.h>
+#include <stdio.h>
+#include <utility/assert.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include "dfm_cmd.h"
+#include "dfm_init.h"
+#include "dfm_fatfs.h"
+#include "dfm_dispboxmgr.h"
+
+//------------------------------------------------------------------------------
+// Local definitions
+//------------------------------------------------------------------------------
+/// Number of consecutive runs of the testloop() function.
+#define NUM_RUNS 25
+
+#if defined (AT91C_IRAM_1)
+#define SRAM_ADDRESS AT91C_IRAM_1
+#define SRAM_SIZE AT91C_IRAM_1_SIZE
+#elif defined(AT91C_IRAM)
+#define SRAM_ADDRESS AT91C_IRAM
+#define SRAM_SIZE AT91C_IRAM_SIZE
+#elif defined(AT91C_ISRAM)
+#define SRAM_ADDRESS AT91C_ISRAM
+#define SRAM_SIZE AT91C_ISRAM_SIZE
+#else
+#error SRAM define
+#endif
+
+//------------------------------------------------------------------------------
+// Imported functions
+//------------------------------------------------------------------------------
+
+extern void DHRY_testloop(int);
+
+//------------------------------------------------------------------------------
+// Internal types
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// Describes a possible clock configuration (processor clock & master clock),
+/// including the necessary register values.
+//------------------------------------------------------------------------------
+struct ClockConfiguration {
+
+ /// Processor clock frequency (in MHz).
+ unsigned short pck;
+ /// Master clock frequency (in MHz).
+ unsigned short mck;
+ /// CKGR_PLL reqister value.
+ unsigned int pllr;
+ /// PMC_MCKR register value.
+ unsigned int mckr;
+};
+
+//------------------------------------------------------------------------------
+// Internal variables
+//------------------------------------------------------------------------------
+
+#define CLKCFGNUM sizeof(clockConfigurations) / sizeof(struct ClockConfiguration)
+
+#if defined(CP15_PRESENT)
+// This base address must be on a 16KB boundary.
+static unsigned char *BufMMU = (unsigned char *) (SRAM_ADDRESS + 0x4000);
+#endif
+
+// Clock configurations for the AT91SAM9263-EK
+#if defined(at91sam9263)
+
+#define AT91C_CKGR_PLLR AT91C_CKGR_PLLAR
+#define AT91C_PMC_LOCK AT91C_PMC_LOCKA
+
+#define AT91C_CKGR_MULA_SHIFT 16
+#define AT91C_CKGR_OUTA_SHIFT 14
+#define AT91C_CKGR_PLLACOUNT_SHIFT 8
+#define AT91C_CKGR_DIVA_SHIFT 0
+
+static const struct ClockConfiguration clockConfigurations[] = {
+
+ // PCK = 240 MHz, MCK = 120 MHz
+ //{240, 120, 0x202BC003, 0x00000102},
+ {240, 120, (AT91C_CKGR_SRCA | (0x2b << AT91C_CKGR_MULA_SHIFT) | (0x3 << AT91C_CKGR_OUTA_SHIFT) \
+ | (0x0 << AT91C_CKGR_PLLACOUNT_SHIFT) | (0x3 << AT91C_CKGR_DIVA_SHIFT)),
+ (AT91C_PMC_MDIV_2 | AT91C_PMC_PRES_CLK | AT91C_PMC_CSS_PLLA_CLK)},
+ // PCK = 120 MHz, MCK = 120 MHz
+ //{120, 120, 0x20156003, 0x00000002},
+ {120, 120, (AT91C_CKGR_SRCA | (0x15 << AT91C_CKGR_MULA_SHIFT) | (0x1 << AT91C_CKGR_OUTA_SHIFT) \
+ | (0x20 << AT91C_CKGR_PLLACOUNT_SHIFT) | (0x3 << AT91C_CKGR_DIVA_SHIFT)),
+ (AT91C_PMC_MDIV_1 | AT91C_PMC_PRES_CLK | AT91C_PMC_CSS_PLLA_CLK)},
+ // PCK = 96 MHz, MCK = 48 MHz
+ //{96, 48, 0x2057400F, 0x00000102},
+ {96, 48, (AT91C_CKGR_SRCA | (0x57 << AT91C_CKGR_MULA_SHIFT) | (0x1 << AT91C_CKGR_OUTA_SHIFT) \
+ | (0x0 << AT91C_CKGR_PLLACOUNT_SHIFT) | (0xf << AT91C_CKGR_DIVA_SHIFT)),
+ (AT91C_PMC_MDIV_2 | AT91C_PMC_PRES_CLK | AT91C_PMC_CSS_PLLA_CLK)},
+ // PCK = 48 MHz, MCK = 48 MHz
+ //{48, 48, 0x2057400F, 0x00000006}
+ {48, 48, (AT91C_CKGR_SRCA | (0x57 << AT91C_CKGR_MULA_SHIFT) | (0x1 << AT91C_CKGR_OUTA_SHIFT) \
+ | (0x0 << AT91C_CKGR_PLLACOUNT_SHIFT) | (0xf << AT91C_CKGR_DIVA_SHIFT)),
+ (AT91C_PMC_MDIV_1 | AT91C_PMC_PRES_CLK_2 | AT91C_PMC_CSS_PLLA_CLK)}
+};
+
+// Clock configurations for the AT91SAM9G20-EK
+#elif defined(at91sam9g20)
+
+#define AT91C_CKGR_PLLR AT91C_CKGR_PLLAR
+#define AT91C_PMC_LOCK AT91C_PMC_LOCKA
+
+#define AT91C_CKGR_MULA_SHIFT 16
+#define AT91C_CKGR_OUTA_SHIFT 14
+#define AT91C_CKGR_PLLACOUNT_SHIFT 8
+#define AT91C_CKGR_DIVA_SHIFT 0
+
+#define AT91_PMC_MCKR_PDIV_SHIFT 12
+
+static const struct ClockConfiguration clockConfigurations[] = {
+
+ // PCK = 400 MHz, MCK = 133 MHz
+ //{400, 133, 0x202A0101, 0x00001302},
+ {400, 133, (AT91C_CKGR_SRCA | (0x2a << AT91C_CKGR_MULA_SHIFT) | (0x0 << AT91C_CKGR_OUTA_SHIFT) \
+ | (0x1 << AT91C_CKGR_PLLACOUNT_SHIFT) | (0x1 << AT91C_CKGR_DIVA_SHIFT)),
+ ((0x1 << AT91_PMC_MCKR_PDIV_SHIFT) | AT91C_PMC_MDIV_3 | AT91C_PMC_PRES_CLK | AT91C_PMC_CSS_PLLA_CLK)},
+ // PCK = 200 MHz, MCK = 100 MHz
+ //{200, 100, 0x202A3F01, 0x0000010A},
+ {200, 100, (AT91C_CKGR_SRCA | (0x2a << AT91C_CKGR_MULA_SHIFT) | (0x0 << AT91C_CKGR_OUTA_SHIFT) \
+ | (0x3f << AT91C_CKGR_PLLACOUNT_SHIFT) | (0x1 << AT91C_CKGR_DIVA_SHIFT)),
+ (AT91C_PMC_MDIV_2 | AT91C_PMC_PRES_CLK_4 | AT91C_PMC_CSS_PLLA_CLK)},
+ // PCK = 96 MHz, MCK = 48 MHz
+ //{96, 48, 0x207C3F03, 0x0000010E},
+ {96, 48, (AT91C_CKGR_SRCA | (0x7c << AT91C_CKGR_MULA_SHIFT) | (0x0 << AT91C_CKGR_OUTA_SHIFT) \
+ | (0x3f << AT91C_CKGR_PLLACOUNT_SHIFT) | (0x3 << AT91C_CKGR_DIVA_SHIFT)),
+ (AT91C_PMC_MDIV_2 | AT91C_PMC_PRES_CLK_8 | AT91C_PMC_CSS_PLLA_CLK)},
+ // PCK = 48 MHz, MCK = 48 MHz
+ //{48, 48, 0x207C3F03, 0x00000012}
+ {48, 48, (AT91C_CKGR_SRCA | (0x7c << AT91C_CKGR_MULA_SHIFT) | (0x0 << AT91C_CKGR_OUTA_SHIFT) \
+ | (0x3f << AT91C_CKGR_PLLACOUNT_SHIFT) | (0x3 << AT91C_CKGR_DIVA_SHIFT)),
+ (AT91C_PMC_MDIV_1 | AT91C_PMC_PRES_CLK_16 | AT91C_PMC_CSS_PLLA_CLK)}
+};
+
+// Clock configurations for the AT91SAM9XE-EK, AT91SAM9261-EK
+#elif defined(at91sam9xe128) || defined(at91sam9xe256) || defined(at91sam9xe512) \
+ || defined(at91sam9261)
+
+#define AT91C_CKGR_PLLR AT91C_CKGR_PLLAR
+#define AT91C_PMC_LOCK AT91C_PMC_LOCKA
+
+#define AT91C_CKGR_MULA_SHIFT 16
+#define AT91C_CKGR_OUTA_SHIFT 14
+#define AT91C_CKGR_PLLACOUNT_SHIFT 8
+#define AT91C_CKGR_DIVA_SHIFT 0
+
+
+static const struct ClockConfiguration clockConfigurations[] = {
+
+ // PCK = 200 MHz, MCK = 100 MHz
+ //{200, 100, 0x208CBF0D, 0x00000102},
+ {200, 100, (AT91C_CKGR_SRCA | (0x8c << AT91C_CKGR_MULA_SHIFT) | (0x2 << AT91C_CKGR_OUTA_SHIFT) \
+ | (0x3f << AT91C_CKGR_PLLACOUNT_SHIFT) | (0xd << AT91C_CKGR_DIVA_SHIFT)),
+ (AT91C_PMC_MDIV_2 | AT91C_PMC_PRES_CLK | AT91C_PMC_CSS_PLLA_CLK)},
+ // PCK = 100 MHz, MCK = 100 MHz
+ //{100, 100, 0x201A3F05, 0x00000002},
+ {100, 100, (AT91C_CKGR_SRCA | (0x1a << AT91C_CKGR_MULA_SHIFT) | (0x0 << AT91C_CKGR_OUTA_SHIFT) \
+ | (0x3f << AT91C_CKGR_PLLACOUNT_SHIFT) | (0x5 << AT91C_CKGR_DIVA_SHIFT)),
+ (AT91C_PMC_MDIV_1 | AT91C_PMC_PRES_CLK | AT91C_PMC_CSS_PLLA_CLK)},
+ // PCK = 96 MHz, MCK = 48 MHz
+ //{96, 48, 0x20483F0E, 0x00000102},
+ {96, 48, (AT91C_CKGR_SRCA | (0x48 << AT91C_CKGR_MULA_SHIFT) | (0x0 << AT91C_CKGR_OUTA_SHIFT) \
+ | (0x3f << AT91C_CKGR_PLLACOUNT_SHIFT) | (0xe << AT91C_CKGR_DIVA_SHIFT)),
+ (AT91C_PMC_MDIV_2 | AT91C_PMC_PRES_CLK | AT91C_PMC_CSS_PLLA_CLK)},
+ // PCK = 48 MHz, MCK = 48 MHz
+ //{48, 48, 0x20483F0E, 0x00000006}
+ {48, 48, (AT91C_CKGR_SRCA | (0x48 << AT91C_CKGR_MULA_SHIFT) | (0x0 << AT91C_CKGR_OUTA_SHIFT) \
+ | (0x3f << AT91C_CKGR_PLLACOUNT_SHIFT) | (0xe << AT91C_CKGR_DIVA_SHIFT)),
+ (AT91C_PMC_MDIV_1 | AT91C_PMC_PRES_CLK_2 | AT91C_PMC_CSS_PLLA_CLK)}
+};
+
+// Clock configurations for the AT91SAM9RL64-EK, AT91CAP9-DK, AT91CAP9-STK
+#elif defined(at91sam9rl64) || defined(at91cap9)
+
+#define AT91C_CKGR_PLLR AT91C_CKGR_PLLAR
+#define AT91C_PMC_LOCK AT91C_PMC_LOCKA
+
+#define AT91C_CKGR_MULA_SHIFT 16
+#define AT91C_CKGR_OUTA_SHIFT 14
+#define AT91C_CKGR_PLLACOUNT_SHIFT 8
+#define AT91C_CKGR_DIVA_SHIFT 0
+
+
+static const struct ClockConfiguration clockConfigurations[] = {
+
+ // PCK = 200 MHz, MCK = 100 MHz
+ //{200, 100, 0x2031BF03, 0x00000102},
+ {200, 100, (AT91C_CKGR_SRCA | (0x31 << AT91C_CKGR_MULA_SHIFT) | (0x2 << AT91C_CKGR_OUTA_SHIFT) \
+ | (0x3f << AT91C_CKGR_PLLACOUNT_SHIFT) | (0x3 << AT91C_CKGR_DIVA_SHIFT)),
+ (AT91C_PMC_MDIV_2 | AT91C_PMC_PRES_CLK | AT91C_PMC_CSS_PLLA_CLK)},
+ // PCK = 100 MHz, MCK = 100 MHz
+ //{100, 100, 0x20183F03, 0x00000002},
+ {100, 100, (AT91C_CKGR_SRCA | (0x18 << AT91C_CKGR_MULA_SHIFT) | (0x0 << AT91C_CKGR_OUTA_SHIFT) \
+ | (0x3f << AT91C_CKGR_PLLACOUNT_SHIFT) | (0x3 << AT91C_CKGR_DIVA_SHIFT)),
+ (AT91C_PMC_MDIV_1 | AT91C_PMC_PRES_CLK | AT91C_PMC_CSS_PLLA_CLK)},
+ // PCK = 96 MHz, MCK = 48 MHz
+ //{96, 48, 0x20073F01, 0x00000102},
+ {96, 48, (AT91C_CKGR_SRCA | (0x7 << AT91C_CKGR_MULA_SHIFT) | (0x0 << AT91C_CKGR_OUTA_SHIFT) \
+ | (0x3f << AT91C_CKGR_PLLACOUNT_SHIFT) | (0x1 << AT91C_CKGR_DIVA_SHIFT)),
+ (AT91C_PMC_MDIV_2 | AT91C_PMC_PRES_CLK | AT91C_PMC_CSS_PLLA_CLK)},
+ // PCK = 48 MHz, MCK = 48 MHz
+ //{48, 48, 0x20073F01, 0x00000006}
+ {48, 48, (AT91C_CKGR_SRCA | (0x7 << AT91C_CKGR_MULA_SHIFT) | (0x0 << AT91C_CKGR_OUTA_SHIFT) \
+ | (0x3f << AT91C_CKGR_PLLACOUNT_SHIFT) | (0x1 << AT91C_CKGR_DIVA_SHIFT)),
+ (AT91C_PMC_MDIV_1 | AT91C_PMC_PRES_CLK_2 | AT91C_PMC_CSS_PLLA_CLK)},
+};
+
+// Clock configuration for the AT91SAM7X-EK, AT91SAM7S-EK, AT91SAM7SE-EK
+#elif defined(at91sam7x128) || defined(at91sam7x256) || defined(at91sam7x512) \
+ || defined(at91sam7xc128) || defined(at91sam7xc256) || defined(at91sam7xc512) \
+ || defined(at91sam7s16) || defined(at91sam7s161) || defined(at91sam7s32) \
+ || defined(at91sam7s321) || defined(at91sam7s64) || defined(at91sam7s128) \
+ || defined(at91sam7s256) || defined(at91sam7s512) || defined(at91sam7se32) \
+ || defined(at91sam7se256) || defined(at91sam7se512)
+
+#define AT91C_CKGR_USBDIV_SHIFT 28
+#define AT91C_CKGR_MUL_SHIFT 16
+#define AT91C_CKGR_OUT_SHIFT 14
+#define AT91C_CKGR_PLLCOUNT_SHIFT 8
+#define AT91C_CKGR_DIV_SHIFT 0
+
+
+static const struct ClockConfiguration clockConfigurations[] = {
+
+ // PCK = 55 MHz, MCK = 55 MHz
+ //{55, 55, 0x006A3F12, 0x00000007},
+ {55, 55, ((0x0 << AT91C_CKGR_USBDIV_SHIFT) | (0x6a << AT91C_CKGR_MUL_SHIFT) \
+ | (0x0 << AT91C_CKGR_OUT_SHIFT) |(0x3f << AT91C_CKGR_PLLCOUNT_SHIFT) \
+ | (0x12 << AT91C_CKGR_DIV_SHIFT)),
+ AT91C_PMC_PRES_CLK_2 | AT91C_PMC_CSS_PLL_CLK},
+ // PCK = 48 MHz, MCK = 48 MHz
+ //{48, 48, 0x00483F0E, 0x00000007},
+ {48, 48, ((0x0 << AT91C_CKGR_USBDIV_SHIFT) | (0x48 << AT91C_CKGR_MUL_SHIFT) \
+ | (0x0 << AT91C_CKGR_OUT_SHIFT) |(0x3f << AT91C_CKGR_PLLCOUNT_SHIFT) \
+ | (0xe << AT91C_CKGR_DIV_SHIFT)),
+ ( AT91C_PMC_PRES_CLK_2 | AT91C_PMC_CSS_PLL_CLK)}
+};
+
+// Clock configuration for the AT91SAM7A3
+#elif defined(at91sam7a3)
+
+#define AT91C_CKGR_USBDIV_SHIFT 28
+#define AT91C_CKGR_MUL_SHIFT 16
+#define AT91C_CKGR_OUT_SHIFT 14
+#define AT91C_CKGR_PLLCOUNT_SHIFT 8
+#define AT91C_CKGR_DIV_SHIFT 0
+
+static const struct ClockConfiguration clockConfigurations[] = {
+
+ // PCK = 60 MHz, MCK = 60 MHz
+ //{60, 60, 0x000C3F02, 0x00000007},
+ {60, 60, ((0x0 << AT91C_CKGR_USBDIV_SHIFT) | (0x6a << AT91C_CKGR_MUL_SHIFT) \
+ | (0x0 << AT91C_CKGR_OUT_SHIFT) |(0x3f << AT91C_CKGR_PLLCOUNT_SHIFT) \
+ | (0x2 << AT91C_CKGR_DIV_SHIFT)),
+ ( AT91C_PMC_PRES_CLK_2 | AT91C_PMC_CSS_PLL_CLK)},
+ // PCK = 48 MHz, MCK = 48 MHz
+ //{48, 48, 0x00483F0E, 0x00000007}
+ {48, 48, ((0x0 << AT91C_CKGR_USBDIV_SHIFT) | (0x48 << AT91C_CKGR_MUL_SHIFT) \
+ | (0x0 << AT91C_CKGR_OUT_SHIFT) |(0x3f << AT91C_CKGR_PLLCOUNT_SHIFT) \
+ | (0x12 << AT91C_CKGR_DIV_SHIFT)),
+ ( AT91C_PMC_PRES_CLK_2 | AT91C_PMC_CSS_PLL_CLK)}
+};
+
+// Clock configuration for the AT91SAM3U4
+#elif defined(at91sam3u4)
+
+#define AT91C_CKGR_PLLR AT91C_CKGR_PLLAR
+#define AT91C_PMC_LOCK AT91C_PMC_LOCKA
+
+#define AT91C_CKGR_MUL_SHIFT 16
+#define AT91C_CKGR_OUT_SHIFT 14
+#define AT91C_CKGR_PLLCOUNT_SHIFT 8
+#define AT91C_CKGR_DIV_SHIFT 0
+
+static const struct ClockConfiguration clockConfigurations[] = {
+
+ // PCK = 84 MHz, MCK = 84 MHz
+ //{84, 84, 0x200d3f01, 0x00000012},
+ {84, 84, ((1 << 29) | (0xd << AT91C_CKGR_MUL_SHIFT) \
+ | (0x0 << AT91C_CKGR_OUT_SHIFT) |(0x3f << AT91C_CKGR_PLLCOUNT_SHIFT) \
+ | (0x1 << AT91C_CKGR_DIV_SHIFT)),
+ ( AT91C_PMC_PRES_CLK_2 | AT91C_PMC_CSS_PLLA_CLK)},
+ // PCK = 48 MHz, MCK = 48 MHz
+ //{48, 48, 0x20073f01, 0x00000012}
+ {48, 48, ((1 << 29) | (0x7 << AT91C_CKGR_MUL_SHIFT) \
+ | (0x0 << AT91C_CKGR_OUT_SHIFT) |(0x3f << AT91C_CKGR_PLLCOUNT_SHIFT) \
+ | (0x1 << AT91C_CKGR_DIV_SHIFT)),
+ ( AT91C_PMC_PRES_CLK_2 | AT91C_PMC_CSS_PLLA_CLK)}
+};
+
+// No clock configuration
+#else
+ #error No clock configuration for this board.
+#endif
+
+/// Number of available clock configurations
+const unsigned char numConfigurations = sizeof(clockConfigurations)
+ / sizeof(struct ClockConfiguration);
+
+//------------------------------------------------------------------------------
+// Internal functions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// Sets the specified clock configuration.
+/// \param configuration Index of the configuration to set.
+//------------------------------------------------------------------------------
+static void SetClockConfiguration(unsigned char configuration)
+{
+ printf("Setting clock configuration #%d ... ", configuration);
+
+ // Switch to main oscillator in two operations
+ AT91C_BASE_PMC->PMC_MCKR = (AT91C_BASE_PMC->PMC_MCKR & ~AT91C_PMC_CSS) | AT91C_PMC_CSS_MAIN_CLK;
+ while ((AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY) == 0);
+
+ // Configure PLL
+ *AT91C_CKGR_PLLR = clockConfigurations[configuration].pllr;
+ while ((AT91C_BASE_PMC->PMC_SR & AT91C_PMC_LOCK) == 0);
+
+ // Configure master clock in two operations
+ AT91C_BASE_PMC->PMC_MCKR = (clockConfigurations[configuration].mckr & ~AT91C_PMC_CSS) | AT91C_PMC_CSS_MAIN_CLK;
+ while ((AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY) == 0);
+ AT91C_BASE_PMC->PMC_MCKR = clockConfigurations[configuration].mckr;
+ while ((AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY) == 0);
+
+ // DBGU reconfiguration
+ DBGU_Configure(DBGU_STANDARD, 115200, clockConfigurations[configuration].mck*1000000);
+ printf("done.\n\r");
+}
+
+//------------------------------------------------------------------------------
+/// Displays the user menu on the DBGU.
+//------------------------------------------------------------------------------
+static void DisplayMenu(void)
+{
+ unsigned int i;
+
+ printf("\n\rMenu :\n\r");
+ printf("------\n\r");
+
+ for (i = 0; i < numConfigurations; i++) {
+
+ printf(" %u: Set PCK = %3d MHz, MCK = %3d MHz\n\r",
+ i,
+ clockConfigurations[i].pck,
+ clockConfigurations[i].mck);
+ }
+}
+
+//------------------------------------------------------------------------------
+/// Computes the number of dhrystones per second that the device can produce
+/// under the current configuration. Outputs four measures on the DBGU.
+//------------------------------------------------------------------------------
+static void ComputeDhrystonesPerSecond(void)
+{
+ unsigned int startTime;
+ unsigned int dhrystonesPerSecond;
+ unsigned char i;
+ char dhrystr[50];
+
+ printf("Computing dhrystones per second ...\n\r");
+
+ // Configure the RTT
+ RTT_SetPrescaler(AT91C_BASE_RTTC, 32768);
+
+ // Perform measures
+ for (i=0; i < 4; i++) {
+
+ dhrystonesPerSecond = 0;
+
+ // Wait for the next second
+ startTime = RTT_GetTime(AT91C_BASE_RTTC);
+ while (startTime == RTT_GetTime(AT91C_BASE_RTTC));
+
+ // Go through test loop
+ startTime = RTT_GetTime(AT91C_BASE_RTTC);
+ while (RTT_GetTime(AT91C_BASE_RTTC) == startTime) {
+
+ DHRY_testloop(NUM_RUNS);
+ dhrystonesPerSecond += NUM_RUNS;
+ }
+ //printf(" - %u dhrystones per second\n\r", dhrystonesPerSecond);
+ sprintf(dhrystr,"- %u dhrystones per second\n\r", dhrystonesPerSecond);
+ DrawStrInDispBoxDefault((void *)BOARD_LCD_BASE, 1, dhrystr);
+ }
+ printf("\n\rFinished\n\r");
+}
+
+//------------------------------------------------------------------------------
+// Exported functions
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+// Portal for 'dhry' command
+// \param argc, number of argument
+// \param argv, argument string array
+// \return 0 succeed, other value failure
+//------------------------------------------------------------------------------
+int DFM_Dhry(int argc, char** argv)
+{
+ unsigned int cfgnum = 0;
+
+ printf("\n\r Dhrystone test! \n\r");
+
+ if(argc == 2 && strcmp(argv[1], "menu") == 0) {
+ DisplayMenu();
+ return 0;
+ }
+
+//#if defined(at91sam3u)
+// OptimizeCpuSpeed();
+//#endif
+ if(argc == 2) {
+ errno = 0;
+ cfgnum = atoi(argv[1]);
+
+ }
+
+ if(argc == 2 && cfgnum < CLKCFGNUM) {
+ SetClockConfiguration(cfgnum);
+ }else {
+ //default set as 0, in sam3u4, it is PCK=84MHZ, MCK=84MHZ
+ SetClockConfiguration(0);
+ }
+
+ ComputeDhrystonesPerSecond();
+
+ return 0;
+}
+
+//define a new command for dhrystone test
+DFM_CMD(dhry, DFM_Dhry, "Perform Dhrystone test", "default");
+
+
+
+
diff --git a/utility/demo-fw/commands/cmd_slidepage.c b/utility/demo-fw/commands/cmd_slidepage.c
new file mode 100644
index 0000000..dfe81e7
--- /dev/null
+++ b/utility/demo-fw/commands/cmd_slidepage.c
@@ -0,0 +1,67 @@
+/* ----------------------------------------------------------------------------
+ * 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 <string.h>
+#include <stdlib.h>
+
+#include "dfm_cmd.h"
+#include "dfm_lcd_tsd.h"
+
+//------------------------------------------------------------------------------
+// Exported functions
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+// Portal for 'slidepage' command
+// \param argc, number of argument
+// \param argv, argument string array
+// \return 0 succeed, other value failure
+//------------------------------------------------------------------------------
+int DFM_SlidePage(int argc, char **argv)
+{
+ unsigned char file[32];
+ if(argc == 2 && strcmp(argv[1], "next") == 0) {
+ ++gActiveSlideIndex;
+ }
+
+ if(argc == 2 && strcmp(argv[1], "previous") == 0) {
+ --gActiveSlideIndex;
+ }
+
+ if(argc == 3 && strcmp(argv[1], "goto") == 0) {
+ gActiveSlideIndex = atoi(argv[2]) - 1;
+ }
+
+ return 0;
+}
+
+//define a new command 'slidepage' for change slide page
+DFM_CMD(slidepage, DFM_SlidePage, "Change display slide", "default");
diff --git a/utility/demo-fw/commands/cmd_slideshow.c b/utility/demo-fw/commands/cmd_slideshow.c
new file mode 100644
index 0000000..a85d722
--- /dev/null
+++ b/utility/demo-fw/commands/cmd_slideshow.c
@@ -0,0 +1,284 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ----------------------------------------------------------------------------
+ */
+
+#include <board.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <adc/adc12.h>
+#include <irq/irq.h>
+#include <rtc/rtc.h>
+
+#include "dfm_config.h"
+#include "dfm_cmd.h"
+#include "dfm_lcd_tsd.h"
+#include "dfm_dispboxmgr.h"
+#include "dfm_it.h"
+
+//------------------------------------------------------------------------------
+// Global variables
+//------------------------------------------------------------------------------
+
+#if defined(at91sam3u4)
+#define BOARD_ADC_FREQ 5000000
+#define ADC_VREF 3300 // 3.3 * 1000
+#endif
+
+#if defined(USE_IT_CHAIN_MGR)
+void RTC_IrqHandlerSlideShow(void);
+TDFM_ItServList gRtcItHandlerSlideShow = {BOARD_RTC_ID, RTC_IrqHandlerSlideShow, NULL};
+#endif
+
+/// count seconds
+unsigned int gSecondCount = 0;
+/// Record when slide show starts
+static unsigned int gSlideShowStartSec = 0xFFFFFFFF;
+/// slide show wait interval
+unsigned int gSlideShowInterval = 5;
+/// default home page to return when slide show ends
+unsigned int gDefaultHomePage = 1;
+/// adc sample value when slide show starts
+unsigned int gPoMeterRefADValue = 0xFFFFFFFF;
+/// adjustment interval base, will be set same as gSlideShowInterval when slide show start
+unsigned int gIntervalBase;
+/// the threshold value for interval adjustment by potentimeter
+unsigned int gInvThreshold = 30;//default is 30 seconds
+
+
+unsigned int xSlPenLast=0;
+unsigned int ySlPenLast=0;
+
+//------------------------------------------------------------------------------
+/// Interrupt RTC handler for slide show.
+//------------------------------------------------------------------------------
+void RTC_IrqHandlerSlideShow()
+{
+ unsigned int status, advalue;
+ unsigned char tmpT;
+
+ status = AT91C_BASE_RTC->RTC_SR;
+
+ if ((status & AT91C_RTC_SECEV) == AT91C_RTC_SECEV) {
+ // Disable RTC interrupt
+ RTC_DisableIt(AT91C_RTC_SECEV);
+ }
+
+ ++gSecondCount;
+
+ if(gSlideShowStartSec == 0xffffffff)
+ gSlideShowStartSec = gSecondCount;
+
+ if(gSecondCount - gSlideShowStartSec >= gSlideShowInterval) {
+ ++gActiveSlideIndex;
+
+ gSlideShowStartSec = gSecondCount;
+ }
+
+#if defined(at91sam3u4)
+ if(gSecondCount & 1 == 0) {
+ ADC12_StartConversion(AT91C_BASE_ADC12B);
+ } else {
+
+// if(gSecondCount % 2 == 0) {
+ advalue = ADC12_GetConvertedData(AT91C_BASE_ADC12B, ADC12_CHANNEL_3);
+
+ advalue = advalue * ADC_VREF / 0xFFF;
+
+ if(gPoMeterRefADValue == 0xFFFFFFFF) {
+ gPoMeterRefADValue = advalue;
+ gSlideShowInterval = advalue * gInvThreshold / ADC_VREF;
+// gIntervalBase = gSlideShowInterval;
+ }
+
+ if(advalue != gPoMeterRefADValue) {
+ gSlideShowInterval = advalue * gInvThreshold / ADC_VREF;
+ }
+// if(advalue > gPoMeterRefADValue) {
+// gSlideShowInterval = (advalue - gPoMeterRefADValue) * (gInvThreshold - gIntervalBase) \
+// /(ADC_VREF - gPoMeterRefADValue) + gIntervalBase;
+// }
+//
+// if(advalue < gPoMeterRefADValue) {
+// gSlideShowInterval = gIntervalBase - (gPoMeterRefADValue - advalue) * gIntervalBase \
+// / gPoMeterRefADValue;
+// }
+
+ if(gSlideShowInterval == 0) {
+ gSlideShowInterval = 1;
+ }
+ }
+#endif
+
+ AT91C_BASE_RTC->RTC_SCCR = AT91C_RTC_SECEV;
+
+ RTC_EnableIt(AT91C_RTC_SECEV);
+
+ tmpT = TSD_GetTouched();
+ if(tmpT)
+ {
+ //printf("Touch \n\r");
+ TSD_ClearTouched();
+ // End slide show command
+ ParseAndRunMultiCmds("slideshow end");
+ ParseAndRunMultiCmds("slidepage goto 02");
+ }
+}
+
+//------------------------------------------------------------------------------
+// Exported functions
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+// Portal for 'slideshow' command
+// \param argc, number of argument
+// \param argv, argument string array
+// \return 0 succeed, other value failure
+//------------------------------------------------------------------------------
+int DFM_SlideShow(int argc, char ** argv)
+{
+ unsigned int value;
+ char string[20];
+
+ if(argc == 3 && strcmp(argv[1], "-interval") == 0) {
+ //command "slideshow -interval up
+ if(strcmp(argv[2], "up")==0) {
+ ++gSlideShowInterval;
+ }
+
+ //command "slideshow -interval down
+ if(strcmp(argv[2], "down")==0) {
+ --gSlideShowInterval;
+ }
+
+ //command "slideshow -interval display
+ // display current gSlideShowInterval value in display box
+ if(strcmp(argv[2], "display")==0) {
+ sprintf(string, "%u ", gSlideShowInterval);
+ DrawStrInDispBoxScrollNoClear((void *)BOARD_LCD_BASE, 1, string);
+ }
+ }
+
+
+ //command "slideshow start"
+ if(argc == 2 && strcmp(argv[1], "start")==0) {
+
+ TSD_ClearTouched();
+
+ //reset variable
+ gSlideShowStartSec = 0xFFFFFFFF;
+ gPoMeterRefADValue = 0xFFFFFFFF;
+
+#if defined(at91sam3u4)
+ ADC12_EnableChannel(AT91C_BASE_ADC12B, ADC12_CHANNEL_3);
+ // Start measurement
+ ADC12_StartConversion(AT91C_BASE_ADC12B);
+#endif
+
+#if defined(USE_IT_CHAIN_MGR)
+ DFM_RegisterItHandler(&gRtcItHandlerSlideShow);
+#endif
+ //enable RTC interrupt
+ IRQ_ConfigureIT(BOARD_RTC_ID, 0, RTC_IrqHandlerSlideShow);
+ RTC_EnableIt(AT91C_RTC_SECEV);
+ IRQ_EnableIT(BOARD_RTC_ID);
+
+ }
+
+ //command "slideshow start -homepage xx"
+ if(argc == 4 && strcmp(argv[1], "start")==0 &&
+ strcmp(argv[2], "-homepage")==0) {
+
+ TSD_ClearTouched();
+
+ //reset variable
+ gSlideShowStartSec = 0xFFFFFFFF;
+
+#if defined(USE_IT_CHAIN_MGR)
+ DFM_RegisterItHandler(&gRtcItHandlerSlideShow);
+#endif
+ //enable RTC interrupt
+ IRQ_ConfigureIT(BOARD_RTC_ID, 0, RTC_IrqHandlerSlideShow);
+ RTC_EnableIt(AT91C_RTC_SECEV);
+ IRQ_EnableIT(BOARD_RTC_ID);
+
+ value = atoi(argv[3]);
+ //in command input, slide start from 1, but in program it starts from 0
+ //note if index number of slide bigger than max, program will correct as
+ //the last of slide
+ gDefaultHomePage = value - 1;
+ }
+
+ //command "slideshow end"
+ if(argc == 2 && strcmp(argv[1], "end")==0) {
+
+ TSD_ClearTouched();
+
+ RTC_DisableIt(AT91C_RTC_SECEV);
+ IRQ_DisableIT(BOARD_RTC_ID);
+
+#if defined(at91sam3u4)
+ DFM_UnRegisterItHandler(&gRtcItHandlerSlideShow);
+#endif
+
+ //reset variable
+ gSlideShowStartSec = 0xFFFFFFFF;
+
+ gActiveSlideIndex = gDefaultHomePage;
+ }
+
+ //command "slideshow start -homepage xx"
+ if(argc == 4 && strcmp(argv[1], "end")==0 &&
+ strcmp(argv[2], "-homepage")==0) {
+
+ TSD_ClearTouched();
+
+ RTC_DisableIt(AT91C_RTC_SECEV);
+ IRQ_DisableIT(BOARD_RTC_ID);
+
+#if defined(at91sam3u4)
+ DFM_UnRegisterItHandler(&gRtcItHandlerSlideShow);
+#endif
+
+ //reset variable
+ gSlideShowStartSec = 0xFFFFFFFF;
+
+ value = atoi(argv[3]);
+ //in command input, slide start from 1, but in program it starts from 0
+ //note if index number of slide bigger than max, program will correct as
+ //the last of slide
+ gActiveSlideIndex = value - 1;
+
+ gDefaultHomePage = gActiveSlideIndex;
+ }
+
+ return 0;
+}
+
+//define a new command 'slideshow' for slide show
+DFM_CMD(slideshow, DFM_SlideShow, "slide show ppt pages", "default");
+
diff --git a/utility/demo-fw/common/dfm_accelerometer.c b/utility/demo-fw/common/dfm_accelerometer.c
new file mode 100644
index 0000000..410fe91
--- /dev/null
+++ b/utility/demo-fw/common/dfm_accelerometer.c
@@ -0,0 +1,647 @@
+/* ----------------------------------------------------------------------------
+ * 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
+///
+/// This file contains algorithms and drivers for tilt sensing.
+///
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+// Headers
+//------------------------------------------------------------------------------
+#include "dfm_accelerometer.h"
+#include "board.h"
+#include <irq/irq.h>
+#include <pio/pio.h>
+#include <pio/pio_it.h>
+#include <adc/adc12.h>
+#include <lcd/draw.h>
+
+#include <stdio.h>
+
+#include <math.h>
+
+#include "dfm_config.h"
+#include "dfm_cmd.h"
+#include "dfm_lcd_tsd.h"
+#include "dfm_dispboxmgr.h"
+#include "dfm_it.h"
+#include "dfm_init.h"
+
+//------------------------------------------------------------------------------
+// Macros
+//------------------------------------------------------------------------------
+#define BOARD_ADC12_FREQ 5000000 //! ADC clock
+#define ADC12_VREF 3300 //! reference voltage 3.3 * 1000,make sure the jumper setting is right
+#define PINS_ACC_ADC PIN_ADC0_AD2,PIN_ADC0_AD6,PIN_ADC0_AD7
+
+#define TAN30 (37) //! fixed point for tanget tan(45)*0x40
+#define TAN15 17 //! fixed point for tangent tan(15)*0x40
+#define DELAY 100
+#define SAMPLES 1
+
+#if defined(at91sam3u4)
+#define AT91C_ID_ADC_PRESENT AT91C_ID_ADC12B
+#define AT91C_BASE_ADC AT91C_BASE_ADC12B
+#endif
+//------------------------------------------------------------------------------
+// External Variables
+//------------------------------------------------------------------------------
+extern const char * gpActiveBinFile;
+extern unsigned int gLcdRefreshFlag;
+extern int rotation_axes_cpt;
+/// record measurement times
+static int count =0;
+//------------------------------------------------------------------------------
+// Variables
+//------------------------------------------------------------------------------
+
+
+unsigned char ADC12_channel_x = ADC12_CHANNEL_2; //!< X Channel For Accelerometer
+unsigned char ADC12_channel_y = ADC12_CHANNEL_6; //!< Y Channel For Accelerometer
+unsigned char ADC12_channel_z = ADC12_CHANNEL_7; //!< Z Channel For Accelerometer
+/// Indicates that the conversion is finished.
+static volatile unsigned char conversionDone;
+
+acc_t acc = { //!< Accelerometer Instance
+ .m = { .x=0 , .y=0 , .z=0 } ,
+ .k = { .x=ACC_ZERO_X , .y=ACC_ZERO_Y , .z=ACC_ZERO_Z } ,
+ .ak = { .x=0 , .y=0 , .z=0 } ,
+} ;
+
+static const Pin pinsADC[] = {PINS_ACC_ADC};
+
+static xyz_t lastMeasure = {0};
+int gDir = DIR_UNCHANGED;
+int gLastDir = DIR_UNCHANGED;
+
+///push button to configure for the applicatino.
+static Pin pinBP4 = PIN_PUSHBUTTON_1;
+//------------------------------------------------------------------------------
+// Functions
+//------------------------------------------------------------------------------
+int DV_Check_AccStatus();
+
+//------------------------------------------------------------------------------
+/// add position
+//------------------------------------------------------------------------------
+xyz_t xyz_add (xyz_t p, xyz_t q)
+{
+ xyz_t r ;
+ r.x = p.x + q.x ;
+ r.y = p.y + q.y ;
+ r.z = p.z + q.z ;
+ return r ;
+}
+
+//------------------------------------------------------------------------------
+/// sub position
+//------------------------------------------------------------------------------
+xyz_t xyz_diff (xyz_t p, xyz_t q)
+{
+ xyz_t r ;
+ r.x = p.x - q.x ;
+ r.y = p.y - q.y ;
+ r.z = p.z - q.z ;
+ return r ;
+}
+
+//------------------------------------------------------------------------------
+/// Invoke platform api to get converted data
+/// \param pAdc address pointer for ADC12B controller
+/// \param ADC12_channel_x channel number for x axis
+/// \param ADC12_channel_y channel number for y axis
+/// \param ADC12_channel_z channel number for z axis
+/// \return converted data for three channels
+//------------------------------------------------------------------------------
+xyz_t acc_get_value ( AT91S_ADC12B *pAdc , unsigned char ADC12_channel_x, unsigned char ADC12_channel_y, unsigned char ADC12_channel_z)
+{
+ xyz_t val ;
+
+ val.x = ADC12_GetConvertedData(pAdc, ADC12_channel_x);
+ val.y = ADC12_GetConvertedData(pAdc, ADC12_channel_y);
+ val.z = ADC12_GetConvertedData(pAdc, ADC12_channel_z);
+
+ val.x = val.x>>ACC_SHIFT;
+ val.y = val.y>>ACC_SHIFT;
+ val.z = val.z>>ACC_SHIFT;
+
+ return val ;
+}
+
+
+//------------------------------------------------------------------------------
+/// get present acceleration value as 0-g value for x and y, 1-g value for z
+//------------------------------------------------------------------------------
+void DoCalibration()
+{
+ int i = 0,j;
+ xyz_t temp ={0};
+ count = 0;
+ acc.m.x = 0;
+ acc.m.y = 0;
+ acc.m.z = 0;
+ for(i = 0; i < 16 ; i++)
+ {
+ if(DV_Check_AccStatus()){
+ temp = xyz_add(acc.m,temp);
+ for(j=0;j<DELAY;j++);
+ }
+
+ }
+ acc.m.x = temp.x /count;
+ acc.m.y = temp.y /count;
+ acc.m.z = temp.z /count;
+
+ count = 0;
+ acc.k = acc.m;
+
+
+}
+
+//------------------------------------------------------------------------------
+///check if the tilt angles are big enough.If yes,get rotation direction
+///according to the sign of two axes
+/// \return rotation direction
+//------------------------------------------------------------------------------
+int DV_Accelerometer_Tilt()
+{
+ int dir = DV_Accelerometer_Unchanged;
+ int x=0,y=0,z=0;
+
+ int i = 0,j;
+ acc.m.x = 0;
+ acc.m.y = 0;
+ acc.m.z = 0;
+
+ count = 0;
+
+ for(i = 0; i < SAMPLES ; i++)
+ {
+ DV_Check_AccStatus();
+ for(j=0;j<DELAY;j++);
+ }
+ acc.m.x = acc.m.x /count;
+ acc.m.y = acc.m.y /count;
+ acc.m.z = acc.m.z /count;
+ count = 0;
+
+ acc.ak = xyz_diff(acc.m,acc.k);
+
+
+
+ x = acc.ak.x;
+ y = acc.ak.y;
+ z = (acc.ak.z + ACC_1G);
+
+
+ if( (unsigned int)(x*x)<<12 > (TAN15*TAN15)*(y*y+z*z) || (unsigned int)(y*y)<<12 > (TAN15*TAN15)*(x*x+z*z))
+ {
+ if((unsigned int)(x*x)<<12 > (TAN15*TAN15)*(y*y+z*z))
+ {
+ if((unsigned int)(y*y)<<12 > (TAN15*TAN15)*(x*x+z*z))
+ {
+ if(x < 0)
+ {
+ if(y < 0)
+ {
+ dir = DV_Accelerometer_up_right;
+ }
+ else
+ {
+ dir =DV_Accelerometer_down_right;
+ }
+ }
+ else
+ {
+ if(y < 0)
+ {
+ dir = DV_Accelerometer_up_left;
+ }
+ else
+ {
+ dir = DV_Accelerometer_down_left;
+
+ }
+ }
+ }
+ else
+ {
+ if(x < 0)
+ {
+ dir = DV_Accelerometer_right;
+ }
+ else
+ {
+ dir = DV_Accelerometer_left;
+ }
+ }
+
+ }
+ else
+ {
+ if(y < 0)
+ {
+ dir = DV_Accelerometer_up;
+ }
+ else
+ {
+ dir = DV_Accelerometer_down;
+ }
+ }
+ }
+
+ return dir;
+
+}
+
+
+//------------------------------------------------------------------------------
+/// get the direction of the board
+/// \return direction
+//------------------------------------------------------------------------------
+int DV_Accelerometer_Dir()
+{
+
+ int dir = gDir;
+ int x=0,y=0,z=0;
+ xyz_t diff = {0};
+
+ ///measure the difference between the last one and the present one
+ diff = xyz_diff(acc.m,lastMeasure);
+
+ ///check the status,acc.m will be changed after called routine
+ ///if conversion is done,otherwise,return immediately
+ DV_Check_AccStatus();
+
+
+ ///no big change since last measurement
+ if( diff.x*diff.x + diff.y*diff.y + diff.z*diff.z < ((ACC_1G*ACC_1G)>>11))
+ {
+ ///keep the old direction
+ return gDir;
+
+ }
+ ///update lastMeasure to the new one
+ lastMeasure = acc.m;
+
+ ///get acceleration offset
+ acc.ak = xyz_diff(acc.m,acc.k);
+
+
+
+ x = acc.ak.x;
+ y = acc.ak.y;
+ z = (acc.ak.z + ACC_1G);
+ /// filter non-tilting operation
+ if( (x*x + y*y+z*z > ACC_AMPLITUDE_UPPER) ||(x*x + y*y+z*z < ACC_AMPLITUDE_LOWER) ){
+ return gDir;
+ }
+
+ ///the board plane is angled with the horizontal surface
+ if( (unsigned int)(x*x)<<12 > (TAN30*TAN30)*(y*y+z*z) || (unsigned int)(y*y)<<12 > (TAN30*TAN30)*(x*x+z*z))
+ {
+
+ if(x*x > y*y + (y*y>>1))
+ {
+ if(x > 0)
+ {
+ dir = DIR_HORIZIONTAL_UP;
+ }
+ else
+ {
+ dir = DIR_HORIZIONTAL_DOWN;
+ }
+ }
+ else if(x*x + (x*x>>1) < y*y)
+ {
+ if(y > 0)
+ {
+ dir = DIR_VERTICAL_UP;
+ }
+ else
+ {
+ dir = DIR_VERTICAL_DOWN;
+ }
+ }
+ //else dir = previous dir
+ //leave gap enough for stabilization
+ ///renew the direction
+ gDir = dir;
+ }
+
+ return gDir;
+
+}
+//------------------------------------------------------------------------------
+/// Check accelerometer is ready?
+/// if the direction is unchanged since last measurement,return "not ready"
+/// \return 0 not ready, other value means ready and command string length
+//------------------------------------------------------------------------------
+unsigned int ACC_CommandIsReady()
+{
+ int dir = DIR_UNCHANGED;
+ unsigned int ret;
+ dir = DV_Accelerometer_Dir();
+ //no change of direction since last measurement
+ if(gLastDir == dir)
+ {
+ ret = 0;
+ }
+ else
+ {
+ ret = 1;
+ }
+ gLastDir = dir;
+ return ret;
+}
+
+
+//------------------------------------------------------------------------------
+// get flipped ppt page
+//------------------------------------------------------------------------------
+const char * ACC_GetCommand()
+{
+ if(gDir == DIR_HORIZIONTAL_UP || gDir == DIR_HORIZIONTAL_DOWN)
+ {
+ //update to portait image file
+ gpActiveBinFile = LCDSLIDEVIMAGEFILE;
+ gLcdRefreshFlag = 1;
+
+ }
+ else
+ {
+ gpActiveBinFile = LCDSLIDEIMAGEFILE;
+ gLcdRefreshFlag = 1;
+
+ }
+ return NULL;
+}
+
+//an example of ShowPrompt
+int ACC_ShowPrompt()
+{
+// int i;
+// switch(gDir)//gDir
+// {
+//
+// case DIR_HORIZIONTAL_UP:
+// printf("Horizontal Up!\n");
+// //LCDD_DrawRectangle((void *)BOARD_LCD_BASE, x,y,width,height,0xE0E0C0);
+// break;
+// case DIR_HORIZIONTAL_DOWN:
+// printf("Horizontal Down!\n");
+// break;
+// case DIR_VERTICAL_UP:
+// printf("Vertical Up!\n");
+// break;
+// case DIR_VERTICAL_DOWN:
+// printf("Vertical Down!\n");
+// break;
+// default:
+// printf("Unchanged!\n");
+// break;
+// }
+// for(i=0;i<5000;i++);
+ return 0;
+}
+
+//global accelerometer entry variable
+TInputEntry gAccEntry = {0, {NULL,NULL},ACC_ShowPrompt, ACC_CommandIsReady, ACC_GetCommand, NULL};
+//------------------------------------------------------------------------------
+/// Check if conversion is done.If done,read the corresponding parameters and
+///start new measurement
+//------------------------------------------------------------------------------
+int DV_Check_AccStatus()
+{
+ //check if conversation is done
+ //if done, read and measure,and start new conversation
+ //else, return directly
+
+
+ if(conversionDone == ((1<<ADC12_channel_x)|(1<<ADC12_channel_y)|(1<<ADC12_channel_z)))//x,y,z all done
+ {
+ // IRQ_DisableIT(AT91C_ID_ADC_PRESENT);
+ DV_ACCELEROMETER_Measure();
+ //sharing variable for main and isr
+ conversionDone= 0;
+ // record the number of measurement
+ count++;
+
+ // Start new measurement
+ ADC12_EnableIt(AT91C_BASE_ADC, 1<<ADC12_channel_x);//Enable EOCx interrupt
+ ADC12_EnableIt(AT91C_BASE_ADC, 1<<ADC12_channel_y);//Enable EOCx interrupt
+ ADC12_EnableIt(AT91C_BASE_ADC, 1<<ADC12_channel_z);//Enable EOCx interrupt
+ ADC12_StartConversion(AT91C_BASE_ADC);
+ // conversionDone for all 3 channels
+ return 1;
+ }else{
+ return 0;
+ }
+
+
+
+}
+
+//------------------------------------------------------------------------------
+/// Interrupt handler for the ADC. Signals that the conversion is finished by
+/// setting a flag variable.
+//------------------------------------------------------------------------------
+void ADC12B_IrqHandler(void)
+{
+ unsigned int status, i;
+ static unsigned char chns[3];
+ AT91PS_ADC12B padc = AT91C_BASE_ADC;
+ chns[0] = ADC12_channel_x;
+ chns[1] = ADC12_channel_y;
+ chns[2] = ADC12_channel_z;;
+
+
+ status = ADC12_GetStatus(padc);
+ //printf("status =0x%X\n\r", status);
+ //TRACE_DEBUG("ADC12_imr=0x%X\n\r", ADC12_GetInterruptMaskStatus());
+
+ for(i=0;i<sizeof(chns)/sizeof(unsigned char);i++) {
+ if (ADC12_IsChannelInterruptStatusSet(status, chns[i])) {
+
+ //printf("channel %d\n\r", chns[i]);
+ ADC12_DisableIt(AT91C_BASE_ADC, 1<<chns[i]);//disable EOCx interrupt
+ conversionDone |= 1<<chns[i];
+ }
+ }
+}
+
+#if defined(USE_IT_CHAIN_MGR)
+TDFM_ItServList gAccADC12BHandler = {AT91C_ID_ADC_PRESENT, ADC12B_IrqHandler, NULL};
+#endif
+//------------------------------------------------------------------------------
+/// ADC12B and accelerometer initialization
+//------------------------------------------------------------------------------
+int DV_ACCELEROMETER_Init(void)
+{
+ int cali_done = 0;
+ char keyStatus = 0;
+ Pin pinSleep;
+ pinSleep.attribute = PIO_DEFAULT;
+ pinSleep.mask = (1<<13);
+ pinSleep.id = AT91C_ID_PIOC;
+ pinSleep.pio = AT91C_BASE_PIOC;
+ pinSleep.type = PIO_OUTPUT_1;
+
+ ///Normal mode
+ PIO_Configure(&pinSleep,1);
+ PIO_Set(&pinSleep);
+
+#ifdef PINS_ADC
+ PIO_Configure(pinsADC, PIO_LISTSIZE(pinsADC));
+#endif
+ ///ADC12B configuration
+ ADC12_Initialize( AT91C_BASE_ADC,
+ AT91C_ID_ADC_PRESENT,
+ AT91C_ADC12B_MR_TRGEN_DIS,
+ 0,
+ AT91C_ADC12B_MR_SLEEP_NORMAL,
+ AT91C_ADC12B_MR_LOWRES_12_BIT,//for 12bit adc,0 means 12bits,1-10bits
+ BOARD_MCK,
+ BOARD_ADC12_FREQ,
+ 10,
+ 2400);
+ ///Enable 3 channels for x,y and z
+ ADC12_EnableChannel(AT91C_BASE_ADC, ADC12_channel_x);
+ ADC12_EnableChannel(AT91C_BASE_ADC, ADC12_channel_y);
+ ADC12_EnableChannel(AT91C_BASE_ADC, ADC12_channel_z);
+
+ ///Enable adc12b interrupt
+ //IRQ_ConfigureIT(AT91C_ID_ADC_PRESENT, 0, ADCC0_IrqHandler);
+ // IRQ_EnableIT(AT91C_ID_ADC_PRESENT);
+#if defined(USE_IT_CHAIN_MGR)
+ DFM_RegisterItHandler(&gAccADC12BHandler);
+#endif
+
+ IRQ_EnableIT(AT91C_ID_ADC_PRESENT);
+
+ conversionDone = 0;
+
+ ///Enable channel interrupt
+ ADC12_EnableIt(AT91C_BASE_ADC, 1<<ADC12_channel_x);
+ ADC12_EnableIt(AT91C_BASE_ADC, 1<<ADC12_channel_y);
+ ADC12_EnableIt(AT91C_BASE_ADC, 1<<ADC12_channel_z);
+
+ /// Start measurement
+ ADC12_StartConversion(AT91C_BASE_ADC);
+
+ ///if calibration needed here?
+
+ // Do calibration first,ineteract with users
+ LCDD_Fill(((void *)BOARD_LCD_BASE),0xffffff);
+ //LCDD_DrawString((void *)BOARD_LCD_BASE,10,100,"Put the board on \nthe horizontal \nsurface and press \nBP4 to start \ncalibration!",0x0);
+
+ //PIO_InitializeInterrupts(0);
+ //PIO_Configure(&pinBP4,1);
+ //keyStatus = 1;
+ while(cali_done == 0)
+ {
+ // Check if button state has changed
+ //unsigned char isButtonPressed = PIO_Get(&pinBP4);
+ //if (isButtonPressed != keyStatus) {
+
+ // Update button state
+ //if (!isButtonPressed) {
+
+ // Key has been pressed
+ //printf("BP4 has been pressed!\n");
+ //keyStatus = 0;
+
+ DoCalibration();
+ cali_done = 1;
+
+
+ //}
+ //}
+ }
+ return 0;
+
+}
+
+//------------------------------------------------------------------------------
+/// Get immediate acceleration
+//------------------------------------------------------------------------------
+void DV_ACCELEROMETER_Measure(void)
+{
+ acc.m = acc_get_value(AT91C_BASE_ADC, ADC12_channel_x, ADC12_channel_y, ADC12_channel_z) ;
+
+}
+
+
+//------------------------------------------------------------------------------
+///
+///Measure the direction,left,right,forward,backward,then switch rotation axis
+///appopriately
+///
+//------------------------------------------------------------------------------
+void DV_Accelerometer_Turn()
+{
+ int dir = DV_Accelerometer_Tilt();
+ switch(dir)
+ {
+ case DV_Accelerometer_Unchanged:
+ rotation_axes_cpt = 0;
+ break;
+ case DV_Accelerometer_left:
+ rotation_axes_cpt = 4;
+ break;
+ case DV_Accelerometer_right:
+ rotation_axes_cpt = 3;
+ break;
+ case DV_Accelerometer_up:
+ rotation_axes_cpt = 2;
+ break;
+ case DV_Accelerometer_down:
+ rotation_axes_cpt = 1;
+ break;
+ case DV_Accelerometer_up_right:
+ rotation_axes_cpt = 6;
+ break;
+ case DV_Accelerometer_up_left:
+ rotation_axes_cpt = 8;
+ break;
+ case DV_Accelerometer_down_right:
+ rotation_axes_cpt = 5;
+ break;
+ case DV_Accelerometer_down_left:
+ rotation_axes_cpt = 7;
+ break;
+ }
+}
+
+
+//Accelerometer init in level 6
+DFM_INIT(6, DV_ACCELEROMETER_Init);
+
+
diff --git a/utility/demo-fw/common/dfm_button.c b/utility/demo-fw/common/dfm_button.c
new file mode 100644
index 0000000..b0d9d54
--- /dev/null
+++ b/utility/demo-fw/common/dfm_button.c
@@ -0,0 +1,248 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ----------------------------------------------------------------------------
+ */
+
+#include <stdio.h>
+#include <pio/pio.h>
+#include <lcd/draw.h>
+#include <lcd/color.h>
+#include <utility/trace.h>
+
+#include "dfm_init.h"
+#include "dfm_cmd.h"
+#include "dfm_button.h"
+#include "dfm_lcd_tsd.h"
+
+//------------------------------------------------------------------------------
+// variable definition
+//------------------------------------------------------------------------------
+/// global BUTTON entry
+TInputEntry gButtonEntry = \
+ {0, {NULL,NULL}, BTN_ShowPrompt, BTN_CommandIsReady, BTN_GetCommand, NULL};
+
+/// global active icon, a focus circle should be drawn around it
+unsigned int gActiveIconIndex;
+
+//button pin definition
+static Pin pinsPushButtons[] = {PINS_PUSHBUTTONS};
+
+//------------------------------------------------------------------------------
+// Exported functions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// Init button
+//------------------------------------------------------------------------------
+int BTN_Init(void)
+{
+ printf("\n\r Init Button!");
+
+ gActiveIconIndex = 0;
+
+ //memset(keyStatus, 1, 2);
+
+ PIO_Configure(pinsPushButtons, PIO_LISTSIZE(pinsPushButtons));
+
+ return 0;
+}
+
+//decleare to init it in level 5
+DFM_INIT(5, BTN_Init);
+
+//------------------------------------------------------------------------------
+/// Draw a focus circle around current active icon
+/// \param colormask, color mask to generate a masked color to draw
+//------------------------------------------------------------------------------
+static void DrawIconSelection(unsigned int linkZoneIndex, unsigned int colorMask)
+{
+ unsigned int i, left, bottom, width, height;
+ unsigned short color16;
+ unsigned int color, color24;
+
+ //index correcttion
+ if(linkZoneIndex >= gActiveSlideHeader.linkcount)
+ linkZoneIndex = gActiveSlideHeader.linkcount - 1;
+
+ bottom = gActiveSlideHeader.linkinfo[linkZoneIndex].linkboxbottom;
+ left = gActiveSlideHeader.linkinfo[linkZoneIndex].linkboxleft;
+ width = gActiveSlideHeader.linkinfo[linkZoneIndex].linkboxwidth;
+ height = gActiveSlideHeader.linkinfo[linkZoneIndex].linkboxheight;
+
+#ifndef RGB16ToRGB24
+/// Convert 16-bits color to 24-bits color, detail lost, only for compatible.
+#define RGB16ToRGB24(color) (((color & 0XF800) << 8) | \
+ ((color & 0x7E0) << 5) | \
+ ((color & 0x1F) << 3))
+#endif
+
+ for(i = 0; i < (width + 2); ++i) {
+ color16 = LCDD_ReadPixel((void *)BOARD_LCD_BASE,
+ left + i,
+ bottom);
+ color = RGB16ToRGB24(color16);
+ color24 = color ^ colorMask;
+
+ LCDD_DrawPixel((void *)BOARD_LCD_BASE,
+ left + i,
+ bottom,
+ color24);
+
+ color16 = LCDD_ReadPixel((void *)BOARD_LCD_BASE,
+ left + i,
+ bottom - height - 1);
+ color = RGB16ToRGB24(color16);
+ color24 = color ^ colorMask;
+
+ LCDD_DrawPixel((void *)BOARD_LCD_BASE,
+ left + i,
+ bottom - height - 1,
+ color24);
+ }
+
+ for(i = 1; i < (height + 1); ++i) {
+ color16 = LCDD_ReadPixel((void *)BOARD_LCD_BASE,
+ left,
+ bottom - i);
+
+ color = RGB16ToRGB24(color16);
+ color24 = color ^ colorMask;
+
+ LCDD_DrawPixel((void *)BOARD_LCD_BASE,
+ left,
+ bottom - i,
+ color24);
+
+ color16 = LCDD_ReadPixel((void *)BOARD_LCD_BASE,
+ left + width + 1,
+ bottom - i);
+
+ color = RGB16ToRGB24(color16);
+ color24 = color ^ colorMask;
+
+ LCDD_DrawPixel((void *)BOARD_LCD_BASE,
+ left + width + 1,
+ bottom - i,
+ color24);
+ }
+
+}
+
+//------------------------------------------------------------------------------
+/// Draw a focus circle on current active icon
+//------------------------------------------------------------------------------
+int BTN_ShowPrompt()
+{
+ static unsigned int iconDrawedIndex = 0xFFFFFFFF;
+ static unsigned int slidePageLoaded = 0xFFFFFFFF;
+
+ if(slidePageLoaded != gActiveSlideIndex) {
+ slidePageLoaded = gActiveSlideIndex;
+ iconDrawedIndex = gActiveIconIndex = 0;
+
+ DrawIconSelection(gActiveIconIndex, COLOR_AZUR);
+ } else {
+ if(iconDrawedIndex != gActiveIconIndex) {
+ DrawIconSelection(iconDrawedIndex, COLOR_AZUR);
+
+ DrawIconSelection(gActiveIconIndex, COLOR_AZUR);
+
+ iconDrawedIndex = gActiveIconIndex;
+ }
+ }
+
+ return 0;
+}
+
+//------------------------------------------------------------------------------
+/// Check button press/release status, if OK button press/released, then true
+/// \return 0 means not ready, 1 means yes.
+//------------------------------------------------------------------------------
+//check if button is pressed
+unsigned int BTN_CommandIsReady()
+{
+ //unsigned int i;
+ static unsigned int selPressFlag = 0;
+ static unsigned int okPressFlag = 0;
+ unsigned int ret = 0;
+ unsigned char btnStatus;
+
+ //read icon selection button status
+ btnStatus = PIO_Get(&(pinsPushButtons[0]));
+
+ //icon selection button pressed
+ if(btnStatus == 0) {
+ if(!selPressFlag) {
+// //use same color mask to clear previous focus circle
+// DrawIconSelection(COLOR_AZUR);
+
+ //increase icon index to next
+ ++gActiveIconIndex;
+ if(gActiveIconIndex >= gActiveSlideHeader.linkcount)
+ gActiveIconIndex = 0;
+
+// //use a color mask to draw a focus circle for icon
+// DrawIconSelection(COLOR_AZUR);
+
+ //set selection button pressed flag to wait button release
+ selPressFlag = 1;
+ }
+ } else {
+ //pressed key released
+ selPressFlag = 0;
+ }
+
+ //read icon confirm button status
+ btnStatus = PIO_Get(&(pinsPushButtons[1]));
+
+ //ok button pressed
+ if(btnStatus == 0)
+ {
+ if(!okPressFlag) {
+ //set ok button pressed flag to wait button release
+ okPressFlag = 1;
+ }
+ } else {
+ if(okPressFlag) {
+ //pressed key released,then return 1 to id command is ready
+ ret = 1;
+ okPressFlag = 0;
+ }
+ }
+
+ return ret;
+}
+
+//------------------------------------------------------------------------------
+/// Get commands for selected icon
+/// \return command string for the selected icon
+//------------------------------------------------------------------------------
+const char * BTN_GetCommand()
+{
+ return GetLinkStrFromActiveSlide(gActiveIconIndex + 1);
+}
+
diff --git a/utility/demo-fw/common/dfm_cmd.c b/utility/demo-fw/common/dfm_cmd.c
new file mode 100644
index 0000000..12463ad
--- /dev/null
+++ b/utility/demo-fw/common/dfm_cmd.c
@@ -0,0 +1,880 @@
+/* ----------------------------------------------------------------------------
+ * 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 <string.h>
+#include <stdio.h>
+#include "dfm_cmd.h"
+#include "dfm_init.h"
+#include "dfm_fatfs.h"
+#include "dfm_console.h"
+#include "dfm_lcd_tsd.h"
+#include "dfm_button.h"
+
+//------------------------------------------------------------------------------
+// variable definition
+//------------------------------------------------------------------------------
+#if defined(__ICCARM__)//IAR Compiler ID
+
+///no need for declaration of section start and end variable in IAR
+
+#elif defined(__CC_ARM) //MDK ARM Compiler ID
+
+///variables for group start/end address
+ extern unsigned int Image$$GShell_region$$Base;
+ extern unsigned int Image$$GShell_region$$Limit;
+
+#elif defined(__GNUC__)//GNU ARM Compiler ID
+
+///variables for group start/end address
+extern long __gs_section_start, __gs_section_end;
+
+#endif
+
+///active group for execution of searching of commands. End with NULL
+static char *gpActGroups[MAX_ACT_GROUP + 1] = {SYS_GROUP};// default group init first.
+
+///entry
+
+//------------------------------------------------------------------------------
+// Internal functions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// parse a tring into '*argv[]', delimitor is space or tab
+/// \param pRawString, the whole line of command string
+/// \param argv, parsed argument string array
+/// \return number of parsed argument
+//------------------------------------------------------------------------------
+static int StringLineToArgs(char *pRawString, char *argv[]) {
+ int argc = 0;
+
+ if(pRawString == NULL)
+ return 0;
+
+ while(argc < MAX_CMD_ARGS) {
+
+ // skip white space characters of string head
+ while ((*pRawString == ' ') || (*pRawString == '\t')) {
+ ++pRawString;
+ }
+
+ if (*pRawString == '\0') {
+ argv[argc] = NULL;
+ return (argc);
+ }
+
+ argv[argc++] = pRawString;
+
+ // find end of string
+ while (*pRawString && (*pRawString != ' ') && (*pRawString != '\t')) {
+ ++pRawString;
+ }
+
+ if (*pRawString == '\0') {
+ argv[argc] = NULL;
+ return (argc);
+ }
+
+ *pRawString++ = '\0';
+ }
+
+ printf ("\n\r Too many arguments. Maximum argus supported is %d!", MAX_CMD_ARGS);
+
+ return (argc);
+}
+
+//------------------------------------------------------------------------------
+/// search active group name in array and return index.
+/// \param pStr, group name string
+/// \param pStrArray, group array
+/// \param iArrayLen, array length
+/// \return group index in group array, -1 if not found
+//------------------------------------------------------------------------------
+static int FindStrIdx(const char * pStr, const char * const pStrArray[], int iArrayLen)
+{
+ int i;
+
+ //search, end when find NULL or exceed max len
+ for(i = 0; i < iArrayLen && pStrArray[i] != NULL; ++i) {
+ //printf("\n\r str is %s, %s, %d",pStr, pStrArray[i], iArrayLen);
+ if(strcmp(pStr, pStrArray[i])==0) {
+ break;
+ }
+ }
+
+ //if not found
+ if(i==iArrayLen || pStrArray[i] == NULL) {
+ i = -1;
+ }
+
+ return i;
+}
+
+//------------------------------------------------------------------------------
+/// Find command in active groups
+/// \param pCmd, command name
+/// \return pointer to command portal, NULL if not found
+//------------------------------------------------------------------------------
+static FStruct * FindCommand(const char * pCmd)
+{
+ int iGrpIdxAct;
+ unsigned int i, iCmdNum;
+ unsigned short int gm, im;// max:0xffff, init value used to id fail search
+ FStruct *pTmpFs, *pFsStart, *pFsEnd;
+
+#if defined(__ICCARM__)
+ pFsStart = __section_begin(GSHELL_SECTION);
+ pFsEnd = __section_end(GSHELL_SECTION);
+#elif defined(__CC_ARM)
+ pFsStart = (FStruct *)&Image$$GShell_region$$Base;
+ pFsEnd = (FStruct *)&Image$$GShell_region$$Limit;
+#elif defined(__GNUC__)
+ pFsStart = (FStruct *)&__gs_section_start;
+ pFsEnd = (FStruct *)&__gs_section_end;
+#else
+#error "Unsupported tool chain"
+#endif
+
+ iCmdNum = pFsEnd - pFsStart;
+
+ for(i=0,gm=0xffff, im=0xffff; i < iCmdNum; ++i) {
+ if(strcmp((pFsStart + i)->pCmdName, pCmd)==0) {
+ iGrpIdxAct = FindStrIdx((pFsStart + i)->pGrpName,
+ gpActGroups,
+ MAX_ACT_GROUP);
+
+ //group is not in active group list
+ if(iGrpIdxAct == -1) {
+ continue;
+ }
+
+ if(iGrpIdxAct < gm) {
+ gm = iGrpIdxAct;
+ im = i;
+ }
+ }
+
+ }
+
+
+ if(gm != 0xffff) {// found
+ pTmpFs = pFsStart + im;
+ } else {//not found
+ pTmpFs = NULL;
+ }
+
+ return pTmpFs;
+}
+
+//------------------------------------------------------------------------------
+// Exported Functions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// Parse a command string and search in active groups, run if matched
+/// \param pCmdString, command string including arguments
+/// \return 0 succeed, other value failure
+//------------------------------------------------------------------------------
+int ParseAndRunCmd(const char * pCmdString)
+{
+ FStruct *pFsCmd;
+ int argc, iRet;
+ char args[DBGU_CMDBUFSIZE];
+ char *argv[MAX_CMD_ARGS + 1];
+
+ //if NULL string, no run
+ if(!pCmdString)
+ return 0;
+
+ unsigned int strLength = strlen(pCmdString);
+
+ //empty string, no run
+ if(strLength == 0)
+ return 0;
+
+ if(strLength < DBGU_CMDBUFSIZE) {
+ strcpy(args, pCmdString);
+ }
+ else {
+ memcpy(args, pCmdString, DBGU_CMDBUFSIZE-1);
+ args[DBGU_CMDBUFSIZE-1] = '\0';
+ }
+
+ // parse a command string to *argv[]
+ argc = StringLineToArgs(args, argv);
+
+ // find matched command
+ if((pFsCmd = FindCommand(argv[0])) == NULL) {
+
+ printf("\n\r Command -'%s'- not found in active groups!", argv[0]);
+ iRet = 1;
+
+ } else {
+ // run command
+ iRet = (pFsCmd->cmdProcess)(argc, argv);
+ }
+
+ // return command running result
+ return iRet;
+}
+
+//------------------------------------------------------------------------------
+/// Parse a string line containing multi commands and arguments, then
+/// search in active groups, run if matched
+/// \param pMultiCmdStr, string line containing multi commands and arguments
+/// \return 0 succeed, other value failure
+//------------------------------------------------------------------------------
+int ParseAndRunMultiCmds(const char * pMultiCmdStr)
+{
+ char pMultiCmdStrBuf[DBGU_CMDBUFSIZE];
+ char *cmds[MAX_MULTI_CMD + 1], *pCmdsStr;
+ unsigned int i;
+ int iRet;
+
+ //if NULL string, no run
+ if(!pMultiCmdStr)
+ return 0;
+
+ unsigned int strLength = strlen(pMultiCmdStr);
+
+ //empty string, no run
+ if(strLength == 0)
+ return 0;
+
+ if(strLength < DBGU_CMDBUFSIZE) {
+ strcpy(pMultiCmdStrBuf, pMultiCmdStr);
+ }
+ else {
+ memcpy(pMultiCmdStrBuf, pMultiCmdStr, DBGU_CMDBUFSIZE-1);
+ pMultiCmdStrBuf[DBGU_CMDBUFSIZE-1] = '\0';
+ }
+
+ i = 0;
+ pCmdsStr = (char *)(&pMultiCmdStrBuf[0]);
+ //parse multi commands
+ while(i < MAX_MULTI_CMD) {
+
+ // skip white space characters of string head
+ while ((*pCmdsStr == ' ') || (*pCmdsStr == '\t')) {
+ ++pCmdsStr;
+ }
+
+ if (*pCmdsStr == '\0') {
+ cmds[i] = NULL;
+ break;
+ }
+
+ cmds[i++] = pCmdsStr;
+
+ // parse commands
+ while (*pCmdsStr) {
+ if( ((*(pCmdsStr - 1) == ' ') || (*(pCmdsStr - 1) == '\t'))
+ && (*pCmdsStr == '&')
+ && (*(pCmdsStr + 1) == '&'))
+ break;// find the mark for next commands, then break
+ else
+ ++ pCmdsStr;
+ }
+
+ if (*pCmdsStr == '\0') {
+ cmds[i] = NULL;
+ break;
+ }
+
+ *(pCmdsStr - 1) = '\0';
+ pCmdsStr += 2;
+
+ }// end of parse
+
+ //if too many command in a line, warning
+ if(i >= MAX_MULTI_CMD)
+ printf ("\n\r Too many command in one line. Maximum cmds supported is %d!", MAX_MULTI_CMD);
+
+ unsigned int j;
+ for (j = 0; j < i; ++j) {
+ iRet |= ParseAndRunCmd(cmds[j]);
+ }
+
+ return iRet;
+}
+
+//------------------------------------------------------------------------------
+/// Run batch command
+/// \param argc, number of command string
+/// \param argv, pointer array to command string
+/// \return 0 succeed, other value failure
+//------------------------------------------------------------------------------
+int RunScript(int argc, char *argv[])
+{
+ int i, iRet=0;
+
+ // run script
+ for(i = 0; i<argc; ++i) {
+ iRet |= ParseAndRunMultiCmds(argv[i]);
+ }
+
+ return iRet;
+}
+
+//------------------------------------------------------------------------------
+/// Show all groups and commands, portal of command 'showall'
+/// \param argc, number of argument
+/// \param argv, argument string array
+/// \return 0 succeed, other value failure
+//------------------------------------------------------------------------------
+int DFM_ShowAllGrpCmd(int argc, char **argv)
+{
+ int i, j, iGrpCnt, iCmdCnt, iCmdNum;
+ char *pGrpList[MAX_LIST_GROUP+1];
+ FStruct *pCmdList[MAX_ACT_CMD];
+ FStruct *pFsStart, *pFsEnd, *pFsTmp;
+
+#if defined(__ICCARM__)
+ pFsStart = __section_begin(GSHELL_SECTION);
+ pFsEnd = __section_end(GSHELL_SECTION);
+#elif defined(__CC_ARM)
+ pFsStart = (FStruct *)&Image$$GShell_region$$Base;
+ pFsEnd = (FStruct *)&Image$$GShell_region$$Limit;
+#elif defined(__GNUC__)
+ pFsStart = (FStruct *) &__gs_section_start;
+ pFsEnd = (FStruct *) &__gs_section_end;
+#else
+#error "Unsupported tool chain"
+#endif
+
+ iCmdNum = pFsEnd - pFsStart;
+
+ //dumb, time consumption but less ram consumption way to list group
+ //get group list in section, MAX_LIST_GROUP limit
+ pGrpList[0] = NULL;
+ for(i=0,iGrpCnt=0; i<iCmdNum && iGrpCnt < MAX_LIST_GROUP; ++i) {
+
+ if(FindStrIdx((pFsStart+i)->pGrpName, pGrpList, MAX_LIST_GROUP) == -1) {
+ pGrpList[iGrpCnt++] = (pFsStart+i)->pGrpName;
+ pGrpList[iGrpCnt] = NULL;
+ }
+ }
+
+ if(iGrpCnt >= MAX_LIST_GROUP) {
+ printf("\n\r Only first 100 groups are shown!");
+ }
+
+ //list all command under group list, sorted
+ //Get command lists first
+ iGrpCnt=0;
+ while(pGrpList[iGrpCnt] != NULL) {
+ for(i=0,iCmdCnt=0;i<iCmdNum && iCmdCnt<MAX_ACT_CMD;++i) {
+ if(strcmp((pFsStart+i)->pGrpName, pGrpList[iGrpCnt]) ==0) {
+ pCmdList[iCmdCnt++]=pFsStart+i;
+ }
+ }
+
+ //show prompt info
+ if(iCmdCnt>=MAX_ACT_CMD) {
+ printf("\n\r Group: %s, (>=%d) commands", pGrpList[iGrpCnt], iCmdCnt);
+ } else {
+ printf("\n\r Group: %s, (%d) commands", pGrpList[iGrpCnt], iCmdCnt);
+ }
+
+ int bExchgFlag;
+ //sort command list
+ for(i = 0; i < iCmdCnt - 1; ++i) {
+ // flag, if no exchange, then array has been sorted
+ bExchgFlag = 0;
+
+ //bubble sort in ascending order
+ for(j = iCmdCnt - 1; j > i; --j){
+ if(strcmp(pCmdList[j]->pCmdName, pCmdList[j-1]->pCmdName) < 0) {
+ pFsTmp = pCmdList[j];
+ pCmdList[j] = pCmdList[j-1];
+ pCmdList[j-1] = pFsTmp;
+
+ // exchanged
+ bExchgFlag = 1;
+ }
+ }
+
+ // if no exchange, array sorted
+ if(!bExchgFlag)
+ break;
+ }
+
+ //print commands under group
+ for(i=0;i<iCmdCnt;++i) {
+ printf("\n\r %s",pCmdList[i]->pCmdName);
+ }
+
+ //check next group then
+ ++iGrpCnt;
+ }
+
+ printf("\n\r");
+
+ return 0;
+}
+
+///define a new system command 'showall'
+DFM_CMD(showall, DFM_ShowAllGrpCmd, "show all groups and commands.", SYS_GROUP);
+
+//------------------------------------------------------------------------------
+/// Show command help message, portal of command 'help'
+/// \param argc, number of argument
+/// \param argv, argument string array
+/// \return 0 succeed, other value failure
+//------------------------------------------------------------------------------
+int DFM_Help(int argc, char **argv)
+{
+ int i, iRet = 0;
+ FStruct *pTmpFs;
+
+ if(argc == 1) { // show all command in active groups
+ int j, iCmdNum, iCmdCnt, bExchgFlag;
+ FStruct *pFsCmds[MAX_ACT_CMD];
+ FStruct *pFsStart, *pFsEnd;
+
+#if defined(__ICCARM__)
+ pFsStart = __section_begin(GSHELL_SECTION);
+ pFsEnd = __section_end(GSHELL_SECTION);
+#elif defined(__CC_ARM)
+ pFsStart = (FStruct *)&Image$$GShell_region$$Base;
+ pFsEnd = (FStruct *)&Image$$GShell_region$$Limit;
+#elif defined(__GNUC__)
+ pFsStart = (FStruct *)&__gs_section_start;
+ pFsEnd = (FStruct *)&__gs_section_end;
+#else
+#error "Unsupported tool chain"
+#endif
+
+ //total command numbers in GSHELL_SECTION
+ iCmdNum = pFsEnd - pFsStart;
+
+ i = 0; iCmdCnt=0;
+ //get all commands in active groups
+ while(i < iCmdNum && iCmdCnt < MAX_ACT_CMD) {
+ if(FindStrIdx((pFsStart+i)->pGrpName, gpActGroups, MAX_ACT_GROUP) != -1) {
+ pFsCmds[iCmdCnt++] = pFsStart + i;
+ }
+ ++i;
+ }
+ //now 'iCmdCnt' has value of available command numbers in active groups
+ if(iCmdCnt < MAX_ACT_CMD) {
+ printf("\n\r Total %d commands available.\n\r", iCmdCnt);
+ } else {
+ printf("\n\r Too many, Only %d commands are shown!", MAX_ACT_CMD);
+ }
+
+
+ // sort active group commands for better help result print
+ for(i = 0; i < iCmdCnt - 1; ++i) {
+ // flag, if no exchange, then array has been sorted
+ bExchgFlag = 0;
+
+ //bubble sort in ascending order
+ for(j = iCmdCnt - 1; j > i; --j){
+ if(strcmp(pFsCmds[j]->pCmdName, pFsCmds[j-1]->pCmdName) < 0) {
+ pTmpFs = pFsCmds[j];
+ pFsCmds[j] = pFsCmds[j-1];
+ pFsCmds[j-1] = pTmpFs;
+
+ // exchanged
+ bExchgFlag = 1;
+ }
+ }
+
+ // no exchange, array sorted
+ if(!bExchgFlag)
+ break;
+ }
+
+ printf("\n\r");
+ //print command, and help message if there is
+ for(i = 0; i < iCmdCnt; ++i) {
+ if(pFsCmds[i] == NULL)
+ continue;
+
+ printf(" %s ",pFsCmds[i]->pCmdName);
+#ifdef USAGE_HELP
+ printf(" %s",pFsCmds[i]->pUsage);
+#endif
+ printf("\n\r");
+ }
+ //end of argc== 1
+
+ } else {
+
+ //print available command help or error message
+ for(i = 1; i < argc; ++i) {
+ pTmpFs = FindCommand(argv[i]);
+
+ if(pTmpFs != NULL) {
+
+#ifdef USAGE_HELP
+ printf("\n\r%s", pTmpFs->pCmdName);
+ if(pTmpFs->pUsage) {
+ printf(" %s\n\r",pTmpFs->pUsage);
+ } else {
+ printf(" <No help information>\n\r");
+ iRet = 1;
+ }
+
+#else
+ printf("\n\r <No usage help for '%s'>", argv[i]);
+
+#endif
+
+ } else {
+ printf("\n\r No command '%s' under active groups!\n\r", argv[i]);
+ iRet = 2;
+ }
+ }
+ }
+
+ return iRet;
+}
+
+///define a new system command 'help'
+DFM_CMD(help, DFM_Help, "help command usage", SYS_GROUP);
+
+//------------------------------------------------------------------------------
+/// Set active groups, portal of command 'setact'
+/// \param argc, number of argument
+/// \param argv, argument string array
+/// \return 0 succeed, other value failure
+//------------------------------------------------------------------------------
+int DFM_SetActiveGrp(int argc, char **argv)
+{
+ int i, iIdxList, iCmdNum, iRet = 0;
+ char *pGrpList[MAX_LIST_GROUP+1];
+ FStruct *pFsStart, *pFsEnd;
+
+ //fill array with NULL, last NULL will act as an end
+ for(i = 0; i < MAX_LIST_GROUP+1; ++i) {
+ pGrpList[i] = NULL;
+ }
+
+#if defined(__ICCARM__)
+ pFsStart = __section_begin(GSHELL_SECTION);
+ pFsEnd = __section_end(GSHELL_SECTION);
+#elif defined(__CC_ARM)
+ pFsStart = (FStruct *)&Image$$GShell_region$$Base;
+ pFsEnd = (FStruct *)&Image$$GShell_region$$Limit;
+#elif defined(__GNUC__)
+ pFsStart = (FStruct *)&__gs_section_start;
+ pFsEnd = (FStruct *)&__gs_section_end;
+#else
+#error "Unsupported tool chain"
+#endif
+
+ iCmdNum = pFsEnd - pFsStart;
+ //printf("\n\r pFsStart is %d", pFsStart);
+
+ if(argc == 1) { //show available groups for help
+
+ printf("\n\r Available Groups:\n\r");
+
+ //collect all buildin group names, only MAX_LIST_GROUP will be shown
+ for(i=0,iIdxList=0; i<iCmdNum && iIdxList<MAX_LIST_GROUP; ++i) {
+ //printf("\n\r group name is %s, cmd name is %s", (pFsStart+i)->pGrpName, (pFsStart+i)->pCmdName);
+ //no group name in list already
+ if(FindStrIdx((pFsStart+i)->pGrpName, pGrpList, MAX_LIST_GROUP) == -1) {
+ pGrpList[iIdxList++] = (pFsStart+i)->pGrpName;
+ //printf("\n\r %s", pGrpList[iIdxList-1]);
+ }
+ }
+
+
+ //show avail group list, MAX_LIST_GROUP
+ for(i=0; pGrpList[i] != NULL; ++i) {
+ printf(" %s\n\r", pGrpList[i]);
+ }
+
+ //reach MAX_LIST_GROUP, show info
+ if(i== MAX_LIST_GROUP) {
+ printf(" ...\n\r");
+ printf(" -Only '%d' groups will be shown!\n\r", MAX_LIST_GROUP);
+ }
+ // end of argc==1
+
+ } else {
+
+ int j,iIdxAct, bFindFlag = 0;
+
+ // used as index in active groups arrays below. Begin after 0(SYS_GROUP/"default")
+ // no appending mode. Previous active groups except SYS_GROUP/"default" will be removed,
+ // if not listed in *argv[].
+ iIdxAct = 1;
+
+ for(i = 1; i < argc ; ++i) {
+ //flag for group name argument match check/
+ bFindFlag = 0;
+
+ //reach limit number of MAX_ACT_GROUP
+ if(iIdxAct >= MAX_ACT_GROUP) {
+ printf("\n\rWarning : Active group number is limited within -'%d'- !\n\r",MAX_ACT_GROUP);
+ iRet = 1;//identify maxium active groups
+ break;
+ }
+
+ //default group is always active, and at the first priority
+ if(strcmp(argv[i], SYS_GROUP) == 0) {
+ continue;
+ }
+
+ //search for matched groups
+ for(j = 0; j < iCmdNum; ++j) {
+ if(strcmp(argv[i], (pFsStart+j)->pGrpName) == 0) {
+ bFindFlag = 1;
+ break;
+ }
+ }
+
+ //group name argument matched
+ if(bFindFlag) {
+ gpActGroups[iIdxAct++] = (pFsStart+j)->pGrpName;
+ } else {
+ printf("\n\r No group '%s' in available list!", argv[i]);
+ iRet = 2;// some error group name input
+ }
+ }
+
+ // no appending mode. previous active groups excetp SYS_GROUP/"default" will be removed,
+ // if not listed in *argv[].
+ while(iIdxAct < MAX_ACT_GROUP) {
+ gpActGroups[iIdxAct++] = NULL;
+ }
+
+ }
+
+ // show active group
+ i =0;
+ printf("\n\r\n\r ----Active Group: ");
+ while(gpActGroups[i] != NULL && i < MAX_ACT_GROUP) {
+ printf(" %s;", gpActGroups[i]);
+ i++;
+ }
+ printf(" ----\n\r");
+
+ return iRet;
+}
+
+///define a new system command 'setact'
+DFM_CMD(setact, DFM_SetActiveGrp, "set active groups", SYS_GROUP);
+
+#if defined(HELLO_TUTOR)
+//------------------------------------------------------------------------------
+/// A simple tutor for using gshell, portal of command 'showall'
+/// \param argc, number of argument
+/// \param argv, argument string array
+/// \return 0 succeed, other value failure
+//------------------------------------------------------------------------------
+int DFM_HelloTutor(int argc, char **argv)
+{
+ char *pTutorInfo = {
+ "\n\r -----------------------------Hello, World----------------------------"
+ "\n\r As a COMMAND 'thirsty' system, you may not know how to talk with me."
+ "\n\r I learnt much to write this message to explain how I can learn new "
+ "\n\r COMMANDs from you."
+ "\n\r"
+ "\n\r --- gs_cmd.h --- under project's --- include --- directory tell you"
+ "\n\r definitions of macros and limits of my system. Put it in your comma-"
+ "\n\r nd portal code's header or source file."
+ "\n\r"
+ "\n\r In this head file, an important macro acts as the translator that is"
+ "\n\r used to teach me your new commands:"
+ "\n\r DFM_CMD(cmdString, procFunc, hlpString, grpName)"
+ "\n\r"
+ "\n\r I'd like to tell you some rules about parameters of above macro."
+ "\n\r 'cmdString' is the command name you want to teach me. Double quota-"
+ "\n\r tion marks, \", is not necessary; 'procFunc' is the portal fuction t-"
+ "\n\r hat perform what this command do; 'hlpString' is help message to re-"
+ "\n\r member what is this command's usage, please note, double quotation "
+ "\n\r marks, \", is necessary; 'grpName' is double quoted string that cla-"
+ "\n\r ssify what group this command belongs to. Use it carefully to avoid "
+ "\n\r mess classification, because I don't limit the name choice."
+ "\n\r"
+ "\n\r The last thing remeber is definition of your portal function should has"
+ "\n\r the same number and type of parameters and return type like following:"
+ "\n\r int FuncName(int argc, char **argv)"
+ "\n\r"
+ "\n\r 'func' is normally pointed yourself portal function when I call this."
+ "\n\r 'argc' and '*argv[]' work as the same way that you learn C language, "
+ "\n\r but they are parsed from command string typed in my console window. "
+ "\n\r"
+ "\n\r If you want to see an example of teaching me a new command, try to type"
+ "\n\r this command under 'DFM_CMD:>' hello example"
+ "\n\r"
+ };
+
+ char *pTutorExample = {
+ "\n\r /* example, hi.c */"
+ "\n\r #include \"gs_cmd.h\""
+ "\n\r"
+ "\n\r int DFM_Hi(int argc, char *argv[])"
+ "\n\r {"
+ "\n\r printf(\"Command %s say HI!\", argv[0]);"
+ "\n\r }"
+ "\n\r"
+ "\n\r DFM_CMD(hi, DFM_Hi, \"say hi to everybody!\", \"default\");"
+ "\n\r\n\r"
+ };
+
+ if(argc == 2 && strcmp(argv[1], "example")==0) {
+ printf("\n\r%s", pTutorExample);
+ } else {
+ printf("\n\r%s", pTutorInfo);
+ }
+
+ return 0;
+}
+
+///define the new system command for tutor, 'hello'
+DFM_CMD(hello, DFM_HelloTutor, "A simple tutor for develop guide", SYS_GROUP);
+
+#endif
+
+
+//-----------------------------------------------------------------------------
+/// Exported Function
+//-----------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// Demo Frame main portal route to get command and interpret it to run
+/// \param argc, command number of initial running
+/// \param argv, pointer array to initial running command strings
+//------------------------------------------------------------------------------
+// void Gshell_MainProcess(int argc, char *argv[])
+// {
+// TCmdQueue *pCmdQueue;
+//
+// //Run autorun script
+// RunScript(argc, argv);
+//
+// //register input entry
+// RegisterInputEntry(&gDBGUEntry);
+// RegisterInputEntry(&gLCDEntry);
+// RegisterInputEntry(&gButtonEntry);
+//
+// ShowPrompt();
+//
+// while(1) {
+// if(!CommandIsReady())
+// continue;
+//
+// pCmdQueue = GetCommandQueue();
+//
+// RunCommandQueue(pCmdQueue);
+//
+// ShowPrompt();
+// }
+//
+// // while(1) {
+// //
+// // unsigned int index;
+// // if(index = TSD_CommandIsReady()) {
+// // pStr = TSD_GetCommand(index);
+// //
+// // printf("\n\r %s", pStr);
+// //
+// // }
+// //
+// // // Check DBGU console input is ready
+// // if(!DBGU_CommandIsReady())
+// // continue;
+// //
+// //
+// //#if 0
+// // //temp code to test sdcard and nandflash mount availability for every time
+// // // a new command is launched to run.
+// // FIL test;
+// // FRESULT res;
+// // unsigned int i;
+// // unsigned char buf[110];
+// //
+// // res = f_open(&test, SDCARD_ROOT_DIRECTORY"sam3demo.bin", FA_OPEN_EXISTING | FA_READ);
+// // if(res != FR_OK) {
+// // printf("\n\r Open file in SDCard fail!");
+// // } else {
+// // printf("\n\r Open file in SDCard succeed!");
+// // //test read file
+// // res = f_read(&test, buf, 100, &i);
+// // if(res!= FR_OK) {
+// // printf("\n\r --read first 100 bytes fail!");
+// // }else {
+// // printf("\n\r --read first 100 bytes succeeds!");
+// // }
+// // }
+// //
+// // f_close(&test);
+// //
+// // res = f_open(&test, NAND_ROOT_DIRECTORY"basic.bin", FA_OPEN_EXISTING | FA_READ);
+// // if(res != FR_OK) {
+// // printf("\n\r Open file in nandflash fail!");
+// // } else {
+// // printf("\n\r Open file in nandflash succeed!");
+// //
+// // res = f_read(&test, buf, 100, &i);
+// // if(res!= FR_OK) {
+// // printf("\n\r --read first 100 bytes fail!");
+// // }else {
+// // printf("\n\r --read first 100 bytes succeeds!");
+// // }
+// // }
+// // f_close(&test);
+// //#endif
+// //
+// //
+// // pStr = DBGU_GetCommand();
+// //
+// // // empty in DBGU command buffer
+// // if(*pStr == '\0') {
+// // continue;
+// // }
+// //
+// // if (strlen(pStr) >= DBGU_CMDBUFSIZE) {
+// // printf ("\n\r Command String is too long(max. %d)!\n\r", DBGU_CMDBUFSIZE);
+// // continue;
+// // }
+// //
+// // // create a local copy to protect console buffer
+// // strcpy (pCmdString, pStr);
+// //
+// // // parse and run command string
+// // ParseAndRunMultiCmds(pCmdString);
+// //
+// //// DBGU_ShowPrompt();
+// //// LCD_ShowPrompt();
+// //
+// // ShowPrompt();
+// // }
+// }
+
diff --git a/utility/demo-fw/common/dfm_console.c b/utility/demo-fw/common/dfm_console.c
new file mode 100644
index 0000000..7118a11
--- /dev/null
+++ b/utility/demo-fw/common/dfm_console.c
@@ -0,0 +1,216 @@
+//------------------------------------------------------------------------------
+// Headers
+//------------------------------------------------------------------------------
+
+#include <string.h>
+#include <dbgu/dbgu.h>
+#include <stdio.h>
+
+#include "dfm_console.h"
+#include "dfm_entry.h"
+#include "dfm_cmd.h"
+
+//------------------------------------------------------------------------------
+// Internal variables
+//------------------------------------------------------------------------------
+
+///DBGU input buffer
+static char gpConsoleBuffer[DBGU_CMDBUFSIZE];
+
+///prompt refresh flag
+static unsigned char gDBGUPromptFlag = 0;
+
+///erase sequence
+static char gpEraseSeq[] = "\b \b";
+///used to expand TABS
+static char gpTabSeq[] = " ";
+
+//------------------------------------------------------------------------------
+// Export variables
+//------------------------------------------------------------------------------
+
+// global DBGU entry
+TInputEntry gDBGUEntry = \
+ {0, {NULL,NULL},DBGU_ShowPrompt, DBGU_CommandIsReady, DBGU_GetCommand, NULL};
+
+//------------------------------------------------------------------------------
+// Internal functions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// output a string to console
+/// \param pStr, string to output to DBGU console
+//------------------------------------------------------------------------------
+static inline void DBGU_puts(const char *pStr)
+{
+ while(*pStr) {
+ DBGU_PutChar(*pStr++);
+ }
+}
+
+//------------------------------------------------------------------------------
+/// remove charaters from buffer positions
+//------------------------------------------------------------------------------
+static char * DBGU_RemoveCharFromBuf (char *buffer, char *p, int *colp, int *np, int plen)
+{
+ char *s;
+
+ if (*np == 0) {
+ return (p);
+ }
+
+ if (*(--p) == '\t') {
+ while (*colp > plen) {
+ DBGU_puts (gpEraseSeq);
+ (*colp)--;
+ }
+ for (s=buffer; s<p; ++s) {
+ if (*s == '\t') {
+ DBGU_puts (gpTabSeq+((*colp) & 07));
+ *colp += 8 - ((*colp) & 07);
+ } else {
+ ++(*colp);
+ DBGU_PutChar (*s);
+ }
+ }
+ } else {
+ DBGU_puts (gpEraseSeq);
+ (*colp)--;
+ }
+ (*np)--;
+ return (p);
+}
+
+//------------------------------------------------------------------------------
+/// Check console is ready?
+/// \return 0 not ready, other value means ready and command string length
+//------------------------------------------------------------------------------
+unsigned int DBGU_CommandIsReady()
+{
+ unsigned char c;
+ static char *p = gpConsoleBuffer;
+ int escflag = 0;
+ char * p_buf = gpConsoleBuffer;
+ static int n = 0; // buffer index
+ int plen = 0; // prompt length
+ static int col=0; // output column cnt
+ unsigned int cmdLen;
+
+ plen = strlen(GS_SHELL_PROMPT);
+
+ //right beginning of a new command input
+ if(col == 0)
+ col = plen;
+
+Tag_for_CombinedKey:
+
+ if(DBGU_IsRxReady()) {
+ c = DBGU_GetChar();
+
+ //
+ // Special character handling
+ //
+ switch (c) {
+ case '\r': // Enter
+ case '\n':
+ *p = '\0';
+ cmdLen = p - p_buf;
+ p = gpConsoleBuffer;
+ n = 0; //clear buffer index as 0
+ col = 0; // this is set for indicate next time input considered as new command
+ gDBGUPromptFlag = 1;//DBGU_puts ("\r\n");
+ return cmdLen;
+
+ case '\0': // nul
+ return 0;
+
+ case 0x03: // ^C - break
+ //p_buf[0] = '\0'; // discard input
+ return 0;
+
+ case 0x15: // ^U - erase line
+ while (col > plen) {
+ DBGU_puts (gpEraseSeq);
+ --col;
+ }
+ p = p_buf;
+ n = 0;
+ return 0;
+
+ case 0x17: // ^W - erase word
+ p=DBGU_RemoveCharFromBuf(p_buf, p, &col, &n, plen);
+ while ((n > 0) && (*p != ' ')) {
+ p=DBGU_RemoveCharFromBuf(p_buf, p, &col, &n, plen);
+ }
+ return 0;
+
+ case 0x08: // ^H - backspace
+ case 0x7F: // DEL - backspace
+ p=DBGU_RemoveCharFromBuf(p_buf, p, &col, &n, plen);
+ return 0;
+
+ case 0x1b: // arrow, home flag
+ escflag = 1;
+ goto Tag_for_CombinedKey;//in window hyperterminal, arrow and home flag
+ // keys are combined 1b + x
+
+ case 'D': //ignore arrow,home key
+ case 'C':
+ case 'H':
+ case 'A':
+ case 'B':
+ if(escflag) {
+ escflag = 0;
+ return 0;
+ }
+
+
+ default:
+ //
+ // Must be a normal character then
+ //
+ if (n < DBGU_CMDBUFSIZE-2) {
+ if (c == '\t') { // expand TABs
+ DBGU_puts (gpTabSeq+(col&07));
+ col += 8 - (col&07);
+ } else {
+ ++col; // echo input
+ DBGU_PutChar (c);
+ }
+ *p++ = c;
+ ++n;
+ } else { // Buffer full
+ DBGU_PutChar ('\a');
+ }
+ }
+ }
+
+ return 0;
+}
+
+//------------------------------------------------------------------------------
+/// get a const pointer to global console input buffer
+/// \return pointer to global DBGU console input buffer
+//------------------------------------------------------------------------------
+const char * DBGU_GetCommand() {
+ return (const char *)gpConsoleBuffer;
+}
+
+//------------------------------------------------------------------------------
+/// Show DBGU console prompt information
+/// \return 0, success
+//------------------------------------------------------------------------------
+int DBGU_ShowPrompt()
+{
+
+#if defined(GS_SHELL_PROMPT)
+ // print prompt
+ if(gDBGUPromptFlag) {
+ DBGU_puts("\n\r");
+ DBGU_puts (GS_SHELL_PROMPT);
+ gDBGUPromptFlag = 0;
+ }
+#endif
+
+ return 0;
+}
diff --git a/utility/demo-fw/common/dfm_dispboxmgr.c b/utility/demo-fw/common/dfm_dispboxmgr.c
new file mode 100644
index 0000000..55ad223
--- /dev/null
+++ b/utility/demo-fw/common/dfm_dispboxmgr.c
@@ -0,0 +1,481 @@
+/* ----------------------------------------------------------------------------
+ * 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 <string.h>
+#include <stdio.h>
+#include <lcd/font.h>
+#include <lcd/color.h>
+#include <lcd/draw.h>
+#include <components/hx8347/hx8347.h>
+#include <utility/trace.h>
+
+#include "dfm_config.h"
+#include "dfm_dispboxmgr.h"
+#include "dfm_accelerometer.h"
+//------------------------------------------------------------------------------
+// Internal variables
+//------------------------------------------------------------------------------
+
+static TDISPBOX_MGR dispBoxMgr= {
+ 0,
+ {{0, {0,0,0,0}, COLOR_WHITE, COLOR_BLUE, 0, 0},
+ {0, {0,0,0,0}, COLOR_WHITE, COLOR_BLUE, 0, 0},
+ {0, {0,0,0,0}, COLOR_WHITE, COLOR_BLUE, 0, 0},
+ {0, {0,0,0,0}, COLOR_WHITE, COLOR_BLUE, 0, 0}}
+};
+
+//------------------------------------------------------------------------------
+// Exported functions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// Set default background color of display box
+//------------------------------------------------------------------------------
+void SetDispBoxBGColor(unsigned int dispBoxID, unsigned int color)
+{
+ dispBoxMgr.dispBoxInfo[dispBoxID - 1].bgColor = color;
+}
+
+//------------------------------------------------------------------------------
+/// set default Font Color of display box
+//------------------------------------------------------------------------------
+void SetDispBoxFontColor(unsigned int dispBoxID, unsigned int color)
+{
+ dispBoxMgr.dispBoxInfo[dispBoxID - 1].fontColor = color;
+}
+
+//------------------------------------------------------------------------------
+/// set display box position info
+//------------------------------------------------------------------------------
+void SetDispBoxPos(unsigned int dispBoxID,
+ unsigned int enableDispBox,
+ unsigned int top,
+ unsigned int left,
+ unsigned int width,
+ unsigned int height)
+{
+ if(dispBoxID > dispBoxMgr.dispBoxCount) {
+ if(dispBoxID < MAX_DISPBOX_PER_SLIDE) {
+ ++dispBoxMgr.dispBoxCount;
+ } else
+ return;
+ }
+
+ dispBoxMgr.dispBoxInfo[dispBoxID - 1].dispBoxEnable = enableDispBox;
+ if(enableDispBox) {
+ dispBoxMgr.dispBoxInfo[dispBoxID - 1].dispBoxZone.top = top;
+ dispBoxMgr.dispBoxInfo[dispBoxID - 1].dispBoxZone.left = left;
+ dispBoxMgr.dispBoxInfo[dispBoxID - 1].dispBoxZone.width = width;
+ dispBoxMgr.dispBoxInfo[dispBoxID - 1].dispBoxZone.height = height;
+
+ //set x,y start position
+ dispBoxMgr.dispBoxInfo[dispBoxID - 1].xCursor = \
+ dispBoxMgr.dispBoxInfo[dispBoxID - 1].dispBoxZone.left + DISPMARGIN;
+ dispBoxMgr.dispBoxInfo[dispBoxID - 1].yCursor = \
+ dispBoxMgr.dispBoxInfo[dispBoxID - 1].dispBoxZone.top + DISPMARGIN;
+
+ if(gDir > 0 && gDir < 3)
+ {
+ dispBoxMgr.dispBoxInfo[dispBoxID-1].xCursor = \
+ (dispBoxMgr.dispBoxInfo[dispBoxID-1].dispBoxZone.left + width) - DISPMARGIN ;
+ dispBoxMgr.dispBoxInfo[dispBoxID-1].yCursor = \
+ dispBoxMgr.dispBoxInfo[dispBoxID - 1].dispBoxZone.top + DISPMARGIN;
+ }
+
+ }
+}
+
+//------------------------------------------------------------------------------
+/// enable display box
+//------------------------------------------------------------------------------
+void EnableDispBox(unsigned int dispBoxID)
+{
+ dispBoxMgr.dispBoxInfo[dispBoxID - 1].dispBoxEnable = DISPBOX_ENABLE;
+}
+
+//------------------------------------------------------------------------------
+/// disable display box
+//------------------------------------------------------------------------------
+void DisableDispBox(unsigned int dispBoxID)
+{
+ dispBoxMgr.dispBoxInfo[dispBoxID - 1].dispBoxEnable = DISPBOX_DISABLE;
+}
+
+//------------------------------------------------------------------------------
+/// Check if any display box region is available
+/// \return 0 mean no display box, other means yes and value is number of display box
+//------------------------------------------------------------------------------
+unsigned int IsDispBoxRegionAvail()
+{
+ if(!dispBoxMgr.dispBoxCount) {
+ return 0;
+ }
+
+ return dispBoxMgr.dispBoxCount;
+}
+
+//------------------------------------------------------------------------------
+/// Check if the required display box is enabled
+/// \return 0 mean no display box, other means yes
+//------------------------------------------------------------------------------
+unsigned int IsDispBoxEnable(unsigned int dispBoxID)
+{
+ if(!dispBoxMgr.dispBoxInfo[dispBoxID - 1].dispBoxEnable)
+ return DISPBOX_DISABLE;
+
+ return DISPBOX_ENABLE;
+}
+
+//------------------------------------------------------------------------------
+/// Draw a string in display box with 'color'
+/// \param pBuffer, LCD base address
+/// \param dispBoxID, display box ID
+/// \param pStr, string to draw
+/// \param fontColor, font color
+/// \param bgColor, background color
+/// \param scrollFlag, idendtify if cleaning display box zone when scrolling back
+/// to display box start position
+//------------------------------------------------------------------------------
+void DrawStringInDispBox(
+ //pointer to LCD base address
+ void *pBuffer,
+ //display box index
+ unsigned int dispBoxID,
+ //pointer to string for show
+ const char *pStr,
+ //display string font color,
+ unsigned int fontColor,
+ //display string background color, 0xFFFFFFFF means no need to set bgColor
+ unsigned int bgColor,
+ //flag for scroll way, current only support 'clear or not clear display box'
+ //when display string reach end and roll back to show.
+ //0 means clear, 1 means don't clear.
+ unsigned int scrollFlag)
+{
+ unsigned int strWidth = 0;
+ unsigned int strHeight = 0;
+ extern const Font gFont;
+ const char *pString = pStr;
+
+ //text direction
+ unsigned int dir = 0;
+
+ ////////////////////////////////////
+ unsigned int width = 0;
+ unsigned int height = 0;
+ unsigned int left = 0;
+ unsigned int top = 0;
+ ///////////////////////////////////
+ TRACE_DEBUG(" draw string on lcd len is %u\n\r", strlen(pStr));
+
+ //no display box or disabled
+ if(!IsDispBoxRegionAvail() || !IsDispBoxEnable(dispBoxID)) {
+ //then display information on DBGU console;
+ printf("\n\r %s", pStr);
+ return;
+ }
+
+#if defined(LCDC_HX8347)
+
+
+ if(LCDD_IsBusy()) return;
+
+ LCDD_SetBusy();
+
+ //a temp way to resolve display direction. Further will be improved based on requirement
+ LCD_WriteReg((void *)BOARD_LCD_BASE, 0x16, 0x68);//); // MY=1, MX=0, MV=1, BGR=1
+ LCD_WriteReg((void *)BOARD_LCD_BASE, 0x02, 0x00); // Column address start2
+ LCD_WriteReg((void *)BOARD_LCD_BASE, 0x03, 0x00); // Column address start1
+ LCD_WriteReg((void *)BOARD_LCD_BASE, 0x04, 0x01); // Column address end2
+ LCD_WriteReg((void *)BOARD_LCD_BASE, 0x05, 0x3F); // Column address end1
+ LCD_WriteReg((void *)BOARD_LCD_BASE, 0x06, 0x00); // Row address start2
+ LCD_WriteReg((void *)BOARD_LCD_BASE, 0x07, 0x00); // Row address start1
+ LCD_WriteReg((void *)BOARD_LCD_BASE, 0x08, 0x00); // Row address end2
+ LCD_WriteReg((void *)BOARD_LCD_BASE, 0x09, 0xEF); // Row address end1
+
+ LCDD_ClearBusy();
+#endif
+ ////////////////////////////////////////////
+
+ if(gDir < 3 && gDir > 0)
+ //if(gDir >= 3 || gDir == 0)
+ {
+ // the protrait view,coordinates was changed after loading
+ //the Y is mirrored and x-y changed
+ height = dispBoxMgr.dispBoxInfo[dispBoxID-1].dispBoxZone.width;
+ //the width is to meet the algorithm calculating string lines
+
+ width = dispBoxMgr.dispBoxInfo[dispBoxID-1].dispBoxZone.height;
+ //it's strange but useful
+ left = dispBoxMgr.dispBoxInfo[dispBoxID-1].dispBoxZone.left + height;
+ top = dispBoxMgr.dispBoxInfo[dispBoxID-1].dispBoxZone.top ;
+
+
+ //for vertical
+ dir = 1;
+
+
+ }
+ else
+ {
+ width = dispBoxMgr.dispBoxInfo[dispBoxID-1].dispBoxZone.width;
+ height = dispBoxMgr.dispBoxInfo[dispBoxID-1].dispBoxZone.height;
+ top = dispBoxMgr.dispBoxInfo[dispBoxID-1].dispBoxZone.top;
+ left = dispBoxMgr.dispBoxInfo[dispBoxID-1].dispBoxZone.left;
+
+ dir = 0;
+
+ }
+ //count lines the string will use
+ ////////////////////////////////////////////
+ //back from start of display box, then clear dispbox zone
+
+
+ if(\
+ (dispBoxMgr.dispBoxInfo[dispBoxID-1].xCursor == \
+ left + DISPMARGIN) \
+ && \
+ (dispBoxMgr.dispBoxInfo[dispBoxID-1].yCursor == \
+ top + LINEDISTANCE)\
+ )
+ {
+ ClearDispBoxZoneDefault(dispBoxID);
+ }
+
+ if(dir)
+ {
+ if(\
+ (dispBoxMgr.dispBoxInfo[dispBoxID-1].xCursor == \
+ left - DISPMARGIN) \
+ && \
+ (dispBoxMgr.dispBoxInfo[dispBoxID-1].yCursor == \
+ top + LINEDISTANCE)\
+ )
+ {
+ ClearDispBoxZoneDefault(dispBoxID);
+ }
+ }
+
+ LCDD_GetStringSize(pString, &strWidth, &strHeight);
+
+ TRACE_DEBUG(" string width and height in pixel is %u, %u\n\r", strWidth, strHeight);
+
+ //count lines the string will use
+ unsigned int linecnt = \
+ (strWidth + CHARDISTANCE) \
+ / (width - DISPMARGIN) + 1;
+
+ //get how many chars the dispbox width can show
+ //to be consistent with lib API, a char width is gFont.width + CHARDISTANCE
+ unsigned int numCharLine = (width - DISPMARGIN) \
+ / (gFont.width + CHARDISTANCE) - 1;
+
+ //if line count larger than current position to bottom of dispbox, clear dispbox area,
+ //reinit x,y to start of dispbox
+ if( linecnt * (gFont.height + LINEDISTANCE) \
+ > \
+ (height - \
+ (dispBoxMgr.dispBoxInfo[dispBoxID-1].yCursor - \
+ top - LINEDISTANCE))\
+ )
+ {
+ if(scrollFlag == 0) {
+ LCDD_DrawRectangle((void *)BOARD_LCD_BASE,
+ left,
+ top,
+ width,
+ height,
+ dispBoxMgr.dispBoxInfo[dispBoxID-1].bgColor);
+ }
+
+ dispBoxMgr.dispBoxInfo[dispBoxID-1].xCursor = \
+ left + DISPMARGIN;
+ dispBoxMgr.dispBoxInfo[dispBoxID-1].yCursor = \
+ top + LINEDISTANCE;
+ }
+
+ if(dir)
+ {
+ if( linecnt * (gFont.height + LINEDISTANCE) \
+ > \
+ (height - \
+ (left - dispBoxMgr.dispBoxInfo[dispBoxID-1].xCursor \
+ - LINEDISTANCE))\
+ )
+ {
+ if(scrollFlag == 0) {
+ // LCDD_DrawRectangle((void *)BOARD_LCD_BASE,
+ // left,
+ // top,
+ // width,
+ // height,
+ // dispBoxMgr.dispBoxInfo[dispBoxID-1].bgColor);
+ ClearDispBoxZoneDefault(dispBoxID);
+ }
+
+ dispBoxMgr.dispBoxInfo[dispBoxID-1].xCursor = \
+ left - DISPMARGIN;
+ dispBoxMgr.dispBoxInfo[dispBoxID-1].yCursor = \
+ top + LINEDISTANCE;
+ }
+ }
+
+ //if whole string show height larger than dispbox height, then only show the content
+ //inside dispbox, the rest is not shown any more
+ if((linecnt * (gFont.height + LINEDISTANCE) > \
+ height)) {
+ linecnt = height / (gFont.height+LINEDISTANCE);
+ //shrink string to a full dispbox size.
+ strWidth = linecnt * numCharLine * (gFont.width+CHARDISTANCE);
+ }
+
+ TRACE_DEBUG(" numcharline is %u, linecnt is %u\n\r", numCharLine, linecnt);
+
+ unsigned int i;
+ for(i = 0; i < linecnt; ++i) {
+ char stringline[80];
+ if(i == linecnt - 1) {
+ //the last char doesn't have additional CHARDISTANCE, to meet API in lib
+ memcpy(stringline, pString, (strWidth+CHARDISTANCE) / (gFont.width+CHARDISTANCE) + 1);
+ stringline[(strWidth+CHARDISTANCE)/(gFont.width+CHARDISTANCE)] = '\0';
+ } else {
+ memcpy(stringline, pString, numCharLine);
+ stringline[numCharLine] = '\0';
+ strWidth -= numCharLine * (gFont.width+CHARDISTANCE);
+ }
+
+ //forward pString to next line
+ pString += numCharLine;
+
+ //draw string
+ if(bgColor == 0xFFFFFFFF) {
+ LCDD_DrawStringEx((void *)BOARD_LCD_BASE,
+ dispBoxMgr.dispBoxInfo[dispBoxID-1].xCursor,
+ dispBoxMgr.dispBoxInfo[dispBoxID-1].yCursor,
+ stringline,
+ fontColor,dir);
+ }else {
+ LCDD_DrawStringWithBGColorEx((void *)BOARD_LCD_BASE,
+ dispBoxMgr.dispBoxInfo[dispBoxID-1].xCursor,
+ dispBoxMgr.dispBoxInfo[dispBoxID-1].yCursor,
+ stringline,
+ fontColor,
+ bgColor,dir);
+ }
+
+ //move x, y to next line, to be consistent with lib api, height is gFont.height + 2
+ if(dir)
+ {
+ // xCursor is vertical to the direction of text,along with the lines of text
+ dispBoxMgr.dispBoxInfo[dispBoxID-1].xCursor -= (gFont.height + LINEDISTANCE);
+ dispBoxMgr.dispBoxInfo[dispBoxID-1].yCursor = \
+ top + DISPMARGIN;
+
+ }
+ else
+ {
+ dispBoxMgr.dispBoxInfo[dispBoxID-1].xCursor = \
+ left + DISPMARGIN;
+ dispBoxMgr.dispBoxInfo[dispBoxID-1].yCursor += gFont.height + LINEDISTANCE;
+ }
+
+ }
+
+#if defined(LCDC_HX8347)
+
+ if(LCDD_IsBusy()) return;
+
+ LCDD_SetBusy();
+
+ //restore previous direction setting
+ LCD_WriteReg((void *)BOARD_LCD_BASE, 0x16, 0xC8);//); // MY=1, MX=1, MV=0, BGR=1
+ LCD_WriteReg((void *)BOARD_LCD_BASE, 0x02, 0x00); // Column address start2
+ LCD_WriteReg((void *)BOARD_LCD_BASE, 0x03, 0x00); // Column address start1
+ LCD_WriteReg((void *)BOARD_LCD_BASE, 0x04, 0x00); // Column address end2
+ LCD_WriteReg((void *)BOARD_LCD_BASE, 0x05, 0xEF); // Column address end1
+ LCD_WriteReg((void *)BOARD_LCD_BASE, 0x06, 0x00); // Row address start2
+ LCD_WriteReg((void *)BOARD_LCD_BASE, 0x07, 0x00); // Row address start1
+ LCD_WriteReg((void *)BOARD_LCD_BASE, 0x08, 0x01); // Row address end2
+ LCD_WriteReg((void *)BOARD_LCD_BASE, 0x09, 0x3F); // Row address end1
+
+ LCDD_ClearBusy();
+#endif
+}
+
+//Draw a string in display box with default font and background color
+//if scroll back then clear
+void DrawStrInDispBoxDefault(void *pBuffer, unsigned int dispBoxID, const char *pStr)
+{
+ DrawStringInDispBox(
+ pBuffer,
+ dispBoxID,
+ pStr,
+ dispBoxMgr.dispBoxInfo[dispBoxID - 1].fontColor,
+ dispBoxMgr.dispBoxInfo[dispBoxID - 1].bgColor,
+ 0);
+}
+
+//Draw a string in display box with default font and background color
+//if scroll back, don't clear
+void DrawStrInDispBoxScrollNoClear(void *pBuffer, unsigned int dispBoxID, const char *pStr)
+{
+ DrawStringInDispBox(
+ pBuffer,
+ dispBoxID,
+ pStr,
+ dispBoxMgr.dispBoxInfo[dispBoxID - 1].fontColor,
+ dispBoxMgr.dispBoxInfo[dispBoxID - 1].bgColor,
+ 1);
+}
+
+//clear display box zone with color
+void ClearDispBoxZoneColor(unsigned int dispBoxID, unsigned int color)
+{
+ if(IsDispBoxRegionAvail() && IsDispBoxEnable(dispBoxID)) {
+
+ LCDD_DrawRectangle((void *)BOARD_LCD_BASE, \
+ dispBoxMgr.dispBoxInfo[dispBoxID - 1].dispBoxZone.left,
+ dispBoxMgr.dispBoxInfo[dispBoxID - 1].dispBoxZone.top,
+ dispBoxMgr.dispBoxInfo[dispBoxID - 1].dispBoxZone.width,
+ dispBoxMgr.dispBoxInfo[dispBoxID - 1].dispBoxZone.height,
+ color);
+ }
+}
+
+//------------------------------------------------------------------------------
+/// Clear display box with default background color
+//------------------------------------------------------------------------------
+void ClearDispBoxZoneDefault(unsigned int dispBoxID)
+{
+ ClearDispBoxZoneColor(dispBoxID, dispBoxMgr.dispBoxInfo[dispBoxID - 1].bgColor);
+}
diff --git a/utility/demo-fw/common/dfm_entry.c b/utility/demo-fw/common/dfm_entry.c
new file mode 100644
index 0000000..f70c2f6
--- /dev/null
+++ b/utility/demo-fw/common/dfm_entry.c
@@ -0,0 +1,142 @@
+
+#include "dfm_entry.h"
+#include "dfm_cmd.h"
+
+//-----------------------------------------------------------------------------
+/// Internal Variables
+//-----------------------------------------------------------------------------
+
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+//point to first input entry
+static TInputEntry *gpFirstInputEntry = NULL;
+
+//-----------------------------------------------------------------------------
+/// Exported Function
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+/// register prompt display entry fucntion into prompt list for calling
+/// The image should be same size as the LCD.
+/// \param pPromptFunc, pointer to global variable of prompt display function
+/// \return 0 success, other value fail
+//------------------------------------------------------------------------------
+int RegisterInputEntry(TInputEntry *pEntryStruct)
+{
+ TInputEntry *pTmpEntry;
+
+ pTmpEntry = gpFirstInputEntry;
+
+ if(pTmpEntry == NULL) {
+ gpFirstInputEntry = pEntryStruct;
+ gpFirstInputEntry->next = NULL;
+
+ return 0;
+ }
+
+ while(pTmpEntry->next != NULL)
+ pTmpEntry = pTmpEntry->next;
+
+ pTmpEntry->next = pEntryStruct;
+ pEntryStruct->next = NULL;
+
+ return 0;
+}
+
+//-----------------------------------------------------------------------------
+/// Calling prompt display entry chained in prompt list
+/// \return 0 success, other value fail
+//------------------------------------------------------------------------------
+int ShowPrompt()
+{
+ TInputEntry *pTmpEntry;
+
+ pTmpEntry = gpFirstInputEntry;
+ while(pTmpEntry != NULL) {
+ //printf("\n\r ********DisplayPrompt********* ");
+ if(pTmpEntry->Prompt)
+ pTmpEntry->Prompt();
+ pTmpEntry = pTmpEntry->next;
+ }
+
+ return 0;
+}
+
+//-----------------------------------------------------------------------------
+/// Check if any command is ready in all input entry, if yes, set the flag
+/// \return 0 no command ready, other means yes and value represents number of
+/// ready input entry
+//------------------------------------------------------------------------------
+unsigned int CommandIsReady()
+{
+ unsigned int ret = 0;
+ TInputEntry *pTmpEntry;
+
+ pTmpEntry = gpFirstInputEntry;
+ while(pTmpEntry != NULL) {
+ if(pTmpEntry->CommandIsReady && pTmpEntry->CommandIsReady()) {
+ pTmpEntry->readyFlag = 1;
+ ++ ret;
+ }
+
+ pTmpEntry = pTmpEntry->next;
+ }
+
+ return ret;
+}
+
+//-----------------------------------------------------------------------------
+/// Get Command Queue
+/// \return 0 no command ready, other means ready and value is available numbers
+//------------------------------------------------------------------------------
+TCmdQueue * GetCommandQueue()
+{
+ TInputEntry *pTmpEntry;
+ TCmdQueue *pQueueFirst, *pTmpQueue = NULL;
+
+ pTmpEntry = gpFirstInputEntry;
+ while(pTmpEntry != NULL) {
+ //check if command ready flag is set
+ if(pTmpEntry->readyFlag) {
+
+ if(pTmpQueue == NULL) {
+ //Set pointer to first available command element of queue
+ pQueueFirst = &(pTmpEntry->CmdElement);
+ pTmpQueue = pQueueFirst;
+ } else {
+ pTmpQueue->next = &(pTmpEntry->CmdElement);
+ pTmpQueue = pTmpQueue->next;
+ }
+
+ pTmpQueue->command = pTmpEntry->GetCommand();
+ pTmpQueue->next = NULL;
+
+ pTmpEntry->readyFlag = 0;
+ }
+
+ pTmpEntry = pTmpEntry->next;
+ }
+
+ return pQueueFirst;
+}
+
+//-----------------------------------------------------------------------------
+/// Run Command Queue
+/// \return 0 success for all, other value fail
+//------------------------------------------------------------------------------
+int RunCommandQueue(TCmdQueue *pCmdQueue)
+{
+ int ret = 0;
+ TCmdQueue *pTmpQueue;
+
+ pTmpQueue = pCmdQueue;
+ while(pTmpQueue != NULL) {
+ ret |= ParseAndRunMultiCmds(pTmpQueue->command);
+ pTmpQueue = pTmpQueue->next;
+ }
+
+ return ret;
+}
diff --git a/utility/demo-fw/common/dfm_fatfs.c b/utility/demo-fw/common/dfm_fatfs.c
new file mode 100644
index 0000000..20348a0
--- /dev/null
+++ b/utility/demo-fw/common/dfm_fatfs.c
@@ -0,0 +1,384 @@
+#include "dfm_fatfs.h"
+#include "dfm_init.h"
+//#include <memories/MEDSdcard.h>
+//#include <utility/trace.h>
+//#include <string.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <irq/irq.h>
+#include <board.h>
+#include <board_memories.h>
+#include <string.h>
+#include <utility/assert.h>
+#include <utility/math.h>
+#include <utility/bmp.h>
+#include <lcd/color.h>
+#include <lcd/lcdd.h>
+#include <lcd/draw.h>
+#include <tsd/tsd.h>
+#include <usb/common/core/USBConfigurationDescriptor.h>
+#include <usb/device/core/USBD.h>
+#include <usb/device/massstorage/MSDDriver.h>
+#include <usb/device/massstorage/MSDLun.h>
+#include <usb/device/core/USBDCallbacks.h>
+#include <memories/MEDSdcard.h>
+#include <components/hx8347/hx8347.h>
+#include <systick/systick.h>
+#include <flash/flashd.h>
+
+#if defined(PINS_NANDFLASH)
+#include <memories/MEDNandFlash.h>
+#include <memories/nandflash/RawNandFlash.h>
+#include <memories/nandflash/TranslatedNandFlash.h>
+#endif
+
+#include "fatfs_config.h"
+
+#include <hx8347/hx8347.h>
+
+#include "dfm_dispboxmgr.h"
+#include "dfm_config.h"
+#include "dfm_cmd.h"
+#include "dfm_varloc.h"
+
+/// Available medias.
+RLOC_OBJ Media medias[MAX_LUNS] _AT(FATFS_MEDIA_OBJ_ADDR);
+
+#if defined(PINS_NANDFLASH)
+/// Pins used to access to nandflash.
+const Pin gpPinsNf[] = {PINS_NANDFLASH};
+/// Nandflash device structure.
+RLOC_OBJ struct TranslatedNandFlash gTranslatedNf _AT(NANDFLASH_TRANS_TAB_ADDR);
+/// Address for transferring command bytes to the nandflash.
+unsigned int gNFCmdBytesAddr = BOARD_NF_COMMAND_ADDR;
+/// Address for transferring address bytes to the nandflash.
+unsigned int gNFAddrBytesAddr = BOARD_NF_ADDRESS_ADDR;
+/// Address for transferring data bytes to the nandflash.
+unsigned int gNFDataBytesAddr = BOARD_NF_DATA_ADDR;
+/// Nandflash chip enable pin.
+const Pin gNFCePin = BOARD_NF_CE_PIN;
+/// Nandflash ready/busy pin.
+const Pin gNFRbPin = BOARD_NF_RB_PIN;
+#endif
+
+//---------------------------------------------------------------------
+/// enable fatfs on SDCard
+//---------------------------------------------------------------------
+int Fatfs_Init_Share()
+{
+ TRACE_DEBUG("\n\r FatFs max media is %u (MAX_LUNS)!", numMedias);
+ numMedias = MAX_LUNS;
+
+ return 0;
+}
+
+DFM_INIT(7, Fatfs_Init_Share);
+
+////////////////////////////
+/// enable fatfs on SDCard /
+////////////////////////////
+
+#if defined(DFM_FATFS_SDCARD)
+//used to mount fatfs on sdcard
+RLOC_OBJ static FATFS fs_sdcard _AT(FATFS_SDCARD_OBJ_ADDR);
+//------------------------------------------------------------------------------
+/// Init sdcard for FatFS
+/// \return 0 succeed, other value failure
+//-----------------------------------------------------------------------------
+int FatFs_SDCard_Init()
+{
+ FRESULT res;
+
+ if(MEDSdcard_Detect(&medias[DRV_MMC], MCI_ID)) {
+
+ if (!MEDSdcard_Initialize(&medias[DRV_MMC], MCI_ID)) {
+ // Initialize sdcard failed
+ TRACE_ERROR("-E- SD Init fail\n\r");
+ return -1;
+ }
+
+ // Mount disk
+ printf("-I- Mount disk %d \n\r", DRV_MMC);
+
+ memset(&fs_sdcard, 0, sizeof(FATFS));
+ res = f_mount(DRV_MMC, &fs_sdcard);
+ if( res != FR_OK ) {
+ TRACE_ERROR("-E- f_mount pb: 0x%X\n\r", res);
+ return -1;
+ }
+
+ DIR dir;
+ // Test if the disk is formated
+ res = f_opendir (&dir,SDCARD_ROOT_DIRECTORY);
+ if(res == FR_OK ){
+
+ TRACE_INFO("-I- The disk is already formated. \n\r");
+ TRACE_INFO("-I- Display files contained on the SDcard :\n\r");
+ //FF_ScanDir(SDCARD_ROOT_DIRECTORY);
+ }
+ else {
+ TRACE_ERROR("-I- The disk is not formated. Exit! \n\r");
+ return -1;
+ }
+
+ return 0;
+ }
+
+ //no sdcard detected in MCI slot
+ return -1;
+}
+
+//Init SDCard in level 6
+//lvl6_init(FatFs_SDCard_Init);
+//_define_init_lvl("6", FatFs_SDCard_Init, 6);
+DFM_INIT(6, FatFs_SDCard_Init);
+
+#endif //end of DFM_FATFS_SDCARD
+
+///////////////////////////////
+/// enable fatfs on nandflash /
+///////////////////////////////
+#if defined(DFM_FATFS_NANDFLASH)
+//used to mount fatfs on nand flash
+RLOC_OBJ static FATFS fs_nandflash _AT(FATFS_NANDFLASH_OBJ_ADDR);
+
+//------------------------------------------------------------------------------
+/// Init Nandflash for FatFS
+/// \return 0 succeed, other value failure
+//-----------------------------------------------------------------------------
+int FatFs_NandFlash_Init()
+{
+ unsigned int delay = 0;
+ unsigned char nfBusWidth = 16, nfRc;
+ unsigned short nfBaseBlock = 0;
+ struct RawNandFlash *pRaw = (struct RawNandFlash*)&gTranslatedNf;
+ struct NandFlashModel *pModel = (struct NandFlashModel*)&gTranslatedNf;
+ unsigned int nfMamagedSize;
+
+ // Configure SMC for NandFlash
+ BOARD_ConfigureNandFlash(nfBusWidth);
+ // Configure PIO for Nand Flash
+ PIO_Configure(gpPinsNf, PIO_LISTSIZE(gpPinsNf));
+
+ // Nand Flash Initialize (ALL flash mapped)
+ nfRc = RawNandFlash_Initialize(pRaw,
+ 0,
+ gNFCmdBytesAddr,
+ gNFAddrBytesAddr,
+ gNFDataBytesAddr,
+ gNFCePin,
+ gNFRbPin);
+ if (nfRc) {
+ printf("Nand not found\n\r");
+ return -1;
+ }
+ else {
+ printf("NF\tNb Blocks %d\n\r",
+ NandFlashModel_GetDeviceSizeInBlocks(pModel));
+ printf("\tBlock Size %uK\n\r",
+ (unsigned int)NandFlashModel_GetBlockSizeInBytes(pModel)/1024);
+ printf("\tPage Size %d\n\r",
+ NandFlashModel_GetPageDataSize(pModel));
+ nfBaseBlock =
+ NF_RESERVE_SIZE / NandFlashModel_GetBlockSizeInBytes(pModel);
+ }
+ printf("NF disk will use area from %dM(B%d)\n\r",
+ NF_RESERVE_SIZE/1024/1024, nfBaseBlock);
+#if 0
+ printf("!! Erase the NF Disk? (y/n):");
+ //updateDelay = INPUT_DELAY;
+ //updateView = 0;
+ while(1) {
+ if(DBGU_IsRxReady()) {
+ char key = DBGU_GetChar();
+ DBGU_PutChar(key);
+ if (key == 'y') {
+ if (nfRc == 0) {
+ unsigned int block;
+ printf(" Erase from %d ... ", nfBaseBlock);
+ for (block = nfBaseBlock;
+ block < NandFlashModel_GetDeviceSizeInBlocks(pModel);
+ block ++) {
+ RawNandFlash_EraseBlock(pRaw, block);
+ }
+ printf("OK");
+ }
+ }
+ printf("\n\r");
+ break;
+ }
+
+ if (++ delay > 0x800000) {
+ printf("n\n\r");
+ break;
+ }
+ }
+#endif
+
+ nfMamagedSize = ((NandFlashModel_GetDeviceSizeInMBytes(pModel) - NF_RESERVE_SIZE/1024/1024) > NF_MANAGED_SIZE/1024/1024) ? \
+ NF_MANAGED_SIZE/1024/1024 : (NandFlashModel_GetDeviceSizeInMBytes(pModel) - NF_RESERVE_SIZE/1024/1024);
+ if (TranslatedNandFlash_Initialize(&gTranslatedNf,
+ 0,
+ gNFCmdBytesAddr,
+ gNFAddrBytesAddr,
+ gNFDataBytesAddr,
+ gNFCePin,
+ gNFRbPin,
+ nfBaseBlock, nfMamagedSize * 1024 * 1024/NandFlashModel_GetBlockSizeInBytes(pModel))) {
+ printf("Nand init error\n\r");
+ return -1;
+ }
+ // Check the data bus width of the NandFlash
+ nfBusWidth =
+ NandFlashModel_GetDataBusWidth(pModel);
+ BOARD_ConfigureNandFlash(nfBusWidth);
+
+ // Media initialize
+ MEDNandFlash_Initialize(&medias[DRV_NAND], &gTranslatedNf);
+
+ // Initialize LUN
+ // LUN_Init(&(luns[DRV_NAND]), &(medias[DRV_NAND]),
+ // msdBuffer, MSD_BUFFER_SIZE,
+ // 0, 0, 0, 0,
+ // 0);
+ //printf("\n\r Init Nandflash is temp ignored!");
+// ++numMedias;
+
+ FRESULT res;
+ // Mount Disk
+ printf("-I- Mount disk 1\n\r");
+ memset(&fs_nandflash, 0, sizeof(FATFS)); // Clear file system object
+ res = f_mount(DRV_NAND, &fs_nandflash);
+ if( res != FR_OK ) {
+ printf("-E- f_mount pb: 0x%X\n\r", res);
+ //return 0;
+ }
+
+ DIR dir;
+ // Test if the disk is formated
+ res = f_opendir (&dir,NAND_ROOT_DIRECTORY);
+ if(res == FR_OK ){
+
+ // erase NAND to re-format it ?
+ printf("-I- The disk is already formated.\n\r");
+
+ // Display the file tree
+ printf("-I- Display files contained on the NAND :\n\r");
+ //FF_ScanDir(NAND_ROOT_DIRECTORY);
+#if 0
+ printf("-I- Erase the NAND to re-format disk ? (y/n)!\n\r");
+
+ unsigned char key = DBGU_GetChar();
+ if( (key == 'y') || (key == 'Y'))
+ {
+ TranslatedNandFlash_EraseAll(&gTranslatedNf ,NandEraseDATA);
+ res = FR_NO_FILESYSTEM;
+ }
+#endif
+ } else {
+ TRACE_ERROR(" Open fatfs on nand flash fail!\n\r");
+ return -1;
+ }
+
+
+ return 0;
+}
+
+//Init nandflash In level 6
+DFM_INIT(6, FatFs_NandFlash_Init);
+
+#endif //end of DFM_FATFS_NANDFLASH
+
+
+//------------------------------------------------------------------------------
+/// Configures the EBI for NandFlash access according to MCK.
+/// \param mck working MCK
+//------------------------------------------------------------------------------
+void ConfigureNandFlashEBI(unsigned int mck)
+{
+ AT91PS_HSMC4_CS pSMC = AT91C_BASE_HSMC4_CS1;
+
+ if (mck <= 48000000) {
+ pSMC->HSMC4_SETUP = 0
+ | ((0 << 0) & AT91C_HSMC4_NWE_SETUP)
+ | ((1 << 8) & AT91C_HSMC4_NCS_WR_SETUP)
+ | ((0 << 16) & AT91C_HSMC4_NRD_SETUP)
+ | ((1 << 24) & AT91C_HSMC4_NCS_RD_SETUP);
+
+ pSMC->HSMC4_PULSE = 0
+ | ((2 << 0) & AT91C_HSMC4_NWE_PULSE)
+ | ((3 << 8) & AT91C_HSMC4_NCS_WR_PULSE)
+ | ((3 << 16) & AT91C_HSMC4_NRD_PULSE)
+ | ((4 << 24) & AT91C_HSMC4_NCS_RD_PULSE);
+
+ pSMC->HSMC4_CYCLE = 0
+ | ((4 << 0) & AT91C_HSMC4_NWE_CYCLE)
+ | ((7 << 16) & AT91C_HSMC4_NRD_CYCLE);
+
+ pSMC->HSMC4_TIMINGS = 0
+ | ((1 << 0) & AT91C_HSMC4_TCLR) // CLE to REN
+ | ((2 << 4) & AT91C_HSMC4_TADL) // ALE to Data
+ | ((1 << 8) & AT91C_HSMC4_TAR) // ALE to REN
+ | ((1 << 16) & AT91C_HSMC4_TRR) // Ready to REN
+ | ((2 << 24) & AT91C_HSMC4_TWB) // WEN to REN
+ | (7 << 28)
+ | (AT91C_HSMC4_NFSEL) // Nand Flash Timing
+ ;
+ }
+ else if (mck <= 84000000) {
+ pSMC->HSMC4_SETUP = 0
+ | ((0 << 0) & AT91C_HSMC4_NWE_SETUP)
+ | ((1 << 8) & AT91C_HSMC4_NCS_WR_SETUP)
+ | ((0 << 16) & AT91C_HSMC4_NRD_SETUP)
+ | ((1 << 24) & AT91C_HSMC4_NCS_RD_SETUP);
+
+ pSMC->HSMC4_PULSE = 0
+ | ((2 << 0) & AT91C_HSMC4_NWE_PULSE)
+ | ((3 << 8) & AT91C_HSMC4_NCS_WR_PULSE)
+ | ((3 << 16) & AT91C_HSMC4_NRD_PULSE)
+ | ((4 << 24) & AT91C_HSMC4_NCS_RD_PULSE);
+
+ pSMC->HSMC4_CYCLE = 0
+ | ((4 << 0) & AT91C_HSMC4_NWE_CYCLE)
+ | ((7 << 16) & AT91C_HSMC4_NRD_CYCLE);
+
+ pSMC->HSMC4_TIMINGS = 0
+ | ((2 << 0) & AT91C_HSMC4_TCLR) // CLE to REN
+ | ((4 << 4) & AT91C_HSMC4_TADL) // ALE to Data
+ | ((2 << 8) & AT91C_HSMC4_TAR) // ALE to REN
+ | ((2 << 16) & AT91C_HSMC4_TRR) // Ready to REN
+ | ((4 << 24) & AT91C_HSMC4_TWB) // WEN to REN
+ | (7 << 28)
+ | (AT91C_HSMC4_NFSEL) // Nand Flash Timing
+ ;
+ }
+ else {
+ pSMC->HSMC4_SETUP = 0
+ | ((1 << 0) & AT91C_HSMC4_NWE_SETUP)
+ | ((2 << 8) & AT91C_HSMC4_NCS_WR_SETUP)
+ | ((1 << 16) & AT91C_HSMC4_NRD_SETUP)
+ | ((2 << 24) & AT91C_HSMC4_NCS_RD_SETUP);
+
+ pSMC->HSMC4_PULSE = 0
+ | ((3 << 0) & AT91C_HSMC4_NWE_PULSE)
+ | ((4 << 8) & AT91C_HSMC4_NCS_WR_PULSE)
+ | ((4 << 16) & AT91C_HSMC4_NRD_PULSE)
+ | ((4 << 24) & AT91C_HSMC4_NCS_RD_PULSE);
+
+ pSMC->HSMC4_CYCLE = 0
+ | ((6 << 0) & AT91C_HSMC4_NWE_CYCLE)
+ | ((9 << 16) & AT91C_HSMC4_NRD_CYCLE);
+
+ pSMC->HSMC4_TIMINGS = 0
+ | ((3 << 0) & AT91C_HSMC4_TCLR) // CLE to REN
+ | ((4 << 4) & AT91C_HSMC4_TADL) // ALE to Data
+ | ((2 << 8) & AT91C_HSMC4_TAR) // ALE to REN
+ | ((2 << 16) & AT91C_HSMC4_TRR) // Ready to REN
+ | ((4 << 24) & AT91C_HSMC4_TWB) // WEN to REN
+ | (7 << 28)
+ | (AT91C_HSMC4_NFSEL) // Nand Flash Timing
+ ;
+ }
+}
+
diff --git a/utility/demo-fw/common/dfm_init.c b/utility/demo-fw/common/dfm_init.c
new file mode 100644
index 0000000..bf0b4dc
--- /dev/null
+++ b/utility/demo-fw/common/dfm_init.c
@@ -0,0 +1,118 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ----------------------------------------------------------------------------
+ */
+
+#include "dfm_init.h"
+
+//------------------------------------------------------------------------------
+// variable definition
+//------------------------------------------------------------------------------
+#if defined(__ICCARM__)//IAR Compiler ID
+
+///no need for declaration of section start and end variable in IAR
+
+#elif defined(__CC_ARM) //MDK ARM Compiler ID
+
+///variables for group start/end address
+extern unsigned int Image$$GS_Init_Region$$Base;
+extern unsigned int Image$$GS_Init_Region$$Limit;
+
+#elif defined(__GNUC__)//GNU ARM Compiler ID
+
+extern unsigned int __gs_init_section_start, __gs_init_section_end;
+
+#endif
+
+//------------------------------------------------------------------------------
+/// Run all init handlers from level 1 to level 7
+/// \return 0 succeed, other value failure
+//-----------------------------------------------------------------------------
+unsigned int RunAllInit()
+{
+ T_INIT *pInitSecStart, *pInitSecEnd, *pInitTmp;
+
+#if defined(__ICCARM__)
+
+ pInitSecStart = __section_begin(".gs_initsection");
+ pInitSecEnd = __section_end(".gs_initsection");
+
+#elif defined(__CC_ARM)
+
+ pInitSecStart = (T_INIT *)&Image$$GS_Init_Region$$Base;
+ pInitSecEnd = (T_INIT *)&Image$$GS_Init_Region$$Limit;
+
+#elif defined(__GNUC__)
+
+ pInitSecStart = (T_INIT *)&__gs_init_section_start;
+ pInitSecEnd = (T_INIT *)&__gs_init_section_end;
+
+#else
+
+#error "Unsupported tool chain!"
+
+#endif
+
+ //count init handler number
+ int iInitNum = pInitSecEnd - pInitSecStart;
+
+ unsigned int i, iLvlTmp, iLvlMin = 0, iLvlMax = 0xffffffff;
+
+ iLvlTmp = 0;
+
+ while(iLvlMin <= iLvlMax && iInitNum > 0) {
+
+ pInitTmp = pInitSecStart;
+ for(i = 0; i < iInitNum && pInitTmp <= pInitSecEnd; ++i, ++pInitTmp) {
+
+ if(iLvlMin == 0)
+ iLvlMin = pInitTmp->initlvl;
+
+ if(iLvlMax == 0xffffffff)
+ iLvlMax = pInitTmp->initlvl;
+
+ if(pInitTmp->initlvl > iLvlMax)
+ iLvlMax = pInitTmp->initlvl;
+
+ if((pInitTmp->initlvl > iLvlTmp && pInitTmp->initlvl < iLvlMin) ||
+ (pInitTmp->initlvl > iLvlTmp && iLvlMin == iLvlTmp))
+ iLvlMin = pInitTmp->initlvl;
+
+ //run initHanddler
+ if(pInitTmp->initlvl == iLvlTmp)
+ pInitTmp->pfInitFunc();
+ }
+
+ if(iLvlTmp == iLvlMax)
+ break;
+
+ iLvlTmp = iLvlMin;
+ }
+
+ return 0;
+}
+
diff --git a/utility/demo-fw/common/dfm_it.c b/utility/demo-fw/common/dfm_it.c
new file mode 100644
index 0000000..e3a0863
--- /dev/null
+++ b/utility/demo-fw/common/dfm_it.c
@@ -0,0 +1,638 @@
+/* ----------------------------------------------------------------------------
+ * 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.
+ * ----------------------------------------------------------------------------
+ */
+
+/*
+** This file contains the exception handlers that use registry calling methodology
+*/
+
+//------------------------------------------------------------------------------
+// Headers
+//------------------------------------------------------------------------------
+
+#include <board.h>
+#include <rtc/rtc.h>
+
+#include "dfm_it.h"
+
+//------------------------------------------------------------------------------
+// Variables
+//------------------------------------------------------------------------------
+
+static volatile TDFM_ItServList *gpItHandlerFirst = NULL;
+
+//------------------------------------------------------------------------------
+// Exported Functions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+// Register It handler into the list
+//------------------------------------------------------------------------------
+int DFM_RegisterItHandler(TDFM_ItServList *pItHandler)
+{
+ volatile TDFM_ItServList *pTmpItHandler;
+
+ pTmpItHandler = gpItHandlerFirst;
+
+ if(pTmpItHandler == NULL) {
+ gpItHandlerFirst = pItHandler;
+ gpItHandlerFirst->next = NULL;
+
+ return 0;
+ }
+
+ while(pTmpItHandler->next != NULL)
+ pTmpItHandler = pTmpItHandler->next;
+
+ pTmpItHandler->next = pItHandler;
+ pItHandler->next = NULL;
+
+ return 0;
+}
+
+//------------------------------------------------------------------------------
+// UnRegister It handler into the list
+//------------------------------------------------------------------------------
+int DFM_UnRegisterItHandler(TDFM_ItServList *pItHandler)
+{
+ volatile TDFM_ItServList *pTmpItHandler;
+ volatile TDFM_ItServList *pTmpPreItHandler;
+
+ pTmpPreItHandler = gpItHandlerFirst;
+ pTmpItHandler = gpItHandlerFirst;
+
+ while(pTmpItHandler != NULL) {
+
+ if(pItHandler == gpItHandlerFirst){
+ gpItHandlerFirst = gpItHandlerFirst->next;
+ pTmpPreItHandler = gpItHandlerFirst;
+ pTmpItHandler = gpItHandlerFirst;
+ continue;
+ }
+
+ if(pTmpItHandler == pItHandler) {
+ if(pTmpPreItHandler != NULL && pTmpItHandler != NULL)
+ pTmpPreItHandler->next = pTmpItHandler->next;
+ }
+
+ //proceed to next
+ pTmpPreItHandler = pTmpItHandler;
+ pTmpItHandler = pTmpItHandler->next;
+ }
+
+ return 0;
+}
+
+////------------------------------------------------------------------------------
+//// Default irq handler
+////------------------------------------------------------------------------------
+//void IrqHandlerNotUsed(void)
+//{
+// while(1);
+//}
+//
+//------------------------------------------------------------------------------
+// Provide weak aliases for each Exception handler to the IrqHandlerNotUsed.
+// As they are weak aliases, any function with the same name will override
+// this definition.
+//------------------------------------------------------------------------------
+
+////------------------------------------------------------------------------------
+//// System interrupt
+////------------------------------------------------------------------------------
+//void NMI_Handler(void)
+//{
+// while(1);
+//}
+//
+////------------------------------------------------------------------------------
+////------------------------------------------------------------------------------
+//void HardFault_Handler(void)
+//{
+// while(1);
+//}
+//
+////------------------------------------------------------------------------------
+////------------------------------------------------------------------------------
+//void MemManage_Handler(void)
+//{
+// while(1);
+//}
+//
+////------------------------------------------------------------------------------
+////------------------------------------------------------------------------------
+//void BusFault_Handler(void)
+//{
+// while(1);
+//}
+//
+////------------------------------------------------------------------------------
+////------------------------------------------------------------------------------
+//void UsageFault_Handler(void)
+//{
+// while(1);
+//}
+//
+////------------------------------------------------------------------------------
+////------------------------------------------------------------------------------
+//void SVC_Handler(void)
+//{
+// while(1);
+//}
+//
+////------------------------------------------------------------------------------
+////------------------------------------------------------------------------------
+//void DebugMon_Handler(void)
+//{
+// while(1);
+//}
+//
+////------------------------------------------------------------------------------
+////------------------------------------------------------------------------------
+//void PendSV_Handler(void)
+//{
+// while(1);
+//}
+//
+
+#if defined(cortexm3)
+//------------------------------------------------------------------------------
+// for Cortex M3
+//------------------------------------------------------------------------------
+void SysTick_Handler(void)
+{
+ volatile TDFM_ItServList *pTmpItServ;
+
+ pTmpItServ = gpItHandlerFirst;
+ while(pTmpItServ != NULL) {
+ if(pTmpItServ->itID == SysTick_IRQn)
+ pTmpItServ->ItHandler();
+
+ pTmpItServ = pTmpItServ->next;
+ }
+}
+#endif
+
+//------------------------------------------------------------------------------
+// External interrupt
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+// for SAM7/9
+//------------------------------------------------------------------------------
+//void SYS_IrqHandler( void )
+//{
+// while(1);
+//}
+//
+////------------------------------------------------------------------------------
+//// SUPPLY CONTROLLER
+////------------------------------------------------------------------------------
+//void SUPC_IrqHandler(void)
+//{
+// while(1);
+//}
+//
+////------------------------------------------------------------------------------
+//// RESET CONTROLLER
+////------------------------------------------------------------------------------
+//void RSTC_IrqHandler(void)
+//{
+// while(1);
+//}
+
+//------------------------------------------------------------------------------
+// REAL TIME CLOCK
+//------------------------------------------------------------------------------
+void RTC_IrqHandler(void)
+{
+ volatile TDFM_ItServList *pTmpItServ;
+ unsigned int status;
+
+ status = AT91C_BASE_RTC->RTC_SR;
+ if ((status & AT91C_RTC_SECEV) == AT91C_RTC_SECEV) {
+ // Disable RTC interrupt
+ RTC_DisableIt(AT91C_RTC_SECEV);
+ }
+
+ pTmpItServ = gpItHandlerFirst;
+ while(pTmpItServ != NULL) {
+ if(pTmpItServ->itID == AT91C_ID_RTC)
+ pTmpItServ->ItHandler();
+
+ pTmpItServ = pTmpItServ->next;
+ }
+
+ AT91C_BASE_RTC->RTC_SCCR = AT91C_RTC_SECEV;
+
+ RTC_EnableIt(AT91C_RTC_SECEV);
+}
+
+//------------------------------------------------------------------------------
+// REAL TIME TIMER
+//------------------------------------------------------------------------------
+void RTT_IrqHandler(void)
+{
+ volatile TDFM_ItServList *pTmpItServ;
+
+ pTmpItServ = gpItHandlerFirst;
+ while(pTmpItServ != NULL) {
+ if(pTmpItServ->itID == AT91C_ID_RTT)
+ pTmpItServ->ItHandler();
+
+ pTmpItServ = pTmpItServ->next;
+ }
+}
+//
+////------------------------------------------------------------------------------
+//// WATCHDOG TIMER
+////------------------------------------------------------------------------------
+//void WDT_IrqHandler(void)
+//{
+// while(1);
+//}
+
+//------------------------------------------------------------------------------
+// PMC
+//------------------------------------------------------------------------------
+void PMC_IrqHandler(void)
+{
+ volatile TDFM_ItServList *pTmpItServ;
+
+ pTmpItServ = gpItHandlerFirst;
+ while(pTmpItServ != NULL) {
+ if(pTmpItServ->itID == AT91C_ID_PMC)
+ pTmpItServ->ItHandler();
+
+ pTmpItServ = pTmpItServ->next;
+ }
+}
+
+//------------------------------------------------------------------------------
+// EFC0
+//------------------------------------------------------------------------------
+void EFC0_IrqHandler(void)
+{
+ volatile TDFM_ItServList *pTmpItServ;
+
+ pTmpItServ = gpItHandlerFirst;
+ while(pTmpItServ != NULL) {
+ if(pTmpItServ->itID == AT91C_ID_EFC0)
+ pTmpItServ->ItHandler();
+
+ pTmpItServ = pTmpItServ->next;
+ }
+}
+
+//------------------------------------------------------------------------------
+// EFC1
+//------------------------------------------------------------------------------
+void EFC1_IrqHandler(void)
+{
+ volatile TDFM_ItServList *pTmpItServ;
+
+ pTmpItServ = gpItHandlerFirst;
+ while(pTmpItServ != NULL) {
+ if(pTmpItServ->itID == AT91C_ID_EFC1)
+ pTmpItServ->ItHandler();
+
+ pTmpItServ = pTmpItServ->next;
+ }
+}
+
+//------------------------------------------------------------------------------
+// DBGU
+//------------------------------------------------------------------------------
+void DBGU_IrqHandler(void)
+{
+ volatile TDFM_ItServList *pTmpItServ;
+
+ pTmpItServ = gpItHandlerFirst;
+ while(pTmpItServ != NULL) {
+ if(pTmpItServ->itID == AT91C_ID_DBGU)
+ pTmpItServ->ItHandler();
+
+ pTmpItServ = pTmpItServ->next;
+ }
+}
+
+//------------------------------------------------------------------------------
+// HSMC4
+//------------------------------------------------------------------------------
+void HSMC4_IrqHandler(void)
+{
+ volatile TDFM_ItServList *pTmpItServ;
+
+ pTmpItServ = gpItHandlerFirst;
+ while(pTmpItServ != NULL) {
+ if(pTmpItServ->itID == AT91C_ID_HSMC4)
+ pTmpItServ->ItHandler();
+
+ pTmpItServ = pTmpItServ->next;
+ }
+}
+
+////------------------------------------------------------------------------------
+//// Parallel IO Controller A
+////------------------------------------------------------------------------------
+//void PIOA_IrqHandler(void)
+//{
+// while(1);
+//}
+//
+////------------------------------------------------------------------------------
+//// Parallel IO Controller B
+////------------------------------------------------------------------------------
+//void PIOB_IrqHandler(void)
+//{
+// while(1);
+//}
+//
+////------------------------------------------------------------------------------
+//// Parallel IO Controller C
+////------------------------------------------------------------------------------
+//void PIOC_IrqHandler(void)
+//{
+// while(1);
+//}
+//
+//------------------------------------------------------------------------------
+// USART 0
+//------------------------------------------------------------------------------
+void USART0_IrqHandler(void)
+{
+ volatile TDFM_ItServList *pTmpItServ;
+
+ pTmpItServ = gpItHandlerFirst;
+ while(pTmpItServ != NULL) {
+ if(pTmpItServ->itID == AT91C_ID_HSMC4)
+ pTmpItServ->ItHandler();
+
+ pTmpItServ = pTmpItServ->next;
+ }
+}
+
+//------------------------------------------------------------------------------
+// USART 1
+//------------------------------------------------------------------------------
+void USART1_IrqHandler(void)
+{
+ volatile TDFM_ItServList *pTmpItServ;
+
+ pTmpItServ = gpItHandlerFirst;
+ while(pTmpItServ != NULL) {
+ if(pTmpItServ->itID == AT91C_ID_HSMC4)
+ pTmpItServ->ItHandler();
+
+ pTmpItServ = pTmpItServ->next;
+ }
+}
+
+//------------------------------------------------------------------------------
+// USART 2
+//------------------------------------------------------------------------------
+void USART2_IrqHandler(void)
+{
+ volatile TDFM_ItServList *pTmpItServ;
+
+ pTmpItServ = gpItHandlerFirst;
+ while(pTmpItServ != NULL) {
+ if(pTmpItServ->itID == AT91C_ID_HSMC4)
+ pTmpItServ->ItHandler();
+
+ pTmpItServ = pTmpItServ->next;
+ }
+}
+
+//------------------------------------------------------------------------------
+// USART 3
+//------------------------------------------------------------------------------
+void USART3_IrqHandler(void)
+{
+ volatile TDFM_ItServList *pTmpItServ;
+
+ pTmpItServ = gpItHandlerFirst;
+ while(pTmpItServ != NULL) {
+ if(pTmpItServ->itID == AT91C_ID_HSMC4)
+ pTmpItServ->ItHandler();
+
+ pTmpItServ = pTmpItServ->next;
+ }
+}
+
+////------------------------------------------------------------------------------
+//// Multimedia Card Interface
+////------------------------------------------------------------------------------
+//void MCI0_IrqHandler(void)
+//{
+// while(1);
+//}
+
+//------------------------------------------------------------------------------
+// TWI 0
+//------------------------------------------------------------------------------
+void TWI0_IrqHandler(void)
+{
+ volatile TDFM_ItServList *pTmpItServ;
+
+ pTmpItServ = gpItHandlerFirst;
+ while(pTmpItServ != NULL) {
+ if(pTmpItServ->itID == AT91C_ID_TWI0)
+ pTmpItServ->ItHandler();
+
+ pTmpItServ = pTmpItServ->next;
+ }
+}
+
+//------------------------------------------------------------------------------
+// TWI 1
+//------------------------------------------------------------------------------
+void TWI1_IrqHandler(void)
+{
+ volatile TDFM_ItServList *pTmpItServ;
+
+ pTmpItServ = gpItHandlerFirst;
+ while(pTmpItServ != NULL) {
+ if(pTmpItServ->itID == AT91C_ID_TWI1)
+ pTmpItServ->ItHandler();
+
+ pTmpItServ = pTmpItServ->next;
+ }
+}
+
+//------------------------------------------------------------------------------
+// Serial Peripheral Interface 0
+//------------------------------------------------------------------------------
+void SPI0_IrqHandler(void)
+{
+ volatile TDFM_ItServList *pTmpItServ;
+
+ pTmpItServ = gpItHandlerFirst;
+ while(pTmpItServ != NULL) {
+ if(pTmpItServ->itID == AT91C_ID_SPI0)
+ pTmpItServ->ItHandler();
+
+ pTmpItServ = pTmpItServ->next;
+ }
+}
+
+//------------------------------------------------------------------------------
+// Serial Synchronous Controller 0
+//------------------------------------------------------------------------------
+void SSC0_IrqHandler(void)
+{
+ volatile TDFM_ItServList *pTmpItServ;
+
+ pTmpItServ = gpItHandlerFirst;
+ while(pTmpItServ != NULL) {
+ if(pTmpItServ->itID == AT91C_ID_SSC0)
+ pTmpItServ->ItHandler();
+
+ pTmpItServ = pTmpItServ->next;
+ }
+}
+
+//------------------------------------------------------------------------------
+// Timer Counter 0
+//------------------------------------------------------------------------------
+void TC0_IrqHandler(void)
+{
+ volatile TDFM_ItServList *pTmpItServ;
+
+ pTmpItServ = gpItHandlerFirst;
+ while(pTmpItServ != NULL) {
+ if(pTmpItServ->itID == AT91C_ID_TC0)
+ pTmpItServ->ItHandler();
+
+ pTmpItServ = pTmpItServ->next;
+ }
+}
+
+//------------------------------------------------------------------------------
+// Timer Counter 1
+//------------------------------------------------------------------------------
+void TC1_IrqHandler(void)
+{
+ volatile TDFM_ItServList *pTmpItServ;
+
+ pTmpItServ = gpItHandlerFirst;
+ while(pTmpItServ != NULL) {
+ if(pTmpItServ->itID == AT91C_ID_TC1)
+ pTmpItServ->ItHandler();
+
+ pTmpItServ = pTmpItServ->next;
+ }
+}
+
+//------------------------------------------------------------------------------
+// Timer Counter 2
+//------------------------------------------------------------------------------
+void TC2_IrqHandler(void)
+{
+ volatile TDFM_ItServList *pTmpItServ;
+
+ pTmpItServ = gpItHandlerFirst;
+ while(pTmpItServ != NULL) {
+ if(pTmpItServ->itID == AT91C_ID_TC2)
+ pTmpItServ->ItHandler();
+
+ pTmpItServ = pTmpItServ->next;
+ }
+}
+
+//------------------------------------------------------------------------------
+// PWM Controller
+//------------------------------------------------------------------------------
+void PWM_IrqHandler(void)
+{
+ volatile TDFM_ItServList *pTmpItServ;
+
+ pTmpItServ = gpItHandlerFirst;
+ while(pTmpItServ != NULL) {
+ if(pTmpItServ->itID == AT91C_ID_PWMC)
+ pTmpItServ->ItHandler();
+
+ pTmpItServ = pTmpItServ->next;
+ }
+}
+
+//------------------------------------------------------------------------------
+// ADC controller0
+//------------------------------------------------------------------------------
+void ADCC0_IrqHandler(void)
+{
+ volatile TDFM_ItServList *pTmpItServ;
+
+ pTmpItServ = gpItHandlerFirst;
+ while(pTmpItServ != NULL) {
+ if(pTmpItServ->itID == AT91C_ID_ADC12B)
+ pTmpItServ->ItHandler();
+
+ pTmpItServ = pTmpItServ->next;
+ }
+}
+
+//------------------------------------------------------------------------------
+// ADC controller1
+//------------------------------------------------------------------------------
+void ADCC1_IrqHandler(void)
+{
+ volatile TDFM_ItServList *pTmpItServ;
+
+ pTmpItServ = gpItHandlerFirst;
+ while(pTmpItServ != NULL) {
+ if(pTmpItServ->itID == AT91C_ID_ADC)
+ pTmpItServ->ItHandler();
+
+ pTmpItServ = pTmpItServ->next;
+ }
+}
+
+//------------------------------------------------------------------------------
+// HDMA
+//------------------------------------------------------------------------------
+void HDMA_IrqHandler(void)
+{
+ volatile TDFM_ItServList *pTmpItServ;
+
+ pTmpItServ = gpItHandlerFirst;
+ while(pTmpItServ != NULL) {
+ if(pTmpItServ->itID == AT91C_ID_HDMA)
+ pTmpItServ->ItHandler();
+
+ pTmpItServ = pTmpItServ->next;
+ }
+}
+
+////------------------------------------------------------------------------------
+//// USB Device High Speed UDP_HS
+////------------------------------------------------------------------------------
+//void UDPD_IrqHandler(void)
+//{
+// while(1);
+//}
diff --git a/utility/demo-fw/common/dfm_lcd_tsd.c b/utility/demo-fw/common/dfm_lcd_tsd.c
new file mode 100644
index 0000000..f1d826c
--- /dev/null
+++ b/utility/demo-fw/common/dfm_lcd_tsd.c
@@ -0,0 +1,1040 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ----------------------------------------------------------------------------
+ */
+
+#include <board.h>
+#include <board_memories.h>
+#include <utility/trace.h>
+#include <utility/bmp.h>
+#include <systick/systick.h>
+#include <lcd/color.h>
+#include <lcd/draw.h>
+#include <lcd/lcdd.h>
+#include <hx8347/hx8347.h>
+#include <tsd/tsd.h>
+#include <flash/flashd.h>
+
+#include "dfm_cmd.h"
+#include "dfm_lcd_tsd.h"
+#include "dfm_dispboxmgr.h"
+#include "dfm_config.h"
+#include "dfm_it.h"
+#include "dfm_init.h"
+#include "dfm_fatfs.h"
+#include "dfm_entry.h"
+#include "dfm_varloc.h"
+
+//global LCD prompt display register entry variable
+TInputEntry gLCDEntry = {0, {NULL,NULL},LCD_ShowPrompt, TSD_CommandIsReady, TSD_GetCommand, NULL};
+
+#define GLOBALSLIDEINFO
+
+#if defined(GLOBALSLIDEINFO)
+///active for slide information
+RLOC_OBJ SlideINFOHeader gActiveSlideHeader _AT(ACTIVESLIDE_INFOHEAD_ADDR);
+#endif
+
+///lcd refresh show flag
+unsigned int gLcdRefreshFlag = 0;
+
+///current slide index shown on LCD
+///the init value is the first slide after program start up.
+unsigned short gActiveSlideIndex = 0;
+
+/// active demo bin max slides
+static unsigned int gActiveBinSlideCount = 0xffffffff;
+
+/// point to the active demo bin file name
+const char * gpActiveBinFile = LCDSLIDEIMAGEFILE;
+
+/// used in system tick count
+volatile unsigned int gTimeStamp = 0;
+
+/// Coordinates at which the pen was last pressed.
+static volatile unsigned int gTSDxPressed;
+static volatile unsigned int gTSDyPressed;
+static volatile unsigned char gTSDPressed = 0;
+
+/// link string index for hot zone hitted, starting from 1, 0 means not hitted
+static unsigned int gLinkIndex = 0;
+
+///Flash1 start address to store demo bin in at91sam3u4
+#define gDemoBinAddrInFlash 0x108000
+
+
+//file buffer used to read bitmap data
+#if defined(__CC_ARM) || defined(__ICCARM__)//up to now, KEIL AND IAR supported
+RLOC_OBJ static unsigned char gpFileBuffer[FILE_BUF_SIZE] _AT(FILE_BUFFER_ADDR);
+#endif
+
+#if defined(BOARD_PSRAM_PINS)
+
+#if defined(__GNUC__) && !defined(__CC_ARM)
+ static unsigned char *gpFileBuffer = (unsigned char *) (BOARD_EBI_PSRAM + 0xa0000);
+#endif
+
+ //PSRAM init entry
+ int Psram_Init(void)
+ {
+ printf("\n\r Init Psram");
+
+ BOARD_ConfigurePsram();
+
+ return 0;
+ }
+
+ //init psram in level 5
+ //lvl5_init(Psram_Init);
+ DFM_INIT(5, Psram_Init);
+
+#elif defined(PINS_SDRAM)
+
+#if defined(__GNUC__) && !defined(__CC_ARM)
+ static unsigned char *gpFileBuffer = (unsigned char *) (AT91C_EBI_SDRAM+ 0xa0000);
+#endif
+
+ //SDRAM init entry
+ int Sdram_Init(void)
+ {
+ printf("\n\r Init Sdram");
+
+ BOARD_ConfigureSdram(BOARD_SDRAM_BUSWIDTH);
+ }
+
+ //init sdram in level 5
+ //lvl5_init(Psram_Init);
+ DFM_INIT(5, Sdram_Init);
+
+#elif defined(PINGS_DDRAM)
+
+#if defined(__GNUC__) && !defined(__CC_ARM)
+ static unsigned char *gpFileBuffer = (unsigned char *) (AT91C_EBI_SDRAM);
+#endif
+
+ //ddram init entry
+ int Ddram_Init(void)
+ {
+ printf("\n\r Init Ddram");
+
+ //configure DDRAM for use
+ BOARD_ConfigureDdram(0, BOARD_DDRAM_BUSWIDTH);
+ }
+
+ //init ddram in level 5
+ //lvl5_init(Psram_Init);
+ DFM_INIT(5, Ddram_Init);
+
+#else
+ #define USE_SRAM_BUF
+ #define BUF_LEN_SRAM 1024
+#endif
+
+//////////////////////////
+///LCD prompt display /
+//////////////////////////
+
+#if defined(USE_LCD_TSD)
+
+#if defined(LCDC_HX8347) //USE hx8347 controller
+//------------------------------------------------------------------------------
+/// Handler for SysTick interrupt. Increments the timestamp counter.
+//------------------------------------------------------------------------------
+void SysTick_HandlerLcdTsd(void)
+{
+ gTimeStamp++;
+
+ // Call TSD_TimerHandler per 10ms
+ if ((gTimeStamp % 10) == 0) {
+
+ TSD_TimerHandler();
+ }
+}
+
+#if defined(USE_IT_CHAIN_MGR)
+TDFM_ItServList gSysTkItHandlerLcdTsd = {SysTick_IRQn, SysTick_HandlerLcdTsd, NULL};
+#endif
+
+//------------------------------------------------------
+/// Init LCD controller of 8347
+//------------------------------------------------------
+int LCD_Init()
+{
+
+ printf("\n\r LCD init in Level 5");
+
+ // 1ms tick, in driver, a wait is called.
+ SysTick_Configure(1, BOARD_MCK/1000, SysTick_HandlerLcdTsd);
+
+#if defined(USE_IT_CHAIN_MGR)
+ DFM_RegisterItHandler(&gSysTkItHandlerLcdTsd);
+#endif
+
+ // Initialize LCD
+ LCDD_Initialize();
+ LCDD_Fill((void *)BOARD_LCD_BASE, COLOR_WHITE);
+ LCDD_Start();
+
+ return 0;
+}
+
+#else //use internal LCD controller
+//------------------------------------------------------
+/// Init LCD controller of 8347
+//------------------------------------------------------
+int LCD_Init()
+{
+ // 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);
+
+ // Set frame buffer
+ LCD_SetFrameBufferAddress(images[0]);
+
+ // Enable DMA and LCD
+ LCD_EnableDma();
+ LCD_Enable(0x0C);
+}
+
+#endif
+
+//lvl5_init(LCD_Init);
+DFM_INIT(5, LCD_Init);
+
+//------------------------------------------------------------------------------
+/// Delay millisecond. Use SysTick interrupt for function implement, so ensure
+/// the SysTick interrupt is enabled before using this function.
+/// \param ms millisecond to be delay
+//------------------------------------------------------------------------------
+void DelayMS(unsigned int ms)
+{
+ unsigned int st = gTimeStamp;
+
+ while (gTimeStamp - st < ms);
+}
+
+//------------------------------------------------------------------------------
+/// Callback called when the pen is pressed on the touchscreen
+/// /param horizontal position (in pixel if ts calibrated)
+/// /param vertical position (in pixel if ts calibrated)
+//------------------------------------------------------------------------------
+void TSD_PenPressed(unsigned int x, unsigned int y)
+{
+ //printf("Pen pressed at (%03u, %03u)\n\r", x, y);
+
+ // Save the coordinates for use by TSD_PenReleased
+ gTSDxPressed = x;
+ gTSDyPressed = y;
+ TSD_SetTouched();
+}
+
+//------------------------------------------------------------------------------
+/// Callback called when the pen is moved on the touchscreen
+/// /param horizontal position (in pixel if ts calibrated)
+/// /param vertical position (in pixel if ts calibrated)
+//------------------------------------------------------------------------------
+void TSD_PenMoved(unsigned int x, unsigned int y)
+{
+ // printf("Pen moved at (%03u, %03u)\n\r", x, y);
+}
+
+//------------------------------------------------------------------------------
+/// Callback called when the touchscreen is released on the touchscreen
+/// /param horizontal position (in pixel if ts calibrated)
+/// /param vertical position (in pixel if ts calibrated)
+//------------------------------------------------------------------------------
+void TSD_PenReleased(unsigned int x, unsigned int y)
+{
+
+}
+
+//------------------------------------------------------------------------------
+/// Get last pen press position
+/// /param point to horizontal position (in pixel if ts calibrated)
+/// /param point vertical position (in pixel if ts calibrated)
+//------------------------------------------------------------------------------
+void TSD_GetPenLastPosition(unsigned int *pX, unsigned int *pY)
+{
+ *pX = gTSDxPressed;
+ *pY = gTSDyPressed;
+}
+
+//---------------------------------------------
+/// init touchscreen
+//---------------------------------------------
+int TSD_Init()
+{
+ printf("\n\r Init TouchScreen");
+
+ gTSDxPressed = gTSDyPressed = 0;
+
+#if defined(at91sam3u4)
+// Internal Flash1
+#define IFLASH1 (0x100000)
+#define IFLASH1_SIZE (0x20000)
+#define IFLASH1_PAGE_SIZE (256) // Internal FLASH 1 Page Size: 256 bytes
+#define IFLASH1_NB_OF_PAGES (512) // Internal FLASH 1 Number of Pages: 512
+#define IFLASH1_LOCK_REGION_SIZE (8192) // Internal FLASH 1 Lock Region Size: 8 Kbytes
+#define IFLASH1_NB_OF_LOCK_BITS (16) // Internal FLASH 1 Number of Lock Bits: 16
+
+ unsigned char error;
+ unsigned int pBuffer[IFLASH1_PAGE_SIZE / 4];
+ unsigned int lastPageAddress;
+ volatile unsigned int *pLastPageData;
+
+ // Read touch screen calibration data
+ // Initialize flash driver
+ FLASHD_Initialize(BOARD_MCK);
+
+ // Calibration data are stored on last page
+ lastPageAddress = IFLASH1 + IFLASH1_SIZE - IFLASH1_PAGE_SIZE;
+ pLastPageData = (volatile unsigned int *) lastPageAddress;
+
+ TSDCom_RestoreCalibrateData((void *)pLastPageData, IFLASH1_PAGE_SIZE);
+
+ // Initialize touchscreen
+ TSD_Initialize((void *)BOARD_LCD_BASE);
+
+ // Save touch screen calibration data
+ // Unlock whole flash
+ error = FLASHD_Unlock(IFLASH1, IFLASH1 + IFLASH1_SIZE, 0, 0);
+ if(error) {
+ printf(" Unlock flash fail.\n\r");
+ } else {
+ TSDCom_ReadCalibrateData(pBuffer, sizeof(pBuffer));
+ error = FLASHD_Write(lastPageAddress, pBuffer, IFLASH1_PAGE_SIZE);
+ if(error) {
+ printf(" Fail to write touch srceen calibration data.\n\r");
+ }
+ }
+#endif
+
+ return 0;
+}
+
+//TouchScreen init in level 5
+DFM_INIT(5, TSD_Init);
+
+#endif
+
+
+///////////////////////////////////////////////////
+/// following is dealling with show slide on slide/
+///////////////////////////////////////////////////
+
+//-----------------------------------------------------------------------------
+/// Displays the given image on the LCD.
+/// The image should be same size as the LCD.
+/// TODO: this display interface should be generalized to consider other LCD properties
+/// \param pImage point to image buffer
+/// \param width image width in pixels.
+/// \param height image height in pixels.
+//------------------------------------------------------------------------------
+static void LCDD_DrawImageRGB565(
+ unsigned short *pImage,
+ unsigned int width,
+ unsigned int height)
+{
+ unsigned int i;
+
+ if ((width != BOARD_LCD_WIDTH) || (height != BOARD_LCD_HEIGHT)) {
+
+ printf("LCDD_DrawImageRGB565: Image size is not fit the LCD");
+ return;
+ }
+
+
+ if(LCDD_IsBusy()) return;
+
+ LCDD_SetBusy();
+
+
+ LCD_SetCursor((void *)BOARD_LCD_BASE, 0, 0);
+ LCD_WriteRAM_Prepare((void *)BOARD_LCD_BASE);
+
+ for (i = 0; i < (width * height); i++) {
+ LCD_WriteRAM((void *)BOARD_LCD_BASE, *(pImage));
+ pImage++;
+ }
+
+ LCDD_ClearBusy();
+}
+
+//------------------------------------------------------------------------------
+///Get slide info header from fatfs file interface
+//------------------------------------------------------------------------------
+static unsigned int GetSlideInfoHeaderFromFile(
+ //fatfs file pointer to demo bin file
+ FIL *pFile,
+ //slide index for get info
+ unsigned int slideIdx,
+ //store read slide info
+ SlideINFOHeader *pSlideheader,
+ //to return actual slide index been read
+ unsigned int *realSlideIdx)
+{
+ DemoBINHeader binheader;
+ FRESULT res;
+ unsigned int i, offset;
+
+ if(!pSlideheader) {
+ TRACE_ERROR(" No slide info returned for null pointer!\n\r");
+ return 1;
+ }
+
+ //seek to start point of file
+ res = f_lseek(pFile, 0);
+ if(res != FR_OK) {
+ TRACE_ERROR(" Operation demo bin file fail! \n\r");
+ return 1;
+ }
+
+ //Read demo bin header information
+ res = f_read(pFile, &binheader, sizeof(DemoBINHeader), &i);
+ if(res != FR_OK ) {
+ TRACE_ERROR(" Fail to read demo bin! \n\r");
+ return 1;
+ }
+
+ TRACE_DEBUG(" demo bin tag is %x \n\r", binheader.tag);
+ TRACE_DEBUG(" demo bin has %u slides \n\r", binheader.slidecount);
+ //Check if it is atmel demo bin
+ if( i != sizeof(DemoBINHeader) || binheader.tag != ATMLBINTAG) {
+ TRACE_ERROR(" Not expected demo bin file! \n\r");
+ return 1;
+ }
+
+ //save max slide count of active demo bin file
+ gActiveBinSlideCount = binheader.slidecount;
+
+ //requested slide index larger than available one in current demo bin
+ if(slideIdx >= binheader.slidecount) {
+ TRACE_WARNING(" Reach max slide count! \n\r");
+
+ if(realSlideIdx)
+ *realSlideIdx = binheader.slidecount - 1;
+
+ slideIdx = binheader.slidecount - 1;
+ }
+
+ //seek the offset to the 'slideindex'th bit map data
+ offset = sizeof(DemoBINHeader) + slideIdx * sizeof(SlideINFOHeader);
+
+ TRACE_DEBUG("\n\r slide header offset is %u", offset);
+
+ //Seek to the position of slide information field
+ res = f_lseek(pFile, offset);
+ if(res != FR_OK) {
+ TRACE_ERROR(" Operation demo bin file fail! \n\r");
+ return 1;
+ }
+
+ //read slide information
+ res = f_read(pFile, pSlideheader, sizeof(SlideINFOHeader), &i);
+ if(res != FR_OK || i != sizeof(SlideINFOHeader)) {
+ TRACE_ERROR(" Read demo bin file fail! \n\r");
+ return 1;
+ }
+
+ return 0;
+}
+
+//------------------------------------------------------------------------------
+/// read slide information from SDCARD, and Show
+/// \param slideIdx, slidex index for reading slide and show
+/// \return 0 succeed, other fail
+//------------------------------------------------------------------------------
+static int ProcessBinFromSDcard(unsigned int slideIdx, const char *pFileWithPath)
+{
+
+// DemoBINHeader binheader;
+ SlideINFOHeader slideheader;
+ unsigned int offset;
+
+ TRACE_DEBUG(" file name is %s \n\r", pFileWithPath);
+
+ FIL demoBinFile;
+ FRESULT res;
+ unsigned int i;
+
+// strcpy(pFile,SDCARD_ROOT_DIRECTORY);
+// strncat(pFile, pFileWithPath, 256-1-strlen(SDCARD_ROOT_DIRECTORY));
+
+ //Open demo bin file
+ res = f_open(&demoBinFile, pFileWithPath, FA_OPEN_EXISTING | FA_READ);
+ if(res != FR_OK) {
+ TRACE_ERROR(" Open demo bin file fail! \n\r");
+ f_close(&demoBinFile);
+ return 1;
+ }
+
+ //get slide info from file
+ if(GetSlideInfoHeaderFromFile(\
+ &demoBinFile,\
+ slideIdx,\
+ &slideheader,\
+ &slideIdx))
+ {
+ TRACE_ERROR(" Read slide header fail!\n\r");
+ f_close(&demoBinFile);
+ return 1;
+ }
+
+ //set real slide index as active
+ gActiveSlideIndex = slideIdx;
+
+ //get the 'slideindex'th slide bit map data offset
+ offset = slideheader.slideoffset;
+
+ TRACE_DEBUG(" slide %u bitmap data at %u \n\r", slideIdx, offset);
+
+#if defined(GLOBALSLIDEINFO)
+ //copy current active slide information to global variable
+ memcpy(&gActiveSlideHeader, &slideheader, sizeof(SlideINFOHeader));
+#endif
+
+ //print the link box information
+ TRACE_DEBUG(" slide has link %u\n\r", gActiveSlideHeader.linkcount);
+ if(slideheader.linkcount) {
+ unsigned int j;
+ for(j = 0; j < slideheader.linkcount; ++j) {
+ TRACE_DEBUG(" link bottom %u, left %u, width %u, height %u \n\r", \
+ slideheader.linkinfo[j].linkboxbottom,\
+ slideheader.linkinfo[j].linkboxleft,\
+ slideheader.linkinfo[j].linkboxwidth,\
+ slideheader.linkinfo[j].linkboxheight);
+ }
+ }
+
+ //seek to offset of the 'slideindex'th slide bit map data
+ res = f_lseek(&demoBinFile, offset);
+ if(res != FR_OK) {
+ TRACE_DEBUG(" Operation demo bin file fail! \n\r");
+ f_close(&demoBinFile);
+ return 1;
+ }
+
+#if !defined(USE_SRAM_BUF)
+ //Read all single slide bitmap data into PSRAM buffer, then write to LCD
+ TRACE_DEBUG(" Ready to read bit map data len %u \n\r", slideheader.slidedatalength);
+
+ //read slide bit map data
+ res = f_read(&demoBinFile, gpFileBuffer, slideheader.slidedatalength, &i);
+
+ TRACE_DEBUG(" Data read len is %u \n\r", i);
+
+ if(res != FR_OK || i != slideheader.slidedatalength) {
+ TRACE_ERROR(" Read bitmap data fail! \n\r");
+ f_close(&demoBinFile);
+ return 1;
+ }
+ f_close(&demoBinFile);
+
+ //Define a pointer to cast bmp header
+ struct BMPHeader *header = (struct BMPHeader *)gpFileBuffer;
+ offset = header->offset;
+
+ //Show slide bitmap header information
+ TRACE_DEBUG("============bmp header outside calling============== \n\r");
+ TRACE_DEBUG(" bmp.type is %x \n\r", header->type);
+ TRACE_DEBUG(" bmp.filesize is %u \n\r", header->fileSize);
+ TRACE_DEBUG(" bmp.width is %u \n\r", header->width);
+ TRACE_DEBUG(" bmp.height is %u \n\r", header->height);
+ TRACE_DEBUG(" bmp.compressed is %u \n\r", header->compression);
+ TRACE_DEBUG(" bmp.bitdepth is %d \n\r", header->bits);
+ TRACE_DEBUG(" bmp.offset is %u \n\r", header->offset);
+
+ //LCDD_DrawImageRGB565((unsigned short *)(pLcdBuffer),BOARD_LCD_WIDTH, BOARD_LCD_HEIGHT);
+ LCDD_DrawImageRGB565((unsigned short *)(gpFileBuffer + offset),BOARD_LCD_WIDTH, BOARD_LCD_HEIGHT);
+
+#else //USE_SRAM_BUF defined
+
+ //USE sram buffer to read bitmap data and then write to LCD
+ unsigned int k;
+ char srambuf[BUF_LEN_SRAM];
+ unsigned short *lcddata;
+
+ //buffer len is not even.
+ if(BUF_LEN_SRAM % 2 != 0) {
+ TRACE_ERROR("SRAM buffer size must be even! \n\r");
+ f_close(&demofilebin);
+ return 1;
+ }
+
+ //buffer len is too short to fit a bmp file header
+ if(BUF_LEN_SRAM < sizeof(struct BMPHeader)) {
+ TRACE_ERROR("SRAM buffer size is too short, Add it large than %u \n\r", sizeof(struct BMPHeader));
+ f_close(&demofilebin);
+ return 1;
+ }
+
+ //read slide bit map header
+ res = f_read(&demofilebin, srambuf, sizeof(struct BMPHeader), &i);
+
+ struct BMPHeader *header = (struct BMPHeader *)&srambuf[0];
+ //Get BMP bitmap data offset
+ offset = header->offset + slideheader.slideoffset;
+
+ //seek to the bitmap data offset
+ res = f_lseek(&demofilebin, offset);
+ if(res != FR_OK) {
+ TRACE_DEBUG(" Can't find BMP bitmap Data in bin file! \n\r");
+ f_close(&demofilebin);
+ return 1;
+ }
+
+ //prepare to write lcd
+ LCD_SetCursor((void *)BOARD_LCD_BASE, 0, 0);
+ LCD_WriteRAM_Prepare((void *)BOARD_LCD_BASE);
+
+ for(k = 0; k < slideheader.slidedatalength && k < LCD16BITDATALEN; k += BUF_LEN_SRAM) {
+
+ lcddata = (unsigned short *)&srambuf[0];
+
+ //read data to buffer
+ res = f_read(&demofilebin, srambuf, \
+ (k + BUF_LEN_SRAM)> slideheader.slidedatalength ? (slideheader.slidedatalength - k): BUF_LEN_SRAM, &i);
+
+ if(res != FR_OK) {
+ TRACE_ERROR(" Read bitmap data fail! \n\r");
+ f_close(&demofilebin);
+ return 1;
+ }
+
+ //write the data to LCD base address
+ while(i>0) {
+ LCD_WriteRAM((void *)BOARD_LCD_BASE, *(lcddata++));
+ i-=2;
+ }
+ }
+
+ f_close(&demofilebin);
+
+#endif//end of USE_SRAM_BUF
+ unsigned int k;
+ if(slideheader.dispboxcount) {
+ for(k = 0; k < slideheader.dispboxcount; ++k) {
+ //conversion rule based on SAM3U current setting.
+ unsigned int top = slideheader.dispboxinfo[k].dispboxleft;
+ unsigned int left = DEMOSLIDEHEIGHT - slideheader.dispboxinfo[k].dispboxbottom;
+ unsigned int width = slideheader.dispboxinfo[k].dispboxheight;
+ unsigned int height = slideheader.dispboxinfo[k].dispboxwidth;
+
+ SetDispBoxPos(k+1, DISPBOX_ENABLE, \
+ top, left, width, height);
+
+ EnableDispBox(k);
+ }
+
+ } else {
+ for(k = 0; k < MAX_DISPBOX_PER_SLIDE; ++k) {
+ DisableDispBox(k);
+ }
+ }
+
+ return 0;
+}
+
+//------------------------------------------------------------------------------
+///read slide information from External NandFlash, and Show
+//------------------------------------------------------------------------------
+static int ProcessBinFromNandFlash(unsigned int slideIdx, const char *pFileWithPath)
+{
+ unsigned int iRet;
+
+ //fatfs mounted on NAND FLASH also, so reuse SDCard code
+ iRet = ProcessBinFromSDcard(slideIdx, pFileWithPath);
+
+ return iRet;
+}
+
+
+//------------------------------------------------------------------------------
+///read slide information from Internal flash, and Show
+//------------------------------------------------------------------------------
+static int ProcessBinFromInternalFlash(unsigned int binStartAddr, unsigned int slideIdx)
+{
+ DemoBINHeader binheader;
+ SlideINFOHeader slideheader;
+ unsigned int offset;
+
+ //get demo bin header information
+ binheader = *(DemoBINHeader*)binStartAddr;
+ TRACE_DEBUG(" bin tag is %x\n\r", binheader.tag);
+ TRACE_DEBUG(" filesize is %u\n\r", binheader.filesize);
+ TRACE_DEBUG(" headersize is %u\n\r", binheader.headersize);
+ TRACE_DEBUG(" bin has %u slide\n\r", binheader.slidecount);
+
+ //check if it has atmel demo bin header tag
+ if(binheader.tag != ATMLBINTAG) {
+ TRACE_ERROR(" Not Atmel demo bin in FLASH1!\n\r");
+ return 1;
+ }
+
+ //check if slide index reachs max
+ if(slideIdx >= binheader.slidecount) {
+ slideIdx = binheader.slidecount - 1;
+ TRACE_WARNING(" Reach max slides!\n\r");
+ }
+
+ //set real slide index as active
+ gActiveSlideIndex = slideIdx;
+
+ //offset of slide info header
+ offset = sizeof(DemoBINHeader) + slideIdx * sizeof(SlideINFOHeader);
+#if defined(GLOBALSLIDEINFO)
+ memcpy(&gActiveSlideHeader, (void*)(binStartAddr+offset), sizeof(SlideINFOHeader));
+#endif
+
+ slideheader = *(SlideINFOHeader *)(binStartAddr+offset);
+ TRACE_DEBUG(" slide has dispbox?%s\n\r",slideheader.dispboxyes?"yes":"no");
+ TRACE_DEBUG(" slideoffset is %u\n\r", slideheader.slideoffset);
+ TRACE_DEBUG(" slidedatalength is %u\n\r", slideheader.slidedatalength);
+ TRACE_DEBUG(" slidewidth is %u\n\r", slideheader.slidewidth);
+ TRACE_DEBUG(" slideheight is %u\n\r", slideheader.slideheight);
+ TRACE_DEBUG(" slide has %u links\n\r", slideheader.linkcount);
+ if(slideheader.linkcount) {
+ TRACE_DEBUG(" link 0'addr is %s\n\r", slideheader.linkinfo[0].linkstring);
+ }
+
+ //offset of slide bmp file
+ offset = slideheader.slideoffset;
+ BMP_displayHeader((unsigned int*)binStartAddr+offset);
+
+ //Get slide bmp file header
+ struct BMPHeader *bmpheader = (struct BMPHeader*)(binStartAddr+offset);
+ if(bmpheader->type != 0x4d42) {
+ TRACE_ERROR(" Slide bitmap file is not correct!\n\r");
+ return 1;
+ }
+
+ //check bitdepth if it is 8. 1,4bitdepth is not supported for complicate
+ //pixel color conversion. 16,24bitdepth bitmap data length too big.
+ //TODO: Care more case of IFlash of some EK board less than 8bit bmp file size, 77k
+ if(bmpheader->bits !=8) {
+ TRACE_ERROR(" Slide bitmap color bitdepth %d is not supported!", bmpheader->bits);
+ return 1;
+ }
+
+ BMP_Decode((void *)(binStartAddr + offset), gpFileBuffer, \
+ bmpheader->width, bmpheader->height, 24);
+
+ unsigned int i;
+ unsigned int color24;
+ unsigned short color16;
+
+ LCD_SetCursor((void *)BOARD_LCD_BASE, 0, 0);
+ LCD_WriteRAM_Prepare((void *)BOARD_LCD_BASE);
+ unsigned char * pImage = gpFileBuffer;
+ for (i = 0; i < (BOARD_LCD_WIDTH * BOARD_LCD_HEIGHT); i++) {
+
+ color24 = (*pImage << 16) | (*(pImage+1) << 8) | (*(pImage+2));
+ pImage += 3;
+ color16 = RGB24ToRGB16(color24);
+ LCD_WriteRAM((void *)BOARD_LCD_BASE, color16);
+ }
+
+
+ unsigned int k;
+ if(slideheader.dispboxcount) {
+ for(k = 0; k < slideheader.dispboxcount; ++k) {
+ //conversion rule based on SAM3U current setting.
+ unsigned int top = slideheader.dispboxinfo[k].dispboxleft;
+ unsigned int left = DEMOSLIDEHEIGHT - slideheader.dispboxinfo[k].dispboxbottom;
+ unsigned int width = slideheader.dispboxinfo[k].dispboxheight;
+ unsigned int height = slideheader.dispboxinfo[k].dispboxwidth;
+
+ SetDispBoxPos(k+1, DISPBOX_ENABLE, \
+ top, left, width, height);
+
+ EnableDispBox(k);
+ }
+
+ } else {
+ for(k = 0; k < MAX_DISPBOX_PER_SLIDE; ++k) {
+ DisableDispBox(k);
+ }
+ }
+
+ return 0;
+}
+
+//------------------------------------------------------------------------------
+/// Show LCD prompt information, normally it is slide from demo bin
+/// \param pFileName, demo bin file name without designated drive path
+//------------------------------------------------------------------------------
+int ReadSlideInfoAndShow(const char * pFileName)
+{
+ int iRet;
+ char pFile[256];
+
+ strcpy(pFile,SDCARD_ROOT_DIRECTORY);
+ strncat(pFile, pFileName, 256-1-strlen(SDCARD_ROOT_DIRECTORY));
+ //gpActiveBinFile = "sam3demo.bin";//fname;
+ iRet = ProcessBinFromSDcard(gActiveSlideIndex, pFile);
+
+ //read from SDCard fail
+ if(iRet) {
+ strcpy(pFile, NAND_ROOT_DIRECTORY);
+ strncat(pFile, pFileName, 256-1-strlen(NAND_ROOT_DIRECTORY));
+
+ iRet = ProcessBinFromNandFlash(gActiveSlideIndex, pFile);
+
+ if(iRet){
+ iRet = ProcessBinFromInternalFlash(gDemoBinAddrInFlash, 0);
+ }
+ }
+
+ //both reading from sdcard and nand flash fail!
+ if(iRet) {
+ TRACE_ERROR("\n\r Read LCD prompt slide information fail!");
+ }
+
+ return iRet;
+}
+
+//------------------------------------------------------------------------------
+/// Check the hit point if it is in hyperlink zone of active slide
+/// \param slideIdx slide index to check the hyperlink on the slide
+/// \return 0 means not in hot zone; other values is the link index start from 1
+//------------------------------------------------------------------------------
+static unsigned int CheckHitLink()
+{
+ unsigned int bottom, left, width, height;
+ unsigned int linkcnt;
+
+#if !defined(GLOBALSLIDEINFO)
+ SlideINFOHeader gActiveSlideHeader;//to consistent with global one
+
+ if(GetActiveSlideInfoHeader(gActiveSlideIndex,\
+ &gActiveSlideHeader,\
+ 0))
+ {
+ //can't get active slide info, Consider as not hit
+ return 0;
+ }
+
+#endif
+
+ linkcnt = gActiveSlideHeader.linkcount;
+ unsigned int i;
+ for(i = 0; i < linkcnt; ++i) {
+ bottom = gActiveSlideHeader.linkinfo[i].linkboxbottom;
+ left = gActiveSlideHeader.linkinfo[i].linkboxleft;
+ width = gActiveSlideHeader.linkinfo[i].linkboxwidth;
+ height = gActiveSlideHeader.linkinfo[i].linkboxheight;
+
+ //inside the link box?
+ if((gTSDxPressed > left) && (gTSDxPressed < (left + width)) && \
+ (gTSDyPressed < bottom) && (gTSDyPressed > (bottom - height)))
+ return i+1;
+ }
+
+ return 0;
+}
+
+//------------------------------------------------------------------------------
+/// Get link string from link index on active slide
+/// \param linkIdx link index on active slide, start from 1
+/// \return NULL means no link string; otherwise, link string
+//------------------------------------------------------------------------------
+char * GetLinkStrFromActiveSlide(unsigned int linkIdx)
+{
+
+#if !defined(GLOBALSLIDEINFO)
+ SlideINFOHeader gActiveSlideHeader;//to consistent with global one
+
+ if(GetActiveSlideInfoHeader(gActiveSlideIndex,\
+ &gActiveSlideHeader,\
+ 0))
+ {
+ //can't get active slide info, Consider as NULL
+ return NULL;
+ }
+
+
+#endif
+ return gActiveSlideHeader.linkinfo[linkIdx-1].linkstring;
+}
+
+//////////////////////////////////////////////////////
+/// exported function /
+//////////////////////////////////////////////////////
+
+//-------------------------------------------------------------------------
+/// Set Touch screen is touched
+//-------------------------------------------------------------------------
+void TSD_SetTouched(void)
+{
+ gTSDPressed = 1;
+}
+
+//-------------------------------------------------------------------------
+/// Clear Touch screen is touched
+//-------------------------------------------------------------------------
+void TSD_ClearTouched(void)
+{
+ gTSDPressed = 0;
+}
+
+//-------------------------------------------------------------------------
+/// Get Touch screen is touched
+//-------------------------------------------------------------------------
+unsigned char TSD_GetTouched(void)
+{
+ return gTSDPressed;
+}
+
+//-------------------------------------------------------------------------
+/// Check if touchscreen hit in a hot zone
+/// \return 0 means no, other values mean yes
+//-------------------------------------------------------------------------
+unsigned int TSD_CommandIsReady()
+{
+ unsigned int ret;
+
+ if(0 == gTSDxPressed && 0 == gTSDyPressed) {
+ return 0;
+ }
+
+ ret = CheckHitLink();
+
+ //set global variable for link index
+ gLinkIndex = ret;
+
+ gTSDxPressed = gTSDyPressed = 0;
+
+ return ret;
+}
+
+//----------------------------------------------------------
+/// Get ready command
+/// \return string pointer to link string
+//----------------------------------------------------------
+const char * TSD_GetCommand()
+{
+ char *pStr;
+
+ //get link string from index
+ pStr = GetLinkStrFromActiveSlide(gLinkIndex);
+
+ //clear
+ gLinkIndex = 0;
+
+ return pStr;
+}
+
+//------------------------------------------------------------------------------
+/// Set LCD fresh show flag, this will cause next call to LCD_ShowPrompt reload
+/// slide page data any way.
+//------------------------------------------------------------------------------
+void LCD_SetRefreshFlag()
+{
+ gLcdRefreshFlag = 1;
+}
+
+//------------------------------------------------------------------------------
+/// Clear LCD fresh show flag
+//------------------------------------------------------------------------------
+void LCD_ClearRefreshFlag()
+{
+ gLcdRefreshFlag = 0;
+}
+
+//------------------------------------------------------------------------------
+/// Show LCD prompt information, normally it is slide from demo bin
+//------------------------------------------------------------------------------
+int LCD_ShowPrompt()
+{
+ static unsigned int slideIndexLoaded = 0xffffffff;
+ int ret;
+
+ if(gActiveSlideHeader.propyes) {
+ if(slideIndexLoaded != gActiveSlideIndex && slideIndexLoaded != 0xffffffff) {
+ ParseAndRunMultiCmds(gActiveSlideHeader.propinfo.onCloseCmds);
+ }
+ }
+
+ //reload show only slide index changed or fresh flag is set
+ if(slideIndexLoaded != gActiveSlideIndex || gLcdRefreshFlag) {
+ ret = ReadSlideInfoAndShow(gpActiveBinFile);
+
+ if(gActiveSlideHeader.propyes && slideIndexLoaded != gActiveSlideIndex) {
+ ParseAndRunMultiCmds(gActiveSlideHeader.propinfo.onInitCmds);
+ }
+
+ slideIndexLoaded = gActiveSlideIndex;
+ gLcdRefreshFlag = 0;
+ }
+
+ if(gActiveSlideHeader.propyes) {
+ ParseAndRunMultiCmds(gActiveSlideHeader.propinfo.onRefreshCmds);
+ }
+
+ return ret;
+}
+
diff --git a/utility/demo-fw/include/DemobinHeader.h b/utility/demo-fw/include/DemobinHeader.h
new file mode 100644
index 0000000..e3d5b5c
--- /dev/null
+++ b/utility/demo-fw/include/DemobinHeader.h
@@ -0,0 +1,107 @@
+/* ----------------------------------------------------------------------------
+ * 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 DEMOBINHEADER_H_
+#define DEMOBINHEADER_H_
+
+#include <string.h>
+
+//------------------------------------------------------------------------------
+// Definitions
+//------------------------------------------------------------------------------
+
+#define MAXSCRIPTSTRINGLINE 128
+
+#define MAXSLIDESPERBIN 50
+
+#define MAXLINKLEN 50
+
+#define MAX_LINK_PER_SLIDE 10
+
+#define MAX_DISPBOX_PER_SLIDE 4
+
+#define DEMOSLIDEWIDTH 240
+
+#define DEMOSLIDEHEIGHT 320
+
+#define ClearDemoBINHeader(pHead) memset((pHead), 0xFF, sizeof(DemoBINHeader))
+
+#define ClearSlideINFOHeader(pHead) memset((pHead), 0xFF, sizeof(SlideINFOHeader))
+
+/// ATMEL DEMO BIN tag value
+#define ATMLBINTAG 0x4C4D5441
+
+/// demo bin file header
+typedef struct {
+ unsigned int tag;///demo bin head,'A','T','M','L'
+ unsigned int filesize;///bin file size
+ unsigned int headersize;///headsize including all SlideINFOHeader fields
+ unsigned int slidecount;///slide numbers
+} DemoBINHeader;
+
+typedef struct {
+ ///value are converted from slides script. noted BMP anticlockwise rotated 90 degree
+ unsigned int linkboxbottom;
+ unsigned int linkboxleft;
+ unsigned int linkboxwidth;
+ unsigned int linkboxheight;
+ ///link string
+ char linkstring[MAXLINKLEN];
+}SlideLinkINFO;
+
+typedef struct {
+ ///value are converted from slides script. noted BMP anticlockwise rotated 90 degree
+ unsigned int dispboxbottom;
+ unsigned int dispboxleft;
+ unsigned int dispboxwidth;
+ unsigned int dispboxheight;
+} SlideDispINFO;
+
+typedef struct {
+ //properties for each slide, command string line supported only now.
+ unsigned int propcnt; //numbers of properties
+ char onInitCmds[MAXLINKLEN];
+ char onRefreshCmds[MAXLINKLEN];
+ char onCloseCmds[MAXLINKLEN];
+} SlidePropINFO;
+
+typedef struct {
+ unsigned int slideoffset;
+ unsigned int slidedatalength;
+ unsigned int slidewidth;
+ unsigned int slideheight;
+ unsigned int dispboxcount;//0 means no display box, others mean yes
+ SlideDispINFO dispboxinfo[MAX_DISPBOX_PER_SLIDE];
+ unsigned int linkcount;
+ SlideLinkINFO linkinfo[MAX_LINK_PER_SLIDE];
+ unsigned int propyes;// 0 means no property settings, 1 or others mean yes
+ SlidePropINFO propinfo;
+} SlideINFOHeader;
+
+#endif /// DEMOBINHEADER_H_
diff --git a/utility/demo-fw/include/dfm_accelerometer.h b/utility/demo-fw/include/dfm_accelerometer.h
new file mode 100644
index 0000000..9e7a9ab
--- /dev/null
+++ b/utility/demo-fw/include/dfm_accelerometer.h
@@ -0,0 +1,93 @@
+/* ----------------------------------------------------------------------------
+ * 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
+///
+/// This file contains apis and definitions for tilt sensing.
+///
+//------------------------------------------------------------------------------
+
+#ifndef DV_ACCELEROMETER_H
+#define DV_ACCELEROMETER_H
+
+#include "dfm_entry.h"
+
+#define ACC_SHIFT 0 //!< Accelerometer filtering value
+#define ACC_ZERO (0x7FF >> ACC_SHIFT) //!< Accelerometer 0 value 0x1000/2
+#define ACC_1G (0x223 >> ACC_SHIFT) //!< Accelerometer 1G value 2.09/3.3 * 0x1000 delta 1g
+
+#define ACC_ZERO_X ACC_ZERO
+#define ACC_ZERO_Y ACC_ZERO
+#define ACC_ZERO_Z ACC_ZERO
+
+#define ACC_AMPLITUDE_UPPER (ACC_1G*ACC_1G*1.01)
+#define ACC_AMPLITUDE_LOWER (ACC_1G*ACC_1G*0.99)
+
+#define DV_Accelerometer_Unchanged 0 //!< default unchanged direction
+#define DV_Accelerometer_normal_up 1 //!< normal up
+#define DV_Accelerometer_up 2 //!< up
+#define DV_Accelerometer_down 3 //!< down
+#define DV_Accelerometer_left 4 //!< left
+#define DV_Accelerometer_right 5 //!< right
+
+#define DV_Accelerometer_up_right 6 //!< up and right
+#define DV_Accelerometer_up_left 7 //!< up and left
+#define DV_Accelerometer_down_left 8 //!< down and left
+#define DV_Accelerometer_down_right 9 //!< down and right
+
+#define DIR_UNCHANGED 0
+#define DIR_HORIZIONTAL_UP 1
+#define DIR_HORIZIONTAL_DOWN 2
+#define DIR_VERTICAL_UP 3
+#define DIR_VERTICAL_DOWN 4
+
+typedef struct {
+ int x;
+ int y;
+ int z;
+} xyz_t;
+
+
+typedef struct {
+ xyz_t m; //!< immediate acceleration
+ xyz_t k; //!< calibration basis
+ xyz_t ak; //!< acceleration difference
+ } acc_t;
+
+extern int gDir;
+
+extern TInputEntry gAccEntry ;
+extern unsigned int gLcdRefreshFlag;
+extern int DV_ACCELEROMETER_Init(void);
+extern void DV_Accelerometer_Turn();
+extern int DV_Check_AccStatus();
+extern void DV_ACCELEROMETER_Measure(void);
+
+#endif
diff --git a/utility/demo-fw/include/dfm_button.h b/utility/demo-fw/include/dfm_button.h
new file mode 100644
index 0000000..e109405
--- /dev/null
+++ b/utility/demo-fw/include/dfm_button.h
@@ -0,0 +1,49 @@
+/* ----------------------------------------------------------------------------
+ * 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 __DFM_BUTTON_H_
+#define __DFM_BUTTON_H_
+
+#include "dfm_lcd_tsd.h"
+#include "dfm_entry.h"
+
+// input entry for register
+extern TInputEntry gButtonEntry;
+
+//draw a focus circle on current active icon
+int BTN_ShowPrompt();
+
+//check if button is pressed
+unsigned int BTN_CommandIsReady();
+
+//get command string for pressed button
+const char * BTN_GetCommand();
+
+#endif //end of __DFM_JOYSTICK_H_
+
diff --git a/utility/demo-fw/include/dfm_cmd.h b/utility/demo-fw/include/dfm_cmd.h
new file mode 100644
index 0000000..c1bde68
--- /dev/null
+++ b/utility/demo-fw/include/dfm_cmd.h
@@ -0,0 +1,136 @@
+/* ----------------------------------------------------------------------------
+ * 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 __DFM_CMD_H
+#define __DFM_CMD_H
+
+//------------------------------------------------------------------------------
+// Definitions
+//------------------------------------------------------------------------------
+
+///limits definition
+#define MAX_LIST_GROUP 100
+/// max active groups
+#define MAX_ACT_GROUP 10
+/// max active commands
+#define MAX_ACT_CMD 255
+/// max command arguments
+#define MAX_CMD_ARGS 10
+/// max command number concatenated in one line
+#define MAX_MULTI_CMD 5
+
+///define NULL
+#ifndef NULL
+#define NULL 0
+#endif
+
+/// structure for describe function
+struct _FStruct {
+ char *pGrpName;
+ char *pCmdName;
+ int (*cmdProcess)(int argc, char **argv);
+#ifdef USAGE_HELP
+ char *pUsage;
+#endif
+};
+
+typedef struct _FStruct FStruct;
+
+
+/// max group numbers allowed to build in
+#define MAX_BUILDIN_GROUP 32
+
+/// section to put all commands
+#define GSHELL_SECTION ".gs_section"
+
+/// system group name, will be always active at the first priority
+#define SYS_GROUP "default"
+
+/// section macro definition
+#if defined(__GNUC__)
+
+#define CMD_OBJ const
+#define INSECTION(secname) __attribute__ ((unused, section(secname)))
+
+#elif defined(__ICCARM__)
+
+#pragma section = GSHELL_SECTION
+
+#define CMD_OBJ __root const
+#define INSECTION(secname) @ secname
+
+#else
+
+#error "unsupported tool chain"
+
+#endif
+
+
+/// usage help compiled
+#ifdef USAGE_HELP
+
+#define DFM_CMD(cmdString, procFunc, hlpString, grpName) \
+ CMD_OBJ FStruct GS_Func_##cmdString INSECTION(GSHELL_SECTION) = {\
+ grpName,\
+ #cmdString,\
+ procFunc,\
+ hlpString\
+ }
+
+#else
+
+#define DFM_CMD(cmdString, procFunc, hlpString, grpName) \
+ CMD_OBJ FStruct GS_Func_##cmdString INSECTION(GSHELL_SECTION)= {\
+ grpName,\
+ #cmdString,\
+ procFunc,\
+ }
+
+#endif
+
+//------------------------------------------------------------------------------
+// Exported Functions
+//------------------------------------------------------------------------------
+
+// Parse a command string and search in active groups, run if matched
+int ParseAndRunCmd(const char * pCmdString);
+
+// Parse a string line containing multi commands and arguments, then
+// search in active groups, run if matched
+int ParseAndRunMultiCmds(const char * pMultiCmdStr);
+
+//------------------------------------------------------------------------------
+/// Run batch command
+//------------------------------------------------------------------------------
+int RunScript(int argc, char *argv[]);
+
+// // Main portal function of gshell
+// void Gshell_MainProcess(int argc, char *argv[]);
+
+#endif /// end of __DFM_CMD_H
diff --git a/utility/demo-fw/include/dfm_config.h b/utility/demo-fw/include/dfm_config.h
new file mode 100644
index 0000000..874d7c4
--- /dev/null
+++ b/utility/demo-fw/include/dfm_config.h
@@ -0,0 +1,38 @@
+#ifndef __DFM_CONFIG_H__
+#define __DFM_CONFIG_H__
+
+//enable fatfs on SDCard
+#define DFM_FATFS_SDCARD
+
+//enable fatfs on Nandflash
+#define DFM_FATFS_NANDFLASH
+
+//enable fatfs on SDRAM
+//#define DFM_FATFS_SDRAM
+
+//enable LCD and touchscreen
+#define USE_LCD_TSD
+
+//define file buffer size, used to read bitmap data
+//note: this config make var relocated to PSRAM,so size is ok.
+#define FILE_BUF_SIZE 0x40000U
+
+//enable interrupt chain management
+#define USE_IT_CHAIN_MGR
+
+//LCD controller
+#define LCDC_HX8347
+
+#ifndef LCDSLIDEIMAGEFILE
+#define LCDSLIDEIMAGEFILE "sam3demo.bin"
+#define LCDSLIDEVIMAGEFILE "SamDEMOV.bin"
+#endif
+
+//enable variable relocation
+#define VAR_RELOCATION
+
+//variable relocation memory base
+#define RELOC_VAR_MEM_BASE BOARD_EBI_PSRAM
+
+#endif // end of __DFM_CONFIG_H__
+
diff --git a/utility/demo-fw/include/dfm_console.h b/utility/demo-fw/include/dfm_console.h
new file mode 100644
index 0000000..39935ef
--- /dev/null
+++ b/utility/demo-fw/include/dfm_console.h
@@ -0,0 +1,55 @@
+/* ----------------------------------------------------------------------------
+ * 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 __DBGU_CONSOLE_H
+#define __DBGU_CONSOLE_H
+
+#include "dfm_entry.h"
+
+#define DBGU_CMDBUFSIZE 256
+
+#ifndef GS_SHELL_PROMPT
+#define GS_SHELL_PROMPT "DFM_DBGU:>"
+#endif
+
+extern TInputEntry gDBGUEntry;
+
+//Get input command and argument string from console
+//extern int DBGU_GetCmdString(const char *const prompt);
+
+//Show DBGU console prompt information
+extern int DBGU_ShowPrompt();
+
+//Check if command is ready on DBGU console
+extern unsigned int DBGU_CommandIsReady();
+
+//Get the pointer to DBGU console input buffer
+extern const char * DBGU_GetCommand();
+
+#endif
diff --git a/utility/demo-fw/include/dfm_dispboxmgr.h b/utility/demo-fw/include/dfm_dispboxmgr.h
new file mode 100644
index 0000000..9920eed
--- /dev/null
+++ b/utility/demo-fw/include/dfm_dispboxmgr.h
@@ -0,0 +1,125 @@
+/* ----------------------------------------------------------------------------
+ * 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_DISPBOX_H_
+#define __LCD_DISPBOX_H_
+
+#include "DemobinHeader.h"
+
+//------------------------------------------------------------------------------
+// Definitions
+//------------------------------------------------------------------------------
+
+///display margin in pixel in dispbox area
+#define DISPMARGIN 2
+///line distance in pixel in dispbox area
+#define LINEDISTANCE 2
+///char distance in pixel, actually this is used to meet API LIB DrawString(...)
+#define CHARDISTANCE 2
+///status of enable display box
+#define DISPBOX_ENABLE 1
+///status of disable display box
+#define DISPBOX_DISABLE 0
+
+typedef struct _DISPBOX_ZONE {
+ /// display box top
+ unsigned int top;
+ /// display box left
+ unsigned int left;
+ /// display box width
+ unsigned int width;
+ /// display box height
+ unsigned int height;
+} TDISPBOX_ZONE;
+
+typedef struct _DISPBOX_INFO {
+ unsigned int dispBoxEnable;
+ TDISPBOX_ZONE dispBoxZone;
+ unsigned int bgColor;// background color
+ unsigned int fontColor;// font color of display box
+ unsigned int xCursor;
+ unsigned int yCursor;
+} TDISPBOX_INFO;
+
+typedef struct _DISPBOX_MGR {
+ unsigned int dispBoxCount;
+ TDISPBOX_INFO dispBoxInfo[MAX_DISPBOX_PER_SLIDE];
+} TDISPBOX_MGR;
+
+//------------------------------------------------------------------------------
+// Exported functions
+//------------------------------------------------------------------------------
+
+//set display box position info
+extern void SetDispBoxPos(
+ unsigned int dispBoxID,
+ unsigned int enabledispbox,
+ unsigned int top,
+ unsigned int left,
+ unsigned int width,
+ unsigned int height);
+
+//Draw a string in display box with
+extern void DrawStringInDispBox(
+ // lcd frame buffer address
+ void *pBuffer,
+ // display box ID, starting from 1
+ unsigned int dispBoxID,
+ //pointer to string for show
+ const char *pStr,
+ //display string font color,
+ unsigned int fontColor,
+ //display string background color, 0xFFFFFFFF means no need to set bgColor
+ unsigned int bgColor,
+ //flag for scroll way, current only support 'clear or not clear display box'
+ //when display string reach end and roll back to show.
+ //0 means clear, 1 means don't clear.
+ unsigned int scrollFlag);
+
+//Draw a string in display box with default font color
+extern void DrawStrInDispBoxDefault(void *pBuffer, unsigned int dispBoxID, const char *pStr);
+
+//Draw a string in display box with default font and background color
+//if scroll back, don't clear
+void DrawStrInDispBoxScrollNoClear(void *pBuffer, unsigned int dispBoxID, const char *pStr);
+
+//clear display box zone with 'color'
+extern void ClearDispBoxZoneColor(unsigned int dispBoxID, unsigned int color);
+
+//Clear display box with default background color
+extern void ClearDispBoxZoneDefault(unsigned int dispBoxID);
+
+//disable display box
+extern void DisableDispBox(unsigned int dispBoxID);
+
+//enable display box
+extern void EnableDispBox(unsigned int dispBoxID);
+
+#endif
+
diff --git a/utility/demo-fw/include/dfm_entry.h b/utility/demo-fw/include/dfm_entry.h
new file mode 100644
index 0000000..fcfab64
--- /dev/null
+++ b/utility/demo-fw/include/dfm_entry.h
@@ -0,0 +1,67 @@
+/* ----------------------------------------------------------------------------
+ * 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 __DFM_ENTRY_H_
+#define __DFM_ENTRY_H_
+
+//structure for command queue
+typedef struct _tCmdQueue {
+ const char * command;
+ struct _tCmdQueue * next;
+} TCmdQueue;
+
+//structure for prompt registry definition
+typedef struct _tInputEntry {
+ unsigned int readyFlag;
+ TCmdQueue CmdElement;
+ int (*Prompt)(void);
+ unsigned int (*CommandIsReady)(void);
+ const char *(*GetCommand)(void);
+ struct _tInputEntry *next;
+} TInputEntry;
+
+
+
+//Register input entry
+extern int RegisterInputEntry(TInputEntry *pEntryStruct);
+
+//Show prompt registered
+extern int ShowPrompt();
+
+//Check if any command is ready
+extern unsigned int CommandIsReady();
+
+//Get command queue
+extern TCmdQueue * GetCommandQueue();
+
+//Run command queue
+extern int RunCommandQueue(TCmdQueue *pCmdQueue);
+
+#endif // end of __DFM_ENTRY_H_
+
diff --git a/utility/demo-fw/include/dfm_fatfs.h b/utility/demo-fw/include/dfm_fatfs.h
new file mode 100644
index 0000000..3803d0c
--- /dev/null
+++ b/utility/demo-fw/include/dfm_fatfs.h
@@ -0,0 +1,96 @@
+/* ----------------------------------------------------------------------------
+ * 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 __DFM_FATFS_H__
+#define __DFM_FATFS_H__
+
+#if defined(PINS_NANDFLASH)
+#include <memories/MEDNandFlash.h>
+#include <memories/nandflash/RawNandFlash.h>
+#include <memories/nandflash/TranslatedNandFlash.h>
+#endif
+
+#include "fatfs_config.h"
+#include "dfm_config.h"
+#include <usb/device/massstorage/MSDLun.h>
+#include <pio/pio.h>
+#include "Media.h"
+
+//Assign storage drive name
+#if _FS_TINY == 0
+#define SDCARD_ROOT_DIRECTORY "0:"
+#define NAND_ROOT_DIRECTORY "1:"
+#else
+#define SDCARD_ROOT_DIRECTORY ""
+#define NAND_ROOT_DIRECTORY ""
+#endif
+
+#if defined(at91cap9stk)
+#define MCI_ID 1 //no connector for MCIO/SPI0
+#else
+#define MCI_ID 0
+#endif
+
+#if defined(PINS_NANDFLASH)
+/// Pins used to access to nandflash.
+extern const Pin gpPinsNf[];// = {PINS_NANDFLASH};
+/// Nandflash device structure.
+extern struct TranslatedNandFlash gTranslatedNf;
+/// Address for transferring command bytes to the nandflash.
+extern unsigned int gNFCmdBytesAddr;// = BOARD_NF_COMMAND_ADDR;
+/// Address for transferring address bytes to the nandflash.
+extern unsigned int gNFAddrBytesAddr;// = BOARD_NF_ADDRESS_ADDR;
+/// Address for transferring data bytes to the nandflash.
+extern unsigned int gNFDataBytesAddr;// = BOARD_NF_DATA_ADDR;
+/// Nandflash chip enable pin.
+extern const Pin gNFCePin;// = BOARD_NF_CE_PIN;
+/// Nandflash ready/busy pin.
+extern const Pin gNFRbPin;// = BOARD_NF_RB_PIN;
+#endif
+
+///// Maximum number of LUNs which can be defined.
+///// (Logical drive = physical drive = medium number)
+#define MAX_LUNS 3
+
+/// Size of one block in bytes.
+#define BLOCK_SIZE 512
+
+/// Size of the reserved Nand Flash (4M)
+#define NF_RESERVE_SIZE (4*1024*1024)
+
+/// Size of the managed Nand Flash (128M)
+#define NF_MANAGED_SIZE (128*1024*1024)
+
+/// Size of the MSD IO buffer in bytes (6K, more the better).
+#define MSD_BUFFER_SIZE (12*BLOCK_SIZE)
+
+extern void ConfigureNandFlashEBI(unsigned int mck);
+
+#endif // end of __DFM_FATFS_H__
+
diff --git a/utility/demo-fw/include/dfm_init.h b/utility/demo-fw/include/dfm_init.h
new file mode 100644
index 0000000..5e63318
--- /dev/null
+++ b/utility/demo-fw/include/dfm_init.h
@@ -0,0 +1,70 @@
+/* ----------------------------------------------------------------------------
+ * 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 __DFM_INIT_
+#define __DFM_INIT_
+
+//struct definition for init interface
+typedef struct _t_init {
+ unsigned int initlvl;
+ int (*pfInitFunc)(void);
+} T_INIT;
+
+
+#if defined(__GNUC__) //GNU C compiler, Keil also supported if --gnu is defined in CFLAG
+
+#define OBJ_HEAD const
+#define INSECTION(secname) __attribute__ ((unused, section(secname)))
+
+#elif defined(__ICCARM__) //ICCARM compiler
+
+#pragma section = ".gs_initsection"
+
+#define OBJ_HEAD __root const
+#define INSECTION(secname) @ secname
+
+#else
+
+/// current only GNUC(keil MDK), IAR EWARM compiler are supported!
+#error "unsupported tool chain"
+
+#endif
+
+/// define a general macro for init function operation management
+#define DFM_INIT(initlvl, initFunc) \
+ OBJ_HEAD T_INIT _gs_init_##initFunc##initlvl INSECTION(".gs_initsection") = {\
+ initlvl, \
+ initFunc\
+ }
+
+//run all init handler from starting from level 1
+unsigned int RunAllInit();
+
+#endif
+
diff --git a/utility/demo-fw/include/dfm_it.h b/utility/demo-fw/include/dfm_it.h
new file mode 100644
index 0000000..e23476d
--- /dev/null
+++ b/utility/demo-fw/include/dfm_it.h
@@ -0,0 +1,47 @@
+/* ----------------------------------------------------------------------------
+ * 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 __DFM_IT_H_
+#define __DFM_IT_H_
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+typedef struct _DFM_ItServList {
+ unsigned int itID;
+ void (*ItHandler)(void);
+ struct _DFM_ItServList * next;
+} TDFM_ItServList;
+
+int DFM_RegisterItHandler(TDFM_ItServList *pItHandler);
+
+int DFM_UnRegisterItHandler(TDFM_ItServList *pItHandler);
+
+#endif
diff --git a/utility/demo-fw/include/dfm_lcd_tsd.h b/utility/demo-fw/include/dfm_lcd_tsd.h
new file mode 100644
index 0000000..d37e4fc
--- /dev/null
+++ b/utility/demo-fw/include/dfm_lcd_tsd.h
@@ -0,0 +1,77 @@
+/* ----------------------------------------------------------------------------
+ * 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 __DFM_LCD_TSD_H__
+#define __DFM_LCD_TSD_H__
+
+#include "dfm_entry.h"
+#include "DemobinHeader.h"
+
+//for LCD prompt register entry
+extern TInputEntry gLCDEntry;
+
+//for change of display slide on lcd
+extern unsigned short gActiveSlideIndex;
+
+#define GLOBALSLIDEINFO
+
+#if defined(GLOBALSLIDEINFO)
+extern SlideINFOHeader gActiveSlideHeader;
+#endif
+
+/// Get link string from link index on active slide
+extern char * GetLinkStrFromActiveSlide(unsigned int linkIdx);
+
+// Show pic on LCD as prompt
+extern int LCD_ShowPrompt();
+
+// Check if hotzones have been hit on touchscreen
+extern unsigned int TSD_CommandIsReady();
+
+// Get hotzone command hyperlink string
+extern const char * TSD_GetCommand();
+
+// Set LCD fresh show flag
+extern void LCD_SetRefreshFlag();
+
+// Clear LCD fresh show flag
+extern void LCD_ClearRefreshFlag();
+
+// Get last pen press position
+extern void TSD_GetPenLastPosition(unsigned int *pX, unsigned int *pY);
+
+/// Set touched flag
+void TSD_SetTouched(void);
+/// Clear touched flag
+void TSD_ClearTouched(void);
+/// Get touched flag
+unsigned char TSD_GetTouched(void);
+
+#endif
+
diff --git a/utility/demo-fw/include/dfm_varloc.h b/utility/demo-fw/include/dfm_varloc.h
new file mode 100644
index 0000000..48c118d
--- /dev/null
+++ b/utility/demo-fw/include/dfm_varloc.h
@@ -0,0 +1,49 @@
+#ifndef __DFM_VARLOC_H_
+#define __DFM_VARLOC_H
+
+#include "dfm_fatfs.h"
+#include "dfm_config.h"
+
+// relocation variables that size is bigger to space start from RELOC_VAR_MEM_BASE
+#ifdef VAR_RELOCATION
+
+ #if defined(__ICCARM__)
+
+ #define RLOC_OBJ __no_init
+ #define _AT(addr) @ (addr)
+
+ #elif defined(__CC_ARM)
+
+ #define RLOC_OBJ
+ #define _AT(addr) __attribute__ ((at(_addr)))
+
+ #elif defined(__GNUC__)
+
+ #define RLOC_OBJ
+ #define _AT(addr)
+ #else
+ #error "Unsupported tool chain"
+ #endif
+
+#else
+ #define RLOC_OBJ
+ #define _AT(addr)
+#endif
+
+#if defined(VAR_RELOCATION) && !defined(RELOC_VAR_MEM_BASE)
+ #error "Enable variables relocation, but not give RELOC_VAR_MEM_BASE"
+#endif
+
+#define FATFS_MEDIA_OBJ_ADDR RELOC_VAR_MEM_BASE
+#define FATFS_SDCARD_OBJ_ADDR (FATFS_MEDIA_OBJ_ADDR + sizeof(Media) * MAX_LUNS)
+#define FATFS_NANDFLASH_OBJ_ADDR (FATFS_SDCARD_OBJ_ADDR + sizeof(FATFS))
+#define NANDFLASH_TRANS_TAB_ADDR (FATFS_NANDFLASH_OBJ_ADDR + sizeof(FATFS))
+#define ACTIVESLIDE_INFOHEAD_ADDR (NANDFLASH_TRANS_TAB_ADDR + sizeof(struct TranslatedNandFlash))
+#define FILE_BUFFER_ADDR (ACTIVESLIDE_INFOHEAD_ADDR + sizeof(SlideINFOHeader))
+
+#define MSDD_LUN_OBJ_ADDR (FILE_BUFFER_ADDR + FILE_BUF_SIZE)
+#define MSDD_BUF_OBJ_ADDR (MSDD_LUN_OBJ_ADDR + sizeof(MSDLun) * MAX_LUNS)
+#define RELOC_VAR_MEM_END (MSDD_BUF_OBJ_ADDR + MSD_BUFFER_SIZE)
+#define RELOC_VAR_MEM_SIZE (RELOC_VAR_MEM_END - RELOC_VAR_MEM_BASE)
+
+#endif // end of _DFM_VARLOC_H_
diff --git a/utility/demo-fw/include/fatfs_config.h b/utility/demo-fw/include/fatfs_config.h
new file mode 100644
index 0000000..45d0bba
--- /dev/null
+++ b/utility/demo-fw/include/fatfs_config.h
@@ -0,0 +1,220 @@
+/* ----------------------------------------------------------------------------
+ * 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 FATFS_CONFIG_H
+#define FATFS_CONFIG_H
+#include "integer.h"
+
+/*-----------------------------------------------------------------------*/
+/* Correspondence between drive number and physical drive */
+/* Note that Tiny-FatFs supports only single drive and always */
+/* accesses drive number 0. */
+
+#define DRV_MMC 0
+#define DRV_SDRAM 2
+#define DRV_ATA 4
+#define DRV_USB 3
+#define DRV_NAND 1
+
+
+#define SECTOR_SIZE_DEFAULT 512
+#define SECTOR_SIZE_SDRAM 512
+#define SECTOR_SIZE_SDCARD 512
+
+/*---------------------------------------------------------------------------/
+/ FatFs Configuration Options
+/
+/ CAUTION! Do not forget to make clean the project after any changes to
+/ the configuration options.
+/
+/----------------------------------------------------------------------------*/
+#define _FFCONFIG 0x007E
+
+/*---------------------------------------------------------------------------/
+/ Function and Buffer Configurations
+/----------------------------------------------------------------------------*/
+
+#define _FS_TINY 0 /* 0 or 1 */
+/* When _FS_TINY is set to 1, FatFs uses the sector buffer in the file system
+/ object instead of the sector buffer in the individual file object for file
+/ data transfer. This reduces memory consumption 512 bytes each file object. */
+
+#if _FS_TINY != 1
+#define _FS_READONLY 0
+/* Setting _FS_READONLY to 1 defines read only configuration. This removes
+/ writing functions, f_write, f_sync, f_unlink, f_mkdir, f_chmod, f_rename,
+/ f_truncate and useless f_getfree. */
+#else
+#define _FS_READONLY 1
+/* Setting _FS_READONLY to 1 defines read only configuration. This removes
+/ writing functions, f_write, f_sync, f_unlink, f_mkdir, f_chmod, f_rename,
+/ f_truncate and useless f_getfree. */
+#endif
+
+#define _FS_MINIMIZE 0 /* 0, 1, 2 or 3 */
+/* The _FS_MINIMIZE option defines minimization level to remove some functions.
+/
+/ 0: Full function.
+/ 1: f_stat, f_getfree, f_unlink, f_mkdir, f_chmod, f_truncate and f_rename
+/ are removed.
+/ 2: f_opendir and f_readdir are removed in addition to level 1.
+/ 3: f_lseek is removed in addition to level 2. */
+
+
+#define _USE_STRFUNC 0 /* 0, 1 or 2 */
+/* To enable string functions, set _USE_STRFUNC to 1 or 2. */
+
+
+#define _USE_MKFS 1 /* 0 or 1 */
+/* To enable f_mkfs function, set _USE_MKFS to 1 and set _FS_READONLY to 0 */
+
+
+#define _USE_FORWARD 0 /* 0 or 1 */
+/* To enable f_forward function, set _USE_FORWARD to 1 and set _FS_TINY to 1. */
+
+
+
+/*---------------------------------------------------------------------------/
+/ Locale and Namespace Configurations
+/----------------------------------------------------------------------------*/
+
+#define _CODE_PAGE 850
+/* The _CODE_PAGE specifies the OEM code page to be used on the target system.
+/ Incorrect setting of the code page can cause a file open failure.
+/
+/ 932 - Japanese Shift-JIS (DBCS, OEM, Windows)
+/ 936 - Simplified Chinese GBK (DBCS, OEM, Windows)
+/ 949 - Korean (DBCS, OEM, Windows)
+/ 950 - Traditional Chinese Big5 (DBCS, OEM, Windows)
+/ 1250 - Central Europe (Windows)
+/ 1251 - Cyrillic (Windows)
+/ 1252 - Latin 1 (Windows)
+/ 1253 - Greek (Windows)
+/ 1254 - Turkish (Windows)
+/ 1255 - Hebrew (Windows)
+/ 1256 - Arabic (Windows)
+/ 1257 - Baltic (Windows)
+/ 1258 - Vietnam (OEM, Windows)
+/ 437 - U.S. (OEM)
+/ 720 - Arabic (OEM)
+/ 737 - Greek (OEM)
+/ 775 - Baltic (OEM)
+/ 850 - Multilingual Latin 1 (OEM)
+/ 858 - Multilingual Latin 1 + Euro (OEM)
+/ 852 - Latin 2 (OEM)
+/ 855 - Cyrillic (OEM)
+/ 866 - Russian (OEM)
+/ 857 - Turkish (OEM)
+/ 862 - Hebrew (OEM)
+/ 874 - Thai (OEM, Windows)
+/ 1 - ASCII only (Valid for non LFN cfg.)
+*/
+
+
+#define _USE_LFN 0 /* 0, 1 or 2 */
+#define _MAX_LFN 255 /* Maximum LFN length to handle (12 to 255) */
+/* The _USE_LFN option switches the LFN support.
+/
+/ 0: Disable LFN. _MAX_LFN and _LFN_UNICODE have no effect.
+/ 1: Enable LFN with static working buffer on the bss. NOT REENTRANT.
+/ 2: Enable LFN with dynamic working buffer on the STACK.
+/
+/ The LFN working buffer occupies (_MAX_LFN + 1) * 2 bytes. When enable LFN,
+/ two Unicode handling functions ff_convert() and ff_wtoupper() must be added
+/ to the project. */
+
+
+#define _LFN_UNICODE 0 /* 0 or 1 */
+/* To switch the character code set on FatFs API to Unicode,
+/ enable LFN feature and set _LFN_UNICODE to 1.
+*/
+
+
+#define _FS_RPATH 0 /* 0 or 1 */
+/* When _FS_RPATH is set to 1, relative path feature is enabled and f_chdir,
+/ f_chdrive function are available.
+/ Note that output of the f_readdir fnction is affected by this option. */
+
+
+
+/*---------------------------------------------------------------------------/
+/ Physical Drive Configurations
+/----------------------------------------------------------------------------*/
+
+#define _DRIVES 2
+/* Number of volumes (logical drives) to be used. */
+
+
+#define _MAX_SS 512 /* 512, 1024, 2048 or 4096 */
+/* Maximum sector size to be handled.
+/ Always set 512 for memory card and hard disk but a larger value may be
+/ required for floppy disk (512/1024) and optical disk (512/2048).
+/ When _MAX_SS is larger than 512, GET_SECTOR_SIZE command must be implememted
+/ to the disk_ioctl function. */
+
+
+#define _MULTI_PARTITION 0 /* 0 or 1 */
+/* When _MULTI_PARTITION is set to 0, each volume is bound to the same physical
+/ drive number and can mount only first primaly partition. When it is set to 1,
+/ each volume is tied to the partitions listed in Drives[]. */
+
+
+
+/*---------------------------------------------------------------------------/
+/ System Configurations
+/----------------------------------------------------------------------------*/
+
+#define _WORD_ACCESS 0 /* 0 or 1 */
+
+/* The _WORD_ACCESS option defines which access method is used to the word
+/ data on the FAT volume.
+/
+/ 0: Byte-by-byte access. Always compatible with all platforms.
+/ 1: Word access. Do not choose this unless following condition is met.
+/
+/ When the byte order on the memory is big-endian or address miss-aligned
+/ word access results incorrect behavior, the _WORD_ACCESS must be set to 0.
+/ If it is not the case, the value can also be set to 1 to improve the
+/ performance and code size. */
+
+
+#define _FS_REENTRANT 0 /* 0 or 1 */
+#define _FS_TIMEOUT 1000 /* Timeout period in unit of time ticks */
+#define _SYNC_t HANDLE /* O/S dependent type of sync object. e.g. HANDLE, OS_EVENT*, ID and etc.. */
+/* The _FS_REENTRANT option switches the reentrancy of the FatFs module.
+/
+/ 0: Disable reentrancy. _SYNC_t and _FS_TIMEOUT have no effect.
+/ 1: Enable reentrancy. Also user provided synchronization handlers,
+/ ff_req_grant, ff_rel_grant, ff_del_syncobj and ff_cre_syncobj
+/ function must be added to the project. */
+
+#include "diskio.h"
+#include "ff.h"
+
+#endif // FATFS_CONFIG_H
diff --git a/utility/demo-fw/pc-tools/CreateDemoBin/Makefile b/utility/demo-fw/pc-tools/CreateDemoBin/Makefile
new file mode 100644
index 0000000..786da50
--- /dev/null
+++ b/utility/demo-fw/pc-tools/CreateDemoBin/Makefile
@@ -0,0 +1,69 @@
+# Output directories
+BIN = bin
+OBJ = obj
+
+# Compiler
+CC = g++
+
+# Optimization level
+OPT =
+
+# Flags
+INCLUDES = -I include
+INCLUDES += -I lib/EasyBMP
+INCLUDES += -I lib/regex
+
+CXXFLAGS = $(OPT) -g -Wall
+CXXFLAGS += -D DEBUG_PROPSECTION
+CXXFLAGS += -D DEBUG_DISPSECTION
+CXXFLAGS += -D DEBUG_SLIDESECTION
+CXXFLAGS += -D DEBUG_LINKSECTION
+CXXFLAGS += -D DEBUG_CONVBMPINFO
+CXXFLAGS += -D DEBUG_BEFOREPARSE
+CXXFLAGS += -D DEBUG_AFTERPARSE
+
+# Movie flas
+ifeq ($(MOVIE_MERGE), on)
+CXXFLAGS += -D MOVIE_MERGE_on
+endif
+
+LDFLAGS = $(OPT)
+
+# VPATH to search source
+VPATH += ./src
+VPATH += ./lib/EasyBMP
+
+# Objects
+OBJS += main.o
+OBJS += ScriptParse.o
+OBJS += EasyBMP.o
+OBJS += CreateDemoBin.o
+
+C_OBJECTS = $(addprefix $(OBJ)/, $(OBJS))
+
+LIBS = lib/libregex.a
+
+# Source code
+
+# Output target
+ifeq ($(MOVIE_MERGE), on)
+TARGET = CreateMovieBin.exe
+else
+TARGET = CreateDemoBin.exe
+endif
+
+# Make target
+.PHONY: all
+all: $(BIN) $(OBJ) $(TARGET)
+
+$(BIN) $(OBJ):
+ mkdir $@
+
+$(OBJS): %.o: %.cpp
+ $(CC) -c $(CXXFLAGS) $(INCLUDES) $< -o $(OBJ)/$@
+
+$(TARGET): $(OBJS)
+ $(CC) $(LDFLAGS) -o $(BIN)/$(TARGET) $(C_OBJECTS) $(LIBS)
+
+clean:
+ -rm -f $(OBJ)/*.o $(BIN)/$(TARGET)
diff --git a/utility/demo-fw/pc-tools/CreateDemoBin/Module1.bas b/utility/demo-fw/pc-tools/CreateDemoBin/Module1.bas
new file mode 100644
index 0000000..4d0fece
--- /dev/null
+++ b/utility/demo-fw/pc-tools/CreateDemoBin/Module1.bas
@@ -0,0 +1,350 @@
+Attribute VB_Name = "Module1"
+Sub ExportPPTInfo()
+
+Dim DataTextStr As String
+Dim SrcPpt As Application
+Dim BaseObj As Object
+Dim OutputText As String
+Dim pShape As Shape
+Dim pTextRange As TextRange
+Dim pActionSetting As ActionSetting
+Dim pSlide As Slide
+Dim pTextFrame As TextFrame
+Dim flag As Integer
+Dim CurType As Integer
+Dim SlideNo As Integer
+Dim HyperlinkNo As Integer
+Dim intOutFile As Integer
+Dim Addr As String
+Dim Filename As String
+Dim Index As Integer
+Dim stringLen As Integer
+Dim Pos As Integer
+Dim Notes As String
+Dim defaulttxt, Options, WSH, inputtext, NameNoExt
+
+ flag = 0
+ CurType = 0
+ SlideNo = 1
+ HyperlinkNo = 1
+
+
+ Set SrcPpt = Application
+ For Each SlideItem In SrcPpt.ActivePresentation.Slides
+ OutputText = OutputText + "Slide" + Str(SlideNo) + ":" + Chr$(13) & Chr$(10)
+ OutputText = OutputText + "Slide Size:" + Chr$(13) & Chr$(10)
+ OutputText = OutputText + "Width: " + Str(SlideItem.Master.Width) + Chr$(13) & Chr$(10) + "Height: " + Str(SlideItem.Master.Height) + Chr$(13) & Chr$(10) + Chr$(13) & Chr$(10)
+
+' MsgBox SlideItem.NotesPage.Shapes.Placeholders(2).TextFrame.TextRange.Text
+ Notes = SlideItem.NotesPage.Shapes.Placeholders(2).TextFrame.TextRange.Text
+ If Notes <> "" Then
+ OutputText = OutputText + "Properties::" + Chr$(13) & Chr$(10)
+ OutputText = OutputText + Notes + Chr$(13) & Chr$(10) + Chr$(13) & Chr$(10)
+ End If
+
+ SlideNo = SlideNo + 1
+ HyperlinkNo = 0
+ For Each linkitem In SlideItem.Hyperlinks
+ flag = 0
+ Addr = linkitem.Address
+ If Addr = "BoxOnly" Then
+ OutputText = OutputText + "Display Box:" + Chr$(13) & Chr$(10)
+ Else
+ HyperlinkNo = HyperlinkNo + 1
+ OutputText = OutputText + "HyperLink" + Str(HyperlinkNo) + "::" + Chr$(13) & Chr$(10)
+ OutputText = OutputText + Chr$(34) + "Link Address" + Chr$(34) + ": " + Addr + Chr$(13) & Chr$(10)
+ End If
+
+ If (TypeName(linkitem.Parent) = "Shape" Or TypeName(linkitem.Parent) = "TextRange") Then
+ flag = 1
+ If TypeName(linkitem.Parent) = "Shape" Then
+ Set pShape = linkitem.Parent
+ OutputText = OutputText + "Top: " + Str(pShape.Top) + Chr$(13) & Chr$(10) + "Left: " + Str(pShape.Left) + Chr$(13) & Chr$(10) + "Width: " + Str(pShape.Width) + Chr$(13) & Chr$(10) + "Height: " + Str(pShape.Height) + Chr$(13) & Chr$(10)
+' MsgBox Str(pShape.Left) + " " + Str(pShape.Top)
+ Else
+ Set pTextRange = linkitem.Parent
+ OutputText = OutputText + "Top: " + Str(pTextRange.BoundTop) + Chr$(13) & Chr$(10) + "Left: " + Str(pTextRange.BoundLeft) + Chr$(13) & Chr$(10) + "Width: " + Str(pTextRange.BoundWidth) + Chr$(13) & Chr$(10) + "Height: " + Str(pTextRange.BoundHeight) + Chr$(13) & Chr$(10)
+' MsgBox Str(pTextRange.BoundLeft) + " " + Str(pTextRange.BoundTop)
+ End If
+ Else
+ Select Case TypeName(linkitem.Parent)
+
+ Case "ActionSetting"
+ Set pActionSetting = linkitem.Parent
+ CurType = 3
+ Case "Slide"
+ Set pSlide = linkitem.Parent
+ CurType = 4
+
+ Case "TextFrame"
+ Set pTextFrame = linkitem.Parent
+ CurType = 5
+
+ End Select
+
+ End If
+ While Not (flag = 1)
+ Select Case CurType
+ Case 3
+ If (TypeName(pActionSetting.Parent) = "Shape" Or TypeName(pActionSetting.Parent) = "TextRange") Then
+ flag = 1
+ If TypeName(pActionSetting.Parent) = "Shape" Then
+ Set pShape = pActionSetting.Parent
+ OutputText = OutputText + "Top: " + Str(pShape.Top) + Chr$(13) & Chr$(10) + "Left: " + Str(pShape.Left) + Chr$(13) & Chr$(10) + "Width: " + Str(pShape.Width) + Chr$(13) & Chr$(10) + "Height: " + Str(pShape.Height) + Chr$(13) & Chr$(10)
+ ' MsgBox Str(pShape.Left) + " " + Str(pShape.Top)
+ Else
+ Set pTextRange = pActionSetting.Parent
+ OutputText = OutputText + "Top: " + Str(pTextRange.BoundTop) + Chr$(13) & Chr$(10) + "Left: " + Str(pTextRange.BoundLeft) + Chr$(13) & Chr$(10) + "Width: " + Str(pTextRange.BoundWidth) + Chr$(13) & Chr$(10) + "Height: " + Str(pTextRange.BoundHeight) + Chr$(13) & Chr$(10)
+ ' MsgBox Str(pTextRange.BoundLeft) + " " + Str(pTextRange.BoundTop)
+ End If
+ Else
+ Select Case TypeName(pActionSetting.Parent)
+ Case "ActionSetting"
+ Set pActionSetting = pActionSetting.Parent
+ CurType = 3
+ Case "Slide"
+ Set pSlide = pActionSetting.Parent
+ CurType = 4
+ Case "TextFrame"
+ Set pTextFrame = pActionSetting.Parent
+ CurType = 5
+ End Select
+
+ End If
+ Case 4
+ If (TypeName(pSlide.Parent) = "Shape" Or TypeName(pSlide.Parent) = "TextRange") Then
+ flag = 1
+ If TypeName(pSlide.Parent) = "Shape" Then
+ Set pShape = pSlide.Parent
+ OutputText = OutputText + "Top: " + Str(pShape.Top) + Chr$(13) & Chr$(10) + "Left: " + Str(pShape.Left) + Chr$(13) & Chr$(10) + "Width: " + Str(pShape.Width) + Chr$(13) & Chr$(10) + "Height: " + Str(pShape.Height) + Chr$(13) & Chr$(10)
+ ' MsgBox Str(pShape.Left) + " " + Str(pShape.Top)
+ Else
+ Set pTextRange = pSlide.Parent
+ OutputText = OutputText + "Top: " + Str(pTextRange.BoundTop) + Chr$(13) & Chr$(10) + "Left: " + Str(pTextRange.BoundLeft) + Chr$(13) & Chr$(10) + "Width: " + Str(pTextRange.BoundWidth) + Chr$(13) & Chr$(10) + "Height: " + Str(pTextRange.BoundHeight) + Chr$(13) & Chr$(10)
+ ' MsgBox Str(pTextRange.BoundLeft) + " " + Str(pTextRange.BoundTop)
+ End If
+ Else
+ Select Case TypeName(pSlide.Parent)
+ Case "ActionSetting"
+ Set pActionSetting = pSlide.Parent
+ CurType = 3
+ Case "Slide"
+ Set pSlide = pSlide.Parent
+ CurType = 4
+ Case "TextFrame"
+ Set pTextFrame = pSlide.Parent
+ CurType = 5
+ End Select
+
+ End If
+ Case 5
+ If (TypeName(pTextFrame.Parent) = "Shape" Or TypeName(pTextFrame.Parent) = "TextRange") Then
+ flag = 1
+ If TypeName(pTextFrame.Parent) = "Shape" Then
+ Set pShape = pTextFrame.Parent
+ OutputText = OutputText + "Top: " + Str(pShape.Top) + Chr$(13) & Chr$(10) + "Left: " + Str(pShape.Left) + Chr$(13) & Chr$(10) + "Width: " + Str(pShape.Width) + Chr$(13) & Chr$(10) + "Height: " + Str(pShape.Height) + Chr$(13) & Chr$(10)
+ ' MsgBox Str(pShape.Left) + " " + Str(pShape.Top)
+ Else
+ Set pTextRange = pTextFrame.Parent
+ OutputText = OutputText + "Top: " + Str(pTextRange.BoundTop) + Chr$(13) & Chr$(10) + "Left: " + Str(pTextRange.BoundLeft) + Chr$(13) & Chr$(10) + "Width: " + Str(pTextRange.BoundWidth) + Chr$(13) & Chr$(10) + "Height: " + Str(pTextRange.BoundHeight) + Chr$(13) & Chr$(10)
+ ' MsgBox Str(pTextRange.BoundLeft) + " " + Str(pTextRange.BoundTop)
+ End If
+ Else
+ Select Case TypeName(pTextFrame.Parent)
+ Case "ActionSetting"
+ Set pActionSetting = pTextFrame.Parent
+ CurType = 3
+ Case "Slide"
+ Set pSlide = pTextFrame.Parent
+ CurType = 4
+ Case "TextFrame"
+ Set pTextFrame = pTextFrame.Parent
+ CurType = 5
+ End Select
+
+ End If
+ End Select
+ Wend
+
+
+ OutputText = OutputText + Chr$(13) & Chr$(10)
+ Next
+
+ For Each linkitem In SlideItem.Master.Hyperlinks
+ flag = 0
+ Addr = linkitem.Address
+ If Addr = "BoxOnly" Then
+ OutputText = OutputText + "Display Box:" + Chr$(13) & Chr$(10)
+ Else
+ HyperlinkNo = HyperlinkNo + 1
+ OutputText = OutputText + "HyperLink" + Str(HyperlinkNo) + "::" + Chr$(13) & Chr$(10)
+ OutputText = OutputText + Chr$(34) + "Link Address" + Chr$(34) + ": " + Addr + Chr$(13) & Chr$(10)
+ End If
+
+ If (TypeName(linkitem.Parent) = "Shape" Or TypeName(linkitem.Parent) = "TextRange") Then
+ flag = 1
+ If TypeName(linkitem.Parent) = "Shape" Then
+ Set pShape = linkitem.Parent
+ OutputText = OutputText + "Top: " + Str(pShape.Top) + Chr$(13) & Chr$(10) + "Left: " + Str(pShape.Left) + Chr$(13) & Chr$(10) + "Width: " + Str(pShape.Width) + Chr$(13) & Chr$(10) + "Height: " + Str(pShape.Height) + Chr$(13) & Chr$(10)
+' MsgBox Str(pShape.Left) + " " + Str(pShape.Top)
+ Else
+ Set pTextRange = linkitem.Parent
+ OutputText = OutputText + "Top: " + Str(pTextRange.BoundTop) + Chr$(13) & Chr$(10) + "Left: " + Str(pTextRange.BoundLeft) + Chr$(13) & Chr$(10) + "Width: " + Str(pTextRange.BoundWidth) + Chr$(13) & Chr$(10) + "Height: " + Str(pTextRange.BoundHeight) + Chr$(13) & Chr$(10)
+' MsgBox Str(pTextRange.BoundLeft) + " " + Str(pTextRange.BoundTop)
+ End If
+ Else
+ Select Case TypeName(linkitem.Parent)
+
+ Case "ActionSetting"
+ Set pActionSetting = linkitem.Parent
+ CurType = 3
+ Case "Slide"
+ Set pSlide = linkitem.Parent
+ CurType = 4
+
+ Case "TextFrame"
+ Set pTextFrame = linkitem.Parent
+ CurType = 5
+
+ End Select
+
+ End If
+ While Not (flag = 1)
+ Select Case CurType
+ Case 3
+ If (TypeName(pActionSetting.Parent) = "Shape" Or TypeName(pActionSetting.Parent) = "TextRange") Then
+ flag = 1
+ If TypeName(pActionSetting.Parent) = "Shape" Then
+ Set pShape = pActionSetting.Parent
+ OutputText = OutputText + "Top: " + Str(pShape.Top) + Chr$(13) & Chr$(10) + "Left: " + Str(pShape.Left) + Chr$(13) & Chr$(10) + "Width: " + Str(pShape.Width) + Chr$(13) & Chr$(10) + "Height: " + Str(pShape.Height) + Chr$(13) & Chr$(10)
+ ' MsgBox Str(pShape.Left) + " " + Str(pShape.Top)
+ Else
+ Set pTextRange = pActionSetting.Parent
+ OutputText = OutputText + "Top: " + Str(pTextRange.BoundTop) + Chr$(13) & Chr$(10) + "Left: " + Str(pTextRange.BoundLeft) + Chr$(13) & Chr$(10) + "Width: " + Str(pTextRange.BoundWidth) + Chr$(13) & Chr$(10) + "Height: " + Str(pTextRange.BoundHeight) + Chr$(13) & Chr$(10)
+ ' MsgBox Str(pTextRange.BoundLeft) + " " + Str(pTextRange.BoundTop)
+ End If
+ Else
+ Select Case TypeName(pActionSetting.Parent)
+ Case "ActionSetting"
+ Set pActionSetting = pActionSetting.Parent
+ CurType = 3
+ Case "Slide"
+ Set pSlide = pActionSetting.Parent
+ CurType = 4
+ Case "TextFrame"
+ Set pTextFrame = pActionSetting.Parent
+ CurType = 5
+ End Select
+
+ End If
+ Case 4
+ If (TypeName(pSlide.Parent) = "Shape" Or TypeName(pSlide.Parent) = "TextRange") Then
+ flag = 1
+ If TypeName(pSlide.Parent) = "Shape" Then
+ Set pShape = pSlide.Parent
+ OutputText = OutputText + "Top: " + Str(pShape.Top) + Chr$(13) & Chr$(10) + "Left: " + Str(pShape.Left) + Chr$(13) & Chr$(10) + "Width: " + Str(pShape.Width) + Chr$(13) & Chr$(10) + "Height: " + Str(pShape.Height) + Chr$(13) & Chr$(10)
+ ' MsgBox Str(pShape.Left) + " " + Str(pShape.Top)
+ Else
+ Set pTextRange = pSlide.Parent
+ OutputText = OutputText + "Top: " + Str(pTextRange.BoundTop) + Chr$(13) & Chr$(10) + "Left: " + Str(pTextRange.BoundLeft) + Chr$(13) & Chr$(10) + "Width: " + Str(pTextRange.BoundWidth) + Chr$(13) & Chr$(10) + "Height: " + Str(pTextRange.BoundHeight) + Chr$(13) & Chr$(10)
+ ' MsgBox Str(pTextRange.BoundLeft) + " " + Str(pTextRange.BoundTop)
+ End If
+ Else
+ Select Case TypeName(pSlide.Parent)
+ Case "ActionSetting"
+ Set pActionSetting = pSlide.Parent
+ CurType = 3
+ Case "Slide"
+ Set pSlide = pSlide.Parent
+ CurType = 4
+ Case "TextFrame"
+ Set pTextFrame = pSlide.Parent
+ CurType = 5
+ End Select
+
+ End If
+ Case 5
+ If (TypeName(pTextFrame.Parent) = "Shape" Or TypeName(pTextFrame.Parent) = "TextRange") Then
+ flag = 1
+ If TypeName(pTextFrame.Parent) = "Shape" Then
+ Set pShape = pTextFrame.Parent
+ OutputText = OutputText + "Top: " + Str(pShape.Top) + Chr$(13) & Chr$(10) + "Left: " + Str(pShape.Left) + Chr$(13) & Chr$(10) + "Width: " + Str(pShape.Width) + Chr$(13) & Chr$(10) + "Height: " + Str(pShape.Height) + Chr$(13) & Chr$(10)
+ ' MsgBox Str(pShape.Left) + " " + Str(pShape.Top)
+ Else
+ Set pTextRange = pTextFrame.Parent
+ OutputText = OutputText + "Top: " + Str(pTextRange.BoundTop) + Chr$(13) & Chr$(10) + "Left: " + Str(pTextRange.BoundLeft) + Chr$(13) & Chr$(10) + "Width: " + Str(pTextRange.BoundWidth) + Chr$(13) & Chr$(10) + "Height: " + Str(pTextRange.BoundHeight) + Chr$(13) & Chr$(10)
+ ' MsgBox Str(pTextRange.BoundLeft) + " " + Str(pTextRange.BoundTop)
+ End If
+ Else
+ Select Case TypeName(pTextFrame.Parent)
+ Case "ActionSetting"
+ Set pActionSetting = pTextFrame.Parent
+ CurType = 3
+ Case "Slide"
+ Set pSlide = pTextFrame.Parent
+ CurType = 4
+ Case "TextFrame"
+ Set pTextFrame = pTextFrame.Parent
+ CurType = 5
+ End Select
+
+ End If
+ End Select
+ Wend
+
+
+ OutputText = OutputText + Chr$(13) & Chr$(10)
+ Next
+ OutputText = OutputText + Chr$(13) & Chr$(10) + Chr$(13) & Chr$(10)
+ Next
+
+ stringLen = Len(SrcPpt.ActivePresentation.Name)
+ For Index = 1 To stringLen
+ If Mid(SrcPpt.ActivePresentation.Name, Index, 1) = "." Then
+ Pos = Index
+ End If
+ Next
+
+ Filename = Left(SrcPpt.ActivePresentation.Name, Pos - 1) + ".txt"
+ NameNoExt = Left(SrcPpt.ActivePresentation.Name, Pos - 1)
+
+ Open Filename For Output As #1
+ Print #1, OutputText
+ Close #1
+
+' Save as PNG files
+With Application.ActivePresentation
+ '.SaveAs SrcPpt.ActivePresentation.Name, ppSaveAsBMP
+ .Export SrcPpt.ActivePresentation.Name, "BMP", 320, 240
+End With
+
+Set WSH = CreateObject("WSCRIPT.SHELL")
+
+defaulttxt = "-profile at91sam3u-ek"
+
+inputtext = "Use following format:" + Chr$(13) & Chr$(10) + " -profile <EK-board-name>, default profiles" + Chr$(13) & Chr$(10) + "Or" + Chr$(13) & Chr$(10) + " -bitdepth xx -width xxx -height xxx -rotate xxx [-noreversebitorder]"
+
+Do
+
+Options = InputBox(inputtext, "Input convert param:", defaulttxt)
+
+If Len(Options) = 0 Then
+Exit Do
+
+Else
+
+inputtext = "../bin/CreateDemoBin.exe " + Options + " " + NameNoExt
+
+WSH.POPUP (inputtext)
+
+WSH.Run (inputtext)
+
+
+Exit Do
+
+End If
+
+Loop
+
+End Sub
+
diff --git a/utility/demo-fw/pc-tools/CreateDemoBin/PPT/CreateDemoBinH.bat b/utility/demo-fw/pc-tools/CreateDemoBin/PPT/CreateDemoBinH.bat
new file mode 100644
index 0000000..7c6f358
--- /dev/null
+++ b/utility/demo-fw/pc-tools/CreateDemoBin/PPT/CreateDemoBinH.bat
@@ -0,0 +1,2 @@
+..\bin\CreateDemoBin -width 320 -height 240 -bitdepth 16 -rotate 270 Sam3DEMO
+pause \ No newline at end of file
diff --git a/utility/demo-fw/pc-tools/CreateDemoBin/PPT/CreateDemoBinIFlash.bat b/utility/demo-fw/pc-tools/CreateDemoBin/PPT/CreateDemoBinIFlash.bat
new file mode 100644
index 0000000..265c8ed
--- /dev/null
+++ b/utility/demo-fw/pc-tools/CreateDemoBin/PPT/CreateDemoBinIFlash.bat
@@ -0,0 +1,2 @@
+..\bin\CreateDemoBin -width 320 -height 240 -bitdepth 8 -rotate 270 -noreversebitmaporder DEMOBINFLASH1
+pause \ No newline at end of file
diff --git a/utility/demo-fw/pc-tools/CreateDemoBin/PPT/CreatelDemoBinV.bat b/utility/demo-fw/pc-tools/CreateDemoBin/PPT/CreatelDemoBinV.bat
new file mode 100644
index 0000000..7171642
--- /dev/null
+++ b/utility/demo-fw/pc-tools/CreateDemoBin/PPT/CreatelDemoBinV.bat
@@ -0,0 +1,2 @@
+..\bin\CreateDemoBin -width 240 -height 320 -bitdepth 16 -rotate 0 -ssPageNumber 17 --ssWidth 320 -ssHeight 240 -ssBitdepth 16 -ssRotate 270 SamDEMOV
+pause \ No newline at end of file
diff --git a/utility/demo-fw/pc-tools/CreateDemoBin/PPT/DEMOBINFLASH1.bin b/utility/demo-fw/pc-tools/CreateDemoBin/PPT/DEMOBINFLASH1.bin
new file mode 100644
index 0000000..c9edee5
--- /dev/null
+++ b/utility/demo-fw/pc-tools/CreateDemoBin/PPT/DEMOBINFLASH1.bin
Binary files differ
diff --git a/utility/demo-fw/pc-tools/CreateDemoBin/PPT/DEMOBINFLASH1.ppt b/utility/demo-fw/pc-tools/CreateDemoBin/PPT/DEMOBINFLASH1.ppt
new file mode 100644
index 0000000..22c843a
--- /dev/null
+++ b/utility/demo-fw/pc-tools/CreateDemoBin/PPT/DEMOBINFLASH1.ppt
Binary files differ
diff --git a/utility/demo-fw/pc-tools/CreateDemoBin/PPT/Module1.bas b/utility/demo-fw/pc-tools/CreateDemoBin/PPT/Module1.bas
new file mode 100644
index 0000000..4d0fece
--- /dev/null
+++ b/utility/demo-fw/pc-tools/CreateDemoBin/PPT/Module1.bas
@@ -0,0 +1,350 @@
+Attribute VB_Name = "Module1"
+Sub ExportPPTInfo()
+
+Dim DataTextStr As String
+Dim SrcPpt As Application
+Dim BaseObj As Object
+Dim OutputText As String
+Dim pShape As Shape
+Dim pTextRange As TextRange
+Dim pActionSetting As ActionSetting
+Dim pSlide As Slide
+Dim pTextFrame As TextFrame
+Dim flag As Integer
+Dim CurType As Integer
+Dim SlideNo As Integer
+Dim HyperlinkNo As Integer
+Dim intOutFile As Integer
+Dim Addr As String
+Dim Filename As String
+Dim Index As Integer
+Dim stringLen As Integer
+Dim Pos As Integer
+Dim Notes As String
+Dim defaulttxt, Options, WSH, inputtext, NameNoExt
+
+ flag = 0
+ CurType = 0
+ SlideNo = 1
+ HyperlinkNo = 1
+
+
+ Set SrcPpt = Application
+ For Each SlideItem In SrcPpt.ActivePresentation.Slides
+ OutputText = OutputText + "Slide" + Str(SlideNo) + ":" + Chr$(13) & Chr$(10)
+ OutputText = OutputText + "Slide Size:" + Chr$(13) & Chr$(10)
+ OutputText = OutputText + "Width: " + Str(SlideItem.Master.Width) + Chr$(13) & Chr$(10) + "Height: " + Str(SlideItem.Master.Height) + Chr$(13) & Chr$(10) + Chr$(13) & Chr$(10)
+
+' MsgBox SlideItem.NotesPage.Shapes.Placeholders(2).TextFrame.TextRange.Text
+ Notes = SlideItem.NotesPage.Shapes.Placeholders(2).TextFrame.TextRange.Text
+ If Notes <> "" Then
+ OutputText = OutputText + "Properties::" + Chr$(13) & Chr$(10)
+ OutputText = OutputText + Notes + Chr$(13) & Chr$(10) + Chr$(13) & Chr$(10)
+ End If
+
+ SlideNo = SlideNo + 1
+ HyperlinkNo = 0
+ For Each linkitem In SlideItem.Hyperlinks
+ flag = 0
+ Addr = linkitem.Address
+ If Addr = "BoxOnly" Then
+ OutputText = OutputText + "Display Box:" + Chr$(13) & Chr$(10)
+ Else
+ HyperlinkNo = HyperlinkNo + 1
+ OutputText = OutputText + "HyperLink" + Str(HyperlinkNo) + "::" + Chr$(13) & Chr$(10)
+ OutputText = OutputText + Chr$(34) + "Link Address" + Chr$(34) + ": " + Addr + Chr$(13) & Chr$(10)
+ End If
+
+ If (TypeName(linkitem.Parent) = "Shape" Or TypeName(linkitem.Parent) = "TextRange") Then
+ flag = 1
+ If TypeName(linkitem.Parent) = "Shape" Then
+ Set pShape = linkitem.Parent
+ OutputText = OutputText + "Top: " + Str(pShape.Top) + Chr$(13) & Chr$(10) + "Left: " + Str(pShape.Left) + Chr$(13) & Chr$(10) + "Width: " + Str(pShape.Width) + Chr$(13) & Chr$(10) + "Height: " + Str(pShape.Height) + Chr$(13) & Chr$(10)
+' MsgBox Str(pShape.Left) + " " + Str(pShape.Top)
+ Else
+ Set pTextRange = linkitem.Parent
+ OutputText = OutputText + "Top: " + Str(pTextRange.BoundTop) + Chr$(13) & Chr$(10) + "Left: " + Str(pTextRange.BoundLeft) + Chr$(13) & Chr$(10) + "Width: " + Str(pTextRange.BoundWidth) + Chr$(13) & Chr$(10) + "Height: " + Str(pTextRange.BoundHeight) + Chr$(13) & Chr$(10)
+' MsgBox Str(pTextRange.BoundLeft) + " " + Str(pTextRange.BoundTop)
+ End If
+ Else
+ Select Case TypeName(linkitem.Parent)
+
+ Case "ActionSetting"
+ Set pActionSetting = linkitem.Parent
+ CurType = 3
+ Case "Slide"
+ Set pSlide = linkitem.Parent
+ CurType = 4
+
+ Case "TextFrame"
+ Set pTextFrame = linkitem.Parent
+ CurType = 5
+
+ End Select
+
+ End If
+ While Not (flag = 1)
+ Select Case CurType
+ Case 3
+ If (TypeName(pActionSetting.Parent) = "Shape" Or TypeName(pActionSetting.Parent) = "TextRange") Then
+ flag = 1
+ If TypeName(pActionSetting.Parent) = "Shape" Then
+ Set pShape = pActionSetting.Parent
+ OutputText = OutputText + "Top: " + Str(pShape.Top) + Chr$(13) & Chr$(10) + "Left: " + Str(pShape.Left) + Chr$(13) & Chr$(10) + "Width: " + Str(pShape.Width) + Chr$(13) & Chr$(10) + "Height: " + Str(pShape.Height) + Chr$(13) & Chr$(10)
+ ' MsgBox Str(pShape.Left) + " " + Str(pShape.Top)
+ Else
+ Set pTextRange = pActionSetting.Parent
+ OutputText = OutputText + "Top: " + Str(pTextRange.BoundTop) + Chr$(13) & Chr$(10) + "Left: " + Str(pTextRange.BoundLeft) + Chr$(13) & Chr$(10) + "Width: " + Str(pTextRange.BoundWidth) + Chr$(13) & Chr$(10) + "Height: " + Str(pTextRange.BoundHeight) + Chr$(13) & Chr$(10)
+ ' MsgBox Str(pTextRange.BoundLeft) + " " + Str(pTextRange.BoundTop)
+ End If
+ Else
+ Select Case TypeName(pActionSetting.Parent)
+ Case "ActionSetting"
+ Set pActionSetting = pActionSetting.Parent
+ CurType = 3
+ Case "Slide"
+ Set pSlide = pActionSetting.Parent
+ CurType = 4
+ Case "TextFrame"
+ Set pTextFrame = pActionSetting.Parent
+ CurType = 5
+ End Select
+
+ End If
+ Case 4
+ If (TypeName(pSlide.Parent) = "Shape" Or TypeName(pSlide.Parent) = "TextRange") Then
+ flag = 1
+ If TypeName(pSlide.Parent) = "Shape" Then
+ Set pShape = pSlide.Parent
+ OutputText = OutputText + "Top: " + Str(pShape.Top) + Chr$(13) & Chr$(10) + "Left: " + Str(pShape.Left) + Chr$(13) & Chr$(10) + "Width: " + Str(pShape.Width) + Chr$(13) & Chr$(10) + "Height: " + Str(pShape.Height) + Chr$(13) & Chr$(10)
+ ' MsgBox Str(pShape.Left) + " " + Str(pShape.Top)
+ Else
+ Set pTextRange = pSlide.Parent
+ OutputText = OutputText + "Top: " + Str(pTextRange.BoundTop) + Chr$(13) & Chr$(10) + "Left: " + Str(pTextRange.BoundLeft) + Chr$(13) & Chr$(10) + "Width: " + Str(pTextRange.BoundWidth) + Chr$(13) & Chr$(10) + "Height: " + Str(pTextRange.BoundHeight) + Chr$(13) & Chr$(10)
+ ' MsgBox Str(pTextRange.BoundLeft) + " " + Str(pTextRange.BoundTop)
+ End If
+ Else
+ Select Case TypeName(pSlide.Parent)
+ Case "ActionSetting"
+ Set pActionSetting = pSlide.Parent
+ CurType = 3
+ Case "Slide"
+ Set pSlide = pSlide.Parent
+ CurType = 4
+ Case "TextFrame"
+ Set pTextFrame = pSlide.Parent
+ CurType = 5
+ End Select
+
+ End If
+ Case 5
+ If (TypeName(pTextFrame.Parent) = "Shape" Or TypeName(pTextFrame.Parent) = "TextRange") Then
+ flag = 1
+ If TypeName(pTextFrame.Parent) = "Shape" Then
+ Set pShape = pTextFrame.Parent
+ OutputText = OutputText + "Top: " + Str(pShape.Top) + Chr$(13) & Chr$(10) + "Left: " + Str(pShape.Left) + Chr$(13) & Chr$(10) + "Width: " + Str(pShape.Width) + Chr$(13) & Chr$(10) + "Height: " + Str(pShape.Height) + Chr$(13) & Chr$(10)
+ ' MsgBox Str(pShape.Left) + " " + Str(pShape.Top)
+ Else
+ Set pTextRange = pTextFrame.Parent
+ OutputText = OutputText + "Top: " + Str(pTextRange.BoundTop) + Chr$(13) & Chr$(10) + "Left: " + Str(pTextRange.BoundLeft) + Chr$(13) & Chr$(10) + "Width: " + Str(pTextRange.BoundWidth) + Chr$(13) & Chr$(10) + "Height: " + Str(pTextRange.BoundHeight) + Chr$(13) & Chr$(10)
+ ' MsgBox Str(pTextRange.BoundLeft) + " " + Str(pTextRange.BoundTop)
+ End If
+ Else
+ Select Case TypeName(pTextFrame.Parent)
+ Case "ActionSetting"
+ Set pActionSetting = pTextFrame.Parent
+ CurType = 3
+ Case "Slide"
+ Set pSlide = pTextFrame.Parent
+ CurType = 4
+ Case "TextFrame"
+ Set pTextFrame = pTextFrame.Parent
+ CurType = 5
+ End Select
+
+ End If
+ End Select
+ Wend
+
+
+ OutputText = OutputText + Chr$(13) & Chr$(10)
+ Next
+
+ For Each linkitem In SlideItem.Master.Hyperlinks
+ flag = 0
+ Addr = linkitem.Address
+ If Addr = "BoxOnly" Then
+ OutputText = OutputText + "Display Box:" + Chr$(13) & Chr$(10)
+ Else
+ HyperlinkNo = HyperlinkNo + 1
+ OutputText = OutputText + "HyperLink" + Str(HyperlinkNo) + "::" + Chr$(13) & Chr$(10)
+ OutputText = OutputText + Chr$(34) + "Link Address" + Chr$(34) + ": " + Addr + Chr$(13) & Chr$(10)
+ End If
+
+ If (TypeName(linkitem.Parent) = "Shape" Or TypeName(linkitem.Parent) = "TextRange") Then
+ flag = 1
+ If TypeName(linkitem.Parent) = "Shape" Then
+ Set pShape = linkitem.Parent
+ OutputText = OutputText + "Top: " + Str(pShape.Top) + Chr$(13) & Chr$(10) + "Left: " + Str(pShape.Left) + Chr$(13) & Chr$(10) + "Width: " + Str(pShape.Width) + Chr$(13) & Chr$(10) + "Height: " + Str(pShape.Height) + Chr$(13) & Chr$(10)
+' MsgBox Str(pShape.Left) + " " + Str(pShape.Top)
+ Else
+ Set pTextRange = linkitem.Parent
+ OutputText = OutputText + "Top: " + Str(pTextRange.BoundTop) + Chr$(13) & Chr$(10) + "Left: " + Str(pTextRange.BoundLeft) + Chr$(13) & Chr$(10) + "Width: " + Str(pTextRange.BoundWidth) + Chr$(13) & Chr$(10) + "Height: " + Str(pTextRange.BoundHeight) + Chr$(13) & Chr$(10)
+' MsgBox Str(pTextRange.BoundLeft) + " " + Str(pTextRange.BoundTop)
+ End If
+ Else
+ Select Case TypeName(linkitem.Parent)
+
+ Case "ActionSetting"
+ Set pActionSetting = linkitem.Parent
+ CurType = 3
+ Case "Slide"
+ Set pSlide = linkitem.Parent
+ CurType = 4
+
+ Case "TextFrame"
+ Set pTextFrame = linkitem.Parent
+ CurType = 5
+
+ End Select
+
+ End If
+ While Not (flag = 1)
+ Select Case CurType
+ Case 3
+ If (TypeName(pActionSetting.Parent) = "Shape" Or TypeName(pActionSetting.Parent) = "TextRange") Then
+ flag = 1
+ If TypeName(pActionSetting.Parent) = "Shape" Then
+ Set pShape = pActionSetting.Parent
+ OutputText = OutputText + "Top: " + Str(pShape.Top) + Chr$(13) & Chr$(10) + "Left: " + Str(pShape.Left) + Chr$(13) & Chr$(10) + "Width: " + Str(pShape.Width) + Chr$(13) & Chr$(10) + "Height: " + Str(pShape.Height) + Chr$(13) & Chr$(10)
+ ' MsgBox Str(pShape.Left) + " " + Str(pShape.Top)
+ Else
+ Set pTextRange = pActionSetting.Parent
+ OutputText = OutputText + "Top: " + Str(pTextRange.BoundTop) + Chr$(13) & Chr$(10) + "Left: " + Str(pTextRange.BoundLeft) + Chr$(13) & Chr$(10) + "Width: " + Str(pTextRange.BoundWidth) + Chr$(13) & Chr$(10) + "Height: " + Str(pTextRange.BoundHeight) + Chr$(13) & Chr$(10)
+ ' MsgBox Str(pTextRange.BoundLeft) + " " + Str(pTextRange.BoundTop)
+ End If
+ Else
+ Select Case TypeName(pActionSetting.Parent)
+ Case "ActionSetting"
+ Set pActionSetting = pActionSetting.Parent
+ CurType = 3
+ Case "Slide"
+ Set pSlide = pActionSetting.Parent
+ CurType = 4
+ Case "TextFrame"
+ Set pTextFrame = pActionSetting.Parent
+ CurType = 5
+ End Select
+
+ End If
+ Case 4
+ If (TypeName(pSlide.Parent) = "Shape" Or TypeName(pSlide.Parent) = "TextRange") Then
+ flag = 1
+ If TypeName(pSlide.Parent) = "Shape" Then
+ Set pShape = pSlide.Parent
+ OutputText = OutputText + "Top: " + Str(pShape.Top) + Chr$(13) & Chr$(10) + "Left: " + Str(pShape.Left) + Chr$(13) & Chr$(10) + "Width: " + Str(pShape.Width) + Chr$(13) & Chr$(10) + "Height: " + Str(pShape.Height) + Chr$(13) & Chr$(10)
+ ' MsgBox Str(pShape.Left) + " " + Str(pShape.Top)
+ Else
+ Set pTextRange = pSlide.Parent
+ OutputText = OutputText + "Top: " + Str(pTextRange.BoundTop) + Chr$(13) & Chr$(10) + "Left: " + Str(pTextRange.BoundLeft) + Chr$(13) & Chr$(10) + "Width: " + Str(pTextRange.BoundWidth) + Chr$(13) & Chr$(10) + "Height: " + Str(pTextRange.BoundHeight) + Chr$(13) & Chr$(10)
+ ' MsgBox Str(pTextRange.BoundLeft) + " " + Str(pTextRange.BoundTop)
+ End If
+ Else
+ Select Case TypeName(pSlide.Parent)
+ Case "ActionSetting"
+ Set pActionSetting = pSlide.Parent
+ CurType = 3
+ Case "Slide"
+ Set pSlide = pSlide.Parent
+ CurType = 4
+ Case "TextFrame"
+ Set pTextFrame = pSlide.Parent
+ CurType = 5
+ End Select
+
+ End If
+ Case 5
+ If (TypeName(pTextFrame.Parent) = "Shape" Or TypeName(pTextFrame.Parent) = "TextRange") Then
+ flag = 1
+ If TypeName(pTextFrame.Parent) = "Shape" Then
+ Set pShape = pTextFrame.Parent
+ OutputText = OutputText + "Top: " + Str(pShape.Top) + Chr$(13) & Chr$(10) + "Left: " + Str(pShape.Left) + Chr$(13) & Chr$(10) + "Width: " + Str(pShape.Width) + Chr$(13) & Chr$(10) + "Height: " + Str(pShape.Height) + Chr$(13) & Chr$(10)
+ ' MsgBox Str(pShape.Left) + " " + Str(pShape.Top)
+ Else
+ Set pTextRange = pTextFrame.Parent
+ OutputText = OutputText + "Top: " + Str(pTextRange.BoundTop) + Chr$(13) & Chr$(10) + "Left: " + Str(pTextRange.BoundLeft) + Chr$(13) & Chr$(10) + "Width: " + Str(pTextRange.BoundWidth) + Chr$(13) & Chr$(10) + "Height: " + Str(pTextRange.BoundHeight) + Chr$(13) & Chr$(10)
+ ' MsgBox Str(pTextRange.BoundLeft) + " " + Str(pTextRange.BoundTop)
+ End If
+ Else
+ Select Case TypeName(pTextFrame.Parent)
+ Case "ActionSetting"
+ Set pActionSetting = pTextFrame.Parent
+ CurType = 3
+ Case "Slide"
+ Set pSlide = pTextFrame.Parent
+ CurType = 4
+ Case "TextFrame"
+ Set pTextFrame = pTextFrame.Parent
+ CurType = 5
+ End Select
+
+ End If
+ End Select
+ Wend
+
+
+ OutputText = OutputText + Chr$(13) & Chr$(10)
+ Next
+ OutputText = OutputText + Chr$(13) & Chr$(10) + Chr$(13) & Chr$(10)
+ Next
+
+ stringLen = Len(SrcPpt.ActivePresentation.Name)
+ For Index = 1 To stringLen
+ If Mid(SrcPpt.ActivePresentation.Name, Index, 1) = "." Then
+ Pos = Index
+ End If
+ Next
+
+ Filename = Left(SrcPpt.ActivePresentation.Name, Pos - 1) + ".txt"
+ NameNoExt = Left(SrcPpt.ActivePresentation.Name, Pos - 1)
+
+ Open Filename For Output As #1
+ Print #1, OutputText
+ Close #1
+
+' Save as PNG files
+With Application.ActivePresentation
+ '.SaveAs SrcPpt.ActivePresentation.Name, ppSaveAsBMP
+ .Export SrcPpt.ActivePresentation.Name, "BMP", 320, 240
+End With
+
+Set WSH = CreateObject("WSCRIPT.SHELL")
+
+defaulttxt = "-profile at91sam3u-ek"
+
+inputtext = "Use following format:" + Chr$(13) & Chr$(10) + " -profile <EK-board-name>, default profiles" + Chr$(13) & Chr$(10) + "Or" + Chr$(13) & Chr$(10) + " -bitdepth xx -width xxx -height xxx -rotate xxx [-noreversebitorder]"
+
+Do
+
+Options = InputBox(inputtext, "Input convert param:", defaulttxt)
+
+If Len(Options) = 0 Then
+Exit Do
+
+Else
+
+inputtext = "../bin/CreateDemoBin.exe " + Options + " " + NameNoExt
+
+WSH.POPUP (inputtext)
+
+WSH.Run (inputtext)
+
+
+Exit Do
+
+End If
+
+Loop
+
+End Sub
+
diff --git a/utility/demo-fw/pc-tools/CreateDemoBin/PPT/SAM3U_MarCom.ppt b/utility/demo-fw/pc-tools/CreateDemoBin/PPT/SAM3U_MarCom.ppt
new file mode 100644
index 0000000..8e9863c
--- /dev/null
+++ b/utility/demo-fw/pc-tools/CreateDemoBin/PPT/SAM3U_MarCom.ppt
Binary files differ
diff --git a/utility/demo-fw/pc-tools/CreateDemoBin/PPT/Sam3DEMO.bin b/utility/demo-fw/pc-tools/CreateDemoBin/PPT/Sam3DEMO.bin
new file mode 100644
index 0000000..9866a3e
--- /dev/null
+++ b/utility/demo-fw/pc-tools/CreateDemoBin/PPT/Sam3DEMO.bin
Binary files differ
diff --git a/utility/demo-fw/pc-tools/CreateDemoBin/PPT/Sam3DEMO.ppt b/utility/demo-fw/pc-tools/CreateDemoBin/PPT/Sam3DEMO.ppt
new file mode 100644
index 0000000..6034f98
--- /dev/null
+++ b/utility/demo-fw/pc-tools/CreateDemoBin/PPT/Sam3DEMO.ppt
Binary files differ
diff --git a/utility/demo-fw/pc-tools/CreateDemoBin/PPT/SamDEMOV.bin b/utility/demo-fw/pc-tools/CreateDemoBin/PPT/SamDEMOV.bin
new file mode 100644
index 0000000..fec7e4c
--- /dev/null
+++ b/utility/demo-fw/pc-tools/CreateDemoBin/PPT/SamDEMOV.bin
Binary files differ
diff --git a/utility/demo-fw/pc-tools/CreateDemoBin/PPT/SamDEMOV.ppt b/utility/demo-fw/pc-tools/CreateDemoBin/PPT/SamDEMOV.ppt
new file mode 100644
index 0000000..612e51f
--- /dev/null
+++ b/utility/demo-fw/pc-tools/CreateDemoBin/PPT/SamDEMOV.ppt
Binary files differ
diff --git a/utility/demo-fw/pc-tools/CreateDemoBin/bin/CreateDemoBin.exe b/utility/demo-fw/pc-tools/CreateDemoBin/bin/CreateDemoBin.exe
new file mode 100644
index 0000000..cb1e084
--- /dev/null
+++ b/utility/demo-fw/pc-tools/CreateDemoBin/bin/CreateDemoBin.exe
Binary files differ
diff --git a/utility/demo-fw/pc-tools/CreateDemoBin/bin/CreateMovieBin.exe b/utility/demo-fw/pc-tools/CreateDemoBin/bin/CreateMovieBin.exe
new file mode 100644
index 0000000..d65906f
--- /dev/null
+++ b/utility/demo-fw/pc-tools/CreateDemoBin/bin/CreateMovieBin.exe
Binary files differ
diff --git a/utility/demo-fw/pc-tools/CreateDemoBin/include/CreateDemoBin.h b/utility/demo-fw/pc-tools/CreateDemoBin/include/CreateDemoBin.h
new file mode 100644
index 0000000..d6d2883
--- /dev/null
+++ b/utility/demo-fw/pc-tools/CreateDemoBin/include/CreateDemoBin.h
@@ -0,0 +1,96 @@
+#ifndef __CREATEDEMOBIN_H
+#define __CREATEDEMOBIN_H
+
+////////////////////////////////////////////////////////////
+//type definition
+///////////////////////////////////////////////////////////
+// BMP (Windows) Header Format
+typedef struct __attribute__ ((packed)) {
+ /// signature, must be 4D42 hex
+ unsigned short type;
+ /// size of BMP file in bytes (unreliable)
+ unsigned int fileSize;
+ /// reserved, must be zero
+ unsigned short reserved1;
+ /// reserved, must be zero
+ unsigned short reserved2;
+ /// offset to start of image data in bytes
+ unsigned int offset;
+ /// size of BITMAPINFOHEADER structure
+ unsigned int headerSize;
+ /// image width in pixels
+ unsigned int width;
+ /// image height in pixels
+ unsigned int height;
+ /// number of planes in the image, must be 1
+ unsigned short planes;
+ /// number of bits per pixel (1, 4, 8, 16, 24, 32)
+ unsigned short bits;
+ /// compression type (0=none, 1=RLE-8, 2=RLE-4)
+ unsigned int compression;
+ /// size of image data in bytes (including padding)
+ unsigned int imageSize;
+ /// horizontal resolution in pixels per meter (unreliable)
+ unsigned int xresolution;
+ /// vertical resolution in pixels per meter (unreliable)
+ unsigned int yresolution;
+ /// number of colors in image, or zero
+ unsigned int ncolours;
+ /// number of important colors, or zero
+ unsigned int importantcolours;
+} BMPHeader;
+
+//option structure for image conversion
+typedef struct _BMPConvOptions {
+ //bitdepth of bmp file stored in demo bin file
+ unsigned int bitdepth;
+ //IMPORTANT NOTES: following width and height means
+ // resized image without any rotation
+ //resized bmp width
+ unsigned int width;
+ //resized bmp height
+ unsigned int height;
+ //anti-clockwise rotate angle
+ unsigned int rotateangle;
+ //reverse bmp bitmap data order
+ //some lcd controller needs to get BMP bitmap data from bottom to top
+ //this is used to indicate conversion
+ unsigned int reversebitmaporder;
+ #if defined(MOVIE_MERGE_on)
+ //slide number for movie binary
+ unsigned int mvSlideNumber;
+ #endif
+ #if defined(SLIDESHOW_MERGE_on)
+ unsigned int ssPageNumber;
+ unsigned int ssBitdepth;
+ unsigned int ssWidth;
+ unsigned int ssHeight;
+ unsigned int ssRotateangle;
+ unsigned int ssReverseBmpOrder;
+ #endif
+} BMPConvOpt;
+
+#define BMP24MAPLEN 320*240*3
+#define BMP16MAPLEN 320*240*2
+
+///////////////////////////////////////////////////////////////////////
+//export functions, steps of creation of atmel demo bin file
+//////////////////////////////////////////////////////////////////////
+
+//Initialize filename variables
+void Step1_CreateFileNameVars(char * name);
+
+//Process ppt information txt file
+bool Step2_ProcessPPTInfoFile(BMPConvOpt *pOption);
+
+//Resize and Rotate slides
+bool Step3_ResizeAndRotateSlideBMP(BMPConvOpt *pOption);
+
+//create demo bin from above variables
+bool Step4_GenerateDemoBin(BMPConvOpt *pOption);
+
+//show generated bin contained bmp information
+void ShowEachBmpHeader();
+
+
+#endif
diff --git a/utility/demo-fw/pc-tools/CreateDemoBin/include/DemoBinHeader.h b/utility/demo-fw/pc-tools/CreateDemoBin/include/DemoBinHeader.h
new file mode 100644
index 0000000..7ad30fa
--- /dev/null
+++ b/utility/demo-fw/pc-tools/CreateDemoBin/include/DemoBinHeader.h
@@ -0,0 +1,82 @@
+/*
+ * AtmlDemobinHeader.h
+ *
+ * Created on: 2009-3-15
+ * Author: Tony.Liu
+ */
+
+#ifndef DEMOBINHEADER_H_
+#define DEMOBINHEADER_H_
+
+#include <string.h>
+
+#define MAXSCRIPTSTRINGLINE 128
+
+#define MAXSLIDESPERBIN 300
+
+#define MAXLINKLEN 50
+
+#define MAX_LINK_PER_SLIDE 10
+
+#define MAX_DISPBOX_PER_SLIDE 4
+
+#define DEMOSLIDEWIDTH 240
+
+#define DEMOSLIDEHEIGHT 320
+
+#define ClearDemoBINHeader(pHead) memset((pHead), 0xFF, sizeof(DemoBINHeader))
+
+#define ClearSlideINFOHeader(pHead) memset((pHead), 0xFF, sizeof(SlideINFOHeader))
+
+/// ATMEL DEMO BIN tag value
+#define ATMLBINTAG 0x4C4D5441
+
+//demo bin file header
+typedef struct {
+ unsigned int tag;//demo bin head,'A','T','M','L'
+ unsigned int filesize;//bin file size
+ unsigned int headersize;//headsize including all SlideINFOHeader fields
+ unsigned int slidecount;//slide numbers
+// PPTINFO pptinfo[MAXSLIDESPERBIN];
+} DemoBINHeader;
+
+typedef struct {
+ //value are converted from slides script. noted BMP anticlockwise rotated 90 degree
+ unsigned int linkboxbottom;
+ unsigned int linkboxleft;
+ unsigned int linkboxwidth;
+ unsigned int linkboxheight;
+ //link string
+ char linkstring[MAXLINKLEN];
+}SlideLinkINFO;
+
+typedef struct {
+ //value are converted from slides script. noted BMP anticlockwise rotated 90 degree
+ unsigned int dispboxbottom;
+ unsigned int dispboxleft;
+ unsigned int dispboxwidth;
+ unsigned int dispboxheight;
+} SlideDispINFO;
+
+typedef struct {
+ //properties for each slide, command string line supported only now.
+ unsigned int propcnt; //numbers of properties
+ char onInitCmds[MAXLINKLEN];
+ char onRefreshCmds[MAXLINKLEN];
+ char onCloseCmds[MAXLINKLEN];
+} SlidePropINFO;
+
+typedef struct {
+ unsigned int slideoffset;
+ unsigned int slidedatalength;
+ unsigned int slidewidth;
+ unsigned int slideheight;
+ unsigned int dispboxcount;//0 means no display box, others mean yes
+ SlideDispINFO dispboxinfo[MAX_DISPBOX_PER_SLIDE];
+ unsigned int linkcount;
+ SlideLinkINFO linkinfo[MAX_LINK_PER_SLIDE];
+ unsigned int propyes;// 0 means no property settings, 1 or others mean yes
+ SlidePropINFO propinfo;
+} SlideINFOHeader;
+
+#endif /* DEMOBINHEADER_H_ */
diff --git a/utility/demo-fw/pc-tools/CreateDemoBin/include/ScriptParse.h b/utility/demo-fw/pc-tools/CreateDemoBin/include/ScriptParse.h
new file mode 100644
index 0000000..05621de
--- /dev/null
+++ b/utility/demo-fw/pc-tools/CreateDemoBin/include/ScriptParse.h
@@ -0,0 +1,103 @@
+/*
+ * ScriptParse.h
+ *
+ * Created on: 2009-3-15
+ * Author: Tony.Liu
+ */
+
+#ifndef SCRIPTPARSE_H_
+#define SCRIPTPARSE_H_
+
+//compile all pattern
+bool CompileAllPtn();
+
+//free all regex objects
+void FreeAllRegex();
+
+//is a space line?
+bool IsSpaceLine(const char *string);
+
+//match slide count line and return the count
+bool GetSlideCount( const char *string, unsigned int *slidenum);
+
+//check slide size line is correct
+bool IsSlideSizeString(const char *string);
+
+//match slide width line and return the width
+bool GetSlideWidth( const char *string, unsigned int *slidewidth);
+
+//match slide height line and return the height
+bool GetSlideHeight( const char *string, unsigned int *slideheight);
+
+//Is Display Box section starting?
+bool IsDispBoxSectionStart(const char *string);
+
+//match link top line and return link top position
+bool GetDispBoxTop(const char *string, unsigned int *top);
+
+//match link left line and return link left position
+bool GetDispBoxLeft(const char *string, unsigned int *left);
+
+//match link width line and return width value
+bool GetDispBoxWidth(const char *string, unsigned int *width);
+
+//match link width line and return width value
+bool GetDispBoxHeight(const char *string, unsigned int *height);
+
+//match hyperlink line and return link count
+bool GetLinkCount(const char *string, unsigned int *linkcnt);
+
+//match link address line and return the address
+bool GetLinkAddr(const char *string, char *link);
+
+//match link top line and return link top position
+bool GetLinkTop(const char *string, unsigned int *top);
+
+//match link left line and return link left position
+bool GetLinkLeft(const char *string, unsigned int *left);
+
+//match link width line and return width value
+bool GetLinkWidth(const char *string, unsigned int *width);
+
+//match link width line and return width value
+bool GetLinkHeight(const char *string, unsigned int *height);
+
+//Parse slide section of script
+//Parse slide section of script
+bool ParseSlideSection(const char *string, \
+ unsigned int *slideindex, \
+ unsigned int *slidewidth, \
+ unsigned int *slideheight);
+
+//Parse hyperlink section of script
+bool ParseLinkSection(const char *string, \
+ unsigned int *linkindex, \
+ char *linkstr, \
+ unsigned int *linktop, \
+ unsigned int *linkleft, \
+ unsigned int *linkwidth, \
+ unsigned int *linkheight);
+
+//Parse display box section of script
+bool ParseDispBoxSection(const char *string, \
+ unsigned int *disptop, \
+ unsigned int *displeft, \
+ unsigned int *dispwidth, \
+ unsigned int *dispheight);
+
+//Parse slide properties section of script
+bool ParsePropertiesSection(const char *string, \
+ char *pOnInitCmds, \
+ char *pOnRefreshCmds, \
+ char *pOnCloseCmds);
+
+//Is slide section starting?
+bool IsSlideSectionStart(const char *string);
+
+//Is hyperlink section starting?
+bool IsLinkSectionStart(const char *string);
+
+//Is slide properties section starting?
+bool IsPropertiesSectionStart(const char *string);
+
+#endif /* SCRIPTPARSE_H_ */
diff --git a/utility/demo-fw/pc-tools/CreateDemoBin/include/profile.h b/utility/demo-fw/pc-tools/CreateDemoBin/include/profile.h
new file mode 100644
index 0000000..65294c9
--- /dev/null
+++ b/utility/demo-fw/pc-tools/CreateDemoBin/include/profile.h
@@ -0,0 +1,22 @@
+/*
+ * profile.h
+ *
+ * Created on: Oct 26, 2009
+ * Author: Tony.Liu
+ */
+
+#ifndef PROFILE_H_
+#define PROFILE_H_
+
+#include "CreateDemoBin.h"
+
+typedef struct {
+ char *pProfileName;
+ BMPConvOpt options;
+} Profile;
+
+static Profile profile[] = {
+ {"at91sam3u-ek", {16, 320, 240, 270, 1}}
+};
+
+#endif /* PROFILE_H_ */
diff --git a/utility/demo-fw/pc-tools/CreateDemoBin/include/regex.h b/utility/demo-fw/pc-tools/CreateDemoBin/include/regex.h
new file mode 100644
index 0000000..2396f78
--- /dev/null
+++ b/utility/demo-fw/pc-tools/CreateDemoBin/include/regex.h
@@ -0,0 +1,556 @@
+/* Definitions for data structures and routines for the regular
+ expression library.
+ Copyright (C) 1985,1989-93,1995-98,2000,2001,2002,2003,2005,2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _REGEX_H
+#define _REGEX_H 1
+
+#include <sys/types.h>
+
+/* Allow the use in C++ code. */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* The following two types have to be signed and unsigned integer type
+ wide enough to hold a value of a pointer. For most ANSI compilers
+ ptrdiff_t and size_t should be likely OK. Still size of these two
+ types is 2 for Microsoft C. Ugh... */
+typedef long int s_reg_t;
+typedef unsigned long int active_reg_t;
+
+/* The following bits are used to determine the regexp syntax we
+ recognize. The set/not-set meanings are chosen so that Emacs syntax
+ remains the value 0. The bits are given in alphabetical order, and
+ the definitions shifted by one from the previous bit; thus, when we
+ add or remove a bit, only one other definition need change. */
+typedef unsigned long int reg_syntax_t;
+
+/* If this bit is not set, then \ inside a bracket expression is literal.
+ If set, then such a \ quotes the following character. */
+#define RE_BACKSLASH_ESCAPE_IN_LISTS ((unsigned long int) 1)
+
+/* If this bit is not set, then + and ? are operators, and \+ and \? are
+ literals.
+ If set, then \+ and \? are operators and + and ? are literals. */
+#define RE_BK_PLUS_QM (RE_BACKSLASH_ESCAPE_IN_LISTS << 1)
+
+/* If this bit is set, then character classes are supported. They are:
+ [:alpha:], [:upper:], [:lower:], [:digit:], [:alnum:], [:xdigit:],
+ [:space:], [:print:], [:punct:], [:graph:], and [:cntrl:].
+ If not set, then character classes are not supported. */
+#define RE_CHAR_CLASSES (RE_BK_PLUS_QM << 1)
+
+/* If this bit is set, then ^ and $ are always anchors (outside bracket
+ expressions, of course).
+ If this bit is not set, then it depends:
+ ^ is an anchor if it is at the beginning of a regular
+ expression or after an open-group or an alternation operator;
+ $ is an anchor if it is at the end of a regular expression, or
+ before a close-group or an alternation operator.
+
+ This bit could be (re)combined with RE_CONTEXT_INDEP_OPS, because
+ POSIX draft 11.2 says that * etc. in leading positions is undefined.
+ We already implemented a previous draft which made those constructs
+ invalid, though, so we haven't changed the code back. */
+#define RE_CONTEXT_INDEP_ANCHORS (RE_CHAR_CLASSES << 1)
+
+/* If this bit is set, then special characters are always special
+ regardless of where they are in the pattern.
+ If this bit is not set, then special characters are special only in
+ some contexts; otherwise they are ordinary. Specifically,
+ * + ? and intervals are only special when not after the beginning,
+ open-group, or alternation operator. */
+#define RE_CONTEXT_INDEP_OPS (RE_CONTEXT_INDEP_ANCHORS << 1)
+
+/* If this bit is set, then *, +, ?, and { cannot be first in an re or
+ immediately after an alternation or begin-group operator. */
+#define RE_CONTEXT_INVALID_OPS (RE_CONTEXT_INDEP_OPS << 1)
+
+/* If this bit is set, then . matches newline.
+ If not set, then it doesn't. */
+#define RE_DOT_NEWLINE (RE_CONTEXT_INVALID_OPS << 1)
+
+/* If this bit is set, then . doesn't match NUL.
+ If not set, then it does. */
+#define RE_DOT_NOT_NULL (RE_DOT_NEWLINE << 1)
+
+/* If this bit is set, nonmatching lists [^...] do not match newline.
+ If not set, they do. */
+#define RE_HAT_LISTS_NOT_NEWLINE (RE_DOT_NOT_NULL << 1)
+
+/* If this bit is set, either \{...\} or {...} defines an
+ interval, depending on RE_NO_BK_BRACES.
+ If not set, \{, \}, {, and } are literals. */
+#define RE_INTERVALS (RE_HAT_LISTS_NOT_NEWLINE << 1)
+
+/* If this bit is set, +, ? and | aren't recognized as operators.
+ If not set, they are. */
+#define RE_LIMITED_OPS (RE_INTERVALS << 1)
+
+/* If this bit is set, newline is an alternation operator.
+ If not set, newline is literal. */
+#define RE_NEWLINE_ALT (RE_LIMITED_OPS << 1)
+
+/* If this bit is set, then `{...}' defines an interval, and \{ and \}
+ are literals.
+ If not set, then `\{...\}' defines an interval. */
+#define RE_NO_BK_BRACES (RE_NEWLINE_ALT << 1)
+
+/* If this bit is set, (...) defines a group, and \( and \) are literals.
+ If not set, \(...\) defines a group, and ( and ) are literals. */
+#define RE_NO_BK_PARENS (RE_NO_BK_BRACES << 1)
+
+/* If this bit is set, then \<digit> matches <digit>.
+ If not set, then \<digit> is a back-reference. */
+#define RE_NO_BK_REFS (RE_NO_BK_PARENS << 1)
+
+/* If this bit is set, then | is an alternation operator, and \| is literal.
+ If not set, then \| is an alternation operator, and | is literal. */
+#define RE_NO_BK_VBAR (RE_NO_BK_REFS << 1)
+
+/* If this bit is set, then an ending range point collating higher
+ than the starting range point, as in [z-a], is invalid.
+ If not set, then when ending range point collates higher than the
+ starting range point, the range is ignored. */
+#define RE_NO_EMPTY_RANGES (RE_NO_BK_VBAR << 1)
+
+/* If this bit is set, then an unmatched ) is ordinary.
+ If not set, then an unmatched ) is invalid. */
+#define RE_UNMATCHED_RIGHT_PAREN_ORD (RE_NO_EMPTY_RANGES << 1)
+
+/* If this bit is set, succeed as soon as we match the whole pattern,
+ without further backtracking. */
+#define RE_NO_POSIX_BACKTRACKING (RE_UNMATCHED_RIGHT_PAREN_ORD << 1)
+
+/* If this bit is set, do not process the GNU regex operators.
+ If not set, then the GNU regex operators are recognized. */
+#define RE_NO_GNU_OPS (RE_NO_POSIX_BACKTRACKING << 1)
+
+/* If this bit is set, turn on internal regex debugging.
+ If not set, and debugging was on, turn it off.
+ This only works if regex.c is compiled -DDEBUG.
+ We define this bit always, so that all that's needed to turn on
+ debugging is to recompile regex.c; the calling code can always have
+ this bit set, and it won't affect anything in the normal case. */
+#define RE_DEBUG (RE_NO_GNU_OPS << 1)
+
+/* If this bit is set, a syntactically invalid interval is treated as
+ a string of ordinary characters. For example, the ERE 'a{1' is
+ treated as 'a\{1'. */
+#define RE_INVALID_INTERVAL_ORD (RE_DEBUG << 1)
+
+/* If this bit is set, then ignore case when matching.
+ If not set, then case is significant. */
+#define RE_ICASE (RE_INVALID_INTERVAL_ORD << 1)
+
+/* This bit is used internally like RE_CONTEXT_INDEP_ANCHORS but only
+ for ^, because it is difficult to scan the regex backwards to find
+ whether ^ should be special. */
+#define RE_CARET_ANCHORS_HERE (RE_ICASE << 1)
+
+/* If this bit is set, then \{ cannot be first in an bre or
+ immediately after an alternation or begin-group operator. */
+#define RE_CONTEXT_INVALID_DUP (RE_CARET_ANCHORS_HERE << 1)
+
+/* If this bit is set, then no_sub will be set to 1 during
+ re_compile_pattern. */
+#define RE_NO_SUB (RE_CONTEXT_INVALID_DUP << 1)
+
+/* This global variable defines the particular regexp syntax to use (for
+ some interfaces). When a regexp is compiled, the syntax used is
+ stored in the pattern buffer, so changing this does not affect
+ already-compiled regexps. */
+extern reg_syntax_t re_syntax_options;
+
+/* Define combinations of the above bits for the standard possibilities.
+ (The [[[ comments delimit what gets put into the Texinfo file, so
+ don't delete them!) */
+/* [[[begin syntaxes]]] */
+#define RE_SYNTAX_EMACS 0
+
+#define RE_SYNTAX_AWK \
+ (RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DOT_NOT_NULL \
+ | RE_NO_BK_PARENS | RE_NO_BK_REFS \
+ | RE_NO_BK_VBAR | RE_NO_EMPTY_RANGES \
+ | RE_DOT_NEWLINE | RE_CONTEXT_INDEP_ANCHORS \
+ | RE_UNMATCHED_RIGHT_PAREN_ORD | RE_NO_GNU_OPS)
+
+#define RE_SYNTAX_GNU_AWK \
+ ((RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DEBUG) \
+ & ~(RE_DOT_NOT_NULL | RE_INTERVALS | RE_CONTEXT_INDEP_OPS \
+ | RE_CONTEXT_INVALID_OPS ))
+
+#define RE_SYNTAX_POSIX_AWK \
+ (RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS \
+ | RE_INTERVALS | RE_NO_GNU_OPS)
+
+#define RE_SYNTAX_GREP \
+ (RE_BK_PLUS_QM | RE_CHAR_CLASSES \
+ | RE_HAT_LISTS_NOT_NEWLINE | RE_INTERVALS \
+ | RE_NEWLINE_ALT)
+
+#define RE_SYNTAX_EGREP \
+ (RE_CHAR_CLASSES | RE_CONTEXT_INDEP_ANCHORS \
+ | RE_CONTEXT_INDEP_OPS | RE_HAT_LISTS_NOT_NEWLINE \
+ | RE_NEWLINE_ALT | RE_NO_BK_PARENS \
+ | RE_NO_BK_VBAR)
+
+#define RE_SYNTAX_POSIX_EGREP \
+ (RE_SYNTAX_EGREP | RE_INTERVALS | RE_NO_BK_BRACES \
+ | RE_INVALID_INTERVAL_ORD)
+
+/* P1003.2/D11.2, section 4.20.7.1, lines 5078ff. */
+#define RE_SYNTAX_ED RE_SYNTAX_POSIX_BASIC
+
+#define RE_SYNTAX_SED RE_SYNTAX_POSIX_BASIC
+
+/* Syntax bits common to both basic and extended POSIX regex syntax. */
+#define _RE_SYNTAX_POSIX_COMMON \
+ (RE_CHAR_CLASSES | RE_DOT_NEWLINE | RE_DOT_NOT_NULL \
+ | RE_INTERVALS | RE_NO_EMPTY_RANGES)
+
+#define RE_SYNTAX_POSIX_BASIC \
+ (_RE_SYNTAX_POSIX_COMMON | RE_BK_PLUS_QM | RE_CONTEXT_INVALID_DUP)
+
+/* Differs from ..._POSIX_BASIC only in that RE_BK_PLUS_QM becomes
+ RE_LIMITED_OPS, i.e., \? \+ \| are not recognized. Actually, this
+ isn't minimal, since other operators, such as \`, aren't disabled. */
+#define RE_SYNTAX_POSIX_MINIMAL_BASIC \
+ (_RE_SYNTAX_POSIX_COMMON | RE_LIMITED_OPS)
+
+#define RE_SYNTAX_POSIX_EXTENDED \
+ (_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \
+ | RE_CONTEXT_INDEP_OPS | RE_NO_BK_BRACES \
+ | RE_NO_BK_PARENS | RE_NO_BK_VBAR \
+ | RE_CONTEXT_INVALID_OPS | RE_UNMATCHED_RIGHT_PAREN_ORD)
+
+/* Differs from ..._POSIX_EXTENDED in that RE_CONTEXT_INDEP_OPS is
+ removed and RE_NO_BK_REFS is added. */
+#define RE_SYNTAX_POSIX_MINIMAL_EXTENDED \
+ (_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \
+ | RE_CONTEXT_INVALID_OPS | RE_NO_BK_BRACES \
+ | RE_NO_BK_PARENS | RE_NO_BK_REFS \
+ | RE_NO_BK_VBAR | RE_UNMATCHED_RIGHT_PAREN_ORD)
+/* [[[end syntaxes]]] */
+
+/* Maximum number of duplicates an interval can allow. Some systems
+ (erroneously) define this in other header files, but we want our
+ value, so remove any previous define. */
+#ifdef RE_DUP_MAX
+# undef RE_DUP_MAX
+#endif
+/* If sizeof(int) == 2, then ((1 << 15) - 1) overflows. */
+#define RE_DUP_MAX (0x7fff)
+
+
+/* POSIX `cflags' bits (i.e., information for `regcomp'). */
+
+/* If this bit is set, then use extended regular expression syntax.
+ If not set, then use basic regular expression syntax. */
+#define REG_EXTENDED 1
+
+/* If this bit is set, then ignore case when matching.
+ If not set, then case is significant. */
+#define REG_ICASE (REG_EXTENDED << 1)
+
+/* If this bit is set, then anchors do not match at newline
+ characters in the string.
+ If not set, then anchors do match at newlines. */
+#define REG_NEWLINE (REG_ICASE << 1)
+
+/* If this bit is set, then report only success or fail in regexec.
+ If not set, then returns differ between not matching and errors. */
+#define REG_NOSUB (REG_NEWLINE << 1)
+
+
+/* POSIX `eflags' bits (i.e., information for regexec). */
+
+/* If this bit is set, then the beginning-of-line operator doesn't match
+ the beginning of the string (presumably because it's not the
+ beginning of a line).
+ If not set, then the beginning-of-line operator does match the
+ beginning of the string. */
+#define REG_NOTBOL 1
+
+/* Like REG_NOTBOL, except for the end-of-line. */
+#define REG_NOTEOL (1 << 1)
+
+/* Use PMATCH[0] to delimit the start and end of the search in the
+ buffer. */
+#define REG_STARTEND (1 << 2)
+
+
+/* If any error codes are removed, changed, or added, update the
+ `re_error_msg' table in regex.c. */
+typedef enum
+{
+#ifdef _XOPEN_SOURCE
+ REG_ENOSYS = -1, /* This will never happen for this implementation. */
+#endif
+
+ REG_NOERROR = 0, /* Success. */
+ REG_NOMATCH, /* Didn't find a match (for regexec). */
+
+ /* POSIX regcomp return error codes. (In the order listed in the
+ standard.) */
+ REG_BADPAT, /* Invalid pattern. */
+ REG_ECOLLATE, /* Inalid collating element. */
+ REG_ECTYPE, /* Invalid character class name. */
+ REG_EESCAPE, /* Trailing backslash. */
+ REG_ESUBREG, /* Invalid back reference. */
+ REG_EBRACK, /* Unmatched left bracket. */
+ REG_EPAREN, /* Parenthesis imbalance. */
+ REG_EBRACE, /* Unmatched \{. */
+ REG_BADBR, /* Invalid contents of \{\}. */
+ REG_ERANGE, /* Invalid range end. */
+ REG_ESPACE, /* Ran out of memory. */
+ REG_BADRPT, /* No preceding re for repetition op. */
+
+ /* Error codes we've added. */
+ REG_EEND, /* Premature end. */
+ REG_ESIZE, /* Compiled pattern bigger than 2^16 bytes. */
+ REG_ERPAREN /* Unmatched ) or \); not returned from regcomp. */
+} reg_errcode_t;
+
+/* This data structure represents a compiled pattern. Before calling
+ the pattern compiler, the fields `buffer', `allocated', `fastmap',
+ `translate', and `no_sub' can be set. After the pattern has been
+ compiled, the `re_nsub' field is available. All other fields are
+ private to the regex routines. */
+
+#ifndef RE_TRANSLATE_TYPE
+# define RE_TRANSLATE_TYPE unsigned char *
+#endif
+
+struct re_pattern_buffer
+{
+ /* Space that holds the compiled pattern. It is declared as
+ `unsigned char *' because its elements are sometimes used as
+ array indexes. */
+ unsigned char *buffer;
+
+ /* Number of bytes to which `buffer' points. */
+ unsigned long int allocated;
+
+ /* Number of bytes actually used in `buffer'. */
+ unsigned long int used;
+
+ /* Syntax setting with which the pattern was compiled. */
+ reg_syntax_t syntax;
+
+ /* Pointer to a fastmap, if any, otherwise zero. re_search uses the
+ fastmap, if there is one, to skip over impossible starting points
+ for matches. */
+ char *fastmap;
+
+ /* Either a translate table to apply to all characters before
+ comparing them, or zero for no translation. The translation is
+ applied to a pattern when it is compiled and to a string when it
+ is matched. */
+ RE_TRANSLATE_TYPE translate;
+
+ /* Number of subexpressions found by the compiler. */
+ size_t re_nsub;
+
+ /* Zero if this pattern cannot match the empty string, one else.
+ Well, in truth it's used only in `re_search_2', to see whether or
+ not we should use the fastmap, so we don't set this absolutely
+ perfectly; see `re_compile_fastmap' (the `duplicate' case). */
+ unsigned can_be_null : 1;
+
+ /* If REGS_UNALLOCATED, allocate space in the `regs' structure
+ for `max (RE_NREGS, re_nsub + 1)' groups.
+ If REGS_REALLOCATE, reallocate space if necessary.
+ If REGS_FIXED, use what's there. */
+#define REGS_UNALLOCATED 0
+#define REGS_REALLOCATE 1
+#define REGS_FIXED 2
+ unsigned regs_allocated : 2;
+
+ /* Set to zero when `regex_compile' compiles a pattern; set to one
+ by `re_compile_fastmap' if it updates the fastmap. */
+ unsigned fastmap_accurate : 1;
+
+ /* If set, `re_match_2' does not return information about
+ subexpressions. */
+ unsigned no_sub : 1;
+
+ /* If set, a beginning-of-line anchor doesn't match at the beginning
+ of the string. */
+ unsigned not_bol : 1;
+
+ /* Similarly for an end-of-line anchor. */
+ unsigned not_eol : 1;
+
+ /* If true, an anchor at a newline matches. */
+ unsigned newline_anchor : 1;
+};
+
+typedef struct re_pattern_buffer regex_t;
+
+/* Type for byte offsets within the string. POSIX mandates this. */
+typedef int regoff_t;
+
+
+/* This is the structure we store register match data in. See
+ regex.texinfo for a full description of what registers match. */
+struct re_registers
+{
+ unsigned num_regs;
+ regoff_t *start;
+ regoff_t *end;
+};
+
+
+/* If `regs_allocated' is REGS_UNALLOCATED in the pattern buffer,
+ `re_match_2' returns information about at least this many registers
+ the first time a `regs' structure is passed. */
+#ifndef RE_NREGS
+# define RE_NREGS 30
+#endif
+
+
+/* POSIX specification for registers. Aside from the different names than
+ `re_registers', POSIX uses an array of structures, instead of a
+ structure of arrays. */
+typedef struct
+{
+ regoff_t rm_so; /* Byte offset from string's start to substring's start. */
+ regoff_t rm_eo; /* Byte offset from string's start to substring's end. */
+} regmatch_t;
+
+/* Declarations for routines. */
+
+/* Sets the current default syntax to SYNTAX, and return the old syntax.
+ You can also simply assign to the `re_syntax_options' variable. */
+extern reg_syntax_t re_set_syntax (reg_syntax_t __syntax);
+
+/* Compile the regular expression PATTERN, with length LENGTH
+ and syntax given by the global `re_syntax_options', into the buffer
+ BUFFER. Return NULL if successful, and an error string if not. */
+extern const char *re_compile_pattern (const char *__pattern, size_t __length,
+ struct re_pattern_buffer *__buffer);
+
+
+/* Compile a fastmap for the compiled pattern in BUFFER; used to
+ accelerate searches. Return 0 if successful and -2 if was an
+ internal error. */
+extern int re_compile_fastmap (struct re_pattern_buffer *__buffer);
+
+
+/* Search in the string STRING (with length LENGTH) for the pattern
+ compiled into BUFFER. Start searching at position START, for RANGE
+ characters. Return the starting position of the match, -1 for no
+ match, or -2 for an internal error. Also return register
+ information in REGS (if REGS and BUFFER->no_sub are nonzero). */
+extern int re_search (struct re_pattern_buffer *__buffer, const char *__string,
+ int __length, int __start, int __range,
+ struct re_registers *__regs);
+
+
+/* Like `re_search', but search in the concatenation of STRING1 and
+ STRING2. Also, stop searching at index START + STOP. */
+extern int re_search_2 (struct re_pattern_buffer *__buffer,
+ const char *__string1, int __length1,
+ const char *__string2, int __length2, int __start,
+ int __range, struct re_registers *__regs, int __stop);
+
+
+/* Like `re_search', but return how many characters in STRING the regexp
+ in BUFFER matched, starting at position START. */
+extern int re_match (struct re_pattern_buffer *__buffer, const char *__string,
+ int __length, int __start, struct re_registers *__regs);
+
+
+/* Relates to `re_match' as `re_search_2' relates to `re_search'. */
+extern int re_match_2 (struct re_pattern_buffer *__buffer,
+ const char *__string1, int __length1,
+ const char *__string2, int __length2, int __start,
+ struct re_registers *__regs, int __stop);
+
+
+/* Set REGS to hold NUM_REGS registers, storing them in STARTS and
+ ENDS. Subsequent matches using BUFFER and REGS will use this memory
+ for recording register information. STARTS and ENDS must be
+ allocated with malloc, and must each be at least `NUM_REGS * sizeof
+ (regoff_t)' bytes long.
+
+ If NUM_REGS == 0, then subsequent matches should allocate their own
+ register data.
+
+ Unless this function is called, the first search or match using
+ PATTERN_BUFFER will allocate its own register data, without
+ freeing the old data. */
+extern void re_set_registers (struct re_pattern_buffer *__buffer,
+ struct re_registers *__regs,
+ unsigned int __num_regs,
+ regoff_t *__starts, regoff_t *__ends);
+
+#if defined _REGEX_RE_COMP || defined _LIBC
+# ifndef _CRAY
+/* 4.2 bsd compatibility. */
+extern char *re_comp (const char *);
+extern int re_exec (const char *);
+# endif
+#endif
+
+/* GCC 2.95 and later have "__restrict"; C99 compilers have
+ "restrict", and "configure" may have defined "restrict". */
+#ifndef __restrict
+# if ! (2 < __GNUC__ || (2 == __GNUC__ && 95 <= __GNUC_MINOR__))
+# if defined restrict || 199901L <= __STDC_VERSION__
+# define __restrict restrict
+# else
+# define __restrict
+# endif
+# endif
+#endif
+/* gcc 3.1 and up support the [restrict] syntax. */
+#ifndef __restrict_arr
+# if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) \
+ && !defined __GNUG__
+# define __restrict_arr __restrict
+# else
+# define __restrict_arr
+# endif
+#endif
+
+/* POSIX compatibility. */
+extern int regcomp (regex_t *__restrict __preg,
+ const char *__restrict __pattern,
+ int __cflags);
+
+extern int regexec (const regex_t *__restrict __preg,
+ const char *__restrict __string, size_t __nmatch,
+ regmatch_t __pmatch[__restrict_arr],
+ int __eflags);
+
+extern size_t regerror (int __errcode, const regex_t *__restrict __preg,
+ char *__restrict __errbuf, size_t __errbuf_size);
+
+extern void regfree (regex_t *__preg);
+
+
+#ifdef __cplusplus
+}
+#endif /* C++ */
+
+#endif /* regex.h */
diff --git a/utility/demo-fw/pc-tools/CreateDemoBin/lib/EasyBMP/BSD_(revised)_license.txt b/utility/demo-fw/pc-tools/CreateDemoBin/lib/EasyBMP/BSD_(revised)_license.txt
new file mode 100644
index 0000000..6785262
--- /dev/null
+++ b/utility/demo-fw/pc-tools/CreateDemoBin/lib/EasyBMP/BSD_(revised)_license.txt
@@ -0,0 +1,10 @@
+Copyright (c) 2005, The EasyBMP Project (http://easybmp.sourceforge.net)
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+ 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 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. \ No newline at end of file
diff --git a/utility/demo-fw/pc-tools/CreateDemoBin/lib/EasyBMP/EasyBMP.cpp b/utility/demo-fw/pc-tools/CreateDemoBin/lib/EasyBMP/EasyBMP.cpp
new file mode 100644
index 0000000..07d33ef
--- /dev/null
+++ b/utility/demo-fw/pc-tools/CreateDemoBin/lib/EasyBMP/EasyBMP.cpp
@@ -0,0 +1,1917 @@
+/*************************************************
+* *
+* EasyBMP Cross-Platform Windows Bitmap Library *
+* *
+* Author: Paul Macklin *
+* email: macklin01@users.sourceforge.net *
+* support: http://easybmp.sourceforge.net *
+* *
+* file: EasyBMP.cpp *
+* date added: 03-31-2006 *
+* date modified: 12-01-2006 *
+* version: 1.06 *
+* *
+* License: BSD (revised/modified) *
+* Copyright: 2005-6 by the EasyBMP Project *
+* *
+* description: Actual source file *
+* *
+*************************************************/
+
+#include "EasyBMP.h"
+
+/* These functions are defined in EasyBMP.h */
+
+bool EasyBMPwarnings = true;
+
+void SetEasyBMPwarningsOff( void )
+{ EasyBMPwarnings = false; }
+void SetEasyBMPwarningsOn( void )
+{ EasyBMPwarnings = true; }
+bool GetEasyBMPwarningState( void )
+{ return EasyBMPwarnings; }
+
+/* These functions are defined in EasyBMP_DataStructures.h */
+
+int IntPow( int base, int exponent )
+{
+ int i;
+ int output = 1;
+ for( i=0 ; i < exponent ; i++ )
+ { output *= base; }
+ return output;
+}
+
+BMFH::BMFH()
+{
+ bfType = 19778;
+ bfReserved1 = 0;
+ bfReserved2 = 0;
+}
+
+void BMFH::SwitchEndianess( void )
+{
+ bfType = FlipWORD( bfType );
+ bfSize = FlipDWORD( bfSize );
+ bfReserved1 = FlipWORD( bfReserved1 );
+ bfReserved2 = FlipWORD( bfReserved2 );
+ bfOffBits = FlipDWORD( bfOffBits );
+ return;
+}
+
+BMIH::BMIH()
+{
+ biPlanes = 1;
+ biCompression = 0;
+ biXPelsPerMeter = DefaultXPelsPerMeter;
+ biYPelsPerMeter = DefaultYPelsPerMeter;
+ biClrUsed = 0;
+ biClrImportant = 0;
+}
+
+void BMIH::SwitchEndianess( void )
+{
+ biSize = FlipDWORD( biSize );
+ biWidth = FlipDWORD( biWidth );
+ biHeight = FlipDWORD( biHeight );
+ biPlanes = FlipWORD( biPlanes );
+ biBitCount = FlipWORD( biBitCount );
+ biCompression = FlipDWORD( biCompression );
+ biSizeImage = FlipDWORD( biSizeImage );
+ biXPelsPerMeter = FlipDWORD( biXPelsPerMeter );
+ biYPelsPerMeter = FlipDWORD( biYPelsPerMeter );
+ biClrUsed = FlipDWORD( biClrUsed );
+ biClrImportant = FlipDWORD( biClrImportant );
+ return;
+}
+
+void BMIH::display( void )
+{
+ using namespace std;
+ cout << "biSize: " << (int) biSize << endl
+ << "biWidth: " << (int) biWidth << endl
+ << "biHeight: " << (int) biHeight << endl
+ << "biPlanes: " << (int) biPlanes << endl
+ << "biBitCount: " << (int) biBitCount << endl
+ << "biCompression: " << (int) biCompression << endl
+ << "biSizeImage: " << (int) biSizeImage << endl
+ << "biXPelsPerMeter: " << (int) biXPelsPerMeter << endl
+ << "biYPelsPerMeter: " << (int) biYPelsPerMeter << endl
+ << "biClrUsed: " << (int) biClrUsed << endl
+ << "biClrImportant: " << (int) biClrImportant << endl << endl;
+}
+
+void BMFH::display( void )
+{
+ using namespace std;
+ cout << "bfType: " << (int) bfType << endl
+ << "bfSize: " << (int) bfSize << endl
+ << "bfReserved1: " << (int) bfReserved1 << endl
+ << "bfReserved2: " << (int) bfReserved2 << endl
+ << "bfOffBits: " << (int) bfOffBits << endl << endl;
+}
+
+/* These functions are defined in EasyBMP_BMP.h */
+
+RGBApixel BMP::GetPixel( int i, int j ) const
+{
+ using namespace std;
+ bool Warn = false;
+ if( i >= Width )
+ { i = Width-1; Warn = true; }
+ if( i < 0 )
+ { i = 0; Warn = true; }
+ if( j >= Height )
+ { j = Height-1; Warn = true; }
+ if( j < 0 )
+ { j = 0; Warn = true; }
+ if( Warn && EasyBMPwarnings )
+ {
+ cout << "EasyBMP Warning: Attempted to access non-existent pixel;" << endl
+ << " Truncating request to fit in the range [0,"
+ << Width-1 << "] x [0," << Height-1 << "]." << endl;
+ }
+ return Pixels[i][j];
+}
+
+bool BMP::SetPixel( int i, int j, RGBApixel NewPixel )
+{
+ Pixels[i][j] = NewPixel;
+ return true;
+}
+
+
+bool BMP::SetColor( int ColorNumber , RGBApixel NewColor )
+{
+ using namespace std;
+ if( BitDepth != 1 && BitDepth != 4 && BitDepth != 8 )
+ {
+ if( EasyBMPwarnings )
+ {
+ cout << "EasyBMP Warning: Attempted to change color table for a BMP object" << endl
+ << " that lacks a color table. Ignoring request." << endl;
+ }
+ return false;
+ }
+ if( !Colors )
+ {
+ if( EasyBMPwarnings )
+ {
+ cout << "EasyBMP Warning: Attempted to set a color, but the color table" << endl
+ << " is not defined. Ignoring request." << endl;
+ }
+ return false;
+ }
+ if( ColorNumber >= TellNumberOfColors() )
+ {
+ if( EasyBMPwarnings )
+ {
+ cout << "EasyBMP Warning: Requested color number "
+ << ColorNumber << " is outside the allowed" << endl
+ << " range [0," << TellNumberOfColors()-1
+ << "]. Ignoring request to set this color." << endl;
+ }
+ return false;
+ }
+ Colors[ColorNumber] = NewColor;
+ return true;
+}
+
+// RGBApixel BMP::GetColor( int ColorNumber ) const
+RGBApixel BMP::GetColor( int ColorNumber )
+{
+ RGBApixel Output;
+ Output.Red = 255;
+ Output.Green = 255;
+ Output.Blue = 255;
+ Output.Alpha = 0;
+
+ using namespace std;
+ if( BitDepth != 1 && BitDepth != 4 && BitDepth != 8 )
+ {
+ if( EasyBMPwarnings )
+ {
+ cout << "EasyBMP Warning: Attempted to access color table for a BMP object" << endl
+ << " that lacks a color table. Ignoring request." << endl;
+ }
+ return Output;
+ }
+ if( !Colors )
+ {
+ if( EasyBMPwarnings )
+ {
+ cout << "EasyBMP Warning: Requested a color, but the color table" << endl
+ << " is not defined. Ignoring request." << endl;
+ }
+ return Output;
+ }
+ if( ColorNumber >= TellNumberOfColors() )
+ {
+ if( EasyBMPwarnings )
+ {
+ cout << "EasyBMP Warning: Requested color number "
+ << ColorNumber << " is outside the allowed" << endl
+ << " range [0," << TellNumberOfColors()-1
+ << "]. Ignoring request to get this color." << endl;
+ }
+ return Output;
+ }
+ Output = Colors[ColorNumber];
+ return Output;
+}
+
+BMP::BMP()
+{
+ Width = 1;
+ Height = 1;
+ BitDepth = 24;
+ Pixels = new RGBApixel* [Width];
+ Pixels[0] = new RGBApixel [Height];
+ Colors = NULL;
+
+ XPelsPerMeter = 0;
+ YPelsPerMeter = 0;
+
+ MetaData1 = NULL;
+ SizeOfMetaData1 = 0;
+ MetaData2 = NULL;
+ SizeOfMetaData2 = 0;
+}
+
+// BMP::BMP( const BMP& Input )
+BMP::BMP( BMP& Input )
+{
+ // first, make the image empty.
+
+ Width = 1;
+ Height = 1;
+ BitDepth = 24;
+ Pixels = new RGBApixel* [Width];
+ Pixels[0] = new RGBApixel [Height];
+ Colors = NULL;
+ XPelsPerMeter = 0;
+ YPelsPerMeter = 0;
+
+ MetaData1 = NULL;
+ SizeOfMetaData1 = 0;
+ MetaData2 = NULL;
+ SizeOfMetaData2 = 0;
+
+ // now, set the correct bit depth
+
+ SetBitDepth( Input.TellBitDepth() );
+
+ // set the correct pixel size
+
+ SetSize( Input.TellWidth() , Input.TellHeight() );
+
+ // set the DPI information from Input
+
+ SetDPI( Input.TellHorizontalDPI() , Input.TellVerticalDPI() );
+
+ // if there is a color table, get all the colors
+
+ if( BitDepth == 1 || BitDepth == 4 ||
+ BitDepth == 8 )
+ {
+ for( int k=0 ; k < TellNumberOfColors() ; k++ )
+ {
+ SetColor( k, Input.GetColor( k ));
+ }
+ }
+
+ // get all the pixels
+
+ for( int j=0; j < Height ; j++ )
+ {
+ for( int i=0; i < Width ; i++ )
+ {
+ Pixels[i][j] = *Input(i,j);
+// Pixels[i][j] = Input.GetPixel(i,j); // *Input(i,j);
+ }
+ }
+}
+
+BMP::~BMP()
+{
+ int i;
+ for(i=0;i<Width;i++)
+ { delete [] Pixels[i]; }
+ delete [] Pixels;
+ if( Colors )
+ { delete [] Colors; }
+
+ if( MetaData1 )
+ { delete [] MetaData1; }
+ if( MetaData2 )
+ { delete [] MetaData2; }
+}
+
+RGBApixel* BMP::operator()(int i, int j)
+{
+ using namespace std;
+ bool Warn = false;
+ if( i >= Width )
+ { i = Width-1; Warn = true; }
+ if( i < 0 )
+ { i = 0; Warn = true; }
+ if( j >= Height )
+ { j = Height-1; Warn = true; }
+ if( j < 0 )
+ { j = 0; Warn = true; }
+ if( Warn && EasyBMPwarnings )
+ {
+ cout << "EasyBMP Warning: Attempted to access non-existent pixel;" << endl
+ << " Truncating request to fit in the range [0,"
+ << Width-1 << "] x [0," << Height-1 << "]." << endl;
+ }
+ return &(Pixels[i][j]);
+}
+
+// int BMP::TellBitDepth( void ) const
+int BMP::TellBitDepth( void )
+{ return BitDepth; }
+
+// int BMP::TellHeight( void ) const
+int BMP::TellHeight( void )
+{ return Height; }
+
+// int BMP::TellWidth( void ) const
+int BMP::TellWidth( void )
+{ return Width; }
+
+// int BMP::TellNumberOfColors( void ) const
+int BMP::TellNumberOfColors( void )
+{
+ int output = IntPow( 2, BitDepth );
+ if( BitDepth == 32 )
+ { output = IntPow( 2, 24 ); }
+ return output;
+}
+
+bool BMP::SetBitDepth( int NewDepth )
+{
+ using namespace std;
+ if( NewDepth != 1 && NewDepth != 4 &&
+ NewDepth != 8 && NewDepth != 16 &&
+ NewDepth != 24 && NewDepth != 32 )
+ {
+ if( EasyBMPwarnings )
+ {
+ cout << "EasyBMP Warning: User attempted to set unsupported bit depth "
+ << NewDepth << "." << endl
+ << " Bit depth remains unchanged at "
+ << BitDepth << "." << endl;
+ }
+ return false;
+ }
+
+ BitDepth = NewDepth;
+ if( Colors )
+ { delete [] Colors; }
+ int NumberOfColors = IntPow( 2, BitDepth );
+ if( BitDepth == 1 || BitDepth == 4 || BitDepth == 8 )
+ { Colors = new RGBApixel [NumberOfColors]; }
+ else
+ { Colors = NULL; }
+ if( BitDepth == 1 || BitDepth == 4 || BitDepth == 8 )
+ { CreateStandardColorTable(); }
+
+ return true;
+}
+
+bool BMP::SetSize(int NewWidth , int NewHeight )
+{
+ using namespace std;
+ if( NewWidth <= 0 || NewHeight <= 0 )
+ {
+ if( EasyBMPwarnings )
+ {
+ cout << "EasyBMP Warning: User attempted to set a non-positive width or height." << endl
+ << " Size remains unchanged at "
+ << Width << " x " << Height << "." << endl;
+ }
+ return false;
+ }
+
+ int i,j;
+
+ for(i=0;i<Width;i++)
+ { delete [] Pixels[i]; }
+ delete [] Pixels;
+
+ Width = NewWidth;
+ Height = NewHeight;
+ Pixels = new RGBApixel* [ Width ];
+
+ for(i=0; i<Width; i++)
+ { Pixels[i] = new RGBApixel [ Height ]; }
+
+ for( i=0 ; i < Width ; i++)
+ {
+ for( j=0 ; j < Height ; j++ )
+ {
+ Pixels[i][j].Red = 255;
+ Pixels[i][j].Green = 255;
+ Pixels[i][j].Blue = 255;
+ Pixels[i][j].Alpha = 0;
+ }
+ }
+
+ return true;
+}
+
+bool BMP::WriteToFile( const char* FileName )
+{
+ using namespace std;
+ if( !EasyBMPcheckDataSize() )
+ {
+ if( EasyBMPwarnings )
+ {
+ cout << "EasyBMP Error: Data types are wrong size!" << endl
+ << " You may need to mess with EasyBMP_DataTypes.h" << endl
+ << " to fix these errors, and then recompile." << endl
+ << " All 32-bit and 64-bit machines should be" << endl
+ << " supported, however." << endl << endl;
+ }
+ return false;
+ }
+
+ FILE* fp = fopen( FileName, "wb" );
+ if( fp == NULL )
+ {
+ if( EasyBMPwarnings )
+ {
+ cout << "EasyBMP Error: Cannot open file "
+ << FileName << " for output." << endl;
+ }
+ fclose( fp );
+ return false;
+ }
+
+ // some preliminaries
+
+ double dBytesPerPixel = ( (double) BitDepth ) / 8.0;
+ double dBytesPerRow = dBytesPerPixel * (Width+0.0);
+ dBytesPerRow = ceil(dBytesPerRow);
+
+ int BytePaddingPerRow = 4 - ( (int) (dBytesPerRow) )% 4;
+ if( BytePaddingPerRow == 4 )
+ { BytePaddingPerRow = 0; }
+
+ double dActualBytesPerRow = dBytesPerRow + BytePaddingPerRow;
+
+ double dTotalPixelBytes = Height * dActualBytesPerRow;
+
+ double dPaletteSize = 0;
+ if( BitDepth == 1 || BitDepth == 4 || BitDepth == 8 )
+ { dPaletteSize = IntPow(2,BitDepth)*4.0; }
+
+ // leave some room for 16-bit masks
+ if( BitDepth == 16 )
+ { dPaletteSize = 3*4; }
+
+ double dTotalFileSize = 14 + 40 + dPaletteSize + dTotalPixelBytes;
+
+ // write the file header
+
+ BMFH bmfh;
+ bmfh.bfSize = (ebmpDWORD) dTotalFileSize;
+ bmfh.bfReserved1 = 0;
+ bmfh.bfReserved2 = 0;
+ bmfh.bfOffBits = (ebmpDWORD) (14+40+dPaletteSize);
+
+ if( IsBigEndian() )
+ { bmfh.SwitchEndianess(); }
+
+ fwrite( (char*) &(bmfh.bfType) , sizeof(ebmpWORD) , 1 , fp );
+ fwrite( (char*) &(bmfh.bfSize) , sizeof(ebmpDWORD) , 1 , fp );
+ fwrite( (char*) &(bmfh.bfReserved1) , sizeof(ebmpWORD) , 1 , fp );
+ fwrite( (char*) &(bmfh.bfReserved2) , sizeof(ebmpWORD) , 1 , fp );
+ fwrite( (char*) &(bmfh.bfOffBits) , sizeof(ebmpDWORD) , 1 , fp );
+
+ // write the info header
+
+ BMIH bmih;
+ bmih.biSize = 40;
+ bmih.biWidth = Width;
+ bmih.biHeight = Height;
+ bmih.biPlanes = 1;
+ bmih.biBitCount = BitDepth;
+ bmih.biCompression = 0;
+ bmih.biSizeImage = (ebmpDWORD) dTotalPixelBytes;
+ if( XPelsPerMeter )
+ { bmih.biXPelsPerMeter = XPelsPerMeter; }
+ else
+ { bmih.biXPelsPerMeter = DefaultXPelsPerMeter; }
+ if( YPelsPerMeter )
+ { bmih.biYPelsPerMeter = YPelsPerMeter; }
+ else
+ { bmih.biYPelsPerMeter = DefaultYPelsPerMeter; }
+
+ bmih.biClrUsed = 0;
+ bmih.biClrImportant = 0;
+
+ // indicates that we'll be using bit fields for 16-bit files
+ if( BitDepth == 16 )
+ { bmih.biCompression = 3; }
+
+ if( IsBigEndian() )
+ { bmih.SwitchEndianess(); }
+
+ fwrite( (char*) &(bmih.biSize) , sizeof(ebmpDWORD) , 1 , fp );
+ fwrite( (char*) &(bmih.biWidth) , sizeof(ebmpDWORD) , 1 , fp );
+ fwrite( (char*) &(bmih.biHeight) , sizeof(ebmpDWORD) , 1 , fp );
+ fwrite( (char*) &(bmih.biPlanes) , sizeof(ebmpWORD) , 1 , fp );
+ fwrite( (char*) &(bmih.biBitCount) , sizeof(ebmpWORD) , 1 , fp );
+ fwrite( (char*) &(bmih.biCompression) , sizeof(ebmpDWORD) , 1 , fp );
+ fwrite( (char*) &(bmih.biSizeImage) , sizeof(ebmpDWORD) , 1 , fp );
+ fwrite( (char*) &(bmih.biXPelsPerMeter) , sizeof(ebmpDWORD) , 1 , fp );
+ fwrite( (char*) &(bmih.biYPelsPerMeter) , sizeof(ebmpDWORD) , 1 , fp );
+ fwrite( (char*) &(bmih.biClrUsed) , sizeof(ebmpDWORD) , 1 , fp);
+ fwrite( (char*) &(bmih.biClrImportant) , sizeof(ebmpDWORD) , 1 , fp);
+
+ // write the palette
+ if( BitDepth == 1 || BitDepth == 4 || BitDepth == 8 )
+ {
+ int NumberOfColors = IntPow(2,BitDepth);
+
+ // if there is no palette, create one
+ if( !Colors )
+ {
+ if( !Colors )
+ { Colors = new RGBApixel [NumberOfColors]; }
+ CreateStandardColorTable();
+ }
+
+ int n;
+ for( n=0 ; n < NumberOfColors ; n++ )
+ { fwrite( (char*) &(Colors[n]) , 4 , 1 , fp ); }
+ }
+
+ // write the pixels
+ int i,j;
+ if( BitDepth != 16 )
+ {
+ ebmpBYTE* Buffer;
+ int BufferSize = (int) ( (Width*BitDepth)/8.0 );
+ while( 8*BufferSize < Width*BitDepth )
+ { BufferSize++; }
+ while( BufferSize % 4 )
+ { BufferSize++; }
+
+ Buffer = new ebmpBYTE [BufferSize];
+ for( j=0 ; j < BufferSize; j++ )
+ { Buffer[j] = 0; }
+
+ j=Height-1;
+
+ while( j > -1 )
+ {
+ bool Success = false;
+ if( BitDepth == 32 )
+ { Success = Write32bitRow( Buffer, BufferSize, j ); }
+ if( BitDepth == 24 )
+ { Success = Write24bitRow( Buffer, BufferSize, j ); }
+ if( BitDepth == 8 )
+ { Success = Write8bitRow( Buffer, BufferSize, j ); }
+ if( BitDepth == 4 )
+ { Success = Write4bitRow( Buffer, BufferSize, j ); }
+ if( BitDepth == 1 )
+ { Success = Write1bitRow( Buffer, BufferSize, j ); }
+ if( Success )
+ {
+ int BytesWritten = (int) fwrite( (char*) Buffer, 1, BufferSize, fp );
+ if( BytesWritten != BufferSize )
+ { Success = false; }
+ }
+ if( !Success )
+ {
+ if( EasyBMPwarnings )
+ {
+ cout << "EasyBMP Error: Could not write proper amount of data." << endl;
+ }
+ j = -1;
+ }
+ j--;
+ }
+
+ delete [] Buffer;
+ }
+
+ if( BitDepth == 16 )
+ {
+ // write the bit masks
+
+ ebmpWORD BlueMask = 31; // bits 12-16
+ ebmpWORD GreenMask = 2016; // bits 6-11
+ ebmpWORD RedMask = 63488; // bits 1-5
+ ebmpWORD ZeroWORD;
+
+ if( IsBigEndian() )
+ { RedMask = FlipWORD( RedMask ); }
+ fwrite( (char*) &RedMask , 2 , 1 , fp );
+ fwrite( (char*) &ZeroWORD , 2 , 1 , fp );
+
+ if( IsBigEndian() )
+ { GreenMask = FlipWORD( GreenMask ); }
+ fwrite( (char*) &GreenMask , 2 , 1 , fp );
+ fwrite( (char*) &ZeroWORD , 2 , 1 , fp );
+
+ if( IsBigEndian() )
+ { BlueMask = FlipWORD( BlueMask ); }
+ fwrite( (char*) &BlueMask , 2 , 1 , fp );
+ fwrite( (char*) &ZeroWORD , 2 , 1 , fp );
+
+ int DataBytes = Width*2;
+ int PaddingBytes = ( 4 - DataBytes % 4 ) % 4;
+
+ // write the actual pixels
+
+ for( j=Height-1 ; j >= 0 ; j-- )
+ //int WriteNumber;
+ //for(j=0, WriteNumber=0; j < Height; ++j)
+ {
+ // write all row pixel data
+ i=0;
+ int WriteNumber = 0;
+ while( WriteNumber < DataBytes )
+ //for(i = 0; i <Width, WriteNumber < DataBytes; ++i)
+ {
+ ebmpWORD TempWORD;
+
+ ebmpWORD RedWORD = (ebmpWORD) ((Pixels[i][j]).Red / 8);
+ ebmpWORD GreenWORD = (ebmpWORD) ((Pixels[i][j]).Green / 4);
+ ebmpWORD BlueWORD = (ebmpWORD) ((Pixels[i][j]).Blue / 8);
+
+ TempWORD = (RedWORD<<11) + (GreenWORD<<5) + BlueWORD;
+ if( IsBigEndian() )
+ { TempWORD = FlipWORD( TempWORD );
+ }
+
+ fwrite( (char*) &TempWORD , 2, 1, fp);
+ WriteNumber += 2;
+ i++;
+ }
+ // }
+ // write any necessary row padding
+ WriteNumber = 0;
+ while( WriteNumber < PaddingBytes )
+ {
+ ebmpBYTE TempBYTE;
+ fwrite( (char*) &TempBYTE , 1, 1, fp);
+ WriteNumber++;
+ }
+ }
+
+ }
+
+ fclose(fp);
+ return true;
+}
+
+bool BMP::ReadFromFile( const char* FileName )
+{
+ using namespace std;
+ if( !EasyBMPcheckDataSize() )
+ {
+ if( EasyBMPwarnings )
+ {
+ cout << "EasyBMP Error: Data types are wrong size!" << endl
+ << " You may need to mess with EasyBMP_DataTypes.h" << endl
+ << " to fix these errors, and then recompile." << endl
+ << " All 32-bit and 64-bit machines should be" << endl
+ << " supported, however." << endl << endl;
+ }
+ return false;
+ }
+
+ FILE* fp = fopen( FileName, "rb" );
+ if( fp == NULL )
+ {
+ if( EasyBMPwarnings )
+ {
+ cout << "EasyBMP Error: Cannot open file "
+ << FileName << " for input." << endl;
+ }
+ SetBitDepth(1);
+ SetSize(1,1);
+ return false;
+ }
+
+ // read the file header
+
+ BMFH bmfh;
+ bool NotCorrupted = true;
+
+ NotCorrupted &= SafeFread( (char*) &(bmfh.bfType) , sizeof(ebmpWORD), 1, fp);
+
+ bool IsBitmap = false;
+
+ if( IsBigEndian() && bmfh.bfType == 16973 )
+ { IsBitmap = true; }
+ if( !IsBigEndian() && bmfh.bfType == 19778 )
+ { IsBitmap = true; }
+
+ if( !IsBitmap )
+ {
+ if( EasyBMPwarnings )
+ {
+ cout << "EasyBMP Error: " << FileName
+ << " is not a Windows BMP file!" << endl;
+ }
+ fclose( fp );
+ return false;
+ }
+
+ NotCorrupted &= SafeFread( (char*) &(bmfh.bfSize) , sizeof(ebmpDWORD) , 1, fp);
+ NotCorrupted &= SafeFread( (char*) &(bmfh.bfReserved1) , sizeof(ebmpWORD) , 1, fp);
+ NotCorrupted &= SafeFread( (char*) &(bmfh.bfReserved2) , sizeof(ebmpWORD) , 1, fp);
+ NotCorrupted &= SafeFread( (char*) &(bmfh.bfOffBits) , sizeof(ebmpDWORD) , 1 , fp);
+
+ if( IsBigEndian() )
+ { bmfh.SwitchEndianess(); }
+
+ // read the info header
+
+ BMIH bmih;
+
+ NotCorrupted &= SafeFread( (char*) &(bmih.biSize) , sizeof(ebmpDWORD) , 1 , fp);
+ NotCorrupted &= SafeFread( (char*) &(bmih.biWidth) , sizeof(ebmpDWORD) , 1 , fp);
+ NotCorrupted &= SafeFread( (char*) &(bmih.biHeight) , sizeof(ebmpDWORD) , 1 , fp);
+ NotCorrupted &= SafeFread( (char*) &(bmih.biPlanes) , sizeof(ebmpWORD) , 1, fp);
+ NotCorrupted &= SafeFread( (char*) &(bmih.biBitCount) , sizeof(ebmpWORD) , 1, fp);
+
+ NotCorrupted &= SafeFread( (char*) &(bmih.biCompression) , sizeof(ebmpDWORD) , 1 , fp);
+ NotCorrupted &= SafeFread( (char*) &(bmih.biSizeImage) , sizeof(ebmpDWORD) , 1 , fp);
+ NotCorrupted &= SafeFread( (char*) &(bmih.biXPelsPerMeter) , sizeof(ebmpDWORD) , 1 , fp);
+ NotCorrupted &= SafeFread( (char*) &(bmih.biYPelsPerMeter) , sizeof(ebmpDWORD) , 1 , fp);
+ NotCorrupted &= SafeFread( (char*) &(bmih.biClrUsed) , sizeof(ebmpDWORD) , 1 , fp);
+ NotCorrupted &= SafeFread( (char*) &(bmih.biClrImportant) , sizeof(ebmpDWORD) , 1 , fp);
+
+ if( IsBigEndian() )
+ { bmih.SwitchEndianess(); }
+
+ // a safety catch: if any of the header information didn't read properly, abort
+ // future idea: check to see if at least most is self-consistent
+
+ if( !NotCorrupted )
+ {
+ if( EasyBMPwarnings )
+ {
+ cout << "EasyBMP Error: " << FileName
+ << " is obviously corrupted." << endl;
+ }
+ SetSize(1,1);
+ SetBitDepth(1);
+ fclose(fp);
+ return false;
+ }
+
+ XPelsPerMeter = bmih.biXPelsPerMeter;
+ YPelsPerMeter = bmih.biYPelsPerMeter;
+
+ // if bmih.biCompression 1 or 2, then the file is RLE compressed
+
+ if( bmih.biCompression == 1 || bmih.biCompression == 2 )
+ {
+ if( EasyBMPwarnings )
+ {
+ cout << "EasyBMP Error: " << FileName << " is (RLE) compressed." << endl
+ << " EasyBMP does not support compression." << endl;
+ }
+ SetSize(1,1);
+ SetBitDepth(1);
+ fclose(fp);
+ return false;
+ }
+
+ // if bmih.biCompression > 3, then something strange is going on
+ // it's probably an OS2 bitmap file.
+
+ if( bmih.biCompression > 3 )
+ {
+ if( EasyBMPwarnings )
+ {
+ cout << "EasyBMP Error: " << FileName << " is in an unsupported format."
+ << endl
+ << " (bmih.biCompression = "
+ << bmih.biCompression << ")" << endl
+ << " The file is probably an old OS2 bitmap or corrupted."
+ << endl;
+ }
+ SetSize(1,1);
+ SetBitDepth(1);
+ fclose(fp);
+ return false;
+ }
+
+ if( bmih.biCompression == 3 && bmih.biBitCount != 16 )
+ {
+ if( EasyBMPwarnings )
+ {
+ cout << "EasyBMP Error: " << FileName
+ << " uses bit fields and is not a" << endl
+ << " 16-bit file. This is not supported." << endl;
+ }
+ SetSize(1,1);
+ SetBitDepth(1);
+ fclose(fp);
+ return false;
+ }
+
+ // set the bit depth
+
+ int TempBitDepth = (int) bmih.biBitCount;
+ if( TempBitDepth != 1 && TempBitDepth != 4
+ && TempBitDepth != 8 && TempBitDepth != 16
+ && TempBitDepth != 24 && TempBitDepth != 32 )
+ {
+ if( EasyBMPwarnings )
+ {
+ cout << "EasyBMP Error: " << FileName << " has unrecognized bit depth." << endl;
+ }
+ SetSize(1,1);
+ SetBitDepth(1);
+ fclose(fp);
+ return false;
+ }
+ SetBitDepth( (int) bmih.biBitCount );
+
+ // set the size
+
+ if( (int) bmih.biWidth <= 0 || (int) bmih.biHeight <= 0 )
+ {
+ if( EasyBMPwarnings )
+ {
+ cout << "EasyBMP Error: " << FileName
+ << " has a non-positive width or height." << endl;
+ }
+ SetSize(1,1);
+ SetBitDepth(1);
+ fclose(fp);
+ return false;
+ }
+ SetSize( (int) bmih.biWidth , (int) bmih.biHeight );
+
+ // some preliminaries
+
+ double dBytesPerPixel = ( (double) BitDepth ) / 8.0;
+ double dBytesPerRow = dBytesPerPixel * (Width+0.0);
+ dBytesPerRow = ceil(dBytesPerRow);
+
+ int BytePaddingPerRow = 4 - ( (int) (dBytesPerRow) )% 4;
+ if( BytePaddingPerRow == 4 )
+ { BytePaddingPerRow = 0; }
+
+ // if < 16 bits, read the palette
+
+ if( BitDepth < 16 )
+ {
+ // determine the number of colors specified in the
+ // color table
+
+ int NumberOfColorsToRead = ((int) bmfh.bfOffBits - 54 )/4;
+ if( NumberOfColorsToRead > IntPow(2,BitDepth) )
+ { NumberOfColorsToRead = IntPow(2,BitDepth); }
+
+ if( NumberOfColorsToRead < TellNumberOfColors() )
+ {
+ if( EasyBMPwarnings )
+ {
+ cout << "EasyBMP Warning: file " << FileName << " has an underspecified" << endl
+ << " color table. The table will be padded with extra" << endl
+ << " white (255,255,255,0) entries." << endl;
+ }
+ }
+
+ int n;
+ for( n=0; n < NumberOfColorsToRead ; n++ )
+ {
+ SafeFread( (char*) &(Colors[n]) , 4 , 1 , fp);
+ }
+ for( n=NumberOfColorsToRead ; n < TellNumberOfColors() ; n++ )
+ {
+ RGBApixel WHITE;
+ WHITE.Red = 255;
+ WHITE.Green = 255;
+ WHITE.Blue = 255;
+ WHITE.Alpha = 0;
+ SetColor( n , WHITE );
+ }
+
+
+ }
+
+ // skip blank data if bfOffBits so indicates
+
+ int BytesToSkip = bmfh.bfOffBits - 54;;
+ if( BitDepth < 16 )
+ { BytesToSkip -= 4*IntPow(2,BitDepth); }
+ if( BitDepth == 16 && bmih.biCompression == 3 )
+ { BytesToSkip -= 3*4; }
+ if( BytesToSkip < 0 )
+ { BytesToSkip = 0; }
+ if( BytesToSkip > 0 && BitDepth != 16 )
+ {
+ if( EasyBMPwarnings )
+ {
+ cout << "EasyBMP Warning: Extra meta data detected in file " << FileName << endl
+ << " Data will be skipped." << endl;
+ }
+ ebmpBYTE* TempSkipBYTE;
+ TempSkipBYTE = new ebmpBYTE [BytesToSkip];
+ SafeFread( (char*) TempSkipBYTE , BytesToSkip , 1 , fp);
+ delete [] TempSkipBYTE;
+ }
+
+ // This code reads 1, 4, 8, 24, and 32-bpp files
+ // with a more-efficient buffered technique.
+
+ int i,j;
+ if( BitDepth != 16 )
+ {
+ int BufferSize = (int) ( (Width*BitDepth) / 8.0 );
+ while( 8*BufferSize < Width*BitDepth )
+ { BufferSize++; }
+ while( BufferSize % 4 )
+ { BufferSize++; }
+ ebmpBYTE* Buffer;
+ Buffer = new ebmpBYTE [BufferSize];
+ j= Height-1;
+ while( j > -1 )
+ {
+ int BytesRead = (int) fread( (char*) Buffer, 1, BufferSize, fp );
+ if( BytesRead < BufferSize )
+ {
+ j = -1;
+ if( EasyBMPwarnings )
+ {
+ cout << "EasyBMP Error: Could not read proper amount of data." << endl;
+ }
+ }
+ else
+ {
+ bool Success = false;
+ if( BitDepth == 1 )
+ { Success = Read1bitRow( Buffer, BufferSize, j ); }
+ if( BitDepth == 4 )
+ { Success = Read4bitRow( Buffer, BufferSize, j ); }
+ if( BitDepth == 8 )
+ { Success = Read8bitRow( Buffer, BufferSize, j ); }
+ if( BitDepth == 24 )
+ { Success = Read24bitRow( Buffer, BufferSize, j ); }
+ if( BitDepth == 32 )
+ { Success = Read32bitRow( Buffer, BufferSize, j ); }
+ if( !Success )
+ {
+ if( EasyBMPwarnings )
+ {
+ cout << "EasyBMP Error: Could not read enough pixel data!" << endl;
+ }
+ j = -1;
+ }
+ }
+ j--;
+ }
+ delete [] Buffer;
+ }
+
+ if( BitDepth == 16 )
+ {
+ int DataBytes = Width*2;
+ int PaddingBytes = ( 4 - DataBytes % 4 ) % 4;
+
+ // set the default mask
+
+ ebmpWORD BlueMask = 31; // bits 12-16
+ ebmpWORD GreenMask = 992; // bits 7-11
+ ebmpWORD RedMask = 31744; // bits 2-6
+
+ // read the bit fields, if necessary, to
+ // override the default 5-5-5 mask
+
+ if( bmih.biCompression != 0 )
+ {
+ // read the three bit masks
+
+ ebmpWORD TempMaskWORD;
+ ebmpWORD ZeroWORD=0;
+
+ SafeFread( (char*) &RedMask , 2 , 1 , fp );
+ if( IsBigEndian() )
+ { RedMask = FlipWORD(RedMask); }
+ SafeFread( (char*) &TempMaskWORD , 2, 1, fp );
+
+ SafeFread( (char*) &GreenMask , 2 , 1 , fp );
+ if( IsBigEndian() )
+ { GreenMask = FlipWORD(GreenMask); }
+ SafeFread( (char*) &TempMaskWORD , 2, 1, fp );
+
+ SafeFread( (char*) &BlueMask , 2 , 1 , fp );
+ if( IsBigEndian() )
+ { BlueMask = FlipWORD(BlueMask); }
+ SafeFread( (char*) &TempMaskWORD , 2, 1, fp );
+ }
+
+ // read and skip any meta data
+
+ if( BytesToSkip > 0 )
+ {
+ if( EasyBMPwarnings )
+ {
+ cout << "EasyBMP Warning: Extra meta data detected in file "
+ << FileName << endl
+ << " Data will be skipped." << endl;
+ }
+ ebmpBYTE* TempSkipBYTE;
+ TempSkipBYTE = new ebmpBYTE [BytesToSkip];
+ SafeFread( (char*) TempSkipBYTE , BytesToSkip , 1 , fp);
+ delete [] TempSkipBYTE;
+ }
+
+ // determine the red, green and blue shifts
+
+ int GreenShift = 0;
+ ebmpWORD TempShiftWORD = GreenMask;
+ while( TempShiftWORD > 31 )
+ { TempShiftWORD = TempShiftWORD>>1; GreenShift++; }
+ int BlueShift = 0;
+ TempShiftWORD = BlueMask;
+ while( TempShiftWORD > 31 )
+ { TempShiftWORD = TempShiftWORD>>1; BlueShift++; }
+ int RedShift = 0;
+ TempShiftWORD = RedMask;
+ while( TempShiftWORD > 31 )
+ { TempShiftWORD = TempShiftWORD>>1; RedShift++; }
+
+ // read the actual pixels
+
+ for( j=Height-1 ; j >= 0 ; j-- )
+ {
+ i=0;
+ int ReadNumber = 0;
+ while( ReadNumber < DataBytes )
+ {
+ ebmpWORD TempWORD;
+ SafeFread( (char*) &TempWORD , 2 , 1 , fp );
+ if( IsBigEndian() )
+ { TempWORD = FlipWORD(TempWORD); }
+ ReadNumber += 2;
+
+ ebmpWORD Red = RedMask & TempWORD;
+ ebmpWORD Green = GreenMask & TempWORD;
+ ebmpWORD Blue = BlueMask & TempWORD;
+
+ ebmpBYTE BlueBYTE = (ebmpBYTE) 8*(Blue>>BlueShift);
+ ebmpBYTE GreenBYTE = (ebmpBYTE) 8*(Green>>GreenShift);
+ ebmpBYTE RedBYTE = (ebmpBYTE) 8*(Red>>RedShift);
+
+ (Pixels[i][j]).Red = RedBYTE;
+ (Pixels[i][j]).Green = GreenBYTE;
+ (Pixels[i][j]).Blue = BlueBYTE;
+
+ i++;
+ }
+ ReadNumber = 0;
+ while( ReadNumber < PaddingBytes )
+ {
+ ebmpBYTE TempBYTE;
+ SafeFread( (char*) &TempBYTE , 1, 1, fp);
+ ReadNumber++;
+ }
+ }
+
+ }
+
+ fclose(fp);
+ return true;
+}
+
+bool BMP::CreateStandardColorTable( void )
+{
+ using namespace std;
+ if( BitDepth != 1 && BitDepth != 4 && BitDepth != 8 )
+ {
+ if( EasyBMPwarnings )
+ {
+ cout << "EasyBMP Warning: Attempted to create color table at a bit" << endl
+ << " depth that does not require a color table." << endl
+ << " Ignoring request." << endl;
+ }
+ return false;
+ }
+
+ if( BitDepth == 1 )
+ {
+ int i;
+ for( i=0 ; i < 2 ; i++ )
+ {
+ Colors[i].Red = i*255;
+ Colors[i].Green = i*255;
+ Colors[i].Blue = i*255;
+ Colors[i].Alpha = 0;
+ }
+ return true;
+ }
+
+ if( BitDepth == 4 )
+ {
+ int i = 0;
+ int j,k,ell;
+
+ // simplify the code for the first 8 colors
+ for( ell=0 ; ell < 2 ; ell++ )
+ {
+ for( k=0 ; k < 2 ; k++ )
+ {
+ for( j=0 ; j < 2 ; j++ )
+ {
+ Colors[i].Red = j*128;
+ Colors[i].Green = k*128;
+ Colors[i].Blue = ell*128;
+ i++;
+ }
+ }
+ }
+
+ // simplify the code for the last 8 colors
+ for( ell=0 ; ell < 2 ; ell++ )
+ {
+ for( k=0 ; k < 2 ; k++ )
+ {
+ for( j=0 ; j < 2 ; j++ )
+ {
+ Colors[i].Red = j*255;
+ Colors[i].Green = k*255;
+ Colors[i].Blue = ell*255;
+ i++;
+ }
+ }
+ }
+
+ // overwrite the duplicate color
+ i=8;
+ Colors[i].Red = 192;
+ Colors[i].Green = 192;
+ Colors[i].Blue = 192;
+
+ for( i=0 ; i < 16 ; i++ )
+ { Colors[i].Alpha = 0; }
+ return true;
+ }
+
+ if( BitDepth == 8 )
+ {
+ int i=0;
+ int j,k,ell;
+
+ // do an easy loop, which works for all but colors
+ // 0 to 9 and 246 to 255
+ for( ell=0 ; ell < 4 ; ell++ )
+ {
+ for( k=0 ; k < 8 ; k++ )
+ {
+ for( j=0; j < 8 ; j++ )
+ {
+ Colors[i].Red = j*32;
+ Colors[i].Green = k*32;
+ Colors[i].Blue = ell*64;
+ Colors[i].Alpha = 0;
+ i++;
+ }
+ }
+ }
+
+ // now redo the first 8 colors
+ i=0;
+ for( ell=0 ; ell < 2 ; ell++ )
+ {
+ for( k=0 ; k < 2 ; k++ )
+ {
+ for( j=0; j < 2 ; j++ )
+ {
+ Colors[i].Red = j*128;
+ Colors[i].Green = k*128;
+ Colors[i].Blue = ell*128;
+ i++;
+ }
+ }
+ }
+
+ // overwrite colors 7, 8, 9
+ i=7;
+ Colors[i].Red = 192;
+ Colors[i].Green = 192;
+ Colors[i].Blue = 192;
+ i++; // 8
+ Colors[i].Red = 192;
+ Colors[i].Green = 220;
+ Colors[i].Blue = 192;
+ i++; // 9
+ Colors[i].Red = 166;
+ Colors[i].Green = 202;
+ Colors[i].Blue = 240;
+
+ // overwrite colors 246 to 255
+ i=246;
+ Colors[i].Red = 255;
+ Colors[i].Green = 251;
+ Colors[i].Blue = 240;
+ i++; // 247
+ Colors[i].Red = 160;
+ Colors[i].Green = 160;
+ Colors[i].Blue = 164;
+ i++; // 248
+ Colors[i].Red = 128;
+ Colors[i].Green = 128;
+ Colors[i].Blue = 128;
+ i++; // 249
+ Colors[i].Red = 255;
+ Colors[i].Green = 0;
+ Colors[i].Blue = 0;
+ i++; // 250
+ Colors[i].Red = 0;
+ Colors[i].Green = 255;
+ Colors[i].Blue = 0;
+ i++; // 251
+ Colors[i].Red = 255;
+ Colors[i].Green = 255;
+ Colors[i].Blue = 0;
+ i++; // 252
+ Colors[i].Red = 0;
+ Colors[i].Green = 0;
+ Colors[i].Blue = 255;
+ i++; // 253
+ Colors[i].Red = 255;
+ Colors[i].Green = 0;
+ Colors[i].Blue = 255;
+ i++; // 254
+ Colors[i].Red = 0;
+ Colors[i].Green = 255;
+ Colors[i].Blue = 255;
+ i++; // 255
+ Colors[i].Red = 255;
+ Colors[i].Green = 255;
+ Colors[i].Blue = 255;
+
+ return true;
+ }
+ return true;
+}
+
+bool SafeFread( char* buffer, int size, int number, FILE* fp )
+{
+ using namespace std;
+ int ItemsRead;
+ if( feof(fp) )
+ { return false; }
+ ItemsRead = (int) fread( buffer , size , number , fp );
+ if( ItemsRead < number )
+ { return false; }
+ return true;
+}
+
+void BMP::SetDPI( int HorizontalDPI, int VerticalDPI )
+{
+ XPelsPerMeter = (int) ( HorizontalDPI * 39.37007874015748 );
+ YPelsPerMeter = (int) ( VerticalDPI * 39.37007874015748 );
+}
+
+// int BMP::TellVerticalDPI( void ) const
+int BMP::TellVerticalDPI( void )
+{
+ if( !YPelsPerMeter )
+ { YPelsPerMeter = DefaultYPelsPerMeter; }
+ return (int) ( YPelsPerMeter / (double) 39.37007874015748 );
+}
+
+// int BMP::TellHorizontalDPI( void ) const
+int BMP::TellHorizontalDPI( void )
+{
+ if( !XPelsPerMeter )
+ { XPelsPerMeter = DefaultXPelsPerMeter; }
+ return (int) ( XPelsPerMeter / (double) 39.37007874015748 );
+}
+
+/* These functions are defined in EasyBMP_VariousBMPutilities.h */
+
+BMFH GetBMFH( const char* szFileNameIn )
+{
+ using namespace std;
+ BMFH bmfh;
+
+ FILE* fp;
+ fp = fopen( szFileNameIn,"rb");
+
+ if( !fp )
+ {
+ if( EasyBMPwarnings )
+ {
+ cout << "EasyBMP Error: Cannot initialize from file "
+ << szFileNameIn << "." << endl
+ << " File cannot be opened or does not exist."
+ << endl;
+ }
+ bmfh.bfType = 0;
+ return bmfh;
+ }
+
+ SafeFread( (char*) &(bmfh.bfType) , sizeof(ebmpWORD) , 1 , fp );
+ SafeFread( (char*) &(bmfh.bfSize) , sizeof(ebmpDWORD) , 1 , fp );
+ SafeFread( (char*) &(bmfh.bfReserved1) , sizeof(ebmpWORD) , 1 , fp );
+ SafeFread( (char*) &(bmfh.bfReserved2) , sizeof(ebmpWORD) , 1 , fp );
+ SafeFread( (char*) &(bmfh.bfOffBits) , sizeof(ebmpDWORD) , 1 , fp );
+
+ fclose( fp );
+
+ if( IsBigEndian() )
+ { bmfh.SwitchEndianess(); }
+
+ return bmfh;
+}
+
+BMIH GetBMIH( const char* szFileNameIn )
+{
+ using namespace std;
+ BMFH bmfh;
+ BMIH bmih;
+
+ FILE* fp;
+ fp = fopen( szFileNameIn,"rb");
+
+ if( !fp )
+ {
+ if( EasyBMPwarnings )
+ {
+ cout << "EasyBMP Error: Cannot initialize from file "
+ << szFileNameIn << "." << endl
+ << " File cannot be opened or does not exist."
+ << endl;
+ }
+ return bmih;
+ }
+
+ // read the bmfh, i.e., first 14 bytes (just to get it out of the way);
+
+ ebmpBYTE TempBYTE;
+ int i;
+ for( i = 14 ; i > 0 ; i-- )
+ { SafeFread( (char*) &TempBYTE , sizeof(ebmpBYTE) , 1, fp ); }
+
+ // read the bmih
+
+ SafeFread( (char*) &(bmih.biSize) , sizeof(ebmpDWORD) , 1 , fp );
+ SafeFread( (char*) &(bmih.biWidth) , sizeof(ebmpDWORD) , 1 , fp );
+ SafeFread( (char*) &(bmih.biHeight) , sizeof(ebmpDWORD) , 1 , fp );
+ SafeFread( (char*) &(bmih.biPlanes) , sizeof(ebmpWORD) , 1 , fp );
+
+ SafeFread( (char*) &(bmih.biBitCount) , sizeof(ebmpWORD) , 1 , fp );
+ SafeFread( (char*) &(bmih.biCompression) , sizeof(ebmpDWORD) , 1 , fp );
+ SafeFread( (char*) &(bmih.biSizeImage) , sizeof(ebmpDWORD) , 1 , fp );
+ SafeFread( (char*) &(bmih.biXPelsPerMeter) , sizeof(ebmpDWORD) , 1 , fp );
+
+ SafeFread( (char*) &(bmih.biYPelsPerMeter) , sizeof(ebmpDWORD) , 1 , fp );
+ SafeFread( (char*) &(bmih.biClrUsed) , sizeof(ebmpDWORD) , 1 , fp );
+ SafeFread( (char*) &(bmih.biClrImportant) , sizeof(ebmpDWORD) , 1 , fp );
+
+ fclose( fp );
+
+ if( IsBigEndian() )
+ { bmih.SwitchEndianess(); }
+
+ return bmih;
+}
+
+void DisplayBitmapInfo( const char* szFileNameIn )
+{
+ using namespace std;
+ FILE* fp;
+ fp = fopen( szFileNameIn,"rb");
+
+ if( !fp )
+ {
+ if( EasyBMPwarnings )
+ {
+ cout << "EasyBMP Error: Cannot initialize from file "
+ << szFileNameIn << "." << endl
+ << " File cannot be opened or does not exist."
+ << endl;
+ }
+ return;
+ }
+ fclose( fp );
+
+ // don't duplicate work! Just use the functions from above!
+
+ BMFH bmfh = GetBMFH(szFileNameIn);
+ BMIH bmih = GetBMIH(szFileNameIn);
+
+ cout << "File information for file " << szFileNameIn
+ << ":" << endl << endl;
+
+ cout << "BITMAPFILEHEADER:" << endl
+ << "bfType: " << bmfh.bfType << endl
+ << "bfSize: " << bmfh.bfSize << endl
+ << "bfReserved1: " << bmfh.bfReserved1 << endl
+ << "bfReserved2: " << bmfh.bfReserved2 << endl
+ << "bfOffBits: " << bmfh.bfOffBits << endl << endl;
+
+ cout << "BITMAPINFOHEADER:" << endl
+ << "biSize: " << bmih.biSize << endl
+ << "biWidth: " << bmih.biWidth << endl
+ << "biHeight: " << bmih.biHeight << endl
+ << "biPlanes: " << bmih.biPlanes << endl
+ << "biBitCount: " << bmih.biBitCount << endl
+ << "biCompression: " << bmih.biCompression << endl
+ << "biSizeImage: " << bmih.biSizeImage << endl
+ << "biXPelsPerMeter: " << bmih.biXPelsPerMeter << endl
+ << "biYPelsPerMeter: " << bmih.biYPelsPerMeter << endl
+ << "biClrUsed: " << bmih.biClrUsed << endl
+ << "biClrImportant: " << bmih.biClrImportant << endl << endl;
+ return;
+}
+
+int GetBitmapColorDepth( const char* szFileNameIn )
+{
+ BMIH bmih = GetBMIH( szFileNameIn );
+ return (int) bmih.biBitCount;
+}
+
+void PixelToPixelCopy( BMP& From, int FromX, int FromY,
+ BMP& To, int ToX, int ToY)
+{
+ *To(ToX,ToY) = *From(FromX,FromY);
+ return;
+}
+
+void PixelToPixelCopyTransparent( BMP& From, int FromX, int FromY,
+ BMP& To, int ToX, int ToY,
+ RGBApixel& Transparent )
+{
+ if( From(FromX,FromY)->Red != Transparent.Red ||
+ From(FromX,FromY)->Green != Transparent.Green ||
+ From(FromX,FromY)->Blue != Transparent.Blue )
+ { *To(ToX,ToY) = *From(FromX,FromY); }
+ return;
+}
+
+void RangedPixelToPixelCopy( BMP& From, int FromL , int FromR, int FromB, int FromT,
+ BMP& To, int ToX, int ToY )
+{
+ // make sure the conventions are followed
+ if( FromB < FromT )
+ { int Temp = FromT; FromT = FromB; FromB = Temp; }
+
+ // make sure that the copied regions exist in both bitmaps
+ if( FromR >= From.TellWidth() )
+ { FromR = From.TellWidth()-1; }
+ if( FromL < 0 ){ FromL = 0; }
+
+ if( FromB >= From.TellHeight() )
+ { FromB = From.TellHeight()-1; }
+ if( FromT < 0 ){ FromT = 0; }
+
+ if( ToX+(FromR-FromL) >= To.TellWidth() )
+ { FromR = To.TellWidth()-1+FromL-ToX; }
+ if( ToY+(FromB-FromT) >= To.TellHeight() )
+ { FromB = To.TellHeight()-1+FromT-ToY; }
+
+ int i,j;
+ for( j=FromT ; j <= FromB ; j++ )
+ {
+ for( i=FromL ; i <= FromR ; i++ )
+ {
+ PixelToPixelCopy( From, i,j,
+ To, ToX+(i-FromL), ToY+(j-FromT) );
+ }
+ }
+
+ return;
+}
+
+void RangedPixelToPixelCopyTransparent(
+ BMP& From, int FromL , int FromR, int FromB, int FromT,
+ BMP& To, int ToX, int ToY ,
+ RGBApixel& Transparent )
+{
+ // make sure the conventions are followed
+ if( FromB < FromT )
+ { int Temp = FromT; FromT = FromB; FromB = Temp; }
+
+ // make sure that the copied regions exist in both bitmaps
+ if( FromR >= From.TellWidth() )
+ { FromR = From.TellWidth()-1; }
+ if( FromL < 0 ){ FromL = 0; }
+
+ if( FromB >= From.TellHeight() )
+ { FromB = From.TellHeight()-1; }
+ if( FromT < 0 ){ FromT = 0; }
+
+ if( ToX+(FromR-FromL) >= To.TellWidth() )
+ { FromR = To.TellWidth()-1+FromL-ToX; }
+ if( ToY+(FromB-FromT) >= To.TellHeight() )
+ { FromB = To.TellHeight()-1+FromT-ToY; }
+
+ int i,j;
+ for( j=FromT ; j <= FromB ; j++ )
+ {
+ for( i=FromL ; i <= FromR ; i++ )
+ {
+ PixelToPixelCopyTransparent( From, i,j,
+ To, ToX+(i-FromL), ToY+(j-FromT) ,
+ Transparent);
+ }
+ }
+
+ return;
+}
+
+bool CreateGrayscaleColorTable( BMP& InputImage )
+{
+ using namespace std;
+ int BitDepth = InputImage.TellBitDepth();
+ if( BitDepth != 1 && BitDepth != 4 && BitDepth != 8 )
+ {
+ if( EasyBMPwarnings )
+ {
+ cout << "EasyBMP Warning: Attempted to create color table at a bit" << endl
+ << " depth that does not require a color table." << endl
+ << " Ignoring request." << endl;
+ }
+ return false;
+ }
+ int i;
+ int NumberOfColors = InputImage.TellNumberOfColors();
+
+ ebmpBYTE StepSize;
+ if( BitDepth != 1 )
+ { StepSize = 255/(NumberOfColors-1); }
+ else
+ { StepSize = 255; }
+
+ for( i=0 ; i < NumberOfColors ; i++ )
+ {
+ ebmpBYTE TempBYTE = i*StepSize;
+ RGBApixel TempColor;
+ TempColor.Red = TempBYTE;
+ TempColor.Green = TempBYTE;
+ TempColor.Blue = TempBYTE;
+ TempColor.Alpha = 0;
+ InputImage.SetColor( i , TempColor );
+ }
+ return true;
+}
+
+bool BMP::Read32bitRow( ebmpBYTE* Buffer, int BufferSize, int Row )
+{
+ int i;
+ if( Width*4 > BufferSize )
+ { return false; }
+ for( i=0 ; i < Width ; i++ )
+ { memcpy( (char*) &(Pixels[i][Row]), (char*) Buffer+4*i, 4 ); }
+ return true;
+}
+
+bool BMP::Read24bitRow( ebmpBYTE* Buffer, int BufferSize, int Row )
+{
+ int i;
+ if( Width*3 > BufferSize )
+ { return false; }
+ for( i=0 ; i < Width ; i++ )
+ { memcpy( (char*) &(Pixels[i][Row]), Buffer+3*i, 3 ); }
+ return true;
+}
+
+bool BMP::Read8bitRow( ebmpBYTE* Buffer, int BufferSize, int Row )
+{
+ int i;
+ if( Width > BufferSize )
+ { return false; }
+ for( i=0 ; i < Width ; i++ )
+ {
+ int Index = Buffer[i];
+ *( this->operator()(i,Row) )= GetColor(Index);
+ }
+ return true;
+}
+
+bool BMP::Read4bitRow( ebmpBYTE* Buffer, int BufferSize, int Row )
+{
+ int Shifts[2] = {4 ,0 };
+ int Masks[2] = {240,15};
+
+ int i=0;
+ int j;
+ int k=0;
+ if( Width > 2*BufferSize )
+ { return false; }
+ while( i < Width )
+ {
+ j=0;
+ while( j < 2 && i < Width )
+ {
+ int Index = (int) ( (Buffer[k]&Masks[j]) >> Shifts[j]);
+ *( this->operator()(i,Row) )= GetColor(Index);
+ i++; j++;
+ }
+ k++;
+ }
+ return true;
+}
+bool BMP::Read1bitRow( ebmpBYTE* Buffer, int BufferSize, int Row )
+{
+ int Shifts[8] = {7 ,6 ,5 ,4 ,3,2,1,0};
+ int Masks[8] = {128,64,32,16,8,4,2,1};
+
+ int i=0;
+ int j;
+ int k=0;
+
+ if( Width > 8*BufferSize )
+ { return false; }
+ while( i < Width )
+ {
+ j=0;
+ while( j < 8 && i < Width )
+ {
+ int Index = (int) ( (Buffer[k]&Masks[j]) >> Shifts[j]);
+ *( this->operator()(i,Row) )= GetColor(Index);
+ i++; j++;
+ }
+ k++;
+ }
+ return true;
+}
+
+bool BMP::Write32bitRow( ebmpBYTE* Buffer, int BufferSize, int Row )
+{
+ int i;
+ if( Width*4 > BufferSize )
+ { return false; }
+ for( i=0 ; i < Width ; i++ )
+ { memcpy( (char*) Buffer+4*i, (char*) &(Pixels[i][Row]), 4 ); }
+ return true;
+}
+
+bool BMP::Write24bitRow( ebmpBYTE* Buffer, int BufferSize, int Row )
+{
+ int i;
+ if( Width*3 > BufferSize )
+ { return false; }
+ for( i=0 ; i < Width ; i++ )
+ { memcpy( (char*) Buffer+3*i, (char*) &(Pixels[i][Row]), 3 ); }
+ return true;
+}
+
+bool BMP::Write8bitRow( ebmpBYTE* Buffer, int BufferSize, int Row )
+{
+ int i;
+ if( Width > BufferSize )
+ { return false; }
+ for( i=0 ; i < Width ; i++ )
+ { Buffer[i] = FindClosestColor( Pixels[i][Row] ); }
+ return true;
+}
+
+bool BMP::Write4bitRow( ebmpBYTE* Buffer, int BufferSize, int Row )
+{
+ int PositionWeights[2] = {16,1};
+
+ int i=0;
+ int j;
+ int k=0;
+ if( Width > 2*BufferSize )
+ { return false; }
+ while( i < Width )
+ {
+ j=0;
+ int Index = 0;
+ while( j < 2 && i < Width )
+ {
+ Index += ( PositionWeights[j]* (int) FindClosestColor( Pixels[i][Row] ) );
+ i++; j++;
+ }
+ Buffer[k] = (ebmpBYTE) Index;
+ k++;
+ }
+ return true;
+}
+
+bool BMP::Write1bitRow( ebmpBYTE* Buffer, int BufferSize, int Row )
+{
+ int PositionWeights[8] = {128,64,32,16,8,4,2,1};
+
+ int i=0;
+ int j;
+ int k=0;
+ if( Width > 8*BufferSize )
+ { return false; }
+ while( i < Width )
+ {
+ j=0;
+ int Index = 0;
+ while( j < 8 && i < Width )
+ {
+ Index += ( PositionWeights[j]* (int) FindClosestColor( Pixels[i][Row] ) );
+ i++; j++;
+ }
+ Buffer[k] = (ebmpBYTE) Index;
+ k++;
+ }
+ return true;
+}
+
+ebmpBYTE BMP::FindClosestColor( RGBApixel& input )
+{
+ using namespace std;
+
+ int i=0;
+ int NumberOfColors = TellNumberOfColors();
+ ebmpBYTE BestI = 0;
+ int BestMatch = 999999;
+
+ while( i < NumberOfColors )
+ {
+ RGBApixel Attempt = GetColor( i );
+ int TempMatch = IntSquare( (int) Attempt.Red - (int) input.Red )
+ + IntSquare( (int) Attempt.Green - (int) input.Green )
+ + IntSquare( (int) Attempt.Blue - (int) input.Blue );
+ if( TempMatch < BestMatch )
+ { BestI = (ebmpBYTE) i; BestMatch = TempMatch; }
+ if( BestMatch < 1 )
+ { i = NumberOfColors; }
+ i++;
+ }
+ return BestI;
+}
+
+bool EasyBMPcheckDataSize( void )
+{
+ using namespace std;
+ bool ReturnValue = true;
+ if( sizeof( ebmpBYTE ) != 1 )
+ {
+ if( EasyBMPwarnings )
+ {
+ cout << "EasyBMP Error: ebmpBYTE has the wrong size ("
+ << sizeof( ebmpBYTE ) << " bytes)," << endl
+ << " Compared to the expected 1 byte value" << endl;
+ }
+ ReturnValue = false;
+ }
+ if( sizeof( ebmpWORD ) != 2 )
+ {
+ if( EasyBMPwarnings )
+ {
+ cout << "EasyBMP Error: ebmpWORD has the wrong size ("
+ << sizeof( ebmpWORD ) << " bytes)," << endl
+ << " Compared to the expected 2 byte value" << endl;
+ }
+ ReturnValue = false;
+ }
+ if( sizeof( ebmpDWORD ) != 4 )
+ {
+ if( EasyBMPwarnings )
+ {
+ cout << "EasyBMP Error: ebmpDWORD has the wrong size ("
+ << sizeof( ebmpDWORD ) << " bytes)," << endl
+ << " Compared to the expected 4 byte value" << endl;
+ }
+ ReturnValue = false;
+ }
+ return ReturnValue;
+}
+
+bool Rescale( BMP& InputImage , char mode, ScaleParam scale )
+{
+ using namespace std;
+ int CapMode = toupper( mode );
+
+ BMP OldImage( InputImage );
+
+ if( CapMode != 'P' &&
+ CapMode != 'W' &&
+ CapMode != 'H' &&
+ CapMode != 'F' &&
+ CapMode != 'D' )
+ {
+ if( EasyBMPwarnings )
+ {
+ char ErrorMessage [1024];
+ sprintf( ErrorMessage, "EasyBMP Error: Unknown rescale mode %c requested\n" , mode );
+ cout << ErrorMessage;
+ }
+ return false;
+ }
+
+ int NewWidth =0;
+ int NewHeight =0;
+
+ int OldWidth = OldImage.TellWidth();
+ int OldHeight= OldImage.TellHeight();
+
+ if( CapMode == 'P' )
+ {
+ NewWidth = (int) floor( OldWidth * scale.ratio / 100.0 );
+ NewHeight = (int) floor( OldHeight * scale.ratio / 100.0 );
+ }
+ if( CapMode == 'F' )
+ {
+ if( OldWidth > OldHeight )
+ { CapMode = 'W'; }
+ else
+ { CapMode = 'H'; }
+ }
+
+ if( CapMode == 'W' )
+ {
+ double percent = (double) scale.keepsize / (double) OldWidth;
+ NewWidth = scale.keepsize;
+ NewHeight = (int) floor( OldHeight * percent );
+ }
+ if( CapMode == 'H' )
+ {
+ double percent = (double) scale.keepsize / (double) OldHeight;
+ NewHeight = scale.keepsize;
+ NewWidth = (int) floor( OldWidth * percent );
+ }
+
+ if( CapMode == 'D')
+ {
+ NewWidth = scale.dimension.width;
+ NewHeight = scale.dimension.height;
+ }
+
+ if( NewWidth < 1 )
+ { NewWidth = 1; }
+ if( NewHeight < 1 )
+ { NewHeight = 1; }
+
+ InputImage.SetSize( NewWidth, NewHeight );
+ InputImage.SetBitDepth( 24 );
+
+ int I,J;
+ double ThetaI,ThetaJ;
+
+ for( int j=0; j < NewHeight-1 ; j++ )
+ {
+ ThetaJ = (double)(j*(OldHeight-1.0))
+ /(double)(NewHeight-1.0);
+ J = (int) floor( ThetaJ );
+ ThetaJ -= J;
+
+ for( int i=0; i < NewWidth-1 ; i++ )
+ {
+ ThetaI = (double)(i*(OldWidth-1.0))
+ /(double)(NewWidth-1.0);
+ I = (int) floor( ThetaI );
+ ThetaI -= I;
+
+ InputImage(i,j)->Red = (ebmpBYTE)
+ ( (1.0-ThetaI-ThetaJ+ThetaI*ThetaJ)*(OldImage(I,J)->Red)
+ +(ThetaI-ThetaI*ThetaJ)*(OldImage(I+1,J)->Red)
+ +(ThetaJ-ThetaI*ThetaJ)*(OldImage(I,J+1)->Red)
+ +(ThetaI*ThetaJ)*(OldImage(I+1,J+1)->Red) );
+ InputImage(i,j)->Green = (ebmpBYTE)
+ ( (1.0-ThetaI-ThetaJ+ThetaI*ThetaJ)*OldImage(I,J)->Green
+ +(ThetaI-ThetaI*ThetaJ)*OldImage(I+1,J)->Green
+ +(ThetaJ-ThetaI*ThetaJ)*OldImage(I,J+1)->Green
+ +(ThetaI*ThetaJ)*OldImage(I+1,J+1)->Green );
+ InputImage(i,j)->Blue = (ebmpBYTE)
+ ( (1.0-ThetaI-ThetaJ+ThetaI*ThetaJ)*OldImage(I,J)->Blue
+ +(ThetaI-ThetaI*ThetaJ)*OldImage(I+1,J)->Blue
+ +(ThetaJ-ThetaI*ThetaJ)*OldImage(I,J+1)->Blue
+ +(ThetaI*ThetaJ)*OldImage(I+1,J+1)->Blue );
+ }
+ InputImage(NewWidth-1,j)->Red = (ebmpBYTE)
+ ( (1.0-ThetaJ)*(OldImage(OldWidth-1,J)->Red)
+ + ThetaJ*(OldImage(OldWidth-1,J+1)->Red) );
+ InputImage(NewWidth-1,j)->Green = (ebmpBYTE)
+ ( (1.0-ThetaJ)*(OldImage(OldWidth-1,J)->Green)
+ + ThetaJ*(OldImage(OldWidth-1,J+1)->Green) );
+ InputImage(NewWidth-1,j)->Blue = (ebmpBYTE)
+ ( (1.0-ThetaJ)*(OldImage(OldWidth-1,J)->Blue)
+ + ThetaJ*(OldImage(OldWidth-1,J+1)->Blue) );
+ }
+
+ for( int i=0 ; i < NewWidth-1 ; i++ )
+ {
+ ThetaI = (double)(i*(OldWidth-1.0))
+ /(double)(NewWidth-1.0);
+ I = (int) floor( ThetaI );
+ ThetaI -= I;
+ InputImage(i,NewHeight-1)->Red = (ebmpBYTE)
+ ( (1.0-ThetaI)*(OldImage(I,OldHeight-1)->Red)
+ + ThetaI*(OldImage(I,OldHeight-1)->Red) );
+ InputImage(i,NewHeight-1)->Green = (ebmpBYTE)
+ ( (1.0-ThetaI)*(OldImage(I,OldHeight-1)->Green)
+ + ThetaI*(OldImage(I,OldHeight-1)->Green) );
+ InputImage(i,NewHeight-1)->Blue = (ebmpBYTE)
+ ( (1.0-ThetaI)*(OldImage(I,OldHeight-1)->Blue)
+ + ThetaI*(OldImage(I,OldHeight-1)->Blue) );
+ }
+
+ *InputImage(NewWidth-1,NewHeight-1) = *OldImage(OldWidth-1,OldHeight-1);
+ return true;
+}
diff --git a/utility/demo-fw/pc-tools/CreateDemoBin/lib/EasyBMP/EasyBMP.h b/utility/demo-fw/pc-tools/CreateDemoBin/lib/EasyBMP/EasyBMP.h
new file mode 100644
index 0000000..52012db
--- /dev/null
+++ b/utility/demo-fw/pc-tools/CreateDemoBin/lib/EasyBMP/EasyBMP.h
@@ -0,0 +1,86 @@
+/*************************************************
+* *
+* EasyBMP Cross-Platform Windows Bitmap Library *
+* *
+* Author: Paul Macklin *
+* email: macklin01@users.sourceforge.net *
+* support: http://easybmp.sourceforge.net *
+* *
+* file: EasyBMP.h *
+* date added: 01-31-2005 *
+* date modified: 12-01-2006 *
+* version: 1.06 *
+* *
+* License: BSD (revised/modified) *
+* Copyright: 2005-6 by the EasyBMP Project *
+* *
+* description: Main include file *
+* *
+*************************************************/
+
+#ifdef _MSC_VER
+// MS Visual Studio gives warnings when using
+// fopen. But fopen_s is not going to work well
+// with most compilers, and fopen_s uses different
+// syntax than fopen. (i.e., a macro won't work)
+// So, we'lll use this:
+#define _CRT_SECURE_NO_DEPRECATE
+#endif
+
+#include <iostream>
+#include <cmath>
+#include <cctype>
+#include <cstring>
+
+#ifndef EasyBMP
+#define EasyBMP
+
+#ifdef __BCPLUSPLUS__
+// The Borland compiler must use this because something
+// is wrong with their cstdio file.
+#include <stdio.h>
+#else
+#include <cstdio>
+#endif
+
+#ifdef __GNUC__
+// If g++ specific code is ever required, this is
+// where it goes.
+#endif
+
+#ifdef __INTEL_COMPILER
+// If Intel specific code is ever required, this is
+// where it goes.
+#endif
+
+#ifndef _DefaultXPelsPerMeter_
+#define _DefaultXPelsPerMeter_
+#define DefaultXPelsPerMeter 3780
+// set to a default of 96 dpi
+#endif
+
+#ifndef _DefaultYPelsPerMeter_
+#define _DefaultYPelsPerMeter_
+#define DefaultYPelsPerMeter 3780
+// set to a default of 96 dpi
+#endif
+
+#include "EasyBMP_DataStructures.h"
+#include "EasyBMP_BMP.h"
+#include "EasyBMP_VariousBMPutilities.h"
+
+#ifndef _EasyBMP_Version_
+#define _EasyBMP_Version_ 1.06
+#define _EasyBMP_Version_Integer_ 106
+#define _EasyBMP_Version_String_ "1.06"
+#endif
+
+#ifndef _EasyBMPwarnings_
+#define _EasyBMPwarnings_
+#endif
+
+void SetEasyBMPwarningsOff( void );
+void SetEasyBMPwarningsOn( void );
+bool GetEasyBMPwarningState( void );
+
+#endif
diff --git a/utility/demo-fw/pc-tools/CreateDemoBin/lib/EasyBMP/EasyBMP_BMP.h b/utility/demo-fw/pc-tools/CreateDemoBin/lib/EasyBMP/EasyBMP_BMP.h
new file mode 100644
index 0000000..7161435
--- /dev/null
+++ b/utility/demo-fw/pc-tools/CreateDemoBin/lib/EasyBMP/EasyBMP_BMP.h
@@ -0,0 +1,86 @@
+/*************************************************
+* *
+* EasyBMP Cross-Platform Windows Bitmap Library *
+* *
+* Author: Paul Macklin *
+* email: macklin01@users.sourceforge.net *
+* support: http://easybmp.sourceforge.net *
+* *
+* file: EasyBMP_VariousBMPutilities.h *
+* date added: 05-02-2005 *
+* date modified: 12-01-2006 *
+* version: 1.06 *
+* *
+* License: BSD (revised/modified) *
+* Copyright: 2005-6 by the EasyBMP Project *
+* *
+* description: Defines BMP class *
+* *
+*************************************************/
+
+#ifndef _EasyBMP_BMP_h_
+#define _EasyBMP_BMP_h_
+
+bool SafeFread( char* buffer, int size, int number, FILE* fp );
+bool EasyBMPcheckDataSize( void );
+
+class BMP
+{private:
+
+ int BitDepth;
+ int Width;
+ int Height;
+ RGBApixel** Pixels;
+ RGBApixel* Colors;
+ int XPelsPerMeter;
+ int YPelsPerMeter;
+
+ ebmpBYTE* MetaData1;
+ int SizeOfMetaData1;
+ ebmpBYTE* MetaData2;
+ int SizeOfMetaData2;
+
+ bool Read32bitRow( ebmpBYTE* Buffer, int BufferSize, int Row );
+ bool Read24bitRow( ebmpBYTE* Buffer, int BufferSize, int Row );
+ bool Read8bitRow( ebmpBYTE* Buffer, int BufferSize, int Row );
+ bool Read4bitRow( ebmpBYTE* Buffer, int BufferSize, int Row );
+ bool Read1bitRow( ebmpBYTE* Buffer, int BufferSize, int Row );
+
+ bool Write32bitRow( ebmpBYTE* Buffer, int BufferSize, int Row );
+ bool Write24bitRow( ebmpBYTE* Buffer, int BufferSize, int Row );
+ bool Write8bitRow( ebmpBYTE* Buffer, int BufferSize, int Row );
+ bool Write4bitRow( ebmpBYTE* Buffer, int BufferSize, int Row );
+ bool Write1bitRow( ebmpBYTE* Buffer, int BufferSize, int Row );
+
+ ebmpBYTE FindClosestColor( RGBApixel& input );
+
+ public:
+
+ int TellBitDepth( void );
+ int TellWidth( void );
+ int TellHeight( void );
+ int TellNumberOfColors( void );
+ void SetDPI( int HorizontalDPI, int VerticalDPI );
+ int TellVerticalDPI( void );
+ int TellHorizontalDPI( void );
+
+ BMP();
+ BMP( BMP& Input );
+ ~BMP();
+ RGBApixel* operator()(int i,int j);
+
+ RGBApixel GetPixel( int i, int j ) const;
+ bool SetPixel( int i, int j, RGBApixel NewPixel );
+
+ bool CreateStandardColorTable( void );
+
+ bool SetSize( int NewWidth, int NewHeight );
+ bool SetBitDepth( int NewDepth );
+ bool WriteToFile( const char* FileName );
+ bool ReadFromFile( const char* FileName );
+
+ RGBApixel GetColor( int ColorNumber );
+ bool SetColor( int ColorNumber, RGBApixel NewColor );
+};
+
+#endif
diff --git a/utility/demo-fw/pc-tools/CreateDemoBin/lib/EasyBMP/EasyBMP_ChangeLog.txt b/utility/demo-fw/pc-tools/CreateDemoBin/lib/EasyBMP/EasyBMP_ChangeLog.txt
new file mode 100644
index 0000000..b0a2c14
--- /dev/null
+++ b/utility/demo-fw/pc-tools/CreateDemoBin/lib/EasyBMP/EasyBMP_ChangeLog.txt
@@ -0,0 +1,821 @@
+EasyBMP Cross-Platform Windows Bitmap Library: Change Log
+
+Library Author(s): Paul Macklin
+ Library License: BSD (revised). See the BSD_(revised)_license.txt
+ file for further information.
+ Copyright: 2005-6 by the EasyBMP Project
+ Email: macklin01@users.sourceforge.net
+ Support: http://easybmp.sourceforge.net
+
+All changes by Paul Macklin unless otherwise noted.
+
+*--------------------------------------------------------------------*
+
+Version: 0.50
+ Date: 1-31-2005
+
+ None! (first release)
+
+*--------------------------------------------------------------------*
+
+Version: 0.51
+ Date: 2-14-2005
+
+ Added full 32-bit BMP file support
+
+ Took out annoying "colors: " message from BMP8 initialization
+ from scratch
+
+ Added more license and copyright info to each file
+
+ Added change log to library
+
+ To do next:
+ Should update the error messages for the initializations
+ Should simplify the reading and writing code
+
+*--------------------------------------------------------------------*
+
+Version: 0.52
+ Date: 2-19-2005
+
+ Fixed a minor bug in the MakeGreyscalePalette function where the
+ 0 color turned out to be (255,255,255), rather than (0,0,0)
+
+ Updated standard colors for 4-bit, 8-bit, and 24-bit
+
+*--------------------------------------------------------------------*
+
+Version: 0.53
+ Date: 2-27-2005
+
+ Fixed unsigned / signed problem that VS.net shows
+
+
+ Tried fix of line 186 in EasyBMP_BMP4.h file. If it works,
+ I'll apply it consistently. I think that VS.net wants us
+ to clear char* blah, then char = new blah [size], just
+ like the old days for g++.
+
+ Removed EasyBMP_StandardColors.h from standard package
+
+*--------------------------------------------------------------------*
+
+Version: 0.54
+ Date: 2-27-2005
+
+ The fix of line 186 in EasyBMP_BMP4.h file appears to have
+ worked. I applied it through the remainder of the code.
+ Hopefully, this should ensure Visual Studio.Net compati-
+ bility.
+
+ Fixed some typos in the comment lines
+
+*--------------------------------------------------------------------*
+
+Version: 0.55
+ Date: 5-2-2005
+
+ Introduced RGBApixel struct.
+
+ Introduced BMFH, BMIH, and BMP classes.
+
+ Deprecated all old code to *_legacy.h.
+
+ Rewrote EasyBMP_VariousBMPutilities.h to use the new
+ BMP class.
+
+*--------------------------------------------------------------------*
+
+Version: 0.56
+ Date: 5-4-2005
+
+ Made Width, Height, and BitDepth private members and added
+ functions for accessing them.
+
+ Made a new function, SetBitDepth, as the only means to
+ change the bit depth. It will create/resize a palette as
+ necessary. This simplifies the WriteToFile code, as well as
+ any palette altering algorithms. (All algorithms can now
+ assume that a properly-sized palette exists.) This will
+ help improve code stability greatly.
+
+ Made a new function, SetSize, as the only way to change the
+ width and height of the image.
+
+ Eliminated useless HasPalette and NumberOfColors members,
+ and added TellNumberOfColors() function.
+
+ Updated EasyBMP_VariousBMPutilities.h to respect privacy
+ of data members.
+
+*--------------------------------------------------------------------*
+
+Version: 0.57
+ Date: 5-8-2005
+
+ Removed fclose(fp) lines from EasyBMP_BMP.h and
+ EasyBMP_VariousBMPutilities.h whenever ( !fp ) occurs,
+ to avoid a crash when trying to close a non-existant file.
+
+
+ Added a line to set bmfh.bfType = 0; to getBMFH() routine
+ in the case where ( !fp ) occurs, so that a nonexistant file
+ doesn't falsely show up as a bitmap file.
+
+ Made error messages in BMP::ReadFromFile(char*) more meaningful,
+ since Argh! doesn't help much. :-)
+
+ Made ReadFromFile operations safer: can deal more effectively
+ with corrupted and/or truncated files by adding the new
+ SafeFread() wrapper function.
+
+ Moved all change-log entries to the change log to make the source
+ file tidier.
+
+ Removed all references to Palettes; renamed them to ColorTables.
+
+*--------------------------------------------------------------------*
+
+Version: 0.58
+ Date: 5-13-2005
+
+ Rewrote ReadFromFile() to fix program crashes on reading 4-bit
+ files. (*grumble* I can't believe there was such a bug in such
+ a late version! */grumble*)
+
+ Added support to ReadFromFile() for reading 1-bit files.
+
+ Rewrote ReadFromFile() to avoid trying to read bitmap files of
+ depths other than 1, 4, 8, 24, and 32 bits.
+
+ Tested reading 4-bit files of width 0,1,2, and 3 (modulo 4),
+ and 1-bit files of width 0,1,2,3,4,5,6, and 7 (modulo 8)
+
+*--------------------------------------------------------------------*
+
+Version: 0.59
+ Date: 5-15-2005
+
+ Made ReadFromFile() more robust. Evidently, reading to the
+ same temp variable all the time made it unstable when reading
+ many files. I would never have guessed. I instead declare BMIH
+ and BMFH objects and read directly to their members. This appears
+ to be more stable when dealing with many ReadFromFile() calls.
+
+ On a related note, made sure to not call SetSize( Width,Height),
+ which is a bit recursive, as well as SetBitDepth( BitDepth ).
+ This appears to help stability, since these two functions were
+ create precisely for the purpose of setting those variables
+ values safely.
+
+ Made use of the boolean return value in SafeFread() to detect
+ when files are obviously corrupted. Used this to have an early
+ catch in ReadFromFile() and set it to a 1x1 1-bit image and
+ exit.
+
+ Made ReadFromFile() stricter, in that it only reads recognized
+ bit depths (1,4,8,24,32). Any other bit depth will prompt the
+ routine to terminate and set it to a 1x1 1-bit file.
+
+ Added write support for 1-bit files.
+
+ Rewrote WriteToFile() for 4,8-bit files to match methods used
+ for reading them.
+
+ Revised CreateStandardColorTable() and
+ CreateGreyscaleColorTable() to add support for 1-bit files.
+
+ Rewrote WriteToFile() to be stricter in only writing known bit
+ depths (1,4,8,24,32) and ignoring all others.
+
+*--------------------------------------------------------------------*
+
+Version: 0.60
+ Date: 5-21-2005
+
+ Deprecated *_legacy.h files.
+
+ Tested library extensivey in linux with good results.
+
+ Made CreateGreyscaleColorTable() stricter, in that it exits
+ if supplied a bit depth other than 1, 4, or 8.
+
+ Made cosmetic changes in EasyBMP_DataStructures.h to
+ improve readability.
+
+ Made SetBitDepth() stricter, in that it will never allow a bitmap
+ to be set to an unsupported bit depth. Only bit depths of 1, 4,
+ 8, 24, or 32 are accepted.
+
+ Made SetSize() stricter, in that it will not allow negative
+ widths or heights.
+
+ Made cosmetic changes in EasyBMP_BMP.h to improve readability.
+
+ Added a check in ReadFromFile() to see if the requested width or
+ height is negative, a good sign of file corruption. In such a
+ case, the file is set to a blank 1x1 1-bit file.
+
+ Added code to ReadFromFile() to set size to 1x1 and bit depth to
+ 1-bit if the file was not found.
+
+*--------------------------------------------------------------------*
+
+Version: 0.61
+ Date: 5-22-2005
+
+ Fixed awIndex typo in WriteToFile().
+
+ Replaced double BestDistance comparisons in WriteToFile()
+ with int BestDistances (so as to do integer operations,
+ rather than double operations). This gave a roughly 100%
+ speedup in 8-bit, 4-bit, and 1-bit write operations on
+ unoptimized (no compiler flags) code and a 30% speedup
+ on optimized code.
+
+ Removed checks like if( BestDistance < 1 ){ k=256; } .. from
+ WriteToFile(), as they give more overhead than savings in my
+ testing. For 8-bit files, there was a slight gain by putting
+ it back in with another method:
+ while( k < 256 && BestDistance > 0 ).
+
+ Redefined StepSize in CreateGreyscaleColorTable() to give a
+ better range of greys in 4-bit mode. As it was, white was not
+ in the color table. (Colors were spaced by 256/16 = 16). Now,
+ colors are spaced by (255-1)/(16-1) = 17, which gives the full
+ range.
+
+*--------------------------------------------------------------------*
+
+Version: 0.62
+ Date: 5-25-2005
+
+ Added endianess check function IsBigEndian() to
+ EasyBMP_DataStructures.h file.
+
+ Added functions to swap bytes in WORD and DWORD multibyte
+ variables to EasyBMP_DataStructures.h file for future big-endian
+ support.
+
+ Added functions to switch endianess to BMFH and BMIH objects
+ to EasyBMP_DataStructures.h file.
+
+ Added endianess checks to ReadFromFile() and WriteToFile()
+ functions in EasyBMP_BMP.h file, along with endianess conversions
+ where necessary.
+
+ Added endianess checks and conversions to GetBMFH() and GetBMIH()
+ functions in EasyBMP_VariousBMPutilities.h file.
+
+ Rewrote GetBitmapInfo() function to use GetBMFH() and GetBMIH()
+ functions instead. (In EasyBMP_VariousBMPutilities.h.) This
+ cuts down on the redundancy in the code.
+
+ Renamed GetBitmapInfo() to DisplayBitmapInfo() in the
+ EasyBMP_VariousBMPutilities.h file.
+
+ With these changes, big-endian architectures should be supported,
+ including IBM PowerPC, Sun Sparc, Motorola 86k, etc., and
+ including Mac OSX.
+
+*--------------------------------------------------------------------*
+
+Version: 0.63
+ Date: 7-20-2005
+
+ Added IntPow(int,int) function to help compiling with std
+ namespace. Besides, integer operations are faster and more
+ accurate.
+
+ Moved Square(double), IntSquare(int), and IntPow(int,int) to
+ EasyBMP_DataStructures.h
+
+ Simplified and cleaned up code in
+ Create4bitColorTable( RGBApixel**).
+
+ Changed safety check in BMP.ReadFromFile(char*) to set size to
+ 1 x 1 if width or height is non-positive, rather than simply
+ negative.
+
+ Added bounds checking to BMP.operator()(int,int) to automatically
+ truncate requested pixel if out of bounds. Also added a warning
+ to cue the user in. :-)
+
+ Made error messages more consistent in format.
+
+ Simplified and cleaned up code in
+ Create4bitColorTable( RGBApixel**).
+
+ Added #include <iostream.h> to EasyBMP.h, since EasyBMP uses
+ cout, etc.
+
+ Simplified and cleaned up code in
+ Create1bitColorTable( RGBApixel**).
+
+ Changed BMP.SetSize(int,int) to disallow non-positive widths and
+ heights, rather than simply negative widths and heights. Such
+ function calls are now ignored.
+
+*--------------------------------------------------------------------*
+
+Version: 0.64
+ Date: 8-2-2005
+
+ Changed "include <iostream.h>" to "include <iostream>" for
+ ANSI-C++ compliance, as well as for better compatibility with the
+ std namespace and VC++. (Thanks, Tommy Li!)
+
+ Added some #ifndef pragmas to each header so that it should be
+ fine to incluce EasyBMP.h in multiple files in larger projects.
+
+ Added "using namespace std" inside any function that used C++
+ math or I/O operations. I avoided putting "using namespace std"
+ anywhere with global scope for maximum compatibility with C++
+ software in the wild.
+
+ Added includes for <cmath> and <cstdio> to EasyBMP.h
+
+ Removed unused temporary variables (TempWORD and TempDWORD) from
+ EasyBMP_BMP.h for cleaner compiling. If I see any more such
+ unused variables, I'll remove them, too.
+
+*--------------------------------------------------------------------*
+
+Version: 0.65
+ Date: 8-13-2005
+
+ Moved implementations of BMP::BMP(), BMP::~BMP(), and
+ BMP::operator()(int,int) outside of the class. This should help
+ for eventually moving everything into a separate cpp file.
+
+ Made RGBApixel** Pixels a private data member of the class
+ BMP.
+
+ Added function void BMP::SetColor(int,RGBApixel) to BMP class
+ to allow safe method of changing a color in the color table.
+
+ Added function RGBApixel BMP::GetColor(int) to BMP class
+ to allow safe method of retrieving a color in the color
+ table.
+
+ Cleaned up error messages in EasyBMP_BMP.h
+
+ Cleaned up error messages in EasyBMP_VariousBMPutilities.h
+
+*--------------------------------------------------------------------*
+
+Version: 0.66
+ Date: 8-18-2005
+
+ EasyBMP_StandardColorTables.h was removed from the library.
+
+ CreateStandardColorTable(RGBApixel**,int) was changed to
+ CreateStandardColorTable() and made a member function of BMP.
+ All other CreateStandardColorTable functions are now unnecessary
+ and have been removed.
+
+ CreateGreyscaleColorTable(RGBApixel**,int) was changed to
+ CreateStandardColorTable( BMP& ) and moved to
+ EasyBMP_VariousBMPutilities.h.
+
+ RGBApixel* Colors was made a private data member of the BMP
+ class.
+
+ CreateGreyscaleColorTable( BMP& ) was renamed to
+ CreateGrayscaleColorTable( BMP& ).
+
+*--------------------------------------------------------------------*
+
+Version: 0.67
+ Date: 9-14-2005
+
+ Made the EasyBMP custom math functions in
+ EasyBMP_DataStructures.h inline. (Square,IntSquare,IntPow).
+ This should make those function calls faster while improving
+ compatibility with compiling DLL's.
+
+ Separated the code from SafeFread() in EasyBMP_BMP.h to
+ improve compatibility with compiling DLL's.
+
+ Removed #define _WINGDI_H from EasyBMP_DataStructures.h to
+ improve compatibility with win32 applications. Instead,
+ there's an extra #ifndef _SELF_DEFINED_BMP_DATA_TYPES
+ conditional added.
+
+ _SELF_DEFINED_BMP_DATA_TYPES renamed to _SELF_DEFINED_WINGDI
+ in EasyBMP_DataStructures.h.
+
+ All bit-flipping functions (IsBigEndian, FlipWORD,
+ FlipDWORD) in EasyBMP_DataStructures.h were made inline
+ to improve execution speed and improve compatibility with
+ compiling DLL's.
+
+ All code was separated from function declarations in
+ EasyBMP_VariousBMPutilities.h to improve compatibility
+ with compiling DLL's.
+
+ Updated and cleaned up layout of EasyBMP_ChangeLog.txt.
+
+ Updated contact and support information in library files.
+
+ Corrected the LGPL license version.
+
+*--------------------------------------------------------------------*
+
+Version: 0.68
+ Date: 10-9-2005
+
+ Changed references to FILE to std::FILE in the SafeFread function
+ in EasyBMP_BMP.h to improve compatibility with Borland's compiler.
+
+ Removed a few assignments in EasyBMP_BMP.h that weren't used to
+ improve efficiency and reduce Borland warnings.
+
+ Changed calls like NotCorrupted = SafeFread() to
+ NotCorrupted &= SafeFread() in BMP::ReadFromFile() in EasyBMP_BMP.h
+ to improve robustness. Now, if the NotCorrupted bit is ever set
+ to false, it stays false, meaning that the function won't "forget"
+ that it encountered file corruption.
+
+*--------------------------------------------------------------------*
+
+Version: 0.69
+ Date: 10-19-2005
+
+ Changed BMP::WriteToFile( char* ) to BMP::WriteToFile(const char*)
+ in EasyBMP_BMP.h to respond to a feature request.
+
+ Changed BMP::ReadFromFile( char* ) to BMP::ReadToFile(const char*)
+ in EasyBMP_BMP.h to respond to a feature request.
+
+ Made BMP::ReadFromFile() and BMP::WriteToFile() in EasyBMP_BMP.h
+ return true/false to indicate success/failure in the operations.
+ These functions previously returned void.
+
+ Made BMP::SetSize() and BMP::SetBitDepth() in EasyBMP_BMP.h
+ return true/false to indicate success/failure in the operations.
+ These functions previously returned void.
+
+ Made BMP::SetColor() and BMP::CreateStandardColorTable() in
+ EasyBMP_BMP.h return true/false to indicate success/failure in the
+ operations. These functions previously returned void.
+
+ Made CreateGrayscaleColorTable() in EasyBMP_VariousBMPutilities.h
+ return true/false to indicate success/failure in the operations.
+ This function previously returned void.
+
+ Changed the char* argument GetBMFH( char* ), GetBMIH( char* ),
+ DisplayBitmapInfo( char* ), and GetBitmapColorDepth( char* ) in
+ EasyBMP_VariousBMPutilities.h to const char* for cleaner, safer
+ programming.
+
+*--------------------------------------------------------------------*
+
+Version: 0.70
+ Date: 10-19-2005
+
+ Found and fixed error in BMP::ReadFromFile() in the check for only
+ reading support bit depths.
+
+ Changed license from LGPL to BSD (revised/modified) to simplify
+ licensing issues and resolve any lingering licensing questions.
+
+ Fixed compiler error when using MSVC++.
+
+ Improved fix to allow compiling with Borland without breaking
+ Borland support.
+
+ Added a few lines to EasyBMP.h to make it easier to tailor code
+ to specific compilers. (For future use as needed.)
+
+ Added a few lines to EasyBMP_BMP.h (in BMP::ReadFromFile(),
+ BMP::WriteToFile(), and BMP::SetBitDepth()) to eventually add
+ support for 16-bit files.
+
+*--------------------------------------------------------------------*
+
+Version: 0.71
+ Date: 11-01-2005
+
+ Cleaned up comments in BMP::ReadFromFile() in EasyBMP_BMP.h
+
+ Added endian-safe read support for 16-bit files that are in the
+ standard 5-5-5 format (not specified in bit fields)
+
+ Added endian-safe read support for 16-bit files that use bit
+ fields, including 5-6-5 files.
+
+ Added endian-safe write support for 16-bit files. Uses the 5-6-5
+ encoding scheme to maximize the utility of the bits used.
+
+ Added a check for compression in BMP::ReadFromFile(). Because
+ file compression is beyond the scope of EasyBMP, such files are
+ not supported, and EasyBMP now properly detects these situations
+ and exits with an error.
+
+ Added a check for files that attempt to use bit fields but are not
+ 16-bit files to BMP::ReadFromFile(). Such files are not supported.
+
+ Added a check to BMP::ReadFromFile() for files that use unknown
+ values of bmih.biCompression, such as old OS2 bitmaps. Such files
+ are not supported.
+
+ Removed "switching endianness" messages from EasyBMP_BMP.h
+
+ Added support for indexed (1, 4, and 8-bit) files that don't
+ specify all the colors.
+
+ Added support for reading files that include extra meta data before
+ the pixels. This data is skipped.
+
+ Added enclosing #ifndef EasyBMP ... lines to EasyBMP.h as a
+ further safeguard when EasyBMP is included in multiple cpp
+ files.
+
+*--------------------------------------------------------------------*
+
+Version: 1.00
+ Date: 02-06-2006
+
+ First Production/Stable release.
+
+ Corrected typographical errors in the comment sections of all
+ files.
+
+ Updated copyright on all files.
+
+ Removed extraneous comment in BMIH::BMIH() function in
+ EasyBMP_DataStructures.h file.
+
+ Replaced instances of \n with the more modern endl in
+ EasyBMP_DataStructures.h, EasyBMP_BMP.h, and
+ EasyBMP_VariousBMPutilities.h.
+
+ Added placeholder MetaData1 and MetaData2 data members to the
+ BMP class for potential future use.
+
+ Removed extraneous comments from EasyBMP_BMP.h.
+
+ Removed warning messages for switching endianness from
+ EasyBMP_VariousBMPutilities.h.
+
+ Updated copyright in EasyBMP_ChangeLog.txt file.
+
+ Fixed formatting issues in EasyBMP_ChangeLog.txt file.
+
+ Added DefaultXpelsPerMeter and DefaultYpelsPerMeter in
+ EasyBMP.h. These will default to 96 dpi.
+
+ Changed BMP::WriteToFile() to use DefaultXpelsPerMeter and
+ DefaultYpelsPerMeter when writing the BMIH structure.
+
+ Added XpelsPerMeter and YpelsPerMeter data members to BMP
+ class so that horizontal and vertical resolution are handled
+ properly. Currently, upon reading a file, the stated resolutions
+ are preserved, and upon writing, if no resolutions are given,
+ the defaults (of 96 DPI) are used.
+
+ Added function void BMP::SetDPI(int,int) to set the horizontal
+ and vertical resolutions.
+
+ Removed some unnecessary code from GetBitmapColorDepth() in
+ EasyBMP_VariousBMPutilities.h.
+
+ Fixed a bug in RangedPixelToPixelCopyTransparent() and
+ RangedPixelToPixelCopy() in EasyBMP_VariousBMPutilities.h which
+ caused copies to be truncated by an extra row or column in
+ certain circumstances.
+
+ Fixed a bug in RangedPixelToPixelCopyTransparent() and
+ RangedPixelToPixelCopy() in EasyBMP_VariousBMPutilities.h which
+ checked the wrong variable (FromT instead of FromB) to see if
+ it was out of range.
+
+ Added extra checks to RangedPixelToPixelCopyTransparent() and
+ RangedPixelToPixelCopy() in EasyBMP_VariousBMPutilities.h to
+ prevent attempted access of out-of-range pixels.
+
+*--------------------------------------------------------------------*
+
+Version: 1.01
+ Date: 03-31-2006
+
+ Made only the short functions Square, IntSquare, IsBigEndian,
+ FlipWORD, and FlipDWORD inline functions in
+ EasyBMP_DataStructures.h.
+
+ Moved all code (other than inline functions) to EasyBMP.cpp.
+
+ Changed DefaultXPelsPerMeter and DefaultYPelsPerMeter to #define
+ lines in EasyBMP.h to make the library compatible with
+ with the header-code split.
+
+ Removed memory hole in ~BMP() where "delete Colors;" was used
+ instead of "delete [] Colors;". Likewise with MetaData1 and
+ MetaData2.
+
+ Fixed memory leak in BMP::SetBitDepth() by changing to
+ delete [] Colors;
+
+ Removed potential memory leak in BMP::WriteToFile() in 24- and
+ 32-bit writing where szTemp wasn't delete at the end of a row.
+
+ Fixed bug where XPelsPerMeter and YPelsPerMeter weren't
+ properly initialized in the BMP::BMP() constructor, leading
+ to strange horizontal and vertical resolutions.
+
+ Fixed memory leak in BMP::ReadFromFile() where TempSkipBYTE
+ wasn't deleted.
+
+ Fixed memory leak in BMP::ReadFromFile() where szTemp wasn't
+ deleted.
+
+ Added BMP::TellVerticalDPI() and BMP::TellHorizontalDPI()
+ functions to give this information. If those values have
+ not yet been set, then they are first set to the EasyBMP
+ defaults of 96 dpi.
+
+ Set uninitialized RGBApixel values to white (255,255,255,0)
+ in a few functions for the BMP class.
+
+ Added a sample cpp application and makefile.
+
+*--------------------------------------------------------------------*
+
+Version: 1.02
+ Date: 05-29-2006
+
+ Inserted a line into EasyBMP.h to suppress the Visual Studio
+ warnings. We'll keep using the C++ standard fopen for now
+ until fopen_s becomes a real standard.
+
+ Moved the code sample and makefile to a subdirectory, so that
+ unzipping EasyBMP#_##.zip into a project directory doesn't
+ overwrite any crucial makefiles.
+
+ Improved SafeFread() to check if the proper amount of data
+ could be read.
+
+ Dramatically cleaned up ReadFromFile() code for 1 and 4
+ bpp files.
+
+ Fixed a typo (draw.o) in the sample makefile.
+
+ Modified ReadFromFile() to use buffering when reading the pixel
+ data. This should substantially improve disk access performance.
+ Only 16 bpp files are read in the old, slower way.
+
+ Changed DWORD from unsigned long to unsigned int. This should
+ fix the issue where 64-bit machines see DWORD as an 8-byte
+ data type, rather than 4 bytes. (Thank you to Bas Wegh!)
+
+ Renamed BYTE, WORD, and DWORD data types to ebmpBYTE, ebmpWORD,
+ and ebmpDWORD to eliminate the possibility of conflict with
+ windows applications, particularly with 64-bit windows, which
+ likely uses 8 byte DWORDS.
+
+ Modified WriteToFile() to use buffering when reading the pixel
+ data. This should substantially improve disk access performance.
+ Only 16 bpp files are read in the old, slower way.
+
+ Added new function, EasyBMPcheckDataSize(), to check that
+ the ebmpBYTE, ebmpWORD, and ebmpDWORD types have the correct
+ type.
+
+ Added some new macros of the EasyBMP version number for easier
+ version checking. New versions include _EasyBMP_Version_
+ (a double), _EasyBMP_Version_String_ (a char* version), and
+ _EasyBMP_Version_Integer_ (an integer version, e.g., 102).
+
+*--------------------------------------------------------------------*
+
+Version: 1.03
+ Date: 06-20-2006
+
+ Inserted a line into EasyBMP.h to suppress the Visual Studio
+
+ Added a check to BMP.SetColor() to ensure that the color table
+ is defined before attempting to set a color entry.
+
+ Added a check to BMP.GetColor() to ensure that the color table
+ is defined before attempting to retrieve a color entry.
+
+ Simplified the conditional in BMP.WriteToFile() from
+ if( BitDepth == 1 || BitDepth == 4 || ... ) to the simpler
+ if( BitDepth != 16 ).
+
+ Removed the old, unused code for writing 1- and 4-bit files
+ from BMP.WriteToFile().
+
+ Removed the line Colors = new RGBApixel [NumberOfColors]; in
+ BMP.ReadFromFile(). This operation is already covered by the
+ earlier SetBitDepth() call, and may contribute to a memory
+ leak. Furthermore, for files that had fewer than expected
+ number of colors (e.g., an 8-bit file with 236 colors), it
+ lead to memory access errors in BMP.GetColor() and BMP.SetColor().
+ (In fact, this is the main motivation for release 1.03.)
+
+ Added a warning when BMP.ReadFromFile() encounters an under-
+ specified color table, and code to pad the table with white
+ entries.
+
+ Added screen output on EasyBMP version and project website to
+ the code sample.
+
+*--------------------------------------------------------------------*
+
+Version: 1.04
+ Date: 07-22-2006
+
+ Removed the assignment to the integer i in IntPow() to eliminate a
+ Borland compiler warning.
+
+ Removed the assignment to the integer i in the Read##bitRow()
+ functions to eliminate Borland compiler warnings.
+
+ Removed the assignment to ZeroWORD in line 478 of EasyBMP.cpp in
+ BMP::WriteToFile() to eliminate Borland compiler warnings.
+
+ Removed the assignment to ZeroWORD in line 825 of EasyBMP.cpp in
+ BMP::ReadFromFile() to eliminate Borland compiler warnings.
+
+ The Borland warnings about conditions always being false are
+ incorrect. (Lines 1587, 1594, and 1601.) Likewise, the Borland
+ warnings about unreachable code (lines 1589, 1596, and 1603) are
+ incorrect. This code serves as a protection on unexpected hardware
+ where the data types may not be of the correct size, and helps to
+ future-proof EasyBMP. The first time this type of error was
+ encountered was on 64-bit CPUs, where the size of the DWORD was
+ larger than assumed when writing EasyBMP. Therefore, we will not
+ "correct" these "errors" detected by Borland. If they bother you,
+ compile with the -w-8008 and -w-8066 options.
+
+ Borland issues warnings about argc and argv being unused in the
+ sample project. These are silly warnings and will be ignored. If
+ this warning bothers you, compile with the -w-8057 option.
+
+ Modified the sample makefile so that EasyBMP.o depends upon
+ EasyBMP.cpp and EasyBMP*.h in the current working directory, rather
+ than the parent directory.
+
+ Added a global EasyBMPwarnings boolean variable, and functions
+ SetEasyBMPwarningsOn() and SetEasyBMPwarningsOff() to enable and
+ disable EasyBMP warnings and errors. Note that this will not
+ disable error checking or any other EasyBMP behavior, other than
+ cout output of the warning and error messages.
+
+ Added the function GetEasyBMPwarningState() to query the EasyBMP
+ warning state. (Either warnings are enabled or disabled.)
+
+ Removed old commented code (Write1bitRow()) from EasyBMP.cpp.
+
+ Replaced the 24-bit EasyBMPbackground.bmp image in the code sample
+ with a dithered 8-bit version to reduce the download size of the
+ core library.
+
+*--------------------------------------------------------------------*
+
+Version: 1.05
+ Date: 11-01-2006
+
+ Renamed BytesRead to ItemsRead in the SafeFread() function in
+ EasyBMP.cpp for greater clarity.
+
+ Added a copy constructor to the BMP class. However, note that
+ passing by value is not recommended practice. (Passing by refer-
+ ence is much faster, and consumes less memory.)
+
+ Added a new function:
+ bool Rescale( BMP& InputImage, char mode, int NewDimension );
+ to resize an image. The mode variables are as follows:
+ 'P': resizes the image to a new percentage of the old size,
+ e.g., 42%, 13%, etc.
+ example: Rescale( SomeImage, 'p', 42 );
+ 'W': resizes the image such that the new width is as specified.
+ example: Rescale( SomeImage, 'W', 100 );
+ 'H': resizes the image such that the new height is as specified.
+ example: Rescale( SomeImage, 'H', 100 );
+ 'F': resizes the image to fit in a square of specified size.
+ example: Rescale( SomeImage, 'F', 100 ); // fits in 100x100
+ // box
+ All rescaling is done with bilinear interpolation.
+
+*--------------------------------------------------------------------*
+
+Version: 1.06
+ Date: 12-01-2006
+
+ Added includes for <cctype> and <cstring> to EasyBMP.h. These are
+ used and should have been included all along. This should help
+ with Intel icc compiling.
+
+ Fixed the && bug in the copy constructor. (Thank you to user
+ fcnature!)
+
+ Added image scaling to the supplied code sample.
+
+ Added GetPixle() and SetPixel() functions for future use. These
+ will be added to enable more careful use of the const keyword.
+
+*--------------------------------------------------------------------* \ No newline at end of file
diff --git a/utility/demo-fw/pc-tools/CreateDemoBin/lib/EasyBMP/EasyBMP_DataStructures.h b/utility/demo-fw/pc-tools/CreateDemoBin/lib/EasyBMP/EasyBMP_DataStructures.h
new file mode 100644
index 0000000..41665e5
--- /dev/null
+++ b/utility/demo-fw/pc-tools/CreateDemoBin/lib/EasyBMP/EasyBMP_DataStructures.h
@@ -0,0 +1,104 @@
+/*************************************************
+* *
+* EasyBMP Cross-Platform Windows Bitmap Library *
+* *
+* Author: Paul Macklin *
+* email: macklin01@users.sourceforge.net *
+* support: http://easybmp.sourceforge.net *
+* *
+* file: EasyBMP_DataStructures.h *
+* date added: 05-02-2005 *
+* date modified: 12-01-2006 *
+* version: 1.06 *
+* *
+* License: BSD (revised/modified) *
+* Copyright: 2005-6 by the EasyBMP Project *
+* *
+* description: Defines basic data structures for *
+* the BMP class *
+* *
+*************************************************/
+
+#ifndef _EasyBMP_Custom_Math_Functions_
+#define _EasyBMP_Custom_Math_Functions_
+inline double Square( double number )
+{ return number*number; }
+
+inline int IntSquare( int number )
+{ return number*number; }
+#endif
+
+int IntPow( int base, int exponent );
+
+#ifndef _EasyBMP_Defined_WINGDI
+#define _EasyBMP_Defined_WINGDI
+ typedef unsigned char ebmpBYTE;
+ typedef unsigned short ebmpWORD;
+ typedef unsigned int ebmpDWORD;
+#endif
+
+#ifndef _EasyBMP_DataStructures_h_
+#define _EasyBMP_DataStructures_h_
+
+inline bool IsBigEndian()
+{
+ short word = 0x0001;
+ if((*(char *)& word) != 0x01 )
+ { return true; }
+ return false;
+}
+
+inline ebmpWORD FlipWORD( ebmpWORD in )
+{ return ( (in >> 8) | (in << 8) ); }
+
+inline ebmpDWORD FlipDWORD( ebmpDWORD in )
+{
+ return ( ((in&0xFF000000)>>24) | ((in&0x000000FF)<<24) |
+ ((in&0x00FF0000)>>8 ) | ((in&0x0000FF00)<<8 ) );
+}
+
+// it's easier to use a struct than a class
+// because we can read/write all four of the bytes
+// at once (as we can count on them being continuous
+// in memory
+
+typedef struct RGBApixel {
+ ebmpBYTE Blue;
+ ebmpBYTE Green;
+ ebmpBYTE Red;
+ ebmpBYTE Alpha;
+} RGBApixel;
+
+class BMFH{
+public:
+ ebmpWORD bfType;
+ ebmpDWORD bfSize;
+ ebmpWORD bfReserved1;
+ ebmpWORD bfReserved2;
+ ebmpDWORD bfOffBits;
+
+ BMFH();
+ void display( void );
+ void SwitchEndianess( void );
+};
+
+class BMIH{
+public:
+ ebmpDWORD biSize;
+ ebmpDWORD biWidth;
+ ebmpDWORD biHeight;
+ ebmpWORD biPlanes;
+ ebmpWORD biBitCount;
+ ebmpDWORD biCompression;
+ ebmpDWORD biSizeImage;
+ ebmpDWORD biXPelsPerMeter;
+ ebmpDWORD biYPelsPerMeter;
+ ebmpDWORD biClrUsed;
+ ebmpDWORD biClrImportant;
+
+ BMIH();
+ void display( void );
+ void SwitchEndianess( void );
+};
+
+#endif
diff --git a/utility/demo-fw/pc-tools/CreateDemoBin/lib/EasyBMP/EasyBMP_VariousBMPutilities.h b/utility/demo-fw/pc-tools/CreateDemoBin/lib/EasyBMP/EasyBMP_VariousBMPutilities.h
new file mode 100644
index 0000000..3a2f464
--- /dev/null
+++ b/utility/demo-fw/pc-tools/CreateDemoBin/lib/EasyBMP/EasyBMP_VariousBMPutilities.h
@@ -0,0 +1,53 @@
+/*************************************************
+* *
+* EasyBMP Cross-Platform Windows Bitmap Library *
+* *
+* Author: Paul Macklin *
+* email: macklin01@users.sourceforge.net *
+* support: http://easybmp.sourceforge.net *
+* *
+* file: EasyBMP_VariousBMPutilities.h *
+* date added: 05-02-2005 *
+* date modified: 12-01-2006 *
+* version: 1.06 *
+* *
+* License: BSD (revised/modified) *
+* Copyright: 2005-6 by the EasyBMP Project *
+* *
+* description: Various utilities. *
+* *
+*************************************************/
+
+#ifndef _EasyBMP_VariousBMPutilities_h_
+#define _EasyBMP_VariousBMPutilities_h_
+
+typedef union {
+ int ratio;
+ int keepsize;
+ struct {
+ short width;
+ short height;
+ } dimension;
+} ScaleParam;
+
+BMFH GetBMFH( const char* szFileNameIn );
+BMIH GetBMIH( const char* szFileNameIn );
+void DisplayBitmapInfo( const char* szFileNameIn );
+int GetBitmapColorDepth( const char* szFileNameIn );
+void PixelToPixelCopy( BMP& From, int FromX, int FromY,
+ BMP& To, int ToX, int ToY);
+void PixelToPixelCopyTransparent( BMP& From, int FromX, int FromY,
+ BMP& To, int ToX, int ToY,
+ RGBApixel& Transparent );
+void RangedPixelToPixelCopy( BMP& From, int FromL , int FromR, int FromB, int FromT,
+ BMP& To, int ToX, int ToY );
+void RangedPixelToPixelCopyTransparent(
+ BMP& From, int FromL , int FromR, int FromB, int FromT,
+ BMP& To, int ToX, int ToY ,
+ RGBApixel& Transparent );
+bool CreateGrayscaleColorTable( BMP& InputImage );
+
+bool Rescale( BMP& InputImage , char mode, ScaleParam scale );
+
+
+#endif
diff --git a/utility/demo-fw/pc-tools/CreateDemoBin/lib/EasyBMP/sample/EasyBMPbackground.bmp b/utility/demo-fw/pc-tools/CreateDemoBin/lib/EasyBMP/sample/EasyBMPbackground.bmp
new file mode 100644
index 0000000..ae1dfa2
--- /dev/null
+++ b/utility/demo-fw/pc-tools/CreateDemoBin/lib/EasyBMP/sample/EasyBMPbackground.bmp
Binary files differ
diff --git a/utility/demo-fw/pc-tools/CreateDemoBin/lib/EasyBMP/sample/EasyBMPsample.cpp b/utility/demo-fw/pc-tools/CreateDemoBin/lib/EasyBMP/sample/EasyBMPsample.cpp
new file mode 100644
index 0000000..2b25ca2
--- /dev/null
+++ b/utility/demo-fw/pc-tools/CreateDemoBin/lib/EasyBMP/sample/EasyBMPsample.cpp
@@ -0,0 +1,82 @@
+/*************************************************
+* *
+* EasyBMP Cross-Platform Windows Bitmap Library *
+* *
+* Author: Paul Macklin *
+* email: macklin01@users.sourceforge.net *
+* support: http://easybmp.sourceforge.net *
+* *
+* file: EasyBMPsample.cpp *
+* date added: 03-31-2006 *
+* date modified: 12-01-2006 *
+* version: 1.06 *
+* *
+* License: BSD (revised/modified) *
+* Copyright: 2005-6 by the EasyBMP Project *
+* *
+* description: Sample application to demonstrate *
+* some functions and capabilities *
+* *
+*************************************************/
+
+#include "EasyBMP.h"
+using namespace std;
+
+int main( int argc, char* argv[] )
+{
+ cout << endl
+ << "Using EasyBMP Version " << _EasyBMP_Version_ << endl << endl
+ << "Copyright (c) by the EasyBMP Project 2005-6" << endl
+ << "WWW: http://easybmp.sourceforge.net" << endl << endl;
+
+ BMP Text;
+ Text.ReadFromFile("EasyBMPtext.bmp");
+
+ BMP Background;
+ Background.ReadFromFile("EasyBMPbackground.bmp");
+
+ BMP Output;
+ Output.SetSize( Background.TellWidth() , Background.TellHeight() );
+ Output.SetBitDepth( 24 );
+
+ RangedPixelToPixelCopy( Background, 0, Output.TellWidth()-1,
+ Output.TellHeight()-1 , 0,
+ Output, 0,0 );
+
+ RangedPixelToPixelCopyTransparent( Text, 0, 380,
+ 43, 0,
+ Output, 110,5,
+ *Text(0,0) );
+
+ RangedPixelToPixelCopyTransparent( Text, 0, Text.TellWidth()-1,
+ Text.TellWidth()-1, 50,
+ Output, 100,442,
+ *Text(0,49) );
+
+ Output.SetBitDepth( 32 );
+ cout << "writing 32bpp ... " << endl;
+ Output.WriteToFile( "EasyBMPoutput32bpp.bmp" );
+
+ Output.SetBitDepth( 24 );
+ cout << "writing 24bpp ... " << endl;
+ Output.WriteToFile( "EasyBMPoutput24bpp.bmp" );
+
+ Output.SetBitDepth( 8 );
+ cout << "writing 8bpp ... " << endl;
+ Output.WriteToFile( "EasyBMPoutput8bpp.bmp" );
+
+ Output.SetBitDepth( 4 );
+ cout << "writing 4bpp ... " << endl;
+ Output.WriteToFile( "EasyBMPoutput4bpp.bmp" );
+
+ Output.SetBitDepth( 1 );
+ cout << "writing 1bpp ... " << endl;
+ Output.WriteToFile( "EasyBMPoutput1bpp.bmp" );
+
+ Output.SetBitDepth( 24 );
+ Rescale( Output, 'p' , 50 );
+ cout << "writing 24bpp scaled image ..." << endl;
+ Output.WriteToFile( "EasyBMPoutput24bpp_rescaled.bmp" );
+
+ return 0;
+}
diff --git a/utility/demo-fw/pc-tools/CreateDemoBin/lib/EasyBMP/sample/EasyBMPtext.bmp b/utility/demo-fw/pc-tools/CreateDemoBin/lib/EasyBMP/sample/EasyBMPtext.bmp
new file mode 100644
index 0000000..6a9e00c
--- /dev/null
+++ b/utility/demo-fw/pc-tools/CreateDemoBin/lib/EasyBMP/sample/EasyBMPtext.bmp
Binary files differ
diff --git a/utility/demo-fw/pc-tools/CreateDemoBin/lib/EasyBMP/sample/makefile b/utility/demo-fw/pc-tools/CreateDemoBin/lib/EasyBMP/sample/makefile
new file mode 100644
index 0000000..591c649
--- /dev/null
+++ b/utility/demo-fw/pc-tools/CreateDemoBin/lib/EasyBMP/sample/makefile
@@ -0,0 +1,53 @@
+#
+# EasyBMP Cross-Platform Windows Bitmap Library
+#
+# Author: Paul Macklin
+# email: macklin01@users.sourceforge.net
+# support: http://easybmp.sourceforge.net
+# file: makefile
+# date added: 04-22-2006
+# date modified: 12-01-2006
+# version: 1.06
+#
+# License: BSD (revised/modified)
+# Copyright: 2005-6 by the EasyBMP Project
+#
+# description: Sample makefile for compiling with
+# the EasyBMP library. This compiles
+# the EasyBMPsample.cpp program.
+#
+
+CC = g++
+
+# this line gives compiler optimizations that are geared towards g++ and Pentium4
+# computers. Comment it out if you don't have a Pentium 4 (or Athlon XP) or up
+
+# CFLAGS = -O3 -Wno-deprecated -mcpu=pentium4 -march=pentium4 \
+# -mfpmath=sse -msse -mmmx -msse2 -pipe -fomit-frame-pointer -s
+
+# Uncomment these two lines to use with any Pentium with MMX or up.
+
+# CFLAGS = -Wno-deprecated -mcpu=pentium -march=pentium -pipe \
+# -fomit-frame-pointer -mmmx -funroll-all-loops -s
+
+# Uncomment these lines for some "safe" optimization flags
+
+CFLAGS = -O3 -pipe -fomit-frame-pointer -funroll-all-loops -s
+
+EasyBMPTest: EasyBMP.o EasyBMPsample.o
+ g++ $(CFLAGS) EasyBMP.o EasyBMPsample.o -o EasyBMPtest
+
+EasyBMP.o: ../EasyBMP.cpp ../EasyBMP*.h
+ cp ../EasyBMP*.h .
+ cp ../EasyBMP.cpp .
+ g++ $(CFLAGS) -c EasyBMP.cpp
+
+EasyBMPsample.o: EasyBMPsample.cpp
+ g++ -c EasyBMPsample.cpp
+
+clean:
+ rm EasyBMP*.h
+ rm EasyBMP.cpp
+ rm EasyBMPtest*
+ rm EasyBMPoutput*.bmp
+ rm -f *.o
diff --git a/utility/demo-fw/pc-tools/CreateDemoBin/lib/libregex.a b/utility/demo-fw/pc-tools/CreateDemoBin/lib/libregex.a
new file mode 100644
index 0000000..c20b68d
--- /dev/null
+++ b/utility/demo-fw/pc-tools/CreateDemoBin/lib/libregex.a
Binary files differ
diff --git a/utility/demo-fw/pc-tools/CreateDemoBin/readme.txt b/utility/demo-fw/pc-tools/CreateDemoBin/readme.txt
new file mode 100644
index 0000000..e787e37
--- /dev/null
+++ b/utility/demo-fw/pc-tools/CreateDemoBin/readme.txt
@@ -0,0 +1,109 @@
+1> directory info:
+
+|-bin [dir]compile executive binary
+|-include [dir]header files
+|-lib [dir]libraries
+|-PPT [dir]directory containing example PPT, demo bin file and vs script
+|-src [dir]source files
+|-Makefile [file]project file to make. use gnu/g++ as compiler.
+|-Module1.bas [file]vb script source of macro 'ExportPPTInfo'
+|-readme.txt [file]this file
+
+
+
+2> usage instructions:
+
+Suppose that demo is for at91sam3u-ek, and power point file is Sam3Demo.ppt.
+
+Sam3Demo.bin and SamDemoV.bin under ./PPT are created bin files with CreateDemoBin.exe, you can use it directly or use CreateDemoBin.exe to recreate it.
+
+Follow these instructions to create a bin from starting(use sam3demo.ppt as example):
+
+[step 1]:
+ Open Sam3DEMO.ppt, when a window pops up, select 'enable macros'. If no this window or you made wrong selection, please check Powerpoint menu 'tools->macro->security...', set it to medium, then close the program and reopen it.(Powerpoint 2003)
+
+[step 2]:
+ Select 'tools->macro->macros...', then run the macro named as 'ExportPPTInfo'. After running, there should be 'Sam3DEMO.txt' and dir 'Sam3DEMO' created. Inside dir 'Sam3DEMO', there should be bmp files named as 'slide1.bmp... slide10.bmp...' If macro 'ExportPPTInfo' is not available, please import content of 'Module1.bas' into VB script edit window, save it to file, then rerun it.
+
+[step 3]:
+ Run CreateDemoBin.bat (or CreateDemoBin sam3demo)under dir same as Sam3DEMO.ppt. If success, Sam3Demo.bin should be created.
+
+ [Please NOTE]:
+a:> Defaultly this bat will generate horizontal view demo binary for sdcard and nandflash(contained slide pics are 320*240 16bit bmp with 270 degree clockwise rotation). For vertical view demo binary, please use CreateDemoBinV.bat to generate sam3demo.bin, then RENAME it to SamDemoV.bin. Before Converting vertical view demo binary, previous generated horizontal view demo binary Sam3Demo.bin must be BACKUPed. Or converting vertical one and renaming it first, then converting horizontal one. Key word sam3demo could be replaced with any actual name of PPT.
+
+b:>This batch files are only for sam3u demo(assuming that PPT name is sam3demo.ppt). For other boards and PPT file, please replace conversion parameters and PPT name. In following section 3, more details about conversion tools with examples are given.
+
+
+
+[step 4]:
+ Copy the bin file into root dir of a SDCARD or using sam-ba to download it into flash1, the program will search the SDcard -> Nandflash -> Internal flash for the demo binary file.(you can use the default binary file Sam3DEMO.bin for SDcard and Nandflash, and DEMOBINFLASH1.bin for the internal flash)
+
+[step 5]:
+ Compile the gshell projects, and load it into sam3u4 flash0 to run.(if DEMOBININFLASH1 is defined, then program will read demo bin data from FLASH1, otherwise, it will read demo bin data with search order of sdcard->nandflash->flash1. Auto run in the init entry will try to read "sam3demo.bin" by default. You can use other demo bin file name under GShell console)
+
+
+
+
+3> CreateDemoBin.exe options and examples:
+
+
+Usage: CreateDemoBin.exe [options] <PPTpathAndnameWithoutExtName>
+ For example, sam3demo.ppt, after running VBS macro in PowerPoint,
+ copy this file under the same directory, then Run:
+
+ CreateDemoBin.exe sam3demo
+ Options:
+ --help, show this information
+ -profile <EK-board-name>, build-in option sets, default board name is at91sam3u-ek
+ -profile help, display all build-in profile details
+ -width <resizedwith>, default is 320 pixel
+ -height <resizedheight>, default is 240 pixel
+ -bitdepth <bitdepth>, default is 16 bit
+ -rotate <clockwise_angel>, times of 90 degree within 360, default is 270 degre
+e
+ -noreversebitmaporder, keep bitmap data original order, default reverse the order for at91sam3u-ek
+
+
+
+[Example 1:Generating demo binary of horizontal view]:
+
+ For demo bin of default horizontal view(based on long side of LCD SCREEN) in sdcard or nandflash of at91sam3u-ek(sam3demo.ppt, and generated txt file and slide bitmap with macro):
+
+createdemobin sam3demo
+or
+createdemobin -profile at91sam3u-ek
+or
+createdemobin -width 320 -height 240 -bitdepth 16 -rotate 270 sam3demo
+
+The built-in default options are for Sam3u demo horizontal view, so you can convert it as first one to use default options.
+
+[Example 2:Generating demo binary of vertical view]:
+
+ For demo bin of vertical view(based on long side of LCD SCREEN) in sdcard or nandflash of at91sam3u-ek(sam3demo.ppt, and generated txt file and slide bitmap with macro):
+
+CreateDemoBin -width 240 -height 320 -bitdepth 16 -rotate 0 sam3demo
+
+*NOTE: after generation, must RENAME sam3demo.bin to samdemov.bin for vertical view.
+
+
+[Example 3:Merge two PPTs to generate a binary]:
+
+For example, PPT file Pa.ppt has 18 pages, PPT file Pb.ppt has 30 pages. It is required that all
+Pb.ppt slide pages should be inserted after the16th page into Pa.ppt:
+Steps:
+? Insert 30 empty pages after the 16th page of Pa.ppt
+? Enable macro security level to medium, and then import vb script macro Module1.bas
+? Run macro ExportPPTInfo, when proceeding to popup window for prompting conversion
+parameters, press cancel to ignore conversion step.
+? Insert 16 pages before the 1st page of Pb.ppt
+? Do steps 2 and 3 for Pb.ppt.
+? Delete slide information file Pa.txt section from slide 17 to slide 46, then copy slide
+information file Pb.txt section from slide 17 to slide 46 at the same position in Pa.txt
+? Copy picture files from slide17.bmp to slide46.bmp in Pb directory to Pa directory to
+overwrite them.
+? Use command sequences above to generate horizontal or vertical binary file.
+
+
+
+
+
diff --git a/utility/demo-fw/pc-tools/CreateDemoBin/src/CreateDemoBin.cpp b/utility/demo-fw/pc-tools/CreateDemoBin/src/CreateDemoBin.cpp
new file mode 100644
index 0000000..393880b
--- /dev/null
+++ b/utility/demo-fw/pc-tools/CreateDemoBin/src/CreateDemoBin.cpp
@@ -0,0 +1,1102 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include "regex.h"
+#include "EasyBMP.h"
+#include "ScriptParse.h"
+#include "DemoBinHeader.h"
+#include "CreateDemoBin.h"
+
+using namespace std;
+
+#define _GNU_SOURCE
+
+///////////////////////////////////////////////////////////////////////////////////////////
+//variable used
+//////////////////////////////////////////////////////////////////////////////////////////
+
+//slide bmp file name array
+static char pptSlidesBmp[MAXSLIDESPERBIN][256];
+//converted slide bmp file name array;
+static char pptSlidesResizedBmp[MAXSLIDESPERBIN][256];
+
+//generated PPT information txt file,default set as Sam3DEMO.txt
+//will be changed based execution argument
+static char pptScriptLink[256] = "Sam3DEMO.txt";
+//generated demo bin file name
+//will be changed based on execution argument
+static char pAtmlDemoBin[256] = "Sam3DEMO.bin";
+//temp file to link all bitmap file, used during creation,will be removed
+//in the end of conversion
+static char pBinContent[256] = "Sam3DEMOContent.tmp";
+
+//variables for parsing script file
+static char line[6*MAXSCRIPTSTRINGLINE];//[6][128];
+static unsigned int slidecnt, slidewidth, slideheight;
+static unsigned int linkcnt, linktop, linkleft, linkwidth, linkheight;
+static unsigned int dispboxtop, dispboxleft, dispboxwidth, dispboxheight;
+static char linkaddr[MAXLINKLEN];
+static char oninitcmds[MAXLINKLEN], onrefreshcmds[MAXLINKLEN], onclosecmds[MAXLINKLEN];
+
+//used to count slides parsed.
+static unsigned int loop=0;
+//binfile header
+static DemoBINHeader binhead;
+//each slide information. valid count is binhead.slidecount
+static SlideINFOHeader slideinfo[MAXSLIDESPERBIN];
+//used to store parsed slides index for reading slide bmp file
+static unsigned int parsedslides[MAXSLIDESPERBIN];
+
+//////////////////////////////////////////////////////////////////////////////////
+//Internal function
+/////////////////////////////////////////////////////////////////////////////////
+
+//rotate BMP with clockwise angel 90 degree
+static bool Rotate90(BMP &Input, BMP &Output)
+{
+ bool bRet = true;
+ int srcHeight = Input.TellHeight();
+ int srcWidth = Input.TellWidth();
+
+ bRet &= Output.SetSize(srcHeight,srcWidth);
+
+ for(int xpos = 0;xpos < srcWidth; xpos++)
+ {
+ for(int ypos=0;ypos<srcHeight;ypos++)
+ {
+ bRet &= Output.SetPixel(srcHeight-1-ypos,xpos,Input.GetPixel(xpos,ypos));
+ }
+ }
+
+ return bRet;
+}
+
+//Rotate BMP with clockwise angel 180 degree
+static bool Rotate180(BMP &Input, BMP &Output)
+{
+ bool bRet = true;
+ int srcHeight = Input.TellHeight();
+ int srcWidth = Input.TellWidth();
+
+ bRet &= Output.SetSize(srcWidth,srcHeight);
+
+ for(int xpos = 0;xpos < srcWidth; xpos++)
+ {
+ for(int ypos=0;ypos<srcHeight;ypos++)
+ {
+ bRet &= Output.SetPixel(srcWidth-1-xpos,srcHeight-1-ypos,Input.GetPixel(xpos,ypos));
+ }
+ }
+
+ return bRet;
+}
+
+//Rotate BMP with clockwise angel 270 degree
+static bool Rotate270(BMP &Input, BMP &Output)
+{
+ bool bRet = true;
+ int srcHeight = Input.TellHeight();
+ int srcWidth = Input.TellWidth();
+
+ bRet &= Output.SetSize(srcHeight,srcWidth);
+
+ for(int xpos = 0;xpos < srcWidth; xpos++)
+ {
+ for(int ypos=0;ypos<srcHeight;ypos++)
+ {
+ bRet &= Output.SetPixel(ypos,srcWidth-1-xpos,Input.GetPixel(xpos,ypos));
+ }
+ }
+
+ return bRet;
+}
+
+//rotate bmp file with clockwise angel
+static bool Rotate(char *pInBmp, char *pOutBmp, unsigned int angle)
+{
+ bool bRet=false;
+
+ //no need to do anything for 0,360,720...
+ if(angle % 360 == 0) {
+ return true;
+ }
+
+ BMP Input;
+ Input.ReadFromFile(pInBmp);
+ BMP Output;
+ Output.SetBitDepth(Input.TellBitDepth());
+
+ switch(angle) {
+ case 90:
+ bRet = Rotate90(Input, Output);
+ break;
+
+ case 180:
+ bRet = Rotate180(Input,Output);
+ break;
+
+ case 270:
+ bRet = Rotate270(Input,Output);
+ break;
+
+ default:
+ fprintf(stderr, "\n\r Sorry, rotation angle other than 90,180,270 is not supported yet!");
+ bRet = false;
+ break;
+ }
+
+ if(bRet)
+ bRet &= Output.WriteToFile(pOutBmp);
+
+ return bRet;
+}
+
+//Read a not empty string line from file
+static bool GetLineNoEmpty(FILE *fp, char *buf, size_t len)
+{
+ char *str=NULL;
+
+ do {
+ str = fgets(buf, len, fp);
+
+ if(!str) {
+ //fprintf(stderr, "\n\rFail to get a line!");
+ return false;
+ }
+ }while(IsSpaceLine(buf));
+
+ return true;
+}
+
+//convert a box zone coordinate based on rotate angle and coordinate origin
+//input coordinate value use upper left as (0,0) coordinate origin
+static bool HotZoneCoordinateConversion(
+ //following four params define a box zone
+ //value is in unresized coordinate, origin point is UPPER_LEFT
+ unsigned int raw_zone_top,
+ unsigned int raw_zone_left,
+ unsigned int raw_zone_width,
+ unsigned int raw_zone_height,
+ //following four param discribe
+ unsigned int resizedwidth,
+ unsigned int resizedheight,
+ double widthresizeratio,
+ double heightresizeratio,
+ //clockwise rotate angle
+ unsigned int rotateangle,
+ //coordinate origin remap, input values use PIC UPPER_LEFT as origin point
+ unsigned int *out_zone_bottom,
+ unsigned int *out_zone_left,
+ unsigned int *out_zone_width,
+ unsigned int *out_zone_height)
+{
+ unsigned int resizedzonetop, resizedzoneleft, resizedzonewidth, resizedzoneheight;
+ unsigned int rotatedzonetop, rotatedzoneleft, rotatedzonewidth, rotatedzoneheight;
+
+ resizedzonetop = (unsigned int)(raw_zone_top * heightresizeratio);
+ resizedzoneleft = (unsigned int)(raw_zone_left * widthresizeratio);
+ resizedzonewidth = (unsigned int)(raw_zone_width * widthresizeratio);
+ resizedzoneheight = (unsigned int)(raw_zone_height * heightresizeratio);
+
+ switch(rotateangle) {
+ case 0:
+ rotatedzonetop = resizedzonetop;
+ rotatedzoneleft = resizedzoneleft;
+ rotatedzonewidth = resizedzonewidth;
+ rotatedzoneheight = resizedzoneheight;
+ break;
+ case 90:
+ rotatedzonetop = resizedwidth - (resizedzoneleft + resizedzonewidth);
+ rotatedzoneleft = resizedheight - (resizedzonetop + resizedzoneheight);
+ rotatedzonewidth = resizedzoneheight;
+ rotatedzoneheight = resizedzonewidth;
+ break;
+ case 180:
+ rotatedzonetop = resizedheight - (resizedzonetop + resizedzoneheight);
+ rotatedzoneleft = resizedwidth - (resizedzoneleft + resizedzonewidth);
+ rotatedzonewidth = resizedzonewidth;
+ rotatedzoneheight = resizedzoneheight;
+ break;
+ case 270:
+ rotatedzonetop = resizedwidth - (resizedzoneleft + resizedzonewidth);
+ rotatedzoneleft = resizedzonetop;
+ rotatedzonewidth = resizedzoneheight;
+ rotatedzoneheight = resizedzonewidth;
+ break;
+ case 360:
+ rotatedzonetop = resizedzonetop;
+ rotatedzoneleft = resizedzoneleft;
+ rotatedzonewidth = resizedzonewidth;
+ rotatedzoneheight = resizedzoneheight;
+ break;
+ default:
+ fprintf(stderr, "\n Sorry, rotate angle other than 0, 90, 180, 270,360 not supported yet!");
+ return false;
+ }
+
+ if(out_zone_bottom && out_zone_left && out_zone_width && out_zone_height) {
+ *out_zone_bottom = rotatedzonetop + rotatedzoneheight;
+ *out_zone_left = rotatedzoneleft;
+ *out_zone_width = rotatedzonewidth;
+ *out_zone_height = rotatedzoneheight;
+ }else {
+ fprintf(stderr, "\n One of output param point is null in HotZoneCoordinateConversion(...)!");
+ return false;
+ }
+
+ return true;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////
+//Export functions:
+// Steps to Create demo bin
+////////////////////////////////////////////////////////////////////////////////////
+
+//Initialize filename variables
+void Step1_CreateFileNameVars(char * name)
+{
+ sprintf(pptScriptLink, "%s.txt", name);
+
+ for(int i = 0; i < MAXSLIDESPERBIN; ++i) {
+ #if !defined(MOVIE_MERGE_on)
+ sprintf(&pptSlidesBmp[i][0],"%s\\\\slide%d.bmp",name, i+1);
+ #else
+ if(i<9 && i>=0){
+ sprintf(&pptSlidesBmp[i][0],"%s\\\\speedway_loop_medium00%d.bmp",name, i+1);
+ } else if (i <99) {
+ sprintf(&pptSlidesBmp[i][0],"%s\\\\speedway_loop_medium0%d.bmp",name, i+1);
+ } else{
+ sprintf(&pptSlidesBmp[i][0],"%s\\\\speedway_loop_medium%d.bmp",name, i+1);
+ }
+ printf("\n\r name: %s", &pptSlidesBmp[i][0]);
+ #endif
+ }
+
+ for(int j = 0; j < MAXSLIDESPERBIN; ++j) {
+ sprintf(&pptSlidesResizedBmp[j][0], "%s\\\\slide%d_resized.bmp", name, j+1);
+ }
+
+ sprintf(pBinContent, "%scontent.tmp", name);
+ sprintf(pAtmlDemoBin, "%s.bin", name);
+
+}
+
+//Process ppt information txt file
+bool Step2_ProcessPPTInfoFile(BMPConvOpt *pOption)
+{
+ //open script file to process
+ FILE *pScriptfile = fopen(pptScriptLink, "rb");
+ if(!pScriptfile)
+ {
+ fclose(pScriptfile);
+ fprintf(stderr, "\n\r Open ppt info txt file %s for creating demo bin fails!", pptScriptLink);
+ return false;
+ }
+
+ //compile all regex pattern, if fail return
+ if(!CompileAllPtn()) {
+ fclose(pScriptfile);
+ FreeAllRegex();
+ fprintf(stderr, "\n\r Compilation pattern fails!");
+ return false;
+ }
+
+ //clear all fields with 0xFF
+ ClearDemoBINHeader(&binhead);
+ for(int i=0;i<MAXSLIDESPERBIN;++i){
+ ClearSlideINFOHeader(&slideinfo[i]);// use 0xFF to clear, considering flash using 0xff as raw data
+ }
+
+ //clear count fields as 0
+ binhead.slidecount = 0;
+ for(int i=0;i<MAXSLIDESPERBIN;++i){
+ slideinfo[i].linkcount = 0;
+ slideinfo[i].dispboxcount = 0;//default 0 means no display box
+ slideinfo[i].propyes = 0; //default 0 means no properties settings
+ }
+
+ //read first line of script file
+ if(!GetLineNoEmpty(pScriptfile, line, MAXSCRIPTSTRINGLINE)) {
+ fclose(pScriptfile);
+ FreeAllRegex();
+ fprintf(stderr, "\n\r Fail to read a effective string line from script file !");
+ return false;
+ }
+
+ //check first line if it match start of slide section
+ if(!IsSlideSectionStart(line)) {
+ fclose(pScriptfile);
+ FreeAllRegex();
+ fprintf(stderr, "\n\r Script file format is not right for slide section starting!");
+ return false;
+ }
+
+ //start loop of parsing script
+ for(loop = 0;loop < MAXSLIDESPERBIN ;++loop) {
+
+ //read slide section from script file, 4 lines information each slide section
+ for(int i = 1; i < 4; ++i) {
+ if(!GetLineNoEmpty(pScriptfile, line+i*MAXSCRIPTSTRINGLINE, MAXSCRIPTSTRINGLINE)) {
+ fclose(pScriptfile);
+ FreeAllRegex();
+ fprintf(stderr, "\n\r Script file format is not right for slide section!");
+ return false;
+ }
+ }
+
+ //parse slide section, to get slide count, slide width, slide height
+ if(!ParseSlideSection(line, &slidecnt, &slidewidth, &slideheight)) {
+ fclose(pScriptfile);
+ FreeAllRegex();
+ fprintf(stderr, "\n\r Script file format is not right for slide section!");
+ return false;
+ }
+
+ //a slide section found, set some fields.
+ //width and height gotten above will be used to calculating resized link box
+ //gotten slide count will be used to index file name
+ ++binhead.slidecount;
+ if(binhead.slidecount > MAXSLIDESPERBIN){
+ //reach max slide per bin
+ binhead.slidecount = MAXSLIDESPERBIN;
+ break;
+ }
+
+ parsedslides[loop]= slidecnt - 1;//record file index in the file name array
+
+ //store temp, as index to file name array, slides index in bin file not depends on this
+ //parsedslides[binhead.slidecount - 1] = slidecnt;//store temp, as index to file name array
+
+ //if rotate angle is times of 180 degree, then no need to switch width and height
+ #if defined(SLIDESHOW_MERGE_on)
+ if(pOption->ssPageNumber > 0 && loop < pOption->ssPageNumber){
+ #endif
+ if(pOption->rotateangle % 180 == 0){
+ slideinfo[binhead.slidecount - 1].slidewidth = pOption->width;//fixed for demo
+ slideinfo[binhead.slidecount - 1].slideheight = pOption->height;//fixed for demo
+ } else if(pOption->rotateangle % 90 == 0) {
+ //if rotate angle is times of 90 degree, but not times of 2*90 degree,
+ //then switch width and height
+ slideinfo[binhead.slidecount - 1].slidewidth = pOption->height;//fixed for demo
+ slideinfo[binhead.slidecount - 1].slideheight = pOption->width;//fixed for demo
+ } else {
+ fprintf(stderr, "\n Sorry, rotate angle %u not supported for coordinate conversion!", pOption->rotateangle);
+ fclose(pScriptfile);
+ FreeAllRegex();
+ return false;
+ }
+ #if defined(SLIDESHOW_MERGE_on)
+ }
+ else {
+ if(pOption->ssRotateangle % 180 == 0){
+ slideinfo[binhead.slidecount - 1].slidewidth = pOption->ssWidth;//fixed for demo
+ slideinfo[binhead.slidecount - 1].slideheight = pOption->ssHeight;//fixed for demo
+ } else if(pOption->ssRotateangle % 90 == 0) {
+ //if rotate angle is times of 90 degree, but not times of 2*90 degree,
+ //then switch width and height
+ slideinfo[binhead.slidecount - 1].slidewidth = pOption->ssHeight;//fixed for demo
+ slideinfo[binhead.slidecount - 1].slideheight = pOption->ssWidth;//fixed for demo
+ } else {
+ fprintf(stderr, "\n Sorry, rotate angle %u not supported for coordinate conversion!", pOption->ssRotateangle);
+ fclose(pScriptfile);
+ FreeAllRegex();
+ return false;
+ }
+ }
+ #endif
+
+ //parse each slide info field,i.e. display box, hyperlink, property config section for now
+ for(;;) {
+ //read available line in ppt information txt file
+ if(!GetLineNoEmpty(pScriptfile, line, MAXSCRIPTSTRINGLINE)) {
+ if(feof(pScriptfile)) {
+ //end of file
+ printf("\n\r OK, reach script file end!");
+ fclose(pScriptfile);
+ FreeAllRegex();
+ return true;
+ }
+ fclose(pScriptfile);
+ FreeAllRegex();
+ fprintf(stderr, "\n\r Script file format is not right for slide info organization!");
+ return false;
+ }
+
+ //
+ //Is it slide section?
+ //
+ if(IsSlideSectionStart(line))
+ break;//yes, break parsing slide info loop and goto next loop of parsing slide section
+
+ //
+ //Is it slide properties section?
+ //
+ if(IsPropertiesSectionStart(line)) {
+ //
+ //Note: Ony 1 properties field in bin file,
+ // So only the lastest properties section content will be recorded!!!
+ //
+
+ //properties section, read remained section string lines
+ for(int i = 1; i < 4; ++i) {
+ if(!GetLineNoEmpty(pScriptfile, line+i*MAXSCRIPTSTRINGLINE, MAXSCRIPTSTRINGLINE)) {
+ fclose(pScriptfile);
+ FreeAllRegex();
+ fprintf(stderr, "\n\r Script file format is not right for 'Properties' section!");
+ return false;
+ }
+ }
+
+ if(!ParsePropertiesSection(line, \
+ oninitcmds, \
+ onrefreshcmds, \
+ onclosecmds)) {
+ fclose(pScriptfile);
+ FreeAllRegex();
+ fprintf(stderr, "\n\r Script file format is not righ for slide 'Properties' section!");
+ return false;
+ }
+
+ //setting flag to indicate having property settings for this slide
+ slideinfo[binhead.slidecount - 1].propyes = 1;
+ slideinfo[binhead.slidecount - 1].propinfo.propcnt = 3;
+ strcpy(slideinfo[binhead.slidecount - 1].propinfo.onInitCmds, oninitcmds);
+ strcpy(slideinfo[binhead.slidecount - 1].propinfo.onRefreshCmds, onrefreshcmds);
+ strcpy(slideinfo[binhead.slidecount - 1].propinfo.onCloseCmds, onclosecmds);
+
+ continue;
+ }
+
+ //
+ //Is it Display box section?
+ //
+ if(IsDispBoxSectionStart(line)) {
+ //display box section, read remained section string lines
+ for(int i = 1; i < 5; ++i) {
+ if(!GetLineNoEmpty(pScriptfile, line+i*MAXSCRIPTSTRINGLINE, MAXSCRIPTSTRINGLINE)) {
+ fclose(pScriptfile);
+ FreeAllRegex();
+ fprintf(stderr, "\n\r Script file format is not right for 'DisplayBox' section!");
+ return false;
+ }
+ }
+
+ //parse display box section
+ if(!ParseDispBoxSection(line, \
+ &dispboxtop, &dispboxleft, &dispboxwidth, &dispboxheight)) {
+ fclose(pScriptfile);
+ FreeAllRegex();
+ fprintf(stderr, "\n\r Script file format is not right for 'DisplayBox' section!");
+ return false;
+ }
+
+ //have display box in slide
+ ++slideinfo[binhead.slidecount - 1].dispboxcount;
+ if(slideinfo[binhead.slidecount - 1].dispboxcount > MAX_DISPBOX_PER_SLIDE) {
+ //reach max display box for a slide
+ slideinfo[binhead.slidecount - 1].dispboxcount = MAX_DISPBOX_PER_SLIDE;
+ continue;
+ }
+
+ //resized ratio
+ double width_ratio;
+ double height_ratio;
+ unsigned int conv_bottom, conv_left, conv_width, conv_height;
+ #if defined(SLIDESHOW_MERGE_on)
+ if(pOption->ssPageNumber > 0 && loop < pOption->ssPageNumber){
+ #endif
+ width_ratio = pOption->width / (double)slidewidth;
+ height_ratio = pOption->height / (double)slideheight;
+
+ #if defined(SLIDESHOW_MERGE_on)
+ }
+ else{
+ width_ratio = pOption->ssWidth / (double)slidewidth;
+ height_ratio = pOption->ssHeight / (double)slideheight;
+ }
+ #endif
+
+ unsigned int tmpRet;
+ #if defined(SLIDESHOW_MERGE_on)
+ if(pOption->ssPageNumber > 0 && loop < pOption->ssPageNumber){
+ #endif
+ tmpRet = HotZoneCoordinateConversion(
+ dispboxtop,
+ dispboxleft,
+ dispboxwidth,
+ dispboxheight,
+ pOption->width,
+ pOption->height,
+ width_ratio,
+ height_ratio,
+ pOption->rotateangle,
+ &conv_bottom,
+ &conv_left,
+ &conv_width,
+ &conv_height);
+ #if defined(SLIDESHOW_MERGE_on)
+ }
+ else{
+ tmpRet = HotZoneCoordinateConversion(
+ dispboxtop,
+ dispboxleft,
+ dispboxwidth,
+ dispboxheight,
+ pOption->ssWidth,
+ pOption->ssHeight,
+ width_ratio,
+ height_ratio,
+ pOption->ssRotateangle,
+ &conv_bottom,
+ &conv_left,
+ &conv_width,
+ &conv_height);
+ }
+ #endif
+ if(!tmpRet)
+ {
+ fclose(pScriptfile);
+ FreeAllRegex();
+ fprintf(stderr, "\n Script file format is not right!");
+ return false;
+ }
+ unsigned int slideindex = binhead.slidecount - 1;
+ unsigned int dispboxindex = slideinfo[binhead.slidecount-1].dispboxcount - 1;
+ slideinfo[slideindex].dispboxinfo[dispboxindex].dispboxbottom = conv_bottom;
+ slideinfo[slideindex].dispboxinfo[dispboxindex].dispboxleft = conv_left;
+ slideinfo[slideindex].dispboxinfo[dispboxindex].dispboxwidth = conv_width;
+ slideinfo[slideindex].dispboxinfo[dispboxindex].dispboxheight = conv_height;
+
+ continue;
+ }
+
+ //
+ //Is it hyperlink section?
+ //
+ if(IsLinkSectionStart(line)) {
+
+ //hyperlink section, read remained section string lines
+ for(int i = 1; i < 6; ++i) {
+ if(!GetLineNoEmpty(pScriptfile, line+i*MAXSCRIPTSTRINGLINE, MAXSCRIPTSTRINGLINE)) {
+ fclose(pScriptfile);
+ FreeAllRegex();
+ fprintf(stderr, "\n\r Script file format is not right!");
+ return false;
+ }
+ }
+
+ //parse hyperlink section
+ if(!ParseLinkSection(line, &linkcnt, linkaddr, \
+ &linktop, &linkleft, &linkwidth, &linkheight)) {
+ fclose(pScriptfile);
+ FreeAllRegex();
+ fprintf(stderr, "\n\r Script file format is not right!");
+ return false;
+ }
+
+ //parsed linkcnt is not used, considering if some links were removed by manual
+ ++(slideinfo[binhead.slidecount - 1].linkcount);
+ if(slideinfo[binhead.slidecount - 1].linkcount > MAX_LINK_PER_SLIDE) {
+ //reach max link limit for a slide
+ slideinfo[binhead.slidecount - 1].linkcount = MAX_LINK_PER_SLIDE;
+ continue;
+ }
+
+ //resize ratio
+ double width_ratio;
+ double height_ratio;
+ unsigned int conv_bottom, conv_left, conv_width, conv_height;
+ #if defined(SLIDESHOW_MERGE_on)
+ if(pOption->ssPageNumber > 0 && loop < pOption->ssPageNumber){
+ #endif
+ width_ratio = pOption->width / (double)slidewidth;
+ height_ratio = pOption->height / (double)slideheight;
+ #if defined(SLIDESHOW_MERGE_on)
+ }
+ else{
+ width_ratio = pOption->ssWidth / (double)slidewidth;
+ height_ratio = pOption->ssHeight / (double)slideheight;
+ }
+ #endif
+ //printf("\n linktop %u, linkleft %u, linkwidth %u, linkheight %u",\
+ // linktop, linkleft, linkwidth, linkheight);
+ unsigned int tmpRet;
+ #if defined(SLIDESHOW_MERGE_on)
+ if(pOption->ssPageNumber > 0 && loop < pOption->ssPageNumber){
+ #endif
+ tmpRet = HotZoneCoordinateConversion(
+ //original link zone params, gotten from slide info txt file
+ linktop,
+ linkleft,
+ linkwidth,
+ linkheight,
+ //resized slide width and height
+ pOption->width,
+ pOption->height,
+ //resize ratio of width and height
+ width_ratio,
+ height_ratio,
+ //clockwise rotate angle
+ pOption->rotateangle,
+ //pointer of output link zone param
+ &conv_bottom,
+ &conv_left,
+ &conv_width,
+ &conv_height);
+ #if defined(SLIDESHOW_MERGE_on)
+ }
+ else{
+ tmpRet = HotZoneCoordinateConversion(
+ //original link zone params, gotten from slide info txt file
+ linktop,
+ linkleft,
+ linkwidth,
+ linkheight,
+ //resized slide width and height
+ pOption->ssWidth,
+ pOption->ssHeight,
+ //resize ratio of width and height
+ width_ratio,
+ height_ratio,
+ //clockwise rotate angle
+ pOption->ssRotateangle,
+ //pointer of output link zone param
+ &conv_bottom,
+ &conv_left,
+ &conv_width,
+ &conv_height);
+ }
+ #endif
+ if(!tmpRet)
+ {
+ //link hot zone coordinate conversion fail, then return false
+ fclose(pScriptfile);
+ FreeAllRegex();
+ fprintf(stderr, "\n Link zone coordinate conversion fail!");
+ return false;
+ }
+
+ //set the slideinfo link value, noted bmp was rotated and resized.
+ unsigned int linkindex = slideinfo[binhead.slidecount-1].linkcount - 1;
+ unsigned int slideindex = binhead.slidecount - 1;
+ slideinfo[slideindex].linkinfo[linkindex].linkboxbottom = conv_bottom;
+ slideinfo[slideindex].linkinfo[linkindex].linkboxleft = conv_left;
+ slideinfo[slideindex].linkinfo[linkindex].linkboxwidth = conv_width;
+ slideinfo[slideindex].linkinfo[linkindex].linkboxheight = conv_height;
+
+#ifdef DEBUG_LINKSECTION
+ printf("\n\r [slide %d, link box %d is %u, %u, %u, %u,addr %s]", slideindex, linkindex,\
+ slideinfo[slideindex].linkinfo[linkindex].linkboxbottom,\
+ slideinfo[slideindex].linkinfo[linkindex].linkboxleft,\
+ slideinfo[slideindex].linkinfo[linkindex].linkboxwidth,\
+ slideinfo[slideindex].linkinfo[linkindex].linkboxheight, \
+ linkaddr);
+#endif
+
+ strcpy(slideinfo[slideindex].linkinfo[linkindex].linkstring, linkaddr);
+
+ continue;
+ }
+
+ //not slide section, not hyperlink section, not display box section, then err
+ fclose(pScriptfile);
+ FreeAllRegex();
+ fprintf(stderr, "\n\r Script file format is not right!");
+ return false;
+
+ }
+ }
+
+ return true;
+}
+
+
+//Resize and Rotate slides
+bool Step3_ResizeAndRotateSlideBMP(BMPConvOpt *pOption)
+{
+ bool bRet=true;
+ BMP pptBMP;
+
+ SetEasyBMPwarningsOff();//set warning message on
+
+ //set pic width and height
+ ScaleParam scale;
+
+ //picture number
+ #if defined(MOVIE_MERGE_on)
+ binhead.slidecount = pOption->mvSlideNumber;
+ #endif
+ int picNum = binhead.slidecount; //sizeof(pptSlidesBmp)/sizeof(char*);
+ //printf("\n\r has %d slides", picNum);
+
+ //resize all picture
+ int i;
+ for(i=0; i<picNum;++i) {
+
+ #if defined(SLIDESHOW_MERGE_on)
+ if(pOption->ssPageNumber > 0 && i < pOption->ssPageNumber){
+ #endif
+ scale.dimension.width = pOption->width;
+ scale.dimension.height = pOption->height;
+ #if defined(SLIDESHOW_MERGE_on)
+ }
+ else{
+ scale.dimension.width = pOption->ssWidth;
+ scale.dimension.height = pOption->ssHeight;
+ }
+ #endif
+ //printf("\n\r process %s before create object",pptSlidesBmp[i]);
+ if(!pptBMP.ReadFromFile(pptSlidesBmp[i])) {
+ fprintf(stderr, "Fail to open slide bit map file for operation!");
+ return false;
+ }
+ //printf("\n\r process %s before rescale",pptSlidesBmp[i]);
+ bRet &= Rescale(pptBMP, 'd', scale);
+ //printf("\n\r process %s before setbitdepth",pptSlidesBmp[i]);
+ #if defined(SLIDESHOW_MERGE_on)
+ if(pOption->ssPageNumber > 0 && i < pOption->ssPageNumber){
+ #endif
+ bRet &= pptBMP.SetBitDepth(pOption->bitdepth);
+ #if defined(SLIDESHOW_MERGE_on)
+ }
+ else{
+ bRet &= pptBMP.SetBitDepth(pOption->ssBitdepth);
+ }
+ #endif
+
+ //printf("\n\r process %s before writefile",pptSlidesBmp[i]);
+ if(!pptBMP.WriteToFile(pptSlidesResizedBmp[i])) {
+ fprintf(stderr, "Fail to open file to write converted bitmap file!");
+ return false;
+ }
+
+ //Rotate BMP
+
+
+
+ #if defined(SLIDESHOW_MERGE_on)
+ if(pOption->ssPageNumber > 0 && i < pOption->ssPageNumber){
+ #endif
+ bRet &= Rotate(pptSlidesResizedBmp[i], pptSlidesResizedBmp[i], pOption->rotateangle);
+ #if defined(SLIDESHOW_MERGE_on)
+ }
+ else{
+ bRet &= Rotate(pptSlidesResizedBmp[i], pptSlidesResizedBmp[i], pOption->ssRotateangle);
+ }
+ #endif
+#ifdef DEBUG_CONVBMPINFO
+ FILE *pBmpFile;
+ pBmpFile = fopen(pptSlidesResizedBmp[i], "rb");
+ if(!pBmpFile) {
+ fprintf(stderr, "\n\r fail to open");
+ exit(3);
+ }
+ BMPHeader bmpHead;
+ fread((char*)&bmpHead, 1, sizeof(BMPHeader), pBmpFile);
+ fclose(pBmpFile);
+
+ printf("\n\r============bmp header==============");
+ printf("\n\r bmp.type is %x", bmpHead.type);
+ printf("\n\r bmp.filesize is %d", bmpHead.fileSize);
+ printf("\n\r bmp.width is %d", bmpHead.width);
+ printf("\n\r bmp.height is %d", bmpHead.height);
+ printf("\n\r bmp.compressed is %d", bmpHead.compression);
+ printf("\n\r bmp.bitdepth is %d", bmpHead.bits);
+
+#endif
+
+ }
+
+ return bRet;
+}
+
+//create demo bin from above variables
+bool Step4_GenerateDemoBin(BMPConvOpt *pOption)
+{
+ FILE *pBMPfile, *pBinContentfile, *pDemoBin;
+ unsigned int offset;
+ unsigned int slideoffset[MAXSLIDESPERBIN];//store each slide offset in temp file
+ char buf[1024];//as read/write file buffer
+
+ //bin file tag 'ATML'
+ binhead.tag = (unsigned int)'L'<<24 | (unsigned int)'M'<<16 |
+ (unsigned int)'T'<<8 | (unsigned int) 'A';
+
+ //first open bincontentfile to store all parsed slide bmp file
+ pBinContentfile = fopen(pBinContent, "wb");
+ if(!pBinContentfile) {
+ fclose(pBinContentfile);
+ fprintf(stderr, "\n Open file fail during creating bin!");
+ return false;
+ }
+
+ slideoffset[0] = 0; offset = 0;
+ //write all parsed slide bmp files into a bincontentfile
+ for(unsigned int i = 0; i<binhead.slidecount; ++i) {
+
+ //at start of each loop, offset is stored with end of position of bincontentfile
+ unsigned int startoffset = offset;
+
+ //slides index bigger than available bmp files
+ if(parsedslides[i]> sizeof(pptSlidesResizedBmp)/ sizeof(char *)) {
+ fclose(pBinContentfile);
+ fprintf(stderr, "\n slide %u,i %u",parsedslides[i], i);
+ fprintf(stderr, "\n Script file and bmp file count is not consistent!");
+ return false;
+ }
+
+ #if !defined(MOVIE_MERGE_on)
+ pBMPfile = fopen(pptSlidesResizedBmp[parsedslides[i]], "rb");
+ #else
+ pBMPfile = fopen(pptSlidesResizedBmp[i], "rb");
+ #endif
+ if(!pBMPfile) {
+ fclose(pBinContentfile);
+ fclose(pBMPfile);
+ fprintf(stderr, "\n Open bmp file fail!");
+ return false;
+ }
+
+ //convert bmp file bitmap data format to meet sam3 lcd coordinate
+ if(pOption->reversebitmaporder){
+
+ struct stat filestat;
+ //////////////////////////
+ unsigned int width = 0;
+ unsigned int height = 0;
+
+ #if defined(SLIDESHOW_MERGE_on)
+ if(pOption->ssPageNumber > 0 && i < pOption->ssPageNumber){
+ #endif
+ width = pOption->width;
+ height = pOption->height;
+ #if defined(SLIDESHOW_MERGE_on)
+ }
+ else{
+ width = pOption->ssWidth;
+ height = pOption->ssHeight;
+ }
+ #endif
+ //default 270 rotate make the bmp look like column-aligned store
+ if(pOption->rotateangle % 180 == 0)
+ {
+ width = pOption->height;
+ height = pOption->width;
+ }
+ #if defined(SLIDESHOW_MERGE_on)
+ if(pOption->ssPageNumber > 0 && i < pOption->ssPageNumber){
+ #endif
+ if(pOption->rotateangle % 180 == 0)
+ {
+ width = pOption->height;
+ height = pOption->width;
+ }
+ #if defined(SLIDESHOW_MERGE_on)
+ }
+ else{
+ if(pOption->ssRotateangle % 180 == 0)
+ {
+ width = pOption->ssHeight;
+ height = pOption->ssWidth;
+ }
+ }
+ #endif
+ //////////////////////////
+ fstat(fileno(pBMPfile), &filestat);
+
+ //printf("\n\r filesize is %u", filestat.st_size);
+ char *bmpfilebuf = (char *)malloc(filestat.st_size+1024);
+ char *convbmpbuf = (char *)malloc(filestat.st_size+1024);
+
+ if(!bmpfilebuf || !convbmpbuf) {
+ fclose(pBMPfile);
+ fclose(pBinContentfile);
+ fprintf(stderr, "\n malloc space for bmp file fail!");
+ return false;
+ }
+
+ size_t numread = fread(bmpfilebuf, 1, filestat.st_size, pBMPfile);
+ if(numread != filestat.st_size) {
+ fclose(pBMPfile);
+ fclose(pBinContentfile);
+ fprintf(stderr, "\n Read bmp file length is not right!");
+ return false;
+ }
+ unsigned int bitmapoffset = ((BMPHeader *)bmpfilebuf)->offset;
+
+ unsigned int byteperpixel = ((BMPHeader *)bmpfilebuf)->bits;
+ if(byteperpixel != 8 && byteperpixel != 16 && byteperpixel !=24 ) {
+ fclose(pBMPfile);
+ fclose(pBinContentfile);
+ fprintf(stderr, "\n Conversion of bitmap order of bit depth %u is not supported yet!", byteperpixel);
+ return false;
+ }
+ byteperpixel /= 8;
+
+ memcpy(convbmpbuf, bmpfilebuf, bitmapoffset);
+
+ //printf("\n\r Begin to convert %ubit bitmap data to meet sam3 lcd format!",byteperpixel*8);
+ //convert orignal bitmap data to sam3-ek LCD api coordinate format
+ unsigned int j,k,s;
+ for (j = 0, s=0; j < width; ++j) {
+
+ for (k = 0; k < height && j*k*byteperpixel < filestat.st_size; k++) {
+
+ *(convbmpbuf+bitmapoffset+s) = bmpfilebuf[ bitmapoffset + \
+ ((width -j - 1)*height + k)*byteperpixel];
+ if(byteperpixel == 2) {
+ *(convbmpbuf+bitmapoffset+s+1) = bmpfilebuf[ bitmapoffset + \
+ ((width -j - 1)*height + k)*byteperpixel+1];
+ }
+ if(byteperpixel == 3) {
+ *(convbmpbuf+bitmapoffset+s+2) = bmpfilebuf[ bitmapoffset + \
+ ((width -j - 1)*height + k)*byteperpixel+2];
+ }
+ s += byteperpixel;
+ }
+ //printf("\n\r j is %d",j);
+ }
+
+ //printf("\n\r End to convert %ubit bitmap data!",byteperpixel*8);
+
+ //check if right long data conversion
+ if(j != width || k != height) {
+ fclose(pBMPfile);
+ fclose(pBinContentfile);
+ fprintf(stderr, "\n\r not all expected bitmap data converted!");
+ return false;
+ }
+
+ fwrite(convbmpbuf, 1, filestat.st_size, pBinContentfile);
+ offset += filestat.st_size;
+
+ free(convbmpbuf);
+ free(bmpfilebuf);
+ } else {
+ //directly write all bmp file into the tmp bincontent file
+ while(!feof(pBMPfile)) {
+ size_t numread = fread(buf, 1, 1024, pBMPfile);
+ fwrite(buf, 1, numread, pBinContentfile);
+ offset += numread;
+ }
+ }
+
+ //store this slide bmp file size
+ slideinfo[i].slidedatalength = offset - startoffset;
+ //printf("\n\r slide size is %u", slideinfo[i].slidedatalength);
+
+ //store offset for next slides
+ slideoffset[i+1]= offset;
+ //printf("\n\r offset is %d", offset);
+ fclose(pBMPfile);
+
+#ifdef DEBUG_DISPSECTION
+ printf("\n --Slide %u has %u display box", i+1, slideinfo[i].dispboxcount);
+ unsigned s;
+ for(s = 0; s < slideinfo[i].dispboxcount; ++s) {
+ printf("\n slide count is %d, botm %d, left %d, width %d, height %d",\
+ i+1, slideinfo[i].dispboxinfo[s].dispboxbottom, \
+ slideinfo[i].dispboxinfo[s].dispboxleft, \
+ slideinfo[i].dispboxinfo[s].dispboxwidth, \
+ slideinfo[i].dispboxinfo[s].dispboxheight);
+ }
+#endif
+
+ }
+ fclose(pBinContentfile);
+
+ //get header size
+ unsigned int headersize = sizeof(DemoBINHeader) + sizeof(SlideINFOHeader)* binhead.slidecount;
+
+ //set headersize field of DemoBINHeader
+ binhead.headersize = headersize;
+ //printf("\n\r headersize is %d", headersize);
+
+ //set file size field of DemoBINHeader
+ binhead.filesize = headersize + offset;//offset should be bincontent filesize now
+
+ //correct slide offset and then set them info information struct
+ for(unsigned int i = 0; i < binhead.slidecount; ++i) {
+ slideinfo[i].slideoffset = slideoffset[i] + headersize;
+}
+
+ pDemoBin = fopen(pAtmlDemoBin, "wb");
+ if(!pDemoBin) {
+ fclose(pDemoBin);
+ fprintf(stderr, "\n\r Open file fail during creating bin!");
+ return false;
+ }
+
+ #if !defined(MOVIE_MERGE_on)
+ fwrite(&binhead, 1, sizeof(DemoBINHeader), pDemoBin);
+ for(unsigned int i = 0; i < binhead.slidecount; ++i) {
+ fwrite(&slideinfo[i], 1, sizeof(SlideINFOHeader), pDemoBin);
+ }
+ #else
+ unsigned int tmpSlideCount = binhead.slidecount;
+ fwrite(&tmpSlideCount, 1, sizeof(unsigned int), pDemoBin);
+ #endif
+
+ //open pBinContentfile in read mode for writing final demo bin
+ pBinContentfile = fopen(pBinContent, "rb");
+ if(!pBinContentfile) {
+ fclose(pBinContentfile);
+ fprintf(stderr, "\n\r Open file fail during creating bin!");
+ return false;
+ }
+
+ //write the slide bin file to final demo bin
+ while(!feof(pBinContentfile)) {
+ size_t numread = fread(buf, 1, 1024, pBinContentfile);
+ fwrite(buf, 1, numread, pDemoBin);
+ }
+
+ fclose(pBinContentfile);
+ fclose(pDemoBin);
+
+ //remove temporary bincontentfile
+ if(remove(pBinContent))
+ fprintf(stderr, "\n\r Can't remove temporary file!");
+
+ return true;
+}
+
+//show generated bin contained bmp information
+void ShowEachBmpHeader()
+{
+ FILE *pBinfile;
+ DemoBINHeader binheader;
+ SlideINFOHeader slideinfo;
+ BMPHeader bmphead;
+
+ pBinfile = fopen(pAtmlDemoBin, "rb");
+ if(!pBinfile) {
+ fprintf(stderr, "\n\r Fail to open demo bin file!!");
+ return;
+ }
+
+ fread(&binheader, 1, sizeof(DemoBINHeader),pBinfile);
+ unsigned int slidecount = binheader.slidecount;
+ printf("\n\r Demo bin has %u slides", slidecount);
+
+ for(unsigned int j=0; j < slidecount;++j) {
+ fseek(pBinfile, sizeof(DemoBINHeader) + j *sizeof(SlideINFOHeader), SEEK_SET);
+ fread(&slideinfo, 1, sizeof(SlideINFOHeader), pBinfile);
+ printf("\n\r slide %d bitdata in %u,length %u",j, slideinfo.slideoffset, slideinfo.slidedatalength);
+ fseek(pBinfile, slideinfo.slideoffset, SEEK_SET);
+ fread(&bmphead, 1, sizeof(BMPHeader), pBinfile);
+ printf("\n\r============bmp header==============");
+ printf("\n\r bmp.type is %x", bmphead.type);
+ printf("\n\r bmp.filesize is %d", bmphead.fileSize);
+ printf("\n\r bmp.width is %d", bmphead.width);
+ printf("\n\r bmp.height is %d", bmphead.height);
+ printf("\n\r bmp.compressed is %d", bmphead.compression);
+ printf("\n\r bmp.bitdepth is %d", bmphead.bits);
+
+ }
+
+ fclose(pBinfile);
+}
+
diff --git a/utility/demo-fw/pc-tools/CreateDemoBin/src/ScriptParse.cpp b/utility/demo-fw/pc-tools/CreateDemoBin/src/ScriptParse.cpp
new file mode 100644
index 0000000..ad0c73b
--- /dev/null
+++ b/utility/demo-fw/pc-tools/CreateDemoBin/src/ScriptParse.cpp
@@ -0,0 +1,851 @@
+/*
+ * ScriptParse.cpp
+ *
+ * Created on: 2009-3-15
+ * Author: Tony.Liu
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include "regex.h"
+#include "ScriptParse.h"
+#include "DemoBinHeader.h"
+
+#define SUBSLEN 10
+#define EBUFLEN 128 /* error buffer length */
+#define BUFLEN 1024 /* matched buffer length */
+
+using namespace std;
+
+static size_t len;
+static regex_t reSpace;
+static regex_t reSlideCnt;
+static regex_t reSlideSize;
+static regex_t reSlideWidth;
+static regex_t reSlideHeight;
+
+static regex_t reSlideDispString;
+static regex_t reSlideDispTop;
+static regex_t reSlideDispLeft;
+static regex_t reSlideDispWidth;
+static regex_t reSlideDispHeight;
+
+static regex_t reSlideLink;
+static regex_t reSlideLinkAddr;
+static regex_t reSlideLinkTop;
+static regex_t reSlideLinkLeft;
+static regex_t reSlideLinkWidth;
+static regex_t reSlideLinkHeight;
+
+static regex_t reSlideProps;
+static regex_t reSlideOnInitCmds;
+static regex_t reSlideOnRefreshCmds;
+static regex_t reSlideOnCloseCmds;
+
+static regmatch_t subs[SUBSLEN];
+static char matched[BUFLEN];
+static char errbuf[EBUFLEN];
+
+static char *pSpacePtn = "^[[:space:]]+$";
+static char *pSlideCntPtn = "^Slide[[:blank:]]+([[:digit:]]+):[[:space:]]+$";
+static char *pSlideSizePtn = "^Slide Size:[[:space:]]+$";
+static char *pSlideWidthPtn = "^Width:[[:blank:]]+([[:digit:]]+([.][[:digit:]]+)?)[[:space:]]+$";
+static char *pSlideHeightPtn = "^Height:[[:blank:]]+([[:digit:]]+([.][[:digit:]]+)?)[[:space:]]+$";
+
+static char *pSlideDispBoxStringPtn = "^Display Box:[[:space:]]+$";
+static char *pSlideDispBoxTopPtn = "^Top:[[:blank:]]+([[:digit:]]+([.][[:digit:]]+)?)[[:space:]]+$";
+static char *pSlideDispBoxLeftPtn = "^Left:[[:blank:]]+([[:digit:]]+([.][[:digit:]]+)?)[[:space:]]+$";
+static char *pSlideDispBoxWidthPtn = "^Width:[[:blank:]]+([[:digit:]]+([.][[:digit:]]+)?)[[:space:]]+$";
+static char *pSlideDispBoxHeightPtn = "^Height:[[:blank:]]+([[:digit:]]+([.][[:digit:]]+)?)[[:space:]]+$";
+
+static char *pSlideLinkPtn = "^HyperLink[[:blank:]]+([[:digit:]]+)::[[:space:]]+$";
+static char *pSlideLinkAddrPtn = "^\"Link Address\":[[:blank:]]+[[:cntrl:]]*(.*)[[:space:]]+[[:cntrl:]]+$";
+static char *pSlideLinkTopPtn = "^Top:[[:blank:]]+([[:digit:]]+([.][[:digit:]]+)?)[[:space:]]+$";
+static char *pSlideLinkLeftPtn = "^Left:[[:blank:]]+([[:digit:]]+([.][[:digit:]]+)?)[[:space:]]+$";
+static char *pSlideLinkWidthPtn = "^Width:[[:blank:]]+([[:digit:]]+([.][[:digit:]]+)?)[[:space:]]+$";
+static char *pSlideLinkHeightPtn = "^Height:[[:blank:]]+([[:digit:]]+([.][[:digit:]]+)?)[[:space:]]+$";
+
+static char *pSlidePropsPtn = "^Properties::[[:space:]]+$";
+static char *pSlideOnInitCmdsPtn = "^OnInitCmds:[[:blank:]]*[[:cntrl:]]*(.*)[[:space:]]+[[:cntrl:]]+$";
+static char *pSlideOnRefreshCmdsPtn = "^OnRefreshCmds:[[:blank:]]*[[:cntrl:]]*(.*)[[:space:]]+[[:cntrl:]]+$";
+static char *pSlideOnCloseCmdsPtn = "^OnCloseCmds:[[:blank:]]*[[:cntrl:]]*(.*)[[:space:]]+[[:cntrl:]]+$";
+
+//compile pattern
+static bool CompileRegexPtn(regex_t *compiled, const char *pattern, int cflags)
+{
+ int err = regcomp (compiled, pattern, cflags);
+ if (err)
+ {
+ len = regerror (err, compiled, errbuf, sizeof (errbuf));
+ //printf("\n\r error compilation!");
+ fprintf (stderr, "error: regcomp: %s\n", errbuf);
+ return false;
+ }
+
+ return true;
+}
+
+//compile all pattern
+bool CompileAllPtn()
+{
+ bool bRet=true;
+
+ //compile slide section head pattern
+ bRet &= CompileRegexPtn(&reSpace, pSpacePtn, REG_EXTENDED | REG_NEWLINE);
+ bRet &= CompileRegexPtn(&reSlideCnt, pSlideCntPtn, REG_EXTENDED | REG_NEWLINE);
+ bRet &= CompileRegexPtn(&reSlideSize, pSlideSizePtn, REG_EXTENDED | REG_NEWLINE);
+ bRet &= CompileRegexPtn(&reSlideWidth, pSlideWidthPtn, REG_EXTENDED | REG_NEWLINE);
+ bRet &= CompileRegexPtn(&reSlideHeight, pSlideHeightPtn, REG_EXTENDED | REG_NEWLINE);
+
+ //compile display box section pattern
+ bRet &= CompileRegexPtn(&reSlideDispString, pSlideDispBoxStringPtn, REG_EXTENDED | REG_NEWLINE);
+ bRet &= CompileRegexPtn(&reSlideDispTop, pSlideDispBoxTopPtn, REG_EXTENDED | REG_NEWLINE);
+ bRet &= CompileRegexPtn(&reSlideDispLeft, pSlideDispBoxLeftPtn, REG_EXTENDED | REG_NEWLINE);
+ bRet &= CompileRegexPtn(&reSlideDispWidth, pSlideDispBoxWidthPtn, REG_EXTENDED | REG_NEWLINE);
+ bRet &= CompileRegexPtn(&reSlideDispHeight, pSlideDispBoxHeightPtn, REG_EXTENDED | REG_NEWLINE);
+
+ //compile hyperlink section pattern
+ bRet &= CompileRegexPtn(&reSlideLink, pSlideLinkPtn, REG_EXTENDED | REG_NEWLINE);
+ bRet &= CompileRegexPtn(&reSlideLinkAddr, pSlideLinkAddrPtn, REG_EXTENDED | REG_NEWLINE);
+ bRet &= CompileRegexPtn(&reSlideLinkTop, pSlideLinkTopPtn, REG_EXTENDED | REG_NEWLINE);
+ bRet &= CompileRegexPtn(&reSlideLinkLeft, pSlideLinkLeftPtn, REG_EXTENDED | REG_NEWLINE);
+ bRet &= CompileRegexPtn(&reSlideLinkWidth, pSlideLinkWidthPtn, REG_EXTENDED | REG_NEWLINE);
+ bRet &= CompileRegexPtn(&reSlideLinkHeight, pSlideLinkHeightPtn, REG_EXTENDED | REG_NEWLINE);
+
+ //compile slide config section pattern
+ bRet &= CompileRegexPtn(&reSlideProps, pSlidePropsPtn, REG_EXTENDED | REG_NEWLINE);
+ bRet &= CompileRegexPtn(&reSlideOnInitCmds, pSlideOnInitCmdsPtn, REG_EXTENDED | REG_NEWLINE);
+ bRet &= CompileRegexPtn(&reSlideOnRefreshCmds, pSlideOnRefreshCmdsPtn, REG_EXTENDED | REG_NEWLINE);
+ bRet &= CompileRegexPtn(&reSlideOnCloseCmds, pSlideOnCloseCmdsPtn, REG_EXTENDED | REG_NEWLINE);
+
+ return bRet;
+}
+
+//free compiled regex pattern
+void FreeAllRegex()
+{
+ //free slide section head patterns
+ regfree(&reSlideCnt);
+ regfree(&reSlideSize);
+ regfree(&reSlideWidth);
+ regfree(&reSlideHeight);
+
+ //free slide display box section patterns
+ regfree(&reSlideDispString);
+ regfree(&reSlideDispTop);
+ regfree(&reSlideDispLeft);
+ regfree(&reSlideDispWidth);
+ regfree(&reSlideDispHeight);
+
+ //free slide hyperlink section patterns
+ regfree(&reSlideLink);
+ regfree(&reSlideLinkAddr);
+ regfree(&reSlideLinkTop);
+ regfree(&reSlideLinkLeft);
+ regfree(&reSlideWidth);
+ regfree(&reSlideHeight);
+
+ //free slide config section pattern
+ regfree(&reSlideProps);
+ regfree(&reSlideOnInitCmds);
+ regfree(&reSlideOnRefreshCmds);
+ regfree(&reSlideOnCloseCmds);;
+}
+
+//match the pattern?
+bool RegexMatch(const regex_t *compiled, const char *string, size_t nmatch, regmatch_t *matchptr, int eflags)
+{
+ bool bRet = true;
+
+ int err = regexec (compiled, string, (size_t)nmatch, matchptr,eflags);
+
+ if (err == REG_NOMATCH)
+ {
+ //fprintf (stderr, "Sorry, no match ...\n");
+ bRet = false;
+ }
+ else if (err)
+ {
+ len = regerror (err, compiled, errbuf, sizeof (errbuf));
+ fprintf (stderr, "error: regexec: %s\n", errbuf);
+ bRet = false;
+ }
+
+ return bRet;
+}
+
+//is a space line?
+bool IsSpaceLine(const char *string)
+{
+ bool bRet = RegexMatch(&reSpace, string, 0,0,0);
+
+ return bRet;
+}
+
+//match slide count line and return the count
+bool GetSlideCount( const char *string, unsigned int *slidenum)
+{
+ bool bRet = false;
+
+#if defined(DEBUG_BEFOREPARSE) && defined(DEBUG_SLIDESECTION)
+ printf("\n\r [Parsing slide count string is %s", string);
+#endif
+
+ bRet = RegexMatch(&reSlideCnt,string, (size_t)SUBSLEN, subs, 0);
+ //not match pattern
+ if(!bRet) {
+ fprintf(stderr, "\n\rNot slide count line...!");
+ return bRet;
+ }
+
+// printf("\n\r %d, %d",subs[1].rm_eo, subs[1].rm_so);
+ int len = subs[1].rm_eo - subs[1].rm_so;
+ memcpy (matched, string + subs[1].rm_so, len);
+ matched[len] = '\0';
+
+#if defined(DEBUG_AFTERPARSE) && defined(DEBUG_SLIDESECTION)
+ printf("\n\r Parsed slide count is %s]",matched);
+#endif
+
+ *slidenum = (unsigned int)floor(atof(matched));
+
+ return bRet;
+}
+
+//check slide size line is correct
+bool IsSlideSizeString(const char *string)
+{
+ bool bRet = false;
+
+ bRet = RegexMatch(&reSlideSize,string, (size_t)SUBSLEN, subs, 0);
+ //not match pattern
+ if(!bRet) {
+ fprintf(stderr, "\n\rNot slide size string line...!");
+ return bRet;
+ }
+
+ return bRet;
+}
+
+//match slide width line and return the width
+bool GetSlideWidth( const char *string, unsigned int *slidewidth)
+{
+ bool bRet = false;
+
+#if defined(DEBUG_BEFOREPARSE) && defined(DEBUG_SLIDESECTION)
+ printf("\n\r [Parsing slide width string is %s", string);
+#endif
+
+ bRet = RegexMatch(&reSlideWidth,string, (size_t)SUBSLEN, subs, 0);
+ //not match pattern
+ if(!bRet) {
+ fprintf(stderr, "\n\rNot slide width line...!");
+ return bRet;
+ }
+
+// printf("\n\r %d, %d",subs[1].rm_eo, subs[1].rm_so);
+ int len = subs[1].rm_eo - subs[1].rm_so;
+ memcpy (matched, string + subs[1].rm_so, len);
+ matched[len] = '\0';
+
+#if defined(DEBUG_AFTERPARSE) && defined(DEBUG_SLIDESECTION)
+ printf("\n\r Parsed slide width is %s]",matched);
+#endif
+
+ *slidewidth = (unsigned int)floor(atof(matched));
+
+ return bRet;
+}
+
+//match slide height line and return the height
+bool GetSlideHeight( const char *string, unsigned int *slideheight)
+{
+ bool bRet = false;
+
+#if defined(DEBUG_BEFOREPARSE) && defined(DEBUG_SLIDESECTION)
+ printf("\n\r [Parsing slide height string is %s", string);
+#endif
+
+ bRet = RegexMatch(&reSlideHeight,string, (size_t)SUBSLEN, subs, 0);
+ //not match pattern
+ if(!bRet) {
+ fprintf(stderr, "\n\rNot slide height line...!");
+ return bRet;
+ }
+
+// printf("\n\r %d, %d",subs[1].rm_eo, subs[1].rm_so);
+ int len = subs[1].rm_eo - subs[1].rm_so;
+ memcpy (matched, string + subs[1].rm_so, len);
+ matched[len] = '\0';
+
+#if defined(DEBUG_AFTERPARSE) && defined(DEBUG_SLIDESECTION)
+ printf("\n\r Parsed slide height is %s]",matched);
+#endif
+
+ *slideheight = (unsigned int)floor(atof(matched));
+
+ return bRet;
+}
+
+//match link top line and return link top position
+bool GetDispBoxTop(const char *string, unsigned int *top)
+{
+ bool bRet = false;
+
+#if defined(DEBUG_BEFOREPARSE) && defined(DEBUG_DISPBOXSECTION)
+ printf("\n\r [Parsing display box top string is %s", string);
+#endif
+
+ bRet = RegexMatch(&reSlideDispTop, string, (size_t)SUBSLEN, subs, 0);
+ //not match pattern
+ if(!bRet) {
+ fprintf(stderr, "\n\rNot link top line...!");
+ return bRet;
+ }
+
+// printf("\n\r %d, %d",subs[1].rm_eo, subs[1].rm_so);
+ int len = subs[1].rm_eo - subs[1].rm_so;
+ memcpy (matched, string + subs[1].rm_so, len);
+ matched[len] = '\0';
+
+#if defined(DEBUG_AFTERPARSE) && defined(DEBUG_DISPBOXSECTION)
+ printf("\n\r Parsed display box top is %s]",matched);
+#endif
+
+ *top = (unsigned int)floor(atof(matched));
+
+ return bRet;
+}
+
+//match link left line and return link left position
+bool GetDispBoxLeft(const char *string, unsigned int *left)
+{
+ bool bRet = false;
+
+#if defined(DEBUG_BEFOREPARSE) && defined(DEBUG_DISPBOXSECTION)
+ printf("\n\r [Parsing display box left string is %s", string);
+#endif
+
+ bRet = RegexMatch(&reSlideDispLeft, string, (size_t)SUBSLEN, subs, 0);
+ //not match pattern
+ if(!bRet) {
+ fprintf(stderr, "\n\rNot link left line...!");
+ return bRet;
+ }
+
+// printf("\n\r %d, %d",subs[1].rm_eo, subs[1].rm_so);
+ int len = subs[1].rm_eo - subs[1].rm_so;
+ memcpy (matched, string + subs[1].rm_so, len);
+ matched[len] = '\0';
+
+#if defined(DEBUG_AFTERPARSE) && defined(DEBUG_DISPBOXSECTION)
+ printf("\n\r Parsed display box left is %s]",matched);
+#endif
+
+ *left = (unsigned int)floor(atof(matched));
+
+ return bRet;
+}
+
+//match link width line and return width value
+bool GetDispBoxWidth(const char *string, unsigned int *width)
+{
+ bool bRet = false;
+
+#if defined(DEBUG_BEFOREPARSE) && defined(DEBUG_DISPBOXSECTION)
+ printf("\n\r [Parsing display box width string is %s", string);
+#endif
+
+ bRet = RegexMatch(&reSlideDispWidth, string, (size_t)SUBSLEN, subs, 0);
+ //not match pattern
+ if(!bRet) {
+ fprintf(stderr, "\n\rNot link width line...!");
+ return bRet;
+ }
+
+// printf("\n\r %d, %d",subs[1].rm_eo, subs[1].rm_so);
+ int len = subs[1].rm_eo - subs[1].rm_so;
+ memcpy (matched, string + subs[1].rm_so, len);
+ matched[len] = '\0';
+
+#if defined(DEBUG_AFTERPARSE) && defined(DEBUG_DISPBOXSECTION)
+ printf("\n\r Parsed display box width is %s]",matched);
+#endif
+
+ *width = (unsigned int)floor(atof(matched));
+
+ return bRet;
+}
+
+//match link width line and return width value
+bool GetDispBoxHeight(const char *string, unsigned int *height)
+{
+ bool bRet = false;
+
+#if defined(DEBUG_BEFOREPARSE) && defined(DEBUG_DISPBOXSECTION)
+ printf("\n\r [Parsing display box height string is %s", string);
+#endif
+
+ bRet = RegexMatch(&reSlideDispHeight, string, (size_t)SUBSLEN, subs, 0);
+ //not match pattern
+ if(!bRet) {
+ fprintf(stderr, "\n\rNot link height line...!");
+ return bRet;
+ }
+
+// printf("\n\r %d, %d",subs[1].rm_eo, subs[1].rm_so);
+ int len = subs[1].rm_eo - subs[1].rm_so;
+ memcpy (matched, string + subs[1].rm_so, len);
+ matched[len] = '\0';
+
+#if defined(DEBUG_AFTERPARSE) && defined(DEBUG_DISPBOXSECTION)
+ printf("\n\r Parsed display box height is %s]",matched);
+#endif
+
+ *height = (unsigned int)floor(atof(matched));
+
+ return bRet;
+}
+
+//match hyperlink line and return link count
+bool GetLinkCount(const char *string, unsigned int *linkcnt)
+{
+ bool bRet = false;
+
+#if defined(DEBUG_BEFOREPARSE) && defined(DEBUG_LINKSECTION)
+ printf("\n\r [Parsing link count string is %s", string);
+#endif
+
+ bRet = RegexMatch(&reSlideLink, string, (size_t)SUBSLEN, subs, 0);
+ //not match pattern
+ if(!bRet) {
+ fprintf(stderr, "\n\rNot hyperlink line...!");
+ return bRet;
+ }
+
+// printf("\n\r %d, %d",subs[1].rm_eo, subs[1].rm_so);
+ int len = subs[1].rm_eo - subs[1].rm_so;
+ memcpy (matched, string + subs[1].rm_so, len);
+ matched[len] = '\0';
+
+#if defined(DEBUG_AFTERPARSE) && defined(DEBUG_LINKSECTION)
+ printf("\n\r Parsed link count is %s]",matched);
+#endif
+
+ *linkcnt = (unsigned int)floor(atof(matched));
+
+ return bRet;
+}
+
+//match link address line and return the address
+bool GetLinkAddr(const char *string, char *link)
+{
+ bool bRet = false;
+
+#if defined(DEBUG_BEFOREPARSE) && defined(DEBUG_LINKSECTION)
+ printf("\n\r [Parsing link address string is %s", string);
+#endif
+
+ bRet = RegexMatch(&reSlideLinkAddr, string, (size_t)SUBSLEN, subs, 0);
+ //not match pattern
+ if(!bRet) {
+ fprintf(stderr, "\n\rNot link address line...!");
+ return bRet;
+ }
+
+ //printf("\n\r %d, %d",subs[1].rm_eo, subs[1].rm_so);
+ int len = subs[1].rm_eo - subs[1].rm_so;
+
+ if(len > MAXLINKLEN - 1) {
+ fprintf(stderr, "\n\r link address is too long!");
+ return false;
+ }
+
+ memcpy (link, string + subs[1].rm_so, len);
+ link[len] = '\0';
+
+#if defined(DEBUG_AFTERPARSE) && defined(DEBUG_LINKSECTION)
+ printf("\n\r");
+ for(int j=0;j<len;++j) {
+ printf(" %d",link[j]);
+ }
+ printf("\n\r Parsed link address %s]",link);
+#endif
+
+ return bRet;
+}
+
+//match link top line and return link top position
+bool GetLinkTop(const char *string, unsigned int *top)
+{
+ bool bRet = false;
+
+#if defined(DEBUG_BEFOREPARSE) && defined(DEBUG_LINKSECTION)
+ printf("\n\r [Parsing link top string is %s", string);
+#endif
+
+ bRet = RegexMatch(&reSlideLinkTop, string, (size_t)SUBSLEN, subs, 0);
+ //not match pattern
+ if(!bRet) {
+ fprintf(stderr, "\n\rNot link top line...!");
+ return bRet;
+ }
+
+// printf("\n\r %d, %d",subs[1].rm_eo, subs[1].rm_so);
+ int len = subs[1].rm_eo - subs[1].rm_so;
+ memcpy (matched, string + subs[1].rm_so, len);
+ matched[len] = '\0';
+
+#if defined(DEBUG_AFTERPARSE) && defined(DEBUG_LINKSECTION)
+ printf("\n\r Parsed link top is %s]",matched);
+#endif
+
+ *top = (unsigned int)floor(atof(matched));
+
+ return bRet;
+}
+
+//match link left line and return link left position
+bool GetLinkLeft(const char *string, unsigned int *left)
+{
+ bool bRet = false;
+
+#if defined(DEBUG_BEFOREPARSE) && defined(DEBUG_LINKSECTION)
+ printf("\n\r [Parsing link left string is %s", string);
+#endif
+
+ bRet = RegexMatch(&reSlideLinkLeft, string, (size_t)SUBSLEN, subs, 0);
+ //not match pattern
+ if(!bRet) {
+ fprintf(stderr, "\n\rNot link left line...!");
+ return bRet;
+ }
+
+// printf("\n\r %d, %d",subs[1].rm_eo, subs[1].rm_so);
+ int len = subs[1].rm_eo - subs[1].rm_so;
+ memcpy (matched, string + subs[1].rm_so, len);
+ matched[len] = '\0';
+
+#if defined(DEBUG_AFTERPARSE) && defined(DEBUG_LINKSECTION)
+ printf("\n\r Parsed link left is %s]",matched);
+#endif
+
+ *left = (unsigned int)floor(atof(matched));
+
+ return bRet;
+}
+
+//match link width line and return width value
+bool GetLinkWidth(const char *string, unsigned int *width)
+{
+ bool bRet = false;
+
+#if defined(DEBUG_BEFOREPARSE) && defined(DEBUG_LINKSECTION)
+ printf("\n\r [Parsing link width string is %s", string);
+#endif
+
+ bRet = RegexMatch(&reSlideLinkWidth, string, (size_t)SUBSLEN, subs, 0);
+ //not match pattern
+ if(!bRet) {
+ fprintf(stderr, "\n\rNot link width line...!");
+ return bRet;
+ }
+
+// printf("\n\r %d, %d",subs[1].rm_eo, subs[1].rm_so);
+ int len = subs[1].rm_eo - subs[1].rm_so;
+ memcpy (matched, string + subs[1].rm_so, len);
+ matched[len] = '\0';
+
+#if defined(DEBUG_AFTERPARSE) && defined(DEBUG_LINKSECTION)
+ printf("\n\r Parsed link width is %s]",matched);
+#endif
+
+ *width = (unsigned int)floor(atof(matched));
+
+ return bRet;
+}
+
+//match link width line and return width value
+bool GetLinkHeight(const char *string, unsigned int *height)
+{
+ bool bRet = false;
+
+#if defined(DEBUG_BEFOREPARSE) && defined(DEBUG_LINKSECTION)
+ printf("\n\r [Parsing link height string is %s", string);
+#endif
+
+ bRet = RegexMatch(&reSlideLinkHeight, string, (size_t)SUBSLEN, subs, 0);
+ //not match pattern
+ if(!bRet) {
+ fprintf(stderr, "\n\rNot link height line...!");
+ return bRet;
+ }
+
+// printf("\n\r %d, %d",subs[1].rm_eo, subs[1].rm_so);
+ int len = subs[1].rm_eo - subs[1].rm_so;
+ memcpy (matched, string + subs[1].rm_so, len);
+ matched[len] = '\0';
+
+#if defined(DEBUG_AFTERPARSE) && defined(DEBUG_LINKSECTION)
+ printf("\n\r Parsed link height is %s]",matched);
+#endif
+
+ *height = (unsigned int)floor(atof(matched));
+
+ return bRet;
+}
+
+//get OnInit cmds of slide
+bool GetSlideOnInitCmds(const char *string, char * pOnInitCmds)
+{
+ bool bRet = false;
+
+#if defined(DEBUG_BEFOREPARSE) && defined(DEBUG_PROPSECTION)
+ printf("\n\r [Parsing OnInitCmds string is %s", string);
+#endif
+
+ bRet = RegexMatch(&reSlideOnInitCmds, string, (size_t)SUBSLEN, subs, 0);
+ //not match pattern
+ if(!bRet) {
+ fprintf(stderr, "\n\r Not OnInit commands line...!");
+ return bRet;
+ }
+
+ //printf("\n\r %d, %d",subs[1].rm_eo, subs[1].rm_so);
+ int len = subs[1].rm_eo - subs[1].rm_so;
+
+ if(len > MAXLINKLEN - 1) {
+ fprintf(stderr, "\n\r OnInitCmds line is too long!");
+ return false;
+ }
+
+ memcpy (pOnInitCmds, string + subs[1].rm_so, len);
+ pOnInitCmds[len] = '\0';
+
+#if defined(DEBUG_AFTERPARSE) && defined(DEBUG_PROPSECTION)
+ printf("\n\r Hex code of parsed: ");
+ for(int j=0;j<len;++j) {
+ printf(" %d",pOnInitCmds[j]);
+ }
+ printf("\n\r Parsed OnInitCmds: %s]",pOnInitCmds);
+#endif
+
+ return bRet;
+}
+
+//Get OnRefreshCmds of slide
+bool GetSlideOnRefreshCmds(const char *string, char *pOnRefreshCmds)
+{
+ bool bRet = false;
+
+#if defined(DEBUG_BEFOREPARSE) && defined(DEBUG_PROPSECTION)
+ printf("\n\r [Parsing OnRefresh string is %s", string);
+#endif
+
+ bRet = RegexMatch(&reSlideOnRefreshCmds, string, (size_t)SUBSLEN, subs, 0);
+ //not match pattern
+ if(!bRet) {
+ fprintf(stderr, "\n\rNot OnRefresh commands line...!");
+ return bRet;
+ }
+
+ //printf("\n\r %d, %d",subs[1].rm_eo, subs[1].rm_so);
+ int len = subs[1].rm_eo - subs[1].rm_so;
+
+ if(len > MAXLINKLEN - 1) {
+ fprintf(stderr, "\n\r OnRefreshCmds is too long!");
+ return false;
+ }
+
+ memcpy (pOnRefreshCmds, string + subs[1].rm_so, len);
+ pOnRefreshCmds[len] = '\0';
+
+#if defined(DEBUG_AFTERPARSE) && defined(DEBUG_PROPSECTION)
+ printf("\n\r Hex code of parsed: ");
+ for(int j=0;j<len;++j) {
+ printf(" %d",pOnRefreshCmds[j]);
+ }
+ printf("\n\r Parsed OnRefreshCmds: %s]",pOnRefreshCmds);
+#endif
+
+ return bRet;
+}
+
+//Get OnCloseCmds of slide
+bool GetSlideOnCloseCmds(const char *string, char *pOnCloseCmds)
+{
+ bool bRet = false;
+
+#if defined(DEBUG_BEFOREPARSE) && defined(DEBUG_PROPSECTION)
+ printf("\n\r [Parsing OnCloseCmds string is %s", string);
+#endif
+
+ bRet = RegexMatch(&reSlideOnCloseCmds, string, (size_t)SUBSLEN, subs, 0);
+ //not match pattern
+ if(!bRet) {
+ fprintf(stderr, "\n\rNot OnCloseCmds line...!");
+ return bRet;
+ }
+
+ //printf("\n\r %d, %d",subs[1].rm_eo, subs[1].rm_so);
+ int len = subs[1].rm_eo - subs[1].rm_so;
+
+ if(len > MAXLINKLEN - 1) {
+ fprintf(stderr, "\n\r OnCloseCmds is too long!");
+ return false;
+ }
+
+ memcpy (pOnCloseCmds, string + subs[1].rm_so, len);
+ pOnCloseCmds[len] = '\0';
+
+#if defined(DEBUG_AFTERPARSE) && defined(DEBUG_PROPSECTION)
+ printf("\n\r Hex code of parsed: ");
+ for(int j=0;j<len;++j) {
+ printf(" %d",pOnCloseCmds[j]);
+ }
+ printf("\n\r Parsed OncloseCmds %s]",pOnCloseCmds);
+#endif
+
+ return bRet;
+}
+
+//Parse slide section of script
+bool ParseSlideSection(const char *string, \
+ unsigned int *slideindex, \
+ unsigned int *slidewidth, \
+ unsigned int *slideheight)
+{
+ bool bRet = true;
+
+ //parse slide section
+ bRet &= GetSlideCount(string, slideindex);
+ bRet &= IsSlideSizeString(string+MAXSCRIPTSTRINGLINE);
+ bRet &= GetSlideWidth(string+MAXSCRIPTSTRINGLINE*2, slidewidth);
+ bRet &= GetSlideHeight(string+MAXSCRIPTSTRINGLINE*3, slideheight);
+
+ //one of parsing fails
+ if(!bRet) {
+ fprintf(stderr, "\n\rScript section format is not right!");
+ return false;
+ }
+
+ return bRet;
+}
+
+//Parse hyperlink section of script
+bool ParseLinkSection(const char *string, \
+ unsigned int *linkindex, \
+ char *linkstr, \
+ unsigned int *linktop, \
+ unsigned int *linkleft, \
+ unsigned int *linkwidth, \
+ unsigned int *linkheight)
+{
+ bool bRet = true;
+
+ //parse link section
+ bRet &= GetLinkCount(string, linkindex);
+ bRet &= GetLinkAddr(string+MAXSCRIPTSTRINGLINE, linkstr);
+ bRet &= GetLinkTop(string+MAXSCRIPTSTRINGLINE*2, linktop);
+ bRet &= GetLinkLeft(string+MAXSCRIPTSTRINGLINE*3, linkleft);
+ bRet &= GetLinkWidth(string+MAXSCRIPTSTRINGLINE*4, linkwidth);
+ bRet &= GetLinkHeight(string+MAXSCRIPTSTRINGLINE*5, linkheight);
+
+ //one of parsing fails
+ if(!bRet) {
+ fprintf(stderr, "\n\r Script link section format is not right!");
+ return false;
+ }
+
+ return bRet;
+}
+
+//Parse display box section of script
+bool ParseDispBoxSection(const char *string, \
+ unsigned int *disptop, \
+ unsigned int *displeft, \
+ unsigned int *dispwidth, \
+ unsigned int *dispheight)
+{
+ bool bRet = true;
+
+ //parse link section
+ bRet &= IsDispBoxSectionStart(string);
+ bRet &= GetDispBoxTop(string+MAXSCRIPTSTRINGLINE, disptop);
+ bRet &= GetDispBoxLeft(string+MAXSCRIPTSTRINGLINE*2, displeft);
+ bRet &= GetDispBoxWidth(string+MAXSCRIPTSTRINGLINE*3, dispwidth);
+ bRet &= GetDispBoxHeight(string+MAXSCRIPTSTRINGLINE*4, dispheight);
+
+ //one of parsing fails
+ if(!bRet) {
+ fprintf(stderr, "\n\r Script link section format is not right!");
+ return false;
+ }
+
+ return bRet;
+}
+
+//Parse slide properties section of script
+bool ParsePropertiesSection(const char *string, \
+ char *pOnInitCmds, \
+ char *pOnRefreshCmds, \
+ char *pOnCloseCmds)
+{
+ bool bRet = true;
+
+ //parse slide properties section
+ bRet &= IsPropertiesSectionStart(string);
+ bRet &= GetSlideOnInitCmds(string+MAXSCRIPTSTRINGLINE, pOnInitCmds);
+ bRet &= GetSlideOnRefreshCmds(string+MAXSCRIPTSTRINGLINE*2, pOnRefreshCmds);
+ bRet &= GetSlideOnCloseCmds(string+MAXSCRIPTSTRINGLINE*3, pOnCloseCmds);
+
+ //if any one of parsing fails
+ if(!bRet) {
+ fprintf(stderr, "\n\r Script slide properties section format is not right!");
+ return false;
+ }
+
+ return bRet;
+}
+
+//Is slide section starting?
+bool IsSlideSectionStart(const char *string)
+{
+ bool bRet;
+ bRet = RegexMatch(&reSlideCnt,string, (size_t)SUBSLEN, subs, 0);
+
+ return bRet;
+}
+
+//Is hyperlink section starting?
+bool IsLinkSectionStart(const char *string)
+{
+ bool bRet;
+ bRet = RegexMatch(&reSlideLink, string, (size_t)SUBSLEN, subs, 0);
+
+ return bRet;
+}
+
+//Is Display Box section starting?
+bool IsDispBoxSectionStart(const char *string)
+{
+ bool bRet;
+ bRet = RegexMatch(&reSlideDispString, string, (size_t)SUBSLEN, subs, 0);
+
+ return bRet;
+}
+
+//Is slide properties section starting?
+bool IsPropertiesSectionStart(const char *string)
+{
+ bool bRet;
+
+ bRet = RegexMatch(&reSlideProps, string, (size_t)SUBSLEN, subs, 0);
+
+ return bRet;
+}
+
+
+
+
diff --git a/utility/demo-fw/pc-tools/CreateDemoBin/src/main.cpp b/utility/demo-fw/pc-tools/CreateDemoBin/src/main.cpp
new file mode 100644
index 0000000..2f9f658
--- /dev/null
+++ b/utility/demo-fw/pc-tools/CreateDemoBin/src/main.cpp
@@ -0,0 +1,268 @@
+//============================================================================
+// Name : CreateAtmelDemoBin.cpp
+// Author : Tony.Liu
+// Version :
+// Copyright : Your copyright notice
+// Description : CreateAtmelDemoBin, c,c++ mix using for EasyBMP and regex compilation
+//============================================================================
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include "profile.h"
+#include "CreateDemoBin.h"
+#include "DemoBinHeader.h"
+
+
+//show usage help
+void ShowHelp(const char * exeName)
+{
+ printf("\n");
+ printf("Usage: %s [options] <PPTpathAndnameWithoutExtName>", exeName);
+ printf("\n For example, sam3demo.ppt, after running VBS macro in PowerPoint, ");
+ printf("\n copy this file under the same directory, then Run:\n");
+ printf("\n %s sam3demo", exeName);
+ printf("\n Options:");
+ printf("\n --help, show this information");
+ printf("\n -profile <EK-board-name>, build-in option sets, default board name is at91sam3u-ek");
+ printf("\n -profile help, display all build-in profile details");
+ printf("\n -width <resizedwith>, default is 320 pixel");
+ printf("\n -height <resizedheight>, default is 240 pixel");
+ printf("\n -bitdepth <bitdepth>, default is 16 bit");
+ printf("\n -rotate <clockwise_angel>, times of 90 degree within 360, default is 270 degree");
+ printf("\n -noreversebitmaporder, keep bitmap data original order, default reverse the order for at91sam3u-ek");
+ printf("\n");
+}
+
+//show profile details
+void ShowProfiles()
+{
+ printf("\n\r profiles details:");
+ printf("\n\r -profile at91sam3u-ek <-> -bitdepth 16 -width 320 -height 240 -rotate 0");
+
+}
+
+//seek matched profile
+static int ProfileOption(char *pProfile, BMPConvOpt *const pOption )
+{
+ unsigned int j;
+ unsigned int i = sizeof(profile)/sizeof(Profile);
+
+ for(j = 0; j < i; j++) {
+ if(strcmp(pProfile, profile[j].pProfileName) == 0) {
+ pOption->bitdepth = profile[j].options.bitdepth;
+ pOption->width = profile[j].options.width;
+ pOption->height = profile[j].options.height;
+ pOption->rotateangle = profile[j].options.rotateangle;
+ pOption->reversebitmaporder = profile[j].options.reversebitmaporder;
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+//get conversion setting option from execution arguments
+static void GetOptsFromargv(int argc, char **argv, BMPConvOpt *pOption)
+{
+ int i;
+
+ //set default option value, it is used for at91SAM3u-ek demo on SDCARD or NANDFLASH
+ pOption->bitdepth = 16;
+ pOption->width = 320;
+ pOption->height = 240;
+ pOption->rotateangle = 270;
+ pOption->reversebitmaporder = 1;
+ #if defined(MOVIE_MERGE_on)
+ pOption->mvSlideNumber = 5;
+ #endif
+ #if defined(SLIDESHOW_MERGE_on)
+ pOption->ssPageNumber = MAXSLIDESPERBIN;
+ pOption->ssBitdepth = 16;
+ pOption->ssWidth = 320;
+ pOption->ssHeight = 240;
+ pOption->ssRotateangle = 270;
+ pOption->ssReverseBmpOrder = 1;
+ #endif
+
+ //parse argument
+ for(i=1;i<argc-1;++i) {
+ if(strcmp(argv[i], "-profile")==0) {
+ if(!ProfileOption(argv[++i], pOption)) {
+ break;
+ }
+
+ continue;
+ }
+
+ if(strcmp(argv[i], "-width")== 0) {
+ pOption->width = (unsigned int)floor(atof(argv[++i]));
+ continue;
+ }
+
+ if(strcmp(argv[i], "-height")==0) {
+ pOption->height = (unsigned int)floor(atof(argv[++i]));
+ continue;
+ }
+
+ if(strcmp(argv[i], "-bitdepth")==0) {
+ pOption->bitdepth = (unsigned int)floor(atof(argv[++i]));
+ continue;
+ }
+
+ if(strcmp(argv[i], "-rotate")==0) {
+ pOption->rotateangle = (unsigned int)floor(atof(argv[++i]));
+ continue;
+ }
+
+ if(strcmp(argv[i], "-noreversebitmaporder")==0) {
+ pOption->reversebitmaporder = 0;
+ continue;
+ }
+
+ #if defined(MOVIE_MERGE_on)
+ if(strcmp(argv[i], "-movieSlideNumber")==0) {
+ pOption->mvSlideNumber = (unsigned int)floor(atof(argv[++i]));
+ continue;
+ }
+ #endif
+
+ #if defined(SLIDESHOW_MERGE_on)
+ if(strcmp(argv[i], "-ssPageNumber")== 0) {
+ pOption->ssPageNumber = (unsigned int)floor(atof(argv[++i]));
+ continue;
+ }
+
+ if(strcmp(argv[i], "-ssWidth")== 0) {
+ pOption->ssWidth = (unsigned int)floor(atof(argv[++i]));
+ continue;
+ }
+
+ if(strcmp(argv[i], "-ssHeight")==0) {
+ pOption->ssHeight = (unsigned int)floor(atof(argv[++i]));
+ continue;
+ }
+
+ if(strcmp(argv[i], "-ssBitdepth")==0) {
+ pOption->ssBitdepth = (unsigned int)floor(atof(argv[++i]));
+ continue;
+ }
+
+ if(strcmp(argv[i], "-ssRotate")==0) {
+ pOption->ssRotateangle = (unsigned int)floor(atof(argv[++i]));
+ continue;
+ }
+
+ if(strcmp(argv[i], "-ssNoreversebitmaporder")==0) {
+ pOption->ssReverseBmpOrder = 0;
+ continue;
+ }
+ #endif
+ }
+
+ printf("\n *****Prepare: Converstion will use following options:");
+ #if defined(SLIDESHOW_MERGE_on)
+ printf("\n Bitdepth: %u; Width: %u; Height: %u; rotate angel: %u; reversebitorder: %s; SS Slide number: %u; SSBitdepth: %u; SSWidth: %u; SSHeight: %u; SS rotate angel: %u;",\
+ pOption->bitdepth,\
+ pOption->width,\
+ pOption->height,\
+ pOption->rotateangle,\
+ pOption->reversebitmaporder ? "yes":"no",\
+ pOption->ssPageNumber,\
+ pOption->ssBitdepth,\
+ pOption->ssWidth,\
+ pOption->ssHeight,\
+ pOption->ssRotateangle);
+ #else
+ printf("\n Bitdepth: %u; Width: %u; Height: %u; rotate angel: %u; reversebitorder: %s;",\
+ pOption->bitdepth,\
+ pOption->width,\
+ pOption->height,\
+ pOption->rotateangle,\
+ pOption->reversebitmaporder ? "yes":"no");
+ #endif
+
+}
+
+////////////////////////////////////////////////////////////////////
+//Main portal
+///////////////////////////////////////////////////////////////////
+
+int main(int argc, char**argv)
+{
+ bool bRet=true;
+ BMPConvOpt option;
+
+ //Show usage help
+ if(argc == 1 || \
+ strcmp(argv[1], "--help")==0 || \
+ strcmp(argv[1], "/?")==0 \
+ )
+ {
+ ShowHelp(argv[0]);
+ return 1;
+ }
+
+ if(argc == 3 && strcmp(argv[1], "-profile") == 0 && strcmp(argv[2], "help") == 0) {
+ ShowProfiles();
+ return 0;
+ }
+
+ //parse execution options ready for following conversion
+ GetOptsFromargv(argc, argv, &option);
+
+ //Init filename variables based on command argument
+ printf("\n\n *****Step1: Create Neccesary file names!");
+ Step1_CreateFileNameVars(argv[argc-1]);
+
+#if 0
+ //check if created file names are correct
+ printf("\n\r %s ", pptScriptLink);
+ printf("\n\r %s", pAtmlDemoBin);
+ printf("\n\r %s", pBinContent);
+ for(int i = 0; i< MAXSLIDESPERBIN; ++i) {
+ printf("\n\r %s", pptSlidesBmp[i]);
+ }
+ for(int j=0; j < MAXSLIDESPERBIN; ++j) {
+ printf("\n\r %s", pptSlides320x240Bmp[j]);
+ }
+ exit(0);
+#endif
+
+ //Parsed generated Script file
+ #if !defined(MOVIE_MERGE_on)
+ printf("\n\n *****Step2: Parse PPT slide information txt file");
+ bRet &= Step2_ProcessPPTInfoFile(&option);
+ printf("\n ****Step2 Result: %s ****", bRet?"Success":"Failure");
+ #endif
+
+ //Resize and rotate saved slide bmp files
+ printf("\n\n *****Step3: Resize,rotate and reset bit depth of slide bmp file");
+ printf("\nbitdepth %u, width %u, height %u, rotateangle %u",option.bitdepth, option.width, option.height, option.rotateangle);
+ bRet &= Step3_ResizeAndRotateSlideBMP(&option);
+ printf("\n ****Step3 Result: %s ****", bRet?"Success":"Failure");
+
+ //Create Atmel Demo bin file
+ printf("\n\n *****Step4: Create demo bin from above step generated information");
+ bRet &= Step4_GenerateDemoBin(&option);
+ printf("\n ****Step4 Result: %s ****", bRet?"Success":"Failure");
+
+#if !defined(MOVIE_MERGE_on)
+ //Show each bmp bitmap file header in demo bin file
+ printf("\n\n *****Done: Check bitmap file information in generated demo bin");
+ ShowEachBmpHeader();
+#endif
+
+ if(bRet) {
+ printf("\n\n -----------Result: Creating demo bin file succeeds!-----------");
+ return 0;
+ }
+ else {
+ printf("\n\n ------------Result: Fail to Create right demo bin!-----------");
+ return 1;
+ }
+
+}
+
+
diff --git a/utility/encryption/aes_hardware.c b/utility/encryption/aes_hardware.c
new file mode 100644
index 0000000..dfbc97f
--- /dev/null
+++ b/utility/encryption/aes_hardware.c
@@ -0,0 +1,391 @@
+/* ----------------------------------------------------------------------------
+ * 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.
+ * ----------------------------------------------------------------------------
+ */
+
+//------------------------------------------------------------------------------
+// Function: Firmware encryption using hardware acceleration
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+// Includes
+//------------------------------------------------------------------------------
+
+#include "aes_hardware.h"
+
+#if defined(USE_ENCRYPTION) && defined(ENCRYPTION_AES_HARD)
+#include "config.h"
+#include <stdio.h>
+#include <string.h>
+#include <board.h>
+#include <utility/trace.h>
+#include <utility/assert.h>
+#include <pmc/pmc.h>
+#include <aes/aes_p.h>
+
+//------------------------------------------------------------------------------
+// Inline functions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// Converts an ASCII value to an hexadecimal one
+/// \param ASCII string
+/// \param Buffer to store integer value
+/// \param Length of string
+//------------------------------------------------------------------------------
+static inline void ASCII2Hex(const unsigned char * ascii,
+ unsigned char * binary,
+ unsigned int length)
+{
+ unsigned int i;
+
+ for (i=0; i < length; i++) {
+ if (ascii[i*2] >= 'A') {
+ binary[i] = ascii[i*2] - 'A' + 10;
+ }
+ else {
+ binary[i] = ascii[i*2] - '0';
+ }
+ binary[i] <<= 4;
+ if (ascii[i*2+1] >= 'A') {
+ binary[i] += ascii[i*2+1] - 'A' + 10;
+ }
+ else {
+ binary[i] += ascii[i*2+1] - '0';
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+// Functions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// Initializes the AES peripheral
+//------------------------------------------------------------------------------
+#ifdef ONLY_ONE_ENCRYPTION
+void aes_hard_init(void)
+{
+ unsigned char key[ENCRYPTION_KEY_LENGTH];
+
+#if defined(ENCRYPTION_CTR) || defined(ENCRYPTION_CBC)
+ unsigned char IV[ENCRYPTION_BLOCK_LENGTH];
+#endif
+
+ TRACE_DEBUG("AES/HARD: Initializing ...\n\r");
+
+ // Activate peripheral clock
+#ifdef AT91C_ID_AES
+ PMC_EnablePeripheral( AT91C_ID_AES );
+#elif AT91C_ID_AESTDES
+ PMC_EnablePeripheral( AT91C_ID_AESTDES );
+#elif AT91C_ID_TDES
+ PMC_EnablePeripheral( AT91C_ID_TDES );
+#else
+#error AES undefined
+#endif
+
+ // Load mode
+ //AES_Configure(AT91C_AES_CIPHER, AT91C_AES_SMOD_PDC, AT91C_AES_OPMOD_ECB);
+
+#if (ENCRYPTION_KEY_LENGTH == 32)
+#if defined(ENCRYPTION_ECB)
+ AT91C_BASE_AES->AES_MR = AT91C_AES_SMOD_PDC // PDC Mode
+ | AT91C_AES_KEYSIZE_256_BIT
+ | AT91C_AES_OPMOD_ECB;
+
+#elif defined(ENCRYPTION_CBC)
+ AT91C_BASE_AES->AES_MR = AT91C_AES_SMOD_PDC // PDC Mode
+ | AT91C_AES_KEYSIZE_256_BIT
+ | AT91C_AES_OPMOD_CBC;
+
+#elif defined(ENCRYPTION_CTR)
+ AT91C_BASE_AES->AES_MR = AT91C_AES_SMOD_PDC // PDC Mode
+ | AT91C_AES_KEYSIZE_256_BIT
+ | AT91C_AES_OPMOD_CTR;
+#endif
+#elif (ENCRYPTION_KEY_LENGTH == 24)
+#if defined(ENCRYPTION_ECB)
+ AT91C_BASE_AES->AES_MR = AT91C_AES_SMOD_PDC // PDC Mode
+ | AT91C_AES_KEYSIZE_192_BIT
+ | AT91C_AES_OPMOD_ECB;
+
+#elif defined(ENCRYPTION_CBC)
+ AT91C_BASE_AES->AES_MR = AT91C_AES_SMOD_PDC // PDC Mode
+ | AT91C_AES_KEYSIZE_192_BIT
+ | AT91C_AES_OPMOD_CBC;
+
+#elif defined(ENCRYPTION_CTR)
+ AT91C_BASE_AES->AES_MR = AT91C_AES_SMOD_PDC // PDC Mode
+ | AT91C_AES_KEYSIZE_192_BIT
+ | AT91C_AES_OPMOD_CTR;
+#endif
+#else
+#if defined(ENCRYPTION_ECB)
+ AT91C_BASE_AES->AES_MR = AT91C_AES_SMOD_PDC // PDC Mode
+ | AT91C_AES_KEYSIZE_128_BIT
+ | AT91C_AES_OPMOD_ECB;
+
+#elif defined(ENCRYPTION_CBC)
+ AT91C_BASE_AES->AES_MR = AT91C_AES_SMOD_PDC // PDC Mode
+ | AT91C_AES_KEYSIZE_128_BIT
+ | AT91C_AES_OPMOD_CBC;
+
+#elif defined(ENCRYPTION_CTR)
+ AT91C_BASE_AES->AES_MR = AT91C_AES_SMOD_PDC // PDC Mode
+ | AT91C_AES_KEYSIZE_128_BIT
+ | AT91C_AES_OPMOD_CTR;
+#endif
+#endif
+
+ // Convert and load key
+ ASCII2Hex((unsigned char*)ENCRYPTION_KEY, key, ENCRYPTION_KEY_LENGTH);
+
+ AES_SetKey((unsigned int*)key, ENCRYPTION_KEY_LENGTH);
+
+ // Convert and load IV
+#if defined(ENCRYPTION_CTR) || defined(ENCRYPTION_CBC)
+ ASCII2Hex((unsigned char*)ENCRYPTION_IV, IV, ENCRYPTION_BLOCK_LENGTH);
+
+ AES_SetVector((unsigned int*)IV);
+#endif
+
+ TRACE_DEBUG("AES/HARD: Initialization done.\n\r");
+}
+#endif
+
+//------------------------------------------------------------------------------
+/// Initializes the AES peripheral for CBC mode
+//------------------------------------------------------------------------------
+#ifndef ONLY_ONE_ENCRYPTION
+#if defined(ENCRYPTION_CBC)
+void aes_hard_init_CBC(void)
+{
+ unsigned char key[ENCRYPTION_KEY_LENGTH];
+ unsigned char IV[ENCRYPTION_BLOCK_LENGTH];
+
+ TRACE_DEBUG("aes_hard_init_CBC\n\r");
+
+ // Activate peripheral clock
+#ifdef AT91C_ID_AES
+ PMC_EnablePeripheral( AT91C_ID_AES );
+#elif AT91C_ID_AESTDES
+ PMC_EnablePeripheral( AT91C_ID_AESTDES );
+#elif AT91C_ID_TDES
+ PMC_EnablePeripheral( AT91C_ID_TDES );
+#else
+#error AES undefined
+#endif
+
+ // Load mode
+ AT91C_BASE_AES->AES_MR = AT91C_AES_SMOD_PDC // PDC Mode
+#if (ENCRYPTION_KEY_LENGTH == 32)
+ | AT91C_AES_KEYSIZE_256_BIT
+#endif
+#if (ENCRYPTION_KEY_LENGTH == 24)
+ | AT91C_AES_KEYSIZE_192_BIT
+#endif
+ | AT91C_AES_OPMOD_CBC; // Cipher Block Chaining mode
+
+ // Convert and load key
+ ASCII2Hex((unsigned char*)ENCRYPTION_KEY, key, ENCRYPTION_KEY_LENGTH);
+
+ AES_SetKey((unsigned int*)key, ENCRYPTION_KEY_LENGTH);
+
+ // Convert and load IV
+ ASCII2Hex((unsigned char*)ENCRYPTION_IV, IV, ENCRYPTION_BLOCK_LENGTH);
+
+ AES_SetVector((unsigned int*)IV);
+}
+#endif
+
+//------------------------------------------------------------------------------
+/// Initializes the AES peripheral for CTR mode
+//------------------------------------------------------------------------------
+#if defined(ENCRYPTION_CTR)
+void aes_hard_init_CTR(void)
+{
+ unsigned char key[ENCRYPTION_KEY_LENGTH];
+ unsigned char IV[ENCRYPTION_BLOCK_LENGTH];
+
+ TRACE_DEBUG("aes_hard_init_CTR\n\r");
+
+ // Activate peripheral clock
+#ifdef AT91C_ID_AES
+ PMC_EnablePeripheral( AT91C_ID_AES );
+#elif AT91C_ID_AESTDES
+ PMC_EnablePeripheral( AT91C_ID_AESTDES );
+#elif AT91C_ID_TDES
+ PMC_EnablePeripheral( AT91C_ID_TDES );
+#else
+#error AES undefined
+#endif
+
+ // Load mode
+ AT91C_BASE_AES->AES_MR = AT91C_AES_SMOD_PDC // PDC Mode
+#if (ENCRYPTION_KEY_LENGTH == 32)
+ | AT91C_AES_KEYSIZE_256_BIT
+#endif
+#if (ENCRYPTION_KEY_LENGTH == 24)
+ | AT91C_AES_KEYSIZE_192_BIT
+#endif
+ | AT91C_AES_OPMOD_CTR; // Counter mode
+
+ // Convert and load key
+ ASCII2Hex((unsigned char*)ENCRYPTION_KEY, key, ENCRYPTION_KEY_LENGTH);
+
+ AES_SetKey((unsigned int*)key, ENCRYPTION_KEY_LENGTH);
+
+ // Convert and load IV
+ ASCII2Hex((unsigned char*)ENCRYPTION_IV, IV, ENCRYPTION_BLOCK_LENGTH);
+
+ AES_SetVector((unsigned int*)IV);
+}
+#endif
+
+//------------------------------------------------------------------------------
+/// Initializes the AES peripheral for ECB mode
+//------------------------------------------------------------------------------
+#if defined(ENCRYPTION_ECB)
+void aes_hard_init_ECB(void)
+{
+ unsigned char key[ENCRYPTION_KEY_LENGTH];
+
+ TRACE_DEBUG("aes_hard_init_ECB\n\r");
+
+ // Activate peripheral clock
+#ifdef AT91C_ID_AES
+ PMC_EnablePeripheral( AT91C_ID_AES );
+#elif AT91C_ID_AESTDES
+ PMC_EnablePeripheral( AT91C_ID_AESTDES );
+#elif AT91C_ID_TDES
+ PMC_EnablePeripheral( AT91C_ID_TDES );
+#else
+#error AES undefined
+#endif
+
+ // Load mode
+ AT91C_BASE_AES->AES_MR = AT91C_AES_SMOD_PDC // PDC Mode
+#if (ENCRYPTION_KEY_LENGTH == 32)
+ | AT91C_AES_KEYSIZE_256_BIT
+#endif
+#if (ENCRYPTION_KEY_LENGTH == 24)
+ | AT91C_AES_KEYSIZE_192_BIT
+#endif
+ | AT91C_AES_OPMOD_ECB; // ECB Electronic CodeBook mode
+
+ // Convert and load key
+ ASCII2Hex((unsigned char*)ENCRYPTION_KEY, key, ENCRYPTION_KEY_LENGTH);
+
+ AES_SetKey((unsigned int*)key, ENCRYPTION_KEY_LENGTH);
+}
+#endif
+#endif // ONLY_ONE_ENCRYPTION
+
+//------------------------------------------------------------------------------
+/// Cleans up the AES peripheral
+//------------------------------------------------------------------------------
+void aes_hard_cleanup(void)
+{
+ TRACE_DEBUG("AES/HARD: Cleaning up ...\n\r");
+
+ AT91C_BASE_AES->AES_MR = 0;
+
+#ifdef AT91C_ID_AES
+ PMC_DisablePeripheral( AT91C_ID_AES );
+#elif AT91C_ID_AESTDES
+ PMC_DisablePeripheral( AT91C_ID_AESTDES );
+#elif AT91C_ID_TDES
+ PMC_DisablePeripheral( AT91C_ID_TDES );
+#else
+#error AES undefined
+#endif
+
+#ifdef AT91C_BASE_PDC_AES
+ // Close PDC
+ AT91C_BASE_PDC_AES->PDC_PTCR = AT91C_PDC_RXTDIS;
+ AT91C_BASE_PDC_AES->PDC_PTCR = AT91C_PDC_TXTDIS;
+
+ // Reset all Counter register Next buffer first
+ AT91C_BASE_PDC_AES->PDC_TNPR = 0;
+ AT91C_BASE_PDC_AES->PDC_TNCR = 0;
+ AT91C_BASE_PDC_AES->PDC_RPR = 0;
+ AT91C_BASE_PDC_AES->PDC_RCR = 0;
+ AT91C_BASE_PDC_AES->PDC_TPR = 0;
+ AT91C_BASE_PDC_AES->PDC_TCR = 0;
+ AT91C_BASE_PDC_AES->PDC_RPR = 0;
+ AT91C_BASE_PDC_AES->PDC_RCR = 0;
+#else
+ //Disable DMA Channels
+ AT91C_BASE_HDMA->HDMA_CHDR = (1<<0)| (1<<1);
+ #endif
+
+ TRACE_DEBUG("AES/HARD: Cleanup done.\n\r");
+}
+
+//------------------------------------------------------------------------------
+/// Decrypts a variable-length cipher text
+/// \param pCipherText text to decrypt
+/// \param pPlainText to store plain text
+/// \param length of cipher text (in bytes)
+/// \return: 1 if ok, 0 if error
+//------------------------------------------------------------------------------
+int aes_hard_decrypt(const unsigned char *pCipherText,
+ unsigned char *pPlainText,
+ unsigned int length)
+{
+ TRACE_DEBUG("aes_hard_decrypt\n\r");
+
+ // Check parameters
+ if ((pCipherText == NULL) || (pPlainText == NULL)) {
+ return 0;
+ }
+
+#ifdef AT91C_BASE_PDC_AES
+ // Set source and destination buffers in PDC
+ AT91C_BASE_PDC_AES->PDC_TPR = (unsigned int) pCipherText;
+ AT91C_BASE_PDC_AES->PDC_RPR = (unsigned int) pPlainText;
+
+ AT91C_BASE_PDC_AES->PDC_TCR = length >> 2;
+ AT91C_BASE_PDC_AES->PDC_RCR = length >> 2;
+
+ // Start decryption and wait
+ AT91C_BASE_PDC_AES->PDC_PTCR = AT91C_PDC_RXTEN | AT91C_PDC_TXTEN;
+ while (((AES_GetStatus()) & AT91C_AES_ENDRX) == 0);
+#else
+
+ // Enable DMA chanels
+ AT91C_BASE_HDMA->HDMA_CHER = (1<<0) | (1<<1);
+ // Wait end of transfer
+ while( (AT91C_BASE_HDMA->HDMA_CHSR & ((1<<0)|(1<<1))) != 0 );
+#endif
+
+ return 1;
+}
+
+#endif // defined(USE_ENCRYPTION) && defined(ENCRYPTION_AES_HARD)
+
diff --git a/utility/encryption/aes_hardware.h b/utility/encryption/aes_hardware.h
new file mode 100644
index 0000000..e7662a4
--- /dev/null
+++ b/utility/encryption/aes_hardware.h
@@ -0,0 +1,101 @@
+/* ----------------------------------------------------------------------------
+ * 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
+///
+/// Firmware encryption using AES hardware acceleration
+/// This code is based on the AES reference implementation published by Paulo
+/// Barreto and Vincent Rijmen.
+///
+/// !Usage
+///
+/// -# aes_hard_init: Initialize AES hardware
+/// -# aes_hard_init_CBC: for the CBC mode
+/// -# aes_hard_init_CTR: for the CTR mode
+/// -# aes_hard_init_ECB: for the ECB mode
+/// -# aes_hard_cleanup: Cleans up AES
+/// -# aes_hard_decrypt: Decrypts a variable-length cipher text
+//------------------------------------------------------------------------------
+
+#ifndef BOOTLOADER_AES_HARDWARE_H
+#define BOOTLOADER_AES_HARDWARE_H
+
+//------------------------------------------------------------------------------
+// Includes
+//------------------------------------------------------------------------------
+#include "config.h"
+
+#if defined(USE_ENCRYPTION) && defined(ENCRYPTION_AES_HARD)
+
+//------------------------------------------------------------------------------
+// Check configuration
+//------------------------------------------------------------------------------
+#if (ENCRYPTION_KEY_LENGTH != 16) && (ENCRYPTION_KEY_LENGTH != 24) \
+ && (ENCRYPTION_KEY_LENGTH != 32)
+ #error Hardware AES acceleration only supports ENCRYPTION_KEY_LENGTH bits keys.
+#endif
+
+#if (ENCRYPTION_BLOCK_LENGTH != 16)
+ #error Hardware AES acceleration only supports ENCRYPTION_KEY_LENGTH bits blocks.
+#endif
+
+#if !defined(ENCRYPTION_ECB) && \
+ !defined(ENCRYPTION_CBC) && \
+ !defined(ENCRYPTION_CTR)
+ #error Only ECB, CBC & CTR modes are supported.
+#endif
+
+//------------------------------------------------------------------------------
+// Definitions
+//------------------------------------------------------------------------------
+#ifdef ONLY_ONE_ENCRYPTION
+#define ENCRYPTION_INIT aes_hard_init
+#define ENCRYPTION_CLEANUP aes_hard_cleanup
+#define ENCRYPTION_DECRYPT aes_hard_decrypt
+#endif
+
+//------------------------------------------------------------------------------
+// Exported functions
+//------------------------------------------------------------------------------
+extern void aes_hard_init(void);
+#ifndef ONLY_ONE_ENCRYPTION
+extern void aes_hard_init_CBC(void);
+extern void aes_hard_init_CTR(void);
+extern void aes_hard_init_ECB(void);
+#endif
+extern void aes_hard_cleanup(void);
+extern int aes_hard_decrypt(const unsigned char *, unsigned char *, unsigned int);
+
+#endif // defined(USE_ENCRYPTION) && defined(ENCRYPTION_AES_HARD)
+#endif // BOOTLOADER_AES_HARDWARE_H
+
+
diff --git a/utility/encryption/aes_reference.c b/utility/encryption/aes_reference.c
new file mode 100644
index 0000000..b3a5c05
--- /dev/null
+++ b/utility/encryption/aes_reference.c
@@ -0,0 +1,801 @@
+/* ----------------------------------------------------------------------------
+ * 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.
+ * ----------------------------------------------------------------------------
+ */
+
+//------------------------------------------------------------------------------
+// Firmware encryption using AES reference implementation
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+// Includes
+//------------------------------------------------------------------------------
+#include "aes_reference.h"
+
+#if defined(USE_ENCRYPTION) && defined(ENCRYPTION_AES_REF)
+#include <stdio.h>
+#include <string.h>
+#include <board.h>
+#include <utility/trace.h>
+#include <utility/assert.h>
+#include <pmc/pmc.h>
+
+//------------------------------------------------------------------------------
+// Global variables
+//------------------------------------------------------------------------------
+#define word8 static unsigned char
+#define word32 static unsigned int
+
+#include "boxes-ref.dat"
+
+static unsigned char shifts[3][2][4] = {
+ {{0,1,2,3}, {0,3,2,1}},
+ {{0,1,2,3}, {0,5,4,3}},
+ {{0,7,5,5}, {0,1,3,4}}
+};
+
+static unsigned char key[KC][4];
+static unsigned char expandedKey[ROUNDS+1][BC][4];
+static unsigned int T0[256], T1[256], T2[256], T3[256], TF[256];
+
+#if defined(ENCRYPTION_CBC) || defined(ENCRYPTION_CTR)
+static unsigned char IV[BC][4];
+#endif
+
+//------------------------------------------------------------------------------
+// Inline functions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// Multiply two elements of GF(2^m) needed for MixColumn and InvMixColumn
+/// \param a first element
+/// \param b second element
+/// \return result of operation
+//------------------------------------------------------------------------------
+static unsigned char mul(unsigned char a, unsigned char b)
+{
+ if (a && b) {
+ return Alogtable[(Logtable[a] + Logtable[b])%255];
+ }
+ else {
+ return 0;
+ }
+}
+
+//------------------------------------------------------------------------------
+/// Returns the minimum between two numbers
+/// \param First number
+/// \param Second number
+/// \return Minimum between the two operands
+//------------------------------------------------------------------------------
+#if defined(ENCRYPTION_CTR)
+static unsigned int min(unsigned int number1, unsigned int number2)
+{
+ if (number1 > number2) {
+ return number2;
+ }
+ else {
+ return number1;
+ }
+}
+#endif
+
+//------------------------------------------------------------------------------
+/// XOR text and round key together
+/// \param Plain text
+/// \param Round key
+//------------------------------------------------------------------------------
+static inline void addRoundKey(unsigned char a[BC][4], const unsigned char rk[BC][4])
+{
+ unsigned int i;
+
+ for (i=0; i < BC; i++) {
+ ((int *) a)[i] ^= ((int *) rk)[i];
+ }
+}
+
+//------------------------------------------------------------------------------
+/// Performs the AES key schedule
+/// \param Key to use
+/// \param Buffer to store expanded key schedule
+//------------------------------------------------------------------------------
+static inline void keySchedule(unsigned char k[KC][4], unsigned char W[ROUNDS+1][BC][4])
+{
+ int t;
+ int rconpointer = 0;
+ unsigned int j;
+ unsigned char tk[KC][4];
+
+ for(j=0; j < KC; j++) {
+ ((int *) tk)[j] = ((int *) k)[j];
+ }
+
+ t = 0;
+ /* copy values into round key array */
+ for(j=0; (j < KC) && (t < (ROUNDS+1)*BC); j++, t++) {
+ ((int *) W[t / BC])[t%BC] = ((int *) tk)[j];
+ }
+
+ while (t < (ROUNDS+1)*BC) {
+
+ tk[0][0] ^= S[tk[KC-1][1]] ^ rcon[rconpointer++];
+ tk[0][1] ^= S[tk[KC-1][2]];
+ tk[0][2] ^= S[tk[KC-1][3]];
+ tk[0][3] ^= S[tk[KC-1][0]];
+
+ if (KC != 8) {
+ for(j=1; j < KC; j++) {
+ ((int *) tk)[j] ^= ((int *) tk)[j-1];
+ }
+ }
+ else {
+ for(j=1; j < KC/2; j++) {
+ ((int *) tk)[j] ^= ((int *) tk)[j-1];
+ }
+ tk[KC/2][0] ^= S[tk[KC/2 - 1][0]];
+ tk[KC/2][1] ^= S[tk[KC/2 - 1][1]];
+ tk[KC/2][2] ^= S[tk[KC/2 - 1][2]];
+ tk[KC/2][3] ^= S[tk[KC/2 - 1][3]];
+
+ for(j=KC/2+1; j < KC; j++) {
+ ((int *) tk)[j] ^= ((int *) tk)[j-1];
+ }
+ }
+
+ // copy values into round key array
+ for(j=0; (j < KC) && (t < (ROUNDS+1)*BC); j++, t++) {
+ ((int *) W[t/BC])[t%BC] = ((int *) tk)[j];
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+/// Performs the AES inverse key schedule
+/// \param Key to use
+/// \param Buffer to store expanded key schedule
+//------------------------------------------------------------------------------
+#if defined(ENCRYPTION_ECB) || defined(ENCRYPTION_CBC)
+static inline void invKeySchedule(unsigned char k[KC][4],
+ unsigned char W[ROUNDS+1][BC][4])
+{
+ unsigned int r;
+ unsigned int j;
+ unsigned char tmp[4];
+
+ // Expand key normally
+ keySchedule(k, W);
+
+ // Apply invMixColumns to all rounds except first and last one
+ for (r=1; r < ROUNDS; r++) {
+ for (j=0; j < BC; j++) {
+ tmp[0] = mul(0x0E, W[r][j][0]) ^ mul(0x0B, W[r][j][1]) ^
+ mul(0x0D, W[r][j][2]) ^ mul(0x09, W[r][j][3]);
+ tmp[1] = mul(0x0E, W[r][j][1]) ^ mul(0x0B, W[r][j][2]) ^
+ mul(0x0D, W[r][j][3]) ^ mul(0x09, W[r][j][0]);
+ tmp[2] = mul(0x0E, W[r][j][2]) ^ mul(0x0B, W[r][j][3]) ^
+ mul(0x0D, W[r][j][0]) ^ mul(0x09, W[r][j][1]);
+ tmp[3] = mul(0x0E, W[r][j][3]) ^ mul(0x0B, W[r][j][0]) ^
+ mul(0x0D, W[r][j][1]) ^ mul(0x09, W[r][j][2]);
+ W[r][j][0] = tmp[0];
+ W[r][j][1] = tmp[1];
+ W[r][j][2] = tmp[2];
+ W[r][j][3] = tmp[3];
+ }
+ }
+}
+#endif
+
+//------------------------------------------------------------------------------
+/// Perform the RotBytes operation needed by the AES cipher
+/// \param input to rotate
+/// \return Rotated word
+//------------------------------------------------------------------------------
+static inline unsigned int rotBytes(unsigned int input)
+{
+ return ((input << 8) | (input >> 24));
+}
+
+//------------------------------------------------------------------------------
+/// Generates the lookup tables needed for encryption
+/// \param Pointer to t0
+/// \param Pointer to t1
+/// \param Pointer to t2
+/// \param Pointer to t3
+/// \param Pointer to tf
+/// \param Box
+//------------------------------------------------------------------------------
+#if defined(ENCRYPTION_CTR)
+static inline void generateEncryptionLUTs(unsigned int * t0,
+ unsigned int * t1,
+ unsigned int * t2,
+ unsigned int * t3,
+ unsigned int * tf,
+ unsigned char box[256])
+{
+ unsigned int a;
+
+ for (a=0; a <= 255; a++) {
+ // Calc t0
+ t0[a] = (mul(2, box[a])) |
+ (box[a] << 8) |
+ (box[a] << 16) |
+ (mul(3, box[a]) << 24);
+
+ // Calc t1, t2, t3
+ t1[a] = rotBytes(t0[a]);
+ t2[a] = rotBytes(t1[a]);
+ t3[a] = rotBytes(t2[a]);
+
+ // Calc tf
+ tf[a] = box[a] | (box[a] << 8) | (box[a] << 16) | (box[a] << 24);
+ }
+}
+#endif
+
+//------------------------------------------------------------------------------
+/// Generates the lookup tables needed for decryption
+/// \param Pointer to t0
+/// \param Pointer to t1
+/// \param Pointer to t2
+/// \param Pointer to t3
+/// \param Pointer to tf
+/// \param Box
+//------------------------------------------------------------------------------
+#if defined(ENCRYPTION_ECB) || defined(ENCRYPTION_CBC)
+static inline void generateDecryptionLUTs(unsigned int * t0,
+ unsigned int * t1,
+ unsigned int * t2,
+ unsigned int * t3,
+ unsigned int * tf,
+ unsigned char box[256])
+{
+ unsigned int a;
+
+ for (a=0; a <= 255; a++) {
+
+ // Calc t0
+ t0[a] = (mul(0x0E, box[a])) |
+ (mul(0x09, box[a]) << 8) |
+ (mul(0x0D, box[a]) << 16) |
+ (mul(0x0B, box[a]) << 24);
+
+ // Calc t1, t2, t3
+ t1[a] = rotBytes(t0[a]);
+ t2[a] = rotBytes(t1[a]);
+ t3[a] = rotBytes(t2[a]);
+
+ // Calc tf
+ tf[a] = box[a] | (box[a] << 8) | (box[a] << 16) | (box[a] << 24);
+ }
+}
+#endif
+
+//------------------------------------------------------------------------------
+/// Copies a block to a buffer
+/// \param Block to copy
+/// \param Buffer to store copy
+//------------------------------------------------------------------------------
+#if defined(ENCRYPTION_CTR)
+static void copyBlock(unsigned char input[BC][4], unsigned char output[BC][4])
+{
+ unsigned int j;
+
+ for (j=0; j < BC; j++) {
+ ((int *) output)[j] = ((int *) input)[j];
+ }
+}
+#endif
+
+//------------------------------------------------------------------------------
+/// Encrypts a block of plain text using precalculated LUTs
+/// \param Block of plain text to encrypt
+/// \param Expanded key
+/// \param Pointer to t0
+/// \param Pointer to t1
+/// \param Pointer to t2
+/// \param Pointer to t3
+/// \param Pointer to tf
+//------------------------------------------------------------------------------
+#if defined(ENCRYPTION_CTR)
+static inline void encrypt(unsigned char a[BC][4],
+ const unsigned char rk[ROUNDS+1][BC][4],
+ unsigned int * t0,
+ unsigned int * t1,
+ unsigned int * t2,
+ unsigned int * t3,
+ unsigned int * tf)
+{
+ unsigned char b[BC][4];
+ unsigned int r;
+ unsigned int j;
+
+ // First key addition
+ addRoundKey(a, rk[0]);
+
+ // ROUNDS-1 ordinary rounds
+ for(r=1; r < ROUNDS; r++) {
+ for (j=0; j < BC; j++) {
+
+ ((int *) b)[j] = t0[a[j][0]] ^
+ t1[a[(j+shifts[SC][0][1])%BC][1]] ^
+ t2[a[(j+shifts[SC][0][2])%BC][2]] ^
+ t3[a[(j+shifts[SC][0][3])%BC][3]] ^
+ ((int *) rk[r])[j];
+ }
+ if ((++r) == ROUNDS) {
+ break;
+ }
+ for (j=0; j < BC; j++) {
+ ((int *) a)[j] = t0[b[j][0]] ^
+ t1[b[(j+shifts[SC][0][1])%BC][1]] ^
+ t2[b[(j+shifts[SC][0][2])%BC][2]] ^
+ t3[b[(j+shifts[SC][0][3])%BC][3]] ^
+ ((int *) rk[r])[j];
+ }
+ }
+
+ // Last round (no MixColumns)
+ for (j=0; j < BC; j++) {
+ ((int *) a)[j] = (t0f[b[j][0]]) ^
+ (t1f[b[(j+shifts[SC][0][1])%BC][1]]) ^
+ (t2f[b[(j+shifts[SC][0][2])%BC][2]]) ^
+ (t3f[b[(j+shifts[SC][0][3])%BC][3]]) ^
+ ((int *) rk[ROUNDS])[j];
+ }
+}
+#endif
+
+//------------------------------------------------------------------------------
+/// Decrypts a block of plain text using precalculated LUTs
+/// \param Block of cipher text to decrypt
+/// \param Expanded key
+/// \param Pointer to t0
+/// \param Pointer to t1
+/// \param Pointer to t2
+/// \param Pointer to t3
+/// \param Pointer to tf
+//------------------------------------------------------------------------------
+#if defined(ENCRYPTION_ECB) || defined(ENCRYPTION_CBC)
+static inline void decrypt(unsigned char a[BC][4],
+ const unsigned char rk[ROUNDS+1][BC][4],
+ unsigned int * t0,
+ unsigned int * t1,
+ unsigned int * t2,
+ unsigned int * t3,
+ unsigned int * tf)
+{
+ unsigned char b[BC][4];
+ unsigned int r;
+ unsigned int j;
+
+ // First key addition
+ addRoundKey(a, rk[ROUNDS]);
+
+ // ROUNDS-1 ordinary rounds
+ for(r=ROUNDS-1; r > 0; r--) {
+ for (j=0; j < BC; j++) {
+ ((int *) b)[j] = t0[a[j][0]] ^
+ t1[a[(j+shifts[SC][1][1])%BC][1]] ^
+ t2[a[(j+shifts[SC][1][2])%BC][2]] ^
+ t3[a[(j+shifts[SC][1][3])%BC][3]] ^
+ ((int *) rk[r])[j];
+ }
+ if ((--r) == 0) {
+ break;
+ }
+ for (j=0; j < BC; j++) {
+ ((int *) a)[j] = t0[b[j][0]] ^
+ t1[b[(j+shifts[SC][1][1])%BC][1]] ^
+ t2[b[(j+shifts[SC][1][2])%BC][2]] ^
+ t3[b[(j+shifts[SC][1][3])%BC][3]] ^
+ ((int *) rk[r])[j];
+ }
+ }
+ // Last round (no MixColumns)
+ for (j=0; j < BC; j++) {
+ ((int *) a)[j] = (t0f[b[j][0]]) ^
+ (t1f[b[(j+shifts[SC][1][1])%BC][1]]) ^
+ (t2f[b[(j+shifts[SC][1][2])%BC][2]]) ^
+ (t3f[b[(j+shifts[SC][1][3])%BC][3]]) ^
+ ((int *) rk[0])[j];
+ }
+}
+#endif
+
+//------------------------------------------------------------------------------
+/// Converts an ASCII hexadecimal representation to a raw binary one
+/// \param ASCII value
+/// \param Buffer to store binary value
+/// \param Size of value
+//------------------------------------------------------------------------------
+static void ASCII2RawHex(const unsigned char * ascii,
+ unsigned char * binary,
+ unsigned int length)
+{
+ unsigned char * ptr;
+ unsigned int i;
+
+ ptr = (unsigned char *) binary;
+ for (i=0; i < length; i++, ptr++, ascii++) {
+ if (*ascii >= 'A') {
+ *ptr = *ascii - 'A' + 10;
+ }
+ else {
+ *ptr = *ascii - '0';
+ }
+ *ptr <<= 4;
+ ascii++;
+ if (*ascii >= 'A') {
+ *ptr += *ascii - 'A' + 10;
+ }
+ else {
+ *ptr += *ascii - '0';
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+/// Decrypts a cipher text using ECB mode
+/// \param Cipher text to decrypt
+/// \param Buffer to store plain text
+/// \param Length of cipher text
+/// \param Expanded key to use
+/// \return 0 if successful, 0 otherwise
+//------------------------------------------------------------------------------
+#if defined(ENCRYPTION_ECB)
+static unsigned int ecb_decrypt(const unsigned char * cipherText,
+ unsigned char * plainText,
+ unsigned int length,
+ unsigned char expandedKey[ROUNDS+1][BC][4])
+{
+ unsigned char block[BC][4];
+ unsigned int i;
+ unsigned int l;
+
+ // Check input parameters
+ if ((cipherText == NULL) || (plainText == NULL) || (expandedKey == NULL)) {
+ TRACE_DEBUG("AES/REF: NULL parameter(s).\n\r");
+ return 0;
+ }
+ if (length%ENCRYPTION_BLOCK_LENGTH != 0) {
+ TRACE_DEBUG("AES/REF: Data length must be a multiple of the cipher block size.\n\r");
+ return 0;
+ }
+ // ECB decryption
+ for (l=0; l < length;) {
+ // Copy cipher text block, decrypt it and copy result
+ for (i=0; i < ENCRYPTION_BLOCK_LENGTH; i++) {
+ ((char *) block)[i] = cipherText[l+i];
+ }
+ decrypt(block, expandedKey, T0, T1, T2, T3, TF);
+ for (i=0; i < ENCRYPTION_BLOCK_LENGTH; i++) {
+ plainText[l+i] = ((char *) block)[i];
+ }
+ l += ENCRYPTION_BLOCK_LENGTH;
+ }
+
+ return 1;
+}
+#endif
+
+//------------------------------------------------------------------------------
+/// Decrypts a cipher text using CBC mode
+/// \param Cipher text to decrypt
+/// \param Buffer to store plain text
+/// \param Length of cipher text (in bytes)
+/// \param Expanded key to use
+/// \param Initialization vector to use
+/// \return 1 if successful, 0 otherwise */
+//------------------------------------------------------------------------------
+#if defined(ENCRYPTION_CBC)
+static unsigned int cbc_decrypt(const unsigned char * cipherText,
+ unsigned char * plainText,
+ unsigned int length,
+ const unsigned char expandedKey[ROUNDS+1][BC][4],
+ unsigned char IV[BC][4])
+{
+ unsigned char block[BC][4];
+ unsigned int i;
+ unsigned int l;
+
+ // Check input parameters
+ if ((cipherText == NULL) || (plainText == NULL)) {
+ TRACE_DEBUG("AES/REF: NULL parameter(s).\n\r");
+ return 0;
+ }
+ if (length%ENCRYPTION_BLOCK_LENGTH != 0) {
+ TRACE_DEBUG("AES/REF: Cipher text length must be a multiple of the cipher block length.\n\r");
+ return 0;
+ }
+ // Decrypt data
+ for (l=0; l < length;) {
+ // Copy and decrypt a block of cipher text
+ for (i=0; i < BC; i++) {
+ ((int *) block)[i] = ((int *) &cipherText[l])[i];
+ }
+ decrypt(block, expandedKey, T0, T1, T2, T3, TF);
+ // Xor decrypted text & IV, copy new IV
+ for (i=0; i < BC; i++) {
+ unsigned int tmp = ((int *) block)[i] ^ ((int *) IV)[i];
+ ((int *) IV)[i] = ((int *) &cipherText[l])[i];
+ ((int *) &plainText[l])[i] = tmp;
+ }
+
+ // Loop progression
+ l += ENCRYPTION_BLOCK_LENGTH;
+ }
+ return 1;
+}
+#endif
+
+//------------------------------------------------------------------------------
+/// Decrypts a cipher text using CTR mode
+/// \param Cipher text to decrypt
+/// \param Buffer to store plain text
+/// \param Length of cipher text
+/// \param Expanded key to use
+/// \param Initialization vector to use
+/// \return 1 if successful, 0 otherwise
+//------------------------------------------------------------------------------
+#if defined(ENCRYPTION_CTR)
+static unsigned int ctr_decrypt(const unsigned char * cipherText,
+ unsigned char * plainText,
+ unsigned int length,
+ const unsigned char expandedKey[ROUNDS+1][BC][4],
+ unsigned char IV[BC][4])
+{
+ unsigned char block[BC][4];
+ unsigned int bytes;
+ unsigned int i;
+ unsigned int l;
+ int k;
+
+ // Check input parameters
+ if ((cipherText == NULL) || (plainText == NULL)) {
+ return 0;
+ }
+ for (l=0; l < length;) {
+ // Copy counter and encrypt it
+ copyBlock(IV, block);
+ encrypt(block, expandedKey, T0, T1, T2, T3, TF);
+
+ // XOR current plain text block with encrypted counter
+ bytes = min(length - l, ENCRYPTION_BLOCK_LENGTH);
+
+ for (i=0; i < bytes; i++) {
+ plainText[l+i] = cipherText[l+i] ^ ((char *) block)[i];
+ }
+ // Increment counter (big-endian) and number of encrypted bytes
+ for (k=ENCRYPTION_BLOCK_LENGTH-1; k >= 0; k--) {
+ if (++((char *) IV)[k] != 0) {
+ break;
+ }
+ }
+ l += bytes;
+ }
+ return 1;
+}
+#endif
+
+//------------------------------------------------------------------------------
+// Functions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// Initializes the AES algorithm
+//------------------------------------------------------------------------------
+#ifdef ONLY_ONE_ENCRYPTION
+void aes_ref_init(void)
+{
+ TRACE_DEBUG("AES/REF: Initializing ...\n\r");
+
+ ASCII2RawHex((unsigned char*)ENCRYPTION_KEY, (unsigned char*)key, ENCRYPTION_KEY_LENGTH);
+
+#if defined(ENCRYPTION_ECB) || defined(ENCRYPTION_CBC)
+
+ // Initialize key schedule
+ invKeySchedule(key, expandedKey);
+
+ // Generate lookup tables
+ generateDecryptionLUTs(T0, T1, T2, T3, TF, Si);
+
+#elif defined(ENCRYPTION_CTR)
+
+ // Initialize key schedule
+ keySchedule(key, expandedKey);
+
+ // Generate lookup tables
+ generateEncryptionLUTs(T0, T1, T2, T3, TF, S);
+#endif
+
+#if defined(ENCRYPTION_CBC) || defined(ENCRYPTION_CTR)
+ // Initialize counter
+ ASCII2RawHex((unsigned char*)ENCRYPTION_IV, (unsigned char*)IV, ENCRYPTION_BLOCK_LENGTH);
+#endif
+
+ TRACE_DEBUG("AES/REF: Initialization done.\n\r");
+}
+#endif
+
+//------------------------------------------------------------------------------
+/// Initializes the AES algorithm mode CBC
+//------------------------------------------------------------------------------
+#ifndef ONLY_ONE_ENCRYPTION
+#if defined(ENCRYPTION_CBC)
+void aes_ref_init_CBC(void)
+{
+ TRACE_DEBUG("aes_ref_init_CBC\n\r");
+
+ ASCII2RawHex((unsigned char*)ENCRYPTION_KEY, (unsigned char*)key, ENCRYPTION_KEY_LENGTH);
+
+ // Initialize key schedule
+ invKeySchedule(key, expandedKey);
+
+ // Generate lookup tables
+ generateDecryptionLUTs(T0, T1, T2, T3, TF, Si);
+
+ // Initialize counter
+ ASCII2RawHex((unsigned char*)ENCRYPTION_IV, (unsigned char*)IV, ENCRYPTION_BLOCK_LENGTH);
+
+ TRACE_DEBUG("AES/REF: Initialization done.\n\r");
+}
+#endif
+
+//------------------------------------------------------------------------------
+/// Initializes the AES algorithm mode ECB
+//------------------------------------------------------------------------------
+#if defined(ENCRYPTION_ECB)
+void aes_ref_init_ECB(void)
+{
+ TRACE_DEBUG("aes_ref_init_ECB\n\r");
+
+ ASCII2RawHex((unsigned char*)ENCRYPTION_KEY, (unsigned char*)key, ENCRYPTION_KEY_LENGTH);
+
+ // Initialize key schedule
+ invKeySchedule(key, expandedKey);
+
+ // Generate lookup tables
+ generateDecryptionLUTs(T0, T1, T2, T3, TF, Si);
+
+ TRACE_DEBUG("AES/REF: Initialization done.\n\r");
+}
+#endif
+
+//------------------------------------------------------------------------------
+/// Initializes the AES algorithm mode CTR
+//------------------------------------------------------------------------------
+#if defined(ENCRYPTION_CTR)
+void aes_ref_init_CTR(void)
+{
+ TRACE_DEBUG("aes_ref_init_CTR\n\r");
+
+ ASCII2RawHex((unsigned char*)ENCRYPTION_KEY, (unsigned char*)key, ENCRYPTION_KEY_LENGTH);
+
+ // Initialize key schedule
+ keySchedule(key, expandedKey);
+
+ // Generate lookup tables
+ generateEncryptionLUTs(T0, T1, T2, T3, TF, S);
+
+ // Initialize counter
+ ASCII2RawHex((unsigned char*)ENCRYPTION_IV, (unsigned char*)IV, ENCRYPTION_BLOCK_LENGTH);
+
+ TRACE_DEBUG("AES/REF: Initialization done.\n\r");
+}
+#endif
+#endif // ONLY_ONE_ENCRYPTION
+
+//------------------------------------------------------------------------------
+/// Cleanup the AES algorithm
+//------------------------------------------------------------------------------
+void aes_ref_cleanup(void)
+{
+ TRACE_DEBUG("AES/REF: Cleaning up ...\n\r");
+ TRACE_DEBUG("AES/REF: Cleanup done.\n\r");
+}
+
+//------------------------------------------------------------------------------
+/// Decrypt a cipher text of variable length
+/// \param Cipher text to decrypt
+/// \param Buffer to store plain text
+/// \param Length of cipher text (in bytes)
+/// \return 1 if decryption was successful, 0 otherwise.
+//------------------------------------------------------------------------------
+#ifdef ONLY_ONE_ENCRYPTION
+int aes_ref_decrypt(const unsigned char * cipherText,
+ unsigned char * plainText,
+ unsigned int length)
+{
+ TRACE_DEBUG("aes_ref_decrypt\n\r");
+#if defined(ENCRYPTION_ECB)
+ return ecb_decrypt(cipherText, plainText, length, expandedKey);
+#elif defined(ENCRYPTION_CBC)
+ return cbc_decrypt(cipherText, plainText, length, expandedKey, IV);;
+#elif defined(ENCRYPTION_CTR)
+ return ctr_decrypt(cipherText, plainText, length, expandedKey, IV);
+#endif
+}
+#endif
+
+//------------------------------------------------------------------------------
+/// Decrypt a cipher text of variable length, mode CBC
+/// \param Cipher text to decrypt
+/// \param Buffer to store plain text
+/// \param Length of cipher text (in bytes)
+/// \return 1 if decryption was successful, 0 otherwise.
+//------------------------------------------------------------------------------
+#ifndef ONLY_ONE_ENCRYPTION
+#if defined(ENCRYPTION_CBC)
+int aes_ref_decrypt_CBC(const unsigned char * cipherText,
+ unsigned char * plainText,
+ unsigned int length)
+{
+ TRACE_DEBUG("aes_ref_decrypt_CBC\n\r");
+ return cbc_decrypt(cipherText, plainText, length, expandedKey, IV);;
+}
+#endif
+
+//------------------------------------------------------------------------------
+/// Decrypt a cipher text of variable length, mode ECB
+/// \param Cipher text to decrypt
+/// \param Buffer to store plain text
+/// \param Length of cipher text (in bytes)
+/// \return 1 if decryption was successful, 0 otherwise.
+//------------------------------------------------------------------------------
+#if defined(ENCRYPTION_ECB)
+int aes_ref_decrypt_ECB(const unsigned char * cipherText,
+ unsigned char * plainText,
+ unsigned int length)
+{
+ TRACE_DEBUG("aes_ref_decrypt_ECB\n\r");
+ return ecb_decrypt(cipherText, plainText, length, expandedKey);
+}
+#endif
+
+//------------------------------------------------------------------------------
+/// Decrypt a cipher text of variable length, mode CTR
+/// \param Cipher text to decrypt
+/// \param Buffer to store plain text
+/// \param Length of cipher text (in bytes)
+/// \return 1 if decryption was successful, 0 otherwise.
+//------------------------------------------------------------------------------
+#if defined(ENCRYPTION_CTR)
+int aes_ref_decrypt_CTR(const unsigned char * cipherText,
+ unsigned char * plainText,
+ unsigned int length)
+{
+ TRACE_DEBUG("aes_ref_decrypt_CTR\n\r");
+ return ctr_decrypt(cipherText, plainText, length, expandedKey, IV);
+}
+#endif
+
+#endif // ONLY_ONE_ENCRYPTION
+
+#endif // defined(USE_ENCRYPTION) && defined(ENCRYPTION_AES_REF)
+
+
+
diff --git a/utility/encryption/aes_reference.h b/utility/encryption/aes_reference.h
new file mode 100644
index 0000000..8de7b75
--- /dev/null
+++ b/utility/encryption/aes_reference.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.
+ * ----------------------------------------------------------------------------
+ */
+
+//------------------------------------------------------------------------------
+/// \unit
+///
+/// !Purpose
+///
+/// Firmware encryption using AES reference implementation
+///
+/// !Usage
+///
+/// -# aes_ref_init: Initialize AES hardware
+/// -# aes_ref_init_CBC: for the CBC mode
+/// -# aes_ref_init_ECB: for the CTR mode
+/// -# aes_ref_init_CTR: for the ECB mode
+/// -# aes_ref_cleanup: Cleans up AES
+/// -# aes_ref_decrypt: Decrypts a variable-length cipher text
+/// -# aes_ref_decrypt_CBC: for CBC mode
+/// -# aes_ref_decrypt_ECB: for ECB mode
+/// -# aes_ref_decrypt_CTR: for CTR mode
+//------------------------------------------------------------------------------
+
+#ifndef BOOTLOADER_AES_REFERENCE_H
+#define BOOTLOADER_AES_REFERENCE_H
+
+//------------------------------------------------------------------------------
+// Includes
+//------------------------------------------------------------------------------
+#include "config.h"
+
+
+#if defined(USE_ENCRYPTION) && defined(ENCRYPTION_AES_REF)
+
+//------------------------------------------------------------------------------
+// Check configuration
+//------------------------------------------------------------------------------
+
+// Supported modes
+#if !defined(ENCRYPTION_ECB) && \
+ !defined(ENCRYPTION_CBC) && \
+ !defined(ENCRYPTION_CTR)
+ #error No other mode than ECB, CBC & CTR are supported.
+#endif
+
+// Supported key length
+#if (ENCRYPTION_KEY_LENGTH != 16) && \
+ (ENCRYPTION_KEY_LENGTH != 24) && \
+ (ENCRYPTION_KEY_LENGTH != 32)
+ #error Only key lengths of 128, 192 or 256 bits are supported.
+#endif
+
+// Supported block length
+#if (ENCRYPTION_BLOCK_LENGTH != 16)
+ #error Only block length of 128 bits is supported.
+#endif
+
+//------------------------------------------------------------------------------
+// Definitions
+//------------------------------------------------------------------------------
+#define BC (ENCRYPTION_BLOCK_LENGTH / 4)
+#define SC ((BC - 4) >> 1)
+#define KC (ENCRYPTION_KEY_LENGTH / 4)
+#define t0f 0x000000FF & tf
+#define t1f 0x0000FF00 & tf
+#define t2f 0x00FF0000 & tf
+#define t3f 0xFF000000 & tf
+
+#if (KC >= BC)
+ #define ROUNDS (KC + 6)
+#else
+ #define ROUNDS (BC + 6)
+#endif
+
+#ifdef ONLY_ONE_ENCRYPTION
+#define ENCRYPTION_INIT aes_ref_init
+#define ENCRYPTION_CLEANUP aes_ref_cleanup
+#define ENCRYPTION_DECRYPT aes_ref_decrypt
+#endif
+
+//------------------------------------------------------------------------------
+// Prototypes
+//------------------------------------------------------------------------------
+extern void aes_ref_init(void);
+extern void aes_ref_init_CBC(void);
+extern void aes_ref_init_ECB(void);
+extern void aes_ref_init_CTR(void);
+extern void aes_ref_cleanup(void);
+extern int aes_ref_decrypt(const unsigned char * cipherText,
+ unsigned char * plainText,
+ unsigned int length);
+extern int aes_ref_decrypt_CBC(const unsigned char * cipherText,
+ unsigned char * plainText,
+ unsigned int length);
+extern int aes_ref_decrypt_ECB(const unsigned char * cipherText,
+ unsigned char * plainText,
+ unsigned int length);
+extern int aes_ref_decrypt_CTR(const unsigned char * cipherText,
+ unsigned char * plainText,
+ unsigned int length);
+
+#endif // defined(USE_ENCRYPTION) && defined(ENCRYPTION_AES_REF)
+
+#endif // BOOTLOADER_AES_REFERENCE_H
+
+
diff --git a/utility/encryption/encryption.h b/utility/encryption/encryption.h
new file mode 100644
index 0000000..d21a43a
--- /dev/null
+++ b/utility/encryption/encryption.h
@@ -0,0 +1,98 @@
+/* ----------------------------------------------------------------------------
+ * 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
+///
+/// Firmware encryption
+///
+/// !Usage
+///
+/// This file must include the header of every encryption module implemented for
+/// the bootloader. It is also responsible for defining mock functions if no
+/// encryption module is selected, as well as checking that parameters are
+/// correctly set.
+//
+/// An encryption module must define the following functions:
+/// -# void encryption_init(void);
+/// -# void encryption_cleanup(void);
+/// -# int encryption_decrypt(const unsigned char *, unsigned char *, unsigned int)
+//------------------------------------------------------------------------------
+
+#ifndef BOOTLOADER_ENCRYPTION_H
+#define BOOTLOADER_ENCRYPTION_H
+
+//------------------------------------------------------------------------------
+// Includes
+//------------------------------------------------------------------------------
+#include "config.h"
+
+
+//------------------------------------------------------------------------------
+// Check configuration
+//------------------------------------------------------------------------------
+#ifdef ONLY_ONE_ENCRYPTION
+#if !defined(ENCRYPTION_INIT) && !defined(USE_ENCRYPTION)
+ #define ENCRYPTION_INIT();
+ #define ENCRYPTION_CLEANUP();
+ #define ENCRYPTION_DECRYPT(...) 1
+
+#elif !defined(ENCRYPTION_INIT) && defined(USE_ENCRYPTION)
+ #error USE_ENCRYPTION defined but no encryption method selected.
+
+#elif !defined(ENCRYPTION_AES_LTC) && \
+ !defined(ENCRYPTION_AES_REF) && \
+ !defined(ENCRYPTION_AES_HARD) && \
+ !defined(ENCRYPTION_3DES_LTC) && \
+ !defined(ENCRYPTION_3DES_HARD)
+ #error No algorithm selected.
+
+#elif !defined(ENCRYPTION_ECB) && \
+ !defined(ENCRYPTION_CBC) && \
+ !defined(ENCRYPTION_CTR)
+ #error No encryption mode selected.
+
+#elif !defined(ENCRYPTION_KEY)
+ #error No key defined.
+
+#elif !defined(ENCRYPTION_KEY_LENGTH)
+ #error No key length selected.
+
+#elif !defined(ENCRYPTION_IV)
+ #error No initialization vector defined.
+
+#elif !defined(ENCRYPTION_BLOCK_LENGTH)
+ #error No block length selected.
+
+#endif
+#endif // ONLY_ONE_ENCRYPTION
+#endif // BOOTLOADER_ENCRYPTION_H
+
diff --git a/utility/encryption/libtomcrypt.c b/utility/encryption/libtomcrypt.c
new file mode 100644
index 0000000..da9ac06
--- /dev/null
+++ b/utility/encryption/libtomcrypt.c
@@ -0,0 +1,445 @@
+/* ----------------------------------------------------------------------------
+ * 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.
+ * ----------------------------------------------------------------------------
+ */
+
+//------------------------------------------------------------------------------
+// Function: Firmware encryption using libTomCrypt
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+// Includes
+//------------------------------------------------------------------------------
+
+#include "libtomcrypt.h"
+#include <stdio.h>
+#include <string.h>
+#include "config.h"
+
+#if defined(USE_ENCRYPTION) && (defined(ENCRYPTION_AES_LTC) || defined(ENCRYPTION_3DES_LTC))
+#include <board.h>
+#include <utility/trace.h>
+#include <utility/assert.h>
+#include <pmc/pmc.h>
+#include <src/headers/tomcrypt.h>
+
+//------------------------------------------------------------------------------
+// Global variables
+//------------------------------------------------------------------------------
+
+#if defined(ENCRYPTION_ECB)
+ symmetric_ECB sECB;
+#endif
+#if defined(ENCRYPTION_CBC)
+ symmetric_CBC sCBC;
+#endif
+#if defined(ENCRYPTION_CTR)
+ symmetric_CTR sCTR;
+#endif
+
+//------------------------------------------------------------------------------
+// Inline functions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// Converts an ASCII string to an hexadecimal value
+/// \param ASCII string to convert
+/// \param Buffer to store converted value
+/// \param Length of buffer
+//------------------------------------------------------------------------------
+static inline void ASCII2Hex(const char * ascii, unsigned char * binary, unsigned int length)
+{
+ unsigned int i;
+
+ for (i=0; i < length; i++) {
+ if (ascii[i*2] >= 'A') {
+ binary[i] = ascii[i*2] - 'A' + 10;
+ }
+ else {
+ binary[i] = ascii[i*2] - '0';
+ }
+ binary[i] <<= 4;
+ if (ascii[i*2+1] >= 'A') {
+ binary[i] += ascii[i*2+1] - 'A' + 10;
+ }
+ else {
+ binary[i] += ascii[i*2+1] - '0';
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+// Functions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// Initializes the decryption process
+//------------------------------------------------------------------------------
+#ifdef ONLY_ONE_ENCRYPTION
+void ltc_init(void)
+{
+ int cipherID;
+ unsigned char key[ENCRYPTION_KEY_LENGTH];
+
+#if defined(ENCRYPTION_CTR) || defined(ENCRYPTION_CBC)
+ unsigned char IV[ENCRYPTION_BLOCK_LENGTH];
+#endif
+
+ TRACE_DEBUG("LTC: Initializing ...\n\r");
+
+ // Register cipher
+ register_cipher(&CIPHER_DESC);
+ cipherID = find_cipher(CIPHER_NAME);
+
+ // Load key
+ ASCII2Hex(ENCRYPTION_KEY, key, ENCRYPTION_KEY_LENGTH);
+
+#if defined(ENCRYPTION_CTR) || defined(ENCRYPTION_CBC)
+ // Load IV
+ ASCII2Hex(ENCRYPTION_IV, IV, ENCRYPTION_BLOCK_LENGTH);
+#endif
+
+ // Start decryption mode
+#if defined(ENCRYPTION_ECB)
+ ecb_start(cipherID, key, ENCRYPTION_KEY_LENGTH, 0, &sECB);
+#elif defined(ENCRYPTION_CBC)
+ cbc_start(cipherID, IV, key, ENCRYPTION_KEY_LENGTH, 0, &sCBC);
+#elif defined(ENCRYPTION_CTR)
+ ctr_start(cipherID, IV, key, ENCRYPTION_KEY_LENGTH, 0, CTR_COUNTER_BIG_ENDIAN, &sCTR);
+#endif
+
+ TRACE_DEBUG("LTC: Initialization done.\n\r");
+}
+#endif // ONLY_ONE_ENCRYPTION
+
+//------------------------------------------------------------------------------
+/// Initializes the decryption process for AES, mode CBC
+//------------------------------------------------------------------------------
+#ifndef ONLY_ONE_ENCRYPTION
+#if defined(ENCRYPTION_CBC)
+void ltc_init_AES_CBC(void)
+{
+ int cipherID;
+ unsigned char key[ENCRYPTION_KEY_LENGTH];
+ unsigned char IV[ENCRYPTION_BLOCK_LENGTH];
+
+ TRACE_DEBUG("LTC: Initializing CBC...\n\r");
+
+ // Register cipher
+ register_cipher(&rijndael_desc);
+ cipherID = find_cipher("rijndael");
+
+ // Load key
+ ASCII2Hex(ENCRYPTION_KEY, key, ENCRYPTION_KEY_LENGTH);
+
+ // Load IV
+ ASCII2Hex(ENCRYPTION_IV, IV, ENCRYPTION_BLOCK_LENGTH);
+
+ // Start decryption mode
+ cbc_start(cipherID, IV, key, ENCRYPTION_KEY_LENGTH, 0, &sCBC);
+
+ TRACE_DEBUG("LTC: Initialization done.\n\r");
+}
+#endif
+
+//------------------------------------------------------------------------------
+/// Initializes the decryption process for AES, mode CTR
+//------------------------------------------------------------------------------
+#if defined(ENCRYPTION_CTR)
+void ltc_init_AES_CTR(void)
+{
+ int cipherID;
+ unsigned char key[ENCRYPTION_KEY_LENGTH];
+ unsigned char IV[ENCRYPTION_BLOCK_LENGTH];
+
+ TRACE_DEBUG("LTC: Initializing CTR...\n\r");
+
+ // Register cipher
+ register_cipher(&rijndael_desc);
+ cipherID = find_cipher("rijndael");
+
+ // Load key
+ ASCII2Hex(ENCRYPTION_KEY, key, ENCRYPTION_KEY_LENGTH);
+
+ // Load IV
+ ASCII2Hex(ENCRYPTION_IV, IV, ENCRYPTION_BLOCK_LENGTH);
+
+ // Start decryption mode
+ ctr_start(cipherID, IV, key, ENCRYPTION_KEY_LENGTH, 0, CTR_COUNTER_BIG_ENDIAN, &sCTR);
+
+ TRACE_DEBUG("LTC: Initialization done.\n\r");
+}
+#endif
+
+//------------------------------------------------------------------------------
+/// Initializes the decryption process for AES, mode ECB
+//------------------------------------------------------------------------------
+#if defined(ENCRYPTION_ECB)
+void ltc_init_AES_ECB(void)
+{
+ int cipherID;
+ unsigned char key[ENCRYPTION_KEY_LENGTH];
+
+ TRACE_DEBUG("LTC: Initializing ECB...\n\r");
+
+ // Register cipher
+ register_cipher(&rijndael_desc);
+ cipherID = find_cipher("rijndael");
+
+ // Load key
+ ASCII2Hex(ENCRYPTION_KEY, key, ENCRYPTION_KEY_LENGTH);
+
+ // Start decryption mode
+ ecb_start(cipherID, key, ENCRYPTION_KEY_LENGTH, 0, &sECB);
+
+ TRACE_DEBUG("LTC: Initialization done.\n\r");
+}
+#endif
+
+//------------------------------------------------------------------------------
+/// Initializes the decryption process for 3DES, mode CBC
+//------------------------------------------------------------------------------
+#if defined(ENCRYPTION_CBC)
+void ltc_init_3DES_CBC(void)
+{
+ int cipherID;
+ unsigned char key[ENCRYPTION_KEY_LENGTH];
+ unsigned char IV[ENCRYPTION_BLOCK_LENGTH];
+
+ TRACE_DEBUG("LTC: Initializing CBC...\n\r");
+
+ // Register cipher
+ register_cipher(&des3_desc);
+ cipherID = find_cipher("3des");
+
+ // Load key
+ ASCII2Hex(ENCRYPTION_KEY, key, ENCRYPTION_KEY_LENGTH);
+
+ // Load IV
+ ASCII2Hex(ENCRYPTION_IV, IV, ENCRYPTION_BLOCK_LENGTH);
+
+ // Start decryption mode
+ cbc_start(cipherID, IV, key, ENCRYPTION_KEY_LENGTH, 0, &sCBC);
+
+ TRACE_DEBUG("LTC: Initialization done.\n\r");
+}
+#endif
+
+//------------------------------------------------------------------------------
+/// Initializes the decryption process for 3DES, mode CTR
+//------------------------------------------------------------------------------
+#if defined(ENCRYPTION_CTR)
+void ltc_init_3DES_CTR(void)
+{
+ int cipherID;
+ unsigned char key[ENCRYPTION_KEY_LENGTH];
+ unsigned char IV[ENCRYPTION_BLOCK_LENGTH];
+
+ TRACE_DEBUG("LTC: Initializing CTR...\n\r");
+
+ // Register cipher
+ register_cipher(&des3_desc);
+ cipherID = find_cipher("3des");
+
+ // Load key
+ ASCII2Hex(ENCRYPTION_KEY, key, ENCRYPTION_KEY_LENGTH);
+
+ // Load IV
+ ASCII2Hex(ENCRYPTION_IV, IV, ENCRYPTION_BLOCK_LENGTH);
+
+ // Start decryption mode
+ ctr_start(cipherID, IV, key, ENCRYPTION_KEY_LENGTH, 0, CTR_COUNTER_BIG_ENDIAN, &sCTR);
+
+ TRACE_DEBUG("LTC: Initialization done.\n\r");
+}
+#endif
+
+//------------------------------------------------------------------------------
+/// Initializes the decryption process for 3DES, mode ECB
+//------------------------------------------------------------------------------
+#if defined(ENCRYPTION_ECB)
+void ltc_init_3DES_ECB(void)
+{
+ int cipherID;
+ unsigned char key[ENCRYPTION_KEY_LENGTH];
+
+ TRACE_DEBUG("LTC: Initializing ECB...\n\r");
+
+ // Register cipher
+ register_cipher(&des3_desc);
+ cipherID = find_cipher("3des");
+
+ // Load key
+ ASCII2Hex(ENCRYPTION_KEY, key, ENCRYPTION_KEY_LENGTH);
+
+ // Start decryption mode
+ ecb_start(cipherID, key, ENCRYPTION_KEY_LENGTH, 0, &sECB);
+
+ TRACE_DEBUG("LTC: Initialization done.\n\r");
+}
+#endif
+#endif // ONLY_ONE_ENCRYPTION
+
+
+//------------------------------------------------------------------------------
+/// Terminates the decryption process
+//------------------------------------------------------------------------------
+#ifdef ONLY_ONE_ENCRYPTION
+void ltc_cleanup(void)
+{
+ TRACE_DEBUG("LTC: Cleaning up ...\n\r");
+
+#if defined(ENCRYPTION_ECB)
+ ecb_done(&sECB);
+#elif defined(ENCRYPTION_CBC)
+ cbc_done(&sCBC);
+#elif defined(ENCRYPTION_CTR)
+ ctr_done(&sCTR);
+#endif
+
+ TRACE_DEBUG("LTC: Cleanup done.\n\r");
+}
+#endif
+
+//------------------------------------------------------------------------------
+/// Terminates the decryption process for mode CBC
+//------------------------------------------------------------------------------
+#ifndef ONLY_ONE_ENCRYPTION
+#if defined(ENCRYPTION_CBC)
+void ltc_cleanup_CBC(void)
+{
+ TRACE_DEBUG("LTC: Cleaning up CBC...\n\r");
+ cbc_done(&sCBC);
+ TRACE_DEBUG("LTC: Cleanup done.\n\r");
+}
+#endif
+
+//------------------------------------------------------------------------------
+/// Terminates the decryption process for mode CTR
+//------------------------------------------------------------------------------
+#if defined(ENCRYPTION_CTR)
+void ltc_cleanup_CTR(void)
+{
+ TRACE_DEBUG("LTC: Cleaning up CTR...\n\r");
+ ctr_done(&sCTR);
+ TRACE_DEBUG("LTC: Cleanup done.\n\r");
+}
+#endif
+
+//------------------------------------------------------------------------------
+/// Terminates the decryption process for mode ECB
+//------------------------------------------------------------------------------
+#if defined(ENCRYPTION_ECB)
+void ltc_cleanup_ECB(void)
+{
+ TRACE_DEBUG("LTC: Cleaning up ECB...\n\r");
+ ecb_done(&sECB);
+ TRACE_DEBUG("LTC: Cleanup done.\n\r");
+}
+#endif
+#endif // ONLY_ONE_ENCRYPTION
+
+//------------------------------------------------------------------------------
+/// Decrypts a block of data
+/// \param Data to decrypt
+/// \param Buffer to store decrypted data
+/// \param Length of data
+/// \return 1 if successful, 0 otherwise.
+//------------------------------------------------------------------------------
+#ifdef ONLY_ONE_ENCRYPTION
+int ltc_decrypt(const unsigned char * cipherText, unsigned char * plainText, unsigned int length)
+{
+#if defined(ENCRYPTION_ECB)
+ if (ecb_decrypt(cipherText, plainText, length, &sECB) != CRYPT_OK) {
+#elif defined(ENCRYPTION_CBC)
+ if (cbc_decrypt(cipherText, plainText, length, &sCBC) != CRYPT_OK) {
+#elif defined(ENCRYPTION_CTR)
+ if (ctr_decrypt(cipherText, plainText, length, &sCTR) != CRYPT_OK) {
+#endif
+ return 0;
+ }
+ else {
+ return 1;
+ }
+}
+#endif
+
+//------------------------------------------------------------------------------
+/// Decrypts a block of data in CBC mode
+/// \param Data to decrypt
+/// \param Buffer to store decrypted data
+/// \param Length of data
+/// \return 1 if successful, 0 otherwise.
+//------------------------------------------------------------------------------
+#ifndef ONLY_ONE_ENCRYPTION
+int ltc_decrypt_CBC(const unsigned char * cipherText, unsigned char * plainText, unsigned int length)
+{
+ if (cbc_decrypt(cipherText, plainText, length, &sCBC) != CRYPT_OK) {
+ return 0;
+ }
+ else {
+ return 1;
+ }
+}
+
+//------------------------------------------------------------------------------
+/// Decrypts a block of data in CTR mode
+/// \param Data to decrypt
+/// \param Buffer to store decrypted data
+/// \param Length of data
+/// \return 1 if successful, 0 otherwise.
+//------------------------------------------------------------------------------
+int ltc_decrypt_CTR(const unsigned char * cipherText, unsigned char * plainText, unsigned int length)
+{
+ if (ctr_decrypt(cipherText, plainText, length, &sCTR) != CRYPT_OK) {
+ return 0;
+ }
+ else {
+ return 1;
+ }
+}
+
+//------------------------------------------------------------------------------
+/// Decrypts a block of data in ECB mode
+/// \param Data to decrypt
+/// \param Buffer to store decrypted data
+/// \param Length of data
+/// \return 1 if successful, 0 otherwise.
+//------------------------------------------------------------------------------
+int ltc_decrypt_ECB(const unsigned char * cipherText, unsigned char * plainText, unsigned int length)
+{
+ if (ecb_decrypt(cipherText, plainText, length, &sECB) != CRYPT_OK) {
+ return 0;
+ }
+ else {
+ return 1;
+ }
+}
+#endif // ONLY_ONE_ENCRYPTION
+
+#endif // defined(USE_ENCRYPTION) && (defined(ENCRYPTION_AES_LTC) || defined(ENCRYPTION_3DES_LTC))
+
diff --git a/utility/encryption/libtomcrypt.h b/utility/encryption/libtomcrypt.h
new file mode 100644
index 0000000..4052075
--- /dev/null
+++ b/utility/encryption/libtomcrypt.h
@@ -0,0 +1,149 @@
+/* ----------------------------------------------------------------------------
+ * 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
+///
+/// Firmware encryption using libTomCrypt
+///
+/// !Usage
+///
+/// -# ltc_init: Initialize LibTomCrypt
+/// -# ltc_init_AES_CBC
+/// -# ltc_init_AES_CTR
+/// -# ltc_init_AES_ECB
+/// -# ltc_init_3DES_CBC
+/// -# ltc_init_3DES_CTR
+/// -# ltc_init_3DES_ECB
+/// -# ltc_cleanup
+/// -# ltc_cleanup_CBC
+/// -# ltc_cleanup_CTR
+/// -# ltc_cleanup_ECB
+/// -# ltc_decrypt
+/// -# ltc_decrypt_CBC
+/// -# ltc_decrypt_CTR
+/// -# ltc_decrypt_ECB
+//------------------------------------------------------------------------------
+
+#ifndef BOOTLOADER_LIBTOMCRYPT_H
+#define BOOTLOADER_LIBTOMCRYPT_H
+
+//------------------------------------------------------------------------------
+// Includes
+//------------------------------------------------------------------------------
+
+#include "config.h"
+
+#if defined(USE_ENCRYPTION) && (defined(ENCRYPTION_AES_LTC) || defined(ENCRYPTION_3DES_LTC))
+
+//------------------------------------------------------------------------------
+// Check configuration
+//------------------------------------------------------------------------------
+
+// Supported modes
+#if !defined(ENCRYPTION_CTR) && \
+ !defined(ENCRYPTION_CBC) && \
+ !defined(ENCRYPTION_ECB)
+ #error No other mode than ECB, CBC & CTR are supported.
+#endif
+
+// Supported key length
+#if defined(ENCRYPTION_AES_LTC)
+ #if (ENCRYPTION_KEY_LENGTH != 16) && \
+ (ENCRYPTION_KEY_LENGTH != 24) && \
+ (ENCRYPTION_KEY_LENGTH != 32)
+ #error Only a key length of 128, 192 or 256 bits are supported with AES.
+ #endif
+#elif defined(ENCRYPTION_3DES_LTC)
+ #if (ENCRYPTION_KEY_LENGTH != 16) && \
+ (ENCRYPTION_KEY_LENGTH != 24)
+ #error Only a key length of 128 or 192 bits are supported with Triple-DES.
+ #endif
+#endif
+
+// Supported block length
+#if defined(ENCRYPTION_AES_LTC)
+ #if (ENCRYPTION_BLOCK_LENGTH != 16)
+ #error Only a block length of 128 bits is supported with AES.
+ #endif
+#elif defined(ENCRYPTION_3DES_LTC)
+ #if (ENCRYPTION_BLOCK_LENGTH != 8)
+ #error Only a block length of 64 bits is supported with Triple-DES.
+ #endif
+#endif
+
+//------------------------------------------------------------------------------
+// Definitions
+//------------------------------------------------------------------------------
+
+// Functions
+#ifdef ONLY_ONE_ENCRYPTION
+#define ENCRYPTION_INIT ltc_init
+#define ENCRYPTION_CLEANUP ltc_cleanup
+#define ENCRYPTION_DECRYPT ltc_decrypt
+
+#if defined(ENCRYPTION_AES_LTC)
+ #define CIPHER_NAME "rijndael"
+ #define CIPHER_DESC rijndael_desc
+#elif defined(ENCRYPTION_3DES_LTC)
+ #define CIPHER_NAME "3des"
+ #define CIPHER_DESC des3_desc
+#endif
+#endif
+
+//------------------------------------------------------------------------------
+// Prototypes
+//------------------------------------------------------------------------------
+
+#ifdef ONLY_ONE_ENCRYPTION
+extern void ltc_init(void);
+#endif
+extern void ltc_init_AES_CBC(void);
+extern void ltc_init_AES_CTR(void);
+extern void ltc_init_AES_ECB(void);
+extern void ltc_init_3DES_CBC(void);
+extern void ltc_init_3DES_CTR(void);
+extern void ltc_init_3DES_ECB(void);
+
+extern void ltc_cleanup(void);
+extern void ltc_cleanup_CBC(void);
+extern void ltc_cleanup_CTR(void);
+extern void ltc_cleanup_ECB(void);
+
+extern int ltc_decrypt(const unsigned char * cipherText, unsigned char * plainText, unsigned int length);
+extern int ltc_decrypt_CBC(const unsigned char * cipherText, unsigned char * plainText, unsigned int length);
+extern int ltc_decrypt_CTR(const unsigned char * cipherText, unsigned char * plainText, unsigned int length);
+extern int ltc_decrypt_ECB(const unsigned char * cipherText, unsigned char * plainText, unsigned int length);
+
+#endif // defined(USE_ENCRYPTION) && (defined(ENCRYPTION_AES_LTC) || defined(ENCRYPTION_3DES_LTC))
+#endif // BOOTLOADER_AES_LIBTOMCRYPT_H
+
+
diff --git a/utility/encryption/tdes_hardware.c b/utility/encryption/tdes_hardware.c
new file mode 100644
index 0000000..c3b1ae2
--- /dev/null
+++ b/utility/encryption/tdes_hardware.c
@@ -0,0 +1,433 @@
+/* ----------------------------------------------------------------------------
+ * 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.
+ * ----------------------------------------------------------------------------
+ */
+
+//------------------------------------------------------------------------------
+// Function: Firmware encryption using TDES hardware acceleration
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+// Includes
+//------------------------------------------------------------------------------
+
+#include "tdes_hardware.h"
+
+#if defined(USE_ENCRYPTION) && defined(ENCRYPTION_3DES_HARD)
+#include <stdio.h>
+#include <string.h>
+#include <board.h>
+#include <utility/trace.h>
+#include <utility/assert.h>
+#include <pmc/pmc.h>
+
+//------------------------------------------------------------------------------
+// Global variables
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+// Inline functions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// Converts an ASCII value to an hexadecimal one
+/// \param ASCII string
+/// \param Buffer to store integer value
+/// \param Length of string
+//------------------------------------------------------------------------------
+static inline void ASCII2Hex(const unsigned char * ascii, unsigned char * binary, unsigned int length)
+{
+ unsigned int i;
+
+ for (i=0; i < length; i++) {
+ if (ascii[i*2] >= 'A') {
+ binary[i] = ascii[i*2] - 'A' + 10;
+ }
+ else {
+ binary[i] = ascii[i*2] - '0';
+ }
+ binary[i] <<= 4;
+ if (ascii[i*2+1] >= 'A') {
+ binary[i] += ascii[i*2+1] - 'A' + 10;
+ }
+ else {
+ binary[i] += ascii[i*2+1] - '0';
+ }
+ }
+}
+//------------------------------------------------------------------------------
+// Functions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// Initializes the TDES peripheral
+//------------------------------------------------------------------------------
+#ifdef ONLY_ONE_ENCRYPTION
+void tdes_hard_init(void)
+{
+ unsigned char key[ENCRYPTION_KEY_LENGTH];
+
+ TRACE_DEBUG("TDES/HARD: Initializing ...\n\r");
+
+ // Activate peripheral clock
+#ifdef AT91C_ID_AES
+ PMC_EnablePeripheral( AT91C_ID_AES );
+#elif AT91C_ID_AESTDES
+ PMC_EnablePeripheral( AT91C_ID_AESTDES );
+#elif AT91C_ID_TDES
+ PMC_EnablePeripheral( AT91C_ID_TDES );
+#else
+#error AES/TDES undefined
+#endif
+
+ // Load mode
+#if (ENCRYPTION_KEY_LENGTH == 24)
+ AT91C_BASE_TDES->TDES_MR = AT91C_TDES_SMOD_MANUAL | TDES_MODE
+ | AT91C_TDES_TDESMOD | TDES_CIPHER;
+#else
+ AT91C_BASE_TDES->TDES_MR = AT91C_TDES_SMOD_MANUAL | TDES_MODE | AT91C_TDES_KEYMOD
+ | AT91C_TDES_TDESMOD | TDES_CIPHER;
+#endif
+
+ // Convert and load key
+ ASCII2Hex((unsigned char*)ENCRYPTION_KEY, key, ENCRYPTION_KEY_LENGTH);
+
+ AT91C_BASE_TDES->TDES_KEY1WxR[0] = ((int *) key)[0];
+ AT91C_BASE_TDES->TDES_KEY1WxR[1] = ((int *) key)[1];
+ AT91C_BASE_TDES->TDES_KEY2WxR[0] = ((int *) key)[2];
+ AT91C_BASE_TDES->TDES_KEY2WxR[1] = ((int *) key)[3];
+
+#if (ENCRYPTION_KEY_LENGTH == 24)
+ AT91C_BASE_TDES->TDES_KEY3WxR[0] = ((int *) key)[4];
+ AT91C_BASE_TDES->TDES_KEY3WxR[1] = ((int *) key)[5];
+#endif
+
+#if defined(ENCRYPTION_CBC)
+ unsigned char IV[8];
+ ASCII2Hex((unsigned char*)ENCRYPTION_IV, IV, ENCRYPTION_BLOCK_LENGTH);
+
+ AT91C_BASE_TDES->TDES_IVxR[0] = ((int *) IV)[0];
+ AT91C_BASE_TDES->TDES_IVxR[1] = ((int *) IV)[1];
+
+#elif defined(ENCRYPTION_CTR)
+ // Convert IV
+ ASCII2Hex((unsigned char*)ENCRYPTION_IV, CTR, ENCRYPTION_BLOCK_LENGTH);
+#endif
+
+ TRACE_DEBUG("TDES/HARD: Initialization done.\n\r");
+}
+#endif
+
+//------------------------------------------------------------------------------
+/// Initializes the DES peripheral for CBC mode
+//------------------------------------------------------------------------------
+#ifndef ONLY_ONE_ENCRYPTION
+void tdes_hard_init_CBC(void)
+{
+ unsigned char key[TDES_ENCRYPTION_KEY_LENGTH];
+ unsigned char IV[8];
+
+ TRACE_DEBUG("tdes_hard_init_CBC\n\r");
+
+ // Activate peripheral clock
+#ifdef AT91C_ID_AES
+ PMC_EnablePeripheral( AT91C_ID_AES );
+#elif AT91C_ID_AESTDES
+ PMC_EnablePeripheral( AT91C_ID_AESTDES );
+#elif AT91C_ID_TDES
+ PMC_EnablePeripheral( AT91C_ID_TDES );
+#else
+#error AES undefined
+#endif
+ // Reset
+ AT91C_BASE_TDES->TDES_CR = AT91C_TDES_SWRST;
+
+ // Load mode
+#if (TDES_ENCRYPTION_KEY_LENGTH == 8)
+ AT91C_BASE_TDES->TDES_MR = AT91C_TDES_SMOD_MANUAL // Manual Mode.
+ | AT91C_TDES_OPMOD_CBC; // Cipher Block Chaining mode
+#elif (TDES_ENCRYPTION_KEY_LENGTH == 16)
+ AT91C_BASE_TDES->TDES_MR = AT91C_TDES_SMOD_MANUAL // Manual Mode.
+ | AT91C_TDES_OPMOD_CBC // Cipher Block Chaining mode
+ | AT91C_TDES_KEYMOD // Two-key algorithm is selected.
+ // There is no need to write TDES_KEY3WxR registers.
+ | AT91C_TDES_TDESMOD; // Triple DES processing using TDES_KEY1WxR, TDES_KEY2WxR and TDES_KEY3WxR registers.
+#elif (TDES_ENCRYPTION_KEY_LENGTH == 24)
+ AT91C_BASE_TDES->TDES_MR = AT91C_TDES_SMOD_MANUAL // Manual Mode.
+ | AT91C_TDES_OPMOD_CBC // Cipher Block Chaining mode
+ // Need to write TDES_KEY3WxR registers.
+ | AT91C_TDES_TDESMOD; // Triple DES processing using TDES_KEY1WxR, TDES_KEY2WxR and TDES_KEY3WxR registers.
+#else
+#error TDES_ENCRYPTION_KEY_LENGTH
+#endif
+
+ // Convert and load key
+ ASCII2Hex((unsigned char*)TDES_ENCRYPTION_KEY, key, TDES_ENCRYPTION_KEY_LENGTH);
+
+ AT91C_BASE_TDES->TDES_KEY1WxR[0] = ((int *) key)[0];
+ AT91C_BASE_TDES->TDES_KEY1WxR[1] = ((int *) key)[1];
+ AT91C_BASE_TDES->TDES_KEY2WxR[0] = ((int *) key)[2];
+ AT91C_BASE_TDES->TDES_KEY2WxR[1] = ((int *) key)[3];
+
+#if (TDES_ENCRYPTION_KEY_LENGTH == 24)
+ AT91C_BASE_TDES->TDES_KEY3WxR[0] = ((int *) key)[4];
+ AT91C_BASE_TDES->TDES_KEY3WxR[1] = ((int *) key)[5];
+#endif
+
+ ASCII2Hex((unsigned char*)ENCRYPTION_IV, IV, ENCRYPTION_BLOCK_LENGTH);
+
+ AT91C_BASE_TDES->TDES_IVxR[0] = ((int *) IV)[0];
+ AT91C_BASE_TDES->TDES_IVxR[1] = ((int *) IV)[1];
+}
+#endif
+
+//------------------------------------------------------------------------------
+/// Initializes the DES peripheral for ECB mode
+//------------------------------------------------------------------------------
+#ifndef ONLY_ONE_ENCRYPTION
+void tdes_hard_init_ECB(void)
+{
+ unsigned char key[TDES_ENCRYPTION_KEY_LENGTH];
+
+ TRACE_DEBUG("tdes_hard_init_ECB\n\r");
+
+ // Activate peripheral clock
+#ifdef AT91C_ID_AES
+ PMC_EnablePeripheral( AT91C_ID_AES );
+#elif AT91C_ID_AESTDES
+ PMC_EnablePeripheral( AT91C_ID_AESTDES );
+#elif AT91C_ID_TDES
+ PMC_EnablePeripheral( AT91C_ID_TDES );
+#else
+#error AES undefined
+#endif
+
+ // Load mode
+#if (TDES_ENCRYPTION_KEY_LENGTH == 8)
+ AT91C_BASE_TDES->TDES_MR = AT91C_TDES_SMOD_MANUAL // Manual Mode.
+ | AT91C_TDES_OPMOD_ECB; // ECB Electronic CodeBook mode
+#elif (TDES_ENCRYPTION_KEY_LENGTH == 16)
+ AT91C_BASE_TDES->TDES_MR = AT91C_TDES_SMOD_MANUAL // Manual Mode.
+ | AT91C_TDES_OPMOD_ECB // ECB Electronic CodeBook mode
+ | AT91C_TDES_KEYMOD // Two-key algorithm is selected.
+ // There is no need to write TDES_KEY3WxR registers.
+ | AT91C_TDES_TDESMOD; // Triple DES processing using TDES_KEY1WxR, TDES_KEY2WxR and TDES_KEY3WxR registers.
+#elif (TDES_ENCRYPTION_KEY_LENGTH == 24)
+ AT91C_BASE_TDES->TDES_MR = AT91C_TDES_SMOD_MANUAL // Manual Mode.
+ | AT91C_TDES_OPMOD_ECB // ECB Electronic CodeBook mode
+ // Need to write TDES_KEY3WxR registers.
+ | AT91C_TDES_TDESMOD; // Triple DES processing using TDES_KEY1WxR, TDES_KEY2WxR and TDES_KEY3WxR registers.
+#else
+#error TDES_ENCRYPTION_KEY_LENGTH
+#endif
+
+ // Convert and load key
+ ASCII2Hex((unsigned char*)TDES_ENCRYPTION_KEY, key, TDES_ENCRYPTION_KEY_LENGTH);
+
+ AT91C_BASE_TDES->TDES_KEY1WxR[0] = ((int *) key)[0];
+ AT91C_BASE_TDES->TDES_KEY1WxR[1] = ((int *) key)[1];
+ AT91C_BASE_TDES->TDES_KEY2WxR[0] = ((int *) key)[2];
+ AT91C_BASE_TDES->TDES_KEY2WxR[1] = ((int *) key)[3];
+
+#if (TDES_ENCRYPTION_KEY_LENGTH == 24)
+ AT91C_BASE_TDES->TDES_KEY3WxR[0] = ((int *) key)[4];
+ AT91C_BASE_TDES->TDES_KEY3WxR[1] = ((int *) key)[5];
+#endif
+}
+#endif
+
+//------------------------------------------------------------------------------
+/// Cleans up the DES peripheral
+//------------------------------------------------------------------------------
+void tdes_hard_cleanup(void)
+{
+ TRACE_DEBUG("TDES/HARD: Cleaning up ...\n\r");
+ AT91C_BASE_TDES->TDES_MR = 0;
+#ifdef AT91C_ID_AES
+ PMC_DisablePeripheral( AT91C_ID_AES );
+#elif AT91C_ID_AESTDES
+ PMC_DisablePeripheral( AT91C_ID_AESTDES );
+#elif AT91C_ID_TDES
+ PMC_DisablePeripheral( AT91C_ID_TDES );
+#else
+#error AES undefined
+#endif
+ TRACE_DEBUG("TDES/HARD: Cleanup done.\n\r");
+}
+
+//------------------------------------------------------------------------------
+/// Decrypts a variable-length cipher text
+/// \param Cipher text to decrypt
+/// \param Buffer to store plain text
+/// \param Length of cipher text (in bytes)
+//------------------------------------------------------------------------------
+#ifdef ONLY_ONE_ENCRYPTION
+int tdes_hard_decrypt(const unsigned char * cipherText,
+ unsigned char * plainText,
+ unsigned int length)
+{
+ unsigned int l;
+
+ TRACE_DEBUG("tdes_hard_decrypt\n\r");
+
+#if defined(ENCRYPTION_ECB) || defined(ENCRYPTION_CBC)
+ for (l=0; l < length;) {
+
+ // Load counter and encrypt it
+ AT91C_BASE_TDES->TDES_IDATAxR[0] = ((int *) &cipherText[l])[0];
+ AT91C_BASE_TDES->TDES_IDATAxR[1] = ((int *) &cipherText[l])[1];
+
+ // Start processing
+ AT91C_BASE_TDES->TDES_CR = AT91C_TDES_START;
+
+ while (!((AT91C_BASE_TDES->TDES_ISR) & AT91C_TDES_DATRDY));
+
+ ((int *) &plainText[l])[0] = AT91C_BASE_TDES->TDES_ODATAxR[0];
+ ((int *) &plainText[l])[1] = AT91C_BASE_TDES->TDES_ODATAxR[1];
+
+ l += ENCRYPTION_BLOCK_LENGTH;
+ }
+
+#elif defined(ENCRYPTION_CTR)
+ unsigned int bytes;
+ unsigned char block[ENCRYPTION_BLOCK_LENGTH];
+ unsigned int e;
+ unsigned int i;
+ int k;
+
+ // Decrypt
+ for (e=0; e < length;) {
+
+ // Load counter and encrypt it
+ AT91C_BASE_TDES->TDES_IDATAxR[0] = ((int *) CTR)[0];
+ AT91C_BASE_TDES->TDES_IDATAxR[1] = ((int *) CTR)[1];
+
+ AT91C_BASE_TDES->TDES_CR = AT91C_TDES_START;
+ while (!(AT91C_BASE_TDES->TDES_ISR & AT91C_TDES_DATRDY));
+
+ ((int *) block)[0] = AT91C_BASE_TDES->TDES_ODATAxR[0];
+ ((int *) block)[1] = AT91C_BASE_TDES->TDES_ODATAxR[1];
+
+ // XOR current plain text block with encrypted counter
+ if ((length-e) < ENCRYPTION_BLOCK_LENGTH) {
+ bytes = length - e;
+ }
+ else {
+ bytes = ENCRYPTION_BLOCK_LENGTH;
+ }
+
+ for (i=0; i < bytes; i++) {
+ plainText[e+i] = cipherText[e+i] ^ ((char *) block)[i];
+ }
+
+ // Increment counter (big-endian) and number of encrypted bytes
+ for (k=ENCRYPTION_BLOCK_LENGTH-1; k >= 0; k--) {
+ if (++((char *) CTR)[k] != 0) {
+ break;
+ }
+ }
+ e += bytes;
+ }
+#endif // ENCRYPTION_CTR
+
+ return 1;
+}
+#endif
+
+//------------------------------------------------------------------------------
+/// Decrypts a variable-length cipher text for CBC mode
+/// \param Cipher text to decrypt
+/// \param Buffer to store plain text
+/// \param Length of cipher text (in bytes)
+//------------------------------------------------------------------------------
+#ifndef ONLY_ONE_ENCRYPTION
+int tdes_hard_decrypt_CBC(const unsigned char * cipherText,
+ unsigned char * plainText,
+ unsigned int length)
+{
+ unsigned int l;
+
+ TRACE_DEBUG("tdes_hard_decrypt_CBC\n\r");
+
+ for (l=0; l < length;) {
+ // Load counter and encrypt it
+ AT91C_BASE_TDES->TDES_IDATAxR[0] = ((int *) &cipherText[l])[0];
+ AT91C_BASE_TDES->TDES_IDATAxR[1] = ((int *) &cipherText[l])[1];
+
+ // Start processing
+ AT91C_BASE_TDES->TDES_CR = AT91C_TDES_START;
+
+ while (!((AT91C_BASE_TDES->TDES_ISR) & AT91C_TDES_DATRDY));
+
+ ((int *) &plainText[l])[0] = AT91C_BASE_TDES->TDES_ODATAxR[0];
+ ((int *) &plainText[l])[1] = AT91C_BASE_TDES->TDES_ODATAxR[1];
+
+ l += ENCRYPTION_BLOCK_LENGTH;
+ }
+ return 1;
+}
+#endif
+
+//------------------------------------------------------------------------------
+/// Decrypts a variable-length cipher text for ECB mode
+/// \param Cipher text to decrypt
+/// \param Buffer to store plain text
+/// \param Length of cipher text (in bytes)
+//------------------------------------------------------------------------------
+#ifndef ONLY_ONE_ENCRYPTION
+int tdes_hard_decrypt_ECB(const unsigned char * cipherText,
+ unsigned char * plainText,
+ unsigned int length)
+{
+ unsigned int l;
+
+ TRACE_DEBUG("tdes_hard_decrypt_ECB\n\r");
+
+ for (l=0; l < length;) {
+
+ // Load counter and encrypt it
+ AT91C_BASE_TDES->TDES_IDATAxR[0] = ((int *) &cipherText[l])[0];
+ AT91C_BASE_TDES->TDES_IDATAxR[1] = ((int *) &cipherText[l])[1];
+
+ // Start processing
+ AT91C_BASE_TDES->TDES_CR = AT91C_TDES_START;
+
+ while (!((AT91C_BASE_TDES->TDES_ISR) & AT91C_TDES_DATRDY));
+
+ ((int *) &plainText[l])[0] = AT91C_BASE_TDES->TDES_ODATAxR[0];
+ ((int *) &plainText[l])[1] = AT91C_BASE_TDES->TDES_ODATAxR[1];
+
+ l += ENCRYPTION_BLOCK_LENGTH;
+ }
+ return 1;
+}
+#endif
+
+#endif // defined(USE_ENCRYPTION) && defined(ENCRYPTION_3DES_HARD)
+
+
+
diff --git a/utility/encryption/tdes_hardware.h b/utility/encryption/tdes_hardware.h
new file mode 100644
index 0000000..d5d2629
--- /dev/null
+++ b/utility/encryption/tdes_hardware.h
@@ -0,0 +1,115 @@
+/* ----------------------------------------------------------------------------
+ * 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
+///
+/// Firmware encryption using TDES hardware acceleration
+///
+/// !Usage
+///
+/// -# tdes_hard_init: Initialize TDES hardware
+/// -# tdes_hard_init_CBC: for the CBC mode
+/// -# tdes_hard_init_ECB: for the ECB mode
+/// -# tdes_hard_cleanup: Cleans up DES
+/// -# tdes_hard_decrypt: Decrypts a variable-length cipher text
+/// -# tdes_hard_decrypt_CBC: for CBC mode
+/// -# tdes_hard_decrypt_ECB: for ECB mode
+//------------------------------------------------------------------------------
+#ifndef BOOTLOADER_TDES_HARDWARE_H
+#define BOOTLOADER_TDES_HARDWARE_H
+
+//------------------------------------------------------------------------------
+// Includes
+//------------------------------------------------------------------------------
+
+#include "config.h"
+
+#if defined(USE_ENCRYPTION) && defined(ENCRYPTION_3DES_HARD)
+
+//------------------------------------------------------------------------------
+// Check configuration
+//------------------------------------------------------------------------------
+
+#ifdef ONLY_ONE_ENCRYPTION
+#if (ENCRYPTION_KEY_LENGTH != 16) && (ENCRYPTION_KEY_LENGTH != 24)
+ #error Triple-DES hardware acceleration only supports 128 and 192 bits keys.
+#endif
+
+#if (ENCRYPTION_BLOCK_LENGTH != 8)
+ #error Triple-DES hardware acceleration only supports 64 bits blocks.
+#endif
+
+#if !defined(ENCRYPTION_ECB) && \
+ !defined(ENCRYPTION_CBC)
+ #error Only ECB, CBC mode are supported.
+#endif
+
+//------------------------------------------------------------------------------
+// Definitions
+//------------------------------------------------------------------------------
+#define ENCRYPTION_INIT tdes_hard_init
+#define ENCRYPTION_CLEANUP tdes_hard_cleanup
+#define ENCRYPTION_DECRYPT tdes_hard_decrypt
+
+#if defined(ENCRYPTION_ECB)
+ #define TDES_MODE AT91C_TDES_OPMOD_ECB
+ #define TDES_CIPHER 0
+#elif defined(ENCRYPTION_CBC)
+ #define TDES_MODE AT91C_TDES_OPMOD_CBC
+ #define TDES_CIPHER 0
+#endif
+
+#endif // ONLY_ONE_ENCRYPTION
+
+//------------------------------------------------------------------------------
+// Exported functions
+//------------------------------------------------------------------------------
+#ifdef ONLY_ONE_ENCRYPTION
+extern void tdes_hard_init(void);
+#endif
+extern void tdes_hard_init_CBC(void);
+extern void tdes_hard_init_ECB(void);
+extern void tdes_hard_cleanup(void);
+extern int tdes_hard_decrypt(const unsigned char * cipherText,
+ unsigned char * plainText,
+ unsigned int length);
+extern int tdes_hard_decrypt_CBC(const unsigned char * cipherText,
+ unsigned char * plainText,
+ unsigned int length);
+extern int tdes_hard_decrypt_ECB(const unsigned char * cipherText,
+ unsigned char * plainText,
+ unsigned int length);
+
+
+#endif // defined(USE_ENCRYPTION) && defined(ENCRYPTION_3DES_HARD)
+#endif // BOOTLOADER_DES_HARDWARE_H
+
diff --git a/utility/hamming.c b/utility/hamming.c
new file mode 100644
index 0000000..b3c3220
--- /dev/null
+++ b/utility/hamming.c
@@ -0,0 +1,335 @@
+/* ----------------------------------------------------------------------------
+ * 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 "hamming.h"
+#include <utility/trace.h>
+#include <utility/assert.h>
+
+//------------------------------------------------------------------------------
+// Internal function
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// Counts and return the number of bits set to '1' in the given byte.
+/// \param byte Byte to count.
+//------------------------------------------------------------------------------
+static unsigned char CountBitsInByte(unsigned char byte)
+{
+ unsigned char count = 0;
+ while (byte > 0) {
+
+ if (byte & 1) {
+
+ count++;
+ }
+ byte >>= 1;
+ }
+
+ return count;
+}
+
+//------------------------------------------------------------------------------
+/// Counts and return the number of bits set to '1' in the given hamming code.
+/// \param code Hamming code.
+//------------------------------------------------------------------------------
+static unsigned char CountBitsInCode256(unsigned char *code)
+{
+ return CountBitsInByte(code[0])
+ + CountBitsInByte(code[1])
+ + CountBitsInByte(code[2]);
+}
+
+//------------------------------------------------------------------------------
+/// Calculates the 22-bit hamming code for a 256-bytes block of data.
+/// \param data Data buffer to calculate code for.
+/// \param code Pointer to a buffer where the code should be stored.
+//------------------------------------------------------------------------------
+static void Compute256(const unsigned char *data, unsigned char *code)
+{
+ unsigned int i;
+ unsigned char columnSum = 0;
+ unsigned char evenLineCode = 0;
+ unsigned char oddLineCode = 0;
+ unsigned char evenColumnCode = 0;
+ unsigned char oddColumnCode = 0;
+
+ // Xor all bytes together to get the column sum;
+ // At the same time, calculate the even and odd line codes
+ for (i=0; i < 256; i++) {
+
+ columnSum ^= data[i];
+
+ // If the xor sum of the byte is 0, then this byte has no incidence on
+ // the computed code; so check if the sum is 1.
+ if ((CountBitsInByte(data[i]) & 1) == 1) {
+
+ // Parity groups are formed by forcing a particular index bit to 0
+ // (even) or 1 (odd).
+ // Example on one byte:
+ //
+ // bits (dec) 7 6 5 4 3 2 1 0
+ // (bin) 111 110 101 100 011 010 001 000
+ // '---'---'---'----------.
+ // |
+ // groups P4' ooooooooooooooo eeeeeeeeeeeeeee P4 |
+ // P2' ooooooo eeeeeee ooooooo eeeeeee P2 |
+ // P1' ooo eee ooo eee ooo eee ooo eee P1 |
+ // |
+ // We can see that: |
+ // - P4 -> bit 2 of index is 0 --------------------'
+ // - P4' -> bit 2 of index is 1.
+ // - P2 -> bit 1 of index if 0.
+ // - etc...
+ // We deduce that a bit position has an impact on all even Px if
+ // the log2(x)nth bit of its index is 0
+ // ex: log2(4) = 2, bit2 of the index must be 0 (-> 0 1 2 3)
+ // and on all odd Px' if the log2(x)nth bit of its index is 1
+ // ex: log2(2) = 1, bit1 of the index must be 1 (-> 0 1 4 5)
+ //
+ // As such, we calculate all the possible Px and Px' values at the
+ // same time in two variables, evenLineCode and oddLineCode, such as
+ // evenLineCode bits: P128 P64 P32 P16 P8 P4 P2 P1
+ // oddLineCode bits: P128' P64' P32' P16' P8' P4' P2' P1'
+ //
+ evenLineCode ^= (255 - i);
+ oddLineCode ^= i;
+ }
+ }
+
+ // At this point, we have the line parities, and the column sum. First, We
+ // must caculate the parity group values on the column sum.
+ for (i=0; i < 8; i++) {
+
+ if (columnSum & 1) {
+
+ evenColumnCode ^= (7 - i);
+ oddColumnCode ^= i;
+ }
+ columnSum >>= 1;
+ }
+
+ // Now, we must interleave the parity values, to obtain the following layout:
+ // Code[0] = Line1
+ // Code[1] = Line2
+ // Code[2] = Column
+ // Line = Px' Px P(x-1)- P(x-1) ...
+ // Column = P4' P4 P2' P2 P1' P1 PadBit PadBit
+ code[0] = 0;
+ code[1] = 0;
+ code[2] = 0;
+
+ for (i=0; i < 4; i++) {
+
+ code[0] <<= 2;
+ code[1] <<= 2;
+ code[2] <<= 2;
+
+ // Line 1
+ if ((oddLineCode & 0x80) != 0) {
+
+ code[0] |= 2;
+ }
+ if ((evenLineCode & 0x80) != 0) {
+
+ code[0] |= 1;
+ }
+
+ // Line 2
+ if ((oddLineCode & 0x08) != 0) {
+
+ code[1] |= 2;
+ }
+ if ((evenLineCode & 0x08) != 0) {
+
+ code[1] |= 1;
+ }
+
+ // Column
+ if ((oddColumnCode & 0x04) != 0) {
+
+ code[2] |= 2;
+ }
+ if ((evenColumnCode & 0x04) != 0) {
+
+ code[2] |= 1;
+ }
+
+ oddLineCode <<= 1;
+ evenLineCode <<= 1;
+ oddColumnCode <<= 1;
+ evenColumnCode <<= 1;
+ }
+
+ // Invert codes (linux compatibility)
+ code[0] = ~code[0];
+ code[1] = ~code[1];
+ code[2] = ~code[2];
+
+ TRACE_DEBUG("Computed code = %02X %02X %02X\n\r",
+ code[0], code[1], code[2]);
+}
+
+//------------------------------------------------------------------------------
+/// Verifies and corrects a 256-bytes block of data using the given 22-bits
+/// hamming code.
+/// Returns 0 if there is no error, otherwise returns a HAMMING_ERROR code.
+/// \param data Data buffer to check.
+/// \param originalCode Hamming code to use for verifying the data.
+//------------------------------------------------------------------------------
+static unsigned char Verify256(
+ unsigned char *data,
+ const unsigned char *originalCode)
+{
+ // Calculate new code
+ unsigned char computedCode[3];
+ unsigned char correctionCode[3];
+ Compute256(data, computedCode);
+
+ // Xor both codes together
+ correctionCode[0] = computedCode[0] ^ originalCode[0];
+ correctionCode[1] = computedCode[1] ^ originalCode[1];
+ correctionCode[2] = computedCode[2] ^ originalCode[2];
+
+ TRACE_DEBUG("Correction code = %02X %02X %02X\n\r",
+ correctionCode[0], correctionCode[1], correctionCode[2]);
+
+ // If all bytes are 0, there is no error
+ if ((correctionCode[0] == 0)
+ && (correctionCode[1] == 0)
+ && (correctionCode[2] == 0)) {
+
+ return 0;
+ }
+ // If there is a single bit error, there are 11 bits set to 1
+ if (CountBitsInCode256(correctionCode) == 11) {
+
+ // Get byte and bit indexes
+ unsigned char byte = correctionCode[0] & 0x80;
+ byte |= (correctionCode[0] << 1) & 0x40;
+ byte |= (correctionCode[0] << 2) & 0x20;
+ byte |= (correctionCode[0] << 3) & 0x10;
+
+ byte |= (correctionCode[1] >> 4) & 0x08;
+ byte |= (correctionCode[1] >> 3) & 0x04;
+ byte |= (correctionCode[1] >> 2) & 0x02;
+ byte |= (correctionCode[1] >> 1) & 0x01;
+
+ unsigned char bit = (correctionCode[2] >> 5) & 0x04;
+ bit |= (correctionCode[2] >> 4) & 0x02;
+ bit |= (correctionCode[2] >> 3) & 0x01;
+
+ // Correct bit
+ TRACE_DEBUG("Correcting byte #%d at bit %d\n\r", byte, bit);
+ data[byte] ^= (1 << bit);
+
+ return Hamming_ERROR_SINGLEBIT;
+ }
+ // Check if ECC has been corrupted
+ if (CountBitsInCode256(correctionCode) == 1) {
+
+ return Hamming_ERROR_ECC;
+ }
+ // Otherwise, this is a multi-bit error
+ else {
+
+ return Hamming_ERROR_MULTIPLEBITS;
+ }
+}
+
+//------------------------------------------------------------------------------
+// Exported functions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// Computes 3-bytes hamming codes for a data block whose size is multiple of
+/// 256 bytes. Each 256 bytes block gets its own code.
+/// \param data Data to compute code for.
+/// \param size Data size in bytes.
+/// \param code Codes buffer.
+//------------------------------------------------------------------------------
+void Hamming_Compute256x(
+ const unsigned char *data,
+ unsigned int size,
+ unsigned char *code)
+{
+ TRACE_DEBUG("Hamming_Compute256x()\n\r");
+
+ while (size > 0) {
+
+ Compute256(data, code);
+ data += 256;
+ code += 3;
+ size -= 256;
+ }
+}
+
+//------------------------------------------------------------------------------
+/// Verifies 3-bytes hamming codes for a data block whose size is multiple of
+/// 256 bytes. Each 256-bytes block is verified with its own code.
+/// Returns 0 if the data is correct, Hamming_ERROR_SINGLEBIT if one or more
+/// block(s) have had a single bit corrected, or either Hamming_ERROR_ECC
+/// or Hamming_ERROR_MULTIPLEBITS.
+/// \param data Data buffer to verify.
+/// \param size Size of the data in bytes.
+/// \param code Original codes.
+//------------------------------------------------------------------------------
+unsigned char Hamming_Verify256x(
+ unsigned char *data,
+ unsigned int size,
+ const unsigned char *code)
+{
+ unsigned char error;
+ unsigned char result = 0;
+
+ TRACE_DEBUG("Hamming_Verify256x()\n\r");
+
+ while (size > 0) {
+
+ error = Verify256(data, code);
+ if (error == Hamming_ERROR_SINGLEBIT) {
+
+ result = Hamming_ERROR_SINGLEBIT;
+ }
+ else if (error) {
+
+ return error;
+ }
+
+ data += 256;
+ code += 3;
+ size -= 256;
+ }
+
+ return result;
+}
+
diff --git a/utility/hamming.h b/utility/hamming.h
new file mode 100644
index 0000000..3d5c555
--- /dev/null
+++ b/utility/hamming.h
@@ -0,0 +1,72 @@
+/* ----------------------------------------------------------------------------
+ * 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 HAMMING_H
+#define HAMMING_H
+
+//------------------------------------------------------------------------------
+// Defines
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// \page "Hamming Code Errors"
+/// These are the possible errors when trying to verify a block of data encoded
+/// using a Hamming code:
+///
+/// !Errors:
+/// - Hamming_ERROR_SINGLEBIT
+/// - Hamming_ERROR_ECC
+/// - Hamming_ERROR_MULTIPLEBITS
+
+/// A single bit was incorrect but has been recovered.
+#define Hamming_ERROR_SINGLEBIT 1
+
+/// The original code has been corrupted.
+#define Hamming_ERROR_ECC 2
+
+/// Multiple bits are incorrect in the data and they cannot be corrected.
+#define Hamming_ERROR_MULTIPLEBITS 3
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+// Exported functions
+//------------------------------------------------------------------------------
+
+extern void Hamming_Compute256x(
+ const unsigned char *data,
+ unsigned int size,
+ unsigned char *code);
+
+extern unsigned char Hamming_Verify256x(
+ unsigned char *data,
+ unsigned int size,
+ const unsigned char *code);
+
+#endif //#ifndef HAMMING_H
+
diff --git a/utility/iap.c b/utility/iap.c
new file mode 100644
index 0000000..a17ae9e
--- /dev/null
+++ b/utility/iap.c
@@ -0,0 +1,98 @@
+/* ----------------------------------------------------------------------------
+ * 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.
+ * ----------------------------------------------------------------------------
+ */
+
+/*
+ Title: IAP implementation
+
+ About: Purpose
+ IAP feature is avalaible on ATMEL chip with internal FLASH. This allows
+ the FLASH memory to be programmed even when the code is also running in
+ FLASH, without writing some SRAM relocated functions.
+ The IAP function entry point is written in the 3rd exception vector
+ (SWI at 0x300008), and is retrieved just by reading the value at this
+ address.
+
+ ROM function algorithm :
+ // Send Command
+ AT91_BASE_MC->MC_FCR = FlashCmd
+ // Wait Flash is ready
+ while ((AT91C_BASE_MC->MC_FSR & AT91C_MC_FRDY) != AT91C_MC_FRDY)
+ return
+*/
+
+//------------------------------------------------------------------------------
+// Headers
+//------------------------------------------------------------------------------
+
+#include "iap.h"
+#include <board.h>
+#include <utility/trace.h>
+
+//------------------------------------------------------------------------------
+// Internal variables
+//------------------------------------------------------------------------------
+
+
+
+//------------------------------------------------------------------------------
+// Exported functions
+//------------------------------------------------------------------------------
+/*
+ Function: IAP_PerformCmd
+ Perform a FLASH command through the IAP function.
+
+ Returns:
+ 0 if the IAP function has executed correctly.
+ -1 if the IAP feature is not implemented in the ROM code.
+*/
+unsigned long IAP_PerformCmd(unsigned long FlashCmd)
+{
+ // Pointer on IAP function in ROM
+ static void (*IAP_Function)(unsigned int) = 0;
+
+ if (IAP_Function == 0) {
+
+ IAP_Function = (void (*)(unsigned int)) (*((unsigned int *) IAP_FUNC_ADDR));
+ TRACE_DEBUG("IAP_PerformCmd : IAP function address in ROM : 0x%08X\n\r", (unsigned int) IAP_Function);
+
+ /* Check if IAP function is implemented (opcode in SWI != 'b' or 'ldr') */
+ if ((((((unsigned long)IAP_Function >> 24) & 0xFF) == 0xEA) ||
+ (((unsigned long)IAP_Function >> 24) & 0xFF) == 0xE5)) {
+ TRACE_ERROR("IAP_PerformCmd : no IAP function address found in ROM\n\r");
+ IAP_Function = 0;
+ return -1;
+ }
+ }
+
+ /* Perform FLASH command */
+ IAP_Function(FlashCmd);
+
+ return 0;
+}
+
diff --git a/utility/iap.h b/utility/iap.h
new file mode 100644
index 0000000..bffd487
--- /dev/null
+++ b/utility/iap.h
@@ -0,0 +1,51 @@
+/* ----------------------------------------------------------------------------
+ * 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.
+ * ----------------------------------------------------------------------------
+ */
+
+/*
+ Title: IAP
+
+ About: Purpose
+ Small function for using IAP feature.
+
+ About: Usage
+ Perform a FLASH command using <IAP_PerformCmd>.
+
+*/
+
+#ifndef IAP_H
+#define IAP_H
+
+//------------------------------------------------------------------------------
+// Exported functions
+//------------------------------------------------------------------------------
+
+extern unsigned long IAP_PerformCmd (unsigned long FlashCmd);
+
+#endif //#ifndef IAP_H
+
diff --git a/utility/led.c b/utility/led.c
new file mode 100644
index 0000000..7048b2a
--- /dev/null
+++ b/utility/led.c
@@ -0,0 +1,162 @@
+/* ----------------------------------------------------------------------------
+ * 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 "led.h"
+#include <board.h>
+#include <pio/pio.h>
+
+//------------------------------------------------------------------------------
+// Local Variables
+//------------------------------------------------------------------------------
+
+#ifdef PINS_LEDS
+static const Pin pinsLeds[] = {PINS_LEDS};
+static const unsigned int numLeds = PIO_LISTSIZE(pinsLeds);
+#endif
+
+//------------------------------------------------------------------------------
+// Global Functions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// Configures the pin associated with the given LED number. If the LED does
+/// not exist on the board, the function does nothing.
+/// \param led Number of the LED to configure.
+/// \return 1 if the LED exists and has been configured; otherwise 0.
+//------------------------------------------------------------------------------
+unsigned char LED_Configure(unsigned int led)
+{
+#ifdef PINS_LEDS
+ // Check that LED exists
+ if (led >= numLeds) {
+
+ return 0;
+ }
+
+ // Configure LED
+ return (PIO_Configure(&pinsLeds[led], 1));
+#else
+ return 0;
+#endif
+}
+
+//------------------------------------------------------------------------------
+/// Turns the given LED on if it exists; otherwise does nothing.
+/// \param led Number of the LED to turn on.
+/// \return 1 if the LED has been turned on; 0 otherwise.
+//------------------------------------------------------------------------------
+unsigned char LED_Set(unsigned int led)
+{
+#ifdef PINS_LEDS
+ // Check if LED exists
+ if (led >= numLeds) {
+
+ return 0;
+ }
+
+ // Turn LED on
+ if (pinsLeds[led].type == PIO_OUTPUT_0) {
+
+ PIO_Set(&pinsLeds[led]);
+ }
+ else {
+
+ PIO_Clear(&pinsLeds[led]);
+ }
+
+ return 1;
+#else
+ return 0;
+#endif
+}
+
+//------------------------------------------------------------------------------
+/// Turns a LED off.
+/// \param led Number of the LED to turn off.
+/// \param 1 if the LED has been turned off; 0 otherwise.
+//------------------------------------------------------------------------------
+unsigned char LED_Clear(unsigned int led)
+{
+#ifdef PINS_LEDS
+ // Check if LED exists
+ if (led >= numLeds) {
+
+ return 0;
+ }
+
+ // Turn LED off
+ if (pinsLeds[led].type == PIO_OUTPUT_0) {
+
+ PIO_Clear(&pinsLeds[led]);
+ }
+ else {
+
+ PIO_Set(&pinsLeds[led]);
+ }
+
+ return 1;
+#else
+ return 0;
+#endif
+}
+
+//------------------------------------------------------------------------------
+/// Toggles the current state of a LED.
+/// \param led Number of the LED to toggle.
+/// \return 1 if the LED has been toggled; otherwise 0.
+//------------------------------------------------------------------------------
+unsigned char LED_Toggle(unsigned int led)
+{
+#ifdef PINS_LEDS
+ // Check if LED exists
+ if (led >= numLeds) {
+
+ return 0;
+ }
+
+ // Toggle LED
+ if (PIO_GetOutputDataStatus(&pinsLeds[led])) {
+
+ PIO_Clear(&pinsLeds[led]);
+ }
+ else {
+
+ PIO_Set(&pinsLeds[led]);
+ }
+
+ return 1;
+#else
+ return 0;
+#endif
+}
+
diff --git a/utility/led.h b/utility/led.h
new file mode 100644
index 0000000..3f4878f
--- /dev/null
+++ b/utility/led.h
@@ -0,0 +1,70 @@
+/* ----------------------------------------------------------------------------
+ * 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
+///
+/// Small set of functions for simple and portable LED usage.
+///
+/// !Usage
+///
+/// -# Configure one or more LEDs using LED_Configure and
+/// LED_ConfigureAll.
+/// -# Set, clear and toggle LEDs using LED_Set, LED_Clear and
+/// LED_Toggle.
+///
+/// LEDs are numbered starting from 0; the number of LEDs depend on the
+/// board being used. All the functions defined here will compile properly
+/// regardless of whether the LED is defined or not; they will simply
+/// return 0 when a LED which does not exist is given as an argument.
+/// Also, these functions take into account how each LED is connected on to
+/// board; thus, <LED_Set> might change the level on the corresponding pin
+/// to 0 or 1, but it will always light the LED on; same thing for the other
+/// methods.
+//------------------------------------------------------------------------------
+
+#ifndef LED_H
+#define LED_H
+
+//------------------------------------------------------------------------------
+// Global Functions
+//------------------------------------------------------------------------------
+
+extern unsigned char LED_Configure(unsigned int led);
+
+extern unsigned char LED_Set(unsigned int led);
+
+extern unsigned char LED_Clear(unsigned int led);
+
+extern unsigned char LED_Toggle(unsigned int led);
+
+#endif //#ifndef LED_H
+
diff --git a/utility/math.c b/utility/math.c
new file mode 100644
index 0000000..6012385
--- /dev/null
+++ b/utility/math.c
@@ -0,0 +1,91 @@
+/* ----------------------------------------------------------------------------
+ * 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 "math.h"
+#include "trace.h"
+
+//------------------------------------------------------------------------------
+// Exported functions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// Returns the minimum value between two integers.
+/// \param a First integer to compare.
+/// \param b Second integer to compare.
+//------------------------------------------------------------------------------
+unsigned int min(unsigned int a, unsigned int b)
+{
+ if (a < b) {
+
+ return a;
+ }
+ else {
+
+ return b;
+ }
+}
+
+//------------------------------------------------------------------------------
+/// Returns the absolute value of an integer.
+/// \param value Integer value.
+//------------------------------------------------------------------------------
+// Do not call this function "abs", problem with gcc !
+unsigned int absv(signed int value)
+{
+ if (value < 0) {
+
+ return -value;
+ }
+ else {
+
+ return value;
+ }
+}
+
+//------------------------------------------------------------------------------
+/// Computes and returns x power of y.
+/// \param x Value.
+/// \param y Power.
+//------------------------------------------------------------------------------
+unsigned int power(unsigned int x, unsigned int y)
+{
+ unsigned int result = 1;
+
+ while (y > 0) {
+
+ result *= x;
+ y--;
+ }
+ return result;
+}
+
diff --git a/utility/math.h b/utility/math.h
new file mode 100644
index 0000000..7e1c486
--- /dev/null
+++ b/utility/math.h
@@ -0,0 +1,41 @@
+/* ----------------------------------------------------------------------------
+ * 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 MATH_H
+#define MATH_H
+
+//------------------------------------------------------------------------------
+// Exported functions
+//------------------------------------------------------------------------------
+
+extern unsigned int min(unsigned int a, unsigned int b);
+extern unsigned int absv(signed int value);
+extern unsigned int power(unsigned int x, unsigned int y);
+#endif //#ifndef MATH_H
+
diff --git a/utility/rand.c b/utility/rand.c
new file mode 100644
index 0000000..a73e8d9
--- /dev/null
+++ b/utility/rand.c
@@ -0,0 +1,58 @@
+/* ----------------------------------------------------------------------------
+ * 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.
+ * ----------------------------------------------------------------------------
+ */
+
+//------------------------------------------------------------------------------
+// Global Functions
+//------------------------------------------------------------------------------
+
+static unsigned long int next = 1;
+
+//------------------------------------------------------------------------------
+// Global Functions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// Initialize the seed for rand generator.
+/// \param seed rand initiation seed
+//------------------------------------------------------------------------------
+void srand(unsigned int seed)
+{
+ next = seed;
+}
+
+//------------------------------------------------------------------------------
+/// Return a random number, maxinum assumed to be 65536
+//------------------------------------------------------------------------------
+
+int rand(void)
+{
+ next = next * 1103515245 + 12345;
+ return (unsigned int)(next/131072) % 65536;
+}
+
diff --git a/utility/rand.h b/utility/rand.h
new file mode 100644
index 0000000..072181b
--- /dev/null
+++ b/utility/rand.h
@@ -0,0 +1,49 @@
+/* ----------------------------------------------------------------------------
+ * 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
+///
+/// Small function for gererating random number.
+///
+//------------------------------------------------------------------------------
+
+#ifndef RAND_H
+#define RAND_H
+
+//------------------------------------------------------------------------------
+// Global Functions
+//------------------------------------------------------------------------------
+
+extern void srand(unsigned int seed);
+extern int rand(void);
+
+#endif //#ifndef RAND_H
diff --git a/utility/retarget.c b/utility/retarget.c
new file mode 100644
index 0000000..8f81ba6
--- /dev/null
+++ b/utility/retarget.c
@@ -0,0 +1,88 @@
+/* ----------------------------------------------------------------------------
+ * 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 file Configures the target-dependent low level functions for character I/O.
+///
+/// !Contents
+/// The code implement the lower-level functions as follows:
+/// - fputc
+/// - ferror
+/// - _ttywrch
+/// - _sys_exit
+///
+///
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+// Headers
+//------------------------------------------------------------------------------
+#include <dbgu/dbgu.h>
+#include <stdio.h>
+
+// Disable semihosting
+#pragma import(__use_no_semihosting_swi)
+
+struct __FILE { int handle;} ;
+FILE __stdout;
+FILE __stderr;
+
+//------------------------------------------------------------------------------
+/// Outputs a character to a file.
+//------------------------------------------------------------------------------
+int fputc(int ch, FILE *f) {
+ if ((f == stdout) || (f == stderr)) {
+ DBGU_PutChar(ch);
+ return ch;
+ }
+ else {
+ return EOF;
+ }
+}
+
+//------------------------------------------------------------------------------
+/// Returns the error status accumulated during file I/O.
+//------------------------------------------------------------------------------
+int ferror(FILE *f) {
+ return EOF;
+}
+
+
+void _ttywrch(int ch) {
+ DBGU_PutChar((unsigned char)ch);
+}
+
+
+void _sys_exit(int return_code) {
+ label: goto label; /* endless loop */
+}
diff --git a/utility/stdio.c b/utility/stdio.c
new file mode 100644
index 0000000..3e76ddc
--- /dev/null
+++ b/utility/stdio.c
@@ -0,0 +1,512 @@
+/* ----------------------------------------------------------------------------
+ * 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 several stdio.h methods, such as printf(), sprintf() and
+/// so on. This reduces the memory footprint of the binary when using those
+/// methods, compared to the libc implementation.
+///
+/// !Usage
+///
+/// Adds stdio.c to the list of file to compile for the project. This will
+/// automatically replace libc methods by the custom ones.
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+// Headers
+//------------------------------------------------------------------------------
+
+#include <stdio.h>
+#include <stdarg.h>
+
+//------------------------------------------------------------------------------
+// Local Definitions
+//------------------------------------------------------------------------------
+
+// Maximum string size allowed (in bytes).
+#define MAX_STRING_SIZE 100
+
+//------------------------------------------------------------------------------
+// Global Variables
+//------------------------------------------------------------------------------
+
+// Required for proper compilation.
+struct _reent r = {0, (FILE *) 0, (FILE *) 1, (FILE *) 0};
+struct _reent *_impure_ptr = &r;
+
+//------------------------------------------------------------------------------
+// Local Functions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+// Writes a character inside the given string. Returns 1.
+// \param pStr Storage string.
+// \param c Character to write.
+//------------------------------------------------------------------------------
+signed int PutChar(char *pStr, char c)
+{
+ *pStr = c;
+ return 1;
+}
+
+//------------------------------------------------------------------------------
+// Writes a string inside the given string.
+// Returns the size of the written
+// string.
+// \param pStr Storage string.
+// \param pSource Source string.
+//------------------------------------------------------------------------------
+signed int PutString(char *pStr, const char *pSource)
+{
+ signed int num = 0;
+
+ while (*pSource != 0) {
+
+ *pStr++ = *pSource++;
+ num++;
+ }
+
+ return num;
+}
+
+//------------------------------------------------------------------------------
+// Writes an unsigned int inside the given string, using the provided fill &
+// width parameters.
+// Returns the size in characters of the written integer.
+// \param pStr Storage string.
+// \param fill Fill character.
+// \param width Minimum integer width.
+// \param value Integer value.
+//------------------------------------------------------------------------------
+signed int PutUnsignedInt(
+ char *pStr,
+ char fill,
+ signed int width,
+ unsigned int value)
+{
+ signed int num = 0;
+
+ // Take current digit into account when calculating width
+ width--;
+
+ // Recursively write upper digits
+ if ((value / 10) > 0) {
+
+ num = PutUnsignedInt(pStr, fill, width, value / 10);
+ pStr += num;
+ }
+ // Write filler characters
+ else {
+
+ while (width > 0) {
+
+ PutChar(pStr, fill);
+ pStr++;
+ num++;
+ width--;
+ }
+ }
+
+ // Write lower digit
+ num += PutChar(pStr, (value % 10) + '0');
+
+ return num;
+}
+
+//------------------------------------------------------------------------------
+// Writes a signed int inside the given string, using the provided fill & width
+// parameters.
+// Returns the size of the written integer.
+// \param pStr Storage string.
+// \param fill Fill character.
+// \param width Minimum integer width.
+// \param value Signed integer value.
+//------------------------------------------------------------------------------
+signed int PutSignedInt(
+ char *pStr,
+ char fill,
+ signed int width,
+ signed int value)
+{
+ signed int num = 0;
+ unsigned int absolute;
+
+ // Compute absolute value
+ if (value < 0) {
+
+ absolute = -value;
+ }
+ else {
+
+ absolute = value;
+ }
+
+ // Take current digit into account when calculating width
+ width--;
+
+ // Recursively write upper digits
+ if ((absolute / 10) > 0) {
+
+ if (value < 0) {
+
+ num = PutSignedInt(pStr, fill, width, -(absolute / 10));
+ }
+ else {
+
+ num = PutSignedInt(pStr, fill, width, absolute / 10);
+ }
+ pStr += num;
+ }
+ else {
+
+ // Reserve space for sign
+ if (value < 0) {
+
+ width--;
+ }
+
+ // Write filler characters
+ while (width > 0) {
+
+ PutChar(pStr, fill);
+ pStr++;
+ num++;
+ width--;
+ }
+
+ // Write sign
+ if (value < 0) {
+
+ num += PutChar(pStr, '-');
+ pStr++;
+ }
+ }
+
+ // Write lower digit
+ num += PutChar(pStr, (absolute % 10) + '0');
+
+ return num;
+}
+
+//------------------------------------------------------------------------------
+// Writes an hexadecimal value into a string, using the given fill, width &
+// capital parameters.
+// Returns the number of char written.
+// \param pStr Storage string.
+// \param fill Fill character.
+// \param width Minimum integer width.
+// \param maj Indicates if the letters must be printed in lower- or upper-case.
+// \param value Hexadecimal value.
+//------------------------------------------------------------------------------
+signed int PutHexa(
+ char *pStr,
+ char fill,
+ signed int width,
+ unsigned char maj,
+ unsigned int value)
+{
+ signed int num = 0;
+
+ // Decrement width
+ width--;
+
+ // Recursively output upper digits
+ if ((value >> 4) > 0) {
+
+ num += PutHexa(pStr, fill, width, maj, value >> 4);
+ pStr += num;
+ }
+ // Write filler chars
+ else {
+
+ while (width > 0) {
+
+ PutChar(pStr, fill);
+ pStr++;
+ num++;
+ width--;
+ }
+ }
+
+ // Write current digit
+ if ((value & 0xF) < 10) {
+
+ PutChar(pStr, (value & 0xF) + '0');
+ }
+ else if (maj) {
+
+ PutChar(pStr, (value & 0xF) - 10 + 'A');
+ }
+ else {
+
+ PutChar(pStr, (value & 0xF) - 10 + 'a');
+ }
+ num++;
+
+ return num;
+}
+
+//------------------------------------------------------------------------------
+// Global Functions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// Stores the result of a formatted string into another string. Format
+/// arguments are given in a va_list instance.
+/// Return the number of characters written.
+/// \param pStr Destination string.
+/// \param length Length of Destination string.
+/// \param pFormat Format string.
+/// \param ap Argument list.
+//------------------------------------------------------------------------------
+signed int vsnprintf(char *pStr, size_t length, const char *pFormat, va_list ap)
+{
+ char fill;
+ unsigned char width;
+ signed int num = 0;
+ signed int size = 0;
+
+ // Clear the string
+ if (pStr) {
+
+ *pStr = 0;
+ }
+
+ // Phase string
+ while (*pFormat != 0 && size < length) {
+
+ // Normal character
+ if (*pFormat != '%') {
+
+ *pStr++ = *pFormat++;
+ size++;
+ }
+ // Escaped '%'
+ else if (*(pFormat+1) == '%') {
+
+ *pStr++ = '%';
+ pFormat += 2;
+ size++;
+ }
+ // Token delimiter
+ else {
+
+ fill = ' ';
+ width = 0;
+ pFormat++;
+
+ // Parse filler
+ if (*pFormat == '0') {
+
+ fill = '0';
+ pFormat++;
+ }
+
+ // Parse width
+ while ((*pFormat >= '0') && (*pFormat <= '9')) {
+
+ width = (width*10) + *pFormat-'0';
+ pFormat++;
+ }
+
+ // Check if there is enough space
+ if (size + width > length) {
+
+ width = length - size;
+ }
+
+ // Parse type
+ switch (*pFormat) {
+ case 'd':
+ case 'i': num = PutSignedInt(pStr, fill, width, va_arg(ap, signed int)); break;
+ case 'u': num = PutUnsignedInt(pStr, fill, width, va_arg(ap, unsigned int)); break;
+ case 'x': num = PutHexa(pStr, fill, width, 0, va_arg(ap, unsigned int)); break;
+ case 'X': num = PutHexa(pStr, fill, width, 1, va_arg(ap, unsigned int)); break;
+ case 's': num = PutString(pStr, va_arg(ap, char *)); break;
+ case 'c': num = PutChar(pStr, va_arg(ap, unsigned int)); break;
+ default:
+ return EOF;
+ }
+
+ pFormat++;
+ pStr += num;
+ size += num;
+ }
+ }
+
+ // NULL-terminated (final \0 is not counted)
+ if (size < length) {
+
+ *pStr = 0;
+ }
+ else {
+
+ *(--pStr) = 0;
+ size--;
+ }
+
+ return size;
+}
+
+//------------------------------------------------------------------------------
+/// Stores the result of a formatted string into another string. Format
+/// arguments are given in a va_list instance.
+/// Return the number of characters written.
+/// \param pString Destination string.
+/// \param length Length of Destination string.
+/// \param pFormat Format string.
+/// \param ... Other arguments
+//------------------------------------------------------------------------------
+signed int snprintf(char *pString, size_t length, const char *pFormat, ...)
+{
+ va_list ap;
+ signed int rc;
+
+ va_start(ap, pFormat);
+ rc = vsnprintf(pString, length, pFormat, ap);
+ va_end(ap);
+
+ return rc;
+}
+
+//------------------------------------------------------------------------------
+/// Stores the result of a formatted string into another string. Format
+/// arguments are given in a va_list instance.
+/// Return the number of characters written.
+/// \param pString Destination string.
+/// \param pFormat Format string.
+/// \param ap Argument list.
+//------------------------------------------------------------------------------
+signed int vsprintf(char *pString, const char *pFormat, va_list ap)
+{
+ return vsnprintf(pString, MAX_STRING_SIZE, pFormat, ap);
+}
+
+//------------------------------------------------------------------------------
+/// Outputs a formatted string on the given stream. Format arguments are given
+/// in a va_list instance.
+/// \param pStream Output stream.
+/// \param pFormat Format string
+/// \param ap Argument list.
+//------------------------------------------------------------------------------
+signed int vfprintf(FILE *pStream, const char *pFormat, va_list ap)
+{
+ char pStr[MAX_STRING_SIZE];
+ char pError[] = "stdio.c: increase MAX_STRING_SIZE\n\r";
+
+ // Write formatted string in buffer
+ if (vsprintf(pStr, pFormat, ap) >= MAX_STRING_SIZE) {
+
+ fputs(pError, stderr);
+ while (1); // Increase MAX_STRING_SIZE
+ }
+
+ // Display string
+ return fputs(pStr, pStream);
+}
+
+//------------------------------------------------------------------------------
+/// Outputs a formatted string on the DBGU stream. Format arguments are given
+/// in a va_list instance.
+/// \param pFormat Format string
+/// \param ap Argument list.
+//------------------------------------------------------------------------------
+signed int vprintf(const char *pFormat, va_list ap)
+{
+ return vfprintf(stdout, pFormat, ap);
+}
+
+//------------------------------------------------------------------------------
+/// Outputs a formatted string on the given stream, using a variable number of
+/// arguments.
+/// \param pStream Output stream.
+/// \param pFormat Format string.
+//------------------------------------------------------------------------------
+signed int fprintf(FILE *pStream, const char *pFormat, ...)
+{
+ va_list ap;
+ signed int result;
+
+ // Forward call to vfprintf
+ va_start(ap, pFormat);
+ result = vfprintf(pStream, pFormat, ap);
+ va_end(ap);
+
+ return result;
+}
+
+//------------------------------------------------------------------------------
+/// Outputs a formatted string on the DBGU stream, using a variable number of
+/// arguments.
+/// \param pFormat Format string.
+//------------------------------------------------------------------------------
+signed int printf(const char *pFormat, ...)
+{
+ va_list ap;
+ signed int result;
+
+ // Forward call to vprintf
+ va_start(ap, pFormat);
+ result = vprintf(pFormat, ap);
+ va_end(ap);
+
+ return result;
+}
+
+//------------------------------------------------------------------------------
+/// Writes a formatted string inside another string.
+/// \param pStr Storage string.
+/// \param pFormat Format string.
+//------------------------------------------------------------------------------
+signed int sprintf(char *pStr, const char *pFormat, ...)
+{
+ va_list ap;
+ signed int result;
+
+ // Forward call to vsprintf
+ va_start(ap, pFormat);
+ result = vsprintf(pStr, pFormat, ap);
+ va_end(ap);
+
+ return result;
+}
+
+//------------------------------------------------------------------------------
+/// Outputs a string on stdout.
+/// \param pStr String to output.
+//------------------------------------------------------------------------------
+signed int puts(const char *pStr)
+{
+ return fputs(pStr, stdout);
+}
+
diff --git a/utility/string.c b/utility/string.c
new file mode 100644
index 0000000..6c2af0d
--- /dev/null
+++ b/utility/string.c
@@ -0,0 +1,239 @@
+/* ----------------------------------------------------------------------------
+ * 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 several methods defined in string.h, for reducing the
+/// memory footprint when using them (since the whole libc.o file gets included
+/// even when using a single method).
+///
+/// !Usage
+///
+/// Add string.c to the list of files to compile for the project. This will
+/// automatically replace standard libc methods by the custom ones.
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+// Headers
+//------------------------------------------------------------------------------
+
+#include <string.h>
+
+//------------------------------------------------------------------------------
+// Global Functions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// Copies data from a source buffer into a destination buffer. The two buffers
+/// must NOT overlap. Returns the destination buffer.
+/// \param pDestination Destination buffer.
+/// \param pSource Source buffer.
+/// \param num Number of bytes to copy.
+//------------------------------------------------------------------------------
+void * memcpy(void *pDestination, const void *pSource, size_t num)
+{
+ unsigned char *pByteDestination;
+ unsigned char *pByteSource;
+ unsigned int *pAlignedSource = (unsigned int *) pSource;
+ unsigned int *pAlignedDestination = (unsigned int *) pDestination;
+
+ // If num is more than 4 bytes, and both dest. and source are aligned,
+ // then copy dwords
+ if ((((unsigned int) pAlignedDestination & 0x3) == 0)
+ && (((unsigned int) pAlignedSource & 0x3) == 0)
+ && (num >= 4)) {
+
+ while (num >= 4) {
+
+ *pAlignedDestination++ = *pAlignedSource++;
+ num -= 4;
+ }
+ }
+
+ // Copy remaining bytes
+ pByteDestination = (unsigned char *) pAlignedDestination;
+ pByteSource = (unsigned char *) pAlignedSource;
+ while (num--) {
+
+ *pByteDestination++ = *pByteSource++;
+ }
+
+ return pDestination;
+}
+
+//------------------------------------------------------------------------------
+/// Fills a memory region with the given value. Returns a pointer to the
+/// memory region.
+/// \param pBuffer Pointer to the start of the memory region to fill
+/// \param value Value to fill the region with
+/// \param num Size to fill in bytes
+//------------------------------------------------------------------------------
+void * memset(void *pBuffer, int value, size_t num)
+{
+ unsigned char *pByteDestination;
+ unsigned int *pAlignedDestination = (unsigned int *) pBuffer;
+ unsigned int alignedValue = (value << 24) | (value << 16) | (value << 8) | value;
+
+ // Set words if possible
+ if ((((unsigned int) pAlignedDestination & 0x3) == 0) && (num >= 4)) {
+ while (num >= 4) {
+ *pAlignedDestination++ = alignedValue;
+ num -= 4;
+ }
+ }
+ // Set remaining bytes
+ pByteDestination = (unsigned char *) pAlignedDestination;
+ while (num--) {
+ *pByteDestination++ = value;
+ }
+ return pBuffer;
+}
+
+//-----------------------------------------------------------------------------
+/// Search a character in the given string.
+/// Returns a pointer to the character location.
+/// \param pString Pointer to the start of the string to search.
+/// \param character The character to find.
+//-----------------------------------------------------------------------------
+char * strchr(const char *pString, int character)
+{
+ char * p = (char *)pString;
+ char c = character & 0xFF;
+
+ while(*p != c) {
+ if (*p == 0) {
+ return 0;
+ }
+ p++;
+ }
+ return p;
+}
+
+//-----------------------------------------------------------------------------
+/// Return the length of a given string
+/// \param pString Pointer to the start of the string.
+//-----------------------------------------------------------------------------
+size_t strlen(const char *pString)
+{
+ unsigned int length = 0;
+
+ while(*pString++ != 0) {
+ length++;
+ }
+ return length;
+}
+
+
+//-----------------------------------------------------------------------------
+/// Search a character backword from the end of given string.
+/// Returns a pointer to the character location.
+/// \param pString Pointer to the start of the string to search.
+/// \param character The character to find.
+//-----------------------------------------------------------------------------
+char * strrchr(const char *pString, int character)
+{
+ char *p = 0;
+
+ while(*pString != 0) {
+ if (*pString++ == character) {
+ p = (char*)pString;
+ }
+ }
+ return p;
+}
+
+//-----------------------------------------------------------------------------
+/// Copy from source string to destination string
+/// Return a pointer to the destination string
+/// \param pDestination Pointer to the destination string.
+/// \param pSource Pointer to the source string.
+//-----------------------------------------------------------------------------
+char * strcpy(char *pDestination, const char *pSource)
+{
+ char *pSaveDest = pDestination;
+
+ for(; (*pDestination = *pSource) != 0; ++pSource, ++pDestination);
+ return pSaveDest;
+}
+
+//-----------------------------------------------------------------------------
+/// Compare the first specified bytes of 2 given strings
+/// Return 0 if equals
+/// Return >0 if 1st string > 2nd string
+/// Return <0 if 1st string < 2nd string
+/// \param pString1 Pointer to the start of the 1st string.
+/// \param pString2 Pointer to the start of the 2nd string.
+/// \param count Number of bytes that should be compared.
+//-----------------------------------------------------------------------------
+int strncmp(const char *pString1, const char *pString2, size_t count)
+{
+ int r;
+
+ while(count) {
+ r = *pString1 - *pString2;
+ if (r == 0) {
+ if (*pString1 == 0) {
+ break;
+ }
+ pString1++;
+ pString2++;
+ count--;
+ continue;
+ }
+ return r;
+ }
+ return 0;
+}
+
+//-----------------------------------------------------------------------------
+/// Copy the first number of bytes from source string to destination string
+/// Return the pointer to the destination string.
+/// \param pDestination Pointer to the start of destination string.
+/// \param pSource Pointer to the start of the source string.
+/// \param count Number of bytes that should be copied.
+//-----------------------------------------------------------------------------
+char * strncpy(char *pDestination, const char *pSource, size_t count)
+{
+ char *pSaveDest = pDestination;
+
+ while (count) {
+ *pDestination = *pSource;
+ if (*pSource == 0) {
+ break;
+ }
+ pDestination++;
+ pSource++;
+ count--;
+ }
+ return pSaveDest;
+}
+
diff --git a/utility/trace.c b/utility/trace.c
new file mode 100644
index 0000000..44bdab1
--- /dev/null
+++ b/utility/trace.c
@@ -0,0 +1,299 @@
+/* ----------------------------------------------------------------------------
+ * 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 "trace.h"
+
+//------------------------------------------------------------------------------
+// Internal variables
+//------------------------------------------------------------------------------
+
+/// Trace level can be set at applet initialization
+#if !defined(NOTRACE) && (DYN_TRACES == 1)
+ unsigned int traceLevel = TRACE_LEVEL;
+#endif
+
+#ifndef NOFPUT
+#include <stdio.h>
+#include <stdarg.h>
+
+//------------------------------------------------------------------------------
+/// \exclude
+/// Implementation of fputc using the DBGU as the standard output. Required
+/// for printf().
+/// \param c Character to write.
+/// \param pStream Output stream.
+/// \param The character written if successful, or -1 if the output stream is
+/// not stdout or stderr.
+//------------------------------------------------------------------------------
+signed int fputc(signed int c, FILE *pStream)
+{
+ if ((pStream == stdout) || (pStream == stderr)) {
+
+ TRACE_PutChar(c);
+ return c;
+ }
+ else {
+
+ return EOF;
+ }
+}
+
+//------------------------------------------------------------------------------
+/// \exclude
+/// Implementation of fputs using the DBGU as the standard output. Required
+/// for printf(). Does NOT currently use the PDC.
+/// \param pStr String to write.
+/// \param pStream Output stream.
+/// \return Number of characters written if successful, or -1 if the output
+/// stream is not stdout or stderr.
+//------------------------------------------------------------------------------
+signed int fputs(const char *pStr, FILE *pStream)
+{
+ signed int num = 0;
+
+ while (*pStr != 0) {
+
+ if (fputc(*pStr, pStream) == -1) {
+
+ return -1;
+ }
+ num++;
+ pStr++;
+ }
+
+ return num;
+}
+
+#undef putchar
+
+//------------------------------------------------------------------------------
+/// \exclude
+/// Outputs a character on the DBGU.
+/// \param c Character to output.
+/// \return The character that was output.
+//------------------------------------------------------------------------------
+signed int putchar(signed int c)
+{
+ return fputc(c, stdout);
+}
+
+#endif //#ifndef NOFPUT
+
+//------------------------------------------------------------------------------
+// Local Functions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// Print char if printable. If not print a point
+/// \param c char to
+//------------------------------------------------------------------------------
+static void PrintChar(unsigned char c)
+{
+ if( (/*c >= 0x00 &&*/ c <= 0x1F) ||
+ (c >= 0xB0 && c <= 0xDF) ) {
+
+ printf(".");
+ }
+ else {
+
+ printf("%c", c);
+ }
+}
+
+//------------------------------------------------------------------------------
+// Global Functions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// Displays the content of the given frame on the Trace interface.
+/// \param pBuffer Pointer to the frame to dump.
+/// \param size Buffer size in bytes.
+//------------------------------------------------------------------------------
+void TRACE_DumpFrame(unsigned char *pFrame, unsigned int size)
+{
+ unsigned int i;
+
+ for (i=0; i < size; i++) {
+ printf("%02X ", pFrame[i]);
+ }
+
+ printf("\n\r");
+}
+
+//------------------------------------------------------------------------------
+/// Displays the content of the given buffer on the Trace interface.
+/// \param pBuffer Pointer to the buffer to dump.
+/// \param size Buffer size in bytes.
+/// \param address Start address to display
+//------------------------------------------------------------------------------
+void TRACE_DumpMemory(
+ unsigned char *pBuffer,
+ unsigned int size,
+ unsigned int address
+ )
+{
+ unsigned int i, j;
+ unsigned int lastLineStart;
+ unsigned char* pTmp;
+
+ for (i=0; i < (size / 16); i++) {
+
+ printf("0x%08X (%04x): ", address + (i*16), (i*16));
+ pTmp = (unsigned char*)&pBuffer[i*16];
+ for (j=0; j < 4; j++) {
+ printf("%02X%02X%02X%02X ", pTmp[0],pTmp[1],pTmp[2],pTmp[3]);
+ pTmp += 4;
+ }
+
+ pTmp = (unsigned char*)&pBuffer[i*16];
+ for (j=0; j < 16; j++) {
+ PrintChar(*pTmp++);
+ }
+
+ printf("\n\r");
+ }
+
+ if( (size%16) != 0) {
+ lastLineStart = size - (size%16);
+ printf("0x%08X: ", address + lastLineStart);
+
+ for (j= lastLineStart; j < lastLineStart+16; j++) {
+
+ if( (j!=lastLineStart) && (j%4 == 0) ) {
+ printf(" ");
+ }
+ if(j<size) {
+ printf("%02X", pBuffer[j]);
+ }
+ else {
+ printf(" ");
+ }
+ }
+
+ printf(" ");
+ for (j= lastLineStart; j <size; j++) {
+ PrintChar(pBuffer[j]);
+ }
+
+ printf("\n\r");
+ }
+}
+
+//------------------------------------------------------------------------------
+/// Reads an integer
+//------------------------------------------------------------------------------
+unsigned char TRACE_GetInteger(unsigned int *pValue)
+{
+ unsigned char key;
+ unsigned char nbNb = 0;
+ unsigned int value = 0;
+ while(1) {
+ key = TRACE_GetChar();
+ TRACE_PutChar(key);
+ if(key >= '0' && key <= '9' ) {
+ value = (value * 10) + (key - '0');
+ nbNb++;
+ }
+ else if(key == 0x0D || key == ' ') {
+ if(nbNb == 0) {
+ printf("\n\rWrite a number and press ENTER or SPACE!\n\r");
+ return 0;
+ } else {
+ printf("\n\r");
+ *pValue = value;
+ return 1;
+ }
+ } else {
+ printf("\n\r'%c' not a number!\n\r", key);
+ return 0;
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+/// Reads an integer and check the value
+//------------------------------------------------------------------------------
+unsigned char TRACE_GetIntegerMinMax(
+ unsigned int *pValue,
+ unsigned int min,
+ unsigned int max
+ )
+{
+ unsigned int value = 0;
+
+ if( TRACE_GetInteger(&value) == 0) {
+ return 0;
+ }
+
+ if(value < min || value > max) {
+ printf("\n\rThe number have to be between %d and %d\n\r", (int)min, (int)max);
+ return 0;
+ }
+
+ printf("\n\r");
+ *pValue = value;
+ return 1;
+}
+
+//------------------------------------------------------------------------------
+/// Reads an hexadecimal number
+//------------------------------------------------------------------------------
+unsigned char TRACE_GetHexa32(unsigned int *pValue)
+{
+ unsigned char key;
+ unsigned int i = 0;
+ unsigned int value = 0;
+ for(i = 0; i < 8; i++) {
+ key = TRACE_GetChar();
+ TRACE_PutChar(key);
+ if(key >= '0' && key <= '9' ) {
+ value = (value * 16) + (key - '0');
+ }
+ else if(key >= 'A' && key <= 'F' ) {
+ value = (value * 16) + (key - 'A' + 10) ;
+ }
+ else if(key >= 'a' && key <= 'f' ) {
+ value = (value * 16) + (key - 'a' + 10) ;
+ }
+ else {
+ printf("\n\rIt is not a hexa character!\n\r");
+ return 0;
+ }
+ }
+
+ printf("\n\r");
+ *pValue = value;
+ return 1;
+}
+
diff --git a/utility/trace.h b/utility/trace.h
new file mode 100644
index 0000000..702fdcf
--- /dev/null
+++ b/utility/trace.h
@@ -0,0 +1,352 @@
+/* ----------------------------------------------------------------------------
+ * 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
+///
+/// Standard output methods for reporting debug information, warnings and
+/// errors, which can be easily be turned on/off.
+///
+/// !Usage
+/// -# Initialize the DBGU using TRACE_CONFIGURE() if you intend to eventually
+/// disable ALL traces; otherwise use DBGU_Configure().
+/// -# Uses the TRACE_DEBUG(), TRACE_INFO(), TRACE_WARNING(), TRACE_ERROR()
+/// TRACE_FATAL() macros to output traces throughout the program.
+/// -# Each type of trace has a level : Debug 5, Info 4, Warning 3, Error 2
+/// and Fatal 1. Disable a group of traces by changing the value of
+/// TRACE_LEVEL during compilation; traces with a level bigger than TRACE_LEVEL
+/// are not generated. To generate no trace, use the reserved value 0.
+/// -# Trace disabling can be static or dynamic. If dynamic disabling is selected
+/// the trace level can be modified in runtime. If static disabling is selected
+/// the disabled traces are not compiled.
+///
+/// !Trace level description
+/// -# TRACE_DEBUG (5): Traces whose only purpose is for debugging the program,
+/// and which do not produce meaningful information otherwise.
+/// -# TRACE_INFO (4): Informational trace about the program execution. Should
+/// enable the user to see the execution flow.
+/// -# TRACE_WARNING (3): Indicates that a minor error has happened. In most case
+/// it can be discarded safely; it may even be expected.
+/// -# TRACE_ERROR (2): Indicates an error which may not stop the program execution,
+/// but which indicates there is a problem with the code.
+/// -# TRACE_FATAL (1): Indicates a major error which prevents the program from going
+/// any further.
+
+//------------------------------------------------------------------------------
+
+#ifndef TRACE_H
+#define TRACE_H
+
+//------------------------------------------------------------------------------
+// Headers
+//------------------------------------------------------------------------------
+
+#include <board.h>
+#include <pio/pio.h>
+#include <stdio.h>
+
+// Select the trace interface
+// (add usart.o file in makefile if Usart interface is selected)
+#define TRACE_DBGU 1
+//#define TRACE_USART_0 1
+//#define TRACE_USART_1 1
+//#define TRACE_USART_2 1
+
+#if defined(TRACE_DBGU)
+#include <dbgu/dbgu.h>
+#else
+#include <usart/usart.h>
+#endif
+
+//------------------------------------------------------------------------------
+// Global Definitions
+//------------------------------------------------------------------------------
+
+/// Softpack Version
+#define SOFTPACK_VERSION "1.9-rc1"
+
+#define TRACE_LEVEL_DEBUG 5
+#define TRACE_LEVEL_INFO 4
+#define TRACE_LEVEL_WARNING 3
+#define TRACE_LEVEL_ERROR 2
+#define TRACE_LEVEL_FATAL 1
+#define TRACE_LEVEL_NO_TRACE 0
+
+// By default, all traces are output except the debug one.
+#if !defined(TRACE_LEVEL)
+#define TRACE_LEVEL TRACE_LEVEL_INFO
+#endif
+
+// By default, trace level is static (not dynamic)
+#if !defined(DYN_TRACES)
+#define DYN_TRACES 0
+#endif
+
+#if defined(NOTRACE)
+#error "Error: NOTRACE has to be not defined !"
+#endif
+
+#undef NOTRACE
+#if (DYN_TRACES==0)
+ #if (TRACE_LEVEL == TRACE_LEVEL_NO_TRACE)
+ #define NOTRACE
+ #endif
+#endif
+
+//------------------------------------------------------------------------------
+// Global Macros
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// Initializes the trace for normal project
+/// \param mode DBGU mode.
+/// \param baudrate DBGU baudrate.
+/// \param mck Master clock frequency.
+//------------------------------------------------------------------------------
+#if defined(TRACE_DBGU)
+ #define TRACE_CONFIGURE(mode, baudrate, mck) { \
+ const Pin pinsDbgu[] = {PINS_DBGU}; \
+ PIO_Configure(pinsDbgu, PIO_LISTSIZE(pinsDbgu)); \
+ DBGU_Configure(mode, baudrate, mck); \
+ }
+#elif defined(TRACE_USART_0)
+ #define TRACE_CONFIGURE(mode, baudrate, mck) { \
+ const Pin pinsUsart[] = {PIN_USART0_TXD, PIN_USART0_RXD}; \
+ AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_US0;\
+ AT91C_BASE_US0->US_IDR = 0xFFFFFFFF;\
+ PIO_Configure(pinsUsart, PIO_LISTSIZE(pinsUsart)); \
+ USART_Configure(AT91C_BASE_US0,USART_MODE_ASYNCHRONOUS, baudrate, mck); \
+ USART_SetTransmitterEnabled(AT91C_BASE_US0,1);\
+ USART_SetReceiverEnabled(AT91C_BASE_US0,1);\
+ }
+#elif defined(TRACE_USART_1)
+ #define TRACE_CONFIGURE(mode, baudrate, mck) { \
+ const Pin pinsUsart[] = {PIN_USART1_TXD, PIN_USART1_RXD}; \
+ AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_US1;\
+ AT91C_BASE_US1->US_IDR = 0xFFFFFFFF;\
+ PIO_Configure(pinsUsart, PIO_LISTSIZE(pinsUsart)); \
+ USART_Configure(AT91C_BASE_US1,USART_MODE_ASYNCHRONOUS, baudrate, mck); \
+ USART_SetTransmitterEnabled(AT91C_BASE_US1,1);\
+ USART_SetReceiverEnabled(AT91C_BASE_US1,1);\
+ }
+#elif defined(TRACE_USART_2)
+ #define TRACE_CONFIGURE(mode, baudrate, mck) { \
+ const Pin pinsUsart[] = {PIN_USART2_TXD, PIN_USART2_RXD}; \
+ AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_US2;\
+ AT91C_BASE_US2->US_IDR = 0xFFFFFFFF;\
+ PIO_Configure(pinsUsart, PIO_LISTSIZE(pinsUsart)); \
+ USART_Configure(AT91C_BASE_US2,USART_MODE_ASYNCHRONOUS, baudrate, mck); \
+ USART_SetTransmitterEnabled(AT91C_BASE_US2,1);\
+ USART_SetReceiverEnabled(AT91C_BASE_US2,1);\
+ }
+#endif
+
+//------------------------------------------------------------------------------
+/// Initializes the trace for ISP project
+/// \param mode DBGU mode.
+/// \param baudrate DBGU baudrate.
+/// \param mck Master clock frequency.
+//------------------------------------------------------------------------------
+#if (TRACE_LEVEL==0) && (DYN_TRACES==0)
+ #define TRACE_CONFIGURE_ISP(mode, baudrate, mck) {}
+#elif defined(TRACE_DBGU)
+ #define TRACE_CONFIGURE_ISP(mode, baudrate, mck) { \
+ const Pin pinsDbgu[] = {PINS_DBGU}; \
+ PIO_Configure(pinsDbgu, PIO_LISTSIZE(pinsDbgu)); \
+ DBGU_Configure(mode, baudrate, mck); \
+ }
+#elif defined(TRACE_USART_0)
+ #define TRACE_CONFIGURE_ISP(mode, baudrate, mck) { \
+ const Pin pinsUsart[] = {PIN_USART0_TXD, PIN_USART0_RXD}; \
+ AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_US0;\
+ AT91C_BASE_US0->US_IDR = 0xFFFFFFFF;\
+ PIO_Configure(pinsUsart, PIO_LISTSIZE(pinsUsart)); \
+ USART_Configure(AT91C_BASE_US0,USART_MODE_ASYNCHRONOUS, baudrate, mck); \
+ USART_SetTransmitterEnabled(AT91C_BASE_US0,1);\
+ USART_SetReceiverEnabled(AT91C_BASE_US0,1);\
+ }
+#elif defined(TRACE_USART_1)
+ #define TRACE_CONFIGURE_ISP(mode, baudrate, mck) { \
+ const Pin pinsUsart[] = {PIN_USART1_TXD, PIN_USART1_RXD}; \
+ AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_US1;\
+ AT91C_BASE_US1->US_IDR = 0xFFFFFFFF;\
+ PIO_Configure(pinsUsart, PIO_LISTSIZE(pinsUsart)); \
+ USART_Configure(AT91C_BASE_US1,USART_MODE_ASYNCHRONOUS, baudrate, mck); \
+ USART_SetTransmitterEnabled(AT91C_BASE_US1,1);\
+ USART_SetReceiverEnabled(AT91C_BASE_US1,1);\
+ }
+#elif defined(TRACE_USART_2)
+ #define TRACE_CONFIGURE_ISP(mode, baudrate, mck) { \
+ const Pin pinsUsart[] = {PIN_USART2_TXD, PIN_USART2_RXD}; \
+ AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_US2;\
+ AT91C_BASE_US2->US_IDR = 0xFFFFFFFF;\
+ PIO_Configure(pinsUsart, PIO_LISTSIZE(pinsUsart)); \
+ USART_Configure(AT91C_BASE_US2,USART_MODE_ASYNCHRONOUS, baudrate, mck); \
+ USART_SetTransmitterEnabled(AT91C_BASE_US2,1);\
+ USART_SetReceiverEnabled(AT91C_BASE_US2,1);\
+ }
+#endif
+
+//------------------------------------------------------------------------------
+/// Macros TRACE_PutChar & TRACE_GetChar & TRACE_IsRxReady
+//------------------------------------------------------------------------------
+#if defined(TRACE_DBGU)
+ #define TRACE_PutChar(c) DBGU_PutChar(c)
+ #define TRACE_GetChar() DBGU_GetChar()
+ #define TRACE_IsRxReady() DBGU_IsRxReady()
+#elif defined(TRACE_USART_0)
+ #define TRACE_PutChar(c) USART_PutChar(AT91C_BASE_US0, c)
+ #define TRACE_GetChar() USART_GetChar(AT91C_BASE_US0)
+ #define TRACE_IsRxReady() USART_IsRxReady(AT91C_BASE_US0)
+#elif defined(TRACE_USART_1)
+ #define TRACE_PutChar(c) USART_PutChar(AT91C_BASE_US1, c)
+ #define TRACE_GetChar() USART_GetChar(AT91C_BASE_US1)
+ #define TRACE_IsRxReady() USART_IsRxReady(AT91C_BASE_US1)
+#elif defined(TRACE_USART_2)
+ #define TRACE_PutChar(c) USART_PutChar(AT91C_BASE_US2, c)
+ #define TRACE_GetChar() USART_GetChar(AT91C_BASE_US2)
+ #define TRACE_IsRxReady() USART_IsRxReady(AT91C_BASE_US2)
+#endif
+
+//------------------------------------------------------------------------------
+/// Outputs a formatted string using <printf> if the log level is high
+/// enough. Can be disabled by defining TRACE_LEVEL=0 during compilation.
+/// \param format Formatted string to output.
+/// \param ... Additional parameters depending on formatted string.
+//------------------------------------------------------------------------------
+#if defined(NOTRACE)
+
+// Empty macro
+#define TRACE_DEBUG(...) { }
+#define TRACE_INFO(...) { }
+#define TRACE_WARNING(...) { }
+#define TRACE_ERROR(...) { }
+#define TRACE_FATAL(...) { while(1); }
+#define TRACE_PERM(...) { }
+
+#define TRACE_DEBUG_WP(...) { }
+#define TRACE_INFO_WP(...) { }
+#define TRACE_WARNING_WP(...) { }
+#define TRACE_ERROR_WP(...) { }
+#define TRACE_FATAL_WP(...) { while(1); }
+#define TRACE_PERM_WP(...) { }
+
+#elif (DYN_TRACES == 1)
+
+// Trace output depends on traceLevel value
+#define TRACE_DEBUG(...) { if (traceLevel >= TRACE_LEVEL_DEBUG) { printf("-D- " __VA_ARGS__); } }
+#define TRACE_INFO(...) { if (traceLevel >= TRACE_LEVEL_INFO) { printf("-I- " __VA_ARGS__); } }
+#define TRACE_WARNING(...) { if (traceLevel >= TRACE_LEVEL_WARNING) { printf("-W- " __VA_ARGS__); } }
+#define TRACE_ERROR(...) { if (traceLevel >= TRACE_LEVEL_ERROR) { printf("-E- " __VA_ARGS__); } }
+#define TRACE_FATAL(...) { if (traceLevel >= TRACE_LEVEL_FATAL) { printf("-F- " __VA_ARGS__); while(1); } }
+#define TRACE_PERM(...) { printf("-P- " __VA_ARGS__); }
+
+#define TRACE_DEBUG_WP(...) { if (traceLevel >= TRACE_LEVEL_DEBUG) { printf(__VA_ARGS__); } }
+#define TRACE_INFO_WP(...) { if (traceLevel >= TRACE_LEVEL_INFO) { printf(__VA_ARGS__); } }
+#define TRACE_WARNING_WP(...) { if (traceLevel >= TRACE_LEVEL_WARNING) { printf(__VA_ARGS__); } }
+#define TRACE_ERROR_WP(...) { if (traceLevel >= TRACE_LEVEL_ERROR) { printf(__VA_ARGS__); } }
+#define TRACE_FATAL_WP(...) { if (traceLevel >= TRACE_LEVEL_FATAL) { printf(__VA_ARGS__); while(1); } }
+#define TRACE_PERM_WP(...) { printf(__VA_ARGS__); }
+
+#else
+
+// Trace compilation depends on TRACE_LEVEL value
+#if (TRACE_LEVEL >= TRACE_LEVEL_DEBUG)
+#define TRACE_DEBUG(...) { printf("-D- " __VA_ARGS__); }
+#define TRACE_DEBUG_WP(...) { printf(__VA_ARGS__); }
+#else
+#define TRACE_DEBUG(...) { }
+#define TRACE_DEBUG_WP(...) { }
+#endif
+
+#if (TRACE_LEVEL >= TRACE_LEVEL_INFO)
+#define TRACE_INFO(...) { printf("-I- " __VA_ARGS__); }
+#define TRACE_INFO_WP(...) { printf(__VA_ARGS__); }
+#else
+#define TRACE_INFO(...) { }
+#define TRACE_INFO_WP(...) { }
+#endif
+
+#if (TRACE_LEVEL >= TRACE_LEVEL_WARNING)
+#define TRACE_WARNING(...) { printf("-W- " __VA_ARGS__); }
+#define TRACE_WARNING_WP(...) { printf(__VA_ARGS__); }
+#else
+#define TRACE_WARNING(...) { }
+#define TRACE_WARNING_WP(...) { }
+#endif
+
+#if (TRACE_LEVEL >= TRACE_LEVEL_ERROR)
+#define TRACE_ERROR(...) { printf("-E- " __VA_ARGS__); }
+#define TRACE_ERROR_WP(...) { printf(__VA_ARGS__); }
+#else
+#define TRACE_ERROR(...) { }
+#define TRACE_ERROR_WP(...) { }
+#endif
+
+#if (TRACE_LEVEL >= TRACE_LEVEL_FATAL)
+#define TRACE_FATAL(...) { printf("-F- " __VA_ARGS__); while(1); }
+#define TRACE_FATAL_WP(...) { printf(__VA_ARGS__); while(1); }
+#else
+#define TRACE_FATAL(...) { while(1); }
+#define TRACE_FATAL_WP(...) { while(1); }
+#endif
+
+#define TRACE_PERM(...) { printf("-P " __VA_ARGS__); }
+#define TRACE_PERM_WP(...) { printf(__VA_ARGS__); }
+
+#endif
+
+
+//------------------------------------------------------------------------------
+// Exported variables
+//------------------------------------------------------------------------------
+// Depending on DYN_TRACES, traceLevel is a modifable runtime variable
+// or a define
+#if !defined(NOTRACE) && (DYN_TRACES == 1)
+ extern unsigned int traceLevel;
+#endif
+
+//------------------------------------------------------------------------------
+// Global Functions
+//------------------------------------------------------------------------------
+
+extern void TRACE_DumpFrame(unsigned char *pFrame, unsigned int size);
+
+extern void TRACE_DumpMemory(unsigned char *pBuffer, unsigned int size, unsigned int address);
+
+extern unsigned char TRACE_GetInteger(unsigned int *pValue);
+
+extern unsigned char TRACE_GetIntegerMinMax(unsigned int *pValue, unsigned int min, unsigned int max);
+
+extern unsigned char TRACE_GetHexa32(unsigned int *pValue);
+
+#endif //#ifndef TRACE_H
+
diff --git a/utility/utility.dir b/utility/utility.dir
new file mode 100644
index 0000000..b318e27
--- /dev/null
+++ b/utility/utility.dir
@@ -0,0 +1,50 @@
+/* ----------------------------------------------------------------------------
+ * 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
+///
+/// The utility directory contains several very small APIs for performing
+/// specific tasks, such as LED configuration, BMP header decoding, etc.
+///
+/// !!!Contents
+///
+/// Most modules contained here are very small and do not fit in any of the
+/// other at91lib categories. They primarily provide helper functions
+/// (e.g. for handling BMP and WAV files) and re-implementation of libc code for
+/// reducing code size (math, stdio, string).
+///
+/// Two important files are assert.h and trace.h. The first one provides macros
+/// for run-time verifications of parameters & values. Trace.h enables the
+/// programmer to add debug traces to APIs that can be easily turned on or off
+/// depending on the debugging needs.
+//------------------------------------------------------------------------------
+
diff --git a/utility/video.c b/utility/video.c
new file mode 100644
index 0000000..d516a1b
--- /dev/null
+++ b/utility/video.c
@@ -0,0 +1,130 @@
+/* ----------------------------------------------------------------------------
+ * 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 "video.h"
+
+//-----------------------------------------------------------------------------
+/// Conversion YCrCb to RGB:<BR>
+/// R = 1.164(Yi – 16) + 1.596(Cr – 128)<BR>
+/// G = 1.164(Yi – 16) – 0.813(Cr – 128) – 0.391(Cb – 128)<BR>
+/// B = 1.164(Yi – 16) + 2.018(Cb – 128)<BR>
+///
+/// Pixel i+1:<BR>
+/// YCrCb to RGB:<BR>
+/// R = 1.164(Yi+1 – 16) + 1.596(Cr – 128)<BR>
+/// G = 1.164(Yi+1 – 16) – 0.813(Cr – 128) – 0.391(Cb – 128)<BR>
+/// B = 1.164(Yi+1 – 16) + 2.018(Cb – 128)
+/// \param ycc Source buffer (YCC)
+/// \param rgb Destination buffer (RGB)
+/// \param len Length of buffer
+//-----------------------------------------------------------------------------
+void VIDEO_Ycc2Rgb(unsigned char *ycc, unsigned short *rgb, unsigned int len)
+{
+ int r_calc_i;
+ int g_calc_i;
+ int b_calc_i;
+ int r_calc_i_incr;
+ int g_calc_i_incr;
+ int b_calc_i_incr;
+ int cr_i;
+ int y_i;
+ int cb_i;
+ int y_i_incr;
+ int val;
+ int val1;
+ int val2;
+ int val3;
+ int val4;
+ int val5;
+ int i;
+
+ for(i=0; i<len; i++)
+ {
+ cb_i = (int)ycc[4*i];
+ y_i = (int )ycc[4*i+1];
+ cr_i = (int )ycc[4*i+2];
+ y_i_incr =(int )ycc[4*i+3];
+
+ val = 1164*(y_i-16);
+ val1 = 1164*(y_i_incr-16);
+ val2 = 1596*(cr_i- 128);
+ val3 = 813*(cb_i-128);
+ val4 = 392*(cr_i-128);
+ val5 = 2017*(cb_i-128);
+
+ r_calc_i = (val + val2)/1000;
+ g_calc_i = (val - val3 - val4)/1000;
+ b_calc_i = (val + val5)/1000;
+ r_calc_i_incr = (val1 + val2)/1000;
+ g_calc_i_incr = (val1 - val3 - val4)/1000;
+ b_calc_i_incr = (val1 + val5)/1000;
+
+ if (r_calc_i < 0)
+ r_calc_i = 0;
+ else if (r_calc_i > 255)
+ r_calc_i = 255;
+
+ if (g_calc_i < 0)
+ g_calc_i = 0;
+ else if (g_calc_i > 255)
+ g_calc_i = 255;
+
+ if (b_calc_i < 0)
+ b_calc_i = 0;
+ else if (b_calc_i > 255)
+ b_calc_i = 255;
+
+ if (r_calc_i_incr < 0)
+ r_calc_i_incr = 0;
+ else if (r_calc_i_incr > 255)
+ r_calc_i_incr = 255;
+
+ if (g_calc_i_incr < 0)
+ g_calc_i_incr = 0;
+ else if (g_calc_i_incr > 255)
+ g_calc_i_incr = 255;
+
+ if (b_calc_i_incr < 0)
+ b_calc_i_incr = 0;
+ else if (b_calc_i_incr > 255)
+ b_calc_i_incr = 255;
+
+ *rgb++ = (((unsigned short )r_calc_i & 0xF8) >> 3)
+ | ((((unsigned short)g_calc_i & 0xF8) >> 3) << 5)
+ | ((((unsigned short)b_calc_i & 0xF8) >> 3) << 10);
+
+ *rgb++ = (((unsigned short )r_calc_i_incr & 0xF8) >> 3)
+ | ((((unsigned short)g_calc_i_incr & 0xF8) >> 3) << 5)
+ | ((((unsigned short)b_calc_i_incr & 0xF8) >> 3) << 10);
+ }
+}
+
diff --git a/utility/video.h b/utility/video.h
new file mode 100644
index 0000000..28f4a18
--- /dev/null
+++ b/utility/video.h
@@ -0,0 +1,89 @@
+/* ----------------------------------------------------------------------------
+ * 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
+///
+/// Video structure, used for LCD and ISI.
+/// Conversion Video from YCC to RGB
+///
+//------------------------------------------------------------------------------
+
+#ifndef _VIDEO_H
+#define _VIDEO_H
+
+//-----------------------------------------------------------------------------
+// Definitions
+//-----------------------------------------------------------------------------
+/// Type of video is YUV
+#define YUV 0
+/// Type of video is RGB
+#define RGB 1
+
+//-----------------------------------------------------------------------------
+/// Video structure
+//-----------------------------------------------------------------------------
+typedef struct _AT91S_VIDEO
+{
+ /// LCD Vertical Size
+ unsigned int lcd_vsize;
+ /// LCD Horizontal Size
+ unsigned int lcd_hsize;
+ /// LCD Number of Bit Per Pixel
+ unsigned int lcd_nbpp;
+ /// LCD Frame Buffer Address
+ unsigned int lcd_fb_addr;
+ /// Base address for the frame buffer descriptors list
+ unsigned int Isi_fbd_base;
+ /// Start of Line Delay
+ unsigned int Hblank;
+ /// Start of frame Delay
+ unsigned int Vblank;
+ /// Vertical size of the Image sensor [0..2047]
+ unsigned int codec_vsize;
+ /// Horizontal size of the Image sensor [0..2047]
+ unsigned int codec_hsize;
+ /// Base address for codec DMA
+ unsigned int codec_fb_addr;
+ /// Buffer index
+ unsigned int IsiPrevBuffIndex;
+ /// Type of video
+ unsigned char rgb_or_yuv;
+}AT91S_VIDEO, *AT91PS_VIDEO;
+
+
+//------------------------------------------------------------------------------
+// Exported functions
+//------------------------------------------------------------------------------
+extern void VIDEO_Ycc2Rgb(unsigned char *ycc, unsigned short *rgb, unsigned int len);
+
+#endif
+
diff --git a/utility/wav.c b/utility/wav.c
new file mode 100644
index 0000000..62c7960
--- /dev/null
+++ b/utility/wav.c
@@ -0,0 +1,84 @@
+/* ----------------------------------------------------------------------------
+ * 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 "wav.h"
+#include <utility/trace.h>
+
+//------------------------------------------------------------------------------
+// Internal constants
+//------------------------------------------------------------------------------
+
+/// WAV letters "RIFF"
+#define WAV_CHUNKID 0x46464952
+/// WAV letters "WAVE"
+#define WAV_FORMAT 0x45564157
+/// WAV letters "fmt "
+#define WAV_SUBCHUNKID 0x20746D66
+
+//------------------------------------------------------------------------------
+// Exported functions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// Returns 1 if the header of a Wav file is valid; otherwise returns 0.
+/// \param file Buffer holding the file to examinate.
+//------------------------------------------------------------------------------
+unsigned char WAV_IsValid(const WavHeader *header)
+{
+ return ((header->chunkID == WAV_CHUNKID)
+ && (header->format == WAV_FORMAT)
+ && (header->subchunk1Size == 0x10));
+}
+
+//------------------------------------------------------------------------------
+/// Display the information of the WAV file (sample rate, stereo/mono and frame
+/// size).
+//------------------------------------------------------------------------------
+void WAV_DisplayInfo(const WavHeader *header)
+{
+ TRACE_PERM_WP( "Wave file header information\n\r");
+ TRACE_PERM_WP( "--------------------------------\n\r");
+ TRACE_PERM_WP( " - Chunk ID = 0x%08X\n\r", header->chunkID);
+ TRACE_PERM_WP( " - Chunk Size = %d\n\r", header->chunkSize);
+ TRACE_PERM_WP( " - Format = 0x%08X\n\r", header->format);
+ TRACE_PERM_WP( " - SubChunk ID = 0x%08X\n\r", header->subchunk1ID);
+ TRACE_PERM_WP( " - Subchunk1 Size = %d\n\r", header->subchunk1Size);
+ TRACE_PERM_WP( " - Audio Format = 0x%04X\n\r", header->audioFormat);
+ TRACE_PERM_WP( " - Num. Channels = %d\n\r", header->numChannels);
+ TRACE_PERM_WP( " - Sample Rate = %d\n\r", header->sampleRate);
+ TRACE_PERM_WP( " - Byte Rate = %d\n\r", header->byteRate);
+ TRACE_PERM_WP( " - Block Align = %d\n\r", header->blockAlign);
+ TRACE_PERM_WP( " - Bits Per Sample = %d\n\r", header->bitsPerSample);
+ TRACE_PERM_WP( " - Subchunk2 ID = 0x%08X\n\r", header->subchunk2ID);
+ TRACE_PERM_WP( " - Subchunk2 Size = %d\n\r", header->subchunk2Size);
+} \ No newline at end of file
diff --git a/utility/wav.h b/utility/wav.h
new file mode 100644
index 0000000..d7e00d9
--- /dev/null
+++ b/utility/wav.h
@@ -0,0 +1,84 @@
+/* ----------------------------------------------------------------------------
+ * 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 WAV_H
+#define WAV_H
+
+//------------------------------------------------------------------------------
+// Exported types
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// Standard WAV file header information.
+//------------------------------------------------------------------------------
+typedef struct _WavHeader
+{
+ /// Contains the letters "RIFF" in ASCII form.
+ unsigned int chunkID;
+ /// Size of the rest of the chunk following this number.
+ unsigned int chunkSize;
+ /// Contains the letters "WAVE".
+ unsigned int format;
+ /// Contains the letters "fmt ".
+ unsigned int subchunk1ID;
+ /// 16 for PCM. This is the size of the rest of the Subchunk
+ /// which follows this number.
+ unsigned int subchunk1Size;
+ /// PCM = 1 (i.e. Linear quantization). Values other than 1 indicate some
+ /// form of compression.
+ unsigned short audioFormat;
+ /// Mono = 1, Stereo = 2, etc.
+ unsigned short numChannels;
+ /// 8000, 44100, etc.
+ unsigned int sampleRate;
+ /// SampleRate * NumChannels * BitsPerSample/8
+ unsigned int byteRate;
+ /// NumChannels * BitsPerSample/8
+ unsigned short blockAlign;
+ /// 8 bits = 8, 16 bits = 16, etc.
+ unsigned short bitsPerSample;
+ /// Contains the letters "data".
+ unsigned int subchunk2ID;
+ /// Number of bytes in the data.
+ unsigned int subchunk2Size;
+
+} WavHeader;
+
+#define WAV_HEADER_SIZE 0x100
+
+//------------------------------------------------------------------------------
+// Exported functions
+//------------------------------------------------------------------------------
+
+extern unsigned char WAV_IsValid(const WavHeader *header);
+
+extern void WAV_DisplayInfo(const WavHeader *header);
+
+#endif //#ifndef WAV_H
+
personal git repositories of Harald Welte. Your mileage may vary