sync
This commit is contained in:
@@ -3,7 +3,7 @@ import argparse
|
|||||||
import sys
|
import sys
|
||||||
from core.config import load_config
|
from core.config import load_config
|
||||||
from core.connection import BuzzerConnection, BuzzerError
|
from core.connection import BuzzerConnection, BuzzerError
|
||||||
from core.commands import info, ls, put, mkdir, rm, confirm, reboot
|
from core.commands import info, ls, put, mkdir, rm, confirm, reboot, play
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
parser = argparse.ArgumentParser(description="Edis Buzzer Host Tool")
|
parser = argparse.ArgumentParser(description="Edis Buzzer Host Tool")
|
||||||
@@ -38,10 +38,16 @@ def main():
|
|||||||
rm_parser.add_argument("path", type=str, help="Pfad der zu löschenden Datei/Ordner")
|
rm_parser.add_argument("path", type=str, help="Pfad der zu löschenden Datei/Ordner")
|
||||||
rm_parser.add_argument("-r", "--recursive", action="store_true", help="Ordnerinhalte rekursiv löschen")
|
rm_parser.add_argument("-r", "--recursive", action="store_true", help="Ordnerinhalte rekursiv löschen")
|
||||||
|
|
||||||
|
# Befehl: play
|
||||||
|
play_parser = subparsers.add_parser("play", help="Spielt eine Datei auf dem Controller ab")
|
||||||
|
play_parser.add_argument("path", type=str, help="Pfad der abzuspielenden Datei (z.B. /lfs/a/neu)")
|
||||||
|
|
||||||
# Befehl: confirm
|
# Befehl: confirm
|
||||||
confirm_parser = subparsers.add_parser("confirm", help="Bestätigt die aktuell laufende Firmware")
|
confirm_parser = subparsers.add_parser("confirm", help="Bestätigt die aktuell laufende Firmware")
|
||||||
|
|
||||||
|
# Befehl: reboot
|
||||||
reboot_parser = subparsers.add_parser("reboot", help="Startet den Buzzer neu")
|
reboot_parser = subparsers.add_parser("reboot", help="Startet den Buzzer neu")
|
||||||
|
|
||||||
# Argumente parsen
|
# Argumente parsen
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
config = load_config(args)
|
config = load_config(args)
|
||||||
@@ -87,6 +93,8 @@ def main():
|
|||||||
confirm.execute(conn)
|
confirm.execute(conn)
|
||||||
elif args.command == "reboot":
|
elif args.command == "reboot":
|
||||||
reboot.execute(conn)
|
reboot.execute(conn)
|
||||||
|
elif args.command == "play":
|
||||||
|
play.execute(conn, path=args.path)
|
||||||
elif args.command == "info" or args.command is None:
|
elif args.command == "info" or args.command is None:
|
||||||
# Wurde kein Befehl oder explizit 'info' angegeben, sind wir hier schon fertig
|
# Wurde kein Befehl oder explizit 'info' angegeben, sind wir hier schon fertig
|
||||||
pass
|
pass
|
||||||
|
|||||||
10
buzzer_tool/core/commands/play.py
Normal file
10
buzzer_tool/core/commands/play.py
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
# core/commands/mkdir.py
|
||||||
|
from core.connection import BuzzerError
|
||||||
|
|
||||||
|
def execute(conn, path: str):
|
||||||
|
"""Spielt eine Datei auf dem Controller ab."""
|
||||||
|
try:
|
||||||
|
conn.send_command(f"play {path}")
|
||||||
|
print(f"▶️ Datei '{path}' wird abgespielt.")
|
||||||
|
except BuzzerError as e:
|
||||||
|
print(f"❌ Fehler beim Abspielen von '{path}': {e}")
|
||||||
@@ -10,6 +10,7 @@ target_sources(app PRIVATE
|
|||||||
src/audio.c
|
src/audio.c
|
||||||
src/usb.c
|
src/usb.c
|
||||||
src/protocol.c
|
src/protocol.c
|
||||||
|
src/utils.c
|
||||||
)
|
)
|
||||||
zephyr_include_directories(src)
|
zephyr_include_directories(src)
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
VERSION_MAJOR = 0
|
VERSION_MAJOR = 0
|
||||||
VERSION_MINOR = 1
|
VERSION_MINOR = 1
|
||||||
PATCHLEVEL = 8
|
PATCHLEVEL = 11
|
||||||
VERSION_TWEAK = 0
|
VERSION_TWEAK = 0
|
||||||
EXTRAVERSION = 0
|
EXTRAVERSION = 0
|
||||||
@@ -38,7 +38,7 @@ K_SEM_DEFINE(audio_ready_sem, 0, 1);
|
|||||||
static const struct device *const i2s_dev = DEVICE_DT_GET(I2S_NODE);
|
static const struct device *const i2s_dev = DEVICE_DT_GET(I2S_NODE);
|
||||||
static const struct gpio_dt_spec amp_en_dev = GPIO_DT_SPEC_GET(AUDIO_AMP_ENABLE_NODE, gpios);
|
static const struct gpio_dt_spec amp_en_dev = GPIO_DT_SPEC_GET(AUDIO_AMP_ENABLE_NODE, gpios);
|
||||||
|
|
||||||
|
static volatile int current_volume = 8;
|
||||||
static volatile bool abort_playback = false;
|
static volatile bool abort_playback = false;
|
||||||
static char next_random_filename[64] = {0};
|
static char next_random_filename[64] = {0};
|
||||||
|
|
||||||
@@ -219,6 +219,8 @@ void audio_thread(void *arg1, void *arg2, void *arg3)
|
|||||||
|
|
||||||
bool trigger_started = false;
|
bool trigger_started = false;
|
||||||
int queued_blocks = 0;
|
int queued_blocks = 0;
|
||||||
|
uint8_t factor = MIN(255, current_volume * 0xFF / 100);
|
||||||
|
LOG_INF("Volume factor: %u (for volume %d%%)", factor, current_volume);
|
||||||
|
|
||||||
while (!abort_playback)
|
while (!abort_playback)
|
||||||
{
|
{
|
||||||
@@ -234,7 +236,7 @@ void audio_thread(void *arg1, void *arg2, void *arg3)
|
|||||||
|
|
||||||
if (abort_playback)
|
if (abort_playback)
|
||||||
{
|
{
|
||||||
k_mem_slab_free(&audio_slab, &block);
|
k_mem_slab_free(&audio_slab, block);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -242,7 +244,7 @@ void audio_thread(void *arg1, void *arg2, void *arg3)
|
|||||||
|
|
||||||
if (bytes_read <= 0)
|
if (bytes_read <= 0)
|
||||||
{
|
{
|
||||||
k_mem_slab_free(&audio_slab, &block);
|
k_mem_slab_free(&audio_slab, block);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -252,7 +254,7 @@ void audio_thread(void *arg1, void *arg2, void *arg3)
|
|||||||
|
|
||||||
for (int i = samples_read - 1; i >= 0; i--)
|
for (int i = samples_read - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
int16_t sample = samples[i];
|
int16_t sample = (samples[i] * factor) >> 8; // Lautstärkeanpassung
|
||||||
samples[i * 2] = sample;
|
samples[i * 2] = sample;
|
||||||
samples[i * 2 + 1] = sample;
|
samples[i * 2 + 1] = sample;
|
||||||
}
|
}
|
||||||
@@ -267,7 +269,7 @@ void audio_thread(void *arg1, void *arg2, void *arg3)
|
|||||||
/* Block in die DMA-Queue schieben */
|
/* Block in die DMA-Queue schieben */
|
||||||
if (i2s_write(i2s_dev, block, AUDIO_BLOCK_SIZE) < 0)
|
if (i2s_write(i2s_dev, block, AUDIO_BLOCK_SIZE) < 0)
|
||||||
{
|
{
|
||||||
k_mem_slab_free(&audio_slab, &block);
|
k_mem_slab_free(&audio_slab, block);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,20 @@
|
|||||||
#include <audio.h>
|
#include <audio.h>
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
#include <usb.h>
|
#include <usb.h>
|
||||||
|
#include <utils.h>
|
||||||
|
|
||||||
|
volatile static uint8_t reboot_code = 0;
|
||||||
|
|
||||||
|
void init_reboot_status()
|
||||||
|
{
|
||||||
|
reboot_code = get_reboot_status();
|
||||||
|
if (reboot_code != 0)
|
||||||
|
{
|
||||||
|
LOG_INF("Device rebooted with status code: 0x%02x", reboot_code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SYS_INIT(init_reboot_status, POST_KERNEL, 0);
|
||||||
|
|
||||||
LOG_MODULE_REGISTER(main, LOG_LEVEL_INF);
|
LOG_MODULE_REGISTER(main, LOG_LEVEL_INF);
|
||||||
|
|
||||||
@@ -24,25 +38,29 @@ int main(void)
|
|||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
rc = fs_init();
|
rc = fs_init();
|
||||||
if (rc < 0) {
|
if (rc < 0)
|
||||||
|
{
|
||||||
LOG_ERR("Filesystem initialization failed: %d", rc);
|
LOG_ERR("Filesystem initialization failed: %d", rc);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = audio_init();
|
rc = audio_init();
|
||||||
if (rc < 0) {
|
if (rc < 0)
|
||||||
|
{
|
||||||
LOG_ERR("Audio initialization failed: %d", rc);
|
LOG_ERR("Audio initialization failed: %d", rc);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = usb_cdc_acm_init();
|
rc = usb_cdc_acm_init();
|
||||||
if (rc < 0) {
|
if (rc < 0)
|
||||||
|
{
|
||||||
LOG_ERR("USB initialization failed: %d", rc);
|
LOG_ERR("USB initialization failed: %d", rc);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = io_init();
|
rc = io_init();
|
||||||
if (rc < 0) {
|
if (rc < 0)
|
||||||
|
{
|
||||||
LOG_ERR("I/O initialization failed: %d", rc);
|
LOG_ERR("I/O initialization failed: %d", rc);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@@ -54,6 +72,11 @@ int main(void)
|
|||||||
LOG_INF("Confirmation of firmware image pending. Inform user...");
|
LOG_INF("Confirmation of firmware image pending. Inform user...");
|
||||||
audio_play("/lfs/sys/update");
|
audio_play("/lfs/sys/update");
|
||||||
}
|
}
|
||||||
|
else if (reboot_code == REBOOT_STATUS_FIRMWARE_CONFIRMED)
|
||||||
|
{
|
||||||
|
LOG_INF("Firmware was just confirmed in the last reboot. Playing confirmation sound.");
|
||||||
|
audio_play("/lfs/sys/confirm");
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LOG_INF("Firmware image already confirmed. No need to confirm again.");
|
LOG_INF("Firmware image already confirmed. No need to confirm again.");
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
#include <app_version.h>
|
#include <app_version.h>
|
||||||
#include <zephyr/sys/crc.h>
|
#include <zephyr/sys/crc.h>
|
||||||
#include <zephyr/dfu/mcuboot.h>
|
#include <zephyr/dfu/mcuboot.h>
|
||||||
#include <zephyr/sys/reboot.h>
|
|
||||||
|
|
||||||
|
#include <utils.h>
|
||||||
#include <usb.h>
|
#include <usb.h>
|
||||||
#include <protocol.h>
|
#include <protocol.h>
|
||||||
#include <audio.h>
|
#include <audio.h>
|
||||||
@@ -41,7 +41,7 @@ void send_error(int32_t error_code)
|
|||||||
usb_write_buffer((const uint8_t *)response, strlen(response));
|
usb_write_buffer((const uint8_t *)response, strlen(response));
|
||||||
}
|
}
|
||||||
|
|
||||||
int send_ls(const char *path)
|
int cmd_ls(const char *path)
|
||||||
{
|
{
|
||||||
struct fs_dir_t dirp;
|
struct fs_dir_t dirp;
|
||||||
struct fs_dirent entry;
|
struct fs_dirent entry;
|
||||||
@@ -65,7 +65,7 @@ int send_ls(const char *path)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int send_info()
|
int cmd_info()
|
||||||
{
|
{
|
||||||
char info[112];
|
char info[112];
|
||||||
struct fs_statvfs stat;
|
struct fs_statvfs stat;
|
||||||
@@ -80,7 +80,7 @@ int send_info()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int put_binary_file(const char *filename, ssize_t filesize, uint32_t expected_crc32)
|
int cmd_put_binary_file(const char *filename, ssize_t filesize, uint32_t expected_crc32)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
ssize_t bytes_written = 0;
|
ssize_t bytes_written = 0;
|
||||||
@@ -228,9 +228,7 @@ int put_binary_file(const char *filename, ssize_t filesize, uint32_t expected_cr
|
|||||||
}
|
}
|
||||||
send_ok();
|
send_ok();
|
||||||
LOG_INF("Firmware upgrade requested, rebooting into bootloader...");
|
LOG_INF("Firmware upgrade requested, rebooting into bootloader...");
|
||||||
k_sleep(K_MSEC(100)); // Kurze Pause, damit die OK-Antwort noch rausgeht
|
reboot_with_status(REBOOT_STATUS_FIRMWARE_UPDATE);
|
||||||
while (log_process());
|
|
||||||
sys_reboot(SYS_REBOOT_COLD);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -247,7 +245,7 @@ int put_binary_file(const char *filename, ssize_t filesize, uint32_t expected_cr
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mkdir(const char *path) {
|
int cmd_mkdir(const char *path) {
|
||||||
int rc = fs_pm_mkdir(path);
|
int rc = fs_pm_mkdir(path);
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
{
|
{
|
||||||
@@ -257,7 +255,7 @@ int mkdir(const char *path) {
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
int rm(const char *path) {
|
int cmd_rm(const char *path) {
|
||||||
int rc = fs_pm_unlink(path);
|
int rc = fs_pm_unlink(path);
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
{
|
{
|
||||||
@@ -267,7 +265,7 @@ int rm(const char *path) {
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
int confirm_firmware() {
|
int cmd_confirm_firmware() {
|
||||||
int rc = boot_write_img_confirmed();
|
int rc = boot_write_img_confirmed();
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
{
|
{
|
||||||
@@ -275,19 +273,50 @@ int confirm_firmware() {
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
LOG_INF("Firmware confirmed successfully");
|
LOG_INF("Firmware confirmed successfully");
|
||||||
audio_play("/lfs/sys/confirm");
|
reboot_with_status(REBOOT_STATUS_FIRMWARE_CONFIRMED);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int reboot_device() {
|
int cmd_reboot_device() {
|
||||||
LOG_INF("Rebooting device as requested by host...");
|
LOG_INF("Rebooting device as requested by host...");
|
||||||
send_ok();
|
send_ok();
|
||||||
k_sleep(K_MSEC(100)); // Kurze Pause, damit die OK-Antwort noch rausgeht
|
reboot_with_status(REBOOT_STATUS_NORMAL);
|
||||||
while (log_process());
|
|
||||||
sys_reboot(SYS_REBOOT_COLD);
|
|
||||||
return 0; // Dieser Code wird nie erreicht, aber wir geben ihn der Vollständigkeit halber zurück
|
return 0; // Dieser Code wird nie erreicht, aber wir geben ihn der Vollständigkeit halber zurück
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cmd_play(const char *filename) {
|
||||||
|
LOG_DBG("Play command received with filename: '%s'", filename);
|
||||||
|
audio_play(filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
int cmd_check(const char *param) {
|
||||||
|
LOG_DBG("Check command received with parameter: '%s'", param);
|
||||||
|
struct fs_file_t file;
|
||||||
|
fs_file_t_init(&file);
|
||||||
|
int rc = fs_pm_open(&file, param, FS_O_READ);
|
||||||
|
if (rc < 0) {
|
||||||
|
LOG_ERR("Check failed: file '%s' not found", param);
|
||||||
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
uint32_t crc32 = 0;
|
||||||
|
uint8_t buffer[256];
|
||||||
|
ssize_t read;
|
||||||
|
while ((read = fs_read(&file, buffer, sizeof(buffer))) > 0)
|
||||||
|
{
|
||||||
|
crc32 = crc32_ieee_update(crc32, buffer, read);
|
||||||
|
}
|
||||||
|
fs_pm_close(&file);
|
||||||
|
if (read < 0) {
|
||||||
|
LOG_ERR("Check failed: error reading file '%s': %d", param, (int)read);
|
||||||
|
return (int)read;
|
||||||
|
}
|
||||||
|
LOG_DBG("Check successful: file '%s' has CRC32 0x%08x", param, crc32);
|
||||||
|
char response[64];
|
||||||
|
snprintf(response, sizeof(response), "CRC32 %s 0x%08x\n", param, crc32);
|
||||||
|
usb_write_buffer((const uint8_t *)response, strlen(response));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void execute_current_command(void)
|
void execute_current_command(void)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
@@ -295,7 +324,7 @@ void execute_current_command(void)
|
|||||||
{
|
{
|
||||||
case CMD_LS:
|
case CMD_LS:
|
||||||
LOG_DBG("Executing LS command with parameters: '%s'", buffer);
|
LOG_DBG("Executing LS command with parameters: '%s'", buffer);
|
||||||
rc = send_ls((char *)buffer);
|
rc = cmd_ls((char *)buffer);
|
||||||
if (rc == 0)
|
if (rc == 0)
|
||||||
{
|
{
|
||||||
send_ok();
|
send_ok();
|
||||||
@@ -311,7 +340,7 @@ void execute_current_command(void)
|
|||||||
LOG_WRN("INFO command received with unexpected parameters: '%s'", buffer);
|
LOG_WRN("INFO command received with unexpected parameters: '%s'", buffer);
|
||||||
}
|
}
|
||||||
LOG_DBG("Executing INFO command");
|
LOG_DBG("Executing INFO command");
|
||||||
rc = send_info();
|
rc = cmd_info();
|
||||||
if (rc == 0)
|
if (rc == 0)
|
||||||
{
|
{
|
||||||
send_ok();
|
send_ok();
|
||||||
@@ -334,7 +363,7 @@ void execute_current_command(void)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
LOG_DBG("Executing PUT_BINARY_FILE command filename: '%s', filesize: %zd, crc32: 0x%08x", filename, filesize, crc32);
|
LOG_DBG("Executing PUT_BINARY_FILE command filename: '%s', filesize: %zd, crc32: 0x%08x", filename, filesize, crc32);
|
||||||
rc = put_binary_file(filename, filesize, crc32);
|
rc = cmd_put_binary_file(filename, filesize, crc32);
|
||||||
if (rc == 0)
|
if (rc == 0)
|
||||||
{
|
{
|
||||||
send_ok();
|
send_ok();
|
||||||
@@ -348,7 +377,7 @@ void execute_current_command(void)
|
|||||||
break;
|
break;
|
||||||
case CMD_MKDIR:
|
case CMD_MKDIR:
|
||||||
LOG_DBG("Executing MKDIR command with parameters: '%s'", buffer);
|
LOG_DBG("Executing MKDIR command with parameters: '%s'", buffer);
|
||||||
rc = mkdir((char *)buffer);
|
rc = cmd_mkdir((char *)buffer);
|
||||||
if (rc == 0) {
|
if (rc == 0) {
|
||||||
send_ok();
|
send_ok();
|
||||||
}
|
}
|
||||||
@@ -358,7 +387,7 @@ void execute_current_command(void)
|
|||||||
break;
|
break;
|
||||||
case CMD_RM:
|
case CMD_RM:
|
||||||
LOG_DBG("Executing RM command with parameters: '%s'", buffer);
|
LOG_DBG("Executing RM command with parameters: '%s'", buffer);
|
||||||
rc = rm((char *)buffer);
|
rc = cmd_rm((char *)buffer);
|
||||||
if (rc == 0) {
|
if (rc == 0) {
|
||||||
send_ok();
|
send_ok();
|
||||||
audio_refresh_file_count(); // Nach erfolgreichem Löschen die Anzahl der verfügbaren Audiodateien aktualisieren
|
audio_refresh_file_count(); // Nach erfolgreichem Löschen die Anzahl der verfügbaren Audiodateien aktualisieren
|
||||||
@@ -369,22 +398,36 @@ void execute_current_command(void)
|
|||||||
break;
|
break;
|
||||||
case CMD_CONFIRM:
|
case CMD_CONFIRM:
|
||||||
LOG_DBG("Executing CONFIRM command");
|
LOG_DBG("Executing CONFIRM command");
|
||||||
rc = confirm_firmware();
|
rc = cmd_confirm_firmware();
|
||||||
if (rc == 0)
|
if (rc != 0) {
|
||||||
{ send_ok();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
send_error(rc);
|
send_error(rc);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
send_ok();
|
||||||
break;
|
break;
|
||||||
case CMD_REBOOT:
|
case CMD_REBOOT:
|
||||||
LOG_DBG("Executing REBOOT command");
|
LOG_DBG("Executing REBOOT command");
|
||||||
rc = reboot_device();
|
rc = cmd_reboot_device();
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
send_error(rc);
|
send_error(rc);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case CMD_PLAY:
|
||||||
|
LOG_DBG("Executing PLAY command");
|
||||||
|
cmd_play((char *)buffer);
|
||||||
|
send_ok();
|
||||||
|
break;
|
||||||
|
case CMD_CHECK:
|
||||||
|
LOG_DBG("Executing CHECK command");
|
||||||
|
rc = cmd_check((char *)buffer);
|
||||||
|
if (rc == 0) {
|
||||||
|
send_ok();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
send_error(rc);
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
LOG_ERR("No execution logic for command %d", current_command);
|
LOG_ERR("No execution logic for command %d", current_command);
|
||||||
send_error(ENOSYS);
|
send_error(ENOSYS);
|
||||||
@@ -435,15 +478,27 @@ protocol_state_t reading_command(uint8_t byte)
|
|||||||
{
|
{
|
||||||
LOG_DBG("Received RM command");
|
LOG_DBG("Received RM command");
|
||||||
current_command = CMD_RM;
|
current_command = CMD_RM;
|
||||||
} else if (strcmp((char *)buffer, "confirm") == 0)
|
}
|
||||||
|
else if (strcmp((char *)buffer, "confirm") == 0)
|
||||||
{
|
{
|
||||||
LOG_DBG("Received CONFIRM command");
|
LOG_DBG("Received CONFIRM command");
|
||||||
current_command = CMD_CONFIRM;
|
current_command = CMD_CONFIRM;
|
||||||
} else if (strcmp((char *)buffer, "reboot") == 0)
|
}
|
||||||
|
else if (strcmp((char *)buffer, "reboot") == 0)
|
||||||
{
|
{
|
||||||
LOG_DBG("Received REBOOT command");
|
LOG_DBG("Received REBOOT command");
|
||||||
current_command = CMD_REBOOT;
|
current_command = CMD_REBOOT;
|
||||||
}
|
}
|
||||||
|
else if (strcmp((char *)buffer, "play") == 0)
|
||||||
|
{
|
||||||
|
LOG_DBG("Received PLAY command");
|
||||||
|
current_command = CMD_PLAY;
|
||||||
|
}
|
||||||
|
else if (strcmp((char *)buffer, "check") == 0)
|
||||||
|
{
|
||||||
|
LOG_DBG("Received CHECK command");
|
||||||
|
current_command = CMD_CHECK;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LOG_DBG("Unknown command: %s", buffer);
|
LOG_DBG("Unknown command: %s", buffer);
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ typedef enum {
|
|||||||
CMD_RM,
|
CMD_RM,
|
||||||
CMD_CONFIRM,
|
CMD_CONFIRM,
|
||||||
CMD_REBOOT,
|
CMD_REBOOT,
|
||||||
|
CMD_PLAY,
|
||||||
|
CMD_CHECK,
|
||||||
/* Weitere Kommandos folgen hier */
|
/* Weitere Kommandos folgen hier */
|
||||||
} protocol_cmd_t;
|
} protocol_cmd_t;
|
||||||
|
|
||||||
|
|||||||
53
firmware/src/utils.c
Normal file
53
firmware/src/utils.c
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
#include <zephyr/kernel.h>
|
||||||
|
#include <zephyr/logging/log.h>
|
||||||
|
#include <zephyr/sys/printk.h>
|
||||||
|
#include <zephyr/logging/log_ctrl.h>
|
||||||
|
#include <zephyr/sys/reboot.h>
|
||||||
|
|
||||||
|
#if IS_ENABLED(CONFIG_SOC_SERIES_NRF52X)
|
||||||
|
#include <hal/nrf_power.h>
|
||||||
|
#elif IS_ENABLED(CONFIG_SOC_SERIES_STM32G0X)
|
||||||
|
#include <stm32_ll_rtc.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
LOG_MODULE_REGISTER(utils, LOG_LEVEL_DBG);
|
||||||
|
|
||||||
|
/* Wir nutzen Register 0 für unseren Reboot-Status */
|
||||||
|
#define REBOOT_STATUS_REG_IDX 0
|
||||||
|
|
||||||
|
void reboot_with_status(uint8_t status)
|
||||||
|
{
|
||||||
|
#if IS_ENABLED(CONFIG_SOC_SERIES_NRF52X)
|
||||||
|
/* Korrigierter Aufruf mit Register-Index 0 */
|
||||||
|
nrf_power_gpregret_set(NRF_POWER, REBOOT_STATUS_REG_IDX, (uint32_t)status);
|
||||||
|
#elif IS_ENABLED(CONFIG_SOC_SERIES_STM32G0X)
|
||||||
|
LL_RTC_BAK_SetRegister(RTC, LL_RTC_BKP_DR0, status);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
LOG_INF("Setting Reboot-Status 0x%02x and resetting...", status);
|
||||||
|
|
||||||
|
k_sleep(K_MSEC(100));
|
||||||
|
LOG_PANIC();
|
||||||
|
|
||||||
|
sys_reboot(SYS_REBOOT_COLD);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t get_reboot_status(void)
|
||||||
|
{
|
||||||
|
uint8_t status = 0;
|
||||||
|
#if IS_ENABLED(CONFIG_SOC_SERIES_NRF52X)
|
||||||
|
/* Korrigierter Aufruf mit Register-Index 0 */
|
||||||
|
status = (uint8_t)nrf_power_gpregret_get(NRF_POWER, REBOOT_STATUS_REG_IDX);
|
||||||
|
/* Register nach dem Lesen löschen */
|
||||||
|
nrf_power_gpregret_set(NRF_POWER, REBOOT_STATUS_REG_IDX, 0);
|
||||||
|
#elif IS_ENABLED(CONFIG_SOC_SERIES_STM32G0X)
|
||||||
|
status = (uint8_t)LL_RTC_BAK_GetRegister(RTC, LL_RTC_BKP_DR0);
|
||||||
|
/* Register nach dem Lesen löschen */
|
||||||
|
LL_RTC_BAK_SetRegister(RTC, LL_RTC_BKP_DR0, 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (status != 0) {
|
||||||
|
printk("Reboot status detected: 0x%02x\n", status);
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
24
firmware/src/utils.h
Normal file
24
firmware/src/utils.h
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
#ifndef UTILS_H
|
||||||
|
#define UTILS_H
|
||||||
|
|
||||||
|
#include <zephyr/kernel.h>
|
||||||
|
|
||||||
|
enum RebootStatus {
|
||||||
|
REBOOT_STATUS_NORMAL = 0x00,
|
||||||
|
REBOOT_STATUS_FIRMWARE_UPDATE = 0xA1,
|
||||||
|
REBOOT_STATUS_FIRMWARE_CONFIRMED = 0xB2
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* @brief Reboots the controller with a specific status code.
|
||||||
|
* On reboot, you can read this status code in the bootloader to determine the reason for the reboot (e.g., normal restart, firmware update, error state).
|
||||||
|
* @param status_code A user-defined code indicating the reason for the reboot.
|
||||||
|
*/
|
||||||
|
void reboot_with_status(uint8_t status_code);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Retrieves the reboot status code set before the last reboot.
|
||||||
|
* This can be used in the bootloader to determine why the device was rebooted and take appropriate actions (e.g., enter firmware update mode if the status indicates a failed update).
|
||||||
|
* @return The reboot status code set before the last reboot, or 0 if no status was set.
|
||||||
|
*/
|
||||||
|
uint8_t get_reboot_status();
|
||||||
|
#endif // UTILS_H
|
||||||
Reference in New Issue
Block a user