]> the.earth.li Git - temper-clone.git/blob - w1.c
Remove unused read_temp() function
[temper-clone.git] / w1.c
1 /*
2  * Basic routines to bit-bang standard 1-Wire via a GPIO pin
3  *
4  * Copyright 2018 Jonathan McDowell <noodles@earth.li>
5  *
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.
10  *
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.
15  *
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/>.
18  */
19 #include <stdbool.h>
20 #include <avr/io.h>
21 #include <util/atomic.h>
22 #include <util/delay.h>
23
24 #include "w1.h"
25
26 uint8_t w1_crc(uint8_t *buf, uint8_t len)
27 {
28         uint8_t i, j, crc;
29
30         crc = 0;
31         for (i = 0; i < len; i++)
32         {
33                 crc ^= buf[i];
34                 for (j = 0; j < 8; j++)
35                 {
36                         crc = crc >> 1 ^ ((crc & 1) ? 0x8c : 0);
37                 }
38         }
39
40         return crc;
41 }
42
43 void w1_write(uint8_t val)
44 {
45         uint8_t i;
46
47         for (i = 0; i < 8; i++) {
48                 ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
49                 {
50                         /* Pull low for 6µs for 1, 60µs for 0 */
51                         DDRB |= 1 << W1_PIN;
52                         if (val & 1)
53                                 _delay_us(6);
54                         else
55                                 _delay_us(60);
56                         /* Release to make up to 70µs total */
57                         DDRB &= ~(1 << W1_PIN);
58                         if (val & 1)
59                                 _delay_us(64);
60                         else
61                                 _delay_us(10);
62                 }
63
64                 val >>= 1;
65         }
66 }
67
68 bool w1_read_bit()
69 {
70         bool val;
71
72         ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
73         {
74                 /* Pull low for 6µs */
75                 DDRB |= 1 << W1_PIN;
76                 _delay_us(6);
77                 /* Release for 9µs */
78                 DDRB &= ~(1 << W1_PIN);
79                 _delay_us(9);
80
81                 /* Read the line state */
82                 val = ((PINB >> W1_PIN) & 1);
83         }
84         _delay_us(55);
85
86         return val;
87 }
88
89 uint8_t w1_read_byte()
90 {
91         uint8_t i, val;
92
93         val = 0;
94         for (i = 0; i < 8; i++) {
95                 if (w1_read_bit())
96                         val |= (1 << i);
97         }
98
99         return val;
100 }
101
102 void w1_read(uint8_t *buf, uint8_t len)
103 {
104         uint8_t i;
105
106         for (i = 0; i < len; i++) {
107                 buf[i] = w1_read_byte();
108         }
109 }
110
111 bool w1_reset(void)
112 {
113         bool present;
114
115         /* Pull low for 480µs */
116         DDRB |= 1 << W1_PIN;
117         _delay_us(480);
118         /* Release for 70µs */
119         DDRB &= ~(1 << W1_PIN);
120         _delay_us(70);
121
122         /* If there's a device present it'll have pulled the line low */
123         present = !((PINB >> W1_PIN) & 1);
124
125         /* Wait for reset to complete */
126         _delay_us(410);
127
128         return present;
129 }
130
131 void w1_setup(void)
132 {
133         /* Set 1w pin to low */
134         PORTB &= (1 << W1_PIN);
135 }