diff options
Diffstat (limited to 'movement')
-rw-r--r-- | movement/filesystem.c | 121 | ||||
-rw-r--r-- | movement/filesystem.h | 9 | ||||
-rw-r--r-- | movement/make/Makefile | 2 | ||||
-rw-r--r-- | movement/movement.c | 26 | ||||
-rw-r--r-- | movement/shell.c | 220 | ||||
-rw-r--r-- | movement/shell.h | 34 | ||||
-rw-r--r-- | movement/shell_cmd_list.c | 159 | ||||
-rw-r--r-- | movement/shell_cmd_list.h | 38 | ||||
-rw-r--r-- | movement/watch_faces/complication/randonaut_face.c | 2 | ||||
-rw-r--r-- | movement/watch_faces/complication/sunrise_sunset_face.c | 2 | ||||
-rw-r--r-- | movement/watch_faces/complication/toss_up_face.c | 3 |
11 files changed, 527 insertions, 89 deletions
diff --git a/movement/filesystem.c b/movement/filesystem.c index 97e35455..9df0a8d2 100644 --- a/movement/filesystem.c +++ b/movement/filesystem.c @@ -100,7 +100,7 @@ static int filesystem_ls(lfs_t *lfs, const char *path) { printf("%4ld bytes ", info.size); - printf("%s\n", info.name); + printf("%s\r\n", info.name); } err = lfs_dir_close(lfs, &dir); @@ -117,11 +117,11 @@ bool filesystem_init(void) { // reformat if we can't mount the filesystem // this should only happen on the first boot if (err < 0) { - printf("Ignore that error! Formatting filesystem...\n"); + printf("Ignore that error! Formatting filesystem...\r\n"); err = lfs_format(&lfs, &cfg); if (err < 0) return false; err = lfs_mount(&lfs, &cfg) == LFS_ERR_OK; - printf("Filesystem mounted with %ld bytes free.\n", filesystem_get_free_space()); + printf("Filesystem mounted with %ld bytes free.\r\n", filesystem_get_free_space()); } return err == LFS_ERR_OK; @@ -139,7 +139,7 @@ bool filesystem_rm(char *filename) { if (filesystem_file_exists(filename)) { return lfs_remove(&lfs, filename) == LFS_ERR_OK; } else { - printf("rm: %s: No such file\n", filename); + printf("rm: %s: No such file\r\n", filename); return false; } } @@ -197,13 +197,13 @@ static void filesystem_cat(char *filename) { char *buf = malloc(info.size + 1); filesystem_read_file(filename, buf, info.size); buf[info.size] = '\0'; - printf("%s\n", buf); + printf("%s\r\n", buf); free(buf); } else { - printf("\n"); + printf("\r\n"); } } else { - printf("cat: %s: No such file\n", filename); + printf("cat: %s: No such file\r\n", filename); } } @@ -223,59 +223,60 @@ bool filesystem_append_file(char *filename, char *text, int32_t length) { return lfs_file_close(&lfs, &file) == LFS_ERR_OK; } -void filesystem_process_command(char *line) { - printf("$ %s", line); - char *command = strtok(line, " \n"); - - if (strcmp(command, "ls") == 0) { - char *directory = strtok(NULL, " \n"); - if (directory == NULL) { - filesystem_ls(&lfs, "/"); - } else { - printf("usage: ls\n"); - } - } else if (strcmp(command, "cat") == 0) { - char *filename = strtok(NULL, " \n"); - if (filename == NULL) { - printf("usage: cat file\n"); - } else { - filesystem_cat(filename); - } - } else if (strcmp(command, "df") == 0) { - printf("free space: %ld bytes\n", filesystem_get_free_space()); - } else if (strcmp(command, "rm") == 0) { - char *filename = strtok(NULL, " \n"); - if (filename == NULL) { - printf("usage: rm file\n"); - } else { - filesystem_rm(filename); - } - } else if (strcmp(command, "echo") == 0) { - char *text = malloc(248); - memset(text, 0, 248); - size_t pos = 0; - char *word = strtok(NULL, " \n"); - while (strcmp(word, ">") && strcmp(word, ">>")) { - sprintf(text + pos, "%s ", word); - pos += strlen(word) + 1; - word = strtok(NULL, " \n"); - if (word == NULL) break; - } - text[strlen(text) - 1] = 0; - char *filename = strtok(NULL, " \n"); - if (filename == NULL) { - printf("usage: echo text > file\n"); - } else if (strchr(filename, '/') || strchr(filename, '\\')) { - printf("subdirectories are not supported\n"); - } else if (!strcmp(word, ">")) { - filesystem_write_file(filename, text, strlen(text)); - filesystem_append_file(filename, "\n", 1); - } else if (!strcmp(word, ">>")) { - filesystem_append_file(filename, text, strlen(text)); - filesystem_append_file(filename, "\n", 1); - } - free(text); +int filesystem_cmd_ls(int argc, char *argv[]) { + if (argc >= 2) { + filesystem_ls(&lfs, argv[1]); } else { - printf("%s: command not found\n", command); + filesystem_ls(&lfs, "/"); } + return 0; } + +int filesystem_cmd_cat(int argc, char *argv[]) { + (void) argc; + filesystem_cat(argv[1]); + return 0; +} + +int filesystem_cmd_df(int argc, char *argv[]) { + (void) argc; + (void) argv; + printf("free space: %ld bytes\r\n", filesystem_get_free_space()); + return 0; +} + +int filesystem_cmd_rm(int argc, char *argv[]) { + (void) argc; + filesystem_rm(argv[1]); + return 0; +} + +int filesystem_cmd_echo(int argc, char *argv[]) { + (void) argc; + + char *line = argv[1]; + size_t line_len = strlen(line); + if (line[0] == '"' || line[0] == '\'') { + line++; + line_len -= 2; + line[line_len] = '\0'; + } + + if (strchr(argv[3], '/')) { + printf("subdirectories are not supported\r\n"); + return -2; + } + + if (!strcmp(argv[2], ">")) { + filesystem_write_file(argv[3], line, line_len); + filesystem_append_file(argv[3], "\n", 1); + } else if (!strcmp(argv[2], ">>")) { + filesystem_append_file(argv[3], line, line_len); + filesystem_append_file(argv[3], "\n", 1); + } else { + return -2; + } + + return 0; +} + diff --git a/movement/filesystem.h b/movement/filesystem.h index 3cd3d092..fa3d9d1a 100644 --- a/movement/filesystem.h +++ b/movement/filesystem.h @@ -96,9 +96,10 @@ bool filesystem_write_file(char *filename, char *text, int32_t length); */ bool filesystem_append_file(char *filename, char *text, int32_t length); -/** @brief Handles the interactive file browser when Movement is plugged in to USB. - * @param line The command that the user typed into the serial console. - */ -void filesystem_process_command(char *line); +int filesystem_cmd_ls(int argc, char *argv[]); +int filesystem_cmd_cat(int argc, char *argv[]); +int filesystem_cmd_df(int argc, char *argv[]); +int filesystem_cmd_rm(int argc, char *argv[]); +int filesystem_cmd_echo(int argc, char *argv[]); #endif // FILESYSTEM_H_ diff --git a/movement/make/Makefile b/movement/make/Makefile index 42dfc644..faeaa6b8 100644 --- a/movement/make/Makefile +++ b/movement/make/Makefile @@ -49,6 +49,8 @@ SRCS += \ ../../littlefs/lfs_util.c \ ../movement.c \ ../filesystem.c \ + ../shell.c \ + ../shell_cmd_list.c \ ../watch_faces/clock/simple_clock_face.c \ ../watch_faces/clock/world_clock_face.c \ ../watch_faces/clock/beats_face.c \ diff --git a/movement/movement.c b/movement/movement.c index 50f5f0fe..816624d4 100644 --- a/movement/movement.c +++ b/movement/movement.c @@ -33,6 +33,7 @@ #include "watch.h" #include "filesystem.h" #include "movement.h" +#include "shell.h" #ifndef MOVEMENT_FIRMWARE #include "movement_config.h" @@ -588,30 +589,9 @@ bool app_loop(void) { } } - // if we are plugged into USB, handle the file browser tasks + // if we are plugged into USB, handle the serial shell if (watch_is_usb_enabled()) { - char line[256] = {0}; -#if __EMSCRIPTEN__ - // This is a terrible hack; ideally this should be handled deeper in the watch library. - // Alas, emscripten treats read() as something that should pop up an input box, so I - // wasn't able to implement this over there. I sense that this relates to read() being - // the wrong way to read data from USB (like we should be using fgets or something), but - // until I untangle that, this will have to do. - char *received_data = (char*)EM_ASM_INT({ - var len = lengthBytesUTF8(tx) + 1; - var s = _malloc(len); - stringToUTF8(tx, s, len); - return s; - }); - memcpy(line, received_data, min(255, strlen(received_data))); - free(received_data); - EM_ASM({ - tx = ""; - }); -#else - read(0, line, 256); -#endif - if (strlen(line)) filesystem_process_command(line); + shell_task(); } event.subsecond = 0; diff --git a/movement/shell.c b/movement/shell.c new file mode 100644 index 00000000..8f146e59 --- /dev/null +++ b/movement/shell.c @@ -0,0 +1,220 @@ +/* + * MIT License + * + * Copyright (c) 2023 Edward Shin + * + * 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 "shell.h" + +#include <ctype.h> +#include <stdbool.h> +#include <stddef.h> +#include <stdint.h> +#include <stdio.h> +#include <string.h> + +#if __EMSCRIPTEN__ +#include <emscripten.h> +#endif + +#include "watch.h" +#include "shell_cmd_list.h" + +extern shell_command_t g_shell_commands[]; +extern const size_t g_num_shell_commands; + +#define NEWLINE "\r\n" + +#define SHELL_BUF_SZ (256) +#define SHELL_MAX_ARGS (16) +#define SHELL_PROMPT "swsh> " + +static char s_buf[SHELL_BUF_SZ] = {0}; +static size_t s_buf_len = 0; +// Pointer to the first invalid byte after the end of input. +static char *const s_buf_end = s_buf + SHELL_BUF_SZ; + +static char *prv_skip_whitespace(char *c) { + while (c >= s_buf && c < s_buf_end) { + if (*c == 0) { + return NULL; + } + if (!isspace((int) *c) != 0) { + return c; + } + c++; + } + return NULL; +} + +static char *prv_skip_non_whitespace(char *c) { + bool in_quote = false; + char quote_char; + while (c >= s_buf && c < s_buf_end) { + if (*c == 0) { + return NULL; + } + // Basic handling of quoted arguments. + // Can't handle recursive quotes. :( + if (in_quote || *c == '"' || *c == '\'') { + if (!in_quote) { + quote_char = *c; + in_quote = true; + } else if (*c == quote_char) { + in_quote = false; + } + } else { + if (isspace((int) *c) != 0) { + return c; + } + } + c++; + } + return NULL; +} + +static int prv_handle_command() { + char *argv[SHELL_MAX_ARGS] = {0}; + int argc = 0; + + char *c = &s_buf[0]; + s_buf[SHELL_BUF_SZ - 1] = '\0'; + + while (argc < SHELL_MAX_ARGS) { + // Skip contiguous whitespace + c = prv_skip_whitespace(c); + if (c == NULL) { + // Reached end of buffer + break; + } + + // We hit non-whitespace, set argv and argc for this upcoming argument + argv[argc++] = c; + + // Skip contiguous non-whitespace + c = prv_skip_non_whitespace(c); + if (c == NULL) { + // Reached end of buffer + break; + } + + // NULL-terminate this arg string and then increment. + *(c++) = '\0'; + } + + if (argc == 0) { + return -1; + } + + // Match against the command list + for (size_t i = 0; i < g_num_shell_commands; i++) { + if (!strcasecmp(g_shell_commands[i].name, argv[0])) { + // If argc isn't valid for this command, display its help instead. + if (((argc - 1) < g_shell_commands[i].min_args) || + ((argc - 1) > g_shell_commands[i].max_args)) { + if (g_shell_commands[i].help != NULL) { + printf(NEWLINE "%s" NEWLINE, g_shell_commands[i].help); + } + return -2; + } + // Call the command's callback + if (g_shell_commands[i].cb != NULL) { + printf(NEWLINE); + int ret = g_shell_commands[i].cb(argc, argv); + if (ret == -2) { + printf(NEWLINE "%s" NEWLINE, g_shell_commands[i].help); + } + return ret; + } + } + } + + return -1; +} + +void shell_task(void) { +#if __EMSCRIPTEN__ + // This is a terrible hack; ideally this should be handled deeper in the watch library. + // Alas, emscripten treats read() as something that should pop up an input box, so I + // wasn't able to implement this over there. I sense that this relates to read() being + // the wrong way to read data from USB (like we should be using fgets or something), but + // until I untangle that, this will have to do. + char *received_data = (char*)EM_ASM_INT({ + var len = lengthBytesUTF8(tx) + 1; + var s = _malloc(len); + stringToUTF8(tx, s, len); + return s; + }); + s_buf_len = min((SHELL_BUF_SZ - 2), strlen(received_data)); + memcpy(s_buf, received_data, s_buf_len); + free(received_data); + s_buf[s_buf_len++] = '\n'; + s_buf[s_buf_len++] = '\0'; + prv_handle_command(); + EM_ASM({ + tx = ""; + }); +#else + // Read one character at a time until we run out. + while (true) { + if (s_buf_len >= (SHELL_BUF_SZ - 1)) { + printf(NEWLINE "Command too long, clearing."); + printf(NEWLINE SHELL_PROMPT); + s_buf_len = 0; + break; + } + + int c = getchar(); + + if (c < 0) { + // Nothing left to read, we're done. + break; + } + + if (c == '\b') { + // Handle backspace character. + // We need to emit a backspace, overwrite the character on the + // screen with a space, and then backspace again to move the cursor. + if (s_buf_len > 0) { + printf("\b \b"); + s_buf_len--; + } + continue; + } else if (c != '\n' && c != '\r') { + // Print regular characters to the screen. + putchar(c); + } + + s_buf[s_buf_len] = c; + + if (c == '\n' || c == '\r') { + // Newline! Handle the command. + s_buf[s_buf_len+1] = '\0'; + (void) prv_handle_command(); + s_buf_len = 0; + printf(NEWLINE SHELL_PROMPT); + break; + } else { + s_buf_len++; + } + } +#endif +} diff --git a/movement/shell.h b/movement/shell.h new file mode 100644 index 00000000..27dbf672 --- /dev/null +++ b/movement/shell.h @@ -0,0 +1,34 @@ +/* + * MIT License + * + * Copyright (c) 2023 Edward Shin + * + * 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 SHELL_H_ +#define SHELL_H_ + +/** @brief Called periodically from the app loop to handle shell commands. + * When a full command is complete, parses and executes its matching + * callback. + */ +void shell_task(void); + +#endif diff --git a/movement/shell_cmd_list.c b/movement/shell_cmd_list.c new file mode 100644 index 00000000..0ea08a56 --- /dev/null +++ b/movement/shell_cmd_list.c @@ -0,0 +1,159 @@ +/* + * MIT License + * + * Copyright (c) 2023 Edward Shin + * + * 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 "shell_cmd_list.h" + +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> + +#include "filesystem.h" +#include "watch.h" + +static int help_cmd(int argc, char *argv[]); +static int flash_cmd(int argc, char *argv[]); +static int stress_cmd(int argc, char *argv[]); + +shell_command_t g_shell_commands[] = { + { + .name = "?", + .help = "print command list", + .min_args = 0, + .max_args = 0, + .cb = help_cmd, + }, + { + .name = "help", + .help = "print command list", + .min_args = 0, + .max_args = 0, + .cb = help_cmd, + }, + { + .name = "flash", + .help = "reboot to UF2 bootloader", + .min_args = 0, + .max_args = 0, + .cb = flash_cmd, + }, + { + .name = "ls", + .help = "usage: ls [PATH]", + .min_args = 0, + .max_args = 1, + .cb = filesystem_cmd_ls, + }, + { + .name = "cat", + .help = "usage: cat <PATH>", + .min_args = 1, + .max_args = 1, + .cb = filesystem_cmd_cat, + }, + { + .name = "df", + .help = "print filesystem free space", + .min_args = 0, + .max_args = 0, + .cb = filesystem_cmd_df, + }, + { + .name = "rm", + .help = "usage: rm [PATH]", + .min_args = 1, + .max_args = 1, + .cb = filesystem_cmd_rm, + }, + { + .name = "echo", + .help = "usage: echo TEXT {>,>>} FILE", + .min_args = 3, + .max_args = 3, + .cb = filesystem_cmd_echo, + }, + { + .name = "stress", + .help = "test CDC write; usage: stress [LEN] [DELAY_MS]", + .min_args = 0, + .max_args = 2, + .cb = stress_cmd, + }, +}; + +const size_t g_num_shell_commands = sizeof(g_shell_commands) / sizeof(shell_command_t); + +static int help_cmd(int argc, char *argv[]) { + (void) argc; + (void) argv; + + printf("Command List:\r\n"); + for (size_t i = 0; i < g_num_shell_commands; i++) { + printf(" %s\t%s\r\n", + g_shell_commands[i].name, + (g_shell_commands[i].help) ? g_shell_commands[i].help : "" + ); + } + + return 0; +} + +static int flash_cmd(int argc, char *argv[]) { + (void) argc; + (void) argv; + + watch_reset_to_bootloader(); + return 0; +} + +#define STRESS_CMD_MAX_LEN (512) +static int stress_cmd(int argc, char *argv[]) { + char test_str[STRESS_CMD_MAX_LEN+1] = {0}; + + int max_len = 512; + int delay = 0; + + if (argc >= 2) { + if ((max_len = atoi(argv[1])) == 0) { + return -1; + } + if (max_len > 512) { + return -1; + } + } + + if (argc >= 3) { + delay = atoi(argv[2]); + } + + for (int i = 0; i < max_len; i++) { + snprintf(&test_str[i], 2, "%u", (i+1)%10); + printf("%u:\t%s\r\n", (i+1), test_str); + if (delay > 0) { + delay_ms(delay); + } + } + + return 0; +} + diff --git a/movement/shell_cmd_list.h b/movement/shell_cmd_list.h new file mode 100644 index 00000000..89031a54 --- /dev/null +++ b/movement/shell_cmd_list.h @@ -0,0 +1,38 @@ +/* + * MIT License + * + * Copyright (c) 2023 Edward Shin + * + * 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 SHELL_CMD_LIST_H_ +#define SHELL_CMD_LIST_H_ + +#include <stdint.h> + +typedef struct { + const char *name; // Name used to invoke the command + const char *help; // Help string + int8_t min_args; // Minimum number of arguments (_excluding_ the command name) + int8_t max_args; // Maximum number of arguments (_excluding_ the command name) + int (*cb)(int argc, char *argv[]); // Callback for the command +} shell_command_t; + +#endif diff --git a/movement/watch_faces/complication/randonaut_face.c b/movement/watch_faces/complication/randonaut_face.c index bca334fb..3bbc147f 100644 --- a/movement/watch_faces/complication/randonaut_face.c +++ b/movement/watch_faces/complication/randonaut_face.c @@ -357,7 +357,7 @@ static uint32_t _get_true_entropy(void) { while (!hri_trng_get_INTFLAG_reg(TRNG, TRNG_INTFLAG_DATARDY)); // Wait for TRNG data to be ready - hri_trng_clear_CTRLA_ENABLE_bit(TRNG); + watch_disable_TRNG(); hri_mclk_clear_APBCMASK_TRNG_bit(MCLK); return hri_trng_read_DATA_reg(TRNG); // Read a single 32-bit word from TRNG and return it #endif diff --git a/movement/watch_faces/complication/sunrise_sunset_face.c b/movement/watch_faces/complication/sunrise_sunset_face.c index 82de9c6e..7330c42c 100644 --- a/movement/watch_faces/complication/sunrise_sunset_face.c +++ b/movement/watch_faces/complication/sunrise_sunset_face.c @@ -197,6 +197,8 @@ static void _sunrise_sunset_face_update_settings_display(movement_event_t event, char buf[12]; switch (state->page) { + case 0: + return; case 1: sprintf(buf, "LA %c %04d", state->working_latitude.sign ? '-' : '+', abs(_sunrise_sunset_face_latlon_from_struct(state->working_latitude))); break; diff --git a/movement/watch_faces/complication/toss_up_face.c b/movement/watch_faces/complication/toss_up_face.c index 08dd0052..cf6ca680 100644 --- a/movement/watch_faces/complication/toss_up_face.c +++ b/movement/watch_faces/complication/toss_up_face.c @@ -255,7 +255,8 @@ uint32_t get_true_entropy(void) { while (!hri_trng_get_INTFLAG_reg(TRNG, TRNG_INTFLAG_DATARDY)); // Wait for TRNG data to be ready - hri_trng_clear_CTRLA_ENABLE_bit(TRNG); + watch_disable_TRNG(); + hri_mclk_clear_APBCMASK_TRNG_bit(MCLK); return hri_trng_read_DATA_reg(TRNG); // Read a single 32-bit word from TRNG and return it #endif |