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