/* * Author: Jon Trulson * 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 #include 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 * * @param uart the index of the uart to use * @throws std::invalid_argument in case of error */ 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. * * @param path the file path for the UART to use * @throws std::invalid_argument in case of error */ 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()) 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.data()); } } /** * 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.data(), buffer.size()); } private: mraa_uart_ow_context m_uart; }; }