summaryrefslogtreecommitdiff
path: root/supervisor/shared
diff options
context:
space:
mode:
authorDan Halbert <halbert@adafruit.com>2020-05-04 16:08:45 -0400
committerGitHub <noreply@github.com>2020-05-04 16:08:45 -0400
commitc377d4bea79710bdf3880dfdbd2970f1ee7fc373 (patch)
tree8be39354a8e1706138357abb2cc6daf7d7d4e290 /supervisor/shared
parentcc290c50c677e16ccdddae74ab0861c9101727fc (diff)
parent4d7e341e44ac40d18e947643ab925cbd7812cd36 (diff)
Merge branch 'master' into non-standard-nvm
Diffstat (limited to 'supervisor/shared')
-rw-r--r--supervisor/shared/autoreload.c8
-rw-r--r--supervisor/shared/external_flash/external_flash.c6
-rw-r--r--supervisor/shared/external_flash/external_flash.h2
-rw-r--r--supervisor/shared/flash.c21
-rw-r--r--supervisor/shared/internal_flash.h33
-rw-r--r--supervisor/shared/tick.c71
-rw-r--r--supervisor/shared/tick.h3
-rw-r--r--supervisor/shared/usb/tusb_config.h4
-rw-r--r--supervisor/shared/usb/usb.c1
9 files changed, 127 insertions, 22 deletions
diff --git a/supervisor/shared/autoreload.c b/supervisor/shared/autoreload.c
index a6212c1a9..1976f6647 100644
--- a/supervisor/shared/autoreload.c
+++ b/supervisor/shared/autoreload.c
@@ -28,6 +28,7 @@
#include "py/mphal.h"
#include "py/reload.h"
+#include "supervisor/shared/tick.h"
static volatile uint32_t autoreload_delay_ms = 0;
static bool autoreload_enabled = false;
@@ -43,6 +44,7 @@ inline void autoreload_tick() {
!autoreload_suspended && !reload_requested) {
mp_raise_reload_exception();
reload_requested = true;
+ supervisor_disable_tick();
}
autoreload_delay_ms--;
}
@@ -69,6 +71,12 @@ inline bool autoreload_is_enabled() {
}
void autoreload_start() {
+ // Enable ticks if we haven't been tracking an autoreload delay. We check
+ // our current state so that we only turn ticks on once. Multiple starts
+ // can occur before we reload and then turn ticks off.
+ if (autoreload_delay_ms == 0) {
+ supervisor_enable_tick();
+ }
autoreload_delay_ms = CIRCUITPY_AUTORELOAD_DELAY_MS;
}
diff --git a/supervisor/shared/external_flash/external_flash.c b/supervisor/shared/external_flash/external_flash.c
index ce4792975..168bbbf68 100644
--- a/supervisor/shared/external_flash/external_flash.c
+++ b/supervisor/shared/external_flash/external_flash.c
@@ -23,11 +23,11 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
-#include "external_flash.h"
+#include "supervisor/shared/external_flash/external_flash.h"
#include <stdint.h>
#include <string.h>
-#include "mpconfigboard.h"
+#include "supervisor/flash.h"
#include "supervisor/spi_flash_api.h"
#include "supervisor/shared/external_flash/common_commands.h"
#include "extmod/vfs.h"
@@ -482,7 +482,7 @@ static void spi_flash_flush_keep_cache(bool keep_cache) {
#endif
}
-void supervisor_flash_flush(void) {
+void supervisor_external_flash_flush(void) {
spi_flash_flush_keep_cache(true);
}
diff --git a/supervisor/shared/external_flash/external_flash.h b/supervisor/shared/external_flash/external_flash.h
index 72b619a2a..db5c677eb 100644
--- a/supervisor/shared/external_flash/external_flash.h
+++ b/supervisor/shared/external_flash/external_flash.h
@@ -45,4 +45,6 @@
#define SPI_FLASH_MAX_BAUDRATE 8000000
#endif
+void supervisor_external_flash_flush(void);
+
#endif // MICROPY_INCLUDED_SUPERVISOR_SHARED_EXTERNAL_FLASH_EXTERNAL_FLASH_H
diff --git a/supervisor/shared/flash.c b/supervisor/shared/flash.c
index 6b1f24b4b..298e7d83e 100644
--- a/supervisor/shared/flash.c
+++ b/supervisor/shared/flash.c
@@ -28,6 +28,7 @@
#include "extmod/vfs_fat.h"
#include "py/runtime.h"
#include "lib/oofatfs/ff.h"
+#include "supervisor/shared/tick.h"
#define VFS_INDEX 0
@@ -110,6 +111,8 @@ mp_uint_t flash_read_blocks(uint8_t *dest, uint32_t block_num, uint32_t num_bloc
return supervisor_flash_read_blocks(dest, block_num - PART1_START_BLOCK, num_blocks);
}
+volatile bool filesystem_dirty = false;
+
mp_uint_t flash_write_blocks(const uint8_t *src, uint32_t block_num, uint32_t num_blocks) {
if (block_num == 0) {
if (num_blocks > 1) {
@@ -118,10 +121,28 @@ mp_uint_t flash_write_blocks(const uint8_t *src, uint32_t block_num, uint32_t nu
// can't write MBR, but pretend we did
return 0;
} else {
+ if (!filesystem_dirty) {
+ // Turn on ticks so that we can flush after a period of time elapses.
+ supervisor_enable_tick();
+ filesystem_dirty = true;
+ }
return supervisor_flash_write_blocks(src, block_num - PART1_START_BLOCK, num_blocks);
}
}
+void supervisor_flash_flush(void) {
+ #if INTERNAL_FLASH_FILESYSTEM
+ port_internal_flash_flush();
+ #else
+ supervisor_external_flash_flush();
+ #endif
+ // Turn off ticks now that our filesystem has been flushed.
+ if (filesystem_dirty) {
+ supervisor_disable_tick();
+ }
+ filesystem_dirty = false;
+}
+
STATIC mp_obj_t supervisor_flash_obj_readblocks(mp_obj_t self, mp_obj_t block_num, mp_obj_t buf) {
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(buf, &bufinfo, MP_BUFFER_WRITE);
diff --git a/supervisor/shared/internal_flash.h b/supervisor/shared/internal_flash.h
new file mode 100644
index 000000000..80257a290
--- /dev/null
+++ b/supervisor/shared/internal_flash.h
@@ -0,0 +1,33 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2020 Scott Shawcroft, for Adafruit Industries LLC
+ *
+ * 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_SHARED_INTERNAL_FLASH_H
+#define MICROPY_INCLUDED_SUPERVISOR_SHARED_INTERNAL_FLASH_H
+
+#include "supervisor/internal_flash.h" // This is per-port.
+
+void port_internal_flash_flush(void);
+
+#endif // MICROPY_INCLUDED_SUPERVISOR_SHARED_INTERNAL_FLASH_H
diff --git a/supervisor/shared/tick.c b/supervisor/shared/tick.c
index 5668f8fa1..dc38e76f6 100644
--- a/supervisor/shared/tick.c
+++ b/supervisor/shared/tick.c
@@ -26,12 +26,13 @@
#include "supervisor/shared/tick.h"
+#include "py/mpstate.h"
#include "supervisor/linker.h"
#include "supervisor/filesystem.h"
+#include "supervisor/port.h"
#include "supervisor/shared/autoreload.h"
-static volatile uint64_t PLACE_IN_DTCM_BSS(ticks_ms);
-static volatile uint32_t PLACE_IN_DTCM_BSS(background_ticks_ms32);
+static volatile uint64_t PLACE_IN_DTCM_BSS(background_ticks);
#if CIRCUITPY_GAMEPAD
#include "shared-module/gamepad/__init__.h"
@@ -44,9 +45,6 @@ static volatile uint32_t PLACE_IN_DTCM_BSS(background_ticks_ms32);
#include "shared-bindings/microcontroller/__init__.h"
void supervisor_tick(void) {
-
- ticks_ms ++;
-
#if CIRCUITPY_FILESYSTEM_FLUSH_INTERVAL_MS > 0
filesystem_tick();
#endif
@@ -54,7 +52,7 @@ void supervisor_tick(void) {
autoreload_tick();
#endif
#ifdef CIRCUITPY_GAMEPAD_TICKS
- if (!(ticks_ms & CIRCUITPY_GAMEPAD_TICKS)) {
+ if (!(port_get_raw_ticks(NULL) & CIRCUITPY_GAMEPAD_TICKS)) {
#if CIRCUITPY_GAMEPAD
gamepad_tick();
#endif
@@ -68,29 +66,70 @@ void supervisor_tick(void) {
uint64_t supervisor_ticks_ms64() {
uint64_t result;
common_hal_mcu_disable_interrupts();
- result = ticks_ms;
+ result = port_get_raw_ticks(NULL);
common_hal_mcu_enable_interrupts();
+ result = result * 1000 / 1024;
return result;
}
uint32_t supervisor_ticks_ms32() {
- return ticks_ms;
+ return supervisor_ticks_ms64();
}
extern void run_background_tasks(void);
void PLACE_IN_ITCM(supervisor_run_background_tasks_if_tick)() {
- uint32_t now32 = ticks_ms;
+ // TODO: Add a global that can be set by anyone to indicate we should run background tasks. That
+ // way we can short circuit the background tasks early. We used to do it based on time but it
+ // breaks cases where we wake up for a short period and then sleep. If we skipped the last
+ // background task or more before sleeping we may end up starving a task like USB.
+ run_background_tasks();
+}
- if (now32 == background_ticks_ms32) {
- return;
+void mp_hal_delay_ms(mp_uint_t delay) {
+ uint64_t start_tick = port_get_raw_ticks(NULL);
+ // Adjust the delay to ticks vs ms.
+ delay = delay * 1024 / 1000;
+ uint64_t end_tick = start_tick + delay;
+ int64_t remaining = delay;
+ while (remaining > 0) {
+ RUN_BACKGROUND_TASKS;
+ // Check to see if we've been CTRL-Ced by autoreload or the user.
+ if(MP_STATE_VM(mp_pending_exception) == MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_kbd_exception)) ||
+ MP_STATE_VM(mp_pending_exception) == MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_reload_exception))) {
+ break;
+ }
+ remaining = end_tick - port_get_raw_ticks(NULL);
+ // We break a bit early so we don't risk setting the alarm before the time when we call
+ // sleep.
+ if (remaining < 1) {
+ break;
+ }
+ port_interrupt_after_ticks(remaining);
+ // Sleep until an interrupt happens.
+ port_sleep_until_interrupt();
+ remaining = end_tick - port_get_raw_ticks(NULL);
}
- background_ticks_ms32 = now32;
+}
- run_background_tasks();
+volatile size_t tick_enable_count = 0;
+extern 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_fake_tick() {
- uint32_t now32 = ticks_ms;
- background_ticks_ms32 = (now32 - 1);
+extern 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();
}
+
diff --git a/supervisor/shared/tick.h b/supervisor/shared/tick.h
index 7ce8281ba..e7e808058 100644
--- a/supervisor/shared/tick.h
+++ b/supervisor/shared/tick.h
@@ -64,4 +64,7 @@ extern uint64_t supervisor_ticks_ms64(void);
*/
extern void supervisor_run_background_if_tick(void);
+extern void supervisor_enable_tick(void);
+extern void supervisor_disable_tick(void);
+
#endif
diff --git a/supervisor/shared/usb/tusb_config.h b/supervisor/shared/usb/tusb_config.h
index ad5825b6c..1b0c83416 100644
--- a/supervisor/shared/usb/tusb_config.h
+++ b/supervisor/shared/usb/tusb_config.h
@@ -74,8 +74,8 @@
//------------- CLASS -------------//
#define CFG_TUD_CDC 1
#define CFG_TUD_MSC 1
-#define CFG_TUD_HID 1
-#define CFG_TUD_MIDI 1
+#define CFG_TUD_HID CIRCUITPY_USB_HID
+#define CFG_TUD_MIDI CIRCUITPY_USB_MIDI
#define CFG_TUD_CUSTOM_CLASS 0
/*------------------------------------------------------------------*/
diff --git a/supervisor/shared/usb/usb.c b/supervisor/shared/usb/usb.c
index a0178528d..774055a82 100644
--- a/supervisor/shared/usb/usb.c
+++ b/supervisor/shared/usb/usb.c
@@ -24,7 +24,6 @@
* THE SOFTWARE.
*/
-#include "tick.h"
#include "py/objstr.h"
#include "shared-bindings/microcontroller/Processor.h"
#include "shared-module/usb_midi/__init__.h"