root / analog_exp / onewire.c @ 168:bfc84ee2839b
History | View | Annotate | Download (3.9 kB)
1 | #include <string.h> |
---|---|
2 | |
3 | #include "debug.h" |
4 | #include "onewire_hal.h" |
5 | #include "onewire.h" |
6 | |
7 | void onewire_tx_byte(uint8_t data) {
|
8 | for(uint8_t i=0; i<8; i++) { |
9 | if(data & 1) { |
10 | onewire_tx1(); |
11 | } else {
|
12 | onewire_tx0(); |
13 | } |
14 | data >>= 1;
|
15 | } |
16 | } |
17 | |
18 | uint8_t onewire_rx_byte(void) {
|
19 | uint8_t data = 0;
|
20 | for(uint8_t i=0; i<8; i++) { |
21 | data >>= 1;
|
22 | data |= (onewire_rx() << 7);
|
23 | } |
24 | return data;
|
25 | } |
26 | |
27 | void onewire_readrom(onewire_id id) {
|
28 | onewire_reset(); |
29 | onewire_tx_byte(ONEWIRE_CMD_READROM); |
30 | for(uint8_t i=0; i<8; i++) { |
31 | id[i] = onewire_rx_byte(); |
32 | } |
33 | } |
34 | |
35 | void onewire_matchrom(onewire_id id) {
|
36 | onewire_reset(); |
37 | onewire_tx_byte(ONEWIRE_CMD_MATCHROM); |
38 | for(uint8_t i=0; i<8; i++) { |
39 | onewire_tx_byte(id[i]); |
40 | } |
41 | } |
42 | |
43 | void onewire_skiprom(void) { |
44 | onewire_reset(); |
45 | onewire_tx_byte(ONEWIRE_CMD_SKIPROM); |
46 | } |
47 | |
48 | typedef struct { |
49 | bool done;
|
50 | uint8_t next_id; |
51 | int8_t prev_deviation; |
52 | onewire_id bit_pattern; |
53 | } onewire_search_state_t; |
54 | |
55 | static bool onewire_search_iter(onewire_search_state_t *state) { |
56 | int8_t deviation = -1;
|
57 | |
58 | if(state->done) return false; |
59 | |
60 | onewire_reset(); |
61 | onewire_tx_byte(ONEWIRE_CMD_SEARCHROM); |
62 | |
63 | for(uint8_t bit_index=0; bit_index<64; bit_index++) { |
64 | uint8_t a = onewire_rx(); |
65 | uint8_t b = onewire_rx(); |
66 | if(a && b) {
|
67 | return false; |
68 | } else if(a != b) { |
69 | if(a) {
|
70 | state->bit_pattern[bit_index / 8] |= (1<<(bit_index % 8)); |
71 | } else {
|
72 | state->bit_pattern[bit_index / 8] &= ~(1<<(bit_index % 8)); |
73 | } |
74 | } else {
|
75 | if(bit_index == state->prev_deviation) {
|
76 | state->bit_pattern[bit_index / 8] |= (1<<(bit_index % 8)); |
77 | } else if(bit_index > state->prev_deviation) { |
78 | state->bit_pattern[bit_index / 8] &= ~(1<<(bit_index % 8)); |
79 | deviation = bit_index; |
80 | } else if((state->bit_pattern[bit_index / 8] & (1<<(bit_index % 8))) == 0) { |
81 | deviation = bit_index; |
82 | } |
83 | } |
84 | if(state->bit_pattern[bit_index / 8] & (1<<(bit_index % 8))) { |
85 | onewire_tx1(); |
86 | } else {
|
87 | onewire_tx0(); |
88 | } |
89 | } |
90 | if(deviation == -1) state->done = true; |
91 | state->prev_deviation = deviation; |
92 | return true; |
93 | } |
94 | |
95 | void onewire_searchrom(onewire_id *id_list, uint8_t *n) {
|
96 | onewire_search_state_t state; |
97 | state.done = false;
|
98 | state.next_id = 0;
|
99 | state.prev_deviation = -1;
|
100 | memset(state.bit_pattern, 0, sizeof(onewire_id)); |
101 | |
102 | while(*n > 0 && onewire_search_iter(&state)) { |
103 | memcpy(id_list[state.next_id++], state.bit_pattern, sizeof(onewire_id));
|
104 | *n = *n - 1;
|
105 | } |
106 | |
107 | *n = state.next_id; |
108 | } |
109 | |
110 | static uint8_t onewire_crc8_byte(uint8_t seed, uint8_t data) {
|
111 | const uint8_t poly = 0x18; |
112 | for(uint8_t i=0; i<8; i++) { |
113 | if((data ^ seed) & 1) { |
114 | seed = ((seed ^ poly) >> 1) | 0x80; |
115 | } else {
|
116 | seed >>= 1;
|
117 | } |
118 | data >>= 1;
|
119 | } |
120 | return seed;
|
121 | } |
122 | |
123 | uint8_t onewire_crc8(uint8_t *data, uint8_t length) { |
124 | uint8_t crc = 0;
|
125 | for(; length > 0; length--) { |
126 | crc = onewire_crc8_byte(crc, *data++); |
127 | } |
128 | return crc;
|
129 | } |
130 | |
131 | bool onewire_crc_rom(onewire_id id) {
|
132 | return onewire_crc8(id, 8) == 0; |
133 | } |
134 | |
135 | void onewire_convert_t(void) { |
136 | onewire_tx_byte(ONEWIRE_CMD_CONVERT_T); |
137 | } |
138 | |
139 | void onewire_write_scratchpad(uint8_t th, uint8_t tl, uint8_t config) {
|
140 | onewire_tx_byte(ONEWIRE_CMD_WRITE_SCRATCHPAD); |
141 | onewire_tx_byte(th); |
142 | onewire_tx_byte(tl); |
143 | onewire_tx_byte(config); |
144 | } |
145 | |
146 | bool onewire_read_scratchpad(ds18b20_scratchpad_t *scratchpad) {
|
147 | onewire_tx_byte(ONEWIRE_CMD_READ_SCRATCHPAD); |
148 | uint8_t *buf = (uint8_t*)scratchpad; |
149 | for(uint8_t i=0; i<sizeof(ds18b20_scratchpad_t); i++) { |
150 | *buf++ = onewire_rx_byte(); |
151 | } |
152 | |
153 | return onewire_crc8((uint8_t*)scratchpad, sizeof(ds18b20_scratchpad_t)) == 0; |
154 | } |
155 |