Merge branch 'master' of gitlab:wintermute/hackover2013-badge-firmware
[hackover2013-badge-firmware.git] / drivers / sensors / ds18b20 / ds18b20.c
1 /**************************************************************************/
2 /*!
3 @file ds18b20.c
4 @author Albertas Mickenas (mic@wemakethings.net)
5 @date 8 August 2012
6 @version 1.0
7
8 @section DESCRIPTION
9 Driver for DALLAS DS18B20 temperature sensor.
10
11 @section Example
12
13 @code
14 #include "core/cpu/cpu.h"
15 #include "drivers/sensors/ds18b20/ds18b20.h"
16
17 int main(void) {
18 cpuInit();
19
20 int32_t temp = 0;
21
22 // Initialise the DS18B20
23 ds18b20Init(3, 0, &IOCON_PIO3_0);
24 while (1) {
25 temp = ds18b20GetTemperature();
26
27 // Use modulus operator to display decimal value
28 printf("Current Temperature: %d.%d C\n", temp / 10000, temp % 10000);
29 }
30 }
31 @endcode
32
33 @section LICENSE
34
35 Software License Agreement (BSD License)
36
37 Copyright (c) 2010, microBuilder SARL
38 All rights reserved.
39
40 Redistribution and use in source and binary forms, with or without
41 modification, are permitted provided that the following conditions are met:
42 1. Redistributions of source code must retain the above copyright
43 notice, this list of conditions and the following disclaimer.
44 2. Redistributions in binary form must reproduce the above copyright
45 notice, this list of conditions and the following disclaimer in the
46 documentation and/or other materials provided with the distribution.
47 3. Neither the name of the copyright holders nor the
48 names of its contributors may be used to endorse or promote products
49 derived from this software without specific prior written permission.
50
51 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
52 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
53 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
54 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
55 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
56 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
57 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
58 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
60 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 */
62 /**************************************************************************/
63
64 #include "ds18b20.h"
65 #include "core/gpio/gpio.h"
66 #include "core/timer16/timer16.h"
67
68 #define CMD_CONVERTTEMP 0x44
69 #define CMD_RSCRATCHPAD 0xbe
70 #define CMD_WSCRATCHPAD 0x4e
71 #define CMD_CPYSCRATCHPAD 0x48
72 #define CMD_RECEEPROM 0xb8
73 #define CMD_RPWRSUPPLY 0xb4
74 #define CMD_SEARCHROM 0xf0
75 #define CMD_READROM 0x33
76 #define CMD_MATCHROM 0x55
77 #define CMD_SKIPROM 0xcc
78 #define CMD_ALARMSEARCH 0xec
79 #define DECIMAL_STEPS_12BIT 625 //.0625
80
81 uint32_t portNum = 0;
82 uint32_t bitPos = 0;
83
84 inline void pullLineLow() {
85 gpioSetDir(portNum, bitPos, gpioDirection_Output);
86 gpioSetValue(portNum, bitPos, 0);
87 }
88
89 inline void releaseLine() {
90 gpioSetDir(portNum, bitPos, gpioDirection_Input);
91 }
92
93 inline void delayUs(uint16_t us) {
94 timer16DelayUS(1, us);
95 }
96
97 inline uint32_t readLineState() {
98 return gpioGetValue(portNum, bitPos );
99 }
100
101 void writeBit(uint8_t bit){
102 //Pull line low for 1uS
103 pullLineLow();
104 delayUs(1);
105 //If we want to write 1, release the line (if not will keep low)
106 if(bit) {
107 releaseLine();
108 }
109 //Wait for 60uS and release the line
110 delayUs(60);
111 releaseLine();
112 }
113
114 uint8_t readBit(void){
115 uint8_t bit = 0;
116 //Pull line low for 1uS
117 pullLineLow();
118 delayUs(1);
119 //Release line and wait for 14uS
120 releaseLine();
121 delayUs(14);
122 //Read line value
123 if(readLineState()){
124 bit=1;
125 }
126 //Wait for 45uS to end and return read value
127 delayUs(45);
128 return bit;
129 }
130
131 uint8_t readByte(void){
132 uint8_t i = 8, n = 0;
133 while(i--){
134 //Shift one position right and store read value
135 n >>= 1;
136 n |= (readBit() << 7);
137 }
138 return n;
139 }
140
141 void writeByte(uint8_t b){
142 uint8_t i = 8;
143 while(i--){
144 //Write actual bit and shift one position right to make the next bit ready
145 writeBit(b & 1);
146 b >>= 1;
147 }
148 }
149
150 uint32_t reset(){
151 uint32_t i;
152 //Pull line low and wait for 480uS
153 pullLineLow();
154 delayUs(480);
155 //Release line and wait for 60uS
156 releaseLine();
157 delayUs(60);
158 //Store line value and wait until the completion of 480uS period
159 i = readLineState();
160 delayUs(420);
161 //Return the value read from the presence pulse (0=OK, 1=WRONG)
162 return i;
163 }
164
165 /*!
166 @brief Initializes DS18B20 sensor driver.
167 */
168
169 void ds18b20Init(uint32_t portNumber, uint32_t bitPosition, volatile uint32_t *ioconReg) {
170 portNum = portNumber;
171 bitPos = bitPosition;
172 timer16Init(1, TIMER16_DEFAULTINTERVAL);
173 timer16Enable(1);
174 gpioSetPullup(ioconReg, gpioPullupMode_Inactive);
175 }
176
177 /*!
178 @brief Returns temperature read from BS18B20
179
180 @note Reading is returned mutiplied by 10000 i.e.
181 for 25.8750 degrees the result will be 258750
182 */
183 uint32_t ds18b20GetTemparature(){
184 //Reset, skip ROM and start temperature conversion
185 if(reset()) {
186 printf("DS18B20 is not responding%s", CFG_PRINTF_NEWLINE);
187 return 0;
188 }
189 writeByte(CMD_SKIPROM);
190 writeByte(CMD_CONVERTTEMP);
191
192 //Wait until conversion is complete
193 uint16_t timeout = 0xFFFF;
194 while(!readBit() && timeout > 0) {
195 timeout--;
196 }
197 if(0 == timeout) {
198 printf("BS18B20 temperature conversion has timed out%s", CFG_PRINTF_NEWLINE);
199 return 0;
200 }
201
202 //Reset, skip ROM and send command to read Scratchpad
203 if(reset()) {
204 printf("DS18B20 is not responding%s", CFG_PRINTF_NEWLINE);
205 return 0;
206 }
207 writeByte(CMD_SKIPROM);
208 writeByte(CMD_RSCRATCHPAD);
209
210 uint8_t scratchpad[2] = {0, 0};
211 //Read Scratchpad (only 2 first bytes)
212 scratchpad[0] = readByte();
213 scratchpad[1] = readByte();
214
215 //Store temperature integer digits and decimal digits
216 int8_t digit = scratchpad[0] >> 4;
217 digit |= (scratchpad[1] & 0x7) << 4;
218 //Store decimal digits
219 uint16_t decimal = scratchpad[0] & 0xf;
220 decimal *= DECIMAL_STEPS_12BIT;
221
222 return digit * 10000 + decimal;
223 }
224
This page took 0.056629 seconds and 5 git commands to generate.