Dans la fonction (main) :
On exécute la fonction (tta_init) du module (TTA).
On exécute la fonction (signal_init) du module (signal).
On exécute la fonction (tta_add_task, signal_wave_on_update) du module (TTA).
On exécute la fonction (tta_add_task, signal_wave_off_update) du module (TTA).
On exécute la fonction (tta_add_task, signal_modulation_update) du module (TTA).
On exécute la fonction (tta_start) du module (TTA). - On rentre dans une boucle infinie.
Puis on exécute la fonction (tta_dispatch_tasks) du module (TTA).
...
void main()
{
tta_init();
signal_init();
tta_add_task(signal_wave_on_update, 0, config_signal_wave_period);
tta_add_task(signal_wave_off_update, config_signal_wave_on_period,
config_signal_wave_period);
tta_add_task(signal_modulation_update, 0,
config_signal_modulation_on_period);
tta_start();
while (true)
{
tta_dispatch_tasks();
}
}
...
Dans la macro (TTA_PRELOAD_TIME_MS) :
On calcule la valeur de pré-chargement du timer T2 afin de réaliser un débordement suivi d'une interruption toutes les (x) millisecondes selon la valeur du paramètre (time_ms).
...
#define TTA_PRELOAD_TIME_MS(time_ms) \
(65536 - ((config_osc_freq * time_ms) / (config_osc_per_inst * 1000)))
...
Dans la structure (sTask) :
On déclare la variable (pTask) de type (pointeur de fonction) pour stocker une tâche.
On déclare la variable (delay) de type (uint, unsigned int) pour stocker le délai d'attente avant la première exécution de la tâche (en nombre de ticks).
On déclare la variable (period) de type (uint, unsigned int) pour stocker la période d'exécution de la tâche (en nombre de ticks).
On déclare la variable (run_me) de type (uchar, unsigned char) pour stocker le drapeau d'exécution de la tâche.
...
typedef struct _sTask
{
void (*pTask)();
uint delay;
uint period;
uchar run_me;
} sTask;
...
Dans la macro (TTA_TASK_MAX) :
On stocke le nombre maximal de tâches du module (TTA).
...
#define TTA_TASK_MAX (8)
...
Dans la variable (g_tta_task_queue) :
On stocke la liste des tâches de type (sTask).
...
static sTask g_tta_task_queue[TTA_TASK_MAX];
...
Dans la fonction (tta_init) :
On exécute la macro (TTA_PRELOAD_TIME_MS) du module (TTA) pour retourner la variable (preload).
On parcourt la liste des tâches du module (TTA, TTA_TASK_MAX).
Puis on exécute la fonction (tta_delete_task) du module (TTA).
Ensuite, on recharge les registres du timer T2 afin de réaliser un débordement suivi d'une interruption toutes les (x) millisecondes selon la valeur du paramètre (config_tta_tick_ms).
...
void tta_init()
{
uchar index;
volatile uint preload = TTA_PRELOAD_TIME_MS(config_tta_tick_ms);
for(index = 0; index < TTA_TASK_MAX; index++)
{
tta_delete_task(index);
}
T2CON = 0x00;
TH2 = preload >> 8;
RCAP2H = preload >> 8;
TL2 = preload;
RCAP2L = preload;
ET2 = 1;
TR2 = 1;
}
...
Dans la fonction (tta_delete_task) :
On initialise les paramètres de la variable (g_tta_task_queue, index) de type (sTask).
...
static void tta_delete_task(const uchar index)
{
g_tta_task_queue[index].pTask = 0x0000;
g_tta_task_queue[index].delay = 0;
g_tta_task_queue[index].period = 0;
g_tta_task_queue[index].run_me = 0;
}
...
Dans la fonction (tta_add_task) :
On démarre une boucle afin de rechercher une place libre dans la liste des tâches (g_tta_task_queue).
On retourne une erreur d'index si aucune place n'est disponible dans la liste des tâches (g_tta_task_queue).
Sinon, on initialise la tâche (g_tta_task_queue, index) avec les paramètres (pTask, delay, period).
On retourne l'index de la nouvelle tâche (index).
...
uchar tta_add_task(void (*pTask)(), const uint delay, const uint period)
{
uchar index = 0;
while((g_tta_task_queue[index].pTask != 0) && (index < TTA_TASK_MAX))
index++;
if(index == TTA_TASK_MAX) return config_tta_index_error;
g_tta_task_queue[index].pTask = pTask;
g_tta_task_queue[index].delay = delay;
g_tta_task_queue[index].period = period;
g_tta_task_queue[index].run_me = 0;
return index;
...
Dans la fonction (tta_start) :
On initialise le registre (EA) à (true) pour activer toute les interruptions.
...
void tta_start()
{
EA = 1;
}
...
Dans la fonction (tta_dispatch_tasks) :
On parcourt la liste des tâches du module (TTA, g_tta_task_queue).
Puis, on exécute la tâche (g_tta_task_queue, index, pTask) du module (TTA) si la variable (g_tta_task_queue, index, run_me) est supérieure à (0).
On décrémente la variable (g_tta_task_queue, index, run_me) après l'exécution de la tâche (g_tta_task_queue, index, pTask).
Puis, on exécute la fonction (tta_delete_task, index) du module (TTA) si la variable (g_tta_task_queue, index, period) est à (0).
Ensuite on exécute la fonction (tta_go_to_sleep) du module (TTA).
...
void tta_dispatch_tasks()
{
uchar index;
for(index = 0; index < TTA_TASK_MAX; index++)
{
if(g_tta_task_queue[index].run_me > 0)
{
(*g_tta_task_queue[index].pTask)();
g_tta_task_queue[index].run_me -= 1;
if(g_tta_task_queue[index].period == 0)
{
tta_delete_task(index);
}
}
}
tta_go_to_sleep();
}
...
Dans la fonction (tta_go_to_sleep) :
On initialise le registre (PCON) à (0x01) pour basculer en mode économie d'énergie (en mode IDLE).
...
static void tta_go_to_sleep()
{
PCON |= 0x01;
}
...
Dans la fonction (on_tta_update_tasks) :
On parcourt la liste des tâches du module (TTA, g_tta_task_queue).
Puis, on incrémente la variable (g_tta_task_queue, index, run_me) du module (TTA) si la variable (g_tta_task_queue, index, delay) est à (0) et si la variable (g_tta_task_queue, index, pTask) est différente de (0).
Puis, on initialise la variable (g_tta_task_queue, index, delay) du module (TTA) avec la valeur de la variable (g_tta_task_queue, index, period) si la variable (g_tta_task_queue, index, period) est différente de (0), si la variable (g_tta_task_queue, index, delay) est à (0) et si la variable (g_tta_task_queue, index, pTask) est différente de (0).
Sinon, on décrémente la variable (g_tta_task_queue, index, delay) du module (TTA) si la variable (g_tta_task_queue, index, delay) est à (0) et si la variable (g_tta_task_queue, index, pTask) est différente de (0).
...
void on_tta_update_tasks() interrupt TTA_INTERRUPT_TIMER_T2
{
uchar index;
TF2 = 0;
for(index = 0; index < TTA_TASK_MAX; index++)
{
if(g_tta_task_queue[index].pTask != 0)
{
if(g_tta_task_queue[index].delay == 0)
{
g_tta_task_queue[index].run_me += 1;
if(g_tta_task_queue[index].period != 0)
{
g_tta_task_queue[index].delay =
g_tta_task_queue[index].period;
}
}
else
{
g_tta_task_queue[index].delay -= 1;
}
}
}
if(config_tta_tick_pin_on)
{
g_tta_tick_pin = !g_tta_tick_pin;
}
}
...