aboutsummaryrefslogtreecommitdiff
path: root/supervisor/shared
diff options
context:
space:
mode:
Diffstat (limited to 'supervisor/shared')
-rw-r--r--supervisor/shared/autoreload.c67
-rw-r--r--supervisor/shared/autoreload.h42
-rw-r--r--supervisor/shared/rgb_led_colors.h34
-rw-r--r--supervisor/shared/rgb_led_status.c316
-rw-r--r--supervisor/shared/rgb_led_status.h73
5 files changed, 532 insertions, 0 deletions
diff --git a/supervisor/shared/autoreload.c b/supervisor/shared/autoreload.c
new file mode 100644
index 000000000..b1d0f05a9
--- /dev/null
+++ b/supervisor/shared/autoreload.c
@@ -0,0 +1,67 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "autoreload.h"
+
+#include "lib/utils/interrupt_char.h"
+#include "py/mphal.h"
+
+volatile uint32_t autoreload_delay_ms = 0;
+bool autoreload_enabled = false;
+volatile bool reload_next_character = false;
+
+inline void autoreload_tick() {
+ if (autoreload_delay_ms == 0) {
+ return;
+ }
+ if (autoreload_delay_ms == 1 && autoreload_enabled && !reload_next_character) {
+ mp_keyboard_interrupt();
+ reload_next_character = true;
+ }
+ autoreload_delay_ms--;
+}
+
+void autoreload_enable() {
+ autoreload_enabled = true;
+ reload_next_character = false;
+}
+
+void autoreload_disable() {
+ autoreload_enabled = false;
+}
+
+inline bool autoreload_is_enabled() {
+ return autoreload_enabled;
+}
+
+void autoreload_start() {
+ autoreload_delay_ms = CIRCUITPY_AUTORELOAD_DELAY_MS;
+}
+
+void autoreload_stop() {
+ autoreload_delay_ms = 0;
+ reload_next_character = false;
+}
diff --git a/supervisor/shared/autoreload.h b/supervisor/shared/autoreload.h
new file mode 100644
index 000000000..bc3c6d21d
--- /dev/null
+++ b/supervisor/shared/autoreload.h
@@ -0,0 +1,42 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef MICROPY_INCLUDED_SUPERVISOR_AUTORELOAD_H
+#define MICROPY_INCLUDED_SUPERVISOR_AUTORELOAD_H
+
+#include <stdbool.h>
+
+extern volatile bool reload_next_character;
+
+void autoreload_tick(void);
+
+void autoreload_start(void);
+void autoreload_stop(void);
+void autoreload_enable(void);
+void autoreload_disable(void);
+bool autoreload_is_enabled(void);
+
+#endif // MICROPY_INCLUDED_SUPERVISOR_AUTORELOAD_H
diff --git a/supervisor/shared/rgb_led_colors.h b/supervisor/shared/rgb_led_colors.h
new file mode 100644
index 000000000..12f5cc3d9
--- /dev/null
+++ b/supervisor/shared/rgb_led_colors.h
@@ -0,0 +1,34 @@
+#define BLACK 0x000000
+#define GREEN 0x001000
+#define BLUE 0x000010
+#define CYAN 0x001010
+#define RED 0x100000
+#define ORANGE 0x100800
+#define YELLOW 0x101000
+#define PURPLE 0x100010
+#define WHITE 0x101010
+
+#define BOOT_RUNNING BLUE
+#define MAIN_RUNNING GREEN
+#define SAFE_MODE YELLOW
+#define ALL_DONE GREEN
+#define REPL_RUNNING WHITE
+
+#define ACTIVE_WRITE 0x200000
+
+#define ALL_GOOD_CYCLE_MS 2000u
+
+#define LINE_NUMBER_TOGGLE_LENGTH 300u
+#define EXCEPTION_TYPE_LENGTH_MS 1000u
+
+#define THOUSANDS WHITE
+#define HUNDREDS BLUE
+#define TENS YELLOW
+#define ONES CYAN
+
+#define INDENTATION_ERROR GREEN
+#define SYNTAX_ERROR CYAN
+#define NAME_ERROR WHITE
+#define OS_ERROR ORANGE
+#define VALUE_ERROR PURPLE
+#define OTHER_ERROR YELLOW
diff --git a/supervisor/shared/rgb_led_status.c b/supervisor/shared/rgb_led_status.c
new file mode 100644
index 000000000..15150f18b
--- /dev/null
+++ b/supervisor/shared/rgb_led_status.c
@@ -0,0 +1,316 @@
+/*
+ * This file is part of the Micro Python project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "mphalport.h"
+#include "common-hal/microcontroller/Pin.h"
+#include "rgb_led_status.h"
+#include "pins.h"
+
+uint8_t rgb_status_brightness = 255;
+#ifdef MICROPY_HW_NEOPIXEL
+#include "shared-bindings/digitalio/DigitalInOut.h"
+#include "shared-bindings/neopixel_write/__init__.h"
+static uint8_t status_neopixel_color[3];
+static digitalio_digitalinout_obj_t status_neopixel;
+#endif
+
+
+#if defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK)
+
+static uint8_t status_apa102_color[12] = {0, 0, 0, 0, 0xff, 0, 0, 0};
+#ifdef CIRCUITPY_BITBANG_APA102
+#include "shared-bindings/bitbangio/SPI.h"
+#include "shared-module/bitbangio/types.h"
+static bitbangio_spi_obj_t status_apa102;
+#else
+#include "shared-bindings/busio/SPI.h"
+busio_spi_obj_t status_apa102;
+#endif
+#endif
+
+#if defined(MICROPY_HW_NEOPIXEL) || (defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK))
+static uint32_t current_status_color = 0;
+#endif
+
+void rgb_led_status_init() {
+ #ifdef MICROPY_HW_NEOPIXEL
+ common_hal_digitalio_digitalinout_construct(&status_neopixel, MICROPY_HW_NEOPIXEL);
+ // Pretend we aren't using the pins. digitalio.DigitalInOut
+ // will mark them as used.
+ neopixel_in_use = false;
+ common_hal_digitalio_digitalinout_switch_to_output(&status_neopixel, false, DRIVE_MODE_PUSH_PULL);
+ #endif
+ #if defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK)
+ #ifdef CIRCUITPY_BITBANG_APA102
+ shared_module_bitbangio_spi_construct(&status_apa102,
+ MICROPY_HW_APA102_SCK,
+ MICROPY_HW_APA102_MOSI,
+ mp_const_none);
+ #else
+ if (status_apa102.current_baudrate > 0) {
+ // Don't use spi_deinit because that leads to infinite
+ // recursion because reset_pin may call
+ // rgb_led_status_init.
+ spi_disable(&status_apa102.spi_master_instance);
+ }
+ common_hal_busio_spi_construct(&status_apa102,
+ MICROPY_HW_APA102_SCK,
+ MICROPY_HW_APA102_MOSI,
+ mp_const_none);
+ #endif
+ // Pretend we aren't using the pins. bitbangio.SPI will
+ // mark them as used.
+ apa102_mosi_in_use = false;
+ apa102_sck_in_use = false;
+ #ifdef CIRCUITPY_BITBANG_APA102
+ shared_module_bitbangio_spi_try_lock(&status_apa102);
+ shared_module_bitbangio_spi_configure(&status_apa102, 100000, 0, 1, 8);
+ #else
+ common_hal_busio_spi_try_lock(&status_apa102);
+ common_hal_busio_spi_configure(&status_apa102, 100000, 0, 1, 8);
+ #endif
+ #endif
+
+ #if defined(MICROPY_HW_NEOPIXEL) || (defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK))
+ // Force a write of the current status color.
+ uint32_t rgb = current_status_color;
+ current_status_color = 0;
+ new_status_color(rgb);
+ #endif
+}
+
+void reset_status_led() {
+ #ifdef MICROPY_HW_NEOPIXEL
+ reset_pin(MICROPY_HW_NEOPIXEL->pin);
+ #endif
+ #if defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK)
+ reset_pin(MICROPY_HW_APA102_MOSI->pin);
+ reset_pin(MICROPY_HW_APA102_SCK->pin);
+ #endif
+}
+
+void new_status_color(uint32_t rgb) {
+ #if defined(MICROPY_HW_NEOPIXEL) || (defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK))
+ if (current_status_color == rgb) {
+ return;
+ }
+ uint32_t rgb_adjusted = color_brightness(rgb, rgb_status_brightness);
+ current_status_color = rgb_adjusted;
+ #endif
+
+ #ifdef MICROPY_HW_NEOPIXEL
+ if (neopixel_in_use) {
+ return;
+ }
+ status_neopixel_color[0] = (rgb_adjusted >> 8) & 0xff;
+ status_neopixel_color[1] = (rgb_adjusted >> 16) & 0xff;
+ status_neopixel_color[2] = rgb_adjusted & 0xff;
+ common_hal_neopixel_write(&status_neopixel, status_neopixel_color, 3);
+ #endif
+ #if defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK)
+ if (apa102_mosi_in_use || apa102_sck_in_use) {
+ return;
+ }
+ status_apa102_color[5] = rgb_adjusted & 0xff;
+ status_apa102_color[6] = (rgb_adjusted >> 8) & 0xff;
+ status_apa102_color[7] = (rgb_adjusted >> 16) & 0xff;
+
+ #ifdef CIRCUITPY_BITBANG_APA102
+ shared_module_bitbangio_spi_write(&status_apa102, status_apa102_color, 8);
+ #else
+ common_hal_busio_spi_write(&status_apa102, status_apa102_color, 8);
+ #endif
+ #endif
+}
+
+void temp_status_color(uint32_t rgb) {
+ #if defined(MICROPY_HW_NEOPIXEL) || (defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK))
+ uint32_t rgb_adjusted = rgb;
+ rgb_adjusted = color_brightness(rgb, rgb_status_brightness);
+ #endif
+ #ifdef MICROPY_HW_NEOPIXEL
+ if (neopixel_in_use) {
+ return;
+ }
+ uint8_t colors[3] = {(rgb_adjusted >> 8) & 0xff, (rgb_adjusted >> 16) & 0xff, rgb_adjusted & 0xff};
+ common_hal_neopixel_write(&status_neopixel, colors, 3);
+ #endif
+ #if defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK)
+ if (apa102_mosi_in_use || apa102_sck_in_use) {
+ return;
+ }
+ uint8_t colors[12] = {0, 0, 0, 0, 0xff, rgb_adjusted & 0xff, (rgb_adjusted >> 8) & 0xff, (rgb_adjusted >> 16) & 0xff, 0x0, 0x0, 0x0, 0x0};
+ #ifdef CIRCUITPY_BITBANG_APA102
+ shared_module_bitbangio_spi_write(&status_apa102, colors, 12);
+ #else
+ common_hal_busio_spi_write(&status_apa102, colors, 12);
+ #endif
+ #endif
+}
+
+void clear_temp_status() {
+ #ifdef MICROPY_HW_NEOPIXEL
+ common_hal_neopixel_write(&status_neopixel, status_neopixel_color, 3);
+ #endif
+ #if defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK)
+ #ifdef CIRCUITPY_BITBANG_APA102
+ shared_module_bitbangio_spi_write(&status_apa102, status_apa102_color, 8);
+ #else
+ common_hal_busio_spi_write(&status_apa102, status_apa102_color, 8);
+ #endif
+ #endif
+}
+
+uint32_t color_brightness(uint32_t color, uint8_t brightness) {
+ #if defined(MICROPY_HW_NEOPIXEL) || (defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK))
+ uint32_t result = ((color & 0xff0000) * brightness / 255) & 0xff0000;
+ result += ((color & 0xff00) * brightness / 255) & 0xff00;
+ result += ((color & 0xff) * brightness / 255) & 0xff;
+ return result;
+ #else
+ return color;
+ #endif
+}
+
+void set_rgb_status_brightness(uint8_t level){
+ rgb_status_brightness = level;
+}
+
+void prep_rgb_status_animation(const pyexec_result_t* result, bool found_main, rgb_status_animation_t* status) {
+ #if defined(MICROPY_HW_NEOPIXEL) || (defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK))
+ new_status_color(ALL_DONE);
+ status->pattern_start = ticks_ms;
+
+ uint32_t total_exception_cycle = 0;
+ status->ones = result->exception_line % 10;
+ status->ones += status->ones > 0 ? 1 : 0;
+ status->tens = (result->exception_line / 10) % 10;
+ status->tens += status->tens > 0 ? 1 : 0;
+ status->hundreds = (result->exception_line / 100) % 10;
+ status->hundreds += status->hundreds > 0 ? 1 : 0;
+ status->thousands = (result->exception_line / 1000) % 10;
+ status->thousands += status->thousands > 0 ? 1 : 0;
+ status->digit_sum = status->ones + status->tens + status->hundreds + status->thousands;
+ uint8_t num_places = 0;
+ uint16_t line = result->exception_line;
+ for (int i = 0; i < 4; i++) {
+ if ((line % 10) > 0) {
+ num_places++;
+ }
+ line /= 10;
+ }
+ status->ok = result->return_code != PYEXEC_EXCEPTION;
+ if (!status->ok) {
+ status->total_exception_cycle = EXCEPTION_TYPE_LENGTH_MS * 3 + LINE_NUMBER_TOGGLE_LENGTH * digit_sum + LINE_NUMBER_TOGGLE_LENGTH * num_places;
+ }
+ if (mp_obj_is_subclass_fast(result->exception_type, &mp_type_IndentationError)) {
+ status->exception_color = INDENTATION_ERROR;
+ } else if (mp_obj_is_subclass_fast(result->exception_type, &mp_type_SyntaxError)) {
+ status->exception_color = SYNTAX_ERROR;
+ } else if (mp_obj_is_subclass_fast(result->exception_type, &mp_type_NameError)) {
+ status->exception_color = NAME_ERROR;
+ } else if (mp_obj_is_subclass_fast(result->exception_type, &mp_type_OSError)) {
+ status->exception_color = OS_ERROR;
+ } else if (mp_obj_is_subclass_fast(result->exception_type, &mp_type_ValueError)) {
+ status->exception_color = VALUE_ERROR;
+ } else {
+ status->exception_color = OTHER_ERROR;
+ }
+ #endif
+}
+
+void tick_rgb_status_animation(rgb_status_animation_t* status) {
+ #if defined(MICROPY_HW_NEOPIXEL) || (defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK))
+ uint32_t tick_diff = ticks_ms - pattern_start;
+ if (status->ok) {
+ // All is good. Ramp ALL_DONE up and down.
+ if (tick_diff > ALL_GOOD_CYCLE_MS) {
+ pattern_start = ticks_ms;
+ tick_diff = 0;
+ }
+
+ uint16_t brightness = tick_diff * 255 / (ALL_GOOD_CYCLE_MS / 2);
+ if (brightness > 255) {
+ brightness = 511 - brightness;
+ }
+ if (safe_mode == NO_SAFE_MODE) {
+ new_status_color(color_brightness(ALL_DONE, brightness));
+ } else {
+ new_status_color(color_brightness(SAFE_MODE, brightness));
+ }
+ } else {
+ if (tick_diff > total_exception_cycle) {
+ pattern_start = ticks_ms;
+ tick_diff = 0;
+ }
+ // First flash the file color.
+ if (tick_diff < EXCEPTION_TYPE_LENGTH_MS) {
+ if (status->found_main) {
+ new_status_color(MAIN_RUNNING);
+ } else {
+ new_status_color(BOOT_RUNNING);
+ }
+ // Next flash the exception color.
+ } else if (tick_diff < EXCEPTION_TYPE_LENGTH_MS * 2) {
+ new_status_color(exception_color);
+ // Finally flash the line number digits from highest to lowest.
+ // Zeroes will not produce a flash but can be read by the absence of
+ // a color from the sequence.
+ } else if (tick_diff < (EXCEPTION_TYPE_LENGTH_MS * 2 + LINE_NUMBER_TOGGLE_LENGTH * digit_sum)) {
+ uint32_t digit_diff = tick_diff - EXCEPTION_TYPE_LENGTH_MS * 2;
+ if ((digit_diff % LINE_NUMBER_TOGGLE_LENGTH) < (LINE_NUMBER_TOGGLE_LENGTH / 2)) {
+ new_status_color(BLACK);
+ } else if (digit_diff < LINE_NUMBER_TOGGLE_LENGTH * thousands) {
+ if (digit_diff < LINE_NUMBER_TOGGLE_LENGTH) {
+ new_status_color(BLACK);
+ } else {
+ new_status_color(THOUSANDS);
+ }
+ } else if (digit_diff < LINE_NUMBER_TOGGLE_LENGTH * (thousands + hundreds)) {
+ if (digit_diff < LINE_NUMBER_TOGGLE_LENGTH * (thousands + 1)) {
+ new_status_color(BLACK);
+ } else {
+ new_status_color(HUNDREDS);
+ }
+ } else if (digit_diff < LINE_NUMBER_TOGGLE_LENGTH * (thousands + hundreds + tens)) {
+ if (digit_diff < LINE_NUMBER_TOGGLE_LENGTH * (thousands + hundreds + 1)) {
+ new_status_color(BLACK);
+ } else {
+ new_status_color(TENS);
+ }
+ } else {
+ if (digit_diff < LINE_NUMBER_TOGGLE_LENGTH * (thousands + hundreds + tens + 1)) {
+ new_status_color(BLACK);
+ } else {
+ new_status_color(ONES);
+ }
+ }
+ } else {
+ new_status_color(BLACK);
+ }
+ }
+ #endif
+}
diff --git a/supervisor/shared/rgb_led_status.h b/supervisor/shared/rgb_led_status.h
new file mode 100644
index 000000000..2ea00f4fe
--- /dev/null
+++ b/supervisor/shared/rgb_led_status.h
@@ -0,0 +1,73 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef MICROPY_INCLUDED_SUPERVISOR_RGB_LED_STATUS_H
+#define MICROPY_INCLUDED_SUPERVISOR_RGB_LED_STATUS_H
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "lib/utils/pyexec.h"
+
+#include "mpconfigport.h"
+#include "rgb_led_colors.h"
+
+// Overall, the time module must be implemented.
+// To work with a DotStar, one must have MICROPY_HW_APA102_SCK and
+// MICROPY_HW_APA102_MOSI defined and bitbangio.SPI or busio.SPI implemented.
+// To work with a NeoPixel, one must have MICROPY_HW_NEOPIXEL defined and
+// neopixel_write implemented.
+
+#if defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK) && !defined(CIRCUITPY_BITBANG_APA102)
+#include "common-hal/busio/SPI.h"
+extern busio_spi_obj_t status_apa102;
+#endif
+
+void rgb_led_status_init(void);
+void reset_status_led(void);
+void new_status_color(uint32_t rgb);
+void temp_status_color(uint32_t rgb);
+void clear_temp_status(void);
+
+uint32_t color_brightness(uint32_t color, uint8_t brightness);
+void set_rgb_status_brightness(uint8_t level);
+
+typedef struct {
+ bool ok;
+ uint32_t pattern_start;
+ uint32_t total_exception_cycle;
+ uint8_t ones;
+ uint8_t tens;
+ uint8_t hundreds;
+ uint8_t thousands;
+ uint32_t exception_color;
+ bool found_main;
+} rgb_status_animation_t;
+
+void prep_rgb_status_animation(const pyexec_result_t* result, bool found_main, rgb_status_animation_t* status);
+void tick_rgb_status_animation(rgb_status_animation_t* status);
+
+#endif // MICROPY_INCLUDED_SUPERVISOR_RGB_LED_STATUS_H