mirror of
https://github.com/eclipse/upm.git
synced 2025-03-15 04:57:30 +03:00
zfm20: Use mraa::Uart instead of tty
Updated the ZFM20 class to use UART functionality provided through the mraa::Uart class instead of using the UART directly. * Switch to mraa::Uart * Added raw uart string constructor, closes #621 * Updated examples * Added a common.i to minimize interface duplication * Removed pointers from C++ functions where references are preferable * Removed dependency on termios * Added typedefs to handle pass-by-reference * Removed flushes * Removed code after throws Signed-off-by: Noel Eck <noel.eck@intel.com>
This commit is contained in:
parent
74b5ec00dc
commit
680649ba6f
@ -38,7 +38,7 @@ main(int argc, char** argv)
|
||||
upm::ZFM20 fp(0);
|
||||
|
||||
// make sure port is initialized properly. 57600 baud is the default.
|
||||
if (!fp.setupTty(B57600)) {
|
||||
if (!fp.setupTty(57600)) {
|
||||
cerr << "Failed to setup tty port parameters" << endl;
|
||||
return 1;
|
||||
}
|
||||
@ -83,7 +83,7 @@ main(int argc, char** argv)
|
||||
|
||||
// we search for a print matching slot 1, where we shored our last
|
||||
// converted fingerprint
|
||||
if ((rv = fp.search(1, &id, &score)) != ZFM20::ERR_OK) {
|
||||
if ((rv = fp.search(1, id, score)) != ZFM20::ERR_OK) {
|
||||
if (rv == ZFM20::ERR_FP_NOTFOUND) {
|
||||
cout << "Finger Print not found" << endl;
|
||||
return 0;
|
||||
|
@ -2,4 +2,4 @@ set (libname "zfm20")
|
||||
set (libdescription "Fingerprint Sensor Module")
|
||||
set (module_src ${libname}.cxx)
|
||||
set (module_hpp ${libname}.hpp)
|
||||
upm_module_init(mraa)
|
||||
upm_module_init(mraa utilities-c)
|
||||
|
11
src/zfm20/common.i
Normal file
11
src/zfm20/common.i
Normal file
@ -0,0 +1,11 @@
|
||||
%include "../upm.i"
|
||||
|
||||
/* Make it easy to use the methods which take a uint& id and score */
|
||||
%include "typemaps.i"
|
||||
%apply uint16_t &OUTPUT {uint16_t &id};
|
||||
%apply uint16_t &OUTPUT {uint16_t &score};
|
||||
|
||||
%{
|
||||
#include "zfm20.hpp"
|
||||
%}
|
||||
%include "zfm20.hpp"
|
@ -1,20 +1,10 @@
|
||||
%module javaupm_zfm20
|
||||
%include "../upm.i"
|
||||
%include "stdint.i"
|
||||
%include "typemaps.i"
|
||||
%include "arrays_java.i";
|
||||
%include "../java_buffer.i";
|
||||
|
||||
%apply uint16_t *OUTPUT { uint16_t *id, uint16_t *score };
|
||||
|
||||
%{
|
||||
#include "zfm20.hpp"
|
||||
speed_t int_B57600 = B57600;
|
||||
%}
|
||||
|
||||
|
||||
%include "zfm20.hpp"
|
||||
speed_t int_B57600 = B57600;
|
||||
%include "common.i"
|
||||
|
||||
%pragma(java) jniclasscode=%{
|
||||
static {
|
||||
|
@ -1,5 +1,4 @@
|
||||
%module jsupm_zfm20
|
||||
%include "../upm.i"
|
||||
%include "../carrays_uint8_t.i"
|
||||
%include "../carrays_uint16_t.i"
|
||||
%include "../carrays_uint32_t.i"
|
||||
@ -7,10 +6,5 @@
|
||||
|
||||
/* Send "int *" to JavaScript as intp */
|
||||
%pointer_functions(int, intp);
|
||||
%{
|
||||
#include "zfm20.hpp"
|
||||
speed_t int_B57600 = B57600;
|
||||
%}
|
||||
|
||||
%include "zfm20.hpp"
|
||||
speed_t int_B57600 = B57600;
|
||||
%include "common.i"
|
||||
|
@ -1,17 +1,9 @@
|
||||
// Include doxygen-generated documentation
|
||||
%include "pyupm_doxy2swig.i"
|
||||
%module pyupm_zfm20
|
||||
%include "../upm.i"
|
||||
%include "../carrays_uint8_t.i"
|
||||
%include "../carrays_uint16_t.i"
|
||||
%include "../carrays_uint32_t.i"
|
||||
%include "cpointer.i"
|
||||
|
||||
/* Send "int *" to python as intp */
|
||||
%pointer_functions(int, intp);
|
||||
%{
|
||||
#include "zfm20.hpp"
|
||||
speed_t int_B57600 = B57600;
|
||||
%}
|
||||
%include "zfm20.hpp"
|
||||
speed_t int_B57600 = B57600;
|
||||
%include "common.i"
|
||||
|
@ -33,154 +33,66 @@ using namespace std;
|
||||
|
||||
static const int defaultDelay = 100; // max wait time for read
|
||||
|
||||
ZFM20::ZFM20(int uart)
|
||||
ZFM20::ZFM20(int uart, int baud): m_uart(uart)
|
||||
{
|
||||
m_ttyFd = -1;
|
||||
|
||||
if ( !(m_uart = mraa_uart_init(uart)) )
|
||||
{
|
||||
throw std::invalid_argument(std::string(__FUNCTION__) +
|
||||
": mraa_uart_init() failed");
|
||||
return;
|
||||
}
|
||||
|
||||
// This requires a recent MRAA (1/2015)
|
||||
const char *devPath = mraa_uart_get_dev_path(m_uart);
|
||||
|
||||
if (!devPath)
|
||||
{
|
||||
throw std::runtime_error(std::string(__FUNCTION__) +
|
||||
": mraa_uart_get_dev_path() failed");
|
||||
return;
|
||||
}
|
||||
|
||||
// now open the tty
|
||||
if ( (m_ttyFd = open(devPath, O_RDWR)) == -1)
|
||||
{
|
||||
throw std::runtime_error(std::string(__FUNCTION__) +
|
||||
": open of " +
|
||||
string(devPath) + " failed: " +
|
||||
string(strerror(errno)));
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the default password and address
|
||||
setPassword(ZFM20_DEFAULT_PASSWORD);
|
||||
setAddress(ZFM20_DEFAULT_ADDRESS);
|
||||
|
||||
initClock();
|
||||
|
||||
if (!setupTty(baud))
|
||||
throw std::runtime_error(std::string(__FUNCTION__) +
|
||||
": failed to set baud rate to " + std::to_string(baud));
|
||||
}
|
||||
|
||||
ZFM20::~ZFM20()
|
||||
|
||||
ZFM20::ZFM20(std::string uart_raw, int baud) : m_uart(uart_raw)
|
||||
{
|
||||
if (m_ttyFd != -1)
|
||||
close(m_ttyFd);
|
||||
// Set the default password and address
|
||||
setPassword(ZFM20_DEFAULT_PASSWORD);
|
||||
setAddress(ZFM20_DEFAULT_ADDRESS);
|
||||
|
||||
mraa_deinit();
|
||||
}
|
||||
initClock();
|
||||
|
||||
bool ZFM20::dataAvailable(unsigned int millis)
|
||||
{
|
||||
if (m_ttyFd == -1)
|
||||
return false;
|
||||
|
||||
struct timeval timeout;
|
||||
|
||||
// no waiting
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = millis * 1000;
|
||||
|
||||
fd_set readfds;
|
||||
|
||||
FD_ZERO(&readfds);
|
||||
|
||||
FD_SET(m_ttyFd, &readfds);
|
||||
|
||||
if (select(m_ttyFd + 1, &readfds, NULL, NULL, &timeout) > 0)
|
||||
return true; // data is ready
|
||||
else
|
||||
return false;
|
||||
if (!setupTty(baud))
|
||||
throw std::runtime_error(std::string(__FUNCTION__) +
|
||||
": failed to set baud rate to " + std::to_string(baud));
|
||||
}
|
||||
|
||||
int ZFM20::readData(char *buffer, int len)
|
||||
{
|
||||
if (m_ttyFd == -1)
|
||||
return(-1);
|
||||
|
||||
if (!dataAvailable(defaultDelay))
|
||||
if (!m_uart.dataAvailable(defaultDelay))
|
||||
return 0; // timed out
|
||||
|
||||
int rv = read(m_ttyFd, buffer, len);
|
||||
int rv = m_uart.read(buffer, len);
|
||||
|
||||
if (rv < 0)
|
||||
{
|
||||
throw std::runtime_error(std::string(__FUNCTION__) +
|
||||
": read() failed: " +
|
||||
string(strerror(errno)));
|
||||
return rv;
|
||||
}
|
||||
": Uart::read() failed: " + string(strerror(errno)));
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
int ZFM20::writeData(char *buffer, int len)
|
||||
{
|
||||
if (m_ttyFd == -1)
|
||||
return(-1);
|
||||
|
||||
// first, flush any pending but unread input
|
||||
tcflush(m_ttyFd, TCIFLUSH);
|
||||
|
||||
int rv = write(m_ttyFd, buffer, len);
|
||||
int rv = m_uart.write(buffer, len);
|
||||
|
||||
if (rv < 0)
|
||||
{
|
||||
throw std::runtime_error(std::string(__FUNCTION__) +
|
||||
": write() failed: " +
|
||||
": Uart::write() failed: " +
|
||||
string(strerror(errno)));
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (rv == 0)
|
||||
{
|
||||
throw std::runtime_error(std::string(__FUNCTION__) +
|
||||
": write() failed, no bytes written");
|
||||
return rv;
|
||||
}
|
||||
|
||||
tcdrain(m_ttyFd);
|
||||
": Uart::write() failed, no bytes written");
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
bool ZFM20::setupTty(speed_t baud)
|
||||
bool ZFM20::setupTty(uint32_t baud)
|
||||
{
|
||||
if (m_ttyFd == -1)
|
||||
return(false);
|
||||
|
||||
struct termios termio;
|
||||
|
||||
// get current modes
|
||||
tcgetattr(m_ttyFd, &termio);
|
||||
|
||||
// setup for a 'raw' mode. 81N, no echo or special character
|
||||
// handling, such as flow control.
|
||||
cfmakeraw(&termio);
|
||||
|
||||
// set our baud rates
|
||||
cfsetispeed(&termio, baud);
|
||||
cfsetospeed(&termio, baud);
|
||||
|
||||
// make it so
|
||||
if (tcsetattr(m_ttyFd, TCSAFLUSH, &termio) < 0)
|
||||
{
|
||||
throw std::runtime_error(std::string(__FUNCTION__) +
|
||||
": tcsetattr() failed: " +
|
||||
string(strerror(errno)));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return m_uart.setBaudRate(baud) == mraa::SUCCESS;
|
||||
}
|
||||
|
||||
int ZFM20::writeCmdPacket(uint8_t *pkt, int len)
|
||||
@ -219,54 +131,25 @@ int ZFM20::writeCmdPacket(uint8_t *pkt, int len)
|
||||
|
||||
void ZFM20::initClock()
|
||||
{
|
||||
gettimeofday(&m_startTime, NULL);
|
||||
upm_clock_init(&m_clock);
|
||||
}
|
||||
|
||||
uint32_t ZFM20::getMillis()
|
||||
{
|
||||
struct timeval elapsed, now;
|
||||
uint32_t elapse;
|
||||
|
||||
// get current time
|
||||
gettimeofday(&now, NULL);
|
||||
|
||||
// compute the delta since m_startTime
|
||||
if( (elapsed.tv_usec = now.tv_usec - m_startTime.tv_usec) < 0 )
|
||||
{
|
||||
elapsed.tv_usec += 1000000;
|
||||
elapsed.tv_sec = now.tv_sec - m_startTime.tv_sec - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
elapsed.tv_sec = now.tv_sec - m_startTime.tv_sec;
|
||||
}
|
||||
|
||||
elapse = (uint32_t)((elapsed.tv_sec * 1000) + (elapsed.tv_usec / 1000));
|
||||
|
||||
// never return 0
|
||||
if (elapse == 0)
|
||||
elapse = 1;
|
||||
|
||||
return elapse;
|
||||
return upm_elapsed_ms(&m_clock);
|
||||
}
|
||||
|
||||
bool ZFM20::verifyPacket(uint8_t *pkt, int len)
|
||||
{
|
||||
// verify packet header
|
||||
if (pkt[0] != ZFM20_START1 || pkt[1] != ZFM20_START2)
|
||||
{
|
||||
throw std::runtime_error(std::string(__FUNCTION__) +
|
||||
": Invalid packet header");
|
||||
return false;
|
||||
}
|
||||
|
||||
// check the ack byte
|
||||
if (pkt[6] != PKT_ACK)
|
||||
{
|
||||
throw std::runtime_error(std::string(__FUNCTION__) +
|
||||
": Invalid ACK code");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -284,25 +167,19 @@ bool ZFM20::getResponse(uint8_t *pkt, int len)
|
||||
while (idx < len)
|
||||
{
|
||||
// wait for some data
|
||||
if (!dataAvailable(100))
|
||||
if (!m_uart.dataAvailable(100))
|
||||
{
|
||||
timer += getMillis();
|
||||
if (timer > ZFM20_TIMEOUT)
|
||||
{
|
||||
throw std::runtime_error(std::string(__FUNCTION__) +
|
||||
": Timed out waiting for packet");
|
||||
return false;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((rv = readData(buf, ZFM20_MAX_PKT_LEN)) == 0)
|
||||
{
|
||||
throw std::runtime_error(std::string(__FUNCTION__) +
|
||||
": readData() failed, no data returned");
|
||||
return false;
|
||||
}
|
||||
|
||||
// copy it into the user supplied buffer
|
||||
for (int i=0; i<rv; i++)
|
||||
@ -353,12 +230,8 @@ int ZFM20::getNumTemplates()
|
||||
|
||||
// check confirmation code
|
||||
if (rPkt[9] != 0x00)
|
||||
{
|
||||
throw std::runtime_error(std::string(__FUNCTION__) +
|
||||
": Invalid confirmation code");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ((rPkt[10] << 8) | rPkt[11]);
|
||||
}
|
||||
|
||||
@ -381,11 +254,8 @@ bool ZFM20::setNewPassword(uint32_t pwd)
|
||||
|
||||
// check confirmation code
|
||||
if (rPkt[9] != 0x00)
|
||||
{
|
||||
throw std::runtime_error(std::string(__FUNCTION__) +
|
||||
": Invalid confirmation code");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_password = pwd;
|
||||
|
||||
@ -411,11 +281,8 @@ bool ZFM20::setNewAddress(uint32_t addr)
|
||||
|
||||
// check confirmation code
|
||||
if (rPkt[9] != 0x00)
|
||||
{
|
||||
throw std::runtime_error(std::string(__FUNCTION__) +
|
||||
": Invalid confirmation code");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_address = addr;
|
||||
|
||||
@ -441,11 +308,8 @@ uint8_t ZFM20::generateImage()
|
||||
uint8_t ZFM20::image2Tz(int slot)
|
||||
{
|
||||
if (slot != 1 && slot != 2)
|
||||
{
|
||||
throw std::out_of_range(std::string(__FUNCTION__) +
|
||||
": slot must be 1 or 2");
|
||||
return ERR_INTERNAL_ERR;
|
||||
}
|
||||
|
||||
const int pktLen = 2;
|
||||
uint8_t pkt[pktLen] = {CMD_IMG2TZ,
|
||||
@ -481,11 +345,8 @@ uint8_t ZFM20::createModel()
|
||||
uint8_t ZFM20::storeModel(int slot, uint16_t id)
|
||||
{
|
||||
if (slot != 1 && slot != 2)
|
||||
{
|
||||
throw std::out_of_range(std::string(__FUNCTION__) +
|
||||
": slot must be 1 or 2");
|
||||
return ERR_INTERNAL_ERR;
|
||||
}
|
||||
|
||||
const int pktLen = 4;
|
||||
uint8_t pkt[pktLen] = {CMD_STORE,
|
||||
@ -540,17 +401,14 @@ uint8_t ZFM20::deleteDB()
|
||||
return rPkt[9];
|
||||
}
|
||||
|
||||
uint8_t ZFM20::search(int slot, uint16_t *id, uint16_t *score)
|
||||
uint8_t ZFM20::search(int slot, uint16_t &id, uint16_t &score)
|
||||
{
|
||||
*id = 0;
|
||||
*score = 0;
|
||||
id = 0;
|
||||
score = 0;
|
||||
|
||||
if (slot != 1 && slot != 2)
|
||||
{
|
||||
throw std::out_of_range(std::string(__FUNCTION__) +
|
||||
": slot must be 1 or 2");
|
||||
return ERR_INTERNAL_ERR;
|
||||
}
|
||||
|
||||
// search from page 0x0000 to page 0x00a3
|
||||
const int pktLen = 6;
|
||||
@ -572,16 +430,16 @@ uint8_t ZFM20::search(int slot, uint16_t *id, uint16_t *score)
|
||||
// if it was found, extract the location and the score
|
||||
if (rPkt[9] == ERR_OK)
|
||||
{
|
||||
*id = ((rPkt[10] << 8) & 0xff) | (rPkt[11] & 0xff);
|
||||
*score = ((rPkt[12] << 8) & 0xff) | (rPkt[13] & 0xff);
|
||||
id = ((rPkt[10] << 8) & 0xff) | (rPkt[11] & 0xff);
|
||||
score = ((rPkt[12] << 8) & 0xff) | (rPkt[13] & 0xff);
|
||||
}
|
||||
|
||||
return rPkt[9];
|
||||
}
|
||||
|
||||
uint8_t ZFM20::match(uint16_t *score)
|
||||
uint8_t ZFM20::match(uint16_t &score)
|
||||
{
|
||||
*score = 0;
|
||||
score = 0;
|
||||
|
||||
const int pktLen = 1;
|
||||
uint8_t pkt[pktLen] = {CMD_MATCH};
|
||||
@ -594,9 +452,7 @@ uint8_t ZFM20::match(uint16_t *score)
|
||||
|
||||
getResponse(rPkt, rPktLen);
|
||||
|
||||
*score = ((rPkt[10] << 8) & 0xff) | (rPkt[11] & 0xff);
|
||||
score = ((rPkt[10] << 8) & 0xff) | (rPkt[11] & 0xff);
|
||||
|
||||
return rPkt[9];
|
||||
}
|
||||
|
||||
|
||||
|
@ -35,13 +35,12 @@
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <termios.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <mraa/uart.h>
|
||||
#include "mraa.hpp"
|
||||
#include "upm_utilities.h"
|
||||
|
||||
#define ZFM20_DEFAULT_UART 0
|
||||
|
||||
@ -153,22 +152,23 @@ namespace upm {
|
||||
/**
|
||||
* ZFM20 constructor
|
||||
*
|
||||
* @param uart Default UART to use (0 or 1)
|
||||
* @param uart Target mraa UART index to use (0 or 1)
|
||||
* @param baud Desired baud rate
|
||||
*/
|
||||
ZFM20(int uart);
|
||||
ZFM20(int uart, int baud = 57600);
|
||||
|
||||
/**
|
||||
* ZFM20 constructor
|
||||
*
|
||||
* @param uart File path (/dev/ttyXXX to uart
|
||||
* @param baud Desired baud rate
|
||||
*/
|
||||
ZFM20(std::string uart_raw, int baud = 57600);
|
||||
|
||||
/**
|
||||
* ZFM20 destructor
|
||||
*/
|
||||
~ZFM20();
|
||||
|
||||
/**
|
||||
* Checks to see if there is data available for reading
|
||||
*
|
||||
* @param millis Number of milliseconds to wait; 0 means no waiting
|
||||
* @return true if there is data available for reading
|
||||
*/
|
||||
bool dataAvailable(unsigned int millis);
|
||||
virtual ~ZFM20() {}
|
||||
|
||||
/**
|
||||
* Reads any available data in a user-supplied buffer. Note: the
|
||||
@ -193,12 +193,12 @@ namespace upm {
|
||||
|
||||
/**
|
||||
* Sets up proper tty I/O modes and the baud rate. For this device,
|
||||
* the default baud rate is 57,600 (B57600).
|
||||
* the default baud rate is 57,600.
|
||||
*
|
||||
* @param baud Desired baud rate.
|
||||
* @return True if successful
|
||||
*/
|
||||
bool setupTty(speed_t baud=B57600);
|
||||
bool setupTty(uint32_t baud = 57600);
|
||||
|
||||
/**
|
||||
* Composes and writes a command packet
|
||||
@ -353,7 +353,7 @@ namespace upm {
|
||||
* @param score Score if found, 0 otherwise
|
||||
* @return One of the ZFM20_ERRORS_T values
|
||||
*/
|
||||
uint8_t search(int slot, uint16_t *id, uint16_t *score);
|
||||
uint8_t search(int slot, uint16_t &id, uint16_t &score);
|
||||
|
||||
/**
|
||||
* Compares the features in characteristics buffers 1 and 2 and
|
||||
@ -362,19 +362,12 @@ namespace upm {
|
||||
* @param score Score
|
||||
* @return One of the ZFM20_ERRORS_T values
|
||||
*/
|
||||
uint8_t match(uint16_t *score);
|
||||
|
||||
|
||||
protected:
|
||||
int ttyFd() { return m_ttyFd; };
|
||||
uint8_t match(uint16_t &score);
|
||||
|
||||
private:
|
||||
mraa_uart_context m_uart;
|
||||
int m_ttyFd;
|
||||
mraa::Uart m_uart;
|
||||
uint32_t m_password;
|
||||
uint32_t m_address;
|
||||
struct timeval m_startTime;
|
||||
upm_clock_t m_clock;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user