Statistics
| Branch: | Tag: | Revision:

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