2 * Basic routines to bit-bang standard 1-Wire via a GPIO pin
4 * Copyright 2018 Jonathan McDowell <noodles@earth.li>
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include <util/atomic.h>
22 #include <util/delay.h>
26 uint8_t w1_crc(uint8_t *buf, uint8_t len)
31 for (i = 0; i < len; i++)
34 for (j = 0; j < 8; j++)
36 crc = crc >> 1 ^ ((crc & 1) ? 0x8c : 0);
43 void w1_write(uint8_t val)
47 for (i = 0; i < 8; i++) {
48 ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
50 /* Pull low for 6µs for 1, 60µs for 0 */
56 /* Release to make up to 70µs total */
57 DDRB &= ~(1 << W1_PIN);
68 uint8_t w1_read_byte()
73 for (i = 0; i < 8; i++) {
74 ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
76 /* Pull low for 6µs */
80 DDRB &= ~(1 << W1_PIN);
83 /* Read the line state */
84 val |= ((PINB >> W1_PIN) & 1) << i;
93 void w1_read(uint8_t *buf, uint8_t len)
97 for (i = 0; i < len; i++) {
98 buf[i] = w1_read_byte();
106 /* Pull low for 480µs */
109 /* Release for 70µs */
110 DDRB &= ~(1 << W1_PIN);
113 /* If there's a device present it'll have pulled the line low */
114 present = !((PINB >> W1_PIN) & 1);
116 /* Wait for reset to complete */
124 /* Set 1w pin to low */
125 PORTB &= (1 << W1_PIN);