thermo.c
Go to the documentation of this file.00001
00041 #include "hw/thermo_map.h"
00042 #include "hw/hw_thermo.h"
00043
00044 #include "cfg/cfg_thermo.h"
00045
00046 #include <cfg/module.h>
00047 #include <cfg/macros.h>
00048 #include <cfg/debug.h>
00049
00050 #include <drv/thermo.h>
00051 #include <drv/timer.h>
00052 #include <drv/ntc.h>
00053
00054
00055
00056
00058 static Timer thermo_timer;
00059
00060 typedef struct ThermoControlDev
00061 {
00062 deg_t hifi_samples[CONFIG_THERMO_HIFI_NUM_SAMPLES];
00063 deg_t cur_hifi_sample;
00064 deg_t target;
00065 thermostatus_t status;
00066 ticks_t expire;
00067 } ThermoControlDev;
00068
00070 ThermoControlDev devs[THERMO_CNT];
00071
00072
00076 thermostatus_t thermo_status(ThermoDev dev)
00077 {
00078 return devs[dev].status;
00079 }
00080
00081
00085 static void thermo_do(ThermoDev index)
00086 {
00087 ThermoControlDev* dev = &devs[index];
00088 deg_t cur_temp;
00089 deg_t tolerance = thermo_hw_tolerance(index);
00090
00091 cur_temp = thermo_hw_read(index);
00092
00093
00094 dev->hifi_samples[dev->cur_hifi_sample] = cur_temp;
00095 if (++dev->cur_hifi_sample == CONFIG_THERMO_HIFI_NUM_SAMPLES)
00096 dev->cur_hifi_sample = 0;
00097
00098 cur_temp = thermo_readTemperature(index);
00099
00100 if (cur_temp == NTC_SHORT_CIRCUIT || cur_temp == NTC_OPEN_CIRCUIT)
00101 {
00102 if (cur_temp == NTC_SHORT_CIRCUIT)
00103 {
00104 #ifdef _DEBUG
00105 if (!(dev->status & THERMOERRF_NTCSHORT))
00106 kprintf("dev[%d], thermo_do: NTC_SHORT\n",index);
00107 #endif
00108 dev->status |= THERMOERRF_NTCSHORT;
00109 }
00110 else
00111 {
00112 #ifdef _DEBUG
00113 if (!(dev->status & THERMOERRF_NTCOPEN))
00114 kprintf("dev[%d], thermo_do: NTC_OPEN\n", index);
00115 #endif
00116 dev->status |= THERMOERRF_NTCOPEN;
00117 }
00118
00119
00120 dev->expire = thermo_hw_timeout(index) + timer_clock();
00121 thermo_hw_off(index);
00122 return;
00123 }
00124 dev->status &= ~(THERMOERRF_NTCOPEN | THERMOERRF_NTCSHORT);
00125
00126 if ((cur_temp < dev->target - tolerance) || (cur_temp > dev->target + tolerance))
00127 {
00128 dev->status &= ~THERMO_TGT_REACH;
00129
00130
00131 if (timer_clock() - dev->expire > 0)
00132 {
00133 dev->status |= THERMOERRF_TIMEOUT;
00134 kprintf("dev[%d], thermo_do: TIMEOUT\n", index);
00135 }
00136 }
00137 else
00138 {
00139
00140 dev->status &= ~THERMO_ERRMASK;
00141 dev->status |= THERMO_TGT_REACH;
00142
00143
00144 dev->expire = thermo_hw_timeout(index) + timer_clock();
00145 }
00146
00147 if (cur_temp < dev->target)
00148 dev->status = (dev->status | THERMO_HEATING) & ~THERMO_FREEZING;
00149 else
00150 dev->status = (dev->status & ~THERMO_HEATING) | THERMO_FREEZING;
00151
00152 thermo_hw_set(index, dev->target, cur_temp);
00153
00154 }
00155
00156
00160 static void thermo_softint(void)
00161 {
00162 int i;
00163 for (i = 0; i < THERMO_CNT; ++i)
00164 if (devs[i].status & THERMO_ACTIVE)
00165 thermo_do((ThermoDev)i);
00166
00167 timer_add(&thermo_timer);
00168 }
00169
00170
00174 void thermo_setTarget(ThermoDev dev, deg_t temperature)
00175 {
00176 ASSERT(dev < THERMO_CNT);
00177 devs[dev].target = temperature;
00178 devs[dev].expire = timer_clock() + thermo_hw_timeout(dev);
00179
00180 kprintf("setTarget dev[%d], T[%d.%d]\n", dev, temperature / 10, temperature % 10);
00181 }
00182
00186 void thermo_start(ThermoDev dev)
00187 {
00188 int i;
00189 deg_t temp;
00190
00191 ASSERT(dev < THERMO_CNT);
00192
00193 devs[dev].status |= THERMO_ACTIVE;
00194
00195
00196 temp = thermo_hw_read(dev);
00197 for (i = 0; i < CONFIG_THERMO_HIFI_NUM_SAMPLES; ++i)
00198 devs[dev].hifi_samples[i] = temp;
00199 devs[dev].cur_hifi_sample = 0;
00200
00201
00202 devs[dev].expire = timer_clock() + thermo_hw_timeout(dev);
00203 }
00204
00208 void thermo_stop(ThermoDev dev)
00209 {
00210 ASSERT(dev < THERMO_CNT);
00211
00212 devs[dev].status &= ~THERMO_ACTIVE;
00213 thermo_hw_off(dev);
00214 }
00215
00216
00220 void thermo_clearErrors(ThermoDev dev)
00221 {
00222 ASSERT(dev < THERMO_CNT);
00223 devs[dev].status &= ~(THERMO_ERRMASK);
00224 }
00225
00226
00230 deg_t thermo_readTemperature(ThermoDev dev)
00231 {
00232 int i;
00233 long accum = 0;
00234
00235 MOD_CHECK(thermo);
00236
00237 for (i = 0; i < CONFIG_THERMO_HIFI_NUM_SAMPLES; i++)
00238 accum += devs[dev].hifi_samples[i];
00239
00240 return (deg_t)(accum / CONFIG_THERMO_HIFI_NUM_SAMPLES);
00241 }
00242
00243 MOD_DEFINE(thermo)
00244
00245
00248 void thermo_init(void)
00249 {
00250 THERMO_HW_INIT;
00251
00252
00253 for (int i = 0; i < THERMO_CNT; i++)
00254 devs[i].status = THERMO_OFF;
00255
00256 MOD_INIT(thermo);
00257
00258 timer_setDelay(&thermo_timer, ms_to_ticks(CONFIG_THERMO_INTERVAL_MS));
00259 timer_setSoftint(&thermo_timer, (Hook)thermo_softint, 0);
00260 timer_add(&thermo_timer);
00261 }