?? pwm.c
字號:
/*
* pwm.c
*
* Copyright (C) STMicroelectronics Limited 2004. All rights reserved.
*
* In-built timer management for ST20-C1.
*/
#include <c1timer.h>
#include <interrup.h>
#include <osassert.h>
#include <ostime.h>
#include <task.h>
#include "pwm.h"
#ifdef C1_CORE
static int limit (int min, int val, int max)
{
return val < min ? min :
val > max ? max :
val;
}
static void *pwm_base_address;
static int pwm_raised, pwm_number;
static void pwm_raise(void)
{
pwm_raised = 1;
interrupt_raise_number(pwm_number);
}
#define PWM3 ((pwm3_t *) pwm_base_address)
static int pwm3_read(void) { return PWM3->CaptureCount; }
static void pwm3_set(int value) { PWM3->CompareVal0 = value; }
static void pwm3_enable(void) { PWM3->IntEnable.CompareInt0 = 1; }
static void pwm3_disable(void) { PWM3->IntEnable.CompareInt0 = 0; }
static timer_api_t pwm3_api = { pwm3_read, pwm3_set, pwm3_enable, pwm3_disable, pwm_raise };
static void pwm3_interrupt(pwm3_t *pwm3)
{
while ((pwm3->IntStatus.CompareInt0 && pwm3->IntEnable.CompareInt0) || pwm_raised) {
pwm_raised = 0;
pwm3->IntAck.CompareInt0 = 1;
timer_interrupt();
}
}
static void pwm3_init(pwm3_t *pwm3, int freq)
{
/* timeslice tick is hardwired. no config required. */
/* calculate the system clock frequency (see pwm4_init for details) and enable */
pwm3->Control.CaptureClkValue = limit(0, (freq*1000 / 15625) - 1, 31);
time_ticks_per_sec_set((freq * 1000) / (pwm3->Control.CaptureClkValue + 1));
pwm3->Control.CaptureEnable = 1;
/* set up capture counter hardware */
pwm3->CaptureCount = 0;
pwm3->IntEnable.CompareInt0 = 0;
pwm3->IntAck.CompareInt0 = ~0;
}
#define PWM4 ((pwm4_t *) pwm_base_address)
static int pwm4_read(void) { return PWM4->CaptureCount; }
static void pwm4_set(int value) { PWM4->CompareVal0 = value; }
static void pwm4_enable(void) { PWM4->IntEnable.CompareInt0 = 1; }
static void pwm4_disable(void) { PWM4->IntEnable.CompareInt0 = 0; }
static timer_api_t pwm4_api = { pwm4_read, pwm4_set, pwm4_enable, pwm4_disable, pwm_raise };
static void pwm4_interrupt(pwm4_t *pwm4)
{
while ((pwm4->IntStatus.CompareInt0 && pwm4->IntEnable.CompareInt0) || pwm_raised) {
pwm_raised = 0;
pwm4->IntAck.CompareInt0 = 1;
timer_interrupt();
}
}
static void pwm4_init(pwm4_t *pwm4, int freq)
{
/* calculate and enable the C1 timeslice tick (freq is in khz)
*
* based on: target_khz * c1_slice_divide = freq / (pwm_divide * (prescale + 1)
*
* where: target_khz = 0.5 (2ms timeslice)
* c1_slice_divide = 64
* pwm_divide = 256
*
* thus: 0.5 * 64 = freq / 256 * (prescale+1)
* or: prescale = (freq / (256 * 0.5 * 64)) - 1
* = (freq / 8192) - 1
*
*/
pwm4->Control.PWMClkValue = limit(0, (freq / 8192) - 1, 15);
pwm4->Control.PWMEnable = 1;
/* calculate the system clock frequency (freq is in khz) and enable
*
* based on: target_khz = freq / (prescale + 1)
*
* where: target_khz = 15.625
*
* thus: 15.625 = freq / (prescale + 1)
* or: prescale = (freq / 15.625) - 1
*
* note: since we perform the calculation as integers then we will
* overflow if freq is greater than 2GHz.
*/
pwm4->Control.CaptureClkValue = limit(0, (freq*1000 / 15625) - 1, 31);
time_ticks_per_sec_set((freq * 1000) / (pwm4->Control.CaptureClkValue + 1));
pwm4->Control.CaptureEnable = 1;
/* set up capture counter hardware */
pwm4->CaptureCount = 0;
pwm4->IntEnable.CompareInt0 = 0;
pwm4->IntAck.CompareInt0 = ~0;
}
int timer_init_pwm(void *base, int number, int level, int freq,
timer_init_pwm_flags_t flags)
{
void (*interrupt)();
void (*init)();
timer_api_t *api;
int err;
FATAL_ERROR_IF_NOT_TASK();
FATAL_ERROR_IF_NULL(base);
FATAL_ERROR_IF(freq > 2000000, "at frequencies over 2GHz internal "
"calculations will overflow");
FATAL_ERROR_IF(pwm_base_address, "timer_init_pwm() can only be called once");
/* switch between PWM3 and PWM4 */
if (timer_init_pwm_flags_pwm3 & flags) {
interrupt = pwm3_interrupt;
init = pwm3_init;
api = &pwm3_api;
} else {
interrupt = pwm4_interrupt;
init = pwm4_init;
api = &pwm4_api;
}
err = interrupt_install(number, level, interrupt, base);
if (0 != err) {
return err;
}
pwm_base_address = base;
pwm_number = number;
init(base, freq);
timer_initialize(api);
return 0;
}
#endif /* C1_CORE */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -