Aversive/Modules/hardware/timer

De Wikidroids

Sommaire

Module hardware/timer

Le module hardware/timer permettrait d'accéder simplement aux fonctionalités usuelles des timers des AVR, sans avoir à configurer des registres. Par exemple, planifier l'exécution d'une fonction au bout d'un certain temps, en microsecondes.

Il serait bien que ce module puisse être utilisé par d'autres modules tels que base/scheduler, devices/servo/multiservo, ... Par contre hardware/pwm resterait standalone, car il fournit des fonctionnalités trop différentes.

Les fonctions ci-dessous d'appliquent sur des timers 16 bits mais pourrait s'appliquer de la même manière sur les timer 8 bits.

Requirements

  • Simple et clair
  • Léger
  • Portable sur tous les AVR (du moment que l'on décrit les registres disponibles quelque part)
  • Avoir une configuration statique ou dynamique, sachant que les fonctions de configuration dynamique ne sont pas inclues dans le binaire si elles ne sont pas utilisées.

Configuration

La configuration statique est stockée, comme habituellement dans aversive, dans timer_config.h

Elle contient :

  • La liste des timers et "sous-timers" utilisés par le module
#define TIMER1_ENABLED
#define TIMER1A_ENABLED
#define TIMER1B_ENABLED
...
  • Le prescaler par défaut. On peut s'inspirer de ce qui est fait dans le scheduler pour les différentes valeurs de timer. Ces valeurs devraient d'ailleurs être communes pour tous les modules d'aversive. A noter que ce module ne gèrerait que des prescaler utilisant l'horloge interne.
#define TIMER1_PRESCALER 8

Fonctions d'initialisation & contrôle

void timer_init()

Initialise les timers en fonction de la configuration statique située dans timer_config.h, met les timer à 0 et les lance. S'il y a plusieurs timers, ils sont lancés de manière synchronisés dans la mesure du possible.

void timerX_start()

Lance le timer en utilisant le prescaler statique

void timerX_stop()

Arrête le timer

void timerX_set(uint16_t t)

Met le timer à la valeur t

uint8_t timerX_get()

retourne la valeur du timer

Enregistrement d'évènements

void timerX_register_OV_intr(void (*func)(void))

Active l'interruption overflow du timer correspondant et enregistre une fonction à appeler à chaque interruption overflow du timer. Si func est NULL, alors c'est équivalent à un désenregistrement : désactive l'interruption overflow du timer et désenregistre la fonction à appeler.

void timerXY_register_OC_intr_at_tics(void (*func)(void), uint16_t t)

Active l'interruption output compare du timer correspondant et enregistre une fonction à appeler à chaque interruption output compare du timer. L'interruption aura lieu lorsque le timer vaudra t (l'unité est la même que celle du timer). Si func est NULL, alors c'est un désenregistrement : désactive l'interruption overflow du timer et désenregistre la fonction à appeler.

void timerXY_register_OC_intr_in_tics(void (*func)(void), uint16_t t)

Active l'interruption output compare du timer correspondant et enregistre une fonction à appeler à chaque interruption output compare du timer. L'interruption aura lieu lorsque le timer vaudra TIMER_COURANT+t (l'unité est la même que celle du timer). Si func est NULL, alors c'est un désenregistrement : désactive l'interruption overflow du timer et désenregistre la fonction à appeler.

void timerXY_register_OC_intr_in_us(void (*func)(void), uint16_t t)

Active l'interruption output compare du timer correspondant et enregistre une fonction à appeler à chaque interruption output compare du timer. L'interruption aura lieu lorsque le timer vaudra TIMER_COURANT+t (l'unité de t est en us). Si func est NULL, alors c'est un désenregistrement : désactive l'interruption overflow du timer et désenregistre la fonction à appeler.

Conversions de temps

uint16_t timerX_get_prescaler_div(void)

retourne le diviseur actuellement en configuration dans le registrer prescaler. Dans le cas d'une configuration statique, cette fonction peut être une simple macro qui retourne le TIMERX_PRESCALER de la configuration. Dans le cas d'une configuration dynamique, il faut lire le registre et en déterminer le diviseur (plus difficile, et surtout fortement dépendant du uC).

void timerX_set_prescaler_div(uint16_t)

Uniquement disponible si la configuration dynamique est activée. Configure le registre prescaler en fonction du diviseur passé en paramètre (toujours relativement hardware dépendant).

uint16_t timerX_us_to_tics(uint16_t us)

Utilise timerX_get_prescaler_div() et CONFIG_QUARTZ pour faire la conversion.

uint16_t timerX_tics_to_us(uint16_t t)

Opération inverse

Boîte à outils
LANGUAGES