Bugfixes
[rtl-433.git] / src / util.c
1 /**
2  * Various utility functions for use by device drivers
3  * 
4  * Copyright (C) 2015 Tommy Vestermark
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  */
10
11 #include "util.h"
12 #include <stdio.h>
13
14 uint8_t reverse8(uint8_t x) {
15     x = (x & 0xF0) >> 4 | (x & 0x0F) << 4;
16     x = (x & 0xCC) >> 2 | (x & 0x33) << 2;
17     x = (x & 0xAA) >> 1 | (x & 0x55) << 1;
18     return x;
19 }
20
21
22 uint8_t crc8(uint8_t const message[], unsigned nBytes, uint8_t polynomial, uint8_t init) {
23     uint8_t remainder = init;   
24     unsigned byte, bit;
25
26     for (byte = 0; byte < nBytes; ++byte) {
27         remainder ^= message[byte];
28         for (bit = 0; bit < 8; ++bit) {
29             if (remainder & 0x80) {
30                 remainder = (remainder << 1) ^ polynomial;
31             }
32             else {
33                 remainder = (remainder << 1);
34             }
35         }
36     }
37     return remainder;
38 }
39
40
41 uint8_t crc8le(uint8_t const message[], unsigned nBytes, uint8_t polynomial, uint8_t init) {
42     uint8_t crc = init, i;      
43     unsigned byte;
44     uint8_t bit;
45
46
47     for (byte = 0; byte < nBytes; ++byte) {
48         for (i = 0x01; i & 0xff; i <<= 1) {
49             bit = (crc & 0x80) == 0x80;     
50             if (message[byte] & i) {
51                 bit = !bit;
52             }
53             crc <<= 1;
54             if (bit) {
55                 crc ^= polynomial;
56             }
57         }
58         crc &= 0xff;
59     }
60
61     return reverse8(crc);
62 }
63
64 uint16_t crc16(uint8_t const message[], unsigned nBytes, uint16_t polynomial, uint16_t init) {
65     uint16_t remainder = init;
66     unsigned byte, bit;
67
68     for (byte = 0; byte < nBytes; ++byte) {
69         remainder ^= message[byte];
70         for (bit = 0; bit < 8; ++bit) {
71             if (remainder & 1) {
72                 remainder = (remainder >> 1) ^ polynomial;
73             }
74             else {
75                 remainder = (remainder >> 1);
76             }
77         }
78     }
79     return remainder;
80 }
81
82 uint16_t crc16_ccitt(uint8_t const message[], unsigned nBytes, uint16_t polynomial, uint16_t init) {
83     uint16_t remainder = init;
84     unsigned byte, bit;
85
86     for (byte = 0; byte < nBytes; ++byte) {
87         remainder ^= message[byte] << 8;
88         for (bit = 0; bit < 8; ++bit) {
89             if (remainder & 0x8000) {
90                 remainder = (remainder << 1) ^ polynomial;
91             }
92             else {
93                 remainder = (remainder << 1);
94             }
95         }
96     }
97     return remainder;
98 }
99
100
101
102 int byteParity(uint8_t inByte){
103     inByte ^= inByte >> 4;
104     inByte &= 0xf;
105     return (0x6996 >> inByte) & 1;
106 }
107
108
109 char* local_time_str(time_t time_secs, char *buf) {
110         time_t etime;
111         struct tm *tm_info;
112
113         if (time_secs == 0) {
114                 extern float sample_file_pos;
115                 if (sample_file_pos != -1.0) {
116                         snprintf(buf, LOCAL_TIME_BUFLEN, "@%fs", sample_file_pos);
117                         return buf;
118                 }
119                 time(&etime);
120         } else {
121                 etime = time_secs;
122         }
123
124         tm_info = localtime(&etime);
125
126         strftime(buf, LOCAL_TIME_BUFLEN, "%Y-%m-%d %H:%M:%S", tm_info);
127         return buf;
128 }
129
130 float celsius2fahrenheit(float celsius)
131 {
132   return celsius * 9 / 5 + 32;
133 }
134
135
136 float fahrenheit2celsius(float fahrenheit)
137 {
138     return (fahrenheit - 32) / 1.8;
139 }
140
141
142 float kmph2mph(float kmph)
143 {
144     return kmph / 1.609344;
145 }
146
147 float mph2kmph(float mph)
148 {
149     return mph * 1.609344;
150 }
151
152
153 // Test code
154 // gcc -I include/ -std=gnu99 -D _TEST src/util.c
155 #ifdef _TEST
156 int main(int argc, char **argv) {
157         fprintf(stderr, "util:: test\n");
158
159         uint8_t msg[] = {0x08, 0x0a, 0xe8, 0x80};
160
161         fprintf(stderr, "util::crc8(): odd parity:  %02X\n", crc8(msg, 3, 0x80));
162         fprintf(stderr, "util::crc8(): even parity: %02X\n", crc8(msg, 4, 0x80));
163
164         return 0;
165 }
166 #endif /* _TEST */