Update benchmark projects.
[bertos.git] / bertos / drv / thermo.c
index fb8cbb7958ccda1bedc1a59444bcd58534118b18..6fa5ba2ed7f869086cf6108fa42c61cdbadbbb99 100644 (file)
  *
  * -->
  *
- * \brief Thermo-control driver
+ * \brief Thermo-control driver.
  *
- * \version $Id$
+ * The Thermo controll can works both with kernel or without it. In the case
+ * we use kernel, the thermo controll is done by one process that poll every
+ * CONFIG_THERMO_INTERVAL_MS the temperature sensor and make all operation to
+ * follow the target temperature. While we not use the kernel the module works
+ * with one timer interrupt in the same way of the kenel case.
  *
  * \author Giovanni Bajo <rasky@develer.com>
  * \author Francesco Sacchi <batt@develer.com>
+ * \author Daniele Basile <asterix@develer.com>
+ *
  */
 
-/*#*
- *#* $Log$
- *#* Revision 1.3  2006/09/20 20:12:41  marco
- *#* Names convention, MOD_* macros.
- *#*
- *#* Revision 1.2  2006/07/19 12:56:26  bernie
- *#* Convert to new Doxygen style.
- *#*
- *#* Revision 1.1  2005/11/04 17:59:47  bernie
- *#* Import into DevLib.
- *#*
- *#*/
-#include <thermo_map.h>
-#include <hw_thermo.h>
+#include "hw/thermo_map.h"
+#include "hw/hw_thermo.h"
+
+#include "cfg/cfg_thermo.h"
+
+#include <cfg/module.h>
+#include <cfg/macros.h>
+#include <cfg/debug.h>
+// Define logging setting (for cfg/log.h module).
+#define LOG_LEVEL         CONFIG_THERMO_LOG_LEVEL
+#define LOG_VERBOSITY     CONFIG_THERMO_LOG_FORMAT
+#include <cfg/log.h>
 
 #include <drv/thermo.h>
 #include <drv/timer.h>
 #include <drv/ntc.h>
 
-#include <cfg/macros.h>
-#include <cfg/debug.h>
+#include <kern/proc.h>
 
+#define THERMO_OFF          0
+#define THERMO_HEATING      BV(0)
+#define THERMO_FREEZING     BV(1)
+#define THERMO_TGT_REACH    BV(2)
+#define THERMOERRF_NTCSHORT BV(3)
+#define THERMOERRF_NTCOPEN  BV(4)
+#define THERMOERRF_TIMEOUT  BV(5)
+#define THERMO_ACTIVE       BV(6)
+#define THERMO_TIMER        BV(7)
 
-/** Interval at which thermo control is performed. */
-#define THERMO_INTERVAL_MS      100
+#define THERMO_ERRMASK      (THERMOERRF_NTCSHORT | THERMOERRF_NTCOPEN | THERMOERRF_TIMEOUT)
 
-/** Number of different samples we interpolate over to get the hifi temperature. */
-#define THERMO_HIFI_NUM_SAMPLES 10
 
-/** Timer for thermo-regulation. */
-static Timer thermo_timer;
+#if CONFIG_KERN
+       /** Stack process for Thermo process. */
+       static PROC_DEFINE_STACK(thermo_poll_stack, 400);
+#else
+       /** Timer for thermo-regulation. */
+       static Timer thermo_timer;
+#endif
 
 typedef struct ThermoControlDev
 {
-       deg_t          hifi_samples[THERMO_HIFI_NUM_SAMPLES];
+       deg_t          hifi_samples[CONFIG_THERMO_HIFI_NUM_SAMPLES];
        deg_t          cur_hifi_sample;
        deg_t          target;
        thermostatus_t status;
        ticks_t        expire;
+       ticks_t        on_time;
 } ThermoControlDev;
 
 /** Array of thermo-devices. */
 ThermoControlDev devs[THERMO_CNT];
 
-
 /**
  * Return the status of the specific \a dev thermo-device.
  */
 thermostatus_t thermo_status(ThermoDev dev)
 {
+       ASSERT(dev < THERMO_CNT);
        return devs[dev].status;
 }
 
@@ -105,7 +120,7 @@ static void thermo_do(ThermoDev index)
 
        // Store the sample into the hifi FIFO buffer for later interpolation
        dev->hifi_samples[dev->cur_hifi_sample] = cur_temp;
-       if (++dev->cur_hifi_sample == THERMO_HIFI_NUM_SAMPLES)
+       if (++dev->cur_hifi_sample == CONFIG_THERMO_HIFI_NUM_SAMPLES)
                dev->cur_hifi_sample = 0;
 
        cur_temp = thermo_readTemperature(index);
@@ -114,18 +129,17 @@ static void thermo_do(ThermoDev index)
        {
                if (cur_temp == NTC_SHORT_CIRCUIT)
                {
-                       #ifdef _DEBUG
-                       if (!(dev->status & THERMOERRF_NTCSHORT))
-                               kprintf("dev[%d], thermo_do: NTC_SHORT\n",index);
-                       #endif
+                       LOG_INFOB(if (!(dev->status & THERMOERRF_NTCSHORT))
+                               LOG_INFO("dev[%d], thermo_do: NTC_SHORT\n",index););
+
                        dev->status |= THERMOERRF_NTCSHORT;
                }
                else
                {
-                       #ifdef _DEBUG
-                       if (!(dev->status & THERMOERRF_NTCOPEN))
-                               kprintf("dev[%d], thermo_do: NTC_OPEN\n", index);
-                       #endif
+
+                       LOG_INFOB(if (!(dev->status & THERMOERRF_NTCOPEN))
+                               LOG_INFO("dev[%d], thermo_do: NTC_OPEN\n", index););
+
                        dev->status |= THERMOERRF_NTCOPEN;
                }
 
@@ -144,7 +158,7 @@ static void thermo_do(ThermoDev index)
                if (timer_clock() - dev->expire > 0)
                {
                        dev->status |= THERMOERRF_TIMEOUT;
-                       kprintf("dev[%d], thermo_do: TIMEOUT\n", index);
+                       LOG_INFO("dev[%d], thermo_do: TIMEOUT\n", index);
                }
        }
        else /* In target */
@@ -166,18 +180,52 @@ static void thermo_do(ThermoDev index)
 
 }
 
-
-/**
- * Thermo soft interrupt.
- */
-static void thermo_softint(void)
+static void poll(void)
 {
-       int i;
-       for (i = 0; i < THERMO_CNT; ++i)
+       for (int i = 0; i < THERMO_CNT; ++i)
                if (devs[i].status & THERMO_ACTIVE)
+               {
+                       LOG_INFO("THERMO [%d] on_time[%ld],\n", i, ticks_to_ms(devs[i].on_time));
+                       if ((devs[i].status & THERMO_TIMER) && (devs[i].on_time - timer_clock() < 0))
+                       {
+                               thermo_stop(i);
+                               continue;
+                       }
+
                        thermo_do((ThermoDev)i);
+               }
+}
 
-       timer_add(&thermo_timer);
+#if CONFIG_KERN
+       static void NORETURN thermo_poll(void)
+       {
+               for (;;)
+               {
+                       poll();
+                       timer_delay(CONFIG_THERMO_INTERVAL_MS);
+               }
+       }
+#else
+       /**
+        * Thermo soft interrupt.
+        */
+       static void thermo_softint(void)
+       {
+               poll();
+               timer_add(&thermo_timer);
+       }
+#endif
+
+/**
+ * Starts a thermo-regulation for channel \a dev, and turn off timer
+ * when \a on_time was elapsed.
+ */
+void thermo_timer(ThermoDev dev, mtime_t on_time)
+{
+       ASSERT(dev < THERMO_CNT);
+       devs[dev].on_time = timer_clock() + ms_to_ticks(on_time);
+       devs[dev].status |= THERMO_TIMER;
+       thermo_start(dev);
 }
 
 
@@ -190,7 +238,7 @@ void thermo_setTarget(ThermoDev dev, deg_t temperature)
        devs[dev].target = temperature;
        devs[dev].expire = timer_clock() + thermo_hw_timeout(dev);
 
-       kprintf("setTarget dev[%d], T[%d.%d]\n", dev, temperature / 10, temperature % 10);
+       LOG_INFO("THERMO Set Target dev[%d], T[%d.%d]\n", dev, temperature / 10, temperature % 10);
 }
 
 /**
@@ -204,10 +252,11 @@ void thermo_start(ThermoDev dev)
        ASSERT(dev < THERMO_CNT);
 
        devs[dev].status |= THERMO_ACTIVE;
+       LOG_INFO("THERMO Start dev[%d], status[%04x]\n", dev, devs[dev].status);
 
        /* Initialize the hifi FIFO with a constant value (the current temperature) */
        temp = thermo_hw_read(dev);
-       for (i = 0; i < THERMO_HIFI_NUM_SAMPLES; ++i)
+       for (i = 0; i < CONFIG_THERMO_HIFI_NUM_SAMPLES; ++i)
                devs[dev].hifi_samples[i] = temp;
        devs[dev].cur_hifi_sample = 0;
 
@@ -247,10 +296,10 @@ deg_t thermo_readTemperature(ThermoDev dev)
 
        MOD_CHECK(thermo);
 
-       for (i = 0; i < THERMO_HIFI_NUM_SAMPLES; i++)
+       for (i = 0; i < CONFIG_THERMO_HIFI_NUM_SAMPLES; i++)
                accum += devs[dev].hifi_samples[i];
 
-       return (deg_t)(accum / THERMO_HIFI_NUM_SAMPLES);
+       return (deg_t)(accum / CONFIG_THERMO_HIFI_NUM_SAMPLES);
 }
 
 MOD_DEFINE(thermo)
@@ -268,7 +317,11 @@ void thermo_init(void)
 
        MOD_INIT(thermo);
 
-       timer_setDelay(&thermo_timer, ms_to_ticks(THERMO_INTERVAL_MS));
-       timer_set_event_softint(&thermo_timer, (Hook)thermo_softint, 0);
-       timer_add(&thermo_timer);
+       #if CONFIG_KERN
+               proc_new_with_name("Thermo", thermo_poll, NULL, sizeof(thermo_poll_stack), thermo_poll_stack);
+       #else
+               timer_setDelay(&thermo_timer, ms_to_ticks(CONFIG_THERMO_INTERVAL_MS));
+               timer_setSoftint(&thermo_timer, (Hook)thermo_softint, 0);
+               timer_add(&thermo_timer);
+       #endif
 }