circuitpython/supervisor/shared/tick.c
Jeff Epler 953694d56c Fix -Wold-style-definion errors in the raspberrypi port
This mostly means changing `void foo()` to `void foo(void)` at
the function definition site. This was previously only an error
if the declaration site didn't have `(void)`, but the unix
coverage build enables the more strict warning and there's little
difficulty in resolving these diagnostics.

.. other ports can be done too, if desired.
2025-05-25 09:16:00 +02:00

152 lines
3.9 KiB
C

// This file is part of the CircuitPython project: https://circuitpython.org
//
// SPDX-FileCopyrightText: Copyright (c) 2019 Jeff Epler for Adafruit Industries
//
// SPDX-License-Identifier: MIT
#include "supervisor/shared/tick.h"
#include "shared/runtime/interrupt_char.h"
#include "py/mphal.h"
#include "py/mpstate.h"
#include "py/runtime.h"
#include "supervisor/filesystem.h"
#include "supervisor/background_callback.h"
#include "supervisor/port.h"
#include "supervisor/shared/stack.h"
#if CIRCUITPY_BLEIO_HCI
#include "common-hal/_bleio/__init__.h"
#endif
#if CIRCUITPY_DISPLAYIO
#include "shared-module/displayio/__init__.h"
#endif
#if CIRCUITPY_KEYPAD
#include "shared-module/keypad/__init__.h"
#endif
#include "shared-bindings/microcontroller/__init__.h"
#if CIRCUITPY_WATCHDOG
#include "shared-bindings/watchdog/__init__.h"
#define WATCHDOG_EXCEPTION_CHECK() (MP_STATE_VM(mp_pending_exception) == &mp_watchdog_timeout_exception)
#else
#define WATCHDOG_EXCEPTION_CHECK() 0
#endif
static volatile uint64_t PLACE_IN_DTCM_BSS(background_ticks);
static background_callback_t tick_callback;
static volatile uint64_t last_finished_tick = 0;
static volatile size_t tick_enable_count = 0;
static void supervisor_background_tick(void *unused) {
port_start_background_tick();
assert_heap_ok();
#if CIRCUITPY_BLEIO_HCI
bleio_hci_background();
#endif
#if CIRCUITPY_DISPLAYIO
displayio_background();
#endif
filesystem_background();
port_background_tick();
assert_heap_ok();
last_finished_tick = port_get_raw_ticks(NULL);
port_finish_background_tick();
}
bool supervisor_background_ticks_ok(void) {
return port_get_raw_ticks(NULL) - last_finished_tick < 1024;
}
void supervisor_tick(void) {
#if CIRCUITPY_FILESYSTEM_FLUSH_INTERVAL_MS > 0
filesystem_tick();
#endif
#if CIRCUITPY_KEYPAD
keypad_tick();
#endif
background_callback_add(&tick_callback, supervisor_background_tick, NULL);
}
static uint64_t _get_raw_subticks(void) {
uint64_t ticks;
uint8_t subticks;
ticks = port_get_raw_ticks(&subticks);
return (ticks << 5) | subticks;
}
uint64_t supervisor_ticks_ms64(void) {
uint64_t result;
result = port_get_raw_ticks(NULL);
result = result * 1000 / 1024;
return result;
}
uint32_t supervisor_ticks_ms32(void) {
return supervisor_ticks_ms64();
}
void mp_hal_delay_ms(mp_uint_t delay_ms) {
uint64_t start_subtick = _get_raw_subticks();
// Convert delay from ms to subticks
uint64_t delay_subticks = (delay_ms * (uint64_t)32768) / 1000;
uint64_t end_subtick = start_subtick + delay_subticks;
int64_t remaining = delay_subticks;
// Loop until we've waited long enough or we've been CTRL-Ced by autoreload
// or the user.
while (remaining > 0 && !mp_hal_is_interrupted()) {
RUN_BACKGROUND_TASKS;
// Exit if interrupted while running background tasks
if (mp_hal_is_interrupted()) {
break;
}
// Recalculate remaining delay after running background tasks
remaining = end_subtick - _get_raw_subticks();
// If remaining delay is less than 1 tick, idle loop until end of delay
int64_t remaining_ticks = remaining / 32;
if (remaining_ticks > 0) {
port_interrupt_after_ticks(remaining_ticks);
// Idle until an interrupt happens.
port_idle_until_interrupt();
}
remaining = end_subtick - _get_raw_subticks();
}
}
void supervisor_enable_tick(void) {
common_hal_mcu_disable_interrupts();
if (tick_enable_count == 0) {
port_enable_tick();
}
tick_enable_count++;
common_hal_mcu_enable_interrupts();
}
void supervisor_disable_tick(void) {
common_hal_mcu_disable_interrupts();
if (tick_enable_count > 0) {
tick_enable_count--;
}
if (tick_enable_count == 0) {
port_disable_tick();
}
common_hal_mcu_enable_interrupts();
}