BeRTOS
pwm.c
Go to the documentation of this file.
00001 
00040 #include "cfg/cfg_pwm.h"
00041 
00042 #include <cfg/macros.h>
00043 #include <cfg/module.h>
00044 
00045 // Define logging setting (for cfg/log.h module).
00046 #define LOG_LEVEL         PWM_LOG_LEVEL
00047 #define LOG_VERBOSITY     PWM_LOG_FORMAT
00048 
00049 #include <cfg/log.h>
00050 #include <cfg/debug.h>
00051 
00052 #include <drv/pwm.h>
00053 
00054 #include CPU_HEADER(pwm)
00055 
00056 #include <cpu/types.h>
00057 #include <cpu/irq.h>
00058 
00059 #include <string.h>
00060 
00061 #if CFG_PWM_ENABLE_OLD_API
00062 
00069     void pwm_setDuty(PwmDev dev, pwm_duty_t duty)
00070     {
00071         pwm_period_t period = 0;
00072         pwm_duty_t real_duty = 0;
00073 
00074         duty = MIN(duty, PWM_MAX_DUTY);
00075 
00076         period = pwm_hw_getPeriod(dev);
00077 
00078         real_duty = (uint64_t)(duty * period) >> (uint64_t)PWM_MAX_PERIOD_LOG2;
00079 
00080         LOG_INFO("real_duty[%d] duty[%d], period[%d]\n", real_duty, duty, period);
00081         pwm_hw_setDutyUnlock(dev, real_duty);
00082     }
00083 
00093     void pwm_setFrequency(PwmDev dev, pwm_freq_t freq)
00094     {
00095         pwm_hw_setFrequency(dev, freq);
00096     }
00097 
00103     void pwm_enable(PwmDev dev, bool state)
00104     {
00105         if (state)
00106             pwm_hw_enable(dev);
00107         else
00108             pwm_hw_disable(dev);
00109     }
00110 
00111     MOD_DEFINE(pwm);
00112 
00117     void pwm_init(void)
00118     {
00119         cpu_flags_t flags;
00120         PwmDev dev;
00121 
00122         IRQ_SAVE_DISABLE(flags);
00123 
00124         pwm_hw_init();
00125 
00126         /* set all pwm to 0 */
00127         for (dev = 0; dev < PWM_CNT; dev++)
00128             pwm_setDuty(dev, 0);
00129 
00130         IRQ_RESTORE(flags);
00131         MOD_INIT(pwm);
00132     }
00133 #endif
00134 
00135 #if !CFG_PWM_ENABLE_OLD_API || defined(__doxygen__)
00136 
00137     INLINE void setRealDuty(Pwm *ctx, pwm_duty_t duty)
00138     {
00139         if (ctx->pol == PWM_POL_LOW_PULSE)
00140             duty = PWM_MAX_DUTY - duty;
00141 
00142         pwm_hwreg_t period = pwm_hw_getPeriod(ctx);
00143         pwm_hwreg_t hw_duty;
00144 
00145         switch (duty)
00146         {
00147         case 0:
00148             hw_duty = 0;
00149             break;
00150         case PWM_MAX_DUTY:
00151             hw_duty = period;
00152             break;
00153         default:
00154             hw_duty = (uint64_t)(duty * period) >> (uint64_t)PWM_MAX_PERIOD_LOG2;
00155         }
00156 
00157         pwm_hw_setDuty(ctx, hw_duty);
00158     }
00159 
00168     void pwm_setDuty(Pwm *ctx, pwm_duty_t duty)
00169     {
00170         ctx->duty = duty;
00171 
00172         if (ctx->enabled)
00173             setRealDuty(ctx, duty);
00174     }
00175 
00185     void pwm_setFrequency(Pwm *ctx, pwm_freq_t freq)
00186     {
00187         pwm_hw_setFrequency(ctx, freq);
00188         pwm_enable(ctx, ctx->enabled);
00189     }
00190 
00202     void pwm_setPolarity(Pwm *ctx, PwmPolarity pol)
00203     {
00204         ctx->pol = pol;
00205         pwm_enable(ctx, ctx->enabled);
00206     }
00207 
00220     void pwm_enable(Pwm *ctx, bool enable)
00221     {
00222         ctx->enabled = enable;
00223 
00224         if (enable)
00225             setRealDuty(ctx, ctx->duty);
00226         else
00227             setRealDuty(ctx, 0);
00228     }
00229 
00237     void pwm_init(Pwm *ctx, unsigned channel)
00238     {
00239         memset(ctx, 0, sizeof(*ctx));
00240         ctx->ch = channel;
00241 
00242         pwm_hw_init(ctx, channel);
00243     }
00244 
00245 #endif
00246 
00247