New example board: reprap
[simavr] / examples / board_reprap / thermistor.c
1 /*
2         thermistor.c
3
4         Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
5
6         This file is part of simavr.
7
8         simavr is free software: you can redistribute it and/or modify
9         it under the terms of the GNU General Public License as published by
10         the Free Software Foundation, either version 3 of the License, or
11         (at your option) any later version.
12
13         simavr is distributed in the hope that it will be useful,
14         but WITHOUT ANY WARRANTY; without even the implied warranty of
15         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16         GNU General Public License for more details.
17
18         You should have received a copy of the GNU General Public License
19         along with simavr.  If not, see <http://www.gnu.org/licenses/>.
20  */
21
22 #include <stdlib.h>
23 #include <pthread.h>
24 #include <string.h>
25 #include <stdio.h>
26 #include <errno.h>
27 #include <unistd.h>
28
29 #include "avr_adc.h"
30
31 #include "thermistor.h"
32
33 /*
34  * called when a byte is send via the uart on the AVR
35  */
36 static void thermistor_in_hook(struct avr_irq_t * irq, uint32_t value, void * param)
37 {
38         thermistor_p p = (thermistor_p)param;
39         avr_adc_mux_t v = *((avr_adc_mux_t*)&value);
40
41 //      printf("%s(%2d/%2d)\n", __func__, p->adc_mux_number, v.src);
42
43         if (v.src != p->adc_mux_number)
44                 return;
45
46         short *t = p->table;
47         for (int ei = 0; ei < p->table_entries; ei++, t += 2) {
48                 if (t[1] < p->current) {
49                         printf("%s(%2d) %.2f matches %3dC is %d adc\n", __func__, v.src,
50                                         p->current, t[1], t[0] / p->oversampling);
51                         avr_raise_irq(p->irq + IRQ_TERM_ADC_VALUE_OUT, t[0] / p->oversampling);
52                         return;
53                 }
54         }
55         printf("%s(%d) temperature out of range (%.2f), we're screwed\n",
56                         __func__, p->adc_mux_number, p->current);
57 }
58
59 static const char * irq_names[IRQ_TERM_COUNT] = {
60         [IRQ_TERM_ADC_TRIGGER_IN] = "8<thermistor.trigger",
61         [IRQ_TERM_TEMP_VALUE_OUT] = "16>thermistor.out",
62 };
63
64 void
65 thermistor_init(
66                 struct avr_t * avr,
67                 thermistor_p p,
68                 int adc_mux_number,
69                 short * table,
70                 int     table_entries,
71                 int oversampling,
72                 float start_temp )
73 {
74         p->avr = avr;
75         p->irq = avr_alloc_irq(&avr->irq_pool, 0, IRQ_TERM_COUNT, irq_names);
76         avr_irq_register_notify(p->irq + IRQ_TERM_ADC_TRIGGER_IN, thermistor_in_hook, p);
77
78         p->oversampling = oversampling;
79         p->table = table;
80         p->table_entries = table_entries;
81         p->adc_mux_number = adc_mux_number;
82         p->current = p->target = start_temp;
83
84         avr_irq_t * src = avr_io_getirq(p->avr, AVR_IOCTL_ADC_GETIRQ, ADC_IRQ_OUT_TRIGGER);
85         avr_irq_t * dst = avr_io_getirq(p->avr, AVR_IOCTL_ADC_GETIRQ, adc_mux_number);
86         if (src && dst) {
87                 avr_connect_irq(src, p->irq + IRQ_TERM_ADC_TRIGGER_IN);
88                 avr_connect_irq(p->irq + IRQ_TERM_ADC_VALUE_OUT, dst);
89         }
90         printf("%s on ADC %d start %.2f\n", __func__, adc_mux_number, p->current);
91 }
92
93 void
94 thermistor_set_temp(
95                 thermistor_p t,
96                 float temp )
97 {
98
99 }