forked from GMMan/flipperzero-tamagotch-p1
-
Notifications
You must be signed in to change notification settings - Fork 2
/
hal.c
146 lines (127 loc) · 3.88 KB
/
hal.c
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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#include <furi.h>
#include <furi_hal.h>
#include <stdlib.h>
#include <stm32wbxx_ll_tim.h>
#include "tama.h"
#define TAG_HAL "TamaLIB"
static void* tama_p1_hal_malloc(u32_t size) {
return malloc(size);
}
static void tama_p1_hal_free(void* ptr) {
free(ptr);
}
static void tama_p1_hal_halt(void) {
g_ctx->halted = true;
}
static bool_t tama_p1_hal_is_log_enabled(log_level_t level) {
switch(level) {
case LOG_ERROR:
return true;
case LOG_INFO:
return true;
case LOG_MEMORY:
return false;
case LOG_CPU:
return false;
default:
return false;
}
}
static void tama_p1_hal_log(log_level_t level, char* buff, ...) {
if(!tama_p1_hal_is_log_enabled(level)) return;
FuriString* string = furi_string_alloc();
va_list args;
va_start(args, buff);
furi_string_cat_vprintf(string, buff, args);
va_end(args);
switch(level) {
case LOG_ERROR:
FURI_LOG_E(TAG_HAL, "%s", furi_string_get_cstr(string));
break;
case LOG_INFO:
FURI_LOG_I(TAG_HAL, "%s", furi_string_get_cstr(string));
break;
case LOG_MEMORY:
break;
case LOG_CPU:
FURI_LOG_D(TAG_HAL, "%s", furi_string_get_cstr(string));
break;
default:
FURI_LOG_D(TAG_HAL, "%s", furi_string_get_cstr(string));
break;
}
furi_string_free(string);
}
static void tama_p1_hal_sleep_until(timestamp_t ts) {
while(true) {
uint32_t count = LL_TIM_GetCounter(TIM2);
uint32_t delay = ts - count;
// FURI_LOG_D(TAG, "delay: %x", delay);
// Stolen from furi_delay_until_tick
if(delay != 0 && 0 == (delay >> (8 * sizeof(uint32_t) - 1))) {
// Not the best place to release mutex, but this is the only place we know whether
// we're ahead or behind, otherwise around the step call we'll always have to
// delay a tick and run more and more behind.
furi_mutex_release(g_state_mutex);
furi_delay_tick(1);
while(furi_mutex_acquire(g_state_mutex, FuriWaitForever) != FuriStatusOk)
furi_delay_tick(1);
} else {
break;
}
}
}
static timestamp_t tama_p1_hal_get_timestamp(void) {
return LL_TIM_GetCounter(TIM2);
}
static void tama_p1_hal_update_screen(void) {
// Do nothing, covered by main loop
}
static void tama_p1_hal_set_lcd_matrix(u8_t x, u8_t y, bool_t val) {
if(val)
g_ctx->framebuffer[y] |= 1 << x;
else
g_ctx->framebuffer[y] &= ~(1 << x);
}
static void tama_p1_hal_set_lcd_icon(u8_t icon, bool_t val) {
if(val)
g_ctx->icons |= 1 << icon;
else
g_ctx->icons &= ~(1 << icon);
}
static void tama_p1_hal_play_frequency(bool_t en) {
if(en) {
if(furi_hal_speaker_is_mine() || furi_hal_speaker_acquire(30)) {
furi_hal_speaker_start(g_ctx->frequency, 0.5f);
}
} else {
if(furi_hal_speaker_is_mine()) {
furi_hal_speaker_stop();
furi_hal_speaker_release();
}
}
g_ctx->buzzer_on = en;
}
static void tama_p1_hal_set_frequency(u32_t freq) {
g_ctx->frequency = freq / 10.0F;
if(g_ctx->buzzer_on) tama_p1_hal_play_frequency(true);
}
static int tama_p1_hal_handler(void) {
// Do nothing
return 0;
}
void tama_p1_hal_init(hal_t* hal) {
hal->malloc = tama_p1_hal_malloc;
hal->free = tama_p1_hal_free;
hal->halt = tama_p1_hal_halt;
hal->is_log_enabled = tama_p1_hal_is_log_enabled;
hal->log = tama_p1_hal_log;
hal->sleep_until = tama_p1_hal_sleep_until;
hal->get_timestamp = tama_p1_hal_get_timestamp;
hal->update_screen = tama_p1_hal_update_screen;
hal->set_lcd_matrix = tama_p1_hal_set_lcd_matrix;
hal->set_lcd_icon = tama_p1_hal_set_lcd_icon;
hal->set_frequency = tama_p1_hal_set_frequency;
hal->play_frequency = tama_p1_hal_play_frequency;
hal->handler = tama_p1_hal_handler;
}