sht11.c
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include <stdio.h>
00038
00039 #include <io.h>
00040
00041 #include <dev/sht11.h>
00042 #include "sht11-arch.h"
00043
00044 #define SDA_0() (SHT11_PxDIR |= BV(SHT11_ARCH_SDA))
00045 #define SDA_1() (SHT11_PxDIR &= ~BV(SHT11_ARCH_SDA))
00046 #define SDA_IS_1 (SHT11_PxIN & BV(SHT11_ARCH_SDA))
00047
00048 #define SCL_0() (SHT11_PxOUT &= ~BV(SHT11_ARCH_SCL))
00049 #define SCL_1() (SHT11_PxOUT |= BV(SHT11_ARCH_SCL))
00050
00051
00052 #define STATUS_REG_W 0x06
00053 #define STATUS_REG_R 0x07
00054 #define MEASURE_TEMP 0x03
00055 #define MEASURE_HUMI 0x05
00056 #define RESET 0x1e
00057
00058
00059 #define delay_400ns() _NOP()
00060
00061 static void
00062 sstart(void)
00063 {
00064 SDA_1(); SCL_0();
00065 delay_400ns();
00066 SCL_1();
00067 delay_400ns();
00068 SDA_0();
00069 delay_400ns();
00070 SCL_0();
00071 delay_400ns();
00072 SCL_1();
00073 delay_400ns();
00074 SDA_1();
00075 delay_400ns();
00076 SCL_0();
00077 }
00078
00079 static void
00080 sreset(void)
00081 {
00082 int i;
00083 SDA_1();
00084 SCL_0();
00085 for(i = 0; i < 9 ; i++) {
00086 SCL_1();
00087 delay_400ns();
00088 SCL_0();
00089 }
00090 sstart();
00091 }
00092
00093
00094
00095
00096 static int
00097 swrite(unsigned _c)
00098 {
00099 unsigned char c = _c;
00100 int i;
00101 int ret;
00102
00103 for(i = 0; i < 8; i++, c <<= 1) {
00104 if(c & 0x80) {
00105 SDA_1();
00106 } else {
00107 SDA_0();
00108 }
00109 SCL_1();
00110 delay_400ns();
00111 SCL_0();
00112 }
00113
00114 SDA_1();
00115 SCL_1();
00116 delay_400ns();
00117 ret = !SDA_IS_1;
00118
00119 SCL_0();
00120
00121 return ret;
00122 }
00123
00124 static unsigned
00125 sread(int send_ack)
00126 {
00127 int i;
00128 unsigned char c = 0x00;
00129
00130 SDA_1();
00131 for(i = 0; i < 8; i++) {
00132 c <<= 1;
00133 SCL_1();
00134 delay_400ns();
00135 if(SDA_IS_1) {
00136 c |= 0x1;
00137 }
00138 SCL_0();
00139 }
00140
00141 if(send_ack) {
00142 SDA_0();
00143 }
00144 SCL_1();
00145 delay_400ns();
00146 SCL_0();
00147
00148 SDA_1();
00149
00150 return c;
00151 }
00152
00153 #define CRC_CHECK
00154 #ifdef CRC_CHECK
00155 static unsigned char
00156 rev8bits(unsigned char v)
00157 {
00158 unsigned char r = v;
00159 int s = 7;
00160
00161 for (v >>= 1; v; v >>= 1) {
00162 r <<= 1;
00163 r |= v & 1;
00164 s--;
00165 }
00166 r <<= s;
00167 return r;
00168 }
00169
00170
00171 static unsigned
00172 crc8_add(unsigned acc, unsigned byte)
00173 {
00174 int i;
00175 acc ^= byte;
00176 for(i = 0; i < 8; i++) {
00177 if(acc & 0x80) {
00178 acc = (acc << 1) ^ 0x31;
00179 } else {
00180 acc <<= 1;
00181 }
00182 }
00183 return acc & 0xff;
00184 }
00185 #endif
00186
00187
00188
00189
00190
00191 void
00192 sht11_init(void)
00193 {
00194
00195
00196
00197
00198
00199 SHT11_PxOUT |= BV(SHT11_ARCH_PWR);
00200 SHT11_PxOUT &= ~(BV(SHT11_ARCH_SDA) | BV(SHT11_ARCH_SCL));
00201 SHT11_PxDIR |= BV(SHT11_ARCH_PWR) | BV(SHT11_ARCH_SCL);
00202 }
00203
00204
00205
00206
00207 void
00208 sht11_off(void)
00209 {
00210 SHT11_PxOUT &= ~BV(SHT11_ARCH_PWR);
00211 SHT11_PxOUT &= ~(BV(SHT11_ARCH_SDA) | BV(SHT11_ARCH_SCL));
00212 SHT11_PxDIR |= BV(SHT11_ARCH_PWR) | BV(SHT11_ARCH_SCL);
00213 }
00214
00215
00216
00217
00218 static unsigned int
00219 scmd(unsigned cmd)
00220 {
00221 unsigned long n;
00222
00223 if(cmd != MEASURE_HUMI && cmd != MEASURE_TEMP) {
00224 return -1;
00225 }
00226
00227 sstart();
00228 if(!swrite(cmd)) {
00229 goto fail;
00230 }
00231
00232 for(n = 0; n < 250000; n++) {
00233 if(!SDA_IS_1) {
00234 unsigned t0, t1, rcrc;
00235 t0 = sread(1);
00236 t1 = sread(1);
00237 rcrc = sread(0);
00238 #ifdef CRC_CHECK
00239 {
00240 unsigned crc;
00241 crc = crc8_add(0x0, cmd);
00242 crc = crc8_add(crc, t0);
00243 crc = crc8_add(crc, t1);
00244 if(crc != rev8bits(rcrc)) {
00245 goto fail;
00246 }
00247 }
00248 #endif
00249 return (t0 << 8) | t1;
00250 }
00251 }
00252
00253 fail:
00254 sreset();
00255 return -1;
00256 }
00257
00258
00259
00260
00261 unsigned int
00262 sht11_temp(void)
00263 {
00264 return scmd(MEASURE_TEMP);
00265 }
00266
00267
00268
00269
00270 unsigned int
00271 sht11_humidity(void)
00272 {
00273 return scmd(MEASURE_HUMI);
00274 }
00275
00276 #if 1
00277 unsigned
00278 sht11_sreg(void)
00279 {
00280 unsigned sreg, rcrc;
00281
00282 sstart();
00283 if(!swrite(STATUS_REG_R)) {
00284 goto fail;
00285 }
00286
00287 sreg = sread(1);
00288 rcrc = sread(0);
00289
00290 #ifdef CRC_CHECK
00291 {
00292 unsigned crc;
00293 crc = crc8_add(0x0, STATUS_REG_R);
00294 crc = crc8_add(crc, sreg);
00295 if (crc != rev8bits(rcrc))
00296 goto fail;
00297 }
00298 #endif
00299
00300 return sreg;
00301
00302 fail:
00303 sreset();
00304 return -1;
00305 }
00306 #endif
00307
00308 #if 0
00309 int
00310 sht11_set_sreg(unsigned sreg)
00311 {
00312 sstart();
00313 if(!swrite(STATUS_REG_W)) {
00314 goto fail;
00315 }
00316 if(!swrite(sreg)) {
00317 goto fail;
00318 }
00319
00320 return 0;
00321
00322 fail:
00323 sreset();
00324 return -1;
00325 }
00326 #endif
00327
00328 #if 0
00329 int
00330 sht11_reset(void)
00331 {
00332 sstart();
00333 if(!swrite(RESET)) {
00334 goto fail;
00335 }
00336
00337 return 0;
00338
00339 fail:
00340 sreset();
00341 return -1;
00342 }
00343 #endif
00344