/* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ /** library for 1-wire protocol as master * @file * @author King Kévin * @date 2017-2018 * @note peripherals used: timer @ref onewire_master_timer, GPIO @ref onewire_master_gpio * @note overdrive mode is not provided */ #pragma once /** @defgroup onewire_master_gpio GPIO used for 1-wire signal * @note external pull-up resistor on pin is required (< 5 kOhm) * @{ */ #define ONEWIRE_MASTER_PORT C /**< GPIO port */ #define ONEWIRE_MASTER_PIN 9 /**< GPIO pin */ /** @} */ /** setup 1-wire peripheral */ void onewire_master_setup(void); /** release 1-wire peripheral */ void onewire_master_release(void); /** send reset pulse * @return if slaves have indicated their presence */ bool onewire_master_reset(void); /** compute CRC for 1-Wire * @note this CRC-8 uses normal polynomial 0x31, reverse polynomial 0x8C, start value 0x00 * @param[in] data bytes on which to calculate CRC checksum on * @param[in] length number of bytes in data * @return computed CRC checksum */ uint8_t onewire_master_crc(uint8_t* data, uint32_t length); /** send READ ROM command and read ROM code response * @note user needs to send reset pulse before * @return ROM code read */ uint64_t onewire_master_rom_read(void); /** send SEARCH ROM command * @note user needs to send reset pulse before * @warning undefined behaviour if a ROM code different than the last found is provided * @param[in,out] code use 0 to start search ROM code from scratch, or last know value to search next; writes back next ROM code found, or 0 if error occurred * @param[in] alarm search only for ROM codes for slaves with an alarm flag set * @return if an additional slave has been detected * @warning when the code found is 0 it very probably means that the 1-wire line is not pulled up instead of actually having found a slave with ROM code 0 */ bool onewire_master_rom_search(uint64_t* code, bool alarm); /** send SKIP ROM command (all slaves on the bus will be selected) * @note user needs to send reset pulse before * @return if operation succeeded */ bool onewire_master_rom_skip(void); /** send MATCH ROM command to select a specific slave * @note user needs to send reset pulse before * @param[in] code ROM code of slave to select * @return if operation succeeded */ bool onewire_master_rom_match(uint64_t code); /** read data byte * @note it is up to the user to send the reset pulse * @param[out] data buffer to save data read * @return if operation succeeded */ bool onewire_master_read_byte(uint8_t* data); /** write data byte * @note it is up to the user to send the reset pulse * @param[in] data byte to write * @return if operation succeeded */ bool onewire_master_write_byte(uint8_t data); /** issue function and read data * @note user needs to send a ROM command before * @param[in] function function command to send * @param[out] data buffer to save read bits (NULL if only the function command should be sent) * @param[in] bits number of bits to read (0 if only the function command should be sent) * @return if operation succeeded */ bool onewire_master_function_read(uint8_t function, uint8_t* data, uint32_t bits); /** issue function and write data * @note user needs to send a ROM command before * @param[in] function function command to send * @param[out] data data to write (NULL if only the function command should be sent) * @param[in] bits number of bits to write (0 if only the function command should be sent) * @return if operation succeeded */ bool onewire_master_function_write(uint8_t function, uint8_t* data, uint32_t bits); /** device corresponding to a family code */ struct onewire_family_code_t { uint8_t code; /**< ROM ID code */ const char* device; /**< device name(s) */ }; /** list of possible devices corresponding to the family code * sources: * - http://owfs.org/index.php?page=family-code-list * - http://owfs.sourceforge.net/family.html * - https://www.maximintegrated.com/en/app-notes/index.mvp/id/155 * - https://github.com/owfs/owfs-doc/wiki/1Wire-Device-List * - IDs seen or reported */ static const struct onewire_family_code_t onewire_family_codes[] = { { .code = 0x01, .device = "DS1990R/DS2401/DS2411/DS2490A", }, { .code = 0x02, .device = "DS1991/DS1425", }, { .code = 0x04, .device = "DS1994/DS2404", }, { .code = 0x05, .device = "DS2405", }, { .code = 0x06, .device = "DS1993", }, { .code = 0x08, .device = "DS1992", }, { .code = 0x09, .device = "DS1982/DS2502/DS2703/DS2704", }, { .code = 0x0a, .device = "DS1995", }, { .code = 0x0b, .device = "DS1985/DS2505", }, { .code = 0x0c, .device = "DS1996", }, { .code = 0x0f, .device = "DS1986/DS2506", }, { .code = 0x10, .device = "DS1920/DS18S20", }, { .code = 0x12, .device = "DS2406/DS2407", }, { .code = 0x14, .device = "DS1971/DS2430A", }, { .code = 0x16, .device = "DS1954/DS1957", }, { .code = 0x18, .device = "DS1963S/DS1962", }, { .code = 0x1a, .device = "DS1963L", }, { .code = 0x1b, .device = "DS2436", }, { .code = 0x1c, .device = "DS28E04-100", }, { .code = 0x1d, .device = "DS2423", }, { .code = 0x1e, .device = "DS2437", }, { .code = 0x1f, .device = "DS2409", }, { .code = 0x20, .device = "DS2450", }, { .code = 0x21, .device = "DS1921", }, { .code = 0x22, .device = "DS1922", }, { .code = 0x23, .device = "DS1973/DS2433", }, { .code = 0x24, .device = "DS1904/DS2415", }, { .code = 0x26, .device = "DS2438", }, { .code = 0x27, .device = "DS2417", }, { .code = 0x28, .device = "DS18B20", }, { .code = 0x29, .device = "DS2408", }, { .code = 0x2c, .device = "DS2890", }, { .code = 0x2d, .device = "DS1972/DS2431", }, { .code = 0x2e, .device = "DS2770", }, { .code = 0x2f, .device = "DS28E01-100", }, { .code = 0x30, .device = "DS2760/DS2761/DS2762", }, { .code = 0x31, .device = "DS2720", }, { .code = 0x32, .device = "DS2780", }, { .code = 0x33, .device = "DS1961S/DS2432", }, { .code = 0x34, .device = "DS2703", }, { .code = 0x35, .device = "DS2755", }, { .code = 0x36, .device = "DS2740", }, { .code = 0x37, .device = "DS1977", }, { .code = 0x3a, .device = "DS2413", }, { .code = 0x3b, .device = "DS1825/MAX31826/MAX31850", }, { .code = 0x3d, .device = "DS2781", }, { .code = 0x41, .device = "DS1922/DS1923/DS2422", }, { .code = 0x42, .device = "DS28EA00", }, { .code = 0x43, .device = "DS28EC20", }, { .code = 0x44, .device = "DS28E10", }, { .code = 0x51, .device = "DS2751", }, { .code = 0x7e, .device = "EDS00xx", }, { .code = 0x81, .device = "DS1420/DS2490R/DS2490B", }, { .code = 0x82, .device = "DS1425", }, { .code = 0x84, .device = "DS2404S", }, { .code = 0x89, .device = "DS1982U/DS2502", }, { .code = 0x8b, .device = "DS1985U/DS2505", }, { .code = 0x8f, .device = "DS1986U/DS2506", }, { .code = 0xa0, .device = "mRS001", }, { .code = 0xa1, .device = "mVM001", }, { .code = 0xa2, .device = "mCM001", }, { .code = 0xa6, .device = "mTS017", }, { .code = 0xb1, .device = "mTC001", }, { .code = 0xb2, .device = "mAM001", }, { .code = 0xb3, .device = "DS2432/mTC002", }, { .code = 0xfc, .device = "BAE0910/BAE0911", }, { .code = 0xff, .device = "Swart LCD", } };