1 1.2 ad /* $NetBSD: onewire_bitbang.c,v 1.2 2019/11/30 23:04:12 ad Exp $ */ 2 1.1 riz /* $OpenBSD: onewire_bitbang.c,v 1.1 2006/03/04 16:27:03 grange Exp $ */ 3 1.1 riz 4 1.2 ad /*- 5 1.2 ad * Copyright (c) 2019 The NetBSD Foundation, Inc. 6 1.2 ad * All rights reserved. 7 1.2 ad * 8 1.2 ad * This code is derived from software contributed to The NetBSD Foundation 9 1.2 ad * by Andrew Doran. 10 1.2 ad * 11 1.2 ad * Redistribution and use in source and binary forms, with or without 12 1.2 ad * modification, are permitted provided that the following conditions 13 1.2 ad * are met: 14 1.2 ad * 1. Redistributions of source code must retain the above copyright 15 1.2 ad * notice, this list of conditions and the following disclaimer. 16 1.2 ad * 2. Redistributions in binary form must reproduce the above copyright 17 1.2 ad * notice, this list of conditions and the following disclaimer in the 18 1.2 ad * documentation and/or other materials provided with the distribution. 19 1.2 ad * 20 1.2 ad * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 1.2 ad * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 1.2 ad * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 1.2 ad * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 1.2 ad * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 1.2 ad * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 1.2 ad * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 1.2 ad * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 1.2 ad * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 1.2 ad * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 1.2 ad * POSSIBILITY OF SUCH DAMAGE. 31 1.2 ad */ 32 1.2 ad 33 1.1 riz /* 34 1.1 riz * Copyright (c) 2006 Alexander Yurchenko <grange (at) openbsd.org> 35 1.1 riz * 36 1.1 riz * Permission to use, copy, modify, and distribute this software for any 37 1.1 riz * purpose with or without fee is hereby granted, provided that the above 38 1.1 riz * copyright notice and this permission notice appear in all copies. 39 1.1 riz * 40 1.1 riz * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 41 1.1 riz * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 42 1.1 riz * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 43 1.1 riz * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 44 1.1 riz * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 45 1.1 riz * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 46 1.1 riz * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 47 1.1 riz */ 48 1.1 riz 49 1.1 riz #include <sys/cdefs.h> 50 1.2 ad __KERNEL_RCSID(0, "$NetBSD: onewire_bitbang.c,v 1.2 2019/11/30 23:04:12 ad Exp $"); 51 1.1 riz 52 1.1 riz /* 53 1.1 riz * 1-Wire bus bit-banging routines. 54 1.1 riz */ 55 1.1 riz 56 1.1 riz #include <sys/param.h> 57 1.1 riz #include <sys/systm.h> 58 1.1 riz #include <sys/device.h> 59 1.2 ad #include <sys/proc.h> 60 1.1 riz 61 1.1 riz #include <dev/onewire/onewirevar.h> 62 1.1 riz 63 1.2 ad /* 64 1.2 ad * Reset the bus. Sequence from DS18B20 datasheet: 65 1.2 ad * 66 1.2 ad * 1: Master pulls bus low for a minimum of 480us. 67 1.2 ad * 2: Bus pulled up by resistor. DS18B20 detects rising edge, waits 15-60us. 68 1.2 ad * 3: DS18B20 pulls bus low for 60-240us. 69 1.2 ad * 4: Bus pulled up by resistor. Master must wait at least 450us. 70 1.2 ad * 71 1.2 ad * 111111111112222233333444444444 72 1.2 ad * 73 1.2 ad * Vpu | +-+ +-----> 74 1.2 ad * | / | / 75 1.2 ad * GND +----------+ +-----+ 76 1.2 ad */ 77 1.1 riz int 78 1.1 riz onewire_bb_reset(const struct onewire_bbops *ops, void *arg) 79 1.1 riz { 80 1.2 ad int s, rv, i; 81 1.1 riz 82 1.2 ad rv = 0; 83 1.1 riz s = splhigh(); 84 1.1 riz ops->bb_tx(arg); 85 1.1 riz ops->bb_set(arg, 0); 86 1.2 ad delay(500); 87 1.1 riz ops->bb_set(arg, 1); 88 1.1 riz ops->bb_rx(arg); 89 1.2 ad for (i = 0; i < 240 / 5; i++) { 90 1.2 ad delay(5); 91 1.1 riz if ((rv = ops->bb_get(arg)) == 0) 92 1.1 riz break; 93 1.1 riz } 94 1.2 ad splx(s); 95 1.2 ad 96 1.2 ad /* 97 1.2 ad * After a bus reset, we must wait for at least 450us before any 98 1.2 ad * further device access. There is no upper bound on this time, so 99 1.2 ad * rather than burning CPU, sleep for 1 tick. 100 1.2 ad */ 101 1.2 ad KASSERT(2001 > hz); 102 1.2 ad (void)kpause("owreset", false, 1, NULL); 103 1.2 ad 104 1.2 ad /* 105 1.2 ad * With a push-pull GPIO, bring the bus high to supply 106 1.2 ad * parasite-powered devices. With either PP or open drain, 107 1.2 ad * past this point on entry to onewire_bb_write_bit() and 108 1.2 ad * onewire_bb_read_bit() we assume that the line is set to 109 1.2 ad * output and not being held low. 110 1.2 ad */ 111 1.2 ad s = splhigh(); 112 1.2 ad ops->bb_tx(arg); 113 1.2 ad ops->bb_set(arg, 1); 114 1.1 riz splx(s); 115 1.1 riz 116 1.2 ad return rv; 117 1.1 riz } 118 1.1 riz 119 1.2 ad /* 120 1.2 ad * Onewire bit write. 121 1.2 ad * 122 1.2 ad * Method: pull the bus low. Then let the pull up resistor settle the bus. 123 1.2 ad * ZERO is signalled by the bus being held low for minimum 60us. 124 1.2 ad * ONE is signalled by the hold being much shorter (minimum 1us). 125 1.2 ad * 126 1.2 ad * In any eventuality, pad the entire transaction to the minimum 60us, plus 127 1.2 ad * an additional bit of recovery time before the next transaction 128 1.2 ad */ 129 1.2 ad void 130 1.2 ad onewire_bb_write_bit(const struct onewire_bbops *ops, void *arg, int value) 131 1.2 ad { 132 1.2 ad int s, d1, d2; 133 1.2 ad 134 1.2 ad if (value) { 135 1.2 ad d1 = 2; 136 1.2 ad d2 = 62; 137 1.2 ad } else { 138 1.2 ad d1 = 62; 139 1.2 ad d2 = 2; 140 1.2 ad } 141 1.2 ad 142 1.2 ad s = splhigh(); 143 1.2 ad ops->bb_set(arg, 0); 144 1.2 ad delay(d1); 145 1.2 ad ops->bb_set(arg, 1); 146 1.2 ad splx(s); 147 1.2 ad /* Timing no longer critical. */ 148 1.2 ad delay(d2); 149 1.2 ad } 150 1.2 ad 151 1.2 ad /* 152 1.2 ad * Onewire bit read. 153 1.2 ad * 154 1.2 ad * Method: pull the bus low for at least 1us. Then let the pull up resistor 155 1.2 ad * settle the bus. ZERO is signalled by the bus being pulled low again by 156 1.2 ad * the slave at some point between 15-45us of transaction start. ONE is 157 1.2 ad * signalled by the bus not being pulled low. 158 1.2 ad * 159 1.2 ad * In any eventuality, pad the entire transaction to the minimum 60us, plus 160 1.2 ad * an additional bit of recovery time before the next transaction. 161 1.2 ad */ 162 1.1 riz int 163 1.2 ad onewire_bb_read_bit(const struct onewire_bbops *ops, void *arg) 164 1.1 riz { 165 1.2 ad int s, rv, us; 166 1.1 riz 167 1.1 riz s = splhigh(); 168 1.1 riz ops->bb_set(arg, 0); 169 1.2 ad delay(2); 170 1.2 ad ops->bb_set(arg, 1); 171 1.2 ad ops->bb_rx(arg); 172 1.2 ad for (us = 62; us >= 60 - 45; us -= 5) { 173 1.2 ad delay(5); 174 1.2 ad if ((rv = ops->bb_get(arg)) == 0) { 175 1.2 ad break; 176 1.1 riz } 177 1.1 riz } 178 1.2 ad splx(s); 179 1.2 ad /* Timing no longer critical, and no further need to poll. */ 180 1.2 ad if (us > 0) { 181 1.2 ad delay(us); 182 1.2 ad } 183 1.2 ad ops->bb_tx(arg); 184 1.1 riz ops->bb_set(arg, 1); 185 1.2 ad return rv; 186 1.1 riz } 187