From 73868b2d4da3df79493f26a2bc93081b5f06d047 Mon Sep 17 00:00:00 2001 From: Ralf Ramsauer Date: Wed, 16 Sep 2015 22:59:14 +0200 Subject: [PATCH] Rewrite of Door class Removed old epaper display and added stub for qrcode printing. Signed-off-by: Ralf Ramsauer --- doorlockd/config.h.in | 2 +- doorlockd/daemon.cpp | 24 +- doorlockd/daemon.h | 6 +- doorlockd/door.cpp | 207 ++++--- doorlockd/door.h | 75 +-- doorlockd/epaper.cpp | 55 -- doorlockd/epaper.h | 42 -- doorlockd/epaper/Display_COG_Process.c | 650 --------------------- doorlockd/epaper/Display_COG_Process.h | 120 ---- doorlockd/epaper/Display_Controller.c | 40 -- doorlockd/epaper/Display_Controller.h | 34 -- doorlockd/epaper/Display_Hardware_Driver.c | 258 -------- doorlockd/epaper/Display_Hardware_Driver.h | 102 ---- doorlockd/epaper/bsp.c | 243 -------- doorlockd/epaper/bsp.h | 61 -- doorlockd/logic.cpp | 22 +- doorlockd/logic.h | 10 +- doorlockd/main.cpp | 24 +- 18 files changed, 190 insertions(+), 1785 deletions(-) delete mode 100644 doorlockd/epaper.cpp delete mode 100644 doorlockd/epaper.h delete mode 100644 doorlockd/epaper/Display_COG_Process.c delete mode 100644 doorlockd/epaper/Display_COG_Process.h delete mode 100644 doorlockd/epaper/Display_Controller.c delete mode 100644 doorlockd/epaper/Display_Controller.h delete mode 100644 doorlockd/epaper/Display_Hardware_Driver.c delete mode 100644 doorlockd/epaper/Display_Hardware_Driver.h delete mode 100644 doorlockd/epaper/bsp.c delete mode 100644 doorlockd/epaper/bsp.h diff --git a/doorlockd/config.h.in b/doorlockd/config.h.in index 94fa872..e1acc5b 100644 --- a/doorlockd/config.h.in +++ b/doorlockd/config.h.in @@ -15,7 +15,7 @@ #define DEFAULT_LDAP_URI "ldaps://ldap1.binary.kitchen/ ldaps://ldap2.binary.kitchen/ ldaps://ldapm.binary.kitchen/" #define DEFAULT_BINDDN "cn=%s,ou=Users,dc=binary-kitchen,dc=de" #define DEFAULT_LOG_FILE "/var/log/doorlockd.log" -#define DEFAULT_PID_FILE "/var/run/doorlockd.pid" +#define DEFAULT_SERIAL_DEVICE "/dev/ttyUSB0" #define TEMPLATE_LOCATION "@CMAKE_INSTALL_PREFIX@/share/doorlockd/template.png" diff --git a/doorlockd/daemon.cpp b/doorlockd/daemon.cpp index 9117b93..2cea094 100644 --- a/doorlockd/daemon.cpp +++ b/doorlockd/daemon.cpp @@ -11,12 +11,10 @@ using namespace std; -void daemonize(const bool daemonize, - const string &dir, +void daemonize(const string &dir, const string &stdinfile, const string &stdoutfile, - const string &stderrfile, - const string &pidFile) + const string &stderrfile) { umask(0); @@ -26,24 +24,6 @@ void daemonize(const bool daemonize, throw runtime_error(strerror(errno)); } - if (daemonize == true) - { - pid_t pid; - if ((pid = fork()) < 0) - { - throw runtime_error(strerror(errno)); - } else if (pid != 0) { - exit(0); - } - - pid = setsid(); - - ofstream pidStream; - pidStream.exceptions(ofstream::failbit | ofstream::badbit); - pidStream.open(pidFile, ofstream::trunc); - pidStream << pid << endl; - } - if (!dir.empty() && chdir(dir.c_str()) < 0) { throw runtime_error(strerror(errno)); diff --git a/doorlockd/daemon.h b/doorlockd/daemon.h index 5c94fd6..83060ea 100644 --- a/doorlockd/daemon.h +++ b/doorlockd/daemon.h @@ -8,11 +8,9 @@ // // This function will also redirect stdin, out and err to the // specified files -void daemonize(const bool daemonize, - const std::string &dir, +void daemonize(const std::string &dir, const std::string &stdinfile, const std::string &stdoutfile, - const std::string &stderrfile, - const std::string &pidFile); + const std::string &stderrfile); #endif diff --git a/doorlockd/door.cpp b/doorlockd/door.cpp index adf1099..494327a 100644 --- a/doorlockd/door.cpp +++ b/doorlockd/door.cpp @@ -1,35 +1,89 @@ -#include - -#include -#include - -#include "config.h" -#include "logger.h" #include "door.h" -using namespace std; - -Door::Door() : - _l(Logger::get()) +Door::Door(const std::string &serDev, + unsigned int baudrate) : + _baudrate(baudrate), + _port(_ioService, serDev), + _logger(Logger::get()) { - _l(LogLevel::info, "Initializing Raspberry Pi GPIOs"); - wiringPiSetup(); - pinMode(_HEARTBEATPIN, OUTPUT); - pinMode(_SCHNAPPERPIN, OUTPUT); - pinMode(_LOCKPIN, INPUT); - pullUpDnControl(_LOCKPIN, PUD_UP); - lock(); + // Configure serial port + _port.set_option(boost::asio::serial_port_base::baud_rate(baudrate)); + _port.set_option(boost::asio::serial_port_base::character_size(8)); + _port.set_option(boost::asio::serial_port_base::stop_bits(boost::asio::serial_port_base::stop_bits::one)); + _port.set_option(boost::asio::serial_port_base::parity(boost::asio::serial_port_base::parity::none)); + _port.set_option(boost::asio::serial_port_base::flow_control(boost::asio::serial_port_base::flow_control::none)); + + _asyncRead(); + + _ioThread = std::thread([this] () { + _ioService.run(); + }); + + // TODO Ping device } Door::~Door() { lock(); + + _ioService.stop(); + _ioService.reset(); + + _port.cancel(); + _port.close(); + + _ioThread.join(); } -Door &Door::get() +bool Door::readByte(char &byte, std::chrono::milliseconds timeout) { - static Door d; - return d; + std::unique_lock lock(_receiveLock); + _receivedCondition.wait_for(lock, timeout); + if (_byteReady) { + byte = recvBuf; + _byteReady = false; + return true; + } + return false; +} + +void Door::_asyncRead() +{ + _port.async_read_some( + boost::asio::buffer(&recvBuf, sizeof(recvBuf)), + [this] (const boost::system::error_code &ec, size_t bytes_transferred) { + if (ec) { + // Operation canceled occurs on system shutdown + // So we return without invoking an additional asyncRead() + if (ec == boost::system::errc::operation_canceled) + return; + + _logger(LogLevel::error, "Serialport error: %s", ec.message().c_str()); + goto out; + } + + if (bytes_transferred != 1) { + _logger(LogLevel::error, "Fatal serial error"); + goto out; + } + + if (recvBuf == 'U') { + _logger(LogLevel::notice, "Someone pushed the unlock button"); + } + if (recvBuf == 'L') { + _logger(LogLevel::notice, "Someone pushed the lock button"); + _logger(LogLevel::notice, "Locking..."); + lock(); + goto out; + } + // TODO EMERGENCY DOOR BUTTON + + _byteReady = true; + _receivedCondition.notify_one(); + + out: + _asyncRead(); + }); } Door::State Door::state() const @@ -39,97 +93,66 @@ Door::State Door::state() const void Door::lock() { - std::lock_guard l(_mutex); + _stateMutex.lock(); - _l(LogLevel::notice, "Executing Pre Lock Script"); - system(PRE_LOCK_SCRIPT); - - digitalWrite(_SCHNAPPERPIN, HIGH); - _l(LogLevel::info, "Door closed"); - - if (_state == State::Unlocked) - { - // Stop the Heartbeat Thread - _state = State::Locked; - _heartbeat.join(); + if (_state == State::Locked) { + _stateMutex.unlock(); + return; } - _l(LogLevel::notice, "Executing Post Lock Script"); - system(POST_LOCK_SCRIPT); + _state = State::Locked; + _stateMutex.unlock(); + _heartbeatCondition.notify_one(); + _heartbeatThread.join(); } void Door::unlock() { - _l(LogLevel::notice, "Executing Pre Unlock Script"); - system(PRE_UNLOCK_SCRIPT); - - // In any case, klacker the schnapper + _stateMutex.lock(); _schnapper = true; - // If heartbeat is already running, return - if (_state == State::Unlocked) - { + if(_state == State::Unlocked) { + _stateMutex.unlock(); return; } - // If not, first set state to unlocked _state = State::Unlocked; + _stateMutex.unlock(); - // Start the Heartbeat Thread - _heartbeat = std::thread([this] () { + _heartbeatThread = std::thread([this] () { + std::unique_lock lock(_heartbeatMutex); - // One "beat" is one complete cycle of the heartbeat clock - auto beat = [this] () { - digitalWrite(_HEARTBEATPIN, HIGH); - usleep(10000); - digitalWrite(_HEARTBEATPIN, LOW); - usleep(10000); - }; - - // The default of the Schnapperpin: always high - digitalWrite(_SCHNAPPERPIN, HIGH); - - // Heartbeat while the state is unlocked while (_state == State::Unlocked) { + if (_state == State::Unlocked) { + writeCMD('u'); - // In case of schnapper, send 0x55 resp. 0xaa to the schnapperpin - if (_schnapper == true) - { - for (int i = 0; i < 32 ; i++) - { - // Set '0' - digitalWrite(_SCHNAPPERPIN, LOW); - // cycle and send - beat(); - // Set '1' - digitalWrite(_SCHNAPPERPIN, HIGH); - // cycle and send - beat(); + if (_schnapper) { + _schnapper = false; + writeCMD('s'); } - - // Reset schnapperpin - digitalWrite(_SCHNAPPERPIN, HIGH); - // and deactivate schnapper for the next round - _schnapper = false; } - // Heartbeat - beat(); - - if (!digitalRead(_LOCKPIN)) { - std::thread([this] () { - _l(LogLevel::info, "Incoming door close request on button press"); - lock(); - }).detach(); - - // Busy wait till door is locked - while(_state == State::Unlocked); - } + _heartbeatCondition.wait_for(lock, Milliseconds(400)); } + writeCMD('l'); }); - - _l(LogLevel::info, "Door opened"); - - _l(LogLevel::notice, "Executing Post Unlock Script"); - system(POST_UNLOCK_SCRIPT); } + +bool Door::writeCMD(char c) +{ + std::lock_guard l(_serialMutex); + + _port.write_some(boost::asio::buffer(&c, sizeof(c))); + char response; + if (readByte(response, Milliseconds(100))) + { + if (c != response) { + _logger(LogLevel::error, "Sent command '%c' but gor response '%c'", c, response); + return false; + } + return true; + } + _logger(LogLevel::error, "Sent Serial command, but got no response!"); + return false; +} + diff --git a/doorlockd/door.h b/doorlockd/door.h index 134a5b0..1b5fdfd 100644 --- a/doorlockd/door.h +++ b/doorlockd/door.h @@ -2,64 +2,69 @@ #define DOOR_H #include +#include #include #include +#include + +#include +#include #include "logger.h" -/* - * The Door class. - * - * This class exists as a singleton as only one door and hence one object may exist. - * Available via the get() method. - * - * This class is responsible for opening and closing the door by sending - * the heartbeat to the AVR board via Raspberry Pi GPIOs - * - * Whenever the unlock() is called, this class also sends a 0x55 resp. 0xaa - * to the AVR in order to klacker the schnapper. - */ -class Door { - +class Door final +{ public: - // Returns the singleton - static Door &get(); + Door(const std::string &serDev, + unsigned int baudrate = 9600); ~Door(); - enum class State {Locked, Unlocked}; + enum class State {Unlocked, Locked}; - // Current state of the door State state() const; - // Lock the door void lock(); - // Unlock the door void unlock(); private: - Door(); + using Milliseconds = std::chrono::milliseconds; - // used for logging - const Logger &_l; + const unsigned int _baudrate; - // Indicates the internal state: Door is open or locked - volatile State _state = { Door::State::Locked }; + // To prevent concurrent writes + std::mutex _serialMutex = { }; - // A Heartbeat thread is started when the door is unlocked - std::thread _heartbeat = { }; + boost::asio::io_service _ioService = { }; + boost::asio::serial_port _port; - // Read by the Heartbeat thread if it should klacker the schnapper or not - bool _schnapper = { false }; + std::mutex _stateMutex = { }; + volatile State _state = { State::Locked }; - // Mutex to avoid concurrent locks - std::mutex _mutex = { }; + std::thread _heartbeatThread = { }; + std::mutex _heartbeatMutex = { }; + std::condition_variable _heartbeatCondition = { }; - // WiringPi GPIO Pins - static constexpr int _HEARTBEATPIN = 10; - static constexpr int _SCHNAPPERPIN = 7; - static constexpr int _LOCKPIN = 15; + std::thread _ioThread = { }; + void _asyncRead(); + + volatile bool _schnapper = { false }; + + // Indicates if recvBuf contains a valid response from AVR Board + volatile bool _byteReady = { false }; + // Actual response + char recvBuf = { }; + + std::condition_variable _receivedCondition = { }; + std::mutex _receiveLock = { }; + + const Logger &_logger; + + // Writed command to AVR board + bool writeCMD(char c); + // Receives one byte and returns true or returns false on timeout + bool readByte(char &byte, Milliseconds timeout); }; #endif diff --git a/doorlockd/epaper.cpp b/doorlockd/epaper.cpp deleted file mode 100644 index 1b4ba3a..0000000 --- a/doorlockd/epaper.cpp +++ /dev/null @@ -1,55 +0,0 @@ -#include -#include -#include - -#include "logger.h" - -extern "C" { -#include "epaper/bsp.h" -#include "epaper/Display_Controller.h" -} - -#include "epaper.h" -#include "config.h" - -using namespace std; - -Epaper::Epaper() : - _logger(Logger::get()) -{ - memset(_prevImg, 0xFF, _ARRAY_SIZE); - // Initialize Epaper library - bsp_init(); -} - -Epaper::~Epaper() -{ -} - -Epaper &Epaper::get() -{ - static Epaper e; - return e; -} - -void Epaper::draw(const string &uri) -{ - unsigned char buffer[_ARRAY_SIZE]; - snprintf((char*)buffer, _ARRAY_SIZE, - "qrencode -l M -d 100 -s 5 \"%s\" -t png -o -" - "| composite -geometry +90+0 /dev/stdin " TEMPLATE_LOCATION " -colorspace gray -depth 1 gray:-", - uri.c_str()); - - FILE* f = popen((const char*)buffer, "r"); - int i = fread(buffer, _ARRAY_SIZE, 1, f); - if (i != 1) - { - _logger(LogLevel::error, "Image format error"); - pclose(f); - return; - } - pclose(f); - - epd_DisplayImg(EPDType_270, buffer, _prevImg); - memcpy(_prevImg, buffer, _ARRAY_SIZE); -} diff --git a/doorlockd/epaper.h b/doorlockd/epaper.h deleted file mode 100644 index a7c82be..0000000 --- a/doorlockd/epaper.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef EPAPER_H -#define EPAPER_H - -#include -#include - -#include "logger.h" - -/* - * The "Epaper" class. - * - * Wrapper for the epaper third Party library. - * - * Exists as singleton, as only one display may exist. - */ -class Epaper { -public: - - static Epaper &get(); - ~Epaper(); - - // This function will draw template.png to the display and - // convert the uri to a QR-Code and paste it on top of template.png - // using imagemagick - void draw(const std::string &uri); - -private: - - constexpr static int _HEIGHT = 176; // In Pixel - constexpr static int _WIDTH = 33; // In Byte - constexpr static int _ARRAY_SIZE = _HEIGHT * _WIDTH; - - Epaper(); - - // The old image is needed when updating the Epaper display - // It informs the display which pixels have to be flipped - uint8_t _prevImg[_ARRAY_SIZE]; - - const Logger &_logger; -}; - -#endif diff --git a/doorlockd/epaper/Display_COG_Process.c b/doorlockd/epaper/Display_COG_Process.c deleted file mode 100644 index ef8c600..0000000 --- a/doorlockd/epaper/Display_COG_Process.c +++ /dev/null @@ -1,650 +0,0 @@ -// Copyright 2013 Pervasive Displays, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at: -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either -// express or implied. See the License for the specific language -// governing permissions and limitations under the License. - -/****************************************************************************** - * Includes - *****************************************************************************/ -//#include "driver_config.h" -//#include "target_config.h" -//#include "type.h" -//#include "gpio.h" -#include "Display_COG_Process.h" -#include "Display_Hardware_Driver.h" -#include "Display_Controller.h" - - -/****************************************************************************** - * Defines and typedefs - *****************************************************************************/ -#define _GaugeFrameTimeMark 0 - -const COG_Parameters_t COG_Parameters[3]= { - { //for 1.44" - {0x00,0x00,0x00,0x00,0x00,0x0f,0xff,0x00}, - 0x03, - (128/8), - 96, - (((128+96)*2)/8), - (43), - 480 - }, - { //for 2.0" - {0x00,0x00,0x00,0x00,0x01,0xFF,0xE0,0x00}, - 0x03, - (200/8), - 96, - (((200+96)*2)/8)+1, - (53), - 480 - }, - { //for 2.7" - {0x00,0x00,0x00,0x7F,0xFF,0xFE,0x00,0x00}, - 0x00, - (264/8), - 176, - (((264+176)*2)/8)+1, - 105, - 630 - }, -}; - -const uint8_t ScanTable[4] = {0xC0, 0x30, 0x0C, 0x03}; - - -/****************************************************************************** - * Local variables - *****************************************************************************/ -static uint32_t StageTime = 480; -static COG_LineDataPacket_t COG_Line; -static uint16_t EPD_Type_Index = 0; -static uint16_t cnt = 0; -static uint32_t Currentframe; -static uint8_t *DataLineEven; -static uint8_t *DataLineOdd; -static uint8_t *DataLineScan; -static uint8_t *DisplayOrgPtr; - - -/****************************************************************************** - * Local functions - *****************************************************************************/ -static void SetTemperature_Factor(uint8_t EPD_Type_Index) -{ - int16_t Temperature; - - //Get current temperature - Temperature = epd_get_temperature(); - - if (Temperature < -10) - { - StageTime = COG_Parameters[EPD_Type_Index].StageTime * 17; - } - else if (Temperature < -5) - { - StageTime = COG_Parameters[EPD_Type_Index].StageTime * 12; - } - else if (Temperature < 5) - { - StageTime = COG_Parameters[EPD_Type_Index].StageTime * 8; - } - else if (Temperature < 10) - { - StageTime = COG_Parameters[EPD_Type_Index].StageTime * 4; - } - else if (Temperature < 15) - { - StageTime = COG_Parameters[EPD_Type_Index].StageTime * 3; - } - else if (Temperature < 20) - { - StageTime = COG_Parameters[EPD_Type_Index].StageTime * 2; - } - else if (Temperature < 40) - { - StageTime = COG_Parameters[EPD_Type_Index].StageTime * 1; - } - else - { - StageTime = (COG_Parameters[EPD_Type_Index].StageTime * 7)/10; - } -} - -static void Driver_TypeSelect(uint8_t typeIndex) -{ - switch(typeIndex) - { - case EPDType_144: - DataLineEven=&COG_Line.LineDatas.COG_144LineData.Even[0]; - DataLineOdd=&COG_Line.LineDatas.COG_144LineData.Odd[0]; - DataLineScan=&COG_Line.LineDatas.COG_144LineData.Scan[0]; - break; - case EPDType_200: - DataLineEven=&COG_Line.LineDatas.COG_20LineData.Even[0]; - DataLineOdd=&COG_Line.LineDatas.COG_20LineData.Odd[0]; - DataLineScan=&COG_Line.LineDatas.COG_20LineData.Scan[0]; - break; - case EPDType_270: - DataLineEven=&COG_Line.LineDatas.COG_27LineData.Even[0]; - DataLineOdd=&COG_Line.LineDatas.COG_27LineData.Odd[0]; - DataLineScan=&COG_Line.LineDatas.COG_27LineData.Scan[0]; - break; - } -} - -//#pragma GCC optimize ("-O3") -static void Display_Stage_1 (uint8_t *PreviousPicture) -{ - uint16_t i,j,k; // general counters - uint8_t TempByte; // Temporary storage for image data check - uint16_t StartClock; -#ifdef DISPLAY_180_DEGREE - uint8_t *DataLinePrt; - DisplayOrgPtr = (PreviousPicture+(uint32_t)((COG_Parameters[EPD_Type_Index].VERTICAL-1)*COG_Parameters[EPD_Type_Index].HORIZONTAL)); -#else - DisplayOrgPtr = PreviousPicture; -#endif - Currentframe = (uint32_t)COG_Parameters[EPD_Type_Index].FrameTime; -//TestPinTrigger(); - cnt = 0; - StartClock = epd_GetCurrentTimeTick(); - do - { -// TestPin2Trigger(); - PreviousPicture = DisplayOrgPtr; -#ifdef DISPLAY_180_DEGREE - DataLinePrt = PreviousPicture; -#endif - for (i = 0; i < COG_Parameters[EPD_Type_Index].VERTICAL; i++) // for every line - { - // SPI (0x04, ...) - epd_SPI_Send_Byte(0x04, COG_Parameters[EPD_Type_Index].VoltageLevel); - k = COG_Parameters[EPD_Type_Index].HORIZONTAL-1; - for (j = 0; j < COG_Parameters[EPD_Type_Index].HORIZONTAL; j++) // check every bit in the line - { - TempByte = (*PreviousPicture++); -#ifdef DISPLAY_180_DEGREE - DataLineEven[j] = ((TempByte & 0x80) ? BLACK3 : WHITE3) - | ((TempByte & 0x20) ? BLACK2 : WHITE2) - | ((TempByte & 0x08) ? BLACK1 : WHITE1) - | ((TempByte & 0x02) ? BLACK0 : WHITE0); - - DataLineOdd[k--] = ((TempByte & 0x01) ? BLACK3 : WHITE3) - | ((TempByte & 0x04) ? BLACK2 : WHITE2) - | ((TempByte & 0x10) ? BLACK1 : WHITE1) - | ((TempByte & 0x40) ? BLACK0 : WHITE0); - DataLinePrt--; -#else - DataLineOdd[j] = ((TempByte & 0x80) ? BLACK3 : WHITE3) - | ((TempByte & 0x20) ? BLACK2 : WHITE2) - | ((TempByte & 0x08) ? BLACK1 : WHITE1) - | ((TempByte & 0x02) ? BLACK0 : WHITE0); - - DataLineEven[k--] = ((TempByte & 0x01) ? BLACK3 : WHITE3) - | ((TempByte & 0x04) ? BLACK2 : WHITE2) - | ((TempByte & 0x10) ? BLACK1 : WHITE1) - | ((TempByte & 0x40) ? BLACK0 : WHITE0); -#endif - } -#ifdef DISPLAY_180_DEGREE - PreviousPicture = DataLinePrt; -#endif - DataLineScan[(i>>2)] = ScanTable[(i%4)]; - // SPI (0x0a, line data....) - epd_SPI_Send(0x0a, (uint8_t *)&COG_Line.uint8, COG_Parameters[EPD_Type_Index].DataLineSize); - - // SPI (0x02, 0x25) - epd_SPI_Send_Byte(0x02, 0x2F); - - DataLineScan[(i>>2)] = 0; - } -#if(!_GaugeFrameTimeMark) - if(COG_Parameters[EPD_Type_Index].FrameTime>0) - { - while(Currentframe>(epd_GetCurrentTimeTick() - StartClock)); - } -#endif - //TestPin2Trigger(); - Currentframe=(uint32_t)(epd_GetCurrentTimeTick() - StartClock)+COG_Parameters[EPD_Type_Index].FrameTime ; - cnt++; - }while (StageTime>Currentframe); -// TestPin2Trigger(); - while(StageTime>(epd_GetCurrentTimeTick() - StartClock)); -// TestPin2Trigger(); -// TestPinTrigger(); -} - -//#pragma GCC optimize ("-O3") -static void Display_Stage_2 (uint8_t *PreviousPicture) -{ - uint16_t i, j, k; // general counters - uint8_t TempByte; // Temporary storage for image data check - uint16_t StartClock; -#ifdef DISPLAY_180_DEGREE - uint8_t *DataLinePrt; - DisplayOrgPtr = (PreviousPicture+(uint32_t)((COG_Parameters[EPD_Type_Index].VERTICAL-1)*COG_Parameters[EPD_Type_Index].HORIZONTAL)); -#else - DisplayOrgPtr = PreviousPicture; -#endif - -// TestPinTrigger(); - cnt = 0; - Currentframe = (uint32_t)COG_Parameters[EPD_Type_Index].FrameTime; - StartClock = epd_GetCurrentTimeTick(); - do - { -// TestPin2Trigger(); - PreviousPicture = DisplayOrgPtr; -#ifdef DISPLAY_180_DEGREE - DataLinePrt = PreviousPicture; -#endif - for (i = 0; i < COG_Parameters[EPD_Type_Index].VERTICAL; i++) // for every line - { - // SPI (0x04, ...) - epd_SPI_Send_Byte(0x04, COG_Parameters[EPD_Type_Index].VoltageLevel); - k = COG_Parameters[EPD_Type_Index].HORIZONTAL-1; - for (j = 0; j < COG_Parameters[EPD_Type_Index].HORIZONTAL; j++) // make every bit in the line black - { - TempByte =(*PreviousPicture++); -#ifdef DISPLAY_180_DEGREE - DataLineEven[j] = ((TempByte & 0x80) ? WHITE3 : NOTHING) - | ((TempByte & 0x20) ? WHITE2 : NOTHING) - | ((TempByte & 0x08) ? WHITE1 : NOTHING) - | ((TempByte & 0x02) ? WHITE0 : NOTHING); - DataLineOdd[k--] = ((TempByte & 0x01) ? WHITE3 : NOTHING) - | ((TempByte & 0x04) ? WHITE2 : NOTHING) - | ((TempByte & 0x10) ? WHITE1 : NOTHING) - | ((TempByte & 0x40) ? WHITE0 : NOTHING); - DataLinePrt--; -#else - DataLineOdd[j] = ((TempByte & 0x80) ? WHITE3 : NOTHING) - | ((TempByte & 0x20) ? WHITE2 : NOTHING) - | ((TempByte & 0x08) ? WHITE1 : NOTHING) - | ((TempByte & 0x02) ? WHITE0 : NOTHING); - DataLineEven[k--] = ((TempByte & 0x01) ? WHITE3 : NOTHING) - | ((TempByte & 0x04) ? WHITE2 : NOTHING) - | ((TempByte & 0x10) ? WHITE1 : NOTHING) - | ((TempByte & 0x40) ? WHITE0 : NOTHING); -#endif - } - -#ifdef DISPLAY_180_DEGREE - PreviousPicture = DataLinePrt; -#endif - DataLineScan[(i>>2)] = ScanTable[(i%4)]; - // SPI (0x0a, line data....) - epd_SPI_Send(0x0a, (uint8_t *)&COG_Line.uint8, COG_Parameters[EPD_Type_Index].DataLineSize); - - epd_SPI_Send_Byte(0x02, 0x25); - - DataLineScan[(i>>2)] = 0; - } -#if(!_GaugeFrameTimeMark) - if(COG_Parameters[EPD_Type_Index].FrameTime>0) - { - while(Currentframe>(epd_GetCurrentTimeTick() - StartClock)); - } -#endif - //TestPin2Trigger(); - Currentframe=(uint32_t)(epd_GetCurrentTimeTick() - StartClock)+COG_Parameters[EPD_Type_Index].FrameTime ; - cnt++; - }while (StageTime>Currentframe); -// TestPin2Trigger(); - while(StageTime>(epd_GetCurrentTimeTick() - StartClock)); -// TestPin2Trigger(); -// TestPinTrigger(); -} - - -//#pragma GCC optimize ("-O3") -static void Display_Stage_3 (uint8_t *Picture) -{ - uint16_t i, j,k; // general counters - uint8_t TempByte; // Temporary storage for image data check - uint16_t StartClock; -#ifdef DISPLAY_180_DEGREE - uint8_t *DataLinePrt; - DisplayOrgPtr = (Picture+(uint32_t)((COG_Parameters[EPD_Type_Index].VERTICAL-1)*COG_Parameters[EPD_Type_Index].HORIZONTAL)); -#else - DisplayOrgPtr = Picture; -#endif - Currentframe = (uint32_t)COG_Parameters[EPD_Type_Index].FrameTime; - cnt = 0; -// TestPinTrigger(); - StartClock = epd_GetCurrentTimeTick(); - do - { -// TestPin2Trigger(); - Picture = DisplayOrgPtr; -#ifdef DISPLAY_180_DEGREE - DataLinePrt = Picture; -#endif - for (i = 0; i < COG_Parameters[EPD_Type_Index].VERTICAL; i++) // for every line - { - // SPI (0x04, 0x03) - epd_SPI_Send_Byte(0x04, COG_Parameters[EPD_Type_Index].VoltageLevel); - k = COG_Parameters[EPD_Type_Index].HORIZONTAL-1; - for (j = 0; j < COG_Parameters[EPD_Type_Index].HORIZONTAL; j++) // check every bit in the line - { - TempByte = (*Picture++); -#ifdef DISPLAY_180_DEGREE - DataLineEven[j] = ((TempByte & 0x80) ? BLACK3 : NOTHING) - | ((TempByte & 0x20) ? BLACK2 : NOTHING ) - | ((TempByte & 0x08) ? BLACK1 : NOTHING ) - | ((TempByte & 0x02) ? BLACK0 : NOTHING ); - - DataLineOdd[k--] = ((TempByte & 0x01) ? BLACK3 : NOTHING) - | ((TempByte & 0x04) ? BLACK2 : NOTHING ) - | ((TempByte & 0x10) ? BLACK1 : NOTHING ) - | ((TempByte & 0x40) ? BLACK0 : NOTHING ); - DataLinePrt--; -#else - DataLineOdd[j] = ((TempByte & 0x80) ? BLACK3 : NOTHING) - | ((TempByte & 0x20) ? BLACK2 : NOTHING ) - | ((TempByte & 0x08) ? BLACK1 : NOTHING ) - | ((TempByte & 0x02) ? BLACK0 : NOTHING ); - - DataLineEven[k--] = ((TempByte & 0x01) ? BLACK3 : NOTHING) - | ((TempByte & 0x04) ? BLACK2 : NOTHING ) - | ((TempByte & 0x10) ? BLACK1 : NOTHING ) - | ((TempByte & 0x40) ? BLACK0 : NOTHING ); -#endif - } -#ifdef DISPLAY_180_DEGREE - Picture = DataLinePrt; -#endif - DataLineScan[(i>>2)] = ScanTable[(i%4)]; - // SPI (0x0a, line data....) - epd_SPI_Send(0x0a, (uint8_t *)&COG_Line.uint8, COG_Parameters[EPD_Type_Index].DataLineSize); - - epd_SPI_Send_Byte(0x02, 0x2F); - - DataLineScan[(i>>2)] = 0; - } -#if(!_GaugeFrameTimeMark) - if(COG_Parameters[EPD_Type_Index].FrameTime>0) - { - while(Currentframe>(epd_GetCurrentTimeTick() - StartClock)); - } -#endif - //TestPin2Trigger(); - Currentframe=(uint32_t)(epd_GetCurrentTimeTick() - StartClock)+COG_Parameters[EPD_Type_Index].FrameTime ; - cnt++; - }while (StageTime>Currentframe); -// TestPin2Trigger(); - while(StageTime>(epd_GetCurrentTimeTick() - StartClock)); -// TestPin2Trigger(); -// TestPinTrigger(); -} - -//#pragma GCC optimize ("-O3") -static void Display_Stage_4 (uint8_t *Picture) -{ - uint16_t i, j,k; // general counters - uint8_t TempByte; // Temporary storage for image data check - uint16_t StartClock; -#ifdef DISPLAY_180_DEGREE - uint8_t *DataLinePrt; - DisplayOrgPtr = (Picture+(uint32_t)((COG_Parameters[EPD_Type_Index].VERTICAL-1)*COG_Parameters[EPD_Type_Index].HORIZONTAL)); -#else - DisplayOrgPtr = Picture; -#endif - Currentframe = (uint32_t)COG_Parameters[EPD_Type_Index].FrameTime; - cnt = 0; -// TestPinTrigger(); - - StartClock = epd_GetCurrentTimeTick(); - do - { -// TestPin2Trigger(); - Picture = DisplayOrgPtr; -#ifdef DISPLAY_180_DEGREE - DataLinePrt = Picture; -#endif - for (i = 0; i < COG_Parameters[EPD_Type_Index].VERTICAL; i++) // for every line - { - // SPI (0x04, ...) - epd_SPI_Send_Byte(0x04, COG_Parameters[EPD_Type_Index].VoltageLevel); - k = COG_Parameters[EPD_Type_Index].HORIZONTAL-1; - for (j = 0; j < COG_Parameters[EPD_Type_Index].HORIZONTAL; j++) // check every bit in the line - { - TempByte =(*Picture++); -#ifdef DISPLAY_180_DEGREE - DataLineEven[j] = ((TempByte & 0x80) ? WHITE3 : BLACK3 ) - | ((TempByte & 0x20) ? WHITE2 : BLACK2 ) - | ((TempByte & 0x08) ? WHITE1 : BLACK1 ) - | ((TempByte & 0x02) ? WHITE0 : BLACK0 ); - - DataLineOdd[k--] = ((TempByte & 0x01) ? WHITE3 : BLACK3 ) - | ((TempByte & 0x04) ? WHITE2 : BLACK2 ) - | ((TempByte & 0x10) ? WHITE1 : BLACK1 ) - | ((TempByte & 0x40) ? WHITE0 : BLACK0 ); - DataLinePrt--; -#else - DataLineOdd[j] = ((TempByte & 0x80) ? WHITE3 : BLACK3 ) - | ((TempByte & 0x20) ? WHITE2 : BLACK2 ) - | ((TempByte & 0x08) ? WHITE1 : BLACK1 ) - | ((TempByte & 0x02) ? WHITE0 : BLACK0 ); - - DataLineEven[k--] = ((TempByte & 0x01) ? WHITE3 : BLACK3 ) - | ((TempByte & 0x04) ? WHITE2 : BLACK2 ) - | ((TempByte & 0x10) ? WHITE1 : BLACK1 ) - | ((TempByte & 0x40) ? WHITE0 : BLACK0 ); -#endif - } -#ifdef DISPLAY_180_DEGREE - Picture = DataLinePrt; -#endif - DataLineScan[(i>>2)] = ScanTable[(i%4)]; - // SPI (0x0a, line data....) - epd_SPI_Send(0x0a, (uint8_t *)&COG_Line.uint8, COG_Parameters[EPD_Type_Index].DataLineSize); - - epd_SPI_Send_Byte(0x02, 0x2F); - - DataLineScan[(i>>2)] = 0; - } -#if(!_GaugeFrameTimeMark) - if(COG_Parameters[EPD_Type_Index].FrameTime>0) - { - while(Currentframe>(epd_GetCurrentTimeTick() - StartClock)); - } -#endif - //TestPin2Trigger(); - Currentframe=(uint32_t)(epd_GetCurrentTimeTick() - StartClock)+COG_Parameters[EPD_Type_Index].FrameTime ; - cnt++; - }while (StageTime>Currentframe); - -// TestPin2Trigger(); - while(StageTime>(epd_GetCurrentTimeTick() - StartClock)); -// TestPin2Trigger(); -// TestPinTrigger(); -} - -static void Display_Nothing (void) -{ - uint16_t i; // general counters - - for (i = 0; i < COG_Parameters[EPD_Type_Index].HORIZONTAL; i++) // make every bit in the line white - { - DataLineEven[i] = 0x00; - DataLineOdd[i] = 0x00; - } - - for (i = 0; i < COG_Parameters[EPD_Type_Index].VERTICAL; i++) // for every line - { - epd_SPI_Send_Byte(0x04, 0x03); - DataLineScan[(i>>2)] = ScanTable[(i%4)]; - // SPI (0x0a, line data....) - epd_SPI_Send(0x0a, (uint8_t *)&COG_Line.uint8, COG_Parameters[EPD_Type_Index].DataLineSize); - - epd_SPI_Send_Byte(0x02, 0x2F); - } -} - -static void Dummy_line(void) -{ - uint16_t i; - - for (i = 0; i < COG_Parameters[EPD_Type_Index].DataLineSize; i++) - { - COG_Line.uint8[i] = 0x00; - } - - epd_SPI_Send_Byte(0x04, 0x03); - - // SPI (0x0a, line data....) - epd_SPI_Send(0x0a, (uint8_t *)&COG_Line.uint8, COG_Parameters[EPD_Type_Index].DataLineSize); - - epd_SPI_Send_Byte(0x02, 0x2F); -} - - -/****************************************************************************** - * Public functions - *****************************************************************************/ -void epd_HwInit(void) -{ - epd_InitDisplayHardware(); -} - -void epd_PowerOn(void) -{ - epd_discharge_low(); - epd_rst_low(); - epd_cs_low(); - epd_spi_init(); - - epd_pwm_active(5); - - epd_panelon_on(); - - epd_pwm_active(10); - - epd_cs_high(); - - //epd_border_high(); - - epd_rst_high(); - - epd_pwm_active(5); - - epd_rst_low(); - - epd_pwm_active(5); - - epd_rst_high(); - - epd_pwm_active(5); -} - -void epd_InitializeDriver(uint8_t EPDIndex) -{ - uint8_t SendBuffer[2]; - uint16_t k; - - EPD_Type_Index = EPDIndex; - - //Data Line Clear - for (k = 0; k <= __LineDataSize; k ++) - { - COG_Line.uint8[k] = 0x00; - } - Driver_TypeSelect(EPDIndex); - k = 0; - - SetTemperature_Factor(EPDIndex); - - /*while (DRIVERBUSY_Get()) - { - delayT32B0Us(500); - if((k++)>=1000) return;//wait 500 ms - } - */ - - // SPI (0x01, 0x0000, 0x0000, 0x01ff, 0xe000) - epd_SPI_Send(0x01, (uint8_t *)&COG_Parameters[EPDIndex].ChannelSelect, 8); - - epd_SPI_Send_Byte(0x06, 0xff); - epd_SPI_Send_Byte(0x07, 0x9d); - epd_SPI_Send_Byte(0x08, 0x00); - - // SPI (0x09, 0xd000) - SendBuffer[0] = 0xd0; - SendBuffer[1] = 0x00; - epd_SPI_Send(0x09, SendBuffer, 2); - - epd_SPI_Send_Byte(0x04,COG_Parameters[EPDIndex].VoltageLevel); - - epd_SPI_Send_Byte(0x03, 0x01); - epd_SPI_Send_Byte(0x03, 0x00); - - epd_pwm_active(5); - - epd_SPI_Send_Byte(0x05, 0x01); - - epd_pwm_active(30); - - epd_SPI_Send_Byte(0x05, 0x03); - epd_delay_ms(30); - epd_SPI_Send_Byte(0x05, 0x0f); - epd_delay_ms(30); - epd_SPI_Send_Byte(0x02, 0x24); -} - -void epd_Display (uint8_t *pNewImg, uint8_t *pPrevImg) -{ - //COG Process - update display in four steps - Display_Stage_1(pPrevImg); - Display_Stage_2(pPrevImg); - Display_Stage_3(pNewImg); - Display_Stage_4(pNewImg); -} - -void epd_PowerOff (void) -{ - Display_Nothing(); - Dummy_line(); - epd_delay_ms(25); - - //border_low(); - //epd_delay_ms(_30ms); - //border_high(); - - epd_SPI_Send_Byte(0x03, 0x01); - epd_SPI_Send_Byte(0x02, 0x05); - epd_SPI_Send_Byte(0x05, 0x0E); - epd_SPI_Send_Byte(0x05, 0x02); - epd_SPI_Send_Byte(0x04, 0x0C); - epd_delay_ms(120); - epd_SPI_Send_Byte(0x05, 0x00); - epd_SPI_Send_Byte(0x07, 0x0D); - epd_SPI_Send_Byte(0x04, 0x50); - epd_delay_ms(40); - epd_SPI_Send_Byte(0x04, 0xA0); - epd_delay_ms(40); - epd_SPI_Send_Byte(0x04, 0x00); - - epd_rst_low(); - epd_cs_low(); - epd_spi_detach(); - epd_panelon_off(); - - //epd_border_low(); - - epd_discharge_high(); - epd_delay_ms(150); - epd_discharge_low(); -} - - - diff --git a/doorlockd/epaper/Display_COG_Process.h b/doorlockd/epaper/Display_COG_Process.h deleted file mode 100644 index bf4f97f..0000000 --- a/doorlockd/epaper/Display_COG_Process.h +++ /dev/null @@ -1,120 +0,0 @@ -// Copyright 2013 Pervasive Displays, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at: -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either -// express or implied. See the License for the specific language -// governing permissions and limitations under the License. - -#ifndef __Display_COG_Process_H_ -#define __Display_COG_Process_H_ - -/****************************************************************************** - * Includes - *****************************************************************************/ - - #include "bsp.h" - -/****************************************************************************** - * Defines and typedefs - *****************************************************************************/ -#define BLACK0 (0x03) -#define BLACK1 (0x0C) -#define BLACK2 (0x30) -#define BLACK3 (0xc0) -#define WHITE0 (0x02) -#define WHITE1 (0x08) -#define WHITE2 (0x20) -#define WHITE3 (0x80) - -#define NOTHING (0x00) -#define SCANON (0xC0) -#define __LineDataSize 111 - -/* -enum -{ - _5ms, - _10ms, - _25ms, - _30ms, - _40ms, - _120ms, - _150ms, - _300ms -}; -*/ - -typedef enum -{ - EPDType_144 = 0, //1.44" display - EPDType_200 = 1, //2.0" display - EPDType_270 = 2 //2.7" display -} EPDType_t; -#define EPD_TYPE_144 0 -#define EPD_TYPE_200 1 -#define EPD_TYPE_270 2 - -typedef struct -{ - uint8_t Even[16]; - uint8_t Scan[24]; - uint8_t Odd [16]; -} COG_144_LineData_t; - -typedef struct -{ - uint8_t Even[25]; - uint8_t Scan[24]; - uint8_t Odd [25]; - uint8_t DummyData; -} COG_20_LineData_t; - -typedef struct -{ - uint8_t Even[33]; - uint8_t Scan[44]; - uint8_t Odd [33]; - uint8_t DummyData; -} COG_27_LineData_t; - -typedef union -{ - union - { - COG_144_LineData_t COG_144LineData; - COG_20_LineData_t COG_20LineData; - COG_27_LineData_t COG_27LineData; - } LineDatas; - uint8_t uint8[__LineDataSize]; -} COG_LineDataPacket_t; - -typedef struct -{ - uint8_t ChannelSelect[8]; - uint8_t VoltageLevel; - uint16_t HORIZONTAL; - uint16_t VERTICAL; - uint8_t DataLineSize; - uint16_t FrameTime; - uint16_t StageTime; -} COG_Parameters_t; - -extern const COG_Parameters_t COG_Parameters[3]; - -/****************************************************************************** - * Prototypes - *****************************************************************************/ -void epd_HwInit(void); -void epd_PowerOn(void); -void epd_InitializeDriver(uint8_t EPDIndex); -void epd_Display(uint8_t *pNewImg, uint8_t *pPrevImg); -void epd_PowerOff(void); - -#endif //__Display_COG_Process_H_ diff --git a/doorlockd/epaper/Display_Controller.c b/doorlockd/epaper/Display_Controller.c deleted file mode 100644 index 9aa5be5..0000000 --- a/doorlockd/epaper/Display_Controller.c +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright 2013 Pervasive Displays, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at: -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either -// express or implied. See the License for the specific language -// governing permissions and limitations under the License. - -/****************************************************************************** - * Includes - *****************************************************************************/ -//#include "driver_config.h" -//#include "type.h" -//#include "gpio.h" -#include "Display_Controller.h" - -/****************************************************************************** - * Global Functions - *****************************************************************************/ - -void epd_DisplayImg(EPDType_t EPDType, uint8_t *pNewImg, uint8_t *pPrevImg) -{ - //always initialize display (has been powered off before) - epd_HwInit(); - epd_PowerOn(); - epd_InitializeDriver(EPDType); - - //display new picture, but first remove old one - epd_Display(pNewImg, pPrevImg); - - //power down display - picture still displayed - epd_PowerOff(); -} - diff --git a/doorlockd/epaper/Display_Controller.h b/doorlockd/epaper/Display_Controller.h deleted file mode 100644 index 8f304e2..0000000 --- a/doorlockd/epaper/Display_Controller.h +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2013 Pervasive Displays, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at: -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either -// express or implied. See the License for the specific language -// governing permissions and limitations under the License. - -#ifndef __Display_Controller_H_ -#define __Display_Controller_H_ - -/****************************************************************************** - * Includes - *****************************************************************************/ -#include "bsp.h" -#include "Display_COG_Process.h" - -/****************************************************************************** - * Defines and typedefs - *****************************************************************************/ -#define DISPLAY_IN_USE EPD_TYPE_270 - -/****************************************************************************** - * Prototypes - *****************************************************************************/ -void epd_DisplayImg(EPDType_t EPDType, uint8_t *pNewImg, uint8_t *pPrevImg); - -#endif //__Display_Controller_H_ diff --git a/doorlockd/epaper/Display_Hardware_Driver.c b/doorlockd/epaper/Display_Hardware_Driver.c deleted file mode 100644 index 04ff563..0000000 --- a/doorlockd/epaper/Display_Hardware_Driver.c +++ /dev/null @@ -1,258 +0,0 @@ -// Copyright 2013 Pervasive Displays, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at: -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either -// express or implied. See the License for the specific language -// governing permissions and limitations under the License. - -/****************************************************************************** - * Includes - *****************************************************************************/ -#include "Display_Hardware_Driver.h" - - -/****************************************************************************** - * Public functions - *****************************************************************************/ -void epd_cs_high(void) -{ - // CS_SET_HIGH; - bsp_pinOut(BSP_PIN_6, 1); -} - -void epd_cs_low(void) -{ - // CS_SET_LOW; - bsp_pinOut(BSP_PIN_6, 0); -} - -void epd_rst_high(void) -{ - // RST_SET_HIGH; - bsp_pinOut(BSP_PIN_12, 1); -} - -void epd_rst_low(void) -{ - // RST_SET_LOW; - bsp_pinOut(BSP_PIN_12, 0); -} - -void epd_discharge_high(void) -{ - // DISCHARGE_SET_HIGH; - bsp_pinOut(BSP_PIN_14, 1); -} - -void epd_discharge_low(void) -{ - // DISCHARGE_SET_LOW; - bsp_pinOut(BSP_PIN_14, 0); -} - -void epd_panelon_off(void) -{ - // PANELON_SET_LOW; - bsp_pinOut(BSP_PIN_13, 0); -} - -void epd_panelon_on(void) -{ - // PANELON_SET_HIGH; - bsp_pinOut(BSP_PIN_13, 1); -} - -void epd_border_high(void) -{ - // BORDER_SET_HIGH; -} - -void epd_border_low(void) -{ - // BORDER_SET_LOW; -} - -void epd_delay_ms(uint32_t Time) -{ - bsp_delayMs(Time); -} - -int16_t epd_get_temperature(void) -{ - return bsp_getTemp(); -} - -uint32_t epd_GetCurrentTimeTick(void) -{ - return bsp_getMsTicks(); -} - -//****************************************************************** -//PWM Configuration/Control -//****************************************************************** -#if 0 -volatile uint32_t period = 500; //96Khz PWM frequency - -void epd_pwm_disable(void) -{ - disable_timer16(1); - LPC_IOCON->PIO1_9 &= 0xFC;//Disable PWM,set general IO - PWM_DIR_OUT(); - PWM_SET_LOW(); -} - -void epd_pwm_active(void) -{ - PWM_SET_HIGH(); - /* Initialize the PWM in timer32_1 enabling match0 output */ - init_timer16PWM(1, period, MATCH0,0); - setMatch_timer16PWM (1, 1, period/8); - enable_timer16(1); -} -#endif -void epd_pwm_active(uint16_t delayInMs) -{ - uint16_t numOfIterations; - - numOfIterations = delayInMs * 100; - // PWM_DIR_OUT; - bsp_pinMode(BSP_PIN_11, BSP_PINMODE_OUTPUT); - for(; numOfIterations > 0; numOfIterations--) - { - // PWM_SET_HIGH; - bsp_pinOut(BSP_PIN_11, 1); - bsp_delayUs(5); //100kHz (96kHz ideal) - // PWM_SET_LOW; - bsp_pinOut(BSP_PIN_11, 0); - bsp_delayUs(5); - } -} - - -//****************************************************************** -//SPI Configuration -//****************************************************************** -void epd_spi_detach(void) -{ -#if 0 - LPC_IOCON->PIO0_8 &= 0xFC;; /* SSP I/O config */ - SPIMISO_DIR_OUT(); - SPIMISO_Set(Low); - - LPC_IOCON->PIO0_9 &= 0xFC; /* SSP MOSI */ - SPIMOSI_DIR_OUT(); - SPIMOSI_Set(Low); - - LPC_IOCON->PIO2_11 &= 0xFC; - SPICLK_DIR_OUT(); - SPICLK_Set(Low); -#endif -} -void epd_spi_init (void) -{ - bsp_spiInit(); -//SSP_IOConfig( SSP_PORT ); /* initialize SSP port */ -//SSP_Init( SSP_PORT ); -} - -void epd_SPI_Send (unsigned char Register, unsigned char *Data, unsigned Length) -{ - uint8_t buf[2]; - - epd_cs_low(); - buf[0] = 0x70; - buf[1] = Register; - bsp_writeToDisplay(buf, 2); - epd_cs_high(); - bsp_delayUs(10); - - epd_cs_low(); - buf[0] = 0x72; - bsp_writeToDisplay(buf, 1); - bsp_writeToDisplay(Data, Length); - epd_cs_high(); - bsp_delayUs(10); -} - - - -void epd_SPI_Send_Byte (uint8_t Register, uint8_t Data) -{ - uint8_t buf[2]; - - epd_cs_low(); - buf[0] = 0x70; - buf[1] = Register; - bsp_writeToDisplay(buf, 2); - epd_cs_high(); - bsp_delayUs(10); - - epd_cs_low(); - buf[0] = 0x72; - buf[1] = Data; - bsp_writeToDisplay(buf, 2); - epd_cs_high(); - bsp_delayUs(10); -} - -void epd_InitDisplayHardware(void) -{ - // RST_DIR_OUT; - bsp_pinMode(BSP_PIN_12, BSP_PINMODE_OUTPUT); - // DISCHARGE_DIR_OUT; - bsp_pinMode(BSP_PIN_14, BSP_PINMODE_OUTPUT); - // CS_DIR_OUT; - bsp_pinMode(BSP_PIN_6, BSP_PINMODE_OUTPUT); - // PANELON_DIR_OUT; - bsp_pinMode(BSP_PIN_13, BSP_PINMODE_OUTPUT); - // DRIVERBUSY_DIR_IN; - bsp_pinMode(BSP_PIN_7, BSP_PINMODE_INPUT); - // BORDER_DIR_OUT; - - - epd_panelon_off(); - epd_spi_init(); - epd_cs_low(); - // epd_pwm_low(); - epd_pwm_active(0); //set output low - epd_rst_low(); - epd_discharge_low(); - -// TESTPin_DIR_OUT(); -// TESTPin2_DIR_OUT(); -} - -//************************************************************************ -void TestPinLow(void) -{ -// TESTPin_Set(0); -} -void TestPinHigh(void) -{ -// TESTPin_Set(1); -} -void TestPinTrigger(void) -{ -// if(TESTPin_Get())TestPinLow(); -// else TestPinHigh(); -} -void TestPin2Low(void) -{ -// TESTPin2_Set(0); -} -void TestPin2High(void) -{ -// TESTPin2_Set(1); -} -void TestPin2Trigger(void) -{ -// if(TESTPin2_Get())TestPin2Low(); -// else TestPin2High(); -} diff --git a/doorlockd/epaper/Display_Hardware_Driver.h b/doorlockd/epaper/Display_Hardware_Driver.h deleted file mode 100644 index a84cf35..0000000 --- a/doorlockd/epaper/Display_Hardware_Driver.h +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright 2013 Pervasive Displays, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at: -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either -// express or implied. See the License for the specific language -// governing permissions and limitations under the License. - -#ifndef __DISPLAY_HARDWARE_DRIVER_H_ -#define __DISPLAY_HARDWARE_DRIVER_H_ - -/****************************************************************************** - * Includes - *****************************************************************************/ - -#include "bsp.h" - - -/****************************************************************************** - * Defines and typedefs - *****************************************************************************/ - -//Pin 12 on Serial Expansion Connector -// #define RST_DIR_OUT SEC14_PIN12_SET_OUTP -// #define RST_SET_HIGH SEC14_PIN12_SET_HIGH -// #define RST_SET_LOW SEC14_PIN12_SET_LOW - -//Pin 14 on Serial Expansion Connector -// #define DISCHARGE_DIR_OUT SEC14_PIN14_SET_OUTP -// #define DISCHARGE_SET_HIGH SEC14_PIN14_SET_HIGH -// #define DISCHARGE_SET_LOW SEC14_PIN14_SET_LOW - -//Pin 6 on Serial Expansion Connector -// #define CS_DIR_OUT SEC14_PIN6_SET_OUTP -// #define CS_SET_HIGH SEC14_PIN6_SET_HIGH -// #define CS_SET_LOW SEC14_PIN6_SET_LOW - -//Pin 13 on Serial Expansion Connector -// #define PANELON_DIR_OUT SEC14_PIN13_SET_OUTP -// #define PANELON_SET_HIGH SEC14_PIN13_SET_HIGH -// #define PANELON_SET_LOW SEC14_PIN13_SET_LOW - -//Pin 7 on Serial Expansion Connector -// #define DRIVERBUSY_DIR_IN SEC14_PIN7_SET_INP -// #define DRIVERBUSY_GET SEC14_PIN7_INP - -//Not implemented -// #define BORDER_DIR_OUT -// #define BORDER_SET_HIGH -// #define BORDER_SET_LOW - -//Pin 11 on Serial Expansion Connector -// #define PWM_DIR_OUT SEC14_PIN11_SET_OUTP -// #define PWM_SET_HIGH SEC14_PIN11_SET_HIGH -// #define PWM_SET_LOW SEC14_PIN11_SET_LOW - - -/****************************************************************************** - * Prototypes - *****************************************************************************/ -void epd_cs_high(void); -void epd_cs_low(void); -void epd_rst_high(void); -void epd_rst_low(void); -void epd_discharge_high(void); -void epd_discharge_low(void); -void epd_panelon_off(void); -void epd_panelon_on(void); - -void epd_pwm_active(uint16_t delayInMs); - -void epd_border_high(void); -void epd_border_low(void); - -void epd_TestPinLow(void); -void epd_TestPinHigh(void); -void epd_TestPinTrigger(void); - -void epd_TestPin2Low(void); -void epd_TestPin2High(void); -void epd_TestPin2Trigger(void); - -void epd_delay_ms(uint32_t Time); -int16_t epd_get_temperature(void); -uint32_t epd_GetCurrentTimeTick(void); - -/***************************************************************************/ -void epd_spi_detach(void); -void epd_spi_init (void); -void epd_SPI_Send (unsigned char Register, unsigned char *Data, unsigned Length); -void epd_SPI_Send_Byte (uint8_t Register, uint8_t Data); -void epd_InitDisplayHardware (void); - -/****************************************************************************/ - -#endif //__DISPLAY_HARDWARE_DRIVER_H_ diff --git a/doorlockd/epaper/bsp.c b/doorlockd/epaper/bsp.c deleted file mode 100644 index ca01073..0000000 --- a/doorlockd/epaper/bsp.c +++ /dev/null @@ -1,243 +0,0 @@ -/***************************************************************************** - * - * Copyright(C) 2012, Embedded Artists AB - * All rights reserved. - * - ****************************************************************************** - * 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. - * Embedded Artists AB 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. Embedded Artists AB - * reserves the right to make changes in the software without - * notification. Embedded Artists AB also make no representation or - * warranty that such application will be suitable for the specified - * use without further testing or modification. - *****************************************************************************/ - -/****************************************************************************** - * Includes - *****************************************************************************/ -#include "bsp.h" -#include -#include -#include - -#include - -/****************************************************************************** - * Typedefs and defines - *****************************************************************************/ - -#define LM75A_I2C_ADDR 0x49 //(0x49 << 1) -#define LM75A_CMD_TEMP 0x00 -#define DISPLAY_BUF_SZ (256) - -/****************************************************************************** - * Local variables - *****************************************************************************/ - -// I2C device handle -static int gI2cFd = -1; - -// mapping between Serial Expansion connector and Raspberry Pi -// GPIOs. Raspberry Pi GPIO numbering according to wiringPi -static int pinMap[BSP_PIN_SZ*2] = -{ - // [SEC] | [PI GPIO#] - BSP_PIN_6, 6, // CS - BSP_PIN_7, 0, // Busy - BSP_PIN_8, -1, // Not Used - BSP_PIN_11, 1, // PWM - BSP_PIN_12, 5, // RST - BSP_PIN_13, 3, // PWR_Ctrl - BSP_PIN_14, 4, // DISCHARGE -}; - -// buffer used when writing to display via SPI -static uint8_t displayBuf[DISPLAY_BUF_SZ]; - -/****************************************************************************** - * Local functions - *****************************************************************************/ - -static int32_t lm75a_readTemp(void) -{ - uint8_t temp[2]; - int16_t t = 0; - - wiringPiI2CWrite(gI2cFd, LM75A_CMD_TEMP); - temp[0] = wiringPiI2CRead(gI2cFd); - temp[1] = wiringPiI2CRead(gI2cFd); - - - // 11 MSB bits used. Celcius is calculated as Temp data * 1/8 - t = ((temp[0] << 8) | (temp[1])); - - return ((t * 100) >> 8); -} - - -/****************************************************************************** - * Public functions - *****************************************************************************/ - - -/****************************************************************************** - * - * Description: - * BSP initialize function. Must be called before any other BSP related - * functions. - * - *****************************************************************************/ -int bsp_init(void) -{ - - if (wiringPiSetup() < 0) { - printf("bsp_init: failed to initialize wiringPi\n"); - return -1; - } - - if ((gI2cFd = wiringPiI2CSetup(LM75A_I2C_ADDR)) < 0) { - printf("bsp_init: failed to initialize I2C\n"); - return -1; - } - - if (wiringPiSPISetup(0, 1000000) < 0) { - printf("bsp_init: failed to initialize SPI\n"); - return -1; - } - - return 0; -} - -/****************************************************************************** - * - * Description: - * Get number of milliseconds - * - *****************************************************************************/ -uint32_t bsp_getMsTicks(void) -{ - return millis(); -} - -/****************************************************************************** - * - * Description: - * Initialize SPI - * - *****************************************************************************/ -void bsp_spiInit(void) -{ - // initialized in bsp_init -} - -/****************************************************************************** - * - * Description: - * Write data to the display - * - *****************************************************************************/ -void bsp_writeToDisplay(uint8_t* data, uint16_t len) -{ - if (len > DISPLAY_BUF_SZ) { - printf("bsp_writeToDisplay: ERROR len=%d > %d\n", len, DISPLAY_BUF_SZ); - return; - } - - memcpy(displayBuf, data, len); - wiringPiSPIDataRW(0, displayBuf, len); - -} - -/****************************************************************************** - * - * Description: - * Delay specified number of milliseconds - * - * Params: - * [in] ms - number of milliseconds to delay - * - *****************************************************************************/ -void bsp_delayMs(uint32_t ms) -{ - delay(ms); -} - -/****************************************************************************** - * - * Description: - * Delay specified number of microseconds - * - * Params: - * [in] us - number of microseconds to delay - * - *****************************************************************************/ -void bsp_delayUs(uint32_t us) -{ - delayMicroseconds(us); -} - -/****************************************************************************** - * - * Description: - * Read temperature - * - * Params: - * [out] temperature - (int16_t) temperature in Celsius - * - *****************************************************************************/ -int16_t bsp_getTemp(void) -{ - lm75a_readTemp(); - bsp_delayMs(5); - return (int16_t)(lm75a_readTemp()/100); -} - -/****************************************************************************** - * - * Description: - * Set the PIN mode of a specific pin - * - *****************************************************************************/ -void bsp_pinMode(bsp_pin_t pin, bps_pinMode_t mode) -{ - int m = INPUT; - int p = 0; - - if (pin >= BSP_PIN_SZ) return; - - if (mode == BSP_PINMODE_OUTPUT) { - m = OUTPUT; - } - - p = pinMap[pin*2+1]; - - pinMode(p, m); -} - -/****************************************************************************** - * - * Description: - * Set PIN to high (1) of low (0) value - * - *****************************************************************************/ -void bsp_pinOut(bsp_pin_t pin, int value) -{ - int p = 0; - int v = LOW; - - if (pin >= BSP_PIN_SZ) return; - - if (value != 0) { - v = HIGH; - } - - p = pinMap[pin*2+1]; - - digitalWrite(p, v); -} - - diff --git a/doorlockd/epaper/bsp.h b/doorlockd/epaper/bsp.h deleted file mode 100644 index c0fbb8a..0000000 --- a/doorlockd/epaper/bsp.h +++ /dev/null @@ -1,61 +0,0 @@ -/***************************************************************************** - * - * Copyright(C) 2012, Embedded Artists AB - * All rights reserved. - * - ****************************************************************************** - * 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. - * Embedded Artists AB 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. Embedded Artists AB - * reserves the right to make changes in the software without - * notification. Embedded Artists AB also make no representation or - * warranty that such application will be suitable for the specified - * use without further testing or modification. - *****************************************************************************/ -#ifndef __BSP_H__ -#define __BSP_H__ - -/****************************************************************************** - * Defines and typedefs - *****************************************************************************/ - -#include -#include -#include - -// pin numbering is for the Serial Expansion Connector -typedef enum -{ - BSP_PIN_6 = 0, - BSP_PIN_7, - BSP_PIN_8, - BSP_PIN_11, - BSP_PIN_12, - BSP_PIN_13, - BSP_PIN_14, - BSP_PIN_SZ // must be last -} bsp_pin_t; - -typedef enum -{ - BSP_PINMODE_INPUT = 0, - BSP_PINMODE_OUTPUT -} bps_pinMode_t; - -/****************************************************************************** - * Prototypes - *****************************************************************************/ -int bsp_init(void); -void bsp_spiInit(void); -void bsp_writeToDisplay(uint8_t* data, uint16_t len); -uint32_t bsp_getMsTicks(void); -void bsp_delayMs(uint32_t ms); -void bsp_delayUs(uint32_t us); -int16_t bsp_getTemp(void); -void bsp_pinMode(bsp_pin_t pin, bps_pinMode_t mode); -void bsp_pinOut(bsp_pin_t pin, int value); - -#endif //__BSP_H__ diff --git a/doorlockd/logic.cpp b/doorlockd/logic.cpp index 4a94202..908323e 100644 --- a/doorlockd/logic.cpp +++ b/doorlockd/logic.cpp @@ -16,10 +16,10 @@ using namespace std; Logic::Logic(const chrono::seconds tokenTimeout, const string &ldapUri, const string &bindDN, - const string &webPrefix) : + const string &webPrefix, + const string &serDev) : _logger(Logger::get()), - _door(Door::get()), - _epaper(Epaper::get()), + _door(serDev), _tokenTimeout(tokenTimeout), _ldapUri(ldapUri), _bindDN(bindDN), @@ -131,11 +131,11 @@ Logic::Response Logic::_lock() Logic::Response Logic::_unlock() { - const auto state = _door.state(); + const auto oldState = _door.state(); _door.unlock(); _createNewToken(false); - if (state == Door::State::Unlocked) + if (oldState == Door::State::Unlocked) { _logger(LogLevel::warning, "Unable to unlock: already unlocked"); return AlreadyUnlocked; @@ -211,12 +211,22 @@ out2: void Logic::_createNewToken(const bool stillValid) { + // Todo Mutex einführen + _prevToken = _curToken; _prevValid = stillValid; _curToken = (((uint64_t)rand())<<32) | ((uint64_t)rand()); - _epaper.draw(_webPrefix + toHexString(_curToken)); + // TODO make things more pretty + const string uri = _webPrefix + toHexString(_curToken); + + const int ARRAY_SIZE=1024; + char buffer[ARRAY_SIZE]; + snprintf(buffer, ARRAY_SIZE, + "qrencode -l M -d 100 -s 5 \"%s\" -t png -o /tmp/qr.png", uri.c_str()); + system(buffer); + ostringstream message; message << "New Token generated: " << toHexString(_curToken) << " old Token: " << toHexString(_prevToken) << " is " << (_prevValid?"still":"not") << " valid"; diff --git a/doorlockd/logic.h b/doorlockd/logic.h index ef264b1..e537418 100644 --- a/doorlockd/logic.h +++ b/doorlockd/logic.h @@ -8,7 +8,6 @@ #include #include "config.h" -#include "epaper.h" #include "door.h" #include "logger.h" @@ -25,7 +24,8 @@ public: Logic(const std::chrono::seconds tokenTimeout, const std::string &ldapUri, const std::string &bindDN, - const std::string &webPrefix); + const std::string &webPrefix, + const std::string &serDev); ~Logic(); enum Response { @@ -65,10 +65,8 @@ private: const Logger &_logger; - // Door reference - Door &_door; - // Epaper reference - Epaper &_epaper; + // The door + Door _door; // Tokens are 64-bit hexadecimal values using Token = uint64_t; diff --git a/doorlockd/main.cpp b/doorlockd/main.cpp index ba92257..092db40 100644 --- a/doorlockd/main.cpp +++ b/doorlockd/main.cpp @@ -102,6 +102,10 @@ private: tcp::socket _socket; }; +void emergencyCB() +{ + cout << "EMERGENCY!" << endl; +} int main(int argc, char** argv) { @@ -112,15 +116,10 @@ int main(int argc, char** argv) string bindDN; string lockPagePrefix; string logfile; - string pidFile; - bool foreground = false; + string serDev; l(LogLevel::notice, "Starting doorlockd"); - // Load SPI and I2C modules - system("/usr/bin/gpio load spi"); - system("/usr/bin/gpio load i2c"); - try { unsigned int timeout; po::options_description desc("usage: doorlockd"); @@ -131,9 +130,8 @@ int main(int argc, char** argv) ("ldap,s", po::value(&ldapUri)->default_value(DEFAULT_LDAP_URI), "Ldap Server") ("bidndn,b", po::value(&bindDN)->default_value(DEFAULT_BINDDN), "Bind DN, %s means username") ("web,w", po::value(&lockPagePrefix)->default_value(DEFAULT_WEB_PREFIX), "Prefix of the webpage") - ("foreground,f", po::bool_switch(&foreground)->default_value(false), "Run in foreground") ("logfile,l", po::value(&logfile)->default_value(DEFAULT_LOG_FILE), "Log file") - ("pid,z", po::value(&pidFile)->default_value(DEFAULT_PID_FILE), "PID file"); + ("serial,i", po::value(&serDev)->default_value(DEFAULT_SERIAL_DEVICE), "Serial port"); po::variables_map vm; po::store(po::command_line_parser(argc, argv).options(desc).run(), vm); @@ -155,12 +153,10 @@ int main(int argc, char** argv) goto out; } - daemonize(!foreground, - "/", + daemonize("/", "/dev/null", logfile, - logfile, - pidFile); + logfile); signal(SIGINT, signal_handler); signal(SIGKILL, signal_handler); @@ -171,7 +167,8 @@ int main(int argc, char** argv) logic = unique_ptr(new Logic(tokenTimeout, ldapUri, bindDN, - lockPagePrefix)); + lockPagePrefix, + serDev)); try { server s(io_service, port); @@ -188,7 +185,6 @@ int main(int argc, char** argv) retval = 0; out: - Door::get().lock(); l(LogLevel::notice, "Doorlockd stopped"); return retval; }