Skip to content

Commit

Permalink
timer_on, counter modules
Browse files Browse the repository at this point in the history
  • Loading branch information
catompiler committed Jun 27, 2024
1 parent 8d8d434 commit a2a2519
Show file tree
Hide file tree
Showing 7 changed files with 248 additions and 9 deletions.
43 changes: 43 additions & 0 deletions timer/counter.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#include "counter.h"
#include "modules/modules.h"
#include "utils/counter.h"


METHOD_INIT_IMPL(M_counter, cnt)
{
}

METHOD_DEINIT_IMPL(M_counter, cnt)
{
}

static void counter_control(M_counter* cnt)
{
if(cnt->control & CONTROL_START){
cnt->out_value = 0;
cnt->m_ref_counter = sys_time.r_counter_ms;

cnt->status = STATUS_RUN;
}
if(cnt->control & CONTROL_STOP){

cnt->status = STATUS_NONE;
}

cnt->control = CONTROL_NONE;
}

METHOD_CALC_IMPL(M_counter, cnt)
{
counter_control(cnt);

if(cnt->status & STATUS_RUN){
// Пройденное время с начала счёта.
cnt->out_value = counter_calc_diff(sys_time.r_counter_ms, cnt->m_ref_counter);
}
}

METHOD_CONTROL_IMPL(M_counter, cnt)
{
counter_control(cnt);
}
65 changes: 65 additions & 0 deletions timer/counter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#ifndef COUNTER_H
#define COUNTER_H

#include "module/base.h"


//! Перечисление возможных бит управления.
enum _E_Counter_Control {
COUNTER_CONTROL_NONE = CONTROL_NONE,
COUNTER_CONTROL_START = CONTROL_START,
COUNTER_CONTROL_STOP = CONTROL_STOP,
};

//! Перечисление возможных бит статуса.
enum _E_Counter_Status {
COUNTER_STATUS_NONE = STATUS_NONE,
COUNTER_STATUS_RUN = STATUS_RUN,
};

//! Предварительная декларация типа модуля.
typedef struct _S_Counter M_counter;

//! Структура модуля.
struct _S_Counter {
// Базовые поля.
control_t control; //!< Слово управления.
status_t status; //!< Слово состояния.
// Входные данные.
// Выходные данные.
reg_u32_t out_value; //!< Значение счётчика.
// Параметры.
// Регистры.
// Методы.
METHOD_INIT(M_counter);
METHOD_DEINIT(M_counter);
METHOD_CALC(M_counter);
METHOD_CONTROL(M_counter);
// Коллбэки.
// Внутренние данные.
uint32_t m_ref_counter; //!< Опорное значение счётчика.
};

EXTERN METHOD_INIT_PROTO(M_counter);
EXTERN METHOD_DEINIT_PROTO(M_counter);
EXTERN METHOD_CALC_PROTO(M_counter);
EXTERN METHOD_CONTROL_PROTO(M_counter);

#define COUNTER_DEFAULTS {\
/* Базовые поля */\
0, 0, /* control, status */\
/* Входные данные */\
/* Выходные данные */\
0, /* out_value */\
/* Параметры */\
/* Регистры */\
/* Методы */\
METHOD_INIT_PTR(M_counter), METHOD_DEINIT_PTR(M_counter),\
METHOD_CALC_PTR(M_counter),\
METHOD_CONTROL_PTR(M_counter),\
/* Коллбэки */\
/* Внутренние данные */\
0, /* m_ref_counter */\
}

#endif /* COUNTER_H */
11 changes: 2 additions & 9 deletions timer/timer.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "timer.h"
#include "modules/modules.h"
#include "utils/counter.h"


METHOD_INIT_IMPL(M_timer, tim)
Expand Down Expand Up @@ -32,14 +33,6 @@ static void timer_control(M_timer* tim)
tim->control = CONTROL_NONE;
}

static uint32_t timer_calc_diff(uint32_t ref, uint32_t cur)
{
// Текущее значение больше опорного - счётчик не переполнился.
if(cur >= ref) return cur - ref;
// Иначе cur < ref - счётчик переполнился.
return UINT32_MAX - ref + cur + 1;
}

METHOD_CALC_IMPL(M_timer, tim)
{
tim->out_timeout = STROBE_NONE;
Expand All @@ -48,7 +41,7 @@ METHOD_CALC_IMPL(M_timer, tim)

if(tim->status & STATUS_RUN){
// Пройденное время с начала счёта.
uint32_t elapsed_time = timer_calc_diff(tim->m_ref_counter, sys_time.r_counter_ms);
uint32_t elapsed_time = counter_calc_diff(sys_time.r_counter_ms, tim->m_ref_counter);
// Если времени прошло больше чем интервал таймера.
if(elapsed_time >= tim->r_interval){
tim->status = STATUS_NONE;
Expand Down
1 change: 1 addition & 0 deletions timer/timer.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ enum _E_Timer_Control {
//! Перечисление возможных бит статуса.
enum _E_Timer_Status {
TIMER_STATUS_NONE = STATUS_NONE,
TIMER_STATUS_RUN = STATUS_RUN,
};

//! Предварительная декларация типа модуля.
Expand Down
41 changes: 41 additions & 0 deletions timer/timer_on.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#include "timer_on.h"


METHOD_INIT_IMPL(M_timer_on, tmr)
{
}

METHOD_DEINIT_IMPL(M_timer_on, tmr)
{
}

METHOD_CALC_IMPL(M_timer_on, tmr)
{
tmr->m_ed.in_value = tmr->in_value;
CALC(tmr->m_ed);

flag_t res = FLAG_NONE;
flag_t cur = FLAG_NONE;

switch(tmr->m_ed.out_value){
default:
case EDGE_DETECT_LOW:
break;
case EDGE_DETECT_HIGH:
cur = FLAG_ACTIVE;
break;
case EDGE_DETECT_LEADING:
tmr->r_tmr.control = CONTROL_START;
CONTROL(tmr->r_tmr);
break;
case EDGE_DETECT_FALLING:
tmr->r_tmr.control = CONTROL_STOP;
CONTROL(tmr->r_tmr);
break;
}
CALC(tmr->r_tmr);

res = (cur & tmr->r_tmr.out_expired);

tmr->out_value = res;
}
71 changes: 71 additions & 0 deletions timer/timer_on.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#ifndef TIMER_ON_H
#define TIMER_ON_H

#include "module/base.h"
#include "edge_detect/edge_detect.h"
#include "timer.h"


//! Перечисление возможных бит управления.
enum _E_Timer_On_Control {
TIMER_ON_CONTROL_NONE = CONTROL_NONE,
};

//! Перечисление возможных бит статуса.
enum _E_Timer_On_Status {
TIMER_ON_STATUS_NONE = STATUS_NONE,
};

//! Предварительная декларация типа модуля.
typedef struct _S_Timer_On M_timer_on;

//! Структура модуля.
struct _S_Timer_On {
// Базовые поля.
control_t control; //!< Слово управления.
status_t status; //!< Слово состояния.
// Входные данные.
flag_t in_value; //!< Входное значение сигнала.
// Выходные данные.
flag_t out_value; //!< Выходное значение сигнала.
// Параметры.
//reg_u32_t r_time_on_ms; //!< Время задержки в мс. // в m_tmr.
// Регистры.
M_timer r_tmr; //!< Таймер времени до срабатывания выхода.
// Методы.
METHOD_INIT(M_timer_on);
METHOD_DEINIT(M_timer_on);
METHOD_CALC(M_timer_on);
// Коллбэки.
// Внутренние данные.
// Внутренние модули.
M_edge_detect m_ed; //!< Детект фронта.
};

EXTERN METHOD_INIT_PROTO(M_timer_on);
EXTERN METHOD_DEINIT_PROTO(M_timer_on);
EXTERN METHOD_CALC_PROTO(M_timer_on);

#define TIMER_ON_DEFCFG(TIME) {\
/* Базовые поля */\
0, 0, /* control, status */\
/* Входные данные */\
0, /* in_value */\
/* Выходные данные */\
0, /* out_value */\
/* Параметры */\
/* Регистры */\
TIMER_DEFCFG(TIME), /* r_tmr */\
/* TIME,*/ /* r_time_on_ms */\
/* Методы */\
METHOD_INIT_PTR(M_timer_on), METHOD_DEINIT_PTR(M_timer_on),\
METHOD_CALC_PTR(M_timer_on),\
/* Коллбэки */\
/* Внутренние данные */\
/* Внутренние модули */\
EDGE_DETECT_DEFAULTS, /* m_ed */\
}

#define TIMER_ON_DEFAULTS TIMER_ON_DEFCFG(0)

#endif /* TIMER_ON_H */
25 changes: 25 additions & 0 deletions utils/counter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#ifndef UTILS_COUNTER_H
#define UTILS_COUNTER_H


#include <stdint.h>
#include "defs/defs.h"


/**
* Вычисляет разницу двух счётчиков
* с учётом возможного переполнения.
* @param cur Текущее значение счётчика.
* @param ref Опорное (прошлое) значение счётчика.
* @return Разница.
*/
ALWAYS_INLINE static uint32_t counter_calc_diff(uint32_t cur, uint32_t ref)
{
// Текущее значение больше опорного - счётчик не переполнился.
if(cur >= ref) return cur - ref;
// Иначе cur < ref - счётчик переполнился.
return UINT32_MAX - ref + cur + 1;
}


#endif /* UTILS_COUNTER_H */

0 comments on commit a2a2519

Please sign in to comment.