tsic.c


1
/*
2
 * tsic.c
3
 *
4
 *  Created on: 01.04.2013
5
 */
6
#include <avr/io.h>
7
#include <util/parity.h>
8
#include <avr/interrupt.h>
9
#include <stdlib.h>
10
#include "uart.h"
11
#include "delay.h"
12
13
extern volatile uint32_t millis;        // mS counter inported from uart.c
14
15
volatile uint16_t temperature = 0;
16
17
char buffer[32];
18
19
void initPCInt(void)
20
{
21
    DDRD &= ~_BV(DDD4);         // PD4 as input
22
    PCIFR |= _BV(PCIF2);        // Clear interrupt flag for PCI2
23
    PCICR |= _BV(PCIE2);        // enable pcint2 (pcint pins 16..23)
24
    PCMSK2 |= _BV(PCINT20);     // (Un)mask bit for PCINT20
25
}
26
27
ISR(PCINT2_vect)
28
{
29
    uint16_t timeout;
30
    uint16_t strobelength;
31
    uint16_t strobetemp;
32
    uint16_t temperaturelow = 0;
33
    uint8_t temperaturehigh = 0;
34
    uint16_t dummy = 0;
35
    uint8_t bitcounter = 0;
36
    uint8_t bytecount = 0;
37
    uint8_t parity = 0;
38
39
    if ((PIND & _BV(PIND4))) { // Ignore if int occurred by rising edge
40
        return;
41
    }
42
43
    PCICR &= ~_BV(PCIE2);                 // disable interrupts
44
45
    while (bytecount < 2) {
46
        temperaturelow = 0;
47
        // Measure strobe time
48
        strobelength = 0;
49
        timeout = 0;
50
        while (!(PIND & _BV(PIND4))) {    // wait for rising edge
51
            strobelength++;
52
            timeout++;
53
            if (timeout == 0) {
54
                PCICR |= _BV(PCIE2);      // enable pcint2
55
                return;
56
            }
57
        }
58
59
        bitcounter = 0;
60
        while (bitcounter < 9) {
61
            // Wait for bit start
62
            timeout = 0;
63
            while ((PIND & _BV(PIND4))) { // wait for falling edge
64
                timeout++;
65
                if (timeout == 0) {
66
                    PCICR |= _BV(PCIE2);  // enable pcint2
67
                    return;
68
                }
69
            }
70
71
            // Delay strobe length
72
            timeout = 0;
73
            dummy = 0;
74
            strobetemp = strobelength;
75
            while (strobetemp--) {
76
                timeout++;
77
                dummy++;
78
                if (timeout == 0) {
79
                    PCICR |= _BV(PCIE2);  // enable pcint2
80
                    return;
81
                }
82
            }
83
            temperaturelow <<= 1;
84
            // Read bit
85
            if (PIND & _BV(PIND4)) {
86
                temperaturelow |= 1;
87
            }
88
89
            // Wait for bit end
90
            timeout = 0;
91
            while (!(PIND & _BV(PIND4))) { // wait for rising edge
92
                timeout++;
93
                if (timeout == 0) {
94
                    PCICR |= _BV(PCIE2);   // enable pcint2
95
                    return;
96
                }
97
            }
98
            bitcounter++;
99
        }
100
        parity = temperaturelow & 1;
101
        temperaturelow >>= 1;               // Strip parity bit;
102
        // Read parity bit
103
        if (parity_even_bit(temperaturelow & 0xff)) {
104
            if (!parity)
105
                // parity error
106
                return;
107
        } else {
108
            if (parity)
109
                // parity error
110
                return;
111
        }
112
113
        if (bytecount == 0) {
114
            temperaturehigh = temperaturelow;
115
            // Wait for stop bit
116
            timeout = 0;
117
            while ((PIND & _BV(PIND4))) {   // wait for falling edge
118
                timeout++;
119
                if (timeout == 0) {
120
                    PCICR |= _BV(PCIE2);    // enable pcint2
121
                    return;
122
                }
123
            }
124
        }
125
        bytecount++;
126
    }
127
    temperature = (temperaturehigh << 8) + temperaturelow;
128
    PCICR |= _BV(PCIE2);                  // enable pcint2
129
}
130
131
int main(void)
132
{
133
    uint32_t displaytimeout = millis;
134
135
    timerInit();
136
    uartInit(1);
137
138
    initPCInt();
139
140
    while (1) {
141
        if ((millis - displaytimeout) > 1000) {
142
143
            displaytimeout = millis;
144
145
            itoa((uint32_t)((uint32_t)temperature * 20000) / 2047 - 5000,buffer,10);
146
            uartWrite("Temp: ");
147
            uartWrite(buffer);
148
            uartWrite("\n");
149
150
        }
151
    }
152
    return 0;
153
}