ds2413: Initial implementation

This adds initial support for the DS2413 Dual Channel Addressable
Switch.  This is a Dallas Semiconductor 1-wire compliant device
providing access to 2 open-drain GPIOs.

https://learn.adafruit.com/adafruit-1-wire-gpio-breakout-ds2413/overview

This driver requires One-Wire over UART support in MRAA (PR #415)
which is not yet merged.

Signed-off-by: Jon Trulson <jtrulson@ics.com>
This commit is contained in:
Jon Trulson 2015-12-16 16:26:25 -07:00 committed by Noel Eck
parent 893b35f77b
commit e1bda1f44b
10 changed files with 562 additions and 0 deletions

View File

@ -265,6 +265,7 @@ if (BACNET_FOUND)
add_example (e50hx)
endif()
add_example (vcap)
add_example (ds2413)
# These are special cases where you specify example binary, source file and module(s)
include_directories (${PROJECT_SOURCE_DIR}/src)

59
examples/c++/ds2413.cxx Normal file
View File

@ -0,0 +1,59 @@
/*
* Author: Jon Trulson <jtrulson@ics.com>
* Copyright (c) 2016 Intel Corporation.
*
* 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 <unistd.h>
#include <iostream>
#include <stdio.h>
#include "ds2413.h"
using namespace std;
using namespace upm;
int main(int argc, char **argv)
{
//! [Interesting]
// Instantiate a DS2413 Module on a Dallas 1-wire bus connected to UART 0
upm::DS2413* sensor = new upm::DS2413(0);
// find all of the DS2413 devices present on the bus
sensor->init();
// how many devices were found?
cout << "Found "<< sensor->devicesFound() << " device(s)" << endl;
// read the gpio and latch values from the first device
// the lower 4 bits are of the form:
// <gpioB latch> <gpioB value> <gpioA latch> <gpioA value>
cout << "GPIO device 0 values: " << sensor->readGpios(0) << endl;
// set the gpio latch values of the first device
cout << "Setting GPIO latches to on" << endl;
sensor->writeGpios(0, 0x03);
cout << "Exiting..." << endl;
delete sensor;
//! [Interesting]
return 0;
}

View File

@ -0,0 +1,55 @@
/*jslint node:true, vars:true, bitwise:true, unparam:true */
/*jshint unused:true */
/*
* Author: Jon Trulson <jtrulson@ics.com>
* Copyright (c) 2015 Intel Corporation.
*
* 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.
*/
var sensorObj = require('jsupm_ds2413');
/************** Main code **************/
// Instantiate a DS2413 Module on a Dallas 1-wire bus connected to UART 0
var sensor = new sensorObj.DS2413(0);
// find all of the DS2413 devices present on the bus
sensor.init();
// how many devices were found?
console.log("Found", sensor.devicesFound(), "device(s)");
// read the gpio and latch values from the first device
// the lower 4 bits are of the form:
// <gpioB latch> <gpioB value> <gpioA latch> <gpioA value>
console.log("GPIO device 0 values:", sensor.readGpios(0));
// set the gpio latch values of the first device
console.log("Setting GPIO latches to on");;
sensor.writeGpios(0, 0x03);
sensor = null;
sensorObj.cleanUp();
sensorObj = null;
console.log("Exiting...");
process.exit(0);

57
examples/python/ds2413.py Normal file
View File

@ -0,0 +1,57 @@
#!/usr/bin/python
# Author: Jon Trulson <jtrulson@ics.com>
# Copyright (c) 2015 Intel Corporation.
#
# 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.
import time, sys, signal, atexit
import pyupm_ds2413 as sensorObj
# Instantiate a DS2413 Module on a Dallas 1-wire bus connected to UART 0
sensor = sensorObj.DS2413(0)
## Exit handlers ##
# This stops python from printing a stacktrace when you hit control-C
def SIGINTHandler(signum, frame):
raise SystemExit
# This function lets you run code on exit
def exitHandler():
print "Exiting..."
sys.exit(0)
# Register exit handlers
atexit.register(exitHandler)
signal.signal(signal.SIGINT, SIGINTHandler)
# find all of the DS2413 devices present on the bus
sensor.init();
# how many devices were found?
print "Found", sensor.devicesFound(), "device(s)"
# read the gpio and latch values from the first device
# the lower 4 bits are of the form:
# <gpioB latch> <gpioB value> <gpioA latch> <gpioA value>
print "GPIO device 0 values:", sensor.readGpios(0)
# set the gpio latch values of the first device
print "Setting GPIO latches to on"
sensor.writeGpios(0, 0x03);

View File

@ -0,0 +1,5 @@
set (libname "ds2413")
set (libdescription "upm DS2413 1-wire Dual Channel Addressable Switch module")
set (module_src ${libname}.cxx)
set (module_h ${libname}.h)
upm_module_init()

165
src/ds2413/ds2413.cxx Normal file
View File

@ -0,0 +1,165 @@
/*
* Author: Jon Trulson <jtrulson@ics.com>
* Copyright (c) 2016 Intel Corporation.
*
* 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 <iostream>
#include <time.h>
#include <stdexcept>
#include "ds2413.h"
using namespace upm;
using namespace std;
DS2413::DS2413(int uart) :
m_uart(uart)
{
m_devicesFound = 0;
// check basic access to the 1-wire bus (presence detect)
mraa::Result rv;
if ((rv = m_uart.reset()) != mraa::SUCCESS)
{
throw std::runtime_error(std::string(__FUNCTION__) +
": reset() failed, no devices on bus?");
return;
}
}
DS2413::~DS2413()
{
}
void DS2413::init()
{
// iterate through the bus and build up a list of detected DS2413
// devices (only)
// empty the map, in case this method has already been run once
// before
m_devicesFound = 0;
m_deviceMap.clear();
// start the search from scratch
string id = m_uart.search(true);
if (id.empty())
{
throw std::runtime_error(std::string(__FUNCTION__) +
": no devices detected on bus");
return;
}
while (!id.empty())
{
// The first byte (id[0]]) is the device type (family) code. We
// are only interested in the family code for this device (0x3a).
if ((uint8_t)id[0] == DS2413_FAMILY_CODE)
{
// we have a winner, add it to our map and continue searching
m_deviceMap[m_devicesFound] = id;
m_devicesFound++;
}
// continue search
id = m_uart.search(false);
}
if (!m_devicesFound)
{
throw std::runtime_error(std::string(__FUNCTION__) +
": no DS2413 devices found on bus");
return;
}
}
int DS2413::readGpios(int index)
{
if (index < 0 || index >= m_devicesFound)
{
throw std::out_of_range(std::string(__FUNCTION__) +
": device index out of range");
return 0;
}
m_uart.command(ACCESS_READ, m_deviceMap[index]);
uint8_t value = m_uart.readByte();
// Validity is performed by taking the high nibble, inverting it, and
// copmpating it to the low nibble. If they are equal, then the
// data is good.
if ( (value & 0x0f) != ((~value >> 4) & 0x0f) )
{
throw std::runtime_error(std::string(__FUNCTION__) +
": returned value failed integrity check");
return 0;
}
m_uart.reset();
// Only the 4 lsb's are relevant
return (value & 0x0f);
}
void DS2413::writeGpios(int index, int value)
{
if (index < 0 || index >= m_devicesFound)
{
throw std::out_of_range(std::string(__FUNCTION__) +
": device index out of range");
return;
}
// mask out everything but the first 2 bits
uint8_t val = (uint8_t)value & 0x03;
// the value must have the upper 8 bits written set to 1's
val |= 0xfc;
m_uart.command(ACCESS_WRITE, m_deviceMap[index]);
// first we write the new value, then the inverted value
m_uart.writeByte(val);
m_uart.writeByte(~val);
// now we read back a response indicating success or failure
uint8_t resp = m_uart.readByte();
if (resp != ACK_SUCCESS)
{
throw std::runtime_error(std::string(__FUNCTION__) +
": failed response validation");
return;
}
m_uart.reset();
return;
}

175
src/ds2413/ds2413.h Normal file
View File

@ -0,0 +1,175 @@
/*
* Author: Jon Trulson <jtrulson@ics.com>
* Copyright (c) 2016 Intel Corporation.
*
* 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.
*/
#pragma once
#include <string>
#include <iostream>
#include <map>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <mraa/common.hpp>
#include <mraa/uart_ow.hpp>
#define DS2413_DEFAULT_UART 0
namespace upm {
/**
* @brief DS2413 modules
* @defgroup ds2413 libupm-ds2413
* @ingroup maxim uart gpio
*/
/**
* @library ds2413
* @sensor ds2413
* @comname DS2413 1-Wire Dual Channel Addressable Switch
* @type gpio
* @man maxim
* @con uart
* @web https://learn.adafruit.com/adafruit-1-wire-gpio-breakout-ds2413/overview
*
* @brief API for the DS2413 1-Wire Dual Channel Addressable Switch
*
* The DS2413 is a dual-channel programmable I/O 1-Wire® chip. The
* PIO outputs are configured as open-drain and provide up to 20mA
* continuous sink capability and off-state operating voltage up
* to 28V. Control and sensing of the PIO pins is performed with
* a dedicated device-level command protocol.
*
* This device requires the use of a UART to provide access to a
* Dallas 1-wire bus, via a new facility supported by MRAA (once
* the relevant PR is accepted), using the UartOW access class.
* It is important to realize that the UART is only being used to
* access and control a Dallas 1-wire compliant bus, it is not
* actually a UART device.
*
* Multiple DS2413 devices can be connected to this bus. This
* module will identify all such devices connected, and allow you
* to access them using an index starting at 0.
*
* @snippet ds2413.cxx Interesting
*/
class DS2413 {
public:
// The family code for these devices. We handle all of them that
// are found on the bus.
static const uint8_t DS2413_FAMILY_CODE = 0x3a;
// commands
typedef enum {
ACCESS_READ = 0xf5,
ACCESS_WRITE = 0x5a
} DS2413_CMD_T;
// possible ack responses for gpio writes
typedef enum {
ACK_SUCCESS = 0xaa,
ACK_FAILURE = 0xff
} DS2413_ACK_T;
/**
* DS2413 object constructor
*
* @param uart Default UART to use (0 or 1). Default is 0.
*/
DS2413(int uart=DS2413_DEFAULT_UART);
/**
* DS2413 object destructor
*/
~DS2413();
/**
* This method will search the 1-wire bus and store information on
* each device detected on the bus. If no devices are found, an
* exception is thrown. Once this function completes
* successfully, you can use devicesFound() to determine how many
* devices were detected.
*/
void init();
/**
* This method will return the number of DS2413 devices that were
* found on the bus.
*
* @return number of DS2413's that were found on the bus
*/
int devicesFound()
{
return m_devicesFound;
}
/**
* Read the GPIO latches and values for a given device. Only the
* lower 4 bits of the return value have any meaning. The bits
* are formatted as follows (from msb to lsb):
* <gpioB latch> <gpioB value> <gpioA latch> <gpioA value>
*
* @param index The device index to access (starts at 0). Default
* is the first device (index = 0)
* @return the 4 bit status of the 2 gpios
*/
int readGpios(int index=0);
/**
* Write the given values to the gpio latches for a given device.
* Only the lower 2 bits of the value have any meaning. The lsb
* is gor gpioA and the next lsb is for gpioB:
* <gpioB latch> <gpioA latch>
*
* @param index The device index to access (starts at 0).
* @param value the value to write to the gpio latches
*/
void writeGpios(int index, int value);
/**
* Return an 8 byte string representing the unique device ID for a
* given device index. If the index is invalid, an empty strig
* will be returned.
*
* @param index The device index to access (starts at 0).
* @return 8 byte string representing the 1-wire device's unique
* rom code.
*/
std::string getId(int index)
{
return m_deviceMap[index];
}
protected:
mraa::UartOW m_uart;
// the total number of devices found
int m_devicesFound;
std::map<int, std::string> m_deviceMap;
private:
};
}

View File

@ -0,0 +1,22 @@
%module javaupm_ds2413
%include "../upm.i"
%include "carrays.i"
%include "std_string.i"
%{
#include "ds2413.h"
%}
%include "ds2413.h"
%array_class(char, charArray);
%pragma(java) jniclasscode=%{
static {
try {
System.loadLibrary("javaupm_ds2413");
} catch (UnsatisfiedLinkError e) {
System.err.println("Native code library failed to load. \n" + e);
System.exit(1);
}
}
%}

11
src/ds2413/jsupm_ds2413.i Normal file
View File

@ -0,0 +1,11 @@
%module jsupm_ds2413
%include "../upm.i"
%include "carrays.i"
%include "std_string.i"
%{
#include "ds2413.h"
%}
%include "ds2413.h"
%array_class(char, charArray);

12
src/ds2413/pyupm_ds2413.i Normal file
View File

@ -0,0 +1,12 @@
%module pyupm_ds2413
%include "../upm.i"
%include "carrays.i"
%include "std_string.i"
%feature("autodoc", "3");
%{
#include "ds2413.h"
%}
%include "ds2413.h"
%array_class(char, charArray);