1.优化定时器允许模式.
This commit is contained in:
@@ -26,7 +26,7 @@ static mr_uint32_t mr_timer_timeout_calculate(mr_timer_t timer, mr_uint32_t time
|
||||
count = 1;
|
||||
}
|
||||
|
||||
if (count < timer->information.max_cut)
|
||||
if (count < timer->info.max_cnt)
|
||||
{
|
||||
timer->reload = 1;
|
||||
timer->cycles = timer->reload;
|
||||
@@ -34,16 +34,16 @@ static mr_uint32_t mr_timer_timeout_calculate(mr_timer_t timer, mr_uint32_t time
|
||||
return count;
|
||||
}
|
||||
|
||||
if (count % timer->information.max_cut == 0)
|
||||
if (count % timer->info.max_cnt == 0)
|
||||
{
|
||||
timer->reload = count / timer->information.max_cut;
|
||||
timer->reload = count / timer->info.max_cnt;
|
||||
timer->cycles = timer->reload;
|
||||
timer->timeout = timer->information.max_cut * timer_period;
|
||||
return timer->information.max_cut;
|
||||
timer->timeout = timer->info.max_cnt * timer_period;
|
||||
return timer->info.max_cnt;
|
||||
}
|
||||
|
||||
/* Calculate the Least error reload */
|
||||
reload_min = count / timer->information.max_cut + 1;
|
||||
reload_min = count / timer->info.max_cnt + 1;
|
||||
reload_max = count / 5;
|
||||
error_min = reload_min;
|
||||
for (i = reload_min; i < reload_max; i++)
|
||||
@@ -54,8 +54,7 @@ static mr_uint32_t mr_timer_timeout_calculate(mr_timer_t timer, mr_uint32_t time
|
||||
{
|
||||
reload_best = i;
|
||||
break;
|
||||
}
|
||||
else if (error < error_min)
|
||||
} else if (error < error_min)
|
||||
{
|
||||
error_min = error;
|
||||
reload_best = i;
|
||||
@@ -74,15 +73,14 @@ static mr_err_t mr_timer_open(mr_device_t device)
|
||||
mr_timer_t timer = (mr_timer_t)device;
|
||||
struct mr_timer_config config = MR_TIMER_CONFIG_DEFAULT;
|
||||
|
||||
/* Setting timer to default config, if the frequency not set */
|
||||
if (timer->config.freq == 0)
|
||||
{
|
||||
timer->config = config;
|
||||
}
|
||||
|
||||
if (timer->config.freq > timer->information.max_freq)
|
||||
{
|
||||
return -MR_ERR_GENERIC;
|
||||
}
|
||||
/* Check the frequency */
|
||||
mr_limit(timer->config.freq, timer->info.min_freq, timer->info.max_freq);
|
||||
|
||||
return timer->ops->configure(timer, &timer->config);
|
||||
}
|
||||
@@ -91,7 +89,7 @@ static mr_err_t mr_timer_close(mr_device_t device)
|
||||
{
|
||||
mr_timer_t timer = (mr_timer_t)device;
|
||||
|
||||
/* Setting timer to close-config */
|
||||
/* Setting timer to close config */
|
||||
timer->config.freq = 0;
|
||||
|
||||
return timer->ops->configure(timer, &timer->config);
|
||||
@@ -101,6 +99,7 @@ static mr_err_t mr_timer_ioctl(mr_device_t device, int cmd, void *args)
|
||||
{
|
||||
mr_timer_t timer = (mr_timer_t)device;
|
||||
mr_err_t ret = MR_ERR_OK;
|
||||
struct mr_timer_config *config = (struct mr_timer_config *)args;
|
||||
|
||||
switch (cmd & _MR_CTRL_FLAG_MASK)
|
||||
{
|
||||
@@ -109,10 +108,7 @@ static mr_err_t mr_timer_ioctl(mr_device_t device, int cmd, void *args)
|
||||
if (args)
|
||||
{
|
||||
/* Check the frequency */
|
||||
if (((struct mr_timer_config *)args)->freq > timer->information.max_freq)
|
||||
{
|
||||
return -MR_ERR_GENERIC;
|
||||
}
|
||||
mr_limit(config->freq, timer->info.min_freq, timer->info.max_freq);
|
||||
|
||||
ret = timer->ops->configure(timer, (struct mr_timer_config *)args);
|
||||
if (ret == MR_ERR_OK)
|
||||
@@ -148,20 +144,21 @@ static mr_ssize_t mr_timer_read(mr_device_t device, mr_off_t pos, void *buffer,
|
||||
{
|
||||
mr_timer_t timer = (mr_timer_t)device;
|
||||
mr_uint32_t *recv_buffer = (mr_uint32_t *)buffer;
|
||||
mr_uint32_t cut = 0;
|
||||
mr_uint32_t cnt = 0;
|
||||
|
||||
if (size < sizeof(*recv_buffer))
|
||||
{
|
||||
return -MR_ERR_INVALID;
|
||||
}
|
||||
|
||||
cut = timer->ops->get_count(timer);
|
||||
if (timer->information.cut_mode == _MR_TIMER_CUT_MODE_DOWN)
|
||||
/* Get the count */
|
||||
cnt = timer->ops->get_count(timer);
|
||||
if (timer->info.cnt_mode == _MR_TIMER_CNT_MODE_DOWN)
|
||||
{
|
||||
cut = timer->timeout / (1000000 / timer->config.freq) - cut;
|
||||
cnt = timer->timeout / (1000000 / timer->config.freq) - cnt;
|
||||
}
|
||||
|
||||
*recv_buffer = timer->overflow * timer->timeout + cut * (1000000 / timer->config.freq);
|
||||
*recv_buffer = timer->overflow * timer->timeout + cnt * (1000000 / timer->config.freq);
|
||||
|
||||
return sizeof(*recv_buffer);
|
||||
}
|
||||
@@ -177,11 +174,6 @@ static mr_ssize_t mr_timer_write(mr_device_t device, mr_off_t pos, const void *b
|
||||
return -MR_ERR_INVALID;
|
||||
}
|
||||
|
||||
if (timer->config.freq == 0)
|
||||
{
|
||||
return -MR_ERR_GENERIC;
|
||||
}
|
||||
|
||||
timer->ops->stop(timer);
|
||||
timer->overflow = 0;
|
||||
period_reload = mr_timer_timeout_calculate(timer, *send_buffer);
|
||||
@@ -189,8 +181,9 @@ static mr_ssize_t mr_timer_write(mr_device_t device, mr_off_t pos, const void *b
|
||||
/* When the time is not less than one time, the timer is started */
|
||||
if (timer->cycles != 0)
|
||||
{
|
||||
timer->ops->start(timer, period_reload);
|
||||
return -MR_ERR_INVALID;
|
||||
}
|
||||
timer->ops->start(timer, period_reload);
|
||||
|
||||
return sizeof(*send_buffer);
|
||||
}
|
||||
@@ -240,7 +233,8 @@ mr_err_t mr_timer_device_add(mr_timer_t timer,
|
||||
MR_ASSERT(ops != MR_NULL);
|
||||
MR_ASSERT(info != MR_NULL);
|
||||
MR_ASSERT(info->max_freq != 0);
|
||||
MR_ASSERT(info->max_cut != 0);
|
||||
MR_ASSERT(info->min_freq != 0);
|
||||
MR_ASSERT(info->max_cnt != 0);
|
||||
|
||||
/* Add the timer-device to the container */
|
||||
ret = mr_device_add(&timer->device, name, MR_DEVICE_TYPE_TIMER, MR_OPEN_RDWR, &device_ops, data);
|
||||
@@ -251,7 +245,7 @@ mr_err_t mr_timer_device_add(mr_timer_t timer,
|
||||
|
||||
/* Initialize the timer fields */
|
||||
timer->config.freq = 0;
|
||||
timer->information = *info;
|
||||
timer->info = *info;
|
||||
timer->reload = 0;
|
||||
timer->cycles = 0;
|
||||
timer->overflow = 0;
|
||||
@@ -277,11 +271,6 @@ void mr_timer_device_isr(mr_timer_t timer, mr_uint16_t event)
|
||||
{
|
||||
timer->overflow++;
|
||||
|
||||
if (timer->cycles != 0)
|
||||
{
|
||||
timer->cycles--;
|
||||
}
|
||||
|
||||
/* Timeout */
|
||||
if (timer->cycles == 0)
|
||||
{
|
||||
@@ -299,6 +288,10 @@ void mr_timer_device_isr(mr_timer_t timer, mr_uint16_t event)
|
||||
timer->device.rx_cb(&timer->device, MR_NULL);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
timer->cycles--;
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
#define MR_TIMER_MODE_PERIOD 0
|
||||
#define MR_TIMER_MODE_ONE_SHOT 1
|
||||
|
||||
#define _MR_TIMER_CUT_MODE_UP 0
|
||||
#define _MR_TIMER_CUT_MODE_DOWN 1
|
||||
#define _MR_TIMER_CNT_MODE_UP 0
|
||||
#define _MR_TIMER_CNT_MODE_DOWN 1
|
||||
|
||||
#define MR_TIMER_EVENT_PIT_INT 0x1000
|
||||
#define _MR_TIMER_EVENT_MASK 0xf000
|
||||
@@ -27,7 +27,7 @@
|
||||
/* Default config for mr_timer_config structure */
|
||||
#define MR_TIMER_CONFIG_DEFAULT \
|
||||
{ \
|
||||
1000, \
|
||||
1000000, \
|
||||
MR_TIMER_MODE_PERIOD, \
|
||||
}
|
||||
|
||||
@@ -40,8 +40,9 @@ struct mr_timer_config
|
||||
struct mr_timer_info
|
||||
{
|
||||
mr_uint32_t max_freq;
|
||||
mr_uint32_t max_cut;
|
||||
mr_uint8_t cut_mode;
|
||||
mr_uint32_t min_freq;
|
||||
mr_uint32_t max_cnt;
|
||||
mr_uint8_t cnt_mode;
|
||||
};
|
||||
|
||||
typedef struct mr_timer *mr_timer_t;
|
||||
@@ -59,7 +60,7 @@ struct mr_timer
|
||||
struct mr_device device;
|
||||
|
||||
struct mr_timer_config config;
|
||||
struct mr_timer_info information;
|
||||
struct mr_timer_info info;
|
||||
mr_uint32_t reload;
|
||||
mr_uint32_t cycles;
|
||||
mr_uint32_t overflow;
|
||||
|
||||
Reference in New Issue
Block a user