RFID tracking with mbed & RS-EDP reference design

Dependencies:   RWDModule mbed SDCard

Files at this revision

API Documentation at this revision

Comitter:
donatien
Date:
Wed Jul 28 11:02:36 2010 +0000
Commit message:

Changed in this revision

Config_Common.h Show annotated file Show diff for this revision Revisions of this file
Config_Impl.h Show annotated file Show diff for this revision Revisions of this file
Ethernet.cpp Show annotated file Show diff for this revision Revisions of this file
EthernetNetIf.lib Show annotated file Show diff for this revision Revisions of this file
FATFileSystem.lib Show annotated file Show diff for this revision Revisions of this file
MySQLClient.lib Show annotated file Show diff for this revision Revisions of this file
NTPClient.lib Show annotated file Show diff for this revision Revisions of this file
README.h Show annotated file Show diff for this revision Revisions of this file
RWDModule.lib Show annotated file Show diff for this revision Revisions of this file
SDCard.lib Show annotated file Show diff for this revision Revisions of this file
fs.cpp Show annotated file Show diff for this revision Revisions of this file
log/logger.cpp Show annotated file Show diff for this revision Revisions of this file
log/logger.h Show annotated file Show diff for this revision Revisions of this file
log/loginfo.h Show annotated file Show diff for this revision Revisions of this file
log/queue.h Show annotated file Show diff for this revision Revisions of this file
log/taginfo.cpp Show annotated file Show diff for this revision Revisions of this file
log/taginfo.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
mifare/RWDMifare.cpp Show annotated file Show diff for this revision Revisions of this file
mifare/RWDMifare.h Show annotated file Show diff for this revision Revisions of this file
ui/beep.cpp Show annotated file Show diff for this revision Revisions of this file
ui/beep.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Config_Common.h	Wed Jul 28 11:02:36 2010 +0000
@@ -0,0 +1,46 @@
+/*
+Copyright (c) 2010 ARM Limited
+
+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:
+ 
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+ 
+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.
+*/
+
+/*
+Setup global parameters here:
+- Log file
+- NTP server
+- SQL server
+*/
+
+#ifndef CONFIG_COMMON_H
+#define CONFIG_COMMON_H
+
+#define LOG_FILE     "/sd/rs_log.txt"
+
+#define NTP_SERVER   "0.uk.pool.ntp.org"
+
+#define SQL_SERVER_IP IpAddr(1,2,3,4)
+#define SQL_SERVER   ""
+#define SQL_USER     "user"
+#define SQL_PASSWORD "********"
+#define SQL_DB       "test"
+#define SQL_TABLE    "locations"
+
+#define TIME_ZONE    1 //BST is UTC + 1
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Config_Impl.h	Wed Jul 28 11:02:36 2010 +0000
@@ -0,0 +1,34 @@
+/*
+Copyright (c) 2010 ARM Limited
+
+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:
+ 
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+ 
+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.
+*/
+
+/*
+BB3-specific configuration.
+*/
+
+#ifndef CONFIG_IMPL_H
+#define CONFIG_IMPL_H
+
+#define SDCARD    1
+
+#define LOCATION_ID  3
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Ethernet.cpp	Wed Jul 28 11:02:36 2010 +0000
@@ -0,0 +1,60 @@
+/*
+Copyright (c) 2010 ARM Limited
+
+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:
+ 
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+ 
+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.
+*/
+
+/*
+Initialization and closing routines for Ethernet interface, and program entry point.
+*/
+
+//Core libs
+#include "mbed.h"
+
+//Network
+#include "EthernetNetIf.h"
+
+EthernetNetIf eth; 
+
+int network_init()
+{
+  while(1)
+  {
+    printf("Start\n");
+
+    EthernetErr ethErr = eth.setup();
+    if(ethErr)
+    {
+      printf("\r\nCould not connect... trying again!\r\n");
+      continue;
+    }
+    break;
+  }
+  
+  IpAddr myIp = eth.getIp();
+
+  printf("Ip Address: %d.%d.%d.%d\n", myIp[0], myIp[1], myIp[2], myIp[3]);
+
+  return 0;
+}
+
+int network_close()
+{
+  return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EthernetNetIf.lib	Wed Jul 28 11:02:36 2010 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/donatien/code/EthernetNetIf/#bc7df6da7589
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FATFileSystem.lib	Wed Jul 28 11:02:36 2010 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_unsupported/code/fatfilesystem/
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MySQLClient.lib	Wed Jul 28 11:02:36 2010 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/donatien/code/MySQLClient/#91c24a06d12c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/NTPClient.lib	Wed Jul 28 11:02:36 2010 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/donatien/code/NTPClient/#7c3f1199256a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/README.h	Wed Jul 28 11:02:36 2010 +0000
@@ -0,0 +1,61 @@
+/*
+
+This is the main program for the RFID Tracking reference design.
+
+-log/
+-----logger.h
+-----logger.cpp
+The logger is responsible for writing data in the CSV file and queueing
+SQL requests and executing them on the SQL server
+using a MySQL client instance.
+
+-----loginfo.h
+This is a generic interface for a data container to be used with the
+logger class.
+
+-----taginfo.h
+-----taginfo.cpp
+This class is a data container for each event's info (tag id, item
+location, timestamp).
+It derives from LogInfo.
+Some methods are available to format this data into CSVs and SQL
+instructions.
+
+-mifare/
+--------RWDMifare.h
+--------RWDMifare.cpp
+This is a specific and quick implementation for the Mifare MicroRWD
+modules.
+The class configures the reader for Mifare operation and can poll for
+UIDs
+
+-ui/
+----beep.h
+----beep.cpp
+This class provides beeping using different tones.
+
+-Config_Common.h
+Setup global parameters here:
+- Log file
+- NTP server
+- SQL server
+
+-main.cpp
+This is the main file for this project.
+
+** Ethernet-specific files **
+
+This is the Ethernet version of the RFID Tracking reference design.
+
+-Config_Impl.h
+BB3-specific configuration.
+
+-Ethernet.cpp
+Initialization and closing routines for Ethernet interface, and program entry point.
+
+** SD Card support **
+
+-fs.cpp
+Setup the SD Filesystem.
+
+*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/RWDModule.lib	Wed Jul 28 11:02:36 2010 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/donatien/code/RWDModule/#0c21bc193afa
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SDCard.lib	Wed Jul 28 11:02:36 2010 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/chris/code/SDCard/#fc0e38551beb
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/fs.cpp	Wed Jul 28 11:02:36 2010 +0000
@@ -0,0 +1,28 @@
+/*
+Copyright (c) 2010 ARM Limited
+
+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:
+ 
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+ 
+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.
+*/
+
+/*
+Setup the SD Filesystem.
+*/
+
+#include "SDFileSystem.h"
+SDFileSystem sd(p5, p6, p7, p8, "sd"); //p9: SD present; p8: CS
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/log/logger.cpp	Wed Jul 28 11:02:36 2010 +0000
@@ -0,0 +1,174 @@
+/*
+Copyright (c) 2010 ARM Limited
+
+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:
+ 
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+ 
+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 "mbed.h"
+#include "logger.h"
+
+#include "MySQLClient.h"
+
+#define MAX_ELEMENTS_IN_QUEUE 50
+
+
+Logger::Logger(const string& table) : m_lSQLReq(MAX_ELEMENTS_IN_QUEUE), m_fd(NULL), m_sqlClient(), m_sqlLastResult(MYSQL_PROCESSING), 
+m_sqlConnecting(false), m_sqlConnected(false), m_sqlConnectionError(false), m_sqlCommand(false)
+{
+  m_table = table;
+}
+
+Logger::~Logger()
+{
+
+}
+
+//Open file for logging
+int Logger::fileOpen(const char* filename)
+{
+  if(m_fd)
+    return -1; //File already opened
+  m_fd = fopen(filename, "a");
+  if(!m_fd) //Try again in "w" mode (creates the file if not existent)
+    m_fd = fopen(filename, "w");
+  if(!m_fd)
+    return -1; //Could not open file
+  return 0;
+}
+
+//Close log file
+int Logger::fileClose()
+{
+  if(!m_fd)
+    return -1; //Nothing to close
+  fclose(m_fd);
+  m_fd = NULL;
+  return 0;
+}
+
+//Try to connect to server
+int Logger::sqlOpen(Host& host, const string& user, const string& password, const string& db)
+{
+  m_sqlClient.open(host, user, password, db, this, &Logger::onMySQLResult); //Non blocking
+  //The onMySQLResult() method will be called on result of this command
+  m_sqlConnecting = true;
+  m_sqlConnectionError = false;
+  return 0;
+}
+  
+//Close server connection
+int Logger::sqlClose()
+{
+  m_sqlClient.exit();
+  m_sqlConnected = false;
+  return 0;
+}
+  
+//Log some data
+int Logger::log(LogInfo* pInfo) //Returns 0 on success, -1 on failure
+{
+
+  if(m_fd) //If file is open, append record to file in CSV format
+  {
+    fputs(pInfo->toCSV().c_str(), m_fd);
+    fputs("\r\n", m_fd); //Append new line
+  }
+  if(m_lSQLReq.size()<MAX_ELEMENTS_IN_QUEUE) //Check if there is (arbitrary) space in queue
+  {
+    m_lSQLReq.push(pInfo->toSQL(m_table)); //Put record in queue for next network push
+    return 0; //Request queued
+  }
+  else
+  {
+    return -1; //Error
+  }
+}
+
+void Logger::service()
+{
+  Net::poll(); //Poll Networking stack
+  if(m_sqlConnected) //Are we connected to the server?
+  {
+    //Can serve SQL requests
+    if(m_sqlCommand && m_sqlLastResult!=MYSQL_PROCESSING) //Previous command completed?
+    {
+      if(m_sqlLastResult==MYSQL_OK) //Has previous command completed with success?
+      {
+        if(!m_lSQLReq.empty())
+        {
+          m_lSQLReq.pop(); //Ok, we can dequeue previous element
+        } 
+      }
+      m_sqlCommand = false; //No command being executed
+    }
+    if(!m_sqlCommand) //Ready for a command?
+    {
+      if(!m_lSQLReq.empty()) //Anything in the queue?
+      {
+        //Execute the next SQL request
+        m_sqlLastResult = m_sqlClient.sql(m_lSQLReq.front()); //MYSQL_PROCESSING
+        m_sqlCommand = true;
+      }
+    }
+  }
+}
+
+bool Logger::isEmpty()
+{
+  return m_lSQLReq.empty();
+}
+
+bool Logger::isConnecting()
+{
+  return m_sqlConnecting;
+}
+
+bool Logger::isConnected()
+{
+  return m_sqlConnected;
+}
+
+bool Logger::connectionError()
+{
+  return m_sqlConnectionError;
+}
+
+MySQLResult Logger::getLastResult() //Returns last command's result
+{
+  return m_sqlLastResult;
+}
+
+void Logger::onMySQLResult(MySQLResult r) //Callback from MySQL client
+{
+  //Update status
+  m_sqlLastResult = r;
+  if(m_sqlConnecting) //Check if we're connecting, if so this result is the result of the connection
+  {
+    m_sqlConnected = (r==0)?true:false; //If no error, we're connected
+    m_sqlConnecting = false;
+    if(r!=0)
+      m_sqlConnectionError = true; //Else there was an error during connection
+  }
+  if( (r==MYSQL_DNS) || (r==MYSQL_PRTCL) || (r==MYSQL_AUTHFAILED) || (r==MYSQL_TIMEOUT) || (r==MYSQL_CONN) ) //Was this a fatal error?
+  {
+    //Connection has been closed, we must reconnect
+    m_sqlConnected = false;
+    m_sqlConnectionError = true;
+  }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/log/logger.h	Wed Jul 28 11:02:36 2010 +0000
@@ -0,0 +1,91 @@
+/*
+Copyright (c) 2010 ARM Limited
+
+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:
+ 
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+ 
+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.
+*/
+
+#ifndef LOGGER_H
+#define LOGGER_H
+
+#include "MySQLClient.h"
+
+#include "queue.h"
+
+#include <string>
+using std::string;
+
+#include "mbed.h"
+
+#include "loginfo.h"
+
+/*
+The logger is responsible for writing data in the CSV file and queueing SQL requests and executing them on the SQL server using a MySQL client instance.
+*/
+class Logger
+{
+public:
+  Logger(const string& table);
+  ~Logger();
+  
+  //File Logging
+  int fileOpen(const char* filename);
+  int fileClose();
+  
+  //SQL Logging
+  int sqlOpen(Host& host, const string& user, const string& password, const string& db);
+  int sqlClose();
+  
+  //Log an event
+  int log(LogInfo* pInfo); //Returns 0 on success, -1 on failure
+  
+  //Main service routine, must be called regularly
+  void service();
+  
+  //Checks if requests queue is empty
+  bool isEmpty();
+
+  //Status info about SQL connection
+  bool isConnecting();    
+  bool isConnected();  
+  bool connectionError();
+  
+  MySQLResult getLastResult();
+  
+protected:
+  //Callback from MySQL client
+  void onMySQLResult(MySQLResult r);
+
+private:
+  mbed::queue<string> m_lSQLReq;
+  FILE* m_fd;
+  
+  string m_table;
+  
+ // Timer m_reqTimer;
+  MySQLClient m_sqlClient;
+  MySQLResult m_sqlLastResult;
+  
+  bool m_sqlConnecting;
+  bool m_sqlConnected;
+  bool m_sqlConnectionError;
+  bool m_sqlCommand;
+
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/log/loginfo.h	Wed Jul 28 11:02:36 2010 +0000
@@ -0,0 +1,42 @@
+/*
+Copyright (c) 2010 ARM Limited
+
+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:
+ 
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+ 
+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.
+*/
+
+/*
+This is a generic interface for a data container to be used with the logger class.
+*/
+
+#ifndef LOGINFO_H
+#define LOGINFO_H
+
+#include <string>
+using std::string;
+
+class LogInfo
+{
+public:
+  LogInfo() {}
+  virtual ~LogInfo() {}
+  virtual string toCSV() const = 0;
+  virtual string toSQL(const string& table) const = 0;
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/log/queue.h	Wed Jul 28 11:02:36 2010 +0000
@@ -0,0 +1,104 @@
+/*
+Copyright (c) 2010 ARM Limited
+
+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:
+ 
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+ 
+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.
+*/
+
+/*
+This is a generic queue implementation to avoid using std::queue.
+*/
+
+
+#ifndef QUEUE_H
+#define QUEUE_H
+
+#include "string.h" //For size_t
+
+namespace mbed {
+
+template<class T>
+class queue
+{
+public:
+  queue(const size_t size) : m_size(size+1)
+  {
+    m_table = new T*[size + 1];
+    m_backPos = m_frontPos = 0;
+  }
+  
+  ~queue()
+  {
+    delete[] m_table;
+  }
+  
+  void push(const T& item)
+  {
+    if(size() >= (m_size - 1))
+      return;
+    m_table[m_backPos] = new T(item);
+    m_backPos++;
+    if(m_backPos>=m_size)
+      m_backPos = 0;
+  }
+  
+  void pop()
+  {
+    if(empty())
+      return;
+    delete m_table[m_frontPos];
+    m_frontPos++;
+    if(m_frontPos>=m_size)
+      m_frontPos = 0;
+  }
+  
+  T& front()
+  {
+    return *m_table[m_frontPos];  
+  }
+  
+  T& back()
+  {
+    return *m_table[m_backPos];
+  }
+  
+  size_t size() const
+  {
+    if(m_backPos >= m_frontPos)
+      return (m_backPos - m_frontPos);
+    else
+      return m_size - (m_frontPos - m_backPos);
+  }
+  
+  bool empty() const
+  {
+    return !size();
+  }
+  
+private:
+  T** m_table;
+  uint32_t m_frontPos; //Position of front element
+  uint32_t m_backPos; //Position of last element
+  
+  size_t m_size;
+  
+};
+
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/log/taginfo.cpp	Wed Jul 28 11:02:36 2010 +0000
@@ -0,0 +1,61 @@
+/*
+Copyright (c) 2010 ARM Limited
+
+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:
+ 
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+ 
+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 "taginfo.h"
+#include <stdio.h>
+
+TagInfo::TagInfo(const uint8_t* id, size_t idLen, int locationId, time_t timestamp) : LogInfo(), m_locationId(locationId), m_timestamp(timestamp)
+{
+  m_idStr = new char[2*idLen+1]; //Each byte is coded on two chars, plus one 0-terminating char
+  char* p = m_idStr; //Copy ID in a c-string format
+  for(int i = 0; i < idLen; i++)
+  {
+    sprintf(p, "%02x", id[i]);
+    p+=2;
+  }
+}
+
+TagInfo::~TagInfo()
+{
+  delete[] m_idStr;
+}
+
+string TagInfo::toCSV() const
+{
+  char str[64] = {0};
+  sprintf(str, "'%s',%d,%d", m_idStr, m_locationId, m_timestamp); //Format info into CSVs
+  return string(str);
+}
+
+string TagInfo::toSQL(const string& table) const
+{
+  char cmd[128] = {0};
+  char time_str[32] = {0};
+  
+  struct tm* timeinfo = localtime ( &m_timestamp );
+  
+  strftime(time_str, 32, "%Y-%m-%d %H:%M:%S", timeinfo);
+    
+  sprintf(cmd, "INSERT INTO %s (TagId, LastLocationId, Timestamp) VALUES('%s',%d,'%s')", table.c_str(), m_idStr, m_locationId, time_str); //Create SQL instruction to be executed by MySQL client
+
+  return string(cmd);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/log/taginfo.h	Wed Jul 28 11:02:36 2010 +0000
@@ -0,0 +1,59 @@
+/*
+Copyright (c) 2010 ARM Limited
+
+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:
+ 
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+ 
+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.
+*/
+
+#ifndef TAGINFO_H
+#define TAGINFO_H
+
+#include "loginfo.h"
+
+#include <ctime> //For time_t type
+
+#include <string>
+using std::string;
+
+#include <time.h>
+
+#include <stdint.h>
+#include <string.h> //For size_t
+
+/*
+This class is a data container for each event's info (tag id, item location, timestamp).
+It derives from LogInfo.
+Some methods are available to format this data into CSVs and SQL instructions.
+*/
+
+class TagInfo : public LogInfo
+{
+public:
+  TagInfo(const uint8_t* id, size_t idLen, int locationId, time_t timestamp);
+  virtual ~TagInfo();
+
+  virtual string toCSV() const;
+  virtual string toSQL(const string& table) const;
+  
+private:
+  char* m_idStr;
+  int m_locationId;
+  time_t m_timestamp;
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Wed Jul 28 11:02:36 2010 +0000
@@ -0,0 +1,188 @@
+/*
+Copyright (c) 2010 ARM Limited
+
+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:
+ 
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+ 
+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.
+*/
+
+/*
+This is the main file for this project.
+*/
+
+//Core libs
+#include "mbed.h"
+
+//Config
+#include "Config_Common.h"
+#include "Config_Impl.h"
+
+//RFID
+#include "RWDMifare.h"
+
+//Network
+#include "NTPClient.h" //To setup RTC
+//The MySQL Client is included in logger.h
+
+//Logging
+#include "taginfo.h"
+#include "logger.h"
+
+//UI
+#include "beep.h"
+
+#define MAX_UID_LEN 10 //Mifare max UID length is 10 bytes (triple-uid)
+
+//Implemented by the interface-specific demos
+int network_init();
+int network_close();
+
+RWDMifare reader(p13, p14, p12);
+Serial pc (USBTX,USBRX);
+
+DigitalIn exitBtn(p19);
+
+Beep beep(p20);
+
+NTPClient ntp;
+Logger logger(SQL_TABLE);
+
+extern "C" void HardFault_Handler() { printf("Hard Fault!\n"); error(""); }
+
+//Main routine
+int main() {
+  pc.baud(115200); //Set bitrate for debug output
+  
+  //Init Mifare Reader
+  RWDMifare::RWDMifareErr readerErr = reader.init();
+  if(readerErr)
+  {
+    beep.beep(Beep::TONE_ERR);
+    printf("Could not init reader (error %d)\n", readerErr);
+    return -1;
+  }
+  
+  //Open network connection
+  int netRc = network_init();
+  if(netRc)
+  {
+    beep.beep(Beep::TONE_ERR);
+    printf("Could not init network interface\n");
+    return -1;
+  }
+
+  //Setup the mbed's RTC
+  NTPResult ntpResult;
+  Host ntpServer(IpAddr(), 123, NTP_SERVER);
+  do
+  {
+    ntpResult = ntp.setTime(ntpServer);
+    if(ntpResult)
+    {
+      beep.beep(Beep::TONE_WARN);
+      printf("Could not get time...\n");
+      wait(5.);  
+    }
+  } while(ntpResult);
+ 
+  //Check time
+  time_t ctTime = time(NULL);  
+  printf("Time is now (UTC) : %s\n", ctime(&ctTime)); 
+   
+  Host sqlServer(SQL_SERVER_IP, 3306, SQL_SERVER);
+  
+  const int locationId = LOCATION_ID; //This is the location id that will be sent on each req to the SQL server
+ 
+  printf("Starting main loop...\n");
+
+  bool connected = false;
+  
+  #if SDCARD
+  logger.fileOpen(LOG_FILE); //Open file on SD card
+  #endif
+  
+  beep.beep(Beep::TONE_OK);
+  
+  uint8_t uid[MAX_UID_LEN]; //Buffer for uid
+  uint8_t lastUid[MAX_UID_LEN] = {0}; //Buffer for previous uid
+  size_t uidLen;
+  size_t lastUidLen = 0;
+  
+  while (!exitBtn.read()) //Main loop
+  {
+    if((!logger.isEmpty())&&(!logger.isConnecting())&&(!logger.isConnected())) //If logger is not ready, check its status
+    {
+      if(logger.connectionError()) //Error connecting to the server?
+      {
+        printf("Connection error (error code %d).\n", logger.getLastResult());
+        beep.beep(Beep::TONE_WARN);
+      }
+      printf("Connecting to SQL Server...\n");
+      logger.sqlOpen(sqlServer, SQL_USER, SQL_PASSWORD, SQL_DB); //Open a connection to server
+      connected = false;
+    }
+    if((!connected)&&logger.isConnected()) //We are now connected
+    {
+      connected = true;
+      printf("Connected to SQL Server...\n");
+      beep.beep(Beep::TONE_OK);
+    }
+    if(!reader.getUID(uid, &uidLen)) //Got an UID successfully
+    {
+      uidLen = (uidLen<10)?uidLen:10; //Check length
+      if( (uidLen != lastUidLen) || !!memcmp(lastUid, uid, uidLen) ) //Compare UID with previous one
+      {
+        beep.beep(Beep::TONE_INFO);
+        printf("Tag ID = ");
+        for(int i = 0; i < uidLen; i++)
+          printf("%02x ", uid[i]);
+        printf("\n");
+
+        time_t timestamp = time(NULL); 
+        timestamp += TIME_ZONE*3600;
+        TagInfo tagInfo(uid, uidLen, locationId, timestamp); //Setup infos for data logging
+        logger.log(&tagInfo); //Pass data to logger
+        
+        //Save uid to avoid duplicate db entries
+        memcpy(lastUid, uid, uidLen);
+        lastUidLen = uidLen;
+      }
+    }
+    else //No card present
+    {
+      lastUidLen = 0; //Last logged card is now out of field
+    }
+    logger.service(); //Process logger service
+  }
+  
+  printf("Stopping...\n");
+  
+  //Close everything nicely
+  logger.sqlClose();
+  
+  #if SDCARD
+  logger.fileClose();
+  #endif
+  
+  network_close();
+  
+  printf("End.\n");
+  beep.beep(Beep::TONE_OK);
+  
+  while(1);
+  
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Wed Jul 28 11:02:36 2010 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/9114680c05da
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mifare/RWDMifare.cpp	Wed Jul 28 11:02:36 2010 +0000
@@ -0,0 +1,87 @@
+/*
+Copyright (c) 2010 ARM Limited
+
+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:
+ 
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+ 
+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 "RWDMifare.h"
+
+RWDMifare::RWDMifare(PinName tx, PinName rx, PinName cts) : RWDModule(tx, rx, cts)
+{
+
+}
+
+RWDMifare::~RWDMifare()
+{
+
+}
+  
+RWDMifare::RWDMifareErr RWDMifare::init()
+{
+  const uint8_t config[] = {0x03, 0x00}; //Configure ready for Mifare Op (0x00 to addr 0x03 in EEPROM)
+  uint8_t resp[64] = {0};
+  //Cf http://www.ibtechnology.co.uk/pdf/MF_ICprot.pdf
+  //Command 'P': cf p11
+  //EEPROM parameters: cf p12
+  //Ack check: cf p13
+  command(0x50, config, 2, resp, 0, 0x80, 0x89); //Program EEPROM command is 0x50 ('P')
+  while(!ready()) //Wait for a response
+  {
+
+  }
+
+  if(!result()) //If this fails, there is something wrong with the hardware
+  {
+    return MIFARE_HW;
+  }
+  
+  return MIFARE_OK;
+}
+  
+RWDMifare::RWDMifareErr RWDMifare::getUID(uint8_t* pUID, size_t* pLen) //pUID must be at least 10-bytes long 
+//(A Mifare UID can either be 4, 7, or 10 bytes long)
+//This reader does not support 10 bytes uids
+{
+  //Cf http://www.ibtechnology.co.uk/pdf/MF_ICprot.pdf
+  //Command 'U': cf p19
+  //Ack check: cf p13
+  command(0x55, NULL, 0, pUID, 7, 0x86, 0x86); //UID command is 0x55 ('U')
+  while(!ready()) //Wait for a response
+  {
+
+  }
+    
+  if(!result()) //Error detected, there is no card in field
+  {
+    return MIFARE_NOCARD;
+  }
+  
+  printf("Got card.\n");
+    
+  //Checks UID length returned by reader
+  int i;
+  for(i = 0; i < 7; i++)
+  {
+    if(pUID[i] == 0) //End of UID, cf http://www.ibtechnology.co.uk/pdf/MF_ICprot.pdf p19
+      break;
+  }
+  *pLen = i;
+  
+  return MIFARE_OK;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mifare/RWDMifare.h	Wed Jul 28 11:02:36 2010 +0000
@@ -0,0 +1,57 @@
+/*
+Copyright (c) 2010 ARM Limited
+
+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:
+ 
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+ 
+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.
+*/
+
+/*
+This is a specific and quick implementation for the Mifare MicroRWD modules.
+The class configures the reader for Mifare operation and can poll for UIDs.
+*/
+
+#ifndef RWD_MIFARE_H
+#define RWD_MIFARE_H
+
+#include "mbed.h"
+#include "RWDModule.h"
+
+class RWDMifare : public RWDModule
+{
+public:
+  RWDMifare(PinName tx, PinName rx, PinName cts);
+  virtual ~RWDMifare();
+  
+  enum RWDMifareErr
+  {
+    MIFARE_OK, //No error
+    MIFARE_HW, //Hardware-specific error
+    MIFARE_NOCARD, //No card in field
+    MIFARE_WRONGKEY //Key is not valid (for auth command)
+  };
+
+  //Initialize the reader to operate in Mifare mode
+  RWDMifareErr init();
+  
+  //Checks if a card is present, and if so gets its UID
+  //Returns UID length as well (4, 7, or 10-bytes long)
+  RWDMifareErr getUID(uint8_t* pUID, size_t* pLen); //pUID must be at least 10-bytes long
+
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ui/beep.cpp	Wed Jul 28 11:02:36 2010 +0000
@@ -0,0 +1,75 @@
+/*
+Copyright (c) 2010 ARM Limited
+
+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:
+ 
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+ 
+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 "mbed.h"
+#include "beep.h"
+
+Beep::Beep(PinName pin) : m_ticker(), m_timeout(), m_out(pin)
+{
+  m_part = NULL;
+  m_pos = 0;
+}
+
+Beep::~Beep()
+{
+
+}
+
+//Tones data is { freq1 (Hz), length1 (s), ... } 
+//For a pause, frequency is set to 0
+//If length=0, end of tone
+const float Beep::Tones[][8] = { {523.25, 0.025, 783.99, 0.075, 0, 0}, //TONE_OK,
+                          {440, 0.050, 0, 0}, //TONE_INFO,
+                          {220, 0.100, 0, 0}, //TONE_WARN,
+                          {110, 0.250, 0, 0}  //TONE_ERR
+                        };
+  
+void Beep::beep(BEEP_TONE tone) //New beep
+{
+  m_ticker.detach(); //Stop previous beep is existing
+  m_timeout.detach();
+  m_part = (float*) Beep::Tones[tone]; //Select tone buf
+  m_pos = 0;
+  beepNote(); //Start with first note
+}
+
+void Beep::beepNote()
+{
+  float freq = m_part[m_pos]; //Setup frequency and length
+  float len = m_part[m_pos+1];
+  m_pos+=2;
+  if(len==0)
+    beepDone();
+  m_timeout.attach(this, &Beep::beepDone, len); //Setup timeout for end of note
+  if(freq>0)
+    m_ticker.attach(this, &Beep::beepTick, .5/freq); //Setup ticker for pin toggling at right freq
+}
+
+void Beep::beepTick()
+{
+  m_out.write(!m_out.read()); //Toggle output pin
+}
+
+void Beep::beepDone()
+{
+  m_ticker.detach(); //Note is done, stop toggling output pin
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ui/beep.h	Wed Jul 28 11:02:36 2010 +0000
@@ -0,0 +1,66 @@
+/*
+Copyright (c) 2010 ARM Limited
+
+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:
+ 
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+ 
+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.
+*/
+
+/*
+This class provides beeping using different tones.
+*/
+
+#ifndef BEEP_H
+#define BEEP_H
+
+#include "mbed.h"
+
+class Beep
+{
+public:
+  Beep(PinName pin);
+  ~Beep();
+  
+  enum BEEP_TONE
+  {
+    TONE_OK = 0,
+    TONE_INFO,
+    TONE_WARN,
+    TONE_ERR
+  };
+  
+  void beep(BEEP_TONE tone);
+
+protected:
+  void beepNote();
+  void beepTick();
+  void beepDone();
+  
+private:
+  Ticker m_ticker;
+  Timeout m_timeout;
+  DigitalOut m_out;
+  
+//  float m_part[8]; //Len, freq, len, freq...
+  float* m_part;
+  int m_pos;
+  
+  static const float Tones[][8];
+
+};
+
+#endif