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.
152 lines
3.9 KiB
C
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();
|
|
}
|