Initial import of onewire-to-usb bridge
[onewire] / main.c
CommitLineData
bba33fe1
JM
1/******************************************************************************/
2/* Files to Include */
3/******************************************************************************/
4
5#if defined(__XC)
6 #include <xc.h> /* XC8 General Include File */
7#elif defined(HI_TECH_C)
8 #include <htc.h> /* HiTech General Include File */
9#endif
10
11#include <stdio.h>
12
13#include <stdint.h> /* For uint8_t definition */
14#include <stdbool.h> /* For true/false definition */
15
16#include "system.h" /* System funct/params, like osc/peripheral config */
17#include "user.h" /* User funct/params, such as InitApp */
18
19#include "onewire.h" /* 1-wire bus functions */
20
21/******************************************************************************/
22/* User Global Variable Declaration */
23/******************************************************************************/
24
25#define LED1 PORTAbits.RA4
26
27/* i.e. uint8_t <variable_name>; */
28
29char outbuff[100];
30char * outp = 0;
31uint8_t outlen = 0;
32
33char inbuff[10];
34uint8_t inlen = 0;
35
36/******************************************************************************/
37/* Main Program */
38/******************************************************************************/
39
40char prompt[9];
41
42// long time period counter, 572 steps is 5 minutes
43char automode = 0;
44uint16_t auto_counter = 0;
45
46void timer_rollover()
47{
48 if (automode) auto_counter++;
49 PIR1bits.TMR1IF = 0;
50}
51void timer_enable() {
52 auto_counter = 0;
53 automode = 1;
54 T1CONbits.TMR1ON = 1;
55}
56
57void timer_disable() {
58 automode = 0;
59 T1CONbits.TMR1ON = 0;
60}
61
62const char * banner = "\r\n\n\nPIC 1-Wire Bridge system. Press 'H' for help.\r\n";
63
64void main(void)
65{
66 prompt[0] = 'c';
67 prompt[1] = 'm';
68 prompt[2] = 'd';
69 prompt[3] = ' ';
70 prompt[4] = '?';
71 prompt[5] = '?';
72 prompt[6] = '>';
73 prompt[7] = ' ';
74 prompt[8] = 0;
75
76 bool usermode = false;
77
78 /* Configure the oscillator for the device */
79 ConfigureOscillator();
80
81 /* Initialize I/O and Peripherals for application */
82 InitApp();
83
84 OW_start();
85 msg_write(banner);
86 //msg_write(prompt);
87
88 LED1 = 0;
89
90 while(1)
91 {
92 CLRWDT();
93
94 if (TRISAbits.TRISA5 == 1) {
95 prompt[4] = 'i';
96 prompt[5] = PORTAbits.RA5 ? '1':'0';
97 } else {
98 prompt[4] = 'o';
99 prompt[5] = PORTAbits.RA5 ? '1':'0';
100 }
101
102
103 if (!msg_empty()) continue;
104
105 if (automode) {
106 if (auto_counter >= 572) {
107 inbuff[inlen++] = 't';
108 auto_counter = 0;
109 }
110 }
111
112 if (!msg_recvready()) continue;
113
114 char cmd = msg_recv();
115
116 if (cmd == '\r' || cmd == '\n') {
117 if (usermode) msg_write("\r\n");
118 }else
119 if (cmd == 'h' || cmd == 'H') {
120 msg_write(banner);
121 msg_write("\nHelp:\r\n");
122 while (!msg_empty());
123 msg_write("E - Enumerate the Bus\r\n");
124 msg_write("R - Reset Bus\r\n");
125 while (!msg_empty());
126 msg_write("0,1,3 - bus to Low, High, Tristate\r\n");
127 msg_write("I - Read (one) Device ID\r\n");
128 while (!msg_empty());
129 msg_write("P - Any device parasitic powered?\r\n");
130 msg_write("S - Read scratchpad memory\r\n");
131 while (!msg_empty());
132 msg_write("T - read temperature of all devices\r\n");
133 msg_write("A - Auto-mode. read every 5 mins.\r\n");
134 while (!msg_empty());
135 msg_write("M - Manual mode.\r\n");
136 msg_write("B - Test battery voltage\r\n");
137 while (!msg_empty());
138 usermode = true;
139 } else
140 if (cmd == 'a' || cmd == 'A') {
141 if (usermode)
142 msg_write("\rAUTO mode enabled. 5 minute timer.\r\n");
143 else
144 msg_write("AUTO ON\n");
145 timer_enable();
146 } else
147 if (cmd == 'm' || cmd == 'M') {
148 if (usermode)
149 msg_write("\rAUTO mode disabled.\r\n");
150 else
151 msg_write("AUTO OFF\n");
152 timer_disable();
153 }else
154 if (cmd == 'r' || cmd == 'R') {
155 int_disable();
156 bool present = OW_reset();
157 int_enable();
158 if (usermode) msg_write("\r");
159 if (present)
160 msg_write("RESET Device detected.\r\n");
161 else
162 msg_write("RESET No Devices detected.\r\n");
163 } else
164 if (cmd == 'e' || cmd == 'E')
165 {
166 char count = 0;
167 if (usermode) msg_write("\r");
168 OW_search_init();
169 while (OW_search())
170 {
171 char val[3];
172 if (usermode) msg_write("ENUM ");
173 for (char j=0; j<8; j++) {
174 tohex(val, romid[j]);
175 msg_write(val);
176 }
177 if (usermode) msg_write("\r\n"); else msg_write("\n");
178 count++;
179 }
180 if (usermode) {
181 if (count==0) msg_write("ERROR No devices found\r\n");
182 } else {
183 msg_write("END\n");
184 }
185 }else
186 if (cmd == 'i' || cmd == 'I') {
187 OW_identify();
188 char val[3];
189 if (usermode) msg_write("\rID ");
190 for (char j=0; j<8; j++) {
191 tohex(val, romid[j]);
192 msg_write(val);
193 }
194 if (usermode) msg_write("\r\n"); else msg_write("\n");
195 }else
196 if (cmd == 'p' || cmd == 'P') {
197 if (usermode) msg_write("\r");
198 bool para = OW_parasite();
199 if (usermode) {
200 if (para)
201 msg_write("PARA Yes\r\n");
202 else
203 msg_write("PARA No\r\n");
204 } else {
205 if (para) msg_write("PARA\n"); else msg_write("DIRECT\n");
206 }
207 }else
208 if (cmd == 's' || cmd =='S') {
209 uint8_t scratch[9];
210 romid[0] = 0; // select all devices
211 OW_read_block(0xBE, scratch, 9);
212 if (usermode) msg_write("\rSCRATCH");
213 for (char j=0; j<9; j++) {
214 char val[3];
215 tohex(val, scratch[j]);
216 msg_write(" ");
217 msg_write(val);
218 }
219 if (usermode) msg_write("\r\n"); else msg_write("\n");
220 }else
221 if (cmd == 't' || cmd == 'T') {
222 char val[3];
223 uint8_t scratch[9];
224
225 // oddly, cant do a mass-convert with parasitic
226 // they seem to all reset when you try
227
228 LED1 = 1;
229
230 // now step through every unit and read the value
231 OW_search_init();
232 while (OW_search())
233 {
234 // convert takes along time, dont trip watchdog
235 CLRWDT();
236 // ask device to do conversion
237 OW_convert();
238 CLRWDT();
239
240 // empty the scratch pad
241 for (char j=0; j<9; j++) scratch[j]=0;
242
243 // read this devices scratch pad
244 OW_read_block(0xBE, scratch, 9);
245
246 // print rom id and temperature
247 if (usermode) msg_write("\r");
248 msg_write("TEMP ");
249 for (char j=0;j<8;j++) {
250 tohex(val, romid[j]);
251 msg_write(val);
252 }
253 msg_write(" ");
254 tohex(val, scratch[1]);
255 msg_write(val);
256 tohex(val, scratch[0]);
257 msg_write(val);
258 if (usermode) msg_write("\r\n"); else msg_write("\n");
259 }
260
261 LED1 = 0;
262 if (!usermode) msg_write("END\n");
263
264 }else
265 if (cmd == '0')
266 {
267 drive_OW_low();
268 if (usermode)
269 msg_write("\rBUS low\r\n");
270 else
271 msg_write("LOW\n");
272 }else
273 if (cmd == '1')
274 {
275 drive_OW_high();
276 if (usermode)
277 msg_write("\rBUS high\r\n");
278 else
279 msg_write("HIGH\n");
280 }else
281 if (cmd == '3')
282 {
283 float_OW();
284 if (usermode)
285 msg_write("\rBUS to tri-state\r\n");
286 else
287 msg_write("TRISTATE\n");
288 }else
289 if (cmd == '!')
290 {
291 // this is to test that the watchdog actually works
292 msg_write("Play dead.\r\n");
293 while (1) { NOP(); }
294 }else
295 if (cmd == '?')
296 {
297 bool line = read_OW();
298 if (line) {
299 if (usermode) msg_write("\rBUS HIGH\r\n");
300 else
301 msg_write("HIGH\n");
302 } else {
303 if (usermode) msg_write("\rBUS LOW\r\n");
304 else msg_write("LOW\n");
305 }
306 }else
307 if (cmd == 'b' || cmd == 'B')
308 {
309 // Read Vdd by sampling FVR
310 FVRCONbits.ADFVR = 0b10; // 2.048v // 1.024v
311 FVRCONbits.FVREN = 1; // enable
312 while (!FVRCONbits.FVRRDY) {};
313 ADCON1bits.ADFM = 1; // right justify
314 ADCON0bits.CHS = 0b11111; // FVR input
315 ADCON1bits.ADPREF = 0b00; // +ve ref Vdd
316 ADCON0bits.ADON = 1; // enable ADC
317
318 ADCON0bits.GO = 1; // start conversion
319 while (ADCON0bits.GO) {}; // wait til finished
320
321 uint16_t volt = 0;
322 volt = (ADRESH << 8) | ADRESL;
323 uint16_t mv = (8192 / volt) * 1024;
324 mv /= 8;
325
326 msg_write("VOLTAGE ");
327 char val[3];
328 tohex(val, ADRESH);
329 msg_write(val);
330 tohex(val, ADRESL);
331 msg_write(val);
332 msg_write("\n");
333
334 ADCON0bits.ADON = 0; // turn off ADC
335 FVRCONbits.FVREN = 0; // turn of FVR
336 }else
337 {
338 if (usermode) {
339 msg_write("ERROR Press H for Help\n");
340 } else {
341 msg_write("\rERROR Unknown command '");
342 msg_writebyte(cmd);
343 msg_write("' Press 'H' for help.\r\n");
344 }
345 }
346
347 if (usermode) msg_write(prompt);
348 }
349}
350
351/* make a hex string from a value
352 * expect 3 char array */
353void tohex(char val[], uint8_t i)
354{
355 char bt = i >> 4;
356 if (bt > 9)
357 val[0] = 'A' + (bt - 10);
358 else
359 val[0] = '0' + bt;
360 bt = i & 0x0F;
361 if (bt > 9)
362 val[1] = 'A' + (bt - 10);
363 else
364 val[1] = '0' + bt;
365 val[2] = 0;
366}
367
368
369/* is the queue empty yet */
370bool msg_empty(void)
371{
372 if (outp == 0) return 1;
373 return 0;
374}
375
376/* new message in the queue */
377void msg_write(const char *msg)
378{
379 char * p = outbuff + outlen;
380 while (outlen < sizeof(outbuff) && *msg != 0) {
381 *(p++) = *(msg++);
382 outlen++;
383 }
384 *p = 0;
385 if (outp == 0) {
386 outp = outbuff;
387 PIE1bits.TXIE = 1;
388 }
389}
390
391void msg_writebyte(const char msg)
392{
393 if (outlen+1 >= (uint8_t)sizeof(outbuff)) return;
394 outbuff[outlen++] = msg;
395 outbuff[outlen] = 0;
396 if (outp == 0) {
397 outp = outbuff;
398 PIE1bits.TXIE = 1;
399 }
400}
401
402void putch(char data)
403{
404 msg_writebyte(data);
405}
406
407/* called from interrupt routine to send next char */
408void msg_sendnext(void)
409{
410 /* we have finished, turn off the iterrupt */
411 if (outp == 0 || *outp == 0) {
412 PIE1bits.TXIE = 0;
413 outp = 0;
414 outlen = 0;
415 return;
416 }
417 TXREG = *outp;
418 outp++;
419}
420
421/* called from interrupt routine to receive next byte */
422void msg_recvnext(void)
423{
424 while (PIR1bits.RCIF) {
425 bool err = RCSTAbits.FERR;
426 char new = RCREG;
427
428 /* bad char, skip it */
429 if (err) continue;
430
431 /* our input buffer has overflowed */
432 if (inlen > sizeof(inbuff)) return;
433
434 /* keep this one */
435 inbuff[inlen++] = new;
436 }
437}
438
439bool msg_recvready(void)
440{
441 if (inlen > 0) return 1;
442 return 0;
443}
444
445char msg_recv(void)
446{
447 if (inlen == 0) return 0;
448
449 /* record and disable the interupt */
450 bool in = PIE1bits.RCIE;
451 PIE1bits.RCIE = 0;
452
453 char new = inbuff[0];
454 inlen--;
455
456 /* shuffle them down one */
457 for (char i=0;i<inlen;i++)
458 inbuff[i] = inbuff[i+1];
459
460 /* restore the interupt */
461 PIE1bits.RCIE = in;
462 return new;
463}
464
465
466void int_disable(void)
467{
468 INTCONbits.GIE = 0;
469}
470
471void int_enable(void)
472{
473 INTCONbits.GIE = 1;
474}