Merge pull request #6473 from tannewt/auto_wifi
Wi-Fi autoconnect and title bar status
This commit is contained in:
commit
5c941ca8cd
@ -120,7 +120,7 @@ Behavior
|
||||
make each file independent from each other.
|
||||
|
||||
- ``boot.py`` runs only once on start up before
|
||||
USB is initialized. This lays the ground work for configuring USB at
|
||||
workflows are initialized. This lays the ground work for configuring USB at
|
||||
startup rather than it being fixed. Since serial is not available,
|
||||
output is written to ``boot_out.txt``.
|
||||
- ``code.py`` (or ``main.py``) is run after every reload until it
|
||||
@ -135,7 +135,10 @@ Behavior
|
||||
possible to fix code that causes nasty crashes by making it available through mass storage after
|
||||
the crash. A reset (the button) is needed after it's fixed to get back into normal mode.
|
||||
- RGB status LED indicating CircuitPython state.
|
||||
- Re-runs ``code.py`` or other main file after file system writes over USB mass storage. (Disable with
|
||||
- One green flash - code completed without error.
|
||||
- Two red flashes - code ended due to an exception.
|
||||
- Three yellow flashes - safe mode. May be due to CircuitPython internal error.
|
||||
- Re-runs ``code.py`` or other main file after file system writes by a workflow. (Disable with
|
||||
``supervisor.disable_autoreload()``)
|
||||
- Autoreload is disabled while the REPL is active.
|
||||
- Main is one of these: ``code.txt``, ``code.py``, ``main.py``,
|
||||
|
40
docs/environment.rst
Normal file
40
docs/environment.rst
Normal file
@ -0,0 +1,40 @@
|
||||
Environment Variables
|
||||
=====================
|
||||
|
||||
CircuitPython 8.0.0 introduces support for environment variables. Environment
|
||||
variables are commonly used to store "secrets" such as Wi-Fi passwords and API
|
||||
keys. This method *does not* make them secure. It only separates them from the
|
||||
code.
|
||||
|
||||
CircuitPython supports these by mimicking the `dotenv <https://github.com/theskumar/python-dotenv>`_
|
||||
CPython library. Other languages such as Javascript, PHP and Ruby also have
|
||||
dotenv libraries.
|
||||
|
||||
These libraries store environment variables in a ``.env`` file. Here is a simple
|
||||
example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
KEY1='value1'
|
||||
# Comment
|
||||
KEY2='value2
|
||||
is multiple lines'
|
||||
|
||||
CircuitPython uses the ``.env`` at the drive root (no folder) as the environment.
|
||||
User code can access the values from the file using `os.getenv()`. It is
|
||||
recommended to save any values used repeatedly in a variable because `os.getenv()`
|
||||
will parse the ``/.env`` on every access.
|
||||
|
||||
CircuitPython behavior
|
||||
----------------------
|
||||
|
||||
CircuitPython will also read the environment to configure its behavior. Other
|
||||
keys are ignored by CircuitPython. Here are the keys it uses:
|
||||
|
||||
CIRCUITPY_WIFI_PASSWORD
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Wi-Fi password used to auto connect to CIRCUITPY_WIFI_SSID
|
||||
|
||||
CIRCUITPY_WIFI_SSID
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
Wi-Fi SSID to auto-connect to even if user code is not running.
|
@ -22,6 +22,7 @@ Full Table of Contents
|
||||
supported_ports.rst
|
||||
troubleshooting.rst
|
||||
drivers.rst
|
||||
environment.rst
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
@ -1375,6 +1375,10 @@ msgstr ""
|
||||
msgid "No I2C device at address: 0x%x"
|
||||
msgstr ""
|
||||
|
||||
#: supervisor/shared/web_workflow/web_workflow.c
|
||||
msgid "No IP"
|
||||
msgstr ""
|
||||
|
||||
#: ports/espressif/common-hal/busio/SPI.c
|
||||
#: ports/mimxrt10xx/common-hal/busio/SPI.c
|
||||
msgid "No MISO Pin"
|
||||
@ -2254,6 +2258,10 @@ msgid ""
|
||||
"To list built-in modules type `help(\"modules\")`.\n"
|
||||
msgstr ""
|
||||
|
||||
#: supervisor/shared/web_workflow/web_workflow.c
|
||||
msgid "Wi-Fi: "
|
||||
msgstr ""
|
||||
|
||||
#: main.c
|
||||
msgid "Woken up by alarm.\n"
|
||||
msgstr ""
|
||||
@ -3579,6 +3587,10 @@ msgstr ""
|
||||
msgid "odd-length string"
|
||||
msgstr ""
|
||||
|
||||
#: supervisor/shared/web_workflow/web_workflow.c
|
||||
msgid "off"
|
||||
msgstr ""
|
||||
|
||||
#: extmod/ulab/code/numpy/create.c extmod/ulab/code/utils/utils.c
|
||||
msgid "offset is too large"
|
||||
msgstr ""
|
||||
|
33
main.c
33
main.c
@ -101,6 +101,10 @@
|
||||
#include "shared-module/memorymonitor/__init__.h"
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_SOCKETPOOL
|
||||
#include "shared-bindings/socketpool/__init__.h"
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_USB_HID
|
||||
#include "shared-module/usb_hid/__init__.h"
|
||||
#endif
|
||||
@ -290,6 +294,16 @@ STATIC void cleanup_after_vm(supervisor_allocation *heap, mp_obj_t exception) {
|
||||
keypad_reset();
|
||||
#endif
|
||||
|
||||
// Close user-initiated sockets.
|
||||
#if CIRCUITPY_SOCKETPOOL
|
||||
socketpool_user_reset();
|
||||
#endif
|
||||
|
||||
// Turn off user initiated WiFi connections.
|
||||
#if CIRCUITPY_WIFI
|
||||
wifi_user_reset();
|
||||
#endif
|
||||
|
||||
// reset_board_buses() first because it may release pins from the never_reset state, so that
|
||||
// reset_port() can reset them.
|
||||
#if CIRCUITPY_BOARD
|
||||
@ -303,6 +317,9 @@ STATIC void cleanup_after_vm(supervisor_allocation *heap, mp_obj_t exception) {
|
||||
stop_mp();
|
||||
free_memory(heap);
|
||||
supervisor_move_memory();
|
||||
|
||||
// Let the workflows know we've reset in case they want to restart.
|
||||
supervisor_workflow_reset();
|
||||
}
|
||||
|
||||
STATIC void print_code_py_status_message(safe_mode_t safe_mode) {
|
||||
@ -889,21 +906,7 @@ int __attribute__((used)) main(void) {
|
||||
|
||||
run_boot_py(safe_mode);
|
||||
|
||||
// Start USB after giving boot.py a chance to tweak behavior.
|
||||
#if CIRCUITPY_USB
|
||||
// Setup USB connection after heap is available.
|
||||
// It needs the heap to build descriptors.
|
||||
usb_init();
|
||||
#endif
|
||||
|
||||
// Set up any other serial connection.
|
||||
serial_init();
|
||||
|
||||
#if CIRCUITPY_BLEIO
|
||||
bleio_reset();
|
||||
supervisor_bluetooth_enable_workflow();
|
||||
supervisor_start_bluetooth();
|
||||
#endif
|
||||
supervisor_workflow_start();
|
||||
|
||||
// Boot script is finished, so now go into REPL or run code.py.
|
||||
int exit_code = PYEXEC_FORCED_EXIT;
|
||||
|
@ -117,6 +117,10 @@ void board_init(void) {
|
||||
true, // backlight_on_high
|
||||
false, // SH1107_addressing
|
||||
50000); // backlight pwm frequency
|
||||
|
||||
#if CIRCUITPY_DEBUG
|
||||
common_hal_never_reset_pin(DEFAULT_UART_BUS_TX);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool espressif_board_reset_pin_number(gpio_num_t pin_number) {
|
||||
|
@ -39,7 +39,7 @@
|
||||
|
||||
STATIC socketpool_socket_obj_t *open_socket_handles[CONFIG_LWIP_MAX_SOCKETS];
|
||||
|
||||
void socket_reset(void) {
|
||||
void socket_user_reset(void) {
|
||||
for (size_t i = 0; i < MP_ARRAY_SIZE(open_socket_handles); i++) {
|
||||
if (open_socket_handles[i]) {
|
||||
if (open_socket_handles[i]->num > 0) {
|
||||
|
@ -45,7 +45,7 @@ typedef struct {
|
||||
mp_uint_t timeout_ms;
|
||||
} socketpool_socket_obj_t;
|
||||
|
||||
void socket_reset(void);
|
||||
void socket_user_reset(void);
|
||||
bool register_open_socket(socketpool_socket_obj_t *self);
|
||||
|
||||
#endif // MICROPY_INCLUDED_ESPRESSIF_COMMON_HAL_SOCKETPOOL_SOCKET_H
|
||||
|
@ -23,3 +23,11 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "shared-bindings/socketpool/__init__.h"
|
||||
|
||||
#include "common-hal/socketpool/Socket.h"
|
||||
|
||||
void socketpool_user_reset(void) {
|
||||
socket_user_reset();
|
||||
}
|
||||
|
@ -236,6 +236,11 @@ wifi_radio_error_t common_hal_wifi_radio_connect(wifi_radio_obj_t *self, uint8_t
|
||||
if (!common_hal_wifi_radio_get_enabled(self)) {
|
||||
mp_raise_RuntimeError(translate("wifi is not enabled"));
|
||||
}
|
||||
wifi_config_t *config = &self->sta_config;
|
||||
|
||||
size_t timeout_ms = timeout * 1000;
|
||||
uint32_t start_time = common_hal_time_monotonic_ms();
|
||||
uint32_t end_time = start_time + timeout_ms;
|
||||
|
||||
EventBits_t bits;
|
||||
// can't block since both bits are false after wifi_init
|
||||
@ -245,18 +250,37 @@ wifi_radio_error_t common_hal_wifi_radio_connect(wifi_radio_obj_t *self, uint8_t
|
||||
pdTRUE,
|
||||
pdTRUE,
|
||||
0);
|
||||
if (((bits & WIFI_CONNECTED_BIT) != 0) &&
|
||||
!((bits & WIFI_DISCONNECTED_BIT) != 0)) {
|
||||
bool connected = ((bits & WIFI_CONNECTED_BIT) != 0) &&
|
||||
!((bits & WIFI_DISCONNECTED_BIT) != 0);
|
||||
if (connected) {
|
||||
// SSIDs are up to 32 bytes. Assume it is null terminated if it is less.
|
||||
if (memcmp(ssid, config->sta.ssid, ssid_len) == 0 &&
|
||||
(ssid_len == 32 || strlen((const char *)config->sta.ssid) == ssid_len)) {
|
||||
// Already connected to the desired network.
|
||||
return WIFI_RADIO_ERROR_NONE;
|
||||
} else {
|
||||
xEventGroupClearBits(self->event_group_handle, WIFI_DISCONNECTED_BIT);
|
||||
// Trying to switch networks so disconnect first.
|
||||
esp_wifi_disconnect();
|
||||
do {
|
||||
RUN_BACKGROUND_TASKS;
|
||||
bits = xEventGroupWaitBits(self->event_group_handle,
|
||||
WIFI_DISCONNECTED_BIT,
|
||||
pdTRUE,
|
||||
pdTRUE,
|
||||
0);
|
||||
} while ((bits & WIFI_DISCONNECTED_BIT) == 0 && !mp_hal_is_interrupted());
|
||||
}
|
||||
}
|
||||
// explicitly clear bits since xEventGroupWaitBits may have timed out
|
||||
xEventGroupClearBits(self->event_group_handle, WIFI_CONNECTED_BIT);
|
||||
xEventGroupClearBits(self->event_group_handle, WIFI_DISCONNECTED_BIT);
|
||||
set_mode_station(self, true);
|
||||
|
||||
wifi_config_t *config = &self->sta_config;
|
||||
memcpy(&config->sta.ssid, ssid, ssid_len);
|
||||
if (ssid_len < 32) {
|
||||
config->sta.ssid[ssid_len] = 0;
|
||||
}
|
||||
memcpy(&config->sta.password, password, password_len);
|
||||
config->sta.password[password_len] = 0;
|
||||
config->sta.channel = channel;
|
||||
@ -289,6 +313,10 @@ wifi_radio_error_t common_hal_wifi_radio_connect(wifi_radio_obj_t *self, uint8_t
|
||||
pdTRUE,
|
||||
pdTRUE,
|
||||
0);
|
||||
// Don't retry anymore if we're over our time budget.
|
||||
if (self->retries_left > 0 && common_hal_time_monotonic_ms() > end_time) {
|
||||
self->retries_left = 0;
|
||||
}
|
||||
} while ((bits & (WIFI_CONNECTED_BIT | WIFI_DISCONNECTED_BIT)) == 0 && !mp_hal_is_interrupted());
|
||||
if ((bits & WIFI_DISCONNECTED_BIT) != 0) {
|
||||
if (self->last_disconnect_reason == WIFI_REASON_AUTH_FAIL) {
|
||||
@ -368,6 +396,14 @@ mp_obj_t common_hal_wifi_radio_get_ipv4_subnet_ap(wifi_radio_obj_t *self) {
|
||||
return common_hal_ipaddress_new_ipv4address(self->ap_ip_info.netmask.addr);
|
||||
}
|
||||
|
||||
uint32_t wifi_radio_get_ipv4_address(wifi_radio_obj_t *self) {
|
||||
if (!esp_netif_is_netif_up(self->netif)) {
|
||||
return 0;
|
||||
}
|
||||
esp_netif_get_ip_info(self->netif, &self->ip_info);
|
||||
return self->ip_info.ip.addr;
|
||||
}
|
||||
|
||||
mp_obj_t common_hal_wifi_radio_get_ipv4_address(wifi_radio_obj_t *self) {
|
||||
if (!esp_netif_is_netif_up(self->netif)) {
|
||||
return mp_const_none;
|
||||
|
@ -42,6 +42,8 @@ wifi_radio_obj_t common_hal_wifi_radio_obj;
|
||||
|
||||
#include "components/log/include/esp_log.h"
|
||||
|
||||
#include "supervisor/workflow.h"
|
||||
|
||||
static const char *TAG = "wifi";
|
||||
|
||||
static void event_handler(void *arg, esp_event_base_t event_base,
|
||||
@ -106,12 +108,19 @@ static void event_handler(void *arg, esp_event_base_t event_base,
|
||||
radio->retries_left = radio->starting_retries;
|
||||
xEventGroupSetBits(radio->event_group_handle, WIFI_CONNECTED_BIT);
|
||||
}
|
||||
supervisor_workflow_request_background();
|
||||
}
|
||||
|
||||
static bool wifi_inited, wifi_ever_inited;
|
||||
static bool wifi_inited;
|
||||
static bool wifi_ever_inited;
|
||||
static bool wifi_user_initiated;
|
||||
|
||||
void common_hal_wifi_init(void) {
|
||||
void common_hal_wifi_init(bool user_initiated) {
|
||||
if (wifi_inited) {
|
||||
return;
|
||||
}
|
||||
wifi_inited = true;
|
||||
wifi_user_initiated = user_initiated;
|
||||
common_hal_wifi_radio_obj.base.type = &wifi_radio_type;
|
||||
|
||||
if (!wifi_ever_inited) {
|
||||
@ -157,6 +166,12 @@ void common_hal_wifi_init(void) {
|
||||
common_hal_wifi_radio_set_enabled(self, true);
|
||||
}
|
||||
|
||||
void wifi_user_reset(void) {
|
||||
if (wifi_user_initiated) {
|
||||
wifi_reset();
|
||||
}
|
||||
}
|
||||
|
||||
void wifi_reset(void) {
|
||||
if (!wifi_inited) {
|
||||
return;
|
||||
@ -176,6 +191,7 @@ void wifi_reset(void) {
|
||||
esp_netif_destroy(radio->ap_netif);
|
||||
radio->ap_netif = NULL;
|
||||
wifi_inited = false;
|
||||
supervisor_workflow_request_background();
|
||||
}
|
||||
|
||||
void ipaddress_ipaddress_to_esp_idf(mp_obj_t ip_address, ip_addr_t *esp_ip_address) {
|
||||
|
@ -282,14 +282,6 @@ void reset_port(void) {
|
||||
#if CIRCUITPY_WATCHDOG
|
||||
watchdog_reset();
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_WIFI
|
||||
wifi_reset();
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_SOCKETPOOL
|
||||
socket_reset();
|
||||
#endif
|
||||
}
|
||||
|
||||
void reset_to_bootloader(void) {
|
||||
|
@ -7,42 +7,10 @@ MCU_CHIP = nrf52833
|
||||
|
||||
INTERNAL_FLASH_FILESYSTEM = 1
|
||||
|
||||
CIRCUITPY_AESIO = 0
|
||||
CIRCUITPY_ALARM = 0
|
||||
CIRCUITPY_AUDIOBUSIO = 0
|
||||
#CIRCUITPY_AUDIOCORE = 0
|
||||
#CIRCUITPY_AUDIOIO = 0
|
||||
CIRCUITPY_AUDIOMIXER = 0
|
||||
CIRCUITPY_AUDIOMP3 = 0
|
||||
CIRCUITPY_BINASCII = 0
|
||||
CIRCUITPY_BITBANGIO = 0
|
||||
CIRCUITPY_BITMAPTOOLS = 0
|
||||
CIRCUITPY_BUILTINS_POW3=0
|
||||
CIRCUITPY_BUSDEVICE = 0
|
||||
CIRCUITPY_COUNTIO = 0
|
||||
CIRCUITPY_DISPLAYIO = 0
|
||||
CIRCUITPY_FRAMEBUFFERIO = 0
|
||||
CIRCUITPY_FREQUENCYIO = 0
|
||||
CIRCUITPY_GETPASS = 0
|
||||
CIRCUITPY_I2CPERIPHERAL = 0
|
||||
CIRCUITPY_JSON = 0
|
||||
CIRCUITPY_KEYPAD = 1
|
||||
CIRCUITPY_MSGPACK = 0
|
||||
#CIRCUITPY_NEOPIXEL_WRITE = 1
|
||||
CIRCUITPY_ONEWIREIO = 0
|
||||
CIRCUITPY_NVM = 0
|
||||
CIRCUITPY_ONEWIREIO = 0
|
||||
CIRCUITPY_PIXELBUF = 1
|
||||
CIRCUITPY_PULSEIO = 1
|
||||
CIRCUITPY_RE = 0
|
||||
CIRCUITPY_RGBMATRIX = 0
|
||||
CIRCUITPY_SDCARDIO = 0
|
||||
CIRCUITPY_SYNTHIO = 0
|
||||
CIRCUITPY_TRACEBACK = 0
|
||||
CIRCUITPY_TOUCHIO = 0
|
||||
CIRCUITPY_TRACEBACK = 0
|
||||
CIRCUITPY_ULAB = 0
|
||||
CIRCUITPY_USB_MIDI = 0
|
||||
CIRCUITPY_VECTORIO = 0
|
||||
CIRCUITPY_ZLIB = 0
|
||||
|
||||
MICROPY_PY_ASYNC_AWAIT = 0
|
||||
|
@ -5,26 +5,5 @@ MCU_CHIP = nrf52833
|
||||
|
||||
INTERNAL_FLASH_FILESYSTEM = 1
|
||||
|
||||
CIRCUITPY_ALARM = 0
|
||||
CIRCUITPY_AUDIOMP3 = 0
|
||||
CIRCUITPY_BITBANGIO = 0
|
||||
CIRCUITPY_BUILTINS_POW3=0
|
||||
CIRCUITPY_BUSDEVICE = 0
|
||||
CIRCUITPY_COUNTIO = 0
|
||||
CIRCUITPY_DISPLAYIO = 0
|
||||
CIRCUITPY_FRAMEBUFFERIO = 0
|
||||
CIRCUITPY_FREQUENCYIO = 0
|
||||
CIRCUITPY_I2CPERIPHERAL = 0
|
||||
CIRCUITPY_JSON = 0
|
||||
CIRCUITPY_KEYPAD = 0
|
||||
CIRCUITPY_MSGPACK = 0
|
||||
CIRCUITPY_NEOPIXEL_WRITE = 0
|
||||
CIRCUITPY_NVM = 0
|
||||
CIRCUITPY_PIXELBUF = 0
|
||||
CIRCUITPY_RE = 0
|
||||
CIRCUITPY_RGBMATRIX = 0
|
||||
CIRCUITPY_SDCARDIO = 0
|
||||
CIRCUITPY_ULAB = 0
|
||||
# USB pins aren't used.
|
||||
CIRCUITPY_USB = 0
|
||||
|
||||
MICROPY_PY_ASYNC_AWAIT = 0
|
||||
|
@ -6,33 +6,3 @@ USB_MANUFACTURER = "Nordic Semiconductor"
|
||||
MCU_CHIP = nrf52833
|
||||
|
||||
INTERNAL_FLASH_FILESYSTEM = 1
|
||||
|
||||
CIRCUITPY_AESIO = 0
|
||||
CIRCUITPY_ALARM = 0
|
||||
CIRCUITPY_AUDIOMP3 = 0
|
||||
CIRCUITPY_BINASCII = 0
|
||||
CIRCUITPY_BITBANGIO = 0
|
||||
CIRCUITPY_BITMAPTOOLS = 0
|
||||
CIRCUITPY_BUSDEVICE = 0
|
||||
CIRCUITPY_COUNTIO = 0
|
||||
CIRCUITPY_DISPLAYIO = 0
|
||||
CIRCUITPY_FRAMEBUFFERIO = 0
|
||||
CIRCUITPY_FREQUENCYIO = 0
|
||||
CIRCUITPY_GETPASS = 0
|
||||
CIRCUITPY_I2CPERIPHERAL = 0
|
||||
CIRCUITPY_JSON = 0
|
||||
CIRCUITPY_KEYPAD = 0
|
||||
CIRCUITPY_MSGPACK = 0
|
||||
CIRCUITPY_NEOPIXEL_WRITE = 0
|
||||
CIRCUITPY_NVM = 0
|
||||
CIRCUITPY_PIXELBUF = 0
|
||||
CIRCUITPY_RE = 0
|
||||
CIRCUITPY_RGBMATRIX = 0
|
||||
CIRCUITPY_SDCARDIO = 0
|
||||
CIRCUITPY_SYNTHIO = 0
|
||||
CIRCUITPY_ULAB = 0
|
||||
CIRCUITPY_USB_MIDI = 0
|
||||
CIRCUITPY_VECTORIO = 0
|
||||
CIRCUITPY_ZLIB = 0
|
||||
|
||||
MICROPY_PY_ASYNC_AWAIT = 0
|
||||
|
@ -13,37 +13,18 @@ INTERNAL_FLASH_FILESYSTEM = 1
|
||||
CIRCUITPY_ALARM = 0
|
||||
CIRCUITPY_AESIO = 1
|
||||
CIRCUITPY_AUDIOMIXER = 0
|
||||
CIRCUITPY_AUDIOMP3 = 0
|
||||
CIRCUITPY_BITBANGIO = 0
|
||||
CIRCUITPY_BITMAPTOOLS = 0
|
||||
CIRCUITPY_BUSDEVICE = 0
|
||||
CIRCUITPY_BUSIO = 1
|
||||
CIRCUITPY_COUNTIO = 0
|
||||
CIRCUITPY_DISPLAYIO = 0
|
||||
CIRCUITPY_ERRNO = 0
|
||||
CIRCUITPY_FRAMEBUFFERIO = 0
|
||||
CIRCUITPY_GETPASS = 0
|
||||
CIRCUITPY_KEYPAD = 0
|
||||
CIRCUITPY_MSGPACK = 0
|
||||
CIRCUITPY_NEOPIXEL_WRITE = 0
|
||||
CIRCUITPY_NVM = 0
|
||||
CIRCUITPY_ONEWIREIO = 0
|
||||
CIRCUITPY_PIXELBUF = 0
|
||||
CIRCUITPY_PULSEIO = 0
|
||||
CIRCUITPY_PWMIO = 1
|
||||
# Deliberately excluded for other reasons than code space, see #5534
|
||||
CIRCUITPY_RAINBOWIO = 0
|
||||
CIRCUITPY_RGBMATRIX = 0
|
||||
CIRCUITPY_ROTARYIO = 0
|
||||
CIRCUITPY_RTC = 1
|
||||
CIRCUITPY_SDCARDIO = 0
|
||||
CIRCUITPY_SYNTHIO = 0
|
||||
CIRCUITPY_TOUCHIO = 0
|
||||
CIRCUITPY_ULAB = 0
|
||||
CIRCUITPY_USB_CDC = 0
|
||||
CIRCUITPY_USB_MIDI = 0
|
||||
CIRCUITPY_WATCHDOG = 1
|
||||
CIRCUITPY_ZLIB = 0
|
||||
|
||||
# Enable micropython.native
|
||||
#CIRCUITPY_ENABLE_MPY_NATIVE = 1
|
||||
|
@ -32,12 +32,7 @@ CIRCUITPY_RTC ?= 1
|
||||
# frequencyio not yet implemented
|
||||
CIRCUITPY_FREQUENCYIO = 0
|
||||
|
||||
CIRCUITPY_RGBMATRIX ?= 1
|
||||
CIRCUITPY_ROTARYIO_SOFTENCODER = 1
|
||||
CIRCUITPY_FRAMEBUFFERIO ?= 1
|
||||
|
||||
CIRCUITPY_COUNTIO ?= 1
|
||||
CIRCUITPY_WATCHDOG ?= 1
|
||||
|
||||
# Sleep and Wakeup
|
||||
CIRCUITPY_ALARM ?= 1
|
||||
@ -60,6 +55,12 @@ MCU_SUB_VARIANT = nrf52840
|
||||
# Fits on nrf52840 but space is tight on nrf52833.
|
||||
CIRCUITPY_AESIO ?= 1
|
||||
|
||||
CIRCUITPY_RGBMATRIX ?= 1
|
||||
CIRCUITPY_FRAMEBUFFERIO ?= 1
|
||||
|
||||
CIRCUITPY_COUNTIO ?= 1
|
||||
CIRCUITPY_WATCHDOG ?= 1
|
||||
|
||||
SD ?= s140
|
||||
SOFTDEV_VERSION ?= 6.1.0
|
||||
|
||||
@ -87,6 +88,8 @@ MCU_SUB_VARIANT = nrf52833
|
||||
SUPEROPT_GC ?= 0
|
||||
SUPEROPT_VM ?= 0
|
||||
|
||||
CIRCUITPY_SYNTHIO ?= 0
|
||||
|
||||
SD ?= s140
|
||||
SOFTDEV_VERSION ?= 7.0.1
|
||||
|
||||
@ -97,5 +100,9 @@ OPTIMIZATION_FLAGS ?= -Os
|
||||
|
||||
CIRCUITPY_LTO = 1
|
||||
CIRCUITPY_LTO_PARTITION = one
|
||||
ifeq ($(INTERNAL_FLASH_FILESYSTEM),1)
|
||||
CIRCUITPY_FULL_BUILD ?= 0
|
||||
CIRCUITPY_PULSEIO ?= 1
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
@ -70,7 +70,9 @@ endif
|
||||
CIRCUITPY_LTO ?= 0
|
||||
CIRCUITPY_LTO_PARTITION ?= balanced
|
||||
ifeq ($(CIRCUITPY_LTO),1)
|
||||
CFLAGS += -flto -flto-partition=$(CIRCUITPY_LTO_PARTITION)
|
||||
CFLAGS += -flto -flto-partition=$(CIRCUITPY_LTO_PARTITION) -DCIRCUITPY_LTO=1
|
||||
else
|
||||
CFLAGS += -DCIRCUITPY_LTO=0
|
||||
endif
|
||||
|
||||
# Produce an object file for translate.c instead of including it in a header.
|
||||
|
@ -233,7 +233,7 @@ typedef long mp_off_t;
|
||||
#define MICROPY_PY_URE_MATCH_SPAN_START_END (CIRCUITPY_RE)
|
||||
#define MICROPY_PY_URE_SUB (CIRCUITPY_RE)
|
||||
|
||||
#define CIRCUITPY_MICROPYTHON_ADVANCED (CIRCUITPY_FULL_BUILD)
|
||||
#define CIRCUITPY_MICROPYTHON_ADVANCED (0)
|
||||
|
||||
#ifndef MICROPY_FATFS_EXFAT
|
||||
#define MICROPY_FATFS_EXFAT (CIRCUITPY_FULL_BUILD)
|
||||
|
@ -460,7 +460,7 @@ CIRCUITPY_USTACK ?= 0
|
||||
CFLAGS += -DCIRCUITPY_USTACK=$(CIRCUITPY_USTACK)
|
||||
|
||||
# for decompressing utlities
|
||||
CIRCUITPY_ZLIB ?= 1
|
||||
CIRCUITPY_ZLIB ?= $(CIRCUITPY_FULL_BUILD)
|
||||
CFLAGS += -DCIRCUITPY_ZLIB=$(CIRCUITPY_ZLIB)
|
||||
|
||||
# ulab numerics library
|
||||
@ -480,6 +480,9 @@ CFLAGS += -DCIRCUITPY_WATCHDOG=$(CIRCUITPY_WATCHDOG)
|
||||
CIRCUITPY_WIFI ?= 0
|
||||
CFLAGS += -DCIRCUITPY_WIFI=$(CIRCUITPY_WIFI)
|
||||
|
||||
CIRCUITPY_WEB_WORKFLOW ?= $(CIRCUITPY_WIFI)
|
||||
CFLAGS += -DCIRCUITPY_WEB_WORKFLOW=$(CIRCUITPY_WEB_WORKFLOW)
|
||||
|
||||
# tinyusb port tailored configuration
|
||||
CIRCUITPY_TUSB_MEM_ALIGN ?= 4
|
||||
CFLAGS += -DCIRCUITPY_TUSB_MEM_ALIGN=$(CIRCUITPY_TUSB_MEM_ALIGN)
|
||||
|
@ -69,5 +69,6 @@ void common_hal_displayio_tilegrid_set_tile(displayio_tilegrid_t *self, uint16_t
|
||||
|
||||
// Private API for scrolling the TileGrid.
|
||||
void common_hal_displayio_tilegrid_set_top_left(displayio_tilegrid_t *self, uint16_t x, uint16_t y);
|
||||
void common_hal_displayio_tilegrid_set_all_tiles(displayio_tilegrid_t *self, uint8_t tile_index);
|
||||
|
||||
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_TILEGRID_H
|
||||
|
@ -27,4 +27,6 @@
|
||||
#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_SOCKETPOOL___INIT___H
|
||||
#define MICROPY_INCLUDED_SHARED_BINDINGS_SOCKETPOOL___INIT___H
|
||||
|
||||
void socketpool_user_reset(void);
|
||||
|
||||
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_SOCKETPOOL___INIT___H
|
||||
|
@ -38,31 +38,52 @@
|
||||
#include "supervisor/shared/translate/translate.h"
|
||||
|
||||
//| class Terminal:
|
||||
//| """Display a character stream with a TileGrid"""
|
||||
//| """Display a character stream with a TileGrid
|
||||
//|
|
||||
//| def __init__(self, tilegrid: displayio.TileGrid, font: fontio.BuiltinFont) -> None:
|
||||
//| ASCII control:
|
||||
//| * ``\\r`` - Move cursor to column 1
|
||||
//| * ``\\n`` - Move cursor down a row
|
||||
//| * ``\\b`` - Move cursor left one if possible
|
||||
//|
|
||||
//| OSC control sequences:
|
||||
//| * ``ESC ] 0; <s> ESC \\`` - Set title bar to <s>
|
||||
//| * ``ESC ] ####; <s> ESC \\`` - Ignored
|
||||
//|
|
||||
//| VT100 control sequences:
|
||||
//| * ``ESC [ K`` - Clear the remainder of the line
|
||||
//| * ``ESC [ #### D`` - Move the cursor to the left by ####
|
||||
//| * ``ESC [ 2 J`` - Erase the entire display
|
||||
//| * ``ESC [ nnnn ; mmmm H`` - Move the cursor to mmmm, nnnn.
|
||||
//| """
|
||||
//|
|
||||
//| def __init__(self, scroll_area: displayio.TileGrid, font: fontio.BuiltinFont, *, title_bar: displayio.TileGrid = None) -> None:
|
||||
//| """Terminal manages tile indices and cursor position based on VT100 commands. The font should be
|
||||
//| a `fontio.BuiltinFont` and the TileGrid's bitmap should match the font's bitmap."""
|
||||
//| ...
|
||||
//|
|
||||
|
||||
STATIC mp_obj_t terminalio_terminal_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
|
||||
enum { ARG_tilegrid, ARG_font };
|
||||
enum { ARG_scroll_area, ARG_font, ARG_title_bar };
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_tilegrid, MP_ARG_REQUIRED | MP_ARG_OBJ },
|
||||
{ MP_QSTR_scroll_area, MP_ARG_REQUIRED | MP_ARG_OBJ },
|
||||
{ MP_QSTR_font, MP_ARG_REQUIRED | MP_ARG_OBJ },
|
||||
{ MP_QSTR_title_bar, MP_ARG_KW_ONLY | MP_ARG_OBJ, { .u_obj = mp_const_none } },
|
||||
};
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||
mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||
|
||||
displayio_tilegrid_t *tilegrid = mp_arg_validate_type(args[ARG_tilegrid].u_obj, &displayio_tilegrid_type, MP_QSTR_tilegrid);
|
||||
displayio_tilegrid_t *scroll_area = mp_arg_validate_type(args[ARG_scroll_area].u_obj, &displayio_tilegrid_type, MP_QSTR_scroll_area);
|
||||
displayio_tilegrid_t *title_bar = NULL;
|
||||
if (args[ARG_title_bar].u_obj != mp_const_none) {
|
||||
title_bar = mp_arg_validate_type(args[ARG_title_bar].u_obj, &displayio_tilegrid_type, MP_QSTR_title_bar);
|
||||
}
|
||||
|
||||
fontio_builtinfont_t *font = mp_arg_validate_type(args[ARG_font].u_obj, &fontio_builtinfont_type, MP_QSTR_font);
|
||||
|
||||
terminalio_terminal_obj_t *self = m_new_obj(terminalio_terminal_obj_t);
|
||||
self->base.type = &terminalio_terminal_type;
|
||||
|
||||
common_hal_terminalio_terminal_construct(self, tilegrid, font);
|
||||
common_hal_terminalio_terminal_construct(self, scroll_area, font, title_bar);
|
||||
return MP_OBJ_FROM_PTR(self);
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,7 @@
|
||||
extern const mp_obj_type_t terminalio_terminal_type;
|
||||
|
||||
extern void common_hal_terminalio_terminal_construct(terminalio_terminal_obj_t *self,
|
||||
displayio_tilegrid_t *tilegrid, const fontio_builtinfont_t *font);
|
||||
displayio_tilegrid_t *scroll_area, const fontio_builtinfont_t *font, displayio_tilegrid_t *title_bar);
|
||||
|
||||
// Write characters. len is in characters NOT bytes!
|
||||
extern size_t common_hal_terminalio_terminal_write(terminalio_terminal_obj_t *self,
|
||||
|
@ -257,6 +257,7 @@ STATIC mp_obj_t wifi_radio_start_ap(size_t n_args, const mp_obj_t *pos_args, mp_
|
||||
|
||||
mp_buffer_info_t ssid;
|
||||
mp_get_buffer_raise(args[ARG_ssid].u_obj, &ssid, MP_BUFFER_READ);
|
||||
mp_arg_validate_length_range(ssid.len, 1, 32, MP_QSTR_ssid);
|
||||
|
||||
mp_buffer_info_t password;
|
||||
password.len = 0;
|
||||
@ -330,9 +331,7 @@ STATIC mp_obj_t wifi_radio_connect(size_t n_args, const mp_obj_t *pos_args, mp_m
|
||||
mp_buffer_info_t ssid;
|
||||
ssid.len = 0;
|
||||
mp_get_buffer_raise(args[ARG_ssid].u_obj, &ssid, MP_BUFFER_READ);
|
||||
if (ssid.len > 32) {
|
||||
mp_raise_ValueError(translate("ssid can't be more than 32 bytes"));
|
||||
}
|
||||
mp_arg_validate_length_range(ssid.len, 1, 32, MP_QSTR_ssid);
|
||||
|
||||
mp_buffer_info_t password;
|
||||
password.len = 0;
|
||||
@ -439,11 +438,11 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(wifi_radio_set_ipv4_address_obj, 1, wifi_radio
|
||||
//| ipv4_address: Optional[ipaddress.IPv4Address]
|
||||
//| """IP v4 Address of the station when connected to an access point. None otherwise."""
|
||||
//|
|
||||
STATIC mp_obj_t wifi_radio_get_ipv4_address(mp_obj_t self) {
|
||||
STATIC mp_obj_t _wifi_radio_get_ipv4_address(mp_obj_t self) {
|
||||
return common_hal_wifi_radio_get_ipv4_address(self);
|
||||
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(wifi_radio_get_ipv4_address_obj, wifi_radio_get_ipv4_address);
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(wifi_radio_get_ipv4_address_obj, _wifi_radio_get_ipv4_address);
|
||||
|
||||
MP_PROPERTY_GETTER(wifi_radio_ipv4_address_obj,
|
||||
(mp_obj_t)&wifi_radio_get_ipv4_address_obj);
|
||||
|
@ -103,6 +103,7 @@ extern mp_obj_t common_hal_wifi_radio_get_ipv4_gateway(wifi_radio_obj_t *self);
|
||||
extern mp_obj_t common_hal_wifi_radio_get_ipv4_gateway_ap(wifi_radio_obj_t *self);
|
||||
extern mp_obj_t common_hal_wifi_radio_get_ipv4_subnet(wifi_radio_obj_t *self);
|
||||
extern mp_obj_t common_hal_wifi_radio_get_ipv4_subnet_ap(wifi_radio_obj_t *self);
|
||||
uint32_t wifi_radio_get_ipv4_address(wifi_radio_obj_t *self);
|
||||
extern mp_obj_t common_hal_wifi_radio_get_ipv4_address(wifi_radio_obj_t *self);
|
||||
extern mp_obj_t common_hal_wifi_radio_get_ipv4_address_ap(wifi_radio_obj_t *self);
|
||||
|
||||
|
@ -42,7 +42,7 @@
|
||||
|
||||
// Called when wifi is imported.
|
||||
STATIC mp_obj_t wifi___init__(void) {
|
||||
common_hal_wifi_init();
|
||||
common_hal_wifi_init(true);
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(wifi___init___obj, wifi___init__);
|
||||
|
@ -31,7 +31,9 @@
|
||||
|
||||
extern wifi_radio_obj_t common_hal_wifi_radio_obj;
|
||||
|
||||
void common_hal_wifi_init(void);
|
||||
void common_hal_wifi_init(bool user_initiated);
|
||||
void common_hal_wifi_gc_collect(void);
|
||||
|
||||
void wifi_user_reset(void);
|
||||
|
||||
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_WIFI___INIT___H
|
||||
|
@ -296,6 +296,27 @@ void common_hal_displayio_tilegrid_set_tile(displayio_tilegrid_t *self, uint16_t
|
||||
self->partial_change = true;
|
||||
}
|
||||
|
||||
void common_hal_displayio_tilegrid_set_all_tiles(displayio_tilegrid_t *self, uint8_t tile_index) {
|
||||
if (tile_index >= self->tiles_in_bitmap) {
|
||||
mp_raise_ValueError(translate("Tile index out of bounds"));
|
||||
}
|
||||
uint8_t *tiles = self->tiles;
|
||||
if (self->inline_tiles) {
|
||||
tiles = (uint8_t *)&self->tiles;
|
||||
}
|
||||
if (tiles == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (uint16_t x = 0; x < self->width_in_tiles; x++) {
|
||||
for (uint16_t y = 0; y < self->height_in_tiles; y++) {
|
||||
tiles[y * self->width_in_tiles + x] = tile_index;
|
||||
}
|
||||
}
|
||||
|
||||
self->full_change = true;
|
||||
}
|
||||
|
||||
bool common_hal_displayio_tilegrid_get_flip_x(displayio_tilegrid_t *self) {
|
||||
return self->flip_x;
|
||||
}
|
||||
|
@ -30,24 +30,28 @@
|
||||
#include "shared-bindings/displayio/TileGrid.h"
|
||||
#include "shared-bindings/terminalio/Terminal.h"
|
||||
|
||||
void common_hal_terminalio_terminal_construct(terminalio_terminal_obj_t *self, displayio_tilegrid_t *tilegrid, const fontio_builtinfont_t *font) {
|
||||
void common_hal_terminalio_terminal_construct(terminalio_terminal_obj_t *self,
|
||||
displayio_tilegrid_t *scroll_area, const fontio_builtinfont_t *font,
|
||||
displayio_tilegrid_t *title_bar) {
|
||||
self->cursor_x = 0;
|
||||
self->cursor_y = 0;
|
||||
self->font = font;
|
||||
self->tilegrid = tilegrid;
|
||||
self->scroll_area = scroll_area;
|
||||
self->title_bar = title_bar;
|
||||
self->title_x = 0;
|
||||
self->title_y = 0;
|
||||
self->first_row = 0;
|
||||
for (uint16_t x = 0; x < self->tilegrid->width_in_tiles; x++) {
|
||||
for (uint16_t y = 0; y < self->tilegrid->height_in_tiles; y++) {
|
||||
common_hal_displayio_tilegrid_set_tile(self->tilegrid, x, y, 0);
|
||||
}
|
||||
common_hal_displayio_tilegrid_set_all_tiles(self->scroll_area, 0);
|
||||
if (self->title_bar) {
|
||||
common_hal_displayio_tilegrid_set_all_tiles(self->title_bar, 0);
|
||||
}
|
||||
|
||||
common_hal_displayio_tilegrid_set_top_left(self->tilegrid, 0, 1);
|
||||
common_hal_displayio_tilegrid_set_top_left(self->scroll_area, 0, 1);
|
||||
}
|
||||
|
||||
size_t common_hal_terminalio_terminal_write(terminalio_terminal_obj_t *self, const byte *data, size_t len, int *errcode) {
|
||||
// Make sure the terminal is initialized before we do anything with it.
|
||||
if (self->tilegrid == NULL) {
|
||||
if (self->scroll_area == NULL) {
|
||||
return len;
|
||||
}
|
||||
const byte *i = data;
|
||||
@ -55,11 +59,34 @@ size_t common_hal_terminalio_terminal_write(terminalio_terminal_obj_t *self, con
|
||||
while (i < data + len) {
|
||||
unichar c = utf8_get_char(i);
|
||||
i = utf8_next_char(i);
|
||||
if (self->in_osc_command) {
|
||||
if (c == 0x1b && i[0] == '\\') {
|
||||
self->in_osc_command = false;
|
||||
self->title_x = 0;
|
||||
self->title_y = 0;
|
||||
i += 1;
|
||||
} else if (self->osc_command == 0 && self->title_bar != NULL && self->title_y < self->title_bar->height_in_tiles) {
|
||||
uint8_t tile_index = fontio_builtinfont_get_glyph_index(self->font, c);
|
||||
if (tile_index != 0xff) {
|
||||
// Clear the tile grid before we start putting new info.
|
||||
if (self->title_x == 0 && self->title_y == 0) {
|
||||
common_hal_displayio_tilegrid_set_all_tiles(self->title_bar, 0);
|
||||
}
|
||||
common_hal_displayio_tilegrid_set_tile(self->title_bar, self->title_x, self->title_y, tile_index);
|
||||
self->title_x++;
|
||||
if (self->title_x >= self->title_bar->width_in_tiles) {
|
||||
self->title_y++;
|
||||
self->title_x %= self->title_bar->width_in_tiles;
|
||||
}
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// Always handle ASCII.
|
||||
if (c < 128) {
|
||||
if (c >= 0x20 && c <= 0x7e) {
|
||||
uint8_t tile_index = fontio_builtinfont_get_glyph_index(self->font, c);
|
||||
common_hal_displayio_tilegrid_set_tile(self->tilegrid, self->cursor_x, self->cursor_y, tile_index);
|
||||
common_hal_displayio_tilegrid_set_tile(self->scroll_area, self->cursor_x, self->cursor_y, tile_index);
|
||||
self->cursor_x++;
|
||||
} else if (c == '\r') {
|
||||
self->cursor_x = 0;
|
||||
@ -71,15 +98,7 @@ size_t common_hal_terminalio_terminal_write(terminalio_terminal_obj_t *self, con
|
||||
self->cursor_x--;
|
||||
}
|
||||
} else if (c == 0x1b) {
|
||||
if (i[0] == '[') {
|
||||
if (i[1] == 'K') {
|
||||
// Clear the rest of the line.
|
||||
for (uint16_t j = self->cursor_x; j < self->tilegrid->width_in_tiles; j++) {
|
||||
common_hal_displayio_tilegrid_set_tile(self->tilegrid, j, self->cursor_y, 0);
|
||||
}
|
||||
i += 2;
|
||||
} else {
|
||||
// Handle commands of the form \x1b[####D
|
||||
// Handle commands of the form \x1b.####D where . is ignored.
|
||||
uint16_t n = 0;
|
||||
uint8_t j = 1;
|
||||
for (; j < 6; j++) {
|
||||
@ -90,6 +109,14 @@ size_t common_hal_terminalio_terminal_write(terminalio_terminal_obj_t *self, con
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i[0] == '[') {
|
||||
if (i[1] == 'K') {
|
||||
// Clear the rest of the line.
|
||||
for (uint16_t k = self->cursor_x; k < self->scroll_area->width_in_tiles; k++) {
|
||||
common_hal_displayio_tilegrid_set_tile(self->scroll_area, k, self->cursor_y, 0);
|
||||
}
|
||||
i += 2;
|
||||
} else {
|
||||
if (c == 'D') {
|
||||
if (n > self->cursor_x) {
|
||||
self->cursor_x = 0;
|
||||
@ -99,14 +126,10 @@ size_t common_hal_terminalio_terminal_write(terminalio_terminal_obj_t *self, con
|
||||
}
|
||||
if (c == 'J') {
|
||||
if (n == 2) {
|
||||
common_hal_displayio_tilegrid_set_top_left(self->tilegrid, 0, 0);
|
||||
common_hal_displayio_tilegrid_set_top_left(self->scroll_area, 0, 0);
|
||||
self->cursor_x = self->cursor_y = start_y = 0;
|
||||
n = 0;
|
||||
for (uint16_t x = 0; x < self->tilegrid->width_in_tiles; x++) {
|
||||
for (uint16_t y = 0; y < self->tilegrid->height_in_tiles; y++) {
|
||||
common_hal_displayio_tilegrid_set_tile(self->tilegrid, x, y, 0);
|
||||
}
|
||||
}
|
||||
common_hal_displayio_tilegrid_set_all_tiles(self->scroll_area, 0);
|
||||
}
|
||||
}
|
||||
if (c == ';') {
|
||||
@ -126,13 +149,13 @@ size_t common_hal_terminalio_terminal_write(terminalio_terminal_obj_t *self, con
|
||||
if (m > 0) {
|
||||
m--;
|
||||
}
|
||||
if (n >= self->tilegrid->height_in_tiles) {
|
||||
n = self->tilegrid->height_in_tiles - 1;
|
||||
if (n >= self->scroll_area->height_in_tiles) {
|
||||
n = self->scroll_area->height_in_tiles - 1;
|
||||
}
|
||||
if (m >= self->tilegrid->width_in_tiles) {
|
||||
m = self->tilegrid->width_in_tiles - 1;
|
||||
if (m >= self->scroll_area->width_in_tiles) {
|
||||
m = self->scroll_area->width_in_tiles - 1;
|
||||
}
|
||||
n = (n + self->tilegrid->top_left_y) % self->tilegrid->height_in_tiles;
|
||||
n = (n + self->scroll_area->top_left_y) % self->scroll_area->height_in_tiles;
|
||||
self->cursor_x = m;
|
||||
self->cursor_y = n;
|
||||
start_y = self->cursor_y;
|
||||
@ -141,30 +164,34 @@ size_t common_hal_terminalio_terminal_write(terminalio_terminal_obj_t *self, con
|
||||
i += j + 1;
|
||||
continue;
|
||||
}
|
||||
} else if (i[0] == ']' && c == ';') {
|
||||
self->in_osc_command = true;
|
||||
self->osc_command = n;
|
||||
i += j + 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
uint8_t tile_index = fontio_builtinfont_get_glyph_index(self->font, c);
|
||||
if (tile_index != 0xff) {
|
||||
common_hal_displayio_tilegrid_set_tile(self->tilegrid, self->cursor_x, self->cursor_y, tile_index);
|
||||
common_hal_displayio_tilegrid_set_tile(self->scroll_area, self->cursor_x, self->cursor_y, tile_index);
|
||||
self->cursor_x++;
|
||||
|
||||
}
|
||||
}
|
||||
if (self->cursor_x >= self->tilegrid->width_in_tiles) {
|
||||
if (self->cursor_x >= self->scroll_area->width_in_tiles) {
|
||||
self->cursor_y++;
|
||||
self->cursor_x %= self->tilegrid->width_in_tiles;
|
||||
self->cursor_x %= self->scroll_area->width_in_tiles;
|
||||
}
|
||||
if (self->cursor_y >= self->tilegrid->height_in_tiles) {
|
||||
self->cursor_y %= self->tilegrid->height_in_tiles;
|
||||
if (self->cursor_y >= self->scroll_area->height_in_tiles) {
|
||||
self->cursor_y %= self->scroll_area->height_in_tiles;
|
||||
}
|
||||
if (self->cursor_y != start_y) {
|
||||
// clear the new row in case of scroll up
|
||||
if (self->cursor_y == self->tilegrid->top_left_y) {
|
||||
for (uint16_t j = 0; j < self->tilegrid->width_in_tiles; j++) {
|
||||
common_hal_displayio_tilegrid_set_tile(self->tilegrid, j, self->cursor_y, 0);
|
||||
if (self->cursor_y == self->scroll_area->top_left_y) {
|
||||
for (uint16_t j = 0; j < self->scroll_area->width_in_tiles; j++) {
|
||||
common_hal_displayio_tilegrid_set_tile(self->scroll_area, j, self->cursor_y, 0);
|
||||
}
|
||||
common_hal_displayio_tilegrid_set_top_left(self->tilegrid, 0, (self->cursor_y + self->tilegrid->height_in_tiles + 1) % self->tilegrid->height_in_tiles);
|
||||
common_hal_displayio_tilegrid_set_top_left(self->scroll_area, 0, (self->cursor_y + self->scroll_area->height_in_tiles + 1) % self->scroll_area->height_in_tiles);
|
||||
}
|
||||
start_y = self->cursor_y;
|
||||
}
|
||||
@ -173,5 +200,5 @@ size_t common_hal_terminalio_terminal_write(terminalio_terminal_obj_t *self, con
|
||||
}
|
||||
|
||||
bool common_hal_terminalio_terminal_ready_to_tx(terminalio_terminal_obj_t *self) {
|
||||
return self->tilegrid != NULL;
|
||||
return self->scroll_area != NULL;
|
||||
}
|
||||
|
@ -39,8 +39,13 @@ typedef struct {
|
||||
const fontio_builtinfont_t *font;
|
||||
uint16_t cursor_x;
|
||||
uint16_t cursor_y;
|
||||
displayio_tilegrid_t *tilegrid;
|
||||
displayio_tilegrid_t *scroll_area;
|
||||
displayio_tilegrid_t *title_bar;
|
||||
uint16_t title_x;
|
||||
uint16_t title_y;
|
||||
uint16_t first_row;
|
||||
uint16_t osc_command;
|
||||
bool in_osc_command;
|
||||
} terminalio_terminal_obj_t;
|
||||
|
||||
#endif /* SHARED_MODULE_TERMINALIO_TERMINAL_H */
|
||||
|
@ -111,16 +111,28 @@ void background_callback_end_critical_section() {
|
||||
CALLBACK_CRITICAL_END;
|
||||
}
|
||||
|
||||
|
||||
// Filter out queued callbacks if they are allocated on the heap.
|
||||
void background_callback_reset() {
|
||||
background_callback_t *new_head = NULL;
|
||||
background_callback_t **previous_next = &new_head;
|
||||
background_callback_t *new_tail = NULL;
|
||||
CALLBACK_CRITICAL_BEGIN;
|
||||
background_callback_t *cb = (background_callback_t *)callback_head;
|
||||
while (cb) {
|
||||
background_callback_t *next = cb->next;
|
||||
if (!HEAP_PTR((void *)cb)) {
|
||||
*previous_next = cb;
|
||||
previous_next = &cb->next;
|
||||
cb->next = NULL;
|
||||
new_tail = cb;
|
||||
} else {
|
||||
memset(cb, 0, sizeof(*cb));
|
||||
}
|
||||
cb = next;
|
||||
}
|
||||
callback_head = NULL;
|
||||
callback_tail = NULL;
|
||||
callback_head = new_head;
|
||||
callback_tail = new_tail;
|
||||
in_background_callback = false;
|
||||
CALLBACK_CRITICAL_END;
|
||||
}
|
||||
|
@ -61,37 +61,26 @@ void supervisor_start_terminal(uint16_t width_px, uint16_t height_px) {
|
||||
uint8_t scale = 2;
|
||||
|
||||
#if CIRCUITPY_TERMINALIO
|
||||
displayio_tilegrid_t *grid = &supervisor_terminal_text_grid;
|
||||
bool tall = height_px > width_px;
|
||||
displayio_tilegrid_t *scroll_area = &supervisor_terminal_scroll_area_text_grid;
|
||||
displayio_tilegrid_t *title_bar = &supervisor_terminal_title_bar_text_grid;
|
||||
bool reset_tiles = false;
|
||||
#if CIRCUITPY_REPL_LOGO
|
||||
uint16_t terminal_width_px = tall ? width_px : width_px - blinka_bitmap.width;
|
||||
uint16_t terminal_height_px = tall ? height_px - blinka_bitmap.height : height_px;
|
||||
#else
|
||||
uint16_t terminal_width_px = width_px;
|
||||
uint16_t terminal_height_px = height_px;
|
||||
#endif
|
||||
uint16_t width_in_tiles = terminal_width_px / grid->tile_width;
|
||||
uint16_t width_in_tiles = width_px / scroll_area->tile_width;
|
||||
// determine scale based on h
|
||||
if (width_in_tiles < 80) {
|
||||
scale = 1;
|
||||
}
|
||||
|
||||
width_in_tiles = terminal_width_px / (grid->tile_width * scale);
|
||||
width_in_tiles = width_px / (scroll_area->tile_width * scale);
|
||||
if (width_in_tiles < 1) {
|
||||
width_in_tiles = 1;
|
||||
}
|
||||
uint16_t height_in_tiles = terminal_height_px / (grid->tile_height * scale);
|
||||
uint16_t remaining_pixels = tall ? 0 : terminal_height_px % (grid->tile_height * scale);
|
||||
if (height_in_tiles < 1 || remaining_pixels > 0) {
|
||||
height_in_tiles += 1;
|
||||
}
|
||||
uint16_t height_in_tiles = height_px / (scroll_area->tile_height * scale);
|
||||
|
||||
uint16_t total_tiles = width_in_tiles * height_in_tiles;
|
||||
|
||||
// check if the terminal tile dimensions are the same
|
||||
if ((grid->width_in_tiles != width_in_tiles) ||
|
||||
(grid->height_in_tiles != height_in_tiles)) {
|
||||
if ((scroll_area->width_in_tiles != width_in_tiles) ||
|
||||
(scroll_area->height_in_tiles != height_in_tiles - 1)) {
|
||||
reset_tiles = true;
|
||||
}
|
||||
// Reuse the previous allocation if possible
|
||||
@ -114,27 +103,39 @@ void supervisor_start_terminal(uint16_t width_px, uint16_t height_px) {
|
||||
uint8_t *tiles = (uint8_t *)tilegrid_tiles->ptr;
|
||||
|
||||
#if CIRCUITPY_REPL_LOGO
|
||||
grid->y = tall ? blinka_bitmap.height : 0;
|
||||
grid->x = tall ? 0 : blinka_bitmap.width;
|
||||
title_bar->x = blinka_bitmap.width;
|
||||
// Align the title bar to the bottom of the logo.
|
||||
title_bar->y = blinka_bitmap.height - title_bar->tile_height;
|
||||
#else
|
||||
grid->y = 0;
|
||||
grid->x = 0;
|
||||
title_bar->x = 0;
|
||||
title_bar->y = 0;
|
||||
#endif
|
||||
grid->top_left_y = 0;
|
||||
if (remaining_pixels > 0) {
|
||||
grid->y -= (grid->tile_height - remaining_pixels);
|
||||
}
|
||||
grid->width_in_tiles = width_in_tiles;
|
||||
grid->height_in_tiles = height_in_tiles;
|
||||
title_bar->top_left_y = 0;
|
||||
title_bar->width_in_tiles = width_in_tiles;
|
||||
title_bar->height_in_tiles = 1;
|
||||
assert(width_in_tiles > 0);
|
||||
assert(height_in_tiles > 0);
|
||||
grid->pixel_width = width_in_tiles * grid->tile_width;
|
||||
grid->pixel_height = height_in_tiles * grid->tile_height;
|
||||
grid->tiles = tiles;
|
||||
title_bar->pixel_width = width_in_tiles * title_bar->tile_width;
|
||||
title_bar->pixel_height = title_bar->tile_height;
|
||||
title_bar->tiles = tiles;
|
||||
title_bar->full_change = true;
|
||||
|
||||
grid->full_change = true;
|
||||
scroll_area->x = 0;
|
||||
#if CIRCUITPY_REPL_LOGO
|
||||
scroll_area->y = blinka_bitmap.height;
|
||||
#else
|
||||
scroll_area->y = scroll_area->tile_height;
|
||||
#endif
|
||||
scroll_area->top_left_y = 0;
|
||||
scroll_area->width_in_tiles = width_in_tiles;
|
||||
scroll_area->height_in_tiles = height_in_tiles - 1;
|
||||
assert(width_in_tiles > 0);
|
||||
assert(height_in_tiles > 1);
|
||||
scroll_area->pixel_width = width_in_tiles * scroll_area->tile_width;
|
||||
scroll_area->pixel_height = (height_in_tiles - 1) * scroll_area->tile_height;
|
||||
scroll_area->tiles = tiles + width_in_tiles;
|
||||
scroll_area->full_change = true;
|
||||
|
||||
common_hal_terminalio_terminal_construct(&supervisor_terminal, grid, &supervisor_terminal_font);
|
||||
common_hal_terminalio_terminal_construct(&supervisor_terminal, scroll_area, &supervisor_terminal_font, title_bar);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -146,18 +147,24 @@ void supervisor_stop_terminal(void) {
|
||||
if (tilegrid_tiles != NULL) {
|
||||
free_memory(tilegrid_tiles);
|
||||
tilegrid_tiles = NULL;
|
||||
supervisor_terminal_text_grid.tiles = NULL;
|
||||
supervisor_terminal.tilegrid = NULL;
|
||||
supervisor_terminal_scroll_area_text_grid.tiles = NULL;
|
||||
supervisor_terminal_title_bar_text_grid.tiles = NULL;
|
||||
supervisor_terminal.scroll_area = NULL;
|
||||
supervisor_terminal.title_bar = NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void supervisor_display_move_memory(void) {
|
||||
#if CIRCUITPY_TERMINALIO
|
||||
displayio_tilegrid_t *scroll_area = &supervisor_terminal_scroll_area_text_grid;
|
||||
displayio_tilegrid_t *title_bar = &supervisor_terminal_title_bar_text_grid;
|
||||
if (tilegrid_tiles != NULL) {
|
||||
supervisor_terminal_text_grid.tiles = (uint8_t *)tilegrid_tiles->ptr;
|
||||
title_bar->tiles = (uint8_t *)tilegrid_tiles->ptr;
|
||||
scroll_area->tiles = (uint8_t *)tilegrid_tiles->ptr + scroll_area->width_in_tiles;
|
||||
} else {
|
||||
supervisor_terminal_text_grid.tiles = NULL;
|
||||
scroll_area->tiles = NULL;
|
||||
title_bar->tiles = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -298,21 +305,21 @@ displayio_tilegrid_t blinka_sprite = {
|
||||
|
||||
#if CIRCUITPY_TERMINALIO
|
||||
#if CIRCUITPY_REPL_LOGO
|
||||
mp_obj_t members[] = { &blinka_sprite, &supervisor_terminal_text_grid, };
|
||||
mp_obj_t members[] = { &blinka_sprite, &supervisor_terminal_title_bar_text_grid, &supervisor_terminal_scroll_area_text_grid, };
|
||||
mp_obj_list_t splash_children = {
|
||||
.base = {.type = &mp_type_list },
|
||||
.alloc = 3,
|
||||
.len = 3,
|
||||
.items = members,
|
||||
};
|
||||
#else
|
||||
mp_obj_t members[] = { &supervisor_terminal_title_bar_text_grid, &supervisor_terminal_scroll_area_text_grid, };
|
||||
mp_obj_list_t splash_children = {
|
||||
.base = {.type = &mp_type_list },
|
||||
.alloc = 2,
|
||||
.len = 2,
|
||||
.items = members,
|
||||
};
|
||||
#else
|
||||
mp_obj_t members[] = { &supervisor_terminal_text_grid, };
|
||||
mp_obj_list_t splash_children = {
|
||||
.base = {.type = &mp_type_list },
|
||||
.alloc = 1,
|
||||
.len = 1,
|
||||
.items = members,
|
||||
};
|
||||
#endif
|
||||
#else
|
||||
#if CIRCUITPY_REPL_LOGO
|
||||
|
@ -43,7 +43,8 @@ extern const fontio_builtinfont_t supervisor_terminal_font;
|
||||
|
||||
// These will change so they must live in RAM.
|
||||
extern displayio_bitmap_t supervisor_terminal_font_bitmap;
|
||||
extern displayio_tilegrid_t supervisor_terminal_text_grid;
|
||||
extern displayio_tilegrid_t supervisor_terminal_scroll_area_text_grid;
|
||||
extern displayio_tilegrid_t supervisor_terminal_title_bar_text_grid;
|
||||
extern terminalio_terminal_obj_t supervisor_terminal;
|
||||
|
||||
#endif
|
||||
|
@ -45,7 +45,7 @@ static
|
||||
#endif
|
||||
inline
|
||||
// gcc10 -flto has issues with this being always_inline for debug builds.
|
||||
#if CIRCUITPY_DEBUG < 1
|
||||
#if !CIRCUITPY_LTO || CIRCUITPY_DEBUG < 1
|
||||
__attribute__((always_inline))
|
||||
#endif
|
||||
const compressed_string_t *translate(const char *original) {
|
||||
|
99
supervisor/shared/web_workflow/web_workflow.c
Normal file
99
supervisor/shared/web_workflow/web_workflow.c
Normal file
@ -0,0 +1,99 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2022 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 <string.h>
|
||||
|
||||
#include "shared-bindings/wifi/Radio.h"
|
||||
#include "supervisor/shared/translate/translate.h"
|
||||
#include "supervisor/shared/web_workflow/web_workflow.h"
|
||||
|
||||
#if CIRCUITPY_WIFI
|
||||
#include "shared-bindings/wifi/__init__.h"
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_DOTENV
|
||||
#include "shared-module/dotenv/__init__.h"
|
||||
#endif
|
||||
|
||||
static wifi_radio_error_t wifi_status = WIFI_RADIO_ERROR_NONE;
|
||||
|
||||
void supervisor_web_workflow_status(void) {
|
||||
serial_write_compressed(translate("Wi-Fi: "));
|
||||
if (common_hal_wifi_radio_get_enabled(&common_hal_wifi_radio_obj)) {
|
||||
uint32_t ipv4_address = wifi_radio_get_ipv4_address(&common_hal_wifi_radio_obj);
|
||||
if (wifi_status == WIFI_RADIO_ERROR_AUTH_EXPIRE ||
|
||||
wifi_status == WIFI_RADIO_ERROR_AUTH_FAIL) {
|
||||
serial_write_compressed(translate("Authentication failure"));
|
||||
} else if (wifi_status != WIFI_RADIO_ERROR_NONE) {
|
||||
mp_printf(&mp_plat_print, "%d", wifi_status);
|
||||
} else if (ipv4_address == 0) {
|
||||
serial_write_compressed(translate("No IP"));
|
||||
} else {
|
||||
uint8_t *octets = (uint8_t *)&ipv4_address;
|
||||
mp_printf(&mp_plat_print, "%d.%d.%d.%d", octets[0], octets[1], octets[2], octets[3]);
|
||||
// TODO: Use these unicode to show signal strength: ▂▄▆█
|
||||
}
|
||||
} else {
|
||||
serial_write_compressed(translate("off"));
|
||||
}
|
||||
}
|
||||
|
||||
void supervisor_start_web_workflow(void) {
|
||||
#if CIRCUITPY_WEB_WORKFLOW && CIRCUITPY_WIFI
|
||||
char ssid[33];
|
||||
char password[64];
|
||||
mp_int_t ssid_len = 0;
|
||||
mp_int_t password_len = 0;
|
||||
|
||||
#if CIRCUITPY_DOTENV
|
||||
ssid_len = dotenv_get_key("/.env", "CIRCUITPY_WIFI_SSID", ssid, sizeof(ssid) - 1);
|
||||
password_len = dotenv_get_key("/.env", "CIRCUITPY_WIFI_PASSWORD", password, sizeof(password) - 1);
|
||||
#endif
|
||||
if (ssid_len <= 0 || (size_t)ssid_len >= sizeof(ssid) ||
|
||||
password_len <= 0 || (size_t)password_len >= sizeof(password)) {
|
||||
return;
|
||||
}
|
||||
common_hal_wifi_init(false);
|
||||
common_hal_wifi_radio_set_enabled(&common_hal_wifi_radio_obj, true);
|
||||
|
||||
// TODO: Do our own scan so that we can find the channel we want before calling connect.
|
||||
// Otherwise, connect will do a full slow scan to pick the best AP.
|
||||
|
||||
// NUL terminate the strings because dotenv doesn't.
|
||||
ssid[ssid_len] = '\0';
|
||||
password[password_len] = '\0';
|
||||
wifi_status = common_hal_wifi_radio_connect(
|
||||
&common_hal_wifi_radio_obj, (uint8_t *)ssid, ssid_len, (uint8_t *)password, password_len,
|
||||
0, 0.1, NULL, 0);
|
||||
|
||||
if (wifi_status != WIFI_RADIO_ERROR_NONE) {
|
||||
common_hal_wifi_radio_set_enabled(&common_hal_wifi_radio_obj, false);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void supervisor_stop_web_workflow(void) {
|
||||
}
|
35
supervisor/shared/web_workflow/web_workflow.h
Normal file
35
supervisor/shared/web_workflow/web_workflow.h
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2022 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
void supervisor_wifi_background(void);
|
||||
void supervisor_wifi_init(void);
|
||||
void supervisor_web_workflow_status(void);
|
||||
void supervisor_start_web_workflow(void);
|
||||
void supervisor_stop_web_workflow(void);
|
@ -26,14 +26,61 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "py/mpconfig.h"
|
||||
#include "supervisor/background_callback.h"
|
||||
#include "supervisor/workflow.h"
|
||||
#include "supervisor/serial.h"
|
||||
#include "supervisor/shared/workflow.h"
|
||||
|
||||
#if CIRCUITPY_BLEIO
|
||||
#include "shared-bindings/_bleio/__init__.h"
|
||||
#include "supervisor/shared/bluetooth/bluetooth.h"
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_USB
|
||||
#include "supervisor/usb.h"
|
||||
#include "tusb.h"
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_WEB_WORKFLOW
|
||||
#include "supervisor/shared/web_workflow/web_workflow.h"
|
||||
#endif
|
||||
static background_callback_t workflow_background_cb;
|
||||
|
||||
static void supervisor_workflow_update_status_bar(void) {
|
||||
// Neighboring "" "" are concatenated by the compiler. Without this separation, the hex code
|
||||
// doesn't get terminated after two following characters and the value is invalid.
|
||||
// This is the OSC command to set the title and the icon text. It can be up to 255 characters
|
||||
// but some may be cut off.
|
||||
serial_write("\x1b" "]0;");
|
||||
serial_write("🐍 ");
|
||||
#if CIRCUITPY_WEB_WORKFLOW
|
||||
supervisor_web_workflow_status();
|
||||
#endif
|
||||
// Send string terminator
|
||||
serial_write("\x1b" "\\");
|
||||
}
|
||||
|
||||
static void workflow_background(void *data) {
|
||||
supervisor_workflow_update_status_bar();
|
||||
}
|
||||
|
||||
// Called during a VM reset. Doesn't actually reset things.
|
||||
void supervisor_workflow_reset(void) {
|
||||
#if CIRCUITPY_BLEIO
|
||||
supervisor_start_bluetooth();
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_WEB_WORKFLOW
|
||||
supervisor_start_web_workflow();
|
||||
#endif
|
||||
|
||||
workflow_background_cb.fun = workflow_background;
|
||||
workflow_background_cb.data = NULL;
|
||||
supervisor_workflow_request_background();
|
||||
}
|
||||
|
||||
void supervisor_workflow_request_background(void) {
|
||||
background_callback_add_core(&workflow_background_cb);
|
||||
}
|
||||
|
||||
// Return true as soon as USB communication with host has started,
|
||||
@ -58,3 +105,25 @@ bool supervisor_workflow_active(void) {
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void supervisor_workflow_start(void) {
|
||||
// Start USB after giving boot.py a chance to tweak behavior.
|
||||
#if CIRCUITPY_USB
|
||||
// Setup USB connection after heap is available.
|
||||
// It needs the heap to build descriptors.
|
||||
usb_init();
|
||||
#endif
|
||||
|
||||
// Set up any other serial connection.
|
||||
serial_init();
|
||||
|
||||
#if CIRCUITPY_BLEIO
|
||||
bleio_reset();
|
||||
supervisor_bluetooth_enable_workflow();
|
||||
supervisor_start_bluetooth();
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_WEB_WORKFLOW
|
||||
supervisor_start_web_workflow();
|
||||
#endif
|
||||
}
|
||||
|
@ -146,6 +146,10 @@ ifeq ($(CIRCUITPY_USB),1)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(CIRCUITPY_WEB_WORKFLOW),1)
|
||||
SRC_SUPERVISOR += supervisor/shared/web_workflow/web_workflow.c
|
||||
endif
|
||||
|
||||
SRC_TINYUSB = $(filter lib/tinyusb/%.c, $(SRC_SUPERVISOR))
|
||||
$(patsubst %.c,$(BUILD)/%.o,$(SRC_TINYUSB)): CFLAGS += -Wno-missing-prototypes
|
||||
|
||||
|
@ -30,3 +30,7 @@ void supervisor_workflow_reset(void);
|
||||
|
||||
// True when the user could be actively iterating on their code.
|
||||
bool supervisor_workflow_active(void);
|
||||
|
||||
void supervisor_workflow_request_background(void);
|
||||
|
||||
void supervisor_workflow_start(void);
|
||||
|
@ -75,8 +75,7 @@ for c in set(all_characters):
|
||||
if missing > 0:
|
||||
print("Font missing", missing, "characters", file=sys.stderr)
|
||||
|
||||
x, y, dx, dy = f.get_bounding_box()
|
||||
tile_x, tile_y = x - dx, y - dy
|
||||
tile_x, tile_y, dx, dy = f.get_bounding_box()
|
||||
total_bits = tile_x * len(all_characters)
|
||||
total_bits += 32 - total_bits % 32
|
||||
bytes_per_row = total_bits // 8
|
||||
@ -139,11 +138,41 @@ displayio_palette_t supervisor_terminal_color = {
|
||||
|
||||
c_file.write(
|
||||
"""\
|
||||
displayio_tilegrid_t supervisor_terminal_text_grid = {{
|
||||
displayio_tilegrid_t supervisor_terminal_scroll_area_text_grid = {{
|
||||
.base = {{ .type = &displayio_tilegrid_type }},
|
||||
.bitmap = (displayio_bitmap_t*) &supervisor_terminal_font_bitmap,
|
||||
.pixel_shader = &supervisor_terminal_color,
|
||||
.x = 16,
|
||||
.x = 0,
|
||||
.y = 0,
|
||||
.pixel_width = {1},
|
||||
.pixel_height = {2},
|
||||
.bitmap_width_in_tiles = {0},
|
||||
.tiles_in_bitmap = {0},
|
||||
.width_in_tiles = 1,
|
||||
.height_in_tiles = 1,
|
||||
.tile_width = {1},
|
||||
.tile_height = {2},
|
||||
.tiles = NULL,
|
||||
.partial_change = false,
|
||||
.full_change = false,
|
||||
.hidden = false,
|
||||
.hidden_by_parent = false,
|
||||
.moved = false,
|
||||
.inline_tiles = false,
|
||||
.in_group = true
|
||||
}};
|
||||
""".format(
|
||||
len(all_characters), tile_x, tile_y
|
||||
)
|
||||
)
|
||||
|
||||
c_file.write(
|
||||
"""\
|
||||
displayio_tilegrid_t supervisor_terminal_title_bar_text_grid = {{
|
||||
.base = {{ .type = &displayio_tilegrid_type }},
|
||||
.bitmap = (displayio_bitmap_t*) &supervisor_terminal_font_bitmap,
|
||||
.pixel_shader = &supervisor_terminal_color,
|
||||
.x = 0,
|
||||
.y = 0,
|
||||
.pixel_width = {1},
|
||||
.pixel_height = {2},
|
||||
@ -228,7 +257,8 @@ terminalio_terminal_obj_t supervisor_terminal = {
|
||||
.font = &supervisor_terminal_font,
|
||||
.cursor_x = 0,
|
||||
.cursor_y = 0,
|
||||
.tilegrid = NULL
|
||||
.scroll_area = NULL,
|
||||
.title_bar = NULL
|
||||
};
|
||||
"""
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user