phase.c
Go to the documentation of this file.00001
00040 #include "hw/hw_phase.h"
00041
00042 #include <cfg/macros.h>
00043 #include <cfg/compiler.h>
00044
00045 #include <cpu/irq.h>
00046 #include <cpu/types.h>
00047
00048 #include <drv/timer.h>
00049 #include <drv/phase.h>
00050
00051 #include <math.h>
00052
00054 static Triac triacs[TRIAC_CNT];
00055
00056 DB(bool phase_initialized;)
00057
00065 DEFINE_ZEROCROSS_ISR()
00066 {
00067 ticks_t period, now;
00068 static ticks_t prev_time;
00069 TriacDev dev;
00070
00071 now = timer_clock_unlocked();
00072 period = now - prev_time;
00073
00074 for (dev = 0; dev < TRIAC_CNT; dev++)
00075 {
00076
00077 if (triacs[dev].duty != CONFIG_TRIAC_MAX_DUTY)
00078 TRIAC_OFF(dev);
00079
00080 timer_setDelay(&triacs[dev].timer, DIV_ROUND(period * (CONFIG_TRIAC_MAX_DUTY - triacs[dev].duty), CONFIG_TRIAC_MAX_DUTY));
00081
00082
00083
00084 if (triacs[dev].running)
00085 {
00086 timer_abort(&triacs[dev].timer);
00087
00088 }
00089
00090 triacs[dev].running = true;
00091 timer_add(&triacs[dev].timer);
00092 }
00093 prev_time = now;
00094 }
00095
00096
00097
00101 void phase_setDuty(TriacDev dev, triac_duty_t duty)
00102 {
00103 cpu_flags_t flags;
00104 IRQ_SAVE_DISABLE(flags);
00105
00106 phase_setDutyUnlock(dev,duty);
00107
00108 IRQ_RESTORE(flags);
00109 }
00110
00111
00112
00116 void phase_setDutyUnlock(TriacDev dev, triac_duty_t duty)
00117 {
00118 triacs[dev].duty = MIN(duty, (triac_duty_t)CONFIG_TRIAC_MAX_DUTY);
00119 }
00120
00121
00122
00129 void phase_setPower(TriacDev dev, triac_power_t power)
00130 {
00131 bool greater_fifty = false;
00132 triac_duty_t duty;
00133
00134 power = MIN(power, (triac_power_t)CONFIG_TRIAC_MAX_POWER);
00135
00136 if (power > CONFIG_TRIAC_MAX_POWER / 2)
00137 {
00138 greater_fifty = true;
00139 power = CONFIG_TRIAC_MAX_POWER - power;
00140 }
00141
00142 duty = TRIAC_POWER_K * sqrt(power);
00143
00144 if (greater_fifty)
00145 duty = CONFIG_TRIAC_MAX_DUTY - duty;
00146 phase_setDuty(dev, duty);
00147 }
00148
00149
00150
00156 static void phase_softint(void *_dev)
00157 {
00158 TriacDev dev = (TriacDev)_dev;
00159
00160
00161 if (triacs[dev].duty)
00162 TRIAC_ON(dev);
00163 triacs[dev].running = false;
00164 }
00165
00166
00167
00171 void phase_init(void)
00172 {
00173 cpu_flags_t flags;
00174 TriacDev dev;
00175
00176
00177 for (dev = 0; dev < TRIAC_CNT; dev++)
00178 {
00179 triacs[dev].duty = 0;
00180 triacs[dev].running = false;
00181 SET_TRIAC_DDR(dev);
00182 TRIAC_OFF(dev);
00183 timer_setSoftint(&triacs[dev].timer, (Hook)phase_softint, (void *)dev);
00184 }
00185 IRQ_SAVE_DISABLE(flags);
00186
00187
00188 PHASE_HW_INIT;
00189 DB(phase_initialized = true;)
00190 IRQ_RESTORE(flags);
00191 }
00192