aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAtsushi Saitoh <lynxeyed@xj9.so-net.ne.jp>2012-02-04 12:38:33 +0900
committerAtsushi Saitoh <lynxeyed@xj9.so-net.ne.jp>2012-02-04 12:38:33 +0900
commit90506dd1ab7a48a4e2fbe6cf7224d27828abf869 (patch)
tree23de598d6445aba54015c9b70f2d0fbded41c044 /src
parenteeda1597368fb49e254629e522295759d7f9c608 (diff)
new release
Diffstat (limited to 'src')
-rwxr-xr-xsrc/FatFs/SD.cpp120
-rwxr-xr-xsrc/FatFs/SD.h74
-rwxr-xr-xsrc/FatFs/diskio.h41
-rwxr-xr-xsrc/FatFs/integer.h37
-rwxr-xr-xsrc/FatFs/pff.cpp845
-rwxr-xr-xsrc/FatFs/pff.h469
-rwxr-xr-xsrc/FatFs/sdcard.cpp287
-rwxr-xr-xsrc/TFTLCD/TFTLCD.h220
-rwxr-xr-xsrc/XBee/XBee.cpp1355
-rwxr-xr-xsrc/XBee/XBee.h964
-rwxr-xr-xsrc/core/LPC11xx.h559
-rwxr-xr-xsrc/core/SPI.cpp213
-rwxr-xr-xsrc/core/SPI.h120
-rwxr-xr-xsrc/core/SPI1.cpp220
-rwxr-xr-xsrc/core/SPI1.h77
-rwxr-xr-xsrc/core/core_cm0.h960
-rwxr-xr-xsrc/core/cr_cpp_config.cpp56
-rwxr-xr-xsrc/core/cr_startup_lpc11.cpp383
-rwxr-xr-xsrc/core/delay.cpp123
-rwxr-xr-xsrc/core/delay.h64
-rwxr-xr-xsrc/core/gpio.cpp102
-rwxr-xr-xsrc/core/gpio.h194
-rwxr-xr-xsrc/core/libmary.h60
-rwxr-xr-xsrc/core/maryoled.cpp484
-rwxr-xr-xsrc/core/maryoled.h127
-rwxr-xr-xsrc/core/startup_mary.cpp26
-rwxr-xr-xsrc/core/system_LPC11xx.cpp452
-rwxr-xr-xsrc/core/system_LPC11xx.h64
-rwxr-xr-xsrc/core/uart.cpp206
-rwxr-xr-xsrc/core/uart.h90
-rwxr-xr-xsrc/user_application.cpp52
31 files changed, 9044 insertions, 0 deletions
diff --git a/src/FatFs/SD.cpp b/src/FatFs/SD.cpp
new file mode 100755
index 0000000..f614794
--- /dev/null
+++ b/src/FatFs/SD.cpp
@@ -0,0 +1,120 @@
+/*
+ * SD.cpp
+ *
+ * Created on: 2011/08/19
+ * Author: atsu
+ */
+#include <libmary.h>
+#include "SD.h"
+//#include "pff.h"
+
+PETITFS SDFile;
+
+PETITFS::PETITFS()
+{
+ this->SDCS = C33;
+}
+
+PETITFS::~PETITFS()
+{
+}
+BOOL PETITFS::begin(int cs_pin)
+{
+ BOOL rt;
+ this->SDCS = cs_pin;
+ rt = begin();
+ return (rt);
+}
+
+BOOL PETITFS::begin(SSP_PORT port)
+{
+ BOOL rt;
+ SPI.begin(port);
+ if(port == LPCXSSP0)
+ rt = begin(P1_4); //for MAPLE
+ else
+ rt = begin();
+ return (rt);
+}
+
+BOOL PETITFS::begin()
+{
+ rc = pf_mount(&fatfs);
+ return (!rc)? TRUE:FALSE;
+}
+
+BOOL PETITFS::exists()
+{
+ return FALSE;
+}
+
+BOOL PETITFS::mkdir()
+{
+ return FALSE;
+}
+
+FRESULT PETITFS::open(const char* filename) //???
+{
+ rc = pf_open(filename);
+ return rc;
+}
+
+
+BOOL PETITFS::remove(const char* filename)
+{
+ return FALSE;
+}
+
+BOOL PETITFS::rmdir(const char* filename)
+{
+ return FALSE;
+}
+
+int PETITFS::available(){}
+void PETITFS::close(){}
+void PETITFS::flush(){}
+int PETITFS::peek(){}
+unsigned long PETITFS::position(){}
+void PETITFS::print(const char *s){}
+void PETITFS::print(int val, RADIX_FORMAT format){}
+void PETITFS::println(const char *s){}
+void PETITFS::println(int val, RADIX_FORMAT format){}
+BOOL PETITFS::seek(unsigned long pos){}
+unsigned long PETITFS::size(){}
+
+int PETITFS::read()
+{
+ rc = pf_read(buff, sizeof(char), &br); /* Read a chunk of file */
+ if (rc || !br)
+ return -1; /* Error or end of file */
+ else
+ return (int)buff[0];
+}
+void PETITFS::write(const char *s){}
+void PETITFS::write(const char *s,int length){}
+
+/*
+class FILE {
+private:
+ char buff[64];
+ FRESULT rc;
+
+public:
+ FILE();
+ ~FILE();
+ int available();
+ void close();
+ void flush();
+ int peek();
+ unsigned long position();
+ void print(const char *s);
+ void print(int val, RADIX_FORMAT format);
+ void println(const char *s);
+ void println(int val, RADIX_FORMAT format) ;
+ BOOL seek(unsigned long pos);
+ unsigned long size();
+ int read();
+ void write(const char *s);
+ void write(const char *s,int length);
+};
+*/
diff --git a/src/FatFs/SD.h b/src/FatFs/SD.h
new file mode 100755
index 0000000..80a9cda
--- /dev/null
+++ b/src/FatFs/SD.h
@@ -0,0 +1,74 @@
+/*
+ * SD.h
+ *
+ * Created on: 2011/08/19
+ * Author: atsu
+ */
+
+#ifndef SD_H_
+#define SD_H_
+
+
+#include <libmary.h>
+#include <SPI.h>
+#include "pff.h"
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+class PETITFS{
+private:
+
+ FATFS fatfs; // File system object
+ DIR dir; // Directory object
+ FILINFO fno; // File information object
+ WORD bw, br, i;
+ char buff[64];
+ FRESULT rc;
+
+public:
+ int SDCS; //CS pin
+ PETITFS();
+ ~PETITFS();
+
+ BOOL begin(SSP_PORT port);
+ BOOL begin(int cs_pin);
+ BOOL begin();
+ BOOL exists();
+ BOOL mkdir();
+ FRESULT open(const char* filename); //???
+ BOOL remove(const char* filename);
+ BOOL rmdir(const char* filename);
+
+ int available();
+ void close();
+ void flush();
+ int peek();
+ unsigned long position();
+ void print(const char *s);
+ void print(int val, RADIX_FORMAT format);
+ void println(const char *s);
+ void println(int val, RADIX_FORMAT format) ;
+ BOOL seek(unsigned long pos);
+ unsigned long size();
+ int read();
+ void write(const char *s);
+ void write(const char *s,int length);
+};
+
+
+
+
+
+
+extern PETITFS SDFile;
+
+
+
+#ifdef __cplusplus
+ } //extern "C"
+#endif
+
+#endif /* SD_H_ */
diff --git a/src/FatFs/diskio.h b/src/FatFs/diskio.h
new file mode 100755
index 0000000..253cff6
--- /dev/null
+++ b/src/FatFs/diskio.h
@@ -0,0 +1,41 @@
+/*-----------------------------------------------------------------------
+/ PFF - Low level disk interface modlue include file (C)ChaN, 2009
+/-----------------------------------------------------------------------*/
+
+#ifndef _DISKIO
+
+#include "integer.h"
+#include <stdint.h>
+
+/* Status of Disk Functions */
+typedef uint8_t DSTATUS;
+
+
+/* Results of Disk Functions */
+typedef enum {
+ RES_OK = 0, /* 0: Function succeeded */
+ RES_ERROR, /* 1: Disk error */
+ RES_NOTRDY, /* 2: Not ready */
+ RES_PARERR /* 3: Invalid parameter */
+} DRESULT;
+
+
+/*---------------------------------------*/
+/* Prototypes for disk control functions */
+
+DSTATUS disk_initialize (void);
+DRESULT disk_readp (uint8_t*, DWORD, WORD, WORD);
+DRESULT disk_writep (const uint8_t*, DWORD);
+
+#define STA_NOINIT 0x01 /* Drive not initialized */
+#define STA_NODISK 0x02 /* No medium in the drive */
+
+/* Card type flags (CardType) */
+#define CT_MMC 0x01 /* MMC ver 3 */
+#define CT_SD1 0x02 /* SD ver 1 */
+#define CT_SD2 0x04 /* SD ver 2 */
+#define CT_SDC (CT_SD1|CT_SD2) /* SD */
+#define CT_BLOCK 0x08 /* Block addressing */
+
+#define _DISKIO
+#endif
diff --git a/src/FatFs/integer.h b/src/FatFs/integer.h
new file mode 100755
index 0000000..4dcd2dd
--- /dev/null
+++ b/src/FatFs/integer.h
@@ -0,0 +1,37 @@
+/*-------------------------------------------*/
+/* Integer type definitions for FatFs module */
+/*-------------------------------------------*/
+
+#ifndef _INTEGER
+
+#if 0
+#include <windows.h>
+#else
+
+/* These types must be 16-bit, 32-bit or larger integer */
+typedef int INT;
+typedef unsigned int UINT;
+
+/* These types must be 8-bit integer */
+typedef signed char CHAR;
+typedef unsigned char UCHAR;
+//typedef unsigned char uint8_t;
+
+/* These types must be 16-bit integer */
+typedef short SHORT;
+typedef unsigned short USHORT;
+typedef unsigned short WORD;
+typedef unsigned short WCHAR;
+
+/* These types must be 32-bit integer */
+typedef long LONG;
+typedef unsigned long ULONG;
+typedef unsigned long DWORD;
+
+/* Boolean type */
+typedef enum { FALSE = 0, TRUE } BOOL;
+
+#endif
+
+#define _INTEGER
+#endif
diff --git a/src/FatFs/pff.cpp b/src/FatFs/pff.cpp
new file mode 100755
index 0000000..8b2de72
--- /dev/null
+++ b/src/FatFs/pff.cpp
@@ -0,0 +1,845 @@
+/*----------------------------------------------------------------------------/
+/ Petit FatFs - FAT file system module R0.02 (C)ChaN, 2009
+/-----------------------------------------------------------------------------/
+/ Petit FatFs module is an open source software to implement FAT file system to
+/ small embedded systems. This is a free software and is opened for education,
+/ research and commercial developments under license policy of following trems.
+/
+/ Copyright (C) 2009, ChaN, all right reserved.
+/
+/ * The Petit FatFs module is a free software and there is NO WARRANTY.
+/ * No restriction on use. You can use, modify and redistribute it for
+/ personal, non-profit or commercial use UNDER YOUR RESPONSIBILITY.
+/ * Redistributions of source code must retain the above copyright notice.
+/
+/-----------------------------------------------------------------------------/
+/ Jun 15,'09 R0.01a First release. (Branched from FatFs R0.07b.)
+/
+/ Dec 14,'09 R0.02 Added multiple code page support.
+/ Added write funciton.
+/ Changed stream read mode interface.
+/----------------------------------------------------------------------------*/
+
+#include "pff.h" /* Petit FatFs configurations and declarations */
+#include "diskio.h" /* Declarations of low level disk I/O functions */
+#include <stdio.h>
+
+
+/*--------------------------------------------------------------------------
+
+ Private Functions
+
+---------------------------------------------------------------------------*/
+
+static
+FATFS *FatFs; /* Pointer to the file system object (logical drive) */
+
+
+
+/*-----------------------------------------------------------------------*/
+/* String functions */
+/*-----------------------------------------------------------------------*/
+
+/* Fill memory */
+static
+void mem_set (void* dst, int val, int cnt) {
+ char *d = (char*)dst;
+ while (cnt--) *d++ = (char)val;
+}
+
+/* Compare memory to memory */
+static
+int mem_cmp (const void* dst, const void* src, int cnt) {
+ const char *d = (const char *)dst, *s = (const char *)src;
+ int r = 0;
+ while (cnt-- && (r = *d++ - *s++) == 0) ;
+ return r;
+}
+
+
+
+/*-----------------------------------------------------------------------*/
+/* FAT access - Read value of a FAT entry */
+/*-----------------------------------------------------------------------*/
+
+static
+CLUST get_fat ( /* 1:IO error, Else:Cluster status */
+ CLUST clst /* Cluster# to get the link information */
+)
+{
+ WORD wc, bc, ofs;
+ uint8_t buf[4];
+ FATFS *fs = FatFs;
+
+
+ if (clst < 2 || clst >= fs->max_clust) /* Range check */
+ return 1;
+
+ switch (fs->fs_type) {
+ case FS_FAT12 :
+ bc = (WORD)clst; bc += bc / 2;
+ ofs = bc % 512; bc /= 512;
+ if (ofs != 511) {
+ if (disk_readp(buf, fs->fatbase + bc, ofs, 2)) break;
+ } else {
+ if (disk_readp(buf, fs->fatbase + bc, 511, 1)) break;
+ if (disk_readp(buf+1, fs->fatbase + bc + 1, 0, 1)) break;
+ }
+ wc = LD_WORD(buf);
+ return (clst & 1) ? (wc >> 4) : (wc & 0xFFF);
+
+ case FS_FAT16 :
+ if (disk_readp(buf, fs->fatbase + clst / 256, (WORD)(((WORD)clst % 256) * 2), 2)) break;
+ return LD_WORD(buf);
+#if _FS_FAT32
+ case FS_FAT32 :
+ if (disk_readp(buf, fs->fatbase + clst / 128, (WORD)(((WORD)clst % 128) * 4), 4)) break;
+ return LD_DWORD(buf) & 0x0FFFFFFF;
+#endif
+ }
+
+ return 1; /* An error occured at the disk I/O layer */
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Get sector# from cluster# */
+/*-----------------------------------------------------------------------*/
+
+static
+DWORD clust2sect ( /* !=0: Sector number, 0: Failed - invalid cluster# */
+ CLUST clst /* Cluster# to be converted */
+)
+{
+ FATFS *fs = FatFs;
+
+
+ clst -= 2;
+ if (clst >= (fs->max_clust - 2)) return 0; /* Invalid cluster# */
+ return (DWORD)clst * fs->csize + fs->database;
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Directory handling - Rewind directory index */
+/*-----------------------------------------------------------------------*/
+
+static
+FRESULT dir_rewind (
+ DIR *dj /* Pointer to directory object */
+)
+{
+ CLUST clst;
+ FATFS *fs = FatFs;
+
+
+ dj->index = 0;
+ clst = dj->sclust;
+ if (clst == 1 || clst >= fs->max_clust) /* Check start cluster range */
+ return FR_DISK_ERR;
+#if _FS_FAT32
+ if (!clst && fs->fs_type == FS_FAT32) /* Replace cluster# 0 with root cluster# if in FAT32 */
+ clst = fs->dirbase;
+#endif
+ dj->clust = clst; /* Current cluster */
+ dj->sect = clst ? clust2sect(clst) : fs->dirbase; /* Current sector */
+
+ return FR_OK; /* Seek succeeded */
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Directory handling - Move directory index next */
+/*-----------------------------------------------------------------------*/
+
+static
+FRESULT dir_next ( /* FR_OK:Succeeded, FR_NO_FILE:End of table */
+ DIR *dj /* Pointer to directory object */
+)
+{
+ CLUST clst;
+ WORD i;
+ FATFS *fs = FatFs;
+
+
+ i = dj->index + 1;
+ if (!i || !dj->sect) /* Report EOT when index has reached 65535 */
+ return FR_NO_FILE;
+
+ if (!(i & (16-1))) { /* Sector changed? */
+ dj->sect++; /* Next sector */
+
+ if (dj->clust == 0) { /* Static table */
+ if (i >= fs->n_rootdir) /* Report EOT when end of table */
+ return FR_NO_FILE;
+ }
+ else { /* Dynamic table */
+ if (((i / 16) & (fs->csize-1)) == 0) { /* Cluster changed? */
+ clst = get_fat(dj->clust); /* Get next cluster */
+ if (clst <= 1) return FR_DISK_ERR;
+ if (clst >= fs->max_clust) /* When it reached end of dynamic table */
+ return FR_NO_FILE; /* Report EOT */
+ dj->clust = clst; /* Initialize data for new cluster */
+ dj->sect = clust2sect(clst);
+ }
+ }
+ }
+
+ dj->index = i;
+
+ return FR_OK;
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Directory handling - Find an object in the directory */
+/*-----------------------------------------------------------------------*/
+
+static
+FRESULT dir_find (
+ DIR *dj /* Pointer to the directory object linked to the file name */
+)
+{
+ FRESULT res;
+ uint8_t c, *dir;
+
+
+ res = dir_rewind(dj); /* Rewind directory object */
+ if (res != FR_OK) return res;
+
+ dir = FatFs->buf;
+ do {
+ res = disk_readp(dir, dj->sect, (WORD)((dj->index % 16) * 32), 32) /* Read an entry */
+ ? FR_DISK_ERR : FR_OK;
+ if (res != FR_OK) break;
+ c = dir[DIR_Name]; /* First character */
+ if (c == 0) { res = FR_NO_FILE; break; } /* Reached to end of table */
+ if (!(dir[DIR_Attr] & AM_VOL) && !mem_cmp(dir, dj->fn, 11)) /* Is it a valid entry? */
+ break;
+ res = dir_next(dj); /* Next entry */
+ } while (res == FR_OK);
+
+ return res;
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Read an object from the directory */
+/*-----------------------------------------------------------------------*/
+#if _USE_DIR
+static
+FRESULT dir_read (
+ DIR *dj /* Pointer to the directory object to store read object name */
+)
+{
+ FRESULT res;
+ uint8_t a, c, *dir;
+
+
+ res = FR_NO_FILE;
+ dir = FatFs->buf;
+ while (dj->sect) {
+ res = disk_readp(dir, dj->sect, (WORD)((dj->index % 16) * 32), 32) /* Read an entry */
+ ? FR_DISK_ERR : FR_OK;
+ if (res != FR_OK) break;
+ c = dir[DIR_Name];
+ if (c == 0) { res = FR_NO_FILE; break; } /* Reached to end of table */
+ a = dir[DIR_Attr] & AM_MASK;
+ if (c != 0xE5 && c != '.' && !(a & AM_VOL)) /* Is it a valid entry? */
+ break;
+ res = dir_next(dj); /* Next entry */
+ if (res != FR_OK) break;
+ }
+
+ if (res != FR_OK) dj->sect = 0;
+
+ return res;
+}
+#endif
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Pick a segment and create the object name in directory form */
+/*-----------------------------------------------------------------------*/
+
+#ifdef _EXCVT
+ static const uint8_t cvt[] = _EXCVT;
+#endif
+
+static
+FRESULT create_name (
+ DIR *dj, /* Pointer to the directory object */
+ const char **path /* Pointer to pointer to the segment in the path string */
+)
+{
+ uint8_t c, d, ni, si, i, *sfn;
+ const char *p;
+
+ /* Create file name in directory form */
+ sfn = dj->fn;
+ mem_set(sfn, ' ', 11);
+ si = i = 0; ni = 8;
+ p = *path;
+ for (;;) {
+ c = p[si++];
+ if (c <= ' ' || c == '/') break; /* Break on end of segment */
+ if (c == '.' || i >= ni) {
+ if (ni != 8 || c != '.') break;
+ i = 8; ni = 11;
+ continue;
+ }
+#ifdef _EXCVT
+ if (c >= 0x80) /* To upper extended char (SBCS) */
+ c = cvt[c - 0x80];
+#endif
+ //if (IsDBCS1(c) && i >= ni - 1) { /* DBC 1st uint8_t? */
+ if (IsDBCS1(c) && i < ni - 1) { /* DBC 1st uint8_t? */
+ d = p[si++]; /* Get 2nd uint8_t */
+ sfn[i++] = c;
+ sfn[i++] = d;
+ } else { /* Single uint8_t code */
+ if (IsLower(c)) c -= 0x20; /* toupper */
+ sfn[i++] = c;
+ }
+ }
+ *path = &p[si]; /* Rerurn pointer to the next segment */
+
+ sfn[11] = (c <= ' ') ? 1 : 0; /* Set last segment flag if end of path */
+
+ return FR_OK;
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Get file information from directory entry */
+/*-----------------------------------------------------------------------*/
+#if _USE_DIR
+static
+void get_fileinfo ( /* No return code */
+ DIR *dj, /* Pointer to the directory object */
+ FILINFO *fno /* Pointer to store the file information */
+)
+{
+ uint8_t i, c, *dir;
+ char *p;
+
+
+ p = fno->fname;
+ if (dj->sect) {
+ dir = FatFs->buf;
+ for (i = 0; i < 8; i++) { /* Copy file name body */
+ c = dir[i];
+ if (c == ' ') break;
+ if (c == 0x05) c = 0xE5;
+ *p++ = c;
+ }
+ if (dir[8] != ' ') { /* Copy file name extension */
+ *p++ = '.';
+ for (i = 8; i < 11; i++) {
+ c = dir[i];
+ if (c == ' ') break;
+ *p++ = c;
+ }
+ }
+ fno->fattrib = dir[DIR_Attr]; /* Attribute */
+ fno->fsize = LD_DWORD(dir+DIR_FileSize); /* Size */
+ fno->fdate = LD_WORD(dir+DIR_WrtDate); /* Date */
+ fno->ftime = LD_WORD(dir+DIR_WrtTime); /* Time */
+ }
+ *p = 0;
+}
+#endif /* _USE_DIR */
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Follow a file path */
+/*-----------------------------------------------------------------------*/
+
+static
+FRESULT follow_path ( /* FR_OK(0): successful, !=0: error code */
+ DIR *dj, /* Directory object to return last directory and found object */
+ const char *path /* Full-path string to find a file or directory */
+)
+{
+ FRESULT res;
+ uint8_t *dir;
+
+
+ while (*path == ' ') path++; /* Skip leading spaces */
+ if (*path == '/') path++; /* Strip heading separator */
+ dj->sclust = 0; /* Set start directory (always root dir) */
+
+ if ((uint8_t)*path <= ' ') { /* Null path means the root directory */
+ res = dir_rewind(dj);
+ FatFs->buf[0] = 0;
+
+ } else { /* Follow path */
+ for (;;) {
+ res = create_name(dj, &path); /* Get a segment */
+ if (res != FR_OK) break;
+ res = dir_find(dj); /* Find it */
+ if (res != FR_OK) { /* Could not find the object */
+ if (res == FR_NO_FILE && !*(dj->fn+11))
+ res = FR_NO_PATH;
+ break;
+ }
+ if (*(dj->fn+11)) break; /* Last segment match. Function completed. */
+ dir = FatFs->buf; /* There is next segment. Follow the sub directory */
+ if (!(dir[DIR_Attr] & AM_DIR)) { /* Cannot follow because it is a file */
+ res = FR_NO_PATH; break;
+ }
+ dj->sclust =
+#if _FS_FAT32
+ ((DWORD)LD_WORD(dir+DIR_FstClusHI) << 16) |
+#endif
+ LD_WORD(dir+DIR_FstClusLO);
+ }
+ }
+
+ return res;
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Check a sector if it is an FAT boot record */
+/*-----------------------------------------------------------------------*/
+
+static
+uint8_t check_fs ( /* 0:The FAT boot record, 1:Valid boot record but not an FAT, 2:Not a boot record, 3:Error */
+ uint8_t *buf, /* Working buffer */
+ DWORD sect /* Sector# (lba) to check if it is an FAT boot record or not */
+)
+{
+ if (disk_readp(buf, sect, 510, 2)) /* Read the boot sector */
+ return 3;
+ if (LD_WORD(buf) != 0xAA55) /* Check record signature */
+ return 2;
+
+ if (!disk_readp(buf, sect, BS_FilSysType, 2) && LD_WORD(buf) == 0x4146) /* Check FAT12/16 */
+ return 0;
+#if _FS_FAT32
+ if (!disk_readp(buf, sect, BS_FilSysType32, 2) && LD_WORD(buf) == 0x4146) /* Check FAT32 */
+ return 0;
+#endif
+ return 1;
+}
+
+
+
+
+/*--------------------------------------------------------------------------
+
+ Public Functions
+
+--------------------------------------------------------------------------*/
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Mount/Unmount a Locical Drive */
+/*-----------------------------------------------------------------------*/
+
+FRESULT pf_mount (
+ FATFS *fs /* Pointer to new file system object (NULL: Unmount) */
+)
+{
+ uint8_t fmt, buf[36];
+ DWORD bsect, fsize, tsect, mclst;
+
+
+ FatFs = 0;
+ if (!fs) return FR_OK; /* Unregister fs object */
+
+ if (disk_initialize() & STA_NOINIT) /* Check if the drive is ready or not */
+ return FR_NOT_READY;
+
+ /* Search FAT partition on the drive */
+ bsect = 0;
+ fmt = check_fs(buf, bsect); /* Check sector 0 as an SFD format */
+ if (fmt == 1) { /* Not an FAT boot record, it may be FDISK format */
+ /* Check a partition listed in top of the partition table */
+ if (disk_readp(buf, bsect, MBR_Table, 16)) { /* 1st partition entry */
+ fmt = 3;
+ } else {
+ if (buf[4]) { /* Is the partition existing? */
+ bsect = LD_DWORD(&buf[8]); /* Partition offset in LBA */
+ fmt = check_fs(buf, bsect); /* Check the partition */
+ }
+ }
+ }
+ if (fmt == 3) return FR_DISK_ERR;
+ if (fmt) return FR_NO_FILESYSTEM; /* No valid FAT patition is found */
+
+ /* Initialize the file system object */
+ if (disk_readp(buf, bsect, 13, sizeof(buf))) return FR_DISK_ERR;
+
+ fsize = LD_WORD(buf+BPB_FATSz16-13); /* Number of sectors per FAT */
+ if (!fsize) fsize = LD_DWORD(buf+BPB_FATSz32-13);
+
+ fsize *= buf[BPB_NumFATs-13]; /* Number of sectors in FAT area */
+ fs->fatbase = bsect + LD_WORD(buf+BPB_RsvdSecCnt-13); /* FAT start sector (lba) */
+ fs->csize = buf[BPB_SecPerClus-13]; /* Number of sectors per cluster */
+ fs->n_rootdir = LD_WORD(buf+BPB_RootEntCnt-13); /* Nmuber of root directory entries */
+ tsect = LD_WORD(buf+BPB_TotSec16-13); /* Number of sectors on the file system */
+ if (!tsect) tsect = LD_DWORD(buf+BPB_TotSec32-13);
+ mclst = (tsect /* Last cluster# + 1 */
+ - LD_WORD(buf+BPB_RsvdSecCnt-13) - fsize - fs->n_rootdir / 16
+ ) / fs->csize + 2;
+ fs->max_clust = (CLUST)mclst;
+
+ fmt = FS_FAT12; /* Determine the FAT sub type */
+ if (mclst >= 0xFF7) fmt = FS_FAT16; /* Number of clusters >= 0xFF5 */
+ if (mclst >= 0xFFF7) /* Number of clusters >= 0xFFF5 */
+#if _FS_FAT32
+ fmt = FS_FAT32;
+#else
+ return FR_NO_FILESYSTEM;
+#endif
+
+ fs->fs_type = fmt; /* FAT sub-type */
+#if _FS_FAT32
+ if (fmt == FS_FAT32)
+ fs->dirbase = LD_DWORD(buf+(BPB_RootClus-13)); /* Root directory start cluster */
+ else
+#endif
+ fs->dirbase = fs->fatbase + fsize; /* Root directory start sector (lba) */
+ fs->database = fs->fatbase + fsize + fs->n_rootdir / 16; /* Data start sector (lba) */
+
+ fs->flag = 0;
+ FatFs = fs;
+
+ return FR_OK;
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Open or Create a File */
+/*-----------------------------------------------------------------------*/
+
+FRESULT pf_open (
+ const char *path /* Pointer to the file name */
+)
+{
+ FRESULT res;
+ DIR dj;
+ uint8_t sp[12], dir[32];
+ FATFS *fs = FatFs;
+
+
+ if (!fs) /* Check file system */
+ return FR_NOT_ENABLED;
+
+ fs->flag = 0;
+ fs->buf = dir;
+ dj.fn = sp;
+ res = follow_path(&dj, path); /* Follow the file path */
+ if (res != FR_OK) return res; /* Follow failed */
+ if (!dir[0] || (dir[DIR_Attr] & AM_DIR)) /* It is a directory */
+ return FR_NO_FILE;
+
+ fs->org_clust = /* File start cluster */
+#if _FS_FAT32
+ ((DWORD)LD_WORD(dir+DIR_FstClusHI) << 16) |
+#endif
+ LD_WORD(dir+DIR_FstClusLO);
+ fs->fsize = LD_DWORD(dir+DIR_FileSize); /* File size */
+ fs->fptr = 0; /* File pointer */
+ fs->flag = FA_OPENED;
+
+ return FR_OK;
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Read File */
+/*-----------------------------------------------------------------------*/
+#if _USE_READ
+
+FRESULT pf_read (
+ void* buff, /* Pointer to the read buffer (NULL:Forward data to the stream)*/
+ WORD btr, /* Number of uint8_ts to read */
+ WORD* br /* Pointer to number of uint8_ts read */
+)
+{
+ DRESULT dr;
+ CLUST clst;
+ DWORD sect, remain;
+ uint8_t *rbuff = (uint8_t *)buff;
+ WORD rcnt;
+ FATFS *fs = FatFs;
+
+
+ *br = 0;
+ if (!fs) return FR_NOT_ENABLED; /* Check file system */
+ if (!(fs->flag & FA_OPENED)) /* Check if opened */
+ return FR_NOT_OPENED;
+
+ remain = fs->fsize - fs->fptr;
+ if (btr > remain) btr = (WORD)remain; /* Truncate btr by remaining uint8_ts */
+
+ while (btr) { /* Repeat until all data transferred */
+ if ((fs->fptr % 512) == 0) { /* On the sector boundary? */
+ if ((fs->fptr / 512 % fs->csize) == 0) { /* On the cluster boundary? */
+ clst = (fs->fptr == 0) ? /* On the top of the file? */
+ fs->org_clust : get_fat(fs->curr_clust);
+ if (clst <= 1) goto fr_abort;
+ fs->curr_clust = clst; /* Update current cluster */
+ fs->csect = 0; /* Reset sector offset in the cluster */
+ }
+ sect = clust2sect(fs->curr_clust); /* Get current sector */
+ if (!sect) goto fr_abort;
+ fs->dsect = sect + fs->csect++;
+ }
+ rcnt = 512 - ((WORD)fs->fptr % 512); /* Get partial sector data from sector buffer */
+ if (rcnt > btr) rcnt = btr;
+ dr = disk_readp(!buff ? 0 : rbuff, fs->dsect, (WORD)(fs->fptr % 512), rcnt);
+ if (dr) goto fr_abort;
+ fs->fptr += rcnt; rbuff += rcnt; /* Update pointers and counters */
+ btr -= rcnt; *br += rcnt;
+ }
+
+ return FR_OK;
+
+fr_abort:
+ fs->flag = 0;
+ return FR_DISK_ERR;
+}
+#endif
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Write File */
+/*-----------------------------------------------------------------------*/
+#if _USE_WRITE
+
+FRESULT pf_write (
+ const void* buff, /* Pointer to the data to be written */
+ WORD btw, /* Number of uint8_ts to write (0:Finalize the current write operation) */
+ WORD* bw /* Pointer to number of uint8_ts written */
+)
+{
+ CLUST clst;
+ DWORD sect, remain;
+ const uint8_t *p = (uint8_t *)buff;
+ WORD wcnt;
+ FATFS *fs = FatFs;
+
+
+ *bw = 0;
+ if (!fs) return FR_NOT_ENABLED; /* Check file system */
+ if (!(fs->flag & FA_OPENED)) /* Check if opened */
+ return FR_NOT_OPENED;
+
+ if (!btw) { /* Finalize request */
+ if ((fs->flag & FA__WIP) && disk_writep(0, 0)) goto fw_abort;
+ fs->flag &= ~FA__WIP;
+ return FR_OK;
+ } else { /* Write data request */
+ if (!(fs->flag & FA__WIP)) /* Round down fptr to the sector boundary */
+ fs->fptr &= 0xFFFFFE00;
+ }
+ remain = fs->fsize - fs->fptr;
+ if (btw > remain) btw = (WORD)remain; /* Truncate btw by remaining uint8_ts */
+
+ while (btw) { /* Repeat until all data transferred */
+ if (((WORD)fs->fptr % 512) == 0) { /* On the sector boundary? */
+ if ((fs->fptr / 512 % fs->csize) == 0) { /* On the cluster boundary? */
+ clst = (fs->fptr == 0) ? /* On the top of the file? */
+ fs->org_clust : get_fat(fs->curr_clust);
+ if (clst <= 1) goto fw_abort;
+ fs->curr_clust = clst; /* Update current cluster */
+ fs->csect = 0; /* Reset sector offset in the cluster */
+ }
+ sect = clust2sect(fs->curr_clust); /* Get current sector */
+ if (!sect) goto fw_abort;
+ fs->dsect = sect + fs->csect++;
+ if (disk_writep(0, fs->dsect)) goto fw_abort; /* Initiate a sector write operation */
+ fs->flag |= FA__WIP;
+ }
+ wcnt = 512 - ((WORD)fs->fptr % 512); /* Number of uint8_ts to write to the sector */
+ if (wcnt > btw) wcnt = btw;
+ if (disk_writep(p, wcnt)) goto fw_abort; /* Send data to the sector */
+ fs->fptr += wcnt; p += wcnt; /* Update pointers and counters */
+ btw -= wcnt; *bw += wcnt;
+ if (((WORD)fs->fptr % 512) == 0) {
+ if (disk_writep(0, 0)) goto fw_abort; /* Finalize the currtent secter write operation */
+ fs->flag &= ~FA__WIP;
+ }
+ }
+
+ return FR_OK;
+
+fw_abort:
+ fs->flag = 0;
+ return FR_DISK_ERR;
+}
+#endif
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Seek File R/W Pointer */
+/*-----------------------------------------------------------------------*/
+#if _USE_LSEEK
+
+FRESULT pf_lseek (
+ DWORD ofs /* File pointer from top of file */
+)
+{
+ CLUST clst;
+ DWORD bcs, sect, ifptr;
+ FATFS *fs = FatFs;
+
+
+ if (!fs) return FR_NOT_ENABLED; /* Check file system */
+ if (!(fs->flag & FA_OPENED)) /* Check if opened */
+ return FR_NOT_OPENED;
+
+ if (ofs > fs->fsize) ofs = fs->fsize; /* Clip offset with the file size */
+ ifptr = fs->fptr;
+ fs->fptr = 0;
+ if (ofs > 0) {
+ bcs = (DWORD)fs->csize * 512; /* Cluster size (uint8_t) */
+ if (ifptr > 0 &&
+ (ofs - 1) / bcs >= (ifptr - 1) / bcs) { /* When seek to same or following cluster, */
+ fs->fptr = (ifptr - 1) & ~(bcs - 1); /* start from the current cluster */
+ ofs -= fs->fptr;
+ clst = fs->curr_clust;
+ } else { /* When seek to back cluster, */
+ clst = fs->org_clust; /* start from the first cluster */
+ fs->curr_clust = clst;
+ }
+ while (ofs > bcs) { /* Cluster following loop */
+ clst = get_fat(clst); /* Follow cluster chain */
+ if (clst <= 1 || clst >= fs->max_clust) goto fe_abort;
+ fs->curr_clust = clst;
+ fs->fptr += bcs;
+ ofs -= bcs;
+ }
+ fs->fptr += ofs;
+ sect = clust2sect(clst); /* Current sector */
+ if (!sect) goto fe_abort;
+ fs->csect = (uint8_t)(ofs / 512); /* Sector offset in the cluster */
+ if (ofs % 512)
+ fs->dsect = sect + fs->csect++;
+ }
+
+ return FR_OK;
+
+fe_abort:
+ fs->flag = 0;
+ return FR_DISK_ERR;
+}
+#endif
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Create a Directroy Object */
+/*-----------------------------------------------------------------------*/
+#if _USE_DIR
+
+FRESULT pf_opendir (
+ DIR *dj, /* Pointer to directory object to create */
+ const char *path /* Pointer to the directory path */
+)
+{
+ FRESULT res;
+ uint8_t sp[12], dir[32];
+ FATFS *fs = FatFs;
+
+
+ if (!fs) { /* Check file system */
+ res = FR_NOT_ENABLED;
+ } else {
+ fs->buf = dir;
+ dj->fn = sp;
+ res = follow_path(dj, path); /* Follow the path to the directory */
+ if (res == FR_OK) { /* Follow completed */
+ if (dir[0]) { /* It is not the root dir */
+ if (dir[DIR_Attr] & AM_DIR) { /* The object is a directory */
+ dj->sclust =
+#if _FS_FAT32
+ ((DWORD)LD_WORD(dir+DIR_FstClusHI) << 16) |
+#endif
+ LD_WORD(dir+DIR_FstClusLO);
+ } else { /* The object is not a directory */
+ res = FR_NO_PATH;
+ }
+ }
+ if (res == FR_OK)
+ res = dir_rewind(dj); /* Rewind dir */
+ }
+ if (res == FR_NO_FILE) res = FR_NO_PATH;
+ }
+
+ return res;
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Read Directory Entry in Sequense */
+/*-----------------------------------------------------------------------*/
+
+FRESULT pf_readdir (
+ DIR *dj, /* Pointer to the open directory object */
+ FILINFO *fno /* Pointer to file information to return */
+)
+{
+ FRESULT res;
+ uint8_t sp[12], dir[32];
+ FATFS *fs = FatFs;
+
+
+ if (!fs) { /* Check file system */
+ res = FR_NOT_ENABLED;
+ } else {
+ fs->buf = dir;
+ dj->fn = sp;
+ if (!fno) {
+ res = dir_rewind(dj);
+ } else {
+ res = dir_read(dj);
+ if (res == FR_NO_FILE) {
+ dj->sect = 0;
+ res = FR_OK;
+ }
+ if (res == FR_OK) { /* A valid entry is found */
+ get_fileinfo(dj, fno); /* Get the object information */
+ res = dir_next(dj); /* Increment index for next */
+ if (res == FR_NO_FILE) {
+ dj->sect = 0;
+ res = FR_OK;
+ }
+ }
+ }
+ }
+
+ return res;
+}
+
+#endif /* _USE_DIR */
+
diff --git a/src/FatFs/pff.h b/src/FatFs/pff.h
new file mode 100755
index 0000000..e28542c
--- /dev/null
+++ b/src/FatFs/pff.h
@@ -0,0 +1,469 @@
+/*---------------------------------------------------------------------------/
+/ Petit FatFs - FAT file system module include file R0.02 (C)ChaN, 2009
+/----------------------------------------------------------------------------/
+/ Petit FatFs module is an open source software to implement FAT file system to
+/ small embedded systems. This is a free software and is opened for education,
+/ research and commercial developments under license policy of following trems.
+/
+/ Copyright (C) 2009, ChaN, all right reserved.
+/
+/ * The Petit FatFs module is a free software and there is NO WARRANTY.
+/ * No restriction on use. You can use, modify and redistribute it for
+/ personal, non-profit or commercial use UNDER YOUR RESPONSIBILITY.
+/ * Redistributions of source code must retain the above copyright notice.
+/
+/----------------------------------------------------------------------------*/
+
+#include "integer.h"
+#include <stdint.h>
+#include <libmary.h>
+/*---------------------------------------------------------------------------/
+/ Petit FatFs Configuration Options
+/
+/ CAUTION! Do not forget to make clean the project after any changes to
+/ the configuration options.
+/
+/----------------------------------------------------------------------------*/
+#ifndef _FATFS
+#define _FATFS
+
+#define _USE_READ 1 /* pf_read(): 0:Remove ,1:Enable */
+
+#define _USE_DIR 1 /* pf_opendir() and pf_readdir(): 0:Remove ,1:Enable */
+
+#define _USE_LSEEK 1 /* pf_lseek(): 0:Remove ,1:Enable */
+
+#define _USE_WRITE 1 /* pf_write(): 0:Remove ,1:Enable */
+
+#define _FS_FAT32 1 /* 0:Supports FAT12/16 only, 1:Enable FAT32 supprt */
+
+
+#define _CODE_PAGE 1
+/* Defines which code page is used for path name. Supported code pages are:
+/ 932, 936, 949, 950, 437, 720, 737, 775, 850, 852, 855, 857, 858, 862, 866,
+/ 874, 1250, 1251, 1252, 1253, 1254, 1255, 1257, 1258 and 1 (ASCII only).
+/ SBCS configurations except for 1 requiers a case conversion table. This
+/ might occupy 128 bytes on the RAM on some platforms, e.g. avr-gcc. */
+
+
+#define _WORD_ACCESS 0 // 1
+/* The _WORD_ACCESS option defines which access method is used to the word
+/ data in the FAT structure.
+/
+/ 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 efficiency. */
+
+
+/* End of configuration options. Do not change followings without care. */
+/*--------------------------------------------------------------------------*/
+
+
+
+#if _FS_FAT32
+#define CLUST DWORD
+#else
+#define CLUST WORD
+#endif
+
+
+/* File system object structure */
+
+typedef struct _FATFS_ {
+ uint8_t fs_type; /* FAT sub type */
+ uint8_t csize; /* Number of sectors per cluster */
+ uint8_t flag; /* File status flags */
+ uint8_t csect; /* File sector address in the cluster */
+ WORD n_rootdir; /* Number of root directory entries (0 on FAT32) */
+ uint8_t* buf; /* Pointer to the disk access buffer */
+ CLUST max_clust; /* Maximum cluster# + 1. Number of clusters is max_clust - 2 */
+ DWORD fatbase; /* FAT start sector */
+ DWORD dirbase; /* Root directory start sector (Cluster# on FAT32) */
+ DWORD database; /* Data start sector */
+ DWORD fptr; /* File R/W pointer */
+ DWORD fsize; /* File size */
+ CLUST org_clust; /* File start cluster */
+ CLUST curr_clust; /* File current cluster */
+ DWORD dsect; /* File current data sector */
+} FATFS;
+
+
+
+/* Directory object structure */
+
+typedef struct _DIR_ {
+ WORD index; /* Current read/write index number */
+ uint8_t* fn; /* Pointer to the SFN (in/out) {file[8],ext[3],status[1]} */
+ CLUST sclust; /* Table start cluster (0:Static table) */
+ CLUST clust; /* Current cluster */
+ DWORD sect; /* Current sector */
+} DIR;
+
+
+
+/* File status structure */
+
+typedef struct _FILINFO_ {
+ DWORD fsize; /* File size */
+ WORD fdate; /* Last modified date */
+ WORD ftime; /* Last modified time */
+ uint8_t fattrib; /* Attribute */
+ char fname[13]; /* File name */
+} FILINFO;
+
+
+
+/* File function return code (FRESULT) */
+
+typedef enum {
+ FR_OK = 0, /* 0 */
+ FR_DISK_ERR, /* 1 */
+ FR_NOT_READY, /* 2 */
+ FR_NO_FILE, /* 3 */
+ FR_NO_PATH, /* 4 */
+ FR_NOT_OPENED, /* 5 */
+ FR_NOT_ENABLED, /* 6 */
+ FR_NO_FILESYSTEM /* 7 */
+} FRESULT;
+
+
+
+/*--------------------------------------------------------------*/
+/* Petit FatFs module application interface */
+
+FRESULT pf_mount (FATFS*); /* Mount/Unmount a logical drive */
+FRESULT pf_open (const char*); /* Open a file */
+FRESULT pf_read (void*, WORD, WORD*); /* Read data from the open file */
+FRESULT pf_write (const void*, WORD, WORD*); /* Write data to the open file */
+FRESULT pf_lseek (DWORD); /* Move file pointer of the open file */
+FRESULT pf_opendir (DIR*, const char*); /* Open a directory */
+FRESULT pf_readdir (DIR*, FILINFO*); /* Read a directory item from the open directory */
+
+
+
+/*--------------------------------------------------------------*/
+/* Flags and offset address */
+
+/* File status flag (FATFS.flag) */
+
+#define FA_OPENED 0x01
+#define FA_WPRT 0x02
+#define FA__WIP 0x40
+
+
+/* FAT sub type (FATFS.fs_type) */
+
+#define FS_FAT12 1
+#define FS_FAT16 2
+#define FS_FAT32 3
+
+
+/* File attribute bits for directory entry */
+
+#define AM_RDO 0x01 /* Read only */
+#define AM_HID 0x02 /* Hidden */
+#define AM_SYS 0x04 /* System */
+#define AM_VOL 0x08 /* Volume label */
+#define AM_LFN 0x0F /* LFN entry */
+#define AM_DIR 0x10 /* Directory */
+#define AM_ARC 0x20 /* Archive */
+#define AM_MASK 0x3F /* Mask of defined bits */
+
+
+/* FatFs refers the members in the FAT structures with uint8_t offset instead
+/ of structure member because there are incompatibility of the packing option
+/ between various compilers. */
+
+#define BS_jmpBoot 0
+#define BS_OEMName 3
+#define BPB_BytsPerSec 11
+#define BPB_SecPerClus 13
+#define BPB_RsvdSecCnt 14
+#define BPB_NumFATs 16
+#define BPB_RootEntCnt 17
+#define BPB_TotSec16 19
+#define BPB_Media 21
+#define BPB_FATSz16 22
+#define BPB_SecPerTrk 24
+#define BPB_NumHeads 26
+#define BPB_HiddSec 28
+#define BPB_TotSec32 32
+#define BS_55AA 510
+
+#define BS_DrvNum 36
+#define BS_BootSig 38
+#define BS_VolID 39
+#define BS_VolLab 43
+#define BS_FilSysType 54
+
+#define BPB_FATSz32 36
+#define BPB_ExtFlags 40
+#define BPB_FSVer 42
+#define BPB_RootClus 44
+#define BPB_FSInfo 48
+#define BPB_BkBootSec 50
+#define BS_DrvNum32 64
+#define BS_BootSig32 66
+#define BS_VolID32 67
+#define BS_VolLab32 71
+#define BS_FilSysType32 82
+
+#define MBR_Table 446
+
+#define DIR_Name 0
+#define DIR_Attr 11
+#define DIR_NTres 12
+#define DIR_CrtTime 14
+#define DIR_CrtDate 16
+#define DIR_FstClusHI 20
+#define DIR_WrtTime 22
+#define DIR_WrtDate 24
+#define DIR_FstClusLO 26
+#define DIR_FileSize 28
+
+
+
+/*--------------------------------*/
+/* Multi-uint8_t word access macros */
+
+#if _WORD_ACCESS == 1 /* Enable word access to the FAT structure */
+#define LD_WORD(ptr) (WORD)(*(WORD*)(uint8_t*)(ptr))
+#define LD_DWORD(ptr) (DWORD)(*(DWORD*)(uint8_t*)(ptr))
+#define ST_WORD(ptr,val) *(WORD*)(uint8_t*)(ptr)=(WORD)(val)
+#define ST_DWORD(ptr,val) *(DWORD*)(uint8_t*)(ptr)=(DWORD)(val)
+#else /* Use uint8_t-by-uint8_t access to the FAT structure */
+#define LD_WORD(ptr) (WORD)(((WORD)*(uint8_t*)((ptr)+1)<<8)|(WORD)*(uint8_t*)(ptr))
+#define LD_DWORD(ptr) (DWORD)(((DWORD)*(uint8_t*)((ptr)+3)<<24)|((DWORD)*(uint8_t*)((ptr)+2)<<16)|((WORD)*(uint8_t*)((ptr)+1)<<8)|*(uint8_t*)(ptr))
+#define ST_WORD(ptr,val) *(uint8_t*)(ptr)=(uint8_t)(val); *(uint8_t*)((ptr)+1)=(uint8_t)((WORD)(val)>>8)
+#define ST_DWORD(ptr,val) *(uint8_t*)(ptr)=(uint8_t)(val); *(uint8_t*)((ptr)+1)=(uint8_t)((WORD)(val)>>8); *(uint8_t*)((ptr)+2)=(uint8_t)((DWORD)(val)>>16); *(uint8_t*)((ptr)+3)=(uint8_t)((DWORD)(val)>>24)
+#endif
+
+
+/*--------------------------------------------------------*/
+/* DBCS code ranges and SBCS extend char conversion table */
+
+#if _CODE_PAGE == 932 /* Japanese Shift-JIS */
+#define _DF1S 0x81 /* DBC 1st uint8_t range 1 start */
+#define _DF1E 0x9F /* DBC 1st uint8_t range 1 end */
+#define _DF2S 0xE0 /* DBC 1st uint8_t range 2 start */
+#define _DF2E 0xFC /* DBC 1st uint8_t range 2 end */
+#define _DS1S 0x40 /* DBC 2nd uint8_t range 1 start */
+#define _DS1E 0x7E /* DBC 2nd uint8_t range 1 end */
+#define _DS2S 0x80 /* DBC 2nd uint8_t range 2 start */
+#define _DS2E 0xFC /* DBC 2nd uint8_t range 2 end */
+
+#elif _CODE_PAGE == 936 /* Simplified Chinese GBK */
+#define _DF1S 0x81
+#define _DF1E 0xFE
+#define _DS1S 0x40
+#define _DS1E 0x7E
+#define _DS2S 0x80
+#define _DS2E 0xFE
+
+#elif _CODE_PAGE == 949 /* Korean */
+#define _DF1S 0x81
+#define _DF1E 0xFE
+#define _DS1S 0x41
+#define _DS1E 0x5A
+#define _DS2S 0x61
+#define _DS2E 0x7A
+#define _DS3S 0x81
+#define _DS3E 0xFE
+
+#elif _CODE_PAGE == 950 /* Traditional Chinese Big5 */
+#define _DF1S 0x81
+#define _DF1E 0xFE
+#define _DS1S 0x40
+#define _DS1E 0x7E
+#define _DS2S 0xA1
+#define _DS2E 0xFE
+
+#elif _CODE_PAGE == 437 /* U.S. (OEM) */
+#define _DF1S 0
+#define _EXCVT {0x80,0x9A,0x90,0x41,0x8E,0x41,0x8F,0x80,0x45,0x45,0x45,0x49,0x49,0x49,0x8E,0x8F,0x90,0x92,0x92,0x4F,0x99,0x4F,0x55,0x55,0x59,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
+ 0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
+ 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
+
+#elif _CODE_PAGE == 720 /* Arabic (OEM) */
+#define _DF1S 0
+#define _EXCVT {0x80,0x81,0x45,0x41,0x84,0x41,0x86,0x43,0x45,0x45,0x45,0x49,0x49,0x8D,0x8E,0x8F,0x90,0x92,0x92,0x93,0x94,0x95,0x49,0x49,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
+ 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
+ 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
+
+#elif _CODE_PAGE == 737 /* Greek (OEM) */
+#define _DF1S 0
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x92,0x92,0x93,0x94,0x95,0x96,0x97,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87, \
+ 0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0xAA,0x92,0x93,0x94,0x95,0x96,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
+ 0x97,0xEA,0xEB,0xEC,0xE4,0xED,0xEE,0xE7,0xE8,0xF1,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
+
+#elif _CODE_PAGE == 775 /* Baltic (OEM) */
+#define _DF1S 0
+#define _EXCVT {0x80,0x9A,0x91,0xA0,0x8E,0x95,0x8F,0x80,0xAD,0xED,0x8A,0x8A,0xA1,0x8D,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0x95,0x96,0x97,0x97,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \
+ 0xA0,0xA1,0xE0,0xA3,0xA3,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xB5,0xB6,0xB7,0xB8,0xBD,0xBE,0xC6,0xC7,0xA5,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
+ 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE3,0xE8,0xE8,0xEA,0xEA,0xEE,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
+
+#elif _CODE_PAGE == 850 /* Multilingual Latin 1 (OEM) */
+#define _DF1S 0
+#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0xDE,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x59,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \
+ 0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
+ 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE7,0xE9,0xEA,0xEB,0xED,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
+
+#elif _CODE_PAGE == 852 /* Latin 2 (OEM) */
+#define _DF1S 0
+#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xDE,0x8F,0x80,0x9D,0xD3,0x8A,0x8A,0xD7,0x8D,0x8E,0x8F,0x90,0x91,0x91,0xE2,0x99,0x95,0x95,0x97,0x97,0x99,0x9A,0x9B,0x9B,0x9D,0x9E,0x9F, \
+ 0xB5,0xD6,0xE0,0xE9,0xA4,0xA4,0xA6,0xA6,0xA8,0xA8,0xAA,0x8D,0xAC,0xB8,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBD,0xBF, \
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC6,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD2,0xD3,0xD2,0xD5,0xD6,0xD7,0xB7,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
+ 0xE0,0xE1,0xE2,0xE3,0xE3,0xD5,0xE6,0xE6,0xE8,0xE9,0xE8,0xEB,0xED,0xED,0xDD,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xEB,0xFC,0xFC,0xFE,0xFF}
+
+#elif _CODE_PAGE == 855 /* Cyrillic (OEM) */
+#define _DF1S 0
+#define _EXCVT {0x81,0x81,0x83,0x83,0x85,0x85,0x87,0x87,0x89,0x89,0x8B,0x8B,0x8D,0x8D,0x8F,0x8F,0x91,0x91,0x93,0x93,0x95,0x95,0x97,0x97,0x99,0x99,0x9B,0x9B,0x9D,0x9D,0x9F,0x9F, \
+ 0xA1,0xA1,0xA3,0xA3,0xA5,0xA5,0xA7,0xA7,0xA9,0xA9,0xAB,0xAB,0xAD,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB6,0xB6,0xB8,0xB8,0xB9,0xBA,0xBB,0xBC,0xBE,0xBE,0xBF, \
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD3,0xD3,0xD5,0xD5,0xD7,0xD7,0xDD,0xD9,0xDA,0xDB,0xDC,0xDD,0xE0,0xDF, \
+ 0xE0,0xE2,0xE2,0xE4,0xE4,0xE6,0xE6,0xE8,0xE8,0xEA,0xEA,0xEC,0xEC,0xEE,0xEE,0xEF,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF8,0xFA,0xFA,0xFC,0xFC,0xFD,0xFE,0xFF}
+
+#elif _CODE_PAGE == 857 /* Turkish (OEM) */
+#define _DF1S 0
+#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0x98,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x98,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9E, \
+ 0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA6,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
+ 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xDE,0x59,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
+
+#elif _CODE_PAGE == 858 /* Multilingual Latin 1 + Euro (OEM) */
+#define _DF1S 0
+#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0xDE,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x59,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \
+ 0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
+ 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE7,0xE9,0xEA,0xEB,0xED,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
+
+#elif _CODE_PAGE == 862 /* Hebrew (OEM) */
+#define _DF1S 0
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
+ 0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
+ 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
+
+#elif _CODE_PAGE == 866 /* Russian (OEM) */
+#define _DF1S 0
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
+ 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
+ 0x90,0x91,0x92,0x93,0x9d,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,0xF0,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
+
+#elif _CODE_PAGE == 874 /* Thai (OEM, Windows) */
+#define _DF1S 0
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
+ 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
+ 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
+
+#elif _CODE_PAGE == 1250 /* Central Europe (Windows) */
+#define _DF1S 0
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x8D,0x8E,0x8F, \
+ 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xA3,0xB4,0xB5,0xB6,0xB7,0xB8,0xA5,0xAA,0xBB,0xBC,0xBD,0xBC,0xAF, \
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF}
+
+#elif _CODE_PAGE == 1251 /* Cyrillic (Windows) */
+#define _DF1S 0
+#define _EXCVT {0x80,0x81,0x82,0x82,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x80,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x8D,0x8E,0x8F, \
+ 0xA0,0xA2,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB2,0xA5,0xB5,0xB6,0xB7,0xA8,0xB9,0xAA,0xBB,0xA3,0xBD,0xBD,0xAF, \
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF}
+
+#elif _CODE_PAGE == 1252 /* Latin 1 (Windows) */
+#define _DF1S 0
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0xAd,0x9B,0x8C,0x9D,0xAE,0x9F, \
+ 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0x9F}
+
+#elif _CODE_PAGE == 1253 /* Greek (Windows) */
+#define _DF1S 0
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
+ 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xA2,0xB8,0xB9,0xBA, \
+ 0xE0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xF2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xFB,0xBC,0xFD,0xBF,0xFF}
+
+#elif _CODE_PAGE == 1254 /* Turkish (Windows) */
+#define _DF1S 0
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x9D,0x9E,0x9F, \
+ 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0x9F}
+
+#elif _CODE_PAGE == 1255 /* Hebrew (Windows) */
+#define _DF1S 0
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
+ 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
+ 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
+
+#elif _CODE_PAGE == 1256 /* Arabic (Windows) */
+#define _DF1S 0
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x8C,0x9D,0x9E,0x9F, \
+ 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
+ 0x41,0xE1,0x41,0xE3,0xE4,0xE5,0xE6,0x43,0x45,0x45,0x45,0x45,0xEC,0xED,0x49,0x49,0xF0,0xF1,0xF2,0xF3,0x4F,0xF5,0xF6,0xF7,0xF8,0x55,0xFA,0x55,0x55,0xFD,0xFE,0xFF}
+
+#elif _CODE_PAGE == 1257 /* Baltic (Windows) */
+#define _DF1S 0
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
+ 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xA8,0xB9,0xAA,0xBB,0xBC,0xBD,0xBE,0xAF, \
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF}
+
+#elif _CODE_PAGE == 1258 /* Vietnam (OEM, Windows) */
+#define _DF1S 0
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0xAC,0x9D,0x9E,0x9F, \
+ 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xEC,0xCD,0xCE,0xCF,0xD0,0xD1,0xF2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xFE,0x9F}
+
+#elif _CODE_PAGE == 1 /* ASCII (for only non-LFN cfg) */
+#define _DF1S 0
+
+#else
+#error Unknown code page
+
+#endif
+
+
+
+/* Character code support macros */
+
+#define IsUpper(c) (((c)>='A')&&((c)<='Z'))
+#define IsLower(c) (((c)>='a')&&((c)<='z'))
+
+#if _DF1S /* DBCS configuration */
+
+#ifdef _DF2S /* Two 1st uint8_t areas */
+#define IsDBCS1(c) (((uint8_t)(c) >= _DF1S && (uint8_t)(c) <= _DF1E) || ((uint8_t)(c) >= _DF2S && (uint8_t)(c) <= _DF2E))
+#else /* One 1st uint8_t area */
+#define IsDBCS1(c) ((uint8_t)(c) >= _DF1S && (uint8_t)(c) <= _DF1E)
+#endif
+
+#ifdef _DS3S /* Three 2nd uint8_t areas */
+#define IsDBCS2(c) (((uint8_t)(c) >= _DS1S && (uint8_t)(c) <= _DS1E) || ((uint8_t)(c) >= _DS2S && (uint8_t)(c) <= _DS2E) || ((uint8_t)(c) >= _DS3S && (uint8_t)(c) <= _DS3E))
+#else /* Two 2nd uint8_t areas */
+#define IsDBCS2(c) (((uint8_t)(c) >= _DS1S && (uint8_t)(c) <= _DS1E) || ((uint8_t)(c) >= _DS2S && (uint8_t)(c) <= _DS2E))
+#endif
+
+#else /* SBCS configuration */
+
+#define IsDBCS1(c) 0
+#define IsDBCS2(c) 0
+
+#endif /* _DF1S */
+
+
+#endif /* _FATFS */
diff --git a/src/FatFs/sdcard.cpp b/src/FatFs/sdcard.cpp
new file mode 100755
index 0000000..b37ad5a
--- /dev/null
+++ b/src/FatFs/sdcard.cpp
@@ -0,0 +1,287 @@
+/*-----------------------------------------------------------------------*/
+/* PFF - Low level disk control module for ATtiny85 (C)ChaN, 2009 */
+/*-----------------------------------------------------------------------*/
+
+#define _WRITE_FUNC 1
+
+#include "diskio.h"
+#include <libmary.h>
+#include <SPI.h>
+#include <SD.h>
+
+
+/* Definitions for MMC/SDC command */
+#define CMD0 (0x40+0) /* GO_IDLE_STATE */
+#define CMD1 (0x40+1) /* SEND_OP_COND (MMC) */
+#define ACMD41 (0xC0+41) /* SEND_OP_COND (SDC) */
+#define CMD8 (0x40+8) /* SEND_IF_COND */
+#define CMD16 (0x40+16) /* SET_BLOCKLEN */
+#define CMD17 (0x40+17) /* READ_SINGLE_BLOCK */
+#define CMD24 (0x40+24) /* WRITE_BLOCK */
+#define CMD55 (0x40+55) /* APP_CMD */
+#define CMD58 (0x40+58) /* READ_OCR */
+
+
+/* USI control functions (Defined in usi.S, Platform dependent) */
+//void xmit_spi (BYTE); /* Send a byte */
+//BYTE rcv_spi (void); /* Send 0xFF and receive a byte */
+void xmit_spi (uint8_t data)
+{
+ SPI.transfer(data);
+}
+int rcv_spi(void)
+{
+ return SPI.transfer(0xff);
+}
+
+/* Port Controls (Platform dependent) */
+//#define SELECT() PORTB &= ~0x08 /* MMC CS = L */
+//#define DESELECT() PORTB |= 0x08 /* MMC CS = H */
+//#define MMC_SEL !(PORTB & 0x08) /* MMC CS status (true:selected) */
+//#define INIT_SPI() { USICR = 0b00011000; } /* Initialize SPI port */
+#define SELECT() digitalWrite(SDFile.SDCS,LOW) // MMC CS = PIO0_2
+#define DESELECT() digitalWrite(SDFile.SDCS,HIGH)
+#define MMC_SEL !digitalRead(SDFile.SDCS)
+#define INIT_SPI_SD(speed) Init_SPI(8, speed, SPI_SDCARD)
+
+/*--------------------------------------------------------------------------
+
+ Module Private Functions
+
+---------------------------------------------------------------------------*/
+
+static
+uint8_t CardType;
+
+
+/*-----------------------------------------------------------------------*/
+/* Deselect the card and release SPI bus */
+/*-----------------------------------------------------------------------*/
+
+static
+void release_spi (void)
+{
+ DESELECT();
+ rcv_spi();
+}
+
+
+/*-----------------------------------------------------------------------*/
+/* Send a command packet to MMC */
+/*-----------------------------------------------------------------------*/
+
+static
+uint8_t send_cmd (
+ uint8_t cmd, /* Command uint8_t */
+ DWORD arg /* Argument */
+)
+{
+ uint8_t n, res;
+
+
+ if (cmd & 0x80) { /* ACMD<n> is the command sequense of CMD55-CMD<n> */
+ cmd &= 0x7F;
+ res = send_cmd(CMD55, 0);
+ if (res > 1) return res;
+ }
+
+ /* Select the card */
+ DESELECT();
+ rcv_spi();
+ SELECT();
+ rcv_spi();
+
+ /* Send a command packet */
+ xmit_spi(cmd); /* Start + Command index */
+ xmit_spi((uint8_t)(arg >> 24)); /* Argument[31..24] */
+ xmit_spi((uint8_t)(arg >> 16)); /* Argument[23..16] */
+ xmit_spi((uint8_t)(arg >> 8)); /* Argument[15..8] */
+ xmit_spi((uint8_t)arg); /* Argument[7..0] */
+ n = 0x01; /* Dummy CRC + Stop */
+ if (cmd == CMD0) n = 0x95; /* Valid CRC for CMD0(0) */
+ if (cmd == CMD8) n = 0x87; /* Valid CRC for CMD8(0x1AA) */
+ xmit_spi(n);
+
+ /* Receive a command response */
+ n = 10; /* Wait for a valid response in timeout of 10 attempts */
+ do {
+ res = rcv_spi();
+ } while ((res & 0x80) && --n);
+
+ return res; /* Return with the response value */
+}
+
+
+
+/*--------------------------------------------------------------------------
+
+ Public Functions
+
+---------------------------------------------------------------------------*/
+
+
+/*-----------------------------------------------------------------------*/
+/* Initialize Disk Drive */
+/*-----------------------------------------------------------------------*/
+
+DSTATUS disk_initialize (void)
+{
+ uint8_t n, cmd, ty, ocr[4];
+ WORD tmr;
+
+
+ //INIT_SPI();
+ //INIT_SPI_SD(SPI_SLOW);
+ pinMode(SDFile.SDCS,OUTPUT); //CS initialize
+ SPI.setBitLength(8);
+ SPI.setDataMode(SPI_MODE0);
+ SPI.setClockDivider(SPI_CLOCK_DIV32);
+ SPI.begin();
+
+#if _WRITE_FUNC
+ if (MMC_SEL) disk_writep(0, 0); /* Finalize write process if it is in progress */
+#endif
+ for (n = 100; n; n--) rcv_spi(); /* Dummy clocks */
+
+ ty = 0;
+ if (send_cmd(CMD0, 0) == 1) { /* Enter Idle state */
+ if (send_cmd(CMD8, 0x1AA) == 1) { /* SDv2 */
+ for (n = 0; n < 4; n++) ocr[n] = rcv_spi(); /* Get trailing return value of R7 resp */
+ if (ocr[2] == 0x01 && ocr[3] == 0xAA) { /* The card can work at vdd range of 2.7-3.6V */
+ for (tmr = 12000; tmr && send_cmd(ACMD41, 1UL << 30); tmr--) ; /* Wait for leaving idle state (ACMD41 with HCS bit) */
+ if (tmr && send_cmd(CMD58, 0) == 0) { /* Check CCS bit in the OCR */
+ for (n = 0; n < 4; n++) ocr[n] = rcv_spi();
+ ty = (ocr[0] & 0x40) ? CT_SD2 | CT_BLOCK : CT_SD2; /* SDv2 (HC or SC) */
+ }
+ }
+ } else { /* SDv1 or MMCv3 */
+ if (send_cmd(ACMD41, 0) <= 1) {
+ ty = CT_SD1; cmd = ACMD41; /* SDv1 */
+ } else {
+ ty = CT_MMC; cmd = CMD1; /* MMCv3 */
+ }
+ for (tmr = 25000; tmr && send_cmd(cmd, 0); tmr--) ; /* Wait for leaving idle state */
+ if (!tmr || send_cmd(CMD16, 512) != 0) /* Set R/W block length to 512 */
+ ty = 0;
+ }
+ }
+ CardType = ty;
+ release_spi();
+
+ if (ty) SPI.setClockDivider(SPI_CLOCK_DIV4);//INIT_SPI_SD(SPI_FAST);
+
+ return ty ? 0 : STA_NOINIT;
+}
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Read partial sector */
+/*-----------------------------------------------------------------------*/
+
+DRESULT disk_readp (
+ uint8_t *buff, /* Pointer to the read buffer (NULL:Read uint8_ts are forwarded to the stream) */
+ DWORD lba, /* Sector number (LBA) */
+ WORD ofs, /* uint8_t offset to read from (0..511) */
+ WORD cnt /* Number of uint8_ts to read (ofs + cnt mus be <= 512) */
+)
+{
+ DRESULT res;
+ uint8_t rc;
+ WORD bc;
+
+
+ if (!(CardType & CT_BLOCK)) lba *= 512; /* Convert to uint8_t address if needed */
+
+ res = RES_ERROR;
+ if (send_cmd(CMD17, lba) == 0) { /* READ_SINGLE_BLOCK */
+
+ bc = 30000;
+ do { /* Wait for data packet in timeout of 100ms */
+ rc = rcv_spi();
+ } while (rc == 0xFF && --bc);
+
+ if (rc == 0xFE) { /* A data packet arrived */
+ bc = 514 - ofs - cnt;
+
+ /* Skip leading uint8_ts */
+ if (ofs) {
+ do rcv_spi(); while (--ofs);
+ }
+
+ /* Receive a part of the sector */
+ if (buff) { /* Store data to the memory */
+ do
+ *buff++ = rcv_spi();
+ while (--cnt);
+ } else { /* Forward data to the outgoing stream (depends on the project) */
+ do
+ //xmit(rcv_spi()); /* (Console output) */
+ Serial.println(rcv_spi(),DEC); // Console output
+ while (--cnt);
+ }
+
+ /* Skip trailing uint8_ts and CRC */
+ do rcv_spi(); while (--bc);
+
+ res = RES_OK;
+ }
+ }
+
+ release_spi();
+
+ return res;
+}
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Write partial sector */
+/*-----------------------------------------------------------------------*/
+#if _WRITE_FUNC
+
+DRESULT disk_writep (
+ const uint8_t *buff, /* Pointer to the uint8_ts to be written (NULL:Initiate/Finalize sector write) */
+ DWORD sa /* Number of uint8_ts to send, Sector number (LBA) or zero */
+)
+{
+ DRESULT res;
+ WORD bc;
+ static WORD wc;
+
+ res = RES_ERROR;
+
+ if (buff) { /* Send data uint8_ts */
+ bc = (WORD)sa;
+ while (bc && wc) { /* Send data uint8_ts to the card */
+ xmit_spi(*buff++);
+ wc--; bc--;
+ }
+ res = RES_OK;
+ } else {
+ if (sa) { /* Initiate sector write process */
+ if (!(CardType & CT_BLOCK)) sa *= 512; /* Convert to uint8_t address if needed */
+ if (send_cmd(CMD24, sa) == 0) { /* WRITE_SINGLE_BLOCK */
+ xmit_spi(0xFF); xmit_spi(0xFE); /* Data block header */
+ wc = 512; /* Set uint8_t counter */
+ res = RES_OK;
+ }
+ } else { /* Finalize sector write process */
+ bc = wc + 2;
+ //while (bc--) xmit_spi(0); /* Fill left uint8_ts and CRC with zeros */
+ while (bc) /* Fill left uint8_ts and CRC with zeros */
+ {
+ xmit_spi(0);
+ bc--;
+ }
+ if ((rcv_spi() & 0x1F) == 0x05) { /* Receive data resp and wait for end of write process in timeout of 300ms */
+ for (bc = 65000; rcv_spi() != 0xFF && bc; bc--) ; /* Wait ready */
+ if (bc) res = RES_OK;
+ }
+ release_spi();
+ }
+ }
+
+ return res;
+}
+#endif
diff --git a/src/TFTLCD/TFTLCD.h b/src/TFTLCD/TFTLCD.h
new file mode 100755
index 0000000..797383c
--- /dev/null
+++ b/src/TFTLCD/TFTLCD.h
@@ -0,0 +1,220 @@
+#include <libmary.h>
+#include <SPI.h>
+
+#define LCD_CS C33//4 //cs
+#define LCD_DC C21//5 //data command
+#define LCD_RES C31//6 //reset
+//MOSI 11 C47
+//CLK 13 C43
+#define DC_DATA HIGH
+#define DC_CMD LOW
+
+//#define STICK_A 7
+//#define STICK_B 8
+//#define STICK_C 9
+//#define STICK_D 10
+//#define STICK_CT 2
+
+
+#define select_disp() digitalWrite(LCD_CS,LOW) //PORTD &= ~(1 << PORTD4)
+#define unselect_disp() digitalWrite(LCD_CS,HIGH) //PORTD |= (1 << PORTD4)
+
+#define set_disp_command() digitalWrite(LCD_DC,LOW) //PORTD &= ~(1 << PORTD5)
+#define set_disp_data() digitalWrite(LCD_DC,HIGH) //PORTD |= (1 << PORTD5)
+
+/* SSD1283A Unique Value */
+/* MUST be need for SSD1283A */
+#define OFS_COL 2
+#define OFS_RAW 0
+#define MAX_X 130
+#define MAX_Y 130
+
+
+
+void sendCmd(unsigned int cmd){
+ select_disp();
+ set_disp_command();
+ // shiftOut2(PIN_MOSI,PIN_CLK,MSBFIRST,cmd);
+ SPI.transfer(cmd);
+ set_disp_data();
+}
+
+void sendData(unsigned int data){
+ select_disp();
+ set_disp_data();
+ //shiftOut2(PIN_MOSI,PIN_CLK,MSBFIRST,data);
+ SPI.transfer(data);
+}
+
+void sendData16(unsigned int data1,unsigned int data2){
+ select_disp();
+ set_disp_data();
+ //shiftOut2(PIN_MOSI,PIN_CLK,MSBFIRST,data);
+ SPI.transfer(data1);
+ SPI.transfer(data2);
+}
+
+void sendColor(unsigned int color){
+ sendData(color&0x00ff);
+}
+
+
+
+
+void initDisplay(){
+ select_disp();
+
+ digitalWrite(LCD_RES, LOW);
+ delay(80);
+ digitalWrite(LCD_RES, HIGH);
+ delay(20);
+
+ /* SSD1283A */
+ sendCmd(0x10); /* Power Control (1) */
+ sendData16(0x2f,0x8e); /* Onchip DCDC Clock,Fine*2 StartCycle,VGH unregurated */
+ /* StepUpCycle fosc,Internal OPAMP Current reserved,Sleep Mode OFF */
+
+ sendCmd(0x11); /* Power Control (2) */
+ sendData16(0x00,0x0c); /* VGH/VCI ratio x4 */
+
+ sendCmd(0x07); /* Display Control */
+ sendData16(0x00,0x21); /* Nomalize source out zero, Vartical Scroll not pafomed */
+ /* 1 Divison Display,Source output GND, Gate output GVOFFL */
+
+ sendCmd(0x28); /* VCOM-OTP1 */
+ sendData16(0x00,0x06);
+
+ sendCmd(0x28); /* VCOM-OTP1 */
+ sendData16(0x00,0x05);
+
+ sendCmd(0x27); /* VCOM-OTP */
+ sendData16(0x05,0x7f);
+
+ sendCmd(0x29); /* VCOM-OTP2 */
+ sendData16(0x89,0xa1);
+
+ sendCmd(0x00); /* Oscillator On */
+ sendData16(0x00,0x01);
+ delay(150);
+
+ sendCmd(0x29); /* VCOM-OTP2 */
+ sendData16(0x80,0xb0);
+ delay(50);
+
+ sendCmd(0x29); /* VCOM-OTP2 */
+ sendData16(0xff,0xfe);
+
+ sendCmd(0x07); /* Display Control */
+ sendData16(0x00,0x23);
+ delay(50);
+
+ sendCmd(0x07); /* Display Control (Confirm) */
+ sendData16(0x00,0x23);
+ delay(50);
+
+ sendCmd(0x07); /* Display Control */
+ sendData16(0x00,0x33); /* Nomalize source out zero, Vartical Scroll not pafomed */
+ /* 1 Divison Display,,Source output GND (OFF) */
+ /* Gate output Selected VGH, others GVOFFL */
+
+ sendCmd(0x01); /* Driver Output Control */
+ sendData16(0x21,0x83); /* Reversal ON ,Cs On Common,BGR,Scanning Mounting Method */
+ /* Output Shift Direction of Gate Driver G131->G0, */
+ /* Output Shift Direction of Source Driver S0->S395, */
+ /* Number of Gate Driver 131 */
+
+ sendCmd(0x2f); /* ??? */
+ sendData16(0xff,0xff);
+
+ sendCmd(0x2c); /* Oscillator frequency */
+ sendData16(0x80,0x00); /* 520kHz */
+
+ sendCmd(0x03); /* Entry mode */
+ sendData16(0x68,0x30); /* Colour mode 65k,OE defines Display Window,D-mode from internal ram */
+ /* Horizontal increment & Vertical increment & AM 0 Horizontal */
+
+ sendCmd(0x40); /* Set Offset */
+ sendData16(0x00,0x02);
+
+ sendCmd(0x27); /* Further bias current setting */
+ sendData16(0x05,0x70); /* Maximum */
+
+ sendCmd(0x02); /* LCD-Driving-Waveform Control */
+ sendData16(0x03,0x00); /* the odd/even frame-select signals and the N-line inversion */
+ /* signals are EORed for alternating drive */
+
+ sendCmd(0x0b); /* Frame Cycle Control */
+ sendData16(0x58,0x0c); /* Amount of Overlap 4 clock cycle */
+ /* Delay amount of the source output 2 clock cycle */
+ /* EQ period 2 clock cycle, Division Ratio 2 */
+
+ sendCmd(0x12); /* Power Control 3 */
+ sendData16(0x06,0x09); /* Set amplitude magnification of VLCD63 = Vref x 2.175 */
+
+ sendCmd(0x13); /* Power Control 4 */
+ sendData16(0x31,0x00); /* Set output voltage of VcomL = VLCD63 x 1.02 */
+
+ sendCmd(0x2a); /* Test Commands ? */
+ sendData16(0x1d,0xd0);
+
+ sendCmd(0x2b); /* Test Commands ? */
+ sendData16(0x0a,0x90);
+
+ sendCmd(0x2d); /* Test Commands ? */
+ sendData16(0x31,0x0f);
+ delay(100);
+
+ sendCmd(0x44); /* Set CAS Address */
+ sendData16(0x83,0x00);
+
+ sendCmd(0x45); /* Set RAS Address */
+ sendData16(0x83,0x00);
+
+ sendCmd(0x21); /* Set RAM Address */
+ sendData16(0x00,0x00);
+
+ sendCmd(0x1e); /* Power Control 5 */
+ sendData16(0x00,0xbf); /* VcomH = VLCD63 x 0.99 */
+ delay(1);
+
+ sendCmd(0x1e); /* Power Control 5 */
+ sendData16(0x00,0x00); /* VcomH =VLCD63 x 0.36 */
+ delay(100);
+
+ unselect_disp();
+}
+
+void resetArea(){
+ int x=0,y=0;
+ int xwidth=130 , yheight=130;
+
+ select_disp();
+
+ /* Set CAS Address */
+ sendCmd(0x44);
+ sendData16(OFS_COL + xwidth - 1, OFS_COL + x);
+
+ /* Set RAS Address */
+ sendCmd(0x45);
+ sendData16(OFS_RAW + yheight - 1, OFS_RAW + y);
+
+ /* Set RAM Address */
+ sendCmd(0x21);
+ sendData16(OFS_RAW + y, OFS_COL + x);
+
+ /* Write RAM */
+ sendCmd(0x22);
+
+ set_disp_data();
+ unselect_disp();
+}
+
+void fillScreen(unsigned int color_H,unsigned int color_L){
+ select_disp();
+ int i;
+ resetArea();
+ for(i=0;i<16900;i++){
+ sendData16(color_H,color_L);
+ }
+ unselect_disp();
+}
diff --git a/src/XBee/XBee.cpp b/src/XBee/XBee.cpp
new file mode 100755
index 0000000..fedcfdb
--- /dev/null
+++ b/src/XBee/XBee.cpp
@@ -0,0 +1,1355 @@
+/**
+ * Copyright (c) 2009 Andrew Rapp. All rights reserved.
+ *
+ * This file is part of XBee-Arduino.
+ *
+ * XBee-Arduino is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * XBee-Arduino 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBee-Arduino. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <libmary.h>
+#include "XBee.h"
+#include <uart.h>
+
+//#include "WProgram.h"
+//#include "HardwareSerial.h"
+
+
+
+XBeeResponse::XBeeResponse() {
+
+}
+
+uint8_t XBeeResponse::getApiId() {
+ return _apiId;
+}
+
+void XBeeResponse::setApiId(uint8_t apiId) {
+ _apiId = apiId;
+}
+
+uint8_t XBeeResponse::getMsbLength() {
+ return _msbLength;
+}
+
+void XBeeResponse::setMsbLength(uint8_t msbLength) {
+ _msbLength = msbLength;
+}
+
+uint8_t XBeeResponse::getLsbLength() {
+ return _lsbLength;
+}
+
+void XBeeResponse::setLsbLength(uint8_t lsbLength) {
+ _lsbLength = lsbLength;
+}
+
+uint8_t XBeeResponse::getChecksum() {
+ return _checksum;
+}
+
+void XBeeResponse::setChecksum(uint8_t checksum) {
+ _checksum = checksum;
+}
+
+uint8_t XBeeResponse::getFrameDataLength() {
+ return _frameLength;
+}
+
+void XBeeResponse::setFrameLength(uint8_t frameLength) {
+ _frameLength = frameLength;
+}
+
+bool XBeeResponse::isAvailable() {
+ return _complete;
+}
+
+void XBeeResponse::setAvailable(bool complete) {
+ _complete = complete;
+}
+
+bool XBeeResponse::isError() {
+ return _errorCode > 0;
+}
+
+uint8_t XBeeResponse::getErrorCode() {
+ return _errorCode;
+}
+
+void XBeeResponse::setErrorCode(uint8_t errorCode) {
+ _errorCode = errorCode;
+}
+
+// copy common fields from xbee response to target response
+void XBeeResponse::setCommon(XBeeResponse &target) {
+ target.setApiId(getApiId());
+ target.setAvailable(isAvailable());
+ target.setChecksum(getChecksum());
+ target.setErrorCode(getErrorCode());
+ target.setFrameLength(getFrameDataLength());
+ target.setMsbLength(getMsbLength());
+ target.setLsbLength(getLsbLength());
+}
+
+#ifdef SERIES_2
+
+ZBTxStatusResponse::ZBTxStatusResponse() : FrameIdResponse() {
+
+}
+
+uint16_t ZBTxStatusResponse::getRemoteAddress() {
+ return (getFrameData()[1] << 8) + getFrameData()[2];
+}
+
+uint8_t ZBTxStatusResponse::getTxRetryCount() {
+ return getFrameData()[3];
+}
+
+uint8_t ZBTxStatusResponse::getDeliveryStatus() {
+ return getFrameData()[4];
+}
+
+uint8_t ZBTxStatusResponse::getDiscoveryStatus() {
+ return getFrameData()[5];
+}
+
+bool ZBTxStatusResponse::isSuccess() {
+ return getDeliveryStatus() == SUCCESS;
+}
+
+void XBeeResponse::getZBTxStatusResponse(XBeeResponse &zbXBeeResponse) {
+
+ // way off?
+ ZBTxStatusResponse* zb = static_cast<ZBTxStatusResponse*>(&zbXBeeResponse);
+ // pass pointer array to subclass
+ zb->setFrameData(getFrameData());
+ setCommon(zbXBeeResponse);
+}
+
+ZBRxResponse::ZBRxResponse(): RxDataResponse() {
+ _remoteAddress64 = XBeeAddress64();
+}
+
+uint16_t ZBRxResponse::getRemoteAddress16() {
+ return (getFrameData()[8] << 8) + getFrameData()[9];
+}
+
+uint8_t ZBRxResponse::getOption() {
+ return getFrameData()[10];
+}
+
+// markers to read data from packet array. this is the index, so the 12th item in the array
+uint8_t ZBRxResponse::getDataOffset() {
+ return 11;
+}
+
+uint8_t ZBRxResponse::getDataLength() {
+ return getPacketLength() - getDataOffset() - 1;
+}
+
+XBeeAddress64& ZBRxResponse::getRemoteAddress64() {
+ return _remoteAddress64;
+}
+
+void XBeeResponse::getZBRxResponse(XBeeResponse &rxResponse) {
+
+ ZBRxResponse* zb = static_cast<ZBRxResponse*>(&rxResponse);
+
+ //TODO verify response api id matches this api for this response
+
+ // pass pointer array to subclass
+ zb->setFrameData(getFrameData());
+ setCommon(rxResponse);
+
+ zb->getRemoteAddress64().setMsb((uint32_t(getFrameData()[0]) << 24) + (uint32_t(getFrameData()[1]) << 16) + (uint16_t(getFrameData()[2]) << 8) + getFrameData()[3]);
+ zb->getRemoteAddress64().setLsb((uint32_t(getFrameData()[4]) << 24) + (uint32_t(getFrameData()[5]) << 16) + (uint16_t(getFrameData()[6]) << 8) + (getFrameData()[7]));
+}
+
+
+ZBRxIoSampleResponse::ZBRxIoSampleResponse() : ZBRxResponse() {
+
+}
+
+// 64 + 16 addresses, sample size, option = 12 (index 11), so this starts at 12
+uint8_t ZBRxIoSampleResponse::getDigitalMaskMsb() {
+ return getFrameData()[12] & 0x1c;
+}
+
+uint8_t ZBRxIoSampleResponse::getDigitalMaskLsb() {
+ return getFrameData()[13];
+}
+
+uint8_t ZBRxIoSampleResponse::getAnalogMask() {
+ return getFrameData()[14] & 0x8f;
+}
+
+bool ZBRxIoSampleResponse::containsAnalog() {
+ return getAnalogMask() > 0;
+}
+
+bool ZBRxIoSampleResponse::containsDigital() {
+ return getDigitalMaskMsb() > 0 || getDigitalMaskLsb() > 0;
+}
+
+bool ZBRxIoSampleResponse::isAnalogEnabled(uint8_t pin) {
+ return ((getAnalogMask() >> pin) & 1) == 1;
+}
+
+bool ZBRxIoSampleResponse::isDigitalEnabled(uint8_t pin) {
+ if (pin <= 7) {
+ // added extra parens to calm avr compiler
+ return ((getDigitalMaskLsb() >> pin) & 1) == 1;
+ } else {
+ return ((getDigitalMaskMsb() >> (pin - 8)) & 1) == 1;
+ }
+}
+
+uint16_t ZBRxIoSampleResponse::getAnalog(uint8_t pin) {
+ // analog starts 13 bytes after sample size, if no dio enabled
+ uint8_t start = 15;
+
+ if (containsDigital()) {
+ // make room for digital i/o
+ start+=2;
+ }
+
+// std::cout << "spacing is " << static_cast<unsigned int>(spacing) << std::endl;
+
+ // start depends on how many pins before this pin are enabled
+ for (int i = 0; i < pin; i++) {
+ if (isAnalogEnabled(pin)) {
+ start+=2;
+ }
+ }
+
+// std::cout << "start for analog pin ["<< static_cast<unsigned int>(pin) << "]/sample " << static_cast<unsigned int>(sample) << " is " << static_cast<unsigned int>(start) << std::endl;
+
+// std::cout << "returning index " << static_cast<unsigned int>(getSampleOffset() + start) << " and index " << static_cast<unsigned int>(getSampleOffset() + start + 1) << ", val is " << static_cast<unsigned int>(getFrameData()[getSampleOffset() + start] << 8) << " and " << + static_cast<unsigned int>(getFrameData()[getSampleOffset() + start + 1]) << std::endl;
+
+ return (uint16_t)((getFrameData()[start] << 8) + getFrameData()[start + 1]);
+}
+
+bool ZBRxIoSampleResponse::isDigitalOn(uint8_t pin) {
+ if (pin <= 7) {
+ // D0-7
+ // DIO LSB is index 5
+ return ((getFrameData()[16] >> pin) & 1) == 1;
+ } else {
+ // D10-12
+ // DIO MSB is index 4
+ return ((getFrameData()[15] >> (pin - 8)) & 1) == 1;
+ }
+}
+
+void XBeeResponse::getZBRxIoSampleResponse(XBeeResponse &response) {
+ ZBRxIoSampleResponse* zb = static_cast<ZBRxIoSampleResponse*>(&response);
+
+
+ // pass pointer array to subclass
+ zb->setFrameData(getFrameData());
+ setCommon(response);
+
+ zb->getRemoteAddress64().setMsb((uint32_t(getFrameData()[0]) << 24) + (uint32_t(getFrameData()[1]) << 16) + (uint16_t(getFrameData()[2]) << 8) + getFrameData()[3]);
+ zb->getRemoteAddress64().setLsb((uint32_t(getFrameData()[4]) << 24) + (uint32_t(getFrameData()[5]) << 16) + (uint16_t(getFrameData()[6]) << 8) + (getFrameData()[7]));
+}
+
+#endif
+
+#ifdef SERIES_1
+
+RxResponse::RxResponse() : RxDataResponse() {
+
+}
+
+uint16_t Rx16Response::getRemoteAddress16() {
+ return (getFrameData()[0] << 8) + getFrameData()[1];
+}
+
+XBeeAddress64& Rx64Response::getRemoteAddress64() {
+ return _remoteAddress;
+}
+
+Rx64Response::Rx64Response() : RxResponse() {
+ _remoteAddress = XBeeAddress64();
+}
+
+Rx16Response::Rx16Response() : RxResponse() {
+
+}
+
+RxIoSampleBaseResponse::RxIoSampleBaseResponse() : RxResponse() {
+
+}
+
+uint8_t RxIoSampleBaseResponse::getSampleOffset() {
+ // sample starts 2 bytes after rssi
+ return getRssiOffset() + 2;
+}
+
+
+uint8_t RxIoSampleBaseResponse::getSampleSize() {
+ return getFrameData()[getSampleOffset()];
+}
+
+bool RxIoSampleBaseResponse::containsAnalog() {
+ return (getFrameData()[getSampleOffset() + 1] & 0x7e) > 0;
+}
+
+bool RxIoSampleBaseResponse::containsDigital() {
+ return (getFrameData()[getSampleOffset() + 1] & 0x1) > 0 || getFrameData()[getSampleOffset() + 2] > 0;
+}
+
+//uint16_t RxIoSampleBaseResponse::getAnalog0(uint8_t sample) {
+// return getAnalog(0, sample);
+//}
+
+bool RxIoSampleBaseResponse::isAnalogEnabled(uint8_t pin) {
+ return (((getFrameData()[getSampleOffset() + 1] >> (pin + 1)) & 1) == 1);
+}
+
+bool RxIoSampleBaseResponse::isDigitalEnabled(uint8_t pin) {
+ if (pin < 8) {
+ return ((getFrameData()[getSampleOffset() + 4] >> pin) & 1) == 1;
+ } else {
+ return (getFrameData()[getSampleOffset() + 3] & 1) == 1;
+ }
+}
+
+uint16_t RxIoSampleBaseResponse::getAnalog(uint8_t pin, uint8_t sample) {
+
+ // analog starts 3 bytes after sample size, if no dio enabled
+ uint8_t start = 3;
+
+ if (containsDigital()) {
+ // make room for digital i/o sample (2 bytes per sample)
+ start+=2*(sample + 1);
+ }
+
+ uint8_t spacing = 0;
+
+ // spacing between samples depends on how many are enabled. add one for each analog that's enabled
+ for (int i = 0; i <= 5; i++) {
+ if (isAnalogEnabled(i)) {
+ // each analog is two bytes
+ spacing+=2;
+ }
+ }
+
+// std::cout << "spacing is " << static_cast<unsigned int>(spacing) << std::endl;
+
+ // start depends on how many pins before this pin are enabled
+ for (int i = 0; i < pin; i++) {
+ if (isAnalogEnabled(pin)) {
+ start+=2;
+ }
+ }
+
+ start+= sample * spacing;
+
+// std::cout << "start for analog pin ["<< static_cast<unsigned int>(pin) << "]/sample " << static_cast<unsigned int>(sample) << " is " << static_cast<unsigned int>(start) << std::endl;
+
+// std::cout << "returning index " << static_cast<unsigned int>(getSampleOffset() + start) << " and index " << static_cast<unsigned int>(getSampleOffset() + start + 1) << ", val is " << static_cast<unsigned int>(getFrameData()[getSampleOffset() + start] << 8) << " and " << + static_cast<unsigned int>(getFrameData()[getSampleOffset() + start + 1]) << std::endl;
+
+ return (uint16_t)((getFrameData()[getSampleOffset() + start] << 8) + getFrameData()[getSampleOffset() + start + 1]);
+}
+
+bool RxIoSampleBaseResponse::isDigitalOn(uint8_t pin, uint8_t sample) {
+ if (pin < 8) {
+ return ((getFrameData()[getSampleOffset() + 4] >> pin) & 1) == 1;
+ } else {
+ return (getFrameData()[getSampleOffset() + 3] & 1) == 1;
+ }
+}
+
+
+//bool RxIoSampleBaseResponse::isDigital0On(uint8_t sample) {
+// return isDigitalOn(0, sample);
+//}
+
+Rx16IoSampleResponse::Rx16IoSampleResponse() : RxIoSampleBaseResponse() {
+
+}
+
+uint16_t Rx16IoSampleResponse::getRemoteAddress16() {
+ return (uint16_t)((getFrameData()[0] << 8) + getFrameData()[1]);
+}
+
+uint8_t Rx16IoSampleResponse::getRssiOffset() {
+ return 2;
+}
+
+void XBeeResponse::getRx16IoSampleResponse(XBeeResponse &response) {
+ Rx16IoSampleResponse* rx = static_cast<Rx16IoSampleResponse*>(&response);
+
+ rx->setFrameData(getFrameData());
+ setCommon(response);
+}
+
+
+Rx64IoSampleResponse::Rx64IoSampleResponse() : RxIoSampleBaseResponse() {
+ _remoteAddress = XBeeAddress64();
+}
+
+XBeeAddress64& Rx64IoSampleResponse::getRemoteAddress64() {
+ return _remoteAddress;
+}
+
+uint8_t Rx64IoSampleResponse::getRssiOffset() {
+ return 8;
+}
+
+void XBeeResponse::getRx64IoSampleResponse(XBeeResponse &response) {
+ Rx64IoSampleResponse* rx = static_cast<Rx64IoSampleResponse*>(&response);
+
+ rx->setFrameData(getFrameData());
+ setCommon(response);
+
+ rx->getRemoteAddress64().setMsb((uint32_t(getFrameData()[0]) << 24) + (uint32_t(getFrameData()[1]) << 16) + (uint16_t(getFrameData()[2]) << 8) + getFrameData()[3]);
+ rx->getRemoteAddress64().setLsb((uint32_t(getFrameData()[4]) << 24) + (uint32_t(getFrameData()[5]) << 16) + (uint16_t(getFrameData()[6]) << 8) + getFrameData()[7]);
+}
+
+TxStatusResponse::TxStatusResponse() : FrameIdResponse() {
+
+}
+
+uint8_t TxStatusResponse::getStatus() {
+ return getFrameData()[1];
+}
+
+bool TxStatusResponse::isSuccess() {
+ return getStatus() == SUCCESS;
+}
+
+void XBeeResponse::getTxStatusResponse(XBeeResponse &txResponse) {
+
+ TxStatusResponse* txStatus = static_cast<TxStatusResponse*>(&txResponse);
+
+ // pass pointer array to subclass
+ txStatus->setFrameData(getFrameData());
+ setCommon(txResponse);
+}
+
+uint8_t RxResponse::getRssi() {
+ return getFrameData()[getRssiOffset()];
+}
+
+uint8_t RxResponse::getOption() {
+ return getFrameData()[getRssiOffset() + 1];
+}
+
+bool RxResponse::isAddressBroadcast() {
+ return (getOption() & 2) == 2;
+}
+
+bool RxResponse::isPanBroadcast() {
+ return (getOption() & 4) == 4;
+}
+
+uint8_t RxResponse::getDataLength() {
+ return getPacketLength() - getDataOffset() - 1;
+}
+
+uint8_t RxResponse::getDataOffset() {
+ return getRssiOffset() + 2;
+}
+
+uint8_t Rx16Response::getRssiOffset() {
+ return RX_16_RSSI_OFFSET;
+}
+
+void XBeeResponse::getRx16Response(XBeeResponse &rx16Response) {
+
+ Rx16Response* rx16 = static_cast<Rx16Response*>(&rx16Response);
+
+ // pass pointer array to subclass
+ rx16->setFrameData(getFrameData());
+ setCommon(rx16Response);
+
+// rx16->getRemoteAddress16().setAddress((getFrameData()[0] << 8) + getFrameData()[1]);
+}
+
+uint8_t Rx64Response::getRssiOffset() {
+ return RX_64_RSSI_OFFSET;
+}
+
+void XBeeResponse::getRx64Response(XBeeResponse &rx64Response) {
+
+ Rx64Response* rx64 = static_cast<Rx64Response*>(&rx64Response);
+
+ // pass pointer array to subclass
+ rx64->setFrameData(getFrameData());
+ setCommon(rx64Response);
+
+ rx64->getRemoteAddress64().setMsb((uint32_t(getFrameData()[0]) << 24) + (uint32_t(getFrameData()[1]) << 16) + (uint16_t(getFrameData()[2]) << 8) + getFrameData()[3]);
+ rx64->getRemoteAddress64().setLsb((uint32_t(getFrameData()[4]) << 24) + (uint32_t(getFrameData()[5]) << 16) + (uint16_t(getFrameData()[6]) << 8) + getFrameData()[7]);
+}
+
+#endif
+
+RemoteAtCommandResponse::RemoteAtCommandResponse() : AtCommandResponse() {
+
+}
+
+uint8_t* RemoteAtCommandResponse::getCommand() {
+ return getFrameData() + 11;
+}
+
+uint8_t RemoteAtCommandResponse::getStatus() {
+ return getFrameData()[13];
+}
+
+bool RemoteAtCommandResponse::isOk() {
+ // weird c++ behavior. w/o this method, it calls AtCommandResponse::isOk(), which calls the AtCommandResponse::getStatus, not this.getStatus!!!
+ return getStatus() == AT_OK;
+}
+
+uint8_t RemoteAtCommandResponse::getValueLength() {
+ return getFrameDataLength() - 14;
+}
+
+uint8_t* RemoteAtCommandResponse::getValue() {
+ if (getValueLength() > 0) {
+ // value is only included for query commands. set commands does not return a value
+ return getFrameData() + 14;
+ }
+
+ return NULL;
+}
+
+uint16_t RemoteAtCommandResponse::getRemoteAddress16() {
+ return uint16_t((getFrameData()[9] << 8) + getFrameData()[10]);
+}
+
+XBeeAddress64& RemoteAtCommandResponse::getRemoteAddress64() {
+ return _remoteAddress64;
+}
+
+void XBeeResponse::getRemoteAtCommandResponse(XBeeResponse &response) {
+
+ // TODO no real need to cast. change arg to match expected class
+ RemoteAtCommandResponse* at = static_cast<RemoteAtCommandResponse*>(&response);
+
+ // pass pointer array to subclass
+ at->setFrameData(getFrameData());
+ setCommon(response);
+
+ at->getRemoteAddress64().setMsb((uint32_t(getFrameData()[1]) << 24) + (uint32_t(getFrameData()[2]) << 16) + (uint16_t(getFrameData()[3]) << 8) + getFrameData()[4]);
+ at->getRemoteAddress64().setLsb((uint32_t(getFrameData()[5]) << 24) + (uint32_t(getFrameData()[6]) << 16) + (uint16_t(getFrameData()[7]) << 8) + (getFrameData()[8]));
+
+}
+
+RxDataResponse::RxDataResponse() : XBeeResponse() {
+
+}
+
+uint8_t RxDataResponse::getData(int index) {
+ return getFrameData()[getDataOffset() + index];
+}
+
+uint8_t* RxDataResponse::getData() {
+ return getFrameData() + getDataOffset();
+}
+
+FrameIdResponse::FrameIdResponse() {
+
+}
+
+uint8_t FrameIdResponse::getFrameId() {
+ return getFrameData()[0];
+}
+
+
+ModemStatusResponse::ModemStatusResponse() {
+
+}
+
+uint8_t ModemStatusResponse::getStatus() {
+ return getFrameData()[0];
+}
+
+void XBeeResponse::getModemStatusResponse(XBeeResponse &modemStatusResponse) {
+
+ ModemStatusResponse* modem = static_cast<ModemStatusResponse*>(&modemStatusResponse);
+
+ // pass pointer array to subclass
+ modem->setFrameData(getFrameData());
+ setCommon(modemStatusResponse);
+
+}
+
+AtCommandResponse::AtCommandResponse() {
+
+}
+
+uint8_t* AtCommandResponse::getCommand() {
+ return getFrameData() + 1;
+}
+
+uint8_t AtCommandResponse::getStatus() {
+ return getFrameData()[3];
+}
+
+uint8_t AtCommandResponse::getValueLength() {
+ return getFrameDataLength() - 4;
+}
+
+uint8_t* AtCommandResponse::getValue() {
+ if (getValueLength() > 0) {
+ // value is only included for query commands. set commands does not return a value
+ return getFrameData() + 4;
+ }
+
+ return NULL;
+}
+
+bool AtCommandResponse::isOk() {
+ return getStatus() == AT_OK;
+}
+
+void XBeeResponse::getAtCommandResponse(XBeeResponse &atCommandResponse) {
+
+ AtCommandResponse* at = static_cast<AtCommandResponse*>(&atCommandResponse);
+
+ // pass pointer array to subclass
+ at->setFrameData(getFrameData());
+ setCommon(atCommandResponse);
+}
+
+uint16_t XBeeResponse::getPacketLength() {
+ return ((_msbLength << 8) & 0xff) + (_lsbLength & 0xff);
+}
+
+uint8_t* XBeeResponse::getFrameData() {
+ return _frameDataPtr;
+}
+
+void XBeeResponse::setFrameData(uint8_t* frameDataPtr) {
+ _frameDataPtr = frameDataPtr;
+}
+
+void XBeeResponse::init() {
+ _complete = false;
+ _errorCode = NO_ERROR;
+ _checksum = 0;
+}
+
+void XBeeResponse::reset() {
+ init();
+ _apiId = 0;
+ _msbLength = 0;
+ _lsbLength = 0;
+ _checksum = 0;
+ _frameLength = 0;
+
+ for (int i = 0; i < MAX_FRAME_DATA_SIZE; i++) {
+ getFrameData()[i] = 0;
+ }
+}
+
+void XBee::resetResponse() {
+ _pos = 0;
+ _escape = false;
+ _response.reset();
+}
+
+XBee::XBee(): _response(XBeeResponse()) {
+ _pos = 0;
+ _escape = false;
+ _checksumTotal = 0;
+ _nextFrameId = 0;
+
+ _response.init();
+ _response.setFrameData(_responseFrameData);
+}
+
+uint8_t XBee::getNextFrameId() {
+
+ _nextFrameId++;
+
+ if (_nextFrameId == 0) {
+ // can't send 0 because that disables status response
+ _nextFrameId = 1;
+ }
+
+ return _nextFrameId;
+}
+
+void XBee::begin(int baud)
+{
+ Serial.begin(baud);//Serial.begin(baud);
+}
+
+/*void XBee::setSerial(HardwareSerial serial) {
+ Serial = serial;
+}*/
+
+XBeeResponse& XBee::getResponse() {
+ return _response;
+}
+
+// TODO how to convert response to proper subclass?
+void XBee::getResponse(XBeeResponse &response) {
+
+ response.setMsbLength(_response.getMsbLength());
+ response.setLsbLength(_response.getLsbLength());
+ response.setApiId(_response.getApiId());
+ response.setFrameLength(_response.getFrameDataLength());
+
+ response.setFrameData(_response.getFrameData());
+}
+
+void XBee::readPacketUntilAvailable() {
+ while (!(getResponse().isAvailable() || getResponse().isError())) {
+ // read some more
+ readPacket();
+ }
+}
+
+bool XBee::readPacket(int timeout) {
+
+ if (timeout < 0) {
+ return false;
+ }
+
+ unsigned long start = millis();
+
+ while (int((millis() - start)) < timeout) {
+
+ readPacket();
+
+ if (getResponse().isAvailable()) {
+ return true;
+ } else if (getResponse().isError()) {
+ return false;
+ }
+ }
+
+ // timed out
+ return false;
+}
+
+void XBee::readPacket() {
+ // reset previous response
+ if (_response.isAvailable() || _response.isError()) {
+ // discard previous packet and start over
+ resetResponse();
+ }
+
+ while (Serial.available()) {
+
+ b = Serial.read();
+
+ if (_pos > 0 && b == START_BYTE && ATAP == 2) {
+ // new packet start before previous packeted completed -- discard previous packet and start over
+ _response.setErrorCode(UNEXPECTED_START_BYTE);
+ return;
+ }
+
+ if (_pos > 0 && b == ESCAPE) {
+ if (Serial.available()) {
+ b = Serial.read();
+ b = 0x20 ^ b;
+ } else {
+ // escape byte. next byte will be
+ _escape = true;
+ continue;
+ }
+ }
+
+ if (_escape == true) {
+ b = 0x20 ^ b;
+ _escape = false;
+ }
+
+ // checksum includes all bytes starting with api id
+ if (_pos >= API_ID_INDEX) {
+ _checksumTotal+= b;
+ }
+
+ switch(_pos) {
+ case 0:
+ if (b == START_BYTE) {
+ _pos++;
+ }
+
+ break;
+ case 1:
+ // length msb
+ _response.setMsbLength(b);
+ _pos++;
+
+ break;
+ case 2:
+ // length lsb
+ _response.setLsbLength(b);
+ _pos++;
+
+ break;
+ case 3:
+ _response.setApiId(b);
+ _pos++;
+
+ break;
+ default:
+ // starts at fifth byte
+
+ if (_pos > MAX_FRAME_DATA_SIZE) {
+ // exceed max size. should never occur
+ _response.setErrorCode(PACKET_EXCEEDS_BYTE_ARRAY_LENGTH);
+ return;
+ }
+
+ // check if we're at the end of the packet
+ // packet length does not include start, length, or checksum bytes, so add 3
+ if (_pos == (_response.getPacketLength() + 3)) {
+ // verify checksum
+
+ //std::cout << "read checksum " << static_cast<unsigned int>(b) << " at pos " << static_cast<unsigned int>(_pos) << std::endl;
+
+ if ((_checksumTotal & 0xff) == 0xff) {
+ _response.setChecksum(b);
+ _response.setAvailable(true);
+
+ _response.setErrorCode(NO_ERROR);
+ } else {
+ // checksum failed
+ _response.setErrorCode(CHECKSUM_FAILURE);
+ }
+
+ // minus 4 because we start after start,msb,lsb,api and up to but not including checksum
+ // e.g. if frame was one byte, _pos=4 would be the byte, pos=5 is the checksum, where end stop reading
+ _response.setFrameLength(_pos - 4);
+
+ // reset state vars
+ _pos = 0;
+
+ _checksumTotal = 0;
+
+ return;
+ } else {
+ // add to packet array, starting with the fourth byte of the apiFrame
+ _response.getFrameData()[_pos - 4] = b;
+ _pos++;
+ }
+ }
+ }
+}
+
+// it's peanut butter jelly time!!
+
+XBeeRequest::XBeeRequest(uint8_t apiId, uint8_t frameId) {
+ _apiId = apiId;
+ _frameId = frameId;
+}
+
+void XBeeRequest::setFrameId(uint8_t frameId) {
+ _frameId = frameId;
+}
+
+uint8_t XBeeRequest::getFrameId() {
+ return _frameId;
+}
+
+uint8_t XBeeRequest::getApiId() {
+ return _apiId;
+}
+
+void XBeeRequest::setApiId(uint8_t apiId) {
+ _apiId = apiId;
+}
+
+//void XBeeRequest::reset() {
+// _frameId = DEFAULT_FRAME_ID;
+//}
+
+//uint8_t XBeeRequest::getPayloadOffset() {
+// return _payloadOffset;
+//}
+//
+//uint8_t XBeeRequest::setPayloadOffset(uint8_t payloadOffset) {
+// _payloadOffset = payloadOffset;
+//}
+
+
+PayloadRequest::PayloadRequest(uint8_t apiId, uint8_t frameId, uint8_t *payload, uint8_t payloadLength) : XBeeRequest(apiId, frameId) {
+ _payloadPtr = payload;
+ _payloadLength = payloadLength;
+}
+
+uint8_t* PayloadRequest::getPayload() {
+ return _payloadPtr;
+}
+
+void PayloadRequest::setPayload(uint8_t* payload) {
+ _payloadPtr = payload;
+}
+
+uint8_t PayloadRequest::getPayloadLength() {
+ return _payloadLength;
+}
+
+void PayloadRequest::setPayloadLength(uint8_t payloadLength) {
+ _payloadLength = payloadLength;
+}
+
+
+XBeeAddress::XBeeAddress() {
+
+}
+
+XBeeAddress64::XBeeAddress64() : XBeeAddress() {
+
+}
+
+XBeeAddress64::XBeeAddress64(uint32_t msb, uint32_t lsb) : XBeeAddress() {
+ _msb = msb;
+ _lsb = lsb;
+}
+
+uint32_t XBeeAddress64::getMsb() {
+ return _msb;
+}
+
+void XBeeAddress64::setMsb(uint32_t msb) {
+ _msb = msb;
+}
+
+uint32_t XBeeAddress64::getLsb() {
+ return _lsb;
+}
+
+void XBeeAddress64::setLsb(uint32_t lsb) {
+ _lsb = lsb;
+}
+
+
+#ifdef SERIES_2
+
+ZBTxRequest::ZBTxRequest() : PayloadRequest(ZB_TX_REQUEST, DEFAULT_FRAME_ID, NULL, 0) {
+
+}
+
+ZBTxRequest::ZBTxRequest(XBeeAddress64 &addr64, uint16_t addr16, uint8_t broadcastRadius, uint8_t option, uint8_t *data, uint8_t dataLength, uint8_t frameId): PayloadRequest(ZB_TX_REQUEST, frameId, data, dataLength) {
+ _addr64 = addr64;
+ _addr16 = addr16;
+ _broadcastRadius = broadcastRadius;
+ _option = option;
+}
+
+ZBTxRequest::ZBTxRequest(XBeeAddress64 &addr64, uint8_t *data, uint8_t dataLength): PayloadRequest(ZB_TX_REQUEST, DEFAULT_FRAME_ID, data, dataLength) {
+ _addr64 = addr64;
+ _addr16 = ZB_BROADCAST_ADDRESS;
+ _broadcastRadius = ZB_BROADCAST_RADIUS_MAX_HOPS;
+ _option = ZB_TX_UNICAST;
+}
+
+uint8_t ZBTxRequest::getFrameData(uint8_t pos) {
+ if (pos == 0) {
+ return (_addr64.getMsb() >> 24) & 0xff;
+ } else if (pos == 1) {
+ return (_addr64.getMsb() >> 16) & 0xff;
+ } else if (pos == 2) {
+ return (_addr64.getMsb() >> 8) & 0xff;
+ } else if (pos == 3) {
+ return _addr64.getMsb() & 0xff;
+ } else if (pos == 4) {
+ return (_addr64.getLsb() >> 24) & 0xff;
+ } else if (pos == 5) {
+ return (_addr64.getLsb() >> 16) & 0xff;
+ } else if (pos == 6) {
+ return (_addr64.getLsb() >> 8) & 0xff;
+ } else if (pos == 7) {
+ return _addr64.getLsb() & 0xff;
+ } else if (pos == 8) {
+ return (_addr16 >> 8) & 0xff;
+ } else if (pos == 9) {
+ return _addr16 & 0xff;
+ } else if (pos == 10) {
+ return _broadcastRadius;
+ } else if (pos == 11) {
+ return _option;
+ } else {
+ return getPayload()[pos - ZB_TX_API_LENGTH];
+ }
+}
+
+uint8_t ZBTxRequest::getFrameDataLength() {
+ return ZB_TX_API_LENGTH + getPayloadLength();
+}
+
+XBeeAddress64& ZBTxRequest::getAddress64() {
+ return _addr64;
+}
+
+uint16_t ZBTxRequest::getAddress16() {
+ return _addr16;
+}
+
+uint8_t ZBTxRequest::getBroadcastRadius() {
+ return _broadcastRadius;
+}
+
+uint8_t ZBTxRequest::getOption() {
+ return _option;
+}
+
+void ZBTxRequest::setAddress64(XBeeAddress64& addr64) {
+ _addr64 = addr64;
+}
+
+void ZBTxRequest::setAddress16(uint16_t addr16) {
+ _addr16 = addr16;
+}
+
+void ZBTxRequest::setBroadcastRadius(uint8_t broadcastRadius) {
+ _broadcastRadius = broadcastRadius;
+}
+
+void ZBTxRequest::setOption(uint8_t option) {
+ _option = option;
+}
+
+#endif
+
+#ifdef SERIES_1
+
+Tx16Request::Tx16Request() : PayloadRequest(TX_16_REQUEST, DEFAULT_FRAME_ID, NULL, 0) {
+
+}
+
+Tx16Request::Tx16Request(uint16_t addr16, uint8_t option, uint8_t *data, uint8_t dataLength, uint8_t frameId) : PayloadRequest(TX_16_REQUEST, frameId, data, dataLength) {
+ _addr16 = addr16;
+ _option = option;
+}
+
+Tx16Request::Tx16Request(uint16_t addr16, uint8_t *data, uint8_t dataLength) : PayloadRequest(TX_16_REQUEST, DEFAULT_FRAME_ID, data, dataLength) {
+ _addr16 = addr16;
+ _option = ACK_OPTION;
+}
+
+uint8_t Tx16Request::getFrameData(uint8_t pos) {
+
+ if (pos == 0) {
+ return (_addr16 >> 8) & 0xff;
+ } else if (pos == 1) {
+ return _addr16 & 0xff;
+ } else if (pos == 2) {
+ return _option;
+ } else {
+ return getPayload()[pos - TX_16_API_LENGTH];
+ }
+}
+
+uint8_t Tx16Request::getFrameDataLength() {
+ return TX_16_API_LENGTH + getPayloadLength();
+}
+
+uint16_t Tx16Request::getAddress16() {
+ return _addr16;
+}
+
+void Tx16Request::setAddress16(uint16_t addr16) {
+ _addr16 = addr16;
+}
+
+uint8_t Tx16Request::getOption() {
+ return _option;
+}
+
+void Tx16Request::setOption(uint8_t option) {
+ _option = option;
+}
+
+Tx64Request::Tx64Request() : PayloadRequest(TX_64_REQUEST, DEFAULT_FRAME_ID, NULL, 0) {
+
+}
+
+Tx64Request::Tx64Request(XBeeAddress64 &addr64, uint8_t option, uint8_t *data, uint8_t dataLength, uint8_t frameId) : PayloadRequest(TX_64_REQUEST, frameId, data, dataLength) {
+ _addr64 = addr64;
+ _option = option;
+}
+
+Tx64Request::Tx64Request(XBeeAddress64 &addr64, uint8_t *data, uint8_t dataLength) : PayloadRequest(TX_64_REQUEST, DEFAULT_FRAME_ID, data, dataLength) {
+ _addr64 = addr64;
+ _option = ACK_OPTION;
+}
+
+uint8_t Tx64Request::getFrameData(uint8_t pos) {
+
+ if (pos == 0) {
+ return (_addr64.getMsb() >> 24) & 0xff;
+ } else if (pos == 1) {
+ return (_addr64.getMsb() >> 16) & 0xff;
+ } else if (pos == 2) {
+ return (_addr64.getMsb() >> 8) & 0xff;
+ } else if (pos == 3) {
+ return _addr64.getMsb() & 0xff;
+ } else if (pos == 4) {
+ return (_addr64.getLsb() >> 24) & 0xff;
+ } else if (pos == 5) {
+ return (_addr64.getLsb() >> 16) & 0xff;
+ } else if (pos == 6) {
+ return(_addr64.getLsb() >> 8) & 0xff;
+ } else if (pos == 7) {
+ return _addr64.getLsb() & 0xff;
+ } else if (pos == 8) {
+ return _option;
+ } else {
+ return getPayload()[pos - TX_64_API_LENGTH];
+ }
+}
+
+uint8_t Tx64Request::getFrameDataLength() {
+ return TX_64_API_LENGTH + getPayloadLength();
+}
+
+XBeeAddress64& Tx64Request::getAddress64() {
+ return _addr64;
+}
+
+void Tx64Request::setAddress64(XBeeAddress64& addr64) {
+ _addr64 = addr64;
+}
+
+uint8_t Tx64Request::getOption() {
+ return _option;
+}
+
+void Tx64Request::setOption(uint8_t option) {
+ _option = option;
+}
+
+#endif
+
+AtCommandRequest::AtCommandRequest() : XBeeRequest(AT_COMMAND_REQUEST, DEFAULT_FRAME_ID) {
+ _command = NULL;
+ clearCommandValue();
+}
+
+AtCommandRequest::AtCommandRequest(uint8_t *command, uint8_t *commandValue, uint8_t commandValueLength) : XBeeRequest(AT_COMMAND_REQUEST, DEFAULT_FRAME_ID) {
+ _command = command;
+ _commandValue = commandValue;
+ _commandValueLength = commandValueLength;
+}
+
+AtCommandRequest::AtCommandRequest(uint8_t *command) : XBeeRequest(AT_COMMAND_REQUEST, DEFAULT_FRAME_ID) {
+ _command = command;
+ clearCommandValue();
+}
+
+uint8_t* AtCommandRequest::getCommand() {
+ return _command;
+}
+
+uint8_t* AtCommandRequest::getCommandValue() {
+ return _commandValue;
+}
+
+uint8_t AtCommandRequest::getCommandValueLength() {
+ return _commandValueLength;
+}
+
+void AtCommandRequest::setCommand(uint8_t* command) {
+ _command = command;
+}
+
+void AtCommandRequest::setCommandValue(uint8_t* value) {
+ _commandValue = value;
+}
+
+void AtCommandRequest::setCommandValueLength(uint8_t length) {
+ _commandValueLength = length;
+}
+
+uint8_t AtCommandRequest::getFrameData(uint8_t pos) {
+
+ if (pos == 0) {
+ return _command[0];
+ } else if (pos == 1) {
+ return _command[1];
+ } else {
+ return _commandValue[pos - AT_COMMAND_API_LENGTH];
+ }
+}
+
+void AtCommandRequest::clearCommandValue() {
+ _commandValue = NULL;
+ _commandValueLength = 0;
+}
+
+//void AtCommandRequest::reset() {
+// XBeeRequest::reset();
+//}
+
+uint8_t AtCommandRequest::getFrameDataLength() {
+ // command is 2 byte + length of value
+ return AT_COMMAND_API_LENGTH + _commandValueLength;
+}
+
+XBeeAddress64 RemoteAtCommandRequest::broadcastAddress64 = XBeeAddress64(0x0, BROADCAST_ADDRESS);
+
+RemoteAtCommandRequest::RemoteAtCommandRequest() : AtCommandRequest(NULL, NULL, 0) {
+ _remoteAddress16 = 0;
+ _applyChanges = false;
+ setApiId(REMOTE_AT_REQUEST);
+}
+
+RemoteAtCommandRequest::RemoteAtCommandRequest(uint16_t remoteAddress16, uint8_t *command, uint8_t *commandValue, uint8_t commandValueLength) : AtCommandRequest(command, commandValue, commandValueLength) {
+ _remoteAddress64 = broadcastAddress64;
+ _remoteAddress16 = remoteAddress16;
+ _applyChanges = true;
+ setApiId(REMOTE_AT_REQUEST);
+}
+
+RemoteAtCommandRequest::RemoteAtCommandRequest(uint16_t remoteAddress16, uint8_t *command) : AtCommandRequest(command, NULL, 0) {
+ _remoteAddress64 = broadcastAddress64;
+ _remoteAddress16 = remoteAddress16;
+ _applyChanges = false;
+ setApiId(REMOTE_AT_REQUEST);
+}
+
+RemoteAtCommandRequest::RemoteAtCommandRequest(XBeeAddress64 &remoteAddress64, uint8_t *command, uint8_t *commandValue, uint8_t commandValueLength) : AtCommandRequest(command, commandValue, commandValueLength) {
+ _remoteAddress64 = remoteAddress64;
+ // don't worry.. works for series 1 too!
+ _remoteAddress16 = ZB_BROADCAST_ADDRESS;
+ _applyChanges = true;
+ setApiId(REMOTE_AT_REQUEST);
+}
+
+RemoteAtCommandRequest::RemoteAtCommandRequest(XBeeAddress64 &remoteAddress64, uint8_t *command) : AtCommandRequest(command, NULL, 0) {
+ _remoteAddress64 = remoteAddress64;
+ _remoteAddress16 = ZB_BROADCAST_ADDRESS;
+ _applyChanges = false;
+ setApiId(REMOTE_AT_REQUEST);
+}
+
+uint16_t RemoteAtCommandRequest::getRemoteAddress16() {
+ return _remoteAddress16;
+}
+
+void RemoteAtCommandRequest::setRemoteAddress16(uint16_t remoteAddress16) {
+ _remoteAddress16 = remoteAddress16;
+}
+
+XBeeAddress64& RemoteAtCommandRequest::getRemoteAddress64() {
+ return _remoteAddress64;
+}
+
+void RemoteAtCommandRequest::setRemoteAddress64(XBeeAddress64 &remoteAddress64) {
+ _remoteAddress64 = remoteAddress64;
+}
+
+bool RemoteAtCommandRequest::getApplyChanges() {
+ return _applyChanges;
+}
+
+void RemoteAtCommandRequest::setApplyChanges(bool applyChanges) {
+ _applyChanges = applyChanges;
+}
+
+
+uint8_t RemoteAtCommandRequest::getFrameData(uint8_t pos) {
+ if (pos == 0) {
+ return (_remoteAddress64.getMsb() >> 24) & 0xff;
+ } else if (pos == 1) {
+ return (_remoteAddress64.getMsb() >> 16) & 0xff;
+ } else if (pos == 2) {
+ return (_remoteAddress64.getMsb() >> 8) & 0xff;
+ } else if (pos == 3) {
+ return _remoteAddress64.getMsb() & 0xff;
+ } else if (pos == 4) {
+ return (_remoteAddress64.getLsb() >> 24) & 0xff;
+ } else if (pos == 5) {
+ return (_remoteAddress64.getLsb() >> 16) & 0xff;
+ } else if (pos == 6) {
+ return(_remoteAddress64.getLsb() >> 8) & 0xff;
+ } else if (pos == 7) {
+ return _remoteAddress64.getLsb() & 0xff;
+ } else if (pos == 8) {
+ return (_remoteAddress16 >> 8) & 0xff;
+ } else if (pos == 9) {
+ return _remoteAddress16 & 0xff;
+ } else if (pos == 10) {
+ return _applyChanges ? 2: 0;
+ } else if (pos == 11) {
+ return getCommand()[0];
+ } else if (pos == 12) {
+ return getCommand()[1];
+ } else {
+ return getCommandValue()[pos - REMOTE_AT_COMMAND_API_LENGTH];
+ }
+}
+
+uint8_t RemoteAtCommandRequest::getFrameDataLength() {
+ return REMOTE_AT_COMMAND_API_LENGTH + getCommandValueLength();
+}
+
+
+// TODO
+//GenericRequest::GenericRequest(uint8_t* frame, uint8_t len, uint8_t apiId): XBeeRequest(apiId, *(frame), len) {
+// _frame = frame;
+//}
+
+void XBee::send(XBeeRequest &request) {
+ // the new new deal
+
+ sendByte(START_BYTE, false);
+
+ // send length
+ uint8_t msbLen = ((request.getFrameDataLength() + 2) >> 8) & 0xff;
+ uint8_t lsbLen = (request.getFrameDataLength() + 2) & 0xff;
+
+ sendByte(msbLen, true);
+ sendByte(lsbLen, true);
+
+ // api id
+ sendByte(request.getApiId(), true);
+ sendByte(request.getFrameId(), true);
+
+ uint8_t checksum = 0;
+
+ // compute checksum, start at api id
+ checksum+= request.getApiId();
+ checksum+= request.getFrameId();
+
+ //std::cout << "frame length is " << static_cast<unsigned int>(request.getFrameDataLength()) << std::endl;
+
+ for (int i = 0; i < request.getFrameDataLength(); i++) {
+// std::cout << "sending byte [" << static_cast<unsigned int>(i) << "] " << std::endl;
+ sendByte(request.getFrameData(i), true);
+ checksum+= request.getFrameData(i);
+ }
+
+ // perform 2s complement
+ checksum = 0xff - checksum;
+
+// std::cout << "checksum is " << static_cast<unsigned int>(checksum) << std::endl;
+
+ // send checksum
+ sendByte(checksum, true);
+
+ // send packet
+ //Serial.flush();
+}
+
+void XBee::sendByte(uint8_t b, bool escape) {
+
+ if (escape && (b == START_BYTE || b == ESCAPE || b == XON || b == XOFF)) {
+// std::cout << "escaping byte [" << toHexString(b) << "] " << std::endl;
+ Serial.print(ESCAPE, BYTE);
+ Serial.print(b ^ 0x20, BYTE);
+ } else {
+ Serial.print(b, BYTE);
+ }
+}
+
diff --git a/src/XBee/XBee.h b/src/XBee/XBee.h
new file mode 100755
index 0000000..1874ec3
--- /dev/null
+++ b/src/XBee/XBee.h
@@ -0,0 +1,964 @@
+/**
+ * Copyright (c) 2009 Andrew Rapp. All rights reserved.
+ *
+ * This file is part of XBee-Arduino.
+ *
+ * XBee-Arduino is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * XBee-Arduino 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBee-Arduino. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef XBee_h
+#define XBee_h
+
+#include <libmary.h>
+#include <inttypes.h>
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+
+
+
+//#define SERIES_1
+#define SERIES_2
+
+// set to ATAP value of XBee. AP=2 is recommended
+#define ATAP 2
+
+#define START_BYTE 0x7e
+#define ESCAPE 0x7d
+#define XON 0x11
+#define XOFF 0x13
+
+
+#ifndef NULL
+ #define NULL 0
+#endif
+// This value determines the size of the byte array for receiving RX packets
+// Most users won't be dealing with packets this large so you can adjust this
+// value to reduce memory consumption. But, remember that
+// if a RX packet exceeds this size, it cannot be parsed!
+
+// This value is determined by the largest packet size (100 byte payload + 64-bit address + option byte and rssi byte) of a series 1 radio
+#define MAX_FRAME_DATA_SIZE 110
+
+#define BROADCAST_ADDRESS 0xffff
+#define ZB_BROADCAST_ADDRESS 0xfffe
+
+// the non-variable length of the frame data (not including frame id or api id or variable data size (e.g. payload, at command set value)
+#define ZB_TX_API_LENGTH 12
+#define TX_16_API_LENGTH 3
+#define TX_64_API_LENGTH 9
+#define AT_COMMAND_API_LENGTH 2
+#define REMOTE_AT_COMMAND_API_LENGTH 13
+// start/length(2)/api/frameid/checksum bytes
+#define PACKET_OVERHEAD_LENGTH 6
+// api is always the third byte in packet
+#define API_ID_INDEX 3
+
+// frame position of rssi byte
+#define RX_16_RSSI_OFFSET 2
+#define RX_64_RSSI_OFFSET 8
+
+#define DEFAULT_FRAME_ID 1
+#define NO_RESPONSE_FRAME_ID 0
+
+// TODO put in tx16 class
+#define ACK_OPTION 0
+#define DISABLE_ACK_OPTION 1
+#define BROADCAST_OPTION 4
+
+// RX options
+#define ZB_PACKET_ACKNOWLEDGED 0x01
+#define ZB_BROADCAST_PACKET 0x02
+
+// not everything is implemented!
+/**
+ * Api Id constants
+ */
+#define TX_64_REQUEST 0x0
+#define TX_16_REQUEST 0x1
+#define AT_COMMAND_REQUEST 0x08
+#define AT_COMMAND_QUEUE_REQUEST 0x09
+#define REMOTE_AT_REQUEST 0x17
+#define ZB_TX_REQUEST 0x10
+#define ZB_EXPLICIT_TX_REQUEST 0x11
+#define RX_64_RESPONSE 0x80
+#define RX_16_RESPONSE 0x81
+#define RX_64_IO_RESPONSE 0x82
+#define RX_16_IO_RESPONSE 0x83
+#define AT_RESPONSE 0x88
+#define TX_STATUS_RESPONSE 0x89
+#define MODEM_STATUS_RESPONSE 0x8a
+#define ZB_RX_RESPONSE 0x90
+#define ZB_EXPLICIT_RX_RESPONSE 0x91
+#define ZB_TX_STATUS_RESPONSE 0x8b
+#define ZB_IO_SAMPLE_RESPONSE 0x92
+#define ZB_IO_NODE_IDENTIFIER_RESPONSE 0x95
+#define AT_COMMAND_RESPONSE 0x88
+#define REMOTE_AT_COMMAND_RESPONSE 0x97
+
+
+/**
+ * TX STATUS constants
+ */
+#define SUCCESS 0x0
+#define CCA_FAILURE 0x2
+#define INVALID_DESTINATION_ENDPOINT_SUCCESS 0x15
+#define NETWORK_ACK_FAILURE 0x21
+#define NOT_JOINED_TO_NETWORK 0x22
+#define SELF_ADDRESSED 0x23
+#define ADDRESS_NOT_FOUND 0x24
+#define ROUTE_NOT_FOUND 0x25
+#define PAYLOAD_TOO_LARGE 0x74
+
+// modem status
+#define HARDWARE_RESET 0
+#define WATCHDOG_TIMER_RESET 1
+#define ASSOCIATED 2
+#define DISASSOCIATED 3
+#define SYNCHRONIZATION_LOST 4
+#define COORDINATOR_REALIGNMENT 5
+#define COORDINATOR_STARTED 6
+
+#define ZB_BROADCAST_RADIUS_MAX_HOPS 0
+
+#define ZB_TX_UNICAST 0
+#define ZB_TX_BROADCAST 8
+
+#define AT_OK 0
+#define AT_ERROR 1
+#define AT_INVALID_COMMAND 2
+#define AT_INVALID_PARAMETER 3
+#define AT_NO_RESPONSE 4
+
+#define NO_ERROR 0
+#define CHECKSUM_FAILURE 1
+#define PACKET_EXCEEDS_BYTE_ARRAY_LENGTH 2
+#define UNEXPECTED_START_BYTE 3
+
+/**
+ * The super class of all XBee responses (RX packets)
+ * Users should never attempt to create an instance of this class; instead
+ * create an instance of a subclass
+ * It is recommend to reuse subclasses to conserve memory
+ */
+class XBeeResponse {
+public:
+ //static const int MODEM_STATUS = 0x8a;
+ /**
+ * Default constructor
+ */
+ XBeeResponse();
+ /**
+ * Returns Api Id of the response
+ */
+ uint8_t getApiId();
+ void setApiId(uint8_t apiId);
+ /**
+ * Returns the MSB length of the packet
+ */
+ uint8_t getMsbLength();
+ void setMsbLength(uint8_t msbLength);
+ /**
+ * Returns the LSB length of the packet
+ */
+ uint8_t getLsbLength();
+ void setLsbLength(uint8_t lsbLength);
+ /**
+ * Returns the packet checksum
+ */
+ uint8_t getChecksum();
+ void setChecksum(uint8_t checksum);
+ /**
+ * Returns the length of the frame data: all bytes after the api id, and prior to the checksum
+ * Note up to release 0.1.2, this was incorrectly including the checksum in the length.
+ */
+ uint8_t getFrameDataLength();
+ void setFrameData(uint8_t* frameDataPtr);
+ /**
+ * Returns the buffer that contains the response.
+ * Starts with byte that follows API ID and includes all bytes prior to the checksum
+ * Length is specified by getFrameDataLength()
+ * Note: Unlike Digi's definition of the frame data, this does not start with the API ID..
+ * The reason for this is all responses include an API ID, whereas my frame data
+ * includes only the API specific data.
+ */
+ uint8_t* getFrameData();
+
+ void setFrameLength(uint8_t frameLength);
+ // to support future 65535 byte packets I guess
+ /**
+ * Returns the length of the packet
+ */
+ uint16_t getPacketLength();
+ /**
+ * Resets the response to default values
+ */
+ void reset();
+ /**
+ * Initializes the response
+ */
+ void init();
+#ifdef SERIES_2
+ /**
+ * Call with instance of ZBTxStatusResponse class only if getApiId() == ZB_TX_STATUS_RESPONSE
+ * to populate response
+ */
+ void getZBTxStatusResponse(XBeeResponse &response);
+ /**
+ * Call with instance of ZBRxResponse class only if getApiId() == ZB_RX_RESPONSE
+ * to populate response
+ */
+ void getZBRxResponse(XBeeResponse &response);
+ /**
+ * Call with instance of ZBRxIoSampleResponse class only if getApiId() == ZB_IO_SAMPLE_RESPONSE
+ * to populate response
+ */
+ void getZBRxIoSampleResponse(XBeeResponse &response);
+#endif
+#ifdef SERIES_1
+ /**
+ * Call with instance of TxStatusResponse only if getApiId() == TX_STATUS_RESPONSE
+ */
+ void getTxStatusResponse(XBeeResponse &response);
+ /**
+ * Call with instance of Rx16Response only if getApiId() == RX_16_RESPONSE
+ */
+ void getRx16Response(XBeeResponse &response);
+ /**
+ * Call with instance of Rx64Response only if getApiId() == RX_64_RESPONSE
+ */
+ void getRx64Response(XBeeResponse &response);
+ /**
+ * Call with instance of Rx16IoSampleResponse only if getApiId() == RX_16_IO_RESPONSE
+ */
+ void getRx16IoSampleResponse(XBeeResponse &response);
+ /**
+ * Call with instance of Rx64IoSampleResponse only if getApiId() == RX_64_IO_RESPONSE
+ */
+ void getRx64IoSampleResponse(XBeeResponse &response);
+#endif
+ /**
+ * Call with instance of AtCommandResponse only if getApiId() == AT_COMMAND_RESPONSE
+ */
+ void getAtCommandResponse(XBeeResponse &responses);
+ /**
+ * Call with instance of RemoteAtCommandResponse only if getApiId() == REMOTE_AT_COMMAND_RESPONSE
+ */
+ void getRemoteAtCommandResponse(XBeeResponse &response);
+ /**
+ * Call with instance of ModemStatusResponse only if getApiId() == MODEM_STATUS_RESPONSE
+ */
+ void getModemStatusResponse(XBeeResponse &response);
+ /**
+ * Returns true if the response has been successfully parsed and is complete and ready for use
+ */
+ bool isAvailable();
+ void setAvailable(bool complete);
+ /**
+ * Returns true if the response contains errors
+ */
+ bool isError();
+ /**
+ * Returns an error code, or zero, if successful.
+ * Error codes include: CHECKSUM_FAILURE, PACKET_EXCEEDS_BYTE_ARRAY_LENGTH, UNEXPECTED_START_BYTE
+ */
+ uint8_t getErrorCode();
+ void setErrorCode(uint8_t errorCode);
+protected:
+ // pointer to frameData
+ uint8_t* _frameDataPtr;
+private:
+ void setCommon(XBeeResponse &target);
+ uint8_t _apiId;
+ uint8_t _msbLength;
+ uint8_t _lsbLength;
+ uint8_t _checksum;
+ uint8_t _frameLength;
+ bool _complete;
+ uint8_t _errorCode;
+};
+
+class XBeeAddress {
+public:
+ XBeeAddress();
+};
+
+/**
+ * Represents a 64-bit XBee Address
+ */
+class XBeeAddress64 : public XBeeAddress {
+public:
+ XBeeAddress64(uint32_t msb, uint32_t lsb);
+ XBeeAddress64();
+ uint32_t getMsb();
+ uint32_t getLsb();
+ void setMsb(uint32_t msb);
+ void setLsb(uint32_t lsb);
+private:
+ uint32_t _msb;
+ uint32_t _lsb;
+};
+
+//class XBeeAddress16 : public XBeeAddress {
+//public:
+// XBeeAddress16(uint16_t addr);
+// XBeeAddress16();
+// uint16_t getAddress();
+// void setAddress(uint16_t addr);
+//private:
+// uint16_t _addr;
+//};
+
+/**
+ * This class is extended by all Responses that include a frame id
+ */
+class FrameIdResponse : public XBeeResponse {
+public:
+ FrameIdResponse();
+ uint8_t getFrameId();
+private:
+ uint8_t _frameId;
+};
+
+/**
+ * Common functionality for both Series 1 and 2 data RX data packets
+ */
+class RxDataResponse : public XBeeResponse {
+public:
+ RxDataResponse();
+ /**
+ * Returns the specified index of the payload. The index may be 0 to getDataLength() - 1
+ * This method is deprecated; use uint8_t* getData()
+ */
+ uint8_t getData(int index);
+ /**
+ * Returns the payload array. This may be accessed from index 0 to getDataLength() - 1
+ */
+ uint8_t* getData();
+ /**
+ * Returns the length of the payload
+ */
+ virtual uint8_t getDataLength() = 0;
+ /**
+ * Returns the position in the frame data where the data begins
+ */
+ virtual uint8_t getDataOffset() = 0;
+};
+
+// getResponse to return the proper subclass:
+// we maintain a pointer to each type of response, when a response is parsed, it is allocated only if NULL
+// can we allocate an object in a function?
+
+#ifdef SERIES_2
+/**
+ * Represents a Series 2 TX status packet
+ */
+class ZBTxStatusResponse : public FrameIdResponse {
+ public:
+ ZBTxStatusResponse();
+ uint16_t getRemoteAddress();
+ uint8_t getTxRetryCount();
+ uint8_t getDeliveryStatus();
+ uint8_t getDiscoveryStatus();
+ bool isSuccess();
+};
+
+/**
+ * Represents a Series 2 RX packet
+ */
+class ZBRxResponse : public RxDataResponse {
+public:
+ ZBRxResponse();
+ XBeeAddress64& getRemoteAddress64();
+ uint16_t getRemoteAddress16();
+ uint8_t getOption();
+ uint8_t getDataLength();
+ // frame position where data starts
+ uint8_t getDataOffset();
+private:
+ XBeeAddress64 _remoteAddress64;
+};
+
+/**
+ * Represents a Series 2 RX I/O Sample packet
+ */
+class ZBRxIoSampleResponse : public ZBRxResponse {
+public:
+ ZBRxIoSampleResponse();
+ bool containsAnalog();
+ bool containsDigital();
+ /**
+ * Returns true if the pin is enabled
+ */
+ bool isAnalogEnabled(uint8_t pin);
+ /**
+ * Returns true if the pin is enabled
+ */
+ bool isDigitalEnabled(uint8_t pin);
+ /**
+ * Returns the 10-bit analog reading of the specified pin.
+ * Valid pins include ADC:xxx.
+ */
+ uint16_t getAnalog(uint8_t pin);
+ /**
+ * Returns true if the specified pin is high/on.
+ * Valid pins include DIO:xxx.
+ */
+ bool isDigitalOn(uint8_t pin);
+ uint8_t getDigitalMaskMsb();
+ uint8_t getDigitalMaskLsb();
+ uint8_t getAnalogMask();
+};
+
+#endif
+
+#ifdef SERIES_1
+/**
+ * Represents a Series 1 TX Status packet
+ */
+class TxStatusResponse : public FrameIdResponse {
+ public:
+ TxStatusResponse();
+ uint8_t getStatus();
+ bool isSuccess();
+};
+
+/**
+ * Represents a Series 1 RX packet
+ */
+class RxResponse : public RxDataResponse {
+public:
+ RxResponse();
+ // remember rssi is negative but this is unsigned byte so it's up to you to convert
+ uint8_t getRssi();
+ uint8_t getOption();
+ bool isAddressBroadcast();
+ bool isPanBroadcast();
+ uint8_t getDataLength();
+ uint8_t getDataOffset();
+ virtual uint8_t getRssiOffset() = 0;
+};
+
+/**
+ * Represents a Series 1 16-bit address RX packet
+ */
+class Rx16Response : public RxResponse {
+public:
+ Rx16Response();
+ uint8_t getRssiOffset();
+ uint16_t getRemoteAddress16();
+protected:
+ uint16_t _remoteAddress;
+};
+
+/**
+ * Represents a Series 1 64-bit address RX packet
+ */
+class Rx64Response : public RxResponse {
+public:
+ Rx64Response();
+ uint8_t getRssiOffset();
+ XBeeAddress64& getRemoteAddress64();
+private:
+ XBeeAddress64 _remoteAddress;
+};
+
+/**
+ * Represents a Series 1 RX I/O Sample packet
+ */
+class RxIoSampleBaseResponse : public RxResponse {
+ public:
+ RxIoSampleBaseResponse();
+ /**
+ * Returns the number of samples in this packet
+ */
+ uint8_t getSampleSize();
+ bool containsAnalog();
+ bool containsDigital();
+ /**
+ * Returns true if the specified analog pin is enabled
+ */
+ bool isAnalogEnabled(uint8_t pin);
+ /**
+ * Returns true if the specified digital pin is enabled
+ */
+ bool isDigitalEnabled(uint8_t pin);
+ /**
+ * Returns the 10-bit analog reading of the specified pin.
+ * Valid pins include ADC:0-5. Sample index starts at 0
+ */
+ uint16_t getAnalog(uint8_t pin, uint8_t sample);
+ /**
+ * Returns true if the specified pin is high/on.
+ * Valid pins include DIO:0-8. Sample index starts at 0
+ */
+ bool isDigitalOn(uint8_t pin, uint8_t sample);
+ uint8_t getSampleOffset();
+ private:
+};
+
+class Rx16IoSampleResponse : public RxIoSampleBaseResponse {
+public:
+ Rx16IoSampleResponse();
+ uint16_t getRemoteAddress16();
+ uint8_t getRssiOffset();
+
+};
+
+class Rx64IoSampleResponse : public RxIoSampleBaseResponse {
+public:
+ Rx64IoSampleResponse();
+ XBeeAddress64& getRemoteAddress64();
+ uint8_t getRssiOffset();
+private:
+ XBeeAddress64 _remoteAddress;
+};
+
+#endif
+
+/**
+ * Represents a Modem Status RX packet
+ */
+class ModemStatusResponse : public XBeeResponse {
+public:
+ ModemStatusResponse();
+ uint8_t getStatus();
+};
+
+/**
+ * Represents an AT Command RX packet
+ */
+class AtCommandResponse : public FrameIdResponse {
+ public:
+ AtCommandResponse();
+ /**
+ * Returns an array containing the two character command
+ */
+ uint8_t* getCommand();
+ /**
+ * Returns the command status code.
+ * Zero represents a successful command
+ */
+ uint8_t getStatus();
+ /**
+ * Returns an array containing the command value.
+ * This is only applicable to query commands.
+ */
+ uint8_t* getValue();
+ /**
+ * Returns the length of the command value array.
+ */
+ uint8_t getValueLength();
+ /**
+ * Returns true if status equals AT_OK
+ */
+ bool isOk();
+};
+
+/**
+ * Represents a Remote AT Command RX packet
+ */
+class RemoteAtCommandResponse : public AtCommandResponse {
+ public:
+ RemoteAtCommandResponse();
+ /**
+ * Returns an array containing the two character command
+ */
+ uint8_t* getCommand();
+ /**
+ * Returns the command status code.
+ * Zero represents a successful command
+ */
+ uint8_t getStatus();
+ /**
+ * Returns an array containing the command value.
+ * This is only applicable to query commands.
+ */
+ uint8_t* getValue();
+ /**
+ * Returns the length of the command value array.
+ */
+ uint8_t getValueLength();
+ /**
+ * Returns the 16-bit address of the remote radio
+ */
+ uint16_t getRemoteAddress16();
+ /**
+ * Returns the 64-bit address of the remote radio
+ */
+ XBeeAddress64& getRemoteAddress64();
+ /**
+ * Returns true if command was successful
+ */
+ bool isOk();
+ private:
+ XBeeAddress64 _remoteAddress64;
+};
+
+
+/**
+ * Super class of all XBee requests (TX packets)
+ * Users should never create an instance of this class; instead use an subclass of this class
+ * It is recommended to reuse Subclasses of the class to conserve memory
+ * <p/>
+ * This class allocates a buffer to
+ */
+class XBeeRequest {
+public:
+ /**
+ * Constructor
+ * TODO make protected
+ */
+ XBeeRequest(uint8_t apiId, uint8_t frameId);
+ /**
+ * Sets the frame id. Must be between 1 and 255 inclusive to get a TX status response.
+ */
+ void setFrameId(uint8_t frameId);
+ /**
+ * Returns the frame id
+ */
+ uint8_t getFrameId();
+ /**
+ * Returns the API id
+ */
+ uint8_t getApiId();
+ // setting = 0 makes this a pure virtual function, meaning the subclass must implement, like abstract in java
+ /**
+ * Starting after the frame id (pos = 0) and up to but not including the checksum
+ * Note: Unlike Digi's definition of the frame data, this does not start with the API ID.
+ * The reason for this is the API ID and Frame ID are common to all requests, whereas my definition of
+ * frame data is only the API specific data.
+ */
+ virtual uint8_t getFrameData(uint8_t pos) = 0;
+ /**
+ * Returns the size of the api frame (not including frame id or api id or checksum).
+ */
+ virtual uint8_t getFrameDataLength() = 0;
+ //void reset();
+protected:
+ void setApiId(uint8_t apiId);
+private:
+ uint8_t _apiId;
+ uint8_t _frameId;
+};
+
+// TODO add reset/clear method since responses are often reused
+/**
+ * Primary interface for communicating with an XBee Radio.
+ * This class provides methods for sending and receiving packets with an XBee radio via the serial port.
+ * The XBee radio must be configured in API (packet) mode (AP=2)
+ * in order to use this software.
+ * <p/>
+ * Since this code is designed to run on a microcontroller, with only one thread, you are responsible for reading the
+ * data off the serial buffer in a timely manner. This involves a call to a variant of readPacket(...).
+ * If your serial port is receiving data faster than you are reading, you can expect to lose packets.
+ * Arduino only has a 128 byte serial buffer so it can easily overflow if two or more packets arrive
+ * without a call to readPacket(...)
+ * <p/>
+ * In order to conserve resources, this class only supports storing one response packet in memory at a time.
+ * This means that you must fully consume the packet prior to calling readPacket(...), because calling
+ * readPacket(...) overwrites the previous response.
+ * <p/>
+ * This class creates an array of size MAX_FRAME_DATA_SIZE for storing the response packet. You may want
+ * to adjust this value to conserve memory.
+ *
+ * \author Andrew Rapp
+ */
+class XBee {
+public:
+ XBee();
+ // for eclipse dev only
+ //void setSerial(HardwareSerial serial);
+ /**
+ * Reads all available serial bytes until a packet is parsed, an error occurs, or the buffer is empty.
+ * You may call <i>xbee</i>.getResponse().isAvailable() after calling this method to determine if
+ * a packet is ready, or <i>xbee</i>.getResponse().isError() to determine if
+ * a error occurred.
+ * <p/>
+ * This method should always return quickly since it does not wait for serial data to arrive.
+ * You will want to use this method if you are doing other timely stuff in your loop, where
+ * a delay would cause problems.
+ * NOTE: calling this method resets the current response, so make sure you first consume the
+ * current response
+ */
+ void readPacket();
+ /**
+ * Waits a maximum of <i>timeout</i> milliseconds for a response packet before timing out; returns true if packet is read.
+ * Returns false if timeout or error occurs.
+ */
+ bool readPacket(int timeout);
+ /**
+ * Reads until a packet is received or an error occurs.
+ * Caution: use this carefully since if you don't get a response, your Arduino code will hang on this
+ * call forever!! often it's better to use a timeout: readPacket(int)
+ */
+ void readPacketUntilAvailable();
+ /**
+ * Starts the serial connection at the supplied baud rate
+ */
+ void begin(int baud);
+ void getResponse(XBeeResponse &response);
+ /**
+ * Returns a reference to the current response
+ * Note: once readPacket is called again this response will be overwritten!
+ */
+ XBeeResponse& getResponse();
+ /**
+ * Sends a XBeeRequest (TX packet) out the serial port
+ */
+ void send(XBeeRequest &request);
+ //uint8_t sendAndWaitForResponse(XBeeRequest &request, int timeout);
+ /**
+ * Returns a sequential frame id between 1 and 255
+ */
+ uint8_t getNextFrameId();
+private:
+ void sendByte(uint8_t b, bool escape);
+ void resetResponse();
+ XBeeResponse _response;
+ bool _escape;
+ // current packet position for response. just a state variable for packet parsing and has no relevance for the response otherwise
+ uint8_t _pos;
+ // last byte read
+ uint8_t b;
+ uint8_t _checksumTotal;
+ uint8_t _nextFrameId;
+ // buffer for incoming RX packets. holds only the api specific frame data, starting after the api id byte and prior to checksum
+ uint8_t _responseFrameData[MAX_FRAME_DATA_SIZE];
+};
+
+/**
+ * All TX packets that support payloads extend this class
+ */
+class PayloadRequest : public XBeeRequest {
+public:
+ PayloadRequest(uint8_t apiId, uint8_t frameId, uint8_t *payload, uint8_t payloadLength);
+ /**
+ * Returns the payload of the packet, if not null
+ */
+ uint8_t* getPayload();
+ /**
+ * Sets the payload array
+ */
+ void setPayload(uint8_t* payloadPtr);
+ /**
+ * Returns the length of the payload array, as specified by the user.
+ */
+ uint8_t getPayloadLength();
+ /**
+ * Sets the length of the payload to include in the request. For example if the payload array
+ * is 50 bytes and you only want the first 10 to be included in the packet, set the length to 10.
+ * Length must be <= to the array length.
+ */
+ void setPayloadLength(uint8_t payloadLength);
+private:
+ uint8_t* _payloadPtr;
+ uint8_t _payloadLength;
+};
+
+#ifdef SERIES_1
+
+/**
+ * Represents a Series 1 TX packet that corresponds to Api Id: TX_16_REQUEST
+ * <p/>
+ * Be careful not to send a data array larger than the max packet size of your radio.
+ * This class does not perform any validation of packet size and there will be no indication
+ * if the packet is too large, other than you will not get a TX Status response.
+ * The datasheet says 100 bytes is the maximum, although that could change in future firmware.
+ */
+class Tx16Request : public PayloadRequest {
+public:
+ Tx16Request(uint16_t addr16, uint8_t option, uint8_t *payload, uint8_t payloadLength, uint8_t frameId);
+ /**
+ * Creates a Unicast Tx16Request with the ACK option and DEFAULT_FRAME_ID
+ */
+ Tx16Request(uint16_t addr16, uint8_t *payload, uint8_t payloadLength);
+ /**
+ * Creates a default instance of this class. At a minimum you must specify
+ * a payload, payload length and a destination address before sending this request.
+ */
+ Tx16Request();
+ uint16_t getAddress16();
+ void setAddress16(uint16_t addr16);
+ uint8_t getOption();
+ void setOption(uint8_t option);
+ uint8_t getFrameData(uint8_t pos);
+ uint8_t getFrameDataLength();
+protected:
+private:
+ uint16_t _addr16;
+ uint8_t _option;
+};
+
+/**
+ * Represents a Series 1 TX packet that corresponds to Api Id: TX_64_REQUEST
+ *
+ * Be careful not to send a data array larger than the max packet size of your radio.
+ * This class does not perform any validation of packet size and there will be no indication
+ * if the packet is too large, other than you will not get a TX Status response.
+ * The datasheet says 100 bytes is the maximum, although that could change in future firmware.
+ */
+class Tx64Request : public PayloadRequest {
+public:
+ Tx64Request(XBeeAddress64 &addr64, uint8_t option, uint8_t *payload, uint8_t payloadLength, uint8_t frameId);
+ /**
+ * Creates a unicast Tx64Request with the ACK option and DEFAULT_FRAME_ID
+ */
+ Tx64Request(XBeeAddress64 &addr64, uint8_t *payload, uint8_t payloadLength);
+ /**
+ * Creates a default instance of this class. At a minimum you must specify
+ * a payload, payload length and a destination address before sending this request.
+ */
+ Tx64Request();
+ XBeeAddress64& getAddress64();
+ void setAddress64(XBeeAddress64& addr64);
+ // TODO move option to superclass
+ uint8_t getOption();
+ void setOption(uint8_t option);
+ uint8_t getFrameData(uint8_t pos);
+ uint8_t getFrameDataLength();
+private:
+ XBeeAddress64 _addr64;
+ uint8_t _option;
+};
+
+#endif
+
+
+#ifdef SERIES_2
+
+/**
+ * Represents a Series 2 TX packet that corresponds to Api Id: ZB_TX_REQUEST
+ *
+ * Be careful not to send a data array larger than the max packet size of your radio.
+ * This class does not perform any validation of packet size and there will be no indication
+ * if the packet is too large, other than you will not get a TX Status response.
+ * The datasheet says 72 bytes is the maximum for ZNet firmware and ZB Pro firmware provides
+ * the ATNP command to get the max supported payload size. This command is useful since the
+ * maximum payload size varies according to certain settings, such as encryption.
+ * ZB Pro firmware provides a PAYLOAD_TOO_LARGE that is returned if payload size
+ * exceeds the maximum.
+ */
+class ZBTxRequest : public PayloadRequest {
+public:
+ /**
+ * Creates a unicast ZBTxRequest with the ACK option and DEFAULT_FRAME_ID
+ */
+ ZBTxRequest(XBeeAddress64 &addr64, uint8_t *payload, uint8_t payloadLength);
+ ZBTxRequest(XBeeAddress64 &addr64, uint16_t addr16, uint8_t broadcastRadius, uint8_t option, uint8_t *payload, uint8_t payloadLength, uint8_t frameId);
+ /**
+ * Creates a default instance of this class. At a minimum you must specify
+ * a payload, payload length and a destination address before sending this request.
+ */
+ ZBTxRequest();
+ XBeeAddress64& getAddress64();
+ uint16_t getAddress16();
+ uint8_t getBroadcastRadius();
+ uint8_t getOption();
+ void setAddress64(XBeeAddress64& addr64);
+ void setAddress16(uint16_t addr16);
+ void setBroadcastRadius(uint8_t broadcastRadius);
+ void setOption(uint8_t option);
+protected:
+ // declare virtual functions
+ uint8_t getFrameData(uint8_t pos);
+ uint8_t getFrameDataLength();
+private:
+ XBeeAddress64 _addr64;
+ uint16_t _addr16;
+ uint8_t _broadcastRadius;
+ uint8_t _option;
+};
+
+#endif
+
+/**
+ * Represents an AT Command TX packet
+ * The command is used to configure the serially connected XBee radio
+ */
+class AtCommandRequest : public XBeeRequest {
+public:
+ AtCommandRequest();
+ AtCommandRequest(uint8_t *command);
+ AtCommandRequest(uint8_t *command, uint8_t *commandValue, uint8_t commandValueLength);
+ uint8_t getFrameData(uint8_t pos);
+ uint8_t getFrameDataLength();
+ uint8_t* getCommand();
+ void setCommand(uint8_t* command);
+ uint8_t* getCommandValue();
+ void setCommandValue(uint8_t* command);
+ uint8_t getCommandValueLength();
+ void setCommandValueLength(uint8_t length);
+ /**
+ * Clears the optional commandValue and commandValueLength so that a query may be sent
+ */
+ void clearCommandValue();
+ //void reset();
+private:
+ uint8_t *_command;
+ uint8_t *_commandValue;
+ uint8_t _commandValueLength;
+};
+
+/**
+ * Represents an Remote AT Command TX packet
+ * The command is used to configure a remote XBee radio
+ */
+class RemoteAtCommandRequest : public AtCommandRequest {
+public:
+ RemoteAtCommandRequest();
+ /**
+ * Creates a RemoteAtCommandRequest with 16-bit address to set a command.
+ * 64-bit address defaults to broadcast and applyChanges is true.
+ */
+ RemoteAtCommandRequest(uint16_t remoteAddress16, uint8_t *command, uint8_t *commandValue, uint8_t commandValueLength);
+ /**
+ * Creates a RemoteAtCommandRequest with 16-bit address to query a command.
+ * 64-bit address defaults to broadcast and applyChanges is true.
+ */
+ RemoteAtCommandRequest(uint16_t remoteAddress16, uint8_t *command);
+ /**
+ * Creates a RemoteAtCommandRequest with 64-bit address to set a command.
+ * 16-bit address defaults to broadcast and applyChanges is true.
+ */
+ RemoteAtCommandRequest(XBeeAddress64 &remoteAddress64, uint8_t *command, uint8_t *commandValue, uint8_t commandValueLength);
+ /**
+ * Creates a RemoteAtCommandRequest with 16-bit address to query a command.
+ * 16-bit address defaults to broadcast and applyChanges is true.
+ */
+ RemoteAtCommandRequest(XBeeAddress64 &remoteAddress64, uint8_t *command);
+ uint16_t getRemoteAddress16();
+ void setRemoteAddress16(uint16_t remoteAddress16);
+ XBeeAddress64& getRemoteAddress64();
+ void setRemoteAddress64(XBeeAddress64 &remoteAddress64);
+ bool getApplyChanges();
+ void setApplyChanges(bool applyChanges);
+ uint8_t getFrameData(uint8_t pos);
+ uint8_t getFrameDataLength();
+ static XBeeAddress64 broadcastAddress64;
+// static uint16_t broadcast16Address;
+private:
+ XBeeAddress64 _remoteAddress64;
+ uint16_t _remoteAddress16;
+ bool _applyChanges;
+};
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif //XBee_h
diff --git a/src/core/LPC11xx.h b/src/core/LPC11xx.h
new file mode 100755
index 0000000..854f719
--- /dev/null
+++ b/src/core/LPC11xx.h
@@ -0,0 +1,559 @@
+/****************************************************************************
+ * $Id:: LPC11xx.h 3635 2010-06-02 00:31:46Z usb00423 $
+ * Project: NXP LPC11xx software example
+ *
+ * Description:
+ * CMSIS Cortex-M0 Core Peripheral Access Layer Header File for
+ * NXP LPC11xx Device Series
+ *
+ ****************************************************************************
+ * Software that is described herein is for illustrative purposes only
+ * which provides customers with programming information regarding the
+ * products. This software is supplied "AS IS" without any warranties.
+ * NXP Semiconductors assumes no responsibility or liability for the
+ * use of the software, conveys no license or title under any patent,
+ * copyright, or mask work right to the product. NXP Semiconductors
+ * reserves the right to make changes in the software without
+ * notification. NXP Semiconductors also make no representation or
+ * warranty that such application will be suitable for the specified
+ * use without further testing or modification.
+****************************************************************************/
+#ifndef __LPC11xx_H__
+#define __LPC11xx_H__
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/** @addtogroup LPC11xx_Definitions LPC11xx Definitions
+ This file defines all structures and symbols for LPC11xx:
+ - Registers and bitfields
+ - peripheral base address
+ - peripheral ID
+ - PIO definitions
+ @{
+*/
+
+
+/******************************************************************************/
+/* Processor and Core Peripherals */
+/******************************************************************************/
+/** @addtogroup LPC11xx_CMSIS LPC11xx CMSIS Definitions
+ Configuration of the Cortex-M0 Processor and Core Peripherals
+ @{
+*/
+
+/*
+ * ==========================================================================
+ * ---------- Interrupt Number Definition -----------------------------------
+ * ==========================================================================
+ */
+
+typedef enum IRQn
+{
+/****** Cortex-M0 Processor Exceptions Numbers ***************************************************/
+ NonMaskableInt_IRQn = -14, /*!< 2 Non Maskable Interrupt */
+ HardFault_IRQn = -13, /*!< 3 Cortex-M0 Hard Fault Interrupt */
+ SVCall_IRQn = -5, /*!< 11 Cortex-M0 SV Call Interrupt */
+ PendSV_IRQn = -2, /*!< 14 Cortex-M0 Pend SV Interrupt */
+ SysTick_IRQn = -1, /*!< 15 Cortex-M0 System Tick Interrupt */
+
+/****** LPC11xx Specific Interrupt Numbers *******************************************************/
+ WAKEUP0_IRQn = 0, /*!< All I/O pins can be used as wakeup source. */
+ WAKEUP1_IRQn = 1, /*!< There are 13 pins in total for LPC11xx */
+ WAKEUP2_IRQn = 2,
+ WAKEUP3_IRQn = 3,
+ WAKEUP4_IRQn = 4,
+ WAKEUP5_IRQn = 5,
+ WAKEUP6_IRQn = 6,
+ WAKEUP7_IRQn = 7,
+ WAKEUP8_IRQn = 8,
+ WAKEUP9_IRQn = 9,
+ WAKEUP10_IRQn = 10,
+ WAKEUP11_IRQn = 11,
+ WAKEUP12_IRQn = 12,
+ CAN_IRQn = 13, /*!< CAN Interrupt */
+ SSP1_IRQn = 14, /*!< SSP1 Interrupt */
+ I2C_IRQn = 15, /*!< I2C Interrupt */
+ TIMER_16_0_IRQn = 16, /*!< 16-bit Timer0 Interrupt */
+ TIMER_16_1_IRQn = 17, /*!< 16-bit Timer1 Interrupt */
+ TIMER_32_0_IRQn = 18, /*!< 32-bit Timer0 Interrupt */
+ TIMER_32_1_IRQn = 19, /*!< 32-bit Timer1 Interrupt */
+ SSP0_IRQn = 20, /*!< SSP0 Interrupt */
+ UART_IRQn = 21, /*!< UART Interrupt */
+ ADC_IRQn = 24, /*!< A/D Converter Interrupt */
+ WDT_IRQn = 25, /*!< Watchdog timer Interrupt */
+ BOD_IRQn = 26, /*!< Brown Out Detect(BOD) Interrupt */
+ EINT3_IRQn = 28, /*!< External Interrupt 3 Interrupt */
+ EINT2_IRQn = 29, /*!< External Interrupt 2 Interrupt */
+ EINT1_IRQn = 30, /*!< External Interrupt 1 Interrupt */
+ EINT0_IRQn = 31, /*!< External Interrupt 0 Interrupt */
+} IRQn_Type;
+
+
+/*
+ * ==========================================================================
+ * ----------- Processor and Core Peripheral Section ------------------------
+ * ==========================================================================
+ */
+
+/* Configuration of the Cortex-M3 Processor and Core Peripherals */
+#define __MPU_PRESENT 0 /*!< MPU present or not */
+#define __NVIC_PRIO_BITS 2 /*!< Number of Bits used for Priority Levels */
+#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */
+
+/*@}*/ /* end of group LPC11xx_CMSIS */
+
+
+#include "core_cm0.h" /* Cortex-M0 processor and core peripherals */
+#include "system_LPC11xx.h" /* System Header */
+
+
+/******************************************************************************/
+/* Device Specific Peripheral Registers structures */
+/******************************************************************************/
+
+#if defined ( __CC_ARM )
+#pragma anon_unions
+#endif
+
+/*------------- System Control (SYSCON) --------------------------------------*/
+/** @addtogroup LPC11xx_SYSCON LPC11xx System Control Block
+ @{
+*/
+typedef struct
+{
+ __IO uint32_t SYSMEMREMAP; /*!< Offset: 0x000 System memory remap (R/W) */
+ __IO uint32_t PRESETCTRL; /*!< Offset: 0x004 Peripheral reset control (R/W) */
+ __IO uint32_t SYSPLLCTRL; /*!< Offset: 0x008 System PLL control (R/W) */
+ __IO uint32_t SYSPLLSTAT; /*!< Offset: 0x00C System PLL status (R/ ) */
+ uint32_t RESERVED0[4];
+
+ __IO uint32_t SYSOSCCTRL; /*!< Offset: 0x020 System oscillator control (R/W) */
+ __IO uint32_t WDTOSCCTRL; /*!< Offset: 0x024 Watchdog oscillator control (R/W) */
+ __IO uint32_t IRCCTRL; /*!< Offset: 0x028 IRC control (R/W) */
+ uint32_t RESERVED1[1];
+ __IO uint32_t SYSRESSTAT; /*!< Offset: 0x030 System reset status Register (R/ ) */
+ uint32_t RESERVED2[3];
+ __IO uint32_t SYSPLLCLKSEL; /*!< Offset: 0x040 System PLL clock source select (R/W) */
+ __IO uint32_t SYSPLLCLKUEN; /*!< Offset: 0x044 System PLL clock source update enable (R/W) */
+ uint32_t RESERVED3[10];
+
+ __IO uint32_t MAINCLKSEL; /*!< Offset: 0x070 Main clock source select (R/W) */
+ __IO uint32_t MAINCLKUEN; /*!< Offset: 0x074 Main clock source update enable (R/W) */
+ __IO uint32_t SYSAHBCLKDIV; /*!< Offset: 0x078 System AHB clock divider (R/W) */
+ uint32_t RESERVED4[1];
+
+ __IO uint32_t SYSAHBCLKCTRL; /*!< Offset: 0x080 System AHB clock control (R/W) */
+ uint32_t RESERVED5[4];
+ __IO uint32_t SSP0CLKDIV; /*!< Offset: 0x094 SSP0 clock divider (R/W) */
+ __IO uint32_t UARTCLKDIV; /*!< Offset: 0x098 UART clock divider (R/W) */
+ __IO uint32_t SSP1CLKDIV; /*!< Offset: 0x09C SSP1 clock divider (R/W) */
+ uint32_t RESERVED6[4];
+
+ __IO uint32_t SYSTICKCLKDIV; /*!< Offset: 0x0B0 SYSTICK clock divider (R/W) */
+ uint32_t RESERVED7[7];
+
+ __IO uint32_t WDTCLKSEL; /*!< Offset: 0x0D0 WDT clock source select (R/W) */
+ __IO uint32_t WDTCLKUEN; /*!< Offset: 0x0D4 WDT clock source update enable (R/W) */
+ __IO uint32_t WDTCLKDIV; /*!< Offset: 0x0D8 WDT clock divider (R/W) */
+ uint32_t RESERVED8[1];
+ __IO uint32_t CLKOUTCLKSEL; /*!< Offset: 0x0E0 CLKOUT clock source select (R/W) */
+ __IO uint32_t CLKOUTUEN; /*!< Offset: 0x0E4 CLKOUT clock source update enable (R/W) */
+ __IO uint32_t CLKOUTDIV; /*!< Offset: 0x0E8 CLKOUT clock divider (R/W) */
+ uint32_t RESERVED9[5];
+
+ __IO uint32_t PIOPORCAP0; /*!< Offset: 0x100 POR captured PIO status 0 (R/ ) */
+ __IO uint32_t PIOPORCAP1; /*!< Offset: 0x104 POR captured PIO status 1 (R/ ) */
+ uint32_t RESERVED10[18];
+
+ __IO uint32_t BODCTRL; /*!< Offset: 0x150 BOD control (R/W) */
+ uint32_t RESERVED11[1];
+ __IO uint32_t SYSTCKCAL; /*!< Offset: 0x158 System tick counter calibration (R/W) */
+ uint32_t RESERVED12;
+ __IO uint32_t MAINREGVOUT0CFG; /*!< Offset: 0x160 Main Regulator Voltage 0 Configuration */
+ __IO uint32_t MAINREGVOUT1CFG; /*!< Offset: 0x164 Main Regulator Voltage 1 Configuration */
+ uint32_t RESERVED13[38];
+
+ __IO uint32_t STARTAPRP0; /*!< Offset: 0x200 Start logic edge control Register 0 (R/W) */
+ __IO uint32_t STARTERP0; /*!< Offset: 0x204 Start logic signal enable Register 0 (R/W) */
+ __IO uint32_t STARTRSRP0CLR; /*!< Offset: 0x208 Start logic reset Register 0 ( /W) */
+ __IO uint32_t STARTSRP0; /*!< Offset: 0x20C Start logic status Register 0 (R/W) */
+ uint32_t RESERVED14[8];
+
+ __IO uint32_t PDSLEEPCFG; /*!< Offset: 0x230 Power-down states in Deep-sleep mode (R/W) */
+ __IO uint32_t PDAWAKECFG; /*!< Offset: 0x234 Power-down states after wake-up (R/W) */
+ __IO uint32_t PDRUNCFG; /*!< Offset: 0x238 Power-down configuration Register (R/W) */
+ uint32_t RESERVED15[101];
+ __O uint32_t VOUTCFGPROT; /*!< Offset: 0x3D0 Voltage Output Configuration Protection Register (W) */
+ uint32_t RESERVED16[8];
+ __I uint32_t DEVICE_ID; /*!< Offset: 0x3F4 Device ID (R/ ) */
+} LPC_SYSCON_TypeDef;
+/*@}*/ /* end of group LPC11xx_SYSCON */
+
+
+/*------------- Pin Connect Block (IOCON) --------------------------------*/
+/** @addtogroup LPC11xx_IOCON LPC11xx I/O Configuration Block
+ @{
+*/
+typedef struct
+{
+ __IO uint32_t PIO2_6; /*!< Offset: 0x000 I/O configuration for pin PIO2_6 (R/W) */
+ uint32_t RESERVED0[1];
+ __IO uint32_t PIO2_0; /*!< Offset: 0x008 I/O configuration for pin PIO2_0/DTR/SSEL1 (R/W) */
+ __IO uint32_t RESET_PIO0_0; /*!< Offset: 0x00C I/O configuration for pin RESET/PIO0_0 (R/W) */
+ __IO uint32_t PIO0_1; /*!< Offset: 0x010 I/O configuration for pin PIO0_1/CLKOUT/CT32B0_MAT2 (R/W) */
+ __IO uint32_t PIO1_8; /*!< Offset: 0x014 I/O configuration for pin PIO1_8/CT16B1_CAP0 (R/W) */
+ uint32_t RESERVED1[1];
+ __IO uint32_t PIO0_2; /*!< Offset: 0x01C I/O configuration for pin PIO0_2/SSEL0/CT16B0_CAP0 (R/W) */
+
+ __IO uint32_t PIO2_7; /*!< Offset: 0x020 I/O configuration for pin PIO2_7 (R/W) */
+ __IO uint32_t PIO2_8; /*!< Offset: 0x024 I/O configuration for pin PIO2_8 (R/W) */
+ __IO uint32_t PIO2_1; /*!< Offset: 0x028 I/O configuration for pin PIO2_1/nDSR/SCK1 (R/W) */
+ __IO uint32_t PIO0_3; /*!< Offset: 0x02C I/O configuration for pin PIO0_3 (R/W) */
+ __IO uint32_t PIO0_4; /*!< Offset: 0x030 I/O configuration for pin PIO0_4/SCL (R/W) */
+ __IO uint32_t PIO0_5; /*!< Offset: 0x034 I/O configuration for pin PIO0_5/SDA (R/W) */
+ __IO uint32_t PIO1_9; /*!< Offset: 0x038 I/O configuration for pin PIO1_9/CT16B1_MAT0 (R/W) */
+ __IO uint32_t PIO3_4; /*!< Offset: 0x03C I/O configuration for pin PIO3_4 (R/W) */
+
+ __IO uint32_t PIO2_4; /*!< Offset: 0x040 I/O configuration for pin PIO2_4 (R/W) */
+ __IO uint32_t PIO2_5; /*!< Offset: 0x044 I/O configuration for pin PIO2_5 (R/W) */
+ __IO uint32_t PIO3_5; /*!< Offset: 0x048 I/O configuration for pin PIO3_5 (R/W) */
+ __IO uint32_t PIO0_6; /*!< Offset: 0x04C I/O configuration for pin PIO0_6/SCK0 (R/W) */
+ __IO uint32_t PIO0_7; /*!< Offset: 0x050 I/O configuration for pin PIO0_7/nCTS (R/W) */
+ __IO uint32_t PIO2_9; /*!< Offset: 0x054 I/O configuration for pin PIO2_9 (R/W) */
+ __IO uint32_t PIO2_10; /*!< Offset: 0x058 I/O configuration for pin PIO2_10 (R/W) */
+ __IO uint32_t PIO2_2; /*!< Offset: 0x05C I/O configuration for pin PIO2_2/DCD/MISO1 (R/W) */
+
+ __IO uint32_t PIO0_8; /*!< Offset: 0x060 I/O configuration for pin PIO0_8/MISO0/CT16B0_MAT0 (R/W) */
+ __IO uint32_t PIO0_9; /*!< Offset: 0x064 I/O configuration for pin PIO0_9/MOSI0/CT16B0_MAT1 (R/W) */
+ __IO uint32_t SWCLK_PIO0_10; /*!< Offset: 0x068 I/O configuration for pin SWCLK/PIO0_10/SCK0/CT16B0_MAT2 (R/W) */
+ __IO uint32_t PIO1_10; /*!< Offset: 0x06C I/O configuration for pin PIO1_10/AD6/CT16B1_MAT1 (R/W) */
+ __IO uint32_t PIO2_11; /*!< Offset: 0x070 I/O configuration for pin PIO2_11/SCK0 (R/W) */
+ __IO uint32_t R_PIO0_11; /*!< Offset: 0x074 I/O configuration for pin TDI/PIO0_11/AD0/CT32B0_MAT3 (R/W) */
+ __IO uint32_t R_PIO1_0; /*!< Offset: 0x078 I/O configuration for pin TMS/PIO1_0/AD1/CT32B1_CAP0 (R/W) */
+ __IO uint32_t R_PIO1_1; /*!< Offset: 0x07C I/O configuration for pin TDO/PIO1_1/AD2/CT32B1_MAT0 (R/W) */
+
+ __IO uint32_t R_PIO1_2; /*!< Offset: 0x080 I/O configuration for pin nTRST/PIO1_2/AD3/CT32B1_MAT1 (R/W) */
+ __IO uint32_t PIO3_0; /*!< Offset: 0x084 I/O configuration for pin PIO3_0/nDTR (R/W) */
+ __IO uint32_t PIO3_1; /*!< Offset: 0x088 I/O configuration for pin PIO3_1/nDSR (R/W) */
+ __IO uint32_t PIO2_3; /*!< Offset: 0x08C I/O configuration for pin PIO2_3/RI/MOSI1 (R/W) */
+ __IO uint32_t SWDIO_PIO1_3; /*!< Offset: 0x090 I/O configuration for pin SWDIO/PIO1_3/AD4/CT32B1_MAT2 (R/W) */
+ __IO uint32_t PIO1_4; /*!< Offset: 0x094 I/O configuration for pin PIO1_4/AD5/CT32B1_MAT3 (R/W) */
+ __IO uint32_t PIO1_11; /*!< Offset: 0x098 I/O configuration for pin PIO1_11/AD7 (R/W) */
+ __IO uint32_t PIO3_2; /*!< Offset: 0x09C I/O configuration for pin PIO3_2/nDCD (R/W) */
+
+ __IO uint32_t PIO1_5; /*!< Offset: 0x0A0 I/O configuration for pin PIO1_5/nRTS/CT32B0_CAP0 (R/W) */
+ __IO uint32_t PIO1_6; /*!< Offset: 0x0A4 I/O configuration for pin PIO1_6/RXD/CT32B0_MAT0 (R/W) */
+ __IO uint32_t PIO1_7; /*!< Offset: 0x0A8 I/O configuration for pin PIO1_7/TXD/CT32B0_MAT1 (R/W) */
+ __IO uint32_t PIO3_3; /*!< Offset: 0x0AC I/O configuration for pin PIO3_3/nRI (R/W) */
+ __IO uint32_t SCK_LOC; /*!< Offset: 0x0B0 SCK pin location select Register (R/W) */
+ __IO uint32_t DSR_LOC; /*!< Offset: 0x0B4 DSR pin location select Register (R/W) */
+ __IO uint32_t DCD_LOC; /*!< Offset: 0x0B8 DCD pin location select Register (R/W) */
+ __IO uint32_t RI_LOC; /*!< Offset: 0x0BC RI pin location Register (R/W) */
+} LPC_IOCON_TypeDef;
+/*@}*/ /* end of group LPC11xx_IOCON */
+
+
+/*------------- Power Management Unit (PMU) --------------------------*/
+/** @addtogroup LPC11xx_PMU LPC11xx Power Management Unit
+ @{
+*/
+typedef struct
+{
+ __IO uint32_t PCON; /*!< Offset: 0x000 Power control Register (R/W) */
+ __IO uint32_t GPREG0; /*!< Offset: 0x004 General purpose Register 0 (R/W) */
+ __IO uint32_t GPREG1; /*!< Offset: 0x008 General purpose Register 1 (R/W) */
+ __IO uint32_t GPREG2; /*!< Offset: 0x00C General purpose Register 2 (R/W) */
+ __IO uint32_t GPREG3; /*!< Offset: 0x010 General purpose Register 3 (R/W) */
+ __IO uint32_t GPREG4; /*!< Offset: 0x014 General purpose Register 4 (R/W) */
+} LPC_PMU_TypeDef;
+/*@}*/ /* end of group LPC11xx_PMU */
+
+
+/*------------- General Purpose Input/Output (GPIO) --------------------------*/
+/** @addtogroup LPC11xx_GPIO LPC11xx General Purpose Input/Output
+ @{
+*/
+typedef struct
+{
+ union {
+ __IO uint32_t MASKED_ACCESS[4096]; /*!< Offset: 0x0000 to 0x3FFC Port data Register for pins PIOn_0 to PIOn_11 (R/W) */
+ struct {
+ uint32_t RESERVED0[4095];
+ __IO uint32_t DATA; /*!< Offset: 0x3FFC Port data Register (R/W) */
+ };
+ };
+ uint32_t RESERVED1[4096];
+ __IO uint32_t DIR; /*!< Offset: 0x8000 Data direction Register (R/W) */
+ __IO uint32_t IS; /*!< Offset: 0x8004 Interrupt sense Register (R/W) */
+ __IO uint32_t IBE; /*!< Offset: 0x8008 Interrupt both edges Register (R/W) */
+ __IO uint32_t IEV; /*!< Offset: 0x800C Interrupt event Register (R/W) */
+ __IO uint32_t IE; /*!< Offset: 0x8010 Interrupt mask Register (R/W) */
+ __IO uint32_t RIS; /*!< Offset: 0x8014 Raw interrupt status Register (R/ ) */
+ __IO uint32_t MIS; /*!< Offset: 0x8018 Masked interrupt status Register (R/ ) */
+ __IO uint32_t IC; /*!< Offset: 0x801C Interrupt clear Register (R/W) */
+} LPC_GPIO_TypeDef;
+/*@}*/ /* end of group LPC11xx_GPIO */
+
+
+/*------------- Timer (TMR) --------------------------------------------------*/
+/** @addtogroup LPC11xx_TMR LPC11xx 16/32-bit Counter/Timer
+ @{
+*/
+typedef struct
+{
+ __IO uint32_t IR; /*!< Offset: 0x000 Interrupt Register (R/W) */
+ __IO uint32_t TCR; /*!< Offset: 0x004 Timer Control Register (R/W) */
+ __IO uint32_t TC; /*!< Offset: 0x008 Timer Counter Register (R/W) */
+ __IO uint32_t PR; /*!< Offset: 0x00C Prescale Register (R/W) */
+ __IO uint32_t PC; /*!< Offset: 0x010 Prescale Counter Register (R/W) */
+ __IO uint32_t MCR; /*!< Offset: 0x014 Match Control Register (R/W) */
+ __IO uint32_t MR0; /*!< Offset: 0x018 Match Register 0 (R/W) */
+ __IO uint32_t MR1; /*!< Offset: 0x01C Match Register 1 (R/W) */
+ __IO uint32_t MR2; /*!< Offset: 0x020 Match Register 2 (R/W) */
+ __IO uint32_t MR3; /*!< Offset: 0x024 Match Register 3 (R/W) */
+ __IO uint32_t CCR; /*!< Offset: 0x028 Capture Control Register (R/W) */
+ __I uint32_t CR0; /*!< Offset: 0x02C Capture Register 0 (R/ ) */
+ uint32_t RESERVED1[3];
+ __IO uint32_t EMR; /*!< Offset: 0x03C External Match Register (R/W) */
+ uint32_t RESERVED2[12];
+ __IO uint32_t CTCR; /*!< Offset: 0x070 Count Control Register (R/W) */
+ __IO uint32_t PWMC; /*!< Offset: 0x074 PWM Control Register (R/W) */
+} LPC_TMR_TypeDef;
+/*@}*/ /* end of group LPC11xx_TMR */
+
+
+/*------------- Universal Asynchronous Receiver Transmitter (UART) -----------*/
+/** @addtogroup LPC11xx_UART LPC11xx Universal Asynchronous Receiver/Transmitter
+ @{
+*/
+typedef struct
+{
+ union {
+ __I uint32_t RBR; /*!< Offset: 0x000 Receiver Buffer Register (R/ ) */
+ __O uint32_t THR; /*!< Offset: 0x000 Transmit Holding Register ( /W) */
+ __IO uint32_t DLL; /*!< Offset: 0x000 Divisor Latch LSB (R/W) */
+ };
+ union {
+ __IO uint32_t DLM; /*!< Offset: 0x004 Divisor Latch MSB (R/W) */
+ __IO uint32_t IER; /*!< Offset: 0x000 Interrupt Enable Register (R/W) */
+ };
+ union {
+ __I uint32_t IIR; /*!< Offset: 0x008 Interrupt ID Register (R/ ) */
+ __O uint32_t FCR; /*!< Offset: 0x008 FIFO Control Register ( /W) */
+ };
+ __IO uint32_t LCR; /*!< Offset: 0x00C Line Control Register (R/W) */
+ __IO uint32_t MCR; /*!< Offset: 0x010 Modem control Register (R/W) */
+ __I uint32_t LSR; /*!< Offset: 0x014 Line Status Register (R/ ) */
+ __I uint32_t MSR; /*!< Offset: 0x018 Modem status Register (R/ ) */
+ __IO uint32_t SCR; /*!< Offset: 0x01C Scratch Pad Register (R/W) */
+ __IO uint32_t ACR; /*!< Offset: 0x020 Auto-baud Control Register (R/W) */
+ uint32_t RESERVED0;
+ __IO uint32_t FDR; /*!< Offset: 0x028 Fractional Divider Register (R/W) */
+ uint32_t RESERVED1;
+ __IO uint32_t TER; /*!< Offset: 0x030 Transmit Enable Register (R/W) */
+ uint32_t RESERVED2[6];
+ __IO uint32_t RS485CTRL; /*!< Offset: 0x04C RS-485/EIA-485 Control Register (R/W) */
+ __IO uint32_t ADRMATCH; /*!< Offset: 0x050 RS-485/EIA-485 address match Register (R/W) */
+ __IO uint32_t RS485DLY; /*!< Offset: 0x054 RS-485/EIA-485 direction control delay Register (R/W) */
+ __I uint32_t FIFOLVL; /*!< Offset: 0x058 FIFO Level Register (R/ ) */
+} LPC_UART_TypeDef;
+/*@}*/ /* end of group LPC11xx_UART */
+
+
+/*------------- Synchronous Serial Communication (SSP) -----------------------*/
+/** @addtogroup LPC11xx_SSP LPC11xx Synchronous Serial Port
+ @{
+*/
+typedef struct
+{
+ __IO uint32_t CR0; /*!< Offset: 0x000 Control Register 0 (R/W) */
+ __IO uint32_t CR1; /*!< Offset: 0x004 Control Register 1 (R/W) */
+ __IO uint32_t DR; /*!< Offset: 0x008 Data Register (R/W) */
+ __I uint32_t SR; /*!< Offset: 0x00C Status Registe (R/ ) */
+ __IO uint32_t CPSR; /*!< Offset: 0x010 Clock Prescale Register (R/W) */
+ __IO uint32_t IMSC; /*!< Offset: 0x014 Interrupt Mask Set and Clear Register (R/W) */
+ __IO uint32_t RIS; /*!< Offset: 0x018 Raw Interrupt Status Register (R/W) */
+ __IO uint32_t MIS; /*!< Offset: 0x01C Masked Interrupt Status Register (R/W) */
+ __IO uint32_t ICR; /*!< Offset: 0x020 SSPICR Interrupt Clear Register (R/W) */
+} LPC_SSP_TypeDef;
+/*@}*/ /* end of group LPC11xx_SSP */
+
+
+/*------------- Inter-Integrated Circuit (I2C) -------------------------------*/
+/** @addtogroup LPC11xx_I2C LPC11xx I2C-Bus Interface
+ @{
+*/
+typedef struct
+{
+ __IO uint32_t CONSET; /*!< Offset: 0x000 I2C Control Set Register (R/W) */
+ __I uint32_t STAT; /*!< Offset: 0x004 I2C Status Register (R/ ) */
+ __IO uint32_t DAT; /*!< Offset: 0x008 I2C Data Register (R/W) */
+ __IO uint32_t ADR0; /*!< Offset: 0x00C I2C Slave Address Register 0 (R/W) */
+ __IO uint32_t SCLH; /*!< Offset: 0x010 SCH Duty Cycle Register High Half Word (R/W) */
+ __IO uint32_t SCLL; /*!< Offset: 0x014 SCL Duty Cycle Register Low Half Word (R/W) */
+ __O uint32_t CONCLR; /*!< Offset: 0x018 I2C Control Clear Register ( /W) */
+ __IO uint32_t MMCTRL; /*!< Offset: 0x01C Monitor mode control register (R/W) */
+ __IO uint32_t ADR1; /*!< Offset: 0x020 I2C Slave Address Register 1 (R/W) */
+ __IO uint32_t ADR2; /*!< Offset: 0x024 I2C Slave Address Register 2 (R/W) */
+ __IO uint32_t ADR3; /*!< Offset: 0x028 I2C Slave Address Register 3 (R/W) */
+ __I uint32_t DATA_BUFFER; /*!< Offset: 0x02C Data buffer register ( /W) */
+ __IO uint32_t MASK0; /*!< Offset: 0x030 I2C Slave address mask register 0 (R/W) */
+ __IO uint32_t MASK1; /*!< Offset: 0x034 I2C Slave address mask register 1 (R/W) */
+ __IO uint32_t MASK2; /*!< Offset: 0x038 I2C Slave address mask register 2 (R/W) */
+ __IO uint32_t MASK3; /*!< Offset: 0x03C I2C Slave address mask register 3 (R/W) */
+} LPC_I2C_TypeDef;
+/*@}*/ /* end of group LPC11xx_I2C */
+
+
+/*------------- Watchdog Timer (WDT) -----------------------------------------*/
+/** @addtogroup LPC11xx_WDT LPC11xx WatchDog Timer
+ @{
+*/
+typedef struct
+{
+ __IO uint32_t MOD; /*!< Offset: 0x000 Watchdog mode register (R/W) */
+ __IO uint32_t TC; /*!< Offset: 0x004 Watchdog timer constant register (R/W) */
+ __O uint32_t FEED; /*!< Offset: 0x008 Watchdog feed sequence register ( /W) */
+ __I uint32_t TV; /*!< Offset: 0x00C Watchdog timer value register (R/ ) */
+ uint32_t RESERVED0;
+ __IO uint32_t WARNINT;
+ __IO uint32_t WINDOW;
+} LPC_WDT_TypeDef;
+/*@}*/ /* end of group LPC11xx_WDT */
+
+
+/*------------- Analog-to-Digital Converter (ADC) ----------------------------*/
+/** @addtogroup LPC11xx_ADC LPC11xx Analog-to-Digital Converter
+ @{
+*/
+typedef struct
+{
+ __IO uint32_t CR; /*!< Offset: 0x000 A/D Control Register (R/W) */
+ __IO uint32_t GDR; /*!< Offset: 0x004 A/D Global Data Register (R/W) */
+ uint32_t RESERVED0;
+ __IO uint32_t INTEN; /*!< Offset: 0x00C A/D Interrupt Enable Register (R/W) */
+ __IO uint32_t DR[8]; /*!< Offset: 0x010-0x02C A/D Channel 0..7 Data Register (R/W) */
+ __I uint32_t STAT; /*!< Offset: 0x030 A/D Status Register (R/ ) */
+} LPC_ADC_TypeDef;
+/*@}*/ /* end of group LPC11xx_ADC */
+
+
+/*------------- CAN Controller (CAN) ----------------------------*/
+/** @addtogroup LPC11xx_CAN LPC11xx Controller Area Network(CAN)
+ @{
+*/
+typedef struct
+{
+ __IO uint32_t CNTL; /* 0x000 */
+ __IO uint32_t STAT;
+ __IO uint32_t EC;
+ __IO uint32_t BT;
+ __IO uint32_t INT;
+ __IO uint32_t TEST;
+ __IO uint32_t BRPE;
+ uint32_t RESERVED0;
+ __IO uint32_t IF1_CMDREQ; /* 0x020 */
+ __IO uint32_t IF1_CMDMSK;
+ __IO uint32_t IF1_MSK1;
+ __IO uint32_t IF1_MSK2;
+ __IO uint32_t IF1_ARB1;
+ __IO uint32_t IF1_ARB2;
+ __IO uint32_t IF1_MCTRL;
+ __IO uint32_t IF1_DA1;
+ __IO uint32_t IF1_DA2;
+ __IO uint32_t IF1_DB1;
+ __IO uint32_t IF1_DB2;
+ uint32_t RESERVED1[13];
+ __IO uint32_t IF2_CMDREQ; /* 0x080 */
+ __IO uint32_t IF2_CMDMSK;
+ __IO uint32_t IF2_MSK1;
+ __IO uint32_t IF2_MSK2;
+ __IO uint32_t IF2_ARB1;
+ __IO uint32_t IF2_ARB2;
+ __IO uint32_t IF2_MCTRL;
+ __IO uint32_t IF2_DA1;
+ __IO uint32_t IF2_DA2;
+ __IO uint32_t IF2_DB1;
+ __IO uint32_t IF2_DB2;
+ uint32_t RESERVED2[21];
+ __I uint32_t TXREQ1; /* 0x100 */
+ __I uint32_t TXREQ2;
+ uint32_t RESERVED3[6];
+ __I uint32_t ND1; /* 0x120 */
+ __I uint32_t ND2;
+ uint32_t RESERVED4[6];
+ __I uint32_t IR1; /* 0x140 */
+ __I uint32_t IR2;
+ uint32_t RESERVED5[6];
+ __I uint32_t MSGV1; /* 0x160 */
+ __I uint32_t MSGV2;
+ uint32_t RESERVED6[6];
+ __IO uint32_t CLKDIV; /* 0x180 */
+} LPC_CAN_TypeDef;
+/*@}*/ /* end of group LPC11xx_CAN */
+
+#if defined ( __CC_ARM )
+#pragma no_anon_unions
+#endif
+
+/******************************************************************************/
+/* Peripheral memory map */
+/******************************************************************************/
+/* Base addresses */
+#define LPC_FLASH_BASE (0x00000000UL)
+#define LPC_RAM_BASE (0x10000000UL)
+#define LPC_APB0_BASE (0x40000000UL)
+#define LPC_AHB_BASE (0x50000000UL)
+
+/* APB0 peripherals */
+#define LPC_I2C_BASE (LPC_APB0_BASE + 0x00000)
+#define LPC_WDT_BASE (LPC_APB0_BASE + 0x04000)
+#define LPC_UART_BASE (LPC_APB0_BASE + 0x08000)
+#define LPC_CT16B0_BASE (LPC_APB0_BASE + 0x0C000)
+#define LPC_CT16B1_BASE (LPC_APB0_BASE + 0x10000)
+#define LPC_CT32B0_BASE (LPC_APB0_BASE + 0x14000)
+#define LPC_CT32B1_BASE (LPC_APB0_BASE + 0x18000)
+#define LPC_ADC_BASE (LPC_APB0_BASE + 0x1C000)
+#define LPC_PMU_BASE (LPC_APB0_BASE + 0x38000)
+#define LPC_SSP0_BASE (LPC_APB0_BASE + 0x40000)
+#define LPC_IOCON_BASE (LPC_APB0_BASE + 0x44000)
+#define LPC_SYSCON_BASE (LPC_APB0_BASE + 0x48000)
+#define LPC_CAN_BASE (LPC_APB0_BASE + 0x50000)
+#define LPC_SSP1_BASE (LPC_APB0_BASE + 0x58000)
+
+/* AHB peripherals */
+#define LPC_GPIO_BASE (LPC_AHB_BASE + 0x00000)
+#define LPC_GPIO0_BASE (LPC_AHB_BASE + 0x00000)
+#define LPC_GPIO1_BASE (LPC_AHB_BASE + 0x10000)
+#define LPC_GPIO2_BASE (LPC_AHB_BASE + 0x20000)
+#define LPC_GPIO3_BASE (LPC_AHB_BASE + 0x30000)
+
+/******************************************************************************/
+/* Peripheral declaration */
+/******************************************************************************/
+#define LPC_I2C ((LPC_I2C_TypeDef *) LPC_I2C_BASE )
+#define LPC_WDT ((LPC_WDT_TypeDef *) LPC_WDT_BASE )
+#define LPC_UART ((LPC_UART_TypeDef *) LPC_UART_BASE )
+#define LPC_TMR16B0 ((LPC_TMR_TypeDef *) LPC_CT16B0_BASE)
+#define LPC_TMR16B1 ((LPC_TMR_TypeDef *) LPC_CT16B1_BASE)
+#define LPC_TMR32B0 ((LPC_TMR_TypeDef *) LPC_CT32B0_BASE)
+#define LPC_TMR32B1 ((LPC_TMR_TypeDef *) LPC_CT32B1_BASE)
+#define LPC_ADC ((LPC_ADC_TypeDef *) LPC_ADC_BASE )
+#define LPC_PMU ((LPC_PMU_TypeDef *) LPC_PMU_BASE )
+#define LPC_SSP0 ((LPC_SSP_TypeDef *) LPC_SSP0_BASE )
+#define LPC_SSP1 ((LPC_SSP_TypeDef *) LPC_SSP1_BASE )
+#define LPC_CAN ((LPC_CAN_TypeDef *) LPC_CAN_BASE )
+#define LPC_IOCON ((LPC_IOCON_TypeDef *) LPC_IOCON_BASE )
+#define LPC_SYSCON ((LPC_SYSCON_TypeDef *) LPC_SYSCON_BASE)
+#define LPC_GPIO0 ((LPC_GPIO_TypeDef *) LPC_GPIO0_BASE )
+#define LPC_GPIO1 ((LPC_GPIO_TypeDef *) LPC_GPIO1_BASE )
+#define LPC_GPIO2 ((LPC_GPIO_TypeDef *) LPC_GPIO2_BASE )
+#define LPC_GPIO3 ((LPC_GPIO_TypeDef *) LPC_GPIO3_BASE )
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __LPC11xx_H__ */
diff --git a/src/core/SPI.cpp b/src/core/SPI.cpp
new file mode 100755
index 0000000..53108a9
--- /dev/null
+++ b/src/core/SPI.cpp
@@ -0,0 +1,213 @@
+/*
+ * ssp.cpp
+ *
+ * Created on: 2011/07/30
+ * Author: lynxeyed
+ */
+#include "gpio.h"
+#include "SPI.h"
+
+
+SSP SPI;
+
+SSP::SSP() //define constructor
+{
+ this->port = marySSP0;
+ bitOrder = LSBFIRST;
+ divider = SPI_CLOCK_DIV4; //Arduino's default
+ dataMode = SPI_MODE0;
+ bitlength = 8;
+ setClockDivider(divider);
+ setBitLength(bitlength);
+ setBitOrder(LSBFIRST);
+ begin();
+}
+
+SSP::~SSP() // destructor
+{
+
+}
+void SSP::begin()
+{
+ ssp_begin(port,divider,dataMode,bitlength);
+ return;
+}
+void SSP::begin(SSP_PORT port)
+{
+ this->port = port;
+ ssp_begin(port,divider,dataMode,bitlength);
+ return;
+}
+void SSP::setBitLength(int bitlength)
+{
+ this->bitlength = bitlength;
+ return;
+}
+void SSP::end()
+{
+ LPC_SSP0->CR1 &= ~(1U << 1); //the SPI controller is disabled
+ return;
+}
+
+void SSP::setBitOrder(SSP_BIT_ORDER bitOrder)
+{
+ this->bitOrder = bitOrder;
+ if(bitOrder == MSBFIRST)
+ {
+ ;
+ }
+ else
+ {
+ ;
+ }
+ return;
+}
+
+void SSP::setClockDivider(SSP_CLK_DIVIDER divider) //See also SSP1CLKDIV(user.manual p.24)
+{
+ this->divider = divider;
+ return;
+
+}
+
+void SSP::setDataMode(SSP_DATA_MODE mode)
+{
+ this->dataMode = mode;
+
+}
+
+unsigned long SSP::transfer(unsigned long txdata)
+{
+ return ssp_transfer(txdata);
+}
+
+
+
+// lowlevel
+
+void ssp_begin(SSP_PORT port,SSP_CLK_DIVIDER divider,SSP_DATA_MODE dataMode,int bitlength)
+{
+ // Initialize SSP
+ // PIO0_2(CN3_3) : SSEL
+ // PIO0_6(CN4_3) : SCLK
+ // PIO0_8(CN4_5) : MISO
+ // PIO0_9(CN4_7) : MOSI
+
+ volatile int sspPhase; //SSP's clock phase
+
+ pinMode(P0_2,OUTPUT); // PIO0_2(CN3_3) out
+ LPC_IOCON->PIO0_2 = 0x00000000; // GPIO, disable pu/pd mos
+ digitalWrite(P0_2,HIGH); // PIO0_2(CN3_3) = 1
+
+ switch(port){
+ case LPCXSSP0:
+ LPC_IOCON->SCK_LOC = 0x00000001;//2; // SCK is PIO2_11
+ LPC_IOCON->PIO2_11 = 0x00000001;//2; // SCK, disable pu/pd mos
+ break;
+ case marySSP0:
+ LPC_IOCON->SCK_LOC = 0x00000002; // SCK is PIO0_6
+ LPC_IOCON->PIO0_6 = 0x00000002; // SCK, disable pu/pd mos
+ break;
+ default: //default = MARY
+ LPC_IOCON->SCK_LOC = 0x00000002; // SCK is PIO0_6
+ LPC_IOCON->PIO0_6 = 0x00000002; // SCK, disable pu/pd mos
+ break;
+ }
+ LPC_IOCON->PIO0_9 = 0x00000001; // MOSI, disable pu/pd mos
+ LPC_IOCON->PIO0_8 = 0x00000011; // MISO, enable pu/pd mos
+
+ //
+ // Initialize SPI
+ //
+ LPC_SYSCON->PRESETCTRL |= (0x1<<0);
+ LPC_SYSCON->SYSAHBCLKCTRL |= (1<<11);
+ //clockDivider
+ LPC_SYSCON->SSP0CLKDIV = 0x01; // Divided by 1
+ switch(divider)
+ {
+ case SPI_CLOCK_DIV1: //Special code
+ LPC_SYSCON->SSP0CLKDIV = 0x01;
+ break;
+ case SPI_CLOCK_DIV2:
+ LPC_SYSCON->SSP0CLKDIV = 0x02;
+ break;
+ case SPI_CLOCK_DIV4:
+ LPC_SYSCON->SSP0CLKDIV = 0x04;
+ break;
+ case SPI_CLOCK_DIV8:
+ LPC_SYSCON->SSP0CLKDIV = 0x08;
+ break;
+ case SPI_CLOCK_DIV16:
+ LPC_SYSCON->SSP0CLKDIV = 0x10;
+ break;
+ case SPI_CLOCK_DIV32:
+ LPC_SYSCON->SSP0CLKDIV = 0x20;
+ break;
+ case SPI_CLOCK_DIV64:
+ LPC_SYSCON->SSP0CLKDIV = 0x40;
+ break;
+ case SPI_CLOCK_DIV128:
+ LPC_SYSCON->SSP0CLKDIV = 0x80;
+ break;
+ default:
+ LPC_SYSCON->SSP0CLKDIV = 0x04; //default
+ break;
+ }
+ // dataMode(MODE0,1,2,3)
+ switch(dataMode)
+ {
+ // SSP0CR0::bit6 = CPOL, bit7 = CPHA
+ case SPI_MODE0: // CPOL=0, CPHA = 0
+ sspPhase = 0;
+ break;
+ case SPI_MODE1: // CPOL=0, CPHA = 1
+ sspPhase = 1;
+ break;
+ case SPI_MODE2: // CPOL=1, CPHA = 0
+ sspPhase = 2;
+ break;
+ case SPI_MODE3: // CPOL=1, CPHA = 1
+ sspPhase = 3;
+ break;
+ case TI_SERIAL_MODE:
+ default:
+ break;
+ }//end switch(dataMode)
+
+ // bitLength
+ LPC_SSP0->CR0 = (sspPhase << 6);
+ LPC_SSP0->CR0 |= (bitlength - 1);
+
+ //SCLKDivider
+ LPC_SSP0->CPSR = 2; //2 or more but even value
+
+
+ // Enable the SSP Interrupt
+ NVIC_EnableIRQ(SSP0_IRQn);
+ NVIC_SetPriority(SSP0_IRQn, 3);
+
+ // Device select as master, SSP Enabled (see also user.manual p.143)
+ LPC_SSP0->CR1 = (1U << 1);
+ return;
+}
+
+unsigned long ssp_transfer(unsigned long txdata)
+{
+ volatile unsigned long rxdata;
+ // Tx
+ while ((LPC_SSP0->SR & ((1U<<1)|(1U<<4))) != 1U << 1);
+ // Send a byte
+ LPC_SSP0->DR = txdata;
+ // Wait until the Busy bit is cleared
+ while ( LPC_SSP0->SR & (1<<4) );
+
+ // Rx
+ while ((LPC_SSP0->SR & (1U<<2)) != 1U << 2 );
+ rxdata = LPC_SSP0->DR;
+
+ return rxdata;
+}
+
+
+
+
diff --git a/src/core/SPI.h b/src/core/SPI.h
new file mode 100755
index 0000000..6040e74
--- /dev/null
+++ b/src/core/SPI.h
@@ -0,0 +1,120 @@
+#ifndef SSP_H_
+#define SSP_H_
+
+
+/**************************************************************************//**
+ * @file SPI.h
+ * @brief Arduino-like library for MARY
+ * @version V0.50
+ * @date 1. August 2011.
+ * @author @@lynxeyed_atsu
+ * @note Copyright (c) 2011 Lynx-EyED's Klavier and Craft-works. <BR>
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions: <BR>
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.<BR>
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ******************************************************************************/
+
+#include "LPC11xx.h"
+#include "gpio.h"
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/*! @enum SSP_PORT
+ @brief SPIポートのチャンネル選択。使用時のCS信号を選択する
+ @note SPIが1ポートしかないMARYでは使用していないので特に影響はないが、2ポート以上あるLPCXpressoやmbedシリーズとの後方互換性を考慮し用意している
+*/
+typedef enum {
+ marySSP0, /*!< MARYのSSPポート(デフォルト) */
+ LPCXSSP0, /*!< LPCXPressoのSSP0ポート */
+ LPCXSSP1 /*!< LPCXpressoのSSP1ポート */
+} SSP_PORT; // Defaults:marySSP1
+
+/*! @enum SSP_BIT_ORDER
+ @brief SSPIバスの入出力に使用するビットオーダーを設定
+ @warning この機能はまだ実装されていない
+ */
+typedef enum {
+ LSBFIRST, /*!< LSBを最初に送出(least-significant bit first) */
+ MSBFIRST /*!< MSBを最初に送出(most-significant bit first) */
+} SSP_BIT_ORDER;
+
+/*! @enum SSP_CLK_DIVIDER
+ @brief SPIクロック分周器の設定. 分周値は2、4、8、16、32、64、128のいずれか
+*/
+typedef enum {
+ SPI_CLOCK_DIV1, /*!< SPIクロックはシステムクロックと同じ(MARY-DUINOオリジナル) */
+ SPI_CLOCK_DIV2, /*!< SPIクロックはシステムクロックの1/2 */
+ SPI_CLOCK_DIV4, /*!< SPIクロックはシステムクロックの1/4 */
+ SPI_CLOCK_DIV8, /*!< SPIクロックはシステムクロックの1/8 */
+ SPI_CLOCK_DIV16, /*!< SPIクロックはシステムクロックの1/16 */
+ SPI_CLOCK_DIV32, /*!< SPIクロックはシステムクロックの1/32 */
+ SPI_CLOCK_DIV64, /*!< SPIクロックはシステムクロックの1/64 */
+ SPI_CLOCK_DIV128 /*!< SPIクロックはシステムクロックの1/128 */
+} SSP_CLK_DIVIDER;
+
+/*! @enum SSP_DATA_MODE
+ @brief SPIの転送モードの設定
+*/
+typedef enum {
+ SPI_MODE0 , /*!< SPIモード0 ( CPOL = 0, CPHA = 0 ) */
+ SPI_MODE1 , /*!< SPIモード1 ( CPOL = 0, CPHA = 1 ) */
+ SPI_MODE2 , /*!< SPIモード2 ( CPOL = 1, CPHA = 0 ) */
+ SPI_MODE3 , /*!< SPIモード3 ( CPOL = 1, CPHA = 1 ) */
+ TI_SERIAL_MODE , /*!< Texas Instrumentsの提唱するシリアル方式 */
+ NXP_I2S /*!< I2Sモード(I2S搭載機種のみ) */
+} SSP_DATA_MODE;
+
+/*! @class SSP
+ @brief SPIを制御するクラス
+*/
+class SSP {
+private:
+ SSP_PORT port; /*!< 使用するポート */
+ SSP_BIT_ORDER bitOrder;
+ SSP_CLK_DIVIDER divider;
+ SSP_DATA_MODE dataMode;
+ int bitlength;
+
+public:
+ SSP(); // announce the constructor to initialize
+ ~SSP();
+ void begin();
+ void begin(SSP_PORT port);
+ void end();
+ void setBitLength(int bitLength);
+ void setBitOrder(SSP_BIT_ORDER bitOrder) ;
+ void setClockDivider(SSP_CLK_DIVIDER divider);
+ void setDataMode(SSP_DATA_MODE mode);
+ unsigned long transfer(unsigned long txdata) ;
+};
+
+
+// lowlevel
+void ssp_begin(SSP_PORT port,SSP_CLK_DIVIDER divider,SSP_DATA_MODE dataMode,int bitLength);
+unsigned long ssp_transfer(unsigned long txdata);
+
+
+
+extern SSP SPI;
+
+
+#ifdef __cplusplus
+ }
+#endif
+
+
+#endif /* SSP_H_ */
diff --git a/src/core/SPI1.cpp b/src/core/SPI1.cpp
new file mode 100755
index 0000000..a164004
--- /dev/null
+++ b/src/core/SPI1.cpp
@@ -0,0 +1,220 @@
+/*
+ * ssp.cpp
+ *
+ * Created on: 2011/07/30
+ * Author: lynxeyed
+ */
+#include "gpio.h"
+#include "SPI1.h"
+
+
+SSP1 SPI1;
+
+SSP1::SSP1() //define constructor
+{
+ this->port = LPCXSSP1;
+ bitOrder = LSBFIRST;
+ divider = SPI_CLOCK_DIV4; //Arduino's default
+ dataMode = SPI_MODE0;
+ bitlength = 8;
+ setClockDivider(divider);
+ setBitLength(bitlength);
+ setBitOrder(LSBFIRST);
+ begin();
+}
+
+SSP1::~SSP1() // destructor
+{
+
+}
+void SSP1::begin()
+{
+ ssp1_begin(port,divider,dataMode,bitlength);
+ return;
+}
+void SSP1::begin(SSP_PORT port)
+{
+ this->port = port;
+ ssp1_begin(port,divider,dataMode,bitlength);
+ return;
+}
+void SSP1::setBitLength(int bitlength)
+{
+ this->bitlength = bitlength;
+ return;
+}
+void SSP1::end()
+{
+ LPC_SSP1->CR1 &= ~(1U << 1); //the SPI controller is disabled
+ return;
+}
+
+void SSP1::setBitOrder(SSP_BIT_ORDER bitOrder)
+{
+ this->bitOrder = bitOrder;
+ if(bitOrder == MSBFIRST)
+ {
+ ;
+ }
+ else
+ {
+ ;
+ }
+ return;
+}
+
+void SSP1::setClockDivider(SSP_CLK_DIVIDER divider) //See also SSP1CLKDIV(user.manual p.24)
+{
+ this->divider = divider;
+ return;
+
+}
+
+void SSP1::setDataMode(SSP_DATA_MODE mode)
+{
+ this->dataMode = mode;
+
+}
+
+unsigned long SSP1::transfer(unsigned long txdata)
+{
+ return ssp1_transfer(txdata);
+}
+
+
+
+// lowlevel
+
+void ssp1_begin(SSP_PORT port,SSP_CLK_DIVIDER divider,SSP_DATA_MODE dataMode,int bitlength)
+{
+ // Initialize SSP
+ // PIO2_0 : SSEL
+ // PIO2_1 : SCLK
+ // PIO2_2 : MISO
+ // PIO2_3 : MOSI
+
+ volatile int sspPhase; //SSP's clock phase
+
+ pinMode(P2_0,OUTPUT); // PIO2_0 out
+ LPC_IOCON->PIO2_0 = 0x00000000; // GPIO, disable pu/pd mos
+ digitalWrite(P2_0,HIGH); // PIO2_0 = 1
+
+ LPC_IOCON->PIO2_1 = 0x00000002; // SCK, disable pu/pd mos
+ LPC_IOCON->PIO2_3 = 0x00000002; // MOSI, disable pu/pd mos
+ LPC_IOCON->PIO2_2 = 0x00000012; // MISO, enable pu/pd mos
+
+ /*
+ switch(port){
+ case LPCXSSP0:
+ LPC_IOCON->SCK_LOC = 0x00000001;//2; // SCK is PIO2_11
+ LPC_IOCON->PIO2_11 = 0x00000001;//2; // SCK, disable pu/pd mos
+ break;
+ case marySSP0:
+ LPC_IOCON->SCK_LOC = 0x00000002; // SCK is PIO0_6
+ LPC_IOCON->PIO0_6 = 0x00000002; // SCK, disable pu/pd mos
+ break;
+ default: //default = MARY
+ LPC_IOCON->SCK_LOC = 0x00000002; // SCK is PIO0_6
+ LPC_IOCON->PIO0_6 = 0x00000002; // SCK, disable pu/pd mos
+ break;
+ }
+ */
+
+ //LPC_IOCON->PIO0_9 = 0x00000001; // MOSI, disable pu/pd mos
+ //LPC_IOCON->PIO0_8 = 0x00000011; // MISO, enable pu/pd mos
+
+ //
+ // Initialize SPI
+ //
+ LPC_SYSCON->PRESETCTRL |= (0x1<<2);
+ LPC_SYSCON->SYSAHBCLKCTRL |= (1<<18);
+ //clockDivider
+ LPC_SYSCON->SSP1CLKDIV = 0x01; // Divided by 1
+ switch(divider)
+ {
+ case SPI_CLOCK_DIV1: //Special code
+ LPC_SYSCON->SSP1CLKDIV = 0x01;
+ break;
+ case SPI_CLOCK_DIV2:
+ LPC_SYSCON->SSP1CLKDIV = 0x02;
+ break;
+ case SPI_CLOCK_DIV4:
+ LPC_SYSCON->SSP1CLKDIV = 0x04;
+ break;
+ case SPI_CLOCK_DIV8:
+ LPC_SYSCON->SSP1CLKDIV = 0x08;
+ break;
+ case SPI_CLOCK_DIV16:
+ LPC_SYSCON->SSP1CLKDIV = 0x10;
+ break;
+ case SPI_CLOCK_DIV32:
+ LPC_SYSCON->SSP1CLKDIV = 0x20;
+ break;
+ case SPI_CLOCK_DIV64:
+ LPC_SYSCON->SSP1CLKDIV = 0x40;
+ break;
+ case SPI_CLOCK_DIV128:
+ LPC_SYSCON->SSP1CLKDIV = 0x80;
+ break;
+ default:
+ LPC_SYSCON->SSP1CLKDIV = 0x04; //default
+ break;
+ }
+ // dataMode(MODE0,1,2,3)
+ switch(dataMode)
+ {
+ // SSP0CR0::bit6 = CPOL, bit7 = CPHA
+ case SPI_MODE0: // CPOL=0, CPHA = 0
+ sspPhase = 0;
+ break;
+ case SPI_MODE1: // CPOL=0, CPHA = 1
+ sspPhase = 1;
+ break;
+ case SPI_MODE2: // CPOL=1, CPHA = 0
+ sspPhase = 2;
+ break;
+ case SPI_MODE3: // CPOL=1, CPHA = 1
+ sspPhase = 3;
+ break;
+ case TI_SERIAL_MODE:
+ default:
+ break;
+ }//end switch(dataMode)
+
+ // bitLength
+ LPC_SSP1->CR0 = (sspPhase << 6);
+ LPC_SSP1->CR0 |= (bitlength - 1);
+
+ //SCLKDivider
+ LPC_SSP1->CPSR = 2; //2 or more but even value
+
+
+ // Enable the SSP Interrupt
+ NVIC_EnableIRQ(SSP1_IRQn);
+ NVIC_SetPriority(SSP1_IRQn, 3);
+
+ // Device select as master, SSP Enabled (see also user.manual p.143)
+ LPC_SSP1->CR1 = (1U << 1);
+ return;
+}
+
+unsigned long ssp1_transfer(unsigned long txdata)
+{
+ volatile unsigned long rxdata;
+ // Tx
+ while ((LPC_SSP1->SR & ((1U<<1)|(1U<<4))) != 1U << 1);
+ // Send a byte
+ LPC_SSP1->DR = txdata;
+ // Wait until the Busy bit is cleared
+ while ( LPC_SSP1->SR & (1<<4) );
+
+ // Rx
+ while ((LPC_SSP1->SR & (1U<<2)) != 1U << 2 );
+ rxdata = LPC_SSP1->DR;
+
+ return rxdata;
+}
+
+
+
+
diff --git a/src/core/SPI1.h b/src/core/SPI1.h
new file mode 100755
index 0000000..6863b8f
--- /dev/null
+++ b/src/core/SPI1.h
@@ -0,0 +1,77 @@
+#ifndef SSP1_H_
+#define SSP1_H_
+
+
+/**************************************************************************//**
+ * @file SPI1.h
+ * @brief Arduino-like library for MARY
+ * @version V0.50
+ * @date 1. August 2011.
+ * @author @@lynxeyed_atsu
+ * @note Copyright (c) 2011 Lynx-EyED's Klavier and Craft-works. <BR>
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions: <BR>
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.<BR>
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ******************************************************************************/
+
+#include "LPC11xx.h"
+#include "gpio.h"
+#include "SPI.h"
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+/*! @class SSP1
+ @brief SPI1を制御するクラス
+*/
+class SSP1 {
+private:
+ SSP_PORT port; /*!< 使用するポート */
+ SSP_BIT_ORDER bitOrder;
+ SSP_CLK_DIVIDER divider;
+ SSP_DATA_MODE dataMode;
+ int bitlength;
+
+public:
+ SSP1(); // announce the constructor to initialize
+ ~SSP1();
+ void begin();
+ void begin(SSP_PORT port);
+ void end();
+ void setBitLength(int bitLength);
+ void setBitOrder(SSP_BIT_ORDER bitOrder) ;
+ void setClockDivider(SSP_CLK_DIVIDER divider);
+ void setDataMode(SSP_DATA_MODE mode);
+ unsigned long transfer(unsigned long txdata) ;
+};
+
+
+// lowlevel
+void ssp1_begin(SSP_PORT port,SSP_CLK_DIVIDER divider,SSP_DATA_MODE dataMode,int bitLength);
+unsigned long ssp1_transfer(unsigned long txdata);
+
+
+
+extern SSP1 SPI1;
+
+
+#ifdef __cplusplus
+ }
+#endif
+
+
+#endif /* SSP1_H_ */
diff --git a/src/core/core_cm0.h b/src/core/core_cm0.h
new file mode 100755
index 0000000..f148b8f
--- /dev/null
+++ b/src/core/core_cm0.h
@@ -0,0 +1,960 @@
+/**************************************************************************//**
+ * @file core_cm0.h
+ * @brief CMSIS Cortex-M0 Core Peripheral Access Layer Header File
+ * @version V1.30
+ * @date 30. October 2009
+ *
+ * @note
+ * Copyright (C) 2009 ARM Limited. All rights reserved.
+ *
+ * @par
+ * ARM Limited (ARM) is supplying this software for use with Cortex-M
+ * processor based microcontrollers. This file can be freely distributed
+ * within development tools that are supporting such ARM based processors.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
+ * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
+ * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
+ * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
+ *
+ ******************************************************************************/
+
+#ifndef __CM0_CORE_H__
+#define __CM0_CORE_H__
+
+/** @addtogroup CMSIS_CM0_core_LintCinfiguration CMSIS CM0 Core Lint Configuration
+ *
+ * List of Lint messages which will be suppressed and not shown:
+ * - not yet checked
+ * .
+ * Note: To re-enable a Message, insert a space before 'lint' *
+ *
+ */
+
+
+/** @addtogroup CMSIS_CM0_core_definitions CM0 Core Definitions
+ This file defines all structures and symbols for CMSIS core:
+ - CMSIS version number
+ - Cortex-M core registers and bitfields
+ - Cortex-M core peripheral base address
+ @{
+ */
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#define __CM0_CMSIS_VERSION_MAIN (0x01) /*!< [31:16] CMSIS HAL main version */
+#define __CM0_CMSIS_VERSION_SUB (0x30) /*!< [15:0] CMSIS HAL sub version */
+#define __CM0_CMSIS_VERSION ((__CM0_CMSIS_VERSION_MAIN << 16) | __CM0_CMSIS_VERSION_SUB) /*!< CMSIS HAL version number */
+
+#define __CORTEX_M (0x00) /*!< Cortex core */
+
+#include <stdint.h> /* Include standard types */
+
+#if defined (__ICCARM__)
+ #include <intrinsics.h> /* IAR Intrinsics */
+#endif
+
+
+#ifndef __NVIC_PRIO_BITS
+ #define __NVIC_PRIO_BITS 2 /*!< standard definition for NVIC Priority Bits */
+#endif
+
+
+
+
+/**
+ * IO definitions
+ *
+ * define access restrictions to peripheral registers
+ */
+
+#ifdef __cplusplus
+ #define __I volatile /*!< defines 'read only' permissions */
+#else
+ #define __I volatile const /*!< defines 'read only' permissions */
+#endif
+#define __O volatile /*!< defines 'write only' permissions */
+#define __IO volatile /*!< defines 'read / write' permissions */
+
+
+
+/*******************************************************************************
+ * Register Abstraction
+ ******************************************************************************/
+/** @addtogroup CMSIS_CM0_core_register CMSIS CM0 Core Register
+ @{
+*/
+
+
+/** @addtogroup CMSIS_CM0_NVIC CMSIS CM0 NVIC
+ memory mapped structure for Nested Vectored Interrupt Controller (NVIC)
+ @{
+ */
+typedef struct
+{
+ __IO uint32_t ISER[1]; /*!< (Offset: 0x000) Interrupt Set Enable Register */
+ uint32_t RESERVED0[31];
+ __IO uint32_t ICER[1]; /*!< (Offset: 0x080) Interrupt Clear Enable Register */
+ uint32_t RSERVED1[31];
+ __IO uint32_t ISPR[1]; /*!< (Offset: 0x100) Interrupt Set Pending Register */
+ uint32_t RESERVED2[31];
+ __IO uint32_t ICPR[1]; /*!< (Offset: 0x180) Interrupt Clear Pending Register */
+ uint32_t RESERVED3[31];
+ uint32_t RESERVED4[64];
+ __IO uint32_t IPR[8]; /*!< (Offset: 0x3EC) Interrupt Priority Register */
+} NVIC_Type;
+/*@}*/ /* end of group CMSIS_CM0_NVIC */
+
+
+/** @addtogroup CMSIS_CM0_SCB CMSIS CM0 SCB
+ memory mapped structure for System Control Block (SCB)
+ @{
+ */
+typedef struct
+{
+ __I uint32_t CPUID; /*!< Offset: 0x00 CPU ID Base Register */
+ __IO uint32_t ICSR; /*!< Offset: 0x04 Interrupt Control State Register */
+ uint32_t RESERVED0;
+ __IO uint32_t AIRCR; /*!< Offset: 0x0C Application Interrupt / Reset Control Register */
+ __IO uint32_t SCR; /*!< Offset: 0x10 System Control Register */
+ __IO uint32_t CCR; /*!< Offset: 0x14 Configuration Control Register */
+ uint32_t RESERVED1;
+ __IO uint32_t SHP[2]; /*!< Offset: 0x1C System Handlers Priority Registers. [0] is RESERVED */
+ __IO uint32_t SHCSR; /*!< Offset: 0x24 System Handler Control and State Register */
+ uint32_t RESERVED2[2];
+ __IO uint32_t DFSR; /*!< Offset: 0x30 Debug Fault Status Register */
+} SCB_Type;
+
+/* SCB CPUID Register Definitions */
+#define SCB_CPUID_IMPLEMENTER_Pos 24 /*!< SCB CPUID: IMPLEMENTER Position */
+#define SCB_CPUID_IMPLEMENTER_Msk (0xFFul << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */
+
+#define SCB_CPUID_VARIANT_Pos 20 /*!< SCB CPUID: VARIANT Position */
+#define SCB_CPUID_VARIANT_Msk (0xFul << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */
+
+#define SCB_CPUID_ARCHITECTURE_Pos 16 /*!< SCB CPUID: ARCHITECTURE Position */
+#define SCB_CPUID_ARCHITECTURE_Msk (0xFul << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */
+
+#define SCB_CPUID_PARTNO_Pos 4 /*!< SCB CPUID: PARTNO Position */
+#define SCB_CPUID_PARTNO_Msk (0xFFFul << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */
+
+#define SCB_CPUID_REVISION_Pos 0 /*!< SCB CPUID: REVISION Position */
+#define SCB_CPUID_REVISION_Msk (0xFul << SCB_CPUID_REVISION_Pos) /*!< SCB CPUID: REVISION Mask */
+
+/* SCB Interrupt Control State Register Definitions */
+#define SCB_ICSR_NMIPENDSET_Pos 31 /*!< SCB ICSR: NMIPENDSET Position */
+#define SCB_ICSR_NMIPENDSET_Msk (1ul << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */
+
+#define SCB_ICSR_PENDSVSET_Pos 28 /*!< SCB ICSR: PENDSVSET Position */
+#define SCB_ICSR_PENDSVSET_Msk (1ul << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */
+
+#define SCB_ICSR_PENDSVCLR_Pos 27 /*!< SCB ICSR: PENDSVCLR Position */
+#define SCB_ICSR_PENDSVCLR_Msk (1ul << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */
+
+#define SCB_ICSR_PENDSTSET_Pos 26 /*!< SCB ICSR: PENDSTSET Position */
+#define SCB_ICSR_PENDSTSET_Msk (1ul << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */
+
+#define SCB_ICSR_PENDSTCLR_Pos 25 /*!< SCB ICSR: PENDSTCLR Position */
+#define SCB_ICSR_PENDSTCLR_Msk (1ul << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */
+
+#define SCB_ICSR_ISRPREEMPT_Pos 23 /*!< SCB ICSR: ISRPREEMPT Position */
+#define SCB_ICSR_ISRPREEMPT_Msk (1ul << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */
+
+#define SCB_ICSR_ISRPENDING_Pos 22 /*!< SCB ICSR: ISRPENDING Position */
+#define SCB_ICSR_ISRPENDING_Msk (1ul << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */
+
+#define SCB_ICSR_VECTPENDING_Pos 12 /*!< SCB ICSR: VECTPENDING Position */
+#define SCB_ICSR_VECTPENDING_Msk (0x1FFul << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */
+
+#define SCB_ICSR_VECTACTIVE_Pos 0 /*!< SCB ICSR: VECTACTIVE Position */
+#define SCB_ICSR_VECTACTIVE_Msk (0x1FFul << SCB_ICSR_VECTACTIVE_Pos) /*!< SCB ICSR: VECTACTIVE Mask */
+
+/* SCB Application Interrupt and Reset Control Register Definitions */
+#define SCB_AIRCR_VECTKEY_Pos 16 /*!< SCB AIRCR: VECTKEY Position */
+#define SCB_AIRCR_VECTKEY_Msk (0xFFFFul << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */
+
+#define SCB_AIRCR_VECTKEYSTAT_Pos 16 /*!< SCB AIRCR: VECTKEYSTAT Position */
+#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFul << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */
+
+#define SCB_AIRCR_ENDIANESS_Pos 15 /*!< SCB AIRCR: ENDIANESS Position */
+#define SCB_AIRCR_ENDIANESS_Msk (1ul << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */
+
+#define SCB_AIRCR_SYSRESETREQ_Pos 2 /*!< SCB AIRCR: SYSRESETREQ Position */
+#define SCB_AIRCR_SYSRESETREQ_Msk (1ul << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */
+
+#define SCB_AIRCR_VECTCLRACTIVE_Pos 1 /*!< SCB AIRCR: VECTCLRACTIVE Position */
+#define SCB_AIRCR_VECTCLRACTIVE_Msk (1ul << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */
+
+/* SCB System Control Register Definitions */
+#define SCB_SCR_SEVONPEND_Pos 4 /*!< SCB SCR: SEVONPEND Position */
+#define SCB_SCR_SEVONPEND_Msk (1ul << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */
+
+#define SCB_SCR_SLEEPDEEP_Pos 2 /*!< SCB SCR: SLEEPDEEP Position */
+#define SCB_SCR_SLEEPDEEP_Msk (1ul << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */
+
+#define SCB_SCR_SLEEPONEXIT_Pos 1 /*!< SCB SCR: SLEEPONEXIT Position */
+#define SCB_SCR_SLEEPONEXIT_Msk (1ul << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */
+
+/* SCB Configuration Control Register Definitions */
+#define SCB_CCR_STKALIGN_Pos 9 /*!< SCB CCR: STKALIGN Position */
+#define SCB_CCR_STKALIGN_Msk (1ul << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */
+
+#define SCB_CCR_UNALIGN_TRP_Pos 3 /*!< SCB CCR: UNALIGN_TRP Position */
+#define SCB_CCR_UNALIGN_TRP_Msk (1ul << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */
+
+/* SCB System Handler Control and State Register Definitions */
+#define SCB_SHCSR_SVCALLPENDED_Pos 15 /*!< SCB SHCSR: SVCALLPENDED Position */
+#define SCB_SHCSR_SVCALLPENDED_Msk (1ul << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */
+
+/* SCB Debug Fault Status Register Definitions */
+#define SCB_DFSR_EXTERNAL_Pos 4 /*!< SCB DFSR: EXTERNAL Position */
+#define SCB_DFSR_EXTERNAL_Msk (1ul << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */
+
+#define SCB_DFSR_VCATCH_Pos 3 /*!< SCB DFSR: VCATCH Position */
+#define SCB_DFSR_VCATCH_Msk (1ul << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */
+
+#define SCB_DFSR_DWTTRAP_Pos 2 /*!< SCB DFSR: DWTTRAP Position */
+#define SCB_DFSR_DWTTRAP_Msk (1ul << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */
+
+#define SCB_DFSR_BKPT_Pos 1 /*!< SCB DFSR: BKPT Position */
+#define SCB_DFSR_BKPT_Msk (1ul << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */
+
+#define SCB_DFSR_HALTED_Pos 0 /*!< SCB DFSR: HALTED Position */
+#define SCB_DFSR_HALTED_Msk (1ul << SCB_DFSR_HALTED_Pos) /*!< SCB DFSR: HALTED Mask */
+/*@}*/ /* end of group CMSIS_CM0_SCB */
+
+
+/** @addtogroup CMSIS_CM0_SysTick CMSIS CM0 SysTick
+ memory mapped structure for SysTick
+ @{
+ */
+typedef struct
+{
+ __IO uint32_t CTRL; /*!< Offset: 0x00 SysTick Control and Status Register */
+ __IO uint32_t LOAD; /*!< Offset: 0x04 SysTick Reload Value Register */
+ __IO uint32_t VAL; /*!< Offset: 0x08 SysTick Current Value Register */
+ __I uint32_t CALIB; /*!< Offset: 0x0C SysTick Calibration Register */
+} SysTick_Type;
+
+/* SysTick Control / Status Register Definitions */
+#define SysTick_CTRL_COUNTFLAG_Pos 16 /*!< SysTick CTRL: COUNTFLAG Position */
+#define SysTick_CTRL_COUNTFLAG_Msk (1ul << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */
+
+#define SysTick_CTRL_CLKSOURCE_Pos 2 /*!< SysTick CTRL: CLKSOURCE Position */
+#define SysTick_CTRL_CLKSOURCE_Msk (1ul << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */
+
+#define SysTick_CTRL_TICKINT_Pos 1 /*!< SysTick CTRL: TICKINT Position */
+#define SysTick_CTRL_TICKINT_Msk (1ul << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */
+
+#define SysTick_CTRL_ENABLE_Pos 0 /*!< SysTick CTRL: ENABLE Position */
+#define SysTick_CTRL_ENABLE_Msk (1ul << SysTick_CTRL_ENABLE_Pos) /*!< SysTick CTRL: ENABLE Mask */
+
+/* SysTick Reload Register Definitions */
+#define SysTick_LOAD_RELOAD_Pos 0 /*!< SysTick LOAD: RELOAD Position */
+#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFul << SysTick_LOAD_RELOAD_Pos) /*!< SysTick LOAD: RELOAD Mask */
+
+/* SysTick Current Register Definitions */
+#define SysTick_VAL_CURRENT_Pos 0 /*!< SysTick VAL: CURRENT Position */
+#define SysTick_VAL_CURRENT_Msk (0xFFFFFFul << SysTick_VAL_CURRENT_Pos) /*!< SysTick VAL: CURRENT Mask */
+
+/* SysTick Calibration Register Definitions */
+#define SysTick_CALIB_NOREF_Pos 31 /*!< SysTick CALIB: NOREF Position */
+#define SysTick_CALIB_NOREF_Msk (1ul << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */
+
+#define SysTick_CALIB_SKEW_Pos 30 /*!< SysTick CALIB: SKEW Position */
+#define SysTick_CALIB_SKEW_Msk (1ul << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */
+
+#define SysTick_CALIB_TENMS_Pos 0 /*!< SysTick CALIB: TENMS Position */
+#define SysTick_CALIB_TENMS_Msk (0xFFFFFFul << SysTick_VAL_CURRENT_Pos) /*!< SysTick CALIB: TENMS Mask */
+/*@}*/ /* end of group CMSIS_CM0_SysTick */
+
+
+/** @addtogroup CMSIS_CM0_CoreDebug CMSIS CM0 Core Debug
+ memory mapped structure for Core Debug Register
+ @{
+ */
+typedef struct
+{
+ __IO uint32_t DHCSR; /*!< Offset: 0x00 Debug Halting Control and Status Register */
+ __O uint32_t DCRSR; /*!< Offset: 0x04 Debug Core Register Selector Register */
+ __IO uint32_t DCRDR; /*!< Offset: 0x08 Debug Core Register Data Register */
+ __IO uint32_t DEMCR; /*!< Offset: 0x0C Debug Exception and Monitor Control Register */
+} CoreDebug_Type;
+
+/* Debug Halting Control and Status Register */
+#define CoreDebug_DHCSR_DBGKEY_Pos 16 /*!< CoreDebug DHCSR: DBGKEY Position */
+#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFul << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */
+
+#define CoreDebug_DHCSR_S_RESET_ST_Pos 25 /*!< CoreDebug DHCSR: S_RESET_ST Position */
+#define CoreDebug_DHCSR_S_RESET_ST_Msk (1ul << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */
+
+#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24 /*!< CoreDebug DHCSR: S_RETIRE_ST Position */
+#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1ul << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */
+
+#define CoreDebug_DHCSR_S_LOCKUP_Pos 19 /*!< CoreDebug DHCSR: S_LOCKUP Position */
+#define CoreDebug_DHCSR_S_LOCKUP_Msk (1ul << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */
+
+#define CoreDebug_DHCSR_S_SLEEP_Pos 18 /*!< CoreDebug DHCSR: S_SLEEP Position */
+#define CoreDebug_DHCSR_S_SLEEP_Msk (1ul << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */
+
+#define CoreDebug_DHCSR_S_HALT_Pos 17 /*!< CoreDebug DHCSR: S_HALT Position */
+#define CoreDebug_DHCSR_S_HALT_Msk (1ul << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */
+
+#define CoreDebug_DHCSR_S_REGRDY_Pos 16 /*!< CoreDebug DHCSR: S_REGRDY Position */
+#define CoreDebug_DHCSR_S_REGRDY_Msk (1ul << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */
+
+#define CoreDebug_DHCSR_C_MASKINTS_Pos 3 /*!< CoreDebug DHCSR: C_MASKINTS Position */
+#define CoreDebug_DHCSR_C_MASKINTS_Msk (1ul << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */
+
+#define CoreDebug_DHCSR_C_STEP_Pos 2 /*!< CoreDebug DHCSR: C_STEP Position */
+#define CoreDebug_DHCSR_C_STEP_Msk (1ul << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */
+
+#define CoreDebug_DHCSR_C_HALT_Pos 1 /*!< CoreDebug DHCSR: C_HALT Position */
+#define CoreDebug_DHCSR_C_HALT_Msk (1ul << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */
+
+#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0 /*!< CoreDebug DHCSR: C_DEBUGEN Position */
+#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1ul << CoreDebug_DHCSR_C_DEBUGEN_Pos) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */
+
+/* Debug Core Register Selector Register */
+#define CoreDebug_DCRSR_REGWnR_Pos 16 /*!< CoreDebug DCRSR: REGWnR Position */
+#define CoreDebug_DCRSR_REGWnR_Msk (1ul << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */
+
+#define CoreDebug_DCRSR_REGSEL_Pos 0 /*!< CoreDebug DCRSR: REGSEL Position */
+#define CoreDebug_DCRSR_REGSEL_Msk (0x1Ful << CoreDebug_DCRSR_REGSEL_Pos) /*!< CoreDebug DCRSR: REGSEL Mask */
+
+/* Debug Exception and Monitor Control Register */
+#define CoreDebug_DEMCR_DWTENA_Pos 24 /*!< CoreDebug DEMCR: DWTENA Position */
+#define CoreDebug_DEMCR_DWTENA_Msk (1ul << CoreDebug_DEMCR_DWTENA_Pos) /*!< CoreDebug DEMCR: DWTENA Mask */
+
+#define CoreDebug_DEMCR_VC_HARDERR_Pos 10 /*!< CoreDebug DEMCR: VC_HARDERR Position */
+#define CoreDebug_DEMCR_VC_HARDERR_Msk (1ul << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */
+
+#define CoreDebug_DEMCR_VC_CORERESET_Pos 0 /*!< CoreDebug DEMCR: VC_CORERESET Position */
+#define CoreDebug_DEMCR_VC_CORERESET_Msk (1ul << CoreDebug_DEMCR_VC_CORERESET_Pos) /*!< CoreDebug DEMCR: VC_CORERESET Mask */
+/*@}*/ /* end of group CMSIS_CM0_CoreDebug */
+
+
+/* Memory mapping of Cortex-M0 Hardware */
+#define SCS_BASE (0xE000E000) /*!< System Control Space Base Address */
+#define CoreDebug_BASE (0xE000EDF0) /*!< Core Debug Base Address */
+#define SysTick_BASE (SCS_BASE + 0x0010) /*!< SysTick Base Address */
+#define NVIC_BASE (SCS_BASE + 0x0100) /*!< NVIC Base Address */
+#define SCB_BASE (SCS_BASE + 0x0D00) /*!< System Control Block Base Address */
+
+#define SCB ((SCB_Type *) SCB_BASE) /*!< SCB configuration struct */
+#define SysTick ((SysTick_Type *) SysTick_BASE) /*!< SysTick configuration struct */
+#define NVIC ((NVIC_Type *) NVIC_BASE) /*!< NVIC configuration struct */
+#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */
+
+/*@}*/ /* end of group CMSIS_CM0_core_register */
+
+
+/*******************************************************************************
+ * Hardware Abstraction Layer
+ ******************************************************************************/
+
+#if defined ( __CC_ARM )
+ #define __ASM __asm /*!< asm keyword for ARM Compiler */
+ #define __INLINE __inline /*!< inline keyword for ARM Compiler */
+
+#elif defined ( __ICCARM__ )
+ #define __ASM __asm /*!< asm keyword for IAR Compiler */
+ #define __INLINE inline /*!< inline keyword for IAR Compiler. Only avaiable in High optimization mode! */
+
+#elif defined ( __GNUC__ )
+ #define __ASM __asm /*!< asm keyword for GNU Compiler */
+ #define __INLINE inline /*!< inline keyword for GNU Compiler */
+
+#elif defined ( __TASKING__ )
+ #define __ASM __asm /*!< asm keyword for TASKING Compiler */
+ #define __INLINE inline /*!< inline keyword for TASKING Compiler */
+
+#endif
+
+
+/* ################### Compiler specific Intrinsics ########################### */
+
+#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
+/* ARM armcc specific functions */
+
+#define __enable_fault_irq __enable_fiq
+#define __disable_fault_irq __disable_fiq
+
+#define __NOP __nop
+#define __WFI __wfi
+#define __WFE __wfe
+#define __SEV __sev
+#define __ISB() __isb(0)
+#define __DSB() __dsb(0)
+#define __DMB() __dmb(0)
+#define __REV __rev
+
+
+/* intrinsic void __enable_irq(); */
+/* intrinsic void __disable_irq(); */
+
+
+/**
+ * @brief Return the Process Stack Pointer
+ *
+ * @return ProcessStackPointer
+ *
+ * Return the actual process stack pointer
+ */
+extern uint32_t __get_PSP(void);
+
+/**
+ * @brief Set the Process Stack Pointer
+ *
+ * @param topOfProcStack Process Stack Pointer
+ *
+ * Assign the value ProcessStackPointer to the MSP
+ * (process stack pointer) Cortex processor register
+ */
+extern void __set_PSP(uint32_t topOfProcStack);
+
+/**
+ * @brief Return the Main Stack Pointer
+ *
+ * @return Main Stack Pointer
+ *
+ * Return the current value of the MSP (main stack pointer)
+ * Cortex processor register
+ */
+extern uint32_t __get_MSP(void);
+
+/**
+ * @brief Set the Main Stack Pointer
+ *
+ * @param topOfMainStack Main Stack Pointer
+ *
+ * Assign the value mainStackPointer to the MSP
+ * (main stack pointer) Cortex processor register
+ */
+extern void __set_MSP(uint32_t topOfMainStack);
+
+/**
+ * @brief Reverse byte order in unsigned short value
+ *
+ * @param value value to reverse
+ * @return reversed value
+ *
+ * Reverse byte order in unsigned short value
+ */
+extern uint32_t __REV16(uint16_t value);
+
+/**
+ * @brief Reverse byte order in signed short value with sign extension to integer
+ *
+ * @param value value to reverse
+ * @return reversed value
+ *
+ * Reverse byte order in signed short value with sign extension to integer
+ */
+extern int32_t __REVSH(int16_t value);
+
+
+#if (__ARMCC_VERSION < 400000)
+
+/**
+ * @brief Return the Priority Mask value
+ *
+ * @return PriMask
+ *
+ * Return state of the priority mask bit from the priority mask register
+ */
+extern uint32_t __get_PRIMASK(void);
+
+/**
+ * @brief Set the Priority Mask value
+ *
+ * @param priMask PriMask
+ *
+ * Set the priority mask bit in the priority mask register
+ */
+extern void __set_PRIMASK(uint32_t priMask);
+
+/**
+ * @brief Return the Control Register value
+ *
+ * @return Control value
+ *
+ * Return the content of the control register
+ */
+extern uint32_t __get_CONTROL(void);
+
+/**
+ * @brief Set the Control Register value
+ *
+ * @param control Control value
+ *
+ * Set the control register
+ */
+extern void __set_CONTROL(uint32_t control);
+
+#else /* (__ARMCC_VERSION >= 400000) */
+
+
+/**
+ * @brief Return the Priority Mask value
+ *
+ * @return PriMask
+ *
+ * Return state of the priority mask bit from the priority mask register
+ */
+static __INLINE uint32_t __get_PRIMASK(void)
+{
+ register uint32_t __regPriMask __ASM("primask");
+ return(__regPriMask);
+}
+
+/**
+ * @brief Set the Priority Mask value
+ *
+ * @param priMask PriMask
+ *
+ * Set the priority mask bit in the priority mask register
+ */
+static __INLINE void __set_PRIMASK(uint32_t priMask)
+{
+ register uint32_t __regPriMask __ASM("primask");
+ __regPriMask = (priMask);
+}
+
+/**
+ * @brief Return the Control Register value
+ *
+ * @return Control value
+ *
+ * Return the content of the control register
+ */
+static __INLINE uint32_t __get_CONTROL(void)
+{
+ register uint32_t __regControl __ASM("control");
+ return(__regControl);
+}
+
+/**
+ * @brief Set the Control Register value
+ *
+ * @param control Control value
+ *
+ * Set the control register
+ */
+static __INLINE void __set_CONTROL(uint32_t control)
+{
+ register uint32_t __regControl __ASM("control");
+ __regControl = control;
+}
+
+#endif /* __ARMCC_VERSION */
+
+
+
+#elif (defined (__ICCARM__)) /*------------------ ICC Compiler -------------------*/
+/* IAR iccarm specific functions */
+
+#define __enable_irq __enable_interrupt /*!< global Interrupt enable */
+#define __disable_irq __disable_interrupt /*!< global Interrupt disable */
+
+static __INLINE void __enable_fault_irq() { __ASM ("cpsie f"); }
+static __INLINE void __disable_fault_irq() { __ASM ("cpsid f"); }
+
+#define __NOP __no_operation /*!< no operation intrinsic in IAR Compiler */
+static __INLINE void __WFI() { __ASM ("wfi"); }
+static __INLINE void __WFE() { __ASM ("wfe"); }
+static __INLINE void __SEV() { __ASM ("sev"); }
+
+/* intrinsic void __ISB(void) */
+/* intrinsic void __DSB(void) */
+/* intrinsic void __DMB(void) */
+/* intrinsic void __set_PRIMASK(); */
+/* intrinsic void __get_PRIMASK(); */
+
+
+/* intrinsic uint32_t __REV(uint32_t value); */
+/* intrinsic uint32_t __REVSH(uint32_t value); */
+
+
+/**
+ * @brief Return the Process Stack Pointer
+ *
+ * @return ProcessStackPointer
+ *
+ * Return the actual process stack pointer
+ */
+extern uint32_t __get_PSP(void);
+
+/**
+ * @brief Set the Process Stack Pointer
+ *
+ * @param topOfProcStack Process Stack Pointer
+ *
+ * Assign the value ProcessStackPointer to the MSP
+ * (process stack pointer) Cortex processor register
+ */
+extern void __set_PSP(uint32_t topOfProcStack);
+
+/**
+ * @brief Return the Main Stack Pointer
+ *
+ * @return Main Stack Pointer
+ *
+ * Return the current value of the MSP (main stack pointer)
+ * Cortex processor register
+ */
+extern uint32_t __get_MSP(void);
+
+/**
+ * @brief Set the Main Stack Pointer
+ *
+ * @param topOfMainStack Main Stack Pointer
+ *
+ * Assign the value mainStackPointer to the MSP
+ * (main stack pointer) Cortex processor register
+ */
+extern void __set_MSP(uint32_t topOfMainStack);
+
+/**
+ * @brief Reverse byte order in unsigned short value
+ *
+ * @param value value to reverse
+ * @return reversed value
+ *
+ * Reverse byte order in unsigned short value
+ */
+extern uint32_t __REV16(uint16_t value);
+
+
+
+
+
+#elif (defined (__GNUC__)) /*------------------ GNU Compiler ---------------------*/
+/* GNU gcc specific functions */
+
+static __INLINE void __enable_irq() { __ASM volatile ("cpsie i"); }
+static __INLINE void __disable_irq() { __ASM volatile ("cpsid i"); }
+
+static __INLINE void __enable_fault_irq() { __ASM volatile ("cpsie f"); }
+static __INLINE void __disable_fault_irq() { __ASM volatile ("cpsid f"); }
+
+static __INLINE void __NOP() { __ASM volatile ("nop"); }
+static __INLINE void __WFI() { __ASM volatile ("wfi"); }
+static __INLINE void __WFE() { __ASM volatile ("wfe"); }
+static __INLINE void __SEV() { __ASM volatile ("sev"); }
+static __INLINE void __ISB() { __ASM volatile ("isb"); }
+static __INLINE void __DSB() { __ASM volatile ("dsb"); }
+static __INLINE void __DMB() { __ASM volatile ("dmb"); }
+
+
+/**
+ * @brief Return the Process Stack Pointer
+ *
+ * @return ProcessStackPointer
+ *
+ * Return the actual process stack pointer
+ */
+extern uint32_t __get_PSP(void);
+
+/**
+ * @brief Set the Process Stack Pointer
+ *
+ * @param topOfProcStack Process Stack Pointer
+ *
+ * Assign the value ProcessStackPointer to the MSP
+ * (process stack pointer) Cortex processor register
+ */
+extern void __set_PSP(uint32_t topOfProcStack);
+
+/**
+ * @brief Return the Main Stack Pointer
+ *
+ * @return Main Stack Pointer
+ *
+ * Return the current value of the MSP (main stack pointer)
+ * Cortex processor register
+ */
+extern uint32_t __get_MSP(void);
+
+/**
+ * @brief Set the Main Stack Pointer
+ *
+ * @param topOfMainStack Main Stack Pointer
+ *
+ * Assign the value mainStackPointer to the MSP
+ * (main stack pointer) Cortex processor register
+ */
+extern void __set_MSP(uint32_t topOfMainStack);
+
+/**
+ * @brief Return the Priority Mask value
+ *
+ * @return PriMask
+ *
+ * Return state of the priority mask bit from the priority mask register
+ */
+extern uint32_t __get_PRIMASK(void);
+
+/**
+ * @brief Set the Priority Mask value
+ *
+ * @param priMask PriMask
+ *
+ * Set the priority mask bit in the priority mask register
+ */
+extern void __set_PRIMASK(uint32_t priMask);
+
+/**
+ * @brief Return the Control Register value
+*
+* @return Control value
+ *
+ * Return the content of the control register
+ */
+extern uint32_t __get_CONTROL(void);
+
+/**
+ * @brief Set the Control Register value
+ *
+ * @param control Control value
+ *
+ * Set the control register
+ */
+extern void __set_CONTROL(uint32_t control);
+
+/**
+ * @brief Reverse byte order in integer value
+ *
+ * @param value value to reverse
+ * @return reversed value
+ *
+ * Reverse byte order in integer value
+ */
+extern uint32_t __REV(uint32_t value);
+
+/**
+ * @brief Reverse byte order in unsigned short value
+ *
+ * @param value value to reverse
+ * @return reversed value
+ *
+ * Reverse byte order in unsigned short value
+ */
+extern uint32_t __REV16(uint16_t value);
+
+/**
+ * @brief Reverse byte order in signed short value with sign extension to integer
+ *
+ * @param value value to reverse
+ * @return reversed value
+ *
+ * Reverse byte order in signed short value with sign extension to integer
+ */
+extern int32_t __REVSH(int16_t value);
+
+
+#elif (defined (__TASKING__)) /*------------------ TASKING Compiler ---------------------*/
+/* TASKING carm specific functions */
+
+/*
+ * The CMSIS functions have been implemented as intrinsics in the compiler.
+ * Please use "carm -?i" to get an up to date list of all instrinsics,
+ * Including the CMSIS ones.
+ */
+
+#endif
+
+
+/** @addtogroup CMSIS_CM0_Core_FunctionInterface CMSIS CM0 Core Function Interface
+ Core Function Interface containing:
+ - Core NVIC Functions
+ - Core SysTick Functions
+ - Core Reset Functions
+*/
+/*@{*/
+
+/* ########################## NVIC functions #################################### */
+
+/* Interrupt Priorities are WORD accessible only under ARMv6M */
+/* The following MACROS handle generation of the register offset and byte masks */
+#define _BIT_SHIFT(IRQn) ( (((uint32_t)(IRQn) ) & 0x03) * 8 )
+#define _SHP_IDX(IRQn) ( ((((uint32_t)(IRQn) & 0x0F)-8) >> 2) )
+#define _IP_IDX(IRQn) ( ((uint32_t)(IRQn) >> 2) )
+
+
+/**
+ * @brief Enable Interrupt in NVIC Interrupt Controller
+ *
+ * @param IRQn The positive number of the external interrupt to enable
+ *
+ * Enable a device specific interupt in the NVIC interrupt controller.
+ * The interrupt number cannot be a negative value.
+ */
+static __INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
+{
+ NVIC->ISER[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* enable interrupt */
+}
+
+/**
+ * @brief Disable the interrupt line for external interrupt specified
+ *
+ * @param IRQn The positive number of the external interrupt to disable
+ *
+ * Disable a device specific interupt in the NVIC interrupt controller.
+ * The interrupt number cannot be a negative value.
+ */
+static __INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
+{
+ NVIC->ICER[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* disable interrupt */
+}
+
+/**
+ * @brief Read the interrupt pending bit for a device specific interrupt source
+ *
+ * @param IRQn The number of the device specifc interrupt
+ * @return 1 = interrupt pending, 0 = interrupt not pending
+ *
+ * Read the pending register in NVIC and return 1 if its status is pending,
+ * otherwise it returns 0
+ */
+static __INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
+{
+ return((uint32_t) ((NVIC->ISPR[0] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if pending else 0 */
+}
+
+/**
+ * @brief Set the pending bit for an external interrupt
+ *
+ * @param IRQn The number of the interrupt for set pending
+ *
+ * Set the pending bit for the specified interrupt.
+ * The interrupt number cannot be a negative value.
+ */
+static __INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
+{
+ NVIC->ISPR[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* set interrupt pending */
+}
+
+/**
+ * @brief Clear the pending bit for an external interrupt
+ *
+ * @param IRQn The number of the interrupt for clear pending
+ *
+ * Clear the pending bit for the specified interrupt.
+ * The interrupt number cannot be a negative value.
+ */
+static __INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
+{
+ NVIC->ICPR[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */
+}
+
+/**
+ * @brief Set the priority for an interrupt
+ *
+ * @param IRQn The number of the interrupt for set priority
+ * @param priority The priority to set
+ *
+ * Set the priority for the specified interrupt. The interrupt
+ * number can be positive to specify an external (device specific)
+ * interrupt, or negative to specify an internal (core) interrupt.
+ *
+ * Note: The priority cannot be set for every core interrupt.
+ */
+static __INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
+{
+ if(IRQn < 0) {
+ SCB->SHP[_SHP_IDX(IRQn)] = (SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFF << _BIT_SHIFT(IRQn))) |
+ (((priority << (8 - __NVIC_PRIO_BITS)) & 0xFF) << _BIT_SHIFT(IRQn)); }
+ else {
+ NVIC->IPR[_IP_IDX(IRQn)] = (NVIC->IPR[_IP_IDX(IRQn)] & ~(0xFF << _BIT_SHIFT(IRQn))) |
+ (((priority << (8 - __NVIC_PRIO_BITS)) & 0xFF) << _BIT_SHIFT(IRQn)); }
+}
+
+/**
+ * @brief Read the priority for an interrupt
+ *
+ * @param IRQn The number of the interrupt for get priority
+ * @return The priority for the interrupt
+ *
+ * Read the priority for the specified interrupt. The interrupt
+ * number can be positive to specify an external (device specific)
+ * interrupt, or negative to specify an internal (core) interrupt.
+ *
+ * The returned priority value is automatically aligned to the implemented
+ * priority bits of the microcontroller.
+ *
+ * Note: The priority cannot be set for every core interrupt.
+ */
+static __INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
+{
+
+ if(IRQn < 0) {
+ return((uint32_t)((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) >> (8 - __NVIC_PRIO_BITS))); } /* get priority for Cortex-M0 system interrupts */
+ else {
+ return((uint32_t)((NVIC->IPR[_IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) >> (8 - __NVIC_PRIO_BITS))); } /* get priority for device specific interrupts */
+}
+
+
+
+/* ################################## SysTick function ############################################ */
+
+#if (!defined (__Vendor_SysTickConfig)) || (__Vendor_SysTickConfig == 0)
+
+/**
+ * @brief Initialize and start the SysTick counter and its interrupt.
+ *
+ * @param ticks number of ticks between two interrupts
+ * @return 1 = failed, 0 = successful
+ *
+ * Initialise the system tick timer and its interrupt and start the
+ * system tick timer / counter in free running mode to generate
+ * periodical interrupts.
+ */
+static __INLINE uint32_t SysTick_Config(uint32_t ticks)
+{
+ if (ticks > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */
+
+ SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1; /* set reload register */
+ NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Cortex-M0 System Interrupts */
+ SysTick->VAL = 0; /* Load the SysTick Counter Value */
+ SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
+ SysTick_CTRL_TICKINT_Msk |
+ SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
+ return (0); /* Function successful */
+}
+
+#endif
+
+
+
+
+/* ################################## Reset function ############################################ */
+
+/**
+ * @brief Initiate a system reset request.
+ *
+ * Initiate a system reset request to reset the MCU
+ */
+static __INLINE void NVIC_SystemReset(void)
+{
+ SCB->AIRCR = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) |
+ SCB_AIRCR_SYSRESETREQ_Msk);
+ __DSB(); /* Ensure completion of memory access */
+ while(1); /* wait until reset */
+}
+
+/*@}*/ /* end of group CMSIS_CM0_Core_FunctionInterface */
+
+#ifdef __cplusplus
+}
+#endif
+
+/*@}*/ /* end of group CMSIS_CM0_core_definitions */
+
+#endif /* __CM0_CORE_H__ */
+
+/*lint -restore */
diff --git a/src/core/cr_cpp_config.cpp b/src/core/cr_cpp_config.cpp
new file mode 100755
index 0000000..8577b2d
--- /dev/null
+++ b/src/core/cr_cpp_config.cpp
@@ -0,0 +1,56 @@
+//*****************************************************************************
+// +--+
+// | ++----+
+// +-++ |
+// | |
+// +-+--+ |
+// | +--+--+
+// +----+ Copyright (c) 2009-10 Code Red Technologies Ltd.
+//
+// Microcontroller Startup code for use with Red Suite
+//
+// Version : 101026
+//
+// Software License Agreement
+//
+// The software is owned by Code Red Technologies and/or its suppliers, and is
+// protected under applicable copyright laws. All rights are reserved. Any
+// use in violation of the foregoing restrictions may subject the user to criminal
+// sanctions under applicable laws, as well as to civil liability for the breach
+// of the terms and conditions of this license.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
+// OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
+// USE OF THIS SOFTWARE FOR COMMERCIAL DEVELOPMENT AND/OR EDUCATION IS SUBJECT
+// TO A CURRENT END USER LICENSE AGREEMENT (COMMERCIAL OR EDUCATIONAL) WITH
+// CODE RED TECHNOLOGIES LTD.
+//
+//*****************************************************************************
+
+#define $(CPPHeapFlag)
+
+#include <stdlib.h>
+
+void *operator new(size_t size) throw() {
+ return malloc(size);
+}
+void operator delete(void *p) throw() {
+ free(p);
+}
+
+extern "C" int __aeabi_atexit(void *object,
+ void (*destructor)(void *),
+ void *dso_handle)
+{
+ return 0;
+}
+
+#ifdef CPP_NO_HEAP
+extern "C" void *malloc(size_t) {
+ return (void *)0;
+}
+
+extern "C" void free(void *) {
+}
+#endif
diff --git a/src/core/cr_startup_lpc11.cpp b/src/core/cr_startup_lpc11.cpp
new file mode 100755
index 0000000..e58e676
--- /dev/null
+++ b/src/core/cr_startup_lpc11.cpp
@@ -0,0 +1,383 @@
+//*****************************************************************************
+// +--+
+// | ++----+
+// +-++ |
+// | |
+// +-+--+ |
+// | +--+--+
+// +----+ Copyright (c) 2009-10 Code Red Technologies Ltd.
+//
+// Microcontroller Startup code for use with Red Suite
+//
+// Version : 101130
+//
+// Software License Agreement
+//
+// The software is owned by Code Red Technologies and/or its suppliers, and is
+// protected under applicable copyright laws. All rights are reserved. Any
+// use in violation of the foregoing restrictions may subject the user to criminal
+// sanctions under applicable laws, as well as to civil liability for the breach
+// of the terms and conditions of this license.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
+// OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
+// USE OF THIS SOFTWARE FOR COMMERCIAL DEVELOPMENT AND/OR EDUCATION IS SUBJECT
+// TO A CURRENT END USER LICENSE AGREEMENT (COMMERCIAL OR EDUCATIONAL) WITH
+// CODE RED TECHNOLOGIES LTD.
+//
+//*****************************************************************************
+#if defined (__cplusplus)
+#ifdef __REDLIB__
+#error Redlib does not support C++
+#else
+//*****************************************************************************
+//
+// The entry point for the C++ library startup
+//
+//*****************************************************************************
+
+extern "C" void __cxa_pure_virtual() {
+ while (1);
+}
+
+
+extern "C" {
+ extern void __libc_init_array(void);
+}
+#endif
+#endif
+
+#define WEAK __attribute__ ((weak))
+#define ALIAS(f) __attribute__ ((weak, alias (#f)))
+
+// Code Red - if CMSIS is being used, then SystemInit() routine
+// will be called by startup code rather than in application's main()
+//#if defined (__USE_CMSIS)
+#include "system_LPC11xx.h"
+//#endif
+
+//*****************************************************************************
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+//*****************************************************************************
+//
+// Forward declaration of the default handlers. These are aliased.
+// When the application defines a handler (with the same name), this will
+// automatically take precedence over these weak definitions
+//
+//*****************************************************************************
+ void ResetISR(void);
+WEAK void NMI_Handler(void);
+WEAK void HardFault_Handler(void);
+WEAK void SVCall_Handler(void);
+WEAK void PendSV_Handler(void);
+WEAK void SysTick_Handler(void);
+WEAK void IntDefaultHandler(void);
+//*****************************************************************************
+//
+// Forward declaration of the specific IRQ handlers. These are aliased
+// to the IntDefaultHandler, which is a 'forever' loop. When the application
+// defines a handler (with the same name), this will automatically take
+// precedence over these weak definitions
+//
+//*****************************************************************************
+
+void CAN_IRQHandler (void) ALIAS(IntDefaultHandler);
+void SSP1_IRQHandler (void) ALIAS(IntDefaultHandler);
+void I2C_IRQHandler (void) ALIAS(IntDefaultHandler);
+void TIMER16_0_IRQHandler (void) ALIAS(IntDefaultHandler);
+void TIMER16_1_IRQHandler (void) ALIAS(IntDefaultHandler);
+void TIMER32_0_IRQHandler (void) ALIAS(IntDefaultHandler);
+void TIMER32_1_IRQHandler (void) ALIAS(IntDefaultHandler);
+void SSP0_IRQHandler (void) ALIAS(IntDefaultHandler);
+void UART_IRQHandler (void) ALIAS(IntDefaultHandler);
+void ADC_IRQHandler (void) ALIAS(IntDefaultHandler);
+void WDT_IRQHandler (void) ALIAS(IntDefaultHandler);
+void BOD_IRQHandler (void) ALIAS(IntDefaultHandler);
+void PIOINT3_IRQHandler (void) ALIAS(IntDefaultHandler);
+void PIOINT2_IRQHandler (void) ALIAS(IntDefaultHandler);
+void PIOINT1_IRQHandler (void) ALIAS(IntDefaultHandler);
+void PIOINT0_IRQHandler (void) ALIAS(IntDefaultHandler);
+void WAKEUP_IRQHandler (void) ALIAS(IntDefaultHandler);
+
+//*****************************************************************************
+//
+// The entry point for the application.
+// __main() is the entry point for redlib based applications
+// main() is the entry point for newlib based applications
+//
+//*****************************************************************************
+//
+// The entry point for the application.
+// __main() is the entry point for Redlib based applications
+// main() is the entry point for Newlib based applications
+//
+//*****************************************************************************
+#if defined (__REDLIB__)
+extern void __main(void);
+#endif
+extern int main(void);
+//*****************************************************************************
+//
+// External declaration for the pointer to the stack top from the Linker Script
+//
+//*****************************************************************************
+extern void _vStackTop(void);
+
+//*****************************************************************************
+#if defined (__cplusplus)
+} // extern "C"
+#endif
+//*****************************************************************************
+//
+// The vector table. Note that the proper constructs must be placed on this to
+// ensure that it ends up at physical address 0x0000.0000.
+//
+//*****************************************************************************
+extern void (* const g_pfnVectors[])(void);
+__attribute__ ((section(".isr_vector")))
+void (* const g_pfnVectors[])(void) = {
+ &_vStackTop, // The initial stack pointer
+ ResetISR, // The reset handler
+ NMI_Handler, // The NMI handler
+ HardFault_Handler, // The hard fault handler
+ 0, // Reserved
+ 0, // Reserved
+ 0, // Reserved
+ 0, // Reserved
+ 0, // Reserved
+ 0, // Reserved
+ 0, // Reserved
+ SVCall_Handler, // SVCall handler
+ 0, // Reserved
+ 0, // Reserved
+ PendSV_Handler, // The PendSV handler
+ SysTick_Handler, // The SysTick handler
+
+ // Wakeup sources for the I/O pins:
+ // PIO0 (0:11)
+ // PIO1 (0)
+ WAKEUP_IRQHandler, // PIO0_0 Wakeup
+ WAKEUP_IRQHandler, // PIO0_1 Wakeup
+ WAKEUP_IRQHandler, // PIO0_2 Wakeup
+ WAKEUP_IRQHandler, // PIO0_3 Wakeup
+ WAKEUP_IRQHandler, // PIO0_4 Wakeup
+ WAKEUP_IRQHandler, // PIO0_5 Wakeup
+ WAKEUP_IRQHandler, // PIO0_6 Wakeup
+ WAKEUP_IRQHandler, // PIO0_7 Wakeup
+ WAKEUP_IRQHandler, // PIO0_8 Wakeup
+ WAKEUP_IRQHandler, // PIO0_9 Wakeup
+ WAKEUP_IRQHandler, // PIO0_10 Wakeup
+ WAKEUP_IRQHandler, // PIO0_11 Wakeup
+ WAKEUP_IRQHandler, // PIO1_0 Wakeup
+
+ CAN_IRQHandler, // C_CAN Interrupt
+ SSP1_IRQHandler, // SPI/SSP1 Interrupt
+ I2C_IRQHandler, // I2C0
+ TIMER16_0_IRQHandler, // CT16B0 (16-bit Timer 0)
+ TIMER16_1_IRQHandler, // CT16B1 (16-bit Timer 1)
+ TIMER32_0_IRQHandler, // CT32B0 (32-bit Timer 0)
+ TIMER32_1_IRQHandler, // CT32B1 (32-bit Timer 1)
+ SSP0_IRQHandler, // SPI/SSP0 Interrupt
+ UART_IRQHandler, // UART0
+
+ 0, // Reserved
+ 0, // Reserved
+
+ ADC_IRQHandler, // ADC (A/D Converter)
+ WDT_IRQHandler, // WDT (Watchdog Timer)
+ BOD_IRQHandler, // BOD (Brownout Detect)
+ 0, // Reserved
+ PIOINT3_IRQHandler, // PIO INT3
+ PIOINT2_IRQHandler, // PIO INT2
+ PIOINT1_IRQHandler, // PIO INT1
+ PIOINT0_IRQHandler, // PIO INT0
+};
+
+//*****************************************************************************
+// Functions to carry out the initialization of RW and BSS data sections. These
+// are written as separate functions rather than being inlined within the
+// ResetISR() function in order to cope with MCUs with multiple banks of
+// memory.
+//*****************************************************************************
+__attribute__ ((section(".after_vectors")))
+void data_init(unsigned int romstart, unsigned int start, unsigned int len) {
+ unsigned int *pulDest = (unsigned int*) start;
+ unsigned int *pulSrc = (unsigned int*) romstart;
+ unsigned int loop;
+ for (loop = 0; loop < len; loop = loop + 4)
+ *pulDest++ = *pulSrc++;
+}
+
+__attribute__ ((section(".after_vectors")))
+void bss_init(unsigned int start, unsigned int len) {
+ unsigned int *pulDest = (unsigned int*) start;
+ unsigned int loop;
+ for (loop = 0; loop < len; loop = loop + 4)
+ *pulDest++ = 0;
+}
+
+#ifndef USE_OLD_STYLE_DATA_BSS_INIT
+//*****************************************************************************
+// The following symbols are constructs generated by the linker, indicating
+// the location of various points in the "Global Section Table". This table is
+// created by the linker via the Code Red managed linker script mechanism. It
+// contains the load address, execution address and length of each RW data
+// section and the execution and length of each BSS (zero initialized) section.
+//*****************************************************************************
+extern unsigned int __data_section_table;
+extern unsigned int __data_section_table_end;
+extern unsigned int __bss_section_table;
+extern unsigned int __bss_section_table_end;
+#else
+//*****************************************************************************
+// The following symbols are constructs generated by the linker, indicating
+// the load address, execution address and length of the RW data section and
+// the execution and length of the BSS (zero initialized) section.
+// Note that these symbols are not normally used by the managed linker script
+// mechanism in Red Suite/LPCXpresso 3.6 (Windows) and LPCXpresso 3.8 (Linux).
+// They are provide here simply so this startup code can be used with earlier
+// versions of Red Suite which do not support the more advanced managed linker
+// script mechanism introduced in the above version. To enable their use,
+// define "USE_OLD_STYLE_DATA_BSS_INIT".
+//*****************************************************************************
+extern unsigned int _etext;
+extern unsigned int _data;
+extern unsigned int _edata;
+extern unsigned int _bss;
+extern unsigned int _ebss;
+#endif
+
+
+//*****************************************************************************
+// Reset entry point for your code.
+// Sets up a simple runtime environment and initializes the C/C++
+// library.
+//*****************************************************************************
+__attribute__ ((section(".after_vectors")))
+void
+ResetISR(void) {
+
+#ifndef USE_OLD_STYLE_DATA_BSS_INIT
+ //
+ // Copy the data sections from flash to SRAM.
+ //
+ unsigned int LoadAddr, ExeAddr, SectionLen;
+ unsigned int *SectionTableAddr;
+
+ // Load base address of Global Section Table
+ SectionTableAddr = &__data_section_table;
+
+ // Copy the data sections from flash to SRAM.
+ while (SectionTableAddr < &__data_section_table_end) {
+ LoadAddr = *SectionTableAddr++;
+ ExeAddr = *SectionTableAddr++;
+ SectionLen = *SectionTableAddr++;
+ data_init(LoadAddr, ExeAddr, SectionLen);
+ }
+ // At this point, SectionTableAddr = &__bss_section_table;
+ // Zero fill the bss segment
+ while (SectionTableAddr < &__bss_section_table_end) {
+ ExeAddr = *SectionTableAddr++;
+ SectionLen = *SectionTableAddr++;
+ bss_init(ExeAddr, SectionLen);
+ }
+#else
+ // Use Old Style Data and BSS section initialization.
+ // This will only initialize a single RAM bank.
+ unsigned int * LoadAddr, *ExeAddr, *EndAddr, SectionLen;
+
+ // Copy the data segment from flash to SRAM.
+ LoadAddr = &_etext;
+ ExeAddr = &_data;
+ EndAddr = &_edata;
+ SectionLen = (void*)EndAddr - (void*)ExeAddr;
+ data_init((unsigned int)LoadAddr, (unsigned int)ExeAddr, SectionLen);
+ // Zero fill the bss segment
+ ExeAddr = &_bss;
+ EndAddr = &_ebss;
+ SectionLen = (void*)EndAddr - (void*)ExeAddr;
+ bss_init ((unsigned int)ExeAddr, SectionLen);
+#endif
+
+//#ifdef __USE_CMSIS
+ SystemInit();
+//#endif
+
+#if defined (__cplusplus)
+ //
+ // Call C++ library initialisation
+ //
+ __libc_init_array();
+#endif
+
+#if defined (__REDLIB__)
+ // Call the Redlib library, which in turn calls main()
+ __main() ;
+#else
+ main();
+#endif
+ //
+ // main() shouldn't return, but if it does, we'll just enter an infinite loop
+ //
+ while (1) {
+ ;
+ }
+}
+//*****************************************************************************
+// Default exception handlers. Override the ones here by defining your own
+// handler routines in your application code.
+//*****************************************************************************
+__attribute__ ((section(".after_vectors")))
+void NMI_Handler(void)
+{
+ while(1)
+ {
+ }
+}
+__attribute__ ((section(".after_vectors")))
+void HardFault_Handler(void)
+{
+ while(1)
+ {
+ }
+}
+__attribute__ ((section(".after_vectors")))
+void SVCall_Handler(void)
+{
+ while(1)
+ {
+ }
+}
+__attribute__ ((section(".after_vectors")))
+void PendSV_Handler(void)
+{
+ while(1)
+ {
+ }
+}
+__attribute__ ((section(".after_vectors")))
+void SysTick_Handler(void)
+{
+ while(1)
+ {
+ }
+}
+
+//*****************************************************************************
+//
+// Processor ends up here if an unexpected interrupt occurs or a specific
+// handler is not present in the application code.
+//
+//*****************************************************************************
+__attribute__ ((section(".after_vectors")))
+void IntDefaultHandler(void)
+{
+ while(1)
+ {
+ }
+}
+
diff --git a/src/core/delay.cpp b/src/core/delay.cpp
new file mode 100755
index 0000000..9d46a23
--- /dev/null
+++ b/src/core/delay.cpp
@@ -0,0 +1,123 @@
+/*
+ * systick.cpp
+ *
+ * Created on: 2011/08/11
+ * Author: atsu
+ */
+
+#include "delay.h"
+
+volatile static unsigned long msTicks; /* counts 1ms timeTicks */
+volatile USER_TIMER_FUNC userfunc; //user function's pointer
+
+/*------------------------------------------------------------------------------
+ delays number of tick Systicks (happens every 1 ms)
+ *------------------------------------------------------------------------------*/
+void delay (unsigned long dlyTicks) {
+ volatile unsigned long curTicks;
+
+ curTicks = msTicks;
+ while ((msTicks - curTicks) < dlyTicks);
+}
+
+
+unsigned long millis(void)
+{
+ return msTicks;
+}
+
+void delayMicroseconds (unsigned long us)
+{
+ volatile unsigned long usTicks;
+
+ //LPC_TMR16B0->TC = 0; //reset timer counter
+ usTicks = LPC_TMR32B1->TC; //usTicks = micros();
+ while ((LPC_TMR32B1->TC - usTicks) < us); //while ((micros() - usTicks) < us);
+
+}
+
+unsigned long micros(void)
+{
+ return LPC_TMR32B1->TC;
+}
+
+//for micros() and delayMicroseconds()
+void setup_TIMER32_1(void)
+{
+ attachMicroseconds(0,0xffffffff);
+ NVIC_DisableIRQ(TIMER_32_1_IRQn);
+}
+
+unsigned long attachMicroseconds(USER_TIMER_FUNC func,int us)
+{
+ LPC_SYSCON->SYSAHBCLKCTRL |= (1UL << 10); // Enable clock for CT32B1 module
+ if(us <= 1)return 0;
+
+ LPC_TMR32B1->PR = 48; //48MHz/48=1MHzに分周する
+ LPC_TMR32B1->MR2 = us - 1; //us
+
+ LPC_TMR32B1->MCR = (0x3 << 6); // clear at MR2 and Interrupt
+
+ NVIC_EnableIRQ(TIMER_32_1_IRQn);
+ NVIC_SetPriority(TIMER_32_1_IRQn,0);//割り込みレベル
+ LPC_TMR32B1->TCR = 1; //タイマスタート
+
+ userfunc = func;
+
+ return 0;
+}
+
+void detachMicroseconds(void)
+{
+ LPC_TMR32B1->MR2 = 0xffffffff; //us
+ NVIC_DisableIRQ(TIMER_32_1_IRQn);
+
+}
+
+/*----------------------------------------------------------------------------
+ Timer32_0_Handler
+ *----------------------------------------------------------------------------*/
+void TIMER32_1_IRQHandler (void)
+{
+ if (LPC_TMR32B1->IR & (1 << 2)) // MR2 Interrupt
+ {
+ if(userfunc)userfunc();
+
+ // Clear Flag
+ LPC_TMR32B1->IR = (1 << 2);
+ }
+}
+
+/*----------------------------------------------------------------------------
+ SysTick_Handler
+ *----------------------------------------------------------------------------*/
+void SysTick_Handler(void) {
+ msTicks++; /* increment counter necessary in Delay() */
+}
+
+void setup_systick (void) {
+
+ //LPC_SYSCON->SYSAHBCLKCTRL |= (1<<6);
+
+ // Setup SysTick Timer for 1 msec interrupts
+ // Configure System tick timer in 10msec period
+ volatile unsigned long period = SystemCoreClock / 1000; // Period for 1msec SYSTICK
+ SysTick_Config(period); // Configuration
+
+#if 1
+ if ( !(SysTick->CTRL & SysTick_CTRL_CLKSOURCE_Msk) )
+ {
+ /* When external reference clock is used(CLKSOURCE in
+ Systick Control and register bit 2 is set to 0), the
+ SYSTICKCLKDIV must be a non-zero value and 2.5 times
+ faster than the reference clock.
+ When core clock, or system AHB clock, is used(CLKSOURCE
+ in Systick Control and register bit 2 is set to 1), the
+ SYSTICKCLKDIV has no effect to the SYSTICK frequency. See
+ more on Systick clock and status register in Cortex-M3
+ technical Reference Manual. */
+ LPC_SYSCON->SYSTICKCLKDIV = 0x08;
+ }
+#endif
+}
+
diff --git a/src/core/delay.h b/src/core/delay.h
new file mode 100755
index 0000000..f72d31f
--- /dev/null
+++ b/src/core/delay.h
@@ -0,0 +1,64 @@
+/*
+ * systick.h
+ *
+ * Created on: 2011/08/11
+ * Author: atsu
+ */
+
+#ifndef SYSTICK_H_
+#define SYSTICK_H_
+
+/**************************************************************************//**
+ * @file systick.h
+ * @brief Arduino-like library for MARY(LPC1114)
+ * @version v.0.50
+ * @date 1. August 2011.
+ * @author this library's assembled by @@dw256 and rebuild by @@lynxeyed_atsu
+ * @note Copyright (c) 2011 Lynx-EyED's Klavier and Craft-works. <BR>
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions: <BR>
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.<BR>
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ******************************************************************************/
+
+
+#include "LPC11xx.h"
+#include "system_LPC11xx.h"
+#include "uart.h"
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+
+typedef void (* USER_TIMER_FUNC)(void);
+
+void delay(unsigned long dlyTicks);
+void delayMicroseconds(unsigned long us);
+unsigned long millis(void);
+//low level
+void SysTick_Handler(void);
+void setup_systick (void);
+unsigned long micros(void);
+unsigned long attachMicroseconds(USER_TIMER_FUNC func,int us);
+void detachMicroseconds(void);
+
+void setup_TIMER32_1(void);
+void TIMER32_1_IRQHandler (void);
+
+#endif /* SYSTICK_H_ */
+
+#ifdef __cplusplus
+ }
+#endif
diff --git a/src/core/gpio.cpp b/src/core/gpio.cpp
new file mode 100755
index 0000000..1a7b18e
--- /dev/null
+++ b/src/core/gpio.cpp
@@ -0,0 +1,102 @@
+#include "gpio.h"
+
+
+/* =======================================
+* Macros and functions for Defining MARY's GPIO Assign
+*
+* CN1_7,8 : (PIO1_2,PIO1_1)
+* should be C17,C18
+*
+* CN2_1...8 : (PIO1_4,PIO1_11,PIO1_7,PIO1_5,PIO3_2,PIO2_0,PIO1_6,PIO0_1)
+* should be C21,C22,C23,C24,C25,C26,C27,C28
+*
+* CN3_1...8 : (PIO1_8,PIO0_3,PIO0_2,PIO3_4,PIO0_4,PIO3_5,PIO0_5,PIO1_7)
+* should be C31,C32,C33,C34,C35,C36,C37,C38
+*
+* CN4_1...7 : (PIO1_9,PIO1_10,PIO0_6,PIO0_11,PIO0_8,PIO1_0,PIO0_9)
+* should be C41,C42,C43,C44,C45,C46,C47
+*
+* see also mary_pinAssign[...] in "gpio.h"
+* =======================================
+*/
+void pinMode(int pin,pinModeState state)
+{
+ if(pin < 20) //arduinoPinAssign(0~19)
+ {
+ if(state == OUTPUT) //OUTPUT
+ {
+ LPC_GPIO[ arduino_pinAssign[pin * 2] ]->DIR |= arduino_pinAssign[pin * 2 + 1];
+ }else //INPUT
+ {
+ LPC_GPIO[ arduino_pinAssign[pin * 2] ]->DIR &= ~(arduino_pinAssign[pin * 2 + 1]);
+ }
+ return;
+ }
+
+ if(pin < 100) return; //(20~99:reserved)
+
+ if(pin < 200) //maryPinAssign(100~119?)
+ {
+ pin = pin - 100;
+ if(state == OUTPUT) //OUTPUT
+ {
+ LPC_GPIO[ mary_pinAssign[pin * 2] ]->DIR |= mary_pinAssign[pin * 2 + 1];
+ }else //INPUT
+ {
+ LPC_GPIO[ mary_pinAssign[pin * 2] ]->DIR &= ~(mary_pinAssign[pin * 2 + 1]);
+ }
+ }
+ return;
+ }
+
+void digitalWrite(int pin,digitalWriteState state)
+{
+ if(pin < 20) //arduinoPinAssign(0~19)
+ {
+ if(state == HIGH) //HIGH
+ {
+ LPC_GPIO[ arduino_pinAssign[pin * 2] ]->MASKED_ACCESS[ arduino_pinAssign[pin * 2 + 1] ] = arduino_pinAssign[pin * 2 + 1];
+ }else //LOW
+ {
+ LPC_GPIO[ arduino_pinAssign[pin * 2] ]->MASKED_ACCESS[ arduino_pinAssign[pin * 2 + 1] ] &= ~(arduino_pinAssign[pin * 2 + 1]);
+ }
+ return;
+ }
+
+ if(pin < 100) return; //arduinoPinAssign(20~99:reserved)
+
+ if(pin < 200) //maryPinAssign(100~119?)
+ {
+ pin = pin - 100;
+ if(state == HIGH) //HIGH
+ {
+ LPC_GPIO[ mary_pinAssign[pin * 2] ]->MASKED_ACCESS[ mary_pinAssign[pin * 2 + 1] ] = mary_pinAssign[pin * 2 + 1];
+ }else //LOW
+ {
+ LPC_GPIO[ mary_pinAssign[pin * 2] ]->MASKED_ACCESS[ mary_pinAssign[pin * 2 + 1] ] &= ~(mary_pinAssign[pin * 2 + 1]);
+ }
+ }
+ return;
+ }
+
+int digitalRead(int pin)
+{
+ volatile int readValue;
+ if(pin < 20) //arduinoPinAssign(0~19)
+ {
+ readValue = (LPC_GPIO[ arduino_pinAssign[pin * 2] ]->MASKED_ACCESS[ arduino_pinAssign[pin * 2 + 1] ])? 1 : 0;
+ return readValue;
+ }
+
+ if(pin < 100) return 0; //(20~99:reserved)
+
+ if(pin < 200) //maryPinAssign(100~199?)
+ {
+ pin = pin - 100;
+ readValue = (LPC_GPIO[ mary_pinAssign[pin * 2] ]->MASKED_ACCESS[ mary_pinAssign[pin * 2 + 1] ])? 1 : 0;
+ return readValue;
+ }
+ return 0;
+}
+
+
diff --git a/src/core/gpio.h b/src/core/gpio.h
new file mode 100755
index 0000000..5b7c05c
--- /dev/null
+++ b/src/core/gpio.h
@@ -0,0 +1,194 @@
+/*
+ * gpio.h
+ *
+ * Created on: 2011/07/27
+ * Author: lynxeyed
+ */
+#ifndef GPIO_H_
+#define GPIO_H_
+
+//#if defined (__USE_CMSIS)
+#include "LPC11xx.h"
+//#endif
+//=======================================
+// Define LPC_GPIO[4] (each top address)
+//=======================================
+static LPC_GPIO_TypeDef (* const LPC_GPIO[4]) = { LPC_GPIO0, LPC_GPIO1, LPC_GPIO2, LPC_GPIO3 };
+
+/* =======================================
+* Macros and functions for Defining MARY's GPIO Assign
+*
+* CN1_7,8 : (PIO1_2,PIO1_1)
+* should be C17,C18
+*
+* CN2_1...8 : (PIO1_4,PIO1_11,PIO1_7,PIO1_5,PIO3_2,PIO2_0,PIO1_6,PIO0_1)
+* should be C21,C22,C23,C24,C25,C26,C27,C28
+*
+* CN3_1...8 : (PIO1_8,PIO0_3,PIO0_2,PIO3_4,PIO0_4,PIO3_5,PIO0_5,PIO1_7)
+* should be C31,C32,C33,C34,C35,C36,C37,C38
+*
+* CN4_1...7 : (PIO1_9,PIO1_10,PIO0_6,PIO0_11,PIO0_8,PIO1_0,PIO0_9)
+* should be C41,C42,C43,C44,C45,C46,C47
+* =======================================
+*/
+#define C17 (100)
+#define C18 (101)
+
+#define C21 (102)
+#define C22 (103)
+#define C23 (104)
+#define C24 (105)
+#define C25 (106)
+#define C26 (107)
+#define C27 (108)
+#define C28 (109)
+
+#define C31 (110)
+#define C32 (111)
+#define C33 (112)
+#define C34 (113)
+#define C35 (114)
+#define C36 (115)
+#define C37 (116)
+#define C38 (117)
+
+#define C41 (118)
+#define C42 (119)
+#define C43 (120)
+#define C44 (121)
+#define C45 (122)
+#define C46 (123)
+#define C47 (124)
+#define GLED (125)
+#define BLED (126)
+#define RLED (127)
+
+// For LPCXpresso LPC1114
+#define P1_2 (100)
+#define P1_1 (101)
+#define P1_4 (102)
+#define P1_11 (103)
+#define P1_7 (104)
+#define P1_5 (105)
+#define P3_2 (106)
+#define P2_0 (107)
+#define P1_6 (108)
+#define P0_1 (109)
+#define P1_8 (110)
+#define P0_3 (111)
+#define P0_2 (112)
+#define P3_4 (113)
+#define P0_4 (114)
+#define P3_5 (115)
+#define P0_5 (116)
+//#define P1_7 (117)
+#define P1_9 (118)
+#define P1_10 (119)
+#define P0_6 (120)
+#define P0_11 (121)
+#define P0_8 (122)
+#define P1_0 (123)
+#define P0_9 (124)
+#define P0_7 (125)
+//#define P1_5 (126)
+//#define P2_0 (127)
+
+#define _BIT0 (1U << 0)
+#define _BIT1 (1U << 1)
+#define _BIT2 (1U << 2)
+#define _BIT3 (1U << 3)
+#define _BIT4 (1U << 4)
+#define _BIT5 (1U << 5)
+#define _BIT6 (1U << 6)
+#define _BIT7 (1U << 7)
+#define _BIT8 (1U << 8)
+#define _BIT9 (1U << 9)
+#define _BIT10 (1U << 10)
+#define _BIT11 (1U << 11)
+
+const unsigned int mary_pinAssign[] =
+{
+ 1, _BIT2, //CN1_7
+ 1, _BIT1, //CN1_8
+
+ 1, _BIT4, //CN2_1
+ 1, _BIT11, //CN2_2
+ 1, _BIT7, //CN2_3
+ 1, _BIT5, //CN2_4
+ 3, _BIT2, //CN2_5
+ 2, _BIT0, //CN2_6
+ 1, _BIT6, //CN2_7
+ 0, _BIT1, //CN2_8
+
+ 1, _BIT8, //CN3_1
+ 0, _BIT3, //CN3_2
+ 0, _BIT2, //CN3_3
+ 3, _BIT4, //CN3_4
+ 0, _BIT4, //CN3_5
+ 3, _BIT5, //CN3_6
+ 0, _BIT5, //CN3_7
+ 1, _BIT7, //CN3_8
+
+ 1, _BIT9, //CN4_1
+ 1, _BIT10, //CN4_2
+ 0, _BIT6, //CN4_3
+ 0, _BIT11, //CN4_4
+ 0, _BIT8, //CN4_5
+ 1, _BIT0, //CN4_6
+ 0, _BIT9, //CN4_7
+ 0, _BIT7, //GLED
+ 1, _BIT5, //BLED
+ 2, _BIT0 //RLED
+};
+
+
+// Arduino's pins assign
+const unsigned int arduino_pinAssign[] =
+{
+ 1, _BIT6, //P1_6:D0/RX
+ 1, _BIT7, //P1_7:D1/TX
+ 0, _BIT3, //P0_3:D2
+ 1, _BIT9, //P1_9:D3
+ 3, _BIT4, //P3_4:D4
+ 2, _BIT4, //P2_4:D5
+ 2, _BIT0, //P2_0:D6
+ 2, _BIT3, //P2_3:D7
+ 2, _BIT2, //P2_2:D8
+ 2, _BIT1, //P2_1:D9
+ 0, _BIT2, //P0_2:D10
+
+ 0, _BIT9, //P0_9:D11
+ 0, _BIT8, //P0_8:D12
+ 0, _BIT6, //P0_6:D13
+
+
+/* 0, _BIT4, //P
+ 3, _BIT5, //CN3_6
+ 0, _BIT5, //CN3_7
+ 1, _BIT7, //CN3_8
+
+ 1, _BIT9, //CN4_1
+ 1, _BIT10, //CN4_2
+ 0, _BIT6, //CN4_3
+ 0, _BIT11, //CN4_4
+ 0, _BIT8, //CN4_5
+ 1, _BIT0, //CN4_6
+ 0, _BIT9, //CN4_7
+ 0, _BIT7, //GLED
+ 1, _BIT5, //BLED
+ 2, _BIT0 //RLED
+*/
+};
+
+
+typedef enum {INPUT, OUTPUT}pinModeState;
+typedef enum {LOW, HIGH}digitalWriteState;
+
+void pinMode(int pin,pinModeState state);
+void digitalWrite(int pin,digitalWriteState state);
+int digitalRead(int pin);
+
+
+
+
+#endif /* GPIO_H_ */
diff --git a/src/core/libmary.h b/src/core/libmary.h
new file mode 100755
index 0000000..eedd3ab
--- /dev/null
+++ b/src/core/libmary.h
@@ -0,0 +1,60 @@
+#ifndef LIBMARY_H_
+#define LIBMARY_H_
+
+/**
+ @mainpage MARY-DUINO (Beta)
+ @section abstruct 概要
+ MARY-DUINOはNXP製LPC1114を搭載したMARY基板でArduinoライクな開発が出来ることを目指すC++ライブラリです
+ @section intro 始めに
+ CQ出版発行・圓山宗智氏によるトランジスタ技術増刊「2枚入り!組み合わせ自在!超小型ARMマイコン基板」に付属している基板をArduinoライクな環境で開発する為の
+ ライブラリです。
+ @section motivation 背景
+ 「2枚入り!組み合わせ自在!超小型ARMマイコン基板」に付属している基板の開発において、よく整備されているライブラリが圓山氏により準備されており、
+ とても使いやすい環境が提供されています。このライブラリではよりお手軽に開発する事を目的としてC++ライブラリをフルスクラッチで作成しており、Arduinoライクな
+ 開発環境を提供しています。今後ここに新たなライブラリを追加し、より使いやすい環境を随時追加してゆきます
+ @section environmen 環境
+ arm-none-eabi-gcc-4.5.0以上またはarm-elf-gcc-4.5.0以上
+ - WindowsではCodesourcery G++かLPCXpresso IDEが動く環境
+ - Mac OSXではSnow Leopard(10.6.1以上)ではXcode 3.4以上がインストール、Lion(10.7)ではXCode 4.1以上がインストールされており、arm-elf-gcc-4.5.0以上がインストールされている事
+ @section history 履歴
+ - 2011/07/15 初版作成
+ */
+
+/**************************************************************************//**
+ * @file libmary.h
+ * @brief Arduino-like library for MARY(LPC1114)
+ * @version v.0.50
+ * @date 1. August 2011.
+ * @author @@lynxeyed_atsu
+ * @note Copyright (c) 2011 Lynx-EyED's Klavier and Craft-works. <BR>
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions: <BR>
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.<BR>
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ******************************************************************************/
+
+
+#include "LPC11xx.h"
+#include "system_LPC11xx.h"
+#include "delay.h"
+#include "gpio.h"
+#include "uart.h"
+
+
+
+// init for arduino-like settings
+
+
+
+#endif /* LIBMARY_H_ */
diff --git a/src/core/maryoled.cpp b/src/core/maryoled.cpp
new file mode 100755
index 0000000..8df935c
--- /dev/null
+++ b/src/core/maryoled.cpp
@@ -0,0 +1,484 @@
+/* mbed Nokia LCD Library
+ * Atsu
+ */
+
+#include "delay.h"
+#include "maryoled.h"
+#include <math.h>
+
+/** General parameters for MARMEX_OB_oled */
+
+#define MARYOLED_ROWS 15
+#define MARYOLED_COLS 16
+#define MARYOLED_WIDTH 128
+#define MARYOLED_HEIGHT 128
+#define MARYOLED_FREQUENCY 20000000
+
+//MARY Pin Assign
+//#define OLED_VCC_ON C21
+//#define OLED_CS C33
+//#define OLED_RES C31
+
+//LPCXpresso pin Assign (MARMEX-SLOT1)
+//#define OLED_VCC_ON P0_7
+//#define OLED_CS P0_2
+//#define OLED_RES P0_1
+
+MARYOLED oled;
+
+MARYOLED::MARYOLED() //default : MARY
+{
+ this->OLED_VCC_ON = C21;
+ this->OLED_CS = C33;
+ this->OLED_RES = C31;
+ this->device = OLED;
+ port = marySSP0;
+ _row = 0;
+ _column = 0;
+ _foreground = 0x00FFFFFF;
+ _background = 0x00000000;
+
+}
+
+MARYOLED::~MARYOLED()
+{
+}
+void MARYOLED::reset(SSP_PORT port)
+{
+ this->port = port;
+ if(port==LPCXSSP0) //LPCXpresso 1114 + MAPLE
+ {
+ this->OLED_VCC_ON = P0_7;
+ this->OLED_CS = P0_2;
+ this->OLED_RES = P0_1;
+ }
+ pinMode(OLED_VCC_ON,OUTPUT);
+ pinMode(OLED_RES,OUTPUT);
+ pinMode(OLED_CS,OUTPUT);
+
+ digitalWrite(OLED_RES,HIGH);
+ digitalWrite(OLED_VCC_ON,LOW);
+
+ reset();
+ return;
+}
+void MARYOLED::reset() {
+ #define GAMMA_LUT_SIZE 63
+ //unsigned char gamma_LUT[ GAMMA_LUT_SIZE ];
+
+ //for ( int i = 0; i < GAMMA_LUT_SIZE; i++ )
+ //gamma_LUT[ i ] = (unsigned char)(powf( ((float)i / 62.0), (1.0 / 0.58) ) * 178.0 + 2.0);
+ unsigned char gamma_LUT[63] =
+ {
+ 0x02, 0x03, 0x04, 0x05,
+ 0x06, 0x07, 0x08, 0x09,
+ 0x0a, 0x0b, 0x0c, 0x0d,
+ 0x0e, 0x0f, 0x10, 0x11,
+ //
+ 0x12, 0x13, 0x15, 0x17,
+ 0x19, 0x1b, 0x1d, 0x1f,
+ 0x21, 0x23, 0x25, 0x27,
+ 0x2a, 0x2d, 0x30, 0x33,
+ //
+ 0x36, 0x39, 0x3c, 0x3f,
+ 0x42, 0x45, 0x48, 0x4c,
+ 0x50, 0x54, 0x58, 0x5c,
+ 0x60, 0x64, 0x68, 0x6c,
+ //
+ 0x70, 0x74, 0x78, 0x7d,
+ 0x82, 0x87, 0x8c, 0x91,
+ 0x96, 0x9b, 0xa0, 0xa5,
+ 0xaa, 0xaf, 0xb4
+ };
+
+ // setup the _spi interface and bring display out of reset
+ digitalWrite( OLED_CS, HIGH );
+ digitalWrite( OLED_RES, LOW );
+
+
+ SPI.setBitLength( 9 ); //9bit mode
+ SPI.setDataMode(SPI_MODE3);
+ SPI.setClockDivider( SPI_CLOCK_DIV2 );
+ SPI.begin(port);
+ //ssp_begin(SPI_CLOCK_DIV1, SPI_MODE0, 9);
+
+ delay( 100 ); //wait 100ms
+ digitalWrite( OLED_RES, LOW );
+ delay( 100 );
+ digitalWrite( OLED_RES, HIGH ); //RESET
+
+ command( SET_DISPLAY_MODE_ALL_OFF );
+
+ command( SET_COMMAND_LOCK );
+ data( 0x12 );
+
+ command( SET_COMMAND_LOCK );
+ data( 0xb1 );
+
+ command( SET_SLEEP_MODE_ON );
+
+ command( FRONT_CLOCK_DRIVER_OSC_FREQ );
+ data( 0xF1 );
+
+ command( SET_MUX_RATIO );
+ data( 0x7F );
+
+ command( SET_DISPAY_OFFSET );
+ data( 0x00 );
+
+ command( SET_DISPAY_START_LINE );
+ data( 0x00 );
+
+ command( SET_REMAP_COLOR_DEPTH );
+ data( 0x74 );
+
+ command( SET_GPIO );
+ data( 0x00);
+
+ command( FUNCTION_SELECTION );
+ data( 0x01 );
+
+ command( SET_SEGMENT_LOW_VOLTAGE );
+ data( 0xA0 );
+ data( 0xB5 );
+ data( 0x55 );
+
+ command( SET_CONTRAST_CURRENT_FOR_COLOR_ABC );
+ data( 0xC8 );
+ data( 0x80 );
+ data( 0xC8 );
+
+ command( MASTER_CONTRAST_CURRENT_CONTROL );
+ data( 0x0F );
+
+ command( LOOKUP_TABLE_FOR_GRAYSCALE_PULSE_WIDTH );
+ for ( int i = 0; i < GAMMA_LUT_SIZE; i++ )
+ data( gamma_LUT[ i ] );
+
+ //command( USE_BUILT_IN_LINEAR_LUT );
+
+ command( SET_RESET_PRECHARGE_PERIOD );
+ data( 0x32 );
+
+ command( ENHANCE_DRIVING_SCHEME_CAPABILITY );
+ data( 0xA4 );//data( 0x04 );
+ data( 0x00 );
+ data( 0x00 );
+
+ command( SET_PRECHARGE_VOLTAGE );
+ data( 0x17 );
+
+ command( SET_SECOND_PRECHARGE_VOLTAGE );
+ data( 0x01 );
+
+ command( SET_VCOMH_VOLTAGE );
+ data( 0x05 );
+ command( SET_DISPLAY_MODE_RESET );
+
+ command( SET_COLUMN_ADDRESS );
+ data( 0x00 );
+ data( 0x7f );
+
+ command( SET_ROW_ADDRESS );
+ data( 0x00 );
+ data( 0x7f );
+
+ cls();
+ //WindowReset();
+
+ digitalWrite(OLED_VCC_ON,HIGH);
+
+ delay( 200 ); //wait 200ms
+
+ command( SET_SLEEP_MODE_OFF );
+ return;
+}
+
+void MARYOLED::command(int value) {
+
+ digitalWrite(OLED_CS,LOW);
+ SPI.transfer(value & 0xff);
+ //ssp_transfer(value & 0xFF);
+ digitalWrite(OLED_CS,HIGH);
+}
+
+void MARYOLED::data(int value) {
+ digitalWrite(OLED_CS,LOW);
+ SPI.transfer(value | 0x100);
+ //ssp_transfer(value | 0x100);
+ digitalWrite(OLED_CS,HIGH);
+}
+
+void MARYOLED::_window( int x, int y, int width, int height )
+{
+ int x1 = x + 0;
+ int y1 = y + 0;
+ int x2 = x1 + width - 1;
+ int y2 = y1 + height - 1;
+
+ command( SET_COLUMN_ADDRESS );
+ data( x1 );
+ data( x2 );
+ command( SET_ROW_ADDRESS );
+ data( y1 );
+ data( y2 );
+ command( WRITE_RAM_COMMAND );
+
+}
+
+void MARYOLED::WindowReset(void)
+{
+ command( SET_COLUMN_ADDRESS );
+ data( 0 );
+ data( 127 );
+ command( SET_ROW_ADDRESS );
+ data( 0 );
+ data( 127 );
+ command( WRITE_RAM_COMMAND );
+}
+
+
+
+
+const unsigned char FONT8x8[97][8] = {
+ {0x08,0x08,0x08,0x00,0x00,0x00,0x00,0x00}, // columns, rows, num_bytes_per_char
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // space 0x20
+ {0x30,0x78,0x78,0x30,0x30,0x00,0x30,0x00}, // !
+ {0x6C,0x6C,0x6C,0x00,0x00,0x00,0x00,0x00}, // "
+ {0x6C,0x6C,0xFE,0x6C,0xFE,0x6C,0x6C,0x00}, // #
+ {0x18,0x3E,0x60,0x3C,0x06,0x7C,0x18,0x00}, // $
+ {0x00,0x63,0x66,0x0C,0x18,0x33,0x63,0x00}, // %
+ {0x1C,0x36,0x1C,0x3B,0x6E,0x66,0x3B,0x00}, // &
+ {0x30,0x30,0x60,0x00,0x00,0x00,0x00,0x00}, // '
+ {0x0C,0x18,0x30,0x30,0x30,0x18,0x0C,0x00}, // (
+ {0x30,0x18,0x0C,0x0C,0x0C,0x18,0x30,0x00}, // )
+ {0x00,0x66,0x3C,0xFF,0x3C,0x66,0x00,0x00}, // *
+ {0x00,0x30,0x30,0xFC,0x30,0x30,0x00,0x00}, // +
+ {0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x30}, // ,
+ {0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x00}, // -
+ {0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00}, // .
+ {0x03,0x06,0x0C,0x18,0x30,0x60,0x40,0x00}, // / (forward slash)
+ {0x3E,0x63,0x63,0x6B,0x63,0x63,0x3E,0x00}, // 0 0x30
+ {0x18,0x38,0x58,0x18,0x18,0x18,0x7E,0x00}, // 1
+ {0x3C,0x66,0x06,0x1C,0x30,0x66,0x7E,0x00}, // 2
+ {0x3C,0x66,0x06,0x1C,0x06,0x66,0x3C,0x00}, // 3
+ {0x0E,0x1E,0x36,0x66,0x7F,0x06,0x0F,0x00}, // 4
+ {0x7E,0x60,0x7C,0x06,0x06,0x66,0x3C,0x00}, // 5
+ {0x1C,0x30,0x60,0x7C,0x66,0x66,0x3C,0x00}, // 6
+ {0x7E,0x66,0x06,0x0C,0x18,0x18,0x18,0x00}, // 7
+ {0x3C,0x66,0x66,0x3C,0x66,0x66,0x3C,0x00}, // 8
+ {0x3C,0x66,0x66,0x3E,0x06,0x0C,0x38,0x00}, // 9
+ {0x00,0x18,0x18,0x00,0x00,0x18,0x18,0x00}, // :
+ {0x00,0x18,0x18,0x00,0x00,0x18,0x18,0x30}, // ;
+ {0x0C,0x18,0x30,0x60,0x30,0x18,0x0C,0x00}, // <
+ {0x00,0x00,0x7E,0x00,0x00,0x7E,0x00,0x00}, // =
+ {0x30,0x18,0x0C,0x06,0x0C,0x18,0x30,0x00}, // >
+ {0x3C,0x66,0x06,0x0C,0x18,0x00,0x18,0x00}, // ?
+ {0x3E,0x63,0x6F,0x69,0x6F,0x60,0x3E,0x00}, // @ 0x40
+ {0x18,0x3C,0x66,0x66,0x7E,0x66,0x66,0x00}, // A
+ {0x7E,0x33,0x33,0x3E,0x33,0x33,0x7E,0x00}, // B
+ {0x1E,0x33,0x60,0x60,0x60,0x33,0x1E,0x00}, // C
+ {0x7C,0x36,0x33,0x33,0x33,0x36,0x7C,0x00}, // D
+ {0x7F,0x31,0x34,0x3C,0x34,0x31,0x7F,0x00}, // E
+ {0x7F,0x31,0x34,0x3C,0x34,0x30,0x78,0x00}, // F
+ {0x1E,0x33,0x60,0x60,0x67,0x33,0x1F,0x00}, // G
+ {0x66,0x66,0x66,0x7E,0x66,0x66,0x66,0x00}, // H
+ {0x3C,0x18,0x18,0x18,0x18,0x18,0x3C,0x00}, // I
+ {0x0F,0x06,0x06,0x06,0x66,0x66,0x3C,0x00}, // J
+ {0x73,0x33,0x36,0x3C,0x36,0x33,0x73,0x00}, // K
+ {0x78,0x30,0x30,0x30,0x31,0x33,0x7F,0x00}, // L
+ {0x63,0x77,0x7F,0x7F,0x6B,0x63,0x63,0x00}, // M
+ {0x63,0x73,0x7B,0x6F,0x67,0x63,0x63,0x00}, // N
+ {0x3E,0x63,0x63,0x63,0x63,0x63,0x3E,0x00}, // O
+ {0x7E,0x33,0x33,0x3E,0x30,0x30,0x78,0x00}, // P 0x50
+ {0x3C,0x66,0x66,0x66,0x6E,0x3C,0x0E,0x00}, // Q
+ {0x7E,0x33,0x33,0x3E,0x36,0x33,0x73,0x00}, // R
+ {0x3C,0x66,0x30,0x18,0x0C,0x66,0x3C,0x00}, // S
+ {0x7E,0x5A,0x18,0x18,0x18,0x18,0x3C,0x00}, // T
+ {0x66,0x66,0x66,0x66,0x66,0x66,0x7E,0x00}, // U
+ {0x66,0x66,0x66,0x66,0x66,0x3C,0x18,0x00}, // V
+ {0x63,0x63,0x63,0x6B,0x7F,0x77,0x63,0x00}, // W
+ {0x63,0x63,0x36,0x1C,0x1C,0x36,0x63,0x00}, // X
+ {0x66,0x66,0x66,0x3C,0x18,0x18,0x3C,0x00}, // Y
+ {0x7F,0x63,0x46,0x0C,0x19,0x33,0x7F,0x00}, // Z
+ {0x3C,0x30,0x30,0x30,0x30,0x30,0x3C,0x00}, // [
+ {0x60,0x30,0x18,0x0C,0x06,0x03,0x01,0x00}, // \ (back slash)
+ {0x3C,0x0C,0x0C,0x0C,0x0C,0x0C,0x3C,0x00}, // ]
+ {0x08,0x1C,0x36,0x63,0x00,0x00,0x00,0x00}, // ^
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF}, // _
+ {0x18,0x18,0x0C,0x00,0x00,0x00,0x00,0x00}, // ` 0x60
+ {0x00,0x00,0x3C,0x06,0x3E,0x66,0x3B,0x00}, // a
+ {0x70,0x30,0x3E,0x33,0x33,0x33,0x6E,0x00}, // b
+ {0x00,0x00,0x3C,0x66,0x60,0x66,0x3C,0x00}, // c
+ {0x0E,0x06,0x3E,0x66,0x66,0x66,0x3B,0x00}, // d
+ {0x00,0x00,0x3C,0x66,0x7E,0x60,0x3C,0x00}, // e
+ {0x1C,0x36,0x30,0x78,0x30,0x30,0x78,0x00}, // f
+ {0x00,0x00,0x3B,0x66,0x66,0x3E,0x06,0x7C}, // g
+ {0x70,0x30,0x36,0x3B,0x33,0x33,0x73,0x00}, // h
+ {0x18,0x00,0x38,0x18,0x18,0x18,0x3C,0x00}, // i
+ {0x06,0x00,0x06,0x06,0x06,0x66,0x66,0x3C}, // j
+ {0x70,0x30,0x33,0x36,0x3C,0x36,0x73,0x00}, // k
+ {0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00}, // l
+ {0x00,0x00,0x66,0x7F,0x7F,0x6B,0x63,0x00}, // m
+ {0x00,0x00,0x7C,0x66,0x66,0x66,0x66,0x00}, // n
+ {0x00,0x00,0x3C,0x66,0x66,0x66,0x3C,0x00}, // o
+ {0x00,0x00,0x6E,0x33,0x33,0x3E,0x30,0x78}, // p
+ {0x00,0x00,0x3B,0x66,0x66,0x3E,0x06,0x0F}, // q
+ {0x00,0x00,0x6E,0x3B,0x33,0x30,0x78,0x00}, // r
+ {0x00,0x00,0x3E,0x60,0x3C,0x06,0x7C,0x00}, // s
+ {0x08,0x18,0x3E,0x18,0x18,0x1A,0x0C,0x00}, // t
+ {0x00,0x00,0x66,0x66,0x66,0x66,0x3B,0x00}, // u
+ {0x00,0x00,0x66,0x66,0x66,0x3C,0x18,0x00}, // v
+ {0x00,0x00,0x63,0x6B,0x7F,0x7F,0x36,0x00}, // w
+ {0x00,0x00,0x63,0x36,0x1C,0x36,0x63,0x00}, // x
+ {0x00,0x00,0x66,0x66,0x66,0x3E,0x06,0x7C}, // y
+ {0x00,0x00,0x7E,0x4C,0x18,0x32,0x7E,0x00}, // z
+ {0x0E,0x18,0x18,0x70,0x18,0x18,0x0E,0x00}, // {
+ {0x0C,0x0C,0x0C,0x00,0x0C,0x0C,0x0C,0x00}, // |
+ {0x70,0x18,0x18,0x0E,0x18,0x18,0x70,0x00}, // }
+ {0x3B,0x6E,0x00,0x00,0x00,0x00,0x00,0x00}, // ~
+ {0x1C,0x36,0x36,0x1C,0x00,0x00,0x00,0x00}
+}; // DEL
+
+void MARYOLED::locate(int column, int row) {
+ _column = column;
+ _row = row;
+}
+
+void MARYOLED::newline() {
+ _column = 0;
+ _row++;
+ if (_row >= rows() ) {
+ _row = 0;
+ }
+}
+
+void MARYOLED::_putp( int colour ) {
+ /*int cnv = 0;
+
+ cnv = (colour >> 8) & 0xf800;
+ cnv |= (colour >> 5) & 0x07e0;
+ cnv |= (colour >> 3) & 0x001f;
+
+ data( cnv >> 8);
+ data( cnv );
+ */
+ unsigned long data1, data2;
+ data1 = ((colour >> 8) & 0xff) | 0x100;
+ data2 = (colour & 0x0ff) | 0x100;
+ data(data1);
+ data(data2);
+ }
+int MARYOLED::_putc(int value) {
+ int x = _column * 8; // FIXME: Char sizes
+ int y = _row * 8;
+ bitblit(x + 1, y + 1, 8, 8, (char*)&(FONT8x8[value - 0x1F][0]));
+
+ _column++;
+
+ if (_column >= MARYOLED_COLS) {
+ _row++;
+ _column = 0;
+ }
+
+ if (_row >= MARYOLED_ROWS) {
+ _row = 0;
+ }
+
+ return value;
+}
+
+void MARYOLED::cls( void ) {
+ fill( 0, 0, MARYOLED_WIDTH , MARYOLED_HEIGHT, _background );
+ _row = 0;
+ _column = 0;
+}
+
+
+void MARYOLED::window(int x, int y, int width, int height) {
+ // digitalWrite( OLED_CS, LOW );
+ _window(x, y, width, height);
+ //digitalWrite( OLED_CS, HIGH );
+}
+
+void MARYOLED::putp(int colour) {
+ //digitalWrite( OLED_CS, LOW );
+ _putp(colour);
+ //digitalWrite( OLED_CS, HIGH );
+}
+
+
+void MARYOLED::pixel(int x, int y, int colour) {
+ //digitalWrite( OLED_CS, LOW );
+ _window(x, y, 1, 1);
+ _putp(colour);
+ //digitalWrite( OLED_CS, HIGH );
+}
+
+void MARYOLED::fill( int x, int y, int width, int height, int colour )
+{
+ digitalWrite( OLED_CS, LOW );
+ _window( x, y, width, height );
+
+ for (int i = 0; i < width * height; i++ ) {
+ _putp( colour );
+ }
+
+ _window( 0, 0, MARYOLED_WIDTH, MARYOLED_HEIGHT );
+ digitalWrite( OLED_CS, HIGH );
+}
+
+
+void MARYOLED::blit( int x, int y, int width, int height, const int* colour ) {
+ digitalWrite( OLED_CS, LOW );
+ _window( x, y, width, height );
+
+ for (int i = 0; i < width * height; i++ ) {
+ _putp( colour[i] );
+ }
+ _window( 0, 0, MARYOLED_WIDTH, MARYOLED_HEIGHT );
+ digitalWrite( OLED_CS, HIGH );
+}
+
+
+void MARYOLED::bitblit( int x, int y, int width, int height, const char* bitstream ) {
+ digitalWrite( OLED_CS, LOW );
+ _window( x, y, width, height );
+
+ for (int i = 0; i < height * width; i++ ) {
+ int byte = i / 8;
+ int bit = i % 8;
+ int colour = ((bitstream[ byte ] << bit) & 0x80) ? _foreground : _background;
+ _putp( colour );
+ }
+ _window( 0, 0, _width, _height );
+ digitalWrite( OLED_CS, HIGH );
+}
+
+void MARYOLED::foreground(int c) {
+ _foreground = c;
+ return;
+}
+
+void MARYOLED::background(int c) {
+ _background = c;
+ return;
+}
+
+int MARYOLED::width() {
+ return MARYOLED_WIDTH;
+}
+
+int MARYOLED::height() {
+ return MARYOLED_HEIGHT;
+}
+
+int MARYOLED::columns() {
+ return MARYOLED_COLS;
+}
+
+int MARYOLED::rows() {
+ return MARYOLED_ROWS;
+}
+
+
diff --git a/src/core/maryoled.h b/src/core/maryoled.h
new file mode 100755
index 0000000..3998f8d
--- /dev/null
+++ b/src/core/maryoled.h
@@ -0,0 +1,127 @@
+/*
+ * MARYOLED.h
+ *
+ * Created on: 2011/08/01
+ * Author: lynxeyed
+ */
+
+#ifndef MARYOLED_H_
+#define MARYOLED_H_
+
+/**************************************************************************//**
+ * @file maryoled.h
+ * @brief Arduino-like library for MARY(LPC1114)
+ * @version v.0.50
+ * @date 1. August 2011.
+ * @author this library's assembled by @@dw256 and @@tedd_okano rebuild by @@lynxeyed_atsu
+ * @note Copyright (c) 2011 Lynx-EyED's Klavier and Craft-works. <BR>
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions: <BR>
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.<BR>
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ******************************************************************************/
+
+#include "SPI.h"
+#include "gpio.h"
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+typedef enum {OLED,Nokia6610,Nokia6100,PCF8833} LCD_DEVICES; // Defaults:OLED
+
+class MARYOLED {
+private:
+ SSP_PORT port;
+ LCD_DEVICES device;
+ int OLED_VCC_ON;
+ int OLED_CS;
+ int OLED_RES;
+ int _row;
+ int _column;
+ int _foreground;
+ int _background;
+ int _width;
+ int _height;
+
+ /** Command list for the OLED controller */
+ enum {
+ SET_DISPLAY_MODE_ALL_OFF = 0xA4,
+ SET_COMMAND_LOCK = 0xFD,
+ SET_SLEEP_MODE_ON = 0xAE,
+ FRONT_CLOCK_DRIVER_OSC_FREQ = 0xB3,
+ SET_MUX_RATIO = 0xCA,
+ SET_DISPAY_OFFSET = 0xA2,
+ SET_DISPAY_START_LINE = 0xA1,
+ SET_REMAP_COLOR_DEPTH = 0xA0,
+ SET_GPIO = 0xB5,
+ FUNCTION_SELECTION = 0xAB,
+ SET_SEGMENT_LOW_VOLTAGE = 0xB4,
+ SET_CONTRAST_CURRENT_FOR_COLOR_ABC = 0xC1,
+ MASTER_CONTRAST_CURRENT_CONTROL = 0xC7,
+ LOOKUP_TABLE_FOR_GRAYSCALE_PULSE_WIDTH = 0xB8,
+ USE_BUILT_IN_LINEAR_LUT = 0xB9,
+ SET_RESET_PRECHARGE_PERIOD = 0xB1,
+ ENHANCE_DRIVING_SCHEME_CAPABILITY = 0xB2,
+ SET_PRECHARGE_VOLTAGE = 0xBB,
+ SET_SECOND_PRECHARGE_VOLTAGE = 0xB6,
+ SET_VCOMH_VOLTAGE = 0xBE,
+ SET_DISPLAY_MODE_RESET = 0xA6,
+ SET_COLUMN_ADDRESS = 0x15,
+ SET_ROW_ADDRESS = 0x75,
+ WRITE_RAM_COMMAND = 0x5C,
+ SET_SLEEP_MODE_OFF = 0xAF
+ };
+ /** Constants for power() function */
+ enum {
+ OFF = 0, /**< : to turning-OFF */
+ ON /**< : to turning-ON */
+ };
+
+
+public:
+ MARYOLED(); // announce the constructor to initialize
+ ~MARYOLED();
+
+ void reset();
+ void reset(SSP_PORT port);
+ void command( int value );
+ void data( int value );
+ void _window( int x, int y, int width, int height );
+ void locate(int column, int row);
+ void newline();
+ void _putp( int colour );
+ int _putc( int value );
+ void cls( void );
+ void window( int x, int y, int width, int height );
+ void WindowReset(void);
+ void putp( int colour );
+ void pixel( int x, int y, int colour );
+ void fill( int x, int y, int width, int height, int colour );
+ void blit( int x, int y, int width, int height, const int* colour );
+ void bitblit( int x, int y, int width, int height, const char* bitstream );
+ void foreground(int c);
+ void background(int c);
+ int width();
+ int height();
+ int columns();
+ int rows();
+};
+
+extern MARYOLED oled;
+
+#ifdef __cplusplus
+ }
+#endif
+#endif /* MARYOLED_H_ */
diff --git a/src/core/startup_mary.cpp b/src/core/startup_mary.cpp
new file mode 100755
index 0000000..8ce5c39
--- /dev/null
+++ b/src/core/startup_mary.cpp
@@ -0,0 +1,26 @@
+/*
+ * startup_mary.cpp
+ *
+ * Created on: 2011/08/04
+ * Author: lynxeyed
+ */
+
+#include "libmary.h"
+
+void setup(void);
+void loop(void);
+
+int main(void)
+{
+
+ setup_systick();
+ setup_TIMER32_1();
+
+ setup();
+
+ while(1)
+ {
+ loop();
+ }
+
+}
diff --git a/src/core/system_LPC11xx.cpp b/src/core/system_LPC11xx.cpp
new file mode 100755
index 0000000..4d8d275
--- /dev/null
+++ b/src/core/system_LPC11xx.cpp
@@ -0,0 +1,452 @@
+/**************************************************************************//**
+ * @file system_LPC11xx.c
+ * @brief CMSIS Cortex-M0 Device Peripheral Access Layer Source File
+ * for the NXP LPC11xx Device Series
+ * @version V1.00
+ * @date 17. November 2009
+ *
+ * @note
+ * Copyright (C) 2009 ARM Limited. All rights reserved.
+ *
+ * @par
+ * ARM Limited (ARM) is supplying this software for use with Cortex-M
+ * processor based microcontrollers. This file can be freely distributed
+ * within development tools that are supporting such ARM based processors.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
+ * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
+ * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
+ * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
+ *
+ ******************************************************************************/
+
+
+#include <stdint.h>
+#include "LPC11xx.h"
+
+/*
+//-------- <<< Use Configuration Wizard in Context Menu >>> ------------------
+*/
+
+/*--------------------- Clock Configuration ----------------------------------
+//
+// <e> Clock Configuration
+// <e1> System Clock Setup
+// <e2> System Oscillator Enable
+// <o3.1> Select System Oscillator Frequency Range
+// <0=> 1 - 20 MHz
+// <1=> 15 - 25 MHz
+// </e2>
+// <e4> Watchdog Oscillator Enable
+// <o5.0..4> Select Divider for Fclkana
+// <0=> 2 <1=> 4 <2=> 6 <3=> 8
+// <4=> 10 <5=> 12 <6=> 14 <7=> 16
+// <8=> 18 <9=> 20 <10=> 22 <11=> 24
+// <12=> 26 <13=> 28 <14=> 30 <15=> 32
+// <16=> 34 <17=> 36 <18=> 38 <19=> 40
+// <20=> 42 <21=> 44 <22=> 46 <23=> 48
+// <24=> 50 <25=> 52 <26=> 54 <27=> 56
+// <28=> 58 <29=> 60 <30=> 62 <31=> 64
+// <o5.5..8> Select Watchdog Oscillator Analog Frequency (Fclkana)
+// <0=> Disabled
+// <1=> 0.5 MHz
+// <2=> 0.8 MHz
+// <3=> 1.1 MHz
+// <4=> 1.4 MHz
+// <5=> 1.6 MHz
+// <6=> 1.8 MHz
+// <7=> 2.0 MHz
+// <8=> 2.2 MHz
+// <9=> 2.4 MHz
+// <10=> 2.6 MHz
+// <11=> 2.7 MHz
+// <12=> 2.9 MHz
+// <13=> 3.1 MHz
+// <14=> 3.2 MHz
+// <15=> 3.4 MHz
+// </e4>
+// <o6> Select Input Clock for sys_pllclkin (Register: SYSPLLCLKSEL)
+// <0=> IRC Oscillator
+// <1=> System Oscillator
+// <2=> WDT Oscillator
+// <3=> Invalid
+// <e7> Use System PLL
+// <i> F_pll = M * F_in
+// <i> F_in must be in the range of 10 MHz to 25 MHz
+// <o8.0..4> M: PLL Multiplier Selection
+// <1-32><#-1>
+// <o8.5..6> P: PLL Divider Selection
+// <0=> 2
+// <1=> 4
+// <2=> 8
+// <3=> 16
+// <o8.7> DIRECT: Direct CCO Clock Output Enable
+// <o8.8> BYPASS: PLL Bypass Enable
+// </e7>
+// <o9> Select Input Clock for Main clock (Register: MAINCLKSEL)
+// <0=> IRC Oscillator
+// <1=> Input Clock to System PLL
+// <2=> WDT Oscillator
+// <3=> System PLL Clock Out
+// </e1>
+// <o10.0..7> System AHB Divider <0-255>
+// <i> 0 = is disabled
+// <o11.0> SYS Clock Enable
+// <o11.1> ROM Clock Enable
+// <o11.2> RAM Clock Enable
+// <o11.3> FLASHREG Flash Register Interface Clock Enable
+// <o11.4> FLASHARRAY Flash Array Access Clock Enable
+// <o11.5> I2C Clock Enable
+// <o11.6> GPIO Clock Enable
+// <o11.7> CT16B0 Clock Enable
+// <o11.8> CT16B1 Clock Enable
+// <o11.9> CT32B0 Clock Enable
+// <o11.10> CT32B1 Clock Enable
+// <o11.11> SSP0 Clock Enable
+// <o11.12> UART Clock Enable
+// <o11.13> ADC Clock Enable
+// <o11.15> WDT Clock Enable
+// <o11.16> IOCON Clock Enable
+// <o11.18> SSP1 Clock Enable
+//
+// <o12.0..7> SSP0 Clock Divider <0-255>
+// <i> 0 = is disabled
+// <o13.0..7> UART Clock Divider <0-255>
+// <i> 0 = is disabled
+// <o14.0..7> SSP1 Clock Divider <0-255>
+// <i> 0 = is disabled
+// </e>
+*/
+#define CLOCK_SETUP 1
+#define SYSCLK_SETUP 1
+#define SYSOSC_SETUP 1
+#define SYSOSCCTRL_Val 0x00000000
+#define WDTOSC_SETUP 0
+#define WDTOSCCTRL_Val 0x000000A0
+//#define SYSPLLCLKSEL_Val 0x00000001
+#define SYSPLLCLKSEL_Val 0x00000000 // for Mary-MB
+#define SYSPLL_SETUP 1
+#define SYSPLLCTRL_Val 0x00000023
+#define MAINCLKSEL_Val 0x00000003
+#define SYSAHBCLKDIV_Val 0x00000001
+//#define AHBCLKCTRL_Val 0x0001005F
+#define AHBCLKCTRL_Val 0x0001FFFF // for Mary-MB
+#define SSP0CLKDIV_Val 0x00000001
+#define UARTCLKDIV_Val 0x00000001
+#define SSP1CLKDIV_Val 0x00000001
+
+/*--------------------- Memory Mapping Configuration -------------------------
+//
+// <e> Memory Mapping
+// <o1.0..1> System Memory Remap (Register: SYSMEMREMAP)
+// <0=> Bootloader mapped to address 0
+// <1=> RAM mapped to address 0
+// <2=> Flash mapped to address 0
+// <3=> Flash mapped to address 0
+// </e>
+*/
+#define MEMMAP_SETUP 0
+#define SYSMEMREMAP_Val 0x00000001
+
+/*
+//-------- <<< end of configuration section >>> ------------------------------
+*/
+
+/*----------------------------------------------------------------------------
+ Check the register settings
+ *----------------------------------------------------------------------------*/
+#define CHECK_RANGE(val, min, max) ((val < min) || (val > max))
+#define CHECK_RSVD(val, mask) (val & mask)
+
+/* Clock Configuration -------------------------------------------------------*/
+#if (CHECK_RSVD((SYSOSCCTRL_Val), ~0x00000003))
+ #error "SYSOSCCTRL: Invalid values of reserved bits!"
+#endif
+
+#if (CHECK_RSVD((WDTOSCCTRL_Val), ~0x000001FF))
+ #error "WDTOSCCTRL: Invalid values of reserved bits!"
+#endif
+
+#if (CHECK_RANGE((SYSPLLCLKSEL_Val), 0, 2))
+ #error "SYSPLLCLKSEL: Value out of range!"
+#endif
+
+#if (CHECK_RSVD((SYSPLLCTRL_Val), ~0x000001FF))
+ #error "SYSPLLCTRL: Invalid values of reserved bits!"
+#endif
+
+#if (CHECK_RSVD((MAINCLKSEL_Val), ~0x00000003))
+ #error "MAINCLKSEL: Invalid values of reserved bits!"
+#endif
+
+#if (CHECK_RANGE((SYSAHBCLKDIV_Val), 0, 255))
+ #error "SYSAHBCLKDIV: Value out of range!"
+#endif
+
+#if (CHECK_RSVD((AHBCLKCTRL_Val), ~0x0001FFFF))
+ #error "AHBCLKCTRL: Invalid values of reserved bits!"
+#endif
+
+#if (CHECK_RANGE((SSP0CLKDIV_Val), 0, 255))
+ #error "SSP0CLKDIV: Value out of range!"
+#endif
+
+#if (CHECK_RANGE((UARTCLKDIV_Val), 0, 255))
+ #error "UARTCLKDIV: Value out of range!"
+#endif
+
+#if (CHECK_RANGE((SSP1CLKDIV_Val), 0, 255))
+ #error "SSP1CLKDIV: Value out of range!"
+#endif
+
+#if (CHECK_RSVD((SYSMEMREMAP_Val), ~0x00000003))
+ #error "SYSMEMREMAP: Invalid values of reserved bits!"
+#endif
+
+
+/*----------------------------------------------------------------------------
+ DEFINES
+ *----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+ Define clocks
+ *----------------------------------------------------------------------------*/
+#define __XTAL (12000000UL) /* Oscillator frequency */
+#define __SYS_OSC_CLK ( __XTAL) /* Main oscillator frequency */
+#define __IRC_OSC_CLK (12000000UL) /* Internal RC oscillator frequency */
+
+
+#define __FREQSEL ((WDTOSCCTRL_Val >> 5) & 0x0F)
+#define __DIVSEL (((WDTOSCCTRL_Val & 0x1F) << 1) + 2)
+
+#if (CLOCK_SETUP) /* Clock Setup */
+ #if (SYSCLK_SETUP) /* System Clock Setup */
+ #if (WDTOSC_SETUP) /* Watchdog Oscillator Setup*/
+ #if (__FREQSEL == 0)
+ #define __WDT_OSC_CLK ( 400000 / __DIVSEL)
+ #elif (__FREQSEL == 1)
+ #define __WDT_OSC_CLK ( 500000 / __DIVSEL)
+ #elif (__FREQSEL == 2)
+ #define __WDT_OSC_CLK ( 800000 / __DIVSEL)
+ #elif (__FREQSEL == 3)
+ #define __WDT_OSC_CLK (1100000 / __DIVSEL)
+ #elif (__FREQSEL == 4)
+ #define __WDT_OSC_CLK (1400000 / __DIVSEL)
+ #elif (__FREQSEL == 5)
+ #define __WDT_OSC_CLK (1600000 / __DIVSEL)
+ #elif (__FREQSEL == 6)
+ #define __WDT_OSC_CLK (1800000 / __DIVSEL)
+ #elif (__FREQSEL == 7)
+ #define __WDT_OSC_CLK (2000000 / __DIVSEL)
+ #elif (__FREQSEL == 8)
+ #define __WDT_OSC_CLK (2200000 / __DIVSEL)
+ #elif (__FREQSEL == 9)
+ #define __WDT_OSC_CLK (2400000 / __DIVSEL)
+ #elif (__FREQSEL == 10)
+ #define __WDT_OSC_CLK (2600000 / __DIVSEL)
+ #elif (__FREQSEL == 11)
+ #define __WDT_OSC_CLK (2700000 / __DIVSEL)
+ #elif (__FREQSEL == 12)
+ #define __WDT_OSC_CLK (2900000 / __DIVSEL)
+ #elif (__FREQSEL == 13)
+ #define __WDT_OSC_CLK (3100000 / __DIVSEL)
+ #elif (__FREQSEL == 14)
+ #define __WDT_OSC_CLK (3200000 / __DIVSEL)
+ #else
+ #define __WDT_OSC_CLK (3400000 / __DIVSEL)
+ #endif
+ #else
+ #define __WDT_OSC_CLK (1600000 / 2)
+ #endif // WDTOSC_SETUP
+
+ /* sys_pllclkin calculation */
+ #if ((SYSPLLCLKSEL_Val & 0x03) == 0)
+ #define __SYS_PLLCLKIN (__IRC_OSC_CLK)
+ #elif ((SYSPLLCLKSEL_Val & 0x03) == 1)
+ #define __SYS_PLLCLKIN (__SYS_OSC_CLK)
+ #elif ((SYSPLLCLKSEL_Val & 0x03) == 2)
+ #define __SYS_PLLCLKIN (__WDT_OSC_CLK)
+ #else
+ #define __SYS_PLLCLKIN (0)
+ #endif
+
+ #if (SYSPLL_SETUP) /* System PLL Setup */
+ #define __SYS_PLLCLKOUT (__SYS_PLLCLKIN * ((SYSPLLCTRL_Val & 0x01F) + 1))
+ #else
+ #define __SYS_PLLCLKOUT (__SYS_PLLCLKIN * (1))
+ #endif // SYSPLL_SETUP
+
+ /* main clock calculation */
+ #if ((MAINCLKSEL_Val & 0x03) == 0)
+ #define __MAIN_CLOCK (__IRC_OSC_CLK)
+ #elif ((MAINCLKSEL_Val & 0x03) == 1)
+ #define __MAIN_CLOCK (__SYS_PLLCLKIN)
+ #elif ((MAINCLKSEL_Val & 0x03) == 2)
+ #define __MAIN_CLOCK (__WDT_OSC_CLK)
+ #elif ((MAINCLKSEL_Val & 0x03) == 3)
+ #define __MAIN_CLOCK (__SYS_PLLCLKOUT)
+ #else
+ #define __MAIN_CLOCK (0)
+ #endif
+
+ #define __SYSTEM_CLOCK (__MAIN_CLOCK / SYSAHBCLKDIV_Val)
+
+ #else // SYSCLK_SETUP
+ #if (SYSAHBCLKDIV_Val == 0)
+ #define __SYSTEM_CLOCK (0)
+ #else
+ #define __SYSTEM_CLOCK (__XTAL / SYSAHBCLKDIV_Val)
+ #endif
+ #endif // SYSCLK_SETUP
+
+#else
+ #define __SYSTEM_CLOCK (__XTAL)
+#endif // CLOCK_SETUP
+
+
+/*----------------------------------------------------------------------------
+ Clock Variable definitions
+ *----------------------------------------------------------------------------*/
+uint32_t SystemCoreClock = __SYSTEM_CLOCK;/*!< System Clock Frequency (Core Clock)*/
+
+
+/*----------------------------------------------------------------------------
+ Clock functions
+ *----------------------------------------------------------------------------*/
+void SystemCoreClockUpdate (void) /* Get Core Clock Frequency */
+{
+ uint32_t wdt_osc = 0;
+
+ /* Determine clock frequency according to clock register values */
+ switch ((LPC_SYSCON->WDTOSCCTRL >> 5) & 0x0F) {
+ case 0: wdt_osc = 400000; break;
+ case 1: wdt_osc = 500000; break;
+ case 2: wdt_osc = 800000; break;
+ case 3: wdt_osc = 1100000; break;
+ case 4: wdt_osc = 1400000; break;
+ case 5: wdt_osc = 1600000; break;
+ case 6: wdt_osc = 1800000; break;
+ case 7: wdt_osc = 2000000; break;
+ case 8: wdt_osc = 2200000; break;
+ case 9: wdt_osc = 2400000; break;
+ case 10: wdt_osc = 2600000; break;
+ case 11: wdt_osc = 2700000; break;
+ case 12: wdt_osc = 2900000; break;
+ case 13: wdt_osc = 3100000; break;
+ case 14: wdt_osc = 3200000; break;
+ case 15: wdt_osc = 3400000; break;
+ }
+ wdt_osc /= ((LPC_SYSCON->WDTOSCCTRL & 0x1F) << 1) + 2;
+
+ switch (LPC_SYSCON->MAINCLKSEL & 0x03) {
+ case 0: /* Internal RC oscillator */
+ SystemCoreClock = __IRC_OSC_CLK;
+ break;
+ case 1: /* Input Clock to System PLL */
+ switch (LPC_SYSCON->SYSPLLCLKSEL & 0x03) {
+ case 0: /* Internal RC oscillator */
+ SystemCoreClock = __IRC_OSC_CLK;
+ break;
+ case 1: /* System oscillator */
+ SystemCoreClock = __SYS_OSC_CLK;
+ break;
+ case 2: /* WDT Oscillator */
+ SystemCoreClock = wdt_osc;
+ break;
+ case 3: /* Reserved */
+ SystemCoreClock = 0;
+ break;
+ }
+ break;
+ case 2: /* WDT Oscillator */
+ SystemCoreClock = wdt_osc;
+ break;
+ case 3: /* System PLL Clock Out */
+ switch (LPC_SYSCON->SYSPLLCLKSEL & 0x03) {
+ case 0: /* Internal RC oscillator */
+ if (LPC_SYSCON->SYSPLLCTRL & 0x180) {
+ SystemCoreClock = __IRC_OSC_CLK;
+ } else {
+ SystemCoreClock = __IRC_OSC_CLK * ((LPC_SYSCON->SYSPLLCTRL & 0x01F) + 1);
+ }
+ break;
+ case 1: /* System oscillator */
+ if (LPC_SYSCON->SYSPLLCTRL & 0x180) {
+ SystemCoreClock = __SYS_OSC_CLK;
+ } else {
+ SystemCoreClock = __SYS_OSC_CLK * ((LPC_SYSCON->SYSPLLCTRL & 0x01F) + 1);
+ }
+ break;
+ case 2: /* WDT Oscillator */
+ if (LPC_SYSCON->SYSPLLCTRL & 0x180) {
+ SystemCoreClock = wdt_osc;
+ } else {
+ SystemCoreClock = wdt_osc * ((LPC_SYSCON->SYSPLLCTRL & 0x01F) + 1);
+ }
+ break;
+ case 3: /* Reserved */
+ SystemCoreClock = 0;
+ break;
+ }
+ break;
+ }
+
+ SystemCoreClock /= LPC_SYSCON->SYSAHBCLKDIV;
+
+}
+
+/**
+ * Initialize the system
+ *
+ * @param none
+ * @return none
+ *
+ * @brief Setup the microcontroller system.
+ * Initialize the System.
+ */
+void SystemInit (void)
+{
+#if (CLOCK_SETUP) /* Clock Setup */
+#if (SYSCLK_SETUP) /* System Clock Setup */
+#if (SYSOSC_SETUP) /* System Oscillator Setup */
+ uint32_t i;
+
+ LPC_SYSCON->PDRUNCFG &= ~(1 << 5); /* Power-up System Osc */
+ LPC_SYSCON->SYSOSCCTRL = SYSOSCCTRL_Val;
+ for (i = 0; i < 200; i++) __NOP();
+ LPC_SYSCON->SYSPLLCLKSEL = SYSPLLCLKSEL_Val; /* Select PLL Input */
+ LPC_SYSCON->SYSPLLCLKUEN = 0x01; /* Update Clock Source */
+ LPC_SYSCON->SYSPLLCLKUEN = 0x00; /* Toggle Update Register */
+ LPC_SYSCON->SYSPLLCLKUEN = 0x01;
+ while (!(LPC_SYSCON->SYSPLLCLKUEN & 0x01)); /* Wait Until Updated */
+#if (SYSPLL_SETUP) /* System PLL Setup */
+ LPC_SYSCON->SYSPLLCTRL = SYSPLLCTRL_Val;
+ LPC_SYSCON->PDRUNCFG &= ~(1 << 7); /* Power-up SYSPLL */
+ while (!(LPC_SYSCON->SYSPLLSTAT & 0x01)); /* Wait Until PLL Locked */
+#endif
+#endif
+#if (WDTOSC_SETUP) /* Watchdog Oscillator Setup*/
+ LPC_SYSCON->WDTOSCCTRL = WDTOSCCTRL_Val;
+ LPC_SYSCON->PDRUNCFG &= ~(1 << 6); /* Power-up WDT Clock */
+#endif
+ LPC_SYSCON->MAINCLKSEL = MAINCLKSEL_Val; /* Select PLL Clock Output */
+ LPC_SYSCON->MAINCLKUEN = 0x01; /* Update MCLK Clock Source */
+ LPC_SYSCON->MAINCLKUEN = 0x00; /* Toggle Update Register */
+ LPC_SYSCON->MAINCLKUEN = 0x01;
+ while (!(LPC_SYSCON->MAINCLKUEN & 0x01)); /* Wait Until Updated */
+#endif
+
+ LPC_SYSCON->SYSAHBCLKDIV = SYSAHBCLKDIV_Val;
+ LPC_SYSCON->SYSAHBCLKCTRL = AHBCLKCTRL_Val;
+ LPC_SYSCON->SSP0CLKDIV = SSP0CLKDIV_Val;
+ LPC_SYSCON->UARTCLKDIV = UARTCLKDIV_Val;
+ LPC_SYSCON->SSP1CLKDIV = SSP1CLKDIV_Val;
+#endif
+
+
+#if (MEMMAP_SETUP || MEMMAP_INIT) /* Memory Mapping Setup */
+ LPC_SYSCON->SYSMEMREMAP = SYSMEMREMAP_Val;
+#endif
+}
diff --git a/src/core/system_LPC11xx.h b/src/core/system_LPC11xx.h
new file mode 100755
index 0000000..385fe38
--- /dev/null
+++ b/src/core/system_LPC11xx.h
@@ -0,0 +1,64 @@
+/**************************************************************************//**
+ * @file system_LPC11xx.h
+ * @brief CMSIS Cortex-M0 Device Peripheral Access Layer Header File
+ * for the NXP LPC11xx Device Series
+ * @version V1.00
+ * @date 17. November 2009
+ *
+ * @note
+ * Copyright (C) 2009 ARM Limited. All rights reserved.
+ *
+ * @par
+ * ARM Limited (ARM) is supplying this software for use with Cortex-M
+ * processor based microcontrollers. This file can be freely distributed
+ * within development tools that are supporting such ARM based processors.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
+ * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
+ * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
+ * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
+ *
+ ******************************************************************************/
+
+
+#ifndef __SYSTEM_LPC11xx_H
+#define __SYSTEM_LPC11xx_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */
+
+
+/**
+ * Initialize the system
+ *
+ * @param none
+ * @return none
+ *
+ * @brief Setup the microcontroller system.
+ * Initialize the System and update the SystemCoreClock variable.
+ */
+extern void SystemInit (void);
+
+/**
+ * Update SystemCoreClock variable
+ *
+ * @param none
+ * @return none
+ *
+ * @brief Updates the SystemCoreClock with current core Clock
+ * retrieved from cpu registers.
+ */
+extern void SystemCoreClockUpdate (void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __SYSTEM_LPC11x_H */
diff --git a/src/core/uart.cpp b/src/core/uart.cpp
new file mode 100755
index 0000000..ea61c3c
--- /dev/null
+++ b/src/core/uart.cpp
@@ -0,0 +1,206 @@
+/*
+ * uart.cpp
+ *
+ * Created on: 2011/07/30
+ * Author: lynxeyed
+ */
+
+#include <string.h>
+#include "LPC11xx.h"
+#include "uart.h"
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+ // Flag mask for UART_LSR register.
+const unsigned long LSR_TEMT = 0x40;
+const unsigned long LSR_THRE = 0x20;
+const unsigned long LSR_RDR = 0x01;
+const unsigned long ACR_START = 0x01;
+const unsigned long IER_RLS = 0x04;
+const unsigned long IER_RBR = 0x01;
+
+USerial Serial;
+
+USerial::USerial()//USerial(SERIAL_PORT port) //define constructor
+{
+ this->port = marySerial1; //default = marySerial1
+ format = OCT;
+ speed = 9600; //baudrate
+ //begin(speed);
+}
+
+USerial::~USerial()
+{
+
+}
+
+void USerial::begin(int speed)
+{
+ this->speed = speed;
+ // Divisor ratio
+ unsigned long Fdiv;
+
+ // Configure P1[7] as TXD output.
+ LPC_IOCON->PIO1_7 &= ~0x07; // FUNC=000 (GPIO)
+ LPC_IOCON->PIO1_7 |= 0x01; // FUNC=001 (TXD)
+
+ // Configure P1[6] as RXD input.
+ LPC_IOCON->PIO1_6 &= ~0x07; // FUNC=000 (GPIO)
+ LPC_IOCON->PIO1_6 |= 0x01; // FUNC=001 (RXD)
+
+ // Enable UART clock
+ LPC_SYSCON->SYSAHBCLKCTRL |= (1<<12); // UART=1
+
+ // Enable UART peripheral clock
+ LPC_SYSCON->UARTCLKDIV = 0x01; // DIV=1
+
+ // fix baud-rate
+ Fdiv = (SystemCoreClock * LPC_SYSCON->SYSAHBCLKDIV) / (LPC_SYSCON->UARTCLKDIV * 16 * speed);
+
+ // Set the baud rate divisor value
+ LPC_UART->LCR |= 0x80;
+ LPC_UART->DLM = Fdiv / 256;
+ LPC_UART->DLL = Fdiv % 256;
+ LPC_UART->LCR &= ~0x80;
+
+ // Configure UART module as
+ // 8 bit, 1 stop bit, no parity
+ // Enable and reset TX and RX FIFO.
+ LPC_UART->LCR = 0x03;
+ LPC_UART->FCR = 0x07;
+
+}
+
+void USerial::end()
+{
+ return;
+}
+
+void USerial::write(const char c) //uart_putc
+{
+ // Wait for TX buffer empty
+ while (!(LPC_UART->LSR & LSR_THRE));
+ // Put a character
+ LPC_UART->THR = c;
+ return;
+}
+
+void USerial::print(const char *s) //uart_puts
+{
+ int n;
+ for (n = 0; *s; s++, n++) {
+ write(*s);
+ }
+ //return n;
+ return;
+}
+
+void USerial::print(int val, RADIX_FORMAT format)
+{
+ if(format == BYTE)
+ {
+ write((char)(val & 0xff));
+ return;
+ }
+ char s[32];
+ int i,j;
+ i=j=0; // header of strings
+ if (val<0)
+ { //minus value
+ s[i]='-';
+ val=~val+1;
+ i++;
+ j++;
+ }
+ switch(format)
+ {
+ case BIN:
+ while (val>0)
+ { // do until zero
+ s[i++]=radix_bin[val%format];
+ val/=format;
+ }
+ break;
+
+ case OCT:
+ while (val>0)
+ { // do until zero
+ s[i++]=radix_oct[val%format];
+ val/=format;
+ }
+ break;
+
+ case DEC: //RADIX = Decimal
+ while (val>0)
+ { // do until zero
+ s[i++]=radix_dec[val%format];
+ val/=format;
+ }
+ break;
+
+ case HEX: //RADIX = Hexadecimal
+ while (val>0)
+ { // do until zero
+ s[i++]=radix_hex[val%format];
+ val/=format;
+ }
+ break;
+ default:
+ break;
+ }
+ s[i--]='\0'; // EOF
+ while (j<i)
+ { // reverse strings array
+ char t;
+ t=s[j]; s[j]=s[i]; s[i]=t;
+ j++; i--;
+ }
+ print(s);
+
+ return ;
+}
+
+void USerial::write(const char *s, int length)
+{
+ int n;
+ for(n=0;n<length;s++,n++)
+ {
+ write(*s);
+ }
+ return;
+}
+
+void USerial::println(const char *s)
+{
+ print(s);
+ write ('\r');
+ write ('\n');
+ return;
+}
+
+
+void USerial::println(int val, RADIX_FORMAT format)
+{
+ print(val,format);
+ write ('\r');
+ write ('\n');
+ return;
+}
+
+int USerial::available(void)
+{
+ return (LPC_UART->LSR & LSR_RDR);
+}
+
+int USerial::read(void)
+{
+ // Wait for RX buffer valid
+ //while (!(LPC_UART->LSR & LSR_RDR));
+ return LPC_UART->RBR;
+}
+
+#ifdef __cplusplus
+} //extern "C"
+#endif
diff --git a/src/core/uart.h b/src/core/uart.h
new file mode 100755
index 0000000..c7e5125
--- /dev/null
+++ b/src/core/uart.h
@@ -0,0 +1,90 @@
+#ifndef UART_H_
+#define UART_H_
+
+/**************************************************************************//**
+ * @file uart.h
+ * @brief Arduino-like library for MARY(LPC1114)
+ * @version v.0.50
+ * @date 1. August 2011.
+ * @author @@lynxeyed_atsu
+ * @note Copyright (c) 2011 Lynx-EyED's Klavier and Craft-works. <BR>
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions: <BR>
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.<BR>
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ******************************************************************************/
+
+#include "LPC11xx.h"
+#ifdef __cplusplus
+ extern "C" {
+#endif
+const char radix_bin[]="01";
+const char radix_oct[]="01234567";
+const char radix_dec[]="0123456789";
+const char radix_hex[]="0123456789ABCDEF";
+
+/*! @enum SERIAL_PORT
+ @brief COMポート(UART)のチャンネル選択。
+ @note UARTが1ポートしかないMARYでは使用していないので特に影響はないが、2ポート以上UARTが存在するLPCXpressoシリーズや
+ mbedシリーズとの後方互換性を考慮し用意している
+*/
+typedef enum {
+ marySerial1, /*!< MARYのUARTポート(デフォルト) */
+ mbedSerial1, /*!< mbed(LPC1768/9)のUART1ポート(将来的に対応予定) */
+ mbedSerial2 /*!< mbed(LPC1768/9)のUART2ポート(将来的に対応予定) */
+} SERIAL_PORT; // Defaults:marySerial1
+
+/*! @enum SERIAL_FORMAT
+ @brief Arduinoのprint(data, format)の第二パラメータ(format)の基数。
+*/
+typedef enum {
+ BYTE = 0x01, /*!< 1バイトのアスキーコードが表示される */
+ BIN = 0x02, /*!< dataで与えられた数値を2進数で表示する */
+ OCT = 0x08, /*!< dataで与えられた数値を8進数で表示する */
+ DEC = 0x0A, /*!< dataで与えられた数値を10進数で表示する */
+ HEX = 0x10 /*!< dataで与えられた数値を16進数で表示する */
+} RADIX_FORMAT;
+
+
+class USerial {
+private:
+ SERIAL_PORT port;
+ RADIX_FORMAT format;
+ int speed;
+
+public:
+ USerial();//USerial(SERIAL_PORT port); // announce the constructor to initialize
+ ~USerial();
+
+ void begin(int speed);
+ void end() ;
+ void print(const char *s);
+ void print(int val, RADIX_FORMAT format);
+ void println(const char *s);
+ void println(int val, RADIX_FORMAT format) ;
+ int read(void);
+ int available(void);
+ void write(const char c);
+ void write(const char *s,int length);
+};
+
+
+extern USerial Serial;
+
+#ifdef __cplusplus
+ }
+#endif
+
+
+#endif /* UART_H_ */
diff --git a/src/user_application.cpp b/src/user_application.cpp
new file mode 100755
index 0000000..c8656fd
--- /dev/null
+++ b/src/user_application.cpp
@@ -0,0 +1,52 @@
+#include <libmary.h>
+#include <stdlib.h>
+#include <SPI1.h>
+
+#define S9706_GATE 6 //Low->High:光量の積算。S9706の6番->(D6に接続)
+#define S9706_RANGE P0_1 //受光感度調整。S9706の4番->(P0_1)に接続。
+
+// PIO2_1 : SCLK -> S9706の5番(CK)
+// PIO2_2 : MISO -> S9706の1番(Dout)
+
+void setup()
+{
+ pinMode(S9706_GATE,OUTPUT);
+ pinMode(S9706_RANGE,OUTPUT);
+ Serial.begin(9600);
+ SPI1.setBitLength(12); //12bit ADC
+ SPI1.setDataMode(SPI_MODE2);
+ SPI1.begin();
+ Serial.println("Start");
+}
+
+int r,g,b;
+
+void loop()
+{
+ digitalWrite(S9706_GATE,LOW);
+ digitalWrite(S9706_RANGE,HIGH);
+
+ Serial.println("積算を開始");
+ digitalWrite(S9706_GATE,HIGH);
+ delay(4);
+
+
+ Serial.println("積算を終了");
+ Serial.println("データリード開始");
+
+ digitalWrite(S9706_GATE,LOW);
+
+ r = SPI1.transfer(0xfff);
+ g = SPI1.transfer(0xfff);
+ b = SPI1.transfer(0xfff);
+
+ Serial.print("r = ");
+ Serial.println(r,DEC);
+ Serial.print("g = ");
+ Serial.println(g,DEC);
+ Serial.print("b = ");
+ Serial.println(b,DEC);
+
+ delay(1000);
+
+}