aboutsummaryrefslogtreecommitdiff
path: root/src/kern/systick/systick_manager.c
blob: 83e37f50336b3eed006deece74e0bfe10d947e8f (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include "kern/systick/systick_manager.h"

#include "arch/stm32l4xxx/peripherals/system.h"
#include "kern/mem.h"
#include "shared/linked_list.h"

typedef struct {
  void* arg;
  void (*callback)(void*);
} systick_listener_t;

LINKED_LIST_DECL(systick_listener_t);
LINKED_LIST_IMPL(systick_listener_t);

static linked_list_t(systick_listener_t) listeners;

void on_systick()
{
  linked_list_foreach(listeners, val) { val.callback(val.arg); }
}

void enable_systick(uint32_t systick_counter)
{
  SCB.strv_r = systick_counter;

  /* Enable interrupts. */
  regset(SCB.stcs_r, scb_tickint, 1);

  /* Start the systick. */
  regset(SCB.stcs_r, scb_enable, 1);
}

void disable_systick()
{
  /* Disable interrupts. */
  regset(SCB.stcs_r, scb_tickint, 0);

  /* Stop the systick. */
  regset(SCB.stcs_r, scb_enable, 0);
}

void systick_add_callback(void (*callback)(void*), void* arg)
{
  systick_listener_t l;
  l.arg = arg;
  l.callback = callback;
  linked_list_push_back(systick_listener_t)(&listeners, l);
}