|
1 /* |
|
2 * MIT License |
|
3 * |
|
4 * Copyright (c) 2017 David Antliff |
|
5 * Copyright (c) 2017 Chris Morgan <chmorgan@gmail.com> |
|
6 * |
|
7 * Permission is hereby granted, free of charge, to any person obtaining a copy |
|
8 * of this software and associated documentation files (the "Software"), to deal |
|
9 * in the Software without restriction, including without limitation the rights |
|
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|
11 * copies of the Software, and to permit persons to whom the Software is |
|
12 * furnished to do so, subject to the following conditions: |
|
13 * |
|
14 * The above copyright notice and this permission notice shall be included in all |
|
15 * copies or substantial portions of the Software. |
|
16 * |
|
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
|
23 * SOFTWARE. |
|
24 */ |
|
25 |
|
26 /** |
|
27 * @file |
|
28 * @brief Interface definitions for the 1-Wire bus component. |
|
29 * |
|
30 * This component provides structures and functions that are useful for communicating |
|
31 * with devices connected to a Maxim Integrated 1-Wire® bus via a single GPIO. |
|
32 * |
|
33 * Currently only externally powered devices are supported. Parasitic power is not supported. |
|
34 */ |
|
35 |
|
36 #ifndef ONE_WIRE_BUS_H |
|
37 #define ONE_WIRE_BUS_H |
|
38 |
|
39 #include <stdint.h> |
|
40 #include <stdbool.h> |
|
41 #include <stddef.h> |
|
42 |
|
43 #ifdef __cplusplus |
|
44 extern "C" { |
|
45 #endif |
|
46 |
|
47 |
|
48 // ROM commands |
|
49 #define OWB_ROM_SEARCH 0xF0 ///< Command ROM search |
|
50 #define OWB_ROM_READ 0x33 ///< ROM read |
|
51 #define OWB_ROM_MATCH 0x55 ///< ROM address match |
|
52 #define OWB_ROM_SKIP 0xCC ///< Skip device |
|
53 #define OWB_ROM_SEARCH_ALARM 0xEC ///< Search device with alarm set |
|
54 |
|
55 #define OWB_ROM_CODE_STRING_LENGTH (17) ///< Typical length of OneWire bus ROM ID as ASCII hex string, including null terminator |
|
56 |
|
57 struct owb_driver; |
|
58 |
|
59 /** |
|
60 * @brief Structure containing 1-Wire bus information relevant to a single instance. |
|
61 */ |
|
62 typedef struct |
|
63 { |
|
64 const struct _OneWireBus_Timing * timing; ///< Pointer to timing information |
|
65 bool use_crc; ///< True if CRC checks are to be used when retrieving information from a device on the bus |
|
66 |
|
67 const struct owb_driver *driver; |
|
68 } OneWireBus; |
|
69 |
|
70 /** |
|
71 * @brief Represents a 1-Wire ROM Code. This is a sequence of eight bytes, where |
|
72 * the first byte is the family number, then the following 6 bytes form the |
|
73 * serial number. The final byte is the CRC8 check byte. |
|
74 */ |
|
75 typedef union |
|
76 { |
|
77 /// Provides access via field names |
|
78 struct fields |
|
79 { |
|
80 uint8_t family[1]; ///< family identifier (1 byte, LSB - read/write first) |
|
81 uint8_t serial_number[6]; ///< serial number (6 bytes) |
|
82 uint8_t crc[1]; ///< CRC check byte (1 byte, MSB - read/write last) |
|
83 } fields; ///< Provides access via field names |
|
84 |
|
85 uint8_t bytes[8]; ///< Provides raw byte access |
|
86 |
|
87 } OneWireBus_ROMCode; |
|
88 |
|
89 /** |
|
90 * @brief Represents the state of a device search on the 1-Wire bus. |
|
91 * |
|
92 * Pass a pointer to this structure to owb_search_first() and |
|
93 * owb_search_next() to iterate through detected devices on the bus. |
|
94 */ |
|
95 typedef struct |
|
96 { |
|
97 OneWireBus_ROMCode rom_code; |
|
98 int last_discrepancy; |
|
99 int last_family_discrepancy; |
|
100 int last_device_flag; |
|
101 } OneWireBus_SearchState; |
|
102 |
|
103 /** |
|
104 * @brief Status codes |
|
105 */ |
|
106 typedef enum |
|
107 { |
|
108 OWB_STATUS_OK, ///< Ok |
|
109 OWB_STATUS_NOT_INITIALIZED, ///< Init error |
|
110 OWB_STATUS_PARAMETER_NULL, ///< NULL parameter |
|
111 OWB_STATUS_DEVICE_NOT_RESPONDING, ///< Device does not respond |
|
112 OWB_STATUS_CRC_FAILED, ///< CRC error |
|
113 OWB_STATUS_TOO_MANY_BITS, ///< Too many bits |
|
114 OWB_STATUS_HW_ERROR ///< Hardware error |
|
115 } owb_status; |
|
116 |
|
117 /** NOTE: Driver assumes that (*init) was called prior to any other methods */ |
|
118 struct owb_driver |
|
119 { |
|
120 const char* name; |
|
121 |
|
122 owb_status (*uninitialize)(const OneWireBus * bus); |
|
123 |
|
124 owb_status (*reset)(const OneWireBus * bus, bool *is_present); |
|
125 |
|
126 /** NOTE: The data is shifted out of the low bits, eg. it is written in the order of lsb to msb */ |
|
127 owb_status (*write_bits)(const OneWireBus *bus, uint8_t out, int number_of_bits_to_write); |
|
128 |
|
129 /** NOTE: Data is read into the high bits, eg. each bit read is shifted down before the next bit is read */ |
|
130 owb_status (*read_bits)(const OneWireBus *bus, uint8_t *in, int number_of_bits_to_read); |
|
131 }; |
|
132 |
|
133 #define container_of(ptr, type, member) ({ \ |
|
134 const typeof( ((type *)0)->member ) *__mptr = (ptr); \ |
|
135 (type *)( (char *)__mptr - offsetof(type,member) );}) |
|
136 |
|
137 /** |
|
138 * @brief call to release resources after completing use of the OneWireBus |
|
139 * @param[in] bus Pointer to initialised bus instance. |
|
140 * @return status |
|
141 */ |
|
142 owb_status owb_uninitialize(OneWireBus * bus); |
|
143 |
|
144 /** |
|
145 * @brief Enable or disable use of CRC checks on device communications. |
|
146 * @param[in] bus Pointer to initialised bus instance. |
|
147 * @param[in] use_crc True to enable CRC checks, false to disable. |
|
148 * @return status |
|
149 */ |
|
150 owb_status owb_use_crc(OneWireBus * bus, bool use_crc); |
|
151 |
|
152 /** |
|
153 * @brief Read ROM code from device - only works when there is a single device on the bus. |
|
154 * @param[in] bus Pointer to initialised bus instance. |
|
155 * @param[out] rom_code the value read from the device's rom |
|
156 * @return status |
|
157 */ |
|
158 owb_status owb_read_rom(const OneWireBus * bus, OneWireBus_ROMCode *rom_code); |
|
159 |
|
160 /** |
|
161 * @brief Verify the device specified by ROM code is present. |
|
162 * @param[in] bus Pointer to initialised bus instance. |
|
163 * @param[in] rom_code ROM code to verify. |
|
164 * @param[out] is_present set to true if a device is present, false if not |
|
165 * @return status |
|
166 */ |
|
167 owb_status owb_verify_rom(const OneWireBus * bus, OneWireBus_ROMCode rom_code, bool* is_present); |
|
168 |
|
169 /** |
|
170 * @brief Reset the 1-Wire bus. |
|
171 * @param[in] bus Pointer to initialised bus instance. |
|
172 * @param[out] a_device_present set to true if at least one device is present on the bus |
|
173 * @return status |
|
174 */ |
|
175 owb_status owb_reset(const OneWireBus * bus, bool* a_device_present); |
|
176 |
|
177 /** |
|
178 * @brief Write a single byte to the 1-Wire bus. |
|
179 * @param[in] bus Pointer to initialised bus instance. |
|
180 * @param[in] data Byte value to write to bus. |
|
181 * @return status |
|
182 */ |
|
183 owb_status owb_write_byte(const OneWireBus * bus, uint8_t data); |
|
184 |
|
185 /** |
|
186 * @brief Read a single byte from the 1-Wire bus. |
|
187 * @param[in] bus Pointer to initialised bus instance. |
|
188 * @param[out] out The byte value read from the bus. |
|
189 * @return status |
|
190 */ |
|
191 owb_status owb_read_byte(const OneWireBus * bus, uint8_t *out); |
|
192 |
|
193 /** |
|
194 * @brief Read a number of bytes from the 1-Wire bus. |
|
195 * @param[in] bus Pointer to initialised bus instance. |
|
196 * @param[in, out] buffer Pointer to buffer to receive read data. |
|
197 * @param[in] len Number of bytes to read, must not exceed length of receive buffer. |
|
198 * @return status. |
|
199 */ |
|
200 owb_status owb_read_bytes(const OneWireBus * bus, uint8_t * buffer, size_t len); |
|
201 |
|
202 /** |
|
203 * @brief Write a number of bytes to the 1-Wire bus. |
|
204 * @param[in] bus Pointer to initialised bus instance. |
|
205 * @param[in] buffer Pointer to buffer to write data from. |
|
206 * @param[in] len Number of bytes to write. |
|
207 * @return status |
|
208 */ |
|
209 owb_status owb_write_bytes(const OneWireBus * bus, const uint8_t * buffer, size_t len); |
|
210 |
|
211 /** |
|
212 * @brief Write a ROM code to the 1-Wire bus ensuring LSB is sent first. |
|
213 * @param[in] bus Pointer to initialised bus instance. |
|
214 * @param[in] rom_code ROM code to write to bus. |
|
215 * @return status |
|
216 */ |
|
217 owb_status owb_write_rom_code(const OneWireBus * bus, OneWireBus_ROMCode rom_code); |
|
218 |
|
219 /** |
|
220 * @brief 1-Wire 8-bit CRC lookup. |
|
221 * @param[in] crc Starting CRC value. Pass in prior CRC to accumulate. |
|
222 * @param[in] data Byte to feed into CRC. |
|
223 * @return Resultant CRC value. |
|
224 * Should be zero if last byte was the CRC byte and the CRC matches. |
|
225 */ |
|
226 uint8_t owb_crc8_byte(uint8_t crc, uint8_t data); |
|
227 |
|
228 /** |
|
229 * @brief 1-Wire 8-bit CRC lookup with accumulation over a block of bytes. |
|
230 * @param[in] crc Starting CRC value. Pass in prior CRC to accumulate. |
|
231 * @param[in] data Array of bytes to feed into CRC. |
|
232 * @param[in] len Length of data array in bytes. |
|
233 * @return Resultant CRC value. |
|
234 * Should be zero if last byte was the CRC byte and the CRC matches. |
|
235 */ |
|
236 uint8_t owb_crc8_bytes(uint8_t crc, const uint8_t * data, size_t len); |
|
237 |
|
238 /** |
|
239 * @brief Locates the first device on the 1-Wire bus, if present. |
|
240 * @param[in] bus Pointer to initialised bus instance. |
|
241 * @param[in,out] state Pointer to an existing search state structure. |
|
242 * @param[out] found_device True if a device is found, false if no devices are found. |
|
243 * If a device is found, the ROM Code can be obtained from the state. |
|
244 * @return status |
|
245 */ |
|
246 owb_status owb_search_first(const OneWireBus * bus, OneWireBus_SearchState * state, bool *found_device); |
|
247 |
|
248 /** |
|
249 * @brief Locates the next device on the 1-Wire bus, if present, starting from |
|
250 * the provided state. Further calls will yield additional devices, if present. |
|
251 * @param[in] bus Pointer to initialised bus instance. |
|
252 * @param[in,out] state Pointer to an existing search state structure. |
|
253 * @param[out] found_device True if a device is found, false if no devices are found. |
|
254 * If a device is found, the ROM Code can be obtained from the state. |
|
255 * @return status |
|
256 */ |
|
257 owb_status owb_search_next(const OneWireBus * bus, OneWireBus_SearchState * state, bool *found_device); |
|
258 |
|
259 /** |
|
260 * @brief Create a string representation of a ROM code, most significant byte (CRC8) first. |
|
261 * @param[in] rom_code The ROM code to convert to string representation. |
|
262 * @param[out] buffer The destination for the string representation. It will be null terminated. |
|
263 * @param[in] len The length of the buffer in bytes. 64-bit ROM codes require 16 characters |
|
264 * to represent as a string, plus a null terminator, for 17 bytes. |
|
265 * See OWB_ROM_CODE_STRING_LENGTH. |
|
266 * @return pointer to the byte beyond the last byte written |
|
267 */ |
|
268 char * owb_string_from_rom_code(OneWireBus_ROMCode rom_code, char * buffer, size_t len); |
|
269 |
|
270 #include "owb_gpio.h" |
|
271 #include "owb_rmt.h" |
|
272 |
|
273 #ifdef __cplusplus |
|
274 } |
|
275 #endif |
|
276 |
|
277 #endif // ONE_WIRE_BUS_H |