0
|
1 /*
|
|
2 * Copyright (c) 2004
|
|
3 * Daniel O'Connor <darius@dons.net.au>. All rights reserved.
|
|
4 *
|
|
5 * Redistribution and use in source and binary forms, with or without
|
|
6 * modification, are permitted provided that the following conditions
|
|
7 * are met:
|
|
8 * 1. Redistributions of source code must retain the above copyright
|
|
9 * notice, this list of conditions and the following disclaimer.
|
|
10 * 2. Redistributions in binary form must reproduce the above copyright
|
|
11 * notice, this list of conditions and the following disclaimer in the
|
|
12 * documentation and/or other materials provided with the distribution.
|
|
13 *
|
|
14 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
17 * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
24 * SUCH DAMAGE.
|
|
25 */
|
|
26
|
|
27 #include <stdio.h>
|
|
28 #include <avr/io.h>
|
|
29 #include <avr/interrupt.h>
|
|
30 #include <avr/signal.h>
|
|
31 #include <avr/pgmspace.h>
|
|
32 #include <string.h>
|
|
33
|
|
34 #include "1wire.h"
|
|
35
|
|
36 #define UART_BAUD_SELECT(baudRate,xtalCpu) ((xtalCpu)/((baudRate)*16l)-1)
|
|
37 #define XTAL_CPU 4000000 /* 4Mhz */
|
|
38 #define UART_BAUD_RATE 9600 /* 9600 baud */
|
|
39
|
|
40 static uint8_t dir = 0;
|
|
41 static volatile uint8_t leds = 0;
|
|
42 static uint8_t ledpos = 0;
|
|
43
|
|
44 void uart_putsP(const char *addr);
|
|
45 void uart_puts(const char *addr);
|
|
46 int uart_putc(char c);
|
|
47 uint8_t uart_getc(void);
|
|
48
|
|
49 uint8_t PROGMEM ledvals[] = {0x01, 0x03, 0x07, 0x0e, 0x1c, 0x38, 0x70, 0xe0, 0xc0, 0x80};
|
|
50
|
|
51 INTERRUPT(SIG_OVERFLOW0) {
|
|
52 if (!leds)
|
|
53 return;
|
|
54
|
|
55 /* Going up */
|
|
56 if (dir == 0) {
|
|
57 if (ledpos == 9) {
|
|
58 dir = 1;
|
|
59 TCNT0 = 0;
|
|
60 goto doleds;
|
|
61 }
|
|
62
|
|
63 ledpos++;
|
|
64 } else {
|
|
65 if (ledpos == 0) {
|
|
66 dir = 0;
|
|
67 TCNT0 = 0;
|
|
68 goto doleds;
|
|
69 }
|
|
70
|
|
71 ledpos--;
|
|
72 }
|
|
73
|
|
74 doleds:
|
|
75 TCNT0 = 0;
|
|
76
|
|
77 PORTA = pgm_read_byte(&ledvals[ledpos]);
|
|
78 }
|
|
79
|
|
80 void
|
|
81 usleep(uint16_t usec) {
|
|
82 /* 4Mhz = 250ns per clock cycle */
|
|
83 usec /= 2;
|
|
84 if (usec < 1)
|
|
85 return;
|
|
86
|
|
87 while (usec--)
|
|
88 asm volatile (
|
|
89 ""
|
|
90 ::);
|
|
91 }
|
|
92
|
|
93 int
|
|
94 main(void) {
|
|
95 uint8_t ROM[8], count;
|
|
96 char foo[40];
|
|
97 int i;
|
|
98
|
|
99 cli();
|
|
100 outp(0xff, DDRA);
|
|
101 outp(0xfe, DDRC);
|
|
102 outp(0x00, PORTC);
|
|
103
|
|
104 /* Init UART */
|
|
105 outp(UART_BAUD_SELECT(UART_BAUD_RATE,XTAL_CPU), UBRR);
|
|
106
|
|
107 /* Enable receiver and transmitter. Turn on transmit interrupts */
|
|
108 outp(BV(RXEN) | BV(TXEN), UCR);
|
|
109
|
|
110 /* Timer Clock divisor - CK/1024 */
|
|
111 outp(BV(CS00) | BV(CS02), TCCR0);
|
|
112
|
|
113 uart_putsP(PSTR("\n\r\n\r===============\n\r"));
|
|
114 uart_putsP(PSTR("Inited!\n\r\n\r"));
|
|
115 uart_putsP(PSTR("Test message 1\n\r"));
|
|
116
|
|
117 count = 0;
|
|
118 while (1) {
|
|
119 char cmd;
|
|
120
|
|
121 cmd = uart_getc();
|
|
122 switch (cmd) {
|
|
123 case 'r':
|
|
124 uart_putsP(PSTR("Resetting... "));
|
|
125
|
|
126 if (OWTouchReset() == 1)
|
|
127 uart_putsP(PSTR("No presense\n\r"));
|
|
128 else
|
|
129 uart_putsP(PSTR("Presense\n\r"));
|
|
130 break;
|
|
131
|
|
132 case 'R':
|
|
133 if (OWReadBit())
|
|
134 uart_putsP(PSTR("Read a 1\n\r"));
|
|
135 else
|
|
136 uart_putsP(PSTR("Read a 0\n\r"));
|
|
137 break;
|
|
138
|
|
139 case 'w':
|
|
140 OWWriteBit(0);
|
|
141 uart_putsP(PSTR("Wote a 0\n\r"));
|
|
142 break;
|
|
143
|
|
144 case 'W':
|
|
145 OWWriteBit(1);
|
|
146 uart_putsP(PSTR("Wote a 1\n\r"));
|
|
147 break;
|
|
148
|
|
149 case 'd':
|
|
150 bzero(ROM, 8);
|
|
151 if (OWTouchReset()) {
|
|
152 uart_putsP(PSTR("No devices on bus\n\r"));
|
|
153 break;
|
|
154 }
|
|
155 if (OWFirst(ROM, 1, 0) == 0) {
|
|
156 uart_putsP(PSTR("No module found\n\r"));
|
|
157 break;
|
|
158 }
|
|
159 do {
|
|
160 uart_putsP(PSTR("Found a module "));
|
|
161 sprintf_P(foo, PSTR("%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x"),
|
|
162 ROM[0],
|
|
163 ROM[1],
|
|
164 ROM[2],
|
|
165 ROM[3],
|
|
166 ROM[4],
|
|
167 ROM[5],
|
|
168 ROM[6],
|
|
169 ROM[7]);
|
|
170 uart_puts(foo);
|
|
171 if (ROM[0] == OW_FAMILY_TEMP) {
|
|
172 uint8_t tempbuf[9];
|
|
173 uint8_t crc;
|
|
174 uint16_t temp;
|
|
175
|
|
176 uart_putsP(PSTR(" is a temp sensor\n\r"));
|
|
177 OWSendCmd(ROM, OW_CONVERTT_CMD);
|
|
178 #if OW_DEBUG
|
|
179 uart_putsP(PSTR("Command sent, waiting\n\r"));
|
|
180 #endif
|
|
181 i = 0;
|
|
182 while (OWReadBit() == 0) {
|
|
183 i++;
|
|
184 }
|
|
185 #if OW_DEBUG
|
|
186 sprintf_P(foo, PSTR("Temp comversion took %d cycles\n\r"), i);
|
|
187 uart_puts(foo);
|
|
188 #endif
|
|
189 OWSendCmd(ROM, OW_RD_SCR_CMD);
|
|
190 crc = 0;
|
|
191 for (i = 0; i < 9; i++) {
|
|
192 tempbuf[i] = OWReadByte();
|
|
193 if (i < 8)
|
|
194 OWCRC(tempbuf[i], &crc);
|
|
195 }
|
|
196
|
|
197 temp = tempbuf[0];
|
|
198 temp |= (uint16_t)tempbuf[1] << 8;
|
|
199 temp <<= 3;
|
|
200
|
|
201 if (crc != tempbuf[9]) {
|
|
202 sprintf_P(foo, PSTR("CRC mismatch got %d vs calcd %d\n\r"), tempbuf[9], crc);
|
|
203 uart_puts(foo);
|
|
204 }
|
|
205
|
|
206 sprintf_P(foo, PSTR("temperature %d.%01d\n\r"),
|
|
207 temp >> 4, (temp << 12) / 6553);
|
|
208 uart_puts(foo);
|
|
209 }
|
|
210
|
|
211 if (ROM[0] == OW_FAMILY_ROM) {
|
|
212 uart_putsP(PSTR(" is a ROM\n\r"));
|
|
213 }
|
|
214 } while (OWNext(ROM, 1, 0));
|
|
215 break;
|
|
216
|
|
217 case 'l':
|
|
218 if (leds == 0) {
|
|
219 leds = 1;
|
|
220 ledpos = 0;
|
|
221 outp(0, TCNT0);
|
|
222 sbi(TIMSK, TOIE0);
|
|
223 sei();
|
|
224 uart_putsP(PSTR("Starting\n\r"));
|
|
225 } else {
|
|
226 leds = 0;
|
|
227 ledpos = 0;
|
|
228 PORTA = 0x00;
|
|
229 cbi(TIMSK, TOIE0);
|
|
230 cli();
|
|
231 uart_putsP(PSTR("Stopping\n\r"));
|
|
232 }
|
|
233
|
|
234 break;
|
|
235
|
|
236 default:
|
|
237 uart_putsP(PSTR("Unknown command\n\r"));
|
|
238 break;
|
|
239 }
|
|
240
|
|
241 }
|
|
242
|
|
243 return(0);
|
|
244 }
|
|
245
|
|
246 int
|
|
247 uart_putc(char c) {
|
|
248 loop_until_bit_is_set(USR, UDRE);
|
|
249 outp(c, UDR);
|
|
250
|
|
251 return(0);
|
|
252 }
|
|
253
|
|
254 void
|
|
255 uart_putsP(const char *addr) {
|
|
256 char c;
|
|
257
|
|
258 while ((c = PRG_RDB((unsigned short)addr++)))
|
|
259 uart_putc(c);
|
|
260 }
|
|
261
|
|
262 void
|
|
263 uart_puts(const char *addr) {
|
|
264 while (*addr)
|
|
265 uart_putc(*addr++);
|
|
266 }
|
|
267
|
|
268 uint8_t
|
|
269 uart_getc(void) {
|
|
270 while (!(inp(USR) & 0x80))
|
|
271 ;
|
|
272
|
|
273 return (inp(UDR));
|
|
274 }
|