#include #include #include #include #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; }