278 lines
8.0 KiB
C++
278 lines
8.0 KiB
C++
/*
|
|
* 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 "uart_ow.h"
|
|
#include "types.hpp"
|
|
#include <stdexcept>
|
|
#include <cstring>
|
|
|
|
namespace mraa
|
|
{
|
|
|
|
/**
|
|
* @brief API for UART One Wire
|
|
*
|
|
* This file defines the UartOW (UART to Dallas 1-wire) interface for libmraa
|
|
*
|
|
* @snippet UartOW.cpp Interesting
|
|
*/
|
|
class UartOW
|
|
{
|
|
public:
|
|
/**
|
|
* UartOW Constructor, takes a pin number which will map directly to the
|
|
* linux uart number, this 'enables' the uart, nothing more
|
|
*
|
|
* @throws std::invalid_argument in case of error
|
|
* @param uart the index of the uart to use
|
|
*/
|
|
UartOW(int uart)
|
|
{
|
|
m_uart = mraa_uart_ow_init(uart);
|
|
|
|
if (m_uart == NULL) {
|
|
throw std::invalid_argument("Error initialising UART_OW");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* UartOW Constructor, takes a string to the path of the serial
|
|
* interface that is needed.
|
|
*
|
|
* @throws std::invalid_argument in case of error
|
|
* @param path the file path for the UART to use
|
|
*/
|
|
UartOW(std::string path)
|
|
{
|
|
m_uart = mraa_uart_ow_init_raw(path.c_str());
|
|
|
|
if (m_uart == NULL) {
|
|
throw std::invalid_argument("Error initialising UART");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Uart destructor
|
|
*/
|
|
~UartOW()
|
|
{
|
|
mraa_uart_ow_stop(m_uart);
|
|
}
|
|
|
|
/**
|
|
* Get string with tty device path within Linux
|
|
* For example. Could point to "/dev/ttyS0"
|
|
*
|
|
* @return char pointer of device path
|
|
*/
|
|
std::string
|
|
getDevicePath()
|
|
{
|
|
std::string ret_val(mraa_uart_ow_get_dev_path(m_uart));
|
|
return ret_val;
|
|
}
|
|
|
|
/**
|
|
* Read a byte from the 1-wire bus
|
|
*
|
|
* @throws std::invalid_argument in case of error
|
|
* @return the byte read
|
|
*/
|
|
uint8_t
|
|
readByte()
|
|
{
|
|
int res = mraa_uart_ow_read_byte(m_uart);
|
|
if (res == -1) {
|
|
throw std::invalid_argument("Unknown UART_OW error");
|
|
}
|
|
return (uint8_t) res;
|
|
}
|
|
|
|
/**
|
|
* Write a byte to a 1-wire bus
|
|
*
|
|
* @param byte the byte to write to the bus
|
|
*
|
|
* @throws std::invalid_argument in case of error
|
|
* @return the byte read back during the time slot
|
|
*/
|
|
uint8_t
|
|
writeByte(uint8_t byte)
|
|
{
|
|
int res = mraa_uart_ow_write_byte(m_uart, byte);
|
|
if (res == -1) {
|
|
throw std::invalid_argument("Unknown UART_OW error");
|
|
}
|
|
return (uint8_t) res;
|
|
}
|
|
|
|
/**
|
|
* Write a bit to a 1-wire bus and read a bit corresponding to the
|
|
* time slot back. This is possible due to the way we wired the TX
|
|
* and RX together with a diode, forming a loopback.
|
|
*
|
|
* @param bit the bit to write to the bus
|
|
* @throws std::invalid_argument in case of error
|
|
* @return the bit read back during the time slot
|
|
*/
|
|
bool
|
|
writeBit(bool bit)
|
|
{
|
|
int res = mraa_uart_ow_bit(m_uart, (bit) ? 1 : 0);
|
|
if (res == -1) {
|
|
throw std::invalid_argument("Unknown UART_OW error");
|
|
}
|
|
return ((res) ? true : false);
|
|
}
|
|
|
|
/**
|
|
* Send a reset pulse to the 1-wire bus and test for device presence
|
|
*
|
|
* @return one of the mraa::Result values
|
|
*/
|
|
mraa::Result
|
|
reset()
|
|
{
|
|
return (mraa::Result) mraa_uart_ow_reset(m_uart);
|
|
}
|
|
|
|
/**
|
|
* Begin a rom code search of the 1-wire bus. This function
|
|
* implements the 1-wire search algorithm. See the uart_ow.c example
|
|
* for an idea on how to use this function to identify all devices
|
|
* present on the bus.
|
|
*
|
|
* @param start true to start a search from scratch, false to
|
|
* continue a previously started search
|
|
* @param id the 8-byte rom code id of the current matched device when a
|
|
* device is found
|
|
* @return one of the mraa::Result values
|
|
*/
|
|
mraa::Result
|
|
search(bool start, uint8_t* id)
|
|
{
|
|
return (mraa::Result) mraa_uart_ow_rom_search(m_uart, (start) ? 1 : 0, id);
|
|
}
|
|
|
|
/**
|
|
* Begin a rom code search of the 1-wire bus. This function
|
|
* implements the 1-wire search algorithm. See the UartOW.cpp
|
|
* example for an idea on how to use this function to identify all
|
|
* devices present on the bus.
|
|
*
|
|
* @param start true to start a search from scratch, false to
|
|
* continue a previously started search
|
|
* @return an empty string if no [more] devices are found, or a
|
|
* string containing the 8-byte romcode of a detected device.
|
|
*/
|
|
std::string
|
|
search(bool start)
|
|
{
|
|
uint8_t id[MRAA_UART_OW_ROMCODE_SIZE];
|
|
mraa_result_t rv;
|
|
|
|
rv = mraa_uart_ow_rom_search(m_uart, (start) ? 1 : 0, id);
|
|
|
|
if (rv == MRAA_SUCCESS) {
|
|
// we found one
|
|
std::string idStr((char*) id, MRAA_UART_OW_ROMCODE_SIZE);
|
|
return idStr;
|
|
} else {
|
|
// failure, or end of search
|
|
return "";
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Send a command byte to a device on the 1-wire bus
|
|
*
|
|
* @param command the command byte to send
|
|
* @param id the rom code id of the device to receive the command,
|
|
* NULL for all devices on the bus
|
|
* @return one of the mraa::Result values
|
|
*/
|
|
mraa::Result
|
|
command(uint8_t command, uint8_t* id)
|
|
{
|
|
return (mraa::Result) mraa_uart_ow_command(m_uart, command, id);
|
|
}
|
|
|
|
/**
|
|
* Send a command byte to a device on the 1-wire bus, supplying
|
|
* the id as a std::string
|
|
*
|
|
* @param command the command byte to send
|
|
* @param id std::string representing the code id of the device to
|
|
* receive the command, or an empty string for all devices on the
|
|
* bus. This string should be 8 bytes in size.
|
|
* @return one of the mraa::Result values
|
|
*/
|
|
mraa::Result
|
|
command(uint8_t command, std::string id)
|
|
{
|
|
if (id.empty() == 0)
|
|
return (mraa::Result) mraa_uart_ow_command(m_uart, command, NULL);
|
|
else {
|
|
if (id.size() != 8) {
|
|
// Only 8 byte romcodes are legal.
|
|
throw std::invalid_argument(std::string(__FUNCTION__) +
|
|
": id must be 8 bytes only");
|
|
}
|
|
return (mraa::Result) mraa_uart_ow_command(m_uart, command, (uint8_t*) id.c_str());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Perform a Dallas 1-wire compliant CRC8 computation on a buffer
|
|
*
|
|
* @param buffer the buffer containing the data
|
|
* @param length the length of the buffer
|
|
* @return the computed CRC
|
|
*/
|
|
uint8_t
|
|
crc8(uint8_t* buffer, uint16_t length)
|
|
{
|
|
return mraa_uart_ow_crc8(buffer, length);
|
|
}
|
|
|
|
/**
|
|
* Perform a Dallas 1-wire compliant CRC8 computation on a
|
|
* std::string based buffer
|
|
*
|
|
* @param buffer std::string buffer containing the data
|
|
* @return the computed CRC
|
|
*/
|
|
uint8_t
|
|
crc8(std::string buffer)
|
|
{
|
|
return mraa_uart_ow_crc8((uint8_t*) buffer.c_str(), buffer.size());
|
|
}
|
|
|
|
private:
|
|
mraa_uart_ow_context m_uart;
|
|
};
|
|
}
|