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 | }
|